34 "Check the convergence of a problem with respect to a user-supplied reference solution."
35 " Replaces ReferenceResidualProblem, currently still used in conjunction with it.");
43 _norm_type_enum(getParam<
MooseEnum>(
"normalization_type")),
44 _accept_mult(getParam<Real>(
"acceptable_multiplier")),
45 _accept_iters(getParam<unsigned
int>(
"acceptable_iterations")),
46 _nl_sys_num(_fe_problem.solverSysNum(getParam<SolverSystemName>(
"solver_sys"))),
47 _residual_vector(nullptr),
48 _reference_vector(nullptr),
51 _unscale_the_residual(getParam<bool>(
"unscale_the_residual")),
52 _reference_vector_tag_id(
Moose::INVALID_TAG_ID)
56 "Reference residual problem does not currently support multiple nonlinear systems "
57 "in a single Convergence object. Multiple Convergence objects can be used, one for "
58 "each nonlinear system, via the 'solver_sys' parameter.");
62 const auto residual_vector_tag_id =
78 "No `reference_vector` is provided, thus the Reference Residual convergence method will "
79 "revert to default tolerance checking. `reference_vector` will become a required parameter "
80 "on June 1st, 2027. If you are using `ReferenceResidualProblem`, either provide a "
81 "reference_vector or use a standard problem type (e.g., remove "
82 "Problem/type=ReferenceResidualProblem from your input file). If you are using "
83 "`ReferenceResidualConvergence`, either provide a reference_vector or utilize "
84 "`DefaultNonlinearConvergence` instead.");
107 mooseAssert(
false,
"This point should not be reached.");
110 paramError(
"reference_vector",
"If local norm is used, a reference_vector must be provided.");
128 auto & s = nonlinear_sys.system();
134 for (
const auto var_num : make_range(s.n_vars()))
136 const auto n_soln_vars = nonlinear_sys.nVariables();
138 const auto converge_on = getParam<std::vector<NonlinearVariableName>>(
"converge_on");
139 if (!converge_on.empty())
142 for (std::size_t i = 0; i < n_soln_vars; ++i)
143 for (
const auto & c : converge_on)
153 unsigned int num_variables_in_groups = 0;
161 " is not grouped with other variables.");
165 unsigned int n_groups = n_soln_vars - num_variables_in_groups +
_group_variables.size();
175 std::set<std::string> check_duplicate;
180 if (check_duplicate.size() != num_variables_in_groups)
181 paramError(
"group_variables",
"A variable cannot be included in multiple groups.");
185 for (
const auto i : make_range(n_soln_vars))
187 bool found_match =
false;
188 for (
const auto var_num : make_range(s.n_vars()))
197 mooseError(
"Could not find solution variable '",
204 unsigned int ungroup_index = 0;
222 "You added variable '",
224 "' to a group but excluded it from the convergence check. This is not "
245 unsigned int num_scalar_vars = 0;
246 unsigned int num_field_vars = 0;
250 for (
const auto var_num : make_range(s.n_vars()))
253 if (nonlinear_sys.isScalarVariable(
_soln_vars[var_num]))
260 if (num_scalar_vars > 0 && num_field_vars > 0)
262 "standard variables and scalar variables are grouped together in group ",
269 std::vector<NonlinearVariableName> names;
276 if (names.size() == 0)
277 mooseError(
"Internal error, something is wrong with variable grouping");
278 else if (names.size() == 1)
283 for (
const auto j : index_range(names))
286 if (j != names.size() - 1)
300 auto & s = nonlinear_sys.system();
303 if (nonlinear_sys.isScalarVariable(
_soln_vars[i]))
331 mooseAssert((*_residual_vector).size() == (*_reference_vector).size(),
332 "Sizes of nonlinear RHS and reference vector should be the same.");
333 mooseAssert((*_reference_vector).size(),
"Reference vector must be provided.");
336 ref->add(std::numeric_limits<Number>::min());
337 auto div = (*_residual_vector).clone();
368 std::ostringstream out;
374 out << std::setprecision(2) << std::scientific;
375 unsigned int var_space = 0;
385 out <<
" " << std::setw(var_space + 8) << std::right <<
_group_names[i] +
"-> res: "
391 out <<
" local res/ref: "
407 _console << out.str() << std::flush;
428 bool convergedRelative =
true;
437 return convergedRelative;
446 std::ostringstream & oss)
451 n_iter, fnorm, ref_norm, rel_tol, abs_tol, oss);
455 oss <<
"Converged normally";
462 oss <<
" Converged due a larger acceptable tolerance due to `acceptible_multiplier` after "
463 "`acceptible_iterations`.";
464 _console <<
" Converged due to ACCEPTABLE tolerances" << std::endl;
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
registerMooseObject("MooseApp", ReferenceResidualConvergence)
void ErrorVector unsigned int
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
virtual void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job.
Default nonlinear convergence criteria for FEProblem.
static InputParameters validParams()
FEProblemBase & _fe_problem
PetscReal _rel_tol
Nonlinear relative tolerance.
virtual bool checkResidualConvergence(const unsigned int n_iter, const Real fnorm, const Real ref_norm, const Real rel_tol, const Real abs_tol, std::ostringstream &oss)
Check the absolute and relative convergence of the nonlinear solution.
PetscReal _abs_tol
Nonlinear absolute tolerance.
virtual std::size_t numNonlinearSystems() const override
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
const InputParameters & parameters() const
Get the parameters of the object.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
const std::string & _name
The name of this class.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Nonlinear system to be solved.
virtual NumericVector< Number > & RHS()=0
Uses a reference residual to define relative convergence criteria.
virtual void nonlinearConvergenceSetup() override
Performs setup necessary for each call to checkConvergence.
bool checkConvergenceIndividVars(const Real fnorm, const Real abs_tol, const Real rel_tol, const Real initial_residual_before_preset_bcs)
Check the convergence by comparing the norm of each variable's residual separately against its refere...
ZeroReferenceType
Container for convergence treatment when the reference residual is zero.
ReferenceResidualConvergence(const InputParameters ¶meters)
virtual bool checkResidualConvergence(const unsigned int n_iter, const Real fnorm, const Real ref_norm, const Real rel_tol, const Real abs_tol, std::ostringstream &oss) override
Check the absolute and relative convergence of the nonlinear solution.
enum ReferenceResidualConvergence::ZeroReferenceType _zero_ref_type
std::vector< bool > _is_var_grouped
Vector of bools to signify if variable is in a group.
const unsigned int _accept_iters
const NumericVector< Number > * _reference_vector
The vector storing the reference residual values.
std::vector< unsigned int > _soln_vars
const bool _unscale_the_residual
Bool to unscale the residual before convergence checks and screen output.
const MooseEnum _norm_type_enum
Enum holding the normalization type.
virtual void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job.
void updateReferenceResidual()
Computes the reference residuals for each group.
const unsigned int _nl_sys_num
Nonlinear system to which this convergence object applies.
virtual NonlinearSystemBase & nonlinearSystem() override
Nonlinear system whose convergence state should be checked.
libMesh::FEMNormType _norm_type
Container for normalization type.
std::vector< NonlinearVariableName > _group_names
std::vector< bool > _converge_on_group
std::vector< unsigned int > _group_index
Group number index for each variable.
static InputParameters validParams()
std::vector< Real > _scaling_factors
Local storage for the scaling factors applied to each of the variables to apply to _ref_resid_vars.
std::vector< bool > _converge_on_var
Flag for each solution variable or group being in 'converge_on'.
std::vector< Real > _group_ref_resid
const NumericVector< Number > * _residual_vector
The optional vector storing the reference residual values.
TagID _reference_vector_tag_id
The reference vector tag id.
bool _local_norm
Flag to optionally perform normalization of residual by reference residual before or after L2 norm is...
std::vector< Real > _group_resid
std::vector< NonlinearVariableName > _soln_var_names
Interface class shared between ReferenceResidualProblem and ReferenceResidualConvergence.
static InputParameters validParams()
bool _use_group_variables
True if any variables are grouped.
std::vector< std::vector< NonlinearVariableName > > _group_variables
Name of variables that are grouped together to check convergence.
void paramWarning(const std::string ¶m, Args... args) const
virtual TagID getVectorTagID(const TagName &tag_name) const
Get a TagID from a TagName.
virtual NumericVector< Number > & getVector(const std::string &name)
Get a raw NumericVector by name.
virtual std::unique_ptr< NumericVector< T > > clone() const=0
bool globCompare(const std::string &candidate, const std::string &pattern, std::size_t c, std::size_t p)
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...