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
« prev ^ index » next coverage.py v7.5.3, created at 2025-03-06 04:00 +0000
1"""ase.units
3Physical constants and units derived from CODATA for converting
4to and from ase internal units.
7"""
10from math import pi, sqrt
12# the version we actually use
13__codata_version__ = '2014'
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."""
22 def __init__(self, *args, **kwargs):
23 super().__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': 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
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
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}
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.
146 Parameters:
148 codata_version: str
149 The CODATA version to be used. Implemented are
151 * '1986'
152 * '1998'
153 * '2002'
154 * '2006'
155 * '2010'
156 * '2014'
157 * '2018'
158 * '2022'
160 Returns:
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.
166 Raises:
168 NotImplementedError
169 If the required CODATA version is not known.
170 """
172 try:
173 u = Units(CODATA[codata_version])
174 except KeyError:
175 raise NotImplementedError('CODATA version "{}" not implemented'
176 .format(codata_version))
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
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
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']
197 u['second'] = 1e10 * sqrt(u['_e'] / u['_amu'])
198 u['fs'] = 1e-15 * u['second']
200 u['kB'] = u['_k'] / u['_e'] # Boltzmann constant, eV/K
202 u['Pascal'] = (1 / u['_e']) / 1e30 # J/m^3
203 u['GPa'] = 1e9 * u['Pascal']
204 u['bar'] = 1e5 * u['Pascal']
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
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
222 u['AUT'] = u['second'] * u['_aut']
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
233 return u
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
245# Now update the module scope:
246globals().update(create_units(__codata_version__))