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

1from __future__ import annotations 

2 

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 

8 

9 

10def obtain_gpts_suggestion(cell_cv, ecut, h, print_suggestions=False): 

11 """Compare PW and LCAO gpts and returns tighter one. 

12 

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. 

17 

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()) 

31 

32 Nopt_c = np.maximum(Nlcao_c, (Npw_c / 4 + 0.5).astype(int) * 4) 

33 

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)}') 

38 

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.') 

46 

47 return Nopt_c 

48 

49 

50def main(argv: list[str] = None) -> None: 

51 import argparse 

52 

53 from ase.io import read 

54 

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".') 

67 

68 args = parser.parse_intermixed_args(argv) 

69 if not args.ecut or not args.grid_spacing: 

70 parser.print_help() 

71 raise SystemExit 

72 

73 sc = [] 

74 for value in args.super_cell.split(','): 

75 sc.append(int(value)) 

76 

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) 

82 

83 

84if __name__ == '__main__': 

85 main()