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
3Physical constants and units derived from CODATA for converting
4to and from ase internal units.
7"""
10from math import pi, sqrt
13# the version we actually use
14__codata_version__ = '2014'
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 def __init__(self, *args, **kwargs):
23 super(Units, self).__init__(*args, **kwargs)
24 self.__dict__ = self
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
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},
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},
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},
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},
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},
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}
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.
133 Parameters:
135 codata_version: str
136 The CODATA version to be used. Implemented are
138 * '1986'
139 * '1998'
140 * '2002'
141 * '2006'
142 * '2010'
143 * '2014'
145 Returns:
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.
151 Raises:
153 NotImplementedError
154 If the required CODATA version is not known.
155 """
157 try:
158 u = Units(CODATA[codata_version])
159 except KeyError:
160 raise NotImplementedError('CODATA version "{0}" not implemented'
161 .format(codata_version))
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
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
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']
182 u['second'] = 1e10 * sqrt(u['_e'] / u['_amu'])
183 u['fs'] = 1e-15 * u['second']
185 u['kB'] = u['_k'] / u['_e'] # Boltzmann constant, eV/K
187 u['Pascal'] = (1 / u['_e']) / 1e30 # J/m^3
188 u['GPa'] = 1e9 * u['Pascal']
189 u['bar'] = 1e5 * u['Pascal']
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
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
207 u['AUT'] = u['second'] * u['_aut']
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
218 return u
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
230# Now update the module scope:
231globals().update(create_units(__codata_version__))