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

#include <NekLinSysIterCG.h>

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

Public Member Functions

 NekLinSysIterCG (const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey)
 Constructor for full direct matrix solve. More...
 
 ~NekLinSysIterCG () override=default
 
- 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)
 

Private Member Functions

void DoConjugateGradient (const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int pNumDir)
 Actual iterative solve. More...
 

Friends

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

Additional Inherited Members

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

Detailed Description

Solves a linear system using iterative methods.

Definition at line 48 of file NekLinSysIterCG.h.

Constructor & Destructor Documentation

◆ NekLinSysIterCG()

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

Constructor for full direct matrix solve.

Definition at line 52 of file NekLinSysIterCG.cpp.

56 : NekLinSysIter(pSession, vRowComm, nDimen, pKey)
57{
58}
NekLinSysIter(const LibUtilities::SessionReaderSharedPtr &pSession, const LibUtilities::CommSharedPtr &vRowComm, const int nDimen, const NekSysKey &pKey)

◆ ~NekLinSysIterCG()

Nektar::LibUtilities::NekLinSysIterCG::~NekLinSysIterCG ( )
overridedefault

Member Function Documentation

◆ create()

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

Definition at line 54 of file NekLinSysIterCG.h.

58 {
61 pSession, vRowComm, nDimen, pKey);
62 p->InitObject();
63 return p;
64 }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< NekLinSysIterCG > NekLinSysIterCGSharedPtr

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

◆ DoConjugateGradient()

void Nektar::LibUtilities::NekLinSysIterCG::DoConjugateGradient ( const int  nGlobal,
const Array< OneD, const NekDouble > &  pInput,
Array< OneD, NekDouble > &  pOutput,
const int  nDir 
)
private

Actual iterative solve.

  Solve a global linear system using the conjugate gradient method.   We solve only for the non-Dirichlet modes. The operator is evaluated   using an auxiliary function m_operator.DoNekSysLhsEval defined by the   specific solver. Distributed math routines are used to support   parallel execution of the solver.     The implemented algorithm uses a reduced-communication reordering of   the standard PCG method (Demmel, Heath and Vorst, 1993)    

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

Definition at line 94 of file NekLinSysIterCG.cpp.

