3#ifndef DUNE_PDELAB_SOLVER_NEWTONLINESEARCH_HH
4#define DUNE_PDELAB_SOLVER_NEWTONLINESEARCH_HH
11 template <
typename Domain>
27 template <
typename Newton>
31 using Domain =
typename Newton::Domain;
32 using Real =
typename Newton::Real;
39 solution.axpy(-1.0, correction);
40 _newton.updateDefect(solution);
56 template <
typename Newton>
60 using Domain =
typename Newton::Domain;
61 using Real =
typename Newton::Real;
68 if ((_newton.result().defect < _newton.getAbsoluteLimit())){
69 solution.axpy(-1.0, correction);
70 _newton.updateDefect(solution);
74 auto verbosity = _newton.getVerbosityLevel();
77 std::cout <<
" Performing line search..." << std::endl;
79 Real bestLambda = 0.0;
80 Real bestDefect = _newton.result().defect;
81 Real previousDefect = _newton.result().defect;
82 bool converged =
false;
84 if (not _previousSolution)
85 _previousSolution = std::make_shared<Domain>(solution);
87 *_previousSolution = solution;
89 for (
unsigned int iteration = 0; iteration < _lineSearchMaxIterations; ++iteration){
91 std::cout <<
" trying line search damping factor: "
92 << std::setw(12) << std::setprecision(4) << std::scientific
96 solution.axpy(-lambda, correction);
97 _newton.updateDefect(solution);
99 if (not std::isfinite(_newton.result().defect))
100 std::cout <<
" NaNs detected" << std::endl;
103 if (_newton.result().defect <= (1.0 - lambda/4) * previousDefect){
105 std::cout <<
" line search converged" << std::endl;
110 if (_newton.result().defect < bestDefect){
111 bestDefect = _newton.result().defect;
115 lambda *= _lineSearchDampingFactor;
116 solution = *_previousSolution;
121 std::cout <<
" max line search iterations exceeded" << std::endl;
123 if (not _acceptBest){
124 solution = *_previousSolution;
125 _newton.updateDefect(solution);
126 DUNE_THROW(NewtonLineSearchError,
127 "NewtonLineSearch::line_search(): line search failed, "
128 "max iteration count reached, "
129 "defect did not improve enough");
132 if (bestLambda == 0.0){
133 solution = *_previousSolution;
134 _newton.updateDefect(solution);
135 DUNE_THROW(NewtonLineSearchError,
136 "NewtonLineSearch::line_search(): line search failed, "
137 "max iteration count reached, "
138 "defect did not improve in any of the iterations");
140 if (bestLambda != lambda){
141 solution = *_previousSolution;
142 solution.axpy(-bestLambda, correction);
143 _newton.updateDefect(solution);
151 std::cout <<
" line search damping factor: "
152 << std::setw(12) << std::setprecision(4) << std::scientific
153 << lambda << std::endl;
171 _lineSearchMaxIterations = parameterTree.get<
unsigned int>(
"line_search_max_iterations",
172 _lineSearchMaxIterations);
173 _lineSearchDampingFactor = parameterTree.get<
Real>(
"line_search_damping_factor",
174 _lineSearchDampingFactor);
175 _acceptBest = parameterTree.get<
bool>(
"line_search_accept_best",
181 std::shared_ptr<Domain> _previousSolution;
184 unsigned int _lineSearchMaxIterations = 10;
185 Real _lineSearchDampingFactor = 0.5;
186 bool _acceptBest =
false;
205 if (name ==
"noLineSearch")
207 if (name ==
"hackbusch_reusken")
209 DUNE_THROW(
Exception,
"Unkown line search strategy: " << name);
223 template <
typename Newton>
224 std::shared_ptr<LineSearchInterface<typename Newton::Domain>>
229 auto lineSearch = std::make_shared<LineSearchNone<Newton>> (newton);
233 auto lineSearch = std::make_shared<LineSearchHackbuschReusken<Newton>> (newton);
236 DUNE_THROW(
Exception,
"Unkown line search strategy");
Definition adaptivity.hh:29
LineSearchStrategy lineSearchStrategyFromString(const std::string &name)
Get a LineSearchStrategy from a string identifier.
Definition newtonlinesearch.hh:203
LineSearchStrategy
Flags for different line search strategies.
Definition newtonlinesearch.hh:191
@ noLineSearch
Definition newtonlinesearch.hh:192
@ hackbuschReusken
Definition newtonlinesearch.hh:193
std::shared_ptr< LineSearchInterface< typename Newton::Domain > > getLineSearch(Newton &newton, const std::string &name)
Get a pointer to a line search.
Definition newtonlinesearch.hh:225
Base class for all PDELab exceptions.
Definition exceptions.hh:19
Abstract base class describing the line search interface.
Definition newtonlinesearch.hh:13
virtual ~LineSearchInterface()
Every abstract base class should have a virtual destructor.
Definition newtonlinesearch.hh:16
virtual void setParameters(const ParameterTree &)=0
Set parameters.
virtual void lineSearch(Domain &, const Domain &)=0
Do line search.
Class for simply updating the solution without line search.
Definition newtonlinesearch.hh:29
typename Newton::Domain Domain
Definition newtonlinesearch.hh:31
virtual void setParameters(const ParameterTree &) override
Set parameters.
Definition newtonlinesearch.hh:43
typename Newton::Real Real
Definition newtonlinesearch.hh:32
virtual void lineSearch(Domain &solution, const Domain &correction) override
Do line search (in this case just update the solution)
Definition newtonlinesearch.hh:37
LineSearchNone(Newton &newton)
Definition newtonlinesearch.hh:34
Hackbusch-Reusken line search.
Definition newtonlinesearch.hh:58
typename Newton::Real Real
Definition newtonlinesearch.hh:61
virtual void setParameters(const ParameterTree ¶meterTree) override
Set parameters.
Definition newtonlinesearch.hh:169
typename Newton::Domain Domain
Definition newtonlinesearch.hh:60
LineSearchHackbuschReusken(Newton &newton)
Definition newtonlinesearch.hh:63
virtual void lineSearch(Domain &solution, const Domain &correction) override
Do line search.
Definition newtonlinesearch.hh:66