2#ifndef AMREX_MLCGSOLVER_H_
3#define AMREX_MLCGSOLVER_H_
4#include <AMReX_Config.H>
65 int solve (MF& solnL,
const MF& rhsL,
RT eps_rel,
RT eps_abs);
74 [[nodiscard]]
int getVerbose ()
const {
return verbose; }
83 [[nodiscard]]
int getMaxIter ()
const {
return maxiter; }
120 [[nodiscard]]
RT dotxy (
const MF& r,
const MF&
z,
bool local =
false);
128 [[nodiscard]]
RT norm_inf (
const MF& res,
bool local =
false);
148 int solve_cg (MF& solnL,
const MF& rhsL,
RT eps_rel,
RT eps_abs);
157 const int amrlev = 0;
163 bool initial_vec_zeroed =
false;
164 std::string print_ident;
167template <
typename MF>
169 : Lp(_lp), solver_type(_typ), mglev(_lp.NMGLevels(0)-1)
174template <
typename MF>
178 if (solver_type == Type::BiCGStab) {
179 return solve_bicgstab(sol,rhs,eps_rel,eps_abs);
181 return solve_cg(sol,rhs,eps_rel,eps_abs);
185template <
typename MF>
191 const int ncomp =
nComp(sol);
193 MF p = Lp.make(amrlev, mglev,
nGrowVect(sol));
194 MF r = Lp.make(amrlev, mglev,
nGrowVect(sol));
198 MF rh = Lp.make(amrlev, mglev, nghost);
199 MF v = Lp.make(amrlev, mglev, nghost);
200 MF t = Lp.make(amrlev, mglev, nghost);
205 if ( initial_vec_zeroed ) {
208 sorig = Lp.make(amrlev, mglev, nghost);
217 Lp.normalize(amrlev, mglev, r);
220 RT rnorm = norm_inf(r);
221 const RT rnorm0 = rnorm;
225 amrex::Print() << print_ident <<
"MLCGSolver_BiCGStab: Initial error (error0) = " << rnorm0 <<
'\n';
229 RT rho_1 = 0, alpha = 0, omega = 0;
231 if ( rnorm0 == 0 || rnorm0 < eps_abs )
235 amrex::Print() << print_ident <<
"MLCGSolver_BiCGStab: niter = 0,"
236 <<
", rnorm = " << rnorm
237 <<
", eps_abs = " << eps_abs <<
'\n';
242 for (; iter <= maxiter; ++iter)
244 const RT rho = dotxy(rh,r);
255 const RT beta = (rho/rho_1)*(alpha/omega);
256 if constexpr (IsMultiFabLike_v<MF>) {
259 Saxpy_Xpay(p, -omega, v, beta, r, 0, 0, ncomp, nghost);
261 Saxpy(p, -omega, v, 0, 0, ncomp, nghost);
262 Xpay(p, beta, r, 0, 0, ncomp, nghost);
266 Lp.normalize(amrlev, mglev, v);
268 RT rhTv = dotxy(rh,v);
269 if ( rhTv !=
RT(0.0) )
277 if constexpr (IsMultiFabLike_v<MF>) {
279 Saxpy_Saxpy(sol, alpha, p, r, -alpha, v, 0, 0, ncomp, nghost);
281 Saxpy(sol, alpha, p, 0, 0, ncomp, nghost);
282 Saxpy(r, -alpha, v, 0, 0, ncomp, nghost);
289 amrex::Print() << print_ident <<
"MLCGSolver_BiCGStab: Half Iter "
290 << std::setw(11) << iter
292 << rnorm/(rnorm0) <<
'\n';
295 if ( rnorm < eps_rel*rnorm0 || rnorm < eps_abs ) {
break; }
298 Lp.normalize(amrlev, mglev, t);
304 RT tvals[2] = { dotxy(t,t,
true), dotxy(t,r,
true) };
310 if ( tvals[0] !=
RT(0.0) )
312 omega = tvals[1]/tvals[0];
318 if constexpr (IsMultiFabLike_v<MF>) {
320 Saypy_Saxpy(sol, omega, r, -omega, t, 0, 0, ncomp, nghost);
322 Saxpy(sol, omega, r, 0, 0, ncomp, nghost);
323 Saxpy(r, -omega, t, 0, 0, ncomp, nghost);
330 amrex::Print() << print_ident <<
"MLCGSolver_BiCGStab: Iteration "
331 << std::setw(11) << iter
333 << rnorm/(rnorm0) <<
'\n';
336 if ( rnorm < eps_rel*rnorm0 || rnorm < eps_abs ) {
break; }
347 amrex::Print() << print_ident <<
"MLCGSolver_BiCGStab: Final: Iteration "
348 << std::setw(4) << iter
350 << rnorm/(rnorm0) <<
'\n';
353 if ( ret == 0 && rnorm > eps_rel*rnorm0 && rnorm > eps_abs)
361 if ( ( ret == 0 || ret == 8 ) && (rnorm < rnorm0) )
363 if ( !initial_vec_zeroed ) {
364 LocalAdd(sol, sorig, 0, 0, ncomp, nghost);
366 if (ret == 8) { ret = 9; }
371 if ( !initial_vec_zeroed ) {
372 LocalAdd(sol, sorig, 0, 0, ncomp, nghost);
379template <
typename MF>
385 const int ncomp =
nComp(sol);
387 MF p = Lp.make(amrlev, mglev,
nGrowVect(sol));
390 MF r = Lp.make(amrlev, mglev, nghost);
391 MF q = Lp.make(amrlev, mglev, nghost);
395 if ( initial_vec_zeroed ) {
398 sorig = Lp.make(amrlev, mglev, nghost);
406 RT rnorm = norm_inf(r);
407 const RT rnorm0 = rnorm;
411 amrex::Print() << print_ident <<
"MLCGSolver_CG: Initial error (error0) : " << rnorm0 <<
'\n';
418 if ( rnorm0 == 0 || rnorm0 < eps_abs )
421 amrex::Print() << print_ident <<
"MLCGSolver_CG: niter = 0,"
422 <<
", rnorm = " << rnorm
423 <<
", eps_abs = " << eps_abs <<
'\n';
428 for (; iter <= maxiter; ++iter)
443 Xpay(p, beta, r, 0, 0, ncomp, nghost);
463 <<
" alpha " << alpha <<
'\n';
465 if constexpr (IsMultiFabLike_v<MF>) {
467 Saxpy_Saxpy(sol, alpha, p, r, -alpha, q, 0, 0, ncomp, nghost);
469 Saxpy(sol, alpha, p, 0, 0, ncomp, nghost);
470 Saxpy(r, -alpha, q, 0, 0, ncomp, nghost);
476 amrex::Print() << print_ident <<
"MLCGSolver_cg: Iteration"
477 << std::setw(4) << iter
479 << rnorm/(rnorm0) <<
'\n';
482 if ( rnorm < eps_rel*rnorm0 || rnorm < eps_abs ) {
break; }
489 amrex::Print() << print_ident <<
"MLCGSolver_cg: Final Iteration"
490 << std::setw(4) << iter
492 << rnorm/(rnorm0) <<
'\n';
495 if ( ret == 0 && rnorm > eps_rel*rnorm0 && rnorm > eps_abs )
503 if ( ( ret == 0 || ret == 8 ) && (rnorm < rnorm0) )
505 if ( !initial_vec_zeroed ) {
506 LocalAdd(sol, sorig, 0, 0, ncomp, nghost);
508 if (ret == 8) { ret = 9; }
513 if ( !initial_vec_zeroed ) {
514 LocalAdd(sol, sorig, 0, 0, ncomp, nghost);
521template <
typename MF>
527 RT result = Lp.xdoty(amrlev, mglev, r,
z, local);
532template <
typename MF>
536 int ncomp =
nComp(res);
#define BL_PROFILE_VAR_START(vname)
Definition AMReX_BLProfiler.H:562
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#define BL_PROFILE_VAR_STOP(vname)
Definition AMReX_BLProfiler.H:563
#define BL_PROFILE_VAR(fname, vname)
Definition AMReX_BLProfiler.H:560
#define BL_PROFILE_VAR_NS(fname, vname)
Definition AMReX_BLProfiler.H:561
CG-family solvers (BiCGStab or CG) for use as the bottom solver in MLMG.
Definition AMReX_MLCGSolver.H:21
RT dotxy(const MF &r, const MF &z, bool local=false)
Dot product helper; set local to true to skip the MPI reduction.
Definition AMReX_MLCGSolver.H:523
void setSolver(Type _typ) noexcept
Switch between BiCGStab and CG after construction.
Definition AMReX_MLCGSolver.H:48
bool getInitSolnZeroed() const
Whether setInitSolnZeroed(true) was requested.
Definition AMReX_MLCGSolver.H:101
void setVerbose(int _verbose)
Control how much logging is emitted (0 = silent).
Definition AMReX_MLCGSolver.H:72
int getNGhost()
Current grow-cell count (same in every direction).
Definition AMReX_MLCGSolver.H:110
MLCGSolverT< MF > & operator=(const MLCGSolverT< MF > &rhs)=delete
int getNumIters() const noexcept
Iteration count from the last solve* call (or -1 if unused).
Definition AMReX_MLCGSolver.H:151
int solve_cg(MF &solnL, const MF &rhsL, RT eps_rel, RT eps_abs)
Raw CG implementation mirroring the high-level solve() signature.
Definition AMReX_MLCGSolver.H:381
RT norm_inf(const MF &res, bool local=false)
Infinity norm helper; set local to true to skip the MPI reduction.
Definition AMReX_MLCGSolver.H:534
void setInitSolnZeroed(bool _sol_zeroed)
Definition AMReX_MLCGSolver.H:99
int solve_bicgstab(MF &solnL, const MF &rhsL, RT eps_rel, RT eps_abs)
Raw BiCGStab implementation mirroring the high-level solve() signature.
Definition AMReX_MLCGSolver.H:187
MLCGSolverT(MLCGSolverT< MF > &&rhs)=delete
typename MLLinOpT< MF >::FAB FAB
Definition AMReX_MLCGSolver.H:24
int getMaxIter() const
Current iteration cap.
Definition AMReX_MLCGSolver.H:83
void setPrintIdentation(std::string s)
Prefix printed messages (e.g., to indent per level).
Definition AMReX_MLCGSolver.H:90
int solve(MF &solnL, const MF &rhsL, RT eps_rel, RT eps_abs)
Solve Lp(solnL)=rhsL to the requested tolerance.
Definition AMReX_MLCGSolver.H:176
Type
Definition AMReX_MLCGSolver.H:27
typename MLLinOpT< MF >::RT RT
Definition AMReX_MLCGSolver.H:25
void setNGhost(int _nghost)
Set the number of grow cells used when allocating temporaries.
Definition AMReX_MLCGSolver.H:108
MLCGSolverT(MLLinOpT< MF > &_lp, Type _typ=Type::BiCGStab)
Construct a solver bound to _lp.
Definition AMReX_MLCGSolver.H:168
int getVerbose() const
Current verbosity level.
Definition AMReX_MLCGSolver.H:74
void setMaxIter(int _maxiter)
Cap the number of Krylov iterations performed.
Definition AMReX_MLCGSolver.H:81
MLCGSolverT(const MLCGSolverT< MF > &rhs)=delete
Abstract base class for multilevel linear operators used by MLMG and the bottom solvers.
Definition AMReX_MLLinOp.H:137
typename FabDataType< MF >::fab_type FAB
Definition AMReX_MLLinOp.H:147
typename FabDataType< MF >::value_type RT
Definition AMReX_MLLinOp.H:148
This class provides the user with a few print options.
Definition AMReX_Print.H:35
void Sum(Gpu::DeviceVector< T > &v, MPI_Comm comm)
Definition AMReX_GpuParallelReduce.H:34
bool IOProcessor() noexcept
Is this CPU the I/O Processor? To get the rank number, call IOProcessorNumber()
Definition AMReX_ParallelDescriptor.H:289
void Max(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:133
Definition AMReX_Amr.cpp:50
int nComp(FabArrayBase const &fa)
Definition AMReX_FabArrayBase.cpp:2852
IntVect nGrowVect(FabArrayBase const &fa)
Definition AMReX_FabArrayBase.cpp:2857
void Saxpy_Xpay(MF &dst, typename MF::value_type a_saxpy, MF const &src_saxpy, typename MF::value_type a_xpay, MF const &src_xpay, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst += a_saxpy * src_saxpy followed by dst = src_xpay + a_xpay * dst
Definition AMReX_FabArrayUtility.H:1914
void Saxpy_Saxpy(MF &dst1, typename MF::value_type a1, MF const &src1, MF &dst2, typename MF::value_type a2, MF const &src2, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst1 += a1 * src1 followed by dst2 += a2 * src2
Definition AMReX_FabArrayUtility.H:1923
void Saypy_Saxpy(MF &dst1, typename MF::value_type a1, MF &dst2, typename MF::value_type a2, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst1 += a1 * dst2 followed by dst2 += a2 * src
Definition AMReX_FabArrayUtility.H:1932
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
void LocalCopy(DMF &dst, SMF const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst = src
Definition AMReX_FabArrayUtility.H:1882
MF::value_type norminf(MF const &mf, int scomp, int ncomp, IntVect const &nghost, bool local=false)
Definition AMReX_FabArrayUtility.H:1961
void Xpay(MF &dst, typename MF::value_type a, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst = src + a * dst
Definition AMReX_FabArrayUtility.H:1906
void Warning(const std::string &msg)
Print a warning message to the diagnostic stream and keep running.
Definition AMReX.cpp:247
void Saxpy(MF &dst, typename MF::value_type a, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst += a * src
Definition AMReX_FabArrayUtility.H:1898
void LocalAdd(MF &dst, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst += src
Definition AMReX_FabArrayUtility.H:1890
void setVal(MF &dst, typename MF::value_type val)
dst = val
Definition AMReX_FabArrayUtility.H:1861