コード例 #1
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_get_odesys__Eyring():
    R = 8.314472
    T_K = 300
    dH = 80e3
    dS = 10
    rsys1 = ReactionSystem.from_string("""
    NOBr -> NO + Br; EyringParam(dH={dH}*J/mol, dS={dS}*J/K/mol)
    """.format(dH=dH, dS=dS), substances='NOBr NO Br'.split())
    kref = 20836643994.118652*T_K*np.exp(-(dH - T_K*dS)/(R*T_K))
    NOBr0_M = 0.7
    init_cond = dict(
        NOBr=NOBr0_M*u.M,
        NO=0*u.M,
        Br=0*u.M
    )
    t = 5*u.second
    params = dict(
        temperature=T_K*u.K
    )

    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)
    check(rsys1)
    rsys2 = ReactionSystem.from_string("""
    NOBr -> NO + Br; MassAction(EyringHS([{dH}*J/mol, {dS}*J/K/mol]))
    """.format(dH=dH, dS=dS), substances='NOBr NO Br'.split())
    check(rsys2)
コード例 #2
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_get_odesys__Eyring_2nd_order_reversible():
    R = 8.314472
    T_K = 273.15 + 20  # 20 degree celsius
    kB = 1.3806504e-23
    h = 6.62606896e-34

    dHf = 74e3
    dSf = R*np.log(h/kB/T_K*1e16)

    dHb = 79e3
    dSb = dSf - 23

    rsys1 = ReactionSystem.from_string("""
    Fe+3 + SCN- -> FeSCN+2; EyringParam(dH={dHf}*J/mol, dS={dSf}*J/K/mol)
    FeSCN+2 -> Fe+3 + SCN-; EyringParam(dH={dHb}*J/mol, dS={dSb}*J/K/mol)
    """.format(dHf=dHf, dSf=dSf, dHb=dHb, dSb=dSb))
    kf_ref = 20836643994.118652*T_K*np.exp(-(dHf - T_K*dSf)/(R*T_K))
    kb_ref = 20836643994.118652*T_K*np.exp(-(dHb - T_K*dSb)/(R*T_K))
    Fe0 = 6e-3
    SCN0 = 2e-3
    init_cond = {
        'Fe+3': Fe0*u.M,
        'SCN-': SCN0*u.M,
        'FeSCN+2': 0*u.M
    }
    t = 3*u.second

    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)

    check(rsys1, {'temperature': T_K*u.K})
    rsys2 = ReactionSystem.from_string("""
    Fe+3 + SCN- -> FeSCN+2; MassAction(EyringHS([{dHf}*J/mol, {dSf}*J/K/mol]))
    FeSCN+2 -> Fe+3 + SCN-; MassAction(EyringHS([{dHb}*J/mol, {dSb}*J/K/mol]))
    """.format(dHf=dHf, dSf=dSf, dHb=dHb, dSb=dSb))
    check(rsys2, {'temperature': T_K*u.K})
    rsys3 = ReactionSystem.from_string("""
    Fe+3 + SCN- -> FeSCN+2; MassAction(EyringHS.fk('dHf', 'dSf'))
    FeSCN+2 -> Fe+3 + SCN-; MassAction(EyringHS.fk('dHb', 'dSb'))
    """)
    check(rsys3, dict(temperature=T_K*u.K,
                      dHf=dHf*u.J/u.mol, dSf=dSf*u.J/u.mol/u.K,
                      dHb=dHb*u.J/u.mol, dSb=dSb*u.J/u.mol/u.K))
コード例 #3
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_get_odesys__Eyring_1st_order_linearly_ramped_temperature():
    from scipy.special import expi

    def analytic_unit0(t, T0, dH, dS):
        R = 8.314472
        kB = 1.3806504e-23
        h = 6.62606896e-34
        A = kB/h*np.exp(dS/R)
        B = dH/R
        return np.exp(A*(
            (-B**2*np.exp(B/T0)*expi(-B/T0) - T0*(B - T0))*np.exp(-B/T0) +
            (B**2*np.exp(B/(t + T0))*expi(-B/(t + T0)) - (t + T0)*(-B + t + T0))*np.exp(-B/(t + T0))
        )/2)

    T_K = 290
    dH = 80e3
    dS = 10
    rsys1 = ReactionSystem.from_string("""
    NOBr -> NO + Br; EyringParam(dH={dH}*J/mol, dS={dS}*J/K/mol)
    """.format(dH=dH, dS=dS))

    NOBr0_M = 0.7
    init_cond = dict(
        NOBr=NOBr0_M*u.M,
        NO=0*u.M,
        Br=0*u.M
    )
    t = 20*u.second

    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)

    check(rsys1)
    rsys2 = ReactionSystem.from_string("""
    NOBr -> NO + Br; MassAction(EyringHS([{dH}*J/mol, {dS}*J/K/mol]))
    """.format(dH=dH, dS=dS))
    check(rsys2)
