diff --git a/lib/ModelingToolkitBase/src/systems/abstractsystem.jl b/lib/ModelingToolkitBase/src/systems/abstractsystem.jl index 31d5deec18..00d57653f9 100644 --- a/lib/ModelingToolkitBase/src/systems/abstractsystem.jl +++ b/lib/ModelingToolkitBase/src/systems/abstractsystem.jl @@ -1998,6 +1998,20 @@ equations during `mtkcompile`. These equations matches generated numerical code. See also [`equations`](@ref) and [`ModelingToolkitBase.get_eqs`](@ref). """ function full_equations(sys::AbstractSystem; simplify = false) + subsys = get_systems(sys) + # Fast path using `IRInfo` + if isempty(subsys) + new_eqs = Equation[] + eqs = equations(sys) + sizehint!(new_eqs, length(eqs)) + info = get_ir_info(sys) + ir = get_irstructure(sys) + @assert length(info.eqs_idxs) == length(eqs) + for (eq, rhs_idx) in zip(eqs, info.eqs_idxs) + push!(new_eqs, eq.lhs ~ ir[rhs_idx]) + end + return new_eqs + end empty_substitutions(sys) && return equations(sys) subs = get_substitutions(sys) neweqs = map(equations(sys)) do eq diff --git a/lib/ModelingToolkitBase/test/serialization.jl b/lib/ModelingToolkitBase/test/serialization.jl index 9bffd12f96..16814a6830 100644 --- a/lib/ModelingToolkitBase/test/serialization.jl +++ b/lib/ModelingToolkitBase/test/serialization.jl @@ -29,8 +29,7 @@ str = String(take!(io)) sys = include_string(@__MODULE__, str) rc2 = expand_connections(rc_model) -@test isapprox(sys, rc2) -@test issetequal(equations(sys), equations(rc2)) +@test issetequal(full_equations(sys), full_equations(rc2)) @test issetequal(unknowns(sys), unknowns(rc2)) @test issetequal(parameters(sys), parameters(rc2)) @@ -54,5 +53,4 @@ sol_ = solve(prob_, ImplicitEuler()) probexpr = ODEProblem{true}(ss, [capacitor.v => 0.0], (0, 0.1); expr = Val{true}, missing_guess_value); prob_obs = eval(probexpr) sol_obs = solve(prob_obs, ImplicitEuler()) -@show all_obs @test sol_obs[all_obs] == sol[all_obs] diff --git a/src/problems/sccnonlinearproblem.jl b/src/problems/sccnonlinearproblem.jl index 4c16426d72..15aebcdcb1 100644 --- a/src/problems/sccnonlinearproblem.jl +++ b/src/problems/sccnonlinearproblem.jl @@ -296,7 +296,10 @@ function build_caches!(sys::System, decomposition::SCCDecomposition) push!(banned_vars, split_indexed_var(u)[1]) end - _eqs = get_eqs(subsys) + # While we own the system and so mutation _should_ be safe, `IRInfo` exists. + # It stores the indices corresponding to equations in the `IRStructure`, which + # would be incorrect if we mutate. + _eqs = copy(get_eqs(subsys)) exprs_to_search = SymbolicT[] for i in eachindex(_eqs) push!(exprs_to_search, _eqs[i].rhs) @@ -306,6 +309,7 @@ function build_caches!(sys::System, decomposition::SCCDecomposition) for i in eachindex(_eqs) _eqs[i] = _eqs[i].lhs ~ subber(_eqs[i].rhs) end + subsys = decomposition.subsystems[i] = ConstructionBase.setproperties(subsys; eqs = _eqs) if decomposition.islinear[i] store_to_mutable_cache!(subsys, CachedLinearAb, nothing)