GCC Code Coverage Report


Directory: ./
File: Model/FSINitscheXFEMModel.hxx
Date: 2024-04-14 07:32:34
Exec Total Coverage
Lines: 393 624 63.0%
Branches: 238 546 43.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: B. Fabreges and M. A. Fernandez
13 //
14
15 // System includes
16
17 // External includes
18
19 // Project includes
20 #include "Geometry/geometricMeshRegion.hpp"
21
22 namespace felisce {
23 template<class SolidPrb>
24
2/4
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
2 FSINitscheXFEMModel<SolidPrb>::FSINitscheXFEMModel():Model()
25 {
26
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 m_name = "Nitsche XFEM FSI Model";
27 2 m_isParFluidVelAllocated = false;
28 2 m_isTimeSchemeFluidExtrapolAllocated = false;
29 2 m_isStructureVelAllocated = false;
30 2 m_isStructureVelOldAllocated = false;
31 2 m_isStructureVelOldOldAllocated = false;
32 2 m_isStructureVelOldStoppingCriteriaAllocated = false;
33 2 m_isStructureVelExtrapolAllocated = false;
34 2 m_isSeqStructureTimeRHSAllocated = false;
35 2 m_isSeqStructureVelExtrapolAllocated = false;
36 2 m_isStructureDispAllocated = false;
37 2 m_isStructureDispOldAllocated = false;
38 2 m_isStopVecAllocated = false;
39 2 m_isStructureNitscheRHSTermsOldAllocated = false;
40 2 m_isStructureTimeSchemeRHSTermsAllocated = false;
41 2 m_isStructureExtrapolatedNitscheTermsRHSAllocated = false;
42
43 2 m_elemFieldTimeSchemeType = NULL;
44 2 m_timeSchemeType = 3;
45 2 m_subIteration = 1;
46 2 m_stoppingCriteriaTol = 1e-3;
47 2 m_timeSchemeExtrapolOrder = 0;
48 2 m_indexTime = 0;
49 2 m_countToInitOldObjects = 0;
50 2 m_reinitializeFluidBdf = false;
51 2 m_feStruc = NULL;
52 2 m_feVel = NULL;
53 2 m_fePre = NULL;
54
55 2 m_RNExtrapolOrder = 0;
56 2 m_numStrucComp = 0;
57 2 }
58
59 template<class SolidPrb>
60 4 FSINitscheXFEMModel<SolidPrb>::~FSINitscheXFEMModel()
61 {
62 4 if(m_isParFluidVelAllocated) {
63
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
8 for(std::size_t i=0; i<m_parFluidVel.size(); ++i)
64 4 m_parFluidVel[i].destroy();
65 4 m_parFluidVel.clear();
66 }
67
68
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if(m_isStructureVelAllocated)
69 4 m_structureVel.destroy();
70
71
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if(m_isStructureVelOldAllocated)
72 4 m_structureVelOld.destroy();
73
74
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if(m_isStructureVelOldOldAllocated)
75 4 m_structureVelOldOld.destroy();
76
77
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
4 if(m_isStructureVelOldStoppingCriteriaAllocated)
78 m_structureVelOldStoppingCriteria.destroy();
79
80
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if(m_isStructureVelExtrapolAllocated)
81 4 m_structureVelExtrapol.destroy();
82
83
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if(m_isSeqStructureTimeRHSAllocated)
84 4 m_seqStructureTimeRHS.destroy();
85
86
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if(m_isSeqStructureVelExtrapolAllocated)
87 4 m_seqStructureVelExtrapol.destroy();
88
89
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if(m_isStructureDispOldAllocated)
90 4 m_structureDispOld.destroy();
91
92
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
4 if(m_isStructureNitscheRHSTermsOldAllocated)
93 m_structureNitscheRHSTermsOld.destroy();
94
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
4 if(m_isStructureTimeSchemeRHSTermsAllocated)
96 m_structureTimeSchemeRHSTerms.destroy();
97
98
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
4 if(m_isStructureExtrapolatedNitscheTermsRHSAllocated)
99 m_structureExtrapolatedNitscheTermsRHS.destroy();
100
101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
4 if(m_isStopVecAllocated)
102 m_stopVec.destroy();
103
104
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if(m_isTimeSchemeFluidExtrapolAllocated) {
105
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
12 for(std::size_t i=0; i<m_timeSchemeFluidExtrapol.size(); ++i)
106 8 m_timeSchemeFluidExtrapol[i].destroy();
107 4 m_timeSchemeFluidExtrapol.clear();
108 }
109
110
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if(m_feStruc != NULL)
111
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 delete m_feStruc;
112
113
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if(m_feVel != NULL)
114
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 delete m_feVel;
115
116
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if(m_fePre != NULL)
117
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 delete m_fePre;
118 }
119
120 /*!
121 * Intersect the meshes and std::set the informations in the two solvers
122 */
123 template<class SolidPrb>
124 2 void FSINitscheXFEMModel<SolidPrb>::initializeDerivedLinearProblem()
125 {
126
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 FEL_CHECK(m_linearProblem.size() == 2, "Need two solver for Nitsche XFEM FSI Model");
127
128 // type conversion of the linear problems
129
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 m_pLinFluid = dynamic_cast<LinearProblemFSINitscheXFEMFluid*>(m_linearProblem[0]);
130
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 m_pLinStruc = dynamic_cast<LinearProblemFSINitscheXFEMSolid<SolidPrb>*>(m_linearProblem[1]);
131
132
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if(FelisceParam::instance().duplicateSupportDof) {
133
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 FEL_CHECK(m_mesh.size() > 1, "Need at least 2 meshes: one for the fluid and one for the structure");
134
135 // build the edges of the fluid mesh
136 2 m_mesh[0]->buildEdges();
137
138 // We intersect the two meshes here (because this function is called before computeDof)
139 // The meshes can be found in the linear problem
140
3/6
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
2 m_intersectMeshes.setMeshesName("fluidMesh", "strucMesh");
141 2 m_intersectMeshes.setVerbose(FelisceParam::verbose());
142 2 m_intersectMeshes.initAndIntersectMeshes(*m_mesh[0], *m_mesh[1]);
143
144 // give access to the intersection to each linear problems
145 2 m_pLinFluid->setDuplicateSupportObject(&m_intersectMeshes);
146 2 m_pLinStruc->setDuplicateSupportObject(&m_intersectMeshes);
147
148 // give direct access to the other linear problem
149 2 m_pLinFluid->setStrucLinPrb(m_pLinStruc);
150 2 m_pLinStruc->setFluidLinPrb(m_pLinFluid);
151
152 // compute normals
153 2 m_mesh[1]->computeNormalTangent();
154 2 m_mesh[1]->computeElementNormal(m_mesh[1]->listElementNormals());
155 2 m_mesh[1]->computeElementNormal(m_mesh[1]->listElementNormalsInit());
156 }
157 2 }
158
159 /*!
160 * Initialize time scheme
161 */
162 template<class SolidPrb>
163 2 void FSINitscheXFEMModel<SolidPrb>::initializeDerivedModel()
164 {
165 // get the type of time discretization.
166 2 m_elemFieldTimeSchemeType = FelisceParam::instance().elementFieldDynamicValue("TimeSchemeType");
167
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if(m_elemFieldTimeSchemeType != NULL) {
168 2 m_timeSchemeType = (felInt) m_elemFieldTimeSchemeType->constant(Comp1);
169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (m_timeSchemeType == 0) {
170 // Robin-Neumann scheme (direct implementation)
171 // Robin-Neumann extrapolation order
172 m_RNExtrapolOrder = (felInt) FelisceParam::instance().fsiRNscheme;
173 m_timeSchemeExtrapolOrder = m_RNExtrapolOrder;
174
175 // resize the sequential std::vector in m_pLinFluid and the parallel one here
176 m_pLinFluid->initRNFluidExtrapol(m_timeSchemeExtrapolOrder);
177 m_timeSchemeFluidExtrapol.resize(m_timeSchemeExtrapolOrder);
178
179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 } else if(m_timeSchemeType == 2) {
180 // Robin-Neumann scheme a la Stenberg
181 // Robin-Neumann extrapolation order
182 m_RNExtrapolOrder = (felInt) FelisceParam::instance().fsiRNscheme;
183 m_timeSchemeExtrapolOrder = m_RNExtrapolOrder;
184
185 // resize the sequential std::vector in m_pLinFluid and the parallel one here
186 m_pLinFluid->initRNFluidExtrapol(m_timeSchemeExtrapolOrder);
187 m_timeSchemeFluidExtrapol.resize(m_timeSchemeExtrapolOrder);
188
189 // resize the sequential std::vector in m_pLinStruc
190 m_pLinStruc->initStabExplicitFluidExtrapol(m_timeSchemeExtrapolOrder);
191
192
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 } else if(m_timeSchemeType == 3) {
193 // stabilized explicit
194 // number of sub iteration (correction + 1)
195
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if(FelisceParam::instance().couplingSchemeStoppingCriteria == 0)
196 2 m_subIteration = (felInt) m_elemFieldTimeSchemeType->constant(Comp2);
197 else if(FelisceParam::instance().couplingSchemeStoppingCriteria == 1) {
198 m_stoppingCriteriaTol = (double) m_elemFieldTimeSchemeType->constant(Comp2);
199 m_stopVec.duplicateFrom(m_pLinStruc->solution());
200 m_isStopVecAllocated = true;
201 }
202
203 // extrapolation order of the initial fluid solution in structure solver
204 2 m_timeSchemeExtrapolOrder = (felInt) m_elemFieldTimeSchemeType->constant(Comp3);
205
206 // resize the sequential std::vector in m_pLinStruc and the parallel one here
207 2 m_pLinStruc->initStabExplicitFluidExtrapol(m_timeSchemeExtrapolOrder);
208 2 m_timeSchemeFluidExtrapol.resize(m_timeSchemeExtrapolOrder);
209
210 } else if(m_timeSchemeType == 4) {
211 // Robin-Neumann semi-implicit
212 // Robin-Neumann extrapolation order
213 m_RNExtrapolOrder = (felInt) FelisceParam::instance().fsiRNscheme;
214
215 // number of sub iterations in the (fluid)-(solid/inertia) problem
216 if(FelisceParam::instance().couplingSchemeStoppingCriteria == 0)
217 m_subIteration = (felInt) m_elemFieldTimeSchemeType->constant(Comp2);
218 else if(FelisceParam::instance().couplingSchemeStoppingCriteria == 1) {
219 m_stoppingCriteriaTol = (double) m_elemFieldTimeSchemeType->constant(Comp2);
220 m_stopVec.duplicateFrom(m_pLinStruc->solution());
221 m_isStopVecAllocated = true;
222 }
223
224 // extrapolation order of the initial fluid solution in structure solver
225 m_timeSchemeExtrapolOrder = (felInt) m_elemFieldTimeSchemeType->constant(Comp3);
226
227 // resize the sequential std::vector in m_pLinStruc and the parallel one here
228 m_pLinStruc->initStabExplicitFluidExtrapol(m_timeSchemeExtrapolOrder);
229 m_timeSchemeFluidExtrapol.resize(m_timeSchemeExtrapolOrder);
230 }
231 }
232
233
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (FelisceParam::instance().orderBdfNS > 2)
234 FEL_ERROR("BDF not yet implemented for order greater than 2 with FDFSI.");
235
236
237 // bdf schemes
238 // fluid
239 2 m_bdfFluid.defineOrder(FelisceParam::instance().orderBdfNS);
240 2 m_pLinFluid->initializeTimeScheme(&m_bdfFluid);
241
242
243 // velocity of the structure
244 // parallel vectors
245 2 m_structureVel.duplicateFrom(m_pLinStruc->solution());
246
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 m_structureVel.set( 0.);
247 2 m_isStructureVelAllocated = true;
248
249 2 m_structureVelOld.duplicateFrom(m_pLinStruc->solution());
250
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 m_structureVelOld.set( 0.);
251 2 m_isStructureVelOldAllocated = true;
252
253 2 m_structureVelOldOld.duplicateFrom(m_pLinStruc->solution());
254
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 m_structureVelOldOld.set( 0.);
255 2 m_isStructureVelOldOldAllocated = true;
256
257
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if(FelisceParam::instance().couplingSchemeStoppingCriteria == 1) {
258 m_structureVelOldStoppingCriteria.duplicateFrom(m_pLinStruc->solution());
259 m_structureVelOldStoppingCriteria.set( 0.);
260 m_isStructureVelOldStoppingCriteriaAllocated = true;
261 }
262
263 2 m_structureVelExtrapol.duplicateFrom(m_pLinStruc->solution());
264
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 m_structureVelExtrapol.set( 0.);
265 2 m_isStructureVelExtrapolAllocated = true;
266
267 // sequential vectors
268 2 m_seqStructureTimeRHS.duplicateFrom(m_pLinStruc->sequentialSolution());
269
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 m_seqStructureTimeRHS.set( 0.0);
270 2 m_isSeqStructureTimeRHSAllocated = true;
271
272 2 m_seqStructureVelExtrapol.duplicateFrom(m_pLinStruc->sequentialSolution());
273
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 m_seqStructureVelExtrapol.set( 0.0);
274 2 m_isSeqStructureVelExtrapolAllocated = true;
275
276
277 // displacement of the structure
278 // parallel vectors
279 2 m_structureDispOld.duplicateFrom(m_pLinStruc->solution());
280
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 m_structureDispOld.set( 0.);
281 2 m_isStructureDispOldAllocated = true;
282
283
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if(m_timeSchemeType == 4 && m_RNExtrapolOrder == 2) {
284 m_structureNitscheRHSTermsOld.duplicateFrom(m_pLinStruc->vector());
285 m_structureNitscheRHSTermsOld.set( 0.);
286 m_isStructureNitscheRHSTermsOldAllocated = true;
287 }
288
289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(m_timeSchemeType == 4) {
290 m_structureTimeSchemeRHSTerms.duplicateFrom(m_pLinStruc->vector());
291 m_structureTimeSchemeRHSTerms.set( 0.);
292 m_isStructureTimeSchemeRHSTermsAllocated = true;
293
294 m_structureExtrapolatedNitscheTermsRHS.duplicateFrom(m_pLinStruc->vector());
295 m_structureExtrapolatedNitscheTermsRHS.set( 0.);
296 m_isStructureExtrapolatedNitscheTermsRHSAllocated = true;
297 }
298
299
300 // Finite element for the linear problems
301 // We assume that there is only one type of volume element for the structure
302 2 const std::vector<GeometricMeshRegion::ElementType>& bagElementTypeDomainStruc = m_pLinStruc->meshLocal()->bagElementTypeDomain();
303
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 FEL_ASSERT(bagElementTypeDomainStruc.size() == 1);
304
305 const RefElement *refEleStruc;
306 const GeoElement *geoEleStruc;
307
308 2 geoEleStruc = GeometricMeshRegion::eltEnumToFelNameGeoEle[bagElementTypeDomainStruc[0]].second;
309
310 2 int idDisplacement = m_pLinStruc->listVariable().getVariableIdList(displacement);
311 2 int typeOfFiniteElement = m_pLinStruc->listVariable()[idDisplacement].finiteElementType();
312
313
1/2
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 refEleStruc = geoEleStruc->defineFiniteEle(bagElementTypeDomainStruc[0], typeOfFiniteElement, *m_pLinStruc->meshLocal());
314
1/2
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 m_feStruc = new CurvilinearFiniteElement(*refEleStruc, *geoEleStruc, m_pLinStruc->listVariable()[idDisplacement].degreeOfExactness());
315
316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 FEL_ASSERT(m_feStruc);
317 2 m_pLinFluid->setStrucFiniteElement(m_feStruc);
318
319 // We assume that there is only one type of volume element for the fluid
320 2 const std::vector<GeometricMeshRegion::ElementType>& bagElementTypeDomainFluid = m_pLinFluid->meshLocal()->bagElementTypeDomain();
321
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 FEL_ASSERT(bagElementTypeDomainFluid.size() == 1);
322
323 const RefElement *refEleVel;
324 const GeoElement *geoEleFluid;
325 const RefElement *refElePre;
326
327 2 geoEleFluid = GeometricMeshRegion::eltEnumToFelNameGeoEle[bagElementTypeDomainFluid[0]].second;
328
329 2 int idVel = m_pLinFluid->listVariable().getVariableIdList(velocity);
330 2 int idPre = m_pLinFluid->listVariable().getVariableIdList(pressure);
331 2 int typeOfFiniteElementVel = m_pLinFluid->listVariable()[idVel].finiteElementType();
332 2 int typeOfFiniteElementPre = m_pLinFluid->listVariable()[idPre].finiteElementType();
333
334
1/2
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 refEleVel = geoEleFluid->defineFiniteEle(bagElementTypeDomainFluid[0], typeOfFiniteElementVel, *m_pLinStruc->meshLocal());
335
1/2
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 m_feVel = new CurrentFiniteElement(*refEleVel, *geoEleFluid, m_pLinFluid->listVariable()[idVel].degreeOfExactness());
336
337
1/2
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 refElePre = geoEleFluid->defineFiniteEle(bagElementTypeDomainFluid[0], typeOfFiniteElementPre, *m_pLinStruc->meshLocal());
338
1/2
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 m_fePre = new CurrentFiniteElement(*refElePre, *geoEleFluid, m_pLinFluid->listVariable()[idPre].degreeOfExactness());
339
340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 FEL_ASSERT(m_feVel);
341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 FEL_ASSERT(m_fePre);
342 2 m_pLinStruc->setFluidFiniteElement(m_feVel, m_fePre);
343
344
345 // initialize the original bdf for the fluid
346 2 m_pLinFluid->initOriginalBdf(m_timeSchemeType, m_timeSchemeExtrapolOrder);
347
348 // Get the number of components in the displacement
349 2 felInt iUnknown = m_pLinStruc->listUnknown().getUnknownIdList(displacement);
350 2 felInt idVar = m_pLinStruc->listUnknown().idVariable(iUnknown);
351 2 m_numStrucComp = m_pLinStruc->listVariable()[idVar].numComponent();
352 2 }
353
354 template<class SolidPrb>
355 36 void FSINitscheXFEMModel<SolidPrb>::preAssemblingMatrixRHS(std::size_t iProblem)
356 {
357
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 18 times.
36 if(iProblem == 0) {
358 // Allocate the extrapolation of the velocity if necessary
359
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if(!m_isParFluidVelAllocated) {
360 // There are orderBdfNS term in the velocity extrapolation
361 18 m_parFluidVel.resize(FelisceParam::instance().orderBdfNS);
362
363 // If we use a projection of the old solution, all the terms have the same size
364
5/6
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 16 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 16 times.
18 if(FelisceParam::instance().useProjectionForNitscheXFEM || m_fstransient->iteration == 0) {
365
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
4 for(std::size_t i=0; i<m_parFluidVel.size(); ++i)
366 2 m_parFluidVel[i].duplicateFrom(m_pLinFluid->vector());
367 } else {
368
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 16 times.
32 for(std::size_t i=0; i<m_parFluidVel.size(); ++i)
369 16 m_parFluidVel[i].duplicateFrom(m_pLinFluid->solutionOld(i));
370 }
371
372 // std::set the extrapolation term to zero
373
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 18 times.
36 for(std::size_t i=0; i<m_parFluidVel.size(); ++i)
374
1/2
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
18 m_parFluidVel[i].set( 0.);
375
376 18 m_isParFluidVelAllocated = true;
377 }
378
379 // initialize fluid extrapolation in fluid linear problem
380
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
18 if((m_timeSchemeType == 0) || (m_timeSchemeType == 2)) {
381 if(!m_isTimeSchemeFluidExtrapolAllocated) {
382 if(FelisceParam::instance().useProjectionForNitscheXFEM || m_fstransient->iteration == 0) {
383 for(std::size_t i=0; i<m_timeSchemeFluidExtrapol.size(); ++i)
384 m_timeSchemeFluidExtrapol[i].duplicateFrom(m_pLinFluid->solution());
385 } else {
386 for(std::size_t i=0; i<m_timeSchemeFluidExtrapol.size(); ++i)
387 m_timeSchemeFluidExtrapol[i].duplicateFrom(m_pLinFluid->solutionOld(i));
388 }
389
390 for(std::size_t i=0; i<m_timeSchemeFluidExtrapol.size(); ++i)
391 m_timeSchemeFluidExtrapol[i].set(0.);
392
393 m_pLinFluid->initRNFluidExtrapol(m_timeSchemeExtrapolOrder);
394 m_pLinFluid->gatherRNFluidExtrapol(m_timeSchemeFluidExtrapol);
395
396 if(m_timeSchemeType == 0)
397 m_isTimeSchemeFluidExtrapolAllocated = true;
398 }
399 }
400 }
401
402
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 18 times.
36 if(iProblem == 1) {
403 // initialize fluid extrapolation in structure linear problem
404
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
18 if ((m_timeSchemeType == 3) || (m_timeSchemeType == 4)) {
405
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if(!m_isTimeSchemeFluidExtrapolAllocated) {
406
5/6
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 16 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 16 times.
18 if(FelisceParam::instance().useProjectionForNitscheXFEM || m_fstransient->iteration == 0) {
407
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
6 for(std::size_t i=0; i<m_timeSchemeFluidExtrapol.size(); ++i)
408 4 m_timeSchemeFluidExtrapol[i].duplicateFrom(m_pLinFluid->solution());
409 } else {
410
2/2
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 16 times.
48 for(std::size_t i=0; i<m_timeSchemeFluidExtrapol.size(); ++i)
411 32 m_timeSchemeFluidExtrapol[i].duplicateFrom(m_pLinFluid->solutionOld(i));
412 }
413
414
2/2
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 18 times.
54 for(std::size_t i=0; i<m_timeSchemeFluidExtrapol.size(); ++i)
415
1/2
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 m_timeSchemeFluidExtrapol[i].set(0.);
416
417 18 m_pLinStruc->initStabExplicitFluidExtrapol(m_timeSchemeExtrapolOrder);
418 18 m_pLinStruc->gatherStabExplicitFluidExtrapol(m_timeSchemeFluidExtrapol);
419 18 m_isTimeSchemeFluidExtrapolAllocated = true;
420 }
421
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
18 } else if (m_timeSchemeType == 2) {
422 if(!m_isTimeSchemeFluidExtrapolAllocated) {
423 m_pLinStruc->initStabExplicitFluidExtrapol(m_timeSchemeExtrapolOrder);
424 m_pLinStruc->gatherStabExplicitFluidExtrapol(m_timeSchemeFluidExtrapol);
425 m_isTimeSchemeFluidExtrapolAllocated = true;
426 }
427 }
428 }
429 36 }
430
431 template<class SolidPrb>
432 void FSINitscheXFEMModel<SolidPrb>::postAssemblingMatrixRHS(std::size_t iProblem)
433 {
434 if(iProblem == 0) {
435 // m_Matrix = m_A + m_Matrix (add static matrix to the dynamic matrix to build
436 // complete matrix of the system
437 m_linearProblem[iProblem]->addMatrixRHS();
438 }
439 }
440
441 template<class SolidPrb>
442 2 void FSINitscheXFEMModel<SolidPrb>::setExternalVec()
443 {
444 // externalVec(0) in m_pLinFluid
445 2 m_pLinFluid->pushBackExternalVec(m_seqStructureVelExtrapol);
446
447 // externalVec(0) in m_pLinSolid
448 2 m_pLinStruc->pushBackExternalVec(m_seqStructureTimeRHS);
449 2 }
450
451 template<class SolidPrb>
452 20 void FSINitscheXFEMModel<SolidPrb>::forward()
453 {
454 // check solution on crack solid to determine crack spring constant -- if it exists in user
455 20 m_pLinStruc->userComputeCrackStress();
456
2/2
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 9 times.
20 if(m_intersectMeshes.hasIntersectionChange()) {
457 // reallocate everything for the fluid
458 // supportDofMeshes, duplication, and dofs
459 11 m_pLinFluid->computeDof(MpiInfo::numProc(), MpiInfo::rankProc());
460
461 // new pattern
462 11 m_pLinFluid->userChangePattern(MpiInfo::numProc(), MpiInfo::rankProc());
463
464 // cut the mesh
465 11 m_pLinFluid->cutMesh();
466
467 // allocate matrices and vectors
468 11 m_pLinFluid->allocateMatrix();
469
470 // determine dof for the boundary conditions
471 11 m_pLinFluid->determineDofAssociateToLabel();
472 11 m_pLinFluid->finalizeEssBCConstantInT();
473
474 // pre assembling to reallocate the extrapolations
475
2/2
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 11 times.
33 for (std::size_t ipb = 0; ipb < m_linearProblem.size(); ipb++) {
476 22 preAssemblingMatrixRHS(ipb);
477 }
478
479 // re build the solver (not possible to change the matrix size in the ksp without destroying it ?)
480 11 m_pLinFluid->buildSolver();
481
482 // Copy all the vectors of the fluid from the original support dof
483 11 m_pLinFluid->copyOriginalSolToCurrentSol();
484 }
485
486
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 18 times.
20 if(m_fstransient->iteration == 0) {
487 // initialize the old objects
488 2 m_pLinFluid->initOldObjects(m_timeSchemeExtrapolOrder);
489
490 // Write solution for postprocessing (if required)
491 2 writeSolutionAndMeshes();
492 }
493
494 // Advance time step.
495 20 updateTime();
496
497 // Print time information
498 20 printNewTimeIterationBanner();
499
500 ///////////////////////
501 // Update Bdf scheme //
502 ///////////////////////
503
504
8/8
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 5 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 18 times.
✓ Branch 9 taken 2 times.
20 if(m_intersectMeshes.hasIntersectionChange() || m_reinitializeFluidBdf || m_fstransient->iteration == 1) {
505 // initialize the bdf for the fluid
506
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
18 if(FelisceParam::instance().useProjectionForNitscheXFEM) {
507 m_pLinFluid->copyOriginalBdfToCurrentBdf(m_timeSchemeType, m_timeSchemeExtrapolOrder);
508 } else {
509
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 felInt order = std::max(m_timeSchemeExtrapolOrder, FelisceParam::instance().orderBdfNS);
510
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 PetscVector zero = PetscVector::null();
511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if(order == 1) {
512 m_bdfFluid.reinitialize(FelisceParam::instance().orderBdfNS, m_pLinFluid->solutionOld(0), zero, zero);
513
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 } else if(order == 2) {
514
2/4
✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 18 times.
✗ Branch 7 not taken.
18 m_bdfFluid.reinitialize(FelisceParam::instance().orderBdfNS, m_pLinFluid->solutionOld(1), m_pLinFluid->solutionOld(0), zero);
515 } else {
516 FEL_ERROR("This bdf order is not implemented for this problem");
517 }
518 18 }
519
520 // Compute the extrapolation of the velocity and initialize the one in the solver
521 18 m_bdfFluid.extrapolateByPart(m_parFluidVel);
522 18 m_pLinFluid->gatherSeqVelExtrapol(m_parFluidVel);
523
524 // Compute the rhs coming from the time scheme and initialize the one in the solver
525 18 m_bdfFluid.computeRHSTimeByPart(m_fstransient->timeStep, m_parFluidVel);
526 18 m_pLinFluid->gatherSeqBdfRHS(m_parFluidVel);
527
528 // std::set flag to false
529 18 m_reinitializeFluidBdf = false;
530 } else {
531 2 m_bdfFluid.update(m_pLinFluid->solution());
532
533 2 m_bdfFluid.extrapolateByPart(m_parFluidVel);
534 2 m_pLinFluid->gatherSeqVelExtrapol(m_parFluidVel);
535
536 2 m_bdfFluid.computeRHSTimeByPart(m_fstransient->timeStep, m_parFluidVel);
537 2 m_pLinFluid->gatherSeqBdfRHS(m_parFluidVel);
538 }
539
540 // structure
541 20 m_structureDispOld.axpby(2., -1., m_pLinStruc->solution());
542 20 m_pLinStruc->gatherVector(m_structureDispOld, m_seqStructureTimeRHS);
543 20 m_structureDispOld.copyFrom(m_pLinStruc->solution());
544 20 m_pLinStruc->gatherSeqLastTimeSol(m_structureDispOld);
545
546
547 // move the mesh if the displacement is a std::vector
548 // if( m_fstransient->iteration > 1 && m_numStrucComp == m_pLinFluid->dimension()) {
549 // m_pLinStruc->meshLocal()->moved() = false;
550 // m_pLinStruc->mesh()->moved() = false;
551 // m_pLinStruc->meshLocal()->moveMesh(m_interfaceDisplacement, 1);
552 // m_pLinStruc->mesh()->moveMesh(m_interfaceDisplacement, 1);
553 // }
554
555 // specific operation of the time schemes
556
1/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
20 switch(m_timeSchemeType) {
557 case 0: {
558 computeTimeSchemeExtrapol();
559 m_pLinFluid->gatherRNFluidExtrapol(m_timeSchemeFluidExtrapol);
560 m_pLinFluid->setUseCurrentFluidSolution(false);
561 m_pLinStruc->setUseCurrentFluidSolution(true);
562 solveProblemFluid();
563 solveProblemSolid();
564 break;
565 }
566
567 case 1: {
568 solveProblemSolid();
569 solveProblemFluid();
570 break;
571 }
572
573 case 2: {
574 // Check if we need to move the mesh to its initial position to assemble solid terms
575 bool moveTheMesh = m_fstransient->iteration > 1 && FelisceParam::instance().useDynamicStructure;
576
577 computeTimeSchemeExtrapol();
578
579 m_pLinFluid->gatherRNFluidExtrapol(m_timeSchemeFluidExtrapol);
580 m_pLinFluid->setUseCurrentFluidSolution(false);
581 solveProblemFluid();
582
583 m_pLinStruc->setUseCurrentFluidSolution(true);
584
585 // Assembly loop
586 // 1) build the term on the original mesh
587 if(moveTheMesh) {
588 m_pLinStruc->meshLocal()->moveMesh(m_interfaceDisplacement, 0);
589 m_pLinStruc->mesh()->moveMesh(m_interfaceDisplacement, 0);
590 }
591
592 m_pLinStruc->isAssemblingOfSolidProblemTerms(true);
593 m_pLinStruc->gatherRNStructExtrapol(m_structureVelExtrapol);
594 m_pLinStruc->assembleMatrixRHSBD(MpiInfo::rankProc());
595
596 // build the term with the fluid on the moved mesh
597 if(moveTheMesh) {
598 m_pLinStruc->meshLocal()->moveMesh(m_interfaceDisplacement, 1.0);
599 m_pLinStruc->mesh()->moveMesh(m_interfaceDisplacement, 1.0);
600 }
601
602 m_pLinStruc->isAssemblingOfSolidProblemTerms(false);
603 m_pLinStruc->initStabExplicitFluidExtrapol(1);
604 m_pLinStruc->assembleMatrixRHSBD(MpiInfo::rankProc());
605
606 m_pLinStruc->setUseCurrentFluidSolution(false);
607
608 m_pLinStruc->initStabExplicitFluidExtrapol(m_timeSchemeExtrapolOrder);
609 m_pLinStruc->gatherStabExplicitFluidExtrapol(m_timeSchemeFluidExtrapol);
610 m_pLinStruc->assembleMatrixRHSBD(MpiInfo::rankProc());
611
612 // Apply boundary conditions.
613 m_pLinStruc->setUserBoundaryCondition();
614
615 // Solve linear system.
616 PetscPrintf(PETSC_COMM_WORLD, "*** Structure solver ***\n");
617 m_pLinStruc->solve(MpiInfo::rankProc(), MpiInfo::numProc());
618
619 ////////////////////////////////////////////////////
620 // Compute the vec to link the two linear problem //
621 ////////////////////////////////////////////////////
622
623 computeTimeSchemeStructureVelExtrapol();
624
625 // gather solution
626 m_pLinStruc->gatherSolution();
627
628 break;
629 }
630
631 20 case 3: {
632 // initialize the fluid solution with the extrapolation
633 20 computeTimeSchemeExtrapol();
634 20 m_pLinStruc->gatherStabExplicitFluidExtrapol(m_timeSchemeFluidExtrapol);
635 20 m_pLinFluid->setUseCurrentFluidSolution(false);
636 20 m_pLinStruc->setUseCurrentFluidSolution(false);
637
638 20 felInt it = 0;
639 20 bool atConvergence = false;
640 20 double abstol = 1e-12;
641
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 20 times.
60 while(!atConvergence) {
642 // clear the matrices at each sub iteration
643 40 m_pLinFluid->clearMatrixRHS(FlagMatrixRHS::matrix_and_rhs);
644 40 m_pLinStruc->clearMatrixRHS(FlagMatrixRHS::matrix_and_rhs);
645
646 40 solveProblemSolid();
647 40 solveProblemFluid();
648
649 // use the fluid solution (not the extrapolation) for the next sub iterations
650
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 20 times.
40 if(it == 0) {
651 20 m_pLinStruc->initStabExplicitFluidExtrapol(1);
652 20 m_pLinStruc->gatherStabExplicitFluidExtrapol(m_pLinFluid->solution());
653
654 20 m_pLinFluid->setUseCurrentFluidSolution(true);
655 20 m_pLinStruc->setUseCurrentFluidSolution(true);
656 } else {
657 20 m_pLinStruc->setStabExplicitFluidExtrapol(m_pLinFluid->sequentialSolution());
658 }
659
660 // increment the number of iteration
661 40 ++it;
662
663 // compute the stopping criteria
664
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 if(FelisceParam::instance().couplingSchemeStoppingCriteria == 0) {
665 // fix number of iteration
666 40 atConvergence = it < m_subIteration ? false : true;
667 } else if(FelisceParam::instance().couplingSchemeStoppingCriteria == 1) {
668 // compute relative error on structure
669 m_stopVec.copyFrom(m_structureVel);
670 double rhs = std::sqrt(m_pLinStruc->computeL2Norm(m_stopVec));
671 m_stopVec.axpy(-1., m_structureVelOldStoppingCriteria);
672 double lhs = std::sqrt(m_pLinStruc->computeL2Norm(m_stopVec));
673
674 atConvergence = ((lhs < m_stoppingCriteriaTol * rhs) || (lhs < abstol)) && (it > 1) ? true : false;
675 PetscPrintf(PETSC_COMM_WORLD, "Relative Error after iteration %d : %12.5e --- %12.5e\n\n", it, lhs, m_stoppingCriteriaTol*rhs);
676 }
677 }
678 20 break;
679 }
680
681 case 4: {
682 ////////////////////////////////////////////////////
683 // fluid-(solid-inertia) problem //
684 ////////////////////////////////////////////////////
685
686 // gather the previous solid-velocity and solid-displacement for the (fluid)-(solid-inertia) problem
687 m_pLinStruc->gatherRNStructExtrapol(m_structureVelExtrapol);
688
689 // initialize the fluid solution with the extrapolation
690 computeTimeSchemeExtrapol();
691 m_pLinStruc->gatherStabExplicitFluidExtrapol(m_timeSchemeFluidExtrapol);
692
693 m_pLinStruc->setUseCurrentFluidSolution(false);
694 m_pLinFluid->setUseCurrentFluidSolution(false);
695
696 m_pLinStruc->isStrucOperatorExplicitlyComputed(true);
697
698 felInt it = 0;
699 bool atConvergence = false;
700 double abstol = 1e-12;
701 while(!atConvergence) {
702 // clear the matrices at each sub iteration
703 m_pLinStruc->clearMatrixRHS(FlagMatrixRHS::matrix_and_rhs);
704 m_pLinFluid->clearMatrixRHS(FlagMatrixRHS::matrix_and_rhs);
705
706 solveProblemSolid();
707 solveProblemFluid();
708
709 // use the fluid solution (not the extrapolation) for the next sub iterations
710 if(it == 0) {
711 m_pLinStruc->initStabExplicitFluidExtrapol(1);
712 m_pLinStruc->gatherStabExplicitFluidExtrapol(m_pLinFluid->solution());
713
714 m_pLinFluid->setUseCurrentFluidSolution(true);
715 m_pLinStruc->setUseCurrentFluidSolution(true);
716 } else {
717 m_pLinStruc->setStabExplicitFluidExtrapol(m_pLinFluid->sequentialSolution());
718 }
719
720 // increment the number of iteration
721 ++it;
722
723 // compute the stopping criteria
724 if(FelisceParam::instance().couplingSchemeStoppingCriteria == 0) {
725 // fix number of iteration
726 atConvergence = it < m_subIteration ? false : true;
727 } else if(FelisceParam::instance().couplingSchemeStoppingCriteria == 1) {
728 // compute relative error on structure
729 m_stopVec.copyFrom(m_structureVelExtrapol);
730 double rhs = std::sqrt(m_pLinStruc->computeL2Norm(m_stopVec));
731 m_stopVec.axpy(-1., m_structureVelOldStoppingCriteria);
732 double lhs = std::sqrt(m_pLinStruc->computeL2Norm(m_stopVec));
733
734 atConvergence = ((lhs < m_stoppingCriteriaTol * rhs) || (lhs < abstol)) && (it > 1) ? true : false;
735 PetscPrintf(PETSC_COMM_WORLD, "Relative Error after iteration %d : %12.5e --- %12.5e\n\n", it, lhs, m_stoppingCriteriaTol*rhs);
736 }
737 }
738
739
740 //////////////////////////////////
741 // solve the real solid problem //
742 //////////////////////////////////
743
744 m_pLinStruc->clearMatrixRHS(FlagMatrixRHS::matrix_and_rhs);
745 m_pLinStruc->isStrucOperatorExplicitlyComputed(false);
746 m_pLinStruc->setUseCurrentFluidSolution(true);
747 m_pLinStruc->initStabExplicitFluidExtrapol(1);
748 m_pLinStruc->gatherStabExplicitFluidExtrapol(m_pLinFluid->solution());
749
750 solveProblemSolid();
751
752 break;
753 }
754
755 default: {
756 solveProblemFluid();
757 solveProblemSolid();
758 break;
759 }
760 }
761
762 // post process //
763 // Write solution (to get the real solution define on the duplicated support dof, not on the original one)
764 20 writeSolutionAndMeshes();
765
766 // update the position of the interface and recompute the intersection
767
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 if(FelisceParam::instance().useDynamicStructure) {
768
769 20 updateInterfacePosition( m_pLinStruc->sequentialSolution() );
770 20 m_intersectMeshes.updateInterfacePosition( m_interfaceDisplacement );
771
772
1/2
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
20 m_mesh[1]->moveMesh(m_interfaceDisplacement, 1.0);
773 20 m_mesh[1]->computeElementNormal(m_mesh[1]->listElementNormals());
774
1/2
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
20 m_mesh[1]->moveMesh(m_interfaceDisplacement, 0.);
775
776 20 m_intersectMeshes.setIteration(m_fstransient->iteration);
777 20 m_intersectMeshes.intersectMeshes(*m_mesh[0], *m_mesh[1]);
778 }
779
780 // save the solution with the original support Dof and delete the matrices, vectors and mapping of the fluid
781
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 7 times.
20 if(m_intersectMeshes.hasIntersectionChange()) {
782 // copy for the fluid
783 13 m_pLinFluid->copyCurrentSolToOriginalSol();
784
785 // delete dynamic parts
786
2/2
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 2 times.
13 if(!hasFinished()) {
787 11 m_pLinFluid->updateOldSolution(1);
788 11 m_pLinFluid->deleteDynamicData();
789 11 m_pLinStruc->deleteDynamicData();
790
791
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(m_isTimeSchemeFluidExtrapolAllocated) {
792
2/2
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 11 times.
33 for(std::size_t i=0; i<m_timeSchemeFluidExtrapol.size(); ++i)
793 22 m_timeSchemeFluidExtrapol[i].destroy();
794
795 11 m_isTimeSchemeFluidExtrapolAllocated = false;
796 }
797
798
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(m_isParFluidVelAllocated) {
799
2/2
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 11 times.
22 for(std::size_t i=0; i<m_parFluidVel.size(); ++i)
800 11 m_parFluidVel[i].destroy();
801
802 11 m_isParFluidVelAllocated = false;
803 }
804 }
805
806 // std::set to true only to remember that the intersection has changed after this time step
807 // If the intersection is not changing at the next time step, we need to reinitialize the old objects
808 13 m_countToInitOldObjects = std::max(m_timeSchemeExtrapolOrder, FelisceParam::instance().orderBdfNS);
809 } else {
810 7 m_pLinFluid->updateOldSolution(m_countToInitOldObjects);
811
812
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
7 if(m_countToInitOldObjects > 0) {
813
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if(m_isTimeSchemeFluidExtrapolAllocated) {
814
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 5 times.
15 for(std::size_t i=0; i<m_timeSchemeFluidExtrapol.size(); ++i)
815 10 m_timeSchemeFluidExtrapol[i].destroy();
816
817 5 m_isTimeSchemeFluidExtrapolAllocated = false;
818 }
819
820
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if(m_isParFluidVelAllocated) {
821
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 5 times.
10 for(std::size_t i=0; i<m_parFluidVel.size(); ++i)
822 5 m_parFluidVel[i].destroy();
823
824 5 m_isParFluidVelAllocated = false;
825 }
826
827 // pre assembling to reallocate the extrapolations
828
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 5 times.
15 for (std::size_t ipb = 0; ipb < m_linearProblem.size(); ipb++) {
829 10 preAssemblingMatrixRHS(ipb);
830 }
831
832 5 m_countToInitOldObjects -= 1;
833 5 m_reinitializeFluidBdf = true;
834 } else {
835
2/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 if((m_timeSchemeType == 2) || (m_timeSchemeType == 3) || (m_timeSchemeType == 4)) {
836 // reset the right size for the extrapolation of the velocity
837 2 m_pLinStruc->initStabExplicitFluidExtrapol(m_timeSchemeExtrapolOrder);
838 }
839 }
840 }
841 20 }
842
843 template<class SolidPrb>
844 40 void FSINitscheXFEMModel<SolidPrb>::solveProblemFluid()
845 {
846 // Assembly loop for front points
847 40 m_pLinFluid->assembleMatrixFrontPoints();
848
849 // Assembly loop for the ghost penalty stabilization
850
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 if(FelisceParam::instance().useGhostPenalty)
851 40 m_pLinFluid->assembleMatrixGhostPenalty();
852
853 // Assembly loop for the face oriented stabilization
854
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 if(FelisceParam::instance().NSStabType == 1)
855 40 m_pLinFluid->assembleMatrixFaceOriented();
856
857 // Main assembly loop and assembly of the matrix
858 // The pattern is reduced to where values have been std::set till here, that is why this loop is called in last
859 40 m_pLinFluid->assembleMatrixRHS(MpiInfo::rankProc());
860
861 // Specific operations before solving the system
862 // postAssemblingMatrixRHS(0);
863
864 // Apply boundary conditions.
865 // m_pLinFluid->finalizeEssBCConstantInT();
866 40 m_pLinFluid->finalizeEssBCTransient();
867 40 m_pLinFluid->applyBC(FelisceParam::instance().essentialBoundaryConditionsMethod, MpiInfo::rankProc());
868
869 // Solve the linear system.
870 40 PetscPrintf(PETSC_COMM_WORLD, "*** Fluid solver ***\n");
871 40 m_pLinFluid->solve(MpiInfo::rankProc(), MpiInfo::numProc());
872
873 // Gather the solution to use it in the solid problem
874 40 m_pLinFluid->gatherSolution();
875 40 }
876
877 template<class SolidPrb>
878 40 void FSINitscheXFEMModel<SolidPrb>::solveProblemSolid()
879 {
880 // Check if we need to move the mesh to its initial position to assemble solid terms
881
3/4
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 4 times.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
40 bool moveTheMesh = m_fstransient->iteration > 1 && FelisceParam::instance().useDynamicStructure;
882
883 // Assembly loop
884 // 1) build the term on the original mesh
885
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 4 times.
40 if(moveTheMesh) {
886
1/2
✓ Branch 3 taken 36 times.
✗ Branch 4 not taken.
36 m_pLinStruc->meshLocal()->moveMesh(m_interfaceDisplacement, 0);
887
1/2
✓ Branch 3 taken 36 times.
✗ Branch 4 not taken.
36 m_pLinStruc->mesh()->moveMesh(m_interfaceDisplacement, 0);
888 }
889
890 40 m_pLinStruc->isAssemblingOfSolidProblemTerms(true);
891 40 m_pLinStruc->assembleMatrixRHSBD(MpiInfo::rankProc());
892
893
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 40 times.
40 if(m_timeSchemeType == 4 && !m_pLinStruc->isStrucOperatorExplicitlyComputed()) {
894 m_structureTimeSchemeRHSTerms.copyFrom(m_pLinStruc->vector());
895 }
896
897 // build the term with the fluid on the moved mesh
898
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 4 times.
40 if(moveTheMesh) {
899
1/2
✓ Branch 3 taken 36 times.
✗ Branch 4 not taken.
36 m_pLinStruc->meshLocal()->moveMesh(m_interfaceDisplacement, 1.0);
900
1/2
✓ Branch 3 taken 36 times.
✗ Branch 4 not taken.
36 m_pLinStruc->mesh()->moveMesh(m_interfaceDisplacement, 1.0);
901 }
902
903 40 m_pLinStruc->isAssemblingOfSolidProblemTerms(false);
904 40 m_pLinStruc->assembleMatrixRHSBD(MpiInfo::rankProc());
905
906
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 40 times.
40 if(m_timeSchemeType == 4 && !m_pLinStruc->isStrucOperatorExplicitlyComputed()) {
907 // update the vec
908 computeTimeSchemeStructureExtrapolRHS();
909
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 } else if(m_timeSchemeType == 4) {
910 // add the extrapolation to the rhs
911 m_pLinStruc->vector().axpy(-1., m_structureExtrapolatedNitscheTermsRHS);
912 }
913
914
915 // Apply boundary conditions.
916 40 m_pLinStruc->setUserBoundaryCondition();
917
918 // Solve linear system.
919 40 PetscPrintf(PETSC_COMM_WORLD, "*** Structure solver ***\n");
920
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
40 if(FelisceParam::instance().useODESolve)
921 m_pLinStruc->solve(MpiInfo::rankProc(), MpiInfo::numProc(), !m_pLinStruc->getUseCurrentFluidSolution());
922 else
923 40 m_linearProblem[1]->solve(MpiInfo::rankProc(), MpiInfo::numProc());
924
925
926 ////////////////////////////////////////////////////
927 // Compute the vec to link the two linear problem //
928 ////////////////////////////////////////////////////
929
930 40 computeTimeSchemeStructureVelExtrapol();
931
932 // gather solution
933 40 m_pLinStruc->gatherSolution();
934 40 }
935
936 template<class SolidPrb>
937 20 void FSINitscheXFEMModel<SolidPrb>::computeTimeSchemeExtrapol()
938 {
939
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 switch (m_timeSchemeExtrapolOrder) {
940 case 0:
941 break;
942 case 1:
943 m_timeSchemeFluidExtrapol[0].copyFrom(m_bdfFluid.sol_n());
944 break;
945 20 case 2:
946
2/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
20 if((m_timeSchemeType == 0) || (m_timeSchemeType == 2)) {
947 m_timeSchemeFluidExtrapol[0].copyFrom(m_bdfFluid.sol_n());
948 m_timeSchemeFluidExtrapol[1].copyFrom(m_bdfFluid.sol_n_1());
949 } else {
950
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 m_timeSchemeFluidExtrapol[0].set( 0.);
951
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 m_timeSchemeFluidExtrapol[1].set( 0.);
952 20 m_timeSchemeFluidExtrapol[0].axpy( 2.0, m_bdfFluid.sol_n());
953 20 m_timeSchemeFluidExtrapol[1].axpy( -1.0, m_bdfFluid.sol_n_1());
954 }
955 20 break;
956 default:
957 FEL_ERROR("unknown time scheme extrapolation order ");
958 break;
959 }
960 20 }
961
962 template<class SolidPrb>
963 40 void FSINitscheXFEMModel<SolidPrb>::computeTimeSchemeStructureVelExtrapol()
964 {
965
3/8
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 40 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
40 bool isRNScheme = (m_timeSchemeType == 0) || (m_timeSchemeType == 2) || (m_timeSchemeType == 4 && !m_pLinStruc->isStrucOperatorExplicitlyComputed());
966
967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if(isRNScheme) {
968 switch(m_RNExtrapolOrder) {
969 case 0:
970 break;
971 case 1:
972 m_structureVelOld.copyFrom(m_structureVel);
973 break;
974 case 2:
975 m_structureVelOldOld.copyFrom(m_structureVelOld);
976 m_structureVelOld.copyFrom(m_structureVel);
977 break;
978 default:
979 FEL_ERROR("unknown time scheme extrapolation order");
980 break;
981 }
982 }
983 else {
984
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
40 if(FelisceParam::instance().couplingSchemeStoppingCriteria == 1) {
985 if(m_timeSchemeType == 3)
986 m_structureVelOldStoppingCriteria.copyFrom(m_structureVel);
987 else
988 m_structureVelOldStoppingCriteria.copyFrom(m_structureVelExtrapol);
989 }
990 }
991
992 // compute the velocity of the structure
993 // dotX^n = ( X^n - X^(n-1) ) / tau
994 40 double tau = m_fstransient->timeStep;
995
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 40 times.
✗ Branch 8 not taken.
40 if(m_timeSchemeType != 4 || (m_timeSchemeType == 4 && !m_pLinStruc->isStrucOperatorExplicitlyComputed())) {
996 40 m_structureVel.copyFrom(m_pLinStruc->solution());
997 40 m_structureVel.axpby(-1./tau, 1./tau, m_structureDispOld);
998 } else {
999 m_structureVelExtrapol.copyFrom(m_pLinStruc->solution());
1000 }
1001
1002
1003 // compute the extrapolation of the velocity
1004
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if (isRNScheme) {
1005 switch (m_RNExtrapolOrder) {
1006 case 0:
1007 // ddot^{n-1} + dt \pd ddot^{\star} = ddot^{n-1}
1008 m_structureVelExtrapol.copyFrom(m_structureVel);
1009 break;
1010 case 1:
1011 // ddot^{n-1} + dt \pd ddot^{{\star} = 2*ddot^{n-1} - ddot^{n-2}
1012 m_structureVelExtrapol.copyFrom(m_structureVel);
1013 m_structureVelExtrapol.axpby(-1., 2. , m_structureVelOld);
1014 break;
1015 case 2:
1016 // ddot^{n-1} + dt \pd ddot^{{\star} = 3*ddot^{n-1} - 3*ddot^{n-2} + ddot^{n-3}
1017 m_structureVelExtrapol.copyFrom(m_structureVel);
1018 m_structureVelExtrapol.axpby(-3., 3., m_structureVelOld);
1019 m_structureVelExtrapol.axpy( 1. , m_structureVelOldOld);
1020 break;
1021 default:
1022 FEL_ERROR("unknown time scheme extrapolation order");
1023 break;
1024 }
1025
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 } else if(m_timeSchemeType == 3) {
1026 // No extrapolation is needed for scheme 3
1027 40 m_structureVelExtrapol.copyFrom(m_structureVel);
1028 }
1029
1030 // the serial std::vector is passed to the fluid problem
1031 40 m_pLinStruc->gatherVector(m_structureVelExtrapol, m_seqStructureVelExtrapol);
1032 40 }
1033
1034 template<class SolidPrb>
1035 void FSINitscheXFEMModel<SolidPrb>::computeTimeSchemeStructureExtrapolRHS()
1036 {
1037 switch(m_RNExtrapolOrder) {
1038 case 0:
1039 break;
1040
1041 case 1:
1042 m_structureExtrapolatedNitscheTermsRHS.copyFrom(m_pLinStruc->vector());
1043 m_structureExtrapolatedNitscheTermsRHS.axpby(-1., 1., m_structureTimeSchemeRHSTerms);
1044 break;
1045
1046 case 2:
1047 m_structureExtrapolatedNitscheTermsRHS.copyFrom(m_pLinStruc->vector());
1048 m_structureExtrapolatedNitscheTermsRHS.axpby(-1., 1., m_structureTimeSchemeRHSTerms);
1049 m_structureExtrapolatedNitscheTermsRHS.axpby(-1., 2. , m_structureNitscheRHSTermsOld);
1050
1051 m_structureNitscheRHSTermsOld.copyFrom(m_pLinStruc->vector());
1052 m_structureNitscheRHSTermsOld.axpby(-1., 1., m_structureTimeSchemeRHSTerms);
1053 break;
1054
1055 default:
1056 FEL_ERROR("unknown time scheme extrapolation order");
1057 break;
1058 }
1059 }
1060
1061 template<class SolidPrb>
1062 22 void FSINitscheXFEMModel<SolidPrb>::writeSolutionAndMeshes()
1063 {
1064 22 if( (m_fstransient->iteration % FelisceParam::instance().frequencyWriteSolution == 0)
1065 or m_hasFinished
1066
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 22 times.
✗ Branch 13 not taken.
22 or ( m_fstransient->iteration >= FelisceParam::instance().intervalWriteSolution[0] && m_fstransient->iteration <= FelisceParam::instance().intervalWriteSolution[1] )) {
1067
1068 // write the mesh
1069
2/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 22 times.
22 if(FelisceParam::verbose()>1)
1070 PetscPrintf(MpiInfo::petscComm(),"Write meshes\n");
1071
1072 22 std::map<felInt, std::vector<felInt> > refToListOfIds;
1073 22 std::string fileName;
1074 22 std::string indexFile;
1075
1076
2/2
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 22 times.
66 for(std::size_t ipb=0; ipb<m_linearProblem.size(); ++ipb) {
1077
2/2
✓ Branch 4 taken 77 times.
✓ Branch 5 taken 44 times.
121 for(std::size_t iUnknown=0; iUnknown<m_linearProblem[ipb]->listUnknown().size(); ++iUnknown) {
1078
1/2
✓ Branch 1 taken 77 times.
✗ Branch 2 not taken.
77 std::stringstream oss;
1079
1/2
✓ Branch 1 taken 77 times.
✗ Branch 2 not taken.
77 oss << m_indexTime;
1080
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 7 times.
77 if(m_indexTime < 10)
1081
2/4
✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 70 times.
✗ Branch 5 not taken.
70 indexFile = "0000" + oss.str();
1082
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 else if(m_indexTime < 100)
1083
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
7 indexFile = "000" + oss.str();
1084 else if(m_indexTime < 1000)
1085 indexFile = "00" + oss.str();
1086 else if(m_indexTime < 10000)
1087 indexFile = "0" + oss.str();
1088 else
1089 indexFile = oss.str();
1090
1091 77 int idVar = m_linearProblem[ipb]->listUnknown().idVariable(iUnknown);
1092
6/12
✓ Branch 5 taken 77 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 77 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 77 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 77 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 77 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 77 times.
✗ Branch 21 not taken.
77 fileName = FelisceParam::instance().resultDir + m_linearProblem[ipb]->listVariable().listVariable()[idVar].name()+".geo."+indexFile+".geo";
1093
1094
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 33 times.
77 if(ipb == 0) {
1095 // fluid, write mesh from the support dof to see the duplication
1096
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 22 times.
44 if(iUnknown == 0) {
1097 // write the mesh only once (with the velocity, the pressure mesh is the same)
1098
2/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
22 if(FelisceParam::instance().outputFileFormat == 0)
1099
2/4
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 22 times.
✗ Branch 6 not taken.
22 m_linearProblem[ipb]->writeGeoForUnknown(iUnknown, fileName);
1100 else if(FelisceParam::instance().outputFileFormat == 1) {
1101 m_linearProblem[ipb]->writeGeoForUnknownEnsightGold(iUnknown, refToListOfIds, fileName);
1102 m_ios[0]->ensight().setRefToListOfIds(refToListOfIds);
1103 }
1104 else
1105 FEL_ERROR("Unknown output file format");
1106 }
1107 } else {
1108 // structure, write mesh from the mesh points to see the displacement
1109
2/4
✓ Branch 3 taken 33 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 33 times.
✗ Branch 9 not taken.
33 m_ios[1]->writeMesh(*m_mesh[1], fileName);
1110 }
1111 }
1112 }
1113 22 m_meshIsWritten = true;
1114 22 ++m_indexTime;
1115
1116
1117 // write the solutions
1118
2/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 22 times.
22 if(FelisceParam::verbose() > 1)
1119 PetscPrintf(MpiInfo::petscComm(),"Write solutions\n");
1120
1121 //PetscVector aux;
1122 //aux.duplicateFrom(m_linearProblem[0]->solution());
1123 //aux.copyFrom(m_linearProblem[0]->solution());
1124 //if(m_fstransient->iteration > 0)
1125 // m_linearProblem[0]->solution().copyFrom(m_bdfFluid.sol_n());
1126
1127
2/2
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 22 times.
66 for (std::size_t ipb = 0; ipb < m_linearProblem.size(); ipb++) {
1128
2/4
✓ Branch 4 taken 44 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 44 times.
✗ Branch 8 not taken.
44 m_linearProblem[ipb]->writeSolution(MpiInfo::rankProc(), m_ios, m_fstransient->time, m_fstransient->iteration);
1129 }
1130
1131 //m_linearProblem[0]->solution().copyFrom(aux);
1132 //m_linearProblem[0]->gatherSolution();
1133 //aux.destroy();
1134
1135
2/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
22 if (MpiInfo::rankProc() == 0) {
1136
2/2
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 22 times.
66 for(std::size_t iio=0; iio<m_ios.size(); ++iio) {
1137
1/2
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
44 if(m_ios[iio]->typeOutput == 1 ) // 1 : ensight
1138
1/2
✓ Branch 4 taken 44 times.
✗ Branch 5 not taken.
44 m_ios[iio]->postProcess(m_fstransient->time, 2);
1139 }
1140 }
1141 22 }
1142 22 }
1143
1144 template<class SolidPrb>
1145 20 void FSINitscheXFEMModel<SolidPrb>::updateInterfacePosition(PetscVector& disp)
1146 {
1147 20 const felInt dim = m_mesh[1]->numCoor();
1148 20 const felInt npt = m_mesh[1]->numPoints();
1149
1150
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 m_interfaceDisplacement.resize(dim * npt, 0.);
1151
1152 double* dispArray;
1153
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 disp.getArray(&dispArray);
1154
1155
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if( m_numStrucComp == 1 ) {
1156 10 auto& normals = m_mesh[1]->listNormals();
1157
1158 // displacement is scalar
1159
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 10 times.
210 for (felInt i = 0; i < npt; ++i)
1160
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 200 times.
600 for(felInt j = 0; j < dim; ++j)
1161 400 m_interfaceDisplacement[j + dim*i] = dispArray[i] * normals[i][j];
1162 } else {
1163 // displacement is a std::vector
1164
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 10 times.
210 for(felInt i = 0; i < npt; ++i)
1165
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 200 times.
600 for(felInt j = 0; j < dim; ++j)
1166 400 m_interfaceDisplacement[j + dim*i] = dispArray[j + dim*i];
1167 }
1168
1169
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 disp.restoreArray(&dispArray);
1170 20 }
1171 }
1172