Chemicals#
- class Chemicals(chemicals, cache=None, db='default')[source]#
Create a Chemicals object that contains Chemical objects as attributes.
- Parameters:
chemicals (Iterable[str or
Chemical
]) –- Strings should be one of the following [-]:
Name, in IUPAC form or common form or an alias registered in PubChem
InChI name, prefixed by ‘InChI=1S/’ or ‘InChI=1/’
InChI key, prefixed by ‘InChIKey=’
PubChem CID, prefixed by ‘PubChem=’
SMILES (prefix with ‘SMILES=’ to ensure smiles parsing)
CAS number
cache (bool, optional) – Whether or not to use cached chemicals.
Examples
Create a Chemicals object from chemical identifiers:
>>> from thermosteam import Chemicals >>> chemicals = Chemicals(['Water', 'Ethanol'], cache=True) >>> chemicals Chemicals([Water, Ethanol])
All chemicals are stored as attributes:
>>> chemicals.Water, chemicals.Ethanol (Chemical('Water'), Chemical('Ethanol'))
Chemicals can also be accessed as items:
>>> chemicals = Chemicals(['Water', 'Ethanol', 'Propane'], cache=True) >>> chemicals['Ethanol'] Chemical('Ethanol') >>> chemicals['Propane', 'Water'] [Chemical('Propane'), Chemical('Water')]
A Chemicals object can be extended with more chemicals:
>>> from thermosteam import Chemical >>> Methanol = Chemical('Methanol') >>> chemicals.append(Methanol) >>> chemicals Chemicals([Water, Ethanol, Propane, Methanol]) >>> new_chemicals = Chemicals(['Hexane', 'Octanol'], cache=True) >>> chemicals.extend(new_chemicals) >>> chemicals Chemicals([Water, Ethanol, Propane, Methanol, Hexane, Octanol])
Chemical objects cannot be repeated:
>>> chemicals.append(chemicals.Water) Traceback (most recent call last): ValueError: Water already defined in chemicals >>> chemicals.extend(chemicals['Ethanol', 'Octanol']) Traceback (most recent call last): ValueError: Ethanol already defined in chemicals
A Chemicals object can only contain Chemical objects:
>>> chemicals.append(10) Traceback (most recent call last): TypeError: only 'Chemical' objects can be appended, not 'int'
You can check whether a Chemicals object contains a given chemical:
>>> 'Water' in chemicals True >>> chemicals.Water in chemicals True >>> 'Butane' in chemicals False
An attempt to access a non-existent chemical raises an UndefinedChemicalAlias error:
>>> chemicals['Butane'] Traceback (most recent call last): UndefinedChemicalAlias: 'Butane'
- compile(skip_checks=False)[source]#
Cast as a CompiledChemicals object.
- Parameters:
skip_checks (bool, optional) – Whether to skip checks for missing or invalid properties.
Warning
If checks are skipped, certain features in thermosteam (e.g. phase equilibrium) cannot be guaranteed to function properly.
Examples
Compile ethanol and water chemicals:
>>> import thermosteam as tmo >>> chemicals = tmo.Chemicals(['Water', 'Ethanol']) >>> chemicals.compile() >>> chemicals CompiledChemicals([Water, Ethanol])
Attempt to compile chemicals with missing properties:
>>> Substance = tmo.Chemical('Substance', search_db=False) >>> chemicals = tmo.Chemicals([Substance]) >>> chemicals.compile() Traceback (most recent call last): RuntimeError: Substance is missing key thermodynamic properties (V, S, H, Cn, Psat, Tb and Hvap); use the `<Chemical>.get_missing_properties()` to check all missing properties
Compile chemicals with missing properties (skipping checks) and note how certain features do not work:
>>> chemicals.compile(skip_checks=True) >>> tmo.settings.set_thermo(chemicals) >>> s = tmo.Stream('s', Substance=10) >>> s.rho Traceback (most recent call last): RuntimeError: No liquid molar volume method selected for component with CASRN 'Substance'
- class CompiledChemicals(chemicals, cache=None)[source]#
Create a CompiledChemicals object that contains Chemical objects as attributes.
- Parameters:
chemicals (Iterable[str or Chemical]) –
- Strings should be one of the following [-]:
Name, in IUPAC form or common form or an alias registered in PubChem
InChI name, prefixed by ‘InChI=1S/’ or ‘InChI=1/’
InChI key, prefixed by ‘InChIKey=’
PubChem CID, prefixed by ‘PubChem=’
SMILES (prefix with ‘SMILES=’ to ensure smiles parsing)
CAS number
cache (optional) – Whether or not to use cached chemicals.
- MW#
MWs of all chemicals.
- Type:
1d ndarray
- Hf#
Heats of formation of all chemicals.
- Type:
1d ndarray
- Hc#
Heats of combustion of all chemicals.
- Type:
1d ndarray
Examples
Create a CompiledChemicals object from chemical identifiers
>>> from thermosteam import CompiledChemicals, Chemical >>> chemicals = CompiledChemicals(['Water', 'Ethanol'], cache=True) >>> chemicals CompiledChemicals([Water, Ethanol])
All chemicals are stored as attributes:
>>> chemicals.Water, chemicals.Ethanol (Chemical('Water'), Chemical('Ethanol'))
Note that because they are compiled, the append and extend methods do not work:
>>> Propane = Chemical('Propane', cache=True) >>> chemicals.append(Propane) Traceback (most recent call last): TypeError: 'CompiledChemicals' object is read-only
You can check whether a Chemicals object contains a given chemical:
>>> 'Water' in chemicals True >>> chemicals.Water in chemicals True >>> 'Butane' in chemicals False
- define_group(name, IDs, composition=None, wt=False)[source]#
Define a group of chemicals.
- Parameters:
Examples
Create a chemical group and get the index:
>>> import thermosteam as tmo >>> chemicals = tmo.CompiledChemicals(['Water', 'Methanol', 'Ethanol'], cache=True) >>> chemicals.define_group('Alcohol', ['Methanol', 'Ethanol'], composition=[0.5, 0.5]) >>> chemicals.get_index('Alcohol') [1, 2] >>> chemicals.get_index(('Water', 'Alcohol')) [0, [1, 2]]
By defining a chemical group, you can conveniently use indexers to retrieve the total value of the group:
>>> # Single phase stream case >>> tmo.settings.set_thermo(chemicals) >>> s1 = tmo.Stream(ID='s1', Water=2) >>> s1.imol['Alcohol'] 0 >>> s1.imol['Methanol', 'Ethanol'] = [2., 1.] >>> s1.imol['Water', 'Alcohol'] array([2., 3.])
>>> # Multi-phase stream case >>> s2 = tmo.Stream(ID='s2', Water=2, Methanol=1, Ethanol=1) >>> s2.vle(V=0.5, P=101325) >>> s2.imol['Alcohol'] 2.0 >>> s2.imol['l', 'Alcohol'] 0.6793 >>> s2.imol['l', ('Water', 'Alcohol')] array([1.321, 0.679])
Because groups are defined with a composition we can set values by groups as well:
>>> s1.imol['Alcohol'] = 3. >>> s1.imol['Ethanol', 'Methanol'] array([1.5, 1.5])
>>> s1.imol['Water', 'Alcohol'] = [3., 1.] >>> s1.imol['Water', 'Ethanol', 'Methanol'] array([3. , 0.5, 0.5])
>>> s2.imol['l', 'Alcohol'] = 1. >>> s2.imol['l', ('Ethanol', 'Methanol')] array([0.5, 0.5])
For SplitIndexer objects, which reflect the separation of chemicals in two streams, group names correspond to nested indexes (without a composition):
>>> # Create a split-indexer >>> indexer = chemicals.isplit(0.7) >>> indexer.show() SplitIndexer: Water 0.7 Methanol 0.7 Ethanol 0.7
>>> # Normal index >>> indexer['Alcohol'] = [0.50, 0.80] # Methanol and ethanol >>> indexer['Alcohol'] array([0.5, 0.8])
>>> # Broadcasted index >>> indexer['Alcohol'] = 0.9 >>> indexer['Alcohol'] array([0.9, 0.9])
>>> # Nested index >>> indexer['Water', 'Alcohol'] = [0.2, [0.6, 0.7]] >>> indexer['Water', 'Alcohol'] array([0.2, array([0.6, 0.7])], dtype=object)
>>> # Broadcasted and nested index >>> indexer['Water', 'Alcohol'] = [0.2, 0.8] >>> indexer['Water', 'Alcohol'] array([0.2, array([0.8, 0.8])], dtype=object)
This feature allows splits to be easily defined for groups of chemicals in BioSTEAM.
- refresh_constants()[source]#
Refresh constant arrays according to their chemical values, including the molecular weight, heats of formation, and heats of combustion.
- get_combustion_reactions()[source]#
Return a ParallelReactions object with all defined combustion reactions.
Examples
>>> chemicals = CompiledChemicals(['H2O', 'Methanol', 'Ethanol', 'CO2', 'O2'], cache=True) >>> rxns = chemicals.get_combustion_reactions() >>> rxns.show() ParallelReaction (by mol): index stoichiometry reactant X[%] [0] Methanol + 1.5 O2 -> 2 H2O + CO2 Methanol 100.00 [1] Ethanol + 3 O2 -> 3 H2O + 2 CO2 Ethanol 100.00
- property formula_array#
An array describing the formulas of all chemicals. Each column is a chemical and each row an element. Rows are ordered by atomic number.
Examples
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol', 'Propane'], cache=True) >>> chemicals.formula_array.sum(0) array([ 3., 9., 11.])
- get_parsable_alias(ID)[source]#
Return an alias of the given chemical identifier that can be parsed by Python as a variable name
- Parameters:
ID (str) – Chemical identifier.
Examples
Get parsable alias of 2,3-Butanediol:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['2,3-Butanediol'], cache=True) >>> chemicals.get_parsable_alias('2,3-Butanediol') 'C4H10O2'
- get_parsable_synonym(ID)#
Return an alias of the given chemical identifier that can be parsed by Python as a variable name
- Parameters:
ID (str) – Chemical identifier.
Examples
Get parsable alias of 2,3-Butanediol:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['2,3-Butanediol'], cache=True) >>> chemicals.get_parsable_alias('2,3-Butanediol') 'C4H10O2'
- get_aliases(ID)[source]#
Return all aliases of a chemical.
- Parameters:
ID (str) – Chemical identifier.
Examples
Get all aliases of water:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water'], cache=True) >>> aliases = chemicals.get_aliases('Water') >>> aliases.sort() >>> aliases ['7732-18-5', 'H2O', 'Water', 'oxidane', 'water']
- get_synonyms(ID)#
Return all aliases of a chemical.
- Parameters:
ID (str) – Chemical identifier.
Examples
Get all aliases of water:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water'], cache=True) >>> aliases = chemicals.get_aliases('Water') >>> aliases.sort() >>> aliases ['7732-18-5', 'H2O', 'Water', 'oxidane', 'water']
- set_alias(ID, alias)[source]#
Set a new alias for a chemical.
Examples
Set new alias for water:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol'], cache=True) >>> chemicals.set_alias('Water', 'H2O') >>> chemicals.H2O is chemicals.Water True
Note that you cannot use one alias for two chemicals:
>>> chemicals.set_alias('Ethanol', 'H2O') Traceback (most recent call last): ValueError: alias 'H2O' already in use by Chemical('Water')
- set_synonym(ID, alias)#
Set a new alias for a chemical.
Examples
Set new alias for water:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol'], cache=True) >>> chemicals.set_alias('Water', 'H2O') >>> chemicals.H2O is chemicals.Water True
Note that you cannot use one alias for two chemicals:
>>> chemicals.set_alias('Ethanol', 'H2O') Traceback (most recent call last): ValueError: alias 'H2O' already in use by Chemical('Water')
- zeros()[source]#
Return an array of zeros with entries that correspond to the orded chemical IDs.
Examples
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol'], cache=True) >>> chemicals.zeros() array([0., 0.])
- ones()[source]#
Return an array of ones with entries that correspond to the ordered chemical IDs.
Examples
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol'], cache=True) >>> chemicals.ones() array([1., 1.])
- kwarray(ID_data)[source]#
Return an array with entries that correspond to the ordered chemical IDs.
Examples
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol'], cache=True) >>> chemicals.kwarray(dict(Water=2)) array([2., 0.])
- array(IDs, data)[source]#
Return an array with entries that correspond to the ordered chemical IDs.
- Parameters:
IDs (iterable) – Compound IDs.
data (array_like) – Data corresponding to IDs.
Examples
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol'], cache=True) >>> chemicals.array(['Water'], [2]) array([2., 0.])
- iarray(IDs, data)[source]#
Return a chemical indexer.
- Parameters:
IDs (iterable) – Chemical IDs.
data (array_like) – Data corresponding to IDs.
Examples
Create a chemical indexer from chemical IDs and data:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Methanol', 'Ethanol'], cache=True) >>> indexer = chemicals.iarray(['Water', 'Ethanol'], [2., 1.]) >>> indexer.show() ChemicalIndexer: Water 2 Ethanol 1
Note that indexers allow for computationally efficient indexing using identifiers:
>>> indexer['Ethanol', 'Water'] array([1., 2.]) >>> indexer['Ethanol'] 1.0
- ikwarray(ID_data)[source]#
Return a chemical indexer.
- Parameters:
ID_data (Dict[str: float]) – Chemical ID-value pairs.
Examples
Create a chemical indexer from chemical IDs and data:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Methanol', 'Ethanol'], cache=True) >>> indexer = chemicals.ikwarray(dict(Water=2., Ethanol=1.)) >>> indexer.show() ChemicalIndexer: Water 2 Ethanol 1
Note that chemical indexers allow for computationally efficient indexing using identifiers:
>>> indexer['Ethanol', 'Water'] array([1., 2.]) >>> indexer['Ethanol'] 1.0
- split(IDs, data)[source]#
Return an array with entries that correspond to the ordered chemical IDs.
- Parameters:
IDs (iterable) – Compound IDs.
data (array_like) – Data corresponding to IDs.
Examples
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol'], cache=True) >>> chemicals.split(['Water'], [1]) array([1., 0.])
- kwsplit(ID_data)[source]#
Return an array with entries that correspond to the ordered chemical IDs.
Examples
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol'], cache=True) >>> chemicals.kwsplit(dict(Water=1)) array([1., 0.])
- isplit(split, order=None)[source]#
Create a SplitIndexer object that represents chemical splits.
- Parameters:
split (Should be one of the following) –
[float] Split fraction
[array_like] Componentwise split
[dict] ID-split pairs
order=None (Iterable[str], options) – Chemical order of split. Defaults to biosteam.settings.chemicals.IDs
Examples
From a dictionary:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Methanol', 'Ethanol'], cache=True) >>> indexer = chemicals.isplit(dict(Water=0.5, Ethanol=1.)) >>> indexer.show() SplitIndexer: Water 0.5 Ethanol 1
From iterable given the order:
>>> indexer = chemicals.isplit([0.5, 1], ['Water', 'Ethanol']) >>> indexer.show() SplitIndexer: Water 0.5 Ethanol 1
From a fraction:
>>> indexer = chemicals.isplit(0.75) >>> indexer.show() SplitIndexer: Water 0.75 Methanol 0.75 Ethanol 0.75
From an iterable (assuming same order as the Chemicals object):
>>> indexer = chemicals.isplit([0.5, 0, 1]) >>> indexer.show() SplitIndexer: Water 0.5 Ethanol 1
- index(ID)[source]#
Return index of specified chemical.
- Parameters:
ID (str) – Chemical identifier.
Examples
Index by ID:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol']) >>> chemicals.index('Water') 0
Indices by CAS number:
>>> chemicals.index('7732-18-5') 0
- indices(IDs)[source]#
Return indices of specified chemicals.
- Parameters:
IDs (iterable) – Chemical identifiers.
Examples
Indices by ID:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol']) >>> chemicals.indices(['Water', 'Ethanol']) [0, 1]
Indices by CAS number:
>>> chemicals.indices(['7732-18-5', '64-17-5']) [0, 1]
- available_indices(IDs)[source]#
Return indices of all chemicals available.
Notes
CAS numbers are also supported.
Examples
Get available indices from IDs:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol'], cache=True) >>> IDs = ('Water', 'Ethanol', 'Octane') >>> chemicals.available_indices(IDs) [0, 1]
- get_index(IDs)[source]#
Return index/indices of specified chemicals.
Notes
CAS numbers are also supported.
Examples
Get multiple indices with a tuple/list of IDs:
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Ethanol'], cache=True) >>> IDs = ('Water', 'Ethanol') >>> chemicals.get_index(IDs) [0, 1]
Get a single index with a string:
>>> chemicals.get_index('Ethanol') 1
An Ellipsis returns a slice:
>>> chemicals.get_index(...) slice(None, None, None)
Collections (without an order) raise an error:
>>> chemicals.get_index({'Water', 'Ethanol'}) Traceback (most recent call last): TypeError: only strings, sequences, and ellipsis are valid index keys
- get_vle_indices(nonzeros)[source]#
Return indices of species in vapor-liquid equilibrium given an array dictating whether or not the chemicals are present.
Examples
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Methanol', 'Ethanol']) >>> data = chemicals.kwarray(dict(Water=2., Ethanol=1.)) >>> chemicals.get_vle_indices(data[data!=0]) [1, 2]
- get_lle_indices(nonzeros)[source]#
Return indices of species in liquid-liquid equilibrium given an array dictating whether or not the chemicals are present.
Examples
>>> from thermosteam import CompiledChemicals >>> chemicals = CompiledChemicals(['Water', 'Methanol', 'Ethanol']) >>> data = chemicals.kwarray(dict(Water=2., Ethanol=1.)) >>> chemicals.get_lle_indices(data[data!=0]) [1, 2]
- append(*args, **kwargs)#
Append a Chemical.
- extend(*args, **kwargs)#
Extend with more Chemical objects.