version 0.4.1
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{
27 double tol{1e-8};
28 int maxIter{20};
29};
30
40template <typename NLO, typename LS = utils::SolverDefault, typename UF = utils::UpdateDefault>
41class NewtonRaphson : public IObservable<NonLinearSolverMessages>
42{
43public:
45 static constexpr bool isLinearSolver =
47
49 using ValueType = typename NLO::template ParameterValue<0>;
50
51 using UpdateFunction = UF;
52 using NonLinearOperator = NLO;
53
60 explicit NewtonRaphson(const NonLinearOperator& nonLinearOperator, LS&& linearSolver = {},
61 UpdateFunction updateFunction = {})
62 : nonLinearOperator_{nonLinearOperator},
63 linearSolver_{std::move(linearSolver)},
64 updateFunction_{updateFunction} {
65 if constexpr (std::is_same_v<typename NonLinearOperator::ValueType, Eigen::VectorXd>)
66 correction_.setZero(this->nonLinearOperator().value().size());
67 }
68
73 void setup(const NewtonRaphsonSettings& settings) { settings_ = settings; }
74
75#ifndef DOXYGEN
76 struct NoPredictor
77 {
78 };
79#endif
85 template <typename SolutionType = NoPredictor>
86 requires std::is_same_v<SolutionType, NoPredictor> ||
87 std::is_convertible_v<SolutionType, std::remove_cvref_t<typename NonLinearOperator::ValueType>>
88 [[nodiscard(
89 "The solve method returns information of the solution process. You should store this information and check if "
90 "it was successful")]] Ikarus::NonLinearSolverInformation
91 solve(const SolutionType& dxPredictor = NoPredictor{}) {
93 Ikarus::NonLinearSolverInformation solverInformation;
94 solverInformation.success = true;
95 auto& x = nonLinearOperator().firstParameter();
96 if constexpr (not std::is_same_v<SolutionType, NoPredictor>)
97 updateFunction_(x, dxPredictor);
98 nonLinearOperator().updateAll();
99 const auto& rx = nonLinearOperator().value();
100 const auto& Ax = nonLinearOperator().derivative();
101 auto rNorm = norm(rx);
102 decltype(rNorm) dNorm;
103 int iter{0};
104 if constexpr (isLinearSolver)
105 linearSolver_.analyzePattern(Ax);
106 while (rNorm > settings_.tol && iter < settings_.maxIter) {
108 if constexpr (isLinearSolver) {
109 linearSolver_.factorize(Ax);
110 linearSolver_.solve(correction_, -rx);
111 dNorm = correction_.norm();
112 updateFunction_(x, correction_);
113 } else {
114 correction_ = -linearSolver_(rx, Ax);
115 dNorm = norm(correction_);
116 updateFunction_(x, correction_);
117 }
118 this->notify(NonLinearSolverMessages::CORRECTIONNORM_UPDATED, static_cast<double>(dNorm));
120 nonLinearOperator().updateAll();
121 rNorm = norm(rx);
122 this->notify(NonLinearSolverMessages::RESIDUALNORM_UPDATED, static_cast<double>(rNorm));
124 ++iter;
125 }
126 if (iter == settings_.maxIter)
127 solverInformation.success = false;
128 solverInformation.iterations = iter;
129 solverInformation.residualNorm = static_cast<double>(rNorm);
130 solverInformation.correctionNorm = static_cast<double>(dNorm);
131 if (solverInformation.success)
133 return solverInformation;
134 }
135
140 auto& nonLinearOperator() { return nonLinearOperator_; }
141
142private:
143 NonLinearOperator nonLinearOperator_;
144 typename NonLinearOperator::ValueType correction_;
145 LS linearSolver_;
146 UpdateFunction updateFunction_;
147 NewtonRaphsonSettings settings_;
148};
149
160template <typename NLO, typename LS = utils::SolverDefault, typename UF = utils::UpdateDefault>
161auto makeNewtonRaphson(const NLO& nonLinearOperator, LS&& linearSolver = {}, UF&& updateFunction = {}) {
162 return std::make_shared<NewtonRaphson<NLO, LS, UF>>(nonLinearOperator, std::forward<LS>(linearSolver),
163 std::move(updateFunction));
164}
165
166} // namespace Ikarus
Several concepts.
Collection of fallback default functions.
Helper for the autodiff library.
Implementation of the Newton-Raphson method for solving nonlinear equations.
Type-erased linear solver with templated scalar type.
Enums for observer messages.
Implementation of the observer design pattern.
auto norm(const Eigen::MatrixBase< Derived > &v)
Adding free norm function to Eigen types.
Definition: linearalgebrahelper.hh:259
Definition: simpleassemblers.hh:22
auto makeNewtonRaphson(const NLO &nonLinearOperator, LS &&linearSolver={}, UF &&updateFunction={})
Function to create a NewtonRaphson solver instance.
Definition: newtonraphson.hh:161
Settings for the Newton-Raphson solver.
Definition: newtonraphson.hh:26
double tol
Definition: newtonraphson.hh:27
int maxIter
Definition: newtonraphson.hh:28
Implementation of the Newton-Raphson method for solving nonlinear equations.
Definition: newtonraphson.hh:42
Ikarus::NonLinearSolverInformation solve(const SolutionType &dxPredictor=NoPredictor{})
Solve the nonlinear system.
Definition: newtonraphson.hh:91
NewtonRaphson(const NonLinearOperator &nonLinearOperator, LS &&linearSolver={}, UpdateFunction updateFunction={})
Constructor for NewtonRaphson.
Definition: newtonraphson.hh:60
UF UpdateFunction
Type representing the update function.
Definition: newtonraphson.hh:51
NLO NonLinearOperator
Type of the non-linear operator.
Definition: newtonraphson.hh:52
auto & nonLinearOperator()
Access the nonlinear operator.
Definition: newtonraphson.hh:140
static constexpr bool isLinearSolver
< Compile-time boolean indicating if the linear solver satisfies the non-linear solver concept
Definition: newtonraphson.hh:45
void setup(const NewtonRaphsonSettings &settings)
Set up the solver with the given settings.
Definition: newtonraphson.hh:73
typename NLO::template ParameterValue< 0 > ValueType
Definition: newtonraphson.hh:49
Information about the result of a non-linear solver.
Definition: solverinfos.hh:19
double correctionNorm
Definition: solverinfos.hh:28
int iterations
Definition: solverinfos.hh:29
double residualNorm
Definition: solverinfos.hh:27
bool success
Definition: solverinfos.hh:26
Represents a NonLinearOperator class for handling nonlinear operators.
Definition: nonlinearoperator.hh:156
Generic observable interface for the Observer design pattern. See for a description of the design pa...
Definition: observer.hh:129
void notify(NonLinearSolverMessages message)
Notify observers about a specific message type.
Concept to check if a linear solver implements all the needed functions for given vector and matrix t...
Definition: concepts.hh:210