Source code for lib.mezcla

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""Pychemqt, Chemical Engineering Process simulator
Copyright (C) 2009-2025, Juan José Gómez Romera <jjgomera@gmail.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.


This module implement mixture component properties

:class:`Mezcla`: The main class with all integrated functionality. Use the
properties in database and calculate state properties with the methods chosen
in configuration

Liquid density calculation methods:
    * :func:`RhoL_RackettMix`
    * :func:`RhoL_CostaldMix`
    * :func:`RhoL_AaltoKeskinenMix`
    * :func:`RhoL_TaitCostaldMix`
    * :func:`RhoL_NasrifarMix`
    * :func:`RhoL_APIMix`

Liquid viscosity calculation methods:
    * :func:`MuL_KendallMonroe`
    * :func:`MuL_Chemcad`

Gas viscosity calculation methods:
    * :func:`MuG_Reichenberg`
    * :func:`MuG_Lucas`
    * :func:`MuG_Chung`
    * :func:`MuG_Wilke`
    * :func:`MuG_Herning`
    * :func:`MuG_P_Chung`
    * :func:`MuG_TRAPP`
    * :func:`MuG_DeanStielMix`
    * :func:`MuG_APIMix`

Liquid thermal conductivity calculation methods:
    * :func:`ThL_Li`
    * :func:`ThL_Power`

Gas thermal conductivity calculation methods:
    * :func:`ThG_MasonSaxena`
    * :func:`ThG_LindsayBromley`
    * :func:`ThG_Chung`
    * :func:`ThG_StielThodosYorizane`
    * :func:`ThG_TRAPP`
    * :func:`ThG_P_Chung`

Surface tension calculation methods:
    * :func:`Tension`

Mixture mass definition:
    * :func:`mix_unitmassflow`
    * :func:`mix_unitmolarflow`
    * :func:`mix_massflow_massfraction`
    * :func:`mix_massflow_molarfraction`
    * :func:`mix_molarflow_massfraction`
    * :func:`mix_molarflow_molarfraction`
