示例#1
0
    def entr_mol_phase(blk, p):
        pobj = blk.params.get_phase(p)

        cname = pobj._cubic_type.name
        bm = getattr(blk, cname + "_bm")[p]
        B = getattr(blk, cname + "_B")[p]
        dam_dT = getattr(blk, cname + "_dam_dT")[p]
        Z = blk.compress_fact_phase[p]

        EoS_u = EoS_param[pobj._cubic_type]['u']
        EoS_w = EoS_param[pobj._cubic_type]['w']
        EoS_p = sqrt(EoS_u**2 - 4 * EoS_w)

        R = Cubic.gas_constant(blk)

        entr_ideal_gas = -R * safe_log(blk.pressure / blk.params.pressure_ref,
                                       eps=eps_SL)
        for j in blk.components_in_phase(p):
            entr_j = get_method(blk, "entr_mol_ig_comp", j)(blk, cobj(blk, j),
                                                            blk.temperature)
            xj = blk.mole_frac_phase_comp[p, j]
            log_xj = blk.log_mole_frac_phase_comp[p, j]

            entr_ideal_gas += xj * (entr_j - R * log_xj)

        # See pg. 102 in Properties of Gases and Liquids
        # or pg. 208 of Sandler, 4th Ed.
        entr_departure = (R * safe_log(
            (Z - B), eps=eps_SL) + dam_dT / (bm * EoS_p) * safe_log(
                (2 * Z + B * (EoS_u + EoS_p)) / (2 * Z + B * (EoS_u - EoS_p)),
                eps=eps_SL))

        return entr_ideal_gas + entr_departure
示例#2
0
def test_smooth_min(simple_model):
    # Test that smooth_min gives correct values
    assert safe_log(4) == pytest.approx(1.386294, abs=1e-4)
    assert safe_log(0) < -5
    assert safe_log(-4) < -5
    assert value(safe_log(simple_model.a, simple_model.e)) == \
        pytest.approx(1.386294, abs=1e-4)
示例#3
0
    def entr_mol_phase_comp(blk, p, j):
        pobj = blk.params.get_phase(p)
        if not (pobj.is_vapor_phase() or pobj.is_liquid_phase()):
            raise PropertyNotSupportedError(_invalid_phase_msg(blk.name, p))

        cname = pobj._cubic_type.name
        bm = getattr(blk, cname + "_bm")[p]
        B = getattr(blk, cname + "_B")[p]
        dadT = getattr(blk, cname + "_dadT")[p]
        Z = blk.compress_fact_phase[p]

        EoS_u = EoS_param[pobj._cubic_type]['u']
        EoS_w = EoS_param[pobj._cubic_type]['w']
        EoS_p = sqrt(EoS_u**2 - 4 * EoS_w)

        # See pg. 102 in Properties of Gases and Liquids
        return (((Cubic.gas_constant(blk) * safe_log(
            (Z - B) / Z, eps=1e-6) * bm * EoS_p + Cubic.gas_constant(blk) *
                  safe_log(Z * blk.params.pressure_ref /
                           (blk.mole_frac_phase_comp[p, j] * blk.pressure),
                           eps=1e-6) * bm * EoS_p + dadT * safe_log(
                               (2 * Z + B * (EoS_u + EoS_p)) /
                               (2 * Z + B * (EoS_u - EoS_p)),
                               eps=1e-6)) / (bm * EoS_p)) +
                get_method(blk, "entr_mol_ig_comp", j)(blk, cobj(blk, j),
                                                       blk.temperature))
示例#4
0
def _log_fug_coeff_method(A, b, bm, B, delta, Z, cubic_type):
    u = EoS_param[cubic_type]['u']
    w = EoS_param[cubic_type]['w']
    p = sqrt(u**2 - 4 * w)

    return ((b / bm * (Z - 1) * (B * p) - safe_log(Z - B, eps=1e-6) *
             (B * p) + A * (b / bm - delta) * safe_log(
                 (2 * Z + B * (u + p)) / (2 * Z + B * (u - p)), eps=1e-6)) /
            (B * p))
