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)
 
void DropBlock (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
 
virtual void v_SolveLinearSystem (const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const AssemblyMapSharedPtr &locToGloMap, const int pNumDir) override
 Solve the matrix system. More...
 
virtual void v_DoMatrixMultiply (const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)=0
 
- Protected Member Functions inherited from Nektar::MultiRegions::GlobalLinSys
virtual void v_Solve (const Array< OneD, const NekDouble > &in, Array< OneD, NekDouble > &out, const AssemblyMapSharedPtr &locToGloMap, const Array< OneD, const NekDouble > &dirForcing=NullNekDouble1DArray)=0
 Solve a linear system based on mapping. More...
 
virtual void v_InitObject ()
 
virtual void v_Initialise (const std::shared_ptr< AssemblyMap > &pLocToGloMap)
 
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 void v_DropBlock (unsigned int n)
 Releases the local block matrix from NekManager of 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)
 

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 62 of file GlobalLinSysIterative.cpp.

65  : GlobalLinSys(pKey, pExpList, pLocToGloMap),
69 {
70  m_tolerance = pLocToGloMap->GetIterativeTolerance();
71  m_maxiter = pLocToGloMap->GetMaxIterations();
72  m_linSysIterSolver = pLocToGloMap->GetLinSysIterSolver();
73 
75  m_expList.lock()->GetComm()->GetRowComm();
76  m_root = (vComm->GetRank()) ? false : true;
77 
78  m_numSuccessiveRHS = pLocToGloMap->GetSuccessiveRHS();
82 
83  if (m_isAconjugate && 0 == m_linSysIterSolver.compare("GMRES"))
84  {
85  WARNINGL0(false, "To use A-conjugate projection, the matrix should be "
86  "symmetric positive definite.");
87  }
88 }
#define WARNINGL0(condition, msg)
Definition: ErrorUtil.hpp:222
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:124
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:298

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 90 of file GlobalLinSysIterative.cpp.

91 {
92 }

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 136 of file GlobalLinSysIterative.h.

139  {
140  boost::ignore_unused(controlFlag);
141 
142  v_DoMatrixMultiply(pInput, pOutput);
143  }
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 145 of file GlobalLinSysIterative.h.

148  {
149  boost::ignore_unused(controlFlag);
150 
151  m_precon->DoPreconditioner(pInput, pOutput);
152  }

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 151 of file GlobalLinSysIterative.cpp.

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

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 268 of file GlobalLinSysIterative.cpp.

269 {
270  if (m_numPrevSols == 0)
271  {
272  return -1;
273  }
274  int latest = (m_numPrevSols - 1 + m_numSuccessiveRHS) % m_numSuccessiveRHS;
275  Array<OneD, NekDouble> b = m_prevBasis[latest];
276  Array<OneD, NekDouble> x = m_prevLinSol[latest];
277  m_prevBasis.clear();
278  m_prevLinSol.clear();
279  m_prevBasis.push_back(b);
280  m_prevLinSol.push_back(x);
281  m_numPrevSols = 1;
282  return latest;
283 }

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 482 of file GlobalLinSysIterative.cpp.

483 {
484  Array<OneD, NekDouble> vExchange(1, 0.0);
485  if (m_map.size() > 0)
486  {
487  vExchange[0] =
488  Vmath::Dot2(pIn.GetDimension(), &pIn[0], &pIn[0], &m_map[0]);
489  }
490 
491  m_expList.lock()->GetComm()->GetRowComm()->AllReduce(
493 
494  // To ensure that very different rhs values are not being
495  // used in subsequent solvers such as the velocit solve in
496  // INC NS. If this works we then need to work out a better
497  // way to control this.
498  NekDouble new_rhs_mag = (vExchange[0] > 1e-6) ? vExchange[0] : 1.0;
499 
501  {
502  m_rhs_magnitude = new_rhs_mag;
503  }
504  else
505  {
507  (1.0 - m_rhs_mag_sm) * new_rhs_mag);
508  }
509 }
unsigned int GetDimension() const
Returns the number of dimensions for the point.
Definition: NekVector.cpp:201

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 289 of file GlobalLinSysIterative.cpp.

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

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

Solve the matrix system.

Implements Nektar::MultiRegions::GlobalLinSys.

Definition at line 97 of file GlobalLinSysIterative.cpp.

101 {
102  if (!m_linsol)
103  {
105  m_expList.lock()->GetComm()->GetRowComm();
107  m_expList.lock()->GetSession();
108 
109  // Check such a module exists for this equation.
112  "NekLinSysIter '" + m_linSysIterSolver +
113  "' is not defined.\n");
115  m_linSysIterSolver, pSession, v_Comm, nGlobal - nDir,
116  LibUtilities::NekSysKey());
117 
122  m_linsol->SetSysOperators(m_NekSysOp);
123  v_UniqueMap();
124  m_linsol->setUniversalUniqueMap(m_map);
125  }
126 
127  if (!m_precon)
128  {
129  m_precon = CreatePrecon(plocToGloMap);
130  m_precon->BuildPreconditioner();
131  }
132 
133  m_linsol->setRhsMagnitude(m_rhs_magnitude);
134  if (m_useProjection)
135  {
136  DoProjection(nGlobal, pInput, pOutput, nDir, m_tolerance,
138  }
139  else
140  {
141  m_linsol->SolveSystem(nGlobal, pInput, pOutput, nDir, m_tolerance);
142  }
143 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
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::LibUtilities::NekFactory< tKey, tBase, tParam >::CreateInstance(), 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:
=
"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 106 of file GlobalLinSysIterative.h.

◆ IteratSolverlookupIds

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

Definition at line 105 of file GlobalLinSysIterative.h.

◆ m_coeffMatrix

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

Definition at line 94 of file GlobalLinSysIterative.h.

Referenced by UpdateKnownSolutions().

◆ m_coeffMatrixFactor

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

Definition at line 95 of file GlobalLinSysIterative.h.

Referenced by DoProjection(), and UpdateKnownSolutions().

◆ m_ipivot

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

Definition at line 96 of file GlobalLinSysIterative.h.

Referenced by DoProjection(), and UpdateKnownSolutions().

◆ m_isAconjugate

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

Definition at line 98 of file GlobalLinSysIterative.h.

Referenced by GlobalLinSysIterative(), and v_SolveLinearSystem().

◆ m_linsol

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

Definition at line 103 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 89 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 65 of file GlobalLinSysIterative.h.

Referenced by GlobalLinSysIterative().

◆ m_NekSysOp

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

Definition at line 101 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 78 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 92 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 74 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 71 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 86 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 68 of file GlobalLinSysIterative.h.

Referenced by GlobalLinSysIterative(), and v_SolveLinearSystem().

◆ m_totalIterations

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

Definition at line 80 of file GlobalLinSysIterative.h.

◆ m_useProjection

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

Whether to apply projection technique.

Definition at line 83 of file GlobalLinSysIterative.h.

Referenced by GlobalLinSysIterative(), and v_SolveLinearSystem().