Set parameter dependent time steps using OrdinaryDiffEq

Hi,

I have a question about how to set time-dependent time steps (or maximum time steps) for solving an ODE. For a quick demo, say we are dealing with this simple ODE:

using OrdinaryDiffEq

f(u, p, t) = 1.01 * p * u
u0 = 1 / 2
p = 1.0 # ODE parameter
tspan = (0.0, 1.0)
prob = ODEProblem(f, u0, tspan, p)
sol = solve(prob, Tsit5(), reltol = 1e-8, abstol = 1e-8)

Tsit5() allows adaptive time steps, and it takes 17 steps to reach t=1.0. I can instead enforce a fixed timestep like

sol = solve(prob, Tsit5(), adaptive=false, dt = 0.01, reltol = 1e-8, abstol = 1e-8)

and as expected, it takes 101 steps.

Now my question is, is it possible to define a customized time step dt(or a maximum-allowed time step dtmax) which is dependent on the ODE parameters prob.p?

I guess this can be achieved via Step Control Callbacks · DiffEqCallbacks.jl (sciml.ai). While continuing to go over its usage, there’s no harm posting my original question here.

You could implement it as a DiscreteCallback and make it determine the maximum step size in each time step. We use this in Trixi.jl to implement our StepsizeCallback

1 Like

Ah I figured it out:

using OrdinaryDiffEq
using DiffEqCallbacks

f(u, p, t) = 1.01 * p * u
u0 = 1 / 2
p = 1.0 # ODE parameter
tspan = (0.0, 1.0)
prob = ODEProblem(f, u0, tspan, p)
dtFE(u, p, t) = 0.1 * p
cb = StepsizeLimiter(dtFE; safety_factor=1, max_step=true)

sol = solve(prob, Tsit5(); callback=cb, adaptive=false, dt=0.1) # dt has a is dummy value