Coverage for gpaw/test/parallel/test_fd_parallel.py: 9%

96 statements  

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

1import pytest 

2import sys 

3 

4from ase.build import molecule 

5from gpaw.utilities import devnull 

6 

7from gpaw import GPAW, FermiDirac 

8from gpaw.utilities import compiled_with_sl 

9from gpaw.mpi import world 

10 

11# Calculates energy and forces for various parallelizations 

12 

13pytestmark = pytest.mark.skipif(world.size != 4, 

14 reason='world.size != 4') 

15 

16 

17def test_parallel_fd_parallel(): 

18 tolerance = 4e-5 

19 

20 parallel = dict() 

21 

22 basekwargs = dict(mode='fd', 

23 eigensolver='rmm-diis', 

24 convergence={'maximum iterations': 3}, 

25 nbands=6, 

26 parallel=parallel) 

27 

28 Eref = None 

29 Fref_av = None 

30 

31 def run(formula='H2O', vacuum=2.0, cell=None, pbc=0, **morekwargs): 

32 print(formula, parallel) 

33 system = molecule(formula) 

34 kwargs = dict(basekwargs) 

35 kwargs.update(morekwargs) 

36 calc = GPAW(**kwargs) 

37 system.calc = calc 

38 system.center(vacuum) 

39 if cell is None: 

40 system.center(vacuum) 

41 else: 

42 system.set_cell(cell) 

43 system.set_pbc(pbc) 

44 system.get_potential_energy() 

45 

46 E = calc.hamiltonian.e_total_free 

47 F_av = calc.get_forces() 

48 

49 nonlocal Eref, Fref_av 

50 if Eref is None: 

51 Eref = E 

52 Fref_av = F_av 

53 

54 eerr = abs(E - Eref) 

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

56 

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

58 print('Energy', E) 

59 print() 

60 print('Forces') 

61 print(F_av) 

62 print() 

63 print('Errs', eerr, ferr) 

64 

65 if eerr > tolerance or ferr > tolerance: 

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

67 stderr = sys.stderr 

68 else: 

69 stderr = devnull 

70 if eerr > tolerance: 

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

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

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

74 if ferr > tolerance: 

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

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

77 print(F_av, file=stderr) 

78 print(file=stderr) 

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

80 print(Fref_av, file=stderr) 

81 print(file=stderr) 

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

83 print(file=stderr) 

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

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

86 print(parallel, file=stderr) 

87 raise AssertionError(msg) 

88 

89 # reference: 

90 # state-parallelization = 1, 

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

92 run() 

93 

94 # state-parallelization = 2, 

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

96 parallel['band'] = 2 

97 parallel['domain'] = (1, 2, world.size // 4) 

98 run() 

99 

100 if compiled_with_sl(): 

101 # state-parallelization = 2, 

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

103 # with blacs 

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

105 run() 

106 

107 # state-parallelization = 1, 

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

109 # with blacs 

110 del parallel['band'] 

111 del parallel['domain'] 

112 run() 

113 

114 # perform spin polarization test 

115 parallel = dict() 

116 

117 basekwargs = dict(mode='fd', 

118 eigensolver='rmm-diis', 

119 convergence={'maximum iterations': 3}, 

120 nbands=6, 

121 parallel=parallel) 

122 

123 Eref = None 

124 Fref_av = None 

125 

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

127 occupations=FermiDirac(width=0.1)) 

128 

129 # start with empty parallel keyword 

130 # del parallel['sl_default'] 

131 # parallel = None 

132 # parallel = dict() 

133 # print parallel 

134 # del parallel['band'] 

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

136 

137 # reference: 

138 # spin-polarization = 2, 

139 # state-paralllization = 1, 

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

141 run(**OH_kwargs) 

142 

143 # spin-polarization = 2, 

144 # state-parallelization= 2, 

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

146 del parallel['domain'] 

147 parallel['band'] = 2 

148 run(**OH_kwargs) 

149 

150 # do last test with buffer_size keyword 

151 parallel['buffer_size'] = 50 

152 run(**OH_kwargs) 

153 

154 if compiled_with_sl(): 

155 # spin-polarization = 2, 

156 # state-parallelization= 2, 

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

158 # with blacs 

159 del parallel['buffer_size'] 

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

161 run(**OH_kwargs) 

162 

163 # spin-polarization = 2, 

164 # state-parallelization = 1, 

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

166 # with blacs 

167 del parallel['band'] 

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

169 run(**OH_kwargs) 

170 

171 # spin-polarization = 1, 

172 # state-parallelization = 1, 

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

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

175 run(**OH_kwargs) 

176 

177 # do last test with buffer_size keyword 

178 parallel['buffer_size'] = 50 

179 run(**OH_kwargs)