MultiStream#
A MultiStream object represents a material flow with multiple phases in a chemical process.
- class MultiStream(ID='', flow=(), T=298.15, P=101325.0, phases=None, units=None, price=0, total_flow=None, thermo=None, characterization_factors=None, vlle=False, **phase_flows)[source]#
Create a MultiStream object that defines material flow rates for multiple phases along with its thermodynamic state. Thermodynamic and transport properties of a stream are available as properties, while thermodynamic equilbrium (e.g. VLE, and bubble and dew points) are available as methods.
- Parameters:
ID (
str
, optional) – A unique identification. If ID is None, stream will not be registered. If no ID is given, stream will be registered with a unique ID.flow (
Sequence
, optional) – All flow rates corresponding to phases by row and chemical IDs by column.T (
float
, optional) – Temperature [K]. Defaults to 298.15.P (
float
, optional) – Pressure [Pa]. Defaults to 101325.phases (
Sequence`[:py:class:`str
], optional) – Tuple denoting the phases present. Defaults to (‘g’, ‘l’).units (
str
, optional) – Flow rate units of measure (only mass, molar, and volumetric flow rates are valid). Defaults to ‘kmol/hr’.price (
float
, optional) – Price per unit mass [USD/kg]. Defaults to 0.total_flow (
float
, optional) – Total flow rate.thermo (
Thermo
, optional) – Thermodynamic equilibrium package. Defaults to thermosteam.settings.get_thermo().vlle (
bool
, optional) – Whether to run rigorous phase equilibrium to determine phases. Defaults to False.
Examples
Before creating streams, first set the chemicals:
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
Create a multi phase stream, defining the thermodynamic condition and flow rates:
>>> s1 = tmo.MultiStream(ID='s1',T=298.15, P=101325, ... l=[('Water', 20), ('Ethanol', 10)], units='kg/hr') >>> s1.show(flow='kg/hr') # Use the show method to select units of display MultiStream: s1 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Water 20 Ethanol 10
The temperature and pressure are stored as attributes:
>>> (s1.T, s1.P) (298.15, 101325.0)
Unlike Stream objects, the mol attribute does not store data, it simply returns the total flow rate of each chemical. Setting an element of the array raises an error to prevent the wrong assumption that the data is linked:
>>> s1.mol sparse([1.11 , 0.217]) >>> s1.mol[0] = 1 Traceback (most recent call last): ValueError: assignment destination is read-only
All flow rates are stored in the imol attribute:
>>> s1.imol.show() # Molar flow rates [kmol/hr] MolarFlowIndexer (kmol/hr): (l) Water 1.11 Ethanol 0.2171 >>> # Index a single chemical in the liquid phase >>> s1.imol['l', 'Water'] 1.1101 >>> # Index multiple chemicals in the liquid phase >>> s1.imol['l', ('Ethanol', 'Water')] array([0.217, 1.11 ]) >>> # Index the vapor phase >>> s1.imol['g'] sparse([0., 0.]) >>> # Index flow of chemicals summed across all phases >>> s1.imol['Ethanol', 'Water'] array([0.217, 1.11 ])
Note that overall chemical flows in MultiStream objects cannot be set like with Stream objects:
>>> # s1.imol['Ethanol', 'Water'] = [1, 0] Traceback (most recent call last): IndexError: multiple phases present; must include phase key to set chemical data
Chemical flows must be set by phase:
>>> s1.imol['l', ('Ethanol', 'Water')] = [1, 0]
The most convinient way to get and set flow rates is through the get_flow and set_flow methods:
>>> # Set flow >>> key = ('l', 'Water') >>> s1.set_flow(1, 'gpm', key) >>> s1.get_flow('gpm', key) 1.0 >>> # Set multiple flows >>> key = ('l', ('Ethanol', 'Water')) >>> s1.set_flow([10, 20], 'kg/hr', key) >>> s1.get_flow('kg/hr', key) array([10., 20.])
Chemical flows across all phases can be retrieved if no phase is given:
>>> s1.get_flow('kg/hr', ('Ethanol', 'Water')) array([10., 20.])
However, setting chemical data requires the phase to be specified:
>>> s1.set_flow([10, 20], 'kg/hr', ('Ethanol', 'Water')) Traceback (most recent call last): IndexError: multiple phases present; must include phase key to set chemical data
Note that for both Stream and MultiStream objects, mol, imol, and get_flow return chemical flows across all phases when given only chemical IDs.
Vapor-liquid equilibrium can be performed by setting 2 degrees of freedom from the following list:
T - Temperature [K]
P - Pressure [Pa]
V - Vapor fraction
H - Enthalpy [kJ/hr]
>>> s1.vle(P=101325, T=365)
Each phase can be accessed separately too:
>>> s1['l'].show() Stream: phase: 'l', T: 365 K, P: 101325 Pa flow (kmol/hr): Water 0.617 Ethanol 0.0238 >>> s1['g'].show() Stream: phase: 'g', T: 365 K, P: 101325 Pa flow (kmol/hr): Water 0.493 Ethanol 0.193
Note that the phase cannot be changed:
>>> s1['g'].phase = 'l' Traceback (most recent call last): AttributeError: phase is locked
- reset_flow(total_flow=None, units=None, phases=None, **phase_flows)[source]#
Convinience method for resetting flow rate data.
Examples
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 1)]) >>> s1.reset_flow(g=[('Ethanol', 1)], phases='lgs', units='kg/hr', total_flow=2) >>> s1.show('cwt') MultiStream: s1 phases: ('g', 'l', 's'), T: 298.15 K, P: 101325 Pa composition (%): (g) Ethanol 100 ------- 2 kg/hr
- get_flow(units, key=Ellipsis)[source]#
Return an array of flow rates in requested units.
- Parameters:
units (
str
) – Units of measure.key –
Index key as (phase, IDs), phase, or IDs where:
phase is a str, ellipsis, or missing.
IDs is a str, Sequence[str], ellipisis, or missing.
Examples
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 20), ('Ethanol', 10)], units='kg/hr') >>> s1.get_flow('kg/hr', ('l', 'Water')) 20.0
>>> s1.get_flow('kg/hr') sparse([20., 10.])
- set_flow(data, units, key=Ellipsis)[source]#
Set flow rates in given units.
- Parameters:
Examples
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 20), ('Ethanol', 10)], units='kg/hr') >>> s1.set_flow(10, 'kg/hr', ('l', 'Water')) >>> s1.get_flow('kg/hr', ('l', 'Water')) 10.0
- split_to(s1, s2, split, energy_balance=True)[source]#
Split molar flow rate from this stream to two others given the split fraction or an array of split fractions.
Examples
>>> import thermosteam as tmo >>> chemicals = tmo.Chemicals(['Water', 'Ethanol'], cache=True) >>> tmo.settings.set_thermo(chemicals) >>> s = tmo.Stream('s', Water=20, Ethanol=10, units='kg/hr') >>> s.phases = ('l', 'g') >>> s1 = tmo.Stream('s1') >>> s2 = tmo.Stream('s2') >>> split = chemicals.kwarray(dict(Water=0.5, Ethanol=0.1)) >>> s.split_to(s1, s2, split) >>> s1.show(flow='kg/hr') MultiStream: s1 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Water 10 Ethanol 1
>>> s2.show(flow='kg/hr') MultiStream: s2 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Water 10 Ethanol 9
- copy_like(other)[source]#
Copy all conditions of another stream.
Examples
Copy data from another stream with the same property package:
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 20), ('Ethanol', 10)], units='kg/hr') >>> s2 = tmo.Stream('s2', Water=2, units='kg/hr') >>> s1.copy_like(s2) >>> s1.show(flow='kg/hr') MultiStream: s1 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Water 2
Copy data from another stream with a different property package:
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 20), ('Ethanol', 10)], units='kg/hr') >>> tmo.settings.set_thermo(['Water'], cache=True) >>> s2 = tmo.Stream('s2', Water=2, units='kg/hr') >>> s1.copy_like(s2) >>> s1.show(flow='kg/hr') MultiStream: s1 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Water 2
- copy_flow(other, phase=Ellipsis, IDs=Ellipsis, *, remove=False, exclude=False)[source]#
Copy flow rates of another stream to self.
- Parameters:
other (
Stream
) – Flow rates will be copied from here.IDs (
Sequence`[:py:class:`str
] |str
, optional) – Chemical IDs. Defaults to all chemicals.remove (
bool
, optional) – If True, copied chemicals will be removed from stream.exclude (
bool
, optional) – If True, exclude designated chemicals when copying.
Notes
Works just like <Stream>.copy_flow, but the phase must be specified.
Examples
Initialize streams:
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 20), ('Ethanol', 10)], units='kg/hr') >>> s2 = tmo.MultiStream('s2')
Copy all flows:
>>> s2.copy_flow(s1) >>> s2.show(flow='kg/hr') MultiStream: s2 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Water 20 Ethanol 10
Reset and copy just water flow:
>>> s2.empty() >>> s2.copy_flow(s1, IDs='Water') >>> s2.show(flow='kg/hr') MultiStream: s2 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Water 20
Reset and copy all flows except water:
>>> s2.empty() >>> s2.copy_flow(s1, IDs='Water', exclude=True) >>> s2.show(flow='kg/hr') MultiStream: s2 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Ethanol 10
Cut and paste flows:
>>> s2.copy_flow(s1, remove=True) >>> s2.show(flow='kg/hr') MultiStream: s2 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Water 20 Ethanol 10 >>> s1.show() MultiStream: s1 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow: 0
The other stream can also be a single phase stream (doesn’t have to be a MultiStream object):
Initialize streams:
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True) >>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, units='kg/hr') >>> s2 = tmo.MultiStream('s2')
Copy all flows:
>>> s2.copy_flow(s1) >>> s2.show(flow='kg/hr') MultiStream: s2 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Water 20 Ethanol 10
Reset and copy just water flow:
>>> s2.empty() >>> s2.copy_flow(s1, IDs='Water') >>> s2.show(flow='kg/hr') MultiStream: s2 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Water 20
Reset and copy all flows except water:
>>> s2.empty() >>> s2.copy_flow(s1, IDs='Water', exclude=True) >>> s2.show(flow='kg/hr') MultiStream: s2 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Ethanol 10
Cut and paste flows:
>>> s2.copy_flow(s1, remove=True) >>> s2.show(flow='kg/hr') MultiStream: s2 phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa flow (kg/hr): (l) Water 20 Ethanol 10 >>> s1.show() Stream: s1 phase: 'l', T: 298.15 K, P: 101325 Pa flow: 0
- get_normalized_mol(IDs)[source]#
Return normalized molar fractions of given chemicals. The sum of the result is always 1.
- Parameters:
IDs (
Sequence`[:py:class:`str
]) – IDs of chemicals to be normalized.
Examples
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol', 'Methanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 20), ('Ethanol', 10), ('Methanol', 10)], units='kmol/hr') >>> s1.get_normalized_mol(('Water', 'Ethanol')) array([0.667, 0.333])
- get_normalized_vol(IDs)[source]#
Return normalized mass fractions of given chemicals. The sum of the result is always 1.
- Parameters:
IDs (
Sequence`[:py:class:`str
]) – IDs of chemicals to be normalized.
Examples
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol', 'Methanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 20), ('Ethanol', 10), ('Methanol', 10)], units='m3/hr') >>> s1.get_normalized_vol(('Water', 'Ethanol')) array([0.667, 0.333])
- get_normalized_mass(IDs)[source]#
Return normalized mass fractions of given chemicals. The sum of the result is always 1.
- Parameters:
IDs (
Sequence`[:py:class:`str
]) – IDs of chemicals to be normalized.
Examples
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol', 'Methanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 20), ('Ethanol', 10), ('Methanol', 10)], units='kg/hr') >>> s1.get_normalized_mass(('Water', 'Ethanol')) array([0.667, 0.333])
- get_molar_composition(IDs)[source]#
Return molar composition of given chemicals.
- Parameters:
IDs (
Sequence`[:py:class:`str
]) – IDs of chemicals.
Examples
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol', 'Methanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 20), ('Ethanol', 10), ('Methanol', 10)], units='kmol/hr') >>> s1.get_molar_composition(('Water', 'Ethanol')) array([0.5 , 0.25])
- get_mass_composition(IDs)[source]#
Return mass composition of given chemicals.
- Parameters:
IDs (
Sequence`[:py:class:`str
]) – IDs of chemicals.
Examples
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol', 'Methanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 20), ('Ethanol', 10), ('Methanol', 10)], units='kg/hr') >>> s1.get_mass_composition(('Water', 'Ethanol')) array([0.5 , 0.25])
- get_volumetric_composition(IDs)[source]#
Return volumetric composition of given chemicals.
- Parameters:
IDs (
Sequence`[:py:class:`str
]) – IDs of chemicals.
Examples
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol', 'Methanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 20), ('Ethanol', 10), ('Methanol', 10)], units='m3/hr') >>> s1.get_volumetric_composition(('Water', 'Ethanol')) array([0.5 , 0.25])
- get_concentration(phase, IDs, units=None)[source]#
Return concentration of given chemicals in kmol/m3.
Examples
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol', 'Methanol'], cache=True) >>> s1 = tmo.MultiStream('s1', l=[('Water', 20), ('Ethanol', 10), ('Methanol', 10)], units='m3/hr') >>> s1.get_concentration('l', ('Water', 'Ethanol')) array([27.673, 4.261])
>>> s1.get_concentration('l', ('Water', 'Ethanol'), 'g/L') array([498.532, 196.291])
- property ID#
Unique identification (str). If set as ‘’, it will choose a default ID.
- print()[source]#
Print in a format that you can use recreate the stream.
Examples
>>> import thermosteam as tmo >>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True) >>> s1 = tmo.MultiStream(ID='s1',T=298.15, P=101325, ... l=[('Water', 20), ('Ethanol', 10)], units='kg/hr') >>> s1.print() MultiStream(ID='s1', phases=('g', 'l'), T=298.15, P=101325, l=[('Water', 1.11), ('Ethanol', 0.2171)])