コード例 #4
0
def test_get_odesys__linear_dependencies__preferred(substances):
    rsys = ReactionSystem.from_string(
        "\n".join(["H2O -> H+ + OH-; 1e-4", "OH- + H+ -> H2O; 1e10"]), substances
    )
    assert isinstance(rsys.substances, OrderedDict)
    odesys, extra = get_odesys(rsys)

    af_H2O_H = extra["linear_dependencies"](["H+", "H2O"])
    import sympy

    y0 = {k: sympy.Symbol(k + "0") for k in rsys.substances}
    af_H2O_H(
        None, {odesys[k]: v for k, v in y0.items()}, None, sympy
    )  # ensure idempotent
    exprs_H2O_H = af_H2O_H(None, {odesys[k]: v for k, v in y0.items()}, None, sympy)
    ref_H2O_H = {
        "H2O": y0["H2O"] + y0["OH-"] - odesys["OH-"],  # oxygen
        "H+": 2 * y0["H2O"]
        + y0["H+"]
        + y0["OH-"]
        - odesys["OH-"]
        - 2 * (y0["H2O"] + y0["OH-"] - odesys["OH-"]),  # hydrogen
    }
    for k, v in ref_H2O_H.items():
        assert (exprs_H2O_H[odesys[k]] - v) == 0
コード例 #5
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
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))
コード例 #6
0
def test_get_native__first_step(solve):
    integrator = 'cvode'
    forgive = 20

    def k(num):
        return "MassAction(unique_keys=('k%d',))" % num

    lines = [  # fictitious isomerization
        "CNO -> ONC; %s" % k(1),
        "ONC -> NCO; %s" % k(2),
        "NCO -> CON; %s" % k(3)
    ]
    rsys = ReactionSystem.from_string('\n'.join(lines), 'CNO ONC NCO CON')
    odesys, extra = get_odesys(rsys, include_params=False)
    if len(solve) > 0:
        from pyodesys.symbolic import PartiallySolvedSystem
        odesys = PartiallySolvedSystem(odesys, extra['linear_dependencies'](solve))
    c0 = defaultdict(float, {'CNO': .7})
    rate_coeffs = (1e78, 2, 3.)
    args = (5, c0, dict(zip('k1 k2 k3'.split(), rate_coeffs)))
    kwargs = dict(integrator=integrator, atol=1e-9, rtol=1e-9, nsteps=1000)
    native = get_native(rsys, odesys, integrator)

    h0 = extra['max_euler_step_cb'](0, *args[1:])
    xout1, yout1, info1 = odesys.integrate(*args, first_step=h0, **kwargs)
    xout2, yout2, info2 = native.integrate(*args, **kwargs)
    ref1 = decay_get_Cref(rate_coeffs, [c0[key] for key in native.names], xout1)
    ref2 = decay_get_Cref(rate_coeffs, [c0[key] for key in native.names], xout2)
    allclose_kw = dict(atol=kwargs['atol']*forgive, rtol=kwargs['rtol']*forgive)

    assert np.allclose(yout1[:, :3], ref1, **allclose_kw)

    assert info2['success']
    assert info2['nfev'] > 10 and info2['nfev'] > 1 and info2['time_cpu'] < 10 and info2['time_wall'] < 10
    assert np.allclose(yout2[:, :3], ref2, **allclose_kw)
コード例 #7
0
def test_get_odesys__linear_dependencies__PartiallySolvedSystem(preferred):
    import sympy
    from pyodesys.symbolic import PartiallySolvedSystem
    rsys = ReactionSystem.from_string('\n'.join(
        ['H2O -> H+ + OH-; 1e-4', 'OH- + H+ -> H2O; 1e10']))
    odesys, extra = get_odesys(rsys)
    c0 = {'H2O': 0, 'H+': 2e-7, 'OH-': 3e-7}
    h0max = extra['max_euler_step_cb'](0, c0)
    analytic_factory = extra['linear_dependencies']()
    y0 = {k: sympy.Symbol(k + '0') for k in rsys.substances}
    analytic_factory(None, {odesys[k]: v for k, v in y0.items()}, None, sympy)
    psys = PartiallySolvedSystem(odesys, analytic_factory)
    xout, yout, info = psys.integrate(1,
                                      c0,
                                      atol=1e-12,
                                      rtol=1e-10,
                                      first_step=h0max * 1e-12,
                                      integrator='cvode')
    c_reac = c0['H+'], c0['OH-']
    H2O_ref = binary_rev(xout, 1e10, 1e-4, c0['H2O'], max(c_reac), min(c_reac))
    assert np.allclose(yout[:, psys.names.index('H2O')], H2O_ref)
    assert np.allclose(yout[:, psys.names.index('H+')],
                       c0['H+'] + c0['H2O'] - H2O_ref)
    assert np.allclose(yout[:, psys.names.index('OH-')],
                       c0['OH-'] + c0['H2O'] - H2O_ref)
コード例 #8
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)
コード例 #9
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_get_odesys__Eyring_2nd_order_linearly_ramped_temperature():
    from scipy.special import expi

    def analytic_unit0(t, k, m, dH, dS):
        R = 8.314472
        kB = 1.3806504e-23
        h = 6.62606896e-34
        A = kB/h*np.exp(dS/R)
        B = dH/R
        return k*np.exp(B*(k*t + 2*m)/(m*(k*t + m)))/(
            A*(-B**2*np.exp(B/(k*t + m))*expi(-B/(k*t + m)) - B*k*t - B*m + k**2*t**2 + 2*k*m*t + m**2)*np.exp(B/m) +
            (A*B**2*np.exp(B/m)*expi(-B/m) - A*m*(-B + m) + k*np.exp(B/m))*np.exp(B/(k*t + m))
        )

    T_K = 290
    dTdt_Ks = 3
    dH = 80e3
    dS = 10
    rsys1 = ReactionSystem.from_string("""
    2 NO2 -> N2O4; EyringParam(dH={dH}*J/mol, dS={dS}*J/K/mol)
    """.format(dH=dH, dS=dS))

    NO2_M = 1.0
    init_cond = dict(
        NO2=NO2_M*u.M,
        N2O4=0*u.M
    )
    t = 20*u.second

    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)

    check(rsys1)
    rsys2 = ReactionSystem.from_string("""
    2 NO2 -> N2O4; MassAction(EyringHS([{dH}*J/mol, {dS}*J/K/mol]))
    """.format(dH=dH, dS=dS))
    check(rsys2)
