Coverage for gpaw/utilities/gpts.py: 96%
46 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-08 00:17 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-08 00:17 +0000
1import warnings
3import numpy as np
5from ase.units import Bohr, Hartree
7from gpaw.fftw import get_efficient_fft_size
8from gpaw.utilities import h2gpts
9from gpaw.wavefunctions.fd import FD
12def get_number_of_grid_points(cell_cv,
13 h=None,
14 mode=None,
15 realspace=None,
16 symmetry=None):
17 if mode is None:
18 mode = FD()
20 if realspace is None:
21 realspace = mode.name != 'pw'
23 if h is None:
24 if mode.name == 'pw':
25 h = np.pi / (4 * mode.ecut)**0.5
26 elif mode.name == 'lcao' and not realspace:
27 h = np.pi / (4 * 340 / Hartree)**0.5
28 else:
29 h = 0.2 / Bohr
31 if realspace or mode.name == 'fd':
32 N_c = h2gpts(h, cell_cv, 4)
33 else:
34 N_c = np.ceil((cell_cv**2).sum(1)**0.5 / h).astype(int)
35 if symmetry is None:
36 N_c = np.array([get_efficient_fft_size(N) for N in N_c])
37 else:
38 N_c = np.array([get_efficient_fft_size(N, n)
39 for N, n in zip(N_c, symmetry.gcd_c)])
41 if symmetry is not None:
42 ok = symmetry.check_grid(N_c)
43 if not ok:
44 warnings.warn(
45 'Initial realspace grid '
46 '({},{},{}) inconsistent with symmetries.'.format(*N_c))
47 # The grid is not symmetric enough. The essential problem
48 # is that we should start at some other Nmin_c and possibly with
49 # other gcd_c when getting the most efficient fft grids
50 gcd_c = symmetry.gcd_c.copy()
51 Nmin_c = N_c.copy()
52 for i in range(3):
53 for op_cc in symmetry.op_scc:
54 for i, o in enumerate((op_cc.T).flat):
55 i1, i2 = np.unravel_index(i, (3, 3))
56 if i1 == i2:
57 continue
58 if o:
59 # The axes are related and therefore they share
60 # lowest common multiple of gcd
61 gcd = np.lcm.reduce(gcd_c[[i1, i2]])
62 gcd_c[[i1, i2]] = gcd
63 # We just take the maximum of the two axes to make
64 # sure that they are divisible always
65 Nmin = np.max([Nmin_c[i1], Nmin_c[i2]])
66 Nmin_c[i1] = Nmin
67 Nmin_c[i2] = Nmin
69 N_c = np.array([get_efficient_fft_size(N, n)
70 for N, n in zip(Nmin_c, gcd_c)])
71 warnings.warn('Using symmetrized grid: ({},{},{}).\n'.format(*N_c))
72 ok = symmetry.check_grid(N_c)
73 assert ok, ('Grid still not constistent with symmetries '
74 '({},{},{})'.format(*N_c))
76 return N_c