Coverage for gpaw/test/lrtddft/test_1.py: 100%

91 statements  

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

1import pytest 

2from ase.units import Bohr 

3from ase.parallel import parprint 

4from gpaw.lrtddft import LrTDDFT 

5from gpaw.mpi import world 

6from gpaw.lrtddft.excited_state import ExcitedState 

7from gpaw import GPAW 

8 

9 

10@pytest.fixture 

11def H2(H2struct): 

12 H2 = H2struct.copy() 

13 H2.calc = GPAW(mode='fd', xc='PBE', 

14 poissonsolver={'name': 'fd'}, 

15 nbands=3, spinpol=False) 

16 H2.get_potential_energy() 

17 return H2 

18 

19 

20@pytest.fixture 

21def H2spin(H2struct): 

22 H2 = H2struct.copy() 

23 H2.calc = GPAW(mode='fd', xc='PBE', nbands=2, 

24 poissonsolver={'name': 'fd'}, 

25 spinpol=True, parallel={'domain': world.size}) 

26 H2.get_potential_energy() 

27 return H2 

28 

29 

30@pytest.fixture 

31def lr(H2): 

32 """LrTDDFT object without spin""" 

33 lr = LrTDDFT(H2.calc, xc='LDA') 

34 lr.diagonalize() 

35 return lr 

36 

37 

38@pytest.fixture 

39def lr_vspin(H2): 

40 lr = LrTDDFT(H2.calc, xc='LDA', nspins=2) 

41 lr.diagonalize() 

42 return lr 

43 

44 

45@pytest.fixture 

46def lr_spin(H2spin): 

47 lr = LrTDDFT(H2spin.calc, xc='LDA', nspins=2) 

48 lr.diagonalize() 

49 return lr 

50 

51 

52@pytest.mark.lrtddft 

53def test_finegrid(H2, lr): 

54 for finegrid in [1, 0]: 

55 lr2 = LrTDDFT(H2.calc, xc='LDA', finegrid=finegrid) 

56 lr2.diagonalize() 

57 parprint('finegrid, t1, t3=', finegrid, lr[0], lr2[0]) 

58 assert lr[0].get_energy() == pytest.approx(lr2[0].get_energy(), 

59 abs=5.e-4) 

60 

61 

62@pytest.mark.lrtddft 

63def test_velocity_form(lr): 

64 for ozr, ozv in zip(lr[0].get_oscillator_strength(), 

65 lr[0].get_oscillator_strength('v')): 

66 assert ozr == pytest.approx(ozv, abs=0.1) 

67 

68 

69@pytest.mark.lrtddft 

70def test_singlet_triplet(lr_vspin, lr_spin): 

71 # singlet/triplet separation 

72 singlet, triplet = lr_vspin.singlets_triplets() 

73 

74 # singlet/triplet separation 

75 precision = 1.e-5 

76 singlet.diagonalize() 

77 assert singlet[0].get_energy() == pytest.approx(lr_spin[1].get_energy(), 

78 abs=precision) 

79 assert singlet[0].get_oscillator_strength()[0] == pytest.approx( 

80 lr_spin[1].get_oscillator_strength()[0], abs=precision) 

81 triplet.diagonalize() 

82 assert triplet[0].get_oscillator_strength()[0] == pytest.approx(0, abs=0) 

83 assert triplet[0].get_energy() == pytest.approx(lr_spin[0].get_energy(), 

84 abs=precision) 

85 assert triplet[0].get_oscillator_strength()[0] == pytest.approx(0, abs=0) 

86 

87 

88@pytest.mark.lrtddft 

89def test_spin(lr, lr_vspin, lr_spin): 

90 # without spin 

91 t1 = lr[0] 

92 ex = ExcitedState(lr, 0) 

93 den = ex.get_pseudo_density() * Bohr**3 

94 

95 # with spin 

96 

97 # the triplet is lower, so that the second is the first singlet 

98 # excited state 

99 t2 = lr_vspin[1] 

100 ex_vspin = ExcitedState(lr_vspin, 1) 

101 den_vspin = ex_vspin.get_pseudo_density() * Bohr**3 

102 

103 parprint('with virtual/wo spin t2, t1=', 

104 t2.get_energy(), t1 .get_energy()) 

105 assert t1.get_energy() == pytest.approx(t2.get_energy(), abs=5.e-7) 

106 gd = lr.calculator.density.gd 

107 finegd = lr.calculator.density.finegd 

108 ddiff = gd.integrate(abs(den - den_vspin)) 

109 parprint(' density integral, difference=', 

110 gd.integrate(den), gd.integrate(den_vspin), ddiff) 

111 parprint(' aed density integral', 

112 finegd.integrate(ex.get_all_electron_density() * Bohr**3), 

113 finegd.integrate(ex_vspin.get_all_electron_density() * 

114 Bohr**3)) 

115 assert ddiff < 1.e-4 

116 

117 for i in range(2): 

118 parprint('i, real, virtual spin: ', i, lr_vspin[i], lr_spin[i]) 

119 assert lr_vspin[i].get_energy() == pytest.approx( 

120 lr_spin[i].get_energy(), abs=6.e-6) 

121 ex_vspin = ExcitedState(lr_vspin, i) 

122 den_vspin = ex_vspin.get_pseudo_density() * Bohr**3 

123 ex_spin = ExcitedState(lr_spin, i) 

124 den_spin = ex_spin.get_pseudo_density() * Bohr**3 

125 ddiff = gd.integrate(abs(den_vspin - den_spin)) 

126 parprint(' density integral, difference=', 

127 gd.integrate(den_vspin), gd.integrate(den_spin), 

128 ddiff) 

129 parprint(' aed density integral', 

130 finegd.integrate(ex_vspin.get_all_electron_density() 

131 * Bohr**3), 

132 finegd.integrate(ex_spin.get_all_electron_density() 

133 * Bohr**3)) 

134 assert ddiff < 3.e-3, ddiff 

135 

136 

137@pytest.mark.lrtddft 

138def test_io(in_tmp_dir, lr): 

139 fname = 'lr.dat.gz' 

140 lr.write(fname) 

141 world.barrier() 

142 

143 lr2 = LrTDDFT.read(fname) 

144 lr2.diagonalize() 

145 

146 assert lr[0].get_energy() == pytest.approx(lr2[0].get_energy(), abs=1e-6)