Example #1
0
def test_get_odesys_3():
    M = u.molar
    s = u.second
    mol = u.mol
    m = u.metre
    substances = list(map(Substance, 'H2O H+ OH-'.split()))
    dissociation = Reaction({'H2O': 1}, {'H+': 1, 'OH-': 1}, 2.47e-5/s)
    recombination = Reaction({'H+': 1, 'OH-': 1}, {'H2O': 1}, 1.37e11/M/s)
    rsys = ReactionSystem([dissociation, recombination], substances)
    odesys = get_odesys(
        rsys, include_params=True, unit_registry=SI_base_registry,
        output_conc_unit=M)[0]
    c0 = {'H2O': 55.4*M, 'H+': 1e-7*M, 'OH-': 1e-4*mol/m**3}
    x, y, p = odesys.to_arrays(-42*u.second,
                               rsys.as_per_substance_array(c0, unit=M), ())
    fout = odesys.f_cb(x, y, p)

    time_unit = get_derived_unit(SI_base_registry, 'time')
    conc_unit = get_derived_unit(SI_base_registry, 'concentration')

    r1 = to_unitless(55.4*2.47e-5*M/s, conc_unit/time_unit)
    r2 = to_unitless(1e-14*1.37e11*M/s, conc_unit/time_unit)
    assert np.all(abs(fout[:, 0] - r2 + r1)) < 1e-10
    assert np.all(abs(fout[:, 1] - r1 + r2)) < 1e-10
    assert np.all(abs(fout[:, 2] - r1 + r2)) < 1e-10
Example #2
0
    def render_setup(self, *, ics, atol, tex=True, tspan=None):
        export = ""
        export += "p = %s\n" % jl_dict(self.pars)
        export += "ics = %s\n" % jl_dict(
            OrderedDict({
                self.substance_key_map[k]: v
                for k, v in to_unitless(ics, u.molar).items()
            }))
        if atol:
            export += "abstol_d = %s\n" % jl_dict({
                self.substance_key_map[k]: v
                for k, v in to_unitless(atol, u.molar).items()
            })
            export += "abstol = Array([get(abstol_d, k, 1e-10) for k=keys(speciesmap(rn))])"
        if tex:
            export += "subst_tex = Dict([%s])\n" % ", ".join(
                '(:%s, ("%s", "%s"))' % (v, k, self.latex_names[k])
                for k, v in self.substance_key_map.items())
        if tspan:
            export += """\
tspan = (0., %12.5g)
u0 = Array([get(ics, k, 1e-28) for k=keys(speciesmap(rn))])
parr = Array([p[k] for k=keys(paramsmap(rn))])
oprob = ODEProblem(rn, u0, tspan, parr)
"""
        return export
Example #3
0
 def check(rsys):
     odesys, extra = get_odesys(rsys, unit_registry=SI_base_registry, constants=const)
     res = odesys.integrate(t, init_cond, params, integrator='cvode')
     NOBr_ref = NOBr0_M*np.exp(-kref*to_unitless(res.xout, u.second))
     ref = np.array([NOBr_ref] + [NOBr0_M - NOBr_ref]*2).T
     cmp = to_unitless(res.yout, u.M)
     assert np.allclose(cmp, ref)
Example #4
0
 def check(rsys):
     odesys, extra = get_odesys(rsys, unit_registry=SI_base_registry, constants=const)
     res = odesys.integrate(t, init_cond, params, integrator='cvode')
     NOBr_ref = NOBr0_M*np.exp(-kref*to_unitless(res.xout, u.second))
     ref = np.array([NOBr_ref] + [NOBr0_M - NOBr_ref]*2).T
     cmp = to_unitless(res.yout, u.M)
     assert np.allclose(cmp, ref)
Example #5
0
def test_get_odesys_3():
    M = u.molar
    s = u.second
    mol = u.mol
    m = u.metre
    substances = list(map(Substance, 'H2O H+ OH-'.split()))
    dissociation = Reaction({'H2O': 1}, {'H+': 1, 'OH-': 1}, 2.47e-5/s)
    recombination = Reaction({'H+': 1, 'OH-': 1}, {'H2O': 1}, 1.37e11/M/s)
    rsys = ReactionSystem([dissociation, recombination], substances)
    odesys = get_odesys(
        rsys, include_params=True, unit_registry=SI_base_registry,
        output_conc_unit=M)[0]
    c0 = {'H2O': 55.4*M, 'H+': 1e-7*M, 'OH-': 1e-4*mol/m**3}
    x, y, p = odesys.pre_process(-42*u.second,
                                 rsys.as_per_substance_array(c0, unit=M))
    fout = odesys.f_cb(x, y, p)

    time_unit = get_derived_unit(SI_base_registry, 'time')
    conc_unit = get_derived_unit(SI_base_registry, 'concentration')

    r1 = to_unitless(55.4*2.47e-5*M/s, conc_unit/time_unit)
    r2 = to_unitless(1e-14*1.37e11*M/s, conc_unit/time_unit)
    assert abs(fout[0] - r2 + r1) < 1e-10
    assert abs(fout[1] - r1 + r2) < 1e-10
    assert abs(fout[2] - r1 + r2) < 1e-10
Example #6
0
 def check(rsys):
     odesys, extra = get_odesys(rsys, unit_registry=SI_base_registry, constants=const)
     res = odesys.integrate(t, init_cond, params, integrator='cvode')
     t_sec = to_unitless(res.xout, u.second)
     NOBr_ref = analytic_b(t_sec)
     cmp = to_unitless(res.yout, u.M)
     ref = np.empty_like(cmp)
     ref[:, odesys.names.index('NOBr')] = NOBr_ref
     ref[:, odesys.names.index('Br')] = Br0_M - NOBr_ref
     ref[:, odesys.names.index('NO')] = NO0_M - NOBr_ref
     assert np.allclose(cmp, ref)
Example #7
0
 def check(rsys):
     odesys, extra = get_odesys(rsys, unit_registry=SI_base_registry, constants=const)
     res = odesys.integrate(t, init_cond, params, integrator='cvode')
     t_sec = to_unitless(res.xout, u.second)
     NOBr_ref = analytic_b(t_sec)
     cmp = to_unitless(res.yout, u.M)
     ref = np.empty_like(cmp)
     ref[:, odesys.names.index('NOBr')] = NOBr_ref
     ref[:, odesys.names.index('Br')] = Br0_M - NOBr_ref
     ref[:, odesys.names.index('NO')] = NO0_M - NOBr_ref
     assert np.allclose(cmp, ref)
Example #8
0
 def check(rsys):
     odes, extra = get_odesys(rsys, unit_registry=SI_base_registry, constants=const, substitutions={
         'temperature': RampedTemp([T_K*u.K, dTdt_Ks*u.K/u.s])})
     for odesys in [odes, odes.as_autonomous()]:
         res = odesys.integrate(t, init_cond, integrator='cvode')
         t_sec = to_unitless(res.xout, u.second)
         NO2_ref = analytic_unit0(t_sec, dTdt_Ks, T_K, dH, dS)
         cmp = to_unitless(res.yout, u.M)
         ref = np.empty_like(cmp)
         ref[:, odesys.names.index('NO2')] = NO2_ref
         ref[:, odesys.names.index('N2O4')] = (NO2_M - NO2_ref)/2
         assert np.allclose(cmp, ref)
Example #9
0
 def check(rsys):
     odes, extra = get_odesys(rsys, unit_registry=SI_base_registry, constants=const, substitutions={
         'temperature': RampedTemp([T_K*u.K, dTdt_Ks*u.K/u.s])})
     for odesys in [odes, odes.as_autonomous()]:
         res = odesys.integrate(t, init_cond, integrator='cvode')
         t_sec = to_unitless(res.xout, u.second)
         NO2_ref = analytic_unit0(t_sec, dTdt_Ks, T_K, dH, dS)
         cmp = to_unitless(res.yout, u.M)
         ref = np.empty_like(cmp)
         ref[:, odesys.names.index('NO2')] = NO2_ref
         ref[:, odesys.names.index('N2O4')] = (NO2_M - NO2_ref)/2
         assert np.allclose(cmp, ref)
Example #10
0
File: bkh.py Project: bjodah/chempy
 def update_data(attrname, old, new):
     _c0 = defaultdict(lambda: 0*output_conc_unit)
     for k, w in c0_widgets.items():
         _c0[k] = w.value * output_conc_unit
     _params = {}
     for (k, w), u in zip(param_widgets.items(), p_units):
         _params[k] = w.value if u is None else w.value * u
     _result = integrate(tout, _c0, _params)
     for idx, k in enumerate(rsys.substances):
         sources[idx].data = {
             'tout': to_unitless(_result.xout, output_time_unit),
             k: to_unitless(_result.yout[:, idx], output_conc_unit)
         }
Example #11
0
 def update_data(attrname, old, new):
     _c0 = defaultdict(lambda: 0 * output_conc_unit)
     for k, w in c0_widgets.items():
         _c0[k] = w.value * output_conc_unit
     _params = {}
     for (k, w), u in zip(param_widgets.items(), p_units):
         _params[k] = w.value if u is None else w.value * u
     _result = integrate(tout, _c0, _params)
     for idx, k in enumerate(rsys.substances):
         sources[idx].data = {
             "tout": to_unitless(_result.xout, output_time_unit),
             k: to_unitless(_result.yout[:, idx], output_conc_unit),
         }
