Nektar++
Public Member Functions | Protected Member Functions | Protected Attributes | Static Protected Attributes | Private Member Functions | List of all members
Nektar::MultiRegions::GlobalLinSysIterative Class Referenceabstract

A global linear system. More...

#include <GlobalLinSysIterative.h>

Inheritance diagram for Nektar::MultiRegions::GlobalLinSysIterative:
[legend]

Public Member Functions

 GlobalLinSysIterative (const GlobalLinSysKey &pKey, const std::weak_ptr< ExpList > &pExpList, const std::shared_ptr< AssemblyMap > &pLocToGloMap)
 Constructor for full direct matrix solve. More...
 
virtual ~GlobalLinSysIterative ()
 
- Public Member Functions inherited from Nektar::MultiRegions::GlobalLinSys
 GlobalLinSys (const GlobalLinSysKey &pKey, const std::weak_ptr< ExpList > &pExpList, const std::shared_ptr< AssemblyMap > &pLocToGloMap)
 Constructor for full direct matrix solve. More...
 
virtual ~GlobalLinSys ()
 
const GlobalLinSysKeyGetKey (void) const
 Returns the key associated with the system. More...
 
const std::weak_ptr< ExpList > & GetLocMat (void) const
 
void InitObject ()
 
void Initialise (const std::shared_ptr< AssemblyMap > &pLocToGloMap)
 
void Solve (const Array< OneD, const NekDouble > &in, Array< OneD, NekDouble > &out, const AssemblyMapSharedPtr &locToGloMap, const Array< OneD, const NekDouble > &dirForcing=NullNekDouble1DArray)
 Solve the linear system for given input and output vectors using a specified local to global map. More...
 
std::shared_ptr< GlobalLinSysGetSharedThisPtr ()
 Returns a shared pointer to the current object. More...
 
int GetNumBlocks ()
 
DNekScalMatSharedPtr GetBlock (unsigned int n)
 
DNekScalBlkMatSharedPtr GetStaticCondBlock (unsigned int n)
 
void DropStaticCondBlock (unsigned int n)
 
void SolveLinearSystem (const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const AssemblyMapSharedPtr &locToGloMap, const int pNumDir=0)
 Solve the linear system for given input and output vectors. More...
 

Protected Member Functions

void DoProjection (const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int pNumDir, const NekDouble tol, const bool isAconjugate)
 projection technique More...
 
void Set_Rhs_Magnitude (const NekVector< NekDouble > &pIn)
 
virtual void v_UniqueMap ()=0
 
- Protected Member Functions inherited from Nektar::MultiRegions::GlobalLinSys
virtual int v_GetNumBlocks ()
 Get the number of blocks in this system. More...
 
virtual DNekScalMatSharedPtr v_GetBlock (unsigned int n)
 Retrieves the block matrix from n-th expansion using the matrix key provided by the m_linSysKey. More...
 
virtual DNekScalBlkMatSharedPtr v_GetStaticCondBlock (unsigned int n)
 Retrieves a the static condensation block matrices from n-th expansion using the matrix key provided by the m_linSysKey. More...
 
virtual void v_DropStaticCondBlock (unsigned int n)
 Releases the static condensation block matrices from NekManager of n-th expansion using the matrix key provided by the m_linSysKey. More...
 
PreconditionerSharedPtr CreatePrecon (AssemblyMapSharedPtr asmMap)
 Create a preconditioner object from the parameters defined in the supplied assembly map. More...
 

Protected Attributes

Array< OneD, int > m_map
 Global to universal unique map. More...
 
int m_maxiter
 maximum iterations More...
 
NekDouble m_tolerance
 Tolerance of iterative solver. More...
 
NekDouble m_rhs_magnitude
 dot product of rhs to normalise stopping criterion More...
 
NekDouble m_rhs_mag_sm
 cnt to how many times rhs_magnitude is called More...
 
PreconditionerSharedPtr m_precon
 
MultiRegions::PreconditionerType m_precontype
 
int m_totalIterations
 
bool m_useProjection
 Whether to apply projection technique. More...
 
bool m_root
 Root if parallel. More...
 
std::string m_linSysIterSolver
 Iterative solver: Conjugate Gradient, GMRES. More...
 
std::vector< Array< OneD, NekDouble > > m_prevLinSol
 Storage for solutions to previous linear problems. More...
 
std::vector< Array< OneD, NekDouble > > m_prevBasis
 
DNekMatSharedPtr m_coeffMatrix
 
Array< OneD, NekDoublem_coeffMatrixFactor
 
Array< OneD, int > m_ipivot
 
int m_numSuccessiveRHS
 
bool m_isAconjugate
 
int m_numPrevSols
 
LibUtilities::NekSysOperators m_NekSysOp
 
LibUtilities::NekLinSysIterSharedPtr m_linsol
 
- Protected Attributes inherited from Nektar::MultiRegions::GlobalLinSys
const GlobalLinSysKey m_linSysKey
 Key associated with this linear system. More...
 
