(git:5e7fe52)
Loading...
Searching...
No Matches
kpoint_lattice_fft_unittest.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!--------------------------------------------------------------------------------------------------!
8 USE fft_tools, ONLY: finalize_fft,&
10 USE kinds, ONLY: dp
19 USE mathconstants, ONLY: gaussi,&
20 twopi,&
21 z_zero
22 USE message_passing, ONLY: mp_comm_type,&
25
26 IMPLICIT NONE
27
28 INTEGER, PARAMETER :: base_block = 2, base_cell = 8, base_n = 16, &
29 base_ncol = 3, ncell = 31, nkp = 64, &
30 nround = 16, nselected = 3
31 INTEGER, PARAMETER :: large_block = 1000, large_ncol = 1000, &
32 large_num_pe = 16
33 COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: inverse_k
34 COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :, :) :: state_inverse_k
35 COMPLEX(KIND=dp), DIMENSION(2, 3, nkp) :: direct, transformed
36 COMPLEX(KIND=dp), DIMENSION(2, 3, nround) :: reconstructed, round_k
37 COMPLEX(KIND=dp), DIMENSION(2, 3, nselected) :: selected_transformed
38 INTEGER :: d, i, icell, info, j, jcell, ik, ix, iy, iz
39 INTEGER, ALLOCATABLE, DIMENSION(:) :: correction_indices
40 INTEGER, DIMENSION(3) :: base_dims, delta, large_dims
41 INTEGER, DIMENSION(3, base_cell) :: base_index
42 INTEGER, DIMENSION(3) :: nkp_grid
43 INTEGER, DIMENSION(3, ncell) :: index_to_cell
44 INTEGER, DIMENSION(3, nround) :: round_index
45 INTEGER, DIMENSION(nselected) :: selected_kpoints
46 LOGICAL :: used_fft
47 REAL(kind=dp), DIMENSION(3, 3) :: hmat
48 REAL(kind=dp) :: base_residual_norm, corrected_projection_error, &
49 corrected_residual_norm, cost_ratio, &
50 expected_cost_ratio, imaginary_residual, &
51 large_block_real, large_ncell_real, &
52 large_ncol_real, projection_error
53 REAL(kind=dp), DIMENSION(3, base_cell) :: base_xkp
54 REAL(kind=dp), DIMENSION(base_n, base_n) :: base_overlap
55 REAL(kind=dp), DIMENSION(base_n, base_n) :: defect_operator
56 REAL(kind=dp), DIMENSION(base_n, base_ncol) :: base_input, base_input_rotated, &
57 base_output, base_output_rotated, &
58 base_state_output, defect_residual
59 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: coarse_inverse, defect_base_output, &
60 defect_corrected_output, local_operator, &
61 selected_output, selected_rhs
62 REAL(kind=dp), DIMENSION(base_ncol, base_ncol) :: column_rotation
63 REAL(kind=dp), DIMENSION(3, nkp) :: xkp, xkp_bad
64 REAL(kind=dp), DIMENSION(2, 3, ncell) :: values_rs
65 REAL(kind=dp), DIMENSION(2, 3, nround) :: round_rs
66 TYPE(mp_comm_type) :: mp_comm
67
68 CALL mp_world_init(mp_comm)
69 CALL init_fft("FFTSG", alltoall=.false., pool_limit=4, &
70 wisdom_file="", plan_style=1)
71
72 nkp_grid = [4, 4, 4]
73 hmat = reshape([4.0_dp, 0.1_dp, 0.2_dp, &
74 0.0_dp, 5.0_dp, 0.3_dp, &
75 0.0_dp, 0.0_dp, 6.0_dp], [3, 3])
76
77 ik = 0
78 DO iz = 0, nkp_grid(3) - 1
79 DO iy = 0, nkp_grid(2) - 1
80 DO ix = 0, nkp_grid(1) - 1
81 ik = ik + 1
82 xkp(:, ik) = [(real(ix, dp) + 0.5_dp)/real(nkp_grid(1), dp), &
83 REAL(iy, dp)/REAL(nkp_grid(2), dp), &
84 (REAL(iz, dp) + 0.25_dp)/REAL(nkp_grid(3), dp)]
85 END DO
86 END DO
87 END DO
88 IF (.NOT. regular_kpoint_grid(xkp, nkp_grid)) error stop "Regular k-point grid not recognized"
89
90 DO icell = 1, ncell
91 index_to_cell(:, icell) = [modulo(3*icell + 1, 11) - 5, &
92 modulo(5*icell + 2, 9) - 4, &
93 modulo(7*icell + 3, 7) - 3]
94 DO d = 1, 3
95 values_rs(1, d, icell) = sin(0.13_dp*real(icell + 2*d, dp))
96 values_rs(2, d, icell) = cos(0.17_dp*real(2*icell - d, dp))
97 END DO
98 END DO
99
100 CALL cell_to_k_grid_fft(values_rs, index_to_cell, xkp, nkp_grid, transformed, used_fft)
101 IF (.NOT. used_fft) error stop "Complete regular grid did not use lattice FFT"
102 CALL direct_reference(values_rs, index_to_cell, xkp, direct)
103 IF (maxval(abs(transformed - direct)) > 2.0e-12_dp) THEN
104 error stop "Shifted lattice FFT differs from direct transform"
105 END IF
106
107 selected_kpoints = [2, 31, 64]
108 CALL cell_to_k_grid_fft(values_rs, index_to_cell, xkp, nkp_grid, selected_transformed, &
109 used_fft, selected_kpoints=selected_kpoints)
110 IF (.NOT. used_fft) error stop "Selected distributed output did not use lattice FFT"
111 IF (maxval(abs(selected_transformed - direct(:, :, selected_kpoints))) > 2.0e-12_dp) THEN
112 error stop "Selected lattice-FFT output differs from the full transform"
113 END IF
114
115 CALL cell_to_k_grid_fft(values_rs, index_to_cell, xkp, nkp_grid, transformed, used_fft, 2, hmat)
116 IF (.NOT. used_fft) error stop "Derivative did not use lattice FFT"
117 CALL direct_reference(values_rs, index_to_cell, xkp, direct, 2, hmat)
118 IF (maxval(abs(transformed - direct)) > 5.0e-12_dp) THEN
119 error stop "Lattice-FFT derivative differs from direct transform"
120 END IF
121
122 nkp_grid = [4, 4, 1]
123 ik = 0
124 DO iy = 0, nkp_grid(2) - 1
125 DO ix = 0, nkp_grid(1) - 1
126 ik = ik + 1
127 xkp(:, ik) = [(real(ix, dp) + 0.5_dp)/real(nkp_grid(1), dp), &
128 REAL(iy, dp)/REAL(nkp_grid(2), dp), 0.0_dp]
129 END DO
130 END DO
131 CALL cell_to_k_grid_fft(values_rs, index_to_cell, xkp(:, 1:ik), nkp_grid, &
132 transformed(:, :, 1:ik), used_fft)
133 IF (.NOT. used_fft) error stop "Singleton grid direction did not use padded lattice FFT"
134 CALL direct_reference(values_rs, index_to_cell, xkp(:, 1:ik), direct(:, :, 1:ik))
135 IF (maxval(abs(transformed(:, :, 1:ik) - direct(:, :, 1:ik))) > 2.0e-12_dp) THEN
136 error stop "Padded lattice FFT differs from direct transform"
137 END IF
138
139 icell = 0
140 DO iy = 0, nkp_grid(2) - 1
141 DO ix = 0, nkp_grid(1) - 1
142 icell = icell + 1
143 round_index(:, icell) = [ix, iy, 0]
144 round_rs(:, :, icell) = values_rs(:, :, icell)
145 END DO
146 END DO
147 CALL cell_to_k_grid_fft(round_rs, round_index, xkp(:, 1:ik), nkp_grid, round_k, used_fft)
148 IF (.NOT. used_fft) error stop "Round-trip forward transform did not use lattice FFT"
149 CALL k_grid_to_cell_fft(round_k, xkp(:, 1:ik), nkp_grid, round_index, reconstructed, used_fft)
150 IF (.NOT. used_fft) error stop "Round-trip inverse transform did not use lattice FFT"
151 IF (maxval(abs(reconstructed - cmplx(round_rs, kind=dp))) > 3.0e-12_dp) THEN
152 error stop "Forward/inverse lattice-FFT round trip is inconsistent"
153 END IF
154
155 nkp_grid = [4, 4, 4]
156
157 xkp_bad = xkp
158 xkp_bad(1, nkp) = xkp_bad(1, nkp) + 0.03125_dp
159 CALL cell_to_k_grid_fft(values_rs, index_to_cell, xkp_bad, nkp_grid, transformed, used_fft)
160 IF (used_fft) error stop "Irregular k-point list incorrectly used lattice FFT"
161 CALL direct_reference(values_rs, index_to_cell, xkp_bad, direct)
162 IF (maxval(abs(transformed - direct)) > 1.0e-14_dp) THEN
163 error stop "Direct lattice-transform fallback is inconsistent"
164 END IF
165
166 ! Verify the block-circulant inverse against direct matrix application and right covariance.
167 base_dims = [4, 2, 1]
168 CALL lattice_grid(base_dims, base_index, base_xkp)
169 base_overlap = 0.0_dp
170 DO jcell = 1, base_cell
171 DO icell = 1, base_cell
172 delta = modulo(base_index(:, icell) - base_index(:, jcell), base_dims)
173 DO i = 1, base_block
174 IF (all(delta == 0)) THEN
175 base_overlap((icell - 1)*base_block + i, (jcell - 1)*base_block + i) = &
176 2.8_dp + 0.2_dp*real(i, kind=dp)
177 ELSE IF ((delta(1) == 1 .OR. delta(1) == base_dims(1) - 1) .AND. &
178 delta(2) == 0) THEN
179 base_overlap((icell - 1)*base_block + i, (jcell - 1)*base_block + i) = -0.12_dp
180 ELSE IF (delta(1) == 0 .AND. delta(2) == 1) THEN
181 base_overlap((icell - 1)*base_block + i, (jcell - 1)*base_block + i) = -0.08_dp
182 END IF
183 END DO
184 IF (all(delta == 0)) THEN
185 base_overlap((icell - 1)*base_block + 1, (jcell - 1)*base_block + 2) = 0.15_dp
186 base_overlap((icell - 1)*base_block + 2, (jcell - 1)*base_block + 1) = 0.15_dp
187 END IF
188 END DO
189 END DO
190 DO j = 1, base_ncol
191 DO i = 1, base_n
192 base_input(i, j) = sin(0.11_dp*real(2*i + 3*j, kind=dp))
193 END DO
194 END DO
195 CALL build_lattice_inverse(base_overlap, base_dims, inverse_k, projection_error, used_fft, info)
196 IF (info /= 0) error stop "Positive lattice overlap failed block Cholesky inversion"
197 IF (.NOT. used_fft) error stop "Block-circulant overlap construction did not use lattice FFT"
198 IF (projection_error > 2.0e-15_dp) error stop "Exact block-circulant overlap was changed by projection"
199 IF (lattice_fft_auto_select(base_dims, base_block, base_ncol, 1, 1, &
200 projection_error, used_fft, info)) THEN
201 error stop "Cost-aware lattice-FFT AUTO accepted a tiny eight-cell operator"
202 END IF
203 IF (.NOT. lattice_fft_auto_select(base_dims, 6, 8, 1, 2, &
204 projection_error, used_fft, info)) THEN
205 error stop "Cost-aware lattice-FFT AUTO rejected an economical eight-cell operator"
206 END IF
207 IF (lattice_fft_auto_select([4, 1, 1], 6, 8, 1, 2, &
208 projection_error, used_fft, info)) THEN
209 error stop "Conservative lattice-FFT AUTO accepted fewer than eight cells"
210 END IF
211 IF (lattice_fft_auto_select(base_dims, 6, 8, 1, 2, 2.0e-3_dp, used_fft, info)) THEN
212 error stop "Conservative lattice-FFT AUTO accepted a large projection error"
213 END IF
214 IF (lattice_fft_auto_select(base_dims, 6, 8, 17, 2, &
215 projection_error, used_fft, info)) THEN
216 error stop "Storage-aware lattice-FFT AUTO accepted too many state operators"
217 END IF
218 IF (lattice_fft_cost_ratio(base_dims, base_block, base_ncol, 1) <= 0.8_dp) THEN
219 error stop "Lattice-FFT cost estimate missed the tiny-batch overhead"
220 END IF
221 large_dims = [100, 100, 1]
222 large_ncell_real = real(product(large_dims), kind=dp)
223 large_block_real = real(large_block, kind=dp)
224 large_ncol_real = real(large_ncol, kind=dp)
225 expected_cost_ratio = ( &
226 large_ncell_real*large_block_real**2*large_ncol_real + &
227 4.0_dp*large_ncell_real*large_block_real*large_ncol_real* &
228 log(large_ncell_real)/log(2.0_dp) + &
229 8.0_dp*large_ncell_real*large_block_real + &
230 2.0_dp*large_ncell_real*large_block_real*large_ncol_real* &
231 log(real(large_num_pe + 1, kind=dp))/log(2.0_dp))/ &
232 ((large_ncell_real*large_block_real)**2*large_ncol_real)
233 cost_ratio = lattice_fft_cost_ratio(large_dims, large_block, large_ncol, large_num_pe)
234 IF (abs(cost_ratio - expected_cost_ratio) > 1.0e-14_dp*expected_cost_ratio) THEN
235 error stop "Lattice-FFT cost estimate overflowed for a large problem"
236 END IF
237 IF (abs(lattice_fft_storage_ratio(base_dims, 1) - 0.25_dp) > 1.0e-14_dp) THEN
238 error stop "Lattice-FFT storage estimate is inconsistent"
239 END IF
240 IF (abs(lattice_local_cost_ratio(base_dims, 1) - 0.28125_dp) > 1.0e-14_dp) THEN
241 error stop "Lattice local-correction cost estimate is inconsistent"
242 END IF
243 IF (abs(lattice_local_storage_ratio(base_dims, 3, 1) - 0.421875_dp) > 1.0e-14_dp) THEN
244 error stop "Lattice local-correction storage estimate is inconsistent"
245 END IF
246 CALL apply_lattice_inverse_dense(inverse_k, base_dims, base_input, base_output, &
247 used_fft, imaginary_residual)
248 IF (.NOT. used_fft) error stop "Block-circulant inverse application did not use lattice FFT"
249 IF (imaginary_residual > 3.0e-13_dp) error stop "Lattice inverse did not reconstruct a real matrix"
250 IF (maxval(abs(matmul(base_overlap, base_output) - base_input)) > 2.0e-11_dp) THEN
251 error stop "FFT block-circulant inverse differs from the dense operator inverse"
252 END IF
253
254 ALLOCATE (state_inverse_k(base_block, base_block, base_cell, base_ncol))
255 DO j = 1, base_ncol
256 state_inverse_k(:, :, :, j) = (0.5_dp + 0.25_dp*real(j, kind=dp))*inverse_k
257 END DO
258 CALL apply_lattice_state_inverse_dense(state_inverse_k, base_dims, base_input, &
259 base_state_output, used_fft, imaginary_residual)
260 IF (.NOT. used_fft) error stop "State-dependent inverse application did not use lattice FFT"
261 DO j = 1, base_ncol
262 IF (maxval(abs(base_state_output(:, j) - &
263 (0.5_dp + 0.25_dp*real(j, kind=dp))*base_output(:, j))) > 3.0e-12_dp) THEN
264 error stop "State-dependent lattice inverse used the wrong column operator"
265 END IF
266 END DO
267 DEALLOCATE (state_inverse_k)
268
269 column_rotation = 0.0_dp
270 column_rotation(1, 1) = cos(0.31_dp)
271 column_rotation(1, 2) = -sin(0.31_dp)
272 column_rotation(2, 1) = sin(0.31_dp)
273 column_rotation(2, 2) = cos(0.31_dp)
274 column_rotation(3, 3) = 1.0_dp
275 base_input_rotated = matmul(base_input, column_rotation)
276 CALL apply_lattice_inverse_dense(inverse_k, base_dims, base_input_rotated, &
277 base_output_rotated, used_fft)
278 IF (maxval(abs(base_output_rotated - matmul(base_output, column_rotation))) > 3.0e-12_dp) THEN
279 error stop "FFT lattice base is not right-covariant under orbital rotations"
280 END IF
281
282 ! Add one localized positive defect and verify the balanced cell correction.
283 defect_operator = base_overlap
284 defect_operator(5, 5) = defect_operator(5, 5) + 0.90_dp
285 defect_operator(6, 6) = defect_operator(6, 6) + 0.60_dp
286 CALL build_lattice_inverse(defect_operator, base_dims, inverse_k, projection_error, used_fft, info)
287 IF (info /= 0 .OR. .NOT. used_fft) error stop "Defective lattice operator failed construction"
288 IF (projection_error <= 1.0e-3_dp) error stop "Localized defect did not break lattice translations"
289 IF (lattice_fft_auto_select(base_dims, 6, 8, 1, 2, projection_error, used_fft, info)) THEN
290 error stop "Lattice-FFT AUTO accepted a localized defect"
291 END IF
293 defect_operator, base_dims, 1, correction_indices, local_operator, coarse_inverse, &
294 corrected_projection_error, info)
295 IF (info /= 0) error stop "Local correction coarse inverse failed"
296 IF (any(correction_indices /= [5, 6])) error stop "Local correction selected the wrong defect cell"
297 IF (corrected_projection_error >= projection_error) THEN
298 error stop "Local correction did not reduce the non-circulant residual"
299 END IF
300
301 ALLOCATE (defect_base_output(base_n, base_ncol), defect_corrected_output(base_n, base_ncol))
302 CALL apply_lattice_inverse_dense(inverse_k, base_dims, base_input, defect_base_output, used_fft)
303 CALL apply_balanced_local_inverse(inverse_k, base_dims, correction_indices, local_operator, &
304 coarse_inverse, base_input, defect_corrected_output)
305 defect_residual = matmul(defect_operator, defect_base_output) - base_input
306 base_residual_norm = norm2(defect_residual)
307 defect_residual = matmul(defect_operator, defect_corrected_output) - base_input
308 corrected_residual_norm = norm2(defect_residual)
309 IF (corrected_residual_norm >= base_residual_norm) THEN
310 error stop "Balanced local correction did not improve inverse application"
311 END IF
312 IF (sum(base_input*defect_corrected_output) <= 0.0_dp) THEN
313 error stop "Balanced local correction lost positive definiteness"
314 END IF
315
316 ALLOCATE (selected_rhs(base_n, SIZE(correction_indices)), &
317 selected_output(base_n, SIZE(correction_indices)))
318 selected_rhs(:, :) = local_operator
319 CALL apply_balanced_local_inverse(inverse_k, base_dims, correction_indices, local_operator, &
320 coarse_inverse, selected_rhs, selected_output)
321 selected_rhs = 0.0_dp
322 DO i = 1, SIZE(correction_indices)
323 selected_rhs(correction_indices(i), i) = 1.0_dp
324 END DO
325 IF (maxval(abs(selected_output - selected_rhs)) > 3.0e-11_dp) THEN
326 error stop "Balanced local correction is not exact in its selected subspace"
327 END IF
328 DEALLOCATE (coarse_inverse, correction_indices, defect_base_output, defect_corrected_output, &
329 local_operator, selected_output, selected_rhs)
330 DEALLOCATE (inverse_k)
331
332 CALL finalize_fft(mp_comm, "")
333 CALL mp_world_finalize()
334
335CONTAINS
336
337! **************************************************************************************************
338!> \brief Apply the balanced two-level inverse used by the production local correction.
339!> \param inverse_k block-circulant base inverse
340!> \param lattice_dims replicated-cell dimensions
341!> \param correction_indices selected coordinate basis
342!> \param operator_columns columns A U
343!> \param coarse_inverse inverse of U^T A U
344!> \param input right-hand sides
345!> \param output corrected inverse action
346! **************************************************************************************************
347 SUBROUTINE apply_balanced_local_inverse(inverse_k, lattice_dims, correction_indices, &
348 operator_columns, coarse_inverse, input, output)
349
350 COMPLEX(KIND=dp), DIMENSION(:, :, :), INTENT(IN) :: inverse_k
351 INTEGER, DIMENSION(3), INTENT(IN) :: lattice_dims
352 INTEGER, DIMENSION(:), INTENT(IN) :: correction_indices
353 REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: operator_columns, coarse_inverse, input
354 REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT) :: output
355
356 INTEGER :: i
357 LOGICAL :: used_fft
358 REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: base_input, coarse_input, &
359 coarse_projected, coarse_residual, &
360 coarse_rhs
361
362 ALLOCATE (base_input(SIZE(input, 1), SIZE(input, 2)), &
363 coarse_input(SIZE(correction_indices), SIZE(input, 2)), &
364 coarse_projected(SIZE(correction_indices), SIZE(input, 2)), &
365 coarse_residual(SIZE(correction_indices), SIZE(input, 2)), &
366 coarse_rhs(SIZE(correction_indices), SIZE(input, 2)))
367 DO i = 1, SIZE(correction_indices)
368 coarse_input(i, :) = input(correction_indices(i), :)
369 END DO
370 coarse_rhs(:, :) = matmul(coarse_inverse, coarse_input)
371 base_input(:, :) = input - matmul(operator_columns, coarse_rhs)
372 CALL apply_lattice_inverse_dense(inverse_k, lattice_dims, base_input, output, used_fft)
373 IF (.NOT. used_fft) error stop "Balanced correction base did not use lattice FFT"
374 coarse_projected(:, :) = matmul(transpose(operator_columns), output)
375 coarse_residual(:, :) = matmul(coarse_inverse, coarse_projected)
376 output(correction_indices, :) = output(correction_indices, :) + coarse_rhs - coarse_residual
377 DEALLOCATE (base_input, coarse_input, coarse_projected, coarse_residual, coarse_rhs)
378
379 END SUBROUTINE apply_balanced_local_inverse
380
381! **************************************************************************************************
382!> \brief ...
383!> \param values_rs ...
384!> \param index_to_cell ...
385!> \param xkp ...
386!> \param values_k ...
387!> \param deriv_direction ...
388!> \param hmat ...
389! **************************************************************************************************
390 SUBROUTINE direct_reference(values_rs, index_to_cell, xkp, values_k, deriv_direction, hmat)
391
392 REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN) :: values_rs
393 INTEGER, DIMENSION(:, :), INTENT(IN) :: index_to_cell
394 REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: xkp
395 COMPLEX(KIND=dp), DIMENSION(:, :, :), INTENT(OUT) :: values_k
396 INTEGER, INTENT(IN), OPTIONAL :: deriv_direction
397 REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN), &
398 OPTIONAL :: hmat
399
400 COMPLEX(KIND=dp) :: factor
401 INTEGER :: icell, ik
402 REAL(KIND=dp), DIMENSION(3) :: cell_index_real, cell_vector
403
404 values_k = z_zero
405 DO ik = 1, SIZE(xkp, 2)
406 DO icell = 1, SIZE(values_rs, 3)
407 factor = exp(gaussi*twopi*sum(xkp(:, ik)*real(index_to_cell(:, icell), kind=dp)))
408 IF (PRESENT(deriv_direction)) THEN
409 cell_index_real = real(index_to_cell(:, icell), kind=dp)
410 cell_vector = matmul(hmat, cell_index_real)
411 factor = factor*gaussi*cell_vector(deriv_direction)
412 END IF
413 values_k(:, :, ik) = values_k(:, :, ik) + factor*values_rs(:, :, icell)
414 END DO
415 END DO
416
417 END SUBROUTINE direct_reference
418
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
subroutine apply_balanced_local_inverse(inverse_k, lattice_dims, correction_indices, operator_columns, coarse_inverse, input, output)
Apply the balanced two-level inverse used by the production local correction.
program kpoint_lattice_fft_unittest
subroutine, public init_fft(fftlib, alltoall, pool_limit, wisdom_file, plan_style)
...
Definition fft_tools.F:181
subroutine, public finalize_fft(para_env, wisdom_file)
does whatever is needed to finalize the current fft setup
Definition fft_tools.F:208
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Batched lattice Fourier transforms for complete regular k-point grids.
subroutine, public k_grid_to_cell_fft(values_k, xkp, nkp_grid, index_to_cell, values_rs, used_fft)
Transform complete reciprocal-grid data back to image-cell values.
subroutine, public cell_to_k_grid_fft(values_rs, index_to_cell, xkp, nkp_grid, values_k, used_fft, deriv_direction, hmat, selected_kpoints)
Transform a batch of real matrices from image cells to every supplied k point.
logical function, public regular_kpoint_grid(xkp, nkp_grid, grid_index, k_offset)
Test and map a complete, uniformly shifted reciprocal grid.
Block-circulant inverse operators for replicated-cell OT preconditioners.
subroutine, public build_lattice_local_correction(operator_matrix, lattice_dims, local_cell_count, correction_indices, operator_columns, coarse_inverse, corrected_projection_error, info)
Build a balanced local correction for selected non-circulant cell blocks.
subroutine, public apply_lattice_inverse_dense(inverse_k, lattice_dims, matrix_in, matrix_out, used_fft, imaginary_residual)
Apply inverse Fourier blocks to a dense cell-major real matrix.
subroutine, public apply_lattice_state_inverse_dense(inverse_k, lattice_dims, matrix_in, matrix_out, used_fft, imaginary_residual, state_indices)
Apply one inverse Fourier operator to every column of a dense real matrix.
subroutine, public build_lattice_inverse(operator_matrix, lattice_dims, inverse_k, projection_error, used_fft, info)
Project a cell-major SPD operator onto lattice translations and invert its Fourier blocks.
pure real(kind=dp) function, public lattice_local_storage_ratio(lattice_dims, operator_count, local_cell_count)
Estimate balanced-local-correction storage relative to one dense real operator.
pure real(kind=dp) function, public lattice_fft_storage_ratio(lattice_dims, operator_count)
Estimate reciprocal-block storage relative to one dense real operator.
pure logical function, public lattice_fft_auto_select(lattice_dims, block_size, rhs_count, operator_count, num_pe, projection_error, used_fft, info)
Conservative error-, work-, and storage-aware AUTO selector.
subroutine, public lattice_grid(lattice_dims, index_to_cell, xkp)
Enumerate a regular direct/reciprocal lattice with the first direction varying fastest.
pure real(kind=dp) function, public lattice_local_cost_ratio(lattice_dims, local_cell_count)
Estimate balanced-local-correction work relative to a dense inverse application.
pure real(kind=dp) function, public lattice_fft_cost_ratio(lattice_dims, block_size, rhs_count, num_pe)
Estimate lattice-FFT application work relative to a dense inverse application.
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public gaussi
real(kind=dp), parameter, public twopi
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
subroutine, public mp_world_init(mp_comm)
initializes the system default communicator
subroutine, public mp_world_finalize()
Finalize the system default communicator and MPI when CP2K owns MPI.