Virtual function for solve implementation.
123{
124 Array<OneD, NekDouble> tmpworkd;
125
127 ->UpdateFields()[0]
128 ->GetNcoeffs();
131 int ido;
132
133 int info;
134
135
136 int iparam[11];
137 int ipntr[14];
138
139 Array<OneD, int> ritzSelect;
140 Array<OneD, NekDouble> dr;
141 Array<OneD, NekDouble> di;
142 Array<OneD, NekDouble> workev;
143 Array<OneD, NekDouble>
z;
145
146 Array<OneD, NekDouble> resid(n);
147 Array<OneD, NekDouble> v(n *
m_kdim);
148 Array<OneD, NekDouble> workl(lworkl, 0.0);
149 Array<OneD, NekDouble> workd(3 * n, 0.0);
150
152
153 if (
m_session->DefinesFunction(
"InitialConditions"))
154 {
155 out << "\tInital vector : input file " << endl;
156 info = 1;
158 }
159 else
160 {
161 out << "\tInital vector : random " << endl;
162 info = 0;
163 }
164
165 char B;
166
167 iparam[0] = 1;
168 iparam[1] = 0;
170 iparam[3] = 1;
171 iparam[4] = 0;
172 iparam[5] = 0;
173
174
176 {
177 iparam[6] = 1;
178 B = 'I';
179 }
180 else
181 {
182 iparam[6] = 3;
183 B = 'G';
184 }
185#if 0
188 {
189 iparam[6] = 3;
190 B = 'G';
191 }
192 else
193 {
194 iparam[6] = 1;
195 B = 'I';
196 }
197#endif
198 iparam[7] = 0;
199 iparam[8] = 0;
200 iparam[9] = 0;
201 iparam[10] = 0;
202
203 int cycle = 0;
204 const char *problem =
206 "ArpackProblemType")]
207 .c_str();
208
210 ofstream pFile(
name.c_str());
211
212 ido = 0;
213
214 while (ido != 99)
215 {
216
219 iparam, ipntr, &workd[0], &workl[0], lworkl, info);
220
221
222
223 out << "\rIteration " << cycle << ", output: " << info
224 << ", ido=" << ido << " " << std::flush;
225
226 if (!((cycle - 1) %
m_kdim) && (cycle >
m_kdim) && (ido != 2))
227 {
228 pFile << "Krylov spectrum at iteration: " << cycle << endl;
229
231 {
232 pFile << "EV Magnitude Angle Growth Frequency "
233 "Residual"
234 << endl;
235 }
236 else
237 {
238 pFile << "EV Real Imaginary inverse real inverse "
239 "imag Residual"
240 << endl;
241 }
242
243 out << endl;
244 for (
int k = 0; k <
m_kdim; ++k)
245 {
246
247 WriteEvs(pFile, k, workl[ipntr[5] - 1 + k],
248 workl[ipntr[6] - 1 + k]);
249 }
250 }
251
252 if (ido == 99)
253 {
254 break;
255 }
256
257 switch (ido)
258 {
259 case -1:
260 case 1:
261
262
263
265
266 m_equ[0]->TransCoeffToPhys();
267
270 {
271
273
274 m_equ[1]->TransCoeffToPhys();
276 }
277
279 {
280 out << endl;
282 }
283
284
286
287 cycle++;
288 break;
289 case 2:
290 {
291
293
294 m_equ[0]->TransCoeffToPhys();
295
296 Array<OneD, MultiRegions::ExpListSharedPtr> fields =
297 m_equ[0]->UpdateFields();
298 for (int i = 0; i < fields.size(); ++i)
299 {
300 fields[i]->IProductWRTBase(fields[i]->GetPhys(),
301 fields[i]->UpdateCoeffs());
302 }
303
304
306 break;
307 }
308 default:
309 ASSERTL0(
false,
"Unexpected reverse communication request.");
310 }
311 }
312
313 out << endl << "Converged in " << iparam[8] << " iterations" << endl;
314
315 ASSERTL0(info >= 0,
" Error with Dnaupd");
316
317 ritzSelect = Array<OneD, int>(
m_kdim, 0);
318 dr = Array<OneD, NekDouble>(
m_nvec + 1, 0.0);
319 di = Array<OneD, NekDouble>(
m_nvec + 1, 0.0);
320 workev = Array<OneD, NekDouble>(3 *
m_kdim);
321 z = Array<OneD, NekDouble>(n * (
m_nvec + 1));
322
324 {
326 }
327 else
328 {
330 }
331
332
333
334
335 sigmai = 0;
336
337
338 Arpack::Dneupd(1,
"A", ritzSelect.get(), dr.get(), di.get(),
z.get(), n,
339 sigmar, sigmai, workev.get(), &B, n, problem,
m_nvec,
341 workd.get(), workl.get(), lworkl, info);
342
343 ASSERTL0(info == 0,
" Error with Dneupd");
344
345 int nconv = iparam[4];
346
347
349 {
351 }
352 else
353 {
355 }
356
358 "Need to implement Ritz re-evaluation of"
359 "eigenvalue. Only one half of complex "
360 "value will be correct");
361
362 Array<OneD, MultiRegions::ExpListSharedPtr> fields =
363 m_equ[0]->UpdateFields();
364
365 out << "Converged Eigenvalues: " << nconv << endl;
366 pFile << "Converged Eigenvalues: " << nconv << endl;
367
369 {
370 out << " Magnitude Angle Growth Frequency" << endl;
371 pFile << " Magnitude Angle Growth Frequency"
372 << endl;
373 for (int i = 0; i < nconv; ++i)
374 {
377
378 std::string file =
m_session->GetSessionName() +
"_eig_" +
379 std::to_string(i) + ".fld";
381 }
382 }
383 else
384 {
385 out << " Real Imaginary " << endl;
386 pFile << " Real Imaginary " << endl;
387 for (int i = 0; i < nconv; ++i)
388 {
390 false);
392 false);
393
394 std::string file =
m_session->GetSessionName() +
"_eig_" +
395 std::to_string(i) + ".fld";
397 }
398 }
399
402
403 pFile.close();
404
405 for (
int j = 0; j <
m_equ[0]->GetNvariables(); ++j)
406 {
409 if (
m_comm->GetRank() == 0)
410 {
411 out <<
"L 2 error (variable " <<
m_equ[0]->GetVariable(j)
412 << ") : " << vL2Error << endl;
413 out <<
"L inf error (variable " <<
m_equ[0]->GetVariable(j)
414 << ") : " << vLinfError << endl;
415 }
416 }
417}
#define ASSERTL0(condition, msg)
#define WARNINGL0(condition, msg)
void CopyFwdToAdj()
Copy the forward field to the adjoint system in transient growth calculations.
void WriteFld(std::string file, std::vector< Array< OneD, NekDouble > > coeffs)
Write coefficients to file.
int m_infosteps
underlying operator is time stepping
void CopyFieldToArnoldiArray(Array< OneD, NekDouble > &array)
Copy fields to Arnoldi storage.
int m_nvec
Dimension of Krylov subspace.
bool m_timeSteppingAlgorithm
Period of time stepping algorithm.
int m_nits
Number of vectors to test.
Array< OneD, NekDouble > m_imag_evl
void CopyArnoldiArrayToField(Array< OneD, NekDouble > &array)
Copy Arnoldi storage to fields.
NekDouble m_evtol
Maxmum number of iterations.
int m_nfields
interval to dump information if required.
Array< OneD, NekDouble > m_real_evl
Operator in solve call is negated.
void WriteEvs(std::ostream &evlout, const int k, const NekDouble real, const NekDouble imag, NekDouble resid=NekConstants::kNekUnsetDouble, bool DumpInverse=true)
static std::string ArpackProblemTypeTrans[]
LibUtilities::SessionReaderSharedPtr m_session
Session reader object.
LibUtilities::CommSharedPtr m_comm
Communication object.
enum EvolutionOperatorType m_EvolutionOperator
Evolution Operator.
Array< OneD, EquationSystemSharedPtr > m_equ
Equation system to solve.
static void Dnaupd(int &ido, const char *bmat, const int &n, const char *which, const int &nev, const double &tol, double *resid, const int &ncv, double *v, const int &ldv, int *iparam, int *ipntr, double *workd, double *workl, const int &lworkl, int &info)
Top level reverse communication interface to solve real double-precision non-symmetric problems.
static void Dneupd(const int &rvec, const char *howmny, const int *select, double *dr, double *di, double *z, const int &ldz, const double &sigmar, const double &sigmai, double *workev, const char *bmat, const int &n, const char *which, const int &nev, const double &tol, double *resid, const int &ncv, double *v, const int &ldv, int *iparam, int *ipntr, double *workd, double *workl, const int &lworkl, int &info)
Post-processing routine to computed eigenvector of computed eigenvalues in Dnaupd.
static const NekDouble kNekUnsetDouble
static const NekDouble kNekZeroTol
std::vector< double > z(NPUPPER)
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add vector y = alpha + x.