コード例 #10
0
ファイル: test_ode.py プロジェクト: yoelcortes/chempy
def test_get_odesys__Eyring_2nd_order_linearly_ramped_temperature():
    from scipy.special import expi

    def analytic_unit0(t, k, m, dH, dS):
        R = 8.314472
        kB = 1.3806504e-23
        h = 6.62606896e-34
        A = kB/h*np.exp(dS/R)
        B = dH/R
        return k*np.exp(B*(k*t + 2*m)/(m*(k*t + m)))/(
            A*(-B**2*np.exp(B/(k*t + m))*expi(-B/(k*t + m)) - B*k*t - B*m + k**2*t**2 + 2*k*m*t + m**2)*np.exp(B/m) +
            (A*B**2*np.exp(B/m)*expi(-B/m) - A*m*(-B + m) + k*np.exp(B/m))*np.exp(B/(k*t + m))
        )

    T_K = 290
    dTdt_Ks = 3
    dH = 80e3
    dS = 10
    rsys1 = ReactionSystem.from_string("""
    2 NO2 -> N2O4; EyringParam(dH={dH}*J/mol, dS={dS}*J/K/mol)
    """.format(dH=dH, dS=dS))

    NO2_M = 1.0
    init_cond = dict(
        NO2=NO2_M*u.M,
        N2O4=0*u.M
    )
    t = 20*u.second

    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)

    check(rsys1)
    rsys2 = ReactionSystem.from_string("""
    2 NO2 -> N2O4; MassAction(EyringHS([{dH}*J/mol, {dS}*J/K/mol]))
    """.format(dH=dH, dS=dS))
    check(rsys2)
コード例 #11
0
ファイル: test_ode.py プロジェクト: yoelcortes/chempy
def test_get_odesys__max_euler_step_cb():
    rsys = ReactionSystem.from_string('\n'.join(['H2O -> H+ + OH-; 1e-4', 'OH- + H+ -> H2O; 1e10']))
    odesys, extra = get_odesys(rsys)
    r1 = 1.01e-4
    r2 = 6e-4
    dH2Odt = r2 - r1
    euler_ref = 2e-7/dH2Odt
    assert abs(extra['max_euler_step_cb'](0, {'H2O': 1.01, 'H+': 2e-7, 'OH-': 3e-7}) - euler_ref)/euler_ref < 1e-8
コード例 #12
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_get_odesys__max_euler_step_cb():
    rsys = ReactionSystem.from_string('\n'.join(['H2O -> H+ + OH-; 1e-4', 'OH- + H+ -> H2O; 1e10']))
    odesys, extra = get_odesys(rsys)
    r1 = 1.01e-4
    r2 = 6e-4
    dH2Odt = r2 - r1
    euler_ref = 2e-7/dH2Odt
    assert abs(extra['max_euler_step_cb'](0, {'H2O': 1.01, 'H+': 2e-7, 'OH-': 3e-7}) - euler_ref)/euler_ref < 1e-8
コード例 #13
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)
コード例 #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)
コード例 #15
0
ファイル: test_odesys.py プロジェクト: chemreac/chemreac
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)
コード例 #16
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_get_odesys__Eyring_2nd_order():
    R = 8.314472
    T_K = 300
    dH = 80e3
    dS = 10
    rsys1b = ReactionSystem.from_string("""
    NO + Br -> NOBr; EyringParam(dH={dH}*J/mol, dS={dS}*J/K/mol)
    """.format(dH=dH, dS=dS))
    c0 = 1  # mol/dm3 === 1000 mol/m3
    kbref = 20836643994.118652*T_K*np.exp(-(dH - T_K*dS)/(R*T_K))/c0
    NO0_M = 1.5
    Br0_M = 0.7
    init_cond = dict(
        NOBr=0*u.M,
        NO=NO0_M*u.M,
        Br=Br0_M*u.M
    )
    t = 5*u.second
    params = dict(
        temperature=T_K*u.K
    )

    def analytic_b(t):
        U, V = NO0_M, Br0_M
        d = U - V
        return (U*(1 - np.exp(-kbref*t*d)))/(U/V - np.exp(-kbref*t*d))

    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)

    check(rsys1b)
    rsys2b = ReactionSystem.from_string("""
    NO + Br -> NOBr; MassAction(EyringHS([{dH}*J/mol, {dS}*J/K/mol]))
    """.format(dH=dH, dS=dS))
    check(rsys2b)
コード例 #17
0
ファイル: test_ode.py プロジェクト: yoelcortes/chempy
def test_get_odesys__Eyring_2nd_order():
    R = 8.314472
    T_K = 300
    dH = 80e3
    dS = 10
    rsys1b = ReactionSystem.from_string("""
    NO + Br -> NOBr; EyringParam(dH={dH}*J/mol, dS={dS}*J/K/mol)
    """.format(dH=dH, dS=dS))
    c0 = 1  # mol/dm3 === 1000 mol/m3
    kbref = 20836643994.118652*T_K*np.exp(-(dH - T_K*dS)/(R*T_K))/c0
    NO0_M = 1.5
    Br0_M = 0.7
    init_cond = dict(
        NOBr=0*u.M,
        NO=NO0_M*u.M,
        Br=Br0_M*u.M
    )
    t = 5*u.second
    params = dict(
        temperature=T_K*u.K
    )

    def analytic_b(t):
        U, V = NO0_M, Br0_M
        d = U - V
        return (U*(1 - np.exp(-kbref*t*d)))/(U/V - np.exp(-kbref*t*d))

    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)

    check(rsys1b)
    rsys2b = ReactionSystem.from_string("""
    NO + Br -> NOBr; MassAction(EyringHS([{dH}*J/mol, {dS}*J/K/mol]))
    """.format(dH=dH, dS=dS))
    check(rsys2b)
