OGS 6.2.1-76-gbb689931b
NumLib::NonlinearSolver< NonlinearSolverTag::Newton > Class Template Referencefinal

Detailed Description

template<>
class NumLib::NonlinearSolver< NonlinearSolverTag::Newton >

Find a solution to a nonlinear equation using the Newton-Raphson method.

Definition at line 79 of file NonlinearSolver.h.

#include <NonlinearSolver.h>

Inheritance diagram for NumLib::NonlinearSolver< NonlinearSolverTag::Newton >:
Collaboration diagram for NumLib::NonlinearSolver< NonlinearSolverTag::Newton >:

Public Types

using System = NonlinearSystem< NonlinearSolverTag::Newton >
 Type of the nonlinear equation system to be solved. More...
 

Public Member Functions

 NonlinearSolver (GlobalLinearSolver &linear_solver, int const maxiter, double const damping=1.0)
 
void setEquationSystem (System &eq, ConvergenceCriterion &conv_crit)
 
void assemble (GlobalVector const &x) const override
 
NonlinearSolverStatus solve (GlobalVector &x, std::function< void(int, GlobalVector const &)> const &postIterationCallback) override
 
- Public Member Functions inherited from NumLib::NonlinearSolverBase
virtual ~NonlinearSolverBase ()=default
 

Private Attributes

GlobalLinearSolver & _linear_solver
 
System_equation_system = nullptr
 
ConvergenceCriterion_convergence_criterion = nullptr
 
int const _maxiter
 maximum number of iterations More...
 
double const _damping
 
std::size_t _res_id = 0u
 ID of the residual vector. More...
 
std::size_t _J_id = 0u
 ID of the Jacobian matrix. More...
 
std::size_t _minus_delta_x_id = 0u
 ID of the $ -\Delta x$ vector. More...
 
std::size_t _x_new_id
 ID of the vector storing $ x - (-\Delta x) $. More...
 

Member Typedef Documentation

◆ System

Type of the nonlinear equation system to be solved.

Definition at line 84 of file NonlinearSolver.h.

Constructor & Destructor Documentation

◆ NonlinearSolver()

NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::NonlinearSolver ( GlobalLinearSolver &  linear_solver,
int const  maxiter,
double const  damping = 1.0 
)
inlineexplicit

Constructs a new instance.

Parameters
linear_solverthe linear solver used by this nonlinear solver.
maxiterthe maximum number of iterations used to solve the equation.
dampingA positive damping factor.
See also
_damping

Definition at line 94 of file NonlinearSolver.h.

97  : _linear_solver(linear_solver), _maxiter(maxiter), _damping(damping)
98  {
99  }
int const _maxiter
maximum number of iterations

Member Function Documentation

◆ assemble()

void NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::assemble ( GlobalVector const &  x) const
overridevirtual

Only assemble the equation system.

Note
This method is needed to preload CrankNicolson time discretization scheme. It is not used for the general solver steps; in those only the solve() method is needed.
Parameters
xthe state at which the equation system will be assembled.

Implements NumLib::NonlinearSolverBase.

Definition at line 178 of file NonlinearSolver.cpp.

180 {
182  // TODO if the equation system would be reset to nullptr after each
183  // assemble() or solve() call, the user would be forced to set the
184  // equation every time and could not forget it.
185 }
virtual void assemble(GlobalVector const &x)=0

◆ setEquationSystem()

void NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::setEquationSystem ( System eq,
ConvergenceCriterion conv_crit 
)
inline

Set the nonlinear equation system that will be solved. TODO doc

Definition at line 103 of file NonlinearSolver.h.

◆ solve()

NonlinearSolverStatus NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::solve ( GlobalVector &  x,
std::function< void(int, GlobalVector const &)> const &  postIterationCallback 
)
overridevirtual

Assemble and solve the equation system.

