13 use,
intrinsic :: iso_c_binding
14 use fftw3, only : fftw_r2hc, fftw_hc2r, fftw_redft00, fftw_redft10, fftw_redft01
18 public :: w_forward, w_backward, p_forward, p_backward
22 integer,
parameter :: nplans = 10
23 integer :: n_r2r_plans = 0
24 type(c_ptr) :: r2r_plans(nplans)
25 integer :: r2r_plan_lengths(nplans)
26 integer :: r2r_plan_nums(nplans)
27 integer(C_INT) :: r2r_plan_kinds(nplans)
29 integer,
parameter :: w_forward = fftw_redft10
30 integer,
parameter :: w_backward = fftw_redft01
31 integer,
parameter :: p_forward = fftw_r2hc
32 integer,
parameter :: p_backward = fftw_hc2r
41 subroutine fft_r2r(u, length, num, kind, rescale)
43 use fftw3, only : fftw_exhaustive, fftw_estimate
44 use fftw3, only : fftw_plan_many_r2r
45 use fftw3, only : fftw_execute_r2r
48 real(DP),
intent(inout) :: u(:,:,:) !>
49 integer,
intent(in) :: length !>
50 integer,
intent(in) :: num !>
51 integer(C_INT) :: kind !>
52 real(DP),
intent(inout) :: rescale !>
54 integer :: i, plan_idx
55 real(DP),
allocatable :: proxy(:)
61 length == r2r_plan_lengths(i) .and. &
62 num == r2r_plan_nums(i) .and. &
63 kind == r2r_plan_kinds(i) &
71 if (plan_idx < 0)
then
72 if (n_r2r_plans == nplans)
then
73 write(*,*)
"Ran out of plans!"
76 n_r2r_plans = n_r2r_plans + 1
77 plan_idx = n_r2r_plans
78 allocate(proxy(num*length))
79 r2r_plans(plan_idx) = fftw_plan_many_r2r(1, &
81 proxy, (/length/), 1, length, &
82 proxy, (/length/), 1, length, &
83 (/kind/), fftw_exhaustive)
85 r2r_plan_lengths(plan_idx) = length
86 r2r_plan_nums(plan_idx) = num
87 r2r_plan_kinds(plan_idx) = kind
91 call fftw_execute_r2r(r2r_plans(plan_idx), u, u)
94 if (kind == fftw_redft00)
then
95 rescale = rescale * sqrt(2.*
real(length-1, kind=dp))
96 else if (kind == w_forward .or. kind == w_backward)
then
97 rescale = rescale * sqrt(2.*
real(length, kind=dp))
98 else if (kind == fftw_r2hc .or. kind == fftw_hc2r)
then
99 rescale = rescale * sqrt(
real(length, kind=dp))
101 write(*,*)
"Don't know how to deal with FFT kind", kind
110 integer,
intent(in) :: i !>
111 integer,
intent(in) :: N !>
112 real(DP),
intent(in) :: L !>
113 integer,
intent(in) :: kind !>
115 real(DP),
parameter :: pi = 4.*atan(1.)
117 if (kind == p_forward)
then
123 else if (kind == w_forward)
then
126 write(*,*)
"Don't know how to deal with FFT kind", kind
134 use fftw3, only : fftw_exhaustive, fftw_estimate
137 real(DP),
intent(inout) :: grid(0:,0:,0:)
138 real(DP),
intent(out) :: grid_t(0:,0:,0:)
139 integer,
intent(in) :: shape_x(3)
140 integer,
intent(in) :: idx
141 integer,
intent(in) :: idx_t
142 integer,
intent(in) :: comm
144 real(DP),
allocatable :: tmp(:,:)
145 real(DP),
allocatable :: tmp_t(:,:)
146 integer :: block0, block1, num
147 integer :: i, j, k, ierr, comm_size
150 if (
size(grid) < 1)
return
154 if (idx == 1 .or. idx_t == 1)
then
155 block0 =
size(grid,2)
156 block1 =
size(grid,1) / comm_size
158 else if (idx == 3 .or. idx_t == 3)
then
159 block0 =
size(grid,3)
160 block1 =
size(grid,1) / comm_size
163 allocate(tmp(0:block0-1, 0:
size(grid,1)-1))
164 allocate(tmp_t(0:block0-1, 0:
size(grid,1)-1))
166 if (idx == 1 .or. idx_t == 1)
then
169 call mpi_alltoall(tmp, block0*block1, nekreal, &
170 tmp_t, block0*block1, nekreal,
comm, ierr)
171 if (ierr /= 0)
write(*,*)
"alltoall errored", ierr, nid
172 do j = 0,
size(grid_t,1) - 1
173 do k = 0,
size(grid_t,2) - 1
174 grid_t(j,k,i) = tmp_t( mod(j,int(block0)), (j / block0) * block1 + k )
178 else if (idx == 3 .or. idx_t == 3)
then
181 call mpi_alltoall(tmp, block0*block1, nekreal, &
182 tmp_t, block0*block1, nekreal,
comm, ierr)
183 if (ierr /= 0)
write(*,*)
"alltoall errored", ierr, nid
184 do j = 0,
size(grid_t,1) - 1
185 do k = 0,
size(grid_t,3) - 1
186 grid_t(j,i,k) = tmp_t( mod(j,int(block0)), (j / block0) * block1 + k )
191 write(*,*)
"Something went wrong in transpose", nid
subroutine transpose(a, lda, b, ldb)
subroutine, public transpose_grid(grid, grid_t, shape_x, idx, idx_t, comm)
Global (parallel) transform of grid data.
subroutine, public fft_r2r(u, length, num, kind, rescale)
Compute a number of 1D FFTs or DCTs.
subroutine mpi_comm_size(comm, nprocs, ierror)
real(dp) function, public wavenumber(i, N, L, kind)
Get the wavenumber of the ith mode.