예제 #1
0
    def _custom_set_poly_fit(self):
        try:
            Tmin, Tmax = self.poly_fit_Tmin, self.poly_fit_Tmax
            poly_fit_coeffs = self.poly_fit_coeffs
            v_Tmin = horner(poly_fit_coeffs, Tmin)
            for T_trans in linspace(Tmin, Tmax, 25):
                v, d1, d2 = horner_and_der2(poly_fit_coeffs, T_trans)
                Psat = exp(v)
                dPsat_dT = Psat * d1
                d2Psat_dT2 = Psat * (d1 * d1 + d2)

                A, B, C = Antoine_ABC = Antoine_coeffs_from_point(T_trans,
                                                                  Psat,
                                                                  dPsat_dT,
                                                                  d2Psat_dT2,
                                                                  base=e)
                self.poly_fit_AB = list(
                    Antoine_AB_coeffs_from_point(T_trans,
                                                 Psat,
                                                 dPsat_dT,
                                                 base=e))
                self.DIPPR101_ABC = list(
                    DIPPR101_ABC_coeffs_from_point(T_trans, Psat, dPsat_dT,
                                                   d2Psat_dT2))

                B_OK = B > 0.0  # B is negated in this implementation, so the requirement is reversed
                C_OK = -T_trans < C < 0.0
                if B_OK and C_OK:
                    self.poly_fit_Antoine = Antoine_ABC
                    break
                else:
                    continue

            # Calculate the extrapolation values
            v_Tmax = horner(poly_fit_coeffs, Tmax)
            v, d1, d2 = horner_and_der2(poly_fit_coeffs, Tmax)
            Psat = exp(v)
            dPsat_dT = Psat * d1
            d2Psat_dT2 = Psat * (d1 * d1 + d2)
            #                A, B, C = Antoine_ABC = Antoine_coeffs_from_point(T_trans, Psat, dPsat_dT, d2Psat_dT2, base=e)
            self.poly_fit_AB_high = list(
                Antoine_AB_coeffs_from_point(Tmax, Psat, dPsat_dT, base=e))
            self.poly_fit_AB_high_ABC_compat = [
                self.poly_fit_AB_high[0], -self.poly_fit_AB_high[1]
            ]
            self.DIPPR101_ABC_high = list(
                DIPPR101_ABC_coeffs_from_point(Tmax, Psat, dPsat_dT,
                                               d2Psat_dT2))

        except:
            pass
예제 #2
0
    def mul(self, T):
        r'''Computes liquid viscosity at a specified temperature
        of an organic compound using the Joback method as a function of
        chemical structure only.

        .. math::
            \mu_{liq} = \text{MW} \exp\left( \frac{ \sum_i \mu_a - 597.82}{T}
            + \sum_i \mu_b - 11.202 \right)

        Parameters
        ----------
        T : float
            Temperature, [K]

        Returns
        -------
        mul : float
            Liquid viscosity, [Pa*s]

        Examples
        --------
        >>> J = Joback('CC(=O)C')
        >>> J.mul(300)
        0.0002940378347162687
        '''
        if self.calculated_mul_coeffs is None:
            self.calculated_mul_coeffs = Joback.mul_coeffs(self.counts)
        a, b = self.calculated_mul_coeffs
        return self.MW*exp(a/T + b)
예제 #3
0
def EQ115(T, A, B, C=0, D=0, E=0):
    r'''DIPPR Equation #115. No major uses; has been used as an alternate
    liquid viscosity expression, and as a model for vapor pressure.
    Only parameters A and B are required.

    .. math::
        Y = \exp\left(A + \frac{B}{T} + C\log T + D T^2 + \frac{E}{T^2}\right)

    Parameters
    ----------
    T : float
        Temperature, [K]
    A-E : float
        Parameter for the equation; chemical and property specific [-]

    Returns
    -------
    Y : float
        Property [constant-specific]

    Notes
    -----
    No coefficients found for this expression.
    This function is not integrable for either dT or Y/T dT.

    References
    ----------
    .. [1] Design Institute for Physical Properties, 1996. DIPPR Project 801
       DIPPR/AIChE
    '''
    return exp(A + B / T + C * log(T) + D * T**2 + E / T**2)
예제 #4
0
def Lee_Kesler(T, Tc, Pc, omega):
    r'''Calculates vapor pressure of a fluid at arbitrary temperatures using a
    CSP relationship by [1]_; requires a chemical's critical temperature and
    acentric factor.

    The vapor pressure is given by:

    .. math::
        \ln P^{sat}_r = f^{(0)} + \omega f^{(1)}

    .. math::
        f^{(0)} = 5.92714-\frac{6.09648}{T_r}-1.28862\ln T_r + 0.169347T_r^6

    .. math::
        f^{(1)} = 15.2518-\frac{15.6875}{T_r} - 13.4721 \ln T_r + 0.43577T_r^6

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]
    omega : float
        Acentric factor [-]

    Returns
    -------
    Psat : float
        Vapor pressure at T [Pa]

    Notes
    -----
    This equation appears in [1]_ in expanded form.
    The reduced pressure form of the equation ensures predicted vapor pressure 
    cannot surpass the critical pressure.

    Examples
    --------
    Example from [2]_; ethylbenzene at 347.2 K.

    >>> Lee_Kesler(347.2, 617.1, 36E5, 0.299)
    13078.694162949312

    References
    ----------
    .. [1] Lee, Byung Ik, and Michael G. Kesler. "A Generalized Thermodynamic
       Correlation Based on Three-Parameter Corresponding States." AIChE Journal
       21, no. 3 (1975): 510-527. doi:10.1002/aic.690210313.
    .. [2] Reid, Robert C..; Prausnitz, John M.;; Poling, Bruce E.
       The Properties of Gases and Liquids. McGraw-Hill Companies, 1987.
    '''
    Tr = T / Tc
    logTr = log(Tr)
    Tr6 = Tr * Tr
    Tr6 *= Tr6 * Tr6
    f0 = 5.92714 - 6.09648 / Tr - 1.28862 * logTr + 0.169347 * Tr6
    f1 = 15.2518 - 15.6875 / Tr - 13.4721 * logTr + 0.43577 * Tr6
    return exp(f0 + omega * f1) * Pc
예제 #5
0
def gibbs_excess_dgammas_dT(xs,
                            GE,
                            dGE_dT,
                            dG_dxs,
                            d2GE_dTdxs,
                            N,
                            T,
                            dgammas_dT=None):
    if dgammas_dT is None:
        dgammas_dT = [0.0] * N

    xdx_totF0 = dGE_dT
    for j in range(N):
        xdx_totF0 -= xs[j] * d2GE_dTdxs[j]
    xdx_totF1 = GE
    for j in range(N):
        xdx_totF1 -= xs[j] * dG_dxs[j]

    T_inv = 1.0 / T
    RT_inv = R_inv * T_inv
    for i in range(N):
        dG_dni = xdx_totF1 + dG_dxs[i]
        dgammas_dT[i] = RT_inv * (d2GE_dTdxs[i] - dG_dni * T_inv +
                                  xdx_totF0) * exp(dG_dni * RT_inv)
    return dgammas_dT
