OGS
NumLib::NonlinearSolver< NonlinearSolverTag::Newton > Class Referencefinal

Detailed Description

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

Definition at line 76 of file NonlinearSolver.h.

#include <NonlinearSolver.h>

Inheritance diagram for NumLib::NonlinearSolver< NonlinearSolverTag::Newton >:
[legend]
Collaboration diagram for NumLib::NonlinearSolver< NonlinearSolverTag::Newton >:
[legend]

Public Types

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

Public Member Functions

 NonlinearSolver (GlobalLinearSolver &linear_solver, int const maxiter, int const recompute_jacobian=1, double const damping=1.0, std::optional< double > const damping_reduction=std::nullopt)
 ~NonlinearSolver ()
void setEquationSystem (System &eq, ConvergenceCriterion &conv_crit)
void calculateNonEquilibriumInitialResiduum (std::vector< GlobalVector * > const &x, std::vector< GlobalVector * > const &x_prev, int const process_id) override
NonlinearSolverStatus solve (std::vector< GlobalVector * > &x, std::vector< GlobalVector * > const &x_prev, std::function< void(int, bool, std::vector< GlobalVector * > const &)> const &postIterationCallback, int const process_id) override
void compensateNonEquilibriumInitialResiduum (bool const value)
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
int const _recompute_jacobian = 1
double const _damping
std::optional< double > const _damping_reduction
GlobalVector_r_neq = nullptr
 non-equilibrium initial residuum.
std::size_t _res_id = 0u
 ID of the residual vector.
std::size_t _J_id = 0u
 ID of the Jacobian matrix.
std::size_t _minus_delta_x_id = 0u
 ID of the \( -\Delta x\) vector.
std::size_t _x_new_id
 ID of the vector storing \( x - (-\Delta x) \).
std::size_t _r_neq_id = 0u
bool _compensate_non_equilibrium_initial_residuum = false

Member Typedef Documentation

◆ System

Type of the nonlinear equation system to be solved.

Definition at line 81 of file NonlinearSolver.h.

Constructor & Destructor Documentation

◆ NonlinearSolver()

NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::NonlinearSolver ( GlobalLinearSolver & linear_solver,
int const maxiter,
int const recompute_jacobian = 1,
double const damping = 1.0,
std::optional< double > const damping_reduction = std::nullopt )
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.
recompute_jacobianrecompute jacobian for the follow-up steps
dampingA positive damping factor.
See also
_damping
Parameters
damping_reductionA parameter that reduces damping
See also
_damping_reduction

Definition at line 94 of file NonlinearSolver.h.

References _damping, _damping_reduction, _linear_solver, _maxiter, and _recompute_jacobian.

Referenced by ~NonlinearSolver(), calculateNonEquilibriumInitialResiduum(), and solve().

◆ ~NonlinearSolver()

Definition at line 637 of file NonlinearSolver.cpp.

638{
639 if (_r_neq != nullptr)
640 {
642 }
643}
GlobalVector * _r_neq
non-equilibrium initial residuum.

References NonlinearSolver(), _r_neq, and NumLib::GlobalVectorProvider::provider.

Member Function Documentation

◆ calculateNonEquilibriumInitialResiduum()

void NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::calculateNonEquilibriumInitialResiduum ( std::vector< GlobalVector * > const & x,
std::vector< GlobalVector * > const & x_prev,
int const process_id )
overridevirtual

Implements NumLib::NonlinearSolverBase.

Definition at line 322 of file NonlinearSolver.cpp.

326{
328 {
329 return;
330 }
331
332 INFO("Calculate non-equilibrium initial residuum.");
333
334 _equation_system->assemble(x, x_prev, process_id);
337
338 // Set the values of the selected entries of _r_neq, which are associated
339 // with the equations that do not need initial residual compensation, to
340 // zero.
341 const auto selected_global_indices =
342 _equation_system->getIndicesOfResiduumWithoutInitialCompensation();
344
346 _equation_system->setReleaseNodalForces(_r_neq, process_id);
347
349}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:36
void finalizeAssembly(PETScMatrix &A)
Definition LinAlg.cpp:198

References NonlinearSolver(), _compensate_non_equilibrium_initial_residuum, _equation_system, _r_neq, _r_neq_id, MathLib::LinAlg::finalizeAssembly(), INFO(), and NumLib::GlobalVectorProvider::provider.

◆ compensateNonEquilibriumInitialResiduum()

void NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::compensateNonEquilibriumInitialResiduum ( bool const value)
inline