const std::weak_ptr< ExpListm_expList
 Local Matrix System. More...
 
const std::map< int, RobinBCInfoSharedPtrm_robinBCInfo
 Robin boundary info. More...
 
bool m_verbose
 

Static Protected Attributes

static std::string IteratSolverlookupIds []
 
static std::string IteratSolverdef
 

Private Member Functions

void UpdateKnownSolutions (const int pGlobalBndDofs, const Array< OneD, const NekDouble > &pSolution, const int pNumDirBndDofs, const bool isAconjugate)
 
int ResetKnownSolutionsToLatestOne ()
 
void DoMatrixMultiplyFlag (const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const bool &controlFlag)
 
void DoPreconditionerFlag (const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const bool &controlFlag)
 
virtual void v_SolveLinearSystem (const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const AssemblyMapSharedPtr &locToGloMap, const int pNumDir)
 Solve the matrix system. More...
 
virtual void v_DoMatrixMultiply (const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)=0
 

Detailed Description

A global linear system.

Solves a linear system using iterative methods.

Definition at line 50 of file GlobalLinSysIterative.h.

Constructor & Destructor Documentation

◆ GlobalLinSysIterative()

Nektar::MultiRegions::GlobalLinSysIterative::GlobalLinSysIterative ( const GlobalLinSysKey pKey,
const std::weak_ptr< ExpList > &  pExpList,
const std::shared_ptr< AssemblyMap > &  pLocToGloMap 
)

Constructor for full direct matrix solve.

Definition at line 63 of file GlobalLinSysIterative.cpp.

68  : GlobalLinSys(pKey, pExpList, pLocToGloMap),
70  m_rhs_mag_sm(0.9),
73  m_useProjection(false),
74  m_numPrevSols(0)
75  {
76  m_tolerance = pLocToGloMap->GetIterativeTolerance();
77  m_maxiter = pLocToGloMap->GetMaxIterations();
78  m_linSysIterSolver = pLocToGloMap->GetLinSysIterSolver();
79 
80  LibUtilities::CommSharedPtr vComm = m_expList.lock()->GetComm()->GetRowComm();
81  m_root = (vComm->GetRank())? false : true;
82 
83  m_numSuccessiveRHS = pLocToGloMap->GetSuccessiveRHS();
87 
88  if(m_isAconjugate && 0 == m_linSysIterSolver.compare("GMRES"))
89  {
90  WARNINGL0(false, "To use A-conjugate projection, the matrix should be symmetric positive definite.");
91  }
92  }
#define WARNINGL0(condition, msg)
Definition: ErrorUtil.hpp:223
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:127
GlobalLinSys(const GlobalLinSysKey &pKey, const std::weak_ptr< ExpList > &pExpList, const std::shared_ptr< AssemblyMap > &pLocToGloMap)
Constructor for full direct matrix solve.
bool m_useProjection
Whether to apply projection technique.
NekDouble m_tolerance
Tolerance of iterative solver.
NekDouble m_rhs_magnitude
dot product of rhs to normalise stopping criterion
std::string m_linSysIterSolver
Iterative solver: Conjugate Gradient, GMRES.
NekDouble m_rhs_mag_sm
cnt to how many times rhs_magnitude is called
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:54
static PreconditionerSharedPtr NullPreconditionerSharedPtr
static const NekDouble kNekUnsetDouble
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:272

References tinysimd::abs(), Nektar::MultiRegions::GlobalLinSys::m_expList, m_isAconjugate, m_linSysIterSolver, m_maxiter, m_numSuccessiveRHS, m_root, m_tolerance, m_useProjection, and WARNINGL0.

◆ ~GlobalLinSysIterative()

Nektar::MultiRegions::GlobalLinSysIterative::~GlobalLinSysIterative ( )
virtual

Definition at line 94 of file GlobalLinSysIterative.cpp.

95  {
96  }

Member Function Documentation

◆ DoMatrixMultiplyFlag()

void Nektar::MultiRegions::GlobalLinSysIterative::DoMatrixMultiplyFlag ( const Array< OneD, NekDouble > &  pInput,
Array< OneD, NekDouble > &  pOutput,
const bool &  controlFlag 
)
inlineprivate

Definition at line 131 of file GlobalLinSysIterative.h.

135  {
136  boost::ignore_unused(controlFlag);
137 
138  v_DoMatrixMultiply(pInput,pOutput);
139  }
virtual void v_DoMatrixMultiply(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)=0

References v_DoMatrixMultiply().

Referenced by DoProjection(), UpdateKnownSolutions(), and v_SolveLinearSystem().

◆ DoPreconditionerFlag()

void Nektar::MultiRegions::GlobalLinSysIterative::DoPreconditionerFlag ( const Array< OneD, NekDouble > &  pInput,
Array< OneD, NekDouble > &  pOutput,
const bool &  controlFlag 
)
inlineprivate

Definition at line 141 of file GlobalLinSysIterative.h.

