@@ -12,6 +12,14 @@ function ode_order_lowering(sys::ODESystem)
12
12
return sys
13
13
end
14
14
15
+ function dae_order_lowering (sys:: ODESystem )
16
+ iv = get_iv (sys)
17
+ eqs_lowered, new_vars = dae_order_lowering (equations (sys), iv, states (sys))
18
+ @set! sys. eqs = eqs_lowered
19
+ @set! sys. states = new_vars
20
+ return sys
21
+ end
22
+
15
23
function ode_order_lowering (eqs, iv, states)
16
24
var_order = OrderedDict {Any,Int} ()
17
25
D = Differential (iv)
@@ -47,3 +55,51 @@ function ode_order_lowering(eqs, iv, states)
47
55
# we want to order the equations and variables to be `(diff, alge)`
48
56
return (vcat (diff_eqs, alge_eqs), vcat (diff_vars, setdiff (states, diff_vars)))
49
57
end
58
+
59
+ function dae_order_lowering (eqs, iv, states)
60
+ var_order = OrderedDict {Any,Int} ()
61
+ D = Differential (iv)
62
+ diff_eqs = Equation[]
63
+ diff_vars = OrderedSet ()
64
+ alge_eqs = Equation[]
65
+ vars = Set ()
66
+ subs = Dict ()
67
+
68
+ for (i, eq) ∈ enumerate (eqs)
69
+ vars! (vars, eq)
70
+ n_diffvars = 0
71
+ for vv in vars
72
+ isdifferential (vv) || continue
73
+ var, maxorder = var_from_nested_derivative (vv)
74
+ isparameter (var) && continue
75
+ n_diffvars += 1
76
+ order = get (var_order, var, nothing )
77
+ seen = order != = nothing
78
+ if ! seen
79
+ order = 1
80
+ end
81
+ maxorder > order && (var_order[var] = maxorder)
82
+ var′ = lower_varname (var, iv, maxorder - 1 )
83
+ subs[vv] = D (var′)
84
+ if ! seen
85
+ push! (diff_vars, var′)
86
+ end
87
+ end
88
+ n_diffvars == 0 && push! (alge_eqs, eq)
89
+ empty! (vars)
90
+ end
91
+
92
+ for (var, order) ∈ var_order
93
+ for o in (order- 1 ): - 1 : 1
94
+ lvar = lower_varname (var, iv, o- 1 )
95
+ rvar = lower_varname (var, iv, o)
96
+ push! (diff_vars, lvar)
97
+
98
+ rhs = rvar
99
+ eq = Differential (iv)(lvar) ~ rhs
100
+ push! (diff_eqs, eq)
101
+ end
102
+ end
103
+
104
+ return ([diff_eqs; substitute .(eqs, (subs,))], vcat (collect (diff_vars), setdiff (states, diff_vars)))
105
+ end
0 commit comments