1

I have a dynamical system for which many events could occur. I want to terminate the integration of the trajectory on an event, but I also want to known which event has been activated.

The workaround I found is to use a global variable to save the event index in the affect! function. Here is a modified version of the bouncing ball example:

using DifferentialEquations

function f(du,u,p,t)
  du[1] = u[2]
  du[2] = -p
  du[3] = u[4]
  du[4] = 0.0
end

function condition(out,u,t,integrator) # Event when event_f(u,t) == 0
  out[1] = u[1]
  out[2] = (u[3] - 10.0)u[3]
end

event_idx = [0, ]  # global variable
function affect!(integrator, idx)
    event_idx[1] = idx
    terminate!(integrator)
end

cb = VectorContinuousCallback(condition,affect!,2)

u0 = [50.0,0.0,0.0,2.0]
tspan = (0.0,15.0)
p = 9.8
prob = ODEProblem(f,u0,tspan,p)
sol = solve(prob,Tsit5(),callback=cb,dt=1e-3,adaptive=false)
println(sol.retcode)
println(event_idx) # [1]

Is there a better solution for doing this?

Chris Rackauckas
  • 18,645
  • 3
  • 50
  • 81
xdze2
  • 3,986
  • 2
  • 12
  • 29
  • You can also use `integrator.p` as a cache, and change around that value, and use `sol.prob.p` at the end. But yeah, this or a `Ref` is a fine way to do it. – Chris Rackauckas Oct 24 '19 at 14:30
  • @ChrisRackauckas Thanks! I didn't know I could access `sol.prob.p` (and for differentialequations.jl, it's the reason I am trying to move to Julia) – xdze2 Oct 25 '19 at 11:45

1 Answers1

0

You can use integrator.p as a cache, and change around that value, and use sol.prob.p at the end. But yeah, this or a Ref is a fine way to do it.

Chris Rackauckas
  • 18,645
  • 3
  • 50
  • 81