Nektar++
Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | Static Private Attributes | Friends | List of all members
Nektar::LibUtilities::NekLinSysIterGMRES Class Reference

#include <NekLinSysIterGMRES.h>

Inheritance diagram for Nektar::LibUtilities::NekLinSysIterGMRES:
[legend]

Public Member Functions

 NekLinSysIterGMRES (const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey=NekSysKey())
 
 ~NekLinSysIterGMRES () override=default
 
int GetMaxLinIte ()
 
- Public Member Functions inherited from Nektar::LibUtilities::NekLinSysIter
 NekLinSysIter (const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey)
 
 ~NekLinSysIter () override=default
 
void SetUniversalUniqueMap (const Array< OneD, const int > &map)
 
void setRhsMagnitude (const NekDouble mag)
 
void SetNekLinSysMaxIterations (const unsigned int in)
 
void SetLinSysMaxStorage (const unsigned int in)
 
bool IsLocal ()
 
- Public Member Functions inherited from Nektar::LibUtilities::NekSys
 NekSys (const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey)
 
virtual ~NekSys ()=default
 
void InitObject ()
 
void SetSysOperators (const NekSysOperators &in)
 
const NekSysOperatorsGetSysOperators ()
 
int SolveSystem (const int nGlobal, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int nDir, const NekDouble tol=1.0E-7, const NekDouble factor=1.0)
 
bool ConvergenceCheck (const int nIteration, const Array< OneD, const NekDouble > &Residual, const NekDouble tol=1.0E-7)
 
void SetFlagWarnings (bool in)
 

Static Public Member Functions

static NekLinSysIterSharedPtr create (const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey)
 
- Static Public Member Functions inherited from Nektar::LibUtilities::NekLinSysIter
static NekLinSysIterSharedPtr CreateInstance (const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey)
 
- Static Public Member Functions inherited from Nektar::LibUtilities::NekSys
static NekSysSharedPtr CreateInstance (const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey)
 

Static Public Attributes

static std::string className
 

Protected Member Functions

void v_InitObject () override
 
int v_SolveSystem (const int nGlobal, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int nDir, const NekDouble tol, const NekDouble factor) override
 
- Protected Member Functions inherited from Nektar::LibUtilities::NekLinSysIter
void Set_Rhs_Magnitude (const NekVector< NekDouble > &pIn)
 
void Set_Rhs_Magnitude (const Array< OneD, NekDouble > &pIn)
 
void SetUniversalUniqueMap ()
 
void v_InitObject () override
 
- Protected Member Functions inherited from Nektar::LibUtilities::NekSys
virtual void v_InitObject ()
 
virtual void v_SetSysOperators (const NekSysOperators &in)
 
virtual int v_SolveSystem (const int nGlobal, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int nDir, const NekDouble tol, const NekDouble factor)
 
virtual bool v_ConvergenceCheck (const int nIteration, const Array< OneD, const NekDouble > &Residual, const NekDouble tol)
 
virtual void v_NekSysInitialGuess (const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pguess)
 

Protected Attributes

int m_maxrestart
 
int m_KrylovMaxHessMatBand
 
bool m_NekLinSysLeftPrecon = false
 
bool m_NekLinSysRightPrecon = true
 
bool m_DifferenceFlag0 = false
 
bool m_DifferenceFlag1 = false
 
- Protected Attributes inherited from Nektar::LibUtilities::NekLinSysIter
Array< OneD, int > m_map
 Global to universal unique map. More...
 
NekDouble m_rhs_magnitude = NekConstants::kNekUnsetDouble
 Dot product of rhs to normalise stopping criterion. More...
 
int m_totalIterations = 0
 
NekDouble m_prec_factor = 1.0
 
int m_LinSysMaxStorage
 
bool m_isLocal
 
- Protected Attributes inherited from Nektar::LibUtilities::NekSys
int m_maxiter
 Maximum iterations. More...
 
NekDouble m_tolerance
 Tolerance of iterative solver. More...
 
LibUtilities::CommSharedPtr m_rowComm
 Communicate. More...
 
bool m_converged
 Whether the iteration has been converged. More...
 
bool m_root
 Root if parallel. More...
 
bool m_verbose
 Verbose. More...
 
bool m_FlagWarnings
 
NekSysOperators m_operator
 Operators. More...
 
int m_SysDimen
 The dimension of the system. More...
 

Private Member Functions

int DoGMRES (const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int pNumDir)
 Actual iterative solve-GMRES. More...
 
