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 |