Coverage for gpaw/elph/gpts.py: 89%
44 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
1from __future__ import annotations
3import numpy as np
4from ase import Atoms
5from gpaw.utilities.gpts import get_number_of_grid_points
6from gpaw.wavefunctions.lcao import LCAO
7from gpaw.wavefunctions.pw import PW
10def obtain_gpts_suggestion(cell_cv, ecut, h, print_suggestions=False):
11 """Compare PW and LCAO gpts and returns tighter one.
13 When two separate simulations using different calculators need to use the
14 same real space grid, like in the electron-phonon coupling case, it might
15 be necessary to specify gpts=(...) explicitly. This tool helps with finding
16 the correct values for a combination of PW and LCAO mode calculations.
18 Parameters
19 ----------
20 cell_cv: np.ndarray
21 cell vector array
22 ecut: int, float
23 planewave cutoff to be used in PW mode
24 h: float
25 intended maximal grid spacing in LCAO mode
26 print_suggestions: bool
27 if True, prints human readable information
28 """
29 Npw_c = get_number_of_grid_points(cell_cv, mode=PW(ecut))
30 Nlcao_c = get_number_of_grid_points(cell_cv, h=h, mode=LCAO())
32 Nopt_c = np.maximum(Nlcao_c, (Npw_c / 4 + 0.5).astype(int) * 4)
34 if print_suggestions:
35 print(f'PW({ecut:3.0f}) -> gpts={list(Npw_c)}')
36 print(f'LCAO, h={h:1.3f} -> gpts={list(Nlcao_c)}')
37 print(f'Recommended for elph: gpts={list(Nopt_c)}')
39 if np.all(Npw_c == Nlcao_c):
40 print(' Both sets of gpts the same. No action needed.')
41 if np.any(Npw_c < Nopt_c):
42 print(f' Add "gpts={Nopt_c.tolist()}" to PW mode calculator.')
43 if np.any(Nlcao_c < Nopt_c):
44 print(f' Use "gpts={list(Nopt_c)}" instead of "h={h:1.3f}" ' +
45 'in LCAO calculator.')
47 return Nopt_c
50def main(argv: list[str] = None) -> None:
51 import argparse
53 from ase.io import read
55 parser = argparse.ArgumentParser(
56 prog='python3 -m gpaw.utilities.gpts',
57 description='Calculate optimal gpts size between PW and LCAO mode.')
58 add = parser.add_argument
59 add('file', metavar='input-file',
60 help='ASE readable structure file.')
61 add('-e', '--ecut', type=float,
62 help='Cutoff "ecut" used in PW mode.')
63 add('-g', '--grid-spacing', type=float,
64 help='Maximal grid spacing "h" used in LCAO mode.')
65 add('-s', '--super-cell', default='1,1,1',
66 help='Supercell size. Example: "-s 2,2,2".')
68 args = parser.parse_intermixed_args(argv)
69 if not args.ecut or not args.grid_spacing:
70 parser.print_help()
71 raise SystemExit
73 sc = []
74 for value in args.super_cell.split(','):
75 sc.append(int(value))
77 atoms = read(args.file)
78 assert isinstance(atoms, Atoms)
79 atoms_sc = atoms * sc
80 cell_cv = atoms_sc.get_cell()
81 obtain_gpts_suggestion(cell_cv, args.ecut, args.grid_spacing, True)
84if __name__ == '__main__':
85 main()