NekDouble DoGmresRestart (const bool restarted, 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. More...
 
void DoArnoldi (const int starttem, const int endtem, const int nGlobal, const int nDir, Array< OneD, NekDouble > &w, Array< OneD, NekDouble > &Vsingle1, Array< OneD, NekDouble > &Vsingle2, Array< OneD, NekDouble > &hsingle)
 
void DoGivensRotation (const int starttem, const int endtem, const int nGlobal, const int nDir, Array< OneD, NekDouble > &c, Array< OneD, NekDouble > &s, Array< OneD, NekDouble > &hsingle, Array< OneD, NekDouble > &eta)
 
void DoBackward (const int number, Array< OneD, Array< OneD, NekDouble > > &A, const Array< OneD, const NekDouble > &b, Array< OneD, NekDouble > &y)
 

Private Attributes

Array< OneD, Array< OneD, NekDouble > > m_hes
 
Array< OneD, Array< OneD, NekDouble > > m_Upper
 
Array< OneD, Array< OneD, NekDouble > > m_V_total
 

Static Private Attributes

static std::string lookupIds []
 
static std::string def
 

Friends

class MemoryManager< NekLinSysIterGMRES >
 Support creation through MemoryManager. More...
 

Detailed Description

Solves a linear system using iterative methods.

Definition at line 46 of file NekLinSysIterGMRES.h.

Constructor & Destructor Documentation

◆ NekLinSysIterGMRES()

Nektar::LibUtilities::NekLinSysIterGMRES::NekLinSysIterGMRES ( const LibUtilities::SessionReaderSharedPtr pSession,
const LibUtilities::CommSharedPtr vRowComm,
const int  nDimen,
const NekSysKey pKey = NekSysKey() 
)

Definition at line 52 of file NekLinSysIterGMRES.cpp.

56 : NekLinSysIter(pSession, vRowComm, nDimen, pKey)
57{
58 m_NekLinSysLeftPrecon = pKey.m_NekLinSysLeftPrecon;
59 m_NekLinSysRightPrecon = pKey.m_NekLinSysRightPrecon;
60
61 m_KrylovMaxHessMatBand = pKey.m_KrylovMaxHessMatBand;
62
65
66 m_DifferenceFlag0 = pKey.m_DifferenceFlag0;
67 m_DifferenceFlag1 = pKey.m_DifferenceFlag1;
68
69 // Allocate array storage of coefficients
70 // Hessenburg matrix
71 m_hes = Array<OneD, Array<OneD, NekDouble>>(m_LinSysMaxStorage);
72 for (size_t nd = 0; nd < m_LinSysMaxStorage; nd++)
73 {
74 m_hes[nd] = Array<OneD, NekDouble>(m_LinSysMaxStorage + 1, 0.0);
75 }
76 // Hesseburg matrix after rotation
77 m_Upper = Array<OneD, Array<OneD, NekDouble>>(m_LinSysMaxStorage);
78 for (size_t nd = 0; nd < m_LinSysMaxStorage; nd++)
79 {
80 m_Upper[nd] = Array<OneD, NekDouble>(m_LinSysMaxStorage + 1, 0.0);
81 }
82 // Total search directions
83 m_V_total = Array<OneD, Array<OneD, NekDouble>>(m_LinSysMaxStorage + 1);
84}
Array< OneD, Array< OneD, NekDouble > > m_V_total
Array< OneD, Array< OneD, NekDouble > > m_Upper
Array< OneD, Array< OneD, NekDouble > > m_hes
NekLinSysIter(const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey)
int m_maxiter
Maximum iterations.
Definition: NekSys.h:289
double NekDouble

References m_DifferenceFlag0, Nektar::LibUtilities::NekSysKey::m_DifferenceFlag0, m_DifferenceFlag1, Nektar::LibUtilities::NekSysKey::m_DifferenceFlag1, m_hes, m_KrylovMaxHessMatBand, Nektar::LibUtilities::NekSysKey::m_KrylovMaxHessMatBand, Nektar::LibUtilities::NekLinSysIter::m_LinSysMaxStorage, Nektar::LibUtilities::NekSys::m_maxiter, m_maxrestart, m_NekLinSysLeftPrecon, Nektar::LibUtilities::NekSysKey::m_NekLinSysLeftPrecon, m_NekLinSysRightPrecon, Nektar::LibUtilities::NekSysKey::m_NekLinSysRightPrecon, m_Upper, and m_V_total.

◆ ~NekLinSysIterGMRES()

Nektar::LibUtilities::NekLinSysIterGMRES::~NekLinSysIterGMRES ( )
overridedefault

Member Function Documentation

◆ create()

static NekLinSysIterSharedPtr Nektar::LibUtilities::NekLinSysIterGMRES::create ( const LibUtilities::SessionReaderSharedPtr pSession,
const LibUtilities::CommSharedPtr vRowComm,
const int  nDimen,
const NekSysKey pKey 
)
inlinestatic

Definition at line 52 of file NekLinSysIterGMRES.h.

56 {
59 pSession, vRowComm, nDimen, pKey);
60 p->InitObject();
61 return p;
62 }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< NekLinSysIter > NekLinSysIterSharedPtr
Definition: NekLinSysIter.h:46

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), and CellMLToNektar.cellml_metadata::p.

