Nektar++
Loading...
Searching...
No Matches
NekNonlinSysIterNewtonHookStep.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: NekNonlinSysIterNewtonHookStep.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// License for the specific language governing rights and limitations under
14// Permission is hereby granted, free of charge, to any person obtaining a
15// copy of this software and associated documentation files (the "Software"),
16// to deal in the Software without restriction, including without limitation
17// the rights to use, copy, modify, merge, publish, distribute, sublicense,
18// and/or sell copies of the Software, and to permit persons to whom the
19// Software is furnished to do so, subject to the following conditions:
20//
21// The above copyright notice and this permission notice shall be included
22// in all copies or substantial portions of the Software.
23//
24// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30// DEALINGS IN THE SOFTWARE.
31//
32// Description: NekNonlinSysIterNewtonHookStep definition
33//
34///////////////////////////////////////////////////////////////////////////////
35
37#include <algorithm>
38#include <cmath>
39#include <vector>
40
41/*
42<SOLVERINFO>
43 <I PROPERTY="NonlinearSolver" VALUE="NewtonHookStep" />
44 <I PROPERTY="LinSysIterSolver" VALUE="GMRES" />
45</SOLVERINFO>
46
47<PARAMETERS>
48 <P> TrustRadiusInit = 1.0e-2 </P>
49 <P> TrustRadiusMin = 1.0e-8 </P>
50 <P> TrustRadiusMax = 1.0e0 </P>
51
52 <P> TrustRegionRhoAccept = 1.0e-1 </P>
53 <P> TrustRegionRhoShrink = 2.5e-1 </P>
54 <P> TrustRegionRhoGrow = 7.5e-1 </P>
55 <P> TrustRegionShrinkFactor = 0.5 </P>
56 <P> TrustRegionGrowFactor = 2.0 </P>
57
58 <P> MaxTrustRegionSteps = 4 </P>
59 <P> MaxTrustRegionGrowthSteps = 3 </P>
60 <P> TrustRegionMaxFallbackResidualGrowth = 10.0 </P>
61
62 <P> LinSysMaxStorage = 1000 </P>
63
64 <P> MeaningfulAredRel = 1.0e-3 </P>
65 <P> MeaningfulAredAbs = 1.0e-12 </P>
66</PARAMETERS>
67*/
68
69using namespace std;
70
72{
76 "Newton solver with GMRES-based hook step.");
77
80 const LibUtilities::CommSharedPtr &vComm, const int nDimen,
81 const NekSysKey &pKey)
82 : NekNonlinSysIterNewton(pSession, vComm, nDimen, pKey)
83{
84 pSession->LoadParameter("TrustRadiusInit", m_trustRadiusInit, 1.0e-2);
85 pSession->LoadParameter("TrustRadiusMin", m_trustRadiusMin, 1.0e-8);
86 pSession->LoadParameter("TrustRadiusMax", m_trustRadiusMax, 1.0e2);
87
88 pSession->LoadParameter("TrustRegionRhoAccept", m_rhoAccept, 1.0e-1);
89 pSession->LoadParameter("TrustRegionRhoShrink", m_rhoShrink, 2.5e-1);
90 pSession->LoadParameter("TrustRegionRhoGrow", m_rhoGrow, 7.5e-1);
91 pSession->LoadParameter("TrustRegionShrinkFactor", m_shrinkFactor, 0.5);
92 pSession->LoadParameter("TrustRegionGrowFactor", m_growFactor, 2.0);
93
94 pSession->LoadParameter("MaxTrustRegionSteps", m_maxTrustRegionSteps, 4);
95 pSession->LoadParameter("MaxTrustRegionGrowthSteps",
97 pSession->LoadParameter("TrustRegionMaxFallbackResidualGrowth",
99 pSession->LoadParameter("MeaningfulAredRel", m_meaningfulAredRel, 1.0e-3);
100 pSession->LoadParameter("MeaningfulAredAbs", m_meaningfulAredAbs, 1.0e-12);
101}
102
104{
106
110
113
115
116 auto gmres = std::dynamic_pointer_cast<NekLinSysIterGMRES>(m_linsol);
117 ASSERTL0(gmres, "NewtonHookStep requires LinSysIterSolver=GMRES.");
118 gmres->EnableHookStepExport(true);
119}
120
122 const int ntotal, const Array<OneD, const NekDouble> &x) const
123{
124 NekDouble nrm2 = Vmath::Dot(ntotal, x, x);
125 m_rowComm->AllReduce(nrm2, LibUtilities::ReduceSum);
126 return sqrt(nrm2);
127}
128
129/*
130 Solve a small dense linear system Ax=b for x
131 using Gaussian elimination with pivoting
132 The system to be solved is
133 $$(H^T H + μI)y=\beta H^t e_1​$$, so a symmetric one
134 could use Cholesky factorisation
135*/
137 std::vector<std::vector<NekDouble>> A, std::vector<NekDouble> b) const
138{
139 int n = static_cast<int>(b.size());
140
141 for (int k = 0; k < n; ++k)
142 {
143 int piv = k;
144 NekDouble amax = std::abs(A[k][k]);
145 for (int i = k + 1; i < n; ++i)
146 {
147 if (std::abs(A[i][k]) > amax)
148 {
149 amax = std::abs(A[i][k]);
150 piv = i;
151 }
152 }
153
154 ASSERTL0(amax > 1.0e-14, "Hook-step dense solve breakdown.");
155
156 if (piv != k)
157 {
158 std::swap(A[piv], A[k]);
159 std::swap(b[piv], b[k]);
160 }
161
162 NekDouble diag = A[k][k];
163 for (int j = k; j < n; ++j)
164 {
165 A[k][j] /= diag;
166 }
167 b[k] /= diag;
168
169 for (int i = k + 1; i < n; ++i)
170 {
171 NekDouble fac = A[i][k];
172 for (int j = k; j < n; ++j)
173 {
174 A[i][j] -= fac * A[k][j];
175 }
176 b[i] -= fac * b[k];
177 }
178 }
179
180 std::vector<NekDouble> x(n, 0.0);
181 for (int i = n - 1; i >= 0; --i)
182 {
183 x[i] = b[i];
184 for (int j = i + 1; j < n; ++j)
185 {
186 x[i] -= A[i][j] * x[j];
187 }
188 }
189
190 return x;
191}
192
193/*
194 Using GMRES data look for $\mu$ such thatm_TrustRadiusInit
195 $(H^T H + μI)y=\beta H^t e_1​$ and $||y(\mu)<\Delta||$
196*/
198 const NekLinSysIterGMRES::GMRESHookData &data, const NekDouble Delta) const
199{
200 int m = data.nswp;
201 Array<OneD, NekDouble> y(m, 0.0);
202
203 std::vector<std::vector<NekDouble>> H(m + 1,
204 std::vector<NekDouble>(m, 0.0));
205
206 for (int j = 0; j < m; ++j)
207 {
208 for (int i = 0; i < m + 1; ++i)
209 {
210 H[i][j] = data.H[j][i];
211 }
212 }
213
214 std::vector<std::vector<NekDouble>> AtA(m, std::vector<NekDouble>(m, 0.0));
215 std::vector<NekDouble> rhs(m, 0.0);
216
217 for (int i = 0; i < m; ++i)
218 {
219 rhs[i] = H[0][i] * data.beta;
220 for (int j = 0; j < m; ++j)
221 {
222 NekDouble sum = 0.0;
223 for (int k = 0; k < m + 1; ++k)
224 {
225 sum += H[k][i] * H[k][j];
226 }
227 AtA[i][j] = sum;
228 }
229 }
230
231 auto computeY = [&](NekDouble mu) {
232 std::vector<std::vector<NekDouble>> A = AtA;
233 for (int i = 0; i < m; ++i)
234 {
235 A[i][i] += mu;
236 }
237 return SolveDenseLinearSystem(A, rhs);
238 };
239
240 auto normY = [&](const std::vector<NekDouble> &yv) {
241 NekDouble s = 0.0;
242 for (auto v : yv)
243 {
244 s += v * v;
245 }
246 return sqrt(s);
247 };
248
249 std::vector<NekDouble> y0 = computeY(0.0);
250 if (normY(y0) <= Delta)
251 {
252 for (int i = 0; i < m; ++i)
253 {
254 y[i] = y0[i];
255 }
256 return y;
257 }
258
259 NekDouble muL = 0.0;
260 NekDouble muR = 1.0;
261
262 while (normY(computeY(muR)) > Delta)
263 {
264 muR *= 10.0;
265 ASSERTL0(muR < 1.0e20, "Unable to bracket hook-step multiplier.");
266 }
267
268 // For now just do 40 iterations, consider a stop cryterion tolerance
269 for (int it = 0; it < 40; ++it)
270 {
271 NekDouble mu = 0.5 * (muL + muR);
272 std::vector<NekDouble> ym = computeY(mu);
273 if (normY(ym) > Delta)
274 {
275 muL = mu;
276 }
277 else
278 {
279 muR = mu;
280 }
281 }
282
283 std::vector<NekDouble> yv = computeY(muR);
284 for (int i = 0; i < m; ++i)
285 {
286 y[i] = yv[i];
287 }
288
289 return y;
290}
291
292/*
293Take computed y spanning the Krylov space and convert to the actual step delta.
294*/
298{
299 int nNonDir = data.nGlobal - data.nDir;
300 Vmath::Zero(nNonDir, delta, 1);
301
302 for (int i = 0; i < data.nswp; ++i)
303 {
304 // Can not mix Array and T* ...
305 Vmath::Svtvp(nNonDir, y[i], &data.V[i][0] + data.nDir, 1, delta.data(),
306 1, delta.data(), 1);
307 }
308
309 auto gmres = std::dynamic_pointer_cast<NekLinSysIterGMRES>(m_linsol);
310 if (gmres && gmres->UsingRightPrecon())
311 {
312 Array<OneD, NekDouble> tmp(nNonDir, 0.0);
313 gmres->ApplyRightPrecon(delta, tmp);
314 Vmath::Vcopy(nNonDir, tmp, 1, delta, 1);
315 }
316}
317
318/*
319Hook step is based on the quadratic model of the problem
320This computes the predicted linearised residual norm in the reduced
321GMRES/Krylov space
322$$
323\sqrt{2m(y)} = || \beta e_1 - H y ||_2
324$$.
325*/
328 const Array<OneD, const NekDouble> &y) const
329{
330 int m = data.nswp;
331 Array<OneD, NekDouble> rred(m + 1, 0.0);
332 rred[0] = data.beta;
333
334 for (int j = 0; j < m; ++j)
335 {
336 for (int i = 0; i < m + 1; ++i)
337 {
338 rred[i] -= data.H[j][i] * y[j];
339 }
340 }
341
342 NekDouble nrm2 = 0.0;
343 for (int i = 0; i < m + 1; ++i)
344 {
345 nrm2 += rred[i] * rred[i];
346 }
347 return sqrt(nrm2);
348}
349
351 const int ntotal, const NekDouble oldResNorm)
352{
353 auto gmres = std::dynamic_pointer_cast<NekLinSysIterGMRES>(m_linsol);
354 ASSERTL0(gmres, "NewtonHookStep requires GMRES.");
355
356 ASSERTL0(!gmres->UsingLeftPrecon(),
357 "Initial NewtonHookStep implementation does not support "
358 "GMRESLeftPrecon.");
359
360 const auto &data = gmres->GetHookData();
361 ASSERTL0(data.valid, "GMRES hook-step data not available.");
362
363 NekDouble trustRadiusTrial = m_trustRadius;
364 cout << " Attempting to apply Newton update with Hookstep "
365 << " Trust radius = " << trustRadiusTrial
366 << " GMRES beta = " << data.beta << " oldResNorm= " << oldResNorm
367 << endl;
368
369 bool haveAcceptedCandidate = false;
370 bool hadShrink = false;
371
372 NekDouble bestResNorm = 0.0;
373 NekDouble bestRho = 0.0;
374 NekDouble bestTrustRadius = 0.0;
375 bool bestBoundaryStep = false;
376
377 // ---------------------------------------------------------------------
378 // Phase 1: recovery by shrinking radius until the first acceptable step.
379 // ---------------------------------------------------------------------
380 for (int it = 0; it < m_maxTrustRegionSteps; ++it)
381 {
383 SolveReducedHookStep(data, trustRadiusTrial);
384
385 Vmath::Zero(ntotal, m_deltaTrial, 1);
387
388 // predicted norm of the residual
389 NekDouble predResNorm = ComputeReducedResidualNorm(data, yHook);
390
392 Vmath::Svtvp(ntotal, -1.0, m_deltaTrial, 1, m_solutionTrial, 1,
393 m_solutionTrial, 1);
394
396
397 NekDouble newResNormSq =
399 m_rowComm->AllReduce(newResNormSq, LibUtilities::ReduceSum);
400 NekDouble newResNorm = sqrt(newResNormSq);
401
402 NekDouble ared = oldResNorm - newResNorm;
403 NekDouble pred = oldResNorm - predResNorm;
404 // Protect from small pred
405 NekDouble rho = (pred > 1.0e-14 * oldResNorm) ? ared / pred : -1.0;
406
407 NekDouble yNorm = CalcL2Norm(data.nswp, yHook);
408 bool boundaryStep = std::abs(yNorm - trustRadiusTrial) <=
409 1.0e-2 * (trustRadiusTrial + 1.0e-14);
410
411 cout << " HookStep TrustRadius trial = " << trustRadiusTrial
412 << " yNorm = " << yNorm << " oldRes = " << oldResNorm
413 << " newRes = " << newResNorm << " predRes = " << predResNorm
414 << " ared = " << ared << " pred = " << pred << " rho = " << rho
415 << endl;
416
417 bool meaningfulDecrease = HasMeaningfulDecrease(oldResNorm, newResNorm);
418
419 if (rho > m_rhoAccept || meaningfulDecrease)
420 {
421 cout << "Accepting HookStep with rho = " << rho << " > "
422 << " m_RhoAccept = " << m_rhoAccept << endl;
423
426
427 bestResNorm = newResNorm;
428 bestRho = rho;
429 bestTrustRadius = trustRadiusTrial;
430 bestBoundaryStep = boundaryStep;
431 haveAcceptedCandidate = true;
432
433 break;
434 }
435
436 hadShrink = true;
437
438 trustRadiusTrial =
439 std::max(m_trustRadiusMin, m_shrinkFactor * trustRadiusTrial);
440
441 cout << " HookStep shrink trial radius to " << trustRadiusTrial
442 << " because current trial was not acceptable." << endl;
443
444 if (trustRadiusTrial <= m_trustRadiusMin + 1.0e-16)
445 {
446 WARNINGL0(false, "Hook-step globalization failed at TrustRadiusMin "
447 "without meaningful residual decrease.");
449 return false;
450 }
451 }
452
453 cout << "HookStep finished the shrink phase with: "
454 << " hadShrink=" << hadShrink << " bestRho=" << bestRho
455 << " bestBoundaryStep=" << bestBoundaryStep << endl;
456
457 // ---------------------------------------------------------------------
458 // No acceptable step found in Phase 1: fallback at TrustRadiusMin.
459 // ---------------------------------------------------------------------
460 if (!haveAcceptedCandidate)
461 {
462 Array<OneD, NekDouble> yFallback =
464
465 Vmath::Zero(ntotal, m_deltaTrial, 1);
467
469 Vmath::Svtvp(ntotal, -1.0, m_deltaTrial, 1, m_solutionTrial, 1,
470 m_solutionTrial, 1);
471
473
474 NekDouble fallbackResNormSq =
476 m_rowComm->AllReduce(fallbackResNormSq, LibUtilities::ReduceSum);
477 NekDouble fallbackResNorm = sqrt(fallbackResNormSq);
478
479 cout << " No acceptable hook-step found."
480 << " Taking fallback TrustRadiusMin = " << m_trustRadiusMin
481 << " residual = " << fallbackResNorm << endl;
482
483 if (!std::isfinite(fallbackResNorm) ||
484 fallbackResNorm > m_maxFallbackResidualGrowth * oldResNorm)
485 {
486 WARNINGL0(false,
487 "Fallback hook-step caused non-finite or excessive "
488 "residual growth.");
490 return false;
491 }
492
496
498 return true;
499 }
500
501 // ---------------------------------------------------------------------
502 // Phase 2: exploration by enlarging radius, but only if Phase 1
503 // succeeded without shrink and the accepted step is a strong
504 // boundary-limited candidate.
505 // ---------------------------------------------------------------------
506 if (!hadShrink && bestRho > m_rhoGrow && bestBoundaryStep)
507 {
508 cout << " HookStep entering exploration phase from TrustRadius = "
509 << bestTrustRadius << " because bestRho = " << bestRho
510 << " > m_rhoGrow = " << m_rhoGrow << endl;
511
512 NekDouble exploreRadius = bestTrustRadius;
513
514 for (int ig = 0; ig < m_maxTrustRegionGrowthSteps; ++ig)
515 {
516 NekDouble enlargedRadius =
517 std::min(m_trustRadiusMax, m_growFactor * exploreRadius);
518
519 if (enlargedRadius <= exploreRadius + 1.0e-16)
520 {
521 break;
522 }
523
525 SolveReducedHookStep(data, enlargedRadius);
526
527 Vmath::Zero(ntotal, m_deltaTrial, 1);
529
530 NekDouble predResNorm = ComputeReducedResidualNorm(data, yHook);
531
533 Vmath::Svtvp(ntotal, -1.0, m_deltaTrial, 1, m_solutionTrial, 1,
534 m_solutionTrial, 1);
535
537
538 NekDouble newResNormSq =
540 m_rowComm->AllReduce(newResNormSq, LibUtilities::ReduceSum);
541 NekDouble newResNorm = sqrt(newResNormSq);
542
543 NekDouble ared = oldResNorm - newResNorm;
544 NekDouble pred = oldResNorm - predResNorm;
545 NekDouble rho = (pred > 1.0e-14 * oldResNorm) ? ared / pred : -1.0;
546
547 NekDouble yNorm = CalcL2Norm(data.nswp, yHook);
548 bool boundaryStep = std::abs(yNorm - enlargedRadius) <=
549 1.0e-2 * (enlargedRadius + 1.0e-14);
550
551 cout << " HookStep exploration trial = " << enlargedRadius
552 << " yNorm = " << yNorm << " oldRes = " << oldResNorm
553 << " newRes = " << newResNorm << " predRes = " << predResNorm
554 << " ared = " << ared << " pred = " << pred << " rho = " << rho
555 << endl;
556
557 bool meaningfulDecrease =
558 HasMeaningfulDecrease(oldResNorm, newResNorm);
559
560 // Candidate must still be admissible.
561 if (!(rho > m_rhoAccept || meaningfulDecrease))
562 {
563 cout << " Exploration step rejected, stop growing radius."
564 << endl;
565 break;
566 }
567
568 // Keep only if actual residual improves on the best accepted one.
569 if (newResNorm < bestResNorm)
570 {
571 cout << " Exploration improved residual from " << bestResNorm
572 << " to " << newResNorm << ", keeping enlarged step."
573 << endl;
574
577
578 bestResNorm = newResNorm;
579 bestRho = rho;
580 bestTrustRadius = enlargedRadius;
581 bestBoundaryStep = boundaryStep;
582
583 exploreRadius = enlargedRadius;
584
585 if (!(bestRho > m_rhoGrow && bestBoundaryStep))
586 {
587 cout << " Exploration stopping because enlarged step is "
588 << "no longer a strong boundary-limited candidate."
589 << endl;
590 break;
591 }
592 }
593 else
594 {
595 cout << " Exploration did not improve residual (best = "
596 << bestResNorm << ", trial = " << newResNorm
597 << "), stopping." << endl;
598 break;
599 }
600 }
601 }
602
603 // ---------------------------------------------------------------------
604 // Finalize with the best accepted candidate found.
605 // ---------------------------------------------------------------------
606 Vmath::Vcopy(ntotal, m_solutionBest, 1, m_Solution, 1);
607 Vmath::Vcopy(ntotal, m_residualBest, 1, m_Residual, 1);
609
610 m_trustRadius = bestTrustRadius;
611
612 if (bestRho < m_rhoShrink)
613 {
614 cout << " Trust Radius shrink because rho < m_rhoShrink = "
615 << m_rhoShrink << " m_shrinkFactor = " << m_shrinkFactor << endl;
618 cout << " Next Trust Radius = " << m_trustRadius << endl;
619 }
620 else if (bestRho > m_rhoGrow && bestBoundaryStep)
621 {
622 cout << " Trust Radius grow because rho > m_rhoGrow = " << m_rhoGrow
623 << " m_growFactor = " << m_growFactor << endl;
626 cout << " Next Trust Radius = " << m_trustRadius << endl;
627 }
628
629 return true;
630}
631
633 const NekDouble oldResNorm, const NekDouble newResNorm) const
634{
635 NekDouble ared = oldResNorm - newResNorm;
636 NekDouble thresh =
637 std::max(m_meaningfulAredAbs, m_meaningfulAredRel * oldResNorm);
638 return ared > thresh;
639}
640} // namespace Nektar::LibUtilities
#define ASSERTL0(condition, msg)
#define WARNINGL0(condition, msg)
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
NekDouble CalcL2Norm(const int ntotal, const Array< OneD, const NekDouble > &x) const
bool HasMeaningfulDecrease(const NekDouble oldResNorm, const NekDouble newResNorm) const
bool v_ApplyNewtonUpdate(const int ntotal, const NekDouble oldResNorm) override
Array< OneD, NekDouble > SolveReducedHookStep(const NekLinSysIterGMRES::GMRESHookData &data, const NekDouble Delta) const
std::vector< NekDouble > SolveDenseLinearSystem(std::vector< std::vector< NekDouble > > A, std::vector< NekDouble > b) const
void BuildHookStepFromKrylovBasis(const NekLinSysIterGMRES::GMRESHookData &data, const Array< OneD, const NekDouble > &y, Array< OneD, NekDouble > &delta)
static NekNonlinSysIterSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vComm, const int nDimen, const NekSysKey &pKey)
NekNonlinSysIterNewtonHookStep(const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vComm, const int nDimen, const NekSysKey &pKey)
NekDouble ComputeReducedResidualNorm(const NekLinSysIterGMRES::GMRESHookData &data, const Array< OneD, const NekDouble > &y) const
LibUtilities::CommSharedPtr m_rowComm
Definition NekSys.h:299
NekSysOperators m_operator
Definition NekSys.h:306
void DoNekSysResEval(InArrayType &inarray, OutArrayType &outarray, const bool &flag=false) const
Definition NekSys.h:141
NekNonlinSysIterFactory & GetNekNonlinSysIterFactory()
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition Comm.h:55
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Svtvp (scalar times vector plus vector): z = alpha*x + y.
Definition Vmath.hpp:396
T Dot(int n, const T *w, const T *x)
dot product
Definition Vmath.hpp:761
void Zero(int n, T *x, const int incx)
Zero vector.
Definition Vmath.hpp:273
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition Vmath.hpp:825
STL namespace.
scalarT< T > sqrt(scalarT< T > in)
Definition scalar.hpp:290
Data exported from GMRES for use by the Newton hook-step solver. The data stored here correspond to t...
NekDouble beta
Initial residual norm beta used in || beta e_1 - H y ||_2.
Array< OneD, Array< OneD, NekDouble > > V
Arnoldi basis vectors V_0,...,V_m; contains nswp + 1 vectors of length nGlobal.
Array< OneD, Array< OneD, NekDouble > > H
Arnoldi Hessenberg matrix stored by columns: H[col][row]. H size is (nswp + 1) x nswp.
int nGlobal
Dimension of the system; length of each Krylov vector.
int nDir
Offset to the non-Dirichlet part of the vector; active size is nGlobal - nDir.
int nswp
Current Krylov subspace dimension, number of done Arnoldi sweeps.