示例#5
0
    def enth_mol_phase(blk, p):
        pobj = blk.params.get_phase(p)
        if not (pobj.is_vapor_phase() or pobj.is_liquid_phase()):
            raise PropertyNotSupportedError(_invalid_phase_msg(blk.name, p))

        cname = pobj._cubic_type.name
        am = getattr(blk, cname + "_am")[p]
        bm = getattr(blk, cname + "_bm")[p]
        B = getattr(blk, cname + "_B")[p]
        dadT = getattr(blk, cname + "_dadT")[p]
        Z = blk.compress_fact_phase[p]

        EoS_u = EoS_param[pobj._cubic_type]['u']
        EoS_w = EoS_param[pobj._cubic_type]['w']
        EoS_p = sqrt(EoS_u**2 - 4 * EoS_w)

        # Derived from equation on pg. 120 in Properties of Gases and Liquids
        return (((blk.temperature * dadT - am) * safe_log(
            (2 * Z + B * (EoS_u + EoS_p)) / (2 * Z + B * (EoS_u - EoS_p)),
            eps=1e-6) + Cubic.gas_constant(blk) * blk.temperature *
                 (Z - 1) * bm * EoS_p) / (bm * EoS_p) +
                sum(blk.mole_frac_phase_comp[p, j] *
                    get_method(blk, "enth_mol_ig_comp", j)
                    (blk, cobj(blk, j), blk.temperature)
                    for j in blk.components_in_phase(p)))
示例#6
0
    def enth_mol_phase(blk, p):
        pobj = blk.params.get_phase(p)

        cname = pobj._cubic_type.name
        am = getattr(blk, cname + "_am")[p]
        bm = getattr(blk, cname + "_bm")[p]
        B = getattr(blk, cname + "_B")[p]
        dam_dT = getattr(blk, cname + "_dam_dT")[p]
        Z = blk.compress_fact_phase[p]
        R = Cubic.gas_constant(blk)
        T = blk.temperature

        EoS_u = EoS_param[pobj._cubic_type]['u']
        EoS_w = EoS_param[pobj._cubic_type]['w']
        EoS_p = sqrt(EoS_u**2 - 4 * EoS_w)

        enth_ideal = sum(blk.mole_frac_phase_comp[p, j] *
                         get_method(blk, "enth_mol_ig_comp", j)
                         (blk, cobj(blk, j), blk.temperature)
                         for j in blk.components_in_phase(p))

        # Derived from equation on pg. 120 in Properties of Gases and Liquids
        enth_departure = (R * T * (Z - 1) + (T * dam_dT - am) /
                          (bm * EoS_p) * safe_log(
                              (2 * Z + B * (EoS_u + EoS_p)) /
                              (2 * Z + B * (EoS_u - EoS_p)),
                              eps=eps_SL))
        return enth_ideal + enth_departure
示例#7
0
    def return_expression(b, rblock, r_idx, T):
        e = None

        if hasattr(b.params, "_electrolyte") and b.params._electrolyte:
            pc_set = b.params.true_phase_component_set
        else:
            pc_set = b.phase_component_set

        # Get reaction orders and construct power law expression
        for p, j in pc_set:
            o = rblock.reaction_order[p, j]

            if e is None and o != 0:
                # Need to strip units from concentration term (if applicable)
                c = get_concentration_term(b, r_idx)[p, j]
                u = pyunits.get_units(c)
                if u is not None:
                    # Has units, so divide conc by units
                    expr = c / u
                else:
                    # Units is None, so just use conc
                    expr = c
                e = o * safe_log(expr, eps=rblock.eps)
            elif e is not None and o != 0:
                # Need to strip units from concentration term (if applicable)
                c = get_concentration_term(b, r_idx)[p, j]
                u = pyunits.get_units(c)
                if u is not None:
                    # Has units, so divide conc by units
                    expr = c / u
                else:
                    # Units is None, so just use conc
                    expr = c
                e = e + o * safe_log(expr, eps=rblock.eps)

        # Need to check units on k_eq as well
        u = pyunits.get_units(b.k_eq[r_idx])
        if u is not None:
            # Has units, so divide k_eq by units
            expr = b.k_eq[r_idx] / u
        else:
            # Units is None, so just use k_eq
            expr = b.k_eq[r_idx]

        return safe_log(expr, eps=rblock.eps) == e
示例#8
0
    def entr_mol_phase_comp(blk, p, j):
        pobj = blk.params.get_phase(p)

        logphi_j = _log_fug_coeff_phase_comp(blk, p, j)
        dlogphi_j_dT = _d_log_fug_coeff_dT_phase_comp(blk, p, j)

        R = Cubic.gas_constant(blk)

        entr_ideal_gas = (
            get_method(blk, "entr_mol_ig_comp", j)(blk, cobj(blk, j),
                                                   blk.temperature) - R *
            (safe_log(blk.pressure / blk.params.pressure_ref, eps=eps_SL) +
             blk.log_mole_frac_phase_comp[p, j]))

        entr_departure = -R * logphi_j - R * blk.temperature * dlogphi_j_dT

        return entr_ideal_gas + entr_departure
