DifferentialEquations.jl
DifferentialEquations.jl copied to clipboard
FunctionCallingCallback not correctly synchronized with events
The FunctionCallingCallback seems to be not correctly synchronized with events as shown with the following test model:
module Test_bouncingBall_withFunctionCallBack
using DifferentialEquations
function f(du,u,p,t) #u[1]: height, u[2]:velocity
du[1] = u[2]
du[2] = -9.81
return nothing
end
# Own result storage (emulated by print statements)
function outputs!(x, t, integrator)::Nothing
println("... Store result at time = $t: h = ", integrator.u[1], ", v = ", integrator.u[2])
return nothing
end
# State event
function condition(out,u,t,integrator)
out[1] = u[1]
return nothing
end
function affect!(integrator, event_index)
println("... State event at ", integrator.t)
# Store result before event
outputs!(integrator.u, integrator.t, integrator)
# Process event
integrator.u[2] = -0.8*integrator.u[2]
auto_dt_reset!(integrator)
set_proposed_dt!(integrator, integrator.dt)
# Store result after event
outputs!(integrator.u, integrator.t, integrator)
return nothing
end
u0 = [1.0,0.0]
tspan = (0.0,0.6)
tspan2 = 0.0:0.1:0.6
prob = ODEProblem(f,u0,tspan)
cb1 = FunctionCallingCallback(outputs!, funcat=tspan2)
cb2 = VectorContinuousCallback(condition,affect!,1)
callbackSet = CallbackSet(cb1,cb2)
sol = solve(prob,
Tsit5(),
save_everystep=false,
save_start=false,
save_end=false,
adaptive=true,
dt=0.1,
callback=callbackSet)
end
This results in the following output:
... Store result at time = 0.0: h = 1.0, v = 0.0
... Store result at time = 0.1: h = 0.9509500000000003, v = -0.9809999999999998
... State event at 0.4515236409857323
... Store result at time = 0.4515236409857323: h = 1.6653345369377348e-15, v = -4.429446918070022
... Store result at time = 0.4515236409857323: h = 1.6653345369377348e-15, v = 3.543557534456018
... Store result at time = 0.2: h = 1.6653345369377348e-15, v = 3.543557534456018
... Store result at time = 0.3: h = 1.6653345369377348e-15, v = 3.543557534456018
... Store result at time = 0.4: h = 1.6653345369377348e-15, v = 3.543557534456018
... Store result at time = 0.5: h = 0.418002671515621, v = 2.087004452526053
... Store result at time = 0.6: h = 0.418002671515621, v = 2.087004452526053
This means the affect-function is called at time = 0.45, but the FunctionCallingCallback for time = 0.2, 0.3, 0.4 is called after the affect-function is called at time = 0.45.