Skip to content

Commit 8a14d18

Browse files
feat: optionally track source information in expand_connections
1 parent f7c02f0 commit 8a14d18

File tree

1 file changed

+57
-3
lines changed

1 file changed

+57
-3
lines changed

lib/ModelingToolkitBase/src/systems/connectors.jl

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -967,14 +967,38 @@ function get_domain_bindings(
967967
return binds
968968
end
969969

970+
"""
971+
$TYPEDEF
972+
973+
Struct that can optionally be returned from [`expand_connections`](@ref) and indicates
974+
where in the system the equations come from, along with other potentially useful source
975+
information.
976+
977+
# Fields
978+
979+
$TYPEDFIELDS
980+
"""
981+
struct EquationSourceInformation
982+
"""
983+
For each equation, a `Vector{Symbol}` denoting the path from the root system to the
984+
subsystem where this equation comes from. Includes the name of the root system. An
985+
empty entry indicates unknown source (typically for connection equations).
986+
"""
987+
eqs_source::Vector{Vector{Symbol}}
988+
"""
989+
A mask indicating which equations arise from `connect` statements.
990+
"""
991+
is_connection_equation::BitVector
992+
end
993+
970994
"""
971995
$(TYPEDSIGNATURES)
972996
973997
Given a hierarchical system with [`connect`](@ref) equations, expand the connection
974998
equations and return the new system. `tol` is the tolerance for handling the singularities
975999
in stream connection equations that happen when a flow variable approaches zero.
9761000
"""
977-
function expand_connections(sys::AbstractSystem; tol = 1e-10)
1001+
function expand_connections(sys::AbstractSystem, ::Val{with_source_info} = Val(false); tol = 1e-10) where {with_source_info}
9781002
# turn analysis points into standard connection equations
9791003
sys = remove_analysis_points(sys)
9801004
# generate the connection sets
@@ -983,7 +1007,31 @@ function expand_connections(sys::AbstractSystem; tol = 1e-10)
9831007
ceqs, instream_csets = generate_connection_equations_and_stream_connections(sys, csets)
9841008
stream_eqs, instream_subs = expand_instream(instream_csets, sys; tol = tol)
9851009

986-
eqs = [equations(sys); ceqs; stream_eqs]
1010+
if with_source_info
1011+
source_visitor = SourceInformationVisitor()
1012+
eqs = equations(sys, source_visitor)
1013+
N = length(eqs) + length(ceqs) + length(stream_eqs)
1014+
sources = source_visitor.sources
1015+
# Names are in reverse order
1016+
foreach(reverse!, sources)
1017+
is_connection_equation = falses(length(sources))
1018+
sizehint!(eqs, N)
1019+
sizehint!(sources, N)
1020+
sizehint!(is_connection_equation, N)
1021+
for eq in ceqs
1022+
push!(eqs, eq)
1023+
push!(sources, Symbol[])
1024+
push!(is_connection_equation, true)
1025+
end
1026+
for eq in stream_eqs
1027+
push!(eqs, eq)
1028+
push!(sources, Symbol[])
1029+
push!(is_connection_equation, true)
1030+
end
1031+
source_info = EquationSourceInformation(sources, is_connection_equation)
1032+
else
1033+
eqs = [equations(sys); ceqs; stream_eqs]
1034+
end
9871035
if !isempty(instream_subs)
9881036
# substitute `instream(..)` expressions with their new values
9891037
for i in eachindex(eqs)
@@ -996,7 +1044,13 @@ function expand_connections(sys::AbstractSystem; tol = 1e-10)
9961044
# build the new system
9971045
sys = flatten(sys, true)
9981046
@set! sys.eqs = eqs
999-
@set sys.bindings = newbinds
1047+
@set! sys.bindings = newbinds
1048+
1049+
if with_source_info
1050+
return sys, source_info
1051+
else
1052+
return sys
1053+
end
10001054
end
10011055

10021056
"""

0 commit comments

Comments
 (0)