Example #12
0
 def check(rsys, params):
     odes, extra = get_odesys(rsys, include_params=False,
                              unit_registry=SI_base_registry, constants=const)
     for odesys in [odes, odes.as_autonomous()]:
         res = odesys.integrate(t, init_cond, params, integrator='cvode')
         t_sec = to_unitless(res.xout, u.second)
         FeSCN_ref = binary_rev(t_sec, kf_ref, kb_ref, 0, Fe0, SCN0)
         cmp = to_unitless(res.yout, u.M)
         ref = np.empty_like(cmp)
         ref[:, odesys.names.index('FeSCN+2')] = FeSCN_ref
         ref[:, odesys.names.index('Fe+3')] = Fe0 - FeSCN_ref
         ref[:, odesys.names.index('SCN-')] = SCN0 - FeSCN_ref
         assert np.allclose(cmp, ref)
Example #13
0
 def check(rsys, params):
     odes, extra = get_odesys(rsys, include_params=False,
                              unit_registry=SI_base_registry, constants=const)
     for odesys in [odes, odes.as_autonomous()]:
         res = odesys.integrate(t, init_cond, params, integrator='cvode')
         t_sec = to_unitless(res.xout, u.second)
         FeSCN_ref = binary_rev(t_sec, kf_ref, kb_ref, 0, Fe0, SCN0)
         cmp = to_unitless(res.yout, u.M)
         ref = np.empty_like(cmp)
         ref[:, odesys.names.index('FeSCN+2')] = FeSCN_ref
         ref[:, odesys.names.index('Fe+3')] = Fe0 - FeSCN_ref
         ref[:, odesys.names.index('SCN-')] = SCN0 - FeSCN_ref
         assert np.allclose(cmp, ref)
Example #14
0
def test_get_native__Radiolytic__named_parameter__units(dep_scaling):
    rsys = ReactionSystem.from_string("""
    -> H; Radiolytic(2*per100eV)
    H + H -> H2; 'k2'
    """,
                                      checks=('substance_keys', 'duplicate',
                                              'duplicate_names'))
    gval = 2 * u.per100eV

    from pyodesys.symbolic import ScaledSys
    kwargs = {} if dep_scaling == 1 else dict(SymbolicSys=ScaledSys,
                                              dep_scaling=dep_scaling)
    odesys, extra = get_odesys(rsys,
                               include_params=False,
                               unit_registry=SI_base_registry,
                               **kwargs)
    c0 = {'H': 42e-6 * u.molar, 'H2': 17e3 * u.nanomolar}
    native = get_native(rsys, odesys, 'cvode')
    tend = 7 * 60 * u.minute
    params = {
        'doserate': 314 * u.Gy / u.hour,
        'k2': 53 / u.molar / u.minute,
        'density': 998 * u.g / u.dm3
    }
    result = native.integrate(tend,
                              c0,
                              params,
                              atol=1e-15,
                              rtol=1e-15,
                              integrator='cvode',
                              nsteps=8000)
    assert result.info['success']

    def analytic_H(t, p, k, H0):
        # dH/dt = p - k2*H**2
        x0 = np.sqrt(2) * np.sqrt(p)
        x1 = x0
        x2 = np.sqrt(k)
        x3 = t * x1 * x2
        x4 = H0 * x2
        x5 = np.sqrt(x0 + 2 * x4)
        x6 = np.sqrt(-1 / (2 * H0 * x2 - x0))
        x7 = x5 * x6 * np.exp(x3)
        x8 = np.exp(-x3) / (x5 * x6)
        return x1 * (x7 - x8) / (2 * x2 * (x7 + x8))

    t_ul = to_unitless(result.xout, u.s)
    p_ul = to_unitless(params['doserate'] * params['density'] * gval,
                       u.micromolar / u.s)
    ref_H_uM = analytic_H(t_ul, p_ul,
                          to_unitless(params['k2'], 1 / u.micromolar / u.s),
                          to_unitless(c0['H'], u.micromolar))
    ref_H2_uM = to_unitless(c0['H2'], u.micromolar) + to_unitless(
        c0['H'], u.micromolar) / 2 + t_ul * p_ul / 2 - ref_H_uM / 2
    assert np.allclose(to_unitless(result.named_dep('H'), u.micromolar),
                       ref_H_uM)
    assert np.allclose(to_unitless(result.named_dep('H2'), u.micromolar),
                       ref_H2_uM)
Example #15
0
def test_get_native__named_parameter__units(dep_scaling):
    rsys = ReactionSystem.from_string(
        """
    -> H; 'p'
    H + H -> H2; 'k2'
    """,
        checks=("substance_keys", "duplicate", "duplicate_names"),
    )
    from pyodesys.symbolic import ScaledSys

    kwargs = ({} if dep_scaling == 1 else dict(SymbolicSys=ScaledSys,
                                               dep_scaling=dep_scaling))
    odesys, extra = get_odesys(rsys,
                               include_params=False,
                               unit_registry=SI_base_registry,
                               **kwargs)
    c0 = {"H": 42e-6 * u.molar, "H2": 17 * u.micromolar}
    native = get_native(rsys, odesys, "cvode")
    tend = 7 * 60 * u.minute
    g_rho_Ddot = g, rho, Ddot = 2 * u.per100eV, 998 * u.g / u.dm3, 314 * u.Gy / u.hour
    params = {"p": reduce(mul, g_rho_Ddot), "k2": 53 / u.molar / u.minute}
    result = native.integrate(tend,
                              c0,
                              params,
                              atol=1e-15,
                              rtol=1e-15,
                              integrator="cvode",
                              nsteps=16000)
    assert result.info["success"]

    def analytic_H(t, p, k, H0):
        # dH/dt = p - k2*H**2
        x0 = np.sqrt(2) * np.sqrt(p)
        x1 = x0
        x2 = np.sqrt(k)
        x3 = t * x1 * x2
        x4 = H0 * x2
        x5 = np.sqrt(x0 + 2 * x4)
        x6 = np.sqrt(-1 / (2 * H0 * x2 - x0))
        x7 = x5 * x6 * np.exp(x3)
        x8 = np.exp(-x3) / (x5 * x6)
        return x1 * (x7 - x8) / (2 * x2 * (x7 + x8))

    t_ul = to_unitless(result.xout, u.s)
    p_ul = to_unitless(params["p"], u.micromolar / u.s)
    ref_H_uM = analytic_H(
        t_ul,
        p_ul,
        to_unitless(params["k2"], 1 / u.micromolar / u.s),
        to_unitless(c0["H"], u.micromolar),
    )
    ref_H2_uM = (to_unitless(c0["H2"], u.micromolar) +
                 to_unitless(c0["H"], u.micromolar) / 2 + t_ul * p_ul / 2 -
                 ref_H_uM / 2)
    assert np.allclose(to_unitless(result.named_dep("H"), u.micromolar),
                       ref_H_uM)
    assert np.allclose(to_unitless(result.named_dep("H2"), u.micromolar),
                       ref_H2_uM)
Example #16
0
def test_get_odesys__with_units():
    a = Substance('A')
    b = Substance('B')
    molar = u.molar
    second = u.second
    r = Reaction({'A': 2}, {'B': 1}, param=1e-3/molar/second)
    rsys = ReactionSystem([r], [a, b])
    odesys = get_odesys(rsys, include_params=True,
                        unit_registry=SI_base_registry)[0]
    c0 = {
        'A': 13*u.mol / u.metre**3,
        'B': .2 * u.molar
    }
    conc_unit = get_derived_unit(SI_base_registry, 'concentration')
    t = np.linspace(0, 10)*u.hour
    xout, yout, info = odesys.integrate(
        t, rsys.as_per_substance_array(c0, unit=conc_unit),
        atol=1e-10, rtol=1e-12)

    t_unitless = to_unitless(xout, u.second)
    Aref = dimerization_irrev(t_unitless, 1e-6, 13.0)
    # Aref = 1/(1/13 + 2*1e-6*t_unitless)
    yref = np.zeros((xout.size, 2))
    yref[:, 0] = Aref
    yref[:, 1] = 200 + (13-Aref)/2
    print((yout - yref*conc_unit)/yout)
    assert allclose(yout, yref*conc_unit)
Example #17
0
def test_ArrheniusMassAction__units(R_from_constants):
    import numpy as np

    Ea = 40e3 * u.J / u.mol
    R = (default_constants.molar_gas_constant if R_from_constants else
         (8.3145 * u.J / u.mol / u.K))
    A, Ea_over_R = 1.2e11 / u.molar**2 / u.second, Ea / R
    ref1 = A * np.exp(-to_unitless(Ea_over_R / (290 * u.K)))
    arrh = Arrhenius([A, Ea_over_R])
    assert allclose(arrh({"temperature": 290 * u.K}), ref1)
    ama = MassAction(arrh)
    r = Reaction({"A": 2, "B": 1}, {"C": 1}, ama, {"B": 1})
    T_ = "temperature"

    def ref(v):
        return (1.2e11 / u.molar**2 / u.second *
                math.exp(-Ea_over_R.simplified / v[T_]) * v["B"] * v["A"]**2)

    ma = r.rate_expr()

    for params in [
        (11.0 * u.molar, 13.0 * u.molar, 17.0 * u.molar, 311.2 * u.kelvin),
        (12 * u.molar, 8 * u.molar, 5 * u.molar, 270 * u.kelvin),
    ]:
        var = dict(zip(["A", "B", "C", T_], params))
        ref_val = ref(var)
        assert abs((ma(var, reaction=r) - ref_val) / ref_val) < 1e-14
