@@ -328,14 +328,12 @@ namespaced by `namespace`.
328328 `ignored_connects[1]`, purely to avoid unnecessary recomputation.
329329"""
330330function connection2set! (connectionsets, namespace, ss, isouter;
331- ignored_connects = ( HierarchySystemT[], HierarchyVariableT[]),
332- namespaced_ignored_systems = ODESystem[] )
333- ignored_systems, ignored_variables = ignored_connects
331+ ignored_systems = HierarchySystemT[], ignored_variables = HierarchyVariableT[])
332+ ns_ignored_systems = from_hierarchy .(ignored_systems )
333+ ns_ignored_variables = from_hierarchy .(ignored_variables)
334334 # ignore specified systems
335335 ss = filter (ss) do s
336- all (namespaced_ignored_systems) do igsys
337- nameof (igsys) != nameof (s)
338- end
336+ ! any (x -> nameof (x) == nameof (s), ns_ignored_systems)
339337 end
340338 # `ignored_variables` for each `s` in `ss`
341339 corresponding_ignored_variables = map (
@@ -434,15 +432,95 @@ function generate_connection_set(
434432 connectionsets = ConnectionSet[]
435433 domain_csets = ConnectionSet[]
436434 sys = generate_connection_set! (
437- connectionsets, domain_csets, sys, find, replace, scalarize, nothing ,
438- # include systems to be ignored
439- ignored_connections (sys))
435+ connectionsets, domain_csets, sys, find, replace, scalarize, nothing , ignored_connections (sys))
440436 csets = merge (connectionsets)
441437 domain_csets = merge ([csets; domain_csets], true )
442438
443439 sys, (csets, domain_csets)
444440end
445441
442+ """
443+ $(TYPEDSIGNATURES)
444+
445+ For a list of `systems` in a connect equation, return the subset of it to ignore (as a
446+ list of hierarchical systems) based on `ignored_system_aps`, the analysis points to be
447+ ignored. All analysis points in `ignored_system_aps` must contain systems (connectors)
448+ as their input/outputs.
449+ """
450+ function systems_to_ignore (ignored_system_aps:: Vector{HierarchyAnalysisPointT} ,
451+ systems:: Union{Vector{<:AbstractSystem}, Tuple{Vararg{<:AbstractSystem}}} )
452+ to_ignore = HierarchySystemT[]
453+ for ap in ignored_system_aps
454+ # if `systems` contains the input of the AP, ignore any outputs of the AP present in it.
455+ isys_hierarchy = HierarchySystemT ([ap[1 ]. input; @view ap[2 : end ]])
456+ isys = from_hierarchy (isys_hierarchy)
457+ any (x -> nameof (x) == nameof (isys), systems) || continue
458+
459+ for outsys in ap[1 ]. outputs
460+ osys_hierarchy = HierarchySystemT ([outsys; @view ap[2 : end ]])
461+ osys = from_hierarchy (osys_hierarchy)
462+ any (x -> nameof (x) == nameof (osys), systems) || continue
463+ push! (to_ignore, HierarchySystemT (osys_hierarchy))
464+ end
465+ end
466+
467+ return to_ignore
468+ end
469+
470+ """
471+ $(TYPEDSIGNATURES)
472+
473+ For a list of `systems` in a connect equation, return the subset of their variables to
474+ ignore (as a list of hierarchical variables) based on `ignored_system_aps`, the analysis
475+ points to be ignored. All analysis points in `ignored_system_aps` must contain variables
476+ as their input/outputs.
477+ """
478+ function variables_to_ignore (ignored_variable_aps:: Vector{HierarchyAnalysisPointT} ,
479+ systems:: Union{Vector{<:AbstractSystem}, Tuple{Vararg{<:AbstractSystem}}} )
480+ to_ignore = HierarchyVariableT[]
481+ for ap in ignored_variable_aps
482+ ivar_hierarchy = HierarchyVariableT ([ap[1 ]. input; @view ap[2 : end ]])
483+ ivar = from_hierarchy (ivar_hierarchy)
484+ any (x -> any (isequal (ivar), renamespace .((x,), unknowns (x))), systems) || continue
485+
486+ for outvar in ap[1 ]. outputs
487+ ovar_hierarchy = HierarchyVariableT ([as_hierarchy (outvar); @view ap[2 : end ]])
488+ ovar = from_hierarchy (ovar_hierarchy)
489+ any (x -> any (isequal (ovar), renamespace .((x,), unknowns (x))), systems) ||
490+ continue
491+ push! (to_ignore, HierarchyVariableT (ovar_hierarchy))
492+ end
493+ end
494+ return to_ignore
495+ end
496+
497+ """
498+ $(TYPEDSIGNATURES)
499+
500+ For a list of variables `vars` in a connect equation, return the subset of them ignore
501+ (as a list of symbolic variables) based on `ignored_system_aps`, the analysis points to
502+ be ignored. All analysis points in `ignored_system_aps` must contain variables as their
503+ input/outputs.
504+ """
505+ function variables_to_ignore (ignored_variable_aps:: Vector{HierarchyAnalysisPointT} ,
506+ vars:: Union{Vector{<:BasicSymbolic}, Tuple{Vararg{<:BasicSymbolic}}} )
507+ to_ignore = eltype (vars)[]
508+ for ap in ignored_variable_aps
509+ ivar_hierarchy = HierarchyVariableT ([ap[1 ]. input; @view ap[2 : end ]])
510+ ivar = from_hierarchy (ivar_hierarchy)
511+ any (isequal (ivar), vars) || continue
512+
513+ for outvar in ap[1 ]. outputs
514+ ovar_hierarchy = HierarchyVariableT ([outvar; @view ap[2 : end ]])
515+ ovar = from_hierarchy (ovar_hierarchy)
516+ any (isequal (ovar), vars) || continue
517+ push! (to_ignore, ovar)
518+ end
519+ end
520+
521+ return to_ignore
522+ end
523+
446524"""
447525 $(TYPEDSIGNATURES)
448526
@@ -456,26 +534,12 @@ Generate connection sets from `connect` equations.
456534- `sys` is the system whose equations are to be searched.
457535- `namespace` is a system representing the namespace in which `sys` exists, or `nothing`
458536 for no namespace (if `sys` is top-level).
459- - `ignored_connects` is a tuple. The first (second) element is a list of systems
460- (variables) in the format returned by `as_hierarchy` to be ignored when generating
461- connections. This is typically because the connections they are used in were removed by
462- analysis point transformations.
463537"""
464538function generate_connection_set! (connectionsets, domain_csets,
465539 sys:: AbstractSystem , find, replace, scalarize, namespace = nothing ,
466- ignored_connects = (HierarchySystemT [], HierarchyVariableT []))
540+ ignored_connects = (HierarchyAnalysisPointT [], HierarchyAnalysisPointT []))
467541 subsys = get_systems (sys)
468- ignored_systems, ignored_variables = ignored_connects
469- # turn hierarchies into namespaced systems
470- namespaced_ignored_systems = from_hierarchy .(ignored_systems)
471- namespaced_ignored_variables = from_hierarchy .(ignored_variables)
472- namespaced_ignored = (namespaced_ignored_systems, namespaced_ignored_variables)
473- # filter the subsystems of `sys` to exclude ignored ones
474- filtered_subsys = filter (subsys) do ss
475- all (namespaced_ignored_systems) do igsys
476- nameof (igsys) != nameof (ss)
477- end
478- end
542+ ignored_system_aps, ignored_variable_aps = ignored_connects
479543
480544 isouter = generate_isouter (sys)
481545 eqs′ = get_eqs (sys)
@@ -501,8 +565,12 @@ function generate_connection_set!(connectionsets, domain_csets,
501565 neweq isa AbstractArray ? append! (eqs, neweq) : push! (eqs, neweq)
502566 else
503567 if lhs isa Connection && get_systems (lhs) === :domain
504- connection2set! (domain_csets, namespace, get_systems (rhs), isouter;
505- ignored_connects, namespaced_ignored_systems)
568+ connected_systems = get_systems (rhs)
569+ connection2set! (domain_csets, namespace, connected_systems, isouter;
570+ ignored_systems = systems_to_ignore (
571+ ignored_system_aps, connected_systems),
572+ ignored_variables = variables_to_ignore (
573+ ignored_variable_aps, connected_systems))
506574 elseif isconnection (rhs)
507575 push! (cts, get_systems (rhs))
508576 else
@@ -519,22 +587,19 @@ function generate_connection_set!(connectionsets, domain_csets,
519587 # all connectors are eventually inside connectors.
520588 T = ConnectionElement
521589 # only generate connection sets for systems that are not ignored
522- for s in filtered_subsys
590+ for s in subsys
523591 isconnector (s) || continue
524592 is_domain_connector (s) && continue
525- _ignored_variables = ignored_systems_for_subsystem (s, ignored_variables)
526- _namespaced_ignored_variables = from_hierarchy .(_ignored_variables)
527593 for v in unknowns (s)
528594 Flow === get_connection_type (v) || continue
529- # ignore specified variables
530- any (isequal (v), _namespaced_ignored_variables) && continue
531595 push! (connectionsets, ConnectionSet ([T (LazyNamespace (namespace, s), v, false )]))
532596 end
533597 end
534598
535599 for ct in cts
536600 connection2set! (connectionsets, namespace, ct, isouter;
537- ignored_connects, namespaced_ignored_systems)
601+ ignored_systems = systems_to_ignore (ignored_system_aps, ct),
602+ ignored_variables = variables_to_ignore (ignored_variable_aps, ct))
538603 end
539604
540605 # pre order traversal
@@ -558,14 +623,15 @@ ignored by `generate_connection_set!` (`expand_variable_connections`), filter
558623their hierarchy to not include `subsys`.
559624"""
560625function ignored_systems_for_subsystem (
561- subsys:: AbstractSystem , ignored_systems:: Vector{<:HierarchyT} )
626+ subsys:: AbstractSystem , ignored_systems:: Vector {<: Union {
627+ HierarchyT, HierarchyAnalysisPointT}})
562628 result = eltype (ignored_systems)[]
563629 # in case `subsys` is namespaced, get its hierarchy and compare suffixes
564630 # instead of the just the last element
565631 suffix = reverse! (namespace_hierarchy (nameof (subsys)))
566632 N = length (suffix)
567633 for igsys in ignored_systems
568- if igsys[(end - N + 1 ): end ] == suffix
634+ if length (igsys) > N && igsys[(end - N + 1 ): end ] == suffix
569635 push! (result, copy (igsys))
570636 for i in 1 : N
571637 pop! (result[end ])
@@ -684,7 +750,6 @@ function expand_variable_connections(sys::AbstractSystem; ignored_variables = no
684750 if ignored_variables === nothing
685751 ignored_variables = ignored_connections (sys)[2 ]
686752 end
687- namespaced_ignored = from_hierarchy .(ignored_variables)
688753 eqs = copy (get_eqs (sys))
689754 valid_idxs = trues (length (eqs))
690755 additional_eqs = Equation[]
@@ -694,14 +759,11 @@ function expand_variable_connections(sys::AbstractSystem; ignored_variables = no
694759 connection = eq. rhs
695760 elements = get_systems (connection)
696761 is_causal_variable_connection (connection) || continue
697- elements = filter (elements) do el
698- all (namespaced_ignored) do var
699- getname (var) != getname (el. var)
700- end
701- end
702762
703763 valid_idxs[i] = false
704764 elements = map (x -> x. var, elements)
765+ to_ignore = variables_to_ignore (ignored_variables, elements)
766+ elements = setdiff (elements, to_ignore)
705767 outvar = first (elements)
706768 for invar in Iterators. drop (elements, 1 )
707769 push! (additional_eqs, outvar ~ invar)
0 commit comments