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

Detailed Description

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

Definition at line 70 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, std::unique_ptr< NewtonStepStrategy > newton_strategy, int const recompute_jacobian=1)
 ~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)
void setTikhonovLambda (double const lambda, int const starting_iteration)
Public Member Functions inherited from NumLib::NonlinearSolverBase
virtual ~NonlinearSolverBase ()=default

Private Attributes

GlobalLinearSolver_linear_solver
System_equation_system = nullptr
int const _maxiter
 maximum number of iterations
std::unique_ptr< NewtonStepStrategy_step_strategy
 Globalization / step-acceptance strategy (e.g. fixed damping).
ConvergenceCriterion_convergence_criterion = nullptr
 Convergence criterion used to terminate the Newton iteration.
int const _recompute_jacobian
 Recompute Jacobian every this many steps.
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
double _tikhonov_lambda = 0.0
 Tikhonov regularization parameter.
int _tikhonov_starting_iteration
 Starting iteration for Tikhonov regularization.

Member Typedef Documentation

◆ System

Type of the nonlinear equation system to be solved.

Definition at line 75 of file NonlinearSolver.h.

Constructor & Destructor Documentation

◆ NonlinearSolver()

NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::NonlinearSolver ( GlobalLinearSolver & linear_solver,
int const maxiter,
std::unique_ptr< NewtonStepStrategy > newton_strategy,
int const recompute_jacobian = 1 )
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.
newton_strategyglobalization / step-acceptance strategy (e.g. fixed damping, line search). Ownership is transferred to the solver.
recompute_jacobianrecompute the Jacobian every this many steps.

Definition at line 87 of file NonlinearSolver.h.

96 {
97 }
int const _maxiter
maximum number of iterations
int const _recompute_jacobian
Recompute Jacobian every this many steps.
std::unique_ptr< NewtonStepStrategy > _step_strategy
Globalization / step-acceptance strategy (e.g. fixed damping).

References _linear_solver, _maxiter, _recompute_jacobian, and _step_strategy.

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

◆ ~NonlinearSolver()

Definition at line 640 of file NonlinearSolver.cpp.

641{
642 if (_r_neq != nullptr)
643 {
645 }
646}
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 349 of file NonlinearSolver.cpp.

353{
355 {
356 return;
357 }
358
359 INFO("Calculate non-equilibrium initial residuum.");
360
361 _equation_system->assemble(x, x_prev, process_id);
364
365 // Set the values of the selected entries of _r_neq, which are associated
366 // with the equations that do not need initial residual compensation, to
367 // zero.
369 _equation_system->getIndicesOfResiduumWithoutInitialCompensation();
370
371#ifdef USE_PETSC
372 // Ghost entry with global index 0 is encoded as -global_size
373 // After abs(), it appears as global_size and must be converted back to 0
374 auto const global_size = _r_neq->size();
375 for (auto& idx : selected_global_indices)
376 {
377 if (idx == global_size)
378 {
379 idx = 0;
380 }
381 }
382#endif
383
386 _equation_system->setReleaseNodalForces(_r_neq, process_id);
387
389}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void finalizeAssembly(PETScMatrix &A)
Definition LinAlg.cpp:191

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 and the convergence criterion used to terminate the iteration. Also forwards the criterion to the step strategy so that strategies that depend on residual or delta-x information (e.g. non-negative damping) can use it.

Definition at line 105 of file NonlinearSolver.h.

106 {
109 _step_strategy->setDampingPolicy(
110 _convergence_criterion->dampingPolicy());
111 }
ConvergenceCriterion * _convergence_criterion
Convergence criterion used to terminate the Newton iteration.

References _convergence_criterion, _equation_system, and _step_strategy.

◆ setTikhonovLambda()

void NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::setTikhonovLambda ( double const lambda,
int const starting_iteration )
inline

Definition at line 130 of file NonlinearSolver.h.

