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

VectorContinuousCallback with duplicate events causes infinite loop

Open pepijndevos opened this issue 2 years ago • 2 comments

MWE:

using OrdinaryDiffEq

f = function (u, p, t)
    -u + sin(-t)
end

prob = ODEProblem(f, 1.0, (0.0, -10.0))

condition(out, u, t, integrator) = out[:] = [-t - 2.95, -t - 2.95]

function affect!(integrator, idx)
    @show integrator, idx
    integrator.u = integrator.u + 2
end

callback = VectorContinuousCallback(condition, affect!, 2)

sol = solve(prob, Tsit5(), callback = callback)

Of course for trivial cases the answer is "don't do that" but when different components or computations end up with the same event, this causes problems.

I've been looking into it a little bit and it seems that find_callback_time gets a vector of all the callbacks that changed sign, so I imagine it should check if after the rootfinding it can "check off" multiple events and move on, but I don't fully understand the code yet, and maybe it's a lot more complicated than that, judging by all the comment about floating point details.

pepijndevos avatar Mar 09 '23 15:03 pepijndevos

I think the main discussion regarding handling of simulteaneous events is in #519 as of now, linking it to connect the discussions (and maybe use this MWE for a test in the future). FWIW, this example kind of works as of DiffEqBase 6.164.2 with right-sided rootfinding (but it will only detect a triggering event instead of both of them, which would be the correct behavior).

callback = VectorContinuousCallback(condition, affect!, 2, rootfind=SciMLBase.RightRootFind)

DaniGlez avatar Mar 11 '25 13:03 DaniGlez

Ben has a PR that should be coming rather soon, like in the next few weeks.

ChrisRackauckas avatar Mar 11 '25 14:03 ChrisRackauckas