Пример #1
0
    def test_dimensions_of_expressions(self):
        a = Quantity("a")
        SI.set_quantity_dimension(a, length)

        t = Quantity("t")
        SI.set_quantity_dimension(t, time)

        res = a**2 / t
        # we can now determine the physical dimension of res
        res_dim = SI.get_dimensional_expr(res)
        self.assertTrue(dimsys_SI.equivalent_dims(res_dim, length**2 / time))

        # In parameter dicts we can describe values along with units
        a_val = Quantity("a_val")
        SI.set_quantity_dimension(a_val, length)
        SI.set_quantity_scale_factor(a_val, 5 * meter)

        parameter_dict = {a: 5 * meter, t: 4 * second}

        res_val = res.subs(parameter_dict)
        # we can now determine the physical dimension of res_val
        # and check it against the expected
        print(SI.get_dimensional_expr(res_val))
        self.assertTrue(
            dimsys_SI.equivalent_dims(SI.get_dimensional_expr(res),
                                      SI.get_dimensional_expr(res_val)))
Пример #2
0
def test_prefix_unit():
    length = Dimension("length")
    m = Quantity("meter", length, 1, abbrev="m")

    pref = {"m": PREFIXES["m"], "c": PREFIXES["c"], "d": PREFIXES["d"]}

    res = [Quantity("millimeter", length, PREFIXES["m"], abbrev="mm"),
           Quantity("centimeter", length, PREFIXES["c"], abbrev="cm"),
           Quantity("decimeter", length, PREFIXES["d"], abbrev="dm")]

    prefs = prefix_unit(m, pref)
    assert set(prefs) == set(res)
    assert set(map(lambda x: x.abbrev, prefs)) == set(symbols("mm,cm,dm"))
Пример #3
0
 def replace_unit(unit_list1):
     unit_list2 = []
     for _ in unit_list1:
         if _ == 1:
             _ = Quantity('Uint_one', 1, 1)
         unit_list2.append(_)
     return unit_list2
Пример #4
0
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 don't 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_abbr, prefix in prefixes.items():
        quantity = Quantity("%s%s" % (prefix.name, unit.name),
                            abbrev=("%s%s" % (prefix.abbrev, unit.abbrev)))
        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
Пример #5
0
def test_prefix_operations():
    m = PREFIXES['m']
    k = PREFIXES['k']
    M = PREFIXES['M']

    dodeca = Prefix('dodeca', 'dd', 1, base=12)

    assert m * k == 1
    assert k * k == M
    assert 1 / m == k
    assert k / m == M

    assert dodeca * dodeca == 144
    assert 1 / dodeca == 1 / 12
    assert k / dodeca == 1000 / 12
    assert dodeca / dodeca == 1

    m = Quantity("meter", 1, 6)
    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)
Пример #6
0
    def __new__(cls, name, parents, dct):
        """Build and register new variable."""
        if '__registry__' not in dct:
            unit = dct.pop('unit', S.One)
            if unit == 1:
                unit = S.One
            definition = dct.pop('expr', None)

            dct.setdefault('name', name)
            dct.setdefault('domain', 'real')
            dct.setdefault('latex_name', dct['name'])
            dct.setdefault('unit', unit)

            instance = super(VariableMeta,
                             cls).__new__(cls, name, parents, dct)

            # Variable with definition expression.
            if definition is not None:
                definition = build_instance_expression(instance, definition)
                derived_unit = derive_unit(definition, name=name)

                if unit == S.One:
                    unit = derived_unit  # only if unit is None
                instance.expr, instance.unit = definition, derived_unit

                if unit != instance.unit:
                    raise ValueError(
                        'Invalid expression units {0} should be {1}'.format(
                            instance.unit, unit
                        )
                    )

            expr = BaseVariable(
                instance,
                dct['name'],
                abbrev=dct['latex_name'],
                dimension=Dimension(Quantity.get_dimensional_expr(unit)),
                scale_factor=unit or S.One,
            )
            instance[expr] = instance

            # Store definition as variable expression.
            if definition is not None:
                instance.__expressions__[expr] = definition

            # Store default variable only if it is defined.
            if 'default' in dct:
                instance.__defaults__[expr] = dct['default']

            # Store unit for each variable:
            instance.__units__[expr] = instance.unit

            return expr

        return super(VariableMeta, cls).__new__(cls, name, parents, dct)