コード例 #18
0
def test_from_ReactionSystem__g_values():
    from chempy import ReactionSystem as RS
    rs = RS.from_string('-> H + OH; Radiolytic(2.1e-7)', checks=())
    rd = ReactionDiffusion.from_ReactionSystem(rs, variables={'density': 998, 'doserate': 0.15})
    gv = rd.g_values
    assert len(gv) == 1
    assert np.allclose(gv[0], rs.as_per_substance_array({'H': 2.1e-7, 'OH': 2.1e-7}))
    assert len(rd.fields) == 1
    assert len(rd.fields[0]) == 1
    assert np.allclose(rd.fields[0][0], 998*0.15)
コード例 #19
0
def test_create_odesys__Radiolytic():
    rsys1 = ReactionSystem.from_string("""
    -> e-(aq); Radiolytic.fk('g_emaq')
    """,
                                       checks=())
    ic1 = {'e-(aq)': 0.0}
    t1 = 5
    p1 = dict(g_emaq=42.0, doserate=17.0, density=5.0)
    odesys1, odesys_extra = create_odesys(rsys1)
    result1 = odesys1.integrate(t1, ic1, p1)
    yref1 = result1.xout * p1['g_emaq'] * p1['doserate'] * p1['density']
    assert np.allclose(yref1, result1.yout.squeeze())
コード例 #20
0
def test_get_odesys__Eyring():
    R = 8.314472
    T_K = 300
    dH = 80e3
    dS = 10
    rsys1 = ReactionSystem.from_string(
        """
    NOBr -> NO + Br; EyringParam(dH={dH}*J/mol, dS={dS}*J/K/mol)
    """.format(
            dH=dH, dS=dS
        ),
        substances="NOBr NO Br".split(),
    )
    kref = 20836643994.118652 * T_K * np.exp(-(dH - T_K * dS) / (R * T_K))
    NOBr0_M = 0.7
    init_cond = dict(NOBr=NOBr0_M * u.M, NO=0 * u.M, Br=0 * u.M)
    t = 5 * u.second
    params = dict(temperature=T_K * u.K)

    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)

    check(rsys1)
    rsys2 = ReactionSystem.from_string(
        """
    NOBr -> NO + Br; MassAction(EyringHS([{dH}*J/mol, {dS}*J/K/mol]))
    """.format(
            dH=dH, dS=dS
        ),
        substances="NOBr NO Br".split(),
    )
    check(rsys2)
コード例 #21
0
def test_get_native__a_substance_no_composition(solve):
    rsys = ReactionSystem.from_string('\n'.join(['H2O -> H2O+ + e-(aq); 1e-8', 'e-(aq) + H2O+ -> H2O; 1e10']))
    odesys, extra = get_odesys(rsys)
    c0 = {'H2O': 0, 'H2O+': 2e-9, 'e-(aq)': 3e-9}
    if len(solve) > 0:
        from pyodesys.symbolic import PartiallySolvedSystem
        odesys = PartiallySolvedSystem(odesys, extra['linear_dependencies'](solve))
    odesys = get_native(rsys, odesys, 'gsl')
    xout, yout, info = odesys.integrate(1, c0, atol=1e-15, rtol=1e-15, integrator='gsl')
    c_reac = c0['H2O+'], c0['e-(aq)']
    H2O_ref = binary_rev(xout, 1e10, 1e-4, c0['H2O'], max(c_reac), min(c_reac))
    assert np.allclose(yout[:, odesys.names.index('H2O')], H2O_ref)
    assert np.allclose(yout[:, odesys.names.index('H2O+')], c0['H2O+'] + c0['H2O'] - H2O_ref)
    assert np.allclose(yout[:, odesys.names.index('e-(aq)')], c0['e-(aq)'] + c0['H2O'] - H2O_ref)
コード例 #22
0
def test_from_ReactionSystem__g_values__units():
    from chempy import ReactionSystem as RS
    from chempy.units import SI_base_registry, default_units as u
    rs = RS.from_string('-> H + OH; Radiolytic(2.1*per100eV)', checks=())
    variables = {'density': .998 * u.kg/u.dm3, 'doserate': 0.15*u.Gy/u.s}
    rd = ReactionDiffusion.from_ReactionSystem(rs, variables=variables, unit_registry=SI_base_registry)
    gv = rd.g_values
    per100eV_as_mol_per_joule = 1.0364268556366418e-07
    ref = 2.1 * per100eV_as_mol_per_joule
    assert len(gv) == 1
    assert np.allclose(gv[0], rs.as_per_substance_array({'H': ref, 'OH': ref}))
    assert len(rd.fields) == 1
    assert len(rd.fields[0]) == 1
    assert np.allclose(rd.fields[0][0], 998*0.15)
