Directory: | ./ |
---|---|
File: | Solver/eigenProblemALP.cpp |
Date: | 2024-04-14 07:32:34 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 334 | 1961 | 17.0% |
Branches: | 292 | 3241 | 9.0% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | // ______ ______ _ _ _____ ______ | ||
2 | // | ____| ____| | (_)/ ____| | ____| | ||
3 | // | |__ | |__ | | _| (___ ___| |__ | ||
4 | // | __| | __| | | | |\___ \ / __| __| | ||
5 | // | | | |____| |____| |____) | (__| |____ | ||
6 | // |_| |______|______|_|_____/ \___|______| | ||
7 | // Finite Elements for Life Sciences and Engineering | ||
8 | // | ||
9 | // License: LGL2.1 License | ||
10 | // FELiScE default license: LICENSE in root folder | ||
11 | // | ||
12 | // Main authors: E. Schenone | ||
13 | // | ||
14 | |||
15 | // System includes | ||
16 | |||
17 | // External includes | ||
18 | |||
19 | // Project includes | ||
20 | #include "Solver/eigenProblemALP.hpp" | ||
21 | #include "FiniteElement/elementMatrix.hpp" | ||
22 | #include "FiniteElement/elementField.hpp" | ||
23 | #include "Core/felisceParam.hpp" | ||
24 | #include "Core/felisceTools.hpp" | ||
25 | |||
26 | namespace felisce | ||
27 | { | ||
28 | /*! Construtor | ||
29 | */ | ||
30 | 1 | EigenProblemALP::EigenProblemALP(): | |
31 |
14/28✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 35 taken 1 times.
✗ Branch 36 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 39 not taken.
✓ Branch 41 taken 1 times.
✗ Branch 42 not taken.
✓ Branch 44 taken 1 times.
✗ Branch 45 not taken.
|
1 | EigenProblem() |
32 | 1 | {} | |
33 | |||
34 | 2 | EigenProblemALP::~EigenProblemALP() { | |
35 | 2 | m_fePotTransMemb = nullptr; | |
36 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
2 | delete [] m_eigenValue; |
37 |
3/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
2 | if ( (FelisceParam::instance().ROMmethod == "ALP") || (FelisceParam::instance().solveEigenProblem) ) { |
38 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
|
52 | for (int i=0; i<m_dimRomBasis; i++) { |
39 | 50 | m_basis[i].destroy(); | |
40 | } | ||
41 | } | ||
42 |
2/6✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
2 | if ( (m_useImprovedRec) && (FelisceParam::instance().ROMmethod == "ALP") ) { |
43 | ✗ | for (int i=0; i<m_dimOrthComp; i++) { | |
44 | ✗ | m_orthComp[i].destroy(); | |
45 | } | ||
46 | } | ||
47 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
2 | if (m_matrixM) { |
48 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
49 | ✗ | delete [] m_matrixM[i]; | |
50 | } | ||
51 | ✗ | delete [] m_matrixM; | |
52 | } | ||
53 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
2 | if (m_zeta.size()) { |
54 | ✗ | for (int i=0; i<m_size2; i++) { | |
55 | ✗ | m_zeta[i].destroy(); | |
56 | } | ||
57 | } | ||
58 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
2 | if (m_tensorB) delete [] m_tensorB; |
59 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
2 | if (m_tensorE) delete [] m_tensorE; |
60 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
2 | if (m_tensorEs) delete [] m_tensorEs; |
61 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
2 | if (m_tensorQ) delete [] m_tensorQ; |
62 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
2 | if (m_tensorT) delete [] m_tensorT; |
63 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
2 | if (m_tensorTs) delete [] m_tensorTs; |
64 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
2 | if (m_tensorU) { |
65 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
66 | ✗ | delete [] m_tensorU[i]; | |
67 | } | ||
68 | ✗ | delete [] m_tensorU; | |
69 | } | ||
70 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
2 | if (m_tensorY) delete [] m_tensorY; |
71 | 2 | m_U_0.destroy(); | |
72 | 2 | m_U_0_seq.destroy(); | |
73 | 2 | m_W_0.destroy(); | |
74 | 2 | m_W_0_seq.destroy(); | |
75 | 2 | m_Ue_0.destroy(); | |
76 | 2 | m_Ue_0_seq.destroy(); | |
77 |
2/6✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
|
2 | if ( (FelisceParam::instance().hasInfarct) && (FelisceParam::instance().ROMmethod == "ALP") ) { |
78 | ✗ | m_FhNf0.destroy(); | |
79 | } | ||
80 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
2 | if (m_solutionInitialized) { |
81 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
2 | delete [] m_beta; |
82 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | if (m_mu) delete [] m_mu; |
83 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | if (m_xi) delete [] m_xi; |
84 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
2 | if (m_gamma) delete [] m_gamma; |
85 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
2 | if (m_eta) delete [] m_eta; |
86 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
2 | if (m_method == 4) { |
87 | ✗ | delete [] m_beta_n_1; | |
88 | ✗ | delete [] m_mu_n_1; | |
89 | ✗ | delete [] m_xi_n_1; | |
90 | ✗ | delete [] m_gamma_extrap; | |
91 | ✗ | delete [] m_eta_extrap; | |
92 | } | ||
93 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
2 | if (FelisceParam::instance().hasSource) { |
94 | ✗ | for (int i=0; i<m_numSource; i++) { | |
95 | ✗ | delete [] m_source[i]; | |
96 | } | ||
97 | ✗ | delete [] m_source; | |
98 | } | ||
99 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
2 | delete [] m_modeMean; |
100 | } | ||
101 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
2 | if (m_fiber) { |
102 | ✗ | delete [] m_fiber; | |
103 | } | ||
104 | |||
105 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
2 | if (FelisceParam::instance().optimizePotential) { |
106 | ✗ | m_initPot.destroy(); | |
107 | } | ||
108 | |||
109 |
3/10✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
|
2 | if ( (m_method != 0 ) && (m_method != -1 ) && (!FelisceParam::instance().solveEigenProblem) && (FelisceParam::instance().ROMmethod == "ALP")) { |
110 | ✗ | m_solutionRom.destroy(); | |
111 | ✗ | m_rhsRom.destroy(); | |
112 | } | ||
113 | |||
114 | } | ||
115 | |||
116 | 1 | void EigenProblemALP::initialize(const GeometricMeshRegion::Pointer& mesh, FelisceTransient::Pointer fstransient, MPI_Comm& comm) { | |
117 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | EigenProblem::initialize(mesh, fstransient, comm); |
118 | |||
119 | 1 | std::unordered_map<std::string, int> mapOfPbm; | |
120 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | mapOfPbm["FKPP"] = 0; |
121 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | mapOfPbm["Monodomain"] = 1; |
122 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | mapOfPbm["Bidomain"] = 2; |
123 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | mapOfPbm["BidomainCurv"] = 2; |
124 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | m_problem = mapOfPbm[FelisceParam::instance().model]; |
125 | |||
126 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_dimRomBasis = FelisceParam::instance().dimRomBasis; |
127 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_useImprovedRec = FelisceParam::instance().useImprovedRec; |
128 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_dimOrthComp = FelisceParam::instance().dimOrthComp; |
129 | |||
130 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_tensorOrder = FelisceParam::instance().orderALP; |
131 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_numSource = FelisceParam::instance().numberOfSource; |
132 | |||
133 | 1 | int id=0; | |
134 | 1 | m_idL = id; | |
135 | 1 | id++; | |
136 | 1 | m_idG = id; | |
137 | 1 | id++; | |
138 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
|
1 | if (!FelisceParam::instance().solveEigenProblem) { |
139 | ✗ | m_idGs = id; | |
140 | ✗ | id++; | |
141 | ✗ | if (FelisceParam::instance().model == "Monodomain") { | |
142 | ✗ | if (m_tensorOrder == 3 ) { | |
143 | ✗ | m_idK = id; | |
144 | ✗ | id++; | |
145 | ✗ | m_idKs = id; | |
146 | ✗ | id++; | |
147 | } | ||
148 | ✗ | } else if ( (FelisceParam::instance().model == "Bidomain") || (FelisceParam::instance().model == "BidomainCurv") ) { | |
149 | ✗ | m_idK = id; | |
150 | ✗ | id++; | |
151 | ✗ | m_idKie = id; | |
152 | ✗ | id++; | |
153 | ✗ | if (m_tensorOrder == 3 ) { | |
154 | ✗ | m_idKs = id; | |
155 | ✗ | id++; | |
156 | } | ||
157 | } | ||
158 | |||
159 | ✗ | if ( (m_useImprovedRec) & (m_idK == 0) ) { | |
160 | ✗ | m_idK = id; | |
161 | ✗ | id++; | |
162 | } | ||
163 | } | ||
164 | 1 | m_numberOfMatrix = id; | |
165 | |||
166 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_coefChi = FelisceParam::instance().chiSchrodinger; |
167 | 1 | std::vector<PhysicalVariable> listVariable; | |
168 | 1 | std::vector<std::size_t> listNumComp; | |
169 |
1/4✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | switch (m_problem) { |
170 | ✗ | case 0: { | |
171 | ✗ | nameOfTheProblem = "Problem Fisher-Kolmogorov-Petrovski-Piskunov equation (FKPP)"; | |
172 | ✗ | listVariable.push_back(potTransMemb); | |
173 | ✗ | listNumComp.push_back(1); | |
174 | //define unknown of the linear system. | ||
175 | ✗ | m_listUnknown.push_back(potTransMemb); | |
176 | ✗ | break; | |
177 | } | ||
178 | ✗ | case 1: { | |
179 | ✗ | nameOfTheProblem = "Problem cardiac Monodomain"; | |
180 | ✗ | listVariable.push_back(potTransMemb); | |
181 | ✗ | listNumComp.push_back(1); | |
182 | //define unknown of the linear system. | ||
183 | ✗ | m_listUnknown.push_back(potTransMemb); | |
184 | ✗ | break; | |
185 | } | ||
186 | 1 | case 2: { | |
187 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | nameOfTheProblem = "Problem cardiac Bidomain"; |
188 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | listVariable.push_back(potTransMemb); |
189 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | listNumComp.push_back(1); |
190 | //define unknown of the linear system. | ||
191 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_listUnknown.push_back(potTransMemb); |
192 | 1 | break; | |
193 | } | ||
194 | ✗ | default: | |
195 | ✗ | FEL_ERROR("Model not defined for ALP solver."); | |
196 | ✗ | break; | |
197 | } | ||
198 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | definePhysicalVariable(listVariable,listNumComp); |
199 | |||
200 | 1 | } | |
201 | |||
202 | ✗ | void EigenProblemALP::initializeSystemSolver() { | |
203 | ✗ | if (m_problem != 2) { | |
204 | ✗ | FEL_ERROR("Method not implemented for this problem."); | |
205 | } | ||
206 | ✗ | felInt* nnz = new felInt[3*m_dimRomBasis+1]; | |
207 | ✗ | for ( felInt i = 0; i<m_dimRomBasis; i++) { | |
208 | ✗ | if (m_method == 1 || m_method == 2) { | |
209 | ✗ | nnz[i] = 1; | |
210 | ✗ | nnz[i+m_dimRomBasis] = 1; | |
211 | ✗ | } else if (m_method == 3 || m_method == 4) { | |
212 | ✗ | nnz[i] = m_dimRomBasis; | |
213 | ✗ | nnz[i+m_dimRomBasis] = m_dimRomBasis; | |
214 | } | ||
215 | ✗ | nnz[i+2*m_dimRomBasis] = 2*m_dimRomBasis+1; | |
216 | } | ||
217 | ✗ | nnz[3*m_dimRomBasis] = m_dimRomBasis+1; | |
218 | ✗ | m_matrixRom.createSeqAIJ(PETSC_COMM_SELF, 3*m_dimRomBasis+1, 3*m_dimRomBasis+1, 0, nnz); | |
219 | ✗ | m_matrixRom.setFromOptions(); | |
220 | ✗ | m_matrixRom.setOption(MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE); | |
221 | ✗ | delete [] nnz; | |
222 | |||
223 | ✗ | m_matrixRom.getVecs(m_solutionRom,m_rhsRom); | |
224 | |||
225 | int ii; | ||
226 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
227 | ✗ | ii=i; | |
228 | ✗ | m_solutionRom.setValues(1,&ii,&m_beta[i],INSERT_VALUES); | |
229 | ✗ | ii=i+m_dimRomBasis; | |
230 | ✗ | m_solutionRom.setValues(1,&ii,&m_mu[i],INSERT_VALUES); | |
231 | ✗ | ii=i+2*m_dimRomBasis; | |
232 | ✗ | m_solutionRom.setValues(1,&ii,&m_xi[i],INSERT_VALUES); | |
233 | } | ||
234 | ✗ | m_solutionRom.assembly(); | |
235 | |||
236 | ✗ | if (FelisceParam::verbose() > 40) | |
237 | ✗ | m_solutionRom.view(); | |
238 | |||
239 | ✗ | m_kspRom->init(); | |
240 | ✗ | m_kspRom->setKSPandPCType(KSPGMRES,PCASM); | |
241 | ✗ | m_kspRom->setTolerances(1.e-10,1.e-10,1000,200); | |
242 | ✗ | m_kspRom->setKSPOptions(KSPGMRES,true); | |
243 | } | ||
244 | |||
245 | // Define Physical Variable associate to the problem | ||
246 | 1 | void EigenProblemALP::initPerElementType() { | |
247 |
1/4✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | switch(m_problem) { |
248 | ✗ | case 0: { | |
249 | //Init pointer on Finite Element, Variable or idVariable | ||
250 | ✗ | m_ipotTransMemb = m_listVariable.getVariableIdList(potTransMemb); | |
251 | ✗ | m_fePotTransMemb = m_listCurrentFiniteElement[m_ipotTransMemb]; | |
252 | ✗ | m_elemFieldU0.initialize(DOF_FIELD,*m_fePotTransMemb); | |
253 | ✗ | break; | |
254 | } | ||
255 | ✗ | case 1: { | |
256 | //Init pointer on Finite Element, Variable or idVariable | ||
257 | ✗ | m_ipotTransMemb = m_listVariable.getVariableIdList(potTransMemb); | |
258 | ✗ | m_fePotTransMemb = m_listCurrentFiniteElement[m_ipotTransMemb]; | |
259 | ✗ | m_elemFieldU0.initialize(DOF_FIELD,*m_fePotTransMemb); | |
260 | ✗ | break; | |
261 | } | ||
262 | 1 | case 2: { | |
263 | //Init pointer on Finite Element, Variable or idVariable | ||
264 | 1 | m_ipotTransMemb = m_listVariable.getVariableIdList(potTransMemb); | |
265 | 1 | m_fePotTransMemb = m_listCurrentFiniteElement[m_ipotTransMemb]; | |
266 | 1 | m_elemFieldU0.initialize(DOF_FIELD,*m_fePotTransMemb); | |
267 | 1 | break; | |
268 | } | ||
269 | ✗ | default: | |
270 | ✗ | FEL_ERROR("Model not defined for ALP solver."); | |
271 | ✗ | break; | |
272 | } | ||
273 | |||
274 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (FelisceParam::instance().hasInfarct) { |
275 | ✗ | m_elemFieldFhNf0.initialize(DOF_FIELD,*m_fePotTransMemb); | |
276 | } | ||
277 | 1 | } | |
278 | |||
279 | // Assemble Matrix | ||
280 | 8192 | void EigenProblemALP::computeElementArray(const std::vector<Point*>& elemPoint, const std::vector<felInt>& elemIdPoint, felInt& iel, FlagMatrixRHS flagMatrixRHS) { | |
281 | IGNORE_UNUSED_ELEM_ID_POINT; | ||
282 | IGNORE_UNUSED_FLAG_MATRIX_RHS; | ||
283 |
1/4✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 8192 times.
✗ Branch 3 not taken.
|
8192 | switch(m_problem) { |
284 | ✗ | case 0: { // FKPP | |
285 | ✗ | m_fePotTransMemb->updateMeasQuadPt(0, elemPoint); | |
286 | ✗ | m_fePotTransMemb->updateFirstDeriv(0, elemPoint); | |
287 | |||
288 | |||
289 | // m_Matrix[0] = Am * grad(phi_i) * grad(phi_j) | ||
290 | ✗ | m_elementMat[m_idL]->grad_phi_i_grad_phi_j(FelisceParam::instance().Am,*m_fePotTransMemb,0,0,1); | |
291 | |||
292 | ✗ | if (FelisceParam::instance().hasInitialCondition || FelisceParam::instance().schroFilter) { | |
293 | // m_Matrix[0] += - m_coefChi * V * phi_i * phi_j | ||
294 | ✗ | m_elemFieldU0.setValue(m_U_0_seq, *m_fePotTransMemb, iel, m_ipotTransMemb, m_ao, m_dof); | |
295 | ✗ | m_elementMat[m_idL]->a_phi_i_phi_j(- m_coefChi,m_elemFieldU0,*m_fePotTransMemb,0,0,1); | |
296 | } | ||
297 | |||
298 | // Matrix[1] = phi_i * phi_j | ||
299 | ✗ | m_elementMat[m_idG]->phi_i_phi_j(1.,*m_fePotTransMemb,0,0,1); | |
300 | |||
301 | ✗ | if (!FelisceParam::instance().solveEigenProblem) { | |
302 | ✗ | if (m_useImprovedRec) { | |
303 | // m_Matrix[m_numberOfMatrix-1] = grad(phi_i) * grad(phi_j) | ||
304 | ✗ | m_elementMat[m_idK]->grad_phi_i_grad_phi_j(1.,*m_fePotTransMemb,0,0,1); | |
305 | } | ||
306 | } | ||
307 | ✗ | break; | |
308 | } | ||
309 | ✗ | case 1: { // Monodomain | |
310 | ✗ | m_fePotTransMemb->updateMeasQuadPt(0, elemPoint); | |
311 | ✗ | m_fePotTransMemb->updateFirstDeriv(0, elemPoint); | |
312 | |||
313 | |||
314 | // m_Matrix[0] = grad(phi_i) * grad(phi_j) | ||
315 | ✗ | m_elementMat[m_idL]->grad_phi_i_grad_phi_j(FelisceParam::instance().intraTransvTensor,*m_fePotTransMemb,0,0,1); | |
316 | |||
317 | ✗ | if (FelisceParam::instance().testCase == 1) { | |
318 | ✗ | std::vector<double> elemFiber; | |
319 | ✗ | getFiberDirection(iel,m_ipotTransMemb, elemFiber); | |
320 | // m_Matrix[0] += (\sigma_i^l-\sigma_i^t) a vec a grad(phi_i) * grad(phi_j) | ||
321 | ✗ | m_elementMat[m_idL]->tau_grad_phi_i_tau_grad_phi_j(FelisceParam::instance().intraFiberTensor-FelisceParam::instance().intraTransvTensor,elemFiber,*m_fePotTransMemb,0,0,1); | |
322 | } | ||
323 | |||
324 | ✗ | if (FelisceParam::instance().hasInitialCondition || FelisceParam::instance().schroFilter) { | |
325 | // m_Matrix[0] += - m_coefChi * V * phi_i * phi_j | ||
326 | ✗ | m_elemFieldU0.setValue(m_U_0_seq, *m_fePotTransMemb, iel, m_ipotTransMemb, m_ao, m_dof); | |
327 | ✗ | m_elementMat[m_idL]->a_phi_i_phi_j(- m_coefChi,m_elemFieldU0,*m_fePotTransMemb,0,0,1); | |
328 | } | ||
329 | |||
330 | // m_Matrix[1] = phi_i * phi_j | ||
331 | ✗ | m_elementMat[m_idG]->phi_i_phi_j(1.,*m_fePotTransMemb,0,0,1); | |
332 | |||
333 | ✗ | if (!FelisceParam::instance().solveEigenProblem) { | |
334 | |||
335 | ✗ | if (FelisceParam::instance().hasInfarct) { | |
336 | // m_Matrix[1] = B_ij = s(x) * phi_i * phi_j | ||
337 | ✗ | m_elemFieldFhNf0.setValue(m_FhNf0, *m_fePotTransMemb, iel, m_ipotTransMemb, m_ao, m_dof); | |
338 | ✗ | m_elementMat[m_idGs]->a_phi_i_phi_j(1.,m_elemFieldFhNf0,*m_fePotTransMemb,0,0,1); | |
339 | } else { | ||
340 | ✗ | double s = FelisceParam::instance().f0; | |
341 | // m_Matrix[1] = B_ij = s * phi_i * phi_j | ||
342 | ✗ | m_elementMat[m_idGs]->phi_i_phi_j(s,*m_fePotTransMemb,0,0,1); | |
343 | } | ||
344 | |||
345 | ✗ | if ( ( (m_tensorOrder == 4 ) & (m_useImprovedRec) ) || (m_tensorOrder == 3 ) ) { | |
346 | // m_Matrix[2] = E_ij = grad(phi_i) * grad(phi_j) | ||
347 | ✗ | m_elementMat[m_idK]->grad_phi_i_grad_phi_j(FelisceParam::instance().intraTransvTensor,*m_fePotTransMemb,0,0,1); | |
348 | ✗ | if (FelisceParam::instance().testCase == 1) { | |
349 | ✗ | std::vector<double> elemFiber; | |
350 | ✗ | getFiberDirection(iel,m_ipotTransMemb, elemFiber); | |
351 | // m_Matrix[2] += (\sigma_i^l-\sigma_i^t) a vec a grad(phi_i) * grad(phi_j) | ||
352 | ✗ | m_elementMat[m_idK]->tau_grad_phi_i_tau_grad_phi_j(FelisceParam::instance().intraFiberTensor-FelisceParam::instance().intraTransvTensor,elemFiber,*m_fePotTransMemb,0,0,1); | |
353 | } | ||
354 | } | ||
355 | |||
356 | ✗ | if (m_tensorOrder == 3 ) { | |
357 | ✗ | if (FelisceParam::instance().hasInfarct) { | |
358 | ✗ | if (FelisceParam::instance().testCase == 2) { | |
359 | // m_Matrix[3] = E^s_ij = s(x) * \sigma_i^t grad(phi_i), grad(phi_j) | ||
360 | ✗ | m_elemFieldFhNf0.setValue(m_FhNf0, *m_fePotTransMemb, iel, m_ipotTransMemb, m_ao, m_dof); | |
361 | ✗ | m_elementMat[m_idKs]->a_grad_phi_i_grad_phi_j(FelisceParam::instance().intraTransvTensor,m_elemFieldFhNf0,*m_fePotTransMemb,0,0,1); | |
362 | ✗ | } else if (FelisceParam::instance().testCase == 1) { | |
363 | ✗ | FEL_ERROR("Error: infarct in fiber directed conductivity case not yet implemented."); | |
364 | } | ||
365 | } else { | ||
366 | ✗ | double s = FelisceParam::instance().f0; | |
367 | ✗ | if (FelisceParam::instance().testCase == 2) { | |
368 | // m_Matrix[3] = E^s_ij = s*\sigma_i^t grad(phi_i), grad(phi_j) | ||
369 | ✗ | m_elementMat[m_idKs]->grad_phi_i_grad_phi_j(s*FelisceParam::instance().intraTransvTensor,*m_fePotTransMemb,0,0,1); | |
370 | ✗ | } else if (FelisceParam::instance().testCase == 1) { | |
371 | ✗ | std::vector<double> elemFiber; | |
372 | ✗ | getFiberDirection(iel,m_ipotTransMemb, elemFiber); | |
373 | // m_Matrix[3] = E^s_ij += s*(\sigma_i^l-\sigma_i^t) a vec a grad(phi_i) * grad(phi_j) | ||
374 | ✗ | m_elementMat[m_idKs]->tau_grad_phi_i_tau_grad_phi_j(s*(FelisceParam::instance().intraFiberTensor-FelisceParam::instance().intraTransvTensor),elemFiber,*m_fePotTransMemb,0,0,1); | |
375 | } | ||
376 | } | ||
377 | } | ||
378 | } | ||
379 | ✗ | break; | |
380 | } | ||
381 | 8192 | case 2: { | |
382 | 8192 | m_fePotTransMemb->updateMeasQuadPt(0, elemPoint); | |
383 | 8192 | m_fePotTransMemb->updateFirstDeriv(0, elemPoint); | |
384 | |||
385 | |||
386 | // m_Matrix[0] = grad(phi_i) * grad(phi_j) | ||
387 | 8192 | m_elementMat[m_idL]->grad_phi_i_grad_phi_j(FelisceParam::instance().intraTransvTensor,*m_fePotTransMemb,0,0,1); | |
388 | |||
389 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8192 times.
|
8192 | if (FelisceParam::instance().testCase == 1) { |
390 | ✗ | std::vector<double> elemFiber; | |
391 | ✗ | getFiberDirection(iel,m_ipotTransMemb, elemFiber); | |
392 | // m_Matrix[0] = \sigma_i^t \grad V_m | ||
393 | ✗ | m_elementMat[m_idL]->grad_phi_i_grad_phi_j(FelisceParam::instance().intraTransvTensor,*m_fePotTransMemb,0,0,1); | |
394 | // m_Matrix[0] += (\sigma_i^l-\sigma_i^t) a vec a grad(phi_i) * grad(phi_j) | ||
395 | ✗ | m_elementMat[m_idL]->tau_grad_phi_i_tau_grad_phi_j(FelisceParam::instance().intraFiberTensor-FelisceParam::instance().intraTransvTensor,elemFiber,*m_fePotTransMemb,0,0,1); | |
396 | } | ||
397 | |||
398 |
3/6✓ Branch 1 taken 8192 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8192 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 8192 times.
|
8192 | if (FelisceParam::instance().hasInitialCondition || FelisceParam::instance().schroFilter) { |
399 | // m_Matrix[0] += - m_coefChi * V * phi_i * phi_j | ||
400 | ✗ | m_elemFieldU0.setValue(m_U_0_seq, *m_fePotTransMemb, iel, m_ipotTransMemb, m_ao, m_dof); | |
401 | ✗ | m_elementMat[m_idL]->a_phi_i_phi_j(- m_coefChi,m_elemFieldU0,*m_fePotTransMemb,0,0,1); | |
402 | } | ||
403 | |||
404 | // m_Matrix[1] = phi_i * phi_j | ||
405 | 8192 | m_elementMat[m_idG]->phi_i_phi_j(1.,*m_fePotTransMemb,0,0,1); | |
406 | |||
407 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8192 times.
|
8192 | if (!FelisceParam::instance().solveEigenProblem) { |
408 | ✗ | if (FelisceParam::instance().hasInfarct) { | |
409 | // m_Matrix[1] = B_ij = s(x) * phi_i * phi_j | ||
410 | ✗ | m_elemFieldFhNf0.setValue(m_FhNf0, *m_fePotTransMemb, iel, m_ipotTransMemb, m_ao, m_dof); | |
411 | ✗ | m_elementMat[m_idGs]->a_phi_i_phi_j(1.,m_elemFieldFhNf0,*m_fePotTransMemb,0,0,1); | |
412 | } else { | ||
413 | ✗ | double s = FelisceParam::instance().f0; | |
414 | // m_Matrix[1] = B_ij = s * phi_i * phi_j | ||
415 | ✗ | m_elementMat[m_idGs]->phi_i_phi_j(s,*m_fePotTransMemb,0,0,1); | |
416 | } | ||
417 | |||
418 | // Matrix[2] = E_ij = \sigma_i^t grad(phi_i), grad(phi_j) | ||
419 | ✗ | m_elementMat[m_idK]->grad_phi_i_grad_phi_j(FelisceParam::instance().intraTransvTensor,*m_fePotTransMemb,0,0,1); | |
420 | // Matrix[3] = Q_ij = (\sigma_i^t+\sigma_e^t) grad(phi_i), grad(phi_j) | ||
421 | ✗ | m_elementMat[m_idKie]->grad_phi_i_grad_phi_j(FelisceParam::instance().intraTransvTensor+FelisceParam::instance().extraTransvTensor,*m_fePotTransMemb,0,0,1); | |
422 | ✗ | if (FelisceParam::instance().testCase == 1) { | |
423 | ✗ | std::vector<double> elemFiber; | |
424 | ✗ | getFiberDirection(iel,m_ipotTransMemb, elemFiber); | |
425 | // Matrix[2] = E_ij = (\sigma_i^l-\sigma_i^t) a vec a grad(phi_i), grad(phi_j) | ||
426 | ✗ | m_elementMat[m_idK]->tau_grad_phi_i_tau_grad_phi_j(FelisceParam::instance().intraFiberTensor-FelisceParam::instance().intraTransvTensor,elemFiber,*m_fePotTransMemb,0,0,1); | |
427 | // Matrix[3] = Q_ij += (\sigma_i^l-\sigma_i^t+\sigma_e^l-\sigma_e^t) a vec a grad(phi_i) * grad(phi_j) | ||
428 | ✗ | m_elementMat[m_idKie]->tau_grad_phi_i_tau_grad_phi_j(FelisceParam::instance().intraFiberTensor-FelisceParam::instance().intraTransvTensor+FelisceParam::instance().extraFiberTensor-FelisceParam::instance().extraTransvTensor,elemFiber,*m_fePotTransMemb,0,0,1); | |
429 | } | ||
430 | |||
431 | ✗ | if (m_tensorOrder == 3 ) { | |
432 | ✗ | if (FelisceParam::instance().hasInfarct) { | |
433 | ✗ | if (FelisceParam::instance().testCase == 2) { | |
434 | // m_Matrix[3] = E^s_ij = s(x) * \sigma_i^t grad(phi_i), grad(phi_j) | ||
435 | ✗ | m_elemFieldFhNf0.setValue(m_FhNf0, *m_fePotTransMemb, iel, m_ipotTransMemb, m_ao, m_dof); | |
436 | ✗ | m_elementMat[m_idKs]->a_grad_phi_i_grad_phi_j(FelisceParam::instance().intraTransvTensor,m_elemFieldFhNf0,*m_fePotTransMemb,0,0,1); | |
437 | ✗ | } else if (FelisceParam::instance().testCase == 1) { | |
438 | ✗ | FEL_ERROR("Error: infarct in fiber directed conductivity case not yet implemented."); | |
439 | } | ||
440 | } else { | ||
441 | ✗ | double s = FelisceParam::instance().f0; | |
442 | ✗ | if (FelisceParam::instance().testCase == 2) { | |
443 | // m_Matrix[3] = E^s_ij = s*\sigma_i^t grad(phi_i), grad(phi_j) | ||
444 | ✗ | m_elementMat[m_idKs]->grad_phi_i_grad_phi_j(s*FelisceParam::instance().intraTransvTensor,*m_fePotTransMemb,0,0,1); | |
445 | ✗ | } else if (FelisceParam::instance().testCase == 1) { | |
446 | ✗ | std::vector<double> elemFiber; | |
447 | ✗ | getFiberDirection(iel,m_ipotTransMemb, elemFiber); | |
448 | // m_Matrix[3] = E^s_ij += s*(\sigma_i^l-\sigma_i^t) a vec a grad(phi_i) * grad(phi_j) | ||
449 | ✗ | m_elementMat[m_idKs]->tau_grad_phi_i_tau_grad_phi_j(s*(FelisceParam::instance().intraFiberTensor-FelisceParam::instance().intraTransvTensor),elemFiber,*m_fePotTransMemb,0,0,1); | |
450 | } | ||
451 | } | ||
452 | } | ||
453 | } | ||
454 | 8192 | break; | |
455 | } | ||
456 | ✗ | default: | |
457 | ✗ | FEL_ERROR("Model not defined for ALP solver."); | |
458 | ✗ | break; | |
459 | } | ||
460 | 8192 | } | |
461 | |||
462 | // Visualize modes as a variable | ||
463 | 1 | void EigenProblemALP::writeMode(const int iter) { | |
464 | int rankProc; | ||
465 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | MPI_Comm_rank(m_petscComm,&rankProc); |
466 | |||
467 | 1 | std::string fileName; | |
468 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (iter > 0) |
469 | ✗ | fileName = "basis" + std::to_string(iter); | |
470 | else | ||
471 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | fileName = "basis"; |
472 | |||
473 | 1 | double* tmpSolToSave = nullptr; | |
474 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | tmpSolToSave = new double[m_numDof]; |
475 | |||
476 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
|
26 | for (int iBasis=0; iBasis<m_dimRomBasis; iBasis++) { |
477 |
1/2✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
|
25 | fromVecToDoubleStar(tmpSolToSave, m_basis[iBasis], rankProc, 1); |
478 |
2/4✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
|
25 | writeEnsightVector(tmpSolToSave, iBasis, fileName); |
479 | } | ||
480 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | delete [] tmpSolToSave; |
481 | |||
482 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (rankProc == 0) |
483 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | writeEnsightCase(m_dimRomBasis, 1.,fileName); |
484 | |||
485 | 1 | } | |
486 | |||
487 | ✗ | void EigenProblemALP::writeEnsightSolution(const int iter) { | |
488 | ✗ | PetscVector solUe; | |
489 | ✗ | solUe.duplicateFrom(m_U_0); | |
490 | ✗ | PetscVector solW; | |
491 | ✗ | solW.duplicateFrom(m_W_0); | |
492 | |||
493 | ✗ | if (iter > 0) { | |
494 | ✗ | projectOnDof(m_beta,m_sol,m_dimRomBasis); | |
495 | ✗ | if ( (m_problem == 1) || (m_problem == 2)) { | |
496 | ✗ | if (FelisceParam::instance().printIonicVar) { | |
497 | ✗ | projectOnDof(m_mu,solW,m_dimRomBasis); | |
498 | } | ||
499 | } | ||
500 | ✗ | if (m_problem == 2) { | |
501 | ✗ | projectOnDof(m_xi,solUe,m_dimRomBasis); | |
502 | } | ||
503 | } else { | ||
504 | ✗ | m_sol.copyFrom(m_U_0); | |
505 | ✗ | if ( (m_problem == 1) || (m_problem == 2)) { | |
506 | ✗ | if (FelisceParam::instance().printIonicVar) { | |
507 | ✗ | solW.copyFrom(m_W_0); | |
508 | } | ||
509 | } | ||
510 | ✗ | if (m_problem == 2) { | |
511 | ✗ | solUe.copyFrom(m_Ue_0); | |
512 | } | ||
513 | } | ||
514 | |||
515 | int rankProc; | ||
516 | ✗ | MPI_Comm_rank(m_petscComm,&rankProc); | |
517 | |||
518 | ✗ | double* tmpSolToSave = nullptr; | |
519 | ✗ | tmpSolToSave = new double[m_numDof]; | |
520 | |||
521 | ✗ | if (m_problem == 0) { | |
522 | ✗ | fromVecToDoubleStar(tmpSolToSave, m_sol, rankProc, 1); | |
523 | ✗ | writeEnsightVector(tmpSolToSave, iter, "sol"); | |
524 | } | ||
525 | |||
526 | ✗ | if ( (m_problem == 1) || (m_problem == 2)) { | |
527 | ✗ | fromVecToDoubleStar(tmpSolToSave, m_sol, rankProc, 1); | |
528 | ✗ | writeEnsightVector(tmpSolToSave, iter, "potTransMemb"); | |
529 | ✗ | if (FelisceParam::instance().printIonicVar) { | |
530 | ✗ | fromVecToDoubleStar(tmpSolToSave, solW, rankProc, 1); | |
531 | ✗ | writeEnsightVector(tmpSolToSave, iter, "ionicVar"); | |
532 | } | ||
533 | } | ||
534 | |||
535 | ✗ | if (m_problem == 2) { | |
536 | ✗ | fromVecToDoubleStar(tmpSolToSave, solUe, rankProc, 1); | |
537 | ✗ | writeEnsightVector(tmpSolToSave, iter, "potExtraCell"); | |
538 | } | ||
539 | |||
540 | ✗ | delete [] tmpSolToSave; | |
541 | ✗ | solUe.destroy(); | |
542 | ✗ | solW.destroy(); | |
543 | |||
544 | ✗ | std::vector<std::string> varNames; | |
545 | ✗ | if (m_problem == 0) { | |
546 | ✗ | varNames.resize(1); | |
547 | ✗ | varNames[0] = "sol"; | |
548 | ✗ | } else if (m_problem == 1) { | |
549 | ✗ | if (FelisceParam::instance().printIonicVar) { | |
550 | ✗ | varNames.resize(2); | |
551 | ✗ | varNames[0] = "potTransMemb"; | |
552 | ✗ | varNames[1] = "ionicVar"; | |
553 | } else { | ||
554 | ✗ | varNames.resize(1); | |
555 | ✗ | varNames[0] = "potTransMemb"; | |
556 | } | ||
557 | ✗ | } else if (m_problem == 2) { | |
558 | ✗ | if (FelisceParam::instance().printIonicVar) { | |
559 | ✗ | varNames.resize(3); | |
560 | ✗ | varNames[0] = "potTransMemb"; | |
561 | ✗ | varNames[1] = "potExtraCell"; | |
562 | ✗ | varNames[2] = "ionicVar"; | |
563 | } else { | ||
564 | ✗ | varNames.resize(2); | |
565 | ✗ | varNames[0] = "potTransMemb"; | |
566 | ✗ | varNames[1] = "potExtraCell"; | |
567 | } | ||
568 | } | ||
569 | ✗ | if (rankProc == 0) | |
570 | ✗ | writeEnsightCase(iter+1, FelisceParam::instance().timeStep * FelisceParam::instance().frequencyWriteSolution,varNames, FelisceParam::instance().time); | |
571 | |||
572 | } | ||
573 | |||
574 | // Solve eigenproblem to build rom basis | ||
575 | 1 | void EigenProblemALP::buildSolver() { | |
576 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | if (FelisceParam::verbose()) PetscPrintf(PETSC_COMM_WORLD,"\nBuilding Slepc Solver.\n"); |
577 | |||
578 | #ifdef FELISCE_WITH_SLEPC | ||
579 | // m_Matrix[0] * Phi = lambda * m_Matrix[1] * Phi | ||
580 | 1 | EPSSetOperators(m_eps,m_Matrix[m_idL].toPetsc(),m_Matrix[m_idG].toPetsc()); | |
581 | 1 | EPSSetDimensions(m_eps,2*m_dimRomBasis,PETSC_DECIDE,PETSC_DECIDE); | |
582 | 1 | EPSSetProblemType(m_eps,EPS_GHEP); | |
583 | 1 | EPSSetType(m_eps, EPSKRYLOVSCHUR); | |
584 | 1 | EPSSetTolerances(m_eps,1.0e-8,1000); // 1.e-05, 200 | |
585 | 1 | EPSKrylovSchurSetRestart(m_eps,0.7); | |
586 | 1 | EPSSetFromOptions(m_eps); | |
587 | #endif | ||
588 | 1 | } | |
589 | |||
590 | 1 | void EigenProblemALP::solve() { | |
591 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
1 | if (FelisceParam::verbose()) PetscPrintf(PETSC_COMM_WORLD,"\nSolve eigenvalue problem.\n"); |
592 | #ifdef FELISCE_WITH_SLEPC | ||
593 | PetscInt nconv; | ||
594 | //First request a singular value from one end of the spectrum | ||
595 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | EPSSetWhichEigenpairs(m_eps,EPS_SMALLEST_REAL); |
596 | //EPSSetInterval(m_eps,-1.e-1,200.); | ||
597 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (m_verbose >= 10) { |
598 | ✗ | m_Matrix[m_idL].view(); | |
599 | ✗ | m_Matrix[m_idG].view(); | |
600 | ✗ | EPSView(m_eps,PETSC_VIEWER_STDOUT_WORLD); | |
601 | } | ||
602 | |||
603 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | EPSSolve(m_eps); |
604 | |||
605 | //Get number of converged singular values | ||
606 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | EPSGetConverged(m_eps,&nconv); |
607 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | PetscPrintf(PETSC_COMM_WORLD," Number of converged values = %d.\n", nconv); |
608 | |||
609 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if ( m_dimRomBasis > m_numDof ) { |
610 | ✗ | PetscPrintf(PETSC_COMM_WORLD," Warning! Number of function basis bigger than number of dof.\n"); | |
611 | ✗ | m_dimRomBasis = m_numDof; | |
612 | } | ||
613 | |||
614 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if ( m_dimRomBasis > nconv ) { |
615 | ✗ | PetscPrintf(PETSC_COMM_WORLD," Warning! Number of function basis bigger than number of converged values.\n"); | |
616 | ✗ | m_dimRomBasis = nconv; | |
617 | } | ||
618 | |||
619 | double sigma; | ||
620 | //Get converged singular values: largest singular value is stored in sigma. | ||
621 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (nconv > 0) { |
622 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
|
26 | for (int i=0; i < m_dimRomBasis; i++) { |
623 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | EPSGetEigenpair(m_eps,i,&sigma,FELISCE_PETSC_NULLPTR,FELISCE_PETSC_NULLPTR,FELISCE_PETSC_NULLPTR); |
624 | } | ||
625 | } else { | ||
626 | ✗ | m_dimRomBasis = 0; | |
627 | ✗ | PetscPrintf(PETSC_COMM_WORLD," Unable to compute smallest singular value!\n\n"); | |
628 | ✗ | exit(1); | |
629 | } | ||
630 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | PetscPrintf(PETSC_COMM_WORLD, "m_dimRomBasis = %d \n", m_dimRomBasis); |
631 | |||
632 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_eigenValue == nullptr) |
633 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | m_eigenValue = new double[m_dimRomBasis]; |
634 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_basis.resize(m_dimRomBasis); |
635 | double norm2; | ||
636 | double normM; | ||
637 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | PetscVector tmpVec; |
638 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | m_Matrix[m_idG].getVecs(nullPetscVector,tmpVec); |
639 | 1 | double imgpart = 0.; | |
640 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
|
26 | for (int i=0; i < m_dimRomBasis; i++) { |
641 |
1/2✓ Branch 3 taken 25 times.
✗ Branch 4 not taken.
|
25 | m_Matrix[m_idG].getVecs(nullPetscVector,m_basis[i]); |
642 |
2/4✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 25 times.
✗ Branch 6 not taken.
|
25 | EPSGetEigenpair(m_eps,i,&m_eigenValue[i],&imgpart,m_basis[i].toPetsc(),FELISCE_PETSC_NULLPTR); |
643 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
|
25 | if (Tools::notEqual(imgpart,0.0)) { |
644 | ✗ | PetscPrintf(PETSC_COMM_WORLD, "Warning! Im(m_eigenValue[%d]) = %e \n", i, imgpart); | |
645 | } | ||
646 |
1/2✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
|
25 | m_basis[i].norm(NORM_2,&norm2); |
647 | |||
648 |
1/2✓ Branch 3 taken 25 times.
✗ Branch 4 not taken.
|
25 | mult(m_Matrix[m_idG], m_basis[i], tmpVec); |
649 |
1/2✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
|
25 | dot(m_basis[i],tmpVec,&normM); |
650 |
1/2✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
25 | if (m_verbose >= 1) { |
651 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | PetscPrintf(PETSC_COMM_WORLD, "m_eigenValue[%d] = %e \n", i, m_eigenValue[i]); |
652 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | PetscPrintf(PETSC_COMM_WORLD, "norm2[%d] = %e \n", i, norm2); |
653 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | PetscPrintf(PETSC_COMM_WORLD, "normM[%d] = %e \n", i, normM); |
654 | } | ||
655 | } | ||
656 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | tmpVec.destroy(); |
657 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | std::string fileName = FelisceParam::instance().resultDir + "/eigenValue"; |
658 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | viewALP(m_eigenValue,m_dimRomBasis,fileName); |
659 | #endif | ||
660 | 1 | } | |
661 | |||
662 | // Reduced model functions | ||
663 | //======================== | ||
664 | // Initialization | ||
665 | 1 | void EigenProblemALP::readData(IO& io) { | |
666 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | if (FelisceParam::verbose() > 0) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::readData.\n"); |
667 | 1 | m_Matrix[m_idG].getVecs(m_U_0,nullPetscVector); | |
668 | 1 | m_U_0.setFromOptions(); | |
669 | |||
670 | 1 | m_U_0_seq.createSeq(PETSC_COMM_SELF,m_numDof); | |
671 | 1 | m_U_0_seq.setFromOptions(); | |
672 | |||
673 | 1 | m_W_0.duplicateFrom(m_U_0); | |
674 | 1 | m_W_0.copyFrom(m_U_0); | |
675 | |||
676 | 1 | m_W_0_seq.createSeq(PETSC_COMM_SELF,m_numDof); | |
677 | 1 | m_W_0_seq.setFromOptions(); | |
678 | |||
679 | 1 | m_Ue_0.duplicateFrom(m_U_0); | |
680 | 1 | m_Ue_0.copyFrom(m_U_0); | |
681 | |||
682 | 1 | m_Ue_0_seq.createSeq(PETSC_COMM_SELF,m_numDof); | |
683 | 1 | m_Ue_0_seq.setFromOptions(); | |
684 | |||
685 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (FelisceParam::instance().hasInitialCondition) { |
686 | // Read initial solution file (*.00000.scl) | ||
687 | ✗ | int idInVar = 0; | |
688 | // potTransMemb | ||
689 | ✗ | double* initialSolution = nullptr; | |
690 | ✗ | initialSolution = new double[m_mesh->numPoints()]; | |
691 | ✗ | io.readVariable(idInVar, 0.,initialSolution, m_mesh->numPoints()); | |
692 | ✗ | idInVar ++; | |
693 | // ionicVar | ||
694 | ✗ | double* ionicSolution = nullptr; | |
695 | ✗ | if ( (m_problem == 1) || (m_problem == 2) ) { | |
696 | ✗ | ionicSolution = new double[m_mesh->numPoints()]; | |
697 | ✗ | io.readVariable(idInVar, 0.,ionicSolution, m_mesh->numPoints()); | |
698 | ✗ | idInVar ++; | |
699 | } | ||
700 | // potExtraCell | ||
701 | ✗ | double* extraCellSolution = nullptr; | |
702 | ✗ | if (m_problem == 2) { | |
703 | ✗ | extraCellSolution = new double[m_mesh->numPoints()]; | |
704 | ✗ | io.readVariable(idInVar, 0.,extraCellSolution, m_mesh->numPoints()); | |
705 | ✗ | idInVar ++; | |
706 | } | ||
707 | // initialize (parallel) initial solution vectors | ||
708 | ✗ | fromDoubleStarToVec(initialSolution, m_U_0, m_mesh->numPoints()); | |
709 | ✗ | if ( (m_problem == 1) || (m_problem == 2) ) | |
710 | ✗ | fromDoubleStarToVec(ionicSolution, m_W_0, m_mesh->numPoints()); | |
711 | ✗ | if (m_problem == 2 ) | |
712 | ✗ | fromDoubleStarToVec(extraCellSolution, m_Ue_0, m_mesh->numPoints()); | |
713 | |||
714 | // initialize SEQUENTIAL initial solution vectors (in order to use elemField and define collocation pts solution) | ||
715 | felInt ia; | ||
716 | ✗ | for (felInt i=0; i< m_numDof; i++) { | |
717 | ✗ | ia = i; | |
718 | ✗ | AOApplicationToPetsc(m_ao,1,&ia); | |
719 | ✗ | m_U_0_seq.setValues(1,&ia,&initialSolution[i],INSERT_VALUES); | |
720 | ✗ | if ( (m_problem == 1) || (m_problem == 2) ) | |
721 | ✗ | m_W_0_seq.setValues(1,&ia,&ionicSolution[i],INSERT_VALUES); | |
722 | ✗ | if (m_problem == 2) | |
723 | ✗ | m_Ue_0_seq.setValues(1,&ia,&extraCellSolution[i],INSERT_VALUES); | |
724 | } | ||
725 | ✗ | m_U_0_seq.assembly(); | |
726 | ✗ | if ( (m_problem == 1) || (m_problem == 2) ) { | |
727 | ✗ | m_W_0_seq.assembly(); | |
728 | } | ||
729 | ✗ | if (m_problem == 2) { | |
730 | ✗ | m_Ue_0_seq.assembly(); | |
731 | } | ||
732 | |||
733 | ✗ | if (initialSolution) delete [] initialSolution; | |
734 | ✗ | if (ionicSolution) delete [] ionicSolution; | |
735 | ✗ | if (extraCellSolution) delete [] extraCellSolution; | |
736 | |||
737 | // Read fibers file (*.00000.vct) | ||
738 | ✗ | if (FelisceParam::instance().testCase == 1) { | |
739 | ✗ | if (m_fiber == nullptr) | |
740 | ✗ | m_fiber = new double[m_mesh->numPoints()*3]; | |
741 | ✗ | io.readVariable(idInVar, 0.,m_fiber, m_mesh->numPoints()*3); | |
742 | ✗ | idInVar ++; | |
743 | } | ||
744 | } | ||
745 | else { | ||
746 | 1 | PetscPrintf(PETSC_COMM_WORLD, "U_0 not read from file (zero vector)."); | |
747 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_U_0.set( 0.); |
748 | 1 | m_U_0.assembly(); | |
749 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if ( (m_problem == 1) || (m_problem == 2) ) { |
750 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (FelisceParam::instance().typeOfIonicModel == "schaf") { |
751 | ✗ | m_W_0.set( 1.); | |
752 | ✗ | m_W_0_seq.set( 1.); | |
753 | } | ||
754 | else { | ||
755 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_W_0.set( 0.); |
756 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_W_0_seq.set( 0.); |
757 | } | ||
758 | 1 | m_W_0.assembly(); | |
759 | 1 | m_W_0_seq.assembly(); | |
760 | } | ||
761 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_U_0_seq.set( 0.); |
762 | 1 | m_U_0_seq.assembly(); | |
763 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_problem == 2) { |
764 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_Ue_0.set( 0.); |
765 | 1 | m_Ue_0.assembly(); | |
766 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | m_Ue_0_seq.set( 0.); |
767 | 1 | m_Ue_0_seq.assembly(); | |
768 | } | ||
769 | } | ||
770 | |||
771 | 1 | } | |
772 | |||
773 | ✗ | void EigenProblemALP::getFiberDirection(felInt iel, int iUnknown, std::vector<double>& elemFiber) { | |
774 | ✗ | int numSupport = static_cast<int>(m_supportDofUnknown[iUnknown].iEle()[iel+1] - m_supportDofUnknown[iUnknown].iEle()[iel]); | |
775 | ✗ | elemFiber.resize( numSupport*3,0.); | |
776 | ✗ | for (int i = 0; i < numSupport; i++) { | |
777 | ✗ | elemFiber[i*3] = m_fiber[3*(m_supportDofUnknown[iUnknown].iSupportDof()[m_supportDofUnknown[iUnknown].iEle()[iel]+i])]; | |
778 | ✗ | elemFiber[i*3+1] = m_fiber[3*(m_supportDofUnknown[iUnknown].iSupportDof()[m_supportDofUnknown[iUnknown].iEle()[iel]+i])+1]; | |
779 | ✗ | elemFiber[i*3+2] = m_fiber[3*(m_supportDofUnknown[iUnknown].iSupportDof()[m_supportDofUnknown[iUnknown].iEle()[iel]+i])+2]; | |
780 | } | ||
781 | } | ||
782 | |||
783 | ✗ | void EigenProblemALP::readBasis() { | |
784 | ✗ | if (FelisceParam::verbose() > 0 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::readBasis()\n"); | |
785 | |||
786 | ✗ | m_basis.resize(m_dimRomBasis); | |
787 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
788 | ✗ | m_Matrix[m_idG].getVecs(m_basis[i],nullPetscVector); | |
789 | ✗ | m_basis[i].setFromOptions(); | |
790 | ✗ | double* vec = new double[m_numDof]; | |
791 | ✗ | readEnsightFile(vec,"basis",i,m_numDof); | |
792 | ✗ | fromDoubleStarToVec(vec, m_basis[i], m_numDof); | |
793 | ✗ | delete [] vec; | |
794 | ✗ | if (FelisceParam::verbose() > 40) m_basis[i].view(); | |
795 | } | ||
796 | |||
797 | ✗ | readEigenValueFromFile(); | |
798 | |||
799 | } | ||
800 | |||
801 | ✗ | void EigenProblemALP::initializeROM() { | |
802 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::initializeROM()\n"); | |
803 | |||
804 | ✗ | m_basis.resize(m_dimRomBasis); | |
805 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
806 | ✗ | m_Matrix[m_idG].getVecs(m_basis[i],nullPetscVector); | |
807 | ✗ | m_basis[i].setFromOptions(); | |
808 | ✗ | double* vec = new double[m_numDof]; | |
809 | ✗ | readEnsightFile(vec,"basis",i,m_numDof); | |
810 | ✗ | fromDoubleStarToVec(vec, m_basis[i], m_numDof); | |
811 | ✗ | delete [] vec; | |
812 | ✗ | if (FelisceParam::verbose() > 40) m_basis[i].view(); | |
813 | } | ||
814 | |||
815 | ✗ | if(m_useImprovedRec==true) { | |
816 | ✗ | m_orthComp.resize(m_dimOrthComp); | |
817 | ✗ | for(int i=0; i<m_dimOrthComp; i++) { | |
818 | ✗ | int fileInd = i + m_dimRomBasis; | |
819 | ✗ | m_Matrix[m_idG].getVecs(m_orthComp[i],nullPetscVector); | |
820 | ✗ | m_orthComp[i].setFromOptions(); | |
821 | ✗ | double* vec = new double[m_numDof]; | |
822 | ✗ | readEnsightFile(vec,"basis",fileInd,m_numDof); | |
823 | ✗ | fromDoubleStarToVec(vec, m_orthComp[i], m_numDof); | |
824 | ✗ | delete [] vec; | |
825 | ✗ | if (FelisceParam::verbose() > 40) m_orthComp[i].view(); | |
826 | } | ||
827 | } | ||
828 | |||
829 | ✗ | readEigenValueFromFile(); | |
830 | ✗ | initializeSolution(); | |
831 | } | ||
832 | |||
833 | ✗ | void EigenProblemALP::readEnsightFile(double* vec, std::string varName, int idIter, felInt size) { | |
834 | ✗ | std::string iteration; | |
835 | ✗ | if (idIter < 10) | |
836 | ✗ | iteration = "0000" + std::to_string(idIter); | |
837 | ✗ | else if (idIter < 100) | |
838 | ✗ | iteration = "000" + std::to_string(idIter); | |
839 | ✗ | else if (idIter < 1000) | |
840 | ✗ | iteration = "00" + std::to_string(idIter); | |
841 | ✗ | else if (idIter < 10000) | |
842 | ✗ | iteration = "0" + std::to_string(idIter); | |
843 | ✗ | else if (idIter < 100000) | |
844 | ✗ | iteration = std::to_string(idIter); | |
845 | |||
846 | ✗ | std::string fileName = FelisceParam::instance().inputDirectory + "/" + varName + "." + iteration + ".scl"; | |
847 | ✗ | if (FelisceParam::verbose() > 1) PetscPrintf(PETSC_COMM_WORLD, "Read file %s\n", fileName.c_str()); | |
848 | ✗ | FILE* pFile = fopen (fileName.c_str(),"r"); | |
849 | ✗ | if (pFile==nullptr) { | |
850 | ✗ | FEL_ERROR("Impossible to read "+fileName +"."); | |
851 | } | ||
852 | char str[80]; | ||
853 | ✗ | std::string display; | |
854 | ✗ | if ( fscanf(pFile,"%s", str) !=1 ) { | |
855 | ✗ | FEL_WARNING("Failed ot read str"); | |
856 | } | ||
857 | ✗ | display = str; | |
858 | ✗ | if ( fscanf(pFile,"%s", str) !=1 ) { | |
859 | ✗ | FEL_WARNING("Failed ot read str"); | |
860 | } | ||
861 | ✗ | display = str; | |
862 | ✗ | if ( fscanf(pFile,"%s", str) !=1) { | |
863 | ✗ | FEL_WARNING("Failed ot read str"); | |
864 | } | ||
865 | ✗ | display = str; | |
866 | //Read values | ||
867 | ✗ | int count = 0; | |
868 | ✗ | for ( felInt i = 0; i < size; i++) { | |
869 | ✗ | if ( fscanf(pFile,"%lf", &vec[i]) !=1 ) { | |
870 | ✗ | FEL_WARNING("Failed ot read vec"); | |
871 | } | ||
872 | ✗ | if ( count == 6 ) { | |
873 | ✗ | if ( fscanf( pFile, "\n" ) !=0 ) { | |
874 | ✗ | FEL_WARNING("Failed ot read"); | |
875 | } | ||
876 | ✗ | count=0; | |
877 | } | ||
878 | ✗ | count++; | |
879 | } | ||
880 | ✗ | fclose(pFile); | |
881 | } | ||
882 | |||
883 | ✗ | void EigenProblemALP::readEigenValueFromFile() { | |
884 | ✗ | std::string fileName = FelisceParam::instance().inputDirectory + "/eigenValue"; | |
885 | ✗ | if (FelisceParam::verbose() > 1) PetscPrintf(PETSC_COMM_WORLD, "Read file %s\n", fileName.c_str()); | |
886 | ✗ | FILE* pFile = fopen (fileName.c_str(),"r"); | |
887 | ✗ | if (pFile==nullptr) { | |
888 | ✗ | FEL_ERROR("Impossible to read "+fileName +"."); | |
889 | } | ||
890 | //Read values | ||
891 | ✗ | m_eigenValue = new double[m_dimRomBasis]; | |
892 | ✗ | for ( felInt i = 0; i < m_dimRomBasis; i++) { | |
893 | ✗ | if ( fscanf(pFile,"%lf", &m_eigenValue[i]) !=1 ) { | |
894 | ✗ | FEL_WARNING("Failed ot read vec"); | |
895 | } | ||
896 | ✗ | if ( fscanf( pFile, "\n" ) !=0 ) { | |
897 | ✗ | FEL_WARNING("Failed ot read"); | |
898 | } | ||
899 | } | ||
900 | ✗ | fclose(pFile); | |
901 | |||
902 | ✗ | if (FelisceParam::verbose() > 10) { | |
903 | ✗ | PetscPrintf(PETSC_COMM_WORLD, "EigenValues:\n"); | |
904 | ✗ | for ( felInt i = 0; i < m_dimRomBasis; i++) { | |
905 | ✗ | PetscPrintf(PETSC_COMM_WORLD, "[%d] %e \n", i, m_eigenValue[i]); | |
906 | } | ||
907 | } | ||
908 | |||
909 | } | ||
910 | |||
911 | ✗ | void EigenProblemALP::computeGamma() { | |
912 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::computeGamma()\n"); | |
913 | |||
914 | ✗ | if (m_gamma == nullptr) | |
915 | ✗ | m_gamma = new double[m_dimRomBasis]; | |
916 | |||
917 | ✗ | switch (m_problem) { | |
918 | ✗ | case 0: { | |
919 | // FKPP: | ||
920 | ✗ | double muFKPP = 10.; | |
921 | ✗ | double coef = - (m_coefChi + muFKPP); | |
922 | // FKPP: | ||
923 | // m_gamma_p = (muFKPP - lambda_p) * beta_p - (m_coefChi + muFKPP) * sum_{ij} beta_i * beta_j * T_{ijp} | ||
924 | ✗ | for (int p=0; p<m_dimRomBasis; p++) { | |
925 | |||
926 | ✗ | m_gamma[p] = (muFKPP - m_eigenValue[p]) * m_beta[p]; | |
927 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
928 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
929 | ✗ | m_gamma[p] += coef * m_beta[i] * m_beta[j] * m_tensorT[thirdOrderGlobalIndex(i,j,p)]; | |
930 | } | ||
931 | } | ||
932 | } | ||
933 | ✗ | break; | |
934 | } | ||
935 | ✗ | case 1: | |
936 | case 2: { | ||
937 | // MONODOMAIN or BIDOMAIN: | ||
938 | ✗ | double Am = FelisceParam::instance().Am; | |
939 | ✗ | double Cm = FelisceParam::instance().Cm; | |
940 | ✗ | double a = FelisceParam::instance().alpha; | |
941 | ✗ | double eps = FelisceParam::instance().epsilon; | |
942 | ✗ | double gam = FelisceParam::instance().gammaEl; | |
943 | |||
944 | ✗ | if (m_eta == nullptr) | |
945 | ✗ | m_eta = new double[m_dimRomBasis]; | |
946 | |||
947 | ✗ | switch (m_tensorOrder) { | |
948 | ✗ | case 3: { | |
949 | // MONODOMAIN: | ||
950 | // gamma_p = - Am mu_p - A_m a sum_{i} (a + (a+1)lambda_i / chi + lambda_i^2/chi^2 )beta_i B_{ip} - sum_{i} beta_i E_{ip} + Am sum_{i} ((a+1)/chi + lambda_i/chi^2) beta_i E^s_ip - Am/chi sum_{ij} beta_i beta_j U_ijp | ||
951 | // eta_p = eps * ro * beta_p - eps * mu_p | ||
952 | |||
953 | // BIDOMAIN: | ||
954 | // gamma_p = - Am mu_p - A_m a sum_{i} (a + (a+1)lambda_i / chi + lambda_i^2/chi^2 )beta_i B_{ip} - sum_{i} beta_i E_{ip} - sum_{i} xi_i E_{ip} + Am sum_{i} ((a+1)/chi + lambda_i/chi^2) beta_i E^s_ip - Am/chi sum_{ij} beta_i beta_j U_ijp | ||
955 | // eta_p = eps * ro * beta_p - eps * mu_p | ||
956 | |||
957 | ✗ | for (int p=0; p<m_dimRomBasis; p++) { | |
958 | ✗ | m_gamma[p] = - Am * m_mu[p]; | |
959 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
960 | ✗ | m_gamma[p] += - Am*( a + (1+a)*m_eigenValue[i]/m_coefChi + (m_eigenValue[i]*m_eigenValue[i])/(m_coefChi*m_coefChi) ) * m_beta[i] * m_tensorB[secondOrderGlobalIndex(i,p)]; | |
961 | ✗ | m_gamma[p] += - m_beta[i]*m_tensorE[secondOrderGlobalIndex(i,p)]; | |
962 | ✗ | if (m_problem == 2) { // bidomain | |
963 | ✗ | m_gamma[p] += - m_xi[i]*m_tensorE[secondOrderGlobalIndex(i,p)]; | |
964 | } | ||
965 | ✗ | m_gamma[p] += Am*( (1+a)/m_coefChi + m_eigenValue[i]/(m_coefChi*m_coefChi) ) * m_beta[i]*m_tensorEs[secondOrderGlobalIndex(i,p)]; | |
966 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
967 | ✗ | m_gamma[p] += - Am/m_coefChi * m_beta[i] * m_beta[j] * m_tensorU[i][secondOrderGlobalIndex(j,p)]; | |
968 | } | ||
969 | } | ||
970 | ✗ | if (FelisceParam::instance().hasSource) { | |
971 | ✗ | double delay[m_numSource]; | |
972 | ✗ | double tPeriod=fmod(m_fstransient->time,FelisceParam::instance().timePeriod); | |
973 | ✗ | for (int iS=0; iS<m_numSource; iS++) { | |
974 | ✗ | delay[iS] = FelisceParam::instance().delayStim[iS]; | |
975 | ✗ | if ((tPeriod>=delay[iS])&&(tPeriod<=(delay[iS]+FelisceParam::instance().stimTime))) | |
976 | ✗ | m_gamma[p] += Am*m_source[iS][p]; | |
977 | } | ||
978 | } | ||
979 | |||
980 | ✗ | m_gamma[p] = m_gamma[p] / (Am*Cm); | |
981 | |||
982 | ✗ | m_eta[p] = eps * ( gam * m_beta[p] - m_mu[p] ); | |
983 | |||
984 | } | ||
985 | |||
986 | ✗ | break; | |
987 | } | ||
988 | ✗ | case 4: { | |
989 | // MONODOMAIN: | ||
990 | // gamma_p = - lambda_p beta_p - Am mu_p - A_m a sum_{i} beta_i B_{ip} - \chi sum_{ij} beta_i beta_j T_{ijp} + (a+1)Am sum_{ij} beta_i beta_j T^s_ijp - Am sum_{ijk} beta_i beta_j beta_k Y_ijkp | ||
991 | // eta_p = eps * ro * beta_p - eps * mu_p | ||
992 | |||
993 | // BIDOMAIN: | ||
994 | // gamma_p = - lambda_p beta_p - lambda_p xi_p- Am mu_p - A_m a sum_{i} beta_i B_{ip} - \chi sum_{ij} beta_i beta_j T_{ijp} - \chi sum_{ij} beta_i xi_j T_{ijp} + (a+1)Am sum_{ij} beta_i beta_j T^s_ijp - Am sum_{ijk} beta_i beta_j beta_k Y_ijkp | ||
995 | // eta_p = eps * ro * beta_p - eps * mu_p | ||
996 | |||
997 | ✗ | for (int p=0; p<m_dimRomBasis; p++) { | |
998 | ✗ | m_gamma[p] = - m_eigenValue[p] * m_beta[p]; | |
999 | ✗ | m_gamma[p] += - Am * m_mu[p]; | |
1000 | ✗ | if (m_problem == 2) { // bidomain | |
1001 | ✗ | m_gamma[p] += - m_eigenValue[p] * m_xi[p]; | |
1002 | } | ||
1003 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1004 | ✗ | m_gamma[p] += - a*Am * m_beta[i] * m_tensorB[secondOrderGlobalIndex(i,p)]; | |
1005 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
1006 | ✗ | m_gamma[p] += (a+1)*Am * m_beta[i] * m_beta[j] * m_tensorTs[thirdOrderGlobalIndex(i,j,p)]; | |
1007 | ✗ | m_gamma[p] += - m_coefChi * m_beta[i] * m_beta[j] * m_tensorT[thirdOrderGlobalIndex(i,j,p)]; | |
1008 | ✗ | if (m_problem == 2) { // bidomain | |
1009 | ✗ | m_gamma[p] += - m_coefChi * m_beta[i] * m_xi[j] * m_tensorT[thirdOrderGlobalIndex(i,j,p)]; | |
1010 | } | ||
1011 | ✗ | for (int k=0; k<m_dimRomBasis; k++) { | |
1012 | ✗ | m_gamma[p] += - Am * m_beta[i] * m_beta[j] * m_beta[k] * m_tensorY[fourthOrderGlobalIndex(i,j,k,p)]; | |
1013 | } | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | ✗ | if (FelisceParam::instance().hasSource) { | |
1018 | ✗ | double delay[m_numSource]; | |
1019 | ✗ | double tPeriod=fmod(m_fstransient->time,FelisceParam::instance().timePeriod); | |
1020 | ✗ | for (int iS=0; iS<m_numSource; iS++) { | |
1021 | ✗ | delay[iS] = FelisceParam::instance().delayStim[iS]; | |
1022 | ✗ | if ((tPeriod>=delay[iS])&&(tPeriod<=(delay[iS]+FelisceParam::instance().stimTime))) | |
1023 | ✗ | m_gamma[p] += Am*m_source[iS][p]; | |
1024 | } | ||
1025 | } | ||
1026 | |||
1027 | ✗ | m_gamma[p] = m_gamma[p] / (Am*Cm); | |
1028 | |||
1029 | ✗ | m_eta[p] = eps * ( gam * m_beta[p] - m_mu[p] ); | |
1030 | |||
1031 | } | ||
1032 | ✗ | break; | |
1033 | } | ||
1034 | ✗ | default: | |
1035 | ✗ | break; | |
1036 | } | ||
1037 | ✗ | break; | |
1038 | } | ||
1039 | ✗ | default: | |
1040 | ✗ | FEL_ERROR("Model not defined for ALP solver."); | |
1041 | ✗ | break; | |
1042 | } | ||
1043 | } | ||
1044 | |||
1045 | ✗ | void EigenProblemALP::computeGammaExtrap() { | |
1046 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::computeGamma()\n"); | |
1047 | |||
1048 | ✗ | if (m_problem != 2) { | |
1049 | ✗ | FEL_ERROR("Time derivative method not implemented for this problem."); | |
1050 | } | ||
1051 | |||
1052 | ✗ | if (m_gamma_extrap == nullptr) | |
1053 | ✗ | m_gamma_extrap = new double[m_dimRomBasis]; | |
1054 | ✗ | if (m_eta_extrap == nullptr) | |
1055 | ✗ | m_eta_extrap = new double[m_dimRomBasis]; | |
1056 | |||
1057 | ✗ | double* beta_extrap = new double[m_dimRomBasis]; | |
1058 | ✗ | double* mu_extrap = new double[m_dimRomBasis]; | |
1059 | ✗ | double* xi_extrap = new double[m_dimRomBasis]; | |
1060 | |||
1061 | double coefExtrap[2]; | ||
1062 | ✗ | coefExtrap[0] = 2.; | |
1063 | ✗ | coefExtrap[1] = -1.; | |
1064 | |||
1065 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1066 | ✗ | beta_extrap[i] = coefExtrap[0]*m_beta[i] + coefExtrap[1]*m_beta_n_1[i]; | |
1067 | ✗ | mu_extrap[i] = coefExtrap[0]*m_mu[i] + coefExtrap[1]*m_mu_n_1[i]; | |
1068 | ✗ | xi_extrap[i] = coefExtrap[0]*m_xi[i] + coefExtrap[1]*m_xi_n_1[i]; | |
1069 | } | ||
1070 | |||
1071 | // MONODOMAIN or BIDOMAIN: | ||
1072 | ✗ | double Am = FelisceParam::instance().Am; | |
1073 | ✗ | double Cm = FelisceParam::instance().Cm; | |
1074 | ✗ | double a = FelisceParam::instance().alpha; | |
1075 | ✗ | double eps = FelisceParam::instance().epsilon; | |
1076 | ✗ | double gam = FelisceParam::instance().gammaEl; | |
1077 | |||
1078 | |||
1079 | ✗ | switch (m_tensorOrder) { | |
1080 | ✗ | case 3: { | |
1081 | // MONODOMAIN: | ||
1082 | // gamma_p = - Am mu_p - A_m a sum_{i} (a + (a+1)lambda_i / chi + lambda_i^2/chi^2 )beta_i B_{ip} - sum_{i} beta_i E_{ip} + Am sum_{i} ((a+1)/chi + lambda_i/chi^2) beta_i E^s_ip - Am/chi sum_{ij} beta_i beta_j U_ijp | ||
1083 | // eta_p = eps * ro * beta_p - eps * mu_p | ||
1084 | |||
1085 | // BIDOMAIN: | ||
1086 | // gamma_p = - Am mu_p - A_m a sum_{i} (a + (a+1)lambda_i / chi + lambda_i^2/chi^2 )beta_i B_{ip} - sum_{i} beta_i E_{ip} - sum_{i} xi_i E_{ip} + Am sum_{i} ((a+1)/chi + lambda_i/chi^2) beta_i E^s_ip - Am/chi sum_{ij} beta_i beta_j U_ijp | ||
1087 | // eta_p = eps * ro * beta_p - eps * mu_p | ||
1088 | |||
1089 | ✗ | for (int p=0; p<m_dimRomBasis; p++) { | |
1090 | ✗ | m_gamma_extrap[p] = - Am * mu_extrap[p]; | |
1091 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1092 | ✗ | m_gamma_extrap[p] += - Am*( a + (1+a)*m_eigenValue[i]/m_coefChi + (m_eigenValue[i]*m_eigenValue[i])/(m_coefChi*m_coefChi) ) * beta_extrap[i] * m_tensorB[secondOrderGlobalIndex(i,p)]; | |
1093 | ✗ | m_gamma_extrap[p] += - beta_extrap[i]*m_tensorE[secondOrderGlobalIndex(i,p)]; | |
1094 | ✗ | m_gamma_extrap[p] += - xi_extrap[i]*m_tensorE[secondOrderGlobalIndex(i,p)]; | |
1095 | ✗ | m_gamma_extrap[p] += Am*( (1+a)/m_coefChi + m_eigenValue[i]/(m_coefChi*m_coefChi) ) * beta_extrap[i]*m_tensorEs[secondOrderGlobalIndex(i,p)]; | |
1096 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
1097 | ✗ | m_gamma_extrap[p] += - Am/m_coefChi * beta_extrap[i] * beta_extrap[j] * m_tensorU[i][secondOrderGlobalIndex(j,p)]; | |
1098 | } | ||
1099 | } | ||
1100 | ✗ | if (FelisceParam::instance().hasSource) { | |
1101 | ✗ | double delay[m_numSource]; | |
1102 | ✗ | double tPeriod=fmod(m_fstransient->time,FelisceParam::instance().timePeriod); | |
1103 | ✗ | for (int iS=0; iS<m_numSource; iS++) { | |
1104 | ✗ | delay[iS] = FelisceParam::instance().delayStim[iS]; | |
1105 | ✗ | if ((tPeriod>=delay[iS])&&(tPeriod<=(delay[iS]+FelisceParam::instance().stimTime))) | |
1106 | ✗ | m_gamma_extrap[p] += Am*m_source[iS][p]; | |
1107 | } | ||
1108 | } | ||
1109 | |||
1110 | ✗ | m_gamma_extrap[p] = m_gamma_extrap[p] / (Am*Cm); | |
1111 | |||
1112 | ✗ | m_eta_extrap[p] = eps * ( gam * beta_extrap[p] - mu_extrap[p] ); | |
1113 | |||
1114 | } | ||
1115 | |||
1116 | ✗ | break; | |
1117 | } | ||
1118 | ✗ | case 4: { | |
1119 | // MONODOMAIN: | ||
1120 | // gamma_p = - lambda_p beta_p - Am mu_p - A_m a sum_{i} beta_i B_{ip} - \chi sum_{ij} beta_i beta_j T_{ijp} + (a+1)Am sum_{ij} beta_i beta_j T^s_ijp - Am sum_{ijk} beta_i beta_j beta_k Y_ijkp | ||
1121 | // eta_p = eps * ro * beta_p - eps * mu_p | ||
1122 | |||
1123 | // BIDOMAIN: | ||
1124 | // gamma_p = - lambda_p beta_p - lambda_p xi_p- Am mu_p - A_m a sum_{i} beta_i B_{ip} - \chi sum_{ij} beta_i beta_j T_{ijp} - \chi sum_{ij} beta_i xi_j T_{ijp} + (a+1)Am sum_{ij} beta_i beta_j T^s_ijp - Am sum_{ijk} beta_i beta_j beta_k Y_ijkp | ||
1125 | // eta_p = eps * ro * beta_p - eps * mu_p | ||
1126 | |||
1127 | ✗ | for (int p=0; p<m_dimRomBasis; p++) { | |
1128 | ✗ | m_gamma_extrap[p] = - m_eigenValue[p] * beta_extrap[p]; | |
1129 | ✗ | m_gamma_extrap[p] += - Am * m_mu[p]; | |
1130 | ✗ | m_gamma_extrap[p] += - m_eigenValue[p] * xi_extrap[p]; | |
1131 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1132 | ✗ | m_gamma_extrap[p] += - a*Am * beta_extrap[i] * m_tensorB[secondOrderGlobalIndex(i,p)]; | |
1133 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
1134 | ✗ | m_gamma_extrap[p] += (a+1)*Am * beta_extrap[i] * beta_extrap[j] * m_tensorTs[thirdOrderGlobalIndex(i,j,p)]; | |
1135 | ✗ | m_gamma_extrap[p] += - m_coefChi * beta_extrap[i] * beta_extrap[j] * m_tensorT[thirdOrderGlobalIndex(i,j,p)]; | |
1136 | ✗ | m_gamma_extrap[p] += - m_coefChi * beta_extrap[i] * xi_extrap[j] * m_tensorT[thirdOrderGlobalIndex(i,j,p)]; | |
1137 | ✗ | for (int k=0; k<m_dimRomBasis; k++) { | |
1138 | ✗ | m_gamma_extrap[p] += - Am * beta_extrap[i] * beta_extrap[j] * beta_extrap[k] * m_tensorY[fourthOrderGlobalIndex(i,j,k,p)]; | |
1139 | } | ||
1140 | } | ||
1141 | } | ||
1142 | |||
1143 | ✗ | if (FelisceParam::instance().hasSource) { | |
1144 | ✗ | double delay[m_numSource]; | |
1145 | ✗ | double tPeriod=fmod(m_fstransient->time,FelisceParam::instance().timePeriod); | |
1146 | ✗ | for (int iS=0; iS<m_numSource; iS++) { | |
1147 | ✗ | delay[iS] = FelisceParam::instance().delayStim[iS]; | |
1148 | ✗ | if ((tPeriod>=delay[iS])&&(tPeriod<=(delay[iS]+FelisceParam::instance().stimTime))) | |
1149 | ✗ | m_gamma_extrap[p] += Am*m_source[iS][p]; | |
1150 | } | ||
1151 | } | ||
1152 | |||
1153 | ✗ | m_gamma_extrap[p] = m_gamma_extrap[p] / (Am*Cm); | |
1154 | |||
1155 | ✗ | m_eta_extrap[p] = eps * ( gam * beta_extrap[p] - mu_extrap[p] ); | |
1156 | |||
1157 | } | ||
1158 | ✗ | break; | |
1159 | } | ||
1160 | ✗ | default: | |
1161 | ✗ | break; | |
1162 | } | ||
1163 | |||
1164 | ✗ | delete[] beta_extrap; | |
1165 | ✗ | delete[] mu_extrap; | |
1166 | ✗ | delete[] xi_extrap; | |
1167 | |||
1168 | } | ||
1169 | |||
1170 | ✗ | void EigenProblemALP::computeMatrixZeta() { | |
1171 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::computeMatrixZeta()\n"); | |
1172 | ✗ | if ( m_zeta.size() == 0 ) { | |
1173 | ✗ | m_size2 = static_cast<int>(m_dimRomBasis*(m_dimRomBasis+1)/2); | |
1174 | ✗ | m_zeta.resize(m_size2); | |
1175 | ✗ | for (int i=0; i<m_size2; i++) | |
1176 | ✗ | m_zeta[i].duplicateFrom(m_basis[0]); | |
1177 | } | ||
1178 | |||
1179 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { // row | |
1180 | ✗ | for (int j=0; j<i+1; j++) { // column | |
1181 | // secondOrderGlobalIndex(i,j) = i*(i+1)/2 + j | ||
1182 | ✗ | pointwiseMult(m_zeta[secondOrderGlobalIndex(i,j)],m_basis[i],m_basis[j]); | |
1183 | } | ||
1184 | } | ||
1185 | |||
1186 | } | ||
1187 | |||
1188 | ✗ | void EigenProblemALP::computeMatrixM() { | |
1189 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::computeMatrixM()\n"); | |
1190 | ✗ | if ( m_matrixM == nullptr ) { | |
1191 | ✗ | m_matrixM = new double*[m_dimRomBasis]; | |
1192 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1193 | ✗ | m_matrixM[i] = new double[m_dimRomBasis]; | |
1194 | } | ||
1195 | } | ||
1196 | |||
1197 | double coef; | ||
1198 | ✗ | double epsilonLambda = 5.e-01; //1.e-01; | |
1199 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1200 | ✗ | m_matrixM[i][i] = 0.; | |
1201 | ✗ | for (int j=0; j<i; j++) { | |
1202 | ✗ | m_matrixM[i][j] = 0.; | |
1203 | ✗ | if ( std::abs(m_eigenValue[i] - m_eigenValue[j] ) > epsilonLambda ) { | |
1204 | ✗ | coef = m_coefChi / ( m_eigenValue[j] - m_eigenValue[i] ); | |
1205 | ✗ | for (int k=0; k < m_dimRomBasis; k++) { | |
1206 | ✗ | m_matrixM[i][j] += coef * m_gamma[k] * m_tensorT[thirdOrderGlobalIndex(k,i,j)]; | |
1207 | } | ||
1208 | } | ||
1209 | ✗ | m_matrixM[j][i] = (-1.0) * m_matrixM[i][j]; | |
1210 | } | ||
1211 | } | ||
1212 | } | ||
1213 | |||
1214 | ✗ | int EigenProblemALP::secondOrderGlobalIndex(int& i, int& j) { | |
1215 | int id; | ||
1216 | |||
1217 | ✗ | if (i >= j) { | |
1218 | ✗ | id = static_cast<int>(i*(i+1)/2+j); | |
1219 | } else { | ||
1220 | ✗ | id = static_cast<int>(j*(j+1)/2+i); | |
1221 | } | ||
1222 | |||
1223 | ✗ | return id; | |
1224 | } | ||
1225 | |||
1226 | ✗ | int EigenProblemALP::thirdOrderGlobalIndex(int& i, int& j, int& k) { | |
1227 | int id; | ||
1228 | int s[3]; | ||
1229 | ✗ | s[0] = i; | |
1230 | ✗ | s[1] = j; | |
1231 | ✗ | s[2] = k; | |
1232 | int temp; | ||
1233 | ✗ | for (int ii=0; ii<3; ii++) { | |
1234 | ✗ | for (int jj=0; jj<2; jj++) { | |
1235 | ✗ | if (s[jj] < s[jj+1]) { | |
1236 | ✗ | temp = s[jj]; | |
1237 | ✗ | s[jj] = s[jj+1]; | |
1238 | ✗ | s[jj+1] = temp; | |
1239 | } | ||
1240 | } | ||
1241 | } | ||
1242 | ✗ | id = static_cast<int>(s[0]*(s[0]+1)*(s[0]+2)/6); | |
1243 | ✗ | id += static_cast<int>(s[1]*(s[1]+1)/2); | |
1244 | ✗ | id += s[2]; | |
1245 | ✗ | return id; | |
1246 | } | ||
1247 | |||
1248 | ✗ | int EigenProblemALP::fourthOrderGlobalIndex(int& i, int& j, int& k, int& h) { | |
1249 | int id; | ||
1250 | int s[4]; | ||
1251 | ✗ | s[0] = i; | |
1252 | ✗ | s[1] = j; | |
1253 | ✗ | s[2] = k; | |
1254 | ✗ | s[3] = h; | |
1255 | int temp; | ||
1256 | ✗ | for (int ii=0; ii<4; ii++) { | |
1257 | ✗ | for (int jj=0; jj<3; jj++) { | |
1258 | ✗ | if (s[jj] < s[jj+1]) { | |
1259 | ✗ | temp = s[jj]; | |
1260 | ✗ | s[jj] = s[jj+1]; | |
1261 | ✗ | s[jj+1] = temp; | |
1262 | } | ||
1263 | } | ||
1264 | } | ||
1265 | ✗ | id = static_cast<int>(s[0]*(s[0]+1)*(s[0]*s[0]+5*s[0]+6)/24); | |
1266 | ✗ | id += static_cast<int>(s[1]*(s[1]+1)*(s[1]+2)/6); | |
1267 | ✗ | id += static_cast<int>(s[2]*(s[2]+1)/2); | |
1268 | ✗ | id += s[3]; | |
1269 | ✗ | return id; | |
1270 | } | ||
1271 | |||
1272 | ✗ | void EigenProblemALP::computeTensor() { | |
1273 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::computeTensor()\n"); | |
1274 | ✗ | int n = m_dimRomBasis; | |
1275 | |||
1276 | ✗ | switch (m_problem) { | |
1277 | ✗ | case 0: { | |
1278 | // T_ijk = < phi_i, zeta_jk > | ||
1279 | ✗ | m_size3 = static_cast<int>(n*(n+1)*(n+2)/6); | |
1280 | ✗ | if (m_tensorT == nullptr) | |
1281 | ✗ | m_tensorT = new double [m_size3]; | |
1282 | |||
1283 | double valueT; | ||
1284 | ✗ | PetscVector phiG; | |
1285 | ✗ | phiG.duplicateFrom(m_basis[0]); | |
1286 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1287 | ✗ | for (int j=0; j<i+1; j++) { | |
1288 | // phiG = zeta_ij^T * G | ||
1289 | ✗ | mult(m_Matrix[m_idG],m_zeta[secondOrderGlobalIndex(i,j)],phiG); | |
1290 | ✗ | for (int k=0; k<j+1; k++) { | |
1291 | // valueT = zeta_ij^T * G * phi_k | ||
1292 | ✗ | dot(m_basis[k],phiG,&valueT); | |
1293 | ✗ | m_tensorT[thirdOrderGlobalIndex(i,j,k)] = valueT; | |
1294 | } | ||
1295 | } | ||
1296 | } | ||
1297 | ✗ | phiG.destroy(); | |
1298 | ✗ | break; | |
1299 | } | ||
1300 | ✗ | case 1: | |
1301 | case 2: { | ||
1302 | ✗ | switch (m_tensorOrder) { | |
1303 | ✗ | case 3: { | |
1304 | // B_ij = <s(x) phi_i, phi_j > = Phi^T G^s Phi | ||
1305 | ✗ | if (m_tensorB == nullptr) | |
1306 | ✗ | m_tensorB = new double [m_size2]; | |
1307 | // E_ij = < sigma grad(phi_i), grad(phi_j) > = Phi^T K Phi | ||
1308 | ✗ | if (m_tensorE == nullptr) | |
1309 | ✗ | m_tensorE = new double [m_size2]; | |
1310 | ✗ | if (m_problem == 2) { // bidomain | |
1311 | // Q_ij = < (sigma_I+sigma_E) grad(phi_i), grad(phi_j) > = Phi^T K_IE Phi | ||
1312 | ✗ | if (m_tensorQ == nullptr) | |
1313 | ✗ | m_tensorQ = new double [secondOrderGlobalIndex(m_dimRomBasis,m_dimRomBasis)+1]; | |
1314 | } | ||
1315 | // Es_ij = < s(x) sigma grad(phi_i), grad(phi_j) > = Phi^T K^s Phi | ||
1316 | ✗ | if (m_tensorEs == nullptr) | |
1317 | ✗ | m_tensorEs = new double [m_size2]; | |
1318 | // T_ijk = < phi_i, zeta_jk > = Phi^T G Z | ||
1319 | ✗ | m_size3 = static_cast<int>(n*(n+1)*(n+2)/6); | |
1320 | ✗ | if (m_tensorT == nullptr) | |
1321 | ✗ | m_tensorT = new double [m_size3]; | |
1322 | // U_ijk = < s(x) sigma grad(phi_i), grad(zeta_jk) > = Phi^T K^s Z | ||
1323 | ✗ | if (m_tensorU == nullptr) { | |
1324 | ✗ | m_tensorU = new double*[m_dimRomBasis]; | |
1325 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1326 | ✗ | m_tensorU[i] = new double[m_size2]; | |
1327 | } | ||
1328 | } | ||
1329 | |||
1330 | double value; | ||
1331 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1332 | // phiG = phi_i^T * G | ||
1333 | ✗ | PetscVector phiG; | |
1334 | ✗ | phiG.duplicateFrom(m_basis[0]); | |
1335 | ✗ | mult(m_Matrix[m_idG],m_basis[i],phiG); | |
1336 | |||
1337 | // phiGs = phi_i^T * G^s | ||
1338 | ✗ | PetscVector phiGs; | |
1339 | ✗ | phiGs.duplicateFrom(m_basis[0]); | |
1340 | ✗ | mult(m_Matrix[m_idGs],m_basis[i],phiGs); | |
1341 | |||
1342 | // phiK = phi_i^T * K | ||
1343 | ✗ | PetscVector phiK; | |
1344 | ✗ | phiK.duplicateFrom(m_basis[0]); | |
1345 | ✗ | mult(m_Matrix[m_idK],m_basis[i],phiK); | |
1346 | |||
1347 | // phiKs = phi_i^T * K^s | ||
1348 | ✗ | PetscVector phiKs; | |
1349 | ✗ | phiKs.duplicateFrom(m_basis[0]); | |
1350 | ✗ | mult(m_Matrix[m_idKs],m_basis[i],phiKs); | |
1351 | |||
1352 | // phiKie = phi_i^T * K_ie | ||
1353 | ✗ | PetscVector phiKie; | |
1354 | ✗ | phiKie.duplicateFrom(m_basis[0]); | |
1355 | ✗ | mult(m_Matrix[m_idKie],m_basis[i],phiKie); | |
1356 | |||
1357 | ✗ | for (int j=0; j<i+1; j++) { | |
1358 | // valueB = phi_i^T * G^s * phi_j | ||
1359 | ✗ | dot(m_basis[j],phiGs,&value); | |
1360 | ✗ | m_tensorB[secondOrderGlobalIndex(i,j)] = value; | |
1361 | |||
1362 | // valueE = phi_i^T * K * phi_j | ||
1363 | ✗ | dot(m_basis[j],phiK,&value); | |
1364 | ✗ | m_tensorE[secondOrderGlobalIndex(i,j)] = value; | |
1365 | |||
1366 | ✗ | if (m_problem == 2) { //bidomain | |
1367 | // valueQ = phi_i^T * K_ie * phi_j | ||
1368 | ✗ | dot(m_basis[j],phiKie,&value); | |
1369 | ✗ | m_tensorQ[secondOrderGlobalIndex(i,j)] = value; | |
1370 | } | ||
1371 | |||
1372 | // valueEs = phi_i^T * K^s * phi_j | ||
1373 | ✗ | dot(m_basis[j],phiKs,&value); | |
1374 | ✗ | m_tensorEs[secondOrderGlobalIndex(i,j)] = value; | |
1375 | |||
1376 | ✗ | for (int k=0; k<j+1; k++) { | |
1377 | // valueT = phi_i^T * G * zeta_jk | ||
1378 | ✗ | dot(m_zeta[secondOrderGlobalIndex(j,k)],phiG,&value); | |
1379 | ✗ | m_tensorT[thirdOrderGlobalIndex(i,j,k)] = value; | |
1380 | } | ||
1381 | } | ||
1382 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
1383 | ✗ | for (int k=0; k<j+1; k++) { | |
1384 | // valueU = phi_i^T * K^s * zeta_jk | ||
1385 | ✗ | dot(m_zeta[secondOrderGlobalIndex(j,k)],phiKs,&value); | |
1386 | ✗ | m_tensorU[i][secondOrderGlobalIndex(j,k)] = value; | |
1387 | } | ||
1388 | } | ||
1389 | ✗ | value = 0.; | |
1390 | ✗ | if (m_problem == 2) { //bidomain | |
1391 | // in order to impose \int(u_E)=0 | ||
1392 | // valueQ = sum_m phi_i,l^T * G_lm | ||
1393 | ✗ | phiG.sum(&value); | |
1394 | ✗ | m_tensorQ[secondOrderGlobalIndex(i,m_dimRomBasis)] = value; | |
1395 | } | ||
1396 | |||
1397 | ✗ | phiG.destroy(); | |
1398 | ✗ | phiGs.destroy(); | |
1399 | ✗ | phiK.destroy(); | |
1400 | ✗ | phiKie.destroy(); | |
1401 | ✗ | phiKs.destroy(); | |
1402 | } | ||
1403 | ✗ | if (m_problem == 2) //bidomain | |
1404 | ✗ | m_tensorQ[secondOrderGlobalIndex(m_dimRomBasis,m_dimRomBasis)] =0.; | |
1405 | ✗ | break; | |
1406 | } | ||
1407 | ✗ | case 4: { | |
1408 | // B_ij = < s phi_i, phi_j > = Phi^T G^s Phi | ||
1409 | ✗ | if (m_tensorB == nullptr) | |
1410 | ✗ | m_tensorB = new double [m_size2]; | |
1411 | ✗ | if (m_problem == 2) { // bidomain | |
1412 | // E_ij = < sigma grad(phi_i), grad(phi_j) > = Phi^T K Phi | ||
1413 | ✗ | if (m_tensorE == nullptr) | |
1414 | ✗ | m_tensorE = new double [m_size2]; | |
1415 | // Q_ij = < (sigma_i+sigma_e) phi_i, phi_j > = Phi^T K_ie Phi | ||
1416 | ✗ | if (m_tensorQ == nullptr) | |
1417 | ✗ | m_tensorQ = new double [secondOrderGlobalIndex(m_dimRomBasis,m_dimRomBasis)+1]; | |
1418 | } | ||
1419 | // T_ijk = < phi_i, zeta_jk > = Phi^T G Z | ||
1420 | ✗ | m_size3 = static_cast<int>(n*(n+1)*(n+2)/6); | |
1421 | ✗ | if (m_tensorT == nullptr) | |
1422 | ✗ | m_tensorT = new double [m_size3]; | |
1423 | // Ts_ijk = < s(x) phi_i, zeta_jk > = Phi^T G^s Z | ||
1424 | ✗ | m_size3 = static_cast<int>(n*(n+1)*(n+2)/6); | |
1425 | ✗ | if (m_tensorTs == nullptr) | |
1426 | ✗ | m_tensorTs = new double [m_size3]; | |
1427 | // Y_ijkh = < s(x) zeta_ij, zeta_kh > = Z^T G^s Z | ||
1428 | ✗ | m_size4 = static_cast<int>(n*(n+1)*(n*n+5*n+6)/24); | |
1429 | ✗ | if (m_tensorY == nullptr) | |
1430 | ✗ | m_tensorY = new double [m_size4]; | |
1431 | |||
1432 | double value; | ||
1433 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1434 | // phiG = phi_i^T * G | ||
1435 | ✗ | PetscVector phiG; | |
1436 | ✗ | phiG.duplicateFrom(m_basis[0]); | |
1437 | ✗ | mult(m_Matrix[m_idG],m_basis[i],phiG); | |
1438 | |||
1439 | // phiGs = phi_i^T * Gs | ||
1440 | ✗ | PetscVector phiGs; | |
1441 | ✗ | phiGs.duplicateFrom(m_basis[0]); | |
1442 | ✗ | mult(m_Matrix[m_idGs],m_basis[i],phiGs); | |
1443 | |||
1444 | // phiK = phi_i^T * K | ||
1445 | ✗ | PetscVector phiK; | |
1446 | ✗ | phiK.duplicateFrom(m_basis[0]); | |
1447 | ✗ | if (m_problem == 2) | |
1448 | ✗ | mult(m_Matrix[m_idK],m_basis[i],phiK); | |
1449 | |||
1450 | // phiKie = phi_i^T * K_ie | ||
1451 | ✗ | PetscVector phiKie; | |
1452 | ✗ | phiKie.duplicateFrom(m_basis[0]); | |
1453 | ✗ | if (m_problem ==2) | |
1454 | ✗ | mult(m_Matrix[m_idKie],m_basis[i],phiKie); | |
1455 | |||
1456 | ✗ | for (int j=0; j<i+1; j++) { | |
1457 | // valueB = phi_i^T * Gs * phi_j | ||
1458 | ✗ | dot(m_basis[j],phiGs,&value); | |
1459 | ✗ | m_tensorB[secondOrderGlobalIndex(i,j)] = value; | |
1460 | |||
1461 | ✗ | if (m_problem == 2) { // bidomain | |
1462 | // valueE = phi_i^T * K * phi_j | ||
1463 | ✗ | dot(m_basis[j],phiK,&value); | |
1464 | ✗ | m_tensorE[secondOrderGlobalIndex(i,j)] = value; | |
1465 | // valueQ = phi_i^T * K_ie * phi_j | ||
1466 | ✗ | dot(m_basis[j],phiKie,&value); | |
1467 | ✗ | m_tensorQ[secondOrderGlobalIndex(i,j)] = value; | |
1468 | } | ||
1469 | |||
1470 | // zetaG = zeta_ij^T * G | ||
1471 | ✗ | PetscVector zetaG; | |
1472 | ✗ | zetaG.duplicateFrom(m_basis[0]); | |
1473 | ✗ | mult(m_Matrix[m_idG],m_zeta[secondOrderGlobalIndex(i,j)],zetaG); | |
1474 | |||
1475 | // zetaGs = zeta_ij^T * G^s | ||
1476 | ✗ | PetscVector zetaGs; | |
1477 | ✗ | zetaGs.duplicateFrom(m_basis[0]); | |
1478 | ✗ | mult(m_Matrix[m_idGs],m_zeta[secondOrderGlobalIndex(i,j)],zetaGs); | |
1479 | |||
1480 | ✗ | for (int k=0; k<j+1; k++) { | |
1481 | // valueT = zeta_ij^T * G * phi_k | ||
1482 | ✗ | dot(m_basis[k],zetaG,&value); | |
1483 | ✗ | m_tensorT[thirdOrderGlobalIndex(i,j,k)] = value; | |
1484 | |||
1485 | // valueTs = zeta_ij^T * Gs * phi_k | ||
1486 | ✗ | dot(m_basis[k],zetaGs,&value); | |
1487 | ✗ | m_tensorTs[thirdOrderGlobalIndex(i,j,k)] = value; | |
1488 | |||
1489 | ✗ | for (int h=0; h<k+1; h++) { | |
1490 | // valueY = zeta_ij^T * Gs * zeta_kh | ||
1491 | ✗ | dot(m_zeta[secondOrderGlobalIndex(k,h)],zetaGs,&value); | |
1492 | ✗ | m_tensorY[fourthOrderGlobalIndex(i,j,k,h)] = value; | |
1493 | } | ||
1494 | } | ||
1495 | ✗ | zetaG.destroy(); | |
1496 | ✗ | zetaGs.destroy(); | |
1497 | } | ||
1498 | ✗ | value = 0.; | |
1499 | // in order to impose \int(u_E)=0 | ||
1500 | ✗ | if (m_problem == 2) { //bidomain | |
1501 | // valueQ = sum_m phi_i,l^T * G_lm | ||
1502 | ✗ | phiG.sum(&value); | |
1503 | ✗ | m_tensorQ[secondOrderGlobalIndex(i,m_dimRomBasis)] = value; | |
1504 | } | ||
1505 | |||
1506 | ✗ | phiG.destroy(); | |
1507 | ✗ | phiGs.destroy(); | |
1508 | ✗ | phiK.destroy(); | |
1509 | ✗ | phiKie.destroy(); | |
1510 | } | ||
1511 | ✗ | if (m_problem == 2) //bidomain | |
1512 | ✗ | m_tensorQ[secondOrderGlobalIndex(m_dimRomBasis,m_dimRomBasis)] =0.; | |
1513 | |||
1514 | ✗ | break; | |
1515 | } | ||
1516 | ✗ | default: | |
1517 | ✗ | break; | |
1518 | } | ||
1519 | ✗ | break; | |
1520 | } | ||
1521 | ✗ | default: | |
1522 | ✗ | FEL_ERROR("Model not defined for ALP solver."); | |
1523 | ✗ | break; | |
1524 | } | ||
1525 | |||
1526 | } | ||
1527 | |||
1528 | 1 | void EigenProblemALP::initializeSolution() { | |
1529 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::initializeSolution()\n"); |
1530 | |||
1531 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if ( !m_solutionInitialized) { |
1532 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_beta == nullptr) |
1533 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | m_beta = new double[m_dimRomBasis]; |
1534 | 1 | projectOnBasis(m_U_0,m_beta,true); | |
1535 | |||
1536 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if ( (m_problem == 1) || (m_problem == 2) ) { |
1537 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_mu == nullptr) |
1538 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | m_mu = new double[m_dimRomBasis]; |
1539 | 1 | projectOnBasis(m_W_0,m_mu,true); | |
1540 | } | ||
1541 | |||
1542 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_problem == 2) { |
1543 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_xi == nullptr) |
1544 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | m_xi = new double[m_dimRomBasis]; |
1545 | 1 | projectOnBasis(m_Ue_0,m_xi,true); | |
1546 | |||
1547 | } | ||
1548 | |||
1549 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (m_method == 4) { |
1550 | ✗ | if (m_beta_n_1 == nullptr) | |
1551 | ✗ | m_beta_n_1 = new double[m_dimRomBasis]; | |
1552 | ✗ | if (m_mu_n_1 == nullptr) | |
1553 | ✗ | m_mu_n_1 = new double[m_dimRomBasis]; | |
1554 | ✗ | if (m_xi_n_1 == nullptr) | |
1555 | ✗ | m_xi_n_1 = new double[m_dimRomBasis]; | |
1556 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1557 | ✗ | m_beta_n_1[i] = m_beta[i]; | |
1558 | ✗ | m_mu_n_1[i] = m_mu[i]; | |
1559 | ✗ | m_xi_n_1[i] = m_xi[i]; | |
1560 | } | ||
1561 | } | ||
1562 | |||
1563 | |||
1564 | 1 | m_solutionInitialized = true; | |
1565 | } | ||
1566 | |||
1567 | 1 | } | |
1568 | |||
1569 | ✗ | void EigenProblemALP::setHeteroTauClose(std::vector<double>& valueTauClose) { | |
1570 | IGNORE_UNUSED_ARGUMENT(valueTauClose); | ||
1571 | ✗ | FEL_WARNING("Hetero TauClose for Classical ALP not implemented."); | |
1572 | } | ||
1573 | |||
1574 | ✗ | void EigenProblemALP::setFhNf0(std::vector<double>& valuef0) { | |
1575 | ✗ | m_FhNf0.createSeq(PETSC_COMM_SELF,m_numDof); | |
1576 | ✗ | m_FhNf0.setFromOptions(); | |
1577 | |||
1578 | // initialize SEQUENTIAL vectors (in order to use elemField) | ||
1579 | felInt ia; | ||
1580 | ✗ | for (felInt i=0; i< m_numDof; i++) { | |
1581 | ✗ | ia = i; | |
1582 | ✗ | AOApplicationToPetsc(m_ao,1,&ia); | |
1583 | ✗ | m_FhNf0.setValues(1,&ia,&valuef0[i],INSERT_VALUES); | |
1584 | } | ||
1585 | ✗ | m_FhNf0.assembly(); | |
1586 | |||
1587 | } | ||
1588 | |||
1589 | ✗ | void EigenProblemALP::setIapp(std::vector<double>& iApp, int& idS) { | |
1590 | ✗ | if (m_source == nullptr) { | |
1591 | ✗ | m_source = new double*[m_numSource]; | |
1592 | ✗ | for (int i=0; i<m_numSource; i++) { | |
1593 | ✗ | m_source[i] = new double[m_dimRomBasis]; | |
1594 | } | ||
1595 | } | ||
1596 | |||
1597 | ✗ | PetscVector RHS; | |
1598 | ✗ | RHS.createSeq(PETSC_COMM_SELF,m_numDof); | |
1599 | ✗ | RHS.setFromOptions(); | |
1600 | // initialize SEQUENTIAL vectors (in order to use elemField) | ||
1601 | felInt ia; | ||
1602 | ✗ | for (felInt i=0; i< m_numDof; i++) { | |
1603 | ✗ | ia = i; | |
1604 | ✗ | AOApplicationToPetsc(m_ao,1,&ia); | |
1605 | ✗ | RHS.setValues(1,&ia,&iApp[i],INSERT_VALUES); | |
1606 | } | ||
1607 | ✗ | RHS.assembly(); | |
1608 | |||
1609 | ✗ | projectOnBasis(RHS, m_source[idS], true); | |
1610 | |||
1611 | ✗ | RHS.destroy(); | |
1612 | } | ||
1613 | |||
1614 | |||
1615 | 75 | void EigenProblemALP::checkSolution(PetscVector& solution, PetscVector& refSol, double & error) { | |
1616 |
2/6✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 75 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
75 | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::checkSolution\n"); |
1617 | |||
1618 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | PetscVector tmpVec1; |
1619 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | tmpVec1.duplicateFrom(refSol); |
1620 | |||
1621 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | PetscVector tmpVec2; |
1622 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | tmpVec2.duplicateFrom(refSol); |
1623 | |||
1624 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | waxpy(tmpVec1,-1.0,refSol,solution); |
1625 | |||
1626 |
1/2✓ Branch 2 taken 75 times.
✗ Branch 3 not taken.
|
75 | mult(m_Matrix[m_idG],tmpVec1,tmpVec2); |
1627 | |||
1628 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | dot(tmpVec1,tmpVec2,&error); |
1629 | |||
1630 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | tmpVec1.destroy(); |
1631 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | tmpVec2.destroy(); |
1632 | 75 | } | |
1633 | |||
1634 | 1 | void EigenProblemALP::checkBasis(int size) { | |
1635 | |||
1636 | 1 | if (size == 0) | |
1637 | 1 | size = m_dimRomBasis; | |
1638 | |||
1639 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (!m_solutionInitialized) { |
1640 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | initializeSolution(); |
1641 | } | ||
1642 | |||
1643 | int rankProc; | ||
1644 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | MPI_Comm_rank(m_petscComm,&rankProc); |
1645 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | PetscVector tmpSol; |
1646 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | tmpSol.duplicateFrom(m_U_0); |
1647 | |||
1648 | 1 | double* tmpSolToSave = nullptr; | |
1649 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | tmpSolToSave = new double[m_numDof]; |
1650 | |||
1651 | // Check convergence on m_U_0 | ||
1652 | 1 | double convergence[size]; | |
1653 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
|
26 | for (int iBasis=0; iBasis < size; iBasis++) { |
1654 | 25 | double tmpVec[iBasis+1]; | |
1655 |
2/2✓ Branch 0 taken 325 times.
✓ Branch 1 taken 25 times.
|
350 | for (int jBasis=0; jBasis<iBasis+1; jBasis++) { |
1656 | 325 | tmpVec[jBasis] = m_beta[jBasis]; | |
1657 | } | ||
1658 | |||
1659 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | projectOnDof(tmpVec,tmpSol,iBasis+1); |
1660 | |||
1661 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | checkSolution(tmpSol,m_U_0,convergence[iBasis]); |
1662 | |||
1663 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | fromVecToDoubleStar(tmpSolToSave, tmpSol, rankProc, 1); |
1664 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
|
25 | if (m_problem == 0) { |
1665 | ✗ | writeEnsightVector(tmpSolToSave, iBasis, "uConv"); | |
1666 | } | ||
1667 |
2/4✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
|
25 | if ( (m_problem == 1) || (m_problem == 2) ) { |
1668 |
2/4✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 25 times.
✗ Branch 6 not taken.
|
25 | writeEnsightVector(tmpSolToSave, iBasis, "potTransMembConv"); |
1669 | } | ||
1670 | |||
1671 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | tmpSol.axpy(-1.,m_U_0); |
1672 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | tmpSol.abs(); |
1673 | double maxU0; | ||
1674 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | m_U_0.max(&maxU0); |
1675 | double minU0; | ||
1676 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | m_U_0.min(&minU0); |
1677 | 25 | double deltaU0 = maxU0-minU0; | |
1678 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | tmpSol.scale(1./deltaU0); |
1679 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | fromVecToDoubleStar(tmpSolToSave, tmpSol, rankProc, 1); |
1680 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
|
25 | if (m_problem == 0) { |
1681 | ✗ | writeEnsightVector(tmpSolToSave, iBasis, "uError"); | |
1682 | } | ||
1683 |
2/4✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
|
25 | if ( (m_problem == 1) || (m_problem == 2) ) { |
1684 |
2/4✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 25 times.
✗ Branch 6 not taken.
|
25 | writeEnsightVector(tmpSolToSave, iBasis, "potTransMembError"); |
1685 | } | ||
1686 | |||
1687 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | PetscPrintf(PETSC_COMM_WORLD, "convergence[%d] = %e \n", iBasis, convergence[iBasis]); |
1688 | |||
1689 | 25 | } | |
1690 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | std::string fileName = FelisceParam::instance().resultDir + "/convergence"; |
1691 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | viewALP(convergence,size,fileName); |
1692 | |||
1693 | // Check convergence on m_W_0 | ||
1694 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if ( (m_problem == 1) || (m_problem == 2) ) { |
1695 | 1 | double convergenceW[size]; | |
1696 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
|
26 | for (int iBasis=0; iBasis < size; iBasis++) { |
1697 | 25 | double tmpVec[iBasis+1]; | |
1698 |
2/2✓ Branch 0 taken 325 times.
✓ Branch 1 taken 25 times.
|
350 | for (int jBasis=0; jBasis<iBasis+1; jBasis++) { |
1699 | 325 | tmpVec[jBasis] = m_mu[jBasis]; | |
1700 | } | ||
1701 | |||
1702 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | projectOnDof(tmpVec,tmpSol,iBasis+1); |
1703 | |||
1704 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | checkSolution(tmpSol,m_W_0,convergenceW[iBasis]); |
1705 | |||
1706 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | fromVecToDoubleStar(tmpSolToSave, tmpSol, rankProc, 1); |
1707 |
2/4✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 25 times.
✗ Branch 6 not taken.
|
25 | writeEnsightVector(tmpSolToSave, iBasis, "ionicVarConv"); |
1708 | |||
1709 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | tmpSol.axpy(-1.,m_W_0); |
1710 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | tmpSol.abs(); |
1711 | double maxU0; | ||
1712 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | m_W_0.max(&maxU0); |
1713 | double minU0; | ||
1714 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | m_W_0.min(&minU0); |
1715 | 25 | double deltaU0 = maxU0-minU0; | |
1716 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | tmpSol.scale(1./deltaU0); |
1717 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | fromVecToDoubleStar(tmpSolToSave, tmpSol, rankProc, 1); |
1718 |
2/4✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 25 times.
✗ Branch 6 not taken.
|
25 | writeEnsightVector(tmpSolToSave, iBasis, "ionicVarError"); |
1719 | |||
1720 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | PetscPrintf(PETSC_COMM_WORLD, "convergenceW[%d] = %e \n", iBasis, convergenceW[iBasis]); |
1721 | 25 | } | |
1722 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | fileName = FelisceParam::instance().resultDir + "/convergenceW"; |
1723 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | viewALP(convergenceW,size,fileName); |
1724 | 1 | } | |
1725 | |||
1726 | // Check convergence on m_Ue_0 | ||
1727 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (m_problem == 2) { |
1728 | 1 | double convergenceUe[size]; | |
1729 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
|
26 | for (int iBasis=0; iBasis < size; iBasis++) { |
1730 | 25 | double tmpVec[iBasis+1]; | |
1731 |
2/2✓ Branch 0 taken 325 times.
✓ Branch 1 taken 25 times.
|
350 | for (int jBasis=0; jBasis<iBasis+1; jBasis++) { |
1732 | 325 | tmpVec[jBasis] = m_xi[jBasis]; | |
1733 | } | ||
1734 | |||
1735 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | projectOnDof(tmpVec,tmpSol,iBasis+1); |
1736 | |||
1737 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | checkSolution(tmpSol,m_Ue_0,convergenceUe[iBasis]); |
1738 | |||
1739 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | fromVecToDoubleStar(tmpSolToSave, tmpSol, rankProc, 1); |
1740 |
2/4✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 25 times.
✗ Branch 6 not taken.
|
25 | writeEnsightVector(tmpSolToSave, iBasis, "potExtraCellConv"); |
1741 | |||
1742 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | tmpSol.axpy(-1.,m_Ue_0); |
1743 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | tmpSol.abs(); |
1744 | double maxU0; | ||
1745 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | m_Ue_0.max(&maxU0); |
1746 | double minU0; | ||
1747 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | m_Ue_0.min(&minU0); |
1748 | 25 | double deltaU0 = maxU0-minU0; | |
1749 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | tmpSol.scale(1./deltaU0); |
1750 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | fromVecToDoubleStar(tmpSolToSave, tmpSol, rankProc, 1); |
1751 |
2/4✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 25 times.
✗ Branch 6 not taken.
|
25 | writeEnsightVector(tmpSolToSave, iBasis, "potExtraCellError"); |
1752 | |||
1753 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | PetscPrintf(PETSC_COMM_WORLD, "convergenceUe[%d] = %e \n", iBasis, convergenceUe[iBasis]); |
1754 | 25 | } | |
1755 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | fileName = FelisceParam::instance().resultDir + "/convergenceUe"; |
1756 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | viewALP(convergenceUe,size,fileName); |
1757 | 1 | } | |
1758 | |||
1759 | 1 | std::vector<std::string> varNames; | |
1760 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (m_problem == 0) { |
1761 | ✗ | varNames.resize(2); | |
1762 | ✗ | varNames[0] = "uConv"; | |
1763 | ✗ | varNames[1] = "uError"; | |
1764 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | } else if (m_problem == 1) { |
1765 | ✗ | if (FelisceParam::instance().printIonicVar) { | |
1766 | ✗ | varNames.resize(4); | |
1767 | ✗ | varNames[0] = "potTransMembConv"; | |
1768 | ✗ | varNames[1] = "ionicVarConv"; | |
1769 | ✗ | varNames[2] = "potTransMembError"; | |
1770 | ✗ | varNames[3] = "ionicVarError"; | |
1771 | } else { | ||
1772 | ✗ | varNames.resize(2); | |
1773 | ✗ | varNames[0] = "potTransMembConv"; | |
1774 | ✗ | varNames[1] = "potTransMembError"; | |
1775 | } | ||
1776 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | } else if (m_problem == 2) { |
1777 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | if (FelisceParam::instance().printIonicVar) { |
1778 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | varNames.resize(6); |
1779 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | varNames[0] = "potTransMembConv"; |
1780 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | varNames[1] = "potExtraCellConv"; |
1781 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | varNames[2] = "ionicVarConv"; |
1782 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | varNames[3] = "potTransMembError"; |
1783 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | varNames[4] = "potExtraCellError"; |
1784 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | varNames[5] = "ionicVarError"; |
1785 | } else { | ||
1786 | ✗ | varNames.resize(4); | |
1787 | ✗ | varNames[0] = "potTransMembConv"; | |
1788 | ✗ | varNames[1] = "potExtraCellConv"; | |
1789 | ✗ | varNames[3] = "potTransMembError"; | |
1790 | ✗ | varNames[4] = "potExtraCellError"; | |
1791 | } | ||
1792 | } | ||
1793 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (rankProc == 0) |
1794 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | writeEnsightCase(size, 1.,varNames); |
1795 | |||
1796 | |||
1797 | |||
1798 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | delete [] tmpSolToSave; |
1799 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | tmpSol.destroy(); |
1800 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
2 | } |
1801 | |||
1802 | //Update functions | ||
1803 | ✗ | void EigenProblemALP::updateBasis() { | |
1804 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::updateBasis()\n"); | |
1805 | |||
1806 | ✗ | std::vector<PetscVector> newPhi; | |
1807 | ✗ | newPhi.resize(m_dimRomBasis); | |
1808 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1809 | ✗ | newPhi[i].duplicateFrom(m_basis[0]); | |
1810 | ✗ | newPhi[i].set(0.); | |
1811 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
1812 | ✗ | newPhi[i].axpy(- m_matrixM[j][i], m_basis[j]); | |
1813 | } | ||
1814 | } | ||
1815 | |||
1816 | ✗ | std::vector<PetscVector> rPhi; | |
1817 | |||
1818 | ✗ | if(m_useImprovedRec==true) { | |
1819 | ✗ | rPhi.resize(m_dimRomBasis); | |
1820 | |||
1821 | ✗ | int psiSize = m_dimOrthComp*m_dimOrthComp; | |
1822 | double* Psi1; | ||
1823 | ✗ | Psi1 = new double [psiSize]; | |
1824 | double* Psi2; | ||
1825 | ✗ | Psi2 = new double [psiSize]; | |
1826 | double* Psi; | ||
1827 | ✗ | Psi = new double [psiSize]; | |
1828 | |||
1829 | ✗ | double valP1=0.0; | |
1830 | ✗ | double valP2=0.0; | |
1831 | ✗ | PetscVector phiK; | |
1832 | ✗ | phiK.duplicateFrom(m_basis[0]); | |
1833 | ✗ | for(int i=0; i<m_dimOrthComp; i++) { | |
1834 | ✗ | mult(m_Matrix[m_idK],m_orthComp[i],phiK); | |
1835 | ✗ | for(int j=0; j<=i; j++) { | |
1836 | ✗ | dot(m_orthComp[j],phiK,&valP1); | |
1837 | ✗ | Psi1[i*(m_dimOrthComp)+j] = valP1; | |
1838 | ✗ | Psi1[j*(m_dimOrthComp)+i] = valP1; | |
1839 | } | ||
1840 | } | ||
1841 | ✗ | phiK.destroy(); | |
1842 | |||
1843 | ✗ | PetscVector tmpU; | |
1844 | ✗ | tmpU.duplicateFrom(m_basis[0]); | |
1845 | ✗ | tmpU.set(0.); | |
1846 | ✗ | for(int i=0; i<m_dimRomBasis; i++) { | |
1847 | ✗ | tmpU.axpy(m_beta[i],m_basis[i]); | |
1848 | } | ||
1849 | ✗ | PetscVector psiG; | |
1850 | ✗ | psiG.duplicateFrom(m_basis[0]); | |
1851 | ✗ | mult(m_Matrix[m_idG],tmpU,psiG); | |
1852 | |||
1853 | |||
1854 | |||
1855 | ✗ | for(int i=0; i<m_dimOrthComp; i++) { | |
1856 | ✗ | for(int j=0; j<=i; j++) { | |
1857 | ✗ | PetscVector zetaP; | |
1858 | ✗ | zetaP.duplicateFrom(m_basis[0]); | |
1859 | ✗ | pointwiseMult(zetaP,m_orthComp[i],m_orthComp[j]); | |
1860 | ✗ | dot(zetaP,psiG,&valP2); | |
1861 | ✗ | Psi2[i*(m_dimOrthComp)+j] = valP2; | |
1862 | ✗ | Psi2[j*(m_dimOrthComp)+i] = valP2; | |
1863 | |||
1864 | ✗ | zetaP.destroy(); | |
1865 | } | ||
1866 | } | ||
1867 | ✗ | psiG.destroy(); | |
1868 | ✗ | tmpU.destroy(); | |
1869 | |||
1870 | ✗ | PetscVector tmpF; | |
1871 | ✗ | tmpF.duplicateFrom(m_basis[0]); | |
1872 | ✗ | tmpF.set(0.); | |
1873 | ✗ | for(int i=0; i<m_dimRomBasis; i++) { | |
1874 | ✗ | tmpF.axpy(m_gamma[i],m_basis[i]); | |
1875 | } | ||
1876 | |||
1877 | ✗ | double tol = 1.0e-9; | |
1878 | ✗ | int maxIt = 2*m_dimOrthComp; | |
1879 | double* tmpRhs; | ||
1880 | ✗ | tmpRhs = new double[m_dimOrthComp]; | |
1881 | double* alpha; | ||
1882 | ✗ | alpha = new double[m_dimOrthComp]; | |
1883 | |||
1884 | |||
1885 | ✗ | for(int i=0; i<m_dimRomBasis; i++) { | |
1886 | ✗ | rPhi[i].duplicateFrom(m_basis[0]); | |
1887 | ✗ | rPhi[i].set(0.); | |
1888 | |||
1889 | ✗ | PetscVector FPhiI; | |
1890 | ✗ | FPhiI.duplicateFrom(m_basis[0]); | |
1891 | ✗ | pointwiseMult(FPhiI,m_basis[i],tmpF); | |
1892 | |||
1893 | ✗ | PetscVector FPhiG; | |
1894 | ✗ | FPhiG.duplicateFrom(m_basis[0]); | |
1895 | ✗ | mult(m_Matrix[m_idG],FPhiI,FPhiG); | |
1896 | |||
1897 | ✗ | for (int l=0; l<m_dimOrthComp; l++) { | |
1898 | ✗ | double rhsVal=0.0; | |
1899 | ✗ | dot(m_orthComp[l],FPhiG,&rhsVal); | |
1900 | ✗ | tmpRhs[l] = m_coefChi * rhsVal; | |
1901 | } | ||
1902 | |||
1903 | ✗ | for (int l=0; l<m_dimOrthComp; l++) { | |
1904 | ✗ | for(int m=0; m<m_dimOrthComp; m++) { | |
1905 | ✗ | Psi[l*m_dimOrthComp+m] = Psi1[l*m_dimOrthComp+m] - m_coefChi*Psi2[l*m_dimOrthComp+m]; | |
1906 | ✗ | if(m==l) { | |
1907 | ✗ | Psi[l*m_dimOrthComp + l] = Psi[l*m_dimOrthComp + l] - m_eigenValue[i]; | |
1908 | } | ||
1909 | } | ||
1910 | } | ||
1911 | ✗ | solveOrthComp(Psi, tmpRhs, alpha, tol, maxIt); | |
1912 | |||
1913 | ✗ | for(int l=0; l<m_dimOrthComp; l++) { | |
1914 | ✗ | rPhi[i].axpy(alpha[l],m_orthComp[l]); | |
1915 | } | ||
1916 | |||
1917 | ✗ | FPhiI.destroy(); | |
1918 | ✗ | FPhiG.destroy(); | |
1919 | } | ||
1920 | ✗ | tmpF.destroy(); | |
1921 | |||
1922 | ✗ | delete [] Psi1; | |
1923 | ✗ | delete [] Psi2; | |
1924 | ✗ | delete [] Psi; | |
1925 | ✗ | delete [] tmpRhs; | |
1926 | ✗ | delete [] alpha; | |
1927 | |||
1928 | |||
1929 | } | ||
1930 | |||
1931 | |||
1932 | ✗ | double dt = FelisceParam::instance().timeStep; | |
1933 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
1934 | ✗ | m_basis[i].axpy(dt,newPhi[i]); | |
1935 | ✗ | newPhi[i].destroy(); | |
1936 | |||
1937 | ✗ | if(m_useImprovedRec==true) { | |
1938 | ✗ | m_basis[i].axpy(dt,rPhi[i]); | |
1939 | ✗ | rPhi[i].destroy(); | |
1940 | } | ||
1941 | } | ||
1942 | |||
1943 | ✗ | MGS(); | |
1944 | ✗ | if(m_useImprovedRec==true) { | |
1945 | ✗ | MGS(m_orthComp); | |
1946 | } | ||
1947 | |||
1948 | ✗ | if (FelisceParam::instance().writeBasisEvolution) | |
1949 | ✗ | writeMode(m_fstransient->iteration); | |
1950 | |||
1951 | } | ||
1952 | |||
1953 | |||
1954 | ✗ | void EigenProblemALP::setPotential() | |
1955 | { | ||
1956 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::setPotential()\n"); | |
1957 | |||
1958 | ✗ | int Nm = FelisceParam::instance().numApproxMode; | |
1959 | ✗ | int nCutOff = FelisceParam::instance().nCutOff; | |
1960 | |||
1961 | ✗ | m_initPot.duplicateFrom(m_basis[0]); | |
1962 | ✗ | m_initPot.copyFrom(m_U_0); | |
1963 | |||
1964 | ✗ | int sizePb = -1; | |
1965 | ✗ | std::vector<PetscVector> lagMult; | |
1966 | ✗ | std::vector<PetscVector> errorRep; | |
1967 | ✗ | if (m_problem == 0) | |
1968 | { // FKPP | ||
1969 | ✗ | sizePb = 1; | |
1970 | } | ||
1971 | ✗ | else if (m_problem == 1) | |
1972 | { // Monodomain | ||
1973 | ✗ | sizePb = 2; | |
1974 | } | ||
1975 | ✗ | else if (m_problem == 2) | |
1976 | { // Bidomain | ||
1977 | ✗ | sizePb = 3; | |
1978 | } | ||
1979 | else | ||
1980 | ✗ | FEL_ERROR("Problem not found."); | |
1981 | ✗ | lagMult.resize(sizePb); | |
1982 | ✗ | errorRep.resize(sizePb); | |
1983 | |||
1984 | ✗ | for (int i=0; i<sizePb; i++) { | |
1985 | ✗ | lagMult[i].duplicateFrom(m_basis[0]); | |
1986 | ✗ | errorRep[i].duplicateFrom(m_basis[0]); | |
1987 | } | ||
1988 | |||
1989 | ✗ | PetscVector tmpVec; | |
1990 | ✗ | tmpVec.duplicateFrom(m_basis[0]); | |
1991 | |||
1992 | ✗ | double errorU = 1.; | |
1993 | ✗ | double errorW = 1.; | |
1994 | ✗ | double errorUe = 1.; | |
1995 | |||
1996 | ✗ | std::vector<double*> coeffBeta; | |
1997 | ✗ | coeffBeta.resize(sizePb); | |
1998 | |||
1999 | ✗ | if (m_beta == nullptr) | |
2000 | ✗ | m_beta = new double[Nm]; | |
2001 | ✗ | projectOnBasis(m_U_0,m_beta,true,Nm); | |
2002 | ✗ | m_solutionInitialized = true; | |
2003 | ✗ | coeffBeta[0] = m_beta; | |
2004 | |||
2005 | ✗ | errorRep[0].copyFrom(m_U_0); | |
2006 | ✗ | for (int i=0; i<Nm; i++) { | |
2007 | ✗ | double coef = -m_beta[i]; | |
2008 | ✗ | errorRep[0].axpy(coef,m_basis[i]); | |
2009 | } | ||
2010 | ✗ | mult(m_Matrix[m_idG],errorRep[0],tmpVec); | |
2011 | ✗ | dot(errorRep[0],tmpVec,&errorU); | |
2012 | // errorU = std::sqrt(errorU)/Nm; | ||
2013 | |||
2014 | ✗ | if (m_problem > 0) { | |
2015 | ✗ | if (m_mu == nullptr) | |
2016 | ✗ | m_mu = new double[Nm]; | |
2017 | ✗ | projectOnBasis(m_W_0,m_mu,true,Nm); | |
2018 | ✗ | coeffBeta[1] = m_mu; | |
2019 | |||
2020 | ✗ | errorRep[1].copyFrom(m_W_0); | |
2021 | ✗ | for (int i=0; i<Nm; i++) { | |
2022 | ✗ | double coef = -m_mu[i]; | |
2023 | ✗ | errorRep[1].axpy(coef,m_basis[i]); | |
2024 | } | ||
2025 | ✗ | mult(m_Matrix[m_idG],errorRep[1],tmpVec); | |
2026 | ✗ | dot(errorRep[1],tmpVec,&errorW); | |
2027 | // errorW = std::sqrt(errorW)/Nm; | ||
2028 | } | ||
2029 | ✗ | if (m_problem == 2) { | |
2030 | ✗ | if (m_xi == nullptr) | |
2031 | ✗ | m_xi = new double[Nm]; | |
2032 | ✗ | projectOnBasis(m_Ue_0,m_xi,true,Nm); | |
2033 | ✗ | coeffBeta[2] = m_xi; | |
2034 | |||
2035 | ✗ | errorRep[2].copyFrom(m_Ue_0); | |
2036 | ✗ | for (int i=0; i<Nm; i++) { | |
2037 | ✗ | double coef = -m_xi[i]; | |
2038 | ✗ | errorRep[2].axpy(coef,m_basis[i]); | |
2039 | } | ||
2040 | ✗ | mult(m_Matrix[m_idG],errorRep[2],tmpVec); | |
2041 | ✗ | dot(errorRep[2],tmpVec,&errorUe); | |
2042 | // errorUe = std::sqrt(errorUe)/Nm; | ||
2043 | } | ||
2044 | |||
2045 | ✗ | for (int i=0; i<sizePb; i++) { | |
2046 | ✗ | lagMult[i].copyFrom(errorRep[i]); | |
2047 | ✗ | lagMult[i].scale(-1.); | |
2048 | } | ||
2049 | |||
2050 | ✗ | PetscVector dLdU; | |
2051 | ✗ | dLdU.duplicateFrom(m_basis[0]); | |
2052 | |||
2053 | ✗ | PetscVector phi_ij; | |
2054 | ✗ | phi_ij.duplicateFrom(m_basis[0]); | |
2055 | |||
2056 | ✗ | PetscVector dUphi; | |
2057 | ✗ | dUphi.duplicateFrom(m_basis[0]); | |
2058 | |||
2059 | ✗ | PetscVector dU; | |
2060 | ✗ | dU.duplicateFrom(m_basis[0]); | |
2061 | |||
2062 | ✗ | PetscVector dUphiTG; | |
2063 | ✗ | dUphiTG.duplicateFrom(m_basis[0]); | |
2064 | ✗ | std::vector<PetscVector> lKeps; | |
2065 | ✗ | lKeps.resize(sizePb); | |
2066 | ✗ | for (int i=0; i<sizePb; i++) { | |
2067 | ✗ | lKeps[i].duplicateFrom(m_basis[0]); | |
2068 | } | ||
2069 | |||
2070 | ✗ | int numIter = 0; | |
2071 | ✗ | double step = 0.25; // 1.e-1; | |
2072 | std::array<double, 3> k; | ||
2073 | ✗ | k[0] = 50.; | |
2074 | ✗ | k[1] = 10.; | |
2075 | ✗ | k[2] = 10.; | |
2076 | |||
2077 | ✗ | double** q = new double* [sizePb]; | |
2078 | ✗ | for (int iPb=0; iPb<sizePb; iPb++) { | |
2079 | ✗ | q[iPb] = new double[nCutOff]; | |
2080 | } | ||
2081 | ✗ | double** theta = new double* [nCutOff]; | |
2082 | ✗ | for (int i=0; i<nCutOff; i++) { | |
2083 | ✗ | theta[i] = new double[nCutOff]; | |
2084 | } | ||
2085 | |||
2086 | ✗ | PetscPrintf(PETSC_COMM_WORLD,"numIter = %i \n",numIter); | |
2087 | ✗ | PetscPrintf(PETSC_COMM_WORLD,"error = %e, %e, %e \n",errorU,errorW,errorUe); | |
2088 | |||
2089 | ✗ | while ( (errorU > 1.e-08) && (errorW > 1.e-08) && (errorUe > 1.e-08) && (numIter < 5000) ) | |
2090 | { | ||
2091 | // q[iPb]_j = <lagMult[iPb]+k*eps[iPb], phi_j> | ||
2092 | ✗ | for (int iPb=0; iPb<sizePb; iPb++) { | |
2093 | ✗ | lKeps[iPb].copyFrom(lagMult[iPb]); | |
2094 | ✗ | lKeps[iPb].axpy(k[iPb],errorRep[iPb]); | |
2095 | ✗ | projectOnBasis(lKeps[iPb], q[iPb], true, nCutOff); | |
2096 | } | ||
2097 | |||
2098 | // dL/dU = (U - u0) | ||
2099 | ✗ | dLdU.copyFrom(m_initPot); | |
2100 | ✗ | dLdU.axpy(-1.,m_U_0); | |
2101 | ✗ | double reg = 1.; | |
2102 | ✗ | dLdU.scale(reg); | |
2103 | // dL/dU -= \chi * \sum \sum ( sum_pb(beta_i q_j) / (lambda_j - lambda_i) phi_i phi_j | ||
2104 | ✗ | for (int i=0; i<Nm; i++) { | |
2105 | ✗ | for (int j=0; j<nCutOff; j++) { | |
2106 | ✗ | if ( std::fabs(m_eigenValue[j] - m_eigenValue[i]) > 1.e-1 ) { | |
2107 | ✗ | pointwiseMult(phi_ij, m_basis[i], m_basis[j]); | |
2108 | ✗ | double coef = 0.; | |
2109 | ✗ | for (int iPb=0; iPb<sizePb; iPb++) { | |
2110 | ✗ | coef += coeffBeta[iPb][i]*q[iPb][j]; | |
2111 | } | ||
2112 | ✗ | coef = - m_coefChi * coef/(m_eigenValue[j] - m_eigenValue[i]); | |
2113 | ✗ | dLdU.axpy(coef,phi_ij); | |
2114 | } | ||
2115 | } | ||
2116 | } | ||
2117 | |||
2118 | // dU = -s dL/dU | ||
2119 | ✗ | dU.set(0.); | |
2120 | ✗ | dU.axpy(-step,dLdU); | |
2121 | |||
2122 | // theta_ij = <dU phi_i, phi_j> | ||
2123 | ✗ | for (int i=0; i<nCutOff; i++) { | |
2124 | ✗ | pointwiseMult(dUphi, dU, m_basis[i]); | |
2125 | ✗ | mult(m_Matrix[m_idG], dUphi, dUphiTG); | |
2126 | ✗ | for (int j=0; j<=i; j++) { | |
2127 | ✗ | dot(dUphiTG, m_basis[j], &theta[i][j]); | |
2128 | ✗ | if (i != j) | |
2129 | ✗ | theta[j][i] = theta[i][j]; | |
2130 | } | ||
2131 | } | ||
2132 | |||
2133 | // Update phi | ||
2134 | ✗ | for (int i=0; i<nCutOff; i++) { | |
2135 | ✗ | for (int j=0; j<nCutOff; j++) { | |
2136 | ✗ | if ( std::fabs(m_eigenValue[j] - m_eigenValue[i]) > 1.e-1 ) { | |
2137 | ✗ | double coef = m_coefChi * theta[i][j]/(m_eigenValue[j] - m_eigenValue[i]); | |
2138 | ✗ | m_basis[i].axpy(coef, m_basis[j]); | |
2139 | } | ||
2140 | } | ||
2141 | } | ||
2142 | ✗ | MGS(nCutOff); | |
2143 | |||
2144 | // Update lambda | ||
2145 | ✗ | for (int i=0; i<nCutOff; i++) { | |
2146 | ✗ | m_eigenValue[i] -= m_coefChi * theta[i][i]; | |
2147 | } | ||
2148 | |||
2149 | // Update beta | ||
2150 | ✗ | projectOnBasis(m_U_0,m_beta,true,Nm); | |
2151 | ✗ | if (m_problem > 0) { | |
2152 | // Update mu | ||
2153 | ✗ | projectOnBasis(m_W_0,m_mu,true,Nm); | |
2154 | } | ||
2155 | ✗ | if (m_problem == 2) { | |
2156 | // Update xi | ||
2157 | ✗ | projectOnBasis(m_Ue_0,m_xi,true,Nm); | |
2158 | } | ||
2159 | |||
2160 | // Compute error | ||
2161 | ✗ | errorRep[0].copyFrom(m_U_0); | |
2162 | ✗ | for (int i=0; i<Nm; i++) { | |
2163 | ✗ | errorRep[0].axpy(-1.*m_beta[i],m_basis[i]); | |
2164 | } | ||
2165 | ✗ | mult(m_Matrix[m_idG],errorRep[0],tmpVec); | |
2166 | ✗ | dot(errorRep[0],tmpVec,&errorU); | |
2167 | // errorU = std::sqrt(errorU)/Nm; | ||
2168 | ✗ | if (m_problem > 0) { | |
2169 | ✗ | errorRep[1].copyFrom(m_W_0); | |
2170 | ✗ | for (int i=0; i<Nm; i++) { | |
2171 | ✗ | errorRep[1].axpy(-1.*m_mu[i],m_basis[i]); | |
2172 | } | ||
2173 | ✗ | mult(m_Matrix[m_idG],errorRep[1],tmpVec); | |
2174 | ✗ | dot(errorRep[1],tmpVec,&errorW); | |
2175 | // errorW = std::sqrt(errorW)/Nm; | ||
2176 | } | ||
2177 | ✗ | if (m_problem == 2) { | |
2178 | ✗ | errorRep[2].copyFrom(m_Ue_0); | |
2179 | ✗ | for (int i=0; i<Nm; i++) { | |
2180 | ✗ | errorRep[2].axpy(-1.*m_xi[i],m_basis[i]); | |
2181 | } | ||
2182 | ✗ | mult(m_Matrix[m_idG],errorRep[2],tmpVec); | |
2183 | ✗ | dot(errorRep[2],tmpVec,&errorUe); | |
2184 | // errorUe = std::sqrt(errorUe)/Nm; | ||
2185 | } | ||
2186 | |||
2187 | // Update Lagrangian Multiplicator | ||
2188 | ✗ | for (int iPb=0; iPb<sizePb; iPb++) { | |
2189 | ✗ | lagMult[iPb].axpy(step, errorRep[iPb]); | |
2190 | } | ||
2191 | |||
2192 | // Update initial potential | ||
2193 | ✗ | m_initPot.axpy(1.,dU); | |
2194 | |||
2195 | ✗ | numIter++; | |
2196 | |||
2197 | ✗ | PetscPrintf(PETSC_COMM_WORLD,"numIter = %i \n",numIter); | |
2198 | ✗ | PetscPrintf(PETSC_COMM_WORLD,"error = %e, %e, %e \n",errorU,errorW,errorUe); | |
2199 | } | ||
2200 | |||
2201 | ✗ | for (int iPb=0; iPb<sizePb; iPb++) { | |
2202 | ✗ | lagMult[iPb].destroy(); | |
2203 | ✗ | errorRep[iPb].destroy(); | |
2204 | ✗ | lKeps[iPb].destroy(); | |
2205 | } | ||
2206 | ✗ | dLdU.destroy(); | |
2207 | ✗ | phi_ij.destroy(); | |
2208 | ✗ | dUphi.destroy(); | |
2209 | ✗ | dU.destroy(); | |
2210 | ✗ | dUphiTG.destroy(); | |
2211 | ✗ | tmpVec.destroy(); | |
2212 | |||
2213 | ✗ | for (int i=0; i<sizePb; i++) { | |
2214 | ✗ | delete [] q[i]; | |
2215 | } | ||
2216 | ✗ | delete [] q; | |
2217 | ✗ | for (int i=0; i<nCutOff; i++) { | |
2218 | ✗ | delete [] theta[i]; | |
2219 | } | ||
2220 | ✗ | delete [] theta; | |
2221 | |||
2222 | // Write initial potential in Ensight file | ||
2223 | ✗ | double* tmpSolToSave = nullptr; | |
2224 | ✗ | tmpSolToSave = new double[m_numDof]; | |
2225 | int rankProc; | ||
2226 | ✗ | MPI_Comm_rank(m_petscComm,&rankProc); | |
2227 | ✗ | fromVecToDoubleStar(tmpSolToSave, m_initPot, rankProc, 1); | |
2228 | ✗ | writeEnsightVector(tmpSolToSave, 0, "initialPotential"); | |
2229 | ✗ | delete [] tmpSolToSave; | |
2230 | |||
2231 | ✗ | std::string fileName = FelisceParam::instance().resultDir + "/eigenValue"; | |
2232 | ✗ | viewALP(m_eigenValue,m_dimRomBasis,fileName); | |
2233 | |||
2234 | ✗ | checkBasis(Nm); | |
2235 | } | ||
2236 | |||
2237 | // Modified Gram-Schmidt (see Golub & Van Loan) | ||
2238 | ✗ | void EigenProblemALP::MGS(int size) | |
2239 | { | ||
2240 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::MGS(int)\n"); | |
2241 | |||
2242 | ✗ | if (size == 0) | |
2243 | ✗ | size = m_dimRomBasis; | |
2244 | |||
2245 | ✗ | for(int iBasis=0; iBasis<size; iBasis++) | |
2246 | { | ||
2247 | ✗ | PetscVector tmpVec; | |
2248 | ✗ | tmpVec.duplicateFrom(m_basis[0]); | |
2249 | ✗ | mult(m_Matrix[m_idG],m_basis[iBasis],tmpVec); | |
2250 | ✗ | double rii = 0.0; | |
2251 | ✗ | dot(tmpVec,m_basis[iBasis],&rii); | |
2252 | ✗ | rii = 1.0/std::sqrt(rii); | |
2253 | ✗ | m_basis[iBasis].scale(rii); | |
2254 | |||
2255 | ✗ | for(int j=iBasis+1; j<size; j++) { | |
2256 | ✗ | double rij = 0.0; | |
2257 | ✗ | dot(tmpVec,m_basis[j],&rij); | |
2258 | ✗ | rij = -1.0 * rij; | |
2259 | ✗ | m_basis[j].axpy(rij,m_basis[iBasis]); | |
2260 | } | ||
2261 | ✗ | tmpVec.destroy(); | |
2262 | } | ||
2263 | } | ||
2264 | |||
2265 | |||
2266 | // Modified Gram-Schmidt (for an extra-space, orthonormal to the basis too) | ||
2267 | // 1 - orthonormalize w.r.t. basis, 2 - orthonormalize extraspace; | ||
2268 | ✗ | void EigenProblemALP::MGS(std::vector<PetscVector>& extraSpace) { | |
2269 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::MGS(std::vector<Vec>)\n"); | |
2270 | |||
2271 | ✗ | for(int j=0; j<m_dimOrthComp; j++) { | |
2272 | ✗ | PetscVector tmpVec; | |
2273 | ✗ | tmpVec.duplicateFrom(m_basis[0]); | |
2274 | ✗ | mult(m_Matrix[m_idG],extraSpace[j],tmpVec); | |
2275 | double* Sij; | ||
2276 | ✗ | Sij = new double[m_dimRomBasis]; | |
2277 | ✗ | for(int i =0; i<m_dimRomBasis; i++) { | |
2278 | ✗ | double sij = 0.0; | |
2279 | ✗ | dot(tmpVec,m_basis[i],&sij); | |
2280 | ✗ | Sij[i] = -1.0*sij; | |
2281 | } | ||
2282 | double* Rjh; | ||
2283 | ✗ | Rjh = new double[j]; | |
2284 | ✗ | for(int h=0; h<j; h++) { | |
2285 | ✗ | double rjh = 0.0; | |
2286 | ✗ | dot(tmpVec,extraSpace[h],&rjh); | |
2287 | ✗ | Rjh[h] = -1.0*rjh; | |
2288 | } | ||
2289 | |||
2290 | ✗ | for(int i=0; i<m_dimRomBasis; i++) { | |
2291 | ✗ | double wheight = Sij[i]; | |
2292 | ✗ | extraSpace[j].axpy(wheight,m_basis[i]); | |
2293 | } | ||
2294 | ✗ | for(int h=0; h<j; h++) { | |
2295 | ✗ | double wheight = Rjh[h]; | |
2296 | ✗ | extraSpace[j].axpy(wheight,extraSpace[h]); | |
2297 | } | ||
2298 | |||
2299 | ✗ | PetscVector tmpNorm; | |
2300 | ✗ | tmpNorm.duplicateFrom(m_basis[0]); | |
2301 | ✗ | mult(m_Matrix[m_idG],extraSpace[j],tmpNorm); | |
2302 | ✗ | double rjj = 0.0; | |
2303 | ✗ | dot(tmpNorm,extraSpace[j],&rjj); | |
2304 | ✗ | rjj = 1.0/std::sqrt(rjj); | |
2305 | ✗ | extraSpace[j].scale(rjj); | |
2306 | |||
2307 | ✗ | tmpVec.destroy(); | |
2308 | ✗ | tmpNorm.destroy(); | |
2309 | ✗ | delete [] Rjh; | |
2310 | ✗ | delete [] Sij; | |
2311 | } | ||
2312 | } | ||
2313 | |||
2314 | ✗ | void EigenProblemALP::updateTensor() { | |
2315 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::updateTensor()\n"); | |
2316 | |||
2317 | ✗ | double dt = FelisceParam::instance().timeStep; | |
2318 | |||
2319 | ✗ | switch (m_problem) { | |
2320 | ✗ | case 0: { | |
2321 | ✗ | double deltaT[m_size3]; | |
2322 | // T^{n+1} = T^n + dt * [T^n, M^n]^{(3)} | ||
2323 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2324 | ✗ | for (int j=0; j<i+1; j++) { | |
2325 | ✗ | for (int k=0; k<j+1; k++) { | |
2326 | ✗ | deltaT[thirdOrderGlobalIndex(i,j,k)] = 0.; | |
2327 | ✗ | for (int l=0; l<m_dimRomBasis; l++) { | |
2328 | // delta T_ijk = sum_l (M_il * T_ljk + M_jl * T_ilk + M_kl * T_ijl ) | ||
2329 | ✗ | deltaT[thirdOrderGlobalIndex(i,j,k)] += m_matrixM[i][l] * m_tensorT[thirdOrderGlobalIndex(l,j,k)]; | |
2330 | ✗ | deltaT[thirdOrderGlobalIndex(i,j,k)] += m_matrixM[j][l] * m_tensorT[thirdOrderGlobalIndex(i,l,k)]; | |
2331 | ✗ | deltaT[thirdOrderGlobalIndex(i,j,k)] += m_matrixM[k][l] * m_tensorT[thirdOrderGlobalIndex(i,j,l)]; | |
2332 | } | ||
2333 | } | ||
2334 | } | ||
2335 | } | ||
2336 | ✗ | for (int idT=0; idT<m_size3; idT++) | |
2337 | ✗ | m_tensorT[idT] += dt * deltaT[idT]; | |
2338 | ✗ | break; | |
2339 | } | ||
2340 | ✗ | case 1: | |
2341 | case 2: { | ||
2342 | ✗ | switch (m_tensorOrder) { | |
2343 | ✗ | case 3: { | |
2344 | ✗ | double deltaB[m_size2]; | |
2345 | // B^{n+1} = B^n + dt * [B^n, M^n]^{(2)} | ||
2346 | ✗ | double deltaE[m_size2]; | |
2347 | // E^{n+1} = E^n + dt * [E^n, M^n]^{(2)} | ||
2348 | ✗ | double deltaEs[m_size2]; | |
2349 | // Es^{n+1} = Es^n + dt * [Es^n, M^n]^{(2)} | ||
2350 | ✗ | double deltaQ[m_size2+m_dimRomBasis]; | |
2351 | // Q^{n+1} = Q^n + dt * [Q^n, M^n]^{(2)} | ||
2352 | ✗ | double deltaT[m_size3]; | |
2353 | // T^{n+1} = T^n + dt * [T^n, M^n]^{(3)} | ||
2354 | ✗ | double** deltaU = new double*[m_dimRomBasis]; | |
2355 | ✗ | for (int i=0; i<m_dimRomBasis; i++) | |
2356 | ✗ | deltaU[i] = new double[m_size2]; | |
2357 | // U^{n+1} = U^n + dt * [U^n, M^n]^{(3)} | ||
2358 | |||
2359 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2360 | ✗ | for (int j=0; j<i+1; j++) { | |
2361 | ✗ | deltaB[secondOrderGlobalIndex(i,j)] = 0.; | |
2362 | ✗ | deltaE[secondOrderGlobalIndex(i,j)] = 0.; | |
2363 | ✗ | deltaEs[secondOrderGlobalIndex(i,j)] = 0.; | |
2364 | ✗ | if (m_problem == 2) // bidomain | |
2365 | ✗ | deltaQ[secondOrderGlobalIndex(i,j)] = 0.; | |
2366 | |||
2367 | ✗ | for (int l=0; l<m_dimRomBasis; l++) { | |
2368 | // delta B_ij = sum_l ( M_il * B_lj + M_jl * B_il ) | ||
2369 | ✗ | deltaB[secondOrderGlobalIndex(i,j)] += m_matrixM[i][l] * m_tensorB[secondOrderGlobalIndex(l,j)]; | |
2370 | ✗ | deltaB[secondOrderGlobalIndex(i,j)] += m_matrixM[j][l] * m_tensorB[secondOrderGlobalIndex(i,l)]; | |
2371 | // delta E_ij = sum_l ( M_il * E_lj + M_jl * E_il ) | ||
2372 | ✗ | deltaE[secondOrderGlobalIndex(i,j)] += m_matrixM[i][l] * m_tensorE[secondOrderGlobalIndex(l,j)]; | |
2373 | ✗ | deltaE[secondOrderGlobalIndex(i,j)] += m_matrixM[j][l] * m_tensorE[secondOrderGlobalIndex(i,l)]; | |
2374 | // delta Es_ij = sum_l ( M_il * Es_lj + M_jl * Es_il ) | ||
2375 | ✗ | deltaEs[secondOrderGlobalIndex(i,j)] += m_matrixM[i][l] * m_tensorEs[secondOrderGlobalIndex(l,j)]; | |
2376 | ✗ | deltaEs[secondOrderGlobalIndex(i,j)] += m_matrixM[j][l] * m_tensorEs[secondOrderGlobalIndex(i,l)]; | |
2377 | ✗ | if (m_problem == 2) { // bidomain | |
2378 | // delta Q_ij = sum_l ( M_il * Q_lj + M_jl * Q_il ) | ||
2379 | ✗ | deltaQ[secondOrderGlobalIndex(i,j)] += m_matrixM[i][l] * m_tensorQ[secondOrderGlobalIndex(l,j)]; | |
2380 | ✗ | deltaQ[secondOrderGlobalIndex(i,j)] += m_matrixM[j][l] * m_tensorQ[secondOrderGlobalIndex(i,l)]; | |
2381 | } | ||
2382 | |||
2383 | } | ||
2384 | ✗ | for (int k=0; k<j+1; k++) { | |
2385 | ✗ | deltaT[thirdOrderGlobalIndex(i,j,k)] = 0.; | |
2386 | ✗ | for (int l=0; l<m_dimRomBasis; l++) { | |
2387 | // delta T_ijk = sum_l (M_il * T_ljk + M_jl * T_ilk + M_kl * T_ijl ) | ||
2388 | ✗ | deltaT[thirdOrderGlobalIndex(i,j,k)] += m_matrixM[i][l] * m_tensorT[thirdOrderGlobalIndex(l,j,k)]; | |
2389 | ✗ | deltaT[thirdOrderGlobalIndex(i,j,k)] += m_matrixM[j][l] * m_tensorT[thirdOrderGlobalIndex(i,l,k)]; | |
2390 | ✗ | deltaT[thirdOrderGlobalIndex(i,j,k)] += m_matrixM[k][l] * m_tensorT[thirdOrderGlobalIndex(i,j,l)]; | |
2391 | } | ||
2392 | } | ||
2393 | } | ||
2394 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
2395 | ✗ | for (int k=0; k<j+1; k++) { | |
2396 | ✗ | deltaU[i][secondOrderGlobalIndex(j,k)] = 0.; | |
2397 | ✗ | for (int l=0; l<m_dimRomBasis; l++) { | |
2398 | // delta U_ijk = sum_l (M_il * U_ljk + M_jl * U_ilk + M_kl * U_ijl ) | ||
2399 | ✗ | deltaU[i][secondOrderGlobalIndex(j,k)] += m_matrixM[i][l] * m_tensorU[l][secondOrderGlobalIndex(j,k)]; | |
2400 | ✗ | deltaU[i][secondOrderGlobalIndex(j,k)] += m_matrixM[j][l] * m_tensorU[i][secondOrderGlobalIndex(l,k)]; | |
2401 | ✗ | deltaU[i][secondOrderGlobalIndex(j,k)] += m_matrixM[k][l] * m_tensorU[i][secondOrderGlobalIndex(j,l)]; | |
2402 | } | ||
2403 | } | ||
2404 | } | ||
2405 | ✗ | if (m_problem == 2) { | |
2406 | ✗ | deltaQ[secondOrderGlobalIndex(m_dimRomBasis,i)] = 0.; | |
2407 | ✗ | for (int l=0; l<m_dimRomBasis; l++) { | |
2408 | // delta Q_Nj = sum_l ( M_jl * Q_lj ) | ||
2409 | ✗ | deltaQ[secondOrderGlobalIndex(m_dimRomBasis,i)] += m_matrixM[i][l] * m_tensorQ[secondOrderGlobalIndex(m_dimRomBasis,l)]; | |
2410 | } | ||
2411 | } | ||
2412 | } | ||
2413 | ✗ | for (int i=0; i<m_size2; i++) { | |
2414 | ✗ | m_tensorB[i] += dt * deltaB[i]; | |
2415 | ✗ | m_tensorE[i] += dt * deltaE[i]; | |
2416 | ✗ | m_tensorEs[i] += dt * deltaEs[i]; | |
2417 | } | ||
2418 | ✗ | if (m_problem == 2) { | |
2419 | ✗ | for (int i=0; i<m_size2+m_dimRomBasis; i++) | |
2420 | ✗ | m_tensorQ[i] += dt * deltaQ[i]; | |
2421 | } | ||
2422 | ✗ | for (int i=0; i<m_size3; i++) | |
2423 | ✗ | m_tensorT[i] += dt * deltaT[i]; | |
2424 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2425 | ✗ | for (int j=0; j<m_size2; j++) | |
2426 | ✗ | m_tensorU[i][j] += dt * deltaU[i][j]; | |
2427 | } | ||
2428 | ✗ | for (int i=0; i<m_dimRomBasis; i++) | |
2429 | ✗ | delete [] deltaU[i]; | |
2430 | ✗ | delete [] deltaU; | |
2431 | ✗ | break; | |
2432 | } | ||
2433 | ✗ | case 4: { | |
2434 | ✗ | double deltaB[m_size2]; | |
2435 | // B^{n+1} = B^n + dt * [B^n, M^n]^{(2)} | ||
2436 | ✗ | double deltaE[m_size2]; | |
2437 | // E^{n+1} = E^n + dt * [E^n, M^n]^{(2)} | ||
2438 | ✗ | double deltaQ[m_size2+m_dimRomBasis]; | |
2439 | // Q^{n+1} = Q^n + dt * [Q^n, M^n]^{(2)} | ||
2440 | ✗ | double deltaT[m_size3]; | |
2441 | // T^{n+1} = T^n + dt * [T^n, M^n]^{(3)} | ||
2442 | ✗ | double deltaTs[m_size3]; | |
2443 | // Ts^{n+1} = Ts^n + dt * [Ts^n, M^n]^{(3)} | ||
2444 | ✗ | double deltaY[m_size4]; | |
2445 | // Y^{n+1} = Y^n + dt * [Y^n, M^n]^{(4)} | ||
2446 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2447 | ✗ | for (int j=0; j<i+1; j++) { | |
2448 | ✗ | deltaB[secondOrderGlobalIndex(i,j)] = 0.; | |
2449 | ✗ | if (m_problem == 2) { // bidomain | |
2450 | ✗ | deltaE[secondOrderGlobalIndex(i,j)] = 0.; | |
2451 | ✗ | deltaQ[secondOrderGlobalIndex(i,j)] = 0.; | |
2452 | } | ||
2453 | ✗ | for (int l=0; l<m_dimRomBasis; l++) { | |
2454 | // delta B_ijk = sum_l (M_il * B_lj + M_jl * B_il ) | ||
2455 | ✗ | deltaB[secondOrderGlobalIndex(i,j)] += m_matrixM[i][l] * m_tensorB[secondOrderGlobalIndex(l,j)]; | |
2456 | ✗ | deltaB[secondOrderGlobalIndex(i,j)] += m_matrixM[j][l] * m_tensorB[secondOrderGlobalIndex(i,l)]; | |
2457 | ✗ | if (m_problem == 2) { // bidomain | |
2458 | // delta E_ijk = sum_l (M_il * E_lj + M_jl * E_il ) | ||
2459 | ✗ | deltaE[secondOrderGlobalIndex(i,j)] += m_matrixM[i][l] * m_tensorE[secondOrderGlobalIndex(l,j)]; | |
2460 | ✗ | deltaE[secondOrderGlobalIndex(i,j)] += m_matrixM[j][l] * m_tensorE[secondOrderGlobalIndex(i,l)]; | |
2461 | // delta Q_ijk = sum_l (M_il * Q_lj + M_jl * Q_il ) | ||
2462 | ✗ | deltaQ[secondOrderGlobalIndex(i,j)] += m_matrixM[i][l] * m_tensorQ[secondOrderGlobalIndex(l,j)]; | |
2463 | ✗ | deltaQ[secondOrderGlobalIndex(i,j)] += m_matrixM[j][l] * m_tensorQ[secondOrderGlobalIndex(i,l)]; | |
2464 | } | ||
2465 | } | ||
2466 | ✗ | for (int k=0; k<j+1; k++) { | |
2467 | ✗ | deltaT[thirdOrderGlobalIndex(i,j,k)] = 0.; | |
2468 | ✗ | deltaTs[thirdOrderGlobalIndex(i,j,k)] = 0.; | |
2469 | ✗ | for (int l=0; l<m_dimRomBasis; l++) { | |
2470 | // delta T_ijk = sum_l (M_il * T_ljk + M_jl * T_ilk + M_kl * T_ijl ) | ||
2471 | ✗ | deltaT[thirdOrderGlobalIndex(i,j,k)] += m_matrixM[i][l] * m_tensorT[thirdOrderGlobalIndex(l,j,k)]; | |
2472 | ✗ | deltaT[thirdOrderGlobalIndex(i,j,k)] += m_matrixM[j][l] * m_tensorT[thirdOrderGlobalIndex(i,l,k)]; | |
2473 | ✗ | deltaT[thirdOrderGlobalIndex(i,j,k)] += m_matrixM[k][l] * m_tensorT[thirdOrderGlobalIndex(i,j,l)]; | |
2474 | |||
2475 | ✗ | deltaTs[thirdOrderGlobalIndex(i,j,k)] += m_matrixM[i][l] * m_tensorTs[thirdOrderGlobalIndex(l,j,k)]; | |
2476 | ✗ | deltaTs[thirdOrderGlobalIndex(i,j,k)] += m_matrixM[j][l] * m_tensorTs[thirdOrderGlobalIndex(i,l,k)]; | |
2477 | ✗ | deltaTs[thirdOrderGlobalIndex(i,j,k)] += m_matrixM[k][l] * m_tensorTs[thirdOrderGlobalIndex(i,j,l)]; | |
2478 | } | ||
2479 | ✗ | for (int h=0; h<k+1; h++) { | |
2480 | ✗ | deltaY[fourthOrderGlobalIndex(i,j,k,h)] = 0.; | |
2481 | ✗ | for (int l=0; l<m_dimRomBasis; l++) { | |
2482 | // delta Y_ijkh = sum_l ( M_il * Y_ljkh + M_jl * Y_ilkh + M_kl * Y_ijlh + M_hl * Y_ijkl ) | ||
2483 | ✗ | deltaY[fourthOrderGlobalIndex(i,j,k,h)] += m_matrixM[i][l] * m_tensorY[fourthOrderGlobalIndex(l,j,k,h)]; | |
2484 | ✗ | deltaY[fourthOrderGlobalIndex(i,j,k,h)] += m_matrixM[j][l] * m_tensorY[fourthOrderGlobalIndex(i,l,k,h)]; | |
2485 | ✗ | deltaY[fourthOrderGlobalIndex(i,j,k,h)] += m_matrixM[k][l] * m_tensorY[fourthOrderGlobalIndex(i,j,l,h)]; | |
2486 | ✗ | deltaY[fourthOrderGlobalIndex(i,j,k,h)] += m_matrixM[h][l] * m_tensorY[fourthOrderGlobalIndex(i,j,k,l)]; | |
2487 | } | ||
2488 | } | ||
2489 | } | ||
2490 | } | ||
2491 | ✗ | if (m_problem == 2) { | |
2492 | ✗ | deltaQ[secondOrderGlobalIndex(m_dimRomBasis,i)] = 0.; | |
2493 | ✗ | for (int l=0; l<m_dimRomBasis; l++) { | |
2494 | // delta Q_Nj = sum_l ( M_jl * Q_lj ) | ||
2495 | ✗ | deltaQ[secondOrderGlobalIndex(m_dimRomBasis,i)] += m_matrixM[i][l] * m_tensorQ[secondOrderGlobalIndex(m_dimRomBasis,l)]; | |
2496 | } | ||
2497 | } | ||
2498 | } | ||
2499 | |||
2500 | ✗ | for (int id=0; id<m_size2; id++) | |
2501 | ✗ | m_tensorB[id] += dt * deltaB[id]; | |
2502 | ✗ | if (m_problem == 2) { | |
2503 | ✗ | for (int id=0; id<m_size2; id++) | |
2504 | ✗ | m_tensorE[id] += dt * deltaE[id]; | |
2505 | ✗ | for (int id=0; id<m_size2+m_dimRomBasis; id++) | |
2506 | ✗ | m_tensorQ[id] += dt * deltaQ[id]; | |
2507 | } | ||
2508 | ✗ | for (int id=0; id<m_size3; id++) { | |
2509 | ✗ | m_tensorT[id] += dt * deltaT[id]; | |
2510 | ✗ | m_tensorTs[id] += dt * deltaTs[id]; | |
2511 | } | ||
2512 | ✗ | for (int id=0; id<m_size4; id++) | |
2513 | ✗ | m_tensorY[id] += dt * deltaY[id]; | |
2514 | ✗ | break; | |
2515 | } | ||
2516 | ✗ | default: | |
2517 | ✗ | break; | |
2518 | } | ||
2519 | ✗ | break; | |
2520 | } | ||
2521 | ✗ | default: | |
2522 | ✗ | FEL_ERROR("Model not defined for ALP solver."); | |
2523 | ✗ | break; | |
2524 | } | ||
2525 | } | ||
2526 | |||
2527 | ✗ | void EigenProblemALP::updateBeta() { | |
2528 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::updateBeta()\n"); | |
2529 | |||
2530 | ✗ | double dt = FelisceParam::instance().timeStep; | |
2531 | ✗ | double deltaBeta[m_dimRomBasis]; | |
2532 | // beta^{n+1} = beta^n - dt * M^n * beta^n + dt * gamma^n | ||
2533 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2534 | ✗ | deltaBeta[i] = m_gamma[i]; | |
2535 | |||
2536 | ✗ | for (int h=0; h<m_dimRomBasis; h++) { | |
2537 | ✗ | deltaBeta[i] -= m_beta[h] * m_matrixM[h][i]; | |
2538 | } | ||
2539 | } | ||
2540 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2541 | ✗ | m_beta[i] += dt * deltaBeta[i]; | |
2542 | } | ||
2543 | |||
2544 | ✗ | if ( (m_problem == 1) || (m_problem == 2) ) { | |
2545 | ✗ | double deltaMu[m_dimRomBasis]; | |
2546 | // mu^{n+1} = mu^n - dt * M^n * mu^n + dt * eta^n | ||
2547 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2548 | ✗ | deltaMu[i] = m_eta[i]; | |
2549 | |||
2550 | ✗ | for (int h=0; h<m_dimRomBasis; h++) { | |
2551 | ✗ | deltaMu[i] -= m_mu[h] * m_matrixM[h][i]; | |
2552 | } | ||
2553 | } | ||
2554 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2555 | ✗ | m_mu[i] += dt * deltaMu[i]; | |
2556 | } | ||
2557 | } | ||
2558 | |||
2559 | ✗ | if (m_problem == 2) { | |
2560 | ✗ | double* newXi = new double[m_dimRomBasis+1]; | |
2561 | ✗ | double* rhsXi = new double[m_dimRomBasis+1]; | |
2562 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2563 | ✗ | newXi[i] = m_xi[i]; | |
2564 | ✗ | rhsXi[i] = 0.; | |
2565 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
2566 | ✗ | rhsXi[i] += - m_beta[j]*m_tensorE[secondOrderGlobalIndex(j,i)]; | |
2567 | } | ||
2568 | } | ||
2569 | ✗ | newXi[m_dimRomBasis] = 0.; | |
2570 | ✗ | rhsXi[m_dimRomBasis] = 0.; | |
2571 | |||
2572 | ✗ | ConjGrad(m_tensorQ, rhsXi, newXi, 1.e-09, 1000, m_dimRomBasis+1); | |
2573 | |||
2574 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2575 | ✗ | m_xi[i] = newXi[i]; | |
2576 | } | ||
2577 | ✗ | delete [] newXi; | |
2578 | ✗ | delete [] rhsXi; | |
2579 | |||
2580 | } | ||
2581 | |||
2582 | ✗ | if (FelisceParam::instance().hasSource) { | |
2583 | ✗ | for (int idS=0; idS<m_numSource; idS++) { | |
2584 | ✗ | double* newSource = new double[m_dimRomBasis]; | |
2585 | // source^{n+1} = source^n - dt * M^n * source^n | ||
2586 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2587 | ✗ | newSource[i] = 0.; | |
2588 | |||
2589 | ✗ | for (int h=0; h<m_dimRomBasis; h++) { | |
2590 | ✗ | newSource[i] += m_source[idS][h] * m_matrixM[i][h]; | |
2591 | } | ||
2592 | } | ||
2593 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2594 | ✗ | m_source[idS][i] += dt * newSource[i]; | |
2595 | } | ||
2596 | ✗ | delete [] newSource; | |
2597 | } | ||
2598 | } | ||
2599 | |||
2600 | } | ||
2601 | |||
2602 | ✗ | void EigenProblemALP::updateBetaMonolithic() { | |
2603 | ✗ | if (FelisceParam::verbose() > 10 ) | |
2604 | ✗ | PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::updateBetaMonolithic()\n"); | |
2605 | |||
2606 | ✗ | double dt = FelisceParam::instance().timeStep; | |
2607 | double value; | ||
2608 | double rhs1; | ||
2609 | double rhs2; | ||
2610 | felInt ia; | ||
2611 | ✗ | m_rhsRom.set(0.); | |
2612 | |||
2613 | // beta^{n+1} = beta^n + dt* gamma^n - dt * M * beta^n | ||
2614 | // mu^{n+1} = mu^n + dt * eta^n - dt * M * mu^n | ||
2615 | // E beta^{n+1} + Q xi^{n+1} = 0 | ||
2616 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2617 | ✗ | rhs1 = m_beta[i] + dt * m_gamma[i]; | |
2618 | ✗ | rhs2 = m_mu[i] + dt * m_eta[i]; | |
2619 | |||
2620 | ✗ | for (int h=0; h<m_dimRomBasis; h++) { | |
2621 | ✗ | rhs1 -= dt * m_beta[h] * m_matrixM[h][i]; | |
2622 | ✗ | rhs2 -= dt * m_mu[h] * m_matrixM[h][i]; | |
2623 | } | ||
2624 | |||
2625 | ✗ | ia = i; | |
2626 | ✗ | m_rhsRom.setValue(ia,rhs1,INSERT_VALUES); | |
2627 | |||
2628 | ✗ | ia = i+m_dimRomBasis; | |
2629 | ✗ | m_rhsRom.setValue(ia,rhs2,INSERT_VALUES); | |
2630 | } | ||
2631 | ✗ | m_rhsRom.assembly(); | |
2632 | |||
2633 | // MatrixRom = [ I 0 0 ] | ||
2634 | // [ 0 I 0 ] | ||
2635 | // [ E 0 Q ] | ||
2636 | |||
2637 | felInt ii; | ||
2638 | felInt jj; | ||
2639 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2640 | ✗ | value = 1.; | |
2641 | |||
2642 | ✗ | ii = i; | |
2643 | ✗ | m_matrixRom.setValues(1,&ii,1,&ii,&value,INSERT_VALUES); | |
2644 | |||
2645 | ✗ | ii = i+m_dimRomBasis; | |
2646 | ✗ | m_matrixRom.setValues(1,&ii,1,&ii,&value,INSERT_VALUES); | |
2647 | |||
2648 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
2649 | ✗ | double valueMatrix = 0.; | |
2650 | |||
2651 | ✗ | valueMatrix = m_tensorE[secondOrderGlobalIndex(i,j)]; | |
2652 | ✗ | ii = i+2*m_dimRomBasis; | |
2653 | ✗ | jj = j; | |
2654 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2655 | |||
2656 | ✗ | valueMatrix = m_tensorQ[secondOrderGlobalIndex(i,j)]; | |
2657 | ✗ | jj = j+2*m_dimRomBasis; | |
2658 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2659 | } | ||
2660 | } | ||
2661 | ✗ | ii = 3*m_dimRomBasis; | |
2662 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
2663 | ✗ | jj = j+2*m_dimRomBasis; | |
2664 | ✗ | double valueMatrix = m_tensorQ[secondOrderGlobalIndex(j,m_dimRomBasis)]; | |
2665 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2666 | ✗ | m_matrixRom.setValues(1,&jj,1,&ii,&valueMatrix,INSERT_VALUES); | |
2667 | } | ||
2668 | ✗ | jj = 3*m_dimRomBasis; | |
2669 | ✗ | double valueMatrix = 0.; | |
2670 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2671 | |||
2672 | ✗ | m_matrixRom.assembly(MAT_FINAL_ASSEMBLY); | |
2673 | |||
2674 | ✗ | m_solutionRom.set(0.); | |
2675 | |||
2676 | // Solve | ||
2677 | ✗ | m_kspRom->setKSPOperator(m_matrixRom, ""); | |
2678 | ✗ | m_kspRom->solve(m_rhsRom, m_solutionRom, 0); | |
2679 | |||
2680 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2681 | ✗ | ia = i; | |
2682 | ✗ | m_solutionRom.getValues(1,&ia,&value); | |
2683 | ✗ | m_beta[i] = value; | |
2684 | ✗ | ia = i+m_dimRomBasis; | |
2685 | ✗ | m_solutionRom.getValues(1,&ia,&value); | |
2686 | ✗ | m_mu[i] = value; | |
2687 | ✗ | ia = i+2*m_dimRomBasis; | |
2688 | ✗ | m_solutionRom.getValues(1,&ia,&value); | |
2689 | ✗ | m_xi[i] = value; | |
2690 | } | ||
2691 | |||
2692 | } | ||
2693 | |||
2694 | ✗ | void EigenProblemALP::updateBetaEI() { | |
2695 | ✗ | if (FelisceParam::verbose() > 10 ) | |
2696 | ✗ | PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::updateBetaEI()\n"); | |
2697 | |||
2698 | ✗ | double dt = FelisceParam::instance().timeStep; | |
2699 | double value; | ||
2700 | double rhs1; | ||
2701 | double rhs2; | ||
2702 | felInt ia; | ||
2703 | ✗ | m_rhsRom.set(0.); | |
2704 | |||
2705 | // (I + dt M) beta^{n+1} = beta^n + dt* gamma^n | ||
2706 | // (I + dt M) mu^{n+1} = mu^n + dt * eta^n | ||
2707 | // E beta^{n+1} + Q xi^{n+1} = 0 | ||
2708 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2709 | ✗ | rhs1 = m_beta[i] + dt * m_gamma[i]; | |
2710 | ✗ | rhs2 = m_mu[i] + dt * m_eta[i]; | |
2711 | |||
2712 | ✗ | ia = i; | |
2713 | ✗ | m_rhsRom.setValue(ia,rhs1,INSERT_VALUES); | |
2714 | |||
2715 | ✗ | ia = i+m_dimRomBasis; | |
2716 | ✗ | m_rhsRom.setValue(ia,rhs2,INSERT_VALUES); | |
2717 | } | ||
2718 | ✗ | m_rhsRom.assembly(); | |
2719 | |||
2720 | // MatrixRom = [ I+dtM 0 0 ] | ||
2721 | // [ 0 I+dtM 0 ] | ||
2722 | // [ E 0 Q ] | ||
2723 | |||
2724 | felInt ii; | ||
2725 | felInt jj; | ||
2726 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2727 | ✗ | value = 1.; | |
2728 | |||
2729 | ✗ | ii = i; | |
2730 | ✗ | m_matrixRom.setValues(1,&ii,1,&ii,&value,INSERT_VALUES); | |
2731 | |||
2732 | ✗ | ii = i+m_dimRomBasis; | |
2733 | ✗ | m_matrixRom.setValues(1,&ii,1,&ii,&value,INSERT_VALUES); | |
2734 | |||
2735 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
2736 | ✗ | double valueMatrix = 0.; | |
2737 | |||
2738 | ✗ | valueMatrix = dt * m_matrixM[i][j]; | |
2739 | ✗ | ii = i; | |
2740 | ✗ | jj = j; | |
2741 | ✗ | if (ii != jj) { | |
2742 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2743 | } | ||
2744 | ✗ | ii = i+m_dimRomBasis; | |
2745 | ✗ | jj = j+m_dimRomBasis; | |
2746 | ✗ | if (ii != jj) { | |
2747 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2748 | } | ||
2749 | |||
2750 | ✗ | valueMatrix = dt * m_tensorE[secondOrderGlobalIndex(i,j)]; | |
2751 | ✗ | ii = i+2*m_dimRomBasis; | |
2752 | ✗ | jj = j; | |
2753 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2754 | |||
2755 | ✗ | valueMatrix = dt * m_tensorQ[secondOrderGlobalIndex(i,j)]; | |
2756 | ✗ | jj = j+2*m_dimRomBasis; | |
2757 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2758 | } | ||
2759 | } | ||
2760 | ✗ | ii = 3*m_dimRomBasis; | |
2761 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
2762 | ✗ | jj = j+2*m_dimRomBasis; | |
2763 | ✗ | double valueMatrix = dt * m_tensorQ[secondOrderGlobalIndex(j,m_dimRomBasis)]; | |
2764 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2765 | ✗ | m_matrixRom.setValues(1,&jj,1,&ii,&valueMatrix,INSERT_VALUES); | |
2766 | } | ||
2767 | ✗ | jj = 3*m_dimRomBasis; | |
2768 | ✗ | double valueMatrix = 0.; | |
2769 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2770 | |||
2771 | ✗ | m_matrixRom.assembly(MAT_FINAL_ASSEMBLY); | |
2772 | |||
2773 | ✗ | m_solutionRom.set(0.); | |
2774 | |||
2775 | // Solve | ||
2776 | ✗ | m_kspRom->setKSPOperator(m_matrixRom, ""); | |
2777 | ✗ | m_kspRom->solve(m_rhsRom, m_solutionRom, 0); | |
2778 | |||
2779 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2780 | ✗ | ia = i; | |
2781 | ✗ | m_solutionRom.getValues(1,&ia,&value); | |
2782 | ✗ | m_beta[i] = value; | |
2783 | ✗ | ia = i+m_dimRomBasis; | |
2784 | ✗ | m_solutionRom.getValues(1,&ia,&value); | |
2785 | ✗ | m_mu[i] = value; | |
2786 | ✗ | ia = i+2*m_dimRomBasis; | |
2787 | ✗ | m_solutionRom.getValues(1,&ia,&value); | |
2788 | ✗ | m_xi[i] = value; | |
2789 | } | ||
2790 | |||
2791 | } | ||
2792 | |||
2793 | ✗ | void EigenProblemALP::updateBetaBdf2() { | |
2794 | |||
2795 | ✗ | if (FelisceParam::verbose() > 10 ) | |
2796 | ✗ | PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::updateBetaEI()\n"); | |
2797 | |||
2798 | ✗ | double dt = FelisceParam::instance().timeStep; | |
2799 | double value; | ||
2800 | double rhs1; | ||
2801 | double rhs2; | ||
2802 | double coefTimeDer[3]; | ||
2803 | ✗ | coefTimeDer[0] = 3./2.; | |
2804 | ✗ | coefTimeDer[1] = 2.; | |
2805 | ✗ | coefTimeDer[2] = -1./2.; | |
2806 | felInt ia; | ||
2807 | ✗ | m_rhsRom.set(0.); | |
2808 | |||
2809 | // (3/2 I + dt M) beta^{n+1} = 2 beta^n - 1/2 beta^{n-1}+ dt* gamma(beta_extrap = 2 beta^n - beta^{n-1}) | ||
2810 | // (3/2 I + dt M) mu^{n+1} = 2 mu^n - 1/2 mu^{n-1} + dt * eta(mu_extrap = 2 mu^n - mu^{n-1)) | ||
2811 | // E beta^{n+1} + Q xi^{n+1} = 0 | ||
2812 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2813 | ✗ | rhs1 = coefTimeDer[1]*m_beta[i] + coefTimeDer[2]*m_beta_n_1[i] + dt * m_gamma_extrap[i]; | |
2814 | ✗ | rhs2 = coefTimeDer[1]*m_mu[i] + coefTimeDer[2]*m_mu_n_1[i] + dt * m_eta_extrap[i]; | |
2815 | |||
2816 | ✗ | ia = i; | |
2817 | ✗ | m_rhsRom.setValue(ia,rhs1,INSERT_VALUES); | |
2818 | |||
2819 | ✗ | ia = i+m_dimRomBasis; | |
2820 | ✗ | m_rhsRom.setValue(ia,rhs2,INSERT_VALUES); | |
2821 | } | ||
2822 | ✗ | m_rhsRom.assembly(); | |
2823 | |||
2824 | // MatrixRom = [ 3/2I+dtM 0 0 ] | ||
2825 | // [ 0 3/2I+dtM 0 ] | ||
2826 | // [ E 0 Q ] | ||
2827 | |||
2828 | felInt ii; | ||
2829 | felInt jj; | ||
2830 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2831 | ✗ | value = coefTimeDer[0]; | |
2832 | |||
2833 | ✗ | ii = i; | |
2834 | ✗ | m_matrixRom.setValues(1,&ii,1,&ii,&value,INSERT_VALUES); | |
2835 | |||
2836 | ✗ | ii = i+m_dimRomBasis; | |
2837 | ✗ | m_matrixRom.setValues(1,&ii,1,&ii,&value,INSERT_VALUES); | |
2838 | |||
2839 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
2840 | ✗ | double valueMatrix = 0.; | |
2841 | |||
2842 | ✗ | valueMatrix = dt * m_matrixM[i][j]; | |
2843 | ✗ | ii = i; | |
2844 | ✗ | jj = j; | |
2845 | ✗ | if (ii != jj) { | |
2846 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2847 | } | ||
2848 | ✗ | ii = i+m_dimRomBasis; | |
2849 | ✗ | jj = j+m_dimRomBasis; | |
2850 | ✗ | if (ii != jj) { | |
2851 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2852 | } | ||
2853 | |||
2854 | ✗ | valueMatrix = dt * m_tensorE[secondOrderGlobalIndex(i,j)]; | |
2855 | ✗ | ii = i+2*m_dimRomBasis; | |
2856 | ✗ | jj = j; | |
2857 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2858 | |||
2859 | ✗ | valueMatrix = dt * m_tensorQ[secondOrderGlobalIndex(i,j)]; | |
2860 | ✗ | jj = j+2*m_dimRomBasis; | |
2861 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2862 | } | ||
2863 | } | ||
2864 | ✗ | ii = 3*m_dimRomBasis; | |
2865 | ✗ | for (int j=0; j<m_dimRomBasis; j++) { | |
2866 | ✗ | jj = j+2*m_dimRomBasis; | |
2867 | ✗ | double valueMatrix = dt * m_tensorQ[secondOrderGlobalIndex(j,m_dimRomBasis)]; | |
2868 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2869 | ✗ | m_matrixRom.setValues(1,&jj,1,&ii,&valueMatrix,INSERT_VALUES); | |
2870 | } | ||
2871 | ✗ | jj = 3*m_dimRomBasis; | |
2872 | ✗ | double valueMatrix = 0.; | |
2873 | ✗ | m_matrixRom.setValues(1,&ii,1,&jj,&valueMatrix,INSERT_VALUES); | |
2874 | |||
2875 | ✗ | m_matrixRom.assembly(MAT_FINAL_ASSEMBLY); | |
2876 | |||
2877 | ✗ | m_solutionRom.set(0.); | |
2878 | |||
2879 | // Solve | ||
2880 | ✗ | m_kspRom->setKSPOperator(m_matrixRom, ""); | |
2881 | ✗ | m_kspRom->solve(m_rhsRom, m_solutionRom, 0); | |
2882 | |||
2883 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2884 | ✗ | m_beta_n_1[i] = m_beta[i]; | |
2885 | ✗ | m_mu_n_1[i] = m_mu[i]; | |
2886 | ✗ | m_xi_n_1[i] = m_xi[i]; | |
2887 | } | ||
2888 | |||
2889 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
2890 | ✗ | ia = i; | |
2891 | ✗ | m_solutionRom.getValues(1,&ia,&value); | |
2892 | ✗ | m_beta[i] = value; | |
2893 | ✗ | ia = i+m_dimRomBasis; | |
2894 | ✗ | m_solutionRom.getValues(1,&ia,&value); | |
2895 | ✗ | m_mu[i] = value; | |
2896 | ✗ | ia = i+2*m_dimRomBasis; | |
2897 | ✗ | m_solutionRom.getValues(1,&ia,&value); | |
2898 | ✗ | m_xi[i] = value; | |
2899 | } | ||
2900 | |||
2901 | } | ||
2902 | |||
2903 | ✗ | void EigenProblemALP::ConjGrad(double* A, double* b, double* x, double tol, int maxIter, int n) { | |
2904 | ✗ | double* res = new double[n]; | |
2905 | ✗ | double* p = new double[n]; | |
2906 | ✗ | double* Ax = new double[n]; | |
2907 | |||
2908 | ✗ | for (int i=0; i<n; i++) { | |
2909 | ✗ | Ax[i] = 0.; | |
2910 | ✗ | for (int j=0; j<n; j++) { | |
2911 | ✗ | Ax[i] += A[secondOrderGlobalIndex(i,j)]*x[j]; | |
2912 | } | ||
2913 | } | ||
2914 | ✗ | for (int i=0; i<n; i++) { | |
2915 | ✗ | res[i] = b[i] - Ax[i]; | |
2916 | ✗ | p[i] = res[i]; | |
2917 | } | ||
2918 | ✗ | double res2 = 0.; | |
2919 | ✗ | double newRes2 = 0.; | |
2920 | ✗ | for (int i=0; i<n; i++) { | |
2921 | ✗ | res2 += res[i]*res[i]; | |
2922 | } | ||
2923 | |||
2924 | ✗ | double* Ap = new double[n]; | |
2925 | double pAp; | ||
2926 | double alpha; | ||
2927 | double beta; | ||
2928 | ✗ | bool isConv = false; | |
2929 | ✗ | int iter = 1; | |
2930 | |||
2931 | ✗ | if (res2 < tol) { | |
2932 | ✗ | isConv = true; | |
2933 | ✗ | if (FelisceParam::verbose()) { | |
2934 | ✗ | PetscPrintf(PETSC_COMM_WORLD,"Conjugate Gradient converged in %i iterations, residual: %1.10f \n",0,res2); | |
2935 | } | ||
2936 | } | ||
2937 | |||
2938 | ✗ | while (!isConv) { | |
2939 | ✗ | for (int i=0; i<n; i++) { | |
2940 | ✗ | Ap[i] = 0.; | |
2941 | ✗ | for (int j=0; j<n; j++) { | |
2942 | ✗ | Ap[i] += A[secondOrderGlobalIndex(i,j)]*p[j]; | |
2943 | } | ||
2944 | } | ||
2945 | ✗ | pAp = 0.; | |
2946 | ✗ | for (int i=0; i<n; i++) | |
2947 | ✗ | pAp += p[i]*Ap[i]; | |
2948 | ✗ | alpha = res2/pAp; | |
2949 | |||
2950 | ✗ | for (int i=0; i<n; i++) { | |
2951 | ✗ | x[i] += alpha*p[i]; | |
2952 | ✗ | res[i] -= alpha*Ap[i]; | |
2953 | ✗ | newRes2 += res[i]*res[i]; | |
2954 | } | ||
2955 | |||
2956 | ✗ | if ( (newRes2 < tol) || (iter >= maxIter) ) { | |
2957 | ✗ | if (newRes2 < tol) { | |
2958 | ✗ | isConv = true; | |
2959 | ✗ | if (FelisceParam::verbose()) { | |
2960 | ✗ | PetscPrintf(PETSC_COMM_WORLD,"Conjugate Gradient converged in %i iterations, residual: %1.10f \n",iter,newRes2); | |
2961 | } | ||
2962 | } else { | ||
2963 | ✗ | PetscPrintf(PETSC_COMM_WORLD,"Conjugate Gradient: %i iterations, residual: %1.10f \n",iter,newRes2); | |
2964 | ✗ | FEL_ERROR("Conjugate Gradient did not converge."); | |
2965 | } | ||
2966 | ✗ | break; | |
2967 | } else { | ||
2968 | ✗ | beta = newRes2/res2; | |
2969 | ✗ | res2 = newRes2; | |
2970 | ✗ | newRes2 = 0.; | |
2971 | ✗ | for (int i=0; i<n; i++) { | |
2972 | ✗ | p[i] = res[i] + beta*p[i]; | |
2973 | } | ||
2974 | ✗ | iter++; | |
2975 | } | ||
2976 | } | ||
2977 | |||
2978 | ✗ | delete [] res; | |
2979 | ✗ | delete [] p; | |
2980 | ✗ | delete [] Ap; | |
2981 | ✗ | delete [] Ax; | |
2982 | |||
2983 | } | ||
2984 | |||
2985 | |||
2986 | |||
2987 | ✗ | void EigenProblemALP::solveOrthComp(double* A, double* b, double* x, double tol, int maxIter) { | |
2988 | ✗ | for (int i=0; i<m_dimOrthComp; i++) { | |
2989 | ✗ | x[i] = 0.0; | |
2990 | } | ||
2991 | |||
2992 | ✗ | double* res = new double[m_dimOrthComp]; | |
2993 | ✗ | double* p = new double[m_dimOrthComp]; | |
2994 | ✗ | double* Ax = new double[m_dimOrthComp]; | |
2995 | |||
2996 | ✗ | for (int i=0; i<m_dimOrthComp; i++) { | |
2997 | ✗ | Ax[i] = 0.; | |
2998 | ✗ | for (int j=0; j<m_dimOrthComp; j++) { | |
2999 | ✗ | Ax[i] += A[i*(m_dimOrthComp)+j]*x[j]; | |
3000 | } | ||
3001 | } | ||
3002 | ✗ | for (int i=0; i<m_dimOrthComp; i++) { | |
3003 | ✗ | res[i] = b[i] - Ax[i]; | |
3004 | ✗ | p[i] = res[i]; | |
3005 | } | ||
3006 | ✗ | double res2 = 0.; | |
3007 | ✗ | double newRes2 = 0.; | |
3008 | ✗ | for (int i=0; i<m_dimOrthComp; i++) { | |
3009 | ✗ | res2 += res[i]*res[i]; | |
3010 | } | ||
3011 | |||
3012 | ✗ | double* Ap = new double[m_dimOrthComp]; | |
3013 | double pAp; | ||
3014 | double alpha; | ||
3015 | double beta; | ||
3016 | ✗ | bool isConv = false; | |
3017 | ✗ | int iter = 1; | |
3018 | |||
3019 | ✗ | while (!isConv) { | |
3020 | ✗ | for (int i=0; i<m_dimOrthComp; i++) { | |
3021 | ✗ | Ap[i] = 0.; | |
3022 | ✗ | for (int j=0; j<m_dimOrthComp; j++) { | |
3023 | ✗ | Ap[i] += A[i*(m_dimOrthComp)+j]*p[j]; | |
3024 | } | ||
3025 | } | ||
3026 | ✗ | pAp = 0.; | |
3027 | ✗ | for (int i=0; i<m_dimOrthComp; i++) | |
3028 | ✗ | pAp += p[i]*Ap[i]; | |
3029 | ✗ | alpha = res2/pAp; | |
3030 | |||
3031 | ✗ | for (int i=0; i<m_dimOrthComp; i++) { | |
3032 | ✗ | x[i] += alpha*p[i]; | |
3033 | ✗ | res[i] -= alpha*Ap[i]; | |
3034 | ✗ | newRes2 += res[i]*res[i]; | |
3035 | } | ||
3036 | |||
3037 | ✗ | if ( (newRes2 < tol) || (iter >= maxIter) ) { | |
3038 | ✗ | isConv = true; | |
3039 | ✗ | if (FelisceParam::verbose() > 10) { | |
3040 | ✗ | PetscPrintf(PETSC_COMM_WORLD,"Conjugate Gradient converged in %i iterations, residual: %1.10f \n",iter,newRes2); | |
3041 | } | ||
3042 | |||
3043 | ✗ | break; | |
3044 | } else { | ||
3045 | ✗ | beta = newRes2/res2; | |
3046 | ✗ | res2 = newRes2; | |
3047 | ✗ | newRes2 = 0.; | |
3048 | ✗ | for (int i=0; i<m_dimOrthComp; i++) { | |
3049 | ✗ | p[i] = res[i] + beta*p[i]; | |
3050 | } | ||
3051 | ✗ | iter++; | |
3052 | } | ||
3053 | } | ||
3054 | |||
3055 | ✗ | for (int i=0; i<m_dimOrthComp; i++) { | |
3056 | ✗ | Ax[i] = 0.; | |
3057 | ✗ | for (int j=0; j<m_dimOrthComp; j++) { | |
3058 | ✗ | Ax[i] += A[i*(m_dimOrthComp)+j]*x[j]; | |
3059 | } | ||
3060 | } | ||
3061 | |||
3062 | ✗ | delete [] res; | |
3063 | ✗ | delete [] p; | |
3064 | ✗ | delete [] Ap; | |
3065 | ✗ | delete [] Ax; | |
3066 | |||
3067 | } | ||
3068 | |||
3069 | |||
3070 | |||
3071 | ✗ | void EigenProblemALP::updateEigenvalue() { | |
3072 | ✗ | if (FelisceParam::verbose() > 10 ) PetscPrintf(PETSC_COMM_WORLD,"\nEigenProblemALP::updateEigenvalue()\n"); | |
3073 | |||
3074 | ✗ | double dt = FelisceParam::instance().timeStep; | |
3075 | ✗ | double newLambda[m_dimRomBasis]; | |
3076 | // lambda_i^{n+1} = lambda_i^n - dt * m_coefChi * sum_h ( gamma_h * T_hii ) | ||
3077 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
3078 | ✗ | newLambda[i] = 0.; | |
3079 | ✗ | for (int h=0; h<m_dimRomBasis; h++) { | |
3080 | ✗ | newLambda[i] += m_gamma[h] * m_tensorT[thirdOrderGlobalIndex(h,i,i)]; | |
3081 | } | ||
3082 | } | ||
3083 | ✗ | for (int i=0; i<m_dimRomBasis; i++) { | |
3084 | ✗ | m_eigenValue[i] -= dt * m_coefChi * newLambda[i]; | |
3085 | } | ||
3086 | } | ||
3087 | |||
3088 | // Projection functions from FE space to RO one | ||
3089 | 3 | void EigenProblemALP::projectOnBasis(PetscVector& vectorDof, double* vectorBasis, bool flagMass, int size) | |
3090 | { | ||
3091 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if (size == 0) |
3092 | 3 | size = m_dimRomBasis; | |
3093 | |||
3094 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | PetscVector tmpVec; |
3095 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | tmpVec.duplicateFrom(vectorDof); |
3096 | |||
3097 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if (flagMass) { |
3098 |
2/2✓ Branch 0 taken 75 times.
✓ Branch 1 taken 3 times.
|
78 | for (int iBasis=0; iBasis<size; iBasis++) { |
3099 |
1/2✓ Branch 3 taken 75 times.
✗ Branch 4 not taken.
|
75 | mult(m_Matrix[m_idG], m_basis[iBasis],tmpVec); |
3100 | |||
3101 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | dot(tmpVec,vectorDof,&vectorBasis[iBasis]); |
3102 | |||
3103 | } | ||
3104 | } else { | ||
3105 | ✗ | for (int iBasis=0; iBasis<size; iBasis++) { | |
3106 | ✗ | dot( m_basis[iBasis],vectorDof,&vectorBasis[iBasis]); | |
3107 | } | ||
3108 | } | ||
3109 | |||
3110 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | tmpVec.destroy(); |
3111 | 3 | } | |
3112 | |||
3113 | // Projection functions from RO space to FE one | ||
3114 | 75 | void EigenProblemALP::projectOnDof(double* vectorBasis, PetscVector& vectorDof, int size) { | |
3115 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | vectorDof.set(0.); |
3116 |
2/2✓ Branch 0 taken 975 times.
✓ Branch 1 taken 75 times.
|
1050 | for (int iBasis=0; iBasis<size; iBasis++) { |
3117 | 975 | vectorDof.axpy(vectorBasis[iBasis],m_basis[iBasis]); | |
3118 | } | ||
3119 | 75 | } | |
3120 | |||
3121 | // Auxiliary function to debug purposes. | ||
3122 | ✗ | void EigenProblemALP::viewALP(double* vToPrint, int vSize, std::ofstream outStream) { | |
3123 | int rankProc; | ||
3124 | ✗ | MPI_Comm_rank(m_petscComm,&rankProc); | |
3125 | ✗ | if (rankProc == 0) { | |
3126 | ✗ | for(int i=0; i<vSize; i++) { | |
3127 | ✗ | outStream << vToPrint[i] << std::endl; | |
3128 | } | ||
3129 | ✗ | outStream.close(); | |
3130 | } | ||
3131 | } | ||
3132 | |||
3133 | |||
3134 | 4 | void EigenProblemALP::viewALP(double* vToPrint, int vSize, std::string fName) { | |
3135 | int rankProc; | ||
3136 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | MPI_Comm_rank(m_petscComm,&rankProc); |
3137 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (rankProc == 0) { |
3138 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | std::ofstream outStream(fName.c_str()); |
3139 |
2/2✓ Branch 0 taken 100 times.
✓ Branch 1 taken 4 times.
|
104 | for(int i=0; i<vSize; i++) { |
3140 |
2/4✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
|
100 | outStream << vToPrint[i] << std::endl; |
3141 | } | ||
3142 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | outStream.close(); |
3143 | 4 | } | |
3144 | 4 | } | |
3145 | |||
3146 | } | ||
3147 |