145  {
146  boost::ignore_unused(controlFlag);
147 
148  m_precon->DoPreconditioner(pInput, pOutput);
149  }

References m_precon.

Referenced by v_SolveLinearSystem().

◆ DoProjection()

void Nektar::MultiRegions::GlobalLinSysIterative::DoProjection ( const int  nGlobal,
const Array< OneD, const NekDouble > &  pInput,
Array< OneD, NekDouble > &  pOutput,
const int  nDir,
const NekDouble  tol,
const bool  isAconjugate 
)
protected

projection technique

This method implements projection techniques in order to speed up successive linear solves with right-hand sides arising from time-dependent discretisations. (P.F.Fischer, Comput. Methods Appl. Mech. Engrg. 163, 1998)

Definition at line 156 of file GlobalLinSysIterative.cpp.

163  {
164  int numIterations = 0;
165  if (0 == m_numPrevSols)
166  {
167  // no previous solutions found
168  numIterations = m_linsol->SolveSystem(nGlobal, pInput, pOutput, nDir, tol);
169  }
170  else
171  {
172  // Get the communicator for performing data exchanges
174  = m_expList.lock()->GetComm()->GetRowComm();
175 
176  // Get vector sizes
177  int nNonDir = nGlobal - nDir;
178 
179  // check the input vector (rhs) is not zero
180  Array<OneD, NekDouble> tmp;
181 
182  NekDouble rhsNorm = Vmath::Dot2(nNonDir,
183  pInput + nDir,
184  pInput + nDir,
185  m_map + nDir);
186 
187  vComm->AllReduce(rhsNorm, Nektar::LibUtilities::ReduceSum);
188 
189  if (rhsNorm < tol * tol * m_rhs_magnitude)
190  {
191  Vmath::Zero(nNonDir, tmp = pOutput+nDir, 1);
192  if(m_verbose && m_root)
193  {
194  cout << "No iterations made"
195  << " using tolerance of " << tol
196  << " (error = " << sqrt(rhsNorm / m_rhs_magnitude)
197  << ", rhs_mag = " << sqrt(m_rhs_magnitude) << ")" << endl;
198  }
199  return;
200  }
201 
202  // Create NekVector wrappers for linear algebra operations
203  NekVector<NekDouble> b (nNonDir, pInput + nDir, eWrapper);
204  NekVector<NekDouble> x (nNonDir, tmp = pOutput + nDir, eWrapper);
205  // Allocate array storage
206  Array<OneD, NekDouble> px_s (nGlobal, 0.0);
207  Array<OneD, NekDouble> pb_s (nGlobal, 0.0);
208  Array<OneD, NekDouble> tmpAx_s (nGlobal, 0.0);
209  Array<OneD, NekDouble> tmpx_s (nGlobal, 0.0);
210 
211  NekVector<NekDouble> pb (nNonDir, tmp = pb_s + nDir, eWrapper);
212  NekVector<NekDouble> px (nNonDir, tmp = px_s + nDir, eWrapper);
213  NekVector<NekDouble> tmpAx (nNonDir, tmp = tmpAx_s + nDir, eWrapper);
214  NekVector<NekDouble> tmpx (nNonDir, tmp = tmpx_s + nDir, eWrapper);
215 
216  // notation follows the paper cited:
217  // \alpha_i = \tilda{x_i}^T b^n
218  // projected x, px = \sum \alpha_i \tilda{x_i}
219 
220  Array<OneD, NekDouble> alpha(m_prevBasis.size(), 0.0);
221  Array<OneD, NekDouble> alphaback(m_prevBasis.size(), 0.0);
222  for (int i = 0; i < m_prevBasis.size(); i++)
223  {
224  alpha[i] = Vmath::Dot2(nNonDir,
225  m_prevBasis[i],
226  pInput + nDir,
227  m_map + nDir);
228  }
229  vComm->AllReduce(alpha, Nektar::LibUtilities::ReduceSum);
230  int n = m_prevBasis.size(), info = -1;
231  Vmath::Vcopy(m_prevBasis.size(), alpha, 1, alphaback, 1);
232  Lapack::Dsptrs('U', n, 1, m_coeffMatrixFactor.get(), m_ipivot.get(), alpha.get(), n, info);
233  if(info!=0)
234  {
235  // Dsptrs fails, only keep the latest solution
236  int latest = ResetKnownSolutionsToLatestOne();
237  alpha[0] = alphaback[latest];
238  }
239  for (int i = 0; i < m_prevBasis.size(); ++i)
240  {
241  NekVector<NekDouble> xi (nNonDir, m_prevLinSol[i], eWrapper);
242  px += alpha[i] * xi;
243  }
244 
245  // pb = b^n - A px
246  Vmath::Vcopy(nNonDir,
247  pInput.get() + nDir, 1,
248  pb_s.get() + nDir, 1);
249 
250  DoMatrixMultiplyFlag(px_s, tmpAx_s, false);
251 
252  pb -= tmpAx;
253 
254  if (m_verbose)
255  {
256  if(m_root)
257  cout << "SuccessiveRHS: " << m_prevBasis.size() << "-bases projection reduces L2-norm of RHS from " << std::sqrt(rhsNorm) << " to ";
258  NekDouble tmprhsNorm = Vmath::Dot2(nNonDir,
259  pb_s + nDir,
260  pb_s + nDir,
261  m_map + nDir);
262  vComm->AllReduce(tmprhsNorm, Nektar::LibUtilities::ReduceSum);
263  if(m_root)
264  cout << std::sqrt(tmprhsNorm) << endl;
265  }
266 
267  // solve the system with projected rhs
268  numIterations = m_linsol->SolveSystem(nGlobal, pb_s, tmpx_s, nDir, tol);
269 
270  // remainder solution + projection of previous solutions
271  x = tmpx + px;
272  }
273  // save the auxiliary solution to prev. known solutions
274  if(numIterations)
275  {
276  UpdateKnownSolutions(nGlobal, pOutput, nDir, isAconjugate);
277  }
278  }
std::vector< Array< OneD, NekDouble > > m_prevBasis
LibUtilities::NekLinSysIterSharedPtr m_linsol
void UpdateKnownSolutions(const int pGlobalBndDofs, const Array< OneD, const NekDouble > &pSolution, const int pNumDirBndDofs, const bool isAconjugate)
std::vector< Array< OneD, NekDouble > > m_prevLinSol
Storage for solutions to previous linear problems.
void DoMatrixMultiplyFlag(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const bool &controlFlag)
Array< OneD, int > m_map
Global to universal unique map.
static void Dsptrs(const char &uplo, const int &n, const int &nrhs, const double *ap, const int *ipiv, double *b, const int &ldb, int &info)
Solve a real symmetric matrix problem using Bunch-Kaufman pivoting.
Definition: Lapack.hpp:209
double NekDouble
T Dot2(int n, const T *w, const T *x, const int *y)
vvtvp (vector times vector times vector): z = w*x*y
Definition: Vmath.cpp:1084
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:436
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1199
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:267