"""


from math import exp, pi

from numpy.lib.scimath import log10, log
from numpy.linalg import solve
from scipy.constants import R

from lib.compuestos import (Componente, RhoL_Costald, RhoL_AaltoKeskinen,
                            RhoL_TaitCostald, RhoL_Nasrifar, MuG_DeanStiel,
                            MuG_API, ThG_StielThodos)
from lib.physics import R_atml, Collision_Neufeld
from lib import unidades, config
from lib.utilities import refDoc


__doi__ = {
    1:
        {"autor": "Wilke, C.R.",
         "title": "A Viscosity Equation for Gas Mixtures",
         "ref": "J. Chem. Phys. 18(4) (1950) 517-519",
         "doi": "10.1063/1.1747673"},
    2:
        {"autor": "API",
         "title": "Technical Data book: Petroleum Refining 6th Edition",
         "ref": "",
         "doi": ""},
    3:
        {"autor": "Poling, B.E, Prausnitz, J.M, O'Connell, J.P",
         "title": "The Properties of Gases and Liquids 5th Edition",
         "ref": "McGraw-Hill, New York, 2001",
         "doi": ""},
    4:
        {"autor": "Li, C.C.",
         "title": "Thermal Conductivity of Liquid Mixtures",
         "ref": "AIChE Journal 22(5) (1976) 927-930",
         "doi": "10.1002/aic.690220520"},
    5:
        {"autor": "Lindsay, A.L., Bromley, L.A.",
         "title": "Thermal Conductivity of Gas Mixtures",
         "ref": "Ind. & Eng. Chem. 42(8) (1950) 1508-1511",
         "doi": "10.1021/ie50488a017"},
    6:
        {"autor": "Mason, E.A., Saxena, S.C.",
         "title": "Approximate Formula for the Thermal Conductivity of Gas "
                  "Mixtures",
         "ref": "Fhys. Fluids 1(5) (1958) 361-369",
         "doi": "10.1063/1.1724352"},
    7:
        {"autor": "Yorizane, M., Yoshiumra, S., Masuoka, H., Yoshida, H.",
         "title": "Thermal Conductivities of Binary Gas Mixtures at High "
                  "Pressures: N2-O2, N2-Ar, CO2-Ar, CO2-CH4",
         "ref": "Ind. Eng. Chem. Fundam. 22(4) (1983) 458-462",
         "doi": "10.1021/i100012a018"},
    8:
        {"autor": "Livingston, J.k Morgan, R., Griggs, M.A.",
         "title": "The Properties of Mixed Liquids III. The Law of Mixtures I",
         "ref": "J. Am. Chem. Soc. 39 (1917) 2261-2275",
         "doi": "10.1021/ja02256a002"},
    9:
        {"autor": "Spencer, C.F., Danner, R.P.",
         "title": "Prediction of Bubble-Point Density of Mixtures",
         "ref": "J. Chem. Eng. Data 18(2) (1973) 230-234",
         "doi": "10.1021/je60057a007"},
    10:
        {"autor": "Hankinson, R.W., Thomson, G.H.",
         "title": "A New Correlation for Saturated Densities of Liquids and "
                  "Their Mixtures",
         "ref": "AIChE Journal 25(4) (1979) 653-663",
         "doi": "10.1002/aic.690250412"},
    11:
        {"autor": "Aalto, M., Keskinen, K.I., Aittamaa, J., Liukkonen, S.",
         "title": "An Improved Correlation for Compressed Liquid Densities of "
                  "Hydrocarbons. Part 2. Mixtures",
         "ref": "Fluid Phase Equilibria 114 (1996) 21-35",
         "doi": "10.1016/0378-3812(95)02824-2"},
    12:
        {"autor": "Thomson, G.H., Brobst, K.R., Hankinson, R.W.",
         "title": "An Improved Correlation for Densities of Compressed Liquids"
                  " and Liquid Mixtures",
         "ref": "AIChE Journal 28(4) (1982): 671-76",
         "doi": "10.1002/aic.690280420"},
    13:
        {"autor": "Nasrifar, K., Ayatollahi, S., Moshfeghian, M.",
         "title": "A Compressed Liquid Density Correlation",
         "ref": "Fluid Phase Equilibria 168 (2000) 149-163",
         "doi": "10.1016/s0378-3812(99)00336-2"},
    14:
        {"autor": "Rea, H.E., Spencer, C.F., Danner, R.P.",
         "title": "Effect of Pressure and Temperature on the Liquid Densities "
                  "of Pure Hydrocarbons",
         "ref": "J. Chem. Eng. Data 18(2) (1973) 227-230",
         "doi": "10.1021/je60057a003"},
    15:
        {"autor": "Chung, T.H., Ajlan, M., Lee, L.L., Starling, K.E.",
         "title": "Generalized Multiparameter Correlation for Nonpolar and "
                  "Polar Fluid Transport Properties",
         "ref": "Ind. Eng. Chem. Res. 27(4) (1988) 671-679",
         "doi": "10.1021/ie00076a024"},
    16:
        {"autor": "Younglove, B.A., Ely, J.F.",
         "title": "Thermophysical Properties of Fluids. II. Methane, Ethane, "
                  "Propane, Isobutane, and Normal Butane",
         "ref": "J. Phys. Chem. Ref. Data 16(4) (1987) 577-798",
         "doi": "10.1063/1.555785"},
    17:
        {"autor": "Ely, J.F.",
         "title": "An Enskog Correction for Size and Mass Difference Effects "
                  "in Mixture Viscosity Prediction",
         "ref": "J. Res. Natl. Bur. Stand. 86(6) (1981) 597-604",
         "doi": "10.6028/jres.086.028"},
    18:
        {"autor": "Chueh, P.L., Prausnitz, J.M.",
         "title": "Vapor-Liquid Equilibria at High Pressures: Calculation of "
                  "Critical Temperatures, Volumes and Pressures of Nonpolar "
                  "Mixtures",
         "ref": "AIChE Journal 13(6) (1967) 1107-1113",
         "doi": "10.1002/aic.690130613"},
    19:
        {"autor": "Dean, D.E., Stiel, L.I.",
         "title": "The Viscosity of Nonpolar Gas Mixtures at Moderate and High"
                  " Pressures",
         "ref": "AIChE Journal 11(3) (1965) 526-532 ",
         "doi": "10.1002/aic.690110330"},
    20:
        {"autor": "Kendall, J., Monroe, P.",
         "title": "The Viscosity of Liquids II. The Viscosity-Composition "
                  "Curve for Ideal Liquid Mixtures",
         "ref": "J. Am. Chem. Soc. 39(9) (1917) 1787-1802",
         "doi": "10.1021/ja02254a001"},
    21:
        {"autor": "Ely, J.F., Hanley, H.J.M.",
         "title": "A Computer Program for the Prediction of Viscosity and "
                  "Thermal Condcutivity in Hydrocarbon Mixtures",
         "ref": "NBS Technical Note 1039 (1981)",
         "doi": ""},
}


[docs] def mix_unitmassflow(unitMassFlow, cmps): """Calculate mixture composition properties with known unitMassFlow""" massFlow = sum(unitMassFlow) unitMolarFlow = [mass/cmp.M for mass, cmp in zip(unitMassFlow, cmps)] molarFlow = sum(unitMolarFlow) molarFraction = [mi/molarFlow for mi in unitMolarFlow] massFraction = [mi/massFlow for mi in unitMassFlow] kw = {} kw["unitMassFlow"] = unitMassFlow kw["unitMolarFlow"] = unitMolarFlow kw["molarFlow"] = molarFlow kw["massFlow"] = massFlow kw["molarFraction"] = molarFraction kw["massFraction"] = massFraction return kw
[docs] def mix_unitmolarflow(unitMolarFlow, cmps): """Calculate mixture composition properties with known unitMolarFlow""" molarFlow = sum(unitMolarFlow) unitMassFlow = [mol*cmp.M for mol, cmp in zip(unitMolarFlow, cmps)] massFlow = sum(unitMassFlow) molarFraction = [mi/molarFlow for mi in unitMolarFlow] massFraction = [mi/massFlow for mi in unitMassFlow] kw = {} kw["unitMassFlow"] = unitMassFlow kw["unitMolarFlow"] = unitMolarFlow kw["molarFlow"] = molarFlow kw["massFlow"] = massFlow kw["molarFraction"] = molarFraction kw["massFraction"] = massFraction return kw
[docs] def mix_massflow_molarfraction(massFlow, molarFraction, cmps): """Calculate mixture composition properties with known massFlow and molarFraction""" pesos = [x*cmp.M for x, cmp in zip(molarFraction, cmps)] M = sum(pesos) molarFlow = massFlow/M massFraction = [peso/M for peso in pesos] unitMassFlow = [x*massFlow for x in massFraction] unitMolarFlow = [x*molarFlow for x in molarFraction] kw = {} kw["unitMassFlow"] = unitMassFlow kw["unitMolarFlow"] = unitMolarFlow kw["molarFlow"] = molarFlow kw["massFlow"] = massFlow kw["molarFraction"] = molarFraction kw["massFraction"] = massFraction return kw
[docs] def mix_massflow_massfraction(massFlow, massFraction, cmps): """Calculate mixture composition properties with known massFlow and massFraction""" unitMassFlow = [x*massFlow for x in massFraction] unitMolarFlow = [mass/cmp.M for mass, cmp in zip(unitMassFlow, cmps)] molarFlow = sum(unitMolarFlow) molarFraction = [mi/molarFlow for mi in unitMolarFlow] kw = {} kw["unitMassFlow"] = unitMassFlow kw["unitMolarFlow"] = unitMolarFlow kw["molarFlow"] = molarFlow kw["massFlow"] = massFlow kw["molarFraction"] = molarFraction kw["massFraction"] = massFraction return kw
[docs] def mix_molarflow_molarfraction(molarFlow, molarFraction, cmps): """Calculate mixture composition properties with known molarFlow and molarFraction""" unitMolarFlow = [x*molarFlow for x in molarFraction] unitMassFlow = [mol*cmp.M for mol, cmp in zip(unitMolarFlow, cmps)] massFlow = sum(unitMassFlow) massFraction = [mi/massFlow for mi in unitMassFlow] kw = {} kw["unitMassFlow"] = unitMassFlow kw["unitMolarFlow"] = unitMolarFlow kw["molarFlow"] = molarFlow kw["massFlow"] = massFlow kw["molarFraction"] = molarFraction kw["massFraction"] = massFraction return kw
[docs] def mix_molarflow_massfraction(molarFlow, massFraction, cmps): """Calculate mixture composition properties with known molarFlow and massFraction""" moles = [x/cmp.M for x, cmp in zip(massFraction, cmps)] M = sum(moles) massFlow = molarFlow*M molarFraction = [mol/molarFlow for mol in moles] unitMassFlow = [x*massFlow for x in massFraction] unitMolarFlow = [x*molarFlow for x in molarFraction] kw = {} kw["unitMassFlow"] = unitMassFlow kw["unitMolarFlow"] = unitMolarFlow kw["molarFlow"] = molarFlow kw["massFlow"] = massFlow kw["molarFraction"] = molarFraction kw["massFraction"] = massFraction return kw
[docs] @refDoc(__doi__, [18, 2]) def Vc_ChuehPrausnitz(xi, Vci, Mi, hydrocarbon=None): r"""Calculates critic volume of a mixture using the Chueh-Prausnitz correlation, also referenced in API procedure 4B3.1 pag 314 .. math:: V_{cm} = \sum_i^n\phi_iV_{ci}+\sum_i^n\sum_j^n\phi_i\phi_j\upsilon_{ij} .. math:: \phi_j = \frac{x_jV_{cj}^{2/3}}{\sum_{i=1}^nx_iV_{ci}^{2/3}} .. math:: \upsilon_{ij} = \frac{V_{ij}\left(V_{ci}+V_{cj}\right)}{2} .. math:: V_{ij} = -1.4684\eta_{ij}+C .. math:: \eta_{ij} = \left|\frac{V_{ci}-V_{cj}}{V_{ci}+V_{cj}}\right| Parameters ---------- xi : list Mole fractions of components, [-] Vci : list Critical volume of components, [m³/kg] Mi : list Molecular weight of components, [g/mol] hydrocarbon : list, optional Hydrocarbon flag of components, default True for all components Returns ------- Vcm : float Critical volume of mixture, [m³/kg] Examples -------- Example from [2]_; 63% nC4 37% nC7 >>> Vc1 = unidades.SpecificVolume(0.0704, "ft3lb") >>> Vc2 = unidades.SpecificVolume(0.0691, "ft3lb") >>> Mi = [58.12, 100.2] >>> Mm = Mi[0]*0.63+Mi[1]*0.37 >>> "%0.2f" % (Vc_ChuehPrausnitz([0.63, 0.37], [Vc1, Vc2], Mi).ft3lb*Mm) '4.35' """ # Define default C parameters: if hydrocarbon is None: hydrocarbon = [True]*len(xi) # Convert critical volumes to molar base Vci = [Vc*M for Vc, M in zip(Vci, Mi)] Mm = sum([M*x for M, x in zip(Mi, xi)]) Vij = [] for Vc_i, C_i in zip(Vci, hydrocarbon): Viji = [] for Vc_j, C_j in zip(Vci, hydrocarbon): if C_i and C_j: C = 0 else: C = 0.1559 mu = abs((Vc_i-Vc_j)/(Vc_i+Vc_j)) Viji.append(-1.4684*mu + C) Vij.append(Viji) nuij = [] for Viji, Vc_i in zip(Vij, Vci): nuiji = [] for V, Vc_j in zip(Viji, Vci): nuiji.append(V*(Vc_i+Vc_j)/2) nuij.append(nuiji) # Eq 2 phii = [] for x_j, Vc_j in zip(xi, Vci): suma = sum([x_i*Vc_i**(2/3) for x_i, Vc_i in zip(xi, Vci)]) phii.append(x_j*Vc_j**(2/3)/suma) # Eq 4 generalized sum1 = sum([phi*Vc for phi, Vc in zip(phii, Vci)]) sum2 = 0 for phi_i, nuiji in zip(phii, nuij): for phi_j, nu in zip(phii, nuiji): sum2 += phi_i*phi_j*nu Vcm = sum1 + sum2 return unidades.SpecificVolume(Vcm/Mm)
# Liquid density correlations
[docs] @refDoc(__doi__, [9, 2, 3]) def RhoL_RackettMix(T, xi, Tci, Pci, Vci, Zrai, Mi): r"""Calculates saturated liquid densities of muxteres using the modified Rackett equation by Spencer-Danner, also referenced in API procedure 6A3.1 pag 479 .. math:: \frac{1}{\rho_{bp}} = R\left(\sum_i x_i \frac{T_{ci}}{P_{ci}}\right) Z_{RAm}^{1+\left(1+T_r\right)^{2/7}} .. math:: Z_{RAm} = \sum_i x_iZ_{RAi} .. math:: T_{cm} = \sum_i \phi_iT_{ci} .. math:: \phi_i = \frac{x_iV_{ci}}{\sum_i x_iV_{ci}} .. math:: 1-k_{ij} = \frac{8\left(V_{ci}V{cj}\right)^{1/2}} {\left(V_{ci}^{1/3}+V_{cj}^{1/3}\right)^3} .. math:: T_{cij} = \left(1+k{ij}\right)\left(T_{ci}T_{cj}\right)^{1/2} Parameters ---------- T : float Temperature, [K] xi : list Mole fractions of components, [-] Tci : list Critical temperature of components, [K] Pci : list Critical pressure of components, [Pa] Vci : list Critical volume of components, [m³/kg] Zrai : list Racket constant of components, [-] Mi : list Molecular weight of components, [g/mol] Returns ------- rho : float Bubble point liquid density at T, [kg/m³] Examples -------- Example from [2]_; 58.71% ethane, 41.29% heptane at 91ºF >>> T = unidades.Temperature(91, "F") >>> xi = [0.5871, 0.4129] >>> Tc1 = unidades.Temperature(89.92, "F") >>> Tc2 = unidades.Temperature(512.7, "F") >>> Pc1 = unidades.Pressure(706.5, "psi") >>> Pc2 = unidades.Pressure(396.8, "psi") >>> Vc1 = unidades.SpecificVolume(0.0788, "ft3lb") >>> Vc2 = unidades.SpecificVolume(0.0691, "ft3lb") >>> Zrai = [0.2819, 0.261] >>> Mi = [30.07, 100.205] >>> args = (T, xi, [Tc1, Tc2], [Pc1, Pc2], [Vc1, Vc2], Zrai, Mi) >>> "%0.2f" % RhoL_RackettMix(*args).kgl '0.56' Example 5-3 from [3]_; 70% ethane, 30% nC10 at 344.26K >>> xi = [0.7, 0.3] >>> Tci = [305.32, 617.7] >>> Pci = [48.72e5, 21.1e5] >>> Vci = [145.5/1000, 624/1000] >>> Zrai = [0.282, 0.247] >>> Mi = [1, 1] >>> args = (344.26, [0.7, 0.3], Tci, Pci, Vci, Zrai, Mi) >>> "%0.1f" % (1/RhoL_RackettMix(*args).gcc) '120.0' """ # Convert critical volumes to molar base Vci = [Vc*M for Vc, M in zip(Vci, Mi)] # Eq 11 Zram = 0 for x, Zra in zip(xi, Zrai): Zram += x*Zra # Eq 13 suma = 0 for x, Vc in zip(xi, Vci): suma += x*Vc phi = [] for x, Vc in zip(xi, Vci): phi.append(x*Vc/suma) # Eq 16 kij = [] for Vc_i in Vci: kiji = [] for Vc_j in Vci: kiji.append(1-8*((Vc_i**(1/3)*Vc_j**(1/3))**0.5/( Vc_i**(1/3)+Vc_j**(1/3)))**3) kij.append(kiji) # Eq 15 Tcij = [] for Tc_i, kiji in zip(Tci, kij): Tciji = [] for Tc_j, k in zip(Tci, kiji): Tciji.append((Tc_i*Tc_j)**0.5*(1-k)) Tcij.append(Tciji) # Eq 14 Tcm = 0 for phi_i, Tciji in zip(phi, Tcij): for phi_j, Tc in zip(phi, Tciji): Tcm += phi_i*phi_j*Tc # Eq 10 suma = 0 for x, Tc, Pc in zip(xi, Tci, Pci): suma += x*Tc/Pc*101325 Tr = T/Tcm V = R_atml*suma*Zram**(1+(1-Tr)**(2/7)) Mm = sum([M*x for M, x in zip(Mi, xi)]) return unidades.Density(Mm/V)
[docs] @refDoc(__doi__, [10, 2, 3]) def RhoL_CostaldMix(T, xi, Tci, wi, Vci, Mi): r"""Calculates saturated liquid densities of pure components using the Corresponding STAtes Liquid Density (COSTALD) method, developed by Hankinson and Thomson, referenced too in API procedure 6A3.2 pag. 482 .. math:: T_{cm} = \frac{\sum_i\sum_jx_ix_j\left(V_i^oT_{ci}V_j^oT_{cj}\right) ^{1/2}}{V_m^o} .. math:: V_m^o = \frac{\sum_i xiV_i^o + 3 \sum_i x_iV_i^{o^{2/3}} \sum_i x_iV_i^{o^{1/3}}}{4} .. math:: \omega_m = \sum_i x_i\omega_{SRKi} Parameters ---------- T : float Temperature [K] xi : list Mole fractions of components, [-] Tci : list Critical temperature of components, [K] wi : list Acentric factor optimized to SRK of components, [-] Vci : list Characteristic volume of components, [m³/kg] Mi : list Molecular weight of components, [g/mol] Returns ------- rho : float Bubble point liquid density at T, [kg/m³] Examples -------- Example from [2]_; 20% methane, 80% nC10 at 160ºF >>> T = unidades.Temperature(160, "F") >>> Tc1 = unidades.Temperature(-116.67, "F") >>> Tc2 = unidades.Temperature(652, "F") >>> Vc1 = unidades.SpecificVolume(1.592/16.04, "ft3lb") >>> Vc2 = unidades.SpecificVolume(9.919/142.28, "ft3lb") >>> Mi = [16.04, 142.28] >>> args = (T, [0.2, 0.8], [Tc1, Tc2], [0.0074, 0.4916], [Vc1, Vc2], Mi) >>> "%0.3f" % RhoL_CostaldMix(*args).kgl '0.667' Example 5-3 from [3]_; 70% ethane, 30% nC10 at 344.26K >>> xi = [0.7, 0.3] >>> Tci = [305.32, 617.7] >>> Vci = [145.5/1000, 624/1000] >>> wi = [0.099, 0.491] >>> Mi = [1, 1] >>> args = (344.26, [0.7, 0.3], Tci, wi, Vci, Mi) >>> "%0.1f" % (1/RhoL_CostaldMix(*args).gcc) '119.5' """ # Convert critical volumes to molar base Vci = [Vc*M for Vc, M in zip(Vci, Mi)] # Apply mixing rules # Eq 24 wm = 0 for x, w in zip(xi, wi): wm += x*w # Eq 21 sum1 = 0 sum2 = 0 sum3 = 0 for x, Vc, Tc in zip(xi, Vci, Tci): sum1 += x*Vc sum2 += x*Vc**(2/3) sum3 += x*Vc**(1/3) Vcm = (sum1+3*sum2*sum3)/4 # Eq 19 & 21 Tcm = 0 for x_i, Vc_i, Tc_i in zip(xi, Vci, Tci): for x_j, Vc_j, Tc_j in zip(xi, Vci, Tci): Tcm += x_i*x_j*(Vc_i*Tc_i*Vc_j*Tc_j)**0.5 Tcm /= Vcm Mm = sum([M*x for M, x in zip(Mi, xi)]) # Apply the pure component procedure with the mixing parameters rho = RhoL_Costald(T, Tcm, wm, Vcm) return unidades.Density(rho*Mm)
[docs] @refDoc(__doi__, [11, 3]) def RhoL_AaltoKeskinenMix(T, P, xi, Tci, Pci, Vci, wi, Mi, rhos): r"""Calculates compressed-liquid density of a mixture, using the Aalto-Keskinen modification of Chang-Zhao correlation .. math:: T_{cm} = \frac{\sum_i\sum_jx_ix_j\left(V_i^oT_{ci}V_j^oT_{cj}\right) ^{1/2}}{V_m^o} .. math:: V_m^o = \frac{\sum_i xiV_i^o + 3 \sum_i x_iV_i^{o^{2/3}} \sum_i x_iV_i^{o^{1/3}}}{4} .. math:: P_{cm} = \frac{\left(0.291-0.08\omega_{SRKm}\right)RT_{cm}}{V_{cm}} .. math:: \omega_{SRKm} = \left(\sum_i x_i\omega_{SRKi}\right)^2 Parameters ---------- T : float Temperature, [K] P : float Pressure, [Pa] xi : list Mole fractions of components, [-] Tci : list Critical temperature of components, [K] Pci : list Critical pressure of components, [Pa] Vci : list Critical volume of components, [m³/kg] wi : list Acentric factor (SRK optimized) of components, [-] Mi : list Molecular weight of components, [g/mol] rhos : float Boiling point liquid density, [kg/m³] Returns ------- rho : float High-pressure liquid density, [kg/m³] Examples -------- Example 5-4 from [3]_; 70% ethane, 30% nC10 at 344.26K and 10000psi >>> P = unidades.Pressure(10000, "psi") >>> xi = [0.7, 0.3] >>> Tci = [305.32, 617.7] >>> Pci = [48.72e5, 21.1e5] >>> Vci = [145.5/1000, 624/1000] >>> wi = [0.099, 0.491] >>> Mi = [1, 1] >>> args = (344.26, P, xi, Tci, Pci, Vci, wi, Mi, 1/116.43*1000) >>> "%0.2f" % (1/RhoL_AaltoKeskinenMix(*args).gcc) '99.05' """ # Convert critical volumes to molar base Vci = [Vc*M for Vc, M in zip(Vci, Mi)] # Apply mixing rules # Eq A5 wm = 0 for x, w in zip(xi, wi): # Avoid problem with square root of negative number, hydrogen, methane if w < 0: w = 0 wm += x*w**0.5 wm *= wm # Eq 2 sum1 = 0 sum2 = 0 sum3 = 0 for x, Vc, Tc in zip(xi, Vci, Tci): sum1 += x*Vc sum2 += x*Vc**(2/3) sum3 += x*Vc**(1/3) Vcm = (sum1+3*sum2*sum3)/4 # Eq 1 Tcm = 0 for x_i, Vc_i, Tc_i in zip(xi, Vci, Tci): for x_j, Vc_j, Tc_j in zip(xi, Vci, Tci): Tcm += x_i*x_j*(Vc_i*Tc_i*Vc_j*Tc_j)**0.5 Tcm /= Vcm # Eq 4 Pcm = (0.291-0.08*wm)*R*Tcm/Vcm*1000 Ps = _Pv(T, Tcm, Pcm, wm) # Apply the pure component procedure with the mixing parameters rho = RhoL_AaltoKeskinen(T, P, Tcm, Pcm, wm, Ps, rhos) return unidades.Density(rho)
[docs] @refDoc(__doi__, [12, 2]) def RhoL_TaitCostaldMix(T, P, xi, Tci, Vci, wi, Mi, rhos): r"""Calculates compressed-liquid density of a mixture, using the Thomson-Brobst-Hankinson modification of Chang-Zhao correlation adapted to mixtures, also referenced in API procedure 6A3.4, pag 489 .. math:: T_{cm} = \frac{\sum_i\sum_jx_ix_j\left(V_i^oT_{ci}V_j^oT_{cj}\right) ^{1/2}}{V_m^o} .. math:: V_m^o = \frac{\sum_i xiV_i^o + 3 \sum_i x_iV_i^{o^{2/3}} \sum_i x_iV_i^{o^{1/3}}}{4} .. math:: P_{cm} = \frac{\left(0.291-0.08\omega_{SRKm}\right)RT_{cm}}{V_{cm}} .. math:: \omega_{SRKm} = \left(\sum_i x_i\omega_{SRKi}\right)^2 .. math:: \frac{P_s}{P_{cm}} = P_m^{(0)}+\omega_{SRKm}P_m^{(1)} .. math:: P_m^{(0)} = 5.8031817 \log T_{rm}+0.07608141\alpha .. math:: P_m^{(1)} = 4.86601\beta .. math:: \alpha = 35 - \frac{36}{T_{rm}}-96.736\log T_{rm}+T_{rm}^6 .. math:: \beta = \log T_{rm}+0.03721754\alpha Parameters ---------- T : float Temperature, [K] P : float Pressure, [Pa] xi : list Mole fractions of components, [-] Tci : list Critical temperature of components, [K] Vci : list Critical volume of components, [m³/kg] wi : list Acentric factor (SRK optimized) of components, [-] Mi : list Molecular weight of components, [g/mol] rhos : float Boiling point liquid density, [kg/m³] Returns ------- rho : float High-pressure liquid density, [kg/m³] Examples -------- Example from [2]_; 20% ethane, 80% nC10 at 166F and 3000psi >>> T = unidades.Temperature(160, "F") >>> P = unidades.Pressure(3000, "psi") >>> xi = [0.2, 0.8] >>> Tc1 = unidades.Temperature(89.92, "F") >>> Tc2 = unidades.Temperature(652, "F") >>> Tci = [Tc1, Tc2] >>> Mi = [30.07, 142.286] >>> Vc1 = unidades.SpecificVolume(2.335/Mi[0], "ft3lb") >>> Vc2 = unidades.SpecificVolume(9.919/Mi[1], "ft3lb") >>> Vci = [Vc1, Vc2] >>> wi = [0.0983, 0.4916] >>> >>> Vs = unidades.SpecificVolume(2.8532/119.8428, "ft3lb") >>> args = (T, P, xi, Tci, Vci, wi, Mi, 1/Vs) >>> "%0.3f" % RhoL_TaitCostaldMix(*args).gcc '0.698' """ # Convert critical volumes to molar base Vci = [Vc*M for Vc, M in zip(Vci, Mi)] # Apply mixing rules # Eq 16 wm = 0 for x, w in zip(xi, wi): wm += x*w # Eq 15 sum1 = 0 sum2 = 0 sum3 = 0 for x, Vc, Tc in zip(xi, Vci, Tci): sum1 += x*Vc sum2 += x*Vc**(2/3) sum3 += x*Vc**(1/3) Vcm = (sum1+3*sum2*sum3)/4 # Eq 13 Tcm = 0 for x_i, Vc_i, Tc_i in zip(xi, Vci, Tci): for x_j, Vc_j, Tc_j in zip(xi, Vci, Tci): Tcm += x_i*x_j*(Vc_i*Tc_i*Vc_j*Tc_j)**0.5 Tcm /= Vcm # Eq 17 Pcm = (0.291-0.08*wm)*R*Tcm/Vcm*1000 # Saturation Pressure Ps = _Pv(T, Tcm, Pcm, wm) # Apply the pure component procedure with the mixing parameters rho = RhoL_TaitCostald(T, P, Tcm, Pcm, wm, Ps, rhos) return unidades.Density(rho)
[docs] @refDoc(__doi__, [13]) def RhoL_NasrifarMix(T, P, xi, Tci, Vci, wi, Mi, rhos): r"""Calculates compressed-liquid density of a mixture, using the Nasrifar correlation .. math:: T_{cm} = \frac{\sum_i\sum_jx_ix_j\left(V_i^oT_{ci}V_j^oT_{cj}\right) ^{1/2}}{V_m^o} .. math:: V_m^o = \frac{\sum_i xiV_i^o + 3 \sum_i x_iV_i^{o^{2/3}} \sum_i x_iV_i^{o^{1/3}}}{4} .. math:: P_{cm} = \frac{\left(0.291-0.08\omega_{SRKm}\right)RT_{cm}}{V_{cm}} .. math:: \omega_{SRKm} = \sum_i x_i\omega_{SRKi} Parameters ---------- T : float Temperature, [K] P : float Pressure, [Pa] xi : list Mole fractions of components, [-] Tci : list Critical temperature of components, [K] Vci : list Critical volume of components, [m³/kg] wi : list Acentric factor (SRK optimized) of components, [-] Mi : list Molecular weight of components, [g/mol] rhos : float Boiling point liquid density, [kg/m³] Returns ------- rho : float High-pressure liquid density, [kg/m³] """ # Convert critical volumes to molar base Vci = [Vc*M for Vc, M in zip(Vci, Mi)] # Apply mixing rules # Eq 25 wm = 0 for x, w in zip(xi, wi): wm += x*w # Eq 24 sum1 = 0 sum2 = 0 sum3 = 0 for x, Vc, Tc in zip(xi, Vci, Tci): sum1 += x*Vc sum2 += x*Vc**(2/3) sum3 += x*Vc**(1/3) Vcm = (sum1+3*sum2*sum3)/4 # Eq 22 Tcm = 0 for x_i, Vc_i, Tc_i in zip(xi, Vci, Tci): for x_j, Vc_j, Tc_j in zip(xi, Vci, Tci): Tcm += x_i*x_j*(Vc_i*Tc_i*Vc_j*Tc_j)**0.5 Tcm /= Vcm Mm = 0 for x, M in zip(xi, Mi): Mm += x*M # Eq 26 Pcm = (0.291-0.08*wm)*R*Tcm/Vcm*1000 # Saturation Pressure Ps = _Pv(T, Tcm, Pcm, wm) # Apply the pure component procedure with the mixing parameters rho = RhoL_Nasrifar(T, P, Tcm, Pcm, wm, Mm, Ps, rhos) return unidades.Density(rho)
[docs] @refDoc(__doi__, [14, 2]) def RhoL_APIMix(T, P, xi, Tci, Pci, rhos, To=None, Po=None): r"""Calculates compressed-liquid density, using the analytical expression of Lu Chart referenced in API procedure 6A2.22 .. math:: \rho_2 = \rho_1\frac{C_2}{C_1} Parameters ---------- T : float Temperature, [K] P : float Pressure, [Pa] xi : list Mole fractions of components, [-] Tci : list Critical temperature of components, [K] Pci : list Critical pressure of components, [Pa] rhos : float Liquid density at 60ºF, [kg/m^3] To : float, optional Reference temperature with known density, [K] Po : float, optional Reference pressure with known density, [Pa] Returns ------- rho : float High-pressure liquid density, [kg/m^3] Examples -------- Example A from [2]; 60.52% Ethylene, 39.48% n-heptane at 162.7ºF and 900psi >>> T = unidades.Temperature(162.7, "F") >>> P = unidades.Pressure(900, "psi") >>> x = [0.6052, 0.3948] >>> Tc = unidades.Temperature(48.58, "F") >>> Tc2 = unidades.Temperature(512.7, "F") >>> Pc = unidades.Pressure(729.8, "psi") >>> Pc2 = unidades.Pressure(396.8, "psi") >>> rs = unidades.Density(37.55, "lbft3") >>> To = unidades.Temperature(49, "F") >>> Po = unidades.Pressure(400, "psi") >>> "%0.1f" % RhoL_APIMix(T, P, x, [Tc, Tc2], [Pc, Pc2], rs, To, Po).lbft3 '31.5' Example C from [2]; 20% methane, 80% n-C10 at 160ºF and 3000psi >>> T = unidades.Temperature(162.7, "F") >>> P = unidades.Pressure(900, "psi") >>> x = [0.2, 0.8] >>> Tc1 = unidades.Temperature(-116.63, "F") >>> Tc2 = unidades.Temperature(652.1, "F") >>> Pc1 = unidades.Pressure(667.8, "psi") >>> Pc2 = unidades.Pressure(304, "psi") >>> rs = unidades.Density(41.65, "lbft3") >>> "%0.1f" % RhoL_APIMix(T, P, x, [Tc1, Tc2], [Pc1, Pc2], rs).lbft3 '42.6' """ # Define reference state if To is None: To = T if Po is None: Po = 101325 # Calculate pseudocritical properties Tc = 0 Pc = 0 for x, Tc_i, Pc_i in zip(xi, Tci, Pci): Tc += x*Tc_i Pc += x*Pc_i def C(Tr, Pr): """Polinomial ajust of Lu chart, referenced in [14]""" A0 = 1.6368-0.04615*Pr+2.1138e-3*Pr**2-0.7845e-5*Pr**3-0.6923e-6*Pr**4 A1 = -1.9693+0.21874*Pr-8.0028e-3*Pr**2-8.2328e-5*Pr**3+5.2604e-6*Pr**4 A2 = 2.4638-.36461*Pr+12.8763e-3*Pr**2+14.8059e-5*Pr**3-8.6895e-6*Pr**4 A3 = -1.5841+.25136*Pr-11.3805e-3*Pr**2+9.5672e-5*Pr**3+2.1812e-6*Pr**4 C = A0 + A1*Tr + A2*Tr**2 + A3*Tr**3 return C C1 = C(To/Tc, Po/Pc) C2 = C(T/Tc, P/Pc) # Eq 1 d2 = rhos*C2/C1 return unidades.Density(d2)
[docs] @refDoc(__doi__, [11, 12]) def _Pv(T, Tcm, Pcm, wm): """Pseudo vapor presure from pseudocritical properties to use in compressed liquid density correlations Parameters ---------- T : float Temperature, [K] Tcm : float Pseudo critical temperature of mixture, [K] Pcm : float Pseudo critical pressure of mixture, [Pa] wm : float Acentric factor of mixture, [-] Returns ------- Pbp : float Boiling point pressure, [Pa] """ Trm = T/Tcm alpha = 35 - 36/Trm - 96.736*log10(Trm) + Trm**6 # Eq 22 beta = log10(Trm) + 0.03721754*alpha # Eq 23 Pro = 5.8031817*log10(Trm)+0.07608141*alpha # Eq 20 # Using Aalto modificated equation Eq 8 Pr1 = 4.86601*beta+0.03721754*alpha # Eq 21 Pbp = Pcm*10**(Pro+wm*Pr1) return unidades.Pressure(Pbp)
# Liquid viscosity correlations
[docs] @refDoc(__doi__, [20, 2, 3]) def MuL_KendallMonroe(xi, mui): r"""Calculate viscosity of liquid mixtures using the Kendall-Monroe method, also referenced in API procedure 11A3.1, pag 1051 .. math:: \mu_m = \left(\sum_{i=1}^nx_i\mu_i^{1/3}\right)^3 Parameters ---------- xi : list Mole fractions of components, [-] mui : list Viscosities of components, [Pa·s] Returns ------- mu : float Viscosity of mixture, [Pa·s] Examples -------- Example A from [2]_; 29.57% nC16, 35.86% benzene, 34.57% nC6 at 77ºF >>> x = [0.2957, 0.3586, 0.3457] >>> mu = [3.03e-3, 0.6e-3, 0.3e-3] >>> "%0.2f" % MuL_KendallMonroe(x, mu).cP '0.89' Example B from [2]_; 25% nC3, 50% nC5, 25% cycloC6 at 160ºF >>> x = [0.25, 0.5, 0.25] >>> mu = [0.109e-3, 0.218e-3, 0.63e-3] >>> "%0.3f" % MuL_KendallMonroe(x, mu).cP '0.256' """ mum = 0 for x, mu in zip(xi, mui): mum += x*mu**(1/3) return unidades.Viscosity(mum**3)
[docs] def MuL_Chemcad(xi, Mi, mui): r"""Calculate viscosity of liquid mixtures using the mixing rules of Arrhenius and with modification used in CHEMCAD® .. math:: \mu_m = e^A .. math:: A = \sum_i \frac{x_iM_i}{M_m}\log\mu_i if M > 2000 .. math:: A = \sum_i x_i\log\mu_i if M < 2000 Parameters ---------- xi : list Mole fractions of components, [-] Mi : list Molecular weight of components, [g/mol] mui : list Viscosities of components, [Pa·s] Returns ------- mu : float Viscosity of mixture, [Pa·s] Notes ----- I can't find any reference for this mixing rule. In some place is refered as the Arrhenius mixing rules, but only for the los molecular weight form. """ Mm = sum([M*x for M, x in zip(Mi, xi)]) if max(Mi) > 2000: A = 0 for x, M, mu in zip(xi, Mi, mui): A += x*M/Mm*log(mu) else: A = 0 for x, mu in zip(xi, mui): A += x*log(mu) return unidades.Viscosity(exp(A))
# Gas viscosity correlations
[docs] @refDoc(__doi__, [3]) def MuG_Reichenberg(T, xi, Tci, Pci, Mi, mui, Di): r"""Calculate viscosity of gas mixtures using the Reichenberg method as explain in [3]_ .. math:: \eta_m = \sum _{i=1}^n K_i\left(1+2\sum_{j=1}^{i-1}H_{ij}K_j + \sum_{j=1≠i}^n \sum_{k=1≠i}^nH_{ij}H_{ik}K_jK_k\right) .. math:: K_i = \frac{x_i\eta_i}{x_i+\eta_i \sum_{k=1≠i}^n x_kH_{ik} \left[3+\left(2M_k/M_i\right)\right]} .. math:: H_{ij} = \left[\frac{M_iM_j}{32\left(M_i+M_j\right)^3}\right]^{1/2} \left(C_i+C_j\right)^2 \frac{\left[1+0.36T_{rij}\left(T_{rij}-1 \right)\right]^{1/6}F_{Rij}}{T_{rij}^{1/2}} .. math:: F_{Ri} = \frac{T_{ri}^{3.5}+\left(10\mu_{ri}\right)^7} {T_{ri}^{3.5}\left[1+\left(10\mu_{ri}\right)^7\right]} .. math:: C_i = \frac{M_i^{1/4}}{\left(\eta_iU_i\right)^{1/2}} .. math:: U_i = \frac{\left[1+0.36T_{ri}\left(T_{ri}-1\right)\right]^{1/6}F_{Ri}} {T_{ri}^{1/2}} .. math:: T_{rij} = \frac{T}{\left(T_{ci}T_{cj}\right)^{1/2}} .. math:: \mu_{rij} = \left(\mu_{ri}\mu_{rj}\right)^{1/2} .. math:: \mu_r = 52.46\frac{\mu^2P_c}{T_c^2} Parameters ---------- T : float Temperature, [K] xi : list Mole fractions of components, [-] Tci : list Critical temperature of components, [K] Pci : list Critical pressure of components, [Pa] Mi : list Molecular weights of components, [g/mol] mui : list Viscosities of components, [Pa·s] Di : list Dipole moment of components, [Debye] Returns ------- mu : float Viscosity of mixture, [Pa·s] Examples -------- Example 9-4 from [3]_; 28.6% N2, 71.4% R22 at 50ºC >>> T = unidades.Temperature(50, "C") >>> x = [0.286, 0.714] >>> Tc = [126.2, 369.28] >>> Pc = [33.98e5, 49.86e5] >>> M = [28.014, 86.468] >>> mu = [188e-7, 134e-7] >>> D = [0, 1.4] >>> "%0.1f" % MuG_Reichenberg(T, x, Tc, Pc, M, mu, D).microP '146.2' """ # Calculate reduced temperatures Tri = [T/Tc for Tc in Tci] Trij = [] for Tc_i in Tci: Triji = [] for Tc_j in Tci: Triji.append(T/(Tc_i*Tc_j)**0.5) Trij.append(Triji) # Calculate reduced viscosity muri = [52.46*D**2*Pc*1e-5/Tc**2 for D, Pc, Tc in zip(Di, Pci, Tci)] murij = [] for mur_i in muri: muriji = [] for mur_j in muri: muriji.append((mur_i*mur_j)**0.5) murij.append(muriji) # Polar correction, Eq 9-5.5 Fri = [] for Tr, mur in zip(Tri, muri): Fri.append((Tr**3.5+(10*mur)**7)/Tr**3.5/(1+(10*mur)**7)) Frij = [] for Triji, muriji in zip(Trij, murij): Friji = [] for Tr, mur in zip(Triji, muriji): Friji.append((Tr**3.5+(10*mur)**7)/Tr**3.5/(1+(10*mur)**7)) Frij.append(Friji) # Eq 9-5.3 Ui = [] for Tr, Fr in zip(Tri, Fri): Ui.append((1+0.36*Tr*(Tr-1))**(1/6)*Fr/Tr**0.5) # Eq 9-5.4 Ci = [M**0.25/(mu*U)**0.5 for M, mu, U in zip(Mi, mui, Ui)] # Eq 9-5.6 Hij = [] for M_i, C_i, Triji, Friji in zip(Mi, Ci, Trij, Frij): Hiji = [] for M_j, C_j, Tr, Fr in zip(Mi, Ci, Triji, Friji): Hiji.append((M_i*M_j/32/(M_i+M_j)**3)**0.5*(C_i+C_j)**2*( 1+0.36*Tr*(Tr-1))**(1/6)*Fr/Tr**0.5) Hij.append(Hiji) # Eq 9-5.2 sumai = [] for i, M_i in enumerate(Mi): sumaij = 0 for j, M_j in enumerate(Mi): if i != j: sumaij += xi[j]*Hij[i][j]*(3+2*M_j/M_i) sumai.append(sumaij) Ki = [x*mu/(x+mu*suma) for x, mu, suma in zip(xi, mui, sumai)] # Eq 9-5.1 mu = 0 for i, K_i in enumerate(Ki): sum1 = 0 for H, K_j in zip(Hij[i], Ki[:i]): sum1 += H*K_j sum2 = 0 for j, K_j in enumerate(Ki): for k, K_k in enumerate(Ki): if j != i and k != i: sum2 += Hij[i][j]*Hij[i][k]*K_j*K_k mu += K_i*(1+2*sum1+sum2) return unidades.Viscosity(mu)
[docs] @refDoc(__doi__, [1, 2, 3]) def MuG_Wilke(xi, Mi, mui): r"""Calculate viscosity of gas mixtures using the Wilke mixing rules, also referenced in API procedure 11B2.1, pag 1102 .. math:: \mu_{m} = \sum_{i=1}^n \frac{\mu_i}{1+\frac{1}{x_i}\sum_{j=1} ^n x_j \phi_{ij}} .. math:: \phi_{ij} = \frac{\left[1+\left(\mu_i/\mu_j\right)^{0.5}(M_j/M_i) ^{0.25}\right]^2}{4/\sqrt{2}\left[1+\left(M_i/M_j\right)\right] ^{0.5}} Parameters ---------- xi : list Mole fractions of components, [-] Mi : list Molecular weights of components, [g/mol] mui : list Viscosities of components, [Pa·s] Returns ------- mu : float Viscosity of mixture, [Pa·s] Examples -------- Selected point in Table II from [1]_ CO2 3.5%, O2 0.3%, CO 27.3%, H2 14.4%, CH4 3.7%, N2 50%, C2 0.8% >>> from numpy import r_ >>> from lib.mEoS import CO2, O2, CO, H2, CH4, N2, C2 >>> Mi = [CO2.M, O2.M, CO.M, H2.M, CH4.M, N2.M, C2.M] >>> xi = [0.035, 0.003, 0.273, 0.144, 0.037, 0.5, 0.008] >>> mui = r_[147.2, 201.9, 174.9, 87.55, 108.7, 178.1, 90.9] >>> "%0.7f" % MuG_Wilke(xi, Mi, mui*1e-9).dynscm2 '0.0001711' Example A from [2]_; 58.18% H2, 41.82% propane at 77ºF and 14.7 psi >>> mu = MuG_Wilke([0.5818, 0.4182], [2.02, 44.1], [8.91e-6, 8.22e-6]) >>> "%0.4f" % mu.cP '0.0092' Example B from [2]_ 95.6% CH4, 3.6% C2, 0.5% C3, 0.3% N2 >>> x = [0.956, 0.036, 0.005, 0.003] >>> Mi = [16.04, 30.07, 44.1, 28.01] >>> mui = [1.125e-5, 9.5e-6, 8.4e-6, 1.79e-5] >>> "%0.5f" % MuG_Wilke(x, Mi, mui).cP '0.01117' Example 9-5 from [3]_, methane 69.7%, n-butane 30.3% >>> mui = [109.4e-7, 72.74e-7] >>> "%0.2f" % MuG_Wilke([0.697, 0.303], [16.043, 58.123], mui).microP '92.25' """ # Eq 4 kij = [] for i, mi in enumerate(Mi): kiji = [] for j, mj in enumerate(Mi): if i == j: kiji.append(0) else: kiji.append((1+(mui[i]/mui[j])**0.5*(mj/mi)**0.25)**2 / 8**0.5/(1+mi/mj)**0.5) kij.append(kiji) # Eq 13 # Precalculate of internal sum suma = [] for i, Xi in enumerate(xi): sumai = 0 if Xi != 0: for j, Xj in enumerate(xi): sumai += kij[i][j]*Xj/Xi suma.append(sumai) mu = 0 for mu_i, sumai in zip(mui, suma): mu += mu_i/(1+sumai) return unidades.Viscosity(mu)
[docs] @refDoc(__doi__, [3]) def MuG_Herning(xi, Mi, mui): r"""Calculate viscosity of gas mixtures using the Herning-Zipperer mixing rules, as explain in [3]_ .. math:: \mu_{m} = \sum_{i=1}^n \frac{\mu_i}{1+\frac{1}{x_i}\sum_{j=1} ^n x_j \phi_{ij}} .. math:: \phi_{ij} = \left(\frac{M_j}{M_i}\right)^{1/2} Parameters ---------- xi : list Mole fractions of components, [-] Mi : list Molecular weights of components, [g/mol] mui : list Viscosities of components, [Pa·s] Returns ------- mu : float Viscosity of mixture, [Pa·s] Examples -------- Example 9-6 from [3]_, methane 69.7%, n-butane 30.3% >>> mui = [109.4e-7, 72.74e-7] >>> "%0.1f" % MuG_Herning([0.697, 0.303], [16.043, 58.123], mui).microP '92.8' """ kij = [] for i, mi in enumerate(Mi): kiji = [] for j, mj in enumerate(Mi): if i == j: kiji.append(0) else: kiji.append((mj/mi)**0.5) kij.append(kiji) suma = [] for i, Xi in enumerate(xi): sumai = 0 if Xi != 0: for j, Xj in enumerate(xi): sumai += kij[i][j]*Xj/Xi suma.append(sumai) mu = 0 for mu_i, sumai in zip(mui, suma): mu += mu_i/(1+sumai) return unidades.Viscosity(mu)
[docs] @refDoc(__doi__, [3]) def MuG_Lucas(T, P, xi, Tci, Pci, Vci, Zci, Mi, Di): r"""Calculate the viscosity of a gas mixture using the Lucas mixing rules as explain in [3]_. .. math:: T_{cm} = \sum_i x_iT_{ci} .. math:: P_{cm} = RT_{cm}\frac{\sum_i x_iZ_{ci}}{\sum_i x_iV_{ci}} .. math:: M_m = \sum_i x_iM_i .. math:: F_{Pm}^o = \sum_i x_iF_{Pi}^o .. math:: F_{Qm}^o = \left(\sum_i x_iF_{Qi}^o\right)A .. math:: A = 1-0.01\left(\frac{M_H}{M_L}\right)^{0.87} Parameters ---------- T : float Temperature, [K] P : float Pressure, [Pa] xi : list Mole fractions of components, [-] Tci : list Critical temperature of components, [K] Pci : list Critical pressure of components, [Pa] Vci : list Critical volume of components, [m³/kg] Zci : list Critical compressibility factor of components, [-] Mi : list Molecular weights of components, [g/mol] Di : list Dipole moment of components, [Debye] Returns ------- mu : float Viscosity of gas, [Pa·s] Examples -------- Example 9-7 in [3]_, 67.7% NH3 33.3% H2 at 33ºC >>> Tc = [405.5, 33.2] >>> Pc = [113.5e5, 13e5] >>> Vc =[72.5/17.031/1000, 64.3/2.016/1000] >>> Zc = [0.244, 0.306] >>> M = [17.031, 2.0158] >>> D = [1.47, 0] >>> mu = MuG_Lucas(33+273.15, 101325, [0.677, 0.323], Tc, Pc, Vc, Zc, M, D) >>> "%0.1f" % mu.microP '116.3' """ # Use critical volume in molar base Vci = [Vc*M*1000 for Vc, M in zip(Vci, Mi)] # Calculate critical properties of mixture Tcm = sum([x*Tc for x, Tc in zip(xi, Tci)]) Zcm = sum([x*Zc for x, Zc in zip(xi, Zci)]) Vcm = sum([x*Vc for x, Vc in zip(xi, Vci)]) Mm = sum([x*M for x, M in zip(xi, Mi)]) Pcm = R*Tcm*Zcm/Vcm*1e6 Trm = T/Tcm Prm = P/Pcm Pcm_bar = Pcm*1e-5 X = 0.176*Tcm**(1/6)/Mm**0.5/Pcm_bar**(2/3) # Polarity and quantum effects correction factors Fpoi = [] Fqoi = [] for Tc, Pc, Zc, M, D in zip(Tci, Pci, Zci, Mi, Di): Tr = T/Tc Pc_bar = Pc*1e-5 mur = 52.46*D**2*Pc_bar/Tc**2 if mur < 0.022: Fpoi.append(1) elif mur < 0.075: Fpoi.append(1 + 30.55*(0.292-Zc)**1.72) else: Fpoi.append(1 + 30.55*(0.292-Zc)**1.72*abs(0.96+0.1*(Tr-0.7))) if Tr < 12: sign = -1 else: sign = 1 if M == 2.0158: Q = 0.76 # Hydrogen Fqoi.append(1.22*Q**0.15*(1+0.00385*((Tr-12)**2)**(1/M)*sign)) elif M == 4.0026: Q = 1.38 # Helium Fqoi.append(1.22*Q**0.15*(1+0.00385*((Tr-12)**2)**(1/M)*sign)) else: Fqoi.append(1) Fpom = sum([x*Fpo for x, Fpo in zip(xi, Fpoi)]) Fqom = sum([x*Fqo for x, Fqo in zip(xi, Fqoi)]) # Calculate A factor Mh = max(Mi) Ml = min(Mi) xh = xi[Mi.index(Mh)] if Mh/Ml > 9 and 0.05 < xh < 0.7: A = 1 - 0.01*(Mh/Ml)**0.87 else: A = 1 Fqom *= A Z1 = Fpom*Fqom*(0.807*Trm**0.618 - 0.357*exp(-0.449*Trm) + 0.34*exp(-4.058*Trm) + 0.018) if Prm < 0.6: # Low pressure correlation mu = Z1/X else: # High pressure correlation if Trm <= 1: alfa = 3.262 + 14.98*Prm**5.508 beta = 1.39 + 14.98*Prm Z2 = 0.6 + 0.76*Prm**alfa + (6.99*Prm**beta-0.6)*(1-Trm) else: a = 1.245e-3/Trm*exp(5.1726*Trm**-0.3286) b = a*(1.6553*Trm-1.2723) c = 0.4489/Trm*exp(3.0578*Trm**-37.7332) d = 1.7368/Trm*exp(2.231*Trm**-7.6351) e = 1.3088 f = 0.9425*exp(-0.1853*Trm**0.4489) Z2 = Z1*(1+a*Prm**e/(b*Prm**f+1/(1+c*Prm**d))) Y = Z2/Z1 Fp = (1+(Fpom-1)/Y**3)/Fpom Fq = (1+(Fqom-1)*(1/Y-0.007*log(Y)**4))/Fqom mu = Z2*Fp*Fq/X return unidades.Viscosity(mu, "microP")
[docs] @refDoc(__doi__, [15, 3]) def MuG_Chung(T, xi, Tci, Vci, Mi, wi, Di, ki): r"""Calculate the viscosity of a gas mixture using the Chung correlation .. math:: \mu=40.785\frac{F_{cm}\left(M_mT\right)^{1/2}}{V_{cm}^{2/3}\Omega_v} .. math:: \sigma_i = 0.809V_{ci}^{1/3} .. math:: \sigma_{ij} = \xi\left(\sigma_i\sigma_j\right)^{1/2} .. math:: \sigma_m^3 = \sum_i \sum_j x_ix_j\sigma_{ij}^3 .. math:: \frac{\epsilon_i}{k} = \frac{T_{ci}}{1.2593} .. math:: \frac{\epsilon_{ij}}{k} = \zeta\left(\frac{\epsilon_i}{k} \frac{\epsilon_j}{k}\right)^{1/2} .. math:: \left(\frac{\epsilon}{k}\right)_m = \frac{\sum_i \sum_j x_ix_j \left(\epsilon_{ij}/k\right)\sigma_{ij}^3}{\sigma_m^3} .. math:: \omega_{ij} = \frac{\omega_i+\omega_j}{2} .. math:: \kappa_{ij} = \left(\kappa_i+\kappa_j\right)^{1/2} .. math:: M_{ij} = \frac{2M_iM_j}{M_i+M_j} .. math:: M_m = \left[\frac{\sum_i\sum_jx_ix_j\left(\epsilon_{ij}/k\right)\sigma_ {ij}^3M_{ij}^{1/2}}{\left(\epsilon/k\right)_m\sigma_m^3}\right]^2 .. math:: \omega_m =\frac{\sum_i\sum_jx_ix_j\omega_{ij}\sigma_{ij}^3}{\sigma_m^3} .. math:: \mu_m^4 = \sigma_m^3\sum_i\sum_j\frac{x_ix_j\mu_i^2\mu_j^2} {\sigma_{ij}^3} .. math:: \kappa_m = \sum_i \sum_j x_ix_j\kappa_{ij} .. math:: F_{cm} = 1-0.2756\omega_m+0.059035\mu_{rm}^4+\kappa_m .. math:: mu_{rm} = \frac{131.3\mu}{\left(V_{cm}T_{cm}\right)^{1/2}} .. math:: T_{cm} = 1.2593\left(\frac{\epsilon}{k}\right)_m .. math:: V_{cm} = \left(\frac{\sigma_m}{0.809}\right)^3 Parameters ---------- T : float Temperature, [K] xi : list Mole fractions of components, [-] Tci : list Critical temperature of components, [K] Vci : list Critical volume of components, [m³/kg] Mi : list Molecular weights of components, [g/mol] wi : list Acentric factor of components, [-] Di : list Dipole moment of components, [Debye] ki : list Correction factor for polar substances, [-] Returns ------- mu : float Viscosity of gas, [Pa·s] Notes ----- The method use binary interaction parameters for disimilar molecules, polar of hidrogen-bonding substances. That parameters must be calculated from experimental data. In this implementation this paramter set equal to unity Examples -------- Example 9-8 in [3]_, 20.4% H2S 79.6% ethyl ether at 331K >>> x = [0.204, 0.796] >>> Tc = [373.4, 466.7] >>> Vc = [98/34.082/1000, 280/74.123/1000] >>> M = [34.082, 74.123] >>> w = [0.09, 0.281] >>> mu = [0.9, 1.3] >>> k = [0, 0] >>> "%0.1f" % MuG_Chung(331, x, Tc, Vc, M, w, mu, k).microP '87.6' """ # Use critical volume in molar base Vci = [Vc*M*1000 for Vc, M in zip(Vci, Mi)] sigmai = [0.809*Vc**(1/3) for Vc in Vci] # Eq 4 eki = [Tc/1.2593 for Tc in Tci] # Eq 5 # Eq 23 sigmaij = [] for s_i in sigmai: sigmaiji = [] for s_j in sigmai: sigmaiji.append((s_i*s_j)**0.5) sigmaij.append(sigmaiji) # Eq 24 ekij = [] for ek_i in eki: ekiji = [] for ek_j in eki: ekiji.append((ek_i*ek_j)**0.5) ekij.append(ekiji) # Eq 25 wij = [] for w_i in wi: wiji = [] for w_j in wi: wiji.append((w_i+w_j)/2) wij.append(wiji) # Eq 26 Mij = [] for M_i in Mi: Miji = [] for M_j in Mi: Miji.append(2*M_i*M_j/(M_i+M_j)) Mij.append(Miji) # Eq 27 kij = [] for k_i in ki: kiji = [] for k_j in ki: kiji.append((k_i*k_j)**0.5) kij.append(kiji) # Eq 14 sm = 0 for x_i, sigmaiji in zip(xi, sigmaij): for x_j, sij in zip(xi, sigmaiji): sm += x_i*x_j*sij**3 sm = sm**(1/3) # Eq 15 ekm = 0 for x_i, sigmaiji, ekiji in zip(xi, sigmaij, ekij): for x_j, sij, ek in zip(xi, sigmaiji, ekiji): ekm += x_i*x_j*ek*sij**3 ekm /= sm**3 # Eq 18 wm = 0 for x_i, sigmaiji, wiji in zip(xi, sigmaij, wij): for x_j, sij, w in zip(xi, sigmaiji, wiji): wm += x_i*x_j*w*sij**3 wm /= sm**3 # Eq 19 Mm = 0 for x_i, sigmaiji, ekiji, Miji in zip(xi, sigmaij, ekij, Mij): for x_j, s, ek, M in zip(xi, sigmaiji, ekiji, Miji): Mm += x_i*x_j*ek*s**2*M**0.5 Mm = (Mm/(ekm*sm**2))**2 # Eq 20 Dm = 0 for x_i, sigmaiji, ekiji, D_i in zip(xi, sigmaij, ekij, Di): for x_j, s, ek, D_j in zip(xi, sigmaiji, ekiji, Di): Dm += x_i*x_j*(D_i*D_j)**2/ek/s**3 Dm = (Dm*ekm*sm**3)**0.25 # Eq 21 km = 0 for x_i, kiji in zip(xi, kij): for x_j, k in zip(xi, kiji): km += x_i*x_j*k Vcm = (sm/0.809)**3 # Eq 16 Tcm = 1.2593*ekm # Eq 17 murm = 131.3*Dm/(Vcm*Tcm)**0.5 # Eq 22 T_ = T/ekm omega = Collision_Neufeld(T_) Fcm = 1 - 0.2756*wm + 0.059035*murm**4 + km # Eq 7 mu = 40.785*Fcm*Mm**0.5*T**0.5/Vcm**(2/3)/omega # Eq 6 return unidades.Viscosity(mu, "microP")
[docs] @refDoc(__doi__, [15, 1]) def MuG_P_Chung(T, xi, Tci, Vci, Mi, wi, Di, ki, rho, muo): r"""Calculate the viscosity of a compressed gas using the Chung correlation .. math:: \mu=40.785\frac{F_c\left(MT\right)^{1/2}}{V_c^{2/3}\Omega_v} Parameters ---------- T : float Temperature, [K] xi : list Mole fractions of components, [-] Tci : list Critical temperature of components, [K] Vci : list Critical volume of components, [m³/kg] Mi : list Molecular weights of components, [g/mol] wi : list Acentric factor of components, [-] Di : list Dipole moment of components, [Debye] ki : list Correction factor for polar substances, [-] rho : float Density, [kg/m³] muo : float Viscosity of low-pressure gas, [Pa·s] Returns ------- mu : float Viscosity of gas mixture, [Pa·s] """ # Use critical volume in molar base Vci = [Vc*M*1000 for Vc, M in zip(Vci, Mi)] sigmai = [0.809*Vc**(1/3) for Vc in Vci] # Eq 4 eki = [Tc/1.2593 for Tc in Tci] # Eq 5 # Eq 23 sigmaij = [] for s_i in sigmai: sigmaiji = [] for s_j in sigmai: sigmaiji.append((s_i*s_j)**0.5) sigmaij.append(sigmaiji) # Eq 24 ekij = [] for ek_i in eki: ekiji = [] for ek_j in eki: ekiji.append((ek_i*ek_j)**0.5) ekij.append(ekiji) # Eq 25 wij = [] for w_i in wi: wiji = [] for w_j in wi: wiji.append((w_i+w_j)/2) wij.append(wiji) # Eq 26 Mij = [] for M_i in Mi: Miji = [] for M_j in Mi: Miji.append(2*M_i*M_j/(M_i+M_j)) Mij.append(Miji) # Eq 27 kij = [] for k_i in ki: kiji = [] for k_j in ki: kiji.append((k_i*k_j)**0.5) kij.append(kiji) # Eq 14 sm = 0 for x_i, sigmaiji in zip(xi, sigmaij): for x_j, sij in zip(xi, sigmaiji): sm += x_i*x_j*sij**3 sm = sm**(1/3) # Eq 15 ekm = 0 for x_i, sigmaiji, ekiji in zip(xi, sigmaij, ekij): for x_j, sij, ek in zip(xi, sigmaiji, ekiji): ekm += x_i*x_j*ek*sij**3 ekm /= sm**3 # Eq 18 wm = 0 for x_i, sigmaiji, wiji in zip(xi, sigmaij, wij): for x_j, sij, w in zip(xi, sigmaiji, wiji): wm += x_i*x_j*w*sij**3 wm /= sm**3 # Eq 19 Mm = 0 for x_i, sigmaiji, ekiji, Miji in zip(xi, sigmaij, ekij, Mij): for x_j, s, ek, M in zip(xi, sigmaiji, ekiji, Miji): Mm += x_i*x_j*ek*s**2*M**0.5 Mm = (Mm/(ekm*sm**2))**2 # Eq 20 Dm = 0 for x_i, sigmaiji, ekiji, D_i in zip(xi, sigmaij, ekij, Di): for x_j, s, ek, D_j in zip(xi, sigmaiji, ekiji, Di): Dm += x_i*x_j*(D_i*D_j)**2/ek/s**3 Dm = (Dm*ekm*sm**3)**0.25 # Eq 21 km = 0 for x_i, kiji in zip(xi, kij): for x_j, k in zip(xi, kiji): km += x_i*x_j*k rho = rho/Mm/1000 Vcm = (sm/0.809)**3 # Eq 16 Tcm = 1.2593*ekm # Eq 17 murm = 131.3*Dm/(Vcm*Tcm)**0.5 # Eq 22 T_ = T/ekm # Table II dat = [ (6.32402, 50.4119, -51.6801, 1189.02), (0.12102e-2, -0.11536e-2, -0.62571e-2, 0.37283e-1), (5.28346, 254.209, -168.481, 3898.27), (6.62263, 38.09570, -8.46414, 31.4178), (19.74540, 7.63034, -14.35440, 31.5267), (-1.89992, -12.53670, 4.98529, -18.1507), (24.27450, 3.44945, -11.29130, 69.3466), (0.79716, 1.11764, 0.12348e-1, -4.11661), (-0.23816, 0.67695e-1, -0.81630, 4.02528), (0.68629e-1, 0.34793, 0.59256, -0.72663)] # Eq 11 A = [] for ao, a1, a2, a3 in dat: A.append(ao + a1*wm + a2*murm**4 + a3*km) A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 = A Y = rho*Vcm/6 G1 = (1-0.5*Y)/(1-Y)**3 G2 = (A1*((1-exp(-A4*Y))/Y)+A2*G1*exp(A5*Y)+A3*G1)/(A1*A4+A2+A3) muk = muo*(1/G2 + A6*Y) mup = (36.344e-6*(Mm*Tcm)**0.5/Vcm**(2/3))*A7*Y**2*G2*exp( A8+A9/T_+A10/T_**2) return unidades.Viscosity(muk+mup, "P")
[docs] @refDoc(__doi__, [1, 21, 16, 17]) def MuG_TRAPP(T, P, xi, Tci, Vci, Zci, Mi, wi, rho, muo): r"""Calculate the viscosity of a compressed gas using the TRAPP (TRAnsport Property Prediction) method. .. math:: \eta_m - \eta_m^o = F_{\eta m}\left(\eta^R-\eta^{Ro}\right) + \Delta\eta^{ENSKOG} .. math:: h_m = \sum_i\sum_jx_ix_jh_{ij} .. math:: f_mh_m = \sum_i\sum_jx_ix_jf_{ij}h_{ij} .. math:: h_{ij} = \frac{\left(h_i^{1/3}+h_j^{1/3}\right)^3}{8} .. math:: f_{ij} = \left(f_if_j\right)^{1/2} .. math:: T_o = T/f_m .. math:: \rho_o = \rho h_m .. math:: F_{\eta m} = \frac{1}{44.094^{1/2}h_m^2} \sum_i\sum_j x_ix_j \left(f_{ij}M_{ij}\right)^{1/2}h_{ij}^{4/3} .. math:: M_{ij} = \frac{2M_iM_j}{M_i+M_j} .. math:: \Delta\eta^{ENSKOG} = \eta_m^{ENSKOG} - \eta_x^{ENSKOG} .. math:: \eta_m^{ENSKOG} = \sum_i \beta_iY_i + \sum_i\sum_jx_ix_j\sigma_{ij}^6 \eta_{ij}^og_{ij} .. math:: \sigma_i = 4.771h_i^{1/3} .. math:: \sigma_{ij} = \frac{\sigma_i+\sigma_j}{2} .. math:: g_{ij} = \frac{1}{1-\xi}+\frac{3\xi}{\left(1-\xi\right)^2}\Theta_{ij}+ \frac{2\xi^2}{\left(1-\xi\right)^3}\Theta_{ij}^2 .. math:: \Theta_{ij} = \frac{\sigma_i\sigma_j}{2\sigma_{ij}} \frac{\sum_kx_k\sigma_k^2}{\sum_k x_k\sigma_k^3} .. math:: \xi = 6.023e-4\frac{\pi}{6}\rho\sum_i x_i\sigma_i^3 .. math:: Y_i = x_i\left[1+\frac{8\pi}{15}6.023e-4\rho\sum_jx_j\left(\frac{M_j} {M_i+M_j}\right)\sigma_{ij}^3g_{ij}\right] .. math:: \sum_i B_{ij}\beta_j = Y_i .. math:: B_{ij} = 2\sum_kx_ix_k\frac{g_{ik}}{\eta_{ij}^o}\left(\frac{M_k} {M_i+M_k}\right)^2\left[\left(1+\frac{5}{3}\frac{M_i}{M_k}\right) \delta_{ij}-\frac{2}{3}\frac{M_i}{M_k}\delta_{jk}\right] .. math:: \sigma_x = \left(\sum_i\sum_jx_ix_j\sigma_{ij}^3\right)^{1/3} .. math:: M_x = \frac{\left(\sum_i\sum_jx_ix_jM_{ij}^{1/2}\sigma_{ij}^4\right)^2} {\sigma_x^8} Parameters ---------- T : float Temperature, [K] xi : list Mole fractions of components, [-] Tci : list Critical temperature of components, [K] Vci : list Critical volume of components, [m³/kg] Zci : list Critical compressibility factor of components, [K] Mi : list Molecular weights of components, [g/mol] wi : list Acentric factor of components, [-] rho : float Density, [kg/m³] muo : float Viscosity of low-pressure gas, [Pa·s] Returns ------- mu : float Viscosity of gas, [Pa·s] Examples -------- Example 9-14 in [3]_, 80% methane, 20% nC10 at 377.6K and 413.7bar >>> x = [0.8, 0.2] >>> M = [16.043, 142.285] >>> Tc = [190.56, 617.7] >>> Vc = [98.6/16.043/1000, 624/142.285/1000] >>> Zc = [0.286, 0.256] >>> w = [0.011, 0.49] >>> rho = 1/243.8*58.123*1000 >>> mu = MuG_TRAPP(377.6, 413.7e5, x, Tc, Vc, Zc, M, w, 448.4, 10.2e-6) >>> "%0.1f" % mu.muPas '82.6' """ # Reference fluid properties, propane TcR = 369.83 rhocR = 1/200 # mol/cm³ ZcR = 0.276 wR = 0.152 # Convert volume to molar base Vci = [Vc*M*1000 for Vc, M in zip(Vci, Mi)] Mm = sum([x*M for x, M in zip(xi, Mi)]) rho = rho/Mm # Calculate shape factor for mixture fi = [] hi = [] for Tc, Vc, Zc, w in zip(Tci, Vci, Zci, wi): fi.append(Tc/TcR*(1+(w-wR)*(0.05203-0.7498*log(T/Tc)))) hi.append(rhocR*Vc*ZcR/Zc*(1-(w-wR)*(0.1436-0.2822*log(T/Tc)))) # Eq 9-7.5 fij = [] for f_i in fi: fiji = [] for f_j in fi: fiji.append((f_i*f_j)**0.5) fij.append(fiji) # Eq 9-7.4 hij = [] for h_i in hi: hiji = [] for h_j in hi: hiji.append((h_i**(1/3)+h_j**(1/3))**3/8) hij.append(hiji) # Eq 9-7.2 hm = 0 for x_i, hiji in zip(xi, hij): for x_j, h in zip(xi, hiji): hm += x_i*x_j*h # Eq 9-7.3 fm = 0 for x_i, hiji, fiji in zip(xi, hij, fij): for x_j, h, f in zip(xi, hiji, fiji): fm += x_i*x_j*f*h/hm # Eq 9-7.9 Mij = [] for M_i in Mi: Miji = [] for M_j in Mi: Miji.append(2*M_i*M_j/(M_i+M_j)) Mij.append(Miji) To = T/fm # Eq 9-7.6 rho0 = rho/1000*hm # Eq 9-7.7 # Eq 9-7.8 suma = 0 for x_i, fiji, Miji, hiji in zip(xi, fij, Mij, hij): for x_j, f, M, h in zip(xi, fiji, Miji, hiji): suma += x_i*x_j*(f*M)**0.5*h**(4/3) Fnm = 44.094**-0.5/hm**2*suma # Calculation of reference residual viscosity # Coefficients in [16]_, pag 796 # Density are in mol/dm³ rho0 *= 1000 rhocR *= 1000 G = -14.113294896 + 968.22940153/To H = rho0**0.5*(rho0-rhocR)/rhocR G2 = 13.686545032 - 12511.628378/To**1.5 G3 = 0.0168910864 + 43.527109444/To + 7659.4543472/To**2 F = G + G2*rho0**0.1+G3*H muR = exp(F)-exp(G) # Calculate of Δη sigmai = [4.771*h**(1/3) for h in hi] sigmaij = [] for s_i in sigmai: sigmaiji = [] for s_j in sigmai: sigmaiji.append((s_i+s_j)/2) sigmaij.append(sigmaiji) # Eq 9-7.16 X = 6.023e-4*pi/6*rho*sum([x*s**3 for x, s in zip(xi, sigmai)]) # Eq 9-7.15 sum2 = sum([x*s**2 for x, s in zip(xi, sigmai)]) sum3 = sum([x*s**3 for x, s in zip(xi, sigmai)]) titaij = [] for s_i, siji in zip(sigmai, sigmaij): titaiji = [] for s_j, sij in zip(sigmai, siji): titaiji.append(s_i*s_j/2/sij*sum2/sum3) titaij.append(titaiji) # Eq 9-7.14 gij = [] for titaiji in titaij: giji = [] for tij in titaiji: giji.append(1/(1-X)+3*X/(1-X)**2*tij+2*X**2/(1-X)**3*tij**2) gij.append(giji) # Eq 9-3.8 muij = [] for miji, siji in zip(Mij, sigmaij): muiji = [] for m, s in zip(miji, siji): muiji.append(2.669*(m*T)**0.5/s**2) muij.append(muiji) # Eq 9-7.19 Bij = [] for i, M_i in enumerate(Mi): Biji = [] for j, M_j in enumerate(Mi): B = 0 for k, M_k in enumerate(Mi): if i == j: dij = 1 else: dij = 0 if j == k: djk = 1 else: djk = 0 B += xi[i]*xi[k]*gij[i][k]/muij[i][k]*(M_k/(M_i+M_k))**2*( (1+5/3*M_i/M_k)*dij - 2/3*M_i/M_k*djk) B *= 2e-1 Biji.append(B) Bij.append(Biji) # Eq 9-7.17 Yi = [] for x_i, M_i, siji, giji in zip(xi, Mi, sigmaij, gij): suma = 0 for x_j, M_j, s, g in zip(xi, Mi, siji, giji): suma += x_j*M_j/(M_i+M_j)*s**3*g Yi.append(x_i*(1+8*pi/15*6.023e-4*rho*suma)) # Eq 9-7.18 betai = solve(Bij, Yi) # Eq 9-7.11 sum1 = sum([b*Y for b, Y in zip(betai, Yi)]) sum2 = 0 for x_i, siji, muiji, giji in zip(xi, sigmaij, muij, gij): for x_j, s, mu, g in zip(xi, siji, muiji, giji): sum2 += x_i*x_j*s**6*mu*g alfa = 48/25/pi*(2*pi/3*6.023e-4)**2 eta_m = sum1 + alfa*10*rho**2*sum2 # ηx for pure hypothethical fluid # Eq 9-7.20 sigmax = 0 for x_i, siji in zip(xi, sigmaij): for x_j, s in zip(xi, siji): sigmax += x_i*x_j*s**3 sigmax = sigmax**(1/3) # Eq 9-7.21 Mx = 0 for x_i, siji, Miji in zip(xi, sigmaij, Mij): for x_j, s, M in zip(xi, siji, Miji): Mx += x_i*x_j*M**0.5*s**4 Mx = Mx**2/sigmax**8 X = 6.023e-4*pi/6*rho*sigmax**3 gxx = 1/(1-X)+3*X/(1-X)**2*0.5+2*X**2/(1-X)**3*0.25 Yx = 1+8*pi/15*6.023e-4*rho*sigmax**3*gxx/2 mux = 26.69*(Mx*T)**0.5/sigmax**2 Bxx = gxx/mux betax = Yx/Bxx eta_x = betax*Yx+alfa*rho**2*sigmax**6*mux*gxx # Eq 9-7.10 # The 0.1 factor because this values are im μP, to convert to μPa·s Dmu = (eta_m-eta_x)*0.1 return unidades.Viscosity(Fnm*muR + Dmu + muo*1e6, "muPas")
[docs] @refDoc(__doi__, [19, 2]) def MuG_DeanStielMix(xi, Tci, Pci, Mi, rhoc, rho, muo): r"""Calculate the viscosity of a compressed gas using the Dean-Stiel correlation, also referenced in API databook Procedure 11B4.1, pag 1107 .. math:: \left(\mu-\mu_o\right)\xi=10.8x10^{-5}\left[exp\left(1.439\rho_r\right) -exp\left(-1.11\rho_r^{1.858}\right)\right] .. math:: \xi = \frac{T_{pc}^{1/6}}{M_m^{1/2}P_{pc}^{2/3} .. math:: T_{pc} = \sum_i x_iT_{ci} .. math:: P_{pc} = \sum_i x_iP_{ci} .. math:: M_m = \sum_i x_iM_i Parameters ---------- xi : list Mole fractions of components, [-] Tci : float Critical temperature of components, [K] Pci : float Critical pressure of components, [Pa] Mi : list Molecular weight of components, [g/mol] rhoc : float Critical Density of mixture, [kg/m³] rho : float Density, [kg/m³] muo : float Viscosity of low-pressure gas, [Pa·s] Returns ------- mu : float Viscosity of gas, [Pa·s] Examples -------- Example in [2]_, 60% Methane 40% propane at 1500psi and 257ºF >>> Tc1 = unidades.Temperature(-116.66, "F") >>> Tc2 = unidades.Temperature(206.02, "F") >>> Pc1 = unidades.Pressure(667.04, "psi") >>> Pc2 = unidades.Pressure(616.13, "psi") >>> x = [0.6, 0.4] >>> args = (x, [Tc1, Tc2], [Pc1, Pc2], [16.04, 44.1], 1, 0.5283, 123e-7) >>> "%0.4f" % MuG_DeanStielMix(*args).cP '0.0163' """ # Calculate pseudo critical properties Tpc = sum([x*Tc for x, Tc in zip(xi, Tci)]) # Eq 5 Ppc = sum([x*Pc for x, Pc in zip(xi, Pci)]) # Eq 6 M = sum([x*M_i for x, M_i in zip(xi, Mi)]) return MuG_DeanStiel(Tpc, Ppc, rhoc, M, rho, muo)
[docs] @refDoc(__doi__, [2]) def MuG_APIMix(T, P, xi, Tci, Pci, muo): r"""Calculate the viscosity of nonhydrocarbon gases at high pressure using the linearization of Carr figure as give in API Databook procedure 11C1.2, pag 1113 .. math:: \frac{\mu}{\mu_o}=A_1hP_r^f + A_2\left(kP_r^l+mP_r^n+pP_r^q\right) Parameters ---------- T : float Temperature, [K] P : float Pressure, [Pa] xi : list Mole fractions of components, [-] Tci : float Critical temperature of components, [K] Pci : float Critical pressure of components, [Pa] muo : float Viscosity of low-pressure gas, [Pa·s] Returns ------- mu : float Viscosity of gas, [Pa·s] Notes ----- This method is recomended for gaseous nonhydrocarbons at high pressure, although this method is also applicable for hydrocarbons. Examples -------- Example B in [2]_, 60% Methane 40% propane at 1500psi and 257ºF >>> T = unidades.Temperature(257, "F") >>> P = unidades.Pressure(1500, "psi") >>> Tc1 = unidades.Temperature(-116.66, "F") >>> Tc2 = unidades.Temperature(206.02, "F") >>> Pc1 = unidades.Pressure(667.04, "psi") >>> Pc2 = unidades.Pressure(616.13, "psi") >>> x = [0.6, 0.4] >>> "%0.4f" % MuG_APIMix(T, P, x, [Tc1, Tc2], [Pc1, Pc2], 123e-7).cP '0.0173' """ # Calculate pseudo critical properties Tpc = sum([x*Tc for x, Tc in zip(xi, Tci)]) # Eq 5 Ppc = sum([x*Pc for x, Pc in zip(xi, Pci)]) # Eq 6 return MuG_API(T, P, Tpc, Ppc, muo)
# Liquid thermal conductivity correlations
[docs] @refDoc(__doi__, [4, 2]) def ThL_Li(xi, Vi, Mi, ki): r"""Calculate thermal conductiviy of liquid nmixtures using the Li method, also referenced in API procedure 12A2.1, pag 1145 .. math:: \lambda_{m} = \sum_{i} \sum_{j} \phi_i \phi_j k_{ij} .. math:: k_{ij} = 2\left(\lambda_i^{-1}+\lambda_j^{-1}\right)^{-1} .. math:: \phi_{i} = \frac{x_iV_i}{\sum_j x_jV_j} Parameters ---------- xi : list Mole fractions of components, [-] Vi : list Specific volume of components, [m³/kg] Mi : list Molecular weight of components, [g/mol] ki : list Thermal conductivities of components, [W/m·K] Returns ------- k : float Thermal conductivities of mixture, [W/m·K] Examples -------- Example from [2]_ 68% nC7, 32% CycloC5 at 32F and 1atm >>> V1 = unidades.MolarVolume(2.285, "ft3lbmol") >>> V2 = unidades.MolarVolume(1.473, "ft3lbmol") >>> k1 = unidades.ThermalConductivity(0.07639, "BtuhftF") >>> k2 = unidades.ThermalConductivity(0.08130, "BtuhftF") >>> "%0.5f" % ThL_Li([0.68, 0.32], [V1, V2], [1, 1], [k1, k2]).BtuhftF '0.07751' """ # Use critical volume in molar base Vi = [V*M*1000 for V, M in zip(Vi, Mi)] # Calculation of binary thermal conductivity pair, Eq 2 kij = [] for k_i in ki: kiji = [] for k_j in ki: kiji.append(2/(1/k_i+1/k_j)) kij.append(kiji) # Calculation of volume fraction, Eq 3 suma = 0 for x, V in zip(xi, Vi): suma += x*V phi = [] for x, V in zip(xi, Vi): phi.append(x*V/suma) # Calculation of misture thermal conductivity, Eq 1 k = 0 for phi_i, ki in zip(phi, kij): for phi_j, k_ij in zip(phi, ki): k += phi_i*phi_j*k_ij return unidades.ThermalConductivity(k)
[docs] @refDoc(__doi__, [3]) def ThL_Power(wi, ki): r"""Calculate thermal conductiviy of liquid nmixtures using the power law method, as referenced in [3]_ .. math:: \lambda_{m} = \frac{1}{\sqrt{\sum_{i} w_i/\lambda_i^2}} Parameters ---------- wi : list Weight fractions of components, [-] ki : list Thermal conductivities of components, [W/m·K] Returns ------- k : float Thermal conductivities of mixture, [W/m·K] Notes ----- This method shold not be used if water is in the mixture or if pure component thermal conductivities are very different, ki/kj < 2 """ km = 0 for w, k in zip(wi, ki): km += w/k**2 km = km**-0.5 return unidades.ThermalConductivity(km)
# Gas thermal conductivity correlations
[docs] @refDoc(__doi__, [5, 2]) def ThG_LindsayBromley(T, xi, Mi, Tbi, mui, ki): r"""Calculate thermal conductiviy of gas mixtures using the Lindsay-Bromley method, also referenced in API procedure 12B2.1, pag 1164 .. math:: k = \sum_{i} \frac{k_i}{\frac{1}{x_i}\sum x_i A_{ij}} .. math:: A_{ij} = \frac{1}{4} \left\{ 1 + \left[\frac{\mu_i}{\mu_j} \left(\frac{M_j}{M_i}\right)^{0.75} \left(\frac{1+S_i/T}{1+S_j/T} \right)\right]^{0.5}\right\}^2\left(\frac{1+S_{ij}/T}{1+S_i/T}\right) .. math:: S_{ij} = (S_i S_j)^{0.5} Parameters ---------- T : float Temperature, [K] xi : list Mole fractions of components, [-] Mi : float Molecular weights of components, [g/mol] Tbi : float Boiling points of components, [K] mui : float Gas viscosities of components, [Pa·s] ki : list Thermal conductivities of components, [W/m·K] Returns ------- k : float Thermal conductivities of mixture, [W/m·K] Examples -------- Example from [2]_ 29.96% nC5, 70.04% nC6 at 212F and 1atm >>> T = unidades.Temperature(212, "F") >>> x = [0.2996, 0.7004] >>> M = [72.15, 86.18] >>> Tb1 = unidades.Temperature(96.93, "F") >>> Tb2 = unidades.Temperature(155.71, "F") >>> mu1 = unidades.Viscosity(0.008631, "cP") >>> mu2 = unidades.Viscosity(0.008129, "cP") >>> k1 = unidades.ThermalConductivity(0.01280, "BtuhftF") >>> k2 = unidades.ThermalConductivity(0.01165, "BtuhftF") >>> k = ThG_LindsayBromley(T, x, M, [Tb1, Tb2], [mu1, mu2], [k1, k2]) >>> "%0.5f" % k.BtuhftF '0.01197' """ # Calculation of Sutherland constants, Eq 14 S = [] for Tb, M in zip(Tbi, Mi): if M == 2.0158 or M == 4.0026: # Hydrogen or helium case S.append(79) else: S.append(1.5*Tb) # Geometric mean of collision Sutherland constants, Eq 15 Sij = [] for Si in S: Siji = [] for Sj in S: Siji.append((Si*Sj)**0.5) Sij.append(Siji) # Eq 12 Aij = [] for mu_i, M_i, Si, Siji in zip(mui, Mi, S, Sij): Aiji = [] for mu_j, M_j, Sj, S_ij in zip(mui, Mi, S, Siji): Aiji.append(0.25*(1+(mu_i/mu_j*(M_j/M_i)**0.75*(1+Si/T)/( 1+Sj/T))**0.5)**2 * (1+S_ij/T)/(1+Si/T)) Aij.append(Aiji) # Calculate thermal conductivity, Eq 11 sumaj = [] for Aiji in Aij: suma = 0 for xj, A_ij in zip(xi, Aiji): suma += A_ij*xj sumaj.append(suma) k = 0 for x_i, k_i, si in zip(xi, ki, sumaj): k += k_i*x_i/si return unidades.ThermalConductivity(k)
[docs] @refDoc(__doi__, [6, 3]) def ThG_MasonSaxena(xi, Mi, mui, ki): r"""Calculate thermal conductiviy of gas mixtures using the Mason-Saxena method .. math:: k = \sum_{i} \frac{k_i}{\frac{1}{x_i}\sum x_i A_{ij}} .. math:: A_{ij} = \frac{\epsilon \left[1+\left(\lambda_{tri}/\lambda_{trj} \right)^{1/2} \left(M_i/M_j\right)^{1/4}\right]^2} {\left[8\left(1+M_i/M_j\right)\right]^{1/2}} .. math:: \frac{\lambda_{tri}}{\lambda_{trj}}=\frac{\mu_i}{\mu_j}\frac{M_i}{M_j} Parameters ---------- xi : list Mole fractions of components, [-] Mi : float Molecular weights of components, [g/mol] mui : float Gas viscosities of components, [Pa·s] ki : list Thermal conductivities of components, [W/m·K] Returns ------- k : float Thermal conductivities of mixture, [W/m·K] Examples -------- Example 10-5 from [3]_; 25% benzene, 75% Argon at 100.6ºC and 1bar >>> xi = [0.25, 0.75] >>> Mi = [78.114, 39.948] >>> mui = [92.5e-7, 271e-7] >>> ki = [0.0166, 0.0214] >>> "%0.4f" % ThG_MasonSaxena(xi, Mi, mui, ki) '0.0184' """ # Aij coefficient with ε=1 as explain in [3]_, Eq 21 Aij = [] for mu_i, M_i in zip(mui, Mi): Aiji = [] for mu_j, M_j in zip(mui, Mi): # Monatomic value of thermal conductivity ratio, Eq 22 lt_ij = mu_i*M_j/mu_j/M_i Aiji.append((1+lt_ij**0.5*(M_i/M_j)**0.25)**2/(8*(1+M_i/M_j))**0.5) Aij.append(Aiji) # Calculate thermal conductivity, Eq 20 sumaj = [] for Aiji in Aij: suma = 0 for xj, A_ij in zip(xi, Aiji): suma += A_ij*xj sumaj.append(suma) k = 0 for x_i, k_i, si in zip(xi, ki, sumaj): k += k_i*x_i/si return unidades.ThermalConductivity(k)
[docs] @refDoc(__doi__, [15, 1]) def ThG_Chung(T, xi, Tci, Vci, Mi, wi, Cvi, mu): r"""Calculate thermal conductivity of gas mixtures at low pressure using the Chung correlation .. math:: \lambda_o = \frac{7.452\mu_o\Psi}{M} .. math:: \Psi = 1 + \alpha \left\{[0.215+0.28288\alpha-1.061\beta+0.26665Z]/ [0.6366+\beta Z + 1.061 \alpha \beta]\right\} .. math:: \alpha = \frac{C_v}{R}-1.5 .. math:: \beta = 0.7862-0.7109\omega + 1.3168\omega^2 .. math:: Z=2+10.5T_r^2 Parameters ---------- T : float Temperature, [K] xi : list Mole fractions of components, [-] Tci : list Critical temperature of compounds, [K] Vci : list Critical volume of compounds, [m³/kg] Mi : list Molecular weight of components, [g/mol] wi : list Acentric factor of compounds, [-] Cvi : list Ideal gas heat capacity at constant volume of components, [J/kg·K] mu : float Gas viscosity [Pa·s] Returns ------- k : float Thermal conductivity, [W/m/k] Examples -------- Example 10-5 from [3]_; 25% benzene, 75% Argon at 100.6ºC and 1bar >>> T = unidades.Temperature(100.6, "C") >>> xi = [0.25, 0.75] >>> Tci = [562.05, 150.86] >>> Vci = [256/78.114/1000, 74.57/39.948/1000] >>> Mi = [78.114, 39.948] >>> wi = [0.21, -0.002] >>> Cvi = [96.2/78.114*1000, 12.5/39.948*1000] >>> mui = [92.5e-7, 271e-7] >>> ki = [0, 0] >>> mu = MuG_Chung(T, xi, Tci, Vci, Mi, wi, mui, ki) >>> "%0.1f" % mu.microP '183.3' >>> "%0.4f" % ThG_Chung(T, xi, Tci, Vci, Mi, wi, Cvi, mu) '0.0222' """ # Molar values Vci = [Vc*M*1000 for Vc, M in zip(Vci, Mi)] Cvi = [Cv*M/1000 for Cv, M in zip(Cvi, Mi)] Cvm = sum([x*Cv for x, Cv in zip(xi, Cvi)]) sigmai = [0.809*Vc**(1/3) for Vc in Vci] # Eq 4 eki = [Tc/1.2593 for Tc in Tci] # Eq 5 # Eq 23 sigmaij = [] for s_i in sigmai: sigmaiji = [] for s_j in sigmai: sigmaiji.append((s_i*s_j)**0.5) sigmaij.append(sigmaiji) # Eq 24 ekij = [] for ek_i in eki: ekiji = [] for ek_j in eki: ekiji.append((ek_i*ek_j)**0.5) ekij.append(ekiji) # Eq 25 wij = [] for w_i in wi: wiji = [] for w_j in wi: wiji.append((w_i+w_j)/2) wij.append(wiji) # Eq 26 Mij = [] for M_i in Mi: Miji = [] for M_j in Mi: Miji.append(2*M_i*M_j/(M_i+M_j)) Mij.append(Miji) # Eq 14 sm = 0 for x_i, sigmaiji in zip(xi, sigmaij): for x_j, sij in zip(xi, sigmaiji): sm += x_i*x_j*sij**3 sm = sm**(1/3) # Eq 15 ekm = 0 for x_i, sigmaiji, ekiji in zip(xi, sigmaij, ekij): for x_j, sij, ek in zip(xi, sigmaiji, ekiji): ekm += x_i*x_j*ek*sij**3 ekm /= sm**3 # Eq 18 wm = 0 for x_i, sigmaiji, wiji in zip(xi, sigmaij, wij): for x_j, sij, w in zip(xi, sigmaiji, wiji): wm += x_i*x_j*w*sij**3 wm /= sm**3 # Eq 19 Mm = 0 for x_i, sigmaiji, ekiji, Miji in zip(xi, sigmaij, ekij, Mij): for x_j, s, ek, M in zip(xi, sigmaiji, ekiji, Miji): Mm += x_i*x_j*ek*s**2*M**0.5 Mm = (Mm/(ekm*sm**2))**2 Tcm = 1.2593*ekm Trm = T/Tcm alpha = Cvm/R - 1.5 beta = 0.7862 - 0.7109*wm + 1.3168*wm**2 Z = 2 + 10.5*Trm**2 phi = 1 + alpha*((0.215 + 0.28288*alpha - 1.061*beta + 0.26665*Z)/( 0.6366 + beta*Z + 1.061*alpha*beta)) # Eq 9 k = 7.452*mu*10/Mm*phi # Viscosity in P return unidades.ThermalConductivity(k, "calscmK")
[docs] @refDoc(__doi__, [15, 1]) def ThG_P_Chung(T, xi, Tci, Vci, Mi, wi, Di, ki, rho, ko): r"""Calculate the thermal conductivity of a compressed gas mixture using the Chung correlation .. math:: \lambda = \frac{31.2 \eta^o\Psi}{M}(1/G_2+B_6y)+qB_7y^2T_r^{1/2}G_2 Parameters ---------- T : float Temperature, [K] xi : list Mole fractions of components, [-] Tci : list Critical temperature of compounds, [K] Vci : list Critical volume of compounds, [m³/kg] Mi : list Molecular weight of components, [g/mol] wi : list Acentric factor of compounds, [-] Di : list Dipole moment of compounds, [Debye] ki : list Corection factor for polar substances, [-] rho : float Density, [kg/m³] ko : float Low-pressure gas thermal conductivity[Pa*S] Returns ------- k : float High-pressure gas thermal conductivity [W/m/k] Examples -------- Example 10-7 from [3]_; 75.5% methane, 24.5% CO2 at 370.8K and 174.8bar >>> Tc = [190.56, 304.12] >>> Vc = [98.6/16.043/1000, 94.07/44.01/1000] >>> M = [16.043, 44.01] >>> w = [0.011, 0.225] >>> x = [0.755, 0.245] >>> D = [0, 0] >>> k = [0, 0] >>> args = (370.8, x, Tc, Vc, M, w, D, k, 1/159*22.9*1000, 0.0377) >>> "%0.3f" % ThG_P_Chung(*args) '0.058' """ # Thermal conductivity in procedure in cal/s·cm·K ko = unidades.ThermalConductivity(ko).calscmK # Use critical volume in molar base Vci = [Vc*M*1000 for Vc, M in zip(Vci, Mi)] sigmai = [0.809*Vc**(1/3) for Vc in Vci] # Eq 4 eki = [Tc/1.2593 for Tc in Tci] # Eq 5 # Eq 23 sigmaij = [] for s_i in sigmai: sigmaiji = [] for s_j in sigmai: sigmaiji.append((s_i*s_j)**0.5) sigmaij.append(sigmaiji) # Eq 24 ekij = [] for ek_i in eki: ekiji = [] for ek_j in eki: ekiji.append((ek_i*ek_j)**0.5) ekij.append(ekiji) # Eq 25 wij = [] for w_i in wi: wiji = [] for w_j in wi: wiji.append((w_i+w_j)/2) wij.append(wiji) # Eq 26 Mij = [] for M_i in Mi: Miji = [] for M_j in Mi: Miji.append(2*M_i*M_j/(M_i+M_j)) Mij.append(Miji) # Eq 27 kij = [] for k_i in ki: kiji = [] for k_j in ki: kiji.append((k_i*k_j)**0.5) kij.append(kiji) # Eq 14 sm = 0 for x_i, sigmaiji in zip(xi, sigmaij): for x_j, sij in zip(xi, sigmaiji): sm += x_i*x_j*sij**3 sm = sm**(1/3) # Eq 15 ekm = 0 for x_i, sigmaiji, ekiji in zip(xi, sigmaij, ekij): for x_j, sij, ek in zip(xi, sigmaiji, ekiji): ekm += x_i*x_j*ek*sij**3 ekm /= sm**3 # Eq 18 wm = 0 for x_i, sigmaiji, wiji in zip(xi, sigmaij, wij): for x_j, sij, w in zip(xi, sigmaiji, wiji): wm += x_i*x_j*w*sij**3 wm /= sm**3 # Eq 19 Mm = 0 for x_i, sigmaiji, ekiji, Miji in zip(xi, sigmaij, ekij, Mij): for x_j, s, ek, M in zip(xi, sigmaiji, ekiji, Miji): Mm += x_i*x_j*ek*s**2*M**0.5 Mm = (Mm/(ekm*sm**2))**2 # Eq 20 Dm = 0 for x_i, sigmaiji, ekiji, D_i in zip(xi, sigmaij, ekij, Di): for x_j, s, ek, D_j in zip(xi, sigmaiji, ekiji, Di): Dm += x_i*x_j*(D_i*D_j)**2/ek/s**3 Dm = (Dm*ekm*sm**3)**0.25 # Eq 21 km = 0 for x_i, kiji in zip(xi, kij): for x_j, k in zip(xi, kiji): km += x_i*x_j*k rho = rho/Mm/1000 Vcm = (sm/0.809)**3 # Eq 16 Tcm = 1.2593*ekm # Eq 17 murm = 131.3*Dm/(Vcm*Tcm)**0.5 # Eq 22 T_ = T/ekm # Table IV dat = [ (2.41657, 0.74824, -0.91858, 121.72100), (-0.50924, -1.50936, -49.99120, 69.98340), (6.61069, 5.62073, 64.75990, 27.03890), (14.54250, -8.91387, -5.63794, 74.34350), (0.79274, 0.82019, -0.69369, 6.31734), (-5.86340, 12.80050, 9.58926, -65.52920), (81.17100, 114.15800, -60.84100, 466.77500)] # Eq 13 B = [] for bo, b1, b2, b3 in dat: B.append(bo + b1*wm + b2*murm**4 + b3*km) B1, B2, B3, B4, B5, B6, B7 = B Y = rho*Vcm/6 G1 = (1-0.5*Y)/(1-Y)**3 H2 = (B1*((1-exp(-B4*Y))/Y)+B2*G1*exp(B5*Y)+B3*G1)/(B1*B4+B2+B3) # Eq 12 kk = ko*(1/H2 + B6*Y) kp = (3.039e-4*(Tcm/Mm)**0.5/Vcm**(2/3))*B7*Y**2*H2*T_**0.5 return unidades.ThermalConductivity(kk+kp, "calscmK")
[docs] @refDoc(__doi__, [7, 3]) def ThG_StielThodosYorizane(T, xi, Tci, Pci, Vci, wi, Mi, V, ko): r"""Calculate thermal conductiviy of gas mixtures at high pressure using the Stiel-Thodos correlation for pure compound using the mixing rules defined by Yorizane et al. .. math:: T_{cm} = \frac{\sum_i \sum_j x_ix_jV_{cij}T_{cij}}{V_{cm}} .. math:: V_{cm} = \sum_i \sum_j x_ix_jV_{cij} .. math:: \omega_m = \sum_i x_i\omega_i .. math:: Z_{cm} = 0.291-0.08\omega_m .. math:: P_{cm} = \frac{Z_{cm}RT_{cm}}{V_{cm}} .. math:: M_m = \sum_i x_iM_i .. math:: T_{cij} = \left(T_{ci}T_{cj}\right)^{1/2} .. math:: V_{cij} = \frac{\left(V_{ci}^{1/3}+V_{cj}^{1/3}\right)^3}{8} Parameters ---------- T : float Temperature, [K] xi : list Mole fractions of components, [-] Tci : list Critical temperature of compounds, [K] Vci : list Critical volume of compounds, [m³/kg] Zci : list Critical pressure of compounds, [-] wi : list Acentric factor of compounds, [-] Mi : list Molecular weight of compounds, [g/mol] V : float Specific volume, [m³/kg] ko : list Thermal conductivities of mixture at low pressure, [W/m·K] Returns ------- k : float Thermal conductivities of mixture, [W/m·K] Examples -------- Example 10-6 from [3]_; 75.5% methane, 24.5% CO2 at 370.8K and 174.8bar >>> Tc = [190.56, 304.12] >>> Pc = [45.99e5, 73.74e5] >>> Vc = [98.6/16.043/1000, 94.07/44.01/1000] >>> M = [16.043, 44.01] >>> w = [0.011, 0.225] >>> x = [0.755, 0.245] >>> args = (370.8, x, Tc, Pc, Vc, w, M, 159/22.9/1000, 0.0377) >>> "%0.4f" % ThG_StielThodosYorizane(*args) '0.0527' """ # Use critical volume in molar base Vci = [Vc*M*1000 for Vc, M in zip(Vci, Mi)] # Eq 8; missing rules for critical properties wm = sum([x*w for x, w in zip(xi, wi)]) Mm = sum([x*M for x, M in zip(xi, Mi)]) Zcm = 0.291-0.08*wm Vcij = [] for Vc_i in Vci: Vciji = [] for Vc_j in Vci: Vciji.append((Vc_i**(1/3)+Vc_j**(1/3))**3/8) Vcij.append(Vciji) Vcm = 0 for x_i, Vciji in zip(xi, Vcij): for x_j, Vc in zip(xi, Vciji): Vcm += x_i*x_j*Vc Tcij = [] for Tc_i in Tci: Tciji = [] for Tc_j in Tci: Tciji.append((Tc_i*Tc_j)**0.5) Tcij.append(Tciji) Tcm = 0 for x_i, Vciji, Tciji in zip(xi, Vcij, Tcij): for x_j, Vc, Tc in zip(xi, Vciji, Tciji): Tcm += x_i*x_j*Vc*Tc/Vcm Pcm = Zcm*R*Tcm/Vcm*1e6 Vcm = Vcm/Mm/1000 km = ThG_StielThodos(T, Tcm, Pcm, Vcm, Mm, V, ko) return unidades.ThermalConductivity(km)
[docs] @refDoc(__doi__, [1, 21]) def ThG_TRAPP(T, xi, Tci, Vci, Zci, wi, Mi, rho, ko): r"""Calculate the thermal conductivity of gas mixtures at high pressure using the TRAPP (TRAnsport Property Prediction) method. .. math:: \lambda_m = \lambda_m^o+F_{\lambda m}X_{\lambda m} \left(\lambda^R-\lambda^{Ro}\right) .. math:: h_m = \sum_i \sum_j x_ix_jh_{ij} .. math:: f_m = \frac{\sum_i \sum_j x_ix_jf_{ij}h_{ij}}{h_m} .. math:: h_{ij}=\frac{\left(h_i^{1/3}+h_j^{1/3}\right)^3}{8} .. math:: f_{ij} = \left(f_if_j\right)^{1/2} .. math:: T_o = T/f_m .. math:: \rho_o = \rho h_m .. math:: F_{\lambda m} = \frac{44.094^{1/2}}{h_m^2} \sum_i \sum_j x_ix_j \left(\frac{f_{ij}}{M_{ij}}\right)^{1/2}h_{ij}^{4/3} .. math:: M_{ij} = \left(\frac{1}{2M_i}+\frac{1}{2M_j}\right)^{-1} .. math:: X_{\lambda m} = \left[1+\frac{2.1866\left(\omega_m-\omega^R\right)} {1-0.505\left(\omega_m-\omega^R\right)}\right]^{1/2} .. math:: \omega_m = \sum_i x_i\omega_i Parameters ---------- T : float Temperature, [K] xi : list Mole fractions of components, [-] Tci : list Critical temperature of compounds, [K] Vci : list Critical volume of compounds, [m³/kg] Zci : list Critical pressure of compounds, [Pa] wi : list Acentric factor of compounds, [-] Mi : list Molecular weight of compounds, [g/mol] rho : float Density, [kg/m3] ko : float Low-pressure gas thermal conductivity, [Pa*S] Returns ------- k : float High-pressure gas thermal conductivity [W/m/k] Examples -------- Example 10-8 from [3]_; 75.5% methane, 24.5% CO2 at 370.8K and 174.8bar >>> Tc = [190.56, 304.12] >>> Vc = [98.6/16.043/1000, 94.07/44.01/1000] >>> Zc = [0.286, 0.274] >>> M = [16.043, 44.01] >>> w = [0.011, 0.225] >>> x = [0.755, 0.245] >>> args = (370.8, x, Tc, Vc, Zc, w, M, 1/159*22.9*1000, 0.0377) >>> "%0.4f" % ThG_TRAPP(*args) '0.0549' """ # Reference fluid properties, propane TcR = 369.83 rhocR = 1/200 # mol/cm³ ZcR = 0.276 wR = 0.152 # Convert volume to molar base Vci = [Vc*M*1000 for Vc, M in zip(Vci, Mi)] Mm = sum([x*M for x, M in zip(xi, Mi)]) rho = rho/Mm/1000 # Calculate shape factor for mixture fi = [] hi = [] for Tc, Vc, Zc, w in zip(Tci, Vci, Zci, wi): fi.append(Tc/TcR*(1+(w-wR)*(0.05203-0.7498*log(T/Tc)))) hi.append(rhocR*Vc*ZcR/Zc*(1-(w-wR)*(0.1436-0.2822*log(T/Tc)))) fij = [] for f_i in fi: fiji = [] for f_j in fi: fiji.append((f_i*f_j)**0.5) fij.append(fiji) hij = [] for h_i in hi: hiji = [] for h_j in hi: hiji.append((h_i**(1/3)+h_j**(1/3))**3/8) hij.append(hiji) hm = 0 for x_i, hiji in zip(xi, hij): for x_j, h in zip(xi, hiji): hm += x_i*x_j*h fm = 0 for x_i, hiji, fiji in zip(xi, hij, fij): for x_j, h, f in zip(xi, hiji, fiji): fm += x_i*x_j*f*h/hm To = T/fm rho0 = rho*hm Mij = [] for M_i in Mi: Miji = [] for M_j in Mi: Miji.append(1/(1/2/M_i+1/2/M_j)) Mij.append(Miji) suma = 0 for x_i, fiji, Miji, hiji in zip(xi, fij, Mij, hij): for x_j, f, M, h in zip(xi, fiji, Miji, hiji): suma += x_i*x_j*(f/M)**0.5*h**(4/3) Flm = 44.094**0.5/hm**2*suma wm = sum([x*w for x, w in zip(xi, wi)]) Xlm = (1+2.1866*(wm-wR)/(1-0.505*(wm-wR)))**0.5 # Coefficients in [53]_, pag 796 # Density are in mol/dm³ rho0 *= 1000 rhocR *= 1000 rhorR = rho0/rhocR TrR = To/TcR lR = 15.2583985944*rhorR + 5.29917319127*rhorR**3 + \ (-3.05330414748+0.450477583739/TrR)*rhorR**4 + \ (1.03144050679-0.185480417707/TrR)*rhorR**5 return unidades.ThermalConductivity(Flm*Xlm*lR*1e-3 + ko)
[docs] @refDoc(__doi__, [8, 2]) def Tension(xi, sigmai): r"""Calculate surface tension of liquid nmixtures using the Morgan-Griggs law of mixtures method, also referenced in API procedure 10A2.1, pag 991 .. math:: \sigma_{m} = \sum_{i} x_i \sigma_i Parameters ---------- xi : list Mole fractions of components, [-] sigmai : list Surface tension of components, [N/m] Returns ------- sigma : float Surface tension of mixture, [N/m] Examples -------- Example from [2]_ 37.9% benzene, 62.1% CycloC6 at 77F and 1atm >>> s1 = unidades.Tension(28.2, "dyncm") >>> s2 = unidades.Tension(24.3, "dyncm") >>> "%0.1f" % Tension([0.379, 0.621], [s1, s2]).dyncm '25.8' """ sigma = 0 for x, s in zip(xi, sigmai): sigma += x*s return unidades.Tension(sigma)
[docs] class Mezcla(config.Entity): """ Class to model mixture calculation, components, physics properties, mixing rules, entity save/load layer. Parameters ---------- tipo : int kind of mix definition: * 0 : Undefined * 1 : Unitary Massflow * 2 : Unitary Molarflow * 3 : Mass flow and molar fractions * 4 : Mass flow and mass fractions * 5 : Molar flow and molar fractions * 6 : Molar flow and mass fractions ids : list Index of component in database, [-] customCmp : list List with additional component defined out of main database fraccionMolar: list Molar fraccion list of compounds, [-] fraccionMasica: list Mass fraccion list of compounds, [-] caudalMasico: float Total mass flow, [kg/h) caudalMolar: float Total molar flow, [kmol/h) caudalUnitarioMasico: list Mass flow for each compund, [kg/h] caudalUnitarioMolar: list Molar flow for each compund, [kmol/h] Notes ----- Additionally can define custom calculation method with the parameters: * *ids*: List with component index of mixture * *rhoLMix*: Liquid density correlation index * *Corr_RhoLMix*: Compressed liquid density correlation index * *MuLMix*: Liquid viscosity correlation index * *MuGMix*: Gas viscosity correlation index * *corr_MuGMix*: Compressed gas viscosity correlation index * *ThCondLMix*: Liquid thermal conductivity correlation index * *ThCondGMix*: Gas thermal conductivity correlation index * *corr_ThCondGMix*: Compressed gas thermal conductivity correlation These options overwrite the project configuration and the user configuration, for now only in API usage. Not custom stream property definition in main program Examples -------- This are several ejemples of usage of this class with several configuration definition, obviously not all correlation return valid values. Liquid density methods: Example from [2]_; 58.71% ethane, 41.29% heptane at 91ºF >>> xi = [0.5871, 0.4129] >>> c0 = Mezcla(2, ids=[3, 11], caudalUnitarioMolar=xi, RhoLMix=0) >>> c1 = Mezcla(2, ids=[3, 11], caudalUnitarioMolar=xi, RhoLMix=1) >>> args = (unidades.Temperature(91, "F"), 101325) >>> "%0.2f %0.2f" % (c0.RhoL(*args).kgl, c1.RhoL(*args).kgl) '0.57 0.57' Example from [3]_; 20% ethane, 80% nC10 at 166F and 3000psi >>> c0 = Mezcla(2, ids=[3, 14], caudalUnitarioMolar=[2, 8], RhoLPMix=0) >>> c1 = Mezcla(2, ids=[3, 14], caudalUnitarioMolar=[2, 8], RhoLPMix=1) >>> c2 = Mezcla(2, ids=[3, 14], caudalUnitarioMolar=[2, 8], RhoLPMix=2) >>> args = (unidades.Temperature(160, "F"), unidades.Pressure(3000, "psi")) >>> "%0.3f %0.3f" % (c0.RhoL(*args).kgl, c1.RhoL(*args).kgl) '0.678 0.681' >>> "%0.3f" % c2.RhoL(*args).kgl '0.687' Gas viscosity methods: Example 9-4 from [3]_; 28.6% N2, 71.4% R22 at 50ºC >>> c0 = Mezcla(2, ids=[46, 220], caudalUnitarioMolar=[286, 714], MuGMix=0) >>> c1 = Mezcla(2, ids=[46, 220], caudalUnitarioMolar=[286, 714], MuGMix=1) >>> c2 = Mezcla(2, ids=[46, 220], caudalUnitarioMolar=[286, 714], MuGMix=2) >>> c3 = Mezcla(2, ids=[46, 220], caudalUnitarioMolar=[286, 714], MuGMix=3) >>> c4 = Mezcla(2, ids=[46, 220], caudalUnitarioMolar=[286, 714], MuGMix=4) >>> args = (unidades.Temperature(50, "C"), 101325, 0) >>> "%0.2f %0.2f" % (c0.Mu_Gas(*args).microP, c1.Mu_Gas(*args).microP) '151.22 160.94' >>> "%0.2f %0.2f" % (c2.Mu_Gas(*args).microP, c3.Mu_Gas(*args).microP) '156.18 148.89' >>> "%0.2f" % c4.Mu_Gas(*args).microP '148.66' Example 9-14 in [3]_, 80% methane, 20% nC10 at 377.6K and 413.7bar >>> c0 = Mezcla(2, ids=[2, 14], caudalUnitarioMolar=[8, 2], MuGPMix=0) >>> c1 = Mezcla(2, ids=[2, 14], caudalUnitarioMolar=[8, 2], MuGPMix=1) >>> c2 = Mezcla(2, ids=[2, 14], caudalUnitarioMolar=[8, 2], MuGPMix=2) >>> c3 = Mezcla(2, ids=[2, 14], caudalUnitarioMolar=[8, 2], MuGPMix=3) >>> c4 = Mezcla(2, ids=[2, 14], caudalUnitarioMolar=[8, 2], MuGPMix=4) >>> args = (377.6, 413.7e5, 448.4) >>> "%0.2f %0.2f" % (c0.Mu_Gas(*args).muPas, c1.Mu_Gas(*args).muPas) '55.66 112.22' >>> "%0.2f %0.2f" % (c2.Mu_Gas(*args).muPas, c3.Mu_Gas(*args).muPas) '83.37 40.78' >>> "%0.2f" % c4.Mu_Gas(*args).muPas '39.91' Liquid viscosity methods: Example A from [2]_; 29.57% nC16, 35.86% benzene, 34.57% nC6 at 77ºF >>> x = [0.2957, 0.3586, 0.3457] >>> c0 = Mezcla(2, ids=[20, 40, 10], caudalUnitarioMolar=x, MuLMix=0) >>> c1 = Mezcla(2, ids=[20, 40, 10], caudalUnitarioMolar=x, MuLMix=1) >>> args = (unidades.Temperature(77, "F"), 101325) >>> "%0.2f %0.2f" % (c0.Mu_Liquido(*args).cP, c1.Mu_Liquido(*args).cP) '0.88 0.76' Liquid thermal conductivity methods: Example from [2]_ 68% nC7, 32% CycloC5 at 32F and 1atm >>> x = [0.68, 0.32] >>> c0 = Mezcla(2, ids=[11, 36], caudalUnitarioMolar=x, ThCondLMix=0) >>> c1 = Mezcla(2, ids=[11, 36], caudalUnitarioMolar=x, ThCondLMix=1) >>> args = (unidades.Temperature(32, "F"), 101325, 0) >>> "%0.3f %0.3f" % (c0.ThCond_Liquido(*args), c1.ThCond_Liquido(*args)) '0.132 0.132' Gas thermal conductivity methods: Example 10-5 from [3]_; 25% benzene, 75% Argon at 100.6ºC and 1bar >>> x = [0.25, 0.75] >>> c0 = Mezcla(2, ids=[40, 98], caudalUnitarioMolar=x, ThCondGMix=0) >>> c1 = Mezcla(2, ids=[40, 98], caudalUnitarioMolar=x, ThCondGMix=1) >>> c2 = Mezcla(2, ids=[40, 98], caudalUnitarioMolar=x, ThCondGMix=2) >>> args = (unidades.Temperature(100.6, "C"), 1e5, 0) >>> "%0.4f %0.4f" % (c0.ThCond_Gas(*args), c1.ThCond_Gas(*args)) '0.0187 0.0197' >>> "%0.4f" % c2.ThCond_Gas(*args) '0.0224' Example 10-6 from [3]_; 75.5% methane, 24.5% CO2 at 370.8K and 174.8bar Here the Chung method is the best option to get the low pressure thermal conductivity of mixture >>> x = [0.755, 0.245] >>> kw = {"caudalUnitarioMolar": x, "ThCondGMix": 2} >>> c0 = Mezcla(2, ids=[2, 49], ThCondGPMix=0, **kw) >>> c1 = Mezcla(2, ids=[2, 49], ThCondGPMix=1, **kw) >>> c2 = Mezcla(2, ids=[2, 49], ThCondGPMix=2, **kw) >>> args = (370.8, 174.8e5, 1/159*22.9*1000) >>> "%0.4f %0.4f" % (c0.ThCond_Gas(*args), c1.ThCond_Gas(*args)) '0.0526 0.0548' >>> "%0.4f" % c2.ThCond_Gas(*args) '0.0580' """ kwargs = {"ids": [], "customCmp": [], "caudalMasico": 0.0, "caudalMolar": 0.0, "caudalUnitarioMolar": [], "caudalUnitarioMasico": [], "fraccionMolar": [], "fraccionMasica": [], "RhoLMix": None, "RhoLPMix": None, "MuLMix": None, "MuGMix": None, "MuGPMix": None, "ThCondLMix": None, "ThCondGMix": None, "ThCondGPMix": None } METHODS_RhoL = ["Rackett", "COSTALD"] METHODS_RhoLP = ["Aalto-Keskinen (1996)", "Tait-COSTALD (1982", "Nasrifar (2000)", "API"] METHODS_MuG = ["Reichenberg (1975)", "Lucas (1984)", "Chung (1988)", "Wilke (1950)", "Herning-Zipperer (1936)"] METHODS_MuGP = ["Lucas (1984)", "Chung (1988)", "TRAPP (1996)", "Dean-Stiel (1965)", "API"] METHODS_MuL = ["Kendall-Monroe", "Arrhenius"] METHODS_ThG = ["Mason-Saxena (1958)", "Lindsay-Bromley (1950)", "Chung (1988)"] METHODS_ThGP = ["Stiel-Thodos-Yorizane (1983)", "TRAPP", "Chung (1988)"] METHODS_ThL = ["Li (1976)", "Power Law"]
[docs] def __init__(self, tipo=0, **kwargs): if tipo == 0: self._bool = False return self._bool = True self.kwargs = Mezcla.kwargs.copy() self.kwargs.update(kwargs) self.Config = config.getMainWindowConfig() if self.kwargs["ids"]: self.ids = self.kwargs.get("ids") elif self.kwargs["customCmp"]: # Initialice ids variable to avoid acumulate in several instances self.ids = [] else: txt = self.Config.get("Components", "Components") if isinstance(txt, str): self.ids = eval(txt) else: self.ids = txt self.componente = [Componente(int(i), **kwargs) for i in self.ids] for cmp in self.kwargs["customCmp"]: self.componente.append(cmp) self.ids.append(0) fraccionMolar = self.kwargs.get("fraccionMolar", None) fraccionMasica = self.kwargs.get("fraccionMasica", None) caudalMasico = self.kwargs.get("caudalMasico", None) caudalMolar = self.kwargs.get("caudalMolar", None) caudalUnitarioMasico = self.kwargs.get("caudalUnitarioMasico", None) caudalUnitarioMolar = self.kwargs.get("caudalUnitarioMolar", None) # normalizce fractions to unit if fraccionMolar: suma = float(sum(fraccionMolar)) fraccionMolar = [x/suma for x in fraccionMolar] if fraccionMasica: suma = float(sum(fraccionMasica)) fraccionMasica = [x/suma for x in fraccionMasica] # calculate all concentration units if tipo == 1: kw = mix_unitmassflow(caudalUnitarioMasico, self.componente) elif tipo == 2: kw = mix_unitmolarflow(caudalUnitarioMolar, self.componente) elif tipo == 3: kw = mix_massflow_molarfraction( caudalMasico, fraccionMolar, self.componente) elif tipo == 4: kw = mix_massflow_massfraction( caudalMasico, fraccionMasica, self.componente) elif tipo == 5: kw = mix_molarflow_molarfraction( caudalMolar, fraccionMolar, self.componente) elif tipo == 6: kw = mix_molarflow_massfraction( caudalMolar, fraccionMasica, self.componente) caudalMolar = kw["molarFlow"] caudalMasico = kw["massFlow"] caudalUnitarioMasico = kw["unitMassFlow"] caudalUnitarioMolar = kw["unitMolarFlow"] fraccionMolar = kw["molarFraction"] fraccionMasica = kw["massFraction"] # # Clean component with null composition # self.zeros = [] # for i, x in enumerate(fraccionMolar): # if not x: # self.zeros.append(i) # # for i in self.zeros[::-1]: # del self.ids[i] # del self.componente[i] # del fraccionMolar[i] # del fraccionMasica[i] # del caudalUnitarioMasico[i] # del caudalUnitarioMolar[i] self.fraccion = [unidades.Dimensionless(f) for f in fraccionMolar] self.caudalmasico = unidades.MassFlow(caudalMasico) self.caudalmolar = unidades.MolarFlow(caudalMolar) self.fraccion_masica = [unidades.Dimensionless(f) for f in fraccionMasica] self.caudalunitariomasico = [unidades.MassFlow(q) for q in caudalUnitarioMasico] self.caudalunitariomolar = [unidades.MolarFlow(q) for q in caudalUnitarioMolar] self.M = unidades.Dimensionless(caudalMasico/caudalMolar) if tipo == 0: self._bool = False self.status = 0 return else: self._bool = True self.status = 1 # Calculate critic temperature, API procedure 4B1.1 pag 304 V = sum([xi*cmp.Vc for xi, cmp in zip(self.fraccion, self.componente)]) k = [xi*cmp.Vc/V for xi, cmp in zip(self.fraccion, self.componente)] Tcm = sum([ki*cmp.Tc for ki, cmp in zip(k, self.componente)]) self.Tc = unidades.Temperature(Tcm) # Calculate pseudocritic temperature t = sum([xi*cmp.Tc for xi, cmp in zip(self.fraccion, self.componente)]) self.tpc = unidades.Temperature(t) # Calculate pseudocritic pressure p = sum([xi*cmp.Pc for xi, cmp in zip(self.fraccion, self.componente)]) self.ppc = unidades.Pressure(p) # Calculate critic pressure, API procedure 4B2.1 pag 307 sumaw = 0 for xi, cmp in zip(self.fraccion, self.componente): sumaw += xi*cmp.f_acent pc = self.ppc+self.ppc*(5.808+4.93*sumaw)*(self.Tc-self.tpc)/self.tpc self.Pc = unidades.Pressure(pc) # Calculate acentric factor, API procedure 6B2.2-6 pag 523 self.f_acent = sum([xi*cmp.f_acent for xi, cmp in zip(self.fraccion, self.componente)]) self.f_acent_mod = sum([xi*cmp.f_acent_mod for xi, cmp in zip(self.fraccion, self.componente)]) # Calculate critic volume Vci = self._arraylize("Vc") Mi = self._arraylize("M") hc = self._arraylize("isHydrocarbon") self.Vc = Vc_ChuehPrausnitz(self.fraccion, Vci, Mi, hydrocarbon=hc) tb = [xi*cmp.Tb for xi, cmp in zip(self.fraccion, self.componente)] self.Tb = unidades.Temperature(sum(tb)) self.SG = sum([xi*cmp.SG for xi, cmp in zip(self.fraccion, self.componente)])
def __call__(self): pass
[docs] def _arraylize(self, prop, unit=None): """Get the compounds property prop as list prop: a string code with the property to return f_acent, M, Vc, Tc,... """ array = [] for cmp in self.componente: value = cmp.__getattribute__(prop) if unit: value = value.__getattribute__(unit) array.append(value) return array
[docs] @refDoc(__doi__, [2], tab=8) def _Ho(self, T): r"""Ideal gas enthalpy, referenced in API procedure 7B4.1, pag 645 .. math:: H_m^o = \sum_i x_wH_i^o Parameters ---------- T : float Temperature, [K] """ h = 0 for xw, cmp in zip(self.fraccion_masica, self.componente): h += xw*cmp._Ho(T) return unidades.Enthalpy(h)
[docs] @refDoc(__doi__, [2], tab=8) def _so(self, T): r""" Ideal gas entropy, referenced in API procedure 7F2.1, pag 741 .. math:: S_m^o = \sum_i x_wS_i^o - \frac{R}{M} x_i\lnx_i Parameters ---------- T : float Temperature, [K] """ s = 0 for x, xw, cmp in zip( self.fraccion, self.fraccion_masica, self.componente): s += xw*cmp._So(T) + R/cmp.M*x*log(x) return unidades.SpecificHeat(s)
[docs] def Cp_Gas(self, T, P): """Calculate specific heat from gas, API procedure 7D4.1, pag 714""" Cp = 0 for xi, cmp in zip(self.fraccion_masica, self.componente): Cp += xi*cmp.Cp_Gas_DIPPR(T) return unidades.SpecificHeat(Cp)
[docs] def Cp_Liquido(self, T): """Calculate specific heat from liquid, API procedure 7D1.9, pag 714""" Cp = 0 for xi, cmp in zip(self.fraccion_masica, self.componente): Cp += xi*cmp.Cp_Liquido(T) return unidades.SpecificHeat(Cp)
[docs] def RhoL(self, T, P): """Calculate the density of liquid phase using any of available correlation""" method = self.kwargs["RhoLMix"] if method is None or method >= len(Mezcla.METHODS_RhoL): method = self.Config.getint("Transport", "RhoLMix") Pcorr = self.kwargs["RhoLPMix"] if Pcorr is None or method >= len(Mezcla.METHODS_RhoLP): Pcorr = self.Config.getint("Transport", "Corr_RhoLMix") # Calculate of low pressure viscosity if method == 0: Tci = self._arraylize("Tc") Pci = self._arraylize("Pc") Vci = self._arraylize("Vc") Zrai = self._arraylize("rackett") Mi = self._arraylize("M") rhos = RhoL_RackettMix(T, self.fraccion, Tci, Pci, Vci, Zrai, Mi) elif method == 1: Tci = self._arraylize("Tc") Vci = self._arraylize("Vc") wi = self._arraylize("f_acent") Mi = self._arraylize("M") rhos = RhoL_CostaldMix(T, self.fraccion, Tci, wi, Vci, Mi) # Add correction factor for high pressure if P < 1e6: rho = rhos elif Pcorr == 0: Tci = self._arraylize("Tc") Pci = self._arraylize("Pc") Vci = self._arraylize("Vc") Mi = self._arraylize("M") wi = self._arraylize("f_acent") Mi = self._arraylize("M") rho = RhoL_AaltoKeskinenMix( T, P, self.fraccion, Tci, Pci, Vci, wi, Mi, rhos) elif Pcorr == 1: Tci = self._arraylize("Tc") Vci = self._arraylize("Vc") Mi = self._arraylize("M") wi = self._arraylize("f_acent") Mi = self._arraylize("M") rho = RhoL_TaitCostaldMix( T, P, self.fraccion, Tci, Vci, wi, Mi, rhos) elif Pcorr == 2: Tci = self._arraylize("Tc") Vci = self._arraylize("Vc") Mi = self._arraylize("M") wi = self._arraylize("f_acent") Mi = self._arraylize("M") rho = RhoL_NasrifarMix(T, P, self.fraccion, Tci, Vci, wi, Mi, rhos) elif Pcorr == 3: Tci = self._arraylize("Tc") Mi = self._arraylize("M") wi = self._arraylize("f_acent") Mi = self._arraylize("M") rho = RhoL_APIMix(T, P, self.fraccion, Tci, Pci, rhos) return rho
[docs] def Mu_Gas(self, T, P, rho): """General method for calculate viscosity of gas""" method = self.kwargs["MuGMix"] if method is None or method >= len(Mezcla.METHODS_MuG): method = self.Config.getint("Transport", "MuGMix") Pcorr = self.kwargs["MuGPMix"] if Pcorr is None or method >= len(Mezcla.METHODS_MuGP): Pcorr = self.Config.getint("Transport", "Corr_MuGMix") # Calculate of low pressure viscosity if method == 0: Tci = self._arraylize("Tc") Pci = self._arraylize("Pc") Mi = self._arraylize("M") Mi = self._arraylize("M") Di = self._arraylize("dipole", "Debye") mui = [cmp.Mu_Gas(T, 101325, rho) for cmp in self.componente] muo = MuG_Reichenberg(T, self.fraccion, Tci, Pci, Mi, mui, Di) elif method == 1: Tci = self._arraylize("Tc") Pci = self._arraylize("Pc") Vci = self._arraylize("Vc") Zci = self._arraylize("Zc") Mi = self._arraylize("M") Di = self._arraylize("dipole", "Debye") muo = MuG_Lucas( T, 101325, self.fraccion, Tci, Pci, Vci, Zci, Mi, Di) elif method == 2: Tci = self._arraylize("Tc") Vci = self._arraylize("Vc") Mi = self._arraylize("M") wi = self._arraylize("f_acent") Di = self._arraylize("dipole", "Debye") ki = [cmp._K_Chung() for cmp in self.componente] muo = MuG_Chung(T, self.fraccion, Tci, Vci, Mi, wi, Di, ki) elif method == 3: Mi = self._arraylize("M") mui = [cmp.Mu_Gas(T, 101325, None) for cmp in self.componente] muo = MuG_Wilke(self.fraccion, Mi, mui) elif method == 4: Mi = self._arraylize("M") mui = [cmp.Mu_Gas(T, 101325, None) for cmp in self.componente] muo = MuG_Herning(self.fraccion, Mi, mui) # Add correction factor for high pressure if P < 1e6: mu = muo elif Pcorr == 0: Tci = self._arraylize("Tc") Pci = self._arraylize("Pc") Vci = self._arraylize("Vc") Zci = self._arraylize("Zc") Mi = self._arraylize("M") Di = self._arraylize("dipole", "Debye") mu = MuG_Lucas(T, P, self.fraccion, Tci, Pci, Vci, Zci, Mi, Di) elif Pcorr == 1: Tci = self._arraylize("Tc") Vci = self._arraylize("Vc") Mi = self._arraylize("M") wi = self._arraylize("f_acent") Di = self._arraylize("dipole", "Debye") ki = [cmp._K_Chung() for cmp in self.componente] mu = MuG_P_Chung( T, self.fraccion, Tci, Vci, Mi, wi, Di, ki, rho, muo) elif Pcorr == 2: Tci = self._arraylize("Tc") Vci = self._arraylize("Vc") Zci = self._arraylize("Zc") Mi = self._arraylize("M") wi = self._arraylize("f_acent") mu = MuG_TRAPP( T, P, self.fraccion, Tci, Vci, Zci, Mi, wi, rho, muo) elif Pcorr == 3: Tci = self._arraylize("Tc") Pci = self._arraylize("Pc") Vci = self._arraylize("Vc") Mi = self._arraylize("M") rhoc = 1/Vc_ChuehPrausnitz(self.fraccion, Vci, Mi) mu = MuG_DeanStielMix(self.fraccion, Tci, Pci, Mi, rhoc, rho, muo) elif Pcorr == 4: Tci = self._arraylize("Tc") Pci = self._arraylize("Pc") mu = MuG_APIMix(T, P, self.fraccion, Tci, Pci, muo) return mu
[docs] def Mu_Liquido(self, T, P): """General method for calculate viscosity of Liquid""" method = self.kwargs["MuLMix"] if method is None or method >= len(Mezcla.METHODS_MuL): method = self.Config.getint("Transport", "MuLMix") if method == 0: mui = [cmp.Mu_Liquido(T, P) for cmp in self.componente] mu = MuL_KendallMonroe(self.fraccion, mui) elif method == 1: Mi = self._arraylize("M") mui = [cmp.Mu_Liquido(T, P) for cmp in self.componente] mu = MuL_Chemcad(self.fraccion, Mi, mui) return mu
[docs] def Tension(self, T): """General method for calculate surface tension""" sigmai = [cmp.Tension(T) for cmp in self.componente] tension = Tension(self.fraccion, sigmai) return unidades.Tension(tension)
[docs] def ThCond_Liquido(self, T, P, rho): """General method for calculate thermal conductivity of liquid""" method = self.kwargs["ThCondLMix"] if method is None or method >= len(Mezcla.METHODS_ThL): method = self.Config.getint("Transport", "ThCondLMix") if method == 0: Vi = [1/cmp.RhoL(T, P) for cmp in self.componente] Mi = self._arraylize("M") ki = [cmp.ThCond_Liquido(T, P, rho) for cmp in self.componente] k = ThL_Li(self.fraccion, Vi, Mi, ki) elif method == 1: ki = [cmp.ThCond_Liquido(T, P, rho) for cmp in self.componente] k = ThL_Power(self.fraccion_masica, ki) return k
[docs] def ThCond_Gas(self, T, P, rho): """General method for calculate thermal conductivity of gas""" method = self.kwargs["ThCondGMix"] if method is None or method >= len(Mezcla.METHODS_ThG): method = self.Config.getint("Transport", "ThCondGMix") Pcorr = self.kwargs["ThCondGPMix"] if Pcorr is None or method >= len(Mezcla.METHODS_ThGP): Pcorr = self.Config.getint("Transport", "Corr_ThCondGMix") # Calculate of low pressure viscosity if method == 0: Mi = self._arraylize("M") mui = [cmp.Mu_Gas(T, 101325, rho) for cmp in self.componente] ki = [cmp.ThCond_Gas(T, P, rho) for cmp in self.componente] ko = ThG_MasonSaxena(self.fraccion, Mi, mui, ki) elif method == 1: Mi = self._arraylize("M") Tbi = self._arraylize("Tb") mui = [cmp.Mu_Gas(T, 101325, rho) for cmp in self.componente] ki = [cmp.ThCond_Gas(T, P, rho) for cmp in self.componente] ko = ThG_LindsayBromley(T, self.fraccion, Mi, Tbi, mui, ki) elif method == 2: Tci = self._arraylize("Tc") Vci = self._arraylize("Vc") Mi = self._arraylize("M") wi = self._arraylize("f_acent") Cvi = [cmp.Cv(T) for cmp in self.componente] Di = self._arraylize("dipole", "Debye") ki = [cmp._K_Chung() for cmp in self.componente] mu = MuG_Chung(T, self.fraccion, Tci, Vci, Mi, wi, Di, ki) ko = ThG_Chung(T, self.fraccion, Tci, Vci, Mi, wi, Cvi, mu) # Add correction factor for high pressure if P < 1e6: k = ko elif Pcorr == 0: Tci = self._arraylize("Tc") Pci = self._arraylize("Pc") Vci = self._arraylize("Vc") wi = self._arraylize("f_acent") Mi = self._arraylize("M") k = ThG_StielThodosYorizane( T, self.fraccion, Tci, Pci, Vci, wi, Mi, 1/rho, ko) elif Pcorr == 1: Tci = self._arraylize("Tc") Vci = self._arraylize("Vc") Zci = self._arraylize("Zc") wi = self._arraylize("f_acent") Mi = self._arraylize("M") k = ThG_TRAPP(T, self.fraccion, Tci, Vci, Zci, wi, Mi, rho, ko) elif Pcorr == 2: Tci = self._arraylize("Tc") Vci = self._arraylize("Vc") Mi = self._arraylize("M") wi = self._arraylize("f_acent") Di = self._arraylize("dipole", "Debye") ki = [cmp._K_Chung() for cmp in self.componente] k = ThG_P_Chung( T, self.fraccion, Tci, Vci, Mi, wi, Di, ki, rho, ko) return k
# Entity related functionality
[docs] def writeStatetoJSON(self, state): mezcla = {} if self._bool: mezcla["ids"] = self.ids mezcla["fraction"] = self.fraccion mezcla["massFraction"] = self.fraccion_masica mezcla["massUnitFlow"] = self.caudalunitariomasico mezcla["molarUnitFlow"] = self.caudalunitariomolar mezcla["massFlow"] = self.caudalmasico mezcla["molarFlow"] = self.caudalmolar mezcla["M"] = self.M mezcla["Tc"] = self.Tc mezcla["tpc"] = self.tpc mezcla["ppc"] = self.ppc mezcla["Pc"] = self.Pc mezcla["w"] = self.f_acent mezcla["wm"] = self.f_acent_mod mezcla["Vc"] = self.Vc mezcla["Tb"] = self.Tb mezcla["SG"] = self.SG state["mezcla"] = mezcla
[docs] def readStatefromJSON(self, mezcla): if mezcla: self._bool = True self.ids = mezcla["ids"] self.componente = [Componente(int(i)) for i in self.ids] self.fraccion = [ unidades.Dimensionless(x) for x in mezcla["fraction"]] self.fraccion_masica = [ unidades.Dimensionless(x) for x in mezcla["massFraction"]] self.caudalunitariomasico = [ unidades.MassFlow(x) for x in mezcla["massUnitFlow"]] self.caudalunitariomolar = [ unidades.MolarFlow(x) for x in mezcla["molarUnitFlow"]] self.caudalmasico = unidades.MassFlow(mezcla["massFlow"]) self.caudalmolar = unidades.MolarFlow(mezcla["molarFlow"]) self.M = unidades.Dimensionless(mezcla["M"]) self.Tc = unidades.Temperature(mezcla["Tc"]) self.tpc = unidades.Temperature(mezcla["tpc"]) self.ppc = unidades.Pressure(mezcla["ppc"]) self.Pc = unidades.Pressure(mezcla["Pc"]) self.f_acent = unidades.Dimensionless(mezcla["w"]) self.f_acent_mod = unidades.Dimensionless(mezcla["wm"]) self.Vc = unidades.SpecificVolume(mezcla["Vc"]) self.Tb = unidades.Temperature(mezcla["Tb"]) self.SG = unidades.Dimensionless(mezcla["SG"])
[docs] def recallZeros(self, lista, val=0): """Method to return any list with null component added""" l = lista[:] for i in self.zeros: l.insert(i, val) return l
# TODO: # ThL_Rowley # Parachor method for tension if __name__ == '__main__': # T = unidades.Temperature(400, "F") # mezcla = Mezcla(1, ids=[4, 40], caudalUnitarioMasico=[26.92, 73.08]) # print(mezcla.Tension(T)) mezcla = Mezcla(2, ids=[1, 2, 40, 41], caudalUnitarioMolar=[ 0.004397674808848511, 0.057137022156057246, 0.7079892468704139, 0.23047605616468061]) P = unidades.Pressure(485, "psi") T = unidades.Temperature(100, "F") print(mezcla.RhoL(T, P))