Example #18
0
def test_create_odesys():
    rsys = ReactionSystem.from_string("""
    A -> B; 'k1'
    B + C -> P; 'k2'
    """, substance_factory=Substance)

    odesys, odesys_extra = create_odesys(rsys, unit_registry=SI_base_registry)

    tend = 10
    c0 = {'A': 1e-6, 'B': 0, 'C': 1, 'P': 0}
    p = dict(k1=3, k2=4)

    tend_units = tend*u.s
    p_units = {'k1': p['k1']/u.s, 'k2': p['k2']/u.M/u.s}
    c0_units = {k: v*u.molar for k, v in c0.items()}

    validation = odesys_extra['validate'](dict(c0_units, **p_units))
    P, = validation['not_seen']
    assert P.name == 'P'

    ref_rates = {'A': -p_units['k1']*c0_units['A'], 'P': p_units['k2']*c0_units['B']*c0_units['C']}
    ref_rates['B'] = -ref_rates['A'] - ref_rates['P']
    ref_rates['C'] = -ref_rates['P']
    assert validation['rates'] == ref_rates

    result1, result1_extra = odesys_extra['unit_aware_solve'](
        tend_units, c0_units, p_units, integrator='cvode')
    assert result1.info['success']

    result2 = odesys.integrate(tend, c0, p, integrator='cvode')
    assert np.allclose(result2.yout[-1, :], to_unitless(result1.yout[-1, :], u.molar))
Example #19
0
 def _check(r):
     res = r({
         "doserate": 0.15 * u.gray / u.second,
         "density": 0.998 * u.kg / u.decimetre**3,
     })
     ref = 0.15 * 0.998 * 2.1e-7 * u.molar / u.second
     assert abs(to_unitless((res - ref) / ref)) < 1e-15
Example #20
0
def test_get_odesys__with_units():
    a = Substance('A')
    b = Substance('B')
    molar = u.molar
    second = u.second
    r = Reaction({'A': 2}, {'B': 1}, param=1e-3/molar/second)
    rsys = ReactionSystem([r], [a, b])
    odesys = get_odesys(rsys, include_params=True,
                        unit_registry=SI_base_registry)[0]
    c0 = {
        'A': 13*u.mol / u.metre**3,
        'B': .2 * u.molar
    }
    conc_unit = get_derived_unit(SI_base_registry, 'concentration')
    t = np.linspace(0, 10)*u.hour
    xout, yout, info = odesys.integrate(
        t, rsys.as_per_substance_array(c0, unit=conc_unit),
        atol=1e-10, rtol=1e-12)

    t_unitless = to_unitless(xout, u.second)
    Aref = dimerization_irrev(t_unitless, 1e-6, 13.0)
    # Aref = 1/(1/13 + 2*1e-6*t_unitless)
    yref = np.zeros((xout.size, 2))
    yref[:, 0] = Aref
    yref[:, 1] = 200 + (13-Aref)/2
    assert allclose(yout, yref*conc_unit)
Example #21
0
def test_create_odesys():
    rsys = ReactionSystem.from_string("""
    A -> B; 'k1'
    B + C -> P; 'k2'
    """, substance_factory=Substance)

    odesys, odesys_extra = create_odesys(rsys, unit_registry=SI_base_registry)

    tend = 10
    c0 = {'A': 1e-6, 'B': 0, 'C': 1, 'P': 0}
    p = dict(k1=3, k2=4)

    tend_units = tend*u.s
    p_units = {'k1': p['k1']/u.s, 'k2': p['k2']/u.M/u.s}
    c0_units = {k: v*u.molar for k, v in c0.items()}

    validation = odesys_extra['validate'](dict(c0_units, **p_units))
    P, = validation['not_seen']
    assert P.name == 'P'

    ref_rates = {'A': -p_units['k1']*c0_units['A'], 'P': p_units['k2']*c0_units['B']*c0_units['C']}
    ref_rates['B'] = -ref_rates['A'] - ref_rates['P']
    ref_rates['C'] = -ref_rates['P']
    assert validation['rates'] == ref_rates

    result1, result1_extra = odesys_extra['unit_aware_solve'](
        tend_units, c0_units, p_units, integrator='cvode')
    assert result1.info['success']

    result2 = odesys.integrate(tend, c0, p, integrator='cvode')
    assert np.allclose(result2.yout[-1, :], to_unitless(result1.yout[-1, :], u.molar))
Example #22
0
def decompose_yields(yields, rxns, atol=1e-10):
    """ Decomposes yields into mass-action reactions

    This function offers a way to express a reaction with non-integer
    stoichiometric coefficients as a linear combination of production reactions
    with integer coefficients.

    Ak = y

    A is (n_species x n_reactions) matrix, k is "rate coefficient", y is yields


    Parameters
    ----------
    yields : OrderedDict
        Specie names as keys and yields as values.
    rxns : iterable :class:`Reaction` instances
        Dict keys must match those of ``yields`` each pair
        of dictionaries gives stoichiometry
        (1st is reactant, 2nd is products).
    atol : float
        Absolute tolerance for residuals.


    Examples
    --------
    >>> from chempy import Reaction
    >>> h2a = Reaction({'H2O': 1}, {'H2': 1, 'O': 1})
    >>> h2b = Reaction({'H2O': 1}, {'H2': 1, 'H2O2': 1}, inact_reac={'H2O': 1})
    >>> decompose_yields({'H2': 3, 'O': 2, 'H2O2': 1}, [h2a, h2b])
    array([2., 1.])

    Raises
    ------
    ValueError
        When atol is exceeded
    numpy.LinAlgError
        When numpy.linalg.lstsq fails to converge

    Returns
    -------
    1-dimensional array of effective rate coefficients.

    """
    from chempy import ReactionSystem
    # Sanity check:
    rxn_keys = set.union(*(rxn.keys() for rxn in rxns))
    for key in yields.keys():
        if key not in rxn_keys:
            raise ValueError("Substance key: %s not in reactions" % key)
    rsys = ReactionSystem(rxns, rxn_keys)
    A = rsys.net_stoichs(yields.keys())
    b = list(yields.values())
    unit = unit_of(b[0])
    x, residuals, rank, s = np.linalg.lstsq(
        np.asarray(A.T, dtype=np.float64), to_unitless(b, unit), rcond=2e-16*max(A.shape))
    if len(residuals) > 0:
        if np.any(residuals > atol):
            raise ValueError("atol not satisfied")
    return x*unit
Example #23
0
def decompose_yields(yields, rxns, atol=1e-10):
    """ Decomposes yields into mass-action reactions

    This function offers a way to express a reaction with non-integer
    stoichiometric coefficients as a linear combination of production reactions
    with integer coefficients.

    Ak = y

    A is (n_species x n_reactions) matrix, k is "rate coefficient", y is yields


    Parameters
    ----------
    yields: OrderedDict
        specie names as keys and yields as values
    rxns: iterable :class:`Reaction` instances
        dict keys must match those of ``yields`` each pair
        of dictionaries gives stoichiometry
        (1st is reactant, 2nd is products)
    atol: float
        absolute tolerance for residuals


    Examples
    --------
    >>> from chempy import Reaction
    >>> h2a = Reaction({'H2O': 1}, {'H2': 1, 'O': 1})
    >>> h2b = Reaction({'H2O': 1}, {'H2': 1, 'H2O2': 1}, inact_reac={'H2O': 1})
    >>> decompose_yields({'H2': 3, 'O': 2, 'H2O2': 1}, [h2a, h2b])
    array([ 2.,  1.])

    Raises
    ------
    ValueError
        When atol is exceeded
    numpy.LinAlgError
        When numpy.linalg.lstsq fails to converge

    Returns
    -------
    1-dimensional array of effective rate coefficients.

    """
    from chempy import ReactionSystem
    # Sanity check:
    rxn_keys = set.union(*(rxn.keys() for rxn in rxns))
    for key in yields.keys():
        if key not in rxn_keys:
            raise ValueError("Substance key: %s not in reactions" % key)
    rsys = ReactionSystem(rxns, rxn_keys)
    A = rsys.net_stoichs(yields.keys())
    b = list(yields.values())
    unit = unit_of(b[0])
    x, residuals, rank, s = np.linalg.lstsq(A.T, to_unitless(b, unit))
    if len(residuals) > 0:
        if np.any(residuals > atol):
            raise ValueError("atol not satisfied")
    return x*unit
Example #24
0
 def _check(r):
     res = r({
         'doserate': 0.15 * u.gray / u.second,
         'density': 0.998 * u.kg / u.decimetre**3,
         'temperature': 298.15 * u.K
     })
     ref = 0.15 * 0.998 * 2.1e-7 * u.molar / u.second
     assert abs(to_unitless((res - ref) / ref)) < 1e-15
