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)))
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"))
def replace_unit(unit_list1): unit_list2 = [] for _ in unit_list1: if _ == 1: _ = Quantity('Uint_one', 1, 1) unit_list2.append(_) return unit_list2
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
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)
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)
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)
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
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)
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
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]
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)
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"))
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
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)
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)
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")
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"))
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())
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)
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))
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)
"""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)
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 = ''
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)
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"))
def dimension(expr: sympy.Expr) -> Dimension: return Quantity._collect_factor_and_dimension(expr)[1]
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
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]
def describedQuantity(name, dimension, description): obj = Quantity(name=name) SI.set_quantity_dimension(obj, dimension) obj.description = description # obj = Symbol(name) return obj
def si_dimension_scale(expr: sympy.Expr) -> Dimension: return Quantity._collect_factor_and_dimension(expr)[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()