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

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."""
23 def __init__(self, *args, **kwargs):
24 super(Units, self).__init__(*args, **kwargs)
25 self.__dict__ = self
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
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},
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},
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},
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},
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},
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}
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.
134 Parameters:
136 codata_version: str
137 The CODATA version to be used. Implemented are
139 * '1986'
140 * '1998'
141 * '2002'
142 * '2006'
143 * '2010'
144 * '2014'
146 Returns:
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.
152 Raises:
154 NotImplementedError
155 If the required CODATA version is not known.
156 """
158 try:
159 u = Units(CODATA[codata_version])
160 except KeyError:
161 raise NotImplementedError('CODATA version "{0}" not implemented'
162 .format(codata_version))
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
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
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']
183 u['second'] = 1e10 * sqrt(u['_e'] / u['_amu'])
184 u['fs'] = 1e-15 * u['second']
186 u['kB'] = u['_k'] / u['_e'] # Boltzmann constant, eV/K
188 u['Pascal'] = (1 / u['_e']) / 1e30 # J/m^3
189 u['GPa'] = 1e9 * u['Pascal']
190 u['bar'] = 1e5 * u['Pascal']
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
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
208 u['AUT'] = u['second'] * u['_aut']
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
219 return u
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
231# Now update the module scope:
232globals().update(create_units(__codata_version__))