Skip to content

Commit 3d3dbff

Browse files
Add a component system
1 parent 9ae43bc commit 3d3dbff

File tree

7 files changed

+90
-27
lines changed

7 files changed

+90
-27
lines changed

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
1616
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1717
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
1818
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
19+
TreeViews = "a2a6695c-b41b-5b7d-aed9-dbfdeacea5d7"
1920

2021
[compat]
2122
DiffEqBase = "6"
@@ -31,8 +32,8 @@ julia = "1.2"
3132

3233
[extras]
3334
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
34-
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3535
StochasticDiffEq = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0"
36+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3637

3738
[targets]
3839
test = ["OrdinaryDiffEq", "Test", "StochasticDiffEq"]

src/ModelingToolkit.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import GeneralizedGenerated
1111
using DocStringExtensions
1212
using Base: RefValue
1313

14+
import TreeViews
15+
1416
"""
1517
$(TYPEDEF)
1618
@@ -109,10 +111,9 @@ export simplify_constants
109111
export Operation, Expression
110112
export calculate_jacobian, generate_jacobian, generate_function
111113
export calculate_massmatrix, generate_diffusion_function
112-
export independent_variables, dependent_variables, parameters
114+
export independent_variable, states, parameters, equations
113115
export simplified_expr, eval_function
114116
export @register, @I
115117
export modelingtoolkitize
116118
export Variable, @variables, @parameters
117-
118119
end # module

src/systems/diffeqs/abstractodesystem.jl

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,54 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = sys.dvs, ps =
159159
syms = Symbol.(sys.dvs))
160160
end
161161

162+
renamespace(namespace,name) = Symbol(string(namespace)*""*string(name))
163+
162164
function DiffEqBase.ODEFunction(sys::AbstractODESystem, args...; kwargs...)
163165
ODEFunction{true}(sys, args...; kwargs...)
164166
end
165167

166-
independent_variables(sys::AbstractODESystem) = Set{Variable}([sys.iv])
167-
dependent_variables(sys::AbstractODESystem) = Set{Variable}(sys.dvs)
168-
parameters(sys::AbstractODESystem) = Set{Variable}(sys.ps)
168+
function namespace_variables(sys::AbstractODESystem)
169+
[rename(x,renamespace(sys.name,x.name)) for x in sys.dvs]
170+
end
171+
172+
function namespace_parameters(sys::AbstractODESystem)
173+
[rename(x,renamespace(sys.name,x.name)) for x in sys.ps]
174+
end
175+
176+
namespace_equations(sys::AbstractODESystem) = namespace_equation.(sys.eqs,sys.name,sys.iv.name)
177+
178+
function namespace_equation(eq::Equation,name,ivname)
179+
_lhs = namespace_operation(eq.lhs,name,ivname)
180+
_rhs = namespace_operation(eq.rhs,name,ivname)
181+
_lhs ~ _rhs
182+
end
183+
184+
function namespace_operation(O::Operation,name,ivname)
185+
if O.op isa Variable && O.op.name != ivname
186+
Operation(rename(O.op,renamespace(name,O.op.name)),namespace_operation.(O.args,name,ivname))
187+
else
188+
Operation(O.op,namespace_operation.(O.args,name,ivname))
189+
end
190+
end
191+
namespace_operation(O::Constant,name,ivname) = O
192+
193+
independent_variable(sys::AbstractODESystem) = sys.iv
194+
states(sys::AbstractODESystem) = [sys.dvs;reduce(vcat,namespace_variables.(sys.systems))]
195+
parameters(sys::AbstractODESystem) = [sys.ps;reduce(vcat,namespace_parameters.(sys.systems))]
196+
197+
function equations(sys::AbstractODESystem)
198+
[sys.eqs;reduce(vcat,namespace_equations.(sys.systems))]
199+
end
200+
201+
function states(sys::AbstractODESystem,name::Symbol)
202+
x = sys.dvs[findfirst(x->x.name==name,sys.dvs)]
203+
Variable(Symbol(string(sys.name)*""*string(x.name)),known=x.known)(sys.iv())
204+
end
205+
206+
function parameters(sys::AbstractODESystem,name::Symbol)
207+
x = sys.ps[findfirst(x->x.name==name,sys.ps)]
208+
Variable(Symbol(string(sys.name)*""*string(x.name)),known=x.known)(sys.iv())
209+
end
169210

170211
function _eq_unordered(a, b)
171212
length(a) === length(b) || return false

src/systems/diffeqs/odesystem.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,14 @@ struct ODESystem <: AbstractODESystem
5555
Name: the name of the system
5656
"""
5757
name::Symbol
58+
"""
59+
systems: The internal systems
60+
"""
61+
systems::Vector{ODESystem}
5862
end
5963