Example #25
0
def _r(r,
       p,
       doserate,
       substmap,
       parmap,
       density=998 * u.kg / u.m3,
       unit_conc=u.molar,
       unit_time=u.second):
    pk, = r.param.unique_keys
    if isinstance(r.param, MassAction):
        ratcoeff = to_unitless(p[pk], unit_conc**(1 - r.order()) / unit_time)
        if not r.inact_reac:
            r_str = '{}, {}'.format(
                parmap[pk],
                r.string(substances=substmap,
                         with_param=False,
                         Reaction_arrow='-->',
                         Reaction_coeff_space=''))
        else:
            all_keys = r.keys()
            reac_stoichs = r.all_reac_stoich(all_keys)
            act_stoichs = r.active_reac_stoich(all_keys)
            rate = '*'.join([parmap[pk]] +
                            [('%s^%d' %
                              (substmap[k], v)) if v > 1 else substmap[k]
                             for k, v in zip(all_keys, act_stoichs) if v > 0])
            r2 = Reaction(
                dict([(k, v) for k, v in zip(all_keys, reac_stoichs) if v]),
                r.prod)
            r_str = '{}, {}'.format(
                rate,
                r2.string(substances=substmap,
                          with_param=False,
                          Reaction_arrow='\u21D2',
                          Reaction_coeff_space=''))
    elif isinstance(r.param, RadiolyticBase):
        ratcoeff = to_unitless(p[pk] * doserate * density,
                               unit_conc / unit_time)
        assert not r.reac and not r.inact_reac and not r.inact_prod
        (prod, n), = r.prod.items()
        assert n == 1
        r_str = ('{}, 0 \u21D2 {}' if ratcoeff > 0 else
                 '{}, {} \u21D2 0').format(parmap[pk], substmap[prod])
    else:
        raise NotImplementedError("Whats that?")
    return r_str, pk, abs(ratcoeff)
Example #26
0
 def check(rsys):
     odes, extra = get_odesys(
         rsys,
         unit_registry=SI_base_registry,
         constants=const,
         substitutions={"temperature": RampedTemp([T_K * u.K, 1 * u.K / u.s])},
     )
     for odesys in [odes, odes.as_autonomous()]:
         res = odesys.integrate(t, init_cond, integrator="cvode")
         t_sec = to_unitless(res.xout, u.second)
         NOBr_ref = NOBr0_M * analytic_unit0(t_sec, T_K, dH, dS)
         cmp = to_unitless(res.yout, u.M)
         ref = np.empty_like(cmp)
         ref[:, odesys.names.index("NOBr")] = NOBr_ref
         ref[:, odesys.names.index("Br")] = NOBr0_M - NOBr_ref
         ref[:, odesys.names.index("NO")] = NOBr0_M - NOBr_ref
         assert np.allclose(cmp, ref)
Example #27
0
 def _check(T=273.15 * u.kelvin):
     result = cv['Be']({
         'temperature': T,
         'molar_gas_constant': R
     },
                       backend=Backend())
     ref = 0.7342617587256584 * u.joule / u.gram / u.kelvin
     assert abs(to_unitless((result - ref) / ref)) < 1e-10
Example #28
0
def test_SpecialFraction_with_units():
    k, kprime = 3.142 * u.s**-1 * u.molar**-0.5, 2.718
    rsys = _get_SpecialFraction_rsys(k, kprime)
    odesys = get_odesys(rsys, include_params=True,
                        unit_registry=SI_base_registry)[0]
    c0 = {'H2': 13*u.molar, 'Br2': 16*u.molar, 'HBr': 19*u.molar}
    r = k*c0['H2']*c0['Br2']**(3/2)/(c0['Br2'] + kprime*c0['HBr'])
    conc_unit = u.mol/u.metre**3
    rate_unit = conc_unit/u.second
    ref = rsys.as_per_substance_array({'H2': -r, 'Br2': -r, 'HBr': 2*r}, unit=rate_unit)
    res = odesys.f_cb(0, rsys.as_per_substance_array(c0, unit=conc_unit))
    assert allclose(to_unitless(ref, rate_unit), res)
Example #29
0
def test_SpecialFraction_with_units():
    k, kprime = 3.142 * u.s**-1 * u.molar**-0.5, 2.718
    rsys = _get_SpecialFraction_rsys(k, kprime)
    odesys = get_odesys(rsys, include_params=True,
                        unit_registry=SI_base_registry)[0]
    c0 = {'H2': 13*u.molar, 'Br2': 16*u.molar, 'HBr': 19*u.molar}
    r = k*c0['H2']*c0['Br2']**(3/2)/(c0['Br2'] + kprime*c0['HBr'])
    conc_unit = u.mol/u.metre**3
    rate_unit = conc_unit/u.second
    ref = rsys.as_per_substance_array({'H2': -r, 'Br2': -r, 'HBr': 2*r}, unit=rate_unit)
    res = odesys.f_cb(0, rsys.as_per_substance_array(c0, unit=conc_unit))
    assert allclose(to_unitless(ref, rate_unit), res)
Example #30
0
def radyields2pdf_table(rd, output_dir=None, save=True, unit_registry=None,
                        siunitx=False, fmtstr='{0:.3f}', **kwargs):
    """ Generate a table with radiolytic yields

    Calls chempy.util.table.render_tex_to_pdf

    Parameters
    ----------
    rd: ReactionDiffusion
    output_dir: str
    save: bool
    unit_registry: dict
    siunitx: bool
    fmtstr: str
    \*\*kwargs:
        extends the table template dictionary
    """
    line_term = r' \\'
    col_delim = ' & '
    header = (col_delim.join(rd.substance_latex_names or rd.substance_names) +
              line_term)
    lines = []
    for cur_gs in rd.g_values:
        if unit_registry is not None:
            gunit = get_derived_unit(unit_registry, 'radiolytic_yield')
            cur_gs = to_unitless(cur_gs, gunit)
        lines.append(col_delim.join(map(
            lambda v: fmtstr.format(v), cur_gs)) + line_term)
    table_template_dict = {
        'table_env': 'table',
        'alignment': ('@{}S' if siunitx else '@{}l')*rd.n,
        'header': header,
        'short_cap': 'G-values',
        'long_cap': 'G-values',
        'label': 'none',
        'body': '\n'.join(lines)
    }
    table_template_dict.update(kwargs)
    table = tex_templates['table']['default'] % table_template_dict

    _envs = ['landscape', 'tiny']
    _pkgs = (['siunitx'] if siunitx else []) + [
        'booktabs', 'lscape', 'amsmath', 'hyperref']
    contents = tex_templates['document']['default'] % {
        'usepkg': '\n'.join([r'\usepackage{%s}' % pkg for pkg in _pkgs]),
        'begins': '\n'.join([r'\begin{%s}' % env for env in _envs]),
        'ends': '\n'.join([r'\end{%s}' % env for env in _envs[::-1]]),
        'table': table
    }
    return render_tex_to_pdf(contents, 'gvalues.tex', 'gvalues.pdf',
                             output_dir, save)
Example #31
0
def test_get_native__Radiolytic__named_parameter__units(scaling_density):
    scaling, density = scaling_density
    rsys = ReactionSystem.from_string("""
    -> H; Radiolytic(2*per100eV)
    H + H -> H2; 'k2'
    """, checks=('substance_keys', 'duplicate', 'duplicate_names'))
    gval = 2*u.per100eV

    from pyodesys.symbolic import ScaledSys
    kwargs = {} if scaling == 1 else dict(SymbolicSys=ScaledSys, dep_scaling=scaling)
    dens = {'density': 998*u.g/u.dm3}
    odesys, extra = get_odesys(rsys, include_params=False, substitutions=dens if density else {},
                               unit_registry=SI_base_registry, **kwargs)
    c0 = {'H': 42e-6*u.molar, 'H2': 17e3*u.nanomolar}
    native = get_native(rsys, odesys, 'cvode')
    tend = 7*60*u.minute
    params = {'doserate': 314*u.Gy/u.hour, 'k2': 53/u.molar/u.minute}
    if not density:
        params.update(dens)
    result = native.integrate(tend, c0, params, atol=1e-15, rtol=1e-15, integrator='cvode', nsteps=8000)
    assert result.info['success']

    def analytic_H(t, p, k, H0):
        # dH/dt = p - k2*H**2
        x0 = np.sqrt(2)*np.sqrt(p)
        x1 = x0
        x2 = np.sqrt(k)
        x3 = t*x1*x2
        x4 = H0*x2
        x5 = np.sqrt(x0 + 2*x4)
        x6 = np.sqrt(-1/(2*H0*x2 - x0))
        x7 = x5*x6*np.exp(x3)
        x8 = np.exp(-x3)/(x5*x6)
        return x1*(x7 - x8)/(2*x2*(x7 + x8))

    t_ul = to_unitless(result.xout, u.s)
    p_ul = to_unitless(params['doserate']*dens['density']*gval, u.micromolar/u.s)
    ref_H_uM = analytic_H(
        t_ul,
        p_ul,
        to_unitless(params['k2'], 1/u.micromolar/u.s),
        to_unitless(c0['H'], u.micromolar)
    )
    ref_H2_uM = to_unitless(c0['H2'], u.micromolar) + to_unitless(c0['H'], u.micromolar)/2 + t_ul*p_ul/2 - ref_H_uM/2
    assert np.allclose(to_unitless(result.named_dep('H'), u.micromolar), ref_H_uM)
    assert np.allclose(to_unitless(result.named_dep('H2'), u.micromolar), ref_H2_uM)
