add read me
This commit is contained in:
@@ -0,0 +1,453 @@
|
||||
# isort:skip_file
|
||||
"""
|
||||
Dimensional analysis and unit systems.
|
||||
|
||||
This module defines dimension/unit systems and physical quantities. It is
|
||||
based on a group-theoretical construction where dimensions are represented as
|
||||
vectors (coefficients being the exponents), and units are defined as a dimension
|
||||
to which we added a scale.
|
||||
|
||||
Quantities are built from a factor and a unit, and are the basic objects that
|
||||
one will use when doing computations.
|
||||
|
||||
All objects except systems and prefixes can be used in SymPy expressions.
|
||||
Note that as part of a CAS, various objects do not combine automatically
|
||||
under operations.
|
||||
|
||||
Details about the implementation can be found in the documentation, and we
|
||||
will not repeat all the explanations we gave there concerning our approach.
|
||||
Ideas about future developments can be found on the `Github wiki
|
||||
<https://github.com/sympy/sympy/wiki/Unit-systems>`_, and you should consult
|
||||
this page if you are willing to help.
|
||||
|
||||
Useful functions:
|
||||
|
||||
- ``find_unit``: easily lookup pre-defined units.
|
||||
- ``convert_to(expr, newunit)``: converts an expression into the same
|
||||
expression expressed in another unit.
|
||||
|
||||
"""
|
||||
|
||||
from .dimensions import Dimension, DimensionSystem
|
||||
from .unitsystem import UnitSystem
|
||||
from .util import convert_to
|
||||
from .quantities import Quantity
|
||||
|
||||
from .definitions.dimension_definitions import (
|
||||
amount_of_substance, acceleration, action, area,
|
||||
capacitance, charge, conductance, current, energy,
|
||||
force, frequency, impedance, inductance, length,
|
||||
luminous_intensity, magnetic_density,
|
||||
magnetic_flux, mass, momentum, power, pressure, temperature, time,
|
||||
velocity, voltage, volume
|
||||
)
|
||||
|
||||
Unit = Quantity
|
||||
|
||||
speed = velocity
|
||||
luminosity = luminous_intensity
|
||||
magnetic_flux_density = magnetic_density
|
||||
amount = amount_of_substance
|
||||
|
||||
from .prefixes import (
|
||||
# 10-power based:
|
||||
yotta,
|
||||
zetta,
|
||||
exa,
|
||||
peta,
|
||||
tera,
|
||||
giga,
|
||||
mega,
|
||||
kilo,
|
||||
hecto,
|
||||
deca,
|
||||
deci,
|
||||
centi,
|
||||
milli,
|
||||
micro,
|
||||
nano,
|
||||
pico,
|
||||
femto,
|
||||
atto,
|
||||
zepto,
|
||||
yocto,
|
||||
# 2-power based:
|
||||
kibi,
|
||||
mebi,
|
||||
gibi,
|
||||
tebi,
|
||||
pebi,
|
||||
exbi,
|
||||
)
|
||||
|
||||
from .definitions import (
|
||||
percent, percents,
|
||||
permille,
|
||||
rad, radian, radians,
|
||||
deg, degree, degrees,
|
||||
sr, steradian, steradians,
|
||||
mil, angular_mil, angular_mils,
|
||||
m, meter, meters,
|
||||
kg, kilogram, kilograms,
|
||||
s, second, seconds,
|
||||
A, ampere, amperes,
|
||||
K, kelvin, kelvins,
|
||||
mol, mole, moles,
|
||||
cd, candela, candelas,
|
||||
g, gram, grams,
|
||||
mg, milligram, milligrams,
|
||||
ug, microgram, micrograms,
|
||||
t, tonne, metric_ton,
|
||||
newton, newtons, N,
|
||||
joule, joules, J,
|
||||
watt, watts, W,
|
||||
pascal, pascals, Pa, pa,
|
||||
hertz, hz, Hz,
|
||||
coulomb, coulombs, C,
|
||||
volt, volts, v, V,
|
||||
ohm, ohms,
|
||||
siemens, S, mho, mhos,
|
||||
farad, farads, F,
|
||||
henry, henrys, H,
|
||||
tesla, teslas, T,
|
||||
weber, webers, Wb, wb,
|
||||
optical_power, dioptre, D,
|
||||
lux, lx,
|
||||
katal, kat,
|
||||
gray, Gy,
|
||||
becquerel, Bq,
|
||||
km, kilometer, kilometers,
|
||||
dm, decimeter, decimeters,
|
||||
cm, centimeter, centimeters,
|
||||
mm, millimeter, millimeters,
|
||||
um, micrometer, micrometers, micron, microns,
|
||||
nm, nanometer, nanometers,
|
||||
pm, picometer, picometers,
|
||||
ft, foot, feet,
|
||||
inch, inches,
|
||||
yd, yard, yards,
|
||||
mi, mile, miles,
|
||||
nmi, nautical_mile, nautical_miles,
|
||||
angstrom, angstroms,
|
||||
ha, hectare,
|
||||
l, L, liter, liters,
|
||||
dl, dL, deciliter, deciliters,
|
||||
cl, cL, centiliter, centiliters,
|
||||
ml, mL, milliliter, milliliters,
|
||||
ms, millisecond, milliseconds,
|
||||
us, microsecond, microseconds,
|
||||
ns, nanosecond, nanoseconds,
|
||||
ps, picosecond, picoseconds,
|
||||
minute, minutes,
|
||||
h, hour, hours,
|
||||
day, days,
|
||||
anomalistic_year, anomalistic_years,
|
||||
sidereal_year, sidereal_years,
|
||||
tropical_year, tropical_years,
|
||||
common_year, common_years,
|
||||
julian_year, julian_years,
|
||||
draconic_year, draconic_years,
|
||||
gaussian_year, gaussian_years,
|
||||
full_moon_cycle, full_moon_cycles,
|
||||
year, years,
|
||||
G, gravitational_constant,
|
||||
c, speed_of_light,
|
||||
elementary_charge,
|
||||
hbar,
|
||||
planck,
|
||||
eV, electronvolt, electronvolts,
|
||||
avogadro_number,
|
||||
avogadro, avogadro_constant,
|
||||
boltzmann, boltzmann_constant,
|
||||
stefan, stefan_boltzmann_constant,
|
||||
R, molar_gas_constant,
|
||||
faraday_constant,
|
||||
josephson_constant,
|
||||
von_klitzing_constant,
|
||||
Da, dalton, amu, amus, atomic_mass_unit, atomic_mass_constant,
|
||||
me, electron_rest_mass,
|
||||
gee, gees, acceleration_due_to_gravity,
|
||||
u0, magnetic_constant, vacuum_permeability,
|
||||
e0, electric_constant, vacuum_permittivity,
|
||||
Z0, vacuum_impedance,
|
||||
coulomb_constant, electric_force_constant,
|
||||
atmosphere, atmospheres, atm,
|
||||
kPa,
|
||||
bar, bars,
|
||||
pound, pounds,
|
||||
psi,
|
||||
dHg0,
|
||||
mmHg, torr,
|
||||
mmu, mmus, milli_mass_unit,
|
||||
quart, quarts,
|
||||
ly, lightyear, lightyears,
|
||||
au, astronomical_unit, astronomical_units,
|
||||
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, bits,
|
||||
byte,
|
||||
kibibyte, kibibytes,
|
||||
mebibyte, mebibytes,
|
||||
gibibyte, gibibytes,
|
||||
tebibyte, tebibytes,
|
||||
pebibyte, pebibytes,
|
||||
exbibyte, exbibytes,
|
||||
)
|
||||
|
||||
from .systems import (
|
||||
mks, mksa, si
|
||||
)
|
||||
|
||||
|
||||
def find_unit(quantity, unit_system="SI"):
|
||||
"""
|
||||
Return a list of matching units or dimension names.
|
||||
|
||||
- If ``quantity`` is a string -- units/dimensions containing the string
|
||||
`quantity`.
|
||||
- If ``quantity`` is a unit or dimension -- units having matching base
|
||||
units or dimensions.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics import units as u
|
||||
>>> u.find_unit('charge')
|
||||
['C', 'coulomb', 'coulombs', 'planck_charge', 'elementary_charge']
|
||||
>>> u.find_unit(u.charge)
|
||||
['C', 'coulomb', 'coulombs', 'planck_charge', 'elementary_charge']
|
||||
>>> u.find_unit("ampere")
|
||||
['ampere', 'amperes']
|
||||
>>> u.find_unit('angstrom')
|
||||
['angstrom', 'angstroms']
|
||||
>>> u.find_unit('volt')
|
||||
['volt', 'volts', 'electronvolt', 'electronvolts', 'planck_voltage']
|
||||
>>> u.find_unit(u.inch**3)[:9]
|
||||
['L', 'l', 'cL', 'cl', 'dL', 'dl', 'mL', 'ml', 'liter']
|
||||
"""
|
||||
unit_system = UnitSystem.get_unit_system(unit_system)
|
||||
|
||||
import sympy.physics.units as u
|
||||
rv = []
|
||||
if isinstance(quantity, str):
|
||||
rv = [i for i in dir(u) if quantity in i and isinstance(getattr(u, i), Quantity)]
|
||||
dim = getattr(u, quantity)
|
||||
if isinstance(dim, Dimension):
|
||||
rv.extend(find_unit(dim))
|
||||
else:
|
||||
for i in sorted(dir(u)):
|
||||
other = getattr(u, i)
|
||||
if not isinstance(other, Quantity):
|
||||
continue
|
||||
if isinstance(quantity, Quantity):
|
||||
if quantity.dimension == other.dimension:
|
||||
rv.append(str(i))
|
||||
elif isinstance(quantity, Dimension):
|
||||
if other.dimension == quantity:
|
||||
rv.append(str(i))
|
||||
elif other.dimension == Dimension(unit_system.get_dimensional_expr(quantity)):
|
||||
rv.append(str(i))
|
||||
return sorted(set(rv), key=lambda x: (len(x), x))
|
||||
|
||||
# NOTE: the old units module had additional variables:
|
||||
# 'density', 'illuminance', 'resistance'.
|
||||
# They were not dimensions, but units (old Unit class).
|
||||
|
||||
__all__ = [
|
||||
'Dimension', 'DimensionSystem',
|
||||
'UnitSystem',
|
||||
'convert_to',
|
||||
'Quantity',
|
||||
|
||||
'amount_of_substance', 'acceleration', 'action', 'area',
|
||||
'capacitance', 'charge', 'conductance', 'current', 'energy',
|
||||
'force', 'frequency', 'impedance', 'inductance', 'length',
|
||||
'luminous_intensity', 'magnetic_density',
|
||||
'magnetic_flux', 'mass', 'momentum', 'power', 'pressure', 'temperature', 'time',
|
||||
'velocity', 'voltage', 'volume',
|
||||
|
||||
'Unit',
|
||||
|
||||
'speed',
|
||||
'luminosity',
|
||||
'magnetic_flux_density',
|
||||
'amount',
|
||||
|
||||
'yotta',
|
||||
'zetta',
|
||||
'exa',
|
||||
'peta',
|
||||
'tera',
|
||||
'giga',
|
||||
'mega',
|
||||
'kilo',
|
||||
'hecto',
|
||||
'deca',
|
||||
'deci',
|
||||
'centi',
|
||||
'milli',
|
||||
'micro',
|
||||
'nano',
|
||||
'pico',
|
||||
'femto',
|
||||
'atto',
|
||||
'zepto',
|
||||
'yocto',
|
||||
|
||||
'kibi',
|
||||
'mebi',
|
||||
'gibi',
|
||||
'tebi',
|
||||
'pebi',
|
||||
'exbi',
|
||||
|
||||
'percent', 'percents',
|
||||
'permille',
|
||||
'rad', 'radian', 'radians',
|
||||
'deg', 'degree', 'degrees',
|
||||
'sr', 'steradian', 'steradians',
|
||||
'mil', 'angular_mil', 'angular_mils',
|
||||
'm', 'meter', 'meters',
|
||||
'kg', 'kilogram', 'kilograms',
|
||||
's', 'second', 'seconds',
|
||||
'A', 'ampere', 'amperes',
|
||||
'K', 'kelvin', 'kelvins',
|
||||
'mol', 'mole', 'moles',
|
||||
'cd', 'candela', 'candelas',
|
||||
'g', 'gram', 'grams',
|
||||
'mg', 'milligram', 'milligrams',
|
||||
'ug', 'microgram', 'micrograms',
|
||||
't', 'tonne', 'metric_ton',
|
||||
'newton', 'newtons', 'N',
|
||||
'joule', 'joules', 'J',
|
||||
'watt', 'watts', 'W',
|
||||
'pascal', 'pascals', 'Pa', 'pa',
|
||||
'hertz', 'hz', 'Hz',
|
||||
'coulomb', 'coulombs', 'C',
|
||||
'volt', 'volts', 'v', 'V',
|
||||
'ohm', 'ohms',
|
||||
'siemens', 'S', 'mho', 'mhos',
|
||||
'farad', 'farads', 'F',
|
||||
'henry', 'henrys', 'H',
|
||||
'tesla', 'teslas', 'T',
|
||||
'weber', 'webers', 'Wb', 'wb',
|
||||
'optical_power', 'dioptre', 'D',
|
||||
'lux', 'lx',
|
||||
'katal', 'kat',
|
||||
'gray', 'Gy',
|
||||
'becquerel', 'Bq',
|
||||
'km', 'kilometer', 'kilometers',
|
||||
'dm', 'decimeter', 'decimeters',
|
||||
'cm', 'centimeter', 'centimeters',
|
||||
'mm', 'millimeter', 'millimeters',
|
||||
'um', 'micrometer', 'micrometers', 'micron', 'microns',
|
||||
'nm', 'nanometer', 'nanometers',
|
||||
'pm', 'picometer', 'picometers',
|
||||
'ft', 'foot', 'feet',
|
||||
'inch', 'inches',
|
||||
'yd', 'yard', 'yards',
|
||||
'mi', 'mile', 'miles',
|
||||
'nmi', 'nautical_mile', 'nautical_miles',
|
||||
'angstrom', 'angstroms',
|
||||
'ha', 'hectare',
|
||||
'l', 'L', 'liter', 'liters',
|
||||
'dl', 'dL', 'deciliter', 'deciliters',
|
||||
'cl', 'cL', 'centiliter', 'centiliters',
|
||||
'ml', 'mL', 'milliliter', 'milliliters',
|
||||
'ms', 'millisecond', 'milliseconds',
|
||||
'us', 'microsecond', 'microseconds',
|
||||
'ns', 'nanosecond', 'nanoseconds',
|
||||
'ps', 'picosecond', 'picoseconds',
|
||||
'minute', 'minutes',
|
||||
'h', 'hour', 'hours',
|
||||
'day', 'days',
|
||||
'anomalistic_year', 'anomalistic_years',
|
||||
'sidereal_year', 'sidereal_years',
|
||||
'tropical_year', 'tropical_years',
|
||||
'common_year', 'common_years',
|
||||
'julian_year', 'julian_years',
|
||||
'draconic_year', 'draconic_years',
|
||||
'gaussian_year', 'gaussian_years',
|
||||
'full_moon_cycle', 'full_moon_cycles',
|
||||
'year', 'years',
|
||||
'G', 'gravitational_constant',
|
||||
'c', 'speed_of_light',
|
||||
'elementary_charge',
|
||||
'hbar',
|
||||
'planck',
|
||||
'eV', 'electronvolt', 'electronvolts',
|
||||
'avogadro_number',
|
||||
'avogadro', 'avogadro_constant',
|
||||
'boltzmann', 'boltzmann_constant',
|
||||
'stefan', 'stefan_boltzmann_constant',
|
||||
'R', 'molar_gas_constant',
|
||||
'faraday_constant',
|
||||
'josephson_constant',
|
||||
'von_klitzing_constant',
|
||||
'Da', 'dalton', 'amu', 'amus', 'atomic_mass_unit', 'atomic_mass_constant',
|
||||
'me', 'electron_rest_mass',
|
||||
'gee', 'gees', 'acceleration_due_to_gravity',
|
||||
'u0', 'magnetic_constant', 'vacuum_permeability',
|
||||
'e0', 'electric_constant', 'vacuum_permittivity',
|
||||
'Z0', 'vacuum_impedance',
|
||||
'coulomb_constant', 'electric_force_constant',
|
||||
'atmosphere', 'atmospheres', 'atm',
|
||||
'kPa',
|
||||
'bar', 'bars',
|
||||
'pound', 'pounds',
|
||||
'psi',
|
||||
'dHg0',
|
||||
'mmHg', 'torr',
|
||||
'mmu', 'mmus', 'milli_mass_unit',
|
||||
'quart', 'quarts',
|
||||
'ly', 'lightyear', 'lightyears',
|
||||
'au', 'astronomical_unit', 'astronomical_units',
|
||||
'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', 'bits',
|
||||
'byte',
|
||||
'kibibyte', 'kibibytes',
|
||||
'mebibyte', 'mebibytes',
|
||||
'gibibyte', 'gibibytes',
|
||||
'tebibyte', 'tebibytes',
|
||||
'pebibyte', 'pebibytes',
|
||||
'exbibyte', 'exbibytes',
|
||||
|
||||
'mks', 'mksa', 'si',
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,265 @@
|
||||
from .unit_definitions import (
|
||||
percent, percents,
|
||||
permille,
|
||||
rad, radian, radians,
|
||||
deg, degree, degrees,
|
||||
sr, steradian, steradians,
|
||||
mil, angular_mil, angular_mils,
|
||||
m, meter, meters,
|
||||
kg, kilogram, kilograms,
|
||||
s, second, seconds,
|
||||
A, ampere, amperes,
|
||||
K, kelvin, kelvins,
|
||||
mol, mole, moles,
|
||||
cd, candela, candelas,
|
||||
g, gram, grams,
|
||||
mg, milligram, milligrams,
|
||||
ug, microgram, micrograms,
|
||||
t, tonne, metric_ton,
|
||||
newton, newtons, N,
|
||||
joule, joules, J,
|
||||
watt, watts, W,
|
||||
pascal, pascals, Pa, pa,
|
||||
hertz, hz, Hz,
|
||||
coulomb, coulombs, C,
|
||||
volt, volts, v, V,
|
||||
ohm, ohms,
|
||||
siemens, S, mho, mhos,
|
||||
farad, farads, F,
|
||||
henry, henrys, H,
|
||||
tesla, teslas, T,
|
||||
weber, webers, Wb, wb,
|
||||
optical_power, dioptre, D,
|
||||
lux, lx,
|
||||
katal, kat,
|
||||
gray, Gy,
|
||||
becquerel, Bq,
|
||||
km, kilometer, kilometers,
|
||||
dm, decimeter, decimeters,
|
||||
cm, centimeter, centimeters,
|
||||
mm, millimeter, millimeters,
|
||||
um, micrometer, micrometers, micron, microns,
|
||||
nm, nanometer, nanometers,
|
||||
pm, picometer, picometers,
|
||||
ft, foot, feet,
|
||||
inch, inches,
|
||||
yd, yard, yards,
|
||||
mi, mile, miles,
|
||||
nmi, nautical_mile, nautical_miles,
|
||||
ha, hectare,
|
||||
l, L, liter, liters,
|
||||
dl, dL, deciliter, deciliters,
|
||||
cl, cL, centiliter, centiliters,
|
||||
ml, mL, milliliter, milliliters,
|
||||
ms, millisecond, milliseconds,
|
||||
us, microsecond, microseconds,
|
||||
ns, nanosecond, nanoseconds,
|
||||
ps, picosecond, picoseconds,
|
||||
minute, minutes,
|
||||
h, hour, hours,
|
||||
day, days,
|
||||
anomalistic_year, anomalistic_years,
|
||||
sidereal_year, sidereal_years,
|
||||
tropical_year, tropical_years,
|
||||
common_year, common_years,
|
||||
julian_year, julian_years,
|
||||
draconic_year, draconic_years,
|
||||
gaussian_year, gaussian_years,
|
||||
full_moon_cycle, full_moon_cycles,
|
||||
year, years,
|
||||
G, gravitational_constant,
|
||||
c, speed_of_light,
|
||||
elementary_charge,
|
||||
hbar,
|
||||
planck,
|
||||
eV, electronvolt, electronvolts,
|
||||
avogadro_number,
|
||||
avogadro, avogadro_constant,
|
||||
boltzmann, boltzmann_constant,
|
||||
stefan, stefan_boltzmann_constant,
|
||||
R, molar_gas_constant,
|
||||
faraday_constant,
|
||||
josephson_constant,
|
||||
von_klitzing_constant,
|
||||
Da, dalton, amu, amus, atomic_mass_unit, atomic_mass_constant,
|
||||
me, electron_rest_mass,
|
||||
gee, gees, acceleration_due_to_gravity,
|
||||
u0, magnetic_constant, vacuum_permeability,
|
||||
e0, electric_constant, vacuum_permittivity,
|
||||
Z0, vacuum_impedance,
|
||||
coulomb_constant, coulombs_constant, electric_force_constant,
|
||||
atmosphere, atmospheres, atm,
|
||||
kPa, kilopascal,
|
||||
bar, bars,
|
||||
pound, pounds,
|
||||
psi,
|
||||
dHg0,
|
||||
mmHg, torr,
|
||||
mmu, mmus, milli_mass_unit,
|
||||
quart, quarts,
|
||||
angstrom, angstroms,
|
||||
ly, lightyear, lightyears,
|
||||
au, astronomical_unit, astronomical_units,
|
||||
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, bits,
|
||||
byte,
|
||||
kibibyte, kibibytes,
|
||||
mebibyte, mebibytes,
|
||||
gibibyte, gibibytes,
|
||||
tebibyte, tebibytes,
|
||||
pebibyte, pebibytes,
|
||||
exbibyte, exbibytes,
|
||||
curie, rutherford
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
'percent', 'percents',
|
||||
'permille',
|
||||
'rad', 'radian', 'radians',
|
||||
'deg', 'degree', 'degrees',
|
||||
'sr', 'steradian', 'steradians',
|
||||
'mil', 'angular_mil', 'angular_mils',
|
||||
'm', 'meter', 'meters',
|
||||
'kg', 'kilogram', 'kilograms',
|
||||
's', 'second', 'seconds',
|
||||
'A', 'ampere', 'amperes',
|
||||
'K', 'kelvin', 'kelvins',
|
||||
'mol', 'mole', 'moles',
|
||||
'cd', 'candela', 'candelas',
|
||||
'g', 'gram', 'grams',
|
||||
'mg', 'milligram', 'milligrams',
|
||||
'ug', 'microgram', 'micrograms',
|
||||
't', 'tonne', 'metric_ton',
|
||||
'newton', 'newtons', 'N',
|
||||
'joule', 'joules', 'J',
|
||||
'watt', 'watts', 'W',
|
||||
'pascal', 'pascals', 'Pa', 'pa',
|
||||
'hertz', 'hz', 'Hz',
|
||||
'coulomb', 'coulombs', 'C',
|
||||
'volt', 'volts', 'v', 'V',
|
||||
'ohm', 'ohms',
|
||||
'siemens', 'S', 'mho', 'mhos',
|
||||
'farad', 'farads', 'F',
|
||||
'henry', 'henrys', 'H',
|
||||
'tesla', 'teslas', 'T',
|
||||
'weber', 'webers', 'Wb', 'wb',
|
||||
'optical_power', 'dioptre', 'D',
|
||||
'lux', 'lx',
|
||||
'katal', 'kat',
|
||||
'gray', 'Gy',
|
||||
'becquerel', 'Bq',
|
||||
'km', 'kilometer', 'kilometers',
|
||||
'dm', 'decimeter', 'decimeters',
|
||||
'cm', 'centimeter', 'centimeters',
|
||||
'mm', 'millimeter', 'millimeters',
|
||||
'um', 'micrometer', 'micrometers', 'micron', 'microns',
|
||||
'nm', 'nanometer', 'nanometers',
|
||||
'pm', 'picometer', 'picometers',
|
||||
'ft', 'foot', 'feet',
|
||||
'inch', 'inches',
|
||||
'yd', 'yard', 'yards',
|
||||
'mi', 'mile', 'miles',
|
||||
'nmi', 'nautical_mile', 'nautical_miles',
|
||||
'ha', 'hectare',
|
||||
'l', 'L', 'liter', 'liters',
|
||||
'dl', 'dL', 'deciliter', 'deciliters',
|
||||
'cl', 'cL', 'centiliter', 'centiliters',
|
||||
'ml', 'mL', 'milliliter', 'milliliters',
|
||||
'ms', 'millisecond', 'milliseconds',
|
||||
'us', 'microsecond', 'microseconds',
|
||||
'ns', 'nanosecond', 'nanoseconds',
|
||||
'ps', 'picosecond', 'picoseconds',
|
||||
'minute', 'minutes',
|
||||
'h', 'hour', 'hours',
|
||||
'day', 'days',
|
||||
'anomalistic_year', 'anomalistic_years',
|
||||
'sidereal_year', 'sidereal_years',
|
||||
'tropical_year', 'tropical_years',
|
||||
'common_year', 'common_years',
|
||||
'julian_year', 'julian_years',
|
||||
'draconic_year', 'draconic_years',
|
||||
'gaussian_year', 'gaussian_years',
|
||||
'full_moon_cycle', 'full_moon_cycles',
|
||||
'year', 'years',
|
||||
'G', 'gravitational_constant',
|
||||
'c', 'speed_of_light',
|
||||
'elementary_charge',
|
||||
'hbar',
|
||||
'planck',
|
||||
'eV', 'electronvolt', 'electronvolts',
|
||||
'avogadro_number',
|
||||
'avogadro', 'avogadro_constant',
|
||||
'boltzmann', 'boltzmann_constant',
|
||||
'stefan', 'stefan_boltzmann_constant',
|
||||
'R', 'molar_gas_constant',
|
||||
'faraday_constant',
|
||||
'josephson_constant',
|
||||
'von_klitzing_constant',
|
||||
'Da', 'dalton', 'amu', 'amus', 'atomic_mass_unit', 'atomic_mass_constant',
|
||||
'me', 'electron_rest_mass',
|
||||
'gee', 'gees', 'acceleration_due_to_gravity',
|
||||
'u0', 'magnetic_constant', 'vacuum_permeability',
|
||||
'e0', 'electric_constant', 'vacuum_permittivity',
|
||||
'Z0', 'vacuum_impedance',
|
||||
'coulomb_constant', 'coulombs_constant', 'electric_force_constant',
|
||||
'atmosphere', 'atmospheres', 'atm',
|
||||
'kPa', 'kilopascal',
|
||||
'bar', 'bars',
|
||||
'pound', 'pounds',
|
||||
'psi',
|
||||
'dHg0',
|
||||
'mmHg', 'torr',
|
||||
'mmu', 'mmus', 'milli_mass_unit',
|
||||
'quart', 'quarts',
|
||||
'angstrom', 'angstroms',
|
||||
'ly', 'lightyear', 'lightyears',
|
||||
'au', 'astronomical_unit', 'astronomical_units',
|
||||
'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', 'bits',
|
||||
'byte',
|
||||
'kibibyte', 'kibibytes',
|
||||
'mebibyte', 'mebibytes',
|
||||
'gibibyte', 'gibibytes',
|
||||
'tebibyte', 'tebibytes',
|
||||
'pebibyte', 'pebibytes',
|
||||
'exbibyte', 'exbibytes',
|
||||
'curie', 'rutherford',
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,43 @@
|
||||
from sympy.physics.units import Dimension
|
||||
|
||||
|
||||
angle: Dimension = Dimension(name="angle")
|
||||
|
||||
# base dimensions (MKS)
|
||||
length = Dimension(name="length", symbol="L")
|
||||
mass = Dimension(name="mass", symbol="M")
|
||||
time = Dimension(name="time", symbol="T")
|
||||
|
||||
# base dimensions (MKSA not in MKS)
|
||||
current: Dimension = Dimension(name='current', symbol='I')
|
||||
|
||||
# other base dimensions:
|
||||
temperature: Dimension = Dimension("temperature", "T")
|
||||
amount_of_substance: Dimension = Dimension("amount_of_substance")
|
||||
luminous_intensity: Dimension = Dimension("luminous_intensity")
|
||||
|
||||
# derived dimensions (MKS)
|
||||
velocity = Dimension(name="velocity")
|
||||
acceleration = Dimension(name="acceleration")
|
||||
momentum = Dimension(name="momentum")
|
||||
force = Dimension(name="force", symbol="F")
|
||||
energy = Dimension(name="energy", symbol="E")
|
||||
power = Dimension(name="power")
|
||||
pressure = Dimension(name="pressure")
|
||||
frequency = Dimension(name="frequency", symbol="f")
|
||||
action = Dimension(name="action", symbol="A")
|
||||
area = Dimension("area")
|
||||
volume = Dimension("volume")
|
||||
|
||||
# derived dimensions (MKSA not in MKS)
|
||||
voltage: Dimension = Dimension(name='voltage', symbol='U')
|
||||
impedance: Dimension = Dimension(name='impedance', symbol='Z')
|
||||
conductance: Dimension = Dimension(name='conductance', symbol='G')
|
||||
capacitance: Dimension = Dimension(name='capacitance')
|
||||
inductance: Dimension = Dimension(name='inductance')
|
||||
charge: Dimension = Dimension(name='charge', symbol='Q')
|
||||
magnetic_density: Dimension = Dimension(name='magnetic_density', symbol='B')
|
||||
magnetic_flux: Dimension = Dimension(name='magnetic_flux')
|
||||
|
||||
# Dimensions in information theory:
|
||||
information: Dimension = Dimension(name='information')
|
||||
@@ -0,0 +1,407 @@
|
||||
from sympy.physics.units.definitions.dimension_definitions import current, temperature, amount_of_substance, \
|
||||
luminous_intensity, angle, charge, voltage, impedance, conductance, capacitance, inductance, magnetic_density, \
|
||||
magnetic_flux, information
|
||||
|
||||
from sympy.core.numbers import (Rational, pi)
|
||||
from sympy.core.singleton import S as S_singleton
|
||||
from sympy.physics.units.prefixes import kilo, mega, milli, micro, deci, centi, nano, pico, kibi, mebi, gibi, tebi, pebi, exbi
|
||||
from sympy.physics.units.quantities import PhysicalConstant, Quantity
|
||||
|
||||
One = S_singleton.One
|
||||
|
||||
#### UNITS ####
|
||||
|
||||
# Dimensionless:
|
||||
percent = percents = Quantity("percent", latex_repr=r"\%")
|
||||
percent.set_global_relative_scale_factor(Rational(1, 100), One)
|
||||
|
||||
permille = Quantity("permille")
|
||||
permille.set_global_relative_scale_factor(Rational(1, 1000), One)
|
||||
|
||||
|
||||
# Angular units (dimensionless)
|
||||
rad = radian = radians = Quantity("radian", abbrev="rad")
|
||||
radian.set_global_dimension(angle)
|
||||
deg = degree = degrees = Quantity("degree", abbrev="deg", latex_repr=r"^\circ")
|
||||
degree.set_global_relative_scale_factor(pi/180, radian)
|
||||
sr = steradian = steradians = Quantity("steradian", abbrev="sr")
|
||||
mil = angular_mil = angular_mils = Quantity("angular_mil", abbrev="mil")
|
||||
|
||||
# Base units:
|
||||
m = meter = meters = Quantity("meter", abbrev="m")
|
||||
|
||||
# gram; used to define its prefixed units
|
||||
g = gram = grams = Quantity("gram", abbrev="g")
|
||||
|
||||
# NOTE: the `kilogram` has scale factor 1000. In SI, kg is a base unit, but
|
||||
# nonetheless we are trying to be compatible with the `kilo` prefix. In a
|
||||
# similar manner, people using CGS or gaussian units could argue that the
|
||||
# `centimeter` rather than `meter` is the fundamental unit for length, but the
|
||||
# scale factor of `centimeter` will be kept as 1/100 to be compatible with the
|
||||
# `centi` prefix. The current state of the code assumes SI unit dimensions, in
|
||||
# the future this module will be modified in order to be unit system-neutral
|
||||
# (that is, support all kinds of unit systems).
|
||||
kg = kilogram = kilograms = Quantity("kilogram", abbrev="kg")
|
||||
kg.set_global_relative_scale_factor(kilo, gram)
|
||||
|
||||
s = second = seconds = Quantity("second", abbrev="s")
|
||||
A = ampere = amperes = Quantity("ampere", abbrev='A')
|
||||
ampere.set_global_dimension(current)
|
||||
K = kelvin = kelvins = Quantity("kelvin", abbrev='K')
|
||||
kelvin.set_global_dimension(temperature)
|
||||
mol = mole = moles = Quantity("mole", abbrev="mol")
|
||||
mole.set_global_dimension(amount_of_substance)
|
||||
cd = candela = candelas = Quantity("candela", abbrev="cd")
|
||||
candela.set_global_dimension(luminous_intensity)
|
||||
|
||||
# derived units
|
||||
newton = newtons = N = Quantity("newton", abbrev="N")
|
||||
|
||||
kilonewton = kilonewtons = kN = Quantity("kilonewton", abbrev="kN")
|
||||
kilonewton.set_global_relative_scale_factor(kilo, newton)
|
||||
|
||||
meganewton = meganewtons = MN = Quantity("meganewton", abbrev="MN")
|
||||
meganewton.set_global_relative_scale_factor(mega, newton)
|
||||
|
||||
joule = joules = J = Quantity("joule", abbrev="J")
|
||||
watt = watts = W = Quantity("watt", abbrev="W")
|
||||
pascal = pascals = Pa = pa = Quantity("pascal", abbrev="Pa")
|
||||
hertz = hz = Hz = Quantity("hertz", abbrev="Hz")
|
||||
|
||||
# CGS derived units:
|
||||
dyne = Quantity("dyne")
|
||||
dyne.set_global_relative_scale_factor(One/10**5, newton)
|
||||
erg = Quantity("erg")
|
||||
erg.set_global_relative_scale_factor(One/10**7, joule)
|
||||
|
||||
# MKSA extension to MKS: derived units
|
||||
coulomb = coulombs = C = Quantity("coulomb", abbrev='C')
|
||||
coulomb.set_global_dimension(charge)
|
||||
volt = volts = v = V = Quantity("volt", abbrev='V')
|
||||
volt.set_global_dimension(voltage)
|
||||
ohm = ohms = Quantity("ohm", abbrev='ohm', latex_repr=r"\Omega")
|
||||
ohm.set_global_dimension(impedance)
|
||||
siemens = S = mho = mhos = Quantity("siemens", abbrev='S')
|
||||
siemens.set_global_dimension(conductance)
|
||||
farad = farads = F = Quantity("farad", abbrev='F')
|
||||
farad.set_global_dimension(capacitance)
|
||||
henry = henrys = H = Quantity("henry", abbrev='H')
|
||||
henry.set_global_dimension(inductance)
|
||||
tesla = teslas = T = Quantity("tesla", abbrev='T')
|
||||
tesla.set_global_dimension(magnetic_density)
|
||||
weber = webers = Wb = wb = Quantity("weber", abbrev='Wb')
|
||||
weber.set_global_dimension(magnetic_flux)
|
||||
|
||||
# CGS units for electromagnetic quantities:
|
||||
statampere = Quantity("statampere")
|
||||
statcoulomb = statC = franklin = Quantity("statcoulomb", abbrev="statC")
|
||||
statvolt = Quantity("statvolt")
|
||||
gauss = Quantity("gauss")
|
||||
maxwell = Quantity("maxwell")
|
||||
debye = Quantity("debye")
|
||||
oersted = Quantity("oersted")
|
||||
|
||||
# Other derived units:
|
||||
optical_power = dioptre = diopter = D = Quantity("dioptre")
|
||||
lux = lx = Quantity("lux", abbrev="lx")
|
||||
|
||||
# katal is the SI unit of catalytic activity
|
||||
katal = kat = Quantity("katal", abbrev="kat")
|
||||
|
||||
# gray is the SI unit of absorbed dose
|
||||
gray = Gy = Quantity("gray")
|
||||
|
||||
# becquerel is the SI unit of radioactivity
|
||||
becquerel = Bq = Quantity("becquerel", abbrev="Bq")
|
||||
|
||||
|
||||
# Common mass units
|
||||
|
||||
mg = milligram = milligrams = Quantity("milligram", abbrev="mg")
|
||||
mg.set_global_relative_scale_factor(milli, gram)
|
||||
|
||||
ug = microgram = micrograms = Quantity("microgram", abbrev="ug", latex_repr=r"\mu\text{g}")
|
||||
ug.set_global_relative_scale_factor(micro, gram)
|
||||
|
||||
# Atomic mass constant
|
||||
Da = dalton = amu = amus = atomic_mass_unit = atomic_mass_constant = PhysicalConstant("atomic_mass_constant")
|
||||
|
||||
t = metric_ton = tonne = Quantity("tonne", abbrev="t")
|
||||
tonne.set_global_relative_scale_factor(mega, gram)
|
||||
|
||||
# Electron rest mass
|
||||
me = electron_rest_mass = Quantity("electron_rest_mass", abbrev="me")
|
||||
|
||||
|
||||
# Common length units
|
||||
|
||||
km = kilometer = kilometers = Quantity("kilometer", abbrev="km")
|
||||
km.set_global_relative_scale_factor(kilo, meter)
|
||||
|
||||
dm = decimeter = decimeters = Quantity("decimeter", abbrev="dm")
|
||||
dm.set_global_relative_scale_factor(deci, meter)
|
||||
|
||||
cm = centimeter = centimeters = Quantity("centimeter", abbrev="cm")
|
||||
cm.set_global_relative_scale_factor(centi, meter)
|
||||
|
||||
mm = millimeter = millimeters = Quantity("millimeter", abbrev="mm")
|
||||
mm.set_global_relative_scale_factor(milli, meter)
|
||||
|
||||
um = micrometer = micrometers = micron = microns = \
|
||||
Quantity("micrometer", abbrev="um", latex_repr=r'\mu\text{m}')
|
||||
um.set_global_relative_scale_factor(micro, meter)
|
||||
|
||||
nm = nanometer = nanometers = Quantity("nanometer", abbrev="nm")
|
||||
nm.set_global_relative_scale_factor(nano, meter)
|
||||
|
||||
pm = picometer = picometers = Quantity("picometer", abbrev="pm")
|
||||
pm.set_global_relative_scale_factor(pico, meter)
|
||||
|
||||
ft = foot = feet = Quantity("foot", abbrev="ft")
|
||||
ft.set_global_relative_scale_factor(Rational(3048, 10000), meter)
|
||||
|
||||
inch = inches = Quantity("inch")
|
||||
inch.set_global_relative_scale_factor(Rational(1, 12), foot)
|
||||
|
||||
yd = yard = yards = Quantity("yard", abbrev="yd")
|
||||
yd.set_global_relative_scale_factor(3, feet)
|
||||
|
||||
mi = mile = miles = Quantity("mile")
|
||||
mi.set_global_relative_scale_factor(5280, feet)
|
||||
|
||||
nmi = nautical_mile = nautical_miles = Quantity("nautical_mile")
|
||||
nmi.set_global_relative_scale_factor(6076, feet)
|
||||
|
||||
angstrom = angstroms = Quantity("angstrom", latex_repr=r'\r{A}')
|
||||
angstrom.set_global_relative_scale_factor(Rational(1, 10**10), meter)
|
||||
|
||||
|
||||
# Common volume and area units
|
||||
|
||||
ha = hectare = Quantity("hectare", abbrev="ha")
|
||||
|
||||
l = L = liter = liters = Quantity("liter", abbrev="l")
|
||||
|
||||
dl = dL = deciliter = deciliters = Quantity("deciliter", abbrev="dl")
|
||||
dl.set_global_relative_scale_factor(Rational(1, 10), liter)
|
||||
|
||||
cl = cL = centiliter = centiliters = Quantity("centiliter", abbrev="cl")
|
||||
cl.set_global_relative_scale_factor(Rational(1, 100), liter)
|
||||
|
||||
ml = mL = milliliter = milliliters = Quantity("milliliter", abbrev="ml")
|
||||
ml.set_global_relative_scale_factor(Rational(1, 1000), liter)
|
||||
|
||||
|
||||
# Common time units
|
||||
|
||||
ms = millisecond = milliseconds = Quantity("millisecond", abbrev="ms")
|
||||
millisecond.set_global_relative_scale_factor(milli, second)
|
||||
|
||||
us = microsecond = microseconds = Quantity("microsecond", abbrev="us", latex_repr=r'\mu\text{s}')
|
||||
microsecond.set_global_relative_scale_factor(micro, second)
|
||||
|
||||
ns = nanosecond = nanoseconds = Quantity("nanosecond", abbrev="ns")
|
||||
nanosecond.set_global_relative_scale_factor(nano, second)
|
||||
|
||||
ps = picosecond = picoseconds = Quantity("picosecond", abbrev="ps")
|
||||
picosecond.set_global_relative_scale_factor(pico, second)
|
||||
|
||||
minute = minutes = Quantity("minute")
|
||||
minute.set_global_relative_scale_factor(60, second)
|
||||
|
||||
h = hour = hours = Quantity("hour")
|
||||
hour.set_global_relative_scale_factor(60, minute)
|
||||
|
||||
day = days = Quantity("day")
|
||||
day.set_global_relative_scale_factor(24, hour)
|
||||
|
||||
anomalistic_year = anomalistic_years = Quantity("anomalistic_year")
|
||||
anomalistic_year.set_global_relative_scale_factor(365.259636, day)
|
||||
|
||||
sidereal_year = sidereal_years = Quantity("sidereal_year")
|
||||
sidereal_year.set_global_relative_scale_factor(31558149.540, seconds)
|
||||
|
||||
tropical_year = tropical_years = Quantity("tropical_year")
|
||||
tropical_year.set_global_relative_scale_factor(365.24219, day)
|
||||
|
||||
common_year = common_years = Quantity("common_year")
|
||||
common_year.set_global_relative_scale_factor(365, day)
|
||||
|
||||
julian_year = julian_years = Quantity("julian_year")
|
||||
julian_year.set_global_relative_scale_factor((365 + One/4), day)
|
||||
|
||||
draconic_year = draconic_years = Quantity("draconic_year")
|
||||
draconic_year.set_global_relative_scale_factor(346.62, day)
|
||||
|
||||
gaussian_year = gaussian_years = Quantity("gaussian_year")
|
||||
gaussian_year.set_global_relative_scale_factor(365.2568983, day)
|
||||
|
||||
full_moon_cycle = full_moon_cycles = Quantity("full_moon_cycle")
|
||||
full_moon_cycle.set_global_relative_scale_factor(411.78443029, day)
|
||||
|
||||
year = years = tropical_year
|
||||
|
||||
|
||||
#### CONSTANTS ####
|
||||
|
||||
# Newton constant
|
||||
G = gravitational_constant = PhysicalConstant("gravitational_constant", abbrev="G")
|
||||
|
||||
# speed of light
|
||||
c = speed_of_light = PhysicalConstant("speed_of_light", abbrev="c")
|
||||
|
||||
# elementary charge
|
||||
elementary_charge = PhysicalConstant("elementary_charge", abbrev="e")
|
||||
|
||||
# Planck constant
|
||||
planck = PhysicalConstant("planck", abbrev="h")
|
||||
|
||||
# Reduced Planck constant
|
||||
hbar = PhysicalConstant("hbar", abbrev="hbar")
|
||||
|
||||
# Electronvolt
|
||||
eV = electronvolt = electronvolts = PhysicalConstant("electronvolt", abbrev="eV")
|
||||
|
||||
# Avogadro number
|
||||
avogadro_number = PhysicalConstant("avogadro_number")
|
||||
|
||||
# Avogadro constant
|
||||
avogadro = avogadro_constant = PhysicalConstant("avogadro_constant")
|
||||
|
||||
# Boltzmann constant
|
||||
boltzmann = boltzmann_constant = PhysicalConstant("boltzmann_constant")
|
||||
|
||||
# Stefan-Boltzmann constant
|
||||
stefan = stefan_boltzmann_constant = PhysicalConstant("stefan_boltzmann_constant")
|
||||
|
||||
# Molar gas constant
|
||||
R = molar_gas_constant = PhysicalConstant("molar_gas_constant", abbrev="R")
|
||||
|
||||
# Faraday constant
|
||||
faraday_constant = PhysicalConstant("faraday_constant")
|
||||
|
||||
# Josephson constant
|
||||
josephson_constant = PhysicalConstant("josephson_constant", abbrev="K_j")
|
||||
|
||||
# Von Klitzing constant
|
||||
von_klitzing_constant = PhysicalConstant("von_klitzing_constant", abbrev="R_k")
|
||||
|
||||
# Acceleration due to gravity (on the Earth surface)
|
||||
gee = gees = acceleration_due_to_gravity = PhysicalConstant("acceleration_due_to_gravity", abbrev="g")
|
||||
|
||||
# magnetic constant:
|
||||
u0 = magnetic_constant = vacuum_permeability = PhysicalConstant("magnetic_constant")
|
||||
|
||||
# electric constat:
|
||||
e0 = electric_constant = vacuum_permittivity = PhysicalConstant("vacuum_permittivity")
|
||||
|
||||
# vacuum impedance:
|
||||
Z0 = vacuum_impedance = PhysicalConstant("vacuum_impedance", abbrev='Z_0', latex_repr=r'Z_{0}')
|
||||
|
||||
# Coulomb's constant:
|
||||
coulomb_constant = coulombs_constant = electric_force_constant = \
|
||||
PhysicalConstant("coulomb_constant", abbrev="k_e")
|
||||
|
||||
|
||||
atmosphere = atmospheres = atm = Quantity("atmosphere", abbrev="atm")
|
||||
|
||||
kPa = kilopascal = Quantity("kilopascal", abbrev="kPa")
|
||||
kilopascal.set_global_relative_scale_factor(kilo, Pa)
|
||||
|
||||
bar = bars = Quantity("bar", abbrev="bar")
|
||||
|
||||
pound = pounds = Quantity("pound") # exact
|
||||
|
||||
psi = Quantity("psi")
|
||||
|
||||
dHg0 = 13.5951 # approx value at 0 C
|
||||
mmHg = torr = Quantity("mmHg")
|
||||
|
||||
atmosphere.set_global_relative_scale_factor(101325, pascal)
|
||||
bar.set_global_relative_scale_factor(100, kPa)
|
||||
pound.set_global_relative_scale_factor(Rational(45359237, 100000000), kg)
|
||||
|
||||
mmu = mmus = milli_mass_unit = Quantity("milli_mass_unit")
|
||||
|
||||
quart = quarts = Quantity("quart")
|
||||
|
||||
|
||||
# Other convenient units and magnitudes
|
||||
|
||||
ly = lightyear = lightyears = Quantity("lightyear", abbrev="ly")
|
||||
|
||||
au = astronomical_unit = astronomical_units = Quantity("astronomical_unit", abbrev="AU")
|
||||
|
||||
|
||||
# Fundamental Planck units:
|
||||
planck_mass = Quantity("planck_mass", abbrev="m_P", latex_repr=r'm_\text{P}')
|
||||
|
||||
planck_time = Quantity("planck_time", abbrev="t_P", latex_repr=r't_\text{P}')
|
||||
|
||||
planck_temperature = Quantity("planck_temperature", abbrev="T_P",
|
||||
latex_repr=r'T_\text{P}')
|
||||
|
||||
planck_length = Quantity("planck_length", abbrev="l_P", latex_repr=r'l_\text{P}')
|
||||
|
||||
planck_charge = Quantity("planck_charge", abbrev="q_P", latex_repr=r'q_\text{P}')
|
||||
|
||||
|
||||
# Derived Planck units:
|
||||
planck_area = Quantity("planck_area")
|
||||
|
||||
planck_volume = Quantity("planck_volume")
|
||||
|
||||
planck_momentum = Quantity("planck_momentum")
|
||||
|
||||
planck_energy = Quantity("planck_energy", abbrev="E_P", latex_repr=r'E_\text{P}')
|
||||
|
||||
planck_force = Quantity("planck_force", abbrev="F_P", latex_repr=r'F_\text{P}')
|
||||
|
||||
planck_power = Quantity("planck_power", abbrev="P_P", latex_repr=r'P_\text{P}')
|
||||
|
||||
planck_density = Quantity("planck_density", abbrev="rho_P", latex_repr=r'\rho_\text{P}')
|
||||
|
||||
planck_energy_density = Quantity("planck_energy_density", abbrev="rho^E_P")
|
||||
|
||||
planck_intensity = Quantity("planck_intensity", abbrev="I_P", latex_repr=r'I_\text{P}')
|
||||
|
||||
planck_angular_frequency = Quantity("planck_angular_frequency", abbrev="omega_P",
|
||||
latex_repr=r'\omega_\text{P}')
|
||||
|
||||
planck_pressure = Quantity("planck_pressure", abbrev="p_P", latex_repr=r'p_\text{P}')
|
||||
|
||||
planck_current = Quantity("planck_current", abbrev="I_P", latex_repr=r'I_\text{P}')
|
||||
|
||||
planck_voltage = Quantity("planck_voltage", abbrev="V_P", latex_repr=r'V_\text{P}')
|
||||
|
||||
planck_impedance = Quantity("planck_impedance", abbrev="Z_P", latex_repr=r'Z_\text{P}')
|
||||
|
||||
planck_acceleration = Quantity("planck_acceleration", abbrev="a_P",
|
||||
latex_repr=r'a_\text{P}')
|
||||
|
||||
|
||||
# Information theory units:
|
||||
bit = bits = Quantity("bit")
|
||||
bit.set_global_dimension(information)
|
||||
|
||||
byte = bytes = Quantity("byte")
|
||||
|
||||
kibibyte = kibibytes = Quantity("kibibyte")
|
||||
mebibyte = mebibytes = Quantity("mebibyte")
|
||||
gibibyte = gibibytes = Quantity("gibibyte")
|
||||
tebibyte = tebibytes = Quantity("tebibyte")
|
||||
pebibyte = pebibytes = Quantity("pebibyte")
|
||||
exbibyte = exbibytes = Quantity("exbibyte")
|
||||
|
||||
byte.set_global_relative_scale_factor(8, bit)
|
||||
kibibyte.set_global_relative_scale_factor(kibi, byte)
|
||||
mebibyte.set_global_relative_scale_factor(mebi, byte)
|
||||
gibibyte.set_global_relative_scale_factor(gibi, byte)
|
||||
tebibyte.set_global_relative_scale_factor(tebi, byte)
|
||||
pebibyte.set_global_relative_scale_factor(pebi, byte)
|
||||
exbibyte.set_global_relative_scale_factor(exbi, byte)
|
||||
|
||||
# Older units for radioactivity
|
||||
curie = Ci = Quantity("curie", abbrev="Ci")
|
||||
|
||||
rutherford = Rd = Quantity("rutherford", abbrev="Rd")
|
||||
@@ -0,0 +1,590 @@
|
||||
"""
|
||||
Definition of physical dimensions.
|
||||
|
||||
Unit systems will be constructed on top of these dimensions.
|
||||
|
||||
Most of the examples in the doc use MKS system and are presented from the
|
||||
computer point of view: from a human point, adding length to time is not legal
|
||||
in MKS but it is in natural system; for a computer in natural system there is
|
||||
no time dimension (but a velocity dimension instead) - in the basis - so the
|
||||
question of adding time to length has no meaning.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import collections
|
||||
from functools import reduce
|
||||
|
||||
from sympy.core.basic import Basic
|
||||
from sympy.core.containers import (Dict, Tuple)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.sorting import default_sort_key
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.matrices.dense import Matrix
|
||||
from sympy.functions.elementary.trigonometric import TrigonometricFunction
|
||||
from sympy.core.expr import Expr
|
||||
from sympy.core.power import Pow
|
||||
|
||||
|
||||
class _QuantityMapper:
|
||||
|
||||
_quantity_scale_factors_global: dict[Expr, Expr] = {}
|
||||
_quantity_dimensional_equivalence_map_global: dict[Expr, Expr] = {}
|
||||
_quantity_dimension_global: dict[Expr, Expr] = {}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._quantity_dimension_map = {}
|
||||
self._quantity_scale_factors = {}
|
||||
|
||||
def set_quantity_dimension(self, quantity, dimension):
|
||||
"""
|
||||
Set the dimension for the quantity in a unit system.
|
||||
|
||||
If this relation is valid in every unit system, use
|
||||
``quantity.set_global_dimension(dimension)`` instead.
|
||||
"""
|
||||
from sympy.physics.units import Quantity
|
||||
dimension = sympify(dimension)
|
||||
if not isinstance(dimension, Dimension):
|
||||
if dimension == 1:
|
||||
dimension = Dimension(1)
|
||||
else:
|
||||
raise ValueError("expected dimension or 1")
|
||||
elif isinstance(dimension, Quantity):
|
||||
dimension = self.get_quantity_dimension(dimension)
|
||||
self._quantity_dimension_map[quantity] = dimension
|
||||
|
||||
def set_quantity_scale_factor(self, quantity, scale_factor):
|
||||
"""
|
||||
Set the scale factor of a quantity relative to another quantity.
|
||||
|
||||
It should be used only once per quantity to just one other quantity,
|
||||
the algorithm will then be able to compute the scale factors to all
|
||||
other quantities.
|
||||
|
||||
In case the scale factor is valid in every unit system, please use
|
||||
``quantity.set_global_relative_scale_factor(scale_factor)`` instead.
|
||||
"""
|
||||
from sympy.physics.units import Quantity
|
||||
from sympy.physics.units.prefixes import Prefix
|
||||
scale_factor = sympify(scale_factor)
|
||||
# replace all prefixes by their ratio to canonical units:
|
||||
scale_factor = scale_factor.replace(
|
||||
lambda x: isinstance(x, Prefix),
|
||||
lambda x: x.scale_factor
|
||||
)
|
||||
# replace all quantities by their ratio to canonical units:
|
||||
scale_factor = scale_factor.replace(
|
||||
lambda x: isinstance(x, Quantity),
|
||||
lambda x: self.get_quantity_scale_factor(x)
|
||||
)
|
||||
self._quantity_scale_factors[quantity] = scale_factor
|
||||
|
||||
def get_quantity_dimension(self, unit):
|
||||
from sympy.physics.units import Quantity
|
||||
# First look-up the local dimension map, then the global one:
|
||||
if unit in self._quantity_dimension_map:
|
||||
return self._quantity_dimension_map[unit]
|
||||
if unit in self._quantity_dimension_global:
|
||||
return self._quantity_dimension_global[unit]
|
||||
if unit in self._quantity_dimensional_equivalence_map_global:
|
||||
dep_unit = self._quantity_dimensional_equivalence_map_global[unit]
|
||||
if isinstance(dep_unit, Quantity):
|
||||
return self.get_quantity_dimension(dep_unit)
|
||||
else:
|
||||
return Dimension(self.get_dimensional_expr(dep_unit))
|
||||
if isinstance(unit, Quantity):
|
||||
return Dimension(unit.name)
|
||||
else:
|
||||
return Dimension(1)
|
||||
|
||||
def get_quantity_scale_factor(self, unit):
|
||||
if unit in self._quantity_scale_factors:
|
||||
return self._quantity_scale_factors[unit]
|
||||
if unit in self._quantity_scale_factors_global:
|
||||
mul_factor, other_unit = self._quantity_scale_factors_global[unit]
|
||||
return mul_factor*self.get_quantity_scale_factor(other_unit)
|
||||
return S.One
|
||||
|
||||
|
||||
class Dimension(Expr):
|
||||
"""
|
||||
This class represent the dimension of a physical quantities.
|
||||
|
||||
The ``Dimension`` constructor takes as parameters a name and an optional
|
||||
symbol.
|
||||
|
||||
For example, in classical mechanics we know that time is different from
|
||||
temperature and dimensions make this difference (but they do not provide
|
||||
any measure of these quantities.
|
||||
|
||||
>>> from sympy.physics.units import Dimension
|
||||
>>> length = Dimension('length')
|
||||
>>> length
|
||||
Dimension(length)
|
||||
>>> time = Dimension('time')
|
||||
>>> time
|
||||
Dimension(time)
|
||||
|
||||
Dimensions can be composed using multiplication, division and
|
||||
exponentiation (by a number) to give new dimensions. Addition and
|
||||
subtraction is defined only when the two objects are the same dimension.
|
||||
|
||||
>>> velocity = length / time
|
||||
>>> velocity
|
||||
Dimension(length/time)
|
||||
|
||||
It is possible to use a dimension system object to get the dimensionsal
|
||||
dependencies of a dimension, for example the dimension system used by the
|
||||
SI units convention can be used:
|
||||
|
||||
>>> from sympy.physics.units.systems.si import dimsys_SI
|
||||
>>> dimsys_SI.get_dimensional_dependencies(velocity)
|
||||
{Dimension(length, L): 1, Dimension(time, T): -1}
|
||||
>>> length + length
|
||||
Dimension(length)
|
||||
>>> l2 = length**2
|
||||
>>> l2
|
||||
Dimension(length**2)
|
||||
>>> dimsys_SI.get_dimensional_dependencies(l2)
|
||||
{Dimension(length, L): 2}
|
||||
|
||||
"""
|
||||
|
||||
_op_priority = 13.0
|
||||
|
||||
# XXX: This doesn't seem to be used anywhere...
|
||||
_dimensional_dependencies = {} # type: ignore
|
||||
|
||||
is_commutative = True
|
||||
is_number = False
|
||||
# make sqrt(M**2) --> M
|
||||
is_positive = True
|
||||
is_real = True
|
||||
|
||||
def __new__(cls, name, symbol=None):
|
||||
|
||||
if isinstance(name, str):
|
||||
name = Symbol(name)
|
||||
else:
|
||||
name = sympify(name)
|
||||
|
||||
if not isinstance(name, Expr):
|
||||
raise TypeError("Dimension name needs to be a valid math expression")
|
||||
|
||||
if isinstance(symbol, str):
|
||||
symbol = Symbol(symbol)
|
||||
elif symbol is not None:
|
||||
assert isinstance(symbol, Symbol)
|
||||
|
||||
obj = Expr.__new__(cls, name)
|
||||
|
||||
obj._name = name
|
||||
obj._symbol = symbol
|
||||
return obj
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def symbol(self):
|
||||
return self._symbol
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
Display the string representation of the dimension.
|
||||
"""
|
||||
if self.symbol is None:
|
||||
return "Dimension(%s)" % (self.name)
|
||||
else:
|
||||
return "Dimension(%s, %s)" % (self.name, self.symbol)
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __neg__(self):
|
||||
return self
|
||||
|
||||
def __add__(self, other):
|
||||
from sympy.physics.units.quantities import Quantity
|
||||
other = sympify(other)
|
||||
if isinstance(other, Basic):
|
||||
if other.has(Quantity):
|
||||
raise TypeError("cannot sum dimension and quantity")
|
||||
if isinstance(other, Dimension) and self == other:
|
||||
return self
|
||||
return super().__add__(other)
|
||||
return self
|
||||
|
||||
def __radd__(self, other):
|
||||
return self.__add__(other)
|
||||
|
||||
def __sub__(self, other):
|
||||
# there is no notion of ordering (or magnitude) among dimension,
|
||||
# subtraction is equivalent to addition when the operation is legal
|
||||
return self + other
|
||||
|
||||
def __rsub__(self, other):
|
||||
# there is no notion of ordering (or magnitude) among dimension,
|
||||
# subtraction is equivalent to addition when the operation is legal
|
||||
return self + other
|
||||
|
||||
def __pow__(self, other):
|
||||
return self._eval_power(other)
|
||||
|
||||
def _eval_power(self, other):
|
||||
other = sympify(other)
|
||||
return Dimension(self.name**other)
|
||||
|
||||
def __mul__(self, other):
|
||||
from sympy.physics.units.quantities import Quantity
|
||||
if isinstance(other, Basic):
|
||||
if other.has(Quantity):
|
||||
raise TypeError("cannot sum dimension and quantity")
|
||||
if isinstance(other, Dimension):
|
||||
return Dimension(self.name*other.name)
|
||||
if not other.free_symbols: # other.is_number cannot be used
|
||||
return self
|
||||
return super().__mul__(other)
|
||||
return self
|
||||
|
||||
def __rmul__(self, other):
|
||||
return self.__mul__(other)
|
||||
|
||||
def __truediv__(self, other):
|
||||
return self*Pow(other, -1)
|
||||
|
||||
def __rtruediv__(self, other):
|
||||
return other * pow(self, -1)
|
||||
|
||||
@classmethod
|
||||
def _from_dimensional_dependencies(cls, dependencies):
|
||||
return reduce(lambda x, y: x * y, (
|
||||
d**e for d, e in dependencies.items()
|
||||
), 1)
|
||||
|
||||
def has_integer_powers(self, dim_sys):
|
||||
"""
|
||||
Check if the dimension object has only integer powers.
|
||||
|
||||
All the dimension powers should be integers, but rational powers may
|
||||
appear in intermediate steps. This method may be used to check that the
|
||||
final result is well-defined.
|
||||
"""
|
||||
|
||||
return all(dpow.is_Integer for dpow in dim_sys.get_dimensional_dependencies(self).values())
|
||||
|
||||
|
||||
# Create dimensions according to the base units in MKSA.
|
||||
# For other unit systems, they can be derived by transforming the base
|
||||
# dimensional dependency dictionary.
|
||||
|
||||
|
||||
class DimensionSystem(Basic, _QuantityMapper):
|
||||
r"""
|
||||
DimensionSystem represents a coherent set of dimensions.
|
||||
|
||||
The constructor takes three parameters:
|
||||
|
||||
- base dimensions;
|
||||
- derived dimensions: these are defined in terms of the base dimensions
|
||||
(for example velocity is defined from the division of length by time);
|
||||
- dependency of dimensions: how the derived dimensions depend
|
||||
on the base dimensions.
|
||||
|
||||
Optionally either the ``derived_dims`` or the ``dimensional_dependencies``
|
||||
may be omitted.
|
||||
"""
|
||||
|
||||
def __new__(cls, base_dims, derived_dims=(), dimensional_dependencies={}):
|
||||
dimensional_dependencies = dict(dimensional_dependencies)
|
||||
|
||||
def parse_dim(dim):
|
||||
if isinstance(dim, str):
|
||||
dim = Dimension(Symbol(dim))
|
||||
elif isinstance(dim, Dimension):
|
||||
pass
|
||||
elif isinstance(dim, Symbol):
|
||||
dim = Dimension(dim)
|
||||
else:
|
||||
raise TypeError("%s wrong type" % dim)
|
||||
return dim
|
||||
|
||||
base_dims = [parse_dim(i) for i in base_dims]
|
||||
derived_dims = [parse_dim(i) for i in derived_dims]
|
||||
|
||||
for dim in base_dims:
|
||||
if (dim in dimensional_dependencies
|
||||
and (len(dimensional_dependencies[dim]) != 1 or
|
||||
dimensional_dependencies[dim].get(dim, None) != 1)):
|
||||
raise IndexError("Repeated value in base dimensions")
|
||||
dimensional_dependencies[dim] = Dict({dim: 1})
|
||||
|
||||
def parse_dim_name(dim):
|
||||
if isinstance(dim, Dimension):
|
||||
return dim
|
||||
elif isinstance(dim, str):
|
||||
return Dimension(Symbol(dim))
|
||||
elif isinstance(dim, Symbol):
|
||||
return Dimension(dim)
|
||||
else:
|
||||
raise TypeError("unrecognized type %s for %s" % (type(dim), dim))
|
||||
|
||||
for dim in dimensional_dependencies.keys():
|
||||
dim = parse_dim(dim)
|
||||
if (dim not in derived_dims) and (dim not in base_dims):
|
||||
derived_dims.append(dim)
|
||||
|
||||
def parse_dict(d):
|
||||
return Dict({parse_dim_name(i): j for i, j in d.items()})
|
||||
|
||||
# Make sure everything is a SymPy type:
|
||||
dimensional_dependencies = {parse_dim_name(i): parse_dict(j) for i, j in
|
||||
dimensional_dependencies.items()}
|
||||
|
||||
for dim in derived_dims:
|
||||
if dim in base_dims:
|
||||
raise ValueError("Dimension %s both in base and derived" % dim)
|
||||
if dim not in dimensional_dependencies:
|
||||
# TODO: should this raise a warning?
|
||||
dimensional_dependencies[dim] = Dict({dim: 1})
|
||||
|
||||
base_dims.sort(key=default_sort_key)
|
||||
derived_dims.sort(key=default_sort_key)
|
||||
|
||||
base_dims = Tuple(*base_dims)
|
||||
derived_dims = Tuple(*derived_dims)
|
||||
dimensional_dependencies = Dict({i: Dict(j) for i, j in dimensional_dependencies.items()})
|
||||
obj = Basic.__new__(cls, base_dims, derived_dims, dimensional_dependencies)
|
||||
return obj
|
||||
|
||||
@property
|
||||
def base_dims(self):
|
||||
return self.args[0]
|
||||
|
||||
@property
|
||||
def derived_dims(self):
|
||||
return self.args[1]
|
||||
|
||||
@property
|
||||
def dimensional_dependencies(self):
|
||||
return self.args[2]
|
||||
|
||||
def _get_dimensional_dependencies_for_name(self, dimension):
|
||||
if isinstance(dimension, str):
|
||||
dimension = Dimension(Symbol(dimension))
|
||||
elif not isinstance(dimension, Dimension):
|
||||
dimension = Dimension(dimension)
|
||||
|
||||
if dimension.name.is_Symbol:
|
||||
# Dimensions not included in the dependencies are considered
|
||||
# as base dimensions:
|
||||
return dict(self.dimensional_dependencies.get(dimension, {dimension: 1}))
|
||||
|
||||
if dimension.name.is_number or dimension.name.is_NumberSymbol:
|
||||
return {}
|
||||
|
||||
get_for_name = self._get_dimensional_dependencies_for_name
|
||||
|
||||
if dimension.name.is_Mul:
|
||||
ret = collections.defaultdict(int)
|
||||
dicts = [get_for_name(i) for i in dimension.name.args]
|
||||
for d in dicts:
|
||||
for k, v in d.items():
|
||||
ret[k] += v
|
||||
return {k: v for (k, v) in ret.items() if v != 0}
|
||||
|
||||
if dimension.name.is_Add:
|
||||
dicts = [get_for_name(i) for i in dimension.name.args]
|
||||
if all(d == dicts[0] for d in dicts[1:]):
|
||||
return dicts[0]
|
||||
raise TypeError("Only equivalent dimensions can be added or subtracted.")
|
||||
|
||||
if dimension.name.is_Pow:
|
||||
dim_base = get_for_name(dimension.name.base)
|
||||
dim_exp = get_for_name(dimension.name.exp)
|
||||
if dim_exp == {} or dimension.name.exp.is_Symbol:
|
||||
return {k: v * dimension.name.exp for (k, v) in dim_base.items()}
|
||||
else:
|
||||
raise TypeError("The exponent for the power operator must be a Symbol or dimensionless.")
|
||||
|
||||
if dimension.name.is_Function:
|
||||
args = (Dimension._from_dimensional_dependencies(
|
||||
get_for_name(arg)) for arg in dimension.name.args)
|
||||
result = dimension.name.func(*args)
|
||||
|
||||
dicts = [get_for_name(i) for i in dimension.name.args]
|
||||
|
||||
if isinstance(result, Dimension):
|
||||
return self.get_dimensional_dependencies(result)
|
||||
elif result.func == dimension.name.func:
|
||||
if isinstance(dimension.name, TrigonometricFunction):
|
||||
if dicts[0] in ({}, {Dimension('angle'): 1}):
|
||||
return {}
|
||||
else:
|
||||
raise TypeError("The input argument for the function {} must be dimensionless or have dimensions of angle.".format(dimension.func))
|
||||
else:
|
||||
if all(item == {} for item in dicts):
|
||||
return {}
|
||||
else:
|
||||
raise TypeError("The input arguments for the function {} must be dimensionless.".format(dimension.func))
|
||||
else:
|
||||
return get_for_name(result)
|
||||
|
||||
raise TypeError("Type {} not implemented for get_dimensional_dependencies".format(type(dimension.name)))
|
||||
|
||||
def get_dimensional_dependencies(self, name, mark_dimensionless=False):
|
||||
dimdep = self._get_dimensional_dependencies_for_name(name)
|
||||
if mark_dimensionless and dimdep == {}:
|
||||
return {Dimension(1): 1}
|
||||
return dict(dimdep.items())
|
||||
|
||||
def equivalent_dims(self, dim1, dim2):
|
||||
deps1 = self.get_dimensional_dependencies(dim1)
|
||||
deps2 = self.get_dimensional_dependencies(dim2)
|
||||
return deps1 == deps2
|
||||
|
||||
def extend(self, new_base_dims, new_derived_dims=(), new_dim_deps=None):
|
||||
deps = dict(self.dimensional_dependencies)
|
||||
if new_dim_deps:
|
||||
deps.update(new_dim_deps)
|
||||
|
||||
new_dim_sys = DimensionSystem(
|
||||
tuple(self.base_dims) + tuple(new_base_dims),
|
||||
tuple(self.derived_dims) + tuple(new_derived_dims),
|
||||
deps
|
||||
)
|
||||
new_dim_sys._quantity_dimension_map.update(self._quantity_dimension_map)
|
||||
new_dim_sys._quantity_scale_factors.update(self._quantity_scale_factors)
|
||||
return new_dim_sys
|
||||
|
||||
def is_dimensionless(self, dimension):
|
||||
"""
|
||||
Check if the dimension object really has a dimension.
|
||||
|
||||
A dimension should have at least one component with non-zero power.
|
||||
"""
|
||||
if dimension.name == 1:
|
||||
return True
|
||||
return self.get_dimensional_dependencies(dimension) == {}
|
||||
|
||||
@property
|
||||
def list_can_dims(self):
|
||||
"""
|
||||
Useless method, kept for compatibility with previous versions.
|
||||
|
||||
DO NOT USE.
|
||||
|
||||
List all canonical dimension names.
|
||||
"""
|
||||
dimset = set()
|
||||
for i in self.base_dims:
|
||||
dimset.update(set(self.get_dimensional_dependencies(i).keys()))
|
||||
return tuple(sorted(dimset, key=str))
|
||||
|
||||
@property
|
||||
def inv_can_transf_matrix(self):
|
||||
"""
|
||||
Useless method, kept for compatibility with previous versions.
|
||||
|
||||
DO NOT USE.
|
||||
|
||||
Compute the inverse transformation matrix from the base to the
|
||||
canonical dimension basis.
|
||||
|
||||
It corresponds to the matrix where columns are the vector of base
|
||||
dimensions in canonical basis.
|
||||
|
||||
This matrix will almost never be used because dimensions are always
|
||||
defined with respect to the canonical basis, so no work has to be done
|
||||
to get them in this basis. Nonetheless if this matrix is not square
|
||||
(or not invertible) it means that we have chosen a bad basis.
|
||||
"""
|
||||
matrix = reduce(lambda x, y: x.row_join(y),
|
||||
[self.dim_can_vector(d) for d in self.base_dims])
|
||||
return matrix
|
||||
|
||||
@property
|
||||
def can_transf_matrix(self):
|
||||
"""
|
||||
Useless method, kept for compatibility with previous versions.
|
||||
|
||||
DO NOT USE.
|
||||
|
||||
Return the canonical transformation matrix from the canonical to the
|
||||
base dimension basis.
|
||||
|
||||
It is the inverse of the matrix computed with inv_can_transf_matrix().
|
||||
"""
|
||||
|
||||
#TODO: the inversion will fail if the system is inconsistent, for
|
||||
# example if the matrix is not a square
|
||||
return reduce(lambda x, y: x.row_join(y),
|
||||
[self.dim_can_vector(d) for d in sorted(self.base_dims, key=str)]
|
||||
).inv()
|
||||
|
||||
def dim_can_vector(self, dim):
|
||||
"""
|
||||
Useless method, kept for compatibility with previous versions.
|
||||
|
||||
DO NOT USE.
|
||||
|
||||
Dimensional representation in terms of the canonical base dimensions.
|
||||
"""
|
||||
|
||||
vec = []
|
||||
for d in self.list_can_dims:
|
||||
vec.append(self.get_dimensional_dependencies(dim).get(d, 0))
|
||||
return Matrix(vec)
|
||||
|
||||
def dim_vector(self, dim):
|
||||
"""
|
||||
Useless method, kept for compatibility with previous versions.
|
||||
|
||||
DO NOT USE.
|
||||
|
||||
|
||||
Vector representation in terms of the base dimensions.
|
||||
"""
|
||||
return self.can_transf_matrix * Matrix(self.dim_can_vector(dim))
|
||||
|
||||
def print_dim_base(self, dim):
|
||||
"""
|
||||
Give the string expression of a dimension in term of the basis symbols.
|
||||
"""
|
||||
dims = self.dim_vector(dim)
|
||||
symbols = [i.symbol if i.symbol is not None else i.name for i in self.base_dims]
|
||||
res = S.One
|
||||
for (s, p) in zip(symbols, dims):
|
||||
res *= s**p
|
||||
return res
|
||||
|
||||
@property
|
||||
def dim(self):
|
||||
"""
|
||||
Useless method, kept for compatibility with previous versions.
|
||||
|
||||
DO NOT USE.
|
||||
|
||||
Give the dimension of the system.
|
||||
|
||||
That is return the number of dimensions forming the basis.
|
||||
"""
|
||||
return len(self.base_dims)
|
||||
|
||||
@property
|
||||
def is_consistent(self):
|
||||
"""
|
||||
Useless method, kept for compatibility with previous versions.
|
||||
|
||||
DO NOT USE.
|
||||
|
||||
Check if the system is well defined.
|
||||
"""
|
||||
|
||||
# not enough or too many base dimensions compared to independent
|
||||
# dimensions
|
||||
# in vector language: the set of vectors do not form a basis
|
||||
return self.inv_can_transf_matrix.is_square
|
||||
@@ -0,0 +1,219 @@
|
||||
"""
|
||||
Module defining unit prefixe class and some constants.
|
||||
|
||||
Constant dict for SI and binary prefixes are defined as PREFIXES and
|
||||
BIN_PREFIXES.
|
||||
"""
|
||||
from sympy.core.expr import Expr
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.core.singleton import S
|
||||
|
||||
class Prefix(Expr):
|
||||
"""
|
||||
This class represent prefixes, with their name, symbol and factor.
|
||||
|
||||
Prefixes are used to create derived units from a given unit. They should
|
||||
always be encapsulated into units.
|
||||
|
||||
The factor is constructed from a base (default is 10) to some power, and
|
||||
it gives the total multiple or fraction. For example the kilometer km
|
||||
is constructed from the meter (factor 1) and the kilo (10 to the power 3,
|
||||
i.e. 1000). The base can be changed to allow e.g. binary prefixes.
|
||||
|
||||
A prefix multiplied by something will always return the product of this
|
||||
other object times the factor, except if the other object:
|
||||
|
||||
- is a prefix and they can be combined into a new prefix;
|
||||
- defines multiplication with prefixes (which is the case for the Unit
|
||||
class).
|
||||
"""
|
||||
_op_priority = 13.0
|
||||
is_commutative = True
|
||||
|
||||
def __new__(cls, name, abbrev, exponent, base=sympify(10), latex_repr=None):
|
||||
|
||||
name = sympify(name)
|
||||
abbrev = sympify(abbrev)
|
||||
exponent = sympify(exponent)
|
||||
base = sympify(base)
|
||||
|
||||
obj = Expr.__new__(cls, name, abbrev, exponent, base)
|
||||
obj._name = name
|
||||
obj._abbrev = abbrev
|
||||
obj._scale_factor = base**exponent
|
||||
obj._exponent = exponent
|
||||
obj._base = base
|
||||
obj._latex_repr = latex_repr
|
||||
return obj
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def abbrev(self):
|
||||
return self._abbrev
|
||||
|
||||
@property
|
||||
def scale_factor(self):
|
||||
return self._scale_factor
|
||||
|
||||
def _latex(self, printer):
|
||||
if self._latex_repr is None:
|
||||
return r'\text{%s}' % self._abbrev
|
||||
return self._latex_repr
|
||||
|
||||
@property
|
||||
def base(self):
|
||||
return self._base
|
||||
|
||||
def __str__(self):
|
||||
return str(self._abbrev)
|
||||
|
||||
def __repr__(self):
|
||||
if self.base == 10:
|
||||
return "Prefix(%r, %r, %r)" % (
|
||||
str(self.name), str(self.abbrev), self._exponent)
|
||||
else:
|
||||
return "Prefix(%r, %r, %r, %r)" % (
|
||||
str(self.name), str(self.abbrev), self._exponent, self.base)
|
||||
|
||||
def __mul__(self, other):
|
||||
from sympy.physics.units import Quantity
|
||||
if not isinstance(other, (Quantity, Prefix)):
|
||||
return super().__mul__(other)
|
||||
|
||||
fact = self.scale_factor * other.scale_factor
|
||||
|
||||
if isinstance(other, Prefix):
|
||||
if fact == 1:
|
||||
return S.One
|
||||
# simplify prefix
|
||||
for p in PREFIXES:
|
||||
if PREFIXES[p].scale_factor == fact:
|
||||
return PREFIXES[p]
|
||||
return fact
|
||||
|
||||
return self.scale_factor * other
|
||||
|
||||
def __truediv__(self, other):
|
||||
if not hasattr(other, "scale_factor"):
|
||||
return super().__truediv__(other)
|
||||
|
||||
fact = self.scale_factor / other.scale_factor
|
||||
|
||||
if fact == 1:
|
||||
return S.One
|
||||
elif isinstance(other, Prefix):
|
||||
for p in PREFIXES:
|
||||
if PREFIXES[p].scale_factor == fact:
|
||||
return PREFIXES[p]
|
||||
return fact
|
||||
|
||||
return self.scale_factor / other
|
||||
|
||||
def __rtruediv__(self, other):
|
||||
if other == 1:
|
||||
for p in PREFIXES:
|
||||
if PREFIXES[p].scale_factor == 1 / self.scale_factor:
|
||||
return PREFIXES[p]
|
||||
return other / self.scale_factor
|
||||
|
||||
|
||||
def prefix_unit(unit, prefixes):
|
||||
"""
|
||||
Return a list of all units formed by unit and the given prefixes.
|
||||
|
||||
You can use the predefined PREFIXES or BIN_PREFIXES, but you can also
|
||||
pass as argument a subdict of them if you do not want all prefixed units.
|
||||
|
||||
>>> from sympy.physics.units.prefixes import (PREFIXES,
|
||||
... prefix_unit)
|
||||
>>> from sympy.physics.units import m
|
||||
>>> pref = {"m": PREFIXES["m"], "c": PREFIXES["c"], "d": PREFIXES["d"]}
|
||||
>>> prefix_unit(m, pref) # doctest: +SKIP
|
||||
[millimeter, centimeter, decimeter]
|
||||
"""
|
||||
|
||||
from sympy.physics.units.quantities import Quantity
|
||||
from sympy.physics.units import UnitSystem
|
||||
|
||||
prefixed_units = []
|
||||
|
||||
for prefix in prefixes.values():
|
||||
quantity = Quantity(
|
||||
"%s%s" % (prefix.name, unit.name),
|
||||
abbrev=("%s%s" % (prefix.abbrev, unit.abbrev)),
|
||||
is_prefixed=True,
|
||||
)
|
||||
UnitSystem._quantity_dimensional_equivalence_map_global[quantity] = unit
|
||||
UnitSystem._quantity_scale_factors_global[quantity] = (prefix.scale_factor, unit)
|
||||
prefixed_units.append(quantity)
|
||||
|
||||
return prefixed_units
|
||||
|
||||
|
||||
yotta = Prefix('yotta', 'Y', 24)
|
||||
zetta = Prefix('zetta', 'Z', 21)
|
||||
exa = Prefix('exa', 'E', 18)
|
||||
peta = Prefix('peta', 'P', 15)
|
||||
tera = Prefix('tera', 'T', 12)
|
||||
giga = Prefix('giga', 'G', 9)
|
||||
mega = Prefix('mega', 'M', 6)
|
||||
kilo = Prefix('kilo', 'k', 3)
|
||||
hecto = Prefix('hecto', 'h', 2)
|
||||
deca = Prefix('deca', 'da', 1)
|
||||
deci = Prefix('deci', 'd', -1)
|
||||
centi = Prefix('centi', 'c', -2)
|
||||
milli = Prefix('milli', 'm', -3)
|
||||
micro = Prefix('micro', 'mu', -6, latex_repr=r"\mu")
|
||||
nano = Prefix('nano', 'n', -9)
|
||||
pico = Prefix('pico', 'p', -12)
|
||||
femto = Prefix('femto', 'f', -15)
|
||||
atto = Prefix('atto', 'a', -18)
|
||||
zepto = Prefix('zepto', 'z', -21)
|
||||
yocto = Prefix('yocto', 'y', -24)
|
||||
|
||||
|
||||
# https://physics.nist.gov/cuu/Units/prefixes.html
|
||||
PREFIXES = {
|
||||
'Y': yotta,
|
||||
'Z': zetta,
|
||||
'E': exa,
|
||||
'P': peta,
|
||||
'T': tera,
|
||||
'G': giga,
|
||||
'M': mega,
|
||||
'k': kilo,
|
||||
'h': hecto,
|
||||
'da': deca,
|
||||
'd': deci,
|
||||
'c': centi,
|
||||
'm': milli,
|
||||
'mu': micro,
|
||||
'n': nano,
|
||||
'p': pico,
|
||||
'f': femto,
|
||||
'a': atto,
|
||||
'z': zepto,
|
||||
'y': yocto,
|
||||
}
|
||||
|
||||
|
||||
kibi = Prefix('kibi', 'Y', 10, 2)
|
||||
mebi = Prefix('mebi', 'Y', 20, 2)
|
||||
gibi = Prefix('gibi', 'Y', 30, 2)
|
||||
tebi = Prefix('tebi', 'Y', 40, 2)
|
||||
pebi = Prefix('pebi', 'Y', 50, 2)
|
||||
exbi = Prefix('exbi', 'Y', 60, 2)
|
||||
|
||||
|
||||
# https://physics.nist.gov/cuu/Units/binary.html
|
||||
BIN_PREFIXES = {
|
||||
'Ki': kibi,
|
||||
'Mi': mebi,
|
||||
'Gi': gibi,
|
||||
'Ti': tebi,
|
||||
'Pi': pebi,
|
||||
'Ei': exbi,
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
"""
|
||||
Physical quantities.
|
||||
"""
|
||||
|
||||
from sympy.core.expr import AtomicExpr
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.physics.units.dimensions import _QuantityMapper
|
||||
from sympy.physics.units.prefixes import Prefix
|
||||
|
||||
|
||||
class Quantity(AtomicExpr):
|
||||
"""
|
||||
Physical quantity: can be a unit of measure, a constant or a generic quantity.
|
||||
"""
|
||||
|
||||
is_commutative = True
|
||||
is_real = True
|
||||
is_number = False
|
||||
is_nonzero = True
|
||||
is_physical_constant = False
|
||||
_diff_wrt = True
|
||||
|
||||
def __new__(cls, name, abbrev=None,
|
||||
latex_repr=None, pretty_unicode_repr=None,
|
||||
pretty_ascii_repr=None, mathml_presentation_repr=None,
|
||||
is_prefixed=False,
|
||||
**assumptions):
|
||||
|
||||
if not isinstance(name, Symbol):
|
||||
name = Symbol(name)
|
||||
|
||||
if abbrev is None:
|
||||
abbrev = name
|
||||
elif isinstance(abbrev, str):
|
||||
abbrev = Symbol(abbrev)
|
||||
|
||||
# HACK: These are here purely for type checking. They actually get assigned below.
|
||||
cls._is_prefixed = is_prefixed
|
||||
|
||||
obj = AtomicExpr.__new__(cls, name, abbrev)
|
||||
obj._name = name
|
||||
obj._abbrev = abbrev
|
||||
obj._latex_repr = latex_repr
|
||||
obj._unicode_repr = pretty_unicode_repr
|
||||
obj._ascii_repr = pretty_ascii_repr
|
||||
obj._mathml_repr = mathml_presentation_repr
|
||||
obj._is_prefixed = is_prefixed
|
||||
return obj
|
||||
|
||||
def set_global_dimension(self, dimension):
|
||||
_QuantityMapper._quantity_dimension_global[self] = dimension
|
||||
|
||||
def set_global_relative_scale_factor(self, scale_factor, reference_quantity):
|
||||
"""
|
||||
Setting a scale factor that is valid across all unit system.
|
||||
"""
|
||||
from sympy.physics.units import UnitSystem
|
||||
scale_factor = sympify(scale_factor)
|
||||
if isinstance(scale_factor, Prefix):
|
||||
self._is_prefixed = True
|
||||
# replace all prefixes by their ratio to canonical units:
|
||||
scale_factor = scale_factor.replace(
|
||||
lambda x: isinstance(x, Prefix),
|
||||
lambda x: x.scale_factor
|
||||
)
|
||||
scale_factor = sympify(scale_factor)
|
||||
UnitSystem._quantity_scale_factors_global[self] = (scale_factor, reference_quantity)
|
||||
UnitSystem._quantity_dimensional_equivalence_map_global[self] = reference_quantity
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def dimension(self):
|
||||
from sympy.physics.units import UnitSystem
|
||||
unit_system = UnitSystem.get_default_unit_system()
|
||||
return unit_system.get_quantity_dimension(self)
|
||||
|
||||
@property
|
||||
def abbrev(self):
|
||||
"""
|
||||
Symbol representing the unit name.
|
||||
|
||||
Prepend the abbreviation with the prefix symbol if it is defines.
|
||||
"""
|
||||
return self._abbrev
|
||||
|
||||
@property
|
||||
def scale_factor(self):
|
||||
"""
|
||||
Overall magnitude of the quantity as compared to the canonical units.
|
||||
"""
|
||||
from sympy.physics.units import UnitSystem
|
||||
unit_system = UnitSystem.get_default_unit_system()
|
||||
return unit_system.get_quantity_scale_factor(self)
|
||||
|
||||
def _eval_is_positive(self):
|
||||
return True
|
||||
|
||||
def _eval_is_constant(self):
|
||||
return True
|
||||
|
||||
def _eval_Abs(self):
|
||||
return self
|
||||
|
||||
def _eval_subs(self, old, new):
|
||||
if isinstance(new, Quantity) and self != old:
|
||||
return self
|
||||
|
||||
def _latex(self, printer):
|
||||
if self._latex_repr:
|
||||
return self._latex_repr
|
||||
else:
|
||||
return r'\text{{{}}}'.format(self.args[1] \
|
||||
if len(self.args) >= 2 else self.args[0])
|
||||
|
||||
def convert_to(self, other, unit_system="SI"):
|
||||
"""
|
||||
Convert the quantity to another quantity of same dimensions.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.units import speed_of_light, meter, second
|
||||
>>> speed_of_light
|
||||
speed_of_light
|
||||
>>> speed_of_light.convert_to(meter/second)
|
||||
299792458*meter/second
|
||||
|
||||
>>> from sympy.physics.units import liter
|
||||
>>> liter.convert_to(meter**3)
|
||||
meter**3/1000
|
||||
"""
|
||||
from .util import convert_to
|
||||
return convert_to(self, other, unit_system)
|
||||
|
||||
@property
|
||||
def free_symbols(self):
|
||||
"""Return free symbols from quantity."""
|
||||
return set()
|
||||
|
||||
@property
|
||||
def is_prefixed(self):
|
||||
"""Whether or not the quantity is prefixed. Eg. `kilogram` is prefixed, but `gram` is not."""
|
||||
return self._is_prefixed
|
||||
|
||||
class PhysicalConstant(Quantity):
|
||||
"""Represents a physical constant, eg. `speed_of_light` or `avogadro_constant`."""
|
||||
|
||||
is_physical_constant = True
|
||||
@@ -0,0 +1,6 @@
|
||||
from sympy.physics.units.systems.mks import MKS
|
||||
from sympy.physics.units.systems.mksa import MKSA
|
||||
from sympy.physics.units.systems.natural import natural
|
||||
from sympy.physics.units.systems.si import SI
|
||||
|
||||
__all__ = ['MKS', 'MKSA', 'natural', 'SI']
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,82 @@
|
||||
from sympy.core.singleton import S
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.physics.units import UnitSystem, centimeter, gram, second, coulomb, charge, speed_of_light, current, mass, \
|
||||
length, voltage, magnetic_density, magnetic_flux
|
||||
from sympy.physics.units.definitions import coulombs_constant
|
||||
from sympy.physics.units.definitions.unit_definitions import statcoulomb, statampere, statvolt, volt, tesla, gauss, \
|
||||
weber, maxwell, debye, oersted, ohm, farad, henry, erg, ampere, coulomb_constant
|
||||
from sympy.physics.units.systems.mks import dimsys_length_weight_time
|
||||
|
||||
One = S.One
|
||||
|
||||
dimsys_cgs = dimsys_length_weight_time.extend(
|
||||
[],
|
||||
new_dim_deps={
|
||||
# Dimensional dependencies for derived dimensions
|
||||
"impedance": {"time": 1, "length": -1},
|
||||
"conductance": {"time": -1, "length": 1},
|
||||
"capacitance": {"length": 1},
|
||||
"inductance": {"time": 2, "length": -1},
|
||||
"charge": {"mass": S.Half, "length": S(3)/2, "time": -1},
|
||||
"current": {"mass": One/2, "length": 3*One/2, "time": -2},
|
||||
"voltage": {"length": -One/2, "mass": One/2, "time": -1},
|
||||
"magnetic_density": {"length": -One/2, "mass": One/2, "time": -1},
|
||||
"magnetic_flux": {"length": 3*One/2, "mass": One/2, "time": -1},
|
||||
}
|
||||
)
|
||||
|
||||
cgs_gauss = UnitSystem(
|
||||
base_units=[centimeter, gram, second],
|
||||
units=[],
|
||||
name="cgs_gauss",
|
||||
dimension_system=dimsys_cgs)
|
||||
|
||||
|
||||
cgs_gauss.set_quantity_scale_factor(coulombs_constant, 1)
|
||||
|
||||
cgs_gauss.set_quantity_dimension(statcoulomb, charge)
|
||||
cgs_gauss.set_quantity_scale_factor(statcoulomb, centimeter**(S(3)/2)*gram**(S.Half)/second)
|
||||
|
||||
cgs_gauss.set_quantity_dimension(coulomb, charge)
|
||||
|
||||
cgs_gauss.set_quantity_dimension(statampere, current)
|
||||
cgs_gauss.set_quantity_scale_factor(statampere, statcoulomb/second)
|
||||
|
||||
cgs_gauss.set_quantity_dimension(statvolt, voltage)
|
||||
cgs_gauss.set_quantity_scale_factor(statvolt, erg/statcoulomb)
|
||||
|
||||
cgs_gauss.set_quantity_dimension(volt, voltage)
|
||||
|
||||
cgs_gauss.set_quantity_dimension(gauss, magnetic_density)
|
||||
cgs_gauss.set_quantity_scale_factor(gauss, sqrt(gram/centimeter)/second)
|
||||
|
||||
cgs_gauss.set_quantity_dimension(tesla, magnetic_density)
|
||||
|
||||
cgs_gauss.set_quantity_dimension(maxwell, magnetic_flux)
|
||||
cgs_gauss.set_quantity_scale_factor(maxwell, sqrt(centimeter**3*gram)/second)
|
||||
|
||||
# SI units expressed in CGS-gaussian units:
|
||||
cgs_gauss.set_quantity_scale_factor(coulomb, 10*speed_of_light*statcoulomb)
|
||||
cgs_gauss.set_quantity_scale_factor(ampere, 10*speed_of_light*statcoulomb/second)
|
||||
cgs_gauss.set_quantity_scale_factor(volt, 10**6/speed_of_light*statvolt)
|
||||
cgs_gauss.set_quantity_scale_factor(weber, 10**8*maxwell)
|
||||
cgs_gauss.set_quantity_scale_factor(tesla, 10**4*gauss)
|
||||
cgs_gauss.set_quantity_scale_factor(debye, One/10**18*statcoulomb*centimeter)
|
||||
cgs_gauss.set_quantity_scale_factor(oersted, sqrt(gram/centimeter)/second)
|
||||
cgs_gauss.set_quantity_scale_factor(ohm, 10**5/speed_of_light**2*second/centimeter)
|
||||
cgs_gauss.set_quantity_scale_factor(farad, One/10**5*speed_of_light**2*centimeter)
|
||||
cgs_gauss.set_quantity_scale_factor(henry, 10**5/speed_of_light**2/centimeter*second**2)
|
||||
|
||||
# Coulomb's constant:
|
||||
cgs_gauss.set_quantity_dimension(coulomb_constant, 1)
|
||||
cgs_gauss.set_quantity_scale_factor(coulomb_constant, 1)
|
||||
|
||||
__all__ = [
|
||||
'ohm', 'tesla', 'maxwell', 'speed_of_light', 'volt', 'second', 'voltage',
|
||||
'debye', 'dimsys_length_weight_time', 'centimeter', 'coulomb_constant',
|
||||
'farad', 'sqrt', 'UnitSystem', 'current', 'charge', 'weber', 'gram',
|
||||
'statcoulomb', 'gauss', 'S', 'statvolt', 'oersted', 'statampere',
|
||||
'dimsys_cgs', 'coulomb', 'magnetic_density', 'magnetic_flux', 'One',
|
||||
'length', 'erg', 'mass', 'coulombs_constant', 'henry', 'ampere',
|
||||
'cgs_gauss',
|
||||
]
|
||||
@@ -0,0 +1,156 @@
|
||||
from sympy.core.singleton import S
|
||||
|
||||
from sympy.core.numbers import pi
|
||||
|
||||
from sympy.physics.units import DimensionSystem, hertz, kilogram
|
||||
from sympy.physics.units.definitions import (
|
||||
G, Hz, J, N, Pa, W, c, g, kg, m, s, meter, gram, second, newton,
|
||||
joule, watt, pascal)
|
||||
from sympy.physics.units.definitions.dimension_definitions import (
|
||||
acceleration, action, energy, force, frequency, momentum,
|
||||
power, pressure, velocity, length, mass, time)
|
||||
from sympy.physics.units.prefixes import PREFIXES, prefix_unit
|
||||
from sympy.physics.units.prefixes import (
|
||||
kibi, mebi, gibi, tebi, pebi, exbi
|
||||
)
|
||||
from sympy.physics.units.definitions import (
|
||||
cd, K, coulomb, volt, ohm, siemens, farad, henry, tesla, weber, dioptre,
|
||||
lux, katal, gray, becquerel, inch, hectare, liter, julian_year,
|
||||
gravitational_constant, speed_of_light, elementary_charge, planck, hbar,
|
||||
electronvolt, avogadro_number, avogadro_constant, boltzmann_constant,
|
||||
stefan_boltzmann_constant, 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, kelvin,
|
||||
mol, mole, candela, electric_constant, boltzmann, angstrom
|
||||
)
|
||||
|
||||
|
||||
dimsys_length_weight_time = DimensionSystem([
|
||||
# Dimensional dependencies for MKS base dimensions
|
||||
length,
|
||||
mass,
|
||||
time,
|
||||
], dimensional_dependencies={
|
||||
# Dimensional dependencies for derived dimensions
|
||||
"velocity": {"length": 1, "time": -1},
|
||||
"acceleration": {"length": 1, "time": -2},
|
||||
"momentum": {"mass": 1, "length": 1, "time": -1},
|
||||
"force": {"mass": 1, "length": 1, "time": -2},
|
||||
"energy": {"mass": 1, "length": 2, "time": -2},
|
||||
"power": {"length": 2, "mass": 1, "time": -3},
|
||||
"pressure": {"mass": 1, "length": -1, "time": -2},
|
||||
"frequency": {"time": -1},
|
||||
"action": {"length": 2, "mass": 1, "time": -1},
|
||||
"area": {"length": 2},
|
||||
"volume": {"length": 3},
|
||||
})
|
||||
|
||||
|
||||
One = S.One
|
||||
|
||||
|
||||
# Base units:
|
||||
dimsys_length_weight_time.set_quantity_dimension(meter, length)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(meter, One)
|
||||
|
||||
# gram; used to define its prefixed units
|
||||
dimsys_length_weight_time.set_quantity_dimension(gram, mass)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(gram, One)
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(second, time)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(second, One)
|
||||
|
||||
# derived units
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(newton, force)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(newton, kilogram*meter/second**2)
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(joule, energy)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(joule, newton*meter)
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(watt, power)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(watt, joule/second)
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(pascal, pressure)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(pascal, newton/meter**2)
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(hertz, frequency)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(hertz, One)
|
||||
|
||||
# Other derived units:
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(dioptre, 1 / length)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(dioptre, 1/meter)
|
||||
|
||||
# Common volume and area units
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(hectare, length**2)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(hectare, (meter**2)*(10000))
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(liter, length**3)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(liter, meter**3/1000)
|
||||
|
||||
|
||||
# Newton constant
|
||||
# REF: NIST SP 959 (June 2019)
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(gravitational_constant, length ** 3 * mass ** -1 * time ** -2)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(gravitational_constant, 6.67430e-11*m**3/(kg*s**2))
|
||||
|
||||
# speed of light
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(speed_of_light, velocity)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(speed_of_light, 299792458*meter/second)
|
||||
|
||||
|
||||
# Planck constant
|
||||
# REF: NIST SP 959 (June 2019)
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(planck, action)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(planck, 6.62607015e-34*joule*second)
|
||||
|
||||
# Reduced Planck constant
|
||||
# REF: NIST SP 959 (June 2019)
|
||||
|
||||
dimsys_length_weight_time.set_quantity_dimension(hbar, action)
|
||||
dimsys_length_weight_time.set_quantity_scale_factor(hbar, planck / (2 * pi))
|
||||
|
||||
|
||||
__all__ = [
|
||||
'mmHg', 'atmosphere', 'newton', 'meter', 'vacuum_permittivity', 'pascal',
|
||||
'magnetic_constant', 'angular_mil', 'julian_year', 'weber', 'exbibyte',
|
||||
'liter', 'molar_gas_constant', 'faraday_constant', 'avogadro_constant',
|
||||
'planck_momentum', 'planck_density', 'gee', 'mol', 'bit', 'gray', 'kibi',
|
||||
'bar', 'curie', 'prefix_unit', 'PREFIXES', 'planck_time', 'gram',
|
||||
'candela', 'force', 'planck_intensity', 'energy', 'becquerel',
|
||||
'planck_acceleration', 'speed_of_light', 'dioptre', 'second', 'frequency',
|
||||
'Hz', 'power', 'lux', 'planck_current', 'momentum', 'tebibyte',
|
||||
'planck_power', 'degree', 'mebi', 'K', 'planck_volume',
|
||||
'quart', 'pressure', 'W', 'joule', 'boltzmann_constant', 'c', 'g',
|
||||
'planck_force', 'exbi', 's', 'watt', 'action', 'hbar', 'gibibyte',
|
||||
'DimensionSystem', 'cd', 'volt', 'planck_charge', 'angstrom',
|
||||
'dimsys_length_weight_time', 'pebi', 'vacuum_impedance', 'planck',
|
||||
'farad', 'gravitational_constant', 'u0', 'hertz', 'tesla', 'steradian',
|
||||
'josephson_constant', 'planck_area', 'stefan_boltzmann_constant',
|
||||
'astronomical_unit', 'J', 'N', 'planck_voltage', 'planck_energy',
|
||||
'atomic_mass_constant', 'rutherford', 'elementary_charge', 'Pa',
|
||||
'planck_mass', 'henry', 'planck_angular_frequency', 'ohm', 'pound',
|
||||
'planck_pressure', 'G', 'avogadro_number', 'psi', 'von_klitzing_constant',
|
||||
'planck_length', 'radian', 'mole', 'acceleration',
|
||||
'planck_energy_density', 'mebibyte', 'length',
|
||||
'acceleration_due_to_gravity', 'planck_temperature', 'tebi', 'inch',
|
||||
'electronvolt', 'coulomb_constant', 'kelvin', 'kPa', 'boltzmann',
|
||||
'milli_mass_unit', 'gibi', 'planck_impedance', 'electric_constant', 'kg',
|
||||
'coulomb', 'siemens', 'byte', 'atomic_mass_unit', 'm', 'kibibyte',
|
||||
'kilogram', 'lightyear', 'mass', 'time', 'pebibyte', 'velocity',
|
||||
'ampere', 'katal',
|
||||
]
|
||||
@@ -0,0 +1,46 @@
|
||||
"""
|
||||
MKS unit system.
|
||||
|
||||
MKS stands for "meter, kilogram, second".
|
||||
"""
|
||||
|
||||
from sympy.physics.units import UnitSystem
|
||||
from sympy.physics.units.definitions import gravitational_constant, hertz, joule, newton, pascal, watt, speed_of_light, gram, kilogram, meter, second
|
||||
from sympy.physics.units.definitions.dimension_definitions import (
|
||||
acceleration, action, energy, force, frequency, momentum,
|
||||
power, pressure, velocity, length, mass, time)
|
||||
from sympy.physics.units.prefixes import PREFIXES, prefix_unit
|
||||
from sympy.physics.units.systems.length_weight_time import dimsys_length_weight_time
|
||||
|
||||
dims = (velocity, acceleration, momentum, force, energy, power, pressure,
|
||||
frequency, action)
|
||||
|
||||
units = [meter, gram, second, joule, newton, watt, pascal, hertz]
|
||||
all_units = []
|
||||
|
||||
# Prefixes of units like gram, joule, newton etc get added using `prefix_unit`
|
||||
# in the for loop, but the actual units have to be added manually.
|
||||
all_units.extend([gram, joule, newton, watt, pascal, hertz])
|
||||
|
||||
for u in units:
|
||||
all_units.extend(prefix_unit(u, PREFIXES))
|
||||
all_units.extend([gravitational_constant, speed_of_light])
|
||||
|
||||
# unit system
|
||||
MKS = UnitSystem(base_units=(meter, kilogram, second), units=all_units, name="MKS", dimension_system=dimsys_length_weight_time, derived_units={
|
||||
power: watt,
|
||||
time: second,
|
||||
pressure: pascal,
|
||||
length: meter,
|
||||
frequency: hertz,
|
||||
mass: kilogram,
|
||||
force: newton,
|
||||
energy: joule,
|
||||
velocity: meter/second,
|
||||
acceleration: meter/(second**2),
|
||||
})
|
||||
|
||||
|
||||
__all__ = [
|
||||
'MKS', 'units', 'all_units', 'dims',
|
||||
]
|
||||
@@ -0,0 +1,54 @@
|
||||
"""
|
||||
MKS unit system.
|
||||
|
||||
MKS stands for "meter, kilogram, second, ampere".
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from sympy.physics.units.definitions import Z0, ampere, coulomb, farad, henry, siemens, tesla, volt, weber, ohm
|
||||
from sympy.physics.units.definitions.dimension_definitions import (
|
||||
capacitance, charge, conductance, current, impedance, inductance,
|
||||
magnetic_density, magnetic_flux, voltage)
|
||||
from sympy.physics.units.prefixes import PREFIXES, prefix_unit
|
||||
from sympy.physics.units.systems.mks import MKS, dimsys_length_weight_time
|
||||
from sympy.physics.units.quantities import Quantity
|
||||
|
||||
dims = (voltage, impedance, conductance, current, capacitance, inductance, charge,
|
||||
magnetic_density, magnetic_flux)
|
||||
|
||||
units = [ampere, volt, ohm, siemens, farad, henry, coulomb, tesla, weber]
|
||||
|
||||
all_units: list[Quantity] = []
|
||||
for u in units:
|
||||
all_units.extend(prefix_unit(u, PREFIXES))
|
||||
all_units.extend(units)
|
||||
|
||||
all_units.append(Z0)
|
||||
|
||||
dimsys_MKSA = dimsys_length_weight_time.extend([
|
||||
# Dimensional dependencies for base dimensions (MKSA not in MKS)
|
||||
current,
|
||||
], new_dim_deps={
|
||||
# Dimensional dependencies for derived dimensions
|
||||
"voltage": {"mass": 1, "length": 2, "current": -1, "time": -3},
|
||||
"impedance": {"mass": 1, "length": 2, "current": -2, "time": -3},
|
||||
"conductance": {"mass": -1, "length": -2, "current": 2, "time": 3},
|
||||
"capacitance": {"mass": -1, "length": -2, "current": 2, "time": 4},
|
||||
"inductance": {"mass": 1, "length": 2, "current": -2, "time": -2},
|
||||
"charge": {"current": 1, "time": 1},
|
||||
"magnetic_density": {"mass": 1, "current": -1, "time": -2},
|
||||
"magnetic_flux": {"length": 2, "mass": 1, "current": -1, "time": -2},
|
||||
})
|
||||
|
||||
MKSA = MKS.extend(base=(ampere,), units=all_units, name='MKSA', dimension_system=dimsys_MKSA, derived_units={
|
||||
magnetic_flux: weber,
|
||||
impedance: ohm,
|
||||
current: ampere,
|
||||
voltage: volt,
|
||||
inductance: henry,
|
||||
conductance: siemens,
|
||||
magnetic_density: tesla,
|
||||
charge: coulomb,
|
||||
capacitance: farad,
|
||||
})
|
||||
@@ -0,0 +1,27 @@
|
||||
"""
|
||||
Naturalunit system.
|
||||
|
||||
The natural system comes from "setting c = 1, hbar = 1". From the computer
|
||||
point of view it means that we use velocity and action instead of length and
|
||||
time. Moreover instead of mass we use energy.
|
||||
"""
|
||||
|
||||
from sympy.physics.units import DimensionSystem
|
||||
from sympy.physics.units.definitions import c, eV, hbar
|
||||
from sympy.physics.units.definitions.dimension_definitions import (
|
||||
action, energy, force, frequency, length, mass, momentum,
|
||||
power, time, velocity)
|
||||
from sympy.physics.units.prefixes import PREFIXES, prefix_unit
|
||||
from sympy.physics.units.unitsystem import UnitSystem
|
||||
|
||||
|
||||
# dimension system
|
||||
_natural_dim = DimensionSystem(
|
||||
base_dims=(action, energy, velocity),
|
||||
derived_dims=(length, mass, time, momentum, force, power, frequency)
|
||||
)
|
||||
|
||||
units = prefix_unit(eV, PREFIXES)
|
||||
|
||||
# unit system
|
||||
natural = UnitSystem(base_units=(hbar, eV, c), units=units, name="Natural system")
|
||||
@@ -0,0 +1,377 @@
|
||||
"""
|
||||
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',
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,150 @@
|
||||
from sympy.physics.units.systems.si import dimsys_SI
|
||||
|
||||
from sympy.core.numbers import pi
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.functions.elementary.complexes import Abs
|
||||
from sympy.functions.elementary.exponential import log
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.trigonometric import (acos, atan2, cos)
|
||||
from sympy.physics.units.dimensions import Dimension
|
||||
from sympy.physics.units.definitions.dimension_definitions import (
|
||||
length, time, mass, force, pressure, angle
|
||||
)
|
||||
from sympy.physics.units import foot
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
|
||||
def test_Dimension_definition():
|
||||
assert dimsys_SI.get_dimensional_dependencies(length) == {length: 1}
|
||||
assert length.name == Symbol("length")
|
||||
assert length.symbol == Symbol("L")
|
||||
|
||||
halflength = sqrt(length)
|
||||
assert dimsys_SI.get_dimensional_dependencies(halflength) == {length: S.Half}
|
||||
|
||||
|
||||
def test_Dimension_error_definition():
|
||||
# tuple with more or less than two entries
|
||||
raises(TypeError, lambda: Dimension(("length", 1, 2)))
|
||||
raises(TypeError, lambda: Dimension(["length"]))
|
||||
|
||||
# non-number power
|
||||
raises(TypeError, lambda: Dimension({"length": "a"}))
|
||||
|
||||
# non-number with named argument
|
||||
raises(TypeError, lambda: Dimension({"length": (1, 2)}))
|
||||
|
||||
# symbol should by Symbol or str
|
||||
raises(AssertionError, lambda: Dimension("length", symbol=1))
|
||||
|
||||
|
||||
def test_str():
|
||||
assert str(Dimension("length")) == "Dimension(length)"
|
||||
assert str(Dimension("length", "L")) == "Dimension(length, L)"
|
||||
|
||||
|
||||
def test_Dimension_properties():
|
||||
assert dimsys_SI.is_dimensionless(length) is False
|
||||
assert dimsys_SI.is_dimensionless(length/length) is True
|
||||
assert dimsys_SI.is_dimensionless(Dimension("undefined")) is False
|
||||
|
||||
assert length.has_integer_powers(dimsys_SI) is True
|
||||
assert (length**(-1)).has_integer_powers(dimsys_SI) is True
|
||||
assert (length**1.5).has_integer_powers(dimsys_SI) is False
|
||||
|
||||
|
||||
def test_Dimension_add_sub():
|
||||
assert length + length == length
|
||||
assert length - length == length
|
||||
assert -length == length
|
||||
|
||||
raises(TypeError, lambda: length + foot)
|
||||
raises(TypeError, lambda: foot + length)
|
||||
raises(TypeError, lambda: length - foot)
|
||||
raises(TypeError, lambda: foot - length)
|
||||
|
||||
# issue 14547 - only raise error for dimensional args; allow
|
||||
# others to pass
|
||||
x = Symbol('x')
|
||||
e = length + x
|
||||
assert e == x + length and e.is_Add and set(e.args) == {length, x}
|
||||
e = length + 1
|
||||
assert e == 1 + length == 1 - length and e.is_Add and set(e.args) == {length, 1}
|
||||
|
||||
assert dimsys_SI.get_dimensional_dependencies(mass * length / time**2 + force) == \
|
||||
{length: 1, mass: 1, time: -2}
|
||||
assert dimsys_SI.get_dimensional_dependencies(mass * length / time**2 + force -
|
||||
pressure * length**2) == \
|
||||
{length: 1, mass: 1, time: -2}
|
||||
|
||||
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(mass * length / time**2 + pressure))
|
||||
|
||||
def test_Dimension_mul_div_exp():
|
||||
assert 2*length == length*2 == length/2 == length
|
||||
assert 2/length == 1/length
|
||||
x = Symbol('x')
|
||||
m = x*length
|
||||
assert m == length*x and m.is_Mul and set(m.args) == {x, length}
|
||||
d = x/length
|
||||
assert d == x*length**-1 and d.is_Mul and set(d.args) == {x, 1/length}
|
||||
d = length/x
|
||||
assert d == length*x**-1 and d.is_Mul and set(d.args) == {1/x, length}
|
||||
|
||||
velo = length / time
|
||||
|
||||
assert (length * length) == length ** 2
|
||||
|
||||
assert dimsys_SI.get_dimensional_dependencies(length * length) == {length: 2}
|
||||
assert dimsys_SI.get_dimensional_dependencies(length ** 2) == {length: 2}
|
||||
assert dimsys_SI.get_dimensional_dependencies(length * time) == {length: 1, time: 1}
|
||||
assert dimsys_SI.get_dimensional_dependencies(velo) == {length: 1, time: -1}
|
||||
assert dimsys_SI.get_dimensional_dependencies(velo ** 2) == {length: 2, time: -2}
|
||||
|
||||
assert dimsys_SI.get_dimensional_dependencies(length / length) == {}
|
||||
assert dimsys_SI.get_dimensional_dependencies(velo / length * time) == {}
|
||||
assert dimsys_SI.get_dimensional_dependencies(length ** -1) == {length: -1}
|
||||
assert dimsys_SI.get_dimensional_dependencies(velo ** -1.5) == {length: -1.5, time: 1.5}
|
||||
|
||||
length_a = length**"a"
|
||||
assert dimsys_SI.get_dimensional_dependencies(length_a) == {length: Symbol("a")}
|
||||
|
||||
assert dimsys_SI.get_dimensional_dependencies(length**pi) == {length: pi}
|
||||
assert dimsys_SI.get_dimensional_dependencies(length**(length/length)) == {length: Dimension(1)}
|
||||
|
||||
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(length**length))
|
||||
|
||||
assert length != 1
|
||||
assert length / length != 1
|
||||
|
||||
length_0 = length ** 0
|
||||
assert dimsys_SI.get_dimensional_dependencies(length_0) == {}
|
||||
|
||||
# issue 18738
|
||||
a = Symbol('a')
|
||||
b = Symbol('b')
|
||||
c = sqrt(a**2 + b**2)
|
||||
c_dim = c.subs({a: length, b: length})
|
||||
assert dimsys_SI.equivalent_dims(c_dim, length)
|
||||
|
||||
def test_Dimension_functions():
|
||||
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(cos(length)))
|
||||
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(acos(angle)))
|
||||
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(atan2(length, time)))
|
||||
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(log(length)))
|
||||
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(log(100, length)))
|
||||
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(log(length, 10)))
|
||||
|
||||
assert dimsys_SI.get_dimensional_dependencies(pi) == {}
|
||||
|
||||
assert dimsys_SI.get_dimensional_dependencies(cos(1)) == {}
|
||||
assert dimsys_SI.get_dimensional_dependencies(cos(angle)) == {}
|
||||
|
||||
assert dimsys_SI.get_dimensional_dependencies(atan2(length, length)) == {}
|
||||
|
||||
assert dimsys_SI.get_dimensional_dependencies(log(length / length, length / length)) == {}
|
||||
|
||||
assert dimsys_SI.get_dimensional_dependencies(Abs(length)) == {length: 1}
|
||||
assert dimsys_SI.get_dimensional_dependencies(Abs(length / length)) == {}
|
||||
|
||||
assert dimsys_SI.get_dimensional_dependencies(sqrt(-1)) == {}
|
||||
@@ -0,0 +1,95 @@
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.matrices.dense import (Matrix, eye)
|
||||
from sympy.physics.units.definitions.dimension_definitions import (
|
||||
action, current, length, mass, time,
|
||||
velocity)
|
||||
from sympy.physics.units.dimensions import DimensionSystem
|
||||
|
||||
|
||||
def test_extend():
|
||||
ms = DimensionSystem((length, time), (velocity,))
|
||||
|
||||
mks = ms.extend((mass,), (action,))
|
||||
|
||||
res = DimensionSystem((length, time, mass), (velocity, action))
|
||||
assert mks.base_dims == res.base_dims
|
||||
assert mks.derived_dims == res.derived_dims
|
||||
|
||||
|
||||
def test_list_dims():
|
||||
dimsys = DimensionSystem((length, time, mass))
|
||||
|
||||
assert dimsys.list_can_dims == (length, mass, time)
|
||||
|
||||
|
||||
def test_dim_can_vector():
|
||||
dimsys = DimensionSystem(
|
||||
[length, mass, time],
|
||||
[velocity, action],
|
||||
{
|
||||
velocity: {length: 1, time: -1}
|
||||
}
|
||||
)
|
||||
|
||||
assert dimsys.dim_can_vector(length) == Matrix([1, 0, 0])
|
||||
assert dimsys.dim_can_vector(velocity) == Matrix([1, 0, -1])
|
||||
|
||||
dimsys = DimensionSystem(
|
||||
(length, velocity, action),
|
||||
(mass, time),
|
||||
{
|
||||
time: {length: 1, velocity: -1}
|
||||
}
|
||||
)
|
||||
|
||||
assert dimsys.dim_can_vector(length) == Matrix([0, 1, 0])
|
||||
assert dimsys.dim_can_vector(velocity) == Matrix([0, 0, 1])
|
||||
assert dimsys.dim_can_vector(time) == Matrix([0, 1, -1])
|
||||
|
||||
dimsys = DimensionSystem(
|
||||
(length, mass, time),
|
||||
(velocity, action),
|
||||
{velocity: {length: 1, time: -1},
|
||||
action: {mass: 1, length: 2, time: -1}})
|
||||
|
||||
assert dimsys.dim_vector(length) == Matrix([1, 0, 0])
|
||||
assert dimsys.dim_vector(velocity) == Matrix([1, 0, -1])
|
||||
|
||||
|
||||
def test_inv_can_transf_matrix():
|
||||
dimsys = DimensionSystem((length, mass, time))
|
||||
assert dimsys.inv_can_transf_matrix == eye(3)
|
||||
|
||||
|
||||
def test_can_transf_matrix():
|
||||
dimsys = DimensionSystem((length, mass, time))
|
||||
assert dimsys.can_transf_matrix == eye(3)
|
||||
|
||||
dimsys = DimensionSystem((length, velocity, action))
|
||||
assert dimsys.can_transf_matrix == eye(3)
|
||||
|
||||
dimsys = DimensionSystem((length, time), (velocity,), {velocity: {length: 1, time: -1}})
|
||||
assert dimsys.can_transf_matrix == eye(2)
|
||||
|
||||
|
||||
def test_is_consistent():
|
||||
assert DimensionSystem((length, time)).is_consistent is True
|
||||
|
||||
|
||||
def test_print_dim_base():
|
||||
mksa = DimensionSystem(
|
||||
(length, time, mass, current),
|
||||
(action,),
|
||||
{action: {mass: 1, length: 2, time: -1}})
|
||||
L, M, T = symbols("L M T")
|
||||
assert mksa.print_dim_base(action) == L**2*M/T
|
||||
|
||||
|
||||
def test_dim():
|
||||
dimsys = DimensionSystem(
|
||||
(length, mass, time),
|
||||
(velocity, action),
|
||||
{velocity: {length: 1, time: -1},
|
||||
action: {mass: 1, length: 2, time: -1}}
|
||||
)
|
||||
assert dimsys.dim == 3
|
||||
@@ -0,0 +1,86 @@
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.core.numbers import Rational
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.physics.units import Quantity, length, meter, W
|
||||
from sympy.physics.units.prefixes import PREFIXES, Prefix, prefix_unit, kilo, \
|
||||
kibi
|
||||
from sympy.physics.units.systems import SI
|
||||
|
||||
x = Symbol('x')
|
||||
|
||||
|
||||
def test_prefix_operations():
|
||||
m = PREFIXES['m']
|
||||
k = PREFIXES['k']
|
||||
M = PREFIXES['M']
|
||||
|
||||
dodeca = Prefix('dodeca', 'dd', 1, base=12)
|
||||
|
||||
assert m * k is S.One
|
||||
assert m * W == W / 1000
|
||||
assert k * k == M
|
||||
assert 1 / m == k
|
||||
assert k / m == M
|
||||
|
||||
assert dodeca * dodeca == 144
|
||||
assert 1 / dodeca == S.One / 12
|
||||
assert k / dodeca == S(1000) / 12
|
||||
assert dodeca / dodeca is S.One
|
||||
|
||||
m = Quantity("fake_meter")
|
||||
SI.set_quantity_dimension(m, S.One)
|
||||
SI.set_quantity_scale_factor(m, S.One)
|
||||
|
||||
assert dodeca * m == 12 * m
|
||||
assert dodeca / m == 12 / m
|
||||
|
||||
expr1 = kilo * 3
|
||||
assert isinstance(expr1, Mul)
|
||||
assert expr1.args == (3, kilo)
|
||||
|
||||
expr2 = kilo * x
|
||||
assert isinstance(expr2, Mul)
|
||||
assert expr2.args == (x, kilo)
|
||||
|
||||
expr3 = kilo / 3
|
||||
assert isinstance(expr3, Mul)
|
||||
assert expr3.args == (Rational(1, 3), kilo)
|
||||
assert expr3.args == (S.One/3, kilo)
|
||||
|
||||
expr4 = kilo / x
|
||||
assert isinstance(expr4, Mul)
|
||||
assert expr4.args == (1/x, kilo)
|
||||
|
||||
|
||||
def test_prefix_unit():
|
||||
m = Quantity("fake_meter", abbrev="m")
|
||||
m.set_global_relative_scale_factor(1, meter)
|
||||
|
||||
pref = {"m": PREFIXES["m"], "c": PREFIXES["c"], "d": PREFIXES["d"]}
|
||||
|
||||
q1 = Quantity("millifake_meter", abbrev="mm")
|
||||
q2 = Quantity("centifake_meter", abbrev="cm")
|
||||
q3 = Quantity("decifake_meter", abbrev="dm")
|
||||
|
||||
SI.set_quantity_dimension(q1, length)
|
||||
|
||||
SI.set_quantity_scale_factor(q1, PREFIXES["m"])
|
||||
SI.set_quantity_scale_factor(q1, PREFIXES["c"])
|
||||
SI.set_quantity_scale_factor(q1, PREFIXES["d"])
|
||||
|
||||
res = [q1, q2, q3]
|
||||
|
||||
prefs = prefix_unit(m, pref)
|
||||
assert set(prefs) == set(res)
|
||||
assert {v.abbrev for v in prefs} == set(symbols("mm,cm,dm"))
|
||||
|
||||
|
||||
def test_bases():
|
||||
assert kilo.base == 10
|
||||
assert kibi.base == 2
|
||||
|
||||
|
||||
def test_repr():
|
||||
assert eval(repr(kilo)) == kilo
|
||||
assert eval(repr(kibi)) == kibi
|
||||
@@ -0,0 +1,575 @@
|
||||
import warnings
|
||||
|
||||
from sympy.core.add import Add
|
||||
from sympy.core.function import (Function, diff)
|
||||
from sympy.core.numbers import (Number, Rational)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.functions.elementary.complexes import Abs
|
||||
from sympy.functions.elementary.exponential import (exp, log)
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.trigonometric import sin
|
||||
from sympy.integrals.integrals import integrate
|
||||
from sympy.physics.units import (amount_of_substance, area, convert_to, find_unit,
|
||||
volume, kilometer, joule, molar_gas_constant,
|
||||
vacuum_permittivity, elementary_charge, volt,
|
||||
ohm)
|
||||
from sympy.physics.units.definitions import (amu, au, centimeter, coulomb,
|
||||
day, foot, grams, hour, inch, kg, km, m, meter, millimeter,
|
||||
minute, quart, s, second, speed_of_light, bit,
|
||||
byte, kibibyte, mebibyte, gibibyte, tebibyte, pebibyte, exbibyte,
|
||||
kilogram, gravitational_constant, electron_rest_mass)
|
||||
|
||||
from sympy.physics.units.definitions.dimension_definitions import (
|
||||
Dimension, charge, length, time, temperature, pressure,
|
||||
energy, mass
|
||||
)
|
||||
from sympy.physics.units.prefixes import PREFIXES, kilo
|
||||
from sympy.physics.units.quantities import PhysicalConstant, Quantity
|
||||
from sympy.physics.units.systems import SI
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
k = PREFIXES["k"]
|
||||
|
||||
|
||||
def test_str_repr():
|
||||
assert str(kg) == "kilogram"
|
||||
|
||||
|
||||
def test_eq():
|
||||
# simple test
|
||||
assert 10*m == 10*m
|
||||
assert 10*m != 10*s
|
||||
|
||||
|
||||
def test_convert_to():
|
||||
q = Quantity("q1")
|
||||
q.set_global_relative_scale_factor(S(5000), meter)
|
||||
|
||||
assert q.convert_to(m) == 5000*m
|
||||
|
||||
assert speed_of_light.convert_to(m / s) == 299792458 * m / s
|
||||
assert day.convert_to(s) == 86400*s
|
||||
|
||||
# Wrong dimension to convert:
|
||||
assert q.convert_to(s) == q
|
||||
assert speed_of_light.convert_to(m) == speed_of_light
|
||||
|
||||
expr = joule*second
|
||||
conv = convert_to(expr, joule)
|
||||
assert conv == joule*second
|
||||
|
||||
|
||||
def test_Quantity_definition():
|
||||
q = Quantity("s10", abbrev="sabbr")
|
||||
q.set_global_relative_scale_factor(10, second)
|
||||
u = Quantity("u", abbrev="dam")
|
||||
u.set_global_relative_scale_factor(10, meter)
|
||||
km = Quantity("km")
|
||||
km.set_global_relative_scale_factor(kilo, meter)
|
||||
v = Quantity("u")
|
||||
v.set_global_relative_scale_factor(5*kilo, meter)
|
||||
|
||||
assert q.scale_factor == 10
|
||||
assert q.dimension == time
|
||||
assert q.abbrev == Symbol("sabbr")
|
||||
|
||||
assert u.dimension == length
|
||||
assert u.scale_factor == 10
|
||||
assert u.abbrev == Symbol("dam")
|
||||
|
||||
assert km.scale_factor == 1000
|
||||
assert km.func(*km.args) == km
|
||||
assert km.func(*km.args).args == km.args
|
||||
|
||||
assert v.dimension == length
|
||||
assert v.scale_factor == 5000
|
||||
|
||||
|
||||
def test_abbrev():
|
||||
u = Quantity("u")
|
||||
u.set_global_relative_scale_factor(S.One, meter)
|
||||
|
||||
assert u.name == Symbol("u")
|
||||
assert u.abbrev == Symbol("u")
|
||||
|
||||
u = Quantity("u", abbrev="om")
|
||||
u.set_global_relative_scale_factor(S(2), meter)
|
||||
|
||||
assert u.name == Symbol("u")
|
||||
assert u.abbrev == Symbol("om")
|
||||
assert u.scale_factor == 2
|
||||
assert isinstance(u.scale_factor, Number)
|
||||
|
||||
u = Quantity("u", abbrev="ikm")
|
||||
u.set_global_relative_scale_factor(3*kilo, meter)
|
||||
|
||||
assert u.abbrev == Symbol("ikm")
|
||||
assert u.scale_factor == 3000
|
||||
|
||||
|
||||
def test_print():
|
||||
u = Quantity("unitname", abbrev="dam")
|
||||
assert repr(u) == "unitname"
|
||||
assert str(u) == "unitname"
|
||||
|
||||
|
||||
def test_Quantity_eq():
|
||||
u = Quantity("u", abbrev="dam")
|
||||
v = Quantity("v1")
|
||||
assert u != v
|
||||
v = Quantity("v2", abbrev="ds")
|
||||
assert u != v
|
||||
v = Quantity("v3", abbrev="dm")
|
||||
assert u != v
|
||||
|
||||
|
||||
def test_add_sub():
|
||||
u = Quantity("u")
|
||||
v = Quantity("v")
|
||||
w = Quantity("w")
|
||||
|
||||
u.set_global_relative_scale_factor(S(10), meter)
|
||||
v.set_global_relative_scale_factor(S(5), meter)
|
||||
w.set_global_relative_scale_factor(S(2), second)
|
||||
|
||||
assert isinstance(u + v, Add)
|
||||
assert (u + v.convert_to(u)) == (1 + S.Half)*u
|
||||
assert isinstance(u - v, Add)
|
||||
assert (u - v.convert_to(u)) == S.Half*u
|
||||
|
||||
|
||||
def test_quantity_abs():
|
||||
v_w1 = Quantity('v_w1')
|
||||
v_w2 = Quantity('v_w2')
|
||||
v_w3 = Quantity('v_w3')
|
||||
|
||||
v_w1.set_global_relative_scale_factor(1, meter/second)
|
||||
v_w2.set_global_relative_scale_factor(1, meter/second)
|
||||
v_w3.set_global_relative_scale_factor(1, meter/second)
|
||||
|
||||
expr = v_w3 - Abs(v_w1 - v_w2)
|
||||
|
||||
assert SI.get_dimensional_expr(v_w1) == (length/time).name
|
||||
|
||||
Dq = Dimension(SI.get_dimensional_expr(expr))
|
||||
|
||||
assert SI.get_dimension_system().get_dimensional_dependencies(Dq) == {
|
||||
length: 1,
|
||||
time: -1,
|
||||
}
|
||||
assert meter == sqrt(meter**2)
|
||||
|
||||
|
||||
def test_check_unit_consistency():
|
||||
u = Quantity("u")
|
||||
v = Quantity("v")
|
||||
w = Quantity("w")
|
||||
|
||||
u.set_global_relative_scale_factor(S(10), meter)
|
||||
v.set_global_relative_scale_factor(S(5), meter)
|
||||
w.set_global_relative_scale_factor(S(2), second)
|
||||
|
||||
def check_unit_consistency(expr):
|
||||
SI._collect_factor_and_dimension(expr)
|
||||
|
||||
raises(ValueError, lambda: check_unit_consistency(u + w))
|
||||
raises(ValueError, lambda: check_unit_consistency(u - w))
|
||||
raises(ValueError, lambda: check_unit_consistency(u + 1))
|
||||
raises(ValueError, lambda: check_unit_consistency(u - 1))
|
||||
raises(ValueError, lambda: check_unit_consistency(1 - exp(u / w)))
|
||||
|
||||
|
||||
def test_mul_div():
|
||||
u = Quantity("u")
|
||||
v = Quantity("v")
|
||||
t = Quantity("t")
|
||||
ut = Quantity("ut")
|
||||
v2 = Quantity("v")
|
||||
|
||||
u.set_global_relative_scale_factor(S(10), meter)
|
||||
v.set_global_relative_scale_factor(S(5), meter)
|
||||
t.set_global_relative_scale_factor(S(2), second)
|
||||
ut.set_global_relative_scale_factor(S(20), meter*second)
|
||||
v2.set_global_relative_scale_factor(S(5), meter/second)
|
||||
|
||||
assert 1 / u == u**(-1)
|
||||
assert u / 1 == u
|
||||
|
||||
v1 = u / t
|
||||
v2 = v
|
||||
|
||||
# Pow only supports structural equality:
|
||||
assert v1 != v2
|
||||
assert v1 == v2.convert_to(v1)
|
||||
|
||||
# TODO: decide whether to allow such expression in the future
|
||||
# (requires somehow manipulating the core).
|
||||
# assert u / Quantity('l2', dimension=length, scale_factor=2) == 5
|
||||
|
||||
assert u * 1 == u
|
||||
|
||||
ut1 = u * t
|
||||
ut2 = ut
|
||||
|
||||
# Mul only supports structural equality:
|
||||
assert ut1 != ut2
|
||||
assert ut1 == ut2.convert_to(ut1)
|
||||
|
||||
# Mul only supports structural equality:
|
||||
lp1 = Quantity("lp1")
|
||||
lp1.set_global_relative_scale_factor(S(2), 1/meter)
|
||||
assert u * lp1 != 20
|
||||
|
||||
assert u**0 == 1
|
||||
assert u**1 == u
|
||||
|
||||
# TODO: Pow only support structural equality:
|
||||
u2 = Quantity("u2")
|
||||
u3 = Quantity("u3")
|
||||
u2.set_global_relative_scale_factor(S(100), meter**2)
|
||||
u3.set_global_relative_scale_factor(Rational(1, 10), 1/meter)
|
||||
|
||||
assert u ** 2 != u2
|
||||
assert u ** -1 != u3
|
||||
|
||||
assert u ** 2 == u2.convert_to(u)
|
||||
assert u ** -1 == u3.convert_to(u)
|
||||
|
||||
|
||||
def test_units():
|
||||
assert convert_to((5*m/s * day) / km, 1) == 432
|
||||
assert convert_to(foot / meter, meter) == Rational(3048, 10000)
|
||||
# amu is a pure mass so mass/mass gives a number, not an amount (mol)
|
||||
# TODO: need better simplification routine:
|
||||
assert str(convert_to(grams/amu, grams).n(2)) == '6.0e+23'
|
||||
|
||||
# Light from the sun needs about 8.3 minutes to reach earth
|
||||
t = (1*au / speed_of_light) / minute
|
||||
# TODO: need a better way to simplify expressions containing units:
|
||||
t = convert_to(convert_to(t, meter / minute), meter)
|
||||
assert t.simplify() == Rational(49865956897, 5995849160)
|
||||
|
||||
# TODO: fix this, it should give `m` without `Abs`
|
||||
assert sqrt(m**2) == m
|
||||
assert (sqrt(m))**2 == m
|
||||
|
||||
t = Symbol('t')
|
||||
assert integrate(t*m/s, (t, 1*s, 5*s)) == 12*m*s
|
||||
assert (t * m/s).integrate((t, 1*s, 5*s)) == 12*m*s
|
||||
|
||||
|
||||
def test_issue_quart():
|
||||
assert convert_to(4 * quart / inch ** 3, meter) == 231
|
||||
assert convert_to(4 * quart / inch ** 3, millimeter) == 231
|
||||
|
||||
def test_electron_rest_mass():
|
||||
assert convert_to(electron_rest_mass, kilogram) == 9.1093837015e-31*kilogram
|
||||
assert convert_to(electron_rest_mass, grams) == 9.1093837015e-28*grams
|
||||
|
||||
def test_issue_5565():
|
||||
assert (m < s).is_Relational
|
||||
|
||||
|
||||
def test_find_unit():
|
||||
assert find_unit('coulomb') == ['coulomb', 'coulombs', 'coulomb_constant']
|
||||
assert find_unit(coulomb) == ['C', 'coulomb', 'coulombs', 'planck_charge', 'elementary_charge']
|
||||
assert find_unit(charge) == ['C', 'coulomb', 'coulombs', 'planck_charge', 'elementary_charge']
|
||||
assert find_unit(inch) == [
|
||||
'm', 'au', 'cm', 'dm', 'ft', 'km', 'ly', 'mi', 'mm', 'nm', 'pm', 'um', 'yd',
|
||||
'nmi', 'feet', 'foot', 'inch', 'mile', 'yard', 'meter', 'miles', 'yards',
|
||||
'inches', 'meters', 'micron', 'microns', 'angstrom', 'angstroms', 'decimeter',
|
||||
'kilometer', 'lightyear', 'nanometer', 'picometer', 'centimeter', 'decimeters',
|
||||
'kilometers', 'lightyears', 'micrometer', 'millimeter', 'nanometers', 'picometers',
|
||||
'centimeters', 'micrometers', 'millimeters', 'nautical_mile', 'planck_length',
|
||||
'nautical_miles', 'astronomical_unit', 'astronomical_units']
|
||||
assert find_unit(inch**-1) == ['D', 'dioptre', 'optical_power']
|
||||
assert find_unit(length**-1) == ['D', 'dioptre', 'optical_power']
|
||||
assert find_unit(inch ** 2) == ['ha', 'hectare', 'planck_area']
|
||||
assert find_unit(inch ** 3) == [
|
||||
'L', 'l', 'cL', 'cl', 'dL', 'dl', 'mL', 'ml', 'liter', 'quart', 'liters', 'quarts',
|
||||
'deciliter', 'centiliter', 'deciliters', 'milliliter',
|
||||
'centiliters', 'milliliters', 'planck_volume']
|
||||
assert find_unit('voltage') == ['V', 'v', 'volt', 'volts', 'planck_voltage']
|
||||
assert find_unit(grams) == ['g', 't', 'Da', 'kg', 'me', 'mg', 'ug', 'amu', 'mmu', 'amus',
|
||||
'gram', 'mmus', 'grams', 'pound', 'tonne', 'dalton', 'pounds',
|
||||
'kilogram', 'kilograms', 'microgram', 'milligram', 'metric_ton',
|
||||
'micrograms', 'milligrams', 'planck_mass', 'milli_mass_unit', 'atomic_mass_unit',
|
||||
'electron_rest_mass', 'atomic_mass_constant']
|
||||
|
||||
|
||||
def test_Quantity_derivative():
|
||||
x = symbols("x")
|
||||
assert diff(x*meter, x) == meter
|
||||
assert diff(x**3*meter**2, x) == 3*x**2*meter**2
|
||||
assert diff(meter, meter) == 1
|
||||
assert diff(meter**2, meter) == 2*meter
|
||||
|
||||
|
||||
def test_quantity_postprocessing():
|
||||
q1 = Quantity('q1')
|
||||
q2 = Quantity('q2')
|
||||
|
||||
SI.set_quantity_dimension(q1, length*pressure**2*temperature/time)
|
||||
SI.set_quantity_dimension(q2, energy*pressure*temperature/(length**2*time))
|
||||
|
||||
assert q1 + q2
|
||||
q = q1 + q2
|
||||
Dq = Dimension(SI.get_dimensional_expr(q))
|
||||
assert SI.get_dimension_system().get_dimensional_dependencies(Dq) == {
|
||||
length: -1,
|
||||
mass: 2,
|
||||
temperature: 1,
|
||||
time: -5,
|
||||
}
|
||||
|
||||
|
||||
def test_factor_and_dimension():
|
||||
assert (3000, Dimension(1)) == SI._collect_factor_and_dimension(3000)
|
||||
assert (1001, length) == SI._collect_factor_and_dimension(meter + km)
|
||||
assert (2, length/time) == SI._collect_factor_and_dimension(
|
||||
meter/second + 36*km/(10*hour))
|
||||
|
||||
x, y = symbols('x y')
|
||||
assert (x + y/100, length) == SI._collect_factor_and_dimension(
|
||||
x*m + y*centimeter)
|
||||
|
||||
cH = Quantity('cH')
|
||||
SI.set_quantity_dimension(cH, amount_of_substance/volume)
|
||||
|
||||
pH = -log(cH)
|
||||
|
||||
assert (1, volume/amount_of_substance) == SI._collect_factor_and_dimension(
|
||||
exp(pH))
|
||||
|
||||
v_w1 = Quantity('v_w1')
|
||||
v_w2 = Quantity('v_w2')
|
||||
|
||||
v_w1.set_global_relative_scale_factor(Rational(3, 2), meter/second)
|
||||
v_w2.set_global_relative_scale_factor(2, meter/second)
|
||||
|
||||
expr = Abs(v_w1/2 - v_w2)
|
||||
assert (Rational(5, 4), length/time) == \
|
||||
SI._collect_factor_and_dimension(expr)
|
||||
|
||||
expr = Rational(5, 2)*second/meter*v_w1 - 3000
|
||||
assert (-(2996 + Rational(1, 4)), Dimension(1)) == \
|
||||
SI._collect_factor_and_dimension(expr)
|
||||
|
||||
expr = v_w1**(v_w2/v_w1)
|
||||
assert ((Rational(3, 2))**Rational(4, 3), (length/time)**Rational(4, 3)) == \
|
||||
SI._collect_factor_and_dimension(expr)
|
||||
|
||||
|
||||
def test_dimensional_expr_of_derivative():
|
||||
l = Quantity('l')
|
||||
t = Quantity('t')
|
||||
t1 = Quantity('t1')
|
||||
l.set_global_relative_scale_factor(36, km)
|
||||
t.set_global_relative_scale_factor(1, hour)
|
||||
t1.set_global_relative_scale_factor(1, second)
|
||||
x = Symbol('x')
|
||||
y = Symbol('y')
|
||||
f = Function('f')
|
||||
dfdx = f(x, y).diff(x, y)
|
||||
dl_dt = dfdx.subs({f(x, y): l, x: t, y: t1})
|
||||
assert SI.get_dimensional_expr(dl_dt) ==\
|
||||
SI.get_dimensional_expr(l / t / t1) ==\
|
||||
Symbol("length")/Symbol("time")**2
|
||||
assert SI._collect_factor_and_dimension(dl_dt) ==\
|
||||
SI._collect_factor_and_dimension(l / t / t1) ==\
|
||||
(10, length/time**2)
|
||||
|
||||
|
||||
def test_get_dimensional_expr_with_function():
|
||||
v_w1 = Quantity('v_w1')
|
||||
v_w2 = Quantity('v_w2')
|
||||
v_w1.set_global_relative_scale_factor(1, meter/second)
|
||||
v_w2.set_global_relative_scale_factor(1, meter/second)
|
||||
|
||||
assert SI.get_dimensional_expr(sin(v_w1)) == \
|
||||
sin(SI.get_dimensional_expr(v_w1))
|
||||
assert SI.get_dimensional_expr(sin(v_w1/v_w2)) == 1
|
||||
|
||||
|
||||
def test_binary_information():
|
||||
assert convert_to(kibibyte, byte) == 1024*byte
|
||||
assert convert_to(mebibyte, byte) == 1024**2*byte
|
||||
assert convert_to(gibibyte, byte) == 1024**3*byte
|
||||
assert convert_to(tebibyte, byte) == 1024**4*byte
|
||||
assert convert_to(pebibyte, byte) == 1024**5*byte
|
||||
assert convert_to(exbibyte, byte) == 1024**6*byte
|
||||
|
||||
assert kibibyte.convert_to(bit) == 8*1024*bit
|
||||
assert byte.convert_to(bit) == 8*bit
|
||||
|
||||
a = 10*kibibyte*hour
|
||||
|
||||
assert convert_to(a, byte) == 10240*byte*hour
|
||||
assert convert_to(a, minute) == 600*kibibyte*minute
|
||||
assert convert_to(a, [byte, minute]) == 614400*byte*minute
|
||||
|
||||
|
||||
def test_conversion_with_2_nonstandard_dimensions():
|
||||
good_grade = Quantity("good_grade")
|
||||
kilo_good_grade = Quantity("kilo_good_grade")
|
||||
centi_good_grade = Quantity("centi_good_grade")
|
||||
|
||||
kilo_good_grade.set_global_relative_scale_factor(1000, good_grade)
|
||||
centi_good_grade.set_global_relative_scale_factor(S.One/10**5, kilo_good_grade)
|
||||
|
||||
charity_points = Quantity("charity_points")
|
||||
milli_charity_points = Quantity("milli_charity_points")
|
||||
missions = Quantity("missions")
|
||||
|
||||
milli_charity_points.set_global_relative_scale_factor(S.One/1000, charity_points)
|
||||
missions.set_global_relative_scale_factor(251, charity_points)
|
||||
|
||||
assert convert_to(
|
||||
kilo_good_grade*milli_charity_points*millimeter,
|
||||
[centi_good_grade, missions, centimeter]
|
||||
) == S.One * 10**5 / (251*1000) / 10 * centi_good_grade*missions*centimeter
|
||||
|
||||
|
||||
def test_eval_subs():
|
||||
energy, mass, force = symbols('energy mass force')
|
||||
expr1 = energy/mass
|
||||
units = {energy: kilogram*meter**2/second**2, mass: kilogram}
|
||||
assert expr1.subs(units) == meter**2/second**2
|
||||
expr2 = force/mass
|
||||
units = {force:gravitational_constant*kilogram**2/meter**2, mass:kilogram}
|
||||
assert expr2.subs(units) == gravitational_constant*kilogram/meter**2
|
||||
|
||||
|
||||
def test_issue_14932():
|
||||
assert (log(inch) - log(2)).simplify() == log(inch/2)
|
||||
assert (log(inch) - log(foot)).simplify() == -log(12)
|
||||
p = symbols('p', positive=True)
|
||||
assert (log(inch) - log(p)).simplify() == log(inch/p)
|
||||
|
||||
|
||||
def test_issue_14547():
|
||||
# the root issue is that an argument with dimensions should
|
||||
# not raise an error when the `arg - 1` calculation is
|
||||
# performed in the assumptions system
|
||||
from sympy.physics.units import foot, inch
|
||||
from sympy.core.relational import Eq
|
||||
assert log(foot).is_zero is None
|
||||
assert log(foot).is_positive is None
|
||||
assert log(foot).is_nonnegative is None
|
||||
assert log(foot).is_negative is None
|
||||
assert log(foot).is_algebraic is None
|
||||
assert log(foot).is_rational is None
|
||||
# doesn't raise error
|
||||
assert Eq(log(foot), log(inch)) is not None # might be False or unevaluated
|
||||
|
||||
x = Symbol('x')
|
||||
e = foot + x
|
||||
assert e.is_Add and set(e.args) == {foot, x}
|
||||
e = foot + 1
|
||||
assert e.is_Add and set(e.args) == {foot, 1}
|
||||
|
||||
|
||||
def test_issue_22164():
|
||||
warnings.simplefilter("error")
|
||||
dm = Quantity("dm")
|
||||
SI.set_quantity_dimension(dm, length)
|
||||
SI.set_quantity_scale_factor(dm, 1)
|
||||
|
||||
bad_exp = Quantity("bad_exp")
|
||||
SI.set_quantity_dimension(bad_exp, length)
|
||||
SI.set_quantity_scale_factor(bad_exp, 1)
|
||||
|
||||
expr = dm ** bad_exp
|
||||
|
||||
# deprecation warning is not expected here
|
||||
SI._collect_factor_and_dimension(expr)
|
||||
|
||||
|
||||
def test_issue_22819():
|
||||
from sympy.physics.units import tonne, gram, Da
|
||||
from sympy.physics.units.systems.si import dimsys_SI
|
||||
assert tonne.convert_to(gram) == 1000000*gram
|
||||
assert dimsys_SI.get_dimensional_dependencies(area) == {length: 2}
|
||||
assert Da.scale_factor == 1.66053906660000e-24
|
||||
|
||||
|
||||
def test_issue_20288():
|
||||
from sympy.core.numbers import E
|
||||
from sympy.physics.units import energy
|
||||
u = Quantity('u')
|
||||
v = Quantity('v')
|
||||
SI.set_quantity_dimension(u, energy)
|
||||
SI.set_quantity_dimension(v, energy)
|
||||
u.set_global_relative_scale_factor(1, joule)
|
||||
v.set_global_relative_scale_factor(1, joule)
|
||||
expr = 1 + exp(u**2/v**2)
|
||||
assert SI._collect_factor_and_dimension(expr) == (1 + E, Dimension(1))
|
||||
|
||||
|
||||
def test_issue_24062():
|
||||
from sympy.core.numbers import E
|
||||
from sympy.physics.units import impedance, capacitance, time, ohm, farad, second
|
||||
|
||||
R = Quantity('R')
|
||||
C = Quantity('C')
|
||||
T = Quantity('T')
|
||||
SI.set_quantity_dimension(R, impedance)
|
||||
SI.set_quantity_dimension(C, capacitance)
|
||||
SI.set_quantity_dimension(T, time)
|
||||
R.set_global_relative_scale_factor(1, ohm)
|
||||
C.set_global_relative_scale_factor(1, farad)
|
||||
T.set_global_relative_scale_factor(1, second)
|
||||
expr = T / (R * C)
|
||||
dim = SI._collect_factor_and_dimension(expr)[1]
|
||||
assert SI.get_dimension_system().is_dimensionless(dim)
|
||||
|
||||
exp_expr = 1 + exp(expr)
|
||||
assert SI._collect_factor_and_dimension(exp_expr) == (1 + E, Dimension(1))
|
||||
|
||||
def test_issue_24211():
|
||||
from sympy.physics.units import time, velocity, acceleration, second, meter
|
||||
V1 = Quantity('V1')
|
||||
SI.set_quantity_dimension(V1, velocity)
|
||||
SI.set_quantity_scale_factor(V1, 1 * meter / second)
|
||||
A1 = Quantity('A1')
|
||||
SI.set_quantity_dimension(A1, acceleration)
|
||||
SI.set_quantity_scale_factor(A1, 1 * meter / second**2)
|
||||
T1 = Quantity('T1')
|
||||
SI.set_quantity_dimension(T1, time)
|
||||
SI.set_quantity_scale_factor(T1, 1 * second)
|
||||
|
||||
expr = A1*T1 + V1
|
||||
# should not throw ValueError here
|
||||
SI._collect_factor_and_dimension(expr)
|
||||
|
||||
|
||||
def test_prefixed_property():
|
||||
assert not meter.is_prefixed
|
||||
assert not joule.is_prefixed
|
||||
assert not day.is_prefixed
|
||||
assert not second.is_prefixed
|
||||
assert not volt.is_prefixed
|
||||
assert not ohm.is_prefixed
|
||||
assert centimeter.is_prefixed
|
||||
assert kilometer.is_prefixed
|
||||
assert kilogram.is_prefixed
|
||||
assert pebibyte.is_prefixed
|
||||
|
||||
def test_physics_constant():
|
||||
from sympy.physics.units import definitions
|
||||
|
||||
for name in dir(definitions):
|
||||
quantity = getattr(definitions, name)
|
||||
if not isinstance(quantity, Quantity):
|
||||
continue
|
||||
if name.endswith('_constant'):
|
||||
assert isinstance(quantity, PhysicalConstant), f"{quantity} must be PhysicalConstant, but is {type(quantity)}"
|
||||
assert quantity.is_physical_constant, f"{name} is not marked as physics constant when it should be"
|
||||
|
||||
for const in [gravitational_constant, molar_gas_constant, vacuum_permittivity, speed_of_light, elementary_charge]:
|
||||
assert isinstance(const, PhysicalConstant), f"{const} must be PhysicalConstant, but is {type(const)}"
|
||||
assert const.is_physical_constant, f"{const} is not marked as physics constant when it should be"
|
||||
|
||||
assert not meter.is_physical_constant
|
||||
assert not joule.is_physical_constant
|
||||
@@ -0,0 +1,55 @@
|
||||
from sympy.concrete.tests.test_sums_products import NS
|
||||
|
||||
from sympy.core.singleton import S
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.physics.units import convert_to, coulomb_constant, elementary_charge, gravitational_constant, planck
|
||||
from sympy.physics.units.definitions.unit_definitions import angstrom, statcoulomb, coulomb, second, gram, centimeter, erg, \
|
||||
newton, joule, dyne, speed_of_light, meter, farad, henry, statvolt, volt, ohm
|
||||
from sympy.physics.units.systems import SI
|
||||
from sympy.physics.units.systems.cgs import cgs_gauss
|
||||
|
||||
|
||||
def test_conversion_to_from_si():
|
||||
assert convert_to(statcoulomb, coulomb, cgs_gauss) == coulomb/2997924580
|
||||
assert convert_to(coulomb, statcoulomb, cgs_gauss) == 2997924580*statcoulomb
|
||||
assert convert_to(statcoulomb, sqrt(gram*centimeter**3)/second, cgs_gauss) == centimeter**(S(3)/2)*sqrt(gram)/second
|
||||
assert convert_to(coulomb, sqrt(gram*centimeter**3)/second, cgs_gauss) == 2997924580*centimeter**(S(3)/2)*sqrt(gram)/second
|
||||
|
||||
# SI units have an additional base unit, no conversion in case of electromagnetism:
|
||||
assert convert_to(coulomb, statcoulomb, SI) == coulomb
|
||||
assert convert_to(statcoulomb, coulomb, SI) == statcoulomb
|
||||
|
||||
# SI without electromagnetism:
|
||||
assert convert_to(erg, joule, SI) == joule/10**7
|
||||
assert convert_to(erg, joule, cgs_gauss) == joule/10**7
|
||||
assert convert_to(joule, erg, SI) == 10**7*erg
|
||||
assert convert_to(joule, erg, cgs_gauss) == 10**7*erg
|
||||
|
||||
|
||||
assert convert_to(dyne, newton, SI) == newton/10**5
|
||||
assert convert_to(dyne, newton, cgs_gauss) == newton/10**5
|
||||
assert convert_to(newton, dyne, SI) == 10**5*dyne
|
||||
assert convert_to(newton, dyne, cgs_gauss) == 10**5*dyne
|
||||
|
||||
|
||||
def test_cgs_gauss_convert_constants():
|
||||
|
||||
assert convert_to(speed_of_light, centimeter/second, cgs_gauss) == 29979245800*centimeter/second
|
||||
|
||||
assert convert_to(coulomb_constant, 1, cgs_gauss) == 1
|
||||
assert convert_to(coulomb_constant, newton*meter**2/coulomb**2, cgs_gauss) == 22468879468420441*meter**2*newton/(2500000*coulomb**2)
|
||||
assert convert_to(coulomb_constant, newton*meter**2/coulomb**2, SI) == 22468879468420441*meter**2*newton/(2500000*coulomb**2)
|
||||
assert convert_to(coulomb_constant, dyne*centimeter**2/statcoulomb**2, cgs_gauss) == centimeter**2*dyne/statcoulomb**2
|
||||
assert convert_to(coulomb_constant, 1, SI) == coulomb_constant
|
||||
assert NS(convert_to(coulomb_constant, newton*meter**2/coulomb**2, SI)) == '8987551787.36818*meter**2*newton/coulomb**2'
|
||||
|
||||
assert convert_to(elementary_charge, statcoulomb, cgs_gauss)
|
||||
assert convert_to(angstrom, centimeter, cgs_gauss) == 1*centimeter/10**8
|
||||
assert convert_to(gravitational_constant, dyne*centimeter**2/gram**2, cgs_gauss)
|
||||
assert NS(convert_to(planck, erg*second, cgs_gauss)) == '6.62607015e-27*erg*second'
|
||||
|
||||
spc = 25000*second/(22468879468420441*centimeter)
|
||||
assert convert_to(ohm, second/centimeter, cgs_gauss) == spc
|
||||
assert convert_to(henry, second**2/centimeter, cgs_gauss) == spc*second
|
||||
assert convert_to(volt, statvolt, cgs_gauss) == 10**6*statvolt/299792458
|
||||
assert convert_to(farad, centimeter, cgs_gauss) == 299792458**2*centimeter/10**5
|
||||
@@ -0,0 +1,86 @@
|
||||
from sympy.physics.units import DimensionSystem, joule, second, ampere
|
||||
|
||||
from sympy.core.numbers import Rational
|
||||
from sympy.core.singleton import S
|
||||
from sympy.physics.units.definitions import c, kg, m, s
|
||||
from sympy.physics.units.definitions.dimension_definitions import length, time
|
||||
from sympy.physics.units.quantities import Quantity
|
||||
from sympy.physics.units.unitsystem import UnitSystem
|
||||
from sympy.physics.units.util import convert_to
|
||||
|
||||
|
||||
def test_definition():
|
||||
# want to test if the system can have several units of the same dimension
|
||||
dm = Quantity("dm")
|
||||
base = (m, s)
|
||||
# base_dim = (m.dimension, s.dimension)
|
||||
ms = UnitSystem(base, (c, dm), "MS", "MS system")
|
||||
ms.set_quantity_dimension(dm, length)
|
||||
ms.set_quantity_scale_factor(dm, Rational(1, 10))
|
||||
|
||||
assert set(ms._base_units) == set(base)
|
||||
assert set(ms._units) == {m, s, c, dm}
|
||||
# assert ms._units == DimensionSystem._sort_dims(base + (velocity,))
|
||||
assert ms.name == "MS"
|
||||
assert ms.descr == "MS system"
|
||||
|
||||
|
||||
def test_str_repr():
|
||||
assert str(UnitSystem((m, s), name="MS")) == "MS"
|
||||
assert str(UnitSystem((m, s))) == "UnitSystem((meter, second))"
|
||||
|
||||
assert repr(UnitSystem((m, s))) == "<UnitSystem: (%s, %s)>" % (m, s)
|
||||
|
||||
|
||||
def test_convert_to():
|
||||
A = Quantity("A")
|
||||
A.set_global_relative_scale_factor(S.One, ampere)
|
||||
|
||||
Js = Quantity("Js")
|
||||
Js.set_global_relative_scale_factor(S.One, joule*second)
|
||||
|
||||
mksa = UnitSystem((m, kg, s, A), (Js,))
|
||||
assert convert_to(Js, mksa._base_units) == m**2*kg*s**-1/1000
|
||||
|
||||
|
||||
def test_extend():
|
||||
ms = UnitSystem((m, s), (c,))
|
||||
Js = Quantity("Js")
|
||||
Js.set_global_relative_scale_factor(1, joule*second)
|
||||
mks = ms.extend((kg,), (Js,))
|
||||
|
||||
res = UnitSystem((m, s, kg), (c, Js))
|
||||
assert set(mks._base_units) == set(res._base_units)
|
||||
assert set(mks._units) == set(res._units)
|
||||
|
||||
|
||||
def test_dim():
|
||||
dimsys = UnitSystem((m, kg, s), (c,))
|
||||
assert dimsys.dim == 3
|
||||
|
||||
|
||||
def test_is_consistent():
|
||||
dimension_system = DimensionSystem([length, time])
|
||||
us = UnitSystem([m, s], dimension_system=dimension_system)
|
||||
assert us.is_consistent == True
|
||||
|
||||
|
||||
def test_get_units_non_prefixed():
|
||||
from sympy.physics.units import volt, ohm
|
||||
unit_system = UnitSystem.get_unit_system("SI")
|
||||
units = unit_system.get_units_non_prefixed()
|
||||
for prefix in ["giga", "tera", "peta", "exa", "zetta", "yotta", "kilo", "hecto", "deca", "deci", "centi", "milli", "micro", "nano", "pico", "femto", "atto", "zepto", "yocto"]:
|
||||
for unit in units:
|
||||
assert isinstance(unit, Quantity), f"{unit} must be a Quantity, not {type(unit)}"
|
||||
assert not unit.is_prefixed, f"{unit} is marked as prefixed"
|
||||
assert not unit.is_physical_constant, f"{unit} is marked as physics constant"
|
||||
assert not unit.name.name.startswith(prefix), f"Unit {unit.name} has prefix {prefix}"
|
||||
assert volt in units
|
||||
assert ohm in units
|
||||
|
||||
def test_derived_units_must_exist_in_unit_system():
|
||||
for unit_system in UnitSystem._unit_systems.values():
|
||||
for preferred_unit in unit_system.derived_units.values():
|
||||
units = preferred_unit.atoms(Quantity)
|
||||
for unit in units:
|
||||
assert unit in unit_system._units, f"Unit {unit} is not in unit system {unit_system}"
|
||||
@@ -0,0 +1,178 @@
|
||||
from sympy.core.containers import Tuple
|
||||
from sympy.core.numbers import pi
|
||||
from sympy.core.power import Pow
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.printing.str import sstr
|
||||
from sympy.physics.units import (
|
||||
G, centimeter, coulomb, day, degree, gram, hbar, hour, inch, joule, kelvin,
|
||||
kilogram, kilometer, length, meter, mile, minute, newton, planck,
|
||||
planck_length, planck_mass, planck_temperature, planck_time, radians,
|
||||
second, speed_of_light, steradian, time, km)
|
||||
from sympy.physics.units.util import convert_to, check_dimensions
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
|
||||
|
||||
def NS(e, n=15, **options):
|
||||
return sstr(sympify(e).evalf(n, **options), full_prec=True)
|
||||
|
||||
|
||||
L = length
|
||||
T = time
|
||||
|
||||
|
||||
def test_dim_simplify_add():
|
||||
# assert Add(L, L) == L
|
||||
assert L + L == L
|
||||
|
||||
|
||||
def test_dim_simplify_mul():
|
||||
# assert Mul(L, T) == L*T
|
||||
assert L*T == L*T
|
||||
|
||||
|
||||
def test_dim_simplify_pow():
|
||||
assert Pow(L, 2) == L**2
|
||||
|
||||
|
||||
def test_dim_simplify_rec():
|
||||
# assert Mul(Add(L, L), T) == L*T
|
||||
assert (L + L) * T == L*T
|
||||
|
||||
|
||||
def test_convert_to_quantities():
|
||||
assert convert_to(3, meter) == 3
|
||||
|
||||
assert convert_to(mile, kilometer) == 25146*kilometer/15625
|
||||
assert convert_to(meter/second, speed_of_light) == speed_of_light/299792458
|
||||
assert convert_to(299792458*meter/second, speed_of_light) == speed_of_light
|
||||
assert convert_to(2*299792458*meter/second, speed_of_light) == 2*speed_of_light
|
||||
assert convert_to(speed_of_light, meter/second) == 299792458*meter/second
|
||||
assert convert_to(2*speed_of_light, meter/second) == 599584916*meter/second
|
||||
assert convert_to(day, second) == 86400*second
|
||||
assert convert_to(2*hour, minute) == 120*minute
|
||||
assert convert_to(mile, meter) == 201168*meter/125
|
||||
assert convert_to(mile/hour, kilometer/hour) == 25146*kilometer/(15625*hour)
|
||||
assert convert_to(3*newton, meter/second) == 3*newton
|
||||
assert convert_to(3*newton, kilogram*meter/second**2) == 3*meter*kilogram/second**2
|
||||
assert convert_to(kilometer + mile, meter) == 326168*meter/125
|
||||
assert convert_to(2*kilometer + 3*mile, meter) == 853504*meter/125
|
||||
assert convert_to(inch**2, meter**2) == 16129*meter**2/25000000
|
||||
assert convert_to(3*inch**2, meter) == 48387*meter**2/25000000
|
||||
assert convert_to(2*kilometer/hour + 3*mile/hour, meter/second) == 53344*meter/(28125*second)
|
||||
assert convert_to(2*kilometer/hour + 3*mile/hour, centimeter/second) == 213376*centimeter/(1125*second)
|
||||
assert convert_to(kilometer * (mile + kilometer), meter) == 2609344 * meter ** 2
|
||||
|
||||
assert convert_to(steradian, coulomb) == steradian
|
||||
assert convert_to(radians, degree) == 180*degree/pi
|
||||
assert convert_to(radians, [meter, degree]) == 180*degree/pi
|
||||
assert convert_to(pi*radians, degree) == 180*degree
|
||||
assert convert_to(pi, degree) == 180*degree
|
||||
|
||||
# https://github.com/sympy/sympy/issues/26263
|
||||
assert convert_to(sqrt(meter**2 + meter**2.0), meter) == sqrt(meter**2 + meter**2.0)
|
||||
assert convert_to((meter**2 + meter**2.0)**2, meter) == (meter**2 + meter**2.0)**2
|
||||
|
||||
|
||||
def test_convert_to_tuples_of_quantities():
|
||||
from sympy.core.symbol import symbols
|
||||
|
||||
alpha, beta = symbols('alpha beta')
|
||||
|
||||
assert convert_to(speed_of_light, [meter, second]) == 299792458 * meter / second
|
||||
assert convert_to(speed_of_light, (meter, second)) == 299792458 * meter / second
|
||||
assert convert_to(speed_of_light, Tuple(meter, second)) == 299792458 * meter / second
|
||||
assert convert_to(joule, [meter, kilogram, second]) == kilogram*meter**2/second**2
|
||||
assert convert_to(joule, [centimeter, gram, second]) == 10000000*centimeter**2*gram/second**2
|
||||
assert convert_to(299792458*meter/second, [speed_of_light]) == speed_of_light
|
||||
assert convert_to(speed_of_light / 2, [meter, second, kilogram]) == meter/second*299792458 / 2
|
||||
# This doesn't make physically sense, but let's keep it as a conversion test:
|
||||
assert convert_to(2 * speed_of_light, [meter, second, kilogram]) == 2 * 299792458 * meter / second
|
||||
assert convert_to(G, [G, speed_of_light, planck]) == 1.0*G
|
||||
|
||||
assert NS(convert_to(meter, [G, speed_of_light, hbar]), n=7) == '6.187142e+34*gravitational_constant**0.5000000*hbar**0.5000000/speed_of_light**1.500000'
|
||||
assert NS(convert_to(planck_mass, kilogram), n=7) == '2.176434e-8*kilogram'
|
||||
assert NS(convert_to(planck_length, meter), n=7) == '1.616255e-35*meter'
|
||||
assert NS(convert_to(planck_time, second), n=6) == '5.39125e-44*second'
|
||||
assert NS(convert_to(planck_temperature, kelvin), n=7) == '1.416784e+32*kelvin'
|
||||
assert NS(convert_to(convert_to(meter, [G, speed_of_light, planck]), meter), n=10) == '1.000000000*meter'
|
||||
|
||||
# similar to https://github.com/sympy/sympy/issues/26263
|
||||
assert convert_to(sqrt(meter**2 + second**2.0), [meter, second]) == sqrt(meter**2 + second**2.0)
|
||||
assert convert_to((meter**2 + second**2.0)**2, [meter, second]) == (meter**2 + second**2.0)**2
|
||||
|
||||
# similar to https://github.com/sympy/sympy/issues/21463
|
||||
assert convert_to(1/(beta*meter + meter), 1/meter) == 1/(beta*meter + meter)
|
||||
assert convert_to(1/(beta*meter + alpha*meter), 1/kilometer) == (1/(kilometer*beta/1000 + alpha*kilometer/1000))
|
||||
|
||||
def test_eval_simplify():
|
||||
from sympy.physics.units import cm, mm, km, m, K, kilo
|
||||
from sympy.core.symbol import symbols
|
||||
|
||||
x, y = symbols('x y')
|
||||
|
||||
assert (cm/mm).simplify() == 10
|
||||
assert (km/m).simplify() == 1000
|
||||
assert (km/cm).simplify() == 100000
|
||||
assert (10*x*K*km**2/m/cm).simplify() == 1000000000*x*kelvin
|
||||
assert (cm/km/m).simplify() == 1/(10000000*centimeter)
|
||||
|
||||
assert (3*kilo*meter).simplify() == 3000*meter
|
||||
assert (4*kilo*meter/(2*kilometer)).simplify() == 2
|
||||
assert (4*kilometer**2/(kilo*meter)**2).simplify() == 4
|
||||
|
||||
|
||||
def test_quantity_simplify():
|
||||
from sympy.physics.units.util import quantity_simplify
|
||||
from sympy.physics.units import kilo, foot
|
||||
from sympy.core.symbol import symbols
|
||||
|
||||
x, y = symbols('x y')
|
||||
|
||||
assert quantity_simplify(x*(8*kilo*newton*meter + y)) == x*(8000*meter*newton + y)
|
||||
assert quantity_simplify(foot*inch*(foot + inch)) == foot**2*(foot + foot/12)/12
|
||||
assert quantity_simplify(foot*inch*(foot*foot + inch*(foot + inch))) == foot**2*(foot**2 + foot/12*(foot + foot/12))/12
|
||||
assert quantity_simplify(2**(foot/inch*kilo/1000)*inch) == 4096*foot/12
|
||||
assert quantity_simplify(foot**2*inch + inch**2*foot) == 13*foot**3/144
|
||||
|
||||
def test_quantity_simplify_across_dimensions():
|
||||
from sympy.physics.units.util import quantity_simplify
|
||||
from sympy.physics.units import ampere, ohm, volt, joule, pascal, farad, second, watt, siemens, henry, tesla, weber, hour, newton
|
||||
|
||||
assert quantity_simplify(ampere*ohm, across_dimensions=True, unit_system="SI") == volt
|
||||
assert quantity_simplify(6*ampere*ohm, across_dimensions=True, unit_system="SI") == 6*volt
|
||||
assert quantity_simplify(volt/ampere, across_dimensions=True, unit_system="SI") == ohm
|
||||
assert quantity_simplify(volt/ohm, across_dimensions=True, unit_system="SI") == ampere
|
||||
assert quantity_simplify(joule/meter**3, across_dimensions=True, unit_system="SI") == pascal
|
||||
assert quantity_simplify(farad*ohm, across_dimensions=True, unit_system="SI") == second
|
||||
assert quantity_simplify(joule/second, across_dimensions=True, unit_system="SI") == watt
|
||||
assert quantity_simplify(meter**3/second, across_dimensions=True, unit_system="SI") == meter**3/second
|
||||
assert quantity_simplify(joule/second, across_dimensions=True, unit_system="SI") == watt
|
||||
|
||||
assert quantity_simplify(joule/coulomb, across_dimensions=True, unit_system="SI") == volt
|
||||
assert quantity_simplify(volt/ampere, across_dimensions=True, unit_system="SI") == ohm
|
||||
assert quantity_simplify(ampere/volt, across_dimensions=True, unit_system="SI") == siemens
|
||||
assert quantity_simplify(coulomb/volt, across_dimensions=True, unit_system="SI") == farad
|
||||
assert quantity_simplify(volt*second/ampere, across_dimensions=True, unit_system="SI") == henry
|
||||
assert quantity_simplify(volt*second/meter**2, across_dimensions=True, unit_system="SI") == tesla
|
||||
assert quantity_simplify(joule/ampere, across_dimensions=True, unit_system="SI") == weber
|
||||
|
||||
assert quantity_simplify(5*kilometer/hour, across_dimensions=True, unit_system="SI") == 25*meter/(18*second)
|
||||
assert quantity_simplify(5*kilogram*meter/second**2, across_dimensions=True, unit_system="SI") == 5*newton
|
||||
|
||||
def test_check_dimensions():
|
||||
x = symbols('x')
|
||||
assert check_dimensions(inch + x) == inch + x
|
||||
assert check_dimensions(length + x) == length + x
|
||||
# after subs we get 2*length; check will clear the constant
|
||||
assert check_dimensions((length + x).subs(x, length)) == length
|
||||
assert check_dimensions(newton*meter + joule) == joule + meter*newton
|
||||
raises(ValueError, lambda: check_dimensions(inch + 1))
|
||||
raises(ValueError, lambda: check_dimensions(length + 1))
|
||||
raises(ValueError, lambda: check_dimensions(length + time))
|
||||
raises(ValueError, lambda: check_dimensions(meter + second))
|
||||
raises(ValueError, lambda: check_dimensions(2 * meter + second))
|
||||
raises(ValueError, lambda: check_dimensions(2 * meter + 3 * second))
|
||||
raises(ValueError, lambda: check_dimensions(1 / second + 1 / meter))
|
||||
raises(ValueError, lambda: check_dimensions(2 * meter*(mile + centimeter) + km))
|
||||
@@ -0,0 +1,204 @@
|
||||
"""
|
||||
Unit system for physical quantities; include definition of constants.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from sympy.core.add import Add
|
||||
from sympy.core.function import (Derivative, Function)
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.core.power import Pow
|
||||
from sympy.core.singleton import S
|
||||
from sympy.physics.units.dimensions import _QuantityMapper
|
||||
from sympy.physics.units.quantities import Quantity
|
||||
|
||||
from .dimensions import Dimension
|
||||
|
||||
|
||||
class UnitSystem(_QuantityMapper):
|
||||
"""
|
||||
UnitSystem represents a coherent set of units.
|
||||
|
||||
A unit system is basically a dimension system with notions of scales. Many
|
||||
of the methods are defined in the same way.
|
||||
|
||||
It is much better if all base units have a symbol.
|
||||
"""
|
||||
|
||||
_unit_systems: dict[str, UnitSystem] = {}
|
||||
|
||||
def __init__(self, base_units, units=(), name="", descr="", dimension_system=None, derived_units: dict[Dimension, Quantity]={}):
|
||||
|
||||
UnitSystem._unit_systems[name] = self
|
||||
|
||||
self.name = name
|
||||
self.descr = descr
|
||||
|
||||
self._base_units = base_units
|
||||
self._dimension_system = dimension_system
|
||||
self._units = tuple(set(base_units) | set(units))
|
||||
self._base_units = tuple(base_units)
|
||||
self._derived_units = derived_units
|
||||
|
||||
super().__init__()
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
Return the name of the system.
|
||||
|
||||
If it does not exist, then it makes a list of symbols (or names) of
|
||||
the base dimensions.
|
||||
"""
|
||||
|
||||
if self.name != "":
|
||||
return self.name
|
||||
else:
|
||||
return "UnitSystem((%s))" % ", ".join(
|
||||
str(d) for d in self._base_units)
|
||||
|
||||
def __repr__(self):
|
||||
return '<UnitSystem: %s>' % repr(self._base_units)
|
||||
|
||||
def extend(self, base, units=(), name="", description="", dimension_system=None, derived_units: dict[Dimension, Quantity]={}):
|
||||
"""Extend the current system into a new one.
|
||||
|
||||
Take the base and normal units of the current system to merge
|
||||
them to the base and normal units given in argument.
|
||||
If not provided, name and description are overridden by empty strings.
|
||||
"""
|
||||
|
||||
base = self._base_units + tuple(base)
|
||||
units = self._units + tuple(units)
|
||||
|
||||
return UnitSystem(base, units, name, description, dimension_system, {**self._derived_units, **derived_units})
|
||||
|
||||
def get_dimension_system(self):
|
||||
return self._dimension_system
|
||||
|
||||
def get_quantity_dimension(self, unit):
|
||||
qdm = self.get_dimension_system()._quantity_dimension_map
|
||||
if unit in qdm:
|
||||
return qdm[unit]
|
||||
return super().get_quantity_dimension(unit)
|
||||
|
||||
def get_quantity_scale_factor(self, unit):
|
||||
qsfm = self.get_dimension_system()._quantity_scale_factors
|
||||
if unit in qsfm:
|
||||
return qsfm[unit]
|
||||
return super().get_quantity_scale_factor(unit)
|
||||
|
||||
@staticmethod
|
||||
def get_unit_system(unit_system):
|
||||
if isinstance(unit_system, UnitSystem):
|
||||
return unit_system
|
||||
|
||||
if unit_system not in UnitSystem._unit_systems:
|
||||
raise ValueError(
|
||||
"Unit system is not supported. Currently"
|
||||
"supported unit systems are {}".format(
|
||||
", ".join(sorted(UnitSystem._unit_systems))
|
||||
)
|
||||
)
|
||||
|
||||
return UnitSystem._unit_systems[unit_system]
|
||||
|
||||
@staticmethod
|
||||
def get_default_unit_system():
|
||||
return UnitSystem._unit_systems["SI"]
|
||||
|
||||
@property
|
||||
def dim(self):
|
||||
"""
|
||||
Give the dimension of the system.
|
||||
|
||||
That is return the number of units forming the basis.
|
||||
"""
|
||||
return len(self._base_units)
|
||||
|
||||
@property
|
||||
def is_consistent(self):
|
||||
"""
|
||||
Check if the underlying dimension system is consistent.
|
||||
"""
|
||||
# test is performed in DimensionSystem
|
||||
return self.get_dimension_system().is_consistent
|
||||
|
||||
@property
|
||||
def derived_units(self) -> dict[Dimension, Quantity]:
|
||||
return self._derived_units
|
||||
|
||||
def get_dimensional_expr(self, expr):
|
||||
from sympy.physics.units import Quantity
|
||||
if isinstance(expr, Mul):
|
||||
return Mul(*[self.get_dimensional_expr(i) for i in expr.args])
|
||||
elif isinstance(expr, Pow):
|
||||
return self.get_dimensional_expr(expr.base) ** expr.exp
|
||||
elif isinstance(expr, Add):
|
||||
return self.get_dimensional_expr(expr.args[0])
|
||||
elif isinstance(expr, Derivative):
|
||||
dim = self.get_dimensional_expr(expr.expr)
|
||||
for independent, count in expr.variable_count:
|
||||
dim /= self.get_dimensional_expr(independent)**count
|
||||
return dim
|
||||
elif isinstance(expr, Function):
|
||||
args = [self.get_dimensional_expr(arg) for arg in expr.args]
|
||||
if all(i == 1 for i in args):
|
||||
return S.One
|
||||
return expr.func(*args)
|
||||
elif isinstance(expr, Quantity):
|
||||
return self.get_quantity_dimension(expr).name
|
||||
return S.One
|
||||
|
||||
def _collect_factor_and_dimension(self, expr):
|
||||
"""
|
||||
Return tuple with scale factor expression and dimension expression.
|
||||
"""
|
||||
from sympy.physics.units import Quantity
|
||||
if isinstance(expr, Quantity):
|
||||
return expr.scale_factor, expr.dimension
|
||||
elif isinstance(expr, Mul):
|
||||
factor = 1
|
||||
dimension = Dimension(1)
|
||||
for arg in expr.args:
|
||||
arg_factor, arg_dim = self._collect_factor_and_dimension(arg)
|
||||
factor *= arg_factor
|
||||
dimension *= arg_dim
|
||||
return factor, dimension
|
||||
elif isinstance(expr, Pow):
|
||||
factor, dim = self._collect_factor_and_dimension(expr.base)
|
||||
exp_factor, exp_dim = self._collect_factor_and_dimension(expr.exp)
|
||||
if self.get_dimension_system().is_dimensionless(exp_dim):
|
||||
exp_dim = 1
|
||||
return factor ** exp_factor, dim ** (exp_factor * exp_dim)
|
||||
elif isinstance(expr, Add):
|
||||
factor, dim = self._collect_factor_and_dimension(expr.args[0])
|
||||
for addend in expr.args[1:]:
|
||||
addend_factor, addend_dim = \
|
||||
self._collect_factor_and_dimension(addend)
|
||||
if not self.get_dimension_system().equivalent_dims(dim, addend_dim):
|
||||
raise ValueError(
|
||||
'Dimension of "{}" is {}, '
|
||||
'but it should be {}'.format(
|
||||
addend, addend_dim, dim))
|
||||
factor += addend_factor
|
||||
return factor, dim
|
||||
elif isinstance(expr, Derivative):
|
||||
factor, dim = self._collect_factor_and_dimension(expr.args[0])
|
||||
for independent, count in expr.variable_count:
|
||||
ifactor, idim = self._collect_factor_and_dimension(independent)
|
||||
factor /= ifactor**count
|
||||
dim /= idim**count
|
||||
return factor, dim
|
||||
elif isinstance(expr, Function):
|
||||
fds = [self._collect_factor_and_dimension(arg) for arg in expr.args]
|
||||
dims = [Dimension(1) if self.get_dimension_system().is_dimensionless(d[1]) else d[1] for d in fds]
|
||||
return (expr.func(*(f[0] for f in fds)), *dims)
|
||||
elif isinstance(expr, Dimension):
|
||||
return S.One, expr
|
||||
else:
|
||||
return expr, Dimension(1)
|
||||
|
||||
def get_units_non_prefixed(self) -> set[Quantity]:
|
||||
"""
|
||||
Return the units of the system that do not have a prefix.
|
||||
"""
|
||||
return set(filter(lambda u: not u.is_prefixed and not u.is_physical_constant, self._units))
|
||||
265
venv/lib/python3.12/site-packages/sympy/physics/units/util.py
Normal file
265
venv/lib/python3.12/site-packages/sympy/physics/units/util.py
Normal file
@@ -0,0 +1,265 @@
|
||||
"""
|
||||
Several methods to simplify expressions involving unit objects.
|
||||
"""
|
||||
from functools import reduce
|
||||
from collections.abc import Iterable
|
||||
from typing import Optional
|
||||
|
||||
from sympy import default_sort_key
|
||||
from sympy.core.add import Add
|
||||
from sympy.core.containers import Tuple
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.core.power import Pow
|
||||
from sympy.core.sorting import ordered
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.core.function import Function
|
||||
from sympy.matrices.exceptions import NonInvertibleMatrixError
|
||||
from sympy.physics.units.dimensions import Dimension, DimensionSystem
|
||||
from sympy.physics.units.prefixes import Prefix
|
||||
from sympy.physics.units.quantities import Quantity
|
||||
from sympy.physics.units.unitsystem import UnitSystem
|
||||
from sympy.utilities.iterables import sift
|
||||
|
||||
|
||||
def _get_conversion_matrix_for_expr(expr, target_units, unit_system):
|
||||
from sympy.matrices.dense import Matrix
|
||||
|
||||
dimension_system = unit_system.get_dimension_system()
|
||||
|
||||
expr_dim = Dimension(unit_system.get_dimensional_expr(expr))
|
||||
dim_dependencies = dimension_system.get_dimensional_dependencies(expr_dim, mark_dimensionless=True)
|
||||
target_dims = [Dimension(unit_system.get_dimensional_expr(x)) for x in target_units]
|
||||
canon_dim_units = [i for x in target_dims for i in dimension_system.get_dimensional_dependencies(x, mark_dimensionless=True)]
|
||||
canon_expr_units = set(dim_dependencies)
|
||||
|
||||
if not canon_expr_units.issubset(set(canon_dim_units)):
|
||||
return None
|
||||
|
||||
seen = set()
|
||||
canon_dim_units = [i for i in canon_dim_units if not (i in seen or seen.add(i))]
|
||||
|
||||
camat = Matrix([[dimension_system.get_dimensional_dependencies(i, mark_dimensionless=True).get(j, 0) for i in target_dims] for j in canon_dim_units])
|
||||
exprmat = Matrix([dim_dependencies.get(k, 0) for k in canon_dim_units])
|
||||
|
||||
try:
|
||||
res_exponents = camat.solve(exprmat)
|
||||
except NonInvertibleMatrixError:
|
||||
return None
|
||||
|
||||
return res_exponents
|
||||
|
||||
|
||||
def convert_to(expr, target_units, unit_system="SI"):
|
||||
"""
|
||||
Convert ``expr`` to the same expression with all of its units and quantities
|
||||
represented as factors of ``target_units``, whenever the dimension is compatible.
|
||||
|
||||
``target_units`` may be a single unit/quantity, or a collection of
|
||||
units/quantities.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.units import speed_of_light, meter, gram, second, day
|
||||
>>> from sympy.physics.units import mile, newton, kilogram, atomic_mass_constant
|
||||
>>> from sympy.physics.units import kilometer, centimeter
|
||||
>>> from sympy.physics.units import gravitational_constant, hbar
|
||||
>>> from sympy.physics.units import convert_to
|
||||
>>> convert_to(mile, kilometer)
|
||||
25146*kilometer/15625
|
||||
>>> convert_to(mile, kilometer).n()
|
||||
1.609344*kilometer
|
||||
>>> convert_to(speed_of_light, meter/second)
|
||||
299792458*meter/second
|
||||
>>> convert_to(day, second)
|
||||
86400*second
|
||||
>>> 3*newton
|
||||
3*newton
|
||||
>>> convert_to(3*newton, kilogram*meter/second**2)
|
||||
3*kilogram*meter/second**2
|
||||
>>> convert_to(atomic_mass_constant, gram)
|
||||
1.660539060e-24*gram
|
||||
|
||||
Conversion to multiple units:
|
||||
|
||||
>>> convert_to(speed_of_light, [meter, second])
|
||||
299792458*meter/second
|
||||
>>> convert_to(3*newton, [centimeter, gram, second])
|
||||
300000*centimeter*gram/second**2
|
||||
|
||||
Conversion to Planck units:
|
||||
|
||||
>>> convert_to(atomic_mass_constant, [gravitational_constant, speed_of_light, hbar]).n()
|
||||
7.62963087839509e-20*hbar**0.5*speed_of_light**0.5/gravitational_constant**0.5
|
||||
|
||||
"""
|
||||
from sympy.physics.units import UnitSystem
|
||||
unit_system = UnitSystem.get_unit_system(unit_system)
|
||||
|
||||
if not isinstance(target_units, (Iterable, Tuple)):
|
||||
target_units = [target_units]
|
||||
|
||||
def handle_Adds(expr):
|
||||
return Add.fromiter(convert_to(i, target_units, unit_system)
|
||||
for i in expr.args)
|
||||
|
||||
if isinstance(expr, Add):
|
||||
return handle_Adds(expr)
|
||||
elif isinstance(expr, Pow) and isinstance(expr.base, Add):
|
||||
return handle_Adds(expr.base) ** expr.exp
|
||||
|
||||
expr = sympify(expr)
|
||||
target_units = sympify(target_units)
|
||||
|
||||
if isinstance(expr, Function):
|
||||
expr = expr.together()
|
||||
|
||||
if not isinstance(expr, Quantity) and expr.has(Quantity):
|
||||
expr = expr.replace(lambda x: isinstance(x, Quantity),
|
||||
lambda x: x.convert_to(target_units, unit_system))
|
||||
|
||||
def get_total_scale_factor(expr):
|
||||
if isinstance(expr, Mul):
|
||||
return reduce(lambda x, y: x * y,
|
||||
[get_total_scale_factor(i) for i in expr.args])
|
||||
elif isinstance(expr, Pow):
|
||||
return get_total_scale_factor(expr.base) ** expr.exp
|
||||
elif isinstance(expr, Quantity):
|
||||
return unit_system.get_quantity_scale_factor(expr)
|
||||
return expr
|
||||
|
||||
depmat = _get_conversion_matrix_for_expr(expr, target_units, unit_system)
|
||||
if depmat is None:
|
||||
return expr
|
||||
|
||||
expr_scale_factor = get_total_scale_factor(expr)
|
||||
return expr_scale_factor * Mul.fromiter(
|
||||
(1/get_total_scale_factor(u)*u)**p for u, p in
|
||||
zip(target_units, depmat))
|
||||
|
||||
|
||||
def quantity_simplify(expr, across_dimensions: bool=False, unit_system=None):
|
||||
"""Return an equivalent expression in which prefixes are replaced
|
||||
with numerical values and all units of a given dimension are the
|
||||
unified in a canonical manner by default. `across_dimensions` allows
|
||||
for units of different dimensions to be simplified together.
|
||||
|
||||
`unit_system` must be specified if `across_dimensions` is True.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.units.util import quantity_simplify
|
||||
>>> from sympy.physics.units.prefixes import kilo
|
||||
>>> from sympy.physics.units import foot, inch, joule, coulomb
|
||||
>>> quantity_simplify(kilo*foot*inch)
|
||||
250*foot**2/3
|
||||
>>> quantity_simplify(foot - 6*inch)
|
||||
foot/2
|
||||
>>> quantity_simplify(5*joule/coulomb, across_dimensions=True, unit_system="SI")
|
||||
5*volt
|
||||
"""
|
||||
|
||||
if expr.is_Atom or not expr.has(Prefix, Quantity):
|
||||
return expr
|
||||
|
||||
# replace all prefixes with numerical values
|
||||
p = expr.atoms(Prefix)
|
||||
expr = expr.xreplace({p: p.scale_factor for p in p})
|
||||
|
||||
# replace all quantities of given dimension with a canonical
|
||||
# quantity, chosen from those in the expression
|
||||
d = sift(expr.atoms(Quantity), lambda i: i.dimension)
|
||||
for k in d:
|
||||
if len(d[k]) == 1:
|
||||
continue
|
||||
v = list(ordered(d[k]))
|
||||
ref = v[0]/v[0].scale_factor
|
||||
expr = expr.xreplace({vi: ref*vi.scale_factor for vi in v[1:]})
|
||||
|
||||
if across_dimensions:
|
||||
# combine quantities of different dimensions into a single
|
||||
# quantity that is equivalent to the original expression
|
||||
|
||||
if unit_system is None:
|
||||
raise ValueError("unit_system must be specified if across_dimensions is True")
|
||||
|
||||
unit_system = UnitSystem.get_unit_system(unit_system)
|
||||
dimension_system: DimensionSystem = unit_system.get_dimension_system()
|
||||
dim_expr = unit_system.get_dimensional_expr(expr)
|
||||
dim_deps = dimension_system.get_dimensional_dependencies(dim_expr, mark_dimensionless=True)
|
||||
|
||||
target_dimension: Optional[Dimension] = None
|
||||
for ds_dim, ds_dim_deps in dimension_system.dimensional_dependencies.items():
|
||||
if ds_dim_deps == dim_deps:
|
||||
target_dimension = ds_dim
|
||||
break
|
||||
|
||||
if target_dimension is None:
|
||||
# if we can't find a target dimension, we can't do anything. unsure how to handle this case.
|
||||
return expr
|
||||
|
||||
target_unit = unit_system.derived_units.get(target_dimension)
|
||||
if target_unit:
|
||||
expr = convert_to(expr, target_unit, unit_system)
|
||||
|
||||
return expr
|
||||
|
||||
|
||||
def check_dimensions(expr, unit_system="SI"):
|
||||
"""Return expr if units in addends have the same
|
||||
base dimensions, else raise a ValueError."""
|
||||
# the case of adding a number to a dimensional quantity
|
||||
# is ignored for the sake of SymPy core routines, so this
|
||||
# function will raise an error now if such an addend is
|
||||
# found.
|
||||
# Also, when doing substitutions, multiplicative constants
|
||||
# might be introduced, so remove those now
|
||||
|
||||
from sympy.physics.units import UnitSystem
|
||||
unit_system = UnitSystem.get_unit_system(unit_system)
|
||||
|
||||
def addDict(dict1, dict2):
|
||||
"""Merge dictionaries by adding values of common keys and
|
||||
removing keys with value of 0."""
|
||||
dict3 = {**dict1, **dict2}
|
||||
for key, value in dict3.items():
|
||||
if key in dict1 and key in dict2:
|
||||
dict3[key] = value + dict1[key]
|
||||
return {key:val for key, val in dict3.items() if val != 0}
|
||||
|
||||
adds = expr.atoms(Add)
|
||||
DIM_OF = unit_system.get_dimension_system().get_dimensional_dependencies
|
||||
for a in adds:
|
||||
deset = set()
|
||||
for ai in a.args:
|
||||
if ai.is_number:
|
||||
deset.add(())
|
||||
continue
|
||||
dims = []
|
||||
skip = False
|
||||
dimdict = {}
|
||||
for i in Mul.make_args(ai):
|
||||
if i.has(Quantity):
|
||||
i = Dimension(unit_system.get_dimensional_expr(i))
|
||||
if i.has(Dimension):
|
||||
dimdict = addDict(dimdict, DIM_OF(i))
|
||||
elif i.free_symbols:
|
||||
skip = True
|
||||
break
|
||||
dims.extend(dimdict.items())
|
||||
if not skip:
|
||||
deset.add(tuple(sorted(dims, key=default_sort_key)))
|
||||
if len(deset) > 1:
|
||||
raise ValueError(
|
||||
"addends have incompatible dimensions: {}".format(deset))
|
||||
|
||||
# clear multiplicative constants on Dimensions which may be
|
||||
# left after substitution
|
||||
reps = {}
|
||||
for m in expr.atoms(Mul):
|
||||
if any(isinstance(i, Dimension) for i in m.args):
|
||||
reps[m] = m.func(*[
|
||||
i for i in m.args if not i.is_number])
|
||||
|
||||
return expr.xreplace(reps)
|
||||
Reference in New Issue
Block a user