References DoMatrixMultiplyFlag(), Vmath::Dot2(), Lapack::Dsptrs(), Nektar::eWrapper, m_coeffMatrixFactor, Nektar::MultiRegions::GlobalLinSys::m_expList, m_ipivot, m_linsol, m_map, m_numPrevSols, m_prevBasis, m_prevLinSol, m_rhs_magnitude, m_root, Nektar::MultiRegions::GlobalLinSys::m_verbose, Nektar::LibUtilities::ReduceSum, ResetKnownSolutionsToLatestOne(), tinysimd::sqrt(), UpdateKnownSolutions(), Vmath::Vcopy(), and Vmath::Zero().

Referenced by v_SolveLinearSystem().

◆ ResetKnownSolutionsToLatestOne()

int Nektar::MultiRegions::GlobalLinSysIterative::ResetKnownSolutionsToLatestOne ( )
private

Definition at line 280 of file GlobalLinSysIterative.cpp.

281  {
282  if(m_numPrevSols==0)
283  {
284  return -1;
285  }
287  Array<OneD, NekDouble> b = m_prevBasis[latest];
288  Array<OneD, NekDouble> x = m_prevLinSol[latest];
289  m_prevBasis.clear();
290  m_prevLinSol.clear();
291  m_prevBasis.push_back(b);
292  m_prevLinSol.push_back(x);
293  m_numPrevSols = 1;
294  return latest;
295  }

References m_numPrevSols, m_numSuccessiveRHS, m_prevBasis, and m_prevLinSol.

Referenced by DoProjection(), and UpdateKnownSolutions().

◆ Set_Rhs_Magnitude()

void Nektar::MultiRegions::GlobalLinSysIterative::Set_Rhs_Magnitude ( const NekVector< NekDouble > &  pIn)
protected

Definition at line 484 of file GlobalLinSysIterative.cpp.

486  {
487  Array<OneD, NekDouble> vExchange(1, 0.0);
488  if (m_map.size() > 0)
489  {
490  vExchange[0] = Vmath::Dot2(pIn.GetDimension(),
491  &pIn[0],&pIn[0],&m_map[0]);
492  }
493 
494  m_expList.lock()->GetComm()->GetRowComm()->AllReduce(
496 
497  // To ensure that very different rhs values are not being
498  // used in subsequent solvers such as the velocit solve in
499  // INC NS. If this works we then need to work out a better
500  // way to control this.
501  NekDouble new_rhs_mag = (vExchange[0] > 1e-6)? vExchange[0] : 1.0;
502 
504  {
505  m_rhs_magnitude = new_rhs_mag;
506  }
507  else
508  {
510  (1.0-m_rhs_mag_sm)*new_rhs_mag);
511  }
512  }

