# When to use a discrete callback in DifferentialEquations.jl

**URL:** <https://discourse.julialang.org/t/when-to-use-a-discrete-callback-in-differentialequations-jl/51493>\
**Category:** General Usage\
**Created:** [December 9, 2020, 4:28am UTC](https://discourse.julialang.org/t/when-to-use-a-discrete-callback-in-differentialequations-jl/51493 "2020-12-09T04:28:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [December 9, 2020, 4:28am UTC](https://discourse.julialang.org/t/when-to-use-a-discrete-callback-in-differentialequations-jl/51493/1 "2020-12-09T04:28:51Z")

</div>

I have a fairly large model I am trying to solve (~100 differential equations). There is a particular parameter that changes every 28 days. Right now, I switch this parameter using a callback function

```julia
function model!(du, u, params, t) 
   a bunch of equations involving params.r 
end

condition(u,t,integrator) = round(t, digits=3) ∈ collect(28:28:800) 
function dose!(integrator)     
   integrator.p.r = 1 - integrator.p.r
end
cb = DiscreteCallback(condition, dose!, save_positions=(false,false))

function run_model() 
    prob = ODEProblem(model!, u0, tspan, params
    sol = solve(prob, callback = cb)
end 

```

So you see, every 28 time steps, I basically switch the `r` parameter that cycles through 0 and 1. My question is, is it cheaper and better to do this in the `model!` function directly and get rid of callbacks? Can I have something like

```julia
function model!(du, u, params, t) 
   if t satisfies condition 
       params.r = 1 - params.r 
   end 
   a bunch of equations involving params.r 
end

```

From preliminary testing this seems to work, but I am not sure what the correct, more efficient way of doing it is.

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [December 9, 2020, 6:13am UTC](https://discourse.julialang.org/t/when-to-use-a-discrete-callback-in-differentialequations-jl/51493/2 "2020-12-09T06:13:49Z")

</div>

As you have it written, if your timesteps are small enough (~`1e-4` s), you could unintentionally dose multiple times depending on the precision specified in `round(t, digits=3)`. Are you using a fixed time step of one day? Seems like you may want a [`PresetTimeCallback`](https://diffeq.sciml.ai/stable/features/callback_functions/#PresetTimeCallback).

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 10, 2020, 4:52am UTC](https://discourse.julialang.org/t/when-to-use-a-discrete-callback-in-differentialequations-jl/51493/3 "2020-12-10T04:52:38Z")

</div>

> [@affans](#):
>
> From preliminary testing this seems to work, but I am not sure what the correct, more efficient way of doing it is.

That decrementing in the function `f` is not safe because time isn’t monotonic in an adaptive ODE solver. You might decrement at a given time point twice.
