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::NekLinSysIterGMRESLoc Class Reference

#include <NekLinSysIterGMRESLoc.h>

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

Public Member Functions

 NekLinSysIterGMRESLoc (const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey=NekSysKey())
 
 ~NekLinSysIterGMRESLoc () 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 nLocal, 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)
 Actual iterative solve-GMRES. More...
 
NekDouble DoGmresRestart (const bool restarted, const bool truncted, const int nLocal, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)
 Actual iterative gmres solver for one restart. More...
 
void DoArnoldi (const int starttem, const int endtem, const int nLocal, Array< OneD, NekDouble > &w, Array< OneD, NekDouble > &wk, Array< OneD, NekDouble > &V1, Array< OneD, NekDouble > &V2, Array< OneD, NekDouble > &h)
 
void DoGivensRotation (const int starttem, const int endtem, Array< OneD, NekDouble > &c, Array< OneD, NekDouble > &s, Array< OneD, NekDouble > &h, 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< NekLinSysIterGMRESLoc >
 Support creation through MemoryManager. More...
 

Detailed Description

Solves a linear system using iterative methods using local storage rather than global

Definition at line 45 of file NekLinSysIterGMRESLoc.h.

Constructor & Destructor Documentation

◆ NekLinSysIterGMRESLoc()

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

Definition at line 54 of file NekLinSysIterGMRESLoc.cpp.

58 : NekLinSysIter(pSession, vRowComm, nDimen, pKey)
59{
60 m_NekLinSysLeftPrecon = pKey.m_NekLinSysLeftPrecon;
61 m_NekLinSysRightPrecon = pKey.m_NekLinSysRightPrecon;
62
63 m_KrylovMaxHessMatBand = pKey.m_KrylovMaxHessMatBand;
64
67
68 m_DifferenceFlag0 = pKey.m_DifferenceFlag0;
69 m_DifferenceFlag1 = pKey.m_DifferenceFlag1;
70
71 m_isLocal = true;
72
73 // Allocate array storage of coefficients
74 // Hessenburg matrix
75 m_hes = Array<OneD, Array<OneD, NekDouble>>(m_LinSysMaxStorage);
76 for (size_t nd = 0; nd < m_LinSysMaxStorage; nd++)
77 {
78 m_hes[nd] = Array<OneD, NekDouble>(m_LinSysMaxStorage + 1, 0.0);
79 }
80 // Hesseburg matrix after rotation
81 m_Upper = Array<OneD, Array<OneD, NekDouble>>(m_LinSysMaxStorage);
82 for (size_t nd = 0; nd < m_LinSysMaxStorage; nd++)
83 {
84 m_Upper[nd] = Array<OneD, NekDouble>(m_LinSysMaxStorage + 1, 0.0);
85 }
86 // Total search directions
87 m_V_total = Array<OneD, Array<OneD, NekDouble>>(m_LinSysMaxStorage + 1);
88}
Array< OneD, Array< OneD, NekDouble > > m_V_total
Array< OneD, Array< OneD, NekDouble > > m_hes
Array< OneD, Array< OneD, NekDouble > > m_Upper
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, Nektar::LibUtilities::NekLinSysIter::m_isLocal, 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.

◆ ~NekLinSysIterGMRESLoc()

Nektar::LibUtilities::NekLinSysIterGMRESLoc::~NekLinSysIterGMRESLoc ( )
overridedefault

Member Function Documentation

◆ create()

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

Definition at line 51 of file NekLinSysIterGMRESLoc.h.

55 {
58 pSession, vRowComm, nDimen, pKey);
59 p->InitObject();
60 return p;
61 }
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::NekLinSysIterGMRESLoc::DoArnoldi ( const int  starttem,
const int  endtem,
const int  nLocal,
Array< OneD, NekDouble > &  w,
Array< OneD, NekDouble > &  wk,
Array< OneD, NekDouble > &  V1,
Array< OneD, NekDouble > &  V2,
Array< OneD, NekDouble > &  h 
)
private

Definition at line 408 of file NekLinSysIterGMRESLoc.cpp.

