# Help with callbacks (to set a variable to a constant value)

Hello!

I am simulating a complex dynamical system with DifferentialEquations.jl and via callbacks I introduce perturbations of some parameters. I would like to introduce a callback which continuously sets a variable to a constant value (letâ€™s say 2.0) when this constant value is reached. How can I do it?

I tried to use Discrete and Continuous callbacks, but my results are not satisfying:

• With DiscreteCallback (see first example below), I manage to set the variable to 2.0 only when the callback is called. In all the other time-steps the variable decreases following its derivative (which is not set to zero!).

• With ContinuousCallback (see second example below), I do not obtain any good result probably because my condition is never met.

I could manipulate the derivative du in the affect! function with DiscreteCallback and I obtain what I want, but I would not like to do that. I would rather preserve the correct physical equation of my model and introduce a callback which defines all the perturbations.
Moreover, with the DiscreteCallback my variable does not hit 2.0 and so the results is not perfect (see third example below).

Problem:

``````function f(du, u, p, t)
du[1] = -u[1] * p
end
u0 = [10.0]
p = 1
prob = ODEProblem(f, u0, (0.0, 10.0),p)
``````

Ex. 1 (DiscreteCallback):

``````condition_d(u, t, integrator) = integrator.u[1] <= 2.0
affect_d!(integrator) = integrator.u[1] = 2.0
cb_d = DiscreteCallback(condition_d, affect_d!)
sol = DifferentialEquations.solve(prob, Tsit5(), callback = cb_d)
plot(sol)
hline!([2.0],line=:dash,color=:red)
``````

Ex. 2 (ContinuousCallback):

``````condition_c(u, t, integrator) = integrator.u[1]-2.0
affect_c!(integrator) = integrator.u[1] = 2.0
cb_c = ContinuousCallback(condition_c, affect_c!)
sol = DifferentialEquations.solve(prob, Tsit5(), callback = cb_c)
plot(sol)
hline!([2.0],line=:dash,color=:red)
``````

Ex. 3 (DiscreteCallback by changing the derivative):

``````condition_d(u, t, integrator) = integrator.u[1] <= 2.0
function affect_d!(integrator)
integrator.u[1] = 2.0
integrator.p = 0
end
cb_d = DiscreteCallback(condition_d, affect_d!)
sol = DifferentialEquations.solve(prob, Tsit5(), callback = cb_d)
plot(sol)
hline!([2.0],line=:dash,color=:red)
``````

You need to set derivative to 0 in the flow function if the constant is achieved. Otherwise, it will continue to change after the `callback`.

Yes I believe so. But is there any way that I can access the derivative inside the affect! function? Perhaps via the integrator interface or any other toolâ€¦? Something like integrator.du[1] = 0â€¦

If you do that it only affects at the event instance. Later, it will continue to integrate with the flow function. Thatâ€™s why you need to handle it in the flow function.

Way 3 should be fine, i.e. changing a parameter.