Coverage for gpaw/test/lcaotddft/test_simple.py: 100%

53 statements  

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

1import numpy as np 

2import pytest 

3 

4from ase.units import Bohr, Hartree 

5from gpaw.external import ConstantElectricField 

6from gpaw.lcaotddft import LCAOTDDFT 

7from gpaw.lcaotddft.densitymatrix import DensityMatrix 

8from gpaw.lcaotddft.dipolemomentwriter import DipoleMomentWriter 

9from gpaw.lcaotddft.energywriter import EnergyWriter 

10from gpaw.lcaotddft.laser import create_laser 

11from gpaw.mpi import world 

12from gpaw.tddft.spectrum import photoabsorption_spectrum 

13 

14 

15@pytest.mark.rttddft 

16def test_lcaotddft_simple(gpw_files, in_tmp_dir): 

17 # Time-propagation calculation 

18 td_calc = LCAOTDDFT(gpw_files['na2_tddft_poisson'], txt='td.out') 

19 dmat = DensityMatrix(td_calc) 

20 DipoleMomentWriter(td_calc, 'dm.dat') 

21 EnergyWriter(td_calc, dmat, 'energy.dat') 

22 td_calc.absorption_kick(np.ones(3) * 1e-5) 

23 td_calc.propagate(20, 3) 

24 photoabsorption_spectrum('dm.dat', 'spec.dat', delta_e=5) 

25 world.barrier() 

26 

27 # Test dipole moment 

28 data_i = np.loadtxt('dm.dat')[:, 2:].ravel() 

29 if 0: 

30 from gpaw.test import print_reference 

31 print_reference(data_i, 'ref_i', '%.12le') 

32 

33 ref_i = [-9.383700894739e-16, 

34 -9.338586948130e-16, 

35 2.131582675483e-14, 

36 8.679923327633e-15, 

37 7.529517689096e-15, 

38 2.074867751820e-14, 

39 1.967175558125e-05, 

40 1.967175557952e-05, 

41 1.805004256446e-05, 

42 3.799528978877e-05, 

43 3.799528978943e-05, 

44 3.602506734201e-05, 

45 5.371491974467e-05, 

46 5.371491974534e-05, 

47 5.385046706407e-05] 

48 

49 tol = 1e-8 

50 assert data_i == pytest.approx(ref_i, abs=tol) 

51 

52 # Test spectrum 

53 data_i = np.loadtxt('spec.dat').ravel() 

54 if 0: 

55 from gpaw.test import print_reference 

56 print_reference(data_i, 'ref_i', '%.12le') 

57 

58 ref_i = [0.000000000000e+00, 

59 0.000000000000e+00, 

60 0.000000000000e+00, 

61 0.000000000000e+00, 

62 5.000000000000e+00, 

63 4.500226856200e-03, 

64 4.500226856200e-03, 

65 4.408379542600e-03, 

66 1.000000000000e+01, 

67 1.659426124300e-02, 

68 1.659426124300e-02, 

69 1.623812256800e-02, 

70 1.500000000000e+01, 

71 3.244686838800e-02, 

72 3.244686838800e-02, 

73 3.168682490900e-02, 

74 2.000000000000e+01, 

75 4.684883744600e-02, 

76 4.684883744600e-02, 

77 4.559689861200e-02, 

78 2.500000000000e+01, 

79 5.466781222200e-02, 

80 5.466781222200e-02, 

81 5.290171209500e-02, 

82 3.000000000000e+01, 

83 5.231586230700e-02, 

84 5.231586230700e-02, 

85 5.008661764300e-02] 

86 

87 tol = 1e-5 

88 assert data_i == pytest.approx(ref_i, abs=tol) 

89 

90 # Test energy - almost no energy should be absorbed due to the delta kick 

91 data_i = np.loadtxt('energy.dat')[:, 1:].ravel() 

92 

93 tol = 1e-8 

94 assert data_i == pytest.approx(0, abs=tol) 

95 

96 

97@pytest.mark.rttddft 

98def test_lcaotddft_laser(gpw_files, in_tmp_dir): 

99 # Simple test with laser instead of delta-kick, so 

100 # that system absorbs a meaningful amount of energy 

101 pulse = {'name': 'GaussianPulse', 'strength': 1e-3, 'time0': 0, 

102 'frequency': 8.6, 'sigma': 1, 'sincos': 'sin'} 

103 pulse = create_laser(pulse) 

104 

105 ext = ConstantElectricField(Hartree / Bohr, [1, 1, 1]) 

106 # Time-propagation calculation 

107 td_calc = LCAOTDDFT(gpw_files['na2_tddft_poisson'], 

108 td_potential={'ext': ext, 'laser': pulse}, 

109 txt='tdout.out') 

110 dmat = DensityMatrix(td_calc) 

111 EnergyWriter(td_calc, dmat, 'energy.dat') 

112 td_calc.propagate(20, 5) 

113 world.barrier() 

114 

115 # Test energy 

116 data_i = np.loadtxt('energy.dat')[:, 1:].ravel() 

117 if 0: 

118 from gpaw.test import print_reference 

119 print_reference(data_i, 'ref_i', '%.12le') 

120 

121 ref_i = [0.000000000000e+00, 

122 0.000000000000e+00, 

123 0.000000000000e+00, 

124 0.000000000000e+00, 

125 0.000000000000e+00, 

126 0.000000000000e+00, 

127 3.722528463257e-08, 

128 -3.245893376302e-08, 

129 4.013500642941e-10, 

130 0.000000000000e+00, 

131 -5.280626269588e-09, 

132 1.342903965806e-08, 

133 5.637101546108e-07, 

134 -4.922112830652e-07, 

135 6.093572091359e-09, 

136 0.000000000000e+00, 

137 -8.051342392790e-08, 

138 2.051779581791e-07, 

139 2.611917989781e-06, 

140 -2.279857594711e-06, 

141 2.837519125221e-08, 

142 0.000000000000e+00, 

143 -3.781277957415e-07, 

144 9.681304530273e-07, 

145 7.288861718524e-06, 

146 -6.358019188912e-06, 

147 7.976064814175e-08, 

148 0.000000000000e+00, 

149 -1.075880055268e-06, 

150 2.773092058317e-06, 

151 1.513288133970e-05, 

152 -1.318711657139e-05, 

153 1.672415533838e-07, 

154 0.000000000000e+00, 

155 -2.291283559219e-06, 

156 5.959395212557e-06] 

157 

158 tol = 1e-8 

159 assert data_i == pytest.approx(ref_i, abs=tol) 

160 

161 

162@pytest.mark.rttddft 

163def test_lcaotddft_fail_with_symmetry(gpw_files, in_tmp_dir): 

164 # Time-propagation calculation 

165 # should not be allowed with symmetries 

166 with pytest.raises(ValueError): 

167 LCAOTDDFT(gpw_files['na2_tddft_poisson_sym'], txt='td.out')