_constants.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. """
  2. Collection of physical constants and conversion factors.
  3. Most constants are in SI units, so you can do
  4. print '10 mile per minute is', 10*mile/minute, 'm/s or', 10*mile/(minute*knot), 'knots'
  5. The list is not meant to be comprehensive, but just convenient for everyday use.
  6. """
  7. from __future__ import annotations
  8. import math as _math
  9. from typing import TYPE_CHECKING, Any
  10. from ._codata import value as _cd
  11. import numpy as _np
  12. if TYPE_CHECKING:
  13. import numpy.typing as npt
  14. """
  15. BasSw 2006
  16. physical constants: imported from CODATA
  17. unit conversion: see e.g., NIST special publication 811
  18. Use at own risk: double-check values before calculating your Mars orbit-insertion burn.
  19. Some constants exist in a few variants, which are marked with suffixes.
  20. The ones without any suffix should be the most common ones.
  21. """
  22. __all__ = [
  23. 'Avogadro', 'Boltzmann', 'Btu', 'Btu_IT', 'Btu_th', 'G',
  24. 'Julian_year', 'N_A', 'Planck', 'R', 'Rydberg',
  25. 'Stefan_Boltzmann', 'Wien', 'acre', 'alpha',
  26. 'angstrom', 'arcmin', 'arcminute', 'arcsec',
  27. 'arcsecond', 'astronomical_unit', 'atm',
  28. 'atmosphere', 'atomic_mass', 'atto', 'au', 'bar',
  29. 'barrel', 'bbl', 'blob', 'c', 'calorie',
  30. 'calorie_IT', 'calorie_th', 'carat', 'centi',
  31. 'convert_temperature', 'day', 'deci', 'degree',
  32. 'degree_Fahrenheit', 'deka', 'dyn', 'dyne', 'e',
  33. 'eV', 'electron_mass', 'electron_volt',
  34. 'elementary_charge', 'epsilon_0', 'erg',
  35. 'exa', 'exbi', 'femto', 'fermi', 'fine_structure',
  36. 'fluid_ounce', 'fluid_ounce_US', 'fluid_ounce_imp',
  37. 'foot', 'g', 'gallon', 'gallon_US', 'gallon_imp',
  38. 'gas_constant', 'gibi', 'giga', 'golden', 'golden_ratio',
  39. 'grain', 'gram', 'gravitational_constant', 'h', 'hbar',
  40. 'hectare', 'hecto', 'horsepower', 'hour', 'hp',
  41. 'inch', 'k', 'kgf', 'kibi', 'kilo', 'kilogram_force',
  42. 'kmh', 'knot', 'lambda2nu', 'lb', 'lbf',
  43. 'light_year', 'liter', 'litre', 'long_ton', 'm_e',
  44. 'm_n', 'm_p', 'm_u', 'mach', 'mebi', 'mega',
  45. 'metric_ton', 'micro', 'micron', 'mil', 'mile',
  46. 'milli', 'minute', 'mmHg', 'mph', 'mu_0', 'nano',
  47. 'nautical_mile', 'neutron_mass', 'nu2lambda',
  48. 'ounce', 'oz', 'parsec', 'pebi', 'peta',
  49. 'pi', 'pico', 'point', 'pound', 'pound_force',
  50. 'proton_mass', 'psi', 'pt', 'short_ton',
  51. 'sigma', 'slinch', 'slug', 'speed_of_light',
  52. 'speed_of_sound', 'stone', 'survey_foot',
  53. 'survey_mile', 'tebi', 'tera', 'ton_TNT',
  54. 'torr', 'troy_ounce', 'troy_pound', 'u',
  55. 'week', 'yard', 'year', 'yobi', 'yocto',
  56. 'yotta', 'zebi', 'zepto', 'zero_Celsius', 'zetta'
  57. ]
  58. # mathematical constants
  59. pi = _math.pi
  60. golden = golden_ratio = (1 + _math.sqrt(5)) / 2
  61. # SI prefixes
  62. yotta = 1e24
  63. zetta = 1e21
  64. exa = 1e18
  65. peta = 1e15
  66. tera = 1e12
  67. giga = 1e9
  68. mega = 1e6
  69. kilo = 1e3
  70. hecto = 1e2
  71. deka = 1e1
  72. deci = 1e-1
  73. centi = 1e-2
  74. milli = 1e-3
  75. micro = 1e-6
  76. nano = 1e-9
  77. pico = 1e-12
  78. femto = 1e-15
  79. atto = 1e-18
  80. zepto = 1e-21
  81. yocto = 1e-24
  82. # binary prefixes
  83. kibi = 2**10
  84. mebi = 2**20
  85. gibi = 2**30
  86. tebi = 2**40
  87. pebi = 2**50
  88. exbi = 2**60
  89. zebi = 2**70
  90. yobi = 2**80
  91. # physical constants
  92. c = speed_of_light = _cd('speed of light in vacuum')
  93. mu_0 = _cd('vacuum mag. permeability')
  94. epsilon_0 = _cd('vacuum electric permittivity')
  95. h = Planck = _cd('Planck constant')
  96. hbar = h / (2 * pi)
  97. G = gravitational_constant = _cd('Newtonian constant of gravitation')
  98. g = _cd('standard acceleration of gravity')
  99. e = elementary_charge = _cd('elementary charge')
  100. R = gas_constant = _cd('molar gas constant')
  101. alpha = fine_structure = _cd('fine-structure constant')
  102. N_A = Avogadro = _cd('Avogadro constant')
  103. k = Boltzmann = _cd('Boltzmann constant')
  104. sigma = Stefan_Boltzmann = _cd('Stefan-Boltzmann constant')
  105. Wien = _cd('Wien wavelength displacement law constant')
  106. Rydberg = _cd('Rydberg constant')
  107. # mass in kg
  108. gram = 1e-3
  109. metric_ton = 1e3
  110. grain = 64.79891e-6
  111. lb = pound = 7000 * grain # avoirdupois
  112. blob = slinch = pound * g / 0.0254 # lbf*s**2/in (added in 1.0.0)
  113. slug = blob / 12 # lbf*s**2/foot (added in 1.0.0)
  114. oz = ounce = pound / 16
  115. stone = 14 * pound
  116. long_ton = 2240 * pound
  117. short_ton = 2000 * pound
  118. troy_ounce = 480 * grain # only for metals / gems
  119. troy_pound = 12 * troy_ounce
  120. carat = 200e-6
  121. m_e = electron_mass = _cd('electron mass')
  122. m_p = proton_mass = _cd('proton mass')
  123. m_n = neutron_mass = _cd('neutron mass')
  124. m_u = u = atomic_mass = _cd('atomic mass constant')
  125. # angle in rad
  126. degree = pi / 180
  127. arcmin = arcminute = degree / 60
  128. arcsec = arcsecond = arcmin / 60
  129. # time in second
  130. minute = 60.0
  131. hour = 60 * minute
  132. day = 24 * hour
  133. week = 7 * day
  134. year = 365 * day
  135. Julian_year = 365.25 * day
  136. # length in meter
  137. inch = 0.0254
  138. foot = 12 * inch
  139. yard = 3 * foot
  140. mile = 1760 * yard
  141. mil = inch / 1000
  142. pt = point = inch / 72 # typography
  143. survey_foot = 1200.0 / 3937
  144. survey_mile = 5280 * survey_foot
  145. nautical_mile = 1852.0
  146. fermi = 1e-15
  147. angstrom = 1e-10
  148. micron = 1e-6
  149. au = astronomical_unit = 149597870700.0
  150. light_year = Julian_year * c
  151. parsec = au / arcsec
  152. # pressure in pascal
  153. atm = atmosphere = _cd('standard atmosphere')
  154. bar = 1e5
  155. torr = mmHg = atm / 760
  156. psi = pound * g / (inch * inch)
  157. # area in meter**2
  158. hectare = 1e4
  159. acre = 43560 * foot**2
  160. # volume in meter**3
  161. litre = liter = 1e-3
  162. gallon = gallon_US = 231 * inch**3 # US
  163. # pint = gallon_US / 8
  164. fluid_ounce = fluid_ounce_US = gallon_US / 128
  165. bbl = barrel = 42 * gallon_US # for oil
  166. gallon_imp = 4.54609e-3 # UK
  167. fluid_ounce_imp = gallon_imp / 160
  168. # speed in meter per second
  169. kmh = 1e3 / hour
  170. mph = mile / hour
  171. mach = speed_of_sound = 340.5 # approx value at 15 degrees in 1 atm. Is this a common value?
  172. knot = nautical_mile / hour
  173. # temperature in kelvin
  174. zero_Celsius = 273.15
  175. degree_Fahrenheit = 1/1.8 # only for differences
  176. # energy in joule
  177. eV = electron_volt = elementary_charge # * 1 Volt
  178. calorie = calorie_th = 4.184
  179. calorie_IT = 4.1868
  180. erg = 1e-7
  181. Btu_th = pound * degree_Fahrenheit * calorie_th / gram
  182. Btu = Btu_IT = pound * degree_Fahrenheit * calorie_IT / gram
  183. ton_TNT = 1e9 * calorie_th
  184. # Wh = watt_hour
  185. # power in watt
  186. hp = horsepower = 550 * foot * pound * g
  187. # force in newton
  188. dyn = dyne = 1e-5
  189. lbf = pound_force = pound * g
  190. kgf = kilogram_force = g # * 1 kg
  191. # functions for conversions that are not linear
  192. def convert_temperature(
  193. val: npt.ArrayLike,
  194. old_scale: str,
  195. new_scale: str,
  196. ) -> Any:
  197. """
  198. Convert from a temperature scale to another one among Celsius, Kelvin,
  199. Fahrenheit, and Rankine scales.
  200. Parameters
  201. ----------
  202. val : array_like
  203. Value(s) of the temperature(s) to be converted expressed in the
  204. original scale.
  205. old_scale : str
  206. Specifies as a string the original scale from which the temperature
  207. value(s) will be converted. Supported scales are Celsius ('Celsius',
  208. 'celsius', 'C' or 'c'), Kelvin ('Kelvin', 'kelvin', 'K', 'k'),
  209. Fahrenheit ('Fahrenheit', 'fahrenheit', 'F' or 'f'), and Rankine
  210. ('Rankine', 'rankine', 'R', 'r').
  211. new_scale : str
  212. Specifies as a string the new scale to which the temperature
  213. value(s) will be converted. Supported scales are Celsius ('Celsius',
  214. 'celsius', 'C' or 'c'), Kelvin ('Kelvin', 'kelvin', 'K', 'k'),
  215. Fahrenheit ('Fahrenheit', 'fahrenheit', 'F' or 'f'), and Rankine
  216. ('Rankine', 'rankine', 'R', 'r').
  217. Returns
  218. -------
  219. res : float or array of floats
  220. Value(s) of the converted temperature(s) expressed in the new scale.
  221. Notes
  222. -----
  223. .. versionadded:: 0.18.0
  224. Examples
  225. --------
  226. >>> from scipy.constants import convert_temperature
  227. >>> import numpy as np
  228. >>> convert_temperature(np.array([-40, 40]), 'Celsius', 'Kelvin')
  229. array([ 233.15, 313.15])
  230. """
  231. # Convert from `old_scale` to Kelvin
  232. if old_scale.lower() in ['celsius', 'c']:
  233. tempo = _np.asanyarray(val) + zero_Celsius
  234. elif old_scale.lower() in ['kelvin', 'k']:
  235. tempo = _np.asanyarray(val)
  236. elif old_scale.lower() in ['fahrenheit', 'f']:
  237. tempo = (_np.asanyarray(val) - 32) * 5 / 9 + zero_Celsius
  238. elif old_scale.lower() in ['rankine', 'r']:
  239. tempo = _np.asanyarray(val) * 5 / 9
  240. else:
  241. raise NotImplementedError("%s scale is unsupported: supported scales "
  242. "are Celsius, Kelvin, Fahrenheit, and "
  243. "Rankine" % old_scale)
  244. # and from Kelvin to `new_scale`.
  245. if new_scale.lower() in ['celsius', 'c']:
  246. res = tempo - zero_Celsius
  247. elif new_scale.lower() in ['kelvin', 'k']:
  248. res = tempo
  249. elif new_scale.lower() in ['fahrenheit', 'f']:
  250. res = (tempo - zero_Celsius) * 9 / 5 + 32
  251. elif new_scale.lower() in ['rankine', 'r']:
  252. res = tempo * 9 / 5
  253. else:
  254. raise NotImplementedError("'%s' scale is unsupported: supported "
  255. "scales are 'Celsius', 'Kelvin', "
  256. "'Fahrenheit', and 'Rankine'" % new_scale)
  257. return res
  258. # optics
  259. def lambda2nu(lambda_: npt.ArrayLike) -> Any:
  260. """
  261. Convert wavelength to optical frequency
  262. Parameters
  263. ----------
  264. lambda_ : array_like
  265. Wavelength(s) to be converted.
  266. Returns
  267. -------
  268. nu : float or array of floats
  269. Equivalent optical frequency.
  270. Notes
  271. -----
  272. Computes ``nu = c / lambda`` where c = 299792458.0, i.e., the
  273. (vacuum) speed of light in meters/second.
  274. Examples
  275. --------
  276. >>> from scipy.constants import lambda2nu, speed_of_light
  277. >>> import numpy as np
  278. >>> lambda2nu(np.array((1, speed_of_light)))
  279. array([ 2.99792458e+08, 1.00000000e+00])
  280. """
  281. return c / _np.asanyarray(lambda_)
  282. def nu2lambda(nu: npt.ArrayLike) -> Any:
  283. """
  284. Convert optical frequency to wavelength.
  285. Parameters
  286. ----------
  287. nu : array_like
  288. Optical frequency to be converted.
  289. Returns
  290. -------
  291. lambda : float or array of floats
  292. Equivalent wavelength(s).
  293. Notes
  294. -----
  295. Computes ``lambda = c / nu`` where c = 299792458.0, i.e., the
  296. (vacuum) speed of light in meters/second.
  297. Examples
  298. --------
  299. >>> from scipy.constants import nu2lambda, speed_of_light
  300. >>> import numpy as np
  301. >>> nu2lambda(np.array((1, speed_of_light)))
  302. array([ 2.99792458e+08, 1.00000000e+00])
  303. """
  304. return c / _np.asanyarray(nu)