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 SetNekLinSysTolerance (const NekDouble in)
 
void SetNekLinSysMaxIterations (const unsigned int in)
 
int GetNekLinSysTolerance ()
 
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 ()
 
int SolveSystem (const int nGlobal, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int nDir=0)
 
const NekSysOperatorsGetSysOperators ()
 
void SetSysOperators (const NekSysOperators &in)
 
void SetFlagWarnings (bool in)
 
void SetRhsMagnitude (const NekDouble mag)
 

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) override
 
- Protected Member Functions inherited from Nektar::LibUtilities::NekLinSysIter
void v_InitObject () override
 
void SetUniversalUniqueMap ()
 
void Set_Rhs_Magnitude (const Array< OneD, NekDouble > &pIn)
 
void ConvergenceCheck (const Array< OneD, const NekDouble > &Residual)
 
- 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)
 

Protected Attributes

int m_maxrestart
 
int m_KrylovMaxHessMatBand
 
int m_LinSysMaxStorage
 
NekDouble m_prec_factor = 1.0
 
bool m_NekLinSysLeftPrecon = false
 
bool m_NekLinSysRightPrecon = true
 
bool m_GMRESCentralDifference = false
 
- Protected Attributes inherited from Nektar::LibUtilities::NekLinSysIter
Array< OneD, int > m_map
 Global to universal unique map. More...
 
NekDouble m_NekLinSysTolerance
 
int m_NekLinSysMaxIterations
 
int m_totalIterations = 0
 
bool m_isLocal
 
- Protected Attributes inherited from Nektar::LibUtilities::NekSys
LibUtilities::CommSharedPtr m_rowComm
 
bool m_converged
 
bool m_root
 
bool m_verbose
 
bool m_FlagWarnings
 
int m_SysDimen
 
NekSysOperators m_operator
 
NekDouble m_rhs_magnitude = NekConstants::kNekUnsetDouble
 

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 46 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
66 NekDouble(pKey.m_LinSysMaxStorage));
67 m_LinSysMaxStorage = min(m_NekLinSysMaxIterations, pKey.m_LinSysMaxStorage);
68
69 m_GMRESCentralDifference = pKey.m_GMRESCentralDifference;
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)
double NekDouble

References m_GMRESCentralDifference, Nektar::LibUtilities::NekSysKey::m_GMRESCentralDifference, m_hes, Nektar::LibUtilities::NekLinSysIter::m_isLocal, m_KrylovMaxHessMatBand, Nektar::LibUtilities::NekSysKey::m_KrylovMaxHessMatBand, m_LinSysMaxStorage, Nektar::LibUtilities::NekSysKey::m_LinSysMaxStorage, m_maxrestart, m_NekLinSysLeftPrecon, Nektar::LibUtilities::NekSysKey::m_NekLinSysLeftPrecon, Nektar::LibUtilities::NekLinSysIter::m_NekLinSysMaxIterations, 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 52 of file NekLinSysIterGMRESLoc.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:47

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 406 of file NekLinSysIterGMRESLoc.cpp.

413{
414 NekDouble alpha, beta, vExchange = 0.0;
415 LibUtilities::Timer timer;
416 timer.Start();
418 timer.Stop();
419 timer.AccumulateRegion("NekSysOperators::DoNekSysLhsEval", 10);
420
422 {
424 }
425
426 Vmath::Smul(nLocal, sqrt(m_prec_factor), w, 1, w, 1);
427
428 // Modified Gram-Schmidt
429 for (int i = starttem; i < endtem; ++i)
430 {
431 // Do inner product on equivalent of global values excluding
432 // Diriclet conditions. To do this need to assmble (and
433 // scatter back vector and then zero Dirichlet conditions.
434 m_operator.DoAssembleLoc(m_V_total[i], wk, true);
435 vExchange = Vmath::Dot(nLocal, wk, w);
436 m_rowComm->AllReduce(vExchange, LibUtilities::ReduceSum);
437
438 h[i] = vExchange;
439
440 beta = -1.0 * vExchange;
441 Vmath::Svtvp(nLocal, beta, m_V_total[i], 1, w, 1, w, 1);
442 }
443 // end of Modified Gram-Schmidt
444
445 // calculate the L2 norm and normalize
446 m_operator.DoAssembleLoc(w, wk, true);
447 vExchange = Vmath::Dot(nLocal, wk, w);
448 m_rowComm->AllReduce(vExchange, LibUtilities::ReduceSum);
449
450 h[endtem] = sqrt(vExchange);
451
452 alpha = 1.0 / h[endtem];
453 Vmath::Smul(nLocal, alpha, w, 1, V2, 1);
454}
LibUtilities::CommSharedPtr m_rowComm
Definition: NekSys.h:291
NekSysOperators m_operator
Definition: NekSys.h:298
void DoAssembleLoc(InArrayType &xn, OutArrayType &xn1, const bool &flag=false) const
Definition: NekSys.h:162
void DoNekSysPrecon(InArrayType &inarray, OutArrayType &outarray, const bool &flag=false) const
Definition: NekSys.h:149
void DoNekSysLhsEval(InArrayType &inarray, OutArrayType &outarray, const bool &flag=false) const
Definition: NekSys.h:142
@ 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:285