415{
416 NekDouble alpha, beta, vExchange = 0.0;
417 LibUtilities::Timer timer;
418 timer.Start();
420 timer.Stop();
421 timer.AccumulateRegion("NekSysOperators::DoNekSysLhsEval", 10);
422
424 {
426 }
427
428 Vmath::Smul(nLocal, sqrt(m_prec_factor), w, 1, w, 1);
429
430 // Modified Gram-Schmidt
431 for (int i = starttem; i < endtem; ++i)
432 {
433 // Do inner product on equivalent of global values excluding
434 // Diriclet conditions. To do this need to assmble (and
435 // scatter back vector and then zero Dirichlet conditions.
436 m_operator.DoAssembleLoc(m_V_total[i], wk, true);
437 vExchange = Vmath::Dot(nLocal, wk, w);
438 m_rowComm->AllReduce(vExchange, LibUtilities::ReduceSum);
439
440 h[i] = vExchange;
441
442 beta = -1.0 * vExchange;
443 Vmath::Svtvp(nLocal, beta, m_V_total[i], 1, w, 1, w, 1);
444 }
445 // end of Modified Gram-Schmidt
446
447 // calculate the L2 norm and normalize
448 m_operator.DoAssembleLoc(w, wk, true);
449 vExchange = Vmath::Dot(nLocal, wk, w);
450 m_rowComm->AllReduce(vExchange, LibUtilities::ReduceSum);
451
452 h[endtem] = sqrt(vExchange);
453
454 alpha = 1.0 / h[endtem];
455 Vmath::Smul(nLocal, alpha, w, 1, V2, 1);
456}
LibUtilities::CommSharedPtr m_rowComm
Communicate.
Definition: NekSys.h:293
NekSysOperators m_operator
Operators.
Definition: NekSys.h:302
void DoAssembleLoc(InArrayType &xn, OutArrayType &xn1, const bool &flag=false) const
Definition: NekSys.h:161
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 Dot(int n, const T *w, const T *x)
dot product
Definition: Vmath.hpp:761
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::DoAssembleLoc(), Nektar::LibUtilities::NekSysOperators::DoNekSysLhsEval(), Nektar::LibUtilities::NekSysOperators::DoNekSysPrecon(), Vmath::Dot(), m_DifferenceFlag1, 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::NekLinSysIterGMRESLoc::DoBackward ( const int  number,
Array< OneD, Array< OneD, NekDouble > > &  A,
const Array< OneD, const NekDouble > &  b,
Array< OneD, NekDouble > &  y 
)
private

Definition at line 513 of file NekLinSysIterGMRESLoc.cpp.

517{
518 // Number is the entry number
519 // but C++'s order need to be one smaller
520 int maxid = number - 1;
521 NekDouble sum;
522 y[maxid] = b[maxid] / A[maxid][maxid];
523 for (int i = maxid - 1; i > -1; --i)
524 {
525 sum = b[i];
526 for (int j = i + 1; j < number; ++j)
527 {
528 // i and j changes due to use Array<OneD,Array<OneD,NekDouble>>
529 sum -= y[j] * A[j][i];
530 }
531 y[i] = sum / A[i][i];
532 }
533}

Referenced by DoGmresRestart().

◆ DoGivensRotation()

void Nektar::LibUtilities::NekLinSysIterGMRESLoc::DoGivensRotation ( const int  starttem,
const int  endtem,
Array< OneD, NekDouble > &  c,
Array< OneD, NekDouble > &  s,
Array< OneD, NekDouble > &  h,
Array< OneD, NekDouble > &  eta 
)
private

Definition at line 459 of file NekLinSysIterGMRESLoc.cpp.

