Skip to content

Commit

Permalink
implement CEOS equilibrium
Browse files Browse the repository at this point in the history
  • Loading branch information
cortespea committed Nov 13, 2023
1 parent a3985d1 commit 1e6146f
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 77 deletions.
182 changes: 108 additions & 74 deletions thermosteam/_chemical_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,31 @@
from collections.abc import Iterable
import thermosteam as tmo

class CachedProperty:
__slots__ = ('fget', 'key')

def __new__(cls, fget):
self = super().__new__(cls)
self.fget = fget
self.key = fget.__name__
return self

def __get__(self, data, _):
cache = data.cache
key = self.key
if key in cache:
value = cache[key]
else:
cache[key] = value = self.fget(data)
return value


class ChemicalData:
"""
Create a ChemicalData object that works as thermo ChemicalPropertiesPackage
and ChemicalConstantsPackage objects.
"""
__slots__ = ('N', 'chemicals', 'index', 'cmps')
__slots__ = ('N', 'chemicals', 'index', 'cmps', 'cache')

def __init__(self, chemicals):
if isinstance(chemicals, tmo.CompiledChemicals):
Expand All @@ -23,6 +42,7 @@ def __init__(self, chemicals):
self.chemicals = tuple(chemicals)
self.N = len(chemicals)
self.cmps = range(self.N)
self.cache = {}

def __iter__(self):
return self.chemicals.__iter__()
Expand Down Expand Up @@ -58,213 +78,227 @@ def __getitem__(self, IDs):
else:
raise KeyError("key must be a string or a tuple, not a '{type(IDs).__name__}' object")

