Skip to content

Commit 6cc8a0c

Browse files
fix: handle derivatives of time-dependent parameters
1 parent f2d00b0 commit 6cc8a0c

File tree

4 files changed

+40
-2
lines changed

4 files changed

+40
-2
lines changed

src/structural_transformation/pantelides.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ function pantelides_reassemble(state::TearingState, var_eq_matching)
5454
D(eq.lhs)
5555
end
5656
rhs = ModelingToolkit.expand_derivatives(D(eq.rhs))
57+
rhs = fast_substitute(rhs, state.param_derivative_map)
5758
substitution_dict = Dict(x.lhs => x.rhs
5859
for x in out_eqs if x !== nothing && x.lhs isa Symbolic)
5960
sub_rhs = substitute(rhs, substitution_dict)

src/structural_transformation/symbolics_tearing.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ function eq_derivative!(ts::TearingState{ODESystem}, ieq::Int; kwargs...)
6565

6666
sys = ts.sys
6767
eq = equations(ts)[ieq]
68-
eq = 0 ~ ModelingToolkit.derivative(eq.rhs - eq.lhs, get_iv(sys))
68+
eq = 0 ~ fast_substitute(
69+
ModelingToolkit.derivative(eq.rhs - eq.lhs, get_iv(sys)), ts.param_derivative_map)
6970
push!(equations(ts), eq)
7071
# Analyze the new equation and update the graph/solvable_graph
7172
# First, copy the previous incidence and add the derivative terms.

src/systems/systemstructure.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ mutable struct TearingState{T <: AbstractSystem} <: AbstractTearingState{T}
207207
fullvars::Vector
208208
structure::SystemStructure
209209
extra_eqs::Vector
210+
param_derivative_map::Dict{BasicSymbolic, Real}
210211
end
211212

212213
TransformationState(sys::AbstractSystem) = TearingState(sys)
@@ -264,6 +265,7 @@ function TearingState(sys; quick_cancel = false, check = true)
264265
var2idx = Dict{Any, Int}()
265266
symbolic_incidence = []
266267
fullvars = []
268+
param_derivative_map = Dict{BasicSymbolic, Real}()
267269
var_counter = Ref(0)
268270
var_types = VariableType[]
269271
addvar! = let fullvars = fullvars, var_counter = var_counter, var_types = var_types
@@ -295,6 +297,10 @@ function TearingState(sys; quick_cancel = false, check = true)
295297
any(isequal(_var), ivs) && continue
296298
if isparameter(_var) ||
297299
(iscall(_var) && isparameter(operation(_var)) || isconstant(_var))
300+
if iv !== nothing && isparameter(_var) && iscall(_var) &&
301+
(args = arguments(_var); length(args)) == 1 && isequal(only(args), iv)
302+
param_derivative_map[Differential(iv)(_var)] = 0.0
303+
end
298304
continue
299305
end
300306
v = scalarize(v)
@@ -439,7 +445,7 @@ function TearingState(sys; quick_cancel = false, check = true)
439445
ts = TearingState(sys, fullvars,
440446
SystemStructure(complete(var_to_diff), complete(eq_to_diff),
441447
complete(graph), nothing, var_types, sys isa AbstractDiscreteSystem),
442-
Any[])
448+
Any[], param_derivative_map)
443449
if sys isa DiscreteSystem
444450
ts = shift_discrete_system(ts)
445451
end

test/structural_transformation/utils.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,3 +282,33 @@ end
282282
@test length(mapping) == 3
283283
end
284284
end
285+
286+
@testset "Issue#3480: Derivatives of time-dependent parameters" begin
287+
@component function FilteredInput(; name, x0 = 0, T = 0.1)
288+
params = @parameters begin
289+
k(t) = x0
290+
T = T
291+
end
292+
vars = @variables begin
293+
x(t) = k
294+
dx(t) = 0
295+
ddx(t)
296+
end
297+
systems = []
298+
eqs = [D(x) ~ dx
299+
D(dx) ~ ddx
300+
dx ~ (k - x) / T]
301+
return ODESystem(eqs, t, vars, params; systems, name)
302+
end
303+
304+
@mtkbuild sys = FilteredInput()
305+
vs = Set()
306+
for eq in equations(sys)
307+
ModelingToolkit.vars!(vs, eq)
308+
end
309+
for eq in observed(sys)
310+
ModelingToolkit.vars!(vs, eq)
311+
end
312+
313+
@test !(D(sys.k) in vs)
314+
end

0 commit comments

Comments
 (0)