version 3.11-dev
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts

The Newton solver and the related parameters. This describes the reference implementation Dumux::NewtonSolver. More...

Description

The Newton solver and the related parameters. This describes the reference implementation Dumux::NewtonSolver.

Newton's method

The following describes Newton's method and the reference implementation Dumux::NewtonSolver of a multi-dimensional Newton solver to solve a non-linear system of equations in DuMux. For solving nonlinear equations with only one unknown, DuMux also provides Dumux::findScalarRootNewton and Dumux::findScalarRootBrent.

We assume that the equations (in DuMux usually the discretized partial differential equations) are formulated as a residual equation:

F(u)=r=0

with the residual operator F:RnR, n is the number of equations, uRn is the vector of unknowns, and rRn is the residual vector.

The goal of Newton's method is to find a vector u such that the residual equation is fulfilled (at least to a good enough approximation F(u)0 as we will discuss below).

Newton's method is an iterative algorithm: it generates a sequence of approximations, uk, that converges (under some circumstances) to the vector u, that satisfies F(u)=0. We start with an initial guess u0 and calculate the initial residual r0=F(u0). Then, we calculate the derivative of the residual operator with respect to the unknowns, the Jacobian matrix, J:RnRn evaluated at uk (in the first step k=0):

J(uk)=F(u)u|u=uk

Note
Computing the residual operator F and the Jacobian matrix J is delegated to the assembler implementation (see e.g. Dumux::FVAssembler). Typically with DuMux, the Jacobian matrix is approximated by finite differences but the implementation of Newton's method in Dumux::NewtonSolver is independent of the way the Jacobian is calculated. The C++ type of the Assembler is a template parameter of Dumux::NewtonSolver and and instance of the assembler must be passed to the Newton solver in its constructor Dumux::NewtonSolver::NewtonSolver.

This allows to compute a tangent direction of residual surface in n-dimensional space as

Δu=ukuk+1=J(uk)1rk

Note
Evaluating Δu is equivalent to solving the linear system

J(uk)Δu=rk

This task is delegated to a linear solver (see e.g. Dumux::LinearSolver) which is passed the Jacobian matrix and the residual vector computed by the assembler earlier. The C++ type of the LinearSolver is a template parameter of Dumux::NewtonSolver and and instance of the linear solver must be passed to the Newton solver in its constructor Dumux::NewtonSolver::NewtonSolver.

With the tangent direction Δu (also called the "update" vector), we update our current approximation uk to get a new approximation uk+1:

uk+1=ukΔu

Note
The update can be customized by a user-defined update strategy or by choosing from the implemented strategies (see below for more details).

This is one Newton step (or iteration). We repeat the steps of calculating the residual and the Jacobian matrix, solve the linear system, and update the approximation until we reach a good enough solution (see below for the available termination criteria).

Note
A good initial guess is crucial to get fast convergence of Newton's method. For time-dependent problems, the initial guess u0 is usually the solution of the previous time step. The initial guess is passed to the Newton solver in the method Dumux::NewtonSolver::apply and Dumux::NewtonSolver::solve.
When choosing a zero initial guess you must be aware that the assembler (based on finite difference approximations) may have difficulties to find a good epsilon to compute the finite difference approximation. In this case, you may need to help the assembler by providing an estimate of the problem-typical magnitude of the unknowns. See Dumux::FVAssembler and the parameters Assembly.NumericDifference.PriVarMagnitude and Assembly.NumericDifference.BaseEpsilon.

The Dumux::NewtonSolver reference implementation of Newton's method has several features discussed below that can be controlled by user-set parameters (e.g. via a parameter input file or the command line, see Runtime Parameters).

Update strategy

Here we describe strategies that differ from the default update strategy, that is:

uk+1=ukΔu

The different strategies can be enabled via runtime parameters as described below.

Line search

The idea of line search is to find an optimal scaling factor αR for the update vector Δu

uk+1=ukαΔu

such that the residual norm evaluated with the new iterate uk+1 that is ||rk+1|| is minimized. That means using line search the following optimization problem is solved: find α such that

α=argminα||F(uk+1αΔu)||22

