def test_water_self_diffusion_coefficient__units():
    from chempy.units import allclose, linspace, default_units as u
    unit = u.m**2/u.s
    assert allclose(1e9*w_sd(298.15*u.K, units=u),
                    2.299*unit, rtol=1e-3, atol=1e-8*unit)
    assert allclose(1e9*w_sd(linspace(297, 299)*u.K, units=u),
                    2.299*u.m**2/u.s, rtol=5e-2, atol=1e-2*unit)
def test_water_density():
    warnings.filterwarnings("error")
    assert abs(water_density(273.15 + 0) - 999.8395) < 0.004
    assert abs(water_density(273.15 + 4) - 999.9720) < 0.003
    assert abs(water_density(273.15 + 10) - 999.7026) < 0.0003
    assert abs(water_density(273.15 + 15) - 999.1026) < 0.0001
    assert abs(water_density(273.15 + 20) - 998.2071) < 0.0005
    assert abs(water_density(273.15 + 22) - 997.7735) < 0.0007
    assert abs(water_density(273.15 + 25) - 997.0479) < 0.0009
    assert abs(water_density(273.15 + 30) - 995.6502) < 0.0016
    assert abs(water_density(273.15 + 40) - 992.2) < 0.02

    try:
        water_density(1)
    except UserWarning:
        pass  # good warning raised
    else:
        raise
    warnings.resetwarnings()

    try:
        import quantities as pq
        import numpy as np
        unit = pq.kg/pq.m**3
        assert allclose(water_density(298.15*pq.K, units=pq),
                        997.047021671824*unit, atol=1e-8*unit)
        assert allclose(water_density(np.linspace(297, 299)*pq.K, units=pq),
                        997*unit, rtol=1e-3, atol=1e-3*unit)
    except ImportError:
        pass
def test_water_self_diffusion_coefficient():
    warnings.filterwarnings("error")
    assert abs(w_sd(273.15 + 0.) - 1.099e-9) < 0.027e-9
    assert abs(w_sd(273.15 + 4.) - 1.261e-9) < 0.011e-9
    assert abs(w_sd(273.15 + 10) - 1.525e-9) < 0.007e-9
    assert abs(w_sd(273.15 + 15) - 1.765e-9) < 0.006e-9
    assert abs(w_sd(273.15 + 20) - 2.023e-9) < 0.001e-9
    assert abs(w_sd(273.15 + 25) - 2.299e-9) < 0.001e-9
    assert abs(w_sd(273.15 + 30) - 2.594e-9) < 0.001e-9
    assert abs(w_sd(273.15 + 35) - 2.907e-9) < 0.004e-9

    try:
        w_sd(1)
    except UserWarning:
        pass  # good warning raised
    else:
        raise
    warnings.resetwarnings()

    try:
        import quantities as pq
        import numpy as np
        unit = pq.m**2 / pq.s
        assert allclose(1e9 * w_sd(298.15 * pq.K, units=pq),
                        2.299 * unit,
                        rtol=1e-3,
                        atol=1e-8 * unit)
        assert allclose(1e9 * w_sd(np.linspace(297, 299) * pq.K, units=pq),
                        2.299 * pq.m**2 / pq.s,
                        rtol=5e-2,
                        atol=1e-2 * unit)
    except ImportError:
        pass
Example #4
0
def test_integrate_nondimensionalisation(from_rsys):
    from chempy import Reaction, ReactionSystem
    from chempy.units import allclose, default_units as u

    # 2A -> B
    if from_rsys:
        rxn = Reaction.from_string('2 A -> B; 2e-3*metre**3/mol/hour', None)
        rsys = ReactionSystem([rxn], 'A B')
        rd = ReactionDiffusion.from_ReactionSystem(rsys, unit_registry=SI_base_registry)
    else:
        rd = ReactionDiffusion.nondimensionalisation(
            2, [[0, 0]], [[1]], [2e-9/(umol/metre**3)/hour],
            unit_registry=SI_base_registry)
    C0 = [3*molar, 4*molar]
    tout = np.linspace(0, 1)*day
    integr = Integration(rd, C0, tout, integrator='scipy')

    k_m3_p_mol_p_sec = 2e-3/3600
    t_sec = np.linspace(0, 24*3600)
    C0_mol_p_m3 = [3000, 4000]
    Cref_mol_p_m3 = np.empty(integr.Cout.squeeze().shape)
    Cref_mol_p_m3[:, 0] = 1/(C0_mol_p_m3[0]**-1 + 2*k_m3_p_mol_p_sec*t_sec)
    missing_A = (C0_mol_p_m3[0] - Cref_mol_p_m3[:, 0])
    Cref_mol_p_m3[:, 1] = C0_mol_p_m3[1] + missing_A/2
    assert allclose(integr.with_units('tout'), t_sec*u.s)
    assert allclose(integr.with_units('Cout').squeeze(),
                    Cref_mol_p_m3*u.mol/u.metre**3, rtol=1e-6)
Example #5
0
def test_TPiecewise():
    expr0 = ShiftedTPoly(
        [273.15 * u.K, 10 / u.molar / u.s, 0.1 / u.molar / u.s / u.K])
    expr1 = ShiftedTPoly([
        298.15 * u.K,
        12.5 / u.molar / u.s,
        0 / u.molar / u.s / u.K,
        2 / u.molar / u.s / u.K**2,
    ])
    pwma = MassAction(
        TPiecewise([273.15 * u.K, expr0, 298.15 * u.K, expr1, 373.15 * u.K]))
    r = Reaction({"e-(aq)": 2}, {"H2": 1, "OH-": 2}, inact_reac={"H2O": 2})
    res0 = pwma({
        "temperature": 293.15 * u.K,
        "e-(aq)": 1e-13 * u.molar
    },
                reaction=r)
    ref0 = 12 * 1e-26 * u.molar / u.s
    assert allclose(res0, ref0)
    assert not allclose(res0, 2 * ref0)

    res1 = pwma({
        "temperature": 300.15 * u.K,
        "e-(aq)": 2e-13 * u.molar
    },
                reaction=r)
    ref1 = 20.5 * 4e-26 * u.molar / u.s
    assert allclose(res1, ref1)
    assert not allclose(res1, ref1 / 2)
