Nektar++
Public Member Functions | Protected Member Functions | 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 DoAconjugateProjection (const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const AssemblyMapSharedPtr &locToGloMap, const int pNumDir)
 A-conjugate projection technique. More...
 
void DoConjugateGradient (const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const AssemblyMapSharedPtr &locToGloMap, const int pNumDir)
 Actual iterative solve. 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...
 
boost::circular_buffer< Array< OneD, NekDouble > > m_prevLinSol
 Storage for solutions to previous linear problems. More...
 
int m_numPrevSols
 Total counter of previous solutions. More...
 
- 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
 

Private Member Functions

void UpdateKnownSolutions (const int pGlobalBndDofs, const Array< OneD, const NekDouble > &pSolution, const int pNumDirBndDofs)
 
NekDouble CalculateAnorm (const int nGlobal, const Array< OneD, const NekDouble > &in, const int nDir)
 
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 51 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 50 of file GlobalLinSysIterative.cpp.

References Nektar::MultiRegions::GlobalLinSys::m_expList, m_maxiter, m_prevLinSol, m_root, m_tolerance, and m_useProjection.

55  : GlobalLinSys(pKey, pExpList, pLocToGloMap),
57  m_rhs_mag_sm(0.9),
60  m_useProjection(false),
61  m_numPrevSols(0)
62  {
63  m_tolerance = pLocToGloMap->GetIterativeTolerance();
64  m_maxiter = pLocToGloMap->GetMaxIterations();
65 
66  LibUtilities::CommSharedPtr vComm = m_expList.lock()->GetComm()->GetRowComm();
67  m_root = (vComm->GetRank())? false : true;
68 
69  int successiveRHS;
70 
71  if((successiveRHS = pLocToGloMap->GetSuccessiveRHS()))
72  {
73  m_prevLinSol.set_capacity(successiveRHS);
74  m_useProjection = true;
75  }
76  else
77  {
78  m_useProjection = false;
79  }
80  }
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:53
bool m_useProjection
Whether to apply projection technique.
boost::circular_buffer< Array< OneD, NekDouble > > m_prevLinSol
Storage for solutions to previous linear problems.
static PreconditionerSharedPtr NullPreconditionerSharedPtr
NekDouble m_tolerance
Tolerance of iterative solver.
int m_numPrevSols
Total counter of previous solutions.
static const NekDouble kNekUnsetDouble
NekDouble m_rhs_magnitude
dot product of rhs to normalise stopping criterion
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.

◆ ~GlobalLinSysIterative()

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

Definition at line 82 of file GlobalLinSysIterative.cpp.

83  {
84  }

Member Function Documentation

◆ CalculateAnorm()

NekDouble Nektar::MultiRegions::GlobalLinSysIterative::CalculateAnorm ( const int  nGlobal,
const Array< OneD, const NekDouble > &  in,
const int  nDir 
)
private

Calculating A-norm of an input vector, A-norm(x) := sqrt( < x, Ax > )

Definition at line 224 of file GlobalLinSysIterative.cpp.

References Vmath::Dot2(), Nektar::MultiRegions::GlobalLinSys::m_expList, m_map, Nektar::LibUtilities::ReduceSum, and v_DoMatrixMultiply().

Referenced by UpdateKnownSolutions().

228  {
229  // Get the communicator for performing data exchanges
231  = m_expList.lock()->GetComm()->GetRowComm();
232 
233  // Get vector sizes
234  int nNonDir = nGlobal - nDir;
235 
236  // Allocate array storage
237  Array<OneD, NekDouble> tmpAx_s (nGlobal, 0.0);
238 
239  v_DoMatrixMultiply(in, tmpAx_s);
240 
241  NekDouble anorm_sq = Vmath::Dot2(nNonDir,
242  in + nDir,
243  tmpAx_s + nDir,
244  m_map + nDir);
245  vComm->AllReduce(anorm_sq, Nektar::LibUtilities::ReduceSum);
246  return std::sqrt(anorm_sq);
247  }
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
virtual void v_DoMatrixMultiply(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)=0
Array< OneD, int > m_map
Global to universal unique map.
double NekDouble
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:127
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:957

◆ DoAconjugateProjection()

void Nektar::MultiRegions::GlobalLinSysIterative::DoAconjugateProjection ( const int  nGlobal,
const Array< OneD, const NekDouble > &  pInput,
Array< OneD, NekDouble > &  pOutput,
const AssemblyMapSharedPtr plocToGloMap,
const int  nDir 
)
protected

