GCC Code Coverage Report


Directory: ./
File: Solver/linearProblem.cpp
Date: 2024-04-14 07:32:34
Exec Total Coverage
Lines: 1396 3446 40.5%
Branches: 1359 4732 28.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: J. Foulon & J-F. Gerbeau & V. Martin
13 //
14
15 // System includes
16 #include <limits>
17 #include <numeric>
18
19 // External includes
20 #include <petsc/private/snesimpl.h>
21 #include "Core/NoThirdPartyWarning/Petsc/sys.hpp"
22
23 // Project includes
24 #include "Core/key_hash.hpp"
25 #include "Model/model.hpp"
26 #include "Solver/linearProblem.hpp"
27 #include "Solver/bdf.hpp"
28 #include "Tools/fe_utilities.hpp"
29 #include "DegreeOfFreedom/boundaryCondition.hpp"
30 #include "PETScInterface/SNESInterface.hpp"
31
32 namespace felisce
33 {
34
35 247 void SnesContext::initialize(LinearProblem& aLinearProblem, int aRankProc, int aSizeProc,
36 ApplyNaturalBoundaryConditionsType aDo_apply_natural, FlagMatrixRHS flag)
37 {
38 247 linearProblem = &aLinearProblem;
39 247 rankProc = aRankProc;
40 247 sizeProc = aSizeProc;
41 247 do_apply_natural = aDo_apply_natural;
42 247 flag_matrix_rhs = flag;
43 247 }
44
45 /***********************************************************************************/
46 /***********************************************************************************/
47
48 518 LinearProblem::LinearProblem(const std::string name, const std::size_t numMat, const std::size_t numVec) :
49
20/40
✓ Branch 2 taken 518 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 518 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 518 times.
✗ Branch 12 not taken.
✓ Branch 26 taken 518 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 518 times.
✗ Branch 30 not taken.
✓ Branch 41 taken 518 times.
✗ Branch 42 not taken.
✓ Branch 54 taken 518 times.
✗ Branch 55 not taken.
✓ Branch 57 taken 518 times.
✗ Branch 58 not taken.
✓ Branch 60 taken 518 times.
✗ Branch 61 not taken.
✓ Branch 63 taken 518 times.
✗ Branch 64 not taken.
✓ Branch 66 taken 518 times.
✗ Branch 67 not taken.
✓ Branch 69 taken 518 times.
✗ Branch 70 not taken.
✓ Branch 72 taken 518 times.
✗ Branch 73 not taken.
✓ Branch 75 taken 518 times.
✗ Branch 76 not taken.
✓ Branch 84 taken 518 times.
✗ Branch 85 not taken.
✓ Branch 92 taken 518 times.
✗ Branch 93 not taken.
✓ Branch 95 taken 518 times.
✗ Branch 96 not taken.
✓ Branch 98 taken 518 times.
✗ Branch 99 not taken.
✓ Branch 103 taken 518 times.
✗ Branch 104 not taken.
✓ Branch 106 taken 518 times.
✗ Branch 107 not taken.
518 m_name(name)
50 {
51
1/2
✓ Branch 1 taken 518 times.
✗ Branch 2 not taken.
518 m_matrices.resize(numMat);
52
1/2
✓ Branch 1 taken 518 times.
✗ Branch 2 not taken.
518 m_vectors.resize(numVec);
53 518 }
54
55 /***********************************************************************************/
56 /***********************************************************************************/
57
58 1036 LinearProblem::~LinearProblem()
59 {
60
2/2
✓ Branch 0 taken 513 times.
✓ Branch 1 taken 5 times.
1036 if(m_initMappingElem) {
61
2/2
✓ Branch 1 taken 525 times.
✓ Branch 2 taken 513 times.
2076 for (std::size_t i = 0; i < m_mappingElem.size(); ++i)
62 1050 ISLocalToGlobalMappingDestroy(&m_mappingElem[i]);
63 }
64
65
6/6
✓ Branch 0 taken 513 times.
✓ Branch 1 taken 5 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 509 times.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 514 times.
1036 if(m_initMappingElemSupport && FelisceParam::instance(this->instanceIndex()).duplicateSupportDof) {
66
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 4 times.
22 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ )
67 14 ISLocalToGlobalMappingDestroy(m_mappingElemSupportPerUnknown[iUnknown]);
68 }
69
70
2/2
✓ Branch 0 taken 513 times.
✓ Branch 1 taken 5 times.
1036 if(m_initMappingNodes) {
71 1026 ISLocalToGlobalMappingDestroy(&m_mappingNodes);
72 }
73
74
2/2
✓ Branch 0 taken 513 times.
✓ Branch 1 taken 5 times.
1036 if(m_initMappingLocalFelisceToGlobalPetsc) {
75
2/2
✓ Branch 1 taken 739 times.
✓ Branch 2 taken 513 times.
2504 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ )
76 1478 ISLocalToGlobalMappingDestroy(&m_mappingIdLocalDofPerUnknownToIdGlobalDofPetsc[iUnknown]);
77 }
78
79
2/2
✓ Branch 0 taken 513 times.
✓ Branch 1 taken 5 times.
1036 if(m_initAO) {
80 1026 AODestroy(&m_ao);
81 }
82
83
2/2
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 514 times.
1036 if(FelisceParam::instance(this->instanceIndex()).duplicateSupportDof) {
84
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
8 if(m_areOriginalSupportDofMeshAllocated) {
85
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 4 times.
22 for(std::size_t i=0; i<m_supportDofUnknownOriginal.size(); ++i) {
86
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
14 delete m_supportDofUnknownOriginal[i];
87 }
88 }
89 }
90 }
91
92 /***********************************************************************************/
93 /***********************************************************************************/
94
95 513 void LinearProblem::initialize(std::vector<GeometricMeshRegion::Pointer>& mesh, MPI_Comm& comm, bool doUseSNES)
96 {
97 IGNORE_UNUSED_ARGUMENT(comm);
98 513 m_mesh = mesh;
99
100 513 m_dimesion = m_mesh[0]->spatialDim();
101
1/2
✗ Branch 5 not taken.
✓ Branch 6 taken 513 times.
1038 if ( ! std::all_of(m_mesh.begin(), m_mesh.end(), [dim = m_dimesion](auto mesh){ return dim == mesh->spatialDim(); } ) ) {
102 auto& r_instance = FelisceParam::instance(this->instanceIndex());
103
104 if ( r_instance.dimension.size() > m_identifier_problem )
105 m_dimesion = r_instance.dimension[m_identifier_problem];
106 else
107 FEL_ERROR("Meshes have different dimensions and problem dimension not provided by input file");
108 }
109
110 513 m_pSNESInterface->doUseSNES() = doUseSNES;
111 513 m_verbosity = FelisceParam::verbose();
112 513 }
113
114 /***********************************************************************************/
115 /***********************************************************************************/
116
117 513 void LinearProblem::definePhysicalVariable(const std::vector<PhysicalVariable>& listVariable, const std::vector<std::size_t>& listNumComp)
118 {
119
2/2
✓ Branch 1 taken 881 times.
✓ Branch 2 taken 513 times.
1394 for (std::size_t iVar = 0; iVar < listVariable.size(); iVar++)
120
2/4
✓ Branch 1 taken 881 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 881 times.
✗ Branch 7 not taken.
881 m_listVariable.addVariable(listVariable[iVar],listNumComp[iVar],this->instanceIndex());
121
122
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 513 times.
513 if (listVariable.size() != m_listVariable.size()) {
123 FEL_ERROR("Problem with your input file. Not enough physical variable defined for this problem!");
124 }
125
126 //link between unknown of the linear system and variable defined in the problem.
127
1/2
✓ Branch 1 taken 513 times.
✗ Branch 2 not taken.
513 Variable variable;
128 513 bool unknownFound = false;
129
2/2
✓ Branch 1 taken 739 times.
✓ Branch 2 taken 513 times.
1252 for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++) {
130
6/6
✓ Branch 1 taken 1333 times.
✓ Branch 2 taken 459 times.
✓ Branch 3 taken 1053 times.
✓ Branch 4 taken 280 times.
✓ Branch 5 taken 1053 times.
✓ Branch 6 taken 739 times.
1792 for (std::size_t iVar = 0; iVar < listVariable.size() && unknownFound == false; iVar++) {
131
1/2
✓ Branch 2 taken 1053 times.
✗ Branch 3 not taken.
1053 variable = m_listVariable[iVar];
132
2/2
✓ Branch 2 taken 739 times.
✓ Branch 3 taken 314 times.
1053 if ( m_listUnknown[iUnknown] == variable.physicalVariable()) {
133 739 m_listUnknown.idVariable(iUnknown) = iVar;
134 739 m_listVariable.listIdUnknownOfVariable(iVar) = static_cast<int>(iUnknown);
135
1/2
✓ Branch 3 taken 739 times.
✗ Branch 4 not taken.
739 m_meshUnknown.push_back(m_listVariable[iVar].idMesh());
136 739 unknownFound = true;
137 }
138 }
139 739 unknownFound = false;
140 }
141
142 //set current mesh
143 513 m_currentMesh = m_meshUnknown.front();
144
2/4
✓ Branch 4 taken 513 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 513 times.
513 if ( std::adjacent_find( m_meshUnknown.begin(), m_meshUnknown.end(), std::not_equal_to<std::size_t>()) != m_meshUnknown.end() )
145 FEL_WARNING( "Unknows defined over different meshes: m_currentMesh = " + std::to_string(m_currentMesh) );
146
147
148
2/2
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 254 times.
513 if (m_verbosity) {
149
2/4
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 259 times.
✗ Branch 5 not taken.
259 PetscPrintf(MpiInfo::petscComm(), "\n/========== Information about the linear system ==========/\n");
150
2/4
✓ Branch 2 taken 259 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 259 times.
✗ Branch 6 not taken.
259 PetscPrintf(MpiInfo::petscComm(), "<%s>.\n", m_name.c_str());
151
2/4
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 259 times.
✗ Branch 5 not taken.
259 PetscPrintf(MpiInfo::petscComm(), "Unknowns are: ");
152
2/2
✓ Branch 1 taken 428 times.
✓ Branch 2 taken 259 times.
687 for (std::size_t iUnkonwn = 0; iUnkonwn < m_listUnknown.size(); iUnkonwn++) {
153
3/6
✓ Branch 3 taken 428 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 428 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 428 times.
✗ Branch 11 not taken.
428 PetscPrintf(MpiInfo::petscComm(), "<%s> ", m_listVariable[m_listUnknown.idVariable(iUnkonwn)].name().c_str());
154 }
155
2/4
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 259 times.
✗ Branch 5 not taken.
259 PetscPrintf(MpiInfo::petscComm(), "\nPhysical variables associated: ");
156
1/2
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
259 std::stringstream msg;
157
1/2
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
259 m_listVariable.print(m_verbosity,msg);
158
3/6
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 259 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 259 times.
✗ Branch 9 not taken.
259 PetscPrintf(MpiInfo::petscComm(), "%s",msg.str().c_str());
159 259 }
160
161
1/2
✓ Branch 1 taken 513 times.
✗ Branch 2 not taken.
513 m_listUnknown.setDefaultMask(m_listVariable);
162
1/2
✓ Branch 1 taken 513 times.
✗ Branch 2 not taken.
513 m_listUnknown.print(1);
163
1/2
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
513 m_numDofUnknown.resize(m_listUnknown.size());
164
1/2
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
513 m_numDofLocalUnknown.resize(m_listUnknown.size());
165 513 }
166
167 /***********************************************************************************/
168 /***********************************************************************************/
169
170 524 void LinearProblem::computeDof(int numProc, int idProc)
171 {
172 int idVar, iMesh;
173
174 /// For each unknown, create the global support dof
175
2/2
✓ Branch 1 taken 761 times.
✓ Branch 2 taken 524 times.
1285 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ ) {
176 761 idVar = m_listUnknown.idVariable(iUnknown);
177 761 iMesh = m_listVariable[idVar].idMesh();
178
1/2
✓ Branch 3 taken 761 times.
✗ Branch 4 not taken.
761 m_supportDofUnknown.emplace_back(m_listVariable[idVar], m_mesh[iMesh]);
179
180
4/6
✓ Branch 1 taken 761 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 761 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 29 times.
✓ Branch 7 taken 732 times.
761 if(FelisceParam::instance(this->instanceIndex()).duplicateSupportDof) {
181
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 22 times.
29 if(!m_areOriginalSupportDofMeshAllocated) {
182
3/6
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 10 not taken.
7 m_supportDofUnknownOriginal.push_back(new SupportDofMesh(m_listVariable[idVar], m_mesh[iMesh]));
183
184
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 3 times.
7 if(iUnknown == m_listUnknown.size() - 1)
185 4 m_areOriginalSupportDofMeshAllocated = true;
186 }
187 } else
188
1/2
✓ Branch 2 taken 732 times.
✗ Branch 3 not taken.
732 m_supportDofUnknownOriginal.push_back(&supportDofUnknown(iUnknown));
189
190 // Print info on the global supportDofMesh
191
2/2
✓ Branch 0 taken 428 times.
✓ Branch 1 taken 333 times.
761 if (m_verbosity) {
192
3/6
✓ Branch 3 taken 428 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 428 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 428 times.
✗ Branch 11 not taken.
428 PetscPrintf(MpiInfo::petscComm(), "\n/======= Global support dof mesh associate to the unknown: <%s>.======/\n", m_listVariable[m_listUnknown.idVariable(iUnknown)].name().c_str());
193
1/2
✓ Branch 2 taken 428 times.
✗ Branch 3 not taken.
428 supportDofUnknown(iUnknown).print(m_verbosity);
194 }
195 }
196
197
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 initSupportDofDerivedProblem();
198
199 // print info
200
6/10
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 265 times.
✓ Branch 3 taken 259 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 259 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 259 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 524 times.
524 if (m_verbosity && FelisceParam::instance(this->instanceIndex()).duplicateSupportDof) {
201 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ ) {
202 PetscPrintf(MpiInfo::petscComm(), "\n/======= NEW Global support dof mesh associate to the unknown: <%s>.======/\n", m_listVariable[m_listUnknown.idVariable(iUnknown)].name().c_str());
203 supportDofUnknown(iUnknown).print(m_verbosity);
204 }
205 }
206
207 /// Copy the list of unknowns, variables and all the support meshes in m_dof.
208
1/2
✓ Branch 3 taken 524 times.
✗ Branch 4 not taken.
524 std::vector<SupportDofMesh*> pSupportDofUnknown(m_supportDofUnknown.size(), nullptr);
209
2/2
✓ Branch 1 taken 761 times.
✓ Branch 2 taken 524 times.
1285 for(std::size_t iUnknown=0; iUnknown < m_supportDofUnknown.size(); ++iUnknown)
210 761 pSupportDofUnknown[iUnknown] = &supportDofUnknown(iUnknown);
211
212
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 m_dof.setDof(m_listUnknown, m_listVariable, pSupportDofUnknown);
213
214 /// Compute numDof and numDofPerUnknown in m_dof.
215 /// Initialize pattern, random repartition on processors before call ParMetis.
216
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 m_dof.initializePattern(numProc, idProc);
217
218 /// Copy numDof and numDofPerUnknown here.
219 524 m_numDof = m_dof.numDof();
220
2/2
✓ Branch 1 taken 761 times.
✓ Branch 2 taken 524 times.
1285 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ )
221 761 m_numDofUnknown[iUnknown] = m_dof.numDofPerUnknown()[iUnknown];
222
223 // Print information about dof
224
2/2
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 265 times.
524 if (m_verbosity) {
225
2/4
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 259 times.
✗ Branch 5 not taken.
259 PetscPrintf(MpiInfo::petscComm(), "\n/========== Information about dof ==========/\n");
226
1/2
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
259 std::stringstream msg;
227
1/2
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
259 m_dof.print(m_verbosity,msg);
228
3/6
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 259 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 259 times.
✗ Branch 9 not taken.
259 PetscPrintf(MpiInfo::petscComm(), "%s\n",msg.str().c_str());
229 259 }
230 524 }
231
232 /***********************************************************************************/
233 /***********************************************************************************/
234
235 640 void LinearProblem::getSupportCoordinate(ElementType& eltType, felInt iel, felInt idSupport, int iUnknown, Point& pt)
236 {
237 // Even if the support dof are duplicated, the coordinates are the same. We can take the coordinate of the first element support for this element.
238 felInt idEltInSupportLocal;
239
1/2
✓ Branch 2 taken 640 times.
✗ Branch 3 not taken.
640 m_supportDofUnknownLocal[iUnknown].getIdElementSupport(eltType, iel, idEltInSupportLocal);
240
1/4
✗ Branch 6 not taken.
✓ Branch 7 taken 640 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
640 FEL_ASSERT(m_supportDofUnknownLocal[iUnknown].iEle()[idEltInSupportLocal] + idSupport < int( m_supportDofUnknownLocal[iUnknown].iSupportDof().size() ) );
241 640 felInt id = m_supportDofUnknownLocal[iUnknown].iSupportDof()[m_supportDofUnknownLocal[iUnknown].iEle()[idEltInSupportLocal] + idSupport];
242
3/6
✓ Branch 1 taken 640 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 640 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 640 times.
640 if ( FelisceParam::instance(this->instanceIndex()).FusionDof ) {
243 // IMPORTANT: Here have to std::unordered_map back the supportDof to the original unfusioned (mesh) data.
244 // This also applies to other type of BC. TO BE DONE
245 auto it = find(supportDofUnknown(iUnknown).listPerm().begin(),supportDofUnknown(iUnknown).listPerm().end(),id);
246 id = it- supportDofUnknown(iUnknown).listPerm().begin();
247 }
248 640 pt = m_supportDofUnknownLocal[iUnknown].listNode()[id];
249 640 }
250
251 /***********************************************************************************/
252 /***********************************************************************************/
253
254 2285059 void LinearProblem::getSupportCoordinate(felInt idElt, felInt idSupport, int iUnknown, Point& pt)
255 {
256 // Even if the support dof are duplicated, the coordinates are the same. We can take the coordinate of the first element support for this element.
257 felInt idEltInSupportLocal;
258
1/2
✓ Branch 2 taken 2285059 times.
✗ Branch 3 not taken.
2285059 m_supportDofUnknownLocal[iUnknown].getIdElementSupport(idElt, idEltInSupportLocal);
259 2285059 felInt id = m_supportDofUnknownLocal[iUnknown].iSupportDof()[m_supportDofUnknownLocal[iUnknown].iEle()[idEltInSupportLocal] + idSupport];
260
4/6
✓ Branch 1 taken 2285059 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2285059 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3135 times.
✓ Branch 7 taken 2281924 times.
2285059 if ( FelisceParam::instance(this->instanceIndex()).FusionDof ) {
261 // IMPORTANT: Here have to std::unordered_map back the supportDof to the original unfusioned (mesh) data.
262 // This also applies to other type of BC. TO BE DONE
263
1/2
✓ Branch 7 taken 3135 times.
✗ Branch 8 not taken.
3135 auto it = find(supportDofUnknown(iUnknown).listPerm().begin(),supportDofUnknown(iUnknown).listPerm().end(),id);
264 3135 id = it- supportDofUnknown(iUnknown).listPerm().begin();
265 }
266 2285059 pt = m_supportDofUnknownLocal[iUnknown].listNode()[id];
267 2285059 }
268
269 /***********************************************************************************/
270 /***********************************************************************************/
271
272 524 void LinearProblem::cutMesh()
273 {
274 /// partitionDof: partition the dof with parmetis and the elements.
275 524 partitionDof(static_cast<idx_t>(MpiInfo::numProc()),MpiInfo::rankProc(), MpiInfo::petscComm());
276 //partitionDof_Petsc(static_cast<idx_t>(MpiInfo::numProc()), rankProc, comm);
277
278 /// set local mesh and local supportDofMeshes
279 524 setLocalMeshAndSupportDofMesh(MpiInfo::rankProc());
280 524 }
281
282 /***********************************************************************************/
283 /***********************************************************************************/
284
285 524 void LinearProblem::partitionDof( idx_t numPart, int rankPart, MPI_Comm comm)
286 {
287 /*!
288 Partitioning of the dof.
289 */
290
291 /*
292 Declaration of the parameters for ParMetis.
293 idx_t define the type for ParMetis int.
294 */
295
296 // Input parameters
297 524 idx_t num_flag = 0; // C-style array index.
298 524 idx_t ncon = 1; // number of weight per vertices of the graph.
299 524 idx_t wgtFlag = 0; // No weight in the graph.
300 idx_t option[3]; // verbose level and random seed for parmetis.
301 524 idx_t vertexdist[numPart + 1]; // Repartition of dof between the processes.
302
303 524 real_t ubvec = static_cast<real_t>(1.05); // Imbalance tolerance
304 524 real_t tpwgts[numPart*ncon]; // See parmetis manual for description
305
306 // Output parameters
307 idx_t edgecut; // Number of edge in the graph that are cut by the partitioning.
308 524 int numRows = m_dof.pattern().numRows();
309
1/2
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
524 std::vector<idx_t> dofPartitionning(numRows, 0); // The partition of the dof.
310
311 /*
312 Initialisation of the parameters.
313 */
314
315 // vertexdist
316 // vertexdist[j] = sum(size in process i), for i=0,..,j-1.
317 // initialize the first value (always 0)
318 524 vertexdist[0] = 0;
319
320 // Gather all the size in vertexdist, starting at index 1 (because vertexdist[0] is 0)
321
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 MPI_Allgather(&numRows, 1, MPI_INT, &vertexdist[1], 1, MPI_INT, comm);
322
323 // Compute the partial sum
324
2/2
✓ Branch 0 taken 1460 times.
✓ Branch 1 taken 524 times.
1984 for (int i = 1; i < numPart; i ++)
325 1460 vertexdist[i + 1] += vertexdist[i];
326
327 // option
328 524 option[0] = 1; // 0 = default values, 1 = user defined, to print all that ugly information.
329 524 option[1] = 0; // verbose level.
330 524 option[2] = 100; // random seed.
331
332 // tpwgts
333
2/2
✓ Branch 0 taken 1984 times.
✓ Branch 1 taken 524 times.
2508 for ( felInt i= 0; i < numPart*ncon; i++)
334 1984 tpwgts[i] = static_cast<real_t>(1.)/numPart;
335
336 /*
337 Parmetis call
338 */
339 524 MPI_Comm comm_bis = PETSC_COMM_WORLD;
340
3/6
✓ Branch 3 taken 524 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 524 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 524 times.
✗ Branch 11 not taken.
524 ParMETIS_V3_PartKway(vertexdist, &m_dof.pattern().rowPointer(0), &m_dof.pattern().columnIndex(0), nullptr, nullptr, &wgtFlag, &num_flag, &ncon, &numPart, tpwgts, &ubvec, option, &edgecut, dofPartitionning.data(), &comm_bis);
341
342 /*
343 Gather the partitioning to all process
344 */
345
1/2
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
524 m_dofPart.resize(m_dof.numDof(), 0);
346
347 524 felInt recvcount[numPart];
348
2/2
✓ Branch 0 taken 1984 times.
✓ Branch 1 taken 524 times.
2508 for(int i=0; i<numPart; i++)
349 1984 recvcount[i] = vertexdist[i+1] - vertexdist[i];
350
351
1/2
✓ Branch 4 taken 524 times.
✗ Branch 5 not taken.
524 MPI_Allgatherv(dofPartitionning.data(), dofPartitionning.size(), MPI_INT, m_dofPart.data(), recvcount, vertexdist, MPI_INT, comm);
352
353 // Count the number of local dofs
354 524 m_numDofLocal = 0;
355
2/2
✓ Branch 1 taken 2604159 times.
✓ Branch 2 taken 524 times.
2604683 for (felInt i = 0; i < m_dof.numDof(); i++) {
356
2/2
✓ Branch 1 taken 750372 times.
✓ Branch 2 taken 1853787 times.
2604159 if (m_dofPart[i] == rankPart)
357 750372 m_numDofLocal++;
358 }
359
360 /*
361 Build the matrix pattern
362 */
363
1/2
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
524 m_dof.buildPattern(rankPart, m_dofPart.data());
364
365 // Pattern operations:
366 // add complementary pattern if there is one
367
2/2
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 503 times.
524 if(m_dof.patternIsChanged()) {
368
2/4
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
21 m_dof.mergeLocalCompPattern(MpiInfo::petscComm(), numPart, rankPart, m_dofPart);
369
370 // free memory, clear the complementary pattern now that is has been merge with the pattern
371 21 m_dof.clearPatternC();
372 }
373
374 /*!
375 Global ordering: AO is an application between global mesh ordering and global ordering of Petsc
376 AO: globalordering to globalordering
377 the action is:
378 - Take the global index associated to the i-th proc
379 - Create an application to a new global index in order to have contiguous global indexes on the processor
380
381 both global ordering are on input (loc2glob and pordering)
382 AOCreateBasic(comm, m_numDofLocal, loc2Glob, pordering, &m_ao);
383
384 Example:
385 Proc 0:
386 glob2loc = [0 1 2 3 8]
387 pordering =[0 1 2 3 4]
388
389 Proc 1:
390 glob2loc = [4 5 6 7]
391 pordering =[5 6 7 8]
392 */
393
394 felInt rstart;
395 524 felInt cptDof = 0;
396
397 524 felInt loc2Glob[m_numDofLocal];
398
2/2
✓ Branch 0 taken 750372 times.
✓ Branch 1 taken 524 times.
750896 for (felInt i = 0; i < m_numDofLocal; i++)
399 750372 loc2Glob[i] = 0;
400
401
2/2
✓ Branch 1 taken 2604159 times.
✓ Branch 2 taken 524 times.
2604683 for (felInt i = 0; i < m_dof.numDof(); i++) {
402
2/2
✓ Branch 1 taken 750372 times.
✓ Branch 2 taken 1853787 times.
2604159 if (m_dofPart[i] == rankPart) {
403 // cptDof (local) -> i (global)
404 750372 loc2Glob[cptDof] = i;
405 750372 cptDof++;
406 }
407 }
408
409 // inclusive sum (rank_0 = numdoflocal_0, rank_i = sum_j=0^rank_i numdoflocal_i)
410
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 MPI_Scan(&m_numDofLocal, &rstart, 1, MPIU_INT, MPI_SUM, comm);
411 524 rstart -= m_numDofLocal;
412
413 524 felInt pordering[m_numDofLocal];
414
2/2
✓ Branch 0 taken 750372 times.
✓ Branch 1 taken 524 times.
750896 for (felInt i= 0; i < m_numDofLocal; i++) {
415 // pordering: so global indexes are contiguous on a processor; pordering: global->global
416 750372 pordering[i] = rstart + i;
417 }
418
419
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 AOCreateBasic(comm, m_numDofLocal, loc2Glob, pordering, &m_ao);
420 //AOView(m_ao,PETSC_VIEWER_STDOUT_WORLD);
421 524 m_initAO = true;
422
423 /*!
424 Compute the element repartition.
425 An element is owned by a process k if most of its dof are on process k.
426 In case of a draw, the element belongs to the process with the smallest id.
427
428 matteo feb 14, changed the way in which surface elements are associated to different proc: now a surface element is associated to the proc who owns also the volume element.
429 the algorithm implemented works correctly with triangles, but no with quadrilateral and not in 2D: in such a case some surface elements will be associated to the wrong proc.
430 this may cause some problems when dealing with complicated BC such as EmbedFSI
431 It can classify uncorrectly the boundary element in 2D and the quadrangular 3D elements.
432
433 benoit sept 14, a surface boundary element is always associated to the proc of its volume element. If there are surface element inside the domain (not boundary), they will
434 be associated to the proc of one of their volume element (the last one in the loop).
435
436 matteo - benoit august 15, works in 2D and 3D.
437 */
438
439 /// Definition of the vector indexes considered
440 typedef std::vector<felInt> VectorIndexType;
441
442 /// Definition of the hasher considered
443 typedef VectorIndexHasher<VectorIndexType> VectorIndexHasherType;
444
445 /// Definition of the key comparor considered
446 typedef VectorIndexComparor<VectorIndexType> VectorIndexComparorType;
447
448 // Declaration of some variables
449 felInt max; // used to compute indice_max.
450 felInt indice_max; // id of the process that owns the element.
451 felInt idDof; // Local number of a dof.
452 felInt ielSupportDof; // Global number of a dof.
453 524 felInt numElemsPerRef = 0; // Number of elements per label.
454 int idVar; // id of a physical variable.
455 felInt numEltTot; // Total number of element (to be computed).
456 felInt numEltVol; // total number of volume element.
457 felInt numEltPerType[GeometricMeshRegion::m_numTypesOfElement]; // Total number of element per type (to be computed).
458 524 felInt numDofPerProcs[numPart]; // Number of dofs per process. //per element to be computed for each element and then cleared
459 524 VectorIndexType vecSupport; // Ids of the support elements of a mesh element
460 GeometricMeshRegion::ElementType eltType; // type of an element
461 524 VectorIndexType ptOfElem; // id of the vertices of an element
462 524 VectorIndexType ptOfBoundaryElem; // id of the vertices of a boundary element
463 524 std::unordered_map<VectorIndexType, felInt, VectorIndexHasherType, VectorIndexComparorType> bndElements; // ids of the points of the boundary elements
464 524 std::vector<int> listUnknown;
465 std::size_t iUnknown;
466
467 // Initialization
468
1/2
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
524 m_eltPart.resize(m_mesh.size());
469
2/2
✓ Branch 1 taken 547 times.
✓ Branch 2 taken 524 times.
1071 for (std::size_t iMesh = 0; iMesh < m_mesh.size(); ++iMesh){
470
471
2/4
✓ Branch 4 taken 547 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 547 times.
✗ Branch 8 not taken.
547 m_eltPart[iMesh].resize(m_mesh[iMesh]->getNumElement(), 0);
472
473 547 bndElements.clear();
474 547 listUnknown.clear();
475
2/2
✓ Branch 1 taken 802 times.
✓ Branch 2 taken 547 times.
1349 for (iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++)
476
2/2
✓ Branch 3 taken 761 times.
✓ Branch 4 taken 41 times.
802 if ( iMesh == m_listVariable[m_listUnknown.idVariable(iUnknown)].idMesh() )
477
1/2
✓ Branch 1 taken 761 times.
✗ Branch 2 not taken.
761 listUnknown.emplace_back(iUnknown);
478
479
2/2
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 524 times.
547 if ( listUnknown.size() == 0 )
480 23 continue;
481
482
2/2
✓ Branch 0 taken 13100 times.
✓ Branch 1 taken 524 times.
13624 for (int ityp = 0; ityp < GeometricMeshRegion::m_numTypesOfElement; ityp++)
483 13100 numEltPerType[ityp] = 0;
484
485 524 numEltTot = 0;
486
1/2
✓ Branch 3 taken 524 times.
✗ Branch 4 not taken.
524 numEltVol = m_mesh[iMesh]->getNumDomainElement();
487
488 524 const std::vector<ElementType>& bagElementTypeDomain = m_mesh[iMesh]->bagElementTypeDomain();
489 524 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_mesh[iMesh]->bagElementTypeDomainBoundary();
490 524 std::vector<felInt>::iterator bndRefIt;
491
492 // first, a loop on the surface elements to store them in bndElements
493
2/2
✓ Branch 1 taken 606 times.
✓ Branch 2 taken 524 times.
1130 for (std::size_t iEltType = 0; iEltType < bagElementTypeDomainBoundary.size(); ++iEltType) {
494 606 eltType = bagElementTypeDomainBoundary[iEltType];
495
1/2
✓ Branch 1 taken 606 times.
✗ Branch 2 not taken.
606 ptOfBoundaryElem.resize(GeometricMeshRegion::m_numPointsPerElt[eltType]);
496
497
2/2
✓ Branch 8 taken 2056 times.
✓ Branch 9 taken 606 times.
2662 for(auto itRef = m_mesh[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_mesh[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
498 2056 numElemsPerRef = itRef->second.second;
499
500 // notBoundarySurfaceLabels = list of surfaces/edges that are part of the domain but are not boundaries of volumes/surfaces
501
5/10
✓ Branch 2 taken 2056 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2056 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 2056 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 2056 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 2056 times.
✗ Branch 17 not taken.
2056 bndRefIt = find(FelisceParam::instance(this->instanceIndex()).notBoundarySurfaceLabels.begin(), FelisceParam::instance(this->instanceIndex()).notBoundarySurfaceLabels.end(), itRef->first);
502
503 // If current element IS a boundary element
504
3/6
✓ Branch 1 taken 2056 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2056 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2056 times.
✗ Branch 9 not taken.
2056 if(bndRefIt == FelisceParam::instance(this->instanceIndex()).notBoundarySurfaceLabels.end()) {
505
2/2
✓ Branch 0 taken 353793 times.
✓ Branch 1 taken 2056 times.
355849 for (felInt iel = 0; iel < numElemsPerRef; iel++) {
506 // get the ids of the vertices of the element
507
1/2
✓ Branch 3 taken 353793 times.
✗ Branch 4 not taken.
353793 m_mesh[iMesh]->getOneElement(eltType, numEltPerType[eltType], ptOfBoundaryElem, 0);
508
509 // sort them
510
1/2
✓ Branch 3 taken 353793 times.
✗ Branch 4 not taken.
353793 std::sort(ptOfBoundaryElem.begin(),ptOfBoundaryElem.end());
511
512 // add the element in the unordered_map
513
1/2
✓ Branch 1 taken 353793 times.
✗ Branch 2 not taken.
353793 bndElements[ptOfBoundaryElem] = numEltTot + numEltVol;
514
515 // increment the counters
516 353793 ++numEltTot;
517 353793 ++numEltPerType[eltType];
518 }
519 } else { // If current element IS NOT a boundary element
520 // for each local element with the current label
521 for (felInt iel = 0; iel < numElemsPerRef; iel++) {
522
523 // Clear local variables
524 max = 0;
525 indice_max = 0;
526 for ( int j = 0; j < numPart; j++)
527 numDofPerProcs[j] = 0;
528
529 // for each unknown of the linear system
530 for (auto itUnknown = listUnknown.begin(); itUnknown < listUnknown.end(); itUnknown++) {
531 iUnknown = *itUnknown;
532
533 // get the global id of the current element
534 idVar = m_listUnknown.idVariable(iUnknown);
535 m_supportDofUnknown[iUnknown].getIdElementSupport(eltType, numEltPerType[eltType], vecSupport);
536
537 // loop over all the support elements
538 for (std::size_t it = 0; it < vecSupport.size(); it++) {
539 // get the id of the support
540 ielSupportDof = vecSupport[it];
541
542 // for each support dof of the current element
543 for (felInt iSupport = 0; iSupport < m_supportDofUnknown[iUnknown].getNumSupportDof(ielSupportDof); iSupport++) {
544
545 // for each components of the current unknown
546 for (std::size_t iComp = 0; iComp < m_listVariable[idVar].numComponent(); iComp++) {
547 // get the global id of the dof and increased numDofPerProcs
548 m_dof.loc2glob(ielSupportDof, iSupport, idVar, iComp, idDof);
549 ++numDofPerProcs[m_dofPart[idDof]];
550 }
551 }
552 }
553 }
554
555 // Find the rank of the process that owns the most dof in the current element.
556 for (int j = 0; j < numPart; j++) {
557 if (max < numDofPerProcs[j]) {
558 max = numDofPerProcs[j];
559 indice_max = j;
560 }
561 }
562
563 // Fill m_eltPart
564 m_eltPart[iMesh][numEltTot + numEltVol] = indice_max;
565
566 ++numEltTot;
567 ++numEltPerType[eltType];
568 }
569 }
570 }
571 }
572
573 // Initialization for the domain elements
574 524 felInt numPointPerBdEle = 0;
575 524 felInt numBdElePerDomainElem = 0;
576 524 numEltTot = 0;
577
578 // For each domain element type
579
2/2
✓ Branch 1 taken 524 times.
✓ Branch 2 taken 524 times.
1048 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
580 524 eltType = bagElementTypeDomain[i];
581
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 ptOfElem.resize(GeometricMeshRegion::m_numPointsPerElt[eltType]);
582 524 numBdElePerDomainElem = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second->numBdEle();
583
584 // for each label where the current element type can be found
585
2/2
✓ Branch 8 taken 538 times.
✓ Branch 9 taken 524 times.
1062 for(auto itRef = m_mesh[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_mesh[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
586 538 numElemsPerRef = itRef->second.second;
587
588 // for each local element with the current label
589
2/2
✓ Branch 0 taken 3297334 times.
✓ Branch 1 taken 538 times.
3297872 for (felInt iel = 0; iel < numElemsPerRef; iel++) {
590
591 // Clear local variables
592 3297334 max = 0;
593 3297334 indice_max = 0;
594
2/2
✓ Branch 0 taken 12552374 times.
✓ Branch 1 taken 3297334 times.
15849708 for ( int j = 0; j < numPart; j++)
595 12552374 numDofPerProcs[j] = 0;
596
597 // for each unknown of the linear system
598
2/2
✓ Branch 4 taken 4561606 times.
✓ Branch 5 taken 3297334 times.
7858940 for (auto itUnknown = listUnknown.begin(); itUnknown < listUnknown.end(); itUnknown++) {
599 4561606 iUnknown = *itUnknown;
600
601 // get the global id of the current element
602 4561606 idVar = m_listUnknown.idVariable(iUnknown);
603
1/2
✓ Branch 2 taken 4561606 times.
✗ Branch 3 not taken.
4561606 supportDofUnknown(iUnknown).getIdElementSupport(eltType, numEltPerType[eltType], vecSupport);
604
605 // loop over all the support elements
606
2/2
✓ Branch 1 taken 4562524 times.
✓ Branch 2 taken 4561606 times.
9124130 for (std::size_t it = 0; it < vecSupport.size(); it++) {
607 // get the id of the support
608 4562524 ielSupportDof = vecSupport[it];
609
610 // for each support dof of the current element
611
2/2
✓ Branch 2 taken 18141698 times.
✓ Branch 3 taken 4562524 times.
22704222 for (felInt iSupport = 0; iSupport < supportDofUnknown(iUnknown).getNumSupportDof(ielSupportDof); iSupport++) {
612
613 // for each components of the current unknown
614
2/2
✓ Branch 2 taken 39086605 times.
✓ Branch 3 taken 18141698 times.
57228303 for (std::size_t iComp = 0; iComp < m_listVariable[idVar].numComponent(); iComp++) {
615 // get the global id of the dof and increased numDofPerProcs
616
1/2
✓ Branch 1 taken 39086605 times.
✗ Branch 2 not taken.
39086605 m_dof.loc2glob(ielSupportDof, iSupport, idVar, iComp, idDof);
617 39086605 ++numDofPerProcs[m_dofPart[idDof]];
618 }
619 }
620 }
621 }
622
623 // Find the rank of the process that owns the most dof in the current element.
624
2/2
✓ Branch 0 taken 12552374 times.
✓ Branch 1 taken 3297334 times.
15849708 for (int j = 0; j < numPart; j++) {
625
2/2
✓ Branch 0 taken 3405460 times.
✓ Branch 1 taken 9146914 times.
12552374 if (max < numDofPerProcs[j]) {
626 3405460 max = numDofPerProcs[j];
627 3405460 indice_max = j;
628 }
629 }
630
631 // Fill m_eltPart
632 3297334 m_eltPart[iMesh][numEltTot] = indice_max;
633
634 // find the boundary element of this domain element
635 // get the current volume element
636
1/2
✓ Branch 3 taken 3297334 times.
✗ Branch 4 not taken.
3297334 m_mesh[iMesh]->getOneElement(eltType, numEltPerType[eltType], ptOfElem, 0);
637
638 // for each of the faces
639
2/2
✓ Branch 0 taken 12703550 times.
✓ Branch 1 taken 3297334 times.
16000884 for (felInt iBdEle = 0; iBdEle < numBdElePerDomainElem; iBdEle++) {
640
1/2
✓ Branch 2 taken 12703550 times.
✗ Branch 3 not taken.
12703550 numPointPerBdEle = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second->numPointPerBdEle( iBdEle );
641
642 // save the IDs of the points of the face
643
1/2
✓ Branch 1 taken 12703550 times.
✗ Branch 2 not taken.
12703550 ptOfBoundaryElem.resize( numPointPerBdEle, 0);
644
2/2
✓ Branch 0 taken 36729116 times.
✓ Branch 1 taken 12703550 times.
49432666 for (int iptBdEle = 0; iptBdEle < numPointPerBdEle; ++iptBdEle ) {
645 // global point numbering of the local face points:
646
1/2
✓ Branch 2 taken 36729116 times.
✗ Branch 3 not taken.
36729116 ptOfBoundaryElem[iptBdEle] = ptOfElem[ GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second->pointOfBdEle(iBdEle, iptBdEle) ];
647 }
648
649 // sort them
650
1/2
✓ Branch 3 taken 12703550 times.
✗ Branch 4 not taken.
12703550 std::sort(ptOfBoundaryElem.begin(), ptOfBoundaryElem.end());
651
652 // if they are the same IDs as of those of the surface element then assign the proc of the volume element to the surface element
653
1/2
✓ Branch 1 taken 12703550 times.
✗ Branch 2 not taken.
12703550 const auto bndEltIt = bndElements.find(ptOfBoundaryElem);
654
2/2
✓ Branch 2 taken 355244 times.
✓ Branch 3 taken 12348306 times.
12703550 if(bndEltIt != bndElements.end()) {
655 // this face is one of the boundary elements
656 355244 m_eltPart[iMesh][bndEltIt->second] = indice_max;
657 }
658 }
659
660 // Increment the counter
661 3297334 ++numEltTot;
662 3297334 ++numEltPerType[eltType];
663 }
664 }
665 }
666 }
667 1048 }
668
669 /***********************************************************************************/
670 /***********************************************************************************/
671 /*
672 void LinearProblem::partitionDof_Petsc( idx_t numPart, int rankPart, MPI_Comm comm)
673 {
674 // ================= Temporary to get rid of warning about usuned arguments...
675 std::cerr << "BEWARE: two arguments of this function were commented" << std::endl;
676 IGNORE_UNUSED_ARGUMENT(numPart);
677 IGNORE_UNUSED_ARGUMENT(comm);
678 // =================
679
680 PetscMatrix Adj;
681 MatPartitioning part;
682 IS is, isg;
683 AO ao;
684 PetscInt* ia;
685 PetscInt* ja;
686 const std::size_t iaSize = m_dof.pattern().numRows() + 1;
687 const std::size_t jaSize = m_dof.pattern().numNonzeros();
688 PetscMalloc(iaSize*sizeof(PetscInt),&ia);
689 PetscMalloc(jaSize*sizeof(PetscInt),&ja);
690
691 for (std::size_t i=0; i<iaSize; ++i)
692 ia[i] = m_dof.pattern().rowPointer(i);
693 for (std::size_t i=0; i<jaSize; ++i)
694 ja[i] = m_dof.pattern().columnIndex(i);
695
696 const PetscInt m = iaSize-1;
697 const PetscInt n = m_dof.numDof();
698
699 std::cout << " ===== Processor: " << rankPart << std::endl;
700 std::cout << " m = " << m << std::endl;
701 std::cout << " n = " << n << std::endl;
702 for (std::size_t i=0; i<iaSize; ++i)
703 std::cout << ia[i] << " " ;
704 std::cout << std::endl;
705 for (std::size_t i=0; i<jaSize; ++i)
706 std::cout << ja[i] << " " ;
707 std::cout << std::endl;
708
709 Adj.createMPIAdj(MpiInfo::petscComm(),m,n,ia,ja,FELISCE_PETSC_NULLPTR);
710 MatPartitioningCreate(MpiInfo::petscComm(),&part);
711 MatPartitioningSetAdjacency(part,Adj.toPetsc());
712 MatPartitioningSetFromOptions(part);
713 MatPartitioningApply(part,&is);
714 ISPartitioningToNumbering(is,&isg);
715 ISView(is,PETSC_VIEWER_STDOUT_WORLD);
716 ISView(isg,PETSC_VIEWER_STDOUT_WORLD);
717
718 AOCreateBasicIS(isg,FELISCE_PETSC_NULLPTR,&ao);
719 // AOView(ao,PETSC_VIEWER_STDOUT_WORLD);
720
721 MatPartitioningDestroy(&part);
722 Adj.destroy();
723
724 PetscFinalize();
725 //exit(1);
726 }
727 */
728 /***********************************************************************************/
729 /***********************************************************************************/
730
731 524 void LinearProblem::setLocalMeshAndSupportDofMesh(int rankPart)
732 {
733
1/2
✓ Branch 3 taken 524 times.
✗ Branch 4 not taken.
524 std::vector<std::vector<felInt> > loc2GlobElem(m_mesh.size());
734
735
1/2
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
524 m_meshLocal.resize(m_mesh.size());
736
1/2
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
524 m_mappingElem.resize(m_mesh.size());
737
1/2
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
524 m_mappingElemSupportPerUnknown.resize(m_listUnknown.size());
738
739
2/2
✓ Branch 1 taken 547 times.
✓ Branch 2 taken 524 times.
1071 for (std::size_t iMesh = 0; iMesh < m_mesh.size(); ++iMesh){
740 /*
741 * Set local mesh and local to global mapping for elements
742 */
743 // Set the local mesh and fill the local to global mapping for the support elements (loc2GlobSupportElem)
744
2/2
✓ Branch 2 taken 525 times.
✓ Branch 3 taken 22 times.
547 if ( !m_meshLocal[iMesh] )
745
1/2
✓ Branch 1 taken 525 times.
✗ Branch 2 not taken.
525 m_meshLocal[iMesh] = felisce::make_shared<GeometricMeshRegion>();
746
1/2
✓ Branch 7 taken 547 times.
✗ Branch 8 not taken.
547 m_meshLocal[iMesh]->setLocalMesh(*m_mesh[iMesh], m_eltPart[iMesh], rankPart, loc2GlobElem[iMesh]);
747
748 // Create the local to global mapping for the elements
749
2/4
✓ Branch 6 taken 547 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 547 times.
✗ Branch 10 not taken.
547 IS_LOCAL_TO_GLOBAL_MAPPING_MACRO(MpiInfo::petscComm(), 1, loc2GlobElem[iMesh].size(), loc2GlobElem[iMesh].data(), PETSC_COPY_VALUES, &m_mappingElem[iMesh]);
750 }
751 524 m_initMappingElem = true;
752
753 /*
754 * Set local support dof mesh and local to global mapping for support elements
755 */
756 // for each unknown, create the support dof and put them in m_supportDofUnknownLocal
757
2/2
✓ Branch 1 taken 761 times.
✓ Branch 2 taken 524 times.
1285 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ ) {
758 761 const int idVar = m_listUnknown.idVariable(iUnknown);
759 761 const int iMesh = m_listVariable[idVar].idMesh();
760
761 // create the local supportdofmeshes
762
1/2
✓ Branch 2 taken 761 times.
✗ Branch 3 not taken.
761 std::vector<felInt> loc2GlobElemSupport = loc2GlobElem[iMesh];
763
1/2
✓ Branch 4 taken 761 times.
✗ Branch 5 not taken.
761 SupportDofMesh supportDofMesh(m_listVariable[idVar], m_meshLocal[iMesh], loc2GlobElemSupport, m_supportDofUnknown[iUnknown]);
764
765 // save them in m_supportDofUnknownLocal
766
1/2
✓ Branch 1 taken 761 times.
✗ Branch 2 not taken.
761 m_supportDofUnknownLocal.push_back(supportDofMesh);
767
768 // Create the mapping
769
4/6
✓ Branch 1 taken 761 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 761 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 29 times.
✓ Branch 7 taken 732 times.
761 if(FelisceParam::instance(this->instanceIndex()).duplicateSupportDof) {
770
1/2
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
29 m_mappingElemSupportPerUnknown[iUnknown] = new ISLocalToGlobalMapping;
771
2/4
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 29 times.
✗ Branch 8 not taken.
29 IS_LOCAL_TO_GLOBAL_MAPPING_MACRO(MpiInfo::petscComm(), 1, loc2GlobElemSupport.size(), loc2GlobElemSupport.data(), PETSC_COPY_VALUES, m_mappingElemSupportPerUnknown[iUnknown]);
772 } else
773 732 m_mappingElemSupportPerUnknown[iUnknown] = &m_mappingElem[iMesh];
774 761 }
775 524 m_initMappingElemSupport = true;
776
777 /*
778 * Print info on the local mesh and supportDofMeshes
779 */
780
2/2
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 265 times.
524 if (m_verbosity) {
781 // print the local mesh
782
2/2
✓ Branch 1 taken 259 times.
✓ Branch 2 taken 259 times.
518 for (std::size_t iMesh = 0; iMesh < m_mesh.size(); ++iMesh) {
783
2/4
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 259 times.
✗ Branch 5 not taken.
259 PetscPrintf(MpiInfo::petscComm(), "\n/================== Local mesh %lu ================/\n", iMesh);
784
3/4
✓ Branch 1 taken 1232 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 973 times.
✓ Branch 4 taken 259 times.
1232 for ( int k = 0; k < MpiInfo::numProc(); ++k ) {
785
3/4
✓ Branch 1 taken 973 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 259 times.
✓ Branch 4 taken 714 times.
973 if( MpiInfo::rankProc() == k )
786
1/2
✓ Branch 3 taken 259 times.
✗ Branch 4 not taken.
259 m_meshLocal[iMesh]->print(m_verbosity);
787 }
788 }
789
790 // print the local supportDofMesh for each unknown
791
2/2
✓ Branch 1 taken 428 times.
✓ Branch 2 taken 259 times.
687 for(std::size_t iUnknown=0; iUnknown<m_listUnknown.size(); iUnknown++) {
792 428 int idVar = m_listUnknown.idVariable(iUnknown);
793
3/6
✓ Branch 2 taken 428 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 428 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 428 times.
✗ Branch 10 not taken.
428 PetscPrintf(MpiInfo::petscComm(), "\n/=========== Local support dof mesh associate to the unknown: <%s> ===========/\n", m_listVariable[idVar].name().c_str());
794
1/2
✓ Branch 2 taken 428 times.
✗ Branch 3 not taken.
428 m_supportDofUnknownLocal[iUnknown].print(m_verbosity);
795 }
796 }
797 524 }
798
799 /***********************************************************************************/
800 /***********************************************************************************/
801
802 524 void LinearProblem::allocateMatrix()
803 {
804 // Create the local to global mapping for support dofs.
805
1/2
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
524 std::vector<felInt> loc2Glob(m_numDofLocal,0);
806 524 felInt cptDof= 0;
807
2/2
✓ Branch 1 taken 2604159 times.
✓ Branch 2 taken 524 times.
2604683 for ( felInt iDof = 0; iDof < m_dof.numDof(); iDof++) {
808
3/4
✓ Branch 2 taken 2604159 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 750372 times.
✓ Branch 5 taken 1853787 times.
2604159 if ( m_dofPart[iDof] == MpiInfo::rankProc() ) {
809 750372 loc2Glob[cptDof] = iDof;
810 750372 cptDof++;
811 }
812 }
813
814 // Global to local mapping on nodes
815
2/4
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 524 times.
✗ Branch 6 not taken.
524 IS_LOCAL_TO_GLOBAL_MAPPING_MACRO(MpiInfo::petscComm(), 1, m_numDofLocal, &loc2Glob[0], PETSC_COPY_VALUES, &m_mappingNodes);
816 // ISLocalToGlobalMappingView( m_mappingNodes, PETSC_VIEWER_STDOUT_WORLD);
817 524 m_initMappingNodes = true;
818
819 // Allocation of the matrix
820
3/4
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 500 times.
✓ Branch 4 taken 24 times.
524 if ( MpiInfo::numProc() > 1 ) {
821 // In parallel
822 // copy to not change the pattern
823
1/2
✓ Branch 3 taken 500 times.
✗ Branch 4 not taken.
500 std::vector<felInt> jCSR = m_dof.pattern().columnIndices();
824
1/2
✓ Branch 4 taken 500 times.
✗ Branch 5 not taken.
500 AOApplicationToPetsc(m_ao, m_dof.pattern().numNonzeros(), jCSR.data());
825
826
2/2
✓ Branch 1 taken 1006 times.
✓ Branch 2 taken 500 times.
1506 for (std::size_t ii = 0; ii < m_matrices.size(); ii++) {
827
2/4
✓ Branch 4 taken 1006 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1006 times.
✗ Branch 8 not taken.
1006 m_matrices[ii].createAIJ(MpiInfo::petscComm(), m_numDofLocal, m_numDofLocal, m_dof.numDof(), m_dof.numDof(), 0, FELISCE_PETSC_NULLPTR, 0, FELISCE_PETSC_NULLPTR);
828
1/2
✓ Branch 6 taken 1006 times.
✗ Branch 7 not taken.
1006 m_matrices[ii].mpiAIJSetPreallocationCSR(m_dof.pattern().rowPointer().data(), jCSR.data(), nullptr);
829
1/2
✓ Branch 2 taken 1006 times.
✗ Branch 3 not taken.
1006 m_matrices[ii].setOption(MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE);
830
1/2
✓ Branch 2 taken 1006 times.
✗ Branch 3 not taken.
1006 m_matrices[ii].setFromOptions();
831 }
832
833 // Create rhs (parallel vector)
834
2/2
✓ Branch 1 taken 738 times.
✓ Branch 2 taken 500 times.
1238 for (std::size_t index = 0, Nvector = m_vectors.size(); index < Nvector; ++index)
835
2/4
✓ Branch 3 taken 738 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 738 times.
✗ Branch 7 not taken.
738 m_vectors[index].createMPI(MpiInfo::petscComm(), m_numDofLocal, m_dof.numDof());
836 500 } else {
837 // In serial
838 24 const std::size_t numRows = m_dof.pattern().numRows();
839
1/2
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 std::vector<felInt> nnz(numRows);
840
2/2
✓ Branch 0 taken 72395 times.
✓ Branch 1 taken 24 times.
72419 for ( felInt idof = 0; idof < static_cast<felInt>(numRows); idof++) {
841
1/2
✓ Branch 2 taken 72395 times.
✗ Branch 3 not taken.
72395 nnz[idof] = m_dof.pattern().numNonzerosInRow(idof);
842 }
843
844
2/2
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 24 times.
57 for (std::size_t ii = 0; ii < m_matrices.size(); ii++) {
845
2/4
✓ Branch 3 taken 33 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 33 times.
✗ Branch 7 not taken.
33 m_matrices[ii].createSeqAIJ(MpiInfo::petscComm(), numRows, numRows, 0, &nnz[0]);
846
1/2
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
33 m_matrices[ii].setOption(MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE);
847
1/2
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
33 m_matrices[ii].setFromOptions();
848 }
849
850
2/2
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 24 times.
57 for (std::size_t index = 0, Nvector = m_vectors.size(); index < Nvector; ++index) {
851
2/4
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 33 times.
✗ Branch 6 not taken.
33 m_vectors[index].create(MpiInfo::petscComm());
852
1/2
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
33 m_vectors[index].setSizes(numRows,numRows);
853
1/2
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
33 m_vectors[index].setFromOptions();
854 }
855 24 }
856
857 524 m_numDof = m_dof.numDof();
858
859 // Create the vector solution
860
2/4
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 524 times.
✗ Branch 5 not taken.
524 m_sol.createMPI(MpiInfo::petscComm(), m_numDofLocal, m_numDof);
861
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 m_sol.set( 0.);
862
863
2/2
✓ Branch 2 taken 283 times.
✓ Branch 3 taken 241 times.
524 if (this->snesInterface().doUseSNES()) {
864
2/4
✓ Branch 1 taken 283 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 283 times.
✗ Branch 5 not taken.
283 m_evaluationState.createMPI(MpiInfo::petscComm(), m_numDofLocal, m_numDof);
865
1/2
✓ Branch 1 taken 283 times.
✗ Branch 2 not taken.
283 m_evaluationState.zeroEntries();
866 }
867
868
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 allocateSequentialSolution();
869 524 m_buildSystem = true;
870
871 // Get the local size of all process
872
2/4
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 524 times.
✗ Branch 6 not taken.
524 std::vector<felInt> localSizeOfVector( MpiInfo::numProc(), 0);
873
874 524 felInt sizeLocal = 0;
875
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 m_sol.getLocalSize(&sizeLocal);
876
877
2/4
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 524 times.
✗ Branch 6 not taken.
524 MPI_Allgather(&sizeLocal, 1, MPI_INT, localSizeOfVector.data(), 1, MPI_INT, MpiInfo::petscComm());
878
879 // For each unknown, create a local to global mapping to map the local id of dof to their global id in the petsc ordering.
880 524 felInt numDofPreviousUnknowns = 0;
881 524 felInt idGlobalDof = 0;
882 524 felInt sumPreviousSizeLocal = 0;
883 524 std::vector<felInt> loc2GlobPerUnknown;
884 felInt sizeIdDof;
885
1/2
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
524 m_mappingIdLocalDofPerUnknownToIdGlobalDofPetsc.resize(m_listUnknown.size());
886
887
3/4
✓ Branch 1 taken 1254 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 730 times.
✓ Branch 4 taken 524 times.
1254 for ( int iProc = 0; iProc < MpiInfo::rankProc(); iProc++)
888 730 sumPreviousSizeLocal += localSizeOfVector[iProc];
889
890
2/2
✓ Branch 1 taken 761 times.
✓ Branch 2 taken 524 times.
1285 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ )
891 761 m_numDofLocalUnknown[iUnknown] = 0;
892
893
2/2
✓ Branch 1 taken 761 times.
✓ Branch 2 taken 524 times.
1285 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ ) {
894
2/2
✓ Branch 1 taken 2604159 times.
✓ Branch 2 taken 761 times.
2604920 for ( felInt iDof = 0; iDof < m_numDofUnknown[iUnknown]; iDof++) {
895 2604159 idGlobalDof = numDofPreviousUnknowns + iDof;
896
1/2
✓ Branch 1 taken 2604159 times.
✗ Branch 2 not taken.
2604159 AOApplicationToPetsc(m_ao, 1, &idGlobalDof);
897
7/8
✓ Branch 0 taken 1674096 times.
✓ Branch 1 taken 930063 times.
✓ Branch 3 taken 1674096 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 750372 times.
✓ Branch 7 taken 923724 times.
✓ Branch 8 taken 750372 times.
✓ Branch 9 taken 1853787 times.
2604159 if ( (sumPreviousSizeLocal <= idGlobalDof) && (idGlobalDof < localSizeOfVector[MpiInfo::rankProc()]+sumPreviousSizeLocal) ) {
898 750372 m_numDofLocalUnknown[iUnknown]++;
899
1/2
✓ Branch 1 taken 750372 times.
✗ Branch 2 not taken.
750372 loc2GlobPerUnknown.push_back(idGlobalDof);
900 }
901 }
902 761 numDofPreviousUnknowns += m_numDofUnknown[iUnknown];
903 761 sizeIdDof = loc2GlobPerUnknown.size();
904
2/4
✓ Branch 3 taken 761 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 761 times.
✗ Branch 7 not taken.
761 IS_LOCAL_TO_GLOBAL_MAPPING_MACRO(MpiInfo::petscComm(), 1, sizeIdDof, loc2GlobPerUnknown.data(), PETSC_COPY_VALUES, &m_mappingIdLocalDofPerUnknownToIdGlobalDofPetsc[iUnknown] );
905 // ISLocalToGlobalMappingView(m_mappingIdLocalDofPerUnknownToIdGlobalDofPetsc[iUnknown], PETSC_VIEWER_STDOUT_WORLD);
906 761 loc2GlobPerUnknown.clear();
907 }
908 524 m_initMappingLocalFelisceToGlobalPetsc = true;
909 524 }
910
911 /***********************************************************************************/
912 /***********************************************************************************/
913
914 524 void LinearProblem::allocateSequentialSolution()
915 {
916 524 m_seqSol.createSeq(PETSC_COMM_SELF, m_numDof);
917
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 m_seqSol.set(0.);
918 524 m_seqSolAllocated = true;
919
920
2/2
✓ Branch 2 taken 283 times.
✓ Branch 3 taken 241 times.
524 if ( this->snesInterface().doUseSNES() ) {
921 283 m_seqEvaluationState.createSeq(PETSC_COMM_SELF, m_numDof);
922
1/2
✓ Branch 1 taken 283 times.
✗ Branch 2 not taken.
283 m_seqEvaluationState.set( 0.);
923 }
924 524 }
925
926 /***********************************************************************************/
927 /***********************************************************************************/
928
929 13518 void LinearProblem::assembleMatrixRHS(int rank, FlagMatrixRHS flagMatrixRHS)
930 {
931 IGNORE_UNUSED_RANK;
932 ElementType eltType; // Geometric element type in the mesh.
933 13518 int numPointPerElt = 0; // Number of points per geometric element.
934 13518 int currentLabel = 0; // Number of label domain.
935 13518 felInt numEltPerLabel = 0; // Number of element for one label and one eltType.
936
937 // Retrieve instance
938
2/4
✓ Branch 1 taken 13518 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13518 times.
✗ Branch 5 not taken.
13518 auto& r_instance = FelisceParam::instance(this->instanceIndex());
939
940 // Get the timer
941 13518 auto& r_timer = r_instance.timer;
942
943
8/12
✓ Branch 1 taken 12566 times.
✓ Branch 2 taken 952 times.
✓ Branch 4 taken 3568 times.
✓ Branch 5 taken 8998 times.
✓ Branch 9 taken 13518 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 13518 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 13518 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 13518 times.
✗ Branch 19 not taken.
13518 r_timer.Start("LinearProblem" + std::to_string(m_identifier_problem) + "::assembleMatrixRHS", m_fstransient ? (m_fstransient->total_number_iterations > 0 ? m_fstransient->total_number_iterations : m_fstransient->iteration ) : 0);
944
945 // TODO: The solution should maybe be modified in here in order to impose the natural BC for NL problems.
946
947 // Use to define a "global" numbering of element in the mesh.
948 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
949
2/2
✓ Branch 0 taken 337950 times.
✓ Branch 1 taken 13518 times.
351468 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
950 337950 eltType = (ElementType)ityp;
951 337950 numElement[eltType] = 0;
952 }
953
954 // Contains points of the current element.
955 13518 std::vector<Point*> elemPoint;
956
957 // Contains ids of point of the current element.
958 13518 std::vector<felInt> elemIdPoint;
959
960 // Use to get element number in support dof mesh ordering.
961 felInt ielSupportDof;
962
963 // Assembly loop.
964 // First loop on geometric type.
965 13518 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[m_currentMesh]->bagElementTypeDomain();
966
2/2
✓ Branch 1 taken 12764 times.
✓ Branch 2 taken 13518 times.
26282 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
967 12764 eltType = bagElementTypeDomain[i];
968
969 // Resize array.
970 12764 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
971
1/2
✓ Branch 1 taken 12764 times.
✗ Branch 2 not taken.
12764 elemPoint.resize(numPointPerElt, nullptr);
972
1/2
✓ Branch 1 taken 12764 times.
✗ Branch 2 not taken.
12764 elemIdPoint.resize(numPointPerElt, 0);
973
974 // Define all current finite element use in the problem from data
975 // file cnfiguration and allocate 1 and elemVec (question: virtual ?).
976
1/2
✓ Branch 1 taken 12764 times.
✗ Branch 2 not taken.
12764 defineFiniteElement(eltType);
977
978 // Element matrix and vector initialisation
979
1/2
✓ Branch 1 taken 12764 times.
✗ Branch 2 not taken.
12764 initElementArray();
980
981 // Allocate array use for assemble with petsc.
982
1/2
✓ Branch 1 taken 12764 times.
✗ Branch 2 not taken.
12764 allocateArrayForAssembleMatrixRHS(flagMatrixRHS);
983
984 // Virtual function use in derived problem to allocate elemenField necessary.
985
1/2
✓ Branch 1 taken 12764 times.
✗ Branch 2 not taken.
12764 initPerElementType(eltType, flagMatrixRHS);
986
987 // Used by user to add specific term (source term for example with elemField).
988
1/2
✓ Branch 1 taken 12764 times.
✗ Branch 2 not taken.
12764 userElementInit();
989
990 // Second loop on region of the mesh.
991
2/2
✓ Branch 8 taken 12794 times.
✓ Branch 9 taken 12764 times.
25558 for(auto itRef = m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
992 12794 currentLabel = itRef->first;
993 12794 numEltPerLabel = itRef->second.second;
994
995 // By default this virtual defines variable m_currentLabel: (m_currentLabel=label).
996 // We can switch on label region with that and define some parameters.
997
1/2
✓ Branch 1 taken 12794 times.
✗ Branch 2 not taken.
12794 initPerDomain(currentLabel, flagMatrixRHS);
998
999 // Third loop on element in the region with the type: eltType. ("real" loop on elements).
1000
2/2
✓ Branch 0 taken 26243229 times.
✓ Branch 1 taken 12794 times.
26256023 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
1001
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 26243229 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
26243229 FEL_ASSERT(!m_elementVector.empty());
1002
1003
2/2
✓ Branch 0 taken 26106349 times.
✓ Branch 1 taken 136880 times.
26243229 if(!r_instance.duplicateSupportDof) {
1004 // Return each id of point of the element and coordinate in two arrays: elemPoint and elemIdPoint.
1005
1/2
✓ Branch 1 taken 26106349 times.
✗ Branch 2 not taken.
26106349 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, &ielSupportDof);
1006
1007 // Clear elementary matrices
1008
2/2
✓ Branch 1 taken 51731821 times.
✓ Branch 2 taken 26106349 times.
77838170 for (std::size_t j = 0, size = m_matrices.size(); j < size ; j++)
1009
1/2
✓ Branch 3 taken 51731821 times.
✗ Branch 4 not taken.
51731821 m_elementMat[j]->zero();
1010
1011 // Clear elementary std::vector.
1012
2/2
✓ Branch 1 taken 26706716 times.
✓ Branch 2 taken 26106349 times.
52813065 for (std::size_t j = 0, size = m_vectors.size(); j < size ; j++)
1013
1/2
✓ Branch 3 taken 26706716 times.
✗ Branch 4 not taken.
26706716 m_elementVector[j]->zero();
1014
1015 // Function call in derived problem to compute specific operators of the problem (Heat, N-S,...).
1016
3/4
✓ Branch 0 taken 24603269 times.
✓ Branch 1 taken 1503080 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24603269 times.
26106349 if (r_instance.NSequationFlag == 1 && r_instance.characteristicMethod != 0) {
1017 // Use method of characteristics for N-S
1018 computeElementArrayCharact(elemPoint, elemIdPoint, ielSupportDof, eltType, numElement[eltType], flagMatrixRHS);
1019 } else{
1020
1/2
✓ Branch 1 taken 26106349 times.
✗ Branch 2 not taken.
26106349 computeElementArray(elemPoint, elemIdPoint, ielSupportDof, flagMatrixRHS);
1021 }
1022
1023 // Compute specific term of users.
1024
1/2
✓ Branch 1 taken 26106349 times.
✗ Branch 2 not taken.
26106349 userElementCompute(elemPoint, elemIdPoint, ielSupportDof, flagMatrixRHS);
1025
1026 // Add values of elemMat in the global matrix: m_matrices[0].
1027
1/2
✓ Branch 1 taken 26106349 times.
✗ Branch 2 not taken.
26106349 setValueMatrixRHS(ielSupportDof, ielSupportDof, flagMatrixRHS);
1028 } else {
1029
1/2
✓ Branch 1 taken 136880 times.
✗ Branch 2 not taken.
136880 m_duplicateSupportDofAssemblyLoop(rank, eltType, numElement[eltType], elemPoint, elemIdPoint, flagMatrixRHS);
1030 }
1031
1032 26243229 numElement[eltType]++;
1033 }
1034 }
1035 // Desallocate array use for assemble with petsc.
1036
1/2
✓ Branch 1 taken 12764 times.
✗ Branch 2 not taken.
12764 desallocateArrayForAssembleMatrixRHS(flagMatrixRHS);
1037 }
1038
1039 // Assembly loop for LumpedModelBC in case of NS model with implicit implementation
1040
6/6
✓ Branch 1 taken 432 times.
✓ Branch 2 taken 13086 times.
✓ Branch 4 taken 176 times.
✓ Branch 5 taken 256 times.
✓ Branch 6 taken 176 times.
✓ Branch 7 taken 13342 times.
13518 if (r_instance.lumpedModelBCLabel.size()>0 && r_instance.model == "NS") {
1041
2/2
✓ Branch 1 taken 352 times.
✓ Branch 2 taken 176 times.
528 for (std::size_t iLabel = 0; iLabel < r_instance.lumpedModelBCLabel.size(); iLabel++) {
1042
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 352 times.
352 if(r_instance.lumpedModelBCAlgo[iLabel] == 2) // use a Enum here... 08/13 VM TODO
1043 assembleMatrixImplLumpedModelBC(rank, iLabel);
1044 }
1045 }
1046
1047 // Assembly / addition of crack term block of the solid model if it exists in the problem
1048
1/2
✓ Branch 1 taken 13518 times.
✗ Branch 2 not taken.
13518 derivedAssembleMatrixCrackModel(rank);
1049
1050
4/4
✓ Branch 0 taken 1916 times.
✓ Branch 1 taken 11602 times.
✓ Branch 2 taken 548 times.
✓ Branch 3 taken 1368 times.
13518 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix) {
1051 // Real assembling of the matrix manage by PETsC.
1052
2/2
✓ Branch 1 taken 27696 times.
✓ Branch 2 taken 12150 times.
39846 for (std::size_t i = 0; i < m_matrices.size(); i++)
1053
1/2
✓ Branch 2 taken 27696 times.
✗ Branch 3 not taken.
27696 m_matrices[i].assembly(MAT_FINAL_ASSEMBLY);
1054 }
1055 // Call with high level of verbose to print matrix in matlab format.
1056
2/4
✓ Branch 2 taken 13518 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13518 times.
✗ Branch 6 not taken.
13518 writeMatrixForMatlab(m_verbosity);
1057
1058
4/4
✓ Branch 0 taken 1916 times.
✓ Branch 1 taken 11602 times.
✓ Branch 2 taken 1368 times.
✓ Branch 3 taken 548 times.
13518 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs) {
1059 // Real assembling of the right hand side (RHS).
1060
2/2
✓ Branch 1 taken 17610 times.
✓ Branch 2 taken 12970 times.
30580 for (std::size_t i = 0; i < m_vectors.size(); i++) {
1061
1/2
✓ Branch 2 taken 17610 times.
✗ Branch 3 not taken.
17610 m_vectors[i].assembly();
1062 }
1063 }
1064
1065 // Call with high level of verbose to print right hand side in matlab format.
1066
2/4
✓ Branch 2 taken 13518 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13518 times.
✗ Branch 6 not taken.
13518 writeRHSForMatlab(m_verbosity);
1067
1068
8/12
✓ Branch 1 taken 12566 times.
✓ Branch 2 taken 952 times.
✓ Branch 4 taken 3568 times.
✓ Branch 5 taken 8998 times.
✓ Branch 9 taken 13518 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 13518 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 13518 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 13518 times.
✗ Branch 19 not taken.
13518 r_timer.Stop("LinearProblem" + std::to_string(m_identifier_problem) + "::assembleMatrixRHS", m_fstransient ? (m_fstransient->total_number_iterations > 0 ? m_fstransient->total_number_iterations : m_fstransient->iteration ) : 0);
1069 13518 }
1070
1071 /***********************************************************************************/
1072 /***********************************************************************************/
1073
1074 12908 void LinearProblem::defineFiniteElement(const ElementType& eltType)
1075 {
1076 12908 m_listCurrentFiniteElement.clear();
1077
1078 std::size_t idMesh;
1079 const RefElement *refEle;
1080 const GeoElement *geoEle;
1081 12908 int typeOfFiniteElement = 0;
1082 CurrentFiniteElement* fe;
1083 12908 geoEle = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second;
1084
2/2
✓ Branch 1 taken 22074 times.
✓ Branch 2 taken 12908 times.
34982 for ( std::size_t iVar = 0, size = m_listVariable.size(); iVar < size; iVar++) {
1085 22074 idMesh = m_listVariable[iVar].idMesh();
1086 22074 typeOfFiniteElement = m_listVariable[iVar].finiteElementType(); // 0 = linear, 1 = quadratic, 2 = bubble
1087 22074 refEle = geoEle->defineFiniteEle(eltType,typeOfFiniteElement, *m_meshLocal[idMesh]); // TODO D.C. here mesh is used just to check i the current element is a bd elt... maybe a simple flag is better...
1088
1/2
✓ Branch 4 taken 22074 times.
✗ Branch 5 not taken.
22074 fe = new CurrentFiniteElement(*refEle,*geoEle,m_listVariable[iVar].getDegreeOfExactness());
1089
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22074 times.
22074 FEL_ASSERT(fe);
1090 22074 m_listCurrentFiniteElement.add(fe);
1091 }
1092 12908 }
1093
1094 /***********************************************************************************/
1095 /***********************************************************************************/
1096
1097 void LinearProblem::defineFiniteElement(const std::vector<ElementType>& eltType)
1098 {
1099 m_listCurrentFiniteElement.clear();
1100
1101 //Initialisation of Finite Element current problem
1102 std::size_t idMesh;
1103 const RefElement *refEle;
1104 const GeoElement *geoEle;
1105 int typeOfFiniteElement = 0;
1106 CurrentFiniteElement* fe;
1107 for ( std::size_t iVar = 0, size = m_listVariable.size(); iVar < size; iVar++) {
1108 idMesh = m_listVariable[iVar].idMesh();
1109 geoEle = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType[iVar]].second;
1110 typeOfFiniteElement = m_listVariable[iVar].finiteElementType(); // 0 = linear, 1 = quadratic, 2 = bubble
1111 refEle = geoEle->defineFiniteEle(eltType[iVar],typeOfFiniteElement, *m_meshLocal[idMesh]);
1112 fe = new CurrentFiniteElement(*refEle,*geoEle,m_listVariable[iVar].getDegreeOfExactness());
1113 FEL_ASSERT(fe);
1114 m_listCurrentFiniteElement.add(fe);
1115 }
1116 }
1117
1118 /***********************************************************************************/
1119 /***********************************************************************************/
1120
1121 12908 void LinearProblem::initElementArray(const bool initTranspose)
1122 {
1123 12908 m_elementMat.clear();
1124 12908 m_elementMatT.clear();
1125 12908 m_elementVector.clear();
1126
1127 int idVar;
1128 12908 std::size_t rowSize = m_listUnknown.getUnknownsRows().size();
1129 12908 std::size_t colSize = m_listUnknown.getUnknownsCols().size();
1130
2/4
✓ Branch 2 taken 12908 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 12908 times.
✗ Branch 7 not taken.
25816 std::vector<std::size_t> numberCmp1(rowSize), numberCmp2(colSize);
1131
2/4
✓ Branch 2 taken 12908 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 12908 times.
✗ Branch 7 not taken.
25816 std::vector<const CurBaseFiniteElement*> finiteElt1(rowSize), finiteElt2(colSize);
1132
1133
2/2
✓ Branch 0 taken 17386 times.
✓ Branch 1 taken 12908 times.
30294 for (std::size_t n = 0; n < rowSize; n++){
1134 17386 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsRows()[n]);
1135 17386 numberCmp1[n] = m_listVariable[idVar].numComponent();
1136 17386 finiteElt1[n] = m_listCurrentFiniteElement[idVar];
1137 }
1138
1139
2/2
✓ Branch 0 taken 17386 times.
✓ Branch 1 taken 12908 times.
30294 for (std::size_t n = 0; n < colSize; n++){
1140 17386 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsCols()[n]);
1141 17386 numberCmp2[n] = m_listVariable[idVar].numComponent();
1142 17386 finiteElt2[n] = m_listCurrentFiniteElement[idVar];
1143 }
1144
1145
2/2
✓ Branch 1 taken 17523 times.
✓ Branch 2 taken 12908 times.
30431 for (std::size_t i = 0; i < m_vectors.size(); i++)
1146
2/4
✓ Branch 1 taken 17523 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17523 times.
✗ Branch 5 not taken.
17523 m_elementVector.push_back(felisce::make_shared<ElementVector>(finiteElt1, numberCmp1));
1147
1148
2/2
✓ Branch 1 taken 28937 times.
✓ Branch 2 taken 12908 times.
41845 for (std::size_t i = 0; i < m_matrices.size(); i++)
1149
2/4
✓ Branch 1 taken 28937 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28937 times.
✗ Branch 5 not taken.
28937 m_elementMat.push_back(felisce::make_shared<ElementMatrix>(finiteElt1, numberCmp1, finiteElt2, numberCmp2));
1150
1151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12908 times.
12908 if (initTranspose)
1152 for (std::size_t i = 0; i < m_matrices.size(); i++)
1153 m_elementMatT.push_back(felisce::make_shared<ElementMatrix>(finiteElt2, numberCmp2, finiteElt1, numberCmp1));
1154 12908 }
1155
1156 /***********************************************************************************/
1157 /***********************************************************************************/
1158
1159 12834 void LinearProblem::initPerDomain(int label, FlagMatrixRHS /*flagMatrixRHS*/)
1160 {
1161 12834 m_currentLabel = label;
1162 12834 }
1163
1164 /***********************************************************************************/
1165 /***********************************************************************************/
1166
1167 1672403 void LinearProblem::setElemPoint(ElementType& eltType, felInt iel, std::vector<Point*>& elemPoint, std::vector<felInt>& elemIdPoint, std::vector<felInt>& vectorSupport)
1168 {
1169 // We assume that the support elements are the same for all the unknown.
1170 1672403 const int iUnknown = m_listUnknown.getUnknownsRows()[0]; // TODO D.C.
1171 1672403 const int iMesh = m_meshUnknown[iUnknown];
1172 1672403 m_supportDofUnknownLocal[iUnknown].getIdElementSupport(eltType, iel, vectorSupport);
1173 1672403 ISLocalToGlobalMappingApply(*m_mappingElemSupportPerUnknown[iUnknown], vectorSupport.size(), vectorSupport.data(), vectorSupport.data());
1174
1175 1672403 const int numPointsPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
1176 1672403 m_meshLocal[iMesh]->getOneElement(eltType, iel, elemIdPoint, 0);
1177
2/2
✓ Branch 0 taken 4863266 times.
✓ Branch 1 taken 1672403 times.
6535669 for (int iPoint = 0; iPoint < numPointsPerElt; iPoint++) {
1178 4863266 elemPoint[iPoint] = &m_meshLocal[iMesh]->listPoints()[elemIdPoint[iPoint]];
1179 }
1180 1672403 }
1181
1182 /***********************************************************************************/
1183 /***********************************************************************************/
1184
1185 26106373 void LinearProblem::setElemPoint(ElementType& eltType, felInt iel, std::vector<Point*>& elemPoint,
1186 std::vector<felInt>& elemIdPoint, felInt* ielSupportDof)
1187 {
1188 // We assume that the support elements are the same for all the unknown defined on the current mesh.
1189 26106373 const int iUnknown = m_listUnknown.getUnknownsRows()[0]; // TODO D.C.
1190 26106373 const int iMesh = m_meshUnknown[iUnknown];
1191 26106373 m_supportDofUnknownLocal[iUnknown].getIdElementSupport(eltType, iel, *ielSupportDof);
1192 26106373 ISLocalToGlobalMappingApply(*m_mappingElemSupportPerUnknown[iUnknown], 1, ielSupportDof, ielSupportDof);
1193
1194 26106373 const int numPointsPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
1195 26106373 m_meshLocal[iMesh]->getOneElement(eltType, iel, elemIdPoint, 0);
1196
2/2
✓ Branch 0 taken 102348195 times.
✓ Branch 1 taken 26106373 times.
128454568 for (int iPoint = 0; iPoint < numPointsPerElt; iPoint++) {
1197 102348195 elemPoint[iPoint] = &m_meshLocal[iMesh]->listPoints()[elemIdPoint[iPoint]];
1198 }
1199 26106373 }
1200
1201 /***********************************************************************************/
1202 /***********************************************************************************/
1203
1204 27895297 void LinearProblem::setValueMatrixRHS(const std::vector<felInt>& ielSupportDof1, const std::vector<felInt>& ielSupportDof2, FlagMatrixRHS flagMatrixRHS, bool buildMatT)
1205 {
1206
4/8
✓ Branch 0 taken 19322011 times.
✓ Branch 1 taken 8573286 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19322011 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 27895297 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
27895297 FEL_ASSERT( flagMatrixRHS != FlagMatrixRHS::only_rhs ? !m_elementMat.empty() : true );
1207
4/10
✓ Branch 0 taken 19322011 times.
✓ Branch 1 taken 8573286 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19322011 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 27895297 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
27895297 FEL_ASSERT( flagMatrixRHS != FlagMatrixRHS::only_rhs && buildMatT ? !m_elementMatT.empty() : true );
1208
4/8
✓ Branch 0 taken 21431071 times.
✓ Branch 1 taken 6464226 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21431071 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 27895297 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
27895297 FEL_ASSERT( flagMatrixRHS != FlagMatrixRHS::only_matrix ? !m_elementVector.empty() : true );
1209
3/6
✓ Branch 0 taken 19322011 times.
✓ Branch 1 taken 8573286 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19322011 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
27895297 FEL_ASSERT( flagMatrixRHS != FlagMatrixRHS::only_rhs ? m_GposColumn != nullptr : true );
1210
3/6
✓ Branch 0 taken 21431071 times.
✓ Branch 1 taken 6464226 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 21431071 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
27895297 FEL_ASSERT( flagMatrixRHS != FlagMatrixRHS::only_matrix ? m_GposLine != nullptr : true );
1211
1212 27895297 const felInt numDofTotal1 = m_elementMat[0]->mat().size1();
1213 27895297 const felInt numDofTotal2 = m_elementMat[0]->mat().size2();
1214 int idVar;
1215 felInt cptGpos;
1216 27895297 std::vector<felInt> loc2globTmp;
1217
1218 // Build the loc2glob map m_GposLine for the first support element (i.e. for the rows of the matrix or RHS)
1219 27895297 cptGpos = 0;
1220
2/2
✓ Branch 2 taken 44920541 times.
✓ Branch 3 taken 27895297 times.
72815838 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsRows().size(); iUnknown++) {
1221 44920541 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsRows()[iUnknown]);
1222
1/2
✓ Branch 6 taken 44920541 times.
✗ Branch 7 not taken.
44920541 m_dof.loc2glob(ielSupportDof1[iUnknown], m_listCurrentFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
1223
1224
2/2
✓ Branch 1 taken 367058941 times.
✓ Branch 2 taken 44920541 times.
411979482 for(std::size_t i=0; i<loc2globTmp.size(); ++i)
1225 367058941 m_GposLine[cptGpos++] = loc2globTmp[i];
1226 }
1227
1228
3/4
✓ Branch 0 taken 12857785 times.
✓ Branch 1 taken 6464226 times.
✓ Branch 2 taken 8573286 times.
✗ Branch 3 not taken.
27895297 switch (flagMatrixRHS) {
1229 12857785 case FlagMatrixRHS::matrix_and_rhs :
1230
1231 // Build the loc2glob map m_GposColumn for the second support element (i.e. for the columns of the matrix)
1232
7/10
✓ Branch 1 taken 12857785 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12854953 times.
✓ Branch 4 taken 2832 times.
✓ Branch 8 taken 12854953 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 12854953 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 12854953 times.
✓ Branch 13 taken 2832 times.
12857785 if(ielSupportDof1 == ielSupportDof2 && m_listUnknown.getUnknownsRows() == m_listUnknown.getUnknownsCols() ) {
1233 // if the two support element are the same (always the case unless we have duplicated support element)
1234
2/2
✓ Branch 0 taken 156239227 times.
✓ Branch 1 taken 12854953 times.
169094180 for ( felInt i = 0; i < numDofTotal1; ++i )
1235 156239227 m_GposColumn[i] = m_GposLine[i];
1236 } else {
1237 // if they are different, compute it.
1238 2832 cptGpos = 0;
1239
2/2
✓ Branch 2 taken 5664 times.
✓ Branch 3 taken 2832 times.
8496 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsCols().size(); iUnknown++) {
1240 5664 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsCols()[iUnknown]);
1241
1/2
✓ Branch 6 taken 5664 times.
✗ Branch 7 not taken.
5664 m_dof.loc2glob(ielSupportDof2[iUnknown], m_listCurrentFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
1242
1243
2/2
✓ Branch 1 taken 25488 times.
✓ Branch 2 taken 5664 times.
31152 for(std::size_t i=0; i<loc2globTmp.size(); ++i)
1244 25488 m_GposColumn[cptGpos++] = loc2globTmp[i];
1245 }
1246 }
1247
1248 // Set values
1249
1/2
✓ Branch 1 taken 12857785 times.
✗ Branch 2 not taken.
12857785 AOApplicationToPetsc(m_ao,numDofTotal1,m_GposLine);
1250
1/2
✓ Branch 1 taken 12857785 times.
✗ Branch 2 not taken.
12857785 AOApplicationToPetsc(m_ao,numDofTotal2,m_GposColumn);
1251
2/2
✓ Branch 1 taken 23419617 times.
✓ Branch 2 taken 12857785 times.
36277402 for (std::size_t i = 0; i < m_matrices.size(); i++) // TODO D.C. why for every matrix?????
1252
1/2
✓ Branch 7 taken 23419617 times.
✗ Branch 8 not taken.
23419617 m_matrices[i].setValues(numDofTotal1,m_GposLine,numDofTotal2,m_GposColumn,m_elementMat[i]->mat().data().begin(),ADD_VALUES);
1253
3/6
✓ Branch 1 taken 12857785 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12857785 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12857785 times.
12857785 for (std::size_t i = 0; i < m_matrices.size() && buildMatT; i++)
1254 m_matrices[i].setValues(numDofTotal2,m_GposColumn,numDofTotal1,m_GposLine,m_elementMatT[i]->mat().data().begin(),ADD_VALUES);
1255
2/2
✓ Branch 1 taken 13458152 times.
✓ Branch 2 taken 12857785 times.
26315937 for (std::size_t i = 0; i < m_vectors.size(); i++)
1256
1/2
✓ Branch 7 taken 13458152 times.
✗ Branch 8 not taken.
13458152 m_vectors[i].setValues(numDofTotal1,m_GposLine, m_elementVector[i]->vec().data().begin(), ADD_VALUES);
1257 12857785 break;
1258
1259 6464226 case FlagMatrixRHS::only_matrix :
1260
1261 // Build the loc2glob map m_GposColumn for the second support element (i.e. for the columns of the matrix)
1262
7/10
✓ Branch 1 taken 6464226 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5640316 times.
✓ Branch 4 taken 823910 times.
✓ Branch 8 taken 5640316 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 5640316 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5640316 times.
✓ Branch 13 taken 823910 times.
6464226 if(ielSupportDof1 == ielSupportDof2 && m_listUnknown.getUnknownsRows() == m_listUnknown.getUnknownsCols() ) {
1263 // if the two support element are the same (always the case unless we have duplicated support element)
1264
2/2
✓ Branch 0 taken 79524068 times.
✓ Branch 1 taken 5640316 times.
85164384 for ( felInt i = 0; i < numDofTotal1; ++i )
1265 79524068 m_GposColumn[i] = m_GposLine[i];
1266 } else {
1267 // if they are different, compute it.
1268 823910 cptGpos = 0;
1269
2/2
✓ Branch 2 taken 1655280 times.
✓ Branch 3 taken 823910 times.
2479190 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsCols().size(); iUnknown++) {
1270 1655280 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsCols()[iUnknown]);
1271
1/2
✓ Branch 6 taken 1655280 times.
✗ Branch 7 not taken.
1655280 m_dof.loc2glob(ielSupportDof2[iUnknown], m_listCurrentFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
1272
1273
2/2
✓ Branch 1 taken 7446540 times.
✓ Branch 2 taken 1655280 times.
9101820 for(std::size_t i=0; i<loc2globTmp.size(); ++i)
1274 7446540 m_GposColumn[cptGpos++] = loc2globTmp[i];
1275 }
1276 }
1277
1278 // Set values
1279
1/2
✓ Branch 1 taken 6464226 times.
✗ Branch 2 not taken.
6464226 AOApplicationToPetsc(m_ao,numDofTotal1,m_GposLine);
1280
1/2
✓ Branch 1 taken 6464226 times.
✗ Branch 2 not taken.
6464226 AOApplicationToPetsc(m_ao,numDofTotal2,m_GposColumn);
1281
2/2
✓ Branch 1 taken 11657476 times.
✓ Branch 2 taken 6464226 times.
18121702 for (std::size_t i = 0; i < m_matrices.size(); i++)
1282
1/2
✓ Branch 7 taken 11657476 times.
✗ Branch 8 not taken.
11657476 m_matrices[i].setValues(numDofTotal1,m_GposLine,numDofTotal2,m_GposColumn,m_elementMat[i]->mat().data().begin(),ADD_VALUES);
1283
3/6
✓ Branch 1 taken 6464226 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 6464226 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6464226 times.
6464226 for (std::size_t i = 0; i < m_matrices.size() && buildMatT; i++)
1284 m_matrices[i].setValues(numDofTotal2,m_GposColumn,numDofTotal1,m_GposLine,m_elementMatT[i]->mat().data().begin(),ADD_VALUES);
1285 6464226 break;
1286
1287 8573286 case FlagMatrixRHS::only_rhs :
1288
1289 // Set values
1290
1/2
✓ Branch 1 taken 8573286 times.
✗ Branch 2 not taken.
8573286 AOApplicationToPetsc(m_ao,numDofTotal1,m_GposLine);
1291
2/2
✓ Branch 1 taken 8573286 times.
✓ Branch 2 taken 8573286 times.
17146572 for (std::size_t i = 0; i < m_vectors.size(); i++)
1292
1/2
✓ Branch 7 taken 8573286 times.
✗ Branch 8 not taken.
8573286 m_vectors[i].setValues(numDofTotal1,m_GposLine,m_elementVector[i]->vec().data().begin(),ADD_VALUES);
1293 8573286 break;
1294
1295 default:
1296 FEL_ERROR("Problem with Matrix/RHS flag.");
1297 }
1298 27895297 }
1299
1300 /***********************************************************************************/
1301 /***********************************************************************************/
1302
1303 27895297 void LinearProblem::setValueMatrixRHS(const felInt ielSupportDof1, const felInt ielSupportDof2, FlagMatrixRHS flagMatrixRHS, bool buildMatT)
1304 {
1305
1/2
✓ Branch 4 taken 27895297 times.
✗ Branch 5 not taken.
27895297 std::vector<felInt> vecIelSupportDof1(m_listUnknown.getUnknownsRows().size(), ielSupportDof1);
1306
1/2
✓ Branch 4 taken 27895297 times.
✗ Branch 5 not taken.
27895297 std::vector<felInt> vecIelSupportDof2(m_listUnknown.getUnknownsCols().size(), ielSupportDof2);
1307
1/2
✓ Branch 1 taken 27895297 times.
✗ Branch 2 not taken.
27895297 setValueMatrixRHS(vecIelSupportDof1, vecIelSupportDof2, flagMatrixRHS, buildMatT);
1308 27895297 }
1309
1310 /***********************************************************************************/
1311 /***********************************************************************************/
1312
1313 void LinearProblem::setValueCustomMatrix(const std::vector<felInt>& ielSupportDof1, const std::vector<felInt>& ielSupportDof2, PetscMatrix& mat, bool buildMatT)
1314 {
1315 FEL_ASSERT( !m_elementMat.empty() );
1316 FEL_ASSERT( buildMatT ? !m_elementMatT.empty() : true );
1317 FEL_ASSERT( m_GposColumn );
1318 FEL_ASSERT( m_GposLine );
1319
1320 const felInt numDofTotal1 = m_elementMat[0]->mat().size1();
1321 const felInt numDofTotal2 = m_elementMat[0]->mat().size2();
1322 int idVar;
1323 felInt cptGpos;
1324 std::vector<felInt> loc2globTmp;
1325
1326 // Build the loc2glob map m_GposLine for the first support element (i.e. for the rows of the matrix or RHS)
1327 cptGpos = 0;
1328 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsRows().size(); iUnknown++) {
1329 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsRows()[iUnknown]);
1330 m_dof.loc2glob(ielSupportDof1[iUnknown], m_listCurrentFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
1331
1332 for(std::size_t i=0; i<loc2globTmp.size(); ++i)
1333 m_GposLine[cptGpos++] = loc2globTmp[i];
1334 }
1335
1336 // Build the loc2glob map m_GposColumn for the second support element (i.e. for the columns of the matrix)
1337 if(ielSupportDof1 == ielSupportDof2 && m_listUnknown.getUnknownsRows() == m_listUnknown.getUnknownsCols() ) {
1338 // if the two support element are the same (always the case unless we have duplicated support element) just copy the first one
1339 for ( felInt i = 0; i < numDofTotal1; ++i )
1340 m_GposColumn[i] = m_GposLine[i];
1341 } else {
1342 // if they are different, compute it.
1343 cptGpos = 0;
1344 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsCols().size(); iUnknown++) {
1345 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsCols()[iUnknown]);
1346 m_dof.loc2glob(ielSupportDof2[iUnknown], m_listCurrentFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
1347
1348 for(std::size_t i=0; i<loc2globTmp.size(); ++i)
1349 m_GposColumn[cptGpos++] = loc2globTmp[i];
1350 }
1351 }
1352
1353 AOApplicationToPetsc(m_ao,numDofTotal1,m_GposLine);
1354 AOApplicationToPetsc(m_ao,numDofTotal2,m_GposColumn);
1355 mat.setValues(numDofTotal1,m_GposLine,numDofTotal2,m_GposColumn,m_elementMat[0]->mat().data().begin(),ADD_VALUES);
1356 if (buildMatT)
1357 mat.setValues(numDofTotal2,m_GposColumn,numDofTotal1,m_GposLine,m_elementMatT[0]->mat().data().begin(),ADD_VALUES);
1358 }
1359
1360 /***********************************************************************************/
1361 /***********************************************************************************/
1362
1363 void LinearProblem::setValueCustomMatrix(const felInt ielSupportDof1, const felInt ielSupportDof2, PetscMatrix& mat, bool buildMatT)
1364 {
1365 std::vector<felInt> vecIelSupportDof1(m_listUnknown.getUnknownsRows().size(), ielSupportDof1);
1366 std::vector<felInt> vecIelSupportDof2(m_listUnknown.getUnknownsCols().size(), ielSupportDof2);
1367 setValueCustomMatrix(vecIelSupportDof1, vecIelSupportDof2, mat, buildMatT);
1368 }
1369
1370 /***********************************************************************************/
1371 /***********************************************************************************/
1372
1373 void LinearProblem::setValueCustomVector(const std::vector<felInt>& ielSupportDof1, InsertMode mode, PetscVector& vec)
1374 {
1375 FEL_ASSERT(!m_elementVector.empty());
1376 FEL_ASSERT( m_GposLine );
1377
1378 const felInt numDofTotal = m_elementVector[0]->vec().size();
1379 int idVar;
1380 felInt cptGpos;
1381 std::vector<felInt> loc2globTmp;
1382
1383 // Build the loc2glob map m_GposLine for the first support element (i.e. RHS)
1384 cptGpos = 0;
1385 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsRows().size(); iUnknown++) {
1386 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsRows()[iUnknown]);
1387 m_dof.loc2glob(ielSupportDof1[iUnknown], m_listCurrentFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
1388
1389 for(std::size_t i=0; i<loc2globTmp.size(); ++i)
1390 m_GposLine[cptGpos++] = loc2globTmp[i];
1391 }
1392
1393 // Set values
1394 AOApplicationToPetsc(m_ao,numDofTotal,m_GposLine);
1395 vec.setValues(numDofTotal,m_GposLine,m_elementVector[0]->vec().data().begin(),mode);
1396 }
1397
1398 /***********************************************************************************/
1399 /***********************************************************************************/
1400
1401 void LinearProblem::setValueCustomVector(const felInt ielSupportDof1, InsertMode mode, PetscVector& vec)
1402 {
1403 std::vector<felInt> vecIelSupportDof1(m_listUnknown.getUnknownsRows().size(), ielSupportDof1);
1404 setValueCustomVector(vecIelSupportDof1, mode, vec);
1405 }
1406
1407 /***********************************************************************************/
1408 /***********************************************************************************/
1409
1410 12908 void LinearProblem::allocateArrayForAssembleMatrixRHS(FlagMatrixRHS flagMatrixRHS)
1411 {
1412 12908 felInt numDofTotalL = 0;
1413 int idVar;
1414
2/2
✓ Branch 2 taken 17386 times.
✓ Branch 3 taken 12908 times.
30294 for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsRows().size(); iUnknown++) {
1415 17386 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsRows()[iUnknown]);
1416 17386 numDofTotalL += m_listCurrentFiniteElement[idVar]->numDof()*m_listVariable[idVar].numComponent();
1417 }
1418
1/2
✓ Branch 0 taken 12908 times.
✗ Branch 1 not taken.
12908 m_GposLine = new felInt[numDofTotalL];
1419
1420
4/4
✓ Branch 0 taken 2060 times.
✓ Branch 1 taken 10848 times.
✓ Branch 2 taken 692 times.
✓ Branch 3 taken 1368 times.
12908 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix) {
1421 11540 felInt numDofTotalC = 0;
1422
2/2
✓ Branch 2 taken 15098 times.
✓ Branch 3 taken 11540 times.
26638 for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsCols().size(); iUnknown++) {
1423 15098 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsCols()[iUnknown]);
1424 15098 numDofTotalC += m_listCurrentFiniteElement[idVar]->numDof()*m_listVariable[idVar].numComponent();
1425 }
1426
1/2
✓ Branch 0 taken 11540 times.
✗ Branch 1 not taken.
11540 m_GposColumn = new felInt[numDofTotalC];
1427 }
1428 12908 }
1429
1430 /***********************************************************************************/
1431 /***********************************************************************************/
1432
1433 32871 void LinearProblem::desallocateArrayForAssembleMatrixRHS(FlagMatrixRHS /*flagMatrixRHS*/)
1434 {
1435
1/2
✓ Branch 0 taken 32871 times.
✗ Branch 1 not taken.
32871 if ( m_GposLine ) {
1436
1/2
✓ Branch 0 taken 32871 times.
✗ Branch 1 not taken.
32871 delete [] m_GposLine;
1437 32871 m_GposLine = nullptr;
1438 }
1439
1440
2/2
✓ Branch 0 taken 30979 times.
✓ Branch 1 taken 1892 times.
32871 if ( m_GposColumn ) {
1441
1/2
✓ Branch 0 taken 30979 times.
✗ Branch 1 not taken.
30979 delete [] m_GposColumn;
1442 30979 m_GposColumn = nullptr;
1443 }
1444 32871 }
1445
1446 /***********************************************************************************/
1447 /***********************************************************************************/
1448
1449 14343 void LinearProblem::assembleMatrixRHSBD(int rank, FlagMatrixRHS flagMatrixRHS)
1450 {
1451 IGNORE_UNUSED_RANK;
1452 ElementType eltType; //geometric element type in the mesh.
1453 14343 int numPointPerElt = 0; //number of points per geometric element.
1454 14343 int currentLabel = 0; //number of label domain.
1455 14343 felInt numEltPerLabel = 0; //number of element for one label and one eltType.
1456
1457 // use to define a "global" numbering of element in the mesh.
1458 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
1459
2/2
✓ Branch 0 taken 358575 times.
✓ Branch 1 taken 14343 times.
372918 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
1460 358575 eltType = (ElementType)ityp;
1461 358575 numElement[eltType] = 0;
1462 }
1463
1464 // contains points of the current element.
1465 14343 std::vector<Point*> elemPoint;
1466
1467 // contains normals of the current element.
1468 14343 std::vector<Point*> elemNormal;
1469
1470 // contains tangents of the current element.
1471 14343 std::vector <std::vector<Point*> > elemTangent;
1472
1473 // contains ids of point of the current element.
1474 14343 std::vector<felInt> elemIdPoint;
1475
1476 // contains the ids of the support elements of a mesh element
1477 14343 std::vector<felInt> vectorIdSupport;
1478
1479 // use to get element number in support dof mesh ordering.
1480 felInt ielSupportDof;
1481
1482 //Assembly loop.
1483 //First loop on geometric type.
1484 14343 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[m_currentMesh]->bagElementTypeDomain();
1485
2/2
✓ Branch 1 taken 14339 times.
✓ Branch 2 taken 14343 times.
28682 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
1486 14339 eltType = bagElementTypeDomain[i];
1487
1488 // Resize array.
1489 14339 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
1490
1/2
✓ Branch 1 taken 14339 times.
✗ Branch 2 not taken.
14339 elemPoint.resize(numPointPerElt, nullptr);
1491
1/2
✓ Branch 1 taken 14339 times.
✗ Branch 2 not taken.
14339 elemIdPoint.resize(numPointPerElt, 0);
1492
2/2
✓ Branch 3 taken 5520 times.
✓ Branch 4 taken 8819 times.
14339 if (m_meshLocal[m_currentMesh]->createNormalTangent()) {
1493
1/2
✓ Branch 1 taken 5520 times.
✗ Branch 2 not taken.
5520 elemNormal.resize(numPointPerElt, nullptr);
1494
1/2
✓ Branch 4 taken 5520 times.
✗ Branch 5 not taken.
5520 elemTangent.resize(m_mesh[m_currentMesh]->domainDim());
1495
2/2
✓ Branch 1 taken 9902 times.
✓ Branch 2 taken 5520 times.
15422 for (std::size_t i=0 ; i<elemTangent.size() ; i++)
1496
1/2
✓ Branch 2 taken 9902 times.
✗ Branch 3 not taken.
9902 elemTangent[i].resize(numPointPerElt, nullptr);
1497 }
1498
1499 //define all current finite element use in the problem from data
1500 //file configuration and allocate elemMat and elemVec (question: virtual ?).
1501
1/2
✓ Branch 1 taken 14339 times.
✗ Branch 2 not taken.
14339 defineCurvilinearFiniteElement(eltType);
1502
1503 // Element matrix and std::vector initialisation
1504
1/2
✓ Branch 1 taken 14339 times.
✗ Branch 2 not taken.
14339 initElementArrayBD();
1505
1506 // Allocate array use for assemble with petsc.
1507
1/2
✓ Branch 1 taken 14339 times.
✗ Branch 2 not taken.
14339 allocateArrayForAssembleMatrixRHSBD(flagMatrixRHS);
1508
1509 // Virtual function use in derived problem to allocate elemenField necessary.
1510
1/2
✓ Branch 1 taken 14339 times.
✗ Branch 2 not taken.
14339 initPerElementTypeBD(eltType, flagMatrixRHS);
1511
1512 // Use by user to add specific term (term source for example with elemField).
1513
1/2
✓ Branch 1 taken 14339 times.
✗ Branch 2 not taken.
14339 userElementInitBD();
1514
1515 // Second loop on region of the mesh.
1516
2/2
✓ Branch 8 taken 14790 times.
✓ Branch 9 taken 14339 times.
29129 for(auto itRef = m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
1517 14790 currentLabel = itRef->first;
1518 14790 numEltPerLabel = itRef->second.second;
1519
1520 //By default this virtual define variable m_currentLabel: (m_currentLabel=label).
1521 //We can switch on label region with that and define some parameters.
1522
1/2
✓ Branch 1 taken 14790 times.
✗ Branch 2 not taken.
14790 initPerDomainBD(currentLabel, flagMatrixRHS);
1523
1524 //Third loop on element in the region with the type: eltType. ("real" loop on elements).
1525
2/2
✓ Branch 0 taken 330618 times.
✓ Branch 1 taken 14790 times.
345408 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
1526 // return each id of point of the element and coordinate in two arrays: elemPoint and elemIdPoint.
1527
1528
2/2
✓ Branch 3 taken 273949 times.
✓ Branch 4 taken 56669 times.
330618 if (m_meshLocal[m_currentMesh]->createNormalTangent()) {
1529
1/2
✓ Branch 1 taken 273949 times.
✗ Branch 2 not taken.
273949 setElemPointNormalTangent(eltType, numElement[eltType], elemPoint, elemNormal, elemTangent, elemIdPoint, vectorIdSupport);
1530 } else {
1531
1/2
✓ Branch 1 taken 56669 times.
✗ Branch 2 not taken.
56669 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
1532 }
1533 // Loop over all the support elements
1534
2/2
✓ Branch 1 taken 330618 times.
✓ Branch 2 taken 330618 times.
661236 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
1535 // get the id of the support
1536 330618 ielSupportDof = vectorIdSupport[it];
1537
1538 // clear elementary matrix.
1539
2/2
✓ Branch 1 taken 656196 times.
✓ Branch 2 taken 330618 times.
986814 for (std::size_t j = 0; j < m_matrices.size(); j++)
1540
1/2
✓ Branch 3 taken 656196 times.
✗ Branch 4 not taken.
656196 m_elementMatBD[j]->zero();
1541
1542 // clear elementary vector.
1543
2/2
✓ Branch 1 taken 656196 times.
✓ Branch 2 taken 330618 times.
986814 for (std::size_t j = 0; j < m_vectors.size(); j++)
1544
1/2
✓ Branch 3 taken 656196 times.
✗ Branch 4 not taken.
656196 m_elementVectorBD[j]->zero();
1545
1546 // function call in derived problem to compute specific operators of the problem (Heat, N-S,...).
1547
2/2
✓ Branch 3 taken 273949 times.
✓ Branch 4 taken 56669 times.
330618 if (m_meshLocal[m_currentMesh]->createNormalTangent())
1548
1/2
✓ Branch 1 taken 273949 times.
✗ Branch 2 not taken.
273949 computeElementArrayBD(elemPoint, elemIdPoint, elemNormal, elemTangent, ielSupportDof, flagMatrixRHS);
1549 else
1550
1/2
✓ Branch 1 taken 56669 times.
✗ Branch 2 not taken.
56669 computeElementArrayBD(elemPoint, elemIdPoint, ielSupportDof,flagMatrixRHS);
1551
1552 // compute specific term of users.
1553
1/2
✓ Branch 1 taken 330618 times.
✗ Branch 2 not taken.
330618 userElementComputeBD(elemPoint, elemIdPoint, ielSupportDof);
1554
1555 // add values of elemMat in the global matrix: m_matrices[0].
1556
1/2
✓ Branch 1 taken 330618 times.
✗ Branch 2 not taken.
330618 setValueMatrixRHSBD(ielSupportDof, ielSupportDof, flagMatrixRHS);
1557 }
1558 330618 numElement[eltType]++;
1559 }
1560 }
1561 // Deallocate array use for assemble with petsc.
1562
1/2
✓ Branch 1 taken 14339 times.
✗ Branch 2 not taken.
14339 desallocateArrayForAssembleMatrixRHS(flagMatrixRHS);
1563 }
1564
1565 // Assembly / addition of crack term block of the solid model if it exists in the problem
1566
1/2
✓ Branch 1 taken 14343 times.
✗ Branch 2 not taken.
14343 derivedAssembleMatrixCrackModel(rank);
1567
1568
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14343 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14343 if( (flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs) || (flagMatrixRHS == FlagMatrixRHS::only_matrix)) {
1569 //real assembling of the matrix manage by PETsC.
1570
2/2
✓ Branch 1 taken 28246 times.
✓ Branch 2 taken 14343 times.
42589 for (std::size_t i = 0; i < m_matrices.size(); i++)
1571
1/2
✓ Branch 2 taken 28246 times.
✗ Branch 3 not taken.
28246 m_matrices[i].assembly(MAT_FINAL_ASSEMBLY);
1572 }
1573 // Call with high level of verbose to print matrix in matlab format.
1574
2/4
✓ Branch 2 taken 14343 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 14343 times.
✗ Branch 6 not taken.
14343 writeMatrixForMatlab(m_verbosity);
1575
1576
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14343 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14343 if( (flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs) || (flagMatrixRHS == FlagMatrixRHS::only_rhs)) {
1577 // Real assembling of the right hand side (RHS).
1578
2/2
✓ Branch 1 taken 28246 times.
✓ Branch 2 taken 14343 times.
42589 for (std::size_t index = 0; index < m_vectors.size(); index++) {
1579
1/2
✓ Branch 2 taken 28246 times.
✗ Branch 3 not taken.
28246 m_vectors[index].assembly();
1580 }
1581 }
1582 //call with high level of verbose to print right hand side in matlab format.
1583
2/4
✓ Branch 2 taken 14343 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 14343 times.
✗ Branch 6 not taken.
14343 writeRHSForMatlab(m_verbosity);
1584 14343 }
1585
1586 /***********************************************************************************/
1587 /***********************************************************************************/
1588
1589 21235 void LinearProblem::defineCurvilinearFiniteElement(const ElementType& eltType)
1590 {
1591 21235 m_listCurvilinearFiniteElement.clear();
1592
1593 //Initialisation of Finite Element curvlinear problem
1594 std::size_t idMesh;
1595 const RefElement *refEle;
1596 const GeoElement *geoEle;
1597 21235 int typeOfFiniteElement = 0;
1598 CurvilinearFiniteElement* fe;
1599 21235 geoEle = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second;
1600
2/2
✓ Branch 1 taken 41290 times.
✓ Branch 2 taken 21235 times.
62525 for ( std::size_t iVar = 0; iVar < m_listVariable.size(); iVar++) {
1601 41290 idMesh = m_listVariable[iVar].idMesh();
1602 41290 typeOfFiniteElement = m_listVariable[iVar].finiteElementType();
1603 41290 refEle = geoEle->defineFiniteEle(eltType,typeOfFiniteElement, *m_meshLocal[idMesh]); // TODO D.C. i don't like that it requires the mesh, maybe a flag ifBfElt is better...
1604
1/2
✓ Branch 4 taken 41290 times.
✗ Branch 5 not taken.
41290 fe = new CurvilinearFiniteElement(*refEle,*geoEle,m_listVariable[iVar].degreeOfExactness());
1605
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41290 times.
41290 FEL_ASSERT(fe);
1606
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 41290 times.
41290 if( FelisceParam::instance(this->instanceIndex()).flipNormal )
1607 fe->m_sign = -1;
1608 41290 m_listCurvilinearFiniteElement.add(fe);
1609 }
1610 21235 }
1611
1612 /***********************************************************************************/
1613 /***********************************************************************************/
1614
1615 void LinearProblem::defineCurvilinearFiniteElement(const std::vector<ElementType>& eltType)
1616 {
1617 m_listCurvilinearFiniteElement.clear();
1618
1619 //Initialisation of Finite Element curvlinear problem
1620 std::size_t idMesh;
1621 const RefElement *refEle;
1622 const GeoElement *geoEle;
1623 int typeOfFiniteElement = 0;
1624 CurvilinearFiniteElement* fe;
1625 for ( std::size_t iVar = 0; iVar < m_listVariable.size(); iVar++) {
1626 idMesh = m_listVariable[iVar].idMesh();
1627 geoEle = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType[iVar]].second;
1628 typeOfFiniteElement = m_listVariable[iVar].finiteElementType();
1629 refEle = geoEle->defineFiniteEle(eltType[iVar],typeOfFiniteElement, *m_meshLocal[idMesh]);
1630 fe = new CurvilinearFiniteElement(*refEle,*geoEle,m_listVariable[iVar].degreeOfExactness());
1631 FEL_ASSERT(fe);
1632 if( FelisceParam::instance(this->instanceIndex()).flipNormal )
1633 fe->m_sign = -1;
1634 m_listCurvilinearFiniteElement.add(fe);
1635 }
1636 }
1637
1638 /***********************************************************************************/
1639 /***********************************************************************************/
1640
1641 5488 void LinearProblem::defineCurrentFiniteElementWithBd(const ElementType& eltType)
1642 {
1643 5488 m_listCurrentFiniteElementWithBd.clear();
1644
1645 //Initialisation of Finite Element current with boundary problem
1646 std::size_t idMesh;
1647 const RefElement *refEle;
1648 const GeoElement *geoEle;
1649 5488 int typeOfFiniteElement = 0;
1650 CurrentFiniteElementWithBd* fewbd;
1651 5488 geoEle = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second;
1652
2/2
✓ Branch 1 taken 9968 times.
✓ Branch 2 taken 5488 times.
15456 for ( std::size_t iVar = 0; iVar < m_listVariable.size(); iVar++) {
1653 9968 idMesh = m_listVariable[iVar].idMesh();
1654 9968 typeOfFiniteElement = m_listVariable[iVar].finiteElementType();
1655 9968 refEle = geoEle->defineFiniteEle(eltType,typeOfFiniteElement, *m_meshLocal[idMesh]);
1656
1/2
✓ Branch 6 taken 9968 times.
✗ Branch 7 not taken.
9968 fewbd = new CurrentFiniteElementWithBd(*refEle,*geoEle,m_listVariable[iVar].getDegreeOfExactness(),m_listVariable[iVar].degreeOfExactness()); //maybe it causes a memory leak
1657 9968 m_listCurrentFiniteElementWithBd.add(fewbd);
1658 }
1659 5488 }
1660
1661 /***********************************************************************************/
1662 /***********************************************************************************/
1663
1664 void LinearProblem::defineCurrentFiniteElementWithBd(const std::vector<ElementType>& eltType)
1665 {
1666 m_listCurrentFiniteElementWithBd.clear();
1667
1668 //Initialisation of Finite Element current with boundary problem
1669 std::size_t idMesh;
1670 const RefElement *refEle;
1671 const GeoElement *geoEle;
1672 int typeOfFiniteElement = 0;
1673 CurrentFiniteElementWithBd* fewbd;
1674 for ( std::size_t iVar = 0; iVar < m_listVariable.size(); iVar++) {
1675 idMesh = m_listVariable[iVar].idMesh();
1676 geoEle = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType[iVar]].second;
1677 typeOfFiniteElement = m_listVariable[iVar].finiteElementType();
1678 refEle = geoEle->defineFiniteEle(eltType[iVar],typeOfFiniteElement, *m_meshLocal[idMesh]);
1679 fewbd = new CurrentFiniteElementWithBd(*refEle,*geoEle,m_listVariable[iVar].getDegreeOfExactness(),m_listVariable[iVar].degreeOfExactness()); //maybe it causes a memory leak
1680 m_listCurrentFiniteElementWithBd.add(fewbd);
1681 }
1682 }
1683
1684 /***********************************************************************************/
1685 /***********************************************************************************/
1686
1687 21235 void LinearProblem::initElementArrayBD(const bool initTranspose)
1688 {
1689 21235 m_elementMatBD.clear();
1690 21235 m_elementMatTBD.clear();
1691 21235 m_elementVectorBD.clear();
1692
1693 int idVar;
1694 21235 std::size_t rowSize = m_listUnknown.getUnknownsRows().size();
1695 21235 std::size_t colSize = m_listUnknown.getUnknownsCols().size();
1696
2/4
✓ Branch 2 taken 21235 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 21235 times.
✗ Branch 7 not taken.
42470 std::vector<std::size_t> numberCmp1(rowSize), numberCmp2(colSize);
1697
2/4
✓ Branch 2 taken 21235 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 21235 times.
✗ Branch 7 not taken.
42470 std::vector<const CurBaseFiniteElement*> finiteElt1(rowSize), finiteElt2(colSize);
1698
1699
2/2
✓ Branch 0 taken 39054 times.
✓ Branch 1 taken 21235 times.
60289 for (std::size_t n = 0; n < rowSize; n++){
1700 39054 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsRows()[n]);
1701 39054 numberCmp1[n] = m_listVariable[idVar].numComponent();
1702 39054 finiteElt1[n] = m_listCurvilinearFiniteElement[idVar];
1703 }
1704
1705
2/2
✓ Branch 0 taken 39054 times.
✓ Branch 1 taken 21235 times.
60289 for (std::size_t n = 0; n < colSize; n++){
1706 39054 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsCols()[n]);
1707 39054 numberCmp2[n] = m_listVariable[idVar].numComponent();
1708 39054 finiteElt2[n] = m_listCurvilinearFiniteElement[idVar];
1709 }
1710
1711
2/2
✓ Branch 1 taken 35234 times.
✓ Branch 2 taken 21235 times.
56469 for (std::size_t i = 0; i < m_vectors.size(); i++)
1712
2/4
✓ Branch 1 taken 35234 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 35234 times.
✗ Branch 5 not taken.
35234 m_elementVectorBD.push_back(felisce::make_shared<ElementVector>(finiteElt1, numberCmp1));
1713
1714
2/2
✓ Branch 1 taken 43102 times.
✓ Branch 2 taken 21235 times.
64337 for (std::size_t i = 0; i < m_matrices.size(); i++)
1715
2/4
✓ Branch 1 taken 43102 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 43102 times.
✗ Branch 5 not taken.
43102 m_elementMatBD.push_back(felisce::make_shared<ElementMatrix>(finiteElt1, numberCmp1, finiteElt2, numberCmp2));
1716
1717
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21235 times.
21235 if (initTranspose)
1718 for (std::size_t i = 0; i < m_matrices.size(); i++)
1719 m_elementMatTBD.push_back(felisce::make_shared<ElementMatrix>(finiteElt2, numberCmp2, finiteElt1, numberCmp1));
1720 21235 }
1721
1722 /***********************************************************************************/
1723 /***********************************************************************************/
1724
1725 14790 void LinearProblem::initPerDomainBD(int label, FlagMatrixRHS /*flagMatrixRHS*/)
1726 {
1727 14790 m_currentLabel = label;
1728 14790 }
1729
1730 /***********************************************************************************/
1731 /***********************************************************************************/
1732
1733 273949 void LinearProblem::setElemPointNormalTangent(ElementType& eltType, felInt iel, std::vector<Point*>& elemPoint,
1734 std::vector<Point*>& elemNormal, std::vector< std::vector<Point*> >& elemTangent,
1735 std::vector<felInt>& elemIdPoint,std::vector<felInt>& vectorSupport)
1736 {
1737 // We assume that the support elements are the same for all the unknown defined on the current mesh.
1738 273949 const int iUnknown = m_listUnknown.getUnknownsRows()[0]; // TODO D.C.
1739 273949 const int iMesh = m_meshUnknown[iUnknown];
1740 273949 m_supportDofUnknownLocal[iUnknown].getIdElementSupport(eltType, iel, vectorSupport);
1741 273949 ISLocalToGlobalMappingApply(*m_mappingElemSupportPerUnknown[iUnknown], vectorSupport.size(), vectorSupport.data(), vectorSupport.data());
1742
1743 273949 const int numPointsPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
1744 273949 m_meshLocal[iMesh]->getOneElement(eltType, iel, elemIdPoint, 0);
1745
2/2
✓ Branch 0 taken 796228 times.
✓ Branch 1 taken 273949 times.
1070177 for (int iPoint = 0; iPoint < numPointsPerElt; iPoint++) {
1746 796228 elemPoint[iPoint] = &m_meshLocal[iMesh]->listPoints()[elemIdPoint[iPoint]];
1747 796228 elemNormal[iPoint] = &m_meshLocal[iMesh]->listNormals()[elemIdPoint[iPoint]];
1748
2/2
✓ Branch 1 taken 1536176 times.
✓ Branch 2 taken 796228 times.
2332404 for (std::size_t j=0 ; j<elemTangent.size() ; j++)
1749 1536176 elemTangent[j][iPoint] = &m_meshLocal[iMesh]->listTangents(j)[elemIdPoint[iPoint]];
1750 }
1751 273949 }
1752
1753 /***********************************************************************************/
1754 /***********************************************************************************/
1755
1756 1010826 void LinearProblem::setValueMatrixRHSBD(const std::vector<felInt>& ielSupportDof1, const std::vector<felInt>& ielSupportDof2, FlagMatrixRHS flagMatrixRHS, bool buildMatT)
1757 {
1758
4/8
✓ Branch 0 taken 977146 times.
✓ Branch 1 taken 33680 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 977146 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1010826 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
1010826 FEL_ASSERT( flagMatrixRHS != FlagMatrixRHS::only_rhs ? !m_elementMatBD.empty() : true );
1759
4/10
✓ Branch 0 taken 977146 times.
✓ Branch 1 taken 33680 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 977146 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1010826 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
1010826 FEL_ASSERT( flagMatrixRHS != FlagMatrixRHS::only_rhs && buildMatT ? !m_elementMatTBD.empty() : true );
1760
4/8
✓ Branch 0 taken 1010586 times.
✓ Branch 1 taken 240 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1010586 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1010826 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
1010826 FEL_ASSERT( flagMatrixRHS != FlagMatrixRHS::only_matrix ? !m_elementVectorBD.empty() : true );
1761
3/6
✓ Branch 0 taken 977146 times.
✓ Branch 1 taken 33680 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 977146 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
1010826 FEL_ASSERT( flagMatrixRHS != FlagMatrixRHS::only_rhs ? m_GposColumn != nullptr : true );
1762
3/6
✓ Branch 0 taken 1010586 times.
✓ Branch 1 taken 240 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1010586 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
1010826 FEL_ASSERT( flagMatrixRHS != FlagMatrixRHS::only_matrix ? m_GposLine != nullptr : true );
1763
1764 1010826 const felInt numDofTotal1 = m_elementMatBD[0]->mat().size1();
1765 1010826 const felInt numDofTotal2 = m_elementMatBD[0]->mat().size2();
1766 int idVar;
1767 felInt cptGpos;
1768 1010826 std::vector<felInt> loc2globTmp;
1769
1770 // Build the loc2glob map m_GposLine for the first support element (i.e. for the rows of the matrix or RHS)
1771 1010826 cptGpos = 0;
1772
2/2
✓ Branch 2 taken 1713420 times.
✓ Branch 3 taken 1010826 times.
2724246 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsRows().size(); iUnknown++) {
1773 1713420 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsRows()[iUnknown]);
1774
1/2
✓ Branch 6 taken 1713420 times.
✗ Branch 7 not taken.
1713420 m_dof.loc2glob(ielSupportDof1[iUnknown], m_listCurvilinearFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
1775
1776
2/2
✓ Branch 1 taken 11124552 times.
✓ Branch 2 taken 1713420 times.
12837972 for(std::size_t i=0; i<loc2globTmp.size(); ++i)
1777 11124552 m_GposLine[cptGpos++] = loc2globTmp[i];
1778 }
1779
1780
3/4
✓ Branch 0 taken 976906 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 33680 times.
✗ Branch 3 not taken.
1010826 switch (flagMatrixRHS) {
1781 976906 case FlagMatrixRHS::matrix_and_rhs :
1782
1783 // Build the loc2glob map m_GposColumn for the second support element (i.e. for the columns of the matrix)
1784
5/10
✓ Branch 1 taken 976906 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 976906 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 976906 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 976906 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 976906 times.
✗ Branch 13 not taken.
976906 if(ielSupportDof1 == ielSupportDof2 && m_listUnknown.getUnknownsRows() == m_listUnknown.getUnknownsCols() ) {
1785 // if the two support element are the same (always the case unless we have duplicated support element)
1786
2/2
✓ Branch 0 taken 10999752 times.
✓ Branch 1 taken 976906 times.
11976658 for ( felInt i = 0; i < numDofTotal1; ++i )
1787 10999752 m_GposColumn[i] = m_GposLine[i];
1788 } else {
1789 // if they are different, compute it.
1790 cptGpos = 0;
1791 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsCols().size(); iUnknown++) {
1792 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsCols()[iUnknown]);
1793 m_dof.loc2glob(ielSupportDof2[iUnknown], m_listCurvilinearFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
1794
1795 for(std::size_t i=0; i<loc2globTmp.size(); ++i)
1796 m_GposColumn[cptGpos++] = loc2globTmp[i];
1797 }
1798 }
1799
1800 // Set values
1801
1/2
✓ Branch 1 taken 976906 times.
✗ Branch 2 not taken.
976906 AOApplicationToPetsc(m_ao,numDofTotal1,m_GposLine);
1802
1/2
✓ Branch 1 taken 976906 times.
✗ Branch 2 not taken.
976906 AOApplicationToPetsc(m_ao,numDofTotal2,m_GposColumn);
1803
2/2
✓ Branch 1 taken 1815652 times.
✓ Branch 2 taken 976906 times.
2792558 for (std::size_t i = 0; i < m_matrices.size(); i++)
1804
1/2
✓ Branch 7 taken 1815652 times.
✗ Branch 8 not taken.
1815652 m_matrices[i].setValues(numDofTotal1,m_GposLine,numDofTotal2,m_GposColumn,m_elementMatBD[i]->mat().data().begin(),ADD_VALUES);
1805
3/6
✓ Branch 1 taken 976906 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 976906 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 976906 times.
976906 for (std::size_t i = 0; i < m_matrices.size() && buildMatT; i++)
1806 m_matrices[i].setValues(numDofTotal2,m_GposColumn,numDofTotal1,m_GposLine,m_elementMatTBD[i]->mat().data().begin(),ADD_VALUES);
1807
2/2
✓ Branch 1 taken 1303234 times.
✓ Branch 2 taken 976906 times.
2280140 for (std::size_t i = 0; i < m_vectors.size(); i++)
1808
1/2
✓ Branch 7 taken 1303234 times.
✗ Branch 8 not taken.
1303234 m_vectors[i].setValues(numDofTotal1,m_GposLine, m_elementVectorBD[i]->vec().data().begin(), ADD_VALUES);
1809 976906 break;
1810
1811 240 case FlagMatrixRHS::only_matrix :
1812
1813 // Build the loc2glob map m_GposColumn for the second support element (i.e. for the columns of the matrix)
1814
5/10
✓ Branch 1 taken 240 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 240 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 240 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 240 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 240 times.
✗ Branch 13 not taken.
240 if(ielSupportDof1 == ielSupportDof2 && m_listUnknown.getUnknownsRows() == m_listUnknown.getUnknownsCols() ) {
1815 // if the two support element are the same (always the case unless we have duplicated support element)
1816
2/2
✓ Branch 0 taken 480 times.
✓ Branch 1 taken 240 times.
720 for ( felInt i = 0; i < numDofTotal1; ++i )
1817 480 m_GposColumn[i] = m_GposLine[i];
1818 } else {
1819 // if they are different, compute it.
1820 cptGpos = 0;
1821 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsCols().size(); iUnknown++) {
1822 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsCols()[iUnknown]);
1823 m_dof.loc2glob(ielSupportDof2[iUnknown], m_listCurvilinearFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
1824
1825 for(std::size_t i=0; i<loc2globTmp.size(); ++i)
1826 m_GposColumn[cptGpos++] = loc2globTmp[i];
1827 }
1828 }
1829
1830 // Set values
1831
1/2
✓ Branch 1 taken 240 times.
✗ Branch 2 not taken.
240 AOApplicationToPetsc(m_ao,numDofTotal1,m_GposLine);
1832
1/2
✓ Branch 1 taken 240 times.
✗ Branch 2 not taken.
240 AOApplicationToPetsc(m_ao,numDofTotal2,m_GposColumn);
1833
2/2
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 240 times.
480 for (std::size_t i = 0; i < m_matrices.size(); i++)
1834
1/2
✓ Branch 7 taken 240 times.
✗ Branch 8 not taken.
240 m_matrices[i].setValues(numDofTotal1,m_GposLine,numDofTotal2,m_GposColumn,m_elementMatBD[i]->mat().data().begin(),ADD_VALUES);
1835
3/6
✓ Branch 1 taken 240 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 240 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 240 times.
240 for (std::size_t i = 0; i < m_matrices.size() && buildMatT; i++)
1836 m_matrices[i].setValues(numDofTotal2,m_GposColumn,numDofTotal1,m_GposLine,m_elementMatTBD[i]->mat().data().begin(),ADD_VALUES);
1837 240 break;
1838
1839 33680 case FlagMatrixRHS::only_rhs :
1840
1841 // Set values
1842
1/2
✓ Branch 1 taken 33680 times.
✗ Branch 2 not taken.
33680 AOApplicationToPetsc(m_ao,numDofTotal1,m_GposLine);
1843
2/2
✓ Branch 1 taken 33680 times.
✓ Branch 2 taken 33680 times.
67360 for (std::size_t i = 0; i < m_vectors.size(); i++)
1844
1/2
✓ Branch 7 taken 33680 times.
✗ Branch 8 not taken.
33680 m_vectors[i].setValues(numDofTotal1,m_GposLine, m_elementVectorBD[i]->vec().data().begin(), ADD_VALUES);
1845 33680 break;
1846
1847 default:
1848 FEL_ERROR("Problem with Matrix/RHS flag.");
1849 }
1850 1010826 }
1851
1852 /***********************************************************************************/
1853 /***********************************************************************************/
1854
1855 1010826 void LinearProblem::setValueMatrixRHSBD(const felInt ielSupportDof1, const felInt ielSupportDof2, FlagMatrixRHS flagMatrixRHS, bool buildMatT)
1856 {
1857
1/2
✓ Branch 4 taken 1010826 times.
✗ Branch 5 not taken.
1010826 std::vector<felInt> vecIelSupportDof1(m_listUnknown.getUnknownsRows().size(), ielSupportDof1);
1858
1/2
✓ Branch 4 taken 1010826 times.
✗ Branch 5 not taken.
1010826 std::vector<felInt> vecIelSupportDof2(m_listUnknown.getUnknownsCols().size(), ielSupportDof2);
1859
1/2
✓ Branch 1 taken 1010826 times.
✗ Branch 2 not taken.
1010826 setValueMatrixRHSBD(vecIelSupportDof1, vecIelSupportDof2, flagMatrixRHS, buildMatT);
1860 1010826 }
1861
1862 /***********************************************************************************/
1863 /***********************************************************************************/
1864
1865 void LinearProblem::setValueCustomMatrixBD(const std::vector<felInt>& ielSupportDof1, const std::vector<felInt>& ielSupportDof2, PetscMatrix& mat, bool buildMatT)
1866 {
1867 FEL_ASSERT( !m_elementMatBD.empty() );
1868 FEL_ASSERT( buildMatT ? !m_elementMatTBD.empty() : true );
1869 FEL_ASSERT( m_GposColumn );
1870 FEL_ASSERT( m_GposLine );
1871
1872 const felInt numDofTotal1 = m_elementMatBD[0]->mat().size1();
1873 const felInt numDofTotal2 = m_elementMatBD[0]->mat().size2();
1874 int idVar;
1875 felInt cptGpos;
1876 std::vector<felInt> loc2globTmp;
1877
1878 // Build the loc2glob map m_GposLine for the first support element (i.e. for the rows of the matrix or RHS)
1879 cptGpos = 0;
1880 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsRows().size(); iUnknown++) {
1881 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsRows()[iUnknown]);
1882 m_dof.loc2glob(ielSupportDof1[iUnknown], m_listCurvilinearFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
1883
1884 for(std::size_t i=0; i<loc2globTmp.size(); ++i)
1885 m_GposLine[cptGpos++] = loc2globTmp[i];
1886 }
1887
1888 // Build the loc2glob map m_GposColumn for the second support element (i.e. for the columns of the matrix)
1889 if(ielSupportDof1 == ielSupportDof2 && m_listUnknown.getUnknownsRows() == m_listUnknown.getUnknownsCols() ) {
1890 // if the two support element are the same (always the case unless we have duplicated support element) just copy the first one
1891 for ( felInt i = 0; i < numDofTotal1; ++i )
1892 m_GposColumn[i] = m_GposLine[i];
1893 } else {
1894 // if they are different, compute it.
1895 cptGpos = 0;
1896 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsCols().size(); iUnknown++) {
1897 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsCols()[iUnknown]);
1898 m_dof.loc2glob(ielSupportDof2[iUnknown], m_listCurvilinearFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
1899
1900 for(std::size_t i=0; i<loc2globTmp.size(); ++i)
1901 m_GposColumn[cptGpos++] = loc2globTmp[i];
1902 }
1903 }
1904
1905 AOApplicationToPetsc(m_ao,numDofTotal1,m_GposLine);
1906 AOApplicationToPetsc(m_ao,numDofTotal2,m_GposColumn);
1907 mat.setValues(numDofTotal1,m_GposLine,numDofTotal2,m_GposColumn,m_elementMatBD[0]->mat().data().begin(),ADD_VALUES);
1908 if (buildMatT)
1909 mat.setValues(numDofTotal2,m_GposColumn,numDofTotal1,m_GposLine,m_elementMatTBD[0]->mat().data().begin(),ADD_VALUES);
1910 }
1911
1912 /***********************************************************************************/
1913 /***********************************************************************************/
1914
1915 void LinearProblem::setValueCustomMatrixBD(const felInt ielSupportDof1, const felInt ielSupportDof2, PetscMatrix& mat, bool buildMatT)
1916 {
1917 std::vector<felInt> vecIelSupportDof1(m_listUnknown.getUnknownsRows().size(), ielSupportDof1);
1918 std::vector<felInt> vecIelSupportDof2(m_listUnknown.getUnknownsCols().size(), ielSupportDof2);
1919 setValueCustomMatrixBD(vecIelSupportDof1, vecIelSupportDof2, mat, buildMatT);
1920 }
1921
1922 /***********************************************************************************/
1923 /***********************************************************************************/
1924
1925 void LinearProblem::setValueCustomVectorBD(const std::vector<felInt>& ielSupportDof1, InsertMode mode, PetscVector& vec)
1926 {
1927 FEL_ASSERT(!m_elementVectorBD.empty());
1928 FEL_ASSERT( m_GposLine );
1929
1930 const felInt numDofTotal = m_elementVectorBD[0]->vec().size();
1931 int idVar;
1932 felInt cptGpos;
1933 std::vector<felInt> loc2globTmp;
1934
1935 // Build the loc2glob map m_GposLine for the first support element (i.e. for the rows of the matrix or RHS)
1936 cptGpos = 0;
1937 for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsRows().size(); iUnknown++) {
1938 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsRows()[iUnknown]);
1939 m_dof.loc2glob(ielSupportDof1[iUnknown], m_listCurvilinearFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
1940
1941 for(std::size_t i=0; i<loc2globTmp.size(); ++i)
1942 m_GposLine[cptGpos++] = loc2globTmp[i];
1943 }
1944
1945 // Set values
1946 AOApplicationToPetsc(m_ao,numDofTotal,m_GposLine);
1947 vec.setValues(numDofTotal,m_GposLine,m_elementVectorBD[0]->vec().data().begin(),mode);
1948 }
1949
1950 /***********************************************************************************/
1951 /***********************************************************************************/
1952
1953 void LinearProblem::setValueCustomVectorBD(const felInt ielSupportDof1, InsertMode mode, PetscVector& vec)
1954 {
1955 std::vector<felInt> vecIelSupportDof1(m_listUnknown.getUnknownsRows().size(), ielSupportDof1);
1956 setValueCustomVectorBD(vecIelSupportDof1, mode, vec);
1957 }
1958
1959 /***********************************************************************************/
1960 /***********************************************************************************/
1961
1962 19963 void LinearProblem::allocateArrayForAssembleMatrixRHSBD(FlagMatrixRHS flagMatrixRHS)
1963 {
1964 int idVar;
1965 19963 felInt numDofTotalL = 0;
1966
2/2
✓ Branch 2 taken 36750 times.
✓ Branch 3 taken 19963 times.
56713 for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsRows().size(); iUnknown++) {
1967 36750 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsRows()[iUnknown]);
1968 36750 numDofTotalL += m_listCurvilinearFiniteElement[idVar]->numDof()*m_listVariable[idVar].numComponent();
1969 }
1970
1/2
✓ Branch 0 taken 19963 times.
✗ Branch 1 not taken.
19963 m_GposLine = new felInt[numDofTotalL];
1971
1972
4/4
✓ Branch 0 taken 528 times.
✓ Branch 1 taken 19435 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 524 times.
19963 if( (flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs) || (flagMatrixRHS == FlagMatrixRHS::only_matrix)) {
1973 19439 felInt numDofTotalC = 0;
1974
2/2
✓ Branch 2 taken 36026 times.
✓ Branch 3 taken 19439 times.
55465 for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.getUnknownsCols().size(); iUnknown++) {
1975 36026 idVar = m_listUnknown.idVariable(m_listUnknown.getUnknownsCols()[iUnknown]);
1976 36026 numDofTotalC += m_listCurvilinearFiniteElement[idVar]->numDof()*m_listVariable[idVar].numComponent();
1977 }
1978
1/2
✓ Branch 0 taken 19439 times.
✗ Branch 1 not taken.
19439 m_GposColumn = new felInt[numDofTotalC];
1979 }
1980 19963 }
1981
1982 /***********************************************************************************/
1983 /***********************************************************************************/
1984
1985 void LinearProblem::assembleMatrixRHSCurrentAndCurvilinearElement(int rank, FlagMatrixRHS flagMatrixRHS)
1986 {
1987 IGNORE_UNUSED_RANK;
1988
1989 ElementType eltType; //geometric element type in the mesh.
1990 int numPointPerElt = 0; //number of points per geometric element.
1991 int currentLabel = 0; //number of label domain.
1992 felInt numEltPerLabel = 0; //number of element for one label and one eltType.
1993
1994 // Use to define a "global" numbering of element in the mesh.
1995 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
1996 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
1997 eltType = (ElementType)ityp;
1998 numElement[eltType] = 0;
1999 }
2000
2001 // Contains points of the current element.
2002 std::vector<Point*> elemPoint;
2003
2004 // Contains ids of point of the current element.
2005 std::vector<felInt> elemIdPoint;
2006
2007 // Contains ids of support elements of a mesh element
2008 std::vector<felInt> vectorIdSupport;
2009
2010 // Use to get element number in support dof mesh ordering.
2011 felInt ielSupportDof;
2012 felInt ielSupportDofCurv;
2013
2014 //Assembly loop current.
2015 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[m_currentMesh]->bagElementTypeDomain();
2016 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
2017 eltType = bagElementTypeDomain[i];
2018
2019 // Resize array.
2020 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
2021 elemPoint.resize(numPointPerElt, nullptr);
2022 elemIdPoint.resize(numPointPerElt, 0);
2023
2024 // Define all current finite element use in the problem from data
2025 // file cnfiguration and allocate 1 and elemVec (question: virtual ?).
2026 defineFiniteElement(eltType);
2027
2028 //Element matrix and vector initialisation
2029 initElementArray();
2030
2031 // Allocate array use for assemble with petsc.
2032 allocateArrayForAssembleMatrixRHS(flagMatrixRHS);
2033
2034 // Virtual function use in derived problem to allocate elemenField necessary.
2035 initPerElementType(eltType, flagMatrixRHS);
2036
2037 // use by user to add specific term (source term for example with elemField).
2038 userElementInit();
2039
2040 // Second loop on region of the mesh.
2041 for(auto itRef = m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
2042 currentLabel = itRef->first;
2043 numEltPerLabel = itRef->second.second;
2044
2045 //By default this virtual defnie variable m_currentLabel: (m_currentLabel=label).
2046 //We can switch on label region with that and define some parameters.
2047 initPerDomain(currentLabel, flagMatrixRHS);
2048
2049 // Third loop on element in the region with the type: eltType. ("real" loop on elements).
2050 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
2051
2052 // Return each id of point of the element and coordinate in two arrays: elemPoint and elemIdPoint.
2053 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
2054
2055 // Loop over all the support elements
2056 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
2057 // Get the id of the support
2058 ielSupportDof = vectorIdSupport[it];
2059
2060 for (std::size_t j = 0; j < m_matrices.size(); j++)
2061 m_elementMat[j]->zero();
2062
2063 // Clear elementary vector.
2064 for (std::size_t j = 0; j < m_vectors.size(); j++)
2065 m_elementVector[j]->zero();
2066
2067 // Function call in derived problem to compute specific operators of the problem (Heat, N-S,...).
2068 computeElementArray(elemPoint, elemIdPoint, ielSupportDof, flagMatrixRHS);
2069
2070 // Compute specific term of users.
2071 //userElementCompute(elemPoint, elemIdPoint, ielSupportDof);
2072
2073 // Add values of elemMat in the global matrix: m_matrices[0].
2074 setValueMatrixRHS(ielSupportDof, ielSupportDof, flagMatrixRHS);
2075 }
2076 numElement[eltType]++;
2077 }
2078 }
2079 // Desallocate array use for assemble with petsc.
2080 desallocateArrayForAssembleMatrixRHS(flagMatrixRHS);
2081 }
2082
2083 //Assembly loop curvilinear.
2084 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[m_currentMesh]->bagElementTypeDomainBoundary();
2085 for (std::size_t i = 0; i < bagElementTypeDomainBoundary.size(); ++i) {
2086 eltType = bagElementTypeDomainBoundary[i];
2087
2088 // Resize array.
2089 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
2090 elemPoint.resize(numPointPerElt, nullptr);
2091 elemIdPoint.resize(numPointPerElt, 0);
2092
2093 // Define all current finite element use in the problem from data
2094 defineCurvilinearFiniteElement(eltType);
2095
2096 // Element matrix and vector initialisation
2097 initElementArrayBD();
2098
2099 //allocate array use for assemble with petsc.
2100 allocateArrayForAssembleMatrixRHSBD(flagMatrixRHS);
2101
2102 //virtual function use in derived problem to allocate elemenField necessary.
2103 initPerElementTypeBoundaryCondition(eltType, flagMatrixRHS);
2104
2105 // use by user to add specific term (term source for example with elemField).
2106 userElementInitNaturalBoundaryCondition();
2107
2108 FEL_ASSERT(!m_elementVectorBD.empty());
2109
2110 // allocate elem field and setValue if BC = constant in space
2111 // if BC = function : setValue in users
2112 // allocateElemFieldBoundaryCondition(idBCforLinCombMethod);
2113
2114 //second loop on region of the mesh.
2115 for(auto itRef = m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
2116 currentLabel = itRef->first;
2117 numEltPerLabel = itRef->second.second;
2118
2119 //By default this virtual define variable m_currentLabel: (m_currentLabel=label).
2120 //We can switch on label region with that and define some parameters.
2121 //We can also fill the elemField allocated in initPerElementTypeBoundaryCondition()
2122 initPerDomainBoundaryCondition(elemPoint, elemIdPoint, currentLabel, numEltPerLabel, &ielSupportDofCurv, eltType, numElement[eltType], flagMatrixRHS);
2123
2124 //Third loop on element in the region with the type: eltType. ("real" loop on elements).
2125 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
2126 // return each id of point of the element and coordinate in two arrays: elemPoint and elemIdPoint.
2127 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
2128
2129 // Loop over all the support elements
2130 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
2131 // Get the id of the support
2132 ielSupportDofCurv = vectorIdSupport[it];
2133
2134 // clear elementary matrix.
2135 for (std::size_t j = 0; j < m_matrices.size(); j++)
2136 m_elementMatBD[j]->zero();
2137
2138 // Clear elementary std::vector.
2139 for (std::size_t j = 0; j < m_vectors.size(); j++)
2140 m_elementVectorBD[j]->zero();
2141
2142 // function call in derived problem to compute specific operators of the problem (Heat, N-S,...).
2143 computeElementArraySurfaceModel(elemPoint, elemIdPoint, ielSupportDofCurv,flagMatrixRHS);
2144
2145 // add values of elemMat in the global matrix: m_matrices[0].
2146 // notBoundarySurfaceLabels = list of surfaces/edges that are part of the domain but are not boundaries of volumes/surfaces
2147 auto bndRefIt = find(FelisceParam::instance(this->instanceIndex()).notBoundarySurfaceLabels.begin(), FelisceParam::instance(this->instanceIndex()).notBoundarySurfaceLabels.end(), currentLabel);
2148
2149 if(bndRefIt != FelisceParam::instance(this->instanceIndex()).notBoundarySurfaceLabels.end()) {
2150 //computeElementArrayBoundaryCondition(elemPoint, elemIdPoint, ielSupportDofCurv,flagMatrixRHS);
2151 setValueMatrixRHSBD(ielSupportDofCurv, ielSupportDofCurv, flagMatrixRHS);
2152 }
2153 }
2154 numElement[eltType]++;
2155 }
2156 }
2157
2158 // Deallocate array use for assemble with petsc.
2159 desallocateArrayForAssembleMatrixRHS(flagMatrixRHS);
2160 }
2161
2162 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix) {
2163 //real assembling of the matrix manage by PETsC.
2164 for (std::size_t i = 0; i < m_matrices.size(); i++)
2165 m_matrices[i].assembly(MAT_FINAL_ASSEMBLY);
2166 }
2167 //call with high level of verbose to print matrix in matlab format.
2168 writeMatrixForMatlab(m_verbosity);
2169
2170 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs) {
2171 //real assembling of the right hand side (RHS).
2172 for (std::size_t index = 0; index < m_vectors.size(); index++) {
2173 m_vectors[index].assembly();
2174 }
2175 }
2176 //call with high level of verbose to print right hand side in matlab format.
2177 writeRHSForMatlab(m_verbosity);
2178 }
2179
2180 /***********************************************************************************/
2181 /***********************************************************************************/
2182
2183 30117 void LinearProblem::applyBC(const int & applicationOption, int rank, FlagMatrixRHS flagMatrixRHSEss, FlagMatrixRHS flagMatrixRHSNat,
2184 const int idBCforLinCombMethod, bool doPrintBC,
2185 ApplyNaturalBoundaryConditionsType do_apply_natural)
2186 {
2187 // Get the timer
2188 30117 auto& r_instance = FelisceParam::instance(this->instanceIndex());
2189 30117 auto& r_timer = r_instance.timer;
2190
2191
7/10
✓ Branch 1 taken 29193 times.
✓ Branch 2 taken 924 times.
✓ Branch 4 taken 18345 times.
✓ Branch 5 taken 10848 times.
✓ Branch 10 taken 30117 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 30117 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 30117 times.
✗ Branch 17 not taken.
30117 r_timer.Start("LinearProblem" + std::to_string(m_identifier_problem) + "::applyBC", m_fstransient ? (m_fstransient->total_number_iterations > 0 ? m_fstransient->total_number_iterations : m_fstransient->iteration ) : 0);
2192
2193
4/4
✓ Branch 0 taken 28953 times.
✓ Branch 1 taken 1164 times.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 28873 times.
30117 if (doPrintBC && m_verbosity > 2) {
2194 80 PetscPrintf(MpiInfo::petscComm(), "\n/============== Information about boundary condition.===============/\n");
2195 80 m_boundaryConditionList.print(m_verbosity);
2196 }
2197 // In some dynamic problems we might want to be able to skip natural conditions, hence this flag.
2198 // Its role is absolutely not the same as the other flag addedBoundaryFlag: in a same problem
2199 // FelisceParam::instance(this->instanceIndex()).addedBoundaryFlag is probably the same all the way whereas do_apply_natural is deemed to be
2200 // true in the first time iteration and then false otherwise in some time schemes.
2201
2/2
✓ Branch 0 taken 25769 times.
✓ Branch 1 taken 4348 times.
30117 if (do_apply_natural == ApplyNaturalBoundaryConditions::yes) {
2202 // Natural boundary condition (Neumann, Neumann Normal, Robin, RobinNormal, EmbedFSI, Natural LumpedModelBC, Backflow stabilization for now).
2203
2/2
✓ Branch 1 taken 6104 times.
✓ Branch 2 taken 19665 times.
25769 if (m_boundaryConditionList.NaturalBoundaryCondition()) {
2204 // Assemble Matrix and/or RHS (depends on flagMatrixRHSNat)
2205 6104 assembleMatrixRHSNaturalBoundaryCondition(rank, flagMatrixRHSNat, idBCforLinCombMethod);
2206 }
2207 }
2208
2209 #ifdef FELISCE_WITH_CVGRAPH
2210
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 30117 times.
30117 if ( FelisceParam::instance(this->instanceIndex()).withCVG ) {
2211 cvgAddExternalResidualToRHS();
2212 }
2213 #endif
2214
2215 // Essential boundary condition (Dirichlet, Essential lumpedModelBC).
2216
5/6
✓ Branch 1 taken 762 times.
✓ Branch 2 taken 29355 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 762 times.
✓ Branch 7 taken 29355 times.
✓ Branch 8 taken 762 times.
30117 if (m_boundaryConditionList.EssentialBoundaryCondition() || FelisceParam::instance(this->instanceIndex()).useEssDerivedBoundaryCondition) {
2217 29355 applyEssentialBoundaryCondition(applicationOption, rank, flagMatrixRHSEss);
2218 }
2219
2220
7/10
✓ Branch 1 taken 29193 times.
✓ Branch 2 taken 924 times.
✓ Branch 4 taken 18345 times.
✓ Branch 5 taken 10848 times.
✓ Branch 10 taken 30117 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 30117 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 30117 times.
✗ Branch 17 not taken.
30117 r_timer.Stop("LinearProblem" + std::to_string(m_identifier_problem) + "::applyBC", m_fstransient ? (m_fstransient->total_number_iterations > 0 ? m_fstransient->total_number_iterations : m_fstransient->iteration ) : 0);
2221 30117 }
2222
2223 /***********************************************************************************/
2224 /***********************************************************************************/
2225
2226 6104 void LinearProblem::assembleMatrixRHSNaturalBoundaryCondition(int rank, FlagMatrixRHS flagMatrixRHS, const int idBCforLinCombMethod)
2227 {
2228 IGNORE_UNUSED_RANK;
2229 ElementType eltType; // Geometric element type in the mesh.
2230 6104 int numPointPerElt = 0; // Number of points per geometric element.
2231 6104 int currentLabel = 0; // Number of label domain.
2232 6104 felInt numEltPerLabel = 0; // Number of element for one label and one eltType.
2233
2234 // Retrieve instance
2235
2/4
✓ Branch 1 taken 6104 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6104 times.
✗ Branch 5 not taken.
6104 auto& r_instance = FelisceParam::instance(this->instanceIndex());
2236
2237 // Use to define a "global" numbering of element in the mesh.
2238 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
2239
2/2
✓ Branch 0 taken 152600 times.
✓ Branch 1 taken 6104 times.
158704 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
2240 152600 eltType = (ElementType)ityp;
2241 152600 numElement[eltType] = 0;
2242 }
2243
2244 // I need to define the CurrentFEWithBd to correctly compute the stress tensor
2245
2/2
✓ Branch 3 taken 118 times.
✓ Branch 4 taken 5986 times.
6104 if(m_meshLocal[m_currentMesh]->statusFaces() == false) {
2246
1/2
✓ Branch 3 taken 118 times.
✗ Branch 4 not taken.
118 m_meshLocal[m_currentMesh]->buildFaces();
2247 }
2248 6104 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[m_currentMesh]->bagElementTypeDomain();
2249
2/2
✓ Branch 1 taken 5384 times.
✓ Branch 2 taken 6104 times.
11488 for (std::size_t ielt = 0; ielt < bagElementTypeDomain.size(); ++ielt) {
2250 5384 eltType = bagElementTypeDomain[ielt];
2251
1/2
✓ Branch 1 taken 5384 times.
✗ Branch 2 not taken.
5384 defineCurrentFiniteElementWithBd(eltType); // TODO no sense here if bagElementTypeDomain.size() > 1 and probably not needed
2252 }
2253
2254 // Contains points of the current element.
2255 6104 std::vector<Point*> elemPoint;
2256
2257 // Contains ids of point of the current element.
2258 6104 std::vector<felInt> elemIdPoint;
2259
2260 // Contains ids of all the support elements associated to a mesh element
2261 6104 std::vector<felInt> vectorIdSupport;
2262
2263 // Use to get element number in support dof mesh ordering.
2264 felInt ielSupportDof;
2265
2266
1/2
✓ Branch 1 taken 6104 times.
✗ Branch 2 not taken.
6104 allocateVectorBoundaryConditionDerivedLinPb();
2267
2268 // First loop on geometric type.
2269 6104 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[m_currentMesh]->bagElementTypeDomainBoundary();
2270
2/2
✓ Branch 1 taken 5624 times.
✓ Branch 2 taken 6104 times.
11728 for (std::size_t i = 0; i < bagElementTypeDomainBoundary.size(); ++i) {
2271 5624 eltType = bagElementTypeDomainBoundary[i];
2272
2273 // Resize array.
2274 5624 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
2275
1/2
✓ Branch 1 taken 5624 times.
✗ Branch 2 not taken.
5624 elemPoint.resize(numPointPerElt, nullptr);
2276
1/2
✓ Branch 1 taken 5624 times.
✗ Branch 2 not taken.
5624 elemIdPoint.resize(numPointPerElt, 0);
2277
2278 // Define all current finite element use in the problem from data
2279 // file configuration and allocate elemMat and elemVec (question: virtual ?).
2280
1/2
✓ Branch 1 taken 5624 times.
✗ Branch 2 not taken.
5624 defineCurvilinearFiniteElement(eltType);
2281
2282 // Element matrix and vector initialisation
2283
1/2
✓ Branch 1 taken 5624 times.
✗ Branch 2 not taken.
5624 initElementArrayBD();
2284
2285 // Allocate array use for assemble with petsc.
2286
1/2
✓ Branch 1 taken 5624 times.
✗ Branch 2 not taken.
5624 allocateArrayForAssembleMatrixRHSBD(flagMatrixRHS);
2287
2288 // Function (1), (2), (3) doing the same stuff for different use: allocate/initialize elementField
2289 // (1) Virtual function use in derived problem to allocate elemenField necessary.
2290
1/2
✓ Branch 1 taken 5624 times.
✗ Branch 2 not taken.
5624 initPerElementTypeBoundaryCondition(eltType, flagMatrixRHS);
2291
2292 // (2) Use by user to add specific term (term source for example with elemField).
2293
1/2
✓ Branch 1 taken 5624 times.
✗ Branch 2 not taken.
5624 userElementInitNaturalBoundaryCondition();
2294
2295 // (3) Allocate Elemfield and setValue if BC = constant in space
2296 // if BC = function : setValue in users
2297
1/2
✓ Branch 1 taken 5624 times.
✗ Branch 2 not taken.
5624 allocateElemFieldBoundaryCondition(idBCforLinCombMethod);
2298
2299 // Second loop on region of the mesh.
2300
2/2
✓ Branch 8 taken 13236 times.
✓ Branch 9 taken 5624 times.
18860 for(auto itRef = m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
2301 13236 currentLabel = itRef->first;
2302 13236 numEltPerLabel = itRef->second.second;
2303
2304 //By default this virtual function assign currentLabel to the member variable m_currentLabel: (m_currentLabel=currentLabel).
2305 //We can switch on label region with that and define some parameters.
2306 //We can also fill the elemField allocated in initPerElementTypeBoundaryCondition()
2307
1/2
✓ Branch 1 taken 13236 times.
✗ Branch 2 not taken.
13236 initPerDomainBoundaryCondition(elemPoint, elemIdPoint, currentLabel, numEltPerLabel, &ielSupportDof, eltType, numElement[eltType], flagMatrixRHS); //it updates label
2308 //Third loop on element in the region with the type: eltType. ("real" loop on elements).
2309
2/2
✓ Branch 0 taken 680208 times.
✓ Branch 1 taken 13236 times.
693444 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
2310
2311
1/2
✓ Branch 0 taken 680208 times.
✗ Branch 1 not taken.
680208 if(!r_instance.duplicateSupportDof) {
2312 // return each id of point of the element and coordinate in two arrays: elemPoint and elemIdPoint.
2313
1/2
✓ Branch 1 taken 680208 times.
✗ Branch 2 not taken.
680208 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
2314
2315 // Loop over all the support elements
2316
2/2
✓ Branch 1 taken 680208 times.
✓ Branch 2 taken 680208 times.
1360416 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
2317 // Get the id of the support
2318 680208 ielSupportDof = vectorIdSupport[it];
2319 // Clear elementary matrix.
2320
2/2
✓ Branch 1 taken 1207616 times.
✓ Branch 2 taken 680208 times.
1887824 for (std::size_t j = 0; j < m_matrices.size(); j++)
2321
1/2
✓ Branch 3 taken 1207616 times.
✗ Branch 4 not taken.
1207616 m_elementMatBD[j]->zero();
2322
2323 // Clear elementary vector.
2324
2/2
✓ Branch 1 taken 680958 times.
✓ Branch 2 taken 680208 times.
1361166 for (std::size_t j = 0; j < m_vectors.size(); j++)
2325
1/2
✓ Branch 3 taken 680958 times.
✗ Branch 4 not taken.
680958 m_elementVectorBD[j]->zero();
2326
2327 // function call in derived problem to compute specific operators of the problem (Heat, N-S,...).initialized in (1)
2328
1/2
✓ Branch 1 taken 680208 times.
✗ Branch 2 not taken.
680208 computeElementArrayBoundaryCondition(elemPoint, elemIdPoint, ielSupportDof,flagMatrixRHS); //it updates fe..
2329 // compute specific term of users (Neumann transient for example) initialized in (2)
2330
1/2
✓ Branch 1 taken 680208 times.
✗ Branch 2 not taken.
680208 userElementComputeNaturalBoundaryCondition(elemPoint, elemIdPoint, ielSupportDof, currentLabel);
2331 // apply bc initialized in (3) if constant or initialized in (1) or (2) if functions
2332
1/2
✓ Branch 1 taken 680208 times.
✗ Branch 2 not taken.
680208 applyNaturalBoundaryCondition(elemPoint, elemIdPoint, ielSupportDof, flagMatrixRHS);
2333 // add values of elemMat in the global matrix: m_matrices[0].
2334
1/2
✓ Branch 1 taken 680208 times.
✗ Branch 2 not taken.
680208 setValueMatrixRHSBD(ielSupportDof, ielSupportDof, flagMatrixRHS);
2335 }
2336 } else {
2337
2338 m_duplicateSupportDofAssemblyLoopBoundaryCondition(rank, eltType, numElement[eltType], elemPoint, elemIdPoint, flagMatrixRHS);
2339 }
2340
2341 680208 numElement[eltType]++;
2342 }
2343 }
2344 //allocate array use for assemble with petsc.
2345
1/2
✓ Branch 1 taken 5624 times.
✗ Branch 2 not taken.
5624 desallocateArrayForAssembleMatrixRHS(flagMatrixRHS);
2346 }
2347
2348
4/4
✓ Branch 0 taken 528 times.
✓ Branch 1 taken 5576 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 524 times.
6104 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix) {
2349 //real assembling of the matrix manage by PETsC.
2350
2/2
✓ Branch 1 taken 12796 times.
✓ Branch 2 taken 5580 times.
18376 for (std::size_t i = 0; i < m_matrices.size(); i++)
2351
1/2
✓ Branch 2 taken 12796 times.
✗ Branch 3 not taken.
12796 m_matrices[i].assembly(MAT_FINAL_ASSEMBLY);
2352 }
2353 //call with high level of verbose to print matrix in matlab format.
2354
2/4
✓ Branch 2 taken 6104 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6104 times.
✗ Branch 6 not taken.
6104 writeMatrixForMatlab(m_verbosity);
2355
2356
4/4
✓ Branch 0 taken 528 times.
✓ Branch 1 taken 5576 times.
✓ Branch 2 taken 524 times.
✓ Branch 3 taken 4 times.
6104 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs) {
2357 //real assembling of the right hand side (RHS).
2358
2/2
✓ Branch 1 taken 6200 times.
✓ Branch 2 taken 6100 times.
12300 for (std::size_t index = 0; index < m_vectors.size(); index++) {
2359
1/2
✓ Branch 2 taken 6200 times.
✗ Branch 3 not taken.
6200 m_vectors[index].assembly();
2360 }
2361 }
2362
2363 //call with high level of verbose to print right hand side in matlab format.
2364
2/4
✓ Branch 2 taken 6104 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6104 times.
✗ Branch 6 not taken.
6104 writeRHSForMatlab(m_verbosity);
2365 6104 }
2366
2367 /***********************************************************************************/
2368 /***********************************************************************************/
2369
2370 5624 void LinearProblem::allocateElemFieldBoundaryCondition(const int idBCforLinCombMethod)
2371 {
2372 // if Function case: setValue in User's or derived problems
2373 5624 int iVariable = -1;
2374 5624 std::size_t idBC = -1;
2375 CurvilinearFiniteElement* fe;
2376 5624 std::vector <double> valueOfBC;
2377
2/2
✓ Branch 1 taken 2666 times.
✓ Branch 2 taken 5624 times.
8290 for (std::size_t i=0; i < m_boundaryConditionList.numNeumannBoundaryCondition(); i++) {
2378 2666 const BoundaryCondition& BC = *m_boundaryConditionList.Neumann(i);
2379 2666 const int num_comp = static_cast<int>(BC.getComp().size());
2380
2381
1/2
✓ Branch 3 taken 2666 times.
✗ Branch 4 not taken.
2666 iVariable = m_listVariable.getVariableIdList(BC.getVariable().physicalVariable());
2382 2666 idBC = m_boundaryConditionList.idBCOfNeumann(i);
2383
1/7
✓ Branch 1 taken 2666 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2666 switch (BC.typeValueBC()) {
2384 2666 case Constant:
2385
1/2
✓ Branch 2 taken 2666 times.
✗ Branch 3 not taken.
2666 m_elemFieldNeumann[i].initialize(CONSTANT_FIELD, num_comp);
2386
2387
2/2
✓ Branch 0 taken 2966 times.
✓ Branch 1 taken 2666 times.
5632 for (int j = 0; j < num_comp; j++) {
2388
3/6
✓ Branch 1 taken 2966 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2966 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 2966 times.
✗ Branch 10 not taken.
2966 valueOfBC.push_back(FelisceParam::instance(this->instanceIndex()).value[m_boundaryConditionList.startIndiceOfValue(idBC)+j]);
2389 }
2390
1/2
✓ Branch 2 taken 2666 times.
✗ Branch 3 not taken.
2666 m_elemFieldNeumann[i].setValue(valueOfBC);
2391 2666 break;
2392 case FunctionS:
2393 fe = m_listCurvilinearFiniteElement[iVariable];
2394 FEL_ASSERT(fe);
2395 m_elemFieldNeumann[i].initialize(QUAD_POINT_FIELD, *fe, num_comp);
2396 break;
2397 case FunctionT:
2398 m_elemFieldNeumann[i].initialize(CONSTANT_FIELD, num_comp);
2399 break;
2400 case FunctionTS:
2401 fe = m_listCurvilinearFiniteElement[iVariable];
2402 FEL_ASSERT(fe);
2403 m_elemFieldNeumann[i].initialize(QUAD_POINT_FIELD, *fe, num_comp);
2404 break;
2405 case EnsightFile:
2406 fe = m_listCurvilinearFiniteElement[iVariable];
2407 FEL_ASSERT(fe);
2408 m_elemFieldNeumann[i].initialize(DOF_FIELD, *fe, num_comp);
2409 break;
2410 case Vector:
2411 //FEL_ERROR("Impossible to define elemFieldNeumann with this type of Boundary Condition.");
2412 fe = m_listCurvilinearFiniteElement[iVariable];
2413 FEL_ASSERT(fe);
2414 m_elemFieldNeumann[i].initialize(DOF_FIELD, *fe, num_comp);
2415 break;
2416
2417 }
2418
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2666 times.
2666 if (m_verbosity > 3) {
2419 std::cout << "i : " << i << std::endl;
2420 std::cout << "Neummann: ";
2421 m_elemFieldNeumann[i].print(2);
2422 }
2423 2666 valueOfBC.clear();
2424 }
2425
2426
2/2
✓ Branch 1 taken 2868 times.
✓ Branch 2 taken 5624 times.
8492 for (std::size_t i=0; i < m_boundaryConditionList.numNeumannNormalBoundaryCondition(); i++) {
2427
2428 2868 const BoundaryCondition& BC = *m_boundaryConditionList.NeumannNormal(i);
2429
2430
1/2
✓ Branch 3 taken 2868 times.
✗ Branch 4 not taken.
2868 FEL_ASSERT_EQUAL(BC.getComp().size(), 1);
2431
2432
1/2
✓ Branch 3 taken 2868 times.
✗ Branch 4 not taken.
2868 iVariable = m_listVariable.getVariableIdList(BC.getVariable().physicalVariable());
2433 2868 idBC = m_boundaryConditionList.idBCOfNeumannNormal(i);
2434
2/6
✓ Branch 1 taken 2244 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 624 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
2868 switch (BC.typeValueBC()) {
2435 2244 case Constant:
2436
1/2
✓ Branch 2 taken 2244 times.
✗ Branch 3 not taken.
2244 m_elemFieldNeumannNormal[i].initialize(CONSTANT_FIELD);
2437 // no setValue if there is no value in datafile (i.e. implicit lumpedModelBC)
2438
3/6
✓ Branch 2 taken 2244 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2244 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2244 times.
✗ Branch 9 not taken.
2244 if ( static_cast<std::size_t>(m_boundaryConditionList.startIndiceOfValue(idBC)) < FelisceParam::instance(this->instanceIndex()).value.size() ) {
2439
3/6
✓ Branch 1 taken 2244 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2244 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 2244 times.
✗ Branch 10 not taken.
2244 valueOfBC.push_back(FelisceParam::instance(this->instanceIndex()).value[m_boundaryConditionList.startIndiceOfValue(idBC)]);
2440
1/2
✓ Branch 2 taken 2244 times.
✗ Branch 3 not taken.
2244 m_elemFieldNeumannNormal[i].setValue(valueOfBC);
2441 }
2442 2244 break;
2443 case FunctionS:
2444 fe = m_listCurvilinearFiniteElement[iVariable];
2445 FEL_ASSERT(fe);
2446 m_elemFieldNeumannNormal[i].initialize(QUAD_POINT_FIELD, *fe);
2447 break;
2448 624 case FunctionT:
2449
1/2
✓ Branch 2 taken 624 times.
✗ Branch 3 not taken.
624 m_elemFieldNeumannNormal[i].initialize(CONSTANT_FIELD);
2450 624 break;
2451 case FunctionTS:
2452 fe = m_listCurvilinearFiniteElement[iVariable];
2453 FEL_ASSERT(fe);
2454 m_elemFieldNeumannNormal[i].initialize(QUAD_POINT_FIELD, *fe);
2455 break;
2456 case Vector:
2457 case EnsightFile:
2458 FEL_ERROR("Impossible to define elemFieldNeumannNormal with this type of Boundary Condition.");
2459 break;
2460 }
2461 2868 valueOfBC.clear();
2462
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 2788 times.
2868 if (m_verbosity > 3) {
2463
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 std::cout << "NeummannNormal: ";
2464
1/2
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
80 m_elemFieldNeumannNormal[i].print(2);
2465 }
2466 }
2467
2468
2/2
✓ Branch 1 taken 328 times.
✓ Branch 2 taken 5624 times.
5952 for (std::size_t i=0; i < m_boundaryConditionList.numRobinBoundaryCondition(); i++) {
2469 328 const BoundaryCondition& BC = *m_boundaryConditionList.Robin(i);
2470 328 const int numComp = static_cast<int>(BC.getComp().size());
2471
2472
1/2
✓ Branch 3 taken 328 times.
✗ Branch 4 not taken.
328 iVariable = m_listVariable.getVariableIdList(BC.getVariable().physicalVariable());
2473 328 idBC = m_boundaryConditionList.idBCOfRobin(i);
2474
1/7
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 328 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
328 switch (BC.typeValueBC()) {
2475 case Constant:
2476 m_elemFieldRobin[i].initialize(CONSTANT_FIELD,numComp);
2477 for (int j = 0; j < numComp; j++) {
2478 valueOfBC.push_back(FelisceParam::instance(this->instanceIndex()).value[m_boundaryConditionList.startIndiceOfValue(idBC)+j]);
2479 }
2480 m_elemFieldRobin[i].setValue(valueOfBC);
2481 break;
2482 case FunctionS:
2483 fe = m_listCurvilinearFiniteElement[iVariable];
2484 FEL_ASSERT(fe);
2485 m_elemFieldRobin[i].initialize(QUAD_POINT_FIELD, *fe,numComp);
2486 break;
2487 case FunctionT:
2488 m_elemFieldRobin[i].initialize(CONSTANT_FIELD,numComp);
2489 break;
2490 case FunctionTS:
2491 fe = m_listCurvilinearFiniteElement[iVariable];
2492 FEL_ASSERT(fe);
2493 m_elemFieldRobin[i].initialize(QUAD_POINT_FIELD, *fe,numComp);
2494 break;
2495 328 case EnsightFile:
2496 328 fe = m_listCurvilinearFiniteElement[iVariable];
2497
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 328 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
328 FEL_ASSERT(fe);
2498
1/2
✓ Branch 2 taken 328 times.
✗ Branch 3 not taken.
328 m_elemFieldRobin[i].initialize(DOF_FIELD, *fe,numComp);
2499 328 break;
2500 case Vector:
2501 FEL_ERROR("Impossible to define elemFieldRobin with this type of Boundary Condition.");
2502 break;
2503 }
2504 328 valueOfBC.clear();
2505
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 328 times.
328 if (m_verbosity > 3) {
2506 std::cout << "Robin: ";
2507 m_elemFieldRobin[i].print(2);
2508 }
2509 }
2510
2511 //RobinNormal
2512
2/2
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 5624 times.
5904 for (std::size_t i=0; i < m_boundaryConditionList.numRobinNormalBoundaryCondition(); i++) {
2513 280 const BoundaryCondition& BC = *m_boundaryConditionList.RobinNormal(i);
2514
2515
1/2
✓ Branch 3 taken 280 times.
✗ Branch 4 not taken.
280 FEL_ASSERT_EQUAL(BC.getComp().size(), 1);
2516
2517
1/2
✓ Branch 3 taken 280 times.
✗ Branch 4 not taken.
280 iVariable = m_listVariable.getVariableIdList(BC.getVariable().physicalVariable());
2518 280 idBC = m_boundaryConditionList.idBCOfRobinNormal(i);
2519
1/7
✓ Branch 1 taken 280 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
280 switch (BC.typeValueBC()) {
2520 280 case Constant:
2521
1/2
✓ Branch 2 taken 280 times.
✗ Branch 3 not taken.
280 m_elemFieldRobinNormal[i].initialize(CONSTANT_FIELD);
2522
3/6
✓ Branch 2 taken 280 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 280 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 280 times.
✗ Branch 9 not taken.
280 if ( static_cast<std::size_t>(m_boundaryConditionList.startIndiceOfValue(idBC)) < FelisceParam::instance(this->instanceIndex()).value.size() ) {
2523
3/6
✓ Branch 1 taken 280 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 280 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 280 times.
✗ Branch 10 not taken.
280 valueOfBC.push_back(FelisceParam::instance(this->instanceIndex()).value[m_boundaryConditionList.startIndiceOfValue(idBC)]);
2524
1/2
✓ Branch 2 taken 280 times.
✗ Branch 3 not taken.
280 m_elemFieldRobinNormal[i].setValue(valueOfBC);
2525 }
2526 280 break;
2527 case FunctionS:
2528 fe = m_listCurvilinearFiniteElement[iVariable];
2529 FEL_ASSERT(fe);
2530 m_elemFieldRobinNormal[i].initialize(QUAD_POINT_FIELD, *fe);
2531 break;
2532 case FunctionT:
2533 m_elemFieldRobinNormal[i].initialize(CONSTANT_FIELD);
2534 break;
2535 case FunctionTS:
2536 fe = m_listCurvilinearFiniteElement[iVariable];
2537 FEL_ASSERT(fe);
2538 m_elemFieldRobinNormal[i].initialize(QUAD_POINT_FIELD, *fe);
2539 break;
2540 case EnsightFile:
2541 fe = m_listCurvilinearFiniteElement[iVariable];
2542 FEL_ASSERT(fe);
2543 m_elemFieldRobinNormal[i].initialize(DOF_FIELD, *fe);
2544 break;
2545 case Vector:
2546 FEL_ERROR("Impossible to define elemFieldRobinNormal with this type of Boundary Condition.");
2547 break;
2548 }
2549
2550 280 valueOfBC.clear();
2551
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
280 if (m_verbosity > 3) {
2552 std::cout << "RobinNormal: ";
2553 m_elemFieldRobinNormal[i].print(2);
2554 }
2555 }
2556
2557 //EmbedFSI new: matteo Feb 2014
2558
2/2
✓ Branch 1 taken 204 times.
✓ Branch 2 taken 5624 times.
5828 for (std::size_t i=0; i < m_boundaryConditionList.numEmbedFSIBoundaryCondition(); i++) {
2559 204 const BoundaryCondition& BC = *m_boundaryConditionList.EmbedFSI(i);
2560
2561
1/2
✓ Branch 3 taken 204 times.
✗ Branch 4 not taken.
204 iVariable = m_listVariable.getVariableIdList(BC.getVariable().physicalVariable());
2562 204 idBC = m_boundaryConditionList.idBCOfEmbedFSI(i);
2563
2564
1/2
✓ Branch 8 taken 204 times.
✗ Branch 9 not taken.
204 FEL_ASSERT_EQUAL( BC.getComp().size(), m_mesh[m_listVariable[iVariable].idMesh()]->domainDim());
2565
1/2
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 FEL_ASSERT_EQUAL( BC.typeValueBC(), EnsightFile);
2566
2567 204 fe = m_listCurvilinearFiniteElement[iVariable];
2568
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 204 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
204 FEL_ASSERT(fe);
2569
2570
1/7
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 204 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
204 switch (BC.typeValueBC()) {
2571 case Constant:
2572 m_elemFieldEmbedFSI[i].initialize(CONSTANT_FIELD);
2573 if ( static_cast<std::size_t>(m_boundaryConditionList.startIndiceOfValue(idBC)) < FelisceParam::instance(this->instanceIndex()).value.size() ) {
2574 valueOfBC.push_back(FelisceParam::instance(this->instanceIndex()).value[m_boundaryConditionList.startIndiceOfValue(idBC)]);
2575 m_elemFieldEmbedFSI[i].setValue(valueOfBC);
2576 }
2577 break;
2578 case FunctionS:
2579 m_elemFieldEmbedFSI[i].initialize(QUAD_POINT_FIELD, *fe, BC.getComp().size());
2580 break;
2581 case FunctionT:
2582 m_elemFieldEmbedFSI[i].initialize(CONSTANT_FIELD, BC.getComp().size());
2583 break;
2584 case FunctionTS:
2585 m_elemFieldEmbedFSI[i].initialize(QUAD_POINT_FIELD, *fe, BC.getComp().size());
2586 break;
2587 204 case EnsightFile:
2588
1/2
✓ Branch 4 taken 204 times.
✗ Branch 5 not taken.
204 m_elemFieldEmbedFSI[i].initialize(DOF_FIELD, *fe, BC.getComp().size());
2589 204 break;
2590 case Vector:
2591 FEL_ERROR("Impossible to define elemFieldEmbedFSI with this type of Boundary Condition.");
2592 break;
2593 }
2594
2595
1/2
✓ Branch 3 taken 204 times.
✗ Branch 4 not taken.
204 m_elemFieldNormalForEmbedFSI[i].initialize( DOF_FIELD, *fe, fe->numCoor() );
2596
1/2
✓ Branch 3 taken 204 times.
✗ Branch 4 not taken.
204 m_elemFieldAlphaForEmbedFSI[i].initialize( DOF_FIELD, *fe, fe->numCoor() );
2597
2598 204 valueOfBC.clear();
2599
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 204 times.
204 if (m_verbosity > 3) {
2600 std::cout << "EmbedFSI: ";
2601 m_elemFieldEmbedFSI[i].print(2);
2602 std::cout << "NormalForEmbedFSI: ";
2603 m_elemFieldNormalForEmbedFSI[i].print(2);
2604 std::cout << "AlphaForEmbedFSI: ";
2605 m_elemFieldAlphaForEmbedFSI[i].print(2);
2606 }
2607 }
2608
2609 // Backflow stabilization, june 2018
2610
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5624 times.
5624 for (std::size_t i=0; i < m_boundaryConditionList.numBackflowStabBoundaryCondition(); i++) {
2611 const BoundaryCondition& BC = *m_boundaryConditionList.BackflowStabBC(i);
2612
2613 FEL_ASSERT_EQUAL(BC.getComp().size(), 1); // for backflow stab use only Comp1 to provide the stab coef
2614
2615 iVariable = m_listVariable.getVariableIdList(BC.getVariable().physicalVariable()); // physicalVariable must be Velocity
2616 idBC = m_boundaryConditionList.idBCOfBackflowStab(i);
2617 switch (BC.typeValueBC()) {
2618 case Constant:
2619 fe = m_listCurvilinearFiniteElement[iVariable];
2620 FEL_ASSERT(fe);
2621 m_elemFieldBackflowStab[i].initialize(DOF_FIELD,*fe,dimension());
2622 break;
2623 default:
2624 FEL_ERROR("For backflow stabilization b.c., the only possible type is 'constant'");
2625 break;
2626 }
2627
2628 valueOfBC.clear();
2629 if (m_verbosity > 3) {
2630 std::cout << "BackflowStab: ";
2631 m_elemFieldBackflowStab[i].print(2);
2632 }
2633 }
2634
2635
1/2
✓ Branch 1 taken 5624 times.
✗ Branch 2 not taken.
5624 allocateElemFieldBoundaryConditionDerivedLinPb(idBCforLinCombMethod);//used in linearProblemNSFracStepProj
2636 5624 }
2637
2638 /***********************************************************************************/
2639 /***********************************************************************************/
2640
2641 200030 void LinearProblem::computeElementArrayBoundaryCondition(const std::vector<Point*>& elemPoint, const std::vector<felInt>& elemIdPoint, felInt& iel, FlagMatrixRHS flagMatrixRHS)
2642 {
2643 IGNORE_UNUSED_FLAG_MATRIX_RHS;
2644 IGNORE_UNUSED_ELEM_ID_POINT;
2645 IGNORE_UNUSED_IEL;
2646 // \todo Dec 2, 2011: Warning: it is inefficient to update all current bd fe here.
2647 // Should depend on the variable where it is necessary (cf boundary condition fields).
2648 // Beside, the normal should not be systematically computed
2649
2650
2/2
✓ Branch 1 taken 598940 times.
✓ Branch 2 taken 200030 times.
798970 for (std::size_t iFe = 0; iFe < m_listCurvilinearFiniteElement.size(); iFe++) {
2651 598940 m_listCurvilinearFiniteElement[iFe]->updateMeasNormal(0, elemPoint);
2652 }
2653 200030 }
2654
2655 /***********************************************************************************/
2656 /***********************************************************************************/
2657
2658 680208 void LinearProblem::applyNaturalBoundaryCondition(const std::vector<Point*>& elemPoint, const std::vector<felInt>& elemIdPoint, felInt& iel, FlagMatrixRHS flagMatrixRHS)
2659 {
2660 IGNORE_UNUSED_IEL;
2661 IGNORE_UNUSED_ELEM_POINT;
2662 IGNORE_UNUSED_ELEM_ID_POINT;
2663 680208 BoundaryCondition* BC = nullptr;
2664 680208 CurvilinearFiniteElement* fe = nullptr;
2665 680208 int iUnknown = -1;
2666 680208 int iblock = -1;
2667 680208 int cptComp = -1;
2668
2669
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 680208 times.
680208 FEL_ASSERT(!m_elementVectorBD.empty());
2670
2671 //Neumann
2672
2/2
✓ Branch 1 taken 174612 times.
✓ Branch 2 taken 680208 times.
854820 for (std::size_t iN=0; iN < m_boundaryConditionList.numNeumannBoundaryCondition(); iN++) {
2673 174612 BC = m_boundaryConditionList.Neumann(iN);
2674 174612 const int iVariable = m_listVariable.getVariableIdList(BC->getVariable().physicalVariable());
2675 174612 iUnknown = BC->getUnknown();
2676 174612 fe = m_listCurvilinearFiniteElement[iVariable];
2677
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 174612 times.
174612 FEL_ASSERT(fe);
2678
2/2
✓ Branch 6 taken 214372 times.
✓ Branch 7 taken 174612 times.
388984 for(auto it_labelNumber = BC->listLabel().begin(); it_labelNumber != BC->listLabel().end(); it_labelNumber++) {
2679
2/2
✓ Branch 1 taken 87008 times.
✓ Branch 2 taken 127364 times.
214372 if(*it_labelNumber == m_currentLabel) {
2680 87008 cptComp = 0;
2681
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 87008 times.
87008 if (m_verbosity>4) {
2682 std::cout << "LABEL = " << m_currentLabel << std::endl;
2683 std::cout << "NEUMANN= ";
2684 m_elemFieldNeumann[iN].print(2);
2685 }
2686
4/4
✓ Branch 0 taken 13120 times.
✓ Branch 1 taken 73888 times.
✓ Branch 2 taken 12960 times.
✓ Branch 3 taken 160 times.
87008 if( (flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs) || (flagMatrixRHS == FlagMatrixRHS::only_rhs)) {
2687
2/2
✓ Branch 5 taken 165808 times.
✓ Branch 6 taken 86848 times.
252656 for(auto it_comp = BC->getComp().begin(); it_comp != BC->getComp().end(); ++it_comp) {
2688
1/2
✓ Branch 2 taken 165808 times.
✗ Branch 3 not taken.
165808 iblock = m_listUnknown.getBlockPosition(iUnknown,*it_comp);
2689
1/2
✓ Branch 4 taken 165808 times.
✗ Branch 5 not taken.
165808 m_elementVectorBD[0]->sourceForComp(1.,*fe,m_elemFieldNeumann[iN],iblock,cptComp);
2690 165808 cptComp++;
2691 }
2692 }
2693 }
2694 }
2695 }
2696
2697 //Neumann Normal
2698
2/2
✓ Branch 1 taken 394088 times.
✓ Branch 2 taken 680208 times.
1074296 for (std::size_t iNN = 0; iNN < m_boundaryConditionList.numNeumannNormalBoundaryCondition(); iNN++) {
2699 394088 BC = m_boundaryConditionList.NeumannNormal(iNN);
2700 394088 const int iVariable = m_listVariable.getVariableIdList(BC->getVariable().physicalVariable());
2701 394088 iUnknown = BC->getUnknown();
2702 394088 fe = m_listCurvilinearFiniteElement[iVariable];
2703
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 394088 times.
394088 FEL_ASSERT(fe);
2704
2/2
✓ Branch 6 taken 394088 times.
✓ Branch 7 taken 394088 times.
788176 for(auto it_labelNumber = BC->listLabel().begin(); it_labelNumber != BC->listLabel().end(); it_labelNumber++) {
2705
2/2
✓ Branch 1 taken 16436 times.
✓ Branch 2 taken 377652 times.
394088 if(*it_labelNumber == m_currentLabel) {
2706
1/2
✓ Branch 1 taken 16436 times.
✗ Branch 2 not taken.
16436 iblock = m_listUnknown.getBlockPosition(iUnknown,0);
2707
2/2
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 15796 times.
16436 if (m_verbosity>3 ) {
2708
3/6
✓ Branch 1 taken 640 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 640 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 640 times.
✗ Branch 8 not taken.
640 std::cout << "LABEL = " << m_currentLabel << std::endl;
2709
1/2
✓ Branch 1 taken 640 times.
✗ Branch 2 not taken.
640 std::cout << "NEUMANN Normal= ";
2710
1/2
✓ Branch 2 taken 640 times.
✗ Branch 3 not taken.
640 m_elemFieldNeumannNormal[iNN].print(2);
2711 }
2712
3/4
✓ Branch 0 taken 1140 times.
✓ Branch 1 taken 15296 times.
✓ Branch 2 taken 1140 times.
✗ Branch 3 not taken.
16436 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs) {
2713
1/2
✓ Branch 4 taken 16436 times.
✗ Branch 5 not taken.
16436 m_elementVectorBD[0]->f_phi_i_scalar_n(1.,*fe,m_elemFieldNeumannNormal[iNN],iblock);
2714 }
2715 }
2716 }
2717 }
2718
2719 //Robin
2720
2/2
✓ Branch 1 taken 19680 times.
✓ Branch 2 taken 680208 times.
699888 for (std::size_t iRobin=0; iRobin<m_boundaryConditionList.numRobinBoundaryCondition(); iRobin++ ) {
2721 19680 BC = m_boundaryConditionList.Robin(iRobin);
2722 19680 const int iVariable = m_listVariable.getVariableIdList(BC->getVariable().physicalVariable());
2723 19680 iUnknown = BC->getUnknown();
2724 19680 fe = m_listCurvilinearFiniteElement[iVariable];
2725
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19680 times.
19680 FEL_ASSERT(fe);
2726
2/2
✓ Branch 6 taken 19680 times.
✓ Branch 7 taken 19680 times.
39360 for(auto it_labelNumber = BC->listLabel().begin(); it_labelNumber != BC->listLabel().end(); it_labelNumber++) {
2727
2/2
✓ Branch 1 taken 6560 times.
✓ Branch 2 taken 13120 times.
19680 if(*it_labelNumber == m_currentLabel) {
2728 6560 cptComp = 0;
2729
1/2
✓ Branch 1 taken 6560 times.
✗ Branch 2 not taken.
6560 iblock = m_listUnknown.getBlockPosition(iUnknown,0);
2730
2731
2/4
✓ Branch 1 taken 6560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6560 times.
✗ Branch 5 not taken.
6560 double coef = FelisceParam::instance(this->instanceIndex()).alphaRobin[iRobin]; //default 0
2732
2/4
✓ Branch 1 taken 6560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6560 times.
✗ Branch 5 not taken.
6560 const double coef2= FelisceParam::instance(this->instanceIndex()).betaRobin[iRobin]; //default 1
2733 6560 coef=coef/coef2;
2734
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6560 times.
6560 if (m_verbosity>3 ) {
2735 std::cout << "LABEL = " << m_currentLabel << std::endl;
2736 std::cout << "ROBIN = ";
2737 m_elemFieldRobin[iRobin].print(2);
2738 std::cout<< "coef "<<coef<< " coef2 "<<coef2<<std::endl;
2739 }
2740
3/4
✓ Branch 0 taken 6560 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 6480 times.
6560 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix) {
2741
1/2
✓ Branch 5 taken 80 times.
✗ Branch 6 not taken.
80 m_elementMatBD[0]->phi_i_phi_j(coef,*fe,iblock,iblock,m_listVariable[iVariable].numComponent());
2742 }
2743
3/4
✓ Branch 0 taken 6560 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6480 times.
✓ Branch 3 taken 80 times.
6560 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs) {
2744
2/2
✓ Branch 5 taken 6480 times.
✓ Branch 6 taken 6480 times.
12960 for(auto it_comp = BC->getComp().begin(); it_comp != BC->getComp().end(); ++it_comp) {
2745
1/2
✓ Branch 2 taken 6480 times.
✗ Branch 3 not taken.
6480 iblock = m_listUnknown.getBlockPosition(iUnknown,*it_comp);
2746
1/2
✓ Branch 4 taken 6480 times.
✗ Branch 5 not taken.
6480 m_elementVectorBD[0]->sourceForComp(1./coef2,*fe,m_elemFieldRobin[iRobin],iblock,cptComp);
2747 6480 cptComp++;
2748 }
2749 }
2750
2751 }
2752 }
2753 }
2754
2755 //RobinNormal
2756
2/2
✓ Branch 1 taken 179200 times.
✓ Branch 2 taken 680208 times.
859408 for (std::size_t iRobinNormal=0; iRobinNormal<m_boundaryConditionList.numRobinNormalBoundaryCondition(); iRobinNormal++ ) {
2757 179200 BC = m_boundaryConditionList.RobinNormal(iRobinNormal);
2758 179200 const int iVariable = m_listVariable.getVariableIdList(BC->getVariable().physicalVariable());
2759 179200 fe = m_listCurvilinearFiniteElement[iVariable];
2760 179200 iUnknown = BC->getUnknown();
2761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 179200 times.
179200 FEL_ASSERT(fe);
2762
2/2
✓ Branch 6 taken 179200 times.
✓ Branch 7 taken 179200 times.
358400 for(auto it_labelNumber = BC->listLabel().begin(); it_labelNumber != BC->listLabel().end(); it_labelNumber++) {
2763
2/2
✓ Branch 1 taken 44800 times.
✓ Branch 2 taken 134400 times.
179200 if(*it_labelNumber == m_currentLabel) {
2764
1/2
✓ Branch 1 taken 44800 times.
✗ Branch 2 not taken.
44800 iblock = m_listUnknown.getBlockPosition(iUnknown,0);
2765
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44800 times.
44800 if (m_verbosity>3 ) {
2766 std::cout << "LABEL = " << m_currentLabel << std::endl;
2767 std::cout << "RobinNormal = ";
2768 m_elemFieldRobinNormal[iRobinNormal].print(2);
2769 }
2770
2/4
✓ Branch 1 taken 44800 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 44800 times.
✗ Branch 5 not taken.
44800 double coef = FelisceParam::instance(this->instanceIndex()).alphaRobinNormal[iRobinNormal];
2771
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 44800 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
44800 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix) {
2772
1/2
✓ Branch 3 taken 44800 times.
✗ Branch 4 not taken.
44800 m_elementMatBD[0]->phi_i_dot_n_phi_j_dot_n(coef, *fe, iblock, iblock, 0);
2773 }
2774
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 44800 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
44800 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs) {
2775
1/2
✓ Branch 4 taken 44800 times.
✗ Branch 5 not taken.
44800 m_elementVectorBD[0]->f_phi_i_scalar_n(1.,*fe,m_elemFieldRobinNormal[iRobinNormal],iblock);
2776 }
2777 }
2778 }
2779 }
2780
2781 //EmbedFSI
2782
2/2
✓ Branch 1 taken 202344 times.
✓ Branch 2 taken 680208 times.
882552 for (std::size_t iEmbedFSI=0; iEmbedFSI<m_boundaryConditionList.numEmbedFSIBoundaryCondition(); iEmbedFSI++ ) {
2783 //Identifying the variables
2784 202344 const int iUnknownPres = m_listUnknown.getUnknownIdList(pressure);
2785 202344 const int idVarPres = m_listUnknown.idVariable(iUnknownPres);
2786 202344 const int iMeshPres = m_listVariable[idVarPres].idMesh();
2787 202344 const int iUnknownVel = m_listUnknown.getUnknownIdList(velocity);
2788 202344 const int idVarVel = m_listUnknown.idVariable(iUnknownVel);
2789 202344 const int iMeshVel = m_listVariable[idVarVel].idMesh();
2790
2791
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 202344 times.
202344 if ( iMeshPres != iMeshVel )
2792 FEL_ERROR("Variables must be defined on same mesh");
2793
2794
2795 202344 CurvilinearFiniteElement& fePres = *m_listCurvilinearFiniteElement[idVarPres];
2796 202344 fePres.updateMeasNormal(0, elemPoint);
2797
2798 // Retriving the Curvlinear FE (as usual..)
2799 202344 BC = m_boundaryConditionList.EmbedFSI(iEmbedFSI);
2800 202344 fe = m_listCurvilinearFiniteElement[idVarVel];
2801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 202344 times.
202344 FEL_ASSERT(fe);
2802 202344 fe->updateMeasNormal(0, elemPoint); //maybe it is not needed here
2803
2804
2/2
✓ Branch 6 taken 2580720 times.
✓ Branch 7 taken 202344 times.
2783064 for(auto it_labelNumber = BC->listLabel().begin(); it_labelNumber != BC->listLabel().end(); it_labelNumber++ ) {
2805
2/2
✓ Branch 1 taken 196477 times.
✓ Branch 2 taken 2384243 times.
2580720 if( *it_labelNumber == m_currentLabel ) {
2806
2807 196477 cptComp = 0;
2808
1/2
✓ Branch 1 taken 196477 times.
✗ Branch 2 not taken.
196477 iblock = m_listUnknown.getBlockPosition(iUnknownVel,0);
2809
1/2
✓ Branch 1 taken 196477 times.
✗ Branch 2 not taken.
196477 int presBlock = m_listUnknown.getBlockPosition(iUnknownPres,0);
2810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 196477 times.
196477 if (m_verbosity>3 ) {
2811 std::cout << "LABEL = " << m_currentLabel << std::endl;
2812 std::cout << "EmbedFSI = ";
2813 m_elemFieldEmbedFSI[iEmbedFSI].print(2);
2814 std::cout << "Normal for EmbedFSI = ";
2815 m_elemFieldNormalForEmbedFSI[iEmbedFSI].print(2);
2816 std::cout << "Alpha for EmbedFSI = ";
2817 m_elemFieldAlphaForEmbedFSI[iEmbedFSI].print(2);
2818 }
2819
2820
2/4
✓ Branch 1 taken 196477 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 196477 times.
✗ Branch 5 not taken.
196477 const double PenalizationParameter = FelisceParam::instance(this->instanceIndex()).penValueForEmbedFSI;
2821
2822
3/4
✓ Branch 0 taken 2800 times.
✓ Branch 1 taken 193677 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2800 times.
196477 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix ) {
2823 //first order transpiration
2824 //penalization of -p, we do that on the nodes!
2825
1/2
✓ Branch 4 taken 193677 times.
✗ Branch 5 not taken.
193677 m_elementMatBD[0]->psi_j_phi_i_dot_n_on_nodes(-PenalizationParameter, m_elemFieldNormalForEmbedFSI[iEmbedFSI], *fe, fePres, iblock, presBlock);
2826
1/2
✓ Branch 6 taken 193677 times.
✗ Branch 7 not taken.
193677 m_elementMatBD[0]->a_phi_i_phi_j( PenalizationParameter, m_elemFieldAlphaForEmbedFSI[iEmbedFSI], *fe, iblock,iblock, m_listVariable[idVarVel].numComponent());
2827 }
2828
2829
3/4
✓ Branch 0 taken 2800 times.
✓ Branch 1 taken 193677 times.
✓ Branch 2 taken 2800 times.
✗ Branch 3 not taken.
196477 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs) {
2830 // first order transpiration + force term
2831
1/2
✓ Branch 7 taken 196477 times.
✗ Branch 8 not taken.
196477 m_elementVectorBD[0]->source( PenalizationParameter, *fe, m_elemFieldEmbedFSI[iEmbedFSI], iblock, m_mesh[iMeshVel]->domainDim());
2832 }
2833 }
2834 }
2835 }
2836
2837 //Backflow stab
2838
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 680208 times.
680208 for (std::size_t iBackflow=0; iBackflow<m_boundaryConditionList.numBackflowStabBoundaryCondition(); iBackflow++ ) {
2839 BC = m_boundaryConditionList.BackflowStabBC(iBackflow);
2840 const int iVelocity = m_listVariable.getVariableIdList(BC->getVariable().physicalVariable());
2841 fe = m_listCurvilinearFiniteElement[iVelocity];
2842 iUnknown = BC->getUnknown();
2843 FEL_ASSERT(fe);
2844 for(auto it_labelNumber = BC->listLabel().begin(); it_labelNumber != BC->listLabel().end(); it_labelNumber++) {
2845 if(*it_labelNumber == m_currentLabel) {
2846 iblock = m_listUnknown.getBlockPosition(iUnknown,0);
2847 if (m_verbosity>3 ) {
2848 std::cout << "LABEL = " << m_currentLabel << std::endl;
2849 std::cout << "BackflowStab = ";
2850 m_elemFieldBackflowStab[iBackflow].print(2);
2851 }
2852 std::size_t idBC = m_boundaryConditionList.idBCOfBackflowStab( iBackflow );
2853 double coef = FelisceParam::instance(this->instanceIndex()).value[m_boundaryConditionList.startIndiceOfValue(idBC)]*FelisceParam::instance(this->instanceIndex()).density;
2854 m_elemFieldBackflowStab[iBackflow].setValue(sequentialSolution(),*fe, iel, iVelocity, m_ao, dof());
2855 m_elementMatBD[0]->f_dot_n_phi_i_phi_j(-coef,*fe,m_elemFieldBackflowStab[iBackflow], 0, 0, this->dimension(),2);
2856 if(flagMatrixRHS == FlagMatrixRHS::only_rhs) {
2857 std::cout << "WARNING !!!! Strange to assemble only the RHS std::vector if you want bacflow stab. To be checked ?" << std::endl;
2858 }
2859 }
2860 }
2861 }
2862 680208 }
2863
2864 /***********************************************************************************/
2865 /***********************************************************************************/
2866
2867 void LinearProblem::computeAndApplyElementNaturalBoundaryCondition(const std::vector<Point*>& elemPoint, const std::vector<felInt>& elemIdPoint, felInt& ielSupportDof1, felInt& ielSupportDof2, felInt& ielGeoGlobal, FlagMatrixRHS flagMatrixRHS)
2868 {
2869 IGNORE_UNUSED_ARGUMENT(ielSupportDof2);
2870 IGNORE_UNUSED_ARGUMENT(ielGeoGlobal);
2871 // function call in derived problem to compute specific operators of the problem (Heat, N-S,...).initialized in (1)
2872 computeElementArrayBoundaryCondition(elemPoint, elemIdPoint, ielSupportDof1, flagMatrixRHS);
2873 // compute specific term of users (Neumann transient for example) initialized in (2)
2874 // It seems to be unnecessary to pass currentLabel to this function.
2875 // In fact similar functions such as userElementCompute does not require this argument.
2876 userElementComputeNaturalBoundaryCondition(elemPoint, elemIdPoint, ielSupportDof1, ielSupportDof2, ielGeoGlobal, m_currentLabel);
2877 // apply bc initialized in (3) if constant or initialized in (1) or (2) if functions
2878 applyNaturalBoundaryCondition(elemPoint, elemIdPoint, ielSupportDof1, flagMatrixRHS);
2879 }
2880
2881 /***********************************************************************************/
2882 /***********************************************************************************/
2883
2884 513 void LinearProblem::defineBC()
2885 {
2886 //TODO:
2887 // maybe variables are no longer needed
2888 // for now I have improved the comments (matteo)
2889 // I changed the parts when a not-unknown variable is found (the elses where the fake BC was created)
2890 513 int iVar = 0;
2891
1/2
✓ Branch 1 taken 513 times.
✗ Branch 2 not taken.
513 Variable variable;
2892 513 std::vector <int> listTmp;
2893 513 int start = 0;
2894 513 int startValue = 0;
2895 513 bool unknownFound = false;
2896 513 int idUnknown = -1;
2897 // for each boundary condition
2898
4/6
✓ Branch 1 taken 2001 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2001 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1488 times.
✓ Branch 8 taken 513 times.
2001 for ( std::size_t i = 0; i < FelisceParam::instance(this->instanceIndex()).type.size(); i++) {
2899 // if we remove the distinction between variables and unknowns (so that we only have unknowns)
2900 // the code would be something like
2901 // variable = FelisceParam.instance().variable[i];
2902 // some type convertion on variable
2903 // if variable in variableList:
2904 // create the BC
2905 // else
2906 // skip it
2907 //
2908 // and all this part > > >
2909 // get the variable associated to the boundary condition
2910
2911
4/8
✓ Branch 1 taken 1488 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1488 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1488 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1488 times.
✗ Branch 12 not taken.
1488 iVar = m_listVariable.getVariableIdList(FelisceParam::instance(this->instanceIndex()).variable[i]);
2912 // if the read variable belongs to a different linearProblem,but in the same model it may not be present in the varialelist: hence this check
2913
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1488 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
1488 FEL_CHECK(iVar>=0,"hello, You have to declare all the variables of the model into each linear problem")
2914
1/2
✓ Branch 2 taken 1488 times.
✗ Branch 3 not taken.
1488 variable = m_listVariable[iVar];
2915 // reset flag
2916 1488 unknownFound = false;
2917
6/6
✓ Branch 1 taken 2144 times.
✓ Branch 2 taken 1091 times.
✓ Branch 3 taken 1747 times.
✓ Branch 4 taken 397 times.
✓ Branch 5 taken 1747 times.
✓ Branch 6 taken 1488 times.
3235 for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size() && unknownFound == false ; iUnknown++) {
2918
2/2
✓ Branch 1 taken 1150 times.
✓ Branch 2 taken 597 times.
1747 if ( m_listUnknown.idVariable(iUnknown) == iVar) {
2919 1150 idUnknown = iUnknown;
2920 1150 unknownFound = true;
2921 }
2922 }
2923
2924
2/2
✓ Branch 0 taken 1150 times.
✓ Branch 1 taken 338 times.
1488 if (unknownFound) { // if it is an unknown:
2925 // for each of the label associated to that BC, store the labels in the listTmp //TODO rename listTmp
2926
4/6
✓ Branch 1 taken 2670 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2670 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1520 times.
✓ Branch 8 taken 1150 times.
2670 for (int j = 0; j < FelisceParam::instance(this->instanceIndex()).numLabel[i]; j++)
2927
3/6
✓ Branch 1 taken 1520 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1520 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1520 times.
✗ Branch 9 not taken.
1520 listTmp.push_back(FelisceParam::instance(this->instanceIndex()).label[j+start]);
2928
2/4
✓ Branch 1 taken 1150 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1150 times.
✗ Branch 5 not taken.
1150 start += FelisceParam::instance(this->instanceIndex()).numLabel[i];
2929
2930 // create the object bc
2931
8/16
✓ Branch 1 taken 1150 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1150 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1150 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1150 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1150 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1150 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 1150 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1150 times.
✗ Branch 26 not taken.
1150 BoundaryCondition* bc = new BoundaryCondition(FelisceParam::instance(this->instanceIndex()).type[i], FelisceParam::instance(this->instanceIndex()).typeValue[i], listTmp, variable, FelisceParam::instance(this->instanceIndex()).component[i]);
2932 //set its unknown id
2933 1150 bc->setUnknown(idUnknown);
2934
2935 // get the correct starting point for reading the values: PAY ATTENTION even if the type of the BC is not constant you have to define a number in the data file!
2936 1150 startValue += bc->getComp().size();
2937
3/4
✓ Branch 1 taken 1150 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 503 times.
✓ Branch 4 taken 647 times.
1150 if (m_boundaryConditionList.size() == 0) //if it is the first BC to be added in the list
2938
1/2
✓ Branch 4 taken 503 times.
✗ Branch 5 not taken.
503 m_boundaryConditionList.startIndiceOfValue().push_back(startValue - bc->getComp().size()); //this is not simply zero.
2939
2940 // add the starting value
2941
1/2
✓ Branch 2 taken 1150 times.
✗ Branch 3 not taken.
1150 m_boundaryConditionList.startIndiceOfValue().push_back(startValue);
2942 //add also the BC
2943
1/2
✓ Branch 1 taken 1150 times.
✗ Branch 2 not taken.
1150 m_boundaryConditionList.add(bc);
2944 //clear the list of labels
2945 1150 listTmp.clear();
2946 } else {
2947 // now it is not necessary to create a BC
2948
3/6
✓ Branch 1 taken 338 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 338 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 338 times.
✗ Branch 9 not taken.
338 startValue += BoundaryCondition::determineNumComponent( FelisceParam::instance(this->instanceIndex()).component[i] );
2949
2/4
✓ Branch 1 taken 338 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 338 times.
✗ Branch 5 not taken.
338 start += FelisceParam::instance(this->instanceIndex()).numLabel[i];
2950 }
2951 }
2952
2953
4/6
✓ Branch 1 taken 513 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 513 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 28 times.
✓ Branch 8 taken 485 times.
513 if (FelisceParam::instance(this->instanceIndex()).lumpedModelBCLabel.size()>0) {
2954 // explicit/implicit and fractional step model // TODO D.C. why are here??? maybe these conditions should be in the appropriate linearProblem...
2955 //====================================
2956
4/6
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 16 times.
✓ Branch 8 taken 12 times.
28 if(FelisceParam::instance(this->instanceIndex()).model == "NSFracStep") {
2957
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 iVar = m_listVariable.getVariableIdList(pressure);
2958
1/2
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
16 variable = m_listVariable[iVar];
2959
4/6
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 32 times.
✓ Branch 8 taken 16 times.
48 for ( std::size_t i = 0; i < FelisceParam::instance(this->instanceIndex()).lumpedModelBCLabel.size(); i++) {
2960
3/6
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 32 times.
✗ Branch 8 not taken.
32 if(FelisceParam::instance(this->instanceIndex()).lumpedModelBCAlgo[i] == 1) {
2961
6/6
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 24 times.
✓ Branch 6 taken 32 times.
56 for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size() && unknownFound == false ; iUnknown++) {
2962
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 8 times.
24 if (m_listUnknown.idVariable(iUnknown) == iVar) {
2963 16 idUnknown = iUnknown;
2964 16 unknownFound = true;
2965 }
2966 }
2967
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
32 if (unknownFound) {
2968
4/8
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 24 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 24 times.
✗ Branch 12 not taken.
24 BoundaryCondition* BC = new BoundaryCondition(EssentialLumpedModelBC,Constant,FelisceParam::instance(this->instanceIndex()).lumpedModelBCLabel[i],variable,Comp1);
2969 24 BC->getUnknown() = idUnknown;
2970
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 m_boundaryConditionList.add(BC);
2971 }
2972 32 unknownFound = false;
2973 } else if(FelisceParam::instance(this->instanceIndex()).lumpedModelBCAlgo[i] == 2) {
2974 FEL_ERROR("LinearProblem::defineBC() : check the implicit algo with NSFracStep model");
2975 }
2976 }
2977 }
2978
3/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
12 else if(FelisceParam::instance(this->instanceIndex()).model == "NS") { // explicit/implicit and monolithic model
2979
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 iVar = m_listVariable.getVariableIdList(velocity);
2980
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 variable = m_listVariable[iVar];
2981
4/6
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 24 times.
✓ Branch 8 taken 12 times.
36 for ( std::size_t i = 0; i < FelisceParam::instance(this->instanceIndex()).lumpedModelBCLabel.size(); i++) {
2982
4/14
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 24 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 24 times.
✗ Branch 19 not taken.
24 if(FelisceParam::instance(this->instanceIndex()).lumpedModelBCAlgo[i] == 1 || FelisceParam::instance(this->instanceIndex()).lumpedModelBCAlgo[i] == 2) {
2983
5/6
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 24 times.
36 for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size() && unknownFound == false ; iUnknown++) {
2984
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if ( m_listUnknown.idVariable(iUnknown) == iVar) {
2985 12 idUnknown = iUnknown;
2986 12 unknownFound = true;
2987 }
2988 }
2989
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (unknownFound) {
2990
4/8
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 24 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 24 times.
✗ Branch 12 not taken.
24 BoundaryCondition* BC = new BoundaryCondition(NaturalLumpedModelBC,Constant,FelisceParam::instance(this->instanceIndex()).lumpedModelBCLabel[i],variable,Comp1);
2991 24 BC->getUnknown() = idUnknown;
2992
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 m_boundaryConditionList.add(BC);
2993 }
2994 24 unknownFound = false;
2995 }
2996 }
2997 }
2998 else if(FelisceParam::instance(this->instanceIndex()).model == "NSlinComb") { // implicit and NSlinCombModel
2999 // we define the lumpedModel BC as NeumannNormal boundary conditions
3000 iVar = m_listVariable.getVariableIdList(velocity);
3001 variable = m_listVariable[iVar];
3002 for ( std::size_t i = 0; i < FelisceParam::instance(this->instanceIndex()).lumpedModelBCLabel.size(); i++) {
3003 if(FelisceParam::instance(this->instanceIndex()).lumpedModelBCAlgo[i] == 2) {
3004 for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size() && unknownFound == false ; iUnknown++) {
3005 if ( m_listUnknown.idVariable(iUnknown) == iVar) {
3006 idUnknown = iUnknown;
3007 unknownFound = true;
3008 }
3009 }
3010 if (unknownFound) {
3011 BoundaryCondition* BC = new BoundaryCondition(NeumannNormal,Constant,FelisceParam::instance(this->instanceIndex()).lumpedModelBCLabel[i],variable,Comp1);
3012 BC->getUnknown() = idUnknown;
3013 // define startIndiceOfValue for 'artificial' NN BC
3014 startValue += BC->getComp().size();
3015 if (m_boundaryConditionList.size() == 0)
3016 m_boundaryConditionList.startIndiceOfValue().push_back(startValue - BC->getComp().size());
3017 m_boundaryConditionList.startIndiceOfValue().push_back(startValue);
3018 m_boundaryConditionList.add(BC);
3019 } else {
3020 //OLD
3021 //BoundaryCondition bc(NeumannNormal, Constant, FelisceParam::instance().lumpedModelBCLabel[i],variable, Comp1);
3022 //startValue += bc.getComp().size();
3023 //NEW
3024 startValue += BoundaryCondition::determineNumComponent( FelisceParam::instance(this->instanceIndex()).component[i] );
3025 }
3026 unknownFound = false;
3027 }
3028 }
3029 }
3030 else { // default case
3031 FEL_ERROR("You have to use the right model with the right algorithm for lumpedModelBC boundary conditions : explicit algorithm is implemented with NSModel or NSFracStepModel, and implicit one with NSModel or NSlinCombModel. You have to take care in your datafile.");
3032 }
3033 }
3034
3035
1/2
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
513 m_elemFieldNeumann.resize(m_boundaryConditionList.numNeumannBoundaryCondition());
3036
1/2
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
513 m_elemFieldNeumannNormal.resize(m_boundaryConditionList.numNeumannNormalBoundaryCondition());
3037
1/2
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
513 m_elemFieldRobin.resize(m_boundaryConditionList.numRobinBoundaryCondition());
3038
1/2
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
513 m_elemFieldRobinNormal.resize(m_boundaryConditionList.numRobinNormalBoundaryCondition());
3039
1/2
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
513 m_elemFieldEmbedFSI.resize(m_boundaryConditionList.numEmbedFSIBoundaryCondition());
3040
1/2
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
513 m_elemFieldNormalForEmbedFSI.resize(m_boundaryConditionList.numEmbedFSIBoundaryCondition());
3041
1/2
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
513 m_elemFieldAlphaForEmbedFSI.resize(m_boundaryConditionList.numEmbedFSIBoundaryCondition());
3042
1/2
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
513 m_elemFieldBackflowStab.resize(m_boundaryConditionList.numBackflowStabBoundaryCondition());
3043 513 }
3044
3045 /***********************************************************************************/
3046 /***********************************************************************************/
3047
3048 template<>
3049 void LinearProblem::applyEssentialBoundaryConditionHelper<DirichletApplicationOptions::symmetricPseudoElimination>(FlagMatrixRHS flagMatrixRHS)
3050 {
3051 std::vector<felInt> rows;
3052 for (int i=0, numDirichletBC = m_boundaryConditionList.numDirichletBoundaryCondition(); i < numDirichletBC; i++) {
3053 const BoundaryCondition* const BC = m_boundaryConditionList.Dirichlet(i);
3054 applyEssentialBoundaryConditionViaSymmetricPseudoEliminationOnBC(flagMatrixRHS,BC,rows);
3055 }
3056 m_matrices[0].zeroRowsColumns(rows.size(), &rows[0], 1.);
3057 }
3058
3059 /***********************************************************************************/
3060 /***********************************************************************************/
3061
3062 template<>
3063 29355 void LinearProblem::applyEssentialBoundaryConditionHelper<DirichletApplicationOptions::nonSymmetricPseudoElimination>(FlagMatrixRHS flagMatrixRHS)
3064 {
3065 29355 std::unordered_set<felInt> idDofBC;
3066 29355 std::unordered_map<felInt, double> idBCAndValue;
3067 29355 std::unordered_set<felInt> idDofOfAllDirichletBC;
3068
3069
2/2
✓ Branch 1 taken 53672 times.
✓ Branch 2 taken 29355 times.
83027 for (std::size_t i=0; i < m_boundaryConditionList.numDirichletBoundaryCondition(); i++) {
3070 53672 const BoundaryCondition* BC = m_boundaryConditionList.Dirichlet(i);
3071 53672 idBCAndValue.clear();
3072 53672 idDofBC.clear();
3073
3074
1/2
✓ Branch 1 taken 53672 times.
✗ Branch 2 not taken.
53672 getListDofOfBC(*BC, idDofBC, idBCAndValue);
3075
3076
2/2
✓ Branch 4 taken 1933333 times.
✓ Branch 5 taken 53672 times.
1987005 for(auto itDofBC = idDofBC.begin(); itDofBC != idDofBC.end(); ++itDofBC) {
3077
1/2
✓ Branch 2 taken 1933333 times.
✗ Branch 3 not taken.
1933333 idDofOfAllDirichletBC.insert(*itDofBC);
3078
4/4
✓ Branch 0 taken 378353 times.
✓ Branch 1 taken 1554980 times.
✓ Branch 2 taken 155780 times.
✓ Branch 3 taken 222573 times.
1933333 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs) {
3079
2/4
✓ Branch 3 taken 1710760 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1710760 times.
✗ Branch 8 not taken.
1710760 vector().setValue(*itDofBC, idBCAndValue[*itDofBC], INSERT_VALUES);
3080 }
3081 }
3082 }
3083
3084 // Get the number of dof in each process for all Dirichlet BC
3085
1/2
✓ Branch 1 taken 29355 times.
✗ Branch 2 not taken.
29355 int sizeTmp[MpiInfo::numProc()];
3086
1/2
✓ Branch 1 taken 29355 times.
✗ Branch 2 not taken.
29355 int sizeDofBC[MpiInfo::numProc()];
3087
3/4
✓ Branch 1 taken 140978 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 111623 times.
✓ Branch 4 taken 29355 times.
140978 for (int rankProc = 0; rankProc < MpiInfo::numProc(); rankProc++) {
3088 111623 sizeTmp[rankProc] = 0;
3089 }
3090
3091
1/2
✓ Branch 2 taken 29355 times.
✗ Branch 3 not taken.
29355 sizeTmp[MpiInfo::rankProc()] = idDofOfAllDirichletBC.size();
3092
3093
3/6
✓ Branch 1 taken 29355 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 29355 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 29355 times.
✗ Branch 8 not taken.
29355 MPI_Allreduce(sizeTmp, sizeDofBC, MpiInfo::numProc(), MPI_INT, MPI_SUM, MpiInfo::petscComm());
3094
3095 29355 int startDof = 0;
3096
3/4
✓ Branch 1 taken 70489 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 41134 times.
✓ Branch 4 taken 29355 times.
70489 for (int rankProc = 0; rankProc < MpiInfo::rankProc(); rankProc++) {
3097 41134 startDof += sizeDofBC[rankProc];
3098 }
3099
3100 // get the number of dof in all processes = sum of sizeDofBC[] (some dof are counted several times)
3101 29355 int numDofBCTotal = 0;
3102
3/4
✓ Branch 1 taken 140978 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 111623 times.
✓ Branch 4 taken 29355 times.
140978 for (int rankProc = 0; rankProc < MpiInfo::numProc(); rankProc++) {
3103 111623 numDofBCTotal += sizeDofBC[rankProc];
3104 }
3105
3106 // put all the id dof in an array (some dof are counted several times)
3107 29355 int dofBCTmp[numDofBCTotal];
3108 29355 int dofBCArray[numDofBCTotal];
3109
2/2
✓ Branch 0 taken 7102342 times.
✓ Branch 1 taken 29355 times.
7131697 for (int iDof = 0; iDof < numDofBCTotal; iDof++)
3110 7102342 dofBCTmp[iDof] = 0;
3111
3112 29355 int iDof = 0;
3113
2/2
✓ Branch 3 taken 1915828 times.
✓ Branch 4 taken 29355 times.
1945183 for(auto itDofBC = idDofOfAllDirichletBC.begin(); itDofBC != idDofOfAllDirichletBC.end(); ++itDofBC) {
3114 1915828 dofBCTmp[startDof + iDof] = *itDofBC;
3115 1915828 iDof++;
3116 }
3117
3118
2/4
✓ Branch 1 taken 29355 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 29355 times.
✗ Branch 5 not taken.
29355 MPI_Allreduce(&dofBCTmp[0], &dofBCArray[0], numDofBCTotal, MPI_INT, MPI_SUM, MpiInfo::petscComm());
3119
3120 // rearrange the id dof in the increasing order (each dof is counted only once)
3121 29355 idDofOfAllDirichletBC.clear();
3122
2/2
✓ Branch 0 taken 7102342 times.
✓ Branch 1 taken 29355 times.
7131697 for (int iDof2 = 0; iDof2 < numDofBCTotal; iDof2++) {
3123
1/2
✓ Branch 1 taken 7102342 times.
✗ Branch 2 not taken.
7102342 idDofOfAllDirichletBC.insert(dofBCArray[iDof2]);
3124 }
3125 29355 numDofBCTotal = idDofOfAllDirichletBC.size();
3126
3127 29355 iDof = 0;
3128
2/2
✓ Branch 3 taken 6424778 times.
✓ Branch 4 taken 29355 times.
6454133 for(auto itDofBC = idDofOfAllDirichletBC.begin(); itDofBC != idDofOfAllDirichletBC.end(); ++itDofBC) {
3129 6424778 dofBCArray[iDof] = *itDofBC;
3130 6424778 iDof++;
3131 }
3132
3133
4/4
✓ Branch 0 taken 3434 times.
✓ Branch 1 taken 25921 times.
✓ Branch 2 taken 1436 times.
✓ Branch 3 taken 1998 times.
29355 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix) {
3134
1/2
✓ Branch 2 taken 27357 times.
✗ Branch 3 not taken.
27357 m_matrices[0].zeroRows(numDofBCTotal, &dofBCArray[0], 1.0);
3135 }
3136 58710 }
3137
3138 /***********************************************************************************/
3139 /***********************************************************************************/
3140
3141 template<>
3142 void LinearProblem::applyEssentialBoundaryConditionHelper<DirichletApplicationOptions::penalization>(FlagMatrixRHS flagMatrixRHS)
3143 {
3144 for (std::size_t i=0; i < m_boundaryConditionList.numDirichletBoundaryCondition(); i++) {
3145 const BoundaryCondition* BC = m_boundaryConditionList.Dirichlet(i);
3146 applyEssentialBoundaryConditionViaPenalizationOnBC(flagMatrixRHS,BC);
3147 }
3148 }
3149
3150 /***********************************************************************************/
3151 /***********************************************************************************/
3152
3153 29355 void LinearProblem::applyEssentialBoundaryCondition(int applicationOption, int rank, FlagMatrixRHS flagMatrixRHS)
3154 {
3155
1/4
✓ Branch 0 taken 29355 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
29355 switch (applicationOption) {
3156 29355 case DirichletApplicationOptions::nonSymmetricPseudoElimination:
3157 29355 applyEssentialBoundaryConditionHelper<DirichletApplicationOptions::nonSymmetricPseudoElimination>(flagMatrixRHS);
3158 29355 break;
3159 case DirichletApplicationOptions::symmetricPseudoElimination:
3160 applyEssentialBoundaryConditionHelper<DirichletApplicationOptions::symmetricPseudoElimination>(flagMatrixRHS);
3161 break;
3162 case DirichletApplicationOptions::penalization:
3163 applyEssentialBoundaryConditionHelper<DirichletApplicationOptions::penalization>(flagMatrixRHS);
3164 break;
3165 default:
3166 FEL_ERROR("Three methods only: nonSymmetricPseudoElimination, symmetricPseudoElimination and penalization");
3167 }
3168
3169
4/8
✓ Branch 3 taken 360 times.
✓ Branch 4 taken 28995 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 360 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 29355 times.
29355 if (FelisceParam::instance(this->instanceIndex()).lumpedModelBCLabel.size()>0 && applicationOption!=0 && FelisceParam::instance(this->instanceIndex()).model == "NSFracStep")
3170 FEL_ERROR("Only one method is implemented to apply lumpedModelBC boundary conditons with fractional step method");
3171
3172 // Other essential boundary conditions
3173 29355 applyEssentialBoundaryConditionDerivedProblem(rank,flagMatrixRHS);
3174
3175
4/4
✓ Branch 0 taken 3434 times.
✓ Branch 1 taken 25921 times.
✓ Branch 2 taken 1436 times.
✓ Branch 3 taken 1998 times.
29355 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix) {
3176 27357 m_matrices[0].assembly(MAT_FINAL_ASSEMBLY);
3177 }
3178
3179
4/4
✓ Branch 0 taken 3434 times.
✓ Branch 1 taken 25921 times.
✓ Branch 2 taken 1998 times.
✓ Branch 3 taken 1436 times.
29355 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs) {
3180 27919 vector().assembly();
3181 }
3182 29355 }
3183
3184 /***********************************************************************************/
3185 /***********************************************************************************/
3186
3187 524 void LinearProblem::determineDofAssociateToLabel()
3188 {
3189 BoundaryCondition* BC;
3190
3191
2/2
✓ Branch 1 taken 1028 times.
✓ Branch 2 taken 524 times.
1552 for (std::size_t idbc = 0 ; idbc < m_boundaryConditionList.numDirichletBoundaryCondition(); idbc ++) {
3192 1028 BC = m_boundaryConditionList.Dirichlet(idbc);
3193 1028 determineElementSuppDofAssociateToBC(BC);
3194 }
3195
3196
2/2
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 524 times.
548 for (std::size_t ilpbc = 0; ilpbc < m_boundaryConditionList.numEssentialLumpedModelBoundaryCondition(); ilpbc ++) {
3197 24 BC = m_boundaryConditionList.EssentialLumpedModelBC(ilpbc);
3198 24 determineElementSuppDofAssociateToBC(BC);
3199 }
3200 524 }
3201
3202 /***********************************************************************************/
3203 /***********************************************************************************/
3204
3205 1052 void LinearProblem::determineElementSuppDofAssociateToBC(BoundaryCondition* BC)
3206 {
3207 ElementType eltType;
3208 1052 int theLabelMesh = 0; /// distinguish between labels from the mesh and the labels from BC (std::set in data files)
3209 1052 felInt numElemsPerLabelMesh = 0;
3210 1052 felInt ielSupportDof = 0;
3211
3212 /// scan to find element with labelBC == labelMesh
3213 1052 const int idUnknown = BC->getUnknown();
3214
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1052 times.
1052 if(BC->listLabel().size() == 0) { /// std::set the list of (integer) labels in BC
3215 for(auto it_nameLabelToLabelNumber = GeometricMeshRegion::descriptionLineEnsightToListLabel.begin(); it_nameLabelToLabelNumber != GeometricMeshRegion::descriptionLineEnsightToListLabel.end(); it_nameLabelToLabelNumber++) {
3216 if (strcmp(BC->nameLabel().c_str(),it_nameLabelToLabelNumber->first.c_str())==0) {
3217 for(auto it_labelNumber = it_nameLabelToLabelNumber->second.begin();it_labelNumber != it_nameLabelToLabelNumber->second.end(); it_labelNumber++) {
3218 BC->listLabel().insert(*it_labelNumber);
3219 }
3220 }
3221 }
3222 }
3223
3224 1052 const int idVar = m_listUnknown.idVariable(idUnknown);
3225 1052 const int iMesh = m_listVariable[idVar].idMesh();
3226
3227 // Clear everything
3228 1052 BC->idEltAndIdSupport().clear();
3229 1052 theLabelMesh = 0;
3230 1052 numElemsPerLabelMesh = 0;
3231 1052 ielSupportDof = 0;
3232
3233 // start from the boundary elements
3234
1/2
✓ Branch 3 taken 1052 times.
✗ Branch 4 not taken.
1052 felInt idLocalElt = m_meshLocal[iMesh]->getNumDomainElement();
3235
3236 1052 felInt cptEltPerLabel = 0;
3237 1052 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[iMesh]->bagElementTypeDomainBoundary();
3238
3239 // for each element type in the bag DomainBoundary
3240
2/2
✓ Branch 1 taken 1233 times.
✓ Branch 2 taken 1052 times.
2285 for (std::size_t jj = 0; jj < bagElementTypeDomainBoundary.size(); ++jj) {
3241 1233 eltType = bagElementTypeDomainBoundary[jj];
3242
3243 // for each label in the mesh
3244
2/2
✓ Branch 7 taken 2471 times.
✓ Branch 8 taken 1233 times.
3704 for(auto itLabelMesh = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin();itLabelMesh != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itLabelMesh++) { /// scan all labels in the mesh
3245 2471 theLabelMesh = itLabelMesh->first;
3246 2471 numElemsPerLabelMesh = itLabelMesh->second.second;
3247
3248 // for each label in the BC
3249 2471 cptEltPerLabel = 0;
3250
2/2
✓ Branch 6 taken 3105 times.
✓ Branch 7 taken 2471 times.
5576 for(auto it_labelBCNumber = BC->listLabel().begin(); it_labelBCNumber != BC->listLabel().end(); it_labelBCNumber++) {
3251
3252 // if the label of the BC is the same as the one of the mesh
3253
2/2
✓ Branch 1 taken 666 times.
✓ Branch 2 taken 2439 times.
3105 if ( theLabelMesh == *it_labelBCNumber ) {
3254 // for each element of this label
3255
2/2
✓ Branch 0 taken 66310 times.
✓ Branch 1 taken 666 times.
66976 for ( felInt iel = 0; iel < numElemsPerLabelMesh; iel++) {
3256 // get the local id of the first support element
3257
1/2
✓ Branch 2 taken 66310 times.
✗ Branch 3 not taken.
66310 m_supportDofUnknownLocal[idUnknown].getIdElementSupport(idLocalElt + cptEltPerLabel, ielSupportDof);
3258
3259 // for each support dof in this element
3260
2/2
✓ Branch 2 taken 201471 times.
✓ Branch 3 taken 66310 times.
267781 for (int iSupport = 0; iSupport < m_supportDofUnknownLocal[idUnknown].getNumSupportDof(ielSupportDof); iSupport++) {
3261 // add it to idEltAndIdSupport
3262
1/2
✓ Branch 2 taken 201471 times.
✗ Branch 3 not taken.
201471 BC->idEltAndIdSupport().emplace_back(idLocalElt + cptEltPerLabel, iSupport);
3263 }
3264
3265 66310 ++cptEltPerLabel;
3266 }
3267 }
3268 }
3269 2471 idLocalElt += numElemsPerLabelMesh;
3270 }
3271 }
3272 1052 }
3273
3274 /***********************************************************************************/
3275 /***********************************************************************************/
3276
3277 664 void LinearProblem::finalizeEssBCConstantInT()
3278 {
3279 BoundaryCondition* BC;
3280 664 int idBC = 0;
3281 664 std::vector <double> valueOfBC;
3282
3283
2/2
✓ Branch 1 taken 1228 times.
✓ Branch 2 taken 664 times.
1892 for (std::size_t idc = 0; idc < m_boundaryConditionList.numDirichletBoundaryCondition(); idc++) {
3284 1228 BC = m_boundaryConditionList.Dirichlet(idc);
3285 1228 idBC = m_boundaryConditionList.idBCOfDirichlet(idc);
3286
2/3
✓ Branch 1 taken 1025 times.
✓ Branch 2 taken 203 times.
✗ Branch 3 not taken.
1228 switch (BC->typeValueBC()) {
3287 1025 case Constant:
3288
2/2
✓ Branch 2 taken 1738 times.
✓ Branch 3 taken 1025 times.
2763 for (unsigned jdc = 0; jdc < BC->getComp().size(); jdc++) {
3289
3/6
✓ Branch 1 taken 1738 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1738 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 1738 times.
✗ Branch 10 not taken.
1738 valueOfBC.push_back(FelisceParam::instance(this->instanceIndex()).value[m_boundaryConditionList.startIndiceOfValue(idBC)+jdc]);
3290 }
3291
1/2
✓ Branch 1 taken 1025 times.
✗ Branch 2 not taken.
1025 BC->setValue(valueOfBC); /// change the name ?
3292 1025 break;
3293 203 case Vector:
3294 case FunctionS:
3295 case FunctionT:
3296 case FunctionTS:
3297 case EnsightFile:
3298 203 break;
3299 // Default case should appear with a warning at compile time instead of an error in runtime
3300 // (that's truly the point of using enums as switch cases)
3301 // default:
3302
3303 //FEL_ERROR("LinearProblem::finalizeEssBCConstantInT: Unknown type of boundary condition");
3304 }
3305 1228 valueOfBC.clear();
3306 }
3307
3308
1/2
✓ Branch 1 taken 664 times.
✗ Branch 2 not taken.
664 userFinalizeEssBCConstantInT();
3309 664 }
3310
3311 /***********************************************************************************/
3312 /***********************************************************************************/
3313
3314 28180 void LinearProblem::finalizeEssBCTransient()
3315 {
3316 // Get the timer
3317 28180 auto& r_instance = FelisceParam::instance(this->instanceIndex());
3318 28180 auto& r_timer = r_instance.timer;
3319
3320
7/10
✓ Branch 1 taken 27328 times.
✓ Branch 2 taken 852 times.
✓ Branch 4 taken 17471 times.
✓ Branch 5 taken 9857 times.
✓ Branch 10 taken 28180 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 28180 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 28180 times.
✗ Branch 17 not taken.
28180 r_timer.Start("LinearProblem" + std::to_string(m_identifier_problem) + "::finalizeEssBCTransient", m_fstransient ? (m_fstransient->total_number_iterations > 0 ? m_fstransient->total_number_iterations : m_fstransient->iteration ) : 0);
3321
3322 #ifdef FELISCE_WITH_CVGRAPH
3323 28180 cvgraphFinalizeEssBC();
3324 #endif
3325 28180 finalizeEssBCTransientDerivedProblem();
3326 28180 userFinalizeEssBCTransient();
3327
3328
7/10
✓ Branch 1 taken 27328 times.
✓ Branch 2 taken 852 times.
✓ Branch 4 taken 17471 times.
✓ Branch 5 taken 9857 times.
✓ Branch 10 taken 28180 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 28180 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 28180 times.
✗ Branch 17 not taken.
28180 r_timer.Stop("LinearProblem" + std::to_string(m_identifier_problem) + "::finalizeEssBCTransient", m_fstransient ? (m_fstransient->total_number_iterations > 0 ? m_fstransient->total_number_iterations : m_fstransient->iteration ) : 0);
3329 28180 }
3330
3331 /***********************************************************************************/
3332 /***********************************************************************************/
3333
3334 53912 void LinearProblem::getListDofOfBC(const BoundaryCondition& BC, std::unordered_set<felInt>& idDofBC, std::unordered_map<int, double>& idBCAndValue)
3335 {
3336 53912 const int iUnknown = BC.getUnknown();
3337 53912 const int idVar = m_listUnknown.idVariable(iUnknown);
3338 53912 std::vector<felInt> idSupportEltLocal;
3339 felInt idSupportEltGlobal;
3340 felInt iSupport;
3341 felInt idDof;
3342 53912 std::unordered_set<felInt> idDof2;
3343 53912 int cptComp = 0;
3344
3345
2/2
✓ Branch 2 taken 5647504 times.
✓ Branch 3 taken 53912 times.
5701416 for (std::size_t iSupportDofBC = 0; iSupportDofBC < BC.idEltAndIdSupport().size(); iSupportDofBC++) {
3346 // Get the local id of the support element
3347
1/2
✓ Branch 4 taken 5647504 times.
✗ Branch 5 not taken.
5647504 m_supportDofUnknownLocal[iUnknown].getIdElementSupport(BC.idEltAndIdSupport()[iSupportDofBC].first, idSupportEltLocal);
3348 5647504 iSupport = BC.idEltAndIdSupport()[iSupportDofBC].second;
3349
3350
2/2
✓ Branch 1 taken 5647664 times.
✓ Branch 2 taken 5647504 times.
11295168 for(std::size_t ielSup=0; ielSup<idSupportEltLocal.size(); ++ielSup) {
3351 // Get the global id of the support element
3352
1/2
✓ Branch 3 taken 5647664 times.
✗ Branch 4 not taken.
5647664 ISLocalToGlobalMappingApply(*m_mappingElemSupportPerUnknown[iUnknown], 1, &idSupportEltLocal[ielSup], &idSupportEltGlobal);
3353
3354 5647664 cptComp = 0;
3355
2/2
✓ Branch 5 taken 7605856 times.
✓ Branch 6 taken 5647664 times.
13253520 for(auto it_comp = BC.getComp().begin(); it_comp != BC.getComp().end(); it_comp++) {
3356 // Get the global id of the dof
3357
1/2
✓ Branch 2 taken 7605856 times.
✗ Branch 3 not taken.
7605856 m_dof.loc2glob(idSupportEltGlobal, iSupport, idVar, *it_comp, idDof);
3358
3359 // Get the global id in the petsc ordering
3360
1/2
✓ Branch 1 taken 7605856 times.
✗ Branch 2 not taken.
7605856 AOApplicationToPetsc(m_ao, 1, &idDof);
3361
3362
1/2
✓ Branch 1 taken 7605856 times.
✗ Branch 2 not taken.
7605856 const bool is_new_element = idDof2.insert(idDof).second;
3363
2/2
✓ Branch 0 taken 1934533 times.
✓ Branch 1 taken 5671323 times.
7605856 if (is_new_element) {
3364 // insert the new dof
3365
1/2
✓ Branch 1 taken 1934533 times.
✗ Branch 2 not taken.
1934533 idDofBC.insert(idDof);
3366
1/2
✓ Branch 5 taken 1934533 times.
✗ Branch 6 not taken.
1934533 idBCAndValue[idDof] = BC.ValueBCInSupportDof()[BC.getComp().size()*iSupportDofBC+cptComp];
3367 }
3368 7605856 cptComp++;
3369 }
3370 }
3371 }
3372 53912 }
3373
3374 /***********************************************************************************/
3375 /***********************************************************************************/
3376
3377 void LinearProblem::getRings()
3378 {
3379 if( !m_ringsComputed ) {
3380 m_ringsComputed = true;
3381
3382 BoundaryCondition *BCLat=nullptr, *BCIn=nullptr, *BCOut=nullptr;
3383
3384 userGetBC(BCLat,BCIn,BCOut);
3385
3386 // TODO: Change to unordered if possible
3387 std::set<felInt> idDofBCIn,idDofBCOut,idDofBCLat,ausin,ausout,globresult;
3388 std::set<felInt> idDofBCInLoc,idDofBCOutLoc,idDofBCLatLoc;
3389
3390 FEL_ASSERT(BCLat)
3391
3392 determineElementSuppDofAssociateToBC(BCLat);
3393 getListDofOfSurfaceByBc( *BCLat, idDofBCLatLoc, MpiInfo::rankProc() );
3394 Tools::allGatherSet(idDofBCLatLoc,idDofBCLat);
3395
3396 if ( BCIn ) {
3397 determineElementSuppDofAssociateToBC(BCIn);
3398 getListDofOfSurfaceByBc( *BCIn, idDofBCInLoc , MpiInfo::rankProc() );
3399 Tools::allGatherSet(idDofBCInLoc,idDofBCIn);
3400 std::set_intersection(idDofBCIn.begin(),idDofBCIn.end(),idDofBCLat.begin(),idDofBCLat.end(),std::inserter(ausin,ausin.begin()));
3401 } else {
3402 if ( FelisceParam::verbose()>2 )
3403 std::cout<<__FILE__<<":"<<__LINE__<<" warning: BCIn is null"<<std::endl;
3404 }
3405
3406 if ( BCOut ) {
3407 determineElementSuppDofAssociateToBC(BCOut);
3408 getListDofOfSurfaceByBc( *BCOut, idDofBCOutLoc, MpiInfo::rankProc() );
3409 Tools::allGatherSet(idDofBCOutLoc,idDofBCOut);
3410 std::set_intersection(idDofBCOut.begin(),idDofBCOut.end(),idDofBCLat.begin(),idDofBCLat.end(),std::inserter(ausout,ausout.begin()));
3411 } else {
3412 if ( FelisceParam::verbose()>2 )
3413 std::cout<<__FILE__<<":"<<__LINE__<<" warning: BCOut is null"<<std::endl;
3414 }
3415
3416 std::set_union(ausin.begin(),ausin.end(),ausout.begin(),ausout.end(),std::inserter(globresult,globresult.begin()));
3417
3418 for(auto iter = globresult.begin();
3419 iter != globresult.end(); iter++ ) {
3420 if ( m_dofPart[*iter] == MpiInfo::rankProc() ) {
3421 m_idDofRings.insert(m_idDofRings.end(),*iter);
3422 }
3423 m_idDofRingsSeq.insert(m_idDofRingsSeq.end(),*iter);
3424 }
3425 }
3426 }
3427
3428 /***********************************************************************************/
3429 /***********************************************************************************/
3430
3431 void LinearProblem::userGetBC( BoundaryCondition* &/*BCLat*/, BoundaryCondition* &/*BCIn*/, BoundaryCondition* &/*BCOut*/)
3432 {
3433 if( FelisceParam::verbose()>2 ) {
3434 std::cout<<"File: "<<__FILE__<<" Line: "<<__LINE__<<std::endl;
3435 std::cout<<"you are calling the virtual function of the mother class..are you sure?"<<std::endl;
3436 }
3437 FEL_ERROR("You are using this important userdefined function from the mother class");
3438 }
3439
3440 /***********************************************************************************/
3441 /***********************************************************************************/
3442
3443 void LinearProblem::getListDofOfSurfaceByBc(const BoundaryCondition& BC, std::set<felInt>& idDofBC, int rankProc )
3444 {
3445 const int iUnknown = BC.getUnknown();
3446 const int idVar = m_listUnknown.idVariable(iUnknown);
3447 std::vector<felInt> idSupportEltLocal;
3448 felInt idSupportEltGlobal;
3449 felInt iSupport;
3450 felInt idDof;
3451 std::set<felInt> idDof2;
3452 int cptComp = 0;
3453
3454 for (unsigned iSupportDofBC = 0; iSupportDofBC < BC.idEltAndIdSupport().size(); iSupportDofBC++){
3455 // get the local id of the support element
3456 m_supportDofUnknownLocal[iUnknown].getIdElementSupport(BC.idEltAndIdSupport()[iSupportDofBC].first, idSupportEltLocal);
3457 iSupport = BC.idEltAndIdSupport()[iSupportDofBC].second;
3458
3459 for(std::size_t ielSup=0; ielSup<idSupportEltLocal.size(); ++ielSup){
3460 // get the global id of the support element
3461 ISLocalToGlobalMappingApply(*m_mappingElemSupportPerUnknown[iUnknown], 1, &idSupportEltLocal[ielSup], &idSupportEltGlobal);
3462
3463 cptComp = 0;
3464 for(int it_comp = 0; it_comp != this->dimension(); it_comp++){
3465 // get the global id of the dof
3466 dof().loc2glob(idSupportEltGlobal, iSupport, idVar, it_comp, idDof);
3467
3468 if( m_dofPart[idDof] == rankProc ) {
3469 // get the global id in the petsc ordering
3470 AOApplicationToPetsc(m_ao, 1, &idDof);
3471
3472 bool is_new_element = idDof2.insert(idDof).second;
3473 if (is_new_element) {
3474 // insert the new dof
3475 idDofBC.insert(idDof);
3476 }
3477 }
3478 cptComp++;
3479 }
3480 }
3481 }
3482 }
3483
3484 /***********************************************************************************/
3485 /***********************************************************************************/
3486
3487 void LinearProblem::setValueBoundaryCondition(BoundaryCondition* bc, PetscVector& vecOfValue)
3488 {
3489 const int iUnknown = bc->getUnknown();
3490 const int idVar = m_listUnknown.idVariable(iUnknown);
3491 const int idMsh = m_listVariable[idVar].idMesh();
3492 if(bc->typeValueBC() == EnsightFile) {
3493 felInt idEltInSupportLocal = 0;
3494 felInt idEltInSupportGlobal = 0;
3495 felInt idDof;
3496 double aux =0.;
3497 bc->ValueBCInSupportDof().clear();
3498 for (unsigned iSupportDofBC = 0; iSupportDofBC < bc->idEltAndIdSupport().size(); iSupportDofBC++) {
3499 // I think this getIdElementSupport is often the identity,
3500 m_supportDofUnknownLocal[iUnknown].getIdElementSupport(bc->idEltAndIdSupport()[iSupportDofBC].first, idEltInSupportLocal);
3501 // loc2glob elementwise
3502 ISLocalToGlobalMappingApply(m_mappingElem[idMsh],1,&idEltInSupportLocal,&idEltInSupportGlobal);
3503 // for each component
3504 for(auto it_comp = bc->getComp().begin(); it_comp != bc->getComp().end(); it_comp++) {
3505 // log2glob idDof
3506 dof().loc2glob(idEltInSupportGlobal, bc->idEltAndIdSupport()[iSupportDofBC].second, idVar, *it_comp, idDof);
3507 AOApplicationToPetsc(m_ao,1,&idDof);
3508 vecOfValue.getValues( 1, &idDof, &aux);
3509 bc->ValueBCInSupportDof().push_back(aux);
3510 }
3511 }
3512 }
3513 }
3514
3515 /***********************************************************************************/
3516 /***********************************************************************************/
3517
3518 13151 void LinearProblem::preSNESAssemble()
3519 {
3520 13151 clearMatrixRHS(FlagMatrixRHS::matrix_and_rhs);
3521 13151 gatherVector(m_evaluationState, m_seqEvaluationState);
3522 13151 preSNESAssembleAdditional();
3523 13151 }
3524
3525 /***********************************************************************************/
3526 /***********************************************************************************/
3527
3528 524 void LinearProblem::buildSolver()
3529 {
3530 // SNES case
3531
2/2
✓ Branch 2 taken 283 times.
✓ Branch 3 taken 241 times.
524 if (this->snesInterface().doUseSNES()) {
3532
1/2
✓ Branch 2 taken 283 times.
✗ Branch 3 not taken.
283 m_pSNESInterface->init();
3533
3534 // Retrieve KSP
3535
1/2
✓ Branch 3 taken 283 times.
✗ Branch 4 not taken.
283 m_KSPInterface->initFromSNES(m_pSNESInterface);
3536
3537 // Put that here: in iterativeSolve() it would duplicate the lines printed at each call.
3538
1/2
✓ Branch 2 taken 283 times.
✗ Branch 3 not taken.
283 m_pSNESInterface->setMonitorSetLinearProblem(this);
3539 }
3540 // Most usual cases
3541 else {
3542
1/2
✓ Branch 2 taken 241 times.
✗ Branch 3 not taken.
241 m_KSPInterface->init();
3543 }
3544
3545 // Setting the type, the GMRES restart, the PC type, tolerances,...
3546
2/4
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 524 times.
✗ Branch 5 not taken.
524 const auto& r_instance = FelisceParam::instance(this->instanceIndex());
3547
1/2
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
524 const std::string solver = r_instance.solver[m_identifier_solver];
3548
1/2
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
524 const std::string preconditioner = r_instance.preconditioner[m_identifier_solver];
3549 524 const double relativeTolerance = r_instance.relativeTolerance[m_identifier_solver];
3550 524 const double absoluteTolerance = r_instance.absoluteTolerance[m_identifier_solver];
3551 524 const int maxIteration = r_instance.maxIteration[m_identifier_solver];
3552 524 const int gmresRestart = r_instance.gmresRestart[m_identifier_solver];
3553
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 const bool initPrevSolution = r_instance.initSolverWithPreviousSolution[m_identifier_solver];
3554
3/6
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 524 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 524 times.
✗ Branch 9 not taken.
524 m_KSPInterface->setKSPandPCType(solver, preconditioner);
3555
1/2
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
524 m_KSPInterface->setTolerances(relativeTolerance, absoluteTolerance, maxIteration, gmresRestart);
3556
3557
2/2
✓ Branch 2 taken 283 times.
✓ Branch 3 taken 241 times.
524 if (this->snesInterface().doUseSNES()) {
3558 283 const double solutionTolerance = r_instance.solutionTolerance[m_identifier_solver];
3559 283 const int maxIterationSNES = r_instance.maxIterationSNES[m_identifier_solver];
3560 283 const int maxFunctionEvaluatedSNES = r_instance.maxFunctionEvaluatedSNES[m_identifier_solver];
3561 283 const double divergenceTolerance = r_instance.divergenceTolerance[m_identifier_solver];
3562
1/2
✓ Branch 2 taken 283 times.
✗ Branch 3 not taken.
283 m_pSNESInterface->setTolerances(absoluteTolerance, relativeTolerance, solutionTolerance, maxIterationSNES, maxFunctionEvaluatedSNES, divergenceTolerance);
3563 }
3564
3565 // Setting KSPpreonly, init with previous solution, setFromOptions,...
3566
2/4
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 524 times.
✗ Branch 6 not taken.
524 m_KSPInterface->setKSPOptions(solver, initPrevSolution);
3567 524 }
3568
3569 /***********************************************************************************/
3570 /***********************************************************************************/
3571
3572 6822 void LinearProblem::solve(int /*rank*/, int /*size*/, bool new_matrix)
3573 {
3574 6822 auto& r_instance = FelisceParam::instance(this->instanceIndex());
3575
3576
1/2
✓ Branch 0 taken 6822 times.
✗ Branch 1 not taken.
6822 if ( new_matrix ) {
3577
1/2
✓ Branch 5 taken 6822 times.
✗ Branch 6 not taken.
6822 m_KSPInterface->setKSPOperator(matrix(), r_instance.setPreconditionerOption[m_identifier_solver]);
3578 }
3579
3580 // Get the timer
3581 6822 auto& r_timer = r_instance.timer;
3582
7/10
✓ Branch 1 taken 5902 times.
✓ Branch 2 taken 920 times.
✓ Branch 4 taken 874 times.
✓ Branch 5 taken 5028 times.
✓ Branch 10 taken 6822 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6822 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 6822 times.
✗ Branch 17 not taken.
6822 r_timer.Start("LinearProblem" + std::to_string(m_identifier_problem) + "::solve", m_fstransient ? (m_fstransient->total_number_iterations > 0 ? m_fstransient->total_number_iterations : m_fstransient->iteration ) : 0);
3583 6822 m_KSPInterface->solve( vector(), m_sol, r_instance.linearSolverVerbose);
3584
7/10
✓ Branch 1 taken 5902 times.
✓ Branch 2 taken 920 times.
✓ Branch 4 taken 874 times.
✓ Branch 5 taken 5028 times.
✓ Branch 10 taken 6822 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6822 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 6822 times.
✗ Branch 17 not taken.
6822 r_timer.Stop("LinearProblem" + std::to_string(m_identifier_problem) + "::solve", m_fstransient ? (m_fstransient->total_number_iterations > 0 ? m_fstransient->total_number_iterations : m_fstransient->iteration ) : 0);
3585
3586 6822 printSolution(m_verbosity);
3587 6822 }
3588
3589 /***********************************************************************************/
3590 /***********************************************************************************/
3591
3592 984 void LinearProblem::solveWithSameMatrix()
3593 {
3594 // Get the timer
3595 984 auto& r_instance = FelisceParam::instance(this->instanceIndex());
3596 984 auto& r_timer = r_instance.timer;
3597
3598 984 m_KSPInterface->setInitialGuessZero();
3599
5/10
✓ Branch 1 taken 984 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 984 times.
✓ Branch 10 taken 984 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 984 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 984 times.
✗ Branch 17 not taken.
984 r_timer.Start("LinearProblem" + std::to_string(m_identifier_problem) + "::solveWithSameMatrix", m_fstransient ? (m_fstransient->total_number_iterations > 0 ? m_fstransient->total_number_iterations : m_fstransient->iteration ) : 0);
3600 984 m_KSPInterface->solve( vector(), m_sol, r_instance.linearSolverVerbose);
3601
5/10
✓ Branch 1 taken 984 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 984 times.
✓ Branch 10 taken 984 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 984 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 984 times.
✗ Branch 17 not taken.
984 r_timer.Stop("LinearProblem" + std::to_string(m_identifier_problem) + "::solveWithSameMatrix", m_fstransient ? (m_fstransient->total_number_iterations > 0 ? m_fstransient->total_number_iterations : m_fstransient->iteration ) : 0);
3602
3603 984 printSolution(m_verbosity);
3604 984 }
3605
3606 /***********************************************************************************/
3607 /***********************************************************************************/
3608
3609 7095 void LinearProblem::iterativeSolve(int /*rank*/, int /*size*/, ApplyNaturalBoundaryConditionsType /*do_apply_natural*/, FlagMatrixRHS /*flag_matrix_rhs*/)
3610 {
3611
2/4
✗ Branch 2 not taken.
✓ Branch 3 taken 7095 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 7095 times.
7095 FEL_ASSERT(this->snesInterface().doUseSNES() && "This method relies on SNES and therefore the flag should be set!");
3612 //SnesContext mySnesContext(*this, rank, size, do_apply_natural, flag_matrix_rhs);
3613
3614 // Initialize the transient info
3615 7095 this->model()->fstransient()->non_linear_iteration = 0;
3616
3617 // Call the SNES solve method.
3618 7095 m_pSNESInterface->solve(m_sol);
3619 7095 printSolution(m_verbosity);
3620 7095 }
3621
3622 /***********************************************************************************/
3623 /***********************************************************************************/
3624
3625 void LinearProblem::createAndCopyMatrixRHSWithoutBC(FlagMatrixRHS flag)
3626 {
3627 if(flag == FlagMatrixRHS::matrix_and_rhs || flag == FlagMatrixRHS::only_matrix) {
3628 if ( m_matrixWithoutBC.isNull() ) {
3629 m_matrixWithoutBC.duplicateFrom(this->matrix(),MAT_COPY_VALUES);
3630 m_matrixWithoutBC.copyFrom(this->matrix(),SAME_NONZERO_PATTERN);
3631 } else {
3632 m_matrixWithoutBC.copyFrom(this->matrix(),SAME_NONZERO_PATTERN);
3633 }
3634 }
3635 if(flag == FlagMatrixRHS::matrix_and_rhs || flag == FlagMatrixRHS::only_rhs) {
3636 if ( m_rhsWithoutBC.isNull() ) {
3637 m_rhsWithoutBC.duplicateFrom(this->vector());
3638 m_residual.duplicateFrom(this->vector());
3639 m_seqResidual.duplicateFrom(this->sequentialSolution());
3640 m_rhsWithoutBC.copyFrom(this->vector());
3641 } else {
3642 m_rhsWithoutBC.copyFrom(this->vector());
3643 }
3644 }
3645 }
3646
3647 /***********************************************************************************/
3648 /***********************************************************************************/
3649
3650 void LinearProblem::computeResidual()
3651 {
3652 m_matrixWithoutBC.scale(-1.);
3653 multAdd(m_matrixWithoutBC,this->solution(),m_rhsWithoutBC,m_residual);
3654 gatherVec(m_residual, m_seqResidual);
3655 m_matrixWithoutBC.scale(-1.);
3656 }
3657
3658 /***********************************************************************************/
3659 /***********************************************************************************/
3660
3661 28068 void LinearProblem::clearMatrixRHS(const FlagMatrixRHS flagMatrixRHS)
3662 {
3663 // Sebastien: really the gathering is nonsensical here: solution is absolutely not use hereafter, and
3664 // clearing Matrix or RHS has nothing to do with it...
3665 // However I can't remove it, because it could break some code: even if the place is very clumsy, some
3666 // problems might not do the gathering at a more fitting place and the result could therefore go astray.
3667 // gatherSolution();
3668
3669
2/2
✓ Branch 2 taken 21826 times.
✓ Branch 3 taken 6242 times.
28068 if (this->snesInterface().doUseSNES()) {
3670 21826 gatherEvaluationState();
3671 }
3672
3673 // Restart problem with vectors and matrix with 0 values
3674
4/4
✓ Branch 0 taken 636 times.
✓ Branch 1 taken 27432 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 632 times.
28068 if (flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix) {
3675 27436 clearMatrix(0);
3676 }
3677
4/4
✓ Branch 0 taken 636 times.
✓ Branch 1 taken 27432 times.
✓ Branch 2 taken 632 times.
✓ Branch 3 taken 4 times.
28068 if (flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs) {
3678 28064 clearVector(0);
3679 }
3680 28068 }
3681
3682 /***********************************************************************************/
3683 /***********************************************************************************/
3684
3685 28480 void LinearProblem::clearMatrix(std::size_t i)
3686 {
3687
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28480 times.
28480 FEL_ASSERT(i < numberOfMatrices());
3688 28480 m_matrices[i].setUnfactored();
3689 28480 m_matrices[i].zeroEntries();
3690 28480 }
3691
3692 /***********************************************************************************/
3693 /***********************************************************************************/
3694
3695 28600 void LinearProblem::clearVector(std::size_t i)
3696 {
3697
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28600 times.
28600 FEL_ASSERT(i < m_vectors.size());
3698 28600 m_vectors[i].zeroEntries();
3699 28600 }
3700
3701 /***********************************************************************************/
3702 /***********************************************************************************/
3703
3704 void LinearProblem::getSolution(double* & solution, int sizeProc, int numProc)
3705 {
3706 IGNORE_UNUSED_NUM_PROC;
3707
3708 PetscVector xsol;
3709 xsol = m_seqSol; // NOTE: Behaviour of copy constructor has been changed in PETSc interface. In order to preserve the memory, we use the assign operator.
3710 felInt ix;
3711 felInt iout;
3712 double valueVec;
3713 for (felInt i=0; i<m_numDofLocal; i++) {
3714 ix=i;
3715 iout = i;
3716 if ( sizeProc > 1)
3717 ISLocalToGlobalMappingApply(m_mappingNodes,1,&ix,&iout);
3718
3719 AOApplicationToPetsc(m_ao,1,&iout);
3720 m_seqSol.getValues(1,&iout,&valueVec);
3721 AOPetscToApplication(m_ao,1,&iout);
3722 xsol.setValues(1,&iout,&valueVec,INSERT_VALUES);
3723 }
3724 xsol.assembly();
3725
3726 // Writing solution for visualization with ensight
3727 PetscVector xsol2;
3728 xsol.scatterToZero(xsol2,INSERT_VALUES,SCATTER_FORWARD);
3729 xsol2.getArray(&solution);
3730 }
3731
3732 /***********************************************************************************/
3733 /***********************************************************************************/
3734
3735 void LinearProblem::setSolution(double* solution, int sizeProc, int numProc)
3736 {
3737 IGNORE_UNUSED_NUM_PROC;
3738 IGNORE_UNUSED_SIZE_PROC;
3739
3740 felInt iout;
3741 felReal valueVec;
3742 for (felInt i=0; i<m_numDof; i++) {
3743 iout = i;
3744 AOApplicationToPetsc(m_ao,1,&iout);
3745 valueVec = solution[iout];
3746 m_seqSol.setValues(1,&iout,&valueVec,INSERT_VALUES);
3747 }
3748 m_seqSol.assembly();
3749 }
3750
3751 /***********************************************************************************/
3752 /***********************************************************************************/
3753
3754 void LinearProblem::getSolutionUnknown(PhysicalVariable unknown, PetscVector& v)
3755 {
3756 v.zeroEntries();
3757 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
3758 felInt shiftDof = 0;
3759 felInt iPos;
3760 felReal value;
3761
3762 for (int iUnknown2 = 0; iUnknown2 < iUnknown; iUnknown2++)
3763 shiftDof += numDofPerUnknown(m_listUnknown[iUnknown2]);
3764
3765 for (felInt iValue = 0; iValue < numDofPerUnknown(unknown); iValue++) {
3766 iPos = iValue + shiftDof;
3767 AOApplicationToPetsc(m_ao,1,&iPos);
3768 m_seqSol.getValues(1,&iPos,&value);
3769 v.setValue(iValue,value,INSERT_VALUES);
3770 }
3771 v.assembly();
3772 }
3773
3774 /***********************************************************************************/
3775 /***********************************************************************************/
3776
3777 void LinearProblem::getVector(double* & value, PetscVector& seqVec, int sizeProc, int numProc)
3778 {
3779 IGNORE_UNUSED_NUM_PROC;
3780 PetscVector xsol;
3781 xsol = seqVec; // NOTE: Behaviour of copy constructor has been changed in PETSc interface. In order to preserve the memory, we use the assign operator.
3782 felInt ix;
3783 felInt iout;
3784 double valueVec;
3785 for (felInt i=0; i<m_numDofLocal; i++) {
3786 ix=i;
3787 iout = i;
3788 if ( sizeProc > 1)
3789 ISLocalToGlobalMappingApply(m_mappingNodes,1,&ix,&iout);
3790
3791 AOApplicationToPetsc(m_ao,1,&iout);
3792 seqVec.getValues(1,&iout,&valueVec);
3793 AOPetscToApplication(m_ao,1,&iout);
3794 xsol.setValues(1,&iout,&valueVec,INSERT_VALUES);
3795 }
3796 xsol.assembly();
3797
3798 // Writing solution for visualization with ensight
3799 PetscVector xsol2;
3800 xsol.scatterToZero(xsol2,INSERT_VALUES,SCATTER_FORWARD);
3801 xsol2.getArray(&value); // Memory Leak one should call VecRestoreArray and then destroy xsol2, same problem in getSolution. Matteo and Benoit
3802 }
3803
3804 /***********************************************************************************/
3805 /***********************************************************************************/
3806
3807 8450 void LinearProblem::findCoordinateWithIdDof(felInt i, Point& pt)
3808 {
3809 8450 felInt inf = 0;
3810 8450 felInt sup = 0;
3811
3812
1/2
✓ Branch 1 taken 8450 times.
✗ Branch 2 not taken.
8450 for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++) {
3813
3814
1/2
✓ Branch 0 taken 8450 times.
✗ Branch 1 not taken.
8450 if (iUnknown == 0) {
3815 8450 inf = 0;
3816 8450 sup = m_numDofUnknown[iUnknown];
3817 } else {
3818 inf += m_numDofUnknown[iUnknown-1];
3819 if (iUnknown == m_listUnknown.size()-1)
3820 sup = m_numDof;
3821 else
3822 sup += m_numDofUnknown[iUnknown];
3823 }
3824
3825
2/4
✓ Branch 0 taken 8450 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8450 times.
✗ Branch 3 not taken.
8450 if ( inf <= i && i < sup ) {
3826 8450 const felInt idDofPerUnknown = i - inf;
3827 8450 const int idVar = m_listUnknown.idVariable(iUnknown);
3828 8450 const felInt idSupportDof = idDofPerUnknown / m_listVariable[idVar].numComponent();
3829 8450 pt = m_supportDofUnknown[iUnknown].listNode()[idSupportDof];
3830
3831 8450 return;
3832 }
3833 }
3834 }
3835
3836 /***********************************************************************************/
3837 /***********************************************************************************/
3838
3839 102 void LinearProblem::initPetscVectors()
3840 {
3841 /*!
3842 The structure of the vectors initializated in #m_vecs and in #m_seqVecs is duplicated
3843 from the solution and from sequentialSolution of LinearProblem, respectively.\n
3844 They are also set to zero.
3845 */
3846
2/2
✓ Branch 3 taken 134 times.
✓ Branch 4 taken 102 times.
236 for ( auto it = m_vecs.begin(); it != m_vecs.end(); ++it ) {
3847
1/2
✓ Branch 3 taken 134 times.
✗ Branch 4 not taken.
134 it->second.duplicateFrom(this->solution());
3848
1/2
✓ Branch 2 taken 134 times.
✗ Branch 3 not taken.
134 it->second.set(0.0);
3849 }
3850
2/2
✓ Branch 3 taken 246 times.
✓ Branch 4 taken 102 times.
348 for ( auto it = m_seqVecs.begin(); it != m_seqVecs.end(); ++it ) {
3851
1/2
✓ Branch 3 taken 246 times.
✗ Branch 4 not taken.
246 it->second.duplicateFrom(this->sequentialSolution());
3852
1/2
✓ Branch 2 taken 246 times.
✗ Branch 3 not taken.
246 it->second.set(0.0);
3853 }
3854 102 }
3855
3856 /***********************************************************************************/
3857 /***********************************************************************************/
3858
3859 std::size_t LinearProblem::instanceIndex() const { return mOwnerModel->instanceIndex(); }
3860
3861 /***********************************************************************************/
3862 /***********************************************************************************/
3863
3864 17051359 std::size_t& LinearProblem::instanceIndex() { return mOwnerModel->instanceIndex(); }
3865
3866 /***********************************************************************************/
3867 /***********************************************************************************/
3868
3869 void LinearProblem::removeAverageFromSolution(PhysicalVariable unknown, int rankProc)
3870 {
3871 IGNORE_UNUSED_RANK_PROC;
3872 gatherSolution();
3873 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
3874 const int idVar = m_listUnknown.idVariable(iUnknown);
3875 const int iMesh = m_listVariable[idVar].idMesh();
3876 const Variable& variable = m_listVariable[idVar];
3877
3878 //geometric element type in the mesh.
3879 ElementType eltType;
3880 //number of points per geometric element.
3881 int numPointPerElt = 0;
3882 //number of element for one label and one eltType.
3883 felInt numEltPerLabel = 0;
3884 //Points of the current element.
3885 std::vector<Point*> elemPoint;
3886 //Id of points of the element.
3887 std::vector<felInt> elemIdPoint;
3888 //Ids of support elements for a mesh element
3889 std::vector<felInt> vectorIdSupport;
3890
3891 // use to identify global id of dof.
3892 felInt idDof;
3893 felInt cpt = 0;
3894 double integralValue = 0.;
3895 double totalMeasure = 0.;
3896 double elementValue = 0.;
3897 //Id link element to its supportDof.
3898 felInt ielSupportDof;
3899
3900 // initialize global numbering from mesh.
3901 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
3902
3903 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
3904 eltType = (ElementType)ityp;
3905 numElement[eltType] = 0;
3906 }
3907
3908 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[iMesh]->bagElementTypeDomain();
3909 CurrentFiniteElement* fePtr = nullptr;
3910 int numComp = 0;
3911 felInt* idGlobalDof = nullptr;
3912 double* dofValue = nullptr;
3913 // todo generalize for every multiple type of element in mesh.
3914 // Do not consider proc where no "current elements" are saved - for surface/volume or surface/segment domains
3915 if(!bagElementTypeDomain.empty()) {
3916 fePtr = m_listCurrentFiniteElement[idVar];
3917 FEL_ASSERT(fePtr);
3918
3919 numComp = variable.numComponent();
3920 // dofValue contains : values in dof by element.
3921 dofValue = new double[fePtr->numDof()*numComp];
3922 // idGlobalDof contains: global number od dof by element.
3923 idGlobalDof = new felInt[fePtr->numDof()*numComp];
3924 }
3925
3926 // Loop on elementType.
3927 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
3928 eltType = bagElementTypeDomain[i];
3929 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
3930 elemPoint.resize(numPointPerElt, nullptr);
3931 elemIdPoint.resize(numPointPerElt,0);
3932 // Loop on region define in the mesh.
3933 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
3934 numEltPerLabel = itRef->second.second;
3935
3936 // Loop on elements.
3937 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {// numEltPerLabel: number of mesh's elements
3938 // get points of element.
3939 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport); // TODO D.C. inside here m_currentMesh is used. It may differ by iMesh
3940
3941 // loop over all the support elements
3942 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
3943 // get the id of the support
3944 ielSupportDof = vectorIdSupport[it];
3945
3946 // compute measure of the current element.
3947 fePtr->updateMeas(0, elemPoint);
3948 // save measure
3949 totalMeasure += fePtr->measure();
3950
3951 cpt = 0;
3952 // identify global id of Dof for the current element.
3953 for(int iComp = 0; iComp<numComp; iComp++) {
3954 for(int iDof=0; iDof<fePtr->numDof(); iDof++) {
3955 m_dof.loc2glob(ielSupportDof,iDof,idVar,iComp,idDof);
3956 idGlobalDof[cpt] = idDof;
3957
3958 cpt++;
3959 }
3960 }
3961
3962 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
3963 AOApplicationToPetsc(m_ao,fePtr->numDof()*numComp,idGlobalDof);
3964 //gets values of associate dofs.
3965 m_seqSol.getValues(fePtr->numDof()*numComp,idGlobalDof,dofValue);
3966
3967 //Interpolation
3968 for(int ig=0; ig<fePtr->numQuadraturePoint(); ig++) {
3969 elementValue = 0.;
3970 cpt = 0;
3971 for(int icomp=0; icomp<numComp; icomp++) {
3972 for(int j=0; j<fePtr->numDof(); j++) {
3973 elementValue += fePtr->phi[ig](j) * dofValue[cpt];
3974 cpt++;
3975 }
3976 integralValue += elementValue * fePtr->weightMeas(ig);
3977 }
3978 }
3979 }
3980 //End of interpolation
3981
3982 numElement[eltType]++;
3983 }
3984 }
3985 }
3986
3987 felInt positionForPetsc[m_numDofLocalUnknown[iUnknown]];
3988 felInt localPosition[m_numDofLocalUnknown[iUnknown]];
3989 double petscValue[m_numDofLocalUnknown[iUnknown]];
3990
3991 //Receive moyenne:
3992 double valueReceive = 0.;
3993 MPI_Allreduce(&integralValue,&valueReceive, 1,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm());
3994 integralValue = valueReceive;
3995 valueReceive = 0.;
3996 MPI_Allreduce(&totalMeasure,&valueReceive, 1,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm());
3997 totalMeasure = valueReceive;
3998
3999 petscValue[0] = -integralValue/totalMeasure;
4000
4001 for (felInt i = 0; i < m_numDofLocalUnknown[iUnknown]; i++) {
4002 localPosition[i] = i;
4003 petscValue[i] = petscValue[0];
4004 }
4005
4006 ISLocalToGlobalMappingApply( m_mappingIdLocalDofPerUnknownToIdGlobalDofPetsc[iUnknown],m_numDofLocalUnknown[iUnknown],&localPosition[0],&positionForPetsc[0]);
4007
4008 //vecsetvalue global sur unknown
4009
4010 // The coordinates associated with the global number should be retrieved
4011 m_sol.setValues(m_numDofLocalUnknown[iUnknown],positionForPetsc,petscValue,ADD_VALUES);
4012 m_sol.assembly();
4013
4014 if(!bagElementTypeDomain.empty()) {
4015 delete [] idGlobalDof;
4016 delete [] dofValue;
4017 }
4018 gatherSolution();
4019 }
4020
4021 /***********************************************************************************/
4022 /***********************************************************************************/
4023
4024 void LinearProblem::removeAverageFromSolutionCurv(PhysicalVariable unknown, int rankProc)
4025 {
4026 IGNORE_UNUSED_RANK_PROC;
4027 gatherSolution();
4028 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
4029 const int idVar = m_listUnknown.idVariable(iUnknown);
4030 const int iMesh = m_listVariable[idVar].idMesh();
4031 Variable variable = m_listVariable[idVar];
4032 // todo generalize for every multiple type of element in mesh.
4033 CurvilinearFiniteElement* fePtr = m_listCurvilinearFiniteElement[idVar];
4034 FEL_ASSERT(fePtr)
4035 CurvilinearFiniteElement& fe = *fePtr;
4036
4037 int numComp = variable.numComponent();
4038 // dofValue contains : values in dof by element.
4039 double dofValue[fe.numDof()*numComp];
4040 // idGlobalDof contains: global number od dof by element.
4041 felInt idGlobalDof[fe.numDof()*numComp];
4042
4043 //geometric element type in the mesh.
4044 ElementType eltType;
4045 //number of points per geometric element.
4046 int numPointPerElt = 0;
4047 //number of element for one label and one eltType.
4048 felInt numEltPerLabel = 0;
4049 //Points of the current element.
4050 std::vector<Point*> elemPoint;
4051 //Id of points of the element.
4052 std::vector<felInt> elemIdPoint;
4053 // Ids of support elements of a mesh element
4054 std::vector <felInt> vectorIdSupport;
4055
4056 // use to identify global id of dof.
4057 felInt idDof;
4058 felInt cpt = 0;
4059 double integralValue = 0.;
4060 double totalMeasure = 0.;
4061 double elementValue = 0.;
4062 //Id link element to its supportDof.
4063 felInt ielSupportDof;
4064
4065 // initialize global numbering from mesh.
4066 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
4067 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
4068 eltType = (ElementType)ityp;
4069 numElement[eltType] = 0;
4070 }
4071
4072 // Loop on elementType.
4073 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[iMesh]->bagElementTypeDomain();
4074 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
4075 eltType = bagElementTypeDomain[i];
4076 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
4077 elemPoint.resize(numPointPerElt, nullptr);
4078 elemIdPoint.resize(numPointPerElt,0);
4079 // Loop on region define in the mesh.
4080 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
4081 numEltPerLabel = itRef->second.second;
4082 // Loop on elements.
4083 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
4084 // get points of element.
4085 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport); // TODO D.C. inside here iMesh is used. It may differ by iMesh
4086
4087 // loop over all the support elements
4088 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
4089 // get the id of the support
4090 ielSupportDof = vectorIdSupport[it];
4091
4092 // compute measure of the current element.
4093 fe.updateMeas(0, elemPoint);
4094 // save measure
4095 totalMeasure += fe.measure();
4096
4097 cpt = 0;
4098 // identify global id of Dof for the current element.
4099 for(int iComp = 0; iComp<numComp; iComp++) {
4100 for(int iDof=0; iDof<fe.numDof(); iDof++) {
4101 m_dof.loc2glob(ielSupportDof,iDof,idVar,iComp,idDof);
4102 idGlobalDof[cpt] = idDof;
4103 cpt++;
4104 }
4105 }
4106
4107 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
4108 AOApplicationToPetsc(m_ao,fe.numDof()*numComp,idGlobalDof);
4109 //gets values of associate dofs.
4110 m_seqSol.getValues(fe.numDof()*numComp,idGlobalDof,dofValue);
4111
4112 //Interpolation
4113 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
4114 elementValue = 0.;
4115 cpt = 0;
4116 for(int icomp=0; icomp<numComp; icomp++) {
4117 for(int j=0; j<fe.numDof(); j++) {
4118 elementValue += fe.phi[ig](j) * dofValue[cpt];
4119 cpt++;
4120 }
4121 integralValue += elementValue * fe.weightMeas(ig);
4122 }
4123 }
4124 }
4125 numElement[eltType]++;
4126 }
4127 }
4128 }
4129
4130 felInt positionForPetsc[m_numDofLocalUnknown[iUnknown]];
4131 felInt localPosition[m_numDofLocalUnknown[iUnknown]];
4132 double petscValue[m_numDofLocalUnknown[iUnknown]];
4133
4134 //Receive moyenne:
4135 double valueReceive = 0.;
4136 MPI_Allreduce(&integralValue,&valueReceive, 1,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm());
4137 integralValue = valueReceive;
4138 valueReceive = 0.;
4139 MPI_Allreduce(&totalMeasure,&valueReceive, 1,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm());
4140 totalMeasure = valueReceive;
4141 petscValue[0] = -integralValue/totalMeasure;
4142
4143 for (felInt i = 0; i < m_numDofLocalUnknown[iUnknown]; i++) {
4144 localPosition[i] = i;
4145 petscValue[i] = petscValue[0];
4146 }
4147
4148 ISLocalToGlobalMappingApply( m_mappingIdLocalDofPerUnknownToIdGlobalDofPetsc[iUnknown],m_numDofLocalUnknown[iUnknown],&localPosition[0],&positionForPetsc[0]);
4149
4150 //vecsetvalue global sur unknown
4151 m_sol.setValues(m_numDofLocalUnknown[iUnknown],positionForPetsc,petscValue,ADD_VALUES);
4152 m_sol.assembly();
4153
4154 gatherSolution();
4155 }
4156
4157 /***********************************************************************************/
4158 /***********************************************************************************/
4159
4160 void LinearProblem::removeMaxSol(PhysicalVariable unknown, double valMax, int rankProc)
4161 {
4162 IGNORE_UNUSED_RANK_PROC;
4163
4164 gatherSolution();
4165
4166 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
4167 const int sizeVar = m_numDofLocalUnknown[iUnknown];
4168 double valueForPetsc[sizeVar];
4169
4170 felInt idLocalValue[sizeVar];
4171 felInt idGlobalValue[sizeVar];
4172
4173 for (felInt i = 0; i < sizeVar; i++) {
4174 idLocalValue[i] = i;
4175 }
4176 ISLocalToGlobalMappingApply(mappingDofLocalToDofGlobal(unknown),sizeVar,&idLocalValue[0],&idGlobalValue[0]);
4177
4178 for (felInt i = 0; i < sizeVar; i++) {
4179 valueForPetsc[i] = -valMax;
4180 }
4181 m_sol.setValues(sizeVar,&idGlobalValue[0],&valueForPetsc[0],ADD_VALUES);
4182 m_sol.assembly();
4183
4184 gatherSolution();
4185 }
4186
4187 /***********************************************************************************/
4188 /***********************************************************************************/
4189
4190 416 void LinearProblem::computeMeanQuantity(PhysicalVariable unknown, const std::vector<int>& label, std::vector<double>& meanQuantity)
4191 {
4192 416 gatherSolution();
4193 416 computeMeanQuantity(m_seqSol,unknown,label,meanQuantity);
4194 416 }
4195
4196 /***********************************************************************************/
4197 /***********************************************************************************/
4198
4199 416 void LinearProblem::computeMeanQuantity(PetscVector& seqVec, PhysicalVariable unknown, const std::vector<int>& label, std::vector<double>& meanQuantity)
4200 {
4201
1/2
✓ Branch 1 taken 416 times.
✗ Branch 2 not taken.
416 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
4202 416 const int idVar = m_listUnknown.idVariable(iUnknown);
4203 416 const int iMesh = m_listVariable[idVar].idMesh();
4204 416 const Variable& variable = m_listVariable[idVar];
4205 416 const int numComp = variable.numComponent();
4206
4207 //geometric element type in the mesh.
4208 ElementType eltType;
4209 //number of points per geometric element.
4210 416 int numPointPerElt = 0;
4211 416 int currentLabel = 0;
4212 //number of element for one label and one eltType.
4213 416 felInt numEltPerLabel = 0;
4214 //Points of the current element.
4215 416 std::vector<Point*> elemPoint;
4216 //Id of points of the element.
4217 416 std::vector<felInt> elemIdPoint;
4218 //Ids of support elements of a mesh element
4219 416 std::vector<felInt> vectorIdSupport;
4220
4221 // use to identify global id of dof.
4222 felInt idDof;
4223 416 felInt cpt = 0;
4224 //Id link element to its supportDof.
4225 felInt ielSupportDof;
4226 416 meanQuantity.clear();
4227
1/2
✓ Branch 2 taken 416 times.
✗ Branch 3 not taken.
416 meanQuantity.resize(label.size(),0.);
4228
4229
1/2
✓ Branch 3 taken 416 times.
✗ Branch 4 not taken.
416 std::vector<double> tmpQuantity(label.size(),0.);
4230
1/2
✓ Branch 3 taken 416 times.
✗ Branch 4 not taken.
416 std::vector<double> measure(label.size(),0.);
4231
1/2
✓ Branch 3 taken 416 times.
✗ Branch 4 not taken.
416 std::vector<double> tmpMeasure(label.size(),0.);
4232
4233 416 int searchLabel=-1;
4234 felInt numElement[GeometricMeshRegion::m_numTypesOfElement];
4235
4236
2/2
✓ Branch 1 taken 744 times.
✓ Branch 2 taken 416 times.
1160 for(std::size_t iLabel = 0; iLabel < label.size(); iLabel++) {
4237 744 searchLabel = label[iLabel];
4238 /// initialize id global of elements.
4239
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 744 times.
19344 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
4240 18600 numElement[static_cast<ElementType>(ityp)] = 0;
4241 }
4242
4243 744 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[iMesh]->bagElementTypeDomainBoundary();
4244
2/2
✓ Branch 1 taken 744 times.
✓ Branch 2 taken 744 times.
1488 for (std::size_t i = 0; i < bagElementTypeDomainBoundary.size(); ++i) {
4245 744 eltType = bagElementTypeDomainBoundary[i];
4246
4247
1/2
✓ Branch 1 taken 744 times.
✗ Branch 2 not taken.
744 defineCurvilinearFiniteElement(eltType);
4248
1/2
✓ Branch 1 taken 744 times.
✗ Branch 2 not taken.
744 initElementArrayBD();
4249
4250 744 CurvilinearFiniteElement* fePtr = m_listCurvilinearFiniteElement[idVar];
4251
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 744 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
744 FEL_ASSERT(fePtr);
4252 744 CurvilinearFiniteElement& fe = *fePtr;
4253 744 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
4254
1/2
✓ Branch 1 taken 744 times.
✗ Branch 2 not taken.
744 elemPoint.resize(numPointPerElt, nullptr);
4255
1/2
✓ Branch 1 taken 744 times.
✗ Branch 2 not taken.
744 elemIdPoint.resize(numPointPerElt, 0);
4256
4257
2/2
✓ Branch 8 taken 2292 times.
✓ Branch 9 taken 744 times.
3036 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
4258 2292 currentLabel = itRef->first;
4259 2292 numEltPerLabel = itRef->second.second;
4260
2/2
✓ Branch 0 taken 186 times.
✓ Branch 1 taken 2106 times.
2292 if ( searchLabel == currentLabel) {
4261 // dofValue contains : values in dof by element.
4262 372 double dofValue[fe.numDof()*numComp];
4263 // idGlobalDof contains: global number od dof by element.
4264 186 felInt idGlobalDof[fe.numDof()*numComp];
4265
2/2
✓ Branch 0 taken 5422 times.
✓ Branch 1 taken 186 times.
5608 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
4266
1/2
✓ Branch 1 taken 5422 times.
✗ Branch 2 not taken.
5422 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
4267
4268 // loop over all the support elements
4269
2/2
✓ Branch 1 taken 5422 times.
✓ Branch 2 taken 5422 times.
10844 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
4270 // get the id of the support
4271 5422 ielSupportDof = vectorIdSupport[it];
4272
4273
1/2
✓ Branch 1 taken 5422 times.
✗ Branch 2 not taken.
5422 fe.updateMeasNormal(0, elemPoint);
4274
2/2
✓ Branch 0 taken 1331 times.
✓ Branch 1 taken 4091 times.
5422 if(numComp == 1) { // only for scalar case
4275
1/2
✓ Branch 1 taken 1331 times.
✗ Branch 2 not taken.
1331 tmpMeasure[iLabel] += fe.measure() ;
4276 }
4277 5422 cpt = 0;
4278
2/2
✓ Branch 1 taken 20406 times.
✓ Branch 2 taken 5422 times.
25828 for(int iDof=0; iDof<fe.numDof(); iDof++) {
4279
2/2
✓ Branch 0 taken 53232 times.
✓ Branch 1 taken 20406 times.
73638 for(int iComp = 0; iComp<numComp; iComp++) {
4280
1/2
✓ Branch 1 taken 53232 times.
✗ Branch 2 not taken.
53232 m_dof.loc2glob(ielSupportDof,iDof,idVar,iComp,idDof);
4281 53232 idGlobalDof[cpt] = idDof;
4282 53232 cpt++;
4283 }
4284 }
4285
4286 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
4287
1/2
✓ Branch 2 taken 5422 times.
✗ Branch 3 not taken.
5422 AOApplicationToPetsc(m_ao,fe.numDof()*numComp,idGlobalDof);
4288 //gets values of associate dofs.
4289
1/2
✓ Branch 2 taken 5422 times.
✗ Branch 3 not taken.
5422 seqVec.getValues(fe.numDof()*numComp,idGlobalDof,dofValue);
4290
4291
2/2
✓ Branch 1 taken 28392 times.
✓ Branch 2 taken 5422 times.
33814 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
4292 28392 cpt = 0;
4293
2/2
✓ Branch 1 taken 110016 times.
✓ Branch 2 taken 28392 times.
138408 for(int idof=0; idof<fe.numDof(); idof++) {
4294
2/2
✓ Branch 0 taken 23958 times.
✓ Branch 1 taken 86058 times.
110016 if( numComp == 1) { // pressure
4295
2/4
✓ Branch 2 taken 23958 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 23958 times.
✗ Branch 6 not taken.
23958 tmpQuantity[iLabel] += fe.phi[ig](idof) * dofValue[cpt] * fe.weightMeas(ig);
4296 23958 cpt++;
4297 } else { // velocity Flux
4298
2/2
✓ Branch 1 taken 258174 times.
✓ Branch 2 taken 86058 times.
344232 for (int icomp = 0; icomp < fe.numCoor(); icomp++) {
4299
3/6
✓ Branch 2 taken 258174 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 258174 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 258174 times.
✗ Branch 10 not taken.
258174 tmpQuantity[iLabel] += fe.phi[ig](idof) * dofValue[cpt] * fe.normal[ig](icomp) * fe.weightMeas(ig);
4300 258174 cpt++;
4301 }
4302 }
4303 }
4304 }
4305 }
4306 5422 numElement[eltType]++;
4307 }
4308 186 } else
4309 2106 numElement[eltType]+= numEltPerLabel;
4310 }
4311 }
4312 }
4313
4314
2/2
✓ Branch 1 taken 744 times.
✓ Branch 2 taken 416 times.
1160 for (std::size_t iq = 0; iq < tmpQuantity.size(); iq++) {
4315 //Synchronise value of processors (every processors get a part of the meanQuantity and measure value).
4316
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 612 times.
744 if(numComp == 1) { // only for scalar case
4317
2/4
✓ Branch 1 taken 132 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 132 times.
✗ Branch 7 not taken.
132 MPI_Allreduce(&tmpMeasure[iq], &measure[iq], 1,MPI_DOUBLE, MPI_SUM,MpiInfo::petscComm());
4318 }
4319
2/4
✓ Branch 1 taken 744 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 744 times.
✗ Branch 7 not taken.
744 MPI_Allreduce(&tmpQuantity[iq], &meanQuantity[iq], 1, MPI_DOUBLE, MPI_SUM, MpiInfo::petscComm());
4320
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 612 times.
744 if(numComp == 1) { // only for scalar case
4321 132 meanQuantity[iq] /= measure[iq];
4322 }
4323 }
4324 416 }
4325
4326 /***********************************************************************************/
4327 /***********************************************************************************/
4328
4329 void LinearProblem::computeMeanExternalQuantity(PetscVector& seqVec, AO externalAO, PhysicalVariable unknown, const std::vector<int>& label, std::vector<double>& meanQuantity)
4330 {
4331 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
4332 const int idVar = m_listUnknown.idVariable(iUnknown);
4333 const int iMesh = m_listVariable[idVar].idMesh();
4334 const Variable& variable = m_listVariable[idVar];
4335 const int numComp = variable.numComponent();
4336
4337 //geometric element type in the mesh.
4338 ElementType eltType;
4339 //number of points per geometric element.
4340 int numPointPerElt = 0;
4341 int currentLabel = 0;
4342 //number of element for one label and one eltType.
4343 felInt numEltPerLabel = 0;
4344 //Points of the current element.
4345 std::vector<Point*> elemPoint;
4346 //Id of points of the element.
4347 std::vector<felInt> elemIdPoint;
4348 //Ids of support elements of a mesh element
4349 std::vector<felInt> vectorIdSupport;
4350
4351 // use to identify global id of dof.
4352 felInt idDof;
4353 felInt cpt = 0;
4354 //Id link element to its supportDof.
4355 felInt ielSupportDof;
4356 meanQuantity.clear();
4357 meanQuantity.resize(label.size(),0.);
4358
4359 std::vector<double> tmpQuantity(label.size(),0.);
4360 std::vector<double> measure(label.size(),0.);
4361 std::vector<double> tmpMeasure(label.size(),0.);
4362
4363 int searchLabel=-1;
4364 felInt numElement[GeometricMeshRegion::m_numTypesOfElement];
4365
4366 for(std::size_t iLabel = 0; iLabel < label.size(); iLabel++) {
4367 searchLabel = label[iLabel];
4368 /// initialize id global of elements.
4369 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
4370 numElement[static_cast<ElementType>(ityp)] = 0;
4371 }
4372
4373 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[iMesh]->bagElementTypeDomainBoundary();
4374 for (std::size_t i = 0; i < bagElementTypeDomainBoundary.size(); ++i) {
4375 eltType = bagElementTypeDomainBoundary[i];
4376
4377 defineCurvilinearFiniteElement(eltType);
4378 initElementArrayBD();
4379
4380 CurvilinearFiniteElement* fePtr = m_listCurvilinearFiniteElement[idVar];
4381 FEL_ASSERT(fePtr);
4382 CurvilinearFiniteElement& fe = *fePtr;
4383 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
4384 elemPoint.resize(numPointPerElt, nullptr);
4385 elemIdPoint.resize(numPointPerElt, 0);
4386
4387 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
4388 currentLabel = itRef->first;
4389 numEltPerLabel = itRef->second.second;
4390 if ( searchLabel == currentLabel) {
4391 // dofValue contains : values in dof by element.
4392 double dofValue[fe.numDof()*numComp];
4393 // idGlobalDof contains: global number od dof by element.
4394 felInt idGlobalDof[fe.numDof()*numComp];
4395 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
4396 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
4397
4398 // loop over all the support elements
4399 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
4400 // get the id of the support
4401 ielSupportDof = vectorIdSupport[it];
4402
4403 fe.updateMeasNormal(0, elemPoint);
4404 if(numComp == 1) { // only for scalar case
4405 tmpMeasure[iLabel] += fe.measure() ;
4406 }
4407 cpt = 0;
4408 for(int iDof=0; iDof<fe.numDof(); iDof++) {
4409 for(int iComp = 0; iComp<numComp; iComp++) {
4410 m_dof.loc2glob(ielSupportDof,iDof,idVar,iComp,idDof);
4411 idGlobalDof[cpt] = idDof;
4412 cpt++;
4413 }
4414 }
4415
4416 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
4417 AOApplicationToPetsc(externalAO,fe.numDof()*numComp,idGlobalDof);
4418 //gets values of associate dofs.
4419 seqVec.getValues(fe.numDof()*numComp,idGlobalDof,dofValue);
4420
4421 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
4422 cpt = 0;
4423 for(int idof=0; idof<fe.numDof(); idof++) {
4424 if( numComp == 1) { // pressure
4425 tmpQuantity[iLabel] += fe.phi[ig](idof) * dofValue[cpt] * fe.weightMeas(ig);
4426 cpt++;
4427 } else { // velocity Flux
4428 for (int icomp = 0; icomp < fe.numCoor(); icomp++) {
4429 tmpQuantity[iLabel] += fe.phi[ig](idof) * dofValue[cpt] * fe.normal[ig](icomp) * fe.weightMeas(ig);
4430 cpt++;
4431 }
4432 }
4433 }
4434 }
4435 }
4436 numElement[eltType]++;
4437 }
4438 } else
4439 numElement[eltType]+= numEltPerLabel;
4440 }
4441 }
4442 }
4443
4444 for (std::size_t iq = 0; iq < tmpQuantity.size(); iq++) {
4445 //Synchronise value of processors (every processors get a part of the meanQuantity and measure value).
4446 if(numComp == 1) { // only for scalar case
4447 MPI_Allreduce(&tmpMeasure[iq], &measure[iq], 1,MPI_DOUBLE, MPI_SUM,MpiInfo::petscComm());
4448 }
4449 MPI_Allreduce(&tmpQuantity[iq], &meanQuantity[iq], 1, MPI_DOUBLE, MPI_SUM, MpiInfo::petscComm());
4450 if(numComp == 1) { // only for scalar case
4451 meanQuantity[iq] /= measure[iq];
4452 }
4453 }
4454 }
4455
4456 /***********************************************************************************/
4457 /***********************************************************************************/
4458
4459 void LinearProblem::computeMeanQuantityDomain(PhysicalVariable unknown, const std::vector<int>& label, std::vector<double>& meanQuantity, std::vector<double>& measure)
4460 {
4461 gatherSolution();
4462 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
4463 const int idVar = m_listUnknown.idVariable(iUnknown);
4464 const int iMesh = m_listVariable[idVar].idMesh();
4465 const Variable& variable = m_listVariable[idVar];
4466 const int numComp = variable.numComponent();
4467
4468 //geometric element type in the mesh.
4469 ElementType eltType;
4470 //number of points per geometric element.
4471 int numPointPerElt = 0;
4472 int currentLabel = 0;
4473 //number of element for one label and one eltType.
4474 felInt numEltPerLabel = 0;
4475 //Points of the current element.
4476 std::vector<Point*> elemPoint;
4477 //Id of points of the element.
4478 std::vector<felInt> elemIdPoint;
4479 //Ids of support elements of a mesh element
4480 std::vector<felInt> vectorIdSupport;
4481
4482 // use to identify global id of dof.
4483 felInt idDof;
4484 felInt cpt = 0;
4485 //Id link element to its supportDof.
4486 felInt ielSupportDof;
4487 meanQuantity.clear();
4488 meanQuantity.resize(numComp*label.size(),0.0);
4489 measure.clear();
4490 measure.resize(label.size(), 0.0);
4491 std::vector<double> tmpQuantity(numComp*label.size(),0.0);
4492 std::vector<double> tmpMeasure(label.size(),0.0);
4493
4494 int searchLabel=-1;
4495 felInt numElement[GeometricMeshRegion::m_numTypesOfElement];
4496 for(std::size_t iLabel = 0; iLabel < label.size(); iLabel++) {
4497 searchLabel = label[iLabel];
4498 /// initialize id global of elements.
4499 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
4500 numElement[static_cast<ElementType>(ityp)] = 0;
4501 }
4502 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[iMesh]->bagElementTypeDomain();
4503 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
4504 eltType = bagElementTypeDomain[i];
4505
4506 defineFiniteElement(eltType);
4507
4508 //Element matrix and vector initialisation
4509 initElementArray();
4510
4511 CurrentFiniteElement* fePtr = m_listCurrentFiniteElement[idVar];
4512 FEL_ASSERT(fePtr);
4513 CurrentFiniteElement& fe = *fePtr;
4514
4515 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
4516
4517 elemPoint.resize(numPointPerElt, nullptr);
4518 elemIdPoint.resize(numPointPerElt, 0);
4519
4520 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
4521 currentLabel = itRef->first;
4522 numEltPerLabel = itRef->second.second;
4523 if ( searchLabel == currentLabel) {
4524 // dofValue contains : values in dof by element.
4525 double dofValue[fe.numDof()*numComp];
4526 // idGlobalDof contains: global number od dof by element.
4527 felInt idGlobalDof[fe.numDof()*numComp];
4528 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
4529 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
4530
4531 // loop over all the support elements
4532 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
4533 // get the id of the support
4534 ielSupportDof = vectorIdSupport[it];
4535
4536 fe.updateMeas(0, elemPoint);
4537 tmpMeasure[iLabel] += fe.measure() ;
4538 cpt = 0;
4539 for(int iDof=0; iDof<fe.numDof(); iDof++) {
4540 for(int iComp = 0; iComp<numComp; iComp++) {
4541 m_dof.loc2glob(ielSupportDof,iDof,iUnknown,iComp,idDof);
4542 idGlobalDof[cpt] = idDof;
4543 cpt++;
4544 }
4545 }
4546
4547 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
4548 AOApplicationToPetsc(m_ao,fe.numDof()*numComp,idGlobalDof);
4549 //gets values of associate dofs.
4550 m_seqSol.getValues(fe.numDof()*numComp,idGlobalDof,dofValue);
4551
4552 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
4553 cpt = 0;
4554 for(int idof=0; idof<fe.numDof(); idof++) {
4555 for (int iComp=0; iComp<numComp; iComp++) {
4556 tmpQuantity[iComp+iLabel*numComp] += fe.phi[ig](idof) * dofValue[cpt] * fe.weightMeas(ig);
4557 cpt++;
4558 }
4559 }
4560 }
4561 }
4562 numElement[eltType]++;
4563 }
4564 } else {
4565 numElement[eltType]+= numEltPerLabel;
4566 }
4567 }
4568 }
4569 }
4570 for (std::size_t iq = 0; iq < label.size(); iq++) {
4571 //Synchronise value of processors (every processors get a part of the meanQuantity and measure value).
4572 MPI_Allreduce(&tmpMeasure[iq], &measure[iq], 1,MPI_DOUBLE, MPI_SUM,MpiInfo::petscComm());
4573 for (int iComp=0; iComp<numComp; iComp++) {
4574 MPI_Allreduce(&tmpQuantity[iComp+iq*numComp], &meanQuantity[iComp+iq*numComp], 1, MPI_DOUBLE, MPI_SUM, MpiInfo::petscComm());
4575 meanQuantity[iComp+iq*numComp] /= measure[iq];
4576 }
4577 }
4578 }
4579
4580 /***********************************************************************************/
4581 /***********************************************************************************/
4582
4583 void LinearProblem::computeMeasure(const std::vector<int>& label, std::vector<double>& measure)
4584 {
4585 // Geometric element type in the mesh.
4586 ElementType eltType;
4587
4588 // Number of points per geometric element.
4589 int numPointPerElt = 0;
4590 int currentLabel = 0;
4591
4592 // Number of element for one label and one eltType.
4593 felInt numEltPerLabel = 0;
4594
4595 //Points of the current element.
4596 std::vector<Point*> elemPoint;
4597
4598 //Id of points of the element.
4599 std::vector<felInt> elemIdPoint;
4600
4601 //Ids of support elements of a mesh element
4602 std::vector<felInt> vectorIdSupport;
4603
4604 std::vector<double> tmpMeasure(label.size(),0.);
4605
4606 int searchLabel=-1;
4607 felInt numElement[GeometricMeshRegion::m_numTypesOfElement];
4608
4609 for(std::size_t iLabel = 0; iLabel < label.size(); iLabel++) {
4610 searchLabel = label[iLabel];
4611 /// initialize id global of elements.
4612 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
4613 numElement[static_cast<ElementType>(ityp)] = 0;
4614 }
4615
4616 // TODO D.C. what if idVar 0 is not defined on m_currentMesh??
4617 // what is the purpose of this function? to compute the volume of elements? it is a geometric operation... why do we use FE?
4618 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[m_currentMesh]->bagElementTypeDomainBoundary();
4619 for (std::size_t i = 0; i < bagElementTypeDomainBoundary.size(); ++i) {
4620 eltType = bagElementTypeDomainBoundary[i];
4621
4622 defineCurvilinearFiniteElement(eltType);
4623 initElementArrayBD();
4624
4625 CurvilinearFiniteElement* fePtr = m_listCurvilinearFiniteElement[0]; // idVar = 0 (default FE)
4626 FEL_ASSERT(fePtr);
4627 CurvilinearFiniteElement& fe = *fePtr;
4628 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
4629 elemPoint.resize(numPointPerElt, nullptr);
4630 elemIdPoint.resize(numPointPerElt, 0);
4631
4632 for(auto itRef = m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
4633 currentLabel = itRef->first;
4634 numEltPerLabel = itRef->second.second;
4635 if ( searchLabel == currentLabel) {
4636 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
4637 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
4638 // loop over all the support elements
4639 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
4640 fe.updateMeas(0, elemPoint);
4641 tmpMeasure[iLabel] += fe.measure() ;
4642 }
4643 numElement[eltType]++;
4644 }
4645 } else
4646 numElement[eltType]+= numEltPerLabel;
4647 }
4648 }
4649 }
4650
4651 for (std::size_t iq = 0; iq < label.size(); iq++) {
4652 //Synchronise value of processors (every processors get a part of the measure value).
4653 MPI_Allreduce(&tmpMeasure[iq], &measure[iq], 1,MPI_DOUBLE, MPI_SUM,MpiInfo::petscComm());
4654 }
4655 }
4656
4657 /***********************************************************************************/
4658 /***********************************************************************************/
4659
4660 void LinearProblem::computeMeasureNormal(const std::vector<int>& label, std::vector<double>& measure, std::vector<double>& normal)
4661 {
4662 //geometric element type in the mesh.
4663 ElementType eltType;
4664 //number of points per geometric element.
4665 int numPointPerElt = 0;
4666 int currentLabel = 0;
4667 //number of element for one label and one eltType.
4668 felInt numEltPerLabel = 0;
4669 //Points of the current element.
4670 std::vector<Point*> elemPoint;
4671 //Id of points of the element.
4672 std::vector<felInt> elemIdPoint;
4673 //Ids of support elements of a mesh element
4674 std::vector<felInt> vectorIdSupport;
4675
4676 std::vector<double> tmpMeasure(label.size(),0.);
4677 std::vector<double> tmpNormal(3*label.size(),0.);
4678 std::vector<int> tmpCounter(label.size(),0);
4679 std::vector<int> counter(label.size(),0);
4680 int searchLabel=-1;
4681 felInt numElement[GeometricMeshRegion::m_numTypesOfElement];
4682
4683 for(std::size_t iLabel = 0; iLabel < label.size(); iLabel++) {
4684 searchLabel = label[iLabel];
4685 /// initialize id global of elements.
4686 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
4687 numElement[static_cast<ElementType>(ityp)] = 0;
4688 }
4689
4690 // TODO D.C. what if idVar 0 is not defined on m_currentMesh??
4691 // what is the purpose of this function? to compute the volume of elements? it is a geometric operation... why do we use FE?
4692 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[m_currentMesh]->bagElementTypeDomainBoundary();
4693 for (std::size_t i = 0; i < bagElementTypeDomainBoundary.size(); ++i) {
4694 eltType = bagElementTypeDomainBoundary[i];
4695
4696 defineCurvilinearFiniteElement(eltType);
4697 initElementArrayBD();
4698
4699 CurvilinearFiniteElement* fePtr = m_listCurvilinearFiniteElement[0]; // idVar = 0 (default FE)
4700 FEL_ASSERT(fePtr);
4701 CurvilinearFiniteElement& fe = *fePtr;
4702 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
4703 elemPoint.resize(numPointPerElt, nullptr);
4704 elemIdPoint.resize(numPointPerElt, 0);
4705
4706 for(auto itRef = m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
4707 currentLabel = itRef->first;
4708 numEltPerLabel = itRef->second.second;
4709 if ( searchLabel == currentLabel) {
4710 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
4711 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
4712 fe.updateMeasNormal(0, elemPoint);
4713 tmpMeasure[iLabel] += fe.measure() ;
4714 for (int icomp = 0; icomp < fe.numCoor(); icomp++) tmpNormal[3*iLabel+icomp] += fe.normal[0](icomp); // 1st gauss point
4715 tmpCounter[iLabel]++;
4716 numElement[eltType]++;
4717 }
4718 } else
4719 numElement[eltType]+= numEltPerLabel;
4720 }
4721 }
4722 }
4723
4724 for (std::size_t iq = 0; iq < label.size(); iq++) {
4725 //Synchronise value of processors (every processors get a part of the measure value).
4726 MPI_Allreduce(&tmpMeasure[iq], &measure[iq], 1,MPI_DOUBLE, MPI_SUM,MpiInfo::petscComm());
4727 MPI_Allreduce(&tmpCounter[iq], &counter[iq], 1,MPI_INT, MPI_SUM,MpiInfo::petscComm());
4728 for (int icomp = 0; icomp < 3; icomp++) {
4729 MPI_Allreduce(&tmpNormal[3*iq+icomp], &normal[3*iq+icomp], 1,MPI_DOUBLE, MPI_SUM,MpiInfo::petscComm());
4730 normal[3*iq+icomp] /= counter[iq];
4731 }
4732 }
4733 }
4734
4735 /***********************************************************************************/
4736 /***********************************************************************************/
4737
4738 void LinearProblem::errorL2(PhysicalVariable unknown, std::vector<double>& fctExactSolOnDof, double& resultL2Norm)
4739 {
4740 gatherSolution();
4741 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
4742 const int idVar = m_listUnknown.idVariable(iUnknown);
4743 const int iMesh = m_listVariable[idVar].idMesh();
4744 const Variable& variable = m_listVariable[idVar];
4745 // todo generalize for every multiple type of element in mesh.
4746 CurrentFiniteElement* fePtr = m_listCurrentFiniteElement[idVar];
4747 FEL_ASSERT(fePtr);
4748 CurrentFiniteElement& fe = *fePtr;
4749
4750 const auto feNumDof = fe.numDof();
4751 const int numComp = variable.numComponent();
4752 // dofValue contains : values in dof by element.
4753 double dofValue[feNumDof*numComp];
4754 // idGlobalDof contains: global number id dof by element.
4755 felInt idGlobalDof[feNumDof*numComp];
4756 felInt idGlobalDof1[feNumDof*numComp];
4757 felInt fctExactSolOnDofSize = fctExactSolOnDof.size();
4758
4759 //geometric element type in the mesh.
4760 ElementType eltType;
4761 //number of points per geometric element.
4762 int numPointPerElt = 0;
4763 //number of element for one label and one eltType.
4764 felInt numEltPerLabel = 0;
4765 //Points of the current element.
4766 std::vector<Point*> elemPoint;
4767 //Id of points of the element.
4768 std::vector<felInt> elemIdPoint;
4769 // Ids of support elements of a mesh element
4770 std::vector<felInt> vectorIdSupport;
4771
4772 // use to identify global id of dof.
4773 felInt idDof;
4774 felInt cpt = 0;
4775 //Id link element to its supportDof.
4776 felInt ielSupportDof;
4777 resultL2Norm = 0.;
4778 double tmpL2Norm = 0.;
4779
4780 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
4781
4782 /// initialize id global of elements.
4783 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
4784 eltType = (ElementType)ityp;
4785 numElement[eltType] = 0;
4786 }
4787
4788 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[iMesh]->bagElementTypeDomain();
4789 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
4790 eltType = bagElementTypeDomain[i];
4791 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
4792 elemPoint.resize(numPointPerElt, nullptr);
4793 elemIdPoint.resize(numPointPerElt, 0);
4794
4795 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
4796 numEltPerLabel = itRef->second.second;
4797 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
4798 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
4799
4800 // Loop over all the support elements
4801 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
4802 // get the id of the support
4803 ielSupportDof = vectorIdSupport[it];
4804
4805 cpt = 0;
4806 for(int iDof=0; iDof<feNumDof; iDof++) {
4807 for(int iComp = 0; iComp<numComp; iComp++) {
4808 m_dof.loc2glob(ielSupportDof,iDof,idVar,iComp,idDof);
4809 idGlobalDof[cpt] = idDof;
4810
4811 if (variable.physicalVariable() == velocity)
4812 idGlobalDof1[cpt] = idDof;
4813 else if (variable.physicalVariable() == pressure)
4814 idGlobalDof1[cpt] = idDof - numDofPerUnknown(velocity); //because the variable order is usually 'velocity pressure'
4815 else
4816 FEL_ERROR("Variable unknown in this errorL2 function.");
4817 cpt++;
4818 }
4819 }
4820
4821 // Mapping to obtain new global numbering. (I/O array: idGlobalDof).
4822 AOApplicationToPetsc(m_ao,feNumDof*numComp,idGlobalDof);
4823 // Gets values of associate dofs.
4824 m_seqSol.getValues(feNumDof*numComp,idGlobalDof,dofValue);
4825
4826 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
4827 double c1 = 0.;
4828 for(int iComp=0; iComp<numComp; iComp++) {
4829 double uicomp = 0.;
4830 for(int idof = 0; idof<feNumDof; idof++) {
4831 cpt = idof*numComp+iComp;
4832 if (idGlobalDof1[cpt] < fctExactSolOnDofSize)
4833 uicomp += fe.phi[ig](idof) * (dofValue[cpt] - fctExactSolOnDof[idGlobalDof1[cpt]]);
4834 }
4835 c1 += uicomp * uicomp;
4836 }
4837 tmpL2Norm += c1 * fe.weightMeas(ig);
4838 }
4839 }
4840 numElement[eltType]++;
4841 }
4842 }
4843 }
4844
4845 MPI_Allreduce(&tmpL2Norm, &resultL2Norm, 1, MPI_DOUBLE, MPI_SUM, MpiInfo::petscComm());
4846 resultL2Norm = std::sqrt(resultL2Norm) ;
4847 }
4848
4849 /***********************************************************************************/
4850 /***********************************************************************************/
4851
4852 void LinearProblem::computel2NormSquared(PhysicalVariable unknown, int rankProc, double& l2NormSquared)
4853 {
4854 IGNORE_UNUSED_RANK_PROC;
4855 gatherSolution();
4856
4857 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
4858 const int idVar = m_listUnknown.idVariable(iUnknown);
4859 const int iMesh = m_listVariable[idVar].idMesh();
4860 const Variable& variable = m_listVariable[idVar];
4861 const int numComp = variable.numComponent();
4862
4863 //geometric element type in the mesh.
4864 ElementType eltType;
4865
4866 //number of points per geometric element.
4867 int numPointPerElt = 0;
4868
4869 //number of element for one label and one eltType.
4870 felInt numEltPerLabel = 0;
4871
4872 //Points of the current element.
4873 std::vector<Point*> elemPoint;
4874
4875 //Id of points of the element.
4876 std::vector<felInt> elemIdPoint;
4877
4878 // Ids of support elements for a mesh element
4879 std::vector <felInt> vectorIdSupport;
4880
4881 // use to identify global id of dof.
4882 felInt idDof;
4883 felInt cpt = 0;
4884
4885 //Id link element to its supportDof.
4886 felInt ielSupportDof;
4887
4888 // l2 norms
4889 l2NormSquared = 0.;
4890 double tmpl2NormSquared = 0;
4891
4892 // number of element by type
4893 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
4894 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
4895 eltType = (ElementType)ityp;
4896 numElement[eltType] = 0;
4897 }
4898
4899 // loop over element type
4900 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[iMesh]->bagElementTypeDomain();
4901 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
4902 eltType = bagElementTypeDomain[i];
4903 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
4904 elemPoint.resize(numPointPerElt, nullptr);
4905 elemIdPoint.resize(numPointPerElt, 0);
4906
4907 // define the finite element
4908 defineFiniteElement(eltType);
4909
4910 //Element matrix and vector initialisation
4911 initElementArray();
4912
4913 CurrentFiniteElement* fePtr = m_listCurrentFiniteElement[idVar];
4914 FEL_ASSERT(fePtr);
4915
4916 // dofValue contains : values in dof by element.
4917 double dofValue[fePtr->numDof()*numComp];
4918
4919 // idGlobalDof contains: global number od dof by element.
4920 felInt idGlobalDof[fePtr->numDof()*numComp];
4921
4922 // loop over labels
4923 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
4924 numEltPerLabel = itRef->second.second;
4925
4926 // loop over element
4927 for (felInt iel = 0; iel < numEltPerLabel; iel++) {
4928 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
4929 fePtr->updateMeas(0, elemPoint);
4930
4931 // loop over all the support elements
4932 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
4933 // get the id of the support
4934 ielSupportDof = vectorIdSupport[it];
4935
4936 cpt = 0;
4937 for(int iDof=0; iDof<fePtr->numDof(); iDof++) {
4938 for(int iComp = 0; iComp<numComp; iComp++) {
4939 m_dof.loc2glob(ielSupportDof,iDof,idVar,iComp,idDof);
4940 idGlobalDof[cpt] = idDof;
4941 cpt++;
4942 }
4943 }
4944
4945 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
4946 AOApplicationToPetsc(m_ao,fePtr->numDof()*numComp,idGlobalDof);
4947
4948 //gets values of associate dofs.
4949 m_seqSol.getValues(fePtr->numDof()*numComp,idGlobalDof,dofValue);
4950
4951 for(int ig=0; ig<fePtr->numQuadraturePoint(); ig++) {
4952 double c1 = 0.;
4953 for(int iComp=0; iComp<numComp; iComp++) {
4954 double uicomp = 0.;
4955 for(int idof = 0; idof<fePtr->numDof(); idof++) {
4956 uicomp += fePtr->phi[ig](idof) * dofValue[idof*numComp+iComp] ;
4957 }
4958 c1 += uicomp * uicomp;
4959 }
4960 tmpl2NormSquared += c1 * fePtr->weightMeas(ig);
4961 }
4962 }
4963 numElement[eltType]++;
4964 }
4965 }
4966 }
4967
4968 MPI_Allreduce(&tmpl2NormSquared,&l2NormSquared, 1,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm());
4969 }
4970
4971 /***********************************************************************************/
4972 /***********************************************************************************/
4973
4974 void LinearProblem::computeSemiNormH1Squared(PhysicalVariable unknown, int rankProc, double& semiNormH1Squared)
4975 {
4976 IGNORE_UNUSED_RANK_PROC;
4977 gatherSolution();
4978 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
4979 const int idVar = m_listUnknown.idVariable(iUnknown);
4980 const int iMesh = m_listVariable[idVar].idMesh();
4981 const Variable& variable = m_listVariable[idVar];
4982 const int numComp = variable.numComponent();
4983
4984 //geometric element type in the mesh.
4985 ElementType eltType;
4986
4987 //number of points per geometric element.
4988 int numPointPerElt = 0;
4989
4990 //number of element for one label and one eltType.
4991 felInt numEltPerLabel = 0;
4992
4993 //Points of the current element.
4994 std::vector<Point*> elemPoint;
4995
4996 //Id of points of the element.
4997 std::vector<felInt> elemIdPoint;
4998
4999 // Ids of support elements for a mesh element
5000 std::vector <felInt> vectorIdSupport;
5001
5002 // use to identify global id of dof.
5003 felInt idDof;
5004 felInt cpt = 0;
5005
5006 //Id link element to its supportDof.
5007 felInt ielSupportDof;
5008 semiNormH1Squared = 0.;
5009 double tmpsemiNormH1Squared = 0.;
5010
5011 // number of element per type
5012 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
5013 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
5014 eltType = (ElementType)ityp;
5015 numElement[eltType] = 0;
5016 }
5017
5018 // loop over element type
5019 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[iMesh]->bagElementTypeDomain();
5020 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
5021 eltType = bagElementTypeDomain[i];
5022 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
5023 elemPoint.resize(numPointPerElt, nullptr);
5024 elemIdPoint.resize(numPointPerElt, 0);
5025
5026 // define finite elements
5027 defineFiniteElement(eltType);
5028
5029 //Element matrix and vector initialisation
5030 initElementArray();
5031
5032 CurrentFiniteElement* fePtr = m_listCurrentFiniteElement[idVar];
5033 FEL_ASSERT(fePtr);
5034
5035 // dofValue contains : values in dof by element.
5036 double dofValue[fePtr->numDof()*numComp];
5037
5038 // idGlobalDof contains: global number od dof by element.
5039 felInt idGlobalDof[fePtr->numDof()*numComp];
5040
5041 // loop over labels
5042 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
5043 numEltPerLabel = itRef->second.second;
5044
5045 // loop over elements
5046 for (felInt iel = 0; iel < numEltPerLabel; iel++) {
5047 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
5048 fePtr->updateFirstDeriv(0, elemPoint);
5049
5050 // loop over all the support elements
5051 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
5052 // get the id of the support
5053 ielSupportDof = vectorIdSupport[it];
5054
5055 cpt = 0;
5056 for(int iDof=0; iDof<fePtr->numDof(); iDof++) {
5057 for(int iComp = 0; iComp<numComp; iComp++) {
5058 m_dof.loc2glob(ielSupportDof,iDof,idVar,iComp,idDof);
5059 idGlobalDof[cpt] = idDof;
5060 cpt++;
5061 }
5062 }
5063
5064 // Mapping to obtain new global numbering. (I/O array: idGlobalDof).
5065 AOApplicationToPetsc(m_ao,fePtr->numDof()*numComp,idGlobalDof);
5066
5067 // Gets values of associate dofs.
5068 m_seqSol.getValues(fePtr->numDof()*numComp,idGlobalDof,dofValue);
5069
5070 for (int ig=0; ig<fePtr->numQuadraturePoint(); ig++) {
5071 double b1 = 0.;
5072 for (int icomp=0; icomp<numComp; icomp++) {
5073 for (int jcoor=0; jcoor<fePtr->numCoor(); jcoor++) {
5074 double a1 = 0.;
5075 for (int idof=0; idof<fePtr->numDof(); idof++) {
5076 a1 += fePtr->dPhi[ig](jcoor,idof) * dofValue[idof*fePtr->numCoor()+icomp];
5077 }
5078 b1 += a1 * a1;
5079 }
5080 }
5081 tmpsemiNormH1Squared += b1 * fePtr->weightMeas(ig) ;
5082 }
5083 }
5084 numElement[eltType]++;
5085 }
5086 }
5087 }
5088
5089 MPI_Allreduce(&tmpsemiNormH1Squared, &semiNormH1Squared, 1, MPI_DOUBLE, MPI_SUM, MpiInfo::petscComm());
5090 }
5091
5092 /***********************************************************************************/
5093 /***********************************************************************************/
5094
5095 void LinearProblem::computePowerBDu(PhysicalVariable unknown, int rankProc, const std::vector<int>& label, double density, std::vector<double>& PowerBDu)
5096 {
5097 IGNORE_UNUSED_RANK_PROC;
5098 gatherSolution();
5099 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
5100 const int idVar = m_listUnknown.idVariable(iUnknown);
5101 const int iMesh = m_listVariable[idVar].idMesh();
5102 const Variable& variable = m_listVariable[idVar];
5103
5104 const int numComp = variable.numComponent();
5105
5106 //geometric element type in the mesh.
5107 ElementType eltType;
5108 //number of points per geometric element.
5109 int numPointPerElt = 0;
5110 //current region of mesh.
5111 int currentLabel = 0;
5112 //number of element for one label and one eltType.
5113 felInt numEltPerLabel = 0;
5114 //Points of the current element.
5115 std::vector<Point*> elemPoint;
5116 //Id of points of the element.
5117 std::vector<felInt> elemIdPoint;
5118 // Ids of support elements for a mesh element
5119 std::vector <felInt> vectorIdSupport;
5120
5121 // use to identify global id of dof.
5122 felInt idDof;
5123 felInt cpt = 0;
5124 //Id link element to its supportDof.
5125 felInt ielSupportDof;
5126 PowerBDu.clear();
5127 PowerBDu.resize(label.size(),0.);
5128
5129 std::vector<double> tmpPowerBDu(label.size());
5130
5131 int searchLabel=-1;
5132 felInt numElement[GeometricMeshRegion::m_numTypesOfElement];
5133
5134 for(std::size_t iLabel = 0; iLabel < label.size(); iLabel++) {
5135 searchLabel = label[iLabel];
5136 tmpPowerBDu[iLabel] = 0.;
5137
5138 /// initialize id global of elements.
5139 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
5140 eltType = (ElementType)ityp;
5141 numElement[eltType] = 0;
5142 }
5143
5144 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[iMesh]->bagElementTypeDomainBoundary();
5145 for (std::size_t i = 0; i < bagElementTypeDomainBoundary.size(); ++i) {
5146 eltType = bagElementTypeDomainBoundary[i];
5147 defineCurvilinearFiniteElement(eltType);
5148 initElementArrayBD();
5149 CurvilinearFiniteElement* fePtr = m_listCurvilinearFiniteElement[idVar];
5150 FEL_ASSERT(fePtr);
5151 CurvilinearFiniteElement& fe = *fePtr;
5152 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
5153 elemPoint.resize(numPointPerElt, nullptr);
5154 elemIdPoint.resize(numPointPerElt, 0);
5155
5156 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
5157 currentLabel = itRef->first;
5158 numEltPerLabel = itRef->second.second;
5159 if ( searchLabel == currentLabel) {
5160 // dofValue contains : values in dof by element.
5161 double dofValue[fe.numDof()*numComp];
5162 // idGlobalDof contains: global number od dof by element.
5163 felInt idGlobalDof[fe.numDof()*numComp];
5164 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
5165 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
5166
5167 // loop over all the support elements
5168 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
5169 // get the id of the support
5170 ielSupportDof = vectorIdSupport[it];
5171
5172 fe.updateMeasNormal(0, elemPoint);
5173 cpt = 0;
5174 for(int iDof=0; iDof<fe.numDof(); iDof++) {
5175 for(int iComp = 0; iComp<numComp; iComp++) {
5176 m_dof.loc2glob(ielSupportDof,iDof,idVar,iComp,idDof);
5177 idGlobalDof[cpt] = idDof;
5178 cpt++;
5179 }
5180 }
5181
5182 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
5183 AOApplicationToPetsc(m_ao,fe.numDof()*numComp,idGlobalDof);
5184 //gets values of associate dofs.
5185 m_seqSol.getValues(fe.numDof()*numComp,idGlobalDof,dofValue);
5186
5187 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
5188 double c1 = 0.;
5189 for(int icomp=0; icomp<fe.numCoor(); icomp++) {
5190 double a1 = 0.;
5191 for (int idof = 0; idof < fe.numDof(); idof++) {
5192 a1 += fe.phi[ig](idof) * dofValue[idof*fe.numCoor()+icomp];
5193 }
5194 c1 += a1 * a1;
5195 }
5196 for (int icomp=0; icomp<fe.numCoor(); icomp++) {
5197 for (int idof = 0; idof < fe.numDof(); idof++) {
5198 tmpPowerBDu[iLabel] += c1 * fe.phi[ig](idof) * dofValue[idof*fe.numCoor()+icomp] * fe.normal[ig](icomp) * fe.weightMeas(ig) * density * 0.5;
5199 }
5200 }
5201 }
5202 }
5203 numElement[eltType]++;
5204 }
5205 } else
5206 numElement[eltType]+= numEltPerLabel;
5207 }
5208 }
5209 }
5210
5211 for (std::size_t i = 0; i < tmpPowerBDu.size(); i++) {
5212 //Symchronise value of processors (every processors get a part of the flux value).
5213 MPI_Allreduce(&tmpPowerBDu[i],&PowerBDu[i], 1,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm());
5214 }
5215 }
5216
5217 /***********************************************************************************/
5218 /***********************************************************************************/
5219
5220 void LinearProblem::computeConvBoundary(PhysicalVariable unknown, PetscVector& testFunction, int rankProc, const std::vector<int>& label, std::vector<double>& convBD)
5221 {
5222 IGNORE_UNUSED_RANK_PROC;
5223 gatherSolution();
5224
5225 /* switch test function to sequential */
5226 PetscVector seqTestFunction;
5227 if (MpiInfo::rankProc() == 0)
5228 seqTestFunction.duplicateFrom(this->sequentialSolution());
5229 gatherVector(testFunction, seqTestFunction);
5230
5231 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
5232 const int idVar = m_listUnknown.idVariable(iUnknown);
5233 const int iMesh = m_listVariable[idVar].idMesh();
5234 const Variable& variable = m_listVariable[idVar];
5235
5236 const int numComp = variable.numComponent();
5237
5238 //geometric element type in the mesh.
5239 ElementType eltType;
5240 //number of points per geometric element.
5241 int numPointPerElt = 0;
5242 //current region of mesh.
5243 int currentLabel = 0;
5244 //number of element for one label and one eltType.
5245 felInt numEltPerLabel = 0;
5246 //Points of the current element.
5247 std::vector<Point*> elemPoint;
5248 //Id of points of the element.
5249 std::vector<felInt> elemIdPoint;
5250 // Ids of support elements for a mesh element
5251 std::vector <felInt> vectorIdSupport;
5252
5253 // use to identify global id of dof.
5254 felInt idDof;
5255 felInt cpt = 0;
5256 //Id link element to its supportDof.
5257 felInt ielSupportDof;
5258 convBD.clear();
5259 convBD.resize(label.size(),0.);
5260
5261 std::vector<double> tmpconvBD(label.size());
5262
5263 int searchLabel=-1;
5264 felInt numElement[GeometricMeshRegion::m_numTypesOfElement];
5265
5266 for(std::size_t iLabel = 0; iLabel < label.size(); iLabel++) {
5267 searchLabel = label[iLabel];
5268 tmpconvBD[iLabel] = 0.;
5269
5270 /// initialize id global of elements.
5271 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
5272 eltType = (ElementType)ityp;
5273 numElement[eltType] = 0;
5274 }
5275
5276 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[iMesh]->bagElementTypeDomainBoundary();
5277 for (std::size_t i = 0; i < bagElementTypeDomainBoundary.size(); ++i) {
5278 eltType = bagElementTypeDomainBoundary[i];
5279 defineCurvilinearFiniteElement(eltType);
5280 initElementArrayBD();
5281 CurvilinearFiniteElement* fePtr = m_listCurvilinearFiniteElement[idVar];
5282 FEL_ASSERT(fePtr);
5283 CurvilinearFiniteElement& fe = *fePtr;
5284 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
5285 elemPoint.resize(numPointPerElt, nullptr);
5286 elemIdPoint.resize(numPointPerElt, 0);
5287
5288 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
5289 currentLabel = itRef->first;
5290 numEltPerLabel = itRef->second.second;
5291 if ( searchLabel == currentLabel) {
5292 // dofValue contains : values in dof by element.
5293 double dofValue[fe.numDof()*numComp];
5294 double dofValue2[fe.numDof()*numComp];
5295 // idGlobalDof contains: global number od dof by element.
5296 felInt idGlobalDof[fe.numDof()*numComp];
5297 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
5298 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
5299
5300 // loop over all the support elements
5301 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
5302 // get the id of the support
5303 ielSupportDof = vectorIdSupport[it];
5304
5305 fe.updateMeasNormal(0, elemPoint);
5306 cpt = 0;
5307 for(int iDof=0; iDof<fe.numDof(); iDof++) {
5308 for(int iComp = 0; iComp<numComp; iComp++) {
5309 m_dof.loc2glob(ielSupportDof,iDof,idVar,iComp,idDof);
5310 idGlobalDof[cpt] = idDof;
5311 cpt++;
5312 }
5313 }
5314
5315 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
5316 AOApplicationToPetsc(m_ao,fe.numDof()*numComp,idGlobalDof);
5317 //gets values of associate dofs.
5318 m_seqSol.getValues(fe.numDof()*numComp,idGlobalDof,dofValue);
5319 seqTestFunction.getValues(fe.numDof()*numComp,idGlobalDof,dofValue2);
5320
5321 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
5322 double c1 = 0.;
5323 for(int icomp=0; icomp<fe.numCoor(); icomp++) {
5324 /* u \cdot w */
5325 for (int idof = 0; idof < fe.numDof(); idof++) {
5326 c1 += fe.phi[ig](idof) * dofValue[idof*fe.numCoor()+icomp] + fe.phi[ig](idof) * dofValue2[idof*fe.numCoor()+icomp];
5327 }
5328 }
5329 for (int icomp=0; icomp<fe.numCoor(); icomp++) {
5330 /* u \cdot n */
5331 for (int idof = 0; idof < fe.numDof(); idof++) {
5332 tmpconvBD[iLabel] += c1 * fe.phi[ig](idof) * dofValue[idof*fe.numCoor()+icomp] * fe.normal[ig](icomp) * fe.weightMeas(ig);
5333 }
5334 }
5335 }
5336 }
5337 numElement[eltType]++;
5338 }
5339 } else
5340 numElement[eltType]+= numEltPerLabel;
5341 }
5342 }
5343 }
5344
5345 for (std::size_t i = 0; i < tmpconvBD.size(); i++) {
5346 //Symchronise value of processors (every processors get a part of the flux value).
5347 MPI_Allreduce(&tmpconvBD[i],&convBD[i], 1,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm());
5348 convBD[i] = convBD[i] * FelisceParam::instance(this->instanceIndex()).density;
5349 }
5350 }
5351
5352 /***********************************************************************************/
5353 /***********************************************************************************/
5354
5355 double LinearProblem::computeViscBoundary(int label, PetscVector& W) {
5356
5357 const int iUnknownVel = m_listUnknown.getUnknownIdList(velocity);
5358 const int idVarVel = m_listUnknown.idVariable(iUnknownVel);
5359 const int iMeshVel = m_listVariable[idVarVel].idMesh();
5360 const Variable& variableVel = m_listVariable[idVarVel];
5361
5362 const int numCompVel = variableVel.numComponent();
5363
5364 //idGlobalDof contains: global number of dof by element.
5365 felInt idGlobalDofVel;
5366 //dofValue contains : values in dof by element.
5367 double dofValueVel;
5368 double dofValueW;
5369
5370 //geometric element type in the mesh.
5371 ElementType eltType;
5372 //current region of mesh.
5373 int currentLabel = 0;
5374 //number of element for one label and one eltType.
5375 felInt numEltPerLabel = 0;
5376 //use to identify global id of dof.
5377 felInt idDof;
5378
5379 felInt numElement[GeometricMeshRegion::m_numTypesOfElement];
5380
5381 if(!m_meshLocal[iMeshVel]->statusFaces()) {
5382 m_meshLocal[iMeshVel]->buildFaces();
5383 }
5384
5385 UBlasMatrix valVel; // val(icomp,jdof)
5386 UBlasMatrix valW; // val(icomp,jdof)
5387
5388 /// initialize id global of elements.
5389 for (int ityp=0; ityp <GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
5390 numElement[static_cast<ElementType>(ityp)] = 0;
5391 }
5392
5393 /// initialize CurrentFiniteElementWithBd on Domain
5394 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[iMeshVel]->bagElementTypeDomain();
5395 for (std::size_t ielt = 0; ielt < bagElementTypeDomain.size(); ++ielt) {
5396 eltType = bagElementTypeDomain[ielt];
5397 defineCurrentFiniteElementWithBd(eltType); // TODO no sense here if bagElementTypeDomain.size() > 1
5398 }
5399
5400 CurrentFiniteElementWithBd* fewbdVelPtr = m_listCurrentFiniteElementWithBd[idVarVel];
5401 FEL_ASSERT(fewbdVelPtr);
5402 CurrentFiniteElementWithBd& fewbdVel = *fewbdVelPtr;
5403
5404 UBlasVector tmpVecDof(fewbdVel.numDof());
5405
5406 UBlasVector tmpVecComp(numCompVel);
5407
5408 UBlasMatrix tmpMatDof(numCompVel,numCompVel);
5409
5410 // contains the support elements ids of a mesh element
5411 std::vector<felInt> vectorIdSupport;
5412
5413 double viscBoundaryLocal = 0;
5414 double viscBoundary;
5415
5416 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[iMeshVel]->bagElementTypeDomainBoundary();
5417 for (std::size_t iet = 0; iet < bagElementTypeDomainBoundary.size(); ++iet) {
5418 eltType = bagElementTypeDomainBoundary[iet];
5419 int numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
5420 std::vector<Point*> elemPoint(numPointPerElt); //Points of the current boundary element.
5421 std::vector<felInt> elemIdPoint(numPointPerElt, 0); //Id of points of the boundary element.
5422
5423 for(auto itRef = m_meshLocal[iMeshVel]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMeshVel]->intRefToBegEndMaps[eltType].end(); itRef++) {
5424 currentLabel = itRef->first;
5425 numEltPerLabel = itRef->second.second;
5426
5427 if ( currentLabel == label ) {
5428 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
5429
5430 /* Compute derivative by looking at associated domain tetra */
5431 std::vector<Point*> elemPointVol;
5432 std::vector<felInt> elemIdPointVol;
5433
5434 int idLocFace = -1; // Local identity of the face of a domain element
5435 felInt idElemVol = -1; // ID of the domain element associated to the face with identity idLocFace
5436
5437 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
5438
5439 // retrieve volume info from the face (given by its point IDs)
5440 m_meshLocal[iMeshVel]->getElementFromBdElem(elemIdPoint, elemIdPointVol, elemPointVol, idLocFace, idElemVol);
5441
5442 CurvilinearFiniteElement& feVel = fewbdVel.bdEle(idLocFace);
5443
5444 fewbdVel.updateFirstDeriv(0, elemPointVol);
5445
5446 fewbdVel.computeCurrentQuadraturePointInternAndBd();
5447 fewbdVel.updateBdMeasNormal();
5448 feVel.updateMeasNormal(0, elemPoint);
5449
5450 valVel.resize(numCompVel,fewbdVel.numDof());
5451 valVel.clear();
5452
5453 valW.resize(numCompVel,fewbdVel.numDof());
5454 valW.clear();
5455
5456 // not initialised properly below.
5457 // loop over all the support elements
5458 for(int iComp = 0; iComp < numCompVel; iComp++) {
5459 for(int iDof = 0; iDof < fewbdVel.numDof(); iDof++) {
5460 m_dof.loc2glob(idElemVol,iDof,idVarVel,iComp,idDof);
5461 idGlobalDofVel = idDof;
5462 m_sol.getValues(1,&idGlobalDofVel,&dofValueVel);
5463 W.getValues(1,&idGlobalDofVel,&dofValueW);
5464 valVel(iComp,iDof) = dofValueVel;
5465 valW(iComp, iDof) = dofValueW;
5466 }
5467 }
5468
5469 ///Compute [Grad_u*n*v] The gradient is calculated over the tetraedra, where as the rest of the terms are calculated over the triangle
5470 tmpVecDof.clear();
5471 double tmpGrad;
5472 for(int icomp=0; icomp<numCompVel; icomp++) {
5473 FEL_ASSERT( feVel.hasNormal() and fewbdVel.hasFirstDeriv() );
5474 for(int ilocg=0; ilocg<fewbdVel.numQuadPointBdEle(idLocFace); ilocg++) {
5475 int ig = ilocg+fewbdVel.indexQuadPoint(idLocFace+1);
5476 // face idLocFace starts at idLocFace+1 (0 for internal quad points)
5477 /// Vector = [n \cdot \grad \phi]:
5478 tmpVecDof = prod(trans(feVel.normal[ilocg]), fewbdVel.dPhi[ig]);
5479 tmpGrad = 0.;
5480
5481
5482 for(int jdof=0; jdof<fewbdVel.numDof(); jdof++) {
5483 /// tmp = [n \cdot \grad f] = \sum f_jdof (grad phi_jdof \cdot n)
5484 tmpGrad+=tmpVecDof(jdof)*valVel(icomp,jdof);
5485 }
5486 tmpGrad *= feVel.weightMeas(ilocg);
5487 for(int idof=0; idof<feVel.numDof(); idof++) {
5488 /// df/dn *phi(idof):
5489 viscBoundaryLocal = tmpGrad * feVel.phi[ilocg](idof) * valW(icomp,idof);
5490 }
5491 }
5492 }
5493
5494 numElement[eltType]++;
5495 }
5496 } else {
5497 numElement[eltType]+= numEltPerLabel;
5498 }
5499 }
5500 }
5501 /* make the sum visible for all procesors */
5502 MPI_Allreduce(&viscBoundaryLocal, &viscBoundary, 1, MPI_DOUBLE, MPI_SUM, MpiInfo::petscComm());
5503 viscBoundary = viscBoundary * FelisceParam::instance(this->instanceIndex()).viscosity;
5504 return viscBoundary;
5505 }
5506
5507 /***********************************************************************************/
5508 /***********************************************************************************/
5509
5510 void LinearProblem::computePowerBDpu(PhysicalVariable unknown1, PhysicalVariable unknown2, int rankProc, const std::vector<int>& label, std::vector<double>& PowerBDpu)
5511 {
5512 IGNORE_UNUSED_RANK_PROC;
5513 gatherSolution();
5514 const int iUnknown1 = m_listUnknown.getUnknownIdList(unknown1);
5515 const int idVar1 = m_listUnknown.idVariable(iUnknown1);
5516 const int iMesh1 = m_listVariable[idVar1].idMesh();
5517 const int iUnknown2 = m_listUnknown.getUnknownIdList(unknown2);
5518 const int idVar2 = m_listUnknown.idVariable(iUnknown2);
5519 const int iMesh2 = m_listVariable[idVar2].idMesh();
5520 const Variable& variable1 = m_listVariable[idVar1];
5521 const Variable& variable2 = m_listVariable[idVar2];
5522
5523 if ( iMesh1 != iMesh2 )
5524 FEL_ERROR("Variables must be defined on same mesh");
5525
5526 const int numComp1 = variable1.numComponent();
5527 const int numComp2 = variable2.numComponent();
5528
5529 //geometric element type in the mesh.
5530 ElementType eltType;
5531 //number of points per geometric element.
5532 int numPointPerElt = 0;
5533 //current region of mesh.
5534 int currentLabel = 0;
5535 //number of element for one label and one eltType.
5536 felInt numEltPerLabel = 0;
5537 //Points of the current element.
5538 std::vector<Point*> elemPoint;
5539 //Id of points of the element.
5540 std::vector<felInt> elemIdPoint;
5541 // Ids of support elements for a mesh element
5542 std::vector <felInt> vectorIdSupport;
5543
5544 // use to identify global id of dof.
5545 felInt idDof;
5546 felInt cpt = 0;
5547 //Id link element to its supportDof.
5548 felInt ielSupportDof;
5549 PowerBDpu.clear();
5550 PowerBDpu.resize(label.size(),0.);
5551
5552 std::vector<double> tmpPowerBDpu(label.size());
5553
5554 int searchLabel=-1;
5555 felInt numElement[GeometricMeshRegion::m_numTypesOfElement];
5556
5557 for(std::size_t iLabel = 0; iLabel < label.size(); iLabel++) {
5558 searchLabel = label[iLabel];
5559 tmpPowerBDpu[iLabel] = 0.;
5560
5561 /// initialize id global of elements.
5562 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
5563 eltType = (ElementType)ityp;
5564 numElement[eltType] = 0;
5565 }
5566
5567 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[iMesh1]->bagElementTypeDomainBoundary();
5568 for (std::size_t i = 0; i < bagElementTypeDomainBoundary.size(); ++i) {
5569 eltType = bagElementTypeDomainBoundary[i];
5570 defineCurvilinearFiniteElement(eltType);
5571 initElementArrayBD();
5572 CurvilinearFiniteElement& fe1 = *m_listCurvilinearFiniteElement[idVar1];
5573 CurvilinearFiniteElement& fe2 = *m_listCurvilinearFiniteElement[idVar2];
5574 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
5575 elemPoint.resize(numPointPerElt, nullptr);
5576 elemIdPoint.resize(numPointPerElt, 0);
5577
5578 for(auto itRef = m_meshLocal[iMesh1]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh1]->intRefToBegEndMaps[eltType].end(); itRef++) {
5579 currentLabel = itRef->first;
5580 numEltPerLabel = itRef->second.second;
5581 if ( searchLabel == currentLabel) {
5582 // dofValue contains : values in dof by element.
5583 double dofValue1[fe1.numDof()*numComp1];
5584 double dofValue2[fe2.numDof()*numComp2];
5585
5586 // idGlobalDof contains: global number of DoF by element.
5587 felInt idGlobalDof1[fe1.numDof()*numComp1];
5588 felInt idGlobalDof2[fe2.numDof()*numComp2];
5589
5590 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
5591 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
5592 // loop over all the support elements
5593 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
5594 // get the id of the support
5595 ielSupportDof = vectorIdSupport[it];
5596
5597 fe1.updateMeasNormal(0, elemPoint);
5598 fe2.updateMeasNormal(0, elemPoint);
5599 int cpt1 = 0;
5600 for(int iDof=0; iDof<fe1.numDof(); iDof++) {
5601 for(int iComp = 0; iComp<numComp1; iComp++) {
5602 m_dof.loc2glob(ielSupportDof,iDof,idVar1,iComp,idDof);
5603 idGlobalDof1[cpt1] = idDof;
5604 cpt1++;
5605 }
5606 }
5607 int cpt2 = 0;
5608 for(int iDof=0; iDof<fe2.numDof(); iDof++) {
5609 for(int iComp = 0; iComp<numComp2; iComp++) {
5610 m_dof.loc2glob(ielSupportDof,iDof,idVar2,iComp,idDof);
5611 idGlobalDof2[cpt2] = idDof;
5612 cpt2++;
5613 }
5614 }
5615
5616 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
5617 AOApplicationToPetsc(m_ao,fe1.numDof()*numComp1,idGlobalDof1);
5618 AOApplicationToPetsc(m_ao,fe2.numDof()*numComp2,idGlobalDof2);
5619 //gets values of associate dofs.
5620 m_seqSol.getValues(fe1.numDof()*numComp1,idGlobalDof1,dofValue1);
5621 m_seqSol.getValues(fe2.numDof()*numComp2,idGlobalDof2,dofValue2);
5622
5623 for(int ig=0; ig<fe2.numQuadraturePoint(); ig++) {
5624 double p1 = 0.;
5625 for(int idof=0; idof<fe1.numDof(); idof++) {
5626 p1 += fe1.phi[ig](idof) * dofValue1[idof];
5627 }
5628 double u1 = 0.;
5629 cpt = 0;
5630 for (int idof = 0; idof<fe2.numDof(); idof++) {
5631 for (int icomp = 0; icomp<numComp2; icomp++) {
5632 u1 += fe2.phi[ig](idof) * dofValue2[cpt] * fe2.normal[ig](icomp);
5633 cpt++;
5634 }
5635 }
5636 tmpPowerBDpu[iLabel] += p1 * u1 * fe2.weightMeas(ig);
5637 }
5638 }
5639 numElement[eltType]++;
5640 }
5641 } else
5642 numElement[eltType]+= numEltPerLabel;
5643 }
5644 }
5645 }
5646
5647 for (std::size_t i = 0; i < tmpPowerBDpu.size(); i++) {
5648 //Symchronise value of processors (every processors get a part of the flux value).
5649 MPI_Allreduce(&tmpPowerBDpu[i],&PowerBDpu[i], 1,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm());
5650 }
5651 }
5652
5653 /***********************************************************************************/
5654 /***********************************************************************************/
5655
5656 void LinearProblem::computeProdUn_Un_1(PhysicalVariable unknown, int rankProc, Bdf& bdf, double& prodUn_Un_1)
5657 {
5658 IGNORE_UNUSED_RANK_PROC;
5659 gatherSolution();
5660 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
5661 const int idVar = m_listUnknown.idVariable(iUnknown);
5662 const int iMesh = m_listVariable[idVar].idMesh();
5663 const Variable& variable = m_listVariable[idVar];
5664 // todo generalize for every multiple type of element in mesh.
5665 CurrentFiniteElement* fePtr = m_listCurrentFiniteElement[idVar];
5666 FEL_ASSERT(fePtr);
5667 CurrentFiniteElement& fe = *fePtr;
5668
5669 const int numComp = variable.numComponent();
5670 // dofValue contains : values in dof by element.
5671 double dofValue1[fe.numDof()*numComp];
5672 double dofValue2[fe.numDof()*numComp];
5673 // idGlobalDof contains: global number od dof by element.
5674 felInt idGlobalDof[fe.numDof()*numComp];
5675
5676 //geometric element type in the mesh.
5677 ElementType eltType;
5678 //number of points per geometric element.
5679 int numPointPerElt = 0;
5680
5681 //current region of mesh.
5682
5683 //number of element for one label and one eltType.
5684 felInt numEltPerLabel = 0;
5685 //Points of the current element.
5686 std::vector<Point*> elemPoint;
5687 //Id of points of the element.
5688 std::vector<felInt> elemIdPoint;
5689 // Ids of support elements for a mesh element
5690 std::vector <felInt> vectorIdSupport;
5691
5692 // use to identify global id of dof.
5693 felInt idDof;
5694 felInt cpt = 0;
5695 //Id link element to its supportDof.
5696 felInt ielSupportDof;
5697 prodUn_Un_1 = 0.;
5698 //double elementValue = 0.;
5699
5700 double tmpprodUn_Un_1 = 0.;
5701
5702 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
5703
5704 /// initialize id global of elements.
5705 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
5706 eltType = (ElementType)ityp;
5707 numElement[eltType] = 0;
5708 }
5709
5710 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[iMesh]->bagElementTypeDomain();
5711 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
5712 eltType = bagElementTypeDomain[i];
5713 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
5714 elemPoint.resize(numPointPerElt, nullptr);
5715 elemIdPoint.resize(numPointPerElt, 0);
5716
5717 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
5718 numEltPerLabel = itRef->second.second;
5719 for (felInt iel = 0; iel < numEltPerLabel; iel++) {
5720 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
5721
5722 // loop over all the support elements
5723 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
5724 // get the id of the support
5725 ielSupportDof = vectorIdSupport[it];
5726
5727 cpt = 0;
5728 for(int iDof=0; iDof<fe.numDof(); iDof++) {
5729 for(int iComp = 0; iComp<numComp; iComp++) {
5730 m_dof.loc2glob(ielSupportDof,iDof,idVar,iComp,idDof);
5731 idGlobalDof[cpt] = idDof;
5732 cpt++;
5733 }
5734 }
5735
5736 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
5737 AOApplicationToPetsc(m_ao,fe.numDof()*numComp,idGlobalDof);
5738 //gets values of associate dofs.
5739 bdf.sol_n().getValues(fe.numDof()*numComp,idGlobalDof,dofValue1);
5740 bdf.sol_n_1().getValues(fe.numDof()*numComp,idGlobalDof,dofValue2);
5741
5742 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
5743 double c1 = 0.;
5744 for(int iComp = 0; iComp<numComp; iComp++) {
5745 double a1 = 0.;
5746 double b1 = 0.;
5747 for(int idof = 0; idof<fe.numDof(); idof++) {
5748 a1 += dofValue1[idof*numComp+iComp] * fe.phi[ig](idof);
5749 b1 += dofValue2[idof*numComp+iComp] * fe.phi[ig](idof);
5750 }
5751 c1 += a1 * b1;
5752 }
5753 tmpprodUn_Un_1 += c1 * fe.weightMeas(ig);
5754 }
5755 }
5756 numElement[eltType]++;
5757 }
5758 }
5759 }
5760
5761 MPI_Allreduce(&tmpprodUn_Un_1,&prodUn_Un_1, 1,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm());
5762 }
5763
5764 /***********************************************************************************/
5765 /***********************************************************************************/
5766
5767 void LinearProblem::computeDiffSquaredUn_Un_1(PhysicalVariable unknown, int rankProc, Bdf& bdf, double& diffSquareUn_Un_1)
5768 {
5769 IGNORE_UNUSED_RANK_PROC;
5770 gatherSolution();
5771 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
5772 const int idVar = m_listUnknown.idVariable(iUnknown);
5773 const int iMesh = m_listVariable[idVar].idMesh();
5774 const Variable& variable = m_listVariable[idVar];
5775 // todo generalize for every multiple type of element in mesh.
5776 CurrentFiniteElement* fePtr = m_listCurrentFiniteElement[idVar];
5777 FEL_ASSERT(fePtr);
5778 CurrentFiniteElement& fe = *fePtr;
5779
5780 const int numComp = variable.numComponent();
5781 // dofValue contains : values in dof by element.
5782 double dofValue1[fe.numDof()*numComp];
5783 double dofValue2[fe.numDof()*numComp];
5784 // idGlobalDof contains: global number od dof by element.
5785 felInt idGlobalDof[fe.numDof()*numComp];
5786
5787 //geometric element type in the mesh.
5788 ElementType eltType;
5789 //number of points per geometric element.
5790 int numPointPerElt = 0;
5791
5792 //number of element for one label and one eltType.
5793 felInt numEltPerLabel = 0;
5794 //Points of the current element.
5795 std::vector<Point*> elemPoint;
5796 //Id of points of the element.
5797 std::vector<felInt> elemIdPoint;
5798 // Ids of support elements for a mesh element
5799 std::vector <felInt> vectorIdSupport;
5800
5801 // use to identify global id of dof.
5802 felInt idDof;
5803 felInt cpt = 0;
5804 //Id link element to its supportDof.
5805 felInt ielSupportDof;
5806 diffSquareUn_Un_1 = 0.;
5807 //double elementValue = 0.;
5808
5809 double tmpdiffSquareUn_Un_1 = 0.;
5810
5811 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
5812
5813 /// initialize id global of elements.
5814 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
5815 eltType = (ElementType)ityp;
5816 numElement[eltType] = 0;
5817 }
5818
5819 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[iMesh]->bagElementTypeDomain();
5820 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
5821 eltType = bagElementTypeDomain[i];
5822 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
5823 elemPoint.resize(numPointPerElt, nullptr);
5824 elemIdPoint.resize(numPointPerElt, 0);
5825
5826 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
5827 numEltPerLabel = itRef->second.second;
5828 for (felInt iel = 0; iel < numEltPerLabel; iel++) {
5829 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
5830
5831 // loop over all the support elements
5832 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
5833 // get the id of the support
5834 ielSupportDof = vectorIdSupport[it];
5835
5836 cpt = 0;
5837 for(int iDof=0; iDof<fe.numDof(); iDof++) {
5838 for(int iComp = 0; iComp<numComp; iComp++) {
5839 m_dof.loc2glob(ielSupportDof,iDof,idVar,iComp,idDof);
5840 idGlobalDof[cpt] = idDof;
5841 cpt++;
5842 }
5843 }
5844
5845 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
5846 AOApplicationToPetsc(m_ao,fe.numDof()*numComp,idGlobalDof);
5847 //gets values of associate dofs.
5848 bdf.sol_n().getValues(fe.numDof()*numComp,idGlobalDof,dofValue1);
5849 bdf.sol_n_1().getValues(fe.numDof()*numComp,idGlobalDof,dofValue2);
5850
5851 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
5852 double c1 = 0.;
5853 for(int iComp = 0; iComp<numComp; iComp++) {
5854 double a1 = 0.;
5855 double b1 = 0.;
5856 for(int idof = 0; idof<fe.numDof(); idof++) {
5857 a1 += dofValue1[idof*numComp+iComp] * fe.phi[ig](idof);
5858 b1 += dofValue2[idof*numComp+iComp] * fe.phi[ig](idof);
5859 }
5860 c1 += (a1 - b1)*(a1 - b1);
5861 }
5862 tmpdiffSquareUn_Un_1 += c1 * fe.weightMeas(ig);
5863 }
5864 }
5865 numElement[eltType]++;
5866 }
5867 }
5868 }
5869
5870 MPI_Allreduce(&tmpdiffSquareUn_Un_1,&diffSquareUn_Un_1, 1,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm());
5871 }
5872
5873 /***********************************************************************************/
5874 /***********************************************************************************/
5875
5876 void LinearProblem::computeTemamTerm(PhysicalVariable unknown, int rankProc, Bdf& bdf, double& temamTerm)
5877 {
5878 IGNORE_UNUSED_RANK_PROC;
5879 gatherSolution();
5880 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
5881 const int idVar = m_listUnknown.idVariable(iUnknown);
5882 const int iMesh = m_listVariable[idVar].idMesh();
5883 const Variable& variable = m_listVariable[idVar];
5884 // todo generalize for every multiple type of element in mesh.
5885 CurrentFiniteElement* fePtr = m_listCurrentFiniteElement[idVar];
5886 FEL_ASSERT(fePtr);
5887 CurrentFiniteElement& fe = *fePtr;
5888
5889 const int numComp = variable.numComponent();
5890 // dofValue contains : values in dof by element.
5891 double dofValue1[fe.numDof()*numComp];
5892 double dofValue2[fe.numDof()*numComp];
5893 // idGlobalDof contains: global number od dof by element.
5894 felInt idGlobalDof[fe.numDof()*numComp];
5895
5896 //geometric element type in the mesh.
5897 ElementType eltType;
5898 //number of points per geometric element.
5899 int numPointPerElt = 0;
5900
5901 //number of element for one label and one eltType.
5902 felInt numEltPerLabel = 0;
5903 //Points of the current element.
5904 std::vector<Point*> elemPoint;
5905 //Id of points of the element.
5906 std::vector<felInt> elemIdPoint;
5907 // Ids of support elements for a mesh element
5908 std::vector <felInt> vectorIdSupport;
5909
5910 // use to identify global id of dof.
5911 felInt idDof;
5912 felInt cpt = 0;
5913 //Id link element to its supportDof.
5914 felInt ielSupportDof;
5915 temamTerm = 0.;
5916 //double elementValue = 0.;
5917
5918 double tmptemamTerm = 0.;
5919
5920 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
5921
5922 /// initialize id global of elements.
5923 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
5924 eltType = (ElementType)ityp;
5925 numElement[eltType] = 0;
5926 }
5927
5928 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[iMesh]->bagElementTypeDomain();
5929 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
5930 eltType = bagElementTypeDomain[i];
5931 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
5932 elemPoint.resize(numPointPerElt, nullptr);
5933 elemIdPoint.resize(numPointPerElt, 0);
5934
5935 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
5936 numEltPerLabel = itRef->second.second;
5937 for (felInt iel = 0; iel < numEltPerLabel; iel++) {
5938 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
5939
5940 // loop over all the support elements
5941 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
5942 // get the id of the support
5943 ielSupportDof = vectorIdSupport[it];
5944
5945 cpt = 0;
5946 for(int iDof=0; iDof<fe.numDof(); iDof++) {
5947 for(int iComp = 0; iComp<numComp; iComp++) {
5948 m_dof.loc2glob(ielSupportDof,iDof,idVar,iComp,idDof);
5949 idGlobalDof[cpt] = idDof;
5950 cpt++;
5951 }
5952 }
5953
5954 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
5955 AOApplicationToPetsc(m_ao,fe.numDof()*numComp,idGlobalDof);
5956 //gets values of associate dofs.
5957 bdf.sol_n().getValues(fe.numDof()*numComp,idGlobalDof,dofValue1);
5958 bdf.sol_n_1().getValues(fe.numDof()*numComp,idGlobalDof,dofValue2);
5959
5960 for (int ig=0; ig<fe.numQuadraturePoint(); ig++) {
5961 // div(u(n-1))
5962 double b1 = 0.;
5963 for (int icomp=0; icomp<numComp; icomp++) {
5964 double a1 = 0.;
5965 for (int idof=0; idof<fe.numDof(); idof++) {
5966 a1 += fe.dPhi[ig](icomp,idof) * dofValue2[idof*fe.numCoor()+icomp];
5967 }
5968 b1 += a1;
5969 }
5970 // u(n) v
5971 double c1 = 0.;
5972 for (int icomp=0; icomp<numComp; icomp++) {
5973 double a1 = 0.;
5974 for (int idof=0; idof<fe.numDof(); idof++) {
5975 a1 += fe.phi[ig](idof) * dofValue1[idof*fe.numCoor()+icomp];
5976 }
5977 c1 += a1;
5978 }
5979 // \int_\Omega div(u(n-1)) \dot u(n) v
5980 tmptemamTerm += b1 * c1 * fe.weightMeas(ig) ;
5981 }
5982 }
5983 numElement[eltType]++;
5984 }
5985 }
5986 }
5987
5988 MPI_Allreduce(&tmptemamTerm,&temamTerm, 1,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm());
5989 }
5990
5991 /***********************************************************************************/
5992 /***********************************************************************************/
5993
5994 void LinearProblem::computeBoundaryStress(int coef, int label, std::vector<double>& stress)
5995 {
5996 const int iUnknownPres = m_listUnknown.getUnknownIdList(pressure);
5997 const int idVarPres = m_listUnknown.idVariable(iUnknownPres);
5998 const int iMeshPres = m_listVariable[idVarPres].idMesh();
5999 const int iUnknownVel = m_listUnknown.getUnknownIdList(velocity);
6000 const int idVarVel = m_listUnknown.idVariable(iUnknownVel);
6001 const int iMeshVel = m_listVariable[idVarVel].idMesh();
6002 const Variable& variablePres = m_listVariable[idVarPres];
6003 const Variable& variableVel = m_listVariable[idVarVel];
6004
6005 const int numCompPres = variablePres.numComponent();
6006 const int numCompVel = variableVel.numComponent();
6007
6008 if ( iMeshPres != iMeshVel )
6009 FEL_ERROR("Variables must be defined on same mesh");
6010
6011 //idGlobalDof contains: global number of dof by element.
6012 felInt idGlobalDofPres;
6013 felInt idGlobalDofVel;
6014 //dofValue contains : values in dof by element.
6015 double dofValuePres;
6016 double dofValueVel;
6017
6018 //geometric element type in the mesh.
6019 ElementType eltType;
6020 //current region of mesh.
6021 int currentLabel = 0;
6022 //number of element for one label and one eltType.
6023 felInt numEltPerLabel = 0;
6024 //use to identify global id of dof.
6025 felInt idDof;
6026
6027 stress.assign(m_numDof,0.);
6028 const double visc = FelisceParam::instance(this->instanceIndex()).viscosity;
6029 felInt numElement[GeometricMeshRegion::m_numTypesOfElement];
6030
6031 if(m_meshLocal[iMeshVel]->statusFaces() == false) {
6032 m_meshLocal[iMeshVel]->buildFaces();
6033 }
6034
6035 UBlasMatrix valPres; // val(icomp,jdof)
6036 UBlasMatrix valVel; // val(icomp,jdof)
6037
6038 /// initialize id global of elements.
6039 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
6040 numElement[static_cast<ElementType>(ityp)] = 0;
6041 }
6042
6043 /// initialize CurrentFiniteElementWithBd on Domain
6044 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[iMeshVel]->bagElementTypeDomain();
6045 for (std::size_t ielt = 0; ielt < bagElementTypeDomain.size(); ++ielt) {
6046 eltType = bagElementTypeDomain[ielt];
6047 defineCurrentFiniteElementWithBd(eltType); // TODO no sense here if bagElementTypeDomain.size() > 1
6048 }
6049
6050 CurrentFiniteElementWithBd* fewbdPresPtr = m_listCurrentFiniteElementWithBd[idVarPres];
6051 FEL_ASSERT(fewbdPresPtr);
6052 CurrentFiniteElementWithBd& fewbdPres = *fewbdPresPtr;
6053
6054 CurrentFiniteElementWithBd* fewbdVelPtr = m_listCurrentFiniteElementWithBd[idVarVel];
6055 FEL_ASSERT(fewbdVelPtr);
6056 CurrentFiniteElementWithBd& fewbdVel = *fewbdVelPtr;
6057
6058 UBlasVector tmpVecDof(fewbdVel.numDof());
6059 UBlasVector tmpVecComp(numCompVel);
6060 UBlasMatrix tmpMatDof(numCompVel,numCompVel);
6061
6062 // contains the support elements ids of a mesh element
6063 std::vector<felInt> vectorIdSupport;
6064
6065 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[iMeshVel]->bagElementTypeDomainBoundary();
6066 for (std::size_t iet = 0; iet < bagElementTypeDomainBoundary.size(); ++iet) {
6067 eltType = bagElementTypeDomainBoundary[iet];
6068 int numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
6069 std::vector<Point*> elemPoint(numPointPerElt); //Points of the current boundary element.
6070 std::vector<felInt> elemIdPoint(numPointPerElt, 0); //Id of points of the boundary element.
6071
6072 for(auto itRef = m_meshLocal[iMeshVel]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMeshVel]->intRefToBegEndMaps[eltType].end(); itRef++) {
6073 currentLabel = itRef->first;
6074 numEltPerLabel = itRef->second.second;
6075
6076 if ( currentLabel == label ) {
6077 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
6078
6079 std::vector<Point*> elemPointVol; // Points of the current domain element.
6080 std::vector<felInt> elemIdPointVol; // Id of points of the domain element.
6081 int idLocFace = -1; // Local identity of the face of a domain element
6082 felInt idElemVol = -1; // ID of the domain element associated to the face with identity idLocFace
6083
6084 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
6085
6086 // retrieve volume info from the face (given by its point IDs)
6087 m_meshLocal[iMeshVel]->getElementFromBdElem(elemIdPoint, elemIdPointVol, elemPointVol, idLocFace, idElemVol);
6088
6089 CurvilinearFiniteElement& fePres = fewbdPres.bdEle(idLocFace);
6090 CurvilinearFiniteElement& feVel = fewbdVel.bdEle(idLocFace);
6091 felInt idDofVel[feVel.numDof()*numCompVel];
6092
6093 fewbdVel.updateFirstDeriv(0, elemPointVol);
6094
6095 fewbdVel.computeCurrentQuadraturePointInternAndBd();
6096 fewbdVel.updateBdMeasNormal();
6097 fePres.updateMeasNormal(0, elemPoint);
6098 feVel.updateMeasNormal(0, elemPoint);
6099
6100 FEL_CHECK(fePres.numQuadraturePoint() == feVel.numQuadraturePoint(), "LinearProblem::computeBoundaryStress: The quadrature rules must be the same for the two elements");
6101
6102 valPres.resize(numCompPres,fePres.numDof());
6103 valVel.resize(numCompVel,fewbdVel.numDof());
6104 valPres.clear();
6105 valVel.clear();
6106
6107 std::vector<double> vecPress(feVel.numDof()*numCompVel,0);
6108 std::vector<double> vecVel(feVel.numDof()*numCompVel,0);
6109 std::vector<double> tmpStress(feVel.numDof()*numCompVel,0.);
6110
6111 felInt ielSupportDof = -1; //Id link element to its supportDof; dumb value to avoid undefined behaviour if
6112 // not initialised properly below.
6113 // loop over all the support elements
6114 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
6115 // get the id of the support
6116 ielSupportDof = vectorIdSupport[it];
6117 for(int iComp = 0; iComp<numCompPres; iComp++) {
6118 for(int iDof=0; iDof<fePres.numDof(); iDof++) {
6119 m_dof.loc2glob(ielSupportDof,iDof,idVarPres,iComp,idDof);
6120 idGlobalDofPres = idDof; //and the petsc ordering?
6121 m_sol.getValues(1,&idGlobalDofPres,&dofValuePres);
6122 valPres(iComp,iDof) = dofValuePres;
6123 }
6124 }
6125 }
6126
6127 for(int iComp = 0; iComp < numCompVel; iComp++) {
6128 for(int iDof = 0; iDof < fewbdVel.numDof(); iDof++) {
6129 m_dof.loc2glob(idElemVol,iDof,idVarVel,iComp,idDof);
6130 idGlobalDofVel = idDof;
6131 m_sol.getValues(1,&idGlobalDofVel,&dofValueVel);
6132 valVel(iComp,iDof) = dofValueVel;
6133 }
6134 }
6135
6136 int cpt3 = 0;
6137 for(int iComp = 0; iComp<numCompVel; iComp++) {
6138 for(int iDof=0; iDof<feVel.numDof(); iDof++) {
6139 FEL_ASSERT(ielSupportDof != -1);
6140 m_dof.loc2glob(ielSupportDof,iDof,idVarVel,iComp,idDof);
6141 idDofVel[cpt3] = idDof;
6142 cpt3++;
6143 }
6144 }
6145
6146 ///Compute int_{Sigma} p*n*v
6147 double tmpPress = 0.;
6148 for(int icomp=0; icomp<feVel.numCoor(); icomp++) {
6149 for(int ig=0; ig<feVel.numQuadraturePoint(); ig++) {
6150 tmpPress = 0.;
6151 for(int jdof=0; jdof<fePres.numDof(); jdof++) {
6152 /// tmp = \sum_jdof ( f_jdof * phi_jdof )
6153 tmpPress += fePres.phi[ig](jdof) * valPres(0,jdof);
6154 }
6155 for(int idof=0; idof<feVel.numDof(); idof++) {
6156 ///summ_idof (f_idof *phim_idof \cdot n)
6157 vecPress[feVel.numDof()*icomp+idof]+= coef * tmpPress *feVel.normal[ig](icomp)*feVel.phi[ig](idof)* feVel.weightMeas(ig);
6158 }
6159 }
6160 }
6161
6162 ///Compute int_{Sigma} [Grad_u*n*v]
6163 tmpVecDof.clear();
6164 double tmpGrad;
6165 for(int icomp=0; icomp<numCompVel; icomp++) {
6166 FEL_ASSERT( feVel.hasNormal() and fewbdVel.hasFirstDeriv() );
6167 for(int ilocg=0; ilocg<fewbdVel.numQuadPointBdEle(idLocFace); ilocg++) {
6168 int ig = ilocg+fewbdVel.indexQuadPoint(idLocFace+1);
6169 // face idLocFace starts at idLocFace+1 (0 for internal quad points)
6170 /// Vector = [n \cdot \grad \phi]:
6171 tmpVecDof = prod(trans(feVel.normal[ilocg]), fewbdVel.dPhi[ig]);
6172 tmpGrad = 0.;
6173
6174 /* if(FelisceParam::instance(this->instanceIndex()).useSymmetricStress){ //to be tested
6175 /// tmpMatDof_ji = Sum_jdof( u_j * grad_i phi_jdof )
6176 tmpMatDof = prod(fewbdVel.dPhi[ig], trans(valVel));
6177 /// tmpVecComp =
6178 tmpVecComp = prod(tmpMatDof, feVel.normal[ilocg]);
6179 /// Vector = [n \cdot \grad \phi]:
6180 tmpGrad = 0.;
6181 tmpGrad = tmpVecComp(icomp);
6182 }
6183 else{
6184 tmpGrad = 0.;
6185 }*/
6186
6187
6188 for(int jdof=0; jdof<fewbdVel.numDof(); jdof++) {
6189 /// tmp = [n \cdot \grad f] = \sum f_jdof (grad phi_jdof \cdot n)
6190 tmpGrad+=tmpVecDof(jdof)*valVel(icomp,jdof);
6191 }
6192 tmpGrad *= coef*visc* feVel.weightMeas(ilocg);
6193 for(int idof=0; idof<feVel.numDof(); idof++) {
6194 /// df/dn *phi(idof):
6195 vecVel[feVel.numDof()*icomp+idof]+= tmpGrad * feVel.phi[ilocg](idof);
6196 }
6197 }
6198 }
6199
6200 for(int jstr=0; jstr<feVel.numDof()*feVel.numCoor(); jstr++) {
6201 tmpStress[jstr] = vecVel[jstr]-vecPress[jstr];
6202 }
6203 numElement[eltType]++;
6204
6205 //assembling local stress std::vector in global stress std::vector
6206 for(int istr = 0; istr < feVel.numDof()*numCompVel; istr++) {
6207 stress[idDofVel[istr]]+=tmpStress[istr];
6208 }
6209 }
6210 } else
6211 numElement[eltType]+= numEltPerLabel;
6212 }
6213 }
6214 }
6215
6216 /***********************************************************************************/
6217 /***********************************************************************************/
6218
6219 void LinearProblem::computeDomainIntegralOfDivergence(PhysicalVariable unknown, const std::vector<int>& label, std::vector<double>& integralOfDivergence)
6220 {
6221 gatherSolution();
6222 const int iUnknown = m_listUnknown.getUnknownIdList(unknown);
6223 const int idVar = m_listUnknown.idVariable(iUnknown);
6224 const int iMesh = m_listVariable[idVar].idMesh();
6225 const Variable& variable = m_listVariable[idVar];
6226 const int numComp = variable.numComponent();
6227 // dofValue contains : values in dof by element.
6228 std::vector<double> dofValue;
6229 // idGlobalDof contains: global number od dof by element.
6230 std::vector<felInt> idGlobalDof;
6231
6232 //geometric element type in the mesh.
6233 ElementType eltType;
6234 //number of points per geometric element.
6235 int numPointPerElt = 0;
6236 int currentLabel = 0;
6237 //number of element for one label and one eltType.
6238 felInt numEltPerLabel = 0;
6239 //Points of the current element.
6240 std::vector<Point*> elemPoint;
6241 //Id of points of the element.
6242 std::vector<felInt> elemIdPoint;
6243 //Ids of support elements of a mesh element
6244 std::vector<felInt> vectorIdSupport;
6245
6246 // use to identify global id of dof.
6247 felInt idDof;
6248 felInt cpt = 0;
6249 //Id link element to its supportDof.
6250 felInt ielSupportDof;
6251 integralOfDivergence.clear();
6252 integralOfDivergence.resize(label.size(),0.);
6253
6254 std::vector<double> tmpQuantity(label.size(),0.);
6255
6256 int searchLabel=-1;
6257 felInt numElement[GeometricMeshRegion::m_numTypesOfElement];
6258 for(std::size_t iLabel = 0; iLabel < label.size(); iLabel++) {
6259 searchLabel = label[iLabel];
6260 /// initialize id global of elements.
6261 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
6262 numElement[static_cast<ElementType>(ityp)] = 0;
6263 }
6264 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[iMesh]->bagElementTypeDomain();
6265 for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) {
6266 eltType = bagElementTypeDomain[i];
6267
6268 defineFiniteElement(eltType);
6269
6270 //Element matrix and vector initialisation
6271 initElementArray();
6272
6273 CurrentFiniteElement* fePtr = m_listCurrentFiniteElement[idVar];
6274 FEL_ASSERT(fePtr);
6275 CurrentFiniteElement& fe = *fePtr;
6276
6277 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
6278
6279 elemPoint.resize(numPointPerElt, nullptr);
6280 elemIdPoint.resize(numPointPerElt, 0);
6281
6282 for(auto itRef = m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[iMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
6283 currentLabel = itRef->first;
6284 numEltPerLabel = itRef->second.second;
6285 if ( searchLabel == currentLabel) {
6286 dofValue.resize(fe.numDof()*numComp);
6287 idGlobalDof.resize(fe.numDof()*numComp);
6288 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
6289 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
6290
6291 // loop over all the support elements
6292 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
6293 // get the id of the support
6294 ielSupportDof = vectorIdSupport[it];
6295
6296 fe.updateFirstDeriv(0, elemPoint);
6297 cpt = 0;
6298 for(int iDof=0; iDof<fe.numDof(); iDof++) {
6299 for(int iComp = 0; iComp<numComp; iComp++) {
6300 m_dof.loc2glob(ielSupportDof,iDof,iUnknown,iComp,idDof);
6301 idGlobalDof[cpt] = idDof;
6302 cpt++;
6303 }
6304 }
6305
6306 //mapping to obtain new global numbering. (I/O array: idGlobalDof).
6307 AOApplicationToPetsc(m_ao,fe.numDof()*numComp,idGlobalDof.data());
6308 //gets values of associate dofs.
6309 m_seqSol.getValues(fe.numDof()*numComp,idGlobalDof.data(),dofValue.data());
6310
6311 for(int ig=0; ig<fe.numQuadraturePoint(); ig++) {
6312 cpt = 0;
6313 for(int idof=0; idof<fe.numDof(); idof++) {
6314 for (int iComp=0; iComp<numComp; iComp++) {
6315 tmpQuantity[iLabel] += fe.dPhi[ig](iComp,idof) * dofValue[cpt] * fe.weightMeas(ig);
6316 cpt++;
6317 }
6318 }
6319 }
6320 }
6321 numElement[eltType]++;
6322 }
6323 } else {
6324 numElement[eltType]+= numEltPerLabel;
6325 }
6326 }
6327 }
6328 }
6329 for (std::size_t iq = 0; iq < label.size(); iq++) {
6330 //Synchronise value of processors (every processors get a part of the meanQuantity and measure value).
6331 MPI_Allreduce(&tmpQuantity[iq], &integralOfDivergence[iq], 1, MPI_DOUBLE, MPI_SUM, MpiInfo::petscComm());
6332 }
6333 }
6334
6335 /***********************************************************************************/
6336 /***********************************************************************************/
6337
6338 136880 void LinearProblem::m_duplicateSupportDofAssemblyLoop(int rank, ElementType& eltType, felInt ielGeo, std::vector<Point*>& elemPoint, std::vector<felInt>& elemIdPoint, FlagMatrixRHS flagMatrixRHS) // TODO D.C.
6339 {
6340 IGNORE_UNUSED_RANK;
6341 felInt ielSupportDof1, ielSupportDof2;
6342
6343 // for one element, list of all the associated support elements.
6344 // it assumes that the number of support elements for a given element is
6345 // the same for all unknown. If it is not the case, one need to implement
6346 // an assembling of the matrix by block ?
6347 136880 std::vector<felInt> vectorIdSupport;
6348
6349 // get the global id of the element
6350 felInt ielGeoGlobal;
6351
1/2
✓ Branch 2 taken 136880 times.
✗ Branch 3 not taken.
136880 ISLocalToGlobalMappingApply(m_mappingElem[m_currentMesh], 1, &ielGeo, &ielGeoGlobal);
6352
6353 // return each id of point of the element and coordinate in two arrays: elemPoint and elemIdPoint.
6354
1/2
✓ Branch 1 taken 136880 times.
✗ Branch 2 not taken.
136880 setElemPoint(eltType, ielGeo, elemPoint, elemIdPoint, vectorIdSupport);
6355
6356 // Fourth loop over all the support elements
6357
2/2
✓ Branch 1 taken 138296 times.
✓ Branch 2 taken 136880 times.
275176 for (std::size_t it1 = 0; it1 < vectorIdSupport.size(); it1++) {
6358 // get the id of the support
6359 138296 ielSupportDof1 = vectorIdSupport[it1];
6360
6361
2/2
✓ Branch 1 taken 141128 times.
✓ Branch 2 taken 138296 times.
279424 for(std::size_t it2 = 0; it2 < vectorIdSupport.size(); it2++) {
6362 // get the id of the support
6363 141128 ielSupportDof2 = vectorIdSupport[it2];
6364
6365 // clear elementary matrices
6366
2/2
✓ Branch 1 taken 141128 times.
✓ Branch 2 taken 141128 times.
282256 for (std::size_t j = 0, size = m_matrices.size(); j < size ; j++)
6367
1/2
✓ Branch 3 taken 141128 times.
✗ Branch 4 not taken.
141128 m_elementMat[j]->zero();
6368
6369 // clear elementary std::vector.
6370
2/2
✓ Branch 1 taken 141128 times.
✓ Branch 2 taken 141128 times.
282256 for (std::size_t j = 0, size = m_vectors.size(); j < size ; j++)
6371
1/2
✓ Branch 3 taken 141128 times.
✗ Branch 4 not taken.
141128 m_elementVector[j]->zero();
6372
6373
1/2
✓ Branch 1 taken 141128 times.
✗ Branch 2 not taken.
141128 computeElementArray(elemPoint, elemIdPoint, ielSupportDof1, ielSupportDof2, eltType, ielGeoGlobal, flagMatrixRHS);
6374
6375 // compute specific term of users. No need for ielSupportDof2 here yet
6376
1/2
✓ Branch 1 taken 141128 times.
✗ Branch 2 not taken.
141128 userElementCompute(elemPoint, elemIdPoint, ielSupportDof1, ielSupportDof2, eltType, ielGeoGlobal, flagMatrixRHS);
6377
6378 // add values of elemMat in the global matrix: m_matrices[0].
6379
1/2
✓ Branch 1 taken 141128 times.
✗ Branch 2 not taken.
141128 setValueMatrixRHS(ielSupportDof1, ielSupportDof2, flagMatrixRHS);
6380 }
6381 }
6382 136880 }
6383
6384 /***********************************************************************************/
6385 /***********************************************************************************/
6386
6387 void LinearProblem::m_duplicateSupportDofAssemblyLoopBoundaryCondition(int rank, ElementType& eltType, felInt ielGeoByType, std::vector<Point*>& elemPoint, std::vector<felInt>& elemIdPoint, FlagMatrixRHS flagMatrixRHS)
6388 {
6389 IGNORE_UNUSED_RANK;
6390 felInt ielSupportDof1, ielSupportDof2;
6391
6392 // for one element, list of all the associated support elements.
6393 // it assumes that the number of support elements for a given element is
6394 // the same for all unknown. If it is not the case, one need to implement
6395 // an assembling of the matrix by block ?
6396 std::vector<felInt> vectorIdSupport;
6397
6398 // get the global id of the element
6399 felInt ielGeoGlobal, ielGeo = 0;
6400 m_meshLocal[m_currentMesh]->getIdElemFromTypeElemAndIdByType(eltType, ielGeoByType, ielGeo);
6401 ISLocalToGlobalMappingApply(m_mappingElem[m_currentMesh], 1, &ielGeo, &ielGeoGlobal);
6402
6403 // return each id of point of the element and coordinate in two arrays: elemPoint and elemIdPoint.
6404 setElemPoint(eltType, ielGeoByType, elemPoint, elemIdPoint, vectorIdSupport);
6405
6406 // Fourth loop over all the support elements
6407 for (std::size_t it1 = 0; it1 < vectorIdSupport.size(); it1++) {
6408 // get the id of the support
6409 ielSupportDof1 = vectorIdSupport[it1];
6410
6411 for(std::size_t it2 = 0; it2 < vectorIdSupport.size(); it2++) {
6412 // get the id of the support
6413 ielSupportDof2 = vectorIdSupport[it2];
6414
6415 // clear elementary matrices
6416 for (std::size_t j = 0; j < m_matrices.size(); j++)
6417 m_elementMatBD[j]->zero();
6418
6419 // clear elementary vector.
6420 for (std::size_t j = 0; j < m_vectors.size(); j++)
6421 m_elementVectorBD[j]->zero();
6422
6423 // compute boundary terms on element
6424 computeAndApplyElementNaturalBoundaryCondition(elemPoint, elemIdPoint, ielSupportDof1, ielSupportDof2, ielGeoGlobal, flagMatrixRHS);
6425
6426 // add values of elemMat in the global matrix: m_matrices[0].
6427 setValueMatrixRHSBD(ielSupportDof1, ielSupportDof2, flagMatrixRHS);
6428 }
6429 }
6430 }
6431
6432 /***********************************************************************************/
6433 /***********************************************************************************/
6434
6435 void LinearProblem::applyEssentialBoundaryConditionViaPenalizationOnBC(FlagMatrixRHS flagMatrixRHS, const BoundaryCondition* const BC)
6436 {
6437 std::unordered_map<int, double> idBCAndValue;
6438 std::unordered_set<felInt> idDofBC;
6439 getListDofOfBC(*BC, idDofBC, idBCAndValue);
6440
6441 // double TGV(std::numeric_limits<double>::max()); using this only homogeneous BD
6442 double TGV(1e30); // TODO
6443 for(auto itDofBC = idDofBC.begin(); itDofBC != idDofBC.end(); ++itDofBC) {
6444 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix)
6445 m_matrices[0].setValue(*itDofBC, *itDofBC, TGV, INSERT_VALUES);
6446 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs)
6447 vector().setValue(*itDofBC, idBCAndValue[*itDofBC]*TGV, INSERT_VALUES);
6448 }
6449 }
6450
6451 /***********************************************************************************/
6452 /***********************************************************************************/
6453
6454 namespace { // anonymous
6455 /// Wrapper around call to AOPetscToApplication
6456 felInt PetscToApplicationIndex(const AO& ao, felInt petscIndex) {
6457 felInt ia = petscIndex;
6458 AOPetscToApplication(ao, 1, &ia);
6459 return ia;
6460 }
6461 } // namespace anonymous
6462
6463 /***********************************************************************************/
6464 /***********************************************************************************/
6465
6466 void LinearProblem::applyEssentialBoundaryConditionViaSymmetricPseudoEliminationOnBC(FlagMatrixRHS flagMatrixRHS, const BoundaryCondition* const BC, std::vector<felInt>& rows)
6467 {
6468 std::unordered_set<felInt> idDofBC;
6469 std::unordered_map<felInt, double> idBCAndValue;
6470 getListDofOfBC(*BC, idDofBC, idBCAndValue);
6471 for(auto itDofBC = idDofBC.begin(), endDofBC = idDofBC.end();itDofBC != endDofBC; ++itDofBC) {
6472 // First we consider the line related to the current degree of freedom
6473 felInt dofPetscIndex = *itDofBC;
6474 felInt dofApplicationIndex = PetscToApplicationIndex(m_ao, dofPetscIndex);
6475 // Modify the std::vector first
6476 if(flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs) {
6477 vector().setValue(dofPetscIndex, idBCAndValue[dofPetscIndex], INSERT_VALUES);
6478 }
6479 // If the matrix is not to be changed, go directly to next iteration
6480 if(flagMatrixRHS != FlagMatrixRHS::matrix_and_rhs && flagMatrixRHS != FlagMatrixRHS::only_matrix)
6481 continue;
6482
6483 // Data required for Petsc operation, that will be performed after the loop ended
6484 rows.push_back(dofApplicationIndex);
6485 }
6486 }
6487
6488 /***********************************************************************************/
6489 /***********************************************************************************/
6490
6491 #ifdef FELISCE_WITH_CVGRAPH
6492
6493 void LinearProblem::setValueMatrixBD(felInt ielSupportDof)
6494 {
6495 const felInt numDofTotal = this->m_elementMatBD[0]->mat().size1();
6496 felInt cptGpos;
6497 int idVar;
6498 std::vector<felInt> loc2globTmp;
6499
6500 // Build the loc2glob map m_GposLine for the first support element (i.e. for the rows of the matrix or RHS)
6501 cptGpos = 0;
6502 for ( std::size_t iUnknown = 0; iUnknown < this->m_listUnknown.getUnknownsRows().size(); iUnknown++) {
6503 idVar = this->m_listUnknown.idVariable(this->m_listUnknown.getUnknownsRows()[iUnknown]);
6504 this->dof().loc2glob(ielSupportDof, this->m_listCurvilinearFiniteElement[idVar]->numDof(), idVar, m_listVariable[idVar].numComponent(), loc2globTmp);
6505 for(std::size_t i=0; i<loc2globTmp.size(); ++i){
6506 m_globPosRow[cptGpos] = loc2globTmp[i];
6507 m_globPosColumn[cptGpos] = loc2globTmp[i];
6508 ++cptGpos;
6509 }
6510 }
6511
6512 for (int i = 0; i < numDofTotal; ++i)
6513 for (int j = 0; j < numDofTotal; ++j)
6514 m_matrixValues[j + i*numDofTotal] = this->m_elementMatBD[0]->mat()(i,j);
6515
6516 /// Now we have to compute where this numbers have to be put into the boundary matrix
6517 /// volume application -> petsc volume
6518 AOApplicationToPetsc(this->m_ao,numDofTotal,m_globPosRow.data());
6519 AOApplicationToPetsc(this->m_ao,numDofTotal,m_globPosColumn.data());
6520 std::vector<felInt> row;
6521 std::vector<felInt> col;
6522 std::vector<felInt> tmpCol;
6523 std::vector<double> val;
6524 /// petsc volume -> boundary application
6525 for ( int k=0; k < numDofTotal; ++k) {
6526 tmpCol.clear();
6527 try {
6528 // petscVol2ApplicationBD can throw an out_of_range while m_globPosRow[k] can not
6529 // The idea is that if this fails it means that this particular dof is not in the mapping
6530 // and that it can be discarded (e.g. pressure nodes when dealing with Stokes problem)
6531 row.push_back(this->m_auxiliaryDofBD->petscVol2ApplicationBD(m_globPosRow[k]));
6532 for ( int k2=0; k2 < numDofTotal; ++k2) {
6533 try {
6534 tmpCol.push_back(this->m_auxiliaryDofBD->petscVol2ApplicationBD(m_globPosColumn[k2]));
6535 val.push_back(m_matrixValues[k2+k*numDofTotal]);
6536 } catch ( const std::out_of_range& oor ){}
6537 }
6538 } catch ( const std::out_of_range& oor ){}
6539 if (tmpCol.size()>0) {
6540 col=tmpCol;
6541 }
6542 }
6543
6544 /// boundary application -> petsc application
6545 AOApplicationToPetsc(this->m_auxiliaryDofBD->ao(),row.size(),row.data());
6546 AOApplicationToPetsc(this->m_auxiliaryDofBD->ao(),col.size(),col.data());
6547 /// set value
6548 m_auxiliaryMatrix.setValues(row.size(),row.data(),col.size(),col.data(),val.data(),ADD_VALUES);
6549 }
6550
6551 /***********************************************************************************/
6552 /***********************************************************************************/
6553
6554 void LinearProblem::computeResidualOnDofs(PetscVector& residual, PetscVector& stressOut, PetscVector& seqStressOut, std::size_t iConn)
6555 {
6556 PetscVector tmpIn = this->dofBD(iConn).allocateBoundaryVector(DofBoundary::parallel);
6557 PetscVector tmpOut = this->dofBD(iConn).allocateBoundaryVector(DofBoundary::parallel);
6558 this->dofBD(iConn).restrictOnBoundary(residual,tmpIn);
6559 if ( this->dofBD(iConn).hasDofsOnBoundary() ) {
6560 m_kspMassBD[iConn].solve(tmpIn, tmpOut, 0);
6561 }
6562 stressOut.zeroEntries();
6563 this->dofBD(iConn).extendOnVolume(stressOut,tmpOut);
6564 this->gatherVector(stressOut,seqStressOut);
6565 }
6566
6567 /***********************************************************************************/
6568 /***********************************************************************************/
6569
6570 void LinearProblem::sendInitialCondition(std::size_t iConn) {
6571 if ( this->slave()->initialConditionNeeded(iConn) ) {
6572 this->sendZero(iConn);
6573 }
6574 }
6575
6576 /***********************************************************************************/
6577 /***********************************************************************************/
6578
6579 void LinearProblem::cvgAddExternalResidualToRHS()
6580 {
6581 // Loop over the cvgraph connections
6582 for ( std::size_t iConn(0); iConn<this->slave()->numConnections(); ++iConn ) {
6583 if ( this->slave()->sumDirectlyIntoRHS(iConn) ) {
6584 sumOnBoundaryCVGraph(vector(), m_seqVecs.Get("cvgraph"+this->slave()->neumannVariable(iConn)), dofBD(iConn) );
6585 }
6586 }
6587 }
6588
6589 /***********************************************************************************/
6590 /***********************************************************************************/
6591
6592 void LinearProblem::sumOnBoundaryCVGraph(PetscVector& v, PetscVector& b, const DofBoundary& dofBD)
6593 {
6594 felInt numLocalDofInterface = dofBD.numLocalDofInterface();
6595 std::vector<double> tmp(numLocalDofInterface);
6596 b.getValues(numLocalDofInterface, dofBD.loc2PetscVolPtr(), tmp.data() );
6597 v.setValues(numLocalDofInterface, dofBD.loc2PetscVolPtr(), tmp.data(),ADD_VALUES);
6598 v.assembly();
6599 }
6600
6601 /***********************************************************************************/
6602 /***********************************************************************************/
6603
6604 void LinearProblem::prepareResidual(std::size_t iConn)
6605 {
6606 if ( m_stressOut.isNull() ) {
6607 m_stressOut.duplicateFrom(this->solution());
6608 m_seqStressOut.duplicateFrom(this->sequentialSolution());
6609 }
6610 if ( this->slave()->residualInterpolationType(iConn) == 0 ) {
6611 if ( m_massBD[iConn].isNull() ) {
6612 this->assembleMassBoundaryAndInitKSP(iConn);
6613 }
6614 this->computeResidualOnDofs( m_residual,m_stressOut,m_seqStressOut, iConn);
6615 } else {
6616 m_seqStressOut.copyFrom( m_seqResidual );
6617 }
6618 }
6619
6620 /***********************************************************************************/
6621 /***********************************************************************************/
6622
6623 28180 void LinearProblem::cvgraphFinalizeEssBC()
6624 {
6625
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 28180 times.
28180 if( FelisceParam::instance(this->instanceIndex()).withCVG ) {
6626 if ( slave()->thereIsAtLeastOneDirichletCondition() ) {
6627 if ( m_fstransient->iteration > 0 ) {
6628 PetscPrintf(MpiInfo::petscComm(), "Finalizing essential BC transient with CVGRAPH data\n");
6629 // Loop over the cvgraph connections
6630 for ( std::size_t iConn(0); iConn < slave()->numConnections(); ++iConn ) {
6631 // Extract the labels of the current connection and store them in a set
6632 std::vector<int> tmp = slave()->interfaceLabels(iConn);
6633 std::unordered_set<int> labels(tmp.begin(),tmp.end());
6634 // Loop over the dirichlet BCs, looking for the correct one.
6635 BoundaryCondition* BC;
6636 for(std::size_t iBC(0); iBC < m_boundaryConditionList.numDirichletBoundaryCondition(); iBC++) {
6637 BC = m_boundaryConditionList.Dirichlet(iBC);
6638 if ( BC->listLabel() == labels ) {
6639 this->setValueBoundaryCondition(BC,m_seqVecs.Get(m_cvgDirichletVariable));
6640 }
6641 }
6642 }
6643 }
6644 }
6645 }
6646 28180 }
6647
6648 /***********************************************************************************/
6649 /***********************************************************************************/
6650
6651 void LinearProblem::assembleRHSOnlyCVGraph()
6652 {
6653 ElementType eltType; //geometric element type in the mesh.
6654 int numPointPerElt = 0; //number of points per geometric element.
6655 int currentLabel = 0; //number of label domain.
6656 felInt numEltPerLabel = 0; //number of element for one label and one eltType.
6657 // use to define a "global" numbering of element in the mesh.
6658 felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ];
6659 for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) {
6660 eltType = (ElementType)ityp;
6661 numElement[eltType] = 0;
6662 }
6663
6664 const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal[m_currentMesh]->bagElementTypeDomain();
6665 for (std::size_t ielt = 0; ielt < bagElementTypeDomain.size(); ++ielt) {
6666 eltType = bagElementTypeDomain[ielt];
6667 defineCurrentFiniteElementWithBd(eltType); // TODO no sense here if bagElementTypeDomain.size() > 1
6668 }
6669
6670 std::vector<Point*> elemPoint;
6671 std::vector<felInt> elemIdPoint, vectorIdSupport;
6672 felInt ielSupportDof;
6673
6674 allocateVectorBoundaryConditionDerivedLinPb();
6675
6676 const std::vector<ElementType>& bagElementTypeDomainBoundary = m_meshLocal[m_currentMesh]->bagElementTypeDomainBoundary();
6677 for (std::size_t i = 0; i < bagElementTypeDomainBoundary.size(); ++i) {
6678 eltType = bagElementTypeDomainBoundary[i];
6679 numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType];
6680 elemPoint.resize(numPointPerElt, nullptr);
6681 elemIdPoint.resize(numPointPerElt, 0);
6682 defineCurvilinearFiniteElement(eltType);
6683 initElementArrayBD();
6684 allocateArrayForAssembleMatrixRHSBD(FlagMatrixRHS::only_rhs);
6685
6686 initPerElementTypeBoundaryCondition(eltType, FlagMatrixRHS::only_rhs);
6687 userElementInitNaturalBoundaryCondition();
6688 allocateElemFieldBoundaryCondition(/*idBCforLinCombMethod*/-1);
6689
6690 //second loop on region of the mesh.
6691 for(auto itRef = m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal[m_currentMesh]->intRefToBegEndMaps[eltType].end(); itRef++) {
6692 currentLabel = itRef->first;
6693 numEltPerLabel = itRef->second.second;
6694 if ( Tools::insideVec(FelisceParam::instance(this->instanceIndex()).interfaceLabels,currentLabel) ) {
6695 initPerDomainBoundaryCondition(elemPoint, elemIdPoint, currentLabel, numEltPerLabel, &ielSupportDof, eltType, numElement[eltType], FlagMatrixRHS::only_rhs);
6696 for ( felInt iel = 0; iel < numEltPerLabel; iel++) {
6697 setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport);
6698 for (std::size_t it = 0; it < vectorIdSupport.size(); it++) {
6699 ielSupportDof = vectorIdSupport[it];
6700 m_elementVectorBD[0]->zero();
6701
6702 cvgraphNaturalBC(iel);
6703 applyNaturalBoundaryCondition(elemPoint, elemIdPoint, ielSupportDof, FlagMatrixRHS::only_rhs);
6704 setValueMatrixRHSBD(ielSupportDof, ielSupportDof, FlagMatrixRHS::only_rhs);
6705 }
6706 numElement[eltType]++;
6707 }
6708 } else {
6709 numElement[eltType]+=numEltPerLabel;
6710 }
6711 }
6712 desallocateArrayForAssembleMatrixRHS(FlagMatrixRHS::only_rhs);
6713 }
6714 m_vectors[0].assembly();
6715 }
6716
6717 /***********************************************************************************/
6718 /***********************************************************************************/
6719
6720 void LinearProblem::applyOnlyCVGBoundaryCondition()
6721 {
6722 if ( FelisceParam::instance(this->instanceIndex()).withCVG ) {
6723 if ( FelisceParam::verbose() > 2) {
6724 PetscPrintf(MpiInfo::petscComm(), "\n/============== Information about boundary condition.===============/\n");
6725 m_boundaryConditionList.print(m_verbosity);
6726 PetscPrintf(MpiInfo::petscComm(), "IMPOSING ONLY CVGRAPH DATA\n");
6727 }
6728 // natural conditions to be applied with the assembly loop
6729 if ( slave()->thereIsAtLeastOneNaturalCondition() ) {
6730 assembleRHSOnlyCVGraph();
6731 }
6732 // natural conditions to be directly summed into RHS
6733 cvgAddExternalResidualToRHS();
6734
6735 // applying dirichlet boundary conditions
6736 if ( slave()->thereIsAtLeastOneDirichletCondition() ) {
6737 for ( std::size_t iConn(0); iConn < slave()->numConnections(); ++iConn ) {
6738 // Extract the labels of the current connection and store them in a set
6739 std::vector<int> tmp = slave()->interfaceLabels(iConn);
6740 std::unordered_set<int> labels(tmp.begin(),tmp.end());
6741 for(std::size_t iBC(0); iBC < m_boundaryConditionList.numDirichletBoundaryCondition(); iBC++) {
6742 const BoundaryCondition* const BC = m_boundaryConditionList.Dirichlet(iBC);
6743 if ( BC->listLabel() == labels ) {
6744 switch ( FelisceParam::instance(this->instanceIndex()).essentialBoundaryConditionsMethod ) {
6745 case DirichletApplicationOptions::symmetricPseudoElimination:
6746 {
6747 std::vector<felInt> rows;//unused because of the only_rhs flag.
6748 applyEssentialBoundaryConditionViaSymmetricPseudoEliminationOnBC(FlagMatrixRHS::only_rhs, BC,rows);
6749 break;
6750 }
6751 case DirichletApplicationOptions::penalization:
6752 applyEssentialBoundaryConditionViaPenalizationOnBC(FlagMatrixRHS::only_rhs, BC);
6753 break;
6754 case DirichletApplicationOptions::nonSymmetricPseudoElimination:
6755 default:
6756 FEL_ERROR("Requested method not yet available for cvgraph");
6757 }
6758 }
6759 }
6760 }
6761 vector().assembly();
6762 }
6763 }
6764 }
6765
6766 /***********************************************************************************/
6767 /***********************************************************************************/
6768
6769 void LinearProblem::sendZero(std::size_t iConn )
6770 {
6771 PetscVector zero;
6772 zero.duplicateFrom(this->sequentialSolution());
6773 zero.zeroEntries();
6774 std::vector<PetscVector> vecs;
6775 for ( std::size_t cVar(0); cVar<this->slave()->numVarToSend(iConn); ++cVar) {
6776 vecs.push_back(zero);
6777 }
6778 this->slave()->sendData(vecs,iConn);
6779 }
6780
6781 #endif
6782 } // felisce namespace
6783