Skip to content

Commit ab4f6c8

Browse files
Merge branch 'master' of github.com:SciML/ModelingToolkit.jl into domain-sets
2 parents fd5e273 + 9915d6d commit ab4f6c8

File tree

8 files changed

+62
-35
lines changed

8 files changed

+62
-35
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ModelingToolkit"
22
uuid = "961ee093-0014-501f-94e3-6117800e7a78"
33
authors = ["Chris Rackauckas <[email protected]>"]
4-
version = "5.17.1"
4+
version = "5.17.4"
55

66
[deps]
77
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"

src/systems/abstractsystem.jl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -665,15 +665,17 @@ AbstractTrees.children(sys::ModelingToolkit.AbstractSystem) = ModelingToolkit.ge
665665
AbstractTrees.printnode(io::IO, sys::ModelingToolkit.AbstractSystem) = print(io, nameof(sys))
666666
AbstractTrees.nodetype(::ModelingToolkit.AbstractSystem) = ModelingToolkit.AbstractSystem
667667

668-
function check_eqs_u0(eqs, dvs, u0)
668+
function check_eqs_u0(eqs, dvs, u0; check_length=true, kwargs...)
669669
if u0 !== nothing
670-
if !(length(eqs) == length(dvs) == length(u0))
671-
throw(ArgumentError("Equations ($(length(eqs))), states ($(length(dvs))), and initial conditions ($(length(u0))) are of different lengths."))
672-
end
673-
else
674-
if !(length(eqs) == length(dvs))
675-
throw(ArgumentError("Equations ($(length(eqs))), states ($(length(dvs))) are of different lengths."))
670+
if check_length
671+
if !(length(eqs) == length(dvs) == length(u0))
672+
throw(ArgumentError("Equations ($(length(eqs))), states ($(length(dvs))), and initial conditions ($(length(u0))) are of different lengths. To allow a different number of equations than states use kwarg check_length=false."))
673+
end
674+
elseif length(dvs) != length(u0)
675+
throw(ArgumentError("States ($(length(dvs))) and initial conditions ($(length(u0))) are of different lengths."))
676676
end
677+
elseif check_length && (length(eqs) != length(dvs))
678+
throw(ArgumentError("Equations ($(length(eqs))) and states ($(length(dvs))) are of different lengths. To allow these to differ use kwarg check_length=false."))
677679
end
678680
return nothing
679681
end
@@ -713,7 +715,7 @@ end
713715

