Directory: | ./ |
---|---|
File: | FiniteElement/elementVector.cpp |
Date: | 2024-04-14 07:32:34 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 349 | 1472 | 23.7% |
Branches: | 389 | 2962 | 13.1% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | // ______ ______ _ _ _____ ______ | ||
2 | // | ____| ____| | (_)/ ____| | ____| | ||
3 | // | |__ | |__ | | _| (___ ___| |__ | ||
4 | // | __| | __| | | | |\___ \ / __| __| | ||
5 | // | | | |____| |____| |____) | (__| |____ | ||
6 | // |_| |______|______|_|_____/ \___|______| | ||
7 | // Finite Elements for Life Sciences and Engineering | ||
8 | // | ||
9 | // License: LGL2.1 License | ||
10 | // FELiScE default license: LICENSE in root folder | ||
11 | // | ||
12 | // Main authors: J. Foulon & J-F. Gerbeau & V. Martin & Miguel Fernandez | ||
13 | // | ||
14 | |||
15 | // System includes | ||
16 | #include <numeric> | ||
17 | |||
18 | // External includes | ||
19 | |||
20 | // Project includes | ||
21 | #include "FiniteElement/elementVector.hpp" | ||
22 | #include "Geometry/curvatures.hpp" | ||
23 | |||
24 | namespace felisce | ||
25 | { | ||
26 | |||
27 | 324810 | ElementVector::ElementVector(const std::vector<const CurBaseFiniteElement*>& fe, const std::vector<std::size_t>& nbr) : | |
28 |
5/10✓ Branch 9 taken 324810 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 324810 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 324810 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 324810 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 324810 times.
✗ Branch 22 not taken.
|
957945 | m_vec( std::inner_product(fe.begin(),fe.end(),nbr.begin(), 0, std::plus<std::size_t>(), [](auto a, auto b){ return a->numDof()*b; }) ) |
29 | { | ||
30 |
1/2✓ Branch 1 taken 324810 times.
✗ Branch 2 not taken.
|
324810 | m_vec.clear(); |
31 | |||
32 | // TODO are the following used whenever there is one finite element?? | ||
33 | // If not would be better allocate the memory using an ad hoc method | ||
34 |
2/2✓ Branch 1 taken 16565 times.
✓ Branch 2 taken 308245 times.
|
324810 | if (fe.size() == 1) { |
35 |
1/2✓ Branch 3 taken 16565 times.
✗ Branch 4 not taken.
|
16565 | m_tmpVecDof.resize(fe[0]->numDof()); |
36 |
1/2✓ Branch 3 taken 16565 times.
✗ Branch 4 not taken.
|
16565 | m_tmpVecDof.resize(fe[0]->numCoor()); |
37 |
1/2✓ Branch 5 taken 16565 times.
✗ Branch 6 not taken.
|
16565 | m_tmpMatDof.resize(fe[0]->numCoor(),fe[0]->numCoor()); |
38 |
1/2✓ Branch 3 taken 16565 times.
✗ Branch 4 not taken.
|
16565 | m_tmpVecCoor.resize(fe[0]->numCoor()); |
39 | } | ||
40 | |||
41 | // | ||
42 | 324810 | std::size_t sum = std::accumulate(nbr.begin(),nbr.end(), 0); | |
43 |
1/2✓ Branch 1 taken 324810 times.
✗ Branch 2 not taken.
|
324810 | m_numRow.resize(sum); |
44 |
1/2✓ Branch 1 taken 324810 times.
✗ Branch 2 not taken.
|
324810 | m_firstRow.resize(sum); |
45 | // | ||
46 | 324810 | std::size_t first = 0; | |
47 | 324810 | std::size_t start = 0; | |
48 | 324810 | std::size_t end = 0; | |
49 |
2/2✓ Branch 1 taken 633135 times.
✓ Branch 2 taken 324810 times.
|
957945 | for (std::size_t i=0; i<nbr.size(); i++) { |
50 | 633135 | end += nbr[i]; | |
51 |
2/2✓ Branch 0 taken 1524365 times.
✓ Branch 1 taken 633135 times.
|
2157500 | for (std::size_t n=start; n<end; n++){ |
52 | 1524365 | m_numRow[ n ]=fe[i]->numDof(); | |
53 | 1524365 | m_firstRow[ n ]=first; | |
54 | 1524365 | first += fe[i]->numDof(); | |
55 | } | ||
56 | 633135 | start += nbr[i]; | |
57 | } | ||
58 | 324810 | } | |
59 | |||
60 | /***********************************************************************************/ | ||
61 | /***********************************************************************************/ | ||
62 | |||
63 | ✗ | ElementVector::ElementVector(const CurBaseFiniteElement& fe1, const std::size_t nbr1) : | |
64 | ✗ | ElementVector(std::vector<const CurBaseFiniteElement*>{&fe1}, | |
65 | ✗ | std::vector<std::size_t>{nbr1}) | |
66 | { | ||
67 | |||
68 | } | ||
69 | |||
70 | /***********************************************************************************/ | ||
71 | /***********************************************************************************/ | ||
72 | |||
73 | ✗ | ElementVector::ElementVector(const CurBaseFiniteElement& fe1, const std::size_t nbr1, | |
74 | ✗ | const CurBaseFiniteElement& fe2, const std::size_t nbr2) : | |
75 | ✗ | ElementVector(std::vector<const CurBaseFiniteElement*>{&fe1,&fe2}, | |
76 | ✗ | std::vector<std::size_t>{nbr1,nbr2}) | |
77 | { | ||
78 | |||
79 | } | ||
80 | |||
81 | /***********************************************************************************/ | ||
82 | /***********************************************************************************/ | ||
83 | |||
84 | ✗ | ElementVector::ElementVector(const CurBaseFiniteElement& fe1, const std::size_t nbr1, | |
85 | const CurBaseFiniteElement& fe2, const std::size_t nbr2, | ||
86 | ✗ | const CurBaseFiniteElement& fe3, const std::size_t nbr3) : | |
87 | ✗ | ElementVector(std::vector<const CurBaseFiniteElement*>{&fe1,&fe2,&fe3}, | |
88 | ✗ | std::vector<std::size_t>{nbr1,nbr2,nbr3}) | |
89 | { | ||
90 | |||
91 | } | ||
92 | |||
93 | /***********************************************************************************/ | ||
94 | /***********************************************************************************/ | ||
95 | |||
96 | 8163406 | void ElementVector::source(const double coef, const CurBaseFiniteElement& fe,const ElementField& elfield,const int iblock,const int numComp) | |
97 | { | ||
98 | double tmp; | ||
99 |
3/4✓ Branch 1 taken 21 times.
✓ Branch 2 taken 399837 times.
✓ Branch 3 taken 7763548 times.
✗ Branch 4 not taken.
|
8163406 | switch(elfield.type()) { |
100 | 21 | case CONSTANT_FIELD: | |
101 |
2/2✓ Branch 0 taken 37 times.
✓ Branch 1 taken 21 times.
|
58 | for(int icomp=0; icomp<numComp; icomp++) { |
102 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | UBlasVectorRange vec = vecBlock(iblock+icomp); |
103 |
2/2✓ Branch 1 taken 82 times.
✓ Branch 2 taken 37 times.
|
119 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { |
104 |
2/4✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 82 times.
✗ Branch 5 not taken.
|
82 | tmp = elfield.val(icomp,0) * fe.weightMeas(ig); |
105 |
2/2✓ Branch 1 taken 534 times.
✓ Branch 2 taken 82 times.
|
616 | for(int idof=0; idof<fe.numDof(); idof++) { |
106 |
2/4✓ Branch 2 taken 534 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 534 times.
✗ Branch 6 not taken.
|
534 | vec(idof) += coef * tmp * fe.phi[ig](idof); |
107 | } | ||
108 | } | ||
109 | 37 | } | |
110 | 21 | break; | |
111 | 399837 | case QUAD_POINT_FIELD: | |
112 |
2/2✓ Branch 0 taken 1059172 times.
✓ Branch 1 taken 399837 times.
|
1459009 | for(int icomp=0; icomp<numComp; icomp++) { |
113 |
1/2✓ Branch 1 taken 1059172 times.
✗ Branch 2 not taken.
|
1059172 | UBlasVectorRange vec = vecBlock(iblock+icomp); |
114 |
2/2✓ Branch 1 taken 8600254 times.
✓ Branch 2 taken 1059172 times.
|
9659426 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { |
115 |
2/4✓ Branch 1 taken 8600254 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8600254 times.
✗ Branch 5 not taken.
|
8600254 | tmp = elfield.val(icomp,ig) * fe.weightMeas(ig); |
116 |
2/2✓ Branch 1 taken 37817090 times.
✓ Branch 2 taken 8600254 times.
|
46417344 | for(int idof=0; idof<fe.numDof(); idof++) { |
117 |
2/4✓ Branch 2 taken 37817090 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 37817090 times.
✗ Branch 6 not taken.
|
37817090 | vec(idof) += coef * tmp * fe.phi[ig](idof); |
118 | } | ||
119 | } | ||
120 | 1059172 | } | |
121 | 399837 | break; | |
122 | 7763548 | case DOF_FIELD: | |
123 |
2/2✓ Branch 0 taken 21273472 times.
✓ Branch 1 taken 7763548 times.
|
29037020 | for(int icomp=0; icomp<numComp; icomp++) { |
124 |
1/2✓ Branch 1 taken 21273472 times.
✗ Branch 2 not taken.
|
21273472 | UBlasVectorRange vec = vecBlock(iblock+icomp); |
125 |
2/2✓ Branch 1 taken 124146625 times.
✓ Branch 2 taken 21273472 times.
|
145420097 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { |
126 | 124146625 | tmp = 0.0; | |
127 |
2/2✓ Branch 1 taken 528122752 times.
✓ Branch 2 taken 124146625 times.
|
652269377 | for(int idof=0; idof<fe.numDof(); idof++) { |
128 |
2/4✓ Branch 2 taken 528122752 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 528122752 times.
✗ Branch 6 not taken.
|
528122752 | tmp += fe.phi[ig](idof) * elfield.val(icomp,idof); |
129 | } | ||
130 |
2/2✓ Branch 1 taken 528122752 times.
✓ Branch 2 taken 124146625 times.
|
652269377 | for(int idof=0; idof<fe.numDof(); idof++) { |
131 |
3/6✓ Branch 2 taken 528122752 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 528122752 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 528122752 times.
✗ Branch 9 not taken.
|
528122752 | vec(idof) += coef * tmp * fe.phi[ig](idof) * fe.weightMeas(ig); |
132 | } | ||
133 | } | ||
134 | 21273472 | } | |
135 | 7763548 | break; | |
136 | // Default case should appear with a warning at compile time instead of an error in runtime | ||
137 | // (that's truly the point of using enums as switch cases) | ||
138 | // default: | ||
139 | // FEL_ERROR("Operator 'source' not yet implemented with this type of element fields"); | ||
140 | } | ||
141 | 8163406 | } | |
142 | |||
143 | /***********************************************************************************/ | ||
144 | /***********************************************************************************/ | ||
145 | |||
146 | ✗ | void ElementVector::source_lumped(const double coef, const CurvilinearFiniteElement& fe,const ElementField& elfield,const int iblock,const int numComp) | |
147 | { | ||
148 | double tmp; | ||
149 | ✗ | switch(elfield.type()) { | |
150 | ✗ | case CONSTANT_FIELD: | |
151 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
152 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
153 | ✗ | tmp = elfield.val(icomp,0) * fe.measure()/fe.numDof(); | |
154 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
155 | ✗ | vec(idof) += coef * tmp; | |
156 | } | ||
157 | } | ||
158 | ✗ | break; | |
159 | ✗ | case DOF_FIELD: | |
160 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
161 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
162 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
163 | ✗ | vec(idof) += coef * elfield.val(icomp,idof) * fe.measure()/fe.numDof(); | |
164 | } | ||
165 | } | ||
166 | ✗ | break; | |
167 | // Default case should appear with a warning at compile time instead of an error in runtime | ||
168 | // (that's truly the point of using enums as switch cases) | ||
169 | ✗ | default: | |
170 | ✗ | FEL_ERROR("Operator 'source lumped' not yet implemented with this type of element fields"); | |
171 | } | ||
172 | } | ||
173 | |||
174 | /***********************************************************************************/ | ||
175 | /***********************************************************************************/ | ||
176 | |||
177 | 172288 | void ElementVector::sourceForComp(const double coef, const CurvilinearFiniteElement& fe,const ElementField& elfield,const int iblock, const int iComp) | |
178 | { | ||
179 | double tmp; | ||
180 |
1/2✓ Branch 1 taken 172288 times.
✗ Branch 2 not taken.
|
172288 | UBlasVectorRange vec = vecBlock(iblock); |
181 |
2/4✓ Branch 1 taken 165808 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6480 times.
✗ Branch 4 not taken.
|
172288 | switch(elfield.type()) { |
182 | 165808 | case CONSTANT_FIELD: | |
183 |
2/2✓ Branch 1 taken 550216 times.
✓ Branch 2 taken 165808 times.
|
716024 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { |
184 |
2/4✓ Branch 1 taken 550216 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 550216 times.
✗ Branch 5 not taken.
|
550216 | tmp = elfield.val(iComp,0) * fe.weightMeas(ig); |
185 |
2/2✓ Branch 1 taken 1610912 times.
✓ Branch 2 taken 550216 times.
|
2161128 | for(int idof=0; idof<fe.numDof(); idof++) { |
186 |
2/4✓ Branch 2 taken 1610912 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1610912 times.
✗ Branch 6 not taken.
|
1610912 | vec(idof) += coef * tmp * fe.phi[ig](idof); |
187 | } | ||
188 | } | ||
189 | 165808 | break; | |
190 | ✗ | case QUAD_POINT_FIELD: | |
191 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
192 | ✗ | tmp = elfield.val(iComp,ig) * fe.weightMeas(ig); | |
193 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
194 | ✗ | vec(idof) += coef * tmp * fe.phi[ig](idof); | |
195 | } | ||
196 | } | ||
197 | ✗ | break; | |
198 | 6480 | case DOF_FIELD: | |
199 |
2/2✓ Branch 1 taken 19440 times.
✓ Branch 2 taken 6480 times.
|
25920 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { |
200 | 19440 | tmp = 0.0; | |
201 |
2/2✓ Branch 1 taken 38880 times.
✓ Branch 2 taken 19440 times.
|
58320 | for(int idof=0; idof<fe.numDof(); idof++) { |
202 |
2/4✓ Branch 2 taken 38880 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 38880 times.
✗ Branch 6 not taken.
|
38880 | tmp += fe.phi[ig](idof) * elfield.val(iComp,idof); |
203 | } | ||
204 |
2/2✓ Branch 1 taken 38880 times.
✓ Branch 2 taken 19440 times.
|
58320 | for(int idof=0; idof<fe.numDof(); idof++) { |
205 |
3/6✓ Branch 2 taken 38880 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 38880 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 38880 times.
✗ Branch 9 not taken.
|
38880 | vec(idof) += coef * tmp * fe.phi[ig](idof) * fe.weightMeas(ig); |
206 | } | ||
207 | } | ||
208 | 6480 | break; | |
209 | // Default case should appear with a warning at compile time instead of an error in runtime | ||
210 | // (that's truly the point of using enums as switch cases) | ||
211 | // default: | ||
212 | // FEL_ERROR("Operator 'source' not yet implemented with this type of element fields"); | ||
213 | } | ||
214 | 172288 | } | |
215 | |||
216 | /***********************************************************************************/ | ||
217 | /***********************************************************************************/ | ||
218 | |||
219 | 63280 | void ElementVector::f_phi_i_scalar_n(const double coef,const CurvilinearFiniteElement& fe,const ElementField& elfield,const int iblock) | |
220 | { | ||
221 | double tmp; | ||
222 |
1/4✓ Branch 1 taken 63280 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
63280 | switch(elfield.type()) { |
223 | 63280 | case CONSTANT_FIELD: | |
224 |
2/2✓ Branch 1 taken 184088 times.
✓ Branch 2 taken 63280 times.
|
247368 | for(int icomp=0; icomp<fe.numCoor(); icomp++) { |
225 |
1/2✓ Branch 1 taken 184088 times.
✗ Branch 2 not taken.
|
184088 | UBlasVectorRange vec = vecBlock(iblock+icomp); |
226 |
2/2✓ Branch 1 taken 595606 times.
✓ Branch 2 taken 184088 times.
|
779694 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { |
227 |
3/6✓ Branch 1 taken 595606 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 595606 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 595606 times.
✗ Branch 9 not taken.
|
595606 | tmp = coef * elfield.val(0,0) * fe.normal[ig](icomp) * fe.weightMeas(ig); |
228 |
2/2✓ Branch 1 taken 1879172 times.
✓ Branch 2 taken 595606 times.
|
2474778 | for(int idof=0; idof<fe.numDof(); idof++) { |
229 |
2/4✓ Branch 2 taken 1879172 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1879172 times.
✗ Branch 6 not taken.
|
1879172 | vec(idof) += tmp * fe.phi[ig](idof); |
230 | } | ||
231 | } | ||
232 | 184088 | } | |
233 | 63280 | break; | |
234 | ✗ | case QUAD_POINT_FIELD: | |
235 | ✗ | for(int icomp=0; icomp<fe.numCoor(); icomp++) { | |
236 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
237 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
238 | ✗ | tmp = coef * elfield.val(0,ig) * fe.normal[ig](icomp) * fe.weightMeas(ig); | |
239 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
240 | ✗ | vec(idof) += tmp * fe.phi[ig](idof); | |
241 | } | ||
242 | } | ||
243 | } | ||
244 | ✗ | break; | |
245 | ✗ | case DOF_FIELD: | |
246 | ✗ | for(int icomp=0; icomp<fe.numCoor(); icomp++) { | |
247 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
248 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
249 | ✗ | tmp = 0.0; | |
250 | ✗ | for(int jdof=0; jdof<fe.numDof(); jdof++) { | |
251 | ✗ | tmp += fe.phi[ig](jdof) * elfield.val(0,jdof); | |
252 | } | ||
253 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
254 | ✗ | vec(idof) += coef * tmp * fe.phi[ig](idof) * fe.normal[ig](icomp)* fe.weightMeas(ig); | |
255 | } | ||
256 | } | ||
257 | } | ||
258 | ✗ | break; | |
259 | // Default case should appear with a warning at compile time instead of an error in runtime | ||
260 | // (that's truly the point of using enums as switch cases) | ||
261 | ✗ | default: | |
262 | ✗ | FEL_ERROR("Operator 'f_phi_i_scalar_n' not yet implemented with this type of element fields"); | |
263 | } | ||
264 | 63280 | } | |
265 | |||
266 | /***********************************************************************************/ | ||
267 | /***********************************************************************************/ | ||
268 | |||
269 | ✗ | void ElementVector::f_phi_i_scalar_piola_n(const double coef,const CurvilinearFiniteElement& fe,const ElementField& elf,const ElementField& elfd,const int iblock) | |
270 | { | ||
271 | (void)coef; | ||
272 | (void)fe; | ||
273 | (void)elf; | ||
274 | (void)elfd; | ||
275 | (void)iblock; | ||
276 | //FEL_CHECK(fe.numCoor() == 3,"ElementVector::f_phi_i_scalar_JF_T_n: works only in 3D"); | ||
277 | |||
278 | // double det, val, p = elf.val(0,0); | ||
279 | // std::vector<UBlasMatrix> piola; | ||
280 | // UBlasMatrix F, mLU; | ||
281 | // UBlasPermutationMatrix pm(fe.numCoor()); | ||
282 | // piola.resize(fe.numQuadraturePoint()); | ||
283 | |||
284 | // for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | ||
285 | // // evaluate piola at quadrature point | ||
286 | // piola[ig].resize(fe.numCoor(),fe.numCoor()); | ||
287 | // F.clear(); | ||
288 | // for(int l=0; l<fe.numDof(); ++l) | ||
289 | // for(int i=0; i<fe.numCoor(); ++i) { | ||
290 | // val = elfd.val(i,l); // d_i at node l | ||
291 | // for(int j=0; i<fe.numCoor(); ++i) | ||
292 | // F(i,j) += val*fe.dPhi[ig](j,l); | ||
293 | // } | ||
294 | // mLU = F; | ||
295 | // int ierr = lu_factorize(mLU, pm); | ||
296 | // FEL_CHECK(ierr==0,"LU factorization failed in f_phi_i_scalar_piola_n"); | ||
297 | // det = 1.; | ||
298 | // for (std::size_t i=0; i < pm.size(); i++) { | ||
299 | // if (pm(i) != i) | ||
300 | // det *= -1.; | ||
301 | // det *= mLU(i,i); | ||
302 | // } | ||
303 | // F.assign(identity_matrix<double>(fe.numCoor())); | ||
304 | // lu_substitute(mLu,pm,F); | ||
305 | // piola[ig] = det * transpose(F); | ||
306 | // } | ||
307 | |||
308 | // for(int icomp=0; icomp<3; icomp++) { | ||
309 | // UBlasVectorRange vec = vecBlock(iblock+icomp); | ||
310 | // for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | ||
311 | // // evaluate F at quadrature point | ||
312 | // F.clear(); | ||
313 | // for(int l=0; l<fe.numDof(); ++l) | ||
314 | // for(int i=0; i<3; ++i) { | ||
315 | // val = elfield.val(i,l) // d_i at node l | ||
316 | // for(int j=0; i<3; ++i) | ||
317 | // F(i,j) += val*fe.dPhi[ig](j,l); | ||
318 | // tmp = coef * p * fe.normal[ig](icomp) * fe.weightMeas(ig); | ||
319 | // for(int idof=0; idof<fe.numDof(); idof++) { | ||
320 | // vec(idof) += tmp * fe.phi[ig](idof); | ||
321 | // } | ||
322 | // } | ||
323 | // } | ||
324 | } | ||
325 | |||
326 | /***********************************************************************************/ | ||
327 | /***********************************************************************************/ | ||
328 | |||
329 | ✗ | void ElementVector::penalty_contact_phi_i_scalar_n(const double coef,const std::vector<double>& normal, const CurvilinearFiniteElement& fe, const ElementField& disp, const ElementField& gap) | |
330 | { | ||
331 | ✗ | FEL_CHECK(disp.type() == DOF_FIELD,"ElementVector::penalty_contact_phi_i_scalar_n: wrong disp field type"); | |
332 | ✗ | FEL_CHECK(gap.type() == QUAD_POINT_FIELD,"ElementVector::penalty_contact_phi_i_scalar_n: wrong gap field type"); | |
333 | double tmp; | ||
334 | ✗ | const double hK2inv = 1./(fe.diameter()*fe.diameter()); | |
335 | ✗ | for(int icomp=0; icomp<fe.numCoor(); icomp++) { | |
336 | ✗ | UBlasVectorRange vec = vecBlock(icomp); | |
337 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
338 | ✗ | tmp = 0.0; | |
339 | // disp at coor point | ||
340 | ✗ | for(int jcomp=0; jcomp<fe.numCoor(); jcomp++) | |
341 | ✗ | for(int jdof=0; jdof<fe.numDof(); jdof++) | |
342 | ✗ | tmp += fe.phi[ig](jdof)*disp.val(jcomp,jdof)*normal[jcomp]; | |
343 | // gap | ||
344 | ✗ | tmp -= gap.val(0,ig); | |
345 | // tmp contains (u \cdot n - g) at quand node ig | ||
346 | ✗ | if (0 <= tmp ) { | |
347 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
348 | //std::cout << coef * (tmp-0.5) * fe.phi[ig](idof) * normal[icomp]* fe.weightMeas(ig) << std::endl; | ||
349 | ✗ | vec(idof) += coef * hK2inv* tmp * fe.phi[ig](idof) * normal[icomp]* fe.weightMeas(ig); | |
350 | } | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | |||
356 | /***********************************************************************************/ | ||
357 | /***********************************************************************************/ | ||
358 | |||
359 | 3840 | void ElementVector::penalty_phi_i_scalar_n(const double coef, CurvilinearFiniteElement& fe, const ElementField& vel, std::size_t iblock) | |
360 | { | ||
361 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3840 times.
|
3840 | FEL_CHECK(vel.type() == DOF_FIELD,"ElementVector::penalty_phi_i_scalar_n: wrong vel field type"); |
362 | double tmp; | ||
363 | 3840 | const double penalty = 1./coef; | |
364 |
2/2✓ Branch 1 taken 7680 times.
✓ Branch 2 taken 3840 times.
|
11520 | for(int icoor=0; icoor<fe.numCoor(); icoor++) { |
365 |
1/2✓ Branch 1 taken 7680 times.
✗ Branch 2 not taken.
|
7680 | UBlasVectorRange vec = vecBlock(icoor+iblock); |
366 |
2/2✓ Branch 1 taken 23040 times.
✓ Branch 2 taken 7680 times.
|
30720 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { |
367 | 23040 | tmp = 0.; | |
368 |
2/2✓ Branch 1 taken 46080 times.
✓ Branch 2 taken 23040 times.
|
69120 | for(int jcomp=0; jcomp<fe.numCoor(); jcomp++) |
369 |
2/2✓ Branch 1 taken 92160 times.
✓ Branch 2 taken 46080 times.
|
138240 | for(int jdof=0; jdof<fe.numDof(); jdof++) |
370 |
3/6✓ Branch 2 taken 92160 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 92160 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 92160 times.
✗ Branch 10 not taken.
|
92160 | tmp -= fe.phi[ig](jdof)*vel.val(jcomp,jdof)*fe.normal[ig][jcomp]; // compute u_dot_n |
371 |
2/2✓ Branch 0 taken 6132 times.
✓ Branch 1 taken 16908 times.
|
23040 | if ( tmp >= 0. ) { |
372 |
2/2✓ Branch 1 taken 12264 times.
✓ Branch 2 taken 6132 times.
|
18396 | for(int idof=0; idof<fe.numDof(); idof++) |
373 |
4/8✓ Branch 2 taken 12264 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 12264 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 12264 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 12264 times.
✗ Branch 13 not taken.
|
12264 | vec(idof) += penalty*tmp*fe.phi[ig](idof)*fe.normal[ig][icoor]*fe.weightMeas(ig); |
374 | } | ||
375 | } | ||
376 | 7680 | } | |
377 | 3840 | } | |
378 | |||
379 | /***********************************************************************************/ | ||
380 | /***********************************************************************************/ | ||
381 | |||
382 | ✗ | void ElementVector::nitsche_contact_phi_i_scalar_n(double gamma,const std::vector<double>& normal, const CurvilinearFiniteElement& fe, const ElementField& disp, const ElementField& gap, const ElementField& lambda) | |
383 | { | ||
384 | ✗ | FEL_CHECK(disp.type() == DOF_FIELD,"ElementVector::penalty_contact_phi_i_scalar_n: wrong disp field type"); | |
385 | ✗ | FEL_CHECK(gap.type() == QUAD_POINT_FIELD,"ElementVector::penalty_contact_phi_i_scalar_n: wrong gap field type"); | |
386 | double tmp; | ||
387 | ✗ | const double penalty = gamma / (fe.diameter()*fe.diameter()); | |
388 | ✗ | const double penalty_inv = fe.diameter()*fe.diameter()/gamma; | |
389 | ✗ | for(int icomp=0; icomp<fe.numCoor(); icomp++) { | |
390 | ✗ | UBlasVectorRange vec = vecBlock(icomp); | |
391 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
392 | ✗ | tmp = 0.0; | |
393 | // disp.n + 1/ gamma * lambda at coor point | ||
394 | ✗ | for(int jcomp=0; jcomp<fe.numCoor(); jcomp++) | |
395 | ✗ | for(int jdof=0; jdof<fe.numDof(); jdof++) | |
396 | ✗ | tmp += fe.phi[ig](jdof)*(disp.val(jcomp,jdof)+ penalty_inv*lambda.val(jcomp,jdof)) *normal[jcomp]; | |
397 | // gap | ||
398 | ✗ | tmp -= gap.val(0,ig); | |
399 | // tmp contains (u \cdot n - g + 1/gamma \lambda ) at quand node ig | ||
400 | ✗ | if (0 <= tmp ) { | |
401 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
402 | ✗ | vec(idof) += penalty * tmp * fe.phi[ig](idof) * normal[icomp]* fe.weightMeas(ig); | |
403 | } | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | } | ||
408 | |||
409 | /***********************************************************************************/ | ||
410 | /***********************************************************************************/ | ||
411 | |||
412 | ✗ | void ElementVector::nitsche_contact_phi_i_scalar_n(double gamma, const CurvilinearFiniteElement& fe, const ElementField& disp, const ElementField& gap, const ElementField& normal, const ElementField& lambda) | |
413 | { | ||
414 | ✗ | FEL_CHECK(disp.type() == DOF_FIELD,"ElementVector::penalty_contact_phi_i_scalar_n: wrong disp field type"); | |
415 | ✗ | FEL_CHECK(gap.type() == QUAD_POINT_FIELD,"ElementVector::penalty_contact_phi_i_scalar_n: wrong gap field type"); | |
416 | double tmp; | ||
417 | ✗ | const double penalty = gamma / (fe.diameter()*fe.diameter()); | |
418 | ✗ | const double penalty_inv = fe.diameter()*fe.diameter()/gamma; | |
419 | ✗ | for(int icomp=0; icomp<fe.numCoor(); icomp++) { | |
420 | ✗ | UBlasVectorRange vec = vecBlock(icomp); | |
421 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
422 | ✗ | tmp = 0.0; | |
423 | // disp.n + 1/ gamma * lambda at coor point | ||
424 | ✗ | for(int jcomp=0; jcomp<fe.numCoor(); jcomp++) | |
425 | ✗ | for(int jdof=0; jdof<fe.numDof(); jdof++) | |
426 | ✗ | tmp += fe.phi[ig](jdof)*(disp.val(jcomp,jdof)+ penalty_inv*lambda.val(jcomp,jdof)) *normal.val(jcomp,ig); | |
427 | // gap | ||
428 | ✗ | tmp -= gap.val(0,ig); | |
429 | // tmp contains (u \cdot n - g + 1/gamma \lambda ) at quand node ig | ||
430 | ✗ | if (0 <= tmp ) { | |
431 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
432 | ✗ | vec(idof) += penalty * tmp * fe.phi[ig](idof) * normal.val(icomp,ig)* fe.weightMeas(ig); | |
433 | } | ||
434 | } | ||
435 | } | ||
436 | } | ||
437 | } | ||
438 | |||
439 | /***********************************************************************************/ | ||
440 | /***********************************************************************************/ | ||
441 | |||
442 | ✗ | void ElementVector::f_n_dot_phi_i(const double coef,const CurvilinearFiniteElement& fe1,const CurvilinearFiniteElement& fe2,const ElementField& elfield,const int iblock) | |
443 | { | ||
444 | double tmp; | ||
445 | ✗ | FEL_CHECK(fe1.numQuadraturePoint() == fe2.numQuadraturePoint(),"ElementVector::f_n_dot_phi_i: The quadrature rules must be the same for the two elements"); | |
446 | ✗ | switch(elfield.type()) { | |
447 | ✗ | case CONSTANT_FIELD: | |
448 | ✗ | for(int icomp=0; icomp<fe1.numCoor(); icomp++) { | |
449 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
450 | ✗ | for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) { | |
451 | ✗ | tmp = coef * elfield.val(0,0) * fe1.normal[ig](icomp) * fe1.weightMeas(ig); | |
452 | ✗ | for(int idof=0; idof<fe1.numDof(); idof++) { | |
453 | ✗ | vec(idof) += tmp * fe1.phi[ig](idof); | |
454 | } | ||
455 | } | ||
456 | } | ||
457 | ✗ | break; | |
458 | ✗ | case QUAD_POINT_FIELD: | |
459 | ✗ | for(int icomp=0; icomp<fe1.numCoor(); icomp++) { | |
460 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
461 | ✗ | for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) { | |
462 | ✗ | tmp = coef * elfield.val(0,ig) * fe1.normal[ig](icomp) * fe1.weightMeas(ig); | |
463 | ✗ | for(int idof=0; idof<fe1.numDof(); idof++) { | |
464 | ✗ | vec(idof) += tmp * fe1.phi[ig](idof); | |
465 | } | ||
466 | } | ||
467 | } | ||
468 | ✗ | break; | |
469 | ✗ | case DOF_FIELD: | |
470 | ✗ | for(int icomp=0; icomp<fe1.numCoor(); icomp++) { | |
471 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
472 | ✗ | for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) { | |
473 | ✗ | tmp = 0.0; | |
474 | ✗ | for(int jdof=0; jdof<fe2.numDof(); jdof++) { | |
475 | ✗ | tmp += fe2.phi[ig](jdof) * elfield.val(0,jdof); | |
476 | } | ||
477 | ✗ | for(int idof=0; idof<fe1.numDof(); idof++) { | |
478 | ✗ | vec(idof) += coef * tmp * fe1.phi[ig](idof) * fe1.normal[ig](icomp)* fe1.weightMeas(ig); | |
479 | } | ||
480 | } | ||
481 | } | ||
482 | ✗ | break; | |
483 | // Default case should appear with a warning at compile time instead of an error in runtime | ||
484 | // (that's truly the point of using enums as switch cases) | ||
485 | // default: | ||
486 | // FEL_ERROR("Operator 'f_n_dot_phi_i' not yet implemented with this type of element fields"); | ||
487 | } | ||
488 | } | ||
489 | |||
490 | /***********************************************************************************/ | ||
491 | /***********************************************************************************/ | ||
492 | |||
493 | ✗ | void ElementVector::f_dot_n_phi_i(const double coef,const CurvilinearFiniteElement& fe1,const CurvilinearFiniteElement& fe2, const ElementField& elfield,const int iblock) | |
494 | { | ||
495 | double tmp,f_dot_n; | ||
496 | ✗ | FEL_CHECK(fe1.numQuadraturePoint() == fe2.numQuadraturePoint(),"ElementVector::f_dot_n_phi_i: The quadrature rules must be the same for the two elements"); | |
497 | ✗ | UBlasVectorRange vec = vecBlock(iblock); | |
498 | ✗ | switch(elfield.type()) { | |
499 | ✗ | case CONSTANT_FIELD: | |
500 | ✗ | for(int icomp=0; icomp<fe1.numCoor(); icomp++) { | |
501 | // UBlasVectorRange vec = vecBlock(iblock + icomp) | ||
502 | ✗ | for(int ig=0; ig<fe2.numQuadraturePoint(); ig++) { | |
503 | ✗ | tmp = coef * elfield.val(0,0) * fe1.normal[ig](icomp) * fe2.weightMeas(ig); | |
504 | ✗ | for(int idof=0; idof<fe2.numDof(); idof++) { | |
505 | ✗ | vec(idof) += tmp * fe2.phi[ig](idof); | |
506 | } | ||
507 | } | ||
508 | } | ||
509 | ✗ | break; | |
510 | ✗ | case QUAD_POINT_FIELD: | |
511 | ✗ | for(int icomp=0; icomp<fe1.numCoor(); icomp++) { | |
512 | // UBlasVectorRange vec = vecBlock(iblock + icomp) | ||
513 | ✗ | for(int ig=0; ig<fe2.numQuadraturePoint(); ig++) { | |
514 | ✗ | tmp = coef * elfield.val(0,ig) * fe1.normal[ig](icomp) * fe2.weightMeas(ig); | |
515 | ✗ | for(int idof=0; idof<fe2.numDof(); idof++) { | |
516 | ✗ | vec(idof) += tmp * fe2.phi[ig](idof); | |
517 | } | ||
518 | } | ||
519 | } | ||
520 | ✗ | break; | |
521 | ✗ | case DOF_FIELD: | |
522 | ✗ | for(int ig=0; ig<fe2.numQuadraturePoint(); ig++) { | |
523 | ✗ | f_dot_n = 0; | |
524 | ✗ | for(int icomp=0; icomp<fe1.numCoor(); icomp++) { | |
525 | ✗ | tmp = 0.0; | |
526 | ✗ | for(int jdof=0; jdof<fe1.numDof(); jdof++) { | |
527 | ✗ | tmp += fe1.phi[ig](jdof) * elfield.val(icomp,jdof); | |
528 | } | ||
529 | ✗ | f_dot_n += tmp * fe1.normal[ig](icomp); | |
530 | } | ||
531 | ✗ | for(int idof=0; idof<fe2.numDof(); idof++) { | |
532 | ✗ | vec(idof) += coef * f_dot_n * fe2.phi[ig](idof) * fe2.weightMeas(ig); | |
533 | } | ||
534 | } | ||
535 | ✗ | break; | |
536 | // Default case should appear with a warning at compile time instead of an error in runtime | ||
537 | // (that's truly the point of using enums as switch cases) | ||
538 | // default: | ||
539 | // FEL_ERROR("Operator 'f_dot_n_phi_i' not yet implemented with this type of element fields"); | ||
540 | } | ||
541 | } | ||
542 | |||
543 | /***********************************************************************************/ | ||
544 | /***********************************************************************************/ | ||
545 | |||
546 | ✗ | void ElementVector::g_dot_n_f_phi_i(const double coef, const CurrentFiniteElement& fe, const ElementField& elt_f, const ElementField& elt_g, const ElementField& elt_n, felInt iblock, felInt numComp) | |
547 | { | ||
548 | ✗ | FEL_ASSERT(elt_f.type() == QUAD_POINT_FIELD); | |
549 | ✗ | FEL_ASSERT(elt_g.type() == DOF_FIELD); | |
550 | ✗ | FEL_ASSERT(elt_n.type() == CONSTANT_FIELD); | |
551 | |||
552 | double tmp; | ||
553 | ✗ | double g_dot_n = 0.0; | |
554 | |||
555 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
556 | ✗ | UBlasVectorRange vec = vecBlock(iblock + icomp); | |
557 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
558 | ✗ | g_dot_n = 0; | |
559 | ✗ | for(int jcomp=0; jcomp<fe.numCoor(); jcomp++) { | |
560 | ✗ | tmp = 0.0; | |
561 | ✗ | for(int jdof=0; jdof<fe.numDof(); jdof++) { | |
562 | ✗ | tmp += fe.phi[ig](jdof) * elt_g.val(jcomp, jdof); | |
563 | } | ||
564 | ✗ | g_dot_n += tmp * elt_n.val(jcomp, 0); | |
565 | } | ||
566 | |||
567 | ✗ | if(g_dot_n < 0) | |
568 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) | |
569 | ✗ | vec(idof) += coef * g_dot_n * elt_f.val(icomp, ig) * fe.phi[ig](idof) * fe.weightMeas(ig); | |
570 | } | ||
571 | } | ||
572 | } | ||
573 | |||
574 | /***********************************************************************************/ | ||
575 | /***********************************************************************************/ | ||
576 | |||
577 | ✗ | void ElementVector::grad_vec2_dot_vec1_dot_phi_i(const double coef, const ElementField& vec1, const ElementField& vec2, const CurrentFiniteElement& fe, const int iblock, const int numComp) | |
578 | { | ||
579 | // Mot implemented for other type yet | ||
580 | ✗ | FEL_ASSERT(vec1.type() == CONSTANT_FIELD); | |
581 | |||
582 | double tmpval1, tmpval2; | ||
583 | |||
584 | ✗ | switch(vec2.type()) { | |
585 | ✗ | case CONSTANT_FIELD: | |
586 | // nothing to do | ||
587 | ✗ | break; | |
588 | |||
589 | ✗ | case QUAD_POINT_FIELD: | |
590 | // cannot compute the derivative of vec2 at integration points | ||
591 | ✗ | FEL_ERROR("grad_vec2_dot_vec1_dot_phi_i does not work with vec2 defined at integration points"); | |
592 | break; | ||
593 | |||
594 | ✗ | case DOF_FIELD: | |
595 | ✗ | for(felInt iComp=0; iComp<numComp; ++iComp) { | |
596 | ✗ | UBlasVectorRange vec = vecBlock(iblock + iComp); | |
597 | ✗ | for(felInt idof=0; idof<fe.numDof(); ++idof) { | |
598 | ✗ | for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) { | |
599 | ✗ | tmpval2 = 0.0; | |
600 | ✗ | for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor) { | |
601 | ✗ | tmpval1 = 0.0; | |
602 | ✗ | for(felInt jdof=0; jdof<fe.numDof(); ++jdof) { | |
603 | ✗ | tmpval1 += vec2.val(iComp, jdof) * fe.dPhi[ig](icoor, jdof); | |
604 | } | ||
605 | ✗ | tmpval2 += tmpval1 * vec1.val(icoor, 0); | |
606 | } | ||
607 | ✗ | vec(idof) += tmpval2 * coef * fe.phi[ig](idof) * fe.weightMeas(ig); | |
608 | } | ||
609 | } | ||
610 | } | ||
611 | ✗ | break; | |
612 | } | ||
613 | } | ||
614 | |||
615 | /***********************************************************************************/ | ||
616 | /***********************************************************************************/ | ||
617 | |||
618 | 4112 | void ElementVector::eps_vec2_dot_vec1_dot_phi_i(const double coef, const ElementField& vec1, const ElementField& vec2, const CurrentFiniteElement& fe, const int iblock, const int numComp) | |
619 | { | ||
620 | // Not implemented for other type yet | ||
621 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4112 times.
|
4112 | FEL_ASSERT(vec1.type() == CONSTANT_FIELD); |
622 | |||
623 | double tmpval1, tmpval2; | ||
624 | |||
625 |
1/4✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4112 times.
✗ Branch 4 not taken.
|
4112 | switch(vec2.type()) { |
626 | ✗ | case CONSTANT_FIELD: | |
627 | // nothing to do | ||
628 | ✗ | break; | |
629 | |||
630 | ✗ | case QUAD_POINT_FIELD: | |
631 | // cannot compute the derivative of vec2 at integration points | ||
632 | ✗ | FEL_ERROR("eps_vec2_dot_vec1_dot_phi_i does not work with vec2 defined at integration points"); | |
633 | break; | ||
634 | |||
635 | 4112 | case DOF_FIELD: | |
636 |
2/2✓ Branch 0 taken 8224 times.
✓ Branch 1 taken 4112 times.
|
12336 | for(felInt iComp=0; iComp<numComp; ++iComp) { |
637 |
1/2✓ Branch 1 taken 8224 times.
✗ Branch 2 not taken.
|
8224 | UBlasVectorRange vec = vecBlock(iblock + iComp); |
638 |
2/2✓ Branch 1 taken 24672 times.
✓ Branch 2 taken 8224 times.
|
32896 | for(felInt idof=0; idof<fe.numDof(); ++idof) { |
639 |
2/2✓ Branch 1 taken 74016 times.
✓ Branch 2 taken 24672 times.
|
98688 | for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) { |
640 | 74016 | tmpval2 = 0.0; | |
641 |
2/2✓ Branch 1 taken 148032 times.
✓ Branch 2 taken 74016 times.
|
222048 | for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor) { |
642 | 148032 | tmpval1 = 0.0; | |
643 |
2/2✓ Branch 1 taken 444096 times.
✓ Branch 2 taken 148032 times.
|
592128 | for(felInt jdof=0; jdof<fe.numDof(); ++jdof) { |
644 |
2/4✓ Branch 1 taken 444096 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 444096 times.
✗ Branch 6 not taken.
|
444096 | tmpval1 += vec2.val(iComp, jdof) * fe.dPhi[ig](icoor, jdof); |
645 |
2/4✓ Branch 1 taken 444096 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 444096 times.
✗ Branch 6 not taken.
|
444096 | tmpval1 += vec2.val(icoor, jdof) * fe.dPhi[ig](iComp, jdof); |
646 | } | ||
647 |
1/2✓ Branch 1 taken 148032 times.
✗ Branch 2 not taken.
|
148032 | tmpval2 += tmpval1 * vec1.val(icoor, 0); |
648 | } | ||
649 |
3/6✓ Branch 2 taken 74016 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 74016 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 74016 times.
✗ Branch 9 not taken.
|
74016 | vec(idof) += tmpval2 * 0.5 * coef * fe.phi[ig](idof) * fe.weightMeas(ig); |
650 | } | ||
651 | } | ||
652 | 8224 | } | |
653 | 4112 | break; | |
654 | } | ||
655 | 4112 | } | |
656 | |||
657 | /***********************************************************************************/ | ||
658 | /***********************************************************************************/ | ||
659 | |||
660 | ✗ | void ElementVector::grad_phi_i_dot_vec1_dot_vec2(const double coef, const ElementField& vec1, const ElementField& vec2, const CurrentFiniteElement& fe, const int iblock, const int numComp) | |
661 | { | ||
662 | // Not implemented for other type yet | ||
663 | ✗ | FEL_ASSERT(vec1.type() == CONSTANT_FIELD); | |
664 | |||
665 | double vecval; | ||
666 | |||
667 | ✗ | switch(vec2.type()) { | |
668 | ✗ | case CONSTANT_FIELD: | |
669 | ✗ | for(felInt iComp=0; iComp<numComp; ++iComp) { | |
670 | ✗ | UBlasVectorRange vec = vecBlock(iblock + iComp); | |
671 | ✗ | for(felInt idof=0; idof<fe.numDof(); ++idof) { | |
672 | ✗ | for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) { | |
673 | ✗ | for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor) { | |
674 | ✗ | vec(idof) += coef * fe.weightMeas(ig) * vec2.val(iComp, 0) * fe.dPhi[ig](icoor, idof) * vec1.val(icoor, 0); | |
675 | } | ||
676 | } | ||
677 | } | ||
678 | } | ||
679 | ✗ | break; | |
680 | |||
681 | ✗ | case QUAD_POINT_FIELD: | |
682 | ✗ | for(felInt iComp=0; iComp<numComp; ++iComp) { | |
683 | ✗ | UBlasVectorRange vec = vecBlock(iblock + iComp); | |
684 | ✗ | for(felInt idof=0; idof<fe.numDof(); ++idof) { | |
685 | ✗ | for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) { | |
686 | ✗ | for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor) { | |
687 | ✗ | vec(idof) += coef * fe.weightMeas(ig) * vec2.val(iComp, ig) * fe.dPhi[ig](icoor, idof) * vec1.val(icoor, 0); | |
688 | } | ||
689 | } | ||
690 | } | ||
691 | } | ||
692 | ✗ | break; | |
693 | |||
694 | ✗ | case DOF_FIELD: | |
695 | ✗ | for(felInt iComp=0; iComp<numComp; ++iComp) { | |
696 | ✗ | UBlasVectorRange vec = vecBlock(iblock + iComp); | |
697 | ✗ | for(felInt idof=0; idof<fe.numDof(); ++idof) { | |
698 | ✗ | for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) { | |
699 | ✗ | vecval = 0.0; | |
700 | ✗ | for(felInt kdof=0; kdof<fe.numDof(); ++kdof) | |
701 | ✗ | vecval += vec2.val(iComp, kdof) * fe.phi[ig](kdof); | |
702 | |||
703 | ✗ | for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor) { | |
704 | ✗ | vec(idof) += coef * fe.weightMeas(ig) * vecval * fe.dPhi[ig](icoor, idof) * vec1.val(icoor, 0); | |
705 | } | ||
706 | } | ||
707 | } | ||
708 | } | ||
709 | |||
710 | ✗ | break; | |
711 | } | ||
712 | } | ||
713 | |||
714 | /***********************************************************************************/ | ||
715 | /***********************************************************************************/ | ||
716 | |||
717 | 4112 | void ElementVector::eps_phi_i_dot_vec1_dot_vec2(const double coef, const ElementField& vec1, const ElementField& vec2, const CurrentFiniteElement& fe, const int iblock, const int numComp) | |
718 | { | ||
719 | // not implemented for other type yet | ||
720 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4112 times.
|
4112 | FEL_ASSERT(vec1.type() == CONSTANT_FIELD); |
721 | |||
722 | double vecvalComp, vecvalCoor; | ||
723 | |||
724 |
1/4✗ Branch 1 not taken.
✓ Branch 2 taken 4112 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
4112 | switch(vec2.type()) { |
725 | ✗ | case CONSTANT_FIELD: | |
726 | ✗ | for(felInt iComp=0; iComp<numComp; ++iComp) { | |
727 | ✗ | UBlasVectorRange vec = vecBlock(iblock + iComp); | |
728 | ✗ | for(felInt idof=0; idof<fe.numDof(); ++idof) { | |
729 | ✗ | for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) { | |
730 | ✗ | for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor) { | |
731 | ✗ | vec(idof) += 0.5 * coef * fe.weightMeas(ig) * vec2.val(iComp, 0) * fe.dPhi[ig](icoor, idof) * vec1.val(icoor, 0); | |
732 | ✗ | vec(idof) += 0.5 * coef * fe.weightMeas(ig) * vec1.val(iComp, 0) * fe.dPhi[ig](icoor, idof) * vec2.val(icoor, 0); | |
733 | } | ||
734 | } | ||
735 | } | ||
736 | } | ||
737 | ✗ | break; | |
738 | |||
739 | 4112 | case QUAD_POINT_FIELD: | |
740 |
2/2✓ Branch 0 taken 8224 times.
✓ Branch 1 taken 4112 times.
|
12336 | for(felInt iComp=0; iComp<numComp; ++iComp) { |
741 |
1/2✓ Branch 1 taken 8224 times.
✗ Branch 2 not taken.
|
8224 | UBlasVectorRange vec = vecBlock(iblock + iComp); |
742 |
2/2✓ Branch 1 taken 24672 times.
✓ Branch 2 taken 8224 times.
|
32896 | for(felInt idof=0; idof<fe.numDof(); ++idof) { |
743 |
2/2✓ Branch 1 taken 74016 times.
✓ Branch 2 taken 24672 times.
|
98688 | for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) { |
744 |
2/2✓ Branch 1 taken 148032 times.
✓ Branch 2 taken 74016 times.
|
222048 | for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor) { |
745 |
5/10✓ Branch 1 taken 148032 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 148032 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 148032 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 148032 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 148032 times.
✗ Branch 15 not taken.
|
148032 | vec(idof) += 0.5 * coef * fe.weightMeas(ig) * vec2.val(iComp, ig) * fe.dPhi[ig](icoor, idof) * vec1.val(icoor, 0); |
746 |
5/10✓ Branch 1 taken 148032 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 148032 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 148032 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 148032 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 148032 times.
✗ Branch 15 not taken.
|
148032 | vec(idof) += 0.5 * coef * fe.weightMeas(ig) * vec1.val(iComp, 0) * fe.dPhi[ig](icoor, idof) * vec2.val(icoor, ig); |
747 | } | ||
748 | } | ||
749 | } | ||
750 | 8224 | } | |
751 | 4112 | break; | |
752 | |||
753 | ✗ | case DOF_FIELD: | |
754 | ✗ | for(felInt iComp=0; iComp<numComp; ++iComp) { | |
755 | ✗ | UBlasVectorRange vec = vecBlock(iblock + iComp); | |
756 | ✗ | for(felInt idof=0; idof<fe.numDof(); ++idof) { | |
757 | ✗ | for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) { | |
758 | ✗ | vecvalComp = 0.0; | |
759 | ✗ | for(felInt kdof=0; kdof<fe.numDof(); ++kdof) | |
760 | ✗ | vecvalComp += vec2.val(iComp, kdof) * fe.phi[ig](kdof); | |
761 | |||
762 | ✗ | for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor) { | |
763 | ✗ | vecvalCoor = 0.0; | |
764 | ✗ | for(felInt kdof=0; kdof<fe.numDof(); ++kdof) | |
765 | ✗ | vecvalCoor += vec2.val(icoor, kdof) * fe.phi[ig](kdof); | |
766 | |||
767 | ✗ | vec(idof) += 0.5 * coef * fe.weightMeas(ig) * vecvalComp * fe.dPhi[ig](icoor, idof) * vec1.val(icoor, 0); | |
768 | ✗ | vec(idof) += 0.5 * coef * fe.weightMeas(ig) * vec1.val(iComp, 0) * fe.dPhi[ig](icoor, idof) * vecvalCoor; | |
769 | } | ||
770 | } | ||
771 | } | ||
772 | } | ||
773 | |||
774 | ✗ | break; | |
775 | } | ||
776 | 4112 | } | |
777 | |||
778 | /***********************************************************************************/ | ||
779 | /***********************************************************************************/ | ||
780 | |||
781 | ✗ | void ElementVector::eps_vec2_vec1_dot_eps_phi_i_vec1(const double coef, const ElementField& vec1, const ElementField& vec2, const CurrentFiniteElement& fe, const int iblock, const int numComp) | |
782 | { | ||
783 | // not implemented for other type yet | ||
784 | ✗ | FEL_ASSERT(vec1.type() == CONSTANT_FIELD); | |
785 | |||
786 | double tmpval1, tmpval2; | ||
787 | |||
788 | ✗ | switch(vec2.type()) { | |
789 | ✗ | case CONSTANT_FIELD: | |
790 | // nothing to do | ||
791 | ✗ | break; | |
792 | |||
793 | ✗ | case QUAD_POINT_FIELD: | |
794 | // cannot compute the derivative of vec2 at integration points | ||
795 | ✗ | FEL_ERROR("eps_vec2_dot_vec1_dot_phi_i does not work with vec2 defined at integration points"); | |
796 | break; | ||
797 | |||
798 | ✗ | case DOF_FIELD: | |
799 | ✗ | for(felInt iComp=0; iComp<numComp; ++iComp) { | |
800 | ✗ | UBlasVectorRange vec = vecBlock(iblock + iComp); | |
801 | ✗ | for(felInt idof=0; idof<fe.numDof(); ++idof) { | |
802 | ✗ | for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) { | |
803 | ✗ | tmpval2 = 0.0; | |
804 | ✗ | for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor) { | |
805 | ✗ | tmpval1 = 0.0; | |
806 | ✗ | for(felInt jdof=0; jdof<fe.numDof(); ++jdof) { | |
807 | ✗ | tmpval1 += vec2.val(iComp, jdof) * fe.dPhi[ig](icoor, jdof); | |
808 | ✗ | tmpval1 += vec2.val(icoor, jdof) * fe.dPhi[ig](iComp, jdof); | |
809 | } | ||
810 | ✗ | tmpval2 += tmpval1 * vec1.val(icoor, 0); | |
811 | } | ||
812 | |||
813 | ✗ | for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor) { | |
814 | ✗ | vec(idof) += 0.25 * coef * fe.weightMeas(ig) * tmpval2 * fe.dPhi[ig](icoor, idof) * vec1.val(icoor, 0); | |
815 | ✗ | vec(idof) += 0.25 * coef * fe.weightMeas(ig) * vec1.val(iComp, 0) * fe.dPhi[ig](icoor, idof) * tmpval2; | |
816 | } | ||
817 | } | ||
818 | } | ||
819 | } | ||
820 | ✗ | break; | |
821 | } | ||
822 | } | ||
823 | |||
824 | /***********************************************************************************/ | ||
825 | /***********************************************************************************/ | ||
826 | |||
827 | ✗ | void ElementVector::grad_vec2_vec1_dot_grad_phi_i_vec1(const double coef, const ElementField& vec1, const ElementField& vec2, const CurrentFiniteElement& fe, const int iblock, const int numComp) | |
828 | { | ||
829 | // not implemented for other type yet | ||
830 | ✗ | FEL_ASSERT(vec1.type() == CONSTANT_FIELD); | |
831 | |||
832 | double tmpval1, tmpval2; | ||
833 | |||
834 | ✗ | switch(vec2.type()) { | |
835 | ✗ | case CONSTANT_FIELD: | |
836 | // nothing to do | ||
837 | ✗ | break; | |
838 | |||
839 | ✗ | case QUAD_POINT_FIELD: | |
840 | // cannot compute the derivative of vec2 at integration points | ||
841 | ✗ | FEL_ERROR("grad_vec2_dot_vec1_dot_phi_i does not work with vec2 defined at integration points"); | |
842 | break; | ||
843 | |||
844 | ✗ | case DOF_FIELD: | |
845 | ✗ | for(felInt iComp=0; iComp<numComp; ++iComp) { | |
846 | ✗ | UBlasVectorRange vec = vecBlock(iblock + iComp); | |
847 | ✗ | for(felInt idof=0; idof<fe.numDof(); ++idof) { | |
848 | ✗ | for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) { | |
849 | ✗ | tmpval2 = 0.0; | |
850 | ✗ | for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor) { | |
851 | ✗ | tmpval1 = 0.0; | |
852 | ✗ | for(felInt jdof=0; jdof<fe.numDof(); ++jdof) { | |
853 | ✗ | tmpval1 += vec2.val(iComp, jdof) * fe.dPhi[ig](icoor, jdof); | |
854 | } | ||
855 | ✗ | tmpval2 += tmpval1 * vec1.val(icoor, 0); | |
856 | } | ||
857 | |||
858 | ✗ | for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor) { | |
859 | ✗ | vec(idof) += coef * fe.weightMeas(ig) * tmpval2 * fe.dPhi[ig](icoor, idof) * vec1.val(icoor, 0); | |
860 | } | ||
861 | } | ||
862 | } | ||
863 | } | ||
864 | ✗ | break; | |
865 | } | ||
866 | } | ||
867 | |||
868 | /***********************************************************************************/ | ||
869 | /***********************************************************************************/ | ||
870 | |||
871 | ✗ | void ElementVector::grad_phi_i_dot_n_f(const double coef,const CurrentFiniteElementWithBd& fewbd, | |
872 | const ElementField& elfield, | ||
873 | const int iblockBd, const int numblockBd, | ||
874 | const int iblock, const int numComp) | ||
875 | { | ||
876 | ✗ | FEL_ASSERT(iblockBd>=0 && iblockBd<fewbd.numBdEle() && (numblockBd-iblockBd) <= fewbd.numBdEle() ); | |
877 | ✗ | FEL_ASSERT(static_cast<int>(m_tmpVecDof.size()) == fewbd.numDof() ); | |
878 | |||
879 | double tmp; | ||
880 | ✗ | switch(elfield.type()) { | |
881 | ✗ | case CONSTANT_FIELD: | |
882 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
883 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
884 | ✗ | for (int ibd=iblockBd; ibd<iblockBd+numblockBd; ibd++) { | |
885 | ✗ | FEL_ASSERT( fewbd.bdEle(ibd).hasNormal() && fewbd.hasFirstDeriv() ); | |
886 | ✗ | for(int ilocg=0; ilocg<fewbd.numQuadPointBdEle(ibd); ilocg++) { | |
887 | ✗ | int ig = ilocg+fewbd.indexQuadPoint(ibd+1); | |
888 | // face ibd starts at ibd+1 (0 for internal quad points) | ||
889 | //! Vector = [n \cdot \grad \phi]: | ||
890 | ✗ | m_tmpVecDof = prod(trans(fewbd.bdEle(ibd).normal[ilocg]), fewbd.dPhi[ig]); | |
891 | ✗ | tmp = coef * elfield.val(icomp,0) * fewbd.bdEle(ibd).weightMeas(ilocg); | |
892 | ✗ | for(int idof=0; idof<fewbd.numDof(); idof++) { | |
893 | // dphi_1/dn(idof) * f: | ||
894 | ✗ | vec(idof) += tmp * m_tmpVecDof(idof); | |
895 | } | ||
896 | } | ||
897 | } | ||
898 | } | ||
899 | ✗ | break; | |
900 | ✗ | case QUAD_POINT_FIELD: | |
901 | ✗ | FEL_ASSERT( elfield.val.size2() == (std::size_t) fewbd.numQuadraturePointInternAndBd() ); //build the elfield from currentFEwBd | |
902 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
903 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
904 | ✗ | for (int ibd=iblockBd; ibd<iblockBd+numblockBd; ibd++) { | |
905 | ✗ | FEL_ASSERT( fewbd.bdEle(ibd).hasNormal() && fewbd.hasFirstDeriv() ); | |
906 | ✗ | for(int ilocg=0; ilocg<fewbd.numQuadPointBdEle(ibd); ilocg++) { | |
907 | ✗ | int ig = ilocg+fewbd.indexQuadPoint(ibd+1); | |
908 | // face ibd starts at ibd+1 (0 for internal quad points) | ||
909 | //! Vector = [n \cdot \grad \phi]: | ||
910 | ✗ | m_tmpVecDof = prod(trans(fewbd.bdEle(ibd).normal[ilocg]), fewbd.dPhi[ig]); | |
911 | ✗ | tmp = coef * elfield.val(icomp,ig) * fewbd.bdEle(ibd).weightMeas(ilocg); | |
912 | ✗ | for(int idof=0; idof<fewbd.numDof(); idof++) { | |
913 | // dphi_1/dn(idof) * f: | ||
914 | ✗ | vec(idof) += tmp * m_tmpVecDof(idof); | |
915 | } | ||
916 | } | ||
917 | } | ||
918 | } | ||
919 | ✗ | break; | |
920 | ✗ | case DOF_FIELD: | |
921 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
922 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
923 | ✗ | for (int ibd=iblockBd; ibd<iblockBd+numblockBd; ibd++) { | |
924 | ✗ | FEL_ASSERT( fewbd.bdEle(ibd).hasNormal() && fewbd.hasFirstDeriv() ); | |
925 | ✗ | for(int ilocg=0; ilocg<fewbd.numQuadPointBdEle(ibd); ilocg++) { | |
926 | ✗ | int ig = ilocg+fewbd.indexQuadPoint(ibd+1); | |
927 | // face ibd starts at ibd+1 (0 for internal quad points) | ||
928 | //! Vector = [n \cdot \grad \phi]: | ||
929 | ✗ | m_tmpVecDof = prod(trans(fewbd.bdEle(ibd).normal[ilocg]), fewbd.dPhi[ig]); | |
930 | |||
931 | ✗ | tmp = 0.0; | |
932 | ✗ | for(int idof=0; idof<fewbd.numDof(); idof++) { | |
933 | ✗ | tmp += fewbd.phi[ig](idof) * elfield.val(icomp,idof) * fewbd.bdEle(ibd).weightMeas(ilocg); | |
934 | } | ||
935 | ✗ | for(int idof=0; idof<fewbd.numDof(); idof++) { | |
936 | // dphi_1/dn(idof) * f: | ||
937 | ✗ | vec(idof) += coef * tmp * m_tmpVecDof(idof); | |
938 | } | ||
939 | } | ||
940 | } | ||
941 | } | ||
942 | ✗ | break; | |
943 | // Default case should appear with a warning at compile time instead of an error in runtime | ||
944 | // (that's truly the point of using enums as switch cases) | ||
945 | // default: | ||
946 | // FEL_ERROR("Operator 'grad_phi_i_dot_n_f' not yet implemented with this type of element fields"); | ||
947 | } | ||
948 | } | ||
949 | |||
950 | /***********************************************************************************/ | ||
951 | /***********************************************************************************/ | ||
952 | |||
953 | ✗ | void ElementVector::grad_f_dot_n_phi_i(const double coef,const CurrentFiniteElementWithBd& fewbd, | |
954 | const ElementField& elfield, | ||
955 | const int iblockBd, const int numblockBd, | ||
956 | const int iblock, const int numComp) | ||
957 | { | ||
958 | ✗ | FEL_ASSERT(iblockBd>=0 && iblockBd<fewbd.numBdEle() && (numblockBd-iblockBd) <= fewbd.numBdEle() ); | |
959 | ✗ | FEL_ASSERT( static_cast<int>(m_tmpVecDof.size()) == fewbd.numDof() ); | |
960 | |||
961 | double tmp; | ||
962 | ✗ | switch(elfield.type()) { | |
963 | ✗ | case CONSTANT_FIELD: | |
964 | // add nothing: grad cst = 0 | ||
965 | ✗ | break; | |
966 | ✗ | case QUAD_POINT_FIELD: | |
967 | ✗ | FEL_ERROR("Operator 'grad_f_dot_n_phi_i' is not well defined for quad_point_field: how to compute grad f ??"); | |
968 | break; | ||
969 | ✗ | case DOF_FIELD: | |
970 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
971 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
972 | ✗ | for (int ibd=iblockBd; ibd<iblockBd+numblockBd; ibd++) { | |
973 | ✗ | FEL_ASSERT( fewbd.bdEle(ibd).hasNormal() && fewbd.hasFirstDeriv() ); | |
974 | ✗ | for(int ilocg=0; ilocg<fewbd.numQuadPointBdEle(ibd); ilocg++) { | |
975 | ✗ | int ig = ilocg+fewbd.indexQuadPoint(ibd+1); | |
976 | // face ibd starts at ibd+1 (0 for internal quad points) | ||
977 | //! Vector = [n \cdot \grad \phi]: | ||
978 | ✗ | m_tmpVecDof = prod(trans(fewbd.bdEle(ibd).normal[ilocg]), fewbd.dPhi[ig]); | |
979 | ✗ | tmp = 0.0; | |
980 | ✗ | for(int jdof=0; jdof<fewbd.numDof(); jdof++) { | |
981 | //! tmp = [n \cdot \grad f] = \sum f_jdof (grad phi_jdof \cdot n) | ||
982 | ✗ | tmp += m_tmpVecDof(jdof) * elfield.val(icomp,jdof); | |
983 | } | ||
984 | ✗ | tmp *= coef * fewbd.bdEle(ibd).weightMeas(ilocg); | |
985 | ✗ | for(int idof=0; idof<fewbd.bdEle(ibd).numDof(); idof++) { | |
986 | //! df/dn *phi(idof): | ||
987 | ✗ | vec(idof) += tmp * fewbd.bdEle(ibd).phi[ilocg](idof); | |
988 | } | ||
989 | } | ||
990 | } | ||
991 | } | ||
992 | ✗ | break; | |
993 | // Default case should appear with a warning at compile time instead of an error in runtime | ||
994 | // (that's truly the point of using enums as switch cases) | ||
995 | // default: | ||
996 | // FEL_ERROR("Operator 'grad_f_dot_n_phi_i' not yet implemented with this type of element fields"); | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | /***********************************************************************************/ | ||
1001 | /***********************************************************************************/ | ||
1002 | |||
1003 | //---------------------------------------------------------------------- | ||
1004 | // Operators \f$ \int_{\Sigma} (\grad f^T \dot n) \phi_i \f$,// shoudl be teseted !!!! saverio 8/10/2012 | ||
1005 | //! where $\Sigma$ is a boundary element. (For Nitsche's treatment...) | ||
1006 | ✗ | void ElementVector::grad_f_Transp_dot_n_phi_i(const double coef,const CurrentFiniteElementWithBd& fewbd, | |
1007 | const ElementField& elfield, | ||
1008 | const int iblockBd, const int numblockBd, | ||
1009 | const int iblock, const int numComp) | ||
1010 | { | ||
1011 | ✗ | FEL_ASSERT(iblockBd>=0 && iblockBd<fewbd.numBdEle() && (numblockBd-iblockBd) <= fewbd.numBdEle() ); | |
1012 | ✗ | FEL_ASSERT( static_cast<int>(m_tmpVecDof.size()) == fewbd.numDof() ); | |
1013 | ✗ | FEL_ASSERT( (int)m_tmpVecComp.size() == fewbd.numCoor()); | |
1014 | double tmp; | ||
1015 | ✗ | switch(elfield.type()) { | |
1016 | ✗ | case CONSTANT_FIELD: | |
1017 | // add nothing: grad cst = 0 | ||
1018 | ✗ | break; | |
1019 | ✗ | case QUAD_POINT_FIELD: | |
1020 | ✗ | FEL_ERROR("Operator 'grad_f_Transp_dot_n_phi_i' is not well defined for quad_point_field: how to compute grad f ??"); | |
1021 | break; | ||
1022 | ✗ | case DOF_FIELD: | |
1023 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
1024 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
1025 | ✗ | for (int ibd=iblockBd; ibd<iblockBd+numblockBd; ibd++) { | |
1026 | ✗ | FEL_ASSERT( fewbd.bdEle(ibd).hasNormal() && fewbd.hasFirstDeriv() ); | |
1027 | ✗ | for(int ilocg=0; ilocg<fewbd.numQuadPointBdEle(ibd); ilocg++) { | |
1028 | ✗ | int ig = ilocg+fewbd.indexQuadPoint(ibd+1); | |
1029 | // face ibd starts at ibd+1 (0 for internal quad points) | ||
1030 | //! Matrix = grad \phi cdot f | ||
1031 | ✗ | m_tmpMatDof = prod(fewbd.dPhi[ig],trans(elfield.val)); | |
1032 | ✗ | m_tmpVecComp = prod(m_tmpMatDof, fewbd.bdEle(ibd).normal[ilocg]); | |
1033 | ✗ | tmp = 0.0; | |
1034 | //! tmp = [n \cdot \grad f] = \sum f_jdof (grad phi_jdof \cdot n) | ||
1035 | ✗ | tmp = m_tmpVecComp(icomp); | |
1036 | ✗ | tmp *= coef * fewbd.bdEle(ibd).weightMeas(ilocg); | |
1037 | ✗ | for(int idof=0; idof<fewbd.bdEle(ibd).numDof(); idof++) { | |
1038 | //! df/dn *phi(idof): | ||
1039 | ✗ | vec(idof) += tmp * fewbd.bdEle(ibd).phi[ilocg](idof); | |
1040 | } | ||
1041 | } | ||
1042 | } | ||
1043 | } | ||
1044 | ✗ | break; | |
1045 | // Default case should appear with a warning at compile time instead of an error in runtime | ||
1046 | // (that's truly the point of using enums as switch cases) | ||
1047 | // default: | ||
1048 | // FEL_ERROR("Operator 'grad_f_Transp_dot_n_phi_i' not yet implemented with this type of element fields"); | ||
1049 | } | ||
1050 | } | ||
1051 | |||
1052 | /***********************************************************************************/ | ||
1053 | /***********************************************************************************/ | ||
1054 | |||
1055 | ✗ | void ElementVector::f_dot_n_f_phi_i(const double coef,const CurvilinearFiniteElement& fe, | |
1056 | const ElementField& elfield1,const ElementField& elfield2, | ||
1057 | const int iblock, const int numComp) | ||
1058 | { | ||
1059 | ✗ | FEL_ASSERT(elfield1.type() != elfield2.type()); | |
1060 | double tmp1, tmp2, f_dot_n; | ||
1061 | ✗ | switch(elfield1.type()) { | |
1062 | ✗ | case CONSTANT_FIELD: | |
1063 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
1064 | ✗ | UBlasVectorRange vec = vecBlock( iblock+icomp ); | |
1065 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
1066 | ✗ | f_dot_n = 0.0; | |
1067 | ✗ | for(int icoor=0; icoor<fe.numCoor(); icoor++) { | |
1068 | ✗ | f_dot_n += elfield1.val(icoor,0)*fe.normal[ig](icoor); | |
1069 | } | ||
1070 | ✗ | tmp2 = elfield2.val(icomp,0) * fe.weightMeas(ig); | |
1071 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
1072 | ✗ | vec(idof) += coef * f_dot_n * tmp2 * fe.phi[ig](idof); | |
1073 | } | ||
1074 | } | ||
1075 | } | ||
1076 | ✗ | break; | |
1077 | ✗ | case QUAD_POINT_FIELD: | |
1078 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
1079 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
1080 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
1081 | ✗ | f_dot_n = 0.0; | |
1082 | ✗ | for(int icoor=0; icoor<fe.numCoor(); icoor++) { | |
1083 | ✗ | f_dot_n += elfield1.val(icoor,ig)*fe.normal[ig](icoor); | |
1084 | } | ||
1085 | ✗ | tmp2 = elfield2.val(icomp,ig) * fe.weightMeas(ig); | |
1086 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
1087 | ✗ | vec(idof) += coef * f_dot_n * tmp2 * fe.phi[ig](idof); | |
1088 | } | ||
1089 | } | ||
1090 | } | ||
1091 | ✗ | break; | |
1092 | ✗ | case DOF_FIELD: | |
1093 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
1094 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
1095 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
1096 | ✗ | tmp2 = 0.0; | |
1097 | ✗ | f_dot_n = 0.0; | |
1098 | ✗ | for(int icoor=0; icoor<fe.numCoor(); icoor++) { | |
1099 | ✗ | tmp1= 0.0; | |
1100 | ✗ | for(int jdof=0; jdof<fe.numDof(); jdof++) { | |
1101 | ✗ | tmp1 += fe.phi[ig](jdof) * elfield1.val(icoor,jdof); | |
1102 | } | ||
1103 | //! sum f_icoor * n_icoor | ||
1104 | ✗ | f_dot_n += tmp1 * fe.normal[ig](icoor); | |
1105 | } | ||
1106 | ✗ | for(int jdof=0; jdof<fe.numDof(); jdof++) { | |
1107 | ✗ | tmp2 += fe.phi[ig](jdof) * elfield2.val(icomp,jdof); | |
1108 | } | ||
1109 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
1110 | ✗ | vec(idof) += coef * f_dot_n * tmp2 * fe.phi[ig](idof) * fe.weightMeas(ig); | |
1111 | } | ||
1112 | } | ||
1113 | } | ||
1114 | ✗ | break; | |
1115 | // Default case should appear with a warning at compile time instead of an error in runtime | ||
1116 | // (that's truly the point of using enums as switch cases) | ||
1117 | // default: | ||
1118 | //FEL_ERROR("Operator 'f_dot_n_f_phi_i' not yet implemented with this type of element fields"); | ||
1119 | } | ||
1120 | } | ||
1121 | |||
1122 | /***********************************************************************************/ | ||
1123 | /***********************************************************************************/ | ||
1124 | |||
1125 | 2541420 | void ElementVector::grad_f_phi_i(const double coef, const CurrentFiniteElement& fe1,const CurrentFiniteElement& fe2,const ElementField& elfield2,const int iblock) | |
1126 | { | ||
1127 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 2541420 times.
|
2541420 | FEL_CHECK(fe1.numQuadraturePoint() == fe2.numQuadraturePoint(), |
1128 | "ElementVector::grad_f_phi_i: The quadrature rules must be the same for the two elements"); | ||
1129 | double tmp; | ||
1130 |
1/4✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2541420 times.
✗ Branch 4 not taken.
|
2541420 | switch(elfield2.type()) { |
1131 | ✗ | case CONSTANT_FIELD: | |
1132 | // add nothing: grad cst = 0 | ||
1133 | ✗ | break; | |
1134 | ✗ | case QUAD_POINT_FIELD: | |
1135 | ✗ | FEL_ERROR("ElementVector::grad_f_phi_i: Operator 'grad_f_phi_i' is not defined for quad_point_field: how to compute grad f ??"); | |
1136 | break; | ||
1137 | 2541420 | case DOF_FIELD: | |
1138 |
2/2✓ Branch 1 taken 7624260 times.
✓ Branch 2 taken 2541420 times.
|
10165680 | for (int icomp=0; icomp<fe1.numCoor(); icomp++) { |
1139 |
1/2✓ Branch 1 taken 7624260 times.
✗ Branch 2 not taken.
|
7624260 | UBlasVectorRange vec = vecBlock(iblock+icomp); |
1140 |
2/2✓ Branch 1 taken 30497040 times.
✓ Branch 2 taken 7624260 times.
|
38121300 | for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) { |
1141 | 30497040 | tmp = 0.0; | |
1142 |
2/2✓ Branch 1 taken 121988160 times.
✓ Branch 2 taken 30497040 times.
|
152485200 | for (int jdof=0; jdof<fe2.numDof(); jdof++) { |
1143 |
2/4✓ Branch 2 taken 121988160 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 121988160 times.
✗ Branch 6 not taken.
|
121988160 | tmp += fe2.dPhi[ig](icomp,jdof)*elfield2.val(0,jdof); |
1144 | } | ||
1145 |
1/2✓ Branch 1 taken 30497040 times.
✗ Branch 2 not taken.
|
30497040 | tmp *= coef * fe1.weightMeas(ig); |
1146 |
2/2✓ Branch 1 taken 121988160 times.
✓ Branch 2 taken 30497040 times.
|
152485200 | for(int idof=0; idof<fe1.numDof(); idof++) { |
1147 |
2/4✓ Branch 2 taken 121988160 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 121988160 times.
✗ Branch 6 not taken.
|
121988160 | vec(idof) += tmp * fe1.phi[ig](idof); |
1148 | } | ||
1149 | } | ||
1150 | 7624260 | } | |
1151 | 2541420 | break; | |
1152 | } | ||
1153 | 2541420 | } | |
1154 | |||
1155 | /***********************************************************************************/ | ||
1156 | /***********************************************************************************/ | ||
1157 | |||
1158 | ✗ | void ElementVector::curl_f_phi_i(const double coef, const CurrentFiniteElement& fe1,const CurrentFiniteElement& fe2,const ElementField& elfield2,const int iblock) | |
1159 | { | ||
1160 | ✗ | FEL_CHECK(fe1.numQuadraturePoint() == fe2.numQuadraturePoint(), "ElementVector::curl_f_phi_i: The quadrature rules must be the same for the two elements"); | |
1161 | ✗ | FEL_CHECK(fe1.numCoor() == 3, "ElementVector::curl_f_phi_i: curl not yet implemented in 2D"); | |
1162 | double tmp0,tmp1,tmp2; | ||
1163 | ✗ | switch(elfield2.type()) { | |
1164 | ✗ | case CONSTANT_FIELD: | |
1165 | // add nothing: curl cst = 0 | ||
1166 | ✗ | break; | |
1167 | ✗ | case QUAD_POINT_FIELD: | |
1168 | ✗ | FEL_ERROR("ElementVector::curl_f_phi_i: Operator 'curl_f_phi_i' is not defined for quad_point_field: how to compute curl f ??"); | |
1169 | break; | ||
1170 | ✗ | case DOF_FIELD: | |
1171 | ✗ | UBlasVectorRange vec0 = vecBlock(iblock+0); | |
1172 | ✗ | UBlasVectorRange vec1 = vecBlock(iblock+1); | |
1173 | ✗ | UBlasVectorRange vec2 = vecBlock(iblock+2); | |
1174 | ✗ | for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) { | |
1175 | ✗ | tmp0 = 0.0; | |
1176 | ✗ | tmp1 = 0.0; | |
1177 | ✗ | tmp2 = 0.0; | |
1178 | ✗ | for (int jdof=0; jdof<fe2.numDof(); jdof++) { | |
1179 | ✗ | tmp0 += fe2.dPhi[ig](1,jdof)*elfield2.val(2,jdof) - fe2.dPhi[ig](2,jdof)*elfield2.val(1,jdof); | |
1180 | ✗ | tmp1 += fe2.dPhi[ig](2,jdof)*elfield2.val(0,jdof) - fe2.dPhi[ig](0,jdof)*elfield2.val(2,jdof); | |
1181 | ✗ | tmp2 += fe2.dPhi[ig](0,jdof)*elfield2.val(1,jdof) - fe2.dPhi[ig](1,jdof)*elfield2.val(0,jdof); | |
1182 | } | ||
1183 | ✗ | tmp0 *= coef * fe1.weightMeas(ig); | |
1184 | ✗ | tmp1 *= coef * fe1.weightMeas(ig); | |
1185 | ✗ | tmp2 *= coef * fe1.weightMeas(ig); | |
1186 | ✗ | for(int idof=0; idof<fe1.numDof(); idof++) { | |
1187 | ✗ | vec0(idof) += tmp0 * fe1.phi[ig](idof); | |
1188 | ✗ | vec1(idof) += tmp1 * fe1.phi[ig](idof); | |
1189 | ✗ | vec2(idof) += tmp2 * fe1.phi[ig](idof); | |
1190 | } | ||
1191 | } | ||
1192 | ✗ | break; | |
1193 | } | ||
1194 | } | ||
1195 | |||
1196 | /***********************************************************************************/ | ||
1197 | /***********************************************************************************/ | ||
1198 | |||
1199 | ✗ | void ElementVector::WGX_dot_phi_i( const CurrentFiniteElement& feWGX, const CurrentFiniteElement& feWSS, const ElementField& WSSField, const int iblock) | |
1200 | { | ||
1201 | double tmp0,tmp1,tmp2; | ||
1202 | ✗ | switch(WSSField.type()) { | |
1203 | ✗ | case CONSTANT_FIELD: | |
1204 | // add nothing: curl cst = 0 | ||
1205 | ✗ | break; | |
1206 | ✗ | case QUAD_POINT_FIELD: | |
1207 | ✗ | FEL_ERROR("ElementVector : not defined for quad_point_field"); | |
1208 | break; | ||
1209 | ✗ | case DOF_FIELD: | |
1210 | ✗ | UBlasVectorRange vec0 = vecBlock(iblock+0); | |
1211 | ✗ | UBlasVectorRange vec1 = vecBlock(iblock+1); | |
1212 | ✗ | UBlasVectorRange vec2 = vecBlock(iblock+2); | |
1213 | ✗ | for(int ig=0; ig<feWGX.numQuadraturePoint(); ig++) { | |
1214 | |||
1215 | ✗ | tmp0 = 0.0; | |
1216 | ✗ | tmp1 = 0.0; | |
1217 | ✗ | tmp2 = 0.0; | |
1218 | |||
1219 | ✗ | for (int jdof=0; jdof<feWSS.numDof(); jdof++) { | |
1220 | //std::cout<<"test WGX "<<WSSField.val(0,jdof)<<" "<<WSSField.val(1,jdof)<<" "<<WSSField.val(2,jdof)<<"\r"; | ||
1221 | ✗ | tmp0 += feWSS.dPhi[ig](0,jdof)*WSSField.val(0,jdof)* feWGX.weightMeas(ig); | |
1222 | ✗ | tmp1 += feWSS.dPhi[ig](1,jdof)*WSSField.val(0,jdof)* feWGX.weightMeas(ig); | |
1223 | ✗ | tmp2 += feWSS.dPhi[ig](2,jdof)*WSSField.val(0,jdof)* feWGX.weightMeas(ig); | |
1224 | } | ||
1225 | |||
1226 | ✗ | for(int idof=0; idof<feWGX.numDof(); idof++) { | |
1227 | ✗ | vec0(idof) += tmp0 * feWGX.phi[ig](idof); | |
1228 | ✗ | vec1(idof) += tmp1 * feWGX.phi[ig](idof); | |
1229 | ✗ | vec2(idof) += tmp2 * feWGX.phi[ig](idof); | |
1230 | |||
1231 | } | ||
1232 | } | ||
1233 | ✗ | break; | |
1234 | } | ||
1235 | } | ||
1236 | |||
1237 | /***********************************************************************************/ | ||
1238 | /***********************************************************************************/ | ||
1239 | |||
1240 | ✗ | void ElementVector::WGY_dot_phi_i( const CurrentFiniteElement& feWGY, const CurrentFiniteElement& feWSS, const ElementField& WSSField, const int iblock) | |
1241 | { | ||
1242 | double tmp0,tmp1,tmp2; | ||
1243 | ✗ | switch(WSSField.type()) { | |
1244 | ✗ | case CONSTANT_FIELD: | |
1245 | // add nothing: curl cst = 0 | ||
1246 | ✗ | break; | |
1247 | ✗ | case QUAD_POINT_FIELD: | |
1248 | ✗ | FEL_ERROR("ElementVector : not defined for quad_point_field"); | |
1249 | break; | ||
1250 | ✗ | case DOF_FIELD: | |
1251 | ✗ | UBlasVectorRange vec0 = vecBlock(iblock+0); | |
1252 | ✗ | UBlasVectorRange vec1 = vecBlock(iblock+1); | |
1253 | ✗ | UBlasVectorRange vec2 = vecBlock(iblock+2); | |
1254 | ✗ | for(int ig=0; ig<feWGY.numQuadraturePoint(); ig++) { | |
1255 | |||
1256 | ✗ | tmp0 = 0.0; | |
1257 | ✗ | tmp1 = 0.0; | |
1258 | ✗ | tmp2 = 0.0; | |
1259 | |||
1260 | ✗ | for (int jdof=0; jdof<feWSS.numDof(); jdof++) { | |
1261 | //std::cout<<"test WGY "<<normalField.val(0,jdof)<<" "<<normalField.val(1,jdof)<<" "<<normalField.val(2,jdof)<<" "<<feWGY.weightMeas(ig)<<" "<<elfield_StressY.val(0,jdof)<<"\r"; | ||
1262 | ✗ | tmp0 += feWSS.dPhi[ig](0,jdof)*WSSField.val(1,jdof)*feWGY.weightMeas(ig); | |
1263 | ✗ | tmp1 += feWSS.dPhi[ig](1,jdof)*WSSField.val(1,jdof)*feWGY.weightMeas(ig); | |
1264 | ✗ | tmp2 += feWSS.dPhi[ig](2,jdof)*WSSField.val(1,jdof)*feWGY.weightMeas(ig); | |
1265 | |||
1266 | } | ||
1267 | |||
1268 | ✗ | for(int idof=0; idof<feWGY.numDof(); idof++) { | |
1269 | ✗ | vec0(idof) += tmp0 * feWGY.phi[ig](idof); | |
1270 | ✗ | vec1(idof) += tmp1 * feWGY.phi[ig](idof); | |
1271 | ✗ | vec2(idof) += tmp2 * feWGY.phi[ig](idof); | |
1272 | |||
1273 | } | ||
1274 | } | ||
1275 | ✗ | break; | |
1276 | } | ||
1277 | } | ||
1278 | |||
1279 | /***********************************************************************************/ | ||
1280 | /***********************************************************************************/ | ||
1281 | |||
1282 | ✗ | void ElementVector::WGZ_dot_phi_i( const CurrentFiniteElement& feWGZ, const CurrentFiniteElement& feWSS, const ElementField& WSSField, const int iblock) | |
1283 | { | ||
1284 | double tmp0,tmp1,tmp2; | ||
1285 | ✗ | switch(WSSField.type()) { | |
1286 | ✗ | case CONSTANT_FIELD: | |
1287 | // add nothing: curl cst = 0 | ||
1288 | ✗ | break; | |
1289 | ✗ | case QUAD_POINT_FIELD: | |
1290 | ✗ | FEL_ERROR("ElementVector : not defined for quad_point_field"); | |
1291 | break; | ||
1292 | ✗ | case DOF_FIELD: | |
1293 | ✗ | UBlasVectorRange vec0 = vecBlock(iblock+0); | |
1294 | ✗ | UBlasVectorRange vec1 = vecBlock(iblock+1); | |
1295 | ✗ | UBlasVectorRange vec2 = vecBlock(iblock+2); | |
1296 | ✗ | for(int ig=0; ig<feWGZ.numQuadraturePoint(); ig++) { | |
1297 | |||
1298 | ✗ | tmp0 = 0.0; | |
1299 | ✗ | tmp1 = 0.0; | |
1300 | ✗ | tmp2 = 0.0; | |
1301 | |||
1302 | ✗ | for (int jdof=0; jdof<feWSS.numDof(); jdof++) { | |
1303 | //std::cout<<"test WGZ "<<normalField.val(0,jdof)<<" "<<normalField.val(1,jdof)<<" "<<normalField.val(2,jdof)<<" "<<feWGZ.weightMeas(ig)<<" "<<elfield_StressZ.val(0,jdof)<<"\r"; | ||
1304 | ✗ | tmp0 += feWSS.dPhi[ig](0,jdof)*WSSField.val(2,jdof)*feWGZ.weightMeas(ig); | |
1305 | ✗ | tmp1 += feWSS.dPhi[ig](1,jdof)*WSSField.val(2,jdof)*feWGZ.weightMeas(ig); | |
1306 | ✗ | tmp2 += feWSS.dPhi[ig](2,jdof)*WSSField.val(2,jdof)*feWGZ.weightMeas(ig); | |
1307 | } | ||
1308 | |||
1309 | ✗ | for(int idof=0; idof<feWGZ.numDof(); idof++) { | |
1310 | ✗ | vec0(idof) += tmp0 * feWGZ.phi[ig](idof); | |
1311 | ✗ | vec1(idof) += tmp1 * feWGZ.phi[ig](idof); | |
1312 | ✗ | vec2(idof) += tmp2 * feWGZ.phi[ig](idof); | |
1313 | } | ||
1314 | } | ||
1315 | ✗ | break; | |
1316 | } | ||
1317 | } | ||
1318 | |||
1319 | /***********************************************************************************/ | ||
1320 | /***********************************************************************************/ | ||
1321 | |||
1322 | ✗ | void ElementVector::stressX_dot_phi_i(const double viscosity, const CurrentFiniteElement& fePres,const CurrentFiniteElement& feStress,const CurrentFiniteElement& feVel,const ElementField& elfield_pressure,const ElementField& elfield_velocity,const int iblock) | |
1323 | { | ||
1324 | ✗ | FEL_CHECK(feStress.numQuadraturePoint() == feVel.numQuadraturePoint(), "ElementVector::stressX_dot_phi_i: The quadrature rules must be the same for all the elements"); | |
1325 | ✗ | FEL_CHECK(feStress.numCoor() == 3, "ElementVector::stressX_dot_phi_i: not yet implemented in 2D"); | |
1326 | double tmp0,tmp1,tmp2; | ||
1327 | ✗ | switch(elfield_velocity.type()) { | |
1328 | ✗ | case CONSTANT_FIELD: | |
1329 | // add nothing: curl cst = 0 | ||
1330 | ✗ | break; | |
1331 | ✗ | case QUAD_POINT_FIELD: | |
1332 | ✗ | FEL_ERROR("ElementVector::curl_f_phi_i: Operator 'stressX_dot_phi_i' is not defined for quad_point_field"); | |
1333 | break; | ||
1334 | ✗ | case DOF_FIELD: | |
1335 | ✗ | UBlasVectorRange vec0 = vecBlock(iblock+0); | |
1336 | ✗ | UBlasVectorRange vec1 = vecBlock(iblock+1); | |
1337 | ✗ | UBlasVectorRange vec2 = vecBlock(iblock+2); | |
1338 | ✗ | for(int ig=0; ig<feStress.numQuadraturePoint(); ig++) { | |
1339 | ✗ | tmp0 = 0.0; | |
1340 | ✗ | tmp1 = 0.0; | |
1341 | ✗ | tmp2 = 0.0; | |
1342 | ✗ | for (int jdof=0; jdof<feVel.numDof(); jdof++) { | |
1343 | ✗ | tmp0 += -elfield_pressure.val(0,jdof) * fePres.phi[ig](jdof) + 2*viscosity*feVel.dPhi[ig](0,jdof)*elfield_velocity.val(0,jdof); | |
1344 | ✗ | tmp1 += feVel.dPhi[ig](1,jdof)*elfield_velocity.val(0,jdof) + feVel.dPhi[ig](0,jdof)*elfield_velocity.val(1,jdof); | |
1345 | ✗ | tmp2 += feVel.dPhi[ig](2,jdof)*elfield_velocity.val(0,jdof) + feVel.dPhi[ig](0,jdof)*elfield_velocity.val(2,jdof); | |
1346 | } | ||
1347 | ✗ | tmp0 *= feStress.weightMeas(ig); | |
1348 | ✗ | tmp1 *= viscosity * feStress.weightMeas(ig); | |
1349 | ✗ | tmp2 *= viscosity * feStress.weightMeas(ig); | |
1350 | ✗ | for(int idof=0; idof<feStress.numDof(); idof++) { | |
1351 | ✗ | vec0(idof) += tmp0 * feStress.phi[ig](idof); | |
1352 | ✗ | vec1(idof) += tmp1 * feStress.phi[ig](idof); | |
1353 | ✗ | vec2(idof) += tmp2 * feStress.phi[ig](idof); | |
1354 | } | ||
1355 | } | ||
1356 | ✗ | break; | |
1357 | } | ||
1358 | } | ||
1359 | |||
1360 | /***********************************************************************************/ | ||
1361 | /***********************************************************************************/ | ||
1362 | |||
1363 | ✗ | void ElementVector::stressY_dot_phi_i(const double viscosity, const CurrentFiniteElement& fePres, const CurrentFiniteElement& feStress,const CurrentFiniteElement& feVel,const ElementField& elfield_pressure,const ElementField& elfield_velocity,const int iblock) | |
1364 | { | ||
1365 | ✗ | FEL_CHECK(feStress.numQuadraturePoint() == feVel.numQuadraturePoint() && fePres.numQuadraturePoint() == feVel.numQuadraturePoint(), "ElementVector::stressY_dot_phi_i: The quadrature rules must be the same for all the elements"); | |
1366 | ✗ | FEL_CHECK(feStress.numCoor() == 3, "ElementVector::stressY_dot_phi_i: not yet implemented in 2D"); | |
1367 | double tmp0,tmp1,tmp2; | ||
1368 | ✗ | switch(elfield_velocity.type()) { | |
1369 | ✗ | case CONSTANT_FIELD: | |
1370 | // add nothing: curl cst = 0 | ||
1371 | ✗ | break; | |
1372 | ✗ | case QUAD_POINT_FIELD: | |
1373 | ✗ | FEL_ERROR("ElementVector::stressY_dot_phi_i: Operator 'stressY_dot_phi_i' is not defined for quad_point_field: how to compute curl f ??"); | |
1374 | break; | ||
1375 | ✗ | case DOF_FIELD: | |
1376 | ✗ | UBlasVectorRange vec0 = vecBlock(iblock+0); | |
1377 | ✗ | UBlasVectorRange vec1 = vecBlock(iblock+1); | |
1378 | ✗ | UBlasVectorRange vec2 = vecBlock(iblock+2); | |
1379 | ✗ | for(int ig=0; ig<feStress.numQuadraturePoint(); ig++) { | |
1380 | ✗ | tmp0 = 0.0; | |
1381 | ✗ | tmp1 = 0.0; | |
1382 | ✗ | tmp2 = 0.0; | |
1383 | ✗ | for (int jdof=0; jdof<feVel.numDof(); jdof++) { | |
1384 | ✗ | tmp0 += feVel.dPhi[ig](1,jdof)*elfield_velocity.val(0,jdof) + feVel.dPhi[ig](0,jdof)*elfield_velocity.val(1,jdof); | |
1385 | ✗ | tmp1 += -elfield_pressure.val(0,jdof) * fePres.phi[ig](jdof) + 2 * viscosity * feVel.dPhi[ig](1,jdof)*elfield_velocity.val(1,jdof); | |
1386 | ✗ | tmp2 += feVel.dPhi[ig](2,jdof)*elfield_velocity.val(1,jdof) + feVel.dPhi[ig](1,jdof)*elfield_velocity.val(2,jdof); | |
1387 | } | ||
1388 | ✗ | tmp0 *= viscosity * feStress.weightMeas(ig); | |
1389 | ✗ | tmp1 *= feStress.weightMeas(ig); | |
1390 | ✗ | tmp2 *= viscosity * feStress.weightMeas(ig); | |
1391 | ✗ | for(int idof=0; idof<feStress.numDof(); idof++) { | |
1392 | ✗ | vec0(idof) += tmp0 * feStress.phi[ig](idof); | |
1393 | ✗ | vec1(idof) += tmp1 * feStress.phi[ig](idof); | |
1394 | ✗ | vec2(idof) += tmp2 * feStress.phi[ig](idof); | |
1395 | } | ||
1396 | } | ||
1397 | ✗ | break; | |
1398 | } | ||
1399 | } | ||
1400 | |||
1401 | /***********************************************************************************/ | ||
1402 | /***********************************************************************************/ | ||
1403 | |||
1404 | ✗ | void ElementVector::stressZ_dot_phi_i(const double viscosity, const CurrentFiniteElement& fePres, const CurrentFiniteElement& feStress,const CurrentFiniteElement& feVel,const ElementField& elfield_pressure,const ElementField& elfield_velocity,const int iblock) | |
1405 | { | ||
1406 | ✗ | FEL_CHECK(feStress.numQuadraturePoint() == feVel.numQuadraturePoint(), "ElementVector::stressZ_dot_phi_i: The quadrature rules must be the same for all the elements"); | |
1407 | ✗ | FEL_CHECK(feStress.numCoor() == 3, "ElementVector::stressZ_dot_phi_i: not yet implemented in 2D"); | |
1408 | double tmp0,tmp1,tmp2; | ||
1409 | ✗ | switch(elfield_velocity.type()) { | |
1410 | ✗ | case CONSTANT_FIELD: | |
1411 | // add nothing: curl cst = 0 | ||
1412 | ✗ | break; | |
1413 | ✗ | case QUAD_POINT_FIELD: | |
1414 | ✗ | FEL_ERROR("ElementVector::stressZ_dot_phi_i: Operator 'stressZ_dot_phi_i' is not defined for quad_point_field: how to compute curl f ??"); | |
1415 | break; | ||
1416 | ✗ | case DOF_FIELD: | |
1417 | ✗ | UBlasVectorRange vec0 = vecBlock(iblock+0); | |
1418 | ✗ | UBlasVectorRange vec1 = vecBlock(iblock+1); | |
1419 | ✗ | UBlasVectorRange vec2 = vecBlock(iblock+2); | |
1420 | ✗ | for(int ig=0; ig<feStress.numQuadraturePoint(); ig++) { | |
1421 | ✗ | tmp0 = 0.0; | |
1422 | ✗ | tmp1 = 0.0; | |
1423 | ✗ | tmp2 = 0.0; | |
1424 | ✗ | for (int jdof=0; jdof<feVel.numDof(); jdof++) { | |
1425 | ✗ | tmp0 += feVel.dPhi[ig](2,jdof)*elfield_velocity.val(0,jdof) + feVel.dPhi[ig](0,jdof)*elfield_velocity.val(2,jdof); | |
1426 | ✗ | tmp1 += feVel.dPhi[ig](2,jdof)*elfield_velocity.val(1,jdof) + feVel.dPhi[ig](1,jdof)*elfield_velocity.val(2,jdof); | |
1427 | ✗ | tmp2 += -elfield_pressure.val(0,jdof) * fePres.phi[ig](jdof)+ 2 * viscosity * feVel.dPhi[ig](2,jdof)*elfield_velocity.val(2,jdof); | |
1428 | } | ||
1429 | ✗ | tmp0 *= viscosity * feStress.weightMeas(ig); | |
1430 | ✗ | tmp1 *= viscosity * feStress.weightMeas(ig); | |
1431 | ✗ | tmp2 *= feStress.weightMeas(ig); | |
1432 | ✗ | for(int idof=0; idof<feStress.numDof(); idof++) { | |
1433 | ✗ | vec0(idof) += tmp0 * feStress.phi[ig](idof); | |
1434 | ✗ | vec1(idof) += tmp1 * feStress.phi[ig](idof); | |
1435 | ✗ | vec2(idof) += tmp2 * feStress.phi[ig](idof); | |
1436 | } | ||
1437 | } | ||
1438 | ✗ | break; | |
1439 | } | ||
1440 | } | ||
1441 | |||
1442 | /***********************************************************************************/ | ||
1443 | /***********************************************************************************/ | ||
1444 | |||
1445 | ✗ | void ElementVector::grad_f_grad_phi_i(const double coef, const CurrentFiniteElement& fe,const ElementField& elfield,const int iblock) | |
1446 | { | ||
1447 | double tmp; | ||
1448 | ✗ | UBlasVectorRange vec = vecBlock(iblock); | |
1449 | ✗ | switch(elfield.type()) { | |
1450 | ✗ | case CONSTANT_FIELD: | |
1451 | // add nothing: grad cst = 0 | ||
1452 | ✗ | break; | |
1453 | ✗ | case QUAD_POINT_FIELD: | |
1454 | ✗ | FEL_ERROR("ElementVector::grad_f_grad_phi_i: Operator 'grad_f_grad_phi_i' is not defined for quad_point_field: how to compute grad f ??"); | |
1455 | break; | ||
1456 | ✗ | case DOF_FIELD: | |
1457 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
1458 | ✗ | for (int icomp=0; icomp<fe.numCoor(); icomp++) { | |
1459 | ✗ | tmp = 0.0; | |
1460 | ✗ | for (int jdof=0; jdof<fe.numDof(); jdof++) | |
1461 | ✗ | tmp += fe.dPhi[ig](icomp,jdof)*elfield.val(0,jdof); | |
1462 | ✗ | tmp *= coef * fe.weightMeas(ig); | |
1463 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) | |
1464 | ✗ | vec(idof) += tmp * fe.dPhi[ig](icomp,idof); | |
1465 | } | ||
1466 | } | ||
1467 | ✗ | break; | |
1468 | } | ||
1469 | } | ||
1470 | |||
1471 | /***********************************************************************************/ | ||
1472 | /***********************************************************************************/ | ||
1473 | |||
1474 | ✗ | void ElementVector::grad_f_grad_phi_i(const double coef,const CurvilinearFiniteElement& fe, const ElementField& elfield, const std::size_t iblock,const std::size_t num) | |
1475 | { | ||
1476 | ✗ | FEL_ASSERT(elfield.type() == DOF_FIELD); | |
1477 | |||
1478 | ✗ | UBlasMatrix tmpBlock(fe.numDof(),fe.numDof(),0); | |
1479 | ✗ | UBlasMatrix tmpAdPhi(fe.contravariantMetric[0].size1(), fe.dPhiRef(0).size2()); | |
1480 | ✗ | for(int ig=0, numQuadPoint = fe.numQuadraturePoint(); ig < numQuadPoint; ig++) { | |
1481 | ✗ | tmpAdPhi = prod(fe.contravariantMetric[ig],fe.dPhiRef(ig)); | |
1482 | ✗ | tmpBlock += coef*fe.weightMeas(ig)*prod(trans(fe.dPhiRef(ig)),tmpAdPhi); | |
1483 | } | ||
1484 | |||
1485 | ✗ | UBlasVector ff = elfield.valAsVec(); | |
1486 | |||
1487 | ✗ | for(std::size_t icoor=0; icoor < num; icoor++) { | |
1488 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icoor); | |
1489 | ✗ | UBlasVectorRange ficoor = UBlasVectorRange(ff,UBlasRange( m_firstRow[icoor], m_firstRow[icoor]+m_numRow[icoor])); | |
1490 | ✗ | vec += prod(tmpBlock,ficoor); | |
1491 | } | ||
1492 | } | ||
1493 | |||
1494 | /***********************************************************************************/ | ||
1495 | /***********************************************************************************/ | ||
1496 | |||
1497 | ✗ | void ElementVector::f_grad_phi_i(const double coef, const CurrentFiniteElement& fe,const ElementField& elfield,const int iblock) | |
1498 | { | ||
1499 | double tmp; | ||
1500 | ✗ | UBlasVectorRange vec = vecBlock(iblock); | |
1501 | ✗ | switch(elfield.type()) { | |
1502 | ✗ | case CONSTANT_FIELD: | |
1503 | // add nothing: grad cst = 0 | ||
1504 | ✗ | break; | |
1505 | ✗ | case QUAD_POINT_FIELD: | |
1506 | ✗ | FEL_ERROR("ElementVector::grad_f_grad_phi_i: Operator 'grad_f_grad_phi_i' is not defined for quad_point_field: how to compute grad f ??"); | |
1507 | break; | ||
1508 | ✗ | case DOF_FIELD: | |
1509 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
1510 | ✗ | for (int icomp=0; icomp<fe.numCoor(); icomp++) { | |
1511 | ✗ | tmp = 0.0; | |
1512 | ✗ | for (int jdof=0; jdof<fe.numDof(); jdof++) | |
1513 | ✗ | tmp += fe.phi[ig](jdof)*elfield.val(icomp,jdof); | |
1514 | ✗ | tmp *= coef * fe.weightMeas(ig); | |
1515 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) | |
1516 | ✗ | vec(idof) += tmp * fe.dPhi[ig](icomp,idof); | |
1517 | } | ||
1518 | } | ||
1519 | ✗ | break; | |
1520 | } | ||
1521 | } | ||
1522 | |||
1523 | /***********************************************************************************/ | ||
1524 | /***********************************************************************************/ | ||
1525 | |||
1526 | 1315282 | void ElementVector::div_f_phi_i(const double coef, const CurrentFiniteElement& fe1,const CurrentFiniteElement& fe2,const ElementField& elfield1,const int iblock) | |
1527 | { | ||
1528 |
1/6✗ Branch 2 not taken.
✓ Branch 3 taken 1315282 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
1315282 | FEL_CHECK(fe1.numQuadraturePoint() == fe2.numQuadraturePoint(),"ElementVector::div_f_phi_i: The quadrature rules must be the same for the two elements"); |
1529 | double tmp; | ||
1530 |
1/2✓ Branch 1 taken 1315282 times.
✗ Branch 2 not taken.
|
1315282 | UBlasVectorRange vec = vecBlock(iblock); |
1531 |
1/4✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1315282 times.
✗ Branch 4 not taken.
|
1315282 | switch(elfield1.type()) { |
1532 | ✗ | case CONSTANT_FIELD: | |
1533 | // add nothing: div cst = 0 | ||
1534 | ✗ | break; | |
1535 | ✗ | case QUAD_POINT_FIELD: | |
1536 | ✗ | FEL_ERROR("ElementVector::div_f_phi_i: Operator 'div_f_phi_i' is not defined for quad_point_field: how to compute div f ??"); | |
1537 | break; | ||
1538 | 1315282 | case DOF_FIELD: | |
1539 |
2/2✓ Branch 1 taken 5266452 times.
✓ Branch 2 taken 1315282 times.
|
6581734 | for(int ig=0; ig<fe2.numQuadraturePoint(); ig++) { |
1540 | 5266452 | tmp = 0.0; | |
1541 |
2/2✓ Branch 1 taken 15783384 times.
✓ Branch 2 taken 5266452 times.
|
21049836 | for (int icomp=0; icomp<fe1.numCoor(); icomp++) { |
1542 |
2/2✓ Branch 1 taken 63101592 times.
✓ Branch 2 taken 15783384 times.
|
78884976 | for (int jdof=0; jdof<fe1.numDof(); jdof++) { |
1543 |
2/4✓ Branch 2 taken 63101592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 63101592 times.
✗ Branch 6 not taken.
|
63101592 | tmp += fe1.dPhi[ig](icomp,jdof) * elfield1.val(icomp,jdof); |
1544 | } | ||
1545 | } | ||
1546 |
1/2✓ Branch 1 taken 5266452 times.
✗ Branch 2 not taken.
|
5266452 | tmp *= coef * fe2.weightMeas(ig); |
1547 |
2/2✓ Branch 1 taken 21049836 times.
✓ Branch 2 taken 5266452 times.
|
26316288 | for(int idof=0; idof<fe2.numDof(); idof++) { |
1548 |
2/4✓ Branch 2 taken 21049836 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 21049836 times.
✗ Branch 6 not taken.
|
21049836 | vec(idof) += tmp * fe2.phi[ig](idof); |
1549 | } | ||
1550 | } | ||
1551 | 1315282 | break; | |
1552 | } | ||
1553 | 1315282 | } | |
1554 | |||
1555 | /***********************************************************************************/ | ||
1556 | /***********************************************************************************/ | ||
1557 | |||
1558 | ✗ | void ElementVector::f_div_phi_i(const double coef, const CurrentFiniteElement& fe1,const CurrentFiniteElement& fe2,const ElementField& elfield2,const int iblock) | |
1559 | { | ||
1560 | ✗ | FEL_CHECK(fe1.numQuadraturePoint() == fe2.numQuadraturePoint(), | |
1561 | "ElementVector::f_div_phi_i: The quadrature rules must be the same for the two elements"); | ||
1562 | double tmp; | ||
1563 | ✗ | switch(elfield2.type()) { | |
1564 | ✗ | case CONSTANT_FIELD: | |
1565 | ✗ | FEL_ERROR("ElementVector::f_div_phi_i: Operator 'f_div_phi_i' is not defined yet for constant_field"); | |
1566 | break; | ||
1567 | ✗ | case QUAD_POINT_FIELD: | |
1568 | ✗ | FEL_ERROR("ElementVector::f_div_phi_i: Operator 'f_div_phi_i' is not defined yet for quad_point_field"); | |
1569 | break; | ||
1570 | ✗ | case DOF_FIELD: | |
1571 | ✗ | for (int icomp=0; icomp<fe1.numCoor(); icomp++) { | |
1572 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
1573 | ✗ | for(int ig=0; ig<fe2.numQuadraturePoint(); ig++) { | |
1574 | ✗ | tmp = 0.0; | |
1575 | ✗ | for (int jdof=0; jdof<fe1.numDof(); jdof++) { | |
1576 | ✗ | tmp += fe2.phi[ig](jdof)*elfield2.val(0,jdof); | |
1577 | } | ||
1578 | ✗ | tmp *= coef * fe1.weightMeas(ig); | |
1579 | ✗ | for(int idof=0; idof<fe1.numDof(); idof++) { | |
1580 | ✗ | vec(idof) += tmp * fe1.dPhi[ig](icomp,idof); | |
1581 | } | ||
1582 | } | ||
1583 | } | ||
1584 | ✗ | break; | |
1585 | } | ||
1586 | } | ||
1587 | |||
1588 | /***********************************************************************************/ | ||
1589 | /***********************************************************************************/ | ||
1590 | |||
1591 | ✗ | void ElementVector::grad_u_dot_grad_LSu_v(const double coef,const ElementField& u,const ElementField& LSu,const std::vector<double>& data,double avHeavU0,double avHeavMinusU0,double insidePar,double outsidePar,const CurvilinearFiniteElement& fe,std::size_t iblock) | |
1592 | { | ||
1593 | ✗ | UBlasVectorRange vec = vecBlock(iblock); | |
1594 | // grad_level_set | ||
1595 | ✗ | UBlasVector vec_grad_phi(2); | |
1596 | //norm of grad_level_set | ||
1597 | // double norm_grad_phi = 0.0; | ||
1598 | // grad_transmembrane_pot | ||
1599 | ✗ | UBlasVector vec_grad_u(2); | |
1600 | ✗ | double grad_u_dot_grad_phi = 0.0; | |
1601 | ✗ | double dirac = 0.0; | |
1602 | ✗ | const double epsilon = 1.0e-5; | |
1603 | |||
1604 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
1605 | ✗ | vec_grad_phi(0) = 0.0; | |
1606 | ✗ | vec_grad_phi(1) = 0.0; | |
1607 | ✗ | vec_grad_u(0) = 0.0; | |
1608 | ✗ | vec_grad_u(1) = 0.0; | |
1609 | ✗ | grad_u_dot_grad_phi = 0.0; | |
1610 | ✗ | for( felInt icoor = 0; icoor<fe.numRefCoor(); icoor++) { | |
1611 | ✗ | for (int idof=0; idof<fe.numDof(); idof++) { | |
1612 | ✗ | vec_grad_phi(icoor) += LSu.val(0, idof) * fe.dPhiRef(ig)(icoor, idof); | |
1613 | ✗ | vec_grad_u(icoor) += u.val(0, idof) * fe.dPhiRef(ig)(icoor, idof); | |
1614 | } | ||
1615 | } | ||
1616 | |||
1617 | ✗ | grad_u_dot_grad_phi = std::sqrt(vec_grad_phi(0)*vec_grad_phi(0)+vec_grad_phi(1)*vec_grad_phi(1)); | |
1618 | |||
1619 | ✗ | for (int idof=0; idof<fe.numDof(); idof++) { | |
1620 | ✗ | dirac = ( 1./ std::sqrt(3.14151) )* ( epsilon / ( epsilon*epsilon + LSu.val(0, idof)*LSu.val(0, idof) ) ); | |
1621 | ✗ | vec(idof) += coef * fe.weightMeas(ig) * grad_u_dot_grad_phi * dirac *(insidePar*(data[idof]-avHeavU0)*(data[idof]-avHeavU0) + outsidePar*(data[idof]-avHeavMinusU0)*(data[idof]-avHeavMinusU0))* fe.phi[ig](idof); | |
1622 | } | ||
1623 | } | ||
1624 | } | ||
1625 | |||
1626 | /***********************************************************************************/ | ||
1627 | /***********************************************************************************/ | ||
1628 | |||
1629 | ✗ | void ElementVector::sourceHyp1DCont(std::vector<double>& coef,const CurrentFiniteElement& fe1,const CurrentFiniteElement& fe2,const ElementField& elfield1,const ElementField& elfield2,const int iblock,int iterm) | |
1630 | { | ||
1631 | ✗ | FEL_CHECK(elfield2.type()==DOF_FIELD,"Operator Continuity for 1D Fsi not yet implemented with this type of element fields"); | |
1632 | ✗ | FEL_CHECK(elfield1.type()==DOF_FIELD,"Operator Continuity for 1D Fsi not yet implemented with this type of element fields"); | |
1633 | ✗ | FEL_CHECK(fe1.numQuadraturePoint() == fe2.numQuadraturePoint(),"The quadrature rules must be the same for the two elements"); | |
1634 | |||
1635 | ✗ | FEL_ASSERT(coef.size()==4); | |
1636 | ✗ | const double dt = coef[0]; | |
1637 | ✗ | const double k = coef[1]; | |
1638 | ✗ | const double betaDivrho = coef[2]; | |
1639 | //const double sectionAtRest = coef[3]; | ||
1640 | |||
1641 | double tmpA,tmpU,tmpDxA,tmpDxU,tmpDxF1,tmpDxF2; | ||
1642 | |||
1643 | ✗ | UBlasVectorRange vec = vecBlock(iblock); | |
1644 | |||
1645 | ✗ | switch (iterm) { | |
1646 | |||
1647 | ✗ | case 0: | |
1648 | |||
1649 | ✗ | break; | |
1650 | ✗ | case 1: { | |
1651 | ✗ | for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) { | |
1652 | ✗ | tmpU=0.0; | |
1653 | ✗ | tmpA=0.0; | |
1654 | ✗ | for(int i=0; i<fe1.numDof(); i++) { | |
1655 | ✗ | tmpA+= elfield1.val(0,i)*fe1.phi[ig](i); | |
1656 | } | ||
1657 | ✗ | for(int j=0; j<fe2.numDof(); j++) { | |
1658 | ✗ | tmpU+= elfield2.val(0,j)*fe2.phi[ig](j); | |
1659 | } | ||
1660 | ✗ | double Au = tmpA*tmpU; | |
1661 | ✗ | double tmp = tmpU*0.5*k*dt; | |
1662 | |||
1663 | ✗ | for(int idof=0; idof<fe1.numDof(); idof++) { | |
1664 | ✗ | vec(idof)+= dt*(Au-tmp)*fe1.dPhi[ig](0,idof)*fe1.weightMeas(ig); | |
1665 | } | ||
1666 | } | ||
1667 | } | ||
1668 | ✗ | break; | |
1669 | |||
1670 | ✗ | case 2: | |
1671 | |||
1672 | ✗ | break; | |
1673 | |||
1674 | ✗ | case 3: { | |
1675 | ✗ | for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) { | |
1676 | ✗ | tmpA=0.0; | |
1677 | ✗ | tmpU=0.0; | |
1678 | ✗ | tmpDxA=0.0; | |
1679 | ✗ | tmpDxU=0.0; | |
1680 | ✗ | for(int i=0; i<fe1.numDof(); i++) { | |
1681 | ✗ | tmpA+= elfield1.val(0,i)*fe1.phi[ig](i); | |
1682 | ✗ | tmpDxA+= elfield1.val(0,i)*fe1.dPhi[ig](0,i); | |
1683 | } | ||
1684 | |||
1685 | ✗ | for(int j=0; j<fe2.numDof(); j++) { | |
1686 | ✗ | tmpU+= elfield2.val(0,j)*fe2.phi[ig](j); | |
1687 | ✗ | tmpDxU+= elfield2.val(0,j)*fe2.dPhi[ig](0,j); | |
1688 | } | ||
1689 | |||
1690 | ✗ | tmpDxF1 = tmpA*tmpDxU + tmpU*tmpDxA; | |
1691 | ✗ | tmpDxF2 = tmpU*tmpDxU + (0.5*betaDivrho/(std::sqrt(tmpA)))*tmpDxA; | |
1692 | |||
1693 | ✗ | for(int idof=0; idof<fe1.numDof(); idof++) { | |
1694 | ✗ | vec(idof)+= -0.5*dt*dt*(tmpU*tmpDxF1+tmpA*tmpDxF2)*fe1.dPhi[ig](0,idof)*fe1.weightMeas(ig); | |
1695 | } | ||
1696 | } | ||
1697 | } | ||
1698 | ✗ | break; | |
1699 | } | ||
1700 | } | ||
1701 | |||
1702 | /***********************************************************************************/ | ||
1703 | /***********************************************************************************/ | ||
1704 | |||
1705 | ✗ | void ElementVector::sourceHyp1DMom(std::vector<double>& coef,const CurrentFiniteElement& fe1,const CurrentFiniteElement& fe2,const ElementField& elfield1,const ElementField& elfield2,const int iblock,int iterm) | |
1706 | { | ||
1707 | ✗ | FEL_CHECK(elfield2.type()==DOF_FIELD,"Operator Momentum for 1D Fsi not yet implemented with this type of element fields"); | |
1708 | ✗ | FEL_CHECK(elfield1.type()==DOF_FIELD,"Operator Momentum for 1D Fsi not yet implemented with this type of element fields"); | |
1709 | ✗ | FEL_CHECK(fe1.numQuadraturePoint() == fe2.numQuadraturePoint(),"The quadrature rules must be the same for the two elements"); | |
1710 | |||
1711 | ✗ | FEL_ASSERT(coef.size()==4); | |
1712 | ✗ | const double dt = coef[0]; | |
1713 | ✗ | const double k = coef[1]; | |
1714 | ✗ | const double betaDivrho = coef[2]; | |
1715 | ✗ | const double r_0 = std::sqrt(coef[3]); | |
1716 | |||
1717 | double tmpA,tmpU,tmpDxA,tmpDxU,tmpDxF1,tmpDxF2; | ||
1718 | |||
1719 | ✗ | UBlasVectorRange vec = vecBlock(iblock); | |
1720 | |||
1721 | ✗ | switch (iterm) { | |
1722 | ✗ | case 0: { | |
1723 | ✗ | for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) { | |
1724 | ✗ | tmpU=0.0; | |
1725 | ✗ | tmpA=0.0; | |
1726 | ✗ | for(int i=0; i<fe1.numDof(); i++) { | |
1727 | ✗ | tmpA+= elfield1.val(0,i)*fe1.phi[ig](i); | |
1728 | } | ||
1729 | ✗ | for(int j=0; j<fe2.numDof(); j++) { | |
1730 | ✗ | tmpU+= elfield2.val(0,j)*fe2.phi[ig](j); | |
1731 | } | ||
1732 | ✗ | const double UdivA = tmpU/tmpA; | |
1733 | ✗ | const double UdivA2 = tmpU/(tmpA*tmpA); | |
1734 | |||
1735 | ✗ | for(int idof=0; idof<fe1.numDof(); idof++) { | |
1736 | ✗ | vec(idof)+= dt*(-k*UdivA+0.5*dt*k*k*UdivA2)*fe2.phi[ig](idof)*fe2.weightMeas(ig); | |
1737 | } | ||
1738 | } | ||
1739 | } | ||
1740 | ✗ | break; | |
1741 | ✗ | case 1: { | |
1742 | ✗ | for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) { | |
1743 | ✗ | tmpU=0.0; | |
1744 | ✗ | tmpA=0.0; | |
1745 | ✗ | for(int i=0; i<fe1.numDof(); i++) { | |
1746 | ✗ | tmpA+= elfield1.val(0,i)*fe1.phi[ig](i); | |
1747 | } | ||
1748 | ✗ | for(int j=0; j<fe2.numDof(); j++) { | |
1749 | ✗ | tmpU+= elfield2.val(0,j)*fe2.phi[ig](j); | |
1750 | } | ||
1751 | ✗ | const double tmpP = betaDivrho*(std::sqrt(tmpA)-r_0); | |
1752 | ✗ | const double U2DivA = (tmpU*tmpU)/tmpA; | |
1753 | |||
1754 | ✗ | for(int idof=0; idof<fe1.numDof(); idof++) { | |
1755 | ✗ | vec(idof)+= dt*(0.5*tmpU*tmpU+tmpP-0.5*dt*k*U2DivA)*fe2.dPhi[ig](0,idof)*fe2.weightMeas(ig); | |
1756 | } | ||
1757 | } | ||
1758 | } | ||
1759 | ✗ | break; | |
1760 | ✗ | case 2: { | |
1761 | ✗ | for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) { | |
1762 | ✗ | tmpU=0.0; | |
1763 | ✗ | tmpA=0.0; | |
1764 | ✗ | tmpDxA=0.0; | |
1765 | ✗ | tmpDxU=0.0; | |
1766 | ✗ | for(int i=0; i<fe1.numDof(); i++) { | |
1767 | ✗ | tmpA+= elfield1.val(0,i)*fe1.phi[ig](i); | |
1768 | ✗ | tmpDxA+= elfield1.val(0,i)*fe1.dPhi[ig](0,i); | |
1769 | } | ||
1770 | |||
1771 | ✗ | for(int j=0; j<fe2.numDof(); j++) { | |
1772 | ✗ | tmpU+= elfield2.val(0,j)*fe2.phi[ig](j); | |
1773 | ✗ | tmpDxU+= elfield2.val(0,j)*fe2.dPhi[ig](0,j); | |
1774 | } | ||
1775 | |||
1776 | ✗ | tmpDxF1 = tmpA*tmpDxU + tmpU*tmpDxA; | |
1777 | ✗ | tmpDxF2 = tmpU*tmpDxU + (0.5*betaDivrho*1.0/(std::sqrt(tmpA)))*tmpDxA; | |
1778 | |||
1779 | ✗ | const double UdivA2 = tmpU/(tmpA*tmpA); | |
1780 | |||
1781 | |||
1782 | ✗ | for(int idof=0; idof<fe1.numDof(); idof++) { | |
1783 | ✗ | vec(idof)+= -0.5*dt*dt*(k*UdivA2*tmpDxF1-(k/tmpA)*tmpDxF2)*fe2.phi[ig](idof)*fe2.weightMeas(ig); | |
1784 | } | ||
1785 | } | ||
1786 | } | ||
1787 | ✗ | break; | |
1788 | ✗ | case 3: { | |
1789 | ✗ | for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) { | |
1790 | ✗ | tmpU=0.0; | |
1791 | ✗ | tmpA=0.0; | |
1792 | ✗ | tmpDxA=0.0; | |
1793 | ✗ | tmpDxU=0.0; | |
1794 | ✗ | for(int i=0; i<fe1.numDof(); i++) { | |
1795 | ✗ | tmpA+= elfield1.val(0,i)*fe1.phi[ig](i); | |
1796 | ✗ | tmpDxA+= elfield1.val(0,i)*fe1.dPhi[ig](0,i); | |
1797 | } | ||
1798 | |||
1799 | ✗ | for(int j=0; j<fe2.numDof(); j++) { | |
1800 | ✗ | tmpU+= elfield2.val(0,j)*fe2.phi[ig](j); | |
1801 | ✗ | tmpDxU+= elfield2.val(0,j)*fe2.dPhi[ig](0,j); | |
1802 | } | ||
1803 | |||
1804 | ✗ | tmpDxF1 = tmpA*tmpDxU + tmpU*tmpDxA; | |
1805 | ✗ | tmpDxF2 = tmpU*tmpDxU + (0.5*betaDivrho/(std::sqrt(tmpA)))*tmpDxA; | |
1806 | |||
1807 | ✗ | const double tmpR = std::sqrt(tmpA); | |
1808 | |||
1809 | ✗ | for(int idof=0; idof<fe1.numDof(); idof++) { | |
1810 | ✗ | vec(idof)+= -0.5*dt*dt*(0.5*(betaDivrho/tmpR)*tmpDxF1 + tmpU*tmpDxF2)*fe2.dPhi[ig](0,idof)*fe2.weightMeas(ig); | |
1811 | } | ||
1812 | } | ||
1813 | } | ||
1814 | ✗ | break; | |
1815 | } | ||
1816 | } | ||
1817 | |||
1818 | /***********************************************************************************/ | ||
1819 | /***********************************************************************************/ | ||
1820 | |||
1821 | ✗ | void ElementVector::abs_u_dot_n_u_dot_phi_i(const double coef, | |
1822 | const ElementField& elfield, | ||
1823 | const CurvilinearFiniteElement& febd, | ||
1824 | const int iblock, const int numComp) { | ||
1825 | double u_n,u_bd; | ||
1826 | ✗ | switch(elfield.type()) { | |
1827 | ✗ | case DOF_FIELD: // P1 | |
1828 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
1829 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
1830 | ✗ | for(int ig=0; ig<febd.numQuadraturePoint(); ig++) { | |
1831 | |||
1832 | // compute 1/2[ ||u.n|| - u.n ](ig) | ||
1833 | ✗ | u_n = 0.0; | |
1834 | ✗ | for(int jdof=0; jdof<febd.numDof(); jdof++) { | |
1835 | ✗ | for (int jcomp=0; jcomp<numComp; jcomp++) { | |
1836 | ✗ | u_n += febd.phi[ig](jdof) * elfield.val(jcomp,jdof) | |
1837 | ✗ | * febd.normal[ig](jcomp); | |
1838 | } | ||
1839 | } | ||
1840 | // compute u_icomp (ig) | ||
1841 | ✗ | u_bd = 0.0; | |
1842 | ✗ | for(int jdof=0; jdof<febd.numDof(); jdof++) { | |
1843 | ✗ | u_bd += febd.phi[ig](jdof) * elfield.val(icomp,jdof); | |
1844 | } | ||
1845 | |||
1846 | |||
1847 | // compute local contribution for component icomp | ||
1848 | ✗ | for(int idof=0; idof<febd.numDof(); idof++) { | |
1849 | ✗ | vec(idof) += coef * 0.5 * (std::abs(u_n) - u_n) * u_bd * | |
1850 | ✗ | febd.phi[ig](idof) * febd.weightMeas(ig); | |
1851 | } | ||
1852 | } | ||
1853 | ✗ | } // for i comp | |
1854 | ✗ | break; | |
1855 | ✗ | case CONSTANT_FIELD: | |
1856 | case QUAD_POINT_FIELD: | ||
1857 | ✗ | FEL_ERROR("Operator 'abs_u_dot_n_u_dot_phi_i' not yet implemented with this type of element fields"); | |
1858 | } | ||
1859 | } | ||
1860 | |||
1861 | /***********************************************************************************/ | ||
1862 | /***********************************************************************************/ | ||
1863 | |||
1864 | ✗ | void ElementVector::u_grad_u_phi_i(const double coef, const CurrentFiniteElement& fe,const ElementField& elfield,const int iblock,const int numComp) | |
1865 | { | ||
1866 | double tmp,u_i2,di2_u_icomp; | ||
1867 | ✗ | switch(elfield.type()) { | |
1868 | ✗ | case DOF_FIELD: | |
1869 | // loop over components [b]: sum_a u_a d_a u_b phi | ||
1870 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
1871 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
1872 | |||
1873 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
1874 | ✗ | tmp = 0.0; | |
1875 | ✗ | for(int i2comp=0; i2comp<numComp; i2comp++) { | |
1876 | ✗ | di2_u_icomp = 0.0; | |
1877 | ✗ | u_i2 = 0.0; | |
1878 | // compute d_a u_b | ||
1879 | ✗ | for (int jdof=0; jdof<fe.numDof(); jdof++) { | |
1880 | ✗ | di2_u_icomp += fe.dPhi[ig](i2comp,jdof)*elfield.val(icomp,jdof); | |
1881 | } | ||
1882 | // compute u_a | ||
1883 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
1884 | ✗ | u_i2 += fe.phi[ig](idof) * elfield.val(i2comp,idof); | |
1885 | } | ||
1886 | // u_a d_a(u_b) | ||
1887 | ✗ | tmp += u_i2*di2_u_icomp; | |
1888 | } | ||
1889 | // add to std::vector | ||
1890 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
1891 | ✗ | vec(idof) += coef * tmp * fe.phi[ig](idof) * fe.weightMeas(ig); | |
1892 | } | ||
1893 | |||
1894 | } // ig | ||
1895 | ✗ | } // icomp | |
1896 | ✗ | break; | |
1897 | ✗ | case CONSTANT_FIELD: | |
1898 | case QUAD_POINT_FIELD: | ||
1899 | |||
1900 | ✗ | FEL_ERROR("Operator 'source' not yet implemented with this type of element fields"); | |
1901 | } | ||
1902 | } | ||
1903 | |||
1904 | /***********************************************************************************/ | ||
1905 | /***********************************************************************************/ | ||
1906 | |||
1907 | ✗ | void ElementVector::u_grad_u_grad_phi_i(const double coef, const CurrentFiniteElement& fe,const ElementField& elfield,const int iblock,const int numComp) | |
1908 | { | ||
1909 | double tmp,u_i2,di2_u_icomp; | ||
1910 | ✗ | UBlasVectorRange vec = vecBlock(iblock); | |
1911 | ✗ | switch(elfield.type()) { | |
1912 | ✗ | case DOF_FIELD: | |
1913 | // loop over components [b]: sum_a u_a d_a u_b phi | ||
1914 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
1915 | |||
1916 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
1917 | ✗ | tmp = 0.0; | |
1918 | ✗ | for(int i2comp=0; i2comp<numComp; i2comp++) { | |
1919 | ✗ | di2_u_icomp = 0.0; | |
1920 | ✗ | u_i2 = 0.0; | |
1921 | // compute d_a u_b | ||
1922 | ✗ | for (int jdof=0; jdof<fe.numDof(); jdof++) { | |
1923 | ✗ | di2_u_icomp += fe.dPhi[ig](i2comp,jdof)*elfield.val(icomp,jdof); | |
1924 | } | ||
1925 | // compute u_a | ||
1926 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
1927 | ✗ | u_i2 += fe.phi[ig](idof) * elfield.val(i2comp,idof); | |
1928 | } | ||
1929 | // u_a d_a(u_b) | ||
1930 | ✗ | tmp += u_i2*di2_u_icomp; | |
1931 | } | ||
1932 | // add to std::vector | ||
1933 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
1934 | ✗ | vec(idof) += coef * tmp * fe.dPhi[ig](icomp,idof) * fe.weightMeas(ig); | |
1935 | } | ||
1936 | |||
1937 | } // ig | ||
1938 | } // icomp | ||
1939 | ✗ | break; | |
1940 | ✗ | case CONSTANT_FIELD: | |
1941 | case QUAD_POINT_FIELD: | ||
1942 | |||
1943 | ✗ | FEL_ERROR("Operator 'source' not yet implemented with this type of element fields"); | |
1944 | } | ||
1945 | } | ||
1946 | |||
1947 | /***********************************************************************************/ | ||
1948 | /***********************************************************************************/ | ||
1949 | |||
1950 | ✗ | void ElementVector::f_dot_n_phi_i_dot_n(const double coef,const CurvilinearFiniteElement& fe,const ElementField& elfield,const int iblock) | |
1951 | { | ||
1952 | double tmp,f_dot_n; | ||
1953 | ✗ | switch(elfield.type()) { | |
1954 | ✗ | case DOF_FIELD: { | |
1955 | ✗ | for(int icomp=0; icomp<fe.numCoor(); icomp++) { | |
1956 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
1957 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
1958 | ✗ | f_dot_n = 0.0; | |
1959 | // compute f \cdot n | ||
1960 | ✗ | for(int icoor=0; icoor<fe.numCoor(); icoor++) { | |
1961 | ✗ | tmp = 0.0; | |
1962 | ✗ | for(int jdof=0; jdof<fe.numDof(); jdof++) { | |
1963 | ✗ | tmp += fe.phi[ig](jdof) * elfield.val(icoor,jdof); | |
1964 | } | ||
1965 | // sum f_icoor * n_icoor | ||
1966 | ✗ | f_dot_n += tmp * fe.normal[ig](icoor); | |
1967 | } | ||
1968 | |||
1969 | ✗ | for( std::size_t idof=0 ; idof < (std::size_t) fe.numDof() ; idof++ ) { | |
1970 | // coef * f_dot_n * ( phi_i \cdot \n ) | ||
1971 | ✗ | vec(idof) += coef * f_dot_n * fe.weightMeas(ig) * fe.normal[ig](icomp) * fe.phi[ig](idof); | |
1972 | } | ||
1973 | } | ||
1974 | } | ||
1975 | } | ||
1976 | ✗ | break; | |
1977 | ✗ | case CONSTANT_FIELD: | |
1978 | case QUAD_POINT_FIELD: | ||
1979 | ✗ | FEL_ERROR("Operator 'f_dot_n_phi_i_dot_n' not yet implemented with this type of element fields"); | |
1980 | } | ||
1981 | } | ||
1982 | |||
1983 | /***********************************************************************************/ | ||
1984 | /***********************************************************************************/ | ||
1985 | |||
1986 | ✗ | void ElementVector::f_times_n_phi_i_times_n(const double coef,const CurvilinearFiniteElement& fe,const ElementField& elfield,const int iblock) | |
1987 | { | ||
1988 | double tmp,aux,inDiagonal; | ||
1989 | ✗ | switch(elfield.type()) { | |
1990 | ✗ | case DOF_FIELD: { | |
1991 | ✗ | for(int icomp=0; icomp<fe.numCoor(); icomp++) { | |
1992 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
1993 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
1994 | ✗ | aux = 0.0; | |
1995 | ✗ | for(int icoor=0; icoor<fe.numCoor(); icoor++) { | |
1996 | ✗ | tmp = 0.0; | |
1997 | ✗ | inDiagonal = 0.0; | |
1998 | ✗ | if (icoor==icomp) { | |
1999 | ✗ | inDiagonal = 1.; | |
2000 | } | ||
2001 | ✗ | for(int jdof=0; jdof<fe.numDof(); jdof++) { | |
2002 | ✗ | tmp += fe.phi[ig](jdof) * elfield.val(icoor,jdof); | |
2003 | } | ||
2004 | ✗ | aux += tmp * (inDiagonal - fe.normal[ig](icoor) * fe.normal[ig](icomp)); | |
2005 | } | ||
2006 | ✗ | for( std::size_t idof=0 ; idof < (std::size_t) fe.numDof() ; idof++ ) { | |
2007 | |||
2008 | ✗ | vec(idof) += coef * aux * fe.weightMeas(ig) * fe.phi[ig](idof); | |
2009 | } | ||
2010 | } | ||
2011 | } | ||
2012 | } | ||
2013 | ✗ | break; | |
2014 | ✗ | case CONSTANT_FIELD: | |
2015 | case QUAD_POINT_FIELD: | ||
2016 | ✗ | FEL_ERROR("Operator 'f_times_n_phi_i_times_n' not yet implemented with this type of element fields"); | |
2017 | } | ||
2018 | } | ||
2019 | |||
2020 | /***********************************************************************************/ | ||
2021 | /***********************************************************************************/ | ||
2022 | |||
2023 | ✗ | void ElementVector::grad_f_dot_n_times_n_phi_i_times_n(const double coef,const CurrentFiniteElementWithBd& fewbd, | |
2024 | const ElementField& elfield, | ||
2025 | const int iblockBd, const int numblockBd, | ||
2026 | const int iblock, const int numComp) | ||
2027 | { | ||
2028 | ✗ | FEL_ASSERT(iblockBd>=0 && iblockBd<fewbd.numBdEle() && (numblockBd-iblockBd) <= fewbd.numBdEle() ); | |
2029 | ✗ | FEL_ASSERT( static_cast<int>(m_tmpVecDof.size()) == fewbd.numDof() ); | |
2030 | |||
2031 | double tmp,aux,inDiagonal; | ||
2032 | ✗ | switch(elfield.type()) { | |
2033 | ✗ | case CONSTANT_FIELD: | |
2034 | // add nothing: grad cst = 0 | ||
2035 | ✗ | break; | |
2036 | ✗ | case QUAD_POINT_FIELD: | |
2037 | ✗ | FEL_ERROR("Operator 'grad_f_dot_n_times_n_phi_i_times_n' is not well defined for quad_point_field: how to compute grad f ??"); | |
2038 | break; | ||
2039 | ✗ | case DOF_FIELD: | |
2040 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
2041 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
2042 | ✗ | for (int ibd=iblockBd; ibd<iblockBd+numblockBd; ibd++) { | |
2043 | ✗ | FEL_ASSERT( fewbd.bdEle(ibd).hasNormal() && fewbd.hasFirstDeriv() ); | |
2044 | ✗ | for(int ilocg=0; ilocg<fewbd.numQuadPointBdEle(ibd); ilocg++) { | |
2045 | ✗ | int ig = ilocg+fewbd.indexQuadPoint(ibd+1); | |
2046 | // face ibd starts at ibd+1 (0 for internal quad points) | ||
2047 | //! Vector = [n \cdot \grad \phi]: | ||
2048 | ✗ | m_tmpVecDof = prod(trans(fewbd.bdEle(ibd).normal[ilocg]), fewbd.dPhi[ig]); | |
2049 | ✗ | tmp = 0.0; | |
2050 | ✗ | for(int icoor=0; icoor<fewbd.numCoor(); icoor++) { | |
2051 | ✗ | aux = 0.0; | |
2052 | ✗ | inDiagonal = 0.0; | |
2053 | ✗ | if (icoor==icomp) { | |
2054 | ✗ | inDiagonal = 1.; | |
2055 | } | ||
2056 | ✗ | for(int jdof=0; jdof<fewbd.numDof(); jdof++) { | |
2057 | //! tmp = [n \cdot \grad f] = \sum f_jdof (grad phi_jdof \cdot n) | ||
2058 | ✗ | aux += m_tmpVecDof(jdof) * elfield.val(icoor,jdof); | |
2059 | } | ||
2060 | ✗ | tmp += aux * (inDiagonal - fewbd.bdEle(ibd).normal[ilocg](icoor) * fewbd.bdEle(ibd).normal[ilocg](icomp)); | |
2061 | } | ||
2062 | ✗ | tmp *= coef * fewbd.bdEle(ibd).weightMeas(ilocg); | |
2063 | ✗ | for(int idof=0; idof<fewbd.numDof(); idof++) { | |
2064 | ✗ | vec(idof) += tmp * fewbd.bdEle(ibd).phi[ilocg](idof); | |
2065 | } | ||
2066 | } | ||
2067 | } | ||
2068 | } | ||
2069 | ✗ | break; | |
2070 | // Default case should appear with a warning at compile time instead of an error in runtime | ||
2071 | // (that's truly the point of using enums as switch cases) | ||
2072 | // default: | ||
2073 | // FEL_ERROR("Operator 'grad_f_dot_n_phi_i' not yet implemented with this type of element fields"); | ||
2074 | } | ||
2075 | } | ||
2076 | |||
2077 | /***********************************************************************************/ | ||
2078 | /***********************************************************************************/ | ||
2079 | |||
2080 | ✗ | void ElementVector::print(int verbose,std::ostream& c) | |
2081 | { | ||
2082 | ✗ | if(verbose) { | |
2083 | ✗ | for (std::size_t i=0; i<numBlockRow(); i++) { | |
2084 | ✗ | c << "Block (" << i << "), "; | |
2085 | ✗ | c << vecBlock( i ) << std::endl; | |
2086 | } | ||
2087 | } | ||
2088 | } | ||
2089 | |||
2090 | /***********************************************************************************/ | ||
2091 | /***********************************************************************************/ | ||
2092 | |||
2093 | 1578000 | void ElementVector::GradientBasedHyperElasticityVector_grad_phi_i(const double coef, | |
2094 | const CurrentFiniteElement& finite_element, | ||
2095 | int quadraturePointIndex, | ||
2096 | UBlasVector& rhsPart, | ||
2097 | std::size_t iblock) | ||
2098 | { | ||
2099 | 1578000 | const std::size_t nC = finite_element.numRefCoor(); | |
2100 |
1/2✓ Branch 1 taken 1578000 times.
✗ Branch 2 not taken.
|
1578000 | const double modified_m_weightmeas = finite_element.weightMeas(quadraturePointIndex) * coef; |
2101 | |||
2102 |
2/4✓ Branch 2 taken 1578000 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1578000 times.
✗ Branch 6 not taken.
|
1578000 | const UBlasMatrix trans_dPhi = trans(finite_element.dPhi[quadraturePointIndex]); |
2103 | |||
2104 |
2/2✓ Branch 0 taken 3156000 times.
✓ Branch 1 taken 1578000 times.
|
4734000 | for (std::size_t icoor = 0u; icoor < nC; ++icoor) { |
2105 |
1/2✓ Branch 1 taken 3156000 times.
✗ Branch 2 not taken.
|
3156000 | UBlasVectorRange vec = vecBlock(iblock + icoor); |
2106 |
2/4✓ Branch 1 taken 3156000 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3156000 times.
✗ Branch 5 not taken.
|
3156000 | UBlasVectorRange Block(rhsPart, UBlasRange(icoor * nC, icoor * nC + nC)); |
2107 | |||
2108 |
3/6✓ Branch 1 taken 3156000 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3156000 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3156000 times.
✗ Branch 8 not taken.
|
3156000 | vec += modified_m_weightmeas * prod(trans_dPhi, Block); |
2109 | 3156000 | } | |
2110 | 1578000 | } | |
2111 | |||
2112 | /***********************************************************************************/ | ||
2113 | /***********************************************************************************/ | ||
2114 | |||
2115 | 1351020 | void ElementVector::stab_supgAdvDiffCT(const double dt, const double stab1, const double density, const double visc, const CurrentFiniteElement& feVel, const CurrentFiniteElement& fePres, | |
2116 | const ElementField& vel, const ElementField& pres, const ElementField& rhs) | ||
2117 | { | ||
2118 |
1/6✗ Branch 2 not taken.
✓ Branch 3 taken 1351020 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
1351020 | FEL_CHECK(feVel.numQuadraturePoint() == fePres.numQuadraturePoint(),"ElementVector::stab_supgAdvDiffCT: The quadrature rules must be the same for the two elements"); |
2119 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1351020 times.
|
1351020 | FEL_ASSERT(vel.type() == DOF_FIELD); |
2120 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1351020 times.
|
1351020 | FEL_ASSERT(pres.type() == DOF_FIELD); |
2121 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1351020 times.
|
1351020 | FEL_ASSERT(rhs.type() == DOF_FIELD); |
2122 | |||
2123 | // Resize if required | ||
2124 |
4/6✓ Branch 1 taken 1351020 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1351020 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 244 times.
✓ Branch 7 taken 1350776 times.
|
1351020 | if (m_tmpVec2Coor.size() != m_tmpVecCoor.size()) |
2125 |
2/4✓ Branch 1 taken 244 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 244 times.
✗ Branch 5 not taken.
|
244 | m_tmpVec2Coor.resize(m_tmpVecCoor.size()); |
2126 | |||
2127 | double weightJ, norm_u, aux, tau; | ||
2128 |
1/2✓ Branch 1 taken 1351020 times.
✗ Branch 2 not taken.
|
1351020 | const double h_elem = feVel.diameter(); |
2129 |
1/2✓ Branch 2 taken 1351020 times.
✗ Branch 3 not taken.
|
1351020 | UBlasVector tmpVecCoor3(feVel.numCoor()); |
2130 | |||
2131 |
2/2✓ Branch 1 taken 5404080 times.
✓ Branch 2 taken 1351020 times.
|
6755100 | for(int ig=0; ig<feVel.numQuadraturePoint(); ig++) { |
2132 |
1/2✓ Branch 1 taken 5404080 times.
✗ Branch 2 not taken.
|
5404080 | weightJ = feVel.weightMeas(ig); |
2133 | |||
2134 | // u at the integration point ig | ||
2135 |
2/4✓ Branch 2 taken 5404080 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5404080 times.
✗ Branch 6 not taken.
|
5404080 | m_tmpVecCoor = prod(vel.val, feVel.phi[ig]); // vel |
2136 | |||
2137 | // grad p at the integration point ig | ||
2138 |
2/2✓ Branch 1 taken 16212240 times.
✓ Branch 2 taken 5404080 times.
|
21616320 | for(int icomp=0; icomp<feVel.numCoor(); icomp++) { // grad pres |
2139 |
1/2✓ Branch 1 taken 16212240 times.
✗ Branch 2 not taken.
|
16212240 | m_tmpVec2Coor(icomp) = 0.0; |
2140 |
2/2✓ Branch 1 taken 64848960 times.
✓ Branch 2 taken 16212240 times.
|
81061200 | for(int idof=0; idof<fePres.numDof(); idof++) |
2141 |
3/6✓ Branch 2 taken 64848960 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 64848960 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 64848960 times.
✗ Branch 9 not taken.
|
64848960 | m_tmpVec2Coor(icomp) += fePres.dPhi[ig](icomp, idof)*pres.val(0, idof); |
2142 | } | ||
2143 | |||
2144 | // rhs at the integration point ig | ||
2145 |
2/4✓ Branch 2 taken 5404080 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5404080 times.
✗ Branch 6 not taken.
|
5404080 | tmpVecCoor3 = prod(rhs.val,feVel.phi[ig]); // rhs |
2146 | |||
2147 |
1/2✓ Branch 1 taken 5404080 times.
✗ Branch 2 not taken.
|
5404080 | norm_u = norm_1(m_tmpVecCoor); |
2148 | 5404080 | tau = 10.*stab1 / std::sqrt( (4./(dt*dt)) + | |
2149 | 5404080 | (4.*norm_u*norm_u)/(h_elem*h_elem) + | |
2150 | 5404080 | (16.*visc*visc)/(density*density*h_elem*h_elem*h_elem*h_elem) | |
2151 | ) / density; | ||
2152 | |||
2153 | // | ||
2154 |
2/2✓ Branch 1 taken 16212240 times.
✓ Branch 2 taken 5404080 times.
|
21616320 | for(int icomp=0; icomp< feVel.numCoor(); icomp++) { |
2155 |
1/2✓ Branch 1 taken 16212240 times.
✗ Branch 2 not taken.
|
16212240 | UBlasVectorRange vec = vecBlock(icomp); |
2156 | |||
2157 |
2/2✓ Branch 1 taken 64848960 times.
✓ Branch 2 taken 16212240 times.
|
81061200 | for(int idof=0; idof<feVel.numDof(); idof++) { |
2158 | 64848960 | aux = 0; | |
2159 |
2/2✓ Branch 1 taken 194546880 times.
✓ Branch 2 taken 64848960 times.
|
259395840 | for(int jcomp=0; jcomp< feVel.numCoor(); jcomp++) |
2160 |
2/4✓ Branch 1 taken 194546880 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 194546880 times.
✗ Branch 6 not taken.
|
194546880 | aux+=m_tmpVecCoor(jcomp)*feVel.dPhi[ig](jcomp,idof); |
2161 |
2/4✓ Branch 1 taken 64848960 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 64848960 times.
✗ Branch 5 not taken.
|
64848960 | vec(idof) -= m_tmpVec2Coor(icomp)*aux*tau*weightJ; // - grad p . vel . grad v |
2162 |
2/4✓ Branch 1 taken 64848960 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 64848960 times.
✗ Branch 5 not taken.
|
64848960 | vec(idof) += tmpVecCoor3(icomp)*aux*tau*weightJ; // rhs . vel . grad v |
2163 | }//idof | ||
2164 | 16212240 | }//icomp | |
2165 | |||
2166 | }//ig | ||
2167 | |||
2168 | 1351020 | } | |
2169 | |||
2170 | /***********************************************************************************/ | ||
2171 | /***********************************************************************************/ | ||
2172 | |||
2173 | 1312620 | void ElementVector::stab_supgProjCT(const double dt,const double stab1,const double density, const double visc, const CurrentFiniteElement& fe, | |
2174 | const ElementField& beta, const ElementField& vel, const ElementField& pres, | ||
2175 | const ElementField& rhs) | ||
2176 | { | ||
2177 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1312620 times.
|
1312620 | FEL_ASSERT(vel.type() == DOF_FIELD); |
2178 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1312620 times.
|
1312620 | FEL_ASSERT(pres.type() == DOF_FIELD); |
2179 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1312620 times.
|
1312620 | FEL_ASSERT(rhs.type() == DOF_FIELD); |
2180 | |||
2181 | // Resize if required | ||
2182 |
4/6✓ Branch 1 taken 1312620 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1312620 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 240 times.
✓ Branch 7 taken 1312380 times.
|
1312620 | if (m_tmpVec2Coor.size() != m_tmpVecCoor.size()) |
2183 |
2/4✓ Branch 1 taken 240 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 240 times.
✗ Branch 5 not taken.
|
240 | m_tmpVec2Coor.resize(m_tmpVecCoor.size()); |
2184 | |||
2185 | double norm_u, di2_u_icomp, tau; | ||
2186 |
1/2✓ Branch 1 taken 1312620 times.
✗ Branch 2 not taken.
|
1312620 | const double h_elem = fe.diameter(); |
2187 | |||
2188 |
1/2✓ Branch 2 taken 1312620 times.
✗ Branch 3 not taken.
|
1312620 | UBlasVector tmpVecCoor3(fe.numCoor()); |
2189 |
1/2✓ Branch 2 taken 1312620 times.
✗ Branch 3 not taken.
|
1312620 | UBlasVector tmpVecCoor4(fe.numCoor()); |
2190 | |||
2191 |
1/2✓ Branch 1 taken 1312620 times.
✗ Branch 2 not taken.
|
1312620 | UBlasVectorRange vec = vecBlock(0); |
2192 |
2/2✓ Branch 1 taken 5250480 times.
✓ Branch 2 taken 1312620 times.
|
6563100 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { |
2193 | |||
2194 | // u at the ig | ||
2195 |
2/4✓ Branch 2 taken 5250480 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5250480 times.
✗ Branch 6 not taken.
|
5250480 | m_tmpVecCoor = prod(beta.val, fe.phi[ig]); // beta |
2196 | |||
2197 | // grad p at the integration point ig | ||
2198 |
2/2✓ Branch 1 taken 15751440 times.
✓ Branch 2 taken 5250480 times.
|
21001920 | for(int icomp=0; icomp<fe.numCoor(); icomp++) { // grad pres |
2199 |
1/2✓ Branch 1 taken 15751440 times.
✗ Branch 2 not taken.
|
15751440 | m_tmpVec2Coor(icomp) = 0.0; |
2200 |
2/2✓ Branch 1 taken 63005760 times.
✓ Branch 2 taken 15751440 times.
|
78757200 | for(int idof=0; idof<fe.numDof(); idof++) |
2201 |
3/6✓ Branch 2 taken 63005760 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 63005760 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 63005760 times.
✗ Branch 9 not taken.
|
63005760 | m_tmpVec2Coor(icomp) += fe.dPhi[ig](icomp, idof)*pres.val(0, idof); |
2202 | } | ||
2203 | |||
2204 | // rhs at the integration point ig | ||
2205 |
2/4✓ Branch 2 taken 5250480 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5250480 times.
✗ Branch 6 not taken.
|
5250480 | tmpVecCoor3 = prod(rhs.val,fe.phi[ig]); // rhs |
2206 | |||
2207 |
2/2✓ Branch 1 taken 15751440 times.
✓ Branch 2 taken 5250480 times.
|
21001920 | for(int icomp=0; icomp<fe.numCoor(); icomp++) { |
2208 |
1/2✓ Branch 1 taken 15751440 times.
✗ Branch 2 not taken.
|
15751440 | tmpVecCoor4(icomp) = 0.0; |
2209 |
2/2✓ Branch 1 taken 47254320 times.
✓ Branch 2 taken 15751440 times.
|
63005760 | for(int i2comp=0; i2comp<fe.numCoor(); i2comp++) { |
2210 | 47254320 | di2_u_icomp = 0.0; | |
2211 | // compute d_a u_b | ||
2212 |
2/2✓ Branch 1 taken 189017280 times.
✓ Branch 2 taken 47254320 times.
|
236271600 | for (int jdof=0; jdof<fe.numDof(); jdof++) |
2213 |
2/4✓ Branch 2 taken 189017280 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 189017280 times.
✗ Branch 6 not taken.
|
189017280 | di2_u_icomp += fe.dPhi[ig](i2comp,jdof)*vel.val(icomp,jdof); |
2214 | |||
2215 | // u_a d_a(u_b) | ||
2216 |
2/4✓ Branch 1 taken 47254320 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 47254320 times.
✗ Branch 5 not taken.
|
47254320 | tmpVecCoor4(icomp) += m_tmpVecCoor(i2comp)*di2_u_icomp; |
2217 | } | ||
2218 | } | ||
2219 | |||
2220 | // stabilization parameter | ||
2221 |
1/2✓ Branch 1 taken 5250480 times.
✗ Branch 2 not taken.
|
5250480 | norm_u = norm_1(m_tmpVecCoor); |
2222 | 5250480 | tau = 10.*stab1 / std::sqrt( (4./(dt*dt)) + | |
2223 | 5250480 | (4.*norm_u*norm_u)/(h_elem*h_elem) + | |
2224 | 5250480 | (16.*visc*visc)/(density*density*h_elem*h_elem*h_elem*h_elem) | |
2225 | ) / density; | ||
2226 | |||
2227 | |||
2228 |
2/2✓ Branch 1 taken 21001920 times.
✓ Branch 2 taken 5250480 times.
|
26252400 | for(int idof=0; idof<fe.numDof(); idof++) |
2229 |
2/2✓ Branch 1 taken 63005760 times.
✓ Branch 2 taken 21001920 times.
|
84007680 | for(int icomp=0; icomp<fe.numCoor(); icomp++) { |
2230 | // - u . grad v | ||
2231 |
4/8✓ Branch 1 taken 63005760 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 63005760 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 63005760 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 63005760 times.
✗ Branch 12 not taken.
|
63005760 | vec(idof) -= tau * fe.weightMeas(ig) * tmpVecCoor4(icomp) * fe.dPhi[ig](icomp,idof); |
2232 | // + f . grad q | ||
2233 |
4/8✓ Branch 1 taken 63005760 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 63005760 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 63005760 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 63005760 times.
✗ Branch 12 not taken.
|
63005760 | vec(idof) += tau * fe.weightMeas(ig) * tmpVecCoor3(icomp) * fe.dPhi[ig](icomp,idof); |
2234 | // - grad p .grad q | ||
2235 |
4/8✓ Branch 1 taken 63005760 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 63005760 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 63005760 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 63005760 times.
✗ Branch 12 not taken.
|
63005760 | vec(idof) -= tau * fe.weightMeas(ig) * m_tmpVec2Coor(icomp)* fe.dPhi[ig](icomp,idof); |
2236 | } | ||
2237 | |||
2238 | }//ig | ||
2239 | |||
2240 | 1312620 | } | |
2241 | |||
2242 | /***********************************************************************************/ | ||
2243 | /***********************************************************************************/ | ||
2244 | |||
2245 | ✗ | void ElementVector::stab_supgRhsFS(const double dt, const double stabSUPG, const double density, const double viscosity, | |
2246 | const double c0, const double c1, const double c2, | ||
2247 | const CurrentFiniteElement& feVel, const CurrentFiniteElement& fePre, | ||
2248 | const ElementField& vel, const ElementField& pres, const ElementField& velRHS) | ||
2249 | { | ||
2250 | // \int_K [stabSUPG * tau * c0 * (vel . \grad) v] . [ c1 velRHS + c2 \grad pres] | ||
2251 | |||
2252 | ✗ | FEL_ASSERT(vel.type() == DOF_FIELD); | |
2253 | ✗ | FEL_ASSERT(pres.type() == DOF_FIELD); | |
2254 | ✗ | FEL_ASSERT(velRHS.type() == DOF_FIELD); | |
2255 | |||
2256 | // Resize if required | ||
2257 | ✗ | if (m_tmpVec2Coor.size() != m_tmpVecCoor.size()) | |
2258 | ✗ | m_tmpVec2Coor.resize(m_tmpVecCoor.size()); | |
2259 | |||
2260 | double weightJ, norm_u, aux; | ||
2261 | ✗ | const double h_elem = feVel.diameter(); | |
2262 | double tau; | ||
2263 | ✗ | UBlasVector tmpVecCoor3(feVel.numCoor()); | |
2264 | |||
2265 | ✗ | for(int ig=0; ig<feVel.numQuadraturePoint(); ig++) { | |
2266 | ✗ | weightJ = feVel.weightMeas(ig); | |
2267 | |||
2268 | // Computation of u and grad p in the element in the integration point ig | ||
2269 | // vel | ||
2270 | ✗ | m_tmpVecCoor = prod(vel.val, feVel.phi[ig]); | |
2271 | |||
2272 | // RHS vel | ||
2273 | ✗ | m_tmpVec2Coor = prod(velRHS.val, feVel.phi[ig]); | |
2274 | |||
2275 | // grad pres | ||
2276 | ✗ | for(int icomp=0; icomp<feVel.numCoor(); icomp++) { | |
2277 | ✗ | tmpVecCoor3(icomp) = 0.0; | |
2278 | ✗ | for(int idof=0; idof<fePre.numDof(); idof++) | |
2279 | ✗ | tmpVecCoor3(icomp) += fePre.dPhi[ig](icomp, idof) * pres.val(0, idof); | |
2280 | } | ||
2281 | |||
2282 | ✗ | norm_u = norm_1(m_tmpVecCoor); | |
2283 | |||
2284 | ✗ | tau = stabSUPG / std::sqrt( (4./(dt*dt)) + | |
2285 | ✗ | (4.*norm_u*norm_u)/(h_elem*h_elem) + | |
2286 | ✗ | (16*viscosity*viscosity)/(density*density*h_elem*h_elem*h_elem*h_elem)); | |
2287 | |||
2288 | ✗ | for(int icomp=0; icomp<feVel.numCoor(); icomp++) { | |
2289 | ✗ | UBlasVectorRange vec = vecBlock(icomp); | |
2290 | |||
2291 | ✗ | for(int idof=0; idof<feVel.numDof(); idof++) { | |
2292 | ✗ | aux = 0; | |
2293 | ✗ | for(int jcomp=0; jcomp<feVel.numCoor(); jcomp++) { | |
2294 | ✗ | aux += m_tmpVecCoor(jcomp) * feVel.dPhi[ig](jcomp, idof); | |
2295 | } | ||
2296 | ✗ | aux *= c0 * tau * weightJ; // tau * C_0 (U . \grad) . v_i | |
2297 | |||
2298 | ✗ | vec(idof) += c1 * aux * m_tmpVec2Coor(icomp); | |
2299 | ✗ | vec(idof) += c2 * aux * tmpVecCoor3(icomp); | |
2300 | } | ||
2301 | } | ||
2302 | } | ||
2303 | } | ||
2304 | |||
2305 | /***********************************************************************************/ | ||
2306 | /***********************************************************************************/ | ||
2307 | |||
2308 | ✗ | void ElementVector::quadratic(const double coef, const CurrentFiniteElement& fe,const ElementField& elfield, const int iblock,const int numComp) | |
2309 | { | ||
2310 | ✗ | if(numComp>1) { | |
2311 | ✗ | FEL_ERROR("Not defined for vector fields!") | |
2312 | } | ||
2313 | |||
2314 | double tmp; | ||
2315 | ✗ | switch(elfield.type()) { | |
2316 | ✗ | case CONSTANT_FIELD: | |
2317 | |||
2318 | ✗ | break; | |
2319 | ✗ | case QUAD_POINT_FIELD: | |
2320 | |||
2321 | ✗ | break; | |
2322 | |||
2323 | ✗ | case DOF_FIELD: | |
2324 | |||
2325 | ✗ | for(int icomp=0; icomp<numComp; icomp++) { | |
2326 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
2327 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
2328 | ✗ | tmp = 0.0; | |
2329 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
2330 | |||
2331 | ✗ | for(int jdof=0; jdof<fe.numDof(); jdof++) { | |
2332 | ✗ | for(int hdof=0; hdof<fe.numDof(); hdof++) { | |
2333 | ✗ | tmp += fe.phi[ig](jdof) * elfield.val(icomp,jdof) *fe.phi[ig](hdof) * elfield.val(icomp,hdof); | |
2334 | } | ||
2335 | } | ||
2336 | ✗ | vec(idof) += coef * tmp * fe.phi[ig](idof) * fe.weightMeas(ig); | |
2337 | } | ||
2338 | } | ||
2339 | |||
2340 | } | ||
2341 | ✗ | break; | |
2342 | } | ||
2343 | } | ||
2344 | |||
2345 | /***********************************************************************************/ | ||
2346 | /***********************************************************************************/ | ||
2347 | |||
2348 | ✗ | void ElementVector::sGrad_phi_i_tensor_sGrad_f(const double coef, const ElementField& f, const ElementField& normalField, const CurvilinearFiniteElement& fe, UBlasMatrix tensor) | |
2349 | { | ||
2350 | ✗ | UBlasVector sGradF(2); | |
2351 | ✗ | sGradF=Curvatures::elemFieldGradient(f); | |
2352 | |||
2353 | // if tensor is the invers of the first fundamental form you get the laplacian operator on the surface | ||
2354 | ✗ | UBlasVector KsGradF(2); | |
2355 | ✗ | KsGradF(0)=0.0; | |
2356 | ✗ | KsGradF(1)=0.0; | |
2357 | ✗ | KsGradF = prod(tensor, sGradF ); | |
2358 | |||
2359 | ✗ | for ( int iLocDof(0); iLocDof < fe.numDof(); iLocDof++) { | |
2360 | ✗ | UBlasVector sGradPhi_i(2); | |
2361 | ✗ | sGradPhi_i=Curvatures::testFuncGradient(iLocDof); | |
2362 | |||
2363 | ✗ | double val = coef * inner_prod(KsGradF, sGradPhi_i) * fe.measure(); | |
2364 | ✗ | for ( int iCoor(0); iCoor < fe.numCoor(); iCoor++) { | |
2365 | ✗ | double value = val*normalField.val(iCoor,iLocDof); // here we multiply the result by the normal std::vector in order to use the result in the NSSimplifiedFSI model | |
2366 | ✗ | UBlasVectorRange rhs = vecBlock(iCoor); | |
2367 | ✗ | rhs(iLocDof) += value; | |
2368 | } | ||
2369 | } | ||
2370 | } | ||
2371 | |||
2372 | /***********************************************************************************/ | ||
2373 | /***********************************************************************************/ | ||
2374 | |||
2375 | 931737 | void ElementVector::sGrad_phi_i_tensor_sGrad_f(const double coef, const ElementField& elemCoef, const ElementField& f, const ElementField& normalField, const CurvilinearFiniteElement& fe, UBlasMatrix tensor) | |
2376 | { | ||
2377 |
1/2✓ Branch 1 taken 931737 times.
✗ Branch 2 not taken.
|
931737 | UBlasVector tmpVecQuadPoint; |
2378 |
1/3✓ Branch 1 taken 931737 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
931737 | switch(elemCoef.type()) { |
2379 | 931737 | case DOF_FIELD: | |
2380 |
1/2✓ Branch 2 taken 931737 times.
✗ Branch 3 not taken.
|
931737 | tmpVecQuadPoint.resize(fe.numQuadraturePoint()); |
2381 |
2/2✓ Branch 1 taken 5590422 times.
✓ Branch 2 taken 931737 times.
|
6522159 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { |
2382 |
3/6✓ Branch 2 taken 5590422 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5590422 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 5590422 times.
✗ Branch 9 not taken.
|
5590422 | tmpVecQuadPoint(ig) = prod(elemCoef.val,fe.phi[ig])(0); |
2383 | } | ||
2384 | 931737 | break; | |
2385 | |||
2386 | ✗ | case CONSTANT_FIELD: | |
2387 | case QUAD_POINT_FIELD: | ||
2388 | ✗ | FEL_ERROR("this case has not been implemented"); | |
2389 | break; | ||
2390 | } | ||
2391 | |||
2392 |
1/2✓ Branch 1 taken 931737 times.
✗ Branch 2 not taken.
|
1863474 | UBlasVector sGradF(2); |
2393 |
2/4✓ Branch 1 taken 931737 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 931737 times.
✗ Branch 5 not taken.
|
931737 | sGradF=Curvatures::elemFieldGradient(f); |
2394 | |||
2395 | // if tensor is the invers of the first fundamental form you get the laplacian operator on the surface | ||
2396 |
1/2✓ Branch 1 taken 931737 times.
✗ Branch 2 not taken.
|
1863474 | UBlasVector KsGradF(2); |
2397 |
1/2✓ Branch 1 taken 931737 times.
✗ Branch 2 not taken.
|
931737 | KsGradF(0)=0.0; |
2398 |
1/2✓ Branch 1 taken 931737 times.
✗ Branch 2 not taken.
|
931737 | KsGradF(1)=0.0; |
2399 |
2/4✓ Branch 1 taken 931737 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 931737 times.
✗ Branch 5 not taken.
|
931737 | KsGradF = prod(tensor, sGradF ); |
2400 | |||
2401 |
2/2✓ Branch 1 taken 2795211 times.
✓ Branch 2 taken 931737 times.
|
3726948 | for ( int iLocDof(0); iLocDof < fe.numDof(); iLocDof++) { |
2402 |
1/2✓ Branch 1 taken 2795211 times.
✗ Branch 2 not taken.
|
2795211 | UBlasVector sGradPhi_i(2); |
2403 |
2/4✓ Branch 1 taken 2795211 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2795211 times.
✗ Branch 5 not taken.
|
2795211 | sGradPhi_i=Curvatures::testFuncGradient(iLocDof); |
2404 | |||
2405 | 2795211 | double val(0.0); | |
2406 |
2/2✓ Branch 1 taken 16771266 times.
✓ Branch 2 taken 2795211 times.
|
19566477 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) |
2407 |
3/6✓ Branch 1 taken 16771266 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16771266 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 16771266 times.
✗ Branch 8 not taken.
|
16771266 | val += coef * tmpVecQuadPoint(ig) * inner_prod(KsGradF, sGradPhi_i) * fe.weightMeas(ig); //TODO only P1! we should integrate, but gradient is constant over the element |
2408 |
2/2✓ Branch 1 taken 8385633 times.
✓ Branch 2 taken 2795211 times.
|
11180844 | for ( int iCoor(0); iCoor < fe.numCoor(); iCoor++) { |
2409 |
1/2✓ Branch 1 taken 8385633 times.
✗ Branch 2 not taken.
|
8385633 | double value = val*normalField.val(iCoor,iLocDof); // here we multiply the result by the normal std::vector in order to use the result in the NSSimplifiedFSI model |
2410 |
1/2✓ Branch 1 taken 8385633 times.
✗ Branch 2 not taken.
|
8385633 | UBlasVectorRange rhs = vecBlock(iCoor); |
2411 |
1/2✓ Branch 1 taken 8385633 times.
✗ Branch 2 not taken.
|
8385633 | rhs(iLocDof) += value; |
2412 | 8385633 | } | |
2413 | 2795211 | } | |
2414 | 931737 | } | |
2415 | |||
2416 | /***********************************************************************************/ | ||
2417 | /***********************************************************************************/ | ||
2418 | |||
2419 | 1 | void ElementVector::operator+=(const ElementVector& vec) | |
2420 | { | ||
2421 | 1 | m_vec += vec.vec(); | |
2422 | 1 | } | |
2423 | |||
2424 | /***********************************************************************************/ | ||
2425 | /***********************************************************************************/ | ||
2426 | |||
2427 | 1 | void ElementVector::operator-=(const ElementVector& vec) | |
2428 | { | ||
2429 | 1 | m_vec -= vec.vec(); | |
2430 | 1 | } | |
2431 | |||
2432 | /***********************************************************************************/ | ||
2433 | /***********************************************************************************/ | ||
2434 | |||
2435 | 1 | void ElementVector::operator*=(const double factor) | |
2436 | { | ||
2437 | 1 | m_vec *= factor; | |
2438 | 1 | } | |
2439 | |||
2440 | /***********************************************************************************/ | ||
2441 | /***********************************************************************************/ | ||
2442 | |||
2443 | 3717260 | void ElementVector::stab_supg(const double dt, const double stab1, const double density, const double visc, | |
2444 | const CurrentFiniteElement& fe,const ElementField& vel,const ElementField& rhs, | ||
2445 | double& Re_elem,double& tau, const int type) | ||
2446 | { | ||
2447 | /* | ||
2448 | Typical value for stab1 = 0.1 | ||
2449 | This stabilization does not include the 1/dt term (not strongly consistant with the time discrete scheme, may | ||
2450 | be viewed as a space-time, P0 in time) | ||
2451 | If type = 1: stabilization parameter depends on dt (Tezduyar) | ||
2452 | If type = 2: stabilization parameter independent of dt (Franca-Frey CMAME 1992) | ||
2453 | */ | ||
2454 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3717260 times.
|
3717260 | FEL_ASSERT(vel.type() == DOF_FIELD); |
2455 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3717260 times.
|
3717260 | FEL_ASSERT(rhs.type() == DOF_FIELD); |
2456 | |||
2457 | // Resize if required | ||
2458 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 3717260 times.
|
3717260 | if (m_tmpVec2Coor.size() != m_tmpVecCoor.size()) |
2459 | ✗ | m_tmpVec2Coor.resize(m_tmpVecCoor.size()); | |
2460 | |||
2461 | double weightJ,norm_u,s,adveps; | ||
2462 | 3717260 | const double h_elem = fe.diameter(); | |
2463 | int i0,i0_pres; | ||
2464 |
2/2✓ Branch 1 taken 14953300 times.
✓ Branch 2 taken 3717260 times.
|
18670560 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { |
2465 | 14953300 | weightJ = fe.weightMeas(ig); | |
2466 | // Computation of u and f in the element in the integration point ig | ||
2467 |
1/2✓ Branch 3 taken 14953300 times.
✗ Branch 4 not taken.
|
14953300 | m_tmpVecCoor = prod(vel.val,fe.phi[ig]); // vel |
2468 | 14953300 | norm_u = norm_1(m_tmpVecCoor); | |
2469 |
1/2✓ Branch 3 taken 14953300 times.
✗ Branch 4 not taken.
|
14953300 | m_tmpVec2Coor = prod(rhs.val,fe.phi[ig]); // rhs |
2470 | 14953300 | Re_elem = density*stab1*norm_u*h_elem/(4*visc); | |
2471 |
2/2✓ Branch 0 taken 14717926 times.
✓ Branch 1 taken 235374 times.
|
14953300 | if(Re_elem<1.0) { |
2472 | 14717926 | tau = stab1*density*h_elem*h_elem/(8*visc); | |
2473 | } else { | ||
2474 | 235374 | tau = h_elem/(2.*norm_u); | |
2475 | } | ||
2476 |
2/2✓ Branch 0 taken 4201300 times.
✓ Branch 1 taken 10752000 times.
|
14953300 | if(type==1) { |
2477 | 4201300 | tau = 10.*stab1 / std::sqrt( (4./(dt*dt)) + | |
2478 | 4201300 | (4.*norm_u*norm_u)/(h_elem*h_elem) + | |
2479 | 4201300 | (16.*visc*visc)/(density*density*h_elem*h_elem*h_elem*h_elem) | |
2480 | 4201300 | ) / density; | |
2481 | // coef 10 is to have a typical value of 0.1 as for type 2 | ||
2482 | } | ||
2483 |
1/2✓ Branch 0 taken 10752000 times.
✗ Branch 1 not taken.
|
10752000 | else if (type==2) { |
2484 | // FreeFem | ||
2485 | 10752000 | tau = stab1*h_elem*h_elem/visc; | |
2486 | } | ||
2487 | ✗ | else if (type==3) { | |
2488 | ✗ | tau = 10.*stab1 / std::sqrt( (16.*visc*visc)/(h_elem*h_elem*h_elem*h_elem) ); | |
2489 | } | ||
2490 | |||
2491 | 14953300 | int ncoor = fe.numCoor(); | |
2492 | 14953300 | i0_pres = m_firstRow[ncoor]; | |
2493 |
2/2✓ Branch 1 taken 59344420 times.
✓ Branch 2 taken 14953300 times.
|
74297720 | for(int idof=0; idof<fe.numDof(); idof++) { |
2494 | 59344420 | adveps=0.0; | |
2495 |
2/2✓ Branch 0 taken 176498920 times.
✓ Branch 1 taken 59344420 times.
|
235843340 | for(int kcoor=0; kcoor<ncoor; kcoor++) { |
2496 | 176498920 | adveps += m_tmpVecCoor[kcoor]* fe.dPhi[ig](kcoor,idof); | |
2497 | } | ||
2498 | 59344420 | adveps *= density*tau*weightJ;// rho (u.\gradv_i) | |
2499 | 59344420 | s=0.0; | |
2500 |
2/2✓ Branch 0 taken 176498920 times.
✓ Branch 1 taken 59344420 times.
|
235843340 | for(int icoor=0; icoor<ncoor; icoor++) { |
2501 | 176498920 | i0 = m_firstRow[icoor]; | |
2502 | 176498920 | m_vec(i0+idof) += m_tmpVec2Coor[icoor]*adveps; | |
2503 | 176498920 | s += fe.dPhi[ig](icoor,idof)*m_tmpVec2Coor(icoor); // same fe for velocity and pressure | |
2504 | } | ||
2505 | 59344420 | m_vec(i0_pres+idof) -= tau*s*weightJ; | |
2506 | |||
2507 | }// idof | ||
2508 | }// ig | ||
2509 | 3717260 | } | |
2510 | |||
2511 | /***********************************************************************************/ | ||
2512 | /***********************************************************************************/ | ||
2513 | |||
2514 | ✗ | void ElementVector::f_scalar_phi_i(const double coef,const CurrentFiniteElement& fe, const ElementField& elfield,const int iblock) | |
2515 | { | ||
2516 | double tmp; | ||
2517 | ✗ | for(int icomp=0; icomp<fe.numCoor(); icomp++) { | |
2518 | ✗ | UBlasVectorRange vec = vecBlock(iblock+icomp); | |
2519 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
2520 | ✗ | tmp = coef*fe.weightMeas(ig); | |
2521 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
2522 | ✗ | vec(idof) += tmp * elfield.val(icomp,idof); | |
2523 | } | ||
2524 | } | ||
2525 | } | ||
2526 | } | ||
2527 | |||
2528 | /***********************************************************************************/ | ||
2529 | /***********************************************************************************/ | ||
2530 | |||
2531 | ✗ | void ElementVector::div_u_div_phi_i(const double coef,const CurrentFiniteElement& fe, const ElementField& elfield, const int iblock) | |
2532 | { | ||
2533 | //rem : elfield is a dof field | ||
2534 | ✗ | for(int kcomp=0; kcomp<fe.numCoor(); kcomp++){ | |
2535 | ✗ | UBlasVectorRange vec = vecBlock(iblock+kcomp); | |
2536 | ✗ | for(int idof=0; idof<fe.numDof(); idof++) { | |
2537 | double tmpi,tmpj; | ||
2538 | ✗ | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { | |
2539 | ✗ | tmpi = 0.0; | |
2540 | ✗ | tmpj = 0.0; | |
2541 | ✗ | for(int jdof=0; jdof<fe.numDof(); jdof++){ | |
2542 | ✗ | for (int jcomp=0; jcomp<fe.numCoor(); jcomp++) { | |
2543 | ✗ | tmpi += fe.dPhi[ig](kcomp,idof); | |
2544 | ✗ | tmpj += fe.dPhi[ig](jcomp,jdof)*elfield.val(jcomp,jdof); | |
2545 | } | ||
2546 | } | ||
2547 | ✗ | vec(idof) += coef*tmpi*tmpj*fe.weightMeas(ig); | |
2548 | } | ||
2549 | } | ||
2550 | } | ||
2551 | } | ||
2552 | |||
2553 | /***********************************************************************************/ | ||
2554 | /***********************************************************************************/ | ||
2555 | |||
2556 | 193437 | void ElementVector::transpirationSurfStabRHS( const double coef, const ElementField& elemCoef, const ElementField& normalField, const ElementField& force, const CurvilinearFiniteElement& fe, UBlasMatrix tensor) | |
2557 | { | ||
2558 | // Tensor is supposed to be the inverse matric tensor | ||
2559 | // TODO compute directly it from fe! | ||
2560 |
1/2✓ Branch 2 taken 193437 times.
✗ Branch 3 not taken.
|
193437 | UBlasVector tmpVecQuadPoint( fe.numQuadraturePoint() ); |
2561 |
1/3✓ Branch 1 taken 193437 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
193437 | switch(elemCoef.type()) { |
2562 | 193437 | case DOF_FIELD: | |
2563 |
2/2✓ Branch 1 taken 1160622 times.
✓ Branch 2 taken 193437 times.
|
1354059 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { |
2564 |
2/4✓ Branch 2 taken 1160622 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1160622 times.
✗ Branch 6 not taken.
|
1160622 | m_tmpVecCoor = prod(elemCoef.val,fe.phi[ig]); |
2565 |
2/4✓ Branch 1 taken 1160622 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1160622 times.
✗ Branch 5 not taken.
|
1160622 | tmpVecQuadPoint(ig) = m_tmpVecCoor(0)*coef; |
2566 | } | ||
2567 | 193437 | break; | |
2568 | ✗ | case CONSTANT_FIELD: | |
2569 | case QUAD_POINT_FIELD: | ||
2570 | ✗ | FEL_ERROR("this case has not been implemented"); | |
2571 | break; | ||
2572 | } | ||
2573 | // Only P1 | ||
2574 | 193437 | double coeffQuad = 0.0; | |
2575 |
2/2✓ Branch 1 taken 1160622 times.
✓ Branch 2 taken 193437 times.
|
1354059 | for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { |
2576 |
3/6✓ Branch 1 taken 1160622 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1160622 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1160622 times.
✗ Branch 8 not taken.
|
1160622 | coeffQuad += tmpVecQuadPoint(ig) * fe.weightMeas(ig) * fe.diameter() ; |
2577 | } | ||
2578 | |||
2579 |
2/2✓ Branch 1 taken 580311 times.
✓ Branch 2 taken 193437 times.
|
773748 | for (int forceLocDof = 0; forceLocDof < fe.numDof(); forceLocDof++) { |
2580 |
2/2✓ Branch 1 taken 1740933 times.
✓ Branch 2 taken 580311 times.
|
2321244 | for (int testLocDof = 0; testLocDof < fe.numDof(); testLocDof++) { |
2581 | |||
2582 | // computation of (\nabla_c\phi_test)^T A^-1 \nabla_c\phi_sol | ||
2583 |
1/2✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
|
1740933 | UBlasVector gradForce(2); |
2584 |
1/2✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
|
1740933 | UBlasVector gradTest(2); |
2585 |
1/2✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
|
1740933 | UBlasVector KgradForce(2); |
2586 |
1/2✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
|
1740933 | KgradForce(0)=0.0; |
2587 |
1/2✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
|
1740933 | KgradForce(1)=0.0; |
2588 |
2/4✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1740933 times.
✗ Branch 5 not taken.
|
1740933 | gradForce = Curvatures::testFuncGradient(forceLocDof); |
2589 |
2/4✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1740933 times.
✗ Branch 5 not taken.
|
1740933 | gradTest = Curvatures::testFuncGradient(testLocDof); |
2590 |
2/4✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1740933 times.
✗ Branch 5 not taken.
|
1740933 | KgradForce = prod(tensor, gradForce ); |
2591 | |||
2592 |
1/2✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
|
1740933 | const double lap = inner_prod(KgradForce, gradTest); |
2593 | |||
2594 |
2/2✓ Branch 1 taken 5222799 times.
✓ Branch 2 taken 1740933 times.
|
6963732 | for ( int forceCoor(0); forceCoor < fe.numCoor(); forceCoor++) { |
2595 |
2/2✓ Branch 1 taken 15668397 times.
✓ Branch 2 taken 5222799 times.
|
20891196 | for ( int testCoor(0); testCoor < fe.numCoor(); testCoor++) { |
2596 | 15668397 | double projCoef = 0; | |
2597 |
2/2✓ Branch 1 taken 47005191 times.
✓ Branch 2 taken 15668397 times.
|
62673588 | for ( int ausCoor(0); ausCoor < fe.numCoor(); ++ausCoor ) { |
2598 | 47005191 | double deltaTest(0), deltaSol(0); | |
2599 |
2/2✓ Branch 0 taken 15668397 times.
✓ Branch 1 taken 31336794 times.
|
47005191 | if ( forceCoor - ausCoor == 0 ) |
2600 | 15668397 | deltaSol = 1; | |
2601 |
2/2✓ Branch 0 taken 15668397 times.
✓ Branch 1 taken 31336794 times.
|
47005191 | if ( testCoor - ausCoor == 0 ) |
2602 | 15668397 | deltaTest = 1; | |
2603 | // Setting normnorm | ||
2604 |
2/4✓ Branch 1 taken 47005191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 47005191 times.
✗ Branch 5 not taken.
|
47005191 | const double normnormSol = normalField.val( forceCoor, forceLocDof)*normalField.val(ausCoor, forceLocDof); |
2605 |
2/4✓ Branch 1 taken 47005191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 47005191 times.
✗ Branch 5 not taken.
|
47005191 | const double normnormTest = normalField.val(testCoor,testLocDof)*normalField.val(ausCoor,testLocDof); |
2606 | 47005191 | projCoef += ( deltaSol - normnormSol ) * ( deltaTest - normnormTest ); | |
2607 | } | ||
2608 | |||
2609 |
1/2✓ Branch 1 taken 15668397 times.
✗ Branch 2 not taken.
|
15668397 | const double value = projCoef * lap * coeffQuad * force.val(forceCoor,forceLocDof); |
2610 | |||
2611 |
1/2✓ Branch 1 taken 15668397 times.
✗ Branch 2 not taken.
|
15668397 | UBlasVectorRange vec = vecBlock(testCoor); |
2612 |
1/2✓ Branch 1 taken 15668397 times.
✗ Branch 2 not taken.
|
15668397 | vec(testLocDof) += value; |
2613 | 15668397 | } | |
2614 | } | ||
2615 | 1740933 | } | |
2616 | } | ||
2617 | 193437 | } | |
2618 | |||
2619 | /***********************************************************************************/ | ||
2620 | /***********************************************************************************/ | ||
2621 | |||
2622 | ✗ | void ElementVector::velocityConstraint(const double coef, const ElementField& disp, const CurvilinearFiniteElement& fe, const int iblock) | |
2623 | { | ||
2624 | ✗ | FEL_CHECK(fe.hasMeas() ,"ElementVector::velocityConstraint: requires covariant basis"); | |
2625 | ✗ | FEL_CHECK(disp.type() == DOF_FIELD,"ElementVector::velocityConstraint: wrong displacement field type"); | |
2626 | |||
2627 | ✗ | const UBlasMatrix& d = disp.val; | |
2628 | |||
2629 | ✗ | UBlasMatrix cbasis(fe.numRefCoor(),fe.numCoor()); // covariant basis in current configuation | |
2630 | ✗ | UBlasVector n(fe.numCoor()); // normal std::vector, not unitary | |
2631 | ✗ | UBlasMatrix datq(fe.numCoor(),fe.numQuadraturePoint()); // displacement at quadrature poins | |
2632 | |||
2633 | ✗ | for (int ic=0; ic <fe.numCoor(); ++ic) { | |
2634 | ✗ | for(int iq=0; iq<fe.numQuadraturePoint(); ++iq) { | |
2635 | ✗ | datq(ic,iq) = 0.0; | |
2636 | ✗ | for(int idof=0; idof<fe.numDof(); ++idof) { | |
2637 | ✗ | datq(ic,iq) += fe.phi[iq](idof) * d(ic,idof); | |
2638 | } | ||
2639 | } | ||
2640 | } | ||
2641 | |||
2642 | ✗ | UBlasVectorRange vec = vecBlock(iblock); | |
2643 | |||
2644 | // Loop on quadrature points | ||
2645 | ✗ | for (int iq=0; iq < fe.numQuadraturePoint(); ++iq) { | |
2646 | |||
2647 | // Covariant basis in current configuratgion | ||
2648 | ✗ | for (int ir=0; ir < fe.numRefCoor(); ++ir) { | |
2649 | ✗ | for (int ic=0; ic <fe.numCoor(); ++ic) { | |
2650 | ✗ | cbasis(ir,ic) = fe.m_covBasis[iq](ir,ic); | |
2651 | ✗ | for(int idof=0; idof< fe.numDof(); idof++) | |
2652 | ✗ | cbasis(ir,ic) += d(ic,idof)*fe.dPhiRef(iq)(ir,idof); | |
2653 | } | ||
2654 | } | ||
2655 | |||
2656 | ✗ | switch ( fe.numRefCoor() ) { // Warning: must be as in CurvilinearFiniteElement::computeNormal() | |
2657 | ✗ | case 1: | |
2658 | ✗ | n(0) = cbasis(0,1); | |
2659 | ✗ | n(1) = - cbasis(0,0); | |
2660 | ✗ | break; | |
2661 | ✗ | case 2: | |
2662 | ✗ | n(0) = fe.m_sign * ( cbasis(0,1) * cbasis(1,2) - cbasis(0,2)*cbasis(1,1) ); | |
2663 | ✗ | n(1) = fe.m_sign * ( cbasis(0,2) * cbasis(1,0) - cbasis(0,0)*cbasis(1,2) ); | |
2664 | ✗ | n(2) = fe.m_sign * ( cbasis(0,0) * cbasis(1,1) - cbasis(0,1)*cbasis(1,0) ); | |
2665 | ✗ | break; | |
2666 | ✗ | default: | |
2667 | ✗ | FEL_ERROR("ElementVector::velocityConstraint: numRefCoor must be 1 or 2"); | |
2668 | } | ||
2669 | |||
2670 | // Update residual in elementary std::vector | ||
2671 | ✗ | for (int ic=0; ic < fe.numCoor(); ++ic) | |
2672 | ✗ | vec(0) += coef*datq(ic,iq)*n(ic)*fe.quadratureRule().weight(iq); | |
2673 | } | ||
2674 | |||
2675 | } | ||
2676 | |||
2677 | /***********************************************************************************/ | ||
2678 | /***********************************************************************************/ | ||
2679 | |||
2680 | ✗ | void ElementVector::followerPressure(const double coef, const ElementField& press, const ElementField& disp, const CurvilinearFiniteElement& fe) | |
2681 | { | ||
2682 | ✗ | FEL_CHECK(fe.hasMeas() ,"ElementVector::followerPressure: requires covariant basis"); | |
2683 | ✗ | FEL_CHECK(disp.type() == DOF_FIELD,"ElementVector::followerPressure: wrong displacement field type"); | |
2684 | ✗ | FEL_CHECK(press.numComp() == 1,"ElementVector::followerPressure: wrong pressure field"); | |
2685 | |||
2686 | ✗ | const UBlasMatrix& d = disp.val; | |
2687 | |||
2688 | ✗ | UBlasMatrix cbasis(fe.numRefCoor(),fe.numCoor()); // covariant basis in current configuation | |
2689 | ✗ | UBlasVector n(fe.numCoor()); // normal std::vector, not unitary | |
2690 | ✗ | UBlasVector patq(fe.numQuadraturePoint()); // pressure at quadrature poins | |
2691 | |||
2692 | // Evaluate pressure at quadrature points | ||
2693 | ✗ | switch(press.type()) { | |
2694 | ✗ | case CONSTANT_FIELD: | |
2695 | ✗ | for(int iq=0; iq<fe.numQuadraturePoint(); ++iq) | |
2696 | ✗ | patq(iq) = press.val(0,0); | |
2697 | ✗ | break; | |
2698 | ✗ | case QUAD_POINT_FIELD: | |
2699 | ✗ | for(int iq=0; iq<fe.numQuadraturePoint(); ++iq) | |
2700 | ✗ | patq(iq) = press.val(0,iq); | |
2701 | ✗ | break; | |
2702 | ✗ | case DOF_FIELD: | |
2703 | ✗ | for(int iq=0; iq<fe.numQuadraturePoint(); ++iq) { | |
2704 | ✗ | patq(iq) = 0.0; | |
2705 | ✗ | for(int idof=0; idof<fe.numDof(); ++idof) | |
2706 | ✗ | patq(iq) += fe.phi[iq](idof) * press.val(0,idof); | |
2707 | } | ||
2708 | ✗ | break; | |
2709 | ✗ | default: | |
2710 | ✗ | FEL_ERROR("this pressure element field type has not been implemented"); | |
2711 | } | ||
2712 | |||
2713 | // Loop on quadrature points | ||
2714 | ✗ | for (int iq=0; iq < fe.numQuadraturePoint(); ++iq) { | |
2715 | |||
2716 | // covariant basis in current configuratgion | ||
2717 | ✗ | for (int ir=0; ir < fe.numRefCoor(); ++ir) { | |
2718 | ✗ | for (int ic=0; ic <fe.numCoor(); ++ic) { | |
2719 | ✗ | cbasis(ir,ic) = fe.m_covBasis[iq](ir,ic); | |
2720 | ✗ | for(int idof=0; idof< fe.numDof(); idof++) | |
2721 | ✗ | cbasis(ir,ic) += d(ic,idof)*fe.dPhiRef(iq)(ir,idof); | |
2722 | } | ||
2723 | } | ||
2724 | |||
2725 | ✗ | switch ( fe.numRefCoor() ) { // Warning: must be as in CurvilinearFiniteElement::computeNormal() | |
2726 | ✗ | case 1: | |
2727 | ✗ | n(0) = cbasis(0,1); | |
2728 | ✗ | n(1) = - cbasis(0,0); | |
2729 | ✗ | break; | |
2730 | ✗ | case 2: | |
2731 | ✗ | n(0) = fe.m_sign * ( cbasis(0,1) * cbasis(1,2) - cbasis(0,2)*cbasis(1,1) ); | |
2732 | ✗ | n(1) = fe.m_sign * ( cbasis(0,2) * cbasis(1,0) - cbasis(0,0)*cbasis(1,2) ); | |
2733 | ✗ | n(2) = fe.m_sign * ( cbasis(0,0) * cbasis(1,1) - cbasis(0,1)*cbasis(1,0) ); | |
2734 | ✗ | break; | |
2735 | ✗ | default: | |
2736 | ✗ | FEL_ERROR("ElementVector::followerPressure: numRefCoor must be 1 or 2"); | |
2737 | } | ||
2738 | |||
2739 | // Update residual in elementary std::vector | ||
2740 | ✗ | for (int ic=0; ic < fe.numCoor(); ++ic) { | |
2741 | ✗ | UBlasVectorRange vec = vecBlock(ic); | |
2742 | ✗ | for(int idof=0; idof< fe.numDof(); idof++) | |
2743 | ✗ | vec(idof) += coef*patq(iq)*n(ic)*fe.phi[iq](idof)*fe.quadratureRule().weight(iq); | |
2744 | } | ||
2745 | } | ||
2746 | } | ||
2747 | |||
2748 | } | ||
2749 |