Changing the default solving loop condition in DifferentialEquations.jl

Hi all!

I’m trying to implement a solver that will stop if one of the variables passes a certain value instead of time-stepping (I may thus change the title of this topic). Say e.g. u[1] < 0 || u[1] > R for maximum range R.

There are two methods I’ve been looking at, but haven’t gotten anything working (out of lack of understanding or whatnot).

Q1: The first way I figured was probably possible was to use the isoutofdomain input argument as isoutofdomain = MyOutOfDomain(u, p, t). Is this correct? When I try it, the solver doesn’t finish (and I’ve solved without this input argument and it solves very quickly, so I’m quite confused as to how adding this would increase computation time by tonnes).

Q2: The second way I could do this is via a callback, i.e. callback = cbRange with cbRange = ContinuousCallback(RangeCond, RangeAffect!). But I’m not quite sure how to implement RangeAffect! so that the solver stops.

Q3: How can I change the stopping condition from the default tspan = (0, T) to stopping with one of the variables (say u[1]) reaching certain values instead? I understand that this means it is possible for this variable potentially not reaching its stopping range values, so there would need to be some sort of implementation to catch when this happens as well.

I figured this is the most minimal way to ask my question(s), but I can expand on the context for you if you want.

Thanks in advance!

I think you want to use a ContinuousCallback, the condition function can be something like u[1]-desired_value and your affect should call the terminate! function.

Integrator Interface · DifferentialEquations.jl!

https://diffeq.sciml.ai/stable/features/callback_functions/#ContinuousCallback

1 Like