si.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. """
  2. SI unit system.
  3. Based on MKSA, which stands for "meter, kilogram, second, ampere".
  4. Added kelvin, candela and mole.
  5. """
  6. from __future__ import annotations
  7. from sympy.physics.units import DimensionSystem, Dimension, dHg0
  8. from sympy.physics.units.quantities import Quantity
  9. from sympy.core.numbers import (Rational, pi)
  10. from sympy.core.singleton import S
  11. from sympy.functions.elementary.miscellaneous import sqrt
  12. from sympy.physics.units.definitions.dimension_definitions import (
  13. acceleration, action, current, impedance, length, mass, time, velocity,
  14. amount_of_substance, temperature, information, frequency, force, pressure,
  15. energy, power, charge, voltage, capacitance, conductance, magnetic_flux,
  16. magnetic_density, inductance, luminous_intensity
  17. )
  18. from sympy.physics.units.definitions import (
  19. kilogram, newton, second, meter, gram, cd, K, joule, watt, pascal, hertz,
  20. coulomb, volt, ohm, siemens, farad, henry, tesla, weber, dioptre, lux,
  21. katal, gray, becquerel, inch, liter, julian_year, gravitational_constant,
  22. speed_of_light, elementary_charge, planck, hbar, electronvolt,
  23. avogadro_number, avogadro_constant, boltzmann_constant, electron_rest_mass,
  24. stefan_boltzmann_constant, Da, atomic_mass_constant, molar_gas_constant,
  25. faraday_constant, josephson_constant, von_klitzing_constant,
  26. acceleration_due_to_gravity, magnetic_constant, vacuum_permittivity,
  27. vacuum_impedance, coulomb_constant, atmosphere, bar, pound, psi, mmHg,
  28. milli_mass_unit, quart, lightyear, astronomical_unit, planck_mass,
  29. planck_time, planck_temperature, planck_length, planck_charge, planck_area,
  30. planck_volume, planck_momentum, planck_energy, planck_force, planck_power,
  31. planck_density, planck_energy_density, planck_intensity,
  32. planck_angular_frequency, planck_pressure, planck_current, planck_voltage,
  33. planck_impedance, planck_acceleration, bit, byte, kibibyte, mebibyte,
  34. gibibyte, tebibyte, pebibyte, exbibyte, curie, rutherford, radian, degree,
  35. steradian, angular_mil, atomic_mass_unit, gee, kPa, ampere, u0, c, kelvin,
  36. mol, mole, candela, m, kg, s, electric_constant, G, boltzmann
  37. )
  38. from sympy.physics.units.prefixes import PREFIXES, prefix_unit
  39. from sympy.physics.units.systems.mksa import MKSA, dimsys_MKSA
  40. derived_dims = (frequency, force, pressure, energy, power, charge, voltage,
  41. capacitance, conductance, magnetic_flux,
  42. magnetic_density, inductance, luminous_intensity)
  43. base_dims = (amount_of_substance, luminous_intensity, temperature)
  44. units = [mol, cd, K, lux, hertz, newton, pascal, joule, watt, coulomb, volt,
  45. farad, ohm, siemens, weber, tesla, henry, candela, lux, becquerel,
  46. gray, katal]
  47. all_units: list[Quantity] = []
  48. for u in units:
  49. all_units.extend(prefix_unit(u, PREFIXES))
  50. all_units.extend(units)
  51. all_units.extend([mol, cd, K, lux])
  52. dimsys_SI = dimsys_MKSA.extend(
  53. [
  54. # Dimensional dependencies for other base dimensions:
  55. temperature,
  56. amount_of_substance,
  57. luminous_intensity,
  58. ])
  59. dimsys_default = dimsys_SI.extend(
  60. [information],
  61. )
  62. SI = MKSA.extend(base=(mol, cd, K), units=all_units, name='SI', dimension_system=dimsys_SI, derived_units={
  63. power: watt,
  64. magnetic_flux: weber,
  65. time: second,
  66. impedance: ohm,
  67. pressure: pascal,
  68. current: ampere,
  69. voltage: volt,
  70. length: meter,
  71. frequency: hertz,
  72. inductance: henry,
  73. temperature: kelvin,
  74. amount_of_substance: mole,
  75. luminous_intensity: candela,
  76. conductance: siemens,
  77. mass: kilogram,
  78. magnetic_density: tesla,
  79. charge: coulomb,
  80. force: newton,
  81. capacitance: farad,
  82. energy: joule,
  83. velocity: meter/second,
  84. })
  85. One = S.One
  86. SI.set_quantity_dimension(radian, One)
  87. SI.set_quantity_scale_factor(ampere, One)
  88. SI.set_quantity_scale_factor(kelvin, One)
  89. SI.set_quantity_scale_factor(mole, One)
  90. SI.set_quantity_scale_factor(candela, One)
  91. # MKSA extension to MKS: derived units
  92. SI.set_quantity_scale_factor(coulomb, One)
  93. SI.set_quantity_scale_factor(volt, joule/coulomb)
  94. SI.set_quantity_scale_factor(ohm, volt/ampere)
  95. SI.set_quantity_scale_factor(siemens, ampere/volt)
  96. SI.set_quantity_scale_factor(farad, coulomb/volt)
  97. SI.set_quantity_scale_factor(henry, volt*second/ampere)
  98. SI.set_quantity_scale_factor(tesla, volt*second/meter**2)
  99. SI.set_quantity_scale_factor(weber, joule/ampere)
  100. SI.set_quantity_dimension(lux, luminous_intensity / length ** 2)
  101. SI.set_quantity_scale_factor(lux, steradian*candela/meter**2)
  102. # katal is the SI unit of catalytic activity
  103. SI.set_quantity_dimension(katal, amount_of_substance / time)
  104. SI.set_quantity_scale_factor(katal, mol/second)
  105. # gray is the SI unit of absorbed dose
  106. SI.set_quantity_dimension(gray, energy / mass)
  107. SI.set_quantity_scale_factor(gray, meter**2/second**2)
  108. # becquerel is the SI unit of radioactivity
  109. SI.set_quantity_dimension(becquerel, 1 / time)
  110. SI.set_quantity_scale_factor(becquerel, 1/second)
  111. #### CONSTANTS ####
  112. # elementary charge
  113. # REF: NIST SP 959 (June 2019)
  114. SI.set_quantity_dimension(elementary_charge, charge)
  115. SI.set_quantity_scale_factor(elementary_charge, 1.602176634e-19*coulomb)
  116. # Electronvolt
  117. # REF: NIST SP 959 (June 2019)
  118. SI.set_quantity_dimension(electronvolt, energy)
  119. SI.set_quantity_scale_factor(electronvolt, 1.602176634e-19*joule)
  120. # Avogadro number
  121. # REF: NIST SP 959 (June 2019)
  122. SI.set_quantity_dimension(avogadro_number, One)
  123. SI.set_quantity_scale_factor(avogadro_number, 6.02214076e23)
  124. # Avogadro constant
  125. SI.set_quantity_dimension(avogadro_constant, amount_of_substance ** -1)
  126. SI.set_quantity_scale_factor(avogadro_constant, avogadro_number / mol)
  127. # Boltzmann constant
  128. # REF: NIST SP 959 (June 2019)
  129. SI.set_quantity_dimension(boltzmann_constant, energy / temperature)
  130. SI.set_quantity_scale_factor(boltzmann_constant, 1.380649e-23*joule/kelvin)
  131. # Stefan-Boltzmann constant
  132. # REF: NIST SP 959 (June 2019)
  133. SI.set_quantity_dimension(stefan_boltzmann_constant, energy * time ** -1 * length ** -2 * temperature ** -4)
  134. SI.set_quantity_scale_factor(stefan_boltzmann_constant, pi**2 * boltzmann_constant**4 / (60 * hbar**3 * speed_of_light ** 2))
  135. # Atomic mass
  136. # REF: NIST SP 959 (June 2019)
  137. SI.set_quantity_dimension(atomic_mass_constant, mass)
  138. SI.set_quantity_scale_factor(atomic_mass_constant, 1.66053906660e-24*gram)
  139. # Molar gas constant
  140. # REF: NIST SP 959 (June 2019)
  141. SI.set_quantity_dimension(molar_gas_constant, energy / (temperature * amount_of_substance))
  142. SI.set_quantity_scale_factor(molar_gas_constant, boltzmann_constant * avogadro_constant)
  143. # Faraday constant
  144. SI.set_quantity_dimension(faraday_constant, charge / amount_of_substance)
  145. SI.set_quantity_scale_factor(faraday_constant, elementary_charge * avogadro_constant)
  146. # Josephson constant
  147. SI.set_quantity_dimension(josephson_constant, frequency / voltage)
  148. SI.set_quantity_scale_factor(josephson_constant, 0.5 * planck / elementary_charge)
  149. # Von Klitzing constant
  150. SI.set_quantity_dimension(von_klitzing_constant, voltage / current)
  151. SI.set_quantity_scale_factor(von_klitzing_constant, hbar / elementary_charge ** 2)
  152. # Acceleration due to gravity (on the Earth surface)
  153. SI.set_quantity_dimension(acceleration_due_to_gravity, acceleration)
  154. SI.set_quantity_scale_factor(acceleration_due_to_gravity, 9.80665*meter/second**2)
  155. # magnetic constant:
  156. SI.set_quantity_dimension(magnetic_constant, force / current ** 2)
  157. SI.set_quantity_scale_factor(magnetic_constant, 4*pi/10**7 * newton/ampere**2)
  158. # electric constant:
  159. SI.set_quantity_dimension(vacuum_permittivity, capacitance / length)
  160. SI.set_quantity_scale_factor(vacuum_permittivity, 1/(u0 * c**2))
  161. # vacuum impedance:
  162. SI.set_quantity_dimension(vacuum_impedance, impedance)
  163. SI.set_quantity_scale_factor(vacuum_impedance, u0 * c)
  164. # Electron rest mass
  165. SI.set_quantity_dimension(electron_rest_mass, mass)
  166. SI.set_quantity_scale_factor(electron_rest_mass, 9.1093837015e-31*kilogram)
  167. # Coulomb's constant:
  168. SI.set_quantity_dimension(coulomb_constant, force * length ** 2 / charge ** 2)
  169. SI.set_quantity_scale_factor(coulomb_constant, 1/(4*pi*vacuum_permittivity))
  170. SI.set_quantity_dimension(psi, pressure)
  171. SI.set_quantity_scale_factor(psi, pound * gee / inch ** 2)
  172. SI.set_quantity_dimension(mmHg, pressure)
  173. SI.set_quantity_scale_factor(mmHg, dHg0 * acceleration_due_to_gravity * kilogram / meter**2)
  174. SI.set_quantity_dimension(milli_mass_unit, mass)
  175. SI.set_quantity_scale_factor(milli_mass_unit, atomic_mass_unit/1000)
  176. SI.set_quantity_dimension(quart, length ** 3)
  177. SI.set_quantity_scale_factor(quart, Rational(231, 4) * inch**3)
  178. # Other convenient units and magnitudes
  179. SI.set_quantity_dimension(lightyear, length)
  180. SI.set_quantity_scale_factor(lightyear, speed_of_light*julian_year)
  181. SI.set_quantity_dimension(astronomical_unit, length)
  182. SI.set_quantity_scale_factor(astronomical_unit, 149597870691*meter)
  183. # Fundamental Planck units:
  184. SI.set_quantity_dimension(planck_mass, mass)
  185. SI.set_quantity_scale_factor(planck_mass, sqrt(hbar*speed_of_light/G))
  186. SI.set_quantity_dimension(planck_time, time)
  187. SI.set_quantity_scale_factor(planck_time, sqrt(hbar*G/speed_of_light**5))
  188. SI.set_quantity_dimension(planck_temperature, temperature)
  189. SI.set_quantity_scale_factor(planck_temperature, sqrt(hbar*speed_of_light**5/G/boltzmann**2))
  190. SI.set_quantity_dimension(planck_length, length)
  191. SI.set_quantity_scale_factor(planck_length, sqrt(hbar*G/speed_of_light**3))
  192. SI.set_quantity_dimension(planck_charge, charge)
  193. SI.set_quantity_scale_factor(planck_charge, sqrt(4*pi*electric_constant*hbar*speed_of_light))
  194. # Derived Planck units:
  195. SI.set_quantity_dimension(planck_area, length ** 2)
  196. SI.set_quantity_scale_factor(planck_area, planck_length**2)
  197. SI.set_quantity_dimension(planck_volume, length ** 3)
  198. SI.set_quantity_scale_factor(planck_volume, planck_length**3)
  199. SI.set_quantity_dimension(planck_momentum, mass * velocity)
  200. SI.set_quantity_scale_factor(planck_momentum, planck_mass * speed_of_light)
  201. SI.set_quantity_dimension(planck_energy, energy)
  202. SI.set_quantity_scale_factor(planck_energy, planck_mass * speed_of_light**2)
  203. SI.set_quantity_dimension(planck_force, force)
  204. SI.set_quantity_scale_factor(planck_force, planck_energy / planck_length)
  205. SI.set_quantity_dimension(planck_power, power)
  206. SI.set_quantity_scale_factor(planck_power, planck_energy / planck_time)
  207. SI.set_quantity_dimension(planck_density, mass / length ** 3)
  208. SI.set_quantity_scale_factor(planck_density, planck_mass / planck_length**3)
  209. SI.set_quantity_dimension(planck_energy_density, energy / length ** 3)
  210. SI.set_quantity_scale_factor(planck_energy_density, planck_energy / planck_length**3)
  211. SI.set_quantity_dimension(planck_intensity, mass * time ** (-3))
  212. SI.set_quantity_scale_factor(planck_intensity, planck_energy_density * speed_of_light)
  213. SI.set_quantity_dimension(planck_angular_frequency, 1 / time)
  214. SI.set_quantity_scale_factor(planck_angular_frequency, 1 / planck_time)
  215. SI.set_quantity_dimension(planck_pressure, pressure)
  216. SI.set_quantity_scale_factor(planck_pressure, planck_force / planck_length**2)
  217. SI.set_quantity_dimension(planck_current, current)
  218. SI.set_quantity_scale_factor(planck_current, planck_charge / planck_time)
  219. SI.set_quantity_dimension(planck_voltage, voltage)
  220. SI.set_quantity_scale_factor(planck_voltage, planck_energy / planck_charge)
  221. SI.set_quantity_dimension(planck_impedance, impedance)
  222. SI.set_quantity_scale_factor(planck_impedance, planck_voltage / planck_current)
  223. SI.set_quantity_dimension(planck_acceleration, acceleration)
  224. SI.set_quantity_scale_factor(planck_acceleration, speed_of_light / planck_time)
  225. # Older units for radioactivity
  226. SI.set_quantity_dimension(curie, 1 / time)
  227. SI.set_quantity_scale_factor(curie, 37000000000*becquerel)
  228. SI.set_quantity_dimension(rutherford, 1 / time)
  229. SI.set_quantity_scale_factor(rutherford, 1000000*becquerel)
  230. # check that scale factors are the right SI dimensions:
  231. for _scale_factor, _dimension in zip(
  232. SI._quantity_scale_factors.values(),
  233. SI._quantity_dimension_map.values()
  234. ):
  235. dimex = SI.get_dimensional_expr(_scale_factor)
  236. if dimex != 1:
  237. # XXX: equivalent_dims is an instance method taking two arguments in
  238. # addition to self so this can not work:
  239. if not DimensionSystem.equivalent_dims(_dimension, Dimension(dimex)): # type: ignore
  240. raise ValueError("quantity value and dimension mismatch")
  241. del _scale_factor, _dimension
  242. __all__ = [
  243. 'mmHg', 'atmosphere', 'inductance', 'newton', 'meter',
  244. 'vacuum_permittivity', 'pascal', 'magnetic_constant', 'voltage',
  245. 'angular_mil', 'luminous_intensity', 'all_units',
  246. 'julian_year', 'weber', 'exbibyte', 'liter',
  247. 'molar_gas_constant', 'faraday_constant', 'avogadro_constant',
  248. 'lightyear', 'planck_density', 'gee', 'mol', 'bit', 'gray',
  249. 'planck_momentum', 'bar', 'magnetic_density', 'prefix_unit', 'PREFIXES',
  250. 'planck_time', 'dimex', 'gram', 'candela', 'force', 'planck_intensity',
  251. 'energy', 'becquerel', 'planck_acceleration', 'speed_of_light',
  252. 'conductance', 'frequency', 'coulomb_constant', 'degree', 'lux', 'planck',
  253. 'current', 'planck_current', 'tebibyte', 'planck_power', 'MKSA', 'power',
  254. 'K', 'planck_volume', 'quart', 'pressure', 'amount_of_substance',
  255. 'joule', 'boltzmann_constant', 'Dimension', 'c', 'planck_force', 'length',
  256. 'watt', 'action', 'hbar', 'gibibyte', 'DimensionSystem', 'cd', 'volt',
  257. 'planck_charge', 'dioptre', 'vacuum_impedance', 'dimsys_default', 'farad',
  258. 'charge', 'gravitational_constant', 'temperature', 'u0', 'hertz',
  259. 'capacitance', 'tesla', 'steradian', 'planck_mass', 'josephson_constant',
  260. 'planck_area', 'stefan_boltzmann_constant', 'base_dims',
  261. 'astronomical_unit', 'radian', 'planck_voltage', 'impedance',
  262. 'planck_energy', 'Da', 'atomic_mass_constant', 'rutherford', 'second', 'inch',
  263. 'elementary_charge', 'SI', 'electronvolt', 'dimsys_SI', 'henry',
  264. 'planck_angular_frequency', 'ohm', 'pound', 'planck_pressure', 'G', 'psi',
  265. 'dHg0', 'von_klitzing_constant', 'planck_length', 'avogadro_number',
  266. 'mole', 'acceleration', 'information', 'planck_energy_density',
  267. 'mebibyte', 's', 'acceleration_due_to_gravity', 'electron_rest_mass',
  268. 'planck_temperature', 'units', 'mass', 'dimsys_MKSA', 'kelvin', 'kPa',
  269. 'boltzmann', 'milli_mass_unit', 'planck_impedance', 'electric_constant',
  270. 'derived_dims', 'kg', 'coulomb', 'siemens', 'byte', 'magnetic_flux',
  271. 'atomic_mass_unit', 'm', 'kibibyte', 'kilogram', 'One', 'curie', 'u',
  272. 'time', 'pebibyte', 'velocity', 'ampere', 'katal',
  273. ]