コード例 #23
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_create_odesys__Radiolytic():
    rsys1 = ReactionSystem.from_string("""
    -> e-(aq); Radiolytic.fk('g_emaq')
    """, checks=())
    ic1 = {'e-(aq)': 0.0}
    t1 = 5
    p1 = dict(
        g_emaq=42.0,
        doserate=17.0,
        density=5.0
    )
    odesys1, odesys_extra = create_odesys(rsys1)
    result1 = odesys1.integrate(t1, ic1, p1)
    yref1 = result1.xout*p1['g_emaq']*p1['doserate']*p1['density']
    assert np.allclose(yref1, result1.yout.squeeze())
コード例 #24
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_get_odesys_rsys_with_units__named_params():
    rsys = ReactionSystem.from_string("""
    A -> B; 'k1'
    B + C -> P; 'k2'
    """, substance_factory=Substance)
    odesys, extra = get_odesys(rsys, include_params=False, unit_registry=SI_base_registry)
    tend = 10
    tend_units = tend*u.s
    c0 = {'A': 1e-6, 'B': 0, 'C': 1, 'P': 0}
    p = {'k1': 3, 'k2': 4}
    p_units = {'k1': 3/u.s, 'k2': 4/u.M/u.s}
    c0_units = {k: v*u.molar for k, v in c0.items()}
    result1 = odesys.integrate(tend_units, c0_units, p_units, integrator='odeint')
    assert result1.info['success']

    with pytest.raises(Exception):
        odesys.integrate(tend, c0, p, integrator='odeint')
コード例 #25
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_get_odesys__linear_dependencies__preferred(substances):
    rsys = ReactionSystem.from_string('\n'.join(['H2O -> H+ + OH-; 1e-4', 'OH- + H+ -> H2O; 1e10']), substances)
    assert isinstance(rsys.substances, OrderedDict)
    odesys, extra = get_odesys(rsys)

    af_H2O_H = extra['linear_dependencies'](['H+', 'H2O'])
    import sympy
    y0 = {k: sympy.Symbol(k+'0') for k in rsys.substances}
    af_H2O_H(None, {odesys[k]: v for k, v in y0.items()}, None, sympy)  # ensure idempotent
    exprs_H2O_H = af_H2O_H(None, {odesys[k]: v for k, v in y0.items()}, None, sympy)
    ref_H2O_H = {
        'H2O': y0['H2O'] + y0['OH-'] - odesys['OH-'],  # oxygen
        'H+': 2*y0['H2O'] + y0['H+'] + y0['OH-'] - odesys['OH-'] - 2*(
            y0['H2O'] + y0['OH-'] - odesys['OH-'])  # hydrogen
    }
    for k, v in ref_H2O_H.items():
        assert (exprs_H2O_H[odesys[k]] - v) == 0
コード例 #26
0
def test_get_odesys__max_euler_step_cb():
    rsys = ReactionSystem.from_string(
        "\n".join(["H2O -> H+ + OH-; 1e-4", "OH- + H+ -> H2O; 1e10"])
    )
    odesys, extra = get_odesys(rsys)
    r1 = 1.01e-4
    r2 = 6e-4
    dH2Odt = r2 - r1
    euler_ref = 2e-7 / dH2Odt
    assert (
        abs(
            extra["max_euler_step_cb"](0, {"H2O": 1.01, "H+": 2e-7, "OH-": 3e-7})
            - euler_ref
        )
        / euler_ref
        < 1e-8
    )
コード例 #27
0
ファイル: test__native.py プロジェクト: bjodah/chempy
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)
コード例 #28
0
ファイル: test_ode.py プロジェクト: yoelcortes/chempy
def test_get_odesys__linear_dependencies__preferred(substances):
    rsys = ReactionSystem.from_string('\n'.join(['H2O -> H+ + OH-; 1e-4', 'OH- + H+ -> H2O; 1e10']), substances)
    assert isinstance(rsys.substances, OrderedDict)
    odesys, extra = get_odesys(rsys)

    af_H2O_H = extra['linear_dependencies'](['H+', 'H2O'])
    import sympy
    y0 = {k: sympy.Symbol(k+'0') for k in rsys.substances}
    af_H2O_H(None, {odesys[k]: v for k, v in y0.items()}, None, sympy)  # ensure idempotent
    exprs_H2O_H = af_H2O_H(None, {odesys[k]: v for k, v in y0.items()}, None, sympy)
    ref_H2O_H = {
        'H2O': y0['H2O'] + y0['OH-'] - odesys['OH-'],  # oxygen
        'H+': 2*y0['H2O'] + y0['H+'] + y0['OH-'] - odesys['OH-'] - 2*(
            y0['H2O'] + y0['OH-'] - odesys['OH-'])  # hydrogen
    }
    for k, v in ref_H2O_H.items():
        assert (exprs_H2O_H[odesys[k]] - v) == 0
コード例 #29
0
ファイル: test_ode.py プロジェクト: yoelcortes/chempy
def test_get_odesys_rsys_with_units__named_params():
    rsys = ReactionSystem.from_string("""
    A -> B; 'k1'
    B + C -> P; 'k2'
    """, substance_factory=Substance)
    odesys, extra = get_odesys(rsys, include_params=False, unit_registry=SI_base_registry)
    tend = 10
    tend_units = tend*u.s
    c0 = {'A': 1e-6, 'B': 0, 'C': 1, 'P': 0}
    p = {'k1': 3, 'k2': 4}
    p_units = {'k1': 3/u.s, 'k2': 4/u.M/u.s}
    c0_units = {k: v*u.molar for k, v in c0.items()}
    result1 = odesys.integrate(tend_units, c0_units, p_units, integrator='odeint')
    assert result1.info['success']

    with pytest.raises(Exception):
        odesys.integrate(tend, c0, p, integrator='odeint')
