diff --git a/lib/ModelingToolkitTearing/src/stateselection_interface.jl b/lib/ModelingToolkitTearing/src/stateselection_interface.jl index 4b1e8ef..e86f8ca 100644 --- a/lib/ModelingToolkitTearing/src/stateselection_interface.jl +++ b/lib/ModelingToolkitTearing/src/stateselection_interface.jl @@ -2,8 +2,14 @@ function StateSelection.var_derivative!(ts::TearingState, v::Int) s = ts.structure var_diff = StateSelection.var_derivative_graph!(s, v) sys = ts.sys - D = Differential(MTKBase.get_iv(sys)) - push!(ts.fullvars, D(ts.fullvars[v])) + iv = MTKBase.get_iv(sys) + # The variables of a discrete system are related by shifts, those of a continuous + # system by differentiation. + if StateSelection.is_only_discrete(s) + push!(ts.fullvars, MTKBase.simplify_shifts(Shift(iv, 1)(ts.fullvars[v]))) + else + push!(ts.fullvars, Differential(iv)(ts.fullvars[v])) + end push!(ts.structure.state_priorities, ts.structure.state_priorities[v]) push!(ts.structure.canonical_ranks, ts.structure.canonical_ranks[v] + 1) push!(ts.structure.var_types, ts.structure.var_types[v]) diff --git a/lib/ModelingToolkitTearing/test/runtests.jl b/lib/ModelingToolkitTearing/test/runtests.jl index 3de3e54..1c5a19c 100644 --- a/lib/ModelingToolkitTearing/test/runtests.jl +++ b/lib/ModelingToolkitTearing/test/runtests.jl @@ -714,3 +714,24 @@ end MTKTearing.scalarize_tearing_state_eqs!(tss[cid]) @test !iszero(Graphs.ne(tss[cid].structure.graph)) end + +@testset "Alias of a variable shifted in a discrete system" begin + # The alias `z ~ y` with `y ~ u(k - 1)` eliminates `u` in favour of `Shift(t, 1)(y)`, + # and the shifted form of the alias target must be built as a shift, not as a + # differential. + k = ShiftIndex(t) + @parameters p = 3.0 + @variables u(t) y(t) z(t) + @named sys = System([u ~ p, y ~ u(k - 1), z ~ y], t) + ss = mtkcompile(sys) + @test length(unknowns(ss)) == 1 + for eq in [equations(ss); observed(ss)] + @test !MTKBase.isdifferential(eq.lhs) + @test !MTKBase.isdifferential(eq.rhs) + end + # `DiscreteProblem` advances the state one tick during construction, so `y` takes + # the value of `u` at the initial tick. + prob = DiscreteProblem(ss, [y => 0.0], (0, 5)) + @test prob[y] == 3.0 + @test prob[z] == 3.0 +end