The default implementation of Dumux::NewtonSolver uses a simple backtracking line search algorithm to approximately solve the above optimization problem. The algorithm is based on the following steps:

  1. Set the initial step size α=1.
  2. Compute the residual norm ||rk+1||=||F(uk+1αΔu)||22.
  3. If the residual norm is smaller than ||rk|| (the norm of the previous residual), α is accepted and the algorithm terminates. Otherwise, alpha is reduced by a factor Newton.LineSearchReductionFactor (default value 0.5) and we continue with step 2 unless α is smaller or equal the Newton.LineSearchMinRelaxationFactor (default value 0.125) in which we accept the step size, even if the residual norm increased.
Note
To customize the line search strategy, create a new class derived from Dumux::NewtonSolver and override the private virtual method Dumux::NewtonSolver::lineSearchUpdate_. Activate line search update by setting the parameter Newton.UseLineSearch = true.

Chopped update

For instance in problems where the residual has multiple roots, it can be beneficial to restrict the search space to a certain region in the parameter space. This can be achieved by a chopped update strategy, where the solution vector is projected back to a feasible region after each Newton step. A chopped update strategy can be enabled by setting Newton.EnableChop = true. As such strategies are usually problem-dependent, there is no default implementation. The parameter will merely active the hook Dumux::NewtonSolver::choppedUpdate_ which can be overridden in a derived class, see Dumux::RichardsNewtonSolver for an example implementation using this strategy.

Note
To customize the chop update strategy, create a new class derived from Dumux::NewtonSolver and override the private virtual method Dumux::NewtonSolver::choppedUpdate_. Activate the chopped update strategy by setting the parameter Newton.EnableChop = true. The line search and chopped update are mutually exclusive, i.e. if Newton.UseLineSearch is set to true, the Newton.EnableChop parameter will be ignored.

Termination criteria

Newton's method finds an approximate solution to the residual equation F(uk)0. But when is the solution "good enough"? A good criterion makes sure that the residual is small enough but should also be easy to compute. Dumux::NewtonSolver provides several termination criteria.

The default is the relative shift criterion in addition to bounds on the minimum and maximum number of iterations. The solver never terminates if k is smaller than Newton.MinSteps (default value 2). The solver always terminates if k is larger than Newton.MaxSteps (default value 18). Dumux::NewtonSolver::apply returns a boolean value indicating whether the solver converged or not; Dumux::NewtonSolver::solve throws Dumux::NumericalProblem is the solver did not converge.

Relative shift criterion

This criterion is enabled per default. The idea is to terminate the algorithm when the solution vector does not change significantly between iterations. This criterion does not check the actual residual but is useful in practice and fast to compute. We compute the maximum difference of any degree of freedom (entry of the vector uk+1) between the current and the previous iteration. This uses the criterion

maxi=1,,n(|uk+1,iuk,i|max{1.0,|uk+1,i+uk,i|0.5})<ϵshift

where uk,i is the i-th entry of the vector uk and ϵshift is a user-defined parameter Newton.MaxRelativeShift (default value 108). The relative shift criterion can be disabled by setting Newton.EnableShiftCriterion = false. The relative shift criterion can be combined with a residual criterion (see below) by enabling a residual criterion without disabling the shift criterion. By default the Newton solver terminates when either of the criteria are fulfilled. If you want to require both criteria to be fulfilled, you can do so by setting Newton.SatisfyResidualAndShiftCriterion = true.

Relative residual norm criterion

This criterion is disabled by default. It can be enabled by setting Newton.EnableResidualCriterion = true. The idea is to terminate the algorithm when the norm of the residual vector is small in comparison to the initial residual norm. The relative residual norm criterion checks if

||rk+1||22||r0||22<ϵr,rel2,

where ||rk+1|| is the norm of the residual vector at iteration k+1 and ||r0|| is the norm of the residual vector at iteration 0. The parameter Newton.ResidualReduction (default value 105) defines the threshold ϵr,rel.

Absolute residual norm criterion

This criterion is disabled by default. The idea is to terminate the algorithm when norm of the residual vector is small enough in comparison with a given absolute threshold. This requires knowledge about the problem because the magnitude of the residual vector has to be estimated. The criterion is enabled by setting Newton.EnableAbsoluteResidualCriterion = true and Newton.EnableResidualCriterion = true. It checks if

||rk+1||22<ϵr,abs2,

where ||rk+1|| is the norm of the residual vector at iteration k+1 and ϵr,abs is a user-defined parameter Newton.MaxAbsoluteResidual (default value 105). The absolute residual norm criterion can be combined with a relative shift criterion by enabling both criteria.