◆ 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 112 of file NonlinearSolver.h.

References _convergence_criterion, and _equation_system.

◆ solve()

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

Assemble and solve the equation system.

Parameters
xin: the initial guess, out: the solution.
x_prevprevious time step solution.
postIterationCallbackcalled after each iteration if set.
process_idusually used in staggered schemes.
Return values
trueif the equation system could be solved
falseotherwise

Implements NumLib::NonlinearSolverBase.

Definition at line 351 of file NonlinearSolver.cpp.

357{
358 namespace LinAlg = MathLib::LinAlg;
359 auto& sys = *_equation_system;
360
362 auto& minus_delta_x =
365
366 bool error_norms_met = false;
367
368 // TODO be more efficient
369 // init minus_delta_x to the right size
371
372 _convergence_criterion->preFirstIteration();
373
374 int iteration = 1;
375#if !defined(USE_PETSC) && !defined(USE_LIS)
377#endif
378 for (; iteration <= _maxiter; ++iteration, _convergence_criterion->reset())
379 {
381 double time_dirichlet = 0.0;
382
384 INFO("Iteration #{:d} started.", iteration);
385 time_iteration.start();
386
387 timer_dirichlet.start();
388 sys.computeKnownSolutions(*x[process_id], process_id);
389 time_dirichlet += timer_dirichlet.elapsed();
390
391 sys.preIteration(iteration, *x[process_id]);
392
394 time_assembly.start();
395 bool mpi_rank_assembly_ok = true;
396 try
397 {
398 sys.assemble(x, x_prev, process_id);
399 }
400 catch (AssemblyException const& e)
401 {
402 ERR("Abort nonlinear iteration. Repeating timestep. Reason: {:s}",
403 e.what());
404 error_norms_met = false;
406 mpi_rank_assembly_ok = false;
407 }
409 {
410 break;
411 }
412 sys.getResidual(*x[process_id], *x_prev[process_id], res);
413 sys.getJacobian(J);
414 INFO("[time] Assembly took {:g} s.", time_assembly.elapsed());
415
416 // Subtract non-equilibrium initial residuum if set
417 if (_r_neq != nullptr)
418 LinAlg::axpy(res, -1, *_r_neq);
419
420 minus_delta_x.setZero();
421
422 timer_dirichlet.start();
423 sys.applyKnownSolutionsNewton(J, res, *x[process_id], minus_delta_x);
424 time_dirichlet += timer_dirichlet.elapsed();
425 INFO("[time] Applying Dirichlet BCs took {:g} s.", time_dirichlet);
426
427 if (!sys.isLinear() && _convergence_criterion->hasResidualCheck())
428 {
429 _convergence_criterion->checkResidual(res);
430 }
431
433 time_linear_solver.start();
434#if !defined(USE_PETSC) && !defined(USE_LIS)
437 {
442 }
443
444 bool iteration_succeeded = false;
446 {
447 ERR("Newton: The linear solver failed in the compute() step.");
448 }
449 else
450 {
452 }
453#else
455#endif
456 INFO("[time] Linear solver took {:g} s.", time_linear_solver.elapsed());
457
459 {
460 ERR("Newton: The linear solver failed.");
461 }
462 else
463 {
464 // TODO could be solved in a better way
465 // cf.
466 // https://petsc.org/release/manualpages/Vec/VecWAXPY
467
468 // Copy pointers, replace the one for the given process id.
473 double damping = _damping;
474 if (_convergence_criterion->hasNonNegativeDamping())
475 {
476 damping = _convergence_criterion->getDampingFactor(
478 }
480 {
481 damping =
482 damping +
483 (1 - damping) *
485 }
487
489 {
491 }
492
493 switch (sys.postIteration(*x_new[process_id]))
494 {
496 break;
498 ERR("Newton: The postIteration() hook reported a "
499 "non-recoverable error.");
500 iteration_succeeded = false;
501 break;
503 INFO(
504 "Newton: The postIteration() hook decided that this "
505 "iteration has to be repeated.");
506 // TODO introduce some onDestroy hook.
508 *x_new[process_id]);
509 continue; // That throws the iteration result away.
510 }
511
513 *x[process_id]); // copy new solution to x
515 *x_new[process_id]);
516 }
517
519 {
520 // Don't compute further error norms, but break here.
521 error_norms_met = false;
522 break;
523 }
524
525 if (sys.isLinear())
526 {
527 error_norms_met = true;
528 }
529 else
530 {
531 if (_convergence_criterion->hasDeltaXCheck())
532 {
533 // Note: x contains the new solution!
535 *x[process_id]);
536 }
537
539 }
540
541 INFO("[time] Iteration #{:d} took {:g} s.", iteration,
542 time_iteration.elapsed());
543
544 if (error_norms_met)
545 {
546 break;
547 }
548
549 // Avoid increment of the 'iteration' if the error norms are not met,
550 // but maximum number of iterations is reached.
551 if (iteration >= _maxiter)
552 {
553 break;
554 }
555 }
556
557 if (iteration > _maxiter)
558 {
559 ERR("Newton: Could not solve the given nonlinear system within {:d} "
560 "iterations",
561 _maxiter);
562 }
563
567
568 return {error_norms_met, iteration};
569}
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:48
std::size_t _J_id
ID of the Jacobian matrix.
std::size_t _x_new_id
ID of the vector storing .
std::size_t _res_id
ID of the residual vector.
void copy(PETScVector const &x, PETScVector &y)
Definition LinAlg.cpp:37
void axpy(PETScVector &y, PetscScalar const a, PETScVector const &x)
Definition LinAlg.cpp:57

