version 0.4
newtonraphson.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2024 The Ikarus Developers mueller@ibb.uni-stuttgart.de
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
9#pragma once
10
18
19namespace Ikarus {
20
26 double tol{1e-8};
27 int maxIter{20};
28 };
29
39 template <typename NonLinearOperatorImpl, typename LinearSolver = utils::SolverDefault,
40 typename UpdateFunctionTypeImpl = utils::UpdateDefault>
41 class NewtonRaphson : public IObservable<NonLinearSolverMessages> {
42 public:
44 static constexpr bool isLinearSolver
45 = Ikarus::Concepts::LinearSolverCheck<LinearSolver, typename NonLinearOperatorImpl::DerivativeType,
46 typename NonLinearOperatorImpl::ValueType>;
47
49 using ValueType = typename NonLinearOperatorImpl::template ParameterValue<0>;
50
51 using UpdateFunctionType = UpdateFunctionTypeImpl;
52 using NonLinearOperator = NonLinearOperatorImpl;
53
60 explicit NewtonRaphson(const NonLinearOperatorImpl& p_nonLinearOperator, LinearSolver&& p_linearSolver = {},
61 UpdateFunctionTypeImpl p_updateFunction = {})
62 : nonLinearOperator_{p_nonLinearOperator},
63 linearSolver{std::move(p_linearSolver)},
64 updateFunction{p_updateFunction} {
65 if constexpr (std::is_same_v<typename NonLinearOperatorImpl::ValueType, Eigen::VectorXd>)
66 correction.setZero(nonLinearOperator().value().size());
67 }
68
73 void setup(const NewtonRaphsonSettings& p_settings) { settings = p_settings; }
74
75#ifndef DOXYGEN
76 struct NoPredictor {};
77#endif
83 template <typename SolutionType = NoPredictor>
84 requires std::is_same_v<SolutionType, NoPredictor> || std::is_convertible_v<
85 SolutionType, std::remove_cvref_t<typename NonLinearOperatorImpl::ValueType>>
86 [[nodiscard(
87 "The solve method returns information of the solution process. You should store this information and check if "
88 "it was successful")]] Ikarus::NonLinearSolverInformation
89 solve(const SolutionType& dx_predictor = NoPredictor{}) {
91 Ikarus::NonLinearSolverInformation solverInformation;
92 solverInformation.success = true;
93 auto& x = nonLinearOperator().firstParameter();
94 if constexpr (not std::is_same_v<SolutionType, NoPredictor>) updateFunction(x, dx_predictor);
95 nonLinearOperator().updateAll();
96 const auto& rx = nonLinearOperator().value();
97 const auto& Ax = nonLinearOperator().derivative();
98 auto rNorm = norm(rx);
99 decltype(rNorm) dNorm;
100 int iter{0};
101 if constexpr (isLinearSolver) linearSolver.analyzePattern(Ax);
102 while (rNorm > settings.tol && iter < settings.maxIter) {
104 if constexpr (isLinearSolver) {
105 linearSolver.factorize(Ax);
106 linearSolver.solve(correction, -rx);
107 dNorm = correction.norm();
108 updateFunction(x, correction);
109 } else {
110 correction = -linearSolver(rx, Ax);
111 dNorm = norm(correction);
112 updateFunction(x, correction);
113 }
114 this->notify(NonLinearSolverMessages::CORRECTIONNORM_UPDATED, static_cast<double>(dNorm));
116 nonLinearOperator().updateAll();
117 rNorm = norm(rx);
118 this->notify(NonLinearSolverMessages::RESIDUALNORM_UPDATED, static_cast<double>(rNorm));
120 ++iter;
121 }
122 if (iter == settings.maxIter) solverInformation.success = false;
123 solverInformation.iterations = iter;
124 solverInformation.residualNorm = static_cast<double>(rNorm);
125 solverInformation.correctionNorm = static_cast<double>(dNorm);
126 if (solverInformation.success) this->notify(NonLinearSolverMessages::FINISHED_SUCESSFULLY, iter);
127 return solverInformation;
128 }
129
134 auto& nonLinearOperator() { return nonLinearOperator_; }
135
136 private:
137 NonLinearOperatorImpl nonLinearOperator_;
138 typename NonLinearOperatorImpl::ValueType correction;
139 LinearSolver linearSolver;
140 UpdateFunctionType updateFunction;
141 NewtonRaphsonSettings settings;
142 };
143
154 template <typename NonLinearOperatorImpl, typename LinearSolver = utils::SolverDefault,
155 typename UpdateFunctionType = utils::UpdateDefault>
156 auto makeNewtonRaphson(const NonLinearOperatorImpl& p_nonLinearOperator, LinearSolver&& p_linearSolver = {},
157 UpdateFunctionType&& p_updateFunction = {}) {
158 return std::make_shared<NewtonRaphson<NonLinearOperatorImpl, LinearSolver, UpdateFunctionType>>(
159 p_nonLinearOperator, std::forward<LinearSolver>(p_linearSolver), std::move(p_updateFunction));
160 }
161
162} // namespace Ikarus
Several concepts.
Collection of fallback default functions.
Helper for the autodiff library.
Enums for observer messages.
Implementation of the observer design pattern.
Implementation of the Newton-Raphson method for solving nonlinear equations.
Type-erased linear solver with templated scalar type.
auto norm(const Eigen::MatrixBase< Derived > &v)
Adding free norm function to Eigen types.
Definition: linearalgebrahelper.hh:258
Definition: simpleassemblers.hh:21
auto makeNewtonRaphson(const NonLinearOperatorImpl &p_nonLinearOperator, LinearSolver &&p_linearSolver={}, UpdateFunctionType &&p_updateFunction={})
Function to create a NewtonRaphson solver instance.
Definition: newtonraphson.hh:156
LinearSolverTemplate< double > LinearSolver
Definition: linearsolver.hh:234
void analyzePattern(const MatrixType &A)
Analyze the pattern of the matrix.
Definition: linearsolver.hh:195
void solve(Eigen::VectorX< ScalarType > &x, const Eigen::VectorX< ScalarType > &b)
Solve the linear system for a vector.
Definition: linearsolver.hh:211
void factorize(const MatrixType &A)
Factorize the matrix.
Definition: linearsolver.hh:204
Settings for the Newton-Raphson solver.
Definition: newtonraphson.hh:25
double tol
Definition: newtonraphson.hh:26
int maxIter
Definition: newtonraphson.hh:27
Implementation of the Newton-Raphson method for solving nonlinear equations.
Definition: newtonraphson.hh:41
typename NonLinearOperatorImpl::template ParameterValue< 0 > ValueType
Definition: newtonraphson.hh:49
void setup(const NewtonRaphsonSettings &p_settings)
Set up the solver with the given settings.
Definition: newtonraphson.hh:73
auto & nonLinearOperator()
Access the nonlinear operator.
Definition: newtonraphson.hh:134
NonLinearOperatorImpl NonLinearOperator
Type of the non-linear operator.
Definition: newtonraphson.hh:52
Ikarus::NonLinearSolverInformation solve(const SolutionType &dx_predictor=NoPredictor{})
Solve the nonlinear system.
Definition: newtonraphson.hh:89
static constexpr bool isLinearSolver
< Compile-time boolean indicating if the linear solver satisfies the non-linear solver concept
Definition: newtonraphson.hh:45
UpdateFunctionTypeImpl UpdateFunctionType
Type representing the update function.
Definition: newtonraphson.hh:51
NewtonRaphson(const NonLinearOperatorImpl &p_nonLinearOperator, LinearSolver &&p_linearSolver={}, UpdateFunctionTypeImpl p_updateFunction={})
Constructor for NewtonRaphson.
Definition: newtonraphson.hh:60
Information about the result of a non-linear solver.
Definition: solverinfos.hh:18
double correctionNorm
Definition: solverinfos.hh:27
int iterations
Definition: solverinfos.hh:28
double residualNorm
Definition: solverinfos.hh:26
bool success
Definition: solverinfos.hh:25
Generic observable interface for the Observer design pattern. See for a description of the design pa...
Definition: observer.hh:125
void notify(NonLinearSolverMessages message)
Notify observers about a specific message type.
Definition: observer.hh:254
Concept to check if a linear solver implements all the needed functions for given vector and matrix t...
Definition: concepts.hh:218