BVP from (Kelley2022)[@cite]
using Ariadne, Krylov, LinearAlgebra
function Phi(t, tdag, vp, v)
phi = 4.0 * tdag * vp + (t * v - 1.0) * v
return phi
end
function Fbvp!(res, U, (force, tv, tvdag, h, n))
@assert 2n == length(U)
res[1] = U[2]
res[2n] = U[2n - 1]
v = view(U, 1:2:(2n - 1))
vp = view(U, 2:2:2n)
force .= Phi.(tv, tvdag, vp, v)
h2 = 0.5 * h
@inbounds @simd for ip in 1:(n - 1)
res[2 * ip + 1] = v[ip + 1] - v[ip] - h2 * (vp[ip] + vp[ip + 1])
res[2 * ip] = vp[ip + 1] - vp[ip] + h2 * (force[ip] + force[ip + 1])
end
return nothing
end
function BVP_U0!(U0, n, tv)
view(U0, 1:2:(2n - 1)) .= exp.(-0.1 .* tv .* tv)
return view(U0, 2:2:2n) .= -0.2 .* view(U0, 1:2:(2n - 1)) .* tv
end
struct GmresPreconditioner{JOp}
J::JOp
itmax::Int
end
function LinearAlgebra.mul!(y, P::GmresPreconditioner, x)
sol, _ = gmres(P.J, x; P.itmax)
return copyto!(y, sol)
end
function BVP_solve(n = 801, T = Float64)
U0 = zeros(T, 2n)
res = zeros(T, 2n)
h = 20.0 / (n - 1)
tv = collect(0:h:20.0)
tvdag = collect(0:h:20.0)
@views tvdag[2:n] .= (1.0 ./ tv[2:n])
force = zeros(n)
BVP_U0!(U0, n, tv)
bvpout, stats = newton_krylov!(
Fbvp!, U0, (force, tv, tvdag, h, n), res,
algo = :fgmres,
N = (J) -> GmresPreconditioner(J, 30),
)
return (; bvpout, tv, stats)
end
BVP_solve()(bvpout = [2.1188362694280456, 1.9618886636148897e-10, 2.119051145468122, 0.017190116597667265, 2.119463399642583, 0.015790247029295795, 2.1200055698396922, 0.027583356868524984, 2.1207867672670417, 0.03491244219673889 … 2.5055650580040285e-9, 2.3841135893299073e-8, 6.989361845333584e-10, 2.3854334108813072e-8, -8.342034303426604e-10, 2.4764054857883552e-8, -1.3141952617646156e-10, 2.5871538888200787e-8, -3.4700836137741015e-11, 2.641160192558712e-8], tv = [0.0, 0.025, 0.05, 0.075, 0.1, 0.125, 0.15, 0.175, 0.2, 0.225 … 19.775, 19.8, 19.825, 19.85, 19.875, 19.9, 19.925, 19.95, 19.975, 20.0], stats = (solved = true, stats = Ariadne.Stats(40, 34420, 1.328500273393806e-7), t = 35.609607587))This page was generated using Literate.jl.