@@ -74,22 +74,50 @@ function ODESystem(deqs::AbstractVector{<:Equation}, iv, dvs, ps;
7474 ODESystem (deqs, iv′, dvs′, ps′, tgrad, jac, Wfact, Wfact_t, name, systems)
7575end
7676
77- var_from_nested_derivative (x) = var_from_nested_derivative (x,0 )
7877var_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+
8080iv_from_nested_derivative (x) = x. op isa Differential ? iv_from_nested_derivative (x. args[1 ]) : x. args[1 ]. op
8181iv_from_nested_derivative (x:: Constant ) = missing
8282
8383function 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... )
93121end
94122
95123Base.:(== )(sys1:: ODESystem , sys2:: ODESystem ) =
0 commit comments