Example #6
0
def test_Expr_dedimensionalisation__2():
    Poly = Expr.from_callback(_poly,
                              parameter_keys=('E', ),
                              argument_names=('x0', Ellipsis))
    T = Poly([3 * u.J, 7 * u.K, 5 * u.K / u.J])
    T = Poly([0.7170172084130019 * u.cal, 12.6 * u.Rankine, 5 * u.K / u.J])

    _ref = 0.8108020083055849  # Al at 273.15 K with R=8.3145
    cv_Al = _get_cv(u.kelvin, u.gram, u.mol)['Al']

    assert isinstance(cv_Al, EinsteinSolid)
    assert cv_Al.args[0] == 0.806 * 428 * u.kelvin
    assert abs(
        cv_Al({
            'temperature': 273.15 * u.K,
            'molar_gas_constant': 8.3145 * u.J / u.K / u.mol
        }) - _ref * u.J / u.gram / u.kelvin) < 1e-14

    cv_Al_units, Al_dedim = cv_Al.dedimensionalisation(SI_base_registry)
    assert allclose(cv_Al_units, [u.K, u.kg / u.mol])
    assert isinstance(Al_dedim, EinsteinSolid)
    T_units, dT = T.dedimensionalisation(SI_base_registry)
    assert allclose(T_units, [u.J, u.K, u.K / u.J])
    assert allclose(dT.args, [3, 7, 5])
    assert abs(
        Al_dedim({
            'temperature': 273.15,
            'molar_gas_constant': 8.3145
        }) - _ref * 1000) < 1e-14
    assert abs(
        Al_dedim({
            'temperature': dT,
            'E': (273.15 - 7) / 5 + 3,
            'molar_gas_constant': 8.3145
        }) - _ref * 1000) < 1e-14
Example #7
0
def test_integrate_nondimensionalisation__g_values(from_rsys):
    from chempy import Reaction, ReactionSystem
    from chempy.units import allclose, default_units as u
    rstr = "-> H + OH; Radiolytic({'radiolytic_yield': 2.1e-7*mol/J})"
    if from_rsys:
        rxn = Reaction.from_string(rstr, None)
        rsys = ReactionSystem([rxn], 'H OH')
        rd = ReactionDiffusion.from_ReactionSystem(
            rsys, unit_registry=SI_base_registry,
            variables=dict(doserate=0.15*u.Gy/u.s, density=0.998*u.kg/u.dm3))
        assert rd.g_value_parents == [-1]
        assert rd.g_values == [[2.1e-7]*2]
        assert abs(rd.fields[0][0] - 0.15*998) < 1e-14
    else:
        rd = ReactionDiffusion.nondimensionalisation(
            2, [[]], [[0, 1]], [2.1e-7*0.15*0.998*u.molar/u.second],
            unit_registry=SI_base_registry)
    C0 = [3*molar, 4*molar]
    tout = np.linspace(0, 1)*day
    integr = Integration(rd, C0, tout, integrator='scipy')
    k_m3_p_mol_p_sec = 0.15*998*2.1e-7
    t_sec = np.linspace(0, 24*3600)
    C0_mol_p_m3 = [3000, 4000]
    Cref_mol_p_m3 = np.empty(integr.Cout.squeeze().shape)
    Cref_mol_p_m3[:, 0] = C0_mol_p_m3[0] + k_m3_p_mol_p_sec*t_sec
    Cref_mol_p_m3[:, 1] = C0_mol_p_m3[1] + k_m3_p_mol_p_sec*t_sec
    print(integr.with_units('Cout').squeeze())
    print(integr.with_units('Cout').squeeze() - Cref_mol_p_m3*u.mole/u.metre**3)
    assert allclose(integr.with_units('tout'), t_sec*u.s)
    assert allclose(integr.with_units('Cout').squeeze(),
                    Cref_mol_p_m3*u.mole/u.metre**3)
Example #8
0
def test_water_density():
    warnings.filterwarnings("error")
    assert abs(water_density(273.15 + 0) - 999.8395) < 0.004
    assert abs(water_density(273.15 + 4) - 999.9720) < 0.003
    assert abs(water_density(273.15 + 10) - 999.7026) < 0.0003
    assert abs(water_density(273.15 + 15) - 999.1026) < 0.0001
    assert abs(water_density(273.15 + 20) - 998.2071) < 0.0005
    assert abs(water_density(273.15 + 22) - 997.7735) < 0.0007
    assert abs(water_density(273.15 + 25) - 997.0479) < 0.0009
    assert abs(water_density(273.15 + 30) - 995.6502) < 0.0016
    assert abs(water_density(273.15 + 40) - 992.2) < 0.02

    try:
        water_density(1)
    except UserWarning:
        pass  # good warning raised
    else:
        raise
    warnings.resetwarnings()

    try:
        import quantities as pq
        import numpy as np
        unit = pq.kg / pq.m**3
        assert allclose(water_density(298.15 * pq.K, units=pq),
                        997.047021671824 * unit,
                        atol=1e-8 * unit)
        assert allclose(water_density(np.linspace(297, 299) * pq.K, units=pq),
                        997 * unit,
                        rtol=1e-3,
                        atol=1e-3 * unit)
    except ImportError:
        pass
def test_water_self_diffusion_coefficient():
    warnings.filterwarnings("error")
    assert abs(w_sd(273.15 + 0.) - 1.099e-9) < 0.027e-9
    assert abs(w_sd(273.15 + 4.) - 1.261e-9) < 0.011e-9
    assert abs(w_sd(273.15 + 10) - 1.525e-9) < 0.007e-9
    assert abs(w_sd(273.15 + 15) - 1.765e-9) < 0.006e-9
    assert abs(w_sd(273.15 + 20) - 2.023e-9) < 0.001e-9
    assert abs(w_sd(273.15 + 25) - 2.299e-9) < 0.001e-9
    assert abs(w_sd(273.15 + 30) - 2.594e-9) < 0.001e-9
    assert abs(w_sd(273.15 + 35) - 2.907e-9) < 0.004e-9

    try:
        w_sd(1)
    except UserWarning:
        pass  # good warning raised
    else:
        raise
    warnings.resetwarnings()

    try:
        import quantities as pq
        import numpy as np
        unit = pq.m**2/pq.s
        assert allclose(1e9*w_sd(298.15*pq.K, units=pq),
                        2.299*unit, rtol=1e-3, atol=1e-8*unit)
        assert allclose(1e9*w_sd(np.linspace(297, 299)*pq.K, units=pq),
                        2.299*pq.m**2/pq.s, rtol=5e-2, atol=1e-2*unit)
    except ImportError:
        pass
