13#ifndef CD_KRYLOVBICGSTABIMPLEM_H
14#define CD_KRYLOVBICGSTABIMPLEM_H
22#include <CD_NamespaceHeader.H>
34 CH_TIME(
"KrylovBiCGStab::define");
41 m_op->create(m_r, a_template);
42 m_op->create(m_rTilde, a_template);
43 m_op->create(m_e, a_template);
44 m_op->create(m_p, a_template);
45 m_op->create(m_pTilde, a_template);
46 m_op->create(m_sTilde, a_template);
47 m_op->create(m_t, a_template);
48 m_op->create(m_v, a_template);
59 m_op->clear(m_rTilde);
62 m_op->clear(m_pTilde);
63 m_op->clear(m_sTilde);
82 CH_TIME(
"KrylovBiCGStab::solve");
84 CH_assert(m_isDefined);
92 auto computeResidual = [&]() ->
void {
94 op.
axby(m_r, a_rhs, m_r, 1.0, -1.0);
103 const Real rnorm0 = op.
norm(m_r, 2);
107 m_residualNorm = 0.0;
120 auto restart = [&]() ->
void {
121 op.
incr(a_phi, m_e, 1.0);
133 rnorm = op.
norm(m_r, 2);
139 auto breakdown = [&]() ->
bool {
140 if (restarts < m_numRestarts) {
151 while (iter < m_maxIter && rnorm > m_eps * rnorm0) {
152 const Real rnormStart = rnorm;
154 const Real rhoNew = op.
dotProduct(m_rTilde, m_r);
166 const Real beta = (rhoNew / rho) * (alpha / omega);
167 op.
incr(m_p, m_v, -omega);
169 op.
incr(m_p, m_r, 1.0);
172 op.
applyOp(m_v, m_pTilde,
true);
174 const Real rtv = op.
dotProduct(m_rTilde, m_v);
182 alpha = rhoNew / rtv;
184 op.
incr(m_e, m_pTilde, alpha);
185 op.
incr(m_r, m_v, -alpha);
187 rnorm = op.
norm(m_r, 2);
188 if (rnorm <= m_eps * rnorm0) {
196 op.
applyOp(m_t, m_sTilde,
true);
200 const Vector<LevelData<T>*> rhsPair[2] = {m_r, m_t};
204 const Real tDotT = dots[1];
214 omega = dots[0] / tDotT;
216 op.
incr(m_e, m_sTilde, omega);
217 op.
incr(m_r, m_t, -omega);
219 rnorm = op.
norm(m_r, 2);
223 if (m_verbosity >= 3) {
225 pout() <<
" KrylovBiCGStab:: iteration = " << iter <<
", rel. residual = " << (rnorm / m_residualScale)
226 <<
", rate = " << ((rnorm > 0.0) ? rnormStart / rnorm : 0.0) << endl;
229 if (rnorm <= m_eps * rnorm0) {
247 if (m_exitStatus == -1) {
248 m_exitStatus = (rnorm <= m_eps * rnorm0) ? 1 : 3;
251 m_residualNorm = rnorm;
254 op.
incr(a_phi, m_e, 1.0);
256 return (m_exitStatus == 1);
259#include <CD_NamespaceFooter.H>
Preconditioned BiCGStab over an AMR hierarchy, with persistent work vectors and fused reductions.
Adapter presenting an already-defined AMRMultiGrid as a LinearOp over the AMR hierarchy.
Definition CD_AMRMultigridKrylovOp.H:78
void incr(Vector< LevelData< T > * > &a_lhs, const Vector< LevelData< T > * > &a_x, Real a_scale) override
Increment a_lhs += a_scale*a_x.
Definition CD_AMRMultigridKrylovOpImplem.H:275
void assign(Vector< LevelData< T > * > &a_lhs, const Vector< LevelData< T > * > &a_rhs) override
Copy a_rhs into a_lhs.
Definition CD_AMRMultigridKrylovOpImplem.H:154
void preCond(Vector< LevelData< T > * > &a_cor, const Vector< LevelData< T > * > &a_residual) override
Apply the preconditioner: a_cor approx L^{-1} a_residual via m_numVCycles multigrid cycles (cycle typ...
Definition CD_AMRMultigridKrylovOpImplem.H:97
void mDotProduct(const Vector< LevelData< T > * > &a_1, const int a_sz, const Vector< LevelData< T > * > a_2[], Real a_mdots[]) override
Batched inner products a_mdots[k] = dotProduct(a_1, a_2[k]) for k=0..a_sz-1.
Definition CD_AMRMultigridKrylovOpImplem.H:214
void axby(Vector< LevelData< T > * > &a_lhs, const Vector< LevelData< T > * > &a_x, const Vector< LevelData< T > * > &a_y, Real a_a, Real a_b) override
Set a_lhs = a_a*a_x + a_b*a_y.
Definition CD_AMRMultigridKrylovOpImplem.H:284
void applyOp(Vector< LevelData< T > * > &a_lhs, const Vector< LevelData< T > * > &a_phi, bool a_homogeneous=false) override
Matrix-vector product L(phi) over the AMR hierarchy (always homogeneous for the Krylov path).
Definition CD_AMRMultigridKrylovOpImplem.H:74
Real norm(const Vector< LevelData< T > * > &a_rhs, int a_ord) override
Norm of a_rhs. For a_ord==2 this is the inner-product-induced norm sqrt(dotProduct(x,...
Definition CD_AMRMultigridKrylovOpImplem.H:306
Real dotProduct(const Vector< LevelData< T > * > &a_1, const Vector< LevelData< T > * > &a_2) override
AMR-composite inner product (allocation-free, fine-covered cells masked out).
Definition CD_AMRMultigridKrylovOpImplem.H:163
void setToZero(Vector< LevelData< T > * > &a_lhs) override
Set a_lhs = 0.
Definition CD_AMRMultigridKrylovOpImplem.H:322
void scale(Vector< LevelData< T > * > &a_lhs, const Real &a_scale) override
Scale a_lhs *= a_scale.
Definition CD_AMRMultigridKrylovOpImplem.H:297
bool isDefined() const noexcept
Whether define() has been called and the work vectors are allocated.
Definition CD_KrylovBiCGStabImplem.H:73
bool solve(Vector< LevelData< T > * > &a_phi, const Vector< LevelData< T > * > &a_rhs) noexcept
Solve a_op(a_phi) = a_rhs (homogeneous operator) with preconditioned BiCGStab.
Definition CD_KrylovBiCGStabImplem.H:80
void undefine() noexcept
Free the persistent work vectors.
Definition CD_KrylovBiCGStabImplem.H:55
void define(AMRMultigridKrylovOp< T > *a_op, const Vector< LevelData< T > * > &a_template) noexcept
Allocate the persistent work vectors. Call once per regrid.
Definition CD_KrylovBiCGStabImplem.H:32
~KrylovBiCGStab() noexcept
Destructor. Frees the persistent work vectors.
Definition CD_KrylovBiCGStabImplem.H:25