Skip to content

Commit 1656277

Browse files
committed
maadd comments
1 parent 26a545d commit 1656277

File tree

3 files changed

+52
-22
lines changed

3 files changed

+52
-22
lines changed

src/structural_transformation/symbolics_tearing.jl

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,32 @@ function substitute_lower_order!(state::TearingState)
241241

242242
end
243243

244+
# Documenting the differences to structural simplification for discrete systems:
245+
# In discrete systems the lowest-order term is x_k-i, instead of x(t). In order
246+
# to substitute dummy variables for x_k-1, x_k-2, ... instead you need to reverse
247+
# the order. So for discrete systems `var_order` is defined a little differently.
248+
#
249+
# The orders will also be off by one. The reason this is is that the dynamics of
250+
# the system should be given in terms of Shift(t, 1)(x(t), x(t-1), ...). But
251+
# having the observables be indexed by the next time step is not so nice. So we
252+
# handle the shifts in the renaming, rather than explicitly.
253+
#
254+
# The substitution should look like the following:
255+
# x(t) -> Shift(t, 1)(x(t))
256+
# x(k-1) -> x(t)
257+
# x(k-2) -> x_{t-1}(t)
258+
# x(k-3) -> x_{t-2}(t)
259+
# and so on...
260+
#
261+
# In the implicit discrete case this shouldn't happen. The simplification should
262+
# look like a NonlinearSystem.
263+
#
264+
# For discrete systems Shift(t, 2)(x(t)) is not equivalent to Shift(t, 1)(Shift(t,1)(x(t))
265+
# This is different from the continuous case where D(D(x)) can be substituted for
266+
# by iteratively substituting x_t ~ D(x), then x_tt ~ D(x_t). For this reason the
267+
# total_sub dict is updated at the time that the renamed variables are written,
268+
# inside the loop where new variables are generated.
269+
244270
import ModelingToolkit: Shift
245271
function tearing_reassemble(state::TearingState, var_eq_matching,
246272
full_var_eq_matching = nothing; simplify = false, mm = nothing, cse_hack = true, array_hack = true)
@@ -318,9 +344,6 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
318344
diff_to_var[dv] = nothing
319345
end
320346
end
321-
@show var_eq_matching
322-
323-
println("Post state selection.")
324347

325348
# `SelectedState` information is no longer needed past here. State selection
326349
# is done. All non-differentiated variables are algebraic variables, and all
@@ -330,26 +353,27 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
330353
is_solvable = let solvable_graph = solvable_graph
331354
(eq, iv) -> eq isa Int && iv isa Int && BipartiteEdge(eq, iv) in solvable_graph
332355
end
333-
idx_to_lowest_shift = Dict{Int, Int}(var => 0 for var in 1:length(fullvars))
334-
for (i,var) in enumerate(fullvars)
335-
key = (operation(var) isa Shift) ? only(arguments(var)) : var
336-
idx_to_lowest_shift[i] = get(lowest_shift, key, 0)
356+
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
337363
end
338364

339365
# if var is like D(x)
340366
isdervar = let diff_to_var = diff_to_var
341367
var -> diff_to_var[var] !== nothing
342368
end
343-
# For discrete variables, we want the substitution to turn
344-
# Shift(t, k)(x(t)) => x_t-k(t)
345369
var_order = let diff_to_var = diff_to_var
346370
dv -> begin
347371
order = 0
348372
while (dv′ = diff_to_var[dv]) !== nothing
349373
order += 1
350374
dv = dv′
351375
end
352-
is_only_discrete(state.structure) && (order = -idx_to_lowest_shift[dv] - order - 1)
376+
is_only_discrete(state.structure) && (order = -idx_to_lowest_shift[dv] - order)
353377
order, dv
354378
end
355379
end
@@ -403,6 +427,7 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
403427
linear_eqs = mm === nothing ? Dict{Int, Int}() :
404428
Dict(reverse(en) for en in enumerate(mm.nzrows))
405429