def test_water_permittivity__units():
    assert allclose(water_permittivity(298.15 * u.K, 1 * u.bar, units=u),
                    78.38436874203077)
    assert allclose(
        water_permittivity(linspace(297.5, 298.65) * u.K, 1 * u.bar, units=u),
        78,
        rtol=1e-2,
        atol=1e-2,
    )
Example #11
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 #12
0
def test_MassAction__expression():
    class GibbsExpr(Expr):
        parameter_keys = ("temperature", )
        argument_names = tuple("dS_over_R dCp_over_R dH_over_R Tref".split())

        def __call__(self, variables, backend=patched_numpy, **kwargs):
            am = dict(
                zip(
                    self.argument_names,
                    map(simplified, self.all_args(variables, backend=backend)),
                ))
            (T, ) = self.all_params(variables, backend=backend)
            return (backend.exp(am["dS_over_R"]) *
                    (T / am["Tref"])**am["dCp_over_R"] *
                    backend.exp(-am["dH_over_R"] / T))

    GeNH3 = GibbsExpr(
        dict(
            dS_over_R=18.8 * u.cal / u.K / u.mol /
            default_constants.molar_gas_constant,  # NOQA
            dCp_over_R=52 * u.cal / u.K / u.mol /
            default_constants.molar_gas_constant,  # NOQA
            dH_over_R=-0.87e3 * u.cal / u.mol /
            default_constants.molar_gas_constant,  # NOQA
            Tref=298.15 * u.K,  # NOQA
        ))
    reac_prod = {"NH3": 1, "H2O": 1}, {"NH4+": 1, "OH-": 1}
    Equilibrium(*reac_prod, GeNH3).check_consistent_units(throw=True)
    Equilibrium(*reac_prod[::-1], 1 / GeNH3).check_consistent_units(throw=True)

    Ea = 40e3 * u.J / u.mol
    R = default_constants.molar_gas_constant
    A, Ea_over_R = 1.2e11 / u.molar**2 / u.second, Ea / R
    arrh = Arrhenius([A, Ea_over_R])
    ama = MassAction(arrh)

    ma_mul_expr = ama * GeNH3
    ma_div_expr = ama / GeNH3
    expr_mul_ma = GeNH3 * ama
    expr_div_ma = GeNH3 / ama
    assert all(
        isinstance(expr, MassAction)
        for expr in [ma_mul_expr, ma_div_expr, expr_mul_ma, expr_div_ma])

    Reaction(*reac_prod, ama).check_consistent_units(throw=True)
    Reaction(*reac_prod[::-1],
             42 * ma_div_expr).check_consistent_units(throw=True)
    Reaction(*reac_prod[::-1],
             42 / u.M / u.s / GeNH3).check_consistent_units(throw=True)

    varbls = {"temperature": 298.15 * u.K}
    r_ama, r_GeNH3 = ama.rate_coeff(varbls), GeNH3(varbls)
    assert allclose(ma_mul_expr.rate_coeff(varbls), r_ama * r_GeNH3)
    assert allclose(ma_div_expr.rate_coeff(varbls), r_ama / r_GeNH3)
    assert allclose(expr_mul_ma.rate_coeff(varbls), r_GeNH3 * r_ama)
    assert allclose(expr_div_ma.rate_coeff(varbls), r_GeNH3 / r_ama)
def test_water_self_diffusion_coefficient__units():
    from chempy.units import allclose, linspace, default_units as u
    unit = u.m**2 / u.s
    assert allclose(1e9 * w_sd(298.15 * u.K, units=u),
                    2.299 * unit,
                    rtol=1e-3,
                    atol=1e-8 * unit)
    assert allclose(1e9 * w_sd(linspace(297, 299) * u.K, units=u),
                    2.299 * u.m**2 / u.s,
                    rtol=5e-2,
                    atol=1e-2 * unit)
Example #14
0
def test_MassAction__rate_coeff():
    perMolar_perSecond = u.perMolar_perSecond

    p1 = MassAction(Constant(perMolar_perSecond) * 10**RTPoly([1, 2*u.kelvin, 3*u.kelvin**2]))
    rcoeff1 = p1.rate_coeff({'temperature': 283.15*u.K})
    ref1 = 10**(1 + 2/283.15 + 3/283.15**2) * perMolar_perSecond
    assert allclose(rcoeff1, ref1)
    rxn1 = Reaction({'A', 'B'}, {'C'}, p1)
    rat1 = rxn1.rate({'A': 2, 'B': 3, 'temperature': 283.15*u.K})
    assert allclose(rat1['A'], -2*3*ref1)
    assert allclose(rat1['B'], -2*3*ref1)
    assert allclose(rat1['C'], 2*3*ref1)
Example #15
0
def test_TPiecewise():
    expr0 = ShiftedTPoly([273.15*u.K, 10/u.molar/u.s, 0.1/u.molar/u.s/u.K])
    expr1 = ShiftedTPoly([298.15*u.K, 12.5/u.molar/u.s, 0/u.molar/u.s/u.K, 2/u.molar/u.s/u.K**2])
    pwma = MassAction(TPiecewise([273.15*u.K, expr0, 298.15*u.K, expr1, 373.15*u.K]))
    r = Reaction({'e-(aq)': 2}, {'H2': 1, 'OH-': 2}, inact_reac={'H2O': 2})
    res0 = pwma({'temperature': 293.15*u.K, 'e-(aq)': 1e-13*u.molar}, reaction=r)
    ref0 = 12*1e-26 * u.molar/u.s
    assert allclose(res0, ref0)
    assert not allclose(res0, 2*ref0)

    res1 = pwma({'temperature': 300.15*u.K, 'e-(aq)': 2e-13*u.molar}, reaction=r)
    ref1 = 20.5*4e-26 * u.molar/u.s
    assert allclose(res1, ref1)
    assert not allclose(res1, ref1/2)