References Vmath::Dot2(), Nektar::NekVector< DataType >::GetDimension(), Nektar::NekConstants::kNekUnsetDouble, Nektar::MultiRegions::GlobalLinSys::m_expList, m_map, m_rhs_mag_sm, m_rhs_magnitude, and Nektar::LibUtilities::ReduceSum.

Referenced by Nektar::MultiRegions::GlobalLinSysIterativeStaticCond::v_PreSolve().

◆ UpdateKnownSolutions()

void Nektar::MultiRegions::GlobalLinSysIterative::UpdateKnownSolutions ( const int  nGlobal,
const Array< OneD, const NekDouble > &  newX,
const int  nDir,
const bool  isAconjugate 
)
private

Updates the storage of previously known solutions. Performs normalisation of input vector wrt A-norm.

Definition at line 301 of file GlobalLinSysIterative.cpp.

306  {
307  // Get vector sizes
308  int nNonDir = nGlobal - nDir;
309  int insertLocation = m_numPrevSols % m_numSuccessiveRHS;
310  int fullbuffer = (m_prevBasis.size() == m_numSuccessiveRHS);
311 
312  // Get the communicator for performing data exchanges
314  = m_expList.lock()->GetComm()->GetRowComm();
315 
316  Array<OneD, NekDouble> tmpAx_s (nGlobal, 0.0);
317  Array<OneD, NekDouble> y_s (m_prevBasis.size() - fullbuffer, 0.0);
318  Array<OneD, NekDouble> invMy_s (y_s.size(), 0.0);
319  Array<OneD, int> ipivot (m_numSuccessiveRHS);
320  Array<OneD, NekDouble> tmp, newBasis;
321 
322  DoMatrixMultiplyFlag(newX, tmpAx_s, false);
323 
324  if(isAconjugate)
325  {
326  newBasis = newX + nDir;
327  }
328  else
329  {
330  newBasis = tmpAx_s + nDir;
331  }
332 
333  // Check the solution is non-zero
334  NekDouble solNorm = Vmath::Dot2(nNonDir,
335  newBasis,
336  tmpAx_s + nDir,
337  m_map + nDir);
338  vComm->AllReduce(solNorm, Nektar::LibUtilities::ReduceSum);
339 
340  if (solNorm < 22.2 * NekConstants::kNekSparseNonZeroTol)
341  {
342  return;
343  }
344 
345  // normalisation of A x
346  Vmath::Smul(nNonDir, 1.0/sqrt(solNorm),
347  tmpAx_s + nDir, 1,
348  tmp = tmpAx_s + nDir, 1);
349 
350  for (int i = 0; i < m_prevBasis.size(); ++i)
351  {
352  if(i == insertLocation) continue;
353  int skip = i > insertLocation;
354  y_s[i-skip] = Vmath::Dot2(nNonDir,
355  m_prevBasis[i],
356  tmpAx_s + nDir,
357  m_map + nDir);
358  }
359  vComm->AllReduce(y_s, Nektar::LibUtilities::ReduceSum);
360 
361  //check if linearly dependent
362  DNekMatSharedPtr tilCoeffMatrix;
363  if(fullbuffer && m_numSuccessiveRHS>1)
364  {
365  tilCoeffMatrix = MemoryManager<DNekMat>::
367  for(int i=0; i<m_numSuccessiveRHS; ++i)
368  {
369  if(i == insertLocation) continue;
370  int iskip = i > insertLocation;
371  for(int j=i; j<m_numSuccessiveRHS; ++j)
372  {
373  if(j == insertLocation) continue;
374  int jskip = j > insertLocation;
375  tilCoeffMatrix->SetValue(i-iskip, j-jskip, m_coeffMatrix->GetValue(i, j));
376  }
377  }
378  }
379  else if(!fullbuffer && m_prevBasis.size())
380  {
382  Vmath::Vcopy(tilCoeffMatrix->GetStorageSize(), m_coeffMatrix->GetPtr(), 1, tilCoeffMatrix->GetPtr(), 1);
383  }
384 
385  int n, info1 = 0, info2 = 0, info3 = 0;
386  if(y_s.size())
387  {
388  n = tilCoeffMatrix->GetRows();
389  Array<OneD, NekDouble> tilCoeffMatrixFactor(tilCoeffMatrix->GetStorageSize());
390  Vmath::Vcopy(tilCoeffMatrix->GetStorageSize(), tilCoeffMatrix->GetPtr(), 1, tilCoeffMatrixFactor, 1);
391  Lapack::Dsptrf('U', n, tilCoeffMatrixFactor.get(), ipivot.get(), info1);
392  if(info1==0)
393  {
394  Vmath::Vcopy(n, y_s, 1, invMy_s, 1);
395  Lapack::Dsptrs('U', n, 1, tilCoeffMatrixFactor.get(), ipivot.get(), invMy_s.get(), n, info2);
396  }
397  }
398  if(info1 || info2)
399  {
400  int latest = ResetKnownSolutionsToLatestOne();
401  y_s[0] = y_s[latest - (latest > insertLocation)];
402  invMy_s[0] = y_s[0];
403  insertLocation = m_numPrevSols % m_numSuccessiveRHS;
404  fullbuffer = (m_prevBasis.size() == m_numSuccessiveRHS);
405  }
406  NekDouble residual = 1.;
407  NekDouble epsilon = 10. * NekConstants::kNekZeroTol;
408  for (int i = 0; i < m_prevBasis.size()-fullbuffer; i++)
409  {
410  residual -= y_s[i] * invMy_s[i];
411  }
412  if(m_verbose && m_root) cout << "SuccessiveRHS: residual " << residual;
413  if (residual < epsilon)
414  {
415  if(m_verbose && m_root) cout << " < " << epsilon << ", reject" << endl;
416  return;
417  }
418 
419  //calculate new coefficient matrix and its factor
420  DNekMatSharedPtr newCoeffMatrix;
421  if(fullbuffer)
422  {
424  Vmath::Vcopy(m_coeffMatrix->GetStorageSize(), m_coeffMatrix->GetPtr(), 1, newCoeffMatrix->GetPtr(), 1);
425  newCoeffMatrix->SetValue(insertLocation, insertLocation, 1.);
426  for(int i=0; i<m_numSuccessiveRHS; ++i)
427  {
428  if(i == insertLocation) continue;
429  int iskip = i > insertLocation;
430  newCoeffMatrix->SetValue(insertLocation, i, y_s[i-iskip]);
431  }
432  }
433  else
434  {
435  newCoeffMatrix = MemoryManager<DNekMat>::AllocateSharedPtr(m_prevBasis.size()+1,m_prevBasis.size()+1,0.0,eSYMMETRIC);
436  newCoeffMatrix->SetValue(insertLocation, insertLocation, 1.);
437  for(int i=0; i<m_prevBasis.size(); ++i)
438  {
439  newCoeffMatrix->SetValue(insertLocation, i, y_s[i]);
440  for(int j=i; j<m_prevBasis.size(); ++j)
441  {
442  newCoeffMatrix->SetValue(i, j, m_coeffMatrix->GetValue(i, j));
443  }
444  }
445  }
446  n = newCoeffMatrix->GetRows();
447  Array<OneD, NekDouble> coeffMatrixFactor(newCoeffMatrix->GetStorageSize());
448  Vmath::Vcopy(newCoeffMatrix->GetStorageSize(), newCoeffMatrix->GetPtr(), 1, coeffMatrixFactor, 1);
449  Lapack::Dsptrf('U', n, coeffMatrixFactor.get(), ipivot.get(), info3);
450  if(info3)
451  {
452  if(m_verbose && m_root) cout << " >= " << epsilon << ", reject (Dsptrf fails)" << endl;
453  return;
454  }
455  if(m_verbose && m_root) cout << " >= " << epsilon << ", accept" << endl;
456 
457  //if success, update basis, rhs, coefficient matrix, and its factor
458  if(m_prevBasis.size() < m_numSuccessiveRHS)
459  {
460  m_prevBasis.push_back(tmp = tmpAx_s + nDir);
461  if(isAconjugate)
462  {
463  m_prevLinSol.push_back(tmp);
464  }
465  else
466  {
467  Array<OneD, NekDouble> solution(nNonDir, 0.0);
468  m_prevLinSol.push_back(solution);
469  }
470  }
471  Vmath::Smul(nNonDir, 1./sqrt(solNorm),
472  tmp = newX + nDir, 1,
473  m_prevLinSol[insertLocation], 1);
474  if(!isAconjugate)
475  {
476  m_prevBasis[insertLocation] = tmpAx_s + nDir;
477  }
478  m_coeffMatrix = newCoeffMatrix;
479  m_coeffMatrixFactor = coeffMatrixFactor;
480  m_ipivot = ipivot;
481  ++m_numPrevSols;
482  }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static void Dsptrf(const char &uplo, const int &n, double *ap, int *ipiv, int &info)
factor a real packed-symmetric matrix using Bunch-Kaufman pivoting.
Definition: Lapack.hpp:182
static const NekDouble kNekSparseNonZeroTol
static const NekDouble kNekZeroTol
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:69
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.cpp:225

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), DoMatrixMultiplyFlag(), Vmath::Dot2(), Lapack::Dsptrf(), Lapack::Dsptrs(), Nektar::eSYMMETRIC, Nektar::NekConstants::kNekSparseNonZeroTol, Nektar::NekConstants::kNekZeroTol, m_coeffMatrix, m_coeffMatrixFactor, Nektar::MultiRegions::GlobalLinSys::m_expList, m_ipivot, m_map, m_numPrevSols, m_numSuccessiveRHS, m_prevBasis, m_prevLinSol, m_root, Nektar::MultiRegions::GlobalLinSys::m_verbose, Nektar::LibUtilities::ReduceSum, ResetKnownSolutionsToLatestOne(), Vmath::Smul(), tinysimd::sqrt(), and Vmath::Vcopy().