Parameters
xin: the initial guess, out: the solution.
postIterationCallbackcalled after each iteration if set.
Return values
trueif the equation system could be solved
falseotherwise

Implements NumLib::NonlinearSolverBase.

Definition at line 187 of file NonlinearSolver.cpp.

References MathLib::LinAlg::axpy(), MathLib::LinAlg::copy(), BaseLib::RunTime::elapsed(), NumLib::FAILURE, NumLib::MatrixProvider::getMatrix(), NumLib::VectorProvider::getVector(), NumLib::GlobalVectorProvider::provider, NumLib::GlobalMatrixProvider::provider, NumLib::MatrixProvider::releaseMatrix(), NumLib::VectorProvider::releaseVector(), NumLib::REPEAT_ITERATION, BaseLib::RunTime::start(), and NumLib::SUCCESS.

191 {
192  namespace LinAlg = MathLib::LinAlg;
193  auto& sys = *_equation_system;
194 
196  _res_id);
197  auto& minus_delta_x =
200  auto& J =
202 
203  bool error_norms_met = false;
204 
205  // TODO be more efficient
206  // init minus_delta_x to the right size
207  LinAlg::copy(x, minus_delta_x);
208 
210 
211  int iteration = 1;
212  for (; iteration <= _maxiter;
213  ++iteration, _convergence_criterion->reset())
214  {
215  BaseLib::RunTime timer_dirichlet;
216  double time_dirichlet = 0.0;
217 
218  BaseLib::RunTime time_iteration;
219  time_iteration.start();
220 
221  timer_dirichlet.start();
222  sys.computeKnownSolutions(x);
223  sys.applyKnownSolutions(x);
224  time_dirichlet += timer_dirichlet.elapsed();
225 
226  sys.preIteration(iteration, x);
227 
228  BaseLib::RunTime time_assembly;
229  time_assembly.start();
230  sys.assemble(x);
231  sys.getResidual(x, res);
232  sys.getJacobian(J);
233  INFO("[time] Assembly took %g s.", time_assembly.elapsed());
234 
235  minus_delta_x.setZero();
236 
237  timer_dirichlet.start();
238  sys.applyKnownSolutionsNewton(J, res, minus_delta_x);
239  time_dirichlet += timer_dirichlet.elapsed();
240  INFO("[time] Applying Dirichlet BCs took %g s.", time_dirichlet);
241 
242  if (!sys.isLinear() && _convergence_criterion->hasResidualCheck())
243  {
245  }
246 
247  BaseLib::RunTime time_linear_solver;
248  time_linear_solver.start();
249  bool iteration_succeeded = _linear_solver.solve(J, res, minus_delta_x);
250  INFO("[time] Linear solver took %g s.", time_linear_solver.elapsed());
251 
252  if (!iteration_succeeded)
253  {
254  ERR("Newton: The linear solver failed.");
255  }
256  else
257  {
258  // TODO could be solved in a better way
259  // cf.
260  // http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecWAXPY.html
261  auto& x_new =
263  LinAlg::axpy(x_new, -_damping, minus_delta_x);
264 
265  if (postIterationCallback)
266  {
267  postIterationCallback(iteration, x_new);
268  }
269 
270  switch(sys.postIteration(x_new))
271  {
273  break;
275  ERR("Newton: The postIteration() hook reported a "
276  "non-recoverable error.");
277  iteration_succeeded = false;
278  break;
280  INFO(
281  "Newton: The postIteration() hook decided that this "
282  "iteration"
283  " has to be repeated.");
284  // TODO introduce some onDestroy hook.
286  continue; // That throws the iteration result away.
287  }
288 
289  LinAlg::copy(x_new, x); // copy new solution to x
291  }
292 
293  if (!iteration_succeeded)
294  {
295  // Don't compute further error norms, but break here.
296  error_norms_met = false;
297  break;
298  }
299 
300  if (sys.isLinear()) {
301  error_norms_met = true;
302  } else {
304  // Note: x contains the new solution!
305  _convergence_criterion->checkDeltaX(minus_delta_x, x);
306  }
307 
308  error_norms_met = _convergence_criterion->isSatisfied();
309  }
310 
311  INFO("[time] Iteration #%u took %g s.", iteration,
312  time_iteration.elapsed());
313 
314  if (error_norms_met)
315  {
316  break;
317  }
318 
319  // Avoid increment of the 'iteration' if the error norms are not met,
320  // but maximum number of iterations is reached.
321  if (iteration >= _maxiter)
322  {
323  break;
324  }
325  }
326 
327  if (iteration > _maxiter)
328  {
329  ERR("Newton: Could not solve the given nonlinear system within %u "
330  "iterations",
331  _maxiter);
332  }
333 
337  minus_delta_x);
338 
339  return {error_norms_met, iteration};
340 }
std::size_t _J_id
ID of the Jacobian matrix.
virtual void releaseMatrix(GlobalMatrix const &A)=0
virtual GlobalVector & getVector()=0
Get an uninitialized vector.
static NUMLIB_EXPORT MatrixProvider & provider
virtual bool hasResidualCheck() const =0
static NUMLIB_EXPORT VectorProvider & provider
std::size_t _x_new_id
ID of the vector storing .
int const _maxiter
maximum number of iterations
virtual void checkDeltaX(GlobalVector const &minus_delta_x, GlobalVector const &x)=0
virtual GlobalMatrix & getMatrix()=0
Get an uninitialized matrix.
Count the running time.
Definition: RunTime.h:32
void start()
Start the timer.
Definition: RunTime.h:36
std::size_t _res_id
ID of the residual vector.
virtual bool hasDeltaXCheck() const =0
virtual void releaseVector(GlobalVector const &x)=0
virtual bool isSatisfied() const
Tell if the convergence criterion is satisfied.
void axpy(MatrixOrVector &y, double const a, MatrixOrVector const &x)
Computes .
Definition: LinAlg.h:57
void copy(MatrixOrVector const &x, MatrixOrVector &y)
Copies x to y.
Definition: LinAlg.h:36
virtual void checkResidual(GlobalVector const &residual)=0
Check if the residual satisfies the convergence criterion.
double elapsed() const
Get the elapsed time after started.
Definition: RunTime.h:52