Example #16
0
def test_MassAction__rate_coeff():
    perMolar_perSecond = u.perMolar_perSecond

    p1 = MassAction(
        Constant(perMolar_perSecond) *
        10**RTPoly([1, 2 * u.kelvin, 3 * u.kelvin**2]))
    rcoeff1 = p1.rate_coeff({"temperature": 283.15 * u.K})
    ref1 = 10**(1 + 2 / 283.15 + 3 / 283.15**2) * perMolar_perSecond
    assert allclose(rcoeff1, ref1)
    rxn1 = Reaction({"A", "B"}, {"C"}, p1)
    rat1 = rxn1.rate({"A": 2, "B": 3, "temperature": 283.15 * u.K})
    assert allclose(rat1["A"], -2 * 3 * ref1)
    assert allclose(rat1["B"], -2 * 3 * ref1)
    assert allclose(rat1["C"], 2 * 3 * ref1)
Example #17
0
def test_ShiftedTPoly__units():
    stp1 = ShiftedTPoly([273.15*u.kelvin, 5, 7/u.kelvin])
    allclose(stp1({'temperature': 274.15*u.kelvin}), 5+7)
    allclose(stp1({'temperature': 273.15*u.kelvin}), 5)
    stp2 = ShiftedTPoly([273.15*u.kelvin, 5*u.m, 7*u.m/u.kelvin, 13*u.m*u.kelvin**-2])
    allclose(stp2({'temperature': 274.15*u.kelvin}), (5+7+13)*u.m)
    allclose(stp2({'temperature': 273.15*u.kelvin}), 5*u.m)
Example #18
0
def test_decompose_yields__units_1():
    from chempy import Reaction
    from chempy.units import default_units as u
    gamma_yields = {
        'OH-': 0.5*u.per100eV,
        'H2O2': 0.7*u.per100eV,
        'OH': 2.7*u.per100eV,
        'H2': 0.45*u.per100eV,
        'H': 0.66*u.per100eV,
        'H+': 3.1*u.per100eV,
        'HO2': 0.02*u.per100eV,
        'e-(aq)': 2.6*u.per100eV,
    }

    rxns = [
        Reaction({'H2O': 1}, {'H+': 1, 'OH-': 1}),
        Reaction({'H2O': 1}, {'H+': 1, 'e-(aq)': 1, 'OH': 1}),
        Reaction({'H2O': 1}, {'H': 2, 'H2O2': 1}, inact_reac={'H2O': 1}),
        Reaction({'H2O': 1}, {'H2': 1, 'H2O2': 1}, inact_reac={'H2O': 1}),
        Reaction({'H2O': 1}, {'H2': 1, 'OH': 2}, inact_reac={'H2O': 1}),
        Reaction({'H2O': 1}, {'H2': 3, 'HO2': 2}, inact_reac={'H2O': 3}),
    ]

    k = decompose_yields(gamma_yields, rxns)
    k_ref = [0.5, 2.6, 0.33, 0.37, 0.05, 0.01]*u.per100eV

    assert allclose(k, k_ref)

    G_H2O = [rxn.net_stoich(['H2O'])[0]*k[i] for i, rxn in enumerate(rxns)]
    ref = 4.64*u.per100eV
    assert abs((_sum(G_H2O)+ref)/ref) < 1e-3
Example #19
0
def test_create_odesys__ShiftedTPoly():
    rxn = Reaction({'A': 1, 'B': 1}, {'C': 3, 'D': 2}, 'k_bi', {'A': 3})
    rsys = ReactionSystem([rxn], 'A B C D')

    _k0, _k1, T0C = 10, 2, 273.15
    rate = MassAction(ShiftedTPoly([T0C*u.K, _k0/u.molar/u.s, _k1/u.molar/u.s/u.K]))
    T_C = 25
    T = (T0C+T_C)*u.kelvin
    p1 = rate.rate_coeff({'temperature': T})
    assert allclose(p1, (_k0 + _k1*T_C)/u.molar/u.s)

    odesys, odesys_extra = create_odesys(rsys)
    ics = {'A': 3*u.molar, 'B': 5*u.molar, 'C': 11*u.molar, 'D': 13*u.molar}
    pars = dict(k_bi=p1)
    validation = odesys_extra['validate'](dict(ics, **pars))
    assert set(map(str, validation['not_seen'])) == {'C', 'D'}

    dedim_ctx = _mk_dedim(SI_base_registry)
    (t, c, _p), dedim_extra = dedim_ctx['dedim_tcp'](-37*u.s, [ics[k] for k in odesys.names], pars)
    fout = odesys.f_cb(t, c, [_p[pk] for pk in odesys.param_names])
    r = 3*5*(_k0 + _k1*25)*1000  # mol/m3/s
    ref = [-4*r, -r, 3*r, 2*r]
    assert np.all(abs((fout - ref)/ref) < 1e-14)

    odesys.integrate(t, c, _p)
Example #20
0
def test_get_native__conc_roots():
    M, s = u.M, u.s
    rsys = ReactionSystem.from_string("2 O3 -> 3 O2; 'k2'")
    u_reg = SI_base_registry.copy()
    odesys, extra = get_odesys(rsys, include_params=False, unit_registry=u_reg)
    c0 = {"O3": 4.2e-3 * M, "O2": 0 * M}
    cr = ["O2"]
    native = get_native(rsys, odesys, "cvode", conc_roots=cr)
    tend = 1e5 * u.s
    params = {"k2": logspace_from_lin(1e-3 / M / s, 1e3 / M / s, 14)}
    tgt_O2 = 1e-3 * M
    results = native.integrate(
        tend,
        c0,
        params,
        integrator="native",
        return_on_root=True,
        special_settings=[unitless_in_registry(tgt_O2, u_reg)],
    )
    assert len(results) == params["k2"].size
    # dydt = -p*y**2
    # 1/y0 - 1/y = -2*pt
    # t = 1/2/p*(1/y - 1/y0)
    tgt_O3 = c0["O3"] - 2 / 3 * tgt_O2
    for r in results:
        ref = rescale(
            1 / 2 / r.named_param("k2") * (1 / tgt_O3 - 1 / c0["O3"]), u.s)
        assert allclose(r.xout[-1], ref, rtol=1e-6)
