Coverage for gpaw/test/response/test_iron_sf_ALDA.py: 19%

77 statements  

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

1""" 

2Calculate the magnetic response in iron using ALDA. 

3 

4Tests whether the magnon energies and scattering intensities 

5have changed for: 

6 * Different kernel calculation strategies 

7 * Different chi0 transitions summation strategies 

8""" 

9 

10import numpy as np 

11import pytest 

12 

13from gpaw import GPAW 

14from gpaw.test import findpeak 

15from gpaw.mpi import world 

16 

17from gpaw.response import ResponseGroundStateAdapter 

18from gpaw.response.chiks import ChiKSCalculator 

19from gpaw.response.susceptibility import ChiFactory 

20from gpaw.response.fxc_kernels import AdiabaticFXCCalculator 

21from gpaw.response.pair_functions import read_pair_function 

22from gpaw.test.gpwfile import response_band_cutoff 

23 

24pytestmark = pytest.mark.skipif(world.size < 4, reason='world.size < 4') 

25 

26 

27@pytest.mark.kspair 

28@pytest.mark.response 

29def test_response_iron_sf_ALDA(in_tmp_dir, gpw_files, scalapack): 

30 # ---------- Inputs ---------- # 

31 

32 # Magnetic response calculation 

33 q_c = [0.0, 0.0, 1 / 4.] 

34 fxc = 'ALDA' 

35 ecut = 300 

36 eta = 0.1 

37 

38 # Test different kernel, summation and symmetry strategies 

39 # rshelmax, rshewmin, bandsummation, qsymmetry 

40 strat_sd = [(None, None, 'pairwise', True), 

41 (-1, 0.001, 'pairwise', True), 

42 (-1, 0.000001, 'pairwise', True), 

43 (-1, 0.000001, 'double', True), 

44 (-1, 0.000001, 'double', False), 

45 (-1, None, 'pairwise', True), 

46 (3, None, 'pairwise', True)] 

47 frq_sw = [np.linspace(0.320, 0.480, 21), 

48 np.linspace(0.420, 0.580, 21), 

49 np.linspace(0.420, 0.580, 21), 

50 np.linspace(0.420, 0.580, 21), 

51 np.linspace(0.420, 0.580, 21), 

52 np.linspace(0.420, 0.580, 21), 

53 np.linspace(0.420, 0.580, 21), 

54 np.linspace(0.420, 0.580, 21)] 

55 

56 # ---------- Script ---------- # 

57 

58 calc = GPAW(gpw_files['fe_pw'], parallel=dict(domain=1)) 

59 nbands = response_band_cutoff['fe_pw'] 

60 gs = ResponseGroundStateAdapter(calc) 

61 

62 for s, ((rshelmax, rshewmin, bandsummation, qsymmetry), 

63 frq_w) in enumerate(zip(strat_sd, frq_sw)): 

64 complex_frequencies = frq_w + 1.j * eta 

65 chiks_calc = ChiKSCalculator(gs, 

66 nbands=nbands, 

67 ecut=ecut, 

68 bandsummation=bandsummation, 

69 qsymmetry=qsymmetry, 

70 nblocks=2) 

71 fxc_calculator = AdiabaticFXCCalculator.from_rshe_parameters( 

72 gs, chiks_calc.context, 

73 rshelmax=rshelmax, 

74 rshewmin=rshewmin) 

75 chi_factory = ChiFactory(chiks_calc, fxc_calculator) 

76 _, chi = chi_factory('+-', q_c, complex_frequencies, fxc=fxc) 

77 chi.write_macroscopic_component('iron_dsus' + '_G%d.csv' % (s + 1)) 

78 chi_factory.context.write_timer() 

79 

80 world.barrier() 

81 

82 # Identify magnon peak in scattering functions 

83 w1_w, chi1_w = read_pair_function('iron_dsus_G1.csv') 

84 w2_w, chi2_w = read_pair_function('iron_dsus_G2.csv') 

85 w3_w, chi3_w = read_pair_function('iron_dsus_G3.csv') 

86 w4_w, chi4_w = read_pair_function('iron_dsus_G4.csv') 

87 w5_w, chi5_w = read_pair_function('iron_dsus_G5.csv') 

88 w6_w, chi6_w = read_pair_function('iron_dsus_G6.csv') 

89 w7_w, chi7_w = read_pair_function('iron_dsus_G7.csv') 

90 print(-chi1_w.imag) 

91 print(-chi2_w.imag) 

92 

93 wpeak1, Ipeak1 = findpeak(w1_w, -chi1_w.imag) 

94 wpeak2, Ipeak2 = findpeak(w2_w, -chi2_w.imag) 

95 wpeak3, Ipeak3 = findpeak(w3_w, -chi3_w.imag) 

96 wpeak4, Ipeak4 = findpeak(w4_w, -chi4_w.imag) 

97 wpeak5, Ipeak5 = findpeak(w5_w, -chi5_w.imag) 

98 wpeak6, Ipeak6 = findpeak(w6_w, -chi6_w.imag) 

99 wpeak7, Ipeak7 = findpeak(w7_w, -chi7_w.imag) 

100 

101 mw1 = wpeak1 * 1000 

102 mw2 = wpeak2 * 1000 

103 mw3 = wpeak3 * 1000 

104 mw4 = wpeak4 * 1000 

105 mw5 = wpeak5 * 1000 

106 mw6 = wpeak6 * 1000 

107 mw7 = wpeak7 * 1000 

108 

109 # Compare new results to test values 

110 print(mw1, mw2, mw3, Ipeak1, Ipeak2, Ipeak3) 

111 test_mw1 = 402. # meV 

112 test_mw2 = 490. # meV 

113 test_mw3 = 490. # meV 

114 test_Ipeak1 = 4.10 # a.u. 

115 test_Ipeak2 = 5.05 # a.u. 

116 test_Ipeak3 = 5.04 # a.u. 

117 

118 # Different kernel strategies should remain the same 

119 # Magnon peak: 

120 assert mw1 == pytest.approx(test_mw1, abs=30.) 

121 assert mw2 == pytest.approx(test_mw2, abs=30.) 

122 assert mw3 == pytest.approx(test_mw3, abs=30.) 

123 

124 # Scattering function intensity: 

125 assert Ipeak1 == pytest.approx(test_Ipeak1, abs=0.5) 

126 assert Ipeak2 == pytest.approx(test_Ipeak2, abs=0.5) 

127 assert Ipeak3 == pytest.approx(test_Ipeak3, abs=0.5) 

128 

129 # The two transitions summation strategies should give identical results 

130 assert mw3 == pytest.approx(mw4, abs=35.) 

131 assert Ipeak3 == pytest.approx(Ipeak4, abs=0.5) 

132 

133 # Toggling symmetry should preserve the result 

134 assert mw5 == pytest.approx(mw4, abs=25.) 

135 assert Ipeak5 == pytest.approx(Ipeak4, abs=0.5) 

136 

137 # Including vanishing coefficients should not matter for the result 

138 assert mw6 == pytest.approx(mw3, abs=2.) 

139 assert Ipeak6 == pytest.approx(Ipeak3, abs=0.1) 

140 assert mw7 == pytest.approx(mw2, abs=2.) 

141 assert Ipeak7 == pytest.approx(Ipeak2, abs=0.1)