Coverage for /builds/debichem-team/python-ase/ase/units.py: 100.00%

48 statements  

« prev     ^ index     » next       coverage.py v7.5.3, created at 2025-03-06 04:00 +0000

1"""ase.units 

2 

3Physical constants and units derived from CODATA for converting 

4to and from ase internal units. 

5 

6 

7""" 

8 

9 

10from math import pi, sqrt 

11 

12# the version we actually use 

13__codata_version__ = '2014' 

14 

15 

16# Instead of a plain dict, if the units are in the __dict__ of a 

17# dict subclass, they can be accessed as attributes in a similar way 

18# to a module. 

19class Units(dict): 

20 """Dictionary for units that supports .attribute access.""" 

21 

22 def __init__(self, *args, **kwargs): 

23 super().__init__(*args, **kwargs) 

24 self.__dict__ = self 

25 

26 

27# this is the hard-coded CODATA values 

28# all other units are dynamically derived from these values upon import of the 

29# module 

30CODATA = { 

31 # the "original" CODATA version ase used ever since 

32 # Constants from Konrad Hinsen's PhysicalQuantities module (1986 CODATA) 

33 # Add the constant pi used to define the mu0 and hbar here for reference 

34 # as well 

35 '1986': {'_c': 299792458., # speed of light, m/s 

36 '_mu0': 4.e-7 * pi, # permeability of vacuum 

37 '_Grav': 6.67259e-11, # gravitational constant 

38 '_hplanck': 6.6260755e-34, # Planck constant, J s 

39 '_e': 1.60217733e-19, # elementary charge 

40 '_me': 9.1093897e-31, # electron mass 

41 '_mp': 1.6726231e-27, # proton mass 

42 '_Nav': 6.0221367e23, # Avogadro number 

43 '_k': 1.380658e-23, # Boltzmann constant, J/K 

44 '_amu': 1.6605402e-27}, # atomic mass unit, kg 

45 

46 # CODATA 1998 taken from 

47 # https://doi.org/10.1103/RevModPhys.72.351 

48 '1998': {'_c': 299792458., 

49 '_mu0': 4.0e-7 * pi, 

50 '_Grav': 6.673e-11, 

51 '_hplanck': 6.62606876e-34, 

52 '_e': 1.602176462e-19, 

53 '_me': 9.10938188e-31, 

54 '_mp': 1.67262158e-27, 

55 '_Nav': 6.02214199e23, 

56 '_k': 1.3806503e-23, 

57 '_amu': 1.66053873e-27}, 

58 

59 # CODATA 2002 taken from 

60 # https://doi.org/10.1103/RevModPhys.77.1 

61 '2002': {'_c': 299792458., 

62 '_mu0': 4.0e-7 * pi, 

63 '_Grav': 6.6742e-11, 

64 '_hplanck': 6.6260693e-34, 

65 '_e': 1.60217653e-19, 

66 '_me': 9.1093826e-31, 

67 '_mp': 1.67262171e-27, 

68 '_Nav': 6.0221415e23, 

69 '_k': 1.3806505e-23, 

70 '_amu': 1.66053886e-27}, 

71 

72 # CODATA 2006 taken from 

73 # https://doi.org/10.1103/RevModPhys.80.633 

74 '2006': {'_c': 299792458., 

75 '_mu0': 4.0e-7 * pi, 

76 '_Grav': 6.67428e-11, 

77 '_hplanck': 6.62606896e-34, 

78 '_e': 1.602176487e-19, 

79 '_me': 9.10938215e-31, 

80 '_mp': 1.672621637e-27, 

81 '_Nav': 6.02214179e23, 

82 '_k': 1.3806504e-23, 

83 '_amu': 1.660538782e-27}, 

84 

85 # CODATA 2010 taken from 

86 # https://doi.org/10.1103/RevModPhys.84.1527 

87 '2010': {'_c': 299792458., 

88 '_mu0': 4.0e-7 * pi, 

89 '_Grav': 6.67384e-11, 

90 '_hplanck': 6.62606957e-34, 

91 '_e': 1.602176565e-19, 

92 '_me': 9.10938291e-31, 

93 '_mp': 1.672621777e-27, 

94 '_Nav': 6.02214129e23, 

95 '_k': 1.3806488e-23, 

96 '_amu': 1.660538921e-27}, 

97 

98 # CODATA 2014 taken from 

99 # http://arxiv.org/pdf/1507.07956.pdf 

100 '2014': {'_c': 299_792_458., # Exact 

101 '_mu0': 4.0e-7 * pi, # Exact 

102 '_Grav': 6.674_08e-11, # +/- 0.000_31e-11 

103 '_hplanck': 6.626_070_040e-34, # +/- 0.000_000_081e-34 

104 '_e': 1.602_176_6208e-19, # +/- 0.000_000_0098e-19 

105 '_me': 9.109_383_56e-31, # +/- 0.000_000_11e-31 

106 '_mp': 1.672_621_898e-27, # +/- 0.000_000_021e-27 

107 '_Nav': 6.022_140_857e23, # +/- 0.000_000_074e23 

108 '_k': 1.380_648_52e-23, # +/- 0.000_000_79e-23 

109 '_amu': 1.660_539_040e-27}, # +/- 0.000_000_020e-27 

110 

111 # CODATA 2018 taken from 

112 # https://physics.nist.gov/cuu/pdf/all_2018.pdf 

113 '2018': {'_c': 299_792_458., # Exact 

114 '_mu0': 1.256_637_062_12e-6, # +/- 0.000_000_000_19e−6 

115 '_Grav': 6.674_30e-11, # +/- 0.000_15e-11 

116 '_hplanck': 6.626_070_15e-34, # Exact 

117 '_e': 1.602_176_634e-19, # Exact 

118 '_me': 9.109_383_7015e-31, # +/- 0.000_000_0028e-31 

119 '_mp': 1.672_621_923_69e-27, # +/- 0.000_000_000_51e-27 

120 '_Nav': 6.022_140_76e23, # Exact 

121 '_k': 1.380_649e-23, # Exact 

122 '_amu': 1.660_539_066_60e-27}, # +/- 0.000_000_000_50e-27 

123 

124 # CODATA 2022 (current) taken from 

125 # https://physics.nist.gov/cuu/Constants/index.html 

126 '2022': {'_c': 299_792_458., # Exact 

127 '_mu0': 1.256_637_061_27e-6, # +/- 0.000_000_000_20e−6 

128 '_Grav': 6.674_30e-11, # +/- 0.000_15e-11 

129 '_hplanck': 6.626_070_15e-34, # Exact 

130 '_e': 1.602_176_634e-19, # Exact 

131 '_me': 9.109_383_7139e-31, # +/- 0.000_000_0028e−31 

132 '_mp': 1.672_621_925_95e-27, # +/- 0.000_000_000_52e−27 

133 '_Nav': 6.022_140_76e23, # Exact 

134 '_k': 1.380_649e-23, # Exact 

135 '_amu': 1.660_539_068_92e-27}, # +/- 0.000_000_000_52e−27 

136} 