Example #21
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 #22
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 #23
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 #24
0
def test_Expr__single_arg__units():
    p = Pressure1(3 * u.mol)
    variables = {
        'temperature': 273.15 * u.kelvin,
        'volume': 170 * u.dm3,
        'R': 8.314 * u.J / u.K / u.mol
    }
    assert allclose(p(variables), 3 * 8.314 * 273.15 / 0.17 * u.Pa)
Example #25
0
def test_Expr__single_arg__units():
    p = Pressure1(3 * u.mol)
    variables = {
        "temperature": 273.15 * u.kelvin,
        "volume": 170 * u.dm3,
        "R": 8.314 * u.J / u.K / u.mol,
    }
    assert allclose(p(variables), 3 * 8.314 * 273.15 / 0.17 * u.Pa)
Example #26
0
def test_MassAction__expression():
    class GibbsExpr(Expr):
        parameter_keys = ('temperature', )
        argument_names = tuple("dS_over_R dCp_over_R dH_over_R Tref".split())

        def __call__(self, variables, backend=patched_numpy, **kwargs):
            am = dict(
                zip(self.argument_names,
                    map(simplified, self.all_args(variables,
                                                  backend=backend))))
            T, = self.all_params(variables, backend=backend)
            return backend.exp(am['dS_over_R']) * (
                T / am['Tref'])**am['dCp_over_R'] * backend.exp(
                    -am['dH_over_R'] / T)

    GeNH3 = GibbsExpr(
        dict(
            dS_over_R=18.8 * u.cal / u.K / u.mol /
            default_constants.molar_gas_constant,  # NOQA
            dCp_over_R=52 * u.cal / u.K / u.mol /
            default_constants.molar_gas_constant,  # NOQA
            dH_over_R=-0.87e3 * u.cal / u.mol /
            default_constants.molar_gas_constant,  # NOQA
            Tref=298.15 * u.K  # NOQA
        ))
    Ea = 40e3 * u.J / u.mol
    R = default_constants.molar_gas_constant
    A, Ea_over_R = 1.2e11 / u.molar**2 / u.second, Ea / R
    arrh = Arrhenius([A, Ea_over_R])
    ama = MassAction(arrh)

    ma_mul_expr = ama * GeNH3
    ma_div_expr = ama / GeNH3
    expr_mul_ma = GeNH3 * ama
    expr_div_ma = GeNH3 / ama
    assert all(
        isinstance(expr, MassAction)
        for expr in [ma_mul_expr, ma_div_expr, expr_mul_ma, expr_div_ma])

    varbls = {'temperature': 298.15 * u.K}
    r_ama, r_GeNH3 = ama.rate_coeff(varbls), GeNH3(varbls)
    assert allclose(ma_mul_expr.rate_coeff(varbls), r_ama * r_GeNH3)
    assert allclose(ma_div_expr.rate_coeff(varbls), r_ama / r_GeNH3)
    assert allclose(expr_mul_ma.rate_coeff(varbls), r_GeNH3 * r_ama)
    assert allclose(expr_div_ma.rate_coeff(varbls), r_GeNH3 / r_ama)
Example #27
0
def test_MassAction__subclass_from_callback__units():
    def rate_coeff(variables, all_args, backend):
        return all_args[0]*backend.exp(all_args[1]/variables['temperature'])
    CustomMassAction = MassAction.subclass_from_callback(
        rate_coeff, cls_attrs=dict(parameter_keys=('temperature',), nargs=2))
    k1 = CustomMassAction([2.1e10/u.molar**2/u.second, -5132.2*u.kelvin], rxn=Reaction({'H2': 2, 'O2': 1}, {'H2O': 2}))
    res = k1({'temperature': 491.67*u.rankine, 'H2': 7000*u.mol/u.metre**3, 'O2': 13*u.molar}, backend=Backend())
    ref = 7*7*13*2.1e10*math.exp(-5132.2/273.15) * u.molar/u.second
    assert allclose(res, ref)
Example #28
0
def test_EyringParamWithUnits():
    mol = u.mol
    J = u.joule
    K = u.kelvin
    T = 273.15*K
    k = EyringParamWithUnits(42e3 * J/mol, 123*J/mol/K)(T)
    ref = _kB_over_h * 273.15 * math.exp(123/_R) * math.exp(-42e3/_R/273.15)
    ref /= u.second
    assert allclose(k, ref)
Example #29
0
def test_GibbsEqConst__units():
    R, T = dc.molar_gas_constant, 298.15 * du.K
    DH = -4e3 * du.J / du.mol
    DS = 16 * du.J / du.K / du.mol
    be = Backend()
    gee = GibbsEqConst([DH / R, DS / R])
    res = gee.eq_const({'temperature': T}, backend=be)
    ref = be.exp(-(DH - T * DS) / (R * T))
    assert allclose(res, ref)
Example #30
0
def test_GibbsEquilibriumConstant__units():
    R, T = dc.molar_gas_constant, 298.15*du.K
    DH = -4e3 * du.J/du.mol
    DS = 16 * du.J/du.K/du.mol
    be = Backend()
    gee = GibbsEquilibriumConstant([DH/R, DS/R])
    res = gee({'temperature': T}, backend=be)
    ref = be.exp(-(DH - T*DS)/(R*T))
    assert allclose(res, ref)
Example #31
0
def test_Expr__single_arg__units__dimensionality():
    p = Pressure2(unique_keys=("n1", ))
    variables = {
        "temperature": 273.15 * u.kelvin,
        "volume": 170 * u.dm3,
        "R": 8.314 * u.J / u.K / u.mol,
    }
    assert allclose(p(dict(n1=3 * u.mol, **variables)),
                    3 * 8.314 * 273.15 / 0.17 * u.Pa)
Example #32
0
def test_MassAction__subclass_from_callback__units():
    def rate_coeff(variables, all_args, backend):
        return all_args[0]*backend.exp(all_args[1]/variables['temperature'])
    CustomMassAction = MassAction.subclass_from_callback(
        rate_coeff, cls_attrs=dict(parameter_keys=('temperature',), nargs=2))
    k1 = CustomMassAction([2.1e10/u.molar**2/u.second, -5132.2*u.kelvin], rxn=Reaction({'H2': 2, 'O2': 1}, {'H2O': 2}))
    res = k1({'temperature': 491.67*u.rankine, 'H2': 7000*u.mol/u.metre**3, 'O2': 13*u.molar}, backend=Backend())
    ref = 7*7*13*2.1e10*math.exp(-5132.2/273.15) * u.molar/u.second
    assert allclose(res, ref)