Example #32
0
def test_get_native__named_parameter__units(dep_scaling):
    rsys = ReactionSystem.from_string("""
    -> H; 'p'
    H + H -> H2; 'k2'
    """, checks=('substance_keys', 'duplicate', 'duplicate_names'))
    from pyodesys.symbolic import ScaledSys
    kwargs = {} if dep_scaling == 1 else dict(SymbolicSys=ScaledSys, dep_scaling=dep_scaling)
    odesys, extra = get_odesys(rsys, include_params=False, unit_registry=SI_base_registry, **kwargs)
    c0 = {'H': 42e-6*u.molar, 'H2': 17*u.micromolar}
    native = get_native(rsys, odesys, 'cvode')
    tend = 7*60*u.minute
    g_rho_Ddot = g, rho, Ddot = 2*u.per100eV, 998*u.g/u.dm3, 314*u.Gy/u.hour
    params = {
        'p': reduce(mul, g_rho_Ddot),
        'k2': 53/u.molar/u.minute
    }
    result = native.integrate(tend, c0, params, atol=1e-15, rtol=1e-15, integrator='cvode', nsteps=16000)
    assert result.info['success']

    def analytic_H(t, p, k, H0):
        # dH/dt = p - k2*H**2
        x0 = np.sqrt(2)*np.sqrt(p)
        x1 = x0
        x2 = np.sqrt(k)
        x3 = t*x1*x2
        x4 = H0*x2
        x5 = np.sqrt(x0 + 2*x4)
        x6 = np.sqrt(-1/(2*H0*x2 - x0))
        x7 = x5*x6*np.exp(x3)
        x8 = np.exp(-x3)/(x5*x6)
        return x1*(x7 - x8)/(2*x2*(x7 + x8))

    t_ul = to_unitless(result.xout, u.s)
    p_ul = to_unitless(params['p'], u.micromolar/u.s)
    ref_H_uM = analytic_H(
        t_ul,
        p_ul,
        to_unitless(params['k2'], 1/u.micromolar/u.s),
        to_unitless(c0['H'], u.micromolar)
    )
    ref_H2_uM = to_unitless(c0['H2'], u.micromolar) + to_unitless(c0['H'], u.micromolar)/2 + t_ul*p_ul/2 - ref_H_uM/2
    assert np.allclose(to_unitless(result.named_dep('H'), u.micromolar), ref_H_uM)
    assert np.allclose(to_unitless(result.named_dep('H2'), u.micromolar), ref_H2_uM)
Example #33
0
def export2julia(armor_rsys, armor_extra, *, ics, kw2=None):
    debj = to_diffeqbiojl(armor_rsys, armor_extra, **(kw2 or {}))
    export = debj['rn']

    def p_odj(od):
        return "Dict([%s])" % ", ".join(
            ['(:%s, %.4g)' % (k, v) for k, v in od.items()])

    # str(od).replace('Ordered', '').replace("',", ',').replace("'", ":")
    export += "p = %s\n" % p_odj(debj['pars'])
    export += "ics = %s\n" % p_odj(
        OrderedDict({
            debj['sbstmap'][k]: v
            for k, v in to_unitless(ics, u.molar).items()
        }))
    export += "subst_tex = Dict([%s])\n" % ", ".join(
        '(:%s, ("%s", "%s"))' % (v, k, armor_rsys.substances[k].latex_name)
        for k, v in debj['sbstmap'].items())
    return export
Example #34
0
def test_create_odesys():
    rsys = ReactionSystem.from_string(
        """
    A -> B; 'k1'
    B + C -> P; 'k2'
    """,
        substance_factory=Substance,
    )

    odesys, odesys_extra = create_odesys(rsys, unit_registry=SI_base_registry)

    tend_ul = 10
    init_conc_ul = {"A": 1e-6, "B": 0, "C": 1}
    params_ul = dict(k1=3, k2=4)

    tend = tend_ul * u.s
    params = {"k1": params_ul["k1"] / u.s, "k2": params_ul["k2"] / u.M / u.s}
    init_conc = {k: v * u.molar for k, v in init_conc_ul.items()}

    validation = odesys_extra["validate"](dict(init_conc, **params))
    (P,) = validation["not_seen"]
    assert P == "P"

    ref_rates = {
        "A": -params["k1"] * init_conc["A"],
        "P": params["k2"] * init_conc["B"] * init_conc["C"],
    }
    ref_rates["B"] = -ref_rates["A"] - ref_rates["P"]
    ref_rates["C"] = -ref_rates["P"]
    assert validation["rates"] == ref_rates

    result1, result1_extra = odesys_extra["unit_aware_solve"](
        tend, defaultdict(lambda: 0 * u.molar, init_conc), params, integrator="cvode"
    )
    assert result1.info["success"]

    result2 = odesys.integrate(
        tend_ul, defaultdict(lambda: 0, init_conc_ul), params_ul, integrator="cvode"
    )
    assert np.allclose(result2.yout[-1, :], to_unitless(result1.yout[-1, :], u.molar))
Example #35
0
def test_ArrheniusMassAction__units(R_from_constants):
    import numpy as np
    Ea = 40e3*u.J/u.mol
    R = default_constants.molar_gas_constant if R_from_constants else (8.3145*u.J/u.mol/u.K)
    A, Ea_over_R = 1.2e11/u.molar**2/u.second, Ea/R
    ref1 = A*np.exp(-to_unitless(Ea_over_R/(290*u.K)))
    arrh = Arrhenius([A, Ea_over_R])
    assert allclose(arrh({'temperature': 290*u.K}), ref1)
    ama = MassAction(arrh)
    r = Reaction({'A': 2, 'B': 1}, {'C': 1}, ama, {'B': 1})
    T_ = 'temperature'

    def ref(v):
        return 1.2e11/u.molar**2/u.second*math.exp(
            -Ea_over_R.simplified/v[T_])*v['B']*v['A']**2
    ma = r.rate_expr()

    for params in [(11.*u.molar, 13.*u.molar, 17.*u.molar, 311.2*u.kelvin),
                   (12*u.molar, 8*u.molar, 5*u.molar, 270*u.kelvin)]:
        var = dict(zip(['A', 'B', 'C', T_], params))
        ref_val = ref(var)
        assert abs((ma(var, reaction=r) - ref_val)/ref_val) < 1e-14
Example #36
0
def test_chained_parameter_variation_from_ReactionSystem():
    g_E_mol_J = 2.1e-7
    rsys = ReactionSystem.from_string(
        """
        (H2O) -> e-(aq) + H+ + OH; Radiolytic(%.2e*mol/J)
        2 OH -> H2O2; 3.6e9/M/s
        H+ + OH- -> H2O; 1.4e11/M/s
        H2O -> H+ + OH-; 1.4e-3/s
        N2O + e-(aq) -> N2 + O-; 9.6e9/M/s
        O- + H+ -> OH; 1e11/M/s
        """ % g_E_mol_J  # neglecting a large body of reactions (just a test-case after all)
    )
    ureg = SI_base_registry
    field_u = get_derived_unit(ureg, 'doserate') * get_derived_unit(ureg, 'density')
    rd = ReactionDiffusion.from_ReactionSystem(rsys, fields=[[0*field_u]], unit_registry=ureg,
                                               param_names=['doserate'])
    dens_kg_dm3 = 0.998
    odesys = rd._as_odesys(
        variables_from_params=dict(
            density=lambda self, params: dens_kg_dm3*1e3*u.kg/u.m**3
        )
    )
    npoints = 5
    durations = [59*u.second, 42*u.minute, 2*u.hour]
    doserates = [135*u.Gy/u.s, 11*u.Gy/u.s, 180*u.Gy/u.minute]
    M = u.molar
    ic = defaultdict(lambda: 0*M, {'H2O': 55.4*M, 'H+': 1e-7*M, 'OH-': 1e-7*M, 'N2O': 20e-3*M})

    result = odesys.chained_parameter_variation(durations, ic, {'doserate': doserates}, npoints=npoints)
    ref_xout_s = [0]
    for dur in map(lambda dur: to_unitless(dur, u.s), durations):
        ref_xout_s += list(np.linspace(ref_xout_s[-1], ref_xout_s[-1] + dur, npoints+1)[1:])
    assert allclose(result.xout, ref_xout_s*u.s)

    N2_M = to_unitless(result.named_dep('N2'), u.M)
    H2O2_M = to_unitless(result.named_dep('H2O2'), u.M)

    e_accum_molar = 0
    for i, (dur, dr) in enumerate(zip(durations, doserates)):
        dur_s = to_unitless(dur, u.s)
        dr_Gy_s = to_unitless(dr, u.Gy/u.s)
        local_ts = np.linspace(0, dur_s, npoints+1)
        # local_ic = {k: result.named_dep(k)[i*npoints] for k in odesys.names}
        for j, (lt, ld) in enumerate(zip(local_ts[1:], np.diff(local_ts))):
            e_accum_molar += ld*g_E_mol_J*dr_Gy_s*dens_kg_dm3
            assert abs(N2_M[i*npoints + j + 1] - e_accum_molar)/e_accum_molar < 1e-3
            assert abs(H2O2_M[i*npoints + j + 1] - e_accum_molar)/e_accum_molar < 1e-3

    res2 = odesys.integrate(durations[0], ic, {'doserate': doserates[0]}, integrator='cvode')
    dr2 = res2.params[res2.odesys.param_names.index('doserate')]
    assert np.asarray(res2.params).shape[-1] == len(odesys.param_names)
    assert allclose(dr2, doserates[0])
    assert allclose(res2.xout[-1], durations[0])
    assert allclose(res2.named_dep('N2')[-1], durations[0]*doserates[0]*g_E_mol_J*u.mol/u.J*dens_kg_dm3*u.kg/u.dm3)
    to_unitless(res2.xout, u.s)
    to_unitless(res2.yout, u.molar)
    to_unitless(dr2, u.Gy/u.s)