References Nektar::LibUtilities::Timer::AccumulateRegion(), Nektar::LibUtilities::beta, Nektar::LibUtilities::NekSysOperators::DoAssembleLoc(), Nektar::LibUtilities::NekSysOperators::DoNekSysLhsEval(), Nektar::LibUtilities::NekSysOperators::DoNekSysPrecon(), Vmath::Dot(), m_GMRESCentralDifference, m_NekLinSysLeftPrecon, Nektar::LibUtilities::NekSys::m_operator, 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 511 of file NekLinSysIterGMRESLoc.cpp.

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

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 457 of file NekLinSysIterGMRESLoc.cpp.

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

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 119 of file NekLinSysIterGMRESLoc.cpp.

122{
125 {
126 Set_Rhs_Magnitude(pInput);
127 }
128
129 NekDouble eps = 0.0;
130 Array<OneD, NekDouble> tmp;
131
133 m_converged = false;
134
135 bool restarted = false;
136 bool truncted = false;
137
139 {
140 truncted = true;
141 }
142
143 for (int nrestart = 0; nrestart < m_maxrestart; ++nrestart)
144 {
145 eps = DoGmresRestart(restarted, truncted, nLocal, pInput, pOutput);
146
147 if (m_converged)
148 {
149 break;
150 }
151 restarted = true;
152 }
153
154 if (m_verbose)
155 {
156 Array<OneD, NekDouble> r0(nLocal);
157 Array<OneD, NekDouble> wk(nLocal);
158
159 // calculate difference in residual of solution
161
162 // Note this is finding the difference between the whole
163 // residual not jsut the non-Dirichlet values.
164 // Probably OK since just an monitoring output?
165 Vmath::Vsub(nLocal, pInput, 1, r0, 1, r0, 1);
166
167 m_operator.DoAssembleLoc(r0, wk, true);
168 NekDouble vExchange = Vmath::Dot(nLocal, wk, r0);
169
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_NekLinSysTolerance
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 nLocal, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)
Actual iterative gmres solver for one restart.
void Set_Rhs_Magnitude(const Array< OneD, NekDouble > &pIn)
static const NekDouble kNekUnsetDouble
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.
Definition: Vmath.hpp:220

References Nektar::LibUtilities::NekSysOperators::DoAssembleLoc(), DoGmresRestart(), Nektar::LibUtilities::NekSysOperators::DoNekSysLhsEval(), Vmath::Dot(), Nektar::NekConstants::kNekUnsetDouble, Nektar::LibUtilities::NekSys::m_converged, Nektar::LibUtilities::NekSys::m_FlagWarnings, m_GMRESCentralDifference, m_KrylovMaxHessMatBand, m_maxrestart, Nektar::LibUtilities::NekLinSysIter::m_NekLinSysTolerance, Nektar::LibUtilities::NekSys::m_operator, m_prec_factor, Nektar::LibUtilities::NekSys::m_rhs_magnitude, Nektar::LibUtilities::NekSys::m_root, Nektar::LibUtilities::NekSys::m_rowComm, Nektar::LibUtilities::NekLinSysIter::m_totalIterations, Nektar::LibUtilities::NekSys::m_verbose, Nektar::LibUtilities::ReduceSum, Nektar::LibUtilities::NekLinSysIter::Set_Rhs_Magnitude(), tinysimd::sqrt(), Vmath::Vsub(), 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 205 of file NekLinSysIterGMRESLoc.cpp.

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

Definition at line 72 of file NekLinSysIterGMRESLoc.h.

73 {
75 }

References m_LinSysMaxStorage, and m_maxrestart.

◆ 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 
)
overrideprotectedvirtual

Reimplemented from Nektar::LibUtilities::NekSys.

Definition at line 98 of file NekLinSysIterGMRESLoc.cpp.

101{
102 int niterations = DoGMRES(nLocal, pInput, pOutput);
103
104 return niterations;
105}
int DoGMRES(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)
Actual iterative solve-GMRES.

References DoGMRES().

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.
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 NekLinSysIterGMRESLoc.h.

◆ def

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

Definition at line 138 of file NekLinSysIterGMRESLoc.h.

◆ lookupIds

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

Definition at line 137 of file NekLinSysIterGMRESLoc.h.

◆ m_GMRESCentralDifference

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

Definition at line 95 of file NekLinSysIterGMRESLoc.h.

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

◆ m_hes

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

Definition at line 141 of file NekLinSysIterGMRESLoc.h.

Referenced by DoGmresRestart(), and NekLinSysIterGMRESLoc().

◆ m_KrylovMaxHessMatBand

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

Definition at line 83 of file NekLinSysIterGMRESLoc.h.

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

◆ m_LinSysMaxStorage

int Nektar::LibUtilities::NekLinSysIterGMRESLoc::m_LinSysMaxStorage
protected

Definition at line 89 of file NekLinSysIterGMRESLoc.h.

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

◆ m_maxrestart

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

Definition at line 79 of file NekLinSysIterGMRESLoc.h.

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

◆ m_NekLinSysLeftPrecon

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

Definition at line 93 of file NekLinSysIterGMRESLoc.h.

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

◆ m_NekLinSysRightPrecon

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

Definition at line 94 of file NekLinSysIterGMRESLoc.h.

Referenced by DoGmresRestart(), and NekLinSysIterGMRESLoc().

◆ m_prec_factor

NekDouble Nektar::LibUtilities::NekLinSysIterGMRESLoc::m_prec_factor = 1.0
protected

Definition at line 91 of file NekLinSysIterGMRESLoc.h.

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

◆ m_Upper

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

Definition at line 143 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 145 of file NekLinSysIterGMRESLoc.h.

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