◆ DoArnoldi()

void Nektar::LibUtilities::NekLinSysIterGMRES::DoArnoldi ( const int  starttem,
const int  endtem,
const int  nGlobal,
const int  nDir,
Array< OneD, NekDouble > &  w,
Array< OneD, NekDouble > &  Vsingle1,
Array< OneD, NekDouble > &  Vsingle2,
Array< OneD, NekDouble > &  hsingle 
)
private

Definition at line 422 of file NekLinSysIterGMRES.cpp.

431{
432 NekDouble alpha, beta, vExchange = 0.0;
433 Array<OneD, NekDouble> tmp;
434 int nNonDir = nGlobal - nDir;
435 LibUtilities::Timer timer;
436 timer.Start();
438 timer.Stop();
439 timer.AccumulateRegion("NekSysOperators::DoNekSysLhsEval", 10);
440
442 {
443 m_operator.DoNekSysPrecon(w + nDir, tmp = w + nDir);
444 }
445
446 Vmath::Smul(nNonDir, sqrt(m_prec_factor), w + nDir, 1, tmp = w + nDir, 1);
447
448 // Modified Gram-Schmidt
449 for (int i = starttem; i < endtem; ++i)
450 {
451 vExchange = Vmath::Dot2(nNonDir, &w[0] + nDir, &m_V_total[i][0] + nDir,
452 &m_map[0] + nDir);
453 m_rowComm->AllReduce(vExchange, LibUtilities::ReduceSum);
454
455 hsingle[i] = vExchange;
456
457 beta = -1.0 * vExchange;
458 Vmath::Svtvp(nNonDir, beta, &m_V_total[i][0] + nDir, 1, &w[0] + nDir, 1,
459 &w[0] + nDir, 1);
460 }
461 // end of Modified Gram-Schmidt
462
463 // calculate the L2 norm and normalize
464 vExchange =
465 Vmath::Dot2(nNonDir, &w[0] + nDir, &w[0] + nDir, &m_map[0] + nDir);
466 m_rowComm->AllReduce(vExchange, LibUtilities::ReduceSum);
467
468 hsingle[endtem] = sqrt(vExchange);
469
470 alpha = 1.0 / hsingle[endtem];
471 Vmath::Smul(nNonDir, alpha, &w[0] + nDir, 1, &Vsingle2[0] + nDir, 1);
472}
Array< OneD, int > m_map
Global to universal unique map.
LibUtilities::CommSharedPtr m_rowComm
Communicate.
Definition: NekSys.h:293
NekSysOperators m_operator
Operators.
Definition: NekSys.h:302
void DoNekSysPrecon(InArrayType &inarray, OutArrayType &outarray, const bool &flag=false) const
Definition: NekSys.h:148
void DoNekSysLhsEval(InArrayType &inarray, OutArrayType &outarray, const bool &flag=false) const
Definition: NekSys.h:141
@ beta
Gauss Radau pinned at x=-1,.
Definition: PointsType.h:59
std::vector< double > w(NPUPPER)
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 Dot2(int n, const T *w, const T *x, const int *y)
dot product
Definition: Vmath.hpp:790
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.hpp:100
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294

References Nektar::LibUtilities::Timer::AccumulateRegion(), Nektar::LibUtilities::beta, Nektar::LibUtilities::NekSysOperators::DoNekSysLhsEval(), Nektar::LibUtilities::NekSysOperators::DoNekSysPrecon(), Vmath::Dot2(), m_DifferenceFlag1, Nektar::LibUtilities::NekLinSysIter::m_map, m_NekLinSysLeftPrecon, Nektar::LibUtilities::NekSys::m_operator, Nektar::LibUtilities::NekLinSysIter::m_prec_factor, Nektar::LibUtilities::NekSys::m_rowComm, m_V_total, Nektar::LibUtilities::ReduceSum, Vmath::Smul(), tinysimd::sqrt(), Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), Vmath::Svtvp(), and Nektar::UnitTests::w().

Referenced by DoGmresRestart().

◆ DoBackward()

void Nektar::LibUtilities::NekLinSysIterGMRES::DoBackward ( const int  number,
Array< OneD, Array< OneD, NekDouble > > &  A,
const Array< OneD, const NekDouble > &  b,
Array< OneD, NekDouble > &  y 
)
private