Example #37
0
def test_get_native__Radiolytic__named_parameter__units(scaling_density):
    scaling, density = scaling_density
    rsys = ReactionSystem.from_string(
        """
    -> H; Radiolytic(2*per100eV)
    H + H -> H2; 'k2'
    """,
        checks=("substance_keys", "duplicate", "duplicate_names"),
    )
    gval = 2 * u.per100eV

    from pyodesys.symbolic import ScaledSys

    kwargs = {} if scaling == 1 else dict(SymbolicSys=ScaledSys,
                                          dep_scaling=scaling)
    dens = {"density": 998 * u.g / u.dm3}
    odesys, extra = get_odesys(rsys,
                               include_params=False,
                               substitutions=dens if density else {},
                               unit_registry=SI_base_registry,
                               **kwargs)
    c0 = {"H": 42e-6 * u.molar, "H2": 17e3 * u.nanomolar}
    native = get_native(rsys, odesys, "cvode")
    tend = 7 * 60 * u.minute
    params = {"doserate": 314 * u.Gy / u.hour, "k2": 53 / u.molar / u.minute}
    if not density:
        params.update(dens)
    result = native.integrate(tend,
                              c0,
                              params,
                              atol=1e-15,
                              rtol=1e-15,
                              integrator="cvode",
                              nsteps=8000)
    assert result.info["success"]

    def analytic_H(t, p, k, H0):
        # dH/dt = p - k2*H**2
        x0 = np.sqrt(2) * np.sqrt(p)
        x1 = x0
        x2 = np.sqrt(k)
        x3 = t * x1 * x2
        x4 = H0 * x2
        x5 = np.sqrt(x0 + 2 * x4)
        x6 = np.sqrt(-1 / (2 * H0 * x2 - x0))
        x7 = x5 * x6 * np.exp(x3)
        x8 = np.exp(-x3) / (x5 * x6)
        return x1 * (x7 - x8) / (2 * x2 * (x7 + x8))

    t_ul = to_unitless(result.xout, u.s)
    p_ul = to_unitless(params["doserate"] * dens["density"] * gval,
                       u.micromolar / u.s)
    ref_H_uM = analytic_H(
        t_ul,
        p_ul,
        to_unitless(params["k2"], 1 / u.micromolar / u.s),
        to_unitless(c0["H"], u.micromolar),
    )
    ref_H2_uM = (to_unitless(c0["H2"], u.micromolar) +
                 to_unitless(c0["H"], u.micromolar) / 2 + t_ul * p_ul / 2 -
                 ref_H_uM / 2)
    assert np.allclose(to_unitless(result.named_dep("H"), u.micromolar),
                       ref_H_uM)
    assert np.allclose(to_unitless(result.named_dep("H2"), u.micromolar),
                       ref_H2_uM)
Example #38
0
 def _check(T=273.15*u.kelvin):
     result = cv['Be']({'temperature': T, 'molar_gas_constant': R}, backend=Backend())
     ref = 0.7342617587256584*u.joule/u.gram/u.kelvin
     assert abs(to_unitless((result - ref)/ref)) < 1e-10
Example #39
0
File: bkh.py Project: bjodah/chempy
 def _C(k):
     return to_unitless(c0[k], output_conc_unit)
# FutureLab
# Primer taller de Python

# Propiedades físicas de compuestos para su uso en química analítica
from chempy import Substance
from chempy.properties.water_density_tanaka_2001 import water_density as rho
from chempy.units import to_unitless, default_units as u

water = Substance.from_formula('H2O')

for T_C in (10, 15, 17):
    concentration_H2O = rho(T=(273.15 + T_C) * u.kelvin,
                            units=u) / water.molar_mass(units=u)
    print('[H2O] = %.2f M (at %d °C)' %
          (to_unitless(concentration_H2O, u.molar), T_C))
Example #41
0
def integration_with_sliders(rsys,
                             tend,
                             c0,
                             parameters,
                             fig_kwargs=None,
                             unit_registry=None,
                             output_conc_unit=None,
                             output_time_unit=None,
                             slider_kwargs=None,
                             x_axis_type="linear",
                             y_axis_type="linear",
                             integrate_kwargs=None,
                             odesys_extra=None,
                             get_odesys_kw=None):
    """
    Parameters
    ----------
    odesys_extra : tuple of :class:`pyodesys.ODESys` & dict
        From :func:`chempy.kinetics.ode.get_odesys`.
    get_odesys_kw : dict
        If odesys_extra is ``None`` the user may pass this for :func:`chempy.kinetics.ode.get_odesys`.
    """

    import numpy as np
    from bokeh.plotting import Figure
    from bokeh.models import ColumnDataSource, HBox, VBoxForm
    from bokeh.models.widgets import Slider

    if slider_kwargs is None:
        slider_kwargs = {}
    if get_odesys_kw is None:
        get_odesys_kw = {}
    if odesys_extra is None:
        odesys, extra = get_odesys(rsys, **get_odesys_kw)
    else:
        odesys, extra = odesys_extra

    state_keys, rarg_keys, p_units = [
        extra[k] for k in ('param_keys', 'unique', 'p_units')
    ]
    if output_conc_unit is None:
        output_conc_unit = 1
    if output_time_unit is None:
        output_conc_unit = 1

    param_keys = list(chain(state_keys, rarg_keys))
    if x_axis_type == 'linear':
        tout = linspace(tend * 0, tend)
    elif x_axis_type == 'log':
        tout = logspace_from_lin(tend * 1e-9, tend)
    else:
        raise NotImplementedError("Unknown x_axis_type: %s" % x_axis_type)

    tout, Cout, info = odesys.integrate(tout, c0, parameters,
                                        **(integrate_kwargs or {}))
    sources = [
        ColumnDataSource(
            data={
                'tout': to_unitless(tout, output_time_unit),
                k: to_unitless(Cout[:, idx], output_conc_unit)
            }) for idx, k in enumerate(rsys.substances)
    ]

    if fig_kwargs is None:
        Cmax = np.max(Cout)
        x_range = list(to_unitless([tend * 0, tend], output_time_unit))
        y_range = list(to_unitless([Cmax * 0, Cmax * 1.1], output_conc_unit))
        fig_kwargs = dict(plot_height=400,
                          plot_width=400,
                          title="C vs t",
                          tools="crosshair,pan,reset,resize,save,wheel_zoom",
                          x_range=x_range,
                          y_range=y_range,
                          x_axis_type=x_axis_type,
                          y_axis_type=y_axis_type)
    plot = Figure(**fig_kwargs)

    colors = 'red green blue black cyan magenta'.split()
    for idx, k in enumerate(rsys.substances):
        plot.line('tout',
                  k,
                  source=sources[idx],
                  line_width=3,
                  line_alpha=0.6,
                  color=colors[idx % len(colors)])

    def _C(k):
        return to_unitless(c0[k], output_conc_unit)

    if p_units is None:
        p_units = [None] * len(param_keys)
    p_ul = [
        to_unitless(parameters[k], _u) for k, _u in zip(param_keys, p_units)
    ]
    c0_widgets = OrderedDict([
        (k,
         Slider(title=k if output_conc_unit is 1 else k + ' / ' +
                output_conc_unit.dimensionality.unicode,
                value=_C(k),
                **slider_kwargs.get(
                    k, dict(start=_C(k) / 2, end=_C(k) * 2, step=_C(k) / 10))))
        for k in rsys.substances
    ])

    def _dict_to_unitless(d, u):
        return {k: to_unitless(v, u) for k, v in d.items()}

    param_widgets = OrderedDict([
        (k,
         Slider(title=k if u is None else k + ' / ' + u.dimensionality.unicode,
                value=v,
                **_dict_to_unitless(
                    slider_kwargs.get(
                        k, dict(start=v / 10, end=v * 10, step=v / 10)), u)))
        for k, v, u in zip(param_keys, p_ul, p_units)
    ])
    all_widgets = list(chain(param_widgets.values(), c0_widgets.values()))

    def update_data(attrname, old, new):
        _c0 = defaultdict(lambda: 0 * output_conc_unit)
        for k, w in c0_widgets.items():
            _c0[k] = w.value * output_conc_unit
        _params = {}
        for (k, w), u in zip(param_widgets.items(), p_units):
            _params[k] = w.value if u is None else w.value * u
        _tout, _Cout, _info = odesys.integrate(tout, _c0, _params)
        for idx, k in enumerate(rsys.substances):
            sources[idx].data = {
                'tout': to_unitless(_tout, output_time_unit),
                k: to_unitless(_Cout[:, idx], output_conc_unit)
            }

    for w in all_widgets:
        w.on_change('value', update_data)

    inputs = VBoxForm(children=all_widgets)
    return HBox(children=[inputs, plot], width=800)