@property
@CachedProperty
def EnthalpyVaporizations(self):
return [i.Hvap for i in self.chemicals]
@property
@CachedProperty
def VaporPressures(self):
return [i.Psat for i in self.chemicals]
@property
@CachedProperty
def SublimationPressures(self):
return [i.Psub for i in self.chemicals]
@property
@CachedProperty
def EnthalpySublimations(self):
return [i.Hsub for i in self.chemicals]
@property
@CachedProperty
def SurfaceTensions(self):
return [i.sigma for i in self.chemicals]
@property
@CachedProperty
def PermittivityLiquids(self):
return [i.epsilon for i in self.chemicals]
@property
@CachedProperty
def CASs(self):
return [i.CAS for i in self.chemicals]
@property
@CachedProperty
def MWs(self):
return [i.MW for i in self.chemicals]
@property
@CachedProperty
def Tms(self):
return [i.Tm for i in self.chemicals]
@property
@CachedProperty
def Tbs(self):
return [i.Tb for i in self.chemicals]
@property
@CachedProperty
def Tcs(self):
return [i.Tc for i in self.chemicals]
@property
@CachedProperty
def Pcs(self):
return [i.Pc for i in self.chemicals]
@property
@CachedProperty
def Vcs(self):
return [i.Vc for i in self.chemicals]
@property
@CachedProperty
def omegas(self):
return [i.omega for i in self.chemicals]
@property
@CachedProperty
def Zcs(self):
return [i.Zc for i in self.chemicals]
@property
@CachedProperty
def Hfus_Tms(self):
return [i.Hfus for i in self.chemicals]
@property
@CachedProperty
def Tts(self):
return [i.Tt for i in self.chemicals]
@property
@CachedProperty
def Pts(self):
return [i.Pt for i in self.chemicals]
@property
@CachedProperty
def dipoles(self):
return [i.dipole for i in self.chemicals]
@property
@CachedProperty
def charges(self):
return [i.charge for i in self.chemicals]
@property
@CachedProperty
def UNIFAC_groups(self):
return [i.UNIFAC for i in self.chemicals]
@property
@CachedProperty
def UNIFAC_Dortmund_groups(self):
return [i.Dortmund for i in self.chemicals]
@property
@CachedProperty
def PSRK_groups(self):
return [i.PSRK for i in self.chemicals]
@property
@CachedProperty
def similarity_variables(self):
return [i.similarity_variable for i in self.chemicals]
@property
@CachedProperty
def StielPolars(self):
return [i.Stiel_Polar for i in self.chemicals]
@property
@CachedProperty
def VolumeGases(self):
return [i.V if i._locked_state else i.V.g for i in self.chemicals]
@property
@CachedProperty
def VolumeLiquids(self):
return [i.V if i._locked_state else i.V.l for i in self.chemicals]
@property
@CachedProperty
def VolumeSolids(self):
return [i.V if i._locked_state else i.V.s for i in self.chemicals]
@property
@CachedProperty
def HeatCapacityGases(self):
return [i.Cn if i._locked_state else i.Cn.g for i in self.chemicals]
@property
@CachedProperty
def HeatCapacityLiquids(self):
return [i.Cn if i._locked_state else i.Cn.l for i in self.chemicals]
@property
@CachedProperty
def HeatCapacitySolids(self):
return [i.Cn if i._locked_state else i.Cn.s for i in self.chemicals]
@property
@CachedProperty
def ViscosityGases(self):
return [i.mu if i._locked_state else i.mu.g for i in self.chemicals]
@property
@CachedProperty
def ViscosityLiquids(self):
return [i.mu if i._locked_state else i.mu.l for i in self.chemicals]
@property
@CachedProperty
def ThermalConductivityGases(self):
return [i.k if i._locked_state else i.k.g for i in self.chemicals]
@property
@CachedProperty
def ThermalConductivityLiquids(self):
return [i.k if i._locked_state else i.k.l for i in self.chemicals]
@property
@CachedProperty
def rhocs(self):
return [None if Vc is None else 1.0/Vc for Vc in self.chemicals.Vcs]
@property
@CachedProperty
def rhocs_mass(self):
return [None if None in (rhoc, MW) else rhoc * 1e-3 * MW
for rhoc, MW in zip(self.rhocs, self.MWs)]
@property
@CachedProperty
def Hfus_Tms_mass(self):
return [None if None in (Hfus, MW) else Hfus * 1000.0 / MW
for Hfus, MW in zip(self.Hfus_Tms, self.MWs)]
@property
@CachedProperty
def Hvap_Tbs(self):
return [Hvap(Tb) for Hvap, Tb in zip(self.EnthalpyVaporizations, self.Tbs)]
@property
@CachedProperty
def Hvap_Tbs_mass(self):
return [None if None in (Hvap, MW) else Hvap*1000.0/MW
for Hvap, MW in zip(self.Hvap_Tbs, self.Tbs)]
@property
@CachedProperty
def Vmg_STPs(self):
return [i.TP_dependent_property(298.15, 101325.0)
for i in self.chemicals.VolumeGases]
@property
@CachedProperty
def rhog_STPs(self):
return [1.0/V if V is not None else None for V in self.chemicals.Vmg_STPs]
@property
@CachedProperty
def rhog_STPs_mass(self):
return [1e-3*MW/V if V is not None else None for V, MW in zip(self.Vmg_STPs, self.MWs)]
@property
@CachedProperty
def Vml_Tbs(self):
return [None if Tb is None else i.T_dependent_property(Tb) for i, Tb in zip(self.VolumeLiquids, self.Tbs)]
@property
@CachedProperty
def Vml_Tms(self):
return [None if Tm is None else i.T_dependent_property(Tm)
for i, Tm in zip(self.VolumeLiquids, self.Tms)]
@property
@CachedProperty
def Vml_STPs(self):
return [i.T_dependent_property(298.15) for i in self.chemicals.VolumeLiquids]
@property
@CachedProperty
def Vml_60Fs(self):
return [i.T_dependent_property(288.7055555555555) for i in self.chemicals.VolumeLiquids]
@property
@CachedProperty
def rhol_STPs(self):
return [1.0/V if V is not None else None for V in self.chemicals.Vml_STPs]
@property
@CachedProperty
def rhol_60Fs(self):
return [1.0/V if V is not None else None for V in self.chemicals.Vml_60Fs]
@property
@CachedProperty
def rhol_STPs_mass(self):
return [1e-3*MW/V if V is not None else None for V, MW in zip(self.Vml_STPs, self.MWs)]
@property
@CachedProperty
def rhol_60Fs_mass(self):
return [1e-3*MW/V if V is not None else None for V, MW in zip(self.Vml_60Fs, self.MWs)]
@property
@CachedProperty
def Hsub_Tts(self):
return [None if Tt is None else i(Tt)
for i, Tt in zip(self.EnthalpySublimations, self.Tts)]
@property
@CachedProperty
def Hsub_Tts_mass(self):
return [Hsub*1000.0/MW if Hsub is not None else None for Hsub, MW in zip(self.Hsub_Tts, self.MWs)]
@property
@CachedProperty
def Stockmayers(self):
return [Stockmayer(Tm=self.Tms[i], Tb=self.Tbs[i], Tc=self.Tcs[i],
Zc=self.Zcs[i], omega=self.omegas[i], CASRN=self.CASs[i])
Tms = self.Tms
Tbs = self.Tbs
Tcs = self.Tcs
Zcs = self.Zcs
omegas = self.omegas
CASs = self.CASs
return [Stockmayer(Tm=Tms[i], Tb=Tbs[i], Tc=Tcs[i],
Zc=Zcs[i], omega=omegas[i], CASRN=CASs[i])
for i in self.cmps]
@property
@CachedProperty
def molecular_diameters(self):
return [molecular_diameter(Tc=self.Tcs[i], Pc=self.Pcs[i], Vc=self.Vcs[i],
Zc=self.Zcs[i], omega=self.omegas[i],
Vm=self.Vml_Tms[i], Vb=self.Vml_Tbs[i],
CASRN=self.CASs[i])
Tcs = self.Tcs
Zcs = self.Zcs
omegas = self.omegas
CASs = self.CASs
Vml_Tms = self.Vml_Tms
Vml_Tb = self.Vml_Tb
Pcs = self.Pcs
Vcs = self.Vcs
return [molecular_diameter(Tc=Tcs[i], Pc=Pcs[i], Vc=Vcs[i],
Zc=Zcs[i], omega=omegas[i],
Vm=Vml_Tms[i], Vb=Vml_Tb[i],
CASRN=CASs[i])
for i in self.cmps]
@property
@CachedProperty
def Psat_298s(self):
return [i(298.15) for i in self.chemicals.VaporPressures]
@property
@CachedProperty
def Hvap_298s(self):
return [o.T_dependent_property(298.15) for o in self.chemicals.EnthalpyVaporizations]
@property
@CachedProperty
def Hvap_298s_mass(self):
return [Hvap*1000.0/MW if Hvap is not None else None for Hvap, MW in zip(self.Hvap_298s, self.MWs)]
@property
@CachedProperty
def Vms_Tms(self):
return [None if Tm is None else i.T_dependent_property(Tm) for i, Tm in zip(self.VolumeSolids, self.Tms)]
@property
@CachedProperty
def rhos_Tms(self):
return [1.0/V if V is not None else None for V in self.chemicals.Vms_Tms]
@property
@CachedProperty
def rhos_Tms_mass(self):
return [1e-3*MW/V if V is not None else None for V, MW in zip(self.Vms_Tms, self.MWs)]
@property
@CachedProperty
def sigma_STPs(self):
return [i.T_dependent_property(298.15) for i in self.SurfaceTensions]
@property
@CachedProperty
def sigma_Tbs(self):
return [None if Tb is None else i.T_dependent_property(Tb)
for i, Tb in zip(self.SurfaceTensions, self.Tbs)]
@property
@CachedProperty
def sigma_Tms(self):
return [None if Tm is None else i.T_dependent_property(Tm)
for i, Tm in zip(self.SurfaceTensions, self.Tms)]
@property
@CachedProperty
def Van_der_Waals_volumes(self):
N = self.N
N_range = self.cmps
Expand All @@ -275,7 +309,7 @@ def Van_der_Waals_volumes(self):
if groups is not None:
UNIFAC_Rs[i] = UNIFAC_RQ(groups)[0]
return [Van_der_Waals_volume(UNIFAC_Rs[i]) if UNIFAC_Rs[i] is not None else None for i in N_range]
@property
@CachedProperty
def Van_der_Waals_areas(self):
N = self.N
N_range = self.cmps
Expand All @@ -286,7 +320,7 @@ def Van_der_Waals_areas(self):
if groups is not None:
UNIFAC_Qs[i] = UNIFAC_RQ(groups)[1]
return [Van_der_Waals_area(UNIFAC_Qs[i]) if UNIFAC_Qs[i] is not None else None for i in N_range]
@property
@CachedProperty
def Parachors(self):
N = self.N
Parachors = [None]*N
Expand Down
Loading

0 comments on commit 1e6146f

Please sign in to comment.