131 {
134 }
double _tikhonov_lambda
Tikhonov regularization parameter.
int _tikhonov_starting_iteration
Starting iteration for Tikhonov regularization.

References _tikhonov_lambda, and _tikhonov_starting_iteration.

◆ 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 391 of file NonlinearSolver.cpp.

397{
398 namespace LinAlg = MathLib::LinAlg;
399 auto& sys = *_equation_system;
400
402 auto& minus_delta_x =
405
406 bool error_norms_met = false;
407
408 // TODO be more efficient
409 // init minus_delta_x to the right size
411
412 _convergence_criterion->preFirstIteration();
413
415
416 int iteration = 1;
417#if !defined(USE_PETSC) && !defined(USE_LIS)
419#endif
420 for (; iteration <= _maxiter; ++iteration, _convergence_criterion->reset())
421 {
423 double time_dirichlet = 0.0;
424
426 INFO("Iteration #{:d} started.", iteration);
427 time_iteration.start();
428
429 timer_dirichlet.start();
430 sys.computeKnownSolutions(*x[process_id], process_id);
431 time_dirichlet += timer_dirichlet.elapsed();
432
433 sys.preIteration(iteration, *x[process_id]);
434
436 time_assembly.start();
437 bool mpi_rank_assembly_ok = true;
438 try
439 {
440 sys.assemble(x, x_prev, process_id);
441 }
442 catch (AssemblyException const& e)
443 {
444 ERR("Abort nonlinear iteration. Repeating timestep. Reason: {:s}",
445 e.what());
446 error_norms_met = false;
448 mpi_rank_assembly_ok = false;
449 }
451 {
452 break;
453 }
454 sys.getResidual(*x[process_id], *x_prev[process_id], res);
455 sys.getJacobian(J);
457 {
458 J.addToDiagonal(_tikhonov_lambda);
459 }
460 INFO("[time] Assembly took {:g} s.", time_assembly.elapsed());
461
462 // Subtract non-equilibrium initial residuum if set
463 if (_r_neq != nullptr)
464 {
465 LinAlg::axpy(res, -1, *_r_neq);
466 }
467
468 minus_delta_x.setZero();
469
470 timer_dirichlet.start();
471 sys.applyKnownSolutionsNewton(J, res, *x[process_id], minus_delta_x);
472 time_dirichlet += timer_dirichlet.elapsed();
473 INFO("[time] Applying Dirichlet BCs took {:g} s.", time_dirichlet);
474
475 if (!sys.isLinear() && _convergence_criterion->hasResidualCheck())
476 {
477 _convergence_criterion->checkResidual(res);
478 }
479
481 time_linear_solver.start();
482#if !defined(USE_PETSC) && !defined(USE_LIS)
485 {
490 }
491 else if (_tikhonov_lambda > 0.0 &&
493 {
494 // Force a refactorization so the newly added regularization term
495 // is actually used by the linear solve instead of being
496 // discarded by a reused, unregularized factorization.
499 }
500
501 bool iteration_succeeded = false;
503 {
504 ERR("Newton: The linear solver failed in the compute() step.");
505 }
506 else
507 {
509 }
510#else
512#endif
513 INFO("[time] Linear solver took {:g} s.", time_linear_solver.elapsed());
514
516 {
517 ERR("Newton: The linear solver failed.");
518 }
519 else
520 {
521 // TODO could be solved in a better way
522 // cf.
523 // https://petsc.org/release/manualpages/Vec/VecWAXPY
524
525 // Copy pointers, replace the one for the given process id.
530 auto const step_result = _step_strategy->applyStep(
533
534 if (step_result.step_length != 1.0)
535 {
536 INFO("Step length: {:g}", step_result.step_length);
537 }
538
539 if (!step_result.success)
540 {
541 ERR("Newton: step strategy failed.");
542 iteration_succeeded = false;
543 }
544 else if (!step_result.x_new_is_set)
545 {
547 }
548
550 {
552 }
553
554 switch (sys.postIteration(*x_new[process_id]))
555 {
557 break;
559 ERR("Newton: The postIteration() hook reported a "
560 "non-recoverable error.");
561 iteration_succeeded = false;
562 break;
564 INFO(
565 "Newton: The postIteration() hook decided that this "
566 "iteration has to be repeated.");
567 // TODO introduce some onDestroy hook.
569 *x_new[process_id]);
570 continue; // That throws the iteration result away.
571 }
572
574 *x[process_id]); // copy new solution to x
576 *x_new[process_id]);
577 }
578
580 {
581 // Don't compute further error norms, but break here.
582 error_norms_met = false;
583 break;
584 }
585
586 if (sys.isLinear())
587 {
588 error_norms_met = true;
589 }
590 else
591 {
592 if (_convergence_criterion->hasDeltaXCheck())
593 {
594 // Note: x contains the new solution!
596 *x[process_id]);
597 }
598
600 }
601
602 INFO("[time] Iteration #{:d} took {:g} s.", iteration,
603 time_iteration.elapsed());
604
605 if (error_norms_met)
606 {
607 break;
608 }
609
610 // Avoid increment of the 'iteration' if the error norms are not met,
611 // but maximum number of iterations is reached.
612 if (iteration >= _maxiter)
613 {
614 break;
615 }
616 }
617
618 if (iteration > _maxiter)
619 {
620 ERR("Newton: Could not solve the given nonlinear system within {:d} "
621 "iterations",
622 _maxiter);
623 }
624
628
629 return {error_norms_met, iteration};
630}
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
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:30
void axpy(PETScVector &y, PetscScalar const a, PETScVector const &x)
Definition LinAlg.cpp:50

