-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConvergenceCriterionDeltaX.cpp
77 lines (64 loc) · 2.64 KB
/
ConvergenceCriterionDeltaX.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/**
* \copyright
* Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "ConvergenceCriterionDeltaX.h"
#include <logog/include/logog.hpp>
#include "BaseLib/ConfigTree.h"
#include "MathLib/LinAlg/LinAlg.h"
namespace NumLib
{
ConvergenceCriterionDeltaX::ConvergenceCriterionDeltaX(
boost::optional<double>&& absolute_tolerance,
boost::optional<double>&& relative_tolerance,
MathLib::VecNormType norm_type)
: _abstol(std::move(absolute_tolerance)),
_reltol(std::move(relative_tolerance)),
_norm_type(norm_type)
{
if ((!_abstol) && (!_reltol))
OGS_FATAL(
"At least one of absolute or relative tolerance has to be "
"specified.");
}
void ConvergenceCriterionDeltaX::checkDeltaX(const GlobalVector& minus_delta_x,
GlobalVector const& x)
{
auto error_dx = MathLib::LinAlg::norm(minus_delta_x, _norm_type);
auto norm_x = MathLib::LinAlg::norm(x, _norm_type);
INFO("Convergence criterion: |dx|=%.4e, |x|=%.4e, |dx|/|x|=%.4e", error_dx,
norm_x, error_dx / norm_x);
bool satisfied_abs = false;
bool satisfied_rel = false;
if (_abstol) {
satisfied_abs = error_dx < *_abstol;
}
if (_reltol) {
satisfied_rel = checkRelativeTolerance(*_reltol, error_dx, norm_x);
}
_satisfied = _satisfied && (satisfied_abs || satisfied_rel);
}
std::unique_ptr<ConvergenceCriterionDeltaX> createConvergenceCriterionDeltaX(
const BaseLib::ConfigTree& config)
{
//! \ogs_file_param{process__convergence_criterion__type}
config.checkConfigParameter("type", "DeltaX");
//! \ogs_file_param{process__convergence_criterion__DeltaX__abstol}
auto abstol = config.getConfigParameterOptional<double>("abstol");
//! \ogs_file_param{process__convergence_criterion__DeltaX__reltol}
auto reltol = config.getConfigParameterOptional<double>("reltol");
auto const norm_type_str =
//! \ogs_file_param{process__convergence_criterion__DeltaX__norm_type}
config.getConfigParameter<std::string>("norm_type");
auto const norm_type = MathLib::convertStringToVecNormType(norm_type_str);
if (norm_type == MathLib::VecNormType::INVALID)
OGS_FATAL("Unknown vector norm type `%s'.", norm_type_str.c_str());
return std::unique_ptr<ConvergenceCriterionDeltaX>(
new ConvergenceCriterionDeltaX(std::move(abstol), std::move(reltol),
norm_type));
}
} // NumLib