|
| 1 | +function get_forward_and_backward_plan(::SimpleLiquid{3, species, T1, T2, P}, F) where {species, T1, T2, P} |
| 2 | + return find_fourier_plans_3d(F) |
| 3 | +end |
| 4 | + |
| 5 | +function get_forward_and_backward_plan(::SimpleLiquid{2, species, T1, T2, P}, F) where {species, T1, T2, P} |
| 6 | + return find_fourier_plans_2d(F) |
| 7 | +end |
| 8 | + |
| 9 | +function find_fourier_plans_3d(F::Vector{T}) where T |
| 10 | + if T <: Number |
| 11 | + forward = FFTW.plan_r2r!(copy(F), FFTW.RODFT00; flags=FFTW.ESTIMATE) |
| 12 | + backward = FFTW.plan_r2r!(copy(F), FFTW.RODFT00; flags=FFTW.ESTIMATE) |
| 13 | + return forward, backward |
| 14 | + elseif T <: AbstractArray |
| 15 | + F2 = copy(F) |
| 16 | + Nspecies = size(F2[1], 1) |
| 17 | + elT = eltype(T) |
| 18 | + F2 = reinterpret(reshape, elT, F2) |
| 19 | + if Nspecies == 1 |
| 20 | + forward = FFTW.plan_r2r!(F2, FFTW.RODFT00; flags=FFTW.ESTIMATE) |
| 21 | + backward = FFTW.plan_r2r!(F2, FFTW.RODFT00; flags=FFTW.ESTIMATE) |
| 22 | + return forward, backward |
| 23 | + else |
| 24 | + forward = FFTW.plan_r2r!(F2, FFTW.RODFT00, 2, flags=FFTW.ESTIMATE) |
| 25 | + backward = FFTW.plan_r2r!(F2, FFTW.RODFT00, 2, flags=FFTW.ESTIMATE) |
| 26 | + return forward, backward |
| 27 | + end |
| 28 | + end |
| 29 | +end |
| 30 | + |
| 31 | +function inverse_radial_fourier_transform_3d(F̂, r, k) |
| 32 | + M = length(r) |
| 33 | + @assert length(k) == length(F̂) == M |
| 34 | + dk = k[2] - k[1] |
| 35 | + dr = r[2] - r[1] |
| 36 | + # @assert dk*dr ≈ π/(M+1) |
| 37 | + F = FFTW.r2r(F̂, FFTW.RODFT00)*dk/(4π^2) |
| 38 | + return F |
| 39 | +end |
| 40 | + |
| 41 | +function radial_fourier_transform_3d(F, r, k) |
| 42 | + M = length(r) |
| 43 | + @assert length(k) == length(F) == M |
| 44 | + dk = k[2] - k[1] |
| 45 | + dr = r[2] - r[1] |
| 46 | + # @assert dk*dr ≈ π/(M+1) |
| 47 | + F̂ = FFTW.r2r(F, FFTW.RODFT00)*2π*dr |
| 48 | + return F̂ |
| 49 | +end |
| 50 | + |
| 51 | + |
| 52 | +""" |
| 53 | + fourier!(F̂, F, plan, equation::OZEquation{3, T1, T2, T3}) where {T1, T2, T3} |
| 54 | +
|
| 55 | +computes the three dimensional radial fourier transform of F = r*f(r), returning F̂ = k*f̂(k), where f̂ is the fourier transform of f. |
| 56 | +it uses the discrete sine tranform provided by the r2r function of FFTW internally. |
| 57 | +""" |
| 58 | +function fourier!(F̂::Vector{T}, F::Vector{T}, plan::FFTW.r2rFFTWPlan, dr) where T |
| 59 | + @. F̂ = F*2π*dr |
| 60 | + if T <: Number |
| 61 | + plan*F̂ |
| 62 | + elseif T<:AbstractMatrix |
| 63 | + F̂2 = reinterpret(reshape, eltype(T), F̂) |
| 64 | + plan*F̂2 |
| 65 | + end |
| 66 | +end |
| 67 | + |
| 68 | +""" |
| 69 | +inverse_fourier!(F, F̂, plan, equation::OZEquation{3, T1, T2, T3}) where {T1, T2, T3} |
| 70 | +
|
| 71 | +computes the three dimensional radial fourier transform of F̂ = k*f̂(k), returning F = r*f(r), where f̂ is the fourier transform of f. |
| 72 | +it uses the discrete sine tranform provided by the r2r function of FFTW internally. |
| 73 | +""" |
| 74 | +function inverse_fourier!(F::AbstractVector{T}, F̂::AbstractVector{T}, plan::FFTW.r2rFFTWPlan, dk) where T |
| 75 | + @. F = F̂ * dk/(4π^2) |
| 76 | + if T <: Number |
| 77 | + plan*F |
| 78 | + elseif T<:AbstractMatrix |
| 79 | + F2 = reinterpret(reshape, eltype(T), F) |
| 80 | + plan*F2 |
| 81 | + end |
| 82 | +end |
0 commit comments