# Callback: Switch between dynamic models and time step depending on the region

**URL:** <https://discourse.julialang.org/t/callback-switch-between-dynamic-models-and-time-step-depending-on-the-region/22077>\
**Category:** General Usage\
**Tags:** diffeq, differentiation\
**Created:** [March 19, 2019, 9:40pm UTC](https://discourse.julialang.org/t/callback-switch-between-dynamic-models-and-time-step-depending-on-the-region/22077 "2019-03-19T21:40:34Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mleprovost](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mleprovost/32/7166_2.png) [@mleprovost](https://discourse.julialang.org/u/mleprovost)\
**Post date:** [March 19, 2019, 9:40pm UTC](https://discourse.julialang.org/t/callback-switch-between-dynamic-models-and-time-step-depending-on-the-region/22077/1 "2019-03-19T21:40:34Z")

</div>

Hello everyone,

I would like to solve an ODE in DifferentialEquations.jl where the right-hand side and the time step depend on the region where is located the particle.  
The function `DiscreteCallBack` seems to be adequate for my problem.  
But I don’t know how to change the right hand of the ODEProblem in the function affect!  
From [http://docs.juliadiffeq.org/latest/basics/integrator.html](http://docs.juliadiffeq.org/latest/basics/integrator.html),  
`integrator.f` should be the function being solved

Here a simplified example of what I am trying to do:  
We have a particle whose dynamic is governed by a first function `f1`. When `u[1]<0.0`, we want to switch to a second dynamic `f2` and change the time step

```julia
using OrdinaryDiffEq

# Model for the first region u[1=]>0
function f1(du,u,p,t)
  du[1] = u[2]
  du[2] = -p
end
# Model for the second region u[2]<0
function f2(du,u,p,t)
  du[1] = -2*u[2]
  du[2] = 0.5*p
end

 function condition(u,t,integrator) # Switch model if u[1]<0.0
  u[1]<0.0
end
function affect!(integrator)
  integrator.f = f2
  set_proposed_dt!(integrator,0.01)
end
cb = DiscreteCallback(condition,affect!)

u0 = [50.0,0.0]
tspan = (0.0,15.0)
p = 9.8
prob = ODEProblem(f1,u0,tspan,p)

sol = solve(prob,RK4(), dt = 0.1, callback=cb)

```

Thank you for your help,

---

<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:** [March 20, 2019, 9:22pm UTC](https://discourse.julialang.org/t/callback-switch-between-dynamic-models-and-time-step-depending-on-the-region/22077/2 "2019-03-20T21:22:52Z")

</div>

You can make those both one function with a boolean that chooses which model to use. Then that boolean can be changed in the callback.

---

<div class="post-metadata">

**Author:** ![mleprovost](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mleprovost/32/7166_2.png) [@mleprovost](https://discourse.julialang.org/u/mleprovost)\
**Post date:** [March 20, 2019, 10:14pm UTC](https://discourse.julialang.org/t/callback-switch-between-dynamic-models-and-time-step-depending-on-the-region/22077/3 "2019-03-20T22:14:05Z")

</div>

Thank you again @ChrisRackauckas for your help.  
Since my system will be switching back and forth between the two regions. Is there a way to define a `affect_neg!` for `DiscreteCallBack`, when the condition switches from True to False, and `affect!` will be used when the condition switches from False to True

---

<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:** [March 20, 2019, 10:36pm UTC](https://discourse.julialang.org/t/callback-switch-between-dynamic-models-and-time-step-depending-on-the-region/22077/4 "2019-03-20T22:36:19Z")

</div>

Just check if the parameter is true or false in `integrator.p`.

---

<div class="post-metadata">

**Author:** ![mleprovost](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mleprovost/32/7166_2.png) [@mleprovost](https://discourse.julialang.org/u/mleprovost)\
**Post date:** [March 20, 2019, 11:14pm UTC](https://discourse.julialang.org/t/callback-switch-between-dynamic-models-and-time-step-depending-on-the-region/22077/5 "2019-03-20T23:14:09Z")

</div>

I am not sure that I understand.

In the following example, my boolean `p` remains true once the callback has been activated and the solution have been in the negative region( where condition is true) and returned to the positive region ( where condition is false). Also the time step stays fixed to 0.5 for the rest of the simulation, and doesn’t return to 0.1 as I would expect in the region positive( where condition is false)

```julia
using DifferentialEquations
using OrdinaryDiffEq

# Model for the first region u[1=]>0
function f(du,u,p,t)
    print(p)
    if p == false
  du[1] = -2.0
    else
  du[1] = 1.0
    end
end
p = false

function condition(u,t,integrator) # Switch model if u[1]<0.0
  u[1]<0.0
end
function affect!(integrator)
  integrator.p = true
  integrator.dtcache = 0.5
end

cb = DiscreteCallback(condition,affect!,save_positions=(false,true))

u0 = [1.0]
tspan = (0.0,5.0)
prob = ODEProblem(f,u0,tspan,p)

sol = solve(prob,RK4(), dt = 0.1,adaptive = false, callback=cb)

```

---

<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:** [March 20, 2019, 11:42pm UTC](https://discourse.julialang.org/t/callback-switch-between-dynamic-models-and-time-step-depending-on-the-region/22077/6 "2019-03-20T23:42:13Z")

</div>

Yes, and to switch back you can check if integrator.p and flip it.

---

<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:** [March 20, 2019, 11:43pm UTC](https://discourse.julialang.org/t/callback-switch-between-dynamic-models-and-time-step-depending-on-the-region/22077/7 "2019-03-20T23:43:18Z")

</div>

Wait, why are you using a DiscreteCallback here instead of a Continuous callback?

---

<div class="post-metadata">

**Author:** ![mleprovost](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mleprovost/32/7166_2.png) [@mleprovost](https://discourse.julialang.org/u/mleprovost)\
**Post date:** [March 22, 2019, 1:07am UTC](https://discourse.julialang.org/t/callback-switch-between-dynamic-models-and-time-step-depending-on-the-region/22077/8 "2019-03-22T01:07:52Z")

</div>

I got it works, thank you. There was some conditions for the switch of regions which were hard to express using ContinuousCallBack. I had to switch the model at multiple of a time scale, which is easier to express with a boolean condition like ( mod(t, Tscale) =0).