714716
promote_connect_rule(::Type{T}, ::Type{S}) where {T, S} = Union{}
715717
promote_connect_rule(::Type{T}, ::Type{T}) where {T} = T
716-
promote_connect_type(t1::Type, t2::Type, ts::Type...) = promote_connect_rule(promote_connect_rule(t1, t2), ts...)
718+
promote_connect_type(t1::Type, t2::Type, ts::Type...) = promote_connect_type(promote_connect_rule(t1, t2), ts...)
717719
@inline function promote_connect_type(::Type{T}, ::Type{S}) where {T,S}
718720
promote_connect_result(
719721
T,

src/systems/diffeqs/abstractodesystem.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ function process_DEProblem(constructor, sys::AbstractODESystem,u0map,parammap;
426426
end
427427
p = varmap_to_vars(parammap,ps; defaults=pdefs)
428428

429-
check_eqs_u0(eqs, dvs, u0)
429+
check_eqs_u0(eqs, dvs, u0; kwargs...)
430430

431431
f = constructor(sys,dvs,ps,u0;ddvs=ddvs,tgrad=tgrad,jac=jac,checkbounds=checkbounds,
432432
linenumbers=linenumbers,parallel=parallel,simplify=simplify,

src/systems/nonlinear/nonlinearsystem.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ function process_NonlinearProblem(constructor, sys::NonlinearSystem,u0map,paramm
226226
u0 = varmap_to_vars(u0map,dvs; defaults=defs)
227227
p = varmap_to_vars(parammap,ps; defaults=defs)
228228

229-
check_eqs_u0(eqs, dvs, u0)
229+
check_eqs_u0(eqs, dvs, u0; kwargs...)
230230

231231
f = constructor(sys,dvs,ps,u0;jac=jac,checkbounds=checkbounds,
232232
linenumbers=linenumbers,parallel=parallel,simplify=simplify,

src/systems/reaction/reactionsystem.jl

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ end
185185
"""
186186
oderatelaw(rx; combinatoric_ratelaw=true)
187187
188-
Given a [`Reaction`](@ref), return the reaction rate law [`Operation`](@ref) used in
188+
Given a [`Reaction`](@ref), return the symbolic reaction rate law used in
189189
generated ODEs for the reaction. Note, for a reaction defined by
190190
191191
`k*X*Y, X+Z --> 2X + Y`
@@ -195,7 +195,7 @@ of the form
195195
196196
`k, 2X+3Y --> Z`
197197
198-
the `Operation` that is returned will be `k * (X(t)^2/2) * (Y(t)^3/6)`.
198+
the expression that is returned will be `k * (X(t)^2/2) * (Y(t)^3/6)`.
199199
200200
Notes:
201201
- Allocates
@@ -240,13 +240,13 @@ function assemble_oderhs(rs; combinatoric_ratelaws=true)
240240
rhsvec
241241
end
242242

243-
function assemble_drift(rs; combinatoric_ratelaws=true, as_odes=true)
243+
function assemble_drift(rs; combinatoric_ratelaws=true, as_odes=true, include_zero_odes=true)
244244
rhsvec = assemble_oderhs(rs; combinatoric_ratelaws=combinatoric_ratelaws)
245245
if as_odes
246246
D = Differential(get_iv(rs))
247-
eqs = [Equation(D(x),rhs) for (x,rhs) in zip(get_states(rs),rhsvec) if (!_iszero(rhs))]
247+
eqs = [Equation(D(x),rhs) for (x,rhs) in zip(get_states(rs),rhsvec) if (include_zero_odes || (!_iszero(rhs)))]
248248
else
249-
eqs = [Equation(0,rhs) for rhs in rhsvec if (!_iszero(rhs))]
249+
eqs = [Equation(0,rhs) for rhs in rhsvec if (include_zero_odes || (!_iszero(rhs)))]
250250
end
251251
eqs
252252
end
@@ -272,7 +272,7 @@ end
272272
"""
273273
jumpratelaw(rx; rxvars=get_variables(rx.rate), combinatoric_ratelaw=true)
274274
275-
Given a [`Reaction`](@ref), return the reaction rate law [`Operation`](@ref) used in
275+
Given a [`Reaction`](@ref), return the symbolic reaction rate law used in
276276
generated stochastic chemical kinetics model SSAs for the reaction. Note,
277277
for a reaction defined by
278278
@@ -283,7 +283,7 @@ the form
283283
284284
`k, 2X+3Y --> Z`
285285
286-
the `Operation` that is returned will be `k * binomial(X,2) *
286+
the expression that is returned will be `k * binomial(X,2) *
287287
binomial(Y,3)`.
288288
289289
Notes:
@@ -411,8 +411,8 @@ law, i.e. for `2S -> 0` at rate `k` the ratelaw would be `k*S^2/2!`. If
411411
ignored.
412412
"""
413413
function Base.convert(::Type{<:ODESystem}, rs::ReactionSystem;
414-
name=nameof(rs), combinatoric_ratelaws=true, kwargs...)
415-
eqs = assemble_drift(rs; combinatoric_ratelaws=combinatoric_ratelaws)
414+
name=nameof(rs), combinatoric_ratelaws=true, include_zero_odes=true, kwargs...)
415+
eqs = assemble_drift(rs; combinatoric_ratelaws=combinatoric_ratelaws, include_zero_odes=include_zero_odes)
416416
systems = map(sys -> (sys isa ODESystem) ? sys : convert(ODESystem, sys), get_systems(rs))
417417
ODESystem(eqs, get_iv(rs), get_states(rs), get_ps(rs); name=name, systems=systems, kwargs...)
418418
end
@@ -431,8 +431,8 @@ law, i.e. for `2S -> 0` at rate `k` the ratelaw would be `k*S^2/2!`. If
431431
ignored.
432432
"""
433433
function Base.convert(::Type{<:NonlinearSystem},rs::ReactionSystem;
434-
name=nameof(rs), combinatoric_ratelaws=true, kwargs...)
435-
eqs = assemble_drift(rs; combinatoric_ratelaws=combinatoric_ratelaws, as_odes=false)
434+
name=nameof(rs), combinatoric_ratelaws=true, include_zero_odes=true, kwargs...)
435+
eqs = assemble_drift(rs; combinatoric_ratelaws=combinatoric_ratelaws, as_odes=false, include_zero_odes=include_zero_odes)
436436
systems = convert.(NonlinearSystem, get_systems(rs))
437437
NonlinearSystem(eqs, get_states(rs), get_ps(rs); name=name, systems=systems, kwargs...)
438438
end
@@ -449,17 +449,18 @@ Notes:
449449
law, i.e. for `2S -> 0` at rate `k` the ratelaw would be `k*S^2/2!`. If
450450
`combinatoric_ratelaws=false` then the ratelaw is `k*S^2`, i.e. the scaling factor is
451451
ignored.
452-
- `noise_scaling=nothing::Union{Vector{Operation},Operation,Nothing}` allows for linear
452+
- `noise_scaling=nothing::Union{Vector{Num},Num,Nothing}` allows for linear
453453
scaling of the noise in the chemical Langevin equations. If `nothing` is given, the default
454-
value as in Gillespie 2000 is used. Alternatively, an `Operation` can be given, this is
454+
value as in Gillespie 2000 is used. Alternatively, a `Num` can be given, this is
455455
added as a parameter to the system (at the end of the parameter array). All noise terms
456456
are linearly scaled with this value. The parameter may be one already declared in the `ReactionSystem`.
457-
Finally, a `Vector{Operation}` can be provided (the length must be equal to the number of reactions).
457+
Finally, a `Vector{Num}` can be provided (the length must be equal to the number of reactions).
458458
Here the noise for each reaction is scaled by the corresponding parameter in the input vector.
459459
This input may contain repeat parameters.
460460
"""
461461
function Base.convert(::Type{<:SDESystem}, rs::ReactionSystem;
462-
noise_scaling=nothing, name=nameof(rs), combinatoric_ratelaws=true, kwargs...)
462+
noise_scaling=nothing, name=nameof(rs), combinatoric_ratelaws=true,
463+
include_zero_odes=true, kwargs...)
463464

464465
if noise_scaling isa Vector
465466
(length(noise_scaling)!=length(equations(rs))) &&
@@ -470,7 +471,8 @@ function Base.convert(::Type{<:SDESystem}, rs::ReactionSystem;
470471
noise_scaling = fill(value(noise_scaling),length(equations(rs)))
471472
end
472473

473-
eqs = assemble_drift(rs; combinatoric_ratelaws=combinatoric_ratelaws)
474+
eqs = assemble_drift(rs; combinatoric_ratelaws=combinatoric_ratelaws,
475+
include_zero_odes=include_zero_odes)
474476
noiseeqs = assemble_diffusion(rs,noise_scaling;
475477
combinatoric_ratelaws=combinatoric_ratelaws)
476478
systems = convert.(SDESystem, get_systems(rs))
@@ -506,13 +508,13 @@ end
506508

507509

508510
# ODEProblem from AbstractReactionNetwork
509-
function DiffEqBase.ODEProblem(rs::ReactionSystem, u0, tspan, p=DiffEqBase.NullParameters(), args...; kwargs...)
510-
return ODEProblem(convert(ODESystem,rs; kwargs...),u0,tspan,p, args...; kwargs...)
511+
function DiffEqBase.ODEProblem(rs::ReactionSystem, u0, tspan, p=DiffEqBase.NullParameters(), args...; check_length=false, kwargs...)
512+
return ODEProblem(convert(ODESystem,rs; kwargs...),u0,tspan,p, args...; check_length, kwargs...)
511513
end
512514

513515
# NonlinearProblem from AbstractReactionNetwork
514-
function DiffEqBase.NonlinearProblem(rs::ReactionSystem, u0, p=DiffEqBase.NullParameters(), args...; kwargs...)
515-
return NonlinearProblem(convert(NonlinearSystem,rs; kwargs...), u0, p, args...; kwargs...)
516+
function DiffEqBase.NonlinearProblem(rs::ReactionSystem, u0, p=DiffEqBase.NullParameters(), args...; check_length=false, kwargs...)
517+
return NonlinearProblem(convert(NonlinearSystem,rs; kwargs...), u0, p, args...; check_length, kwargs...)
516518
end
517519

518520

test/connectors.jl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,19 @@ end
1313
ODESystem(Equation[], t, [x], [p], defaults=Dict(x=>1.0, p=>1.0))
1414
end
1515

16-
ModelingToolkit.connect(::Type{<:Foo}, sys1, sys2) = [sys1.x ~ sys2.x]
16+
function ModelingToolkit.connect(::Type{<:Foo}, ss...)
17+
n = length(ss)-1
18+
eqs = Vector{Equation}(undef, n)
19+
for i in 1:n
20+
eqs[i] = ss[i].x ~ ss[i+1].x
21+
end
22+
eqs
23+
end
24+
1725
@named f1 = Foo()
1826
@named f2 = Foo()
27+
@named f3 = Foo()
28+
@named f4 = Foo()
1929
@named g = Goo()
2030

2131
@test isequal(connect(f1, f2), [f1.x ~ f2.x])
@@ -24,6 +34,9 @@ ModelingToolkit.connect(::Type{<:Foo}, sys1, sys2) = [sys1.x ~ sys2.x]
2434
# Note that since there're overloadings, these tests are not re-runable.
2535
ModelingToolkit.promote_connect_rule(::Type{<:Foo}, ::Type{<:Goo}) = Foo
2636
@test isequal(connect(f1, g), [f1.x ~ g.x])
37+
@test isequal(connect(f1, f2, g), [f1.x ~ f2.x; f2.x ~ g.x])
38+
@test isequal(connect(f1, f2, g, f3), [f1.x ~ f2.x; f2.x ~ g.x; g.x ~ f3.x])
39+
@test isequal(connect(f1, f2, g, f3, f4), [f1.x ~ f2.x; f2.x ~ g.x; g.x ~ f3.x; f3.x ~ f4.x])
2740
ModelingToolkit.promote_connect_rule(::Type{<:Goo}, ::Type{<:Foo}) = Foo
2841
@test isequal(connect(f1, g), [f1.x ~ g.x])
2942
# test conflict

test/odesystem.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,3 +330,13 @@ sys = ode_order_lowering(sys)
330330
prob = ODEProblem(sys, [], tspan)
331331
sol = solve(prob, Tsit5())
332332
@test sum(abs, sol[end]) < 1
333+
334+
335+
# check_eqs_u0 kwarg test
336+
@parameters t
337+
@variables x1(t) x2(t)
338+
D =Differential(t)
339+
eqs = [D(x1) ~ -x1]
340+
sys = ODESystem(eqs,t,[x1,x2],[])
341+
@test_throws ArgumentError ODEProblem(sys, [1.0,1.0], (0.0,1.0))
342+
prob = ODEProblem(sys, [1.0,1.0], (0.0,1.0), check_length=false)

test/reactionsystem_components.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ pars = [α₀,α,K,n,δ,β,μ]
1717
@named rs = ReactionSystem(rxs, t, specs, pars)
1818

1919
# using ODESystem components
20-
@named os₁ = convert(ODESystem, rs)
21-
@named os₂ = convert(ODESystem, rs)
22-
@named os₃ = convert(ODESystem, rs)
20+
@named os₁ = convert(ODESystem, rs; include_zero_odes=false)
21+
@named os₂ = convert(ODESystem, rs; include_zero_odes=false)
22+
@named os₃ = convert(ODESystem, rs; include_zero_odes=false)
2323
connections = [os₁.R ~ os₃.P,
2424
os₂.R ~ os₁.P,
2525
os₃.R ~ os₂.P]

0 commit comments

Comments
 (0)