Output and Saving Controls

These callbacks extend the output and saving controls available during time stepping.

DiffEqCallbacks.SavedValuesType
SavedValues{tType<:Real, savevalType}

Container used by SavingCallback to store saved time points and user-defined values.

Fields

  • t::Vector{tType}: saved time points.
  • saveval::Vector{savevalType}: values returned by the saving function.
source
DiffEqCallbacks.SavingCallbackFunction
SavingCallback(save_func, saved_values::SavedValues;
    saveat = Vector{eltype(saved_values.t)}(),
    save_everystep = isempty(saveat),
    save_start = true,
    tdir = 1)

The saving callback lets you define a function save_func(u, t, integrator) which returns quantities of interest that shall be saved.

Arguments

  • save_func(u, t, integrator) returns the quantities which shall be saved. Note that this should allocate the output (not as a view to u).
  • saved_values::SavedValues is the types that save_func will return, i.e. save_func(t, u, integrator)::savevalType. It's specified via SavedValues(typeof(t),savevalType), i.e. give the type for time and the type that save_func will output (or higher compatible type).

Keyword Arguments

  • saveat mimics saveat in solve from solve.
  • save_everystep mimics save_everystep from solve.
  • save_start mimics save_start from solve.
  • save_end mimics save_end from solve.
  • tdir should be sign(tspan[end]-tspan[1]). It defaults to 1 and should be adapted if tspan[1] > tspan[end].

The outputted values are saved into saved_values. Time points are found via saved_values.t and the values are saved_values.saveval.

source
DiffEqCallbacks.FunctionCallingCallbackFunction
FunctionCallingCallback(func;
    funcat = Vector{Float64}(),
    func_everystep = isempty(funcat),
    func_start = true,
    tdir = 1)

The function calling callback lets you define a function func(u,t,integrator) which gets called at the time points of interest. The constructor is:

  • func(u, t, integrator) is the function to be called.
  • funcat values or interval that the function is sure to be evaluated at.
  • func_everystep whether to call the function after each integrator step.
  • func_start whether the function is called at the initial condition.
  • tdir should be sign(tspan[end]-tspan[1]). It defaults to 1 and should be adapted if tspan[1] > tspan[end].
source
DiffEqCallbacks.IndependentlyLinearizedSolutionType
IndependentlyLinearizedSolution
IndependentlyLinearizedSolution(prob::SciMLBase.AbstractDEProblem, num_derivatives = 0)

Efficient datastructure that holds a set of independently linearized solutions (obtained via the LinearizingSavingCallback) with related, but slightly different time vectors. Stores a single time vector with a packed BitMatrix denoting which u vectors are sampled at which timepoints. Provides an efficient iterate() method that can be used to reconstruct coherent views of the state variables at all timepoints, as well as an efficient sample!() method that can sample at arbitrary timesteps.

Arguments

  • prob: differential equation problem used to infer the time, state, and storage dimensions.
  • num_derivatives: number of derivative rows to store in addition to the primal state values.

Returns

An IndependentlyLinearizedSolution storage object for use with LinearizingSavingCallback.

Example

ils = IndependentlyLinearizedSolution(prob)
sol = solve(prob, solver; callback = LinearizingSavingCallback(ils))
source
DiffEqCallbacks.LinearizingSavingCallbackFunction
LinearizingSavingCallback(ils::IndependentlyLinearizedSolution)
LinearizingSavingCallback(ilss::Vector{IndependentlyLinearizedSolution})

Return a saving callback that inserts interpolation points so that linear interpolation of the saved values is within abstol/reltol of the integrator interpolation.

The algorithm internally checks 3 equidistant points between each time point to determine goodness of fit versus the linearly interpolated function; this should be sufficient for interpolations up to the 4th order, higher orders may need more points to ensure good fit. This has not been implemented yet.

Arguments

Keyword Arguments

  • interpolate_mask: a BitVector selecting the u indices for which the integrator interpolant can be queried. False indices are linearly interpolated from the solution time points without subdivision.
  • abstol: absolute tolerance for comparing linearized and integrator interpolation. Defaults to the integrator absolute tolerance.
  • reltol: relative tolerance for comparing linearized and integrator interpolation. Defaults to the integrator relative tolerance.

Returns

A DiscreteCallback that stores independently linearized output in ils.

Example

ils = IndependentlyLinearizedSolution(prob)
sol = solve(prob, solver; callback = LinearizingSavingCallback(ils))
source

Saving Example

In this example, we will solve a matrix equation and at each step save a tuple of values which contains the current trace and the norm of the matrix. We build the SavedValues cache to use Float64 for time and Tuple{Float64,Float64} for the saved values, and then call the solver with the callback.

using DiffEqCallbacks, OrdinaryDiffEq, LinearAlgebra
prob = ODEProblem((du, u, p, t) -> du .= u, rand(4, 4), (0.0, 1.0))
saved_values = SavedValues(Float64, Tuple{Float64, Float64})
cb = SavingCallback((u, t, integrator) -> (tr(u), norm(u)), saved_values)
sol = solve(prob, Tsit5(), callback = cb)

print(saved_values.saveval)
[(3.208255468587482, 2.8412311070031566), (3.5458357239684766, 3.140192187905121), (4.544133028678977, 4.024284300878181), (6.3530989682547165, 5.626304573065129), (8.72094215751001, 7.723266548720919)]

Note that the values are retrieved from the cache as .saveval, and the time points are found as .t. If we want to control the saved times, we use saveat in the callback. The save controls like saveat act analogously to how they act in the solve function.

saved_values = SavedValues(Float64, Tuple{Float64, Float64})
cb = SavingCallback((u, t, integrator) -> (tr(u), norm(u)), saved_values,
    saveat = 0.0:0.1:1.0)
sol = solve(prob, Tsit5(), callback = cb)
print(saved_values.saveval)
print(saved_values.t)
[(3.208255468587482, 2.8412311070031566), (3.545670641714721, 3.1400459910579004), (3.9185722168345456, 3.4702876334254245), (4.3306916428267055, 3.8352606053080973), (4.7861556171073865, 4.238619510020042), (5.289518749552634, 4.684397910158377), (5.84582035188561, 5.177058620285692), (6.460633145922078, 5.721536842953235), (7.140104417754994, 6.3232766148476), (7.891032574524425, 6.988298605467694), (8.72094215751001, 7.723266548720919)][0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]