コード例 #30
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_get_odesys_rsys_with_units():
    rsys = ReactionSystem.from_string("""
    A -> B; 0.096/s
    B + C -> P; 4e3/M/s
    """, substance_factory=Substance)
    with pytest.raises(Exception):
        get_odesys(rsys)  # not a strict test, SI_base_registry could be made the default

    odesys, extra = get_odesys(rsys, unit_registry=SI_base_registry)
    tend = 10
    tend_units = tend*u.s
    c0 = {'A': 1e-6, 'B': 0, 'C': 1, 'P': 0}
    c0_units = {k: v*u.molar for k, v in c0.items()}
    result1 = odesys.integrate(tend_units, c0_units, integrator='gsl')
    assert result1.info['success']

    with pytest.raises(Exception):
        odesys.integrate(tend, c0, integrator='gsl')
コード例 #31
0
ファイル: test_ode.py プロジェクト: yoelcortes/chempy
def test_get_odesys_rsys_with_units():
    rsys = ReactionSystem.from_string("""
    A -> B; 0.096/s
    B + C -> P; 4e3/M/s
    """, substance_factory=Substance)
    with pytest.raises(Exception):
        get_odesys(rsys)  # not a strict test, SI_base_registry could be made the default

    odesys, extra = get_odesys(rsys, unit_registry=SI_base_registry)
    tend = 10
    tend_units = tend*u.s
    c0 = {'A': 1e-6, 'B': 0, 'C': 1, 'P': 0}
    c0_units = {k: v*u.molar for k, v in c0.items()}
    result1 = odesys.integrate(tend_units, c0_units, integrator='gsl')
    assert result1.info['success']

    with pytest.raises(Exception):
        odesys.integrate(tend, c0, integrator='gsl')
コード例 #32
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_get_odesys__linear_dependencies__PartiallySolvedSystem(preferred):
    import sympy
    from pyodesys.symbolic import PartiallySolvedSystem
    rsys = ReactionSystem.from_string('\n'.join(['H2O -> H+ + OH-; 1e-4', 'OH- + H+ -> H2O; 1e10']))
    odesys, extra = get_odesys(rsys)
    c0 = {'H2O': 0, 'H+': 2e-7, 'OH-': 3e-7}
    h0max = extra['max_euler_step_cb'](0, c0)
    analytic_factory = extra['linear_dependencies']()
    y0 = {k: sympy.Symbol(k+'0') for k in rsys.substances}
    analytic_factory(None, {odesys[k]: v for k, v in y0.items()}, None, sympy)
    psys = PartiallySolvedSystem(odesys, analytic_factory)
    xout, yout, info = psys.integrate(1, c0, atol=1e-12, rtol=1e-10, first_step=h0max*1e-12,
                                      integrator='cvode')
    c_reac = c0['H+'], c0['OH-']
    H2O_ref = binary_rev(xout, 1e10, 1e-4, c0['H2O'], max(c_reac), min(c_reac))
    assert np.allclose(yout[:, psys.names.index('H2O')], H2O_ref)
    assert np.allclose(yout[:, psys.names.index('H+')], c0['H+'] + c0['H2O'] - H2O_ref)
    assert np.allclose(yout[:, psys.names.index('OH-')], c0['OH-'] + c0['H2O'] - H2O_ref)
コード例 #33
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
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)
コード例 #34
0
ファイル: test_ode.py プロジェクト: yoelcortes/chempy
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)
コード例 #35
0
ファイル: test__native.py プロジェクト: bjodah/chempy
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)
コード例 #36
0
ファイル: test_ode.py プロジェクト: vishwamshukla/Epsilon
def test_get_odesys__cstr():
    rsys = ReactionSystem.from_string("2 H2O2 -> O2 + 2 H2O; 5")
    odesys, extra = get_odesys(rsys, cstr=True)
    fr, fc = extra['cstr_fr_fc']
    tout, c0 = np.linspace(0, .13, 7), {'H2O2': 2, 'O2': 4, 'H2O': 3}
    params = {fr: 13, fc['H2O2']: 11, fc['O2']: 43, fc['H2O']: 45}
    res = odesys.integrate(tout, c0, params)
    from chempy.kinetics.integrated import binary_irrev_cstr

    def get_analytic(result, k, n):
        ref = binary_irrev_cstr(result.xout, 5, result.named_dep('H2O2')[0],
                                result.named_dep(k)[0], result.named_param(fc['H2O2']), result.named_param(fc[k]),
                                result.named_param(fr), n)
        return np.array(ref).T

    ref_O2 = get_analytic(res, 'O2', 1)
    ref_H2O = get_analytic(res, 'H2O', 2)
    assert np.allclose(res.named_dep('H2O2'), ref_O2[:, 0])
    assert np.allclose(res.named_dep('H2O2'), ref_H2O[:, 0])
    assert np.allclose(res.named_dep('O2'), ref_O2[:, 1])
    assert np.allclose(res.named_dep('H2O'), ref_H2O[:, 1])
コード例 #37
0
ファイル: test__native.py プロジェクト: bjodah/chempy
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)
コード例 #38
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))
コード例 #39
0
def test_get_odesys_rsys_with_units__named_params():
    rsys = ReactionSystem.from_string(
        """
    A -> B; 'k1'
    B + C -> P; 'k2'
    """,
        substance_factory=Substance,
    )
    odesys, extra = get_odesys(
        rsys, include_params=False, unit_registry=SI_base_registry
    )
    tend = 10
    tend_units = tend * u.s
    c0 = {"A": 1e-6, "B": 0, "C": 1, "P": 0}
    p = {"k1": 3, "k2": 4}
    p_units = {"k1": 3 / u.s, "k2": 4 / u.M / u.s}
    c0_units = {k: v * u.molar for k, v in c0.items()}
    result1 = odesys.integrate(tend_units, c0_units, p_units, integrator="odeint")
    assert result1.info["success"]

    with pytest.raises(Exception):
        odesys.integrate(tend, c0, p, integrator="odeint")