예제 #6
0
    def gammas(self):
        r'''Calculate and return the activity coefficients of a liquid phase
        using an activity coefficient model.

        .. math::
            \gamma_i = \exp\left(\frac{\frac{\partial n_i G^E}{\partial n_i }}{RT}\right)

        Returns
        -------
        gammas : list[float]
            Activity coefficients, [-]

        Notes
        -----
        '''
        try:
            return self._gammas
        except:
            pass
        # Matches the gamma formulation perfectly
        GE = self.GE()
        dG_dxs = self.dGE_dxs()
        if self.scalar:
            dG_dns = dxs_to_dn_partials(dG_dxs, self.xs, GE)
            RT_inv = 1.0 / (R * self.T)
            gammas = [exp(i * RT_inv) for i in dG_dns]
        else:
            gammas = gibbs_excess_gammas(self.xs, dG_dxs, GE, self.T)
        self._gammas = gammas
        return gammas
예제 #7
0
def Antoine_AB_coeffs_from_point(T, Psat, dPsat_dT, base=10.0):
    r'''Calculates the antoine coefficients `A`, `B`, with `C` set to zero to
    improve low-temperature or high-temperature extrapolation, from a known
    vapor pressure and its first temperature derivative.

    Parameters
    ----------
    T : float
        Temperature of fluid, [K]
    Psat : float
        Vapor pressure at specified `T` [Pa]
    dPsat_dT : float
        First temperature derivative of vapor pressure at specified `T` [Pa/K]
    Base : float, optional
        Base of logarithm; 10 by default

    Returns
    -------
    A : float
        Antoine `A` parameter, [-]
    B : float
        Antoine `B` parameter, [K]

    Notes
    -----
    Coefficients are for calculating vapor pressure in Pascal. This is
    primarily useful for interconverting vapor pressure models, not fitting
    experimental data.

    Derived with SymPy as follows:

    >>> from sympy import * # doctest: +SKIP
    >>> base, A, B, T = symbols('base, A, B, T') # doctest: +SKIP
    >>> v = base**(A - B/T) # doctest: +SKIP
    >>> d1, d2 = diff(v, T), diff(v, T, 2) # doctest: +SKIP
    >>> vk, d1k = symbols('vk, d1k') # doctest: +SKIP
    >>> solve([Eq(v, vk), Eq(d1, d1k)], [A, B]) # doctest: +SKIP

    Examples
    --------
    Recalculate some coefficients from a calcualted value and its derivative:

    >>> T = 178.01
    >>> A, B = (27.358925161569008, 5445.569591293226)
    >>> Psat = Antoine(T, A, B, C=0, base=exp(1))
    >>> dPsat_dT = B*exp(1)**(A - B/T)*log(exp(1))/T**2
    >>> Antoine_AB_coeffs_from_point(T, Psat, dPsat_dT, base=exp(1))
    (27.35892516156901, 5445.569591293226)

    References
    ----------
    .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition.
       New York: McGraw-Hill Professional, 2000.
    '''
    log_base_inv = 1.0 / log(base)
    Psat_inv = 1.0 / Psat
    A = log(Psat * exp(T * dPsat_dT * Psat_inv)) * log_base_inv
    B = T * T * dPsat_dT * log_base_inv * Psat_inv
    return (A, B)
예제 #8
0
def regular_solution_gammas(T,
                            xs,
                            Vs,
                            SPs,
                            lambda_coeffs,
                            N,
                            xsVs=None,
                            Hi_sums=None,
                            dGE_dxs=None,
                            gammas=None):
    if xsVs is None:
        xsVs = [0.0] * N

    for i in range(N):
        xsVs[i] = xs[i] * Vs[i]

    xsVs_sum = 0.0
    for i in range(N):
        xsVs_sum += xsVs[i]
    xsVs_sum_inv = 1.0 / xsVs_sum

    if Hi_sums is None:
        Hi_sums = [0.0] * N

    Hi_sums = regular_solution_Hi_sums(SPs=SPs,
                                       Vs=Vs,
                                       xsVs=xsVs,
                                       coeffs=lambda_coeffs,
                                       N=N,
                                       Hi_sums=Hi_sums)
    GE = regular_solution_GE(SPs=SPs,
                             xsVs=xsVs,
                             coeffs=lambda_coeffs,
                             N=N,
                             xsVs_sum_inv=xsVs_sum_inv)

    if dGE_dxs is None:
        dGE_dxs = [0.0] * N
    dG_dxs = regular_solution_dGE_dxs(Vs=Vs,
                                      Hi_sums=Hi_sums,
                                      N=N,
                                      xsVs_sum_inv=xsVs_sum_inv,
                                      GE=GE,
                                      dGE_dxs=dGE_dxs)
    xdx_totF = GE
    for i in range(N):
        xdx_totF -= xs[i] * dG_dxs[i]

    if gammas is None:
        gammas = [0.0] * N

    for i in range(N):
        gammas[i] = dG_dxs[i] + xdx_totF
    RT_inv = 1.0 / (R * T)
    for i in range(N):
        gammas[i] *= RT_inv
    for i in range(N):
        gammas[i] = exp(gammas[i])
    return gammas
예제 #9
0
def Henry_pressure_mixture(Hs, weights=None, zs=None):
    r'''Mixing rule for Henry's law components. Applies a logarithmic average
    to all solvent components and mole fractions. Optionally, weight factors
    can be provided instead of using mole fractions - only specify one of them.

    A common weight factor is using volume fractions of powers of them, or
    using critical volumes.

    Parameters
    ----------
    Hs : list[float or None]
        Henry's law constant between each gas and the solvent (None for other
        solvents of gases without parameters available), [Pa]
    weights : list[float], optional
        Weight factors, [-]
    zs : list[float]
        Mole fractions of all species in phase, [-]

    Returns
    -------
    H : value
        Henry's law constant for the gas in the liquid phase, [-]

    Notes
    -----
    The default weight factor formulation is from [1]_.

    Examples
    --------
    >>> Henry_pressure_mixture([1072330.36341, 744479.751106, None], zs=[.48, .48, .04])
    893492.1611602883

    References
    ----------
    .. [1] Gmehling, Jurgen. Chemical Thermodynamics: For Process Simulation.
       Weinheim, Germany: Wiley-VCH, 2012.
    '''
    N = len(Hs)
    if weights is None and zs is None:
        raise ValueError("Weights or mole fractions are required")
    if weights is None:
        z_solvent = 0.0
        for i in range(N):
            if Hs[i] is not None:
                z_solvent += zs[i]
        # Default parameters - when weight specified only weight by that
        z_solvent_inv = 1.0/z_solvent
        weights = [0.0]*N
        for i in range(N):
            weights[i] = zs[i]*z_solvent_inv
    num = 0.0
    for i in range(N):
        if Hs[i] is not None:
            num += weights[i]*log(Hs[i])
    H = exp(num)
    return H