97{
98 // Get vector sizes
99 int nNonDir = nGlobal - nDir;
100
101 // Allocate array storage
102 Array<OneD, NekDouble> w_A(nGlobal, 0.0);
103 Array<OneD, NekDouble> s_A(nGlobal, 0.0);
104 Array<OneD, NekDouble> p_A(nNonDir, 0.0);
105 Array<OneD, NekDouble> r_A(nNonDir, 0.0);
106 Array<OneD, NekDouble> q_A(nNonDir, 0.0);
107 Array<OneD, NekDouble> tmp;
108
109 NekDouble alpha;
111 NekDouble rho;
112 NekDouble rho_new;
113 NekDouble mu;
114 NekDouble eps;
115 Array<OneD, NekDouble> vExchange(3, 0.0);
116
117 // Copy initial residual from input
118 Vmath::Vcopy(nNonDir, pInput + nDir, 1, r_A, 1);
119
120 // Zero homogeneous out array ready for solution updates
121 // Should not be earlier in case input vector is same as
122 // output and above copy has been peformed
123 Vmath::Zero(nNonDir, tmp = pOutput + nDir, 1);
124
125 // Evaluate initial residual error for exit check
126 vExchange[2] = Vmath::Dot2(nNonDir, r_A, r_A, m_map + nDir);
127
128 m_rowComm->AllReduce(vExchange[2], Nektar::LibUtilities::ReduceSum);
129
130 eps = vExchange[2];
131
133 {
134 NekVector<NekDouble> inGlob(nGlobal, pInput, eWrapper);
135 Set_Rhs_Magnitude(inGlob);
136 }
137
139
140 // If input residual is less than tolerance skip solve.
142 {
143 if (m_verbose && m_root)
144 {
145 cout << "CG iterations made = " << m_totalIterations
146 << " using tolerance of " << m_tolerance
147 << " (error = " << sqrt(eps / m_rhs_magnitude)
148 << ", rhs_mag = " << sqrt(m_rhs_magnitude) << ")" << endl;
149 }
150 return;
151 }
152
153 m_operator.DoNekSysPrecon(r_A, tmp = w_A + nDir);
154 m_operator.DoNekSysLhsEval(w_A, s_A);
155
156 vExchange[0] = Vmath::Dot2(nNonDir, r_A, w_A + nDir, m_map + nDir);
157 vExchange[1] = Vmath::Dot2(nNonDir, s_A + nDir, w_A + nDir, m_map + nDir);
158
159 m_rowComm->AllReduce(vExchange, Nektar::LibUtilities::ReduceSum);
160
161 rho = vExchange[0];
162 mu = vExchange[1];
163 beta = 0.0;
164 alpha = rho / mu;
166
167 // Continue until convergence
168 while (true)
169 {
171 {
172 if (m_root)
173 {
174 cout << "CG iterations made = " << m_totalIterations
175 << " using tolerance of " << m_tolerance
176 << " (error = " << sqrt(eps / m_rhs_magnitude)
177 << ", rhs_mag = " << sqrt(m_rhs_magnitude) << ")" << endl;
178 }
180 "Exceeded maximum number of iterations");
181 }
182
183 // Compute new search direction p_k, q_k
184 Vmath::Svtvp(nNonDir, beta, &p_A[0], 1, &w_A[nDir], 1, &p_A[0], 1);
185 Vmath::Svtvp(nNonDir, beta, &q_A[0], 1, &s_A[nDir], 1, &q_A[0], 1);
186
187 // Update solution x_{k+1}
188 Vmath::Svtvp(nNonDir, alpha, &p_A[0], 1, &pOutput[nDir], 1,
189 &pOutput[nDir], 1);
190
191 // Update residual vector r_{k+1}
192 Vmath::Svtvp(nNonDir, -alpha, &q_A[0], 1, &r_A[0], 1, &r_A[0], 1);
193
194 // Apply preconditioner
195 m_operator.DoNekSysPrecon(r_A, tmp = w_A + nDir);
196
197 // Perform the method-specific matrix-vector multiply operation.
198 m_operator.DoNekSysLhsEval(w_A, s_A);
199
200 // <r_{k+1}, w_{k+1}>
201 vExchange[0] = Vmath::Dot2(nNonDir, r_A, w_A + nDir, m_map + nDir);
202
203 // <s_{k+1}, w_{k+1}>
204 vExchange[1] =
205 Vmath::Dot2(nNonDir, s_A + nDir, w_A + nDir, m_map + nDir);
206
207 // <r_{k+1}, r_{k+1}>
208 vExchange[2] = Vmath::Dot2(nNonDir, r_A, r_A, m_map + nDir);
209
210 // Perform inner-product exchanges
211 m_rowComm->AllReduce(vExchange, Nektar::LibUtilities::ReduceSum);
212
213 rho_new = vExchange[0];
214 mu = vExchange[1];
215 eps = vExchange[2];
216
218
219 // Test if norm is within tolerance
221 {
222 if (m_verbose && m_root)
223 {
224 cout << "CG iterations made = " << m_totalIterations
225 << " using tolerance of " << m_tolerance
226 << " (error = " << sqrt(eps / m_rhs_magnitude)
227 << ", rhs_mag = " << sqrt(m_rhs_magnitude) << ")" << endl;
228 }
229 break;
230 }
231
232 // Compute search direction and solution coefficients
233 beta = rho_new / rho;
234 alpha = rho_new / (mu - rho_new * beta / alpha);
235 rho = rho_new;
236 }
237}
#define ROOTONLY_NEKERROR(type, msg)
Definition: ErrorUtil.hpp:205
NekDouble m_rhs_magnitude
Dot product of rhs to normalise stopping criterion.
void Set_Rhs_Magnitude(const NekVector< NekDouble > &pIn)
Array< OneD, int > m_map
Global to universal unique map.
bool m_root
Root if parallel.
Definition: NekSys.h:297
LibUtilities::CommSharedPtr m_rowComm
Communicate.
Definition: NekSys.h:293
bool m_verbose
Verbose.
Definition: NekSys.h:299
NekDouble m_tolerance
Tolerance of iterative solver.
Definition: NekSys.h:291
NekSysOperators m_operator
Operators.
Definition: NekSys.h:302
int m_maxiter
Maximum iterations.
Definition: NekSys.h:289
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
static const NekDouble kNekUnsetDouble
double NekDouble
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 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
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294

References Nektar::LibUtilities::beta, Nektar::LibUtilities::NekSysOperators::DoNekSysLhsEval(), Nektar::LibUtilities::NekSysOperators::DoNekSysPrecon(), Vmath::Dot2(), Nektar::ErrorUtil::efatal, Nektar::eWrapper, Nektar::NekConstants::kNekUnsetDouble, Nektar::LibUtilities::NekLinSysIter::m_map, Nektar::LibUtilities::NekSys::m_maxiter, Nektar::LibUtilities::NekSys::m_operator, 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, ROOTONLY_NEKERROR, Nektar::LibUtilities::NekLinSysIter::Set_Rhs_Magnitude(), tinysimd::sqrt(), Vmath::Svtvp(), Vmath::Vcopy(), and Vmath::Zero().

Referenced by v_SolveSystem().

◆ v_InitObject()

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

◆ v_SolveSystem()

int Nektar::LibUtilities::NekLinSysIterCG::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 68 of file NekLinSysIterCG.cpp.

73{
74 m_tolerance = max(tol, 1.0E-16);
75
76 DoConjugateGradient(nGlobal, pInput, pOutput, nDir);
77
78 return m_totalIterations;
79}
void DoConjugateGradient(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int pNumDir)
Actual iterative solve.

References DoConjugateGradient(), Nektar::LibUtilities::NekSys::m_tolerance, and Nektar::LibUtilities::NekLinSysIter::m_totalIterations.

Friends And Related Function Documentation

◆ MemoryManager< NekLinSysIterCG >

friend class MemoryManager< NekLinSysIterCG >
friend

Support creation through MemoryManager.

Definition at line 46 of file NekLinSysIterCG.h.

Member Data Documentation

◆ className

string Nektar::LibUtilities::NekLinSysIterCG::className
static
Initial value:
=
"ConjugateGradient", NekLinSysIterCG::create,
"NekLinSysIterCG 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 65 of file NekLinSysIterCG.h.