From 21ae63149c555f2dbaa093cb3b097c249f517594 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Wed, 17 Sep 2025 13:48:08 +0530 Subject: [PATCH 1/5] fix: fix minor bug in `generate_initializesystem` --- src/systems/nonlinear/initializesystem.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systems/nonlinear/initializesystem.jl b/src/systems/nonlinear/initializesystem.jl index f377f0202f..9ccef2f48b 100644 --- a/src/systems/nonlinear/initializesystem.jl +++ b/src/systems/nonlinear/initializesystem.jl @@ -154,7 +154,7 @@ function generate_initializesystem_timevarying(sys::AbstractSystem; # 3) process other variables for var in vars if var ∈ keys(op) - push!(eqs_ics, var ~ defs[var]) + push!(eqs_ics, var ~ op[var]) elseif var ∈ keys(guesses) push!(defs, var => guesses[var]) elseif check_defguess From 7ffb3172be0aa7a652eae557d4a0401497046457 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Thu, 18 Sep 2025 11:43:16 +0530 Subject: [PATCH 2/5] refactor: remove dead code in `unhack_observed` --- src/systems/nonlinear/initializesystem.jl | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/systems/nonlinear/initializesystem.jl b/src/systems/nonlinear/initializesystem.jl index 9ccef2f48b..79fbbfb16b 100644 --- a/src/systems/nonlinear/initializesystem.jl +++ b/src/systems/nonlinear/initializesystem.jl @@ -824,8 +824,6 @@ Counteracts the CSE/array variable hacks in `symbolics_tearing.jl` so it works w initialization. """ function unhack_observed(obseqs::Vector{Equation}, eqs::Vector{Equation}) - subs = Dict() - tempvars = Set() rm_idxs = Int[] for (i, eq) in enumerate(obseqs) iscall(eq.rhs) || continue @@ -835,20 +833,7 @@ function unhack_observed(obseqs::Vector{Equation}, eqs::Vector{Equation}) end end - for (i, eq) in enumerate(obseqs) - if eq.lhs in tempvars - subs[eq.lhs] = eq.rhs - push!(rm_idxs, i) - end - end - obseqs = obseqs[setdiff(eachindex(obseqs), rm_idxs)] - obseqs = map(obseqs) do eq - fixpoint_sub(eq.lhs, subs) ~ fixpoint_sub(eq.rhs, subs) - end - eqs = map(eqs) do eq - fixpoint_sub(eq.lhs, subs) ~ fixpoint_sub(eq.rhs, subs) - end return obseqs, eqs end From 584f690e56dccd847592280b918319e30afe50fc Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Thu, 18 Sep 2025 11:43:35 +0530 Subject: [PATCH 3/5] refactor: only substitute with non-empty rules --- src/systems/connectors.jl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/systems/connectors.jl b/src/systems/connectors.jl index c0ddf5baee..a4156990ab 100644 --- a/src/systems/connectors.jl +++ b/src/systems/connectors.jl @@ -895,10 +895,12 @@ function expand_connections(sys::AbstractSystem; tol = 1e-10) stream_eqs, instream_subs = expand_instream(instream_csets, sys; tol = tol) eqs = [equations(sys); ceqs; stream_eqs] - # substitute `instream(..)` expressions with their new values - for i in eachindex(eqs) - eqs[i] = fixpoint_sub( - eqs[i], instream_subs; maxiters = max(length(instream_subs), 10)) + if !isempty(instream_subs) + # substitute `instream(..)` expressions with their new values + for i in eachindex(eqs) + eqs[i] = fixpoint_sub( + eqs[i], instream_subs; maxiters = max(length(instream_subs), 10)) + end end # get the defaults for domain networks d_defs = domain_defaults(sys, domain_csets) From a27467abd5c3f8203d8276f7c186ae8f2dce61ff Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Thu, 18 Sep 2025 11:55:16 +0530 Subject: [PATCH 4/5] fix: handle edge case in `trivial_tearing!` --- src/systems/systemstructure.jl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/systems/systemstructure.jl b/src/systems/systemstructure.jl index a1460731cb..edad19db5f 100644 --- a/src/systems/systemstructure.jl +++ b/src/systems/systemstructure.jl @@ -635,6 +635,7 @@ function trivial_tearing!(ts::TearingState) matched_vars = BitSet() # variable to index in fullvars var_to_idx = Dict{Any, Int}(ts.fullvars .=> eachindex(ts.fullvars)) + sys_eqs = equations(ts) complete!(ts.structure) var_to_diff = ts.structure.var_to_diff @@ -654,6 +655,14 @@ function trivial_tearing!(ts::TearingState) push!(blacklist, i) continue end + # Edge case for `var ~ var` equations. They don't show up in the incidence + # graph because `TearingState` makes them `0 ~ 0`, but they do cause `var` + # to show up twice in `original_eqs` which fails the assertion. + sys_eq = sys_eqs[i] + if isequal(sys_eq.lhs, 0) && isequal(sys_eq.rhs, 0) + continue + end + # if a variable was the LHS of two trivial observed equations, we wouldn't have # included it in the list. Error if somehow it made it through. @assert !(vari in matched_vars) From 5f652534e9c0bec2793c31fed01ac1eb5be31a06 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Mon, 6 Oct 2025 17:36:02 +0530 Subject: [PATCH 5/5] feat: retain `solvable_graph` in `tearing_reassemble` --- src/structural_transformation/symbolics_tearing.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/structural_transformation/symbolics_tearing.jl b/src/structural_transformation/symbolics_tearing.jl index 39b959c5a6..4a19f6f419 100644 --- a/src/structural_transformation/symbolics_tearing.jl +++ b/src/structural_transformation/symbolics_tearing.jl @@ -889,6 +889,8 @@ function reorder_vars!(state::TearingState, var_eq_matching, var_sccs, eq_orderi # the new reality of the system we've just created. new_graph = contract_variables(graph, var_eq_matching, varsperm, eqsperm, nsolved_eq, nsolved_var) + new_solvable_graph = contract_variables(solvable_graph, var_eq_matching, varsperm, eqsperm, + nsolved_eq, nsolved_var) new_var_to_diff = complete(DiffGraph(length(var_ordering))) for (v, d) in enumerate(var_to_diff) @@ -919,6 +921,7 @@ function reorder_vars!(state::TearingState, var_eq_matching, var_sccs, eq_orderi # Update system structure @set! state.structure.graph = complete(new_graph) + @set! state.structure.solvable_graph = complete(new_solvable_graph) @set! state.structure.var_to_diff = new_var_to_diff @set! state.structure.eq_to_diff = new_eq_to_diff @set! state.fullvars = new_fullvars