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"
18#include "MeshLib/MeshSubset.h"
21
22namespace NumLib
23{
25 std::vector<double>&& absolute_tolerances,
26 std::vector<double>&& relative_tolerances,
27 std::vector<double>&& damping_alpha,
28 bool damping_alpha_switch,
29 const MathLib::VecNormType norm_type)
31 _abstols(std::move(absolute_tolerances)),
32 _reltols(std::move(relative_tolerances)),
33 _damping_alpha(std::move(damping_alpha)),
34 _damping_alpha_switch(damping_alpha_switch)
35{
36 if (_abstols.size() != _reltols.size())
37 {
38 OGS_FATAL(
39 "The number of absolute and relative tolerances given must be the "
40 "same.");
41 }
42
43 if (_abstols.empty())
44 {
45 OGS_FATAL("The given tolerances vector is empty.");
46 }
47}
48
50 const GlobalVector& minus_delta_x, GlobalVector const& x)
51{
52 if (!_dof_table)
53 {
54 OGS_FATAL("D.o.f. table has not been set.");
55 }
56
57 for (unsigned global_component = 0; global_component < _abstols.size();
58 ++global_component)
59 {
60 // TODO short cut if tol <= 0.0
61 auto error_dx =
62 norm(minus_delta_x, global_component, _norm_type, *_dof_table);
63 auto norm_x = norm(x, global_component, _norm_type, *_dof_table);
64
65 INFO(
66 "Convergence criterion, component {:d}: |dx|={:.4e}, |x|={:.4e}, "
67 "|dx|/|x|={:.4e}",
68 global_component, error_dx, norm_x,
69 (norm_x == 0. ? std::numeric_limits<double>::quiet_NaN()
70 : (error_dx / norm_x)));
71
72 bool const satisfied_abs = error_dx < _abstols[global_component];
73 bool const satisfied_rel = checkRelativeTolerance(
74 _reltols[global_component], error_dx, norm_x);
75
76 _satisfied = _satisfied && (satisfied_abs || satisfied_rel);
77 }
78}
79
81 const GlobalVector& minus_delta_x, GlobalVector const& x,
82 double damping_orig)
83{
84 if (!_dof_table)
85 {
86 OGS_FATAL("D.o.f. table has not been set.");
87 }
88
90 double damping_final = 1;
91 for (unsigned global_component = 0;
92 global_component < _damping_alpha.size();
93 ++global_component)
94 {
95 auto const& ms = _dof_table->getMeshSubset(global_component);
96 assert(ms.getMeshID() == _mesh->getID());
97 DBUG("Non-negative damping for component: {:d} alpha: {:g}",
98 global_component, _damping_alpha[global_component]);
99 for (auto const& l :
101 {
102 auto index = _dof_table->getGlobalIndex(l, global_component);
103 damping_final = std::min(
104 damping_final,
105 damping_orig / std::max(1.0, (minus_delta_x.get(index) *
106 _damping_alpha[global_component] /
107 x.get(index))));
108 }
109 }
110 DBUG("Final damping value due to non-negative damping: {:g}",
111 damping_final);
112 return damping_final;
113}
114
116 const LocalToGlobalIndexMap& dof_table, MeshLib::Mesh const& mesh)
117{
118 _dof_table = &dof_table;
119 _mesh = &mesh;
120
122 static_cast<int>(_abstols.size()))
123 {
124 OGS_FATAL(
125 "The number of components in the DOF table and the number of "
126 "tolerances given do not match.");
127 }
128}
129
130std::unique_ptr<ConvergenceCriterionPerComponentDeltaX>
132{
134 config.checkConfigParameter("type", "PerComponentDeltaX");
135
136 auto abstols =
138 config.getConfigParameterOptional<std::vector<double>>("abstols");
139 auto reltols =
141 config.getConfigParameterOptional<std::vector<double>>("reltols");
142 auto damping_alpha =
144 config.getConfigParameterOptional<std::vector<double>>("damping_alpha");
145 auto const norm_type_str =
147 config.getConfigParameter<std::string>("norm_type");
148
149 bool damping_alpha_switch = true;
150 if ((!abstols) && (!reltols))
151 {
152 OGS_FATAL(
153 "At least one of absolute or relative tolerance has to be "
154 "specified.");
155 }
156 if (!abstols)
157 {
158 abstols = std::vector<double>(reltols->size());
159 }
160 else if (!reltols)
161 {
162 reltols = std::vector<double>(abstols->size());
163 }
164 if (!damping_alpha)
165 {
166 damping_alpha = std::vector<double>(abstols->size(), 0.0);
167 damping_alpha_switch = false;
168 }
169
170 auto const norm_type = MathLib::convertStringToVecNormType(norm_type_str);
171
172 if (norm_type == MathLib::VecNormType::INVALID)
173 {
174 OGS_FATAL("Unknown vector norm type `{:s}'.", norm_type_str);
175 }
176
177 return std::make_unique<ConvergenceCriterionPerComponentDeltaX>(
178 std::move(*abstols), std::move(*reltols), std::move(*damping_alpha),
179 damping_alpha_switch, norm_type);
180}
181
182} // namespace NumLib
#define OGS_FATAL(...)
Definition Error.h:26
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
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
double get(IndexType rowId) const
get entry
Definition EigenVector.h:58
std::size_t getID() const
Get id of the mesh.
Definition Mesh.h:123
ConvergenceCriterionPerComponentDeltaX(std::vector< double > &&absolute_tolerances, std::vector< double > &&relative_tolerances, std::vector< double > &&damping_alpha, bool daming_alpha_switch, const MathLib::VecNormType norm_type)
double getDampingFactor(const GlobalVector &minus_delta_x, GlobalVector const &x, double damping_orig) override
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.
const MathLib::VecNormType _norm_type
GlobalIndexType getGlobalIndex(MeshLib::Location const &l, int const variable_id, int const component_id) const
MeshLib::MeshSubset const & getMeshSubset(int const variable_id, int const component_id) const
void setLocalAccessibleVector(PETScVector const &x)
Definition LinAlg.cpp:27
VecNormType convertStringToVecNormType(const std::string &str)
convert string to VecNormType
auto meshLocations(Mesh const &mesh, MeshItemType const item_type)
Definition Mesh.h:238
bool checkRelativeTolerance(const double reltol, const double numerator, const double denominator)
std::unique_ptr< ConvergenceCriterionPerComponentDeltaX > createConvergenceCriterionPerComponentDeltaX(const BaseLib::ConfigTree &config)
double norm(GlobalVector const &x, unsigned const global_component, MathLib::VecNormType norm_type, LocalToGlobalIndexMap const &dof_table)