@@ -171,27 +171,34 @@ Compute the sensitivity function in analysis point `ap`. The sensitivity functio
171
171
See also [`get_comp_sensitivity`](@ref), [`get_looptransfer`](@ref).
172
172
"""
173
173
function get_sensitivity (sys, ap_name:: Symbol ; kwargs... )
174
- find = let ap_name = ap_name
175
- x -> x isa AnalysisPoint && nameof (x) === ap_name
174
+ find = function (x, ns)
175
+ x isa AnalysisPoint || return false
176
+ if ns === nothing
177
+ nameof (x) === ap_name
178
+ else
179
+ Symbol (ns, :_ , nameof (x)) === ap_name
180
+ end
176
181
end
177
182
t = get_iv (sys)
178
- @variables d (t) = 0 # Perturbation serving as input to sensivity transfer function
183
+ @variables d (t) = 0 # Perturbation serving as input to sensitivity transfer function
179
184
namespace = Ref {Union{Nothing, Symbol}} (nothing )
180
- this_ap = Ref {Union{Nothing, AnalysisPoint}} (nothing )
181
- replace = let d = d, namespace = namespace, this_ap = this_ap
182
- (ap, ns) -> begin
183
- namespace[] = ns
184
- this_ap [] = ap
185
+ apr = Ref {Union{Nothing, AnalysisPoint}} (nothing )
186
+ replace = let d = d, namespace = namespace, apr = apr
187
+ function (ap, ns)
188
+ namespace[] = ns # Save the namespace to make it available for renamespace below
189
+ apr [] = ap
185
190
(ap. out. u ~ ap. in. u + d), d
186
191
end
187
192
end
188
193
sys = expand_connections (sys, find, replace)
189
- (ap = this_ap []) === nothing && error (" Did not find analysis point $ap " )
194
+ (ap = apr []) === nothing && error (" Did not find analysis point $ap " )
190
195
u = ap. out. u
191
196
if (ns = namespace[]) != = nothing
192
- d = ModelingToolkit. renamespace (d, ns)
193
- u = ModelingToolkit. renamespace (u, ns)
197
+ @show ns
198
+ @show d = ModelingToolkit. renamespace (ns, d)
199
+ @show u = ModelingToolkit. renamespace (ns, u)
194
200
end
201
+ @show u, d
195
202
ModelingToolkit. linearize (sys, [d], [u]; kwargs... )
196
203
end
197
204
@@ -209,23 +216,34 @@ Compute the complementary sensitivity function in analysis point `ap`. The compl
209
216
210
217
See also [`get_sensitivity`](@ref), [`get_looptransfer`](@ref).
211
218
"""
212
- function get_comp_sensitivity (sys, ap:: AnalysisPoint ; kwargs... )
213
- sys = ModelingToolkit. flatten (sys) # To get namespacing right
219
+ function get_comp_sensitivity (sys, ap_name:: Symbol ; kwargs... )
220
+ find = function (x, ns)
221
+ x isa AnalysisPoint || return false
222
+ if ns === nothing
223
+ nameof (x) === ap_name
224
+ else
225
+ Symbol (ns, :_ , nameof (x)) === ap_name
226
+ end
227
+ end
214
228
t = get_iv (sys)
215
- @variables d (t) = 0 # Perturbation serving as input to sensivity transfer function
216
- found = false
217
- new_eqs = map (equations (sys)) do eq
218
- eq. rhs == ap || (return eq)
219
- found = true
220
- ap. out. u + d ~ ap. in. u # This assumes that the connector has an internal vaiable named u
229
+ @variables d (t) = 0 # Perturbation serving as input to sensitivity transfer function
230
+ namespace = Ref {Union{Nothing, Symbol}} (nothing )
231
+ apr = Ref {Union{Nothing, AnalysisPoint}} (nothing )
232
+ replace = let d = d, namespace = namespace, apr = apr
233
+ function (ap, ns)
234
+ namespace[] = ns # Save the namespace to make it available for renamespace below
235
+ apr[] = ap
236
+ (ap. out. u + d ~ ap. in. u), d
237
+ end
221
238
end
222
- found || error (" Did not find analysis point $ap " )
223
- @set! sys. eqs = new_eqs
224
- @set! sys. states = [states (sys); d]
225
- @set! sys. defaults = merge (ModelingToolkit. defaults (sys), Dict (d => 0 ))
226
-
227
- sys = expand_analysis_points (sys) # Any remaining analysis points are removed by this
228
- ModelingToolkit. linearize (sys, [d], [ap. in. u]; kwargs... )
239
+ sys = expand_connections (sys, find, replace)
240
+ (ap = apr[]) === nothing && error (" Did not find analysis point $ap " )
241
+ u = ap. in. u
242
+ if (ns = namespace[]) != = nothing
243
+ d = ModelingToolkit. renamespace (ns, d)
244
+ u = ModelingToolkit. renamespace (ns, u)
245
+ end
246
+ ModelingToolkit. linearize (sys, [d], [u]; kwargs... )
229
247
end
230
248
231
249
"""
@@ -242,19 +260,34 @@ Compute the (linearized) loop-transfer function in analysis point `ap`, from `ap
242
260
243
261
See also [`get_sensitivity`](@ref), [`get_comp_sensitivity`](@ref), [`open_loop`](@ref).
244
262
"""
245
- function get_looptransfer (sys, ap:: AnalysisPoint ; kwargs... )
246
- sys = ModelingToolkit. flatten (sys) # To get namespacing right
263
+ function get_looptransfer (sys, ap_name:: Symbol ; kwargs... )
264
+ find = function (x, ns)
265
+ x isa AnalysisPoint || return false
266
+ if ns === nothing
267
+ nameof (x) === ap_name
268
+ else
269
+ Symbol (ns, :_ , nameof (x)) === ap_name
270
+ end
271
+ end
247
272
t = get_iv (sys)
248
- found = false
249
- new_eqs = map (equations (sys)) do eq
250
- eq. rhs == ap || (return eq)
251
- found = true
252
- 0 ~ 0 # This assumes that the connector has an internal vaiable named u
273
+ namespace = Ref {Union{Nothing, Symbol}} (nothing )
274
+ apr = Ref {Union{Nothing, AnalysisPoint}} (nothing )
275
+ replace = let namespace = namespace, apr = apr
276
+ function (ap, ns)
277
+ namespace[] = ns # Save the namespace to make it available for renamespace below
278
+ apr[] = ap
279
+ (0 ~ 0 ), nothing
280
+ end
253
281
end
254
- found || error (" Did not find analysis point $ap " )
255
- @set! sys. eqs = new_eqs
256
- sys = expand_analysis_points (sys) # Any remaining analysis points are removed by this
257
- ModelingToolkit. linearize (sys, [ap. out. u], [ap. in. u]; kwargs... )
282
+ sys = expand_connections (sys, find, replace)
283
+ (ap = apr[]) === nothing && error (" Did not find analysis point $ap " )
284
+ u = ap. out. u
285
+ y = ap. in. u
286
+ if (ns = namespace[]) != = nothing
287
+ y = ModelingToolkit. renamespace (ns, y)
288
+ u = ModelingToolkit. renamespace (ns, u)
289
+ end
290
+ ModelingToolkit. linearize (sys, [u], [y]; kwargs... )
258
291
end
259
292
260
293
"""
@@ -273,54 +306,78 @@ Open the loop at analysis point `ap` by breaking the connection through `ap`.
273
306
274
307
See also [`get_sensitivity`](@ref), [`get_comp_sensitivity`](@ref), [`get_looptransfer`](@ref).
275
308
"""
276
- function open_loop (sys, ap:: AnalysisPoint ; kwargs... )
277
- sys = ModelingToolkit. flatten (sys) # To get namespacing right
309
+ function open_loop (sys, ap_name:: Symbol ; kwargs... )
310
+ find = function (x, ns)
311
+ x isa AnalysisPoint || return false
312
+ if ns === nothing
313
+ nameof (x) === ap_name
314
+ else
315
+ Symbol (ns, :_ , nameof (x)) === ap_name
316
+ end
317
+ end
278
318
t = get_iv (sys)
279
319
@variables u (t)= 0 [input = true ]
280
320
@variables y (t)= 0 [output = true ]
281
- found = false
282
- new_eqs = map (equations (sys)) do eq
283
- eq. rhs == ap || (return [eq])
284
- found = true
285
- [ap. out. u ~ u
286
- ap. in. u ~ y]
321
+ namespace = Ref {Union{Nothing, Symbol}} (nothing )
322
+ apr = Ref {Union{Nothing, AnalysisPoint}} (nothing )
323
+ replace = let u = u, y = y, namespace = namespace, apr = apr
324
+ function (ap, ns)
325
+ namespace[] = ns # Save the namespace to make it available for renamespace below
326
+ apr[] = ap
327
+ [ap. out. u ~ u, ap. in. u ~ y], [u, y]
328
+ end
287
329
end
288
- found || error (" Did not find analysis point $ap " )
289
- new_eqs = reduce (vcat, new_eqs)
290
- @set! sys. eqs = new_eqs
291
- @set! sys. states = [states (sys); u; y]
292
- @set! sys. defaults = merge (ModelingToolkit. defaults (sys), Dict (u => 0 , y => 0 ))
330
+ if (ns = namespace[]) != = nothing
331
+ y = ModelingToolkit. renamespace (ns, y)
332
+ u = ModelingToolkit. renamespace (ns, u)
333
+ end
334
+ sys = expand_connections (sys, find, replace)
335
+ (ap = apr[]) === nothing && error (" Did not find analysis point $ap " )
293
336
sys
294
337
end
295
338
296
339
"""
297
- ModelingToolkit.linearize(sys, input::AnalysisPoint, output::AnalysisPoint )
340
+ ModelingToolkit.linearize(sys, input_name::Symbol, output_name::Symbol )
298
341
299
342
Linearize a system between two analysis points.
300
343
All parts of the model that do not appear between `input` and `output` will be neglected.
301
344
"""
302
- function ModelingToolkit. linearize (sys, input :: AnalysisPoint , output :: AnalysisPoint ;
345
+ function ModelingToolkit. linearize (sys, input_name :: Symbol , output_name :: Symbol ;
303
346
kwargs... )
304
- sys = ModelingToolkit. flatten (sys) # To get namespacing right
347
+ find = function (x, ns)
348
+ x isa AnalysisPoint || return false
349
+ if ns === nothing
350
+ nameof (x) ∈ (input_name, output_name)
351
+ else
352
+ Symbol (ns, :_ , nameof (x)) ∈ (input_name, output_name)
353
+ end
354
+ end
305
355
t = get_iv (sys)
306
356
@variables u (t)= 0 [input = true ]
307
357
@variables y (t)= 0 [output = true ]
308
- new_eqs = map (equations (sys)) do eq
309
- if eq. rhs == input
310
- [input. out. u ~ u]
311
- # input.in.u ~ 0] # We only need to ground one of the ends, hence not including this equation
312
- elseif eq. rhs == output
313
- [output. in. u ~ y
314
- output. out. u ~ 0 ]
315
- else
316
- return [eq]
358
+ namespace = Ref {Union{Nothing, Symbol}} (nothing )
359
+ apr = Ref {Union{Nothing, AnalysisPoint}} (nothing )
360
+ replace = let u = u, y = y, namespace = namespace, apr = apr
361
+ function (ap, ns)
362
+ namespace[] = ns # Save the namespace to make it available for renamespace below
363
+ apr[] = ap
364
+ if nameof (ap) === input_name
365
+ [ap. out. u ~ u], u
366
+ # input.in.u ~ 0] # We only need to ground one of the ends, hence not including this equation
367
+ elseif nameof (ap) === output_name
368
+ [ap. in. u ~ y
369
+ ap. out. u ~ 0 ], y
370
+ else
371
+ error (" This should never happen" )
372
+ end
317
373
end
318
374
end
319
- new_eqs = reduce (vcat, new_eqs)
320
- @set! sys. eqs = new_eqs
321
- @set! sys. states = [states (sys); u; y]
322
- @set! sys. defaults = merge (ModelingToolkit. defaults (sys), Dict (u => 0 , y => 0 ))
323
- sys = expand_analysis_points (sys)
375
+ sys = expand_connections (sys, find, replace)
376
+ (ap = apr[]) === nothing && error (" Did not find analysis point $ap " )
377
+ if (ns = namespace[]) != = nothing
378
+ y = ModelingToolkit. renamespace (ns, y)
379
+ u = ModelingToolkit. renamespace (ns, u)
380
+ end
324
381
ModelingToolkit. linearize (sys, [u], [y]; kwargs... )
325
382
end
326
383
@@ -331,11 +388,7 @@ for f in [:get_sensitivity, :get_comp_sensitivity, :get_looptransfer, :open_loop
331
388
end
332
389
end
333
390
334
- function ModelingToolkit. linearize (sys, input_name :: Symbol , output_name :: Symbol ;
391
+ function ModelingToolkit. linearize (sys, input :: AnalysisPoint , output :: AnalysisPoint ;
335
392
kwargs... )
336
- input = find_analysis_point (sys, input_name)
337
- input === nothing && error (" Failed to find an analysis point named $input_name " )
338
- output = find_analysis_point (sys, output_name)
339
- output === nothing && error (" Failed to find an analysis point named $output_name " )
340
- ModelingToolkit. linearize (sys, input, output; kwargs... )
393
+ ModelingToolkit. linearize (sys, nameof (input), nameof (output); kwargs... )
341
394
end
0 commit comments