@@ -152,7 +152,7 @@ function Symbolics.connect(var1::ConnectableSymbolicT, var2::ConnectableSymbolic
152
152
vars:: ConnectableSymbolicT... )
153
153
allvars = (var1, var2, vars... )
154
154
validate_causal_variables_connection (allvars)
155
- return Equation (Connection (), Connection (map (SymbolicWithNameof, allvars)))
155
+ return Equation (Connection (), Connection (map (SymbolicWithNameof, unwrap .( allvars) )))
156
156
end
157
157
158
158
function flowvar (sys:: AbstractSystem )
@@ -328,14 +328,12 @@ namespaced by `namespace`.
328
328
`ignored_connects[1]`, purely to avoid unnecessary recomputation.
329
329
"""
330
330
function 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)
334
334
# ignore specified systems
335
335
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)
339
337
end
340
338
# `ignored_variables` for each `s` in `ss`
341
339
corresponding_ignored_variables = map (
@@ -434,15 +432,95 @@ function generate_connection_set(
434
432
connectionsets = ConnectionSet[]
435
433
domain_csets = ConnectionSet[]
436
434
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))
440
436
csets = merge (connectionsets)
441
437
domain_csets = merge ([csets; domain_csets], true )
442
438
443
439
sys, (csets, domain_csets)
444
440
end
445
441
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
+
446
524
"""
447
525
$(TYPEDSIGNATURES)
448
526
@@ -456,26 +534,12 @@ Generate connection sets from `connect` equations.
456
534
- `sys` is the system whose equations are to be searched.
457
535
- `namespace` is a system representing the namespace in which `sys` exists, or `nothing`
458
536
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.
463
537
"""
464
538
function generate_connection_set! (connectionsets, domain_csets,
465
539
sys:: AbstractSystem , find, replace, scalarize, namespace = nothing ,
466
- ignored_connects = (HierarchySystemT [], HierarchyVariableT []))
540
+ ignored_connects = (HierarchyAnalysisPointT [], HierarchyAnalysisPointT []))
467
541
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
479
543
480
544
isouter = generate_isouter (sys)
481
545
eqs′ = get_eqs (sys)
@@ -501,8 +565,12 @@ function generate_connection_set!(connectionsets, domain_csets,
501
565
neweq isa AbstractArray ? append! (eqs, neweq) : push! (eqs, neweq)
502
566
else
503
567
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))
506
574
elseif isconnection (rhs)
507
575
push! (cts, get_systems (rhs))
508
576
else
@@ -519,22 +587,19 @@ function generate_connection_set!(connectionsets, domain_csets,
519
587
# all connectors are eventually inside connectors.
520
588
T = ConnectionElement
521
589
# only generate connection sets for systems that are not ignored
522
- for s in filtered_subsys
590
+ for s in subsys
523
591
isconnector (s) || continue
524
592
is_domain_connector (s) && continue
525
- _ignored_variables = ignored_systems_for_subsystem (s, ignored_variables)
526
- _namespaced_ignored_variables = from_hierarchy .(_ignored_variables)
527
593
for v in unknowns (s)
528
594
Flow === get_connection_type (v) || continue
529
- # ignore specified variables
530
- any (isequal (v), _namespaced_ignored_variables) && continue
531
595
push! (connectionsets, ConnectionSet ([T (LazyNamespace (namespace, s), v, false )]))
532
596
end
533
597
end
534
598
535
599
for ct in cts
536
600
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))
538
603
end
539
604
540
605
# pre order traversal
@@ -558,14 +623,15 @@ ignored by `generate_connection_set!` (`expand_variable_connections`), filter
558
623
their hierarchy to not include `subsys`.
559
624
"""
560
625
function ignored_systems_for_subsystem (
561
- subsys:: AbstractSystem , ignored_systems:: Vector{<:HierarchyT} )
626
+ subsys:: AbstractSystem , ignored_systems:: Vector {<: Union {
627
+ HierarchyT, HierarchyAnalysisPointT}})
562
628
result = eltype (ignored_systems)[]
563
629
# in case `subsys` is namespaced, get its hierarchy and compare suffixes
564
630
# instead of the just the last element
565
631
suffix = reverse! (namespace_hierarchy (nameof (subsys)))
566
632
N = length (suffix)
567
633
for igsys in ignored_systems
568
- if igsys[(end - N + 1 ): end ] == suffix
634
+ if length (igsys) > N && igsys[(end - N + 1 ): end ] == suffix
569
635
push! (result, copy (igsys))
570
636
for i in 1 : N
571
637
pop! (result[end ])
@@ -684,7 +750,6 @@ function expand_variable_connections(sys::AbstractSystem; ignored_variables = no
684
750
if ignored_variables === nothing
685
751
ignored_variables = ignored_connections (sys)[2 ]
686
752
end
687
- namespaced_ignored = from_hierarchy .(ignored_variables)
688
753
eqs = copy (get_eqs (sys))
689
754
valid_idxs = trues (length (eqs))
690
755
additional_eqs = Equation[]
@@ -694,14 +759,11 @@ function expand_variable_connections(sys::AbstractSystem; ignored_variables = no
694
759
connection = eq. rhs
695
760
elements = get_systems (connection)
696
761
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
702
762
703
763
valid_idxs[i] = false
704
764
elements = map (x -> x. var, elements)
765
+ to_ignore = variables_to_ignore (ignored_variables, elements)
766
+ elements = setdiff (elements, to_ignore)
705
767
outvar = first (elements)
706
768
for invar in Iterators. drop (elements, 1 )
707
769
push! (additional_eqs, outvar ~ invar)
0 commit comments