Example #1
0
def set_quantity(quantity, dimension, scale_factor):
    """
    Set value and unit to physical quantity.
    Example:

        >>> import sympy.physics.units as un
        >>> from sympy.functions import *
        >>> from sympy.physics.units import Quantity
        >>> from utils import *
        >>> from sympy.physics.units import convert_to
        >>>
        >>> 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()
        >>> m = E/c**2
        7.74e+18*joule/c**2

        convert_to(m, un.kg).n()
        86.0*kilogram

    :param quantity: physical quantity, for example length, mass or energy
    :param dimension: time, length, mass ... based on sympy.physics.units
    :param scale_factor: value to be set to `quantity` parameter
    """
    SI.set_quantity_dimension(quantity, dimension)
    SI.set_quantity_scale_factor(quantity, scale_factor)
Example #2
0
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
Example #3
0
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))
Example #4
0
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)
Example #5
0
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))
Example #6
0
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)
Example #7
0
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)

    with warns_deprecated_sympy():
        assert (3000,
                Dimension(1)) == Quantity._collect_factor_and_dimension(3000)
Example #8
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)
Example #9
0
 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)
Example #10
0
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))

    with warns_deprecated_sympy():
        Dq1 = Dimension(Quantity.get_dimensional_expr(expr))
        assert Dq == Dq1

    assert SI.get_dimension_system().get_dimensional_dependencies(Dq) == {
        'length': 1,
        'time': -1,
    }
    assert meter == sqrt(meter**2)
Example #11
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"))
Example #12
0
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,
    }
Example #13
0
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,
    }
Example #14
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)))
Example #15
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)
Example #16
0
 def check_unit_consistency(expr):
     SI._collect_factor_and_dimension(expr)
Example #17
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())


Example #18
0
# real=True, positive=True)
th_0p95: Symbol = Symbol(r"t^{\rightarrow{0.95}}", real=True, negative=False)
h_0p95: Symbol = Symbol(r"h_{0.95}", real=True, negative=False)
th_0p9: Symbol = Symbol(r"t^{\rightarrow{0.9}}", real=True, negative=False)
# h_0p9: Symbol = Symbol(r"h_{0.9}", real=True, negative=False)
t_oneyear: Symbol = Symbol(r"t_{\mathrm{1y}}", real=True, positive=True)
t_My: Symbol = Symbol(r"t_{\mathrm{My}}", real=True, positive=True)
that: Symbol = Symbol(r"\hat{t}", real=True, negative=False)
tv_0: Symbol = Symbol(r"t^{\downarrow_{0}}", real=True, positive=True)
th_0: Symbol = Symbol(r"t^{\rightarrow_{0}}", real=True, positive=True)

beta: Symbol = Symbol(r"\beta", real=True)
beta_: Symbol = Symbol(r"\beta_x", real=True)
beta_crit: Symbol = Symbol(r"\beta_c", real=True)
beta_0: Symbol = Symbol(r"\beta_0", real=True, positive=True)
SI.set_quantity_dimension(beta_0, 1)
betaplus: Symbol = Symbol(r"\beta^+", real=True, positive=True)
alpha: Symbol = Symbol(r"\alpha", real=True)
alpha_ext: Symbol = Symbol(r"\alpha_\mathrm{ext}", real=True)
alphaplus: Symbol = Symbol(r"\alpha^+", real=True, positive=True)
alpha_extremum: Symbol = Symbol(r"\alpha_\text{extremum}")
beta_at_alpha_extremum: Symbol = Symbol(r"\beta_{\text{extremum}\{\alpha\}}")
phi: Symbol = Symbol(r"\phi", real=True)
psi: Symbol = Symbol(r"\psi", real=True)

rvec: Symbol = Symbol(r"\mathbf{r}", real=True)
r: Symbol = Symbol(r"r", real=True, negative=False)
rx: Symbol = Symbol(r"{r}^x", real=True, negative=False)
rz: Symbol = Symbol(r"{r}^z", real=True)
rvechat: Symbol = Symbol(r"\mathbf{\hat{r}}", real=True)
rhat: Symbol = Symbol(r"\hat{r}", real=True, negative=False)
Example #19
0
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)

SI.set_quantity_dimension(h2, length)
SI.set_quantity_scale_factor(h2, 4.8 * un.meters)

SI.set_quantity_dimension(g, acceleration)
SI.set_quantity_scale_factor(g, 9.81 * un.m / un.s**2)

SI.set_quantity_dimension(etha, One)
Example #20
0
def describedQuantity(name, dimension, description):
    obj = Quantity(name=name)
    SI.set_quantity_dimension(obj, dimension)
    obj.description = description
    # obj = Symbol(name)
    return obj