References NonlinearSolver(), _convergence_criterion, _equation_system, _J_id, _linear_solver, _maxiter, _minus_delta_x_id, _r_neq, _recompute_jacobian, _res_id, _step_strategy, _tikhonov_lambda, _tikhonov_starting_iteration, _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 165 of file NonlinearSolver.h.

Referenced by calculateNonEquilibriumInitialResiduum(), and compensateNonEquilibriumInitialResiduum().

◆ _convergence_criterion

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

Convergence criterion used to terminate the Newton iteration.

Definition at line 146 of file NonlinearSolver.h.

Referenced by setEquationSystem(), 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 153 of file NonlinearSolver.h.

Referenced by solve().

◆ _linear_solver

Definition at line 137 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 140 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 154 of file NonlinearSolver.h.

Referenced by solve().

◆ _r_neq

non-equilibrium initial residuum.

Definition at line 151 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 157 of file NonlinearSolver.h.

Referenced by calculateNonEquilibriumInitialResiduum().

◆ _recompute_jacobian

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

Recompute Jacobian every this many steps.

Definition at line 148 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 152 of file NonlinearSolver.h.

Referenced by solve().

◆ _step_strategy

std::unique_ptr<NewtonStepStrategy> NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_step_strategy
private

Globalization / step-acceptance strategy (e.g. fixed damping).

Definition at line 143 of file NonlinearSolver.h.

Referenced by NonlinearSolver(), setEquationSystem(), and solve().

◆ _tikhonov_lambda

double NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_tikhonov_lambda = 0.0
private

Tikhonov regularization parameter.

Definition at line 166 of file NonlinearSolver.h.

Referenced by setTikhonovLambda(), and solve().

◆ _tikhonov_starting_iteration

int NumLib::NonlinearSolver< NonlinearSolverTag::Newton >::_tikhonov_starting_iteration
private
Initial value:
=
0

Starting iteration for Tikhonov regularization.

Definition at line 167 of file NonlinearSolver.h.

Referenced by setTikhonovLambda(), and 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 155 of file NonlinearSolver.h.

Referenced by solve().


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