Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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 

13# the version we actually use 

14__codata_version__ = '2014' 

15 

16 

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

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

19# to a module. 

20class Units(dict): 

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

22 

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

24 super(Units, self).__init__(*args, **kwargs) 

25 self.__dict__ = self 

26 

27 

28# this is the hard-coded CODATA values 

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

30# module 

31CODATA = { 

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

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

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

35 # as well 

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

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

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

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

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

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

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

43 '_Nav': 6.0221367e23, # Avogadro number 

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

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

46 

47 # CODATA 1998 taken from 

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

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

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

51 '_Grav': 6.673e-11, 

52 '_hplanck': 6.62606876e-34, 

53 '_e': 1.602176462e-19, 

54 '_me': 9.10938188e-31, 

55 '_mp': 1.67262158e-27, 

56 '_Nav': 6.02214199e23, 

57 '_k': 1.3806503e-23, 

58 '_amu': 1.66053873e-27}, 

59 

60 # CODATA 2002 taken from 

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

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

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

64 '_Grav': 6.6742e-11, 

65 '_hplanck': 6.6260693e-34, 

66 '_e': 1.60217653e-19, 

67 '_me': 9.1093826e-31, 

68 '_mp': 1.67262171e-27, 

69 '_Nav': 6.0221415e23, 

70 '_k': 1.3806505e-23, 

71 '_amu': 1.66053886e-27}, 

72 

73 # CODATA 2006 taken from 

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

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

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

77 '_Grav': 6.67428e-11, 

78 '_hplanck': 6.62606896e-34, 

79 '_e': 1.602176487e-19, 

80 '_me': 9.10938215e-31, 

81 '_mp': 1.672621637e-27, 

82 '_Nav': 6.02214179e23, 

83 '_k': 1.3806504e-23, 

84 '_amu': 1.660538782e-27}, 

85 

86 # CODATA 2010 taken from 

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

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

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

90 '_Grav': 6.67384e-11, 

91 '_hplanck': 6.62606957e-34, 

92 '_e': 1.602176565e-19, 

93 '_me': 9.10938291e-31, 

94 '_mp': 1.672621777e-27, 

95 '_Nav': 6.02214129e23, 

96 '_k': 1.3806488e-23, 

97 '_amu': 1.660538921e-27}, 

98 

99 # CODATA 2014 taken from 

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

101 '2014': {'_c': 299792458., 

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

103 '_Grav': 6.67408e-11, 

104 '_hplanck': 6.626070040e-34, 

105 '_e': 1.6021766208e-19, 

106 '_me': 9.10938356e-31, 

107 '_mp': 1.672621898e-27, 

108 '_Nav': 6.022140857e23, 

109 '_k': 1.38064852e-23, 

110 '_amu': 1.660539040e-27}, 

111 

112 # CODATA 2018 taken from 

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

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

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

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

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

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

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

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

121 '_Nav': 6.02214076e23, # Exact 

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

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

124} 

125 

126 

127def create_units(codata_version): 

128 """ 

129 Function that creates a dictionary containing all units previously hard 

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

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

132 or to update your local or global namespace. 

133 

134 Parameters: 

135 

136 codata_version: str 

137 The CODATA version to be used. Implemented are 

138 

139 * '1986' 

140 * '1998' 

141 * '2002' 

142 * '2006' 

143 * '2010' 

144 * '2014' 

145 

146 Returns: 

147 

148 units: dict 

149 Dictionary that contains all formerly hard coded variables from 

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

151 

152 Raises: 

153 

154 NotImplementedError 

155 If the required CODATA version is not known. 

156 """ 

157 

158 try: 

159 u = Units(CODATA[codata_version]) 

160 except KeyError: 

161 raise NotImplementedError('CODATA version "{0}" not implemented' 

162 .format(codata_version)) 

163 

164 # derived from the CODATA values 

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

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

167 

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

169 u['nm'] = 10.0 

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

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

172 

173 u['eV'] = 1.0 

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

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

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

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

178 u['mol'] = u['_Nav'] 

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

180 u['Ry'] = u['Rydberg'] 

181 u['Ha'] = u['Hartree'] 

182 

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

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

185 

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

187 

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

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

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

191 

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

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

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

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

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

197 

198 # Derived atomic units that have no assigned name: 

199 # atomic unit of time, s: 

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

201 # atomic unit of velocity, m/s: 

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

203 # atomic unit of force, N: 

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

205 # atomic unit of pressure, Pa: 

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

207 

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

209 

210 # SI units 

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

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

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

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

215 # derived 

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

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

218 

219 return u 

220 

221 

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

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

224# values are immediately overwritten. 

225# pylint: disable=invalid-name 

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

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

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

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

230 

231# Now update the module scope: 

232globals().update(create_units(__codata_version__))