GCC Code Coverage Report


Directory: ./
File: Model/NSlinCombModel.cpp
Date: 2024-04-14 07:32:34
Exec Total Coverage
Lines: 0 141 0.0%
Branches: 0 200 0.0%

Line Branch Exec Source
1 // ______ ______ _ _ _____ ______
2 // | ____| ____| | (_)/ ____| | ____|
3 // | |__ | |__ | | _| (___ ___| |__
4 // | __| | __| | | | |\___ \ / __| __|
5 // | | | |____| |____| |____) | (__| |____
6 // |_| |______|______|_|_____/ \___|______|
7 // Finite Elements for Life Sciences and Engineering
8 //
9 // License: LGL2.1 License
10 // FELiScE default license: LICENSE in root folder
11 //
12 // Main authors: J Fouchet & C Bui
13 //
14
15 // System includes
16
17 // External includes
18
19 // Project includes
20 #include "Model/NSlinCombModel.hpp"
21 #include "DegreeOfFreedom/boundaryCondition.hpp"
22 #include "Solver/linearProblemNS.hpp"
23
24 namespace felisce {
25 NSlinCombModel::NSlinCombModel():Model() {
26 m_lumpedModelBC = nullptr;
27 m_name = "NSlinComb";
28 m_coefProblem = nullptr;
29 }
30
31 NSlinCombModel::~NSlinCombModel() {
32 if(m_lumpedModelBC) delete m_lumpedModelBC;
33 if(m_coefProblem) delete m_coefProblem;
34 m_stationnarySolutionsVec.clear();
35 m_labelListlinCombBC.clear();
36 m_fluxLinCombBCtotal.clear();
37 m_fluxLinCombBC.clear();
38 m_solExtrapolate.destroy();
39 }
40
41 void NSlinCombModel::initializeDerivedModel() {
42 if( FelisceParam::instance().lumpedModelBCLabel.size() ) {
43 m_lumpedModelBC = new LumpedModelBC(m_fstransient);
44 static_cast<LinearProblemNS*>(m_linearProblem[0])->initializeLumpedModelBC(m_lumpedModelBC);
45 }
46
47 if (FelisceParam::instance().orderBdfNS > 2)
48 FEL_ERROR("BDF not yet implemented for order greater than 2 with Navier-Stokes.");
49
50 if (FelisceParam::instance().NSequationFlag > 0 && FelisceParam::instance().characteristicMethod == 0)
51 FEL_ERROR("You have to use the method of characteristics with this model.");
52
53 m_bdfNS.defineOrder(FelisceParam::instance().orderBdfNS);
54 m_linearProblem[0]->initializeTimeScheme(&m_bdfNS);
55
56 m_coefProblem = new CoefProblem();
57 m_coefProblem->initializeCoefProblem(MpiInfo::petscComm());
58 }
59
60 void NSlinCombModel::preAssemblingMatrixRHS(std::size_t iProblem) {
61 m_U_0.duplicateFrom(m_linearProblem[iProblem]->vector());
62 m_U_0.set(0.0);
63
64 m_solExtrapolate.duplicateFrom(m_linearProblem[iProblem]->vector());
65 m_solExtrapolate.zeroEntries();
66
67 const auto num_dofs = m_linearProblem[iProblem]->numDofPerUnknown(0);
68 felInt idGlobalDof[num_dofs];
69 felReal valueByDofU_0[num_dofs];
70
71 for ( felInt i = 0; i < num_dofs; i++) {
72 idGlobalDof[i] = i;
73 valueByDofU_0[i] = 0.;
74 }
75
76 //Use global mapping for parallel computation (in sequential: (before mapping idGlobalDof) == (after mapping idGlobalDof)).
77 AOApplicationToPetsc(m_linearProblem[iProblem]->ao(),num_dofs,idGlobalDof);
78 // "add" values in Petsc vectors.
79 m_U_0.setValues(num_dofs,idGlobalDof,valueByDofU_0,INSERT_VALUES);
80 //assemble m_U_0.
81 m_U_0.assembly();
82
83 //Initialize solution for solver.
84 m_linearProblem[iProblem]->solution().copyFrom(m_U_0);
85 // First assembly loop in iteration 0 to build static matrix.
86 m_linearProblem[iProblem]->assembleMatrixRHS(MpiInfo::rankProc());
87 }
88
89 void NSlinCombModel::postAssemblingMatrixRHS(std::size_t iProblem) {
90 // _Matrix = _A + _Matrix (add static matrix to the dynamic matrix to build
91 // complete matrix of the system
92 m_linearProblem[iProblem]->addMatrixRHS();
93 }
94
95 void NSlinCombModel::preProcessing() {
96 PetscPrintf(MpiInfo::petscComm(),"\n----------------------------------------------\n");
97 PetscPrintf(MpiInfo::petscComm()," Pre-processing ... ... ...");
98 PetscPrintf(MpiInfo::petscComm(),"\n----------------------------------------------\n");
99
100 m_coefProblem->buildSolver();
101
102 //==========================================================
103 // Compute the inflowOutflowBCnumber time-indepedent functions u_i
104 //==========================================================
105
106 int numInflowOutflowBC = m_linearProblem[0]->getBoundaryConditionList().numNeumannNormalBoundaryCondition();
107
108 // fill m_labelListlinCombBC
109 for (int i = 0; i < numInflowOutflowBC; i++) {
110 // add the corresponding labels
111 std::copy( m_linearProblem[0]->getBoundaryConditionList().NeumannNormal(i)->listLabel().begin(), m_linearProblem[0]->getBoundaryConditionList().NeumannNormal(i)->listLabel().end(), std::back_inserter( m_labelListlinCombBC ) );
112 }
113
114 // change of the bc
115 //==================
116
117 // If we use the implicit algorithm, all the lumpedModel boundary conditions are defined as NeumannNormal ones ( cf defineBC() ) and
118 // all the Dirichlet BC are defined temporarily as homogeneous Dirichlet BC.
119 if (m_linearProblem[0]->getBoundaryConditionList().numDirichletBoundaryCondition()) {
120 BoundaryCondition* BC = m_linearProblem[0]->getBoundaryConditionList().Dirichlet(0);
121 std::vector<double> valueOfBC(BC->getComp().size(), 0.);
122 for (std::size_t iDirichletBC = 0; iDirichletBC < m_linearProblem[0]->getBoundaryConditionList().numDirichletBoundaryCondition(); iDirichletBC++) {
123 BC = m_linearProblem[0]->getBoundaryConditionList().Dirichlet(iDirichletBC);
124 BC->setValue(valueOfBC);
125 }
126 valueOfBC.clear();
127 }
128
129 // "forward" of the preprocessing
130 //================================
131
132 PetscPrintf(MpiInfo::petscComm(),"\n --- --- --- Allocate Matrix RHS for Alpha_i problem --- --- --- \n ");
133
134 m_coefProblem->allocateMatrixRHS(numInflowOutflowBC, MpiInfo::rankProc());
135 m_stationnarySolutionsVec.resize(numInflowOutflowBC);
136
137 postAssemblingMatrixRHS();
138
139 for (int idInflowOutflowBC = 0; idInflowOutflowBC < numInflowOutflowBC; idInflowOutflowBC++) {
140
141 m_linearProblem[0]->vector().zeroEntries();
142
143 PetscPrintf(MpiInfo::petscComm(),"\n-----------------------------\n");
144 PetscPrintf(MpiInfo::petscComm()," u_i with i=%d ... ... ...",idInflowOutflowBC);
145 PetscPrintf(MpiInfo::petscComm(),"\n-----------------------------\n");
146
147 PetscPrintf(MpiInfo::petscComm(),"\n --- --- --- Solve Stokes problem --- --- --- \n ");
148
149 PetscPrintf(MpiInfo::petscComm(),"\n ApplyBC ... \n ");
150
151 // The NeumannNormal boundary conditions are updated in allocateElemFieldBoundaryConditionDerivedLinPb()
152 m_linearProblem[0]->applyBC(FelisceParam::instance().essentialBoundaryConditionsMethod, MpiInfo::rankProc(), FlagMatrixRHS::matrix_and_rhs, FlagMatrixRHS::matrix_and_rhs, idInflowOutflowBC);
153
154 PetscPrintf(MpiInfo::petscComm(),"\n Solve ... \n ");
155
156 // Solve linear system.
157 m_linearProblem[0]->solve(MpiInfo::rankProc(), MpiInfo::numProc());
158
159 PetscPrintf(MpiInfo::petscComm(),"\n --- --- --- Compute flux --- --- --- \n ");
160
161 // Computing flux : \int_{\gamma_i} u_j \cdot normale
162 m_linearProblem[0]->computeMeanQuantity(velocity,m_labelListlinCombBC,m_fluxLinCombBC );
163
164 PetscPrintf(MpiInfo::petscComm(),"\n labels :");
165 for (unsigned int i = 0; i < m_labelListlinCombBC.size(); i++)
166 PetscPrintf(MpiInfo::petscComm()," %d",m_labelListlinCombBC[i]);
167
168 PetscPrintf(MpiInfo::petscComm(),"\n compute Flux :");
169 for (unsigned int i = 0; i < m_fluxLinCombBC.size(); i++)
170 PetscPrintf(MpiInfo::petscComm()," %f",m_fluxLinCombBC[i]);
171 PetscPrintf(MpiInfo::petscComm(),"\n");
172
173 // Stock the solution u_i
174 //=============================
175
176 m_stationnarySolutionsVec[idInflowOutflowBC].duplicateFrom(m_linearProblem[0]->solution());
177 m_stationnarySolutionsVec[idInflowOutflowBC].copyFrom(m_linearProblem[0]->solution());
178
179 //=============================================
180 // Assembling of A (to determine the \alpha_i)
181 //=============================================
182
183 PetscPrintf(MpiInfo::petscComm(),"\n --- --- --- Assemble Matrix for Alpha_i problem --- --- --- \n ");
184
185 m_coefProblem->assembleMatrix(idInflowOutflowBC, m_fluxLinCombBC, MpiInfo::rankProc());
186 //m_coefProblem->writeMatrixForMatlab(30);
187 }
188
189 m_linearProblem[0]->solution().zeroEntries();
190 m_linearProblem[0]->sequentialSolution().zeroEntries();
191
192 // initialize m_fluxLinCombBCtotal to 0
193 m_fluxLinCombBCtotal.resize(m_fluxLinCombBC.size(), 0.);
194
195 // std::set the right values for all the Dirichlet boundary conditions except for the transient ones
196 m_linearProblem[0]->finalizeEssBCConstantInT();
197 }
198
199 void NSlinCombModel::forward() {
200 // Write solution for postprocessing (if required)
201 // Update m_seqSol (!). Write it.
202 writeSolution();
203
204 // Advance time step.
205 updateTime();
206
207 // Print time information
208 printNewTimeIterationBanner();
209
210 if ( m_fstransient->iteration == 1) {
211 m_bdfNS.initialize(m_U_0);
212 m_bdfNS.extrapolate(m_solExtrapolate);
213 m_linearProblem[0]->initExtrapol(m_solExtrapolate);
214 } else {
215 m_bdfNS.update(m_linearProblem[0]->solution());
216 m_bdfNS.extrapolate(m_solExtrapolate);
217 m_linearProblem[0]->updateExtrapol(m_solExtrapolate);
218 }
219
220 m_bdfNS.computeRHSTime(m_fstransient->timeStep);
221
222 //=====================
223 // Compute \tilde{u}^n
224 //=====================
225
226 // m_seqSol = u^n-1 thanks to writeSolution()
227
228 // Fill the m_seqBdfRHS
229 m_linearProblem[0]->gatherVectorBeforeAssembleMatrixRHS();
230
231 // Assembly loop on elements.
232 m_linearProblem[0]->assembleMatrixRHS(MpiInfo::rankProc());
233
234 // Specific operations before solve the system.
235 postAssemblingMatrixRHS();
236
237 // Apply essential transient boundary conditions.
238 m_linearProblem[0]->finalizeEssBCTransient();
239
240 m_linearProblem[0]->applyBC(FelisceParam::instance().essentialBoundaryConditionsMethod, MpiInfo::rankProc());
241
242 // Solve linear system.
243 m_linearProblem[0]->solve(MpiInfo::rankProc(), MpiInfo::numProc());
244
245 //========================================
246 // Assembling of RHS for \alpha_i problem
247 //========================================
248
249 PetscPrintf(MpiInfo::petscComm(),"\n --- --- --- Compute flux --- --- --- \n ");
250
251 // Computing flux : \int_{\gamma_i} \tilde{u}^n \cdot normale
252 m_linearProblem[0]->computeMeanQuantity(velocity, m_labelListlinCombBC, m_fluxLinCombBC);
253
254 PetscPrintf(MpiInfo::petscComm(),"\n labels :");
255 for (unsigned int i = 0; i < m_labelListlinCombBC.size(); i++)
256 PetscPrintf(MpiInfo::petscComm()," %d",m_labelListlinCombBC[i]);
257
258 PetscPrintf(MpiInfo::petscComm(),"\n compute Flux :");
259 for (unsigned int i = 0; i < m_fluxLinCombBC.size(); i++)
260 PetscPrintf(MpiInfo::petscComm()," %f",m_fluxLinCombBC[i]);
261 PetscPrintf(MpiInfo::petscComm(),"\n");
262
263 PetscPrintf(MpiInfo::petscComm(),"\n --- --- --- Assemble RHS for Alpha_i problem --- --- --- \n ");
264
265 unsigned int numNeumannNormalBCwithoutWindkessel = m_fluxLinCombBC.size() - FelisceParam::instance().lumpedModelBCLabel.size();
266 std::vector<double> pressure;
267 if (numNeumannNormalBCwithoutWindkessel) {
268 BoundaryCondition* BC;
269 int idBC;
270 for(unsigned int iNeumannNormalBC = 0; iNeumannNormalBC < numNeumannNormalBCwithoutWindkessel; iNeumannNormalBC++) {
271 BC = m_linearProblem[0]->getBoundaryConditionList().NeumannNormal(iNeumannNormalBC);
272 idBC = m_linearProblem[0]->getBoundaryConditionList().idBCOfNeumannNormal(iNeumannNormalBC);
273 switch ( BC->typeValueBC() ) {
274 case Constant:
275 pressure.push_back(FelisceParam::instance().value[m_linearProblem[0]->getBoundaryConditionList().startIndiceOfValue(idBC)]);
276 break;
277 case FunctionT:
278 // warning: one has to define in his userNS file the following virtual function
279 // double userComputeValueNeumannNormalTransient(const int iNeumannNormalBC)
280 pressure.push_back(m_linearProblem[0]->userComputeValueNeumannNormalTransient(iNeumannNormalBC));
281 break;
282 case FunctionS:
283 case FunctionTS:
284 case Vector:
285 case EnsightFile:
286 FEL_ERROR("Impossible to compute the value with this type of Boundary Condition.");
287 break;
288 }
289 }
290 }
291
292 // here m_fluxLinCombBCtotal = \sum_{j=1}^{n-1} ( \int_{\gamma_i} u^j \cdot normale )
293 m_coefProblem->assembleRHS(pressure, m_fluxLinCombBC, m_fluxLinCombBCtotal, MpiInfo::rankProc());
294 pressure.clear();
295 //m_coefProblem->writeRHSForMatlab(30);
296
297 //==================================================
298 // Solve (I-A)alpha = b (to determine the \alpha_i)
299 //==================================================
300
301 PetscPrintf(MpiInfo::petscComm(),"\n --- --- --- Solve Alpha_i --- --- --- \n ");
302
303 m_coefProblem->solve(MpiInfo::rankProc(), MpiInfo::numProc());
304
305 //==========================
306 // Compute the solution u^n
307 //==========================
308
309 PetscPrintf(MpiInfo::petscComm(),"\n --- --- --- Revise the solution --- --- --- \n ");
310
311 // m_sol = u^n = \tilde{u}^n + \sum_i alpha_i^n u_i
312 static_cast<LinearProblemNS*>(m_linearProblem[0])->reviseSolution(m_coefProblem->solution(), m_stationnarySolutionsVec);
313
314 // Computing flux : \int_{\gamma_i} u^n \cdot normale
315 m_linearProblem[0]->computeMeanQuantity(velocity,m_labelListlinCombBC,m_fluxLinCombBC);
316 // update m_fluxLinCombBCtotal = \sum_{j=1}^n ( \int_{\gamma_i} u^j \cdot normale )
317 for (unsigned int i = 0; i < m_fluxLinCombBC.size(); i++)
318 m_fluxLinCombBCtotal[i] += m_fluxLinCombBC[i];
319 }
320
321 }
322