Referenced by DoProjection().

◆ v_DoMatrixMultiply()

virtual void Nektar::MultiRegions::GlobalLinSysIterative::v_DoMatrixMultiply ( const Array< OneD, NekDouble > &  pInput,
Array< OneD, NekDouble > &  pOutput 
)
privatepure virtual

◆ v_SolveLinearSystem()

void Nektar::MultiRegions::GlobalLinSysIterative::v_SolveLinearSystem ( const int  pNumRows,
const Array< OneD, const NekDouble > &  pInput,
Array< OneD, NekDouble > &  pOutput,
const AssemblyMapSharedPtr locToGloMap,
const int  pNumDir 
)
privatevirtual

Solve the matrix system.

Implements Nektar::MultiRegions::GlobalLinSys.

Definition at line 101 of file GlobalLinSysIterative.cpp.

107  {
108  if (!m_linsol)
109  {
111  m_expList.lock()->GetComm()->GetRowComm();
113  m_expList.lock()->GetSession();
114 
115  // Check such a module exists for this equation.
117  ModuleExists(m_linSysIterSolver),
118  "NekLinSysIter '" + m_linSysIterSolver +
119  "' is not defined.\n");
121  CreateInstance(m_linSysIterSolver, pSession,
122  v_Comm, nGlobal - nDir, LibUtilities::NekSysKey());
123 
128  m_linsol->SetSysOperators(m_NekSysOp);
129  v_UniqueMap();
130  m_linsol->setUniversalUniqueMap(m_map);
131  }
132 
133  if (!m_precon)
134  {
135  m_precon = CreatePrecon(plocToGloMap);
136  m_precon->BuildPreconditioner();
137  }
138 
139  m_linsol->setRhsMagnitude(m_rhs_magnitude);
140  if (m_useProjection)
141  {
142  DoProjection(nGlobal, pInput, pOutput, nDir, m_tolerance, m_isAconjugate);
143  }
144  else
145  {
146  m_linsol->SolveSystem(nGlobal, pInput, pOutput, nDir, m_tolerance);
147  }
148  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
void DefineNekSysLhsEval(FuncPointerT func, ObjectPointerT obj)
Definition: NekSys.h:107
void DefineNekSysPrecon(FuncPointerT func, ObjectPointerT obj)
Definition: NekSys.h:114
PreconditionerSharedPtr CreatePrecon(AssemblyMapSharedPtr asmMap)
Create a preconditioner object from the parameters defined in the supplied assembly map.
void DoProjection(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int pNumDir, const NekDouble tol, const bool isAconjugate)
projection technique
void DoPreconditionerFlag(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const bool &controlFlag)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
NekLinSysIterFactory & GetNekLinSysIterFactory()

