123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- """
- 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
|