예제 #10
0
def Wagner_original(T, Tc, Pc, a, b, c, d):
    r'''Calculates vapor pressure using the Wagner equation (3, 6 form).

    Requires critical temperature and pressure as well as four coefficients
    specific to each chemical.

    .. math::
        \ln P^{sat}= \ln P_c + \frac{a\tau + b \tau^{1.5} + c\tau^3 + d\tau^6}
        {T_r}
        
    .. math::
        \tau = 1 - \frac{T}{T_c}

    Parameters
    ----------
    T : float
        Temperature of fluid, [K]
    Tc : float
        Critical temperature, [K]
    Pc : float
        Critical pressure, [Pa]
    a, b, c, d : floats
        Parameters for wagner equation. Specific to each chemical. [-]

    Returns
    -------
    Psat : float
        Vapor pressure at T [Pa]

    Notes
    -----
    Warning: Pc is often treated as adjustable constant.

    Examples
    --------
    Methane, coefficients from [2]_, at 100 K.

    >>> Wagner_original(100.0, 190.53, 4596420., a=-6.00435, b=1.1885, 
    ... c=-0.834082, d=-1.22833)
    34520.44601450499

    References
    ----------
    .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition.
       New York: McGraw-Hill Professional, 2000.
    .. [2] McGarry, Jack. "Correlation and Prediction of the Vapor Pressures of
       Pure Liquids over Large Pressure Ranges." Industrial & Engineering
       Chemistry Process Design and Development 22, no. 2 (April 1, 1983):
       313-22. doi:10.1021/i200021a023.
    '''
    Tr = T / Tc
    tau = 1.0 - Tr
    tau2 = tau * tau
    tau_Tr = tau / Tr
    return Pc * exp(((d * tau2 * tau + c) * tau2 + a + b * sqrt(tau)) * tau_Tr)
예제 #11
0
    def calculate_derivative(self, T, method, order=1):
        r'''Method to calculate a derivative of a vapor pressure with respect to
        temperature, of a given order  using a specified method. If the method
        is BESTFIT, an anlytical derivative is used; otherwise SciPy's
        derivative function, with a delta of 1E-6 K and a number of points
        equal to 2*order + 1.

        If the calculation does not succeed, returns the actual error
        encountered.

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        method : str
            Method for which to find the derivative
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        derivative : float
            Calculated derivative property, [`units/K^order`]
        '''
        if order == 1 and method == BESTFIT:
            # if T < self.poly_fit_Tmin:
            #     return self.poly_fit_Tmin_slope*exp(
            #             (T - self.poly_fit_Tmin)*self.poly_fit_Tmin_slope
            #             + self.poly_fit_Tmin_value)
            # elif T > self.poly_fit_Tmax:
            #     return self.poly_fit_Tmax_slope*exp((T - self.poly_fit_Tmax)
            #                                         *self.poly_fit_Tmax_slope
            #                                         + self.poly_fit_Tmax_value)
            # else:
            v, der = horner_and_der(self.poly_fit_coeffs, T)
            return der * exp(v)
        elif order == 2 and method == BESTFIT:
            v, der, der2 = horner_and_der2(self.poly_fit_coeffs, T)
            return (der * der + der2) * exp(v)

        return super(VaporPressure,
                     self).calculate_derivative(T, method, order)
예제 #12
0
def gibbs_excess_gammas(xs, dG_dxs, GE, T, gammas=None):
    xdx_totF = GE
    N = len(xs)
    for i in range(N):
        xdx_totF -= xs[i] * dG_dxs[i]
    RT_inv = R_inv / T
    if gammas is None:
        gammas = [0.0] * N
    for i in range(N):
        gammas[i] = exp((dG_dxs[i] + xdx_totF) * RT_inv)
    return gammas
예제 #13
0
def Psub_Clapeyron(T, Tt, Pt, Hsub_t):
    r'''Calculates sublimation pressure of a solid at arbitrary temperatures
    using an approximate themodynamic identity - the Clapeyron equation as
    described in [1]_ and [2]_.
    Requires a chemical's triple temperature, triple pressure, and triple
    enthalpy of sublimation.

    The sublimation pressure of a chemical at `T` is given by:

    .. math::
        \ln \frac{P}{P_{tp}} = -\frac{\Delta H_{sub}}{R}
        \left(\frac{1}{T}-\frac{1}{T_{tp}} \right)
        
    Parameters
    ----------
    T : float
        Temperature of solid [K]
    Tt : float
        Triple temperature of solid [K]
    Pt : float
        Truple pressure of solid [Pa]
    Hsub_t : float
        Enthalpy of fusion at the triple point of the chemical, [J/mol]

    Returns
    -------
    Psub : float
        Sublimation pressure, [Pa]

    Notes
    -----
    Does not seem to capture the decrease in sublimation pressure quickly
    enough.
    
    Examples
    --------
    >>> Psub_Clapeyron(250, Tt=273.15, Pt=611.0, Hsub_t=51100.0)
    76.06457150831804
    >>> Psub_Clapeyron(300, Tt=273.15, Pt=611.0, Hsub_t=51100.0)
    4577.282832876156
    
    References
    ----------
    .. [1] Goodman, B. T., W. V. Wilding, J. L. Oscarson, and R. L. Rowley. 
       "Use of the DIPPR Database for the Development of QSPR Correlations: 
       Solid Vapor Pressure and Heat of Sublimation of Organic Compounds." 
       International Journal of Thermophysics 25, no. 2 (March 1, 2004): 
       337-50. https://doi.org/10.1023/B:IJOT.0000028471.77933.80.
    .. [2] Feistel, Rainer, and Wolfgang Wagner. "Sublimation Pressure and 
       Sublimation Enthalpy of H2O Ice Ih between 0 and 273.16K." Geochimica et
       Cosmochimica Acta 71, no. 1 (January 1, 2007): 36-45. 
       https://doi.org/10.1016/j.gca.2006.08.034.
    '''
    return Pt * exp(Hsub_t * (T - Tt) / (R * T * Tt))
예제 #14
0
def solubility_eutectic(T, Tm, Hm, Cpl=0, Cps=0, gamma=1):
    r'''Returns the maximum solubility of a solute in a solvent.

    .. math::
        \ln x_i^L \gamma_i^L = \frac{\Delta H_{m,i}}{RT}\left(
        1 - \frac{T}{T_{m,i}}\right) - \frac{\Delta C_{p,i}(T_{m,i}-T)}{RT}
        + \frac{\Delta C_{p,i}}{R}\ln\frac{T_m}{T}

    .. math::
        \Delta C_{p,i} = C_{p,i}^L - C_{p,i}^S

    Parameters
    ----------
    T : float
        Temperature of the system [K]
    Tm : float
        Melting temperature of the solute [K]
    Hm : float
        Heat of melting at the melting temperature of the solute [J/mol]
    Cpl : float, optional
        Molar heat capacity of the solute as a liquid [J/mol/K]
    Cpls: float, optional
        Molar heat capacity of the solute as a solid [J/mol/K]
    gamma : float, optional
        Activity coefficient of the solute as a liquid [-]

    Returns
    -------
    x : float
        Mole fraction of solute at maximum solubility [-]

    Notes
    -----
    gamma is of the solute in liquid phase

    Examples
    --------
    From [1]_, matching example

    >>> solubility_eutectic(T=260., Tm=278.68, Hm=9952., Cpl=0, Cps=0, gamma=3.0176)
    0.2434007130748

    References
    ----------
    .. [1] Gmehling, Jurgen. Chemical Thermodynamics: For Process Simulation.
       Weinheim, Germany: Wiley-VCH, 2012.
    '''
    dCp = Cpl - Cps
    x = exp(-R_inv * ((Hm * (1.0 - T / Tm) - dCp *
                       (Tm - T)) / T + dCp * log(Tm / T))) / gamma
    return x
