76 ? pSession->GetParameter(
"GMRESDeltaDirection")
79 m_flexible = pSession->DefinesParameter(
"FlexibleGMRES")
80 ? pSession->GetParameter(
"FlexibleGMRES")
113 int niterations =
DoGMRES(nGlobal, pInput, pOutput, nDir);
123 iter =
DoGMRES(nGlobal, rhs, x, nDir);
149 int nNonDir = nGlobal - nDir;
162 bool truncted =
false;
169 for (
int nrestart = 0; nrestart <
m_maxrestart; ++nrestart)
172 DoGmresRestart(nrestart, truncted, nGlobal, pInput, pOutput, nDir);
186 Vmath::Vsub(nNonDir, &pInput[0] + nDir, 1, &r0[0] + nDir, 1,
199 <<
" with (GMRES eps = " << eps <<
" REAL eps= " << eps1
205 cout <<
" CONVERGED" << endl;
209 cout <<
" WARNING: Exceeded maxIt" << endl;
222 const unsigned int nrestart,
const bool truncted,
const int nGlobal,
229 int nNonDir = nGlobal - nDir;
278 Vmath::Vcopy(nNonDir, &pInput[0] + nDir, 1, &r0[0] + nDir, 1);
311 vExchange =
Vmath::Dot2(nNonDir, &pInput[0] + nDir,
312 &pInput[0] + nDir, &
m_map[0] + nDir);
333 if (truncted && (starttem) > 0)
335 id_start[nd] = starttem;
344 alpha = 1.0 / eta[0];
392 starttem = id_start[idtem];
393 endtem = id_end[idtem];
395 DoArnoldi(starttem, endtem, nGlobal, nDir, w, Z1, V2, h1);
399 starttem = starttem - 1;
406 eps = eta[nd + 1] * eta[nd + 1];
442 for (
int i = 0; i < nswp + 1; ++i)
449 for (
int i = 0; i < nswp; ++i)
463 for (
int i = 0; i < nswp; ++i)
474 solution.data(), 1, solution.data(), 1);
478 Vmath::Svtvp(nNonDir, y_total[i], &Z_total[i][0] + nDir, 1,
479 solution.data(), 1, solution.data(), 1);
486 auto last = std::move(
m_delta.back());
487 Vmath::Vcopy(nNonDir, solution.data(), 1, &last[0] + nDir, 1);
489 m_delta.push_front(std::move(last));
498 Vmath::Vadd(nNonDir, solution.data(), 1, &pOutput[0] + nDir, 1,
499 &pOutput[0] + nDir, 1);
506 const int nGlobal,
const int nDir,
514 int nNonDir = nGlobal - nDir;
529 for (
int i = starttem; i < endtem; ++i)
537 beta = -1.0 * vExchange;
548 h[endtem] =
sqrt(vExchange);
550 alpha = 1.0 / h[endtem];
551 Vmath::Smul(nNonDir, alpha, &w[0] + nDir, 1, &V2[0] + nDir, 1);
564 int idtem = endtem - 1;
570 for (
int i = starttem; i < idtem; ++i)
572 dbl = c[i] * h[i] - s[i] * h[i + 1];
573 h[i + 1] = s[i] * h[i] + c[i] * h[i + 1];
583 else if (
abs(hh) >
abs(dd))
586 s[idtem] = 1.0 /
sqrt(1.0 + dbl * dbl);
587 c[idtem] = dbl * s[idtem];
592 c[idtem] = 1.0 /
sqrt(1.0 + dbl * dbl);
593 s[idtem] = dbl * c[idtem];
596 h[idtem] = c[idtem] * h[idtem] - s[idtem] * h[endtem];
599 dbl = c[idtem] * eta[idtem] - s[idtem] * eta[endtem];
600 eta[endtem] = s[idtem] * eta[idtem] + c[idtem] * eta[endtem];
614 int maxid = number - 1;
616 y[maxid] = b[maxid] /
A[maxid][maxid];
617 for (
int i = maxid - 1; i > -1; --i)
620 for (
int j = i + 1; j < number; ++j)
623 sum -= y[j] *
A[j][i];
625 y[i] = sum /
A[i][i];
#define WARNINGL1(condition, msg)
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
int v_SolveSystem(const int nGlobal, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int nDir) override
void DoGivensRotation(const int starttem, const int endtem, Array< OneD, NekDouble > &c, Array< OneD, NekDouble > &s, Array< OneD, NekDouble > &h, Array< OneD, NekDouble > &eta)
NekLinSysIterGMRES(const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey=NekSysKey())
Array< OneD, Array< OneD, NekDouble > > m_Z_total
int DoGMRES(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int pNumDir)
Actual iterative solve-GMRES.
NekDouble DoGmresRestart(const unsigned int nrestart, const bool truncted, const int nGlobal, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int nDir)
Actual iterative gmres solver for one restart.
void DoBackward(const int number, Array< OneD, Array< OneD, NekDouble > > &A, const Array< OneD, const NekDouble > &b, Array< OneD, NekDouble > &y)
Array< OneD, Array< OneD, NekDouble > > m_V_total
Array< OneD, Array< OneD, NekDouble > > m_Upper
static std::string className
int m_KrylovMaxHessMatBand
Array< OneD, Array< OneD, NekDouble > > m_hes
void v_InitObject() override
bool m_NekLinSysRightPrecon
void DoArnoldi(const int starttem, const int endtem, const int nGlobal, const int nDir, Array< OneD, NekDouble > &w, Array< OneD, NekDouble > &V1, Array< OneD, NekDouble > &V2, Array< OneD, NekDouble > &h)
bool m_GMRESCentralDifference
bool m_NekLinSysLeftPrecon
static NekLinSysIterSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey)
unsigned int m_GMRESDeltaDirection
void v_DoIterate(const int nGlobal, const Array< OneD, NekDouble > &rhs, Array< OneD, NekDouble > &x, const int nDir, NekDouble &err, int &iter) override
std::deque< Array< OneD, NekDouble > > m_delta
void v_InitObject() override
int m_NekLinSysMaxIterations
void Set_Rhs_Magnitude(const Array< OneD, NekDouble > &pIn)
NekDouble m_NekLinSysTolerance
Array< OneD, int > m_map
Global to universal unique map.
LibUtilities::CommSharedPtr m_rowComm
NekSysOperators m_operator
NekDouble m_rhs_magnitude
bool m_NekLinSysLeftPrecon
bool m_GMRESCentralDifference
bool m_NekLinSysRightPrecon
int m_KrylovMaxHessMatBand
void DoNekSysPrecon(InArrayType &inarray, OutArrayType &outarray, const bool &flag=false) const
void DoNekSysLhsEval(InArrayType &inarray, OutArrayType &outarray, const bool &flag=false) const
void AccumulateRegion(std::string, int iolevel=0)
Accumulate elapsed time for a region.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
NekLinSysIterFactory & GetNekLinSysIterFactory()
@ beta
Gauss Radau pinned at x=-1,.
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
static const NekDouble kNekUnsetDouble
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.
T Dot2(int n, const T *w, const T *x, const int *y)
dot product
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
void Zero(int n, T *x, const int incx)
Zero vector.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
scalarT< T > abs(scalarT< T > in)
scalarT< T > min(scalarT< T > lhs, scalarT< T > rhs)
scalarT< T > sqrt(scalarT< T > in)
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.
bool valid
True if hook step data is usable.
Array< OneD, Array< OneD, NekDouble > > H
Arnoldi Hessenberg matrix stored by columns: H[col][row]. H size is (nswp + 1) x nswp.
Array< OneD, NekDouble > yNewton
Unconstrained reduced GMRES solution y of size 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.