_constants.py 10 KB

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