Definition at line 529 of file NekLinSysIterGMRES.cpp.

533{
534 // Number is the entry number
535 // but C++'s order need to be one smaller
536 int maxid = number - 1;
537 NekDouble sum;
538 y[maxid] = b[maxid] / A[maxid][maxid];
539 for (int i = maxid - 1; i > -1; --i)
540 {
541 sum = b[i];
542 for (int j = i + 1; j < number; ++j)
543 {
544 // i and j changes due to use Array<OneD,Array<OneD,NekDouble>>
545 sum -= y[j] * A[j][i];
546 }
547 y[i] = sum / A[i][i];
548 }
549}

Referenced by DoGmresRestart().

◆ DoGivensRotation()

void Nektar::LibUtilities::NekLinSysIterGMRES::DoGivensRotation ( const int  starttem,
const int  endtem,
const int  nGlobal,
const int  nDir,
Array< OneD, NekDouble > &  c,
Array< OneD, NekDouble > &  s,
Array< OneD, NekDouble > &  hsingle,
Array< OneD, NekDouble > &  eta 
)
private

Definition at line 475 of file NekLinSysIterGMRES.cpp.

482{
483 NekDouble temp_dbl;
484 NekDouble dd;
485 NekDouble hh;
486 int idtem = endtem - 1;
487 // The starttem and endtem are beginning and ending order of Givens rotation
488 // They usually equal to the beginning position and ending position of
489 // Hessenburg matrix But sometimes starttem will change, like if it is
490 // initial 0 and becomes nonzero because previous Givens rotation See Yu
491 // Pan's User Guide
492 for (int i = starttem; i < idtem; ++i)
493 {
494 temp_dbl = c[i] * hsingle[i] - s[i] * hsingle[i + 1];
495 hsingle[i + 1] = s[i] * hsingle[i] + c[i] * hsingle[i + 1];
496 hsingle[i] = temp_dbl;
497 }
498 dd = hsingle[idtem];
499 hh = hsingle[endtem];
500 if (hh == 0.0)
501 {
502 c[idtem] = 1.0;
503 s[idtem] = 0.0;
504 }
505 else if (abs(hh) > abs(dd))
506 {
507 temp_dbl = -dd / hh;
508 s[idtem] = 1.0 / sqrt(1.0 + temp_dbl * temp_dbl);
509 c[idtem] = temp_dbl * s[idtem];
510 }
511 else
512 {
513 temp_dbl = -hh / dd;
514 c[idtem] = 1.0 / sqrt(1.0 + temp_dbl * temp_dbl);
515 s[idtem] = temp_dbl * c[idtem];
516 }
517
518 hsingle[idtem] = c[idtem] * hsingle[idtem] - s[idtem] * hsingle[endtem];
519 hsingle[endtem] = 0.0;
520
521 temp_dbl = c[idtem] * eta[idtem] - s[idtem] * eta[endtem];
522 eta[endtem] = s[idtem] * eta[idtem] + c[idtem] * eta[endtem];
523 eta[idtem] = temp_dbl;
524}
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:298

References tinysimd::abs(), and tinysimd::sqrt().

Referenced by DoGmresRestart().

◆ DoGMRES()

int Nektar::LibUtilities::NekLinSysIterGMRES::DoGMRES ( const int  nGlobal,
const Array< OneD, const NekDouble > &  pInput,
Array< OneD, NekDouble > &  pOutput,
const int  nDir 
)
private

Actual iterative solve-GMRES.

  Solve a global linear system using the Gmres  We solve only for the non-Dirichlet modes. The operator is evaluated   using an auxiliary function v_DoMatrixMultiply defined by the   specific solver. Distributed math routines are used to support   parallel execution of the solver.    

Parameters
pInputInput residual of all DOFs.  
pOutputSolution vector of all DOFs.  

Definition at line 116 of file NekLinSysIterGMRES.cpp.