Пример #7
0
def test_prefix_operations():
    m = PREFIXES['m']
    k = PREFIXES['k']
    M = PREFIXES['M']

    dodeca = Prefix('dodeca', 'dd', 1, base=12)

    assert m * k == 1
    assert k * k == M
    assert 1 / m == k
    assert k / m == M

    assert dodeca * dodeca == 144
    assert 1 / dodeca == S(1) / 12
    assert k / dodeca == S(1000) / 12
    assert dodeca / dodeca == 1

    m = Quantity("fake_meter")
    m.set_dimension(S.One)
    m.set_scale_factor(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 == (S(1)/3, kilo)

    expr4 = kilo / x
    assert isinstance(expr4, Mul)
    assert (expr4).args == (1/x, kilo)
Пример #8
0
def fea_compile_y(y_unit0, p=True):
    if y_unit0 == 1:
        y_unit0 = Quantity('Uint_one', 1, 1)
    sn = collect_factor_and_dimension(y_unit0)[0] * symbols('y%s' % 1)
    un = collect_factor_and_dimension(y_unit0)[1]
    sn2 = un.get_dimensional_dependencies()
    if 'mass' in sn2:
        sn = sn / (1000**sn2['mass'])
    un = Dim(un)
    sym = symbols('y%s' % 1)
    sym_str = str(sym)
    if p:
        print(sn, sym, un, y_unit0, sym_str)
    else:
        pass
    return sn, sym, un, y_unit0
Пример #9
0
def derive_unit(expr, name=None):
    """Derive SI-unit from an expression, omitting scale factors."""
    from essm.variables import Variable
    from essm.variables.utils import extract_variables
    from sympy.physics.units import Dimension
    from sympy.physics.units.dimensions import dimsys_SI

    variables = extract_variables(expr)
    for var1 in variables:
        q1 = Quantity('q_' + str(var1))
        q1.set_dimension(
            Dimension(Quantity.get_dimensional_expr(var1.definition.unit)))
        q1.set_scale_factor(var1.definition.unit)
        expr = expr.xreplace({var1: q1})
    dim = Dimension(Quantity.get_dimensional_expr(expr))
    return functools.reduce(
        operator.mul,
        (SI_DIMENSIONS[d]**p
         for d, p in dimsys_SI.get_dimensional_dependencies(dim).items()), 1)
Пример #10
0
def test_prefix_operations():
    m = PREFIXES['m']
    k = PREFIXES['k']
    M = PREFIXES['M']

    dodeca = Prefix('dodeca', 'dd', 1, base=12)

    assert m * k == 1
    assert k * k == M
    assert 1 / m == k
    assert k / m == M

    assert dodeca * dodeca == 144
    assert 1 / dodeca == 1 / 12
    assert k / dodeca == 1000 / 12
    assert dodeca / dodeca == 1

    m = Quantity("meter", 1, 6)
    assert dodeca / m == 12 / m
Пример #11
0
def scale(base, kind, prefixes="", multiplier=1):
    """
    Define a scale of similar quantities.
    """
    base, abbrev = base.split('/')

    res = []
    for prefix in ['', *prefixes]:
        q = Quantity(_names[prefix] + base, abbrev=abbrev)
        q.set_dimension(kind[0])
        q.set_scale_factor(multiplier * _factor[prefix] * kind[1])
        res.append(q)

    return res if prefixes else res[0]
Пример #12
0
def test_prefix_operations():
    m = PREFIXES["m"]
    k = PREFIXES["k"]
    M = PREFIXES["M"]

    dodeca = Prefix("dodeca", "dd", 1, base=12)

    assert m * k == 1
    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 == 1

    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)