Example #33
0
def test_Expr__single_arg__units__dimensionality():
    p = Pressure2(unique_keys=('n1', ))
    variables = {
        'temperature': 273.15 * u.kelvin,
        'volume': 170 * u.dm3,
        'R': 8.314 * u.J / u.K / u.mol
    }
    assert allclose(p(dict(n1=3 * u.mol, **variables)),
                    3 * 8.314 * 273.15 / 0.17 * u.Pa)
Example #34
0
def test_TPiecewise():
    expr0 = TPolyMassAction(
        [273.15 * u.K, 10 / u.molar / u.s, 0.1 / u.molar / u.s / u.K])
    expr1 = TPolyMassAction([
        298.15 * u.K, 12.5 / u.molar / u.s, 0 / u.molar / u.s / u.K,
        2 / u.molar / u.s / u.K**2
    ])
    pw = TPiecewise(
        [273.15 * u.K, 298.15 * u.K, expr0, 298.15 * u.K, 373.15 * u.K, expr1])
    Reaction({'e-(aq)': 2}, {'H2': 1, 'OH-': 2}, pw, {'H2O': 2})
    res0 = pw({'temperature': 293.15 * u.K, 'e-(aq)': 1e-13 * u.molar})
    ref0 = 12 * 1e-26 * u.molar / u.s
    assert allclose(res0, ref0)
    assert not allclose(res0, 2 * ref0)

    res1 = pw({'temperature': 300.15 * u.K, 'e-(aq)': 2e-13 * u.molar})
    ref1 = 20.5 * 4e-26 * u.molar / u.s
    assert allclose(res1, ref1)
    assert not allclose(res1, ref1 / 2)
Example #35
0
def test_ArrheniusParamWithUnits():
    _2 = _get_ref2_units()
    ap = ArrheniusParamWithUnits(_2.A, _2.Ea)

    k = ap(_2.T)
    assert abs((k - _2.k)/_2.k) < 1e-4

    r = Reaction({'H2O2': 1}, {'OH': 2}, ap)
    ratc = r.rate_expr().rate_coeff({'temperature': _2.T})
    assert allclose(ratc, _2.k, rtol=1e-4)
Example #36
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 #37
0
def test_Expr_dedimensionalisation__2():
    Poly = Expr.from_callback(_poly, parameter_keys=('E',), argument_names=('x0', Ellipsis))
    T = Poly([3*u.J, 7*u.K, 5*u.K/u.J])
    T = Poly([0.7170172084130019*u.cal, 12.6*u.Rankine, 5*u.K/u.J])

    _ref = 0.8108020083055849  # Al at 273.15 K with R=8.3145
    cv_Al = _get_cv(u.kelvin, u.gram, u.mol)['Al']

    assert isinstance(cv_Al, EinsteinSolid)
    assert cv_Al.args[0] == 0.806*428*u.kelvin
    assert abs(cv_Al({'temperature': 273.15*u.K, 'molar_gas_constant': 8.3145*u.J/u.K/u.mol}) -
               _ref*u.J/u.gram/u.kelvin) < 1e-14

    cv_Al_units, Al_dedim = cv_Al.dedimensionalisation(SI_base_registry)
    assert allclose(cv_Al_units, [u.K, u.kg/u.mol])
    assert isinstance(Al_dedim, EinsteinSolid)
    T_units, dT = T.dedimensionalisation(SI_base_registry)
    assert allclose(T_units, [u.J, u.K, u.K/u.J])
    assert allclose(dT.args, [3, 7, 5])
    assert abs(Al_dedim({'temperature': 273.15, 'molar_gas_constant': 8.3145}) - _ref*1000) < 1e-14
    assert abs(Al_dedim({'temperature': dT, 'E': (273.15-7)/5 + 3, 'molar_gas_constant': 8.3145}) - _ref*1000) < 1e-14
Example #38
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 #39
0
def test_Expr__single_arg__units():

    class Pressure(Expr):
        argument_names = ('n',)
        parameter_keys = ('temperature', 'volume', 'R')

        def __call__(self, variables, backend=None):
            n, = self.all_args(variables, backend=backend)
            T, V, R = self.all_params(variables, backend=backend)
            return n*R*T/V
    p = Pressure(3*u.mol)
    variables = {'temperature': 273.15*u.kelvin, 'volume': 170*u.dm3, 'R': 8.314*u.J/u.K/u.mol}
    assert allclose(p(variables), 3*8.314*273.15/0.17*u.Pa)
Example #40
0
def test_decompose_yields__units_1():
    from chempy import Reaction
    from chempy.units import default_units as u

    gamma_yields = {
        "OH-": 0.5 * u.per100eV,
        "H2O2": 0.7 * u.per100eV,
        "OH": 2.7 * u.per100eV,
        "H2": 0.45 * u.per100eV,
        "H": 0.66 * u.per100eV,
        "H+": 3.1 * u.per100eV,
        "HO2": 0.02 * u.per100eV,
        "e-(aq)": 2.6 * u.per100eV,
    }

    rxns = [
        Reaction({"H2O": 1}, {
            "H+": 1,
            "OH-": 1
        }),
        Reaction({"H2O": 1}, {
            "H+": 1,
            "e-(aq)": 1,
            "OH": 1
        }),
        Reaction({"H2O": 1}, {
            "H": 2,
            "H2O2": 1
        }, inact_reac={"H2O": 1}),
        Reaction({"H2O": 1}, {
            "H2": 1,
            "H2O2": 1
        }, inact_reac={"H2O": 1}),
        Reaction({"H2O": 1}, {
            "H2": 1,
            "OH": 2
        }, inact_reac={"H2O": 1}),
        Reaction({"H2O": 1}, {
            "H2": 3,
            "HO2": 2
        }, inact_reac={"H2O": 3}),
    ]

    k = decompose_yields(gamma_yields, rxns)
    k_ref = [0.5, 2.6, 0.33, 0.37, 0.05, 0.01] * u.per100eV

    assert allclose(k, k_ref)

    G_H2O = [rxn.net_stoich(["H2O"])[0] * k[i] for i, rxn in enumerate(rxns)]
    ref = 4.64 * u.per100eV
    assert abs((_sum(G_H2O) + ref) / ref) < 1e-3
