Hi there
Please post code enclosed in ```
to make it a lot more readable.
While I am not sure about your problem specifically, your MWE does have several issues I’d like to address:
Module loading
You should load modules at toplevel and not via @eval
. Using @eval using ...
basically makes performant code impossible and make everything much more inconvenient (e.g. you need to use invokelatest
).
Undefined variables
Your MWE uses the variable x_first_callback
but it is never defined. You probably meant test_callback
. However…
Wrong construction of DiscreteCallback
you never arrive there because your code errors on constructing the DiscreteCallback
. You wrote:
test_callback = DiscreteCallback(example_callback, sqrt(-1))
This fails immediately with DomainError
because you compute sqrt(-1)
before even constructing the callback! You probably forgot to make it an anonymous function like so:
test_callback = DiscreteCallback(example_callback, (integrator) -> sqrt(-1))
This perhaps also explains why the “outer” solver fails: You never catch your exception because it is thrown outside the try-catch that was intended to catch it.
Your improved MWE doesn’t have this problem because test_callback
is constructed correctly.
It is unclear to me what the consequence of a failure of the inner solver for the outer solver should be so I can’t recommend a good way to solve your original problem. I suggest you open a new thread where you explain the structure of the problem you want to solve and then likely someone knowledgeable will pop in, explaining how to handle your case in the best way
Here is a suggestion of how your MWE code could look like (where I also fixed some other issues your code had):
module julia_try_catch_ode
using DifferentialEquations
function run()
dfdt_0 = [0.0]
tbounds = (0.0, 5.0) # tuple is preferred
dfdt_prob = ODEProblem(dfdt!, dfdt_0, tbounds)
dfdt_sol = solve(dfdt_prob)
end
function dfdt!(df, f, p, t) # mutating function get a ! in Julia
# df = [-1.0] # this doesn't overwrite df
df[1] = -1.0
internal_IC = [0.0]
internal_bounds = (0.0, 5.0)
test_callback = DiscreteCallback((_,_,_)->true, (_)->sqrt(-1))
internal_prob = ODEProblem(dfdt_2, internal_IC, internal_bounds)
try
doomed_solve = solve(internal_prob, callback = test_callback)
catch e
# internal solve failed
# what does that mean for the outer solve?
end
# return df # no need to return
end
function dfdt_2(df, f, p, t)
# df = [-1.0] # this doesn't overwrite df
df[1] = -1.0
end
run()
end