Skip to content

Commit 36abc8b

Browse files
Merge pull request #3625 from aml5600/andrew/cov-handle-connections
handle connections in change_independent_variable
2 parents fafb47b + 05ebbdc commit 36abc8b

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

src/systems/diffeqs/basic_transformations.jl

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,22 @@ function change_independent_variable(
178178
return ex::T
179179
end
180180

181+
# overload to specifically handle equations, which can be an equation or a connection
182+
function transform(eq::Equation, systems_map)
183+
if eq.rhs isa Connection
184+
eq = connect((systems_map[nameof(s)] for s in eq.rhs.systems)...)
185+
else
186+
eq = transform(eq)
187+
end
188+
return eq::Equation
189+
end
190+
181191
# Use the utility function to transform everything in the system!
182192
function transform(sys::AbstractODESystem)
183-
eqs = map(transform, get_eqs(sys))
193+
systems = map(transform, get_systems(sys)) # recurse through subsystems
194+
# transform equations and connections
195+
systems_map = Dict(get_name(s) => s for s in systems)
196+
eqs = map(eq -> transform(eq, systems_map)::Equation, get_eqs(sys))
184197
unknowns = map(transform, get_unknowns(sys))
185198
unknowns = filter(var -> !isequal(var, iv2), unknowns) # remove e.g. u
186199
ps = map(transform, get_ps(sys))
@@ -191,19 +204,19 @@ function change_independent_variable(
191204
defaults = Dict(transform(var) => transform(val)
192205
for (var, val) in get_defaults(sys))
193206
guesses = Dict(transform(var) => transform(val) for (var, val) in get_guesses(sys))
207+
connector_type = get_connector_type(sys)
194208
assertions = Dict(transform(ass) => msg for (ass, msg) in get_assertions(sys))
195-
systems = get_systems(sys) # save before reconstructing system
196209
wascomplete = iscomplete(sys) # save before reconstructing system
197210
sys = typeof(sys)( # recreate system with transformed fields
198211
eqs, iv2, unknowns, ps; observed, initialization_eqs,
199-
parameter_dependencies, defaults, guesses,
212+
parameter_dependencies, defaults, guesses, connector_type,
200213
assertions, name = nameof(sys), description = description(sys)
201214
)
202-
systems = map(transform, systems) # recurse through subsystems
203215
sys = compose(sys, systems) # rebuild hierarchical system
204216
if wascomplete
205217
wasflat = isempty(systems)
206-
sys = complete(sys; flatten = wasflat) # complete output if input was complete
218+
wassplit = is_split(sys)
219+
sys = complete(sys; split = wassplit, flatten = wasflat) # complete output if input was complete
207220
end
208221
return sys
209222
end

test/basic_transformations.jl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using ModelingToolkit, OrdinaryDiffEq, DataInterpolations, DynamicQuantities, Test
2+
using ModelingToolkitStandardLibrary.Blocks: RealInput, RealOutput
23

34
@independent_variables t
45
D = Differential(t)
@@ -259,3 +260,30 @@ end
259260
nested_input_sys = complete(nested_input_sys; flatten = false)
260261
@test change_independent_variable(nested_input_sys, nested_input_sys.x) isa ODESystem
261262
end
263+
264+
@testset "Change of variables, connections" begin
265+
@mtkmodel ConnectSys begin
266+
@components begin
267+
in = RealInput()
268+
out = RealOutput()
269+
end
270+
@variables begin
271+
x(t)
272+
y(t)
273+
end
274+
@equations begin
275+
connect(in, out)
276+
in.u ~ x
277+
D(x) ~ -out.u
278+
D(y) ~ 1
279+
end
280+
end
281+
@named sys = ConnectSys()
282+
sys = complete(sys; flatten = false)
283+
new_sys = change_independent_variable(sys, sys.y; add_old_diff = true)
284+
ss = structural_simplify(new_sys; allow_symbolic = true)
285+
prob = ODEProblem(ss, [ss.t => 0.0, ss.x => 1.0], (0.0, 1.0))
286+
sol = solve(prob, Tsit5(); reltol = 1e-5)
287+
@test all(isapprox.(sol[ss.t], sol[ss.y]; atol = 1e-10))
288+
@test all(sol[ss.x][2:end] .< sol[ss.x][1])
289+
end

0 commit comments

Comments
 (0)