Coverage for gpaw/test/lcao/test_kpts_many_combinations.py: 93%

76 statements  

« prev     ^ index     » next       coverage.py v7.7.1, created at 2025-07-08 00:17 +0000

1import pytest 

2from itertools import count 

3from ase.build import bulk 

4from gpaw import GPAW 

5from gpaw.mpi import world 

6from gpaw.utilities import compiled_with_sl 

7 

8 

9def ikwargs(): 

10 for augment_grids in [False, True]: 

11 for sl_auto in ([0, 1] if compiled_with_sl() else [0]): 

12 if world.size == 16: 

13 # This won't happen in ordinary test suite 

14 parsizes = [[4, 2, 2], [2, 4, 2], [2, 2, 4]] 

15 elif world.size == 8: 

16 parsizes = [[2, 2, 2]] 

17 elif world.size == 4: 

18 parsizes = [[1, 2, 2]] 

19 elif world.size == 2: 

20 parsizes = [[1, 1, 2]] 

21 else: 

22 assert world.size == 1 

23 parsizes = [[1, 1, 1]] 

24 for kpt, band, domain in parsizes: 

25 parallel = dict(kpt=kpt, 

26 band=band, 

27 domain=domain, 

28 sl_auto=sl_auto, 

29 augment_grids=augment_grids) 

30 yield dict(parallel=parallel) 

31 

32 

33@pytest.mark.old_gpaw_only 

34def test_lcao_kpts_many_combinations(in_tmp_dir): 

35 counter = count() 

36 

37 for spinpol in [False, True]: 

38 # We want a non-trivial cell: 

39 atoms0 = bulk('Ti') * (2, 1, 1) 

40 atoms0.cell[0] *= 1.2 

41 # We want most arrays to be different so we can detect ordering/shape 

42 # trouble: 

43 atoms0.symbols = 'HOFePb' 

44 atoms0.rattle(stdev=0.1) 

45 

46 if spinpol: 

47 atoms0.set_initial_magnetic_moments([1.0] * len(atoms0)) 

48 

49 kwargs = [] 

50 energies = [] 

51 eerrs = [] 

52 forces = [] 

53 ferrs = [] 

54 

55 from time import time 

56 for kwargs in ikwargs(): 

57 i = next(counter) 

58 

59 if world.rank == 0: 

60 print(i, kwargs) 

61 

62 if kwargs['parallel']['kpt'] == 4 and not spinpol: 

63 continue # Core without kpoints 

64 

65 calc = GPAW( 

66 mode='lcao', 

67 basis='sz(dzp)', 

68 xc='PBE', h=0.3, 

69 symmetry={'point_group': False}, # No symmetry here anyway 

70 txt='gpaw.{:02d}.spin{}.txt'.format(int(spinpol), i), 

71 kpts=(4, 1, 1), 

72 convergence={'maximum iterations': 2}, 

73 **kwargs) 

74 atoms = atoms0.copy() 

75 t1 = time() 

76 atoms.calc = calc 

77 e = atoms.get_potential_energy() 

78 f = atoms.get_forces() 

79 t2 = time() 

80 if world.rank == 0: 

81 print('T', t2 - t1) 

82 energies.append(e) 

83 forces.append(f) 

84 corrname = calc.wfs.atomic_correction.name 

85 if kwargs['parallel']['sl_auto']: 

86 assert corrname == 'sparse' 

87 else: 

88 assert corrname == 'dense' 

89 

90 if energies: 

91 eerr = abs(e - energies[0]) 

92 ferr = abs(f - forces[0]).max() 

93 eerrs.append(eerr) 

94 ferrs.append(ferr) 

95 if world.rank == 0: 

96 print('Eerr {} Ferr {}'.format(eerr, ferr)) 

97 print() 

98 

99 if world.rank == 0: 

100 print('eerrs', eerrs) 

101 print('ferrs', ferrs) 

102 

103 maxeerr = max(eerrs) 

104 maxferr = max(ferrs) 

105 print('maxeerr', maxeerr) 

106 print('maxferr', maxferr) 

107 assert maxeerr < 1e-9, maxeerr 

108 assert maxferr < 1e-10, maxferr