SciML / StochasticDelayDiffEq.jl

Stochastic delay differential equations (SDDE) solvers for the SciML scientific machine learning ecosystem
MIT License
25 stars 10 forks source link

Callback implementation #34

Closed laserschwelle closed 3 years ago

laserschwelle commented 3 years ago

I'm trying to simulate a driven, self coupled laser and wanted to utilise callbacks for the driving. Are callback not implemented for SDDEs yet, or am I doing something wrong?

Julia v1.4.2 StochasticDelayDiffEq v0.2.5

Simplified example of what I'm trying to do, which works fine without the callback:

using StochasticDelayDiffEq

delay(u, h, p, t) = 0.3 * h(p, t-p)
stoc(u, h, p, t) = 0.1
h(p, t) = 0.;

p = 0.5
tspan = (0.0, 4.0)
lags = [p];

prob = SDDEProblem(
    delay,
    stoc,
    h,
    tspan,
    p;
    constant_lags=lags
);

condition(u,t,integrator) = t == 3
affect!(integrator) = integrator.u -= 0.3
cb = DiscreteCallback(condition, affect!)

sol = solve(prob, RKMil(), tstops=[3]);
cb_sol = solve(prob, RKMil(), tstops=[3], callback=cb);

The last line returns u_modified!: method has not been implemented for the integrator.

Thank you for the great work so far, I'm just getting into Julia because of this package!

devmotion commented 3 years ago

It's implemented in https://github.com/SciML/StochasticDelayDiffEq.jl/blob/0b95521f3983588fcdd7a9746094c0be8c89987c/src/integrators/interface.jl#L224 but it seems it is not qualified properly?! Can you check if it works if you change function u_modified! to function DiffEqBase.u_modified!?

devmotion commented 3 years ago

In general, it seems quite many methods are not qualified properly and do not actually implement the DiffEqBase interface...

laserschwelle commented 3 years ago

The new error message is: ERROR: MethodError: no method matching handle_callback_modifiers! [...] Closest candidates are: handle_callback_modifiers!(::StochasticDiffEq.SDEIntegrator)

devmotion commented 3 years ago

It seems this method is actually missing. I assume this can be fixed by defining

function OrdinaryDiffEq.handle_callback_modifiers!(integrator::StochasticDelayDiffEq.SDDEIntegrator)
    integrator.reeval_fsal = true # recalculate fsalfirst after applying step

    # update heap of discontinuities
    # discontinuity is assumed to be of order 0, i.e. solution x is discontinuous
    push!(integrator.opts.d_discontinuities, StochasticDelayDiffEq.Discontinuity(integrator.tdir * integrator.t, 0))
end

Can you check if it fixes the problem?

laserschwelle commented 3 years ago

It fails during the precompile ERROR: LoadError: LoadError: UndefVarError: OrdinaryDiffEq not defined [...] ERROR: Failed to precompile StochasticDelayDiffEq I pasted the function at the very end of StochasticDelayDiffEq.jl/src/integrators/interface.jl

devmotion commented 3 years ago

Fixed by https://github.com/SciML/StochasticDelayDiffEq.jl/pull/35.

laserschwelle commented 3 years ago

Thank you!