OGS
ConvergenceCriterionPerComponentDeltaX.cpp
Go to the documentation of this file.
1
12
13#include <limits>
14
15#include "BaseLib/ConfigTree.h"
16#include "BaseLib/Logging.h"
19
20namespace NumLib
21{
23 std::vector<double>&& absolute_tolerances,
24 std::vector<double>&& relative_tolerances,
25 const MathLib::VecNormType norm_type)
27 _abstols(std::move(absolute_tolerances)),
28 _reltols(std::move(relative_tolerances))
29{
30 if (_abstols.size() != _reltols.size())
31 {
33 "The number of absolute and relative tolerances given must be the "
34 "same.");
35 }
36
37 if (_abstols.empty())
38 {
39 OGS_FATAL("The given tolerances vector is empty.");
40 }
41}
42
44 const GlobalVector& minus_delta_x, GlobalVector const& x)
45{
46 if ((!_dof_table) || (!_mesh))
47 {
48 OGS_FATAL("D.o.f. table or mesh have not been set.");
49 }
50
51 for (unsigned global_component = 0; global_component < _abstols.size();
52 ++global_component)
53 {
54 // TODO short cut if tol <= 0.0
55 auto error_dx = norm(minus_delta_x, global_component, _norm_type,
56 *_dof_table, *_mesh);
57 auto norm_x =
58 norm(x, global_component, _norm_type, *_dof_table, *_mesh);
59
60 INFO(
61 "Convergence criterion, component {:d}: |dx|={:.4e}, |x|={:.4e}, "
62 "|dx|/|x|={:.4e}",
63 global_component, error_dx, norm_x,
64 (norm_x == 0. ? std::numeric_limits<double>::quiet_NaN()
65 : (error_dx / norm_x)));
66
67 bool const satisfied_abs = error_dx < _abstols[global_component];
68 bool const satisfied_rel = checkRelativeTolerance(
69 _reltols[global_component], error_dx, norm_x);
70
71 _satisfied = _satisfied && (satisfied_abs || satisfied_rel);
72 }
73}
74
76 const LocalToGlobalIndexMap& dof_table, MeshLib::Mesh const& mesh)
77{
78 _dof_table = &dof_table;
79 _mesh = &mesh;
80
82 static_cast<int>(_abstols.size()))
83 {
85 "The number of components in the DOF table and the number of "
86 "tolerances given do not match.");
87 }
88}
89
90std::unique_ptr<ConvergenceCriterionPerComponentDeltaX>
92{
94 config.checkConfigParameter("type", "PerComponentDeltaX");
95
96 auto abstols =
98 config.getConfigParameterOptional<std::vector<double>>("abstols");
99 auto reltols =
101 config.getConfigParameterOptional<std::vector<double>>("reltols");
102 auto const norm_type_str =
104 config.getConfigParameter<std::string>("norm_type");
105
106 if ((!abstols) && (!reltols))
107 {
108 OGS_FATAL(
109 "At least one of absolute or relative tolerance has to be "
110 "specified.");
111 }
112 if (!abstols)
113 {
114 abstols = std::vector<double>(reltols->size());
115 }
116 else if (!reltols)
117 {
118 reltols = std::vector<double>(abstols->size());
119 }
120
121 auto const norm_type = MathLib::convertStringToVecNormType(norm_type_str);
122
123 if (norm_type == MathLib::VecNormType::INVALID)
124 {
125 OGS_FATAL("Unknown vector norm type `{:s}'.", norm_type_str);
126 }
127
128 return std::make_unique<ConvergenceCriterionPerComponentDeltaX>(
129 std::move(*abstols), std::move(*reltols), norm_type);
130}
131
132} // namespace NumLib
#define OGS_FATAL(...)
Definition Error.h:26
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
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
Global vector based on Eigen vector.
Definition EigenVector.h:25
void checkDeltaX(const GlobalVector &minus_delta_x, GlobalVector const &x) override
void setDOFTable(const LocalToGlobalIndexMap &dof_table, MeshLib::Mesh const &mesh) override
Sets the d.o.f. table used to extract data for a specific component.
ConvergenceCriterionPerComponentDeltaX(std::vector< double > &&absolute_tolerances, std::vector< double > &&relative_tolerances, const MathLib::VecNormType norm_type)
const MathLib::VecNormType _norm_type
VecNormType convertStringToVecNormType(const std::string &str)
convert string to VecNormType
double norm(GlobalVector const &x, unsigned const global_component, MathLib::VecNormType norm_type, LocalToGlobalIndexMap const &dof_table, MeshLib::Mesh const &mesh)
bool checkRelativeTolerance(const double reltol, const double numerator, const double denominator)
std::unique_ptr< ConvergenceCriterionPerComponentDeltaX > createConvergenceCriterionPerComponentDeltaX(const BaseLib::ConfigTree &config)