BELFEM 0.9.3
Berkeley Lab Finite Element Framework
Loading...
Searching...
No Matches
cl_SolverParameters.hpp
Go to the documentation of this file.
1/*
2 * BELFEM -- The Berkeley Lab Finite Element Framework
3 * Copyright (c) 2026, The Regents of the University of California, through
4 * Lawrence Berkeley National Laboratory (subject to receipt of any required
5 * approvals from the U.S. Dept. of Energy). All rights reserved.
6 *
7 * Developers: Christian Messe, Gregory Giard
8 *
9 * See the top-level LICENSE file for the complete license and disclaimer.
10 */
11
12#ifndef BELFEM_CL_SOLVERPARAMETERS_HPP
13#define BELFEM_CL_SOLVERPARAMETERS_HPP
14#include "en_SolverEnums.hpp"
15#include "cl_Input_Section.hpp"
16#include "commtools.hpp"
17
18namespace belfem
19{
27 {
28 const proc_t mCommRank ;
29 const SolverType mSolverType = gDefaultSolver ;
30
31 // CSR is recommended: STRUMPACK's set_distributed_csr_matrix() is
32 // its primary and most-tested MPI interface. The MPIAIJ path
33 // (set_MPIAIJ_matrix) causes hangs during distributed multifrontal
34 // factorization and lacks upstream C++ test coverage.
35 DistributedMatrixType mDistributedMatrixType = DistributedMatrixType::CSR ;
36
38
40
41 // BLR compression tolerance, consumed ONLY when the deck says
42 // compression scheme : blr. One number, two strictnesses:
43 // STRUMPACK applies it as a RELATIVE rel_tol, MUMPS as the
44 // ABSOLUTE CNTL(7) dropping parameter ( MUMPS 5.7.3 §5.19 ).
45 // See src/sparse/doc/solver_memory_and_compression.md §4
46 real mCompressionCutoff = 1e-8 ;
47
48 // true once the deck ( or a programmatic caller ) stated a
49 // cutoff — distinguishes a chosen trade from the inherited
50 // default in the headroom check
51 bool mHaveCompressionCutoff = false ;
52
53 // MUMPS only: per-process working-memory cap in MB, handed to
54 // ICNTL(23) before the first factorization. 0 = not stated; the
55 // wrapper then measures the machine itself in initialize() ( see
56 // MUMPS::memory_budget_mb ) and applies that number as ICNTL(23)
57 // on the first out-of-workspace failure. An explicit value wins
58 // over that measurement
59 uint mMemoryBudget = 0 ;
60 bool mHaveMemoryBudget = false ;
61
62 // MC64 matrix matching, only used by STRUMPACK. Its permutation is
63 // load-bearing for the coupled h-phi Jacobian: without it the Newton
64 // stage hits exact zero pivots that replace_tiny_pivots cannot absorb.
65 // Expensive in MPI mode ( STRUMPACK gathers the full matrix on rank 0,
66 // once per initialize ) -- ( matching : off ) is an opt-out for cases
67 // verified to tolerate it.
68 bool mUseMatrixMatching = true ;
69
70 // STRUMPACK / serial-METIS only. METIS_NodeNDP returns the separator
71 // tree; METIS_NodeND does not, so STRUMPACK has to rebuild a supernodal
72 // tree from the elimination tree instead, and that reconstruction is
73 // what produces very deep trees. Observed on a large 3D deck:
74 // "used METIS_NodeND (iso METIS_NodeNDP)",
75 // "supernodal tree was built from etree", 56 levels — and STRUMPACK's
76 // own diagnostic then warned that it "does not handle this safely,
77 // which could lead to segmentation faults due to stack overflows",
78 // recommending precisely this flag. The same deep tree is the likely
79 // cause of the factorisation memory landing overwhelmingly on one rank
80 // ( 23 GiB against 2.8 GiB on its siblings ).
81 //
82 // METIS_NodeNDP is UNDOCUMENTED in METIS and declared by STRUMPACK
83 // itself, so it is kept switchable: ( metis nodendp : false ) restores
84 // METIS_NodeND if a METIS build does not provide it. Irrelevant to
85 // PARMETIS and SCOTCH, which ignore the flag.
86 bool mUseMetisNodeNDP = true ;
87
88 // Only used for PETSc, ignored otherwise.
89 //
90 // ASM ( additive Schwarz, PETSc default sub-solver ILU(0) ) rather than
91 // the former GAMG-in-parallel / JACOBI-in-serial pair, for two reasons.
92 //
93 // 1. The consumer is not the operator GAMG is built for. Smoothed
94 // aggregation assumes a symmetric elliptic system; that describes
95 // the PICARD thermal operator ( M/dt + K, SPD ) but not the NEWTON
96 // tangent, which carries the non-symmetric mixed-operator term
97 // ( B'*grad T ) (x) ( dlambda/dT * N ) from mt_thermal_h. On a
98 // coupled tape stack GAMG needed about nine times more Krylov
99 // iterations on the Newton iterates than on the Picard iterates
100 // of the same step -- a penalty that appears exactly when the
101 // algorithm flips. ASM is slightly
102 // worse on the Picard operator ( ~107 ) and does not degrade on the
103 // Newton one, which is the trade this default takes.
104 //
105 // 2. The old pair changed the preconditioner WITH THE RANK COUNT, so a
106 // serial and a parallel run of the same deck solved with different
107 // numerics. Same defect class as the thermal Picard freeze, where
108 // partition-order roundoff selected the nonlinear algorithm. ASM with one block
109 // degenerates to ILU, so the family is now continuous in comm_size.
110 //
111 // A deck that knows its operator is symmetric can still ask for GAMG
112 // through ( preconditioner : gamg ) -- and should, since GAMG wins on
113 // the Picard operator.
114 Preconditioner mPreconditioner = Preconditioner::ASM ;
115
116 // only used for PETSc and STRUMPACK. AUTO resolves to PREONLY behind a
117 // direct LU preconditioner and GMRES otherwise ( cl_SolverPETSC.cpp ),
118 // which is the correct choice for the non-symmetric Newton tangent
119 // above -- a symmetric-only method such as CG must not become the
120 // default while that term is in the operator.
121 KrylovMethod mKrylovMethod = KrylovMethod::AUTO ;
122
123 // Relative tolerance: PETSc KSP rtol AND STRUMPACK outer-GMRES
124 // rel_tol, always applied ( an unstated deck would otherwise
125 // inherit the library's 1e-6, and that loose exit test becomes the
126 // printed nonlinear residual — see strumpacktools ).
127 //
128 // 1e-10 rather than 1e-8 because a transient solved for an ABSOLUTE
129 // field accepts an absolute error of ~rtol * |field| per step. A
130 // thermal run in kelvin therefore drifts by ~rtol * T every step, and
131 // in an adiabatic or weakly forced problem nothing pulls it back:
132 // measured on a thermal run from a uniform 77 K start: a drift of
133 // 8.6e-5 K in 23 steps at rtol 1e-8, and 2.6e-7 K
134 // at rtol 1e-10. The failure is silent -- no residual, no message --
135 // so the default carries the safety margin rather than the deck.
136 // ( The old reassurance "STRUMPACK pays nothing, the factorization
137 // already delivers ~2e-16" was refuted by the A/B: on an
138 // ill-conditioned matrix the raw factor gives ~4 digits and the
139 // OUTER GMRES is what reaches deep residuals. )
140 //
141 // This is a mitigation, not the cure. The cure is to solve in
142 // increment form, where the criterion becomes scale-free.
143 real mRelativeTolerance = 1e-10;
144
145 // Set when the deck or set_relative_tolerance() stated a value.
146 // This flag does not control application of mRelativeTolerance:
147 // STRUMPACK always applies it, as PETSc does. Do not add a
148 // have_relative_tolerance() guard in strumpacktools. PREC_GMRES,
149 // maxit 50, and abs_tol prevent stalls. The flag remains in
150 // synchronize() so the positional payload keeps its slot ( current
151 // width 13, see the history note in synchronize() ).
152 bool mHaveRelativeTolerance = false ;
153
154 // Absolute tolerance of the ITERATIVE part of a linear solve.
155 //
156 // STRUMPACK: exit test of the outer GMRES next to rel_tol. The
157 // library default is 1e-10 ( StrumpackOptions.hpp ), and BELFEM
158 // shipped with it unset for years — on a SMALL right-hand side
159 // ( transient startup, ||b|| ~ 1e-2 ) that floor sits exactly at
160 // a 1e-11 RELATIVE nonlinear target and Newton converges only by
161 // GMRES overshoot lottery.
162 // 1e-14 restores >= 3 decades of headroom while keeping GMRES:
163 // the factorization-preconditioned iteration reaches it in a few
164 // extra Arnoldi steps, and the maxit cap bounds the cost.
165 //
166 // PETSc: passed as KSP atol when stated in the deck; PETSC_DEFAULT
167 // otherwise ( the historical behavior ).
168 real mAbsoluteTolerance = 1e-14 ;
169
170 // true once the deck ( or a programmatic caller ) stated an
171 // absolute tolerance. PETSc applies the value only then;
172 // STRUMPACK always applies mAbsoluteTolerance, because its
173 // library default is the overshoot-lottery defect above.
174 bool mHaveAbsoluteTolerance = false ;
175
176 bool mUseInitialGuess = false ;
177
178 // deck-stated Krylov iteration budget for ITERATIVE solvers
179 // ( "max iterations" in a linear section — distinct from the
180 // nonlinear key of the same name, which the controller parses ).
181 // 0 = not stated, keep the library default ( PETSc: 10000 ).
182 // Consumed by PETSc only; STRUMPACK's refinement cap is a fixed
183 // safety net against the refinement stall, deliberately not deck-tunable
184 uint mMaxNumIterations = 0 ;
185
186 public:
187
188 SolverParameters( const SolverType aType ) ;
189
190 SolverParameters( const input::Section * aInput );
191
192 SolverParameters( const SolverParameters & aOther );
193
196
197 ~SolverParameters() = default ;
198
199 void
201
202 void
203 set_preconditioner( const Preconditioner aPreconditioner );
204
205 void
206 set_krylov_method( const KrylovMethod aKrylovMethod );
207
208 void
209 set_reordering_method( const ReorderingMethod aReorderingMethod );
210
211 void
212 set_compression_method( const CompressionMethod aCompressionMethod );
213
214 void
215 set_relative_tolerance( const real aEpsilon );
216
217 void
218 set_absolute_tolerance( const real aEpsilon );
219
220 void
221 set_use_initial_guess( const bool aUse );
222
223 void
224 set_matrix_matching( const bool aUse );
225
227 type() const ;
228
231
233 preconditioner() const;
234
236 krylov_method() const;
237
239 reordering_method() const;
240
242 compression_method() const;
243
244 real
245 relative_tolerance() const ;
246
247 real
248 absolute_tolerance() const ;
249
252 bool
254
255 bool
257
259 uint
260 max_iterations() const ;
261
264 void
265 set_max_iterations( const int aMaxIterations );
266
269 void
270 set_compression_cutoff( const real aCutoff );
271
273 bool
275
276 real
277 compression_cutoff() const ;
278
281 void
282 set_memory_budget( const uint aMegaBytes );
283
285 bool
286 have_memory_budget() const ;
287
289 uint
290 memory_budget() const ;
291
292
293 bool
294 use_initial_guess() const ;
295
296 bool
297 use_matrix_matching() const ;
298
299 bool
300 use_metis_nodendp() const ;
301
302 void
303 synchronize();
304
305 private:
306
308 get_solver_type_from_input( const input::Section * aInput ) const ;
309
310 };
311}
312#endif //BELFEM_CL_SOLVERPARAMETERS_HPP
bool use_matrix_matching() const
Definition cl_SolverParameters.cpp:362
void set_preconditioner(const Preconditioner aPreconditioner)
Definition cl_SolverParameters.cpp:165
real compression_cutoff() const
Definition cl_SolverParameters.cpp:297
void set_memory_budget(const uint aMegaBytes)
Definition cl_SolverParameters.cpp:322
SolverParameters(SolverParameters &&aOther)=delete
uint max_iterations() const
deck-stated Krylov iteration budget; 0 = library default
Definition cl_SolverParameters.cpp:282
void set_reordering_method(const ReorderingMethod aReorderingMethod)
Definition cl_SolverParameters.cpp:177
real relative_tolerance() const
Definition cl_SolverParameters.cpp:258
void set_matrix_matching(const bool aUse)
Definition cl_SolverParameters.cpp:215
void set_compression_method(const CompressionMethod aCompressionMethod)
Definition cl_SolverParameters.cpp:183
bool have_compression_cutoff() const
true if the cutoff was stated rather than inherited
Definition cl_SolverParameters.cpp:316
void set_max_iterations(const int aMaxIterations)
Definition cl_SolverParameters.cpp:288
CompressionMethod compression_method() const
Definition cl_SolverParameters.cpp:252
DistributedMatrixType distributed_matrix_type() const
Definition cl_SolverParameters.cpp:228
void set_use_initial_guess(const bool aUse)
Definition cl_SolverParameters.cpp:209
real absolute_tolerance() const
Definition cl_SolverParameters.cpp:270
bool use_initial_guess() const
Definition cl_SolverParameters.cpp:356
SolverType type() const
Definition cl_SolverParameters.cpp:221
void set_compression_cutoff(const real aCutoff)
Definition cl_SolverParameters.cpp:303
void set_krylov_method(const KrylovMethod aKrylovMethod)
Definition cl_SolverParameters.cpp:171
KrylovMethod krylov_method() const
Definition cl_SolverParameters.cpp:240
void set_distributed_matrix_type(const DistributedMatrixType aType)
Definition cl_SolverParameters.cpp:159
bool have_absolute_tolerance() const
Definition cl_SolverParameters.cpp:276
bool have_memory_budget() const
true if the deck ( or a caller ) stated a budget
Definition cl_SolverParameters.cpp:344
Preconditioner preconditioner() const
Definition cl_SolverParameters.cpp:234
uint memory_budget() const
MB per process; 0 when not stated.
Definition cl_SolverParameters.cpp:350
SolverParameters(const SolverType aType)
Definition cl_SolverParameters.cpp:21
SolverParameters & operator=(SolverParameters &&aOther)=delete
void set_relative_tolerance(const real aEpsilon)
Definition cl_SolverParameters.cpp:189
bool use_metis_nodendp() const
Definition cl_SolverParameters.cpp:368
void synchronize()
Definition cl_SolverParameters.cpp:374
ReorderingMethod reordering_method() const
Definition cl_SolverParameters.cpp:246
bool have_relative_tolerance() const
Definition cl_SolverParameters.cpp:264
void set_absolute_tolerance(const real aEpsilon)
Definition cl_SolverParameters.cpp:199
One hierarchical section of a configuration file.
Definition cl_Input_Section.hpp:34
USER GUIDES:
Definition cl_Capacitor.cpp:16
DistributedMatrixType
Definition en_SolverEnums.hpp:66
@ CSR
Definition en_SolverEnums.hpp:68
unsigned int uint
Definition typedefs.hpp:30
int proc_t
Definition commtypes.hpp:29
const SolverType gDefaultSolver
Definition en_SolverEnums.hpp:209
SolverType
Definition en_SolverEnums.hpp:23
ReorderingMethod
Definition en_SolverEnums.hpp:116
@ AUTOMATIC
Definition en_SolverEnums.hpp:120
KrylovMethod
PETSC only.
Definition en_SolverEnums.hpp:101
@ AUTO
Definition en_SolverEnums.hpp:109
Preconditioner
PETSC only.
Definition en_SolverEnums.hpp:79
@ ASM
Definition en_SolverEnums.hpp:81
double real
Definition typedefs.hpp:36
CompressionMethod
Definition en_SolverEnums.hpp:129
@ AUTOMATIC
Definition en_SolverEnums.hpp:132