#!/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/>.'''
from csv import reader
import os
from lib.EoS.cubic import Cubic
# Load parameters from database file
dat = {}
fp = os.path.join(os.environ["pychemqt"], "dat", "MathiasCopeman.csv")
with open(fp) as file:
my_data = reader(file)
for string in my_data:
data = string[0].split(":")
if data[0] == "CAS-nr.":
continue
cas = data[0]
c1 = float(data[1])
c2 = float(data[2])
c3 = float(data[3])
dat[cas] = (c1, c2, c3)
[docs]
class PRMathiasCopeman(Cubic):
r"""Mathias-Copeman alpha temperature dependency modification of
Peng-Robinson cubic equation of state, [1]_
.. math::
\begin{array}[t]{l}
P = \frac{RT}{V-b}-\frac{a}{V\left(V+b\right)+b\left(V-b\right)}\\
a = 0.45747\frac{R^2T_c^2}{P_c}\alpha\\
b = 0.0778\frac{RT_c}{P_c}\\
\alpha^{0.5} = 1 + c_1\left(1-Tr^{0.5}\right) +
c_2\left(1-Tr^{0.5}\right)^2 + c_3\left(1-Tr^{0.5}\right)^3\\
\end{array}
In case T > Tc it use a special alpha temperature dependence give in [3]_
.. math::
\alpha^{0.5} = 1 + c_1\left(1-Tr^{0.5}\right)
The C1, C2 and C3 parameters are those given in [2]_
Parameters
----------
alpha : int
Correlation index for alpha expresion at supercritical temperatures:
* 0 - Original
* 1 - Coquelet formulation
Examples
--------
Helmholtz energy formulation example for supplementary documentatión from
[4]_, the critical parameter are override for the valued used in paper
to get the values of test
>>> from lib.mezcla import Mezcla
>>> from lib.compuestos import Componente
>>> ch4 = Componente(2)
>>> ch4.Tc, ch4.Pc, ch4.f_acent = 190.564, 4599200, 0.011
>>> o2 = Componente(47)
>>> o2.Tc, o2.Pc, o2.f_acent = 154.581, 5042800, 0.022
>>> ar = Componente(98)
>>> ar.Tc, ar.Pc, ar.f_acent = 150.687, 4863000, -0.002
>>> zi = [0.5, 0.3, 0.2]
>>> cmpList = [ch4, o2, ar]
>>> mix = Mezcla(5, customCmp=cmpList, caudalMolar=1, fraccionMolar=zi)
>>> eq = PRMathiasCopeman(800, 34933409.8798343, mix, R=8.3144598)
>>> fir = eq._phir(800, 5000, eq.yi)
>>> delta = 5000
>>> tau = 1/800
>>> print("fir: %0.15f" % (fir["fir"]))
fir: 0.034118184296355
>>> print("fird: %0.15f" % (fir["fird"]*delta))
fird: 0.050381225002564
>>> print("firt: %0.14f" % (fir["firt"]*tau))
firt: 0.10841024634867
>>> print("firdd: %0.15f" % (fir["firdd"]*delta**2))
firdd: 0.031329489702333
>>> print("firdt: %0.15f" % (fir["firdt"]*delta*tau))
firdt: 0.098515746761245
>>> print("firtt: %0.14f" % (fir["firtt"]*tau**2))
firtt: -0.55088266208097
>>> print("firddd: %0.16f" % (fir["firddd"]*delta**3))
firddd: -0.0018875965519497
>>> print("firddt: %0.15f" % (fir["firddt"]*delta**2*tau))
firddt: -0.016659995071735
>>> print("firdtt: %0.14f" % (fir["firdtt"]*delta*tau**2))
firdtt: -0.50060412793624
>>> print("firttt: %0.13f" % (fir["firttt"]*tau**3))
firttt: 2.5911592464473
"""
__title__ = "PR-Mathias-Copeman (1983)"
__status__ = "PR-MC"
__doi__ = (
{"autor": "Mathias, P.M., Copeman, T.W.",
"title": "Extension of the Peng-Robinson Equation of State to Complex"
" Mixtures: Evaluation of the Various Forms of the Local "
"Composition Concept",
"ref": "Fluid Phase Equilibria 13 (1983) 91-108",
"doi": "10.1016/0378-3812(83)80084-3"},
{"autor": "Horstmann, S., Jabloniec, A., Krafczyk, J., Fischer, K., "
"Gmehling, J.",
"title": "PSRK group contribution equation of state: comprehensive "
"revision and extension IV, including critical constants "
"and α-function parameters for 1000 components",
"ref": "Fluid Phase Equilibria 227 (2005) 157-164",
"doi": "10.1016/j.fluid.2004.11.002"},
{"autor": "Coquelet, C., Chapoy, A., Richon, D.",
"title": "Development of a New Alpha Function for the Peng-Robinson "
"Equation of State: Comparative Study of Alpha Function "
"Models for Pure Gases (Natural Gas Components) and "
"Water-Gas Systems",
"ref": "Int. J. Thermophys. 25(1) (2004) 133-158",
"doi": "10.1023/b_ijot.0000022331.46865.2f"},
{"autor": "Bell, I.H., Jäger, A.",
"title": "Helmholtz Energy Transformations of Common Cubic Equations "
"of State for Use with Pure Fluids and Mixtures",
"ref": "J. Res. of NIST 121 (2016) 236-263",
"doi": "10.6028/jres.121.011"})
[docs]
def _cubicDefinition(self, T):
"""Definition of coefficients for generic cubic equation of state"""
# Schmidt-Wenzel factorization of terms
self.u = 1+2**0.5
self.w = 1-2**0.5
ao = []
bi = []
ai = []
C1 = []
C2 = []
C3 = []
for cmp in self.componente:
if cmp.CASNumber in dat:
c1, c2, c3 = dat[cmp.CASNumber]
else:
# Use the generalized correlation from [2]_
# Eq 17-19
c1 = 0.1316*cmp.f_acent**2 + 1.4031*cmp.f_acent + 0.3906
c2 = -1.3127*cmp.f_acent**2 + 0.3015*cmp.f_acent - 0.1213
c3 = 0.7661*cmp.f_acent + 0.3041
ao.append(0.45724*self.R**2*cmp.Tc**2/cmp.Pc)
bi.append(0.0778*self.R*cmp.Tc/cmp.Pc)
term = 1-(T/cmp.Tc)**0.5
alfa = self.kwargs.get("alpha", 0)
if T/cmp.Tc > 1 and alfa == 1:
alfa = (1 + c1*term)**2
else:
alfa = (1 + c1*term + c2*term**2 + c3*term**3)**2
ai.append(ao[-1]*alfa)
C1.append(c1)
C2.append(c2)
C3.append(c3)
self.ai = ai
self.ao = ao
self.bi = bi
self.C1 = C1
self.C2 = C2
self.C3 = C3
[docs]
def _GEOS(self, xi):
am, bm = self._mixture(None, xi, [self.ai, self.bi])
delta = 2*bm
epsilon = -bm**2
return am, bm, delta, epsilon
[docs]
def _da(self, tau, x):
"""Calculate the derivatives of α, this procedure is used for Helmholtz
energy formulation of EoS for calculation of properties, alternate alfa
formulation must define this procedure for any change of formulation
"""
C1 = self.C1
C2 = self.C2
C3 = self.C3
Tr, rhor = self._Tr()
# Eq 64-67
Di = []
Dt = []
Dtt = []
Dttt = []
for cmp in self.componente:
Di.append(1-(Tr/cmp.Tc)**0.5/tau**0.5)
Dt.append((Tr/cmp.Tc)**0.5/2/tau**1.5)
Dtt.append(-3*(Tr/cmp.Tc)**0.5/4/tau**2.5)
Dttt.append(15*(Tr/cmp.Tc)**0.5/8/tau**3.5)
# Eq 63
Bi = []
for c1, c2, c3, d in zip(C1, C2, C3, Di):
Bi.append(1+c1*d+c2*d**2+c3*d**3)
# Eq 69-71
Bt = []
Btt = []
Bttt = []
for c1, c2, c3, d, dt, dtt, dttt in zip(C1, C2, C3, Di, Dt, Dtt, Dttt):
cs = (c1, c2, c3)
bt = 0
btt = 0
bttt = 0
for n, c in enumerate(cs):
n += 1
bt += n*c*d**(n-1)*dt
btt += n*c*((n-1)*dt**2+d*dtt)*d**(n-2)
bttt += n*c*(3*(n-1)*d*dt*dtt+(n**2-3*n+2)*dt**3+d**2*dttt) * \
d**(n-3)
Bt.append(bt)
Btt.append(btt)
Bttt.append(bttt)
# Eq 73-75
dait = []
daitt = []
daittt = []
for a, B, bt, btt, bttt in zip(self.ao, Bi, Bt, Btt, Bttt):
dait.append(2*a*B*bt)
daitt.append(2*a*(B*btt+bt**2))
daittt.append(2*a*(B*bttt+3*bt*btt))
# Eq 52
uij = []
for aii in self.ai:
uiji = []
for ajj in self.ai:
uiji.append(aii*ajj)
uij.append(uiji)
# Eq 59-61
duijt = []
duijtt = []
duijttt = []
for aii, diit, diitt, diittt in zip(self.ai, dait, daitt, daittt):
duijit = []
duijitt = []
duijittt = []
for ajj, djjt, djjtt, djjttt in zip(self.ai, dait, daitt, daittt):
duijit.append(aii*djjt + ajj*diit)
duijitt.append(aii*djjtt + 2*diit*djjt + ajj*diitt)
duijittt.append(
aii*djjttt + 3*diit*djjtt + 3*diitt*djjt + ajj*diittt)
duijt.append(duijit)
duijtt.append(duijitt)
duijttt.append(duijittt)
# Eq 54-56
daijt = []
daijtt = []
daijttt = []
for uiji, duijit, duijitt, duijittt, kiji in zip(
uij, duijt, duijtt, duijttt, self.kij):
daijit = []
daijitt = []
daijittt = []
for u, ut, utt, uttt, k in zip(
uiji, duijit, duijitt, duijittt, kiji):
daijit.append((1-k)/2/u**0.5*ut)
daijitt.append((1-k)/4/u**1.5*(2*u*utt-ut**2))
daijittt.append(
(1-k)/8/u**2.5*(4*u**2*uttt - 6*u*ut*utt + 3*ut**3))
daijt.append(daijit)
daijtt.append(daijitt)
daijttt.append(daijittt)
# Eq 51
damt = 0
damtt = 0
damttt = 0
for xi, daijit, daijitt, daijittt in zip(x, daijt, daijtt, daijttt):
for xj, dat, datt, dattt in zip(x, daijit, daijitt, daijittt):
damt += xi*xj*dat
damtt += xi*xj*datt
damttt += xi*xj*dattt
# Eq 126
aij = []
for a_i in self.ai:
aiji = []
for a_j in self.ai:
aiji.append((a_i*a_j)**0.5)
aij.append(aiji)
daxi = []
for i, (xi, aiji) in enumerate(zip(x, aij)):
daxij = 0
for xj, a in zip(x, aiji):
daxij += 2*xj*a
daxi.append(daxij)
kw = {}
kw["dat"] = damt
kw["datt"] = damtt
kw["dattt"] = damttt
kw["daxi"] = daxi
return kw
if __name__ == "__main__":
from lib.mezcla import Mezcla
from lib.compuestos import Componente
ch4 = Componente(2)
ch4.Tc, ch4.Pc, ch4.f_acent = 190.564, 4599200, 0.011
o2 = Componente(47)
o2.Tc, o2.Pc, o2.f_acent = 154.581, 5042800, 0.022
ar = Componente(98)
ar.Tc, ar.Pc, ar.f_acent = 150.687, 4863000, -0.002
mix = Mezcla(5, customCmp=[ch4, o2, ar], caudalMolar=1,
fraccionMolar=[0.5, 0.3, 0.2])
eq = PRMathiasCopeman(800, 34933409.8798343, mix, R=8.3144598)
phir = eq._phir(800, 5000, eq.yi)
print(phir["fir"])
print(0.034118184296355)
# from lib.mezcla import Mezcla
# from lib.compuestos import Componente
# ch4 = Componente(2)
# ch4.Tc, ch4.Pc, ch4.f_acent = 190.564, 4599200, 0.011
# o2 = Componente(47)
# o2.Tc, o2.Pc, o2.f_acent = 154.581, 5042800, 0.022
# ar = Componente(98)
# ar.Tc, ar.Pc, ar.f_acent = 150.687, 4863000, -0.002
# mix = Mezcla(5, customCmp=[ch4, o2, ar], caudalMolar=1,
# fraccionMolar=[0.5, 0.3, 0.2])
# eq = PRMathiasCopeman(800, 34933409.8798343, mix)
# eq = PRMathiasCopeman(800, 34933409.8798343, mix)
# print(eq._phir(800, 5000, eq.yi))