137 

138 

139def create_units(codata_version): 

140 """ 

141 Function that creates a dictionary containing all units previously hard 

142 coded in ase.units depending on a certain CODATA version. Note that 

143 returned dict has attribute access it can be used in place of the module 

144 or to update your local or global namespace. 

145 

146 Parameters: 

147 

148 codata_version: str 

149 The CODATA version to be used. Implemented are 

150 

151 * '1986' 

152 * '1998' 

153 * '2002' 

154 * '2006' 

155 * '2010' 

156 * '2014' 

157 * '2018' 

158 * '2022' 

159 

160 Returns: 

161 

162 units: dict 

163 Dictionary that contains all formerly hard coded variables from 

164 ase.units as key-value pairs. The dict supports attribute access. 

165 

166 Raises: 

167 

168 NotImplementedError 

169 If the required CODATA version is not known. 

170 """ 

171 

172 try: 

173 u = Units(CODATA[codata_version]) 

174 except KeyError: 

175 raise NotImplementedError('CODATA version "{}" not implemented' 

176 .format(codata_version)) 

177 

178 # derived from the CODATA values 

179 u['_eps0'] = (1 / u['_mu0'] / u['_c']**2) # permittivity of vacuum 

180 u['_hbar'] = u['_hplanck'] / (2 * pi) # Planck constant / 2pi, J s 

