Coverage for gpaw/test/lcao/test_lcao_parallel_kpt.py: 12%

92 statements  

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

1import sys 

2 

3import pytest 

4from ase.build import molecule 

5from gpaw.utilities import devnull 

6 

7from gpaw import GPAW, LCAO, FermiDirac, KohnShamConvergenceError 

8from gpaw.utilities import compiled_with_sl 

9from gpaw.forces import calculate_forces 

10from gpaw.mpi import world 

11 

12# Calculates energy and forces for various parallelizations 

13 

14pytestmark = pytest.mark.skipif(world.size < 4, 

15 reason='world.size < 4') 

16 

17 

18@pytest.mark.old_gpaw_only # doesn't work with new GPAW yet 

19def test_lcao_lcao_parallel_kpt(): 

20 tolerance = 4e-5 

21 

22 parallel = dict() 

23 

24 basekwargs = dict(mode=LCAO(atomic_correction='dense'), 

25 maxiter=3, 

26 nbands=6, 

27 h=0.3, 

28 kpts=(4, 4, 4), # 8 kpts in the IBZ 

29 parallel=parallel) 

30 

31 Eref = None 

32 Fref_av = None 

33 

34 def run(formula='H2O', vacuum=1.0, cell=None, pbc=1, **morekwargs): 

35 print(formula, parallel) 

36 system = molecule(formula) 

37 kwargs = dict(basekwargs) 

38 kwargs.update(morekwargs) 

39 calc = GPAW(**kwargs) 

40 system.calc = calc 

41 system.center(vacuum) 

42 if cell is None: 

43 system.center(vacuum) 

44 else: 

45 system.set_cell(cell) 

46 system.set_pbc(pbc) 

47 

48 try: 

49 system.get_potential_energy() 

50 except KohnShamConvergenceError: 

51 pass 

52 

53 E = calc.hamiltonian.e_total_free 

54 F_av = calculate_forces(calc.wfs, calc.density, 

55 calc.hamiltonian) 

56 

57 nonlocal Eref, Fref_av 

58 if Eref is None: 

59 Eref = E 

60 Fref_av = F_av 

61 

62 eerr = abs(E - Eref) 

63 ferr = abs(F_av - Fref_av).max() 

64 

65 if calc.wfs.world.rank == 0: 

66 print('Energy', E) 

67 print() 

68 print('Forces') 

69 print(F_av) 

70 print() 

71 print('Errs', eerr, ferr) 

72 

73 if eerr > tolerance or ferr > tolerance: 

74 if calc.wfs.world.rank == 0: 

75 stderr = sys.stderr 

76 else: 

77 stderr = devnull 

78 if eerr > tolerance: 

79 print('Failed!', file=stderr) 

80 print('E = %f, Eref = %f' % (E, Eref), file=stderr) 

81 msg = 'Energy err larger than tolerance: %f' % eerr 

82 if ferr > tolerance: 

83 print('Failed!', file=stderr) 

84 print('Forces:', file=stderr) 

85 print(F_av, file=stderr) 

86 print(file=stderr) 

87 print('Ref forces:', file=stderr) 

88 print(Fref_av, file=stderr) 

89 print(file=stderr) 

90 msg = 'Force err larger than tolerance: %f' % ferr 

91 print(file=stderr) 

92 print('Args:', file=stderr) 

93 print(formula, vacuum, cell, pbc, morekwargs, file=stderr) 

94 print(parallel, file=stderr) 

95 raise AssertionError(msg) 

96 

97 # reference: 

98 # kpt-parallelization = 8, 

99 # state-parallelization = 1, 

100 # domain-decomposition = (1,1,1) 

101 run() 

102 

103 # kpt-parallelization = 2, 

104 # state-parallelization = 2, 

105 # domain-decomposition = (1,2,1) 

106 parallel['band'] = 2 if world.size >= 2 else 1 

107 parallel['domain'] = (1, 2 if world.size >= 4 else 1, 1) 

108 run() 

109 

110 if compiled_with_sl(): 

111 # kpt-parallelization = 2, 

112 # state-parallelization = 2, 

113 # domain-decomposition = (1,2,1) 

114 # with blacs 

115 parallel['sl_default'] = (2 if world.size >= 2 else 1, 

116 2 if world.size >= 4 else 1, 2) 

117 run() 

118 

119 # perform spin polarization test 

120 parallel = dict() 

121 

122 basekwargs = dict(mode=LCAO(atomic_correction='sparse'), 

123 maxiter=3, 

124 nbands=6, 

125 kpts=(4, 1, 1), 

126 parallel=parallel) 

127 

128 Eref = None 

129 Fref_av = None 

130 

131 OH_kwargs = dict(formula='NH2', vacuum=1.5, pbc=1, spinpol=1, 

132 occupations=FermiDirac(width=0.1)) 

133 

134 # reference: 

135 # kpt-parallelization = 4, 

136 # spin-polarization = 2, 

137 # state-parallelization = 1, 

138 # domain-decomposition = (1, 1, 1) 

139 run(**OH_kwargs) 

140 

141 # kpt-parallelization = 2, 

142 # spin-polarization = 2, 

143 # state-parallelization = 1, 

144 # domain-decomposition = (1, 2, 1) 

145 parallel['domain'] = (1, 2, 1) 

146 run(**OH_kwargs) 

147 

148 # kpt-parallelization = 2, 

149 # spin-polarization = 2, 

150 # state-parallelization = 2, 

151 # domain-decomposition = (1, 1, 1) 

152 del parallel['domain'] 

153 parallel['band'] = 2 

154 run(**OH_kwargs) # test for forces is failing in this case! 

155 

156 if compiled_with_sl(): 

157 # kpt-parallelization = 2, 

158 # spin-polarization = 2, 

159 # state-parallelization = 2, 

160 # domain-decomposition = (1, 2, 1) 

161 # with blacs 

162 parallel['domain'] = (1, 2, 1) 

163 parallel['sl_default'] = (2, 1, 2) 

164 run(**OH_kwargs) 

165 

166 # kpt-parallelization = 2, 

167 # spin-polarization = 2, 

168 # state-parallelization = 2, 

169 # domain-decomposition = (1, 2, 1) 

170 # with blacs 

171 parallel['sl_default'] = (2, 2, 2) 

172 run(**OH_kwargs)