Description
IMO the default behaviour of structural_simplify
caused by sort_eqs = true
is very surprising, and actually leads to problems in our downstream application.
Take the following example:
t = ModelingToolkit.t_nounits
D = ModelingToolkit.D_nounits
ps = @parameters Ka CL Vc
dvs = @variables Depot(t) Central(t)
eqs = [
D(Depot) ~ -Ka * Depot
D(Central) ~ Ka * Depot - CL / Vc * Central
]
@mtkbuild sys = ODESystem(eqs, t, dvs, ps)
In contrast to what was desired (and presumably expected) the order of state variables changed from
julia> dvs
2-element Vector{Num}:
Depot(t)
Central(t)
to
julia> ModelingToolkit.unknowns(sys)
2-element Vector{SymbolicUtils.BasicSymbolic{Real}}:
Central(t)
Depot(t)
Arguably changing the order of states/unknowns is much more surprising than changing the order of parameters, in particular in a case where @mtkbuild
does not perform any actual simplification.
In our application, users may refer to states/compartments by integers when defining events/doses, so the reordering is not only surprising but actually breaks existing code (arguably, referring to compartments by integers is not ideal but that's how it's done in common data formats in the field, and telling people they can't use their existing datasets anymore doesn't seem feasible).
I think one could avoid these surprises in many (all?) cases by making sort_eqs
an internal implementation detail but not user-facing. I'm not sure if it's possible since I'm not familiar with the implementation, but in principle I would assume that the tearing algorithm could operate on the sorted equations but the states of the resulting simplified system could be permuted such that they are in the same order as the original system, before returning the result of structural_simplify
to the user.