GCC Code Coverage Report


Directory: ./
File: FiniteElement/currentFiniteElement.cpp
Date: 2024-04-14 07:32:34
Exec Total Coverage
Lines: 156 295 52.9%
Branches: 103 365 28.2%

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-F. Gerbeau
13 //
14
15 // System includes
16 #include <cmath>
17
18 // External includes
19
20 // Project includes
21 #include "FiniteElement/currentFiniteElement.hpp"
22 #include "Tools/math_utilities.hpp"
23
24 namespace felisce
25 {
26 53102 CurrentFiniteElement::CurrentFiniteElement(
27 const RefElement& refEle,
28 const GeoElement& geoEle,
29 const std::vector<DegreeOfExactness>& degOfExactness
30 53102 ) : CurBaseFiniteElement(refEle, geoEle, degOfExactness)
31 {
32
1/2
✓ Branch 1 taken 53102 times.
✗ Branch 2 not taken.
53102 dPhi.resize(m_numQuadraturePoint);
33
1/2
✓ Branch 1 taken 53102 times.
✗ Branch 2 not taken.
53102 m_jacobian.resize(m_numQuadraturePoint);
34
35
1/2
✓ Branch 1 taken 53102 times.
✗ Branch 2 not taken.
53102 m_indexQuadPoint.resize(2);
36 53102 m_indexQuadPoint[0] = 0;
37 53102 m_indexQuadPoint[1] = m_numQuadraturePoint;
38
39
2/2
✓ Branch 2 taken 233314 times.
✓ Branch 3 taken 53102 times.
286416 for(int ig=m_indexQuadPoint[0]; ig<m_indexQuadPoint[1]; ig++) {
40
1/2
✓ Branch 2 taken 233314 times.
✗ Branch 3 not taken.
233314 m_jacobian[ig].resize(m_numCoor,m_numCoor);
41
1/2
✓ Branch 2 taken 233314 times.
✗ Branch 3 not taken.
233314 dPhi[ig].resize(m_numRefCoor,m_numDof);
42 }
43 53102 }
44
45 /***********************************************************************************/
46 /***********************************************************************************/
47
48 13976 CurrentFiniteElement::CurrentFiniteElement(
49 const RefElement& refEle,
50 const GeoElement& geoEle,
51 const DegreeOfExactness& degOfExactness
52
2/4
✓ Branch 2 taken 13976 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13976 times.
✗ Branch 6 not taken.
13976 ) : CurrentFiniteElement(refEle, geoEle, std::vector<DegreeOfExactness>(1, degOfExactness))
53 {
54 13976 }
55
56 /***********************************************************************************/
57 /***********************************************************************************/
58
59 205972 CurrentFiniteElement::~CurrentFiniteElement()
60 {
61 138806 m_jacobian.clear();
62 138806 dPhi.clear();
63 205972 }
64
65 /***********************************************************************************/
66 /***********************************************************************************/
67
68 void CurrentFiniteElement::allocateOnDofsDataStructures()
69 {
70 //Experimental..it has been tested ONLY on P1 tetra, but it should be more general (matteo)
71 m_dPhiRefOnDofs.resize(m_numDof);
72 m_phiGeoOnDofs.resize(m_numDof);
73 m_dPhiGeoOnDofs.resize(m_numDof);
74 dPhiOnDofs.resize(m_numDof);
75 phiOnDofs.resize(m_numDof);
76 m_jacobianOnDofs.resize(m_numDof);
77 for ( int idof(0); idof<m_numDof; idof++ ) {
78 m_dPhiRefOnDofs[idof].resize(m_numRefCoor,m_numDof);
79 m_phiGeoOnDofs[idof].resize(m_numPoint);
80 m_dPhiGeoOnDofs[idof].resize(m_numRefCoor,m_numPoint);
81 phiOnDofs[idof].resize(m_numDof);
82 dPhiOnDofs[idof].resize(m_numRefCoor,m_numDof);
83 m_jacobianOnDofs[idof].resize(m_numCoor,m_numCoor);
84
85 QuadraturePoint point(0.,0.,0.,0.);
86 for (int pcoor=0; pcoor<m_numRefCoor; pcoor++ ) {
87 point.coor(pcoor)=m_refEle.nodeCoor(idof,pcoor);
88 }
89 for(int i=0; i<m_numDof; i++ ) {
90 phiOnDofs[idof](i) = m_refEle.basisFunction().phi(i, point);
91 for(int icoor=0; icoor<m_numRefCoor; icoor++ ) {
92 m_dPhiRefOnDofs[idof](icoor,i) = m_refEle.basisFunction().dPhi(i,icoor, point);
93 }
94 }
95 for(int k=0; k<m_numPoint; k++) {
96 m_phiGeoOnDofs[idof](k)= m_geoEle.basisFunction().phi(k, point);
97 for(int icoor=0; icoor<m_numRefCoor; icoor++) {
98 m_dPhiGeoOnDofs[idof](icoor,k) = m_geoEle.basisFunction().dPhi(k,icoor, point);
99 }
100 }
101 }
102 m_phiDPhiOnDofs=true;
103 }
104
105 /***********************************************************************************/
106 /***********************************************************************************/
107
108 42102782 void CurrentFiniteElement::computeJacobian(const int iBlockBd,const std::size_t numBlockBd)
109 {
110
3/6
✓ Branch 0 taken 42102782 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 42102782 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 42102782 times.
42102782 FEL_ASSERT( numBlockBd > 0 && numBlockBd < m_indexQuadPoint.size() );
111 // derivatives of geo map:
112
2/2
✓ Branch 2 taken 208082119 times.
✓ Branch 3 taken 42102782 times.
250184901 for ( int ig = m_indexQuadPoint[iBlockBd]; ig <m_indexQuadPoint[iBlockBd+numBlockBd]; ig++) {
113
1/2
✓ Branch 4 taken 208082119 times.
✗ Branch 5 not taken.
208082119 m_jacobian[ig] = prod(m_dPhiGeo[ig],m_point);
114 }
115 42102782 }
116
117 /***********************************************************************************/
118 /***********************************************************************************/
119
120 void CurrentFiniteElement::computeJacobianOnDofs()
121 {
122 // derivatives of geo map:
123 for ( int idof(0); idof<m_numDof; ++idof) {
124 m_jacobianOnDofs[idof] = prod(m_dPhiGeoOnDofs[idof],m_point);
125 }
126 }
127
128 /***********************************************************************************/
129 /***********************************************************************************/
130
131 130177 void CurrentFiniteElement::computeMeas()
132 {
133
2/2
✓ Branch 0 taken 722153 times.
✓ Branch 1 taken 130177 times.
852330 for (int ig = 0; ig <m_numQuadraturePoint; ig++) {
134 722153 m_meas(ig) = MathUtilities::Det(m_jacobian[ig]);
135 722153 weightMeas(ig) = m_meas(ig) * m_quadratureRule->weight(ig);
136 }
137 130177 }
138
139 /***********************************************************************************/
140 /***********************************************************************************/
141
142 41955997 void CurrentFiniteElement::computeMeasDer(const int iBlockBd,const std::size_t numBlockBd)
143 {
144
3/6
✓ Branch 0 taken 41955997 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 41955997 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 41955997 times.
41955997 FEL_ASSERT( numBlockBd > 0 && numBlockBd < m_indexQuadPoint.size() );
145
1/2
✓ Branch 1 taken 41955997 times.
✗ Branch 2 not taken.
41955997 UBlasMatrix inv_jacobian(m_numCoor,m_numCoor);
146 double det;
147
2/2
✓ Branch 2 taken 207310142 times.
✓ Branch 3 taken 41955997 times.
249266139 for (int ig = m_indexQuadPoint[iBlockBd]; ig <m_indexQuadPoint[iBlockBd+numBlockBd]; ig++) {
148
1/2
✓ Branch 2 taken 207310142 times.
✗ Branch 3 not taken.
207310142 MathUtilities::InvertMatrix(m_jacobian[ig], inv_jacobian, det);
149 //! on internal quad points only (boundary quad pts are set from CurvilinearFE):
150
3/4
✓ Branch 0 taken 207310142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 196054166 times.
✓ Branch 3 taken 11255976 times.
207310142 if ( ig >=0 && ig < m_numQuadraturePoint ) {
151
1/2
✓ Branch 1 taken 196054166 times.
✗ Branch 2 not taken.
196054166 m_meas(ig) = det;
152
3/6
✓ Branch 1 taken 196054166 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 196054166 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 196054166 times.
✗ Branch 8 not taken.
196054166 weightMeas(ig) = m_meas(ig) * m_quadratureRule->weight(ig);
153 }
154
3/6
✓ Branch 2 taken 207310142 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 207310142 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 207310142 times.
✗ Branch 10 not taken.
207310142 noalias(dPhi[ig]) = prod(inv_jacobian, m_dPhiRef[ig]);
155 }
156 41955997 }
157
158 /***********************************************************************************/
159 /***********************************************************************************/
160
161 void CurrentFiniteElement::computeDerOnDofs()
162 {
163 UBlasMatrix inv_jacobian(m_numCoor,m_numCoor);
164 double det;
165 for (int idof(0); idof<m_numDof; ++idof) {
166 MathUtilities::InvertMatrix(m_jacobianOnDofs[idof], inv_jacobian, det);
167 noalias(dPhiOnDofs[idof]) = prod(inv_jacobian, dPhiOnDofs[idof]);
168 }
169 }
170
171 /***********************************************************************************/
172 /***********************************************************************************/
173
174 16608 void CurrentFiniteElement::computePiolaMeasDer(const int iBlockBd,const std::size_t numBlockBd, const std::vector<double>& normal)
175 {
176
3/6
✓ Branch 0 taken 16608 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 16608 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 16608 times.
16608 FEL_ASSERT( numBlockBd > 0 && numBlockBd < m_indexQuadPoint.size() );
177
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 16608 times.
16608 FEL_ASSERT( (felInt)normal.size() == m_numCoor);
178
179
1/2
✓ Branch 1 taken 16608 times.
✗ Branch 2 not taken.
16608 UBlasMatrix inv_jacobian(m_numCoor,m_numCoor);
180
1/2
✓ Branch 1 taken 16608 times.
✗ Branch 2 not taken.
16608 UBlasVector meas(m_numCoor);
181 double det;
182
183
2/2
✓ Branch 2 taken 49824 times.
✓ Branch 3 taken 16608 times.
66432 for (int ig = m_indexQuadPoint[iBlockBd]; ig <m_indexQuadPoint[iBlockBd+numBlockBd]; ig++) {
184
2/2
✓ Branch 0 taken 99648 times.
✓ Branch 1 taken 49824 times.
149472 for(felInt i=0; i<m_numCoor; ++i)
185
1/2
✓ Branch 2 taken 99648 times.
✗ Branch 3 not taken.
99648 meas(i) = normal[i];
186
187
1/2
✓ Branch 2 taken 49824 times.
✗ Branch 3 not taken.
49824 MathUtilities::InvertMatrix(m_jacobian[ig], inv_jacobian, det);
188
3/6
✓ Branch 2 taken 49824 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 49824 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 49824 times.
✗ Branch 10 not taken.
49824 noalias(dPhi[ig]) = prod(inv_jacobian, m_dPhiRef[ig]);
189
190
2/4
✓ Branch 0 taken 49824 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49824 times.
✗ Branch 3 not taken.
49824 if ( ig >=0 && ig < m_numQuadraturePoint )
191
1/2
✓ Branch 1 taken 49824 times.
✗ Branch 2 not taken.
49824 m_meas(ig) = det;
192
193 // Now, the norm of the inverse of the transpose of the jacobian times the normal vector
194
2/4
✓ Branch 1 taken 49824 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49824 times.
✗ Branch 5 not taken.
49824 meas = prod(inv_jacobian, meas);
195
196 //! On internal quad points only (boundary quad pts are set from CurvilinearFE):
197
2/4
✓ Branch 0 taken 49824 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49824 times.
✗ Branch 3 not taken.
49824 if ( ig >=0 && ig < m_numQuadraturePoint ) {
198
2/4
✓ Branch 1 taken 49824 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49824 times.
✗ Branch 5 not taken.
49824 m_meas(ig) *= norm_2(meas);
199
3/6
✓ Branch 1 taken 49824 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49824 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 49824 times.
✗ Branch 8 not taken.
49824 weightMeas(ig) = m_meas(ig) * m_quadratureRule->weight(ig);
200 }
201 }
202 16608 }
203
204 /***********************************************************************************/
205 /***********************************************************************************/
206
207 4583540 void CurrentFiniteElement::update(const int id,const std::vector<Point*>& point)
208 {
209 4583540 updatePoint(point);
210 4583540 m_hasMeas = false;
211 4583540 m_hasFirstDeriv = false;
212 4583540 m_hasSecondDeriv = false;
213 4583540 m_hasQuadPtCoor = false;
214 4583540 m_currentId = id;
215 4583540 }
216
217 /***********************************************************************************/
218 /***********************************************************************************/
219
220 110481 void CurrentFiniteElement::updateMeas(const int id,const std::vector<Point*>& point)
221 {
222 110481 updatePoint(point);
223 110481 m_hasMeas = true;
224 110481 m_hasFirstDeriv = false;
225 110481 m_hasSecondDeriv = false;
226 110481 m_hasQuadPtCoor = false;
227 110481 m_currentId = id;
228 110481 computeJacobian(0,m_indexQuadPoint.size()-1); // on all quad points
229 110481 computeMeas();
230 110481 }
231
232 /***********************************************************************************/
233 /***********************************************************************************/
234
235 19696 void CurrentFiniteElement::updateMeasQuadPt(const int id,const std::vector<Point*>& point)
236 {
237 19696 updatePoint(point);
238 19696 m_hasMeas = true;
239 19696 m_hasFirstDeriv = false;
240 19696 m_hasSecondDeriv = false;
241 19696 m_hasQuadPtCoor = false; // std::set to "true" in computeCurrentQuadraturePoint()
242 19696 m_currentId = id;
243 19696 computeJacobian(0,m_indexQuadPoint.size()-1); // on all quad points
244 19696 computeMeas();
245 19696 computeCurrentQuadraturePoint();
246 19696 }
247
248 /***********************************************************************************/
249 /***********************************************************************************/
250
251 41941773 void CurrentFiniteElement::updateFirstDeriv(const int id,const std::vector<Point*>& point)
252 {
253 41941773 updatePoint(point);
254 41941773 m_hasMeas = true;
255 41941773 m_hasFirstDeriv = true;
256 41941773 m_hasSecondDeriv = false;
257 41941773 m_hasQuadPtCoor = false;
258 41941773 m_currentId = id;
259 41941773 computeJacobian(0,m_indexQuadPoint.size()-1); // on all quad points
260 41941773 computeMeasDer(0,m_indexQuadPoint.size()-1);
261 41941773 }
262
263 /***********************************************************************************/
264 /***********************************************************************************/
265
266 void CurrentFiniteElement::updateFirstDerivOnDofs(const int id,const std::vector<Point*>& point)
267 {
268 updateFirstDeriv(id,point);
269 if ( m_phiDPhiOnDofs == false ) {
270 FEL_ERROR("Error: you should call allocateOnDofsDataStructures");
271 }
272 computeJacobianOnDofs();
273 computeDerOnDofs();
274 }
275
276 /***********************************************************************************/
277 /***********************************************************************************/
278
279 2720 void CurrentFiniteElement::updateBasisAndFirstDeriv(const int id, const std::vector<Point*>& point) {
280
1/2
✓ Branch 1 taken 2720 times.
✗ Branch 2 not taken.
2720 updatePoint(point);
281 2720 m_hasMeas = true;
282 2720 m_hasFirstDeriv = true;
283 2720 m_hasSecondDeriv = false;
284 2720 m_hasQuadPtCoor = false;
285 2720 m_hasOriginalQuadPoint = true;
286 2720 m_currentId = id;
287
288
1/2
✓ Branch 2 taken 2720 times.
✗ Branch 3 not taken.
2720 std::vector<Point> pts(m_numQuadraturePoint);
289
2/2
✓ Branch 0 taken 8160 times.
✓ Branch 1 taken 2720 times.
10880 for(felInt ipt=0; ipt<m_numQuadraturePoint; ++ipt)
290
1/2
✓ Branch 1 taken 8160 times.
✗ Branch 2 not taken.
8160 pts[ipt] = m_quadratureRule->quadraturePoint(ipt);
291
292 // recompute the basis function at the original quadrature point
293
1/2
✓ Branch 1 taken 2720 times.
✗ Branch 2 not taken.
2720 updateBasisWithQuadPoint(pts);
294
295 // first deriv
296
1/2
✓ Branch 2 taken 2720 times.
✗ Branch 3 not taken.
2720 computeJacobian(0, m_indexQuadPoint.size()-1);
297
298
1/2
✓ Branch 2 taken 2720 times.
✗ Branch 3 not taken.
2720 computeMeasDer(0, m_indexQuadPoint.size()-1);
299 2720 }
300
301 /***********************************************************************************/
302 /***********************************************************************************/
303
304 28112 void CurrentFiniteElement::updateSubElementFirstDeriv(const int id, const std::vector<Point*>& ptElem, const std::vector<Point*>& ptSubElem, CurBaseFiniteElement* feSurf)
305 {
306
1/2
✓ Branch 1 taken 28112 times.
✗ Branch 2 not taken.
28112 updatePoint(ptElem);
307 28112 m_hasMeas = true;
308 28112 m_hasFirstDeriv = true;
309 28112 m_hasSecondDeriv = false;
310 28112 m_hasQuadPtCoor = false;
311 28112 m_hasOriginalQuadPoint = false;
312 28112 m_currentId = id;
313
314 // find the coordinate of the sub element in the reference element of the element
315
1/2
✓ Branch 3 taken 28112 times.
✗ Branch 4 not taken.
28112 std::vector<Point*> ptSubRef(ptSubElem.size());
316
1/5
✗ Branch 2 not taken.
✓ Branch 3 taken 28112 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
28112 switch(m_geoEle.shape().typeShape()) {
317
318 case Quadrilateral: {
319 // square
320 for(std::size_t ipt=0; ipt<ptSubElem.size(); ++ipt) {
321 ptSubRef[ipt] = new Point();
322 ptSubRef[ipt]->x() = 2.*(ptSubElem[ipt]->x() - ptElem[0]->x())/(ptElem[2]->x() - ptElem[0]->x()) - 1.;
323 ptSubRef[ipt]->y() = 2.*(ptSubElem[ipt]->y() - ptElem[0]->y())/(ptElem[2]->y() - ptElem[0]->y()) - 1.;
324 }
325 break;
326 }
327
328 28112 case Triangle: {
329 // triangle
330 // this value can not be equal to zero unless the triangle is flat.
331 28112 const double det = (ptElem[2]->y() - ptElem[0]->y())*(ptElem[1]->x() - ptElem[0]->x())
332 28112 - (ptElem[2]->x() - ptElem[0]->x())*(ptElem[1]->y() - ptElem[0]->y());
333
334
2/2
✓ Branch 1 taken 67728 times.
✓ Branch 2 taken 28112 times.
95840 for(std::size_t ipt=0; ipt<ptSubElem.size(); ++ipt) {
335
1/2
✓ Branch 1 taken 67728 times.
✗ Branch 2 not taken.
135456 ptSubRef[ipt] = new Point();
336
337 135456 ptSubRef[ipt]->x() = (ptElem[2]->y() - ptElem[0]->y())*(ptSubElem[ipt]->x() - ptElem[0]->x())/det
338 67728 + (ptElem[0]->x() - ptElem[2]->x())*(ptSubElem[ipt]->y() - ptElem[0]->y())/det;
339
340 135456 ptSubRef[ipt]->y() = (ptElem[0]->y() - ptElem[1]->y())*(ptSubElem[ipt]->x() - ptElem[0]->x())/det
341 67728 + (ptElem[1]->x() - ptElem[0]->x())*(ptSubElem[ipt]->y() - ptElem[0]->y())/det;
342 }
343 28112 break;
344 }
345
346 case Tetrahedron: {
347 // coordinates of the subElement in the reference Tetrahedra
348 // inversion of the map matrix
349 //std::cout << " Vertex Current Elem K: ";
350 //for( int it=0; it<ptElem.size(); ++it){
351 // ptElem[it]->print(10,std::cout);
352 // std::cout<<std::endl;
353 //}
354 //std::cout << " Vertex Current SubElem K_i: ";
355 //for( int it=0; it<ptSubElem.size(); ++it){
356 // ptSubElem[it]->print(10,std::cout);
357 // std::cout<<std::endl;
358 //}
359
360 UBlasMatrix FLU(m_numCoor,m_numCoor);
361 UBlasMatrix inv_FLU(m_numCoor,m_numCoor);
362 UBlasVector refPoint(m_numCoor);
363 double det;
364
365 // Filling the matrix
366 for(int indx = 0; indx < m_numCoor ; ++indx){
367 FLU(0,indx) = ptElem[indx+1]->x() - ptElem[0]->x();
368 FLU(1,indx) = ptElem[indx+1]->y() - ptElem[0]->y();
369 FLU(2,indx) = ptElem[indx+1]->z() - ptElem[0]->z();
370 }
371
372 MathUtilities::InvertMatrix(FLU, inv_FLU, det);
373
374 for(std::size_t ipt=0; ipt<ptSubElem.size(); ++ipt) {
375 // Filling the rhs
376 refPoint[0] = ptSubElem[ipt]->x() - ptElem[0]->x();
377 refPoint[1] = ptSubElem[ipt]->y() - ptElem[0]->y();
378 refPoint[2] = ptSubElem[ipt]->z() - ptElem[0]->z();
379
380 refPoint = prod(inv_FLU,refPoint);
381
382 ptSubRef[ipt] = new Point();
383 ptSubRef[ipt]->x() = refPoint[0];
384 ptSubRef[ipt]->y() = refPoint[1];
385 ptSubRef[ipt]->z() = refPoint[2];
386 }
387
388 break;
389 }
390
391 case NullShape:
392 case Node:
393 case Segment:
394 case Hexahedron:
395 case Prism:
396 case Pyramid: {
397 FEL_ERROR("The transformation is not implemented for this type of mesh cells");
398 break;
399 }
400 }
401
402 // create the current finite element for the sub element and update it
403 CurBaseFiniteElement* feSubElt;
404
2/2
✓ Branch 0 taken 11504 times.
✓ Branch 1 taken 16608 times.
28112 if(feSurf == nullptr) {
405 // volume sub elem
406
2/4
✓ Branch 2 taken 11504 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 11504 times.
✗ Branch 6 not taken.
11504 feSubElt = new CurrentFiniteElement(m_refEle, m_geoEle, (DegreeOfExactness) m_quadratureRule->degreeOfExactness());
407
1/2
✓ Branch 1 taken 11504 times.
✗ Branch 2 not taken.
11504 ((CurrentFiniteElement*) feSubElt)->updateMeasQuadPt(id, ptSubRef);
408 } else {
409 // curvi sub elem
410
2/4
✓ Branch 5 taken 16608 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 16608 times.
✗ Branch 9 not taken.
16608 feSubElt = new CurvilinearFiniteElement(feSurf->refEle(), feSurf->geoEle(), (DegreeOfExactness) feSurf->quadratureRule().degreeOfExactness());
411
1/2
✓ Branch 1 taken 16608 times.
✗ Branch 2 not taken.
16608 ((CurvilinearFiniteElement*) feSubElt)->updateMeasQuadPt(id, ptSubRef);
412 }
413
414 // recompute the basis function at the new quadrature points for the element
415
1/2
✓ Branch 1 taken 28112 times.
✗ Branch 2 not taken.
28112 updateBasisWithQuadPoint(feSubElt->currentQuadPoint);
416
417 // update the derivatives for the element (no need to recompute the jacobian, it's
418 // a constant if the mapping from the reference element to the current element is affine)
419
1/2
✓ Branch 2 taken 28112 times.
✗ Branch 3 not taken.
28112 computeJacobian(0, m_indexQuadPoint.size()-1);
420
421
2/2
✓ Branch 0 taken 11504 times.
✓ Branch 1 taken 16608 times.
28112 if(feSurf == nullptr){
422
423
1/2
✓ Branch 2 taken 11504 times.
✗ Branch 3 not taken.
11504 computeMeasDer(0, m_indexQuadPoint.size()-1);
424 }
425 else {
426
1/2
✓ Branch 2 taken 16608 times.
✗ Branch 3 not taken.
16608 std::vector<double> normal(m_numCoor);
427 double norm;
428
1/2
✓ Branch 0 taken 16608 times.
✗ Branch 1 not taken.
16608 if(m_numCoor == 2) {
429 16608 normal[0] = ptSubRef[0]->y() - ptSubRef[1]->y();
430 16608 normal[1] = ptSubRef[1]->x() - ptSubRef[0]->x();
431 16608 norm = std::sqrt(normal[0]*normal[0] + normal[1]*normal[1]);
432 16608 normal[0] /= norm;
433 16608 normal[1] /= norm;
434 } else {
435 // normal in 3d
436 normal[0] = (ptSubRef[1]->y() - ptSubRef[0]->y())*(ptSubRef[2]->z() - ptSubRef[0]->z()) - ((ptSubRef[1]->z() - ptSubRef[0]->z())*(ptSubRef[2]->y() - ptSubRef[0]->y()));
437 normal[1] = (ptSubRef[1]->z() - ptSubRef[0]->z())*(ptSubRef[2]->x() - ptSubRef[0]->x()) - ((ptSubRef[1]->x() - ptSubRef[0]->x())*(ptSubRef[2]->z() - ptSubRef[0]->z()));
438 normal[2] = (ptSubRef[1]->x() - ptSubRef[0]->x())*(ptSubRef[2]->y() - ptSubRef[0]->y()) - ((ptSubRef[2]->x() - ptSubRef[0]->x())*(ptSubRef[1]->y() - ptSubRef[0]->y()));
439 norm = std::sqrt(normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2]);
440 normal[0] /= norm;
441 normal[1] /= norm;
442 normal[2] /= norm;
443 }
444
445
1/2
✓ Branch 2 taken 16608 times.
✗ Branch 3 not taken.
16608 computePiolaMeasDer(0, m_indexQuadPoint.size()-1, normal);
446 16608 }
447
448 // change the weight of the quadrature point
449
2/2
✓ Branch 1 taken 67728 times.
✓ Branch 2 taken 28112 times.
95840 for(int ig=0; ig<feSubElt->numQuadraturePoint(); ++ig) {
450
3/6
✓ Branch 1 taken 67728 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 67728 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 67728 times.
✗ Branch 8 not taken.
67728 weightMeas(ig) = m_meas(ig) * feSubElt->weightMeas(ig);
451 }
452
2/2
✓ Branch 1 taken 16608 times.
✓ Branch 2 taken 28112 times.
44720 for(int ig=feSubElt->numQuadraturePoint(); ig<m_numQuadraturePoint; ++ig) {
453
1/2
✓ Branch 1 taken 16608 times.
✗ Branch 2 not taken.
16608 weightMeas(ig) = 0.;
454 }
455
456 // delete
457
2/2
✓ Branch 1 taken 67728 times.
✓ Branch 2 taken 28112 times.
95840 for(std::size_t ipt=0; ipt<ptSubRef.size(); ++ipt)
458
1/2
✓ Branch 1 taken 67728 times.
✗ Branch 2 not taken.
67728 delete ptSubRef[ipt];
459 28112 ptSubRef.clear();
460
461
1/2
✓ Branch 0 taken 28112 times.
✗ Branch 1 not taken.
28112 delete feSubElt;
462 28112 }
463
464 /***********************************************************************************/
465 /***********************************************************************************/
466
467 void CurrentFiniteElement::identifyLocBDDof(const CurvilinearFiniteElement& curvFe, std::vector<int>& map) const
468 {
469 // This function compare the point supporting dofs of a curvilinear finite element,
470 // with the point supporting dofs of "this" a current finite element.
471 // the return value "std::unordered_map" connects the local ids of the dofs on the curvFe to the loc ids of the dofs
472 // on the currentFiniteElement.
473 // You probably do not want to use this function and you would like to use the currentFiniteElementWithBD
474 // Which does similar things in a better way.
475 map.resize(curvFe.numDof());
476 Point p,pref,pv,pvref;
477 for (int iBD(0); iBD<curvFe.numDof();iBD++){
478 map[iBD]=-1;
479 for (int pcoor=0; pcoor<m_numRefCoor-1; pcoor++ ) {
480 pref.coor(pcoor)=curvFe.refEle().nodeCoor(iBD,pcoor);
481 }
482 curvFe.coorMap(p,pref);
483 for (int iV(0); iV<this->numDof();iV++){
484 for (int pcoor=0; pcoor<m_numRefCoor; pcoor++ ) {
485 pvref.coor(pcoor)=m_refEle.nodeCoor(iV,pcoor);
486 }
487 coorMap(pv,pvref);
488 if ( p == pv ) {
489 map[iBD]=iV;
490 }
491 }
492 if (map[iBD]==-1) {
493 FEL_ERROR("err");
494 }
495 }
496 }
497
498 /***********************************************************************************/
499 /***********************************************************************************/
500
501 void CurrentFiniteElement::print(int verbose,std::ostream& c) const
502 {
503 if(verbose) {
504 c << "CurrentFiniteElement: " << "\n";
505 m_printBase(verbose, c);
506 int theNumQuadPointTotal = m_indexQuadPoint.back();
507 if ( theNumQuadPointTotal != m_numQuadraturePoint ) {
508 c << " numQuadPoint: " << m_numQuadraturePoint << "\n";
509 c << " numQuadPointTotal(intern+boundary): " << theNumQuadPointTotal << "\n";
510 }
511
512 if( m_hasPoint && verbose > 1 ) c << " point = " << m_point << "\n";
513 if( m_hasMeas && verbose > 1 ) c << " meas = " << measure() << "\n";
514 if( verbose > 2 ) {
515 if ( theNumQuadPointTotal != m_numQuadraturePoint ) {
516 c << " The numQuadPoint=" << m_numQuadraturePoint << " first are internal. The others live on the boundary elements of the element.\n";
517 }
518 for (int ig = 0; ig <theNumQuadPointTotal; ig++ ) {
519 c << " phi[ig=" <<ig<< "] = " << phi[ig] << "\n";
520 }
521 }
522 if( verbose > 2 ) {
523 for (int ig = 0; ig <theNumQuadPointTotal; ig++ ) {
524 c << " phiGeo[ig=" <<ig<< "] = " << m_phiGeo[ig] << "\n";
525 }
526 }
527 if( m_hasFirstDeriv && verbose > 2 ) {
528 for (int ig = 0; ig <theNumQuadPointTotal; ig++ ) {
529 c << " dphi[ig=" <<ig<< "] = " << dPhi[ig] << "\n";
530 }
531 }
532 if( verbose > 2 ) {
533 for (int ig = 0; ig <theNumQuadPointTotal; ig++ ) {
534 c << " dphiGeo[ig=" <<ig<< "] = " << m_dPhiGeo[ig] << "\n";
535 }
536 }
537 if( verbose > 2 ) {
538 for (int ig = 0; ig <theNumQuadPointTotal; ig++ ) {
539 c << " dphiRef[ig=" <<ig<< "] = " << m_dPhiRef[ig] << "\n";
540 }
541 }
542 if( m_hasFirstDeriv && verbose > 2 ) {
543 for (int ig = 0; ig <theNumQuadPointTotal; ig++ ) {
544 c << " jacobian[ig=" <<ig<< "] = " << m_jacobian[ig] << "\n";
545 }
546 }
547 if( m_hasQuadPtCoor && verbose > 2 ) {
548 for (int ig = 0; ig <theNumQuadPointTotal; ig++ ) {
549 c << " currentQuadPoint[ig=" <<ig<< "] : ";
550 currentQuadPoint[ig].print(verbose,c);
551 }
552 }
553 if( m_phiDPhiOnDofs && verbose > 2 ) {
554 for (int idof = 0; idof <m_numDof; idof++ ) {
555 c << " phiOnDofs[idof=" <<idof<< "] : "<<phiOnDofs[idof]<<std::endl;
556 }
557 for (int idof = 0; idof <m_numDof; idof++ ) {
558 c << " dPhiOnDofs[idof=" <<idof<< "] : "<<dPhiOnDofs[idof]<<std::endl;
559 }
560 for (int idof = 0; idof <m_numDof; idof++ ) {
561 c << " jacobianOnDodfs[idof=" <<idof<< "] : "<<m_jacobianOnDofs[idof]<<std::endl;
562 }
563 for (int idof = 0; idof <m_numDof; idof++ ) {
564 c << " phiGeoOnDofs[idof=" <<idof<< "] : "<<m_phiGeoOnDofs[idof]<<std::endl;
565 }
566 for (int idof = 0; idof <m_numDof; idof++ ) {
567 c << " dPhiGeoOnDofs[idof=" <<idof<< "] : "<<m_dPhiGeoOnDofs[idof]<<std::endl;
568 }
569 for (int idof = 0; idof <m_numDof; idof++ ) {
570 c << " dPhiRefOnDofs[idof=" <<idof<< "] : "<<m_dPhiRefOnDofs[idof]<<std::endl;
571 }
572 }
573 if ( verbose > 3) {
574 m_quadratureRule->print(verbose);
575 }
576 std::cout << std::endl;
577 }
578 }
579 }
580