|
1 |
| -using ContinuumArrays, QuasiArrays, FillArrays, InfiniteArrays |
2 |
| -import QuasiArrays: Inclusion, QuasiDiagonal |
| 1 | +using ClassicalOrthogonalPolynomials, OrdinaryDiffEq, Plots |
3 | 2 |
|
4 |
| -using Plots; pyplot(); |
5 | 3 |
|
6 |
| -S = LinearSpline(range(0,1; length=10)) |
7 |
| -xx = range(0,1; length=1000) |
| 4 | +#### |
| 5 | +# 1D Helmholtz w/ Dirichlet conditions |
| 6 | +# |
| 7 | +# We solve `u'' + 4^2*u = f`, `u(-1) = 1`, `u(1) = 2` with rectangular collocation. That is, |
| 8 | +# we discretise `u` at `n` second kind Chebyshev points (containing ±1) |
| 9 | +# but `f` at `n-2` first kind Chebyshev points (interior to [-1,1]). |
| 10 | +# The reduction in degrees of freedom allows us to impose boundary conditions. |
| 11 | +#### |
8 | 12 |
|
9 |
| -S = Jacobi(true,true) |
| 13 | +T = ChebyshevT() # basis |
| 14 | +n = 100 |
| 15 | +x₁ = reverse(ChebyshevGrid{1}(n-2)) # 1st kind points, sorted |
| 16 | +x₂ = reverse(ChebyshevGrid{2}(n)) # 2nd kind points, sorted |
| 17 | +V = T[x₂,1:n] # Vandermonde matrix, its inverse is transform from values to coefficients |
| 18 | +D₂ = diff(T,2)[x₁,1:n] / V # 2nd derivative from x₂ to x₁ |
| 19 | +R = T[x₁,1:n] / V # discretisation of identity matrix |
10 | 20 |
|
| 21 | +B_l = [1; zeros(n-1)]' # Left Dirichlet conditions |
| 22 | +B_r = [zeros(n-1); 1]' # Right Dirichlet conditions |
11 | 23 |
|
12 |
| -P = Legendre() |
13 |
| -X = QuasiDiagonal(Inclusion(-1..1)) |
| 24 | +u = [B_l; D₂ + 4^2*R; B_r] \ [1; exp.(x₁); 2] |
| 25 | +plot(x₂, u) |
14 | 26 |
|
15 |
| -@test X[-1:0.1:1,-1:0.1:1] == Diagonal(-1:0.1:1) |
| 27 | +#### |
| 28 | +# Heat equation |
| 29 | +# |
| 30 | +# We solve `u_t = u_xx` with rectangular collocation with zero Dirchlet conditions. That is, |
| 31 | +# we discretise `u` at 2nd kind Chebyshev points (containing ±1) |
| 32 | +# but the range of `u_xx` at 1st kind Chebyshev points (interior to [-1,1]). |
| 33 | +#### |
16 | 34 |
|
17 |
| -axes(X) |
18 |
| -J = pinv(P)*X*P |
| 35 | +u₀ = x -> (1-x^2) * exp(x) # initial condition |
19 | 36 |
|
20 |
| -J - I |
21 |
| -Vcat(Hcat(1, Zeros(1,∞)), J) |
| 37 | +function heat!(du, u, D₂, t) |
| 38 | + du[1] = u[1] # left bc |
| 39 | + mul!(@view(du[2:end-1]), D₂, u) |
| 40 | + du[end] = u[end] # right bc |
| 41 | +end |
| 42 | +prob = ODEProblem(ODEFunction(heat!, mass_matrix = [B_l; R; B_r]), u₀.(x₂), (0., 1.), D₂) |
| 43 | +sol = solve(prob, Rodas5(), reltol = 1e-8, abstol = 1e-8) |
| 44 | + |
| 45 | +t = range(0,1,100) |
| 46 | +contourf(t, x₂, hcat(sol.(t)...)) |
| 47 | + |
| 48 | + |
| 49 | +#### |
| 50 | +# Burgers equation |
| 51 | +# |
| 52 | +# We solve `u_t = u_xx - ν*u*u'` with rectangular collocation with zero Dirchlet conditions. |
| 53 | +#### |
| 54 | + |
| 55 | +D₁ = diff(T,1)[x₁,1:n] / V # 1st derivative from x₂ to x₁ |
| 56 | + |
| 57 | +function burgers!(du, u, (D₁, D₂, R, ν), t) |
| 58 | + du[1] = u[1] # left bc |
| 59 | + mul!(@view(du[2:end-1]), D₂, u) |
| 60 | + @view(du[2:end-1]) .-= ν .* (R*u) .* (D₁*u) # currently allocating, pass temp |
| 61 | + du[end] = u[end] # right bc |
| 62 | +end |
| 63 | +prob = ODEProblem(ODEFunction(burgers!, mass_matrix = [B_l; R; B_r]), u₀.(x₂), (0., 1.), (D₁, D₂, R, 3)) |
| 64 | +sol = solve(prob, Rodas5(), reltol = 1e-8, abstol = 1e-8) |
| 65 | + |
| 66 | +t = range(0,1,100) |
| 67 | +contourf(t, x₂, hcat(sol.(t)...)) |
0 commit comments