GCC Code Coverage Report


Directory: ./
File: FiniteElement/elementMatrix.cpp
Date: 2024-04-14 07:32:34
Exec Total Coverage
Lines: 595 1553 38.3%
Branches: 655 3346 19.6%

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 <iomanip>
17 #include <numeric>
18
19 // External includes
20
21 // Project includes
22 #include "Core/felisceTools.hpp"
23 #include "FiniteElement/elementMatrix.hpp"
24 #include "Geometry/curvatures.hpp"
25
26 namespace felisce
27 {
28 ElementMatrix::ElementMatrix(const ElementMatrix& rOther)
29 : m_mat(rOther.m_mat),
30 m_numRow(rOther.m_numRow),
31 m_firstRow(rOther.m_firstRow),
32 m_numCol(rOther.m_numCol),
33 m_firstCol(rOther.m_firstCol),
34 m_tmpMat(rOther.m_tmpMat),
35 m_tmpVecCoor(rOther.m_tmpVecCoor),
36 m_tmpVec2Coor(rOther.m_tmpVec2Coor),
37 m_tmpVecDof(rOther.m_tmpVecDof),
38 m_tmpVec2Dof(rOther.m_tmpVec2Dof),
39 m_tmpVecQuadPoint(rOther.m_tmpVecQuadPoint)
40 {
41 }
42
43 /***********************************************************************************/
44 /***********************************************************************************/
45
46 300 ElementMatrix& ElementMatrix::operator=(const ElementMatrix& rOther)
47 {
48 300 m_mat = rOther.m_mat;
49 300 m_numRow = rOther.m_numRow;
50 300 m_firstRow = rOther.m_firstRow;
51 300 m_numCol =rOther.m_numCol;
52 300 m_firstCol = rOther.m_firstCol;
53 300 m_tmpMat = rOther.m_tmpMat;
54 300 m_tmpVecCoor = rOther.m_tmpVecCoor;
55 300 m_tmpVec2Coor = rOther.m_tmpVec2Coor;
56 300 m_tmpVecDof = rOther.m_tmpVecDof;
57 300 m_tmpVec2Dof = rOther.m_tmpVec2Dof;
58 300 m_tmpVecQuadPoint = rOther.m_tmpVecQuadPoint;
59 300 return *this;
60 }
61
62 /***********************************************************************************/
63 /***********************************************************************************/
64
65 120 void ElementMatrix::duplicateFrom(const ElementMatrix& elmat)
66 {
67 // Copy values
68 120 *this = elmat;
69
70 // Clear matrices
71 120 m_mat.clear();
72 120 m_tmpMat.clear();
73 120 }
74
75 /***********************************************************************************/
76 /***********************************************************************************/
77
78 184 ElementMatrix::ElementMatrix(const std::vector<const CurBaseFiniteElement*>& fe, const std::vector<std::size_t>& nbr, const std::vector<std::size_t>& nbc) :
79 184 ElementMatrix(fe, nbr, fe, nbc)
80 {
81
82 184 }
83
84 /***********************************************************************************/
85 /***********************************************************************************/
86
87 72223 ElementMatrix::ElementMatrix(const std::vector<const CurBaseFiniteElement*>& fer, const std::vector<std::size_t>& nbr, const std::vector<const CurBaseFiniteElement*>& fec, const std::vector<std::size_t>& nbc) :
88 193232 m_mat( std::inner_product(fer.begin(),fer.end(),nbr.begin(), 0, std::plus<std::size_t>(), [](auto a, auto b){ return a->numDof()*b; }),
89 193232 std::inner_product(fec.begin(),fec.end(),nbc.begin(), 0, std::plus<std::size_t>(), [](auto a, auto b){ return a->numDof()*b; }) ),
90
2/4
✓ Branch 4 taken 72223 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 72223 times.
✗ Branch 8 not taken.
193232 m_tmpMat( std::inner_product(fer.begin(),fer.end(),nbr.begin(), 0, std::plus<std::size_t>(), [](auto a, auto b){ return a->numDof()*b; }),
91
6/12
✓ Branch 9 taken 72223 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 72223 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 72223 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 72223 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 72223 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 72223 times.
✗ Branch 26 not taken.
265455 std::inner_product(fec.begin(),fec.end(),nbc.begin(), 0, std::plus<std::size_t>(), [](auto a, auto b){ return a->numDof()*b; }) )
92 {
93
1/2
✓ Branch 1 taken 72223 times.
✗ Branch 2 not taken.
72223 m_mat.clear();
94
1/2
✓ Branch 1 taken 72223 times.
✗ Branch 2 not taken.
72223 m_tmpMat.clear();
95
96 // TODO are the following used whenever there are one or two finite elements??
97 // If not would be better allocate the memory using an ad hoc method
98
2/2
✓ Branch 1 taken 23517 times.
✓ Branch 2 taken 48706 times.
72223 if (fer.size() == 1) {
99
1/2
✓ Branch 3 taken 23517 times.
✗ Branch 4 not taken.
23517 m_tmpVecCoor.resize(fer[0]->numCoor());
100
1/2
✓ Branch 3 taken 23517 times.
✗ Branch 4 not taken.
23517 m_tmpVecDof.resize(fer[0]->numDof());
101
1/2
✓ Branch 3 taken 23517 times.
✗ Branch 4 not taken.
23517 m_tmpVecQuadPoint.resize(fer[0]->numQuadraturePoint());
102
2/2
✓ Branch 1 taken 48666 times.
✓ Branch 2 taken 40 times.
48706 } else if (fer.size() == 2) {
103 // THIS LOOKS REALLY UGLY!!!!!!!!!!!!!!!! (different from the constructor with curvilinearFE.)
104 // CANNOT THIS BE MOVED ELSEWHERE ??? VM 2013/04
105 // Needed for the functions a_grad_phi_i_grad_phi_j and a_eps_phi_i_eps_phi_j
106
1/2
✓ Branch 3 taken 48666 times.
✗ Branch 4 not taken.
48666 m_tmpVecQuadPoint.resize(fer[1]->numQuadraturePoint());
107 }
108
109 //
110 72223 std::size_t sumr = std::accumulate(nbr.begin(),nbr.end(),0);
111 72223 std::size_t sumc = std::accumulate(nbc.begin(),nbc.end(),0);
112
1/2
✓ Branch 1 taken 72223 times.
✗ Branch 2 not taken.
72223 m_numRow.resize(sumr);
113
1/2
✓ Branch 1 taken 72223 times.
✗ Branch 2 not taken.
72223 m_firstRow.resize(sumr);
114
1/2
✓ Branch 1 taken 72223 times.
✗ Branch 2 not taken.
72223 m_numCol.resize(sumc);
115
1/2
✓ Branch 1 taken 72223 times.
✗ Branch 2 not taken.
72223 m_firstCol.resize(sumc);
116 //
117 72223 std::size_t first = 0;
118 72223 std::size_t start = 0;
119 72223 std::size_t end = 0;
120
2/2
✓ Branch 1 taken 121009 times.
✓ Branch 2 taken 72223 times.
193232 for (std::size_t i=0; i<nbr.size(); i++) {
121 121009 end += nbr[i];
122
2/2
✓ Branch 0 taken 267032 times.
✓ Branch 1 taken 121009 times.
388041 for (std::size_t n=start; n<end; n++){
123 267032 m_numRow[ n ]=fer[i]->numDof();
124 267032 m_firstRow[ n ]=first;
125 267032 first += fer[i]->numDof();
126 }
127 121009 start += nbr[i];
128 }
129 //
130 72223 first = 0;
131 72223 start = 0;
132 72223 end = 0;
133
2/2
✓ Branch 1 taken 121009 times.
✓ Branch 2 taken 72223 times.
193232 for (std::size_t i=0; i<nbc.size(); i++) {
134 121009 end += nbc[i];
135
2/2
✓ Branch 0 taken 267032 times.
✓ Branch 1 taken 121009 times.
388041 for (std::size_t n=start; n<end; n++){
136 267032 m_numCol[ n ]=fec[i]->numDof();
137 267032 m_firstCol[ n ]=first;
138 267032 first += fec[i]->numDof();
139 }
140 121009 start += nbc[i];
141 }
142 72223 }
143
144 /***********************************************************************************/
145 /***********************************************************************************/
146
147 ElementMatrix::ElementMatrix(const CurBaseFiniteElement& fe, const std::size_t nbr1, const std::size_t nbc1 ) :
148 ElementMatrix(std::vector<const CurBaseFiniteElement*>{&fe},
149 std::vector<std::size_t>{nbr1},
150 std::vector<std::size_t>{nbc1})
151 {
152
153 }
154
155 /***********************************************************************************/
156 /***********************************************************************************/
157
158 ElementMatrix::ElementMatrix(const CurBaseFiniteElement& fe1, const std::size_t nbr1, const std::size_t nbc1,
159 const CurBaseFiniteElement& fe2, const std::size_t nbr2, const std::size_t nbc2 ) :
160 ElementMatrix(std::vector<const CurBaseFiniteElement*>{&fe1,&fe2},
161 std::vector<std::size_t>{nbr1,nbr2},
162 std::vector<std::size_t>{nbc1,nbc2})
163 {
164
165 }
166
167 /***********************************************************************************/
168 /***********************************************************************************/
169
170 ElementMatrix::ElementMatrix(const CurBaseFiniteElement& fe1, const std::size_t nbr1, const std::size_t nbc1,
171 const CurBaseFiniteElement& fe2, const std::size_t nbr2, const std::size_t nbc2,
172 const CurBaseFiniteElement& fe3, const std::size_t nbr3, const std::size_t nbc3 ) :
173 ElementMatrix(std::vector<const CurBaseFiniteElement*>{&fe1,&fe2,&fe3},
174 std::vector<std::size_t>{nbr1,nbr2,nbr3},
175 std::vector<std::size_t>{nbc1,nbc2,nbc3})
176 {
177
178 }
179
180 /***********************************************************************************/
181 /***********************************************************************************/
182
183 61 void ElementMatrix::operator+=(const ElementMatrix& rhs)
184 {
185
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 61 times.
61 FEL_ASSERT(m_firstRow == rhs.m_firstRow);
186
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 61 times.
61 FEL_ASSERT(m_numCol == rhs.m_numCol);
187
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 61 times.
61 FEL_ASSERT(m_firstCol == rhs.m_firstCol);
188
189 61 m_mat += rhs.m_mat;
190 61 }
191
192 /***********************************************************************************/
193 /***********************************************************************************/
194
195 61 void ElementMatrix::operator-=(const ElementMatrix& rhs)
196 {
197
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 61 times.
61 FEL_ASSERT(m_firstRow == rhs.m_firstRow);
198
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 61 times.
61 FEL_ASSERT(m_numCol == rhs.m_numCol);
199
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 61 times.
61 FEL_ASSERT(m_firstCol == rhs.m_firstCol);
200
201 61 m_mat -= rhs.m_mat;
202 61 }
203
204 /***********************************************************************************/
205 /***********************************************************************************/
206
207 181 void ElementMatrix::operator*=(const double factor)
208 {
209 181 m_mat *= factor;
210 181 }
211
212 /***********************************************************************************/
213 /***********************************************************************************/
214
215 void ElementMatrix::print(std::size_t verbose,std::ostream& c) //cannot be "const" because of matrix_range.
216 {
217 if(verbose) {
218 for (std::size_t i=0; i<m_firstRow.size(); i++) {
219 for (std::size_t j=0; j<m_firstCol.size(); j++) {
220 c << "Block (" << i << "," << j << "): ";
221 UBlasMatrixRange b(m_mat,UBlasRange( m_firstRow[i], m_firstRow[i]+m_numRow[i]),
222 UBlasRange( m_firstCol[j], m_firstCol[j]+m_numCol[j]));
223 c << std::endl;
224 for(unsigned int ir=0; ir<m_numRow[i]; ir++) {
225 for(unsigned int ic=0; ic<m_numCol[j]; ic++) {
226 c << std::setw(12) << std::setprecision(9) << b(ir,ic) << " ";
227 }
228 c<< std::endl;
229 }
230 }
231 }
232 }
233 }
234
235 /***********************************************************************************/
236 /***********************************************************************************/
237
238 9745913 void ElementMatrix::grad_phi_i_grad_phi_j(const double coef,const CurrentFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
239 {
240
1/2
✓ Branch 1 taken 9745913 times.
✗ Branch 2 not taken.
9745913 m_tmpMat.clear();
241
1/2
✓ Branch 1 taken 9745913 times.
✗ Branch 2 not taken.
9745913 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
242
2/2
✓ Branch 1 taken 40299453 times.
✓ Branch 2 taken 9745913 times.
50045366 for(int ig=0, numQuadPoint = fe.numQuadraturePoint(); ig < numQuadPoint; ig++) {
243
5/10
✓ Branch 3 taken 40299453 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 40299453 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 40299453 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 40299453 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 40299453 times.
✗ Branch 16 not taken.
40299453 tmpBlock += coef * fe.weightMeas(ig) * prod(trans(fe.dPhi[ig]),fe.dPhi[ig]);
244 }
245
246
2/2
✓ Branch 0 taken 26476709 times.
✓ Branch 1 taken 9745913 times.
36222622 for(std::size_t icoor=0; icoor < num; icoor++) {
247
1/2
✓ Branch 1 taken 26476709 times.
✗ Branch 2 not taken.
26476709 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
248
1/2
✓ Branch 1 taken 26476709 times.
✗ Branch 2 not taken.
26476709 matrix += tmpBlock;
249 26476709 }
250 9745913 }
251
252 /***********************************************************************************/
253 /***********************************************************************************/
254
255 2760 void ElementMatrix::grad_phi_i_grad_phi_j(const double coef,const CurvilinearFiniteElement& fe,const std::size_t iblock, const std::size_t jblock,const std::size_t num)
256 {
257
1/2
✓ Branch 1 taken 2760 times.
✗ Branch 2 not taken.
2760 m_tmpMat.clear();
258
1/2
✓ Branch 1 taken 2760 times.
✗ Branch 2 not taken.
2760 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
259
1/2
✓ Branch 5 taken 2760 times.
✗ Branch 6 not taken.
2760 UBlasMatrix tmpAdPhi(fe.contravariantMetric[0].size1(), fe.dPhiRef(0).size2());
260
2/2
✓ Branch 1 taken 5520 times.
✓ Branch 2 taken 2760 times.
8280 for(int ig=0, numQuadPoint = fe.numQuadraturePoint(); ig < numQuadPoint; ig++) {
261
2/4
✓ Branch 3 taken 5520 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 5520 times.
✗ Branch 7 not taken.
5520 tmpAdPhi = prod(fe.contravariantMetric[ig],fe.dPhiRef(ig));
262
5/10
✓ Branch 2 taken 5520 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5520 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 5520 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 5520 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 5520 times.
✗ Branch 15 not taken.
5520 tmpBlock += coef*fe.weightMeas(ig)*prod(trans(fe.dPhiRef(ig)),tmpAdPhi);
263 }
264
265
2/2
✓ Branch 0 taken 2760 times.
✓ Branch 1 taken 2760 times.
5520 for(std::size_t icoor=0; icoor < num; icoor++) {
266
1/2
✓ Branch 1 taken 2760 times.
✗ Branch 2 not taken.
2760 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
267
1/2
✓ Branch 1 taken 2760 times.
✗ Branch 2 not taken.
2760 matrix += tmpBlock;
268 2760 }
269 2760 }
270
271 /***********************************************************************************/
272 /***********************************************************************************/
273
274 void ElementMatrix::u_grad_phi_j_phi_i(const double coef,const ElementField& vel, const CurvilinearFiniteElement& fe,const std::size_t iblock, const std::size_t jblock, const std::size_t num)
275 {
276 m_tmpMat.clear();
277 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock,jblock);
278
279 const int numDof = fe.numDof();
280 const int numRefCoor = fe.numRefCoor();
281 const int numCoor = fe.numCoor();
282 UBlasVector velContra(numRefCoor);
283
284 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
285 switch(vel.type()) {
286 case CONSTANT_FIELD:
287 // nothing to do : the constant field has been computed before the integration loop
288 for(int icoor=0; icoor<vel.numComp(); icoor++)
289 m_tmpVecCoor(icoor) = vel.val(icoor,0);
290 break;
291 case DOF_FIELD: {
292 m_tmpVecCoor = prod(vel.val,fe.phi[ig]);
293 break;
294 }
295 case QUAD_POINT_FIELD: {
296 for(int icoor=0; icoor<vel.numComp(); icoor++)
297 m_tmpVecCoor(icoor) = vel.val(icoor,ig);
298 break;
299 }
300 // Default case should appear with a warning at compile time instead of an error in runtime
301 // (that's truly the point of using enums as switch cases)
302 // default:
303 // FEL_ERROR("Operator 'u_grad_phi_j_phi_i' not yet implemented with this type of element fields");
304 }
305 const double weightMas = fe.weightMeas(ig);
306 double sum;
307
308 // Compute contravaint components of vel
309 for (int icoorRef=0; icoorRef < numRefCoor; icoorRef++){
310 sum = 0;
311 for (int icoor=0; icoor< numCoor; icoor++)
312 sum += m_tmpVecCoor(icoor)*fe.contravariantCompleteBasis[ig](icoor,icoorRef);
313 velContra(icoorRef) = sum;
314 }
315
316 // Compute direction derivative of the ref basis functions
317 for(int jdof=0; jdof< numDof; jdof++) {
318 sum = 0;
319 for (int icoorRef=0; icoorRef < numRefCoor; icoorRef++)
320 sum += fe.dPhiRef(ig)(icoorRef,jdof) * velContra(icoorRef) ;
321 m_tmpVecDof(jdof) = sum;
322 }
323 //m_tmpVecDof = prod(trans(fe.dPhi[ig]),m_tmpVecCoor); // m_tmpVecDof = vel \cdot \nabla \phi_i
324 for(int idof=0; idof<fe.numDof(); idof++) {
325 for(int jdof=0; jdof<fe.numDof(); jdof++) {
326 tmpblock(idof,jdof) += coef * weightMas * m_tmpVecDof(jdof) * fe.phi[ig](idof);
327 }
328 }
329 }
330
331 for(std::size_t icoor=0; icoor<num; icoor++) {
332 UBlasMatrixRange block = matBlock(iblock+icoor,jblock+icoor);
333 block += tmpblock;
334 }
335 }
336
337 /***********************************************************************************/
338 /***********************************************************************************/
339
340 void ElementMatrix::a_grad_phi_i_grad_phi_j(const double coef,const ElementField& scalfct,const CurrentFiniteElement& fe,const std::size_t iblock, const std::size_t jblock, const std::size_t num)
341 {
342 m_tmpMat.clear();
343 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
344
345 switch(scalfct.type()) {
346 case CONSTANT_FIELD:
347 // nothing to do : the constant field has been computed before the integration loop
348 for(int ig=0; ig<fe.numQuadraturePoint(); ig++)
349 m_tmpVecQuadPoint(ig) = scalfct.val(0,0);
350 break;
351 case DOF_FIELD:
352 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
353 m_tmpVecCoor = prod(scalfct.val,fe.phi[ig]);
354 m_tmpVecQuadPoint(ig) = m_tmpVecCoor(0);
355 }
356 break;
357 case QUAD_POINT_FIELD:
358 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
359 m_tmpVecQuadPoint(ig) = scalfct.val(0,ig);
360 }
361 break;
362 // Default case should appear with a warning at compile time instead of an error in runtime
363 // (that's truly the point of using enums as switch cases)
364 // default:
365 // FEL_ERROR("Operator 'a_grad_phi_i_grad_phi_j' not yet implemented with this type of element fields");
366 }
367
368 for(int ig=0; ig<fe.numQuadraturePoint(); ig++)
369 tmpblock += coef * m_tmpVecQuadPoint(ig) * fe.weightMeas(ig) * prod(trans(fe.dPhi[ig]),fe.dPhi[ig]);
370
371 for(std::size_t icoor=0; icoor<num; icoor++) {
372 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
373 matrix += tmpblock;
374 }
375 }
376
377 /***********************************************************************************/
378 /***********************************************************************************/
379
380 void ElementMatrix::a_grad_phi_i_grad_phi_j(const double coef,const ElementField& scalfct,const CurvilinearFiniteElement& fe,const std::size_t iblock, const std::size_t jblock, const std::size_t num)
381 {
382 m_tmpMat.clear();
383 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
384
385 switch(scalfct.type()) {
386 case CONSTANT_FIELD:
387 // nothing to do : the constant field has been computed before the integration loop
388 for(int ig=0; ig<fe.numQuadraturePoint(); ig++)
389 m_tmpVecQuadPoint(ig) = scalfct.val(0,0);
390 break;
391 case DOF_FIELD:
392 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
393 m_tmpVecCoor = prod(scalfct.val,fe.phi[ig]);
394 m_tmpVecQuadPoint(ig) = m_tmpVecCoor(0);
395 }
396 break;
397 case QUAD_POINT_FIELD:
398 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
399 m_tmpVecQuadPoint(ig) = scalfct.val(0,ig);
400 }
401 break;
402 // Default case should appear with a warning at compile time instead of an error in runtime
403 // (that's truly the point of using enums as switch cases)
404 // default:
405 // FEL_ERROR("Operator 'a_grad_phi_i_grad_phi_j' not yet implemented with this type of element fields");
406 }
407 UBlasMatrix tmpAdPhi;
408 for(int ig=0, numQuadPoint = fe.numQuadraturePoint(); ig < numQuadPoint; ig++) {
409 tmpAdPhi = prod(fe.contravariantMetric[ig],fe.dPhiRef(ig));
410 tmpBlock += coef*fe.weightMeas(ig)*m_tmpVecQuadPoint(ig)*prod(trans(fe.dPhiRef(ig)),tmpAdPhi);
411 }
412
413 for(std::size_t icoor=0; icoor<num; icoor++) {
414 UBlasMatrixRange mat = matBlock(iblock+icoor,jblock+icoor);
415 mat += tmpBlock;
416 }
417 }
418
419 /***********************************************************************************/
420 /***********************************************************************************/
421
422 8133273 void ElementMatrix::eps_phi_i_eps_phi_j(const double coef,const CurrentFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
423 {
424
1/2
✓ Branch 1 taken 8133273 times.
✗ Branch 2 not taken.
8133273 m_tmpMat.clear();
425 8133273 const double f2 = 0.5 *coef;
426
1/2
✓ Branch 1 taken 8133273 times.
✗ Branch 2 not taken.
8133273 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
427
428
1/2
✓ Branch 1 taken 8133273 times.
✗ Branch 2 not taken.
8133273 grad_phi_i_grad_phi_j(f2, fe, iblock, jblock, num);
429
430 // Add the cross terms and the remaining diagonal term.
431
2/2
✓ Branch 0 taken 24168943 times.
✓ Branch 1 taken 8133273 times.
32302216 for (std::size_t icoor=0; icoor<num; icoor++) {
432
2/2
✓ Branch 0 taken 72045077 times.
✓ Branch 1 taken 24168943 times.
96214020 for (std::size_t jcoor=0; jcoor<num; jcoor++) {
433
2/2
✓ Branch 1 taken 287288804 times.
✓ Branch 2 taken 72045077 times.
359333881 for(int idof=0; idof<fe.numDof(); idof++) {
434
2/2
✓ Branch 1 taken 1146480704 times.
✓ Branch 2 taken 287288804 times.
1433769508 for(int jdof=0; jdof<fe.numDof(); jdof++) {
435
1/2
✓ Branch 1 taken 1146480704 times.
✗ Branch 2 not taken.
1146480704 tmpBlock(idof,jdof) = 0.;
436
2/2
✓ Branch 1 taken 4742319488 times.
✓ Branch 2 taken 1146480704 times.
5888800192 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
437
4/8
✓ Branch 1 taken 4742319488 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4742319488 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 4742319488 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 4742319488 times.
✗ Branch 13 not taken.
4742319488 tmpBlock(idof,jdof) += f2 * fe.weightMeas(ig) * fe.dPhi[ig](icoor,jdof) * fe.dPhi[ig](jcoor,idof);
438 }
439 }
440 }
441
442
1/2
✓ Branch 1 taken 72045077 times.
✗ Branch 2 not taken.
72045077 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+jcoor);
443
1/2
✓ Branch 1 taken 72045077 times.
✗ Branch 2 not taken.
72045077 matrix += tmpBlock;
444 72045077 }
445 }
446 8133273 }
447
448 /***********************************************************************************/
449 /***********************************************************************************/
450
451 void ElementMatrix::a_eps_phi_i_eps_phi_j(const double coef,const ElementField& scalfct,const CurrentFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
452 {
453 m_tmpMat.clear();
454 const double f2 = 0.5 *coef;
455 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
456
457 switch(scalfct.type()) {
458 case CONSTANT_FIELD:
459 // nothing to do : the constant field has been computed before the integration loop
460 for(int ig=0; ig<fe.numQuadraturePoint(); ig++)
461 m_tmpVecQuadPoint(ig) = scalfct.val(0,0);
462 break;
463 case DOF_FIELD:
464 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
465 m_tmpVecCoor = prod(scalfct.val,fe.phi[ig]);
466 m_tmpVecQuadPoint(ig) = m_tmpVecCoor(0);
467 }
468 break;
469 case QUAD_POINT_FIELD:
470 for(int ig=0; ig<fe.numQuadraturePoint(); ig++)
471 m_tmpVecQuadPoint(ig) = scalfct.val(0,ig);
472 break;
473 // Default case should appear with a warning at compile time instead of an error in runtime
474 // (that's truly the point of using enums as switch cases)
475 // default:
476 // FEL_ERROR("Operator 'a_eps_phi_i_eps_phi_j' not yet implemented with this type of element fields");
477 }
478
479 for(int ig=0; ig<fe.numQuadraturePoint(); ig++)
480 tmpBlock += f2 * m_tmpVecQuadPoint(ig) * fe.weightMeas(ig) * prod(trans(fe.dPhi[ig]),fe.dPhi[ig]);
481
482 // Laplace operator on each velocity components
483 for(std::size_t icoor=0; icoor<num; icoor++) {
484 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
485 matrix += tmpBlock;
486 }
487
488 // Cross terms
489 for (int icoor=0; icoor<fe.numRefCoor(); icoor++) {
490 for (int jcoor=0; jcoor<fe.numRefCoor(); jcoor++) {
491 for(int idof=0; idof<fe.numDof(); idof++) {
492 for(int jdof=0; jdof<fe.numDof(); jdof++) {
493 tmpBlock(idof,jdof) = 0.;
494 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
495 tmpBlock(idof,jdof) += f2 * m_tmpVecQuadPoint(ig) * fe.weightMeas(ig) * fe.dPhi[ig](icoor,idof) * fe.dPhi[ig](jcoor,jdof);
496 }
497 }
498 }
499 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+jcoor);
500 matrix += tmpBlock;
501 }
502 }
503 }
504
505 /***********************************************************************************/
506 /***********************************************************************************/
507
508 242 void ElementMatrix::tau_grad_phi_i_tau_grad_phi_j(const double coef,const std::vector<double>& diffTensor,const CurrentFiniteElement& fe,const std::size_t iblock, const std::size_t jblock,const std::size_t num,std::size_t dim)
509 {
510
1/2
✓ Branch 1 taken 242 times.
✗ Branch 2 not taken.
242 m_tmpMat.clear();
511
1/2
✓ Branch 1 taken 242 times.
✗ Branch 2 not taken.
242 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
512 double norm;
513
1/2
✓ Branch 1 taken 242 times.
✗ Branch 2 not taken.
242 UBlasMatrix vec_tensor(dim,1);
514
1/2
✓ Branch 1 taken 242 times.
✗ Branch 2 not taken.
242 UBlasMatrix tensor(dim,dim);
515 //compute diffTensor at quadrature point
516
2/2
✓ Branch 1 taken 1452 times.
✓ Branch 2 taken 242 times.
1694 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
517
2/2
✓ Branch 0 taken 2904 times.
✓ Branch 1 taken 1452 times.
4356 for (int icoor=0; icoor<static_cast<int>(dim); icoor++) {
518
1/2
✓ Branch 1 taken 2904 times.
✗ Branch 2 not taken.
2904 vec_tensor(icoor,0) = 0.;
519 }
520
2/2
✓ Branch 1 taken 2904 times.
✓ Branch 2 taken 1452 times.
4356 for (std::size_t icoor=0; icoor<std::size_t(fe.numCoor()); icoor++) {
521
2/2
✓ Branch 1 taken 8712 times.
✓ Branch 2 taken 2904 times.
11616 for (int idof=0; idof<fe.numDof(); idof++) {
522
2/4
✓ Branch 2 taken 8712 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 8712 times.
✗ Branch 7 not taken.
8712 vec_tensor(icoor,0) += fe.phi[ig](idof)*diffTensor[icoor+dim*idof];
523 }
524 }
525 1452 norm = 0.;
526
2/2
✓ Branch 0 taken 2904 times.
✓ Branch 1 taken 1452 times.
4356 for (std::size_t icoor=0; icoor<dim; icoor++) {
527
2/4
✓ Branch 1 taken 2904 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2904 times.
✗ Branch 5 not taken.
2904 norm += vec_tensor(icoor,0)*vec_tensor(icoor,0);
528 }
529
1/2
✓ Branch 0 taken 1452 times.
✗ Branch 1 not taken.
1452 if (std::fabs(norm) < 1.0e-8)
530
4/8
✓ Branch 1 taken 1452 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1452 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1452 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1452 times.
✗ Branch 11 not taken.
1452 tensor = 0.0 * prod(vec_tensor,trans(vec_tensor));
531 else
532 tensor = 1./norm * prod(vec_tensor,trans(vec_tensor));
533
534
6/12
✓ Branch 3 taken 1452 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1452 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1452 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1452 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1452 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1452 times.
✗ Branch 19 not taken.
1452 tmpBlock += coef * fe.weightMeas(ig) * prod(trans(prod(tensor,fe.dPhi[ig])),fe.dPhi[ig]);
535 }
536
2/2
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 242 times.
484 for(std::size_t icoor=0; icoor<num; icoor++) {
537
1/2
✓ Branch 1 taken 242 times.
✗ Branch 2 not taken.
242 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
538
1/2
✓ Branch 1 taken 242 times.
✗ Branch 2 not taken.
242 matrix += tmpBlock;
539 242 }
540 242 }
541
542 /***********************************************************************************/
543 /***********************************************************************************/
544
545 void ElementMatrix::tau_grad_phi_i_tau_grad_phi_j(const double coef,const std::vector<double>& diffTensor,const CurvilinearFiniteElement& fe,const std::size_t iblock, const std::size_t jblock,const std::size_t num)
546 {
547 //For fibers in cardiac electrophysiology
548 m_tmpMat.clear();
549 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
550 UBlasVector vec_tensor(3);
551 double norm;
552 UBlasVector sp_covBasis(2);
553 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
554 vec_tensor.clear();
555 for (int icoor=0; icoor<fe.numCoor(); icoor++) {
556 for (int idof=0; idof<fe.numDof(); idof++) {
557 vec_tensor(icoor) += fe.phi[ig](idof)*diffTensor[icoor+3*idof];
558 }
559 }
560 norm = norm_2(vec_tensor);
561
562 sp_covBasis(0) = vec_tensor(0)*fe.contravariantCompleteBasis[ig](0,0)+vec_tensor(1)*fe.contravariantCompleteBasis[ig](1,0)+vec_tensor(2)*fe.contravariantCompleteBasis[ig](2,0);
563 sp_covBasis(1) = vec_tensor(0)*fe.contravariantCompleteBasis[ig](0,1)+vec_tensor(1)*fe.contravariantCompleteBasis[ig](1,1)+vec_tensor(2)*fe.contravariantCompleteBasis[ig](2,1);
564 for (int idof=0; idof<fe.numDof(); idof++) {
565 for(int jdof=0; jdof<fe.numDof(); jdof++) {
566 for (int icoor=0; icoor<fe.numRefCoor(); icoor++) {
567 for (int jcoor=0; jcoor<fe.numRefCoor(); jcoor++) {
568 if (Tools::equal(norm,0.)) {
569 tmpBlock(idof,jdof) = 0.;
570 } else {
571 tmpBlock(idof,jdof) += coef / norm * (fe.weightMeas(ig) * fe.dPhiRef(ig)(icoor,idof) * sp_covBasis(icoor) * sp_covBasis(jcoor) * fe.dPhiRef(ig)(jcoor,jdof));
572 }
573 }
574 }
575 }
576 }
577 }
578 for(std::size_t icoor=0; icoor<num; icoor++) {
579 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
580 matrix += tmpBlock;
581 }
582 }
583
584 /***********************************************************************************/
585 /***********************************************************************************/
586
587 void ElementMatrix::tau_orthotau_grad_phi_i_grad_phi_j(const double coef,const std::vector<double>& diffTensor,const std::vector<double>& angle,const CurvilinearFiniteElement& fe,const std::size_t iblock, const std::size_t jblock,const std::size_t num)
588 {
589 m_tmpMat.clear();
590 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
591
592 // tau in quadrature point
593 UBlasVector vec_tensor(3);
594
595 // Orthogonal vector of tau in the tangent plane
596 UBlasVector vec_ortho_tensor(3);
597
598 // Decomposition of tau in the covariant basis
599 UBlasVector tau_covBasis(2);
600
601 // Decomposition of the tau orthogonal in the covariant basis
602 UBlasVector tau_ortho_covBasis(2);
603
604 // Norm of vector tau
605 double norm = 0.;
606
607 // Fibers in the atria turn
608 double Theta = 0.;
609 double iTheta = 0.;
610 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
611 vec_tensor(0) = 0.;
612 vec_tensor(1) = 0.;
613 vec_tensor(2) = 0.;
614 for (int icoor=0; icoor<fe.numCoor(); icoor++) {
615 for (int idof=0; idof<fe.numDof(); idof++) {
616 vec_tensor(icoor) += fe.phi[ig](idof)*diffTensor[icoor+3*idof];
617 }
618 }
619 for (int idof=0; idof<fe.numDof(); idof++) {
620 Theta = angle[idof];
621
622 if (std::fabs(Theta) < 1.0e-8) {
623 iTheta = 1.;
624 } else {
625 iTheta = 1./2.+ std::sin(2.* Theta)/(4.* Theta);
626 }
627
628 norm = vec_tensor(0)*vec_tensor(0)+vec_tensor(1)*vec_tensor(1)+vec_tensor(2)*vec_tensor(2);
629 //vec_ortho_tensor = vec_tensor vec a_3
630 vec_ortho_tensor(0) = - fe.contravariantCompleteBasis[ig](1,2)*vec_tensor(2) + fe.contravariantCompleteBasis[ig](2,2)*vec_tensor(1);
631 vec_ortho_tensor(1) = - fe.contravariantCompleteBasis[ig](2,2)*vec_tensor(0) + fe.contravariantCompleteBasis[ig](0,2)*vec_tensor(2);
632 vec_ortho_tensor(2) = - fe.contravariantCompleteBasis[ig](0,2)*vec_tensor(1) + fe.contravariantCompleteBasis[ig](1,2)*vec_tensor(0);
633
634 //(vec_tensor.a^1) and (vec_tensor.a^2)
635 tau_covBasis(0) = vec_tensor(0)*fe.contravariantCompleteBasis[ig](0,0) + vec_tensor(1)*fe.contravariantCompleteBasis[ig](1,0) + vec_tensor(2)*fe.contravariantCompleteBasis[ig](2,0);
636 tau_covBasis(1) = vec_tensor(0)*fe.contravariantCompleteBasis[ig](0,1) + vec_tensor(1)*fe.contravariantCompleteBasis[ig](1,1) + vec_tensor(2)*fe.contravariantCompleteBasis[ig](2,1);
637
638 //(diffTensorOrtho.a^1) and (diffTensorOrtho.a^2)
639 tau_ortho_covBasis(0) = vec_ortho_tensor(0)*fe.contravariantCompleteBasis[ig](0,0) + vec_ortho_tensor(1)*fe.contravariantCompleteBasis[ig](1,0) + vec_ortho_tensor(2)*fe.contravariantCompleteBasis[ig](2,0);
640 tau_ortho_covBasis(1) = vec_ortho_tensor(0)*fe.contravariantCompleteBasis[ig](0,1) + vec_ortho_tensor(1)*fe.contravariantCompleteBasis[ig](1,1) + vec_ortho_tensor(2)*fe.contravariantCompleteBasis[ig](2,1);
641 }
642 for (int idof=0; idof<fe.numDof(); idof++) {
643 for(int jdof=0; jdof<fe.numDof(); jdof++) {
644 for (int icoor=0; icoor<fe.numRefCoor(); icoor++) {
645 for (int jcoor=0; jcoor<fe.numRefCoor(); jcoor++) {
646 if (std::fabs(norm) < 1.0e-8) {
647 tmpBlock(idof,jdof) = 0.;
648 } else {
649 tmpBlock(idof,jdof) += coef / norm * fe.weightMeas(ig) * (iTheta * fe.dPhiRef(ig)(icoor,idof) * tau_covBasis(icoor) * tau_covBasis(jcoor) * fe.dPhiRef(ig)(jcoor,jdof) + (1. - iTheta) * fe.dPhiRef(ig)(icoor,idof) * tau_ortho_covBasis(icoor) * tau_ortho_covBasis(jcoor) * fe.dPhiRef(ig)(jcoor,jdof));
650 }
651 }
652 }
653 }
654 }
655 }
656
657 for(std::size_t icoor=0; icoor<num; icoor++) {
658 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
659 matrix += tmpBlock;
660 }
661 }
662
663 /***********************************************************************************/
664 /***********************************************************************************/
665
666 4209 void ElementMatrix::grad_phi_i_GradientBasedElastTensor_grad_phi_j(const double coef,
667 const CurrentFiniteElement& fe,
668 UBlasMatrix& GradientBasedElastTensor,
669 const std::size_t iblock, const std::size_t jblock)
670 {
671 4209 const std::size_t nC = fe.numRefCoor();
672 4209 const int numQuadraturePoint = fe.numQuadraturePoint();
673 4209 const std::vector<UBlasMatrix>& dPhi = fe.dPhi; // alias
674
675
2/2
✓ Branch 0 taken 8618 times.
✓ Branch 1 taken 4209 times.
12827 for (std::size_t icoor = 0u; icoor < nC; ++icoor) {
676
2/2
✓ Branch 0 taken 17836 times.
✓ Branch 1 taken 8618 times.
26454 for (std::size_t jcoor = 0u; jcoor < nC; ++jcoor) {
677
1/2
✓ Branch 1 taken 17836 times.
✗ Branch 2 not taken.
17836 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + jcoor);
678
679 UBlasMatrixRange Block(GradientBasedElastTensor,
680
1/2
✓ Branch 1 taken 17836 times.
✗ Branch 2 not taken.
17836 UBlasRange(icoor * nC, icoor * nC + nC),
681
2/4
✓ Branch 1 taken 17836 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17836 times.
✗ Branch 5 not taken.
35672 UBlasRange(jcoor * nC, jcoor * nC + nC));
682
683
2/2
✓ Branch 0 taken 55544 times.
✓ Branch 1 taken 17836 times.
73380 for(int ig = 0; ig < numQuadraturePoint; ++ig) {
684
3/6
✓ Branch 2 taken 55544 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 55544 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 55544 times.
✗ Branch 9 not taken.
111088 UBlasMatrix tmpBlock = prod(trans(dPhi[ig]), Block);
685
4/8
✓ Branch 2 taken 55544 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 55544 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 55544 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 55544 times.
✗ Branch 12 not taken.
55544 matrix += coef * fe.weightMeas(ig) * prod(tmpBlock, dPhi[ig]);
686 55544 }
687 17836 }
688 }
689 4209 }
690
691 /***********************************************************************************/
692 /***********************************************************************************/
693
694 1578000 void ElementMatrix::grad_phi_i_GradientBasedHyperElastTensor_grad_phi_j(const double coef,
695 const CurrentFiniteElement& finite_element,
696 int quadraturePointIndex,
697 UBlasMatrix& GradientBasedHyperElastTensor,
698 const std::size_t iblock, const std::size_t jblock)
699 {
700 1578000 const std::size_t nC = finite_element.numRefCoor();
701
702 1578000 const UBlasMatrix& dPhi = finite_element.dPhi[quadraturePointIndex]; // alias
703
1/2
✓ Branch 1 taken 1578000 times.
✗ Branch 2 not taken.
1578000 const double modified_m_weightmeas = finite_element.weightMeas(quadraturePointIndex) * coef;
704
705
2/2
✓ Branch 0 taken 3156000 times.
✓ Branch 1 taken 1578000 times.
4734000 for (std::size_t icoor = 0u; icoor < nC; ++icoor) {
706
2/2
✓ Branch 0 taken 6312000 times.
✓ Branch 1 taken 3156000 times.
9468000 for (std::size_t jcoor = 0u; jcoor < nC; ++jcoor) {
707
1/2
✓ Branch 1 taken 6312000 times.
✗ Branch 2 not taken.
6312000 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + jcoor);
708
709 UBlasMatrixRange Block(GradientBasedHyperElastTensor,
710
1/2
✓ Branch 1 taken 6312000 times.
✗ Branch 2 not taken.
6312000 UBlasRange(icoor * nC, icoor * nC + nC),
711
2/4
✓ Branch 1 taken 6312000 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6312000 times.
✗ Branch 5 not taken.
12624000 UBlasRange(jcoor * nC, jcoor * nC + nC));
712
713
3/6
✓ Branch 1 taken 6312000 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6312000 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6312000 times.
✗ Branch 8 not taken.
12624000 UBlasMatrix tmpBlock = prod(trans(dPhi), Block);
714
3/6
✓ Branch 1 taken 6312000 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6312000 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6312000 times.
✗ Branch 8 not taken.
6312000 matrix += modified_m_weightmeas * prod(tmpBlock, dPhi);
715 6312000 }
716 }
717 1578000 }
718
719 /***********************************************************************************/
720 /***********************************************************************************/
721
722 8316850 void ElementMatrix::phi_i_phi_j(const double coef,const CurBaseFiniteElement& fe,const std::size_t iblock, const std::size_t jblock,const std::size_t num)
723 {
724
1/2
✓ Branch 1 taken 8316850 times.
✗ Branch 2 not taken.
8316850 m_tmpMat.clear();
725
1/2
✓ Branch 1 taken 8316850 times.
✗ Branch 2 not taken.
8316850 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
726
2/2
✓ Branch 1 taken 34507337 times.
✓ Branch 2 taken 8316850 times.
42824187 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
727
4/8
✓ Branch 3 taken 34507337 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 34507337 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 34507337 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 34507337 times.
✗ Branch 13 not taken.
34507337 tmpBlock += ( coef * fe.weightMeas(ig) ) * outer_prod(fe.phi[ig], fe.phi[ig]);
728 }
729
730
2/2
✓ Branch 0 taken 24523716 times.
✓ Branch 1 taken 8316850 times.
32840566 for(std::size_t icoor=0; icoor<num; icoor++) {
731
1/2
✓ Branch 1 taken 24523716 times.
✗ Branch 2 not taken.
24523716 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
732
1/2
✓ Branch 1 taken 24523716 times.
✗ Branch 2 not taken.
24523716 matrix += tmpBlock;
733 24523716 }
734 8316850 }
735
736 /***********************************************************************************/
737 /***********************************************************************************/
738
739 void ElementMatrix::setZerosLung(const double coef,const CurvilinearFiniteElement& fe,const std::size_t iblock, const std::size_t jblock,const std::size_t num)
740 {
741 //NOTE: Nicolas : trick to ensure some elements of the matrix have particular value
742 m_tmpMat.clear();
743 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
744 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
745 tmpBlock = ( coef * fe.weightMeas(ig) ) * outer_prod(fe.phi[ig], fe.phi[ig]);
746 }
747
748 for(std::size_t icoor=0; icoor<num; icoor++) {
749 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
750 matrix += tmpBlock;
751 }
752 }
753
754 /***********************************************************************************/
755 /***********************************************************************************/
756
757 6 void ElementMatrix::phi_i_phi_j_lumped(const double coef,const CurBaseFiniteElement& fe,const std::size_t iblock, const std::size_t jblock,const std::size_t num)
758 {
759
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 m_tmpMat.clear();
760
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
761
2/2
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 6 times.
40 for(int i=0; i <fe.numDof(); ++i) {
762
2/4
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 34 times.
✗ Branch 6 not taken.
34 tmpBlock(i,i) += coef * fe.measure()/fe.numDof();
763 }
764
765
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6 times.
22 for(std::size_t icoor=0; icoor<num; icoor++) {
766
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
767
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 matrix += tmpBlock;
768 16 }
769 6 }
770
771 /***********************************************************************************/
772 /***********************************************************************************/
773
774 193677 void ElementMatrix::a_phi_i_phi_j(const double coef,const ElementField& scalfct,const CurBaseFiniteElement& fe,const std::size_t iblock, const std::size_t jblock, const std::size_t num)
775 {
776
1/2
✓ Branch 1 taken 193677 times.
✗ Branch 2 not taken.
193677 m_tmpMat.clear();
777
1/2
✓ Branch 1 taken 193677 times.
✗ Branch 2 not taken.
193677 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
778
779
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 193677 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
193677 switch(scalfct.type()) {
780 case CONSTANT_FIELD:
781 // nothing to do : the constant field has been computed before the integration loop
782 for(int ig=0; ig<fe.numQuadraturePoint(); ig++)
783 m_tmpVecQuadPoint(ig) = scalfct.val(0,0);
784 break;
785 193677 case DOF_FIELD:
786
2/2
✓ Branch 1 taken 1161342 times.
✓ Branch 2 taken 193677 times.
1355019 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
787
2/4
✓ Branch 2 taken 1161342 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1161342 times.
✗ Branch 6 not taken.
1161342 m_tmpVecCoor = prod(scalfct.val,fe.phi[ig]);
788
2/4
✓ Branch 1 taken 1161342 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1161342 times.
✗ Branch 5 not taken.
1161342 m_tmpVecQuadPoint(ig) = m_tmpVecCoor(0);
789 }
790 193677 break;
791 case QUAD_POINT_FIELD:
792 for(int ig=0; ig<fe.numQuadraturePoint(); ig++)
793 m_tmpVecQuadPoint(ig) = scalfct.val(0,ig);
794 break;
795 // Default case should appear with a warning at compile time instead of an error in runtime
796 // (that's truly the point of using enums as switch cases)
797 // default:
798 // FEL_ERROR("Operator 'a_phi_i_phi_j' not yet implemented with this type of element fields");
799 }
800
801
2/2
✓ Branch 1 taken 1161342 times.
✓ Branch 2 taken 193677 times.
1355019 for(int ig=0; ig<fe.numQuadraturePoint(); ig++)
802
5/10
✓ Branch 3 taken 1161342 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1161342 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1161342 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1161342 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1161342 times.
✗ Branch 16 not taken.
1161342 tmpblock += coef * m_tmpVecQuadPoint(ig) * fe.weightMeas(ig) * outer_prod(fe.phi[ig], fe.phi[ig]);
803
804
2/2
✓ Branch 0 taken 580791 times.
✓ Branch 1 taken 193677 times.
774468 for(std::size_t icoor=0; icoor<num; icoor++) {
805
1/2
✓ Branch 1 taken 580791 times.
✗ Branch 2 not taken.
580791 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
806
1/2
✓ Branch 1 taken 580791 times.
✗ Branch 2 not taken.
580791 matrix += tmpblock;
807 580791 }
808 193677 }
809
810 /***********************************************************************************/
811 /***********************************************************************************/
812
813 void ElementMatrix::penalty_contact_phi_i_scalar_n_phi_j_scalar_n(const double coef,const std::vector<double>& normal, const CurvilinearFiniteElement& fe,const ElementField& disp, const ElementField& gap)
814 {
815 FEL_CHECK(disp.type() == DOF_FIELD,"ElementMatlrix::penalty_contact_phi_i_scalar_n_phi_j_scalar_n: wrong disp field type");
816 FEL_CHECK(gap.type() == QUAD_POINT_FIELD,"ElementMatrix::penalty_contact_phi_i_scalar_n_phi_j_scalar_n: wrong gap field type");
817 double tmp;
818 const double hK2inv = 1./(fe.diameter()*fe.diameter());
819 for(int icoor=0; icoor<fe.numCoor(); icoor++) {
820 for(int jcoor=0; jcoor<fe.numCoor(); jcoor++) {
821 UBlasMatrixRange matrix = matBlock(icoor,jcoor);
822 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
823 tmp = 0.;
824 // disp at coor point
825 for(int jcomp=0; jcomp<fe.numCoor(); jcomp++)
826 for(int jdof=0; jdof<fe.numDof(); jdof++)
827 tmp += fe.phi[ig](jdof)*disp.val(jcomp,jdof)*normal[jcomp];
828 // gap
829 tmp -= gap.val(0,ig);
830 // tmp contains f \cdot n at quand node ig
831 if (0 <= tmp ) {
832 matrix += hK2inv*normal[icoor]*normal[jcoor]*( coef * fe.weightMeas(ig) ) * outer_prod(fe.phi[ig], fe.phi[ig]);
833 // std::cout << " contact force acting on quadrature node " << ig << " of element " << fe.id() << std::endl;
834 }
835 }
836 }
837 }
838 }
839
840 /***********************************************************************************/
841 /***********************************************************************************/
842
843 3840 void ElementMatrix::penalty_phi_i_scalar_n_phi_j_scalar_n(const double coef, CurvilinearFiniteElement& fe, const ElementField& vel, std::size_t iblock, std::size_t jblock) {
844
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3840 times.
3840 FEL_CHECK(vel.type() == DOF_FIELD,"ElementMatrix::penalty_phi_i_scalar_n_phi_j_scalar_n: wrong vel field type");
845 double tmp;
846 3840 const double penalty = 1./coef;
847
2/2
✓ Branch 1 taken 7680 times.
✓ Branch 2 taken 3840 times.
11520 for(int icoor=0; icoor<fe.numCoor(); icoor++) {
848
2/2
✓ Branch 1 taken 15360 times.
✓ Branch 2 taken 7680 times.
23040 for(int jcoor=0; jcoor<fe.numCoor(); jcoor++) {
849
1/2
✓ Branch 1 taken 15360 times.
✗ Branch 2 not taken.
15360 UBlasMatrixRange matrix = matBlock(icoor+iblock,jcoor+jblock);
850
2/2
✓ Branch 1 taken 46080 times.
✓ Branch 2 taken 15360 times.
61440 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
851 46080 tmp = 0.;
852
2/2
✓ Branch 1 taken 92160 times.
✓ Branch 2 taken 46080 times.
138240 for(int jcomp=0; jcomp<fe.numCoor(); jcomp++)
853
2/2
✓ Branch 1 taken 184320 times.
✓ Branch 2 taken 92160 times.
276480 for(int jdof=0; jdof<fe.numDof(); jdof++)
854
3/6
✓ Branch 2 taken 184320 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 184320 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 184320 times.
✗ Branch 10 not taken.
184320 tmp -= fe.phi[ig](jdof)*vel.val(jcomp,jdof)*fe.normal[ig][jcomp];// compute u_dot_n
855
2/2
✓ Branch 0 taken 12264 times.
✓ Branch 1 taken 33816 times.
46080 if ( tmp >= 0. ) { //Heaviside
856
7/14
✓ Branch 1 taken 12264 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 12264 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 12264 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 12264 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 12264 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 12264 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 12264 times.
✗ Branch 24 not taken.
12264 matrix += penalty*fe.normal[ig][icoor]*fe.normal[ig][jcoor]*outer_prod(fe.phi[ig], fe.phi[ig])*fe.weightMeas(ig);
857 }
858 }
859 15360 }
860 }
861 3840 }
862
863 /***********************************************************************************/
864 /***********************************************************************************/
865
866 void ElementMatrix::nitsche_contact_phi_i_scalar_n_phi_j_scalar_n(double gamma,const std::vector<double>& normal, const CurvilinearFiniteElement& fe,const ElementField& disp, const ElementField& gap, const ElementField& lambda)
867 {
868 FEL_CHECK(disp.type() == DOF_FIELD,"ElementMatlrix::penalty_contact_phi_i_scalar_n_phi_j_scalar_n: wrong disp field type");
869 FEL_CHECK(gap.type() == QUAD_POINT_FIELD,"ElementMatrix::penalty_contact_phi_i_scalar_n_phi_j_scalar_n: wrong gap field type");
870 double tmp;
871 const double penalty = gamma / (fe.diameter()*fe.diameter());
872 const double penalty_inv = fe.diameter()*fe.diameter()/gamma;
873 int zblock = 2*fe.numCoor()-1; // 3 in 2d, and 5 in 3d
874 for(int icoor=0; icoor<fe.numCoor(); icoor++) {
875 for(int jcoor=0; jcoor<fe.numCoor(); jcoor++) {
876 UBlasMatrixRange matrixUV = matBlock(icoor,jcoor);
877 UBlasMatrixRange matrixZV = matBlock(icoor,jcoor+zblock);
878 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
879 tmp = 0.;
880 // disp.n + gamma + lambda.h at coor point
881 for(int jcomp=0; jcomp<fe.numCoor(); jcomp++)
882 for(int jdof=0; jdof<fe.numDof(); jdof++)
883 tmp += fe.phi[ig](jdof)*(disp.val(jcomp,jdof)+penalty_inv*lambda.val(jcomp,jdof)) *normal[jcomp];
884 // gap a coor point
885 tmp -= gap.val(0,ig);
886 // tmp contains f \cdot n at quand node ig
887 if (0 <= tmp ) {
888 //std::cout << tmp<< std::endl;
889 matrixUV += penalty*normal[icoor]*normal[jcoor] * outer_prod(fe.phi[ig], fe.phi[ig]) * fe.weightMeas(ig);
890 matrixZV += normal[icoor]*normal[jcoor] * outer_prod(fe.phi[ig], fe.phi[ig]) * fe.weightMeas(ig);
891 }
892 }
893 }
894 }
895 }
896
897 /***********************************************************************************/
898 /***********************************************************************************/
899
900 void ElementMatrix::nitsche_contact_phi_i_scalar_n_phi_j_scalar_n(double gamma, const CurvilinearFiniteElement& fe,const ElementField& disp, const ElementField& gap, const ElementField& normal, const ElementField& lambda)
901 {
902 FEL_CHECK(disp.type() == DOF_FIELD,"ElementMatlrix::penalty_contact_phi_i_scalar_n_phi_j_scalar_n: wrong disp field type");
903 FEL_CHECK(gap.type() == QUAD_POINT_FIELD,"ElementMatrix::penalty_contact_phi_i_scalar_n_phi_j_scalar_n: wrong gap field type");
904 double tmp;
905 const double penalty = gamma / (fe.diameter()*fe.diameter());
906 const double penalty_inv = fe.diameter()*fe.diameter()/gamma;
907 int zblock = 2*fe.numCoor()-1; // 3 in 2d, and 5 in 3d
908 for(int icoor=0; icoor<fe.numCoor(); icoor++) {
909 for(int jcoor=0; jcoor<fe.numCoor(); jcoor++) {
910 UBlasMatrixRange matrixUV = matBlock(icoor,jcoor);
911 UBlasMatrixRange matrixZV = matBlock(icoor,jcoor+zblock);
912 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
913 tmp = 0.;
914 // disp.n + gamma + lambda.h at coor point
915 for(int jcomp=0; jcomp<fe.numCoor(); jcomp++)
916 for(int jdof=0; jdof<fe.numDof(); jdof++)
917 tmp += fe.phi[ig](jdof)*(disp.val(jcomp,jdof)+penalty_inv*lambda.val(jcomp,jdof)) *normal.val(jcomp,ig);
918 // gap a coor point
919 tmp -= gap.val(0,ig);
920 // tmp contains f \cdot n at quand node ig
921 if (0 <= tmp ) {
922 //std::cout << tmp<< std::endl;
923 matrixUV += penalty*normal.val(icoor,ig)*normal.val(jcoor,ig) * outer_prod(fe.phi[ig], fe.phi[ig]) * fe.weightMeas(ig);
924 matrixZV += normal.val(icoor,ig)*normal.val(jcoor,ig) * outer_prod(fe.phi[ig], fe.phi[ig]) * fe.weightMeas(ig);
925 }
926 }
927 }
928 }
929 }
930
931 /***********************************************************************************/
932 /***********************************************************************************/
933
934 void ElementMatrix::phi_i_psi_j_scalar_n(const double coef,const CurvilinearFiniteElement& fe1, const CurvilinearFiniteElement& fe2, const std::size_t iblock, const std::size_t jblock,const std::size_t num)
935 {
936 FEL_CHECK(fe1.numQuadraturePoint() == fe2.numQuadraturePoint(),"ElementMatrix::phi_i_psi_j_scalar_n: The quadrature rules must be the same for the two elements");
937 for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) {
938 for(std::size_t icoor=0; icoor<num; icoor++) {
939 UBlasMatrixRange mat_block = matBlock(iblock,jblock+icoor);
940 mat_block += (coef * fe1.weightMeas(ig) * fe1.normal[ig][icoor]) * outer_prod(fe2.phi[ig],fe1.phi[ig]);
941 }
942 }
943 }
944
945 /***********************************************************************************/
946 /***********************************************************************************/
947
948 6981268 void ElementMatrix::psi_j_div_phi_i_and_psi_i_div_phi_j (const CurrentFiniteElement& fe1,const CurrentFiniteElement& fe2,const std::size_t iblock, const std::size_t jblock,const double coef1,const double coef2)
949 {
950 6981268 m_tmpMat.clear();
951
2/2
✓ Branch 1 taken 20748490 times.
✓ Branch 2 taken 6981268 times.
27729758 for(int icoor=0; icoor<fe1.numCoor(); icoor++) {
952
1/2
✓ Branch 1 taken 20748490 times.
✗ Branch 2 not taken.
20748490 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat,iblock+icoor,jblock);
953
2/2
✓ Branch 1 taken 87228112 times.
✓ Branch 2 taken 20748490 times.
107976602 for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) {
954
2/2
✓ Branch 1 taken 350665336 times.
✓ Branch 2 taken 87228112 times.
437893448 for(int idof=0; idof<fe1.numDof(); idof++) {
955
2/2
✓ Branch 1 taken 1399246528 times.
✓ Branch 2 taken 350665336 times.
1749911864 for(int jdof=0; jdof<fe2.numDof(); jdof++) {
956
4/8
✓ Branch 1 taken 1399246528 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1399246528 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1399246528 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1399246528 times.
✗ Branch 13 not taken.
1399246528 tmpBlock(idof,jdof) += fe1.weightMeas(ig) * fe1.dPhi[ig](icoor,idof) * fe2.phi[ig](jdof);
957 }
958 }
959 }
960 20748490 }
961
962
2/2
✓ Branch 1 taken 20748490 times.
✓ Branch 2 taken 6981268 times.
27729758 for(int icoor=0; icoor<fe1.numCoor(); icoor++) {
963
1/2
✓ Branch 1 taken 20748490 times.
✗ Branch 2 not taken.
20748490 UBlasMatrixRange tmp = getMatBlock(m_tmpMat,iblock+icoor,jblock);
964
1/2
✓ Branch 1 taken 20748490 times.
✗ Branch 2 not taken.
20748490 UBlasMatrixRange mat1 = matBlock(iblock+icoor,jblock);
965
1/2
✓ Branch 1 taken 20748490 times.
✗ Branch 2 not taken.
20748490 UBlasMatrixRange mat2 = matBlock(jblock,iblock+icoor);
966
2/4
✓ Branch 1 taken 20748490 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20748490 times.
✗ Branch 5 not taken.
20748490 mat1 += coef1 * tmp;
967
3/6
✓ Branch 1 taken 20748490 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20748490 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20748490 times.
✗ Branch 8 not taken.
20748490 mat2 += coef2 * trans(tmp);
968 20748490 }
969 6981268 }
970
971 /***********************************************************************************/
972 /***********************************************************************************/
973
974 2662 void ElementMatrix::psi_j_div_phi_i(const double coef, const CurrentFiniteElement& fei,const CurrentFiniteElement& fej,const std::size_t iblock, const std::size_t jblock)
975 {
976 2662 m_tmpMat.clear();
977
2/2
✓ Branch 1 taken 5324 times.
✓ Branch 2 taken 2662 times.
7986 for(int icoor=0; icoor<fei.numCoor(); icoor++) {
978
1/2
✓ Branch 1 taken 5324 times.
✗ Branch 2 not taken.
5324 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat,iblock+icoor,jblock);
979
2/2
✓ Branch 1 taken 17424 times.
✓ Branch 2 taken 5324 times.
22748 for(int ig=0; ig<fei.numQuadraturePoint(); ig++) {
980
2/2
✓ Branch 1 taken 52272 times.
✓ Branch 2 taken 17424 times.
69696 for(int idof=0; idof<fei.numDof(); idof++) {
981
2/2
✓ Branch 1 taken 156816 times.
✓ Branch 2 taken 52272 times.
209088 for(int jdof=0; jdof<fej.numDof(); jdof++) {
982
4/8
✓ Branch 1 taken 156816 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 156816 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 156816 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 156816 times.
✗ Branch 13 not taken.
156816 tmpBlock(idof,jdof) += coef*fei.weightMeas(ig) * fei.dPhi[ig](icoor,idof) * fej.phi[ig](jdof);
983 }
984 }
985 }
986
1/2
✓ Branch 1 taken 5324 times.
✗ Branch 2 not taken.
5324 UBlasMatrixRange block = matBlock(iblock+icoor,jblock);
987
1/2
✓ Branch 1 taken 5324 times.
✗ Branch 2 not taken.
5324 block+=tmpBlock;
988 5324 }
989 2662 }
990
991 /***********************************************************************************/
992 /***********************************************************************************/
993
994 void ElementMatrix::phi_j_grad_psi_i(const double coef, const CurrentFiniteElement& fei,const CurrentFiniteElement& fej,const std::size_t iblock, const std::size_t jblock)
995 {
996 m_tmpMat.clear();
997 for(int icoor=0; icoor<fej.numCoor(); icoor++) {
998 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat,iblock,jblock+icoor);
999 for(int ig=0; ig<fei.numQuadraturePoint(); ig++) {
1000 for(int idof=0; idof<fei.numDof(); idof++) {
1001 for(int jdof=0; jdof<fej.numDof(); jdof++) {
1002 tmpBlock(idof,jdof) += coef*fei.weightMeas(ig) * fej.phi[ig](jdof) * fei.dPhi[ig](icoor,idof);
1003 }
1004 }
1005 }
1006 UBlasMatrixRange block = matBlock(iblock,jblock+icoor);
1007 block+=tmpBlock;
1008 }
1009 }
1010
1011 /***********************************************************************************/
1012 /***********************************************************************************/
1013
1014 void ElementMatrix::phi_i_grad_psi_j(const double coef, const CurrentFiniteElement& fei,const CurrentFiniteElement& fej,const std::size_t iblock, const std::size_t jblock)
1015 {
1016 m_tmpMat.clear();
1017 for(int icoor=0; icoor<fei.numCoor(); icoor++) {
1018 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat,iblock+icoor,jblock);
1019 for(int ig=0; ig<fei.numQuadraturePoint(); ig++) {
1020 for(int idof=0; idof<fei.numDof(); idof++) {
1021 for(int jdof=0; jdof<fej.numDof(); jdof++) {
1022 tmpBlock(idof,jdof) += coef*fei.weightMeas(ig) * fei.phi[ig](idof) * fej.dPhi[ig](icoor,jdof);
1023 }
1024 }
1025 }
1026 UBlasMatrixRange block = matBlock(iblock+icoor,jblock);
1027 block+=tmpBlock;
1028 }
1029 }
1030
1031 /***********************************************************************************/
1032 /***********************************************************************************/
1033
1034 2662 void ElementMatrix::psi_i_div_phi_j(const double coef, const CurrentFiniteElement& fej,const CurrentFiniteElement& fei,const std::size_t iblock, const std::size_t jblock)
1035 {
1036 2662 m_tmpMat.clear();
1037
2/2
✓ Branch 1 taken 5324 times.
✓ Branch 2 taken 2662 times.
7986 for(int jcoor=0; jcoor<fej.numCoor(); jcoor++) {
1038
1/2
✓ Branch 1 taken 5324 times.
✗ Branch 2 not taken.
5324 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat,iblock,jblock+jcoor);
1039
2/2
✓ Branch 1 taken 17424 times.
✓ Branch 2 taken 5324 times.
22748 for(int ig=0; ig<fej.numQuadraturePoint(); ig++) {
1040
2/2
✓ Branch 1 taken 52272 times.
✓ Branch 2 taken 17424 times.
69696 for(int jdof=0; jdof<fej.numDof(); jdof++) {
1041
2/2
✓ Branch 1 taken 156816 times.
✓ Branch 2 taken 52272 times.
209088 for(int idof=0; idof<fei.numDof(); idof++) {
1042
4/8
✓ Branch 1 taken 156816 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 156816 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 156816 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 156816 times.
✗ Branch 13 not taken.
156816 tmpBlock(idof,jdof) += coef*fej.weightMeas(ig) * fej.dPhi[ig](jcoor,jdof) * fei.phi[ig](idof);
1043 }
1044 }
1045 }
1046
1/2
✓ Branch 1 taken 5324 times.
✗ Branch 2 not taken.
5324 UBlasMatrixRange block = matBlock(iblock,jblock+jcoor);
1047
1/2
✓ Branch 1 taken 5324 times.
✗ Branch 2 not taken.
5324 block+=tmpBlock;
1048 5324 }
1049 2662 }
1050
1051 /***********************************************************************************/
1052 /***********************************************************************************/
1053
1054 8987078 void ElementMatrix::u_grad_phi_j_phi_i(const double coef,const ElementField& vel,const CurrentFiniteElement& fe,const std::size_t iblock, const std::size_t jblock, const std::size_t num, bool transpose)
1055 {
1056
1/2
✓ Branch 1 taken 8987078 times.
✗ Branch 2 not taken.
8987078 m_tmpMat.clear();
1057
1/2
✓ Branch 1 taken 8987078 times.
✗ Branch 2 not taken.
8987078 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
1058
2/2
✓ Branch 1 taken 39029704 times.
✓ Branch 2 taken 8987078 times.
48016782 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
1059
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 39029704 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
39029704 switch(vel.type()) {
1060 case CONSTANT_FIELD:
1061 // nothing to do : the constant field has been computed before the integration loop
1062 for(int icoor=0; icoor<vel.numComp(); icoor++)
1063 m_tmpVecCoor(icoor) = vel.val(icoor,0);
1064 break;
1065 39029704 case DOF_FIELD: {
1066
2/4
✓ Branch 2 taken 39029704 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 39029704 times.
✗ Branch 6 not taken.
39029704 m_tmpVecCoor = prod(vel.val,fe.phi[ig]);
1067 39029704 break;
1068 }
1069 case QUAD_POINT_FIELD: {
1070 for(int icoor=0; icoor<vel.numComp(); icoor++)
1071 m_tmpVecCoor(icoor) = vel.val(icoor,ig);
1072 break;
1073 }
1074 // Default case should appear with a warning at compile time instead of an error in runtime
1075 // (that's truly the point of using enums as switch cases)
1076 // default:
1077 // FEL_ERROR("Operator 'u_grad_phi_j_phi_i' not yet implemented with this type of element fields");
1078 }
1079
3/6
✓ Branch 2 taken 39029704 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 39029704 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 39029704 times.
✗ Branch 9 not taken.
39029704 m_tmpVecDof = prod(trans(fe.dPhi[ig]),m_tmpVecCoor); // m_tmpVecDof = vel \cdot \nabla \phi_i
1080
2/2
✓ Branch 1 taken 167316712 times.
✓ Branch 2 taken 39029704 times.
206346416 for(int idof=0; idof<fe.numDof(); idof++) {
1081
2/2
✓ Branch 1 taken 804051136 times.
✓ Branch 2 taken 167316712 times.
971367848 for(int jdof=0; jdof<fe.numDof(); jdof++) {
1082
4/8
✓ Branch 1 taken 804051136 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 804051136 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 804051136 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 804051136 times.
✗ Branch 12 not taken.
804051136 tmpblock(idof,jdof) += coef * fe.weightMeas(ig) * m_tmpVecDof(jdof) * fe.phi[ig](idof);
1083 }
1084 }
1085 }
1086
1087
1/2
✓ Branch 0 taken 8987078 times.
✗ Branch 1 not taken.
8987078 if ( transpose == false )
1088
2/2
✓ Branch 0 taken 26193666 times.
✓ Branch 1 taken 8987078 times.
35180744 for(std::size_t icoor=0; icoor<num; icoor++) {
1089
1/2
✓ Branch 1 taken 26193666 times.
✗ Branch 2 not taken.
26193666 UBlasMatrixRange block = matBlock(iblock+icoor,jblock+icoor);
1090
1/2
✓ Branch 1 taken 26193666 times.
✗ Branch 2 not taken.
26193666 block += tmpblock;
1091 26193666 }
1092 else {
1093 for(std::size_t icoor=0; icoor<num; icoor++) {
1094 UBlasMatrixRange block = matBlock(iblock+icoor,jblock+icoor);
1095 block += trans(tmpblock);
1096 }
1097 }
1098 8987078 }
1099
1100 /***********************************************************************************/
1101 /***********************************************************************************/
1102
1103 void ElementMatrix::u_grad_phi_i_grad_psi_j(const double coef,const ElementField& vel,const CurrentFiniteElement& fe1, const CurrentFiniteElement& fe2, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
1104 {
1105 m_tmpMat.clear();
1106 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat,jblock, iblock);
1107 for(int ig=0; ig<fe1.numQuadraturePoint(); ig++) {
1108 switch(vel.type()) {
1109 case CONSTANT_FIELD:
1110 // nothing to do : the constant field has been computed before the integration loop
1111 for(int icoor=0; icoor<vel.numComp(); icoor++)
1112 m_tmpVecCoor(icoor) = vel.val(icoor,0);
1113 break;
1114 case DOF_FIELD: {
1115 m_tmpVecCoor = prod(vel.val,fe1.phi[ig]);
1116 break;
1117 }
1118 case QUAD_POINT_FIELD: {
1119 for(int icoor=0; icoor<vel.numComp(); icoor++)
1120 m_tmpVecCoor(icoor) = vel.val(icoor,ig);
1121 break;
1122 }
1123 }
1124 m_tmpVecDof = prod(trans(fe1.dPhi[ig]),m_tmpVecCoor); // m_tmpVecDof = vel \cdot \nabla \phi_i
1125 for(int icoor=0; icoor<fe1.numCoor(); icoor++) {
1126 for(int idof=0; idof<fe2.numDof(); idof++) {
1127 for(int jdof=0; jdof<fe1.numDof(); jdof++) {
1128 tmpblock(jdof, idof) += coef * fe1.weightMeas(ig) * m_tmpVecDof(jdof) * fe2.dPhi[ig](icoor,idof);
1129 }
1130 }
1131 }
1132
1133 for(std::size_t icoor=0; icoor<num; icoor++) {
1134 UBlasMatrixRange block = matBlock(jblock, iblock+icoor);
1135 block += tmpblock;
1136 }
1137 }
1138 }
1139
1140 /***********************************************************************************/
1141 /***********************************************************************************/
1142
1143 void ElementMatrix::phi_grad_u(const double coef, const ElementField& vel, const CurrentFiniteElement& fe,
1144 const std::size_t iblock, const std::size_t jblock, const std::size_t num)
1145 {
1146 m_tmpMat.clear();
1147 double grad;
1148 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
1149
1150 for( std::size_t icoor = 0; icoor<num; icoor++) {
1151 for( std::size_t jcoor = 0; jcoor<num; jcoor++) {
1152
1153 for(int idof = 0; idof < fe.numDof(); idof++) {
1154 for(int jdof = 0; jdof < fe.numDof(); jdof++) {
1155 tmpblock(idof, jdof) = 0.;
1156 }
1157 }
1158
1159 for(int ig = 0; ig < fe.numQuadraturePoint(); ig++) {
1160 grad = 0.;
1161 for(int idof = 0; idof<fe.numDof(); idof++) {
1162 grad += vel.val(icoor, idof) * fe.dPhi[ig](jcoor, idof);
1163 }
1164 tmpblock += coef * fe.weightMeas(ig) * grad * outer_prod(fe.phi[ig], fe.phi[ig]);
1165 }
1166 UBlasMatrixRange matrix = matBlock(iblock+icoor, jblock+jcoor);
1167 matrix += tmpblock;
1168 }
1169 }
1170 }
1171
1172 /***********************************************************************************/
1173 /***********************************************************************************/
1174
1175 //----------------------------------------------------------------------
1176 // operator \int_{Sigma} u^{n+1} Grad u^{n} \dot v - v Grad u^{n} \dot u^{n+1} :
1177 // NS total pressure formulation
1178 void ElementMatrix::phi_grad_u_minus_grad_u_phi(const double coef, const ElementField& vel,
1179 const CurrentFiniteElement& fe, const std::size_t iblock,
1180 const std::size_t jblock, const std::size_t num)
1181 {
1182 m_tmpMat.clear();
1183 double grad;
1184 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
1185
1186 for( std::size_t icoor = 0; icoor<num; icoor++) {
1187 for( std::size_t jcoor = 0; jcoor<num; jcoor++) {
1188
1189 if (icoor!=jcoor) {
1190
1191 for(int idof = 0; idof < fe.numDof(); idof++) {
1192 for(int jdof = 0; jdof < fe.numDof(); jdof++) {
1193 tmpblock(idof, jdof) = 0.;
1194 }
1195 }
1196
1197 for(int ig = 0; ig < fe.numQuadraturePoint(); ig++) {
1198 grad = 0.;
1199 for(int idof = 0; idof<fe.numDof(); idof++) {
1200 grad += vel.val(icoor, idof) * fe.dPhi[ig](jcoor, idof) - vel.val(jcoor, idof) * fe.dPhi[ig](icoor, idof);
1201 }
1202 tmpblock += coef * fe.weightMeas(ig) * grad * outer_prod(fe.phi[ig], fe.phi[ig]);
1203 }
1204 UBlasMatrixRange matrix = matBlock(iblock+icoor, jblock+jcoor);
1205 matrix += tmpblock;
1206 }
1207 }
1208 }
1209 }
1210
1211 /***********************************************************************************/
1212 /***********************************************************************************/
1213
1214 15517188 void ElementMatrix::div_u_phi_j_phi_i(const double coef, const ElementField& vel, const CurrentFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
1215 {
1216
1/2
✓ Branch 1 taken 15517188 times.
✗ Branch 2 not taken.
15517188 m_tmpMat.clear();
1217
1/2
✓ Branch 3 taken 15517188 times.
✗ Branch 4 not taken.
15517188 std::vector<double> v(fe.numCoor());
1218
1219
1/2
✓ Branch 1 taken 15517188 times.
✗ Branch 2 not taken.
15517188 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
1220
1221
2/2
✓ Branch 1 taken 65114144 times.
✓ Branch 2 taken 15517188 times.
80631332 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
1222
2/2
✓ Branch 1 taken 191912528 times.
✓ Branch 2 taken 65114144 times.
257026672 for (int icoor=0; icoor<fe.numCoor(); icoor++) {
1223 191912528 v[icoor] = 0;
1224
2/2
✓ Branch 1 taken 804285704 times.
✓ Branch 2 taken 191912528 times.
996198232 for (int jdof=0; jdof<fe.numDof(); jdof++) {
1225
2/4
✓ Branch 1 taken 804285704 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 804285704 times.
✗ Branch 6 not taken.
804285704 v[icoor] += vel.val(icoor,jdof) * fe.dPhi[ig](icoor,jdof);
1226 }
1227 }
1228
1229 65114144 double div=0.0;
1230
2/2
✓ Branch 1 taken 191912528 times.
✓ Branch 2 taken 65114144 times.
257026672 for(int i=0; i<fe.numCoor(); i++) {
1231 191912528 div += v[i];
1232 }
1233
1234
4/8
✓ Branch 3 taken 65114144 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 65114144 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 65114144 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 65114144 times.
✗ Branch 13 not taken.
65114144 tmpBlock += coef * fe.weightMeas(ig) * div * outer_prod(fe.phi[ig], fe.phi[ig]);
1235 }
1236
1237
2/2
✓ Branch 0 taken 45739996 times.
✓ Branch 1 taken 15517188 times.
61257184 for(std::size_t icoor=0; icoor<num; icoor++) {
1238
1/2
✓ Branch 1 taken 45739996 times.
✗ Branch 2 not taken.
45739996 UBlasMatrixRange mat = matBlock(iblock+icoor,jblock+icoor);
1239
1/2
✓ Branch 1 taken 45739996 times.
✗ Branch 2 not taken.
45739996 mat += tmpBlock;
1240 45739996 }
1241 15517188 }
1242
1243 /***********************************************************************************/
1244 /***********************************************************************************/
1245
1246 void ElementMatrix::convective_rot(const double coef, const ElementField& vel, const CurrentFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
1247 {
1248 IGNORE_UNUSED_ARGUMENT(num);
1249 m_tmpMat.clear();
1250 std::vector<double> v(fe.numCoor());
1251
1252 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
1253
1254 // \int_{\Omega} coef rot(u^{n+1} x u^n \cdot v
1255 for(int icoor=0; icoor<fe.numCoor(); icoor++) {
1256 for(int jcoor=0; jcoor<fe.numCoor(); jcoor++) {
1257 for (int idof=0; idof<fe.numDof(); idof++) {
1258 for (int jdof=0; jdof<fe.numDof(); jdof++) {
1259 tmpBlock(idof,jdof) = 0.;
1260 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
1261 tmpBlock(idof,jdof) -= coef * fe.weightMeas(ig) * fe.dPhi[ig](icoor,jdof) * vel.val(jcoor,ig) * fe.phi[ig](idof);
1262 }
1263 }
1264 }
1265 UBlasMatrixRange mat = matBlock(iblock+icoor,jblock+jcoor);
1266 mat += tmpBlock;
1267 }
1268 }
1269
1270 // \int_{\Omega} coef/2 u^{n+1} \cdot u^n) div(v)
1271 for(int icoor=0; icoor<fe.numCoor(); icoor++) {
1272 for(int jcoor=0; jcoor<fe.numCoor(); jcoor++) {
1273 for(int idof=0; idof<fe.numDof(); idof++) {
1274 for(int jdof=0; jdof<fe.numDof(); jdof++) {
1275 tmpBlock(idof,jdof) = 0.;
1276 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
1277 tmpBlock(idof,jdof) -= coef * fe.weightMeas(ig) * 0.5 * fe.dPhi[ig](icoor,idof) * vel.val(jcoor,ig) * fe.phi[ig](jdof);
1278 }
1279 }
1280 }
1281 UBlasMatrixRange mat = matBlock(iblock+icoor,jblock+jcoor);
1282 mat += tmpBlock;
1283 }
1284 }
1285
1286 for (int idof=0; idof<fe.numDof(); idof++) {
1287 for (int jdof=0; jdof<fe.numDof(); jdof++) {
1288 tmpBlock(idof,jdof) = 0.;
1289 for(int jcoor=0; jcoor<fe.numCoor(); jcoor++) {
1290 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
1291 tmpBlock(idof,jdof) += coef * fe.weightMeas(ig) * fe.dPhi[ig](jcoor,jdof) * vel.val(jcoor,ig) * fe.phi[ig](idof);
1292 }
1293 }
1294 }
1295 }
1296
1297 for(int icoor=0; icoor<fe.numCoor(); icoor++) {
1298 UBlasMatrixRange mat = matBlock(iblock+icoor,jblock+icoor);
1299 mat += tmpBlock;
1300 }
1301 }
1302
1303 /***********************************************************************************/
1304 /***********************************************************************************/
1305
1306 void ElementMatrix::grad_phi_i_dot_vec_phi_j(const double coef, const ElementField& vec, const CurrentFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
1307 {
1308 FEL_CHECK(vec.type() == CONSTANT_FIELD, "grad_phi_i_dot_vec_phi_j is not implemented for this type of vec");
1309
1310 m_tmpMat.clear();
1311 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
1312
1313 for(felInt idof=0; idof<fe.numDof(); ++idof)
1314 for(felInt jdof=0; jdof<fe.numDof(); ++jdof)
1315 for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig)
1316 for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor)
1317 tmpblock(idof, jdof) += coef * fe.dPhi[ig](icoor, idof) * vec.val(icoor, 0) * fe.phi[ig](jdof) * fe.weightMeas(ig);
1318
1319
1320 for(std::size_t icoor=0; icoor<num; icoor++) {
1321 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + icoor);
1322 matrix += tmpblock;
1323 }
1324 }
1325
1326 /***********************************************************************************/
1327 /***********************************************************************************/
1328
1329 4432 void ElementMatrix::eps_phi_i_dot_vec_phi_j(const double coef, const ElementField& vec, const CurrentFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
1330 {
1331
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4432 times.
4432 FEL_CHECK(vec.type() == CONSTANT_FIELD, "eps_phi_i_dot_vec_phi_j is not implemented for this type of vec");
1332
1333
2/2
✓ Branch 0 taken 8864 times.
✓ Branch 1 taken 4432 times.
13296 for(std::size_t icoor=0; icoor<num; ++icoor) {
1334
2/2
✓ Branch 0 taken 17728 times.
✓ Branch 1 taken 8864 times.
26592 for(std::size_t jcoor=0; jcoor<num; ++jcoor) {
1335
1/2
✓ Branch 1 taken 17728 times.
✗ Branch 2 not taken.
17728 m_tmpMat.clear();
1336
1/2
✓ Branch 1 taken 17728 times.
✗ Branch 2 not taken.
17728 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
1337
1338
2/2
✓ Branch 0 taken 8864 times.
✓ Branch 1 taken 8864 times.
17728 if(icoor == jcoor) {
1339
2/2
✓ Branch 1 taken 26592 times.
✓ Branch 2 taken 8864 times.
35456 for(felInt idof=0; idof<fe.numDof(); ++idof)
1340
2/2
✓ Branch 1 taken 79776 times.
✓ Branch 2 taken 26592 times.
106368 for(felInt jdof=0; jdof<fe.numDof(); ++jdof)
1341
2/2
✓ Branch 1 taken 239328 times.
✓ Branch 2 taken 79776 times.
319104 for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig)
1342
2/2
✓ Branch 1 taken 478656 times.
✓ Branch 2 taken 239328 times.
717984 for(felInt kcoor=0; kcoor<fe.numRefCoor(); ++kcoor)
1343
5/10
✓ Branch 2 taken 478656 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 478656 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 478656 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 478656 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 478656 times.
✗ Branch 16 not taken.
478656 tmpblock(idof, jdof) += 0.5 * coef * fe.dPhi[ig](kcoor, idof) * vec.val(kcoor, 0) * fe.phi[ig](jdof) * fe.weightMeas(ig);
1344 }
1345
1346
2/2
✓ Branch 1 taken 53184 times.
✓ Branch 2 taken 17728 times.
70912 for(felInt idof=0; idof<fe.numDof(); ++idof)
1347
2/2
✓ Branch 1 taken 159552 times.
✓ Branch 2 taken 53184 times.
212736 for(felInt jdof=0; jdof<fe.numDof(); ++jdof)
1348
2/2
✓ Branch 1 taken 478656 times.
✓ Branch 2 taken 159552 times.
638208 for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig)
1349
5/10
✓ Branch 2 taken 478656 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 478656 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 478656 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 478656 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 478656 times.
✗ Branch 16 not taken.
478656 tmpblock(idof, jdof) += 0.5 * coef * fe.dPhi[ig](jcoor, idof) * vec.val(icoor, 0) * fe.phi[ig](jdof) * fe.weightMeas(ig);
1350
1351
1/2
✓ Branch 1 taken 17728 times.
✗ Branch 2 not taken.
17728 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + jcoor);
1352
1/2
✓ Branch 1 taken 17728 times.
✗ Branch 2 not taken.
17728 matrix += tmpblock;
1353 17728 }
1354 }
1355 4432 }
1356
1357 /***********************************************************************************/
1358 /***********************************************************************************/
1359
1360 void ElementMatrix::phi_i_grad_phi_j_dot_vec(const double coef, const ElementField& vec, const CurrentFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
1361 {
1362 FEL_CHECK(vec.type() == CONSTANT_FIELD, "phi_i_grad_phi_j_dot_vec is not implemented for this type of vec");
1363
1364 m_tmpMat.clear();
1365 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
1366
1367 for(felInt idof=0; idof<fe.numDof(); ++idof)
1368 for(felInt jdof=0; jdof<fe.numDof(); ++jdof)
1369 for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig)
1370 for(felInt icoor=0; icoor<fe.numRefCoor(); ++icoor)
1371 tmpblock(idof, jdof) += coef * fe.dPhi[ig](icoor, jdof) * vec.val(icoor, 0) * fe.phi[ig](idof) * fe.weightMeas(ig);
1372
1373
1374 for(std::size_t icoor=0; icoor<num; icoor++) {
1375 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + icoor);
1376 matrix += tmpblock;
1377 }
1378 }
1379
1380 /***********************************************************************************/
1381 /***********************************************************************************/
1382
1383 320 void ElementMatrix::phi_i_eps_phi_j_dot_vec(const double coef, const ElementField& vec, const CurrentFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
1384 {
1385
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 320 times.
320 FEL_CHECK(vec.type() == CONSTANT_FIELD, "eps_phi_i_dot_vec_phi_j is not implemented for this type of vec");
1386
2/2
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 320 times.
960 for(std::size_t icoor=0; icoor<num; ++icoor) {
1387
2/2
✓ Branch 0 taken 1280 times.
✓ Branch 1 taken 640 times.
1920 for(std::size_t jcoor=0; jcoor<num; ++jcoor) {
1388
1/2
✓ Branch 1 taken 1280 times.
✗ Branch 2 not taken.
1280 m_tmpMat.clear();
1389
1/2
✓ Branch 1 taken 1280 times.
✗ Branch 2 not taken.
1280 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
1390
1391
2/2
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 640 times.
1280 if(icoor == jcoor) {
1392
2/2
✓ Branch 1 taken 1920 times.
✓ Branch 2 taken 640 times.
2560 for(felInt idof=0; idof<fe.numDof(); ++idof)
1393
2/2
✓ Branch 1 taken 5760 times.
✓ Branch 2 taken 1920 times.
7680 for(felInt jdof=0; jdof<fe.numDof(); ++jdof)
1394
2/2
✓ Branch 1 taken 17280 times.
✓ Branch 2 taken 5760 times.
23040 for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig)
1395
2/2
✓ Branch 1 taken 34560 times.
✓ Branch 2 taken 17280 times.
51840 for(felInt kcoor=0; kcoor<fe.numRefCoor(); ++kcoor)
1396
5/10
✓ Branch 2 taken 34560 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 34560 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 34560 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 34560 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 34560 times.
✗ Branch 16 not taken.
34560 tmpblock(idof, jdof) += 0.5 * coef * fe.dPhi[ig](kcoor, jdof) * vec.val(kcoor, 0) * fe.phi[ig](idof) * fe.weightMeas(ig);
1397 }
1398
1399
2/2
✓ Branch 1 taken 3840 times.
✓ Branch 2 taken 1280 times.
5120 for(felInt idof=0; idof<fe.numDof(); ++idof)
1400
2/2
✓ Branch 1 taken 11520 times.
✓ Branch 2 taken 3840 times.
15360 for(felInt jdof=0; jdof<fe.numDof(); ++jdof)
1401
2/2
✓ Branch 1 taken 34560 times.
✓ Branch 2 taken 11520 times.
46080 for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig)
1402
5/10
✓ Branch 2 taken 34560 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 34560 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 34560 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 34560 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 34560 times.
✗ Branch 16 not taken.
34560 tmpblock(idof, jdof) += 0.5 * coef * fe.dPhi[ig](icoor, jdof) * vec.val(jcoor, 0) * fe.phi[ig](idof) * fe.weightMeas(ig);
1403
1404
1/2
✓ Branch 1 taken 1280 times.
✗ Branch 2 not taken.
1280 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + jcoor);
1405
1/2
✓ Branch 1 taken 1280 times.
✗ Branch 2 not taken.
1280 matrix += tmpblock;
1406 1280 }
1407 }
1408 320 }
1409
1410 /***********************************************************************************/
1411 /***********************************************************************************/
1412
1413 void ElementMatrix::eps_phi_j_vec_dot_eps_phi_i_vec(const double coef, const ElementField& vec, const CurrentFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
1414 {
1415 FEL_CHECK(vec.type() == CONSTANT_FIELD, "ElementMatrix::eps_phi_j_vec_dot_eps_phi_i_vec is not implemented for non constant vec");
1416
1417 double tmpvali, tmpvalj;
1418 double deri, derj;
1419
1420 for(std::size_t icoor=0; icoor<num; ++icoor) {
1421 for(std::size_t jcoor=0; jcoor<num; ++jcoor) {
1422 m_tmpMat.clear();
1423 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
1424
1425 if(icoor == jcoor) {
1426 for(felInt idof=0; idof<fe.numDof(); ++idof) {
1427 for(felInt jdof=0; jdof<fe.numDof(); ++jdof) {
1428 for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) {
1429 tmpvali = 0.;
1430 tmpvalj = 0.;
1431
1432 for(felInt kcoor=0; kcoor<fe.numRefCoor(); ++kcoor) {
1433 tmpvali += fe.dPhi[ig](kcoor, idof) * vec.val(kcoor, 0);
1434 tmpvalj += fe.dPhi[ig](kcoor, jdof) * vec.val(kcoor, 0);
1435 }
1436
1437 tmpblock(idof, jdof) += 0.25 * coef * tmpvali * tmpvalj * fe.weightMeas(ig);
1438 }
1439 }
1440 }
1441 }
1442
1443 for(felInt idof=0; idof<fe.numDof(); ++idof) {
1444 for(felInt jdof=0; jdof<fe.numDof(); ++jdof) {
1445 for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) {
1446 tmpvali = 0.; deri = 0.;
1447 tmpvalj = 0.; derj = 0.;
1448
1449 for(felInt kcoor=0; kcoor<fe.numRefCoor(); ++kcoor) {
1450 tmpvali += fe.dPhi[ig](kcoor, idof) * vec.val(kcoor, 0);
1451 tmpvalj += fe.dPhi[ig](kcoor, jdof) * vec.val(kcoor, 0);
1452 deri += fe.dPhi[ig](kcoor, idof) * vec.val(icoor, 0);
1453 derj += fe.dPhi[ig](kcoor, jdof) * vec.val(jcoor, 0);
1454 }
1455
1456 tmpblock(idof, jdof) += 0.25 * coef * fe.dPhi[ig](icoor, jdof) * vec.val(jcoor, 0) * tmpvali * fe.weightMeas(ig);
1457 tmpblock(idof, jdof) += 0.25 * coef * fe.dPhi[ig](jcoor, idof) * vec.val(icoor, 0) * tmpvalj * fe.weightMeas(ig);
1458 tmpblock(idof, jdof) += 0.25 * coef * deri * derj * fe.weightMeas(ig);
1459 }
1460 }
1461 }
1462
1463 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + jcoor);
1464 matrix += tmpblock;
1465 }
1466 }
1467 }
1468
1469 /***********************************************************************************/
1470 /***********************************************************************************/
1471
1472 void ElementMatrix::grad_phi_j_vec_dot_grad_phi_i_vec(const double coef, const ElementField& vec, const CurrentFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
1473 {
1474 FEL_CHECK(vec.type() == CONSTANT_FIELD, "ElementMatrix::eps_phi_j_vec_dot_eps_phi_i_vec is not implemented for non constant vec");
1475
1476 double tmpvali, tmpvalj;
1477
1478 m_tmpMat.clear();
1479 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
1480
1481 for(felInt idof=0; idof<fe.numDof(); ++idof) {
1482 for(felInt jdof=0; jdof<fe.numDof(); ++jdof) {
1483 for(felInt ig=0; ig<fe.numQuadraturePoint(); ++ig) {
1484 tmpvali = 0.;
1485 tmpvalj = 0.;
1486
1487 for(felInt kcoor=0; kcoor<fe.numRefCoor(); ++kcoor) {
1488 tmpvali += fe.dPhi[ig](kcoor, idof) * vec.val(kcoor, 0);
1489 tmpvalj += fe.dPhi[ig](kcoor, jdof) * vec.val(kcoor, 0);
1490 }
1491
1492 tmpblock(idof, jdof) += coef * tmpvali * tmpvalj * fe.weightMeas(ig);
1493 }
1494 }
1495 }
1496
1497 for(std::size_t icoor=0; icoor<num; icoor++) {
1498 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + icoor);
1499 matrix += tmpblock;
1500 }
1501 }
1502
1503 /***********************************************************************************/
1504 /***********************************************************************************/
1505
1506 void ElementMatrix::grad_phi_i_dot_n_psi_j(const CurrentFiniteElementWithBd& fewbd1,
1507 const CurrentFiniteElementWithBd& fewbd2,
1508 int iblockBd, int numblockBd,
1509 const std::size_t iblock, const std::size_t jblock,const std::size_t num,
1510 const double coef1,const double coef2)
1511 {
1512 FEL_ASSERT(iblockBd>=0 && iblockBd<fewbd1.numBdEle() && (numblockBd-iblockBd) <= fewbd1.numBdEle() );
1513 m_tmpMat.clear();
1514 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
1515 for (int ibd=iblockBd; ibd<iblockBd+numblockBd; ibd++) {
1516 FEL_ASSERT( fewbd1.bdEle(ibd).hasNormal() && fewbd1.hasFirstDeriv() );
1517 for(int ilocg=0; ilocg<fewbd1.numQuadPointBdEle(ibd); ilocg++) {
1518 const int ig = ilocg+fewbd1.indexQuadPoint(ibd+1); // face ibd starts at ibd+1 (0 for internal quad points)
1519 //NB: is "ig2 = ig1"??? The quad points should be the same for the 2 currentFEwBd... VM 10/2011
1520
1521 //! Vector = [n \cdot \grad \phi(jdof)]: (std::vector line)
1522 m_tmpVecDof = prod(trans(fewbd1.bdEle(ibd).normal[ilocg]), fewbd1.dPhi[ig]);
1523
1524 // these 2 loops below are equivalent to the 2 outer_prod (below). is a method much faster than the other??? vm 11/2011
1525 // beware: one does 2 outer_prod, and only one is useful (+ 2 matrix * scalar products). improve this...
1526
1527 /* for(int idof=0;idof<fewbd1.numDof();idof++){
1528 for(int jdof=0;jdof<fewbd2.numDof();jdof++){
1529 // dphi_1/dn(jdof) * psi_2(idof):
1530 double theval = fewbd1.bdEle(ibd).weightMeas(ilocg) * fewbd2.phi[ig](idof) * m_tmpVecDof(jdof);
1531 tmpBlock(idof,jdof) += coef1 * theval;
1532 tmpBlock(jdof,idof) += coef2 * theval;
1533 }
1534 }*/
1535 //! Matrix = Vector^T * Vector (* val)
1536 tmpBlock += ( coef1 * fewbd1.bdEle(ibd).weightMeas(ilocg) ) * outer_prod( fewbd2.phi[ig], m_tmpVecDof );
1537 tmpBlock += ( coef2 * fewbd1.bdEle(ibd).weightMeas(ilocg) ) * outer_prod( m_tmpVecDof, fewbd2.phi[ig] );
1538 }
1539 }
1540 for(std::size_t icoor=0; icoor<num; icoor++) {
1541 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
1542 matrix += tmpBlock;
1543 }
1544 }
1545
1546 /***********************************************************************************/
1547 /***********************************************************************************/
1548
1549 void ElementMatrix::grad_phi_i_dot_n_grad_phi_j_dot_n(const double coef,const CurrentFiniteElementWithBd& fewbd,
1550 int iblockBd, int numblockBd,
1551 const std::size_t iblock, const std::size_t jblock,const std::size_t num)
1552 {
1553 FEL_ASSERT(iblockBd>=0 && iblockBd<fewbd.numBdEle() && (numblockBd-iblockBd) <= fewbd.numBdEle() );
1554 m_tmpMat.clear();
1555 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
1556 for (int ibd=iblockBd; ibd<iblockBd+numblockBd; ibd++) {
1557 FEL_ASSERT( fewbd.bdEle(ibd).hasNormal() && fewbd.hasFirstDeriv() );
1558 for(int ilocg=0; ilocg<fewbd.numQuadPointBdEle(ibd); ilocg++) {
1559 const int ig = ilocg+fewbd.indexQuadPoint(ibd+1); // face ibd starts at ibd+1 (0 for internal quad points)
1560
1561 //! Vector = [n \cdot \grad \phi(jdof)]:
1562 m_tmpVecDof = prod(trans(fewbd.bdEle(ibd).normal[ilocg]), fewbd.dPhi[ig]);
1563 //! Matrix = Vector^T * Vector (* val)
1564 tmpBlock += ( coef * fewbd.bdEle(ibd).weightMeas(ilocg) ) * outer_prod( m_tmpVecDof, m_tmpVecDof );
1565 }
1566 }
1567 for(std::size_t icoor=0; icoor<num; icoor++) {
1568 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
1569 matrix += tmpBlock;
1570 }
1571 }
1572
1573 /***********************************************************************************/
1574 /***********************************************************************************/
1575
1576 2458444 void ElementMatrix::grad_phi_j_dot_n_grad_psi_i_dot_n(const double coef, const CurrentFiniteElementWithBd& fewbdphi, const CurrentFiniteElementWithBd& fewbdpsi, felInt iBdPhi, felInt iBdPsi, const std::size_t iblock, const std::size_t jblock, const std::size_t numBlock)
1577 {
1578 // Check that the ids of the boundary is in the bound
1579
3/6
✓ Branch 0 taken 2458444 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2458444 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2458444 times.
2458444 FEL_ASSERT(iBdPhi>=0 && iBdPhi<fewbdphi.numBdEle());
1580
3/6
✓ Branch 0 taken 2458444 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2458444 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2458444 times.
2458444 FEL_ASSERT(iBdPsi>=0 && iBdPsi<fewbdpsi.numBdEle());
1581
1582 // Check that the normal and the derivatives have been computed
1583
4/8
✓ Branch 1 taken 2458444 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2458444 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2458444 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2458444 times.
2458444 FEL_ASSERT(fewbdphi.bdEle(iBdPhi).hasNormal() && fewbdphi.hasFirstDeriv());
1584
4/8
✓ Branch 1 taken 2458444 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2458444 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2458444 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2458444 times.
2458444 FEL_ASSERT(fewbdpsi.bdEle(iBdPsi).hasNormal() && fewbdpsi.hasFirstDeriv());
1585
1586 // Check that the number of integration point is the same on the boundary
1587
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 2458444 times.
2458444 FEL_ASSERT(fewbdphi.numQuadPointBdEle(iBdPhi) == fewbdpsi.numQuadPointBdEle(iBdPsi));
1588
1589 // Resize if required
1590
3/6
✓ Branch 1 taken 2458444 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2458444 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2458444 times.
2458444 if (m_tmpVec2Dof.size() != m_tmpVecDof.size())
1591 m_tmpVec2Dof.resize(m_tmpVecDof.size());
1592
1593 // Clear
1594
1/2
✓ Branch 1 taken 2458444 times.
✗ Branch 2 not taken.
2458444 m_tmpMat.clear();
1595
1/2
✓ Branch 1 taken 2458444 times.
✗ Branch 2 not taken.
2458444 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
1596
1597 // Compute the integral over the boundary
1598
2/2
✓ Branch 1 taken 4916888 times.
✓ Branch 2 taken 2458444 times.
7375332 for(felInt ilocg=0; ilocg<fewbdpsi.numQuadPointBdEle(iBdPsi); ++ilocg) {
1599 // Boundary iBdPhi starts at iBdPhi+1 (0 for internal quad points)
1600 4916888 const felInt igphi = ilocg + fewbdphi.indexQuadPoint(iBdPhi+1);
1601 4916888 const felInt igpsi = ilocg + fewbdpsi.indexQuadPoint(iBdPsi+1);
1602
1603 // Compute \grad \phi(jdof) \cdot nphi and \grad \psi(jdof) \cdot npsi
1604
4/8
✓ Branch 2 taken 4916888 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 4916888 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 4916888 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 4916888 times.
✗ Branch 13 not taken.
4916888 m_tmpVecDof = prod(trans(fewbdphi.bdEle(iBdPhi).normal[ilocg]), fewbdphi.dPhi[igphi]);
1605
4/8
✓ Branch 2 taken 4916888 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 4916888 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 4916888 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 4916888 times.
✗ Branch 13 not taken.
4916888 m_tmpVec2Dof = prod(trans(fewbdpsi.bdEle(iBdPsi).normal[ilocg]), fewbdpsi.dPhi[igpsi]);
1606
1607 // Compute Vector^T * Vector (* val)
1608
5/10
✓ Branch 1 taken 4916888 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4916888 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4916888 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4916888 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4916888 times.
✗ Branch 14 not taken.
4916888 tmpBlock += (coef * fewbdpsi.bdEle(iBdPsi).weightMeas(ilocg)) * outer_prod(m_tmpVec2Dof, m_tmpVecDof);
1609 }
1610
1611
2/2
✓ Branch 0 taken 3698992 times.
✓ Branch 1 taken 2458444 times.
6157436 for(std::size_t icoor=0; icoor<numBlock; icoor++) {
1612
1/2
✓ Branch 1 taken 3698992 times.
✗ Branch 2 not taken.
3698992 UBlasMatrixRange matrix = matBlock(iblock+icoor, jblock+icoor);
1613
1/2
✓ Branch 1 taken 3698992 times.
✗ Branch 2 not taken.
3698992 matrix += tmpBlock;
1614 3698992 }
1615 2458444 }
1616
1617 /***********************************************************************************/
1618 /***********************************************************************************/
1619
1620 void ElementMatrix::grad_phi_j_grad_psi_i(const double coef, const CurrentFiniteElementWithBd& fewbdphi, const CurrentFiniteElementWithBd& fewbdpsi, felInt iBdPhi, felInt iBdPsi, const std::size_t iblock, const std::size_t jblock, const std::size_t numBlock)
1621 {
1622 // Check that the ids of the boundary is in the bound
1623 FEL_ASSERT(iBdPhi>=0 && iBdPhi<fewbdphi.numBdEle());
1624 FEL_ASSERT(iBdPsi>=0 && iBdPsi<fewbdpsi.numBdEle());
1625
1626 // Check that the derivatives have been computed
1627 FEL_ASSERT(fewbdphi.hasFirstDeriv());
1628 FEL_ASSERT(fewbdpsi.hasFirstDeriv());
1629
1630 // Check that the number of integration point is the same on the boundary
1631 FEL_ASSERT(fewbdphi.numQuadPointBdEle(iBdPhi) == fewbdpsi.numQuadPointBdEle(iBdPsi));
1632
1633 // Clear
1634 m_tmpMat.clear();
1635 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
1636
1637 // Compute the integral over the boundary
1638 for(felInt ilocg=0; ilocg<fewbdpsi.numQuadPointBdEle(iBdPsi); ++ilocg) {
1639 // boundary iBdPhi starts at iBdPhi+1 (0 for internal quad points)
1640 const felInt igphi = ilocg + fewbdphi.indexQuadPoint(iBdPhi+1);
1641 const felInt igpsi = ilocg + fewbdpsi.indexQuadPoint(iBdPsi+1);
1642
1643 tmpBlock += coef * fewbdpsi.bdEle(iBdPsi).weightMeas(ilocg) * prod(trans(fewbdpsi.dPhi[igpsi]), fewbdphi.dPhi[igphi]);
1644 }
1645
1646 for(std::size_t icoor=0; icoor<numBlock; icoor++) {
1647 UBlasMatrixRange matrix = matBlock(iblock+icoor, jblock+icoor);
1648 matrix += tmpBlock;
1649 }
1650 }
1651
1652 /***********************************************************************************/
1653 /***********************************************************************************/
1654
1655 85595 void ElementMatrix::div_phi_j_div_phi_i(const double coef, const CurrentFiniteElement& fe, const std::size_t iblock, std::size_t, const std::size_t num)
1656 {
1657 85595 m_tmpMat.clear();
1658
2/2
✓ Branch 0 taken 219333 times.
✓ Branch 1 taken 85595 times.
304928 for(std::size_t icoor=iblock; icoor<num; icoor++) {
1659
2/2
✓ Branch 0 taken 401214 times.
✓ Branch 1 taken 219333 times.
620547 for(std::size_t jcoor=icoor; jcoor<num; jcoor++) {
1660
1/2
✓ Branch 1 taken 401214 times.
✗ Branch 2 not taken.
401214 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat,icoor,jcoor);
1661
2/2
✓ Branch 1 taken 1492500 times.
✓ Branch 2 taken 401214 times.
1893714 for(felInt idof=0; idof<fe.numDof(); ++idof) {
1662
2/2
✓ Branch 1 taken 5632932 times.
✓ Branch 2 taken 1492500 times.
7125432 for(felInt jdof=0; jdof<fe.numDof(); ++jdof) {
1663
2/2
✓ Branch 1 taken 26833854 times.
✓ Branch 2 taken 5632932 times.
32466786 for(felInt ig=0; ig<fe.numQuadraturePoint(); ig++) {
1664
4/8
✓ Branch 1 taken 26833854 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 26833854 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 26833854 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 26833854 times.
✗ Branch 13 not taken.
26833854 tmpBlock(idof, jdof) += coef * fe.weightMeas(ig) * fe.dPhi[ig](jcoor, jdof) * fe.dPhi[ig](icoor, idof);
1665 }
1666 }
1667 }
1668
1/2
✓ Branch 1 taken 401214 times.
✗ Branch 2 not taken.
401214 UBlasMatrixRange mat1 = matBlock(icoor,jcoor);
1669
2/2
✓ Branch 0 taken 219333 times.
✓ Branch 1 taken 181881 times.
401214 if (jcoor==icoor) {
1670
1/2
✓ Branch 1 taken 219333 times.
✗ Branch 2 not taken.
219333 mat1 += tmpBlock;
1671 } else {
1672
1/2
✓ Branch 1 taken 181881 times.
✗ Branch 2 not taken.
181881 mat1 += tmpBlock;
1673
1/2
✓ Branch 1 taken 181881 times.
✗ Branch 2 not taken.
181881 UBlasMatrixRange mat2 = matBlock(jcoor,icoor);
1674
2/4
✓ Branch 1 taken 181881 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 181881 times.
✗ Branch 5 not taken.
181881 mat2 += trans(tmpBlock);
1675 181881 }
1676 401214 }
1677 }
1678 85595 }
1679
1680 /***********************************************************************************/
1681 /***********************************************************************************/
1682
1683 8106366 void ElementMatrix::stab_supg(const double dt, const double stab1, const double stab2, const double density, const double visc,
1684 const CurrentFiniteElement& fe,const ElementField& vel,const ElementField& rhs,
1685 ElementVector& elemVec,double& Re_elem,double& tau, const int type)
1686 {
1687 /**
1688 * Typical value for stab1 = 0.1
1689 * This stabilization does not include the 1/dt term (not strongly consistant with the time discrete scheme, may be viewed as a space-time, P0 in time)
1690 * If type = 1: stabilization parameter depends on dt (Tezduyar)
1691 * If type = 2: stabilization parameter independent of dt (Franca-Frey CMAME 1992)
1692 */
1693
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8106366 times.
8106366 FEL_ASSERT(vel.type() == DOF_FIELD);
1694
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8106366 times.
8106366 FEL_ASSERT(rhs.type() == DOF_FIELD);
1695
1696 // Resize if required
1697
2/2
✓ Branch 2 taken 3016 times.
✓ Branch 3 taken 8103350 times.
8106366 if (m_tmpVec2Coor.size() != m_tmpVecCoor.size())
1698 3016 m_tmpVec2Coor.resize(m_tmpVecCoor.size());
1699
1700 double weightJ,norm_u,delta,s,adv_j,div,adveps;
1701 8106366 const double h_elem = fe.diameter();
1702 int i0,j0,i0_pres;
1703
2/2
✓ Branch 1 taken 41905474 times.
✓ Branch 2 taken 8106366 times.
50011840 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
1704 41905474 weightJ = fe.weightMeas(ig);
1705 // Computation of u and f in the element in the integration point ig
1706
1/2
✓ Branch 3 taken 41905474 times.
✗ Branch 4 not taken.
41905474 m_tmpVecCoor = prod(vel.val,fe.phi[ig]); // vel
1707 41905474 norm_u = norm_1(m_tmpVecCoor);
1708
1/2
✓ Branch 3 taken 41905474 times.
✗ Branch 4 not taken.
41905474 m_tmpVec2Coor = prod(rhs.val,fe.phi[ig]); // rhs
1709 41905474 Re_elem = density*stab1*norm_u*h_elem/(4*visc);
1710
2/2
✓ Branch 0 taken 41633562 times.
✓ Branch 1 taken 271912 times.
41905474 if(Re_elem<1.) {
1711 41633562 tau = stab1*density*h_elem*h_elem/(8*visc);
1712 41633562 delta = stab2*norm_u*h_elem*Re_elem;
1713 } else {
1714 271912 tau = h_elem/(2.*norm_u);
1715 271912 delta = stab2*norm_u*h_elem;
1716 }
1717
2/2
✓ Branch 0 taken 18869764 times.
✓ Branch 1 taken 23035710 times.
41905474 if(type==1) {
1718 18869764 tau = 10.*stab1 / std::sqrt( (4./(dt*dt)) +
1719 18869764 (4.*norm_u*norm_u)/(h_elem*h_elem) +
1720 18869764 (16.*visc*visc)/(density*density*h_elem*h_elem*h_elem*h_elem)
1721 18869764 ) / density;
1722 // coef 10 is to have a typical value of 0.1 as for type 2
1723 18869764 delta = stab2*h_elem*h_elem/tau ;
1724 }
1725
1726 41905474 int ncoor = fe.numCoor();
1727 41905474 i0_pres = m_firstRow[ncoor];
1728
2/2
✓ Branch 1 taken 164756572 times.
✓ Branch 2 taken 41905474 times.
206662046 for(int idof=0; idof<fe.numDof(); idof++) {
1729 164756572 adveps=0.;
1730
2/2
✓ Branch 0 taken 485545744 times.
✓ Branch 1 taken 164756572 times.
650302316 for(int kcoor=0; kcoor<ncoor; kcoor++) {
1731 485545744 adveps += m_tmpVecCoor[kcoor]* fe.dPhi[ig](kcoor,idof);
1732 }
1733 164756572 adveps *= density*tau*weightJ;// rho (u.\gradv_i)
1734 164756572 s=0.;
1735
2/2
✓ Branch 0 taken 485545744 times.
✓ Branch 1 taken 164756572 times.
650302316 for(int icoor=0; icoor<ncoor; icoor++) {
1736 485545744 i0 = m_firstRow[icoor];
1737 485545744 elemVec.vec()[i0+idof] += m_tmpVec2Coor[icoor]*adveps;
1738 485545744 s += fe.dPhi[ig](icoor,idof)*m_tmpVec2Coor(icoor); // same fe for velocity and pressure
1739 }
1740 164756572 elemVec.vec()[i0_pres+idof] -= tau*s*weightJ;
1741
2/2
✓ Branch 1 taken 650430316 times.
✓ Branch 2 taken 164756572 times.
815186888 for(int jdof=0; jdof<fe.numDof(); jdof++) {
1742 650430316 adv_j = 0.;
1743
2/2
✓ Branch 0 taken 1924991032 times.
✓ Branch 1 taken 650430316 times.
2575421348 for(int kcoor=0; kcoor<ncoor; kcoor++) {
1744 1924991032 adv_j += m_tmpVecCoor(kcoor)*fe.dPhi[ig](kcoor,jdof);
1745 }
1746 650430316 adv_j *= density; // rho (u.\grad v_j)
1747
2/2
✓ Branch 0 taken 1924991032 times.
✓ Branch 1 taken 650430316 times.
2575421348 for(int icoor=0; icoor<ncoor; icoor++) {
1748 1924991032 i0 = m_firstRow[icoor];
1749 1924991032 div = delta*fe.dPhi[ig](icoor,idof)*weightJ;
1750
2/2
✓ Branch 0 taken 5722373264 times.
✓ Branch 1 taken 1924991032 times.
7647364296 for(int jcoor=0; jcoor<ncoor; jcoor++) {
1751 5722373264 j0 = m_firstCol[jcoor];
1752
2/2
✓ Branch 0 taken 1924991032 times.
✓ Branch 1 taken 3797382232 times.
5722373264 if(icoor==jcoor) {
1753 1924991032 m_mat(i0+idof,j0+jdof) += adv_j*adveps; // on the diagonal blocks
1754 }
1755 5722373264 m_mat(i0+idof,j0+jdof) += div*fe.dPhi[ig](jcoor,jdof);
1756 }// jcoor
1757 1924991032 m_mat(i0+idof,i0_pres+jdof) += adveps*fe.dPhi[ig](icoor,jdof); // // same fe for velocity and pressure
1758 1924991032 m_mat(i0_pres+idof,i0+jdof) -= fe.dPhi[ig](icoor,idof)*tau*weightJ*adv_j;
1759 1924991032 m_mat(i0_pres+idof,i0_pres+jdof) -= fe.dPhi[ig](icoor,idof)*fe.dPhi[ig](icoor,jdof)*tau*weightJ;
1760 }// icoor
1761 }// jdof
1762 }// idof
1763 }// ig
1764 8106366 }
1765
1766 /***********************************************************************************/
1767 /***********************************************************************************/
1768
1769 void ElementMatrix::stab_supgNSHeat(const double dt, const double stab1, const double alpha, const double density, const double visc,
1770 const CurrentFiniteElement& fe, const ElementField& vel, const int type, const std::vector<double> & gravity)
1771 {
1772 FEL_ASSERT(vel.type() == DOF_FIELD);
1773
1774 double weightJ,norm_u,Re_elem,adv_i,tau = 0.0;
1775 const double h_elem = fe.diameter();
1776 const felInt numCompVel = fe.numCoor();
1777 FEL_ASSERT(std::size_t(numCompVel) == gravity.size());
1778
1779 const felInt jBlockTemp = numCompVel + 1;
1780 const felInt iBlockPres = numCompVel;
1781
1782 felInt iStartVel,jStartTemp,iStartPre;
1783
1784 const double coeffVel=density*density*alpha;
1785 const double coeffPre=-density*alpha;
1786
1787 jStartTemp = m_firstCol[jBlockTemp];
1788 iStartPre = m_firstRow[iBlockPres];
1789
1790 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
1791 weightJ = fe.weightMeas(ig);
1792
1793 // Evaluation of the extrapolated velocity on the current quadrature node
1794 m_tmpVecCoor = prod(vel.val,fe.phi[ig]);
1795
1796 // Local Reynolds computation and parameter settings
1797 norm_u = norm_1(m_tmpVecCoor);
1798 Re_elem = density*stab1*norm_u*h_elem/(4*visc);
1799
1800 if (type==0) {
1801 if(Re_elem<1.) {
1802 tau = stab1*density*h_elem*h_elem/(8*visc);
1803 } else {
1804 tau = h_elem/(2.*norm_u);
1805 }
1806 } else if (type==1) {
1807 tau = 10.*stab1 / std::sqrt( (4./(dt*dt)) +
1808 (4.*norm_u*norm_u)/(h_elem*h_elem) +
1809 (16.*visc*visc)/(density*density*h_elem*h_elem*h_elem*h_elem)
1810 ) / density;
1811 }
1812
1813 for (int idof=0; idof<fe.numDof(); ++idof) {
1814 //w\dot \nabla \phi_{idof} (x_{ig})
1815 adv_i = 0;
1816 for (int kcoor=0; kcoor<numCompVel; kcoor++) {
1817 adv_i += m_tmpVecCoor[kcoor]*fe.dPhi[ig](kcoor,idof);
1818 }
1819 adv_i *= weightJ * coeffVel * tau;
1820 for (int icoor=0; icoor<numCompVel; icoor++) {
1821 iStartVel = m_firstRow[icoor];
1822 adv_i *= gravity[icoor];
1823 for (int jdof=0; jdof<fe.numDof(); ++jdof) {
1824 m_mat(iStartVel+idof,jStartTemp+jdof) += adv_i * fe.phi[ig](jdof);
1825 }
1826 }
1827 }
1828
1829 for (int idof=0; idof<fe.numDof(); ++idof) {
1830 //nabla \phi_{idof}\cdot gravity
1831 adv_i = 0;
1832 for (int kcoor=0; kcoor<numCompVel; kcoor++) {
1833 adv_i += gravity[kcoor]*fe.dPhi[ig](kcoor,idof);
1834 }
1835 adv_i *= weightJ * coeffPre * tau;
1836 for (int jdof=0; jdof<fe.numDof(); ++jdof) {
1837 m_mat(iStartPre+idof,jStartTemp+jdof) += adv_i * fe.phi[ig](jdof);
1838 }
1839 }
1840 }
1841 }
1842
1843 /***********************************************************************************/
1844 /***********************************************************************************/
1845
1846 1312620 void ElementMatrix::stab_supgAdvDiffCT(const double dt, const double stab1, const double stab2, const double density, const double visc,
1847 const CurrentFiniteElement& fe,const ElementField& vel)
1848 {
1849
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1312620 times.
1312620 FEL_ASSERT(vel.type() == DOF_FIELD);
1850
1851 double weightJ,norm_u,delta,adv_j,div,adveps, tau;
1852 1312620 const double h_elem = fe.diameter();
1853 int i0,j0;
1854
2/2
✓ Branch 1 taken 5250480 times.
✓ Branch 2 taken 1312620 times.
6563100 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
1855 5250480 weightJ = fe.weightMeas(ig);
1856 // Computation of u and f in the element in the integration point ig
1857
1/2
✓ Branch 3 taken 5250480 times.
✗ Branch 4 not taken.
5250480 m_tmpVecCoor = prod(vel.val,fe.phi[ig]); // vel
1858 5250480 norm_u = norm_1(m_tmpVecCoor);
1859 5250480 delta = stab2*norm_u*h_elem;
1860 5250480 tau = 10.*stab1 / std::sqrt( (4./(dt*dt)) +
1861 5250480 (4.*norm_u*norm_u)/(h_elem*h_elem) +
1862 5250480 (16.*visc*visc)/(density*density*h_elem*h_elem*h_elem*h_elem)
1863 ) / density;
1864 5250480 int ncoor = fe.numCoor();
1865
2/2
✓ Branch 1 taken 21001920 times.
✓ Branch 2 taken 5250480 times.
26252400 for(int idof=0; idof<fe.numDof(); idof++) {
1866 21001920 adveps=0.;
1867
2/2
✓ Branch 0 taken 63005760 times.
✓ Branch 1 taken 21001920 times.
84007680 for(int kcoor=0; kcoor<ncoor; kcoor++) {
1868 63005760 adveps += m_tmpVecCoor[kcoor]* fe.dPhi[ig](kcoor,idof);
1869 }
1870 21001920 adveps *= density*tau*weightJ;// rho (u.\gradv_i)
1871
2/2
✓ Branch 1 taken 84007680 times.
✓ Branch 2 taken 21001920 times.
105009600 for(int jdof=0; jdof<fe.numDof(); jdof++) {
1872 84007680 adv_j = 0.;
1873
2/2
✓ Branch 0 taken 252023040 times.
✓ Branch 1 taken 84007680 times.
336030720 for(int kcoor=0; kcoor<ncoor; kcoor++) {
1874 252023040 adv_j += m_tmpVecCoor(kcoor)*fe.dPhi[ig](kcoor,jdof);
1875 }
1876 84007680 adv_j *= density; // rho (u.\grad v_j)
1877
2/2
✓ Branch 0 taken 252023040 times.
✓ Branch 1 taken 84007680 times.
336030720 for(int icoor=0; icoor<ncoor; icoor++) {
1878 252023040 i0 = m_firstRow[icoor];
1879 252023040 div = delta*fe.dPhi[ig](icoor,idof)*weightJ;
1880
2/2
✓ Branch 0 taken 756069120 times.
✓ Branch 1 taken 252023040 times.
1008092160 for(int jcoor=0; jcoor<ncoor; jcoor++) {
1881 756069120 j0 = m_firstCol[jcoor];
1882
2/2
✓ Branch 0 taken 252023040 times.
✓ Branch 1 taken 504046080 times.
756069120 if(icoor==jcoor) {
1883 252023040 m_mat(i0+idof,j0+jdof) += adv_j*adveps; // on the diagonal blocks
1884 }
1885 756069120 m_mat(i0+idof,j0+jdof) += div*fe.dPhi[ig](jcoor,jdof);
1886 }// jcoor
1887 }// icoor
1888 }// jdof
1889 }// idof
1890 }// ig
1891 1312620 }
1892
1893 /***********************************************************************************/
1894 /***********************************************************************************/
1895
1896 1312620 void ElementMatrix::stab_supgProjCT(const double dt, const double stab1, const double density, const double visc, const CurrentFiniteElement& fe,const ElementField& vel)
1897 {
1898
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1312620 times.
1312620 FEL_ASSERT(vel.type() == DOF_FIELD);
1899
1/2
✓ Branch 1 taken 1312620 times.
✗ Branch 2 not taken.
1312620 UBlasMatrixRange matrix = matBlock(0,0);
1900 double norm_u;
1901
1/2
✓ Branch 1 taken 1312620 times.
✗ Branch 2 not taken.
1312620 const double h_elem = fe.diameter();
1902 double tau;
1903
2/2
✓ Branch 1 taken 5250480 times.
✓ Branch 2 taken 1312620 times.
6563100 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
1904 // Computation of u and f in the element in the integration point ig
1905
2/4
✓ Branch 2 taken 5250480 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5250480 times.
✗ Branch 6 not taken.
5250480 m_tmpVecCoor = prod(vel.val,fe.phi[ig]); // vel
1906
1/2
✓ Branch 1 taken 5250480 times.
✗ Branch 2 not taken.
5250480 norm_u = norm_1(m_tmpVecCoor);
1907 5250480 tau = 10.*stab1 / std::sqrt( (4./(dt*dt)) +
1908 5250480 (4.*norm_u*norm_u)/(h_elem*h_elem) +
1909 5250480 (16.*visc*visc)/(density*density*h_elem*h_elem*h_elem*h_elem)
1910 ) / density;
1911
5/10
✓ Branch 3 taken 5250480 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 5250480 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 5250480 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 5250480 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 5250480 times.
✗ Branch 16 not taken.
5250480 matrix += tau * fe.weightMeas(ig) * prod(trans(fe.dPhi[ig]),fe.dPhi[ig]);
1912 }
1913 1312620 }
1914
1915 /***********************************************************************************/
1916 /***********************************************************************************/
1917
1918 void ElementMatrix::stab_supgMatrixFS(const double dt, const double stabSUPG, const double density, const double viscosity,
1919 const double c0, const double c1, const double c2,
1920 const CurrentFiniteElement& fe, const ElementField& vel)
1921 {
1922 // Compute :
1923 // (int_K stabSUPG * tau * c0 * (vel . \grad) . v ) . (c1 u + c2 (vel . \grad) . u)
1924 // tau is computed automatically in the function
1925 FEL_ASSERT(vel.type() == DOF_FIELD);
1926 double weightJ, norm_u, adv_j, adveps, phij;
1927 const double h_elem = fe.diameter();
1928 double tau;
1929 int i0;
1930 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
1931 weightJ = fe.weightMeas(ig);
1932
1933 // Computation of U in the element in the integration point ig
1934 m_tmpVecCoor = prod(vel.val,fe.phi[ig]);
1935 norm_u = norm_1(m_tmpVecCoor);
1936
1937 tau = stabSUPG / std::sqrt( (4./(dt*dt)) +
1938 (4.*norm_u*norm_u)/(h_elem*h_elem) +
1939 (16*viscosity*viscosity)/(density*density*h_elem*h_elem*h_elem*h_elem));
1940
1941 int ncoor = fe.numCoor();
1942 for(int idof=0; idof<fe.numDof(); idof++) {
1943 adveps=0.;
1944 for(int kcoor=0; kcoor<ncoor; kcoor++) {
1945 adveps += m_tmpVecCoor(kcoor) * fe.dPhi[ig](kcoor, idof);
1946 }
1947 adveps *= c0 * tau * weightJ; // tau * C_0 (U . \grad) . v_i
1948
1949 for(int jdof=0; jdof<fe.numDof(); jdof++) {
1950 adv_j = 0.;
1951 for(int kcoor=0; kcoor<ncoor; kcoor++) {
1952 adv_j += m_tmpVecCoor(kcoor) * fe.dPhi[ig](kcoor, jdof);
1953 }
1954 adv_j *= c2; // C_2 (U . \grad) . v_j)
1955
1956 phij = c1 * fe.phi[ig](jdof); // C_1 v_j
1957
1958 for(int icoor=0; icoor<ncoor; icoor++) {
1959 i0 = m_firstRow[icoor];
1960
1961 // on the diagonal blocks
1962 m_mat(i0 + idof, i0 + jdof) += adveps * adv_j;
1963 m_mat(i0 + idof, i0 + jdof) += adveps * phij;
1964
1965 } // icoor
1966 } // jdof
1967 } // idof
1968 } // ig
1969 }
1970
1971 /***********************************************************************************/
1972 /***********************************************************************************/
1973
1974 void ElementMatrix::f_dot_n_grad_phi_i_grad_phi_j(const double coef,const CurvilinearFiniteElement& fe, const ElementField& elfield,const std::size_t iblock, const std::size_t jblock,const std::size_t num)
1975 {
1976 m_tmpMat.clear();
1977 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
1978 UBlasMatrix tmpAdPhi;
1979 double tmp,f_dot_n;
1980 for(int ig=0, numQuadPoint = fe.numQuadraturePoint(); ig < numQuadPoint; ig++) {
1981 f_dot_n = 0.;
1982 for(int icomp=0; icomp<fe.numCoor(); icomp++) {
1983 tmp = 0.;
1984 for(int jdof=0; jdof<fe.numDof(); jdof++) {
1985 tmp += fe.phi[ig](jdof) * elfield.val(icomp,jdof);
1986 }
1987 f_dot_n += tmp * fe.normal[ig](icomp);
1988 }
1989 tmpAdPhi = prod(fe.contravariantMetric[ig],fe.dPhiRef(ig));
1990
1991 if (f_dot_n < 0)
1992 tmpBlock += coef*f_dot_n*fe.weightMeas(ig)*prod(trans(fe.dPhiRef(ig)),tmpAdPhi);
1993 }
1994
1995 for(std::size_t icoor=0; icoor < num; icoor++) {
1996 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
1997 matrix += tmpBlock;
1998 }
1999 }
2000
2001 /***********************************************************************************/
2002 /***********************************************************************************/
2003
2004 900 void ElementMatrix:: f_dot_n_phi_i_phi_j(const double coef, const CurvilinearFiniteElement& fe,const ElementField& elfield, const std::size_t iblock, const std::size_t jblock,const std::size_t num, int stabFlag)
2005 {
2006
1/2
✓ Branch 1 taken 900 times.
✗ Branch 2 not taken.
900 m_tmpMat.clear();
2007 double tmp,f_dot_n;
2008
1/2
✓ Branch 1 taken 900 times.
✗ Branch 2 not taken.
900 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
2009
2/2
✓ Branch 1 taken 1800 times.
✓ Branch 2 taken 900 times.
2700 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
2010 1800 f_dot_n = 0.;
2011
2/2
✓ Branch 1 taken 3600 times.
✓ Branch 2 taken 1800 times.
5400 for(int icomp=0; icomp<fe.numCoor(); icomp++) {
2012 3600 tmp = 0.;
2013
2/2
✓ Branch 1 taken 7200 times.
✓ Branch 2 taken 3600 times.
10800 for(int jdof=0; jdof<fe.numDof(); jdof++) {
2014
2/4
✓ Branch 2 taken 7200 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 7200 times.
✗ Branch 6 not taken.
7200 tmp += fe.phi[ig](jdof) * elfield.val(icomp,jdof);
2015 }
2016
1/2
✓ Branch 2 taken 3600 times.
✗ Branch 3 not taken.
3600 f_dot_n += tmp * fe.normal[ig](icomp);
2017 }
2018 // outflow stabilization
2019
1/2
✓ Branch 0 taken 1800 times.
✗ Branch 1 not taken.
1800 if (stabFlag == 2) {
2020
2/2
✓ Branch 0 taken 1046 times.
✓ Branch 1 taken 754 times.
1800 if (f_dot_n < 0)
2021
4/8
✓ Branch 3 taken 1046 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1046 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1046 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1046 times.
✗ Branch 13 not taken.
1046 tmpBlock += f_dot_n * coef * fe.weightMeas(ig) * outer_prod(fe.phi[ig], fe.phi[ig]);
2022 } else { // this is no longer outflow stabilization.
2023 tmpBlock += f_dot_n * coef * fe.weightMeas(ig) * outer_prod(fe.phi[ig], fe.phi[ig]);
2024 }
2025
2026 }
2027
2028
2/2
✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 900 times.
2700 for(std::size_t icoor=0; icoor<num; icoor++) {
2029
1/2
✓ Branch 1 taken 1800 times.
✗ Branch 2 not taken.
1800 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
2030
1/2
✓ Branch 1 taken 1800 times.
✗ Branch 2 not taken.
1800 matrix += tmpBlock;
2031 1800 }
2032 900 }
2033
2034 /***********************************************************************************/
2035 /***********************************************************************************/
2036
2037 12816 void ElementMatrix:: f_dot_n_phi_i_phi_j(const double coef, const CurrentFiniteElement& fe, const ElementField& elt_f, const ElementField& elt_n, const std::size_t iblock, const std::size_t jblock, const std::size_t num, felInt stabFlag)
2038 {
2039
1/2
✓ Branch 1 taken 12816 times.
✗ Branch 2 not taken.
12816 m_tmpMat.clear();
2040 double tmp, f_dot_n;
2041
1/2
✓ Branch 1 taken 12816 times.
✗ Branch 2 not taken.
12816 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
2042
2/2
✓ Branch 1 taken 38448 times.
✓ Branch 2 taken 12816 times.
51264 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
2043 38448 f_dot_n = 0.;
2044
2/2
✓ Branch 1 taken 76896 times.
✓ Branch 2 taken 38448 times.
115344 for(int icomp=0; icomp<fe.numCoor(); icomp++) {
2045 76896 tmp = 0.;
2046
2/2
✓ Branch 1 taken 230688 times.
✓ Branch 2 taken 76896 times.
307584 for(int jdof=0; jdof<fe.numDof(); jdof++) {
2047
2/4
✓ Branch 2 taken 230688 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 230688 times.
✗ Branch 6 not taken.
230688 tmp += fe.phi[ig](jdof) * elt_f.val(icomp, jdof);
2048 }
2049
1/2
✓ Branch 1 taken 76896 times.
✗ Branch 2 not taken.
76896 f_dot_n += tmp * elt_n.val(icomp, 0);
2050 }
2051
2052
3/4
✓ Branch 0 taken 20578 times.
✓ Branch 1 taken 17870 times.
✓ Branch 2 taken 20578 times.
✗ Branch 3 not taken.
38448 if (f_dot_n < 0 || stabFlag != 2)
2053
4/8
✓ Branch 3 taken 38448 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 38448 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 38448 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 38448 times.
✗ Branch 13 not taken.
38448 tmpBlock += f_dot_n * coef * fe.weightMeas(ig) * outer_prod(fe.phi[ig], fe.phi[ig]);
2054 }
2055
2056
2/2
✓ Branch 0 taken 25632 times.
✓ Branch 1 taken 12816 times.
38448 for(std::size_t icoor=0; icoor<num; icoor++) {
2057
1/2
✓ Branch 1 taken 25632 times.
✗ Branch 2 not taken.
25632 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + icoor);
2058
1/2
✓ Branch 1 taken 25632 times.
✗ Branch 2 not taken.
25632 matrix += tmpBlock;
2059 25632 }
2060 12816 }
2061
2062 /***********************************************************************************/
2063 /***********************************************************************************/
2064
2065 void ElementMatrix::abs_u_dot_n_phi_i_phi_j(const double coef,
2066 ElementField& vel,
2067 CurvilinearFiniteElement& fe,
2068 const std::size_t iblock, const std::size_t jblock,int num)
2069 {
2070
2071 m_tmpMat.clear();
2072
2073 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
2074 double tmp;
2075 double u_dot_n;
2076
2077 //switch(vel.type()){
2078 //case DOF_FIELD: {
2079 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) { // loop on gauss pts.
2080 u_dot_n = 0;
2081 for(int icomp=0; icomp<fe.numCoor(); icomp++) {
2082 tmp = 0.;
2083 for(int jdof=0; jdof<fe.numDof(); jdof++) {
2084 tmp += fe.phi[ig](jdof) * vel.val(icomp,jdof);
2085 }
2086 u_dot_n += tmp * fe.normal[ig](icomp);
2087 }
2088 tmpBlock += 0.5 * (std::abs(u_dot_n)-u_dot_n) *
2089 coef * fe.weightMeas(ig) * outer_prod(fe.phi[ig], fe.phi[ig]);
2090 }
2091
2092 //std::cout << " block" << iblock << "," << jblock << std::endl;
2093 for(int icoor=0; icoor<num; icoor++) {
2094 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
2095 matrix += tmpBlock;
2096 }
2097 }
2098
2099 /***********************************************************************************/
2100 /***********************************************************************************/
2101
2102 void ElementMatrix::phi_i_times_n_phi_j_times_n(const double coef, const CurvilinearFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const int numComp)
2103 {
2104 IGNORE_UNUSED_ARGUMENT(numComp);
2105 m_tmpMat.clear();
2106 // TGV \int_element_in_Gamma [ (phi_i \cdot \tau) \tau ] \cdot [ (phi_j \cdot \tau) \tau ] =
2107 // = TGV \int_element_in_Gamma (phi_i \cdot \tau) (phi_j \cdot \tau) =
2108 // = TGV \int_element_in_Gamma [ (I - n x n^t) phi_i ] \cdot [ (I - n x n^t) phi_j ]
2109
2110 UBlasIdentityMatrix IdeMat(fe.numCoor());
2111
2112 for( std::size_t icoor=0 ; icoor < (std::size_t) fe.numCoor() ; icoor++ ) {
2113 for( std::size_t jcoor=0 ; jcoor < (std::size_t) fe.numCoor() ; jcoor++ ) {
2114 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat,iblock+icoor,jblock+jcoor);
2115 for( std::size_t idof=0 ; idof < (std::size_t) fe.numDof() ; idof++ ) {
2116 for( std::size_t jdof=0 ; jdof < (std::size_t) fe.numDof() ; jdof++ ) {
2117 for( std::size_t ig=0; ig < (std::size_t) fe.numQuadraturePoint(); ig++ ) {
2118 tmpBlock(idof,jdof) += coef * fe.weightMeas(ig) * ( IdeMat(icoor,jcoor) - fe.normal[ig](icoor) * fe.normal[ig](jcoor) ) * fe.phi[ig](idof) * fe.phi[ig](jdof);
2119 }
2120 }
2121 }
2122 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+jcoor);
2123 matrix += tmpBlock;
2124 }
2125 }
2126 }
2127
2128 /***********************************************************************************/
2129 /***********************************************************************************/
2130
2131 44800 void ElementMatrix::phi_i_dot_n_phi_j_dot_n(const double coef, const CurvilinearFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const int numComp)
2132 {
2133 IGNORE_UNUSED_ARGUMENT(numComp);
2134
2135 44800 m_tmpMat.clear();
2136
2137
2/2
✓ Branch 1 taken 134400 times.
✓ Branch 2 taken 44800 times.
179200 for( std::size_t icoor=0 ; icoor < (std::size_t) fe.numCoor() ; icoor++ ) {
2138
2/2
✓ Branch 1 taken 403200 times.
✓ Branch 2 taken 134400 times.
537600 for( std::size_t jcoor=0 ; jcoor < (std::size_t) fe.numCoor() ; jcoor++ ) {
2139
2140
1/2
✓ Branch 1 taken 403200 times.
✗ Branch 2 not taken.
403200 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat,iblock+icoor,jblock+jcoor);
2141
2142
2/2
✓ Branch 1 taken 1209600 times.
✓ Branch 2 taken 403200 times.
1612800 for( std::size_t ig=0; ig < (std::size_t) fe.numQuadraturePoint(); ig++ ) {
2143
2144
2/2
✓ Branch 1 taken 3628800 times.
✓ Branch 2 taken 1209600 times.
4838400 for( std::size_t idof=0 ; idof < (std::size_t) fe.numDof() ; idof++ ) {
2145
2/2
✓ Branch 1 taken 10886400 times.
✓ Branch 2 taken 3628800 times.
14515200 for( std::size_t jdof=0 ; jdof < (std::size_t) fe.numDof() ; jdof++ ) {
2146
2147 // coef * (phi_i \cdot \n_icoor) * (phi_j \cdot \n_jcoor)
2148
6/12
✓ Branch 1 taken 10886400 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 10886400 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 10886400 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 10886400 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 10886400 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 10886400 times.
✗ Branch 21 not taken.
10886400 tmpBlock(idof,jdof) += coef * fe.weightMeas(ig) * fe.normal[ig](icoor) * fe.phi[ig](idof) * fe.normal[ig](jcoor) * fe.phi[ig](jdof);
2149 }
2150 }
2151 }
2152
1/2
✓ Branch 1 taken 403200 times.
✗ Branch 2 not taken.
403200 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+jcoor);
2153
1/2
✓ Branch 1 taken 403200 times.
✗ Branch 2 not taken.
403200 matrix += tmpBlock;
2154 403200 }
2155 }
2156 44800 }
2157
2158 /***********************************************************************************/
2159 /***********************************************************************************/
2160
2161 void ElementMatrix::phi_i_dot_t_phi_j_dot_t(const double coef, const CurvilinearFiniteElement& fe, const std::size_t iblock, const std::size_t jblock, const int numComp)
2162 {
2163 // IGNORE_UNUSED_ARGUMENT(numComp);
2164
2165 m_tmpMat.clear();
2166 for( std::size_t icoor=0 ; icoor < (std::size_t) fe.numCoor() ; icoor++ ) {
2167 for( std::size_t jcoor=0 ; jcoor < (std::size_t) fe.numCoor() ; jcoor++ ) {
2168
2169 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat,iblock+icoor,jblock+jcoor);
2170
2171 for( std::size_t ig=0; ig < (std::size_t) fe.numQuadraturePoint(); ig++ ) {
2172
2173 for( std::size_t idof=0 ; idof < (std::size_t) fe.numDof() ; idof++ ) {
2174 for( std::size_t jdof=0 ; jdof < (std::size_t) fe.numDof() ; jdof++ ) {
2175
2176 for( int ic=0 ; ic < numComp ; ic++ ) {
2177 // coef * (phi_i \cdot \t_icoor) * (phi_j \cdot \t_jcoor)
2178 tmpBlock(idof,jdof) += coef * fe.weightMeas(ig) * fe.tangent[ig](ic,icoor) * fe.phi[ig](idof) * fe.tangent[ig](ic,jcoor) * fe.phi[ig](jdof);
2179 }
2180 }
2181 }
2182 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+jcoor);
2183 matrix += tmpBlock;
2184 }
2185 }
2186 }
2187 }
2188
2189 /***********************************************************************************/
2190 /***********************************************************************************/
2191
2192 void ElementMatrix::eps_phi_j_n_dot_n_phi_i_dot_n(const double coeff, const CurrentFiniteElementWithBd& fe,int iblockBd,int numblockBd,const std::size_t iblock,const std::size_t jblock,std::size_t /*num*/)
2193 {
2194 //matteo feb 14
2195 FEL_ASSERT(iblockBd>=0 && iblockBd<fe.numBdEle() && (numblockBd-iblockBd) <= fe.numBdEle() );
2196 m_tmpMat.clear();
2197
2198 for (int ibd=iblockBd; ibd<iblockBd+numblockBd; ibd++) {
2199 FEL_ASSERT( fe.bdEle(ibd).hasNormal() && fe.hasFirstDeriv() );
2200 for( std::size_t icoor=0 ; icoor < (std::size_t) fe.numCoor() ; icoor++ ) {
2201 for( std::size_t jcoor=0 ; jcoor < (std::size_t) fe.numCoor() ; jcoor++ ) {
2202 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat,iblock+icoor,jblock+jcoor);
2203 //std::cout<<" nRow "<<numBlockRow()<<" nCol "<<numBlockRow()<<std::endl;
2204 for( std::size_t jdof=0 ; jdof < (std::size_t) fe.numDof() ; jdof++ ) { // number of dof of the volume element
2205 for( std::size_t idof=0 ; idof < (std::size_t) fe.bdEle(ibd).numDof() ; idof++ ) { //number of dof of the surface element
2206 for( int ilocg=0; ilocg<fe.numQuadPointBdEle(ibd); ilocg++) {
2207 int ig = ilocg+fe.indexQuadPoint(ibd+1); // face ibd starts at ibd+1 (0 for internal quad points)
2208 for( std::size_t jaux=0 ; jaux < (std::size_t) fe.numCoor() ; jaux++ ) {
2209 //std::cout<<"(i,j) ("<<idof<<","<<jdof<<")"<<std::endl;
2210 tmpBlock(idof,jdof) += coeff * fe.bdEle(ibd).weightMeas(ilocg) * fe.dPhi[ig](jaux,jdof) * fe.bdEle(ibd).normal[ilocg](jaux)
2211 * fe.bdEle(ibd).normal[ilocg](jcoor) * fe.bdEle(ibd).normal[ilocg](icoor) * fe.bdEle(ibd).phi[ilocg](idof);
2212 }
2213 }
2214 }
2215 }
2216 //std::cout << " tmpBlock " << tmpBlock << std::endl;
2217 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+jcoor);
2218 matrix += tmpBlock;
2219 }
2220 }
2221 }
2222 }
2223
2224 /***********************************************************************************/
2225 /***********************************************************************************/
2226
2227 void ElementMatrix::psi_j_phi_i_dot_n(const double coeff,const CurvilinearFiniteElement& feVel, const CurvilinearFiniteElement& fePres,const std::size_t iblock,std::size_t presBlock,std::size_t /*num*/)
2228 {
2229 // Matteo feb 14
2230 m_tmpMat.clear();
2231 for( std::size_t icoor=0 ; icoor < (std::size_t) feVel.numCoor() ; icoor++ ) {
2232 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat,iblock+icoor,presBlock);
2233 for( std::size_t idof=0 ; idof < (std::size_t) feVel.numDof() ; idof++ ) {
2234 for( std::size_t jdof=0 ; jdof < (std::size_t) fePres.numDof() ; jdof++ ) {
2235 for( std::size_t ig=0; ig < (std::size_t) feVel.numQuadraturePoint(); ig++ ) {
2236 tmpBlock(idof,jdof) += coeff * feVel.weightMeas(ig) * feVel.normal[ig](icoor) * feVel.phi[ig](idof) * fePres.phi[ig](jdof);
2237 }
2238 }
2239 }
2240 UBlasMatrixRange matrix = matBlock(iblock+icoor,presBlock);
2241 matrix += tmpBlock;
2242 }
2243 }
2244
2245 /***********************************************************************************/
2246 /***********************************************************************************/
2247
2248 //this type of elementmatrix is rectangular and it is used in EmbedFSI boundary condition (matteo feb 2014)
2249 ElementMatrix::ElementMatrix(const CurBaseFiniteElement& feVel1, const CurBaseFiniteElement& feVel2, std::size_t nbr1, std::size_t nbc1,
2250 const CurBaseFiniteElement& fePres, std::size_t nbr2, std::size_t nbc2) :
2251 m_mat( feVel2.numDof()*nbr1 + fePres.numDof()*nbr2, feVel1.numDof()*nbc1 + fePres.numDof()*nbc2 ),
2252 m_tmpMat( feVel2.numDof()*nbr1 + fePres.numDof()*nbr2, feVel1.numDof()*nbc1 + fePres.numDof()*nbc2 )
2253 {
2254
2255 //
2256 m_numRow.resize( nbr1 + nbr2 );
2257 m_firstRow.resize( nbr1 + nbr2 );
2258 m_numCol.resize( nbc1 + nbc2 );
2259 m_firstCol.resize( nbc1 + nbc2 );
2260 //
2261 std::size_t first=0;
2262 for (std::size_t n=0; n<nbr1; n++) {
2263 m_numRow[ n ]=feVel2.numDof();
2264 m_firstRow[ n ]=first;
2265 first += feVel2.numDof();
2266 }
2267 for (std::size_t n=nbr1; n<nbr1+nbr2; n++) {
2268 m_numRow[ n ]=fePres.numDof();
2269 m_firstRow[ n ]=first;
2270 first += fePres.numDof();
2271 }
2272 //
2273 first=0;
2274 for (std::size_t n=0; n<nbc1; n++) {
2275 m_numCol[ n ]=feVel1.numDof();
2276 m_firstCol[ n ]=first;
2277 first += feVel1.numDof();
2278 }
2279 for (std::size_t n=nbc1; n<nbc1 + nbc2; n++) {
2280 m_numCol[ n ]=fePres.numDof();
2281 m_firstCol[ n ]=first;
2282 first += fePres.numDof();
2283 }
2284 m_mat.clear();
2285 m_tmpMat.clear();
2286 }
2287
2288 /***********************************************************************************/
2289 /***********************************************************************************/
2290
2291 193677 void ElementMatrix::psi_j_phi_i_dot_n_on_nodes( const double coeff, const ElementField& normal, const CurvilinearFiniteElement& feVel, const CurvilinearFiniteElement& fePres,const std::size_t iblock,std::size_t presBlock)
2292 {
2293
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 193677 times.
193677 FEL_ASSERT( normal.type() == DOF_FIELD );
2294
2295 193677 m_tmpMat.clear();
2296
2/2
✓ Branch 1 taken 580791 times.
✓ Branch 2 taken 193677 times.
774468 for( std::size_t icoor=0 ; icoor < (std::size_t) feVel.numCoor() ; icoor++ ) {
2297
1/2
✓ Branch 1 taken 580791 times.
✗ Branch 2 not taken.
580791 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat,iblock+icoor,presBlock);
2298
2/2
✓ Branch 1 taken 1741893 times.
✓ Branch 2 taken 580791 times.
2322684 for( std::size_t idof=0 ; idof < (std::size_t) feVel.numDof() ; idof++ ) {
2299
2/2
✓ Branch 1 taken 5224719 times.
✓ Branch 2 taken 1741893 times.
6966612 for( std::size_t jdof=0 ; jdof < (std::size_t) fePres.numDof() ; jdof++ ) {
2300
2/2
✓ Branch 1 taken 31342554 times.
✓ Branch 2 taken 5224719 times.
36567273 for( std::size_t ig=0; ig < (std::size_t) feVel.numQuadraturePoint(); ig++ ) {
2301
5/10
✓ Branch 1 taken 31342554 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 31342554 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 31342554 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 31342554 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 31342554 times.
✗ Branch 16 not taken.
31342554 tmpBlock(idof,jdof) += coeff * feVel.weightMeas(ig) * normal.val( icoor, jdof ) * feVel.phi[ig](idof) * fePres.phi[ig](jdof);
2302 }
2303 }
2304 }
2305
1/2
✓ Branch 1 taken 580791 times.
✗ Branch 2 not taken.
580791 UBlasMatrixRange matrix = matBlock(iblock+icoor,presBlock);
2306
1/2
✓ Branch 1 taken 580791 times.
✗ Branch 2 not taken.
580791 matrix += tmpBlock;
2307 580791 }
2308 193677 }
2309
2310 /***********************************************************************************/
2311 /***********************************************************************************/
2312
2313 void ElementMatrix::sGrad_psi_j_tensor_sGrad_phi_i(const double coef, const ElementField& normalField, const CurvilinearFiniteElement& fe, const UBlasMatrix& tensor)
2314 {
2315 for ( int solLocDof(0); solLocDof < fe.numDof(); solLocDof++) {
2316 UBlasVector gradSol(2);
2317 gradSol=Curvatures::testFuncGradient(solLocDof);
2318
2319 UBlasVector KgradSol(2);
2320 KgradSol(0)=0.;
2321 KgradSol(1)=0.;
2322 KgradSol = prod(tensor, gradSol );
2323
2324 for ( int testLocDof(0); testLocDof < fe.numDof(); testLocDof++) {
2325
2326 UBlasVector gradTest(2);
2327 gradTest=Curvatures::testFuncGradient(testLocDof);
2328
2329 double val = coef*inner_prod(KgradSol, gradTest) * fe.measure(); //TODO only P1! we should integrate, but gradient is constant over the element
2330 for ( int solCoor(0); solCoor < fe.numCoor(); solCoor++) {
2331 for ( int testCoor(0); testCoor < fe.numCoor(); testCoor++) {
2332 double value = val* normalField.val(testCoor,testLocDof)* normalField.val(solCoor,testLocDof);
2333 UBlasMatrixRange matrix = matBlock(solCoor,testCoor);
2334 matrix(solLocDof,testLocDof) += value;
2335 }
2336 }
2337 }
2338 }
2339 }
2340
2341 /***********************************************************************************/
2342 /***********************************************************************************/
2343
2344 void ElementMatrix::sGrad_psi_j_tensor_sGrad_phi_i_for_scalar(const double coef, const CurvilinearFiniteElement& fe, const UBlasMatrix& tensor, const std::size_t blockId)
2345 {
2346 for ( int solLocDof(0); solLocDof < fe.numDof(); solLocDof++) {
2347 UBlasVector gradSol(2);
2348 gradSol=Curvatures::testFuncGradient(solLocDof);
2349 UBlasVector KgradSol(2);
2350 KgradSol(0)=0.;
2351 KgradSol(1)=0.;
2352 KgradSol = prod(tensor, gradSol );
2353 for ( int testLocDof(0); testLocDof < fe.numDof(); testLocDof++) {
2354 UBlasVector gradTest(2);
2355 gradTest=Curvatures::testFuncGradient(testLocDof);
2356 double val = coef*inner_prod(KgradSol, gradTest) * fe.measure(); //TODO only P1! we should integrate, but gradient is constant over the element
2357 UBlasMatrixRange matrix = matBlock(blockId,blockId);
2358 matrix(solLocDof,testLocDof) += val;
2359 }
2360 }
2361 }
2362
2363 /***********************************************************************************/
2364 /***********************************************************************************/
2365
2366 931737 void ElementMatrix::sGrad_psi_j_tensor_sGrad_phi_i(const double coef, const ElementField& elemCoef, const ElementField& normalField, const CurvilinearFiniteElement& fe, const UBlasMatrix& tensor)
2367 {
2368
1/3
✓ Branch 1 taken 931737 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
931737 switch(elemCoef.type()) {
2369 931737 case DOF_FIELD:
2370
2/2
✓ Branch 1 taken 5590422 times.
✓ Branch 2 taken 931737 times.
6522159 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
2371
1/2
✓ Branch 3 taken 5590422 times.
✗ Branch 4 not taken.
5590422 m_tmpVecCoor = prod(elemCoef.val,fe.phi[ig]);
2372 5590422 m_tmpVecQuadPoint(ig) = m_tmpVecCoor(0);
2373 }
2374 931737 break;
2375 case CONSTANT_FIELD:
2376 case QUAD_POINT_FIELD:
2377 FEL_ERROR("this case has not been implemented");
2378 break;
2379 }
2380
2381
2/2
✓ Branch 1 taken 2795211 times.
✓ Branch 2 taken 931737 times.
3726948 for ( int solLocDof(0); solLocDof < fe.numDof(); solLocDof++) {
2382
1/2
✓ Branch 1 taken 2795211 times.
✗ Branch 2 not taken.
2795211 UBlasVector gradSol(2);
2383
2/4
✓ Branch 1 taken 2795211 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2795211 times.
✗ Branch 5 not taken.
2795211 gradSol=Curvatures::testFuncGradient(solLocDof);
2384
2385
1/2
✓ Branch 1 taken 2795211 times.
✗ Branch 2 not taken.
2795211 UBlasVector KgradSol(2);
2386
1/2
✓ Branch 1 taken 2795211 times.
✗ Branch 2 not taken.
2795211 KgradSol(0)=0.;
2387
1/2
✓ Branch 1 taken 2795211 times.
✗ Branch 2 not taken.
2795211 KgradSol(1)=0.;
2388
2/4
✓ Branch 1 taken 2795211 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2795211 times.
✗ Branch 5 not taken.
2795211 KgradSol = prod(tensor, gradSol );
2389
2390
2/2
✓ Branch 1 taken 8385633 times.
✓ Branch 2 taken 2795211 times.
11180844 for ( int testLocDof(0); testLocDof < fe.numDof(); testLocDof++) {
2391
1/2
✓ Branch 1 taken 8385633 times.
✗ Branch 2 not taken.
8385633 UBlasVector gradTest(2);
2392
2/4
✓ Branch 1 taken 8385633 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8385633 times.
✗ Branch 5 not taken.
8385633 gradTest=Curvatures::testFuncGradient(testLocDof);
2393
2394 8385633 double val = 0.0;
2395
2/2
✓ Branch 1 taken 50313798 times.
✓ Branch 2 taken 8385633 times.
58699431 for(int ig=0; ig<fe.numQuadraturePoint(); ig++)
2396
3/6
✓ Branch 1 taken 50313798 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 50313798 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 50313798 times.
✗ Branch 8 not taken.
50313798 val += coef * m_tmpVecQuadPoint(ig) * inner_prod(KgradSol, gradTest) * fe.weightMeas(ig); //TODO only P1! we should integrate, but gradient is constant over the element
2397
2/2
✓ Branch 1 taken 25156899 times.
✓ Branch 2 taken 8385633 times.
33542532 for ( int solCoor(0); solCoor < fe.numCoor(); solCoor++) {
2398
2/2
✓ Branch 1 taken 75470697 times.
✓ Branch 2 taken 25156899 times.
100627596 for ( int testCoor(0); testCoor < fe.numCoor(); testCoor++) {
2399
2/4
✓ Branch 1 taken 75470697 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 75470697 times.
✗ Branch 5 not taken.
75470697 double value = val* normalField.val(testCoor,testLocDof)* normalField.val(solCoor,testLocDof);
2400
1/2
✓ Branch 1 taken 75470697 times.
✗ Branch 2 not taken.
75470697 UBlasMatrixRange matrix = matBlock(solCoor,testCoor);
2401
1/2
✓ Branch 1 taken 75470697 times.
✗ Branch 2 not taken.
75470697 matrix(solLocDof,testLocDof) += value;
2402 75470697 }
2403 }
2404 8385633 }
2405 2795211 }
2406 931737 }
2407
2408 /***********************************************************************************/
2409 /***********************************************************************************/
2410
2411 void ElementMatrix::dpsi_j_dh_psi_i(const double coef, const CurrentFiniteElement& fei,const CurrentFiniteElement& fej,std::size_t h, const std::size_t iblock, const std::size_t jblock)
2412 {
2413 m_tmpMat.clear();
2414
2415 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
2416 for(int ig=0; ig<fei.numQuadraturePoint(); ig++) {
2417 for(int idof=0; idof<fei.numDof(); idof++) {
2418 for(int jdof=0; jdof<fej.numDof(); jdof++) {
2419 tmpBlock(idof,jdof) += coef*fei.weightMeas(ig) * fei.phi[ig](idof) * fej.dPhi[ig](h,jdof);
2420 }
2421 }
2422 }
2423 UBlasMatrixRange block = matBlock(iblock,jblock);
2424 block+=tmpBlock;
2425 }
2426
2427 /***********************************************************************************/
2428 /***********************************************************************************/
2429
2430 193437 void ElementMatrix::transpirationSurfStab( const double coef, const ElementField& elemCoef, const ElementField& normalField, const CurvilinearFiniteElement& fe, const UBlasMatrix& tensor)
2431 {
2432 // Tensor is supposed to be the inverse matric tensor
2433 // TODO compute directly it from fe!
2434
1/3
✓ Branch 1 taken 193437 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
193437 switch(elemCoef.type()) {
2435 193437 case DOF_FIELD:
2436
2/2
✓ Branch 1 taken 1160622 times.
✓ Branch 2 taken 193437 times.
1354059 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
2437
1/2
✓ Branch 3 taken 1160622 times.
✗ Branch 4 not taken.
1160622 m_tmpVecCoor = prod(elemCoef.val,fe.phi[ig]);
2438 1160622 m_tmpVecQuadPoint(ig) = m_tmpVecCoor(0)*coef;
2439 }
2440 193437 break;
2441 case CONSTANT_FIELD:
2442 case QUAD_POINT_FIELD:
2443 FEL_ERROR("this case has not been implemented");
2444 break;
2445 }
2446
2447 // Only P1
2448 193437 double coeffQuad = 0.0;
2449
2/2
✓ Branch 1 taken 1160622 times.
✓ Branch 2 taken 193437 times.
1354059 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
2450 1160622 coeffQuad += m_tmpVecQuadPoint(ig) * fe.weightMeas(ig) * fe.diameter() ;
2451 }
2452
2453
2/2
✓ Branch 1 taken 580311 times.
✓ Branch 2 taken 193437 times.
773748 for ( int solLocDof(0); solLocDof < fe.numDof(); solLocDof++) {
2454
2/2
✓ Branch 1 taken 1740933 times.
✓ Branch 2 taken 580311 times.
2321244 for ( int testLocDof(0); testLocDof < fe.numDof(); testLocDof++) {
2455 // Computation of (\nabla_c\phi_test)^T A^-1 \nabla_c\phi_sol
2456
1/2
✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
1740933 UBlasVector gradSol(2);
2457
1/2
✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
1740933 UBlasVector gradTest(2);
2458
1/2
✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
1740933 UBlasVector KgradSol(2);
2459
1/2
✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
1740933 KgradSol(0)=0.;
2460
1/2
✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
1740933 KgradSol(1)=0.;
2461
2/4
✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1740933 times.
✗ Branch 5 not taken.
1740933 gradSol = Curvatures::testFuncGradient(solLocDof);
2462
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);
2463
2/4
✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1740933 times.
✗ Branch 5 not taken.
1740933 KgradSol = prod(tensor, gradSol );
2464
2465
1/2
✓ Branch 1 taken 1740933 times.
✗ Branch 2 not taken.
1740933 const double lap = inner_prod(KgradSol, gradTest);
2466
2467
2/2
✓ Branch 1 taken 5222799 times.
✓ Branch 2 taken 1740933 times.
6963732 for ( int solCoor(0); solCoor < fe.numCoor(); solCoor++) {
2468
2/2
✓ Branch 1 taken 15668397 times.
✓ Branch 2 taken 5222799 times.
20891196 for ( int testCoor(0); testCoor < fe.numCoor(); testCoor++) {
2469
2470 15668397 double projCoef = 0;
2471
2/2
✓ Branch 1 taken 47005191 times.
✓ Branch 2 taken 15668397 times.
62673588 for ( int ausCoor(0); ausCoor < fe.numCoor(); ++ausCoor ) {
2472 47005191 double deltaTest(0), deltaSol(0);
2473
2/2
✓ Branch 0 taken 15668397 times.
✓ Branch 1 taken 31336794 times.
47005191 if ( solCoor - ausCoor == 0 )
2474 15668397 deltaSol = 1;
2475
2/2
✓ Branch 0 taken 15668397 times.
✓ Branch 1 taken 31336794 times.
47005191 if ( testCoor - ausCoor == 0 )
2476 15668397 deltaTest = 1;
2477 // setting normnorm
2478
2/4
✓ Branch 1 taken 47005191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 47005191 times.
✗ Branch 5 not taken.
47005191 double normnormSol = normalField.val( solCoor, solLocDof)*normalField.val(ausCoor, solLocDof);
2479
2/4
✓ Branch 1 taken 47005191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 47005191 times.
✗ Branch 5 not taken.
47005191 double normnormTest = normalField.val(testCoor,testLocDof)*normalField.val(ausCoor,testLocDof);
2480 47005191 projCoef += ( deltaSol - normnormSol ) * ( deltaTest - normnormTest );
2481 }
2482
2483 15668397 const double value = projCoef * lap * coeffQuad;
2484
2485
1/2
✓ Branch 1 taken 15668397 times.
✗ Branch 2 not taken.
15668397 UBlasMatrixRange matrix = matBlock(solCoor,testCoor);
2486
1/2
✓ Branch 1 taken 15668397 times.
✗ Branch 2 not taken.
15668397 matrix(solLocDof,testLocDof) += value;
2487 15668397 }
2488 }
2489 1740933 }
2490 }
2491 193437 }
2492
2493 /***********************************************************************************/
2494 /***********************************************************************************/
2495
2496 void ElementMatrix::velocityConstraint(const double coef, const ElementField& disp, const CurvilinearFiniteElement& fe, int iblock)
2497 {
2498 FEL_CHECK(fe.hasMeas() ,"ElementMatrix::velocityConstraint: requires covariant basis");
2499 FEL_CHECK(disp.type() == DOF_FIELD,"ElementMatrix::velocityConstraint: wrong displacement field type");
2500
2501 const UBlasMatrix& d = disp.val;
2502
2503 UBlasMatrix cbasis(fe.numRefCoor(),fe.numCoor()); // covariant basis in current configuation
2504 UBlasVector n(fe.numCoor()); // normal std::vector, not unitary
2505
2506 double sum;
2507
2508 // loop on quadrature points
2509 for (int iq=0; iq < fe.numQuadraturePoint(); ++iq) {
2510 // covariant basis in current configuratgion
2511 for (int ir=0; ir < fe.numRefCoor(); ++ir) {
2512 for (int ic=0; ic <fe.numCoor(); ++ic) {
2513 cbasis(ir,ic) = fe.m_covBasis[iq](ir,ic);
2514 for(int idof=0; idof< fe.numDof(); idof++)
2515 cbasis(ir,ic) += d(ic,idof)*fe.dPhiRef(iq)(ir,idof);
2516 }
2517 }
2518
2519 switch ( fe.numRefCoor() ) { // Warning: must be as in CurvilinearFiniteElement::computeNormal()
2520 case 1:
2521 n(0) = cbasis(0,1);
2522 n(1) = - cbasis(0,0);
2523 break;
2524 case 2:
2525 n(0) = fe.m_sign * ( cbasis(0,1) * cbasis(1,2) - cbasis(0,2)*cbasis(1,1) );
2526 n(1) = fe.m_sign * ( cbasis(0,2) * cbasis(1,0) - cbasis(0,0)*cbasis(1,2) );
2527 n(2) = fe.m_sign * ( cbasis(0,0) * cbasis(1,1) - cbasis(0,1)*cbasis(1,0) );
2528 break;
2529 default:
2530 FEL_ERROR("ElementMatrix::velocityConstraint numRefCoor must be 1 or 2");
2531 }
2532
2533 // Update elementary matrix
2534 for (int ic=0; ic < fe.numCoor(); ++ic) {
2535 UBlasMatrixRange matrix1 = matBlock(ic,iblock);
2536 UBlasMatrixRange matrix2 = matBlock(iblock,ic);
2537 for(int idof=0 ; idof < fe.numDof() ; ++idof) {
2538 sum = fe.quadratureRule().weight(iq) * n(ic) * fe.phi[iq](idof);
2539 matrix1(idof,0) += coef*sum;
2540 matrix2(0,idof) += coef*sum;
2541 }
2542 }
2543 }
2544 }
2545
2546 /***********************************************************************************/
2547 /***********************************************************************************/
2548
2549 void ElementMatrix::followerPressure(const double coef, const ElementField& press, const ElementField& disp, const CurvilinearFiniteElement& fe)
2550 {
2551 FEL_CHECK(fe.hasMeas() ,"ElementMatrix::followerPressure: requires covariant basis");
2552 FEL_CHECK(disp.type() == DOF_FIELD,"ElementMatrix::followerPressure: wrong displacement field type");
2553 FEL_CHECK(press.numComp() == 1,"ElementMatrix::followerPressure: wrong pressure field");
2554
2555 const UBlasMatrix& d = disp.val;
2556
2557 UBlasMatrix cbasis(fe.numRefCoor(),fe.numCoor()); // covariant basis in current configuation
2558 UBlasVector n(fe.numCoor()); // normal std::vector, not unitary
2559 UBlasVector patq(fe.numQuadraturePoint()); // pressure at quadrature poins
2560 std::vector<UBlasMatrix> A(fe.numRefCoor());
2561 for (int ir=0; ir<fe.numRefCoor(); ++ir) {
2562 A[ir].resize(fe.numCoor(),fe.numCoor());
2563 A[ir].clear();
2564 }
2565 double tmp;
2566
2567 // evaluate pressure at quadrature points
2568 switch(press.type()) {
2569 case CONSTANT_FIELD:
2570 for(int iq=0; iq<fe.numQuadraturePoint(); ++iq)
2571 patq(iq) = press.val(0,0);
2572 break;
2573 case QUAD_POINT_FIELD:
2574 for(int iq=0; iq<fe.numQuadraturePoint(); ++iq)
2575 patq(iq) = press.val(0,iq);
2576 break;
2577 case DOF_FIELD:
2578 for(int iq=0; iq<fe.numQuadraturePoint(); ++iq) {
2579 patq(iq) = 0.;
2580 for(int idof=0; idof<fe.numDof(); ++idof)
2581 patq(iq) += fe.phi[iq](idof) * press.val(0,idof);
2582 }
2583 break;
2584 default:
2585 FEL_ERROR("this pressure element field type has not been implemented");
2586 }
2587
2588 // loop on quadrature points
2589 for (int iq=0; iq < fe.numQuadraturePoint(); ++iq) {
2590
2591 // covariant basis in current configuratgion
2592 for (int ir=0; ir < fe.numRefCoor(); ++ir) {
2593 for (int ic=0; ic <fe.numCoor(); ++ic) {
2594 cbasis(ir,ic) = fe.m_covBasis[iq](ir,ic);
2595 for(int idof=0; idof< fe.numDof(); idof++)
2596 cbasis(ir,ic) += d(ic,idof)*fe.dPhiRef(iq)(ir,idof);
2597 }
2598 }
2599
2600 switch ( fe.numRefCoor() ) {
2601 case 1:
2602 A[0](0,1) = 1;
2603 A[0](1,0) = -1;
2604 break;
2605 case 2:
2606 // - A1
2607 A[1](1,0) = cbasis(0,2);
2608 A[1](2,0) = - cbasis(0,1);
2609 A[1](0,1) = - cbasis(0,2);
2610 A[1](2,1) = cbasis(0,0);
2611 A[1](0,2) = cbasis(0,1);
2612 A[1](1,2) = - cbasis(0,0);
2613 A[1] *= fe.m_sign;
2614 // A2
2615 A[0](1,0) = - cbasis(1,2);
2616 A[0](2,0) = cbasis(1,1);
2617 A[0](0,1) = cbasis(1,2);
2618 A[0](2,1) = - cbasis(1,0);
2619 A[0](0,2) = - cbasis(1,1);
2620 A[0](1,2) = cbasis(1,0);
2621 A[0] *= fe.m_sign;
2622 break;
2623 default:
2624 FEL_ERROR("ElementMatrix::followerPressure: numRefCoor must be 1 or 2");
2625 }
2626
2627 for (int ic=0; ic < fe.numCoor(); ++ic)
2628 for (int jc=0; jc < fe.numCoor(); ++jc) {
2629 UBlasMatrixRange mat = matBlock(ic,jc);
2630 for (int ir=0; ir < fe.numRefCoor(); ++ir) {
2631 tmp = coef*patq(iq)*A[ir](ic,jc)*fe.quadratureRule().weight(iq);
2632 for(int idof=0; idof< fe.numDof(); idof++)
2633 for(int jdof=0; jdof< fe.numDof(); jdof++)
2634 mat(idof,jdof) += tmp * fe.dPhiRef(iq)(ir,jdof) * fe.phi[iq](idof);
2635 }
2636 }
2637 }
2638 }
2639
2640 /***********************************************************************************/
2641 /***********************************************************************************/
2642
2643 void ElementMatrix::psi_j_phi_i(const double coef, const CurrentFiniteElement& fePhi, const CurrentFiniteElement& fePsi, const std::size_t iblock, const std::size_t jblock,const std::size_t num)
2644 {
2645 // check that the number of integration point is the same
2646 FEL_ASSERT(fePhi.numQuadraturePoint() == fePsi.numQuadraturePoint());
2647
2648 m_tmpMat.clear();
2649 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
2650 for(int ig=0; ig<fePhi.numQuadraturePoint(); ig++) {
2651 tmpBlock += ( coef * fePhi.weightMeas(ig) ) * outer_prod(fePhi.phi[ig], fePsi.phi[ig]);
2652 }
2653
2654 for(std::size_t icoor=0; icoor<num; icoor++) {
2655 UBlasMatrixRange matrix = matBlock(iblock+icoor,jblock+icoor);
2656 matrix += tmpBlock;
2657 }
2658 }
2659
2660 /***********************************************************************************/
2661 /***********************************************************************************/
2662
2663 void ElementMatrix::psi_j_eps_phi_i_dot_vec(const double coef, const ElementField& vec, const CurrentFiniteElement& fePhi, const CurrentFiniteElement& fePsi, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
2664 {
2665 FEL_CHECK(vec.type() == CONSTANT_FIELD, "psi_j_eps_phi_i_dot_vec is not implemented for this type of vec");
2666 for(std::size_t icoor=0; icoor<num; ++icoor) {
2667 for(std::size_t jcoor=0; jcoor<num; ++jcoor) {
2668 m_tmpMat.clear();
2669 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
2670
2671 if(icoor == jcoor) {
2672 for(felInt idof=0; idof<fePhi.numDof(); ++idof)
2673 for(felInt jdof=0; jdof<fePhi.numDof(); ++jdof)
2674 for(felInt ig=0; ig<fePhi.numQuadraturePoint(); ++ig)
2675 for(felInt kcoor=0; kcoor<fePhi.numRefCoor(); ++kcoor)
2676 tmpblock(idof, jdof) += 0.5 * coef * fePhi.dPhi[ig](kcoor, idof) * vec.val(kcoor, 0) * fePsi.phi[ig](jdof) * fePhi.weightMeas(ig);
2677 }
2678
2679 for(felInt idof=0; idof<fePhi.numDof(); ++idof)
2680 for(felInt jdof=0; jdof<fePhi.numDof(); ++jdof)
2681 for(felInt ig=0; ig<fePhi.numQuadraturePoint(); ++ig)
2682 tmpblock(idof, jdof) += 0.5 * coef * fePhi.dPhi[ig](icoor, idof) * vec.val(icoor, 0) * fePsi.phi[ig](jdof) * fePhi.weightMeas(ig);
2683
2684 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + jcoor);
2685 matrix += tmpblock;
2686 }
2687 }
2688 }
2689
2690 /***********************************************************************************/
2691 /***********************************************************************************/
2692
2693 void ElementMatrix::psi_j_grad_phi_i_dot_vec(const double coef, const ElementField& vec, const CurrentFiniteElement& fePhi, const CurrentFiniteElement& fePsi, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
2694 {
2695 FEL_CHECK(vec.type() == CONSTANT_FIELD, "psi_j_grad_phi_i_dot_vec is not implemented for this type of vec");
2696
2697 m_tmpMat.clear();
2698 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
2699
2700 for(felInt idof=0; idof<fePhi.numDof(); ++idof)
2701 for(felInt jdof=0; jdof<fePhi.numDof(); ++jdof)
2702 for(felInt ig=0; ig<fePhi.numQuadraturePoint(); ++ig)
2703 for(felInt icoor=0; icoor<fePhi.numRefCoor(); ++icoor)
2704 tmpblock(idof, jdof) += coef * fePhi.dPhi[ig](icoor, idof) * vec.val(icoor, 0) * fePsi.phi[ig](jdof) * fePhi.weightMeas(ig);
2705
2706
2707 for(std::size_t icoor=0; icoor<num; icoor++) {
2708 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + icoor);
2709 matrix += tmpblock;
2710 }
2711 }
2712
2713 /***********************************************************************************/
2714 /***********************************************************************************/
2715
2716 void ElementMatrix::eps_psi_j_dot_vec_phi_i(const double coef, const ElementField& vec, const CurrentFiniteElement& fePhi, const CurrentFiniteElement& fePsi, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
2717 {
2718 FEL_CHECK(vec.type() == CONSTANT_FIELD, "eps_psi_j_dot_vec_phi_i is not implemented for this type of vec");
2719
2720 for(std::size_t icoor=0; icoor<num; ++icoor) {
2721 for(std::size_t jcoor=0; jcoor<num; ++jcoor) {
2722 m_tmpMat.clear();
2723 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
2724
2725 if(icoor == jcoor) {
2726 for(felInt idof=0; idof<fePhi.numDof(); ++idof)
2727 for(felInt jdof=0; jdof<fePsi.numDof(); ++jdof)
2728 for(felInt ig=0; ig<fePhi.numQuadraturePoint(); ++ig)
2729 for(felInt kcoor=0; kcoor<fePhi.numRefCoor(); ++kcoor)
2730 tmpblock(idof, jdof) += 0.5 * coef * fePsi.dPhi[ig](kcoor, jdof) * vec.val(kcoor, 0) * fePhi.phi[ig](idof) * fePhi.weightMeas(ig);
2731 }
2732
2733 for(felInt idof=0; idof<fePhi.numDof(); ++idof)
2734 for(felInt jdof=0; jdof<fePhi.numDof(); ++jdof)
2735 for(felInt ig=0; ig<fePhi.numQuadraturePoint(); ++ig)
2736 tmpblock(idof, jdof) += 0.5 * coef * fePsi.dPhi[ig](icoor, jdof) * vec.val(jcoor, 0) * fePhi.phi[ig](idof) * fePhi.weightMeas(ig);
2737
2738 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + jcoor);
2739 matrix += tmpblock;
2740 }
2741 }
2742 }
2743
2744 /***********************************************************************************/
2745 /***********************************************************************************/
2746
2747 void ElementMatrix::grad_psi_j_dot_vec_phi_i(const double coef, const ElementField& vec, const CurrentFiniteElement& fePhi, const CurrentFiniteElement& fePsi, const std::size_t iblock, const std::size_t jblock, const std::size_t num)
2748 {
2749 FEL_CHECK(vec.type() == CONSTANT_FIELD, "grad_psi_j_dot_vec_phi_i is not implemented for this type of vec");
2750
2751 m_tmpMat.clear();
2752 UBlasMatrixRange tmpblock = getMatBlock(m_tmpMat, iblock, jblock);
2753
2754 for(felInt idof=0; idof<fePhi.numDof(); ++idof)
2755 for(felInt jdof=0; jdof<fePsi.numDof(); ++jdof)
2756 for(felInt ig=0; ig<fePhi.numQuadraturePoint(); ++ig)
2757 for(felInt icoor=0; icoor<fePhi.numRefCoor(); ++icoor)
2758 tmpblock(idof, jdof) += coef * fePsi.dPhi[ig](icoor, jdof) * vec.val(icoor, 0) * fePhi.phi[ig](idof) * fePhi.weightMeas(ig);
2759
2760
2761 for(std::size_t icoor=0; icoor<num; icoor++) {
2762 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + icoor);
2763 matrix += tmpblock;
2764 }
2765 }
2766
2767 /***********************************************************************************/
2768 /***********************************************************************************/
2769
2770 void ElementMatrix::f_dot_n_psi_j_phi_i(const double coef, const CurrentFiniteElement& fePhi, const CurrentFiniteElement& fePsi, const ElementField& elt_f, const ElementField& elt_n, const std::size_t iblock, const std::size_t jblock, const std::size_t num, felInt stabFlag)
2771 {
2772 m_tmpMat.clear();
2773 double tmp, f_dot_n;
2774 UBlasMatrixRange tmpBlock = getMatBlock(m_tmpMat, iblock, jblock);
2775 for(int ig=0; ig<fePhi.numQuadraturePoint(); ig++) {
2776 f_dot_n = 0.;
2777 for(int icomp=0; icomp<fePhi.numCoor(); icomp++) {
2778 tmp = 0.;
2779 for(int jdof=0; jdof<fePhi.numDof(); jdof++) {
2780 tmp += fePhi.phi[ig](jdof) * elt_f.val(icomp, jdof);
2781 }
2782 f_dot_n += tmp * elt_n.val(icomp, 0);
2783 }
2784
2785 if (f_dot_n < 0 || stabFlag != 2)
2786 tmpBlock += f_dot_n * coef * fePhi.weightMeas(ig) * outer_prod(fePhi.phi[ig], fePsi.phi[ig]);
2787 }
2788
2789 for(std::size_t icoor=0; icoor<num; icoor++) {
2790 UBlasMatrixRange matrix = matBlock(iblock + icoor, jblock + icoor);
2791 matrix += tmpBlock;
2792 }
2793 }
2794
2795 /***********************************************************************************/
2796 /***********************************************************************************/
2797
2798 // phi_i is the test function
2799 void ElementMatrix::const_phi_i_dot_n(const double coeff,const CurvilinearFiniteElement& fePhi, const std::size_t iBlock, const std::size_t jBlock)
2800 {
2801 double tmp;
2802 for (int ic=0; ic<fePhi.numCoor(); ++ic) {
2803 UBlasMatrixRange matrix = matBlock(iBlock+ic,jBlock);
2804 for (int idof=0; idof<fePhi.numDof(); ++idof) {
2805 tmp = 0.;
2806 for (int iq=0; iq<fePhi.numQuadraturePoint(); ++iq)
2807 tmp += coeff * fePhi.weightMeas(iq) * fePhi.normal[iq](ic) * fePhi.phi[iq](idof);
2808
2809 matrix(idof,0) += tmp;
2810 }
2811 }
2812 }
2813
2814 // const is the test function
2815 void ElementMatrix::const_phi_j_dot_n(const double coeff,const CurvilinearFiniteElement& fePhi, const std::size_t iBlock, const std::size_t jBlock)
2816 {
2817 double tmp;
2818 for (int ic=0; ic<fePhi.numCoor(); ++ic) {
2819 UBlasMatrixRange matrix = matBlock(iBlock,jBlock+ic);
2820 for (int idof=0; idof<fePhi.numDof(); ++idof) {
2821 tmp = 0.;
2822 for (int iq=0; iq<fePhi.numQuadraturePoint(); ++iq)
2823 tmp += coeff * fePhi.weightMeas(iq) * fePhi.normal[iq](ic) * fePhi.phi[iq](idof);
2824
2825 matrix(0,idof) += tmp;
2826 }
2827 }
2828 }
2829
2830 // phi_i is the test function
2831 void ElementMatrix::const_phi_i(const double coeff, const CurvilinearFiniteElement& fePhi, const std::size_t iBlock, const std::size_t jBlock)
2832 {
2833 double tmp;
2834 UBlasMatrixRange matrix = matBlock(iBlock,jBlock);
2835 for (int idof=0; idof<fePhi.numDof(); ++idof) {
2836 tmp = 0.;
2837 for (int iq=0; iq<fePhi.numQuadraturePoint(); ++iq)
2838 tmp += coeff * fePhi.weightMeas(iq) * fePhi.phi[iq](idof);
2839
2840 matrix(idof,0) += tmp;
2841 }
2842 }
2843
2844 // const is the test function
2845 void ElementMatrix::const_phi_j(const double coeff,const CurvilinearFiniteElement& fePhi, const std::size_t iBlock, const std::size_t jBlock)
2846 {
2847 double tmp;
2848 UBlasMatrixRange matrix = matBlock(iBlock,jBlock);
2849 for (int idof=0; idof<fePhi.numDof(); ++idof) {
2850 tmp = 0.;
2851 for (int iq=0; iq<fePhi.numQuadraturePoint(); ++iq)
2852 tmp += coeff * fePhi.weightMeas(iq) * fePhi.phi[iq](idof);
2853
2854 matrix(0,idof) += tmp;
2855 }
2856 }
2857
2858
2859 }
2860