22 #include "../base/base_uses.f90"
29 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'pw_grid_info'
47 icommensurate, ref_grid, n_orig)
RESULT(n)
49 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: hmat
50 REAL(kind=
dp),
INTENT(IN) :: cutoff
51 LOGICAL,
INTENT(IN) :: spherical, odd, fft_usage
52 INTEGER,
INTENT(IN) :: ncommensurate, icommensurate
53 TYPE(pw_grid_type),
INTENT(IN),
OPTIONAL :: ref_grid
54 INTEGER,
INTENT(IN),
OPTIONAL :: n_orig(3)
55 INTEGER,
DIMENSION(3) :: n
57 INTEGER :: my_icommensurate
59 IF (ncommensurate > 0)
THEN
60 my_icommensurate = icommensurate
61 cpassert(icommensurate > 0)
62 cpassert(icommensurate <= ncommensurate)
67 IF (my_icommensurate > 1)
THEN
68 cpassert(
PRESENT(ref_grid))
69 n = ref_grid%npts/2**(my_icommensurate - 1)
70 cpassert(all(ref_grid%npts == n*2**(my_icommensurate - 1)))
73 n = pw_grid_find_n(hmat, cutoff=cutoff, fft_usage=fft_usage, ncommensurate=ncommensurate, &
74 spherical=spherical, odd=odd, n_orig=n_orig)
91 FUNCTION pw_grid_find_n(hmat, cutoff, fft_usage, spherical, odd, ncommensurate, &
94 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: hmat
95 REAL(kind=
dp),
INTENT(IN) :: cutoff
96 LOGICAL,
INTENT(IN) :: fft_usage, spherical, odd
97 INTEGER,
INTENT(IN) :: ncommensurate
98 INTEGER,
INTENT(IN),
OPTIONAL :: n_orig(3)
99 INTEGER,
DIMENSION(3) :: n
101 INTEGER :: idir, my_icommensurate, &
102 my_ncommensurate, nsubgrid, &
103 nsubgrid_new, ntest(3), t_icommensurate
104 LOGICAL :: ftest, subgrid_is_ok
112 my_ncommensurate = ncommensurate
113 IF (my_ncommensurate > 0)
THEN
118 cpassert(my_icommensurate <= my_ncommensurate)
119 cpassert(my_icommensurate > 0 .OR. my_ncommensurate <= 0)
120 cpassert(my_ncommensurate >= 0)
122 IF (
PRESENT(n_orig))
THEN
125 cpassert(cutoff > 0.0_dp)
126 n = pw_grid_n_from_cutoff(hmat, cutoff)
132 IF (.NOT. spherical)
THEN
135 IF (my_ncommensurate > 0)
THEN
141 subgrid_is_ok = .true.
142 DO t_icommensurate = 1, my_ncommensurate - 1
143 nsubgrid = n(idir)/2**(my_ncommensurate - t_icommensurate)
145 subgrid_is_ok = (nsubgrid == nsubgrid_new) .AND. &
146 (
modulo(n(idir), 2**(my_ncommensurate - t_icommensurate)) == 0)
147 IF (.NOT. subgrid_is_ok)
EXIT
149 IF (subgrid_is_ok)
THEN
153 ntest(idir) = n(idir) + 1
162 IF (odd) n = n + mod(n + 1, 2)
167 IF (my_ncommensurate > 0)
THEN
168 DO my_icommensurate = 1, my_ncommensurate
169 ftest = any(
modulo(n, 2**(my_ncommensurate - my_icommensurate)) .NE. 0)
170 cpassert(.NOT. ftest)
174 END FUNCTION pw_grid_find_n
187 INTEGER,
DIMENSION(3),
INTENT(in) :: n
188 LOGICAL,
INTENT(in),
OPTIONAL :: odd
189 INTEGER,
DIMENSION(3) :: nout
194 IF (
PRESENT(odd)) my_odd = odd
195 cpassert(all(n >= 0))
224 FUNCTION pw_grid_n_from_cutoff(hmat, cutoff)
RESULT(n)
226 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: hmat
227 REAL(kind=
dp),
INTENT(IN) :: cutoff
228 INTEGER,
DIMENSION(3) :: n
231 REAL(kind=
dp) :: alat(3)
234 alat(i) = sum(hmat(:, i)**2)
236 cpassert(all(alat /= 0._dp))
237 n = 2*floor(sqrt(2.0_dp*cutoff*alat)/
twopi) + 1
239 END FUNCTION pw_grid_n_from_cutoff
248 INTEGER,
DIMENSION(3),
INTENT(in) :: npts
249 INTEGER,
DIMENSION(2, 3) :: bounds
251 bounds(1, :) = -npts/2
252 bounds(2, :) = bounds(1, :) + npts - 1
273 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts
274 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: h_inv
275 REAL(kind=
dp) :: cutoff
277 REAL(kind=
dp) :: gcut, gdum(3), length
281 gdum(:) =
twopi*h_inv(1, :)*real((npts(1) - 1)/2, kind=
dp)
282 length = sqrt(gdum(1)**2 + gdum(2)**2 + gdum(3)**2)
286 gdum(:) =
twopi*h_inv(2, :)*real((npts(2) - 1)/2, kind=
dp)
287 length = sqrt(gdum(1)**2 + gdum(2)**2 + gdum(3)**2)
288 gcut = min(gcut, length)
291 gdum(:) =
twopi*h_inv(3, :)*real((npts(3) - 1)/2, kind=
dp)
292 length = sqrt(gdum(1)**2 + gdum(2)**2 + gdum(3)**2)
293 gcut = min(gcut, length)
295 cutoff = gcut - 1.e-8_dp
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
real(kind=dp), parameter, public twopi
This module returns additional info on PW grids.
real(kind=dp) function, public pw_find_cutoff(npts, h_inv)
Given a grid and a box, calculate the corresponding cutoff *** This routine calculates the cutoff in ...
integer function, dimension(2, 3), public pw_grid_bounds_from_n(npts)
returns the bounds that distribute n points evenly around 0
integer function, dimension(3), public pw_grid_init_setup(hmat, cutoff, spherical, odd, fft_usage, ncommensurate, icommensurate, ref_grid, n_orig)
...
integer function, dimension(3), public pw_grid_n_for_fft(n, odd)
returns the closest number of points >= n, on which you can perform ffts