Example #41
0
def test_decompose_yields__units_1():
    from chempy import Reaction
    from chempy.units import default_units as u
    gamma_yields = {
        'OH-': 0.5 * u.per100eV,
        'H2O2': 0.7 * u.per100eV,
        'OH': 2.7 * u.per100eV,
        'H2': 0.45 * u.per100eV,
        'H': 0.66 * u.per100eV,
        'H+': 3.1 * u.per100eV,
        'HO2': 0.02 * u.per100eV,
        'e-(aq)': 2.6 * u.per100eV,
    }

    rxns = [
        Reaction({'H2O': 1}, {
            'H+': 1,
            'OH-': 1
        }),
        Reaction({'H2O': 1}, {
            'H+': 1,
            'e-(aq)': 1,
            'OH': 1
        }),
        Reaction({'H2O': 1}, {
            'H': 2,
            'H2O2': 1
        }, inact_reac={'H2O': 1}),
        Reaction({'H2O': 1}, {
            'H2': 1,
            'H2O2': 1
        }, inact_reac={'H2O': 1}),
        Reaction({'H2O': 1}, {
            'H2': 1,
            'OH': 2
        }, inact_reac={'H2O': 1}),
        Reaction({'H2O': 1}, {
            'H2': 3,
            'HO2': 2
        }, inact_reac={'H2O': 3}),
    ]

    k = decompose_yields(gamma_yields, rxns)
    k_ref = [0.5, 2.6, 0.33, 0.37, 0.05, 0.01] * u.per100eV

    assert allclose(k, k_ref)

    G_H2O = [rxn.net_stoich(['H2O'])[0] * k[i] for i, rxn in enumerate(rxns)]
    ref = 4.64 * u.per100eV
    assert abs((_sum(G_H2O) + ref) / ref) < 1e-3
Example #42
0
def test_ArrheniusParamWithUnits():
    s = u.second
    mol = u.mol
    J = u.joule
    K = u.kelvin
    act_J__mol = 42e3
    ap = ArrheniusParamWithUnits(1e10 / s, act_J__mol * J / mol)
    freezing_K = 273.15
    k = ap(freezing_K * K)
    ref = 1e10 / s * math.exp(-act_J__mol / (8.3145 * freezing_K))
    assert abs((k - ref) / ref) < 1e-4

    r = Reaction({'H2O2': 1}, {'OH': 2}, ap)
    ratc = r.rate_expr().rate_coeff({'temperature': freezing_K * u.K})
    assert allclose(ratc, ref, rtol=1e-4)
Example #43
0
def test_get_odesys__time_dep_temperature():
    import sympy as sp

    def refA(t, A0, A, Ea_over_R, T0, dTdt):
        T = (T0 + dTdt * t)
        d_Ei = sp.Ei(-Ea_over_R / T0).n(100).round(90) - sp.Ei(
            -Ea_over_R / T).n(100).round(90)
        d_Texp = T0 * sp.exp(-Ea_over_R / T0) - T * sp.exp(-Ea_over_R / T)
        return A0 * sp.exp(A / dTdt * (Ea_over_R * d_Ei + d_Texp)).n(30)

    params = A0, A, Ea_over_R, T0, dTdt = [13, 1e10, 56e3 / 8, 273, 2]
    B0 = 11
    rate = MassAction(Arrhenius([A, Ea_over_R]))
    rxn = Reaction({'A': 1}, {'B': 3}, rate)
    rsys = ReactionSystem([rxn], 'A B')
    rt = RampedTemp([T0, dTdt], ('init_temp', 'ramp_rate'))
    odesys, extra = get_odesys(rsys, False, substitutions={'temperature': rt})
    all_pk, unique, p_units = map(extra.get,
                                  'param_keys unique p_units'.split())
    conc = {'A': A0, 'B': B0}
    tout = [2, 5, 10]

    for ramp_rate in [2, 3, 4]:
        unique['ramp_rate'] = ramp_rate
        xout, yout, info = odesys.integrate(10,
                                            conc,
                                            unique,
                                            atol=1e-10,
                                            rtol=1e-12)
        params[-1] = ramp_rate
        Aref = np.array([float(refA(t, *params)) for t in xout])
        # Aref = 1/(1/13 + 2*1e-6*t_unitless)
        yref = np.zeros((xout.size, 2))
        yref[:, 0] = Aref
        yref[:, 1] = B0 + 3 * (A0 - Aref)
        assert allclose(yout, yref)

    unique['ramp_rate'] = 2
    x, y, p = odesys.to_arrays(tout, conc, unique)
    fout = odesys.f_cb(x, y, p)

    def r(t):
        return A * np.exp(-Ea_over_R /
                          (T0 + dTdt * t)) * A0  # refA(t, *params)

    ref = np.array([[-r(2), -r(5), -r(10)], [3 * r(2), 3 * r(5), 3 * r(10)]]).T
    assert np.allclose(fout, ref)
Example #44
0
def test_Expr__single_arg__units():
    class Pressure(Expr):
        argument_names = ('n', )
        parameter_keys = ('temperature', 'volume', 'R')

        def __call__(self, variables, backend=None):
            n, = self.all_args(variables, backend=backend)
            T, V, R = self.all_params(variables, backend=backend)
            return n * R * T / V

    p = Pressure(3 * u.mol)
    variables = {
        'temperature': 273.15 * u.kelvin,
        'volume': 170 * u.dm3,
        'R': 8.314 * u.J / u.K / u.mol
    }
    assert allclose(p(variables), 3 * 8.314 * 273.15 / 0.17 * u.Pa)
