'''Chemical Engineering Design Library (ChEDL). Utilities for process modeling.
Copyright (C) 2019, 2020, 2021 Caleb Bell <Caleb.Andrew.Bell@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
This module contains classes for storing data and objects which are necessary
for doing thermodynamic calculations. The intention for these classes is to
serve as an in-memory storage layer between the disk and methods which do
full thermodynamic calculations.
For reporting bugs, adding feature requests, or submitting pull requests,
please use the `GitHub issue tracker <https://github.com/CalebBell/thermo/>`_.
.. contents:: :local:
Chemical Constants Class
========================
.. autoclass:: ChemicalConstantsPackage
:members: subset, properties, correlations_from_IDs, constants_from_IDs,
from_IDs, with_new_constants, as_json, from_json, __add__
:undoc-members:
:exclude-members:
Chemical Correlations Class
===========================
.. autoclass:: PropertyCorrelationsPackage
:members: subset, __add__
:undoc-members:
:exclude-members:
Sample Constants and Correlations
=================================
.. autodata:: iapws_constants
.. autodata:: iapws_correlations
.. autodata:: lemmon2000_constants
.. autodata:: lemmon2000_correlations
'''
__all__ = ['ChemicalConstantsPackage', 'PropertyCorrelationsPackage',
'iapws_constants', 'iapws_correlations', 'lemmon2000_constants',
'lemmon2000_correlations']
from chemicals import identifiers
from chemicals.acentric import Stiel_polar_factor, omega
from chemicals.combustion import HHV_stoichiometry, LHV_from_HHV, combustion_stoichiometry
# For Constants
from chemicals.critical import Pc, Tc, Vc
from chemicals.dipole import dipole_moment as dipole
from chemicals.elements import (
atom_fractions,
charge_from_formula,
homonuclear_elements,
molecular_weight,
periodic_table,
similarity_variable,
simple_formula_parser,
)
from chemicals.environment import GWP, ODP, logP
from chemicals.identifiers import CAS_from_any
from chemicals.lennard_jones import Stockmayer, molecular_diameter
from chemicals.phase_change import Hfus, Tb, Tm
from chemicals.reaction import Gibbs_formation, Hfg, Hfl, Hfs, S0g
from chemicals.refractivity import RI
from chemicals.safety import LFL, STEL, TWA, UFL, Carcinogen, Ceiling, Skin, T_autoignition, T_flash
from chemicals.solubility import solubility_parameter, hansen_delta_d, hansen_delta_p, hansen_delta_h
from chemicals.triple import Pt, Tt
from chemicals.utils import Parachor, hash_any_primitive
from fluids.constants import R
from thermo.chemical import user_chemical_property_lookup
from thermo.electrochem import conductivity
from thermo.eos import PR
from thermo.heat_capacity import (
HeatCapacityGas,
HeatCapacityGasMixture,
HeatCapacityLiquid,
HeatCapacityLiquidMixture,
HeatCapacitySolid,
HeatCapacitySolidMixture,
)
from thermo.interface import SurfaceTension, SurfaceTensionMixture
from thermo.permittivity import PermittivityLiquid
from thermo.phase_change import EnthalpySublimation, EnthalpyVaporization
from thermo.serialize import JsonOptEncodable
from thermo.thermal_conductivity import (
ThermalConductivityGas,
ThermalConductivityGasMixture,
ThermalConductivityLiquid,
ThermalConductivityLiquidMixture,
ThermalConductivitySolid,
)
from thermo.unifac import UNIFAC_RQ, UNIFAC_group_assignment_DDBST, Van_der_Waals_area, Van_der_Waals_volume
from thermo.utils import identify_phase
from thermo.utils.mixture_property import MixtureProperty
from thermo.vapor_pressure import SublimationPressure, VaporPressure
from thermo.viscosity import ViscosityGas, ViscosityGasMixture, ViscosityLiquid, ViscosityLiquidMixture
from thermo.volume import VolumeGas, VolumeGasMixture, VolumeLiquid, VolumeLiquidMixture, VolumeSolid, VolumeSolidMixture
CAS_H2O = '7732-18-5'
warn_chemicals_msg ="""`chemicals <https://github.com/CalebBell/chemicals>`_ is a
project with a focus on collecting data and
correlations from various sources. In no way is it a project to
critically evaluate these and provide recommendations. You are
strongly encouraged to check values from it and modify them
if you want different values. If you believe there is a value
which has a typographical error please report it to the
`chemicals <https://github.com/CalebBell/chemicals>`_
project. If data is missing or not as accuracte
as you would like, and you know of a better method or source,
new methods and sources can be added to
`chemicals <https://github.com/CalebBell/chemicals>`_
fairly easily once the data entry is complete."""
[docs]class ChemicalConstantsPackage:
non_vector_properties = ('atomss', 'Carcinogens', 'CASs', 'Ceilings', 'charges',
'conductivities', 'dipoles', 'economic_statuses', 'formulas', 'Gfgs',
'Gfgs_mass', 'GWPs', 'Hcs', 'Hcs_lower', 'Hcs_lower_mass', 'Hcs_mass',
'Hfgs', 'Hfgs_mass', 'Hfus_Tms', 'Hfus_Tms_mass', 'Hsub_Tts',
'Hsub_Tts_mass', 'Hvap_298s', 'Hvap_298s_mass', 'Hvap_Tbs', 'Hvap_Tbs_mass',
'InChI_Keys', 'InChIs', 'legal_statuses', 'LFLs', 'logPs',
'molecular_diameters', 'MWs', 'names', 'aliases', 'ODPs', 'omegas',
'Parachors', 'Pcs', 'phase_STPs', 'Psat_298s', 'PSRK_groups',
'Pts', 'PubChems', 'rhocs', 'rhocs_mass', 'rhol_STPs',
'rhol_STPs_mass', 'RIs', 'S0gs', 'S0gs_mass', 'Sfgs',
'Sfgs_mass', 'similarity_variables', 'Skins', 'smiless',
'STELs', 'StielPolars', 'Stockmayers', 'Tautoignitions',
'Tbs', 'Tcs', 'Tflashs', 'Tms', 'Tts', 'TWAs', 'UFLs',
'UNIFAC_Dortmund_groups', 'UNIFAC_groups',
'Van_der_Waals_areas', 'Van_der_Waals_volumes', 'Vcs',
'Vml_STPs', 'Vml_Tms', 'Zcs', 'UNIFAC_Rs', 'UNIFAC_Qs',
'rhos_Tms', 'Vms_Tms', 'rhos_Tms_mass', 'solubility_parameters',
'Vml_60Fs', 'rhol_60Fs', 'rhol_60Fs_mass',
'conductivity_Ts', 'RI_Ts',
'Vmg_STPs', 'rhog_STPs', 'rhog_STPs_mass', 'sigma_STPs',
'sigma_Tms', 'sigma_Tbs', 'Hf_STPs', 'Hf_STPs_mass',
)
__full_path__ = f"{__module__}.{__qualname__}"
properties = ('atom_fractions',) + non_vector_properties
"""Tuple of all properties that can be held by this object."""
__slots__ = properties + ('N', 'cmps', 'water_index', 'n_atoms') + ('_hash', '_CAS_to_index', '_unique_atoms')
non_vectors = ('atom_fractions',)
non_vectors_set = set(non_vectors)
json_version = 1
non_json_attributes = []
obj_references = []
vectorized = False
def _missing_properties(self):
missing = []
empty_list = [None]*self.N
for prop in self.non_vector_properties:
if getattr(self, prop) == empty_list:
missing.append(prop)
return tuple(missing)
def as_dict(self):
new = {}
properties = self.properties
for p in properties:
v = getattr(self, p)
if v is not None:
new[p] = v
return new
def _custom_as_json(self, d, cache):
del d['cmps']
# economic_statuses
for k in ('PSRK_groups', 'UNIFAC_Dortmund_groups', 'UNIFAC_groups'):
# keys are stored as strings and not ints
d[k] = [{str(k): v for k, v in r.items()} if r is not None else r for r in d[k]]
# This is not so much a performance optimization as an improvement on file size
# and readability. Do not remove it! Comparing against an empty list is the
# fastest way to check as of 2023.
# Benchmarking 7 components with Python json savings is 136 µs down to 101 µs.
# Benchmarking with orjson shown a slowdown from 46 to 50.2 µs but the json is
# much nicer.
N = self.N
empty_list = [None]*N
for k in self.non_vector_properties:
if d[k] == empty_list:
del d[k]
def _custom_from_json(self, *args):
self.cmps = range(self.N)
empty_list = [None]*self.N
for k in self.non_vector_properties:
if not hasattr(self, k):
setattr(self, k, empty_list)
for k in ('TWAs', 'STELs'):
# tuple gets converted to a json list
l = getattr(self, k)
setattr(self, k, [tuple(v) if v is not None else v for v in l])
for k in ('PSRK_groups', 'UNIFAC_Dortmund_groups', 'UNIFAC_groups'):
obj = getattr(self, k)
obj = [{int(k): v for k, v in r.items()} if r is not None else r for r in obj]
setattr(self, k, obj)
[docs] def as_json(self, cache=None, option=0):
r'''Method to create a JSON friendly serialization of the chemical constants
package which can be stored, and reloaded later.
Returns
-------
json_repr : dict
Json friendly representation, [-]
Notes
-----
Examples
--------
>>> import json
>>> constants = ChemicalConstantsPackage(MWs=[18.01528, 106.165], names=['water', 'm-xylene'])
>>> string = json.dumps(constants.as_json())
'''
return JsonOptEncodable.as_json(self, cache, option)
[docs] @classmethod
def from_json(cls, json_repr, cache=None):
r'''Method to create a ChemicalConstantsPackage from a JSON
serialization of another ChemicalConstantsPackage.
Parameters
----------
json_repr : dict
Json representation, [-]
Returns
-------
constants : ChemicalConstantsPackage
Newly created object from the json serialization, [-]
Notes
-----
It is important that the input be in the same format as that
created by :obj:`ChemicalConstantsPackage.as_json`.
Examples
--------
>>> import json
>>> constants = ChemicalConstantsPackage(MWs=[18.01528, 106.165], names=['water', 'm-xylene'])
>>> string = json.dumps(constants.as_json())
>>> new_constants = ChemicalConstantsPackage.from_json(json.loads(string))
>>> assert hash(new_constants) == hash(constants)
'''
return JsonOptEncodable.from_json(json_repr, cache)
def __hash__(self):
try:
return self._hash
except:
pass
hashes = []
for k in self.properties:
hashes.append(hash_any_primitive(getattr(self, k)))
self._hash = hash_any_primitive(hashes)
return self._hash
def __eq__(self, other):
return self.__hash__() == hash(other)
[docs] def __add__(self, b):
r'''Method to create a new :obj:`ChemicalConstantsPackage` object
from two other :obj:`ChemicalConstantsPackage` objects.
Returns
-------
new : :obj:`ChemicalConstantsPackage`
New object, [-]
Notes
-----
Examples
--------
>>> a = ChemicalConstantsPackage.constants_from_IDs(IDs=['water', 'hexane'])
>>> b = ChemicalConstantsPackage.constants_from_IDs(IDs=['toluene'])
>>> c = a + b
'''
if not isinstance(b, ChemicalConstantsPackage):
raise TypeError('Adding to a ChemicalConstantsPackage requires that the other object '
'also be a ChemicalConstantsPackage.')
a = self
a_dict = a.as_dict()
b_dict = b.as_dict()
kwargs = {}
for k in a_dict.keys():
kwargs[k] = a_dict[k] + b_dict[k]
return ChemicalConstantsPackage(**kwargs)
[docs] def with_new_constants(self, **kwargs):
r'''Method to construct a new ChemicalConstantsPackage that replaces or
adds one or more properties for all components.
Parameters
----------
kwargs : dict[str: list[float]]
Properties specified by name [various]
Returns
-------
new_constants : ChemicalConstantsPackage
Object with new and/or replaced properties, [-]
Notes
-----
Examples
--------
>>> base = ChemicalConstantsPackage(MWs=[18.01528, 106.165, 106.165, 106.165], names=['water', 'o-xylene', 'p-xylene', 'm-xylene'], omegas=[0.344, 0.3118, 0.324, 0.331], Pcs=[22048320.0, 3732000.0, 3511000.0, 3541000.0], Tcs=[647.14, 630.3, 616.2, 617.0])
>>> base.with_new_constants(Tms=[40.0, 20.0, 10.0, 30.0], omegas=[0.0, 0.1, 0.2, 0.3])
ChemicalConstantsPackage(MWs=[18.01528, 106.165, 106.165, 106.165], names=['water', 'o-xylene', 'p-xylene', 'm-xylene'], omegas=[0.0, 0.1, 0.2, 0.3], Pcs=[22048320.0, 3732000.0, 3511000.0, 3541000.0], Tcs=[647.14, 630.3, 616.2, 617.0], Tms=[40.0, 20.0, 10.0, 30.0])
'''
new = {}
properties = self.non_vector_properties
for p in properties:
v = getattr(self, p)
if v is not None:
new[p] = v
new.update(kwargs)
return ChemicalConstantsPackage(**new)
[docs] def subset(self, idxs=None, properties=None):
r'''Method to construct a new ChemicalConstantsPackage that removes
all components not specified in the `idxs` argument. Although this
class has a great many attributes, it is often sufficient to work with
a subset of those properties; and if a list of properties is provided,
only those properties will be added to the new object as well.
Parameters
----------
idxs : list[int] or Slice or None
Indexes of components that should be included; if None, all
components will be included , [-]
properties : tuple[str] or None
List of properties to be included; all properties will be included
if this is not specified
Returns
-------
subset_consts : ChemicalConstantsPackage
Object with reduced properties and or components, [-]
Notes
-----
It is not intended for properties to be edited in this object!
One optimization is that all entirely empty properties use the same
list-of-Nones.
All properties should have been specified before constructing the first
ChemicalConstantsPackage.
Examples
--------
>>> base = ChemicalConstantsPackage(MWs=[18.01528, 106.165, 106.165, 106.165], names=['water', 'o-xylene', 'p-xylene', 'm-xylene'], omegas=[0.344, 0.3118, 0.324, 0.331], Pcs=[22048320.0, 3732000.0, 3511000.0, 3541000.0], Tcs=[647.14, 630.3, 616.2, 617.0])
>>> base.subset([0])
ChemicalConstantsPackage(MWs=[18.01528], names=['water'], omegas=[0.344], Pcs=[22048320.0], Tcs=[647.14])
>>> base.subset(slice(1,4))
ChemicalConstantsPackage(MWs=[106.165, 106.165, 106.165], names=['o-xylene', 'p-xylene', 'm-xylene'], omegas=[0.3118, 0.324, 0.331], Pcs=[3732000.0, 3511000.0, 3541000.0], Tcs=[630.3, 616.2, 617.0])
>>> base.subset(idxs=[0, 3], properties=('names', 'MWs'))
ChemicalConstantsPackage(MWs=[18.01528, 106.165], names=['water', 'm-xylene'])
'''
if idxs is None:
idxs = self.cmps
if properties is None:
properties = self.non_vector_properties
else:
properties = list(properties)
if 'MWs' not in properties:
properties.append('MWs')
is_slice = isinstance(idxs, slice)
if not is_slice:
is_one = len(idxs) == 1
idx = idxs[0]
new = {}
if is_slice:
for p in properties:
v = getattr(self, p)
if v is not None:
new[p] = v[idxs]
elif is_one:
for p in properties:
v = getattr(self, p)
if v is not None:
new[p] = [v[idx]]
else:
for p in properties:
v = getattr(self, p)
if v is not None:
new[p] = [v[i] for i in idxs]
return ChemicalConstantsPackage(**new)
def __repr__(self):
return self._make_str()
def _make_str(self, delim=', ', properties=None):
'''Method to create a new string representing the
object.
'''
if properties is None:
properties = self.properties
s = 'ChemicalConstantsPackage('
for k in properties:
if any(i is not None for i in getattr(self, k)):
s += f'{k}={getattr(self, k)}{delim}'
s = s[:-2] + ')'
return s
def compound_index(self, CAS=None, name=None, smiles=None, InChI=None,
InChI_Key=None, PubChem=None):
r'''Method to retrieve the index of a compound given one of the
optional identifiers for the compound.
Parameters
----------
CAS : str, optional
The CAS number of the compound, [-]
name : str, optional
The (provided) name of the compound, [-]
smiles : str, optional
Smiles identifier, [-]
InChI : str, optional
InChI identifier, [-]
InChI_Key : str, optional
InChI key identifier, [-]
PubChem : int, optional
PubChem identifier, [-]
Returns
-------
index : int
The index of the component (if found), [-]
Raises
------
ValueError
If no identifier is provided for any argument, this is raised
IndexError
If no match is found for the provided identifier, this is raised
'''
if CAS is not None:
CAS_to_index = self.CAS_to_index
return CAS_to_index[CAS]
elif name is not None:
return self.names.index(name)
elif smiles is not None:
return self.smiless.index(smiles)
elif InChI is not None:
return self.InChIs.index(InChI)
elif InChI_Key is not None:
return self.InChI_Keys.index(InChI_Key)
elif PubChem is not None:
return self.PubChems.index(PubChem)
else:
raise ValueError("No identifier provided")
@property
def CAS_to_index(self):
r'''Dictionary of CAS: index, used for efficiently
looking up which index a specified CAS number is in.
This can save a lot of time, but does take a little more memory.
Returns
-------
CAS_to_index : dict[str: int]
Dictionary for CAS to index lookups, [-]
'''
try:
return self._CAS_to_index
except:
self._CAS_to_index = {CAS: i for i, CAS in enumerate(self.CASs)}
return self._CAS_to_index
@property
def unique_atoms(self):
r'''Tuple of all of the atoms in the package. Useful for iterating
over all the atom dictionaries.
Returns
-------
unique_atoms : tuple
Unique atoms, [-]
'''
try:
return self._unique_atoms
except:
all_atoms = set()
for atoms in self.atomss:
all_atoms.update(atoms.keys())
self._unique_atoms = tuple(sorted(all_atoms))
return self._unique_atoms
[docs] @staticmethod
def constants_from_IDs(IDs):
r'''Method to construct a new `ChemicalConstantsPackage` with loaded
parameters from the `chemicals library <https://github.com/CalebBell/chemicals>`_,
using whatever default methods and values happen to be in that library.
Expect values to change over time.
Parameters
----------
IDs : list[str]
Identifying strings for each compound;
most identifiers are accepted and all inputs are documented in
:obj:`chemicals.identifiers.search_chemical`, [-]
Returns
-------
constants : ChemicalConstantsPackage
New `ChemicalConstantsPackage` with loaded values, [-]
Notes
-----
.. warning::
%s
Examples
--------
>>> constants = ChemicalConstantsPackage.constants_from_IDs(IDs=['water', 'hexane'])
'''
return ChemicalConstantsPackage._from_IDs(IDs, correlations=False)
try:
constants_from_IDs.__func__.__doc__ = constants_from_IDs.__func__.__doc__ %(warn_chemicals_msg)
except:
pass
[docs] @staticmethod
def correlations_from_IDs(IDs):
r'''Method to construct a new `PropertyCorrelationsPackage` with loaded
parameters from the `chemicals library <https://github.com/CalebBell/chemicals>`_,
using whatever default methods and values happen to be in that library.
Expect values to change over time.
Parameters
----------
IDs : list[str]
Identifying strings for each compound;
most identifiers are accepted and all inputs are documented in
:obj:`chemicals.identifiers.search_chemical`, [-]
Returns
-------
correlations : PropertyCorrelationsPackage
New `PropertyCorrelationsPackage` with loaded values, [-]
Notes
-----
.. warning::
%s
Examples
--------
>>> correlations = ChemicalConstantsPackage.constants_from_IDs(IDs=['ethanol', 'methanol'])
'''
return ChemicalConstantsPackage._from_IDs(IDs, correlations=True)[1]
try:
correlations_from_IDs.__func__.__doc__ = correlations_from_IDs.__func__.__doc__ %(warn_chemicals_msg)
except:
pass
[docs] @staticmethod
def from_IDs(IDs):
r'''Method to construct a new `ChemicalConstantsPackage` and
`PropertyCorrelationsPackage` with loaded
parameters from the `chemicals library <https://github.com/CalebBell/chemicals>`_,
using whatever default methods and values happen to be in that library.
Expect values to change over time.
Parameters
----------
IDs : list[str]
Identifying strings for each compound;
most identifiers are accepted and all inputs are documented in
:obj:`chemicals.identifiers.search_chemical`, [-]
Returns
-------
constants : PropertyCorrelationsPackage
New `PropertyCorrelationsPackage` with loaded values, [-]
correlations : PropertyCorrelationsPackage
New `PropertyCorrelationsPackage` with loaded values, [-]
Notes
-----
.. warning::
%s
Examples
--------
>>> constants, correlations = ChemicalConstantsPackage.from_IDs(IDs=['water', 'decane'])
'''
return ChemicalConstantsPackage._from_IDs(IDs, correlations=True)
try:
from_IDs.__func__.__doc__ = from_IDs.__func__.__doc__ %(warn_chemicals_msg)
except:
pass
@staticmethod
def _from_IDs(IDs, correlations=False):
# Properties which were wrong from Mixture, Chemical: Parachor, solubility_parameter
N = len(IDs)
CASs = [CAS_from_any(ID) for ID in IDs]
pubchem_db = identifiers.pubchem_db
metadatas = [pubchem_db.search_CAS(CAS) for CAS in CASs]
names = [i.common_name.lower() for i in metadatas]
PubChems = [i.pubchemid for i in metadatas]
formulas = [i.formula for i in metadatas]
smiless = [i.smiles for i in metadatas]
InChIs = [i.InChI for i in metadatas]
InChI_Keys = [i.InChI_key for i in metadatas]
atomss = [simple_formula_parser(f) for f in formulas]
aliases = IDs
# MWs = [i.MW for i in metadatas] # Should be the same but there are still some inconsistencies
MWs = [molecular_weight(atomss[i]) for i in range(N)]
similarity_variables = [similarity_variable(atoms, MW) for atoms, MW in zip(atomss, MWs)]
charges = [charge_from_formula(formula) for formula in formulas]
Tms = [Tm(CAS) for CAS in CASs]
Tbs = [Tb(CAS) for CAS in CASs]
Tcs = [Tc(CAS) for CAS in CASs]
Pcs = [Pc(CAS) for CAS in CASs]
Vcs = [Vc(CAS) for CAS in CASs]
omegas = [omega(CAS) for CAS in CASs]
dipoles = [dipole(CAS) for CAS in CASs]
Tts = [Tt(CAS) for CAS in CASs]
Pts = [Pt(CAS) for CAS in CASs]
Zcs = [None]*N
for i in range(N):
try:
Zcs[i] = Vcs[i]*Pcs[i]/(R*Tcs[i])
except:
pass
VaporPressures = [VaporPressure(Tb=Tbs[i], Tc=Tcs[i], Pc=Pcs[i], omega=omegas[i], CASRN=CASs[i],
**user_chemical_property_lookup(CASs[i], 'VaporPressure'))
for i in range(N)]
Psat_298s = [VaporPressures[i].T_dependent_property(298.15) for i in range(N)]
phase_STPs = [identify_phase(T=298.15, P=101325., Tm=Tms[i], Tb=Tbs[i], Tc=Tcs[i], Psat=Psat_298s[i]) for i in range(N)]
for i in range(N):
if Pts[i] is None:
try:
Pts[i] = VaporPressures[i].T_dependent_property(Tts[i])
except:
pass
rhocs = [1.0/Vc if Vc else None for Vc in Vcs]
rhocs_mass = [1e-3*MW/Vc if Vc else None for Vc, MW in zip(Vcs, MWs)]
Hfus_Tms = [Hfus(CAS) for CAS in CASs]
Hfus_Tms_mass = [Hfus*1000.0/MW if Hfus is not None else None for Hfus, MW in zip(Hfus_Tms, MWs)]
EnthalpyVaporizations = [EnthalpyVaporization(CASRN=CAS, Tb=Tb, Tc=Tc, Pc=Pc, omega=omega, similarity_variable=sv,
**user_chemical_property_lookup(CAS, 'EnthalpyVaporization'))
for CAS, Tb, Tc, Pc, sv, omega in zip(CASs, Tbs, Tcs, Pcs, similarity_variables, omegas)]
Hvap_Tbs = [o.T_dependent_property(Tb) if Tb else None for o, Tb, in zip(EnthalpyVaporizations, Tbs)]
Hvap_Tbs_mass = [Hvap*1000.0/MW if Hvap is not None else None for Hvap, MW in zip(Hvap_Tbs, MWs)]
Hvap_298s = [o.T_dependent_property(298.15) for o in EnthalpyVaporizations]
Hvap_298s_mass = [Hvap*1000.0/MW if Hvap is not None else None for Hvap, MW in zip(Hvap_298s, MWs)]
StielPolars = [None]*N
for i in range(N):
try:
StielPolars[i] = Stiel_polar_factor(Psat=VaporPressures[i].T_dependent_property(T=Tcs[i]*0.6), Pc=Pcs[i], omega=omegas[i])
except:
pass
enclosed_eoss = []
for i in range(N):
try:
enclosed_eoss.append([PR(T=298.15, P=101325.0, Tc=Tcs[i], Pc=Pcs[i], omega=omegas[i])])
except:
enclosed_eoss.append(None)
VolumeGases = [VolumeGas(MW=MWs[i], Tc=Tcs[i], Pc=Pcs[i],
omega=omegas[i], dipole=dipoles[i],
eos=enclosed_eoss[i], CASRN=CASs[i]) for i in range(N)]
Vmg_STPs = [VolumeGases[i].TP_dependent_property(298.15, 101325.0)
for i in range(N)]
rhog_STPs = [1.0/V if V is not None else None for V in Vmg_STPs]
rhog_STPs_mass = [1e-3*MW/V if V is not None else None for V, MW in zip(Vmg_STPs, MWs)]
VolumeLiquids = [VolumeLiquid(MW=MWs[i], Tb=Tbs[i], Tc=Tcs[i],
Pc=Pcs[i], Vc=Vcs[i], Zc=Zcs[i], omega=omegas[i], dipole=dipoles[i],
Psat=VaporPressures[i], CASRN=CASs[i],
eos=enclosed_eoss[i], **user_chemical_property_lookup(CASs[i], 'VolumeLiquid'))
for i in range(N)]
Vml_Tbs = [VolumeLiquids[i].T_dependent_property(Tbs[i]) if Tbs[i] is not None else None
for i in range(N)]
Vml_Tms = [VolumeLiquids[i].T_dependent_property(Tms[i]) if Tms[i] is not None else None
for i in range(N)]
Vml_STPs = [VolumeLiquids[i].T_dependent_property(298.15)
for i in range(N)]
Vml_60Fs = [VolumeLiquids[i].T_dependent_property(288.7055555555555)
for i in range(N)]
rhol_STPs = [1.0/V if V is not None else None for V in Vml_STPs]
rhol_60Fs = [1.0/V if V is not None else None for V in Vml_60Fs]
rhol_STPs_mass = [1e-3*MW/V if V is not None else None for V, MW in zip(Vml_STPs, MWs)]
rhol_60Fs_mass = [1e-3*MW/V if V is not None else None for V, MW in zip(Vml_60Fs, MWs)]
VolumeSolids = [VolumeSolid(CASRN=CASs[i], MW=MWs[i], Tt=Tts[i], Vml_Tt=Vml_Tms[i], **user_chemical_property_lookup(CASs[i], 'VolumeSolid')) for i in range(N)]
Vms_Tms = [VolumeSolids[i].T_dependent_property(Tms[i]) if Tms[i] is not None else None for i in range(N)]
rhos_Tms = [1.0/V if V is not None else None for V in Vms_Tms]
rhos_Tms_mass = [1e-3*MW/V if V is not None else None for V, MW in zip(Vms_Tms, MWs)]
Hfgs = [Hfg(CAS) for CAS in CASs]
Hfgs_mass = [Hf*1000.0/MW if Hf is not None else None for Hf, MW in zip(Hfgs, MWs)]
Hfls = [Hfl(CAS) for CAS in CASs]
Hfls_mass = [Hf*1000.0/MW if Hf is not None else None for Hf, MW in zip(Hfls, MWs)]
Hfss = [Hfs(CAS) for CAS in CASs]
Hfss_mass = [Hf*1000.0/MW if Hf is not None else None for Hf, MW in zip(Hfss, MWs)]
S0gs = [S0g(CAS) for CAS in CASs]
S0gs_mass = [S0*1000.0/MW if S0 is not None else None for S0, MW in zip(S0gs, MWs)]
Hf_STPs, Hf_STPs_mass = [None]*N, [None]*N
for i in range(N):
if phase_STPs[i] == 'g':
Hf_STPs[i] = Hfgs[i]
Hf_STPs_mass[i] = Hfgs_mass[i]
elif phase_STPs[i] == 'l':
Hf_STPs[i] = Hfls[i]
Hf_STPs_mass[i] = Hfls_mass[i]
elif phase_STPs[i] == 's':
Hf_STPs[i] = Hfss[i]
Hf_STPs_mass[i] = Hfss_mass[i]
# Compute Gfgs
Gfgs = [None]*N
for i in range(N):
# Compute Gf and Gf(ig)
dHfs_std = []
S0_abs_elements = []
coeffs_elements = []
for atom, count in atomss[i].items():
try:
ele = periodic_table[atom]
H0, S0 = ele.Hf, ele.S0
if ele.number in homonuclear_elements:
H0, S0 = 0.5*H0, 0.5*S0
except KeyError:
H0, S0 = None, None # D, T
dHfs_std.append(H0)
S0_abs_elements.append(S0)
coeffs_elements.append(count)
elemental_reaction_data = (dHfs_std, S0_abs_elements, coeffs_elements)
try:
Gfgs[i] = Gibbs_formation(Hfgs[i], S0gs[i], dHfs_std, S0_abs_elements, coeffs_elements)
except:
pass
Gfgs_mass = [Gf*1000.0/MW if Gf is not None else None for Gf, MW in zip(Gfgs, MWs)]
Sfgs = [(Hfgs[i] - Gfgs[i])*(1.0/298.15) if (Hfgs[i] is not None and Gfgs[i] is not None) else None
for i in range(N)]
Sfgs_mass = [Sf*1000.0/MW if Sf is not None else None for Sf, MW in zip(Sfgs, MWs)]
HeatCapacityGases = [HeatCapacityGas(CASRN=CASs[i], MW=MWs[i], similarity_variable=similarity_variables[i],
**user_chemical_property_lookup(CASs[i], 'HeatCapacityGas')) for i in range(N)]
HeatCapacitySolids = [HeatCapacitySolid(CASRN=CASs[i], MW=MWs[i], similarity_variable=similarity_variables[i],
**user_chemical_property_lookup(CASs[i], 'HeatCapacitySolid')) for i in range(N)]
HeatCapacityLiquids = [HeatCapacityLiquid(CASRN=CASs[i], MW=MWs[i], similarity_variable=similarity_variables[i], Tc=Tcs[i], omega=omegas[i],
Cpgm=HeatCapacityGases[i],
**user_chemical_property_lookup(CASs[i], 'HeatCapacityLiquid')) for i in range(N)]
EnthalpySublimations = [EnthalpySublimation(CASRN=CASs[i], Tm=Tms[i], Tt=Tts[i],
Cpg=HeatCapacityGases[i], Cps=HeatCapacitySolids[i],
Hvap=EnthalpyVaporizations[i], **user_chemical_property_lookup(CASs[i], 'EnthalpySublimation'))
for i in range(N)]
Hsub_Tts = [EnthalpySublimations[i](Tts[i]) if Tts[i] is not None else None
for i in range(N)]
Hsub_Tts_mass = [Hsub*1000.0/MW if Hsub is not None else None for Hsub, MW in zip(Hsub_Tts, MWs)]
combustion_stoichiometries = [combustion_stoichiometry(atoms) for atoms in atomss]
Hcs = [None]*N
for i in range(N):
try:
Hcs[i] = HHV_stoichiometry(combustion_stoichiometries[i], Hf=Hf_STPs[i]) if Hf_STPs[i] is not None else None
except:
pass
Hcs_mass = [Hc*1000.0/MW if Hc is not None else None for Hc, MW in zip(Hcs, MWs)]
Hcs_lower = [LHV_from_HHV(Hcs[i], combustion_stoichiometries[i].get('H2O', 0.0)) if Hcs[i] is not None else None
for i in range(N)]
Hcs_lower_mass = [Hc*1000.0/MW if Hc is not None else None for Hc, MW in zip(Hcs_lower, MWs)]
Tflashs = [T_flash(CAS) for CAS in CASs]
Tautoignitions = [T_autoignition(CAS) for CAS in CASs]
LFLs = [LFL(Hc=Hcs[i], atoms=atomss[i], CASRN=CASs[i]) for i in range(N)]
UFLs = [UFL(Hc=Hcs[i], atoms=atomss[i], CASRN=CASs[i]) for i in range(N)]
TWAs = [TWA(CAS) for CAS in CASs]
STELs = [STEL(CAS) for CAS in CASs]
Skins = [Skin(CAS) for CAS in CASs]
Ceilings = [Ceiling(CAS) for CAS in CASs]
Carcinogens = [Carcinogen(CAS) for CAS in CASs]
# Environmental
GWPs = [GWP(CAS) for CAS in CASs]
ODPs = [ODP(CAS) for CAS in CASs]
logPs = [logP(CAS) for CAS in CASs]
# Analytical
RIs, RI_Ts = [None]*N, [None]*N
for i in range(N):
RIs[i], RI_Ts[i] = RI(CASs[i])
conductivities, conductivity_Ts = [None]*N, [None]*N
for i in range(N):
conductivities[i], conductivity_Ts[i] = conductivity(CASs[i])
Stockmayers = [Stockmayer(Tm=Tms[i], Tb=Tbs[i], Tc=Tcs[i], Zc=Zcs[i], omega=omegas[i], CASRN=CASs[i]) for i in range(N)]
molecular_diameters = [molecular_diameter(Tc=Tcs[i], Pc=Pcs[i], Vc=Vcs[i], Zc=Zcs[i], omega=omegas[i],
Vm=Vml_Tms[i], Vb=Vml_Tbs[i], CASRN=CASs[i]) for i in range(N)]
UNIFAC_group_assignment_DDBST
UNIFAC_groups = []
UNIFAC_Dortmund_groups = []
PSRK_groups = []
for CAS in CASs:
assignment = UNIFAC_group_assignment_DDBST(CAS, 'UNIFAC')
UNIFAC_groups.append(assignment)
assignment = UNIFAC_group_assignment_DDBST(CAS, 'MODIFIED_UNIFAC')
UNIFAC_Dortmund_groups.append(assignment)
assignment = UNIFAC_group_assignment_DDBST(CAS, 'PSRK')
PSRK_groups.append(assignment)
UNIFAC_Rs, UNIFAC_Qs = [None]*N, [None]*N
for i in range(N):
groups = UNIFAC_groups[i]
if groups is not None:
UNIFAC_Rs[i], UNIFAC_Qs[i] = UNIFAC_RQ(groups)
solubility_parameters = [solubility_parameter(T=298.15, Hvapm=Hvap_298s[i], Vml=Vml_STPs[i]) if (Hvap_298s[i] is not None and Vml_STPs[i] is not None) else None
for i in range(N)]
Van_der_Waals_volumes = [Van_der_Waals_volume(UNIFAC_Rs[i]) if UNIFAC_Rs[i] is not None else None for i in range(N)]
Van_der_Waals_areas = [Van_der_Waals_area(UNIFAC_Qs[i]) if UNIFAC_Qs[i] is not None else None for i in range(N)]
SurfaceTensions = [SurfaceTension(CASRN=CASs[i], MW=MWs[i], Tb=Tbs[i], Tc=Tcs[i], Pc=Pcs[i], Vc=Vcs[i], Zc=Zcs[i],
omega=omegas[i], StielPolar=StielPolars[i], Hvap_Tb=Hvap_Tbs[i], Vml=VolumeLiquids[i],
Cpl=HeatCapacityLiquids[i], **user_chemical_property_lookup(CASs[i], 'SurfaceTension'))
for i in range(N)]
sigma_STPs = [SurfaceTensions[i].T_dependent_property(298.15) for i in range(N)]
sigma_Tbs = [SurfaceTensions[i].T_dependent_property(Tbs[i]) if Tbs[i] is not None else None for i in range(N)]
sigma_Tms = [SurfaceTensions[i].T_dependent_property(Tms[i]) if Tms[i] is not None else None for i in range(N)]
Parachors = [None]*N
for i in range(N):
try:
Parachors[i] = Parachor(sigma=sigma_STPs[i], MW=MWs[i], rhol=rhol_STPs_mass[i], rhog=rhog_STPs_mass[i])
except:
pass
atom_fractionss = [atom_fractions(atomss[i]) for i in range(N)]
# Too slow
# economic_statuses = [None]*N#[economic_status(CASs[i], method='Combined') for i in range(N)]
# legal_statuses = [None]*N#[legal_status(CASs[i], method='COMBINED') for i in range(N)]
GWPs = [GWP(CASRN=CASs[i]) for i in range(N)]
ODPs = [ODP(CASRN=CASs[i]) for i in range(N)]
logPs = [logP(CASRN=CASs[i]) for i in range(N)]
constants = ChemicalConstantsPackage(CASs=CASs, names=names, MWs=MWs, Tms=Tms,
Tbs=Tbs, Tcs=Tcs, Pcs=Pcs, Vcs=Vcs, omegas=omegas, Zcs=Zcs,
rhocs=rhocs, rhocs_mass=rhocs_mass, Hfus_Tms=Hfus_Tms,
Hfus_Tms_mass=Hfus_Tms_mass, Hvap_Tbs=Hvap_Tbs,
Hvap_Tbs_mass=Hvap_Tbs_mass,
Vml_STPs=Vml_STPs, rhol_STPs=rhol_STPs, rhol_STPs_mass=rhol_STPs_mass,
Vml_60Fs=Vml_60Fs, rhol_60Fs=rhol_60Fs, rhol_60Fs_mass=rhol_60Fs_mass,
Vmg_STPs=Vmg_STPs, rhog_STPs=rhog_STPs, rhog_STPs_mass=rhog_STPs_mass,
Hfgs=Hfgs, Hfgs_mass=Hfgs_mass, Gfgs=Gfgs, Gfgs_mass=Gfgs_mass,
Sfgs=Sfgs, Sfgs_mass=Sfgs_mass, S0gs=S0gs, S0gs_mass=S0gs_mass,
Hf_STPs=Hf_STPs, Hf_STPs_mass=Hf_STPs_mass,
Tts=Tts, Pts=Pts, Hsub_Tts=Hsub_Tts, Hsub_Tts_mass=Hsub_Tts_mass,
Hcs=Hcs, Hcs_mass=Hcs_mass, Hcs_lower=Hcs_lower, Hcs_lower_mass=Hcs_lower_mass,
Tflashs=Tflashs, Tautoignitions=Tautoignitions, LFLs=LFLs, UFLs=UFLs,
TWAs=TWAs, STELs=STELs, Ceilings=Ceilings, Skins=Skins,
Carcinogens=Carcinogens,
Psat_298s=Psat_298s, Hvap_298s=Hvap_298s, Hvap_298s_mass=Hvap_298s_mass,
Vml_Tms=Vml_Tms, Vms_Tms=Vms_Tms, rhos_Tms=rhos_Tms, rhos_Tms_mass=rhos_Tms_mass,
sigma_STPs=sigma_STPs, sigma_Tbs=sigma_Tbs, sigma_Tms=sigma_Tms,
RIs=RIs, RI_Ts=RI_Ts, conductivities=conductivities,
conductivity_Ts=conductivity_Ts,
charges=charges, dipoles=dipoles, Stockmayers=Stockmayers,
molecular_diameters=molecular_diameters, Van_der_Waals_volumes=Van_der_Waals_volumes,
Van_der_Waals_areas=Van_der_Waals_areas, Parachors=Parachors, StielPolars=StielPolars,
atomss=atomss, atom_fractions=atom_fractionss,
similarity_variables=similarity_variables, phase_STPs=phase_STPs,
UNIFAC_Rs=UNIFAC_Rs, UNIFAC_Qs=UNIFAC_Qs, solubility_parameters=solubility_parameters,
UNIFAC_groups=UNIFAC_groups, UNIFAC_Dortmund_groups=UNIFAC_Dortmund_groups,
PSRK_groups=PSRK_groups,
# Other identifiers
PubChems=PubChems, formulas=formulas, smiless=smiless, InChIs=InChIs,
InChI_Keys=InChI_Keys, aliases=aliases,
# economic_statuses=economic_statuses, legal_statuses=legal_statuses,
GWPs=GWPs, ODPs=ODPs, logPs=logPs,
)
if not correlations:
return constants
SublimationPressures = [SublimationPressure(CASRN=CASs[i], Tt=Tts[i], Pt=Pts[i], Hsub_t=Hsub_Tts[i],
**user_chemical_property_lookup(CASs[i], 'SublimationPressure'))
for i in range(N)]
PermittivityLiquids = [PermittivityLiquid(CASRN=CASs[i], **user_chemical_property_lookup(CASs[i], 'PermittivityLiquid')) for i in range(N)]
ViscosityLiquids = [ViscosityLiquid(CASRN=CASs[i], MW=MWs[i], Tm=Tms[i], Tc=Tcs[i], Pc=Pcs[i], Vc=Vcs[i], omega=omegas[i], Psat=VaporPressures[i],
Vml=VolumeLiquids[i], **user_chemical_property_lookup(CASs[i], 'ViscosityLiquid')) for i in range(N)]
ViscosityGases = [ViscosityGas(CASRN=CASs[i], MW=MWs[i], Tc=Tcs[i], Pc=Pcs[i], Zc=Zcs[i], dipole=dipoles[i],
Vmg=VolumeGases[i], **user_chemical_property_lookup(CASs[i], 'ViscosityGas')) for i in range(N)]
ThermalConductivityLiquids = [ThermalConductivityLiquid(CASRN=CASs[i], MW=MWs[i], Tm=Tms[i], Tb=Tbs[i], Tc=Tcs[i], Pc=Pcs[i],
omega=omegas[i], Hfus=Hfus_Tms[i], **user_chemical_property_lookup(CASs[i], 'ThermalConductivityLiquid'))
for i in range(N)]
ThermalConductivitySolids = [ThermalConductivitySolid(CASRN=CASs[i], **user_chemical_property_lookup(CASs[i], 'ThermalConductivitySolid'))
for i in range(N)]
ThermalConductivityGases =[ThermalConductivityGas(CASRN=CASs[i], MW=MWs[i], Tb=Tbs[i], Tc=Tcs[i], Pc=Pcs[i], Vc=Vcs[i],
Zc=Zcs[i], omega=omegas[i], dipole=dipoles[i], Vmg=VolumeGases[i],
Cpgm=HeatCapacityGases[i], mug=ViscosityGases[i],
**user_chemical_property_lookup(CASs[i], 'ThermalConductivityGas'))
for i in range(N)]
properties = PropertyCorrelationsPackage(constants, VaporPressures=VaporPressures, SublimationPressures=SublimationPressures,
VolumeGases=VolumeGases, VolumeLiquids=VolumeLiquids, VolumeSolids=VolumeSolids,
HeatCapacityGases=HeatCapacityGases, HeatCapacityLiquids=HeatCapacityLiquids, HeatCapacitySolids=HeatCapacitySolids,
ViscosityGases=ViscosityGases, ViscosityLiquids=ViscosityLiquids,
ThermalConductivityGases=ThermalConductivityGases, ThermalConductivityLiquids=ThermalConductivityLiquids,
ThermalConductivitySolids=ThermalConductivitySolids,
EnthalpyVaporizations=EnthalpyVaporizations, EnthalpySublimations=EnthalpySublimations,
SurfaceTensions=SurfaceTensions, PermittivityLiquids=PermittivityLiquids)
return constants, properties
def __init__(self, CASs=None, names=None, MWs=None, Tms=None, Tbs=None,
# Critical state points
Tcs=None, Pcs=None, Vcs=None, omegas=None,
Zcs=None, rhocs=None, rhocs_mass=None,
# Phase change enthalpy
Hfus_Tms=None, Hfus_Tms_mass=None, Hvap_Tbs=None,
Hvap_Tbs_mass=None,
# Standard values
Vml_STPs=None, rhol_STPs=None, rhol_STPs_mass=None,
Vml_60Fs=None, rhol_60Fs=None, rhol_60Fs_mass=None,
Vmg_STPs=None, rhog_STPs=None, rhog_STPs_mass=None,
# Reaction (ideal gas)
Hfgs=None, Hfgs_mass=None, Gfgs=None, Gfgs_mass=None,
Sfgs=None, Sfgs_mass=None, S0gs=None, S0gs_mass=None,
Hf_STPs=None, Hf_STPs_mass=None,
# Triple point
Tts=None, Pts=None, Hsub_Tts=None, Hsub_Tts_mass=None,
# Combustion
Hcs=None, Hcs_mass=None, Hcs_lower=None, Hcs_lower_mass=None,
# Fire safety
Tflashs=None, Tautoignitions=None, LFLs=None, UFLs=None,
# Other safety
TWAs=None, STELs=None, Ceilings=None, Skins=None,
Carcinogens=None, legal_statuses=None, economic_statuses=None,
# Environmental
GWPs=None, ODPs=None, logPs=None,
Psat_298s=None, Hvap_298s=None, Hvap_298s_mass=None,
Vml_Tms=None, rhos_Tms=None, Vms_Tms=None, rhos_Tms_mass=None,
# Analytical
sigma_STPs=None, sigma_Tbs=None, sigma_Tms=None,
RIs=None, RI_Ts=None, conductivities=None,
conductivity_Ts=None,
# Odd constants
charges=None, dipoles=None, Stockmayers=None,
molecular_diameters=None, Van_der_Waals_volumes=None,
Van_der_Waals_areas=None, Parachors=None, StielPolars=None,
atomss=None, atom_fractions=None,
similarity_variables=None, phase_STPs=None,
solubility_parameters=None,
# Other identifiers
PubChems=None, formulas=None, smiless=None, InChIs=None,
InChI_Keys=None, aliases=None,
# Groups
UNIFAC_groups=None, UNIFAC_Dortmund_groups=None,
PSRK_groups=None, UNIFAC_Rs=None, UNIFAC_Qs=None,
):
self.N = N = len(MWs)
self.cmps = range(N)
empty_list = [None]*N
if atom_fractions is None: atom_fractions = empty_list
if atomss is None: atomss = empty_list
if Carcinogens is None: Carcinogens = empty_list
if CASs is None: CASs = empty_list
if aliases is None: aliases = empty_list
if Ceilings is None: Ceilings = empty_list
if charges is None: charges = empty_list
if conductivities is None: conductivities = empty_list
if dipoles is None: dipoles = empty_list
if economic_statuses is None: economic_statuses = empty_list
if formulas is None: formulas = empty_list
if Gfgs is None: Gfgs = empty_list
if Gfgs_mass is None: Gfgs_mass = empty_list
if GWPs is None: GWPs = empty_list
if Hcs is None: Hcs = empty_list
if Hcs_lower is None: Hcs_lower = empty_list
if Hcs_lower_mass is None: Hcs_lower_mass = empty_list
if Hcs_mass is None: Hcs_mass = empty_list
if Hfgs is None: Hfgs = empty_list
if Hfgs_mass is None: Hfgs_mass = empty_list
if Hfus_Tms is None: Hfus_Tms = empty_list
if Hfus_Tms_mass is None: Hfus_Tms_mass = empty_list
if Hsub_Tts is None: Hsub_Tts = empty_list
if Hsub_Tts_mass is None: Hsub_Tts_mass = empty_list
if Hvap_298s is None: Hvap_298s = empty_list
if Hvap_298s_mass is None: Hvap_298s_mass = empty_list
if Hvap_Tbs is None: Hvap_Tbs = empty_list
if Hvap_Tbs_mass is None: Hvap_Tbs_mass = empty_list
if InChI_Keys is None: InChI_Keys = empty_list
if InChIs is None: InChIs = empty_list
if legal_statuses is None: legal_statuses = empty_list
if LFLs is None: LFLs = empty_list
if logPs is None: logPs = empty_list
if molecular_diameters is None: molecular_diameters = empty_list
if names is None: names = empty_list
if ODPs is None: ODPs = empty_list
if omegas is None: omegas = empty_list
if Parachors is None: Parachors = empty_list
if Pcs is None: Pcs = empty_list
if phase_STPs is None: phase_STPs = empty_list
if Psat_298s is None: Psat_298s = empty_list
if PSRK_groups is None: PSRK_groups = empty_list
if Pts is None: Pts = empty_list
if PubChems is None: PubChems = empty_list
if rhocs is None: rhocs = empty_list
if rhocs_mass is None: rhocs_mass = empty_list
if rhol_STPs is None: rhol_STPs = empty_list
if rhol_STPs_mass is None: rhol_STPs_mass = empty_list
if RIs is None: RIs = empty_list
if S0gs is None: S0gs = empty_list
if S0gs_mass is None: S0gs_mass = empty_list
if Sfgs is None: Sfgs = empty_list
if Sfgs_mass is None: Sfgs_mass = empty_list
if similarity_variables is None: similarity_variables = empty_list
if Skins is None: Skins = empty_list
if smiless is None: smiless = empty_list
if STELs is None: STELs = empty_list
if StielPolars is None: StielPolars = empty_list
if Stockmayers is None: Stockmayers = empty_list
if solubility_parameters is None: solubility_parameters = empty_list
if Tautoignitions is None: Tautoignitions = empty_list
if Tbs is None: Tbs = empty_list
if Tcs is None: Tcs = empty_list
if Tflashs is None: Tflashs = empty_list
if Tms is None: Tms = empty_list
if Tts is None: Tts = empty_list
if TWAs is None: TWAs = empty_list
if UFLs is None: UFLs = empty_list
if UNIFAC_Dortmund_groups is None: UNIFAC_Dortmund_groups = empty_list
if UNIFAC_groups is None: UNIFAC_groups = empty_list
if UNIFAC_Rs is None: UNIFAC_Rs = empty_list
if UNIFAC_Qs is None: UNIFAC_Qs = empty_list
if Van_der_Waals_areas is None: Van_der_Waals_areas = empty_list
if Van_der_Waals_volumes is None: Van_der_Waals_volumes = empty_list
if Vcs is None: Vcs = empty_list
if Vml_STPs is None: Vml_STPs = empty_list
if Vml_Tms is None: Vml_Tms = empty_list
if rhos_Tms is None: rhos_Tms = empty_list
if Vms_Tms is None: Vms_Tms = empty_list
if Zcs is None: Zcs = empty_list
if Vml_60Fs is None: Vml_60Fs = empty_list
if rhol_60Fs is None: rhol_60Fs = empty_list
if rhol_60Fs_mass is None: rhol_60Fs_mass = empty_list
if RI_Ts is None: RI_Ts = empty_list
if conductivity_Ts is None: conductivity_Ts = empty_list
if rhos_Tms_mass is None: rhos_Tms_mass = empty_list
if Vmg_STPs is None: Vmg_STPs = empty_list
if rhog_STPs is None: rhog_STPs = empty_list
if rhog_STPs_mass is None: rhog_STPs_mass = empty_list
if sigma_STPs is None: sigma_STPs = empty_list
if sigma_Tbs is None: sigma_Tbs = empty_list
if sigma_Tms is None: sigma_Tms = empty_list
if Hf_STPs is None: Hf_STPs = empty_list
if Hf_STPs_mass is None: Hf_STPs_mass = empty_list
self.atom_fractions = atom_fractions
self.atomss = atomss
self.Carcinogens = Carcinogens
self.CASs = CASs
self.Ceilings = Ceilings
self.charges = charges
self.conductivities = conductivities
self.dipoles = dipoles
self.economic_statuses = economic_statuses
self.formulas = formulas
self.Gfgs = Gfgs
self.Gfgs_mass = Gfgs_mass
self.GWPs = GWPs
self.Hcs = Hcs
self.Hcs_lower = Hcs_lower
self.Hcs_lower_mass = Hcs_lower_mass
self.Hcs_mass = Hcs_mass
self.Hfgs = Hfgs
self.Hfgs_mass = Hfgs_mass
self.Hfus_Tms = Hfus_Tms
self.Hfus_Tms_mass = Hfus_Tms_mass
self.Hsub_Tts = Hsub_Tts
self.Hsub_Tts_mass = Hsub_Tts_mass
self.Hvap_298s = Hvap_298s
self.Hvap_298s_mass = Hvap_298s_mass
self.Hvap_Tbs = Hvap_Tbs
self.Hvap_Tbs_mass = Hvap_Tbs_mass
self.InChI_Keys = InChI_Keys
self.InChIs = InChIs
self.legal_statuses = legal_statuses
self.aliases = aliases
self.LFLs = LFLs
self.logPs = logPs
self.molecular_diameters = molecular_diameters
self.MWs = MWs
self.names = names
self.ODPs = ODPs
self.omegas = omegas
self.Parachors = Parachors
self.Pcs = Pcs
self.phase_STPs = phase_STPs
self.Psat_298s = Psat_298s
self.PSRK_groups = PSRK_groups
self.Pts = Pts
self.PubChems = PubChems
self.rhocs = rhocs
self.rhocs_mass = rhocs_mass
self.rhol_STPs = rhol_STPs
self.rhol_STPs_mass = rhol_STPs_mass
self.RIs = RIs
self.S0gs = S0gs
self.S0gs_mass = S0gs_mass
self.Sfgs = Sfgs
self.Sfgs_mass = Sfgs_mass
self.similarity_variables = similarity_variables
self.solubility_parameters = solubility_parameters
self.Skins = Skins
self.smiless = smiless
self.STELs = STELs
self.StielPolars = StielPolars
self.Stockmayers = Stockmayers
self.Tautoignitions = Tautoignitions
self.Tbs = Tbs
self.Tcs = Tcs
self.Tflashs = Tflashs
self.Tms = Tms
self.Tts = Tts
self.TWAs = TWAs
self.UFLs = UFLs
self.UNIFAC_Dortmund_groups = UNIFAC_Dortmund_groups
self.UNIFAC_groups = UNIFAC_groups
self.UNIFAC_Rs = UNIFAC_Rs
self.UNIFAC_Qs = UNIFAC_Qs
self.Van_der_Waals_areas = Van_der_Waals_areas
self.Van_der_Waals_volumes = Van_der_Waals_volumes
self.Vcs = Vcs
self.Vml_STPs = Vml_STPs
self.Vml_Tms = Vml_Tms
self.rhos_Tms = rhos_Tms
self.Vms_Tms = Vms_Tms
self.Zcs = Zcs
self.Vml_60Fs = Vml_60Fs
self.rhol_60Fs = rhol_60Fs
self.rhol_60Fs_mass = rhol_60Fs_mass
self.conductivity_Ts = conductivity_Ts
self.RI_Ts = RI_Ts
self.rhos_Tms_mass = rhos_Tms_mass
self.Vmg_STPs = Vmg_STPs
self.rhog_STPs = rhog_STPs
self.rhog_STPs_mass = rhog_STPs_mass
self.sigma_STPs = sigma_STPs
self.sigma_Tbs = sigma_Tbs
self.sigma_Tms = sigma_Tms
self.Hf_STPs = Hf_STPs
self.Hf_STPs_mass = Hf_STPs_mass
try:
self.water_index = CASs.index(CAS_H2O)
except ValueError:
self.water_index = None
try:
self.n_atoms = [sum(i.values()) for i in atomss]
except:
self.n_atoms = None
constants_docstrings = {'N': (int, "Number of components in the package", "[-]", None),
'cmps': (range, "Iterator over all components", "[-]", None),
'atom_fractions': ("list[dict]", "Breakdown of each component into its elemental fractions, as a dict", "[-]", None),
'atomss': ("list[dict]", "Breakdown of each component into its elements and their counts, as a dict", "[-]", None),
'Carcinogens': ("list[dict]", "Status of each component in cancer causing registries", "[-]", None),
'CASs': ("list[str]", "CAS registration numbers for each component", "[-]", None),
'Ceilings': ("list[tuple[(float, str)]]", "Ceiling exposure limits to chemicals (and their units; ppm or mg/m^3)", "[various]", None),
'charges': ("list[float]", "Charge number (valence) for each component", "[-]", None),
'conductivities': ("list[float]", "Electrical conductivities for each component", "[S/m]", None),
'conductivity_Ts': ("list[float]", "Temperatures at which the electrical conductivities for each component were measured", "[K]", None),
'dipoles': ("list[float]", "Dipole moments for each component", "[debye]", None),
'economic_statuses': ("list[dict]", "Status of each component in in relation to import and export from various regions", "[-]", None),
'formulas': ("list[str]", "Formulas of each component", "[-]", None),
'Gfgs': ("list[float]", "Ideal gas standard molar Gibbs free energy of formation for each component", "[J/mol]", None),
'Gfgs_mass': ("list[float]", "Ideal gas standard Gibbs free energy of formation for each component", "[J/kg]", None),
'GWPs': ("list[float]", "Global Warming Potentials for each component (impact/mass chemical)/(impact/mass CO2)", "[-]", None),
'Hcs': ("list[float]", "Higher standard molar heats of combustion for each component", "[J/mol]", None),
'Hcs_mass': ("list[float]", "Higher standard heats of combustion for each component", "[J/kg]", None),
'Hcs_lower': ("list[float]", "Lower standard molar heats of combustion for each component", "[J/mol]", None),
'Hcs_lower_mass': ("list[float]", "Lower standard heats of combustion for each component", "[J/kg]", None),
'Hfgs': ("list[float]", "Ideal gas standard molar enthalpies of formation for each component", "[J/mol]", None),
'Hfgs_mass': ("list[float]", "Ideal gas standard enthalpies of formation for each component", "[J/kg]", None),
'Hfus_Tms': ("list[float]", "Molar heats of fusion for each component at their respective melting points", "[J/mol]", None),
'Hfus_Tms_mass': ("list[float]", "Heats of fusion for each component at their respective melting points", "[J/kg]", None),
'Hsub_Tts': ("list[float]", "Heats of sublimation for each component at their respective triple points", "[J/mol]", None),
'Hsub_Tts_mass': ("list[float]", "Heats of sublimation for each component at their respective triple points", "[J/kg]", None),
'Hvap_298s': ("list[float]", "Molar heats of vaporization for each component at 298.15 K", "[J/mol]", None),
'Hvap_298s_mass': ("list[float]", "Heats of vaporization for each component at 298.15 K", "[J/kg]", None),
'Hvap_Tbs': ("list[float]", "Molar heats of vaporization for each component at their respective normal boiling points", "[J/mol]", None),
'Hvap_Tbs_mass': ("list[float]", "Heats of vaporization for each component at their respective normal boiling points", "[J/kg]", None),
'InChI_Keys': ("list[str]", "InChI Keys for each component", "[-]", None),
'InChIs': ("list[str]", "InChI strings for each component", "[-]", None),
'legal_statuses': ("list[dict]", "Status of each component in in relation to import and export rules from various regions", "[-]", None),
'LFLs': ("list[float]", "Lower flammability limits for each component", "[-]", None),
'logPs': ("list[float]", "Octanol-water partition coefficients for each component", "[-]", None),
'molecular_diameters': ("list[float]", "Lennard-Jones molecular diameters for each component", "[angstrom]", None),
'MWs': ("list[float]", "Molecular weights for each component", "[g/mol]", None),
'names': ("list[str]", "Names for each component", "[-]", None),
'aliases': ("list[str]", "Aliases for each component", "[-]", None),
'ODPs': ("list[float]", "Ozone Depletion Potentials for each component (impact/mass chemical)/(impact/mass CFC-11)", "[-]", None),
'omegas': ("list[float]", "Acentric factors for each component", "[-]", None),
'Parachors': ("list[float]", "Parachors for each component", "[N^0.25*m^2.75/mol]", None),
'Pcs': ("list[float]", "Critical pressures for each component", "[Pa]", None),
'phase_STPs': ("list[str]", "Standard states ('g', 'l', or 's') for each component", "[-]", None),
'Psat_298s': ("list[float]", "Vapor pressures for each component at 298.15 K", "[Pa]", None),
'PSRK_groups': ("list[dict]", "PSRK subgroup: count groups for each component", "[-]", None),
'Pts': ("list[float]", "Triple point pressures for each component", "[Pa]", None),
'PubChems': ("list[int]", "Pubchem IDs for each component", "[-]", None),
'rhocs': ("list[float]", "Molar densities at the critical point for each component", "[mol/m^3]", None),
'rhocs_mass': ("list[float]", "Densities at the critical point for each component", "[kg/m^3]", None),
'rhol_STPs': ("list[float]", "Molar liquid densities at STP for each component", "[mol/m^3]", None),
'rhol_STPs_mass': ("list[float]", "Liquid densities at STP for each component", "[kg/m^3]", None),
'RIs': ("list[float]", "Refractive indexes for each component", "[-]", None),
'RI_Ts': ("list[float]", "Temperatures at which the refractive indexes were reported for each component", "[K]", None),
'S0gs': ("list[float]", "Ideal gas absolute molar entropies at 298.15 K at 1 atm for each component", "[J/(mol*K)]", None),
'S0gs_mass': ("list[float]", "Ideal gas absolute entropies at 298.15 K at 1 atm for each component", "[J/(kg*K)]", None),
'Sfgs': ("list[float]", "Ideal gas standard molar entropies of formation for each component", "[J/(mol*K)]", None),
'Sfgs_mass': ("list[float]", "Ideal gas standard entropies of formation for each component", "[J/(kg*K)]", None),
'solubility_parameters': ("list[float]", "Solubility parameters for each component at 298.15 K", "[Pa^0.5]", None),
'similarity_variables': ("list[float]", "Similarity variables for each component", "[mol/g]", None),
'Skins': ("list[bool]", "Whether each compound can be absorbed through the skin or not", "[-]", None),
'smiless': ("list[str]", "SMILES identifiers for each component", "[-]", None),
'STELs': ("list[tuple[(float, str)]]", "Short term exposure limits to chemicals (and their units; ppm or mg/m^3)", "[various]", None),
'StielPolars': ("list[float]", "Stiel polar factors for each component", "[-]", None),
'Stockmayers': ("list[float]", "Lennard-Jones Stockmayer parameters (depth of potential-energy minimum over k) for each component", "[K]", None),
'Tautoignitions': ("list[float]", "Autoignition temperatures for each component", "[K]", None),
'Tbs': ("list[float]", "Boiling temperatures for each component", "[K]", None),
'Tcs': ("list[float]", "Critical temperatures for each component", "[K]", None),
'Tms': ("list[float]", "Melting temperatures for each component", "[K]", None),
'Tflashs': ("list[float]", "Flash point temperatures for each component", "[K]", None),
'Tts': ("list[float]", "Triple point temperatures for each component", "[K]", None),
'TWAs': ("list[tuple[(float, str)]]", "Time-weighted average exposure limits to chemicals (and their units; ppm or mg/m^3)", "[various]", None),
'UFLs': ("list[float]", "Upper flammability limits for each component", "[-]", None),
'UNIFAC_Dortmund_groups': ("list[dict]", "UNIFAC_Dortmund_group: count groups for each component", "[-]", None),
'UNIFAC_groups': ("list[dict]", "UNIFAC_group: count groups for each component", "[-]", None),
'UNIFAC_Rs': ("list[float]", "UNIFAC `R` parameters for each component", "[-]", None),
'UNIFAC_Qs': ("list[float]", "UNIFAC `Q` parameters for each component", "[-]", None),
'Van_der_Waals_areas': ("list[float]", "Unnormalized Van der Waals areas for each component", "[m^2/mol]", None),
'Van_der_Waals_volumes': ("list[float]", "Unnormalized Van der Waals volumes for each component", "[m^3/mol]", None),
'Vcs': ("list[float]", "Critical molar volumes for each component", "[m^3/mol]", None),
'Vml_STPs': ("list[float]", "Liquid molar volumes for each component at STP", "[m^3/mol]", None),
'Vml_Tms': ("list[float]", "Liquid molar volumes for each component at their respective melting points", "[m^3/mol]", None),
'Vms_Tms': ("list[float]", "Solid molar volumes for each component at their respective melting points", "[m^3/mol]", None),
'Vml_60Fs': ("list[float]", "Liquid molar volumes for each component at 60 °F", "[m^3/mol]", None),
'rhos_Tms': ("list[float]", "Solid molar densities for each component at their respective melting points", "[mol/m^3]", None),
'rhol_60Fs': ("list[float]", "Liquid molar densities for each component at 60 °F", "[mol/m^3]", None),
'rhol_60Fs_mass': ("list[float]", "Liquid mass densities for each component at 60 °F", "[kg/m^3]", None),
'rhos_Tms_mass': ("list[float]", "Solid mass densities for each component at their melting point", "[kg/m^3]", None),
'Zcs': ("list[float]", "Critical compressibilities for each component", "[-]", None),
'n_atoms': ("int", "Number of total atoms in a collection of 1 molecule of each species", "[-]", None),
'water_index': ("int", "Index of water in the package", "[-]", None),
'Vmg_STPs': ("list[float]", "Gas molar volumes for each component at STP; metastable if normally another state", "[m^3/mol]", None),
'rhog_STPs': ("list[float]", "Molar gas densities at STP for each component; metastable if normally another state", "[mol/m^3]", None),
'rhog_STPs_mass': ("list[float]", "Gas densities at STP for each component; metastable if normally another state", "[kg/m^3]", None),
'sigma_STPs': ("list[float]", "Liquid-air surface tensions at 298.15 K and the higher of 101325 Pa or the saturation pressure", "[N/m]", None),
'sigma_Tms': ("list[float]", "Liquid-air surface tensions at the melting point and 101325 Pa", "[N/m]", None),
'sigma_Tbs': ("list[float]", "Liquid-air surface tensions at the normal boiling point and 101325 Pa", "[N/m]", None),
'Hf_STPs': ("list[float]", "Standard state molar enthalpies of formation for each component", "[J/mol]", None),
'Hf_STPs_mass': ("list[float]", "Standard state mass enthalpies of formation for each component", "[J/kg]", None),
}
constants_doc = r"""Class for storing efficiently chemical constants for a
group of components. This is intended as a base
object from which a set of thermodynamic methods can access miscellaneous for
purposes such as phase identification or initialization.
Examples
--------
Create a package with water and the xylenes, suitable for use with equations of
state:
>>> ChemicalConstantsPackage(MWs=[18.01528, 106.165, 106.165, 106.165], names=['water', 'o-xylene', 'p-xylene', 'm-xylene'], omegas=[0.344, 0.3118, 0.324, 0.331], Pcs=[22048320.0, 3732000.0, 3511000.0, 3541000.0], Tcs=[647.14, 630.3, 616.2, 617.0])
ChemicalConstantsPackage(MWs=[18.01528, 106.165, 106.165, 106.165], names=['water', 'o-xylene', 'p-xylene', 'm-xylene'], omegas=[0.344, 0.3118, 0.324, 0.331], Pcs=[22048320.0, 3732000.0, 3511000.0, 3541000.0], Tcs=[647.14, 630.3, 616.2, 617.0])
Notes
-----
All parameters are also attributes.
Parameters
----------
"""
for name, (var_type, desc, units, return_desc) in constants_docstrings.items():
type_name = var_type if type(var_type) is str else var_type.__name__
new = f"""{name} : {type_name}
{desc}, {units}.
"""
constants_doc += new
try:
ChemicalConstantsPackage.__doc__ = constants_doc
except:
pass # py2
#print(constants_doc)
properties_to_classes = {'VaporPressures': VaporPressure,
'VolumeLiquids': VolumeLiquid,
'VolumeGases': VolumeGas,
'VolumeSolids': VolumeSolid,
'HeatCapacityGases': HeatCapacityGas,
'HeatCapacitySolids': HeatCapacitySolid,
'HeatCapacityLiquids': HeatCapacityLiquid,
'EnthalpyVaporizations': EnthalpyVaporization,
'EnthalpySublimations': EnthalpySublimation,
'SublimationPressures': SublimationPressure,
'PermittivityLiquids': PermittivityLiquid,
'ViscosityLiquids': ViscosityLiquid,
'ViscosityGases': ViscosityGas,
'ThermalConductivityLiquids': ThermalConductivityLiquid,
'ThermalConductivitySolids': ThermalConductivitySolid,
'ThermalConductivityGases': ThermalConductivityGas,
'SurfaceTensions': SurfaceTension}
classes_to_properties = {v:k for k, v in properties_to_classes.items()}
mix_properties_to_classes = {'VolumeGasMixture': VolumeGasMixture,
'VolumeLiquidMixture': VolumeLiquidMixture,
'VolumeSolidMixture': VolumeSolidMixture,
'HeatCapacityGasMixture': HeatCapacityGasMixture,
'HeatCapacityLiquidMixture': HeatCapacityLiquidMixture,
'HeatCapacitySolidMixture': HeatCapacitySolidMixture,
'ViscosityGasMixture': ViscosityGasMixture,
'ViscosityLiquidMixture': ViscosityLiquidMixture,
'ThermalConductivityGasMixture': ThermalConductivityGasMixture,
'ThermalConductivityLiquidMixture': ThermalConductivityLiquidMixture,
'SurfaceTensionMixture': SurfaceTensionMixture}
[docs]class PropertyCorrelationsPackage:
r'''Class for creating and storing `T` and `P` and `zs` dependent chemical
property objects. All parameters are also attributes.
This object can be used either to hold already-created property objects;
or to create new ones and hold them.
Parameters
----------
constants : :obj:`ChemicalConstantsPackage`
Object holding all constant properties, [-]
VaporPressures : list[:obj:`thermo.vapor_pressure.VaporPressure`], optional
Objects holding vapor pressure data and methods, [-]
SublimationPressures : list[:obj:`thermo.vapor_pressure.SublimationPressure`], optional
Objects holding sublimation pressure data and methods, [-]
VolumeGases : list[:obj:`thermo.volume.VolumeGas`], optional
Objects holding gas volume data and methods, [-]
VolumeLiquids : list[:obj:`thermo.volume.VolumeLiquid`], optional
Objects holding liquid volume data and methods, [-]
VolumeSolids : list[:obj:`thermo.volume.VolumeSolid`], optional
Objects holding solid volume data and methods, [-]
HeatCapacityGases : list[:obj:`thermo.heat_capacity.HeatCapacityGas`], optional
Objects holding gas heat capacity data and methods, [-]
HeatCapacityLiquids : list[:obj:`thermo.heat_capacity.HeatCapacityLiquid`], optional
Objects holding liquid heat capacity data and methods, [-]
HeatCapacitySolids : list[:obj:`thermo.heat_capacity.HeatCapacitySolid`], optional
Objects holding solid heat capacity data and methods, [-]
ViscosityGases : list[:obj:`thermo.viscosity.ViscosityGas`], optional
Objects holding gas viscosity data and methods, [-]
ViscosityLiquids : list[:obj:`thermo.viscosity.ViscosityLiquid`], optional
Objects holding liquid viscosity data and methods, [-]
ThermalConductivityGases : list[:obj:`thermo.thermal_conductivity.ThermalConductivityGas`], optional
Objects holding gas thermal conductivity data and methods, [-]
ThermalConductivityLiquids : list[:obj:`thermo.thermal_conductivity.ThermalConductivityLiquid`], optional
Objects holding liquid thermal conductivity data and methods, [-]
ThermalConductivitySolids : list[:obj:`thermo.thermal_conductivity.ThermalConductivitySolid`], optional
Objects holding solid thermal conductivity data and methods, [-]
EnthalpyVaporizations : list[:obj:`thermo.phase_change.EnthalpyVaporization`], optional
Objects holding enthalpy of vaporization data and methods, [-]
EnthalpySublimations : list[:obj:`thermo.phase_change.EnthalpySublimation`], optional
Objects holding enthalpy of sublimation data and methods, [-]
SurfaceTensions : list[:obj:`thermo.interface.SurfaceTension`], optional
Objects holding surface tension data and methods, [-]
PermittivityLiquids : list[:obj:`thermo.permittivity.PermittivityLiquid`], optional
Objects holding permittivity data and methods, [-]
skip_missing : bool, optional
If False, any properties not provided will have objects created; if
True, no extra objects will be created.
VolumeSolidMixture : :obj:`thermo.volume.VolumeSolidMixture`, optional
Predictor object for the volume of solid mixtures, [-]
VolumeLiquidMixture : :obj:`thermo.volume.VolumeLiquidMixture`, optional
Predictor object for the volume of liquid mixtures, [-]
VolumeGasMixture : :obj:`thermo.volume.VolumeGasMixture`, optional
Predictor object for the volume of gas mixtures, [-]
HeatCapacityLiquidMixture : :obj:`thermo.heat_capacity.HeatCapacityLiquidMixture`, optional
Predictor object for the heat capacity of liquid mixtures, [-]
HeatCapacityGasMixture : :obj:`thermo.heat_capacity.HeatCapacityGasMixture`, optional
Predictor object for the heat capacity of gas mixtures, [-]
HeatCapacitySolidMixture : :obj:`thermo.heat_capacity.HeatCapacitySolidMixture`, optional
Predictor object for the heat capacity of solid mixtures, [-]
ViscosityLiquidMixture : :obj:`thermo.viscosity.ViscosityLiquidMixture`, optional
Predictor object for the viscosity of liquid mixtures, [-]
ViscosityGasMixture : :obj:`thermo.viscosity.ViscosityGasMixture`, optional
Predictor object for the viscosity of gas mixtures, [-]
ThermalConductivityLiquidMixture : :obj:`thermo.thermal_conductivity.ThermalConductivityLiquidMixture`, optional
Predictor object for the thermal conductivity of liquid mixtures, [-]
ThermalConductivityGasMixture : :obj:`thermo.thermal_conductivity.ThermalConductivityGasMixture`, optional
Predictor object for the thermal conductivity of gas mixtures, [-]
SurfaceTensionMixture : :obj:`thermo.interface.SurfaceTensionMixture`, optional
Predictor object for the surface tension of liquid mixtures, [-]
Attributes
----------
pure_correlations : tuple(str)
List of all pure component property objects, [-]
Examples
--------
Create a package from CO2 and n-hexane, with ideal-gas heat capacities
provided while excluding all other properties:
>>> constants = ChemicalConstantsPackage(CASs=['124-38-9', '110-54-3'], MWs=[44.0095, 86.17536], names=['carbon dioxide', 'hexane'], omegas=[0.2252, 0.2975], Pcs=[7376460.0, 3025000.0], Tbs=[194.67, 341.87], Tcs=[304.2, 507.6], Tms=[216.65, 178.075])
>>> correlations = PropertyCorrelationsPackage(constants=constants, skip_missing=True, HeatCapacityGases=[HeatCapacityGas(poly_fit=(50.0, 1000.0, [-3.1115474168865828e-21, 1.39156078498805e-17, -2.5430881416264243e-14, 2.4175307893014295e-11, -1.2437314771044867e-08, 3.1251954264658904e-06, -0.00021220221928610925, 0.000884685506352987, 29.266811602924644])), HeatCapacityGas(poly_fit=(200.0, 1000.0, [1.3740654453881647e-21, -8.344496203280677e-18, 2.2354782954548568e-14, -3.4659555330048226e-11, 3.410703030634579e-08, -2.1693611029230923e-05, 0.008373280796376588, -1.356180511425385, 175.67091124888998]))])
Create a package from various data files, creating all property objects:
>>> correlations = PropertyCorrelationsPackage(constants=constants, skip_missing=False)
'''
pure_correlations = ('VaporPressures', 'VolumeLiquids', 'VolumeGases',
'VolumeSolids', 'HeatCapacityGases', 'HeatCapacitySolids',
'HeatCapacityLiquids', 'EnthalpyVaporizations',
'EnthalpySublimations', 'SublimationPressures',
'PermittivityLiquids', 'ViscosityLiquids', 'ViscosityGases',
'ThermalConductivityLiquids', 'ThermalConductivityGases',
'ThermalConductivitySolids',
'SurfaceTensions')
mixture_correlations = ('VolumeGasMixture', 'VolumeLiquidMixture', 'VolumeSolidMixture',
'HeatCapacityGasMixture', 'HeatCapacityLiquidMixture',
'HeatCapacitySolidMixture', 'ViscosityGasMixture',
'ViscosityLiquidMixture', 'ThermalConductivityGasMixture',
'ThermalConductivityLiquidMixture', 'SurfaceTensionMixture')
correlations = pure_correlations + mixture_correlations
# __slots__ = correlations + ('constants', 'skip_missing')
json_version = 1
non_json_attributes = []
obj_references = correlations + ('constants',)
vectorized = False
__full_path__ = f"{__module__}.{__qualname__}"
def __eq__(self, other):
return self.__hash__() == hash(other)
def __hash__(self):
hashes = []
for k in self.correlations:
# print('hashing', hash_any_primitive(getattr(self, k)), getattr(self, k))
hashes.append(hash_any_primitive(getattr(self, k)))
return hash_any_primitive(hashes)
def __repr__(self):
return self._make_str()
def _make_str(self, delim=', ', correlations=None):
'''Method to create a new string representing the
object.
'''
if correlations is None:
correlations = self.correlations
s = 'PropertyCorrelationsPackage('
for k in correlations:
obj = getattr(self, k)
if obj is None:
continue
if isinstance(obj, MixtureProperty):
s += f'{k}Obj={obj}{delim}\n'
elif any(i is not None for i in obj):
s += f'{k}={obj}{delim}\n'
s += f'constants={self.constants}{delim}\n'
s += f'skip_missing={self.skip_missing}{delim}'
s = s[:-2] + ')'
return s
def as_json(self, cache=None, option=0):
r'''Method to create a JSON friendly serialization of the chemical
properties package which can be stored, and reloaded later.
Returns
-------
json_repr : dict
JSON-friendly representation, [-]
Notes
-----
Examples
--------
'''
return JsonOptEncodable.as_json(self, cache, option)
@classmethod
def from_json(cls, json_repr, cache=None):
r'''Method to create a :obj:`PropertyCorrelationsPackage` from a JSON
serialization of another :obj:`PropertyCorrelationsPackage`.
Parameters
----------
json_repr : dict
JSON-friendly representation, [-]
Returns
-------
correlations : :obj:`PropertyCorrelationsPackage`
Newly created object from the json serialization, [-]
Notes
-----
It is important that the input string be in the same format as that
created by :obj:`PropertyCorrelationsPackage.as_json`.
Examples
--------
'''
return JsonOptEncodable.from_json(json_repr, cache)
[docs] def __add__(self, b):
r'''Method to create a new :obj:`PropertyCorrelationsPackage` object
from two other :obj:`PropertyCorrelationsPackage` objects.
Returns
-------
new : :obj:`PropertyCorrelationsPackage`
New object, [-]
Notes
-----
Examples
--------
>>> a = ChemicalConstantsPackage.correlations_from_IDs(IDs=['water', 'hexane'])
>>> b = ChemicalConstantsPackage.correlations_from_IDs(IDs=['toluene'])
>>> c = a + b
'''
if not isinstance(b, PropertyCorrelationsPackage):
raise TypeError('Adding to a PropertyCorrelationsPackage requires that the other object '
'also be a PropertyCorrelationsPackage.')
a = self
mixture_correlations = self.mixture_correlations
a_dict = a.__dict__
b_dict = b.__dict__
kwargs = {}
for k in a_dict.keys():
if k not in mixture_correlations:
kwargs[k] = a_dict[k] + b_dict[k]
return PropertyCorrelationsPackage(**kwargs)
[docs] def subset(self, idxs):
r'''Method to construct a new PropertyCorrelationsPackage that removes
all components not specified in the `idxs` argument.
Parameters
----------
idxs : list[int] or Slice or None
Indexes of components that should be included; if None, all
components will be included , [-]
Returns
-------
subset_correlations : PropertyCorrelationsPackage
Object with components, [-]
Notes
-----
'''
is_slice = isinstance(idxs, slice)
def atindexes(values):
if is_slice:
return values[idxs]
return [values[i] for i in idxs]
new = {'constants': self.constants.subset(idxs)}
for p in self.pure_correlations:
if hasattr(self, p):
v = getattr(self, p)
if v is not None:
new[p] = atindexes(v)
return PropertyCorrelationsPackage(skip_missing=self.skip_missing, **new)
def __init__(self, constants, VaporPressures=None, SublimationPressures=None,
VolumeGases=None, VolumeLiquids=None, VolumeSolids=None,
HeatCapacityGases=None, HeatCapacityLiquids=None, HeatCapacitySolids=None,
ViscosityGases=None, ViscosityLiquids=None,
ThermalConductivityGases=None, ThermalConductivityLiquids=None,
ThermalConductivitySolids=None,
EnthalpyVaporizations=None, EnthalpySublimations=None,
SurfaceTensions=None, PermittivityLiquids=None,
VolumeGasMixtureObj=None, VolumeLiquidMixtureObj=None, VolumeSolidMixtureObj=None,
HeatCapacityGasMixtureObj=None, HeatCapacityLiquidMixtureObj=None, HeatCapacitySolidMixtureObj=None,
ViscosityGasMixtureObj=None, ViscosityLiquidMixtureObj=None,
ThermalConductivityGasMixtureObj=None, ThermalConductivityLiquidMixtureObj=None,
SurfaceTensionMixtureObj=None, skip_missing=False,
):
self.constants = constants
self.skip_missing = skip_missing
cmps = constants.cmps
if VaporPressures is None and not skip_missing:
VaporPressures = [VaporPressure(Tb=constants.Tbs[i], Tc=constants.Tcs[i], Pc=constants.Pcs[i],
omega=constants.omegas[i], CASRN=constants.CASs[i],
**user_chemical_property_lookup(constants.CASs[i], 'VaporPressure'))
for i in cmps]
if VolumeLiquids is None and not skip_missing:
VolumeLiquids = [VolumeLiquid(MW=constants.MWs[i], Tb=constants.Tbs[i], Tc=constants.Tcs[i],
Pc=constants.Pcs[i], Vc=constants.Vcs[i], Zc=constants.Zcs[i], omega=constants.omegas[i],
dipole=constants.dipoles[i],
Psat=VaporPressures[i],
**user_chemical_property_lookup(constants.CASs[i], 'VolumeLiquid'),
eos=None, CASRN=constants.CASs[i])
for i in cmps]
if VolumeGases is None and not skip_missing:
VolumeGases = [VolumeGas(MW=constants.MWs[i], Tc=constants.Tcs[i], Pc=constants.Pcs[i],
omega=constants.omegas[i], dipole=constants.dipoles[i],
eos=None, CASRN=constants.CASs[i])
for i in cmps]
if VolumeSolids is None and not skip_missing:
VolumeSolids = [VolumeSolid(CASRN=constants.CASs[i], MW=constants.MWs[i],
Tt=constants.Tts[i], Vml_Tt=constants.Vml_Tms[i])
for i in cmps]
if HeatCapacityGases is None and not skip_missing:
HeatCapacityGases = [HeatCapacityGas(CASRN=constants.CASs[i], MW=constants.MWs[i],
similarity_variable=constants.similarity_variables[i],
**user_chemical_property_lookup(constants.CASs[i], 'HeatCapacityGas'))
for i in cmps]
if HeatCapacitySolids is None and not skip_missing:
HeatCapacitySolids = [HeatCapacitySolid(MW=constants.MWs[i], similarity_variable=constants.similarity_variables[i],
CASRN=constants.CASs[i], **user_chemical_property_lookup(constants.CASs[i], 'HeatCapacitySolid'))
for i in cmps]
if HeatCapacityLiquids is None and not skip_missing:
HeatCapacityLiquids = [HeatCapacityLiquid(CASRN=constants.CASs[i], MW=constants.MWs[i],
similarity_variable=constants.similarity_variables[i],
Tc=constants.Tcs[i], omega=constants.omegas[i],
Cpgm=HeatCapacityGases[i], **user_chemical_property_lookup(constants.CASs[i], 'HeatCapacityLiquid'))
for i in cmps]
if EnthalpyVaporizations is None and not skip_missing:
EnthalpyVaporizations = [EnthalpyVaporization(CASRN=constants.CASs[i], Tb=constants.Tbs[i],
Tc=constants.Tcs[i], Pc=constants.Pcs[i], omega=constants.omegas[i],
similarity_variable=constants.similarity_variables[i],
**user_chemical_property_lookup(constants.CASs[i], 'EnthalpyVaporization'))
for i in cmps]
if EnthalpySublimations is None and not skip_missing:
EnthalpySublimations = [EnthalpySublimation(CASRN=constants.CASs[i], Tm=constants.Tms[i], Tt=constants.Tts[i],
Cpg=HeatCapacityGases[i], Cps=HeatCapacitySolids[i],
Hvap=EnthalpyVaporizations[i])
for i in cmps]
if SublimationPressures is None and not skip_missing:
SublimationPressures = [SublimationPressure(CASRN=constants.CASs[i], Tt=constants.Tts[i], Pt=constants.Pts[i],
Hsub_t=constants.Hsub_Tts[i])
for i in cmps]
if PermittivityLiquids is None and not skip_missing:
PermittivityLiquids = [PermittivityLiquid(CASRN=constants.CASs[i]) for i in cmps]
# missing - ThermalConductivityGas, SurfaceTension
if ViscosityLiquids is None and not skip_missing:
ViscosityLiquids = [ViscosityLiquid(CASRN=constants.CASs[i], MW=constants.MWs[i], Tm=constants.Tms[i],
Tc=constants.Tcs[i], Pc=constants.Pcs[i], Vc=constants.Vcs[i],
omega=constants.omegas[i], Psat=VaporPressures[i],
Vml=VolumeLiquids[i])
for i in cmps]
if ViscosityGases is None and not skip_missing:
ViscosityGases = [ViscosityGas(CASRN=constants.CASs[i], MW=constants.MWs[i], Tc=constants.Tcs[i],
Pc=constants.Pcs[i], Zc=constants.Zcs[i], dipole=constants.dipoles[i],
Vmg=VolumeGases[i]) # Vmg is not currently used actually
for i in cmps]
if ThermalConductivityLiquids is None and not skip_missing:
ThermalConductivityLiquids = [ThermalConductivityLiquid(CASRN=constants.CASs[i], MW=constants.MWs[i],
Tm=constants.Tms[i], Tb=constants.Tbs[i],
Tc=constants.Tcs[i], Pc=constants.Pcs[i],
omega=constants.omegas[i], Hfus=constants.Hfus_Tms[i])
for i in cmps]
if ThermalConductivitySolids is None and not skip_missing:
ThermalConductivitySolids = [ThermalConductivitySolid(CASRN=constants.CASs[i]) for i in cmps]
if ThermalConductivityGases is None and not skip_missing:
ThermalConductivityGases = [ThermalConductivityGas(CASRN=constants.CASs[i], MW=constants.MWs[i], Tb=constants.Tbs[i],
Tc=constants.Tcs[i], Pc=constants.Pcs[i], Vc=constants.Vcs[i],
Zc=constants.Zcs[i], omega=constants.omegas[i], dipole=constants.dipoles[i],
Vmg=VolumeGases[i], mug=ViscosityLiquids[i],
Cpgm=HeatCapacityGases[i])
for i in cmps]
if SurfaceTensions is None and not skip_missing:
SurfaceTensions = [SurfaceTension(CASRN=constants.CASs[i], MW=constants.MWs[i], Tb=constants.Tbs[i],
Tc=constants.Tcs[i], Pc=constants.Pcs[i], Vc=constants.Vcs[i],
Zc=constants.Zcs[i], omega=constants.omegas[i], StielPolar=constants.StielPolars[i],
Hvap_Tb=constants.Hvap_Tbs[i], Vml=VolumeLiquids[i],
Cpl=HeatCapacityLiquids[i])
for i in cmps]
self.VaporPressures = VaporPressures
self.VolumeLiquids = VolumeLiquids
self.VolumeGases = VolumeGases
self.VolumeSolids = VolumeSolids
self.HeatCapacityGases = HeatCapacityGases
self.HeatCapacitySolids = HeatCapacitySolids
self.HeatCapacityLiquids = HeatCapacityLiquids
self.EnthalpyVaporizations = EnthalpyVaporizations
self.EnthalpySublimations = EnthalpySublimations
self.SublimationPressures = SublimationPressures
self.PermittivityLiquids = PermittivityLiquids
self.ViscosityLiquids = ViscosityLiquids
self.ViscosityGases = ViscosityGases
self.ThermalConductivityLiquids = ThermalConductivityLiquids
self.ThermalConductivityGases = ThermalConductivityGases
self.ThermalConductivitySolids = ThermalConductivitySolids
self.SurfaceTensions = SurfaceTensions
# Mixture objects
if VolumeSolidMixtureObj is None and not skip_missing:
VolumeSolidMixtureObj = VolumeSolidMixture(CASs=constants.CASs, MWs=constants.MWs, VolumeSolids=VolumeSolids)
if VolumeLiquidMixtureObj is None and not skip_missing:
VolumeLiquidMixtureObj = VolumeLiquidMixture(MWs=constants.MWs, Tcs=constants.Tcs, Pcs=constants.Pcs, Vcs=constants.Vcs, Zcs=constants.Zcs, omegas=constants.omegas, CASs=constants.CASs, VolumeLiquids=VolumeLiquids)
if VolumeGasMixtureObj is None and not skip_missing:
VolumeGasMixtureObj = VolumeGasMixture(eos=None, MWs=constants.MWs, CASs=constants.CASs, VolumeGases=VolumeGases)
if HeatCapacityLiquidMixtureObj is None and not skip_missing:
HeatCapacityLiquidMixtureObj = HeatCapacityLiquidMixture(MWs=constants.MWs, CASs=constants.CASs, HeatCapacityLiquids=HeatCapacityLiquids)
if HeatCapacityGasMixtureObj is None and not skip_missing:
HeatCapacityGasMixtureObj = HeatCapacityGasMixture(MWs=constants.MWs, CASs=constants.CASs, HeatCapacityGases=HeatCapacityGases)
if HeatCapacitySolidMixtureObj is None and not skip_missing:
HeatCapacitySolidMixtureObj = HeatCapacitySolidMixture(MWs=constants.MWs, CASs=constants.CASs, HeatCapacitySolids=HeatCapacitySolids)
if ViscosityLiquidMixtureObj is None and not skip_missing:
ViscosityLiquidMixtureObj = ViscosityLiquidMixture(MWs=constants.MWs, CASs=constants.CASs, ViscosityLiquids=ViscosityLiquids)
if ViscosityGasMixtureObj is None and not skip_missing:
ViscosityGasMixtureObj = ViscosityGasMixture(MWs=constants.MWs, molecular_diameters=constants.molecular_diameters, Stockmayers=constants.Stockmayers, CASs=constants.CASs, ViscosityGases=ViscosityGases)
if ThermalConductivityLiquidMixtureObj is None and not skip_missing:
ThermalConductivityLiquidMixtureObj = ThermalConductivityLiquidMixture(CASs=constants.CASs, MWs=constants.MWs, ThermalConductivityLiquids=ThermalConductivityLiquids)
if ThermalConductivityGasMixtureObj is None and not skip_missing:
ThermalConductivityGasMixtureObj = ThermalConductivityGasMixture(MWs=constants.MWs, Tbs=constants.Tbs, CASs=constants.CASs, ThermalConductivityGases=ThermalConductivityGases, ViscosityGases=ViscosityGases)
if SurfaceTensionMixtureObj is None and not skip_missing:
SurfaceTensionMixtureObj = SurfaceTensionMixture(MWs=constants.MWs, Tbs=constants.Tbs, Tcs=constants.Tcs, CASs=constants.CASs, SurfaceTensions=SurfaceTensions, VolumeLiquids=VolumeLiquids)
self.VolumeSolidMixture = VolumeSolidMixtureObj
self.VolumeLiquidMixture = VolumeLiquidMixtureObj
self.VolumeGasMixture = VolumeGasMixtureObj
self.HeatCapacityLiquidMixture = HeatCapacityLiquidMixtureObj
self.HeatCapacityGasMixture = HeatCapacityGasMixtureObj
self.HeatCapacitySolidMixture = HeatCapacitySolidMixtureObj
self.ViscosityLiquidMixture = ViscosityLiquidMixtureObj
self.ViscosityGasMixture = ViscosityGasMixtureObj
self.ThermalConductivityLiquidMixture = ThermalConductivityLiquidMixtureObj
self.ThermalConductivityGasMixture = ThermalConductivityGasMixtureObj
self.SurfaceTensionMixture = SurfaceTensionMixtureObj
def as_poly_fit(self, props=None):
multiple_props = isinstance(props, (tuple, list)) and isinstance(props[0], str)
if props is None or multiple_props:
if multiple_props:
iter_props = props
else:
iter_props = self.pure_correlations
s = f'{self.__class__.__name__}('
s += 'constants=constants, skip_missing=True,\n'
for prop in iter_props:
prop_attr = getattr(self, prop)
if prop_attr is not None:
try:
s += f'{prop}={self.as_poly_fit(prop_attr)},\n'
except Exception as e:
print(e, prop)
s += ')'
return s
s = '['
for obj in props:
s += (obj.as_poly_fit() + ',\n')
s += ']'
return s
# Values except for omega from IAPWS; heat capacity isn't official.
iapws_constants = ChemicalConstantsPackage(CASs=['7732-18-5'], MWs=[18.015268], omegas=[0.344],atomss=[{'H': 2, 'O': 1}], names=['water'],
Pcs=[22064000.0], Tcs=[647.096], Tts=[273.16], Pts=[611.654771008], Hfgs=[-241822.0], Sfgs=[-44.5], Gfgs=[-228554.325])
""":obj:`ChemicalConstantsPackage` : Object intended to hold the IAPWS-95 water constants
for use with the :obj:`thermo.phases.IAPWS95` phase object.
"""
iapws_correlations = PropertyCorrelationsPackage(constants=iapws_constants, skip_missing=True,
SublimationPressures=[SublimationPressure(CASRN="7732-18-5", method="IAPWS", load_data=False)],
SurfaceTensions=[SurfaceTension(load_data=False, Tc=647.14, exp_poly_fit_ln_tau=(248.14999999999998, 643.9043, 647.14,
[-2.8494246663280267e-05, -0.0007642770215779117, -0.0087879657158058, -0.056840919106152674, -0.22915223013722677, -0.607083777358256,
-1.0946692428934923, -0.08982641235684152, -2.383855224250596]))],
HeatCapacityGases=[HeatCapacityGas(load_data=False, poly_fit=(50.0, 1000.0, [5.543665000518528e-22, -2.403756749600872e-18,
4.2166477594350336e-15, -3.7965208514613565e-12, 1.823547122838406e-09, -4.3747690853614695e-07, 5.437938301211039e-05, -0.003220061088723078, 33.32731489750759]))])
""":obj:`PropertyCorrelationsPackage`: IAPWS correlations and properties, [-]"""
lemmon2000_constants = ChemicalConstantsPackage(CASs=['132259-10-0'], MWs=[28.9586], omegas=[0.0335],
Pcs=[3.78502E6], Tcs=[132.6312])
""":obj:`ChemicalConstantsPackage` : Object intended to hold the Lemmon (2000) air constants
for use with the :obj:`thermo.phases.DryAirLemmon` phase object.
"""
# 20 coefficients gets a very good fit 1e-8 rtol
lemmon2000_correlations = PropertyCorrelationsPackage(constants=lemmon2000_constants, skip_missing=True,
HeatCapacityGases=[HeatCapacityGas(load_data=False, poly_fit=(132.6313, 2000.0, [-6.626125905505976e-57, 1.3834500819751098e-52, -1.33739947283832e-48, 7.939514061796618e-45, -3.2364291450043207e-41, 9.594346367764268e-38, -2.13653752371752e-34, 3.6389955418840433e-31, -4.779579487030328e-28, 4.842352128842408e-25, -3.7575972075674665e-22, 2.2015407920080106e-19, -9.545492841183412e-17, 3.0147537523176223e-14, -7.116946884523906e-12, 1.4112957512038422e-09, -2.416177742609162e-07, 3.041947869442721e-05, -0.0022420811935852042, 29.099089803167224]))])
""":obj:`PropertyCorrelationsPackage`: Lemmon (2000) air correlations and properties, [-]"""