References ASSERTL0, Nektar::MultiRegions::GlobalLinSys::CreatePrecon(), Nektar::LibUtilities::NekSysOperators::DefineNekSysLhsEval(), Nektar::LibUtilities::NekSysOperators::DefineNekSysPrecon(), DoMatrixMultiplyFlag(), DoPreconditionerFlag(), DoProjection(), Nektar::LibUtilities::GetNekLinSysIterFactory(), Nektar::MultiRegions::GlobalLinSys::m_expList, m_isAconjugate, m_linsol, m_linSysIterSolver, m_map, m_NekSysOp, m_precon, m_rhs_magnitude, m_tolerance, m_useProjection, and v_UniqueMap().

◆ v_UniqueMap()

virtual void Nektar::MultiRegions::GlobalLinSysIterative::v_UniqueMap ( )
protectedpure virtual

Member Data Documentation

◆ IteratSolverdef

std::string Nektar::MultiRegions::GlobalLinSysIterative::IteratSolverdef
staticprotected
Initial value:
=
"LinSysIterSolver", "ConjugateGradient")
static std::string RegisterDefaultSolverInfo(const std::string &pName, const std::string &pValue)
Registers the default string value of a solver info property.

Definition at line 107 of file GlobalLinSysIterative.h.

◆ IteratSolverlookupIds

std::string Nektar::MultiRegions::GlobalLinSysIterative::IteratSolverlookupIds
staticprotected
Initial value:
=
{
"LinSysIterSolver", "ConjugateGradient", MultiRegions::
"LinSysIterSolver", "GMRES", MultiRegions::eGMRES),
}
static std::string RegisterEnumValue(std::string pEnum, std::string pString, int pEnumValue)
Registers an enumeration value.

Definition at line 106 of file GlobalLinSysIterative.h.

◆ m_coeffMatrix

DNekMatSharedPtr Nektar::MultiRegions::GlobalLinSysIterative::m_coeffMatrix
protected

Definition at line 95 of file GlobalLinSysIterative.h.

Referenced by UpdateKnownSolutions().

◆ m_coeffMatrixFactor

Array<OneD, NekDouble> Nektar::MultiRegions::GlobalLinSysIterative::m_coeffMatrixFactor
protected

