FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
nloptls.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
8#include <kernel/solver/base.hpp>
9#include <kernel/solver/iterative.hpp>
10#include <kernel/solver/linesearch.hpp>
11#include <kernel/solver/nlopt_precond.hpp>
12
13namespace FEAT
14{
15 namespace Solver
16 {
17
41 template<typename Functional_, typename Filter_>
42 class NLOptLS : public PreconditionedIterativeSolver<typename Functional_::VectorTypeR>
43 {
44 public:
46 typedef Functional_ FunctionalType;
48 typedef Filter_ FilterType;
51
53 typedef typename Functional_::GradientType GradientType;
55 typedef typename Functional_::VectorTypeR VectorType;
57 typedef typename Functional_::DataType DataType;
58
63
64 protected:
66 Functional_& _functional;
68 Filter_& _filter;
69
74
87
88 public:
105 explicit NLOptLS(const String& plot_name_, Functional_& functional, Filter_& filter,
106 std::shared_ptr<PrecondType> precond = nullptr) :
107 BaseClass(plot_name_, precond),
108 _functional(functional),
109 _filter(filter),
111 _tol_step(Math::eps<DataType>()),
112 _fval_init(-Math::huge<DataType>()),
113 _fval(Math::huge<DataType>()),
114 _fval_prev(-Math::huge<DataType>()),
115 _steplength(1),
117 _ls_its(~Index(0))
118 {
119 // set communicator by functional (same interface as matrix)
120 this->_set_comm_by_matrix(functional);
121 }
122
145 explicit NLOptLS(const String& plot_name, const String& section_name, const PropertyMap* section,
146 Functional_& functional, Filter_& filter, std::shared_ptr<PrecondType> precond = nullptr) :
147 BaseClass(plot_name, section_name, section, precond),
148 _functional(functional),
149 _filter(filter),
151 _tol_step(Math::eps<DataType>()),
152 _fval_init(-Math::huge<DataType>()),
153 _fval(Math::huge<DataType>()),
154 _fval_prev(-Math::huge<DataType>()),
155 _steplength(1),
157 _ls_its(~Index(0))
158 {
159 // set communicator by functional (same interface as matrix)
160 this->_set_comm_by_matrix(functional);
161
162 auto tol_fval_p = section->get_entry("tol_fval");
163 if (tol_fval_p.second)
164 {
165 set_tol_fval((DataType)std::stod(tol_fval_p.first));
166 }
167
168 auto tol_step_p = section->get_entry("tol_step");
169 if (tol_step_p.second)
170 {
171 set_tol_step((DataType)std::stod(tol_step_p.first));
172 }
173 }
174
178 virtual ~NLOptLS()
179 {
180 }
181
182 virtual String get_summary() const override
183 {
184 String msg(this->get_plot_name()+ ": its: "+stringify(this->get_num_iter())
185 +" ("+ stringify(this->get_status())+")"
186 +", evals: "+stringify(_functional.get_num_func_evals())+" (func) "
187 + stringify(_functional.get_num_grad_evals()) + " (grad) "
188 + stringify(_functional.get_num_hess_evals()) + " (hess)"
189 +" last step: "+stringify_fp_sci(_steplength)+"\n");
190 msg +=this->get_plot_name()+": fval: "+stringify_fp_sci(_fval_init)
191 + " -> "+stringify_fp_sci(_fval)
192 + ", factor "+stringify_fp_sci(_fval/_fval_init)
193 + ", last reduction "+stringify_fp_sci(_fval_prev - _fval)+"\n";
194 msg += this->get_plot_name() +": grad: "+stringify_fp_sci(this->_def_init)
195 + " -> "+stringify_fp_sci(this->_def_cur)
196 + ", factor " +stringify_fp_sci(this->_def_cur/this->_def_init);
197
198 return msg;
199 }
200
209 {
210 return _tol_fval;
211 }
212
222 {
223 return _tol_step;
224 }
225
235 virtual void set_tol_fval(DataType tol_fval)
236 {
237 _tol_fval = tol_fval;
238 }
239
250 virtual void set_tol_step(DataType tol_step)
251 {
252 _tol_step = tol_step;
253 }
254
258 virtual void set_ls_iter_digits(Index digits)
259 {
260 _ls_iter_digits = digits;
261 }
262
263 protected:
267 virtual Status _set_initial_defect(const VectorType& vec_def, const VectorType& vec_sol) override
268 {
269 // store new defect
270 this->_def_init = this->_def_cur = this->_calc_def_norm(vec_def, vec_sol);
271 this->_num_iter = Index(0);
272 this->_num_stag_iter = Index(0);
273
274 _fval_init = _fval;
275 _fval_prev = Math::huge<DataType>();
277 _ls_its = Index(0);
278
279 Statistics::add_solver_expression(
280 std::make_shared<ExpressionDefect>(this->name(), this->_def_init, this->get_num_iter()));
281
282 if(this->_plot_iter())
283 {
284 String msg = this->_plot_name
285 + ": " + stringify(this->_num_iter).pad_front(this->_iter_digits)
286 + " (" + stringify(this->_ls_its).pad_front(_ls_iter_digits) + ")"
287 + " : " + stringify_fp_sci(this->_def_cur)
288 + " / " + stringify_fp_sci(this->_def_cur / this->_def_init)
289 + " : " + stringify_fp_sci(this->_fval);
290
291 this->_print_line(msg);
292 }
293
294 // Ensure that the initial fval and defect are neither NaN nor infinity
295 if( !(Math::isfinite(this->_def_init) && Math::isfinite(this->_fval_init)) )
296 {
297 return Status::aborted;
298 }
299
300 // Check if the initial defect is already low enough
301 if(this->_def_init <= Math::sqr(Math::eps<DataType>()))
302 {
303 return Status::success;
304 }
305
306 // continue iterating
307 return Status::progress;
308 }
309
325 virtual Status _set_new_defect(const VectorType& vec_r, const VectorType& vec_sol) override
326 {
327 // increase iteration count
328 ++this->_num_iter;
329
330 // first, let's see if we have to compute the defect at all
331 bool calc_def = false;
332 calc_def = calc_def || (this->_min_iter < this->_max_iter);
333 calc_def = calc_def || this->_plot_iter();
334 calc_def = calc_def || (this->_min_stag_iter > Index(0));
335
336 // compute new defect
337 if(calc_def)
338 {
339 this->_def_cur = this->_calc_def_norm(vec_r, vec_sol);
340 Statistics::add_solver_expression(
341 std::make_shared<ExpressionDefect>(this->name(), this->_def_cur, this->get_num_iter()));
342 }
343
344 // plot?
345 if(this->_plot_iter())
346 {
347 String msg = this->_plot_name
348 + ": " + stringify(this->_num_iter).pad_front(this->_iter_digits)
349 + " (" + stringify(this->_ls_its).pad_front(_ls_iter_digits) + ")"
350 + " : " + stringify_fp_sci(this->_def_cur)
351 + " / " + stringify_fp_sci(this->_def_cur / this->_def_init)
352 + " : " + stringify_fp_sci(this->_fval)
353 + " : " + stringify_fp_sci(this->_steplength);
354
355 // print message line via comm (if available)
356 this->_print_line(msg);
357 }
358
359 // ensure that the defect is neither NaN nor infinity
360 if(!Math::isfinite(this->_def_cur))
361 {
362 return Status::aborted;
363 }
364
365 // is diverged?
366 if(this->is_diverged())
367 {
368 return Status::diverged;
369 }
370
371 // minimum number of iterations performed?
372 if(this->_num_iter < this->_min_iter)
373 {
374 return Status::progress;
375 }
376
377 // maximum number of iterations performed?
378 if(this->_num_iter >= this->_max_iter)
379 {
380 return Status::max_iter;
381 }
382
383 // Check for convergence of the gradient norm (relative AND absolute criterion)
384 if(this->is_converged())
385 {
386 return Status::success;
387 }
388
389 // Check for convergence wrt. the function value improvement if _tol_fval says so
390 if(_tol_fval > DataType(0))
391 {
392 // This is the factor for the relative function value
394 // Make sure it is at least 1
395 scale = Math::max(scale, DataType(1));
396 // Check for success
397 if(Math::abs(_fval_prev - _fval) <= _tol_fval*scale)
398 {
399 return Status::success;
400 }
401 }
402
404 {
405 return Status::success;
406 }
407
408 // If there were too many stagnated iterations, the solver is stagnated
409 if(this->_min_stag_iter > 0 && this->_num_stag_iter > this->_min_stag_iter)
410 {
411 return Status::stagnated;
412 }
413
414 // continue iterating
415 return Status::progress;
416 }
417
418 };
419 } // namespace Solver
420} //namespace FEAT
FEAT Kernel base header.
A class organizing a tree of key-value pairs.
std::pair< String, bool > get_entry(String key) const
Retrieves a value by its key.
DataType _def_init
initial defect
Definition: iterative.hpp:237
Status get_status() const
Returns the status.
Definition: iterative.hpp:576
String get_plot_name() const
Returns the plot name of the solver.
Definition: iterative.hpp:523
Index _min_iter
minimum number of iterations
Definition: iterative.hpp:227
Index _iter_digits
iteration count digits for plotting
Definition: iterative.hpp:243
Index get_num_iter() const
Returns number of performed iterations.
Definition: iterative.hpp:462
void _set_comm_by_matrix(const Matrix_ &matrix)
Sets the communicator for the solver from a matrix.
Definition: iterative.hpp:680
void _print_line(const String &line) const
Prints a line.
Definition: iterative.hpp:752
bool is_diverged() const
checks for divergence
Definition: iterative.hpp:552
String _plot_name
name of the solver in plots
Definition: iterative.hpp:211
virtual DataType _calc_def_norm(const VectorType &vec_def, const VectorType &vec_sol)
Computes the defect norm.
Definition: iterative.hpp:706
Index _num_iter
number of performed iterations
Definition: iterative.hpp:231
bool _plot_iter(Status st=Status::progress) const
Plot the current iteration?
Definition: iterative.hpp:720
Index _num_stag_iter
number of consecutive stagnated iterations
Definition: iterative.hpp:235
DataType _def_cur
current defect
Definition: iterative.hpp:239
Index _max_iter
maximum number of iterations
Definition: iterative.hpp:229
bool is_converged() const
checks for convergence
Definition: iterative.hpp:533
Index _min_stag_iter
minimum number of stagnation iterations
Definition: iterative.hpp:233
Linesearch base class.
Definition: linesearch.hpp:34
Base class for line search based nonlinear optimizers.
Definition: nloptls.hpp:43
NLOptLS(const String &plot_name, const String &section_name, const PropertyMap *section, Functional_ &functional, Filter_ &filter, std::shared_ptr< PrecondType > precond=nullptr)
Constructor.
Definition: nloptls.hpp:145
Functional_::DataType DataType
Underlying floating point type.
Definition: nloptls.hpp:57
Functional_::GradientType GradientType
Type of the functional's gradient has.
Definition: nloptls.hpp:53
DataType _fval_init
Initial function value.
Definition: nloptls.hpp:76
Solver::Linesearch< Functional_, Filter_ > LinesearchType
Our type of linesearch.
Definition: nloptls.hpp:50
virtual Status _set_initial_defect(const VectorType &vec_def, const VectorType &vec_sol) override
Internal function: sets the initial defect vector.
Definition: nloptls.hpp:267
DataType _fval_prev
Functional value from the previous iteration.
Definition: nloptls.hpp:80
virtual Status _set_new_defect(const VectorType &vec_r, const VectorType &vec_sol) override
Internal function: sets the new defect norm.
Definition: nloptls.hpp:325
DataType _fval
Current functional value.
Definition: nloptls.hpp:78
Index _ls_iter_digits
The number of digits used to plot line search iteration numbers.
Definition: nloptls.hpp:84
Functional_ & _functional
Our nonlinear functional.
Definition: nloptls.hpp:66
virtual void set_tol_fval(DataType tol_fval)
Sets the tolerance for function value improvement.
Definition: nloptls.hpp:235
Functional_::VectorTypeR VectorType
Input type for the gradient.
Definition: nloptls.hpp:55
Functional_ FunctionalType
The nonlinear functional type.
Definition: nloptls.hpp:46
DataType _tol_fval
Tolerance for function improvement.
Definition: nloptls.hpp:71
DataType _tol_step
Tolerance for the length of the update step.
Definition: nloptls.hpp:73
Filter_ FilterType
The filter type.
Definition: nloptls.hpp:48
NLOptLS(const String &plot_name_, Functional_ &functional, Filter_ &filter, std::shared_ptr< PrecondType > precond=nullptr)
Constructor.
Definition: nloptls.hpp:105
virtual ~NLOptLS()
Empty virtual destructor.
Definition: nloptls.hpp:178
virtual void set_ls_iter_digits(Index digits)
Sets the number of digits used to plot line search iteration numbers.
Definition: nloptls.hpp:258
Index _ls_its
The number of iterations the linesearch performed in the last iteration of this solver.
Definition: nloptls.hpp:86
virtual void set_tol_step(DataType tol_step)
Sets the tolerance for the linesearch step size.
Definition: nloptls.hpp:250
virtual DataType get_tol_step()
Gets the tolerance for the linesearch step size.
Definition: nloptls.hpp:221
Filter_ & _filter
The filter we apply to the gradient.
Definition: nloptls.hpp:68
DataType _steplength
The last step length of the line search.
Definition: nloptls.hpp:82
virtual String get_summary() const override
Returns a summary string.
Definition: nloptls.hpp:182
NLOptPrecond< typename Functional_::VectorTypeL, Filter_ > PrecondType
Generic preconditioner.
Definition: nloptls.hpp:62
virtual DataType get_tol_fval()
Gets the tolerance for function value improvement.
Definition: nloptls.hpp:208
PreconditionedIterativeSolver< VectorType > BaseClass
Our baseclass.
Definition: nloptls.hpp:60
Abstract base class for preconditioners for nonlinear optimization.
Abstract base-class for preconditioned iterative solvers.
Definition: iterative.hpp:1027
virtual String name() const =0
Returns a descriptive string.
String class implementation.
Definition: string.hpp:46
String pad_front(size_type len, char c=' ') const
Pads the front of the string up to a desired length.
Definition: string.hpp:392
T_ abs(T_ x)
Returns the absolute value.
Definition: math.hpp:275
T_ sqr(T_ x)
Returns the square of a value.
Definition: math.hpp:95
bool isfinite(T_ x)
Checks whether a value is finite.
T_ max(T_ a, T_ b)
Returns the maximum of two values.
Definition: math.hpp:137
Status
Solver status return codes enumeration.
Definition: base.hpp:47
@ success
solving successful (convergence criterion fulfilled)
@ progress
continue iteration (internal use only)
@ stagnated
solver stagnated (stagnation criterion fulfilled)
@ max_iter
solver reached maximum iterations
@ diverged
solver diverged (divergence criterion fulfilled)
@ aborted
premature abort (solver aborted due to internal errors or preconditioner failure)
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:944
String stringify_fp_sci(DataType_ value, int precision=0, int width=0, bool sign=false)
Prints a floating point value to a string in scientific notation.
Definition: string.hpp:1088
std::uint64_t Index
Index data type.