3#ifndef DUNE_PDELAB_SOLVER_LINESEARCH_HH
4#define DUNE_PDELAB_SOLVER_LINESEARCH_HH
6#include <dune/pdelab/solver/newtonerrors.hh>
13 template <
typename Domain>
29 std::cout <<
"NewtonMethod::_lineSearch->printParameters() is not implemented." << std::endl;
35 template <
typename Solver>
39 using Domain =
typename Solver::Domain;
40 using Real =
typename Solver::Real;
45 virtual void lineSearch(Domain& solution,
const Domain& correction)
override
47 solution.axpy(-1.0, correction);
48 _solver.updateDefect(solution);
56 std::cout <<
"LineSearch.Type........... None" << std::endl;
70 template <
typename Solver>
74 using Domain =
typename Solver::Domain;
75 using Real =
typename Solver::Real;
78 _solver(solver), _forceAcceptBest(forceAcceptBest) {}
81 virtual void lineSearch(Domain& solution,
const Domain& correction)
override
83 if ((_solver.result().defect < _solver.getAbsoluteLimit())){
84 solution.axpy(-1.0, correction);
85 _solver.updateDefect(solution);
89 auto verbosity = _solver.getVerbosityLevel();
92 std::cout <<
" Performing line search..." << std::endl;
94 Real bestLambda = 0.0;
95 Real bestDefect = _solver.result().defect;
96 Real previousDefect = _solver.result().defect;
97 bool converged =
false;
99 if (not _previousSolution)
100 _previousSolution = std::make_shared<Domain>(solution);
102 *_previousSolution = solution;
104 for (
unsigned int iteration = 0; iteration < _lineSearchMaxIterations; ++iteration){
106 std::cout <<
" trying line search damping factor: "
107 << std::setw(12) << std::setprecision(4) << std::scientific
111 solution.axpy(-lambda, correction);
112 _solver.updateDefect(solution);
114 if (not std::isfinite(_solver.result().defect))
115 std::cout <<
" NaNs detected" << std::endl;
118 if (_solver.result().defect <= (1.0 - lambda/4) * previousDefect){
120 std::cout <<
" line search converged" << std::endl;
125 if (_solver.result().defect < bestDefect){
126 bestDefect = _solver.result().defect;
130 lambda *= _lineSearchDampingFactor;
131 solution = *_previousSolution;
136 std::cout <<
" max line search iterations exceeded" << std::endl;
138 if (not (_acceptBest or _forceAcceptBest)){
139 solution = *_previousSolution;
140 _solver.updateDefect(solution);
142 "LineSearch::lineSearch(): line search failed, "
143 "max iteration count reached, "
144 "defect did not improve enough");
147 if (bestLambda == 0.0){
148 solution = *_previousSolution;
149 _solver.updateDefect(solution);
151 "LineSearch::lineSearch(): line search failed, "
152 "max iteration count reached, "
153 "defect did not improve in any of the iterations");
155 if (bestLambda != lambda){
156 solution = *_previousSolution;
157 solution.axpy(-bestLambda, correction);
158 _solver.updateDefect(solution);
166 std::cout <<
" line search damping factor: "
167 << std::setw(12) << std::setprecision(4) << std::scientific
168 << lambda << std::endl;
186 _lineSearchMaxIterations = parameterTree.
get<
unsigned int>(
"MaxIterations",
187 _lineSearchMaxIterations);
188 _lineSearchDampingFactor = parameterTree.
get<Real>(
"DampingFactor",
189 _lineSearchDampingFactor);
190 _acceptBest = parameterTree.
get<
bool>(
"AcceptBest", _acceptBest);
195 std::cout <<
"LineSearch.Type........... Hackbusch-Reusken" << std::endl;
196 std::cout <<
"LineSearch.MaxIterations.. " << _lineSearchMaxIterations << std::endl;
197 std::cout <<
"LineSearch.DampingFactor.. " << _lineSearchDampingFactor << std::endl;
198 std::cout <<
"LineSearch.AcceptBest..... " << (_acceptBest or _forceAcceptBest) << std::endl;
203 std::shared_ptr<Domain> _previousSolution;
206 unsigned int _lineSearchMaxIterations = 10;
207 Real _lineSearchDampingFactor = 0.5;
208 bool _acceptBest =
false;
209 bool _forceAcceptBest;
213 enum class LineSearchStrategy
217 hackbuschReuskenAcceptBest
229 LineSearchStrategy lineSearchStrategyFromString (
const std::string& name)
231 if (name ==
"noLineSearch")
232 return LineSearchStrategy::noLineSearch;
233 if (name ==
"hackbuschReusken")
234 return LineSearchStrategy::hackbuschReusken;
235 if (name ==
"hackbuschReuskenAcceptBest")
236 return LineSearchStrategy::hackbuschReuskenAcceptBest;
237 DUNE_THROW(Exception,
"Unkown line search strategy: " << name);
252 template <
typename Solver>
253 std::shared_ptr<LineSearchInterface<typename Solver::Domain>>
254 createLineSearch(Solver& solver, LineSearchStrategy strategy)
256 if (strategy == LineSearchStrategy::noLineSearch){
257 auto lineSearch = std::make_shared<LineSearchNone<Solver>> (solver);
260 if (strategy == LineSearchStrategy::hackbuschReusken){
261 auto lineSearch = std::make_shared<LineSearchHackbuschReusken<Solver>> (solver);
264 if (strategy == LineSearchStrategy::hackbuschReuskenAcceptBest){
265 auto lineSearch = std::make_shared<LineSearchHackbuschReusken<Solver>> (solver,
true);
266 std::cout <<
"Warning: linesearch hackbuschReuskenAcceptBest is deprecated and will be removed after PDELab 2.7.\n"
267 <<
" Please use 'hackbuschReusken' and add the parameter 'LineSearchAcceptBest : true'";
270 DUNE_THROW(Exception,
"Unkown line search strategy");
Hackbusch-Reusken line search.
Definition: linesearch.hh:72
virtual void setParameters(const ParameterTree ¶meterTree) override
Set parameters.
Definition: linesearch.hh:184
virtual void printParameters() const override
Print paramters.
Definition: linesearch.hh:193
virtual void lineSearch(Domain &solution, const Domain &correction) override
Do line search.
Definition: linesearch.hh:81
Abstract base class describing the line search interface.
Definition: linesearch.hh:15
virtual ~LineSearchInterface()
Every abstract base class should have a virtual destructor.
Definition: linesearch.hh:18
virtual void printParameters() const
Print paramters.
Definition: linesearch.hh:27
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: linesearch.hh:37
virtual void printParameters() const override
Print paramters.
Definition: linesearch.hh:54
virtual void lineSearch(Domain &solution, const Domain &correction) override
Do line search (in this case just update the solution)
Definition: linesearch.hh:45
virtual void setParameters(const ParameterTree &) override
Set parameters.
Definition: linesearch.hh:51
Hierarchical structure of string parameters.
Definition: parametertree.hh:37
std::string get(const std::string &key, const std::string &defaultValue) const
get value as string
Definition: parametertree.cc:188
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218