sig
  type solver_result = Success | RootsFound | StopTimeReached
  type step_stats = {
    num_steps : int;
    actual_init_step : float;
    last_step : float;
    current_step : float;
    current_time : float;
  }
  type interpolant_type = Hermite | Lagrange
  type linearity = Linear of bool | Nonlinear
  type 'data error_weight_fun = 'data -> 'data -> unit
  type ('data, 'kind) tolerance =
      SStolerances of float * float
    | SVtolerances of float * ('data, 'kind) Nvector.t
    | WFtolerances of 'data error_weight_fun
  val default_tolerances : ('data, 'kind) tolerance
  type predictor_method =
      TrivialPredictor
    | MaximumOrderPredictor
    | VariableOrderPredictor
    | CutoffOrderPredictor
  type 'd nonlin_system_data = {
    tcur : float;
    zpred : 'd;
    zi : 'd;
    fi : 'd;
    gamma : float;
    sdata : 'd;
  }
  type 'd rootsfn = float -> '-> Sundials.RealArray.t -> unit
  val no_roots : int * 'd rootsfn
  type adaptivity_args = {
    h1 : float;
    h2 : float;
    h3 : float;
    e1 : float;
    e2 : float;
    e3 : float;
    q : int;
    p : int;
  }
  type 'd adaptivity_fn = float -> '-> adaptivity_args -> float
  type adaptivity_params = {
    ks : (float * float * float) option;
    method_order : bool;
  }
  type 'd adaptivity_method =
      PIDcontroller of adaptivity_params
    | PIcontroller of adaptivity_params
    | Icontroller of adaptivity_params
    | ExplicitGustafsson of adaptivity_params
    | ImplicitGustafsson of adaptivity_params
    | ImExGustafsson of adaptivity_params
    | AdaptivityFn of 'd adaptivity_fn
  type 'd rhsfn = float -> '-> '-> unit
  type 'd stability_fn = float -> '-> float
  type 'd resize_fn = '-> '-> unit
  type 'd postprocess_step_fn = float -> '-> unit
  type 'd triple = 'd * 'd * 'd
  type ('t, 'd) jacobian_arg =
    ('t, 'd) Arkode_impl.jacobian_arg = {
    jac_t : float;
    jac_y : 'd;
    jac_fy : 'd;
    jac_tmp : 't;
  }
  type ('d, 'k) session = ('d, 'k, Arkode.arkstep) Arkode_impl.session
  type 'a serial_session = (Nvector_serial.data, 'a) Arkode.ARKStep.session
    constraint 'a = [> Nvector_serial.kind ]
  type ('data, 'kind) linear_solver =
      ('data, 'kind, Arkode.arkstep) Arkode_impl.lin_solver
  type 'a serial_linear_solver =
      (Nvector_serial.data, 'a) Arkode.ARKStep.linear_solver
    constraint 'a = [> Nvector_serial.kind ]
  module Dls :
    sig
      val dense :
        ?context:Sundials.Context.t ->
        ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
        'Sundials.Matrix.dense ->
        (Sundials.Matrix.Dense.t, 'a, [ `Dls ])
        Sundials_LinearSolver.serial_t
      val lapack_dense :
        ?context:Sundials.Context.t ->
        ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
        'Sundials.Matrix.dense ->
        (Sundials.Matrix.Dense.t, 'a, [ `Dls ])
        Sundials_LinearSolver.serial_t
      val band :
        ?context:Sundials.Context.t ->
        ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
        'Sundials.Matrix.band ->
        (Sundials.Matrix.Band.t, 'a, [ `Dls ]) Sundials_LinearSolver.serial_t
      val lapack_band :
        ?context:Sundials.Context.t ->
        ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
        'Sundials.Matrix.band ->
        (Sundials.Matrix.Band.t, 'a, [ `Dls ]) Sundials_LinearSolver.serial_t
      module Klu :
        sig
          type ordering =
            Sundials_LinearSolver_impl.Klu.ordering =
              Amd
            | ColAmd
            | Natural
          val make :
            ?context:Sundials.Context.t ->
            ?ordering:ordering ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            ('s, 'a) Sundials.Matrix.sparse ->
            ('Sundials.Matrix.Sparse.t, 'a, [ `Dls | `Klu ])
            Sundials_LinearSolver.serial_t
          val reinit :
            ('Sundials.Matrix.Sparse.t, [> Nvector_serial.kind ] as 'a,
             [> `Klu ])
            Sundials_LinearSolver.serial_t ->
            ('s, 'a) Sundials.Matrix.sparse -> ?nnz:int -> unit -> unit
          val set_ordering :
            ('Sundials.Matrix.Sparse.t, [> Nvector_serial.kind ],
             [> `Klu ])
            Sundials_LinearSolver.serial_t -> ordering -> unit
        end
      val klu :
        ?context:Sundials.Context.t ->
        ?ordering:Klu.ordering ->
        ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
        ('s, 'a) Sundials.Matrix.sparse ->
        ('Sundials.Matrix.Sparse.t, 'a, [ `Dls | `Klu ])
        Sundials_LinearSolver.serial_t
      module Superlumt :
        sig
          type ordering =
            Sundials_LinearSolver_impl.Superlumt.ordering =
              Natural
            | MinDegreeProd
            | MinDegreeSum
            | ColAmd
          val make :
            ?context:Sundials.Context.t ->
            ?ordering:ordering ->
            nthreads:int ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            ('s, 'a) Sundials.Matrix.sparse ->
            ('Sundials.Matrix.Sparse.t, 'a, [ `Dls | `Slu ])
            Sundials_LinearSolver.serial_t
          val set_ordering :
            ('Sundials.Matrix.Sparse.t, [> Nvector_serial.kind ],
             [> `Slu ])
            Sundials_LinearSolver.serial_t -> ordering -> unit
        end
      val superlumt :
        ?context:Sundials.Context.t ->
        ?ordering:Superlumt.ordering ->
        nthreads:int ->
        ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
        ('s, 'a) Sundials.Matrix.sparse ->
        ('Sundials.Matrix.Sparse.t, 'a, [> `Dls | `Slu ])
        Sundials_LinearSolver.serial_t
      type 'm jac_fn =
          (Sundials.RealArray.t Common.triple, Sundials.RealArray.t)
          Common.jacobian_arg -> '-> unit
      type 'm linsys_fn =
          (Sundials.RealArray.t Common.triple, Sundials.RealArray.t)
          Common.jacobian_arg -> '-> 'm option -> bool -> float -> bool
      val solver :
        ?jac:'m jac_fn ->
        ?linsys:'m linsys_fn ->
        ('m, Sundials.RealArray.t, [> Nvector_serial.kind ] as 'a, [> `Dls ])
        Sundials.LinearSolver.t -> 'Arkode.ARKStep.serial_linear_solver
      val get_work_space :
        [> Nvector_serial.kind ] Arkode.ARKStep.serial_session -> int * int
      val get_num_jac_evals :
        [> Nvector_serial.kind ] Arkode.ARKStep.serial_session -> int
      val get_num_lin_rhs_evals :
        [> Nvector_serial.kind ] Arkode.ARKStep.serial_session -> int
    end
  module Spils :
    sig
      type gramschmidt_type =
        Sundials_LinearSolver_impl.Iterative.gramschmidt_type =
          ModifiedGS
        | ClassicalGS
      val spbcgs :
        ?context:Sundials.Context.t ->
        ?maxl:int ->
        ('d, 'k) Nvector.t ->
        ('m, 'd, 'k, [ `Iter | `Spbcgs ]) Sundials_LinearSolver.t
      val spfgmr :
        ?context:Sundials.Context.t ->
        ?maxl:int ->
        ?max_restarts:int ->
        ?gs_type:gramschmidt_type ->
        ('d, 'k) Nvector.t ->
        ('m, 'd, 'k, [ `Iter | `Spfgmr ]) Sundials_LinearSolver.t
      val spgmr :
        ?context:Sundials.Context.t ->
        ?maxl:int ->
        ?max_restarts:int ->
        ?gs_type:gramschmidt_type ->
        ('d, 'k) Nvector.t ->
        ('m, 'd, 'k, [ `Iter | `Spgmr ]) Sundials_LinearSolver.t
      val sptfqmr :
        ?context:Sundials.Context.t ->
        ?maxl:int ->
        ('d, 'k) Nvector.t ->
        ('m, 'd, 'k, [ `Iter | `Sptfqmr ]) Sundials_LinearSolver.t
      val pcg :
        ?context:Sundials.Context.t ->
        ?maxl:int ->
        ('d, 'k) Nvector.t ->
        ('m, 'd, 'k, [ `Iter | `Pcg ]) Sundials_LinearSolver.t
      module Algorithms :
        sig
          val qr_fact :
            int ->
            Sundials.RealArray2.t -> Sundials.RealArray.t -> bool -> unit
          val qr_sol :
            int ->
            Sundials.RealArray2.t ->
            Sundials.RealArray.t -> Sundials.RealArray.t -> unit
          val modified_gs :
            ('d, 'k) Nvector.t array ->
            Sundials.RealArray2.t -> int -> int -> float
          val classical_gs :
            ('d, 'k) Nvector.t array ->
            Sundials.RealArray2.t ->
            int ->
            int -> Sundials.RealArray.t -> ('d, 'k) Nvector.t array -> float
        end
      val set_maxl :
        ('m, 'd, 'k, [< `Iter | `Pcg | `Spbcgs | `Sptfqmr ])
        Sundials_LinearSolver.t -> int -> unit
      val set_gs_type :
        ('m, 'd, 'k, [< `Iter | `Spfgmr | `Spgmr ]) Sundials_LinearSolver.t ->
        gramschmidt_type -> unit
      val set_max_restarts :
        ('m, 'd, 'k, [< `Iter | `Spfgmr | `Spgmr ]) Sundials_LinearSolver.t ->
        int -> unit
      type preconditioning_type =
        Sundials_LinearSolver_impl.Iterative.preconditioning_type =
          PrecNone
        | PrecLeft
        | PrecRight
        | PrecBoth
      val set_prec_type :
        ('m, 'd, 'k, [> `Iter ]) Sundials_LinearSolver.t ->
        preconditioning_type -> unit
      val set_info_file :
        ('m, 'd, 'k, [> `Iter ]) Sundials_LinearSolver.t ->
        ?print_level:bool -> Sundials.Logfile.t -> unit
      val set_print_level :
        ('m, 'd, 'k, [> `Iter ]) Sundials_LinearSolver.t -> bool -> unit
      type 'd prec_solve_arg = {
        rhs : 'd;
        gamma : float;
        delta : float;
        left : bool;
      }
      type 'd prec_solve_fn =
          (unit, 'd) Common.jacobian_arg -> 'd prec_solve_arg -> '-> unit
      type 'd prec_setup_fn =
          (unit, 'd) Common.jacobian_arg -> bool -> float -> bool
      type ('d, 'k, 's) preconditioner =
          ('d, 'k, 's) Arkode_impl.SpilsTypes.preconditioner
      module Banded :
        sig
          type bandrange = { mupper : int; mlower : int; }
          val prec_left :
            bandrange ->
            (Nvector_serial.data, [> Nvector_serial.kind ], 's)
            preconditioner
          val prec_right :
            bandrange ->
            (Nvector_serial.data, [> Nvector_serial.kind ], 's)
            preconditioner
          val prec_both :
            bandrange ->
            (Nvector_serial.data, [> Nvector_serial.kind ], 's)
            preconditioner
          type ('a, 'b) serial_session =
              (Nvector_serial.data, 'a, 'b) Arkode_impl.session
            constraint 'a = [> Nvector_serial.kind ]
            constraint 'b = [< `ARKStep | `MRIStep ]
          val get_work_space :
            ([> Nvector_serial.kind ], [< `ARKStep | `MRIStep ])
            serial_session -> int * int
          val get_num_rhs_evals :
            ([> Nvector_serial.kind ], [< `ARKStep | `MRIStep ])
            serial_session -> int
        end
      type 'd jac_times_setup_fn = (unit, 'd) Common.jacobian_arg -> unit
      type 'd jac_times_vec_fn =
          ('d, 'd) Common.jacobian_arg -> '-> '-> unit
      val prec_none : ('d, 'k, Arkode.arkstep) preconditioner
      val prec_left :
        ?setup:'d prec_setup_fn ->
        'd prec_solve_fn -> ('d, 'k, Arkode.arkstep) preconditioner
      val prec_right :
        ?setup:'d prec_setup_fn ->
        'd prec_solve_fn -> ('d, 'k, Arkode.arkstep) preconditioner
      val prec_both :
        ?setup:'d prec_setup_fn ->
        'd prec_solve_fn -> ('d, 'k, Arkode.arkstep) preconditioner
      val solver :
        ('m, 'd, 'k, [> `Iter ]) Sundials.LinearSolver.t ->
        ?jac_times_vec:'d jac_times_setup_fn option * 'd jac_times_vec_fn ->
        ?jac_times_rhs:'d rhsfn ->
        ('d, 'k, Arkode.arkstep) preconditioner ->
        ('d, 'k) Arkode.ARKStep.linear_solver
      val set_jac_eval_frequency :
        ('d, 'k) Arkode.ARKStep.session -> int -> unit
      val set_linear_solution_scaling :
        ('d, 'k) Arkode.ARKStep.session -> bool -> unit
      val set_eps_lin : ('d, 'k) Arkode.ARKStep.session -> float -> unit
      val set_ls_norm_factor :
        ('d, 'k) Arkode.ARKStep.session -> float -> unit
      val get_work_space : ('d, 'k) Arkode.ARKStep.session -> int * int
      val get_num_lin_iters : ('d, 'k) Arkode.ARKStep.session -> int
      val get_num_lin_conv_fails : ('d, 'k) Arkode.ARKStep.session -> int
      val get_num_prec_evals : ('d, 'k) Arkode.ARKStep.session -> int
      val get_num_prec_solves : ('d, 'k) Arkode.ARKStep.session -> int
      val get_num_jtsetup_evals : ('d, 'k) Arkode.ARKStep.session -> int
      val get_num_jtimes_evals : ('d, 'k) Arkode.ARKStep.session -> int
      val get_num_lin_rhs_evals : ('d, 'k) Arkode.ARKStep.session -> int
      val set_preconditioner :
        ('d, 'k) Arkode.ARKStep.session ->
        ?setup:'d prec_setup_fn -> 'd prec_solve_fn -> unit
      val set_jac_times :
        ('d, 'k) Arkode.ARKStep.session ->
        ?jac_times_setup:'d jac_times_setup_fn -> 'd jac_times_vec_fn -> unit
      val clear_jac_times : ('d, 'k) Arkode.ARKStep.session -> unit
    end
  val matrix_embedded_solver :
    (unit, 'data, 'kind, [> `MatE ]) Sundials.LinearSolver.t ->
    ('data, 'kind) Arkode.ARKStep.linear_solver
  module Mass :
    sig
      type ('data, 'kind) solver
      type 'a serial_solver =
          (Nvector_serial.data, 'a) Arkode.ARKStep.Mass.solver
        constraint 'a = [> Nvector_serial.kind ]
      module Dls :
        sig
          val dense :
            ?context:Sundials.Context.t ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            'Sundials.Matrix.dense ->
            (Sundials.Matrix.Dense.t, 'a, [ `Dls ])
            Sundials_LinearSolver.serial_t
          val lapack_dense :
            ?context:Sundials.Context.t ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            'Sundials.Matrix.dense ->
            (Sundials.Matrix.Dense.t, 'a, [ `Dls ])
            Sundials_LinearSolver.serial_t
          val band :
            ?context:Sundials.Context.t ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            'Sundials.Matrix.band ->
            (Sundials.Matrix.Band.t, 'a, [ `Dls ])
            Sundials_LinearSolver.serial_t
          val lapack_band :
            ?context:Sundials.Context.t ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            'Sundials.Matrix.band ->
            (Sundials.Matrix.Band.t, 'a, [ `Dls ])
            Sundials_LinearSolver.serial_t
          module Klu :
            sig
              type ordering =
                Sundials_LinearSolver_impl.Klu.ordering =
                  Amd
                | ColAmd
                | Natural
              val make :
                ?context:Sundials.Context.t ->
                ?ordering:ordering ->
                ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
                ('s, 'a) Sundials.Matrix.sparse ->
                ('Sundials.Matrix.Sparse.t, 'a, [ `Dls | `Klu ])
                Sundials_LinearSolver.serial_t
              val reinit :
                ('Sundials.Matrix.Sparse.t, [> Nvector_serial.kind ] as 'a,
                 [> `Klu ])
                Sundials_LinearSolver.serial_t ->
                ('s, 'a) Sundials.Matrix.sparse -> ?nnz:int -> unit -> unit
              val set_ordering :
                ('Sundials.Matrix.Sparse.t, [> Nvector_serial.kind ],
                 [> `Klu ])
                Sundials_LinearSolver.serial_t -> ordering -> unit
            end
          val klu :
            ?context:Sundials.Context.t ->
            ?ordering:Klu.ordering ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            ('s, 'a) Sundials.Matrix.sparse ->
            ('Sundials.Matrix.Sparse.t, 'a, [ `Dls | `Klu ])
            Sundials_LinearSolver.serial_t
          module Superlumt :
            sig
              type ordering =
                Sundials_LinearSolver_impl.Superlumt.ordering =
                  Natural
                | MinDegreeProd
                | MinDegreeSum
                | ColAmd
              val make :
                ?context:Sundials.Context.t ->
                ?ordering:ordering ->
                nthreads:int ->
                ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
                ('s, 'a) Sundials.Matrix.sparse ->
                ('Sundials.Matrix.Sparse.t, 'a, [ `Dls | `Slu ])
                Sundials_LinearSolver.serial_t
              val set_ordering :
                ('Sundials.Matrix.Sparse.t, [> Nvector_serial.kind ],
                 [> `Slu ])
                Sundials_LinearSolver.serial_t -> ordering -> unit
            end
          val superlumt :
            ?context:Sundials.Context.t ->
            ?ordering:Superlumt.ordering ->
            nthreads:int ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            ('s, 'a) Sundials.Matrix.sparse ->
            ('Sundials.Matrix.Sparse.t, 'a, [> `Dls | `Slu ])
            Sundials_LinearSolver.serial_t
          type 'm mass_fn =
              float -> Sundials.RealArray.t triple -> '-> unit
          val solver :
            'Arkode.ARKStep.Mass.Dls.mass_fn ->
            bool ->
            ('m, Sundials.RealArray.t, [> Nvector_serial.kind ] as 'a,
             [> `Dls ])
            Sundials.LinearSolver.t -> 'Arkode.ARKStep.Mass.serial_solver
          val get_work_space :
            [> Nvector_serial.kind ] Arkode.ARKStep.serial_session ->
            int * int
          val get_num_setups :
            [> Nvector_serial.kind ] Arkode.ARKStep.serial_session -> int
          val get_num_mult_setups :
            [> Nvector_serial.kind ] Arkode.ARKStep.serial_session -> int
          val get_num_solves :
            [> Nvector_serial.kind ] Arkode.ARKStep.serial_session -> int
          val get_num_mult :
            [> Nvector_serial.kind ] Arkode.ARKStep.serial_session -> int
        end
      module Spils :
        sig
          type gramschmidt_type =
            Sundials_LinearSolver_impl.Iterative.gramschmidt_type =
              ModifiedGS
            | ClassicalGS
          val spbcgs :
            ?context:Sundials.Context.t ->
            ?maxl:int ->
            ('d, 'k) Nvector.t ->
            ('m, 'd, 'k, [ `Iter | `Spbcgs ]) Sundials_LinearSolver.t
          val spfgmr :
            ?context:Sundials.Context.t ->
            ?maxl:int ->
            ?max_restarts:int ->
            ?gs_type:gramschmidt_type ->
            ('d, 'k) Nvector.t ->
            ('m, 'd, 'k, [ `Iter | `Spfgmr ]) Sundials_LinearSolver.t
          val spgmr :
            ?context:Sundials.Context.t ->
            ?maxl:int ->
            ?max_restarts:int ->
            ?gs_type:gramschmidt_type ->
            ('d, 'k) Nvector.t ->
            ('m, 'd, 'k, [ `Iter | `Spgmr ]) Sundials_LinearSolver.t
          val sptfqmr :
            ?context:Sundials.Context.t ->
            ?maxl:int ->
            ('d, 'k) Nvector.t ->
            ('m, 'd, 'k, [ `Iter | `Sptfqmr ]) Sundials_LinearSolver.t
          val pcg :
            ?context:Sundials.Context.t ->
            ?maxl:int ->
            ('d, 'k) Nvector.t ->
            ('m, 'd, 'k, [ `Iter | `Pcg ]) Sundials_LinearSolver.t
          module Algorithms :
            sig
              val qr_fact :
                int ->
                Sundials.RealArray2.t -> Sundials.RealArray.t -> bool -> unit
              val qr_sol :
                int ->
                Sundials.RealArray2.t ->
                Sundials.RealArray.t -> Sundials.RealArray.t -> unit
              val modified_gs :
                ('d, 'k) Nvector.t array ->
                Sundials.RealArray2.t -> int -> int -> float
              val classical_gs :
                ('d, 'k) Nvector.t array ->
                Sundials.RealArray2.t ->
                int ->
                int ->
                Sundials.RealArray.t -> ('d, 'k) Nvector.t array -> float
            end
          val set_maxl :
            ('m, 'd, 'k, [< `Iter | `Pcg | `Spbcgs | `Sptfqmr ])
            Sundials_LinearSolver.t -> int -> unit
          val set_gs_type :
            ('m, 'd, 'k, [< `Iter | `Spfgmr | `Spgmr ])
            Sundials_LinearSolver.t -> gramschmidt_type -> unit
          val set_max_restarts :
            ('m, 'd, 'k, [< `Iter | `Spfgmr | `Spgmr ])
            Sundials_LinearSolver.t -> int -> unit
          type preconditioning_type =
            Sundials_LinearSolver_impl.Iterative.preconditioning_type =
              PrecNone
            | PrecLeft
            | PrecRight
            | PrecBoth
          val set_prec_type :
            ('m, 'd, 'k, [> `Iter ]) Sundials_LinearSolver.t ->
            preconditioning_type -> unit
          val set_info_file :
            ('m, 'd, 'k, [> `Iter ]) Sundials_LinearSolver.t ->
            ?print_level:bool -> Sundials.Logfile.t -> unit
          val set_print_level :
            ('m, 'd, 'k, [> `Iter ]) Sundials_LinearSolver.t -> bool -> unit
          type 'd prec_solve_arg = { rhs : 'd; delta : float; left : bool; }
          type 'd prec_solve_fn =
              float ->
              'Arkode.ARKStep.Mass.Spils.prec_solve_arg -> '-> unit
          type 'd prec_setup_fn = float -> unit
          type ('d, 'k) preconditioner
          val prec_none : ('d, 'k) Arkode.ARKStep.Mass.Spils.preconditioner
          val prec_left :
            ?setup:'Arkode.ARKStep.Mass.Spils.prec_setup_fn ->
            'Arkode.ARKStep.Mass.Spils.prec_solve_fn ->
            ('d, 'k) Arkode.ARKStep.Mass.Spils.preconditioner
          val prec_right :
            ?setup:'Arkode.ARKStep.Mass.Spils.prec_setup_fn ->
            'Arkode.ARKStep.Mass.Spils.prec_solve_fn ->
            ('d, 'k) Arkode.ARKStep.Mass.Spils.preconditioner
          val prec_both :
            ?setup:'Arkode.ARKStep.Mass.Spils.prec_setup_fn ->
            'Arkode.ARKStep.Mass.Spils.prec_solve_fn ->
            ('d, 'k) Arkode.ARKStep.Mass.Spils.preconditioner
          type mass_times_setup_fn = float -> unit
          type 'd mass_times_vec_fn = float -> '-> '-> unit
          val solver :
            ('m, 'd, 'k, [> `Iter ]) Sundials.LinearSolver.t ->
            ?mass_times_setup:Arkode.ARKStep.Mass.Spils.mass_times_setup_fn ->
            'Arkode.ARKStep.Mass.Spils.mass_times_vec_fn ->
            bool ->
            ('d, 'k) Arkode.ARKStep.Mass.Spils.preconditioner ->
            ('d, 'k) Arkode.ARKStep.Mass.solver
          val set_eps_lin : ('d, 'k) Arkode.ARKStep.session -> float -> unit
          val set_ls_norm_factor :
            ('d, 'k) Arkode.ARKStep.session -> float -> unit
          val get_work_space : ('d, 'k) Arkode.ARKStep.session -> int * int
          val get_num_lin_iters : ('d, 'k) Arkode.ARKStep.session -> int
          val get_num_conv_fails : ('d, 'k) Arkode.ARKStep.session -> int
          val get_num_mtsetups : ('d, 'k) Arkode.ARKStep.session -> int
          val get_num_mass_mult : ('d, 'k) Arkode.ARKStep.session -> int
          val get_num_prec_evals : ('d, 'k) Arkode.ARKStep.session -> int
          val get_num_prec_solves : ('d, 'k) Arkode.ARKStep.session -> int
          val set_preconditioner :
            ('d, 'k) Arkode.ARKStep.session ->
            ?setup:'Arkode.ARKStep.Mass.Spils.prec_setup_fn ->
            'Arkode.ARKStep.Mass.Spils.prec_solve_fn -> unit
          val set_times :
            ('d, 'k) Arkode.ARKStep.session ->
            ?mass_times_setup:Arkode.ARKStep.Mass.Spils.mass_times_setup_fn ->
            'Arkode.ARKStep.Mass.Spils.mass_times_vec_fn -> unit
        end
      val matrix_embedded_solver :
        (unit, 'data, 'kind, [> `MatE ]) Sundials.LinearSolver.t ->
        ('data, 'kind) Arkode.ARKStep.linear_solver
    end
  type 'data res_weight_fun = 'data -> 'data -> unit
  type ('data, 'kind) res_tolerance =
      ResStolerance of float
    | ResVtolerance of ('data, 'kind) Nvector.t
    | ResFtolerance of 'data Arkode.ARKStep.res_weight_fun
  type ('d, 'k) problem
  val implicit :
    ?nlsolver:('data, 'kind, ('data, 'kind) Arkode.ARKStep.session,
               [ `Nvec ])
              Sundials_NonlinearSolver.t ->
    ?nlsrhsfn:'data rhsfn ->
    ?lsolver:('data, 'kind) Arkode.ARKStep.linear_solver ->
    ?linearity:linearity ->
    'data rhsfn -> ('data, 'kind) Arkode.ARKStep.problem
  val explicit : 'data rhsfn -> ('data, 'kind) Arkode.ARKStep.problem
  val imex :
    ?nlsolver:('data, 'kind, ('data, 'kind) Arkode.ARKStep.session,
               [ `Nvec ])
              Sundials_NonlinearSolver.t ->
    ?nlsrhsfn:'data rhsfn ->
    ?lsolver:('data, 'kind) Arkode.ARKStep.linear_solver ->
    ?linearity:linearity ->
    fsi:'data rhsfn ->
    fse:'data rhsfn -> unit -> ('data, 'kind) Arkode.ARKStep.problem
  val init :
    ?context:Sundials.Context.t ->
    ('data, 'kind) Arkode.ARKStep.problem ->
    ('data, 'kind) tolerance ->
    ?restol:('data, 'kind) Arkode.ARKStep.res_tolerance ->
    ?order:int ->
    ?mass:('data, 'kind) Arkode.ARKStep.Mass.solver ->
    ?roots:int * 'data rootsfn ->
    float ->
    ('data, 'kind) Nvector.t -> ('data, 'kind) Arkode.ARKStep.session
  val evolve_normal :
    ('d, 'k) Arkode.ARKStep.session ->
    float -> ('d, 'k) Nvector.t -> float * solver_result
  val evolve_one_step :
    ('d, 'k) Arkode.ARKStep.session ->
    float -> ('d, 'k) Nvector.t -> float * solver_result
  val get_dky :
    ('d, 'k) Arkode.ARKStep.session ->
    ('d, 'k) Nvector.t -> float -> int -> unit
  val reinit :
    ('d, 'k) Arkode.ARKStep.session ->
    ?problem:('d, 'k) Arkode.ARKStep.problem ->
    ?order:int ->
    ?mass:('d, 'k) Arkode.ARKStep.Mass.solver ->
    ?roots:int * 'd rootsfn -> float -> ('d, 'k) Nvector.t -> unit
  val reset : ('d, 'k) Arkode.ARKStep.session -> float -> ('d, 'k) Nvector.t
  val resize :
    ('d, 'k) Arkode.ARKStep.session ->
    ?resize_nvec:'d resize_fn ->
    ?lsolver:('d, 'k) Arkode.ARKStep.linear_solver ->
    ?mass:('d, 'k) Arkode.ARKStep.Mass.solver ->
    ('d, 'k) tolerance ->
    ?restol:('d, 'k) Arkode.ARKStep.res_tolerance ->
    float -> ('d, 'k) Nvector.t -> float -> unit
  val set_tolerances :
    ('d, 'k) Arkode.ARKStep.session -> ('d, 'k) tolerance -> unit
  val set_res_tolerance :
    ('d, 'k) Arkode.ARKStep.session ->
    ('d, 'k) Arkode.ARKStep.res_tolerance -> unit
  val set_defaults : ('d, 'k) Arkode.ARKStep.session -> unit
  val set_diagnostics :
    ?logfile:Sundials.Logfile.t -> ('d, 'k) Arkode.ARKStep.session -> unit
  val set_interpolant_type :
    ('d, 'k) Arkode.ARKStep.session -> interpolant_type -> unit
  val set_interpolant_degree : ('d, 'k) Arkode.ARKStep.session -> int -> unit
  val clear_diagnostics : ('d, 'k) Arkode.ARKStep.session -> unit
  val set_error_file :
    ('d, 'k) Arkode.ARKStep.session -> Sundials.Logfile.t -> unit
  val set_err_handler_fn :
    ('d, 'k) Arkode.ARKStep.session ->
    (Sundials.Util.error_details -> unit) -> unit
  val clear_err_handler_fn : ('d, 'k) Arkode.ARKStep.session -> unit
  val set_init_step : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_fixed_step :
    ('d, 'k) Arkode.ARKStep.session -> float option -> unit
  val set_max_num_constr_fails :
    ('d, 'k) Arkode.ARKStep.session -> int -> unit
  val set_max_hnil_warns : ('d, 'k) Arkode.ARKStep.session -> int -> unit
  val set_max_num_steps : ('d, 'k) Arkode.ARKStep.session -> int -> unit
  val set_max_err_test_fails : ('d, 'k) Arkode.ARKStep.session -> int -> unit
  val set_min_step : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_max_step : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_optimal_params : ('d, 'k) Arkode.ARKStep.session -> unit
  val set_stop_time : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_imex : ('d, 'k) Arkode.ARKStep.session -> unit
  val set_explicit : ('d, 'k) Arkode.ARKStep.session -> unit
  val set_implicit : ('d, 'k) Arkode.ARKStep.session -> unit
  val set_tables :
    ('d, 'k) Arkode.ARKStep.session ->
    ?global_method_order:int ->
    ?global_embedding_order:int ->
    ?implicit_table:Arkode.ButcherTable.t ->
    ?explicit_table:Arkode.ButcherTable.t -> unit -> unit
  val set_ark_table_num :
    ('d, 'k) Arkode.ARKStep.session -> Arkode.ButcherTable.ark_table -> unit
  val set_erk_table_num :
    ('d, 'k) Arkode.ARKStep.session -> Arkode.ButcherTable.erk_table -> unit
  val set_dirk_table_num :
    ('d, 'k) Arkode.ARKStep.session -> Arkode.ButcherTable.dirk_table -> unit
  val set_adaptivity_method :
    ('d, 'k) Arkode.ARKStep.session -> 'd adaptivity_method -> unit
  val set_cfl_fraction : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_error_bias : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_fixed_step_bounds :
    ('d, 'k) Arkode.ARKStep.session -> float -> float -> unit
  val set_max_cfail_growth : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_max_efail_growth : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_max_first_growth : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_max_growth : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_min_reduction : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_safety_factor : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_small_num_efails : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_stability_fn :
    ('d, 'k) Arkode.ARKStep.session -> 'd stability_fn -> unit
  val clear_stability_fn : ('d, 'k) Arkode.ARKStep.session -> unit
  val set_linear : ('d, 'k) Arkode.ARKStep.session -> bool -> unit
  val set_nonlinear : ('d, 'k) Arkode.ARKStep.session -> unit
  val set_predictor_method :
    ('d, 'k) Arkode.ARKStep.session -> predictor_method -> unit
  val set_max_nonlin_iters : ('d, 'k) Arkode.ARKStep.session -> int -> unit
  val set_max_conv_fails : ('d, 'k) Arkode.ARKStep.session -> int -> unit
  type 'd stage_predict_fn = float -> '-> unit
  val set_stage_predict_fn :
    ('d, 'k) Arkode.ARKStep.session ->
    'Arkode.ARKStep.stage_predict_fn -> unit
  val clear_stage_predict_fn : ('d, 'k) Arkode.ARKStep.session -> unit
  val set_nonlin_conv_coef : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_constraints :
    ('d, 'k) Arkode.ARKStep.session -> ('d, 'k) Nvector.t -> unit
  val set_nonlin_crdown : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_nonlin_rdiv : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_delta_gamma_max : ('d, 'k) Arkode.ARKStep.session -> float -> unit
  val set_lsetup_frequency : ('d, 'k) Arkode.ARKStep.session -> int -> unit
  val set_postprocess_step_fn :
    ('d, 'k) Arkode.ARKStep.session -> 'd postprocess_step_fn -> unit
  val clear_postprocess_step_fn : ('d, 'k) Arkode.ARKStep.session -> unit
  val get_work_space : ('d, 'k) Arkode.ARKStep.session -> int * int
  val get_num_steps : ('d, 'k) Arkode.ARKStep.session -> int
  val get_num_exp_steps : ('d, 'k) Arkode.ARKStep.session -> int
  val get_num_acc_steps : ('d, 'k) Arkode.ARKStep.session -> int
  val get_num_step_attempts : ('d, 'k) Arkode.ARKStep.session -> int
  val get_num_rhs_evals : ('d, 'k) Arkode.ARKStep.session -> int * int
  val get_num_err_test_fails : ('d, 'k) Arkode.ARKStep.session -> int
  val get_last_step : ('d, 'k) Arkode.ARKStep.session -> float
  val get_current_step : ('d, 'k) Arkode.ARKStep.session -> float
  val get_actual_init_step : ('d, 'k) Arkode.ARKStep.session -> float
  val get_current_time : ('d, 'k) Arkode.ARKStep.session -> float
  val get_current_state : ('d, 'k) Arkode.ARKStep.session -> 'd
  val get_nonlin_system_data :
    ('d, 'k) Arkode.ARKStep.session -> 'd nonlin_system_data
  val compute_state :
    ('d, 'k) Arkode.ARKStep.session ->
    ('d, 'k) Nvector.t -> ('d, 'k) Nvector.t -> unit
  val get_current_gamma : ('d, 'k) Arkode.ARKStep.session -> float
  val get_current_butcher_tables :
    ('d, 'k) Arkode.ARKStep.session ->
    Arkode.ButcherTable.t option * Arkode.ButcherTable.t option
  val get_tol_scale_factor : ('d, 'k) Arkode.ARKStep.session -> float
  val get_err_weights :
    ('d, 'k) Arkode.ARKStep.session -> ('d, 'k) Nvector.t -> unit
  val get_res_weights :
    ('d, 'k) Arkode.ARKStep.session -> ('d, 'k) Nvector.t -> unit
  val get_est_local_errors :
    ('d, 'k) Arkode.ARKStep.session -> ('d, 'k) Nvector.t -> unit
  type timestepper_stats = {
    exp_steps : int;
    acc_steps : int;
    step_attempts : int;
    num_nfe_evals : int;
    num_nfi_evals : int;
    num_lin_solv_setups : int;
    num_err_test_fails : int;
  }
  val get_timestepper_stats :
    ('d, 'k) Arkode.ARKStep.session -> Arkode.ARKStep.timestepper_stats
  val get_step_stats : ('d, 'k) Arkode.ARKStep.session -> step_stats
  val print_timestepper_stats :
    ('d, 'k) Arkode.ARKStep.session -> Stdlib.out_channel -> unit
  val print_step_stats :
    ('d, 'k) Arkode.ARKStep.session -> Stdlib.out_channel -> unit
  val write_session :
    ?logfile:Sundials.Logfile.t -> ('d, 'k) Arkode.ARKStep.session -> unit
  val get_num_lin_solv_setups : ('d, 'k) Arkode.ARKStep.session -> int
  val get_num_nonlin_solv_iters : ('d, 'k) Arkode.ARKStep.session -> int
  val get_num_nonlin_solv_conv_fails : ('d, 'k) Arkode.ARKStep.session -> int
  val get_nonlin_solv_stats : ('d, 'k) Arkode.ARKStep.session -> int * int
  val set_root_direction :
    ('d, 'k) Arkode.ARKStep.session -> Sundials.RootDirs.d array -> unit
  val set_all_root_directions :
    ('d, 'k) Arkode.ARKStep.session -> Sundials.RootDirs.d -> unit
  val set_no_inactive_root_warn : ('d, 'k) Arkode.ARKStep.session -> unit
  val get_num_roots : ('d, 'k) Arkode.ARKStep.session -> int
  val get_root_info :
    ('d, 'k) Arkode.ARKStep.session -> Sundials.Roots.t -> unit
  val get_num_g_evals : ('d, 'k) Arkode.ARKStep.session -> int
  val get_num_constr_fails : ('d, 'k) Arkode.ARKStep.session -> int
  val write_parameters :
    ?logfile:Sundials.Logfile.t -> ('d, 'k) Arkode.ARKStep.session -> unit
  val write_butcher :
    ?logfile:Sundials.Logfile.t -> ('d, 'k) Arkode.ARKStep.session -> unit
end