Skip to content

Commit d45c53e

Browse files
committed
Add and test errors when changing independent variable
1 parent 22ac438 commit d45c53e

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

src/systems/diffeqs/basic_transformations.jl

+19-3
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,22 @@ 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+
end
59+
60+
iv = unwrap(iv)
5461
iv1 = get_iv(sys) # e.g. t
55-
iv2name = nameof(operation(unwrap(iv))) # TODO: handle namespacing?
62+
63+
if !iscall(iv) || !isequal(only(arguments(iv)), iv1)
64+
error("New independent variable $iv is not a function of the independent variable $iv1 of the system $(nameof(sys))")
65+
end
66+
67+
iv2func = iv # e.g. a(t)
68+
iv2name = nameof(operation(iv))
5669
iv2, = @independent_variables $iv2name # e.g. a
57-
iv2func, = @variables $iv2name(iv1) # e.g. a(t)
5870
D1 = Differential(iv1)
5971
D2 = Differential(iv2)
6072

@@ -98,8 +110,12 @@ function change_independent_variable(sys::AbstractODESystem, iv, eq = nothing; v
98110
end
99111
end
100112

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

104120
# 3) Add equations for dummy variables
105121
div1_div2 = 1 / div2_div1

test/basic_transformations.jl

+14
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,17 @@ 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 = ODESystem([D(x) ~ t], t; name = :M) |> complete
115+
end

0 commit comments

Comments
 (0)