예제 #15
0
def Wagner(T, Tc, Pc, a, b, c, d):
    r'''Calculates vapor pressure using the Wagner equation (2.5, 5 form).

    Requires critical temperature and pressure as well as four coefficients
    specific to each chemical.

    .. math::
        \ln P^{sat}= \ln P_c + \frac{a\tau + b \tau^{1.5} + c\tau^{2.5}
        + d\tau^5} {T_r}

    .. math::
        \tau = 1 - \frac{T}{T_c}

    Parameters
    ----------
    T : float
        Temperature of fluid, [K]
    Tc : float
        Critical temperature, [K]
    Pc : float
        Critical pressure, [Pa]
    a, b, c, d : floats
        Parameters for wagner equation. Specific to each chemical. [-]

    Returns
    -------
    Psat : float
        Vapor pressure at T [Pa]

    Notes
    -----
    Warning: Pc is often treated as adjustable constant.

    Examples
    --------
    Methane, coefficients from [2]_, at 100 K.

    >>> Wagner(100., 190.551, 4599200, -6.02242, 1.26652, -0.5707, -1.366)
    34415.00476263708

    References
    ----------
    .. [1] Wagner, W. "New Vapour Pressure Measurements for Argon and Nitrogen and
       a New Method for Establishing Rational Vapour Pressure Equations."
       Cryogenics 13, no. 8 (August 1973): 470-82. doi:10.1016/0011-2275(73)90003-9
    .. [2] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition.
       New York: McGraw-Hill Professional, 2000.
    '''
    Tr = T / Tc
    tau = 1.0 - T / Tc
    return Pc * exp((a * tau + b * tau**1.5 + c * tau**2.5 + d * tau**5) / Tr)
예제 #16
0
    def solve_prop_poly_fit(self, goal):
        poly_fit_Tmin, poly_fit_Tmax = self.poly_fit_Tmin, self.poly_fit_Tmax
        poly_fit_Tmin_slope, poly_fit_Tmax_slope = self.poly_fit_Tmin_slope, self.poly_fit_Tmax_slope
        poly_fit_Tmin_value, poly_fit_Tmax_value = self.poly_fit_Tmin_value, self.poly_fit_Tmax_value
        coeffs = self.poly_fit_coeffs

        T_low = log(goal * exp(poly_fit_Tmin * poly_fit_Tmin_slope -
                               poly_fit_Tmin_value)) / poly_fit_Tmin_slope
        if T_low <= poly_fit_Tmin:
            return T_low
        T_high = log(goal * exp(poly_fit_Tmax * poly_fit_Tmax_slope -
                                poly_fit_Tmax_value)) / poly_fit_Tmax_slope
        if T_high >= poly_fit_Tmax:
            return T_high
        else:
            lnPGoal = log(goal)

            def to_solve(T):
                # dPsat and Psat are both in log basis
                dPsat = Psat = 0.0
                for c in coeffs:
                    dPsat = T * dPsat + Psat
                    Psat = T * Psat + c

                return Psat - lnPGoal, dPsat

            # Guess with the two extrapolations from the linear fits
            # By definition both guesses are in the range of they would have been returned
            if T_low > poly_fit_Tmax:
                T_low = poly_fit_Tmax
            if T_high < poly_fit_Tmin:
                T_high = poly_fit_Tmin
            T = newton(to_solve,
                       0.5 * (T_low + T_high),
                       fprime=True,
                       low=poly_fit_Tmin,
                       high=poly_fit_Tmax)
            return T
예제 #17
0
def Watson_sigma(T, Tc, a1, a2, a3=0.0, a4=0.0, a5=0.0):
    r'''Calculates air-water surface tension using the Watson [1]_
    emperical (parameter-regressed) method developed by NIST.
    
    .. math::
        \sigma = \exp\left[a_{1} + \ln(1 - T_r)\left(
        a_2 + a_3T_r + a_4T_r^2 + a_5T_r^3 \right)\right]

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    a1 : float
        Regression parameter, [-]
    a2 : float
        Regression parameter, [-]
    a3 : float
        Regression parameter, [-]
    a4 : float
        Regression parameter, [-]
    a5 : float
        Regression parameter, [-]

    Returns
    -------
    sigma : float
        Liquid surface tension, [N/m]

    Notes
    -----
    This expression is also used for enthalpy of vaporization in [1]_.
    The coefficients from NIST TDE for enthalpy of vaporization are kJ/mol.

    Examples
    --------
    Isooctane at 350 K from [1]_:

    >>> Watson_sigma(T=350.0, Tc=543.836, a1=-3.02417, a2=1.21792, a3=-5.26877e-9, a4=5.62659e-9, a5=-2.27553e-9)
    0.0138340926605649

    References
    ----------
    .. [1] "ThermoData Engine (TDE103b V10.1) User’s Guide." 
       https://trc.nist.gov/TDE/Help/TDE103b/Eqns-Pure-SurfaceTension/HVPExpansion-SurfaceTension.htm
    '''
    Tr = T / Tc
    l = log(1.0 - Tr)
    return exp(a1 + l * (a2 + Tr * (a3 + Tr * (a4 + a5 * Tr))))
예제 #18
0
def boiling_critical_relation(T, Tb, Tc, Pc):
    r'''Calculates vapor pressure of a fluid at arbitrary temperatures using a
    CSP relationship as in [1]_; requires a chemical's critical temperature
    and pressure as well as boiling point.

    The vapor pressure is given by:

    .. math::
        \ln P^{sat}_r = h\left( 1 - \frac{1}{T_r}\right)

    .. math::
        h = T_{br} \frac{\ln(P_c/101325)}{1-T_{br}}

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tb : float
        Boiling temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]

    Returns
    -------
    Psat : float
        Vapor pressure at T [Pa]

    Notes
    -----
    Units are Pa. Formulation makes intuitive sense; a logarithmic form of
    interpolation.

    Examples
    --------
    Example as in [1]_ for ethylbenzene

    >>> boiling_critical_relation(347.2, 409.3, 617.1, 36E5)
    15209.467273093938

    References
    ----------
    .. [1] Reid, Robert C..; Prausnitz, John M.;; Poling, Bruce E.
       The Properties of Gases and Liquids. McGraw-Hill Companies, 1987.
    '''
    Tbr = Tb / Tc
    Tr = T / Tc
    h = Tbr * log(Pc / 101325.) / (1 - Tbr)
    return exp(h * (1 - 1 / Tr)) * Pc
예제 #19
0
def Henry_pressure(T, A, B=0.0, C=0.0, D=0.0, E=0.0, F=0.0):
    r'''Calculates Henry's law constant as a function of temperature according
    to the SI units of `Pa` and using a common temperature dependence as used
    in many process simulation applications.

    Only the `A` parameter is required - which has no temperature dependence
    when used by itself.
    As the model is exponential, a sufficiently high temperature may cause an
    OverflowError.
    A negative temperature (or just low, if fit poorly) may cause a math domain
    error.

    .. math::
        H_{12} = \exp\left(A_{12} + \frac{B_{12}}{T} + C_{12}\ln(T) + D_{12}T
         + \frac{E_{12}}{T^2} \right)

    Parameters
    ----------
    T : float
        Temperature, [K]
    A-F : float
        Parameter for the equation; chemical and property specific [-]

    Returns
    -------
    H12 : float
        Henry's constant [Pa]

    Notes
    -----
    Add 11.51292 to the `A` constant if it is said to provide units of `bar`,
    so that it provides units of `Pa` instead.

    The `F` parameter is not often included in models. It is rare to fit
    all parameters.

    Examples
    --------
    Random test example.

    >>> Henry_pressure(300.0, A=15.0, B=300.0, C=.04, D=1e-3, E=1e2, F=1e-5)
    37105004.47898146

    References
    ----------
    .. [1] Gmehling, Jurgen. Chemical Thermodynamics: For Process Simulation.
       Weinheim, Germany: Wiley-VCH, 2012.
    '''
    T_inv = 1.0/T
    return exp(A + T_inv*(B + E*T_inv)  + C*log(T) + T*(D + F*T))