コード例 #40
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, 0.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 validation["not_seen"] == {"OH"}

    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)
コード例 #41
0
def test_get_native__a_substance_no_composition(solve):
    rsys = ReactionSystem.from_string("\n".join(
        ["H2O -> H2O+ + e-(aq); 1e-8", "e-(aq) + H2O+ -> H2O; 1e10"]))
    odesys, extra = get_odesys(rsys)
    c0 = {"H2O": 0, "H2O+": 2e-9, "e-(aq)": 3e-9}
    if len(solve) > 0:
        from pyodesys.symbolic import PartiallySolvedSystem

        odesys = PartiallySolvedSystem(odesys,
                                       extra["linear_dependencies"](solve))
    odesys = get_native(rsys, odesys, "gsl")
    xout, yout, info = odesys.integrate(1,
                                        c0,
                                        atol=1e-15,
                                        rtol=1e-15,
                                        integrator="gsl")
    c_reac = c0["H2O+"], c0["e-(aq)"]
    H2O_ref = binary_rev(xout, 1e10, 1e-4, c0["H2O"], max(c_reac), min(c_reac))
    assert np.allclose(yout[:, odesys.names.index("H2O")], H2O_ref)
    assert np.allclose(yout[:, odesys.names.index("H2O+")],
                       c0["H2O+"] + c0["H2O"] - H2O_ref)
    assert np.allclose(yout[:, odesys.names.index("e-(aq)")],
                       c0["e-(aq)"] + c0["H2O"] - H2O_ref)
コード例 #42
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))
コード例 #43
0
def test_get_odesys__linear_dependencies__PartiallySolvedSystem(preferred):
    import sympy
    from pyodesys.symbolic import PartiallySolvedSystem

    rsys = ReactionSystem.from_string(
        "\n".join(["H2O -> H+ + OH-; 1e-4", "OH- + H+ -> H2O; 1e10"])
    )
    odesys, extra = get_odesys(rsys)
    c0 = {"H2O": 0, "H+": 2e-7, "OH-": 3e-7}
    h0max = extra["max_euler_step_cb"](0, c0)
    analytic_factory = extra["linear_dependencies"]()
    y0 = {k: sympy.Symbol(k + "0") for k in rsys.substances}
    analytic_factory(None, {odesys[k]: v for k, v in y0.items()}, None, sympy)
    psys = PartiallySolvedSystem(odesys, analytic_factory)
    xout, yout, info = psys.integrate(
        1, c0, atol=1e-12, rtol=1e-10, first_step=h0max * 1e-12, integrator="cvode"
    )
    c_reac = c0["H+"], c0["OH-"]
    H2O_ref = binary_rev(xout, 1e10, 1e-4, c0["H2O"], max(c_reac), min(c_reac))
    assert np.allclose(yout[:, psys.names.index("H2O")], H2O_ref)
    assert np.allclose(yout[:, psys.names.index("H+")], c0["H+"] + c0["H2O"] - H2O_ref)
    assert np.allclose(
        yout[:, psys.names.index("OH-")], c0["OH-"] + c0["H2O"] - H2O_ref
    )
コード例 #44
0
def test_get_odesys__Eyring_1st_order_linearly_ramped_temperature():
    from scipy.special import expi

    def analytic_unit0(t, T0, dH, dS):
        R = 8.314472
        kB = 1.3806504e-23
        h = 6.62606896e-34
        A = kB / h * np.exp(dS / R)
        B = dH / R
        return np.exp(
            A
            * (
                (-(B ** 2) * np.exp(B / T0) * expi(-B / T0) - T0 * (B - T0))
                * np.exp(-B / T0)
                + (
                    B ** 2 * np.exp(B / (t + T0)) * expi(-B / (t + T0))
                    - (t + T0) * (-B + t + T0)
                )
                * np.exp(-B / (t + T0))
            )
            / 2
        )

    T_K = 290
    dH = 80e3
    dS = 10
    rsys1 = ReactionSystem.from_string(
        """
    NOBr -> NO + Br; EyringParam(dH={dH}*J/mol, dS={dS}*J/K/mol)
    """.format(
            dH=dH, dS=dS
        )
    )

    NOBr0_M = 0.7
    init_cond = dict(NOBr=NOBr0_M * u.M, NO=0 * u.M, Br=0 * u.M)
    t = 20 * u.second

    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)

    check(rsys1)
    rsys2 = ReactionSystem.from_string(
        """
    NOBr -> NO + Br; MassAction(EyringHS([{dH}*J/mol, {dS}*J/K/mol]))
    """.format(
            dH=dH, dS=dS
        )
    )
    check(rsys2)
コード例 #45
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_get_odesys__cstr():
    rsys = ReactionSystem.from_string("2 H2O2 -> O2 + 2 H2O; 5")
    odesys, extra = get_odesys(rsys, cstr=True)
    fr, fc = extra['cstr_fr_fc']
    _check_cstr(odesys, fr, fc)