119{
121
123 {
124 NekVector<NekDouble> inGlob(nGlobal, pInput, eWrapper);
125 Set_Rhs_Magnitude(inGlob);
126 }
127
128 // Get vector sizes
129 NekDouble eps = 0.0;
130 int nNonDir = nGlobal - nDir;
131
132 Array<OneD, NekDouble> tmp;
133
134 // zero homogeneous out array ready for solution updates
135 // Should not be earlier in case input vector is same as
136 // output and above copy has been peformed
137 Vmath::Zero(nNonDir, tmp = pOutput + nDir, 1);
138
140 m_converged = false;
141
142 bool restarted = false;
143 bool truncted = false;
144
146 {
147 truncted = true;
148 }
149
150 for (int nrestart = 0; nrestart < m_maxrestart; ++nrestart)
151 {
152 eps =
153 DoGmresRestart(restarted, truncted, nGlobal, pInput, pOutput, nDir);
154
155 if (m_converged)
156 {
157 break;
158 }
159 restarted = true;
160 }
161
162 if (m_verbose)
163 {
164 Array<OneD, NekDouble> r0(nGlobal, 0.0);
166 Vmath::Svtvp(nNonDir, -1.0, &r0[0] + nDir, 1, &pInput[0] + nDir, 1,
167 &r0[0] + nDir, 1);
168 NekDouble vExchange = Vmath::Dot2(nNonDir, &r0[0] + nDir, &r0[0] + nDir,
169 &m_map[0] + nDir);
170 m_rowComm->AllReduce(vExchange, LibUtilities::ReduceSum);
171 NekDouble eps1 = vExchange;
172
173 if (m_root)
174 {
175 int nwidthcolm = 13;
176
177 cout << std::scientific << std::setw(nwidthcolm)
178 << std::setprecision(nwidthcolm - 8)
179 << " GMRES iterations made = " << m_totalIterations
180 << " using tolerance of " << m_tolerance
181 << " (error = " << sqrt(eps * m_prec_factor / m_rhs_magnitude)
182 << ")";
183
184 cout << " WITH (GMRES eps = " << eps << " REAL eps= " << eps1
185 << ")";
186
187 if (m_converged)
188 {
189 cout << " CONVERGED" << endl;
190 }
191 else
192 {
193 cout << " WARNING: Exceeded maxIt" << endl;
194 }
195 }
196 }
197
198 if (m_FlagWarnings)
199 {
200 WARNINGL1(m_converged, "GMRES did not converge.");
201 }
202 return m_totalIterations;
203}
#define WARNINGL1(condition, msg)
Definition: ErrorUtil.hpp:243
NekDouble DoGmresRestart(const bool restarted, 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.
NekDouble m_rhs_magnitude
Dot product of rhs to normalise stopping criterion.
void Set_Rhs_Magnitude(const NekVector< NekDouble > &pIn)
bool m_root
Root if parallel.
Definition: NekSys.h:297
bool m_verbose
Verbose.
Definition: NekSys.h:299
NekDouble m_tolerance
Tolerance of iterative solver.
Definition: NekSys.h:291
bool m_converged
Whether the iteration has been converged.
Definition: NekSys.h:295
static const NekDouble kNekUnsetDouble
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.hpp:273

References DoGmresRestart(), Nektar::LibUtilities::NekSysOperators::DoNekSysLhsEval(), Vmath::Dot2(), Nektar::eWrapper, Nektar::NekConstants::kNekUnsetDouble, Nektar::LibUtilities::NekSys::m_converged, m_DifferenceFlag0, Nektar::LibUtilities::NekSys::m_FlagWarnings, m_KrylovMaxHessMatBand, Nektar::LibUtilities::NekLinSysIter::m_map, m_maxrestart, Nektar::LibUtilities::NekSys::m_operator, Nektar::LibUtilities::NekLinSysIter::m_prec_factor, Nektar::LibUtilities::NekLinSysIter::m_rhs_magnitude, Nektar::LibUtilities::NekSys::m_root, Nektar::LibUtilities::NekSys::m_rowComm, Nektar::LibUtilities::NekSys::m_tolerance, Nektar::LibUtilities::NekLinSysIter::m_totalIterations, Nektar::LibUtilities::NekSys::m_verbose, Nektar::LibUtilities::ReduceSum, Nektar::LibUtilities::NekLinSysIter::Set_Rhs_Magnitude(), tinysimd::sqrt(), Vmath::Svtvp(), WARNINGL1, and Vmath::Zero().

Referenced by v_SolveSystem().

◆ DoGmresRestart()

NekDouble Nektar::LibUtilities::NekLinSysIterGMRES::DoGmresRestart ( const bool  restarted,
const bool  truncted,
const int  nGlobal,
const Array< OneD, const NekDouble > &  pInput,
Array< OneD, NekDouble > &  pOutput,
const int  nDir 
)
private

Actual iterative gmres solver for one restart.

Definition at line 205 of file NekLinSysIterGMRES.cpp.

209{
210 int nNonDir = nGlobal - nDir;
211
212 // Allocate array storage of coefficients
213 // Residual
214 Array<OneD, NekDouble> eta(m_LinSysMaxStorage + 1, 0.0);
215 // Givens rotation c
216 Array<OneD, NekDouble> cs(m_LinSysMaxStorage, 0.0);
217 // Givens rotation s
218 Array<OneD, NekDouble> sn(m_LinSysMaxStorage, 0.0);
219 // Total coefficients, just for check
220 Array<OneD, NekDouble> y_total(m_LinSysMaxStorage, 0.0);
221 // Search direction order
222 Array<OneD, int> id(m_LinSysMaxStorage, 0);
223 Array<OneD, int> id_start(m_LinSysMaxStorage, 0);
224 Array<OneD, int> id_end(m_LinSysMaxStorage, 0);
225 // Temporary variables
226 int idtem;
227 int starttem;
228 int endtem;
229
230 NekDouble eps;
231 NekDouble beta, alpha;
232 NekDouble vExchange = 0;
233 // Temporary Array
234 Array<OneD, NekDouble> w(nGlobal, 0.0);
235 Array<OneD, NekDouble> wk(nGlobal, 0.0);
236 Array<OneD, NekDouble> r0(nGlobal, 0.0);
237 Array<OneD, NekDouble> tmp;
238 Array<OneD, NekDouble> Vsingle1;
239 Array<OneD, NekDouble> Vsingle2;
240 Array<OneD, NekDouble> hsingle1;
241 Array<OneD, NekDouble> hsingle2;
242
243 if (restarted)
244 {
245 // This is A*x
247
248 // The first search direction
249 beta = -1.0;
250
251 // This is r0 = b-A*x
252 Vmath::Svtvp(nNonDir, beta, &r0[0] + nDir, 1, &pInput[0] + nDir, 1,
253 &r0[0] + nDir, 1);
254 }
255 else
256 {
257 // This is r0 = b, x = x0 assumed to be zero
258 Vmath::Vcopy(nNonDir, &pInput[0] + nDir, 1, &r0[0] + nDir, 1);
259 }
260
262 {
263 m_operator.DoNekSysPrecon(r0 + nDir, tmp = r0 + nDir);
264 }
265
266 // Norm of (r0)
267 // The m_map tells how to connect
268 vExchange =
269 Vmath::Dot2(nNonDir, &r0[0] + nDir, &r0[0] + nDir, &m_map[0] + nDir);
270 m_rowComm->AllReduce(vExchange, LibUtilities::ReduceSum);
271 eps = vExchange;
272
273 // Detect zero input array
274 // Causes Arnoldi to breakdown, hence stop here
276 {
277 m_converged = true;
279 {
280 m_prec_factor = 1.0;
281 }
282 return eps;
283 }
284
285 if (!restarted)
286 {
289 {
290 // Evaluate initial residual error for exit check
291 vExchange = Vmath::Dot2(nNonDir, &pInput[0] + nDir,
292 &pInput[0] + nDir, &m_map[0] + nDir);
293 m_rowComm->AllReduce(vExchange, LibUtilities::ReduceSum);
294 m_prec_factor = vExchange / eps;
295 }
296 else
297 {
298 m_prec_factor = 1.0;
299 }
300 }
301
302 Vmath::Smul(nNonDir, sqrt(m_prec_factor), r0 + nDir, 1, tmp = r0 + nDir, 1);
303 eps = eps * m_prec_factor;
304 eta[0] = sqrt(eps);
305
306 // Give an order for the entries in Hessenburg matrix
307 for (int nd = 0; nd < m_LinSysMaxStorage; ++nd)
308 {
309 id[nd] = nd;
310 id_end[nd] = nd + 1;
311 starttem = id_end[nd] - m_KrylovMaxHessMatBand;
312 if (truncted && (starttem) > 0)
313 {
314 id_start[nd] = starttem;
315 }
316 else
317 {
318 id_start[nd] = 0;
319 }
320 }
321
322 // Normlized by r0 norm V(:,1)=r0/norm(r0)
323 alpha = 1.0 / eta[0];
324
325 // Scalar multiplication
326 if (m_V_total[0].size() == 0)
327 {
328 m_V_total[0] = Array<OneD, NekDouble>(nGlobal, 0.0);
329 }
330 Vmath::Smul(nNonDir, alpha, &r0[0] + nDir, 1, &m_V_total[0][0] + nDir, 1);
331
332 // Restarted Gmres(m) process
334 {
335 Vsingle1 = Array<OneD, NekDouble>(nGlobal, 0.0);
336 }
337
338 int nswp = 0;
339 for (int nd = 0; nd < m_LinSysMaxStorage; ++nd)
340 {
341 if (m_V_total[nd + 1].size() == 0)
342 {
343 m_V_total[nd + 1] = Array<OneD, NekDouble>(nGlobal, 0.0);
344 }
345 Vmath::Zero(nGlobal, m_V_total[nd + 1], 1);
347 Vsingle2 = m_V_total[nd + 1];
348 hsingle1 = m_hes[nd];
349
351 {
353 tmp = Vsingle1 + nDir);
354 }
355 else
356 {
357 Vsingle1 = m_V_total[nd];
358 }
359
360 // w here is no need to add nDir due to temporary Array
361 idtem = id[nd];
362 starttem = id_start[idtem];
363 endtem = id_end[idtem];
364
365 DoArnoldi(starttem, endtem, nGlobal, nDir, w, Vsingle1, Vsingle2,
366 hsingle1);
367
368 if (starttem > 0)
369 {
370 starttem = starttem - 1;
371 }
372
373 hsingle2 = m_Upper[nd];
374 Vmath::Vcopy(m_LinSysMaxStorage + 1, &hsingle1[0], 1, &hsingle2[0], 1);
375 DoGivensRotation(starttem, endtem, nGlobal, nDir, cs, sn, hsingle2,
376 eta);
377
378 eps = eta[nd + 1] * eta[nd + 1];
379
380 // This Gmres merge truncted Gmres to accelerate.
381 // If truncted, cannot jump out because
382 // the last term of eta is not residual
383 if ((!truncted) || (nd < m_KrylovMaxHessMatBand))
384 {
385 if ((eps < m_tolerance * m_tolerance * m_rhs_magnitude) && nd > 0)
386 {
387 m_converged = true;
388 }
389 }
390 nswp++;
392
393 if (m_converged)
394 {
395 break;
396 }
397 }
398
399 DoBackward(nswp, m_Upper, eta, y_total);
400
401 // Calculate output V_total * y_total.
402 Array<OneD, NekDouble> solution(nNonDir, 0.0);
403 for (int i = 0; i < nswp; ++i)
404 {
405 Vmath::Svtvp(nNonDir, y_total[i], &m_V_total[i][0] + nDir, 1,
406 solution.get(), 1, solution.get(), 1);
407 }
408
410 {
411 m_operator.DoNekSysPrecon(solution, solution);
412 }
413
414 // Update output.
415 Vmath::Vadd(nNonDir, solution.get(), 1, &pOutput[0] + nDir, 1,
416 &pOutput[0] + nDir, 1);
417
418 return eps;
419}
void DoBackward(const int number, Array< OneD, Array< OneD, NekDouble > > &A, const Array< OneD, const NekDouble > &b, Array< OneD, NekDouble > &y)
void DoGivensRotation(const int starttem, const int endtem, const int nGlobal, const int nDir, Array< OneD, NekDouble > &c, Array< OneD, NekDouble > &s, Array< OneD, NekDouble > &hsingle, Array< OneD, NekDouble > &eta)
void DoArnoldi(const int starttem, const int endtem, const int nGlobal, const int nDir, Array< OneD, NekDouble > &w, Array< OneD, NekDouble > &Vsingle1, Array< OneD, NekDouble > &Vsingle2, Array< OneD, NekDouble > &hsingle)
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.
Definition: Vmath.hpp:180
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825