465{
466 NekDouble temp_dbl;
467 NekDouble dd;
468 NekDouble hh;
469 int idtem = endtem - 1;
470 // The starttem and endtem are beginning and ending order of Givens rotation
471 // They usually equal to the beginning position and ending position of
472 // Hessenburg matrix But sometimes starttem will change, like if it is
473 // initial 0 and becomes nonzero because previous Givens rotation See Yu
474 // Pan's User Guide
475 for (int i = starttem; i < idtem; ++i)
476 {
477 temp_dbl = c[i] * h[i] - s[i] * h[i + 1];
478 h[i + 1] = s[i] * h[i] + c[i] * h[i + 1];
479 h[i] = temp_dbl;
480 }
481 dd = h[idtem];
482 hh = h[endtem];
483 if (hh == 0.0)
484 {
485 c[idtem] = 1.0;
486 s[idtem] = 0.0;
487 }
488 else if (abs(hh) > abs(dd))
489 {
490 temp_dbl = -dd / hh;
491 s[idtem] = 1.0 / sqrt(1.0 + temp_dbl * temp_dbl);
492 c[idtem] = temp_dbl * s[idtem];
493 }
494 else
495 {
496 temp_dbl = -hh / dd;
497 c[idtem] = 1.0 / sqrt(1.0 + temp_dbl * temp_dbl);
498 s[idtem] = temp_dbl * c[idtem];
499 }
500
501 h[idtem] = c[idtem] * h[idtem] - s[idtem] * h[endtem];
502 h[endtem] = 0.0;
503
504 temp_dbl = c[idtem] * eta[idtem] - s[idtem] * eta[endtem];
505 eta[endtem] = s[idtem] * eta[idtem] + c[idtem] * eta[endtem];
506 eta[idtem] = temp_dbl;
507}
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:298

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

Referenced by DoGmresRestart().

◆ DoGMRES()

int Nektar::LibUtilities::NekLinSysIterGMRESLoc::DoGMRES ( const int  nLocal,
const Array< OneD, const NekDouble > &  pInput,
Array< OneD, NekDouble > &  pOutput 
)
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 in local format.
pOutputSolution vector in local format but with continuous values

Definition at line 121 of file NekLinSysIterGMRESLoc.cpp.

124{
127 {
128 Set_Rhs_Magnitude(pInput);
129 }
130
131 NekDouble eps = 0.0;
132 Array<OneD, NekDouble> tmp;
133
135 m_converged = false;
136
137 bool restarted = false;
138 bool truncted = false;
139
141 {
142 truncted = true;
143 }
144
145 for (int nrestart = 0; nrestart < m_maxrestart; ++nrestart)
146 {
147 eps = DoGmresRestart(restarted, truncted, nLocal, pInput, pOutput);
148
149 if (m_converged)
150 {
151 break;
152 }
153 restarted = true;
154 }
155
156 if (m_verbose)
157 {
158 Array<OneD, NekDouble> r0(nLocal);
159 Array<OneD, NekDouble> wk(nLocal);
160
161 // calculate difference in residual of solution
163
164 // Note this is finding the difference between the whole
165 // residual not jsut the non-Dirichlet values.
166 // Probably OK since just an monitoring output?
167 Vmath::Svtvp(nLocal, -1.0, r0, 1, pInput, 1, r0, 1);
168
169 m_operator.DoAssembleLoc(r0, wk, true);
170 NekDouble vExchange = Vmath::Dot(nLocal, wk, r0);
171
172 m_rowComm->AllReduce(vExchange, LibUtilities::ReduceSum);
173 NekDouble eps1 = vExchange;
174
175 if (m_root)
176 {
177 int nwidthcolm = 13;
178
179 cout << std::scientific << std::setw(nwidthcolm)
180 << std::setprecision(nwidthcolm - 8)
181 << " GMRES iterations made = " << m_totalIterations
182 << " using tolerance of " << m_tolerance
183 << " (error = " << sqrt(eps * m_prec_factor / m_rhs_magnitude)
184 << ")";
185
186 cout << " WITH (GMRES eps = " << eps << " REAL eps= " << eps1
187 << ")";
188
189 if (m_converged)
190 {
191 cout << " CONVERGED" << endl;
192 }
193 else
194 {
195 cout << " WARNING: Exceeded maxIt" << endl;
196 }
197 }
198 }
199
200 if (m_FlagWarnings)
201 {
202 WARNINGL1(m_converged, "GMRES did not converge.");
203 }
204 return m_totalIterations;
205}
#define WARNINGL1(condition, msg)
Definition: ErrorUtil.hpp:243
NekDouble DoGmresRestart(const bool restarted, const bool truncted, const int nLocal, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)
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

