Skip to content

Commit 8de0a39

Browse files
authored
add ability to modify system _after_ analysis point handling, but before linearization (#316)
This allows conversion to JuliaSimCompiler.IRSystem for the structural simplification
1 parent d4a6e2c commit 8de0a39

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

src/Blocks/analysis_points.jl

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,8 @@ end
285285

286286
const SymOrVec = Union{Symbol, Vector{Symbol}}
287287

288-
function get_sensitivity_function(sys, ap_name::SymOrVec; loop_openings = nothing,
288+
function get_sensitivity_function(
289+
sys, ap_name::SymOrVec; loop_openings = nothing, system_modifier = identity,
289290
kwargs...)
290291
find = namespaced_ap_match(ap_name, loop_openings)
291292
t = get_iv(sys)
@@ -311,10 +312,12 @@ function get_sensitivity_function(sys, ap_name::SymOrVec; loop_openings = nothin
311312
permutation = _check_and_sort!(ap_name, aps, namespaces, multiplicities)
312313
dn = ModelingToolkit.renamespace.(namespaces, d[permutation])
313314
un = ModelingToolkit.renamespace.(namespaces, u[permutation])
315+
sys = system_modifier(sys)
314316
ModelingToolkit.linearization_function(sys, dn, un; kwargs...)
315317
end
316318

317-
function get_comp_sensitivity_function(sys, ap_name::SymOrVec; loop_openings = nothing,
319+
function get_comp_sensitivity_function(
320+
sys, ap_name::SymOrVec; loop_openings = nothing, system_modifier = identity,
318321
kwargs...)
319322
find = namespaced_ap_match(ap_name, loop_openings)
320323
t = get_iv(sys)
@@ -340,10 +343,12 @@ function get_comp_sensitivity_function(sys, ap_name::SymOrVec; loop_openings = n
340343
permutation = _check_and_sort!(ap_name, aps, namespaces, multiplicities)
341344
dn = ModelingToolkit.renamespace.(namespaces, d[permutation])
342345
un = ModelingToolkit.renamespace.(namespaces, u[permutation])
346+
sys = system_modifier(sys)
343347
ModelingToolkit.linearization_function(sys, dn, un; kwargs...)
344348
end
345349

346-
function get_looptransfer_function(sys, ap_name::SymOrVec; loop_openings = nothing,
350+
function get_looptransfer_function(
351+
sys, ap_name::SymOrVec; loop_openings = nothing, system_modifier = identity,
347352
kwargs...)
348353
find = namespaced_ap_match(ap_name, loop_openings)
349354
t = get_iv(sys)
@@ -366,6 +371,7 @@ function get_looptransfer_function(sys, ap_name::SymOrVec; loop_openings = nothi
366371
y = reduce(vcat, ap_var(ap.in) for ap in aps)
367372
yn = ModelingToolkit.renamespace.(namespaces, y)# permutation applied in _check_and_sort
368373
un = ModelingToolkit.renamespace.(namespaces, u)
374+
sys = system_modifier(sys)
369375
ModelingToolkit.linearization_function(sys, un, yn; kwargs...)
370376
end
371377

@@ -387,7 +393,8 @@ Open the loop at analysis point `ap` by breaking the connection through `ap`.
387393
388394
See also [`get_sensitivity`](@ref), [`get_comp_sensitivity`](@ref), [`get_looptransfer`](@ref).
389395
"""
390-
function open_loop(sys, ap_name::Symbol; ground_input = false, kwargs...)
396+
function open_loop(
397+
sys, ap_name::Symbol; ground_input = false, system_modifier = identity, kwargs...)
391398
find = namespaced_ap_match(ap_name, nothing)
392399
t = get_iv(sys)
393400
@variables u(t)=0 [input = true]
@@ -407,12 +414,13 @@ function open_loop(sys, ap_name::Symbol; ground_input = false, kwargs...)
407414
end
408415
sys = expand_connections(sys, find, replace)
409416
(ap = apr[]) === nothing && error("Did not find analysis point $ap_name")
410-
sys
417+
sys = system_modifier(sys)
411418
end
412419

413420
function ModelingToolkit.linearization_function(sys::ModelingToolkit.AbstractSystem,
414421
input_name::SymOrVec, output_name;
415422
loop_openings = nothing,
423+
system_modifier = identity, # This is used to, e.g., apply JuliaSimCompiler.IRSystem after analysis-point handling
416424
kwargs...)
417425
t = get_iv(sys)
418426
@variables u(t)=0 [input = true]
@@ -474,7 +482,7 @@ function ModelingToolkit.linearization_function(sys::ModelingToolkit.AbstractSys
474482
else
475483
yn = output_name
476484
end
477-
ModelingToolkit.linearization_function(sys, un, yn; kwargs...)
485+
ModelingToolkit.linearization_function(system_modifier(sys), un, yn; kwargs...)
478486
end
479487

480488
# Add a method to get_sensitivity that accepts the name of an AnalysisPoint
@@ -497,9 +505,10 @@ for f in [:get_sensitivity, :get_comp_sensitivity, :get_looptransfer]
497505
loop_openings = nothing,
498506
op = Dict(),
499507
p = DiffEqBase.NullParameters(),
508+
system_modifier = identity,
500509
kwargs...)
501510
lin_fun, ssys = $(Symbol(string(f) * "_function"))(sys, ap, args...; op, p,
502-
loop_openings,
511+
loop_openings, system_modifier,
503512
kwargs...)
504513
ModelingToolkit.linearize(ssys, lin_fun; op, p, kwargs...), ssys
505514
end
@@ -513,9 +522,9 @@ Linearize a system between two analysis points. To get a loop-transfer function,
513522
The output is allowed to be either an analysis-point name, or a vector of symbolic variables like the standard interface to `linearize`. The input must be an analysis-point name.
514523
"""
515524
function ModelingToolkit.linearize(sys, input_name::SymOrVec, output_name;
516-
loop_openings = nothing, kwargs...)
517-
lin_fun, ssys = linearization_function(sys, input_name, output_name; loop_openings,
518-
kwargs...)
525+
loop_openings = nothing, system_modifier = identity, kwargs...)
526+
lin_fun, ssys = linearization_function(sys, input_name, output_name;
527+
loop_openings, system_modifier, kwargs...)
519528
ModelingToolkit.linearize(ssys, lin_fun; kwargs...), ssys
520529
end
521530

0 commit comments

Comments
 (0)