chombo-discharge
Loading...
Searching...
No Matches
Public Member Functions | Public Attributes | Protected Attributes | List of all members
KrylovGMRES< T > Class Template Reference

Restarted GMRES(m) acting on an AMR hierarchy through AMRMultigridKrylovOp. More...

#include <CD_KrylovGMRES.H>

Inheritance diagram for KrylovGMRES< T >:
Inheritance graph
[legend]

Public Member Functions

 KrylovGMRES () noexcept=default
 Default constructor. Call define() before use.
 
 ~KrylovGMRES () noexcept
 Destructor. Frees the persistent basis and scratch.
 
void define (AMRMultigridKrylovOp< T > *a_op, const Vector< LevelData< T > * > &a_template) noexcept
 Allocate the persistent basis (m_restart + 1 vectors) and scratch. Call once per regrid.
 
void undefine () noexcept
 Free the persistent basis and scratch.
 
bool isDefined () const noexcept
 Whether define() has been called.
 
bool solve (Vector< LevelData< T > * > &a_phi, const Vector< LevelData< T > * > &a_rhs) noexcept
 Solve a_op(a_phi) = a_rhs (homogeneous operator) with restarted GMRES(m_restart).
 

Public Attributes

Real m_eps = 1.E-10
 Relative residual tolerance, measured against m_residualScale.
 
int m_maxIter = 50
 Maximum number of iterations (total Arnoldi steps across restart cycles).
 
int m_restart = 30
 Restart length m in GMRES(m). Must be set before define() (sizes the persistent basis).
 
bool m_reorthogonalize = true
 Whether to do one classical Gram-Schmidt reorthogonalization pass (robustness; on by default).
 
int m_verbosity = -1
 Verbosity; at >= 4 a terse one-line-per-iteration residual history is printed.
 
int m_exitStatus = -1
 Exit status after solve(): 1 = converged, 3 = max iterations, -1 = not run.
 
Real m_residualNorm = -1.0
 Final residual norm after solve() (in the adapter inner-product norm).
 
int m_iterations = 0
 Number of Arnoldi iterations performed by the last solve().
 
Real m_residualScale = 0.0
 Norm that both the printed residual and the convergence test are measured against.
 

Protected Attributes

AMRMultigridKrylovOp< T > * m_op = nullptr
 Operator/adapter (not owned).
 
bool m_isDefined = false
 Whether the basis/scratch are allocated.
 
int m_allocRestart = 0
 Restart length the persistent storage was sized for.
 
Vector< Vector< LevelData< T > * > > m_basis
 Arnoldi basis, size m_allocRestart + 1.
 
Vector< LevelData< T > * > m_w
 A*K^{-1}*v_j scratch.
 
Vector< LevelData< T > * > m_z
 K^{-1}*v_j and final preconditioned-update scratch.
 
Vector< LevelData< T > * > m_c
 Accumulated unpreconditioned solution update (sum y_k v_k).
 
Vector< LevelData< T > * > m_r
 Residual.
 
Vector< Real > m_H
 Hessenberg matrix, column-major, leading dimension m_allocRestart + 1.
 
Vector< Real > m_cs
 Givens cosines.
 
Vector< Real > m_sn
 Givens sines.
 
Vector< Real > m_g
 Rotated residual right-hand side.
 
Vector< Real > m_y
 Least-squares solution.
 
Vector< Real > m_hcol
 Persistent scratch for one Gram-Schmidt projection row (size m_allocRestart).
 
Vector< Real > m_corr
 Persistent scratch for the reorthogonalization correction row (size m_allocRestart).
 

Detailed Description

template<class T>
class KrylovGMRES< T >

Restarted GMRES(m) acting on an AMR hierarchy through AMRMultigridKrylovOp.

A chombo-discharge replacement for Chombo's GMRESSolver on the outer Krylov path, written for scale-out. The Arnoldi basis (m_restart + 1 hierarchies) and the few scratch vectors are allocated once in define() and reused across solves (no per-solve allocation). Orthogonalization uses classical Gram-Schmidt issued through the adapter's batched mDotProduct, so each Arnoldi step costs a single MPI reduction (plus one for the norm) regardless of the AMR level count – as opposed to the modified Gram-Schmidt / per-vector dot products that scale poorly. Right preconditioning keeps the tracked residual the true residual; the preconditioned solution update is formed once per restart cycle (one extra preCond), so the basis vectors need not be stored in preconditioned form.

Note
T is the FAB type (EBCellFAB or MFCellFAB).

Member Function Documentation

◆ define()

template<class T >
void KrylovGMRES< T >::define ( AMRMultigridKrylovOp< T > *  a_op,
const Vector< LevelData< T > * > &  a_template 
)
noexcept

Allocate the persistent basis (m_restart + 1 vectors) and scratch. Call once per regrid.

Parameters
[in]a_opThe (already define()d) operator/adapter to solve against
[in]a_templateA hierarchy whose layout the work vectors mirror (e.g. the rhs)

◆ isDefined()

template<class T >
bool KrylovGMRES< T >::isDefined ( ) const
noexcept

Whether define() has been called.

Returns
True if defined.

◆ solve()

template<class T >
bool KrylovGMRES< T >::solve ( Vector< LevelData< T > * > &  a_phi,
const Vector< LevelData< T > * > &  a_rhs 
)
noexcept

Solve a_op(a_phi) = a_rhs (homogeneous operator) with restarted GMRES(m_restart).

Parameters
[in,out]a_phiSolution (in: initial guess; out: solution). Warm starts are honoured.
[in]a_rhsRight-hand side.
Returns
True if converged (m_exitStatus == 1).

Member Data Documentation

◆ m_residualScale

template<class T >
Real KrylovGMRES< T >::m_residualScale = 0.0

Norm that both the printed residual and the convergence test are measured against.

The driver sets this to the zero-residual ||r_zero|| = ||rhs - L(0)||, which is the scale the hosting solver itself uses to decide whether a solution has converged. Measuring the exit test on that same scale is what makes m_eps mean the same thing here as it does to the caller, and is also what lets a warm start pay for itself: scaling the tolerance by this solve's own initial residual instead would demand the same reduction factor no matter how good the initial guess was. A non-positive value falls back to this solve's initial residual norm, which is the right scale when there is no host to agree with.


The documentation for this class was generated from the following files: