Skip to content

Commit 6a72042

Browse files
committed
hybrid jump-ODEs
1 parent 29ffd99 commit 6a72042

File tree

2 files changed

+44
-10
lines changed

2 files changed

+44
-10
lines changed

src/systems/jumps/jumpsystem.jl

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -482,19 +482,31 @@ function DiffEqBase.ODEProblem(sys::JumpSystem, u0map, tspan::Union{Tuple, Nothi
482482
use_union = false,
483483
eval_expression = false,
484484
eval_module = @__MODULE__,
485+
check_length = false,
485486
kwargs...)
486487
if !iscomplete(sys)
487488
error("A completed `JumpSystem` is required. Call `complete` or `structural_simplify` on the system before creating a `DiscreteProblem`")
488489
end
489490

490-
_, u0, p = process_SciMLProblem(EmptySciMLFunction, sys, u0map, parammap;
491-
t = tspan === nothing ? nothing : tspan[1], use_union, tofloat = false, check_length = false)
492-
493-
observedfun = ObservedFunctionCache(sys; eval_expression, eval_module)
494-
495-
f = (du, u, p, t) -> (du .= 0; nothing)
496-
df = ODEFunction(f; sys, observed = observedfun)
497-
ODEProblem(df, u0, tspan, p; kwargs...)
491+
# forward everything to be an ODESystem but the jumps
492+
if has_equations(sys)
493+
osys = ODESystem(equations(sys).x[4], get_iv(sys), unknowns(sys), parameters(sys);
494+
observed = observed(sys), name = nameof(sys), description = description(sys),
495+
systems = get_systems(sys), defaults = defaults(sys),
496+
discrete_events = discrete_events(sys),
497+
parameter_dependencies = parameter_dependencies(sys),
498+
metadata = get_metadata(sys), gui_metadata = get_gui_metadata(sys))
499+
osys = complete(osys)
500+
return ODEProblem(osys, u0map, tspan, parammap; check_length, kwargs...)
501+
else
502+
_, u0, p = process_SciMLProblem(EmptySciMLFunction, sys, u0map, parammap;
503+
t = tspan === nothing ? nothing : tspan[1], use_union, tofloat = false,
504+
check_length = false)
505+
f = (du, u, p, t) -> (du .= 0; nothing)
506+
observedfun = ObservedFunctionCache(sys; eval_expression, eval_module)
507+
df = ODEFunction(f; sys, observed = observedfun)
508+
return ODEProblem(df, u0, tspan, p; check_length, kwargs...)
509+
end
498510
end
499511

500512
"""
@@ -530,8 +542,8 @@ function JumpProcesses.JumpProblem(js::JumpSystem, prob,
530542
for j in eqs.x[2]]
531543
vrjs = VariableRateJump[assemble_vrj(js, j, unknowntoid; eval_expression, eval_module)
532544
for j in eqs.x[3]]
533-
((prob isa DiscreteProblem) && !isempty(vrjs)) &&
534-
error("Use continuous problems such as an ODEProblem or a SDEProblem with VariableRateJumps")
545+
((prob isa DiscreteProblem) && (!isempty(vrjs) || has_equations(js))) &&
546+
error("Use continuous problems such as an ODEProblem or a SDEProblem with VariableRateJumps and/or coupled differential equations.")
535547
jset = JumpSet(Tuple(vrjs), Tuple(crjs), nothing, majs)
536548

537549
# dep graphs are only for constant rate jumps

test/jumpsystem.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,3 +422,25 @@ let
422422
@test issetequal(us, [x5])
423423
@test issetequal(ps, [p5])
424424
end
425+
426+
# PDMP test
427+
let
428+
@variables X(t) Y(t)
429+
@parameters k1 k2
430+
rate1 = k1 * X
431+
affect1! = [X ~ X - 1]
432+
rate2 = k1
433+
affect2! = [Y ~ Y + 1]
434+
eqs = [D(X) ~ k2, D(Y) ~ -k2/100*Y]
435+
vrj1 = VariableRateJump(rate1, affect1!)
436+
vrj2 = VariableRateJump(rate2, affect2!)
437+
@named jsys = JumpSystem([vrj1, vrj2, eqs[1], eqs[2]], t, [X, Y], [k1, k2])
438+
jsys = complete(jsys)
439+
u0 = [X => 0.0, Y => 0.0]
440+
p = [k1 => 1.0, k2 => 20.0]
441+
tspan = (0.0, 20.0)
442+
oprob = ODEProblem(jsys, u0, tspan, p)
443+
jprob = JumpProblem(jsys, oprob; rng)
444+
sol = solve(jprob, Tsit5())
445+
446+
end

0 commit comments

Comments
 (0)