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)
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

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

606{
607 if (_r_neq != nullptr)
608 {
610 }
611}
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 327 of file NonlinearSolver.cpp.

331{
333 {
334 return;
335 }
336
337 INFO("Calculate non-equilibrium initial residuum.");
338
339 _equation_system->assemble(x, x_prev, process_id);
342
343 // Set the values of the selected entries of _r_neq, which are associated
344 // with the equations that do not need initial residual compensation, to
345 // zero.
347 _equation_system->getIndicesOfResiduumWithoutInitialCompensation();
348
349#ifdef USE_PETSC
350 // Ghost entry with global index 0 is encoded as -global_size
351 // After abs(), it appears as global_size and must be converted back to 0
352 auto const global_size = _r_neq->size();
353 for (auto& idx : selected_global_indices)
354 {
355 if (idx == global_size)
356 {
357 idx = 0;
358 }
359 }
360#endif
361
364 _equation_system->setReleaseNodalForces(_r_neq, process_id);
365
367}
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.

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

375{
376 namespace LinAlg = MathLib::LinAlg;
377 auto& sys = *_equation_system;
378
380 auto& minus_delta_x =
383
384 bool error_norms_met = false;
385
386 // TODO be more efficient
387 // init minus_delta_x to the right size
389
390 _convergence_criterion->preFirstIteration();
391
393
394 int iteration = 1;
395#if !defined(USE_PETSC) && !defined(USE_LIS)
397#endif
398 for (; iteration <= _maxiter; ++iteration, _convergence_criterion->reset())
399 {
401 double time_dirichlet = 0.0;
402
404 INFO("Iteration #{:d} started.", iteration);
405 time_iteration.start();
406
407 timer_dirichlet.start();
408 sys.computeKnownSolutions(*x[process_id], process_id);
409 time_dirichlet += timer_dirichlet.elapsed();
410
411 sys.preIteration(iteration, *x[process_id]);
412
414 time_assembly.start();
415 bool mpi_rank_assembly_ok = true;
416 try
417 {
418 sys.assemble(x, x_prev, process_id);
419 }
420 catch (AssemblyException const& e)
421 {
422 ERR("Abort nonlinear iteration. Repeating timestep. Reason: {:s}",
423 e.what());
424 error_norms_met = false;
426 mpi_rank_assembly_ok = false;
427 }
429 {
430 break;
431 }
432 sys.getResidual(*x[process_id], *x_prev[process_id], res);
433 sys.getJacobian(J);
434 INFO("[time] Assembly took {:g} s.", time_assembly.elapsed());
435
436 // Subtract non-equilibrium initial residuum if set
437 if (_r_neq != nullptr)
438 {
439 LinAlg::axpy(res, -1, *_r_neq);
440 }
441
442 minus_delta_x.setZero();
443
444 timer_dirichlet.start();
445 sys.applyKnownSolutionsNewton(J, res, *x[process_id], minus_delta_x);
446 time_dirichlet += timer_dirichlet.elapsed();
447 INFO("[time] Applying Dirichlet BCs took {:g} s.", time_dirichlet);
448
449 if (!sys.isLinear() && _convergence_criterion->hasResidualCheck())
450 {
451 _convergence_criterion->checkResidual(res);
452 }
453
455 time_linear_solver.start();
456#if !defined(USE_PETSC) && !defined(USE_LIS)
459 {
464 }
465
466 bool iteration_succeeded = false;
468 {
469 ERR("Newton: The linear solver failed in the compute() step.");
470 }
471 else
472 {
474 }
475#else
477#endif
478 INFO("[time] Linear solver took {:g} s.", time_linear_solver.elapsed());
479
481 {
482 ERR("Newton: The linear solver failed.");
483 }
484 else
485 {
486 // TODO could be solved in a better way
487 // cf.
488 // https://petsc.org/release/manualpages/Vec/VecWAXPY
489
490 // Copy pointers, replace the one for the given process id.
495 auto const step_result = _step_strategy->applyStep(
498
499 if (step_result.step_length != 1.0)
500 {
501 INFO("Step length: {:g}", step_result.step_length);
502 }
503
504 if (!step_result.success)
505 {
506 ERR("Newton: step strategy failed.");
507 iteration_succeeded = false;
508 }
509 else if (!step_result.x_new_is_set)
510 {
512 }
513
515 {
517 }
518
519 switch (sys.postIteration(*x_new[process_id]))
520 {
522 break;
524 ERR("Newton: The postIteration() hook reported a "
525 "non-recoverable error.");
526 iteration_succeeded = false;
527 break;
529 INFO(
530 "Newton: The postIteration() hook decided that this "
531 "iteration has to be repeated.");
532 // TODO introduce some onDestroy hook.
534 *x_new[process_id]);
535 continue; // That throws the iteration result away.
536 }
537
539 *x[process_id]); // copy new solution to x
541 *x_new[process_id]);
542 }
543
545 {
546 // Don't compute further error norms, but break here.
547 error_norms_met = false;
548 break;
549 }
550
551 if (sys.isLinear())
552 {
553 error_norms_met = true;
554 }
555 else
556 {
557 if (_convergence_criterion->hasDeltaXCheck())
558 {
559 // Note: x contains the new solution!
561 *x[process_id]);
562 }
563
565 }
566
567 INFO("[time] Iteration #{:d} took {:g} s.", iteration,
568 time_iteration.elapsed());
569
570 if (error_norms_met)
571 {
572 break;
573 }
574
575 // Avoid increment of the 'iteration' if the error norms are not met,
576 // but maximum number of iterations is reached.
577 if (iteration >= _maxiter)
578 {
579 break;
580 }
581 }
582
583 if (iteration > _maxiter)
584 {
585 ERR("Newton: Could not solve the given nonlinear system within {:d} "
586 "iterations",
587 _maxiter);
588 }
589
593
594 return {error_norms_met, iteration};
595}
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, _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 159 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 140 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 147 of file NonlinearSolver.h.

Referenced by solve().

◆ _linear_solver

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

Referenced by solve().

◆ _r_neq

non-equilibrium initial residuum.

Definition at line 145 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 151 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 142 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 146 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 137 of file NonlinearSolver.h.

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

Referenced by solve().


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