Skip to content

Commit ae9c174

Browse files
committed
Add and test errors when changing independent variable
1 parent dfc5269 commit ae9c174

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

src/systems/diffeqs/basic_transformations.jl

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,24 @@ function liouville_transform(sys::AbstractODESystem; kwargs...)
5151
end
5252

5353
function change_independent_variable(sys::AbstractODESystem, iv, eq = nothing; verbose = false, simplify = true, dummies = false, kwargs...)
54+
if !iscomplete(sys)
55+
error("Cannot change independent variable of incomplete system $(nameof(sys))")
56+
elseif isscheduled(sys)
57+
error("Cannot change independent variable of structurally simplified system $(nameof(sys))")
58+
elseif !isempty(get_systems(sys))
59+
error("Cannot change independent variable of hierarchical system $(nameof(sys)). Flatten it first.") # TODO: implement
60+
end
61+
62+
iv = unwrap(iv)
5463
iv1 = get_iv(sys) # e.g. t
55-
iv2name = nameof(operation(unwrap(iv))) # TODO: handle namespacing?
64+
65+
if !iscall(iv) || !isequal(only(arguments(iv)), iv1)
66+
error("New independent variable $iv is not a function of the independent variable $iv1 of the system $(nameof(sys))")
67+
end
68+
69+
iv2func = iv # e.g. a(t)
70+
iv2name = nameof(operation(iv))
5671
iv2, = @independent_variables $iv2name # e.g. a
57-
iv2func, = @variables $iv2name(iv1) # e.g. a(t)
5872
D1 = Differential(iv1)
5973
D2 = Differential(iv2)
6074

@@ -98,8 +112,12 @@ function change_independent_variable(sys::AbstractODESystem, iv, eq = nothing; v
98112
end
99113
end
100114

101-
isnothing(div2_div1) && error("No equation for $D1($iv2func) was specified.")
102115
verbose && println("Found $div2 = $div2_div1")
116+
if isnothing(div2_div1)
117+
error("No equation for $D1($iv2func) was specified.")
118+
elseif isequal(div2_div1, 0)
119+
error("Cannot change independent variable from $iv1 to $iv2 with singular transformation $(div2 ~ div2_div1).")
120+
end
103121

104122
# 3) Add equations for dummy variables
105123
div1_div2 = 1 / div2_div1

test/basic_transformations.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,18 @@ end
9999
sol = solve(prob, Tsit5(); reltol = 1e-5)
100100
@test all(isapprox.(sol[Mx.y], sol[Mx.x - g*(Mx.x/v)^2/2]; atol = 1e-10)) # compare to analytical solution (x(t) = v*t, y(t) = v*t - g*t^2/2)
101101
end
102+
103+
@testset "Change independent variable (errors)" begin
104+
@variables x(t) y z(y) w(t) v(t)
105+
M = ODESystem([D(x) ~ 0, v ~ x], t; name = :M)
106+
@test_throws "incomplete" ModelingToolkit.change_independent_variable(M, M.x)
107+
M = complete(M)
108+
@test_throws "singular" ModelingToolkit.change_independent_variable(M, M.x)
109+
@test_throws "structurally simplified" ModelingToolkit.change_independent_variable(structural_simplify(M), y)
110+
@test_throws "No equation" ModelingToolkit.change_independent_variable(M, w)
111+
@test_throws "No equation" ModelingToolkit.change_independent_variable(M, v)
112+
@test_throws "not a function of the independent variable" ModelingToolkit.change_independent_variable(M, y)
113+
@test_throws "not a function of the independent variable" ModelingToolkit.change_independent_variable(M, z)
114+
M = compose(M, M)
115+
@test_throws "hierarchical" ModelingToolkit.change_independent_variable(M, M.x)
116+
end

0 commit comments

Comments
 (0)