6064
function ODESystem(deqs::AbstractVector{<:Equation}, iv, dvs, ps;
65+
systems = ODESystem[],
6166
name=gensym(:ODESystem))
6267
iv′ = clean(iv)
6368
dvs′ = [clean(dv) for dv dvs]
@@ -66,7 +71,7 @@ function ODESystem(deqs::AbstractVector{<:Equation}, iv, dvs, ps;
6671
jac = RefValue(Matrix{Expression}(undef, 0, 0))
6772
Wfact = RefValue(Matrix{Expression}(undef, 0, 0))
6873
Wfact_t = RefValue(Matrix{Expression}(undef, 0, 0))
69-
ODESystem(deqs, iv′, dvs′, ps′, tgrad, jac, Wfact, Wfact_t, name)
74+
ODESystem(deqs, iv′, dvs′, ps′, tgrad, jac, Wfact, Wfact_t, name, systems)
7075
end
7176

7277
var_from_nested_derivative(x) = var_from_nested_derivative(x,0)

src/systems/diffeqs/sdesystem.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,23 @@ struct SDESystem <: AbstractODESystem
3333
Name: the name of the system
3434
"""
3535
name::Symbol
36+
"""
37+
Systems: the internal systems
38+
"""
39+
systems::Vector{SDESystem}
3640
end
3741

38-
function SDESystem(deqs::AbstractVector{<:Equation}, neqs, iv, dvs, ps; name = gensym(:SDESystem))
42+
function SDESystem(deqs::AbstractVector{<:Equation}, neqs, iv, dvs, ps;
43+
systems = SDESystem[],
44+
name = gensym(:SDESystem))
3945
dvs′ = [clean(dv) for dv dvs]
4046
ps′ = [clean(p) for p ps]
4147
iv′ = clean(iv)
4248
tgrad = RefValue(Vector{Expression}(undef, 0))
4349
jac = RefValue(Matrix{Expression}(undef, 0, 0))
4450
Wfact = RefValue(Matrix{Expression}(undef, 0, 0))
4551
Wfact_t = RefValue(Matrix{Expression}(undef, 0, 0))
46-
SDESystem(deqs, neqs, iv′, dvs′, ps′, tgrad, jac, Wfact, Wfact_t, name)
52+
SDESystem(deqs, neqs, iv′, dvs′, ps′, tgrad, jac, Wfact, Wfact_t, name, systems)
4753
end
4854

4955
function generate_diffusion_function(sys::SDESystem, dvs = sys.dvs, ps = sys.ps, expression = Val{true}; kwargs...)

src/variables.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,13 @@ Define one or more known variables.
168168
macro parameters(xs...)
169169
esc(_parse_vars(:parameters, true, xs))
170170
end
171+
172+
function rename(x::Variable,name::Symbol)
173+
Variable(name,known=x.known)
174+
end
175+
176+
TreeViews.hastreeview(x::Variable) = true
177+
function TreeViews.treelabel(io::IO,x::Variable,
178+
mime::MIME"text/plain" = MIME"text/plain"())
179+
show(io,mime,Text(x.name))
180+
end

test/components.jl

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,28 @@ using Test
99

1010
eqs = [D(x) ~ σ*(y-x),
1111
D(y) ~ x*-z)-y,
12-
0 ~ x + y + z]
12+
0 ~ x + y + β*z]
1313

14-
de1 = ODESystem(eqs,t,[x,y,z],[σ,ρ,β],name=:lorenz1)
15-
de2 = ODESystem(eqs,t,[x,y,z],[σ,ρ,β],name=:lorenz2)
14+
lorenz1 = ODESystem(eqs,t,[x,y,z],[σ,ρ,β],name=:lorenz1)
15+
lorenz2 = ODESystem(eqs,t,[x,y,z],[σ,ρ,β],name=:lorenz2)
1616

1717
@parameters α
1818
@variables a(t)
19-
for
19+
connnectedeqs = [D(a) ~ a*states(lorenz1,:x)]
2020

21-
convert(DAESystem,sys)
22-
convert(ODESystem,sys)
21+
connected = ODESystem(connnectedeqs,t,[a],[α],systems=[lorenz1,lorenz2],name=:connectedlorenz)
2322

24-
connected = ODESystems(connnectedeqs,[a],[α],systems=[de1,de2],name=:connectedlorenz)
23+
@variables lorenz1′x(t) lorenz1′y(t) lorenz1′z(t) lorenz2′x(t) lorenz2′y(t) lorenz2′z(t)
24+
@parameters lorenz1′σ lorenz1′ρ lorenz1′β lorenz2′σ lorenz2′ρ lorenz2′β
2525

26-
deleteat!(de2.eqs,3)
27-
de2
28-
push!(de2.eqs,convert(ModelingToolkit.ODEExpr,D(z) ~ z^2)[2])
26+
eqs_flat = [D(a) ~ a*lorenz1′x,
27+
D(lorenz1′x) ~ lorenz1′σ*(lorenz1′y-lorenz1′x),
28+
D(lorenz1′y) ~ lorenz1′x*(lorenz1′ρ-lorenz1′z)-lorenz1′y,
29+
0 ~ lorenz1′x + lorenz1′y + lorenz1′β*lorenz1′z,
30+
D(lorenz2′x) ~ lorenz2′σ*(lorenz2′y-lorenz2′x),
31+
D(lorenz2′y) ~ lorenz2′x*(lorenz2′ρ-lorenz2′z)-lorenz2′y,
32+
0 ~ lorenz2′x + lorenz2′y + lorenz2′β*lorenz2′z]
2933

30-
check_consistency(de2)
31-
32-
b = a*z
33-
[states(de1,:x) ~ α*states(de2,:z),
34-
D(a) ~ b*states(de1,:x)]
35-
36-
states(states) == [lorenz1′x,lorenz1′y,lorenz1′z,lorenz2′x,lorenz2′y,lorenz2′z,a]
37-
parameters(connected) == [lorenz1′σ,lorenz1′ρ,lorenz1′β,lorenz2′σ,lorenz2′ρ,lorenz2′β,α]
34+
@test [x.name for x in states(connected)] == [:a,:lorenz1′x,:lorenz1′y,:lorenz1′z,:lorenz2′x,:lorenz2′y,:lorenz2′z]
35+
@test [x.name for x in parameters(connected)] == [,:lorenz1′σ,:lorenz1′ρ,:lorenz1′β,:lorenz2′σ,:lorenz2′ρ,:lorenz2′β]
36+
@test eqs_flat == equations(connected)

0 commit comments

Comments
 (0)