Skip to content

Commit c2d30e2

Browse files
committed
Add sort_states to make mass matrix identity-like
1 parent 7a1f784 commit c2d30e2

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

src/systems/abstractsystem.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ function structural_simplify(sys::AbstractSystem)
527527
if sys isa ODESystem
528528
sys = dae_index_lowering(sys)
529529
end
530-
sys = tearing(sys)
530+
sys = sort_states(tearing(sys))
531531
fullstates = [map(eq->eq.lhs, observed(sys)); states(sys)]
532532
@set! sys.observed = topsort_equations(observed(sys), fullstates)
533533
return sys

src/systems/diffeqs/odesystem.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,33 @@ function _eq_unordered(a, b)
279279
end
280280
return true
281281
end
282+
283+
"""
284+
$(SIGNATURES)
285+
286+
Sort the states so that the mass matrix is as identity-like as possible.
287+
"""
288+
function sort_states(sys::ODESystem)
289+
sys = flatten(sys)
290+
eqs = equations(sys)
291+
sts = states(sys)
292+
sorted_states = OrderedSet()
293+
var2idx = Dict(sts .=> eachindex(sts))
294+
idx = 0
295+
for eq in eqs
296+
if isdiffeq(eq)
297+
var = arguments(eq.lhs)[1]
298+
if haskey(var2idx, var)
299+
pop!(var2idx, var)
300+
push!(sorted_states, var)
301+
end
302+
end
303+
end
304+
305+
var2idx = collect(pairs(var2idx))
306+
sorted_states = collect(sorted_states)
307+
append!(sorted_states, map(x->x[1], sort(var2idx, by=x->x[2])))
308+
309+
@set! sys.states = sorted_states
310+
@set! sys.structure = nothing
311+
end

0 commit comments

Comments
 (0)