예제 #20
0
    def dgammas_dT(self):
        r'''Calculate and return the temperature derivatives of activity
        coefficients of a liquid phase using an activity coefficient model.

        .. math::
            \frac{\partial \gamma_i}{\partial T} =
            \left(\frac{\frac{\partial^2 n G^E}{\partial T \partial n_i}}{RT} -
            \frac{{\frac{\partial n_i G^E}{\partial n_i }}}{RT^2}\right)
             \exp\left(\frac{\frac{\partial n_i G^E}{\partial n_i }}{RT}\right)


        Returns
        -------
        dgammas_dT : list[float]
            Temperature derivatives of activity coefficients, [1/K]

        Notes
        -----
        '''
        r'''
        from sympy import *
        R, T = symbols('R, T')
        f = symbols('f', cls=Function)
        diff(exp(f(T)/(R*T)), T)
        '''
        try:
            return self._dgammas_dT
        except AttributeError:
            pass
        d2nGE_dTdns = self.d2nGE_dTdns()

        dG_dxs = self.dGE_dxs()
        GE = self.GE()
        dG_dns = dxs_to_dn_partials(dG_dxs, self.xs, GE)

        T_inv = 1.0/self.T
        RT_inv = R_inv*T_inv
        self._dgammas_dT = dgammas_dT = []
        for i in self.cmps:
            x1 = dG_dns[i]*T_inv
            dgammas_dT.append(RT_inv*(d2nGE_dTdns[i] - x1)*exp(dG_dns[i]*RT_inv))
        return dgammas_dT
예제 #21
0
def EQ101(T, A, B, C, D, E):
    r'''DIPPR Equation # 101. Used in calculating vapor pressure, sublimation
    pressure, and liquid viscosity.
    All 5 parameters are required. E is often an integer. As the model is
    exponential, a sufficiently high temperature will cause an OverflowError.
    A negative temperature (or just low, if fit poorly) may cause a math domain
    error.

    .. math::
        Y = \exp\left(A + \frac{B}{T} + C\cdot \ln T + D \cdot T^E\right)

    Parameters
    ----------
    T : float
        Temperature, [K]
    A-E : float
        Parameter for the equation; chemical and property specific [-]

    Returns
    -------
    Y : float
        Property [constant-specific]

    Notes
    -----
    This function is not integrable for either dT or Y/T dT.

    Examples
    --------
    Water vapor pressure; DIPPR coefficients normally listed in Pa.

    >>> EQ101(300, 73.649, -7258.2, -7.3037, 4.1653E-6, 2)
    3537.44834545549

    References
    ----------
    .. [1] Design Institute for Physical Properties, 1996. DIPPR Project 801
       DIPPR/AIChE
    '''
    return exp(A + B / T + C * log(T) + D * T**E)
예제 #22
0
def interaction_exp(T, N, A, B, C, D, E, F, lambdas=None):
    if lambdas is None:
        lambdas = [[0.0] * N for i in range(N)]  # numba: delete
#        lambdas = zeros((N, N)) # numba: uncomment

#        # 87% of the time of this routine is the exponential.
    T2 = T * T
    Tinv = 1.0 / T
    T2inv = Tinv * Tinv
    logT = log(T)
    for i in range(N):
        Ai = A[i]
        Bi = B[i]
        Ci = C[i]
        Di = D[i]
        Ei = E[i]
        Fi = F[i]
        lambdais = lambdas[i]
        # Might be more efficient to pass over this matrix later,
        # and compute all the exps
        # Spoiler: it was not.

        # Also - it was tested the impact of using fewer terms
        # there was very little, to no impact from that
        # the exp is the huge time sink.
        for j in range(N):
            lambdais[j] = exp(Ai[j] + Bi[j] * Tinv + Ci[j] * logT + Di[j] * T +
                              Ei[j] * T2inv + Fi[j] * T2)


#            lambdas[i][j] = exp(A[i][j] + B[i][j]*Tinv
#                    + C[i][j]*logT + D[i][j]*T
#                    + E[i][j]*T2inv + F[i][j]*T2)
#    135 µs ± 1.09 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) # without out specified numba
#    129 µs ± 2.45 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) # with out specified numba
#    118 µs ± 2.67 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) # without out specified numba 1 term
#    115 µs ± 1.77 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) # with out specified numba 1 term

    return lambdas
예제 #23
0
    def calculate(self, T, method):
        r'''Method to calculate sublimation pressure of a fluid at temperature
        `T` with a given method.

        This method has no exception handling; see :obj:`T_dependent_property <thermo.utils.TDependentProperty.T_dependent_property>`
        for that.

        Parameters
        ----------
        T : float
            Temperature at calculate sublimation pressure, [K]
        method : str
            Name of the method to use

        Returns
        -------
        Psub : float
            Sublimation pressure at T, [pa]
        '''
        if method == BESTFIT:
            if T < self.poly_fit_Tmin:
                Psub = (T - self.poly_fit_Tmin
                        ) * self.poly_fit_Tmin_slope + self.poly_fit_Tmin_value
            elif T > self.poly_fit_Tmax:
                Psub = (T - self.poly_fit_Tmax
                        ) * self.poly_fit_Tmax_slope + self.poly_fit_Tmax_value
            else:
                Psub = horner(self.poly_fit_coeffs, T)
            Psub = exp(Psub)
        elif method == PSUB_CLAPEYRON:
            Psub = max(
                Psub_Clapeyron(T, Tt=self.Tt, Pt=self.Pt, Hsub_t=self.Hsub_t),
                1e-200)
        elif method in self.tabular_data:
            Psub = self.interpolate(T, method)
        return Psub
예제 #24
0
def Edalat(T, Tc, Pc, omega):
    r'''Calculates vapor pressure of a fluid at arbitrary temperatures using a
    CSP relationship by [1]_. Requires a chemical's critical temperature,
    pressure, and acentric factor. Claimed to have a higher accuracy than the
    Lee-Kesler CSP relationship.

    The vapor pressure of a chemical at `T` is given by:

    .. math::
        \ln(P^{sat}/P_c) = \frac{a\tau + b\tau^{1.5} + c\tau^3 + d\tau^6}
        {1-\tau}
        
    .. math::
        a = -6.1559 - 4.0855\omega
        
    .. math::
        b = 1.5737 - 1.0540\omega - 4.4365\times 10^{-3} d
        
    .. math::
        c = -0.8747 - 7.8874\omega
        
    .. math::
        d = \frac{1}{-0.4893 - 0.9912\omega + 3.1551\omega^2}
        
    .. math::
        \tau = 1 - \frac{T}{T_c}
        
    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]
    omega : float
        Acentric factor [-]

    Returns
    -------
    Psat : float
        Vapor pressure, [Pa]

    Notes
    -----
    [1]_ found an average error of 6.06% on 94 compounds and 1106 data points.
    
    Examples
    --------
    >>> Edalat(347.2, 617.1, 36E5, 0.299)
    13461.273080743307

    References
    ----------
    .. [1] Edalat, M., R. B. Bozar-Jomehri, and G. A. Mansoori. "Generalized 
       Equation Predicts Vapor Pressure of Hydrocarbons." Oil and Gas Journal; 
       91:5 (February 1, 1993).
    '''
    tau = 1. - T / Tc
    a = -6.1559 - 4.0855 * omega
    c = -0.8747 - 7.8874 * omega
    d = 1. / (-0.4893 - 0.9912 * omega + 3.1551 * omega * omega)
    b = 1.5737 - 1.0540 * omega - 4.4365E-3 * d
    tau_15 = tau**1.5
    tau3 = tau_15 * tau_15
    lnPr = (a * tau + b * tau_15 + c * tau3 + d * tau3 * tau3) / (1. - tau)
    return exp(lnPr) * Pc
