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;
114 const Real scale = (m_residualScale > 0.0) ? m_residualScale : rnorm0;
115 const Real epsScaled = m_eps * scale;
125 auto restart = [&]() ->
void {
126 op.
incr(a_phi, m_e, 1.0);
138 rnorm = op.
norm(m_r, 2);
144 auto breakdown = [&]() ->
bool {
145 if (restarts < m_numRestarts) {
156 while (iter < m_maxIter && rnorm > epsScaled) {
157 const Real rnormStart = rnorm;
159 const Real rhoNew = op.
dotProduct(m_rTilde, m_r);
171 const Real beta = (rhoNew / rho) * (alpha / omega);
172 op.
incr(m_p, m_v, -omega);
174 op.
incr(m_p, m_r, 1.0);
177 op.
applyOp(m_v, m_pTilde,
true);
179 const Real rtv = op.
dotProduct(m_rTilde, m_v);
187 alpha = rhoNew / rtv;
189 op.
incr(m_e, m_pTilde, alpha);
190 op.
incr(m_r, m_v, -alpha);
192 rnorm = op.
norm(m_r, 2);
193 if (rnorm <= epsScaled) {
201 op.
applyOp(m_t, m_sTilde,
true);
205 const Vector<LevelData<T>*> rhsPair[2] = {m_r, m_t};
209 const Real tDotT = dots[1];
219 omega = dots[0] / tDotT;
221 op.
incr(m_e, m_sTilde, omega);
222 op.
incr(m_r, m_t, -omega);
224 rnorm = op.
norm(m_r, 2);
228 if (m_verbosity >= 3) {
230 pout() <<
" KrylovBiCGStab:: iteration = " << iter <<
", rel. residual = " << (rnorm / scale)
231 <<
", rate = " << ((rnorm > 0.0) ? rnormStart / rnorm : 0.0) << endl;
234 if (rnorm <= epsScaled) {
252 if (m_exitStatus == -1) {
253 m_exitStatus = (rnorm <= epsScaled) ? 1 : 3;
256 m_residualNorm = rnorm;
259 op.
incr(a_phi, m_e, 1.0);
261 return (m_exitStatus == 1);
264#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