コード例 #46
0
def test_get_odesys__Eyring_2nd_order_reversible():
    R = 8.314472
    T_K = 273.15 + 20  # 20 degree celsius
    kB = 1.3806504e-23
    h = 6.62606896e-34

    dHf = 74e3
    dSf = R * np.log(h / kB / T_K * 1e16)

    dHb = 79e3
    dSb = dSf - 23

    rsys1 = ReactionSystem.from_string(
        """
    Fe+3 + SCN- -> FeSCN+2; EyringParam(dH={dHf}*J/mol, dS={dSf}*J/K/mol)
    FeSCN+2 -> Fe+3 + SCN-; EyringParam(dH={dHb}*J/mol, dS={dSb}*J/K/mol)
    """.format(
            dHf=dHf, dSf=dSf, dHb=dHb, dSb=dSb
        )
    )
    kf_ref = 20836643994.118652 * T_K * np.exp(-(dHf - T_K * dSf) / (R * T_K))
    kb_ref = 20836643994.118652 * T_K * np.exp(-(dHb - T_K * dSb) / (R * T_K))
    Fe0 = 6e-3
    SCN0 = 2e-3
    init_cond = {"Fe+3": Fe0 * u.M, "SCN-": SCN0 * u.M, "FeSCN+2": 0 * u.M}
    t = 3 * u.second

    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)

    check(rsys1, {"temperature": T_K * u.K})
    rsys2 = ReactionSystem.from_string(
        """
    Fe+3 + SCN- -> FeSCN+2; MassAction(EyringHS([{dHf}*J/mol, {dSf}*J/K/mol]))
    FeSCN+2 -> Fe+3 + SCN-; MassAction(EyringHS([{dHb}*J/mol, {dSb}*J/K/mol]))
    """.format(
            dHf=dHf, dSf=dSf, dHb=dHb, dSb=dSb
        )
    )
    check(rsys2, {"temperature": T_K * u.K})
    rsys3 = ReactionSystem.from_string(
        """
    Fe+3 + SCN- -> FeSCN+2; MassAction(EyringHS.fk('dHf', 'dSf'))
    FeSCN+2 -> Fe+3 + SCN-; MassAction(EyringHS.fk('dHb', 'dSb'))
    """
    )
    check(
        rsys3,
        dict(
            temperature=T_K * u.K,
            dHf=dHf * u.J / u.mol,
            dSf=dSf * u.J / u.mol / u.K,
            dHb=dHb * u.J / u.mol,
            dSb=dSb * u.J / u.mol / u.K,
        ),
    )
コード例 #47
0
ファイル: test_ode.py プロジェクト: yoelcortes/chempy
def test_create_odesys__cstr():
    rsys = ReactionSystem.from_string("2 H2O2 -> O2 + 2 H2O; 'k2'")
    fr, fc = 'feedratio', OrderedDict([(sk, 'fc_%s' % sk) for sk in rsys.substances])
    odesys, extra = create_odesys(rsys, rates_kw=dict(cstr_fr_fc=(fr, fc)))
    _check_cstr(odesys, fr, fc, extra_pars=dict(k2=5))
コード例 #48
0
ファイル: test_ode.py プロジェクト: yoelcortes/chempy
def test_get_odesys__cstr():
    rsys = ReactionSystem.from_string("2 H2O2 -> O2 + 2 H2O; 5")
    odesys, extra = get_odesys(rsys, cstr=True)
    fr, fc = extra['cstr_fr_fc']
    _check_cstr(odesys, fr, fc)
コード例 #49
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)
コード例 #50
0
ファイル: test_ode.py プロジェクト: bjodah/chempy
def test_create_odesys__cstr():
    rsys = ReactionSystem.from_string("2 H2O2 -> O2 + 2 H2O; 'k2'")
    fr, fc = 'feedratio', OrderedDict([(sk, 'fc_%s' % sk) for sk in rsys.substances])
    odesys, extra = create_odesys(rsys, rates_kw=dict(cstr_fr_fc=(fr, fc)))
    _check_cstr(odesys, fr, fc, extra_pars=dict(k2=5))
コード例 #51
0
from collections import defaultdict
from chempy.equilibria import EqSystem
eqsys = EqSystem.from_string("""HCO3- = H+ + CO3-2; 10**-10.3
H2CO3 = H+ + HCO3-; 10**-6.3
H2O = H+ + OH-; 10**-14/55.4
""")
arr, info, sane = eqsys.root(defaultdict(float, {'H2O': 55.4, 'HCO3-': 1e-2}))
conc = dict(zip(eqsys.substances, arr))
from math import log10
print("pH: %.2f" % -log10(conc['H+']))

# 测量离子浓度

from chempy import ReactionSystem  # The rate constants below are arbitrary
rsys = ReactionSystem.from_string("""2 Fe+2 + H2O2 -> 2 Fe+3 + 2 OH-; 42
	   2 Fe+3 + H2O2 -> 2 Fe+2 + O2 + 2 H+; 17
       H+ + OH- -> H2O; 1e10
       H2O -> H+ + OH-; 1e-4""")  # "[H2O]" = 1.0 (actually 55.4 at RT)
from chempy.kinetics.ode import get_odesys
odesys, extra = get_odesys(rsys)
from collections import defaultdict
import numpy as np
tout = sorted(np.concatenate((np.linspace(0, 23), np.logspace(-8, 1))))
c0 = defaultdict(float, {
    'Fe+2': 0.05,
    'H2O2': 0.1,
    'H2O': 1.0,
    'H+': 1e-2,
    'OH-': 1e-12
})
result = odesys.integrate(tout, c0, atol=1e-12, rtol=1e-14)
import matplotlib.pyplot as plt