예제 #25
0
def Sanjari(T, Tc, Pc, omega):
    r'''Calculates vapor pressure of a fluid at arbitrary temperatures using a
    CSP relationship by [1]_. Requires a chemical's critical temperature,
    pressure, and acentric factor. Although developed for refrigerants,
    this model should have some general predictive ability.

    The vapor pressure of a chemical at `T` is given by:

    .. math::
        P^{sat} = P_c\exp(f^{(0)} + \omega f^{(1)} + \omega^2 f^{(2)})

    .. math::
        f^{(0)} = a_1 + \frac{a_2}{T_r} + a_3\ln T_r + a_4 T_r^{1.9}

    .. math::
        f^{(1)} = a_5 + \frac{a_6}{T_r} + a_7\ln T_r + a_8 T_r^{1.9}

    .. math::
        f^{(2)} = a_9 + \frac{a_{10}}{T_r} + a_{11}\ln T_r + a_{12} T_r^{1.9}

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]
    omega : float
        Acentric factor [-]

    Returns
    -------
    Psat : float
        Vapor pressure, [Pa]

    Notes
    -----
    a[1-12] are as follows:
    6.83377, -5.76051, 0.90654, -1.16906,
    5.32034, -28.1460, -58.0352, 23.57466,
    18.19967, 16.33839, 65.6995, -35.9739.

    For a claimed fluid not included in the regression, R128, the claimed AARD
    was 0.428%. A re-calculation using 200 data points from 125.45 K to
    343.90225 K evenly spaced by 1.09775 K as generated by NIST Webbook April
    2016 produced an AARD of 0.644%. It is likely that the author's regression
    used more precision in its coefficients than was shown here. Nevertheless,
    the function is reproduced as shown in [1]_.

    For Tc=808 K, Pc=1100000 Pa, omega=1.1571, this function actually declines
    after 770 K.

    Examples
    --------
    >>> Sanjari(347.2, 617.1, 36E5, 0.299)
    13651.916109552523

    References
    ----------
    .. [1] Sanjari, Ehsan, Mehrdad Honarmand, Hamidreza Badihi, and Ali
       Ghaheri. "An Accurate Generalized Model for Predict Vapor Pressure of
       Refrigerants." International Journal of Refrigeration 36, no. 4
       (June 2013): 1327-32. doi:10.1016/j.ijrefrig.2013.01.007.
    '''
    Tr = T / Tc
    Tr_inv = 1.0 / Tr
    log_Tr = log(Tr)
    Tr_19 = Tr**1.9
    f0 = 6.83377 + -5.76051 * Tr_inv + 0.90654 * log_Tr + -1.16906 * Tr_19
    f1 = 5.32034 + -28.1460 * Tr_inv + -58.0352 * log_Tr + 23.57466 * Tr_19
    f2 = 18.19967 + 16.33839 * Tr_inv + 65.6995 * log_Tr + -35.9739 * Tr_19
    return Pc * exp(f0 + omega * f1 + omega * omega * f2)
예제 #26
0
def Ambrose_Walton(T, Tc, Pc, omega):
    r'''Calculates vapor pressure of a fluid at arbitrary temperatures using a
    CSP relationship by [1]_; requires a chemical's critical temperature and
    acentric factor.

    The vapor pressure is given by:

    .. math::
        \ln P_r=f^{(0)}+\omega f^{(1)}+\omega^2f^{(2)}

    .. math::
        f^{(0)}=\frac{-5.97616\tau + 1.29874\tau^{1.5}- 0.60394\tau^{2.5}
        -1.06841\tau^5}{T_r}

    .. math::
        f^{(1)}=\frac{-5.03365\tau + 1.11505\tau^{1.5}- 5.41217\tau^{2.5}
        -7.46628\tau^5}{T_r}

    .. math::
        f^{(2)}=\frac{-0.64771\tau + 2.41539\tau^{1.5}- 4.26979\tau^{2.5}
        +3.25259\tau^5}{T_r}

    .. math::
        \tau = 1-T_{r}

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]
    omega : float
        Acentric factor [-]

    Returns
    -------
    Psat : float
        Vapor pressure at T [Pa]

    Notes
    -----
    Somewhat more accurate than the :obj:`Lee_Kesler` formulation.

    Examples
    --------
    Example from [2]_; ethylbenzene at 347.25 K.

    >>> Ambrose_Walton(347.25, 617.15, 36.09E5, 0.304)
    13278.878504306222

    References
    ----------
    .. [1] Ambrose, D., and J. Walton. "Vapour Pressures up to Their Critical
       Temperatures of Normal Alkanes and 1-Alkanols." Pure and Applied
       Chemistry 61, no. 8 (1989): 1395-1403. doi:10.1351/pac198961081395.
    .. [2] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition.
       New York: McGraw-Hill Professional, 2000.
    '''
    Tr = T / Tc
    tau = 1.0 - Tr
    tau15 = tau**1.5
    tau25 = tau * tau15
    tau5 = tau25 * tau25
    f0 = (-5.97616 * tau + 1.29874 * tau15 - 0.60394 * tau25 - 1.06841 * tau5)
    f1 = (-5.03365 * tau + 1.11505 * tau15 - 5.41217 * tau25 - 7.46628 * tau5)
    f2 = (-0.64771 * tau + 2.41539 * tau15 - 4.26979 * tau25 + 3.25259 * tau5)
    return Pc * exp((f0 + omega * (f1 + f2 * omega)) / Tr)
