# Module Kinsol

module Kinsol: sig .. end
Solves nonlinear systems using Newton-Krylov techniques.

This module solves numerically problems of the form $F(u) = 0$ given an initial guess $u_0$.

This documented interface is structured as follows.

Author(s): Timothy Bourke (Inria/ENS), Jun Inoue (Inria/ENS), Marc Pouzet (UPMC/ENS/Inria)
Version: 2.7.0

type ('data, 'kind) session = ('data, 'kind) session
A session with the KINSOL solver.

An example session with Kinsol (kinsol_skel.ml):

(* 1. Define a system function. *)
let pi, e = 4. *. atan 1., exp 1.
let sysf u r =
r.{0} <- 0.5 *. sin(u.{0}*.u.{1}) -. 0.25 *. u.{1} /. pi -. 0.5 *. u.{0};
r.{1} <- (1. -. 0.25/.pi)*.(exp(2.*.u.{0})-.e) +. e*.u.{1}/.pi -. 2.*.e*.u.{0};
r.{2} <- u.{2} -. u.{0} +. 0.25;
r.{3} <- u.{3} -. u.{0} +. 1.0;
r.{4} <- u.{4} -. u.{1} +. 1.5;
r.{5} <- u.{5} -. u.{1} +. 2.0 *. pi

(* 2. Set vector with initial guess.
The length of this vector determines the problem size. *)
let ud = Sundials.RealArray.of_list [ 0.25; 1.5; 0.; -0.75; 0.; 1.5 -. 2. *.pi ]
let u = Nvector_serial.wrap ud

(* 3. Create and initialize a solver session.
This will initialize a specific linear solver. *)
let s = Kinsol.(init ~linsolv:(Dls.dense ()) sysf u);;

(* 4. Set optional inputs, e.g.,
call [set_*] functions to change solver parameters. *)
let c = Sundials.(RealArray.of_list [
Constraint.unconstrained;
Constraint.unconstrained;
Constraint.geq_zero;
Constraint.leq_zero;
Constraint.geq_zero;
Constraint.leq_zero ]) in
Kinsol.set_constraints s (Nvector_serial.wrap c);
Kinsol.set_func_norm_tol s 1.0e-5;
Kinsol.set_scaled_step_tol s 1.0e-5;
Kinsol.set_max_setup_calls s 1;;

(* 5. Solve the problem. *)
let snv = Nvector_serial.make (Sundials.RealArray.length ud) 1.0 in
ignore (Kinsol.(solve s u Newton snv snv));

Printf.printf "%8.5g %8.6g\n" ud.{0} ud.{1};;

(* 6. Get optional outputs,
call the [get_*] functions to examine solver statistics. *)
let fnorm = Kinsol.get_func_norm s;;