A-conjugate projection technique.

This method implements A-conjugate projection technique 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 115 of file GlobalLinSysIterative.cpp.

References DoConjugateGradient(), Vmath::Dot2(), Nektar::eWrapper, Nektar::NekConstants::kNekZeroTol, Nektar::MultiRegions::GlobalLinSys::m_expList, m_map, m_numPrevSols, m_prevLinSol, Nektar::LibUtilities::ReduceSum, UpdateKnownSolutions(), v_DoMatrixMultiply(), Vmath::Vcopy(), and Vmath::Zero().

Referenced by v_SolveLinearSystem().

121  {
122  // Get the communicator for performing data exchanges
124  = m_expList.lock()->GetComm()->GetRowComm();
125 
126  // Get vector sizes
127  int nNonDir = nGlobal - nDir;
128  Array<OneD, NekDouble> tmp;
129 
130  if (0 == m_numPrevSols)
131  {
132  // no previous solutions found, call CG
133 
134  DoConjugateGradient(nGlobal, pInput, pOutput, plocToGloMap, nDir);
135 
136  UpdateKnownSolutions(nGlobal, pOutput, nDir);
137  }
138  else
139  {
140  // Create NekVector wrappers for linear algebra operations
141  NekVector<NekDouble> b (nNonDir, pInput + nDir, eWrapper);
142  NekVector<NekDouble> x (nNonDir, tmp = pOutput + nDir, eWrapper);
143 
144  // check the input vector (rhs) is not zero
145 
146  NekDouble rhsNorm = Vmath::Dot2(nNonDir,
147  pInput + nDir,
148  pInput + nDir,
149  m_map + nDir);
150 
151  vComm->AllReduce(rhsNorm, Nektar::LibUtilities::ReduceSum);
152 
153  if (rhsNorm < NekConstants::kNekZeroTol)
154  {
155  Array<OneD, NekDouble> tmp = pOutput+nDir;
156  Vmath::Zero(nNonDir, tmp, 1);
157  return;
158  }
159 
160  // Allocate array storage
161  Array<OneD, NekDouble> px_s (nGlobal, 0.0);
162  Array<OneD, NekDouble> pb_s (nGlobal, 0.0);
163  Array<OneD, NekDouble> tmpAx_s (nGlobal, 0.0);
164  Array<OneD, NekDouble> tmpx_s (nGlobal, 0.0);
165 
166  NekVector<NekDouble> pb (nNonDir, tmp = pb_s + nDir, eWrapper);
167  NekVector<NekDouble> px (nNonDir, tmp = px_s + nDir, eWrapper);
168  NekVector<NekDouble> tmpAx (nNonDir, tmp = tmpAx_s + nDir, eWrapper);
169  NekVector<NekDouble> tmpx (nNonDir, tmp = tmpx_s + nDir, eWrapper);
170 
171 
172  // notation follows the paper cited:
173  // \alpha_i = \tilda{x_i}^T b^n
174  // projected x, px = \sum \alpha_i \tilda{x_i}
175 
176  Array<OneD, NekDouble> alpha (m_prevLinSol.size(), 0.0);
177  for (int i = 0; i < m_prevLinSol.size(); i++)
178  {
179  alpha[i] = Vmath::Dot2(nNonDir,
180  m_prevLinSol[i],
181  pInput + nDir,
182  m_map + nDir);
183  }
184  vComm->AllReduce(alpha, Nektar::LibUtilities::ReduceSum);
185 
186  for (int i = 0; i < m_prevLinSol.size(); i++)
187  {
188  if (alpha[i] < NekConstants::kNekZeroTol)
189  {
190  continue;
191  }
192 
193  NekVector<NekDouble> xi (nNonDir, m_prevLinSol[i], eWrapper);
194  px += alpha[i] * xi;
195  }
196 
197  // pb = b^n - A px
198  Vmath::Vcopy(nNonDir,
199  pInput.get() + nDir, 1,
200  pb_s.get() + nDir, 1);
201 
202  v_DoMatrixMultiply(px_s, tmpAx_s);
203 
204  pb -= tmpAx;
205 
206 
207  // solve the system with projected rhs
208  DoConjugateGradient(nGlobal, pb_s, tmpx_s, plocToGloMap, nDir);
209 
210 
211  // remainder solution + projection of previous solutions
212  x = tmpx + px;
213 
214  // save the auxiliary solution to prev. known solutions
215  UpdateKnownSolutions(nGlobal, tmpx_s, nDir);
216  }
217  }
void UpdateKnownSolutions(const int pGlobalBndDofs, const Array< OneD, const NekDouble > &pSolution, const int pNumDirBndDofs)
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
boost::circular_buffer< Array< OneD, NekDouble > > m_prevLinSol
Storage for solutions to previous linear problems.
virtual void v_DoMatrixMultiply(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)=0
static const NekDouble kNekZeroTol
int m_numPrevSols
Total counter of previous solutions.
Array< OneD, int > m_map
Global to universal unique map.
double NekDouble
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:127
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:957
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:376
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1064
void DoConjugateGradient(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const AssemblyMapSharedPtr &locToGloMap, const int pNumDir)
Actual iterative solve.

