Skip to content

Commit ac768f3

Browse files
authored
Merge pull request #391 from SciML/myb/ordering
Place algebraic equations after differential equations
2 parents e9cfca7 + 07e690b commit ac768f3

File tree

3 files changed

+33
-22
lines changed

3 files changed

+33
-22
lines changed

Project.toml

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

66
[deps]
77
ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
8+
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
89
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
910
DiffEqJump = "c894b116-72e5-5b58-be3c-e6d8d4ac2b12"
1011
DiffRules = "b552c78f-8df3-52c6-915a-8e097449b14b"
@@ -28,6 +29,7 @@ Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
2829

2930
[compat]
3031
ArrayInterface = "2.8"
32+
DataStructures = "0.17"
3133
DiffEqBase = "6.28"
3234
DiffEqJump = "6.7.5"
3335
DiffRules = "0.1, 1.0"

src/systems/diffeqs/first_order_transform.jl

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using DataStructures: OrderedDict
12
function lower_varname(var::Variable, idv, order)
23
order == 0 && return var
34
name = Symbol(var.name, , string(idv.name)^order)
@@ -24,43 +25,42 @@ function ode_order_lowering(sys::ODESystem)
2425
end
2526

2627
function ode_order_lowering(eqs, iv, states)
27-
var_order = Dict{Variable,Int}()
28-
vars = Variable[]
29-
new_eqs = Equation[]
30-
new_vars = Variable[]
28+
var_order = OrderedDict{Variable,Int}()
3129
D = Differential(iv())
30+
diff_eqs = Equation[]
31+
diff_vars = Variable[]
32+
alge_eqs = Equation[]
33+
alge_vars = Variable[]
3234

3335
for (i, (eq, ss)) enumerate(zip(eqs, states))
3436
if isequal(eq.lhs, Constant(0))
35-
push!(new_vars, ss)
36-
push!(new_eqs, eq)
37+
push!(alge_vars, ss)
38+
push!(alge_eqs, eq)
3739
else
3840
var, maxorder = var_from_nested_derivative(eq.lhs)
39-
if maxorder > get(var_order, var, 0)
40-
var_order[var] = maxorder
41-
any(isequal(var), vars) || push!(vars, var)
42-
end
41+
# only save to the dict when we need to lower the order to save memory
42+
maxorder > get(var_order, var, 1) && (var_order[var] = maxorder)
4343
var′ = lower_varname(var, iv, maxorder - 1)
4444
rhs′ = rename_lower_order(eq.rhs)
45-
push!(new_vars, var′)
46-
push!(new_eqs, D(var′(iv())) ~ rhs′)
45+
push!(diff_vars, var′)
46+
push!(diff_eqs, D(var′(iv())) ~ rhs′)
4747
end
4848
end
4949

50-
for var vars
51-
order = var_order[var]
50+
for (var, order) var_order
5251
for o in (order-1):-1:1
5352
lvar = lower_varname(var, iv, o-1)
5453
rvar = lower_varname(var, iv, o)
55-
push!(new_vars, lvar)
54+
push!(diff_vars, lvar)
5655

5756
rhs = rvar(iv())
5857
eq = Differential(iv())(lvar(iv())) ~ rhs
59-
push!(new_eqs, eq)
58+
push!(diff_eqs, eq)
6059
end
6160
end
6261

63-
return (new_eqs, new_vars)
62+
# we want to order the equations and variables to be `(diff, alge)`
63+
return (vcat(diff_eqs, alge_eqs), vcat(diff_vars, alge_vars))
6464
end
6565

6666
function rename_lower_order(O::Expression)

test/lowering_solving.jl

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
1-
using ModelingToolkit, OrdinaryDiffEq, Test
1+
using ModelingToolkit, OrdinaryDiffEq, Test, LinearAlgebra
22

33
@parameters t σ ρ β
4-
@variables x(t) y(t) z(t)
4+
@variables x(t) y(t) z(t) k(t)
55
@derivatives D'~t
66

77
eqs = [D(D(x)) ~ σ*(y-x),
88
D(y) ~ x*-z)-y,
99
D(z) ~ x*y - β*z]
1010

11-
sys = ODESystem(eqs)
12-
sys = ode_order_lowering(sys)
11+
sys′ = ODESystem(eqs)
12+
sys = ode_order_lowering(sys′)
13+
14+
eqs2 = [0 ~ x*y - k,
15+
D(D(x)) ~ σ*(y-x),
16+
D(y) ~ x*-z)-y,
17+
D(z) ~ x*y - β*z]
18+
sys2 = ODESystem(eqs2, t, [x, y, z, k], sys′.ps)
19+
sys2 = ode_order_lowering(sys2)
20+
# test equation/varible ordering
21+
ModelingToolkit.calculate_massmatrix(sys2) == Diagonal([1, 1, 1, 1, 0])
1322

1423
u0 = [D(x) => 2.0,
1524
x => 1.0,

0 commit comments

Comments
 (0)