Definition at line 96 of file GlobalLinSysIterative.h.

Referenced by DoProjection(), and UpdateKnownSolutions().

◆ m_ipivot

Array<OneD, int> Nektar::MultiRegions::GlobalLinSysIterative::m_ipivot
protected

Definition at line 97 of file GlobalLinSysIterative.h.

Referenced by DoProjection(), and UpdateKnownSolutions().

◆ m_isAconjugate

bool Nektar::MultiRegions::GlobalLinSysIterative::m_isAconjugate
protected

Definition at line 99 of file GlobalLinSysIterative.h.

Referenced by GlobalLinSysIterative(), and v_SolveLinearSystem().

◆ m_linsol

LibUtilities::NekLinSysIterSharedPtr Nektar::MultiRegions::GlobalLinSysIterative::m_linsol
protected

Definition at line 104 of file GlobalLinSysIterative.h.

Referenced by DoProjection(), and v_SolveLinearSystem().

◆ m_linSysIterSolver

std::string Nektar::MultiRegions::GlobalLinSysIterative::m_linSysIterSolver
protected

Iterative solver: Conjugate Gradient, GMRES.

Definition at line 90 of file GlobalLinSysIterative.h.

Referenced by GlobalLinSysIterative(), and v_SolveLinearSystem().

◆ m_map

Array<OneD, int> Nektar::MultiRegions::GlobalLinSysIterative::m_map
protected

◆ m_maxiter

int Nektar::MultiRegions::GlobalLinSysIterative::m_maxiter
protected

maximum iterations

Definition at line 66 of file GlobalLinSysIterative.h.

Referenced by GlobalLinSysIterative().

◆ m_NekSysOp

LibUtilities::NekSysOperators Nektar::MultiRegions::GlobalLinSysIterative::m_NekSysOp
protected

Definition at line 102 of file GlobalLinSysIterative.h.

Referenced by v_SolveLinearSystem().

◆ m_numPrevSols

int Nektar::MultiRegions::GlobalLinSysIterative::m_numPrevSols
protected

◆ m_numSuccessiveRHS

int Nektar::MultiRegions::GlobalLinSysIterative::m_numSuccessiveRHS
protected

◆ m_precon

PreconditionerSharedPtr Nektar::MultiRegions::GlobalLinSysIterative::m_precon
protected

◆ m_precontype

MultiRegions::PreconditionerType Nektar::MultiRegions::GlobalLinSysIterative::m_precontype
protected

Definition at line 79 of file GlobalLinSysIterative.h.

◆ m_prevBasis

std::vector<Array<OneD, NekDouble> > Nektar::MultiRegions::GlobalLinSysIterative::m_prevBasis
protected

◆ m_prevLinSol

std::vector<Array<OneD, NekDouble> > Nektar::MultiRegions::GlobalLinSysIterative::m_prevLinSol
protected

Storage for solutions to previous linear problems.

Definition at line 93 of file GlobalLinSysIterative.h.

Referenced by DoProjection(), ResetKnownSolutionsToLatestOne(), and UpdateKnownSolutions().

◆ m_rhs_mag_sm

NekDouble Nektar::MultiRegions::GlobalLinSysIterative::m_rhs_mag_sm
protected

cnt to how many times rhs_magnitude is called

Definition at line 75 of file GlobalLinSysIterative.h.

Referenced by Set_Rhs_Magnitude(), and Nektar::MultiRegions::GlobalLinSysIterativeStaticCond::v_PreSolve().

◆ m_rhs_magnitude

NekDouble Nektar::MultiRegions::GlobalLinSysIterative::m_rhs_magnitude
protected

dot product of rhs to normalise stopping criterion

Definition at line 72 of file GlobalLinSysIterative.h.

Referenced by DoProjection(), Set_Rhs_Magnitude(), Nektar::MultiRegions::GlobalLinSysIterativeStaticCond::v_PreSolve(), and v_SolveLinearSystem().

◆ m_root

bool Nektar::MultiRegions::GlobalLinSysIterative::m_root
protected

Root if parallel.

Definition at line 87 of file GlobalLinSysIterative.h.

Referenced by DoProjection(), GlobalLinSysIterative(), and UpdateKnownSolutions().

◆ m_tolerance

NekDouble Nektar::MultiRegions::GlobalLinSysIterative::m_tolerance
protected

Tolerance of iterative solver.

Definition at line 69 of file GlobalLinSysIterative.h.

Referenced by GlobalLinSysIterative(), and v_SolveLinearSystem().

◆ m_totalIterations

int Nektar::MultiRegions::GlobalLinSysIterative::m_totalIterations
protected

Definition at line 81 of file GlobalLinSysIterative.h.

◆ m_useProjection

bool Nektar::MultiRegions::GlobalLinSysIterative::m_useProjection
protected

Whether to apply projection technique.

Definition at line 84 of file GlobalLinSysIterative.h.

Referenced by GlobalLinSysIterative(), and v_SolveLinearSystem().