23 use,
intrinsic :: iso_c_binding
32 fftw_execute_dft_c2r, &
33 fftw_execute_dft_r2c, &
42 fftw_plan_dft_r2c_1d, &
43 fftw_plan_dft_r2c_2d, &
44 fftw_plan_dft_r2c_3d, &
45 fftw_plan_dft_c2r_1d, &
46 fftw_plan_dft_c2r_2d, &
47 fftw_plan_dft_c2r_3d, &
68 public :: fftw_mpi_default_block
70#if defined(HAVE_OPENMP) && defined(HAVE_FFTW3_THREADS)
73 fftw_plan_with_nthreads, &
79 include
"fftw3-mpi.f03"
89 use,
intrinsic :: iso_c_binding
106 subroutine fftw_prepare_plan(plan, dim, n, is_real, sign, flags, din_, cin_, cout_)
107 type(c_ptr),
intent(inout) :: plan
108 integer,
intent(in) :: dim
109 integer,
intent(in) :: n(:)
110 logical,
intent(in) :: is_real
111 integer,
intent(in) :: sign
112 integer,
intent(in) :: flags
113 real(real64),
optional,
target,
intent(in) :: din_(:,:,:)
114 complex(real64),
optional,
target,
intent(in) :: cin_(:,:,:)
115 complex(real64),
optional,
target,
intent(in) :: cout_(:,:,:)
117 real(real64),
pointer :: rin(:,:,:)
118 real(real64),
pointer :: rout(:,:,:)
119 complex(real64),
pointer :: cin(:,:,:)
120 complex(real64),
pointer :: cout(:,:,:)
121 logical :: aligned_memory
125 assert(sign == fftw_forward .or. sign == fftw_backward)
127 aligned_memory = .false.
128 if (
present(din_) .or.
present(cin_))
then
129 assert(
present(cout_))
130 assert(
present(din_) .neqv.
present(cin_))
131 aligned_memory = .
true.
133 assert(
present(din_))
135 assert(
present(cin_))
140 if (sign == fftw_forward)
then
141 if (.not. aligned_memory)
then
142 safe_allocate(rin(1:n(1), 1:n(2), 1:n(3)))
143 safe_allocate(cout(1:n(1)/2+1, 1:n(2), 1:n(3)))
151 plan = fftw_plan_dft_r2c_1d(n(1), rin, cout, flags)
153 plan = fftw_plan_dft_r2c_2d(n(2), n(1),rin, cout, flags)
155 plan = fftw_plan_dft_r2c_3d(n(3), n(2), n(1), rin, cout, flags)
158 if (.not. aligned_memory)
then
159 safe_deallocate_p(rin)
160 safe_deallocate_p(cout)
165 if (.not. aligned_memory)
then
166 safe_allocate(cin(1:n(1)/2+1, 1:n(2), 1:n(3)))
167 safe_allocate(rout(1:n(1), 1:n(2), 1:n(3)))
175 plan = fftw_plan_dft_c2r_1d(n(1), cin, rout, flags)
177 plan = fftw_plan_dft_c2r_2d(n(2), n(1), cin, rout, flags)
179 plan = fftw_plan_dft_c2r_3d(n(3), n(2), n(1), cin, rout, flags)
182 if (.not. aligned_memory)
then
183 safe_deallocate_p(cin)
184 safe_deallocate_p(rout)
190 if (.not. aligned_memory)
then
191 safe_allocate(cin(1:n(1), 1:n(2), 1:n(3)))
192 safe_allocate(cout(1:n(1), 1:n(2), 1:n(3)))
194 if (sign == fftw_forward)
then
205 plan = fftw_plan_dft_1d(n(1), cin, cout, sign, flags)
207 plan = fftw_plan_dft_2d(n(2), n(1), cin, cout, sign, flags)
209 plan = fftw_plan_dft_3d(n(3), n(2), n(1), cin, cout, sign, flags)
212 if (.not. aligned_memory)
then
213 safe_deallocate_p(cin)
214 safe_deallocate_p(cout)
225 integer,
intent(in) :: rs_n(:)
226 logical,
intent(in) :: is_real
227 integer,
intent(out) :: fs_n(:)
232 if (is_real) fs_n(1) = rs_n(1)/2 + 1
239 integer,
intent(in) :: rs_n(:)
240 logical,
intent(in) :: is_real
241 integer,
intent(in) :: fs_n(:)
242 real(real64),
pointer,
intent(inout) :: drs_data(:,:,:)
243 complex(real64),
pointer,
intent(inout) :: zrs_data(:,:,:)
244 complex(real64),
pointer,
intent(inout) :: fs_data(:,:,:)
245 type(c_ptr) :: address
250 address = fftw_alloc_real(int(product(rs_n(1:3)), c_size_t))
251 call c_f_pointer(address, drs_data, rs_n)
253 address = fftw_alloc_complex(int(product(rs_n(1:3)), c_size_t))
254 call c_f_pointer(address, zrs_data, rs_n)
256 address = fftw_alloc_complex(int(product(fs_n(1:3)), c_size_t))
257 call c_f_pointer(address, fs_data, fs_n)
264 logical,
intent(in) :: is_real
265 real(real64),
pointer,
intent(inout) :: drs_data(:,:,:)
266 complex(real64),
pointer,
intent(inout) :: zrs_data(:,:,:)
267 complex(real64),
pointer,
intent(inout) :: fs_data(:,:,:)
272 call fftw_free(c_loc(drs_data))
275 call fftw_free(c_loc(zrs_data))
278 call fftw_free(c_loc(fs_data))
subroutine, public fftw_prepare_plan(plan, dim, n, is_real, sign, flags, din_, cin_, cout_)
subroutine, public fftw_free_memory(is_real, drs_data, zrs_data, fs_data)
subroutine, public fftw_get_dims(rs_n, is_real, fs_n)
subroutine, public fftw_alloc_memory(rs_n, is_real, fs_n, drs_data, zrs_data, fs_data)