Skip to content

Commit 3600b0d

Browse files
committed
Change independent variable of 2nd-order systems
1 parent acec3cb commit 3600b0d

File tree

2 files changed

+10
-9
lines changed

2 files changed

+10
-9
lines changed

src/systems/diffeqs/basic_transformations.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ function liouville_transform(sys::AbstractODESystem)
5757
end
5858

5959
# TODO: handle case when new iv is a variable already in the system
60-
function change_independent_variable(sys::AbstractODESystem, iv, iv1_of_iv2; kwargs...)
60+
function change_independent_variable(sys::AbstractODESystem, iv, iv1_of_iv2, iv2_of_iv1; kwargs...)
6161
iv1 = ModelingToolkit.get_iv(sys) # old independent variable
6262
iv2 = iv # new independent variable
6363

@@ -76,10 +76,10 @@ function change_independent_variable(sys::AbstractODESystem, iv, iv1_of_iv2; kwa
7676
end
7777
end
7878
eq = expand_derivatives(eq) # expand out with chain rule to get d(iv2)/d(iv1)
79-
div1_div2 = Differential(iv2)(iv1_of_iv2) |> expand_derivatives
80-
div2_div1 = 1 / div1_div2
81-
eq = substitute(eq, Differential(iv1)(iv2func) => div2_div1) # substitute in d(iv1)/d(iv2)
79+
eq = substitute(eq, Differential(iv1)(iv2func) => Differential(iv1)(iv2_of_iv1)) # substitute in d(iv2)/d(iv1)
80+
eq = expand_derivatives(eq)
8281
eq = substitute(eq, iv2func => iv2) # make iv2 independent
82+
eq = substitute(eq, iv1 => iv1_of_iv2) # substitute any remaining old ivars
8383
eqs[i] = eq
8484
end
8585

test/basic_transformations.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,22 @@ sol = solve(prob, Tsit5())
3939
@variables x(t) y(t) z(t)
4040
eqs = [
4141
D(x) ~ y
42-
D(y) ~ 2*D(x)
42+
D(D(y)) ~ 2 * x * D(y)
4343
z ~ x + D(y)
4444
]
4545
@named sys1 = ODESystem(eqs, t)
4646

4747
@independent_variables s
48-
@named sys2 = ModelingToolkit.change_independent_variable(sys1, s, s^2)
48+
@named sys2 = ModelingToolkit.change_independent_variable(sys1, s, s^2, (t))
4949

5050
sys1 = structural_simplify(sys1)
5151
sys2 = structural_simplify(sys2)
52-
prob1 = ODEProblem(sys1, unknowns(sys1) .=> 1.0, (0.0, 1.0))
53-
prob2 = ODEProblem(sys2, unknowns(sys2) .=> 1.0, (0.0, 1.0))
52+
prob1 = ODEProblem(sys1, [sys1.x => 1.0, sys1.y => 1.0, Differential(t)(sys1.y) => 0.0], (1.0, 4.0))
53+
prob2 = ODEProblem(sys2, [sys2.x => 1.0, sys2.y => 1.0, Differential(s)(sys2.y) => 0.0], (1.0, 2.0))
5454
sol1 = solve(prob1, Tsit5(); reltol = 1e-10, abstol = 1e-10)
5555
sol2 = solve(prob2, Tsit5(); reltol = 1e-10, abstol = 1e-10)
5656
ts = range(0.0, 1.0, length = 50)
5757
ss = .√(ts)
58-
@test isapprox(sol1(ts), sol2(ss); atol = 1e-8)
58+
@test all(isapprox.(sol1(ts, idxs=sys1.x), sol2(ss, idxs=sys2.x); atol = 1e-7)) &&
59+
all(isapprox.(sol1(ts, idxs=sys1.y), sol2(ss, idxs=sys2.y); atol = 1e-7))
5960
end

0 commit comments

Comments
 (0)