Adaptive time stepping

The extended interface Dumux::NewtonSolver::solve with time loop in the signature provides an automated adaptive time stepping strategy. The idea is retry the entire algorithm with a lower the time step size if the Newton solver fails to converge. This is repeated until the Newton solver either converges or the maximum number of allowed retry steps is reached.

The factor by which the time step size is reduced after each non-converged try is set by the parameter Newton.RetryTimeStepReductionFactor (default value 0.5). The maximum number of retries is set by the parameter Newton.MaxTimeStepDivisions (default value 10). If the maximum number of retries is reached, the a Dumux::NumericalProblem is thrown.

Finally, Dumux::NewtonSolver::suggestTimeStepSize suggest a new time-step size based on the current time-step size and the convergence history of the Newton solver. In particular, the implemented heuristic determines how much the time step size is adjusted depends on how far away the Newton is from converging within m iterations, where m is set by the parameter Newton.TargetSteps (default value 10).

Partial reassembly (Quasi-Newton method)

Technically, when using a finite difference approximation of the Jacobian, we use a so-called quasi-Newton method for which the Jacobian matrix is replaced by an approximation. Another strategy is useful for simulations where the Jacobian matrix is expensive to compute but not all degrees of freedom are expected to change significantly between iterations (for example if changes only happen in parts of the simulation domain).

If supported by the assembler (e.g. Dumux::FVAssembler), the Newton solver can tell the assembler to only recompute those entries of the Jacobian matrix that are associated with primary variables that have changed significantly. This strategy is enabled via the parameter Newton.EnablePartialReassembly (default value is false).

The threshold for the partial reassembly is computed can also be controlled via parameters. The threshold θr for each entry is computed as

θr=max(θmin,min(θmax,ωϵshift))

where θmin is set by Newton.ReassemblyMinThreshold (default value 101Δushift) and θmax is set by Newton.ReassemblyMaxThreshold (default value 102Δushift), ω is a weight (default value 103), and ϵshift is the maximum relative shift threshold parameter (Newton.MaxRelativeShift) described above.

Primary variable switching

Switching primary variables during Newton's method is a form of nonlinear preconditioning. We solve an alternative problem with different primary variables where the hope that the root is easier to find. This can be, for instance, because the finite difference approximation of the Jacobian is numerically better conditioned in the new variables. The strategy depends on the problem at hand. For an example, see for instance 2pnc for a model with activated primary variable switch.


🛠 Edit above doc on GitLab

Files

file  multidomain/newtonconvergencewriter.hh
 This class provides the infrastructure to write the convergence behaviour of the Newton method for multidomain simulations into a VTK file.
 
file  multidomain/newtonsolver.hh
 
file  nonlinear/newtonconvergencewriter.hh
 This class provides the infrastructure to write the convergence behaviour of the newton method into a VTK file.
 
file  nonlinear/newtonsolver.hh
 Reference implementation of a Newton solver.
 
file  staggerednewtonconvergencewriter.hh
 This class provides the infrastructure to write the convergence behaviour of the newton method for the staggered discretization scheme into a VTK file.
 

Classes

class  Dumux::MultiDomainNewtonConvergenceWriter< MDTraits >
 Writes the intermediate solutions for every Newton iteration. More...
 
class  Dumux::MultiDomainNewtonSolver< Assembler, LinearSolver, CouplingManager, Reassembler, Comm >
 Newton solver for coupled problems. More...
 
struct  Dumux::ConvergenceWriterInterface< SolutionVector, ResidualVector >
 A convergence writer interface Provide an interface that show the minimal requirements a convergence write passed to a newton method has to fulfill. More...
 
class  Dumux::NewtonConvergenceWriter< GridGeometry, SolutionVector, ResidualVector >
 Writes the intermediate solutions for every Newton iteration. More...
 
class  Dumux::NewtonSolver< Assembler, LinearSolver, Reassembler, Comm >
 An implementation of a Newton solver. The comprehensive documentation is in Newton solver, providing more details about the algorithm and the related parameters. More...
 
class  Dumux::StaggeredNewtonConvergenceWriter< GridGeometry, SolutionVector, ResidualVector >
 Writes the intermediate solutions for every Newton iteration (for staggered grid scheme) More...