See sundials: Skeleton of main program
type [> Nvector_serial.kind ] serial_session = (Nvector_serial.data, [> Nvector_serial.kind ] as 'a) session
Alias for sessions based on serial nvectors.

## Linear solvers

type ('data, 'kind) linear_solver = ('data, 'kind) linear_solver
Linear solvers used by Kinsol.
See sundials: Linear Solver Specification Functions
type [> Nvector_serial.kind ] serial_linear_solver = (Nvector_serial.data, [> Nvector_serial.kind ] as 'a) linear_solver
Alias for linear solvers that are restricted to serial nvectors.
type 'd double = 'd * 'd
Workspaces with two temporary vectors.
type ('t, 'd) jacobian_arg = ('t, 'd) jacobian_arg = {
    jac_u : 'd; (* The current unscaled iterate. *)    jac_fu : 'd; (* The current value of the vector $F(u)$. *)    jac_tmp : 't; (* Workspace data. *)
}
Arguments common to Jacobian callback functions.
See sundials: KINDlsDenseJacFn
See sundials: KINDlsBandJacFn
See sundials: KINSpilsPrecSolveFn
See sundials: KINSpilsPrecSetupFn
type bandrange = bandrange = {
    mupper : int; (* The upper half-bandwidth. *)    mlower : int; (* The lower half-bandwidth. *)
}
The range of nonzero entries in a band matrix.
module Dls: sig .. end
Direct Linear Solvers operating on dense and banded matrices.
module Sls: sig .. end
Sparse Linear Solvers.
module Spils: sig .. end
Scaled Preconditioned Iterative Linear Solvers.
module Alternate: sig .. end
Alternate Linear Solvers.

## Solver initialization and use

type 'data sysfn = 'data -> 'data -> unit
System function that defines nonlinear problem. The call sysfun u fval must calculate $F(u)$ into fval using the current value vector u.

Raising Sundials.RecoverableFailure indicates a recoverable error. Any other exception is treated as an unrecoverable error.

u and fval should not be accessed after the function returns.

See sundials: KINSysFn
val init : ?max_iters:int ->       ?maa:int ->       ?linsolv:('data, 'kind) linear_solver ->       'data sysfn ->       ('data, 'kind) Nvector.t -> ('data, 'kind) session
Creates and initializes a session with the Kinsol solver. The call init ~max_lin_iters:mli ~maa:maa ~linsolv:ls f tmpl has as arguments:
• mli, the maximum number of nonlinear iterations allowed,
• maa, the size of the Anderson acceleration subspace for the Picard and FixedPoint strategies,
• ls, the linear solver to use (required for the Newton, LineSearch, and Picard strategies),
• f, the system function of the nonlinear problem, and,
• tmpl a template to initialize the session (e.g., the initial guess vector).

See sundials: KINCreate/KINInit
See sundials: KINSetNumMaxIters
See sundials: KINSetMAA
See sundials: Linear solver specification functions
type strategy = 
 | Newton (* Basic Newton iteration. (KIN_NONE) *) | LineSearch (* Newton iteration with globalization. (KIN_LINESEARCH) *) | Picard (* Picard iteration with Anderson Acceleration. (KIN_PICARD) *) | FixedPoint (* Fixed-point iteration with Anderson Acceleration. (KIN_FP) *)
Strategy used to solve the non-linear system.
type result = 
 | Success (* The scaled norm of $F(u)$ is less than fnormtol. See Kinsol.set_func_norm_tol. (KIN_SUCCESS) *) | InitialGuessOK (* The initial guess already satisfies the system. (KIN_INITIAL_GUESS_OK) *) | StoppedOnStepTol (* Stopped based on scaled step length. The current iterate is an approximate solution, or the algorithm stalled near an invalid solution, or scsteptol is too large (see Kinsol.set_scaled_step_tol). (KIN_STEP_LT_STPTOL) *)
Results of non-linear solution attempts.
val solve : ('d, 'k) session ->       ('d, 'k) Nvector.t ->       strategy -> ('d, 'k) Nvector.t -> ('d, 'k) Nvector.t -> result
Computes an approximate solution to a nonlinear system. The call solve s u strategy u_scale f_scale has arguments:
• s, a solver session,
• u, an initial guess that is replaced with an approximate solution for $F(u) = 0$,
• strategy, strategy used to solve the non-linear system,
• u_scale, the diagonal elements of the scaling matrix $D_u$ for vector u chosen so that all $D_u u$ all have roughly the same magnitude when u is close to a root of $F(u)$, and,
• f_scale, the diagonal elements of the scaling matrix $D_f$ for $F(u)$ chosen so that all $D_f F(u)$ have roughtly the same magnitude when u is not near a root of $F(u)$.
The function either returns a Kinsol.result or raises one of the exceptions listed below.
Raises
• MissingLinearSolver A linear solver is required but was not given.
• IllInput Missing or illegal solver inputs.
• LineSearchNonConvergence Line search could not find a suitable iterate.
• MaxIterationsReached The maximum number of nonlinear iterations was reached.
• MaxNewtonStepExceeded Five consecutive steps satisfied a scaled step length test.
• LineSearchBetaConditionFailure Line search could not satisfy the beta-condition.
• LinearSolverNoRecovery The Kinsol.Spils.prec_solve_fn callback raised Sundials.RecoverableFailure but the preconditioner is already current.
• LinearSolverInitFailure Linear solver initialization failed.
• LinearSetupFailure Linear solver setup failed unrecoverably.
• LinearSolveFailure Linear solver solution failed unrecoverably.
• SystemFunctionFailure The Kinsol.sysfn callback failed unrecoverably.
• FirstSystemFunctionFailure The Kinsol.sysfn callback raised Sundials.RecoverableFailure when first called.
• RepeatedSystemFunctionFailure The Kinsol.sysfn callback raised Sundials.RecoverableFailure repeatedly.
See sundials: KINSol

## Modifying the solver (optional input functions)

val set_no_init_setup : ('d, 'k) session -> unit
Specifies that an initial call to the preconditioner setup function should not be made. This feature is useful when solving a sequence of problems where the final preconditioner values of one problem become the initial values for the next problem.
See sundials: KINSetNoInitSetup
val set_init_setup : ('d, 'k) session -> unit
Specifies that an initial call to the preconditioner setup function should be made (the default).
See sundials: KINSetNoInitSetup
val set_no_res_mon : [> Nvector_serial.kind ] serial_session -> unit
Disables the nonlinear residual monitoring scheme that controls Jacobian updating. It only has an effect for the Dense and Band solvers.
See sundials: KINSetNoResMon
val set_res_mon : [> Nvector_serial.kind ] serial_session -> unit
Enables the nonlinear residual monitoring scheme that controls Jacobian updating. It only has an effect for the Dense and Band solvers.
See sundials: KINSetNoResMon
val set_max_setup_calls : ('d, 'k) session -> int -> unit
Specifies the maximum number of nonlinear iterations between calls to the preconditioner setup function. Pass 0 to set the default (10).
See sundials: KINSetMaxSetupCalls
val set_max_sub_setup_calls : [> Nvector_serial.kind ] serial_session -> int -> unit
Specifies the maximum number of nonlinear iterations between checks by the residual monitoring algorithm. Pass 0 to set the default (5). It only affects the Dense and Band solvers.
See sundials: KINSetMaxSubSetupCalls
type eta_params = {
    egamma : float option; (* default = 0.9 *)    ealpha : float option; (* default = 2.0 *)
}
The parameters gamma and alpha in the formula for the Eisenstat and Walker Choice 2 for eta. Set either to None to specify its default value. The legal values are $0 < \mathtt{egamma} \leq 1.0 \wedge 1 < \mathtt{ealpha} \leq 2.0$.
See sundials: Stopping criteria for iterative linear solvers
type eta_choice = 
 | EtaChoice1 (* Eisenstat and Walker Choice 1 *) | EtaChoice2 of eta_params (* Eisenstat and Walker Choice 2 *) | EtaConstant of float option (* Constant (default = 0.1) *)
The eta parameter in the stopping criteria for the linear system solver.
See sundials: Stopping criteria for iterative linear solvers
val set_eta_choice : ('d, 'k) session -> eta_choice -> unit
Specifies the method for computing the value of the eta coefficient used in the calculation of the linear solver convergence tolerance.
See sundials: KINSetEtaForm
See sundials: KINSetEtaConstValue
See sundials: KINSetEtaParams
val set_res_mon_const_value : ('d, 'k) session -> float -> unit
Specifies the constant value of omega when using residual monitoring. Pass 0.0 to specify the default value (0.9). The legal values are $0 < \mathtt{omega} < 1.0$.
See sundials: KINSetResMonConstValue
val set_res_mon_params : ('d, 'k) session -> ?omegamin:float -> ?omegamax:float -> unit -> unit
Specifies the minimum and maximum values in the formula for omega. The legal values are $0 < \mathtt{omegamin} < \mathtt{omegamax} < 1.0$.
See sundials: KINSetResMonParams
See sundials: Residual monitoring for Modified Newton method
val set_no_min_eps : ('d, 'k) session -> unit
Specifies that the scaled linear residual tolerance (epsilon) is not bounded from below.
See sundials: KINSetNoMinEps
See sundials: KINSetFuncNormTol
val set_min_eps : ('d, 'k) session -> unit
Specifies that the scaled linear residual tolerance (epsilon) is bounded from below. That is, the positive minimum value $0.01\mathtt{fnormtol}$ is applied to epsilon.
See sundials: KINSetNoMinEps
See sundials: KINSetFuncNormTol
val set_max_newton_step : ('d, 'k) session -> float -> unit
Specifies the maximum allowable scaled length of the Newton step. Pass 0.0 to specify the default value $1000\lVert u_0 \rVert_{D_u}$, otherwise the given value must be greater than zero.
See sundials: KINSetMaxNewtonStep
val set_max_beta_fails : ('d, 'k) session -> float -> unit
Specifies the maximum number of beta-condition failures in the line search algorithm. Pass 0.0 to specify the default (10).
See sundials: KINSetMaxBetaFails
val set_rel_err_func : ('d, 'k) session -> float -> unit
Specifies the relative error in computing $F(u)$, which is used in the difference quotient approximation of the Jacobian-vector product. Pass 0.0 to specify the default value ($\sqrt{\mathtt{unit\_roundoff}}$).
See sundials: KINSetRelErrFunc
val set_func_norm_tol : ('d, 'k) session -> float -> unit
Specifies the stopping tolerance on the scaled maximum norm. It must be greater than zero. Pass 0.0 to specify the default value ($\mathtt{unit\_roundoff}^\frac{1}{3}$).
See sundials: KINSetFuncNormTol
val set_scaled_step_tol : ('d, 'k) session -> float -> unit
Specifies the stopping tolerance on the minimum scaled step length, which must be greater than zero. Pass 0.0 to specify the default value ($\mathtt{unit\_roundoff}^\frac{1}{3}$).
See sundials: KINSetScaledStepTol
val set_constraints : ('d, 'k) session -> ('d, 'k) Nvector.t -> unit
Specifies a vector defining inequality constraints for each component of the solution vector u. See Sundials.Constraint.
See sundials: KINSetConstraints
val set_sys_func : ('d, 'k) session -> ('d -> 'd -> unit) -> unit
Changes the system function. Allows solutions of several problems of the same size but with different functions.
See sundials: KINSetSysFunc
See sundials: KINSysFn

### Logging and error handling

val set_error_file : ('d, 'k) session -> Sundials.Logfile.t -> unit
Configure the default error handler to write messages to a file. By default it writes to Sundials.Logfile.stderr.
See sundials: KINSetErrFile
val set_err_handler_fn : ('d, 'k) session -> (Sundials.error_details -> unit) -> unit
Specifies a custom function for handling error messages. The handler must not fail: any exceptions are trapped and discarded.
See sundials: KINSetErrHandlerFn
See sundials: KINErrHandlerFn
val clear_err_handler_fn : ('d, 'k) session -> unit
Restores the default error handling function.
See sundials: KINSetErrHandlerFn
val set_info_file : ('d, 'k) session -> Sundials.Logfile.t -> unit
Write informational (non-error) messages to the given file. By default they are written to Sundials.Logfile.stdout.
See sundials: KINSetInfoFile
val set_info_handler_fn : ('d, 'k) session -> (Sundials.error_details -> unit) -> unit
Specifies a custom function for handling informational (non-error) messages. The error_code field of Sundials.error_details is 0 for such messages. The handler must not fail: any exceptions are trapped and discarded.
See sundials: KINSetInfoHandlerFn
See sundials: KINInfoHandlerFn
val clear_info_handler_fn : ('d, 'k) session -> unit
Restores the default information handling function.
See sundials: KINSetErrHandlerFn
type print_level = 
 | NoInformation (* No information displayed. (0) *) | ShowScaledNorms (* At each nonlinear iteration, display the scaled Euclidean norm of the system function at the current iterate, the scaled norm of the Newton step (if no globalization strategy is used), and the number of function evaluations performed so far. (1) *) | ShowScaledDFNorm (* Additionally display $\lVert F(u) \rVert_{DF}$ if no globalization strategy is used, and $\lVert F(u)\rVert_{DF,\infty}$, otherwise. (2) *) | ShowGlobalValues (* Additionally display the values used by the global strategy and statistical information for the linear solver. (3) *)
Increasing levels of verbosity for informational messages.
val set_print_level : ('d, 'k) session -> print_level -> unit
Sets the level of verbosity of informational messages.
See sundials: KINSetPrintLevel

## Querying the solver (optional output functions)

val get_work_space : ('d, 'k) session -> int * int
Returns the sizes of the real and integer workspaces.
Returns (real_size, integer_size)
See sundials: KINGetWorkSpace
val get_num_func_evals : ('d, 'k) session -> int
Returns the number of evaluations of the system function.
See sundials: KINGetNumFuncEvals
val get_num_nonlin_solv_iters : ('d, 'k) session -> int
Returns the number of nonlinear iterations.
See sundials: KINGetNumNonlinSolvIters
val get_num_beta_cond_fails : ('d, 'k) session -> int
Returns the number of beta-condition failures.
See sundials: KINGetNumBetaCondFails
val get_num_backtrack_ops : ('d, 'k) session -> int
Returns the number of backtrack operations (step length adjustments) performed by the line search algorithm.
See sundials: KINGetNumBacktrackOps
val get_func_norm : ('d, 'k) session -> float
Returns the scaled Euclidiean l2 norm of the nonlinear system function $F(u)$ evaluated at the current iterate.
See sundials: KINGetFuncNorm
val get_step_length : ('d, 'k) session -> float
Returns the scaled Euclidiean l2 norm of the step used during the previous iteration.
See sundials: KINGetStepLength

## Exceptions

exception IllInput
An input parameter was invalid.
See sundials: KIN_ILL_INPUT
exception LineSearchNonConvergence
Line search could not find an iterate sufficiently distinct from the current one, or an iterate satisfying the sufficient decrease condition. The latter could mean that the current iterate is “close” to an approximate solution, but that the difference approximation of the matrix-vector product is inaccurate, or that scsteptol (Kinsol.set_scaled_step_tol) is too large.
See sundials: KIN_LINESEARCH_NONCONV
exception MaxIterationsReached
The maximum number of nonlinear iterations has been reached.
See sundials: KIN_MAXITER_REACHED
exception MaxNewtonStepExceeded
Five consecutive steps exceed the maximum newton step. That is, the five steps satisfy the inequality $\\|D_u p\\|_{L2} > 0.99 \mathtt{mxnewtstep}$, where $p$ denotes the current step and mxnewtstep is a scalar upper bound on the scaled step length (see Kinsol.set_max_newton_step). It could be that $\\| D_F F(u)\\|_{L2}$ is bounded from above by a positive value or that mxnewtstep is too small.
See sundials: KIN_MXNEWT_5X_EXCEEDED
exception LineSearchBetaConditionFailure
The line search algorithm could not satisfy the “beta-condition” for mxnbcf + 1 nonlinear iterations. The failures need not occur in consecutive iterations. They may indicate that the algorithm is making poor progress.
See sundials: KIN_LINESEARCH_BCFAIL
exception LinearSolverNoRecovery
The Kinsol.Spils.prec_solve_fn callback raised Sundials.RecoverableFailure but the preconditioner is already current.
See sundials: KIN_LINSOLV_NO_RECOVERY
exception LinearSolverInitFailure
Linear solver initialization failed.
See sundials: KIN_LINIT_FAIL
exception LinearSetupFailure
The Kinsol.Spils.prec_setup_fn callback failed unrecoverably.
See sundials: KIN_LSETUP_FAIL
exception LinearSolverFailure
Either Kinsol.Spils.prec_solve_fn failed unrecoverably or the linear solver encountered an error condition.
See sundials: KIN_LSOLVE_FAIL
exception SystemFunctionFailure
The Kinsol.sysfn callback failed unrecoverably.
See sundials: KIN_SYSFUNC_FAIL
exception FirstSystemFunctionFailure
The Kinsol.sysfn callback raised Sundials.RecoverableFailure when first called.
See sundials: KIN_FIRST_SYSFUNC_FAIL
exception RepeatedSystemFunctionFailure
The Kinsol.sysfn callback raised Sundials.RecoverableFailure repeatedly. No recovery is possible.
See sundials: KIN_REPTD_SYSFUNC_ERR
exception MissingLinearSolver
A linear solver is required but was not specified.