OGS
ConvergenceCriterionResidual.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
7#include "BaseLib/Logging.h"
9
10namespace NumLib
11{
13 std::optional<double>&& absolute_tolerance,
14 std::optional<double>&& relative_tolerance,
15 const MathLib::VecNormType norm_type)
16 : ConvergenceCriterion(norm_type),
17 _abstol(std::move(absolute_tolerance)),
18 _reltol(std::move(relative_tolerance))
19{
20 if ((!_abstol) && (!_reltol))
21 {
23 "At least one of absolute or relative tolerance has to be "
24 "specified.");
25 }
26}
27
29 const GlobalVector& minus_delta_x, GlobalVector const& x)
30{
31 auto error_dx = MathLib::LinAlg::norm(minus_delta_x, _norm_type);
32 auto norm_x = MathLib::LinAlg::norm(x, _norm_type);
33
34 INFO("Convergence criterion: |dx|={:.4e}, |x|={:.4e}, |dx|/|x|={:.4e}",
35 error_dx, norm_x,
36 (norm_x == 0. ? std::numeric_limits<double>::quiet_NaN()
37 : (error_dx / norm_x)));
38}
39
41{
42 auto norm_res = MathLib::LinAlg::norm(residual, _norm_type);
43
45 {
46 INFO("Convergence criterion: |r0|={:.4e}", norm_res);
47 _residual_norm_0 = norm_res;
48 }
49 else
50 {
52 (_residual_norm_0 < std::numeric_limits<double>::epsilon())
53 ? norm_res
55 if (_residual_norm_0 < std::numeric_limits<double>::epsilon())
56 {
57 INFO("Convergence criterion: |r|={:.4e} |r0|={:.4e}", norm_res,
59 }
60 else
61 {
62 INFO(
63 "Convergence criterion: |r|={:.4e} |r0|={:.4e} |r|/|r0|={:.4e}",
64 norm_res, _residual_norm_0,
65 (_residual_norm_0 == 0.
66 ? std::numeric_limits<double>::quiet_NaN()
67 : (norm_res / _residual_norm_0)));
68 }
69 }
70
71 bool satisfied_abs = false;
72 bool satisfied_rel = false;
73
74 if (_abstol)
75 {
76 satisfied_abs = norm_res < *_abstol;
77 }
79 {
80 satisfied_rel =
82 }
83
84 _satisfied = _satisfied && (satisfied_abs || satisfied_rel);
85}
86
87std::unique_ptr<ConvergenceCriterionResidual>
89{
91 config.checkConfigParameter("type", "Residual");
92
94 auto abstol = config.getConfigParameterOptional<double>("abstol");
96 auto reltol = config.getConfigParameterOptional<double>("reltol");
97 auto const norm_type_str =
99 config.getConfigParameter<std::string>("norm_type");
100 auto const norm_type = MathLib::convertStringToVecNormType(norm_type_str);
101
102 if (norm_type == MathLib::VecNormType::INVALID)
103 {
104 OGS_FATAL("Unknown vector norm type `{:s}'.", norm_type_str);
105 }
106
107 return std::make_unique<ConvergenceCriterionResidual>(
108 std::move(abstol), std::move(reltol), norm_type);
109}
110
111} // namespace NumLib
#define OGS_FATAL(...)
Definition Error.h:19
MathLib::EigenVector GlobalVector
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
std::optional< T > getConfigParameterOptional(std::string const &param) const
T getConfigParameter(std::string const &param) const
void checkConfigParameter(std::string const &param, std::string_view const value) const
void checkResidual(const GlobalVector &residual) override
Check if the residual satisfies the convergence criterion.
ConvergenceCriterionResidual(std::optional< double > &&absolute_tolerance, std::optional< double > &&relative_tolerance, const MathLib::VecNormType norm_type)
void checkDeltaX(const GlobalVector &minus_delta_x, GlobalVector const &x) override
ConvergenceCriterion(const MathLib::VecNormType norm_type)
const MathLib::VecNormType _norm_type
double norm(MatrixOrVector const &x, MathLib::VecNormType type)
Definition LinAlg.h:89
VecNormType convertStringToVecNormType(const std::string &str)
convert string to VecNormType
bool checkRelativeTolerance(const double reltol, const double numerator, const double denominator)
std::unique_ptr< ConvergenceCriterionResidual > createConvergenceCriterionResidual(const BaseLib::ConfigTree &config)