◆ DoConjugateGradient()

void Nektar::MultiRegions::GlobalLinSysIterative::DoConjugateGradient ( const int  nGlobal,
const Array< OneD, const NekDouble > &  pInput,
Array< OneD, NekDouble > &  pOutput,
const AssemblyMapSharedPtr plocToGloMap,
const int  nDir 
)
protected

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

References Nektar::MultiRegions::GlobalLinSys::CreatePrecon(), Vmath::Dot2(), Nektar::ErrorUtil::efatal, Nektar::eWrapper, Nektar::NekConstants::kNekUnsetDouble, Nektar::MultiRegions::GlobalLinSys::m_expList, m_map, m_maxiter, m_precon, m_rhs_magnitude, m_root, m_tolerance, m_totalIterations, Nektar::MultiRegions::GlobalLinSys::m_verbose, CellMLToNektar.cellml_metadata::p, Nektar::LibUtilities::ReduceSum, ROOTONLY_NEKERROR, Set_Rhs_Magnitude(), Vmath::Svtvp(), v_DoMatrixMultiply(), v_UniqueMap(), and Vmath::Zero().

Referenced by DoAconjugateProjection(), and v_SolveLinearSystem().

360  {
361  if (!m_precon)
362  {
363  v_UniqueMap();
364  m_precon = CreatePrecon(plocToGloMap);
365  m_precon->BuildPreconditioner();
366  }
367 
368  // Get the communicator for performing data exchanges
370  = m_expList.lock()->GetComm()->GetRowComm();
371 
372  // Get vector sizes
373  int nNonDir = nGlobal - nDir;
374 
375  // Allocate array storage
376  Array<OneD, NekDouble> w_A (nGlobal, 0.0);
377  Array<OneD, NekDouble> s_A (nGlobal, 0.0);
378  Array<OneD, NekDouble> p_A (nNonDir, 0.0);
379  Array<OneD, NekDouble> r_A (nNonDir, 0.0);
380  Array<OneD, NekDouble> q_A (nNonDir, 0.0);
381  Array<OneD, NekDouble> tmp;
382 
383  // Create NekVector wrappers for linear algebra operations
384  NekVector<NekDouble> in (nNonDir,pInput + nDir, eWrapper);
385  NekVector<NekDouble> out(nNonDir,tmp = pOutput + nDir,eWrapper);
386  NekVector<NekDouble> w (nNonDir,tmp = w_A + nDir, eWrapper);
387  NekVector<NekDouble> s (nNonDir,tmp = s_A + nDir, eWrapper);
388  NekVector<NekDouble> p (nNonDir,p_A, eWrapper);
389  NekVector<NekDouble> r (nNonDir,r_A, eWrapper);
390  NekVector<NekDouble> q (nNonDir,q_A, eWrapper);
391 
392  int k;
393  NekDouble alpha, beta, rho, rho_new, mu, eps, min_resid;
394  Array<OneD, NekDouble> vExchange(3,0.0);
395 
396  // Copy initial residual from input
397  r = in;
398  // zero homogeneous out array ready for solution updates
399  // Should not be earlier in case input vector is same as
400  // output and above copy has been peformed
401  Vmath::Zero(nNonDir,tmp = pOutput + nDir,1);
402 
403 
404  // evaluate initial residual error for exit check
405  vExchange[2] = Vmath::Dot2(nNonDir,
406  r_A,
407  r_A,
408  m_map + nDir);
409 
410  vComm->AllReduce(vExchange, Nektar::LibUtilities::ReduceSum);
411 
412  eps = vExchange[2];
413 
415  {
416  NekVector<NekDouble> inGlob (nGlobal, pInput, eWrapper);
417  Set_Rhs_Magnitude(inGlob);
418  }
419 
420  m_totalIterations = 0;
421 
422  // If input residual is less than tolerance skip solve.
424  {
425  if (m_verbose && m_root)
426  {
427  cout << "CG iterations made = " << m_totalIterations
428  << " using tolerance of " << m_tolerance
429  << " (error = " << sqrt(eps/m_rhs_magnitude)
430  << ", rhs_mag = " << sqrt(m_rhs_magnitude) << ")"
431  << endl;
432  }
433  return;
434  }
435 
436  m_precon->DoPreconditioner(r_A, tmp = w_A + nDir);
437 
438  v_DoMatrixMultiply(w_A, s_A);
439 
440  k = 0;
441 
442  vExchange[0] = Vmath::Dot2(nNonDir,
443  r_A,
444  w_A + nDir,
445  m_map + nDir);
446 
447  vExchange[1] = Vmath::Dot2(nNonDir,
448  s_A + nDir,
449  w_A + nDir,
450  m_map + nDir);
451 
452  vComm->AllReduce(vExchange, Nektar::LibUtilities::ReduceSum);
453 
454  rho = vExchange[0];
455  mu = vExchange[1];
456  min_resid = m_rhs_magnitude;
457  beta = 0.0;
458  alpha = rho/mu;
459  m_totalIterations = 1;
460 
461  // Continue until convergence
462  while (true)
463  {
464  if(k >= m_maxiter)
465  {
466  if (m_root)
467  {
468  cout << "CG iterations made = " << m_totalIterations
469  << " using tolerance of " << m_tolerance
470  << " (error = " << sqrt(eps/m_rhs_magnitude)
471  << ", rhs_mag = " << sqrt(m_rhs_magnitude) << ")"
472  << endl;
473  }
475  "Exceeded maximum number of iterations");
476  }
477 
478  // Compute new search direction p_k, q_k
479  Vmath::Svtvp(nNonDir, beta, &p_A[0], 1, &w_A[nDir], 1, &p_A[0], 1);
480  Vmath::Svtvp(nNonDir, beta, &q_A[0], 1, &s_A[nDir], 1, &q_A[0], 1);
481 
482  // Update solution x_{k+1}
483  Vmath::Svtvp(nNonDir, alpha, &p_A[0], 1, &pOutput[nDir], 1, &pOutput[nDir], 1);
484 
485  // Update residual vector r_{k+1}
486  Vmath::Svtvp(nNonDir, -alpha, &q_A[0], 1, &r_A[0], 1, &r_A[0], 1);
487 
488  // Apply preconditioner
489  m_precon->DoPreconditioner(r_A, tmp = w_A + nDir);
490 
491  // Perform the method-specific matrix-vector multiply operation.
492  v_DoMatrixMultiply(w_A, s_A);
493 
494  // <r_{k+1}, w_{k+1}>
495  vExchange[0] = Vmath::Dot2(nNonDir,
496  r_A,
497  w_A + nDir,
498  m_map + nDir);
499  // <s_{k+1}, w_{k+1}>
500  vExchange[1] = Vmath::Dot2(nNonDir,
501  s_A + nDir,
502  w_A + nDir,
503  m_map + nDir);
504 
505  // <r_{k+1}, r_{k+1}>
506  vExchange[2] = Vmath::Dot2(nNonDir,
507  r_A,
508  r_A,
509  m_map + nDir);
510 
511  // Perform inner-product exchanges
512  vComm->AllReduce(vExchange, Nektar::LibUtilities::ReduceSum);
513 
514  rho_new = vExchange[0];
515  mu = vExchange[1];
516  eps = vExchange[2];
517 
519 
520  // test if norm is within tolerance
521  if (eps < m_tolerance * m_tolerance * m_rhs_magnitude)
522  {
523  if (m_verbose && m_root)
524  {
525  cout << "CG iterations made = " << m_totalIterations
526  << " using tolerance of " << m_tolerance
527  << " (error = " << sqrt(eps/m_rhs_magnitude)
528  << ", rhs_mag = " << sqrt(m_rhs_magnitude) << ")"
529  << endl;
530  }
531  break;
532  }
533  min_resid = min(min_resid, eps);
534 
535  // Compute search direction and solution coefficients
536  beta = rho_new/rho;
537  alpha = rho_new/(mu - rho_new*beta/alpha);
538  rho = rho_new;
539  k++;
540  }
541  }
void Set_Rhs_Magnitude(const NekVector< NekDouble > &pIn)
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
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.cpp:488
virtual void v_DoMatrixMultiply(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)=0
NekDouble m_tolerance
Tolerance of iterative solver.
Array< OneD, int > m_map
Global to universal unique map.
double NekDouble
static const NekDouble kNekUnsetDouble
NekDouble m_rhs_magnitude
dot product of rhs to normalise stopping criterion
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:127
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:957
#define ROOTONLY_NEKERROR(type, msg)
Definition: ErrorUtil.hpp:213
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:376
PreconditionerSharedPtr CreatePrecon(AssemblyMapSharedPtr asmMap)
Create a preconditioner object from the parameters defined in the supplied assembly map...

