@@ -360,9 +360,8 @@ by iteratively substituting x_t ~ D(x), then x_tt ~ D(x_t). For this reason the
360
360
total_sub dict is updated at the time that the renamed variables are written,
361
361
inside the loop where new variables are generated.
362
362
"""
363
- function generate_derivative_variables! (ts:: TearingState , neweqs, total_sub, var_eq_matching, var_order ;
363
+ function generate_derivative_variables! (ts:: TearingState , neweqs, total_sub, var_eq_matching;
364
364
is_discrete = false , mm = nothing )
365
-
366
365
@unpack fullvars, sys, structure = ts
367
366
@unpack solvable_graph, var_to_diff, eq_to_diff, graph, lowest_shift = structure
368
367
eq_var_matching = invview (var_eq_matching)
@@ -386,13 +385,14 @@ function generate_derivative_variables!(ts::TearingState, neweqs, total_sub, var
386
385
387
386
# v is the index of the current variable, x = fullvars[v]
388
387
# dv is the index of the derivative dx = D(x), x_t is the substituted variable
389
- #
390
388
# For ODESystems: lv is the index of the lowest-order variable (x(t))
391
389
# For DiscreteSystems:
392
390
# - lv is the index of the lowest-order variable (Shift(t, k)(x(t)))
393
391
# - uv is the index of the highest-order variable (x(t))
394
392
for v in 1 : length (var_to_diff)
395
393
dv = var_to_diff[v]
394
+ println ()
395
+ @show (v, dv)
396
396
if is_discrete
397
397
x = fullvars[v]
398
398
op = operation (x)
@@ -405,6 +405,9 @@ function generate_derivative_variables!(ts::TearingState, neweqs, total_sub, var
405
405
end
406
406
dv isa Int || continue
407
407
408
+ @show dv
409
+ @show var_eq_matching[dv]
410
+ @show fullvars
408
411
solved = var_eq_matching[dv] isa Int
409
412
solved && continue
410
413
@@ -429,9 +432,10 @@ function generate_derivative_variables!(ts::TearingState, neweqs, total_sub, var
429
432
430
433
dx = fullvars[dv]
431
434
# add `x_t`
432
- order, lv = var_order (dv)
435
+ order, lv = var_order (diff_to_var, dv)
433
436
x_t = is_discrete ? lower_name (fullvars[lv], iv, - low- order- 1 ; unshifted = fullvars[uv]) :
434
437
lower_name (fullvars[lv], iv, order)
438
+ @show dx, x_t
435
439
push! (fullvars, simplify_shifts (x_t))
436
440
v_t = length (fullvars)
437
441
v_t_idx = add_vertex! (var_to_diff)
@@ -443,23 +447,23 @@ function generate_derivative_variables!(ts::TearingState, neweqs, total_sub, var
443
447
@assert v_t_idx == ndsts (graph) == ndsts (solvable_graph) == length (fullvars) ==
444
448
length (var_eq_matching)
445
449
446
- # Add the substitutions to total_sub directly.
450
+ # Add discrete substitutions to total_sub directly.
447
451
is_discrete && begin
448
452
idx_to_lowest_shift[v_t] = idx_to_lowest_shift[dv]
449
- @show dx
450
453
if operation (dx) isa Shift
451
454
total_sub[dx] = x_t
452
455
for e in 𝑑neighbors (graph, dv)
453
456
add_edge! (graph, e, v_t)
454
457
rem_edge! (graph, e, dv)
455
458
end
456
- @show graph
459
+ # Do not add the lowest-order substitution as an equation, just substitute
457
460
! (operation (x) isa Shift) && begin
458
461
var_to_diff[v_t] = var_to_diff[dv]
459
462
continue
460
463
end
461
464
end
462
465
end
466
+
463
467
# add `D(x) - x_t ~ 0`
464
468
push! (neweqs, 0 ~ x_t - dx)
465
469
add_vertex! (graph, SRC)
@@ -489,7 +493,7 @@ such that the mass matrix is:
489
493
490
494
Update the state to account for the new ordering and equations.
491
495
"""
492
- function solve_and_generate_equations! (state:: TearingState , neweqs, total_sub, var_eq_matching, var_order ; simplify = false )
496
+ function solve_and_generate_equations! (state:: TearingState , neweqs, total_sub, var_eq_matching; simplify = false )
493
497
@unpack fullvars, sys, structure = state
494
498
@unpack solvable_graph, var_to_diff, eq_to_diff, graph, lowest_shift = structure
495
499
eq_var_matching = invview (var_eq_matching)
@@ -530,13 +534,11 @@ function solve_and_generate_equations!(state::TearingState, neweqs, total_sub, v
530
534
531
535
toporder = topological_sort (DiCMOBiGraph {false} (graph, var_eq_matching))
532
536
eqs = Iterators. reverse (toporder)
533
- idep = ModelingToolkit. has_iv (sys) ? ModelingToolkit. get_iv (sys) : nothing
534
-
535
- @show eq_var_matching
536
- @show fullvars
537
- @show neweqs
537
+ idep = iv
538
538
539
- # Equation ieq is solved for the RHS of iv
539
+ # Generate differential equations.
540
+ # fullvars[iv] is a differential variable of the form D^n(x), and neweqs[ieq]
541
+ # is solved to give the RHS.
540
542
for ieq in eqs
541
543
iv = eq_var_matching[ieq]
542
544
if is_solvable (ieq, iv)
@@ -546,7 +548,7 @@ function solve_and_generate_equations!(state::TearingState, neweqs, total_sub, v
546
548
if isdervar (iv)
547
549
isnothing (D) &&
548
550
error (" Differential found in a non-differential system. Likely this is a bug in the construction of an initialization system. Please report this issue with a reproducible example. Offending equation: $(equations (sys)[ieq]) " )
549
- order, lv = var_order (iv)
551
+ order, lv = var_order (diff_to_var, iv)
550
552
dx = D (fullvars[lv])
551
553
eq = dx ~ simplify_shifts (Symbolics. fixpoint_sub (
552
554
Symbolics. symbolic_linear_solve (neweqs[ieq],
@@ -634,8 +636,9 @@ function solve_and_generate_equations!(state::TearingState, neweqs, total_sub, v
634
636
d′ = eqsperm[d]
635
637
new_eq_to_diff[v′] = d′ > 0 ? d′ : nothing
636
638
end
639
+ new_fullvars = fullvars[invvarsperm]
637
640
638
- fullvars[invvarsperm] , new_var_to_diff, new_eq_to_diff, neweqs, subeqs, graph
641
+ new_fullvars , new_var_to_diff, new_eq_to_diff, neweqs, subeqs, graph
639
642
end
640
643
641
644
# Terminology and Definition:
649
652
650
653
import ModelingToolkit: Shift
651
654
655
+ # Give the order of the variable indexed by dv
656
+ function var_order (diff_to_var, dv)
657
+ order = 0
658
+ while (dv′ = diff_to_var[dv]) != = nothing
659
+ order += 1
660
+ dv = dv′
661
+ end
662
+ order, dv
663
+ end
664
+
652
665
function tearing_reassemble (state:: TearingState , var_eq_matching,
653
666
full_var_eq_matching = nothing ; simplify = false , mm = nothing , cse_hack = true , array_hack = true )
654
667
@unpack fullvars, sys, structure = state
@@ -667,22 +680,12 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
667
680
dummy_sub = Dict ()
668
681
is_discrete = is_only_discrete (state. structure)
669
682
670
- var_order = let diff_to_var = diff_to_var
671
- dv -> begin
672
- order = 0
673
- while (dv′ = diff_to_var[dv]) != = nothing
674
- order += 1
675
- dv = dv′
676
- end
677
- order, dv
678
- end
679
- end
680
-
681
683
# Structural simplification
682
684
substitute_dummy_derivatives! (state, neweqs, dummy_sub, var_eq_matching)
683
- generate_derivative_variables! (state, neweqs, total_sub, var_eq_matching, var_order ;
685
+ generate_derivative_variables! (state, neweqs, total_sub, var_eq_matching;
684
686
is_discrete, mm)
685
- new_fullvars, new_var_to_diff, new_eq_to_diff, neweqs, subeqs, graph = solve_and_generate_equations! (state, neweqs, total_sub, var_eq_matching, var_order; simplify)
687
+ new_fullvars, new_var_to_diff, new_eq_to_diff, neweqs, subeqs, graph =
688
+ solve_and_generate_equations! (state, neweqs, total_sub, var_eq_matching; simplify)
686
689
687
690
# Update system
688
691
var_to_diff = new_var_to_diff
@@ -698,25 +701,18 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
698
701
i -> (! isempty (𝑑neighbors (graph, i)) ||
699
702
(var_to_diff[i] != = nothing && ! isempty (𝑑neighbors (graph, var_to_diff[i]))))
700
703
end
701
- @show graph
702
- println ()
703
- println (" Shift test..." )
704
- @show neweqs
705
- @show fullvars
704
+ @show ispresent .(collect (1 : length (fullvars)))
706
705
@show 𝑑neighbors (graph, 5 )
706
+ @show var_to_diff[5 ]
707
707
708
+ @show neweqs
709
+ @show fullvars
708
710
sys = state. sys
709
711
obs_sub = dummy_sub
710
712
for eq in neweqs
711
713
isdiffeq (eq) || continue
712
714
obs_sub[eq. lhs] = eq. rhs
713
715
end
714
- is_discrete && for eq in subeqs
715
- obs_sub[eq. rhs] = eq. lhs
716
- end
717
-
718
- @show obs_sub
719
- @show observed (sys)
720
716
# TODO : compute the dependency correctly so that we don't have to do this
721
717
obs = [fast_substitute (observed (sys), obs_sub); subeqs]
722
718
0 commit comments