Coverage for /builds/kinetik161/ase/ase/units.py: 100.00%

48 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-12-10 11:04 +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': 299792458., 

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

102 '_Grav': 6.67408e-11, 

103 '_hplanck': 6.626070040e-34, 

104 '_e': 1.6021766208e-19, 

105 '_me': 9.10938356e-31, 

106 '_mp': 1.672621898e-27, 

107 '_Nav': 6.022140857e23, 

108 '_k': 1.38064852e-23, 

109 '_amu': 1.660539040e-27}, 

110 

111 # CODATA 2018 taken from 

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

113 '2018': {'_c': 299792458., # Exact 

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

115 '_Grav': 6.67430e-11, # +/- 0.000_15e-11 

116 '_hplanck': 6.62607015e-34, # Exact 

117 '_e': 1.602176634e-19, # Exact 

118 '_me': 9.1093837015e-31, # +/- 0.000_000_0028e-31 

119 '_mp': 1.67262192369e-27, # +/- 0.000_000_000_51e-27 

120 '_Nav': 6.02214076e23, # Exact 

121 '_k': 1.380649e-23, # Exact 

122 '_amu': 1.66053906660e-27}, # +/- 0.000_000_000_50e-27 

123} 

124 

125 

126def create_units(codata_version): 

127 """ 

128 Function that creates a dictionary containing all units previously hard 

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

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

131 or to update your local or global namespace. 

132 

133 Parameters: 

134 

135 codata_version: str 

136 The CODATA version to be used. Implemented are 

137 

138 * '1986' 

139 * '1998' 

140 * '2002' 

141 * '2006' 

142 * '2010' 

143 * '2014' 

144 

145 Returns: 

146 

147 units: dict 

148 Dictionary that contains all formerly hard coded variables from 

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

150 

151 Raises: 

152 

153 NotImplementedError 

154 If the required CODATA version is not known. 

155 """ 

156 

157 try: 

158 u = Units(CODATA[codata_version]) 

159 except KeyError: 

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

161 .format(codata_version)) 

162 

163 # derived from the CODATA values 

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

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

166 

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

168 u['nm'] = 10.0 

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

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

171 

172 u['eV'] = 1.0 

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

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

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

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

177 u['mol'] = u['_Nav'] 

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

179 u['Ry'] = u['Rydberg'] 

180 u['Ha'] = u['Hartree'] 

181 

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

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

184 

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

186 

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

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

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

190 

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

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

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

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

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

196 

197 # Derived atomic units that have no assigned name: 

198 # atomic unit of time, s: 

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

200 # atomic unit of velocity, m/s: 

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

202 # atomic unit of force, N: 

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

204 # atomic unit of pressure, Pa: 

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

206 

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

208 

209 # SI units 

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

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

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

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

214 # derived 

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

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

217 

218 return u 

219 

220 

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

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

223# values are immediately overwritten. 

224# pylint: disable=invalid-name 

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

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

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

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

229 

230# Now update the module scope: 

231globals().update(create_units(__codata_version__))