References Nektar::LibUtilities::beta, DoArnoldi(), DoBackward(), DoGivensRotation(), Nektar::LibUtilities::NekSysOperators::DoNekSysLhsEval(), Nektar::LibUtilities::NekSysOperators::DoNekSysPrecon(), Vmath::Dot2(), Nektar::NekConstants::kNekUnsetDouble, Nektar::LibUtilities::NekSys::m_converged, m_DifferenceFlag0, m_hes, m_KrylovMaxHessMatBand, Nektar::LibUtilities::NekLinSysIter::m_LinSysMaxStorage, Nektar::LibUtilities::NekLinSysIter::m_map, m_NekLinSysLeftPrecon, m_NekLinSysRightPrecon, Nektar::LibUtilities::NekSys::m_operator, Nektar::LibUtilities::NekLinSysIter::m_prec_factor, Nektar::LibUtilities::NekLinSysIter::m_rhs_magnitude, Nektar::LibUtilities::NekSys::m_rowComm, Nektar::LibUtilities::NekSys::m_tolerance, Nektar::LibUtilities::NekLinSysIter::m_totalIterations, m_Upper, m_V_total, Nektar::LibUtilities::ReduceSum, Vmath::Smul(), tinysimd::sqrt(), Vmath::Svtvp(), Vmath::Vadd(), Vmath::Vcopy(), Nektar::UnitTests::w(), and Vmath::Zero().

