Skip to content

Commit 2a422fb

Browse files
Merge pull request #3748 from AayushSabharwal/as/loop-opening-defs
feat: better handle loop opening defaults
2 parents f5d3f48 + 92b395a commit 2a422fb

File tree

7 files changed

+527
-511
lines changed

7 files changed

+527
-511
lines changed

src/linearization.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ function linearization_function(sys::AbstractSystem, inputs,
4545
warn_initialize_determined = true,
4646
guesses = Dict(),
4747
warn_empty_op = true,
48+
t = 0.0,
4849
kwargs...)
4950
op = Dict(op)
5051
if isempty(op) && warn_empty_op
@@ -73,7 +74,7 @@ function linearization_function(sys::AbstractSystem, inputs,
7374
end
7475

7576
prob = ODEProblem{true, SciMLBase.FullSpecialize}(
76-
sys, merge(op, anydict(p)), (nothing, nothing); allow_incomplete = true,
77+
sys, merge(op, anydict(p)), (t, t); allow_incomplete = true,
7778
algebraic_only = true, guesses)
7879
u0 = state_values(prob)
7980

@@ -753,7 +754,7 @@ function linearize(sys, inputs, outputs; op = Dict(), t = 0.0,
753754
inputs,
754755
outputs;
755756
zero_dummy_der,
756-
op,
757+
op, t,
757758
kwargs...)
758759
mats, extras = linearize(ssys, lin_fun; op, t, allow_input_derivatives)
759760
mats, ssys, extras

src/systems/analysis_points.jl

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -486,14 +486,19 @@ struct Break <: AnalysisPointTransformation
486486
Whether to add a new input variable connected to all the outputs of `ap`.
487487
"""
488488
add_input::Bool
489+
"""
490+
Whether the default of the added input variable should be the input of `ap`. Only
491+
applicable if `add_input == true`.
492+
"""
493+
default_outputs_to_input::Bool
489494
end
490495

491496
"""
492497
$(TYPEDSIGNATURES)
493498
494-
`Break` the given analysis point `ap` without adding an input.
499+
`Break` the given analysis point `ap`.
495500
"""
496-
Break(ap::AnalysisPoint) = Break(ap, false)
501+
Break(ap::AnalysisPoint, add_input::Bool = false) = Break(ap, add_input, false)
497502

498503
function apply_transformation(tf::Break, sys::AbstractSystem)
499504
modify_nested_subsystem(sys, tf.ap) do breaksys
@@ -517,7 +522,11 @@ function apply_transformation(tf::Break, sys::AbstractSystem)
517522
push!(breaksys_eqs, ap_var(outsys) ~ new_var)
518523
end
519524
defs = copy(get_defaults(breaksys))
520-
defs[new_var] = new_def
525+
defs[new_var] = if tf.default_outputs_to_input
526+
ap_ivar
527+
else
528+
new_def
529+
end
521530
@set! breaksys.defaults = defs
522531
unks = copy(get_unknowns(breaksys))
523532
push!(unks, new_var)
@@ -803,7 +812,7 @@ Given a list of analysis points, break the connection for each and set the outpu
803812
"""
804813
function handle_loop_openings(sys::AbstractSystem, aps)
805814
for ap in canonicalize_ap(sys, aps)
806-
sys, (outvar,) = apply_transformation(Break(ap, true), sys)
815+
sys, (outvar,) = apply_transformation(Break(ap, true, true), sys)
807816
if Symbolics.isarraysymbolic(outvar)
808817
push!(get_eqs(sys), outvar ~ zeros(size(outvar)))
809818
else
@@ -815,7 +824,7 @@ end
815824

816825
const DOC_LOOP_OPENINGS = """
817826
- `loop_openings`: A list of analysis points whose connections should be removed and
818-
the outputs set to zero as a part of the linear analysis.
827+
the outputs set to the input as a part of the linear analysis.
819828
"""
820829

821830
const DOC_SYS_MODIFIER = """
@@ -952,7 +961,7 @@ function linearization_ap_transform(sys,
952961
for input in inputs
953962
if nameof(input) in loop_openings
954963
delete!(loop_openings, nameof(input))
955-
sys, (input_var,) = apply_transformation(Break(input, true), sys)
964+
sys, (input_var,) = apply_transformation(Break(input, true, true), sys)
956965
else
957966
sys, (input_var,) = apply_transformation(PerturbOutput(input), sys)
958967
end

src/systems/connectiongraph.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,10 +414,6 @@ function remove_negative_connections!(
414414
# if there is any other variable, start removing
415415
push!(idxs_to_rm[edge_j], var_j)
416416
end
417-
if should_rm
418-
# if there was any other variable, also remove `input_j`
419-
push!(idxs_to_rm, input_j)
420-
end
421417
end
422418
end
423419

@@ -459,6 +455,7 @@ function connectionsets(graph::ConnectionGraph)
459455
disjoint_sets = IntDisjointSets(length(invmap))
460456
for edge_i in 𝑠vertices(bigraph)
461457
hyperedge = 𝑠neighbors(bigraph, edge_i)
458+
isempty(hyperedge) && continue
462459
root, rest = Iterators.peel(hyperedge)
463460
for vert in rest
464461
union!(disjoint_sets, root, vert)

src/systems/connectors.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,16 @@ function _generate_connectionsets!(connection_state::AbstractConnectionState,
468468
[namespace; var_ns], length(var_ns) == 1 || isouter(var_ns[1]), type)
469469
end
470470
add_connection_edge!(connection_state, hyperedge)
471+
472+
# Removed analysis points generate causal connections in the negative graph. These
473+
# should also remove `Equality` connections involving the same variables, so also
474+
# add an `Equality` variant of the edge.
475+
if connection_state isa NegativeConnectionState
476+
hyperedge = map(hyperedge) do cvert
477+
ConnectionVertex(cvert.name, cvert.isouter, Equality)
478+
end
479+
add_connection_edge!(connection_state, hyperedge)
480+
end
471481
end
472482
end
473483

0 commit comments

Comments
 (0)