17 #ifndef DOXYGEN_SHOULD_SKIP_THIS
19 #include "sll_working_precision.h"
20 #include "sll_assert.h"
21 #include "sll_memory.h"
28 sll_real64,
dimension(:),
pointer :: twiddles => null()
31 sll_int32 :: direction
32 sll_int32 :: problem_rank
33 sll_int32,
dimension(:),
pointer :: problem_shape
36 interface fft_new_plan
37 module procedure fftpack_new_plan_c2c_1d, fftpack_new_plan_r2r_1d, &
38 fftpack_new_plan_r2c_1d, fftpack_new_plan_c2r_1d, &
39 fftpack_new_plan_c2r_2d, fftpack_new_plan_r2c_2d, &
40 fftpack_new_plan_c2c_2d
43 interface fft_apply_plan
44 module procedure fftpack_apply_plan_c2c_1d, fftpack_apply_plan_r2r_1d, &
45 fftpack_apply_plan_r2c_1d, fftpack_apply_plan_c2r_1d, &
46 fftpack_apply_plan_c2r_2d, fftpack_apply_plan_r2c_2d, &
47 fftpack_apply_plan_c2c_2d
50 integer,
parameter :: FFT_FORWARD = -1
51 integer,
parameter :: FFT_BACKWARD = 1
57 integer,
parameter :: FFT_NORMALIZE_FORWARD = 2**0
58 integer,
parameter :: FFT_NORMALIZE_INVERSE = 2**0
59 integer,
parameter :: FFT_NORMALIZE = 2**0
61 integer,
parameter :: FFTPACK_MOD = 100
63 interface fft_get_mode
64 module procedure fft_get_mode_complx_1d, fft_get_mode_real_1d
67 interface fft_set_mode
68 module procedure fft_set_mode_complx_1d, fft_set_mode_real_1d
73 subroutine print_defaultfftlib()
74 print *,
'The library used is FFTPACK'
77 function fft_get_mode_complx_1d(plan, array, k)
result(mode)
78 type(sll_fft_plan),
pointer :: plan
79 sll_comp64,
dimension(0:) :: array
85 function fft_get_mode_real_1d(plan, data, k)
result(mode)
86 type(sll_fft_plan),
pointer :: plan
87 sll_real64,
dimension(0:) ::
data
88 sll_int32 :: k, n_2, n
91 n = plan%problem_shape(1)
95 mode = cmplx(
data(0), 0.0_f64, kind=f64)
96 else if (k .eq. n_2)
then
97 mode = cmplx(
data(n - 1), 0.0_f64, kind=f64)
98 else if (k .gt. n_2)
then
99 mode = cmplx(
data(2*(n - k) - 1), -
data(2*(n - k)), kind=f64)
101 mode = cmplx(
data(2*k - 1),
data(2*k), kind=f64)
105 subroutine fft_set_mode_complx_1d(plan, array, new_value, k)
106 type(sll_fft_plan),
pointer :: plan
107 sll_comp64,
dimension(0:) :: array
109 sll_comp64 :: new_value
113 subroutine fft_set_mode_real_1d(plan, data, new_value, k)
114 type(sll_fft_plan),
pointer :: plan
115 sll_real64,
dimension(0:) ::
data
116 sll_int32 :: k, n_2, n, index_mode
117 sll_comp64 :: new_value
119 n = plan%problem_shape(1)
123 data(0) = real(new_value, kind=f64)
124 else if (k .eq. n_2)
then
125 data(n - 1) = real(new_value, kind=f64)
126 else if (k .gt. n_2)
then
127 data(2*(n - k) - 1) = real(new_value, kind=f64)
128 data(2*(n - k)) = -aimag(new_value)
130 data(2*k - 1) = real(new_value, kind=f64)
131 data(2*k) = aimag(new_value)
142 function fft_ith_stored_mode(plan, i)
143 type(sll_fft_plan),
pointer :: plan
144 sll_int32 :: i, fft_ith_stored_mode
145 fft_ith_stored_mode = i
146 end function fft_ith_stored_mode
152 function fftpack_new_plan_c2c_1d(nx, array_in, array_out, direction, flags)
result(plan)
153 sll_int32,
intent(in) :: nx
154 sll_comp64,
dimension(:) :: array_in, array_out
155 sll_int32,
intent(in) :: direction
156 sll_int32,
optional,
intent(in) :: flags
157 type(sll_fft_plan),
pointer :: plan
160 sll_allocate(plan, ierr)
161 plan%library = fftpack_mod
162 plan%direction = direction
163 if (
present(flags))
then
168 plan%problem_rank = 1
169 sll_allocate(plan%problem_shape(1), ierr)
170 plan%problem_shape = (/nx/)
171 allocate (plan%twiddles(4*nx + 15))
172 call zffti(nx, plan%twiddles)
175 subroutine fftpack_apply_plan_c2c_1d(plan, array_in, array_out)
176 type(sll_fft_plan),
pointer,
intent(in) :: plan
177 sll_comp64,
dimension(:),
intent(inout) :: array_in, array_out
181 if (loc(array_in) .ne. loc(array_out))
then
185 nx = plan%problem_shape(1)
187 if (plan%direction .eq. fft_forward)
then
188 call zfftf(nx, array_out, plan%twiddles)
189 else if (plan%direction .eq. fft_backward)
then
190 call zfftb(nx, array_out, plan%twiddles)
193 if (fft_is_present_flag(plan%style, fft_normalize))
then
194 factor = 1.0_f64/real(nx, kind=f64)
195 array_out = factor*array_out
201 function fftpack_new_plan_r2r_1d(nx, array_in, array_out, direction, flags)
result(plan)
202 sll_int32,
intent(in) :: nx
203 sll_real64,
dimension(:) :: array_in, array_out
204 sll_int32,
intent(in) :: direction
205 sll_int32,
optional,
intent(in) :: flags
206 type(sll_fft_plan),
pointer :: plan
209 sll_allocate(plan, ierr)
210 plan%library = fftpack_mod
211 plan%direction = direction
212 if (
present(flags))
then
217 plan%problem_rank = 1
218 sll_allocate(plan%problem_shape(1), ierr)
219 plan%problem_shape = (/nx/)
221 sll_allocate(plan%twiddles(2*nx + 15), ierr)
222 call dffti(nx, plan%twiddles)
225 subroutine fftpack_apply_plan_r2r_1d(plan, array_in, array_out)
226 type(sll_fft_plan),
pointer,
intent(in) :: plan
227 sll_real64,
dimension(:),
intent(inout) :: array_in, array_out
231 if (loc(array_in) .ne. loc(array_out))
then
235 nx = plan%problem_shape(1)
237 if (plan%direction .eq. fft_forward)
then
238 call dfftf(nx, array_out, plan%twiddles)
239 else if (plan%direction .eq. fft_backward)
then
240 call dfftb(nx, array_out, plan%twiddles)
243 if (fft_is_present_flag(plan%style, fft_normalize))
then
244 factor = 1.0_f64/real(nx, kind=f64)
245 array_out = factor*array_out
250 function fftpack_new_plan_r2c_1d(nx, array_in, array_out, flags)
result(plan)
251 sll_int32,
intent(in) :: nx
252 sll_real64,
dimension(:) :: array_in
253 sll_comp64,
dimension(:) :: array_out
254 sll_int32,
optional,
intent(in) :: flags
255 type(sll_fft_plan),
pointer :: plan
258 print *,
"function fftpack_new_plan_r2c_1d is not implemented"
261 subroutine fftpack_apply_plan_r2c_1d(plan, array_in, array_out)
262 type(sll_fft_plan),
pointer :: plan
263 sll_real64,
dimension(0:),
intent(inout) :: array_in
264 sll_comp64,
dimension(0:),
intent(out) :: array_out
268 print *,
"subroutine fftpack_apply_plan_r2c_1d is not implemented"
271 function fftpack_new_plan_c2r_1d(nx, array_in, array_out, flags)
result(plan)
272 sll_int32,
intent(in) :: nx
273 sll_real64,
dimension(:) :: array_out
274 sll_comp64,
dimension(:) :: array_in
275 sll_int32,
optional,
intent(in) :: flags
276 type(sll_fft_plan),
pointer :: plan
279 print *,
"function fftpack_new_plan_c2r_1d is not implemented"
282 subroutine fftpack_apply_plan_c2r_1d(plan, array_in, array_out)
283 type(sll_fft_plan),
pointer :: plan
284 sll_real64,
dimension(0:),
intent(inout) :: array_out
285 sll_comp64,
dimension(0:),
intent(out) :: array_in
289 print *,
"subroutine fftpack_apply_plan_c2r_1d is not implemented"
292 function fftpack_new_plan_c2c_2d(NX, NY, array_in, array_out, direction, flags) &
295 sll_int32,
intent(in) :: nx, ny
296 sll_comp64,
dimension(0:, 0:),
target,
intent(in) :: array_in, array_out
297 sll_int32,
intent(in) :: direction
298 sll_int32,
optional,
intent(in) :: flags
299 type(sll_fft_plan),
pointer :: plan
302 logical :: two_direction
304 print *,
"function fftpack_new_plan_c2c_2d is not implemented"
305 end function fftpack_new_plan_c2c_2d
307 subroutine fftpack_apply_plan_c2c_2d(plan, array_in, array_out)
308 type(sll_fft_plan),
pointer :: plan
309 sll_comp64,
dimension(0:, 0:),
intent(inout) :: array_in, array_out
310 sll_int32 :: i, nx, ny
311 sll_int32,
dimension(2) :: fft_shape
312 logical :: two_direction
314 print *,
"subroutine fftpack_apply_plan_c2c_2d is not implemented"
315 end subroutine fftpack_apply_plan_c2c_2d
317 function fftpack_new_plan_c2r_2d(nx, ny, array_in, array_out, flags)
result(plan)
318 sll_int32,
intent(in) :: nx, ny
319 sll_comp64,
dimension(:, :),
intent(in) :: array_in
320 sll_real64,
dimension(:, :),
intent(in) :: array_out
321 sll_int32,
optional,
intent(in) :: flags
322 type(sll_fft_plan),
pointer :: plan
325 print *,
"function fftpack_new_plan_c2r_2d is no implemented"
326 end function fftpack_new_plan_c2r_2d
328 subroutine fftpack_apply_plan_c2r_2d(plan, array_in, array_out)
329 type(sll_fft_plan),
pointer :: plan
330 sll_comp64,
dimension(0:, 0:),
intent(inout) :: array_in
331 sll_real64,
dimension(0:, 0:),
intent(out) :: array_out
332 sll_int32 :: nx, i, ny, k, j
335 print *,
"subroutine fftpack_apply_plan_c2r_2d is not implemented"
336 end subroutine fftpack_apply_plan_c2r_2d
338 function fftpack_new_plan_r2c_2d(nx, ny, array_in, array_out, flags)
result(plan)
339 sll_int32,
intent(in) :: nx, ny
340 sll_real64,
dimension(:, :),
intent(in) :: array_in
341 sll_comp64,
dimension(:, :),
intent(in) :: array_out
342 sll_int32,
optional,
intent(in) :: flags
343 type(sll_fft_plan),
pointer :: plan
346 print *,
"function fftpack_new_plan_r2c_2d is not implemented"
349 subroutine fftpack_apply_plan_r2c_2d(plan, array_in, array_out)
350 type(sll_fft_plan),
pointer :: plan
351 sll_real64,
dimension(0:, 0:),
intent(inout) :: array_in
352 sll_comp64,
dimension(0:, 0:),
intent(out) :: array_out
353 sll_int32 :: nx, i, ny, k
356 print *,
"subroutine fftpack_apply_plan_r2c_2d is not implemented"
357 end subroutine fftpack_apply_plan_r2c_2d
363 subroutine fft_delete_plan(plan)
364 type(sll_fft_plan),
pointer :: plan
366 if (.not.
associated(plan))
then
367 print *,
' Error in fft_delete_plan subroutine'
368 print *,
' you try to delete a plan not associated'
372 if (
associated(plan%twiddles))
then
373 deallocate (plan%twiddles)
374 plan%twiddles => null()
380 #endif /* DOXYGEN_SHOULD_SKIP_THIS */