@@ -53,6 +53,17 @@ function liouville_transform(sys::AbstractODESystem; kwargs...)
53
53
)
54
54
end
55
55
56
+ function split_eqs_connections (eqs_in:: Vector{<:Equation} )
57
+ eqs = Equation[]
58
+ cons = Equation[]
59
+
60
+ for eq in eqs_in
61
+ eq. lhs isa Connection ? push! (cons, eq) : push! (eqs, eq)
62
+ end
63
+
64
+ return eqs, cons
65
+ end
66
+
56
67
"""
57
68
change_independent_variable(
58
69
sys::AbstractODESystem, iv, eqs = [];
@@ -158,7 +169,7 @@ function change_independent_variable(
158
169
function transform (ex:: T ) where {T}
159
170
# 1) Replace the argument of every function; e.g. f(t) -> f(u(t))
160
171
for var in vars (ex; op = Nothing) # loop over all variables in expression (op = Nothing prevents interpreting "D(f(t))" as one big variable)
161
- is_function_of_iv1 = iscall (var) && isequal (only (arguments (var)), iv1) # of the form f(t)?
172
+ is_function_of_iv1 = iscall (var) && isequal (first (arguments (var)), iv1) # of the form f(t)?
162
173
if is_function_of_iv1 && ! isequal (var, iv2_of_iv1) # prevent e.g. u(t) -> u(u(t))
163
174
var_of_iv1 = var # e.g. f(t)
164
175
var_of_iv2_of_iv1 = substitute (var_of_iv1, iv1 => iv2_of_iv1) # e.g. f(u(t))
@@ -178,9 +189,22 @@ function change_independent_variable(
178
189
return ex:: T
179
190
end
180
191
192
+ # overload to specifically handle equations, which can be an equation of a connection
193
+ function transform (eq:: Equation , systems_map)
194
+ if eq. rhs isa Connection
195
+ eq = connect ((systems_map[nameof (s)] for s in eq. rhs. systems). .. )
196
+ else
197
+ eq = transform (eq)
198
+ end
199
+ return eq:: Equation
200
+ end
201
+
181
202
# Use the utility function to transform everything in the system!
182
203
function transform (sys:: AbstractODESystem )
183
- eqs = map (transform, get_eqs (sys))
204
+ systems = map (transform, get_systems (sys)) # recurse through subsystems
205
+ # transform equations and connections
206
+ systems_map = Dict (get_name (s) => s for s in systems)
207
+ eqs = map (eq -> transform (eq, systems_map):: Equation , get_eqs (sys))
184
208
unknowns = map (transform, get_unknowns (sys))
185
209
unknowns = filter (var -> ! isequal (var, iv2), unknowns) # remove e.g. u
186
210
ps = map (transform, get_ps (sys))
@@ -191,19 +215,19 @@ function change_independent_variable(
191
215
defaults = Dict (transform (var) => transform (val)
192
216
for (var, val) in get_defaults (sys))
193
217
guesses = Dict (transform (var) => transform (val) for (var, val) in get_guesses (sys))
218
+ connector_type = get_connector_type (sys)
194
219
assertions = Dict (transform (ass) => msg for (ass, msg) in get_assertions (sys))
195
- systems = get_systems (sys) # save before reconstructing system
196
220
wascomplete = iscomplete (sys) # save before reconstructing system
197
221
sys = typeof (sys)( # recreate system with transformed fields
198
222
eqs, iv2, unknowns, ps; observed, initialization_eqs,
199
- parameter_dependencies, defaults, guesses,
223
+ parameter_dependencies, defaults, guesses, connector_type,
200
224
assertions, name = nameof (sys), description = description (sys)
201
225
)
202
- systems = map (transform, systems) # recurse through subsystems
203
226
sys = compose (sys, systems) # rebuild hierarchical system
204
227
if wascomplete
205
228
wasflat = isempty (systems)
206
- sys = complete (sys; flatten = wasflat) # complete output if input was complete
229
+ wassplit = is_split (sys)
230
+ sys = complete (sys; split = wassplit, flatten = wasflat) # complete output if input was complete
207
231
end
208
232
return sys
209
233
end
0 commit comments