Example #42
0
File: bkh.py Project: bjodah/chempy
def integration_with_sliders(
        rsys, tend, c0, parameters, fig_kwargs=None, slider_kwargs=None, conc_bounds=None,
        x_axis_type="linear", y_axis_type="linear", integrate_kwargs=None, odesys_extra=None,
        get_odesys_kw=None, integrate=None):
    """
    Parameters
    ----------
    rsys : ReactionSystem
    tend : float like
    c0 : dict
        Initial concentrations.
    parameters : dict
        Parameter values.
    fig_kwargs : dict
        Keyword-arguments passed to bokeh's ``Figure``.
    slider_kwargs : dict
        Keyword-arguments passed to bokeh's ``Slider``.
    conc_bounds : dict of dicts
        Mapping substance key to dict of bounds ('start', 'end', 'step').
    x_axis_type : str
    y_axis_type : str
    integrate_kwargs : dict
        Keyword-arguments passed to integrate.
    odesys_extra : tuple
        If odesys & extra have already been generated (avoids call to ``get_odesys``).
    get_odesys_kw : dict
        Keyword-arguments passed to ``get_odesys``.
    integrate : callback
        Defaults to ``odesys.integrate``.

    """

    import numpy as np
    from bokeh.plotting import Figure
    from bokeh.models import ColumnDataSource, Column, Row
    from bokeh.models.widgets import Slider

    if slider_kwargs is None:
        slider_kwargs = {}
    if get_odesys_kw is None:
        get_odesys_kw = {}
    if odesys_extra is None:
        odesys, extra = get_odesys(rsys, **get_odesys_kw)
    else:
        odesys, extra = odesys_extra
    if integrate is None:
        integrate = odesys.integrate

    state_keys, rarg_keys, p_units = [extra[k] for k in ('param_keys', 'unique', 'p_units')]
    output_conc_unit = get_odesys_kw.get('output_conc_unit', None)
    output_time_unit = get_odesys_kw.get('output_time_unit', None)
    unit_registry = get_odesys_kw.get('unit_registry', None)
    if output_conc_unit is None:
        if unit_registry is not None:
            raise ValueError("if unit_registry is given, output_conc_unit must also be given")
        output_conc_unit = 1
    if output_time_unit is None:
        if unit_registry is not None:
            raise ValueError("if unit_registry is given, output_time_unit must also be given")
        output_conc_unit = 1

    param_keys = list(chain(state_keys, rarg_keys))
    if x_axis_type == 'linear':
        tout = linspace(tend*0, tend)
    elif x_axis_type == 'log':
        tout = logspace_from_lin(tend*1e-9, tend)
    else:
        raise NotImplementedError("Unknown x_axis_type: %s" % x_axis_type)

    result = integrate(tout, c0, parameters, **(integrate_kwargs or {}))
    sources = [ColumnDataSource(data={
        'tout': to_unitless(result.xout, output_time_unit),
        k: to_unitless(result.yout[:, idx], output_conc_unit)
    }) for idx, k in enumerate(rsys.substances)]
    if fig_kwargs is None:
        Cmax = np.max(result.yout)
        x_range = list(to_unitless([result.xout[0], result.xout[-1]], output_time_unit))
        y_range = list(to_unitless([Cmax*0, Cmax*1.1], output_conc_unit))
        fig_kwargs = dict(plot_height=400, plot_width=400, title="C vs t",
                          tools="crosshair,pan,reset,save,wheel_zoom",
                          x_range=x_range, y_range=y_range, x_axis_type=x_axis_type,
                          y_axis_type=y_axis_type)
    plot = Figure(**fig_kwargs)

    colors = 'red green blue black cyan magenta'.split()
    for idx, k in enumerate(rsys.substances):
        plot.line('tout', k, source=sources[idx], line_width=3, line_alpha=0.6,
                  color=colors[idx % len(colors)])

    def _C(k):
        return to_unitless(c0[k], output_conc_unit)
    if p_units is None:
        p_units = [None]*len(param_keys)
    p_ul = [to_unitless(parameters[k], _u) for k, _u in zip(param_keys, p_units)]

    def _dict_to_unitless(d, u):
        return {k: to_unitless(v, u) for k, v in d.items()}

    c0_widgets = OrderedDict()
    for k in rsys.substances:
        if conc_bounds is not None and k in conc_bounds:
            if k in slider_kwargs:
                raise ValueError("Key '%s' both in slider_kwargs and conc_bounds" % k)
            slider_defaults = _dict_to_unitless(conc_bounds[k], output_conc_unit)
        else:
            ck = _C(k)
            if ck == 0:
                max_ = max(*[_C(k) for k in rsys.substances])
                slider_defaults = dict(start=0, end=max_, step=max_/100)
            else:
                slider_defaults = dict(start=_C(k)/2, end=_C(k)*2, step=_C(k)/10)
        c0_widgets[k] = Slider(
            title=k if output_conc_unit is 1 else k + ' / ' + output_conc_unit.dimensionality.unicode,
            value=_C(k), **slider_kwargs.get(k, slider_defaults)
        )

    param_widgets = OrderedDict([
        (k, Slider(title=k if u is None else k + ' / ' + u.dimensionality.unicode,
                   value=v, **_dict_to_unitless(
                       slider_kwargs.get(k, dict(start=v/10, end=v*10, step=v/10)),
                       u)))
        for k, v, u in zip(param_keys, p_ul, p_units)])
    all_widgets = list(chain(param_widgets.values(), c0_widgets.values()))

    def update_data(attrname, old, new):
        _c0 = defaultdict(lambda: 0*output_conc_unit)
        for k, w in c0_widgets.items():
            _c0[k] = w.value * output_conc_unit
        _params = {}
        for (k, w), u in zip(param_widgets.items(), p_units):
            _params[k] = w.value if u is None else w.value * u
        _result = integrate(tout, _c0, _params)
        for idx, k in enumerate(rsys.substances):
            sources[idx].data = {
                'tout': to_unitless(_result.xout, output_time_unit),
                k: to_unitless(_result.yout[:, idx], output_conc_unit)
            }

    for w in all_widgets:
        w.on_change('value', update_data)

    inputs = Column(children=all_widgets)
    return Row(children=[inputs, plot], width=800)
Example #43
0
File: bkh.py Project: bjodah/chempy
 def _dict_to_unitless(d, u):
     return {k: to_unitless(v, u) for k, v in d.items()}
