#!/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/>.
Module with stream definition:
* :class:`Corriente`: Stream general class model
* :class:`PsyStream`: Stream specified as psychrometric state
"""
import logging
import os
from scipy.constants import R
from tools.qt import QtWidgets, translate
from lib.physics import R_atml
from lib import unidades, config
from lib import EoS, mEoS, gerg, iapws97, freeSteam, refProp, coolProp
from lib.solids import Solid
from lib.mezcla import Mezcla, mix_molarflow_molarfraction
from lib.psycrometry import PsychroState
from lib.thermo import ThermoWater, ThermoAdvanced, ThermoRefProp
[docs]
class Corriente(config.Entity):
"""Class to model a stream object
Parameters:
-T: temperature, Kelvin
-P: Pressure, Pa
-x: quality
-caudalMasico: mass flow in kg/s (solid component excluded)
-caudalMolar: molar flow in kmol/s (solid component excluded)
-caudalVolumetrico: volumetric flow in m3/s
-caudalUnitarioMolar: Array with molar flows for each component
-caudalUnitarioMasico: Array with mass flows for each component
-fraccionMolar: Array with molar fractions for each component
-fraccionMasica: Array with mass fractions for each component
-mezcla: instance of class Mezcla to define all mixture variables
-solido: Instance of class Solid to define all solid variables
-caudalSolido: mass flow, in kg/h for solids component, array for each
solid component
-diametroMedio: mean diameter for particules, in micrometer
-distribucion_fraccion: Array with mass fraccion of solid particle
distribution
-distribucion_diametro: Array with particle diameter of solid particle
distribution, in micrometer
-notas: Description text for stream
Aditional parameter for define a corriente with different properties than
the project config, components for debug, thermodynamic method for add per
stream configuration:
-ids: Array with index of components
-solids: Array with index of solids components
-K: Name of method for K values calculation, ej: "SRK", "Lee-Kesler"
-alfa: Name of method for alpha calculation, available only for some K
methods
-mix: Mixing rule for calculate mix properties
-H: Name of method for enthalpy calculation, ej: "SRK", "Lee-Kesler"
-Cp_ideal: Bool to choose method for ideal cp:
0 - Ideal parameters
1 - DIPPR parameters
-MEoS: Use meos equation if is available
-iapws: Use iapws97 standard for water
-GERG: Use GERG-2008 equation if is available
-freesteam: Use freesteam external library for water
-coolProp: Use coolProp external library if is available
-refprop: Use refProp external library if is available
"""
kwargs = {"T": 0.0,
"P": 0.0,
"x": None,
"caudalMasico": 0.0,
"caudalVolumetrico": 0.0,
"caudalMolar": 0.0,
"caudalUnitarioMolar": [],
"caudalUnitarioMasico": [],
"fraccionMolar": [],
"fraccionMasica": [],
"mezcla": None,
"solido": None,
"caudalSolido": [],
"diametroMedio": 0.0,
"distribucion_fraccion": [],
"distribucion_diametro": [],
"ids": [],
"solids": None,
"K": "",
"alfa": "",
"mix": "",
"H": "",
"Cp_ideal": None,
"MEoS": None,
"iapws": None,
"GERG": None,
"freesteam": None,
"coolProp": None,
"refprop": None}
status = 0
msg = translate("Corriente", "Unknown variables")
kwargs_forbidden = ["entrada", "mezcla", "solido"]
solido = None
[docs]
def __init__(self, **kwargs):
self.kwargs = Corriente.kwargs.copy()
self.__call__(**kwargs)
def __call__(self, **kwargs):
# Clean input parameters to get only the defined in the last run
if kwargs.get("mezcla", None):
kwargs.update(kwargs["mezcla"].kwargs)
if kwargs.get("solido", None):
kwargs.update(kwargs["solido"].kwargs)
if kwargs.get("caudalUnitarioMasico", []):
self.kwargs["caudalUnitarioMolar"] = []
self.kwargs["fraccionMolar"] = []
self.kwargs["fraccionMasica"] = []
self.kwargs["caudalMasico"] = None
self.kwargs["caudalVolumetrico"] = None
self.kwargs["caudalMolar"] = None
elif kwargs.get("caudalUnitarioMolar", []):
self.kwargs["caudalUnitarioMasico"] = []
self.kwargs["fraccionMolar"] = []
self.kwargs["fraccionMasica"] = []
self.kwargs["caudalMasico"] = None
self.kwargs["caudalVolumetrico"] = None
self.kwargs["caudalMolar"] = None
elif kwargs.get("caudalMasico", None) and \
kwargs.get("fraccionMolar", []):
self.kwargs["caudalUnitarioMasico"] = []
self.kwargs["caudalUnitarioMolar"] = []
self.kwargs["fraccionMasica"] = []
self.kwargs["caudalVolumetrico"] = None
self.kwargs["caudalMolar"] = None
elif kwargs.get("caudalMasico", None) and \
kwargs.get("fraccionMasica", []):
self.kwargs["caudalUnitarioMasico"] = []
self.kwargs["caudalUnitarioMolar"] = []
self.kwargs["fraccionMolar"] = []
self.kwargs["caudalVolumetrico"] = None
self.kwargs["caudalMolar"] = None
elif kwargs.get("caudalMasico", None):
self.kwargs["caudalUnitarioMasico"] = []
self.kwargs["caudalUnitarioMolar"] = []
self.kwargs["caudalVolumetrico"] = None
self.kwargs["caudalMolar"] = None
elif kwargs.get("caudalMolar", None) and \
kwargs.get("fraccionMolar", []):
self.kwargs["caudalUnitarioMasico"] = []
self.kwargs["caudalUnitarioMolar"] = []
self.kwargs["fraccionMasica"] = []
self.kwargs["caudalMasico"] = None
self.kwargs["caudalVolumetrico"] = None
elif kwargs.get("caudalMolar", None) and \
kwargs.get("fraccionMasica", []):
self.kwargs["caudalUnitarioMasico"] = []
self.kwargs["caudalUnitarioMolar"] = []
self.kwargs["fraccionMolar"] = []
self.kwargs["caudalMasico"] = None
self.kwargs["caudalVolumetrico"] = None
elif kwargs.get("caudalMolar", None):
self.kwargs["caudalUnitarioMasico"] = []
self.kwargs["caudalUnitarioMolar"] = []
self.kwargs["caudalMasico"] = None
self.kwargs["caudalVolumetrico"] = None
elif kwargs.get("caudalVolumetrico", None) and \
kwargs.get("fraccionMolar", []):
self.kwargs["caudalUnitarioMasico"] = []
self.kwargs["caudalUnitarioMolar"] = []
self.kwargs["fraccionMasica"] = []
self.kwargs["caudalMasico"] = None
elif kwargs.get("caudalVolumetrico") and \
kwargs.get("fraccionMasica", []):
self.kwargs["caudalUnitarioMasico"] = []
self.kwargs["caudalUnitarioMolar"] = []
self.kwargs["fraccionMolar"] = []
self.kwargs["caudalMasico"] = None
elif kwargs.get("caudalVolumetrico", None):
self.kwargs["caudalUnitarioMasico"] = []
self.kwargs["caudalUnitarioMolar"] = []
self.kwargs["caudalMolar"] = []
self.kwargs["caudalMasico"] = None
elif kwargs.get("fraccionMasica", []):
self.kwargs["caudalUnitarioMasico"] = []
self.kwargs["caudalUnitarioMolar"] = []
self.kwargs["fraccionMolar"] = []
elif kwargs.get("fraccionMolar", []):
self.kwargs["caudalUnitarioMasico"] = []
self.kwargs["caudalUnitarioMolar"] = []
self.kwargs["fraccionMasica"] = []
elif kwargs.get("x", None) and self.kwargs["T"] and self.kwargs["P"]:
self.kwargs["T"] = 0.0
elif kwargs.get("T", 0.0) and self.kwargs["x"] and self.kwargs["P"]:
self.kwargs["P"] = 0.0
elif kwargs.get("P", 0.0) and self.kwargs["T"] and self.kwargs["x"]:
self.kwargs["x"] = None
self.kwargs.update(kwargs)
for key, value in list(self.kwargs.items()):
if value:
self._bool = True
break
logging.info('Calculate STREAM')
kw_new = {}
for key, value in list(kwargs.items()):
if self.__class__.kwargs[key] != value:
kw_new[key] = value
logging.debug('kwarg; %s' % kw_new)
if self.calculable:
statusmsg = (
translate("Corriente", "Underspecified"),
translate("Corriente", "Solved"),
translate("Corriente", "Ignored"),
translate("Corriente", "Warning"),
translate("Corriente", "Calculating..."),
translate("Corriente", "Error"))
status = statusmsg[self.status]
logging.debug('%s %s' % (status, self.msg))
QtWidgets.QApplication.processEvents()
self.status = 1
self.calculo()
self.msg = ""
elif self.tipoFlujo:
if self.kwargs["mezcla"]:
self.mezcla = self.kwargs["mezcla"]
else:
self.mezcla = Mezcla(self.tipoFlujo, **self.kwargs)
elif self.tipoSolido:
if self.kwargs["solido"]:
self.solido = self.kwargs["solido"]
else:
self.solido = Solid(**self.kwargs)
if self.solido:
self.solido.RhoS(self.kwargs["T"])
@property
def calculable(self):
# Thermo definition
self.tipoTermodinamica = ""
if self.kwargs["T"] and self.kwargs["P"]:
self.tipoTermodinamica = "TP"
elif self.kwargs["T"] and self.kwargs["x"]:
self.tipoTermodinamica = "Tx"
elif self.kwargs["P"] and self.kwargs["x"]:
self.tipoTermodinamica = "Px"
# Mix definition
self.tipoFlujo = 0
if self.kwargs["caudalUnitarioMasico"]:
self.tipoFlujo = 1
elif self.kwargs["caudalUnitarioMolar"]:
self.tipoFlujo = 2
elif self.kwargs["caudalMasico"] and self.kwargs["fraccionMolar"]:
self.tipoFlujo = 3
elif self.kwargs["caudalMasico"] and self.kwargs["fraccionMasica"]:
self.tipoFlujo = 4
elif self.kwargs["caudalMolar"] and self.kwargs["fraccionMolar"]:
self.tipoFlujo = 5
elif self.kwargs["caudalMolar"] and self.kwargs["fraccionMasica"]:
self.tipoFlujo = 6
elif self.kwargs["caudalVolumetrico"] and self.kwargs["fraccionMolar"]:
self.kwargs["caudalMolar"] = 1
self.tipoFlujo = 5
elif self.kwargs["caudalVolumetrico"] and \
self.kwargs["fraccionMasica"]:
self.kwargs["caudalMolar"] = 1
self.tipoFlujo = 6
elif self.kwargs["mezcla"]:
self.tipoFlujo = 7
# Solid definition
self.tipoSolido = 0
if sum(self.kwargs["caudalSolido"]) > 0:
if self.kwargs["distribucion_fraccion"] and \
self.kwargs["distribucion_diametro"]:
self.tipoSolido = 2
elif self.kwargs["diametroMedio"]:
self.tipoSolido = 1
if self.kwargs["solido"]:
self.tipoSolido = self.kwargs["solido"].status
return self.tipoTermodinamica and self.tipoFlujo
[docs]
def calculo(self):
Config = config.getMainWindowConfig()
if self.kwargs["mezcla"]:
self.mezcla = self.kwargs["mezcla"]
else:
self.mezcla = Mezcla(self.tipoFlujo, **self.kwargs)
self.ids = self.mezcla.ids
self.componente = self.mezcla.componente
self.fraccion = self.mezcla.fraccion
self.caudalmasico = self.mezcla.caudalmasico
self.caudalmolar = self.mezcla.caudalmolar
self.fraccion_masica = self.mezcla.fraccion_masica
self.caudalunitariomasico = self.mezcla.caudalunitariomasico
self.caudalunitariomolar = self.mezcla.caudalunitariomolar
T = unidades.Temperature(self.kwargs.get("T", None))
P = unidades.Pressure(self.kwargs.get("P", None))
x = self.kwargs.get("x", None)
self._method()
setData = True
if self._thermo == "freesteam":
compuesto = freeSteam.Freesteam(**self.kwargs)
elif self._thermo == "iapws":
compuesto = iapws97.IAPWS97(**self.kwargs)
elif self._thermo == "refprop":
if not self.kwargs["ids"]:
self.kwargs["ids"] = self.ids
# Avoid overwrite refprop H parameter
kwargs = self.kwargs.copy()
del kwargs["H"]
compuesto = refProp.RefProp(**kwargs)
elif self._thermo == "gerg":
ids = []
for id in self.ids:
ids.append(gerg.id_GERG.index(id))
kwargs = self.kwargs
kwargs["mezcla"] = self.mezcla
compuesto = gerg.GERG(
componente=ids, fraccion=self.fraccion, **kwargs)
elif self._thermo == "coolprop":
if not self.kwargs["ids"]:
self.kwargs["ids"] = self.ids
compuesto = coolProp.CoolProp(**self.kwargs)
elif self._thermo == "meos":
class_ = mEoS.__all__[mEoS.id_mEoS.index(self.ids[0])]
if self.tipoTermodinamica == "TP":
compuesto = class_(T=T, P=P)
elif self.tipoTermodinamica == "Tx":
compuesto = class_(T=T, x=x)
elif self.tipoTermodinamica == "Px":
compuesto = class_(P=P, x=x)
elif self._thermo == "eos":
if self.kwargs["K"]:
index = EoS.K_name.index(self.kwargs["K"])
K = EoS.K[index]
else:
K = EoS.K[Config.getint("Thermo", "K")]
if self.kwargs["H"]:
index = EoS.H_name.index(self.kwargs["H"])
H = EoS.H[index]
else:
H = EoS.H[Config.getint("Thermo", "H")]
setData = False
self.M = unidades.Dimensionless(self.mezcla.M)
self.Tc = self.mezcla.Tc
self.Pc = self.mezcla.Pc
self.SG = unidades.Dimensionless(self.mezcla.SG)
if self.tipoTermodinamica == "TP":
self.T = unidades.Temperature(T)
self.P = unidades.Pressure(P)
eos = K(self.T, self.P, self.mezcla)
self.eos = eos
self.x = unidades.Dimensionless(eos.x)
else:
self.x = unidades.Dimensionless(x)
# self.mezcla.recallZeros(eos.xi)
# self.mezcla.recallZeros(eos.yi)
# self.mezcla.recallZeros(eos.Ki, 1.)
if 0. < self.x < 1.:
self.Liquido = Mezcla(
tipo=5, ids=self.mezcla.ids, fraccionMolar=eos.xi,
caudalMolar=self.caudalmolar*(1-self.x))
self.Gas = Mezcla(
tipo=5, ids=self.mezcla.ids, fraccionMolar=eos.yi,
caudalMolar=self.caudalmolar*self.x)
elif self.x <= 0:
self.Liquido = self.mezcla
self.Gas = Mezcla()
else:
self.Liquido = Mezcla()
self.Gas = self.mezcla
# self.Gas.Z = unidades.Dimensionless(eos.Zg)
# self.Liquido.Z = unidades.Dimensionless(eos.Zl)
# if H == K:
# eosH = eos
# else:
# eosH = H(self.T, self.P.atm, self.mezcla)
# self.H_exc = eosH.H_exc
self.H_exc = (0, 0)
self.Liquido.Q = unidades.VolFlow(0)
self.Gas.Q = unidades.VolFlow(0)
self.Liquido.h = unidades.Power(0)
self.Gas.h = unidades.Power(0)
if self.x < 1:
# There is liquid phase
if Config.getboolean("Transport", "RhoLEoS") and eos.rhoL:
self.Liquido.rho = eos.rhoL
self.Liquido.Z = unidades.Dimensionless(float(eos.Zl))
else:
self.Liquido.rho = self.Liquido.RhoL(T, P)
Z = self.Liquido.rho*R*T/P
self.Liquido.Z = unidades.Dimensionless(Z)
# Hl = (self.Liquido._Ho(self.T).Jg-self.Liquido.Hv_DIPPR(self.T).Jg)*self.Liquido.caudalmasico.gh
Hl = 0
self.Liquido.h = unidades.Power(Hl-R*self.T/self.M*self.H_exc[1]*(1-self.x)*self.Liquido.caudalmasico.gh, "Jh")
self.Liquido.cp = self.Liquido.Cp_Liquido(T)
self.Liquido.Q = unidades.VolFlow(self.Liquido.caudalmasico/self.Liquido.rho)
# Transport properties
self.Liquido.mu = self.Liquido.Mu_Liquido(T, P)
k = self.Liquido.ThCond_Liquido(T, P, self.Liquido.rho)
self.Liquido.k = k
self.Liquido.sigma = self.Liquido.Tension(T)
self.Liquido.Prandt = self.Liquido.cp*self.Liquido.mu/self.Liquido.k
if self.x > 0:
# There is gas phase
if eos.rhoG:
self.Gas.Z = unidades.Dimensionless(float(eos.Zg))
self.Gas.rho = eos.rhoG
else:
self.Gas.rho = self.Liquido.RhoL(T, P)
Z = self.Gas.rho*R*T/P
self.Gas.Z = unidades.Dimensionless(Z)
self.Gas.rho = unidades.Density(self.P/self.Gas.Z/R/self.T*self.M, "gl")
self.Gas.rhoSd = unidades.Density(1./self.Gas.Z/R_atml/298.15*self.M, "gl")
Hg = self.Gas._Ho(self.T).Jg*self.Gas.caudalmasico.gh
self.Gas.h = unidades.Power(Hg-R*self.T/self.M*self.H_exc[0]*self.x*self.Gas.caudalmasico.gh, "Jh")
self.Gas.cp = self.Gas.Cp_Gas(T, self.P)
self.Gas.mu = self.Gas.Mu_Gas(T, self.P, self.Gas.rho)
self.Gas.k = self.Gas.ThCond_Gas(T, self.P, self.Gas.rho)
self.Gas.Q = unidades.VolFlow(self.Gas.caudalmasico/self.Gas.rho)
self.Gas.Prandt = self.Gas.cp*self.Gas.mu/self.Gas.k
self.Q = unidades.VolFlow(self.Liquido.Q+self.Gas.Q)
self.h = unidades.Power(self.Liquido.h+self.Gas.h)
self.Molaridad = [caudal/self.Q.m3h for caudal in self.caudalunitariomolar]
# print(self.Liquido.mu, self.Liquido.k)
# self.Liquido.fraccion = self.Liquido.recallZeros(self.Liquido.fraccion)
# print(self.Liquido.fraccion)
# self.Liquido.recallZeros(eos.yi)
# self.Liquido.recallZeros(eos.Ki, 1.)
# TODO:
self.cp_cv = 0.5
self.cp_cv_ideal = 0.5
self.s = 0
self.rho = 0
if setData:
# Asignación de valores comun
self.cmp = compuesto
self.T = compuesto.T
self.P = compuesto.P
self.x = compuesto.x
self.M = unidades.Dimensionless(compuesto.M)
self.Tc = compuesto.Tc
self.Pc = compuesto.Pc
self.h = unidades.Power(compuesto.h*self.caudalmasico)
self.s = unidades.Entropy(compuesto.s*self.caudalmasico)
self.rho = compuesto.rho
self.Q = unidades.VolFlow(compuesto.v*self.caudalmasico)
# harcoded thermo derived global properties in corriente for avoid
# losing data
if self._thermo != "eos":
compuesto._fillCorriente(self)
# if self.__class__!=mEoS.H2O:
# agua=mEoS.H2O(T=self.T, P=self.P.MPa)
# self.SG=unidades.Dimensionless(self.rho/agua.rho)
# else:
self.SG = unidades.Dimensionless(1.)
self.Liquido = compuesto.Liquido
self.Gas = compuesto.Gas
# if self.x<1: #Fase líquida
# self.Liquido=compuesto.Liquido
# if self.x>0: #Fase gaseosa
# self.Gas=compuesto
# elif 0<self.x<1: #Ambas fases
# self.Liquido=compuesto.Liquido
# self.Gas=compuesto.Gas
# self.QLiquido=self.Q*(1-self.x)
# elif self.x==1: #Fase gaseosa
# self.Gas=compuesto
# self.Liquido=None
# self.QLiquido=unidades.VolFlow(0)
# self.Gas.rhoSd=unidades.Density(1./R_atml/298.15*self.M, "gl")
if self.x > 0:
self.Gas.Q = unidades.VolFlow(self.Q*self.x)
self.Gas.caudalmasico = unidades.MassFlow(self.caudalmasico*self.x)
self.Gas.caudalmolar = unidades.MolarFlow(self.caudalmolar*self.x)
kw = mix_molarflow_molarfraction(
self.Gas.caudalmolar, self.Gas.fraccion, self.componente)
self.Gas.caudalunitariomasico = [
unidades.MassFlow(f) for f in kw["unitMassFlow"]]
self.Gas.caudalunitariomolar = [
unidades.MolarFlow(f) for f in kw["unitMolarFlow"]]
self.Gas.ids = self.ids
if self.x < 1:
self.Liquido.Q = unidades.VolFlow(self.Q*(1-self.x))
self.Liquido.caudalmasico = unidades.MassFlow(self.caudalmasico*(1-self.x))
self.Liquido.caudalmolar = unidades.MolarFlow(self.caudalmolar*(1-self.x))
kw = mix_molarflow_molarfraction(
self.Liquido.caudalmolar, self.Liquido.fraccion, self.componente)
self.Liquido.caudalunitariomasico = [
unidades.MassFlow(f) for f in kw["unitMassFlow"]]
self.Liquido.caudalunitariomolar = [
unidades.MolarFlow(f) for f in kw["unitMolarFlow"]]
self.Liquido.sigma = compuesto.sigma
self.Liquido.ids = self.ids
if Config.get("Components", "Solids"):
if self.kwargs["solido"]:
self.solido = self.kwargs["solido"]
else:
self.solido = Solid(**self.kwargs)
if self.solido.status:
self.solido.RhoS(T)
else:
self.solido = None
if self.kwargs["caudalVolumetrico"]:
self.kwargs["caudalMolar"] *= self.kwargs["caudalVolumetrico"]/self.Q
Q = self.kwargs["caudalVolumetrico"]
self.kwargs["caudalVolumetrico"] = None
self.calculo()
self.kwargs["caudalVolumetrico"] = Q
self.kwargs["caudalMolar"] = None
[docs]
def _method(self):
"""Find the thermodynamic method to use
Define internal variables to know the definition:
_thermo: Method of definition, one of this values:
eos, iapws, freesteam, meos, coolprop, refprop, gerg
_dependence: In advanced method with external dependencias define
the neccesary dependences to calculate
"""
Config = config.getMainWindowConfig()
# MEoS availability,
if self.kwargs["MEoS"] is not None:
_meos = self.kwargs["MEoS"]
else:
_meos = Config.getboolean("Thermo", "MEoS")
mEoS_available = self.ids[0] in mEoS.id_mEoS
MEoS = _meos and len(self.ids) == 1 and mEoS_available
# iapws availability
if self.kwargs["iapws"] is not None:
_iapws = self.kwargs["iapws"]
else:
_iapws = Config.getboolean("Thermo", "iapws")
IAPWS = _iapws and len(self.ids) == 1 and self.ids[0] == 62
# freesteam availability
if self.kwargs["freesteam"] is not None:
_freesteam = self.kwargs["freesteam"]
else:
_freesteam = Config.getboolean("Thermo", "freesteam")
FREESTEAM = _freesteam and len(self.ids) == 1 and \
self.ids[0] == 62 and os.environ["freesteam"]
COOLPROP_available = True
GERG_available = True
REFPROP_available = True
for id in self.ids:
if id not in coolProp.all__:
COOLPROP_available = False
if id not in refProp.all__:
REFPROP_available = False
if id not in gerg.id_GERG:
GERG_available = False
# coolprop availability
if self.kwargs["coolProp"] is not None:
_coolprop = self.kwargs["coolProp"]
else:
_coolprop = Config.getboolean("Thermo", "coolprop")
COOLPROP = _coolprop and os.environ["CoolProp"] and COOLPROP_available
# refprop availability
if self.kwargs["refprop"] is not None:
_refprop = self.kwargs["refprop"]
else:
_refprop = Config.getboolean("Thermo", "refprop")
REFPROP = _refprop and os.environ["refprop"] and REFPROP_available
# GERG availability
if self.kwargs["GERG"] is not None:
_gerg = self.kwargs["GERG"]
else:
_gerg = Config.getboolean("Thermo", "GERG")
GERG = _gerg and GERG_available
# Final selection
if IAPWS and FREESTEAM:
self._thermo = "freesteam"
self._dependence = "freesteam"
elif IAPWS:
self._thermo = "iapws"
elif _meos and REFPROP:
self._thermo = "refprop"
self._dependence = "refprop"
elif _meos and COOLPROP:
self._thermo = "coolprop"
self._dependence = "CoolProp"
elif MEoS and GERG:
self._thermo = "gerg"
elif MEoS and len(self.ids)==1:
self._thermo = "meos"
else:
self._thermo = "eos"
[docs]
def setSolid(self, solid):
self.solido = solid
@property
def psystream(self):
xw = self.fraccion_masica[self.ids.index(62)]
xa = self.fraccion_masica[self.ids.index(475)]
psystream = PsyStream(caudalMasico=self.caudalMasico, P=self.P,
tdb=self.T, w=xw/xa)
return psystream
[docs]
def clone(self, **kwargs):
"""Create a new stream instance with change only kwags new values"""
old_kwargs = self.kwargs.copy()
if "split" in kwargs:
split = kwargs["split"]
del kwargs["split"]
if self.kwargs["caudalUnitarioMasico"]:
kwargs["caudalUnitarioMasico"] = []
for caudal in self.kwargs["caudalUnitarioMasico"]:
kwargs["caudalUnitarioMasico"].append(split*caudal)
if self.kwargs["caudalUnitarioMolar"]:
kwargs["caudalUnitarioMolar"] = []
for caudal in self.kwargs["caudalUnitarioMolar"]:
kwargs["caudalUnitarioMolar"].append(split*caudal)
if self.kwargs["caudalMasico"]:
kwargs["caudalMasico"] = split*self.kwargs["caudalMasico"]
if self.kwargs["caudalMolar"]:
kwargs["caudalMolar"] = split*self.kwargs["caudalMolar"]
if "x" in kwargs:
del old_kwargs["T"]
if "mezcla" in kwargs:
old_kwargs.update(kwargs["mezcla"].kwargs)
del kwargs["mezcla"]
old_kwargs.update(kwargs)
return Corriente(**old_kwargs)
def __repr__(self):
"""String representation of any instance"""
if self.status:
return "Corriente at %0.2fK and %0.2fatm" % (self.T, self.P.atm)
else:
return "%s empty" % (self.__class__)
[docs]
def txt(self):
txt = str(self.notasPlain)+os.linesep+os.linesep
txt += "#---------------"
txt += translate("Corriente", "Input properties")
txt += "-----------------#"+os.linesep
for key, value in list(self.kwargs.items()):
if value:
txt += key+": "+str(value)+os.linesep
if self.calculable:
txt += os.linesep + "#---------------"
txt += translate("Corriente", "Global stream")
txt += "-------------------#"+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Temperature"),
self.T.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Pressure"),
self.P.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Vapor Fraction"),
self.x.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Molar Flow"),
self.caudalmasico.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Mass Flow"),
self.caudalmolar.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Volumetric Flow"),
self.Q.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Enthalpy"),
self.h.str)+os.linesep
txt += "%-25s\t%s" % ("Tc", self.Tc.str)+os.linesep
txt += "%-25s\t%s" % ("Pc", self.Pc.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "SG, water=1"),
self.SG.str)+os.linesep
txt += os.linesep+"%-25s\t%s" % (
translate("Corriente", "Molecular weight"),
self.M.str)+os.linesep
txt += "#"+translate("Corriente", "Molar Composition")
txt += os.linesep
for cmp, xi in zip(self.componente, self.fraccion):
txt += "%-25s\t %0.4f" % (cmp.name, xi)+os.linesep
if self.x > 0:
txt += os.linesep+"#---------------"
txt += translate("Corriente", "Vapor Only")
txt += "--------------------#"+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Molar Flow"),
self.Gas.caudalmasico.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Mass Flow"),
self.Gas.caudalmolar.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Volumetric Flow"),
self.Gas.Q.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Molecular weight"),
self.Gas.M.str)+os.linesep
txt += os.linesep+"#"
txt += translate("Corriente", "Molar Composition")
txt += os.linesep
for cmp, xi in zip(self.componente, self.Gas.fraccion):
txt += "%-25s\t %0.4f" % (cmp.name, xi)+os.linesep
txt += os.linesep+"%-25s\t%s" % (
translate("Corriente", "Density"),
self.Gas.rho.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Compresibility"),
self.Gas.Z.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Enthalpy"),
self.Gas.h.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Heat Capacity"),
self.Gas.cp.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Viscosity"),
self.Gas.mu.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Thermal conductivity"),
self.Gas.k.str)+os.linesep
if self.x < 1:
txt += os.linesep+"#---------------"
txt += translate("Corriente", "Liquid Only")
txt += "-------------------#"+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Molar Flow"),
self.Liquido.caudalmasico.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Mass Flow"),
self.Liquido.caudalmolar.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Volumetric Flow"),
self.Liquido.Q.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Molecular weight"),
self.Liquido.M.str)+os.linesep
txt += os.linesep+"#"
txt += translate("Corriente", "Molar Composition")
txt += os.linesep
for cmp, xi in zip(self.componente, self.Liquido.fraccion):
txt += "%-25s\t %0.4f" % (cmp.name, xi)+os.linesep
txt += os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Density"),
self.Liquido.rho.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Compresibility"),
self.Liquido.Z.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Enthalpy"),
self.Liquido.h.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Heat Capacity"),
self.Liquido.cp.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Viscosity"),
self.Liquido.mu.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Thermal Conductivity"),
self.Liquido.k.str)+os.linesep
txt += "%-25s\t%s" % (
translate("Corriente", "Surface Tension"),
self.Liquido.sigma.str)+os.linesep
else:
txt += os.linesep+"#---------------"
txt += translate("Corriente", "No Fluid Stream")
txt += "-------------------#"+os.linesep
if self.solido.status:
txt += os.linesep+"#---------------"
txt += translate("Corriente", "Solid")
txt += "-------------------#"+os.linesep
for cmp, G in zip(self.solido.componente, self.solido.caudalUnitario):
txt += "%-25s\t%s" % (cmp.name, G.str)+os.linesep
txt += os.linesep
txt += "%-25s\t%s" % (translate("Corriente", "Density"),
self.solido.rho.str)+os.linesep
txt += "%-25s\t%s" % (translate("Corriente", "Mean Diameter"),
self.solido.diametro_medio.str)+os.linesep
if self.solido.diametros:
txt += os.linesep + "#"
txt += translate("Corriente", "Particle Size Distribution")
txt += os.linesep
txt += "%s, %s \t%s" % (translate("Corriente", "Diameter"), unidades.Length.text("ParticleDiameter"), translate("Corriente", "Fraction"))+os.linesep
for di, xi in zip(self.solido.diametros, self.solido.fracciones):
txt += "%10.4f\t%0.4f\t" % (di.config("ParticleDiameter"),
xi)+os.linesep
# Add advanced properties to report
if self.calculable and self._thermo != "eos":
doc = self._doc()
if 0 < self.x < 1:
param = "%-40s\t%-20s\t%-20s"
else:
param = "%-40s\t%s"
if self.x == 0:
txtphases = "%60s" % translate("Corriente", "Liquid")+os.linesep
phases = [self.Liquido]
elif self.x == 1:
txtphases = "%60s" % translate("Corriente", "Gas")+os.linesep
phases = [self.Gas]
else:
txtphases = "%60s\t%20s" % (translate("Corriente", "Liquid"), translate("Corriente", "Gas"))+os.linesep
phases = [self.Liquido, self.Gas]
complejos = ""
data = self.cmp.properties()
for propiedad, key, unit in data:
if key == "sigma":
if self.x < 1:
complejos += "%-40s\t%s" % (propiedad, self.Liquido.sigma.str)
complejos += os.linesep
elif key in ["f", "fi"]:
complejos += propiedad + os.linesep
for i, cmp in enumerate(self.componente):
values = [" " + cmp.name]
for phase in phases:
values.append(phase.__getattribute__(key)[i].str)
complejos += param % tuple(values) + os.linesep
elif key in ["K", "csat", "dpdt_sat", "cv2p", "chempot"]:
complejos += propiedad + os.linesep
for i, cmp in enumerate(self.componente):
values = [" " + cmp.name]
values.append(self.__getattribute__(key)[i].str)
complejos += "%-40s\t%s" % tuple(values)
complejos += os.linesep
elif key in self.Gas.__dict__ or key in self.Liquido.__dict__:
values = [propiedad]
for phase in phases:
values.append(phase.__getattribute__(key).str)
complejos += param % tuple(values) + os.linesep
else:
complejos += "%-40s\t%s" % (propiedad, self.__getattribute__(key).str)
complejos += os.linesep
txt += doc + os.linesep + txtphases + complejos
return txt
[docs]
def _doc(self):
"""Return a text repr of class with all properties"""
if self._thermo == "meos":
title = translate("Corriente", "Advanced MEoS properties")
doc_param = [self.cmp._constants["__doi__"]]
else:
title = translate("Corriente", "Advanced thermo properties")
doc_param = self.cmp.__doi__
doc = ""
for doi in doc_param:
doc += doi["autor"] + "; " + doi["title"] + "; " + doi["ref"]
doc += os.linesep
txt = os.linesep + os.linesep + "#---------------"
txt += title + "-------------------#" + os.linesep
txt += doc
return txt
[docs]
@classmethod
def propertiesNames(cls):
list = [
(translate("Corriente", "Temperature"), "T", unidades.Temperature),
(translate("Corriente", "Pressure"), "P", unidades.Pressure),
(translate("Corriente", "Vapor Fraction"), "x", unidades.Dimensionless),
(translate("Corriente", "Molar Flow"), "caudalmolar", unidades.MolarFlow),
(translate("Corriente", "Mass Flow"), "caudalmasico", unidades.MassFlow),
(translate("Corriente", "Volumetric Flow"), "Q", unidades.VolFlow),
(translate("Corriente", "Enthalpy"), "h", unidades.Enthalpy),
(translate("Corriente", "Critic Temperature"), "Tc", unidades.Temperature),
(translate("Corriente", "Critic Pressure"), "Pc", unidades.Pressure),
(translate("Corriente", "SG, water=1"), "SG", unidades.Dimensionless),
(translate("Corriente", "Molecular weight"), "M", unidades.Dimensionless),
(translate("Corriente", "Molar Composition"), "fraccion", unidades.Dimensionless),
(translate("Corriente", "Mass Composition"), "fraccion_masica", unidades.Dimensionless),
(translate("Corriente", "Molar Component Flow"), "caudalunitariomolar", unidades.MolarFlow),
(translate("Corriente", "Mass Component Flow"), "caudalunitariomasico", unidades.MassFlow),
(translate("Corriente", "Notes"), "notasPlain", str)]
return list
[docs]
def propertiesListTitle(self, index):
"""Define los titulos para los popup de listas"""
lista = [comp.name for comp in self.componente]
return lista
[docs]
def writeToJSON(self, data):
"""Read entity from file"""
config.Entity.writeToJSON(self, data)
# Solid state, can be defined without a thermo status
solid = {}
if self.solido is not None:
self.solido.writeStatetoJSON(solid)
data["solid"] = solid
[docs]
def writeStatetoJSON(self, state):
state["thermo"] = self._thermo
state["bool"] = self._bool
state["thermoType"] = self.tipoTermodinamica
state["T"] = self.T
state["P"] = self.P
state["x"] = self.x
state["M"] = self.M
state["Tc"] = self.Tc
state["Pc"] = self.Pc
state["h"] = self.h
state["s"] = self.s
state["rho"] = self.rho
state["Q"] = self.Q
state["SG"] = self.SG
if self._thermo != "eos":
self.cmp._writeGlobalState(self, state)
state["fluxType"] = self.tipoFlujo
self.mezcla.writeStatetoJSON(state)
self.Liquido.writeStatetoJSON(state, "liquid")
self.Gas.writeStatetoJSON(state, "gas")
if state["liquid"]:
state["liquid"]["sigma"] = self.Liquido.sigma
if self._thermo == "meos":
state["meos_eq"] = self.cmp.kwargs["eq"]
[docs]
def readFromJSON(self, data):
"""Read entity from file"""
config.Entity.readFromJSON(self, data)
# Read solid
self.solido = Solid()
self.solido.readStatefromJSON(data["solid"])
[docs]
def readStatefromJSON(self, state):
self._thermo = state["thermo"]
self._bool = state["bool"]
self.tipoTermodinamica = state["thermoType"]
self.T = unidades.Temperature(state["T"])
self.P = unidades.Pressure(state["P"])
self.x = unidades.Dimensionless(state["x"])
self.M = unidades.Dimensionless(state["M"])
self.Tc = unidades.Temperature(state["Tc"])
self.Pc = unidades.Pressure(state["Pc"])
self.h = unidades.Power(state["h"])
self.s = unidades.Entropy(state["s"])
self.rho = unidades.Density(state["rho"])
self.Q = unidades.VolFlow(state["Q"])
self.SG = unidades.Dimensionless(state["SG"])
self.tipoFlujo = state["fluxType"]
self.mezcla = Mezcla()
self.mezcla.readStatefromJSON(state["mezcla"])
self.ids = self.mezcla.ids
self.componente = self.mezcla.componente
self.fraccion = self.mezcla.fraccion
self.caudalmasico = self.mezcla.caudalmasico
self.caudalmolar = self.mezcla.caudalmolar
self.fraccion_masica = self.mezcla.fraccion_masica
self.caudalunitariomasico = self.mezcla.caudalunitariomasico
self.caudalunitariomolar = self.mezcla.caudalunitariomolar
# Define the advanced thermo component if is necessary
if self._thermo == "freesteam":
self.cmp = freeSteam.Freesteam()
elif self._thermo == "iapws":
self.cmp = iapws97.IAPWS97()
elif self._thermo == "refprop":
self.cmp = refProp.RefProp(ids=self.ids)
elif self._thermo == "coolprop":
self.cmp = coolProp.CoolProp(ids=self.ids)
elif self._thermo == "meos":
eq = state["meos_eq"]
self.cmp = mEoS.__all__[mEoS.id_mEoS.index(self.ids[0])](eq=eq)
# Load advanced properties from global phase
if self._thermo != "eos":
self.cmp._readGlobalState(self, state)
# Load state for phases
if self._thermo in ["iapws", "freesteam"]:
self.Liquido = ThermoWater()
self.Gas = ThermoWater()
elif self._thermo in ["coolprop", "meos"]:
self.Liquido = ThermoAdvanced()
self.Gas = ThermoAdvanced()
elif self._thermo == "refprop":
self.Liquido = ThermoRefProp()
self.Gas = ThermoRefProp()
else:
self.Liquido = Mezcla()
self.Gas = Mezcla()
self.Liquido.readStatefromJSON(state["liquid"])
self.Gas.readStatefromJSON(state["gas"])
if state["liquid"]:
self.Liquido.sigma = unidades.Tension(state["liquid"]["sigma"])
[docs]
class PsyStream(config.Entity):
"""
Class to model a stream as psychrometric state
kwargs definition parameters:
P: Pressure, Pa
z: altitude, m
tdp: dew-point temperature
tdb: dry-bulb temperature
twb: web-bulb temperature
w: Humidity Ratio [kg water/kg dry air]
HR: Relative humidity
h: Mixture enthalpy
v: Mixture specified volume
state: opcional for predefined psychrometric state
P: input for barometric pressure, z is an alternate pressure input
For flow definition, one of:
caudalMasico
caudalVolumetrico
caudalMolar
"""
kwargs = {"z": 0.0,
"P": 0.0,
"tdb": 0.0,
"tdb": 0.0,
"twb": 0.0,
"w": None,
"HR": None,
"h": None,
"v": 0.0,
"caudalMasico": 0.0,
"caudalVolumetrico": 0.0,
"caudalMolar": 0.0,
"state": None}
status = 0
msg = "undefined"
[docs]
def __init__(self, **kwargs):
self.kwargs = PsyStream.kwargs.copy()
self.__call__(**kwargs)
def __call__(self, **kwargs):
if kwargs.get("state", None):
kwargs.update(kwargs["state"].kwargs)
self.kwargs.update(kwargs)
for key, value in list(self.kwargs.items()):
if value:
self._bool = True
break
if self.calculable:
self.status = 1
self.calculo()
self.msg = ""
@property
def calculable(self):
# State definition
tdp = self.kwargs.get("tdp", 0)
tdb = self.kwargs.get("tdb", 0)
twb = self.kwargs.get("twb", 0)
w = self.kwargs.get("w", None)
HR = self.kwargs.get("HR", None)
h = self.kwargs.get("h", None)
v = self.kwargs.get("v", 0)
self.mode = -1
if tdb and w is not None:
self.mode = 0
elif tdb and HR is not None:
self.mode = 1
elif tdb and twb:
self.mode = 2
elif tdb and tdp:
self.mode = 3
elif tdp and HR is not None:
self.mode = 4
elif self.kwargs["state"]:
self.mode = 5
# Flow definition
caudal = self.kwargs["caudalVolumetrico"] \
or self.kwargs["caudalMolar"] or self.kwargs["caudalMasico"]
return bool(self.mode+1) and caudal
[docs]
def calculo(self):
if self.kwargs["state"]:
self.state = self.kwargs["state"]
else:
self.state = PsychroState(**self.kwargs)
kwargs = self.kwargs
self.__dict__.update(self.state.__dict__)
self.kwargs = kwargs
self.updateFlow()
[docs]
def updatekwargsFlow(self, key, value):
self.kwargs[key] = value
if key == "caudalMasico" and value:
self.kwargs["caudalVolumetrico"] = 0.0
self.kwargs["caudalMolar"] = 0.0
elif key == "caudalMolar" and value:
self.kwargs["caudalVolumetrico"] = 0.0
self.kwargs["caudalMasico"] = 0.0
elif key == "caudalVolumetrico" and value:
self.kwargs["caudalMasico"] = 0.0
self.kwargs["caudalMolar"] = 0.0
if self.status:
self.updateFlow()
elif self.calculable:
self.status = 1
self.calculo()
self.msg = ""
[docs]
def updateFlow(self):
if self.kwargs["caudalMasico"]:
G = self.kwargs["caudalMasico"]
M = G/(self.Xw*18.01528+self.Xa*28.9645)
Q = G*self.v
elif self.kwargs["caudalMolar"]:
M = self.kwargs["caudalMolar"]
G = M*self.Xw*18.01528+M*self.Xa*28.9645
Q = G*self.v
elif self.kwargs["caudalVolumetrico"]:
Q = self.kwargs["caudalVolumetrico"]
G = Q*self.rho
M = G/(self.Xw*18.01528+self.Xa*28.9645)
self.caudalMasico = unidades.MassFlow(G)
self.caudalVolumetrico = unidades.VolFlow(Q)
self.caudalMolar = unidades.MolarFlow(M)
@property
def corriente(self):
corriente = Corriente(T=self.state.twb, P=self.state.P,
caudalMasico=self.caudalMasico, ids=[62, 475],
fraccionMolar=[self.state.Xw, self.state.Xa])
return corriente
if __name__ == '__main__':
# mezcla=Corriente()
# if mezcla:
# print True
# else:
# print False
# mezcla=Corriente(T=300)
# mezcla(P=101325)
# mezcla(caudalMasico=2)
# mezcla(fraccionMolar=[1, 0, 0, 0])
# print mezcla.caudalmasico, mezcla.caudalmolar
# mezcla(caudalMolar=3, fraccionMolar=[1, 0, 0, 0])
# print mezcla.caudalmasico, mezcla.caudalmolar
# print mezcla.x, mezcla.H_exc
# print mezcla.T, mezcla.P.atm, mezcla.Q.ft3s
# mezcla.clear()
# agua=Corriente(T=300, P=1e5, caudalMasico=5, fraccionMolar=[1.])
# agua2=agua.clone(P=101325, split=0.9)
# print agua.P, agua.Liquido.caudalmasico
# z=0.965
# mez=Mezcla(tipo=3, fraccionMolar=[z, 1-z], caudalMasico=1.)
# tb=mez.componente[0].Tb
# print tb
# corr=Corriente(T=tb, P=101325., mezcla=mez)
# print corr.eos._Dew_T()
# corr=Corriente(T=300, P=101325.)
# if corr:
# print bool(corr)
# aire=Corriente(T=350, P=101325, caudalMasico=0.01, ids=[475, 62], fraccionMolar=[0.99, 0.01])
# agua=Corriente(T=300, P=101325, caudalMasico=0.1, ids=[62], fraccionMolar=[1.])
# aire=PsyStream(caudal=5, tdb=300, HR=50)
# agua=Corriente(T=300, P=101325, caudalMasico=1., ids=[62], fraccionMolar=[1.], MEoS=True)
# agua2=Corriente(T=300, P=101325, caudalMasico=1., ids=[62], fraccionMolar=[1.], iapws=True)
# from pprint import pprint
# pprint(agua.__dict__)
# pprint(agua2.__dict__)
# print(agua.rho, agua2.rho)
T = unidades.Temperature(120, "F")
P = unidades.Pressure(485, "psi")
stream = Corriente(T=T, P=P, caudalMolar=5.597, ids=[1, 2, 40, 41],
fraccionMolar=[0.3177, 0.5894, 0.0715, 0.0214],
K="Peng-Robinson", H="Benedict-Webb-Rubin-Starling")
# from lib.mEoS import H2O
# agua = H2O(T=300, P=101325)
# agua1 = Corriente(T=300, P=101325, caudalMasico=1., ids=[62], fraccionMolar=[1.], MEoS=True)
# # agua2=Corriente(T=300, P=101325, caudalMasico=1., ids=[62], fraccionMolar=[1.], iapws=True)
# from pprint import pprint
# pprint(agua.__dict__)
# pprint(agua1.__dict__)
# agua2=Corriente(T=300, P=101325, caudalMasico=1., ids=[62], fraccionMolar=[1.], MEoS=True, refprop=True)
# print(agua.rho, agua1.rho, agua2.rho)
# agua3 = Corriente(T=300, P=101325, caudalMasico=1., ids=[62], fraccionMolar=[1.], MEoS=False, K="BWRS", H="BWRS")
# print(agua.rho, agua1.rho, agua3.Gas.rho)
# P = unidades.Pressure(410.3, "psi")
# T = unidades.Temperature(400, "F")
# mix = Corriente(T=T, P=P, caudalMasico=1., ids=[4, 40],
# caudalUnitarioMasico=[26.92, 73.08], K="GS", H="BWRS")
# print(mix.x)
zi = [0.31767, 0.58942, 0.07147, 0.02144]
P = unidades.Pressure(485, "psi")
T = unidades.Temperature(100, "F")
mix = Corriente(T=T, P=P, ids=[1, 2, 40, 41], caudalUnitarioMolar=zi,
K="GS", H="BWRS")
print(mix.x)
print(mix.Liquido.fraccion)
print(mix.Gas.fraccion)
zi = [0.31767, 0.58942, 0.07147, 0.02144, 0]
mix = Corriente(T=T, P=P, ids=[1, 2, 40, 41, 34], caudalUnitarioMolar=zi,
K="GS", H="BWRS")
print(mix.x)
print(mix.Liquido.fraccion)
print(mix.Gas.fraccion)
# P = unidades.Pressure(485, "psi")
# T = unidades.Temperature(100, "F")
# mix = Corriente(T=T, P=P, caudalMasico=1., ids=[1, 2, 40, 41],
# caudalUnitarioMolar=[0.31767, 0.58942, 0.07147, 0.02144],
# K="PR76", H="PR76")
# mix = Corriente(T=293.15, P=5e6, caudalMasico=1.,
# ids=[2, 3, 4, 6, 5, 8, 46, 49, 50, 22],
# caudalUnitarioMolar=[1]*10, K="PR76", H="PR76")
# print(mix.x)