From 1f6b0378200501d82ffb124be8b3a3d845782f77 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Thu, 18 Jun 2026 12:45:31 +0530 Subject: [PATCH 1/2] fix: avoid mutating buffer being iterated when updating `total_sub` incidence --- lib/ModelingToolkitTearing/src/reassemble.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/ModelingToolkitTearing/src/reassemble.jl b/lib/ModelingToolkitTearing/src/reassemble.jl index ebdb4cd..50c427e 100644 --- a/lib/ModelingToolkitTearing/src/reassemble.jl +++ b/lib/ModelingToolkitTearing/src/reassemble.jl @@ -967,7 +967,10 @@ function codegen_equation!(eg::EquationGenerator, # We will add `neweq.lhs` to `total_sub`, so any equation involving it won't be # incident on it. Remove the edges incident on `iv` from the graph, and add # the replacement vertices from `ieq` so that the incidence is still correct. - for e in đť‘‘neighbors(graph, iv) + # + # The `copy` is necessary because `rem_edge!` will mutate the buffer that we + # iterate over. + for e in copy(đť‘‘neighbors(graph, iv)) e == ieq && continue for v in đť‘ neighbors(graph, ieq) add_edge!(graph, e, v) From c807c2f380700a77f6bf707866e5c86788002442 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Thu, 18 Jun 2026 12:50:21 +0530 Subject: [PATCH 2/2] docs: add comment explaining graph validity in `generate_system_equations!` --- lib/ModelingToolkitTearing/src/reassemble.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/ModelingToolkitTearing/src/reassemble.jl b/lib/ModelingToolkitTearing/src/reassemble.jl index 50c427e..8db6ac9 100644 --- a/lib/ModelingToolkitTearing/src/reassemble.jl +++ b/lib/ModelingToolkitTearing/src/reassemble.jl @@ -425,6 +425,10 @@ function generate_system_equations!(state::TearingState, neweqs::Vector{Equation (var_to_diff[i] !== nothing && !isempty(đť‘‘neighbors(graph, var_to_diff[i])))) end + # NOTE: `state.structure.graph` should be accurate despite `generate_system_equations!` + # mutating the graph (when generating differential equations/populating `total_sub`). + # If the graph disagrees with symbolic incidence at any point during the execution of + # this function, then there is some invalid operation happening on the graph. digraph = DiCMOBiGraph{false}(graph, var_eq_matching) for (i, scc) in enumerate(var_sccs) # note that the `vscc <-> escc` relation is a set-to-set mapping, and not