Пример #13
0
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 set(map(lambda v: v.abbrev, prefs)) == set(symbols("mm,cm,dm"))
Пример #14
0
 def get_dimensional_expr(expr):
     """Return dimensions of expression."""
     if isinstance(expr, Mul):
         return Mul(*[Variable.get_dimensional_expr(i) for i in expr.args])
     elif isinstance(expr, Pow):
         return Variable.get_dimensional_expr(expr.base) ** expr.exp
     elif isinstance(expr, Add):
         return Variable.get_dimensional_expr(expr.args[0])
     elif isinstance(expr, Derivative):
         dim = Variable.get_dimensional_expr(expr.expr)
         for independent, count in expr.variable_count:
             dim /= Variable.get_dimensional_expr(independent)**count
         return dim
     elif isinstance(expr, Function):
         args = [Variable.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 expr.dimension.name
     elif isinstance(expr, BaseVariable):
         return Quantity.get_dimensional_expr(expr.definition.unit)
     return S.One
Пример #15
0
def derive_baseunit(expr, name=None):
    """Derive SI base unit from an expression, omitting scale factors."""
    from essm.variables import Variable
    from essm.variables.utils import extract_variables
    from sympy.physics.units import Dimension
    from sympy.physics.units.systems.si import dimsys_SI

    Variable.check_unit(expr)  # check for dimensional consistency
    variables = extract_variables(expr)
    for var1 in variables:
        q1 = Quantity('q_' + str(var1))
        SI.set_quantity_dimension(
            q1,
            Dimension(
                SI.get_dimensional_expr(derive_baseunit(
                    var1.definition.unit))))
        SI.set_quantity_scale_factor(q1, var1.definition.unit)
        expr = expr.xreplace({var1: q1})
    dim = Dimension(Variable.get_dimensional_expr(expr))
    return functools.reduce(
        operator.mul,
        (SI_BASE_DIMENSIONS[Symbol(d)]**p
         for d, p in dimsys_SI.get_dimensional_dependencies(dim).items()), 1)
Пример #16
0
def test_prefix_operations():
    m = PREFIXES['m']
    k = PREFIXES['k']
    M = PREFIXES['M']

    dodeca = Prefix('dodeca', 'dd', 1, base=12)

    assert m * k == 1
    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 == 1

    m = Quantity("fake_meter")
    m.set_dimension(S.One)
    m.set_scale_factor(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)
Пример #17
0
from sympy import Rational, pi, sqrt
from sympy.physics.units import Quantity
from sympy.physics.units.dimensions import (
    acceleration, action, amount_of_substance, capacitance, charge,
    conductance, current, energy, force, frequency, information, impedance,
    inductance, length, luminous_intensity, magnetic_density, magnetic_flux,
    mass, power, pressure, temperature, time, velocity, voltage)
from sympy.physics.units.prefixes import (centi, deci, kilo, micro, milli,
                                          nano, pico, kibi, mebi, gibi, tebi,
                                          pebi, exbi)

#### UNITS ####

# Dimensionless:

percent = percents = Quantity("percent", 1, Rational(1, 100))
permille = Quantity("permille", 1, Rational(1, 1000))

# Angular units (dimensionless)

rad = radian = radians = Quantity("radian", 1, 1)
deg = degree = degrees = Quantity("degree", 1, pi / 180, abbrev="deg")
sr = steradian = steradians = Quantity("steradian", 1, 1, abbrev="sr")
mil = angular_mil = angular_mils = Quantity("angular_mil",
                                            1,
                                            2 * pi / 6400,
                                            abbrev="mil")

# Base units:

m = meter = meters = Quantity("meter", length, 1, abbrev="m")
Пример #18
0
def test_prefix_unit():
    m = Quantity("fake_meter", abbrev="m")
    m.set_dimension(length)
    m.set_scale_factor(1)

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

    q1.set_dimension(length)
    q1.set_dimension(length)
    q1.set_dimension(length)

    q1.set_scale_factor(PREFIXES["m"])
    q1.set_scale_factor(PREFIXES["c"])
    q1.set_scale_factor(PREFIXES["d"])

    res = [q1, q2, q3]

    prefs = prefix_unit(m, pref)
    assert set(prefs) == set(res)
    assert set(map(lambda x: x.abbrev, prefs)) == set(symbols("mm,cm,dm"))
Пример #19
0
from sympy import symbols, solve, Eq, pretty_print
from sympy.physics.units import Quantity, mass, acceleration, power, velocity
from sympy.physics.units import convert_to
from sympy.physics.units import kilo
from sympy.physics.units import km, hour, m, s, kg, W
from sympy.physics.units.systems import SI

a = symbols("a")
m_ = Quantity("m")
v = Quantity("v")
W_ = Quantity("W")

SI.set_quantity_dimension(a, acceleration)

SI.set_quantity_dimension(m_, mass)
SI.set_quantity_scale_factor(m_, 1000*kg)

SI.set_quantity_dimension(v, velocity)
SI.set_quantity_scale_factor(v, 60*km/hour)

SI.set_quantity_dimension(W_, power)
SI.set_quantity_scale_factor(W_, 120*kilo*W)

eq = Eq(W_, m_*a*v)
result = solve(eq, a)[0]
pretty_print(result)

pretty_print(convert_to(result, m / s ** 2).n())


Пример #20
0
def derive_quantity(expr, name=None):
    """Derive a quantity from an expression."""
    factor, dimension = Quantity._collect_factor_and_dimension(expr)
    return Quantity(name or str(expr), dimension, factor)
Пример #21
0
import sympy.physics.units as un
from sympy import symbols, Eq, pretty_print
from sympy.interactive import init_printing
from sympy.physics.units import Quantity
from sympy.physics.units import convert_to
from utils import *

init_printing()

E = Quantity("E")
c = Quantity("c")

set_quantity(E, un.energy, 2.15e12 * un.kilo * un.watts * un.hour)
set_quantity(c, un.speed, 3.00e8 * un.m / un.s)
E = convert_to(E, un.joule).n()

print('Heavy water:')
pretty_print(Eq(symbols('D2O'), 2 * symbols('D') + symbols('O')))

print('Let nucleosynthesis reaction be like below:')
pretty_print(Eq(symbols('D'), symbols('H_^2')))
pretty_print(Eq(symbols('H^2') + symbols('H^2'), symbols('He_^4')))

print('a).')
m = symbols('m')
pretty_print(Eq(m, symbols('E') / c**2))
m = E / c**2
m = convert_to(m, un.kg).n()

pretty_print("Energy to mass  : {}".format(m))
Пример #22
0
import sympy.physics.units as un
from sympy import symbols, solve, Eq, pretty_print
from sympy.physics.units import Quantity
from sympy.physics.units import convert_to
from sympy.physics.units import length, acceleration, mass
from sympy.physics.units.definitions.unit_definitions import One
from sympy.physics.units.systems import SI
from sympy.interactive import init_printing

init_printing()

Wo = symbols("Wo")
v = symbols("v")

rho = Quantity("rho")
s = Quantity("s")
g = Quantity("g")
h1 = Quantity("h1")
h2 = Quantity("h2")
etha = Quantity("etha")
theta = Quantity("theta")

SI.set_quantity_dimension(rho, mass / length**3)
SI.set_quantity_scale_factor(rho, 1.0 * un.grams / un.cm**3)

SI.set_quantity_dimension(s, length**2)
SI.set_quantity_scale_factor(s, 35.0 * un.cm**2)

SI.set_quantity_dimension(h1, length)
SI.set_quantity_scale_factor(h1, 2.4 * un.meters)
Пример #23
0
"""This module provides the Units class for simplification of units.
It should be rolled into SymPy.  It can perform simplification of
units, e.g., volts / amperes -> ohms.

Copyright 2020--2021 Michael Hayes, UCECE

"""

import sympy.physics.units as u
from sympy.physics.units.systems.si import dimsys_SI
from sympy.physics.units.systems import SI
from sympy.physics.units import UnitSystem, Quantity
from sympy import S

dB = Quantity('dB', 'dB')


class Units(object):
    def __init__(self, unit_system="SI"):

        self.unit_system = UnitSystem.get_unit_system(unit_system)
        self.dim_sys = self.unit_system.get_dimension_system()
        self._mapping = {}

        for i in u.__dict__:
            unit = getattr(u, i)
            if not isinstance(unit, u.Quantity):
                continue

            key = self._makekey(unit)
Пример #24
0
import sympy.physics.units as u
from sympy.physics.units import Dimension, Quantity, find_unit
from sympy.physics.units.systems import SI

joule = u.joule
kelvin = u.kelvin
kilogram = u.kilogram
meter = u.meter
mole = u.mole
pascal = u.pascal
second = u.second
watt = u.watt

SI_DIMENSIONS = {
    str(Quantity.get_dimensional_expr(d)): d
    for d in SI._base_units
}


def markdown(unit):
    """Return markdown representation of a unit."""
    from sympy.printing import StrPrinter
    from operator import itemgetter
    # displays short units (m instead of meter)
    StrPrinter._print_Quantity = lambda self, expr: str(expr.abbrev)
    if unit.is_Pow:
        item = unit.args
        return '{0}$^{{{1}}}$'.format(item[0], item[1])
    if unit.is_Mul:
        str1 = ''
Пример #25
0
    def test_numerification(self):
        # apply a function defined with units

        def v_unit(t):
            # Note:
            # At the moment t has to be a scalar
            cond_1 = simplify(t) == 0
            cond_2 = dimsys_SI.equivalent_dims(SI.get_dimensional_expr(t),
                                               time)
            assert cond_1 | cond_2
            omega = 2 * pi / second
            # phi = 0
            phi = pi / 8
            V_0 = 20 * meter / second
            V_range = 5 * meter / second
            return V_0 + V_range * sin(omega * t + phi)

        # Note

        ts = [second * t for t in np.linspace(0, float(2 * pi), 100)]
        ysf = [v_unit(t) for t in ts]

        fig = plt.figure()
        ax = fig.add_subplot(1, 1, 1)
        auto_plot_with_units(ax, ts, ysf)
        fig.savefig("example3_auto.pdf")
        t = Quantity("t")
        SI.set_quantity_dimension(t, time)

        # We can transform Expressions to numerical functions
        # This also works for Expressions of Quanteties and functions that
        # contain units

        v = Function("v")
        m = Quantity("m")
        # create an expression containing a function
        E = m / 2 * v(t)**2

        # print(v_unit(3*day))

        # substitute paramters
        E_parUnit = E.subs({m: 5 * kilogram})

        # lambify the expression to a function
        tup = (t, )
        E_funcUnit = lambdify(tup, E_parUnit, {"v": v_unit})

        # ysE = [E_funcUnit(t) for t in ts]
        #
        # fig = plt.figure()
        # ax = fig.add_subplot(1, 1, 1)
        # auto_plot_with_units(ax, ts, ysE)
        # fig.savefig("example4_auto.pdf")

        # ####################################################################################################
        #
        # Exampe 5
        # Here we assume that parameters, arguments and return values of functions
        # have units attached.
        # This is natural from sympys perspective and allows computations involving
        # quanteties ( numbers with units ) to be completely transparent.
        # E.g. a function or expression receiving a
        # length argument  will always compute the correct result since the argument
        # carries its unit with it. Also the result can be expressed in any unit
        # compatible with its dimension.
        #
        # However numerical computations in scipy like solving an ode require numbers
        # or functions that consume and return numbers (as opposed to quanteties)
        # To perform those computations we temporarily have to remove units from the
        # arguments before the computation and attach units to the results.
        # We can automatically convert 'numerify' a function working on quanteties
        # (f_quant) to  a function on number (f_num) if we choose the units for
        # arguments and return values.
        # The resulting purely numerical function f_num represents
        # f_quant faithfully for those units and for those units only.
        # This has several consequences:
        # - Along with f_num the untis of the arguments and the return value have to
        #   be remembered externally since they are no intrinsic part of f_num.
        # - The numerical representations of different functions and paramters
        #   should be consistent. E.g in f_quant(g_quant(x_qunat)) x_qant,f_quant
        #   and g_quant should be "numerified" making sure that x_num represents
        #   the original quantity with respect to the unit that f_num expects and
        #   that f_num returns its result w.r.t. the unit g_num expects...
        #   This is possible with the help of the unit system.
        # - Unfortunately the "numerification" of functions is computationally
        #   expensive as the numeric function f_num everytime it is called it will
        #   attach units call f_quant and remove units from the result.

        def numerify(f_quant, *units):
            def f_num(*num_args):
                target_unit = units[-1]
                u_args = tuple(num_arg * units[ind]
                               for ind, num_arg in enumerate(num_args))
                res_quant = f_quant(*u_args)
                # res_quant_target_unit = convert_to(res_quant, target_unit)
                # res_num = factor(res_quant_target_unit, target_unit)/target_unit
                res_num = simplify(res_quant / target_unit)
                return float(res_num)

            return f_num

        C_0 = describedQuantity("C_0", mass, "")
        C_1 = describedQuantity("C_1", mass, "")
        t = describedQuantity("t", time, "")
        k_01 = describedQuantity("k_01", 1 / time, "")
        k_10 = describedQuantity("k_10", 1 / time, "")
        k_0o = describedQuantity("k_0o", 1 / time, "")

        k_1o = Function("k_1o")

        state_variables = [C_0, C_1]  # order is important
        inputs = {
            0: sin(t) + 2,
            1: cos(t) + 2
        }  # input to pool 0  # input to pool 1
        outputs = {
            0: k_0o * C_0**3,  # output from pool 0
            1: k_1o(t) * C_1**3,  # output from pool 0
        }
        internal_fluxes = {
            (0, 1): k_01 * C_0 * C_1**2,  # flux from pool 0  to pool 1
            (1, 0): k_10 * C_0 * C_1,  # flux from pool 1 to pool 0
        }
        time_symbol = t
        srm = SmoothReservoirModel(state_variables, time_symbol, inputs,
                                   outputs, internal_fluxes)

        par_dict_quant = {
            k_01: 1 / 100 * 1 / day,
            k_10: 1 / 100 * 1 / day,
            k_0o: 1 / 2 * 1 / day,
        }

        def k_1o_func_quant(t):
            omega = 2 * pi / day
            phi = pi / 8
            V_0 = 20 * kilogram / day
            V_range = 5 * kilogram / day
            u_res = V_0 + V_range * sin(omega * t + phi)
            return u_res

        times_quant = np.linspace(0, 20, 16) * year
        start_values_quant = np.array([1 * gram, 2 * kilogram])

        # Note that the time units of the parameters the function and the time array
        # are different.  Also note that the components of the startvalue tuple are
        # given with respect to two different units (gigagram and kilogram)  and the
        # k_1o_func_quant uses kilogram/second as the unit for the return value.
        #
        # The different units are handled correctly by sympy, becuase the same quantety
        # can be represented with respect to differnt units (1*day=24*hour)
        #
        # If we convert ot purely numerical values and functions, we have to consider
        # the consistency of the whole ensemble The easiest way to achieve this is to
        # normalize all times to an arbitrary but common unit of time (e.g. year), and
        # all masses to an arbitrary unit of mass (e.g. kilogram)

        # create a numerical function expecting its argument to be a number measuring
        # years and returning a number to be interpreted as kilogram/year
        k_1o_func_num = numerify(k_1o_func_quant, year, kilogram / year)

        # create a par_dict of numbers (since all parameter in the dictionary are rates
        # we can deal with the whole dict at once
        par_dict_num = {
            k: to_number(v, 1 / year)
            for k, v in par_dict_quant.items()
        }

        # extract the times in years
        times_num = np.array([to_number(t, year) for t in times_quant])

        # crete numerical start values
        start_values_num = np.array(
            [to_number(v, kilogram) for v in start_values_quant])
        n_smr = SmoothModelRun(
            srm,
            par_dict_num,
            start_values_num,
            times_num,
            func_set={k_1o: k_1o_func_num},
        )
        before = tm.time()
        sol_num = n_smr.solve()  # extremely slow
        after = tm.time()
        print(before - after)

        def k_1o_func_num_manual(t):
            omega = 2 * pi
            phi = pi / 8
            V_0 = 20
            V_range = 5
            u_res = V_0 + V_range * sin(omega * t + phi)
            return u_res

        n_smr = SmoothModelRun(
            srm,
            par_dict_num,
            start_values_num,
            times_num,
            func_set={k_1o: k_1o_func_num_manual},
        )
        before = tm.time()
        sol_num = n_smr.solve()
        after = tm.time()
        print(before - after)
Пример #26
0
def test_prefix_unit():
    m = Quantity("fake_meter", abbrev="m")
    m.set_dimension(length)
    m.set_scale_factor(1)

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

    q1.set_dimension(length)
    q1.set_dimension(length)
    q1.set_dimension(length)

    q1.set_scale_factor(PREFIXES["m"])
    q1.set_scale_factor(PREFIXES["c"])
    q1.set_scale_factor(PREFIXES["d"])

    res = [q1, q2, q3]

    prefs = prefix_unit(m, pref)
    assert set(prefs) == set(res)
    assert set(map(lambda x: x.abbrev, prefs)) == set(symbols("mm,cm,dm"))
Пример #27
0
def dimension(expr: sympy.Expr) -> Dimension:
    return Quantity._collect_factor_and_dimension(expr)[1]
Пример #28
0
import operator as op

from lark import Lark, InlineTransformer
from sympy import S
from sympy.physics import units
from sympy.physics.units import Quantity
from sympy.physics.units.dimensions import dimsys_SI

from sidekick import namespace

DIMENSIONLESS = Quantity("dimensionless")
DIMENSIONLESS.set_dimension(S.One)
DIMENSIONLESS.set_scale_factor(S.One)
SIMPY_UNITS = {k: v for k, v in vars(units).items() if not k.startswith('_')}
UNITS = namespace(**SIMPY_UNITS, )

grammar = Lark(r"""
?start : expr
       | NUMBER           -> dimensionless
        
?expr  : expr "*" atom    -> mul
       | expr atom        -> mul
       | expr "/" atom    -> div
       | atom
     
?atom  : name "^" number  -> pow
       | name number      -> pow
       | name
       
name   : NAME 
number : NUMBER 
Пример #29
0
import numpy as np
import sympy.physics.units as un
from sympy.physics.units import Quantity
from utils import *
from sympy.physics.units import convert_to
from sympy import *

init_printing()

# Polar Earth radius
R_P_km = 6356.912
R_P = get_quantity(Quantity("R_P"), un.length, R_P_km * un.km)

# Equatorial Earth radius
R_E_km = 6378.388
R_E = get_quantity(Quantity("R_E"), un.length, R_E_km * un.km)

# Average Earth radius
R_km = (6356.912 + 6378.388) / 2
R = get_quantity(Quantity("R"), un.length, R_km * un.km)

# RD - is a table with raw data
# Where:
#    RD[0] - distances from the surface of the Earth, km
#    RD[1] - densities at depth from above row, g/cm^3
#    RD[2] - densities at 'breach', if value is 0, then no 'breach'
# //@formatter:off
RD = [
    [0.0, 30.0, 100.0, 200.0, 400.0, 1000.0, 2000.0, 2900.0, 3500.0, 5000.0, 6000.0],
    [2.6,  3.0,   3.4,   3.5,   3.6,    4.7,    5.2,    5.7,   10.2,   11.5,   17.0],
    [0.0,  3.3,   0.0,   0.0,   0.0,    0.0,    0.0,    9.4,    0.0,   16.8,    0.0]
Пример #30
0
def describedQuantity(name, dimension, description):
    obj = Quantity(name=name)
    SI.set_quantity_dimension(obj, dimension)
    obj.description = description
    # obj = Symbol(name)
    return obj
Пример #31
0
def si_dimension_scale(expr: sympy.Expr) -> Dimension:
    return Quantity._collect_factor_and_dimension(expr)[0]
Пример #32
0
import sympy.physics.units as un
from sympy import symbols, solve, Eq, pretty_print
from sympy.functions import *
from sympy.interactive import init_printing
from sympy.physics.units import Quantity
from sympy.physics.units import convert_to
from utils import *

init_printing()

hp_to_watts = 745.7

W0 = Quantity("W0")
W = Quantity("W")
m = Quantity("m")
v = Quantity("v")
g = Quantity("g")
theta = symbols("theta")

set_quantity(W0, un.power, 85 * hp_to_watts * un.watts)
set_quantity(W, un.power, 20 * hp_to_watts * un.watts)
set_quantity(m, un.mass, 1200 * un.kg)
set_quantity(v, un.velocity, 48 * un.km / un.hour)
set_quantity(g, un.acceleration, 9.81 * un.m / un.s**2)

eq = Eq(sin(theta), (W0 - W) / (m * g * v))
pretty_print(eq)

theta = solve(eq, theta)[1]

theta = convert_to(theta, un.watts).n()