@@ -237,8 +237,49 @@ function check_diff_graph(var_to_diff, fullvars)
237
237
end
238
238
=#
239
239
240
- function substitute_lower_order! (state:: TearingState )
241
-
240
+
241
+ function substitute_dummy_derivatives! (fullvars, var_to_diff, diff_to_var, var_eq_matching, neweqs)
242
+ # Dummy derivatives may determine that some differential variables are
243
+ # algebraic variables in disguise. The derivative of such variables are
244
+ # called dummy derivatives.
245
+
246
+ # Step 1:
247
+ # Replace derivatives of non-selected unknown variables by dummy derivatives
248
+
249
+ dummy_sub = Dict ()
250
+ for var in 1 : length (fullvars)
251
+ dv = var_to_diff[var]
252
+ dv === nothing && continue
253
+ if var_eq_matching[var] != = SelectedState ()
254
+ dd = fullvars[dv]
255
+ v_t = setio (diff2term_with_unit (unwrap (dd), unwrap (iv)), false , false )
256
+ for eq in 𝑑neighbors (graph, dv)
257
+ dummy_sub[dd] = v_t
258
+ neweqs[eq] = fast_substitute (neweqs[eq], dd => v_t)
259
+ end
260
+ fullvars[dv] = v_t
261
+ # If we have:
262
+ # x -> D(x) -> D(D(x))
263
+ # We need to to transform it to:
264
+ # x x_t -> D(x_t)
265
+ # update the structural information
266
+ dx = dv
267
+ x_t = v_t
268
+ while (ddx = var_to_diff[dx]) != = nothing
269
+ dx_t = D (x_t)
270
+ for eq in 𝑑neighbors (graph, ddx)
271
+ neweqs[eq] = fast_substitute (neweqs[eq], fullvars[ddx] => dx_t)
272
+ end
273
+ fullvars[ddx] = dx_t
274
+ dx = ddx
275
+ x_t = dx_t
276
+ end
277
+ diff_to_var[dv] = nothing
278
+ end
279
+ end
280
+ end
281
+
282
+ function generate_derivative_variables! ()
242
283
end
243
284
244
285
# Documenting the differences to structural simplification for discrete systems:
@@ -281,88 +322,50 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
281
322
end
282
323
end
283
324
284
- neweqs = collect (equations (state))
285
- lower_name = is_only_discrete (state. structure) ? lower_varname_withshift : lower_varname_with_unit
286
-
287
- # Terminology and Definition:
288
- #
289
- # A general DAE is in the form of `F(u'(t), u(t), p, t) == 0`. We can
290
- # characterize variables in `u(t)` into two classes: differential variables
291
- # (denoted `v(t)`) and algebraic variables (denoted `z(t)`). Differential
292
- # variables are marked as `SelectedState` and they are differentiated in the
293
- # DAE system, i.e. `v'(t)` are all the variables in `u'(t)` that actually
294
- # appear in the system. Algebraic variables are variables that are not
295
- # differential variables.
296
- #
297
- # Dummy derivatives may determine that some differential variables are
298
- # algebraic variables in disguise. The derivative of such variables are
299
- # called dummy derivatives.
300
-
301
- # Step 1:
302
- # Replace derivatives of non-selected unknown variables by dummy derivatives
303
-
304
325
if ModelingToolkit. has_iv (state. sys)
305
326
iv = get_iv (state. sys)
306
327
if is_only_discrete (state. structure)
307
328
D = Shift (iv, 1 )
329
+ lower_name = lower_varname_withshift
330
+ idx_to_lowest_shift = Dict {Int, Int} (var => 0 for var in 1 : length (fullvars))
331
+ for (i,var) in enumerate (fullvars)
332
+ key = (operation (var) isa Shift) ? only (arguments (var)) : var
333
+ idx_to_lowest_shift[i] = get (lowest_shift, key, 0 )
334
+ end
308
335
else
309
336
D = Differential (iv)
337
+ lower_name = lower_varname_with_unit
310
338
end
311
339
else
312
340
iv = D = nothing
341
+ lower_name = lower_varname_with_unit
313
342
end
343
+
314
344
diff_to_var = invview (var_to_diff)
345
+ neweqs = collect (equations (state))
315
346
316
- dummy_sub = Dict ()
317
- for var in 1 : length (fullvars)
318
- dv = var_to_diff[var]
319
- dv === nothing && continue
320
- if var_eq_matching[var] != = SelectedState ()
321
- dd = fullvars[dv]
322
- v_t = setio (diff2term_with_unit (unwrap (dd), unwrap (iv)), false , false )
323
- for eq in 𝑑neighbors (graph, dv)
324
- dummy_sub[dd] = v_t
325
- neweqs[eq] = fast_substitute (neweqs[eq], dd => v_t)
326
- end
327
- fullvars[dv] = v_t
328
- # If we have:
329
- # x -> D(x) -> D(D(x))
330
- # We need to to transform it to:
331
- # x x_t -> D(x_t)
332
- # update the structural information
333
- dx = dv
334
- x_t = v_t
335
- while (ddx = var_to_diff[dx]) != = nothing
336
- dx_t = D (x_t)
337
- for eq in 𝑑neighbors (graph, ddx)
338
- neweqs[eq] = fast_substitute (neweqs[eq], fullvars[ddx] => dx_t)
339
- end
340
- fullvars[ddx] = dx_t
341
- dx = ddx
342
- x_t = dx_t
343
- end
344
- diff_to_var[dv] = nothing
345
- end
346
- end
347
+ # Terminology and Definition:
348
+ #
349
+ # A general DAE is in the form of `F(u'(t), u(t), p, t) == 0`. We can
350
+ # characterize variables in `u(t)` into two classes: differential variables
351
+ # (denoted `v(t)`) and algebraic variables (denoted `z(t)`). Differential
352
+ # variables are marked as `SelectedState` and they are differentiated in the
353
+ # DAE system, i.e. `v'(t)` are all the variables in `u'(t)` that actually
354
+ # appear in the system. Algebraic variables are variables that are not
355
+ # differential variables.
347
356
357
+ substitute_dummy_derivatives! (fullvars, var_to_diff, diff_to_var, var_eq_matching, neweqs)
358
+
348
359
# `SelectedState` information is no longer needed past here. State selection
349
360
# is done. All non-differentiated variables are algebraic variables, and all
350
361
# variables that appear differentiated are differential variables.
351
362
352
- # ## extract partition information
363
+ # ## Extract partition information
353
364
is_solvable = let solvable_graph = solvable_graph
354
365
(eq, iv) -> eq isa Int && iv isa Int && BipartiteEdge (eq, iv) in solvable_graph
355
366
end
356
367
357
- if is_only_discrete (state. structure)
358
- idx_to_lowest_shift = Dict {Int, Int} (var => 0 for var in 1 : length (fullvars))
359
- for (i,var) in enumerate (fullvars)
360
- key = (operation (var) isa Shift) ? only (arguments (var)) : var
361
- idx_to_lowest_shift[i] = get (lowest_shift, key, 0 )
362
- end
363
- end
364
-
365
- # if var is like D(x)
368
+ # if var is like D(x) or Shift(t, 1)(x)
366
369
isdervar = let diff_to_var = diff_to_var
367
370
var -> diff_to_var[var] != = nothing
368
371
end
0 commit comments