예제 #27
0
    def mu(self):
        try:
            return self._mu
        except AttributeError:
            pass
        phase_fractions = self.phase_fractions
        phase_count = len(phase_fractions)
        result = self.result

        if phase_count == 1:
            self._mu = mu = self.phases[0].mu()
            return mu
        elif self.state == 'l' or self.result.gas is None:
            # Multiple liquids - either a bulk liquid, or a result with no gases
            method = self.settings.mu_LL
            if method == AS_ONE_LIQUID:
                mu = self.correlations.ViscosityLiquidMixture.mixture_property(
                    self.T, self.P, self.zs, self.ws())
            else:
                mus = [i.mu() for i in self.phases]
                if method in mole_methods:
                    betas = self.phase_fractions
                elif method in mass_methods:
                    betas = self.betas_mass
                elif method in volume_methods:
                    betas = self.betas_volume

                mu = 0.0
                if method in linear_methods:
                    for i in range(len(self.phase_fractions)):
                        mu += betas[i] * mus[i]
                elif method in prop_power_methods:
                    exponent = self.settings.mu_LL_power_exponent
                    for i in range(len(self.phase_fractions)):
                        mu += betas[i] * mus[i]**exponent
                    mu = mu**(1.0 / exponent)
                elif method in log_prop_methods:
                    for i in range(len(self.phase_fractions)):
                        mu += betas[i] * log(mus[i])
                    mu = exp(mu)
            self._mu = mu
            return mu

        method = self.settings.mu_VL
        if method == AS_ONE_LIQUID:
            self._mu = mu = self.correlations.ViscosityLiquidMixture.mixture_property(
                self.T, self.P, self.zs, self.ws())
            return mu
        elif method == AS_ONE_GAS:
            self._mu = mu = self.correlations.ViscosityGasMixture.mixture_property(
                self.T, self.P, self.zs, self.ws())
            return mu

        mug = result.gas.mu()
        if phase_count == 2:
            mul = result.liquids[0].mu()
        else:
            mul = result.liquid_bulk.mu()

        if method in MU_VL_CORRELATIONS_SET:
            x = result.betas_mass[0]
            rhog = result.gas.rho_mass()
            if phase_count == 2:
                rhol = result.liquids[0].rho_mass()
            else:
                rhol = result.liquid_bulk.rho_mass()

            mu = gas_liquid_viscosity(x, mul, mug, rhol, rhog, Method=method)
        else:
            mus = [mug, mul]
            if method in mole_methods:
                VF = self.result.beta_gas
                betas = [VF, 1.0 - VF]
            elif method in mass_methods:
                betas = self.betas_mass_states[:2]
            elif method in volume_methods:
                betas = self.betas_volume_states[:2]

            if method in linear_methods:
                mu = betas[0] * mus[0] + betas[1] * mus[1]
            elif method in prop_power_methods:
                exponent = self.settings.mu_LL_power_exponent
                mu = (betas[0] * mus[0]**exponent +
                      betas[1] * mus[1]**exponent)**(1.0 / exponent)
            elif method in log_prop_methods:
                mu = exp(betas[0] * log(mus[0]) + betas[1] * log(mus[1]))
        self._mu = mu
        return mu
예제 #28
0
    def calculate(self, T, method):
        r'''Method to calculate vapor pressure of a fluid at temperature `T`
        with a given method.

        This method has no exception handling; see :obj:`thermo.utils.TDependentProperty.T_dependent_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature at calculate vapor pressure, [K]
        method : str
            Name of the method to use

        Returns
        -------
        Psat : float
            Vapor pressure at T, [pa]
        '''
        if method == BESTFIT:
            if T < self.poly_fit_Tmin:
                Psat = (T - self.poly_fit_Tmin
                        ) * self.poly_fit_Tmin_slope + self.poly_fit_Tmin_value
            elif T > self.poly_fit_Tmax:
                Psat = (T - self.poly_fit_Tmax
                        ) * self.poly_fit_Tmax_slope + self.poly_fit_Tmax_value
            else:
                Psat = horner(self.poly_fit_coeffs, T)
            Psat = exp(Psat)
        elif method == BEST_FIT_AB:
            if T < self.poly_fit_Tmax:
                return self.calculate(T, BESTFIT)
            A, B = self.poly_fit_AB_high_ABC_compat
            return exp(A + B / T)
        elif method == BEST_FIT_ABC:
            if T < self.poly_fit_Tmax:
                return self.calculate(T, BESTFIT)
            A, B, C = self.DIPPR101_ABC_high
            return exp(A + B / T + C * log(T))
        elif method == WAGNER_MCGARRY:
            Psat = Wagner_original(T, self.WAGNER_MCGARRY_Tc,
                                   self.WAGNER_MCGARRY_Pc,
                                   *self.WAGNER_MCGARRY_coefs)
        elif method == WAGNER_POLING:
            Psat = Wagner(T, self.WAGNER_POLING_Tc, self.WAGNER_POLING_Pc,
                          *self.WAGNER_POLING_coefs)
        elif method == ANTOINE_EXTENDED_POLING:
            Psat = TRC_Antoine_extended(T, *self.ANTOINE_EXTENDED_POLING_coefs)
        elif method == ANTOINE_POLING:
            A, B, C = self.ANTOINE_POLING_coefs
            Psat = Antoine(T, A, B, C, base=10.0)
        elif method == DIPPR_PERRY_8E:
            Psat = EQ101(T, *self.Perrys2_8_coeffs)
        elif method == VDI_PPDS:
            Psat = Wagner(T, self.VDI_PPDS_Tc, self.VDI_PPDS_Pc,
                          *self.VDI_PPDS_coeffs)
        elif method == COOLPROP:
            Psat = PropsSI('P', 'T', T, 'Q', 0, self.CASRN)
        elif method == BOILING_CRITICAL:
            Psat = boiling_critical_relation(T, self.Tb, self.Tc, self.Pc)
        elif method == LEE_KESLER_PSAT:
            Psat = Lee_Kesler(T, self.Tc, self.Pc, self.omega)
        elif method == AMBROSE_WALTON:
            Psat = Ambrose_Walton(T, self.Tc, self.Pc, self.omega)
        elif method == SANJARI:
            Psat = Sanjari(T, self.Tc, self.Pc, self.omega)
        elif method == EDALAT:
            Psat = Edalat(T, self.Tc, self.Pc, self.omega)
        elif method == EOS:
            Psat = self.eos[0].Psat(T)
        elif method == BESTFIT:
            Psat = exp(horner(self.poly_fit_coeffs, T))
        else:
            return self._base_calculate(T, method)
        return Psat
