DifferentialEquations.jl icon indicating copy to clipboard operation
DifferentialEquations.jl copied to clipboard

FunctionCallingCallback not correctly synchronized with events

Open MartinOtter opened this issue 5 years ago • 3 comments

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.

MartinOtter avatar Oct 18 '20 13:10 MartinOtter