Example #45
0
def test_create_odesys__validate__catalyst():
    rsys1 = ReactionSystem.from_string("""
    H2O2 + Pt -> 2 OH + Pt; 'k_decomp'
    """)
    ic1 = defaultdict(lambda: 0*u.molar, {'H2O2': 3.0*u.molar, 'Pt': 0.5*u.molar})
    t1 = linspace(0*u.s, .3*u.s, 7)
    p1 = dict(k_decomp=42/u.second/u.molar)
    odesys1, odesys_extra = create_odesys(rsys1)
    validation = odesys_extra['validate'](dict(ic1, **p1))
    assert not validation['not_seen']

    dedim_ctx = _mk_dedim(SI_base_registry)
    (t, c, _p), dedim_extra = dedim_ctx['dedim_tcp'](t1, [ic1[k] for k in odesys1.names], p1)
    result1 = odesys1.integrate(t, c, _p)
    tout = result1.xout * dedim_extra['unit_time']
    cout = result1.yout * dedim_extra['unit_conc']
    yref1 = ic1['H2O2']*np.exp(-tout*ic1['Pt']*p1['k_decomp'])
    assert allclose(yref1, cout[:, odesys1.names.index('H2O2')], rtol=1e-6)
Example #46
0
def test_get_odesys__time_dep_temperature():
    import sympy as sp

    def refA(t, A0, A, Ea_over_R, T0, dTdt):
        T = (T0 + dTdt*t)
        d_Ei = sp.Ei(-Ea_over_R/T0).n(100).round(90) - sp.Ei(-Ea_over_R/T).n(100).round(90)
        d_Texp = T0*sp.exp(-Ea_over_R/T0) - T*sp.exp(-Ea_over_R/T)
        return A0*sp.exp(A/dTdt*(Ea_over_R*d_Ei + d_Texp)).n(30)

    params = A0, A, Ea_over_R, T0, dTdt = [13, 1e10, 56e3/8, 273, 2]
    B0 = 11
    rate = MassAction(Arrhenius([A, Ea_over_R]))
    rxn = Reaction({'A': 1}, {'B': 3}, rate)
    rsys = ReactionSystem([rxn], 'A B')
    rt = RampedTemp([T0, dTdt], ('init_temp', 'ramp_rate'))
    odesys, extra = get_odesys(rsys, False, substitutions={'temperature': rt})
    all_pk, unique, p_units = map(extra.get, 'param_keys unique p_units'.split())
    conc = {'A': A0, 'B': B0}
    tout = [2, 5, 10]

    for ramp_rate in [2, 3, 4]:
        unique['ramp_rate'] = ramp_rate
        xout, yout, info = odesys.integrate(10, conc, unique, atol=1e-10, rtol=1e-12)
        params[-1] = ramp_rate
        Aref = np.array([float(refA(t, *params)) for t in xout])
        # Aref = 1/(1/13 + 2*1e-6*t_unitless)
        yref = np.zeros((xout.size, 2))
        yref[:, 0] = Aref
        yref[:, 1] = B0 + 3*(A0-Aref)
        assert allclose(yout, yref)

    unique['ramp_rate'] = 2
    x, y, p = odesys.to_arrays(tout, conc, unique)
    fout = odesys.f_cb(x, y, p)

    def r(t):
        return A*np.exp(-Ea_over_R/(T0 + dTdt*t))*A0  # refA(t, *params)

    ref = np.array([
        [-r(2), -r(5), -r(10)],
        [3*r(2), 3*r(5), 3*r(10)]
    ]).T
    assert np.allclose(fout, ref)
Example #47
0
def test_get_native__conc_roots():
    M, s = u.M, u.s
    rsys = ReactionSystem.from_string("2 O3 -> 3 O2; 'k2'")
    u_reg = SI_base_registry.copy()
    odesys, extra = get_odesys(rsys, include_params=False, unit_registry=u_reg)
    c0 = {'O3': 4.2e-3*M, 'O2': 0*M}
    cr = ['O2']
    native = get_native(rsys, odesys, 'cvode', conc_roots=cr)
    tend = 1e5*u.s
    params = {'k2': logspace_from_lin(1e-3/M/s, 1e3/M/s, 14)}
    tgt_O2 = 1e-3*M
    results = native.integrate(tend, c0, params, integrator='native', return_on_root=True,
                               special_settings=[unitless_in_registry(tgt_O2, u_reg)])
    assert len(results) == params['k2'].size
    # dydt = -p*y**2
    # 1/y0 - 1/y = -2*pt
    # t = 1/2/p*(1/y - 1/y0)
    tgt_O3 = c0['O3'] - 2/3 * tgt_O2
    for r in results:
        ref = rescale(1/2/r.named_param('k2')*(1/tgt_O3 - 1/c0['O3']), u.s)
        assert allclose(r.xout[-1], ref, rtol=1e-6)
Example #48
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 #49
0
def test_eval_template():
    rendered = eval_template("${2*pi*arg*m**2}", arg=1/math.pi)
    val = eval(rendered, get_parsing_context())
    assert allclose(val, 2*u.m**2)
Example #50
0
def test_Expr__single_arg__units():
    p = Pressure1(3*u.mol)
    variables = {'temperature': 273.15*u.kelvin, 'volume': 170*u.dm3, 'R': 8.314*u.J/u.K/u.mol}
    assert allclose(p(variables), 3*8.314*273.15/0.17*u.Pa)
Example #51
0
def test_Expr__single_arg__units__dimensionality():
    p = Pressure2(unique_keys=('n1',))
    variables = {'temperature': 273.15*u.kelvin, 'volume': 170*u.dm3, 'R': 8.314*u.J/u.K/u.mol}
    assert allclose(p(dict(n1=3*u.mol, **variables)), 3*8.314*273.15/0.17*u.Pa)
Example #52
0
def test_ArrheniusParamWithUnits__from_rateconst_at_T():
    _2 = _get_ref2_units()
    apu = ArrheniusParamWithUnits.from_rateconst_at_T(_2.Ea, (_2.T, _2.k))
    assert allclose(apu(_2.T), _2.k)
Example #53
0
def test_eval_template__Reaction():
    rendered = eval_template("2 OH -> H2O2; ${6*pi*arg}/M/s", arg=1/math.pi)
    assert allclose(Reaction.from_string(rendered).param,
                    Reaction.from_string("2 OH -> H2O2; 6.0/M/s").param)
Example #54
0
def test_nernst_potential__units():
    J = default_units.joule
    K = default_units.kelvin
    coulomb = default_units.coulomb
    v = nernst_potential(145, 15, 1, 310*K, default_constants)
    assert allclose(1000 * v, 60.605*J/coulomb, rtol=1e-4)