You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

378 lines
14 KiB

"""
SI unit system.
Based on MKSA, which stands for "meter, kilogram, second, ampere".
Added kelvin, candela and mole.
"""
from __future__ import annotations
from sympy.physics.units import DimensionSystem, Dimension, dHg0
from sympy.physics.units.quantities import Quantity
from sympy.core.numbers import (Rational, pi)
from sympy.core.singleton import S
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.physics.units.definitions.dimension_definitions import (
acceleration, action, current, impedance, length, mass, time, velocity,
amount_of_substance, temperature, information, frequency, force, pressure,
energy, power, charge, voltage, capacitance, conductance, magnetic_flux,
magnetic_density, inductance, luminous_intensity
)
from sympy.physics.units.definitions import (
kilogram, newton, second, meter, gram, cd, K, joule, watt, pascal, hertz,
coulomb, volt, ohm, siemens, farad, henry, tesla, weber, dioptre, lux,
katal, gray, becquerel, inch, liter, julian_year, gravitational_constant,
speed_of_light, elementary_charge, planck, hbar, electronvolt,
avogadro_number, avogadro_constant, boltzmann_constant, electron_rest_mass,
stefan_boltzmann_constant, Da, atomic_mass_constant, molar_gas_constant,
faraday_constant, josephson_constant, von_klitzing_constant,
acceleration_due_to_gravity, magnetic_constant, vacuum_permittivity,
vacuum_impedance, coulomb_constant, atmosphere, bar, pound, psi, mmHg,
milli_mass_unit, quart, lightyear, astronomical_unit, planck_mass,
planck_time, planck_temperature, planck_length, planck_charge, planck_area,
planck_volume, planck_momentum, planck_energy, planck_force, planck_power,
planck_density, planck_energy_density, planck_intensity,
planck_angular_frequency, planck_pressure, planck_current, planck_voltage,
planck_impedance, planck_acceleration, bit, byte, kibibyte, mebibyte,
gibibyte, tebibyte, pebibyte, exbibyte, curie, rutherford, radian, degree,
steradian, angular_mil, atomic_mass_unit, gee, kPa, ampere, u0, c, kelvin,
mol, mole, candela, m, kg, s, electric_constant, G, boltzmann
)
from sympy.physics.units.prefixes import PREFIXES, prefix_unit
from sympy.physics.units.systems.mksa import MKSA, dimsys_MKSA
derived_dims = (frequency, force, pressure, energy, power, charge, voltage,
capacitance, conductance, magnetic_flux,
magnetic_density, inductance, luminous_intensity)
base_dims = (amount_of_substance, luminous_intensity, temperature)
units = [mol, cd, K, lux, hertz, newton, pascal, joule, watt, coulomb, volt,
farad, ohm, siemens, weber, tesla, henry, candela, lux, becquerel,
gray, katal]
all_units: list[Quantity] = []
for u in units:
all_units.extend(prefix_unit(u, PREFIXES))
all_units.extend(units)
all_units.extend([mol, cd, K, lux])
dimsys_SI = dimsys_MKSA.extend(
[
# Dimensional dependencies for other base dimensions:
temperature,
amount_of_substance,
luminous_intensity,
])
dimsys_default = dimsys_SI.extend(
[information],
)
SI = MKSA.extend(base=(mol, cd, K), units=all_units, name='SI', dimension_system=dimsys_SI, derived_units={
power: watt,
magnetic_flux: weber,
time: second,
impedance: ohm,
pressure: pascal,
current: ampere,
voltage: volt,
length: meter,
frequency: hertz,
inductance: henry,
temperature: kelvin,
amount_of_substance: mole,
luminous_intensity: candela,
conductance: siemens,
mass: kilogram,
magnetic_density: tesla,
charge: coulomb,
force: newton,
capacitance: farad,
energy: joule,
velocity: meter/second,
})
One = S.One
SI.set_quantity_dimension(radian, One)
SI.set_quantity_scale_factor(ampere, One)
SI.set_quantity_scale_factor(kelvin, One)
SI.set_quantity_scale_factor(mole, One)
SI.set_quantity_scale_factor(candela, One)
# MKSA extension to MKS: derived units
SI.set_quantity_scale_factor(coulomb, One)
SI.set_quantity_scale_factor(volt, joule/coulomb)
SI.set_quantity_scale_factor(ohm, volt/ampere)
SI.set_quantity_scale_factor(siemens, ampere/volt)
SI.set_quantity_scale_factor(farad, coulomb/volt)
SI.set_quantity_scale_factor(henry, volt*second/ampere)
SI.set_quantity_scale_factor(tesla, volt*second/meter**2)
SI.set_quantity_scale_factor(weber, joule/ampere)
SI.set_quantity_dimension(lux, luminous_intensity / length ** 2)
SI.set_quantity_scale_factor(lux, steradian*candela/meter**2)
# katal is the SI unit of catalytic activity
SI.set_quantity_dimension(katal, amount_of_substance / time)
SI.set_quantity_scale_factor(katal, mol/second)
# gray is the SI unit of absorbed dose
SI.set_quantity_dimension(gray, energy / mass)
SI.set_quantity_scale_factor(gray, meter**2/second**2)
# becquerel is the SI unit of radioactivity
SI.set_quantity_dimension(becquerel, 1 / time)
SI.set_quantity_scale_factor(becquerel, 1/second)
#### CONSTANTS ####
# elementary charge
# REF: NIST SP 959 (June 2019)
SI.set_quantity_dimension(elementary_charge, charge)
SI.set_quantity_scale_factor(elementary_charge, 1.602176634e-19*coulomb)
# Electronvolt
# REF: NIST SP 959 (June 2019)
SI.set_quantity_dimension(electronvolt, energy)
SI.set_quantity_scale_factor(electronvolt, 1.602176634e-19*joule)
# Avogadro number
# REF: NIST SP 959 (June 2019)
SI.set_quantity_dimension(avogadro_number, One)
SI.set_quantity_scale_factor(avogadro_number, 6.02214076e23)
# Avogadro constant
SI.set_quantity_dimension(avogadro_constant, amount_of_substance ** -1)
SI.set_quantity_scale_factor(avogadro_constant, avogadro_number / mol)
# Boltzmann constant
# REF: NIST SP 959 (June 2019)
SI.set_quantity_dimension(boltzmann_constant, energy / temperature)
SI.set_quantity_scale_factor(boltzmann_constant, 1.380649e-23*joule/kelvin)
# Stefan-Boltzmann constant
# REF: NIST SP 959 (June 2019)
SI.set_quantity_dimension(stefan_boltzmann_constant, energy * time ** -1 * length ** -2 * temperature ** -4)
SI.set_quantity_scale_factor(stefan_boltzmann_constant, pi**2 * boltzmann_constant**4 / (60 * hbar**3 * speed_of_light ** 2))
# Atomic mass
# REF: NIST SP 959 (June 2019)
SI.set_quantity_dimension(atomic_mass_constant, mass)
SI.set_quantity_scale_factor(atomic_mass_constant, 1.66053906660e-24*gram)
# Molar gas constant
# REF: NIST SP 959 (June 2019)
SI.set_quantity_dimension(molar_gas_constant, energy / (temperature * amount_of_substance))
SI.set_quantity_scale_factor(molar_gas_constant, boltzmann_constant * avogadro_constant)
# Faraday constant
SI.set_quantity_dimension(faraday_constant, charge / amount_of_substance)
SI.set_quantity_scale_factor(faraday_constant, elementary_charge * avogadro_constant)
# Josephson constant
SI.set_quantity_dimension(josephson_constant, frequency / voltage)
SI.set_quantity_scale_factor(josephson_constant, 0.5 * planck / elementary_charge)
# Von Klitzing constant
SI.set_quantity_dimension(von_klitzing_constant, voltage / current)
SI.set_quantity_scale_factor(von_klitzing_constant, hbar / elementary_charge ** 2)
# Acceleration due to gravity (on the Earth surface)
SI.set_quantity_dimension(acceleration_due_to_gravity, acceleration)
SI.set_quantity_scale_factor(acceleration_due_to_gravity, 9.80665*meter/second**2)
# magnetic constant:
SI.set_quantity_dimension(magnetic_constant, force / current ** 2)
SI.set_quantity_scale_factor(magnetic_constant, 4*pi/10**7 * newton/ampere**2)
# electric constant:
SI.set_quantity_dimension(vacuum_permittivity, capacitance / length)
SI.set_quantity_scale_factor(vacuum_permittivity, 1/(u0 * c**2))
# vacuum impedance:
SI.set_quantity_dimension(vacuum_impedance, impedance)
SI.set_quantity_scale_factor(vacuum_impedance, u0 * c)
# Electron rest mass
SI.set_quantity_dimension(electron_rest_mass, mass)
SI.set_quantity_scale_factor(electron_rest_mass, 9.1093837015e-31*kilogram)
# Coulomb's constant:
SI.set_quantity_dimension(coulomb_constant, force * length ** 2 / charge ** 2)
SI.set_quantity_scale_factor(coulomb_constant, 1/(4*pi*vacuum_permittivity))
SI.set_quantity_dimension(psi, pressure)
SI.set_quantity_scale_factor(psi, pound * gee / inch ** 2)
SI.set_quantity_dimension(mmHg, pressure)
SI.set_quantity_scale_factor(mmHg, dHg0 * acceleration_due_to_gravity * kilogram / meter**2)
SI.set_quantity_dimension(milli_mass_unit, mass)
SI.set_quantity_scale_factor(milli_mass_unit, atomic_mass_unit/1000)
SI.set_quantity_dimension(quart, length ** 3)
SI.set_quantity_scale_factor(quart, Rational(231, 4) * inch**3)
# Other convenient units and magnitudes
SI.set_quantity_dimension(lightyear, length)
SI.set_quantity_scale_factor(lightyear, speed_of_light*julian_year)
SI.set_quantity_dimension(astronomical_unit, length)
SI.set_quantity_scale_factor(astronomical_unit, 149597870691*meter)
# Fundamental Planck units:
SI.set_quantity_dimension(planck_mass, mass)
SI.set_quantity_scale_factor(planck_mass, sqrt(hbar*speed_of_light/G))
SI.set_quantity_dimension(planck_time, time)
SI.set_quantity_scale_factor(planck_time, sqrt(hbar*G/speed_of_light**5))
SI.set_quantity_dimension(planck_temperature, temperature)
SI.set_quantity_scale_factor(planck_temperature, sqrt(hbar*speed_of_light**5/G/boltzmann**2))
SI.set_quantity_dimension(planck_length, length)
SI.set_quantity_scale_factor(planck_length, sqrt(hbar*G/speed_of_light**3))
SI.set_quantity_dimension(planck_charge, charge)
SI.set_quantity_scale_factor(planck_charge, sqrt(4*pi*electric_constant*hbar*speed_of_light))
# Derived Planck units:
SI.set_quantity_dimension(planck_area, length ** 2)
SI.set_quantity_scale_factor(planck_area, planck_length**2)
SI.set_quantity_dimension(planck_volume, length ** 3)
SI.set_quantity_scale_factor(planck_volume, planck_length**3)
SI.set_quantity_dimension(planck_momentum, mass * velocity)
SI.set_quantity_scale_factor(planck_momentum, planck_mass * speed_of_light)
SI.set_quantity_dimension(planck_energy, energy)
SI.set_quantity_scale_factor(planck_energy, planck_mass * speed_of_light**2)
SI.set_quantity_dimension(planck_force, force)
SI.set_quantity_scale_factor(planck_force, planck_energy / planck_length)
SI.set_quantity_dimension(planck_power, power)
SI.set_quantity_scale_factor(planck_power, planck_energy / planck_time)
SI.set_quantity_dimension(planck_density, mass / length ** 3)
SI.set_quantity_scale_factor(planck_density, planck_mass / planck_length**3)
SI.set_quantity_dimension(planck_energy_density, energy / length ** 3)
SI.set_quantity_scale_factor(planck_energy_density, planck_energy / planck_length**3)
SI.set_quantity_dimension(planck_intensity, mass * time ** (-3))
SI.set_quantity_scale_factor(planck_intensity, planck_energy_density * speed_of_light)
SI.set_quantity_dimension(planck_angular_frequency, 1 / time)
SI.set_quantity_scale_factor(planck_angular_frequency, 1 / planck_time)
SI.set_quantity_dimension(planck_pressure, pressure)
SI.set_quantity_scale_factor(planck_pressure, planck_force / planck_length**2)
SI.set_quantity_dimension(planck_current, current)
SI.set_quantity_scale_factor(planck_current, planck_charge / planck_time)
SI.set_quantity_dimension(planck_voltage, voltage)
SI.set_quantity_scale_factor(planck_voltage, planck_energy / planck_charge)
SI.set_quantity_dimension(planck_impedance, impedance)
SI.set_quantity_scale_factor(planck_impedance, planck_voltage / planck_current)
SI.set_quantity_dimension(planck_acceleration, acceleration)
SI.set_quantity_scale_factor(planck_acceleration, speed_of_light / planck_time)
# Older units for radioactivity
SI.set_quantity_dimension(curie, 1 / time)
SI.set_quantity_scale_factor(curie, 37000000000*becquerel)
SI.set_quantity_dimension(rutherford, 1 / time)
SI.set_quantity_scale_factor(rutherford, 1000000*becquerel)
# check that scale factors are the right SI dimensions:
for _scale_factor, _dimension in zip(
SI._quantity_scale_factors.values(),
SI._quantity_dimension_map.values()
):
dimex = SI.get_dimensional_expr(_scale_factor)
if dimex != 1:
# XXX: equivalent_dims is an instance method taking two arguments in
# addition to self so this can not work:
if not DimensionSystem.equivalent_dims(_dimension, Dimension(dimex)): # type: ignore
raise ValueError("quantity value and dimension mismatch")
del _scale_factor, _dimension
__all__ = [
'mmHg', 'atmosphere', 'inductance', 'newton', 'meter',
'vacuum_permittivity', 'pascal', 'magnetic_constant', 'voltage',
'angular_mil', 'luminous_intensity', 'all_units',
'julian_year', 'weber', 'exbibyte', 'liter',
'molar_gas_constant', 'faraday_constant', 'avogadro_constant',
'lightyear', 'planck_density', 'gee', 'mol', 'bit', 'gray',
'planck_momentum', 'bar', 'magnetic_density', 'prefix_unit', 'PREFIXES',
'planck_time', 'dimex', 'gram', 'candela', 'force', 'planck_intensity',
'energy', 'becquerel', 'planck_acceleration', 'speed_of_light',
'conductance', 'frequency', 'coulomb_constant', 'degree', 'lux', 'planck',
'current', 'planck_current', 'tebibyte', 'planck_power', 'MKSA', 'power',
'K', 'planck_volume', 'quart', 'pressure', 'amount_of_substance',
'joule', 'boltzmann_constant', 'Dimension', 'c', 'planck_force', 'length',
'watt', 'action', 'hbar', 'gibibyte', 'DimensionSystem', 'cd', 'volt',
'planck_charge', 'dioptre', 'vacuum_impedance', 'dimsys_default', 'farad',
'charge', 'gravitational_constant', 'temperature', 'u0', 'hertz',
'capacitance', 'tesla', 'steradian', 'planck_mass', 'josephson_constant',
'planck_area', 'stefan_boltzmann_constant', 'base_dims',
'astronomical_unit', 'radian', 'planck_voltage', 'impedance',
'planck_energy', 'Da', 'atomic_mass_constant', 'rutherford', 'second', 'inch',
'elementary_charge', 'SI', 'electronvolt', 'dimsys_SI', 'henry',
'planck_angular_frequency', 'ohm', 'pound', 'planck_pressure', 'G', 'psi',
'dHg0', 'von_klitzing_constant', 'planck_length', 'avogadro_number',
'mole', 'acceleration', 'information', 'planck_energy_density',
'mebibyte', 's', 'acceleration_due_to_gravity', 'electron_rest_mass',
'planck_temperature', 'units', 'mass', 'dimsys_MKSA', 'kelvin', 'kPa',
'boltzmann', 'milli_mass_unit', 'planck_impedance', 'electric_constant',
'derived_dims', 'kg', 'coulomb', 'siemens', 'byte', 'magnetic_flux',
'atomic_mass_unit', 'm', 'kibibyte', 'kilogram', 'One', 'curie', 'u',
'time', 'pebibyte', 'velocity', 'ampere', 'katal',
]