示例#9
0
    def gibbs_mol_phase_comp(blk, p, j):
        # Calling the enthalpy and entropy directly adds a lot of overhead
        # because expressions involving the derivative of the fugacity coefficient
        # are generated. Those terms cancel mathematically, but I suspect Pyomo
        # leaves them in, causing trouble.
        R = Cubic.gas_constant(blk)
        T = blk.temperature
        logphi_j = _log_fug_coeff_phase_comp(blk, p, j)

        enth_ideal_gas = get_method(blk, "enth_mol_ig_comp", j)(blk,
                                                                cobj(blk, j),
                                                                T)

        entr_ideal_gas = (
            get_method(blk, "entr_mol_ig_comp", j)(blk, cobj(blk, j), T) - R *
            (safe_log(blk.pressure / blk.params.pressure_ref, eps=eps_SL) +
             blk.log_mole_frac_phase_comp[p, j]))
        gibbs_ideal_gas = enth_ideal_gas - T * entr_ideal_gas
        gibbs_departure = R * T * logphi_j

        return gibbs_ideal_gas + gibbs_departure
示例#10
0
    def energy_internal_mol_phase(blk, p):
        pobj = blk.params.get_phase(p)

        cname = pobj._cubic_type.name
        am = getattr(blk, cname + "_am")[p]
        bm = getattr(blk, cname + "_bm")[p]
        B = getattr(blk, cname + "_B")[p]
        dam_dT = getattr(blk, cname + "_dam_dT")[p]
        Z = blk.compress_fact_phase[p]

        EoS_u = EoS_param[pobj._cubic_type]['u']
        EoS_w = EoS_param[pobj._cubic_type]['w']
        EoS_p = sqrt(EoS_u**2 - 4 * EoS_w)

        # Derived from equation on pg. 120 in Properties of Gases and Liquids
        # Departure function for U is similar to H minus the RT(Z-1) term
        return (((blk.temperature * dam_dT - am) * safe_log(
            (2 * Z + B * (EoS_u + EoS_p)) / (2 * Z + B * (EoS_u - EoS_p)),
            eps=eps_SL)) / (bm * EoS_p) +
                sum(blk.mole_frac_phase_comp[p, j] *
                    EoSBase.energy_internal_mol_ig_comp_pure(blk, j)
                    for j in blk.components_in_phase(p)))
示例#11
0
    def energy_internal_mol_phase_comp(blk, p, j):
        pobj = blk.params.get_phase(p)
        if not (pobj.is_vapor_phase() or pobj.is_liquid_phase()):
            raise PropertyNotSupportedError(_invalid_phase_msg(blk.name, p))

        cname = pobj._cubic_type.name
        am = getattr(blk, cname + "_am")[p]
        bm = getattr(blk, cname + "_bm")[p]
        B = getattr(blk, cname + "_B")[p]
        dadT = getattr(blk, cname + "_dadT")[p]
        Z = blk.compress_fact_phase[p]

        EoS_u = EoS_param[pobj._cubic_type]['u']
        EoS_w = EoS_param[pobj._cubic_type]['w']
        EoS_p = sqrt(EoS_u**2 - 4 * EoS_w)

        # Derived from equation on pg. 120 in Properties of Gases and Liquids
        # Departure function for U is similar to H minus the RT(Z-1) term
        return (((blk.temperature * dadT - am) * safe_log(
            (2 * Z + B * (EoS_u + EoS_p)) / (2 * Z + B * (EoS_u - EoS_p)),
            eps=1e-6)) / (bm * EoS_p) +
                EoSBase.energy_internal_mol_ig_comp_pure(blk, j))
示例#12
0
    def cp_mol_phase(blk, p):
        pobj = blk.params.get_phase(p)
        cname = pobj._cubic_type.name

        am = getattr(blk, cname + "_am")[p]
        bm = getattr(blk, cname + "_bm")[p]
        B = getattr(blk, cname + "_B")[p]

        dam_dT = getattr(blk, cname + "_dam_dT")[p]
        d2am_dT2 = getattr(blk, cname + "_d2am_dT2")[p]

        T = blk.temperature
        R = Cubic.gas_constant(blk)
        Z = blk.compress_fact_phase[p]
        dZdT = _dZ_dT(blk, p)

        EoS_u = EoS_param[pobj._cubic_type]['u']
        EoS_w = EoS_param[pobj._cubic_type]['w']
        EoS_p = sqrt(EoS_u**2 - 4 * EoS_w)

        expression1 = 2 * Z + (EoS_u + EoS_p) * B
        expression2 = 2 * Z + (EoS_u - EoS_p) * B
        expression3 = B * (dZdT + Z / T) / (Z**2 + Z * EoS_u * B +
                                            EoS_w * B**2)

        cp_ideal_gas = sum(
            blk.mole_frac_phase_comp[p, j] *
            get_method(blk, "cp_mol_ig_comp", j)(blk, cobj(blk, j), T)
            for j in blk.components_in_phase(p))

        # Derived from the relations in Chapter 6 of [1]
        cp_departure = (
            R * (T * dZdT + Z - 1) +
            (T * d2am_dT2 /
             (EoS_p * bm)) * safe_log(expression1 / expression2, eps=eps_SL) +
            ((am - T * dam_dT) * expression3 / bm))

        return cp_ideal_gas + cp_departure