◆ Set_Rhs_Magnitude()

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

Definition at line 543 of file GlobalLinSysIterative.cpp.

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 DoConjugateGradient(), and Nektar::MultiRegions::GlobalLinSysIterativeStaticCond::v_PreSolve().

545  {
546  Array<OneD, NekDouble> vExchange(1, 0.0);
547  if (m_map.num_elements() > 0)
548  {
549  vExchange[0] = Vmath::Dot2(pIn.GetDimension(),
550  &pIn[0],&pIn[0],&m_map[0]);
551  }
552 
553  m_expList.lock()->GetComm()->GetRowComm()->AllReduce(
555 
556  // To ensure that very different rhs values are not being
557  // used in subsequent solvers such as the velocit solve in
558  // INC NS. If this works we then need to work out a better
559  // way to control this.
560  NekDouble new_rhs_mag = (vExchange[0] > 1e-6)? vExchange[0] : 1.0;
561 
563  {
564  m_rhs_magnitude = new_rhs_mag;
565  }
566  else
567  {
569  (1.0-m_rhs_mag_sm)*new_rhs_mag);
570  }
571  }
NekDouble m_rhs_mag_sm
cnt to how many times rhs_magnitude is called
Array< OneD, int > m_map
Global to universal unique map.
double NekDouble
static const NekDouble kNekUnsetDouble
NekDouble m_rhs_magnitude
dot product of rhs to normalise stopping criterion
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:127
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:957
unsigned int GetDimension() const
Returns the number of dimensions for the point.
Definition: NekVector.cpp:209

