Directory: | ./ |
---|---|
File: | Solver/eigenProblem.cpp |
Date: | 2024-04-14 07:32:34 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 485 | 870 | 55.7% |
Branches: | 379 | 1142 | 33.2% |
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: E. Schenone | ||
13 | // | ||
14 | |||
15 | // System includes | ||
16 | |||
17 | // External includes | ||
18 | |||
19 | // Project includes | ||
20 | #include "Solver/eigenProblem.hpp" | ||
21 | #include "FiniteElement/elementMatrix.hpp" | ||
22 | #include "FiniteElement/elementField.hpp" | ||
23 | #include "Core/felisceParam.hpp" | ||
24 | |||
25 | namespace felisce | ||
26 | { | ||
27 | /*! Constructor | ||
28 | */ | ||
29 |
6/12✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
|
1 | EigenProblem::EigenProblem() |
30 | { | ||
31 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | nullPetscVector = PetscVector::null(); |
32 | 1 | } | |
33 | |||
34 | /***********************************************************************************/ | ||
35 | /***********************************************************************************/ | ||
36 | |||
37 | 2 | EigenProblem::~EigenProblem() | |
38 | { | ||
39 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
2 | if(m_seqSolAllocated) { |
40 | 2 | m_seqSol.zeroEntries(); | |
41 | 2 | m_seqSol.destroy(); | |
42 | } | ||
43 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
2 | if (m_initNumDofUnknown) { |
44 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
2 | delete [] m_numDofUnknown; |
45 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
2 | delete [] m_numDofLocalUnknown; |
46 | } | ||
47 | |||
48 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
2 | if (m_buildSystem ) { |
49 | 2 | m_sol.destroy(); | |
50 | } | ||
51 | |||
52 | #ifdef FELISCE_WITH_SLEPC | ||
53 | 2 | EPSDestroy(&m_eps); | |
54 | #endif | ||
55 | |||
56 | } | ||
57 | |||
58 | /***********************************************************************************/ | ||
59 | /***********************************************************************************/ | ||
60 | |||
61 | 1 | void EigenProblem::initialize(const GeometricMeshRegion::Pointer& mesh, FelisceTransient::Pointer fstransient, MPI_Comm& comm) | |
62 | { | ||
63 | 1 | m_fstransient = fstransient; | |
64 | 1 | m_petscComm = comm; | |
65 | 1 | m_verbose = FelisceParam::verbose(); | |
66 | 1 | m_mesh = mesh; | |
67 | |||
68 | #ifdef FELISCE_WITH_SLEPC | ||
69 | 1 | EPSCreate(comm, &m_eps); | |
70 | #endif | ||
71 | 1 | } | |
72 | |||
73 | /***********************************************************************************/ | ||
74 | /***********************************************************************************/ | ||
75 | |||
76 | 1 | void EigenProblem::definePhysicalVariable(const std::vector<PhysicalVariable>& listVariable, const std::vector<std::size_t>& listNumComp) | |
77 | { | ||
78 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for (std::size_t iVar = 0; iVar < listVariable.size(); iVar++) { |
79 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | m_listVariable.addVariable(listVariable[iVar],listNumComp[iVar]); |
80 | } | ||
81 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (listVariable.size() != m_listVariable.size()) { |
82 | ✗ | FEL_ERROR("Problem with your input file. Not Enought physical variable defined for this problem!"); | |
83 | } | ||
84 | |||
85 | //link between unknown of the linear system and variable define in the problem. | ||
86 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | Variable variable; |
87 | 1 | bool unknown = false; | |
88 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++) { |
89 |
5/6✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
|
2 | for (std::size_t iVar = 0; iVar < listVariable.size() && unknown == false; iVar++) { |
90 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | variable = m_listVariable[iVar]; |
91 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if ( m_listUnknown[iUnknown] == variable.physicalVariable()) { |
92 | 1 | m_listUnknown.idVariable(iUnknown) = iVar; | |
93 | 1 | m_listVariable.listIdUnknownOfVariable(iVar) = static_cast<int>(iUnknown); | |
94 | 1 | unknown = true; | |
95 | } | ||
96 | } | ||
97 | 1 | unknown = false; | |
98 | } | ||
99 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_verbose) { |
100 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | PetscPrintf(m_petscComm, "\n/========== Information about the linear system ==========/\n"); |
101 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | PetscPrintf(m_petscComm, "<%s>.\n", nameOfTheProblem.c_str()); |
102 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | PetscPrintf(m_petscComm, "Unknonwns are: "); |
103 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for (std::size_t iUnkonwn = 0; iUnkonwn < m_listUnknown.size(); iUnkonwn++) { |
104 |
2/4✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
1 | PetscPrintf(m_petscComm, "<%s> ", m_listVariable[m_listUnknown.idVariable(iUnkonwn)].name().c_str()); |
105 | } | ||
106 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | PetscPrintf(m_petscComm, "\nPhysical variables associate: "); |
107 | } | ||
108 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_listVariable.print(m_verbose); |
109 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_listUnknown.setDefaultMask(m_listVariable); |
110 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_listUnknown.print(1); |
111 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_numDofUnknown == nullptr) |
112 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | m_numDofUnknown = new felInt[m_listUnknown.size()]; |
113 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_numDofLocalUnknown == nullptr) |
114 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | m_numDofLocalUnknown = new felInt[m_listUnknown.size()]; |
115 | 1 | m_initNumDofUnknown = true; | |
116 | |||
117 | //todo Jeremie 01 02 2012: assemble multiple matrix | ||
118 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_Matrix.resize(m_numberOfMatrix); |
119 | 1 | } | |
120 | |||
121 | /***********************************************************************************/ | ||
122 | /***********************************************************************************/ | ||
123 | |||
124 | 1 | void EigenProblem::computeDof(int numProc, int idProc) | |
125 | { | ||
126 | // felInt numElement = m_mesh->getNumDomainElement() + m_mesh->getNumBoundaryElement(); | ||
127 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ ) { |
128 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | SupportDofMesh supportDofMesh(m_listVariable[m_listUnknown.idVariable(iUnknown)], m_mesh); |
129 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_supportDofUnknown.push_back(supportDofMesh); |
130 | |||
131 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_verbose) { |
132 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | PetscPrintf(m_petscComm, "\n/=======Global support dof mesh associate to the unknown: <%s>.======/\n", |
133 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | m_listVariable[m_listUnknown.idVariable(iUnknown)].name().c_str()); |
134 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | supportDofMesh.print(m_verbose); |
135 | } | ||
136 | 1 | } | |
137 | |||
138 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | std::vector<SupportDofMesh*> pSupportDofUnknown(m_supportDofUnknown.size(), nullptr); |
139 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for(std::size_t iUnknown=0; iUnknown < m_supportDofUnknown.size(); ++iUnknown) |
140 | 1 | pSupportDofUnknown[iUnknown] = &m_supportDofUnknown[iUnknown]; | |
141 | |||
142 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_dof.setDof(m_listUnknown, m_listVariable, pSupportDofUnknown); |
143 | //m_dof.buildPattern(); | ||
144 | //Initialize pattern, random repartition on processors before call ParMetis. | ||
145 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_dof.initializePattern(numProc, idProc); |
146 | |||
147 | 1 | m_numDof = m_dof.numDof(); | |
148 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ ) { |
149 | 1 | m_numDofUnknown[iUnknown] = m_dof.numDofPerUnknown()[iUnknown]; | |
150 | } | ||
151 | |||
152 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_verbose) { |
153 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | PetscPrintf(m_petscComm, "\n/========== Information about dof ==========/\n"); |
154 | } | ||
155 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_dof.print(m_verbose); |
156 | 1 | } | |
157 | |||
158 | /***********************************************************************************/ | ||
159 | /***********************************************************************************/ | ||
160 | |||
161 | 1 | void EigenProblem::partitionDof( idx_t numPart, int rankPart, MPI_Comm comm) | |
162 | { | ||
163 | /*! | ||
164 | Partitioning of the dof. | ||
165 | */ | ||
166 | |||
167 | /* | ||
168 | Declaration of the parameters for ParMetis. | ||
169 | idx_t define the type for ParMetis int. | ||
170 | */ | ||
171 | |||
172 | // Input parameters | ||
173 | 1 | idx_t num_flag = 0; // C-style array index. | |
174 | 1 | idx_t ncon = 1; // number of weight per vertices of the graph. | |
175 | 1 | idx_t wgtFlag = 0; // No weight in the graph. | |
176 | idx_t option[3]; // verbose level and random seed for parmetis. | ||
177 | 1 | idx_t vertexdist[numPart + 1]; // Repartition of dof between the processes. | |
178 | |||
179 | 1 | real_t ubvec = static_cast<real_t>(1.05); // Imbalance tolerance | |
180 | |||
181 | // Output parameters | ||
182 | idx_t edgecut; // Number of edge in the graph that are cut by the partitioning. | ||
183 | 1 | int numRows = m_dof.pattern().numRows(); | |
184 |
1/2✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | std::vector<idx_t> dofPartitionning(m_dof.pattern().numRows(), 0); // The partition of the dof. |
185 | |||
186 | /* | ||
187 | Initialisation of the parameters. | ||
188 | */ | ||
189 | |||
190 | // vertexdist | ||
191 | // vertexdist[j] = sum(size in process i), for i=0,..,j-1. | ||
192 | // initialize the first value (always 0) | ||
193 | 1 | vertexdist[0] = 0; | |
194 | |||
195 | // Gather all the size in vertexdist, starting at index 1 (because vertexdist[0] is 0) | ||
196 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | MPI_Allgather(&numRows, 1, MPI_INT, &vertexdist[1], 1, MPI_INT, comm); |
197 | |||
198 | // Compute the partial sum | ||
199 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | for (int i = 1; i < numPart; i ++) |
200 | ✗ | vertexdist[i + 1] += vertexdist[i]; | |
201 | |||
202 | // option | ||
203 | 1 | option[0] = 1; // 0 = default values, 1 = user defined. | |
204 | 1 | option[1] = 100; // verbose level. | |
205 | 1 | option[2] = 100; // random seed. | |
206 | |||
207 | { | ||
208 | // tpwgts | ||
209 | 1 | real_t tpwgts[numPart*ncon]; // See parmetis manual for description | |
210 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | for ( felInt i= 0; i < numPart*ncon; i++) |
211 | 1 | tpwgts[i] = static_cast<real_t>(1.)/numPart; | |
212 | |||
213 | /* | ||
214 | Parmetis call | ||
215 | */ | ||
216 | |||
217 | 1 | MPI_Comm comm_bis = PETSC_COMM_WORLD; | |
218 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
|
1 | 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); |
219 | 1 | } | |
220 | |||
221 | /* | ||
222 | Gather the partitioning to all process | ||
223 | */ | ||
224 | |||
225 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | m_dofPart.resize(m_dof.numDof(), 0); |
226 | |||
227 | { | ||
228 | 1 | felInt recvcount[numPart]; | |
229 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | for(int i=0; i<numPart; i++) |
230 | 1 | recvcount[i] = vertexdist[i+1] - vertexdist[i]; | |
231 | |||
232 |
1/2✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | MPI_Allgatherv(dofPartitionning.data(), dofPartitionning.size(), MPI_INT, m_dofPart.data(), recvcount, vertexdist, MPI_INT, comm); |
233 | 1 | } | |
234 | |||
235 | // Count the number of local dofs | ||
236 |
2/2✓ Branch 1 taken 4225 times.
✓ Branch 2 taken 1 times.
|
4226 | for (felInt i = 0; i < m_dof.numDof(); i++) { |
237 |
1/2✓ Branch 1 taken 4225 times.
✗ Branch 2 not taken.
|
4225 | if (m_dofPart[i] == rankPart) |
238 | 4225 | m_numDofLocal++; | |
239 | } | ||
240 | |||
241 | /* | ||
242 | Build the matrix pattern | ||
243 | */ | ||
244 | |||
245 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | m_dof.buildPattern(rankPart, m_dofPart.data()); |
246 | |||
247 | // Pattern operations | ||
248 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if(m_dof.patternIsChanged()) { |
249 | ✗ | m_dof.mergeLocalCompPattern(m_petscComm, numPart, rankPart, m_dofPart); | |
250 | |||
251 | //free memory | ||
252 | ✗ | m_dof.clearPatternC(); | |
253 | } | ||
254 | |||
255 | /*! | ||
256 | Global ordering: AO is an application between global mesh ordering and global ordering of Petsc | ||
257 | AO: globalordering to globalordering | ||
258 | the action is: | ||
259 | - Take the global index associated to the i-th proc | ||
260 | - Create an application to a new global index in order to have contiguous global indexes on the processor | ||
261 | |||
262 | both global ordering are on input (loc2glob and pordering) | ||
263 | AOCreateBasic(comm, m_numDofLocal, loc2Glob, pordering, &m_ao); | ||
264 | |||
265 | Example: | ||
266 | Proc 0: | ||
267 | glob2loc = [0 1 2 3 8] | ||
268 | pordering =[0 1 2 3 4] | ||
269 | |||
270 | Proc 1: | ||
271 | glob2loc = [4 5 6 7] | ||
272 | pordering =[5 6 7 8] | ||
273 | */ | ||
274 | { | ||
275 | felInt rstart; | ||
276 | 1 | felInt cptDof = 0; | |
277 | |||
278 | 1 | felInt loc2Glob[m_numDofLocal]; | |
279 |
2/2✓ Branch 0 taken 4225 times.
✓ Branch 1 taken 1 times.
|
4226 | for (felInt i = 0; i < m_numDofLocal; i++) |
280 | 4225 | loc2Glob[i] = 0; | |
281 | |||
282 |
2/2✓ Branch 1 taken 4225 times.
✓ Branch 2 taken 1 times.
|
4226 | for (felInt i = 0; i < m_dof.numDof(); i++) { |
283 |
1/2✓ Branch 1 taken 4225 times.
✗ Branch 2 not taken.
|
4225 | if (m_dofPart[i] == rankPart) { |
284 | // cptDof (local) -> i (global) | ||
285 | 4225 | loc2Glob[cptDof] = i; | |
286 | 4225 | cptDof++; | |
287 | } | ||
288 | } | ||
289 | |||
290 | // inclusive sum (rank_0 = numdoflocal_0, rank_i = sum_j=0^rank_i numdoflocal_i) | ||
291 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | MPI_Scan(&m_numDofLocal, &rstart, 1, MPIU_INT, MPI_SUM, comm); |
292 | 1 | rstart -= m_numDofLocal; | |
293 | |||
294 | 1 | felInt pordering[m_numDofLocal]; | |
295 |
2/2✓ Branch 0 taken 4225 times.
✓ Branch 1 taken 1 times.
|
4226 | for (felInt i= 0; i < m_numDofLocal; i++) { |
296 | // pordering: so global indexes are contiguous on a processor; pordering: global->global | ||
297 | 4225 | pordering[i] = rstart + i; | |
298 | } | ||
299 | |||
300 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | AOCreateBasic(comm, m_numDofLocal, loc2Glob, pordering, &m_ao); |
301 | // AOView(m_ao,PETSC_VIEWER_STDOUT_WORLD); | ||
302 | 1 | } | |
303 | |||
304 | /*! | ||
305 | Compute the element repartition. | ||
306 | An element is owned by a process k if most of its dof are on process k. | ||
307 | In case of a draw, the element belongs to the process with the smallest id. | ||
308 | */ | ||
309 | |||
310 | // Declaration of some variables | ||
311 | 1 | felInt max = 0; // used to compute indice_max. | |
312 | 1 | felInt indice_max = 0; // id of the process that owns the element. | |
313 | felInt idDof; // Local number of a dof. | ||
314 | felInt ielSupportDof; // Global number of a dof. | ||
315 | 1 | felInt numElemsPerRef = 0; // Number of elements per label. | |
316 | int idVar; // id of a physical variable. | ||
317 | 1 | felInt numEltTot = 0; // Total number of element (to be computed). | |
318 | felInt numEltPerType[GeometricMeshRegion::m_numTypesOfElement]; // Total number of element per type (to be computed). | ||
319 | 1 | felInt numDofPerProcs[numPart]; // Number of dofs per process. | |
320 | GeometricMeshRegion::ElementType eltType; | ||
321 | |||
322 | // Initialization | ||
323 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | for ( int i = 0; i < numPart; i++) |
324 | 1 | numDofPerProcs[i] = 0; | |
325 | |||
326 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
|
26 | for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++) |
327 | 25 | numEltPerType[ityp] = 0; | |
328 | |||
329 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | m_eltPart.resize(m_mesh->getNumElement(), 0); |
330 | |||
331 | // bag containing all the domain element type. | ||
332 | 1 | const std::vector<ElementType>& bagElementTypeDomain =m_mesh->bagElementTypeDomain(); | |
333 | |||
334 | // for each domain element type | ||
335 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) { |
336 | 1 | eltType = bagElementTypeDomain[i]; | |
337 | |||
338 | // for each label where the current element type can be found | ||
339 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
|
2 | for(auto itRef =m_mesh->intRefToBegEndMaps[eltType].begin(); itRef !=m_mesh->intRefToBegEndMaps[eltType].end(); itRef++) { |
340 | 1 | numElemsPerRef = itRef->second.second; | |
341 | |||
342 | // for each local element with the current label | ||
343 |
2/2✓ Branch 0 taken 8192 times.
✓ Branch 1 taken 1 times.
|
8193 | for (felInt iel = 0; iel < numElemsPerRef; iel++) { |
344 | |||
345 | // for each unknown of the linear system | ||
346 |
2/2✓ Branch 1 taken 8192 times.
✓ Branch 2 taken 8192 times.
|
16384 | for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++) { |
347 | // get the global id of the current element | ||
348 | 8192 | idVar = m_listUnknown.idVariable(iUnknown); | |
349 |
1/2✓ Branch 2 taken 8192 times.
✗ Branch 3 not taken.
|
8192 | m_supportDofUnknown[iUnknown].getIdElementSupport(eltType, numEltPerType[eltType], ielSupportDof); |
350 | |||
351 | // for each support dof of the current element | ||
352 |
2/2✓ Branch 2 taken 24576 times.
✓ Branch 3 taken 8192 times.
|
32768 | for (felInt iSupport = 0; iSupport < m_supportDofUnknown[iUnknown].getNumSupportDof(ielSupportDof); iSupport++) { |
353 | |||
354 | // for each components of the current unknown | ||
355 |
2/2✓ Branch 2 taken 24576 times.
✓ Branch 3 taken 24576 times.
|
49152 | for (std::size_t iComp = 0; iComp < m_listVariable[idVar].numComponent(); iComp++) { |
356 | // get the global id of the dof and increased numDofPerProcs | ||
357 |
1/2✓ Branch 1 taken 24576 times.
✗ Branch 2 not taken.
|
24576 | m_dof.loc2glob(ielSupportDof, iSupport, idVar, iComp, idDof); |
358 | 24576 | ++numDofPerProcs[m_dofPart[idDof]]; | |
359 | } | ||
360 | } | ||
361 | } | ||
362 | |||
363 | // Find the rank of the process that owns the most dof in the current element. | ||
364 |
2/2✓ Branch 0 taken 8192 times.
✓ Branch 1 taken 8192 times.
|
16384 | for (int j = 0; j < numPart; j++) { |
365 |
1/2✓ Branch 0 taken 8192 times.
✗ Branch 1 not taken.
|
8192 | if (max < numDofPerProcs[j]) { |
366 | 8192 | max = numDofPerProcs[j]; | |
367 | 8192 | indice_max = j; | |
368 | } | ||
369 | } | ||
370 | |||
371 | // Fill m_eltPart | ||
372 | 8192 | m_eltPart[numEltTot] = indice_max; | |
373 | |||
374 | // Increment the counter | ||
375 | 8192 | numEltPerType[eltType]++; | |
376 | 8192 | numEltTot++; | |
377 | |||
378 | // Clear local variables | ||
379 | 8192 | max = 0; | |
380 | 8192 | indice_max = 0; | |
381 |
2/2✓ Branch 0 taken 8192 times.
✓ Branch 1 taken 8192 times.
|
16384 | for ( int j = 0; j < numPart; j++) |
382 | 8192 | numDofPerProcs[j] = 0; | |
383 | } | ||
384 | } | ||
385 | } | ||
386 | |||
387 | // bag containing all the "boundary" element type. | ||
388 | 1 | const std::vector<ElementType>& bagElementTypeDomainBoundary =m_mesh->bagElementTypeDomainBoundary(); | |
389 | |||
390 | // Do the same thing but with the "boundaries" element this time | ||
391 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for (std::size_t i = 0; i < bagElementTypeDomainBoundary.size(); ++i) { |
392 | 1 | eltType = bagElementTypeDomainBoundary[i]; | |
393 | |||
394 |
2/2✓ Branch 6 taken 4 times.
✓ Branch 7 taken 1 times.
|
5 | for(auto itRef =m_mesh->intRefToBegEndMaps[eltType].begin(); itRef !=m_mesh->intRefToBegEndMaps[eltType].end(); itRef++) { |
395 | 4 | numElemsPerRef = itRef->second.second; | |
396 | |||
397 |
2/2✓ Branch 0 taken 256 times.
✓ Branch 1 taken 4 times.
|
260 | for (felInt iel = 0; iel < numElemsPerRef; iel++) { |
398 | |||
399 |
2/2✓ Branch 1 taken 256 times.
✓ Branch 2 taken 256 times.
|
512 | for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++) { |
400 | 256 | idVar = m_listUnknown.idVariable(iUnknown); | |
401 |
1/2✓ Branch 2 taken 256 times.
✗ Branch 3 not taken.
|
256 | m_supportDofUnknown[iUnknown].getIdElementSupport(eltType, numEltPerType[eltType], ielSupportDof); |
402 | |||
403 |
2/2✓ Branch 2 taken 512 times.
✓ Branch 3 taken 256 times.
|
768 | for (int iSupport = 0; iSupport < m_supportDofUnknown[iUnknown].getNumSupportDof(ielSupportDof); iSupport++) { |
404 | |||
405 |
2/2✓ Branch 2 taken 512 times.
✓ Branch 3 taken 512 times.
|
1024 | for (std::size_t iComp = 0; iComp < m_listVariable[idVar].numComponent(); iComp++) { |
406 |
1/2✓ Branch 1 taken 512 times.
✗ Branch 2 not taken.
|
512 | m_dof.loc2glob(ielSupportDof,iSupport,idVar,iComp,idDof); |
407 | 512 | numDofPerProcs[ m_dofPart[idDof] ]++; | |
408 | } | ||
409 | } | ||
410 | } | ||
411 | |||
412 |
2/2✓ Branch 0 taken 256 times.
✓ Branch 1 taken 256 times.
|
512 | for (int j = 0; j < numPart; j++) { |
413 |
1/2✓ Branch 0 taken 256 times.
✗ Branch 1 not taken.
|
256 | if (max < numDofPerProcs[j] ) { |
414 | 256 | max = numDofPerProcs[j]; | |
415 | 256 | indice_max = j; | |
416 | } | ||
417 | } | ||
418 | |||
419 | 256 | m_eltPart[numEltTot] = indice_max; | |
420 | 256 | numEltPerType[eltType]++; | |
421 | 256 | numEltTot++; | |
422 | |||
423 | 256 | max = 0; | |
424 | 256 | indice_max = 0; | |
425 |
2/2✓ Branch 0 taken 256 times.
✓ Branch 1 taken 256 times.
|
512 | for (int j = 0; j < numPart; j++) |
426 | 256 | numDofPerProcs[j] = 0; | |
427 | } | ||
428 | } | ||
429 | } | ||
430 | 2 | } | |
431 | |||
432 | /***********************************************************************************/ | ||
433 | /***********************************************************************************/ | ||
434 | |||
435 | ✗ | void EigenProblem::getSupportCoordinate(felInt idElt, | |
436 | felInt idSupport, | ||
437 | int iUnknown, | ||
438 | Point& pt) | ||
439 | { | ||
440 | ✗ | const felInt id = m_supportDofUnknownLocal[iUnknown].iSupportDof()[m_supportDofUnknownLocal[iUnknown].iEle()[idElt] | |
441 | ✗ | + idSupport]; | |
442 | ✗ | pt = m_supportDofUnknownLocal[iUnknown].listNode()[id]; | |
443 | } | ||
444 | |||
445 | /***********************************************************************************/ | ||
446 | /***********************************************************************************/ | ||
447 | |||
448 | 1 | void EigenProblem::cutMesh() | |
449 | { | ||
450 | 1 | partitionDof(static_cast<idx_t>(MpiInfo::numProc()), MpiInfo::rankProc(), MpiInfo::petscComm()); | |
451 | 1 | setLocalMeshAndSupportDofMesh(MpiInfo::rankProc()); | |
452 | 1 | } | |
453 | |||
454 | /***********************************************************************************/ | ||
455 | /***********************************************************************************/ | ||
456 | |||
457 | 1 | void EigenProblem::setLocalMeshAndSupportDofMesh(int rankPart) { | |
458 | 1 | int idVar = -1; | |
459 | |||
460 | // Set the local mesh and fill the local to global mapping for the support elements (loc2GlobSupportElem) | ||
461 | 1 | std::vector<felInt> loc2GlobElem; | |
462 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_meshLocal = felisce::make_shared<GeometricMeshRegion>(); |
463 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | m_meshLocal->setLocalMesh(*m_mesh, m_eltPart, rankPart, loc2GlobElem); |
464 | |||
465 | |||
466 | // for each unknown, create the support dof and put them in m_supportDofUnknownLocal | ||
467 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ ) { |
468 | 1 | idVar = m_listUnknown.idVariable(iUnknown); | |
469 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | SupportDofMesh supportDofMesh(m_listVariable[idVar], m_meshLocal, loc2GlobElem, m_supportDofUnknown[iUnknown]); |
470 | |||
471 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_supportDofUnknownLocal.push_back(supportDofMesh); |
472 | 1 | } | |
473 | |||
474 | // Create the local to global mapping for the elements | ||
475 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | IS_LOCAL_TO_GLOBAL_MAPPING_MACRO(m_petscComm, 1, loc2GlobElem.size(), loc2GlobElem.data(), PETSC_COPY_VALUES, &m_mappingElem); |
476 | |||
477 | // print info on the local mesh and supportDofMeshes | ||
478 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_verbose) { |
479 | // print the local mesh | ||
480 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | PetscPrintf(m_petscComm, "\n/================== Local mesh ================/\n"); |
481 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | m_meshLocal->print(m_verbose); |
482 | |||
483 | // print the local supportDofMesh for each unknown | ||
484 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for(std::size_t iUnknown=0; iUnknown<m_listUnknown.size(); iUnknown++) { |
485 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | PetscPrintf(m_petscComm, |
486 | "\n/=========== Local support dof mesh associate to the unknown: <%s> ===========/\n", | ||
487 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | m_listVariable[idVar].name().c_str()); |
488 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | m_supportDofUnknownLocal[iUnknown].print(m_verbose); |
489 | } | ||
490 | } | ||
491 | 1 | } | |
492 | |||
493 | /***********************************************************************************/ | ||
494 | /***********************************************************************************/ | ||
495 | |||
496 | 1 | void EigenProblem::allocateMatrix() | |
497 | { | ||
498 | // Create the local to global mapping for support dofs. | ||
499 | 1 | felInt loc2Glob[m_numDofLocal]; | |
500 | 1 | felInt cptDof= 0; | |
501 |
2/2✓ Branch 0 taken 4225 times.
✓ Branch 1 taken 1 times.
|
4226 | for ( felInt iLDof = 0; iLDof < m_numDofLocal; iLDof++) |
502 | 4225 | loc2Glob[iLDof] = 0; | |
503 | |||
504 |
2/2✓ Branch 1 taken 4225 times.
✓ Branch 2 taken 1 times.
|
4226 | for ( felInt iDof = 0; iDof < m_dof.numDof(); iDof++) { |
505 |
2/4✓ Branch 2 taken 4225 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4225 times.
✗ Branch 5 not taken.
|
4225 | if ( m_dofPart[iDof] == MpiInfo::rankProc() ) { |
506 | 4225 | loc2Glob[cptDof] = iDof; | |
507 | 4225 | cptDof++; | |
508 | } | ||
509 | } | ||
510 | |||
511 | // global to local mapping on nodes | ||
512 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | IS_LOCAL_TO_GLOBAL_MAPPING_MACRO(m_petscComm, 1, m_numDofLocal, loc2Glob, PETSC_COPY_VALUES, &m_mappingNodes); |
513 | // ISLocalToGlobalMappingView( m_mappingNodes, PETSC_VIEWER_STDOUT_WORLD); | ||
514 | |||
515 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
|
1 | if ( MpiInfo::numProc() > 1 ) { |
516 | ✗ | felInt iCSR[m_dof.pattern().numRows()+1]; | |
517 | ✗ | felInt jCSR[m_dof.pattern().numNonzeros()]; | |
518 | |||
519 | ✗ | iCSR[0] = 0; | |
520 | ✗ | std::set<felInt> jCSRSorted; | |
521 | felInt connect; | ||
522 | felInt globValue; | ||
523 | ✗ | for ( felInt ii = 0; ii < m_numDofLocal; ii++) { | |
524 | ✗ | connect = m_dof.pattern().numNonzerosInRow(ii); | |
525 | ✗ | iCSR[ii+1] = iCSR[ii] + connect; | |
526 | ✗ | for ( felInt jj = 0; jj < connect; jj++) { | |
527 | ✗ | globValue = m_dof.pattern().columnIndex( m_dof.pattern().rowPointer(ii) + jj ); | |
528 | ✗ | AOApplicationToPetsc(m_ao, 1, &globValue); | |
529 | ✗ | jCSRSorted.insert( globValue ); | |
530 | } | ||
531 | ✗ | felInt kk = 0; | |
532 | ✗ | for(auto it_jCSR = jCSRSorted.begin(); it_jCSR != jCSRSorted.end(); it_jCSR++) { | |
533 | ✗ | jCSR[ iCSR[ii] + kk] = *it_jCSR; | |
534 | ✗ | kk++; | |
535 | } | ||
536 | ✗ | jCSRSorted.clear(); | |
537 | } | ||
538 | ✗ | for (std::size_t ii = 0; ii < m_Matrix.size(); ii++) { | |
539 | ✗ | m_Matrix[ii].createAIJ(m_petscComm, m_numDofLocal, m_numDofLocal, m_dof.numDof(), m_dof.numDof(), 0, FELISCE_PETSC_NULLPTR, 0, FELISCE_PETSC_NULLPTR); | |
540 | ✗ | m_Matrix[ii].setFromOptions(); | |
541 | ✗ | m_Matrix[ii].mpiAIJSetPreallocationCSR( iCSR, jCSR, nullptr); | |
542 | ✗ | m_Matrix[ii].setOption(MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE); | |
543 | } | ||
544 | ✗ | } else { | |
545 | 1 | const std::size_t numRows = m_dof.pattern().numRows(); | |
546 | 1 | felInt nnz[ numRows ]; | |
547 |
2/2✓ Branch 0 taken 4225 times.
✓ Branch 1 taken 1 times.
|
4226 | for ( felInt idof = 0; idof < static_cast<felInt>(numRows) ; idof++) { |
548 |
1/2✓ Branch 2 taken 4225 times.
✗ Branch 3 not taken.
|
4225 | nnz[idof] = m_dof.pattern().numNonzerosInRow(idof); |
549 | } | ||
550 | |||
551 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
|
3 | for (std::size_t ii = 0; ii < m_Matrix.size(); ii++) { |
552 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | m_Matrix[ii].createSeqAIJ(m_petscComm, numRows, numRows, 0, nnz); |
553 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | m_Matrix[ii].setFromOptions(); |
554 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | m_Matrix[ii].setOption(MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE); |
555 | } | ||
556 | 1 | } | |
557 | |||
558 | 1 | m_numDof = m_dof.numDof(); | |
559 | |||
560 | // Create the std::vector solution | ||
561 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_sol.createMPI(m_petscComm, m_numDofLocal, m_numDof); |
562 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_sol.set( 0.); |
563 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | allocateSequentialSolution(); |
564 | 1 | m_buildSystem = true; | |
565 | |||
566 | // Get the local size of all process | ||
567 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | m_localSizeOfVector.resize(MpiInfo::numProc()); |
568 |
3/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
|
2 | for (int ii = 0; ii < MpiInfo::numProc(); ii++) |
569 | 1 | m_localSizeOfVector[ii] = 0; | |
570 | |||
571 | 1 | felInt sizeLocal = 0; | |
572 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_sol.getLocalSize(&sizeLocal); |
573 | |||
574 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | MPI_Allgather(&sizeLocal, 1, MPI_INT, &m_localSizeOfVector[0], 1, MPI_INT, m_petscComm); |
575 | |||
576 | // For each unknown, create a local to global mapping to std::unordered_map the local id of dof to their global id in the petsc ordering. | ||
577 | 1 | felInt idGlobalDof = 0; | |
578 | 1 | felInt sumPreviousSizeLocal = 0; | |
579 | 1 | std::vector<felInt> loc2GlobPerUnknown; | |
580 | felInt sizeIdDof; | ||
581 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | m_mappingIdLocalDofPerUnknownToIdGlobalDofPetsc.resize(m_listUnknown.size()); |
582 | |||
583 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
|
1 | for ( int iProc = 0; iProc < MpiInfo::rankProc(); iProc++) |
584 | ✗ | sumPreviousSizeLocal += m_localSizeOfVector[iProc]; | |
585 | |||
586 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ ) |
587 | 1 | m_numDofLocalUnknown[iUnknown] = 0; | |
588 | |||
589 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++ ) { |
590 |
2/2✓ Branch 0 taken 4225 times.
✓ Branch 1 taken 1 times.
|
4226 | for ( felInt iDof = 0; iDof < m_numDofUnknown[iUnknown]; iDof++) { |
591 |
1/2✓ Branch 1 taken 4225 times.
✗ Branch 2 not taken.
|
4225 | AOApplicationToPetsc(m_ao, 1, &idGlobalDof); |
592 |
4/8✓ Branch 0 taken 4225 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 4225 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 4225 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4225 times.
✗ Branch 9 not taken.
|
4225 | if ( (sumPreviousSizeLocal <= idGlobalDof) && (idGlobalDof < m_localSizeOfVector[MpiInfo::rankProc()]+sumPreviousSizeLocal) ) { |
593 | 4225 | m_numDofLocalUnknown[iUnknown]++; | |
594 |
1/2✓ Branch 1 taken 4225 times.
✗ Branch 2 not taken.
|
4225 | loc2GlobPerUnknown.push_back(idGlobalDof); |
595 | } | ||
596 | 4225 | idGlobalDof++; | |
597 | } | ||
598 | 1 | sizeIdDof = loc2GlobPerUnknown.size(); | |
599 | |||
600 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | IS_LOCAL_TO_GLOBAL_MAPPING_MACRO(m_petscComm, 1, sizeIdDof, loc2GlobPerUnknown.data(), PETSC_COPY_VALUES, |
601 | &m_mappingIdLocalDofPerUnknownToIdGlobalDofPetsc[iUnknown] ); | ||
602 | 1 | loc2GlobPerUnknown.clear(); | |
603 | } | ||
604 | 2 | } | |
605 | |||
606 | /***********************************************************************************/ | ||
607 | /***********************************************************************************/ | ||
608 | |||
609 | 1 | void EigenProblem::allocateSequentialSolution() | |
610 | { | ||
611 | 1 | m_seqSol.createSeq(PETSC_COMM_SELF,m_numDof); | |
612 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_seqSol.set(0.0); |
613 | 1 | m_seqSolAllocated=true; | |
614 | 1 | } | |
615 | |||
616 | /***********************************************************************************/ | ||
617 | /***********************************************************************************/ | ||
618 | |||
619 | 1 | void EigenProblem::assembleMatrix() | |
620 | { | ||
621 | ElementType eltType; // geometric element type in the mesh. | ||
622 | 1 | int numPointPerElt = 0; // number of points per geometric element. | |
623 | 1 | int currentLabel = 0; // number of label domain. | |
624 | 1 | felInt numEltPerLabel = 0; // number of element for one label and one eltType. | |
625 | |||
626 | // use to define a "global" numbering of element in the mesh. | ||
627 | felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ]; | ||
628 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
|
26 | for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) { |
629 | 25 | eltType = (ElementType)ityp; | |
630 | 25 | numElement[eltType] = 0; | |
631 | } | ||
632 | |||
633 | // contains points of the current element. | ||
634 | 1 | std::vector<Point*> elemPoint; | |
635 | // contains ids of point of the current element. | ||
636 | 1 | std::vector<felInt> elemIdPoint; | |
637 | // use to get element number in support dof mesh ordering. | ||
638 | felInt ielSupportDof; | ||
639 | |||
640 | //Assembly loop. | ||
641 | //First loop on geometric type. | ||
642 | 1 | const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal->bagElementTypeDomain(); | |
643 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) { |
644 | 1 | eltType = bagElementTypeDomain[i]; | |
645 | //resize array. | ||
646 | 1 | numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType]; | |
647 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | elemPoint.resize(numPointPerElt, nullptr); |
648 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | elemIdPoint.resize(numPointPerElt, 0); |
649 | //define all current finite element use in the problem from data | ||
650 | //file cnfiguration and allocate 1 and elemVec (question: virtual ?). | ||
651 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | defineFiniteElement(eltType); |
652 | //allocate array use for assemble with petsc. | ||
653 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | allocateArrayForAssembleMatrix(); |
654 | //virtual function use in derived problem to allocate elemenField necessary. | ||
655 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | initPerElementType(); |
656 | //second loop on region of the mesh. | ||
657 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
|
2 | for(auto itRef = m_meshLocal->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal->intRefToBegEndMaps[eltType].end(); itRef++) { |
658 | 1 | currentLabel = itRef->first; | |
659 | 1 | numEltPerLabel = itRef->second.second; | |
660 | //By default this virtual defnie variable m_currentLabel: (m_currentLabel=label). | ||
661 | //We can switch on label region with that and define some parameters. | ||
662 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | initPerDomain(currentLabel); |
663 | //Third loop on element in the region with the type: eltType. ("real" loop on elements). | ||
664 |
2/2✓ Branch 0 taken 8192 times.
✓ Branch 1 taken 1 times.
|
8193 | for ( felInt iel = 0; iel < numEltPerLabel; iel++) { |
665 | // return each id of point of the element and coordinate in two arrays: elemPoint and elemIdPoint. | ||
666 |
1/2✓ Branch 1 taken 8192 times.
✗ Branch 2 not taken.
|
8192 | setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, &ielSupportDof); |
667 | //todo Jeremie 01 02 2012: assemble multiple matrix | ||
668 |
2/2✓ Branch 1 taken 16384 times.
✓ Branch 2 taken 8192 times.
|
24576 | for (std::size_t j = 0; j < m_Matrix.size(); j++) |
669 |
1/2✓ Branch 3 taken 16384 times.
✗ Branch 4 not taken.
|
16384 | m_elementMat[j]->zero(); |
670 |
1/2✓ Branch 1 taken 8192 times.
✗ Branch 2 not taken.
|
8192 | computeElementArray(elemPoint, elemIdPoint, ielSupportDof); |
671 | // add values of elemMat in the global matrix: m_Matrix[0]. | ||
672 |
1/2✓ Branch 1 taken 8192 times.
✗ Branch 2 not taken.
|
8192 | setValueMatrix(&ielSupportDof); |
673 | 8192 | numElement[eltType]++; | |
674 | } | ||
675 | } | ||
676 | //desallocate array use for assemble with petsc. | ||
677 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | desallocateArrayForAssembleMatrix(); |
678 | } | ||
679 | |||
680 | //real assembling of the matrix manage by PETsC. | ||
681 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
|
3 | for (std::size_t i = 0; i < m_Matrix.size(); i++) { |
682 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | m_Matrix[i].assembly(MAT_FINAL_ASSEMBLY); |
683 | } | ||
684 | |||
685 | //call with high level of verbose to print matrix in matlab format. | ||
686 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | writeMatrixForMatlab(m_verbose); |
687 | 1 | } | |
688 | |||
689 | /***********************************************************************************/ | ||
690 | /***********************************************************************************/ | ||
691 | |||
692 | ✗ | void EigenProblem::assembleMatrixBD() | |
693 | { | ||
694 | ElementType eltType; //geometric element type in the mesh. | ||
695 | ✗ | int numPointPerElt = 0; //number of points per geometric element. | |
696 | ✗ | int currentLabel = 0; //number of label domain. | |
697 | ✗ | felInt numEltPerLabel = 0; //number of element for one label and one eltType. | |
698 | |||
699 | // use to define a "global" numbering of element in the mesh. | ||
700 | felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ]; | ||
701 | ✗ | for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) { | |
702 | ✗ | eltType = (ElementType)ityp; | |
703 | ✗ | numElement[eltType] = 0; | |
704 | } | ||
705 | |||
706 | // contains points of the current element. | ||
707 | ✗ | std::vector<Point*> elemPoint; | |
708 | |||
709 | // contains ids of point of the current element. | ||
710 | ✗ | std::vector<felInt> elemIdPoint; | |
711 | |||
712 | // contains the ids of the support elements of a mesh element | ||
713 | ✗ | std::vector<felInt> vectorIdSupport; | |
714 | |||
715 | // use to get element number in support dof mesh ordering. | ||
716 | felInt ielSupportDof; | ||
717 | |||
718 | //Assembly loop. | ||
719 | //First loop on geometric type. | ||
720 | ✗ | const std::vector<ElementType>& bagElementTypeDomain = m_meshLocal->bagElementTypeDomain(); | |
721 | ✗ | for (std::size_t i = 0; i < bagElementTypeDomain.size(); ++i) { | |
722 | ✗ | eltType = bagElementTypeDomain[i]; | |
723 | |||
724 | //resize array. | ||
725 | ✗ | numPointPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType]; | |
726 | ✗ | elemPoint.resize(numPointPerElt, nullptr); | |
727 | ✗ | elemIdPoint.resize(numPointPerElt, 0); | |
728 | |||
729 | //define all current finite element use in the problem from data | ||
730 | //file configuration and allocate elemMat and elemVec (question: virtual ?). | ||
731 | ✗ | defineCurvilinearFiniteElement(eltType); | |
732 | |||
733 | //allocate array use for assemble with petsc. | ||
734 | ✗ | allocateArrayForAssembleMatrixBD(); | |
735 | |||
736 | //virtual function use in derived problem to allocate elemenField necessary. | ||
737 | ✗ | initPerElementTypeBD(); | |
738 | |||
739 | // use by user to add specific term (term source for example with elemField). | ||
740 | ✗ | userElementInitBD(); | |
741 | |||
742 | //second loop on region of the mesh. | ||
743 | ✗ | for(auto itRef = m_meshLocal->intRefToBegEndMaps[eltType].begin(); itRef != m_meshLocal->intRefToBegEndMaps[eltType].end(); itRef++) { | |
744 | ✗ | currentLabel = itRef->first; | |
745 | ✗ | numEltPerLabel = itRef->second.second; | |
746 | |||
747 | //By default this virtual defnie variable m_currentLabel: (m_currentLabel=label). | ||
748 | //We can switch on label region with that and define some parameters. | ||
749 | ✗ | initPerDomainBD(currentLabel); | |
750 | |||
751 | //Third loop on element in the region with the type: eltType. ("real" loop on elements). | ||
752 | ✗ | for ( felInt iel = 0; iel < numEltPerLabel; iel++) { | |
753 | // return each id of point of the element and coordinate in two arrays: elemPoint and elemIdPoint. | ||
754 | ✗ | setElemPoint(eltType, numElement[eltType], elemPoint, elemIdPoint, vectorIdSupport); | |
755 | |||
756 | // loop over all the support elements | ||
757 | ✗ | for (std::size_t it = 0; it < vectorIdSupport.size(); it++) { | |
758 | // get the id of the support | ||
759 | ✗ | ielSupportDof = vectorIdSupport[it]; | |
760 | |||
761 | //todo Jeremie 01 02 2012: assemble multiple matrix | ||
762 | ✗ | for (std::size_t j = 0; j < m_Matrix.size(); j++) | |
763 | ✗ | m_elementMatBD[j]->zero(); | |
764 | |||
765 | // function call in derived problem to compute specific operators of the problem (Heat, N-S,...). | ||
766 | ✗ | computeElementArrayBD(elemPoint, elemIdPoint, ielSupportDof); | |
767 | |||
768 | // add values of elemMat in the global matrix: m_Matrix[0]. | ||
769 | ✗ | setValueMatrixBD(&ielSupportDof); | |
770 | } | ||
771 | ✗ | numElement[eltType]++; | |
772 | } | ||
773 | } | ||
774 | //allocate array use for assemble with petsc. | ||
775 | ✗ | desallocateArrayForAssembleMatrix(); | |
776 | } | ||
777 | |||
778 | ✗ | for (std::size_t i = 0; i < m_Matrix.size(); i++) { | |
779 | ✗ | m_Matrix[i].assembly(MAT_FINAL_ASSEMBLY); | |
780 | } | ||
781 | //call with high level of verbose to print matrix in matlab format. | ||
782 | ✗ | writeMatrixForMatlab(m_verbose); | |
783 | } | ||
784 | |||
785 | /***********************************************************************************/ | ||
786 | /***********************************************************************************/ | ||
787 | |||
788 | 1 | void EigenProblem::initElementArray() | |
789 | { | ||
790 | int idVar; | ||
791 | |||
792 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | std::vector<std::size_t> numberCmp(m_listUnknown.size()); |
793 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | std::vector<const CurBaseFiniteElement*> finiteElt(m_listUnknown.size()); |
794 | |||
795 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for (std::size_t n=0; n<m_listUnknown.size(); n++){ |
796 | 1 | idVar = m_listUnknown.idVariable(n); | |
797 | 1 | numberCmp[n] = m_listVariable[idVar].numComponent(); | |
798 | 1 | finiteElt[n] = m_listCurrentFiniteElement[idVar]; | |
799 | } | ||
800 | |||
801 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
|
3 | for (std::size_t i = 0; i < m_Matrix.size(); i++) |
802 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | m_elementMat.push_back(felisce::make_shared<ElementMatrix>(finiteElt, numberCmp, numberCmp)); |
803 | 1 | } | |
804 | |||
805 | /***********************************************************************************/ | ||
806 | /***********************************************************************************/ | ||
807 | |||
808 | ✗ | void EigenProblem::initElementArrayBD() | |
809 | { | ||
810 | int idVar; | ||
811 | |||
812 | ✗ | std::vector<std::size_t> numberCmp(m_listUnknown.size()); | |
813 | ✗ | std::vector<const CurBaseFiniteElement*> finiteElt(m_listUnknown.size()); | |
814 | ✗ | for (std::size_t n=0; n<m_listUnknown.size(); n++){ | |
815 | ✗ | idVar = m_listUnknown.idVariable(n); | |
816 | ✗ | numberCmp[n] = m_listVariable[idVar].numComponent(); | |
817 | ✗ | finiteElt[n] = m_listCurvilinearFiniteElement[idVar]; | |
818 | } | ||
819 | |||
820 | ✗ | for (std::size_t i = 0; i < m_Matrix.size(); i++) | |
821 | ✗ | m_elementMatBD.push_back(felisce::make_shared<ElementMatrix>(finiteElt, numberCmp, numberCmp)); | |
822 | } | ||
823 | |||
824 | /***********************************************************************************/ | ||
825 | /***********************************************************************************/ | ||
826 | |||
827 | 1 | void EigenProblem::defineFiniteElement(const ElementType& eltType) | |
828 | { | ||
829 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (m_listCurrentFiniteElement.size() > 0) { |
830 | ✗ | m_listCurrentFiniteElement.clear(); | |
831 | //todo Jeremie 01 02 2012: assemble multiple matrix | ||
832 | ✗ | m_elementMat.clear(); | |
833 | } | ||
834 | const RefElement *refEle; | ||
835 | |||
836 | 1 | int typeOfFiniteElement = 0; | |
837 | CurrentFiniteElement* fe; | ||
838 | 1 | const GeoElement *geoEle = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second; | |
839 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for ( std::size_t iVar = 0, size = m_listVariable.size(); iVar < size; iVar++) { |
840 | 1 | typeOfFiniteElement = m_listVariable[iVar].finiteElementType(); // 0 = linear, 1 = quadratic, 2 = bubble | |
841 | 1 | refEle = geoEle->defineFiniteEle(eltType,typeOfFiniteElement, *m_meshLocal); | |
842 |
1/2✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | fe = new CurrentFiniteElement(*refEle,*geoEle,m_listVariable[iVar].getDegreeOfExactness()); |
843 | 1 | m_listCurrentFiniteElement.add(fe); | |
844 | } | ||
845 | //Element matrix and std::vector initialisation | ||
846 | 1 | initElementArray(); | |
847 | 1 | } | |
848 | |||
849 | /***********************************************************************************/ | ||
850 | /***********************************************************************************/ | ||
851 | |||
852 | ✗ | void EigenProblem::defineCurvilinearFiniteElement(const ElementType& eltType) | |
853 | { | ||
854 | ✗ | if (m_listCurvilinearFiniteElement.size() > 0) { | |
855 | ✗ | m_listCurvilinearFiniteElement.clear(); | |
856 | ✗ | std::cout << m_Matrix.size(); | |
857 | ✗ | m_elementMatBD.clear(); | |
858 | } | ||
859 | //Initialisation of Finite Element curvlinear problem | ||
860 | const RefElement *refEle; | ||
861 | const GeoElement *geoEle; | ||
862 | ✗ | int typeOfFiniteElement = 0; | |
863 | CurvilinearFiniteElement* fe; | ||
864 | ✗ | geoEle = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second; | |
865 | ✗ | for ( std::size_t iVar = 0; iVar < m_listVariable.size(); iVar++) { | |
866 | ✗ | typeOfFiniteElement = m_listVariable[iVar].finiteElementType(); | |
867 | ✗ | refEle = geoEle->defineFiniteEle(eltType,typeOfFiniteElement, *m_meshLocal); | |
868 | ✗ | fe = new CurvilinearFiniteElement(*refEle,*geoEle,m_listVariable[iVar].degreeOfExactness()); | |
869 | ✗ | FEL_ASSERT(fe); | |
870 | ✗ | m_listCurvilinearFiniteElement.add(fe); | |
871 | } | ||
872 | //Element matrix and std::vector initialisation | ||
873 | ✗ | initElementArrayBD(); | |
874 | } | ||
875 | |||
876 | /***********************************************************************************/ | ||
877 | /***********************************************************************************/ | ||
878 | |||
879 | 8192 | void EigenProblem::setElemPoint(ElementType& eltType, felInt iel, std::vector<Point*>& elemPoint, | |
880 | std::vector<felInt>& elemIdPoint, felInt* ielSupportDof) | ||
881 | { | ||
882 | // int iVar = 0; // id of the variable. ielSupport always the same with all variable. | ||
883 | 8192 | int iUnknown = 0; | |
884 | 8192 | m_supportDofUnknownLocal[iUnknown].getIdElementSupport(eltType, iel, *ielSupportDof); | |
885 | 8192 | ISLocalToGlobalMappingApply(m_mappingElem,1,ielSupportDof,ielSupportDof); | |
886 | |||
887 | 8192 | int numPointsPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType]; | |
888 | 8192 | m_meshLocal->getOneElement(eltType,iel,elemIdPoint,0); | |
889 |
2/2✓ Branch 0 taken 24576 times.
✓ Branch 1 taken 8192 times.
|
32768 | for (int iPoint = 0; iPoint < numPointsPerElt; iPoint++) { |
890 | 24576 | elemPoint[iPoint] = &m_meshLocal->listPoints()[elemIdPoint[iPoint]]; // => m_meshLocal not const | |
891 | } | ||
892 | 8192 | } | |
893 | |||
894 | /***********************************************************************************/ | ||
895 | /***********************************************************************************/ | ||
896 | |||
897 | ✗ | void EigenProblem::setElemPoint(ElementType& eltType, felInt iel, std::vector<Point*>& elemPoint, | |
898 | std::vector<felInt>& elemIdPoint, std::vector<felInt>& vectorSupport) | ||
899 | { | ||
900 | // int iVar = 0; // id of the variable. ielSupport always the same with all variable. | ||
901 | // We assume that the support elements are the same for all the unknown. | ||
902 | ✗ | int iUnknown = 0; | |
903 | ✗ | m_supportDofUnknownLocal[iUnknown].getIdElementSupport(eltType, iel, vectorSupport); | |
904 | ✗ | ISLocalToGlobalMappingApply(m_mappingElem, vectorSupport.size(), vectorSupport.data(), vectorSupport.data()); | |
905 | ✗ | int numPointsPerElt = GeometricMeshRegion::m_numPointsPerElt[eltType]; | |
906 | ✗ | m_meshLocal->getOneElement(eltType, iel, elemIdPoint, 0); | |
907 | ✗ | for (int iPoint = 0; iPoint < numPointsPerElt; iPoint++) { | |
908 | ✗ | elemPoint[iPoint] = &m_meshLocal->listPoints()[elemIdPoint[iPoint]]; // => m_meshLocal not const | |
909 | } | ||
910 | } | ||
911 | |||
912 | /***********************************************************************************/ | ||
913 | /***********************************************************************************/ | ||
914 | |||
915 | 8192 | void EigenProblem::setValueMatrix(const felInt* ielSupportDof) | |
916 | { | ||
917 | // \todo: works (a priori) only for the square matrix | ||
918 | 8192 | const felInt numDofTotal = m_elementMat[0]->mat().size1(); | |
919 | 8192 | felInt node1 = 0; | |
920 | 8192 | felInt node2 = 0; | |
921 | 8192 | felInt cptGposLine = 0; | |
922 | 8192 | felInt cptGposLine2 = 0; | |
923 | 8192 | felInt sizeSupport = 0; | |
924 | 8192 | felInt sizeSupport2 = 0; | |
925 | 8192 | felInt cptBlock = 0; | |
926 | 8192 | int idVar = -1; | |
927 | 8192 | int idVar2 = -1; | |
928 |
2/2✓ Branch 1 taken 8192 times.
✓ Branch 2 taken 8192 times.
|
16384 | for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++) { |
929 | 8192 | idVar = m_listUnknown.idVariable(iUnknown); | |
930 | 8192 | sizeSupport = m_listCurrentFiniteElement[idVar]->numDof(); | |
931 | // Warning: in elemMat the order is e.g. ( ux, uy, p) | ||
932 | // in the matrix the order is (ux1,uy1,ux2,uy2,...,p1,p2,..) | ||
933 |
2/2✓ Branch 2 taken 8192 times.
✓ Branch 3 taken 8192 times.
|
16384 | for (std::size_t iComp = 0; iComp < m_listVariable[idVar].numComponent(); iComp++) { |
934 | 8192 | cptBlock++; | |
935 |
2/2✓ Branch 0 taken 24576 times.
✓ Branch 1 taken 8192 times.
|
32768 | for ( int iSupport = 0; iSupport < sizeSupport; iSupport++) { |
936 |
1/2✓ Branch 1 taken 24576 times.
✗ Branch 2 not taken.
|
24576 | m_dof.loc2glob(*ielSupportDof, iSupport, idVar, iComp, node1); |
937 | 24576 | m_GposLine[cptGposLine]= node1; | |
938 | 24576 | cptGposLine2 = 0; | |
939 |
2/2✓ Branch 1 taken 24576 times.
✓ Branch 2 taken 24576 times.
|
49152 | for ( std::size_t iUnknown2 = 0; iUnknown2 <m_listUnknown.size(); iUnknown2++) { |
940 | 24576 | idVar2 = m_listUnknown.idVariable(iUnknown2); | |
941 | 24576 | sizeSupport2 = m_listCurrentFiniteElement[idVar2]->numDof(); | |
942 | // order matters: comp before support to manage ( ux, uy, p) order in mat elem to (ux1,uy1,ux2,uy2,...,p1,p2,..)!!!! | ||
943 |
2/2✓ Branch 2 taken 24576 times.
✓ Branch 3 taken 24576 times.
|
49152 | for (std::size_t jComp = 0; jComp <m_listVariable[idVar2].numComponent(); jComp++) { |
944 |
2/2✓ Branch 0 taken 73728 times.
✓ Branch 1 taken 24576 times.
|
98304 | for (felInt jSupport = 0; jSupport < sizeSupport2; jSupport++) { |
945 |
1/2✓ Branch 1 taken 73728 times.
✗ Branch 2 not taken.
|
73728 | int iConnect = m_dof.getNumGlobComp( iUnknown, iComp); |
946 |
1/2✓ Branch 1 taken 73728 times.
✗ Branch 2 not taken.
|
73728 | int jConnect = m_dof.getNumGlobComp( iUnknown2, jComp); |
947 |
2/4✓ Branch 2 taken 73728 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 73728 times.
✗ Branch 5 not taken.
|
73728 | if ( m_listUnknown.mask()(iConnect, jConnect) > 0) { |
948 |
1/2✓ Branch 1 taken 73728 times.
✗ Branch 2 not taken.
|
73728 | m_dof.loc2glob(*ielSupportDof,jSupport,idVar2,jComp,node2); |
949 | 73728 | m_GposColumn[cptGposLine2] = node2; | |
950 |
2/2✓ Branch 1 taken 147456 times.
✓ Branch 2 taken 73728 times.
|
221184 | for (std::size_t i = 0; i < m_Matrix.size(); i++) { |
951 |
1/2✓ Branch 4 taken 147456 times.
✗ Branch 5 not taken.
|
147456 | m_valueMat[i][cptGposLine2 + cptGposLine*numDofTotal] = m_elementMat[i]->mat()(cptGposLine, cptGposLine2); |
952 | } | ||
953 | 73728 | cptGposLine2++; | |
954 | } | ||
955 | } | ||
956 | } | ||
957 | } | ||
958 | 24576 | cptGposLine++; | |
959 | } | ||
960 | } | ||
961 | } | ||
962 | |||
963 |
1/2✓ Branch 1 taken 8192 times.
✗ Branch 2 not taken.
|
8192 | AOApplicationToPetsc(m_ao,cptGposLine,m_GposLine); |
964 |
1/2✓ Branch 1 taken 8192 times.
✗ Branch 2 not taken.
|
8192 | AOApplicationToPetsc(m_ao,cptGposLine2,m_GposColumn); |
965 |
2/2✓ Branch 1 taken 16384 times.
✓ Branch 2 taken 8192 times.
|
24576 | for (std::size_t i = 0; i < m_Matrix.size(); i++) { |
966 |
1/2✓ Branch 3 taken 16384 times.
✗ Branch 4 not taken.
|
16384 | m_Matrix[i].setValues(numDofTotal,m_GposLine,numDofTotal,m_GposColumn,m_valueMat[i],ADD_VALUES); |
967 | } | ||
968 | 8192 | } | |
969 | |||
970 | /***********************************************************************************/ | ||
971 | /***********************************************************************************/ | ||
972 | |||
973 | 1 | void EigenProblem::allocateArrayForAssembleMatrix() | |
974 | { | ||
975 | 1 | felInt numDofTotal = 0; | |
976 | 1 | int idFE = -1; //(idFE = idVar) | |
977 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++) { |
978 | 1 | idFE = m_listUnknown.idVariable(iUnknown); | |
979 | 1 | numDofTotal += m_listCurrentFiniteElement[idFE]->numDof()*m_listVariable[idFE].numComponent(); | |
980 | } | ||
981 | |||
982 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_GposColumn == nullptr) |
983 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | m_GposColumn = new felInt[numDofTotal]; |
984 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_GposLine == nullptr) |
985 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | m_GposLine = new felInt[numDofTotal]; |
986 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
|
3 | for (std::size_t i = 0; i < m_Matrix.size(); i++) { |
987 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
2 | m_valueMat.push_back(new double[numDofTotal*numDofTotal]); |
988 | } | ||
989 | 1 | } | |
990 | |||
991 | /***********************************************************************************/ | ||
992 | /***********************************************************************************/ | ||
993 | |||
994 | ✗ | void EigenProblem::setValueMatrixBD(const felInt* ielSupportDof) | |
995 | { | ||
996 | ✗ | const felInt numDofTotal = m_elementMatBD[0]->mat().size1(); | |
997 | |||
998 | ✗ | felInt node1 = 0; | |
999 | ✗ | felInt node2 = 0; | |
1000 | ✗ | felInt cptGposLine = 0; | |
1001 | ✗ | felInt cptGposLine2 = 0; | |
1002 | ✗ | felInt sizeSupport = 0; | |
1003 | ✗ | felInt sizeSupport2 = 0; | |
1004 | ✗ | felInt cptBlock = 0; | |
1005 | ✗ | int idVar = -1; | |
1006 | ✗ | int idVar2 = -1; | |
1007 | |||
1008 | ✗ | for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++) { | |
1009 | ✗ | idVar = m_listUnknown.idVariable(iUnknown); | |
1010 | ✗ | sizeSupport = m_listCurvilinearFiniteElement[idVar]->numDof(); | |
1011 | // order matters: comp before support to manage ( ux, uy, p) order in mat elem to (ux1,uy1,ux2,uy2,...,p1,p2,..)!!!! | ||
1012 | ✗ | for (std::size_t iComp = 0; iComp < m_listVariable[idVar].numComponent(); iComp++) { | |
1013 | ✗ | cptBlock++; | |
1014 | ✗ | for ( int iSupport = 0; iSupport < sizeSupport; iSupport++) { | |
1015 | ✗ | m_dof.loc2glob(*ielSupportDof, iSupport, idVar, iComp, node1); | |
1016 | ✗ | m_GposLine[cptGposLine]= node1; | |
1017 | ✗ | cptGposLine2 = 0; | |
1018 | ✗ | for ( std::size_t iUnknown2 = 0; iUnknown2 <m_listUnknown.size(); iUnknown2++) { | |
1019 | ✗ | idVar2 = m_listUnknown.idVariable(iUnknown2); | |
1020 | ✗ | sizeSupport2 = m_listCurvilinearFiniteElement[idVar2]->numDof(); | |
1021 | // order matters: comp before support to manage ( ux, uy, p) order in mat elem to (ux1,uy1,ux2,uy2,...,p1,p2,..)!!!! | ||
1022 | ✗ | for (std::size_t jComp = 0; jComp <m_listVariable[idVar2].numComponent(); jComp++) { | |
1023 | ✗ | for ( int jSupport = 0; jSupport < sizeSupport2; jSupport++) { | |
1024 | ✗ | int iConnect = m_dof.getNumGlobComp( iUnknown, iComp); | |
1025 | ✗ | int jConnect = m_dof.getNumGlobComp( iUnknown2, jComp); | |
1026 | ✗ | if ( m_listUnknown.mask()(iConnect, jConnect) > 0) { | |
1027 | ✗ | m_dof.loc2glob(*ielSupportDof,jSupport,idVar2,jComp,node2); | |
1028 | ✗ | m_GposColumn[cptGposLine2] = node2; | |
1029 | ✗ | for (std::size_t i = 0; i < m_Matrix.size(); i++) { | |
1030 | |||
1031 | ✗ | m_valueMat[i][cptGposLine2 + cptGposLine*numDofTotal] = m_elementMatBD[i]->mat()(cptGposLine, cptGposLine2); | |
1032 | } | ||
1033 | ✗ | cptGposLine2++; | |
1034 | } | ||
1035 | } | ||
1036 | } | ||
1037 | } | ||
1038 | ✗ | cptGposLine++; | |
1039 | } | ||
1040 | } | ||
1041 | } | ||
1042 | |||
1043 | ✗ | AOApplicationToPetsc(m_ao,cptGposLine,m_GposLine); | |
1044 | ✗ | AOApplicationToPetsc(m_ao,cptGposLine2,m_GposColumn); | |
1045 | ✗ | for (std::size_t i = 0; i < m_Matrix.size(); i++) { | |
1046 | ✗ | m_Matrix[i].setValues(numDofTotal,m_GposLine,numDofTotal,m_GposColumn,m_valueMat[i],ADD_VALUES); | |
1047 | } | ||
1048 | } | ||
1049 | |||
1050 | /***********************************************************************************/ | ||
1051 | /***********************************************************************************/ | ||
1052 | |||
1053 | ✗ | void EigenProblem::allocateArrayForAssembleMatrixBD() | |
1054 | { | ||
1055 | ✗ | felInt numDofTotal = 0; | |
1056 | ✗ | for (std::size_t iFe = 0; iFe < m_listCurvilinearFiniteElement.size(); iFe++) { | |
1057 | ✗ | numDofTotal += m_listCurvilinearFiniteElement[iFe]->numDof()*m_listVariable[iFe].numComponent(); | |
1058 | } | ||
1059 | ✗ | m_GposColumn = new felInt[numDofTotal]; | |
1060 | ✗ | m_GposLine = new felInt[numDofTotal]; | |
1061 | |||
1062 | ✗ | for (std::size_t i = 0; i < m_Matrix.size(); i++) { | |
1063 | ✗ | m_valueMat.push_back(new double[numDofTotal*numDofTotal]); | |
1064 | } | ||
1065 | } | ||
1066 | |||
1067 | /***********************************************************************************/ | ||
1068 | /***********************************************************************************/ | ||
1069 | |||
1070 | 1 | void EigenProblem::desallocateArrayForAssembleMatrix() | |
1071 | { | ||
1072 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
|
3 | for (std::size_t i = 0; i < m_Matrix.size(); i++) { |
1073 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | delete [] m_valueMat[i]; |
1074 | } | ||
1075 | 1 | m_valueMat.clear(); | |
1076 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | delete [] m_GposLine; |
1077 | 1 | m_GposLine = nullptr; | |
1078 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | delete [] m_GposColumn; |
1079 | 1 | m_GposColumn = nullptr; | |
1080 | 1 | } | |
1081 | |||
1082 | /***********************************************************************************/ | ||
1083 | /***********************************************************************************/ | ||
1084 | |||
1085 | ✗ | void EigenProblem::scaleMatrix(felReal coef, int i) | |
1086 | { | ||
1087 | ✗ | m_Matrix[i].scale(coef); | |
1088 | } | ||
1089 | |||
1090 | /***********************************************************************************/ | ||
1091 | /***********************************************************************************/ | ||
1092 | |||
1093 | ✗ | void EigenProblem::scaleMatrix(felReal coef, PetscMatrix& M) | |
1094 | { | ||
1095 | ✗ | M.scale(coef); | |
1096 | } | ||
1097 | |||
1098 | /***********************************************************************************/ | ||
1099 | /***********************************************************************************/ | ||
1100 | |||
1101 | ✗ | void EigenProblem::printSolution(int verbose) const | |
1102 | { | ||
1103 | ✗ | if (verbose > 19) { | |
1104 | ✗ | PetscPrintf(m_petscComm,"\n/================Solution of the assembly system Ax=b================/\n"); | |
1105 | ✗ | m_sol.view(); | |
1106 | } | ||
1107 | } | ||
1108 | |||
1109 | /***********************************************************************************/ | ||
1110 | /***********************************************************************************/ | ||
1111 | |||
1112 | ✗ | void EigenProblem::printMatrix(PetscMatrix& M) | |
1113 | { | ||
1114 | ✗ | M.view(); | |
1115 | } | ||
1116 | |||
1117 | /***********************************************************************************/ | ||
1118 | /***********************************************************************************/ | ||
1119 | |||
1120 | ✗ | void EigenProblem::printVector(PetscVector& V) | |
1121 | { | ||
1122 | ✗ | V.view(); | |
1123 | } | ||
1124 | |||
1125 | /***********************************************************************************/ | ||
1126 | /***********************************************************************************/ | ||
1127 | |||
1128 | 1 | void EigenProblem::writeMatrixForMatlab(int verbose) const | |
1129 | { | ||
1130 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (verbose > 20) { |
1131 | ✗ | PetscPrintf(m_petscComm,"\n/===========Matrix write in Matlab file matrix.m=============/\n"); | |
1132 | PetscViewer viewer; | ||
1133 | ✗ | PetscViewerCreate(m_petscComm,&viewer); | |
1134 | ✗ | PetscViewerASCIIOpen(m_petscComm,"matrix.m",&viewer); | |
1135 | ✗ | PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB); | |
1136 | ✗ | m_Matrix[0].view(viewer); | |
1137 | } | ||
1138 | 1 | } | |
1139 | |||
1140 | /***********************************************************************************/ | ||
1141 | /***********************************************************************************/ | ||
1142 | |||
1143 | ✗ | void EigenProblem::writeMatrixForMatlab(std::string const& fileName, PetscMatrix& matrix) const | |
1144 | { | ||
1145 | ✗ | PetscPrintf(m_petscComm,"\n/===========Matrix write in Matlab file fileName=============/\n"); | |
1146 | PetscViewer viewer; | ||
1147 | ✗ | PetscViewerCreate(m_petscComm,&viewer); | |
1148 | ✗ | PetscViewerASCIIOpen(m_petscComm,fileName.c_str(),&viewer); | |
1149 | ✗ | PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB); | |
1150 | ✗ | matrix.view(viewer); | |
1151 | } | ||
1152 | |||
1153 | /***********************************************************************************/ | ||
1154 | /***********************************************************************************/ | ||
1155 | |||
1156 | ✗ | void EigenProblem::writeVectorForMatlab(std::string const& fileName, PetscVector& vector) const | |
1157 | { | ||
1158 | ✗ | PetscPrintf(m_petscComm,"\n/===========std::vector write in Matlab file std::vector.m=============/\n"); | |
1159 | PetscViewer viewer; | ||
1160 | ✗ | PetscViewerCreate(m_petscComm,&viewer); | |
1161 | ✗ | PetscViewerASCIIOpen(m_petscComm,fileName.c_str(),&viewer); | |
1162 | ✗ | PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB); | |
1163 | ✗ | vector.view(viewer); | |
1164 | } | ||
1165 | |||
1166 | /***********************************************************************************/ | ||
1167 | /***********************************************************************************/ | ||
1168 | |||
1169 | ✗ | void EigenProblem::buildSolver() | |
1170 | { | ||
1171 | #ifdef FELISCE_WITH_SLEPC | ||
1172 | ✗ | EPSSetOperators(m_eps,m_Matrix[0].toPetsc(),FELISCE_PETSC_NULLPTR); | |
1173 | ✗ | EPSSetDimensions(m_eps,1,PETSC_DECIDE,PETSC_DECIDE); | |
1174 | ✗ | EPSSetFromOptions(m_eps); | |
1175 | #endif | ||
1176 | } | ||
1177 | |||
1178 | /***********************************************************************************/ | ||
1179 | /***********************************************************************************/ | ||
1180 | |||
1181 | ✗ | void EigenProblem::buildSVD() | |
1182 | { | ||
1183 | #ifdef FELISCE_WITH_SLEPC | ||
1184 | // TODO: Replace with this when SLEPc has SVDSetOperators in all versions | ||
1185 | // SVDSetOperators(m_svd,m_Matrix[0].toPetsc(), FELISCE_PETSC_NULLPTR); | ||
1186 | #if PETSC_VERSION_LT(3, 19, 0) | ||
1187 | SVDSetOperator(m_svd,m_Matrix[0].toPetsc()); | ||
1188 | #else | ||
1189 | // TODO: Replace with this when SLEPc has SVDSetOperators in all versions | ||
1190 | ✗ | SVDSetOperators(m_svd,m_Matrix[0].toPetsc(), FELISCE_PETSC_NULLPTR); | |
1191 | #endif | ||
1192 | ✗ | SVDSetType(m_svd,SVDCROSS); | |
1193 | ✗ | SVDSetFromOptions(m_svd); | |
1194 | #endif | ||
1195 | } | ||
1196 | |||
1197 | /***********************************************************************************/ | ||
1198 | /***********************************************************************************/ | ||
1199 | |||
1200 | ✗ | void EigenProblem::solve() | |
1201 | { | ||
1202 | #ifdef FELISCE_WITH_SLEPC | ||
1203 | PetscInt nconv1; | ||
1204 | PetscInt nconv2; | ||
1205 | ✗ | PetscReal sigma_1 = 0.; | |
1206 | ✗ | PetscReal sigma_n = 0.; | |
1207 | //First request a singular value from one end of the spectrum | ||
1208 | ✗ | EPSSetWhichEigenpairs(m_eps,EPS_LARGEST_MAGNITUDE); | |
1209 | ✗ | if (m_verbose >= 10) { | |
1210 | ✗ | m_Matrix[0].view(); | |
1211 | ✗ | EPSView(m_eps,PETSC_VIEWER_STDOUT_WORLD); | |
1212 | } | ||
1213 | |||
1214 | ✗ | EPSSolve(m_eps); | |
1215 | |||
1216 | //Get number of converged singular values | ||
1217 | ✗ | EPSGetConverged(m_eps,&nconv1); | |
1218 | //Get converged singular values: largest singular value is stored in sigma_1. | ||
1219 | ✗ | if (nconv1 > 0) { | |
1220 | ✗ | EPSGetEigenpair(m_eps,0,&sigma_1,FELISCE_PETSC_NULLPTR,FELISCE_PETSC_NULLPTR,FELISCE_PETSC_NULLPTR); | |
1221 | } else { | ||
1222 | ✗ | PetscPrintf(PETSC_COMM_WORLD," Unable to compute large singular value!\n\n"); | |
1223 | } | ||
1224 | |||
1225 | //Request a singular value from the other end of the spectrum | ||
1226 | ✗ | EPSSetWhichEigenpairs(m_eps,EPS_SMALLEST_MAGNITUDE); | |
1227 | ✗ | EPSSolve(m_eps); | |
1228 | //Get number of converged eigenpairs | ||
1229 | ✗ | EPSGetConverged(m_eps,&nconv2); | |
1230 | //Get converged singular values: smallest singular value is stored in sigma_n. | ||
1231 | ✗ | if (nconv2 > 0) { | |
1232 | ✗ | EPSGetEigenpair(m_eps,0,&sigma_n,FELISCE_PETSC_NULLPTR,FELISCE_PETSC_NULLPTR,FELISCE_PETSC_NULLPTR); | |
1233 | } else { | ||
1234 | ✗ | PetscPrintf(PETSC_COMM_WORLD," Unable to compute small singular value!\n\n"); | |
1235 | } | ||
1236 | |||
1237 | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
1238 | Display solution | ||
1239 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | ||
1240 | ✗ | if (nconv1 > 0 && nconv2 > 0) { | |
1241 | ✗ | PetscPrintf(PETSC_COMM_WORLD," Computed singular values: sigma_1=%6F, sigma_n=%6F\n",sigma_1,sigma_n); | |
1242 | ✗ | PetscPrintf(PETSC_COMM_WORLD," Estimated condition number: sigma_1/sigma_n=%6F\n\n",sigma_1/sigma_n); | |
1243 | } | ||
1244 | #endif | ||
1245 | } | ||
1246 | |||
1247 | /***********************************************************************************/ | ||
1248 | /***********************************************************************************/ | ||
1249 | |||
1250 | ✗ | void EigenProblem::solveSVD() | |
1251 | { | ||
1252 | #ifdef FELISCE_WITH_SLEPC | ||
1253 | ✗ | SVDSetDimensions(m_svd,1,PETSC_DECIDE,PETSC_DECIDE); | |
1254 | PetscInt nconv1; | ||
1255 | ✗ | PetscReal sigma_1 = 0.; | |
1256 | ✗ | SVDSetWhichSingularTriplets(m_svd,SVD_LARGEST); | |
1257 | ✗ | SVDSolve(m_svd); | |
1258 | ✗ | SVDGetConverged(m_svd,&nconv1); | |
1259 | ✗ | if (nconv1 > 0) { | |
1260 | ✗ | SVDGetSingularTriplet(m_svd,0,&sigma_1,nullptr,nullptr); | |
1261 | } else { | ||
1262 | ✗ | PetscPrintf(PETSC_COMM_WORLD," Unable to compute large singular value!\n\n"); | |
1263 | } | ||
1264 | |||
1265 | PetscInt nconv2; | ||
1266 | ✗ | PetscReal sigma_n = 0.; | |
1267 | ✗ | SVDSetWhichSingularTriplets(m_svd,SVD_SMALLEST); | |
1268 | ✗ | SVDSolve(m_svd); | |
1269 | ✗ | SVDGetConverged(m_svd,&nconv2); | |
1270 | ✗ | if (nconv2 > 0) { | |
1271 | ✗ | SVDGetSingularTriplet(m_svd,0,&sigma_n,nullptr,nullptr); | |
1272 | } else { | ||
1273 | ✗ | PetscPrintf(PETSC_COMM_WORLD," Unable to compute small singular value!\n\n"); | |
1274 | } | ||
1275 | |||
1276 | #endif | ||
1277 | } | ||
1278 | |||
1279 | /***********************************************************************************/ | ||
1280 | /***********************************************************************************/ | ||
1281 | |||
1282 | 1 | void EigenProblem::clearMatrix(const int i) { | |
1283 | 1 | m_Matrix[i].setUnfactored(); | |
1284 | 1 | m_Matrix[i].zeroEntries(); | |
1285 | 1 | } | |
1286 | |||
1287 | /***********************************************************************************/ | ||
1288 | /***********************************************************************************/ | ||
1289 | |||
1290 | 1 | void EigenProblem::gatherSolution() { | |
1291 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | PetscVector vout; |
1292 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_sol.scatterToAll(vout,INSERT_VALUES,SCATTER_FORWARD); |
1293 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_seqSol.copyFrom(vout); |
1294 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | vout.destroy(); |
1295 | 1 | } | |
1296 | |||
1297 | /***********************************************************************************/ | ||
1298 | /***********************************************************************************/ | ||
1299 | |||
1300 | 175 | void EigenProblem::fromVecToDoubleStar(double* solution, PetscVector& sol, int rank, int dimension, felInt size) { | |
1301 | IGNORE_UNUSED_ARGUMENT(dimension); | ||
1302 | |||
1303 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 175 times.
|
175 | if (FelisceParam::verbose() >= 40 ) |
1304 | ✗ | sol.view(); | |
1305 | felInt sizeVec; | ||
1306 |
1/2✓ Branch 1 taken 175 times.
✗ Branch 2 not taken.
|
175 | sol.getSize(&sizeVec); |
1307 | |||
1308 | // Check if the demanded double* output has the same dimension of the input Vec | ||
1309 |
1/2✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
|
175 | if (size == 0) |
1310 | 175 | size = sizeVec; | |
1311 | |||
1312 |
1/2✓ Branch 1 taken 175 times.
✗ Branch 2 not taken.
|
175 | PetscVector xsol; |
1313 |
1/2✓ Branch 1 taken 175 times.
✗ Branch 2 not taken.
|
175 | sol.scatterToZero(xsol, INSERT_VALUES, SCATTER_FORWARD); |
1314 | |||
1315 | 175 | felInt iout[size]; | |
1316 |
2/2✓ Branch 0 taken 739375 times.
✓ Branch 1 taken 175 times.
|
739550 | for (felInt i=0; i<size; i++) |
1317 | 739375 | iout[i] = i; | |
1318 | |||
1319 |
1/2✓ Branch 1 taken 175 times.
✗ Branch 2 not taken.
|
175 | AOApplicationToPetsc(m_ao, size, iout); |
1320 | |||
1321 |
1/2✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
|
175 | if(rank == 0) { |
1322 |
1/2✓ Branch 1 taken 175 times.
✗ Branch 2 not taken.
|
175 | xsol.getValues( size, iout, solution); |
1323 | } | ||
1324 |
1/2✓ Branch 1 taken 175 times.
✗ Branch 2 not taken.
|
175 | xsol.destroy(); |
1325 |
1/2✓ Branch 1 taken 175 times.
✗ Branch 2 not taken.
|
350 | } |
1326 | |||
1327 | /***********************************************************************************/ | ||
1328 | /***********************************************************************************/ | ||
1329 | |||
1330 | ✗ | void EigenProblem::fromDoubleStarToVec(double* solution, PetscVector& sol, felInt size) { | |
1331 | felInt ia; | ||
1332 | ✗ | for (felInt i=0; i< size; i++) { | |
1333 | ✗ | ia = i; | |
1334 | ✗ | AOApplicationToPetsc(m_ao,1,&ia); | |
1335 | ✗ | sol.setValues(1,&ia,&solution[i],INSERT_VALUES); | |
1336 | } | ||
1337 | |||
1338 | ✗ | sol.assembly(); | |
1339 | |||
1340 | ✗ | if (FelisceParam::verbose() >= 40 ) | |
1341 | ✗ | sol.view(); | |
1342 | } | ||
1343 | |||
1344 | /***********************************************************************************/ | ||
1345 | /***********************************************************************************/ | ||
1346 | |||
1347 | ✗ | void EigenProblem::writeSolution(int rank, IO& io, double& time, int iteration) | |
1348 | { | ||
1349 | // to be sure that m_seqSol is up to date | ||
1350 | ✗ | gatherSolution(); | |
1351 | |||
1352 | ✗ | felInt iout[m_numDof]; | |
1353 | ✗ | felReal valueVec[m_numDof]; | |
1354 | ✗ | for (felInt i=0; i<m_numDof; i++) | |
1355 | ✗ | iout[i] = i; | |
1356 | ✗ | AOApplicationToPetsc(m_ao,m_numDof,iout); | |
1357 | ✗ | m_seqSol.getValues(m_numDof,iout,valueVec); | |
1358 | |||
1359 | ✗ | int idVar = -1; | |
1360 | ✗ | int idVar2 = -1; | |
1361 | // Write solution in ensight format | ||
1362 | ✗ | if ( rank == 0) { | |
1363 | double* solution; | ||
1364 | ✗ | for ( std::size_t iUnknown = 0; iUnknown < m_listUnknown.size(); iUnknown++) { | |
1365 | ✗ | felInt numValueStart = 0; | |
1366 | ✗ | idVar = m_listUnknown.idVariable(iUnknown); | |
1367 | ✗ | for ( std::size_t iUnknown2 = 0; iUnknown2 < iUnknown; iUnknown2++) { | |
1368 | ✗ | idVar2 = m_listUnknown.idVariable(iUnknown2); | |
1369 | ✗ | numValueStart += m_supportDofUnknown[iUnknown2].listNode().size()*m_listVariable[idVar2].numComponent(); | |
1370 | } | ||
1371 | ✗ | switch (m_listVariable[idVar].numComponent()) { | |
1372 | ✗ | case 1: | |
1373 | ✗ | solution = new double[m_supportDofUnknown[iUnknown].listNode().size()]; | |
1374 | ✗ | for (felInt i = 0; i < static_cast<felInt>(m_supportDofUnknown[iUnknown].listNode().size()); i++) { | |
1375 | ✗ | solution[i] = valueVec[i+numValueStart]; | |
1376 | } | ||
1377 | ✗ | io.writeSolution(rank, time, iteration, 0, m_listVariable[idVar].name(), solution, m_supportDofUnknown[iUnknown].listNode().size(), m_mesh->domainDim(),true); | |
1378 | ✗ | break; | |
1379 | ✗ | case 2: | |
1380 | ✗ | solution = new double[m_supportDofUnknown[iUnknown].listNode().size()*3]; | |
1381 | ✗ | for (felInt i = 0; i < static_cast<felInt>(m_supportDofUnknown[iUnknown].listNode().size()); i++) { | |
1382 | ✗ | solution[i*3] = valueVec[i*2+numValueStart]; | |
1383 | ✗ | solution[i*3+1] = valueVec[i*2+1+numValueStart]; | |
1384 | ✗ | solution[i*3+2] = 0.; | |
1385 | } | ||
1386 | ✗ | io.writeSolution(rank, time, iteration, 1, m_listVariable[idVar].name(), solution, m_supportDofUnknown[iUnknown].listNode().size(), m_mesh->domainDim(),true); | |
1387 | ✗ | break; | |
1388 | ✗ | case 3: | |
1389 | ✗ | solution = new double[m_supportDofUnknown[iUnknown].listNode().size()*3]; | |
1390 | ✗ | for (felInt i = 0; i < static_cast<felInt>(m_supportDofUnknown[iUnknown].listNode().size()); i++) { | |
1391 | ✗ | solution[i*3] = valueVec[i*3+numValueStart]; | |
1392 | ✗ | solution[i*3+1] = valueVec[i*3+1+numValueStart]; | |
1393 | ✗ | solution[i*3+2] = valueVec[i*3+2+numValueStart]; | |
1394 | } | ||
1395 | ✗ | io.writeSolution(rank, time, iteration, 1, m_listVariable[idVar].name(), solution, m_supportDofUnknown[iUnknown].listNode().size(), m_mesh->domainDim(),true); | |
1396 | ✗ | break; | |
1397 | ✗ | default: | |
1398 | ✗ | FEL_ERROR("Problem with the dimension of your solution to write it.") | |
1399 | ✗ | break; | |
1400 | } | ||
1401 | //delete [] solution; | ||
1402 | } | ||
1403 | } | ||
1404 | } | ||
1405 | |||
1406 | /***********************************************************************************/ | ||
1407 | /***********************************************************************************/ | ||
1408 | |||
1409 | 175 | void EigenProblem::writeEnsightVector(double* solValue, int idIter, | |
1410 | std::string varName) | ||
1411 | { | ||
1412 | int rankProc; | ||
1413 |
1/2✓ Branch 1 taken 175 times.
✗ Branch 2 not taken.
|
175 | MPI_Comm_rank(m_petscComm,&rankProc); |
1414 | |||
1415 | 175 | std::string iteration; | |
1416 |
2/2✓ Branch 0 taken 70 times.
✓ Branch 1 taken 105 times.
|
175 | if (idIter < 10) |
1417 |
2/4✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 70 times.
✗ Branch 5 not taken.
|
70 | iteration = "0000" + std::to_string(idIter); |
1418 |
1/2✓ Branch 0 taken 105 times.
✗ Branch 1 not taken.
|
105 | else if (idIter < 100) |
1419 |
2/4✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 105 times.
✗ Branch 5 not taken.
|
105 | iteration = "000" + std::to_string(idIter); |
1420 | ✗ | else if (idIter < 1000) | |
1421 | ✗ | iteration = "00" + std::to_string(idIter); | |
1422 | ✗ | else if (idIter < 10000) | |
1423 | ✗ | iteration = "0" + std::to_string(idIter); | |
1424 | ✗ | else if (idIter < 100000) | |
1425 | ✗ | iteration = std::to_string(idIter); | |
1426 | |||
1427 |
6/12✓ Branch 1 taken 175 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 175 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 175 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 175 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 175 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 175 times.
✗ Branch 17 not taken.
|
350 | std::string fileName = FelisceParam::instance().resultDir + "/" + varName + "." + iteration + ".scl"; |
1428 | FILE * solFile; | ||
1429 |
1/2✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
|
175 | if (rankProc == 0) { |
1430 |
1/2✓ Branch 2 taken 175 times.
✗ Branch 3 not taken.
|
175 | solFile = fopen(fileName.c_str(),"w"); |
1431 |
1/2✓ Branch 1 taken 175 times.
✗ Branch 2 not taken.
|
175 | fprintf(solFile, "Scalar per node\n"); |
1432 | 175 | int count = 0; | |
1433 |
2/2✓ Branch 0 taken 739375 times.
✓ Branch 1 taken 175 times.
|
739550 | for(int j=0; j < m_numDof; j++) { |
1434 |
1/2✓ Branch 1 taken 739375 times.
✗ Branch 2 not taken.
|
739375 | fprintf(solFile,"%12.5e", solValue[j]); |
1435 | 739375 | count++; | |
1436 |
2/2✓ Branch 0 taken 123200 times.
✓ Branch 1 taken 616175 times.
|
739375 | if(count == 6) { |
1437 |
1/2✓ Branch 1 taken 123200 times.
✗ Branch 2 not taken.
|
123200 | fprintf(solFile,"\n"); |
1438 | 123200 | count = 0; | |
1439 | } | ||
1440 | } | ||
1441 |
1/2✓ Branch 1 taken 175 times.
✗ Branch 2 not taken.
|
175 | fprintf(solFile,"\n"); |
1442 |
1/2✓ Branch 1 taken 175 times.
✗ Branch 2 not taken.
|
175 | fclose(solFile); |
1443 | } | ||
1444 | 175 | } | |
1445 | |||
1446 | /***********************************************************************************/ | ||
1447 | /***********************************************************************************/ | ||
1448 | |||
1449 | 1 | void EigenProblem::writeEnsightCase(const int numIt, | |
1450 | const double dt, std::string varName, double time0) | ||
1451 | { | ||
1452 | FILE * pFile; | ||
1453 |
4/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
|
2 | std::string caseName = FelisceParam::instance().resultDir + "/" + varName + ".case"; |
1454 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | pFile = fopen(caseName.c_str(),"w"); |
1455 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile,"FORMAT\n"); |
1456 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile,"type: ensight\n"); |
1457 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "GEOMETRY\n"); |
1458 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
|
1 | std::string nameGeo = "model: 1 " + FelisceParam::instance().outputMesh[0] + "\n"; |
1459 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | fprintf(pFile,"%s", nameGeo.c_str()); |
1460 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "VARIABLE\n"); |
1461 |
4/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
|
2 | std::string secName = "scalar per node: 1 " + varName + " " + varName +".*****.scl\n"; |
1462 | |||
1463 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | fprintf(pFile, "%s", secName.c_str()); |
1464 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "TIME\n"); |
1465 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "time std::set: %d \n", 1); |
1466 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "number of steps: %d \n", numIt); |
1467 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "filename start number: %d\n", 0); |
1468 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "filename increment: %d\n", 1); |
1469 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "time values:\n"); |
1470 | |||
1471 | 1 | int count=0; | |
1472 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
|
26 | for(int j=0; j < numIt; j++) { |
1473 | 25 | double valT = time0 + j*dt; | |
1474 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | fprintf(pFile,"%lf ",valT); |
1475 | 25 | count++; | |
1476 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 21 times.
|
25 | if(count == 6) { |
1477 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | fprintf(pFile,"\n"); |
1478 | 4 | count=0; | |
1479 | } | ||
1480 | } | ||
1481 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fclose(pFile); |
1482 | 1 | } | |
1483 | |||
1484 | /***********************************************************************************/ | ||
1485 | /***********************************************************************************/ | ||
1486 | |||
1487 | 1 | void EigenProblem::writeEnsightCase(const int numIt, | |
1488 | const double dt, | ||
1489 | std::vector<std::string> varName, | ||
1490 | double time0) | ||
1491 | { | ||
1492 | FILE * pFile; | ||
1493 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | std::string caseName = FelisceParam::instance().resultDir + "/" |
1494 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
3 | + varName[0] + ".case"; |
1495 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | pFile = fopen(caseName.c_str(),"w"); |
1496 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile,"FORMAT\n"); |
1497 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile,"type: ensight\n"); |
1498 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "GEOMETRY\n"); |
1499 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
|
1 | std::string nameGeo = "model: 1 " + FelisceParam::instance().outputMesh[0] + "\n"; |
1500 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | fprintf(pFile,"%s", nameGeo.c_str()); |
1501 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "VARIABLE\n"); |
1502 | |||
1503 | 1 | std::string secName; | |
1504 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1 times.
|
7 | for (std::size_t i=0; i<varName.size(); i++) { |
1505 |
4/8✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 13 not taken.
|
6 | secName = "scalar per node: 1 " + varName[i] + " " + varName[i] +".*****.scl\n"; |
1506 |
1/2✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
|
6 | fprintf(pFile, "%s", secName.c_str()); |
1507 | } | ||
1508 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "TIME\n"); |
1509 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "time std::set: %d \n", 1); |
1510 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "number of steps: %d \n", numIt); |
1511 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "filename start number: %d\n", 0); |
1512 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "filename increment: %d\n", 1); |
1513 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fprintf(pFile, "time values:\n"); |
1514 | |||
1515 | 1 | int count=0; | |
1516 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
|
26 | for(int j=0; j < numIt; j++) { |
1517 | 25 | double valT = time0 + j*dt; | |
1518 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | fprintf(pFile,"%lf ",valT); |
1519 | 25 | count++; | |
1520 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 21 times.
|
25 | if(count == 6) { |
1521 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | fprintf(pFile,"\n"); |
1522 | 4 | count=0; | |
1523 | } | ||
1524 | } | ||
1525 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fclose(pFile); |
1526 | 1 | } | |
1527 | |||
1528 | /***********************************************************************************/ | ||
1529 | /***********************************************************************************/ | ||
1530 | |||
1531 | ✗ | void EigenProblem::writeGeoForUnknown(int iUnknown) | |
1532 | { | ||
1533 | // Intialization | ||
1534 | // ============= | ||
1535 | ✗ | std::string fileNameGeo, fileNameRoot, fileName; | |
1536 | ElementType eltType; | ||
1537 | ✗ | Ensight ens(FelisceParam::instance().inputDirectory,FelisceParam::instance().inputFile,FelisceParam::instance().inputMesh[0],FelisceParam::instance().outputMesh[0],FelisceParam::instance().meshDir,FelisceParam::instance().resultDir); | |
1538 | ✗ | std::string keyWord; | |
1539 | int the_ref; | ||
1540 | ✗ | short verbose = 0; | |
1541 | FILE * pFile; | ||
1542 | // int nVpEl = 0; | ||
1543 | // felInt startindex = 0; | ||
1544 | ✗ | felInt numElemsPerRef = 0; | |
1545 | ✗ | felInt ielSupportDof = 0; | |
1546 | ✗ | std::vector<felInt> elem; | |
1547 | felInt numElement[ GeometricMeshRegion::m_numTypesOfElement ]; | ||
1548 | ✗ | for (int ityp=0; ityp<GeometricMeshRegion::m_numTypesOfElement; ityp++ ) { | |
1549 | ✗ | eltType = (ElementType)ityp; | |
1550 | ✗ | numElement[eltType] = 0; | |
1551 | } | ||
1552 | ✗ | const int idVar = m_listUnknown.idVariable(iUnknown); | |
1553 | ✗ | fileNameGeo = listVariable().listVariable()[idVar].name()+".geo"; | |
1554 | ✗ | fileNameRoot = FelisceParam::instance().resultDir; | |
1555 | ✗ | fileName = fileNameRoot + fileNameGeo; | |
1556 | ✗ | if (verbose>0) std::cout << "Writing file "<< fileName << std::endl; | |
1557 | |||
1558 | ✗ | pFile = fopen (fileName.c_str(),"w"); | |
1559 | ✗ | if (pFile==nullptr) { | |
1560 | ✗ | std::string command = "mkdir -p " + FelisceParam::instance().resultDir; | |
1561 | ✗ | int ierr = system(command.c_str()); | |
1562 | ✗ | if (ierr>0) { | |
1563 | ✗ | FEL_ERROR("Impossible to write "+fileName+" geo mesh"); | |
1564 | } | ||
1565 | ✗ | pFile = fopen (fileName.c_str(),"w"); | |
1566 | } | ||
1567 | //! Descriptions lines (All Geometry files must contain these first six lines) | ||
1568 | ✗ | fprintf(pFile,"Geometry file\n"); | |
1569 | ✗ | fprintf(pFile,"Geometry file\n"); | |
1570 | ✗ | fprintf(pFile,"node id assign\n"); | |
1571 | ✗ | fprintf(pFile,"element id assign\n"); | |
1572 | ✗ | fprintf(pFile,"coordinates\n"); | |
1573 | ✗ | fprintf(pFile,"%8d\n",(int)m_supportDofUnknown[iUnknown].listNode().size()); | |
1574 | |||
1575 | //! write the vertices | ||
1576 | ✗ | if ( m_mesh->numCoor() == 3 ) { | |
1577 | ✗ | for(felInt iv=0; iv< static_cast<felInt>(m_supportDofUnknown[iUnknown].listNode().size()); iv++) { | |
1578 | ✗ | fprintf( pFile,"%12.5e%12.5e%12.5e\n", m_supportDofUnknown[iUnknown].listNode()[iv].x(), | |
1579 | ✗ | m_supportDofUnknown[iUnknown].listNode()[iv].y(),m_supportDofUnknown[iUnknown].listNode()[iv].z() ); | |
1580 | } | ||
1581 | ✗ | } else if ( m_mesh->numCoor() == 2 ) { | |
1582 | ✗ | double zcoor = 0.; | |
1583 | ✗ | for(felInt iv=0; iv< static_cast<felInt>(m_supportDofUnknown[iUnknown].listNode().size()); iv++) { | |
1584 | ✗ | fprintf( pFile, "%12.5e%12.5e%12.5e\n", m_supportDofUnknown[iUnknown].listNode()[iv].x(), m_supportDofUnknown[iUnknown].listNode()[iv].y(), zcoor); | |
1585 | } | ||
1586 | } else { | ||
1587 | ✗ | std::ostringstream msg; | |
1588 | msg << "Error in writing geo File " << fileNameGeo << ". " | ||
1589 | ✗ | << "Expecting mesh with 2 or 3 coordinates (it is " << m_mesh->numCoor() << ")." | |
1590 | ✗ | << std::endl; | |
1591 | ✗ | FEL_ERROR(msg.str()); | |
1592 | } | ||
1593 | |||
1594 | //!write the elements per references. | ||
1595 | //------------ | ||
1596 | ✗ | felInt cptpart = 0; | |
1597 | ✗ | std::string DescriptionLine,felName; | |
1598 | ✗ | GeometricMeshRegion::IntRefToElementType_type& intRefToEnum = m_mesh->intRefToEnum(); | |
1599 | ✗ | for(auto it_ref = intRefToEnum.begin(); | |
1600 | ✗ | it_ref != intRefToEnum.end(); ++it_ref) { | |
1601 | ✗ | the_ref = (*it_ref).first; | |
1602 | |||
1603 | ✗ | for(auto it_elem = it_ref->second.begin(); | |
1604 | ✗ | it_elem != it_ref->second.end(); ++it_elem) { | |
1605 | ✗ | eltType = *it_elem; | |
1606 | ✗ | if (m_mesh->flagFormatMesh() == GeometricMeshRegion::FormatMedit) { | |
1607 | ✗ | cptpart++; | |
1608 | ✗ | fprintf ( pFile, "part%8d\n",cptpart ); | |
1609 | ✗ | if ( m_listVariable[idVar].finiteElementType() == 0 ) | |
1610 | ✗ | felName = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].first; | |
1611 | ✗ | else if ( m_listVariable[idVar].finiteElementType() == 1 ) | |
1612 | ✗ | felName = GeometricMeshRegion::eltEnumToFelNameGeoEle[GeometricMeshRegion::eltLinearToEltQuad[eltType]].first; | |
1613 | else { | ||
1614 | ✗ | if(m_mesh->domainDim() == GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].second->numCoor()) | |
1615 | ✗ | felName = GeometricMeshRegion::eltEnumToFelNameGeoEle[GeometricMeshRegion::eltLinearToEltBubble[eltType]].first; | |
1616 | else | ||
1617 | ✗ | felName = GeometricMeshRegion::eltEnumToFelNameGeoEle[eltType].first; | |
1618 | } | ||
1619 | |||
1620 | ✗ | auto it_felName = FelisceParam::instance().felName2MapintRef2DescLine.find(felName); | |
1621 | ✗ | if ( it_felName == FelisceParam::instance().felName2MapintRef2DescLine.end() ) { | |
1622 | //std::cout << "Warning: ----------->trying to access an unexisting element: " << felName << " in input file !!!!!!!" << std::endl; | ||
1623 | ✗ | DescriptionLine = felName + "m_ref_" + std::to_string(the_ref); | |
1624 | } else { | ||
1625 | ✗ | auto it_ref2 = it_felName->second.find(the_ref); | |
1626 | ✗ | if ( it_ref2 == it_felName->second.end() ) { | |
1627 | /*std::cout << "Warning: trying to access an unexisting reference: " << the_ref << "for element : " | ||
1628 | << felName << " in input file !!!!! " << std::endl << std::flush;*/ | ||
1629 | ✗ | DescriptionLine = felName + "m_ref_" + std::to_string(the_ref); | |
1630 | } else { | ||
1631 | ✗ | DescriptionLine = it_ref2->second; | |
1632 | } | ||
1633 | } | ||
1634 | ✗ | fprintf (pFile, "%s", DescriptionLine.c_str() ); | |
1635 | } | ||
1636 | ✗ | fprintf(pFile,"\n"); | |
1637 | ✗ | keyWord = ens.eltFelNameToEns6Pair()[felName].second; | |
1638 | ✗ | fprintf( pFile, "%s", keyWord.c_str() ); | |
1639 | ✗ | fprintf(pFile,"\n"); | |
1640 | ✗ | numElemsPerRef =m_mesh->intRefToBegEndMaps[eltType][the_ref].second; | |
1641 | // startindex =m_mesh->intRefToBegEndMaps[eltType][the_ref].first; | ||
1642 | ✗ | fprintf(pFile,"%8d\n", numElemsPerRef); | |
1643 | // nVpEl = GeometricMeshRegion::m_numPointsPerElt[eltType]; | ||
1644 | ✗ | for ( felInt iel = 0; iel < numElemsPerRef; iel++) { | |
1645 | ✗ | m_supportDofUnknown[iUnknown].getIdElementSupport(eltType, numElement[eltType], ielSupportDof); | |
1646 | ✗ | elem.resize(m_supportDofUnknown[iUnknown].getNumSupportDof(ielSupportDof),0); | |
1647 | ✗ | for ( int iSupport = 0; iSupport < m_supportDofUnknown[iUnknown].getNumSupportDof(ielSupportDof); iSupport++) { | |
1648 | ✗ | elem[iSupport] = m_supportDofUnknown[iUnknown].iSupportDof()[ m_supportDofUnknown[iUnknown].iEle()[ielSupportDof] + iSupport]; | |
1649 | } | ||
1650 | ✗ | for (std::size_t ivert = 0; ivert < elem.size(); ivert++) { | |
1651 | ✗ | fprintf( pFile, "%8d", elem[ivert]+1); | |
1652 | } | ||
1653 | ✗ | fprintf(pFile,"\n"); | |
1654 | ✗ | numElement[eltType]++; | |
1655 | } | ||
1656 | } | ||
1657 | } | ||
1658 | ✗ | fclose(pFile); | |
1659 | } | ||
1660 | |||
1661 | /***********************************************************************************/ | ||
1662 | /***********************************************************************************/ | ||
1663 | |||
1664 | ✗ | void EigenProblem::findCoordinateWithIdDof(felInt i, Point& pt) | |
1665 | { | ||
1666 | ✗ | felInt inf = 0; | |
1667 | ✗ | felInt sup = 0; | |
1668 | ✗ | int idUnknown = -1; | |
1669 | ✗ | int idVar = -1; | |
1670 | ✗ | bool findUnknown = false; | |
1671 | ✗ | for (std::size_t iUnknown = 0; iUnknown < m_listUnknown.size() && findUnknown == false; iUnknown++) { | |
1672 | ✗ | if (iUnknown == 0) { | |
1673 | ✗ | inf = 0; | |
1674 | ✗ | sup = m_numDofUnknown[iUnknown]; | |
1675 | } else { | ||
1676 | ✗ | inf += m_numDofUnknown[iUnknown-1]; | |
1677 | ✗ | if (iUnknown == m_listUnknown.size()-1) | |
1678 | ✗ | sup = m_numDof; | |
1679 | else | ||
1680 | ✗ | sup += m_numDofUnknown[iUnknown]; | |
1681 | } | ||
1682 | |||
1683 | ✗ | if (inf <= i && i < sup) { | |
1684 | ✗ | idUnknown = iUnknown; | |
1685 | ✗ | findUnknown = true; | |
1686 | } | ||
1687 | } | ||
1688 | ✗ | const felInt idDofPerUnknown = i - inf; | |
1689 | ✗ | felInt idSupportDof = -1; | |
1690 | ✗ | idVar = m_listUnknown.idVariable(idUnknown); | |
1691 | ✗ | idSupportDof = idDofPerUnknown/m_listVariable[idVar].numComponent(); | |
1692 | ✗ | pt = m_supportDofUnknown[idUnknown].listNode()[idSupportDof]; | |
1693 | } | ||
1694 | |||
1695 | } | ||
1696 |