Source code for thermosteam.properties.interface

# -*- coding: utf-8 -*-
"""
All data and methods related to a chemical's surface tension.

References
----------
.. [1] Diky, Vladimir, Robert D. Chirico, Chris D. Muzny, Andrei F.
    Kazakov, Kenneth Kroenlein, Joseph W. Magee, Ilmutdin Abdulagatov, and
    Michael Frenkel. "ThermoData Engine (TDE): Software Implementation of
    the Dynamic Data Evaluation Concept." Journal of Chemical Information
    and Modeling 53, no. 12 (2013): 3418-30. doi:10.1021/ci4005699.
.. [2] Somayajulu, G. R. "A Generalized Equation for Surface Tension from
    the Triple Point to the Critical Point." International Journal of
    Thermophysics 9, no. 4 (July 1988): 559-66. doi:10.1007/BF00503154.
.. [3] Jasper, Joseph J. "The Surface Tension of Pure Liquid Compounds."
    Journal of Physical and Chemical Reference Data 1, no. 4
    (October 1, 1972): 841-1010. doi:10.1063/1.3253106.
.. [4] Speight, James. Lange's Handbook of Chemistry. 16 edition.
    McGraw-Hill Professional, 2005.
.. [5] Brock, James R., and R. Byron Bird. "Surface Tension and the
    Principle of Corresponding States." AIChE Journal 1, no. 2
    (June 1, 1955): 174-77. doi:10.1002/aic.690010208
.. [6] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition.
   New York: McGraw-Hill Professional, 2000.
.. [7] Curl, R. F., and Kenneth Pitzer. "Volumetric and Thermodynamic
   Properties of Fluids-Enthalpy, Free Energy, and Entropy." Industrial &
   Engineering Chemistry 50, no. 2 (February 1, 1958): 265-74.
   doi:10.1021/ie50578a047
.. [8] Pitzer, K. S.: Thermodynamics, 3d ed., New York, McGraw-Hill,
   1995, p. 521.
.. [9] Sastri, S. R. S., and K. K. Rao. "A Simple Method to Predict
    Surface Tension of Organic Liquids." The Chemical Engineering Journal
    and the Biochemical Engineering Journal 59, no. 2 (October 1995): 181-86.
    doi:10.1016/0923-0467(94)02946-6.
.. [10] Zuo, You-Xiang, and Erling H. Stenby. "Corresponding-States and
    Parachor Models for the Calculation of Interfacial Tensions." The
    Canadian Journal of Chemical Engineering 75, no. 6 (December 1, 1997):
    1130-37. doi:10.1002/cjce.5450750617
.. [11] Hakim, D. I., David Steinberg, and L. I. Stiel. "Generalized
    Relationship for the Surface Tension of Polar Fluids." Industrial &
    Engineering Chemistry Fundamentals 10, no. 1 (February 1, 1971): 174-75.
    doi:10.1021/i160037a032.
.. [12] Miqueu, C, D Broseta, J Satherley, B Mendiboure, J Lachaise, and
    A Graciaa. "An Extended Scaled Equation for the Temperature Dependence
    of the Surface Tension of Pure Compounds Inferred from an Analysis of
    Experimental Data." Fluid Phase Equilibria 172, no. 2 (July 5, 2000):
    169-82. doi:10.1016/S0378-3812(00)00384-8.
.. [13] Aleem, W., N. Mellon, S. Sufian, M. I. A. Mutalib, and D. Subbarao.
    "A Model for the Estimation of Surface Tension of Pure Hydrocarbon 
    Liquids." Petroleum Science and Technology 33, no. 23-24 (December 17, 
    2015): 1908-15. doi:10.1080/10916466.2015.1110593.
.. [14] Mersmann, Alfons, and Matthias Kind. "Prediction of Mechanical and 
    Thermal Properties of Pure Liquids, of Critical Data, and of Vapor 
    Pressure." Industrial & Engineering Chemistry Research, January 31, 
    2017. https://doi.org/10.1021/acs.iecr.6b04323.

"""
from math import log, exp
from ..base import sigma, TDependentHandleBuilder, InterpolatedTDependentModel
from .utils import CASDataReader
from .._constants import N_A, k
from .miscdata import VDI_saturation_dict, VDI_tabular_data
from .dippr import DIPPR_EQ106

