Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/ModelingToolkitBase/src/systems/abstractsystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why can we only do this if we don't have subsytems? Is that fixable?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a comment. get_ir_info will build the IRInfo if a cached one does not exist. Doing so requires the ParameterBindingsGraph, which is only valid for flattened systems. I'll add a comment.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how hard would it be to remove that restriction? The bifurcation here seems sub-optimal.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not very hard, but it doesn't matter much. We hit the slow path for hierarchical systems, which we can't simulate anyway. The only case where full_equations on a hierarchical system matters is if the user is directly building a system that they will complete and never mtkcompile. It's safe to assume those systems are few and far between, and not large enough for the speedup here to matter. Flattening the system will also invalidate the cached IRInfo, so we'll redo this anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough. I'm just coming at this from a code simplicity perspective, but I'm fine with this as is.

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
Expand Down
4 changes: 1 addition & 3 deletions lib/ModelingToolkitBase/test/serialization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand All @@ -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]
6 changes: 5 additions & 1 deletion src/problems/sccnonlinearproblem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
Loading