Generateurv2/backend/env/lib/python3.10/site-packages/sympy/physics/units/quantities.py
2022-06-24 17:14:37 +02:00

212 lines
7.2 KiB
Python

"""
Physical quantities.
"""
from sympy import AtomicExpr, Symbol, sympify
from sympy.physics.units.dimensions import _QuantityMapper
from sympy.physics.units.prefixes import Prefix
from sympy.utilities.exceptions import SymPyDeprecationWarning
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
_diff_wrt = True
def __new__(cls, name, abbrev=None, dimension=None, scale_factor=None,
latex_repr=None, pretty_unicode_repr=None,
pretty_ascii_repr=None, mathml_presentation_repr=None,
**assumptions):
if not isinstance(name, Symbol):
name = Symbol(name)
# For Quantity(name, dim, scale, abbrev) to work like in the
# old version of Sympy:
if not isinstance(abbrev, str) and not \
isinstance(abbrev, Symbol):
dimension, scale_factor, abbrev = abbrev, dimension, scale_factor
if dimension is not None:
SymPyDeprecationWarning(
deprecated_since_version="1.3",
issue=14319,
feature="Quantity arguments",
useinstead="unit_system.set_quantity_dimension_map",
).warn()
if scale_factor is not None:
SymPyDeprecationWarning(
deprecated_since_version="1.3",
issue=14319,
feature="Quantity arguments",
useinstead="SI_quantity_scale_factors",
).warn()
if abbrev is None:
abbrev = name
elif isinstance(abbrev, str):
abbrev = Symbol(abbrev)
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
if dimension is not None:
# TODO: remove after deprecation:
obj.set_dimension(dimension)
if scale_factor is not None:
# TODO: remove after deprecation:
obj.set_scale_factor(scale_factor)
return obj
def set_dimension(self, dimension, unit_system="SI"):
SymPyDeprecationWarning(
deprecated_since_version="1.5",
issue=17765,
feature="Moving method to UnitSystem class",
useinstead="unit_system.set_quantity_dimension or {}.set_global_relative_scale_factor".format(self),
).warn()
from sympy.physics.units import UnitSystem
unit_system = UnitSystem.get_unit_system(unit_system)
unit_system.set_quantity_dimension(self, dimension)
def set_scale_factor(self, scale_factor, unit_system="SI"):
SymPyDeprecationWarning(
deprecated_since_version="1.5",
issue=17765,
feature="Moving method to UnitSystem class",
useinstead="unit_system.set_quantity_scale_factor or {}.set_global_relative_scale_factor".format(self),
).warn()
from sympy.physics.units import UnitSystem
unit_system = UnitSystem.get_unit_system(unit_system)
unit_system.set_quantity_scale_factor(self, scale_factor)
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)
# 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
@staticmethod
def get_dimensional_expr(expr, unit_system="SI"):
SymPyDeprecationWarning(
deprecated_since_version="1.5",
issue=17765,
feature="get_dimensional_expr() is now associated with UnitSystem objects. " \
"The dimensional relations depend on the unit system used.",
useinstead="unit_system.get_dimensional_expr"
).warn()
from sympy.physics.units import UnitSystem
unit_system = UnitSystem.get_unit_system(unit_system)
return unit_system.get_dimensional_expr(expr)
@staticmethod
def _collect_factor_and_dimension(expr, unit_system="SI"):
"""Return tuple with scale factor expression and dimension expression."""
SymPyDeprecationWarning(
deprecated_since_version="1.5",
issue=17765,
feature="This method has been moved to the UnitSystem class.",
useinstead="unit_system._collect_factor_and_dimension",
).warn()
from sympy.physics.units import UnitSystem
unit_system = UnitSystem.get_unit_system(unit_system)
return unit_system._collect_factor_and_dimension(expr)
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()