Exemple #1
0
def omega_definition(Psat, Pc):
    r'''Returns the acentric factor of a fluid according to its fundamental
    definition using the vapor pressure at a reduced temperature of 0.7Tc.

    .. math::
        \omega \equiv -\log_{10}\left[\lim_{T/T_c=0.7}(P^{sat}/P_c)\right]-1.0

    Parameters
    ----------
    Psat : float
        Vapor pressure of the fluid at a reduced temperature of 0.7 [Pa]
    Pc : float
        Critical pressure of the fluid [Pa]

    Returns
    -------
    omega : float
        Acentric factor of the fluid [-]

    Notes
    -----

    Examples
    --------
    Water

    >>> omega_definition(999542, 22048320.0)
    0.3435744558761711

    References
    ----------
    .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition.
       New York: McGraw-Hill Professional, 2000.
    '''
    return -log10(Psat / Pc) - 1.0
Exemple #2
0
def Stiel_polar_factor(Psat, Pc, omega):
    r'''This function handles the calculation of a chemical's Stiel Polar
    factor, directly through the definition of Stiel-polar factor.
    Requires the vapor pressure `Psat` at a reduced temperature of 0.6,
    the critical pressure `Pc`, and the acentric factor `omega`.

    .. math::
        x = \log P_r|_{T_r=0.6} + 1.70 \omega + 1.552

    Parameters
    ----------
    Psat : float
        Vapor pressure of fluid at a reduced temperature of 0.6 [Pa]
    Pc : float
        Critical pressure of fluid [Pa]
    omega : float
        Acentric factor of the fluid [-]

    Returns
    -------
    factor : float
        Stiel polar factor of compound

    Notes
    -----
    A few points have also been published in [2]_, which may be used for
    comparison. Currently this is only used for a surface tension correlation.

    Examples
    --------
    Calculating the factor for water:
    
    >>> Stiel_polar_factor(Psat=169745, Pc=22048321.0, omega=0.344)
    0.02322146744772713

    References
    ----------
    .. [1] Halm, Roland L., and Leonard I. Stiel. "A Fourth Parameter for the
       Vapor Pressure and Entropy of Vaporization of Polar Fluids." AIChE
       Journal 13, no. 2 (1967): 351-355. doi:10.1002/aic.690130228.
    .. [2] D, Kukoljac Miloš, and Grozdanić Dušan K. "New Values of the
       Polarity Factor." Journal of the Serbian Chemical Society 65, no. 12
       (January 1, 2000). http://www.shd.org.rs/JSCS/Vol65/No12-Pdf/JSCS12-07.pdf
    '''
    Pr = Psat / Pc
    factor = log10(Pr) + 1.70 * omega + 1.552
    return factor
Exemple #3
0
    def nus(self):
        T, P = self.T, self.P
        Tcs, Pcs, omegas = self._Tcs, self._Pcs, self._omegas
        regular, CASs = self.regular, self._CASs
        nus = []
        limit_Tr = self.version > 0

        for i in range(self.N):
            # TODO validate and take T, P derivatives; n derivatives are from regular solution only
            Tr = T / Tcs[i]
            Pr = P / Pcs[i]

            if regular[i]:
                coeffs = self.simple_coeffs
            elif CASs[i] == '1333-74-0':
                coeffs = self.hydrogen_coeffs
            elif CASs[i] == '74-82-8':
                coeffs = self.methane_coeffs
            else:
                raise ValueError("Fail")
            A0, A1, A2, A3, A4, A5, A6, A7, A8, A9 = coeffs

            log10_v0 = A0 + A1 / Tr + A2 * Tr + A3 * Tr**2 + A4 * Tr**3 + (
                A5 + A6 * Tr + A7 * Tr**2) * Pr + (A8 +
                                                   A9 * Tr) * Pr**2 - log10(Pr)
            log10_v1 = -4.23893 + 8.65808 * Tr - 1.2206 / Tr - 3.15224 * Tr**3 - 0.025 * (
                Pr - 0.6)
            if Tr > 1.0 and limit_Tr:
                log10_v1 = 1.0

            if regular[i]:
                v = 10.0**(log10_v0 + omegas[i] * log10_v1)
            else:
                # Chao Seader mentions
                v = 10.0**(log10_v0)
            nus.append(v)
        return nus
def balance_stoichiometry(matrix, rounding=9, allow_fractional=False):
    r'''This function balances a chemical reaction.

    Parameters
    ----------
    matrix : list[list[float]]
        Chemical reaction matrix for further processing; rows contain element
         counts of each compound, and the columns represent each chemical, [-]

    Returns
    -------
    coefficients : list[float]
        Balanced coefficients; all numbers are positive, [-]

    Notes
    -----
    Balance the reaction 4 NH3 + 5 O2 = 4 NO + 6 H2O, without knowing the 
    coefficients:
        
    >>> matrix = stoichiometric_matrix([{'N': 1, 'H': 3}, {'O': 2}, {'N': 1, 'O': 1}, {'H': 2, 'O': 1}], [True, True, False, False])
    >>> matrix
    [[3, 0, 0, -2], [1, 0, -1, 0], [0, 2, -1, -1]]
    >>> balance_stoichiometry(matrix)
    [4.0, 5.0, 4.0, 6.0]
    >>> balance_stoichiometry(matrix, allow_fractional=True)
    [1.0, 1.25, 1.0, 1.5]
    
    This algorithm relies on `scipy`.
    The behavior of this function for inputs which do not have a unique 
    solution is undefined.
    
    This algorithm may suffer from floating point issues. If you believe there
    is an error in the result, please report your reaction to the developers.

    References
    ----------
    .. [1] Sen, S. K., Hans Agarwal, and Sagar Sen. "Chemical Equation 
       Balancing: An Integer Programming Approach." Mathematical and Computer 
       Modelling 44, no. 7 (October 1, 2006): 678-91.
       https://doi.org/10.1016/j.mcm.2006.02.004.
    .. [2] URAVNOTE, NOVOODKRITI PARADOKSI V. TEORIJI, and ENJA KEMIJSKIH 
       REAKCIJ. "New Discovered Paradoxes in Theory of Balancing Chemical 
       Reactions." Materiali in Tehnologije 45, no. 6 (2011): 503-22.
    '''
    import scipy.linalg
    done = scipy.linalg.null_space(matrix)
    if len(done[0]) > 1:
        raise ValueError("No solution")
    d = done[:, 0].tolist()

    min_value_inv = 1.0 / min(d)
    d = [i * min_value_inv for i in d]

    if not allow_fractional:
        from fractions import Fraction
        max_denominator = 10**rounding
        fs = [
            Fraction(x).limit_denominator(max_denominator=max_denominator)
            for x in d
        ]
        all_denominators = set([i.denominator for i in fs])
        if 1 in all_denominators:
            all_denominators.remove(1)

        for den in sorted(list(all_denominators), reverse=True):
            fs = [num * den for num in fs]
            if all(i.denominator == 1 for i in fs):
                break

        # May have gone too far
        return [float(i) for i in fs]
#        done = False
#        for i in range(100):
#            for c in d:
#                ratio = c.as_integer_ratio()[1]
#                if ratio != 1:
#                    d = [di*ratio for di in d]
#                    break
#                done = True
#            if done:
#                break
#
#        d_as_int = [int(i) for i in d]
#        for i, j in zip(d, d_as_int):
#            if i != j:
#                raise ValueError("Could not find integer coefficients (%s, %s)" %(i, j))
#        return d_as_int
    else:
        d = [round(i, rounding + int(ceil(log10(abs(i))))) for i in d]
        return d