GCC Code Coverage Report


Directory: ./
File: Model/model.cpp
Date: 2024-04-14 07:32:34
Exec Total Coverage
Lines: 277 427 64.9%
Branches: 274 720 38.1%

Line Branch Exec Source
1 // ______ ______ _ _ _____ ______
2 // | ____| ____| | (_)/ ____| | ____|
3 // | |__ | |__ | | _| (___ ___| |__
4 // | __| | __| | | | |\___ \ / __| __|
5 // | | | |____| |____| |____) | (__| |____
6 // |_| |______|______|_|_____/ \___|______|
7 // Finite Elements for Life Sciences and Engineering
8 //
9 // License: LGL2.1 License
10 // FELiScE default license: LICENSE in root folder
11 //
12 // Main authors: J. Foulon & M. Fragu
13 //
14
15 // System includes
16 #include <ctime>
17
18 // External includes
19
20 // Project includes
21 #include "Core/mpiInfo.hpp"
22 #include "Model/model.hpp"
23 #include "Solver/CVGraphInterface.hpp"
24 #include "Solver/linearProblemHarmonicExtension.hpp"
25 #include "Tools/fe_utilities.hpp"
26
27 namespace felisce
28 {
29
30
4/8
✓ Branch 2 taken 467 times.
✗ Branch 3 not taken.
✓ Branch 13 taken 467 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 467 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 467 times.
✗ Branch 21 not taken.
467 Model::Model()
31 {
32 467 }
33
34 /***********************************************************************************/
35 /***********************************************************************************/
36
37 934 Model::~Model() {
38
39
2/2
✓ Branch 0 taken 461 times.
✓ Branch 1 taken 6 times.
934 if (m_linearProblemIsInitialized) {
40
2/2
✓ Branch 2 taken 459 times.
✓ Branch 3 taken 2 times.
922 if(FelisceParam::instance(this->instanceIndex()).duplicateSupportDof == false)
41 918 writeSolution();
42 }
43
44 // Prints chrono table
45 934 auto& r_instance = FelisceParam::instance(this->instanceIndex());
46
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 467 times.
934 if (r_instance.chronoToScreen) {
47 r_instance.timer.ToScreen();
48 }
49
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 467 times.
934 if (r_instance.chronoToFile) {
50 r_instance.timer.resultDir() = r_instance.resultDir;
51 r_instance.timer.ToFile();
52 }
53
54
2/2
✓ Branch 1 taken 513 times.
✓ Branch 2 taken 467 times.
1960 for(std::size_t i=0; i<m_linearProblem.size(); i++) {
55
2/4
✓ Branch 1 taken 513 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 513 times.
✗ Branch 5 not taken.
1026 if(m_linearProblem[i]) delete m_linearProblem[i];
56 }
57
58 #ifdef FELISCE_WITH_CVGRAPH
59 // necessary to destroy manually all petsc objects before the petsc finalize
60
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 467 times.
934 if ( ! m_rhsWithForceTermWithoutBC.isNull() ) {
61 m_rhsWithForceTermWithoutBC.destroy();
62 }
63 #endif
64
2/2
✓ Branch 0 taken 461 times.
✓ Branch 1 taken 6 times.
934 if (m_linearProblemIsInitialized) {
65 922 m_U_0.destroy();
66
67 922 PetscPrintf(MpiInfo::petscComm(), "\n==============================================================\n");
68 922 PetscPrintf(MpiInfo::petscComm(), "FELiScE %s : normal end\n",m_name.c_str());
69 // current date and time system
70 922 time_t now = time(nullptr);
71 922 char* date_time = ctime(&now);
72 922 PetscPrintf(MpiInfo::petscComm(), "%s",date_time);
73 922 PetscPrintf(MpiInfo::petscComm(), "==============================================================\n");
74
75
2/2
✓ Branch 0 taken 453 times.
✓ Branch 1 taken 8 times.
922 if (m_callPetscInitialize)
76 906 PetscFinalize();
77 }
78
79
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 466 times.
934 if (m_eigenProblemIsInitialized) {
80
81 2 PetscPrintf(MpiInfo::petscComm(), "\n==============================================================\n");
82 2 PetscPrintf(MpiInfo::petscComm(), "FELiScE %s : normal end\n",m_name.c_str());
83 // current date and time system
84 2 time_t now = time(nullptr);
85 2 char* date_time = ctime(&now);
86 2 PetscPrintf(MpiInfo::petscComm(), "%s",date_time);
87 2 PetscPrintf(MpiInfo::petscComm(), "==============================================================\n");
88
89 #ifdef FELISCE_WITH_SLEPC
90
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 if (m_callPetscInitialize)
91 2 SlepcFinalize();
92 #endif
93 }
94
95 934 m_ios.clear();
96 }
97
98 /***********************************************************************************/
99 /***********************************************************************************/
100
101 namespace { // anonymous
102 // Print which architecture is used
103 250 void printArchitecture(const MPI_Comm& comm) {
104
1/2
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
250 std::ostringstream oconv;
105
1/2
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
250 oconv << "FELiScE ";
106
1/2
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
250 oconv << 8 * sizeof(void*);
107
1/2
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
250 oconv << " bits ";
108
2/4
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 250 times.
✗ Branch 6 not taken.
250 PetscPrintf(comm,"%s",oconv.str().c_str());
109 250 }
110 } // namespace anonymous
111
112 /***********************************************************************************/
113 /***********************************************************************************/
114
115 462 void Model::initializeModel(CommandLineOption& opt, FelisceTransient& fstransient, const MPI_Comm comm, const bool callPetscInitialize)
116 {
117 // Update instance index
118 462 m_instanceIndex = opt.instanceIndex();
119
1/2
✓ Branch 2 taken 462 times.
✗ Branch 3 not taken.
462 auto& r_instance = FelisceParam::instance(this->instanceIndex());
120
121 // Get timer
122 462 auto& r_timer = r_instance.timer;
123
2/4
✓ Branch 2 taken 462 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 462 times.
✗ Branch 6 not taken.
462 r_timer.Start("Model::initializeModel");
124
125
1/2
✓ Branch 1 taken 462 times.
✗ Branch 2 not taken.
462 m_fstransient = felisce::make_shared<FelisceTransient>(fstransient);
126 462 m_callPetscInitialize = callPetscInitialize;
127
1/2
✓ Branch 2 taken 462 times.
✗ Branch 3 not taken.
462 const std::string help = "Felisce\n\n";
128
129 //Initialize Petsc (MPI)
130 //======================
131
1/2
✓ Branch 0 taken 462 times.
✗ Branch 1 not taken.
462 if (comm == MPI_COMM_WORLD) { // default communicator
132 #ifdef FELISCE_WITH_SLEPC
133
1/2
✓ Branch 4 taken 462 times.
✗ Branch 5 not taken.
462 SlepcInitialize(&opt.argcPetsc(), &opt.argvPetsc(), FELISCE_PETSC_NULLPTR, help.c_str());
134 #else
135 PetscInitialize(&opt.argcPetsc(), &opt.argvPetsc(), FELISCE_PETSC_NULLPTR, help.c_str());
136 #endif
137
1/2
✓ Branch 1 taken 462 times.
✗ Branch 2 not taken.
462 MpiInfo::petscComm()=MPI_COMM_WORLD;
138 } else { // user defined communicator (for use with CVGraph for instance...) This is a delicate part, think about before touching it!Saverio
139 // From petsc documentation:
140 // If you wish PETSc code to run ONLY on a subcommunicator of MPI_COMM_WORLD, create that communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize().
141 // Thus if you are running a four process job and two processes will run PETSc and have PetscInitialize() and PetscFinalize() and two process will not, then do this.
142 // If ALL processes in the job are using PetscInitialize() and PetscFinalize() then you don't need to do this, even if different subcommunicators of the job are doing different things with PETSc.
143 PETSC_COMM_WORLD = comm;
144 if (callPetscInitialize) {
145 #ifdef FELISCE_WITH_SLEPC
146 SlepcInitialize(&opt.argcPetsc(),&opt.argvPetsc(), FELISCE_PETSC_NULLPTR, help.c_str());
147 #else
148 PetscInitialize(&opt.argcPetsc(),&opt.argvPetsc(), FELISCE_PETSC_NULLPTR, help.c_str());
149 #endif
150 }
151 MpiInfo::petscComm() = PETSC_COMM_WORLD;
152 }
153
154 int rankProc,numProc;
155
2/4
✓ Branch 1 taken 462 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 462 times.
✗ Branch 5 not taken.
462 MPI_Comm_rank(MpiInfo::petscComm(),&rankProc);
156
2/4
✓ Branch 1 taken 462 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 462 times.
✗ Branch 5 not taken.
462 MPI_Comm_size(MpiInfo::petscComm(),&numProc);
157
1/2
✓ Branch 1 taken 462 times.
✗ Branch 2 not taken.
462 MpiInfo::rankProc()=rankProc;
158
1/2
✓ Branch 1 taken 462 times.
✗ Branch 2 not taken.
462 MpiInfo::numProc()=numProc;
159
160 // Printing logo
161
3/4
✓ Branch 1 taken 462 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 128 times.
✓ Branch 4 taken 334 times.
462 if (MpiInfo::rankProc() == 0) {
162 std::cout << " ______ ______ _ _ _____ ______ \n"
163 << " | ____| ____| | (_)/ ____| | ____| \n"
164 << " | |__ | |__ | | _| (___ ___| |__ \n"
165 << " | __| | __| | | | |\\___ \\ / __| __| \n"
166 << " | | | |____| |____| |____) | (__| |____ \n"
167 << " |_| |______|______|_|_____/ \\___|______| \n"
168
8/16
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 128 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 128 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 128 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 128 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 128 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 128 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 128 times.
✗ Branch 23 not taken.
128 << " Finite Elements for Life Sciences and Engineering\n" << std::endl;
169 }
170
171 // current date and time system
172 462 time_t now = std::time(nullptr);
173 462 char* date_time = ctime(&now);
174
3/4
✓ Branch 1 taken 462 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 250 times.
✓ Branch 4 taken 212 times.
462 if (FelisceParam::verbose()) {
175
2/4
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 250 times.
✗ Branch 5 not taken.
250 PetscPrintf(MpiInfo::petscComm(), "\n================================================================\n");
176
177
1/2
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
250 printArchitecture(comm);
178
179
5/8
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 240 times.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 10 times.
✗ Branch 10 not taken.
250 if(MpiInfo::numProc()==1) PetscPrintf(MpiInfo::petscComm(), "on 1 processor \n");
180
3/6
✓ Branch 1 taken 240 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 240 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 240 times.
✗ Branch 8 not taken.
240 else PetscPrintf(MpiInfo::petscComm(), "on %d processors \n", MpiInfo::numProc());
181
2/4
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 250 times.
✗ Branch 5 not taken.
250 PetscPrintf(MpiInfo::petscComm(), "%s", date_time);
182
2/4
✓ Branch 1 taken 250 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 250 times.
✗ Branch 5 not taken.
250 PetscPrintf(MpiInfo::petscComm(), "=================================================================\n");
183 }
184
2/4
✓ Branch 1 taken 462 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 462 times.
✗ Branch 5 not taken.
462 r_instance.print(FelisceParam::verbose());
185
186 //Read the mesh file
187 //==================
188
1/2
✓ Branch 1 taken 462 times.
✗ Branch 2 not taken.
462 readMesh();
189
190 462 m_modelIsInitialized = true;
191
192
2/2
✓ Branch 1 taken 468 times.
✓ Branch 2 taken 462 times.
930 for(std::size_t iio=0; iio<m_ios.size(); ++iio) {
193
1/2
✓ Branch 3 taken 468 times.
✗ Branch 4 not taken.
468 m_ios[iio]->readInputFile();
194 }
195
196 //Error message if method of characteristics is used in parallel, to be removed when this method is implemented in parallel
197
3/4
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 446 times.
462 if (r_instance.NSequationFlag == 1 && r_instance.characteristicMethod != 0) {
198 if (MpiInfo::numProc() > 1)
199 FEL_ERROR("Method of characteristics has not been implemented yet in parallel!");
200 }
201
202 //Verify if this model use CVGraphInterface
203 //==================================
204
1/2
✓ Branch 1 taken 462 times.
✗ Branch 2 not taken.
462 if ( !strcmp(r_instance.CVGraphInterface.c_str(),"default")) {
205 462 m_initializeCVGraphInterface = false;
206 } else {
207 m_initializeCVGraphInterface = true;
208 }
209
210
2/4
✓ Branch 2 taken 462 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 462 times.
✗ Branch 6 not taken.
462 r_timer.Stop("Model::initializeModel");
211 462 }
212
213 /***********************************************************************************/
214 /***********************************************************************************/
215
216 456 void Model::initializeLinearProblem(const std::vector<LinearProblem*>& linearPb, bool doUseSNES)
217 {
218
1/2
✓ Branch 3 taken 456 times.
✗ Branch 4 not taken.
456 std::vector<bool> aDoUseSNES(linearPb.size(), doUseSNES);
219
1/2
✓ Branch 1 taken 456 times.
✗ Branch 2 not taken.
456 initializeLinearProblem(linearPb,aDoUseSNES);
220 456 }
221
222 /***********************************************************************************/
223 /***********************************************************************************/
224
225 461 void Model::initializeLinearProblem(const std::vector<LinearProblem*>& linearPb, const std::vector<bool>& doUseSNES)
226 {
227 461 auto& r_instance = FelisceParam::instance(this->instanceIndex());
228
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 461 times.
461 FEL_CHECK( doUseSNES.size() == linearPb.size(),"Number of linear problems and doUseSNES differ");
229
230 // Check connections between variables and meshes
231 461 checkConnectionVariablesMeshs();
232
233 // Get timer
234 461 auto& r_timer = r_instance.timer;
235
236 // Initilize solution backup
237
2/4
✓ Branch 2 taken 461 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 461 times.
✗ Branch 6 not taken.
461 r_timer.Start("Model::Initialize solution backup");
238 461 m_solutionBackup.resize(linearPb.size());
239
2/2
✓ Branch 1 taken 513 times.
✓ Branch 2 taken 461 times.
974 for(std::size_t i=0; i<m_solutionBackup.size(); ++i) {
240 513 m_solutionBackup[i].initialize(r_instance.inputDirectory, r_instance.inputFile, r_instance.inputMesh,
241 513 r_instance.outputMesh, r_instance.meshDir, r_instance.resultDir, r_instance.prefixName);
242 }
243
2/4
✓ Branch 2 taken 461 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 461 times.
✗ Branch 6 not taken.
461 r_timer.Stop("Model::Initialize solution backup");
244
245 // Copy all linear system in m_linearProblem
246
2/2
✓ Branch 1 taken 513 times.
✓ Branch 2 taken 461 times.
974 for (std::size_t ipb = 0; ipb < linearPb.size(); ipb++) {
247 513 m_linearProblem.push_back(linearPb[ipb]);
248 513 linearPb[ipb]->identifierProblem() = ipb;
249 }
250
251 // Definition of specific linear problems in each model
252
2/4
✓ Branch 2 taken 461 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 461 times.
✗ Branch 6 not taken.
461 r_timer.Start("Model::initializeDerivedLinearProblem");
253 461 initializeDerivedLinearProblem();
254
2/4
✓ Branch 2 taken 461 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 461 times.
✗ Branch 6 not taken.
461 r_timer.Stop("Model::initializeDerivedLinearProblem");
255
256 // For each linear system,
257
2/2
✓ Branch 1 taken 513 times.
✓ Branch 2 taken 461 times.
974 for (std::size_t ipb = 0; ipb < linearPb.size(); ipb++) {
258 // Set the model
259 513 m_linearProblem[ipb]->model() = this;
260
261 // Initialize it
262
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Start("LinearProblem" + std::to_string(ipb) + "::initialize");
263
1/2
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
513 m_linearProblem[ipb]->initialize(m_mesh, m_fstransient, MpiInfo::petscComm(), doUseSNES[ipb]);
264
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Stop("LinearProblem" + std::to_string(ipb) + "::initialize");
265
266
2/2
✓ Branch 2 taken 76 times.
✓ Branch 3 taken 437 times.
513 if (r_instance.solver.size() < linearPb.size()) {
267 76 m_linearProblem[ipb]->fixIdOfTheProblemSolver(0);
268 } else {
269 437 m_linearProblem[ipb]->fixIdOfTheProblemSolver(ipb);
270 }
271
272 // And compute the dof.
273
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Start("LinearProblem" + std::to_string(ipb) + "::computeDof");
274 513 m_linearProblem[ipb]->computeDof(MpiInfo::numProc(), MpiInfo::rankProc());
275
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Stop("LinearProblem" + std::to_string(ipb) + "::computeDof");
276 }
277
278 // Define initial conditions
279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 461 times.
461 if (r_instance.hasInitialCondition) {
280 for (std::size_t ipb = 0; ipb < linearPb.size(); ipb++) {
281 for (std::size_t ii = 0; ii < r_instance.valueInitCond.size(); ii++) {
282 m_initialCondition.addVariable(*m_linearProblem[ipb]->listVariable().getVariable(r_instance.nameVariableInitCond[ii]));
283 }
284 m_initialCondition.print(FelisceParam::verbose(),std::cout);
285 }
286 }
287
288 // For each linear system
289
2/2
✓ Branch 1 taken 513 times.
✓ Branch 2 taken 461 times.
974 for (std::size_t ipb = 0; ipb < linearPb.size(); ipb++) {
290 // userChangePattern: user function to change the pattern if needed in the specific application.
291
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Start("LinearProblem" + std::to_string(ipb) + "::userChangePattern");
292 513 m_linearProblem[ipb]->userChangePattern(MpiInfo::numProc(), MpiInfo::rankProc());
293
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Stop("LinearProblem" + std::to_string(ipb) + "::userChangePattern");
294
295 // cutMesh: partitioning of the dof and elements.
296
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Start("LinearProblem" + std::to_string(ipb) + "::cutMesh");
297 513 m_linearProblem[ipb]->cutMesh();
298
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Stop("LinearProblem" + std::to_string(ipb) + "::cutMesh");
299
300 // allocateMatrix: Allocate memory for the matrix _Matrix and std::vector _RHS in the linearProblem class
301
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Start("LinearProblem" + std::to_string(ipb) + "::allocateMatrix");
302 513 m_linearProblem[ipb]->allocateMatrix();
303
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Stop("LinearProblem" + std::to_string(ipb) + "::allocateMatrix");
304 }
305
306 // Specific initialization of the user model (useful after allocate Matrix of linear problem)
307
2/4
✓ Branch 2 taken 461 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 461 times.
✗ Branch 6 not taken.
461 r_timer.Start("Model::initializeDerivedModel");
308 461 initializeDerivedModel();
309
2/4
✓ Branch 2 taken 461 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 461 times.
✗ Branch 6 not taken.
461 r_timer.Stop("Model::initializeDerivedModel");
310
311
2/4
✓ Branch 2 taken 461 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 461 times.
✗ Branch 6 not taken.
461 r_timer.Start("Model::setExternalVec");
312 // Make the connection between the different linear pb (to be defined in the derived class)
313 461 setExternalVec();
314
2/4
✓ Branch 2 taken 461 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 461 times.
✗ Branch 6 not taken.
461 r_timer.Stop("Model::setExternalVec");
315
316
2/2
✓ Branch 1 taken 513 times.
✓ Branch 2 taken 461 times.
974 for (std::size_t ipb = 0; ipb < linearPb.size(); ipb++) {
317 //Define boundary condition of the problem
318
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Start("LinearProblem" + std::to_string(ipb) + "::defineBC");
319 513 m_linearProblem[ipb]->defineBC();
320
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Stop("LinearProblem" + std::to_string(ipb) + "::defineBC");
321
322 //Compute boundary condition
323
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Start("LinearProblem" + std::to_string(ipb) + "::Compute boundary condition");
324 513 m_linearProblem[ipb]->determineDofAssociateToLabel();
325 513 m_linearProblem[ipb]->finalizeEssBCConstantInT();
326 513 m_linearProblem[ipb]->finalizeEssBCTransient();
327
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Stop("LinearProblem" + std::to_string(ipb) + "::Compute boundary condition");
328
329 //Apply specific operations before assembling
330
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Start("LinearProblem" + std::to_string(ipb) + "::preAssemblingMatrixRHS");
331 513 preAssemblingMatrixRHS(ipb);
332
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Stop("LinearProblem" + std::to_string(ipb) + "::preAssemblingMatrixRHS");
333
334 // Gather to write initial solution.
335 513 m_linearProblem[ipb]->gatherSolution();
336
337
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Start("LinearProblem" + std::to_string(ipb) + "::buildSolver");
338 513 m_linearProblem[ipb]->buildSolver();
339
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Stop("LinearProblem" + std::to_string(ipb) + "::buildSolver");
340 }
341
342 // Initialize object which manage output.
343
2/2
✓ Branch 1 taken 467 times.
✓ Branch 2 taken 461 times.
928 for(std::size_t iio=0; iio<m_ios.size(); ++iio) {
344 467 m_ios[iio]->initializeOutput();
345 }
346
347
2/2
✓ Branch 1 taken 513 times.
✓ Branch 2 taken 461 times.
974 for(std::size_t ipb = 0; ipb < m_linearProblem.size(); ipb++) {
348
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Start("LinearProblem" + std::to_string(ipb) + "::clearMatrixRHS");
349 513 m_linearProblem[ipb]->clearMatrixRHS();
350
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Stop("LinearProblem" + std::to_string(ipb) + "::clearMatrixRHS");
351
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Start("LinearProblem" + std::to_string(ipb) + "::InitializeDerivedAttributes");
352 513 m_linearProblem[ipb]->InitializeDerivedAttributes();
353
3/6
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 513 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 513 times.
✗ Branch 9 not taken.
513 r_timer.Stop("LinearProblem" + std::to_string(ipb) + "::InitializeDerivedAttributes");
354 }
355
2/4
✓ Branch 2 taken 461 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 461 times.
✗ Branch 6 not taken.
461 r_timer.Start("Model::setInitialCondition");
356 461 setInitialCondition();
357
2/4
✓ Branch 2 taken 461 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 461 times.
✗ Branch 6 not taken.
461 r_timer.Stop("Model::setInitialCondition");
358
359 461 m_fstransient->iteration=0;
360
361 461 m_linearProblemIsInitialized = true;
362 461 }
363
364
365 /***********************************************************************************/
366 /***********************************************************************************/
367
368 461 void Model::checkConnectionVariablesMeshs()
369 {
370 461 auto& r_instance = FelisceParam::instance(this->instanceIndex());
371
372
2/2
✓ Branch 1 taken 455 times.
✓ Branch 2 taken 6 times.
461 if( m_mesh.size() == 1 ) {
373 // If only one mesh provided -> every variables is defined on that mesh
374
1/2
✓ Branch 2 taken 455 times.
✗ Branch 3 not taken.
455 r_instance.idMesh.resize(r_instance.physicalVariable.size(), 0);
375 }
376 else {
377
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 FEL_CHECK(r_instance.idMesh.size() == r_instance.physicalVariable.size(), "Error idmesh->size() != physicalVariable.size()");
378
2/2
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 6 times.
25 for(std::size_t i=0; i<r_instance.idMesh.size(); ++i){
379
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 19 times.
19 FEL_CHECK(static_cast<std::size_t>(r_instance.idMesh[i]) < m_mesh.size(),"Error in idMesh mesh ID greater than m_mesh.size()");
380 }
381 }
382 461 }
383
384 /***********************************************************************************/
385 /***********************************************************************************/
386
387 393 void Model::initializeLinearProblem(LinearProblem* linearPb, bool doUseSNES)
388 {
389
1/2
✓ Branch 2 taken 393 times.
✗ Branch 3 not taken.
393 std::vector<LinearProblem*> linPb(1, linearPb);
390
1/2
✓ Branch 1 taken 393 times.
✗ Branch 2 not taken.
393 initializeLinearProblem(linPb, doUseSNES);
391 393 }
392
393 /***********************************************************************************/
394 /***********************************************************************************/
395
396 53 void Model::finalizeLinearProblem(const std::vector<LinearProblem*>& linearPb)
397 {
398 // For each linear system,
399
2/2
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 53 times.
106 for (std::size_t ipb = 0; ipb < linearPb.size(); ipb++) {
400
1/2
✓ Branch 4 taken 53 times.
✗ Branch 5 not taken.
53 m_linearProblem[ipb]->finalize(m_mesh, m_fstransient, MpiInfo::petscComm());
401 }
402 53 }
403
404 /***********************************************************************************/
405 /***********************************************************************************/
406
407 53 void Model::finalizeLinearProblem(LinearProblem* linearPb)
408 {
409
1/2
✓ Branch 2 taken 53 times.
✗ Branch 3 not taken.
53 std::vector<LinearProblem*> linPb(1, linearPb);
410
1/2
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
53 finalizeLinearProblem(linPb);
411 53 }
412
413 /***********************************************************************************/
414 /***********************************************************************************/
415
416 11420 void Model::updateTime(const FlagMatrixRHS flagMatrixRHS)
417 {
418
2/2
✓ Branch 1 taken 12232 times.
✓ Branch 2 taken 11420 times.
23652 for(std::size_t i=0; i<m_linearProblem.size(); i++) {
419 12232 m_linearProblem[i]->clearMatrixRHS(flagMatrixRHS);
420 }
421 11420 m_fstransient->iteration++;
422 11420 m_fstransient->time +=m_fstransient->timeStep;
423 11420 }
424
425 /***********************************************************************************/
426 /***********************************************************************************/
427
428 24 void Model::SolveStaticProblem()
429 {
430 24 PetscPrintf(MpiInfo::petscComm(), "----------------------------------------------\n");
431 24 PetscPrintf(MpiInfo::petscComm(), "--------------- Static problem ---------------\n");
432 24 PetscPrintf(MpiInfo::petscComm(), "----------------------------------------------\n");
433
434 // Retrieve linear problem
435 24 auto p_linear_problem = m_linearProblem[0];
436
437 // Solve the system.
438 24 p_linear_problem->iterativeSolve(MpiInfo::rankProc(), MpiInfo::numProc());
439 24 }
440
441 /***********************************************************************************/
442 /***********************************************************************************/
443
444 344 void Model::SolveDynamicProblem()
445 {
446 344 PetscPrintf(MpiInfo::petscComm(), "----------------------------------------------\n");
447 344 PetscPrintf(MpiInfo::petscComm(), "--------------- Dynamic problem --------------\n");
448 344 PetscPrintf(MpiInfo::petscComm(), "----------------------------------------------\n");
449
450
2/2
✓ Branch 1 taken 10880 times.
✓ Branch 2 taken 344 times.
11224 while (!hasFinished()) {
451 10880 forward();
452 }
453 344 }
454
455 /***********************************************************************************/
456 /***********************************************************************************/
457
458 11721 bool Model::hasFinished()
459 {
460 11721 const auto& r_instance = FelisceParam::instance(this->instanceIndex());
461
4/4
✓ Branch 1 taken 11673 times.
✓ Branch 2 taken 48 times.
✓ Branch 4 taken 322 times.
✓ Branch 5 taken 11351 times.
11721 m_hasFinished = ( m_fstransient->time > r_instance.timeMax || m_fstransient->iteration >= r_instance.timeIterationMax );
462
463 11721 return m_hasFinished;
464 }
465
466 /***********************************************************************************/
467 /***********************************************************************************/
468
469 double Model::getTime() const
470 {
471 return m_fstransient->time;
472 }
473
474 /***********************************************************************************/
475 /***********************************************************************************/
476
477 11544 void Model::printNewTimeIterationBanner()
478 {
479 11544 PetscPrintf(MpiInfo::petscComm(),"\n----------------------------------------------\n");
480 11544 PetscPrintf(MpiInfo::petscComm(),"%s Iteration: %d, Time: %e \n", m_name.c_str(), m_fstransient->iteration, m_fstransient->time);
481 11544 PetscPrintf(MpiInfo::petscComm(),"----------------------------------------------\n");
482 11544 }
483
484 /***********************************************************************************/
485 /***********************************************************************************/
486
487 void Model::setTime(const double time)
488 {
489 m_fstransient->time = time;
490 }
491
492 /***********************************************************************************/
493 /***********************************************************************************/
494
495 462 void Model::readMesh()
496 {
497 462 auto& r_instance = FelisceParam::instance(this->instanceIndex());
498 462 const std::size_t nbMesh = r_instance.inputMesh.size();
499 462 m_mesh.resize(nbMesh);
500 462 m_ios.resize(nbMesh);
501
502
2/2
✓ Branch 0 taken 468 times.
✓ Branch 1 taken 462 times.
930 for(std::size_t imesh=0; imesh<nbMesh; ++imesh) {
503 468 auto& p_io = m_ios[imesh];
504 468 auto& r_mesh = m_mesh[imesh];
505 936 p_io = felisce::make_shared<IO>(r_instance.inputDirectory, r_instance.inputFile, r_instance.inputMesh[imesh],
506 468 r_instance.outputMesh[imesh], r_instance.meshDir, r_instance.resultDir,
507 936 r_instance.prefixName[imesh]);
508 468 r_mesh = felisce::make_shared<GeometricMeshRegion>();
509
510 468 p_io->readMesh(*r_mesh, r_instance.spaceUnit);
511
512
2/2
✓ Branch 1 taken 250 times.
✓ Branch 2 taken 218 times.
468 if (FelisceParam::verbose()) {
513 250 PetscPrintf(MpiInfo::petscComm(),"\n/========Information about the input mesh========/.\n");
514 250 PetscPrintf(MpiInfo::petscComm(),"Name of the input mesh: <%s>.\n", r_instance.inputMesh[imesh].c_str());
515 }
516
517
2/2
✓ Branch 1 taken 131 times.
✓ Branch 2 taken 337 times.
468 if (MpiInfo::rankProc() == 0) {
518 131 r_mesh->print(FelisceParam::verbose());
519 }
520
521 468 int& num_coor = r_instance.numCoor;
522
2/2
✓ Branch 0 taken 462 times.
✓ Branch 1 taken 6 times.
468 if (num_coor == 0) {
523 462 num_coor = r_mesh->numCoor();
524
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 } else if (num_coor != r_mesh->numCoor()) {
525 FEL_ERROR("Mesh dimensions are inconsistent. Combining 2D and 3D meshes is not supported.");
526 }
527
528 // Check if the mesh is inverted
529
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 468 times.
468 if (r_instance.checkVolumeOrientation) {
530 if (FEUtilities::CheckVolumeIsInverted(*r_mesh)) {
531 FEL_ERROR("Mesh is inverted. Check connectivity");
532 }
533 }
534 }
535
536 462 m_meshIsRead = true;
537 462 }
538
539 /***********************************************************************************/
540 /***********************************************************************************/
541
542 126 void Model::writeMesh()
543 {
544 // Getting instance
545 126 const auto& r_instance = FelisceParam::instance(this->instanceIndex());
546
547
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 124 times.
126 if(FelisceParam::verbose()>1) {
548 2 PetscPrintf(MpiInfo::petscComm(),"Write mesh\n");
549 }
550
551
1/2
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
126 if(!r_instance.duplicateSupportDof) {
552
2/2
✓ Branch 1 taken 127 times.
✓ Branch 2 taken 126 times.
253 for(std::size_t imesh=0; imesh<m_mesh.size(); ++imesh)
553
2/4
✓ Branch 4 taken 127 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 127 times.
✗ Branch 10 not taken.
127 m_ios[imesh]->writeMesh(*m_mesh[imesh]);
554 } else {
555 // because writeGeoForUnknown write the mesh from the support element not from the mesh
556 // This way, the duplicated support elements are saved and the mesh has the same dof as the solutions
557 for(std::size_t ipb=0; ipb<m_linearProblem.size(); ++ipb) {
558 for(std::size_t iUnknown=0; iUnknown<m_linearProblem[ipb]->listUnknown().size(); ++iUnknown) {
559 m_linearProblem[ipb]->writeGeoForUnknown(iUnknown);
560 }
561 }
562 }
563
564 126 m_meshIsWritten = true;
565 126 }
566
567 /***********************************************************************************/
568 /***********************************************************************************/
569
570 void Model::buildEdges()
571 {
572 for(std::size_t imesh=0; imesh<m_mesh.size(); ++imesh)
573 m_mesh[imesh]->buildEdges();
574 }
575
576 /***********************************************************************************/
577 /***********************************************************************************/
578
579 void Model::buildFaces()
580 {
581 for(std::size_t imesh=0; imesh<m_mesh.size(); ++imesh)
582 m_mesh[imesh]->buildFaces();
583 }
584
585 /***********************************************************************************/
586 /***********************************************************************************/
587
588 11983 void Model::writeSolution()
589 {
590 11983 const auto& r_instance = FelisceParam::instance(this->instanceIndex());
591
592
2/2
✓ Branch 1 taken 3062 times.
✓ Branch 2 taken 8921 times.
11983 if (MpiInfo::rankProc() == 0) {
593
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 2937 times.
3062 if (!m_meshIsWritten) {
594 125 writeMesh();
595 }
596 }
597
598 11983 if( (m_fstransient->iteration % r_instance.frequencyWriteSolution == 0)
599 || m_hasFinished
600
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 11983 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 11983 times.
✗ Branch 11 not taken.
11983 || ( m_fstransient->iteration >= r_instance.intervalWriteSolution[0] && m_fstransient->iteration <= r_instance.intervalWriteSolution[1] )) {
601
602
2/2
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 11875 times.
11983 if(FelisceParam::verbose() > 1)
603 108 PetscPrintf(MpiInfo::petscComm(),"Write solutions\n");
604
605
2/2
✓ Branch 1 taken 12825 times.
✓ Branch 2 taken 11983 times.
24808 for (std::size_t ipb = 0; ipb < m_linearProblem.size(); ipb++) {
606 12825 m_linearProblem[ipb]->writeSolution(MpiInfo::rankProc(), m_ios, m_fstransient->time, m_fstransient->iteration);
607 }
608
609
2/2
✓ Branch 1 taken 3062 times.
✓ Branch 2 taken 8921 times.
11983 if (MpiInfo::rankProc() == 0) {
610
2/2
✓ Branch 1 taken 3066 times.
✓ Branch 2 taken 3062 times.
6128 for(std::size_t iio=0; iio<m_ios.size(); ++iio) {
611
1/2
✓ Branch 2 taken 3066 times.
✗ Branch 3 not taken.
3066 if ( m_ios[iio]->typeOutput == 1 ) // 1 : ensight{
612 3066 m_ios[iio]->postProcess(m_fstransient->time/*, !m_sameGeometricMeshForVariable*/);
613 }
614 }
615 }
616
617 // Warning. If using a bdf for time derivative resolution, you have to modify this call with your bdf method order.
618
2/2
✓ Branch 1 taken 12825 times.
✓ Branch 2 taken 11983 times.
24808 for (std::size_t ipb = 0; ipb < m_linearProblem.size(); ipb++) {
619
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 12825 times.
12825 if(m_solutionBackup[ipb].hasToBackup(m_fstransient->iteration, r_instance.frequencyBackup) ) {
620 if(FelisceParam::verbose() > 1)
621 PetscPrintf(MpiInfo::petscComm(),"Backup the solutions for linear problem %ld\n", static_cast<unsigned long>(ipb));
622
623 // Backup of linear problem variables
624 m_linearProblem[ipb]->writeSolutionBackup(m_initialCondition.listVariable(), MpiInfo::rankProc(), m_solutionBackup[ipb].listIO(), m_fstransient->time, m_fstransient->iteration);
625
626 // This part has to be improved (07/05/13, Elisa) TODO
627
628 // Backup of linear problem meshes
629 m_solutionBackup[ipb].backup(m_fstransient->time, m_mesh, MpiInfo::rankProc());
630 }
631 }
632 11983 }
633
634 /***********************************************************************************/
635 /***********************************************************************************/
636
637 void Model::ComputeStress(int coef, int label, std::vector<double>& stress)
638 {
639 m_linearProblem[0]->computeBoundaryStress(coef,label,stress);
640 }
641
642 /***********************************************************************************/
643 /***********************************************************************************/
644
645 void Model::addCallbackXYZ(const char *name, const CallbackXYZ& cb)
646 {
647 m_mapCallbackXYZ[name] = cb;
648 }
649
650 /***********************************************************************************/
651 /***********************************************************************************/
652
653 8 void Model::addCallbackXYZT(const char* name, const CallbackXYZT& cb)
654 {
655
3/6
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
8 m_mapCallbackXYZT[name] = cb;
656
657 //give the callback to each ElementFieldDynamicValue that want it
658 Component comp;
659 ElementFieldDynamicValue *efDV;
660 // iterate on all elementFieldDynamicValue contained in the std::unordered_map
661
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 for (auto it = FelisceParam::instance(this->instanceIndex()).elementFieldDynamicValueMap.begin() ;
662
3/4
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 8 times.
16 it != FelisceParam::instance(this->instanceIndex()).elementFieldDynamicValueMap.end() ;
663 8 it++) {
664 8 efDV = it->second;
665 // iterate on all components
666
3/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 8 times.
16 for (int icomp=0 ; icomp < efDV->numComp() ; ++icomp) {
667 8 comp = efDV->allComp[icomp];
668
669 // if the component has to be std::set with the function passed to
670 // Model::addCallbackXYZT, give it to the ElementFieldDynamicValue
671
11/24
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4 times.
✓ Branch 14 taken 4 times.
✓ Branch 15 taken 8 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 8 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 8 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 4 times.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
8 if ( efDV->typeValueOfElementField(comp) == FROM_FUNCTION && efDV->functionName(comp) == static_cast<std::string>(name)) {
672
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 efDV->setCallbackXYZT(cb,comp);
673 }
674 }
675 }
676 8 }
677
678 /***********************************************************************************/
679 /***********************************************************************************/
680
681 CallbackXYZ& Model::callbackXYZ(const char* name)
682 {
683 auto it = m_mapCallbackXYZ.find(name);
684 auto end = m_mapCallbackXYZ.end();
685
686 if (it == end) {
687 const int n = m_mapCallbackXYZ.size();
688 std::ostringstream msg;
689 msg << "No such callback '" << name << "'. ";
690 msg << n << (n>1 ? " candidates" : " candidate") << (n>0 ? ": (" : ".");
691 std::size_t counter = 1;
692 for (it = m_mapCallbackXYZ.begin() ; it != end ; it++) {
693 ++counter;
694 msg << "'" << it->first << "'" << (counter == m_mapCallbackXYZ.size() ? ")." : ", ");
695 }
696 FEL_ERROR(msg.str().c_str());
697 }
698
699 return it->second;
700 }
701
702 /***********************************************************************************/
703 /***********************************************************************************/
704
705 CallbackXYZT& Model::callbackXYZT(const char* name)
706 {
707 auto it = m_mapCallbackXYZT.find(name);
708 auto end = m_mapCallbackXYZT.end();
709
710 if (it == end) {
711 int n = m_mapCallbackXYZT.size();
712 std::ostringstream msg;
713 msg << "No such callback '" << name << "'. ";
714 msg << n << (n>1 ? " candidates" : " candidate") << (n>0 ? ": (" : ".");
715 std::size_t counter = 1;
716 for (it = m_mapCallbackXYZT.begin() ; it != end; it++) {
717 ++counter;
718 msg << "'" << it->first << "'" << (counter == m_mapCallbackXYZT.size() ? ")." : ", ");
719 }
720 FEL_ERROR(msg.str().c_str());
721 }
722
723 return it->second;
724 }
725
726 /***********************************************************************************/
727 /***********************************************************************************/
728
729 double Model::evaluateCallback(const char* name, double x, double y, double z)
730 {
731 CallbackXYZ cb = callbackXYZ(name);
732 return cb(x,y,z);
733 }
734
735 /***********************************************************************************/
736 /***********************************************************************************/
737
738 double Model::evaluateCallback(const char* name, double x, double y, double z, double t)
739 {
740 CallbackXYZT cb = callbackXYZT(name);
741 return cb(x,y,z,t);
742 }
743
744 /***********************************************************************************/
745 /***********************************************************************************/
746
747 266 void Model::setInitialCondition()
748 {
749 266 const auto& r_instance = FelisceParam::instance(this->instanceIndex());
750
751
2/2
✓ Branch 1 taken 299 times.
✓ Branch 2 taken 266 times.
565 for (std::size_t iProblem=0; iProblem<m_linearProblem.size(); iProblem++) {
752
1/2
✓ Branch 0 taken 299 times.
✗ Branch 1 not taken.
299 if (!r_instance.restartSolution) {
753 299 m_U_0.duplicateFrom(m_linearProblem[iProblem]->vector());
754
1/2
✓ Branch 1 taken 299 times.
✗ Branch 2 not taken.
299 m_U_0.set(0.0);
755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 299 times.
299 if (r_instance.hasInitialCondition) {
756
757 int idVar = -1;
758 double valueByDofU_0;
759 felInt aa = 0;
760
761 for (std::size_t iListVar = 0; iListVar < m_initialCondition.listVariable().size(); iListVar++) {
762 for ( std::size_t iUnknown = 0; iUnknown < m_linearProblem[iProblem]->listUnknown().size(); iUnknown++) {
763 idVar = m_linearProblem[iProblem]->listUnknown().idVariable(iUnknown);
764 if ( m_linearProblem[iProblem]->listVariable()[idVar].name() == m_initialCondition.listVariable()[iListVar].name() ) {
765 felInt numDofLpU = m_linearProblem[iProblem]->numDofLocalPerUnknown(m_linearProblem[iProblem]->listUnknown()[iUnknown]);
766 felInt idLocalValue[numDofLpU];
767 felInt idGlobalValue[numDofLpU];
768 for ( felInt ii = 0; ii < numDofLpU; ii++) {
769 idLocalValue[ii] = ii;
770 }
771 ISLocalToGlobalMappingApply(m_linearProblem[iProblem]->mappingDofLocalToDofGlobal(m_linearProblem[iProblem]->listUnknown()[iUnknown]),numDofLpU,&idLocalValue[0],&idGlobalValue[0]);
772 for (felInt ii = 0; ii < numDofLpU; ii++) {
773
774 // TODO this part of the function is not defined for a generic Model... maybe it should be moved or rewritten
775 if(r_instance.readDisplFromFile && r_instance.useALEformulation) {
776 aa = idGlobalValue[ii];
777 static_cast<LinearProblemHarmonicExtension*>(m_linearProblem[1])->HarmExtSol().getValues(1, &aa, &valueByDofU_0);
778 } else {
779 valueByDofU_0 = r_instance.valueInitCond[iListVar];
780 }
781 m_U_0.setValue(idGlobalValue[ii],valueByDofU_0,INSERT_VALUES);
782 }
783 }
784 }
785 }
786 }
787 299 m_U_0.assembly();
788 } else {
789 m_initialCondition.initializeFromFile(r_instance.restartSolutionDir, r_instance.prefixName[m_linearProblem[iProblem]->currentMesh()] + "_bkp.case");
790 userDefinedInitialConditions(iProblem);
791 }
792
793 //Initialize solution for solver.
794 299 m_linearProblem[iProblem]->solution().copyFrom(m_U_0);
795 }
796 266 }
797
798 /***********************************************************************************/
799 /***********************************************************************************/
800
801 void Model::writeMatrixForMatlab(const std::string& filename, unsigned int index) const
802 {
803 m_linearProblem[index]->writeMatrixForMatlab(std::numeric_limits<int>::max(), filename);
804 }
805
806 /***********************************************************************************/
807 /***********************************************************************************/
808
809 void Model::writeRHSForMatlab(const std::string& filename, unsigned int index) const
810 {
811 m_linearProblem[index]->writeRHSForMatlab(std::numeric_limits<int>::max(), filename);
812 }
813
814 /***********************************************************************************/
815 /***********************************************************************************/
816
817 #ifdef FELISCE_WITH_CVGRAPH
818
819 void Model::startIterationCVG()
820 {
821 cvgMainSlave* slave=m_linearProblem[0]->slave();
822 if (slave==nullptr) {
823 FEL_ERROR("slave not initialized");
824 }
825 if( slave->newTimeStep() ) {
826 std::stringstream msg;
827 msg<<"Starting a new time step"<<std::endl;
828 PetscPrintf(MpiInfo::petscComm(),"%s",msg.str().c_str());
829 cvgraphNewTimeStep();
830 m_rhsWithoutBC_zeroed=false;
831 } else if( slave->redoTimeStep() ){
832 std::stringstream msg;
833 msg << "......................................" << std::endl;
834 msg << "Redo time step at time t= " << m_fstransient->time << std::endl;
835 PetscPrintf(MpiInfo::petscComm(),"%s",msg.str().c_str());
836 rhsWithoutBC_restore();
837 m_linearProblem[0]->matrix(0).copyFrom(m_linearProblem[0]->matrixWithoutBC(),SAME_NONZERO_PATTERN);
838 m_linearProblem[0]->vector().copyFrom(m_linearProblem[0]->rhsWithoutBC());
839 } else if( slave->redoTimeStepOnlyCVGData() ) {
840 std::stringstream msg;
841 msg << "......................................" << std::endl;
842 msg << "Redo time step, with only cvg data, at time t= " << m_fstransient->time << std::endl;
843 PetscPrintf(MpiInfo::petscComm(),"%s",msg.str().c_str());
844 rhsWithoutBC_zeroEntries();
845 m_linearProblem[0]->matrix(0).copyFrom(m_linearProblem[0]->matrixWithoutBC(),SAME_NONZERO_PATTERN);
846 m_linearProblem[0]->vector().zeroEntries();
847 m_linearProblem[0]->applyBC(FelisceParam::instance(this->instanceIndex()).essentialBoundaryConditionsMethod, MpiInfo::rankProc(), FlagMatrixRHS::only_matrix);//We insert dirichlet and robin parts to the matrix.
848 } else {
849 slave->msgInfo().print(1);
850 FEL_ERROR("Error: unexpected timeStatus");
851 }
852 }
853
854 /***********************************************************************************/
855 /***********************************************************************************/
856
857 void Model::ImposeCVGraphInterfaceSolution(double* ImpValue)
858 {
859 m_cvgraphInterf->ImposeSolution(ImpValue);
860 }
861
862 /***********************************************************************************/
863 /***********************************************************************************/
864
865 void Model::ImposeCVGraphInterfaceSolutionAndComputedVariable(double* ImpValue, int idVariable)
866 {
867 m_cvgraphInterf->ImposeSolutionAndComputedVariable(ImpValue, idVariable);
868 }
869
870 /***********************************************************************************/
871 /***********************************************************************************/
872
873 void Model::ExtractCVGraphInterfaceSolution(double* valueDofInterface)
874 {
875 m_cvgraphInterf->ExtractSolution(m_linearProblem[0]->solution(), valueDofInterface);
876 }
877
878 /***********************************************************************************/
879 /***********************************************************************************/
880
881 void Model::ExtractCVGraphInterfaceSolution(double* valueDofInterface, int idVariable)
882 {
883 m_cvgraphInterf->ExtractSolution( m_linearProblem[0]->solution(), valueDofInterface, idVariable);
884 }
885
886 /***********************************************************************************/
887 /***********************************************************************************/
888
889 void Model::ExtractCVGraphInterfaceSolutionAndComputedVariable(double* valueDofInterface,int idVariable, std::vector<double>& interfaceComputedVariable)
890 {
891 m_cvgraphInterf->ExtractSolutionAndComputedVariable( m_linearProblem[0]->solution(), interfaceComputedVariable, valueDofInterface, idVariable);
892 }
893
894 /***********************************************************************************/
895 /***********************************************************************************/
896
897 void Model::StoreCVGraphInterfaceSolution(double* StoringValue)
898 {
899 m_cvgraphInterf->StoreSolution(StoringValue);
900 }
901
902 /***********************************************************************************/
903 /***********************************************************************************/
904
905 void Model::rhsWithoutBC_zeroEntries()
906 {
907 // If the m_rhsWithoutBC was already zeroed we do nothing
908 if ( !m_rhsWithoutBC_zeroed ) {
909
910 // We save a copy of it before erasing it.
911 // So that we can restore it later
912 if ( m_rhsWithForceTermWithoutBC.isNull() ) {
913 // In case it was not initialized we do it now.
914 m_rhsWithForceTermWithoutBC.duplicateFrom(m_linearProblem[0]->rhsWithoutBC());
915 }
916 m_rhsWithForceTermWithoutBC.copyFrom(m_linearProblem[0]->rhsWithoutBC());
917
918 // We std::set it to zero.
919 m_linearProblem[0]->rhsWithoutBC().zeroEntries();
920 m_rhsWithoutBC_zeroed=true;
921 }
922 }
923
924 /***********************************************************************************/
925 /***********************************************************************************/
926
927 void Model::rhsWithoutBC_restore()
928 {
929 // If it was zeroed, we restore it.
930 if (m_rhsWithoutBC_zeroed) {
931 m_linearProblem[0]->rhsWithoutBC().copyFrom(m_rhsWithForceTermWithoutBC);
932 }
933 }
934
935 #endif
936 }
937