예제 #29
0
def collision_integral_Neufeld_Janzen_Aziz(T_star, l=1, s=1):
    r'''Calculates Lennard-Jones collision integral for any of 16 values of
    (l,j) for the wide range of 0.3 < T_star < 100. Values are accurate to
    0.1 % of actual values, but the calculation of actual values is
    computationally intensive and so these simplifications are used, developed
    in [1]_.

    .. math::
        \Omega_D = \frac{A}{T^{*B}} + \frac{C}{\exp(DT^*)} +
        \frac{E}{\exp(FT^{*})} + \frac{G}{\exp(HT^*)} + RT^{*B}\sin(ST^{*W}-P)

    Parameters
    ----------
    Tstar : float
        Reduced temperature of the fluid [-]
    l : int
        term
    s : int
        term

    Returns
    -------
    Omega : float
        Collision integral of A and B

    Notes
    -----
    Acceptable pairs of (l,s) are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5),
    (1, 6), (1, 7), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (3, 3), (3, 4),
    (3, 5), and (4, 4).

    .. math::
        T^* = \frac{k_b T}{\epsilon}

    Results are very similar to those of the more modern formulation,
    `collision_integral_Kim_Monroe`.

    Calculations begin to yield overflow errors in some values of (l, 2) after
    T_star = 75, beginning with (1, 7). Also susceptible are (1, 5) and (1, 6).

    Examples
    --------
    >>> collision_integral_Neufeld_Janzen_Aziz(100, 1, 1)
    0.516717697672334

    References
    ----------
    .. [1] Neufeld, Philip D., A. R. Janzen, and R. A. Aziz. "Empirical
       Equations to Calculate 16 of the Transport Collision Integrals
       Omega(l, S)* for the Lennard-Jones (12-6) Potential." The Journal of
       Chemical Physics 57, no. 3 (August 1, 1972): 1100-1102.
       doi:10.1063/1.1678363
    '''
    if l == 1 and s == 1:
        A, B, C, D, E, F, G, H = 1.06036, 0.1561, 0.193, 0.47635, 1.03587, 1.52996, 1.76474, 3.89411
    elif l == 1 and s == 2:
        A, B, C, D, E, F, G, H = 1.0022, 0.1553, 0.16105, 0.72751, 0.86125, 2.06848, 1.95162, 4.84492
    elif l == 1 and s == 3:
        A, B, C, D, E, F, R, S, W, P = 0.96573, 0.15611, 0.44067, 1.5242, 2.38981, 5.08063, -0.0005373, 19.2866, -1.30775, 6.58711
    elif l == 1 and s == 4:
        A, B, C, D, E, F, R, S, W, P = 0.93447, 0.15578, 0.39478, 1.85761, 2.45988, 6.15727, 0.0004246, 12.988, -1.36399, 3.3329
    elif l == 1 and s == 5:
        A, B, C, D, E, F, R, S, W, P = 0.90972, 0.15565, 0.35967, 2.18528, 2.45169, 7.17936, -0.0003814, 9.38191, 0.14025, 9.93802
    elif l == 1 and s == 6:
        A, B, C, D, E, F, R, S, W, P = 0.88928, 0.15562, 0.33305, 2.51303, 2.36298, 8.1169, -0.0004649, 9.86928, 0.12851, 9.82414
    elif l == 1 and s == 7:
        A, B, C, D, E, F, R, S, W, P = 0.87208, 0.15568, 0.36583, 3.01399, 2.70659, 9.9231, -0.0004902, 10.2274, 0.12306, 9.97712
    elif l == 2 and s == 2:
        A, B, C, D, E, F, R, S, W, P = 1.16145, 0.14874, 0.52487, 0.7732, 2.16178, 2.43787, -0.0006435, 18.0323, -0.7683, 7.27371
    elif l == 2 and s == 3:
        A, B, C, D, E, F, R, S, W, P = 1.11521, 0.14796, 0.44844, 0.99548, 2.30009, 3.06031, 0.0004565, 38.5868, -0.69403, 2.56375
    elif l == 2 and s == 4:
        A, B, C, D, E, F, R, S, W, P = 1.08228, 0.14807, 0.47128, 1.31596, 2.42738, 3.90018, -0.0005623, 3.08449, 0.28271, 3.22871
    elif l == 2 and s == 5:
        A, B, C, D, E, F, R, S, W, P = 1.05581, 0.14822, 0.51203, 1.67007, 2.57317, 4.85939, -0.000712, 4.7121, 0.2173, 4.7353
    elif l == 2 and s == 6:
        A, B, C, D, E, F, R, S, W, P = 1.03358, 0.14834, 0.53928, 2.01942, 2.7235, 5.84817, -0.0008576, 7.66012, 0.15493, 7.6011
    elif l == 3 and s == 3:
        A, B, C, D, E, F, G, H, R, S, W, P = 1.05567, 0.1498, 0.30887, 0.86437, 1.35766, 2.44123, 1.2903, 5.55734, 0.0002339, 57.7757, -1.0898, 6.9475
    elif l == 3 and s == 4:
        A, B, C, D, E, F, R, S, W, P = 1.02621, 0.1505, 0.55381, 1.4007, 2.06176, 4.26234, 0.0005227, 11.3331, -0.8209, 3.87185
    elif l == 3 and s == 5:
        A, B, C, D, E, F, R, S, W, P = 0.99958, 0.15029, 0.50441, 1.64304, 2.06947, 4.87712, -0.0005184, 3.45031, 0.26821, 3.73348
    elif l == 4 and s == 4:
        A, B, C, D, E, F, R, S, W, P = 1.12007, 0.14578, 0.53347, 1.11986, 2.28803, 3.27567, 0.0007427, 21.048, -0.28759, 6.69149
    else:
        raise ValueError('Input values of l and s are not supported')
    omega = A / T_star**B + C / exp(D * T_star) + E / exp(F * T_star)
    if (l == 1 and (s == 1 or s == 2)) or (s == 3 and l == 3):
        omega += G / exp(H * T_star)
    if not (l == 1 and (s == 1 or s == 2)):
        omega += R * T_star**B * sin(S * T_star**W - P)
    return omega
예제 #30
0
def Antoine_coeffs_from_point(T, Psat, dPsat_dT, d2Psat_dT2, base=10.0):
    r'''Calculates the antoine coefficients `A`, `B`, and `C` from a known
    vapor pressure and its first and second temperature derivative.

    Parameters
    ----------
    T : float
        Temperature of fluid, [K]
    Psat : float
        Vapor pressure at specified `T` [Pa]
    dPsat_dT : float
        First temperature derivative of vapor pressure at specified `T` [Pa/K]
    d2Psat_dT2 : float
        Second temperature derivative of vapor pressure at specified `T` [Pa/K^2]
    Base : float, optional
        Base of logarithm; 10 by default

    Returns
    -------
    A : float
        Antoine `A` parameter, [-]
    B : float
        Antoine `B` parameter, [K]
    C : float
        Antoine `C` parameter, [K]

    Notes
    -----
    Coefficients are for calculating vapor pressure in Pascal. This is 
    primarily useful for interconverting vapor pressure models, not fitting 
    experimental data.
    
    Derived with SymPy as follows:
        
    >>> from sympy import * # doctest: +SKIP
    >>> base, A, B, C, T = symbols('base, A, B, C, T') # doctest: +SKIP
    >>> v = base**(A - B/(T + C)) # doctest: +SKIP
    >>> d1, d2 = diff(v, T), diff(v, T, 2) # doctest: +SKIP
    >>> vk, d1k, d2k = symbols('vk, d1k, d2k') # doctest: +SKIP
    >>> solve([Eq(v, vk), Eq(d1, d1k), Eq(d2, d2k)], [A, B, C]) # doctest: +SKIP

    Examples
    --------
    Recalculate some coefficients from a calcualted value and its derivative:
        
    
    >>> T = 178.01
    >>> A, B, C = (24.0989474955895, 4346.793091137991, -18.96968471040141)
    >>> Psat = Antoine(T, A, B, C, base=exp(1))
    >>> dPsat_dT, d2Psat_dT2 = (0.006781441203850251, 0.0010801244983894853) # precomputed
    >>> Antoine_coeffs_from_point(T, Psat, dPsat_dT, d2Psat_dT2, base=exp(1))
    (24.098947495155453, 4346.793090994682, -18.969684713118813)
    
    References
    ----------
    .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition.
       New York: McGraw-Hill Professional, 2000.
    '''
    A = log(Psat * exp(2 * dPsat_dT**2 /
                       (dPsat_dT**2 - d2Psat_dT2 * Psat))) / log(base)
    B = 4 * dPsat_dT**3 * Psat / (
        (dPsat_dT**4 - 2 * dPsat_dT**2 * d2Psat_dT2 * Psat +
         d2Psat_dT2**2 * Psat**2) * log(base))
    C = (-T * dPsat_dT**2 + T * d2Psat_dT2 * Psat +
         2 * dPsat_dT * Psat) / (dPsat_dT**2 - d2Psat_dT2 * Psat)
    return (A, B, C)