示例#13
0
def test_log_power_law_equil_with_order():
    m = ConcreteModel()

    # # Add a test thermo package for validation
    m.pparams = PhysicalParameterTestBlock()

    # Add a solid phase for testing
    m.pparams.sol = SolidPhase()

    m.thermo = m.pparams.build_state_block([1])

    # Create a dummy reaction parameter block
    m.rparams = GenericReactionParameterBlock(
        default={
            "property_package": m.pparams,
            "base_units": {
                "time": pyunits.s,
                "mass": pyunits.kg,
                "amount": pyunits.mol,
                "length": pyunits.m,
                "temperature": pyunits.K
            },
            "equilibrium_reactions": {
                "r1": {
                    "stoichiometry": {
                        ("p1", "c1"): -1,
                        ("p1", "c2"): 2,
                        ("sol", "c1"): -3,
                        ("sol", "c2"): 4
                    },
                    "equilibrium_form": log_power_law_equil,
                    "concentration_form": ConcentrationForm.moleFraction,
                    "parameter_data": {
                        "reaction_order": {
                            ("p1", "c1"): 1,
                            ("p1", "c2"): 2,
                            ("p2", "c1"): 3,
                            ("p2", "c2"): 4,
                            ("sol", "c1"): 5,
                            ("sol", "c2"): 6
                        }
                    }
                }
            }
        })

    # Create a dummy state block
    m.rxn = Block([1])
    add_object_reference(m.rxn[1], "phase_component_set",
                         m.pparams._phase_component_set)
    add_object_reference(m.rxn[1], "params", m.rparams)
    add_object_reference(m.rxn[1], "state_ref", m.thermo[1])

    m.rxn[1].k_eq = Var(["r1"], initialize=1)

    log_power_law_equil.build_parameters(
        m.rparams.reaction_r1, m.rparams.config.equilibrium_reactions["r1"])

    # Check parameter construction
    assert isinstance(m.rparams.reaction_r1.reaction_order, Var)
    assert len(m.rparams.reaction_r1.reaction_order) == 6
    assert m.rparams.reaction_r1.reaction_order["p1", "c1"].value == 1
    assert m.rparams.reaction_r1.reaction_order["p1", "c2"].value == 2
    assert m.rparams.reaction_r1.reaction_order["p2", "c1"].value == 3
    assert m.rparams.reaction_r1.reaction_order["p2", "c2"].value == 4
    assert m.rparams.reaction_r1.reaction_order["sol", "c1"].value == 5
    assert m.rparams.reaction_r1.reaction_order["sol", "c2"].value == 6
    assert isinstance(m.rparams.reaction_r1.eps, Param)
    assert m.rparams.reaction_r1.eps.value == 1e-15

    # Check reaction form
    rform = log_power_law_equil.return_expression(m.rxn[1],
                                                  m.rparams.reaction_r1, "r1",
                                                  300)

    assert str(rform) == str(
        safe_log(m.rxn[1].k_eq["r1"], eps=m.rparams.reaction_r1.eps) ==
        m.rparams.reaction_r1.reaction_order["p1", "c1"] *
        safe_log(m.thermo[1].mole_frac_phase_comp["p1", "c1"],
                 eps=m.rparams.reaction_r1.eps) +
        m.rparams.reaction_r1.reaction_order["p1", "c2"] *
        safe_log(m.thermo[1].mole_frac_phase_comp["p1", "c2"],
                 eps=m.rparams.reaction_r1.eps) +
        m.rparams.reaction_r1.reaction_order["p2", "c1"] *
        safe_log(m.thermo[1].mole_frac_phase_comp["p2", "c1"],
                 eps=m.rparams.reaction_r1.eps) +
        m.rparams.reaction_r1.reaction_order["p2", "c2"] *
        safe_log(m.thermo[1].mole_frac_phase_comp["p2", "c2"],
                 eps=m.rparams.reaction_r1.eps) +
        m.rparams.reaction_r1.reaction_order["sol", "c1"] *
        safe_log(m.thermo[1].mole_frac_phase_comp["sol", "c1"],
                 eps=m.rparams.reaction_r1.eps) +
        m.rparams.reaction_r1.reaction_order["sol", "c2"] *
        safe_log(m.thermo[1].mole_frac_phase_comp["sol", "c2"],
                 eps=m.rparams.reaction_r1.eps))