Referenced by DoGMRES().

◆ GetMaxLinIte()

int Nektar::LibUtilities::NekLinSysIterGMRES::GetMaxLinIte ( )
inline

◆ v_InitObject()

void Nektar::LibUtilities::NekLinSysIterGMRES::v_InitObject ( )
overrideprotectedvirtual

◆ v_SolveSystem()

int Nektar::LibUtilities::NekLinSysIterGMRES::v_SolveSystem ( const int  nGlobal,
const Array< OneD, const NekDouble > &  pInput,
Array< OneD, NekDouble > &  pOutput,
const int  nDir,
const NekDouble  tol,
const NekDouble  factor 
)
overrideprotectedvirtual

Reimplemented from Nektar::LibUtilities::NekSys.

Definition at line 94 of file NekLinSysIterGMRES.cpp.

98{
99 m_tolerance = max(tol, 1.0E-15);
100 int niterations = DoGMRES(nGlobal, pInput, pOutput, nDir);
101
102 return niterations;
103}
int DoGMRES(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int pNumDir)
Actual iterative solve-GMRES.

References DoGMRES(), and Nektar::LibUtilities::NekSys::m_tolerance.

Friends And Related Function Documentation

◆ MemoryManager< NekLinSysIterGMRES >

friend class MemoryManager< NekLinSysIterGMRES >
friend