__all__ = ('REFPROP', 
           'Somayajulu', 
           'Jasper', 
           'Brock_Bird', 
           'Pitzer', 
           'Sastri_Rao', 
           'Zuo_Stenby',
           'Hakim_Steinberg_Stiel', 
           'Miqueu',
           'Mersmann_Kind_surface_tension'
)

read = CASDataReader(__file__, 'Interface')
_Mulero_Cachadina = read('MuleroCachadinaParameters.tsv')
_Jasper_Lange = read('Jasper-Lange.tsv')
_Somayajulu = read('Somayajulu.tsv')
_Somayajulu_2 = read('SomayajuluRevised.tsv')
_VDI_PPDS_11 = read('VDI PPDS surface tensions.tsv')


### Regressed coefficient-based functions

[docs]@sigma(ref='[1]_', method="regression-based REFPROP") def REFPROP(T, Tc, sigma0, n0, sigma1=0, n1=0, sigma2=0, n2=0): r""" Notes ----- Relatively recent, and most accurate. Function as implemented in [1]_: .. math:: \sigma(T)=\sigma_0\left(1-\frac{T}{T_c}\right)^{n_0}+ \sigma_1\left(1-\frac{T}{T_c}\right)^{n_1}+ \sigma_2\left(1-\frac{T}{T_c}\right)^{n_2} Form of function returns imaginary results when T > Tc, in which case None is returned instead. Examples -------- Parameters for water at 298.15 K: >>> f = REFPROP(647.096, -0.1306, 2.471, 0.2151, 1.233) >>> f(298.15) 0.07205503890847453 """ Tr = T/Tc invTr = 1. - Tr return sigma0*(invTr)**n0 + sigma1*(invTr)**n1 + sigma2*(invTr)**n2
[docs]@sigma(ref='[2]_') def Somayajulu(T, Tc, a, b, c): r''' Notes ----- The surface tension in [2]_ is given by: .. math:: \sigma=aX^{5/4}+bX^{9/4}+cX^{13/4} X=(T_c-T)/T_c Internal units are mN/m. Form of function returns imaginary results when T > Tc; None is returned if this is the case. Function is claimed valid from the triple to the critical point. Results can be evaluated beneath the triple point. Examples -------- Water at 300 K: >>> f = Somayajulu(647.126, 232.713514, -140.18645, -4.890098) >>> f(300) 0.07166386387996757 ''' X = (Tc-T)/Tc return (a*X**1.25 + b*X**2.25 + c*X**3.25)/1000.
[docs]@sigma(ref="[3]_ [4]_") def Jasper(T, a, b): r''' Notes ----- Calculates surface tension of a fluid given two parameters, a linear fit in Celcius from [1]_ with data reprinted in [2]_. .. math:: \sigma = a - bT Internal units are mN/m, and degrees Celcius. This function has been checked against several references. Examples -------- >>> f = Jasper(24, 0.0773) >>> f(298.15) 0.0220675 ''' return (a - b*(T-273.15))/1000
### CSP methods
[docs]@sigma(ref="[5]_") def Brock_Bird(T, Tb, Tc, Pc): r''' Notes ----- Calculates air-water surface tension using the [1]_ emperical method. Old and tested. .. math:: \sigma = P_c^{2/3}T_c^{1/3}Q(1-T_r)^{11/9} Q = 0.1196 \left[ 1 + \frac{T_{br}\ln (P_c/1.01325)}{1-T_{br}}\right]-0.279 Numerous arrangements of this equation are available. This is a DIPPR Procedure 7A: Method for the Surface Tension of Pure, Nonpolar, Nonhydrocarbon Liquids. The exact equation is not in the original paper. If the equation yields a negative result, returns None instead. Examples -------- p-dichloribenzene at 412.15 K, from DIPPR; value differs due to a slight difference in method: >>> f = Brock_Bird(447.3, 685, 3.952E6) >>> f(412.15) 0.02208448325192495 Chlorobenzene from Poling, as compared with a % error value at 293 K: >>> f = Brock_Bird(404.75, 633.0, 4530000.0) >>> f(293.15) 0.032985686413713036 ''' Tbr = Tb/Tc Tr = T/Tc Pc = Pc/1E5 # Convert to bar Q = 0.1196*(1 + Tbr*log(Pc/1.01325)/(1-Tbr))-0.279 sigma = (Pc)**(2/3.)*Tc**(1/3.)*Q*(1-Tr)**(11/9.) return sigma/1000 # convert to N/m
[docs]@sigma(ref="[6]_") def Pitzer(T, Tc, Pc, omega): r''' Notes ----- Calculates air-water surface tension using the correlation derived by [6]_ from the works of [7]_ and [8]_. Based on critical property CSP methods. .. math:: \sigma = P_c^{2/3}T_c^{1/3}\frac{1.86 + 1.18\omega}{19.05} \left[ \frac{3.75 + 0.91 \omega}{0.291 - 0.08 \omega}\right]^{2/3} (1-T_r)^{11/9} The source of this equation has not been reviewed. Internal units of presure are bar, surface tension of mN/m. Examples -------- Chlorobenzene from Poling, as compared with a % error value at 293 K: >>> f = Pitzer(633.0, 4530000.0, 0.249) >>> f(293.) 0.03458453513446387 ''' Tr = T/Tc Pc = Pc/1E5 # Convert to bar sigma = Pc**(2/3.0)*Tc**(1/3.0)*(1.86+1.18*omega)/19.05 * ( (3.75+0.91*omega)/(0.291-0.08*omega))**(2/3.0)*(1-Tr)**(11/9.0) return sigma/1000. # N/m, please
[docs]@sigma(ref='[9]_', other_params=['chemicaltype']) def Sastri_Rao(T, Tb, Tc, Pc, chemicaltype=None): r''' Other Parameters ---------------- chemicaltype : 'alcohol' or 'acid' Notes ----- Calculates air-water surface tension using the correlation derived by [9]_ based on critical property CSP methods and chemical classes. .. math:: \sigma = K P_c^xT_b^y T_c^z\left[\frac{1-T_r}{1-T_{br}}\right]^m The source of this equation has not been reviewed. Internal units of presure are bar, surface tension of mN/m. Examples -------- Chlorobenzene from Poling, as compared with a % error value at 293 K. >>> f = Sastri_Rao(404.75, 633.0, 4530000.0) >>> f(293.15) 0.03234567739694441 ''' if chemicaltype == 'alcohol': k, x, y, z, m = 2.28, 0.25, 0.175, 0, 0.8 elif chemicaltype == 'acid': k, x, y, z, m = 0.125, 0.50, -1.5, 1.85, 11/9.0 else: k, x, y, z, m = 0.158, 0.50, -1.5, 1.85, 11/9.0 Tr = T/Tc Tbr = Tb/Tc Pc = Pc/1E5 # Convert to bar sigma = k*Pc**x*Tb**y*Tc**z*((1 - Tr)/(1 - Tbr))**m return sigma/1000. # N/m
def ST_r(ST, Tc, Pc): return log(1. + ST/(Tc**(1/3.0)*Pc**(2/3.0)))
[docs]@sigma(ref="[10]_") def Zuo_Stenby(T, Tc, Pc, omega): r''' Notes ----- Calculates air-water surface tension using the reference fluids methods of [10]_: .. math:: \sigma^{(1)} = 40.520(1-T_r)^{1.287} \sigma^{(2)} = 52.095(1-T_r)^{1.21548} \sigma_r = \sigma_r^{(1)}+ \frac{\omega - \omega^{(1)}} {\omega^{(2)}-\omega^{(1)}} (\sigma_r^{(2)}-\sigma_r^{(1)}) \sigma = T_c^{1/3}P_c^{2/3}[\exp{(\sigma_r)} -1] Presently untested. Have not personally checked the sources. I strongly believe it is broken. The reference values for methane and n-octane are from the DIPPR database. Examples -------- Chlorobenzene: >>> f = Zuo_Stenby(633.0, 4530000.0, 0.249) >>> f(293.) 0.03345569011871088 ''' Tc_1, Pc_1, omega_1 = 190.56, 4599000.0/1E5, 0.012 Tc_2, Pc_2, omega_2 = 568.7, 2490000.0/1E5, 0.4 Pc = Pc/1E5 ST_1 = 40.520*(1 - T/Tc)**1.287 # Methane ST_2 = 52.095*(1 - T/Tc)**1.21548 # n-octane ST_r_1, ST_r_2 = ST_r(ST_1, Tc_1, Pc_1), ST_r(ST_2, Tc_2, Pc_2) sigma_r = ST_r_1 + (omega-omega_1)/(omega_2 - omega_1)*(ST_r_2-ST_r_1) sigma = Tc**(1/3.0)*Pc**(2/3.0)*(exp(sigma_r)-1) return sigma/1000 # N/m, please
[docs]@sigma(ref='[11]_') def Hakim_Steinberg_Stiel(T, Tc, Pc, omega, StielPolar=0): r''' Notes ----- Calculates air-water surface tension using the reference fluids methods of [11]_: .. math:: \sigma = 4.60104\times 10^{-7} P_c^{2/3}T_c^{1/3}Q_p \left(\frac{1-T_r}{0.4}\right)^m Q_p = 0.1574+0.359\omega-1.769\chi-13.69\chi^2-0.51\omega^2+1.298\omega\chi m = 1.21+0.5385\omega-14.61\chi-32.07\chi^2-1.65\omega^2+22.03\omega\chi Original equation for m and Q are used. Internal units are atm and mN/m. Examples -------- 1-butanol, as compared to value in CRC Handbook of 0.02493: >>> f = Hakim_Steinberg_Stiel(563.0, 4414000.0, 0.59, StielPolar=-0.07872) >>> f(298.15) 0.021907902575190447 ''' Q = (0.1574 + 0.359*omega - 1.769*StielPolar - 13.69*StielPolar**2 - 0.510*omega**2 + 1.298*StielPolar*omega) m = (1.210 + 0.5385*omega - 14.61*StielPolar - 32.07*StielPolar**2 - 1.656*omega**2 + 22.03*StielPolar*omega) Tr = T/Tc Pc = Pc/101325. sigma = Pc**(2/3.)*Tc**(1/3.)*Q*((1 - Tr)/0.4)**m sigma = sigma/1000. # convert to N/m return sigma
[docs]@sigma(ref="[12]_") def Miqueu(T, Tc, Vc, omega): r''' Notes ----- Calculates air-water surface tension using the methods of [1]_. .. math:: \sigma = k T_c \left( \frac{N_a}{V_c}\right)^{2/3} (4.35 + 4.14 \omega)t^{1.26}(1+0.19t^{0.5} - 0.487t) Uses Avogadro's constant and the Boltsman constant. Internal units of volume are mL/mol and mN/m. However, either a typo is in the article or author's work, or my value of k is off by 10; this is corrected nonetheless. Created with 31 normal fluids, none polar or hydrogen bonded. Has an AARD of 3.5%. Examples -------- Bromotrifluoromethane, 2.45 mN/m: >>> f = Miqueu(340.1, 0.000199, 0.1687) >>> f(300.) 0.003474099603581931 ''' Vc = Vc*1E6 t = 1.-T/Tc return k*Tc*(N_A/Vc)**(2/3.)*(4.35 + 4.14*omega)*t**1.26*(1+0.19*t**0.5 - 0.25*t)*10000
[docs]@sigma(other_params=['n_associated'], ref='[14]_') def Mersmann_Kind_surface_tension(T, Tm, Tb, Tc, Pc, n_associated=1): r''' Other Parameters ---------------- n_associated : int Number of associated molecules in a cluster (2 for alcohols, 1 otherwise), [-] Notes ----- Estimates the surface tension of organic liquid substances according to the method of [1]_: .. math:: \sigma^* = \frac{\sigma n_{ass}^{1/3}} {(kT_c)^{1/3} T_{rm}P_c^{2/3}} \sigma^* = \left(\frac{T_b - T_m}{T_m}\right)^{1/3} \left[6.25(1-T_r) + 31.3(1-T_r)^{4/3}\right] In the equation, all quantities must be in SI units. `k` is the boltzman constant. Examples -------- MTBE at STP (the actual value is 0.0181): >>> f = Mersmann_Kind_surface_tension(164.15, 328.25, 497.1, 3430000.0) >>> f(298.15) 0.016744309508833335 ''' Tr = T/Tc sigma_star = ((Tb - Tm)/Tm)**(1/3.)*(6.25*(1. - Tr) + 31.3*(1. - Tr)**(4/3.)) sigma = sigma_star*(k*Tc)**(1/3.)*(Tm/Tc)*Pc**(2/3.)*n_associated**(-1/3.) return sigma
@TDependentHandleBuilder('sigma') def surface_tension_handle(handle, CAS, MW, Tb, Tc, Pc, Vc, Zc, omega, StielPolar): add_model = handle.add_model if CAS in _Mulero_Cachadina: _, sigma0, n0, sigma1, n1, sigma2, n2, Tc, Tmin, Tmax = _Mulero_Cachadina[CAS] STREFPROP_coeffs = (Tc, sigma0, n0, sigma1, n1, sigma2, n2) add_model(REFPROP.from_args(STREFPROP_coeffs), Tmin, Tmax) if CAS in _Somayajulu_2: _, Tt, Tc, a, b, c = _Somayajulu_2[CAS] SOMAYAJULU2_coeffs = (Tc, a, b, c) Tmin = Tt; Tmax = Tc add_model(Somayajulu.from_args(SOMAYAJULU2_coeffs), Tmin, Tmax) elif CAS in _Somayajulu: _, Tt, Tc, a, b, c = _Somayajulu[CAS] SOMAYAJULU_coeffs = (Tc, a, b, c) Tmin = Tt; Tmax = Tc add_model(Somayajulu.from_args(SOMAYAJULU_coeffs), Tmin, Tmax) if CAS in VDI_saturation_dict: Ts, Ys = VDI_tabular_data(CAS, 'sigma') Tmin = Ts[0] *Ts, Tmax = Ts Ys = Ys[:-1] add_model(InterpolatedTDependentModel(Ts, Ys), Tmin, Tmax) if CAS in _Jasper_Lange: _, a, b, Tmin, Tmax= _Jasper_Lange[CAS] JASPER_coeffs = (a, b) add_model(Jasper.from_args(JASPER_coeffs)) data = (Tc, Vc, omega) if all(data): add_model(Miqueu.from_args(data), 0.0, Tc) data = (Tb, Tc, Pc) if all(data): add_model(Brock_Bird.from_args(data), 0.0, Tc) add_model(Sastri_Rao.from_args(data), 0.0, Tc) data = (Tc, Pc, omega) if all(data): add_model(Pitzer.from_args(data), 0.0, Tc) add_model(Zuo_Stenby.from_args(data), 0.0, Tc) if CAS in _VDI_PPDS_11: _, Tm, Tc, a, b, c, d, e = _VDI_PPDS_11[CAS] VDI_PPDS_coeffs = (Tc, a, b, c, d, e) add_model(DIPPR_EQ106.from_args(VDI_PPDS_coeffs))