430+
total_sub = Dict()
406431
for v in 1:length(var_to_diff)
407432
is_highest_discrete = begin
408433
var = fullvars[v]
@@ -442,8 +467,13 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
442467
end
443468
dx = fullvars[dv]
444469
# add `x_t`
445-
order, lv = var_order(dv)
470+
println()
471+
@show order, lv = var_order(dv)
446472
x_t = lower_name(fullvars[lv], iv, order)
473+
@show fullvars[v]
474+
@show fullvars[dv]
475+
@show fullvars[lv]
476+
@show dx, x_t
447477
push!(fullvars, simplify_shifts(x_t))
448478
v_t = length(fullvars)
449479
v_t_idx = add_vertex!(var_to_diff)
@@ -466,11 +496,16 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
466496
add_edge!(solvable_graph, dummy_eq, dv)
467497
@assert nsrcs(graph) == nsrcs(solvable_graph) == dummy_eq
468498
@label FOUND_DUMMY_EQ
469-
is_only_discrete(state.structure) && (idx_to_lowest_shift[v_t] = idx_to_lowest_shift[dv])
499+
is_only_discrete(state.structure) && begin
500+
idx_to_lowest_shift[v_t] = idx_to_lowest_shift[dv]
501+
operation(dx) isa Shift && (total_sub[dx] = x_t)
502+
order == 1 && (total_sub[x_t] = fullvars[var_to_diff[dv]])
503+
end
470504
var_to_diff[v_t] = var_to_diff[dv]
471505
var_eq_matching[dv] = unassigned
472506
eq_var_matching[dummy_eq] = dv
473507
end
508+
@show total_sub
474509

475510
# Will reorder equations and unknowns to be:
476511
# [diffeqs; ...]
@@ -490,15 +525,13 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
490525
# Solve solvable equations
491526
println()
492527
println("SOLVING SOLVABLE EQUATIONS.")
493-
@show eq_var_matching
494528
toporder = topological_sort(DiCMOBiGraph{false}(graph, var_eq_matching))
495529
eqs = Iterators.reverse(toporder)
496-
@show eqs
497-
@show neweqs
498-
@show fullvars
499-
total_sub = Dict()
500530
idep = iv
531+
@show eq_var_matching
532+
501533
for ieq in eqs
534+
println()
502535
iv = eq_var_matching[ieq]
503536
if is_solvable(ieq, iv)
504537
# We don't solve differential equations, but we will need to try to
@@ -513,7 +546,6 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
513546
dx = D(simplify_shifts(lower_name(
514547
fullvars[lv], idep, order - 1)))
515548
@show dx
516-
@show neweqs[ieq]
517549
eq = dx ~ simplify_shifts(Symbolics.fixpoint_sub(
518550
Symbolics.symbolic_linear_solve(neweqs[ieq],
519551
fullvars[iv]),

src/structural_transformation/utils.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,8 @@ end
451451

452452
function lower_varname_withshift(var, iv, order)
453453
order == 0 && return var
454-
ds = "$iv-$order"
454+
#order == -1 && return Shift(iv, 1)(var)
455+
ds = "$iv-$(order-1)"
455456
d_separator = 'ˍ'
456457

457458
if ModelingToolkit.isoperator(var, ModelingToolkit.Shift)

src/systems/systemstructure.jl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,9 +476,6 @@ function shift_discrete_system(ts::TearingState, lowest_shift)
476476
vars!(discvars, eq; op = Union{Sample, Hold})
477477
end
478478
iv = get_iv(sys)
479-
discmap = Dict(k => StructuralTransformations.simplify_shifts(Shift(iv, -get(lowest_shift, k, 0))(k))
480-
for k in discvars
481-
if any(isequal(k), fullvars) && !isa(operation(k), Union{Sample, Hold}))
482479

483480
discmap = Dict(k => StructuralTransformations.simplify_shifts(Shift(iv, 1)(k)) for k in discvars
484481
if any(isequal(k), fullvars) && !isa(operation(k), Union{Sample, Hold}))

0 commit comments

Comments
 (0)