Support creation through MemoryManager.

Definition at line 1 of file NekLinSysIterGMRES.h.

Member Data Documentation

◆ className

string Nektar::LibUtilities::NekLinSysIterGMRES::className
static
Initial value:
=
"GMRES", NekLinSysIterGMRES::create, "NekLinSysIterGMRES solver.")
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:197
static NekLinSysIterSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey)
NekLinSysIterFactory & GetNekLinSysIterFactory()

Definition at line 64 of file NekLinSysIterGMRES.h.

◆ def

std::string Nektar::LibUtilities::NekLinSysIterGMRES::def
staticprivate

Definition at line 130 of file NekLinSysIterGMRES.h.

◆ lookupIds

std::string Nektar::LibUtilities::NekLinSysIterGMRES::lookupIds[]
staticprivate

Definition at line 129 of file NekLinSysIterGMRES.h.

◆ m_DifferenceFlag0

bool Nektar::LibUtilities::NekLinSysIterGMRES::m_DifferenceFlag0 = false
protected

Definition at line 88 of file NekLinSysIterGMRES.h.

Referenced by DoGMRES(), DoGmresRestart(), and NekLinSysIterGMRES().

◆ m_DifferenceFlag1

bool Nektar::LibUtilities::NekLinSysIterGMRES::m_DifferenceFlag1 = false
protected

Definition at line 89 of file NekLinSysIterGMRES.h.

Referenced by DoArnoldi(), and NekLinSysIterGMRES().

◆ m_hes

Array<OneD, Array<OneD, NekDouble> > Nektar::LibUtilities::NekLinSysIterGMRES::m_hes
private

Definition at line 133 of file NekLinSysIterGMRES.h.

Referenced by DoGmresRestart(), and NekLinSysIterGMRES().

◆ m_KrylovMaxHessMatBand

int Nektar::LibUtilities::NekLinSysIterGMRES::m_KrylovMaxHessMatBand
protected

Definition at line 83 of file NekLinSysIterGMRES.h.

Referenced by DoGMRES(), DoGmresRestart(), and NekLinSysIterGMRES().

◆ m_maxrestart

int Nektar::LibUtilities::NekLinSysIterGMRES::m_maxrestart
protected

Definition at line 79 of file NekLinSysIterGMRES.h.

Referenced by DoGMRES(), GetMaxLinIte(), and NekLinSysIterGMRES().

◆ m_NekLinSysLeftPrecon

bool Nektar::LibUtilities::NekLinSysIterGMRES::m_NekLinSysLeftPrecon = false
protected

Definition at line 85 of file NekLinSysIterGMRES.h.

Referenced by DoArnoldi(), DoGmresRestart(), and NekLinSysIterGMRES().

◆ m_NekLinSysRightPrecon

bool Nektar::LibUtilities::NekLinSysIterGMRES::m_NekLinSysRightPrecon = true
protected

Definition at line 86 of file NekLinSysIterGMRES.h.

Referenced by DoGmresRestart(), and NekLinSysIterGMRES().

◆ m_Upper

Array<OneD, Array<OneD, NekDouble> > Nektar::LibUtilities::NekLinSysIterGMRES::m_Upper
private

Definition at line 135 of file NekLinSysIterGMRES.h.

Referenced by DoGmresRestart(), and NekLinSysIterGMRES().

◆ m_V_total

Array<OneD, Array<OneD, NekDouble> > Nektar::LibUtilities::NekLinSysIterGMRES::m_V_total
private

Definition at line 137 of file NekLinSysIterGMRES.h.

Referenced by DoArnoldi(), DoGmresRestart(), and NekLinSysIterGMRES().