Member Data Documentation

◆ _convergence_criterion

ConvergenceCriterion* NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_convergence_criterion = nullptr
private

Definition at line 121 of file NonlinearSolver.h.

◆ _damping

double const NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_damping
private

A positive damping factor. The default value 1.0 gives a non-damped Newton method. Common values are in the range 0.5 to 0.7 for somewhat conservative method and seldom become smaller than 0.2 for very conservative approach.

Definition at line 128 of file NonlinearSolver.h.

◆ _equation_system

System* NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_equation_system = nullptr
private

Definition at line 118 of file NonlinearSolver.h.

◆ _J_id

std::size_t NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_J_id = 0u
private

ID of the Jacobian matrix.

Definition at line 131 of file NonlinearSolver.h.

◆ _linear_solver

GlobalLinearSolver& NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_linear_solver
private

Definition at line 117 of file NonlinearSolver.h.

◆ _maxiter

int const NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_maxiter
private

maximum number of iterations

Definition at line 122 of file NonlinearSolver.h.

◆ _minus_delta_x_id

std::size_t NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_minus_delta_x_id = 0u
private

ID of the $ -\Delta x$ vector.

Definition at line 132 of file NonlinearSolver.h.

◆ _res_id

std::size_t NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_res_id = 0u
private

ID of the residual vector.

Definition at line 130 of file NonlinearSolver.h.

◆ _x_new_id

std::size_t NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_x_new_id
private
Initial value:
=
0u

ID of the vector storing $ x - (-\Delta x) $.

Definition at line 133 of file NonlinearSolver.h.


The documentation for this class was generated from the following files: