11.1. The SUNNonlinearSolver API
The SUNNonlinSol API defines several nonlinear solver operations that enable
SUNDIALS integrators to utilize any SUNNonlinSol implementation that
provides the required functions. These functions can be divided into three
categories. The first are the core nonlinear solver functions. The second
consists of “set” routines to supply the nonlinear solver with
functions provided by the SUNDIALS time integrators and to modify solver
parameters. The final group consists of “get” routines for retrieving nonlinear
solver statistics. All of these functions are defined in the header file
sundials/sundials_nonlinearsolver.h
.
11.1.1. SUNNonlinearSolver core functions
The core nonlinear solver functions consist of two required functions to get the
nonlinear solver type (SUNNonlinSolGetType()
) and solve the nonlinear system
(SUNNonlinSolSolve()
). The remaining three functions for nonlinear solver
initialization (SUNNonlinSolInitialize()
), setup
(SUNNonlinSolSetup()
), and destruction (SUNNonlinSolFree()
) are optional.
-
enum SUNNonlinearSolver_Type
An identifier indicating the form of the nonlinear system expected by the nonlinear solver.
-
enumerator SUNNONLINEARSOLVER_ROOTFIND
The nonlinear solver expects systems in rootfinding form \(F(y) = 0\)
-
enumerator SUNNONLINEARSOLVER_FIXEDPOINT
The nonlinear solver expects systems in fixed-point form \(G(y) = y\).
-
enumerator SUNNONLINEARSOLVER_ROOTFIND
-
SUNNonlinearSolver_Type SUNNonlinSolGetType(SUNNonlinearSolver NLS)
This required function returns the nonlinear solver type.
- Arguments:
NLS – a SUNNonlinSol object.
- Return value:
The
SUNNonlinearSolver_Type
type identifier for the nonlinear solver.
-
SUNErrCode SUNNonlinSolInitialize(SUNNonlinearSolver NLS)
This optional function handles nonlinear solver initialization and may perform any necessary memory allocations.
- Arguments:
NLS – a SUNNonlinSol object.
- Return value:
A
SUNErrCode
.- Notes:
It is assumed all solver-specific options have been set prior to calling
SUNNonlinSolInitialize()
. SUNNonlinSol implementations that do not require initialization may set this operation toNULL
.
-
SUNErrCode SUNNonlinSolSetup(SUNNonlinearSolver NLS, N_Vector y, void *mem)
This optional function performs any solver setup needed for a nonlinear solve.
- Arguments:
NLS – a SUNNonlinSol object.
y – the initial guess passed to the nonlinear solver.
mem – the SUNDIALS integrator memory structure.
- Return value:
A
SUNErrCode
.- Notes:
SUNDIALS integrators call
SUNNonlinSolSetup()
before each step attempt. SUNNonlinSol implementations that do not require setup may set this operation toNULL
.
-
int SUNNonlinSolSolve(SUNNonlinearSolver NLS, N_Vector y0, N_Vector ycor, N_Vector w, sunrealtype tol, sunbooleantype callLSetup, void *mem)
This required function solves the nonlinear system \(F(y)=0\) or \(G(y)=y\).
- Arguments:
NLS – a SUNNonlinSol object.
y0 – the predicted value for the new solution state. This must remain unchanged throughout the solution process.
ycor – on input the initial guess for the correction to the predicted state (zero) and on output the final correction to the predicted state.
w – the solution error weight vector used for computing weighted error norms.
tol – the requested solution tolerance in the weighted root-mean-squared norm.
callLSetup – a flag indicating that the integrator recommends for the linear solver setup function to be called.
mem – the SUNDIALS integrator memory structure.
- Return value:
The return value is zero for a successul solve, a positive value for a recoverable error (i.e., the solve failed and the integrator should reduce the step size and reattempt the step), and a negative value for an unrecoverable error (i.e., the solve failed the and the integrator should halt and return an error to the user).
-
SUNErrCode SUNNonlinSolFree(SUNNonlinearSolver NLS)
This optional function frees any memory allocated by the nonlinear solver.
- Arguments:
NLS – a SUNNonlinSol object.
- Return value:
11.1.2. SUNNonlinearSolver “set” functions
The following functions are used to supply nonlinear solver modules with
functions defined by the SUNDIALS integrators and to modify solver
parameters. Only the routine for setting the nonlinear system defining function
(SUNNonlinSolSetSysFn()
) is required. All other set functions are optional.
-
SUNErrCode SUNNonlinSolSetSysFn(SUNNonlinearSolver NLS, SUNNonlinSolSysFn SysFn)
This required function is used to provide the nonlinear solver with the function defining the nonlinear system. This is the function \(F(y)\) in \(F(y)=0\) for
SUNNONLINEARSOLVER_ROOTFIND
modules or \(G(y)\) in \(G(y)=y\) forSUNNONLINEARSOLVER_FIXEDPOINT
modules.- Arguments:
NLS – a SUNNonlinSol object.
SysFn – the function defining the nonlinear system. See §11.1.4 for the definition of
SUNNonlinSolSysFn
.
- Return value:
-
SUNErrCode SUNNonlinSolSetLSetupFn(SUNNonlinearSolver NLS, SUNNonlinSolLSetupFn SetupFn)
This optional function is called by SUNDIALS integrators to provide the nonlinear solver with access to its linear solver setup function.
- Arguments:
NLS – a SUNNonlinSol object.
SetupFn – a wrapper function to the SUNDIALS integrator’s linear solver setup function. See §11.1.4 for the definition of
SUNNonlinSolLSetupFn
.
- Return value:
- Notes:
The
SUNNonlinSolLSetupFn
function sets up the linear system \(Ax=b\) where \(A = \frac{\partial F}{\partial y}\) is the linearization of the nonlinear residual function \(F(y) = 0\) (when using SUNLinSol direct linear solvers) or calls the user-defined preconditioner setup function (when using SUNLinSol iterative linear solvers). SUNNonlinSol implementations that do not require solving this system, do not utilize SUNLinSol linear solvers, or use SUNLinSol linear solvers that do not require setup may set this operation toNULL
.
-
SUNErrCode SUNNonlinSolSetLSolveFn(SUNNonlinearSolver NLS, SUNNonlinSolLSolveFn SolveFn)
This optional function is called by SUNDIALS integrators to provide the nonlinear solver with access to its linear solver solve function.
- Arguments:
NLS – a SUNNonlinSol object.
SolveFn – a wrapper function to the SUNDIALS integrator’s linear solver solve function. See §11.1.4 for the definition of
SUNNonlinSolLSolveFn
.
- Return value:
- Notes:
The
SUNNonlinSolLSolveFn
function solves the linear system \(Ax=b\) where \(A = \frac{\partial F}{\partial y}\) is the linearization of the nonlinear residual function \(F(y) = 0\). SUNNonlinSol implementations that do not require solving this system or do not use SUNLinSol linear solvers may set this operation toNULL
.
-
SUNErrCode SUNNonlinSolSetConvTestFn(SUNNonlinearSolver NLS, SUNNonlinSolConvTestFn CTestFn, void *ctest_data)
This optional function is used to provide the nonlinear solver with a function for determining if the nonlinear solver iteration has converged. This is typically called by SUNDIALS integrators to define their nonlinear convergence criteria, but may be replaced by the user.
- Arguments:
NLS – a SUNNonlinSol object.
CTestFn – a SUNDIALS integrator’s nonlinear solver convergence test function. See §11.1.4 for the definition of
SUNNonlinSolConvTestFn
.ctest_data – is a data pointer passed to CTestFn every time it is called.
- Return value:
- Notes:
SUNNonlinSol implementations utilizing their own convergence test criteria may set this function to
NULL
.
-
SUNErrCode SUNNonlinSolSetMaxIters(SUNNonlinearSolver NLS, int maxiters)
This optional function sets the maximum number of nonlinear solver iterations. This is typically called by SUNDIALS integrators to define their default iteration limit, but may be adjusted by the user.
- Arguments:
NLS – a SUNNonlinSol object.
maxiters – the maximum number of nonlinear iterations.
- Return value:
11.1.3. SUNNonlinearSolver “get” functions
The following functions allow SUNDIALS integrators to retrieve nonlinear
solver statistics. The routines to get the number of iterations in the most
recent solve (SUNNonlinSolGetNumIters()
) and number of convergence failures
are optional. The routine to get the current nonlinear solver iteration
(SUNNonlinSolGetCurIter()
) is required when using the convergence test
provided by the SUNDIALS integrator or when using an iterative SUNLinSol
linear solver module; otherwise SUNNonlinSolGetCurIter()
is optional.
-
SUNErrCode SUNNonlinSolGetNumIters(SUNNonlinearSolver NLS, long int *niters)
This optional function returns the number of nonlinear solver iterations in the most recent solve. This is typically called by the SUNDIALS integrator to store the nonlinear solver statistics, but may also be called by the user.
- Arguments:
NLS – a SUNNonlinSol object.
niters – the total number of nonlinear solver iterations.
- Return value:
-
SUNErrCode SUNNonlinSolGetCurIter(SUNNonlinearSolver NLS, int *iter)
This function returns the iteration index of the current nonlinear solve. This function is required when using SUNDIALS integrator-provided convergence tests or when using an iterative SUNLinSol linear solver module; otherwise it is optional.
- Arguments:
NLS – a SUNNonlinSol object.
iter – the nonlinear solver iteration in the current solve starting from zero.
- Return value:
-
SUNErrCode SUNNonlinSolGetNumConvFails(SUNNonlinearSolver NLS, long int *nconvfails)
This optional function returns the number of nonlinear solver convergence failures in the most recent solve. This is typically called by the SUNDIALS integrator to store the nonlinear solver statistics, but may also be called by the user.
- Arguments:
NLS – a SUNNonlinSol object.
nconvfails – the total number of nonlinear solver convergence failures.
- Return value:
11.1.4. Functions provided by SUNDIALS integrators
To interface with SUNNonlinSol modules, the SUNDIALS integrators
supply a variety of routines for evaluating the nonlinear system,
calling the SUNLinSol setup and solve functions, and testing the
nonlinear iteration for convergence. These integrator-provided routines
translate between the user-supplied ODE or DAE systems and the generic
interfaces to the nonlinear or linear systems of equations that result
in their solution. The functions provided to a SUNNonlinSol
module have types defined in the header file
sundials/sundials_nonlinearsolver.h
; these are also described below.
-
typedef int (*SUNNonlinSolSysFn)(N_Vector ycor, N_Vector F, void *mem)
These functions evaluate the nonlinear system \(F(y)\) for
SUNNONLINEARSOLVER_ROOTFIND
type modules or \(G(y)\) forSUNNONLINEARSOLVER_FIXEDPOINT
type modules. Memory for F must by be allocated prior to calling this function. The vector ycor will be left unchanged.- Arguments:
ycor – is the current correction to the predicted state at which the nonlinear system should be evaluated.
F – is the output vector containing \(F(y)\) or \(G(y)\), depending on the solver type.
mem – is the SUNDIALS integrator memory structure.
- Return value:
The return value is zero for a successul solve, a positive value for a recoverable error, and a negative value for an unrecoverable error.
- Notes:
SUNDIALS integrators formulate nonlinear systems as a function of the correction to the predicted solution. On each call to the nonlinear system function the integrator will compute and store the current solution based on the input correction. Additionally, the residual will store the value of the ODE right-hand side function or DAE residual used in computing the nonlinear system. These stored values are then directly used in the integrator-supplied linear solver setup and solve functions as applicable.
-
typedef int (*SUNNonlinSolLSetupFn)(sunbooleantype jbad, sunbooleantype *jcur, void *mem)
These functions are wrappers to the SUNDIALS integrator’s function for setting up linear solves with SUNLinSol modules.
- Arguments:
jbad – is an input indicating whether the nonlinear solver believes that \(A\) has gone stale (
SUNTRUE
) or not (SUNFALSE
).jcur – is an output indicating whether the routine has updated the Jacobian \(A\) (
SUNTRUE
) or not (SUNFALSE
).mem – is the SUNDIALS integrator memory structure.
- Return value:
The return value is zero for a successul solve, a positive value for a recoverable error, and a negative value for an unrecoverable error.
- Notes:
The
SUNNonlinSolLSetupFn
function sets up the linear system \(Ax=b\) where \(A = \frac{\partial F}{\partial y}\) is the linearization of the nonlinear residual function \(F(y) = 0\) (when using SUNLinSol direct linear solvers) or calls the user-defined preconditioner setup function (when using SUNLinSol iterative linear solvers). SUNNonlinSol implementations that do not require solving this system, do not utilize SUNLinSol linear solvers, or use SUNLinSol linear solvers that do not require setup may ignore these functions.As discussed in the description of
SUNNonlinSolSysFn
, the linear solver setup function assumes that the nonlinear system function has been called prior to the linear solver setup function as the setup will utilize saved values from the nonlinear system evaluation (e.g., the updated solution).
-
typedef int (*SUNNonlinSolLSolveFn)(N_Vector b, void *mem)
These functions are wrappers to the SUNDIALS integrator’s function for solving linear systems with SUNLinSol modules.
- Arguments:
b – contains the right-hand side vector for the linear solve on input and the solution to the linear system on output.
mem – is the SUNDIALS integrator memory structure.
- Return value:
The return value is zero for a successul solve, a positive value for a recoverable error, and a negative value for an unrecoverable error.
- Notes:
The
SUNNonlinSolLSolveFn
function solves the linear system \(Ax=b\) where \(A = \frac{\partial F}{\partial y}\) is the linearization of the nonlinear residual function \(F(y) = 0\). SUNNonlinSol implementations that do not require solving this system or do not use SUNLinSol linear solvers may ignore these functions.As discussed in the description of
SUNNonlinSolSysFn
, the linear solver solve function assumes that the nonlinear system function has been called prior to the linear solver solve function as the setup may utilize saved values from the nonlinear system evaluation (e.g., the updated solution).
-
typedef int (*SUNNonlinSolConvTestFn)(SUNNonlinearSolver NLS, N_Vector ycor, N_Vector del, sunrealtype tol, N_Vector ewt, void *ctest_data)
These functions are SUNDIALS integrator-specific convergence tests for nonlinear solvers and are typically supplied by each SUNDIALS integrator, but users may supply custom problem-specific versions as desired.
- Arguments:
NLS – is the SUNNonlinSol object.
ycor – is the current correction (nonlinear iterate).
del – is the difference between the current and prior nonlinear iterates.
tol – is the nonlinear solver tolerance.
ewt – is the weight vector used in computing weighted norms.
ctest_data – is the data pointer provided to
SUNNonlinSolSetConvTestFn()
.
- Return value:
The return value of this routine will be a negative value if an unrecoverable error occurred or one of the following:
SUN_SUCCESS
– the iteration is converged.SUN_NLS_CONTINUE
– the iteration has not converged, keep iterating.SUN_NLS_CONV_RECVR
– the iteration appears to be diverging, try to recover.
- Notes:
The tolerance passed to this routine by SUNDIALS integrators is the tolerance in a weighted root-mean-squared norm with error weight vector
ewt
. SUNNonlinSol modules utilizing their own convergence criteria may ignore these functions.
11.1.5. SUNNonlinearSolver return codes
The functions provided to SUNNonlinSol modules by each SUNDIALS integrator, and functions within the SUNDIALS-provided SUNNonlinSol implementations, utilize a common set of return codes shown in Table 11.1. Here, negative values correspond to non-recoverable failures, positive values to recoverable failures, and zero to a successful call.
Name |
Value |
Description |
---|---|---|
SUN_SUCCESS |
0 |
successful call or converged solve |
SUN_NLS_CONTINUE |
901 |
the nonlinear solver is not converged, keep iterating |
SUN_NLS_CONV_RECVR |
902 |
the nonlinear solver appears to be diverging, try to recover |
11.1.6. The generic SUNNonlinearSolver module
SUNDIALS integrators interact with specific SUNNonlinSol
implementations through the generic SUNNonlinSol module on which all
other SUNNonlinSol implementations are built. The
SUNNonlinearSolver
type is a pointer to a structure containing an
implementation-dependent content field and an ops
field.
A SUNNonlinearSolver
is a pointer to the
_generic_SUNNonlinearSolver
structure:
-
typedef struct _generic_SUNNonlinearSolver *SUNNonlinearSolver
-
struct _generic_SUNNonlinearSolver
The structure defining the SUNDIALS nonlinear solver class.
-
void *content
Pointer to nonlinear solver-specific member data
-
SUNNonlinearSolver_Ops ops
A virtual table of nonlinear solver operations provided by a specific implementation
-
SUNContext sunctx
The SUNDIALS simulation context
-
void *content
The virtual table structure is defined as
-
typedef struct _generic_SUNNonlinearSolver_Ops *SUNNonlinearSolver_Ops
-
struct _generic_SUNNonlinearSolver_Ops
The structure defining
SUNNonlinearSolver
operations.-
SUNNonlinearSolver_Type (*gettype)(SUNNonlinearSolver)
The function implementing
SUNNonlinSolGetType()
-
int (*initialize)(SUNNonlinearSolver)
The function implementing
SUNNonlinSolInitialize()
-
int (*setup)(SUNNonlinearSolver, N_Vector, void*)
The function implementing
SUNNonlinSolSetup()
-
int (*solve)(SUNNonlinearSolver, N_Vector, N_Vector, N_Vector, sunrealtype, sunbooleantype, void*)
The function implementing
SUNNonlinSolSolve()
-
int (*free)(SUNNonlinearSolver)
The function implementing
SUNNonlinSolFree()
-
int (*setsysfn)(SUNNonlinearSolver, SUNNonlinSolSysFn)
The function implementing
SUNNonlinSolSetSysFn()
-
int (*setlsetupfn)(SUNNonlinearSolver, SUNNonlinSolLSetupFn)
The function implementing
SUNNonlinSolSetLSetupFn()
-
int (*setlsolvefn)(SUNNonlinearSolver, SUNNonlinSolLSolveFn)
The function implementing
SUNNonlinSolSetLSolveFn()
-
int (*setctestfn)(SUNNonlinearSolver, SUNNonlinSolConvTestFn, void*)
The function implementing
SUNNonlinSolSetConvTestFn()
-
int (*setmaxiters)(SUNNonlinearSolver, int)
The function implementing
SUNNonlinSolSetMaxIters()
-
int (*getnumiters)(SUNNonlinearSolver, long int*)
The function implementing
SUNNonlinSolGetNumIters()
-
int (*getcuriter)(SUNNonlinearSolver, int*)
The function implementing
SUNNonlinSolGetCurIter()
-
int (*getnumconvfails)(SUNNonlinearSolver, long int*)
The function implementing
SUNNonlinSolGetNumConvFails()
-
SUNNonlinearSolver_Type (*gettype)(SUNNonlinearSolver)
The generic SUNNonlinSol module defines and implements the nonlinear
solver operations defined in
§11.1.1–§11.1.3.
These routines are in fact only wrappers to the nonlinear solver
operations provided by a particular SUNNonlinSol implementation,
which are accessed through the ops field of the SUNNonlinearSolver
structure. To illustrate this point we show below the implementation
of a typical nonlinear solver operation from the generic SUNNonlinSol
module, namely SUNNonlinSolSolve()
, which solves the nonlinear
system and returns a flag denoting a successful or failed solve:
int SUNNonlinSolSolve(SUNNonlinearSolver NLS,
N_Vector y0, N_Vector y,
N_Vector w, sunrealtype tol,
sunbooleantype callLSetup, void* mem)
{
return((int) NLS->ops->solve(NLS, y0, y, w, tol, callLSetup, mem));
}
11.1.7. Implementing a Custom SUNNonlinearSolver Module
A SUNNonlinSol implementation must do the following:
Specify the content of the SUNNonlinSol module.
Define and implement the required nonlinear solver operations defined in §11.1.1–§11.1.3. Note that the names of the module routines should be unique to that implementation in order to permit using more than one SUNNonlinSol module (each with different
SUNNonlinearSolver
internal data representations) in the same code.Define and implement a user-callable constructor to create a
SUNNonlinearSolver
object.
To aid in the creation of custom SUNNonlinearSolver
modules, the generic
SUNNonlinearSolver
module provides the utility functions
SUNNonlinSolNewEmpty()
and SUNNonlinSolFreeEmpty()
. When used
in custom SUNNonlinearSolver
constructors these functions will ease the
introduction of any new optional nonlinear solver operations to the
SUNNonlinearSolver
API by ensuring that only required operations need to
be set.
-
SUNNonlinearSolver SUNNonlinSolNewEmpty(SUNContext sunctx)
This function allocates a new generic
SUNNonlinearSolver
object and initializes its content pointer and the function pointers in the operations structure toNULL
.- Return value:
If successful, this function returns a
SUNNonlinearSolver
object. If an error occurs when allocating the object, then this routine will returnNULL
.
-
void SUNNonlinSolFreeEmpty(SUNNonlinearSolver NLS)
This routine frees the generic
SUNNonlinearSolver
object, under the assumption that any implementation-specific data that was allocated within the underlying content structure has already been freed. It will additionally test whether the ops pointer isNULL
, and, if it is not, it will free it as well.- Arguments:
NLS – a SUNNonlinearSolver object
Additionally, a SUNNonlinearSolver
implementation may do
the following:
Define and implement additional user-callable “set” routines acting on the
SUNNonlinearSolver
object, e.g., for setting various configuration options to tune the performance of the nonlinear solve algorithm.Provide additional user-callable “get” routines acting on the
SUNNonlinearSolver
object, e.g., for returning various solve statistics.