OGS
CreateNonlinearSolver.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
6#include <spdlog/fmt/ranges.h>
7
8#include <boost/algorithm/string.hpp>
9#include <memory>
10
12#include "BaseLib/ConfigTree.h"
13#include "BaseLib/Error.h"
17
18namespace NumLib
19{
20std::pair<std::unique_ptr<NonlinearSolverBase>, NonlinearSolverTag>
22 BaseLib::ConfigTree const& config)
23{
25 auto const type = config.getConfigParameter<std::string>("type");
26
28 auto const max_iter = config.getConfigParameter<int>("max_iter");
29
30 if (type == "Picard")
31 {
32 auto const damping =
34 config.getConfigParameter<double>("damping", 1.0);
35
36 auto const anderson_config =
38 config.getConfigSubtreeOptional("anderson");
39 int anderson_depth = 0;
40 if (anderson_config)
41 {
42 anderson_depth =
44 anderson_config->getConfigParameter<int>("depth");
45
46 if (anderson_depth < 0)
47 {
49 "Anderson acceleration depth must be non-negative, got "
50 "{:d}.",
51 anderson_depth);
52 }
53 if (anderson_depth < AndersonAcceleration::min_mixing_depth)
54 {
55 WARN(
56 "Anderson acceleration with a depth of {:d} has no effect: "
57 "mixing fewer than {:d} stored steps reproduces the plain "
58 "Picard update. Use a depth >= {:d} to accelerate, or drop "
59 "the <anderson> subtree to disable the acceleration "
60 "explicitly.",
63 }
64 }
65 if (damping <= 0.0 || damping > 1.0)
66 {
68 "The damping factor for the Picard method must be in (0, 1], "
69 "got {:g}.",
70 damping);
71 }
72
73 auto const tag = NonlinearSolverTag::Picard;
74 using ConcreteNLS = NonlinearSolver<tag>;
75 return std::make_pair(
76 std::make_unique<ConcreteNLS>(linear_solver, max_iter,
77 anderson_depth, damping),
78 tag);
79 }
80 if (type == "Newton")
81 {
82 auto const recompute_jacobian =
84 config.getConfigParameter<int>("recompute_jacobian", 1);
85
87 auto const damping = config.getConfigParameter<double>("damping", 1.0);
88 if (damping <= 0)
89 {
91 "The damping factor for the Newton method must be positive, "
92 "got "
93 "{:g}.",
94 damping);
95 }
96 auto const damping_reduction =
98 config.getConfigParameterOptional<double>("damping_reduction");
99 std::unique_ptr<NewtonStepStrategy> standard_newton;
100 if (damping_reduction)
101 {
102 standard_newton = std::make_unique<DampingReductionStrategy>(
103 damping, *damping_reduction);
104 }
105 else
106 {
107 standard_newton = std::make_unique<FixedDampingStrategy>(damping);
108 }
109 auto const tag = NonlinearSolverTag::Newton;
110 using ConcreteNLS = NonlinearSolver<tag>;
111 auto solver = std::make_unique<ConcreteNLS>(linear_solver, max_iter,
112 std::move(standard_newton),
113 recompute_jacobian);
114 auto const tikhonov_config =
116 config.getConfigSubtreeOptional("tikhonov");
117 if (tikhonov_config)
118 {
119 auto const tikhonov_lambda =
121 tikhonov_config->getConfigParameter<double>("lambda");
122 auto const tikhonov_starting_iteration =
124 tikhonov_config->getConfigParameter<int>("starting_iteration",
125 0);
126 solver->setTikhonovLambda(tikhonov_lambda,
127 tikhonov_starting_iteration);
128 DBUG("Newton solver: Tikhonov regularization lambda = {:g}",
129 tikhonov_lambda);
130 }
131 return std::make_pair(std::move(solver), tag);
132 }
133#ifdef USE_PETSC
134 if (boost::iequals(type, "PETScSNES"))
135 {
136 auto prefix =
138 config.getConfigParameter<std::string>("prefix", "");
139 auto const tag = NonlinearSolverTag::Newton;
140 using ConcreteNLS = PETScNonlinearSolver;
141 return std::make_pair(std::make_unique<ConcreteNLS>(
142 linear_solver, max_iter, std::move(prefix)),
143 tag);
144 }
145 static constexpr std::array valid_types = {"PETScSNES", "Newton", "Picard"};
146#else
147 static constexpr std::array valid_types = {"Newton", "Picard"};
148#endif
149
150 OGS_FATAL("Invalid non-linear solver type '{}'. Supported values: {}.",
151 type, fmt::join(valid_types, ", "));
152}
153
154} // namespace NumLib
#define OGS_FATAL(...)
Definition Error.h:10
MathLib::EigenLisLinearSolver GlobalLinearSolver
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
std::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
std::optional< T > getConfigParameterOptional(std::string const &param) const
T getConfigParameter(std::string const &param) const
static constexpr int min_mixing_depth
NonlinearSolverTag
Tag used to specify which nonlinear solver will be used.
Definition Types.h:13
std::pair< std::unique_ptr< NonlinearSolverBase >, NonlinearSolverTag > createNonlinearSolver(GlobalLinearSolver &linear_solver, BaseLib::ConfigTree const &config)