(git:6344619)
Loading...
Searching...
No Matches
fft_lib.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7MODULE fft_lib
8
9 USE fft_kinds, ONLY: dp
10 USE fft_plan, ONLY: fft_plan_type
11 USE fftsg_lib, ONLY: fftsg1dm,&
12 fftsg3d,&
15 USE fftw3_lib, ONLY: &
16 fft_alloc => fftw_alloc, fft_dealloc => fftw_dealloc, fftw31dm, fftw33d, &
19#include "../../base/base_uses.f90"
20
21 IMPLICIT NONE
22 PRIVATE
23
24 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'fft_lib'
25
26 INTEGER, SAVE :: fft_type = 0
27
31 PUBLIC :: fft_alloc, fft_dealloc
32
33CONTAINS
34! **************************************************************************************************
35!> \brief Interface to FFT libraries
36!> \param fftlib ...
37!> \return ...
38!> \par History
39!> IAB 09-Jan-2009 : Modified to use fft_plan_type
40!> (c) The Numerical Algorithms Group (NAG) Ltd, 2009 on behalf of the HECToR project
41!> \author JGH
42! **************************************************************************************************
43 FUNCTION fft_library(fftlib) RESULT(flib)
44
45 CHARACTER(len=*), INTENT(IN) :: fftlib
46 INTEGER :: flib
47
48 SELECT CASE (fftlib)
49 CASE DEFAULT
50 flib = -1
51 CASE ("FFTSG")
52 flib = 1
53 CASE ("FFTW3")
54 flib = 3
55 END SELECT
56
57 END FUNCTION fft_library
58
59! **************************************************************************************************
60!> \brief Query whether the active FFT backend supports arbitrary transform lengths.
61!> \return whether arbitrary positive transform lengths are supported
62! **************************************************************************************************
63 LOGICAL FUNCTION fft_supports_arbitrary_lengths() RESULT(supported)
64
65 supported = fft_type == fft_library("FFTW3")
66
68
69! **************************************************************************************************
70!> \brief ...
71!> \param fftlib ...
72!> \param plan_style ...
73!> \param wisdom_file ...
74! **************************************************************************************************
75 SUBROUTINE fft_do_init(fftlib, plan_style, wisdom_file)
76 CHARACTER(LEN=*), INTENT(IN) :: fftlib
77 INTEGER, INTENT(IN) :: plan_style
78 CHARACTER(LEN=*), INTENT(IN) :: wisdom_file
79
80 fft_type = fft_library(fftlib)
81 SELECT CASE (fft_type)
82 CASE DEFAULT
83 cpabort("fft_do_init")
84 CASE (1)
85 CALL fftsg_do_init()
86 CASE (3)
87 CALL fftw3_do_init(wisdom_file, plan_style)
88 END SELECT
89
90 END SUBROUTINE fft_do_init
91
92! **************************************************************************************************
93!> \brief ...
94!> \param wisdom_file ...
95!> \param ionode ...
96!> \param export_wisdom Export the FFTW wisdom to wisdom_file (default: no export)
97! **************************************************************************************************
98 SUBROUTINE fft_do_cleanup(wisdom_file, ionode, export_wisdom)
99 CHARACTER(LEN=*), INTENT(IN) :: wisdom_file
100 LOGICAL, INTENT(IN) :: ionode
101 LOGICAL, INTENT(IN), OPTIONAL :: export_wisdom
102
103 SELECT CASE (fft_type)
104 CASE DEFAULT
105 cpabort("fft_do_cleanup")
106 CASE (1)
107 CALL fftsg_do_cleanup()
108 CASE (3)
109 CALL fftw3_do_cleanup(wisdom_file, ionode, export_wisdom)
110 END SELECT
111
112 END SUBROUTINE fft_do_cleanup
113
114! **************************************************************************************************
115!> \brief ...
116!> \param DATA ...
117!> \param max_length ...
118! **************************************************************************************************
119 SUBROUTINE fft_get_lengths(DATA, max_length)
120 INTEGER, DIMENSION(*) :: data
121 INTEGER, INTENT(INOUT) :: max_length
122
123 CALL fftw3_get_lengths(DATA, max_length)
124
125 END SUBROUTINE fft_get_lengths
126
127! **************************************************************************************************
128
129! **************************************************************************************************
130!> \brief ...
131!> \param plan ...
132!> \param fft_in_place ...
133!> \param fsign ...
134!> \param n ...
135!> \param zin ...
136!> \param zout ...
137! **************************************************************************************************
138 SUBROUTINE fft_create_plan_3d(plan, fft_in_place, fsign, n, zin, zout)
139
140 TYPE(fft_plan_type), INTENT(INOUT) :: plan
141 LOGICAL, INTENT(IN) :: fft_in_place
142 INTEGER, INTENT(IN) :: fsign
143 INTEGER, DIMENSION(3), INTENT(IN) :: n
144 COMPLEX(KIND=dp), DIMENSION(*), INTENT(INOUT) :: zin, zout
145
146 plan%fsign = fsign
147 plan%fft_in_place = fft_in_place
148 plan%n_3d = n
149!$ plan%need_alt_plan = .FALSE.
150
151 ! Planning only needed for FFTW3
152 IF (fft_type == 3) THEN
153 CALL fftw3_create_plan_3d(plan, zin, zout)
154 plan%valid = .true.
155 END IF
156
157 END SUBROUTINE fft_create_plan_3d
158
159!
160! really ugly, plan is intent out, because plan%fsign is also a status flag
161! if something goes wrong, plan%fsign is set to zero, and the plan becomes invalid
162!
163! **************************************************************************************************
164!> \brief ...
165!> \param plan ...
166!> \param scale ...
167!> \param zin ...
168!> \param zout ...
169!> \param stat ...
170! **************************************************************************************************
171 SUBROUTINE fft_3d(plan, scale, zin, zout, stat)
172 TYPE(fft_plan_type), INTENT(IN) :: plan
173 REAL(kind=dp), INTENT(IN) :: scale
174 COMPLEX(KIND=dp), DIMENSION(*), INTENT(INOUT) :: zin, zout
175 INTEGER, INTENT(OUT) :: stat
176
177 stat = plan%fsign
178 IF (plan%n_3d(1)*plan%n_3d(2)*plan%n_3d(3) > 0) THEN
179 SELECT CASE (fft_type)
180 CASE DEFAULT
181 cpabort("fft_3d")
182 CASE (1)
183 CALL fftsg3d(plan%fft_in_place, stat, scale, plan%n_3d, zin, zout)
184 CASE (3)
185 CALL fftw33d(plan, scale, zin, zout, stat)
186 END SELECT
187 END IF
188 ! stat is set to zero on error, -1,+1 are OK
189 IF (stat == 0) THEN
190 stat = 1
191 ELSE
192 stat = 0
193 END IF
194
195 END SUBROUTINE fft_3d
196
197! **************************************************************************************************
198
199! **************************************************************************************************
200!> \brief ...
201!> \param plan ...
202!> \param fsign ...
203!> \param trans_in ...
204!> \param trans_out ...
205!> \param ldx_in ...
206!> \param ldx_out ...
207!> \param n ...
208!> \param m ...
209!> \param zin ...
210!> \param zout ...
211! **************************************************************************************************
212 SUBROUTINE fft_create_plan_1d(plan, fsign, trans_in, trans_out, ldx_in, ldx_out, n, m, zin, zout)
213 TYPE(fft_plan_type), INTENT(INOUT) :: plan
214 INTEGER, INTENT(IN) :: fsign
215 LOGICAL, INTENT(IN) :: trans_in, trans_out
216 INTEGER, INTENT(IN) :: ldx_in, ldx_out, n, m
217 COMPLEX(KIND=dp), DIMENSION(*), INTENT(IN) :: zin, zout
218
219 plan%fsign = fsign
220 plan%trans_in = trans_in
221 plan%trans_out = trans_out
222 IF (plan%trans_in) THEN
223 plan%ldx_in = ldx_in
224 plan%ldy_in = n
225 ELSE
226 plan%ldx_in = ldx_in
227 plan%ldy_in = m
228 END IF
229 IF (plan%trans_out) THEN
230 plan%ldx_out = ldx_out
231 plan%ldy_out = n
232 ELSE
233 plan%ldx_out = ldx_out
234 plan%ldy_out = m
235 END IF
236
237 plan%n = n
238 plan%m = m
239!$ plan%need_alt_plan = .FALSE.
240
241 ! Planning only needed for FFTW3
242 IF ((fft_type == 3) .AND. (n*m /= 0)) THEN
243 CALL fftw3_create_plan_1d(plan, zin, zout)
244 plan%valid = .true.
245 ELSE
246 plan%valid = .false.
247 END IF
248
249 END SUBROUTINE fft_create_plan_1d
250
251! **************************************************************************************************
252!> \brief ...
253!> \param plan ...
254! **************************************************************************************************
255 SUBROUTINE fft_destroy_plan(plan)
256 TYPE(fft_plan_type), INTENT(INOUT) :: plan
257
258! Planning only needed for FFTW3
259
260 IF (plan%valid .AND. fft_type == 3) THEN
261 CALL fftw3_destroy_plan(plan)
262 plan%valid = .false.
263 END IF
264
265 END SUBROUTINE fft_destroy_plan
266
267! **************************************************************************************************
268!> \brief ...
269!> \param plan ...
270!> \param zin ...
271!> \param zout ...
272!> \param scale ...
273!> \param stat ...
274! **************************************************************************************************
275 SUBROUTINE fft_1d(plan, zin, zout, scale, stat)
276 TYPE(fft_plan_type), INTENT(IN) :: plan
277 COMPLEX(KIND=dp), DIMENSION(*), INTENT(INOUT) :: zin, zout
278 REAL(kind=dp), INTENT(IN) :: scale
279 INTEGER, INTENT(OUT) :: stat
280
281 stat = plan%fsign
282 IF (plan%n*plan%m > 0) THEN
283 SELECT CASE (fft_type)
284 CASE DEFAULT
285 cpabort("fft_1d")
286 CASE (1)
287 CALL fftsg1dm(stat, plan%trans_in, plan%trans_out, plan%n, plan%m, &
288 plan%ldx_in, plan%ldy_in, plan%ldx_out, plan%ldy_out, zin, zout, scale)
289 CASE (3)
290 CALL fftw31dm(plan, zin, zout, scale, stat)
291 END SELECT
292 END IF
293 ! stat is set to zero on error, -1,+1 are OK
294 IF (stat == 0) THEN
295 stat = 1
296 ELSE
297 stat = 0
298 END IF
299
300 END SUBROUTINE fft_1d
301
302END MODULE fft_lib
Defines the basic variable types.
Definition fft_kinds.F:13
integer, parameter, public dp
Definition fft_kinds.F:18
subroutine, public fft_3d(plan, scale, zin, zout, stat)
...
Definition fft_lib.F:172
subroutine, public fft_destroy_plan(plan)
...
Definition fft_lib.F:256
integer function, public fft_library(fftlib)
Interface to FFT libraries.
Definition fft_lib.F:44
subroutine, public fft_1d(plan, zin, zout, scale, stat)
...
Definition fft_lib.F:276
subroutine, public fft_do_cleanup(wisdom_file, ionode, export_wisdom)
...
Definition fft_lib.F:99
subroutine, public fft_create_plan_1d(plan, fsign, trans_in, trans_out, ldx_in, ldx_out, n, m, zin, zout)
...
Definition fft_lib.F:213
subroutine, public fft_do_init(fftlib, plan_style, wisdom_file)
...
Definition fft_lib.F:76
subroutine, public fft_get_lengths(data, max_length)
...
Definition fft_lib.F:120
subroutine, public fft_create_plan_3d(plan, fft_in_place, fsign, n, zin, zout)
...
Definition fft_lib.F:139
logical function, public fft_supports_arbitrary_lengths()
Query whether the active FFT backend supports arbitrary transform lengths.
Definition fft_lib.F:64
Type to store data about a (1D or 3D) FFT, including FFTW plan.
Definition fft_plan.F:18
subroutine, public fftsg_do_init()
...
Definition fftsg_lib.F:25
subroutine, public fftsg1dm(fsign, trans_in, trans_out, n, m, ldx_in, ldy_in, ldx_out, ldy_out, zin, zout, scale)
...
Definition fftsg_lib.F:141
subroutine, public fftsg_do_cleanup()
...
Definition fftsg_lib.F:34
subroutine, public fftsg3d(fft_in_place, fsign, scale, n, zin, zout)
...
Definition fftsg_lib.F:79
subroutine, public fftw3_do_cleanup(wisdom_file, ionode, export_wisdom)
...
Definition fftw3_lib.F:198
subroutine, public fftw3_destroy_plan(plan)
...
Definition fftw3_lib.F:1114
subroutine, public fftw3_get_lengths(data, max_length)
...
Definition fftw3_lib.F:309
subroutine, public fftw3_create_plan_1d(plan, zin, zout)
...
Definition fftw3_lib.F:1039
subroutine, public fftw3_create_plan_3d(plan, zin, zout)
...
Definition fftw3_lib.F:718
subroutine, public fftw33d(plan, scale, zin, zout, stat)
...
Definition fftw3_lib.F:949
subroutine, public fftw3_do_init(wisdom_file, plan_style)
...
Definition fftw3_lib.F:242
subroutine, public fftw31dm(plan, zin, zout, scale, stat)
...
Definition fftw3_lib.F:1150