181 

182 u['Ang'] = u['Angstrom'] = 1.0 

183 u['nm'] = 10.0 

184 u['Bohr'] = (4e10 * pi * u['_eps0'] * u['_hbar']**2 / 

185 u['_me'] / u['_e']**2) # Bohr radius 

186 

187 u['eV'] = 1.0 

188 u['Hartree'] = (u['_me'] * u['_e']**3 / 16 / pi**2 / 

189 u['_eps0']**2 / u['_hbar']**2) 

190 u['kJ'] = 1000.0 / u['_e'] 

191 u['kcal'] = 4.184 * u['kJ'] 

192 u['mol'] = u['_Nav'] 

193 u['Rydberg'] = 0.5 * u['Hartree'] 

194 u['Ry'] = u['Rydberg'] 

195 u['Ha'] = u['Hartree'] 

196 

197 u['second'] = 1e10 * sqrt(u['_e'] / u['_amu']) 

198 u['fs'] = 1e-15 * u['second'] 

199 

200 u['kB'] = u['_k'] / u['_e'] # Boltzmann constant, eV/K 

201 

202 u['Pascal'] = (1 / u['_e']) / 1e30 # J/m^3 

203 u['GPa'] = 1e9 * u['Pascal'] 

204 u['bar'] = 1e5 * u['Pascal'] 

205 

206 u['Debye'] = 1.0 / 1e11 / u['_e'] / u['_c'] 

207 u['alpha'] = (u['_e']**2 / (4 * pi * u['_eps0']) / 

208 u['_hbar'] / u['_c']) # fine structure constant 

209 u['invcm'] = (100 * u['_c'] * u['_hplanck'] / 

210 u['_e']) # cm^-1 energy unit 

211 

212 # Derived atomic units that have no assigned name: 

213 # atomic unit of time, s: 

214 u['_aut'] = u['_hbar'] / (u['alpha']**2 * u['_me'] * u['_c']**2) 

215 # atomic unit of velocity, m/s: 

216 u['_auv'] = u['_e']**2 / u['_hbar'] / (4 * pi * u['_eps0']) 

217 # atomic unit of force, N: 

218 u['_auf'] = u['alpha']**3 * u['_me']**2 * u['_c']**3 / u['_hbar'] 

219 # atomic unit of pressure, Pa: 

220 u['_aup'] = u['alpha']**5 * u['_me']**4 * u['_c']**5 / u['_hbar']**3 

221 

222 u['AUT'] = u['second'] * u['_aut'] 

223 

224 # SI units 

225 u['m'] = 1e10 * u['Ang'] # metre 

226 u['kg'] = 1. / u['_amu'] # kilogram 

227 u['s'] = u['second'] # second 

228 u['A'] = 1.0 / u['_e'] / u['s'] # ampere 

229 # derived 

230 u['J'] = u['kJ'] / 1000 # Joule = kg * m**2 / s**2 

231 u['C'] = 1.0 / u['_e'] # Coulomb = A * s 

232 

233 return u 

234 

235 

236# Define all the expected symbols with dummy values so that introspection 

237# will know that they exist when the module is imported, even though their 

238# values are immediately overwritten. 

239# pylint: disable=invalid-name 

240(_Grav, _Nav, _amu, _auf, _aup, _aut, _auv, _c, _e, _eps0, 

241 _hbar, _hplanck, _k, _me, _mp, _mu0, alpha, eV, fs, invcm, 

242 kB, kJ, kcal, kg, m, mol, nm, s, second, A, AUT, Ang, Angstrom, 

243 Bohr, C, Debye, GPa, Ha, Hartree, J, Pascal, bar, Ry, Rydberg) = [0.0] * 44 

244 

245# Now update the module scope: 

246globals().update(create_units(__codata_version__))