Directory: | ./ |
---|---|
File: | Solver/linearProblemFSINitscheXFEMFluid.cpp |
Date: | 2024-04-14 07:32:34 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 1013 | 1358 | 74.6% |
Branches: | 926 | 2025 | 45.7% |
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: | ||
13 | // | ||
14 | |||
15 | // System includes | ||
16 | |||
17 | // External includes | ||
18 | |||
19 | // Project includes | ||
20 | #include "Solver/linearProblemFSINitscheXFEMFluid.hpp" | ||
21 | #include "Core/felisceTools.hpp" | ||
22 | #include "FiniteElement/elementVector.hpp" | ||
23 | #include "FiniteElement/elementMatrix.hpp" | ||
24 | #include "Geometry/neighFacesOfEdges.hpp" | ||
25 | |||
26 | namespace felisce { | ||
27 | 2 | LinearProblemFSINitscheXFEMFluid::LinearProblemFSINitscheXFEMFluid(): | |
28 | LinearProblem("Fictitious Domain Fluid Structure Interaction"), | ||
29 | 2 | m_viscosity(0.), | |
30 | 2 | m_density(0.), | |
31 |
18/36✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 2 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 2 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 2 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 2 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 2 times.
✗ Branch 31 not taken.
✓ Branch 35 taken 2 times.
✗ Branch 36 not taken.
✓ Branch 38 taken 2 times.
✗ Branch 39 not taken.
✓ Branch 41 taken 2 times.
✗ Branch 42 not taken.
✓ Branch 44 taken 2 times.
✗ Branch 45 not taken.
✓ Branch 47 taken 2 times.
✗ Branch 48 not taken.
✓ Branch 50 taken 2 times.
✗ Branch 51 not taken.
✓ Branch 53 taken 2 times.
✗ Branch 54 not taken.
✓ Branch 60 taken 2 times.
✗ Branch 61 not taken.
✓ Branch 63 taken 2 times.
✗ Branch 64 not taken.
|
2 | m_bdf(nullptr) { |
32 | 2 | m_isSeqVelExtrapolAllocated = false; | |
33 | 2 | m_isSeqBdfRHSAllocated = false; | |
34 | 2 | m_isSeqOriginalSolAllocated = false; | |
35 | 2 | m_isSeqRNFluidExtrapolAllocated = false; | |
36 | 2 | m_feStruc = nullptr; | |
37 | 2 | m_elemFieldTimeSchemeType = nullptr; | |
38 | 2 | m_timeSchemeType = 0; | |
39 | 2 | m_numOriginalDof = 0; | |
40 | 2 | m_useCurrentFluidSolution = false; | |
41 | |||
42 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | m_seqVelExtrapol.resize(FelisceParam::instance().orderBdfNS); |
43 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
|
4 | for(std::size_t i=0; i<m_seqVelExtrapol.size(); ++i) |
44 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
2 | m_seqVelExtrapol[i] = PetscVector::null(); |
45 | |||
46 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | m_seqBdfRHS.resize(FelisceParam::instance().orderBdfNS); |
47 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
|
4 | for(std::size_t i=0; i<m_seqBdfRHS.size(); ++i) |
48 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
2 | m_seqBdfRHS[i] = PetscVector::null(); |
49 | 2 | } | |
50 | |||
51 | 4 | LinearProblemFSINitscheXFEMFluid::~LinearProblemFSINitscheXFEMFluid() { | |
52 | 4 | m_bdf = nullptr; | |
53 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
4 | if (m_isSeqBdfRHSAllocated) { |
54 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
|
8 | for(std::size_t i=0; i<m_seqBdfRHS.size(); ++i) |
55 | 4 | m_seqBdfRHS[i].destroy(); | |
56 | 4 | m_seqBdfRHS.clear(); | |
57 | } | ||
58 | |||
59 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
4 | if (m_isSeqVelExtrapolAllocated) { |
60 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
|
8 | for(std::size_t i=0; i<m_seqVelExtrapol.size(); ++i) |
61 | 4 | m_seqVelExtrapol[i].destroy(); | |
62 | 4 | m_seqVelExtrapol.clear(); | |
63 | } | ||
64 | |||
65 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
|
16 | for(std::size_t iPt=0; iPt < m_mshPts.size(); ++iPt) { |
66 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
12 | delete m_mshPts[iPt]; |
67 | } | ||
68 | |||
69 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
|
12 | for(std::size_t iPt=0; iPt < m_subItfPts.size(); ++iPt) { |
70 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
8 | delete m_subItfPts[iPt]; |
71 | } | ||
72 | |||
73 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
4 | if (m_isSeqOriginalSolAllocated) |
74 | 4 | m_tmpSeqOriginalSol.destroy(); | |
75 | |||
76 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
|
12 | for(std::size_t i=0; i<m_solutionOld.size(); ++i) |
77 | 8 | m_solutionOld[i].destroy(); | |
78 | |||
79 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
|
12 | for(std::size_t i=0; i<m_sequentialSolutionOld.size(); ++i) |
80 | 8 | m_sequentialSolutionOld[i].destroy(); | |
81 | |||
82 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
|
12 | for(std::size_t i=0; i<m_aoOld.size(); ++i) |
83 | 8 | AODestroy(&m_aoOld[i]); | |
84 | } | ||
85 | |||
86 | 2 | void LinearProblemFSINitscheXFEMFluid::initialize(std::vector<GeometricMeshRegion::Pointer>& mesh, FelisceTransient::Pointer fstransient, MPI_Comm& comm, bool doUseSNES) { | |
87 | // calling initialize in LinearProblem | ||
88 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | LinearProblem::initialize(mesh,comm, doUseSNES); |
89 | |||
90 | // the problem | ||
91 | 2 | m_fstransient = fstransient; | |
92 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | setNumberOfMatrix(1); |
93 | |||
94 | // define variable of the linear system | ||
95 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | std::vector<PhysicalVariable> listVariable(2); |
96 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | std::vector<std::size_t> listNumComp(2); |
97 | 2 | listVariable[0] = velocity; | |
98 | 2 | listNumComp[0] = 2; // because it only works for 2d in the fluid | |
99 | 2 | listVariable[1] = pressure; | |
100 | 2 | listNumComp[1] = 1; | |
101 | |||
102 | //define unknown of the linear system. | ||
103 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_listUnknown.push_back(velocity); |
104 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_listUnknown.push_back(pressure); |
105 | |||
106 | // link between variable and unknowns | ||
107 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | definePhysicalVariable(listVariable, listNumComp); |
108 | |||
109 | // data from the data file | ||
110 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_viscosity = FelisceParam::instance().viscosity; |
111 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_density = FelisceParam::instance().density; |
112 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_useSymmetricStress = FelisceParam::instance().useSymmetricStress; |
113 | |||
114 | // get the time scheme type from the data file | ||
115 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | m_elemFieldTimeSchemeType = FelisceParam::instance().elementFieldDynamicValue("TimeSchemeType"); |
116 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if(m_elemFieldTimeSchemeType != nullptr) |
117 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_timeSchemeType = (felInt) m_elemFieldTimeSchemeType->constant(Comp1); |
118 | |||
119 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if ((m_timeSchemeType == 0) || (m_timeSchemeType == 2)) { |
120 | // Robin-Neumann scheme | ||
121 | // extrapolation order | ||
122 | ✗ | m_betaRN.resize(FelisceParam::instance().fsiRNscheme); | |
123 | ✗ | if (FelisceParam::instance().fsiRNscheme == 1){ | |
124 | ✗ | m_betaRN[0] = 1.; | |
125 | ✗ | } else if (FelisceParam::instance().fsiRNscheme == 2){ | |
126 | ✗ | m_betaRN[0] = 2.; | |
127 | ✗ | m_betaRN[1] = -1.; | |
128 | } | ||
129 | } | ||
130 | |||
131 | // sub element | ||
132 | 2 | m_numVerPerFluidElt = m_mesh[m_currentMesh]->domainDim() + 1; | |
133 | 2 | m_numVerPerSolidElt = m_mesh[m_currentMesh]->domainDim(); | |
134 | |||
135 | // create the std::vector of points for the fluid elements | ||
136 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_mshPts.resize(m_numVerPerFluidElt); |
137 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
|
8 | for(std::size_t iver=0; iver < m_mshPts.size(); ++iver) { |
138 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
12 | m_mshPts[iver] = new Point(); |
139 | } | ||
140 | |||
141 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_itfPts.resize(m_numVerPerSolidElt); |
142 | |||
143 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_subItfPts.resize(m_numVerPerSolidElt); |
144 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
|
6 | for(std::size_t iver=0; iver < m_subItfPts.size(); ++iver) { |
145 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
8 | m_subItfPts[iver] = new Point(); |
146 | } | ||
147 | 2 | } | |
148 | |||
149 | |||
150 | 2 | void LinearProblemFSINitscheXFEMFluid::addSolidVariable() { | |
151 |
2/2✓ Branch 2 taken 3 times.
✓ Branch 3 taken 2 times.
|
5 | for(std::size_t iUnknown=0; iUnknown<m_pLinStruc->listUnknown().size(); ++iUnknown) { |
152 | 3 | m_listVariable.addVariable(m_pLinStruc->listUnknown()[iUnknown], m_pLinStruc->listVariable()[m_pLinStruc->listUnknown().idVariable(iUnknown)].numComponent()); | |
153 | } | ||
154 | 2 | } | |
155 | |||
156 | |||
157 | 160 | void LinearProblemFSINitscheXFEMFluid::initPerElementType(ElementType eltType, FlagMatrixRHS flagMatrixRHS) { | |
158 | IGNORE_UNUSED_ELT_TYPE; | ||
159 | IGNORE_UNUSED_FLAG_MATRIX_RHS; | ||
160 | |||
161 | // Get id of the variables | ||
162 | 160 | m_iVelocity = m_listVariable.getVariableIdList(velocity); | |
163 | 160 | m_iPressure = m_listVariable.getVariableIdList(pressure); | |
164 | |||
165 | // Get the finite elements | ||
166 | 160 | m_feVel = m_listCurrentFiniteElement[m_iVelocity]; | |
167 | 160 | m_fePres = m_listCurrentFiniteElement[m_iPressure]; | |
168 | |||
169 | // Get the variables of the problem | ||
170 | 160 | m_velocity = &m_listVariable[m_iVelocity]; | |
171 | 160 | m_pressure = &m_listVariable[m_iPressure]; | |
172 | |||
173 | |||
174 | // Initialize the element fields | ||
175 |
2/4✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 160 times.
|
160 | if ((m_timeSchemeType == 0) || (m_timeSchemeType == 2)){ |
176 | ✗ | m_seqVelDofPts.resize(FelisceParam::instance().fsiRNscheme); | |
177 | ✗ | m_seqPreDofPts.resize(FelisceParam::instance().fsiRNscheme); | |
178 | } else { | ||
179 | 160 | m_seqVelDofPts.resize(1); | |
180 | 160 | m_seqPreDofPts.resize(1); | |
181 | } | ||
182 | 160 | m_elemFieldAdv.initialize(DOF_FIELD, *m_feVel, dimension()); | |
183 | 160 | m_elemFieldAdvDup.initialize(DOF_FIELD, *m_feVel, dimension()); | |
184 | 160 | m_elemFieldAdvTmp.initialize(DOF_FIELD, *m_feVel, dimension()); | |
185 | 160 | m_elemFieldRHS.initialize(DOF_FIELD, *m_feVel, dimension()); | |
186 | 160 | m_elemFieldRHSbdf.initialize(DOF_FIELD, *m_feVel, dimension()); | |
187 | 160 | m_elemFieldTotalPressureFormulation.initialize(QUAD_POINT_FIELD, *m_feVel, dimension()); | |
188 | 160 | m_elemFieldNormal.initialize(CONSTANT_FIELD, m_feVel->numCoor()); | |
189 | 160 | m_elemFieldNormalInit.initialize(CONSTANT_FIELD, m_feVel->numCoor()); | |
190 | 160 | m_elemFieldAux.initialize(CONSTANT_FIELD, m_feVel->numCoor()); | |
191 |
2/2✓ Branch 1 taken 160 times.
✓ Branch 2 taken 160 times.
|
320 | for(std::size_t i=0; i<m_seqVelDofPts.size(); ++i){ |
192 | 160 | m_seqVelDofPts[i].initialize(DOF_FIELD, *m_feVel, dimension()); | |
193 | 160 | m_seqPreDofPts[i].initialize(DOF_FIELD, *m_fePres, 1); | |
194 | } | ||
195 | |||
196 | // solid | ||
197 | 160 | felInt idUnknownSolid = m_pLinStruc->listUnknown().getUnknownIdList(displacement); | |
198 | 160 | felInt idVarSolid = m_pLinStruc->listUnknown().idVariable(idUnknownSolid); | |
199 | 160 | m_strucVelQuadPts.initialize(QUAD_POINT_FIELD, *m_feVel, dimension()); | |
200 | 160 | m_strucVelDofPts.initialize(DOF_FIELD, *m_feStruc, m_pLinStruc->listVariable()[idVarSolid].numComponent()); | |
201 | 160 | m_ddotComp.initialize(QUAD_POINT_FIELD, *m_fePres, 1); | |
202 | 160 | } | |
203 | |||
204 | |||
205 | ✗ | void LinearProblemFSINitscheXFEMFluid::initPerElementTypeBoundaryCondition(ElementType& eltType, FlagMatrixRHS flagMatrixRHS) { | |
206 | IGNORE_UNUSED_ELT_TYPE; | ||
207 | IGNORE_UNUSED_FLAG_MATRIX_RHS; | ||
208 | |||
209 | // get the id of the variables | ||
210 | ✗ | m_iVelocity = m_listVariable.getVariableIdList(velocity); | |
211 | ✗ | m_iPressure = m_listVariable.getVariableIdList(pressure); | |
212 | |||
213 | // Get the curvilinear finite elements | ||
214 | ✗ | m_curvFeVel = m_listCurvilinearFiniteElement[m_iVelocity]; | |
215 | ✗ | m_curvFePress = m_listCurvilinearFiniteElement[m_iPressure]; | |
216 | |||
217 | // Get the variables of the problem | ||
218 | ✗ | m_velocity = &m_listVariable[m_iVelocity]; | |
219 | ✗ | m_pressure = &m_listVariable[m_iPressure]; | |
220 | } | ||
221 | |||
222 | |||
223 | // Virtual function in linearProblem. To allocate additional setValue. For Essential boundary conditions type | ||
224 | 42 | void LinearProblemFSINitscheXFEMFluid::finalizeEssBCTransientDerivedProblem() { | |
225 | |||
226 | 42 | } | |
227 | |||
228 | |||
229 | |||
230 | 13 | void LinearProblemFSINitscheXFEMFluid::userChangePattern(int numProc, int rankProc) { | |
231 | // There may be integrals that involve the dof of the two duplicated support elements. | ||
232 | // The integrals for the ghost penalty modify also the pattern | ||
233 | // same for the face-oriented stabilization | ||
234 | (void) numProc; | ||
235 | (void) rankProc; | ||
236 | |||
237 | // definition of variables | ||
238 | felInt currentIelGeo, oppositeIelGeo; | ||
239 | felInt node1, node2; | ||
240 | felInt idVar1, idVar2; | ||
241 | felInt ielSupport, jelSupport; | ||
242 | 13 | std::vector<felInt> vecSupportCurrent, vecSupportOpposite; | |
243 | bool isAnInnerFace; | ||
244 | bool computeBothSide; | ||
245 | bool addOppositeSupportElt; | ||
246 | bool isDomainElement; | ||
247 | |||
248 | GeometricMeshRegion::ElementType eltType, eltTypeOpp; | ||
249 | felInt numEltPerLabel; | ||
250 | felInt numElement[GeometricMeshRegion::m_numTypesOfElement]; | ||
251 | felInt idByType; | ||
252 | felInt numFacesPerElement; | ||
253 | |||
254 | 13 | const std::vector<felInt>& iSupportDof = m_supportDofUnknown[0].iSupportDof(); | |
255 | 13 | const std::vector<felInt>& iEle = m_supportDofUnknown[0].iEle(); | |
256 | 13 | const std::vector<GeometricMeshRegion::ElementType>& bagDomain =m_mesh[m_currentMesh]->bagElementTypeDomain(); | |
257 | |||
258 | // the initial repartition of dof | ||
259 | 13 | felInt numDof = dof().numDof(); | |
260 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | felInt numDofByProc = numDof/MpiInfo::numProc(); |
261 | 13 | felInt numDofProc = 0; | |
262 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | felInt beginIdDofLocal = MpiInfo::rankProc()*numDofByProc; |
263 | felInt endIdDofLocal; | ||
264 | |||
265 |
3/6✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
|
13 | if(MpiInfo::rankProc() == MpiInfo::numProc()-1) { |
266 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | numDofProc = numDof - MpiInfo::rankProc()*numDofByProc; |
267 | 13 | endIdDofLocal = numDof; | |
268 | } else { | ||
269 | ✗ | numDofProc = numDofByProc; | |
270 | ✗ | endIdDofLocal = beginIdDofLocal + numDofProc; | |
271 | } | ||
272 | |||
273 | |||
274 | // the complementary pattern | ||
275 | 13 | std::vector<felInt> iCSR, jCSR; | |
276 |
1/2✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
13 | std::vector< std::set<felInt> > nodesNeighborhood(numDofProc); |
277 | |||
278 | // build the edges or faces depending on the dimension | ||
279 | // In this function, "faces" refers to either edges or faces. | ||
280 |
3/10✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
|
13 | if(FelisceParam::instance().useGhostPenalty || FelisceParam::instance().NSStabType == 1) { |
281 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | if(dimension() == 2) |
282 |
1/2✓ Branch 3 taken 13 times.
✗ Branch 4 not taken.
|
13 | m_mesh[m_currentMesh]->buildEdges(); |
283 | else | ||
284 | ✗ | m_mesh[m_currentMesh]->buildFaces(); | |
285 | } | ||
286 | |||
287 | |||
288 | |||
289 | // -------------------------------------------------------------------------- // | ||
290 | // Complementary pattern for : // | ||
291 | // - An interface with a tip inside the fluid domain | ||
292 | // - Robin-Neumann scheme (terms like u1 v2) // | ||
293 | // - ghost penalty without face-oriented stabilization (opposite element) // | ||
294 | // -------------------------------------------------------------------------- // | ||
295 | // loop over the unknowns of the problem | ||
296 |
2/2✓ Branch 1 taken 26 times.
✓ Branch 2 taken 13 times.
|
39 | for (std::size_t iUnknown1 = 0; iUnknown1 < m_listUnknown.size(); iUnknown1++) { |
297 | 26 | idVar1 = m_listUnknown.idVariable(iUnknown1); | |
298 | |||
299 | // loop over all the intersected elements | ||
300 |
1/2✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
|
26 | auto& idInterElt = m_duplicateSupportElements->getIntersectedMshElt(); |
301 |
2/2✓ Branch 4 taken 970 times.
✓ Branch 5 taken 26 times.
|
996 | for (auto ielIt = idInterElt.begin(); ielIt != idInterElt.end(); ++ielIt) { |
302 | // get the geometric id of the element and the ids of its support elements | ||
303 | 970 | currentIelGeo = ielIt->first; | |
304 |
1/2✓ Branch 3 taken 970 times.
✗ Branch 4 not taken.
|
970 | m_mesh[m_currentMesh]->getTypeElemFromIdElem(currentIelGeo, eltType, idByType); |
305 | |||
306 | 970 | isDomainElement = false; | |
307 |
2/2✓ Branch 1 taken 970 times.
✓ Branch 2 taken 970 times.
|
1940 | for(std::size_t i=0; i<bagDomain.size(); ++i) |
308 |
2/2✓ Branch 1 taken 918 times.
✓ Branch 2 taken 52 times.
|
970 | if(bagDomain[i] == eltType) |
309 | 918 | isDomainElement = true; | |
310 | |||
311 | 970 | numFacesPerElement = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second->numBdEle(); | |
312 | |||
313 |
1/2✓ Branch 2 taken 970 times.
✗ Branch 3 not taken.
|
970 | m_supportDofUnknown[iUnknown1].getIdElementSupport(currentIelGeo, vecSupportCurrent); |
314 | |||
315 | // loop over the support elements | ||
316 |
2/2✓ Branch 1 taken 1940 times.
✓ Branch 2 taken 970 times.
|
2910 | for(std::size_t ielSup=0; ielSup<vecSupportCurrent.size(); ++ielSup) { |
317 | 1940 | ielSupport = vecSupportCurrent[ielSup]; | |
318 | |||
319 | // for all support dof in this support element | ||
320 |
2/2✓ Branch 2 taken 5716 times.
✓ Branch 3 taken 1940 times.
|
7656 | for (felInt iSup = 0; iSup < m_supportDofUnknown[iUnknown1].getNumSupportDof(ielSupport); ++iSup) { |
321 | // for all component of the unknown | ||
322 |
2/2✓ Branch 2 taken 8574 times.
✓ Branch 3 taken 5716 times.
|
14290 | for (std::size_t iComp = 0; iComp < m_listVariable[idVar1].numComponent(); iComp++) { |
323 | // get the global id of the support dof | ||
324 |
1/2✓ Branch 2 taken 8574 times.
✗ Branch 3 not taken.
|
8574 | dof().loc2glob(ielSupport, iSup, idVar1, iComp, node1); |
325 | |||
326 | // If this support dof is owned by this process | ||
327 |
2/4✓ Branch 0 taken 8574 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8574 times.
✗ Branch 3 not taken.
|
8574 | if(node1 >= beginIdDofLocal && node1 < endIdDofLocal) { |
328 | // for all unknown in the linear problem | ||
329 |
2/2✓ Branch 1 taken 17148 times.
✓ Branch 2 taken 8574 times.
|
25722 | for (std::size_t iUnknown2 = 0; iUnknown2 < m_listUnknown.size(); ++iUnknown2) { |
330 | 17148 | idVar2 = m_listUnknown.idVariable(iUnknown2); | |
331 | |||
332 | // for all support element different than the ielSup | ||
333 | 17148 | std::size_t jelSup = 0; | |
334 |
2/2✓ Branch 1 taken 34296 times.
✓ Branch 2 taken 17148 times.
|
51444 | while(jelSup < vecSupportCurrent.size()) { |
335 |
2/2✓ Branch 0 taken 17148 times.
✓ Branch 1 taken 17148 times.
|
34296 | if(jelSup != ielSup) { |
336 | 17148 | jelSupport = vecSupportCurrent[jelSup]; | |
337 | |||
338 | // for all support dof in this support element | ||
339 |
2/2✓ Branch 2 taken 50820 times.
✓ Branch 3 taken 17148 times.
|
67968 | for (felInt jSup = 0; jSup < supportDofUnknown(iUnknown2).getNumSupportDof(jelSupport); ++jSup) { |
340 | // for all component of the second unknown | ||
341 |
2/2✓ Branch 2 taken 76230 times.
✓ Branch 3 taken 50820 times.
|
127050 | for (std::size_t jComp = 0; jComp < m_listVariable[idVar2].numComponent(); jComp++) { |
342 | // If the two current components are connected | ||
343 |
1/2✓ Branch 2 taken 76230 times.
✗ Branch 3 not taken.
|
76230 | felInt iConnect = dof().getNumGlobComp(iUnknown1, iComp); |
344 |
1/2✓ Branch 2 taken 76230 times.
✗ Branch 3 not taken.
|
76230 | felInt jConnect = dof().getNumGlobComp(iUnknown2, jComp); |
345 |
2/4✓ Branch 2 taken 76230 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 76230 times.
✗ Branch 5 not taken.
|
76230 | if (m_listUnknown.mask()(iConnect, jConnect) > 0) { |
346 | // get the global id of the second support dof | ||
347 |
1/2✓ Branch 2 taken 76230 times.
✗ Branch 3 not taken.
|
76230 | dof().loc2glob(jelSupport, jSup, idVar2, jComp, node2); |
348 |
2/2✓ Branch 0 taken 76074 times.
✓ Branch 1 taken 156 times.
|
76230 | if(node1 != node2) |
349 |
1/2✓ Branch 2 taken 76074 times.
✗ Branch 3 not taken.
|
76074 | nodesNeighborhood[node1].insert(node2); |
350 | } | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | 34296 | ++jelSup; | |
355 | } | ||
356 | |||
357 | // Ghost penalty but no face-oriented stabilization | ||
358 |
5/12✓ Branch 1 taken 17148 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17148 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 17148 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 17148 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 17148 times.
|
17148 | if(FelisceParam::instance().useGhostPenalty && FelisceParam::instance().NSStabType != 1 && isDomainElement) { |
359 | // loop over the boundaries of the element | ||
360 | ✗ | for(felInt iface=0; iface < numFacesPerElement; ++iface) { | |
361 | // check if this face is an inner face or a boundary | ||
362 | ✗ | oppositeIelGeo = currentIelGeo; | |
363 | ✗ | eltTypeOpp = eltType; | |
364 | ✗ | isAnInnerFace = m_mesh[m_currentMesh]->getAdjElement(eltTypeOpp, oppositeIelGeo, iface); | |
365 | |||
366 | ✗ | if(isAnInnerFace) { | |
367 | // get the support element of the opposite element | ||
368 | ✗ | supportDofUnknown(iUnknown2).getIdElementSupport(oppositeIelGeo, vecSupportOpposite); | |
369 | |||
370 | // check if the opposite element is duplicated or not | ||
371 | ✗ | if(vecSupportOpposite.size() > 1) { | |
372 | // take the element on the same side | ||
373 | ✗ | jelSupport = vecSupportOpposite[ielSup]; | |
374 | ✗ | computeBothSide = false; | |
375 | ✗ | addOppositeSupportElt = true; | |
376 | } else { | ||
377 | ✗ | jelSupport = vecSupportOpposite[0]; | |
378 | |||
379 | // the opposite element is not duplicated, check if it is on the same side | ||
380 | ✗ | std::size_t sizeCurrent = m_supportDofUnknown[0].getNumSupportDof(ielSupport); | |
381 | ✗ | std::size_t sizeOpposite = m_supportDofUnknown[0].getNumSupportDof(jelSupport); | |
382 | |||
383 | ✗ | felInt countSupportDofInCommon = 0; | |
384 | ✗ | for(std::size_t iSup1=0; iSup1<sizeCurrent; ++iSup1) { | |
385 | ✗ | for(std::size_t iSup2=0; iSup2<sizeOpposite; ++iSup2) { | |
386 | ✗ | if(iSupportDof[iEle[jelSupport] + iSup2] == iSupportDof[iEle[ielSupport] + iSup1]) { | |
387 | ✗ | ++countSupportDofInCommon; | |
388 | } | ||
389 | } | ||
390 | } | ||
391 | |||
392 | ✗ | if(countSupportDofInCommon > 1) { | |
393 | // the elements are on the same side | ||
394 | ✗ | computeBothSide = true; | |
395 | ✗ | addOppositeSupportElt = true; | |
396 | } else { | ||
397 | ✗ | computeBothSide = false; | |
398 | ✗ | addOppositeSupportElt = false; | |
399 | } | ||
400 | } | ||
401 | |||
402 | ✗ | if(addOppositeSupportElt) { | |
403 | // for all support dof in this support element | ||
404 | ✗ | for (felInt jSup = 0; jSup < supportDofUnknown(iUnknown2).getNumSupportDof(jelSupport); ++jSup) { | |
405 | // for all component of the second unknown | ||
406 | ✗ | for (std::size_t jComp = 0; jComp < m_listVariable[idVar2].numComponent(); jComp++) { | |
407 | // If the two current components are connected | ||
408 | ✗ | felInt iConnect = dof().getNumGlobComp(iUnknown1, iComp); | |
409 | ✗ | felInt jConnect = dof().getNumGlobComp(iUnknown2, jComp); | |
410 | ✗ | if (m_listUnknown.mask()(iConnect, jConnect) > 0) { | |
411 | // get the global id of the second support dof | ||
412 | ✗ | dof().loc2glob(jelSupport, jSup, idVar2, jComp, node2); | |
413 | ✗ | if(node1 != node2) { | |
414 | ✗ | nodesNeighborhood[node1].insert(node2); | |
415 | |||
416 | ✗ | if(computeBothSide) | |
417 | ✗ | nodesNeighborhood[node2].insert(node1); | |
418 | } | ||
419 | } | ||
420 | } | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | } | ||
425 | } | ||
426 | } | ||
427 | } | ||
428 | } | ||
429 | } | ||
430 | } | ||
431 | } | ||
432 | } | ||
433 | |||
434 | |||
435 | // ----------------------------------------------------- // | ||
436 | // Complementary pattern for face-oriented stabilization // | ||
437 | // ----------------------------------------------------- // | ||
438 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
✗ Branch 4 not taken.
|
13 | if(FelisceParam::instance().NSStabType == 1) { |
439 | // loop on the unknown of the linear problem | ||
440 |
2/2✓ Branch 1 taken 26 times.
✓ Branch 2 taken 13 times.
|
39 | for (std::size_t iUnknown1 = 0; iUnknown1 < m_listUnknown.size(); ++iUnknown1) { |
441 | 26 | idVar1 = m_listUnknown.idVariable(iUnknown1); | |
442 | 26 | currentIelGeo = 0; | |
443 | |||
444 | // first loop on element type | ||
445 |
2/2✓ Branch 4 taken 26 times.
✓ Branch 5 taken 26 times.
|
52 | for (std::size_t i=0; i<m_mesh[m_currentMesh]->bagElementTypeDomain().size(); ++i) { |
446 | 26 | eltType = m_mesh[m_currentMesh]->bagElementTypeDomain()[i]; | |
447 | 26 | const GeoElement* geoEle = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second; | |
448 | 26 | numElement[eltType] = 0; | |
449 | 26 | numFacesPerElement = geoEle->numBdEle(); | |
450 | |||
451 | // second loop on region of the mesh. | ||
452 |
2/2✓ Branch 8 taken 26 times.
✓ Branch 9 taken 26 times.
|
52 | for(auto itRef = m_mesh[m_currentMesh]->intRefToBegEndMaps[eltType].begin(); itRef !=m_mesh[m_currentMesh]->intRefToBegEndMaps[eltType].end(); itRef++) { |
453 | 26 | numEltPerLabel = itRef->second.second; | |
454 | |||
455 | // Third loop on element | ||
456 |
2/2✓ Branch 0 taken 88972 times.
✓ Branch 1 taken 26 times.
|
88998 | for (felInt iel = 0; iel < numEltPerLabel; iel++) { |
457 |
1/2✓ Branch 2 taken 88972 times.
✗ Branch 3 not taken.
|
88972 | m_supportDofUnknown[iUnknown1].getIdElementSupport(eltType, numElement[eltType], vecSupportCurrent); |
458 | |||
459 |
2/2✓ Branch 1 taken 89890 times.
✓ Branch 2 taken 88972 times.
|
178862 | for(std::size_t ielSup=0; ielSup<vecSupportCurrent.size(); ++ielSup) { |
460 | 89890 | ielSupport = vecSupportCurrent[ielSup]; | |
461 | |||
462 | // for all support dof in this support element | ||
463 |
2/2✓ Branch 2 taken 269670 times.
✓ Branch 3 taken 89890 times.
|
359560 | for (felInt iSup = 0; iSup < m_supportDofUnknown[iUnknown1].getNumSupportDof(ielSupport); ++iSup) { |
464 | // for all component of the unknown | ||
465 |
2/2✓ Branch 2 taken 404505 times.
✓ Branch 3 taken 269670 times.
|
674175 | for (std::size_t iComp = 0; iComp < m_listVariable[idVar1].numComponent(); iComp++) { |
466 | // get the global id of the support dof | ||
467 |
1/2✓ Branch 2 taken 404505 times.
✗ Branch 3 not taken.
|
404505 | dof().loc2glob(ielSupport, iSup, idVar1, iComp, node1); |
468 | |||
469 | // if this node is on this process | ||
470 |
2/4✓ Branch 0 taken 404505 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 404505 times.
✗ Branch 3 not taken.
|
404505 | if(node1 >= beginIdDofLocal && node1 < endIdDofLocal) { |
471 | // loop over the boundaries of the element | ||
472 |
2/2✓ Branch 0 taken 1213515 times.
✓ Branch 1 taken 404505 times.
|
1618020 | for(felInt iface=0; iface < numFacesPerElement; ++iface) { |
473 | // check if this face is an inner face or a boundary | ||
474 | 1213515 | oppositeIelGeo = currentIelGeo; | |
475 | 1213515 | eltTypeOpp = eltType; | |
476 |
1/2✓ Branch 3 taken 1213515 times.
✗ Branch 4 not taken.
|
1213515 | isAnInnerFace = m_mesh[m_currentMesh]->getAdjElement(eltTypeOpp, oppositeIelGeo, iface); |
477 | |||
478 |
2/2✓ Branch 0 taken 1190349 times.
✓ Branch 1 taken 23166 times.
|
1213515 | if(isAnInnerFace) { |
479 | // for all unknown | ||
480 |
2/2✓ Branch 1 taken 2380698 times.
✓ Branch 2 taken 1190349 times.
|
3571047 | for (std::size_t iUnknown2 = 0; iUnknown2 < m_listUnknown.size(); ++iUnknown2) { |
481 | 2380698 | idVar2 = m_listUnknown.idVariable(iUnknown2); | |
482 | |||
483 | // get the support element of the opposite element | ||
484 |
1/2✓ Branch 2 taken 2380698 times.
✗ Branch 3 not taken.
|
2380698 | supportDofUnknown(iUnknown2).getIdElementSupport(oppositeIelGeo, vecSupportOpposite); |
485 | |||
486 | // check if the opposite element and the current element are both duplicated | ||
487 |
2/2✓ Branch 2 taken 2354508 times.
✓ Branch 3 taken 26190 times.
|
2380698 | if(vecSupportCurrent.size() == vecSupportOpposite.size()) { |
488 | // take the element on the same side | ||
489 | 2354508 | jelSupport = vecSupportOpposite[ielSup]; | |
490 | 2354508 | addOppositeSupportElt = true; | |
491 | } else { | ||
492 | 26190 | addOppositeSupportElt = false; | |
493 | 26190 | jelSupport = -1; | |
494 |
6/6✓ Branch 1 taken 34920 times.
✓ Branch 2 taken 21672 times.
✓ Branch 3 taken 30402 times.
✓ Branch 4 taken 4518 times.
✓ Branch 5 taken 30402 times.
✓ Branch 6 taken 26190 times.
|
56592 | for(std::size_t jelSup=0; jelSup < vecSupportOpposite.size() && !addOppositeSupportElt; ++jelSup) { |
495 | 30402 | jelSupport = vecSupportOpposite[jelSup]; | |
496 | |||
497 | // the opposite element is not duplicated, check if it is on the same side | ||
498 | 30402 | std::size_t sizeCurrent = m_supportDofUnknown[0].getNumSupportDof(ielSupport); | |
499 | 30402 | std::size_t sizeOpposite = m_supportDofUnknown[0].getNumSupportDof(jelSupport); | |
500 | |||
501 | 30402 | felInt countSupportDofInCommon = 0; | |
502 |
2/2✓ Branch 0 taken 91206 times.
✓ Branch 1 taken 30402 times.
|
121608 | for(std::size_t iSup1=0; iSup1<sizeCurrent; ++iSup1) { |
503 |
2/2✓ Branch 0 taken 273618 times.
✓ Branch 1 taken 91206 times.
|
364824 | for(std::size_t iSup2=0; iSup2<sizeOpposite; ++iSup2) { |
504 |
2/2✓ Branch 4 taken 36324 times.
✓ Branch 5 taken 237294 times.
|
273618 | if(iSupportDof[iEle[jelSupport] + iSup2] == iSupportDof[iEle[ielSupport] + iSup1]) { |
505 | 36324 | ++countSupportDofInCommon; | |
506 | } | ||
507 | } | ||
508 | } | ||
509 | |||
510 |
2/2✓ Branch 0 taken 17460 times.
✓ Branch 1 taken 12942 times.
|
30402 | if(countSupportDofInCommon > 1) |
511 | 17460 | addOppositeSupportElt = true; | |
512 | } | ||
513 | } | ||
514 | |||
515 |
2/2✓ Branch 0 taken 2371968 times.
✓ Branch 1 taken 8730 times.
|
2380698 | if(addOppositeSupportElt) { |
516 | // for all support dof in this support element | ||
517 |
2/2✓ Branch 2 taken 7115904 times.
✓ Branch 3 taken 2371968 times.
|
9487872 | for (felInt jSup = 0; jSup < supportDofUnknown(iUnknown2).getNumSupportDof(jelSupport); ++jSup) { |
518 | // for all component of the second unknown | ||
519 |
2/2✓ Branch 2 taken 10673856 times.
✓ Branch 3 taken 7115904 times.
|
17789760 | for (std::size_t jComp = 0; jComp < m_listVariable[idVar2].numComponent(); jComp++) { |
520 | // If the two current components are connected | ||
521 |
1/2✓ Branch 2 taken 10673856 times.
✗ Branch 3 not taken.
|
10673856 | felInt iConnect = dof().getNumGlobComp(iUnknown1, iComp); |
522 |
1/2✓ Branch 2 taken 10673856 times.
✗ Branch 3 not taken.
|
10673856 | felInt jConnect = dof().getNumGlobComp(iUnknown2, jComp); |
523 |
2/4✓ Branch 2 taken 10673856 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10673856 times.
✗ Branch 5 not taken.
|
10673856 | if (m_listUnknown.mask()(iConnect, jConnect) > 0) { |
524 | // get the global id of the second support dof | ||
525 |
1/2✓ Branch 2 taken 10673856 times.
✗ Branch 3 not taken.
|
10673856 | dof().loc2glob(jelSupport, jSup, idVar2, jComp, node2); |
526 |
2/2✓ Branch 0 taken 9883200 times.
✓ Branch 1 taken 790656 times.
|
10673856 | if(node1 != node2) |
527 |
1/2✓ Branch 2 taken 9883200 times.
✗ Branch 3 not taken.
|
9883200 | nodesNeighborhood[node1].insert(node2); |
528 | } | ||
529 | } | ||
530 | } | ||
531 | } | ||
532 | } | ||
533 | } | ||
534 | } | ||
535 | } | ||
536 | } | ||
537 | } | ||
538 | } | ||
539 | 88972 | ++currentIelGeo; | |
540 | 88972 | ++numElement[eltType]; | |
541 | } | ||
542 | } | ||
543 | } | ||
544 | } | ||
545 | } | ||
546 | |||
547 | |||
548 | // ----------------------------------------------------------------- // | ||
549 | // build the complementary pattern and merge it with the current one // | ||
550 | // ----------------------------------------------------------------- // | ||
551 | 13 | felInt dofSize = 0; | |
552 | felInt pos; | ||
553 | |||
554 |
1/2✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
13 | iCSR.resize(dof().pattern().numRows() + 1, 0); |
555 |
2/2✓ Branch 1 taken 72045 times.
✓ Branch 2 taken 13 times.
|
72058 | for(std::size_t iNode=0; iNode<nodesNeighborhood.size(); ++iNode) |
556 | 72045 | dofSize += nodesNeighborhood[iNode].size(); | |
557 | |||
558 |
1/2✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
|
13 | if(dofSize > 0) { |
559 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | jCSR.resize(dofSize, 0); |
560 |
2/2✓ Branch 1 taken 72045 times.
✓ Branch 2 taken 13 times.
|
72058 | for(std::size_t iNode=0; iNode<nodesNeighborhood.size(); ++iNode) { |
561 | 72045 | iCSR[iNode + 1] = iCSR[iNode] + nodesNeighborhood[iNode].size(); | |
562 | 72045 | pos = 0; | |
563 |
2/2✓ Branch 5 taken 2604318 times.
✓ Branch 6 taken 72045 times.
|
2676363 | for (auto it=nodesNeighborhood[iNode].begin(); it != nodesNeighborhood[iNode].end(); ++it) { |
564 | 2604318 | jCSR[iCSR[iNode] + pos] = *it; | |
565 | 2604318 | ++pos; | |
566 | } | ||
567 | } | ||
568 | |||
569 | // Now, call merge pattern | ||
570 |
1/2✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
13 | dof().mergeGlobalPattern(iCSR, jCSR); |
571 | } | ||
572 | 13 | } | |
573 | |||
574 | |||
575 | |||
576 | 141128 | void LinearProblemFSINitscheXFEMFluid::computeElementArray(const std::vector<Point*>& elemPoint, const std::vector<felInt>& elemIdPoint, felInt& iel1, felInt& iel2, ElementType& eltType, felInt& ielGeo, FlagMatrixRHS flagMatrixRHS) { | |
577 | IGNORE_UNUSED_FLAG_MATRIX_RHS; | ||
578 | IGNORE_UNUSED_ELT_TYPE; | ||
579 | IGNORE_UNUSED_ELEM_ID_POINT; | ||
580 | |||
581 | 141128 | std::vector<felInt> strucElemIds; | |
582 | |||
583 | // get the side of the support element | ||
584 | // here iel2 is refering to the solution because it will std::set the column in the global matrix | ||
585 | // (see the function setValueMatrixRHS in linearProblem.cpp) | ||
586 | sideOfInterface sideOfSupportElementForSolution; | ||
587 | double side; | ||
588 | felInt ielSupportDof; | ||
589 |
1/2✓ Branch 2 taken 141128 times.
✗ Branch 3 not taken.
|
141128 | m_supportDofUnknown[0].getIdElementSupport(ielGeo, ielSupportDof); |
590 |
2/2✓ Branch 0 taken 138296 times.
✓ Branch 1 taken 2832 times.
|
141128 | sideOfSupportElementForSolution = ielSupportDof == iel2 ? LEFT : RIGHT; |
591 |
2/2✓ Branch 0 taken 138296 times.
✓ Branch 1 taken 2832 times.
|
141128 | side = sideOfSupportElementForSolution == LEFT ? 1. : -1.; |
592 | |||
593 |
2/2✓ Branch 0 taken 138296 times.
✓ Branch 1 taken 2832 times.
|
141128 | if(iel1 == iel2) { |
594 | ////////////////////////////////// | ||
595 | // VOLUME ELEMENT - SUB ELEMENT // | ||
596 | ////////////////////////////////// | ||
597 |
1/2✓ Branch 1 taken 138296 times.
✗ Branch 2 not taken.
|
138296 | felInt numSubElement = m_duplicateSupportElements->getNumSubMshEltPerMshElt(ielGeo); |
598 | |||
599 | |||
600 | // ------------------------------------------- | ||
601 | // Get the support element of the old solutions | ||
602 |
1/2✓ Branch 3 taken 138296 times.
✗ Branch 4 not taken.
|
138296 | std::vector<felInt> ielOld(m_solutionOld.size()); |
603 |
1/2✓ Branch 3 taken 138296 times.
✗ Branch 4 not taken.
|
138296 | std::vector< std::vector<felInt> > oldSupportElement(m_solutionOld.size()); |
604 |
2/2✓ Branch 1 taken 276592 times.
✓ Branch 2 taken 138296 times.
|
414888 | for(std::size_t i=0; i<oldSupportElement.size(); ++i) { |
605 |
1/2✓ Branch 4 taken 276592 times.
✗ Branch 5 not taken.
|
276592 | m_supportDofUnknownOld[i][0].getIdElementSupport(ielGeo, oldSupportElement[i]); |
606 | |||
607 | // std::set the id for the old solution | ||
608 |
2/2✓ Branch 2 taken 5552 times.
✓ Branch 3 taken 271040 times.
|
276592 | if(oldSupportElement[i].size() > 1) { |
609 | // this element is also duplicated for the old solution | ||
610 |
2/2✓ Branch 0 taken 2844 times.
✓ Branch 1 taken 2708 times.
|
5552 | ielOld[i] = sideOfSupportElementForSolution == LEFT ? oldSupportElement[i][0] : oldSupportElement[i][1]; |
611 | } else { | ||
612 | // this element is NOT duplicated for the old solution | ||
613 | 271040 | ielOld[i] = oldSupportElement[i][0]; | |
614 | } | ||
615 | } | ||
616 | |||
617 |
2/2✓ Branch 0 taken 2832 times.
✓ Branch 1 taken 135464 times.
|
138296 | if(numSubElement > 0) { |
618 | // Volume sub elements | ||
619 | felInt subElemId; | ||
620 |
1/2✓ Branch 2 taken 2832 times.
✗ Branch 3 not taken.
|
2832 | std::vector<double> tmpPt(3); |
621 | |||
622 | // loop over the sub-elements | ||
623 |
2/2✓ Branch 0 taken 11216 times.
✓ Branch 1 taken 2832 times.
|
14048 | for(felInt iSubElt=0; iSubElt < numSubElement; ++iSubElt) { |
624 |
1/2✓ Branch 1 taken 11216 times.
✗ Branch 2 not taken.
|
11216 | subElemId = m_duplicateSupportElements->getSubMshEltIdxMsh(ielGeo, iSubElt); |
625 | |||
626 | // if the side of the sub-element is the same as the element | ||
627 |
3/4✓ Branch 1 taken 11216 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5608 times.
✓ Branch 4 taken 5608 times.
|
11216 | if(m_duplicateSupportElements->getSubMshEltSide(ielGeo, iSubElt) == sideOfSupportElementForSolution) { |
628 | // -------------------------------------------------- | ||
629 | // fill the std::vector with the points of the sub-element | ||
630 |
2/2✓ Branch 0 taken 16824 times.
✓ Branch 1 taken 5608 times.
|
22432 | for(std::size_t iPt=0; iPt < m_numVerPerFluidElt; ++iPt) { |
631 |
1/2✓ Branch 1 taken 16824 times.
✗ Branch 2 not taken.
|
16824 | m_duplicateSupportElements->getSubMshEltVerCrd(subElemId, iPt, tmpPt); |
632 | 16824 | *m_mshPts[iPt] = Point(tmpPt[0], tmpPt[1], tmpPt[2]); | |
633 | } | ||
634 | |||
635 | // --------------------- | ||
636 | // Update finite element | ||
637 |
1/2✓ Branch 1 taken 5608 times.
✗ Branch 2 not taken.
|
5608 | m_feVel->updateSubElementFirstDeriv(0, elemPoint, m_mshPts); |
638 |
1/2✓ Branch 1 taken 5608 times.
✗ Branch 2 not taken.
|
5608 | m_fePres->updateSubElementFirstDeriv(0, elemPoint, m_mshPts); |
639 | |||
640 | |||
641 | // ----------------------- | ||
642 | // build classic NS matrix | ||
643 |
1/2✓ Branch 1 taken 5608 times.
✗ Branch 2 not taken.
|
5608 | computeElementMatrixRHS(); |
644 |
3/4✓ Branch 1 taken 11216 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5608 times.
✓ Branch 4 taken 5608 times.
|
11216 | for(felInt i=0; i<FelisceParam::instance().orderBdfNS; ++i) |
645 |
1/2✓ Branch 2 taken 5608 times.
✗ Branch 3 not taken.
|
5608 | computeElementMatrixRHSPartDependingOnOldTimeStep(iel1, ielOld[i], i); |
646 | } | ||
647 | } | ||
648 | 2832 | } else { | |
649 | // No volume sub elements | ||
650 |
3/4✓ Branch 1 taken 270928 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 135464 times.
✓ Branch 4 taken 135464 times.
|
270928 | for(felInt i=0; i<FelisceParam::instance().orderBdfNS; ++i) { |
651 |
2/2✓ Branch 2 taken 48 times.
✓ Branch 3 taken 135416 times.
|
135464 | if(oldSupportElement[i].size() > 1) { |
652 | // old element is duplicated, get the sub elements | ||
653 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | felInt numSubElementOld = m_duplicateSupportElements->getNumSubMshEltMshOld(ielGeo, i); |
654 | |||
655 | felInt subElemIdOld; | ||
656 |
1/2✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
|
48 | std::vector<double> tmpPtOld(3); |
657 | felInt ielOldTmp; | ||
658 | |||
659 |
2/2✓ Branch 0 taken 144 times.
✓ Branch 1 taken 48 times.
|
192 | for(felInt iSubElt=0; iSubElt < numSubElementOld; ++iSubElt) { |
660 |
1/2✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
|
144 | subElemIdOld = m_duplicateSupportElements->getSubMshEltIdxMshOld(ielGeo, iSubElt, i); |
661 | |||
662 | // -------------------------------------------------- | ||
663 | // fill the std::vector with the points of the sub-element | ||
664 |
2/2✓ Branch 0 taken 432 times.
✓ Branch 1 taken 144 times.
|
576 | for(std::size_t iPt=0; iPt < m_numVerPerFluidElt; ++iPt) { |
665 |
1/2✓ Branch 1 taken 432 times.
✗ Branch 2 not taken.
|
432 | m_duplicateSupportElements->getSubMshEltVerCrdOld(subElemIdOld, iPt, tmpPtOld, i); |
666 | 432 | *m_mshPts[iPt] = Point(tmpPtOld[0], tmpPtOld[1], tmpPtOld[2]); | |
667 | } | ||
668 | |||
669 | // --------------------- | ||
670 | // Update finite element | ||
671 |
1/2✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
|
144 | m_feVel->updateSubElementFirstDeriv(0, elemPoint, m_mshPts); |
672 |
1/2✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
|
144 | m_fePres->updateSubElementFirstDeriv(0, elemPoint, m_mshPts); |
673 | |||
674 | |||
675 | // -------------------------------------------------------- | ||
676 | // Get the id of the support element owning the sub element | ||
677 |
3/4✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
✓ Branch 4 taken 64 times.
|
144 | ielOldTmp = m_duplicateSupportElements->getSubMshEltSideOld(subElemIdOld, i) == LEFT ? oldSupportElement[i][0] : oldSupportElement[i][1]; |
678 | |||
679 | |||
680 | // ----------------------- | ||
681 | // build classic NS matrix | ||
682 |
1/2✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
|
144 | computeElementMatrixRHSPartDependingOnOldTimeStep(iel1, ielOldTmp, i); |
683 | } | ||
684 | 48 | } | |
685 | } | ||
686 | |||
687 | // Update finite element if needed | ||
688 |
5/6✓ Branch 1 taken 134104 times.
✓ Branch 2 taken 1360 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 134104 times.
✓ Branch 6 taken 1360 times.
✓ Branch 7 taken 134104 times.
|
135464 | if(!m_feVel->hasOriginalQuadPoint() || !m_fePres->hasOriginalQuadPoint()) { |
689 |
1/2✓ Branch 1 taken 1360 times.
✗ Branch 2 not taken.
|
1360 | m_feVel->updateBasisAndFirstDeriv(0, elemPoint); |
690 |
1/2✓ Branch 1 taken 1360 times.
✗ Branch 2 not taken.
|
1360 | m_fePres->updateBasisAndFirstDeriv(0, elemPoint); |
691 | } else { | ||
692 |
1/2✓ Branch 1 taken 134104 times.
✗ Branch 2 not taken.
|
134104 | m_feVel->updateFirstDeriv(0, elemPoint); |
693 |
1/2✓ Branch 1 taken 134104 times.
✗ Branch 2 not taken.
|
134104 | m_fePres->updateFirstDeriv(0, elemPoint); |
694 | } | ||
695 | |||
696 | // build classic NS matrix | ||
697 |
1/2✓ Branch 1 taken 135464 times.
✗ Branch 2 not taken.
|
135464 | computeElementMatrixRHS(); |
698 | |||
699 | // build matrix and rhs depending on old time step if this element is not intersected | ||
700 | // by the old solutions | ||
701 |
3/4✓ Branch 1 taken 270928 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 135464 times.
✓ Branch 4 taken 135464 times.
|
270928 | for(felInt i=0; i<FelisceParam::instance().orderBdfNS; ++i) { |
702 |
2/2✓ Branch 2 taken 135416 times.
✓ Branch 3 taken 48 times.
|
135464 | if(oldSupportElement[i].size() == 1) |
703 |
1/2✓ Branch 2 taken 135416 times.
✗ Branch 3 not taken.
|
135416 | computeElementMatrixRHSPartDependingOnOldTimeStep(iel1, ielOld[i], i); |
704 | } | ||
705 | } | ||
706 | |||
707 | |||
708 | |||
709 | //////////////////////////// | ||
710 | // SUB STRUCTURE ELEMENTS // | ||
711 | //////////////////////////// | ||
712 |
1/2✓ Branch 1 taken 138296 times.
✗ Branch 2 not taken.
|
138296 | numSubElement = m_duplicateSupportElements->getNumSubItfEltPerMshElt(ielGeo); |
713 |
2/2✓ Branch 0 taken 2832 times.
✓ Branch 1 taken 135464 times.
|
138296 | if(numSubElement > 0) { |
714 | felInt subElemId; | ||
715 | felInt elemId; | ||
716 |
1/2✓ Branch 2 taken 2832 times.
✗ Branch 3 not taken.
|
2832 | std::vector<double> tmpPt(3); |
717 |
1/2✓ Branch 3 taken 2832 times.
✗ Branch 4 not taken.
|
2832 | std::vector<double> itfNormal(dimension(),0); |
718 |
1/2✓ Branch 3 taken 2832 times.
✗ Branch 4 not taken.
|
2832 | std::vector<double> itfNormalInit(dimension(),0); |
719 | |||
720 |
2/2✓ Branch 0 taken 4112 times.
✓ Branch 1 taken 2832 times.
|
6944 | for(felInt iSubElt=0; iSubElt < numSubElement; ++iSubElt) { |
721 | // get the id of the sub element | ||
722 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | subElemId = m_duplicateSupportElements->getSubItfEltIdxMsh(ielGeo, iSubElt); |
723 | |||
724 | // get the id of the element owing this sub-element | ||
725 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | elemId = m_duplicateSupportElements->getItfEltIdxOfSubItfElt(subElemId); |
726 | |||
727 | // get the normal to this sub element | ||
728 | 4112 | GeometricMeshRegion::ElementType eltTypeStruc = m_pLinStruc->mesh()->bagElementTypeDomain()[0]; | |
729 |
1/2✓ Branch 4 taken 4112 times.
✗ Branch 5 not taken.
|
4112 | m_pLinStruc->mesh()->listElementNormal(eltTypeStruc, elemId).getCoor(itfNormal); |
730 |
1/2✓ Branch 4 taken 4112 times.
✗ Branch 5 not taken.
|
4112 | m_pLinStruc->mesh()->listElementNormalInit(eltTypeStruc, elemId).getCoor(itfNormalInit); |
731 | |||
732 | // fill the std::vector with the points of the sub-element | ||
733 |
2/2✓ Branch 0 taken 8224 times.
✓ Branch 1 taken 4112 times.
|
12336 | for(std::size_t iPt=0; iPt < m_numVerPerSolidElt; ++iPt) { |
734 |
1/2✓ Branch 1 taken 8224 times.
✗ Branch 2 not taken.
|
8224 | m_duplicateSupportElements->getSubItfEltVerCrd(subElemId, iPt, tmpPt); |
735 | 8224 | *m_subItfPts[iPt] = Point(tmpPt[0], tmpPt[1], tmpPt[2]); | |
736 | } | ||
737 | |||
738 | // Get the coordinates of the element owning this sub-element | ||
739 | 4112 | int numPointsPerElt = GeometricMeshRegion::m_numPointsPerElt[eltTypeStruc]; | |
740 |
1/2✓ Branch 2 taken 4112 times.
✗ Branch 3 not taken.
|
4112 | std::vector<felInt> strucElemPtsId(numPointsPerElt); |
741 | |||
742 |
1/2✓ Branch 3 taken 4112 times.
✗ Branch 4 not taken.
|
4112 | m_pLinStruc->mesh()->getOneElement(eltTypeStruc, elemId, strucElemPtsId, 0); |
743 | |||
744 |
2/2✓ Branch 0 taken 8224 times.
✓ Branch 1 taken 4112 times.
|
12336 | for (int iPoint = 0; iPoint < numPointsPerElt; ++iPoint) |
745 | 8224 | m_itfPts[iPoint] = &m_pLinStruc->mesh()->listPoint(strucElemPtsId[iPoint]); | |
746 | |||
747 | |||
748 | // update the finite element | ||
749 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | m_feVel->updateSubElementFirstDeriv(0, elemPoint, m_subItfPts, m_feStruc); |
750 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | m_fePres->updateSubElementFirstDeriv(0, elemPoint, m_subItfPts, m_feStruc); |
751 | |||
752 | // Set element field | ||
753 |
6/8✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4112 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2056 times.
✓ Branch 6 taken 2056 times.
✓ Branch 7 taken 2056 times.
✓ Branch 8 taken 2056 times.
|
4112 | if(FelisceParam::instance().useProjectionForNitscheXFEM || m_useCurrentFluidSolution) { |
754 |
2/2✓ Branch 1 taken 2056 times.
✓ Branch 2 taken 2056 times.
|
4112 | for(std::size_t i=0; i<m_seqVelDofPts.size(); ++i){ |
755 |
2/4✓ Branch 0 taken 2056 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2056 times.
|
2056 | if ((m_timeSchemeType == 0) || (m_timeSchemeType == 2)){ |
756 | ✗ | m_seqVelDofPts[i].setValue(m_seqRNFluidExtrapol[i], *m_feVel, iel2, m_iVelocity, m_ao, dof()); | |
757 | ✗ | m_seqPreDofPts[i].setValue(m_seqRNFluidExtrapol[i], *m_fePres, iel2, m_iPressure, m_ao, dof()); | |
758 | }else{ | ||
759 |
1/2✓ Branch 4 taken 2056 times.
✗ Branch 5 not taken.
|
2056 | m_seqVelDofPts[i].setValue(sequentialSolution(), *m_feVel, iel2, m_iVelocity, m_ao, dof()); |
760 |
1/2✓ Branch 4 taken 2056 times.
✗ Branch 5 not taken.
|
2056 | m_seqPreDofPts[i].setValue(sequentialSolution(), *m_fePres, iel2, m_iPressure, m_ao, dof()); |
761 | } | ||
762 | } | ||
763 | } else { | ||
764 |
2/2✓ Branch 1 taken 2056 times.
✓ Branch 2 taken 2056 times.
|
4112 | for(std::size_t i=0; i<m_seqVelDofPts.size(); ++i){ |
765 |
1/2✓ Branch 6 taken 2056 times.
✗ Branch 7 not taken.
|
2056 | m_seqVelDofPts[i].setValue(m_sequentialSolutionOld[i], *m_feVel, ielOld[i], m_iVelocity, m_aoOld[i], m_dofOld[i]); |
766 |
1/2✓ Branch 6 taken 2056 times.
✗ Branch 7 not taken.
|
2056 | m_seqPreDofPts[i].setValue(m_sequentialSolutionOld[i], *m_fePres, ielOld[i], m_iPressure, m_aoOld[i], m_dofOld[i]); |
767 | } | ||
768 | } | ||
769 | |||
770 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | m_elemFieldNormal.setValue(itfNormal); |
771 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | m_elemFieldNormalInit.setValue(itfNormalInit); |
772 | |||
773 | |||
774 | // Inflow stabilization for NS | ||
775 |
5/10✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4112 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 4112 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4112 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4112 times.
✗ Branch 11 not taken.
|
4112 | if(FelisceParam::instance().NSequationFlag == 1 && FelisceParam::instance().useInterfaceFlowStab) { |
776 | // compute (\beta \cdot n)_- u_i v_i | ||
777 |
2/4✓ Branch 4 taken 4112 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4112 times.
✗ Branch 8 not taken.
|
4112 | m_elementMat[0]->f_dot_n_phi_i_phi_j(0.5 * side * FelisceParam::instance().density, *m_feVel, m_elemFieldAdv, m_elemFieldNormal, 0, 0, dimension(), 0); |
778 | } | ||
779 | |||
780 | // compute the elementary matrix and rhs | ||
781 |
1/6✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4112 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
4112 | switch(m_timeSchemeType) { |
782 | ✗ | case 0: { | |
783 | // Robin-Neumann schemes (direct implementation) (0th, 1st and 2nd order extrapolated variants) | ||
784 | |||
785 | // MATRIX // | ||
786 | // \rho_s \epsilon / dt \int_S u_i . v_i | ||
787 | ✗ | double penaltyParam = FelisceParam::instance().densitySolid * FelisceParam::instance().thickness / m_fstransient->timeStep; | |
788 | ✗ | m_elementMat[0]->phi_i_phi_j(penaltyParam, *m_feVel, 0, 0, dimension()); | |
789 | |||
790 | |||
791 | // RHS // | ||
792 | // update the value of the structure on that sub element (std::set m_strucVelQuadPts) | ||
793 | ✗ | updateStructureVel(elemId, externalVec(0)); | |
794 | ✗ | updateSubStructureVel(m_itfPts, m_subItfPts); | |
795 | |||
796 | // \rho_s \epsilon / dt \int_S ( ddot^{n-1} + dt \pd ddot^{\star} ) . v_i | ||
797 | ✗ | m_elementVector[0]->source(penaltyParam, *m_feVel, m_strucVelQuadPts, 0, dimension()); | |
798 | |||
799 | ✗ | for(std::size_t i=0; i<m_seqVelDofPts.size(); ++i){ | |
800 | // velocity | ||
801 | ✗ | if(m_useSymmetricStress) | |
802 | ✗ | m_elementVector[0]->eps_vec2_dot_vec1_dot_phi_i(-2. * side * m_viscosity * m_betaRN[i], m_elemFieldNormal, m_seqVelDofPts[i], *m_feVel, 0, dimension()); | |
803 | else | ||
804 | ✗ | m_elementVector[0]->grad_vec2_dot_vec1_dot_phi_i(-side * m_viscosity * m_betaRN[i], m_elemFieldNormal, m_seqVelDofPts[i], *m_feVel, 0, dimension()); | |
805 | |||
806 | // pressure | ||
807 | ✗ | for(felInt idim=0; idim<dimension(); ++idim) | |
808 | ✗ | m_elementVector[0]->source(side * m_elemFieldNormal.val(idim,0) * m_betaRN[i], *m_feVel, m_seqPreDofPts[i], idim, 1); | |
809 | } | ||
810 | |||
811 | ✗ | break; | |
812 | } | ||
813 | |||
814 | ✗ | case 1: { | |
815 | // Robin-Robin | ||
816 | // MATRIX // | ||
817 | // Nitsche's penalty term, \gamma \nu / h u_i . v_i | ||
818 | ✗ | double penaltyParam = m_viscosity*FelisceParam::instance().NitschePenaltyParam/m_feVel->diameter(); | |
819 | ✗ | m_elementMat[0]->phi_i_phi_j(penaltyParam, *m_feVel, 0, 0, dimension()); | |
820 | |||
821 | // RHS // | ||
822 | // Nitsche's consistency term in the RHS // | ||
823 | // velocity | ||
824 | ✗ | if(m_useSymmetricStress) | |
825 | ✗ | m_elementVector[0]->eps_vec2_dot_vec1_dot_phi_i(-2. * side * m_viscosity, m_elemFieldNormal, m_seqVelDofPts[0], *m_feVel, 0, dimension()); | |
826 | else | ||
827 | ✗ | m_elementVector[0]->grad_vec2_dot_vec1_dot_phi_i(-side * m_viscosity, m_elemFieldNormal, m_seqVelDofPts[0], *m_feVel, 0, dimension()); | |
828 | |||
829 | // pressure | ||
830 | ✗ | for(felInt idim=0; idim<dimension(); ++idim) | |
831 | ✗ | m_elementVector[0]->source(side * m_elemFieldNormal.val(idim,0), *m_feVel, m_seqPreDofPts[0], idim, 1); | |
832 | |||
833 | // update the value of the solid velocity (std::set m_strucVelDofPts and m_strucVelQuadPts) | ||
834 | // m_strucVelDofPts.val.clear(); | ||
835 | ✗ | updateStructureVel(elemId, externalVec(0)); | |
836 | |||
837 | // m_strucVelQuadPts.val.clear(); | ||
838 | ✗ | updateSubStructureVel(m_itfPts, m_subItfPts); | |
839 | |||
840 | // penalty term (RHS part) | ||
841 | ✗ | m_elementVector[0]->source(penaltyParam, *m_feVel, m_strucVelQuadPts, 0, dimension()); | |
842 | |||
843 | ✗ | break; | |
844 | } | ||
845 | |||
846 | ✗ | case 2: { | |
847 | // Robin-Neumann schemes a la Stenberg (0th, 1st and 2nd order extrapolated variants) | ||
848 | |||
849 | // MATRIX // | ||
850 | |||
851 | ✗ | double alpha = 0.5; | |
852 | ✗ | double RNParam = FelisceParam::instance().densitySolid * FelisceParam::instance().thickness / m_fstransient->timeStep; | |
853 | ✗ | double penaltyParam1 = (m_feVel->diameter()) / (m_viscosity*FelisceParam::instance().NitschePenaltyParam + RNParam*m_feVel->diameter()); | |
854 | ✗ | double penaltyParam2 = (FelisceParam::instance().NitschePenaltyParam*m_viscosity ) / (m_viscosity*FelisceParam::instance().NitschePenaltyParam + RNParam*m_feVel->diameter()); | |
855 | |||
856 | // + u_i . v_i | ||
857 | ✗ | m_elementMat[0]->phi_i_phi_j(alpha * penaltyParam2 * RNParam, *m_feVel, 0, 0, dimension()); | |
858 | |||
859 | // - \sigma(u_i, p_i)n_i . v_i | ||
860 | ✗ | double coef = alpha * RNParam * penaltyParam1 + (1 - alpha); | |
861 | ✗ | computeNitscheSigma_u_v(coef * side * m_viscosity, coef * -side); | |
862 | |||
863 | // - \sigma(0, -q_i)n_i . u_i (flip of sign because of the implementation of NS terms crossed with q) | ||
864 | ✗ | computeNitscheSigma_v_u(0., alpha * penaltyParam1 * RNParam * -side); | |
865 | |||
866 | // - \sigma(u_i, p_i)n_i . \sigma(0, -q_i)n_i (flip of sign because of the implementation of NS terms crossed with q) | ||
867 | ✗ | computeStenbergSigma_u_Sigma_v( m_viscosity * alpha * penaltyParam1 , - alpha * penaltyParam1 ); | |
868 | |||
869 | // RHS // | ||
870 | |||
871 | // update the value of the structure on that sub element (std::set m_strucVelQuadPts) | ||
872 | ✗ | updateStructureVel(elemId, externalVec(0)); | |
873 | ✗ | updateSubStructureVel(m_itfPts, m_subItfPts); | |
874 | |||
875 | // + (ddot^{n-1} + dt \pd ddot^{\star}) . v_i | ||
876 | ✗ | m_elementVector[0]->source(alpha * penaltyParam2 * RNParam , *m_feVel, m_strucVelQuadPts, 0, dimension()); | |
877 | |||
878 | // - (ddot^{n-1} + dt \pd ddot^{\star}) . \sigma(0, -q_i) n_i (flip of sign because of the implementation of NS terms crossed with q) | ||
879 | ✗ | computeNitscheDpoint_Sigma_v(0., -side * alpha * penaltyParam1 * RNParam); | |
880 | |||
881 | // + \sigma( u^{\star}, p^{\star})n_i . v_i | ||
882 | ✗ | for(std::size_t i=0; i<m_seqVelDofPts.size(); ++i){ | |
883 | // velocity | ||
884 | ✗ | if(m_useSymmetricStress) | |
885 | ✗ | m_elementVector[0]->eps_vec2_dot_vec1_dot_phi_i(-2. * side * m_viscosity * m_betaRN[i] * alpha * penaltyParam2 , m_elemFieldNormal, m_seqVelDofPts[i], *m_feVel, 0, dimension()); | |
886 | else | ||
887 | ✗ | m_elementVector[0]->grad_vec2_dot_vec1_dot_phi_i(-side * m_viscosity * m_betaRN[i] * alpha * penaltyParam2, m_elemFieldNormal, m_seqVelDofPts[i], *m_feVel, 0, dimension()); | |
888 | |||
889 | // pressure | ||
890 | ✗ | for(felInt idim=0; idim<dimension(); ++idim) | |
891 | ✗ | m_elementVector[0]->source(side * m_elemFieldNormal.val(idim,0) * m_betaRN[i] * alpha * penaltyParam2, *m_feVel, m_seqPreDofPts[i], idim, 1); | |
892 | } | ||
893 | |||
894 | // - \sigma( u^{\star}, p^{\star})n_i . \sigma(0, -q_i)n_i | ||
895 | ✗ | for(std::size_t i=0; i<m_seqVelDofPts.size(); ++i){ | |
896 | ✗ | std::vector<double> vec(dimension()); | |
897 | ✗ | for(felInt idim=0; idim<dimension(); ++idim){ | |
898 | ✗ | for(felInt j=0; j<dimension(); ++j){ | |
899 | ✗ | vec[j] = 2 * m_elemFieldNormal.val(j,0) * m_elemFieldNormal.val(idim,0); | |
900 | } | ||
901 | ✗ | m_elemFieldAux.setValue(vec); | |
902 | ✗ | if(m_useSymmetricStress) | |
903 | ✗ | m_elementVector[0]->eps_vec2_dot_vec1_dot_phi_i(2. * m_viscosity * m_betaRN[i] * alpha * penaltyParam1 , m_elemFieldAux, m_seqVelDofPts[i], *m_feVel, dimension(), 1); | |
904 | else | ||
905 | ✗ | m_elementVector[0]->grad_vec2_dot_vec1_dot_phi_i( m_viscosity * m_betaRN[i] * alpha * penaltyParam1 , m_elemFieldNormal, m_seqVelDofPts[i], *m_feVel, dimension(), 1); | |
906 | } | ||
907 | ✗ | m_elementVector[0]->source(- m_betaRN[i] * alpha * penaltyParam1, *m_feVel, m_seqPreDofPts[i], dimension(), 1); | |
908 | } | ||
909 | |||
910 | |||
911 | ✗ | break; | |
912 | } | ||
913 | |||
914 | 4112 | case 3: { | |
915 | /////////////////////////////// | ||
916 | // stabilize explicit scheme // | ||
917 | /////////////////////////////// | ||
918 | |||
919 | // update the value of the solid velocity (std::set m_strucVelDofPts and m_strucVelQuadPts) | ||
920 |
1/2✓ Branch 2 taken 4112 times.
✗ Branch 3 not taken.
|
4112 | updateStructureVel(elemId, externalVec(0)); |
921 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | updateSubStructureVel(m_itfPts, m_subItfPts); |
922 | |||
923 |
2/4✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4112 times.
|
4112 | if(FelisceParam::instance().usePenaltyFreeNitscheMethod) { |
924 | ✗ | double pressureStabilization = 1./FelisceParam::instance().NitschePenaltyParam; | |
925 | |||
926 | /*** MATRIX ***/ | ||
927 | // Nitsche's consistency terms, \sigma(v_i, q_i)n_i . u_i - \sigma(u_i, p_i)n_i . v_i | ||
928 | ✗ | computeNitscheSigma_u_v(side * m_viscosity, -side); | |
929 | ✗ | computeNitscheSigma_v_u(-side * m_viscosity, -side); | |
930 | |||
931 | // stabilization of the coupling with the structure | ||
932 | // m_elementMat[0]->phi_i_phi_j(-pressureStabilization * m_feVel->diameter() / m_viscosity, *m_fePres, dimension(), dimension(), 1); | ||
933 | ✗ | computeNitscheSigma_u_Sigma_v(pressureStabilization * m_feVel->diameter() / m_viscosity); | |
934 | |||
935 | /*** RHS ***/ | ||
936 | // -ddot \sigma(v_i, q_i) n_i // | ||
937 | ✗ | computeNitscheDpoint_Sigma_v(-side * m_viscosity, -side); | |
938 | |||
939 | // stabilization of the coupling with the structure | ||
940 | // m_elementVector[0]->source(-pressureStabilization * m_feVel->diameter() / m_viscosity, *m_fePres, m_seqPreDofPts[0], dimension(), 1); | ||
941 | ✗ | computeNitscheSigma_uold_Sigma_v(pressureStabilization * m_feVel->diameter() / m_viscosity); | |
942 | } else { | ||
943 | 4112 | double pressureStabilization = 1.; | |
944 |
2/4✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4112 times.
✗ Branch 5 not taken.
|
4112 | double penaltyParam = m_viscosity*FelisceParam::instance().NitschePenaltyParam/m_feVel->diameter(); |
945 | |||
946 | /*** MATRIX ***/ | ||
947 | // Nitsche's penalty term, \gamma \mu / h u_i . v_i | ||
948 |
1/2✓ Branch 4 taken 4112 times.
✗ Branch 5 not taken.
|
4112 | m_elementMat[0]->phi_i_phi_j(penaltyParam, *m_feVel, 0, 0, dimension()); |
949 | |||
950 | // Nitsche's consistency terms, - \sigma(v_i, -q_i)n_i . u_i | ||
951 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | computeNitscheSigma_v_u(0., -side); |
952 | |||
953 | // stabilization of the coupling with the structure | ||
954 |
1/2✓ Branch 5 taken 4112 times.
✗ Branch 6 not taken.
|
4112 | m_elementMat[0]->phi_i_phi_j(-pressureStabilization/penaltyParam, *m_fePres, dimension(), dimension(), 1); |
955 | |||
956 | /*** RHS ***/ | ||
957 | // penalty term, \gamma \mu / h \dot{d}^n v_i | ||
958 |
1/2✓ Branch 4 taken 4112 times.
✗ Branch 5 not taken.
|
4112 | m_elementVector[0]->source(penaltyParam, *m_feVel, m_strucVelQuadPts, 0, dimension()); |
959 | |||
960 | // ddot \sigma(v_i, -q_i) n_i // | ||
961 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | computeNitscheDpoint_Sigma_v(0., -side); |
962 | |||
963 | // stabilization of the coupling with the structure | ||
964 |
1/2✓ Branch 5 taken 4112 times.
✗ Branch 6 not taken.
|
4112 | m_elementVector[0]->source(-pressureStabilization/penaltyParam, *m_fePres, m_seqPreDofPts[0], dimension(), 1); |
965 | |||
966 | |||
967 | // RHS // | ||
968 | // Nitsche's consistency term in the RHS \sigma(u_i^{n-1}, p_i^{n-1}n_i . v_i | ||
969 | // velocity | ||
970 |
1/2✓ Branch 0 taken 4112 times.
✗ Branch 1 not taken.
|
4112 | if(m_useSymmetricStress) |
971 |
1/2✓ Branch 5 taken 4112 times.
✗ Branch 6 not taken.
|
4112 | m_elementVector[0]->eps_vec2_dot_vec1_dot_phi_i(-2. * side * m_viscosity, m_elemFieldNormal, m_seqVelDofPts[0], *m_feVel, 0, dimension()); |
972 | else | ||
973 | ✗ | m_elementVector[0]->grad_vec2_dot_vec1_dot_phi_i(-side * m_viscosity, m_elemFieldNormal, m_seqVelDofPts[0], *m_feVel, 0, dimension()); | |
974 | |||
975 | // pressure | ||
976 |
2/2✓ Branch 1 taken 8224 times.
✓ Branch 2 taken 4112 times.
|
12336 | for(felInt idim=0; idim<dimension(); ++idim) |
977 |
2/4✓ Branch 4 taken 8224 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8224 times.
✗ Branch 8 not taken.
|
8224 | m_elementVector[0]->source(side * m_elemFieldNormal.val(idim,0), *m_feVel, m_seqPreDofPts[0], idim, 1); |
978 | } | ||
979 | |||
980 | 4112 | break; | |
981 | } | ||
982 | |||
983 | ✗ | case 4: { | |
984 | // Robin-Neumann semi-implict schemes (0th, 1st and 2nd order extrapolated variants) | ||
985 | // MATRIX | ||
986 | // Nitsche's penalty term, \gamma \nu / h u_i . v_i | ||
987 | ✗ | double pressureStabilization = 1.; | |
988 | ✗ | double penaltyParam = m_viscosity*FelisceParam::instance().NitschePenaltyParam/m_feVel->diameter(); | |
989 | ✗ | m_elementMat[0]->phi_i_phi_j(penaltyParam, *m_feVel, 0, 0, dimension()); | |
990 | |||
991 | // Nitsche's consistency terms, -\sigma(u_i, p_i)n_i . v_i - \sigma(v_i, q_i)n_i . u_i | ||
992 | // u_i & v_i | ||
993 | ✗ | computeNitscheSigma_v_u(0., -side); | |
994 | |||
995 | // stabilization of the coupling with the structure | ||
996 | ✗ | m_elementMat[0]->phi_i_phi_j(-pressureStabilization/penaltyParam, *m_fePres, dimension(), dimension(), 1); | |
997 | |||
998 | // RHS // | ||
999 | // Nitsche's consistency term in the RHS // | ||
1000 | // velocity | ||
1001 | ✗ | if(m_useSymmetricStress) | |
1002 | ✗ | m_elementVector[0]->eps_vec2_dot_vec1_dot_phi_i(-2. * side * m_viscosity, m_elemFieldNormal, m_seqVelDofPts[0], *m_feVel, 0, dimension()); | |
1003 | else | ||
1004 | ✗ | m_elementVector[0]->grad_vec2_dot_vec1_dot_phi_i(-side * m_viscosity, m_elemFieldNormal, m_seqVelDofPts[0], *m_feVel, 0, dimension()); | |
1005 | |||
1006 | // pressure | ||
1007 | ✗ | for(felInt idim=0; idim<dimension(); ++idim) | |
1008 | ✗ | m_elementVector[0]->source(side * m_elemFieldNormal.val(idim,0), *m_feVel, m_seqPreDofPts[0], idim, 1); | |
1009 | |||
1010 | |||
1011 | // RHS // | ||
1012 | // Nitsche's consistency term in the RHS // | ||
1013 | |||
1014 | // update the value of the solid velocity (std::set m_strucVelDofPts and m_strucVelQuadPts) | ||
1015 | // m_strucVelDofPts.val.clear(); | ||
1016 | ✗ | updateStructureVel(elemId, m_pLinStruc->sequentialSolution()); | |
1017 | |||
1018 | // m_strucVelQuadPts.val.clear(); | ||
1019 | ✗ | updateSubStructureVel(m_itfPts, m_subItfPts); | |
1020 | |||
1021 | // penalty term (RHS part) | ||
1022 | ✗ | m_elementVector[0]->source(penaltyParam, *m_feVel, m_strucVelQuadPts, 0, dimension()); | |
1023 | |||
1024 | // ddot \sigma(v_i, q_i) n_i // | ||
1025 | // computeNitscheDpoint_Sigma_v(side * m_viscosity, -side); | ||
1026 | ✗ | computeNitscheDpoint_Sigma_v(0., -side); | |
1027 | |||
1028 | // stabilization of the coupling with the structure | ||
1029 | ✗ | m_elementVector[0]->source(-pressureStabilization/penaltyParam, *m_fePres, m_seqPreDofPts[0], dimension(), 1); | |
1030 | ✗ | break; | |
1031 | } | ||
1032 | |||
1033 | ✗ | default: { | |
1034 | ✗ | FEL_ERROR("Bad Time splitting scheme"); | |
1035 | ✗ | break; | |
1036 | } | ||
1037 | } | ||
1038 | 4112 | } | |
1039 | 2832 | } | |
1040 | 138296 | } else { | |
1041 | |||
1042 | // ------------------------------------------- | ||
1043 | // Get the support element of the old solutions | ||
1044 |
1/2✓ Branch 3 taken 2832 times.
✗ Branch 4 not taken.
|
2832 | std::vector<felInt> ielOld(m_solutionOld.size()); |
1045 |
1/2✓ Branch 3 taken 2832 times.
✗ Branch 4 not taken.
|
2832 | std::vector<felInt> ielOldDup(m_solutionOld.size()); |
1046 |
1/2✓ Branch 3 taken 2832 times.
✗ Branch 4 not taken.
|
2832 | std::vector< std::vector<felInt> > oldSupportElement(m_solutionOld.size()); |
1047 |
2/2✓ Branch 1 taken 5664 times.
✓ Branch 2 taken 2832 times.
|
8496 | for(std::size_t i=0; i<oldSupportElement.size(); ++i) { |
1048 |
1/2✓ Branch 4 taken 5664 times.
✗ Branch 5 not taken.
|
5664 | m_supportDofUnknownOld[i][0].getIdElementSupport(ielGeo, oldSupportElement[i]); |
1049 | |||
1050 | // std::set the id for the old solution | ||
1051 |
2/2✓ Branch 2 taken 5416 times.
✓ Branch 3 taken 248 times.
|
5664 | if(oldSupportElement[i].size() > 1) { |
1052 | // this element is also duplicated for the old solution | ||
1053 |
2/2✓ Branch 0 taken 2708 times.
✓ Branch 1 taken 2708 times.
|
5416 | if(sideOfSupportElementForSolution == LEFT) { |
1054 | 2708 | ielOld[i] = oldSupportElement[i][0]; | |
1055 | 2708 | ielOldDup[i] = oldSupportElement[i][1]; | |
1056 | } else { | ||
1057 | 2708 | ielOld[i] = oldSupportElement[i][1]; | |
1058 | 2708 | ielOldDup[i] = oldSupportElement[i][0]; | |
1059 | } | ||
1060 | } else { | ||
1061 | // this element is NOT duplicated for the old solution | ||
1062 | 248 | ielOld[i] = oldSupportElement[i][0]; | |
1063 | 248 | ielOldDup[i] = oldSupportElement[i][0]; | |
1064 | } | ||
1065 | } | ||
1066 | |||
1067 | //////////////////////////// | ||
1068 | // SUB STRUCTURE ELEMENTS // | ||
1069 | //////////////////////////// | ||
1070 |
1/2✓ Branch 1 taken 2832 times.
✗ Branch 2 not taken.
|
2832 | felInt numSubElement = m_duplicateSupportElements->getNumSubItfEltPerMshElt(ielGeo); |
1071 |
1/2✓ Branch 0 taken 2832 times.
✗ Branch 1 not taken.
|
2832 | if(numSubElement > 0) { |
1072 | felInt subElemId; | ||
1073 | felInt elemId; | ||
1074 |
1/2✓ Branch 2 taken 2832 times.
✗ Branch 3 not taken.
|
2832 | std::vector<double> tmpPt(3); |
1075 |
1/2✓ Branch 3 taken 2832 times.
✗ Branch 4 not taken.
|
2832 | std::vector<double> itfNormal(dimension(),0); |
1076 |
1/2✓ Branch 3 taken 2832 times.
✗ Branch 4 not taken.
|
2832 | std::vector<double> itfNormalInit(dimension(),0); |
1077 | |||
1078 | // std::set the extrapolation of velocity | ||
1079 |
1/2✓ Branch 1 taken 2832 times.
✗ Branch 2 not taken.
|
2832 | m_elemFieldAdv.val.clear(); |
1080 |
1/2✓ Branch 1 taken 2832 times.
✗ Branch 2 not taken.
|
2832 | m_elemFieldAdvDup.val.clear(); |
1081 |
2/4✓ Branch 1 taken 2832 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2832 times.
✗ Branch 4 not taken.
|
2832 | if(FelisceParam::instance().NSequationFlag == 1) { |
1082 |
2/4✓ Branch 1 taken 2832 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2832 times.
|
2832 | if(FelisceParam::instance().useProjectionForNitscheXFEM) { |
1083 | ✗ | for(felInt i=0; i<FelisceParam::instance().orderBdfNS; ++i) { | |
1084 | ✗ | m_elemFieldAdvTmp.setValue(m_seqVelExtrapol[i], *m_feVel, iel1, m_iVelocity, m_ao, dof()); | |
1085 | ✗ | m_elemFieldAdv.val += m_elemFieldAdvTmp.val; | |
1086 | ✗ | m_elemFieldAdvTmp.setValue(m_seqVelExtrapol[i], *m_feVel, iel2, m_iVelocity, m_ao, dof()); | |
1087 | ✗ | m_elemFieldAdvDup.val += m_elemFieldAdvTmp.val; | |
1088 | } | ||
1089 | } else { | ||
1090 |
3/4✓ Branch 1 taken 5664 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2832 times.
✓ Branch 4 taken 2832 times.
|
5664 | for(felInt i=0; i<FelisceParam::instance().orderBdfNS; ++i) { |
1091 |
1/2✓ Branch 5 taken 2832 times.
✗ Branch 6 not taken.
|
2832 | m_elemFieldAdvTmp.setValue(m_seqVelExtrapol[i], *m_feVel, ielOld[i], m_iVelocity, m_aoOld[i], m_dofOld[i]); |
1092 |
1/2✓ Branch 1 taken 2832 times.
✗ Branch 2 not taken.
|
2832 | m_elemFieldAdv.val += m_elemFieldAdvTmp.val; |
1093 |
1/2✓ Branch 5 taken 2832 times.
✗ Branch 6 not taken.
|
2832 | m_elemFieldAdvTmp.setValue(m_seqVelExtrapol[i], *m_feVel, ielOldDup[i], m_iVelocity, m_aoOld[i], m_dofOld[i]); |
1094 |
1/2✓ Branch 1 taken 2832 times.
✗ Branch 2 not taken.
|
2832 | m_elemFieldAdvDup.val += m_elemFieldAdvTmp.val; |
1095 | } | ||
1096 | } | ||
1097 | } | ||
1098 | |||
1099 | |||
1100 |
2/2✓ Branch 0 taken 4112 times.
✓ Branch 1 taken 2832 times.
|
6944 | for(felInt iSubElt=0; iSubElt < numSubElement; ++iSubElt) { |
1101 | // get the id of the sub element | ||
1102 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | subElemId = m_duplicateSupportElements->getSubItfEltIdxMsh(ielGeo, iSubElt); |
1103 | |||
1104 | // get the id of the element owing this sub element | ||
1105 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | elemId = m_duplicateSupportElements->getItfEltIdxOfSubItfElt(subElemId); |
1106 | |||
1107 | // get the normal to this sub element | ||
1108 | 4112 | GeometricMeshRegion::ElementType eltTypeStruc = m_pLinStruc->mesh()->bagElementTypeDomain()[0]; | |
1109 |
1/2✓ Branch 4 taken 4112 times.
✗ Branch 5 not taken.
|
4112 | m_pLinStruc->mesh()->listElementNormal(eltTypeStruc, elemId).getCoor(itfNormal); |
1110 |
1/2✓ Branch 4 taken 4112 times.
✗ Branch 5 not taken.
|
4112 | m_pLinStruc->mesh()->listElementNormalInit(eltTypeStruc, elemId).getCoor(itfNormalInit); |
1111 | |||
1112 | // fill the std::vector with the points of the sub-element | ||
1113 |
2/2✓ Branch 0 taken 8224 times.
✓ Branch 1 taken 4112 times.
|
12336 | for(std::size_t iPt=0; iPt < m_numVerPerSolidElt; ++iPt) { |
1114 |
1/2✓ Branch 1 taken 8224 times.
✗ Branch 2 not taken.
|
8224 | m_duplicateSupportElements->getSubItfEltVerCrd(subElemId, iPt, tmpPt); |
1115 | 8224 | *m_subItfPts[iPt] = Point(tmpPt[0], tmpPt[1], tmpPt[2]); | |
1116 | } | ||
1117 | |||
1118 | // Get the coordinates of the element owning this sub-element | ||
1119 | 4112 | int numPointsPerElt = GeometricMeshRegion::m_numPointsPerElt[eltTypeStruc]; | |
1120 |
1/2✓ Branch 2 taken 4112 times.
✗ Branch 3 not taken.
|
4112 | std::vector<felInt> strucElemPtsId(numPointsPerElt); |
1121 | |||
1122 |
1/2✓ Branch 3 taken 4112 times.
✗ Branch 4 not taken.
|
4112 | m_pLinStruc->mesh()->getOneElement(eltTypeStruc, elemId, strucElemPtsId, 0); |
1123 | |||
1124 |
2/2✓ Branch 0 taken 8224 times.
✓ Branch 1 taken 4112 times.
|
12336 | for (int iPoint = 0; iPoint < numPointsPerElt; ++iPoint) |
1125 | 8224 | m_itfPts[iPoint] = &m_pLinStruc->mesh()->listPoint(strucElemPtsId[iPoint]); | |
1126 | |||
1127 | |||
1128 | // update the finite element | ||
1129 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | m_feVel->updateSubElementFirstDeriv(0, elemPoint, m_subItfPts, m_feStruc); |
1130 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | m_fePres->updateSubElementFirstDeriv(0, elemPoint, m_subItfPts, m_feStruc); |
1131 | |||
1132 | // Set element field | ||
1133 |
6/8✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4112 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2056 times.
✓ Branch 6 taken 2056 times.
✓ Branch 7 taken 2056 times.
✓ Branch 8 taken 2056 times.
|
4112 | if(FelisceParam::instance().useProjectionForNitscheXFEM || m_useCurrentFluidSolution > 0) { |
1134 |
2/2✓ Branch 1 taken 2056 times.
✓ Branch 2 taken 2056 times.
|
4112 | for(std::size_t i=0; i<m_seqVelDofPts.size(); ++i){ |
1135 |
2/4✓ Branch 0 taken 2056 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2056 times.
|
2056 | if ((m_timeSchemeType == 0) || (m_timeSchemeType == 2)){ |
1136 | ✗ | m_seqVelDofPts[i].setValue(m_seqRNFluidExtrapol[i], *m_feVel, iel2, m_iVelocity, m_ao, dof()); | |
1137 | ✗ | m_seqPreDofPts[i].setValue(m_seqRNFluidExtrapol[i], *m_fePres, iel2, m_iPressure, m_ao, dof()); | |
1138 | } else { | ||
1139 |
1/2✓ Branch 4 taken 2056 times.
✗ Branch 5 not taken.
|
2056 | m_seqVelDofPts[i].setValue(sequentialSolution(), *m_feVel, iel2, m_iVelocity, m_ao, dof()); |
1140 |
1/2✓ Branch 4 taken 2056 times.
✗ Branch 5 not taken.
|
2056 | m_seqPreDofPts[i].setValue(sequentialSolution(), *m_fePres, iel2, m_iPressure, m_ao, dof()); |
1141 | } | ||
1142 | } | ||
1143 | } else { | ||
1144 |
2/2✓ Branch 1 taken 2056 times.
✓ Branch 2 taken 2056 times.
|
4112 | for(std::size_t i=0; i<m_seqVelDofPts.size(); ++i){ |
1145 |
1/2✓ Branch 6 taken 2056 times.
✗ Branch 7 not taken.
|
2056 | m_seqVelDofPts[i].setValue(m_sequentialSolutionOld[i], *m_feVel, ielOld[i], m_iVelocity, m_aoOld[i], m_dofOld[i]); |
1146 |
1/2✓ Branch 6 taken 2056 times.
✗ Branch 7 not taken.
|
2056 | m_seqPreDofPts[i].setValue(m_sequentialSolutionOld[i], *m_fePres, ielOld[i], m_iPressure, m_aoOld[i], m_dofOld[i]); |
1147 | } | ||
1148 | } | ||
1149 | |||
1150 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | m_elemFieldNormal.setValue(itfNormal); |
1151 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | m_elemFieldNormalInit.setValue(itfNormalInit); |
1152 | |||
1153 | // compute Inflow stabilization for NS equation | ||
1154 |
5/10✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4112 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 4112 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4112 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4112 times.
✗ Branch 11 not taken.
|
4112 | if(FelisceParam::instance().NSequationFlag == 1 && FelisceParam::instance().useInterfaceFlowStab) { |
1155 |
2/4✓ Branch 4 taken 4112 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4112 times.
✗ Branch 8 not taken.
|
4112 | m_elementMat[0]->f_dot_n_phi_i_phi_j(0.25 * side * FelisceParam::instance().density, *m_feVel, m_elemFieldAdv, m_elemFieldNormal, 0, 0, dimension(), 0); |
1156 |
2/4✓ Branch 4 taken 4112 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4112 times.
✗ Branch 8 not taken.
|
4112 | m_elementMat[0]->f_dot_n_phi_i_phi_j(0.25 * side * FelisceParam::instance().density, *m_feVel, m_elemFieldAdvDup, m_elemFieldNormal, 0, 0, dimension(), 0); |
1157 | } | ||
1158 | |||
1159 | // compute the elementary matrix and rhs | ||
1160 |
1/6✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4112 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
4112 | switch(m_timeSchemeType) { |
1161 | |||
1162 | ✗ | case 0: { | |
1163 | // Robin-Neumann schemes (0th, 1st and 2nd order extrapolated variants) | ||
1164 | // MATRIX // | ||
1165 | ✗ | computeNitscheSigma_u_v(-1 * side * m_viscosity, side); | |
1166 | |||
1167 | // RHS // | ||
1168 | ✗ | for(std::size_t i=0; i<m_seqVelDofPts.size(); ++i){ | |
1169 | // velocity | ||
1170 | ✗ | if(m_useSymmetricStress) | |
1171 | ✗ | m_elementVector[0]->eps_vec2_dot_vec1_dot_phi_i(-2. * side * m_viscosity * m_betaRN[i], m_elemFieldNormal, m_seqVelDofPts[i], *m_feVel, 0, dimension()); | |
1172 | else | ||
1173 | ✗ | m_elementVector[0]->grad_vec2_dot_vec1_dot_phi_i(-side * m_viscosity * m_betaRN[i], m_elemFieldNormal, m_seqVelDofPts[i], *m_feVel, 0, dimension()); | |
1174 | |||
1175 | // pressure | ||
1176 | ✗ | for(felInt idim=0; idim<dimension(); ++idim) | |
1177 | ✗ | m_elementVector[0]->source(side * m_elemFieldNormal.val(idim,0) * m_betaRN[i], *m_feVel, m_seqPreDofPts[i], idim, 1); | |
1178 | } | ||
1179 | ✗ | break; | |
1180 | } | ||
1181 | |||
1182 | ✗ | case 1: { | |
1183 | ✗ | break; | |
1184 | } | ||
1185 | |||
1186 | ✗ | case 2: { | |
1187 | // Robin-Neumann schemes a la Stenberg (0th, 1st and 2nd order extrapolated variants) | ||
1188 | |||
1189 | ✗ | double alpha = 0.5; | |
1190 | ✗ | double RNParam = FelisceParam::instance().densitySolid * FelisceParam::instance().thickness / m_fstransient->timeStep; | |
1191 | ✗ | double penaltyParam1 = (m_feVel->diameter()) / (m_viscosity*FelisceParam::instance().NitschePenaltyParam + RNParam*m_feVel->diameter()); | |
1192 | ✗ | double penaltyParam2 = (FelisceParam::instance().NitschePenaltyParam*m_viscosity ) / (m_viscosity*FelisceParam::instance().NitschePenaltyParam + RNParam*m_feVel->diameter()); | |
1193 | |||
1194 | // MATRIX // | ||
1195 | |||
1196 | // + \sigma(u_i, p_i)n_i . v_j | ||
1197 | ✗ | computeNitscheSigma_u_v(-1 * side * m_viscosity * alpha * penaltyParam2, side * alpha * penaltyParam2); | |
1198 | |||
1199 | // - \sigma(u_i, p_i)n_i . \sigma(0, -q_i)n_i | ||
1200 | ✗ | computeStenbergSigma_u_Sigma_v( -m_viscosity * alpha * penaltyParam1 , alpha * penaltyParam1 ); | |
1201 | |||
1202 | // RHS // | ||
1203 | |||
1204 | // + \sigma( u^{\star}, p^{\star})n_i . v_i | ||
1205 | ✗ | for(std::size_t i=0; i<m_seqVelDofPts.size(); ++i){ | |
1206 | // velocity | ||
1207 | ✗ | if(m_useSymmetricStress) | |
1208 | ✗ | m_elementVector[0]->eps_vec2_dot_vec1_dot_phi_i(-2. * side * m_viscosity * m_betaRN[i] * alpha * penaltyParam2 , m_elemFieldNormal, m_seqVelDofPts[i], *m_feVel, 0, dimension()); | |
1209 | else | ||
1210 | ✗ | m_elementVector[0]->grad_vec2_dot_vec1_dot_phi_i(-side * m_viscosity * m_betaRN[i] * alpha * penaltyParam2, m_elemFieldNormal, m_seqVelDofPts[i], *m_feVel, 0, dimension()); | |
1211 | |||
1212 | // pressure | ||
1213 | ✗ | for(felInt idim=0; idim<dimension(); ++idim) | |
1214 | ✗ | m_elementVector[0]->source(side * m_elemFieldNormal.val(idim,0) * m_betaRN[i] * alpha * penaltyParam2, *m_feVel, m_seqPreDofPts[i], idim, 1); | |
1215 | } | ||
1216 | |||
1217 | // - \sigma( u^{\star}, p^{\star})n_i . \sigma(0, -q_i)n_i | ||
1218 | ✗ | for(std::size_t i=0; i<m_seqVelDofPts.size(); ++i){ | |
1219 | ✗ | std::vector<double> vec(dimension()); | |
1220 | ✗ | for(felInt idim=0; idim<dimension(); ++idim){ | |
1221 | ✗ | for(felInt j=0; j<dimension(); ++j){ | |
1222 | ✗ | vec[j] = 2 * m_elemFieldNormal.val(j,0) * m_elemFieldNormal.val(idim,0); | |
1223 | } | ||
1224 | ✗ | m_elemFieldAux.setValue(vec); | |
1225 | ✗ | if(m_useSymmetricStress) | |
1226 | ✗ | m_elementVector[0]->eps_vec2_dot_vec1_dot_phi_i(-2. * m_viscosity * m_betaRN[i] * alpha * penaltyParam1 , m_elemFieldAux, m_seqVelDofPts[i], *m_feVel, dimension(), 1); | |
1227 | else | ||
1228 | ✗ | m_elementVector[0]->grad_vec2_dot_vec1_dot_phi_i( -m_viscosity * m_betaRN[i] * alpha * penaltyParam1 , m_elemFieldNormal, m_seqVelDofPts[i], *m_feVel, dimension(), 1); | |
1229 | } | ||
1230 | ✗ | m_elementVector[0]->source(m_betaRN[i] * alpha * penaltyParam1, *m_feVel, m_seqPreDofPts[i], dimension(), 1); | |
1231 | } | ||
1232 | |||
1233 | ✗ | break; | |
1234 | } | ||
1235 | |||
1236 | 4112 | case 3:{ | |
1237 | 4112 | break; | |
1238 | } | ||
1239 | |||
1240 | ✗ | case 4:{ | |
1241 | ✗ | break; | |
1242 | } | ||
1243 | |||
1244 | ✗ | default: { | |
1245 | ✗ | FEL_ERROR("Bad Time splitting scheme"); | |
1246 | ✗ | break; | |
1247 | } | ||
1248 | } | ||
1249 | 4112 | } | |
1250 | 2832 | } | |
1251 | 2832 | } | |
1252 | 141128 | } | |
1253 | |||
1254 | |||
1255 | |||
1256 | 40 | void LinearProblemFSINitscheXFEMFluid::assembleMatrixFrontPoints() { | |
1257 | // Assemble the matrix to take the crack point into account | ||
1258 | // Enforce continuity accros the fictitious interface | ||
1259 | 40 | felInt nbrVerFro = m_duplicateSupportElements->getNumFrontPoints(); | |
1260 | |||
1261 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
40 | if(nbrVerFro > 0) { |
1262 | 40 | std::vector<felInt> verFro; | |
1263 | 40 | std::vector<felInt> verFro_temp; // generic front vertex std::vector for checking multi fronts within element | |
1264 | felInt idElem; | ||
1265 | 40 | GeometricMeshRegion::ElementType eltType = m_mesh[m_currentMesh]->bagElementTypeDomain()[0]; | |
1266 | |||
1267 | 40 | felInt numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType]; | |
1268 |
1/2✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
40 | std::vector<Point*> elemPoint(numPointPerElt); |
1269 |
1/2✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
40 | std::vector<felInt> elemIdPoint(numPointPerElt, 0); |
1270 | |||
1271 | 40 | std::vector<felInt> vectorIdSupport; | |
1272 |
1/2✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
40 | std::vector<double> itfNormal(dimension(), 0.); |
1273 | |||
1274 | // define finite element | ||
1275 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | defineFiniteElement(eltType); |
1276 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | initElementArray(); |
1277 | |||
1278 | // allocate arrays for assembling the matrix | ||
1279 | 40 | FlagMatrixRHS flag = FlagMatrixRHS::only_matrix; | |
1280 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | allocateArrayForAssembleMatrixRHS(flag); |
1281 | |||
1282 | // init variables | ||
1283 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | initPerElementType(eltType, flag); |
1284 | |||
1285 |
2/2✓ Branch 0 taken 80 times.
✓ Branch 1 taken 40 times.
|
120 | for(felInt iVer=0; iVer<nbrVerFro; ++iVer) { |
1286 | // get the info on the front point | ||
1287 |
1/2✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
|
80 | m_duplicateSupportElements->getFrontPointInfo(iVer, verFro); |
1288 | |||
1289 | // get the fluid element in which the fictitious interface is | ||
1290 | 80 | idElem = verFro[1]; | |
1291 | |||
1292 | // get the support elements | ||
1293 |
1/2✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
|
80 | setElemPoint(eltType, idElem, elemPoint, elemIdPoint, vectorIdSupport); |
1294 | |||
1295 | // fill the std::vector with the points of the fictitious interface | ||
1296 | 80 | *m_subItfPts[0] = Point(m_pLinStruc->mesh()->listPoint(verFro[0])); | |
1297 | 80 | *m_subItfPts[1] = Point(m_mesh[m_currentMesh]->listPoint(verFro[2])); | |
1298 | |||
1299 | // now check if two fronts are in same element--then opposite vertex is other front) | ||
1300 |
2/2✓ Branch 0 taken 160 times.
✓ Branch 1 taken 80 times.
|
240 | for(felInt iVer2=0; iVer2<nbrVerFro; ++iVer2) { |
1301 |
2/2✓ Branch 0 taken 80 times.
✓ Branch 1 taken 80 times.
|
160 | if(iVer2!=iVer){ |
1302 |
1/2✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
|
80 | m_duplicateSupportElements->getFrontPointInfo(iVer2, verFro_temp); |
1303 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
|
80 | if(verFro[1]==verFro_temp[1]){ |
1304 | ✗ | *m_subItfPts[1] = Point(m_pLinStruc->mesh()->listPoint(verFro[2])); | |
1305 | } | ||
1306 | } | ||
1307 | } | ||
1308 | // special initial case for pre-determined crack point when nbrVerFro is 1 for one crack initially with the crack point being the same | ||
1309 | // NOTE THIS CURRENTLY ONLY WORKS FOR ONE CRACK IN A SOLID | ||
1310 |
3/8✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 80 times.
|
80 | if(FelisceParam::instance().hasCrack && nbrVerFro==1) { |
1311 | ✗ | *m_subItfPts[1] = Point(m_pLinStruc->mesh()->listPoint(verFro[2])); | |
1312 | } | ||
1313 | |||
1314 | |||
1315 | |||
1316 | // update the finite element | ||
1317 |
1/2✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
|
80 | m_feVel->updateSubElementFirstDeriv(0, elemPoint, m_subItfPts, m_feStruc); |
1318 |
1/2✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
|
80 | m_fePres->updateSubElementFirstDeriv(0, elemPoint, m_subItfPts, m_feStruc); |
1319 | |||
1320 | // compute the normal | ||
1321 | 80 | itfNormal[0] = -(m_subItfPts[1]->y() - m_subItfPts[0]->y()); | |
1322 | 80 | itfNormal[1] = m_subItfPts[1]->x() - m_subItfPts[0]->x(); | |
1323 | |||
1324 | 80 | double norm = std::sqrt(itfNormal[0]*itfNormal[0] + itfNormal[1]*itfNormal[1]); | |
1325 | 80 | itfNormal[0] /= norm; | |
1326 | 80 | itfNormal[1] /= norm; | |
1327 |
1/2✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
|
80 | m_elemFieldNormal.setValue(itfNormal); |
1328 | |||
1329 | // parameters | ||
1330 |
2/4✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
|
80 | double penaltyParam = m_viscosity*FelisceParam::instance().NitschePenaltyParam/m_feVel->diameter(); |
1331 | |||
1332 | // loop over the support elements | ||
1333 |
2/2✓ Branch 1 taken 160 times.
✓ Branch 2 taken 80 times.
|
240 | for(std::size_t iSup1=0; iSup1 < vectorIdSupport.size(); ++iSup1) { |
1334 | 160 | felInt iel1 = vectorIdSupport[iSup1]; | |
1335 |
2/2✓ Branch 1 taken 320 times.
✓ Branch 2 taken 160 times.
|
480 | for(std::size_t iSup2=0; iSup2 < vectorIdSupport.size(); ++iSup2) { |
1336 | 320 | felInt iel2 = vectorIdSupport[iSup2]; | |
1337 | |||
1338 | // clear elementary matrix | ||
1339 |
2/2✓ Branch 1 taken 320 times.
✓ Branch 2 taken 320 times.
|
640 | for (std::size_t j = 0, size = numberOfMatrices(); j < size ; j++) |
1340 |
1/2✓ Branch 3 taken 320 times.
✗ Branch 4 not taken.
|
320 | m_elementMat[j]->zero(); |
1341 | |||
1342 | |||
1343 | // get the side | ||
1344 | sideOfInterface sideOfSupportElementForSolution; | ||
1345 | double side; | ||
1346 |
2/2✓ Branch 0 taken 160 times.
✓ Branch 1 taken 160 times.
|
320 | sideOfSupportElementForSolution = iSup2 == 0 ? LEFT : RIGHT; |
1347 |
2/2✓ Branch 0 taken 160 times.
✓ Branch 1 taken 160 times.
|
320 | side = sideOfSupportElementForSolution == LEFT ? 1. : -1.; |
1348 | |||
1349 | // std::set the extrapolation of velocity | ||
1350 |
5/10✓ Branch 1 taken 320 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 320 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 320 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 320 times.
✗ Branch 11 not taken.
|
320 | if(FelisceParam::instance().NSequationFlag == 1 && FelisceParam::instance().useInterfaceFlowStab) { |
1351 | // Get the support element of the old solutions | ||
1352 |
1/2✓ Branch 3 taken 320 times.
✗ Branch 4 not taken.
|
320 | std::vector<felInt> ielOld(m_solutionOld.size()); |
1353 |
1/2✓ Branch 3 taken 320 times.
✗ Branch 4 not taken.
|
320 | std::vector<felInt> ielOldDup(m_solutionOld.size()); |
1354 |
1/2✓ Branch 3 taken 320 times.
✗ Branch 4 not taken.
|
320 | std::vector< std::vector<felInt> > oldSupportElement(m_solutionOld.size()); |
1355 |
2/2✓ Branch 1 taken 640 times.
✓ Branch 2 taken 320 times.
|
960 | for(std::size_t i=0; i<oldSupportElement.size(); ++i) { |
1356 |
1/2✓ Branch 4 taken 640 times.
✗ Branch 5 not taken.
|
640 | m_supportDofUnknownOld[i][0].getIdElementSupport(idElem, oldSupportElement[i]); |
1357 | |||
1358 | // std::set the id for the old solution | ||
1359 |
1/2✓ Branch 2 taken 640 times.
✗ Branch 3 not taken.
|
640 | if(oldSupportElement[i].size() > 1) { |
1360 | // this element is also duplicated for the old solution | ||
1361 |
2/2✓ Branch 0 taken 320 times.
✓ Branch 1 taken 320 times.
|
640 | if(sideOfSupportElementForSolution == LEFT) { |
1362 | 320 | ielOld[i] = oldSupportElement[i][0]; | |
1363 | 320 | ielOldDup[i] = oldSupportElement[i][1]; | |
1364 | } else { | ||
1365 | 320 | ielOld[i] = oldSupportElement[i][1]; | |
1366 | 320 | ielOldDup[i] = oldSupportElement[i][0]; | |
1367 | } | ||
1368 | } else { | ||
1369 | // this element is NOT duplicated for the old solution | ||
1370 | ✗ | ielOld[i] = oldSupportElement[i][0]; | |
1371 | ✗ | ielOldDup[i] = oldSupportElement[i][0]; | |
1372 | } | ||
1373 | } | ||
1374 | |||
1375 | |||
1376 |
1/2✓ Branch 1 taken 320 times.
✗ Branch 2 not taken.
|
320 | m_elemFieldAdv.val.clear(); |
1377 |
1/2✓ Branch 1 taken 320 times.
✗ Branch 2 not taken.
|
320 | m_elemFieldAdvDup.val.clear(); |
1378 |
2/4✓ Branch 1 taken 320 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 320 times.
|
320 | if(FelisceParam::instance().useProjectionForNitscheXFEM) { |
1379 | ✗ | for(felInt i=0; i<FelisceParam::instance().orderBdfNS; ++i) { | |
1380 | ✗ | m_elemFieldAdvTmp.setValue(m_seqVelExtrapol[i], *m_feVel, iel1, m_iVelocity, m_ao, dof()); | |
1381 | ✗ | m_elemFieldAdv.val += m_elemFieldAdvTmp.val; | |
1382 | ✗ | m_elemFieldAdvTmp.setValue(m_seqVelExtrapol[i], *m_feVel, iel2, m_iVelocity, m_ao, dof()); | |
1383 | ✗ | m_elemFieldAdvDup.val += m_elemFieldAdvTmp.val; | |
1384 | } | ||
1385 | } else { | ||
1386 |
3/4✓ Branch 1 taken 640 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320 times.
✓ Branch 4 taken 320 times.
|
640 | for(felInt i=0; i<FelisceParam::instance().orderBdfNS; ++i) { |
1387 |
1/2✓ Branch 5 taken 320 times.
✗ Branch 6 not taken.
|
320 | m_elemFieldAdvTmp.setValue(m_seqVelExtrapol[i], *m_feVel, ielOld[i], m_iVelocity, m_aoOld[i], m_dofOld[i]); |
1388 |
1/2✓ Branch 1 taken 320 times.
✗ Branch 2 not taken.
|
320 | m_elemFieldAdv.val += m_elemFieldAdvTmp.val; |
1389 |
1/2✓ Branch 5 taken 320 times.
✗ Branch 6 not taken.
|
320 | m_elemFieldAdvTmp.setValue(m_seqVelExtrapol[i], *m_feVel, ielOldDup[i], m_iVelocity, m_aoOld[i], m_dofOld[i]); |
1390 |
1/2✓ Branch 1 taken 320 times.
✗ Branch 2 not taken.
|
320 | m_elemFieldAdvDup.val += m_elemFieldAdvTmp.val; |
1391 | } | ||
1392 | } | ||
1393 | 320 | } | |
1394 | |||
1395 |
2/2✓ Branch 0 taken 160 times.
✓ Branch 1 taken 160 times.
|
320 | if(iSup1 == iSup2) { |
1396 | // enforce the continuity | ||
1397 | // Nitsche's penalty term, \gamma \nu / h u_i . v_i | ||
1398 |
1/2✓ Branch 4 taken 160 times.
✗ Branch 5 not taken.
|
160 | m_elementMat[0]->phi_i_phi_j(penaltyParam, *m_feVel, 0, 0, dimension()); |
1399 | |||
1400 | // Nitsche's consistency terms, -\sigma(u_i, p_i)n_i . v_i - \sigma(v_i, q_i)n_i . u_i | ||
1401 | // u_i & v_i | ||
1402 |
1/2✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
|
160 | computeNitscheSigma_u_v(0.5 * side * m_viscosity, -0.5 * side); |
1403 |
1/2✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
|
160 | computeNitscheSigma_v_u(0.5 * side * m_viscosity, -0.5 * side); |
1404 | |||
1405 | // stabilize inflow | ||
1406 |
5/10✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 160 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 160 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 160 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 160 times.
✗ Branch 11 not taken.
|
160 | if(FelisceParam::instance().NSequationFlag == 1 && FelisceParam::instance().useInterfaceFlowStab){ |
1407 | // (0.5 \rho_f \beta_1 \cdot n_2) (u_1 \cdot v_1)-(0.5 \rho_f \beta_2 \cdot n_2) (u_2 \cdot v_2) | ||
1408 |
2/4✓ Branch 4 taken 160 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 160 times.
✗ Branch 8 not taken.
|
160 | m_elementMat[0]->f_dot_n_phi_i_phi_j(0.5 * side * FelisceParam::instance().density, *m_feVel, m_elemFieldAdv, m_elemFieldNormal, 0, 0, dimension(), 0); |
1409 | } | ||
1410 | } else { | ||
1411 |
1/2✓ Branch 4 taken 160 times.
✗ Branch 5 not taken.
|
160 | m_elementMat[0]->phi_i_phi_j(-penaltyParam, *m_feVel, 0, 0, dimension()); |
1412 | |||
1413 |
1/2✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
|
160 | computeNitscheSigma_u_v(-0.5 * side * m_viscosity, 0.5 * side); |
1414 |
1/2✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
|
160 | computeNitscheSigma_v_u( 0.5 * side * m_viscosity, -0.5 * side); |
1415 | |||
1416 | // stabilize inflow | ||
1417 |
5/10✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 160 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 160 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 160 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 160 times.
✗ Branch 11 not taken.
|
160 | if(FelisceParam::instance().NSequationFlag == 1 && FelisceParam::instance().useInterfaceFlowStab) { |
1418 |
2/4✓ Branch 4 taken 160 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 160 times.
✗ Branch 8 not taken.
|
160 | m_elementMat[0]->f_dot_n_phi_i_phi_j(0.25 * side * FelisceParam::instance().density, *m_feVel, m_elemFieldAdv, m_elemFieldNormal, 0, 0, dimension(), 0); |
1419 |
2/4✓ Branch 4 taken 160 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 160 times.
✗ Branch 8 not taken.
|
160 | m_elementMat[0]->f_dot_n_phi_i_phi_j(0.25 * side * FelisceParam::instance().density, *m_feVel, m_elemFieldAdvDup, m_elemFieldNormal, 0, 0, dimension(), 0); |
1420 | } | ||
1421 | } | ||
1422 | |||
1423 | // add values of elemMat in the global matrix: matrix(0). | ||
1424 |
1/2✓ Branch 3 taken 320 times.
✗ Branch 4 not taken.
|
320 | setValueMatrixRHS(vectorIdSupport[iSup1], vectorIdSupport[iSup2], flag); |
1425 | } | ||
1426 | } | ||
1427 | } | ||
1428 | |||
1429 | // desallocate array use for assemble with petsc. | ||
1430 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | desallocateArrayForAssembleMatrixRHS(flag); |
1431 | 40 | } | |
1432 | 40 | } | |
1433 | |||
1434 | |||
1435 | |||
1436 | |||
1437 | 40 | void LinearProblemFSINitscheXFEMFluid::assembleMatrixGhostPenalty() { | |
1438 | // ------------- // | ||
1439 | // Ghost penalty // | ||
1440 | // ------------- // | ||
1441 | |||
1442 | // get the types of elements | ||
1443 | 40 | GeometricMeshRegion::ElementType eltType = m_meshLocal[m_currentMesh]->bagElementTypeDomain()[0]; | |
1444 | 40 | felInt numEdgePerType = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second->numEdge(); | |
1445 | 40 | felInt numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];; | |
1446 |
1/2✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
40 | std::vector<felInt> idOfFacesCurrent(numEdgePerType, -1); |
1447 |
1/2✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
40 | std::vector<felInt> idOfFacesOpposite(numEdgePerType, -1); |
1448 | |||
1449 | // define finite element | ||
1450 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | defineFiniteElement(eltType); |
1451 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | initElementArray(); |
1452 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | defineCurrentFiniteElementWithBd(eltType); |
1453 | |||
1454 | // allocate arrays for assembling the matrix | ||
1455 | 40 | FlagMatrixRHS flag = FlagMatrixRHS::only_matrix; | |
1456 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | allocateArrayForAssembleMatrixRHS(flag); |
1457 | |||
1458 | // init variables | ||
1459 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | initPerElementType(eltType, flag); |
1460 | 40 | m_feVelWithBd = m_listCurrentFiniteElementWithBd[m_iVelocity]; | |
1461 | |||
1462 | // get global supportDofMesh informations | ||
1463 | 40 | std::vector<felInt>& iEle = m_supportDofUnknown[0].iEle(); | |
1464 | 40 | std::vector<felInt>& iSupportDof = m_supportDofUnknown[0].iSupportDof(); | |
1465 | |||
1466 | // element informations | ||
1467 | 40 | std::pair<bool, GeometricMeshRegion::ElementType> adjElt; | |
1468 | 40 | std::vector<felInt> ielCurrentSupportElt; | |
1469 | 40 | std::vector<felInt> ielOppositeSupportElt; | |
1470 |
1/2✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
40 | std::vector<Point*> elemCurrentPoint(m_numVerPerFluidElt); |
1471 |
1/2✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
40 | std::vector<felInt> elemCurrentIdPoint(m_numVerPerFluidElt); |
1472 |
1/2✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
40 | std::vector<Point*> elemOppositePoint(m_numVerPerFluidElt); |
1473 |
1/2✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
40 | std::vector<felInt> elemOppositeIdPoint(m_numVerPerFluidElt); |
1474 | felInt currentIelGeo; | ||
1475 | felInt currentGlobalIelGeo; | ||
1476 | felInt oppositeGlobalIelGeo; | ||
1477 | felInt idCurrentSupElt; | ||
1478 | felInt idOppositeSupElt; | ||
1479 | |||
1480 | // loop over all the intersected elements | ||
1481 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | auto& idInterElt = m_duplicateSupportElements->getIntersectedMshElt(); |
1482 |
6/8✓ Branch 4 taken 1456 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 1416 times.
✓ Branch 11 taken 40 times.
✓ Branch 12 taken 1456 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1416 times.
✓ Branch 16 taken 40 times.
|
1456 | for (auto ielIt = idInterElt.begin(); ielIt != idInterElt.end() && ielIt->first < meshLocal()->numElements(eltType); ++ielIt) { |
1483 | // get the geometric id of the element and the ids of its support elements | ||
1484 | 1416 | currentIelGeo = ielIt->first; | |
1485 |
1/2✓ Branch 2 taken 1416 times.
✗ Branch 3 not taken.
|
1416 | ISLocalToGlobalMappingApply(m_mappingElem[m_currentMesh], 1, ¤tIelGeo, ¤tGlobalIelGeo); |
1486 | |||
1487 | // get all the faces of the element | ||
1488 |
1/2✓ Branch 1 taken 1416 times.
✗ Branch 2 not taken.
|
1416 | if(dimension() == 2) |
1489 |
1/2✓ Branch 3 taken 1416 times.
✗ Branch 4 not taken.
|
1416 | m_mesh[m_currentMesh]->getAllEdgeOfElement(currentGlobalIelGeo, idOfFacesCurrent); |
1490 | else | ||
1491 | ✗ | m_mesh[m_currentMesh]->getAllFaceOfElement(currentGlobalIelGeo, idOfFacesCurrent); | |
1492 | |||
1493 | // get informations on the current element | ||
1494 |
1/2✓ Branch 1 taken 1416 times.
✗ Branch 2 not taken.
|
1416 | setElemPoint(eltType, currentIelGeo, elemCurrentPoint, elemCurrentIdPoint, ielCurrentSupportElt); |
1495 | |||
1496 | // for each support elements | ||
1497 |
2/2✓ Branch 1 taken 2832 times.
✓ Branch 2 taken 1416 times.
|
4248 | for(std::size_t iSup=0; iSup<ielCurrentSupportElt.size(); ++iSup) { |
1498 |
2/2✓ Branch 0 taken 1416 times.
✓ Branch 1 taken 1416 times.
|
2832 | sideOfInterface side = iSup == 0 ? LEFT : RIGHT; |
1499 | 2832 | idCurrentSupElt = ielCurrentSupportElt[iSup]; | |
1500 | |||
1501 | // loop over all the edges of the current support element | ||
1502 |
2/2✓ Branch 1 taken 8496 times.
✓ Branch 2 taken 2832 times.
|
11328 | for(std::size_t iface=0; iface < idOfFacesCurrent.size(); ++iface) { |
1503 | 8496 | bool computeGhostPenaltyOnThisEdge = false; | |
1504 | 8496 | bool computeBothSide = false; | |
1505 | 8496 | oppositeGlobalIelGeo = currentGlobalIelGeo; | |
1506 | |||
1507 | // get the neighboor. If it exists, this is an inner edge | ||
1508 | // first = true if there is an adjacent element | ||
1509 | // second = the ElementType of the adjacent element if first is true | ||
1510 |
1/2✓ Branch 3 taken 8496 times.
✗ Branch 4 not taken.
|
8496 | adjElt = m_mesh[m_currentMesh]->getAdjElement(oppositeGlobalIelGeo, iface); |
1511 | |||
1512 |
2/2✓ Branch 0 taken 8336 times.
✓ Branch 1 taken 160 times.
|
8496 | if(adjElt.first) { |
1513 | // This edge is an inner edge | ||
1514 | // get information on the opposite element | ||
1515 |
1/2✓ Branch 2 taken 8336 times.
✗ Branch 3 not taken.
|
8336 | m_supportDofUnknown[0].getIdElementSupport(oppositeGlobalIelGeo, ielOppositeSupportElt); |
1516 |
1/2✓ Branch 3 taken 8336 times.
✗ Branch 4 not taken.
|
8336 | m_mesh[m_currentMesh]->getOneElement(oppositeGlobalIelGeo, elemOppositeIdPoint); |
1517 |
2/2✓ Branch 0 taken 25008 times.
✓ Branch 1 taken 8336 times.
|
33344 | for (felInt iPoint=0; iPoint<numPointPerElt; ++iPoint) |
1518 | 25008 | elemOppositePoint[iPoint] = &(m_mesh[m_currentMesh]->listPoints()[elemOppositeIdPoint[iPoint]]); | |
1519 | |||
1520 | |||
1521 | 8336 | idOppositeSupElt = ielOppositeSupportElt[0]; | |
1522 |
2/2✓ Branch 1 taken 5344 times.
✓ Branch 2 taken 2992 times.
|
8336 | if(ielOppositeSupportElt.size() == 2) { |
1523 | // the other element is also duplicated, take the one on the same side | ||
1524 | 5344 | computeGhostPenaltyOnThisEdge = true; | |
1525 |
2/2✓ Branch 0 taken 2672 times.
✓ Branch 1 taken 2672 times.
|
5344 | idOppositeSupElt = side == LEFT ? ielOppositeSupportElt[0] : ielOppositeSupportElt[1]; |
1526 | } else { | ||
1527 | // the other element is not duplicated, nothing to do if it is not on the same side | ||
1528 | 2992 | std::size_t sizeCurrent = m_supportDofUnknown[0].getNumSupportDof(idCurrentSupElt); | |
1529 | 2992 | std::size_t sizeOpposite = m_supportDofUnknown[0].getNumSupportDof(idOppositeSupElt); | |
1530 | |||
1531 | 2992 | felInt countSupportDofInCommon = 0; | |
1532 |
2/2✓ Branch 0 taken 8976 times.
✓ Branch 1 taken 2992 times.
|
11968 | for(std::size_t iSup1=0; iSup1<sizeCurrent; ++iSup1) { |
1533 |
2/2✓ Branch 0 taken 26928 times.
✓ Branch 1 taken 8976 times.
|
35904 | for(std::size_t iSup2=0; iSup2<sizeOpposite; ++iSup2) { |
1534 |
2/2✓ Branch 5 taken 3152 times.
✓ Branch 6 taken 23776 times.
|
26928 | if(iSupportDof[iEle[ielOppositeSupportElt[0]] + iSup2] == iSupportDof[iEle[idCurrentSupElt] + iSup1]) { |
1535 | 3152 | ++countSupportDofInCommon; | |
1536 | } | ||
1537 | } | ||
1538 | } | ||
1539 | |||
1540 |
2/2✓ Branch 0 taken 1496 times.
✓ Branch 1 taken 1496 times.
|
2992 | if(countSupportDofInCommon > 1) { |
1541 | // the elements are on the same side | ||
1542 | 1496 | idOppositeSupElt = ielOppositeSupportElt[0]; | |
1543 | 1496 | computeGhostPenaltyOnThisEdge = true; | |
1544 | 1496 | computeBothSide = true; | |
1545 | } | ||
1546 | } | ||
1547 | |||
1548 | // add the contribution of this edge | ||
1549 |
2/2✓ Branch 0 taken 6840 times.
✓ Branch 1 taken 1496 times.
|
8336 | if(computeGhostPenaltyOnThisEdge) { |
1550 | // finite element with boundary for the opposite element | ||
1551 | 6840 | const GeoElement *geoEle = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second; | |
1552 | 6840 | felInt typeOfFiniteElement = m_velocity->finiteElementType(); | |
1553 |
1/2✓ Branch 3 taken 6840 times.
✗ Branch 4 not taken.
|
6840 | const RefElement *refEle = geoEle->defineFiniteEle(eltType, typeOfFiniteElement, *m_meshLocal[m_currentMesh]); |
1554 |
1/2✓ Branch 3 taken 6840 times.
✗ Branch 4 not taken.
|
6840 | CurrentFiniteElementWithBd oppositeEltFEWithBd(*refEle, *geoEle, m_velocity->degreeOfExactness(), m_velocity->degreeOfExactness()); |
1555 | |||
1556 | |||
1557 | // update the finite elements | ||
1558 |
1/2✓ Branch 1 taken 6840 times.
✗ Branch 2 not taken.
|
6840 | m_feVelWithBd->updateFirstDeriv(0, elemCurrentPoint); |
1559 |
1/2✓ Branch 1 taken 6840 times.
✗ Branch 2 not taken.
|
6840 | m_feVelWithBd->updateBdMeasNormal(); |
1560 |
1/2✓ Branch 1 taken 6840 times.
✗ Branch 2 not taken.
|
6840 | oppositeEltFEWithBd.updateFirstDeriv(0, elemOppositePoint); |
1561 |
1/2✓ Branch 1 taken 6840 times.
✗ Branch 2 not taken.
|
6840 | oppositeEltFEWithBd.updateBdMeasNormal(); |
1562 | |||
1563 | |||
1564 | // find the local id of the edge in the opposite element | ||
1565 | 6840 | felInt localIdFaceOpposite = -1; | |
1566 |
1/2✓ Branch 1 taken 6840 times.
✗ Branch 2 not taken.
|
6840 | if(dimension() == 2) |
1567 |
1/2✓ Branch 3 taken 6840 times.
✗ Branch 4 not taken.
|
6840 | m_mesh[m_currentMesh]->getAllEdgeOfElement(eltType, oppositeGlobalIelGeo, idOfFacesOpposite); |
1568 | else | ||
1569 | ✗ | m_mesh[m_currentMesh]->getAllFaceOfElement(eltType, oppositeGlobalIelGeo, idOfFacesOpposite); | |
1570 | |||
1571 |
2/2✓ Branch 1 taken 20520 times.
✓ Branch 2 taken 6840 times.
|
27360 | for(std::size_t jface=0; jface<idOfFacesOpposite.size(); ++jface) { |
1572 |
2/2✓ Branch 2 taken 6840 times.
✓ Branch 3 taken 13680 times.
|
20520 | if(idOfFacesCurrent[iface] == idOfFacesOpposite[jface]) { |
1573 | 6840 | localIdFaceOpposite = jface; | |
1574 | } | ||
1575 | } | ||
1576 | |||
1577 | // std::set coefficient of the ghost penalty | ||
1578 |
3/6✓ Branch 1 taken 6840 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6840 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6840 times.
✗ Branch 8 not taken.
|
6840 | double gammag = FelisceParam::instance().coefGhostPenalty * m_viscosity * m_feVelWithBd->bdEle(iface).diameter(); |
1579 | |||
1580 | // ----------------------------------- // | ||
1581 | // current element for phi_i and phi_j // | ||
1582 | // ----------------------------------- // | ||
1583 |
1/2✓ Branch 3 taken 6840 times.
✗ Branch 4 not taken.
|
6840 | m_elementMat[0]->zero(); |
1584 |
1/2✓ Branch 4 taken 6840 times.
✗ Branch 5 not taken.
|
6840 | m_elementMat[0]->grad_phi_j_dot_n_grad_psi_i_dot_n(gammag, *m_feVelWithBd, *m_feVelWithBd, iface, iface, 0, 0, dimension()); |
1585 |
1/2✓ Branch 1 taken 6840 times.
✗ Branch 2 not taken.
|
6840 | setValueMatrixRHS(idCurrentSupElt, idCurrentSupElt, flag); |
1586 | |||
1587 | // -------------------------------------------------------- // | ||
1588 | // current element for phi_i and opposite element for phi_j // | ||
1589 | // -------------------------------------------------------- // | ||
1590 |
1/2✓ Branch 3 taken 6840 times.
✗ Branch 4 not taken.
|
6840 | m_elementMat[0]->zero(); |
1591 |
1/2✓ Branch 4 taken 6840 times.
✗ Branch 5 not taken.
|
6840 | m_elementMat[0]->grad_phi_j_dot_n_grad_psi_i_dot_n(gammag, oppositeEltFEWithBd, *m_feVelWithBd, localIdFaceOpposite, iface, 0, 0, dimension()); |
1592 |
1/2✓ Branch 1 taken 6840 times.
✗ Branch 2 not taken.
|
6840 | setValueMatrixRHS(idCurrentSupElt, idOppositeSupElt, flag); |
1593 | |||
1594 | // if the opposite element is not duplicated, it will not be handle in this loop | ||
1595 | // compute all the term in this case | ||
1596 |
2/2✓ Branch 0 taken 1496 times.
✓ Branch 1 taken 5344 times.
|
6840 | if(computeBothSide) { |
1597 | // -------------------------------------------------------- // | ||
1598 | // opposite element for phi_i and current element for phi_j // | ||
1599 | // -------------------------------------------------------- // | ||
1600 |
1/2✓ Branch 3 taken 1496 times.
✗ Branch 4 not taken.
|
1496 | m_elementMat[0]->zero(); |
1601 |
1/2✓ Branch 4 taken 1496 times.
✗ Branch 5 not taken.
|
1496 | m_elementMat[0]->grad_phi_j_dot_n_grad_psi_i_dot_n(gammag, *m_feVelWithBd, oppositeEltFEWithBd, iface, localIdFaceOpposite, 0, 0, dimension()); |
1602 |
1/2✓ Branch 1 taken 1496 times.
✗ Branch 2 not taken.
|
1496 | setValueMatrixRHS(idOppositeSupElt, idCurrentSupElt, flag); |
1603 | |||
1604 | // ------------------------------------ // | ||
1605 | // opposite element for phi_i and phi_j // | ||
1606 | // ------------------------------------ // | ||
1607 |
1/2✓ Branch 3 taken 1496 times.
✗ Branch 4 not taken.
|
1496 | m_elementMat[0]->zero(); |
1608 |
1/2✓ Branch 4 taken 1496 times.
✗ Branch 5 not taken.
|
1496 | m_elementMat[0]->grad_phi_j_dot_n_grad_psi_i_dot_n(gammag, oppositeEltFEWithBd, oppositeEltFEWithBd, localIdFaceOpposite, localIdFaceOpposite, 0, 0, dimension()); |
1609 |
1/2✓ Branch 1 taken 1496 times.
✗ Branch 2 not taken.
|
1496 | setValueMatrixRHS(idOppositeSupElt, idOppositeSupElt, flag); |
1610 | } | ||
1611 | 6840 | } | |
1612 | } | ||
1613 | } | ||
1614 | } | ||
1615 | } | ||
1616 | |||
1617 | // desallocate array use for assemble with petsc. | ||
1618 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | desallocateArrayForAssembleMatrixRHS(flag); |
1619 | 40 | } | |
1620 | |||
1621 | |||
1622 | |||
1623 | 40 | void LinearProblemFSINitscheXFEMFluid::assembleMatrixFaceOriented() { | |
1624 | // Use Face-oriented stabilization | ||
1625 | // E. Burman, M. A. Fernandez and P. Hansbo, Continuous interior penalty finite element method for | ||
1626 | // Oseen's equations, 2006. | ||
1627 | 40 | std::pair<bool, GeometricMeshRegion::ElementType> adjElt; | |
1628 | |||
1629 | GeometricMeshRegion::ElementType eltType; // Type of element | ||
1630 | GeometricMeshRegion::ElementType eltTypeOpp; // Type of element | ||
1631 | |||
1632 | bool addOppositeSupportElt; // true if we need to compute the stabilization on this face | ||
1633 | |||
1634 | 40 | felInt ielCurrentLocalGeo = 0; // local geometric id of the current element | |
1635 | 40 | felInt ielCurrentGlobalGeo = 0; // global geometric id of the current element | |
1636 | 40 | felInt ielOppositeGlobalGeo = 0; // global geometric id of the opposite element | |
1637 | felInt numFacesPerType; // number of faces of an element of a given type | ||
1638 | felInt numEltPerLabel; // number of element by reference | ||
1639 | felInt numPointPerElt; // number of vertices by element | ||
1640 | felInt currentSupport; // id of the current support element | ||
1641 | felInt oppositeSupport; // id of the opposite support element | ||
1642 | 40 | std::vector<felInt> ielCurrentGlobalSup; // local support element id of the current element | |
1643 | 40 | std::vector<felInt> ielOppositeGlobalSup; // local support element id of the opposite element | |
1644 | |||
1645 | 40 | std::vector<felInt> idOfFacesCurrent; // ids of the current element edges | |
1646 | 40 | std::vector<felInt> idOfFacesOpposite; // ids of the opposite element edges | |
1647 | 40 | std::vector<felInt> currentElemIdPoint; // ids of the vertices of the current element | |
1648 | 40 | std::vector<felInt> oppositeElemIdPoint; // ids of the vertices of the opposite element | |
1649 | 40 | std::vector<Point*> currentElemPoint; // point coordinates of the current element vertices | |
1650 | 40 | std::vector<Point*> oppositeElemPoint; // point coordinates of the opposite element vertices | |
1651 | 40 | std::vector<felInt> countElement; // count the element by type | |
1652 | |||
1653 | 40 | FlagMatrixRHS flag = FlagMatrixRHS::only_matrix; // flag to only assemble the matrix | |
1654 | |||
1655 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | ElementField elemFieldAdvFace; |
1656 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | ElementField elemFieldAdvFaceTmp; |
1657 | |||
1658 | 40 | const std::vector<felInt>& iSupportDof = m_supportDofUnknown[0].iSupportDof(); | |
1659 | 40 | const std::vector<felInt>& iEle = m_supportDofUnknown[0].iEle(); | |
1660 | |||
1661 | // resize std::vector | ||
1662 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | countElement.resize(GeometricMeshRegion::m_numTypesOfElement, 0); |
1663 | |||
1664 | // volume bag | ||
1665 | 40 | const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[m_currentMesh]->bagElementTypeDomain(); | |
1666 | |||
1667 | |||
1668 | // finite element with bd for the opposite element | ||
1669 | 40 | std::unordered_map<GeometricMeshRegion::ElementType, CurrentFiniteElementWithBd*> oppositeEltFEWithBdVel; | |
1670 | 40 | std::unordered_map<GeometricMeshRegion::ElementType, CurrentFiniteElementWithBd*> oppositeEltFEWithBdPre; | |
1671 | |||
1672 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 2 taken 40 times.
|
80 | for (std::size_t i=0; i<bagElementTypeDomain.size(); ++i) { |
1673 | 40 | eltType = bagElementTypeDomain[i]; | |
1674 | |||
1675 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | m_velocity = &m_listVariable[m_listVariable.getVariableIdList(velocity)]; |
1676 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | m_pressure = &m_listVariable[m_listVariable.getVariableIdList(pressure)]; |
1677 | 40 | const GeoElement *geoEle = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second; | |
1678 | |||
1679 | 40 | felInt typeOfFEVel = m_velocity->finiteElementType(); | |
1680 |
1/2✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
40 | const RefElement *refEleVel = geoEle->defineFiniteEle(eltType, typeOfFEVel, *m_mesh[m_currentMesh]); |
1681 |
3/6✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 40 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
|
40 | oppositeEltFEWithBdVel[eltType] = new CurrentFiniteElementWithBd(*refEleVel, *geoEle, m_velocity->degreeOfExactness(), m_velocity->degreeOfExactness()); |
1682 | |||
1683 | 40 | felInt typeOfFEPre = m_pressure->finiteElementType(); | |
1684 |
1/2✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
40 | const RefElement *refElePre = geoEle->defineFiniteEle(eltType, typeOfFEPre, *m_mesh[m_currentMesh]); |
1685 |
3/6✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 40 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
|
40 | oppositeEltFEWithBdPre[eltType] = new CurrentFiniteElementWithBd(*refElePre, *geoEle, m_pressure->degreeOfExactness(), m_pressure->degreeOfExactness()); |
1686 | } | ||
1687 | |||
1688 | |||
1689 | // ---------------------------- | ||
1690 | // First loop on geometric type | ||
1691 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 2 taken 40 times.
|
80 | for (std::size_t itype=0; itype<bagElementTypeDomain.size(); ++itype) { |
1692 | // get element type and number of vertices and "faces" | ||
1693 | 40 | eltType = bagElementTypeDomain[itype]; | |
1694 | 40 | numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType]; | |
1695 | 40 | numFacesPerType = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second->numBdEle(); | |
1696 | |||
1697 | // resize of vectors | ||
1698 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | idOfFacesCurrent.resize(numFacesPerType, -1); |
1699 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | idOfFacesOpposite.resize(numFacesPerType, -1); |
1700 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | currentElemIdPoint.resize(numPointPerElt, -1); |
1701 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | oppositeElemIdPoint.resize(numPointPerElt, -1); |
1702 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | currentElemPoint.resize(numPointPerElt, nullptr); |
1703 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | oppositeElemPoint.resize(numPointPerElt, nullptr); |
1704 | |||
1705 | // define finite element | ||
1706 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | defineFiniteElement(eltType); |
1707 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | initElementArray(); |
1708 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | defineCurrentFiniteElementWithBd(eltType); |
1709 | |||
1710 | // allocate arrays for assembling the matrix | ||
1711 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | allocateArrayForAssembleMatrixRHS(flag); |
1712 | |||
1713 | // init variables | ||
1714 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | initPerElementType(eltType, flag); |
1715 | 40 | m_feVelWithBd = m_listCurrentFiniteElementWithBd[m_iVelocity]; | |
1716 | 40 | m_fePreWithBd = m_listCurrentFiniteElementWithBd[m_iPressure]; | |
1717 | |||
1718 | |||
1719 | // --------------------------------- | ||
1720 | // second loop on region of the mesh | ||
1721 |
2/2✓ Branch 8 taken 40 times.
✓ Branch 9 taken 40 times.
|
80 | for(auto itRef = m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].end(); itRef++) { |
1722 | // get the number of element with this reference | ||
1723 | 40 | numEltPerLabel = itRef->second.second; | |
1724 | |||
1725 | // std::set the current label of LinearProblem to the current one of this loop | ||
1726 |
1/2✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
40 | initPerDomain(itRef->first, flag); |
1727 | |||
1728 | // --------------------- | ||
1729 | // third loop on element | ||
1730 |
2/2✓ Branch 0 taken 136880 times.
✓ Branch 1 taken 40 times.
|
136920 | for(felInt iel=0; iel<numEltPerLabel; ++iel) { |
1731 | // get the global id of the current geometric element | ||
1732 |
1/2✓ Branch 2 taken 136880 times.
✗ Branch 3 not taken.
|
136880 | ISLocalToGlobalMappingApply(m_mappingElem[m_currentMesh], 1, &ielCurrentLocalGeo, &ielCurrentGlobalGeo); |
1733 | |||
1734 | // get all the faces of the element | ||
1735 |
1/2✓ Branch 1 taken 136880 times.
✗ Branch 2 not taken.
|
136880 | if(dimension() == 2) |
1736 |
1/2✓ Branch 3 taken 136880 times.
✗ Branch 4 not taken.
|
136880 | m_mesh[m_currentMesh]->getAllEdgeOfElement(ielCurrentGlobalGeo, idOfFacesCurrent); |
1737 | else | ||
1738 | ✗ | m_mesh[m_currentMesh]->getAllFaceOfElement(ielCurrentGlobalGeo, idOfFacesCurrent); | |
1739 | |||
1740 | // get informations on the current element | ||
1741 |
1/2✓ Branch 2 taken 136880 times.
✗ Branch 3 not taken.
|
136880 | setElemPoint(eltType, countElement[eltType], currentElemPoint, currentElemIdPoint, ielCurrentGlobalSup); |
1742 | |||
1743 | // update the finite elements | ||
1744 |
1/2✓ Branch 1 taken 136880 times.
✗ Branch 2 not taken.
|
136880 | m_feVelWithBd->updateFirstDeriv(0, currentElemPoint); |
1745 |
1/2✓ Branch 1 taken 136880 times.
✗ Branch 2 not taken.
|
136880 | m_feVelWithBd->updateBdMeasNormal(); |
1746 |
1/2✓ Branch 1 taken 136880 times.
✗ Branch 2 not taken.
|
136880 | m_fePreWithBd->updateFirstDeriv(0, currentElemPoint); |
1747 |
1/2✓ Branch 1 taken 136880 times.
✗ Branch 2 not taken.
|
136880 | m_fePreWithBd->updateBdMeasNormal(); |
1748 | |||
1749 | |||
1750 | // loop over the support element of the current geometric element | ||
1751 |
2/2✓ Branch 1 taken 138296 times.
✓ Branch 2 taken 136880 times.
|
275176 | for(std::size_t ielSup=0; ielSup<ielCurrentGlobalSup.size(); ++ielSup) { |
1752 | 138296 | currentSupport = ielCurrentGlobalSup[ielSup]; | |
1753 | |||
1754 | // get the old support dof | ||
1755 |
2/4✓ Branch 2 taken 138296 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 138296 times.
✗ Branch 6 not taken.
|
138296 | std::vector< std::vector<felInt> > oldSupportElement(FelisceParam::instance().orderBdfNS); |
1756 |
2/4✓ Branch 2 taken 138296 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 138296 times.
✗ Branch 6 not taken.
|
138296 | std::vector<felInt> ielOld(FelisceParam::instance().orderBdfNS); |
1757 | |||
1758 |
3/4✓ Branch 1 taken 276592 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138296 times.
✓ Branch 4 taken 138296 times.
|
276592 | for(felInt iextrap=0; iextrap<FelisceParam::instance().orderBdfNS; ++iextrap) { |
1759 | // get the old support element | ||
1760 |
1/2✓ Branch 4 taken 138296 times.
✗ Branch 5 not taken.
|
138296 | m_supportDofUnknownOld[iextrap][0].getIdElementSupport(ielCurrentGlobalGeo, oldSupportElement[iextrap]); |
1761 | |||
1762 | // std::set the id for the old solution | ||
1763 |
2/2✓ Branch 2 taken 2792 times.
✓ Branch 3 taken 135504 times.
|
138296 | if(oldSupportElement[iextrap].size() > 1) |
1764 | 2792 | ielOld[iextrap] = oldSupportElement[iextrap][ielSup]; | |
1765 | else | ||
1766 | 135504 | ielOld[iextrap] = oldSupportElement[iextrap][0]; | |
1767 | } | ||
1768 | |||
1769 | // compute coefficients | ||
1770 |
1/2✓ Branch 1 taken 138296 times.
✗ Branch 2 not taken.
|
138296 | m_elemFieldAdv.val.clear(); |
1771 |
2/4✓ Branch 1 taken 138296 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 138296 times.
|
138296 | if(FelisceParam::instance().useProjectionForNitscheXFEM) { |
1772 | ✗ | for(felInt iextrap=0; iextrap<FelisceParam::instance().orderBdfNS; ++iextrap) { | |
1773 | ✗ | m_elemFieldAdvTmp.setValue(m_seqVelExtrapol[iextrap], *m_feVel, currentSupport, m_iVelocity, m_ao, dof()); | |
1774 | ✗ | m_elemFieldAdv.val += m_elemFieldAdvTmp.val; | |
1775 | } | ||
1776 | } else { | ||
1777 |
3/4✓ Branch 1 taken 276592 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138296 times.
✓ Branch 4 taken 138296 times.
|
276592 | for(felInt iextrap=0; iextrap<FelisceParam::instance().orderBdfNS; ++iextrap) { |
1778 |
1/2✓ Branch 5 taken 138296 times.
✗ Branch 6 not taken.
|
138296 | m_elemFieldAdvTmp.setValue(m_seqVelExtrapol[iextrap], *m_feVel, ielOld[iextrap], m_iVelocity, m_aoOld[iextrap], m_dofOld[iextrap]); |
1779 |
1/2✓ Branch 1 taken 138296 times.
✗ Branch 2 not taken.
|
138296 | m_elemFieldAdv.val += m_elemFieldAdvTmp.val; |
1780 | } | ||
1781 | } | ||
1782 | |||
1783 | 138296 | double normVelExtrap = 0; | |
1784 |
2/2✓ Branch 1 taken 414888 times.
✓ Branch 2 taken 138296 times.
|
553184 | for(std::size_t jcol=0; jcol<m_elemFieldAdv.val.size2(); ++jcol) |
1785 |
2/4✓ Branch 1 taken 414888 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 414888 times.
✗ Branch 5 not taken.
|
414888 | normVelExtrap = std::max(normVelExtrap, norm_2(column(m_elemFieldAdv.val, jcol))); |
1786 | |||
1787 |
1/2✓ Branch 1 taken 138296 times.
✗ Branch 2 not taken.
|
138296 | double hK = m_feVelWithBd->diameter(); |
1788 | 138296 | double ReK = m_density * normVelExtrap * hK / m_viscosity; | |
1789 |
1/2✓ Branch 1 taken 138296 times.
✗ Branch 2 not taken.
|
138296 | double coeffVel = FelisceParam::instance().stabFOVel * std::min(1., ReK) * hK * hK; |
1790 | |||
1791 | 138296 | double gammaP = 0.; | |
1792 |
2/4✓ Branch 1 taken 138296 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 138296 times.
|
138296 | if(FelisceParam::instance().NSequationFlag == 0) { |
1793 | ✗ | gammaP = FelisceParam::instance().stabFOPre * hK * hK * hK / m_viscosity; | |
1794 | } else { | ||
1795 |
2/2✓ Branch 0 taken 55048 times.
✓ Branch 1 taken 83248 times.
|
138296 | double xiPre = ReK < 1 ? m_density * hK * hK * hK / m_viscosity : hK * hK / normVelExtrap; |
1796 |
1/2✓ Branch 1 taken 138296 times.
✗ Branch 2 not taken.
|
138296 | gammaP = FelisceParam::instance().stabFOPre * xiPre; |
1797 | } | ||
1798 | |||
1799 | // -------------------------------------------------------- | ||
1800 | // loop over all the faces of the current geometric element | ||
1801 |
2/2✓ Branch 1 taken 414888 times.
✓ Branch 2 taken 138296 times.
|
553184 | for(std::size_t iface=0; iface<idOfFacesCurrent.size(); ++iface) { |
1802 | // check if this face is an inner face or a boundary | ||
1803 | 414888 | ielOppositeGlobalGeo = ielCurrentGlobalGeo; | |
1804 | |||
1805 | // first = true if there is an adjacent element | ||
1806 | // second = the ElementType of the adjacent element if first is true | ||
1807 |
1/2✓ Branch 3 taken 414888 times.
✗ Branch 4 not taken.
|
414888 | adjElt =m_mesh[m_currentMesh]->getAdjElement(ielOppositeGlobalGeo, iface); |
1808 | |||
1809 | // compute the stabilization only on inner faces | ||
1810 |
2/2✓ Branch 0 taken 406968 times.
✓ Branch 1 taken 7920 times.
|
414888 | if(adjElt.first) { |
1811 | // get the type of the opposite element | ||
1812 | 406968 | eltTypeOpp = adjElt.second; | |
1813 | |||
1814 | // find the local id of the edge in the opposite element | ||
1815 | 406968 | felInt localIdFaceOpposite = -1; | |
1816 |
1/2✓ Branch 1 taken 406968 times.
✗ Branch 2 not taken.
|
406968 | if(dimension() == 2) |
1817 |
1/2✓ Branch 3 taken 406968 times.
✗ Branch 4 not taken.
|
406968 | m_mesh[m_currentMesh]->getAllEdgeOfElement(ielOppositeGlobalGeo, idOfFacesOpposite); |
1818 | else | ||
1819 | ✗ | m_mesh[m_currentMesh]->getAllFaceOfElement(ielOppositeGlobalGeo, idOfFacesOpposite); | |
1820 | |||
1821 |
2/2✓ Branch 1 taken 1220904 times.
✓ Branch 2 taken 406968 times.
|
1627872 | for(std::size_t jface=0; jface<idOfFacesOpposite.size(); ++jface) { |
1822 |
2/2✓ Branch 2 taken 406968 times.
✓ Branch 3 taken 813936 times.
|
1220904 | if(idOfFacesCurrent[iface] == idOfFacesOpposite[jface]) { |
1823 | 406968 | localIdFaceOpposite = jface; | |
1824 | } | ||
1825 | } | ||
1826 | |||
1827 | // get information on the opposite element | ||
1828 | // same as the function "setElemPoint" but here ielOppositeGlobalGeo is global | ||
1829 | // we assume that the supportDofMesh is the same for all unknown (like in setElemPoint) | ||
1830 |
1/2✓ Branch 2 taken 406968 times.
✗ Branch 3 not taken.
|
406968 | m_supportDofUnknown[0].getIdElementSupport(ielOppositeGlobalGeo, ielOppositeGlobalSup); |
1831 |
1/2✓ Branch 3 taken 406968 times.
✗ Branch 4 not taken.
|
406968 | m_mesh[m_currentMesh]->getOneElement(ielOppositeGlobalGeo, oppositeElemIdPoint); |
1832 |
2/2✓ Branch 0 taken 1220904 times.
✓ Branch 1 taken 406968 times.
|
1627872 | for (felInt iPoint=0; iPoint<numPointPerElt; ++iPoint) |
1833 | 1220904 | oppositeElemPoint[iPoint] = &(m_mesh[m_currentMesh]->listPoints()[oppositeElemIdPoint[iPoint]]); | |
1834 | |||
1835 | // compare the number of support element | ||
1836 |
2/2✓ Branch 2 taken 402480 times.
✓ Branch 3 taken 4488 times.
|
406968 | if(ielCurrentGlobalSup.size() == ielOppositeGlobalSup.size()) { |
1837 | // both are duplicated or both are not. Take the element on the same side | ||
1838 | 402480 | oppositeSupport = ielOppositeGlobalSup[ielSup]; | |
1839 | 402480 | addOppositeSupportElt = true; | |
1840 | } else { | ||
1841 | // One is duplicated, the other is not | ||
1842 | 4488 | addOppositeSupportElt = false; | |
1843 |
6/6✓ Branch 1 taken 5984 times.
✓ Branch 2 taken 3712 times.
✓ Branch 3 taken 5208 times.
✓ Branch 4 taken 776 times.
✓ Branch 5 taken 5208 times.
✓ Branch 6 taken 4488 times.
|
9696 | for(std::size_t jelSup=0; jelSup < ielOppositeGlobalSup.size() && !addOppositeSupportElt; ++jelSup) { |
1844 | 5208 | oppositeSupport = ielOppositeGlobalSup[jelSup]; | |
1845 | |||
1846 | // check if this opposite support element is on the same side as the current support element | ||
1847 | 5208 | std::size_t sizeCurrent = m_supportDofUnknown[0].getNumSupportDof(currentSupport); | |
1848 | 5208 | std::size_t sizeOpposite = m_supportDofUnknown[0].getNumSupportDof(oppositeSupport); | |
1849 | |||
1850 | 5208 | felInt countSupportDofInCommon = 0; | |
1851 |
2/2✓ Branch 0 taken 15624 times.
✓ Branch 1 taken 5208 times.
|
20832 | for(std::size_t iSup1=0; iSup1<sizeCurrent; ++iSup1) { |
1852 |
2/2✓ Branch 0 taken 46872 times.
✓ Branch 1 taken 15624 times.
|
62496 | for(std::size_t iSup2=0; iSup2<sizeOpposite; ++iSup2) { |
1853 |
2/2✓ Branch 4 taken 6224 times.
✓ Branch 5 taken 40648 times.
|
46872 | if(iSupportDof[iEle[oppositeSupport] + iSup2] == iSupportDof[iEle[currentSupport] + iSup1]) { |
1854 | 6224 | ++countSupportDofInCommon; | |
1855 | } | ||
1856 | } | ||
1857 | } | ||
1858 | |||
1859 |
2/2✓ Branch 0 taken 2992 times.
✓ Branch 1 taken 2216 times.
|
5208 | if(countSupportDofInCommon > 1) |
1860 | 2992 | addOppositeSupportElt = true; | |
1861 | } | ||
1862 | } | ||
1863 | |||
1864 | // if there really is an opposite support element | ||
1865 | // Even for an inner edge, it is possible that the current support element has no opposite | ||
1866 | // support element (if it is duplicated and the opposite element is not). | ||
1867 |
2/2✓ Branch 0 taken 405472 times.
✓ Branch 1 taken 1496 times.
|
406968 | if(addOppositeSupportElt) { |
1868 | // update the opposite finite elements | ||
1869 |
2/4✓ Branch 1 taken 405472 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 405472 times.
✗ Branch 5 not taken.
|
405472 | oppositeEltFEWithBdVel[eltTypeOpp]->updateFirstDeriv(0, oppositeElemPoint); |
1870 |
2/4✓ Branch 1 taken 405472 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 405472 times.
✗ Branch 5 not taken.
|
405472 | oppositeEltFEWithBdVel[eltTypeOpp]->updateBdMeasNormal(); |
1871 |
2/4✓ Branch 1 taken 405472 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 405472 times.
✗ Branch 5 not taken.
|
405472 | oppositeEltFEWithBdPre[eltTypeOpp]->updateFirstDeriv(0, oppositeElemPoint); |
1872 |
2/4✓ Branch 1 taken 405472 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 405472 times.
✗ Branch 5 not taken.
|
405472 | oppositeEltFEWithBdPre[eltTypeOpp]->updateBdMeasNormal(); |
1873 | |||
1874 | |||
1875 | // compute coefficient | ||
1876 |
2/4✓ Branch 2 taken 405472 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 405472 times.
✗ Branch 6 not taken.
|
405472 | elemFieldAdvFace.initialize(DOF_FIELD, m_feVelWithBd->bdEle(iface), dimension()); |
1877 |
2/4✓ Branch 2 taken 405472 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 405472 times.
✗ Branch 6 not taken.
|
405472 | elemFieldAdvFaceTmp.initialize(DOF_FIELD, m_feVelWithBd->bdEle(iface), dimension()); |
1878 |
2/4✓ Branch 1 taken 405472 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 405472 times.
|
405472 | if(FelisceParam::instance().useProjectionForNitscheXFEM) { |
1879 | ✗ | for(felInt iextrap=0; iextrap<FelisceParam::instance().orderBdfNS; ++iextrap) { | |
1880 | ✗ | elemFieldAdvFaceTmp.setValue(m_seqVelExtrapol[iextrap], *m_feVelWithBd, iface, currentSupport, m_iVelocity, m_ao, dof()); | |
1881 | ✗ | elemFieldAdvFace.val += elemFieldAdvFaceTmp.val; | |
1882 | } | ||
1883 | } else { | ||
1884 |
3/4✓ Branch 1 taken 810944 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 405472 times.
✓ Branch 4 taken 405472 times.
|
810944 | for(felInt iextrap=0; iextrap<FelisceParam::instance().orderBdfNS; ++iextrap) { |
1885 |
1/2✓ Branch 5 taken 405472 times.
✗ Branch 6 not taken.
|
405472 | elemFieldAdvFaceTmp.setValue(m_seqVelExtrapol[iextrap], *m_feVelWithBd, iface, ielOld[iextrap], m_iVelocity, m_aoOld[iextrap], m_dofOld[iextrap]); |
1886 |
1/2✓ Branch 1 taken 405472 times.
✗ Branch 2 not taken.
|
405472 | elemFieldAdvFace.val += elemFieldAdvFaceTmp.val; |
1887 | } | ||
1888 | } | ||
1889 | |||
1890 |
4/8✓ Branch 1 taken 405472 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 405472 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 405472 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 405472 times.
✗ Branch 12 not taken.
|
810944 | UBlasVector normalVel = prod(trans(elemFieldAdvFace.val), m_feVelWithBd->bdEle(iface).normal[0]); |
1891 |
1/2✓ Branch 1 taken 405472 times.
✗ Branch 2 not taken.
|
405472 | double normVelBd = norm_inf(normalVel); |
1892 | 405472 | double gammaU = coeffVel * normVelBd; | |
1893 | |||
1894 | // We can now compute all the integrals. | ||
1895 | // There is a minus sign for gammaP because there is one for q div(u). | ||
1896 | // current element for phi_i and phi_j | ||
1897 |
1/2✓ Branch 3 taken 405472 times.
✗ Branch 4 not taken.
|
405472 | m_elementMat[0]->zero(); |
1898 |
1/2✓ Branch 4 taken 405472 times.
✗ Branch 5 not taken.
|
405472 | m_elementMat[0]->grad_phi_j_dot_n_grad_psi_i_dot_n(gammaU, *m_feVelWithBd, *m_feVelWithBd, iface, iface, 0, 0, dimension()); |
1899 |
1/2✓ Branch 5 taken 405472 times.
✗ Branch 6 not taken.
|
405472 | m_elementMat[0]->grad_phi_j_dot_n_grad_psi_i_dot_n(-gammaP, *m_fePreWithBd, *m_fePreWithBd, iface, iface, dimension(), dimension(), 1); |
1900 | // m_elementMat[0]->grad_phi_j_grad_psi_i(-gammaP, *m_fePreWithBd, *m_fePreWithBd, iface, iface, dimension(), dimension(), 1); | ||
1901 |
1/2✓ Branch 1 taken 405472 times.
✗ Branch 2 not taken.
|
405472 | setValueMatrixRHS(currentSupport, currentSupport, flag); |
1902 | |||
1903 | // current element for phi_i and opposite element for phi_j | ||
1904 |
1/2✓ Branch 3 taken 405472 times.
✗ Branch 4 not taken.
|
405472 | m_elementMat[0]->zero(); |
1905 |
2/4✓ Branch 4 taken 405472 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 405472 times.
✗ Branch 8 not taken.
|
405472 | m_elementMat[0]->grad_phi_j_dot_n_grad_psi_i_dot_n(gammaU, *oppositeEltFEWithBdVel[eltTypeOpp], *m_feVelWithBd, localIdFaceOpposite, iface, 0, 0, dimension()); |
1906 |
2/4✓ Branch 5 taken 405472 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 405472 times.
✗ Branch 9 not taken.
|
405472 | m_elementMat[0]->grad_phi_j_dot_n_grad_psi_i_dot_n(-gammaP, *oppositeEltFEWithBdPre[eltTypeOpp], *m_fePreWithBd, localIdFaceOpposite, iface, dimension(), dimension(), 1); |
1907 | // m_elementMat[0]->grad_phi_j_grad_psi_i(gammaP, oppositeEltFEWithBdPre, *m_fePreWithBd, localIdFaceOpposite, iface, dimension(), dimension(), 1); | ||
1908 |
1/2✓ Branch 1 taken 405472 times.
✗ Branch 2 not taken.
|
405472 | setValueMatrixRHS(currentSupport, oppositeSupport, flag); |
1909 | |||
1910 | // current element for phi_i and opposite element for phi_j | ||
1911 |
2/4✓ Branch 4 taken 405472 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 405472 times.
✗ Branch 11 not taken.
|
405472 | m_elementMat[0]->mat() = trans(m_elementMat[0]->mat()); |
1912 |
1/2✓ Branch 1 taken 405472 times.
✗ Branch 2 not taken.
|
405472 | setValueMatrixRHS(oppositeSupport, currentSupport, flag); |
1913 | |||
1914 | // current element for phi_i and phi_j | ||
1915 |
1/2✓ Branch 3 taken 405472 times.
✗ Branch 4 not taken.
|
405472 | m_elementMat[0]->zero(); |
1916 |
3/6✓ Branch 4 taken 405472 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 405472 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 405472 times.
✗ Branch 11 not taken.
|
405472 | m_elementMat[0]->grad_phi_j_dot_n_grad_psi_i_dot_n(gammaU, *oppositeEltFEWithBdVel[eltTypeOpp], *oppositeEltFEWithBdVel[eltTypeOpp], localIdFaceOpposite, localIdFaceOpposite, 0, 0, dimension()); |
1917 |
3/6✓ Branch 5 taken 405472 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 405472 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 405472 times.
✗ Branch 12 not taken.
|
405472 | m_elementMat[0]->grad_phi_j_dot_n_grad_psi_i_dot_n(-gammaP, *oppositeEltFEWithBdPre[eltTypeOpp], *oppositeEltFEWithBdPre[eltTypeOpp], localIdFaceOpposite, localIdFaceOpposite, dimension(), dimension(), 1); |
1918 | // m_elementMat[0]->grad_phi_j_grad_psi_i(-gammaP, oppositeEltFEWithBdPre, oppositeEltFEWithBdPre, localIdFaceOpposite, localIdFaceOpposite, dimension(), dimension(), 1); | ||
1919 |
1/2✓ Branch 1 taken 405472 times.
✗ Branch 2 not taken.
|
405472 | setValueMatrixRHS(oppositeSupport, oppositeSupport, flag); |
1920 | 405472 | } | |
1921 | } | ||
1922 | } | ||
1923 | 138296 | } | |
1924 | 136880 | ++countElement[eltType]; | |
1925 | 136880 | ++ielCurrentLocalGeo; | |
1926 | } | ||
1927 | } | ||
1928 | } | ||
1929 | |||
1930 | // desallocate array use for assemble with petsc. | ||
1931 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | desallocateArrayForAssembleMatrixRHS(flag); |
1932 | |||
1933 | // desallocate opposite finite elements | ||
1934 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 2 taken 40 times.
|
80 | for (std::size_t i=0; i<bagElementTypeDomain.size(); ++i) { |
1935 | 40 | eltType = bagElementTypeDomain[i]; | |
1936 |
2/4✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
40 | delete oppositeEltFEWithBdVel[eltType]; |
1937 |
2/4✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
40 | delete oppositeEltFEWithBdPre[eltType]; |
1938 | } | ||
1939 | 40 | } | |
1940 | |||
1941 | |||
1942 | |||
1943 | |||
1944 | ✗ | void LinearProblemFSINitscheXFEMFluid::computeElementArrayBoundaryCondition(const std::vector<Point*>& elemPoint, const std::vector<felInt>& elemIdPoint, felInt& ielSupportDof, FlagMatrixRHS flagMatrixRHS) { | |
1945 | IGNORE_UNUSED_FLAG_MATRIX_RHS; | ||
1946 | IGNORE_UNUSED_ELEM_ID_POINT; | ||
1947 | |||
1948 | // call to the function in linear problem that updates the curvilinear finite element | ||
1949 | //LinearProblem::computeElementArrayBoundaryCondition(elemPoint, elemIdPoint, ielSupportDof, flagMatrixRHS); | ||
1950 | ✗ | if(m_curvFeVel->hasOriginalQuadPoint()) { | |
1951 | ✗ | m_curvFeVel->updateMeasNormalContra(0, elemPoint); | |
1952 | ✗ | m_curvFePress->updateMeasNormalContra(0, elemPoint); | |
1953 | } else { | ||
1954 | ✗ | m_curvFeVel->updateBasisAndNormalContra(0, elemPoint); | |
1955 | ✗ | m_curvFePress->updateBasisAndNormalContra(0, elemPoint); | |
1956 | } | ||
1957 | |||
1958 | // we change the curvilinear finite element here | ||
1959 | // the integrals will automatically be computed on the physical part of the boundary | ||
1960 | |||
1961 | // get the global id of the geometric element | ||
1962 | ✗ | felInt iel = -1; | |
1963 | ✗ | bool isfound = false; | |
1964 | ✗ | std::vector<felInt> tmpSupport; | |
1965 | ✗ | felInt start = ielSupportDof > m_mesh[m_currentMesh]->getNumElement() - 1 ? m_mesh[m_currentMesh]->getNumElement() - 1 : ielSupportDof; | |
1966 | ✗ | for(felInt i=start; i>0 && !isfound; --i) { | |
1967 | // we start at ielSupportDof (should be close to the geometric id) | ||
1968 | ✗ | m_supportDofUnknown[0].getIdElementSupport(i, tmpSupport); | |
1969 | ✗ | for(std::size_t j=0; j<tmpSupport.size(); ++j) { | |
1970 | ✗ | if(tmpSupport[j] == ielSupportDof) { | |
1971 | ✗ | iel = i; | |
1972 | ✗ | isfound = true; | |
1973 | } | ||
1974 | } | ||
1975 | } | ||
1976 | |||
1977 | ✗ | if(!isfound) { | |
1978 | ✗ | FEL_ERROR("geometric element not found, check the search function"); | |
1979 | } | ||
1980 | |||
1981 | // check if this element is intersected | ||
1982 | ✗ | std::vector< std::vector< Point > > bndElem; | |
1983 | ✗ | m_duplicateSupportElements->getSubBndElt(iel, bndElem); | |
1984 | |||
1985 | ✗ | if(!bndElem.empty()) { | |
1986 | // get the "side" of the current support element | ||
1987 | sideOfInterface side; | ||
1988 | felInt ielSupport; | ||
1989 | ✗ | m_supportDofUnknown[0].getIdElementSupport(iel, ielSupport); | |
1990 | ✗ | side = ielSupport == ielSupportDof ? LEFT : RIGHT; | |
1991 | |||
1992 | // get the side of the sub elements | ||
1993 | ✗ | std::vector<sideOfInterface> bndElemSide; | |
1994 | ✗ | m_duplicateSupportElements->getSubBndEltSide(iel, bndElemSide); | |
1995 | |||
1996 | // integration over the left or right sub element only | ||
1997 | ✗ | for(std::size_t iSubElt=0; iSubElt<bndElemSide.size(); ++iSubElt) { | |
1998 | ✗ | if(bndElemSide[iSubElt] == side) { | |
1999 | // get the points defining the sub element | ||
2000 | ✗ | for(std::size_t iPt=0; iPt < m_numVerPerSolidElt; ++iPt) { | |
2001 | ✗ | *m_subItfPts[iPt] = bndElem[iSubElt][iPt]; | |
2002 | } | ||
2003 | |||
2004 | // update measure | ||
2005 | ✗ | m_curvFeVel->updateSubElementMeasNormal(0, elemPoint, m_subItfPts); | |
2006 | ✗ | m_curvFePress->updateSubElementMeasNormal(0, elemPoint, m_subItfPts); | |
2007 | } | ||
2008 | } | ||
2009 | } | ||
2010 | } | ||
2011 | |||
2012 | |||
2013 | |||
2014 | 320 | void LinearProblemFSINitscheXFEMFluid::computeNitscheSigma_u_v(double velCoeff, double preCoeff) { | |
2015 | // \int_K (velCoeff \grad u vec - preCoeff p vec) \cdot v | ||
2016 |
1/2✓ Branch 0 taken 320 times.
✗ Branch 1 not taken.
|
320 | if(m_useSymmetricStress) |
2017 | 320 | m_elementMat[0]->phi_i_eps_phi_j_dot_vec(2.*velCoeff, m_elemFieldNormal, *m_feVel, 0, 0, dimension()); | |
2018 | else | ||
2019 | ✗ | m_elementMat[0]->phi_i_grad_phi_j_dot_vec(velCoeff, m_elemFieldNormal, *m_feVel, 0, 0, dimension()); | |
2020 | |||
2021 | // same finite element for the pressure and the velocity | ||
2022 |
2/2✓ Branch 1 taken 640 times.
✓ Branch 2 taken 320 times.
|
960 | for(felInt idim=0; idim<dimension(); ++idim) |
2023 | 640 | m_elementMat[0]->phi_i_phi_j(preCoeff*m_elemFieldNormal.val(idim,0), *m_feVel, idim, dimension(), 1); | |
2024 | 320 | } | |
2025 | |||
2026 | |||
2027 | 4432 | void LinearProblemFSINitscheXFEMFluid::computeNitscheSigma_v_u(double velCoeff, double preCoeff) { | |
2028 | // \int_K (velCoeff \grad v vec - preCoeff q vec) \cdot u | ||
2029 |
1/2✓ Branch 0 taken 4432 times.
✗ Branch 1 not taken.
|
4432 | if(m_useSymmetricStress) |
2030 | 4432 | m_elementMat[0]->eps_phi_i_dot_vec_phi_j(2.*velCoeff, m_elemFieldNormal, *m_feVel, 0, 0, dimension()); | |
2031 | else | ||
2032 | ✗ | m_elementMat[0]->grad_phi_i_dot_vec_phi_j(velCoeff, m_elemFieldNormal, *m_feVel, 0, 0, dimension()); | |
2033 | |||
2034 | // same finite element for the pressure and velocity | ||
2035 |
2/2✓ Branch 1 taken 8864 times.
✓ Branch 2 taken 4432 times.
|
13296 | for(felInt idim=0; idim<dimension(); ++idim) |
2036 | 8864 | m_elementMat[0]->phi_i_phi_j(preCoeff*m_elemFieldNormal.val(idim,0), *m_feVel, dimension(), idim, 1); | |
2037 | 4432 | } | |
2038 | |||
2039 | |||
2040 | ✗ | void LinearProblemFSINitscheXFEMFluid::computeNitscheSigma_u_Sigma_v(double coeff) { | |
2041 | // same finite element for pressure and velocity | ||
2042 | // eps(u)n . eps(v)n, eps(u)n . qn, -pn . eps(v)n | ||
2043 | ✗ | if(m_useSymmetricStress) { | |
2044 | ✗ | m_elementMat[0]->eps_phi_j_vec_dot_eps_phi_i_vec(4.*m_viscosity*m_viscosity*coeff, m_elemFieldNormal, *m_feVel, 0, 0, dimension()); | |
2045 | |||
2046 | ✗ | for(felInt idim=0; idim<dimension(); ++idim) { | |
2047 | ✗ | m_elementMat[0]->phi_i_eps_phi_j_dot_vec(2.*m_viscosity*coeff*m_elemFieldNormal.val(idim,0), m_elemFieldNormal, *m_feVel, dimension(), idim, 1); | |
2048 | |||
2049 | ✗ | m_elementMat[0]->eps_phi_i_dot_vec_phi_j(-2.*m_viscosity*coeff*m_elemFieldNormal.val(idim,0), m_elemFieldNormal, *m_feVel, idim, dimension(), 1); | |
2050 | } | ||
2051 | } else { | ||
2052 | ✗ | m_elementMat[0]->grad_phi_j_vec_dot_grad_phi_i_vec(m_viscosity*m_viscosity*coeff, m_elemFieldNormal, *m_feVel, 0, 0, dimension()); | |
2053 | |||
2054 | ✗ | for(felInt idim=0; idim<dimension(); ++idim) { | |
2055 | ✗ | m_elementMat[0]->phi_i_grad_phi_j_dot_vec(m_viscosity*coeff*m_elemFieldNormal.val(idim,0), m_elemFieldNormal, *m_feVel, dimension(), idim, 1); | |
2056 | |||
2057 | ✗ | m_elementMat[0]->grad_phi_i_dot_vec_phi_j(-m_viscosity*coeff*m_elemFieldNormal.val(idim,0), m_elemFieldNormal, *m_feVel, idim, dimension(), 1); | |
2058 | } | ||
2059 | } | ||
2060 | |||
2061 | // -pn . qn = -pq | ||
2062 | ✗ | m_elementMat[0]->phi_i_phi_j(-coeff, *m_fePres, dimension(), dimension(), 1); | |
2063 | } | ||
2064 | |||
2065 | |||
2066 | |||
2067 | |||
2068 | ✗ | void LinearProblemFSINitscheXFEMFluid::computeNitscheSigma_uold_Sigma_v(double coeff) { | |
2069 | // same finite element for pressure and velocity | ||
2070 | // eps(uold)n . eps(v)n, eps(uold)n . qn, -poldn . eps(v)n | ||
2071 | ✗ | if(m_useSymmetricStress) { | |
2072 | ✗ | m_elementVector[0]->eps_vec2_vec1_dot_eps_phi_i_vec1(4.*m_viscosity*m_viscosity*coeff, m_elemFieldNormal, m_seqVelDofPts[0], *m_feVel, 0, dimension()); | |
2073 | |||
2074 | ✗ | for(felInt idim=0; idim<dimension(); ++idim) { | |
2075 | ✗ | m_elementVector[0]->eps_vec2_dot_vec1_dot_phi_i(2.*m_viscosity*coeff*m_elemFieldNormal.val(idim,0), m_elemFieldNormal, m_seqVelDofPts[0], *m_feVel, dimension(), 1); | |
2076 | |||
2077 | ✗ | m_elementVector[0]->eps_phi_i_dot_vec1_dot_vec2(-2.*m_viscosity*coeff*m_elemFieldNormal.val(idim,0), m_elemFieldNormal, m_seqVelDofPts[0], *m_feVel, idim, 1); | |
2078 | } | ||
2079 | } else { | ||
2080 | ✗ | m_elementVector[0]->grad_vec2_vec1_dot_grad_phi_i_vec1(m_viscosity*m_viscosity*coeff, m_elemFieldNormal, m_seqVelDofPts[0], *m_feVel, 0, dimension()); | |
2081 | |||
2082 | ✗ | for(felInt idim=0; idim<dimension(); ++idim) { | |
2083 | ✗ | m_elementVector[0]->grad_vec2_dot_vec1_dot_phi_i(m_viscosity*coeff*m_elemFieldNormal.val(idim,0), m_elemFieldNormal, m_seqVelDofPts[0], *m_feVel, dimension(), 1); | |
2084 | |||
2085 | ✗ | m_elementVector[0]->grad_phi_i_dot_vec1_dot_vec2(-m_viscosity*coeff*m_elemFieldNormal.val(idim,0), m_elemFieldNormal, m_seqVelDofPts[0], *m_feVel, idim, 1); | |
2086 | } | ||
2087 | } | ||
2088 | |||
2089 | // -poldn . qn = -pold q | ||
2090 | ✗ | m_elementVector[0]->source(-coeff, *m_fePres, m_seqPreDofPts[0], dimension(), 1); | |
2091 | |||
2092 | } | ||
2093 | |||
2094 | |||
2095 | |||
2096 | 4112 | void LinearProblemFSINitscheXFEMFluid::computeNitscheDpoint_Sigma_v(double velCoeff, double preCoeff) { | |
2097 | // \int_K ddot \cdot (velCoeff \grad v vec - preCoeff q vec) | ||
2098 |
1/2✓ Branch 0 taken 4112 times.
✗ Branch 1 not taken.
|
4112 | if(m_useSymmetricStress) |
2099 | 4112 | m_elementVector[0]->eps_phi_i_dot_vec1_dot_vec2(2.*velCoeff, m_elemFieldNormal, m_strucVelQuadPts, *m_feVel, 0, dimension()); | |
2100 | else | ||
2101 | ✗ | m_elementVector[0]->grad_phi_i_dot_vec1_dot_vec2(velCoeff, m_elemFieldNormal, m_strucVelQuadPts, *m_feVel, 0, dimension()); | |
2102 | |||
2103 |
2/2✓ Branch 1 taken 8224 times.
✓ Branch 2 taken 4112 times.
|
12336 | for(felInt idim=0; idim<dimension(); ++idim) { |
2104 |
2/2✓ Branch 1 taken 24672 times.
✓ Branch 2 taken 8224 times.
|
32896 | for(felInt ig=0; ig<m_feVel->numQuadraturePoint(); ++ig) { |
2105 | 24672 | m_ddotComp.val(0, ig) = m_strucVelQuadPts.val(idim, ig); | |
2106 | } | ||
2107 | 8224 | m_elementVector[0]->source(preCoeff*m_elemFieldNormal.val(idim,0), *m_feVel, m_ddotComp, dimension(), 1); | |
2108 | } | ||
2109 | 4112 | } | |
2110 | |||
2111 | ✗ | void LinearProblemFSINitscheXFEMFluid::computeStenbergSigma_u_Sigma_v(double velCoeff, double preCoeff) { | |
2112 | // \int_K (velCoeff \grad u vec - preCoeff p vec) \cdot q vec | ||
2113 | // assuming same finite element for the pressure and the velocity | ||
2114 | ✗ | std::vector<double> vec(dimension()); | |
2115 | ✗ | for(felInt idim=0; idim<dimension(); ++idim){ | |
2116 | ✗ | for(felInt i=0; i<dimension(); ++i){ | |
2117 | ✗ | vec[i] = 2 * m_elemFieldNormal.val(i,0) * m_elemFieldNormal.val(idim,0); | |
2118 | } | ||
2119 | ✗ | m_elemFieldAux.setValue(vec); | |
2120 | ✗ | if(m_useSymmetricStress) | |
2121 | ✗ | m_elementMat[0]->phi_i_eps_phi_j_dot_vec(2. * velCoeff , m_elemFieldAux, *m_feVel, dimension(), idim, 1); | |
2122 | else | ||
2123 | ✗ | m_elementMat[0]->phi_i_grad_phi_j_dot_vec( velCoeff , m_elemFieldAux, *m_feVel, dimension(), idim, 1); | |
2124 | } | ||
2125 | ✗ | m_elementMat[0]->phi_i_phi_j(preCoeff, *m_feVel, dimension() , dimension(), 1); | |
2126 | } | ||
2127 | |||
2128 | |||
2129 | |||
2130 | |||
2131 | 2 | void LinearProblemFSINitscheXFEMFluid::setStrucFiniteElement(CurvilinearFiniteElement* strucFE) { | |
2132 | 2 | m_feStruc = strucFE; | |
2133 | 2 | } | |
2134 | |||
2135 | 2 | void LinearProblemFSINitscheXFEMFluid::setStrucLinPrb(LinearProblem* pLinPrb) { | |
2136 | 2 | m_pLinStruc = pLinPrb; | |
2137 | 2 | } | |
2138 | |||
2139 | |||
2140 | |||
2141 | |||
2142 | |||
2143 | 4112 | void LinearProblemFSINitscheXFEMFluid::updateStructureVel(felInt strucId, PetscVector& strucVel) { | |
2144 | felInt idSupportEltGlobal; | ||
2145 | felInt idDof; | ||
2146 |
1/2✓ Branch 2 taken 4112 times.
✗ Branch 3 not taken.
|
4112 | felInt idUnknown = m_pLinStruc->listUnknown().getUnknownIdList(displacement); |
2147 | 4112 | felInt idVar = m_pLinStruc->listUnknown().idVariable(idUnknown); | |
2148 | |||
2149 | // get the global support element | ||
2150 | // there should be only one for the structure | ||
2151 |
1/2✓ Branch 2 taken 4112 times.
✗ Branch 3 not taken.
|
4112 | m_pLinStruc->supportDofUnknown(idUnknown).getIdElementSupport(strucId, idSupportEltGlobal); |
2152 | |||
2153 | // loop over all the support dof of this support element | ||
2154 |
2/2✓ Branch 2 taken 8224 times.
✓ Branch 3 taken 4112 times.
|
12336 | for (felInt iSupport = 0; iSupport < m_pLinStruc->supportDofUnknown(idUnknown).getNumSupportDof(idSupportEltGlobal); iSupport++) { |
2155 | // loop over the components | ||
2156 | // for(std::size_t iComp=0; iComp<m_pLinStruc->meshLocal()->numCoor(); ++iComp){ | ||
2157 |
2/2✓ Branch 3 taken 12336 times.
✓ Branch 4 taken 8224 times.
|
20560 | for(std::size_t iComp=0; iComp<m_pLinStruc->listVariable()[idVar].numComponent(); ++iComp) { |
2158 | // local to global id of the dof | ||
2159 |
1/2✓ Branch 2 taken 12336 times.
✗ Branch 3 not taken.
|
12336 | m_pLinStruc->dof().loc2glob(idSupportEltGlobal, iSupport, idVar, iComp, idDof); |
2160 | |||
2161 | // petsc ordering | ||
2162 |
1/2✓ Branch 2 taken 12336 times.
✗ Branch 3 not taken.
|
12336 | AOApplicationToPetsc(m_pLinStruc->ao(), 1, &idDof); |
2163 | |||
2164 | // get values | ||
2165 |
2/4✓ Branch 1 taken 12336 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12336 times.
✗ Branch 5 not taken.
|
12336 | strucVel.getValues(1, &idDof, &m_strucVelDofPts.val(iComp, iSupport)); |
2166 | } | ||
2167 | } | ||
2168 | 4112 | } | |
2169 | |||
2170 | 4112 | void LinearProblemFSINitscheXFEMFluid::updateSubStructureVel(const std::vector<Point*>& ptElem, const std::vector<Point*>& ptSubElem) { | |
2171 |
1/4✗ Branch 1 not taken.
✓ Branch 2 taken 4112 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
4112 | FEL_ASSERT(ptElem.size() == 2); |
2172 | |||
2173 | // compute the value of the displacement at the new integration points | ||
2174 | // get the coordinate of the integration point in the sub element | ||
2175 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | m_feStruc->update(0, ptSubElem); |
2176 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | m_feStruc->computeCurrentQuadraturePoint(); |
2177 | |||
2178 | // compute the coordinate of these integration points in the reference element with the mapping of the | ||
2179 | // structure element (not the structure sub element) | ||
2180 |
1/2✓ Branch 3 taken 4112 times.
✗ Branch 4 not taken.
|
4112 | std::vector<Point> intPoints(m_feStruc->numQuadraturePoint()); |
2181 | double dx, dy; | ||
2182 | 4112 | dx = std::abs(ptElem[1]->x() - ptElem[0]->x()); | |
2183 | 4112 | dy = std::abs(ptElem[1]->y() - ptElem[0]->y()); | |
2184 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4112 times.
|
4112 | if(dx >= dy) { |
2185 | ✗ | for(int ig=0; ig<m_feStruc->numQuadraturePoint(); ++ig) { | |
2186 | ✗ | intPoints[ig][0] = 2.*(m_feStruc->currentQuadPoint[ig].x() - ptElem[0]->x())/(ptElem[1]->x() - ptElem[0]->x()) - 1.; | |
2187 | ✗ | intPoints[ig][1] = 0.; | |
2188 | } | ||
2189 | } else { | ||
2190 |
2/2✓ Branch 1 taken 8224 times.
✓ Branch 2 taken 4112 times.
|
12336 | for(int ig=0; ig<m_feStruc->numQuadraturePoint(); ++ig) { |
2191 | 8224 | intPoints[ig][0]= 2.*(m_feStruc->currentQuadPoint[ig].y() - ptElem[0]->y())/(ptElem[1]->y() - ptElem[0]->y()) - 1.; | |
2192 | 8224 | intPoints[ig][1] = 0; | |
2193 | } | ||
2194 | } | ||
2195 | |||
2196 | // update the structure finite element with the element (really needed ? we only want to access the basis | ||
2197 | // function directly to evaluate them at the computed integration points). | ||
2198 |
1/2✓ Branch 1 taken 4112 times.
✗ Branch 2 not taken.
|
4112 | m_feStruc->update(0, ptElem); |
2199 | |||
2200 | |||
2201 | // Now we can evaluate the basis function of the reference element at the integration points of | ||
2202 | // the sub element | ||
2203 |
2/2✓ Branch 1 taken 2056 times.
✓ Branch 2 taken 2056 times.
|
4112 | if(m_strucVelDofPts.numComp() == 1) { |
2204 | // The solid is a scalar function. The displacement is in the normal direction. | ||
2205 |
2/2✓ Branch 1 taken 4112 times.
✓ Branch 2 taken 2056 times.
|
6168 | for(int icomp=0; icomp<m_feVel->numCoor(); ++icomp) { |
2206 |
2/2✓ Branch 1 taken 8224 times.
✓ Branch 2 taken 4112 times.
|
12336 | for(int ig=0; ig<m_feStruc->numQuadraturePoint(); ++ig) { |
2207 |
1/2✓ Branch 1 taken 8224 times.
✗ Branch 2 not taken.
|
8224 | m_strucVelQuadPts.val(icomp, ig) = 0; |
2208 |
2/2✓ Branch 1 taken 16448 times.
✓ Branch 2 taken 8224 times.
|
24672 | for(int idof=0; idof<m_feStruc->numDof(); ++idof) { |
2209 |
4/8✓ Branch 1 taken 16448 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 16448 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 16448 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 16448 times.
✗ Branch 14 not taken.
|
16448 | m_strucVelQuadPts.val(icomp, ig) += m_strucVelDofPts.val(0, idof) * m_feStruc->refEle().basisFunction().phi(idof, intPoints[ig]) * m_elemFieldNormalInit.val(icomp, 0); |
2210 | } | ||
2211 | } | ||
2212 | } | ||
2213 | } else { | ||
2214 | // The solid is a std::vector. | ||
2215 |
2/2✓ Branch 1 taken 4112 times.
✓ Branch 2 taken 2056 times.
|
6168 | for(int icomp=0; icomp<m_feVel->numCoor(); ++icomp) { |
2216 |
2/2✓ Branch 1 taken 8224 times.
✓ Branch 2 taken 4112 times.
|
12336 | for(int ig=0; ig<m_feStruc->numQuadraturePoint(); ++ig) { |
2217 |
1/2✓ Branch 1 taken 8224 times.
✗ Branch 2 not taken.
|
8224 | m_strucVelQuadPts.val(icomp, ig) = 0; |
2218 |
2/2✓ Branch 1 taken 16448 times.
✓ Branch 2 taken 8224 times.
|
24672 | for(int idof=0; idof<m_feStruc->numDof(); ++idof) { |
2219 |
3/6✓ Branch 1 taken 16448 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 16448 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 16448 times.
✗ Branch 11 not taken.
|
16448 | m_strucVelQuadPts.val(icomp, ig) += m_strucVelDofPts.val(icomp, idof) * m_feStruc->refEle().basisFunction().phi(idof, intPoints[ig]); |
2220 | } | ||
2221 | } | ||
2222 | } | ||
2223 | } | ||
2224 | 4112 | } | |
2225 | |||
2226 | |||
2227 | 141072 | void LinearProblemFSINitscheXFEMFluid::computeElementMatrixRHS() { | |
2228 | // mass coefficient | ||
2229 | 141072 | double coef = m_density/m_fstransient->timeStep; | |
2230 | |||
2231 | //================================ | ||
2232 | // matrix | ||
2233 | //================================ | ||
2234 | |||
2235 | // Laplacian operator | ||
2236 |
1/2✓ Branch 0 taken 141072 times.
✗ Branch 1 not taken.
|
141072 | if (m_useSymmetricStress) { |
2237 | // \mu \int \epsilon u^{n+1} : \epsilon v | ||
2238 | 141072 | m_elementMat[0]->eps_phi_i_eps_phi_j(2*m_viscosity,*m_feVel, 0, 0, dimension()); | |
2239 | } else { | ||
2240 | // \mu \int \nabla u^{n+1} : \nabla v | ||
2241 | ✗ | m_elementMat[0]->grad_phi_i_grad_phi_j(m_viscosity, *m_feVel, 0, 0, dimension()); | |
2242 | } | ||
2243 | |||
2244 | // div and grad operator | ||
2245 | // \int q \nabla \cdot u^{n+1} and \int p \nabla \cdot v | ||
2246 | 141072 | m_elementMat[0]->psi_j_div_phi_i_and_psi_i_div_phi_j (*m_feVel, *m_fePres, 0, m_velocity->numComponent(), -1, -1); | |
2247 | |||
2248 | // mass matrix from the time scheme | ||
2249 | // \int u^{n+1} \cdot v | ||
2250 | 141072 | m_elementMat[0]->phi_i_phi_j(m_bdf->coeffDeriv0()*coef, *m_feVel, 0, 0, dimension()); | |
2251 | 141072 | } | |
2252 | |||
2253 | |||
2254 | 141168 | void LinearProblemFSINitscheXFEMFluid::computeElementMatrixRHSPartDependingOnOldTimeStep(felInt iel, felInt ielOld, felInt idTimeStep) { | |
2255 | // --------------- // | ||
2256 | // convective term // | ||
2257 | // --------------- // | ||
2258 |
1/3✗ Branch 1 not taken.
✓ Branch 2 taken 141168 times.
✗ Branch 3 not taken.
|
141168 | switch(FelisceParam::instance().NSequationFlag) { |
2259 | ✗ | case 0: | |
2260 | // Stoke's model, no convective term | ||
2261 | ✗ | break; | |
2262 | |||
2263 | 141168 | case 1: | |
2264 | // classic Navier Stokes convective term : \rho (u \cdot \grad) u | ||
2265 | // Natural condition: \sigma(u,p) \cdot n = 0 | ||
2266 | // discretization : \rho (u^{n} \cdot \grad) u^{n+1} | ||
2267 | // DEFAULT METHOD | ||
2268 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 141168 times.
|
141168 | if(FelisceParam::instance().useProjectionForNitscheXFEM) |
2269 | ✗ | m_elemFieldAdv.setValue(m_seqVelExtrapol[idTimeStep], *m_feVel, iel, m_iVelocity, m_ao, dof()); | |
2270 | else | ||
2271 | 141168 | m_elemFieldAdv.setValue(m_seqVelExtrapol[idTimeStep], *m_feVel, ielOld, m_iVelocity, m_aoOld[idTimeStep], m_dofOld[idTimeStep]); | |
2272 | |||
2273 | 141168 | m_elementMat[0]->u_grad_phi_j_phi_i(m_density, m_elemFieldAdv, *m_feVel, 0, 0, dimension()); | |
2274 | |||
2275 | |||
2276 | // Temam's operator to stabilize the convective term | ||
2277 | // Convective term in energy balance : | ||
2278 | // ... + \rho/2 \int_Gamma (u^n.n)|u^n+1|^2 - \rho/2 \int_Omega (\nabla . u^n) |u^n+1|^2 + ... | ||
2279 | // Add \rho/2 \int_Omega (\nabla . u^n) u^n+1 v to delete the second term. | ||
2280 | // it's consistent with the exact solution (divergence = 0) | ||
2281 | 141168 | m_elementMat[0]->div_u_phi_j_phi_i(0.5*m_density, m_elemFieldAdv, *m_feVel, 0, 0, dimension()); | |
2282 | 141168 | break; | |
2283 | |||
2284 | ✗ | default: | |
2285 | ✗ | FEL_ERROR("Error: Wrong or not implemented convection method, check the param NSequationFlag in the data file"); | |
2286 | } | ||
2287 | |||
2288 | |||
2289 | |||
2290 | //================================ | ||
2291 | // RHS | ||
2292 | //================================ | ||
2293 | // bdf | ||
2294 | // \frac{\rho}{\dt} \sum_{i=1}^k \alpha_i u_{n+1-i} | ||
2295 | // 'm_density' and not 'coef' because the time step is integrated into the bdf term | ||
2296 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 141168 times.
|
141168 | if(FelisceParam::instance().useProjectionForNitscheXFEM) |
2297 | ✗ | m_elemFieldRHSbdf.setValue(m_seqBdfRHS[idTimeStep], *m_feVel, iel, m_iVelocity, m_ao, dof()); | |
2298 | else | ||
2299 | 141168 | m_elemFieldRHSbdf.setValue(m_seqBdfRHS[idTimeStep], *m_feVel, ielOld, m_iVelocity, m_aoOld[idTimeStep], m_dofOld[idTimeStep]); | |
2300 | |||
2301 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 141168 times.
|
141168 | assert(!m_elementVector.empty()); |
2302 | 141168 | m_elementVector[0]->source(m_density, *m_feVel, m_elemFieldRHSbdf, 0, dimension()); | |
2303 | |||
2304 | |||
2305 | // --------------------------------------------------------------------- // | ||
2306 | // SUPG Stabilization (works with a bdf 1 but wrong with a higher order) // | ||
2307 | // --------------------------------------------------------------------- // | ||
2308 |
2/6✗ Branch 2 not taken.
✓ Branch 3 taken 141168 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 141168 times.
✗ Branch 8 not taken.
|
141168 | if((m_velocity->finiteElementType() == m_pressure->finiteElementType()) || FelisceParam::instance().NSequationFlag == 1) { |
2309 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 141168 times.
|
141168 | if(FelisceParam::instance().NSStabType == 0) { |
2310 | ✗ | double stab1 = FelisceParam::instance().stabSUPG; | |
2311 | ✗ | double stab2 = FelisceParam::instance().stabdiv; | |
2312 | ✗ | int type = FelisceParam::instance().typeSUPG; | |
2313 | double Re_elem, tau; | ||
2314 | |||
2315 | // compute advection velocity | ||
2316 | ✗ | if(FelisceParam::instance().useProjectionForNitscheXFEM) | |
2317 | ✗ | m_elemFieldAdv.setValue(m_seqVelExtrapol[idTimeStep], *m_feVel, iel, m_iVelocity, m_ao, dof()); | |
2318 | else | ||
2319 | ✗ | m_elemFieldAdv.setValue(m_seqVelExtrapol[idTimeStep], *m_feVel, ielOld, m_iVelocity, m_aoOld[idTimeStep], m_dofOld[idTimeStep]); | |
2320 | |||
2321 | // Beware: if elemFieldRHS is modified in userNS, it wont be considered here... | ||
2322 | // (usually elemFieldRHS = 0 (no body force)) | ||
2323 | ✗ | m_elementMat[0]->stab_supg(m_fstransient->timeStep, | |
2324 | ✗ | stab1, stab2, m_density, m_viscosity, *m_feVel, | |
2325 | ✗ | m_elemFieldAdv, m_elemFieldRHS, *m_elementVector[0], | |
2326 | Re_elem, tau, type); | ||
2327 | } | ||
2328 | } | ||
2329 | 141168 | } | |
2330 | |||
2331 | |||
2332 | |||
2333 | |||
2334 | |||
2335 | /*! | ||
2336 | * Gather the extrapolation of the velocity into m_seqVelExtrapol. | ||
2337 | * If m_seqVelExtrapol is null, it will be created and allocated during the gathering | ||
2338 | * according to the parallel shape of parallelVec | ||
2339 | */ | ||
2340 | 20 | void LinearProblemFSINitscheXFEMFluid::gatherSeqVelExtrapol(std::vector<PetscVector>& parallelVec) { | |
2341 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 2 taken 20 times.
|
40 | for(std::size_t i=0; i<parallelVec.size(); ++i) |
2342 | 20 | gatherVector(parallelVec[i], m_seqVelExtrapol[i]); | |
2343 | |||
2344 | 20 | m_isSeqVelExtrapolAllocated = true; | |
2345 | 20 | } | |
2346 | |||
2347 | ✗ | PetscVector& LinearProblemFSINitscheXFEMFluid::getVelExtrapol(felInt n) { | |
2348 | ✗ | return m_seqVelExtrapol[n]; | |
2349 | } | ||
2350 | |||
2351 | |||
2352 | /*! | ||
2353 | * Gather the rhs part of the time derivative of the velocity into m_seqBdfRHS. | ||
2354 | * If m_seqBdfRHS is null, it will be created and allocated during the gathering | ||
2355 | * according to the parallel shape of bdf->vector() | ||
2356 | */ | ||
2357 | 20 | void LinearProblemFSINitscheXFEMFluid::gatherSeqBdfRHS(std::vector<PetscVector>& parallelVec) { | |
2358 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 2 taken 20 times.
|
40 | for(std::size_t i=0; i<parallelVec.size(); ++i) |
2359 | 20 | gatherVector(parallelVec[i], m_seqBdfRHS[i]); | |
2360 | |||
2361 | 20 | m_isSeqBdfRHSAllocated = true; | |
2362 | 20 | } | |
2363 | |||
2364 | |||
2365 | |||
2366 | ✗ | void LinearProblemFSINitscheXFEMFluid::addMatrixRHS() { | |
2367 | ✗ | matrix(0).axpy(1,matrix(1),SAME_NONZERO_PATTERN); | |
2368 | } | ||
2369 | |||
2370 | /*! | ||
2371 | \brief Duplicate the support dof intersected by the structure | ||
2372 | */ | ||
2373 | 13 | void LinearProblemFSINitscheXFEMFluid::initSupportDofDerivedProblem() { | |
2374 | /////////////////////////////// | ||
2375 | // duplicate the support dof // | ||
2376 | /////////////////////////////// | ||
2377 | 13 | m_duplicateSupportElements->duplicateIntersectedSupportElements(m_supportDofUnknown); | |
2378 | 13 | } | |
2379 | |||
2380 | |||
2381 | /*! | ||
2382 | \brief Initialize the bdf for the solution defined on the non duplicated support dof mesh | ||
2383 | */ | ||
2384 | 2 | void LinearProblemFSINitscheXFEMFluid::initOriginalBdf(felInt timeScheme, felInt extrapolOrder) { | |
2385 | // create the std::vector solution with the original supportDofMesh | ||
2386 | // first, compute the number of dof in the original supportDofMesh | ||
2387 | 2 | felInt idVar = 0; | |
2388 | 2 | felInt numSupportOfDof = 0; | |
2389 | 2 | m_numOriginalDof = 0; | |
2390 | |||
2391 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
|
6 | for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); ++iUnknown) { |
2392 | 4 | idVar = m_listUnknown.idVariable(iUnknown); | |
2393 | 4 | numSupportOfDof = m_supportDofUnknownOriginal[iUnknown]->numSupportDof(); | |
2394 | 4 | m_numOriginalDof += numSupportOfDof * m_listVariable[idVar].numComponent(); | |
2395 | } | ||
2396 | |||
2397 | 2 | m_tmpSeqOriginalSol.create(PETSC_COMM_SELF); | |
2398 | 2 | m_tmpSeqOriginalSol.setType(VECSEQ); | |
2399 | 2 | m_tmpSeqOriginalSol.setSizes(PETSC_DECIDE, m_numOriginalDof); | |
2400 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_tmpSeqOriginalSol.set(0.); |
2401 | |||
2402 | // initialize the bdf storing all fluid solution with the original support dof mesh | ||
2403 | 2 | m_seqOriginalSolutions.defineOrder(FelisceParam::instance().orderBdfNS); | |
2404 | |||
2405 |
4/8✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
|
2 | if(FelisceParam::instance().orderBdfNS == 1 && timeScheme == 3 && extrapolOrder == 2) { |
2406 | 2 | m_seqOriginalSolutions.initialize(m_tmpSeqOriginalSol, m_tmpSeqOriginalSol); | |
2407 | ✗ | } else if ( ((timeScheme == 0) || (timeScheme == 2)) && extrapolOrder == 2 ) { | |
2408 | ✗ | m_seqOriginalSolutions.initialize(m_tmpSeqOriginalSol, m_tmpSeqOriginalSol); | |
2409 | } else { | ||
2410 | ✗ | m_seqOriginalSolutions.initialize(m_tmpSeqOriginalSol); | |
2411 | } | ||
2412 | 2 | m_isSeqOriginalSolAllocated = true; | |
2413 | 2 | } | |
2414 | |||
2415 | |||
2416 | 2 | void LinearProblemFSINitscheXFEMFluid::setDuplicateSupportObject(DuplicateSupportDof* object) { | |
2417 | 2 | m_duplicateSupportElements = object; | |
2418 | 2 | } | |
2419 | |||
2420 | |||
2421 | 13 | void LinearProblemFSINitscheXFEMFluid::copyCurrentSolToOriginalSol() { | |
2422 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
|
13 | if(!m_isSeqOriginalSolAllocated) { |
2423 | ✗ | FEL_ERROR("The bdf storing all the data with the original supportDofMesh should already be created at this point"); | |
2424 | } | ||
2425 | |||
2426 | // get the last original solution (will be deleted after the update anyway) | ||
2427 | // m_tmpSeqOriginalSol.copyFrom(m_seqOriginalSolutions.sol_n()); | ||
2428 | // m_tmpSeqOriginalSol.set(0.); | ||
2429 | 13 | felInt numTotalDof = 0; | |
2430 | 13 | felInt numTotalDofOriginal = 0; | |
2431 | |||
2432 | // Copy only the value of the original support dofs | ||
2433 | // All the id of the duplicated points are at the end. The ids of the original points are thus from 0 to the | ||
2434 | // number of support dof in the original supportDofMesh | ||
2435 |
2/2✓ Branch 1 taken 26 times.
✓ Branch 2 taken 13 times.
|
39 | for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); ++iUnknown) { |
2436 | 26 | felInt idVar = m_listUnknown.idVariable(iUnknown); | |
2437 | 26 | felInt numOriginalSupportDof = m_supportDofUnknownOriginal[iUnknown]->numSupportDof(); | |
2438 | 26 | felInt numOriginalDofOfUnknown = numOriginalSupportDof * m_listVariable[idVar].numComponent(); | |
2439 | |||
2440 |
1/2✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
|
26 | std::vector<felInt> ids(numOriginalDofOfUnknown); |
2441 |
1/2✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
|
26 | std::vector<double> values(numOriginalDofOfUnknown, 0.); |
2442 |
2/2✓ Branch 1 taken 70590 times.
✓ Branch 2 taken 26 times.
|
70616 | for(std::size_t i=0; i<ids.size(); ++i) { |
2443 | 70590 | ids[i] = i + numTotalDof; | |
2444 | } | ||
2445 | |||
2446 |
1/2✓ Branch 4 taken 26 times.
✗ Branch 5 not taken.
|
26 | sequentialSolution().getValues(numOriginalDofOfUnknown, ids.data(), values.data()); |
2447 | |||
2448 |
2/2✓ Branch 1 taken 70590 times.
✓ Branch 2 taken 26 times.
|
70616 | for(std::size_t i=0; i<ids.size(); ++i) { |
2449 | 70590 | ids[i] = i + numTotalDofOriginal; | |
2450 | } | ||
2451 | |||
2452 |
1/2✓ Branch 3 taken 26 times.
✗ Branch 4 not taken.
|
26 | m_tmpSeqOriginalSol.setValues(numOriginalDofOfUnknown, ids.data(), values.data(), INSERT_VALUES); |
2453 | |||
2454 | 26 | numTotalDof += supportDofUnknown(iUnknown).numSupportDof() * m_listVariable[idVar].numComponent(); | |
2455 | 26 | numTotalDofOriginal += numOriginalDofOfUnknown; | |
2456 | 26 | } | |
2457 | |||
2458 | 13 | m_tmpSeqOriginalSol.assembly(); | |
2459 | |||
2460 | // update the bdf of the original support dof mesh | ||
2461 | 13 | m_seqOriginalSolutions.update(m_tmpSeqOriginalSol); | |
2462 | 13 | } | |
2463 | |||
2464 | |||
2465 | 11 | void LinearProblemFSINitscheXFEMFluid::copyOriginalToCurrent(PetscVector& vecSeqOriginal, PetscVector& vecSeqCurrent, PetscVector& vecParCurrent) { | |
2466 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | PetscVector tmpSeqVec; |
2467 |
2/4✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
|
11 | if(vecSeqCurrent.isNull()) { |
2468 | ✗ | tmpSeqVec.duplicateFrom(sequentialSolution()); | |
2469 | } else { | ||
2470 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | tmpSeqVec = vecSeqCurrent; |
2471 | } | ||
2472 | |||
2473 | // copy the serial solution | ||
2474 | 11 | felInt numTotalDof = 0; | |
2475 | 11 | felInt numTotalDofOriginal = 0; | |
2476 | |||
2477 |
2/2✓ Branch 1 taken 22 times.
✓ Branch 2 taken 11 times.
|
33 | for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); ++iUnknown) { |
2478 | 22 | felInt idVar = m_listUnknown.idVariable(iUnknown); | |
2479 | 22 | felInt numComp = m_listVariable[idVar].numComponent(); | |
2480 | |||
2481 | 22 | felInt numOriginalSupportDof = m_supportDofUnknownOriginal[iUnknown]->numSupportDof(); | |
2482 | 22 | felInt numOriginalDofOfUnknown = numOriginalSupportDof * numComp; | |
2483 | |||
2484 | 22 | felInt numSupportDof = supportDofUnknown(iUnknown).numSupportDof(); | |
2485 | 22 | felInt numDofOfUnknown = numSupportDof * numComp; | |
2486 | |||
2487 |
1/2✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
|
22 | std::vector<felInt> ids(numDofOfUnknown, -1); |
2488 |
1/2✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
|
22 | std::vector<double> values(numDofOfUnknown, 0.); |
2489 | |||
2490 | // get the id of the dofs in the original std::vector (duplicate the id of the duplicate dof in the current) | ||
2491 |
2/2✓ Branch 0 taken 59730 times.
✓ Branch 1 taken 22 times.
|
59752 | for(felInt i=0; i<numOriginalDofOfUnknown; ++i) { |
2492 | 59730 | ids[i] = i + numTotalDofOriginal; | |
2493 | } | ||
2494 | |||
2495 | 22 | felInt count = numOriginalDofOfUnknown; | |
2496 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | auto& idVerMsh = m_duplicateSupportElements->getIntersectedVerMsh(); |
2497 |
2/2✓ Branch 4 taken 818 times.
✓ Branch 5 taken 22 times.
|
840 | for(auto it = idVerMsh.begin(); it != idVerMsh.end(); ++it) { |
2498 |
2/2✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 818 times.
|
2045 | for(felInt i=0; i<numComp; ++i) { |
2499 | 1227 | ids[count++] = numTotalDofOriginal + it->first * numComp + i; | |
2500 | } | ||
2501 | } | ||
2502 | |||
2503 | // get the values in the serial original std::vector (we get multiple times the duplicated ones) | ||
2504 |
1/2✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
|
22 | vecSeqOriginal.getValues(numDofOfUnknown, ids.data(), values.data()); |
2505 | |||
2506 | // get the id in the current std::vector | ||
2507 |
2/2✓ Branch 1 taken 60957 times.
✓ Branch 2 taken 22 times.
|
60979 | for(std::size_t i=0; i<ids.size(); ++i) { |
2508 | 60957 | ids[i] = i + numTotalDof; | |
2509 | } | ||
2510 | |||
2511 |
1/2✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
|
22 | tmpSeqVec.setValues(numDofOfUnknown, ids.data(), values.data(), INSERT_VALUES); |
2512 | |||
2513 | 22 | numTotalDof += numDofOfUnknown; | |
2514 | 22 | numTotalDofOriginal += numOriginalDofOfUnknown; | |
2515 | 22 | } | |
2516 | |||
2517 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | tmpSeqVec.assembly(); |
2518 | |||
2519 | // scatter the serial solution to the parallel one | ||
2520 |
2/4✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
✗ Branch 4 not taken.
|
11 | if(vecParCurrent.isNotNull()) { |
2521 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | tmpSeqVec.scatterToZeroNotCreatingVector(vecParCurrent, INSERT_VALUES, SCATTER_REVERSE); |
2522 | } | ||
2523 | |||
2524 |
2/4✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
|
11 | if(vecSeqCurrent.isNull()) { |
2525 | ✗ | tmpSeqVec.destroy(); | |
2526 | } | ||
2527 | 11 | } | |
2528 | |||
2529 | |||
2530 | 11 | void LinearProblemFSINitscheXFEMFluid::deleteDynamicData() { | |
2531 | // here, we delete all the matrices, vectors and mapping of the linear problem. | ||
2532 | // everything will be rebuilt at the next iteration | ||
2533 | // This is almost a copy of the destructor of LinearProblem | ||
2534 | |||
2535 | // sequential solution | ||
2536 | 11 | bool& isSeqSolAlloc = isSequentialSolutionAllocated(); | |
2537 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | if(isSeqSolAlloc) { |
2538 | 11 | sequentialSolution().destroy(); | |
2539 | 11 | isSeqSolAlloc = false; | |
2540 | } | ||
2541 | |||
2542 | // element matrices and matrices | ||
2543 | 11 | m_elementMat.clear(); | |
2544 | |||
2545 | // element vectors | ||
2546 | 11 | m_elementVector.clear(); | |
2547 | 11 | m_elementMatBD.clear(); | |
2548 | 11 | m_elementVectorBD.clear(); | |
2549 | |||
2550 | // solution and rhs | ||
2551 | 11 | bool& areSolAndRhsAlloc = areSolutionAndRHSAllocated(); | |
2552 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | if (areSolAndRhsAlloc) { |
2553 |
2/2✓ Branch 1 taken 11 times.
✓ Branch 2 taken 11 times.
|
22 | for (unsigned int i = 0; i < numberOfVectors(); i++) |
2554 | 11 | vector(i).destroy(); | |
2555 | |||
2556 | 11 | solution().destroy(); | |
2557 | 11 | areSolAndRhsAlloc = false; | |
2558 | } | ||
2559 | |||
2560 | // finite elements | ||
2561 | 11 | m_listCurrentFiniteElement.clear(); | |
2562 | 11 | m_listCurvilinearFiniteElement.clear(); | |
2563 | |||
2564 | // mappings | ||
2565 | 11 | bool& isMapElemAlloc = isMappingElemAllocated(); | |
2566 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | if(isMapElemAlloc) { |
2567 | 11 | ISLocalToGlobalMappingDestroy(&mappingElem()); | |
2568 | 11 | isMapElemAlloc = false; | |
2569 | } | ||
2570 | |||
2571 | 11 | bool& isMapElemSupportAlloc = isMappingElemSupportAllocated(); | |
2572 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | if(isMapElemSupportAlloc) { |
2573 |
2/2✓ Branch 1 taken 22 times.
✓ Branch 2 taken 11 times.
|
33 | for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ ) |
2574 | 22 | ISLocalToGlobalMappingDestroy(mappingElemSupportPerUnknown(iUnknown)); | |
2575 | |||
2576 | 11 | isMapElemSupportAlloc = false; | |
2577 | } | ||
2578 | |||
2579 | 11 | bool& isMapNodesAlloc = isMappingNodesAllocated(); | |
2580 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | if(isMapNodesAlloc) { |
2581 | 11 | ISLocalToGlobalMappingDestroy(&mappingNodes()); | |
2582 | 11 | isMapNodesAlloc = false; | |
2583 | } | ||
2584 | |||
2585 | 11 | bool& isMapFelToPetscAlloc = isMappingLocalFelisceToGlobalPetscAllocated(); | |
2586 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | if(isMapFelToPetscAlloc) { |
2587 |
2/2✓ Branch 1 taken 22 times.
✓ Branch 2 taken 11 times.
|
33 | for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ ) |
2588 | 22 | ISLocalToGlobalMappingDestroy(&mappingIdFelisceToPetsc(iUnknown)); | |
2589 | |||
2590 | 11 | isMapFelToPetscAlloc = false; | |
2591 | } | ||
2592 | |||
2593 | // AO (copy the AO, it will be destroy with the old one) | ||
2594 | 11 | bool& isAOAlloc = isAOAllocated(); | |
2595 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | if(isAOAlloc) { |
2596 | 11 | AODestroy(&ao()); | |
2597 | 11 | isAOAlloc = false; | |
2598 | } | ||
2599 | |||
2600 | |||
2601 | // dofs (the pattern is useless for the old dof) | ||
2602 | 11 | dof().numDof() = 0; | |
2603 | 11 | dof().numDofPerUnknown().clear(); | |
2604 | 11 | dof().clearPattern(); | |
2605 | |||
2606 | |||
2607 | // repartition of the dof | ||
2608 | 11 | m_dofPart.clear(); | |
2609 | 11 | m_eltPart.clear(); | |
2610 | |||
2611 | |||
2612 | // supportDofMesh (copy the old one) | ||
2613 | 11 | m_supportDofUnknown.clear(); | |
2614 | 11 | m_supportDofUnknownLocal.clear(); | |
2615 | |||
2616 | |||
2617 | // local mesh | ||
2618 | 11 | m_meshLocal[m_currentMesh]->domainDim() = GeometricMeshRegion::GeoMeshUndefined; | |
2619 | 11 | m_meshLocal[m_currentMesh]->deleteElements(); | |
2620 | |||
2621 | // extrapolation and time rhs of this class | ||
2622 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | if(m_isSeqVelExtrapolAllocated) { |
2623 | ✗ | for(std::size_t i=0; i<m_seqVelExtrapol.size(); ++i) { | |
2624 | ✗ | m_seqVelExtrapol[i].destroy(); | |
2625 | ✗ | m_seqVelExtrapol[i] = PetscVector::null(); | |
2626 | } | ||
2627 | ✗ | m_isSeqVelExtrapolAllocated = false; | |
2628 | } | ||
2629 | |||
2630 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | if(m_isSeqBdfRHSAllocated) { |
2631 | ✗ | for(std::size_t i=0; i<m_seqBdfRHS.size(); ++i) { | |
2632 | ✗ | m_seqBdfRHS[i].destroy(); | |
2633 | ✗ | m_seqBdfRHS[i] = PetscVector::null(); | |
2634 | } | ||
2635 | ✗ | m_isSeqBdfRHSAllocated = false; | |
2636 | } | ||
2637 | |||
2638 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | if(m_isSeqRNFluidExtrapolAllocated) { |
2639 | ✗ | for(std::size_t i=0; i<m_seqRNFluidExtrapol.size(); ++i) { | |
2640 | ✗ | m_seqRNFluidExtrapol[i].destroy(); | |
2641 | ✗ | m_seqRNFluidExtrapol[i] = PetscVector::null(); | |
2642 | } | ||
2643 | ✗ | m_isSeqRNFluidExtrapolAllocated = false; | |
2644 | } | ||
2645 | 11 | } | |
2646 | |||
2647 | |||
2648 | 11 | void LinearProblemFSINitscheXFEMFluid::copyOriginalSolToCurrentSol() { | |
2649 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | if(!m_isSeqOriginalSolAllocated) { |
2650 | ✗ | FEL_ERROR("The bdf storing all the data with the original supportDofMesh should already be created at this point"); | |
2651 | } | ||
2652 | |||
2653 | 11 | copyOriginalToCurrent(m_seqOriginalSolutions.sol_n(), sequentialSolution(), solution()); | |
2654 | 11 | } | |
2655 | |||
2656 | |||
2657 | ✗ | void LinearProblemFSINitscheXFEMFluid::copyOriginalBdfToCurrentBdf(felInt timeScheme, felInt extrapolOrder) { | |
2658 | ✗ | if(!m_isSeqOriginalSolAllocated) { | |
2659 | ✗ | FEL_ERROR("The bdf storing all the data with the original supportDofMesh should already be created at this point"); | |
2660 | } | ||
2661 | |||
2662 | // first, reinitialize the bdf with the solution to get vectors of right size | ||
2663 | ✗ | felInt order = FelisceParam::instance().orderBdfNS; | |
2664 | |||
2665 | // copy all bdf solution | ||
2666 | ✗ | PetscVector zero = PetscVector::null(); | |
2667 | ✗ | if(order == 1) { | |
2668 | ✗ | if(timeScheme == 3 && extrapolOrder == 2) { | |
2669 | ✗ | m_bdf->reinitialize(order, solution(), solution(), zero); | |
2670 | ✗ | copyOriginalToCurrent(m_seqOriginalSolutions.sol_n_1(), zero, m_bdf->sol_n_1()); | |
2671 | ✗ | } else if ( ((timeScheme == 0) || (timeScheme == 2)) && extrapolOrder == 2) { | |
2672 | ✗ | m_bdf->reinitialize(order, solution(), solution(), zero); | |
2673 | ✗ | copyOriginalToCurrent(m_seqOriginalSolutions.sol_n_1(), zero, m_bdf->sol_n_1()); | |
2674 | }else { | ||
2675 | ✗ | m_bdf->reinitialize(order, solution(), zero, zero); | |
2676 | } | ||
2677 | ✗ | } else if(order == 2) { | |
2678 | ✗ | m_bdf->reinitialize(order, solution(), solution(), zero); | |
2679 | ✗ | copyOriginalToCurrent(m_seqOriginalSolutions.sol_n_1(), zero, m_bdf->sol_n_1()); | |
2680 | } else { | ||
2681 | ✗ | FEL_ERROR("Wrong bdf order"); | |
2682 | } | ||
2683 | } | ||
2684 | |||
2685 | |||
2686 | |||
2687 | 2 | void LinearProblemFSINitscheXFEMFluid::initOldObjects(felInt stabExplicitExtrapolOrder) { | |
2688 | // compute how many old solution we need to store | ||
2689 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | felInt order = std::max(stabExplicitExtrapolOrder, FelisceParam::instance().orderBdfNS); |
2690 | |||
2691 | // resize std::vector | ||
2692 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_sequentialSolutionOld.resize(order); |
2693 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_solutionOld.resize(order); |
2694 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_aoOld.resize(order); |
2695 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_supportDofUnknownOld.resize(order); |
2696 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | m_dofOld.resize(order); |
2697 | |||
2698 | |||
2699 | // init old solution | ||
2700 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
|
6 | for(std::size_t i=0; i<m_sequentialSolutionOld.size(); ++i) { |
2701 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | m_sequentialSolutionOld[i].duplicateFrom(sequentialSolution()); |
2702 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | m_sequentialSolutionOld[i].copyFrom(sequentialSolution()); |
2703 | } | ||
2704 | |||
2705 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
|
6 | for(std::size_t i=0; i<m_solutionOld.size(); ++i) { |
2706 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | m_solutionOld[i].duplicateFrom(solution()); |
2707 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | m_solutionOld[i].copyFrom(solution()); |
2708 | } | ||
2709 | |||
2710 | |||
2711 | // init old AO | ||
2712 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
|
6 | for(std::size_t i=0; i<m_aoOld.size(); ++i) { |
2713 | 4 | m_aoOld[i] = ao(); | |
2714 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | PetscObjectReference((PetscObject)ao()); |
2715 | } | ||
2716 | |||
2717 | |||
2718 | // init old support dof | ||
2719 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
|
6 | for(std::size_t i=0; i<m_supportDofUnknownOld.size(); ++i) |
2720 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | m_supportDofUnknownOld[i] = m_supportDofUnknown; |
2721 | |||
2722 | |||
2723 | // init old dof | ||
2724 |
1/2✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
2 | std::vector<SupportDofMesh*> pSupportDofUnknown(m_supportDofUnknown.size(), nullptr); |
2725 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
|
6 | for(std::size_t i=0; i<m_dofOld.size(); ++i) { |
2726 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 4 times.
|
12 | for(std::size_t iUnknown=0; iUnknown < m_supportDofUnknown.size(); ++iUnknown) |
2727 | 8 | pSupportDofUnknown[iUnknown] = &m_supportDofUnknownOld[i][iUnknown]; | |
2728 | |||
2729 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | m_dofOld[i].setDof(m_listUnknown, m_listVariable, pSupportDofUnknown); |
2730 | 4 | m_dofOld[i].numDof() = dof().numDof(); | |
2731 |
1/2✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
4 | m_dofOld[i].numDofPerUnknown() = dof().numDofPerUnknown(); |
2732 | } | ||
2733 | 2 | } | |
2734 | |||
2735 | |||
2736 | 18 | void LinearProblemFSINitscheXFEMFluid::updateOldSolution(felInt countInitOld) { | |
2737 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
|
18 | if(countInitOld > 0) { |
2738 | // sequential solution | ||
2739 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | m_sequentialSolutionOld[m_sequentialSolutionOld.size() - 1].destroy(); |
2740 |
2/2✓ Branch 1 taken 16 times.
✓ Branch 2 taken 16 times.
|
32 | for(std::size_t i=m_sequentialSolutionOld.size() - 1; i>0; --i) |
2741 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | m_sequentialSolutionOld[i] = m_sequentialSolutionOld[i-1]; |
2742 | |||
2743 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | m_sequentialSolutionOld[0].duplicateFrom(sequentialSolution()); |
2744 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | m_sequentialSolutionOld[0].copyFrom(sequentialSolution()); |
2745 | |||
2746 | |||
2747 | // parallel solution | ||
2748 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | m_solutionOld[m_solutionOld.size() - 1].destroy(); |
2749 |
2/2✓ Branch 1 taken 16 times.
✓ Branch 2 taken 16 times.
|
32 | for(std::size_t i=m_solutionOld.size() - 1; i>0; --i) |
2750 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | m_solutionOld[i] = m_solutionOld[i-1]; |
2751 | |||
2752 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | m_solutionOld[0].duplicateFrom(solution()); |
2753 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | m_solutionOld[0].copyFrom(solution()); |
2754 | |||
2755 | |||
2756 | // AO | ||
2757 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | AODestroy(&m_aoOld[m_aoOld.size() - 1]); |
2758 |
2/2✓ Branch 1 taken 16 times.
✓ Branch 2 taken 16 times.
|
32 | for(std::size_t i=m_aoOld.size() - 1; i>0; --i) |
2759 | 16 | m_aoOld[i] = m_aoOld[i-1]; | |
2760 | 16 | m_aoOld[0] = ao(); | |
2761 |
1/2✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
16 | PetscObjectReference((PetscObject)ao()); |
2762 | |||
2763 | |||
2764 | // supportDofMesh (copy the old one) | ||
2765 |
2/2✓ Branch 1 taken 16 times.
✓ Branch 2 taken 16 times.
|
32 | for(std::size_t i=m_supportDofUnknownOld.size() - 1; i>0; --i) |
2766 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | m_supportDofUnknownOld[i] = m_supportDofUnknownOld[i-1]; |
2767 |
1/2✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
16 | m_supportDofUnknownOld[0] = m_supportDofUnknown; |
2768 | |||
2769 | |||
2770 | // dofs | ||
2771 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | std::vector<SupportDofMesh*> pSupportDofUnknown(m_supportDofUnknown.size(), nullptr); |
2772 |
2/2✓ Branch 1 taken 16 times.
✓ Branch 2 taken 16 times.
|
32 | for(std::size_t i=m_dofOld.size() - 1; i>0; --i) { |
2773 | 16 | m_dofOld[i].numDof() = m_dofOld[i-1].numDof(); | |
2774 |
1/2✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
|
16 | m_dofOld[i].numDofPerUnknown() = m_dofOld[i-1].numDofPerUnknown(); |
2775 | } | ||
2776 | |||
2777 | 16 | m_dofOld[0].numDof() = dof().numDof(); | |
2778 |
1/2✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
|
16 | m_dofOld[0].numDofPerUnknown() = dof().numDofPerUnknown(); |
2779 | |||
2780 | |||
2781 | // delete extrapolations | ||
2782 |
2/2✓ Branch 1 taken 16 times.
✓ Branch 2 taken 16 times.
|
32 | for(std::size_t i=0; i<m_seqVelExtrapol.size(); ++i) { |
2783 |
1/2✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
16 | m_seqVelExtrapol[i].destroy(); |
2784 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
|
16 | m_seqVelExtrapol[i] = PetscVector::null(); |
2785 | } | ||
2786 | 16 | m_isSeqVelExtrapolAllocated = false; | |
2787 | |||
2788 | // delete rhs time | ||
2789 |
2/2✓ Branch 1 taken 16 times.
✓ Branch 2 taken 16 times.
|
32 | for(std::size_t i=0; i<m_seqBdfRHS.size(); ++i) { |
2790 |
1/2✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
16 | m_seqBdfRHS[i].destroy(); |
2791 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
|
16 | m_seqBdfRHS[i] = PetscVector::null(); |
2792 | } | ||
2793 | 16 | m_isSeqBdfRHSAllocated = false; | |
2794 | 16 | } else { | |
2795 | // copy the solutions | ||
2796 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
|
4 | for(std::size_t i=m_sequentialSolutionOld.size() - 1; i>0; --i) |
2797 | 2 | m_sequentialSolutionOld[i].copyFrom(m_sequentialSolutionOld[i-1]); | |
2798 | 2 | m_sequentialSolutionOld[0].copyFrom(sequentialSolution()); | |
2799 | |||
2800 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
|
4 | for(std::size_t i=m_solutionOld.size() - 1; i>0; --i) |
2801 | 2 | m_solutionOld[i].copyFrom(m_solutionOld[i-1]); | |
2802 | 2 | m_solutionOld[0].copyFrom(solution()); | |
2803 | } | ||
2804 | 18 | } | |
2805 | |||
2806 | |||
2807 | /*! | ||
2808 | * Gather the extrapolation of the fluid velocity and pressure for the RN schemes | ||
2809 | * into m_seqStabExplicitFluidExtrapol. | ||
2810 | * If m_seqStabExplicitFluidExtrapol is null, it will be created and allocated during the gathering | ||
2811 | * according to the parallel shape of parFluidExtrapol | ||
2812 | */ | ||
2813 | ✗ | void LinearProblemFSINitscheXFEMFluid::gatherRNFluidExtrapol(std::vector<PetscVector>& parFluidExtrapol) { | |
2814 | ✗ | for(std::size_t i=0; i<parFluidExtrapol.size(); ++i) | |
2815 | ✗ | gatherVector(parFluidExtrapol[i], m_seqRNFluidExtrapol[i]); | |
2816 | |||
2817 | ✗ | m_isSeqRNFluidExtrapolAllocated = true; | |
2818 | } | ||
2819 | |||
2820 | ✗ | void LinearProblemFSINitscheXFEMFluid::gatherRNFluidExtrapol(PetscVector& parFluidExtrapol) { | |
2821 | ✗ | gatherVector(parFluidExtrapol, m_seqRNFluidExtrapol[0]); | |
2822 | ✗ | m_isSeqRNFluidExtrapolAllocated = true; | |
2823 | } | ||
2824 | |||
2825 | ✗ | void LinearProblemFSINitscheXFEMFluid::setRNFluidExtrapol(PetscVector& seqFluidExtrapol) { | |
2826 | ✗ | m_seqRNFluidExtrapol[0].copyFrom(seqFluidExtrapol); | |
2827 | } | ||
2828 | |||
2829 | ✗ | void LinearProblemFSINitscheXFEMFluid::initRNFluidExtrapol(felInt order) { | |
2830 | ✗ | if(m_isSeqRNFluidExtrapolAllocated) { | |
2831 | ✗ | for(std::size_t i=0; i<m_seqRNFluidExtrapol.size(); ++i) | |
2832 | ✗ | m_seqRNFluidExtrapol[i].destroy(); | |
2833 | } | ||
2834 | |||
2835 | ✗ | m_seqRNFluidExtrapol.resize(order); | |
2836 | ✗ | for(std::size_t i=0; i<m_seqRNFluidExtrapol.size(); ++i) | |
2837 | ✗ | m_seqRNFluidExtrapol[i] = PetscVector::null(); | |
2838 | } | ||
2839 | } | ||
2840 |