References Nektar::LibUtilities::NekSysOperators::DoAssembleLoc(), DoGmresRestart(), Nektar::LibUtilities::NekSysOperators::DoNekSysLhsEval(), Vmath::Dot(), Nektar::NekConstants::kNekUnsetDouble, Nektar::LibUtilities::NekSys::m_converged, m_DifferenceFlag0, Nektar::LibUtilities::NekSys::m_FlagWarnings, m_KrylovMaxHessMatBand, 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(), and WARNINGL1.

Referenced by v_SolveSystem().

◆ DoGmresRestart()

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

Actual iterative gmres solver for one restart.

Definition at line 207 of file NekLinSysIterGMRESLoc.cpp.

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

References ASSERTL0, Nektar::LibUtilities::beta, DoArnoldi(), Nektar::LibUtilities::NekSysOperators::DoAssembleLoc(), DoBackward(), DoGivensRotation(), Nektar::LibUtilities::NekSysOperators::DoNekSysLhsEval(), Nektar::LibUtilities::NekSysOperators::DoNekSysPrecon(), Vmath::Dot(), Nektar::NekConstants::kNekUnsetDouble, Nektar::LibUtilities::NekSys::m_converged, m_DifferenceFlag0, m_hes, m_KrylovMaxHessMatBand, Nektar::LibUtilities::NekLinSysIter::m_LinSysMaxStorage, 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::NekLinSysIterGMRESLoc::GetMaxLinIte ( )
inline

◆ v_InitObject()

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

◆ v_SolveSystem()

int Nektar::LibUtilities::NekLinSysIterGMRESLoc::v_SolveSystem ( const int  nLocal,
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 98 of file NekLinSysIterGMRESLoc.cpp.

102{
103 m_tolerance = max(tol, 1.0E-15);
104 int niterations = DoGMRES(nLocal, pInput, pOutput);
105
106 return niterations;
107}
int DoGMRES(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)
Actual iterative solve-GMRES.

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

Friends And Related Function Documentation

◆ MemoryManager< NekLinSysIterGMRESLoc >

friend class MemoryManager< NekLinSysIterGMRESLoc >
friend

Support creation through MemoryManager.

Definition at line 1 of file NekLinSysIterGMRESLoc.h.

Member Data Documentation

◆ className

string Nektar::LibUtilities::NekLinSysIterGMRESLoc::className
static
Initial value:
=
"NekLinSysIterGMRES local storage 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 62 of file NekLinSysIterGMRESLoc.h.

◆ def

std::string Nektar::LibUtilities::NekLinSysIterGMRESLoc::def
staticprivate

Definition at line 131 of file NekLinSysIterGMRESLoc.h.

◆ lookupIds

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

Definition at line 130 of file NekLinSysIterGMRESLoc.h.

◆ m_DifferenceFlag0

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

Definition at line 86 of file NekLinSysIterGMRESLoc.h.

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

◆ m_DifferenceFlag1

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

Definition at line 87 of file NekLinSysIterGMRESLoc.h.

Referenced by DoArnoldi(), and NekLinSysIterGMRESLoc().

◆ m_hes

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

Definition at line 134 of file NekLinSysIterGMRESLoc.h.

Referenced by DoGmresRestart(), and NekLinSysIterGMRESLoc().

◆ m_KrylovMaxHessMatBand

int Nektar::LibUtilities::NekLinSysIterGMRESLoc::m_KrylovMaxHessMatBand
protected

Definition at line 81 of file NekLinSysIterGMRESLoc.h.

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

◆ m_maxrestart

int Nektar::LibUtilities::NekLinSysIterGMRESLoc::m_maxrestart
protected

Definition at line 77 of file NekLinSysIterGMRESLoc.h.

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

◆ m_NekLinSysLeftPrecon

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

Definition at line 83 of file NekLinSysIterGMRESLoc.h.

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

◆ m_NekLinSysRightPrecon

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

Definition at line 84 of file NekLinSysIterGMRESLoc.h.

Referenced by DoGmresRestart(), and NekLinSysIterGMRESLoc().

◆ m_Upper

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

Definition at line 136 of file NekLinSysIterGMRESLoc.h.

Referenced by DoGmresRestart(), and NekLinSysIterGMRESLoc().

◆ m_V_total

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

Definition at line 138 of file NekLinSysIterGMRESLoc.h.

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