Can I enable the ContinuousCallback only on certain intervals?

I understand the difference between the DiscreteCallback and the ContinuousCallback. My question is, how could I use the continuous one while being active only on a specified interval of the independent variable?

For example, let’s say I’m interested in finding value x, such that the solution y(x) to the differential equation y'' + y = 0 hits the value 0.5 on the interval x\geq 4.

At first, I tried cheesing my way around by including the interval requirement in the condition and returning some nonzero value, if I’m outside of the interval of interest.

using Plots, DifferentialEquations

function f!(du, u, p, t) 
	du[1] = u[2]
	du[2] = -u[1]

x0 = [1.0, 0.0]
span = (0.0, 10.0)

condition(u, t, int) = (t < 4 ? -1.0 : u[1] - 0.5)
affect!(int) = terminate!(int)
cb = ContinuousCallback(condition, affect!)
prob = ODEProblem(f, x0, span; callback = cb)
sol = solve(prob) 
plot(sol, idxs = (1))

This seems to work, but if I change the initial condition to x0 = [-1.0, 0.0], this ‘solution’ fails miserably:

The problem is, the condition switches sign at the interval boundary and the integration is stopped at x=4. What is the intended way to do this? I would like to solve similar problem, but with a more complicated system.

1 Like

Okay, I slept on it and it occurred to me that I can simply put the interval condition inside of the affect! function. So this example problem would be solved by setting this:

condition(u, t, int) = u[1] - 0.5
affect!(int) = int.t < 4 ? nothing : terminate!(int)
1 Like