chombo-discharge
Loading...
Searching...
No Matches
CD_EllipticSolverChain.H
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2021-2026 SINTEF Energy Research
3 *
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 */
6
13#ifndef CD_ELLIPTICSOLVERCHAIN_H
14#define CD_ELLIPTICSOLVERCHAIN_H
15
16// Std includes
17#include <algorithm>
18#include <string>
19
20// Chombo includes
21#include <AMRMultiGrid.H>
22#include <LevelData.H>
23#include <Vector.H>
24#include <parstream.H>
25
26// Our includes
28#include <CD_KrylovBiCGStab.H>
29#include <CD_KrylovGMRES.H>
30#include <CD_NamespaceHeader.H>
31
38
42enum class SolverType
43{
47 GMG,
48
52 GMRES,
53
58};
59
64{
69 Vector<SolverType> solvers = Vector<SolverType>(1, SolverType::GMG);
70
74 Real eps = 1.E-10;
75
79 int maxIter = 50;
80
84 int restart = 30;
85
90 int numVCycles = 1;
91
95 int verbosity = -1;
96
101 bool
103 {
104 for (int i = 0; i < solvers.size(); i++) {
105 if (solvers[i] != SolverType::GMG) {
106 return true;
107 }
108 }
109
110 return false;
111 }
112};
113
130{
135
142
151 int
152 startIndex(const Vector<SolverType>& a_solvers)
153 {
154 if (!m_latched) {
155 return 0;
156 }
157
158 if (m_reprobeNext || m_sinceProbe + 1 >= std::max(1, retryInterval)) {
159 m_sinceProbe = 0;
160 m_reprobeNext = false;
161
162 return 0; // re-probe GMG (periodic or adaptive)
163 }
164
165 m_sinceProbe++; // another solve skipped GMG; advance toward the next periodic re-probe
166
167 return this->firstNonGmg(a_solvers);
168 }
169
182 void
183 recordOutcome(const bool a_gmgAttempted,
184 const bool a_gmgConverged,
185 const int a_krylovIters = -1,
186 const int a_verbosity = -1,
187 const std::string& a_name = "")
188 {
189 if (a_gmgAttempted) {
190 const bool wasLatched = m_latched;
191
192 m_latched = !a_gmgConverged;
193 if (m_latched) {
194 m_sinceProbe = 0;
195 }
196
197 if (a_verbosity >= 1 && wasLatched && !m_latched) {
198 pout() << a_name << " - multigrid re-probe succeeded; releasing the Krylov fallback latch" << endl;
199 }
200 }
201 else if (m_latched && reprobeIters > 0 && a_krylovIters >= 0 && a_krylovIters <= reprobeIters) {
202 // The Krylov fallback found the problem easy, so GMG alone may now succeed -- re-probe it next solve.
203 m_reprobeNext = true;
204 }
205 }
206
211 bool
212 isLatched() const
213 {
214 return m_latched;
215 }
216
217protected:
221 bool m_latched = false;
222
227
231 bool m_reprobeNext = false;
232
238 int
239 firstNonGmg(const Vector<SolverType>& a_solvers) const
240 {
241 for (int i = 0; i < a_solvers.size(); i++) {
242 if (a_solvers[i] != SolverType::GMG) {
243 return i;
244 }
245 }
246
247 return 0;
248 }
249};
250
258inline SolverType
259toSolverType(const std::string& a_str)
260{
261 if (a_str == "gmg") {
262 return SolverType::GMG;
263 }
264 else if (a_str == "gmres") {
265 return SolverType::GMRES;
266 }
267 else if (a_str == "bicgstab") {
269 }
270 else {
271 MayDay::Error("EllipticSolverChain::toSolverType - solver must be 'gmg', 'gmres', or 'bicgstab'");
272 }
273
274 return SolverType::GMG;
275}
276
282inline std::string
284{
285 switch (a_type) {
286 case SolverType::GMG: {
287 return "gmg";
288 }
289 case SolverType::GMRES: {
290 return "gmres";
291 }
293 return "bicgstab";
294 }
295 }
296
297 return "unknown";
298}
299
310template <class T>
312{
313public:
317 using Vec = Vector<LevelData<T>*>;
318
322 KrylovSolver() noexcept = default;
323
327 ~KrylovSolver() noexcept;
328
340 void
341 define(AMRMultiGrid<LevelData<T>>* a_mg,
342 const Vector<RefCountedPtr<LevelData<BaseFab<bool>>>>& a_validCells,
343 const Vector<Real>& a_dx,
344 const int a_lbase,
345 const int a_lmax,
346 const int a_numVCycles);
347
357 bool
358 solve(Vec& a_phi, const Vec& a_rhs, const bool a_zeroPhi, const SolverType a_type, const Settings& a_settings);
359
364 int
366 {
367 return m_lastKrylovIters;
368 }
369
377 void
378 snapshotGuess(Vec& a_phi, const Vec& a_rhs);
379
389 bool
390 keepOrRestore(Vec& a_phi, const Vec& a_rhs);
391
392protected:
397 void
398 allocateWork(const Vec& a_template);
399
403 void
404 freeWork();
405
409 AMRMultiGrid<LevelData<T>>* m_mg = nullptr;
410
415
420
425
430
434 int m_lbase = 0;
435
439 int m_lmax = 0;
440
444 bool m_isDefined = false;
445
449 bool m_workAllocated = false;
450
455
460
465
469 Real m_initResidual = 0.0;
470};
471
472} // namespace EllipticSolverChain
473
474#include <CD_NamespaceFooter.H>
475
477
478#endif
Linear-operator adapter that exposes an AMR-multigrid cycle as a Krylov preconditioner.
Implementation of CD_EllipticSolverChain.H.
Preconditioned BiCGStab over an AMR hierarchy, with persistent work vectors and fused reductions.
Restarted, right-preconditioned GMRES over an AMR hierarchy, with persistent basis and fused reductio...
Adapter presenting an already-defined AMRMultiGrid as a LinearOp over the AMR hierarchy.
Definition CD_AMRMultigridKrylovOp.H:78
Stateful owner of the outer-Krylov solver path.
Definition CD_EllipticSolverChain.H:312
Vec m_dphi
Persistent correction.
Definition CD_EllipticSolverChain.H:459
Vec m_phiInit
Snapshot of the chain's starting guess (the initial-residual solution) for the warm-start rule.
Definition CD_EllipticSolverChain.H:464
bool keepOrRestore(Vec &a_phi, const Vec &a_rhs)
Warm-start rule applied between fallback attempts.
Definition CD_EllipticSolverChainImplem.H:76
bool m_workAllocated
Whether r0/dphi are allocated for the current grid.
Definition CD_EllipticSolverChain.H:449
int lastKrylovIterations() const
Iteration count of the most recent Krylov solve (GMRES/BiCGStab).
Definition CD_EllipticSolverChain.H:365
int m_lastKrylovIters
Iteration count of the most recent Krylov solve, or -1 if none has run.
Definition CD_EllipticSolverChain.H:429
bool solve(Vec &a_phi, const Vec &a_rhs, const bool a_zeroPhi, const SolverType a_type, const Settings &a_settings)
Solve L(phi) = rhs with the chosen outer Krylov method preconditioned by the multigrid cycle.
Definition CD_EllipticSolverChainImplem.H:119
int m_lmax
Finest level.
Definition CD_EllipticSolverChain.H:439
void snapshotGuess(Vec &a_phi, const Vec &a_rhs)
Snapshot the chain's starting guess and its residual for the fallback warm-start rule.
Definition CD_EllipticSolverChainImplem.H:62
Real m_initResidual
Residual of the snapshot (the initial residual of the fallback chain).
Definition CD_EllipticSolverChain.H:469
bool m_isDefined
Whether define() has been called.
Definition CD_EllipticSolverChain.H:444
Vec m_r0
Persistent initial residual.
Definition CD_EllipticSolverChain.H:454
AMRMultiGrid< LevelData< T > > * m_mg
Multigrid solver (not owned).
Definition CD_EllipticSolverChain.H:409
KrylovGMRES< T > m_gmres
Custom GMRES solver (lazily defined on first GMRES solve).
Definition CD_EllipticSolverChain.H:424
KrylovSolver() noexcept=default
Default constructor. Must call define() before use.
int m_lbase
Coarsest level.
Definition CD_EllipticSolverChain.H:434
Vector< LevelData< T > * > Vec
Multilevel data type.
Definition CD_EllipticSolverChain.H:317
void define(AMRMultiGrid< LevelData< T > > *a_mg, const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > &a_validCells, const Vector< Real > &a_dx, const int a_lbase, const int a_lmax, const int a_numVCycles)
Define the multigrid-preconditioner adapter and reset the persistent work. Call once per regrid.
Definition CD_EllipticSolverChainImplem.H:95
AMRMultigridKrylovOp< T > m_op
Multigrid-cycle-as-preconditioner adapter.
Definition CD_EllipticSolverChain.H:414
KrylovBiCGStab< T > m_bicg
Custom BiCGStab solver (lazily defined on first BiCGStab solve).
Definition CD_EllipticSolverChain.H:419
void allocateWork(const Vec &a_template)
Lazily allocate the persistent residual-correction vectors r0/dphi from a template hierarchy.
Definition CD_EllipticSolverChainImplem.H:52
void freeWork()
Free the persistent work vectors and undefine the custom solvers.
Definition CD_EllipticSolverChainImplem.H:37
Preconditioned BiCGStab solver acting on an AMR hierarchy through AMRMultigridKrylovOp.
Definition CD_KrylovBiCGStab.H:36
Restarted GMRES(m) acting on an AMR hierarchy through AMRMultigridKrylovOp.
Definition CD_KrylovGMRES.H:38
Support code for using an AMR-multigrid cycle as a preconditioner for an outer Krylov solver.
Definition CD_EllipticSolverChain.H:37
std::string solverTypeName(const SolverType a_type)
Human-readable name for a solver type, for diagnostic output.
Definition CD_EllipticSolverChain.H:283
SolverType toSolverType(const std::string &a_str)
Map a solver-type string to the corresponding enum.
Definition CD_EllipticSolverChain.H:259
SolverType
Top-level solve method.
Definition CD_EllipticSolverChain.H:43
@ BiCGStab
BiCGStab preconditioned by the multigrid cycle.
@ GMG
Stand-alone multigrid V-cycling (no outer Krylov).
@ GMRES
GMRES preconditioned by the multigrid cycle.
Stateful policy for the solver fallback chain.
Definition CD_EllipticSolverChain.H:130
int retryInterval
Re-probe GMG every this many solves while latched. Clamped to >= 1; 1 reproduces always-retry behavio...
Definition CD_EllipticSolverChain.H:134
bool isLatched() const
Whether the policy is currently latched onto the Krylov fallback.
Definition CD_EllipticSolverChain.H:212
int startIndex(const Vector< SolverType > &a_solvers)
Start index into a_solvers for this solve, advancing the re-probe counter. Call exactly once per solv...
Definition CD_EllipticSolverChain.H:152
void recordOutcome(const bool a_gmgAttempted, const bool a_gmgConverged, const int a_krylovIters=-1, const int a_verbosity=-1, const std::string &a_name="")
Record the outcome of this solve and update the latch.
Definition CD_EllipticSolverChain.H:183
bool m_reprobeNext
Whether a cheap Krylov solve has armed an adaptive early re-probe of GMG on the next solve.
Definition CD_EllipticSolverChain.H:231
bool m_latched
Whether a failed GMG attempt has latched us onto the Krylov fallback.
Definition CD_EllipticSolverChain.H:221
int firstNonGmg(const Vector< SolverType > &a_solvers) const
Index of the first non-GMG solver in the chain, or 0 if there is none.
Definition CD_EllipticSolverChain.H:239
int m_sinceProbe
Solves since the last GMG attempt while latched.
Definition CD_EllipticSolverChain.H:226
int reprobeIters
Adaptive early re-probe: re-probe GMG on the next solve whenever the Krylov fallback converged in thi...
Definition CD_EllipticSolverChain.H:141
Outer-Krylov configuration. Defaults reproduce stand-alone multigrid (solvers == {GMG}).
Definition CD_EllipticSolverChain.H:64
Real eps
Relative residual tolerance.
Definition CD_EllipticSolverChain.H:74
int restart
GMRES restart length (unused for BiCGStab).
Definition CD_EllipticSolverChain.H:84
Vector< SolverType > solvers
Solvers attempted in order; the first that converges wins. E.g. {GMG, GMRES} means "try stand-alone ...
Definition CD_EllipticSolverChain.H:69
int maxIter
Maximum outer iterations.
Definition CD_EllipticSolverChain.H:79
bool usesKrylov() const
Whether any solver in the chain is a Krylov method (and hence needs the preconditioner adapter).
Definition CD_EllipticSolverChain.H:102
int numVCycles
Number of multigrid cycles applied per preconditioner invocation. The cycle type (V/W) is deferred to...
Definition CD_EllipticSolverChain.H:90
int verbosity
Outer Krylov verbosity.
Definition CD_EllipticSolverChain.H:95