Skip to content

Commit f039e65

Browse files
refactor: allow printing the problematic equations in topsort_equations
1 parent c990bb8 commit f039e65

1 file changed

Lines changed: 37 additions & 1 deletion

File tree

lib/ModelingToolkitBase/src/systems/systems.jl

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,12 @@ function observed2graph(sys::AbstractSystem, eqs::Vector{Equation}, unknowns::Ve
983983
return graph, assigns
984984
end
985985

986+
"""
987+
Toggle to control whether `topsort_equations` prints the equations in the
988+
cycle, if present.
989+
"""
990+
TOPSORT_EQS_PRINT_CYCLE::Bool = false
991+
986992
"""
987993
$(TYPEDSIGNATURES)
988994
@@ -1054,7 +1060,37 @@ function topsort_equations(sys::AbstractSystem, eqs::Vector{Equation}, unknowns:
10541060
end
10551061
end
10561062

1057-
(check && idx != neqs) && throw(ArgumentError("The equations have at least one cycle."))
1063+
if check && idx != neqs
1064+
# Build a directed eq→eq subgraph over unsorted equations, find smallest SCC.
1065+
if TOPSORT_EQS_PRINT_CYCLE
1066+
unsorted = findall(>(0), degrees)
1067+
unsorted_set = Set(unsorted)
1068+
n_unsorted = length(unsorted)
1069+
old_to_new = Dict(old => new for (new, old) in enumerate(unsorted))
1070+
1071+
g = SimpleDiGraph(n_unsorted)
1072+
for src_old in unsorted
1073+
for dst_old in 𝑑neighbors(graph, assigns[src_old])
1074+
dst_old in unsorted_set || continue
1075+
add_edge!(g, old_to_new[src_old], old_to_new[dst_old])
1076+
end
1077+
end
1078+
1079+
sccs = strongly_connected_components(g)
1080+
nontrivial = filter(scc -> length(scc) >= 2, sccs)
1081+
smallest_new = isempty(nontrivial) ? collect(1:n_unsorted) :
1082+
nontrivial[argmin(length.(nontrivial))]
1083+
1084+
println("=== topsort_equations: CYCLE DETECTED ===")
1085+
println("Smallest cycle ($(length(smallest_new)) equations):")
1086+
for new_idx in smallest_new
1087+
old_idx = unsorted[new_idx]
1088+
println(" LHS = $(unknowns[assigns[old_idx]])")
1089+
println(" EQ = $(eqs[old_idx])")
1090+
end
1091+
end
1092+
throw(ArgumentError("The equations have at least one cycle."))
1093+
end
10581094

10591095
return ordered_eqs
10601096
end

0 commit comments

Comments
 (0)