◆ UpdateKnownSolutions()

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

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

Definition at line 253 of file GlobalLinSysIterative.cpp.

References CalculateAnorm(), Vmath::Dot2(), Nektar::eWrapper, Nektar::NekConstants::kNekZeroTol, Nektar::MultiRegions::GlobalLinSys::m_expList, m_map, m_numPrevSols, m_prevLinSol, Nektar::LibUtilities::ReduceSum, Vmath::Smul(), v_DoMatrixMultiply(), and Vmath::Vcopy().

Referenced by DoAconjugateProjection().

257  {
258  // Get vector sizes
259  int nNonDir = nGlobal - nDir;
260 
261  // Get the communicator for performing data exchanges
263  = m_expList.lock()->GetComm()->GetRowComm();
264 
265  // Check the solution is non-zero
266  NekDouble solNorm = Vmath::Dot2(nNonDir,
267  newX + nDir,
268  newX + nDir,
269  m_map + nDir);
270  vComm->AllReduce(solNorm, Nektar::LibUtilities::ReduceSum);
271 
272  if (solNorm < NekConstants::kNekZeroTol)
273  {
274  return;
275  }
276 
277 
278  // Allocate array storage
279  Array<OneD, NekDouble> tmpAx_s (nGlobal, 0.0);
280  Array<OneD, NekDouble> px_s (nGlobal, 0.0);
281  Array<OneD, NekDouble> tmp1, tmp2;
282 
283  // Create NekVector wrappers for linear algebra operations
284  NekVector<NekDouble> px (nNonDir, tmp1 = px_s + nDir, eWrapper);
285  NekVector<NekDouble> tmpAx (nNonDir, tmp2 = tmpAx_s + nDir, eWrapper);
286 
287 
288  // calculating \tilda{x} - sum \alpha_i\tilda{x}_i
289 
290  Vmath::Vcopy(nNonDir,
291  tmp1 = newX + nDir, 1,
292  tmp2 = px_s + nDir, 1);
293 
294  if (m_prevLinSol.size() > 0)
295  {
296  v_DoMatrixMultiply(newX, tmpAx_s);
297  }
298 
299  Array<OneD, NekDouble> alpha (m_prevLinSol.size(), 0.0);
300  for (int i = 0; i < m_prevLinSol.size(); i++)
301  {
302  alpha[i] = Vmath::Dot2(nNonDir,
303  m_prevLinSol[i],
304  tmpAx_s + nDir,
305  m_map + nDir);
306  }
307  vComm->AllReduce(alpha, Nektar::LibUtilities::ReduceSum);
308 
309  for (int i = 0; i < m_prevLinSol.size(); i++)
310  {
311  if (alpha[i] < NekConstants::kNekZeroTol)
312  {
313  continue;
314  }
315 
316  NekVector<NekDouble> xi (nNonDir, m_prevLinSol[i], eWrapper);
317  px -= alpha[i] * xi;
318  }
319 
320 
321  // Some solutions generated by CG are identical zeros, see
322  // solutions generated for Test_Tet_equitri.xml (IncNavierStokesSolver).
323  // Not going to store identically zero solutions.
324 
325  NekDouble anorm = CalculateAnorm(nGlobal, px_s, nDir);
326  if (anorm < NekConstants::kNekZeroTol)
327  {
328  return;
329  }
330 
331  // normalisation of new solution
332  Vmath::Smul(nNonDir, 1.0/anorm, px_s.get() + nDir, 1, px_s.get() + nDir, 1);
333 
334  // updating storage with non-Dirichlet-dof part of new solution vector
335  m_prevLinSol.push_back(px_s + nDir);
336  m_numPrevSols++;
337  }
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
boost::circular_buffer< Array< OneD, NekDouble > > m_prevLinSol
Storage for solutions to previous linear problems.
virtual void v_DoMatrixMultiply(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)=0
NekDouble CalculateAnorm(const int nGlobal, const Array< OneD, const NekDouble > &in, const int nDir)
static const NekDouble kNekZeroTol
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*y.
Definition: Vmath.cpp:216
int m_numPrevSols
Total counter of previous solutions.
Array< OneD, int > m_map
Global to universal unique map.
double NekDouble
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:127
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:957
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1064

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

