Exercise in DiffEqTutorials, "Failed to build the parameter derivatives"

This is from the tutorial of DiffEqTutorials, Callbacks and Events, exercise 2:

using DifferentialEquations, ParameterizedFunctions
ball! = @ode_def BallBounce begin
  dy =  v
  dv = -g + k*v
end g e k

throws error
┌ Warning: Failed to build the parameter derivatives.

This error, whatever it is, causes DiscreteCallback to not work.
Only the ground callback is still working.

u0 = [50.0,0.0] # height, velocity
tspan = (0.0,15.0)
p = (9.8, 0.9, 0.0)

function condition_ground(u,t,integrator)
    u[1] # height at zero
end
function affect_ground!(integrator)
    integrator.u[2] = -integrator.p[2] * integrator.u[2]
end
bounce_cb = ContinuousCallback(condition_ground,affect_ground!)

function condition_kick(u,t,integrator)
    t === 2
end
function affect_kick!(integrator)
    integrator.u[2] += 50
end
kick_cb = DiscreteCallback(condition_kick,affect_kick!)

function condition_wind(u,t,integrator)
    t === 10
end
function affect_wind!(integrator)
    integrator.p[3] += 50
end
wind_cb = DiscreteCallback(condition_wind,affect_wind!)

cb = CallbackSet(bounce_cb,kick_cb, wind_cb);

prob = ODEProblem(ball!,u0,tspan,p,callback=cb)
sol = solve(prob,Tsit5(),tstops=[2.0, 10.0])
plot(sol)

That’s completely harmless since you’re not doing sensitivity analysis. ParameterizedFunctions.jl will soon be removed from all tutorials.

For this, your main issue was the use of === which was causing the scalar checks to not return true. To check whether two numbers are the same, use ==. Other than that, your wind resistance was huge and it wasn’t resistance, it was wind acceleration! You can analytically calculate why it would explode given your model, so that should be changed to be something like a negative. Also, your parameters needs to be a mutable container if you’re going to mutate them, so using a parameter vector is wise.

Here’s a working solution:

using DifferentialEquations, ParameterizedFunctions
ball! = @ode_def BallBounce begin
  dy =  v
  dv = -g + k*v
end g e k

u0 = [50.0,0.0] # height, velocity
tspan = (0.0,15.0)
p = [9.8, 0.9, 0.0]

function condition_ground(u,t,integrator)
    u[1] # height at zero
end
function affect_ground!(integrator)
    integrator.u[2] = -integrator.p[2] * integrator.u[2]
end
bounce_cb = ContinuousCallback(condition_ground,affect_ground!)

function condition_kick(u,t,integrator)
    t == 2
end
function affect_kick!(integrator)
    integrator.u[2] += 50
end
kick_cb = DiscreteCallback(condition_kick,affect_kick!)

function condition_wind(u,t,integrator)
    t == 10
end
function affect_wind!(integrator)
    integrator.p[3] -= 1
end
wind_cb = DiscreteCallback(condition_wind,affect_wind!)

cb = CallbackSet(bounce_cb,kick_cb, wind_cb);

prob = ODEProblem(ball!,u0,tspan,p,callback=cb)
sol = solve(prob,Tsit5(),tstops=[2.0, 10.0])
plot(sol)

superball