@@ -74,22 +74,50 @@ function ODESystem(deqs::AbstractVector{<:Equation}, iv, dvs, ps;
74
74
ODESystem (deqs, iv′, dvs′, ps′, tgrad, jac, Wfact, Wfact_t, name, systems)
75
75
end
76
76
77
- var_from_nested_derivative (x) = var_from_nested_derivative (x,0 )
78
77
var_from_nested_derivative (x:: Constant ) = (missing , missing )
79
- var_from_nested_derivative (x,i) = x. op isa Differential ? var_from_nested_derivative (x. args[1 ],i+ 1 ) : (x. op,i)
78
+ var_from_nested_derivative (x,i= 0 ) = x. op isa Differential ? var_from_nested_derivative (x. args[1 ],i+ 1 ) : (x. op,i)
79
+
80
80
iv_from_nested_derivative (x) = x. op isa Differential ? iv_from_nested_derivative (x. args[1 ]) : x. args[1 ]. op
81
81
iv_from_nested_derivative (x:: Constant ) = missing
82
82
83
83
function ODESystem (eqs; kwargs... )
84
- ivs = unique (skipmissing (iv_from_nested_derivative (eq. lhs) for eq ∈ eqs))
85
- length (ivs) == 1 || throw (ArgumentError (" one independent variable currently supported" ))
86
- iv = first (ivs)
87
-
88
- dvs = unique (skipmissing (var_from_nested_derivative (eq. lhs)[1 ] for eq ∈ eqs))
89
- ps = filter (vars (eq. rhs for eq ∈ eqs)) do x
90
- isparameter (x) & ! isequal (x, iv)
91
- end |> collect
92
- ODESystem (eqs, iv, dvs, ps; kwargs... )
84
+ # NOTE: this assumes that the order of algebric equations doesn't matter
85
+ diffvars = OrderedSet {Variable} ()
86
+ allstates = OrderedSet {Variable} ()
87
+ ps = OrderedSet {Variable} ()
88
+ # reorder equations such that it is in the form of `diffeq, algeeq`
89
+ diffeq = Equation[]
90
+ algeeq = Equation[]
91
+ # initial loop for finding `iv`
92
+ iv = nothing
93
+ for eq in eqs
94
+ if ! (eq. lhs isa Constant) # assume eq.lhs is either Differential or Constant
95
+ iv = iv_from_nested_derivative (eq. lhs)
96
+ end
97
+ end
98
+ iv === nothing && throw (ArgumentError (" No differential variable detected." ))
99
+ for eq in eqs
100
+ for var in vars (eq. rhs for eq ∈ eqs)
101
+ var isa Variable || continue
102
+ if isparameter (var)
103
+ isequal (var, iv) || push! (ps, var)
104
+ else
105
+ push! (allstates, var)
106
+ end
107
+ end
108
+ if eq. lhs isa Constant
109
+ push! (algeeq, eq)
110
+ else
111
+ diffvar = first (var_from_nested_derivative (eq. lhs))
112
+ iv == iv_from_nested_derivative (eq. lhs) || throw (ArgumentError (" An ODESystem can only have one independent variable." ))
113
+ diffvar in diffvars && throw (ArgumentError (" The differential variable $diffvar is not unique in the system of equations." ))
114
+ push! (diffvars, diffvar)
115
+ push! (diffeq, eq)
116
+ end
117
+ end
118
+ algevars = setdiff (allstates, diffvars)
119
+ # the orders here are very important!
120
+ return ODESystem (append! (diffeq, algeeq), iv, vcat (collect (diffvars), collect (algevars)), ps; kwargs... )
93
121
end
94
122
95
123
Base.:(== )(sys1:: ODESystem , sys2:: ODESystem ) =
0 commit comments