|
50 | 50 |
|
51 | 51 | @testset "Change independent variable (Friedmann equation)" begin
|
52 | 52 | D = Differential(t)
|
53 |
| - @variables a(t) ρr(t) ρm(t) ρΛ(t) ρ(t) P(t) ϕ(t) |
| 53 | + @variables a(t) ȧ(t) ρr(t) ρm(t) ρΛ(t) ρ(t) P(t) ϕ(t) |
54 | 54 | @parameters Ωr0 Ωm0 ΩΛ0
|
55 | 55 | eqs = [
|
56 | 56 | ρr ~ 3/(8*Num(π)) * Ωr0 / a^4
|
57 | 57 | ρm ~ 3/(8*Num(π)) * Ωm0 / a^3
|
58 | 58 | ρΛ ~ 3/(8*Num(π)) * ΩΛ0
|
59 | 59 | ρ ~ ρr + ρm + ρΛ
|
60 |
| - D(a) ~ √(8*Num(π)/3*ρ*a^4) |
| 60 | + ȧ ~ √(8*Num(π)/3*ρ*a^4) |
| 61 | + D(a) ~ ȧ |
61 | 62 | D(D(ϕ)) ~ -3*D(a)/a*D(ϕ)
|
62 | 63 | ]
|
63 |
| - @named M1 = ODESystem(eqs, t) |
64 |
| - M1 = complete(M1) |
| 64 | + M1 = ODESystem(eqs, t; name = :M) |> complete |
65 | 65 |
|
66 |
| - M2 = ModelingToolkit.change_independent_variable(M1, M1.a) |
| 66 | + # Apply in two steps, where derivatives are defined at each step: first t -> a, then a -> b |
| 67 | + M2 = ModelingToolkit.change_independent_variable(M1, M1.a) |> complete #, D(b) ~ D(a)/a; verbose = true) |
| 68 | + @variables b(M2.a) |
| 69 | + M3 = ModelingToolkit.change_independent_variable(M2, b, Differential(M2.a)(b) ~ exp(-b)) |
67 | 70 | M2 = structural_simplify(M2; allow_symbolic = true)
|
| 71 | + M3 = structural_simplify(M3; allow_symbolic = true) |
68 | 72 | @test length(unknowns(M2)) == 2
|
69 | 73 | end
|
| 74 | + |
| 75 | +@testset "Change independent variable (simple)" begin |
| 76 | + @variables x(t) |
| 77 | + Mt = ODESystem([D(x) ~ 2*x], t; name = :M) |> complete |
| 78 | + Mx = ModelingToolkit.change_independent_variable(Mt, Mt.x) |
| 79 | + @test (@variables x x_t(x) x_tt(x); Set(equations(Mx)) == Set([x_t ~ 2x, x_tt ~ 4x])) |
| 80 | +end |
| 81 | + |
| 82 | +@testset "Change independent variable (free fall)" begin |
| 83 | + @variables x(t) y(t) |
| 84 | + @parameters g v # gravitational acceleration and constant horizontal velocity |
| 85 | + Mt = ODESystem([D(D(y)) ~ -g, D(x) ~ v], t; name = :M) |> complete # gives (x, y) as function of t, ... |
| 86 | + Mx = ModelingToolkit.change_independent_variable(Mt, Mt.x) # ... but we want y as a function of x |
| 87 | + Mx = structural_simplify(Mx; allow_symbolic = true) |
| 88 | + Dx = Differential(Mx.x) |
| 89 | + prob = ODEProblem(Mx, [Mx.y => 0.0, Dx(Mx.y) => 1.0], (0.0, 20.0), [g => 9.81, v => 10.0]) # 1 = dy/dx = (dy/dt)/(dx/dt) means equal initial horizontal and vertical velocities |
| 90 | + sol = solve(prob, Tsit5(); reltol = 1e-5) |
| 91 | + @test all(isapprox.(sol[Mx.y], sol[Mx.x - g*(Mx.x/v)^2/2]; atol = 1e-10)) # eliminate t from anal solution x(t) = v*t, y(t) = v*t - g*t^2/2 |
| 92 | +end |
0 commit comments