Example #44
0
def integration_with_sliders(
    rsys,
    tend,
    c0,
    parameters,
    fig_kwargs=None,
    slider_kwargs=None,
    conc_bounds=None,
    x_axis_type="linear",
    y_axis_type="linear",
    integrate_kwargs=None,
    odesys_extra=None,
    get_odesys_kw=None,
    integrate=None,
):
    """
    Parameters
    ----------
    rsys : ReactionSystem
    tend : float like
    c0 : dict
        Initial concentrations.
    parameters : dict
        Parameter values.
    fig_kwargs : dict
        Keyword-arguments passed to bokeh's ``Figure``.
    slider_kwargs : dict
        Keyword-arguments passed to bokeh's ``Slider``.
    conc_bounds : dict of dicts
        Mapping substance key to dict of bounds ('start', 'end', 'step').
    x_axis_type : str
    y_axis_type : str
    integrate_kwargs : dict
        Keyword-arguments passed to integrate.
    odesys_extra : tuple
        If odesys & extra have already been generated (avoids call to ``get_odesys``).
    get_odesys_kw : dict
        Keyword-arguments passed to ``get_odesys``.
    integrate : callback
        Defaults to ``odesys.integrate``.

    """

    import numpy as np
    from bokeh.plotting import Figure
    from bokeh.models import ColumnDataSource, Column, Row
    from bokeh.models.widgets import Slider

    if slider_kwargs is None:
        slider_kwargs = {}
    if get_odesys_kw is None:
        get_odesys_kw = {}
    if odesys_extra is None:
        odesys, extra = get_odesys(rsys, **get_odesys_kw)
    else:
        odesys, extra = odesys_extra
    if integrate is None:
        integrate = odesys.integrate

    state_keys, rarg_keys, p_units = [
        extra[k] for k in ("param_keys", "unique", "p_units")
    ]
    output_conc_unit = get_odesys_kw.get("output_conc_unit", None)
    output_time_unit = get_odesys_kw.get("output_time_unit", None)
    unit_registry = get_odesys_kw.get("unit_registry", None)
    if output_conc_unit is None:
        if unit_registry is not None:
            raise ValueError(
                "if unit_registry is given, output_conc_unit must also be given"
            )
        output_conc_unit = 1
    if output_time_unit is None:
        if unit_registry is not None:
            raise ValueError(
                "if unit_registry is given, output_time_unit must also be given"
            )
        output_conc_unit = 1

    param_keys = list(chain(state_keys, rarg_keys))
    if x_axis_type == "linear":
        tout = linspace(tend * 0, tend)
    elif x_axis_type == "log":
        tout = logspace_from_lin(tend * 1e-9, tend)
    else:
        raise NotImplementedError("Unknown x_axis_type: %s" % x_axis_type)

    result = integrate(tout, c0, parameters, **(integrate_kwargs or {}))
    sources = [
        ColumnDataSource(
            data={
                "tout": to_unitless(result.xout, output_time_unit),
                k: to_unitless(result.yout[:, idx], output_conc_unit),
            }) for idx, k in enumerate(rsys.substances)
    ]
    if fig_kwargs is None:
        Cmax = np.max(result.yout)
        x_range = list(
            to_unitless([result.xout[0], result.xout[-1]], output_time_unit))
        y_range = list(to_unitless([Cmax * 0, Cmax * 1.1], output_conc_unit))
        fig_kwargs = dict(
            plot_height=400,
            plot_width=400,
            title="C vs t",
            tools="crosshair,pan,reset,save,wheel_zoom",
            x_range=x_range,
            y_range=y_range,
            x_axis_type=x_axis_type,
            y_axis_type=y_axis_type,
        )
    plot = Figure(**fig_kwargs)

    colors = "red green blue black cyan magenta".split()
    for idx, k in enumerate(rsys.substances):
        plot.line(
            "tout",
            k,
            source=sources[idx],
            line_width=3,
            line_alpha=0.6,
            color=colors[idx % len(colors)],
        )

    def _C(k):
        return to_unitless(c0[k], output_conc_unit)

    if p_units is None:
        p_units = [None] * len(param_keys)
    p_ul = [
        to_unitless(parameters[k], _u) for k, _u in zip(param_keys, p_units)
    ]

    def _dict_to_unitless(d, u):
        return {k: to_unitless(v, u) for k, v in d.items()}

    c0_widgets = OrderedDict()
    for k in rsys.substances:
        if conc_bounds is not None and k in conc_bounds:
            if k in slider_kwargs:
                raise ValueError(
                    "Key '%s' both in slider_kwargs and conc_bounds" % k)
            slider_defaults = _dict_to_unitless(conc_bounds[k],
                                                output_conc_unit)
        else:
            ck = _C(k)
            if ck == 0:
                max_ = max(*[_C(k) for k in rsys.substances])
                slider_defaults = dict(start=0, end=max_, step=max_ / 100)
            else:
                slider_defaults = dict(start=_C(k) / 2,
                                       end=_C(k) * 2,
                                       step=_C(k) / 10)
        c0_widgets[k] = Slider(
            title=(k + " / " + output_conc_unit.dimensionality.unicode)
            if hasattr(output_conc_unit, "dimensionality") else k,
            value=_C(k),
            **slider_kwargs.get(k, slider_defaults))

    param_widgets = OrderedDict([(
        k,
        Slider(title=k if u is None else k + " / " + u.dimensionality.unicode,
               value=v,
               **_dict_to_unitless(
                   slider_kwargs.get(
                       k, dict(start=v / 10, end=v * 10, step=v / 10)),
                   u,
               )),
    ) for k, v, u in zip(param_keys, p_ul, p_units)])
    all_widgets = list(chain(param_widgets.values(), c0_widgets.values()))

    def update_data(attrname, old, new):
        _c0 = defaultdict(lambda: 0 * output_conc_unit)
        for k, w in c0_widgets.items():
            _c0[k] = w.value * output_conc_unit
        _params = {}
        for (k, w), u in zip(param_widgets.items(), p_units):
            _params[k] = w.value if u is None else w.value * u
        _result = integrate(tout, _c0, _params)
        for idx, k in enumerate(rsys.substances):
            sources[idx].data = {
                "tout": to_unitless(_result.xout, output_time_unit),
                k: to_unitless(_result.yout[:, idx], output_conc_unit),
            }

    for w in all_widgets:
        w.on_change("value", update_data)

    inputs = Column(children=all_widgets)
    return Row(children=[inputs, plot], width=800)
Example #45
0
 def _C(k):
     return to_unitless(c0[k], output_conc_unit)
Example #46
0
 def _dict_to_unitless(d, u):
     return {k: to_unitless(v, u) for k, v in d.items()}
Example #47
0
File: bkh.py Project: adelq/chempy
def integration_with_sliders(
        rsys, tend, c0, parameters, fig_kwargs=None, unit_registry=None, output_conc_unit=None,
        output_time_unit=None, slider_kwargs=None, x_axis_type="linear", y_axis_type="linear",
        integrate_kwargs=None, substitutions=None):

    import numpy as np
    from bokeh.plotting import Figure
    from bokeh.models import ColumnDataSource, HBox, VBoxForm
    from bokeh.models.widgets import Slider

    if slider_kwargs is None:
        slider_kwargs = {}
    odesys, state_keys, rarg_keys, p_units = get_odesys(
        rsys, unit_registry=unit_registry, substitutions=substitutions,
        output_conc_unit=output_conc_unit,
        output_time_unit=output_time_unit)[:4]
    if output_conc_unit is None:
        output_conc_unit = 1
    if output_time_unit is None:
        output_conc_unit = 1

    param_keys = list(chain(state_keys, rarg_keys))
    if x_axis_type == 'linear':
        tout = linspace(tend*0, tend)
    elif x_axis_type == 'log':
        tout = logspace_from_lin(tend*1e-9, tend)
    else:
        raise NotImplementedError("Unknown x_axis_type: %s" % x_axis_type)

    tout, Cout, info = odesys.integrate(tout, c0, parameters, **(integrate_kwargs or {}))
    sources = [ColumnDataSource(data={
        'tout': to_unitless(tout, output_time_unit),
        k: to_unitless(Cout[:, idx], output_conc_unit)
    }) for idx, k in enumerate(rsys.substances)]

    if fig_kwargs is None:
        Cmax = np.max(Cout)
        x_range = list(to_unitless([tend*0, tend], output_time_unit))
        y_range = list(to_unitless([Cmax*0, Cmax*1.1], output_conc_unit))
        fig_kwargs = dict(plot_height=400, plot_width=400, title="C vs t",
                          tools="crosshair,pan,reset,resize,save,wheel_zoom",
                          x_range=x_range, y_range=y_range, x_axis_type=x_axis_type,
                          y_axis_type=y_axis_type)
    plot = Figure(**fig_kwargs)

    colors = 'red green blue black cyan magenta'.split()
    for idx, k in enumerate(rsys.substances):
        plot.line('tout', k, source=sources[idx], line_width=3, line_alpha=0.6,
                  color=colors[idx % len(colors)])

    def _C(k):
        return to_unitless(c0[k], output_conc_unit)
    p_ul = [to_unitless(parameters[k], _u) for k, _u in zip(param_keys, p_units)]
    c0_widgets = OrderedDict([
        (k, Slider(
            title=k if output_conc_unit is 1 else k + ' / ' + output_conc_unit.dimensionality.unicode,
            value=_C(k), **slider_kwargs.get(k, dict(start=_C(k)/2, end=_C(k)*2, step=_C(k)/10))))
        for k in rsys.substances])

    def _dict_to_unitless(d, u):
        return {k: to_unitless(v, u) for k, v in d.items()}

    param_widgets = OrderedDict([
        (k, Slider(title=k if u is None else k + ' / ' + u.dimensionality.unicode,
                   value=v, **_dict_to_unitless(
                       slider_kwargs.get(k, dict(start=v/10, end=v*10, step=v/10)),
                       u)))
        for k, v, u in zip(param_keys, p_ul, p_units)])
    all_widgets = list(chain(param_widgets.values(), c0_widgets.values()))

    def update_data(attrname, old, new):
        _c0 = defaultdict(lambda: 0*output_conc_unit)
        for k, w in c0_widgets.items():
            _c0[k] = w.value * output_conc_unit
        _params = {}
        for (k, w), u in zip(param_widgets.items(), p_units):
            _params[k] = w.value if u is None else w.value * u
        _tout, _Cout, _info = odesys.integrate(tout, _c0, _params)
        for idx, k in enumerate(rsys.substances):
            sources[idx].data = {
                'tout': to_unitless(_tout, output_time_unit),
                k: to_unitless(_Cout[:, idx], output_conc_unit)
            }

    for w in all_widgets:
        w.on_change('value', update_data)

    inputs = VBoxForm(children=all_widgets)
    return HBox(children=[inputs, plot], width=800)
Example #48
0
 def _check(r):
     res = r({'doserate': 0.15*u.gray/u.second,
              'density': 0.998*u.kg/u.decimetre**3,
              'temperature': 298.15*u.K})
     ref = 0.15*0.998*2.1e-7*u.molar/u.second
     assert abs(to_unitless((res - ref)/ref)) < 1e-15