References NonlinearSolver(), _convergence_criterion, _damping, _damping_reduction, _equation_system, _J_id, _linear_solver, _maxiter, _minus_delta_x_id, _r_neq, _recompute_jacobian, _res_id, _x_new_id, BaseLib::MPI::anyOf(), MathLib::LinAlg::axpy(), MathLib::LinAlg::copy(), BaseLib::RunTime::elapsed(), ERR(), NumLib::FAILURE, INFO(), NumLib::GlobalMatrixProvider::provider, NumLib::GlobalVectorProvider::provider, MathLib::RECOMPUTE_AND_STORE, NumLib::REPEAT_ITERATION, MathLib::REUSE, BaseLib::RunTime::start(), and NumLib::SUCCESS.

Member Data Documentation

◆ _compensate_non_equilibrium_initial_residuum

bool NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_compensate_non_equilibrium_initial_residuum = false
private

Enables computation of the non-equilibrium initial residuum \( r_{\rm neq} \) before the first time step. The forces are zero if the external forces are in equilibrium with the initial state/initial conditions. During the simulation the new residuum reads \( \tilde r = r - r_{\rm neq} \).

Definition at line 170 of file NonlinearSolver.h.

Referenced by calculateNonEquilibriumInitialResiduum(), and compensateNonEquilibriumInitialResiduum().

◆ _convergence_criterion

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

Definition at line 140 of file NonlinearSolver.h.

Referenced by setEquationSystem(), and solve().

◆ _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 149 of file NonlinearSolver.h.

Referenced by NonlinearSolver(), and solve().

◆ _damping_reduction

std::optional<double> const NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_damping_reduction
private

A parameter that reduces the damping by iteration / _damping_reduction If the expression is smaller than zero, then damping is the same for all iterations. If the expression is bigger than one it is clamped by one.

Definition at line 154 of file NonlinearSolver.h.

Referenced by NonlinearSolver(), and solve().

◆ _equation_system

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

◆ _J_id

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

ID of the Jacobian matrix.

Definition at line 158 of file NonlinearSolver.h.

Referenced by solve().

◆ _linear_solver

Definition at line 136 of file NonlinearSolver.h.

Referenced by NonlinearSolver(), and solve().

◆ _maxiter

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

maximum number of iterations

Definition at line 141 of file NonlinearSolver.h.

Referenced by NonlinearSolver(), and solve().

◆ _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 159 of file NonlinearSolver.h.

Referenced by solve().

◆ _r_neq

non-equilibrium initial residuum.

Definition at line 156 of file NonlinearSolver.h.

Referenced by ~NonlinearSolver(), calculateNonEquilibriumInitialResiduum(), and solve().

◆ _r_neq_id

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

ID of the non-equilibrium initial residuum vector.

Definition at line 162 of file NonlinearSolver.h.

Referenced by calculateNonEquilibriumInitialResiduum().

◆ _recompute_jacobian

int const NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_recompute_jacobian = 1
private

Definition at line 143 of file NonlinearSolver.h.

Referenced by NonlinearSolver(), and solve().

◆ _res_id

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

ID of the residual vector.

Definition at line 157 of file NonlinearSolver.h.

Referenced by solve().

◆ _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 160 of file NonlinearSolver.h.

Referenced by solve().


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