|
| 1 | +# # 1D bratu equation from (Kan2022-ko)[@cite] |
| 2 | + |
| 3 | +# ## Necessary packages |
| 4 | +using NewtonKrylov, Krylov |
| 5 | +using KrylovPreconditioners |
| 6 | +using SparseArrays, LinearAlgebra |
| 7 | +using CairoMakie |
| 8 | +using KernelAbstractions |
| 9 | + |
| 10 | +# ## 1D Bratu equations |
| 11 | +# $y′′ + λ * exp(y) = 0$ |
| 12 | + |
| 13 | +@kernel function bratu_kernel!(res, y, Δx, λ) |
| 14 | + i = @index(Global, Linear) |
| 15 | + N = length(res) |
| 16 | + y_l = i == 1 ? zero(eltype(y)) : y[i - 1] |
| 17 | + y_r = i == N ? zero(eltype(y)) : y[i + 1] |
| 18 | + y′′ = (y_r - 2y[i] + y_l) / Δx^2 |
| 19 | + |
| 20 | + res[i] = y′′ + λ * exp(y[i]) # = 0 |
| 21 | +end |
| 22 | + |
| 23 | +function bratu!(res, y, Δx, λ) |
| 24 | + device = KernelAbstractions.get_backend(res) |
| 25 | + kernel = bratu_kernel!(device) |
| 26 | + kernel(res, y, Δx, λ, ndrange = length(res)) |
| 27 | + return nothing |
| 28 | +end |
| 29 | + |
| 30 | +function bratu(y, dx, λ) |
| 31 | + res = similar(y) |
| 32 | + bratu!(res, y, dx, λ) |
| 33 | + return res |
| 34 | +end |
| 35 | + |
| 36 | +# ## Reference solution |
| 37 | +function true_sol_bratu(x) |
| 38 | + ## for λ = 3.51382, 2nd sol θ = 4.8057 |
| 39 | + θ = 4.79173 |
| 40 | + return -2 * log(cosh(θ * (x - 0.5) / 2) / (cosh(θ / 4))) |
| 41 | +end |
| 42 | + |
| 43 | +# ## Choice of parameters |
| 44 | +const N = 10_000 |
| 45 | +const λ = 3.51382 |
| 46 | +const dx = 1 / (N + 1) # Grid-spacing |
| 47 | + |
| 48 | +# ### Domain and Inital condition |
| 49 | +x = LinRange(0.0 + dx, 1.0 - dx, N) |
| 50 | +u₀ = sin.(x .* π) |
| 51 | + |
| 52 | +lines(x, u₀, label = "Inital guess") |
| 53 | + |
| 54 | +# ## Reference solution evaluated over domain |
| 55 | +reference = true_sol_bratu.(x) |
| 56 | + |
| 57 | +fig, ax = lines(x, u₀, label = "Inital guess") |
| 58 | +lines!(ax, x, reference, label = "Reference solution") |
| 59 | +axislegend(ax, position = :cb) |
| 60 | +fig |
| 61 | + |
| 62 | +# ## Solving using inplace variant and CG |
| 63 | +uₖ, _ = newton_krylov!( |
| 64 | + (res, u) -> bratu!(res, u, dx, λ), |
| 65 | + copy(u₀), similar(u₀); |
| 66 | + Solver = CgSolver, |
| 67 | +) |
| 68 | + |
| 69 | +ϵ = abs2.(uₖ .- reference) |
| 70 | + |
| 71 | +let |
| 72 | + fig = Figure(size = (800, 800)) |
| 73 | + ax = Axis(fig[1, 1], title = "", ylabel = "", xlabel = "") |
| 74 | + |
| 75 | + lines!(ax, x, reference, label = "True solution") |
| 76 | + lines!(ax, x, u₀, label = "Initial guess") |
| 77 | + lines!(ax, x, uₖ, label = "Newton-Krylov solution") |
| 78 | + |
| 79 | + axislegend(ax, position = :cb) |
| 80 | + |
| 81 | + ax = Axis(fig[1, 2], title = "Error", ylabel = "abs2 err", xlabel = "") |
| 82 | + lines!(ax, abs2.(uₖ .- reference)) |
| 83 | + |
| 84 | + fig |
| 85 | +end |
0 commit comments