Skip to content

Commit 9e0568f

Browse files
Merge pull request #3736 from AayushSabharwal/as/connector-rework
refactor: rewrite connection expansion implementation
2 parents cd03953 + c66a92f commit 9e0568f

10 files changed

+1139
-797
lines changed

src/ModelingToolkit.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ include("systems/index_cache.jl")
161161
include("systems/parameter_buffer.jl")
162162
include("systems/abstractsystem.jl")
163163
include("systems/model_parsing.jl")
164+
include("systems/connectiongraph.jl")
164165
include("systems/connectors.jl")
165166
include("systems/state_machines.jl")
166167
include("systems/analysis_points.jl")

src/systems/abstractsystem.jl

Lines changed: 13 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,104 +1368,6 @@ struct IgnoredAnalysisPoint
13681368
outputs::Vector{Union{BasicSymbolic, AbstractSystem}}
13691369
end
13701370

1371-
const HierarchyVariableT = Vector{Union{BasicSymbolic, Symbol}}
1372-
const HierarchySystemT = Vector{Union{AbstractSystem, Symbol}}
1373-
"""
1374-
The type returned from `analysis_point_common_hierarchy`.
1375-
"""
1376-
const HierarchyAnalysisPointT = Vector{Union{IgnoredAnalysisPoint, Symbol}}
1377-
"""
1378-
The type returned from `as_hierarchy`.
1379-
"""
1380-
const HierarchyT = Union{HierarchyVariableT, HierarchySystemT}
1381-
1382-
"""
1383-
$(TYPEDSIGNATURES)
1384-
1385-
The inverse operation of `as_hierarchy`.
1386-
"""
1387-
function from_hierarchy(hierarchy::HierarchyT)
1388-
namefn = hierarchy[1] isa AbstractSystem ? nameof : getname
1389-
foldl(@view hierarchy[2:end]; init = hierarchy[1]) do sys, name
1390-
rename(sys, Symbol(name, NAMESPACE_SEPARATOR, namefn(sys)))
1391-
end
1392-
end
1393-
1394-
"""
1395-
$(TYPEDSIGNATURES)
1396-
1397-
Represent an ignored analysis point as a namespaced hierarchy. The hierarchy is built
1398-
using the common hierarchy of all involved systems/variables.
1399-
"""
1400-
function analysis_point_common_hierarchy(ap::IgnoredAnalysisPoint)::HierarchyAnalysisPointT
1401-
isys = as_hierarchy(ap.input)
1402-
osyss = as_hierarchy.(ap.outputs)
1403-
suffix = Symbol[]
1404-
while isys[end] == osyss[1][end] && allequal(last.(osyss))
1405-
push!(suffix, isys[end])
1406-
pop!(isys)
1407-
pop!.(osyss)
1408-
end
1409-
isys = from_hierarchy(isys)
1410-
osyss = from_hierarchy.(osyss)
1411-
newap = IgnoredAnalysisPoint(isys, osyss)
1412-
hierarchy = HierarchyAnalysisPointT([suffix; newap])
1413-
reverse!(hierarchy)
1414-
return hierarchy
1415-
end
1416-
1417-
"""
1418-
$(TYPEDSIGNATURES)
1419-
1420-
Represent a namespaced system (or variable) `sys` as a hierarchy. Return a vector, where
1421-
the first element is the unnamespaced system (variable) and subsequent elements are
1422-
`Symbol`s representing the parents of the unnamespaced system (variable) in order from
1423-
inner to outer.
1424-
"""
1425-
function as_hierarchy(sys::Union{AbstractSystem, BasicSymbolic})::HierarchyT
1426-
namefn = sys isa AbstractSystem ? nameof : getname
1427-
# get the hierarchy
1428-
hierarchy = namespace_hierarchy(namefn(sys))
1429-
# rename the system with unnamespaced name
1430-
newsys = rename(sys, hierarchy[end])
1431-
# and remove it from the list
1432-
pop!(hierarchy)
1433-
# reverse it to go from inner to outer
1434-
reverse!(hierarchy)
1435-
# concatenate
1436-
T = sys isa AbstractSystem ? AbstractSystem : BasicSymbolic
1437-
return Union{Symbol, T}[newsys; hierarchy]
1438-
end
1439-
1440-
"""
1441-
$(TYPEDSIGNATURES)
1442-
1443-
Get the analysis points to ignore for `sys` and its subsystems. The returned value is a
1444-
`Tuple` similar in structure to the `ignored_connections` field.
1445-
"""
1446-
function ignored_connections(sys::AbstractSystem)
1447-
has_ignored_connections(sys) ||
1448-
return (HierarchyAnalysisPointT[], HierarchyAnalysisPointT[])
1449-
1450-
ics = get_ignored_connections(sys)
1451-
if ics === nothing
1452-
ics = (HierarchyAnalysisPointT[], HierarchyAnalysisPointT[])
1453-
end
1454-
# turn into hierarchies
1455-
ics = (map(analysis_point_common_hierarchy, ics[1]),
1456-
map(analysis_point_common_hierarchy, ics[2]))
1457-
systems = get_systems(sys)
1458-
# for each subsystem, get its ignored connections, add the name of the subsystem
1459-
# to the hierarchy and concatenate corresponding buffers of the result
1460-
result = mapreduce(Broadcast.BroadcastFunction(vcat), systems; init = ics) do subsys
1461-
sub_ics = ignored_connections(subsys)
1462-
(map(Base.Fix2(push!, nameof(subsys)), sub_ics[1]),
1463-
map(Base.Fix2(push!, nameof(subsys)), sub_ics[2]))
1464-
end
1465-
return (Vector{HierarchyAnalysisPointT}(result[1]),
1466-
Vector{HierarchyAnalysisPointT}(result[2]))
1467-
end
1468-
14691371
"""
14701372
$(TYPEDSIGNATURES)
14711373
@@ -1993,35 +1895,20 @@ function n_expanded_connection_equations(sys::AbstractSystem)
19931895
# TODO: what about inputs?
19941896
isconnector(sys) && return length(get_unknowns(sys))
19951897
sys = remove_analysis_points(sys)
1996-
n_variable_connect_eqs = 0
1997-
for eq in equations(sys)
1998-
is_causal_variable_connection(eq.rhs) || continue
1999-
n_variable_connect_eqs += length(get_systems(eq.rhs)) - 1
2000-
end
2001-
20021898
sys, (csets, _) = generate_connection_set(sys)
2003-
ceqs, instream_csets = generate_connection_equations_and_stream_connections(csets)
2004-
n_outer_stream_variables = 0
2005-
for cset in instream_csets
2006-
n_outer_stream_variables += count(x -> x.isouter, cset.set)
2007-
end
2008-
2009-
#n_toplevel_unused_flows = 0
2010-
#toplevel_flows = Set()
2011-
#for cset in csets
2012-
# e1 = first(cset.set)
2013-
# e1.sys.namespace === nothing || continue
2014-
# for e in cset.set
2015-
# get_connection_type(e.v) === Flow || continue
2016-
# push!(toplevel_flows, e.v)
2017-
# end
2018-
#end
2019-
#for m in get_systems(sys)
2020-
# isconnector(m) || continue
2021-
# n_toplevel_unused_flows += count(x->get_connection_type(x) === Flow && !(x in toplevel_flows), get_unknowns(m))
2022-
#end
2023-
2024-
nextras = n_outer_stream_variables + length(ceqs) + n_variable_connect_eqs
1899+
1900+
n_extras = 0
1901+
for cset in csets
1902+
rep = cset[1]
1903+
if rep.type <: Union{InputVar, OutputVar, Equality}
1904+
n_extras += length(cset) - 1
1905+
elseif rep.type == Flow
1906+
n_extras += 1
1907+
elseif rep.type == Stream
1908+
n_extras += count(x -> x.isouter, cset)
1909+
end
1910+
end
1911+
return n_extras
20251912
end
20261913

20271914
Base.show(io::IO, sys::AbstractSystem; kws...) = show(io, MIME"text/plain"(), sys; kws...)

src/systems/analysis_points.jl

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -432,19 +432,15 @@ function with_analysis_point_ignored(sys::AbstractSystem, ap::AnalysisPoint)
432432
has_ignored_connections(sys) || return sys
433433
ignored = get_ignored_connections(sys)
434434
if ignored === nothing
435-
ignored = (IgnoredAnalysisPoint[], IgnoredAnalysisPoint[])
435+
ignored = Connection[]
436436
else
437-
ignored = copy.(ignored)
437+
ignored = copy(ignored)
438438
end
439439
if ap.outputs === nothing
440440
error("Empty analysis point")
441441
end
442442

443-
if ap.input isa AbstractSystem && all(x -> x isa AbstractSystem, ap.outputs)
444-
push!(ignored[1], IgnoredAnalysisPoint(ap.input, ap.outputs))
445-
else
446-
push!(ignored[2], IgnoredAnalysisPoint(unwrap(ap.input), unwrap.(ap.outputs)))
447-
end
443+
push!(ignored, Connection([unwrap(ap.input); unwrap.(ap.outputs)]))
448444

449445
return @set sys.ignored_connections = ignored
450446
end

0 commit comments

Comments
 (0)