|
| 1 | +using FastTransforms |
| 2 | + |
| 3 | +function oprec!(n::Integer, v::AbstractVector, alpha::Real, delta2::Real) |
| 4 | + if n > 0 |
| 5 | + v[1] = 1 |
| 6 | + end |
| 7 | + if n > 1 |
| 8 | + v[2] = (4*alpha+8-(alpha+4)*delta2)/4 |
| 9 | + end |
| 10 | + for i = 1:n-2 |
| 11 | + v[i+2] = (((2*i+alpha+2)*(2*i+alpha+4)+alpha*(alpha+2))/(2*(i+1)*(2*i+alpha+2))*(2*i+alpha+3)/(i+alpha+3) - delta2/4*(2*i+alpha+3)/(i+1)*(2*i+alpha+4)/(i+alpha+3))*v[i+1] - (i+alpha+1)/(i+alpha+3)*(2*i+alpha+4)/(2*i+alpha+2)*v[i] |
| 12 | + end |
| 13 | + return v |
| 14 | +end |
| 15 | + |
| 16 | +# This example calculates the spectrum of the nonlocal diffusion operator: |
| 17 | +# |
| 18 | +# \mathcal{L}_\delta u = \int_{\mathbb{S}^2} \rho_\delta(|\mathbf{x}-\mathbf{y}|)\left[u(\mathbf{x}) - u(\mathbf{y})\right] \,\mathrm{d}\Omega(\mathbf{y}), |
| 19 | +# |
| 20 | +# defined in Eq. (2) of |
| 21 | +# |
| 22 | +# R. M. Slevinsky, H. Montanelli, and Q. Du, [A spectral method for nonlocal diffusion operators on the sphere](https://doi.org/10.1016/j.jcp.2018.06.024), *J. Comp. Phys.*, **372**:893--911, 2018. |
| 23 | +# |
| 24 | + |
| 25 | +function evaluate_lambda(n::Integer, alpha::T, delta::T) where T |
| 26 | + delta2 = delta*delta |
| 27 | + scl = (1+alpha)*(2-delta2/2) |
| 28 | + |
| 29 | + lambda = Vector{T}(undef, n) |
| 30 | + |
| 31 | + if n > 0 |
| 32 | + lambda[1] = 0 |
| 33 | + end |
| 34 | + if n > 1 |
| 35 | + lambda[2] = -2 |
| 36 | + end |
| 37 | + |
| 38 | + oprec!(n-2, view(lambda, 3:n), alpha, delta2) |
| 39 | + |
| 40 | + for i = 2:n-1 |
| 41 | + lambda[i+1] *= -scl/(i-1) |
| 42 | + end |
| 43 | + |
| 44 | + p = plan_jac2jac(T, n-1, zero(T), zero(T), alpha, zero(T)) |
| 45 | + |
| 46 | + lambda[2:end] .= p'lambda[2:end] |
| 47 | + |
| 48 | + for i = 2:n-1 |
| 49 | + lambda[i+1] = ((2i-1)*lambda[i+1] + (i-1)*lambda[i])/i |
| 50 | + end |
| 51 | + |
| 52 | + for i = 2:n-1 |
| 53 | + lambda[i+1] += lambda[i] |
| 54 | + end |
| 55 | + |
| 56 | + return lambda |
| 57 | +end |
| 58 | + |
| 59 | +lambda = evaluate_lambda(1024, -0.5, 0.025) |
| 60 | +lambdabf = evaluate_lambda(1024, parse(BigFloat, "-0.5"), parse(BigFloat, "0.025")) |
| 61 | + |
| 62 | +norm(lambda64-lambdabf, Inf)/norm(lambda64, Inf) |
0 commit comments