Skip to content

Commit 8f8cf61

Browse files
author
Karl Wessel
committed
fix first ODE perturbation example
1 parent 2497d9b commit 8f8cf61

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

docs/src/examples/perturbation.md

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,27 @@
22

33
## Prelims
44

5-
In the previous tutorial, [Mixed Symbolic-Numeric Perturbation Theory](https://symbolics.juliasymbolics.org/stable/examples/perturbation/), we discussed how to solve algebraic equations using **Symbolics.jl**. Here, our goal is to extend the method to differential equations. First, we import the following helper functions that were introduced in [Mixed Symbolic/Numerical Methods for Perturbation Theory - Algebraic Equations](@ref perturb_alg):
5+
In the previous tutorial, [Mixed Symbolic-Numeric Perturbation Theory](https://symbolics.juliasymbolics.org/stable/examples/perturbation/), we discussed how to solve algebraic equations using **Symbolics.jl**. Here, our goal is to extend the method to differential equations. First, we import the following helper functions that were introduced in [Mixed Symbolic/Numerical Methods for Perturbation Theory - Algebraic Equations](https://symbolics.juliasymbolics.org/stable/examples/perturbation/):
66

77
```julia
88
using Symbolics, SymbolicUtils
99

10-
def_taylor(x, ps) = sum([a * x^i for (i, a) in enumerate(ps)])
11-
def_taylor(x, ps, p₀) = p₀ + def_taylor(x, ps)
10+
def_taylor(x, ps) = sum([a * x^(i - 1) for (i, a) in enumerate(ps)])
1211

1312
function collect_powers(eq, x, ns; max_power = 100)
1413
eq = substitute(expand(eq), Dict(x^j => 0 for j in (last(ns) + 1):max_power))
1514

1615
eqs = []
1716
for i in ns
1817
powers = Dict(x^j => (i == j ? 1 : 0) for j in 1:last(ns))
19-
push!(eqs, substitute(eq, powers))
18+
e = substitute(eq, powers)
19+
20+
# manually remove zeroth order from higher orders
21+
if 0 in ns && i != 0
22+
e = e - eqs[1]
23+
end
24+
25+
push!(eqs, e)
2026
end
2127
eqs
2228
end
@@ -46,20 +52,21 @@ with the initial conditions $x(0) = 0$, and $\dot{x}(0) = 1$. Note that for $\ep
4652

4753
```julia
4854
using ModelingToolkit: t_nounits as t, D_nounits as D
49-
n = 3
50-
@variables ϵ y[1:n](t) ∂∂y[1:n](t)
55+
order = 2
56+
n = order + 1
57+
@variables ϵ (y(t))[1:n] (∂∂y(t))[1:n]
5158
```
5259

5360
Next, we define $x$.
5461

5562
```julia
56-
x = def_taylor(ϵ, y[3:end], y[2])
63+
x = def_taylor(ϵ, y)
5764
```
5865

5966
We need the second derivative of `x`. It may seem that we can do this using `Differential(t)`; however, this operation needs to wait for a few steps because we need to manipulate the differentials as separate variables. Instead, we define dummy variables `∂∂y` as the placeholder for the second derivatives and define
6067

6168
```julia
62-
∂∂x = def_taylor(ϵ, ∂∂y[3:end], ∂∂y[2])
69+
∂∂x = def_taylor(ϵ, ∂∂y)
6370
```
6471

6572
as the second derivative of `x`. After rearrangement, our governing equation is $\ddot{x}(t)(1 + \epsilon x(t))^{-2} + 1 = 0$, or
@@ -71,7 +78,7 @@ eq = ∂∂x * (1 + ϵ * x)^2 + 1
7178
The next two steps are the same as the ones for algebraic equations (note that we pass `1:n` to `collect_powers` because the zeroth order term is needed here)
7279

7380
```julia
74-
eqs = collect_powers(eq, ϵ, 1:n)
81+
eqs = collect_powers(eq, ϵ, 0:order)
7582
```
7683

7784
and,
@@ -99,8 +106,8 @@ unknowns(sys)
99106
```julia
100107
# the initial conditions
101108
# everything is zero except the initial velocity
102-
u0 = zeros(2n + 2)
103-
u0[3] = 1.0 # y₀ˍt
109+
u0 = zeros(2order + 2)
110+
u0[2] = 1.0 # yˍt₁
104111

105112
prob = ODEProblem(sys, u0, (0, 3.0))
106113
sol = solve(prob; dtmax = 0.01)
@@ -109,7 +116,7 @@ sol = solve(prob; dtmax = 0.01)
109116
Finally, we calculate the solution to the problem as a function of `ϵ` by substituting the solution to the ODE system back into the defining equation for `x`. Note that `𝜀` is a number, compared to `ϵ`, which is a symbolic variable.
110117

111118
```julia
112-
X = 𝜀 -> sum([𝜀^(i - 1) * sol[y[i]] for i in eachindex(y)])
119+
X = 𝜀 -> sum([𝜀^(i - 1) * sol[yi] for (i, yi) in enumerate(y)])
113120
```
114121

115122
Using `X`, we can plot the trajectory for a range of $𝜀$s.

0 commit comments

Comments
 (0)