References DoAconjugateProjection(), DoConjugateGradient(), and m_useProjection.

96  {
97  if (m_useProjection)
98  {
99  DoAconjugateProjection(nGlobal, pInput, pOutput, plocToGloMap, nDir);
100  }
101  else
102  {
103  // applying plain Conjugate Gradient
104  DoConjugateGradient(nGlobal, pInput, pOutput, plocToGloMap, nDir);
105  }
106  }
bool m_useProjection
Whether to apply projection technique.
void DoAconjugateProjection(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const AssemblyMapSharedPtr &locToGloMap, const int pNumDir)
A-conjugate projection technique.
void DoConjugateGradient(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const AssemblyMapSharedPtr &locToGloMap, const int pNumDir)
Actual iterative solve.

◆ v_UniqueMap()

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

Member Data Documentation

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

Referenced by DoConjugateGradient(), and GlobalLinSysIterative().

◆ m_numPrevSols

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

Total counter of previous solutions.

Definition at line 94 of file GlobalLinSysIterative.h.

Referenced by DoAconjugateProjection(), and UpdateKnownSolutions().

◆ m_precon

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

◆ m_precontype

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

Definition at line 80 of file GlobalLinSysIterative.h.

◆ m_prevLinSol

boost::circular_buffer<Array<OneD, NekDouble> > Nektar::MultiRegions::GlobalLinSysIterative::m_prevLinSol
protected

Storage for solutions to previous linear problems.

Definition at line 91 of file GlobalLinSysIterative.h.

Referenced by DoAconjugateProjection(), GlobalLinSysIterative(), 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 76 of file GlobalLinSysIterative.h.

Referenced by Set_Rhs_Magnitude().

◆ m_rhs_magnitude

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

dot product of rhs to normalise stopping criterion

Definition at line 73 of file GlobalLinSysIterative.h.

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

◆ m_root

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

Root if parallel.

Definition at line 88 of file GlobalLinSysIterative.h.

Referenced by DoConjugateGradient(), and GlobalLinSysIterative().

◆ m_tolerance

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

Tolerance of iterative solver.

Definition at line 70 of file GlobalLinSysIterative.h.

Referenced by DoConjugateGradient(), and GlobalLinSysIterative().

◆ m_totalIterations

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

Definition at line 82 of file GlobalLinSysIterative.h.

Referenced by DoConjugateGradient().

◆ m_useProjection

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

Whether to apply projection technique.

Definition at line 85 of file GlobalLinSysIterative.h.

Referenced by GlobalLinSysIterative(), and v_SolveLinearSystem().