Reference documentation for deal.II version 9.3.0

#include <deal.II/sundials/arkode.h>
Classes  
class  AdditionalData 
Public Member Functions  
ARKode (const AdditionalData &data=AdditionalData(), const MPI_Comm &mpi_comm=MPI_COMM_WORLD)  
~ARKode ()  
unsigned int  solve_ode (VectorType &solution) 
unsigned int  solve_ode_incrementally (VectorType &solution, const double intermediate_time, const bool reset_solver=false) 
void  reset (const double t, const double h, const VectorType &y) 
void *  get_arkode_memory () const 
Private Member Functions  
DeclException1 (ExcFunctionNotProvided, std::string,<< "Please provide an implementation for the function << arg1<< "\")  
int  do_evolve_time (VectorType &solution, ::DiscreteTime &time, const bool do_reset) 
void  setup_system_solver (const VectorType &solution) 
void  setup_mass_solver (const VectorType &solution) 
void  set_functions_to_trigger_an_assert () 
Private Attributes  
AdditionalData  data 
void *  arkode_mem 
MPI_Comm  communicator 
double  last_end_time 
std::unique_ptr< internal::LinearSolverWrapper< VectorType > >  linear_solver 
std::unique_ptr< internal::LinearSolverWrapper< VectorType > >  mass_solver 
Interface to SUNDIALS additive RungeKutta methods (ARKode).
The class ARKode is a wrapper to SUNDIALS variablestep, embedded, additive RungeKutta solver which is a general purpose solver for systems of ordinary differential equations characterized by the presence of both fast and slow dynamics.
Fast dynamics are treated implicitly, and slow dynamics are treated explicitly, using nested families of implicit and explicit RungeKutta solvers.
Citing directly from ARKode documentation:
ARKode solves ODE initial value problems (IVPs) in \(R^N\). These problems should be posed in explicit form as
\[ M\dot y = f_E(t, y) + f_I (t, y), \qquad y(t_0) = y_0. \]
Here, \(t\) is the independent variable (e.g. time), and the dependent variables are given by \(y \in R^N\), and we use notation \(\dot y\) to denote \(dy/dt\). \(M\) is a usersupplied nonsingular operator from \(R^N \to R^N\). This operator may depend on \(t\) but not on \(y\).
For standard systems of ordinary differential equations and for problems arising from the spatial semidiscretization of partial differential equations using finite difference or finite volume methods, \(M\) is typically the identity matrix, \(I\). For PDEs using a finiteelement spatial semidiscretization \(M\) is typically a wellconditioned mass matrix.
The two righthand side functions may be described as:
ARKode may be used to solve stiff, nonstiff and multirate problems. Roughly speaking, stiffness is characterized by the presence of at least one rapidly damped mode, whose time constant is small compared to the time scale of the solution itself. In the implicit/explicit (ImEx) splitting above, these stiff components should be included in the righthand side function \(f_I (t, y)\).
For multirate problems, a user should provide both of the functions \(f_E\) and \(f_I\) that define the IVP system.
For nonstiff problems, only \(f_E\) should be provided, and \(f_I\) is assumed to be zero, i.e. the system reduces to the nonsplit IVP:
\[ M\dot y = f_E(t, y), \qquad y(t_0) = y_0. \]
In this scenario, the ARK methods reduce to classical explicit RungeKutta methods (ERK). For these classes of methods, ARKode allows orders of accuracy \(q = \{2, 3, 4, 5, 6, 8\}\), with embeddings of orders \(p = \{1, 2, 3, 4, 5, 7\}\). These default to the HeunEuler212, BogackiShampine423, Zonneveld534, CashKarp645, Verner856 and Fehlberg1378 methods, respectively.
Finally, for stiff (linear or nonlinear) problems the user may provide only \(f_I\), implying that \(f_E = 0\), so that the system reduces to the nonsplit IVP
\[ M\dot y = f_I(t, y), \qquad y(t_0) = y_0. \]
Similarly to ERK methods, in this scenario the ARK methods reduce to classical diagonallyimplicit RungeKutta methods (DIRK). For these classes of methods, ARKode allows orders of accuracy \(q = \{2, 3, 4, 5\}\), with embeddings of orders \(p = \{1, 2, 3, 4\}\). These default to the SDIRK212, ARK423 (implicit), SDIRK534 and ARK845 (implicit) methods, respectively.
For both DIRK and ARK methods, an implicit system of the form
\[ G(z_i) \dealcoloneq M z_i  h_n A^I_{i,i} f_I (t^I_{n,i}, z_i)  a_i = 0 \]
must be solved for each stage \(z_i , i = 1, \ldots, s\), where we have the data
\[ a_i \dealcoloneq M y_{n1} + h_n \sum_{j=1}^{i1} [ A^E_{i,j} f_E(t^E_{n,j}, z_j) + A^I_{i,j} f_I (t^I_{n,j}, z_j)] \]
for the ARK methods, or
\[ a_i \dealcoloneq M y_{n1} + h_n \sum_{j=1}^{i1} A^I_{i,j} f_I (t^I_{n,j}, z_j) \]
for the DIRK methods. Here \(A^I_{i,j}\) and \(A^E_{i,j}\) are the Butcher's tables for the chosen solver.
If \(f_I(t,y)\) depends nonlinearly on \(y\) then the systems above correspond to a nonlinear system of equations; if \(f_I (t, y)\) depends linearly on \(y\) then this is a linear system of equations. By specifying the flag implicit_function_is_linear
, ARKode takes some shortcuts that allow a faster solution process.
For systems of either type, ARKode allows a choice of solution strategy. The default solver choice is a variant of Newton's method,
\[ z_i^{m+1} = z_i^m +\delta^{m+1}, \]
where \(m\) is the Newton index, and the Newton update \(\delta^{m+1}\) requires the solution of the linear Newton system
\[ N(z_i^m) \delta^{m+1} = G(z_i^m), \]
where
\[ N \dealcoloneq M  \gamma J, \quad J \dealcoloneq \frac{\partial f_I}{\partial y}, \qquad \gamma\dealcoloneq h_n A^I_{i,i}. \]
As an alternate to Newton's method, ARKode may solve for each stage \(z_i ,i = 1, \ldots , s\) using an Andersonaccelerated fixed point iteration
\[ z_i^{m+1} = g(z_i^{m}), m=0,1,\ldots. \]
Unlike with Newton's method, this option does not require the solution of a linear system at each iteration, instead opting for solution of a lowdimensional leastsquares solution to construct the nonlinear update.
Finally, if the user specifies implicit_function_is_linear
, i.e., \(f_I(t, y)\) depends linearly on \(y\), and if the Newtonbased nonlinear solver is chosen, then the system will be solved using only a single Newton iteration. Notice that in order for the Newton solver to be used, at least the jacobian_times_vector() function (or solve_jacobian_system() for SUNDIALS version > 4.0.0) should be supplied. If this function is not supplied, then only the fixedpoint iteration will be supported, and the implicit_function_is_linear
setting is ignored.
The optimal solver (Newton vs fixedpoint) is highly problemdependent. Since fixedpoint solvers do not require the solution of any linear systems, each iteration may be significantly less costly than their Newton counterparts. However, this can come at the cost of slower convergence (or even divergence) in comparison with Newtonlike methods. These fixedpoint solvers do allow for user specification of the Andersonaccelerated subspace size, \(m_k\). While the required amount of solver memory grows proportionately to \(m_k N\), larger values of \(m_k\) may result in faster convergence.
This improvement may be significant even for "small" values, e.g. \(1 \leq m_k \leq 5\), and convergence may not improve (or even deteriorate) for larger values of \(m_k\). While ARKode uses a Newtonbased iteration as its default solver due to its increased robustness on very stiff problems, it is highly recommended that users also consider the fixedpoint solver for their cases when attempting a new problem.
For either the Newton or fixedpoint solvers, it is wellknown that both the efficiency and robustness of the algorithm intimately depends on the choice of a good initial guess. In ARKode, the initial guess for either nonlinear solution method is a predicted value \(z_i(0)\) that is computed explicitly from the previouslycomputed data (e.g. \(y_{n2}, y_{n1}\), and \(z_j\) where \(j < i\)). Additional information on the specific predictor algorithms implemented in ARKode is provided in ARKode documentation.
The user has to provide the implementation of at least one (or both) of the following std::function
s:
If the mass matrix is different from the identity, the user should supply
If the use of a Newton method is desired, then the user should also supply
Only for SUNDIALS version > 4.0.0: A SUNDIALS default solver (SPGMR) is used to solve the linear systems. To use a custom linear solver for the mass matrix and/or Jacobian, set:
Only for SUNDIALS version > 4.0.0: To use a custom preconditioner with either a default or custom linear solver, set:
Also the following functions could be rewritten. By default they do nothing, or are not required.
To produce output at fixed steps, set the function
Any other custom settings of the ARKODE object can be specified in
To provide a simple example, consider the harmonic oscillator problem:
\[ \begin{split} u'' & = k^2 u \\ u (0) & = 0 \\ u'(0) & = k \end{split} \]
We write it in terms of a first order ode:
\[ \begin{matrix} y_0' & = y_1 \\ y_1' & =  k^2 y_0 \end{matrix} \]
That is \(y' = A y\) where
\[ A \dealcoloneq \begin{matrix} 0 & 1 \\ k^2 &0 \end{matrix} \]
and \(y(0)=(0, k)\).
The exact solution is \(y_0(t) = \sin(k t)\), \(y_1(t) = y_0'(t) = k \cos(k *t)\), \(y_1'(t) = k^2 \sin(k t)\).
A minimal implementation, using only explicit RK methods, is given by the following code snippet:
SUNDIALS::ARKode< VectorType >::ARKode  (  const AdditionalData &  data = AdditionalData() , 
const MPI_Comm &  mpi_comm = MPI_COMM_WORLD 

) 
SUNDIALS::ARKode< VectorType >::~ARKode  (  ) 
unsigned int SUNDIALS::ARKode< VectorType >::solve_ode  (  VectorType &  solution  ) 
unsigned int SUNDIALS::ARKode< VectorType >::solve_ode_incrementally  (  VectorType &  solution, 
const double  intermediate_time,  
const bool  reset_solver = false 

) 
Integrate the initial value problem. Compared to the function above, this function allows to specify an intermediate_time
for the next solution. Repeated calls of this function must use monotonously increasing values for intermediate_time
. The last solution state is saved internally along with the intermediate_time
and will be reused as initial condition for the next call.
Users may find this function useful when integrating ARKode into an outer time loop of their own, especially when output_step() is too restrictive.
intermediate_time
may be larger than AdditionalData::final_time, which is ignored by this function.solution  The final solution. If the solver restarts, either because it is the first ever solve or the flag reset_solver is set, the vector is also used as initial condition. 
intermediate_time  The time for the incremental solution step. Must be greater than the last time that was used in a previous call to this function. 
reset_solver  Optional flag to recreate all internal objects which may be desirable for spatial adaptivity methods. If set to true , reset() is called before solving the ODE, which sets solution as initial condition. This will not reset the stored time from previous calls to this function. 
void SUNDIALS::ARKode< VectorType >::reset  (  const double  t, 
const double  h,  
const VectorType &  y  
) 
Clear internal memory and start with clean objects. This function is called when the simulation starts and when the user returns true to a call to solver_should_restart().
By default solver_should_restart() returns false. If the user needs to implement, for example, local adaptivity in space, he or she may assign a different function to solver_should_restart() that performs all mesh changes, transfers the solution to the new mesh, and returns true.
t  The new starting time 
h  The new starting time step 
y  The new initial solution 
void * SUNDIALS::ARKode< VectorType >::get_arkode_memory  (  )  const 
Provides user access to the internally used ARKODE memory.
This functionality is intended for users who wish to query additional information directly from the ARKODE integrator, refer to the ARKODE manual for the various ARKStepGet...
functions. The ARKStepSet...
functions should not be called since this might lead to conflicts with various settings that are performed by this ARKode object.

private 
Throw an exception when a function with the given name is not implemented.

private 

private 

private 

private 
DEAL_II_DEPRECATED std::function<void(VectorType &)> SUNDIALS::ARKode< VectorType >::reinit_vector 
A function object that was used to reinit
the given vector. Setting this field does no longer have any effect and all auxiliary vectors are reinited automatically based on the usersupplied vector in solve_ode().
std::function< int(const double t, const VectorType &y, VectorType &explicit_f)> SUNDIALS::ARKode< VectorType >::explicit_function 
A function object that users may supply and that is intended to compute the explicit part of the IVP right hand side. Sets \(explicit_f = f_E(t, y)\).
At least one of explicit_function() or implicit_function() must be provided. According to which one is provided, explicit, implicit, or mixed RK methods are used.
This function should return:
std::function<int(const double t, const VectorType &y, VectorType &res)> SUNDIALS::ARKode< VectorType >::implicit_function 
A function object that users may supply and that is intended to compute the implicit part of the IVP right hand side. Sets \(implicit_f = f_I(t, y)\).
At least one of explicit_function() or implicit_function() must be provided. According to which one is provided, explicit, implicit, or mixed RK methods are used.
This function should return:
std::function<int(const int convfail, const double t, const double gamma, const VectorType &ypred, const VectorType &fpred, bool & j_is_current)> SUNDIALS::ARKode< VectorType >::setup_jacobian 
A function object that users may supply and that is intended to prepare the linear solver for subsequent calls to solve_jacobian_system().
Make sure that after a call to this function, we know how to compute solutions of systems \(A x = b\), where \(A\) is some approximation to the Newton matrix, \(M  \gamma \partial f_I/\partial y\). This function is optional. If the user does not provide it, then solve_jacobian_system() is assumed to also perform the setup internally.
The setup_jacobian() function may call a usersupplied function to compute needed data related to the Jacobian matrix. Alternatively, it may choose to retrieve and use stored values of this data. In either case, setup_jacobian() may also preprocess that data as needed for solve_jacobian_system(), which may involve calling a generic function (such as for LU factorization).
This data may be intended either for direct use (in a direct linear solver) or for use in a preconditioner (in a preconditioned iterative linear solver). The setup_jacobian() function is not called at every stage solve (or even every time step), but only as frequently as the solver determines that it is appropriate to perform the setup task. In this way, Jacobianrelated data generated by setup_jacobian() is expected to be used over a number of time steps.
If the user uses a matrix based computation of the Jacobian, then this is the right place where an assembly routine shoulde be called to assemble both a matrix and a preconditioner for the Jacobian system. Subsequent calls (possibly more than one) to solve_jacobian_system() can assume that this function has been called at least once.
Notice that no assumption is made by this interface on what the user should do in this function. ARKode only assumes that after a call to setup_jacobian() it is possible to call solve_jacobian_system(), to obtain a solution \(x\) to the system \(J x = b\). If this function is not provided, then it is never called.
Arguments to the function are
[in]  t  the current time 
[in]  gamma  the current factor to use in the jacobian computation 
[in]  ypred  is the predicted \(y\) vector for the current ARKode internal step 
[in]  fpred  is the value of the implicit righthand side at ypred, \(f_I (t_n, ypred)\). 
[in]  convfail  Input flag used to indicate any problem that occurred during the solution of the nonlinear equation on the current time step for which the linear solver is being used. This flag can be used to help decide whether the Jacobian data kept by a linear solver needs to be updated or not. Its possible values are: 
[out]  j_is_current  a boolean to be filled in by setup_jacobian(). The value should be set to true if the Jacobian data is current after the call, and should be set to false if its Jacobian data is not current. If setup_jacobian() calls for reevaluation of Jacobian data (based on convfail and ARKode state data), then it should set j_is_current to true unconditionally, otherwise an infinite loop can result. 
This function should return:
std::function<int(const double t, const double gamma, const VectorType &ycur, const VectorType &fcur, const VectorType &rhs, VectorType & dst)> SUNDIALS::ARKode< VectorType >::solve_jacobian_system 
A function object that users may supply and that is intended to solve the Jacobian linear system. This function will be called by ARKode (possibly several times) after setup_jacobian() has been called at least once. ARKode tries to do its best to call setup_jacobian() the minimum amount of times. If convergence can be achieved without updating the Jacobian, then ARKode does not call setup_jacobian() again. If, on the contrary, internal ARKode convergence tests fail, then ARKode calls again setup_jacobian() with updated vectors and coefficients so that successive calls to solve_jacobian_systems() lead to better convergence in the Newton process.
If you do not specify a solve_jacobian_system() function, then a fixed point iteration is used instead of a Newton method. Notice that this may not converge, or may converge very slowly.
The jacobian \(J\) should be (an approximation of) the system Jacobian
\[ J = M  \gamma \frac{\partial f_I}{\partial y} \]
evaluated at t
, ycur
. fcur
is \(f_I(t,ycur)\).
A call to this function should store in dst
the result of \(J^{1}\) applied to src
, i.e., J*dst = src
. It is the users responsibility to set up proper solvers and preconditioners inside this function.
Arguments to the function are
[in]  t  the current time 
[in]  gamma  the current factor to use in the jacobian computation 
[in]  ycur  is the current \(y\) vector for the current ARKode internal step 
[in]  fcur  is the current value of the implicit righthand side at ycur, \(f_I (t_n, ypred)\). 
This function should return:
std::function<int(const double t)> SUNDIALS::ARKode< VectorType >::setup_mass 
A function object that users may supply and that is intended to set up the mass matrix. This function is called by ARKode any time a mass matrix update is required. The user should compute the mass matrix (or update all the variables that allow the application of the mass matrix). This function is called by ARKode once, before any call to solve_mass_system().
ARKode supports the case where the mass matrix may depend on time, but not the case where the mass matrix depends on the solution itself.
If the user does not provide a solve_mass_matrix() function, then the identity is used. If the setup_mass() function is not provided, then solve_mass_system() should do all the work by itself.
If the user uses a matrix based computation of the mass matrix, then this is the right place where an assembly routine shoulde be called to assemble both a matrix and a preconditioner. Subsequent calls (possibly more than one) to solve_mass_system() can assume that this function has been called at least once.
Notice that no assumption is made by this interface on what the user should do in this function. ARKode only assumes that after a call to setup_mass() it is possible to call solve_mass_system(), to obtain a solution \(x\) to the system \(M x = b\).
This function should return:
std::function<int(const VectorType &rhs, VectorType &dst)> SUNDIALS::ARKode< VectorType >::solve_mass_system 
A function object that users may supply and that is intended to solve the mass matrix linear system. This function will be called by ARKode (possibly several times) after setup_mass() has been called at least once. ARKode tries to do its best to call setup_mass() the minimum amount of times.
A call to this function should store in dst
the result of \(M^{1}\) applied to src
, i.e., M*dst = src
. It is the users responsibility to set up proper solvers and preconditioners inside this function.
This function should return:
std::function<int(double t, const VectorType &v, VectorType &Mv)> SUNDIALS::ARKode< VectorType >::mass_times_vector 
A function object that users may supply and that is intended to compute the product of the mass matrix with a given vector v
. This function will be called by ARKode (possibly several times) after mass_times_setup() has been called at least once. ARKode tries to do its best to call mass_times_setup() the minimum amount of times.
A call to this function should store in Mv
the result of \(M\) applied to v
.
This function should return:
std::function<int(const double t)> SUNDIALS::ARKode< VectorType >::mass_times_setup 
A function object that users may supply and that is intended to set up the mass matrix. This function is called by ARKode any time a mass matrix update is required. The user should compute the mass matrix (or update all the variables that allow the application of the mass matrix). This function is guaranteed to be called by ARKode at least once, before any call to mass_times_vector().
ARKode supports the case where the mass matrix may depend on time, but not the case where the mass matrix depends on the solution itself.
If the user does not provide a mass_times_vector() function, then the identity is used. If the mass_times_setup() function is not provided, then mass_times_vector() should do all the work by itself.
If the user uses a matrixbased computation of the mass matrix, then this is the right place where an assembly routine should be called to assemble the matrix. Subsequent calls (possibly more than one) to mass_times_vector() can assume that this function has been called at least once.
t  The current evaluation time 
This function should return:
std::function<int(const VectorType &v, VectorType & Jv, double t, const VectorType &y, const VectorType &fy)> SUNDIALS::ARKode< VectorType >::jacobian_times_vector 
A function object that users may supply and that is intended to compute the product of the Jacobian matrix with a given vector v
. The Jacobian here refers to \(J=\frac{\partial f_I}{\partial y}\), i.e., the Jacobian of the userspecified implicit_function.
A call to this function should store in Jv
the result of \(J\) applied to v
.
Arguments to the function are
[in]  v  The vector to be multiplied by the Jacobian 
[out]  Jv  The vector to be filled with the product J*v 
[in]  t  The current time 
[in]  y  The current \(y\) vector for the current ARKode internal step 
[in]  fy  The current value of the implicit righthand side at y, \(f_I (t_n, y)\). 
This function should return:
std::function<int(realtype t, const VectorType &y, const VectorType &fy)> SUNDIALS::ARKode< VectorType >::jacobian_times_setup 
A function object that users may supply and that is intended to set up all data necessary for the application of jacobian_times_setup(). This function is called by ARKode any time a Jacobian update is required. The user should compute the Jacobian (or update all the variables that allow the application of Jacobian). This function is guaranteed to be called by ARKode at least once, before any call to jacobian_times_vector().
If the jacobian_times_setup() function is not provided, then jacobian_times_vector() should do all the work by itself.
If the user uses a matrix based computation of the Jacobian, then this is the right place where an assembly routine should be called to assemble the matrix. Subsequent calls (possibly more than one) to jacobian_times_vector() can assume that this function has been called at least once.
t  The current time 
y  The current ARKode internal solution vector \(y\) 
fy  The implicit righthand side function evaluated at the current time \(t\) and state \(y\), i.e., \(f_I(y,t)\) 
This function should return:
LinearSolveFunction<VectorType> SUNDIALS::ARKode< VectorType >::solve_linearized_system 
A LinearSolveFunction object that users may supply and that is intended to solve the linearized system \(Ax=b\), where \(A = M\gamma J\) is the Jacobian of the nonlinear residual. The application of the mass matrix \(M\) and Jacobian \(J\) are known through the functions mass_times_vector() and jacobian_times_vector() and \(\gamma\) is a factor provided by SUNDIALS. The matrixvector product \(Ax\) is encoded in the supplied SundialsOperator. If a preconditioner was set through jacobian_preconditioner_solve(), it is encoded in the SundialsPreconditioner. If no preconditioner was supplied this way, the preconditioner is the identity matrix, i.e., no preconditioner. The user is free to use a custom preconditioner in this function object that is not supplied through SUNDIALS.
If you do not specify a solve_linearized_system() function, then a SUNDIALS packaged SPGMR solver with default settings is used.
For more details on the function type refer to LinearSolveFunction.
LinearSolveFunction<VectorType> SUNDIALS::ARKode< VectorType >::solve_mass 
A LinearSolveFunction object that users may supply and that is intended to solve the mass system \(Mx=b\). The matrixvector product \(Mx\) is encoded in the supplied SundialsOperator. If a preconditioner was set through mass_preconditioner_solve(), it is encoded in the SundialsPreconditioner. If no preconditioner was supplied this way, the preconditioner is the identity matrix, i.e., no preconditioner. The user is free to use a custom preconditioner in this function object that is not supplied through SUNDIALS.
The user must specify this function if a nonidentity mass matrix is used and applied in mass_times_vector().
For more details on the function type refer to LinearSolveFunction.
std::function<int(double t, const VectorType &y, const VectorType &fy, const VectorType &r, VectorType & z, double gamma, double tol, int lr)> SUNDIALS::ARKode< VectorType >::jacobian_preconditioner_solve 
A function object that users may supply to either pass a preconditioner to a SUNDIALS builtin solver or to apply a custom preconditioner within the user's own linear solve specified in solve_linearized_system().
This function should compute the solution to the preconditioner equation \(Pz=r\) and store it in z
. In this equation \(P\) should approximate the Jacobian \(M\gamma J\) of the nonlinear system.
[in]  t  The current time 
[in]  y  The current \(y\) vector for the current ARKode internal step 
[in]  fy  The current value of the implicit righthand side at y, \(f_I (t_n, y)\). 
[in]  r  The righthand side of the preconditioner equation 
[out]  z  The solution of applying the preconditioner, i.e., solving \(Pz=r\) 
[in]  gamma  The value \(\gamma\) in the preconditioner equation 
[in]  tol  The tolerance up to which the system should be solved 
[in]  lr  An input flag indicating whether the preconditioner solve is to use the left preconditioner (lr = 1) or the right preconditioner (lr = 2). Only relevant if used with a SUNDIALS packaged solver. If used with a custom solve_mass() function this will be set to zero. 
This function should return:
std::function<int(double t, const VectorType &y, const VectorType &fy, int jok, int & jcur, double gamma)> SUNDIALS::ARKode< VectorType >::jacobian_preconditioner_setup 
A function object that users may supply to set up a preconditioner specified in jacobian_preconditioner_solve().
This function should prepare the solution of the preconditioner equation \(Pz=r\). In this equation \(P\) should approximate the Jacobian \(M\gamma J\) of the nonlinear system.
If the jacobian_preconditioner_setup() function is not provided, then jacobian_preconditioner_solve() should do all the work by itself.
[in]  t  The current time 
[in]  y  The current \(y\) vector for the current ARKode internal step 
[in]  fy  The current value of the implicit righthand side at y, \(f_I (t_n, y)\). 
[in]  jok  An input flag indicating whether the Jacobianrelated data needs to be updated. The jok argument provides for the reuse of Jacobian data in the preconditioner solve function. When jok = SUNFALSE, the Jacobianrelated data should be recomputed from scratch. When jok = SUNTRUE the Jacobian data, if saved from the previous call to this function, can be reused (with the current value of gamma). A call with jok = SUNTRUE can only occur after a call with jok = SUNFALSE. 
[out]  jcur  On output this should be set to SUNTRUE if Jacobian data was recomputed, or set to SUNFALSE if Jacobian data was not recomputed, but saved data was still reused. 
[in]  gamma  The value \(\gamma\) in \(M\gamma J\). The preconditioner should approximate the inverse of this matrix. 
This function should return:
std::function< int(double t, const VectorType &r, VectorType &z, double tol, int lr)> SUNDIALS::ARKode< VectorType >::mass_preconditioner_solve 
A function object that users may supply to either pass a preconditioner to a SUNDIALS builtin solver or to apply a custom preconditioner within the user's own linear solve specified in solve_mass().
This function should compute the solution to the preconditioner equation \(Pz=r\) and store it in z
. In this equation \(P\) should approximate the mass matrix \(M\).
[in]  t  The current time 
[in]  r  The righthand side of the preconditioner equation 
[out]  z  The solution of applying the preconditioner, i.e., solving \(Pz=r\) 
[in]  gamma  The value \(\gamma\) in the preconditioner equation 
[in]  tol  The tolerance up to which the system should be solved 
[in]  lr  An input flag indicating whether the preconditioner solve is to use the left preconditioner (lr = 1) or the right preconditioner (lr = 2). Only relevant if used with a SUNDIALS packaged solver. If used with a custom solve_mass() function this will be set to zero. 
This function should return:
std::function<int(double t)> SUNDIALS::ARKode< VectorType >::mass_preconditioner_setup 
A function object that users may supply to set up a preconditioner specified in mass_preconditioner_solve().
This function should prepare the solution of the preconditioner equation \(Pz=r\). In this equation \(P\) should approximate the mass matrix \(M\).
If the mass_preconditioner_setup() function is not provided, then mass_preconditioner_solve() should do all the work by itself.
[in]  t  The current time 
This function should return:
std::function<void(const double t, const VectorType & sol, const unsigned int step_number)> SUNDIALS::ARKode< VectorType >::output_step 
A function object that users may supply and that is intended to postprocess the solution. This function is called by ARKode at fixed time increments (every output_period
seconds), and it is passed a polynomial interpolation of the solution, computed using the current ARK order and the (internally stored) previously computed solution steps.
output_period
step, and therefore calls this function consecutively several times by simply performing all intermediate interpolations. There is no relationship between how many times this function is called and how many time steps have actually been computed. std::function<bool(const double t, VectorType &sol)> SUNDIALS::ARKode< VectorType >::solver_should_restart 
A function object that users may supply and that is intended to evaluate whether the solver should be restarted (for example because the number of degrees of freedom has changed).
This function is supposed to perform all operations that are necessary in sol
to make sure that the resulting vectors are consistent, and of the correct final size.
For example, one may decide that a local refinement is necessary at time t. This function should then return true, and change the dimension of sol
to reflect the new dimension. Since ARKode does not know about the new dimension, an internal reset is necessary.
The default implementation simply returns false
, i.e., no restart is performed during the evolution.
std::function<VectorType &()> SUNDIALS::ARKode< VectorType >::get_local_tolerances 
std::function<void(void *arkode_mem)> SUNDIALS::ARKode< VectorType >::custom_setup 
A function object that users may supply and which is intended to perform custom settings on the supplied arkode_mem
object. Refer to the SUNDIALS documentation for valid options.
For instance, the following code attaches two files for diagnostic and error output of the internal ARKODE implementation:
arkode_mem  pointer to the ARKODE memory block which can be used for custom calls to ARKStepSet... methods. 

private 

private 

private 

private 
The final time in the last call to solve_ode().

private 

private 