Stream#

class Stream(ID='', flow=(), phase='l', T=298.15, P=101325.0, units=None, price=0.0, total_flow=None, thermo=None, characterization_factors=None, vlle=False, **chemical_flows)[source]#

Create a Stream object that defines material flow rates 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`[:py:class:`float]) – All flow rates corresponding to defined chemicals.

  • phase (str, optional) – ‘g’ for gas, ‘l’ for liquid, and ‘s’ for solid. Defaults to ‘l’.

  • T (float, optional) – Temperature [K]. Defaults to 298.15.

  • P (float, optional) – Pressure [Pa]. Defaults to 101325.

  • 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) – Thermo object to initialize input and output streams. Defaults to settings.thermo.

  • characterization_factors (dict`[:py:class:`str, float], optional) – Characterization factors for life cycle assessment.

  • vlle (bool, optional) – Whether to run rigorous phase equilibrium to determine phases. Defaults to False.

  • **chemical_flows (float) – ID - flow pairs.

Examples

Before creating a stream, first set the chemicals:

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)

Create a stream, defining the thermodynamic condition and flow rates:

>>> s1 = tmo.Stream(ID='s1',
...                 Water=20, Ethanol=10, units='kg/hr',
...                 T=298.15, P=101325, phase='l')
>>> s1.show(flow='kg/hr') # Use the show method to select units of display
Stream: s1
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water    20
              Ethanol  10
>>> s1.show(composition=True, flow='kg/hr') # Its also possible to show by composition
Stream: s1
phase: 'l', T: 298.15 K, P: 101325 Pa
composition (%): Water    66.7
                 Ethanol  33.3
                 -------  30 kg/hr

All flow rates are stored as a sparse array in the mol attribute. These arrays work just like numpy arrays, but are more scalable (saving memory and increasing speed) for sparse chemical data:

>>> s1.mol # Molar flow rates [kmol/hr]
sparse([1.11 , 0.217])

Mass and volumetric flow rates are also available for convenience:

>>> s1.mass
sparse([20., 10.])
>>> s1.vol
sparse([0.02 , 0.013])

The data of these arrays are linked to the molar flows:

>>> # Mass flows are always up to date with molar flows
>>> s1.mol[0] = 1
>>> s1.mass[0]
18.015
>>> # Changing mass flows changes molar flows
>>> s1.mass[0] *= 2
>>> s1.mol[0]
2.0
>>> # New arrays are not linked to molar flows
>>> s1.mass + 2
sparse([38.031, 12.   ])

The temperature, pressure and phase are attributes as well:

>>> (s1.T, s1.P, s1.phase)
(298.15, 101325.0, 'l')

The most convinient way to get and set flow rates is through the get_flow and set_flow methods:

>>> # Set flow
>>> s1.set_flow(1, 'gpm', 'Water')
>>> s1.get_flow('gpm', 'Water')
1.0
>>> # Set multiple flows
>>> s1.set_flow([10, 20], 'kg/hr', ('Ethanol', 'Water'))
>>> s1.get_flow('kg/hr', ('Ethanol', 'Water'))
array([10., 20.])

It is also possible to index using IDs through the imol, imass, and ivol indexers:

>>> s1.imol.show()
ChemicalMolarFlowIndexer (kmol/hr):
 (l) Water    1.11
     Ethanol  0.2171
>>> s1.imol['Water']
1.1101687012358397
>>> s1.imol['Ethanol', 'Water']
array([0.217, 1.11 ])

Thermodynamic properties are available as stream properties:

>>> s1.H # Enthalpy (kJ/hr)
0.0

Note that the reference enthalpy is 0.0 at the reference temperature of 298.15 K, and pressure of 101325 Pa. Retrive the enthalpy at a 10 degC above the reference.

>>> s1.T += 10
>>> s1.H
1083.46

Other thermodynamic properties are temperature and pressure dependent as well:

>>> s1.rho # Density [kg/m3]
909.14

It may be more convinient to get properties with different units:

>>> s1.get_property('rho', 'g/cm3')
0.9091

It is also possible to set some of the properties in different units:

>>> s1.set_property('T', 40, 'degC')
>>> s1.T
313.15

Bubble point and dew point computations can be performed through stream methods:

>>> bp = s1.bubble_point_at_P() # Bubble point at constant pressure
>>> bp
BubblePointValues(T=357.14, P=101325, IDs=('Water', 'Ethanol'), z=[0.836 0.164], y=[0.492 0.508])

The bubble point results contain all results as attributes:

>>> tmo.docround(bp.T) # Temperature [K]
357.1442
>>> bp.y # Vapor composition
array([0.49, 0.51])

Vapor-liquid equilibrium can be performed by setting 2 degrees of freedom from the following list: T [Temperature; in K], P [Pressure; in Pa], V [Vapor fraction], H [Enthalpy; in kJ/hr].

Set vapor fraction and pressure of the stream:

>>> s1.vle(P=101325, V=0.5)
>>> s1.show()
MultiStream: s1
phases: ('g', 'l'), T: 364.78 K, P: 101325 Pa
flow (kmol/hr): (g) Water    0.472
                    Ethanol  0.191
                (l) Water    0.638
                    Ethanol  0.0257

Note that the stream is a now a MultiStream object to manage multiple phases. Each phase can be accessed separately too:

>>> s1['l'].show()
Stream:
phase: 'l', T: 364.78 K, P: 101325 Pa
flow (kmol/hr): Water    0.638
                Ethanol  0.0257
>>> s1['g'].show()
Stream:
phase: 'g', T: 364.78 K, P: 101325 Pa
flow (kmol/hr): Water    0.472
                Ethanol  0.191

We can convert a MultiStream object back to a Stream object by setting the phase:

>>> s1.phase = 'l'
>>> s1.show(flow='kg/hr')
Stream: s1
phase: 'l', T: 364.78 K, P: 101325 Pa
flow (kg/hr): Water    20
              Ethanol  10
display_units = DisplayUnits(T='K', P='Pa', flow='kmol/hr', composition=False, sort=False, N=7)#

Units of measure for IPython display (class attribute)

characterization_factors: dict[str, float]#

Characterization factors for life cycle assessment [impact/kg].

scale(scale)[source]#

Multiply flow rate by given scale.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=1)
>>> s1.scale(100)
>>> s1.F_mol
100.0
rescale(scale)#

Multiply flow rate by given scale.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=1)
>>> s1.scale(100)
>>> s1.F_mol
100.0
reset_flow(phase=None, units=None, total_flow=None, **chemical_flows)[source]#

Convinience method for resetting flow rate data.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=1)
>>> s1.reset_flow(Ethanol=1, phase='g', units='kg/hr', total_flow=2)
>>> s1.show('cwt')
Stream: s1
phase: 'g', T: 298.15 K, P: 101325 Pa
composition (%): Ethanol  100
                 -------  2 kg/hr
get_CF(key, basis=None, units=None)[source]#

Returns the life-cycle characterization factor on a kg basis given the impact indicator key.

Parameters:
  • key (str) – Key of impact indicator.

  • basis (str, optional) – Basis of characterization factor. Mass is the only valid dimension (for now). Defaults to ‘kg’.

  • units (str, optional) – Units of impact indicator. Before using this argument, the default units of the impact indicator should be defined with settings.define_impact_indicator. Units must also be dimensionally consistent with the default units.

set_CF(key, value, basis=None, units=None)[source]#

Set the life-cycle characterization factor on a kg basis given the impact indicator key and the units of measure.

Parameters:
  • key (str) – Key of impact indicator.

  • value (float) – Characterization factor value.

  • basis (str, optional) – Basis of characterization factor. Mass is the only valid dimension (for now). Defaults to ‘kg’.

  • units (str, optional) – Units of impact indicator. Before using this argument, the default units of the impact indicator should be defined with settings.define_impact_indicator. Units must also be dimensionally consistent with the default units.

get_impact(key)[source]#

Return hourly rate of the impact indicator given the key.

empty_negative_flows()[source]#

Replace flows of all components with negative values with 0.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=1, Ethanol=-1)
>>> s1.empty_negative_flows()
>>> s1.show()
Stream: s1
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kmol/hr): Water  1
shares_flow_rate_with(other)[source]#

Return whether other stream shares data with this one.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water'], cache=True)
>>> s1 = tmo.Stream('s1')
>>> other = s1.flow_proxy()
>>> s1.shares_flow_rate_with(other)
True
>>> s1 = tmo.MultiStream('s1', phases=('l', 'g'))
>>> s1['g'].shares_flow_rate_with(s1)
True
>>> s2 = tmo.MultiStream('s2', phases=('l', 'g'))
>>> s1['g'].shares_flow_rate_with(s2)
False
>>> s1['g'].shares_flow_rate_with(s2['g'])
False
>>> s1 = tmo.MultiStream('s1')
>>> other = s1.flow_proxy()
>>> s1.shares_flow_rate_with(other)
True
>>> s1 = tmo.MultiStream('s1', phases=('l', 'g'))
>>> s1.shares_flow_rate_with(s1['g'])
True
>>> s2 = tmo.MultiStream('s2', phases=('l', 'g'))
>>> s2.shares_flow_rate_with(s1['g'])
False
>>> s1.shares_flow_rate_with(s2)
False
as_stream()[source]#

Does nothing.

get_data()[source]#

Return a StreamData object containing data on material flow rates, temperature, pressure, and phase(s).

See also

Stream.set_data

Examples

Get and set data from stream at different conditions

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water'], cache=True)
>>> stream = tmo.Stream('stream', Water=10)
>>> data = stream.get_data()
>>> stream.vle(V=0.5, P=101325)
>>> data_vle = stream.get_data()
>>> stream.set_data(data)
>>> stream.show()
Stream: stream
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kmol/hr): Water  10
>>> stream.set_data(data_vle)
>>> stream.show()
MultiStream: stream
phases: ('g', 'l'), T: 373.12 K, P: 101325 Pa
flow (kmol/hr): (g) Water  5
                (l) Water  5

Note that only StreamData objects are valid for this method:

>>> stream.set_data({'T': 298.15})
Traceback (most recent call last):
ValueError: stream_data must be a StreamData object; not dict
set_data(stream_data)[source]#

Set material flow rates, temperature, pressure, and phase(s) through a StreamData object

See also

Stream.get_data

property price: float#

Price of stream per unit mass [USD/kg].

isempty()[source]#

Return whether or not stream is empty.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water'], cache=True)
>>> stream = tmo.Stream()
>>> stream.isempty()
True
sanity_check()[source]#

Raise an InfeasibleRegion error if flow rates are infeasible.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water'], cache=True)
>>> s1 = tmo.Stream('s1')
>>> s1.sanity_check()
>>> s1.mol[0] = -1.
>>> s1.sanity_check()
Traceback (most recent call last):
InfeasibleRegion: negative material flow rate is infeasible
property vapor_fraction: float#

Molar vapor fraction.

property liquid_fraction: float#

Molar liquid fraction.

property solid_fraction: float#

Molar solid fraction.

isfeed()[source]#

Return whether stream has a sink but no source.

isproduct()[source]#

Return whether stream has a source but no sink.

property main_chemical: str#

ID of chemical with the largest mol fraction in stream.

disconnect_source()[source]#

Disconnect stream from source.

disconnect_sink()[source]#

Disconnect stream from sink.

disconnect()[source]#

Disconnect stream from unit operations.

reset_cache()[source]#

Reset cache regarding equilibrium methods.

get_atomic_flow(symbol)[source]#

Return flow rate of atom [kmol / hr] given the atomic symbol.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water'], cache=True)
>>> stream = tmo.Stream(Water=1)
>>> stream.get_atomic_flow('H') # kmol/hr of H
2.0
>>> stream.get_atomic_flow('O') # kmol/hr of O
1.0
get_atomic_flows()[source]#

Return dictionary of atomic flow rates [kmol / hr].

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water'], cache=True)
>>> stream = tmo.Stream(Water=1)
>>> stream.get_atomic_flows()
{'H': 2.0, 'O': 1.0}
get_flow(units, key=Ellipsis)[source]#

Return an flow rates in requested units.

Parameters:
  • units (str) – Units of measure.

  • key (Sequence`[:py:class:`str] | str, optional) – Chemical identifiers.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, units='kg/hr')
>>> s1.get_flow('kg/hr', 'Water')
20.0
set_flow(data, units, key=Ellipsis)[source]#

Set flow rates in given units.

Parameters:
  • data (NDArray[float] | float) – Flow rate data.

  • units (str) – Units of measure.

  • key (Sequence`[:py:class:`str] | str, optional) – Chemical identifiers.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream(ID='s1', Water=20, Ethanol=10, units='kg/hr')
>>> s1.set_flow(10, 'kg/hr', 'Water')
>>> s1.get_flow('kg/hr', 'Water')
10.0
get_total_flow(units)[source]#

Get total flow rate in given units.

Parameters:

units (str) – Units of measure.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, units='kg/hr')
>>> s1.get_total_flow('kg/hr')
30.0
set_total_flow(value, units)[source]#

Set total flow rate in given units keeping the composition constant.

Parameters:
  • value (float) – New total flow rate.

  • units (str) – Units of measure.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, units='kg/hr')
>>> s1.set_total_flow(1.0,'kg/hr')
>>> s1.get_total_flow('kg/hr')
0.9999999999999999
property source: Unit#

Outlet location.

property sink: Unit#

Inlet location.

get_downstream_units(ends=None, facilities=True)[source]#

Return a set of all units downstream.

get_upstream_units(ends=None, facilities=True)[source]#

Return a set of all units upstream.

property thermal_condition: ThermalCondition#

Contains the temperature and pressure conditions of the stream.

property T: float#

Temperature [K].

property P: float#

Pressure [Pa].

property phase: str#

Phase of stream.

property mol: ndarray[Any, dtype[float]]#

Molar flow rates [kmol/hr].

property mass: SparseVector | SparseArray#

Mass flow rates [kg/hr].

property vol: SparseVector | SparseArray#

Volumetric flow rates [m3/hr].

property imol: Indexer#

Flow rate indexer with data [kmol/hr].

property imass: Indexer#

Flow rate indexer with data [kg/hr].

property ivol: Indexer#

Flow rate indexer with data [m3/hr].

property cost: float#

Total cost of stream [USD/hr].

property F_mol: float#

Total molar flow rate [kmol/hr].

property F_mass: float#

Total mass flow rate [kg/hr].

property F_vol: float#

Total volumetric flow rate [m3/hr].

property H: float#

Enthalpy flow rate [kJ/hr].

property h: float#

Specific enthalpy [kJ/kmol].

property S: float#

Absolute entropy flow rate [kJ/hr/K].

property Hnet: float#

Total enthalpy flow rate (including heats of formation) [kJ/hr].

property Hf: float#

Enthalpy of formation flow rate [kJ/hr].

property LHV: float#

Lower heating value flow rate [kJ/hr].

property HHV: float#

Higher heating value flow rate [kJ/hr].

property Hvap: float#

Enthalpy of vaporization flow rate [kJ/hr].

property C: float#

Isobaric heat capacity flow rate [kJ/K/hr].

property z_mol: ndarray[Any, dtype[float]]#

Molar composition.

property z_mass: ndarray[Any, dtype[float]]#

Mass composition.

property z_vol: ndarray[Any, dtype[float]]#

Volumetric composition.

property MW: float#

Overall molecular weight.

property V: float#

Molar volume [m^3/mol].

property kappa: float#

Thermal conductivity [W/m/k].

property Cn: float#

Molar isobaric heat capacity [J/mol/K].

property mu: float#

Hydrolic viscosity [Pa*s].

property sigma: float#

Surface tension [N/m].

property epsilon: float#

Relative permittivity [-].

property Cp: float#

Isobaric heat capacity [J/g/K].

property alpha: float#

Thermal diffusivity [m^2/s].

property rho: float#

Density [kg/m^3].

property nu: float#

Kinematic viscosity [m^2/s].

property Pr: float#

Prandtl number [-].

property available_chemicals: list[Chemical]#

All chemicals with nonzero flow.

in_thermal_equilibrium(other)[source]#

Return whether or not stream is in thermal equilibrium with another stream.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> stream = Stream(Water=1, T=300)
>>> other = Stream(Water=1, T=300)
>>> stream.in_thermal_equilibrium(other)
True
classmethod sum(streams, ID=None, thermo=None, energy_balance=True, vle=False)[source]#

Return a new Stream object that represents the sum of all given streams.

Examples

Sum two streams:

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, units='kg/hr')
>>> s_sum = tmo.Stream.sum([s1, s1], 's_sum')
>>> s_sum.show(flow='kg/hr')
Stream: s_sum
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water    40
              Ethanol  20

Sum two streams with new property package:

>>> thermo = tmo.Thermo(['Water', 'Ethanol', 'Methanol'], cache=True)
>>> s_sum = tmo.Stream.sum([s1, s1], 's_sum', thermo)
>>> s_sum.show(flow='kg/hr')
Stream: s_sum
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water    40
              Ethanol  20
separate_out(other, energy_balance=True)[source]#

Separate out given stream from this one.

Examples

Separate out another stream with the same thermodynamic property package:

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=30, Ethanol=10, units='kg/hr')
>>> s2 = tmo.Stream('s2', Water=10, Ethanol=5, units='kg/hr')
>>> s1.separate_out(s2)
>>> s1.show(flow='kg/hr')
Stream: s1
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water    20
              Ethanol  5

It’s also possible to separate out streams with different property packages so long as all chemicals are defined in the mixed stream’s property package:

>>> tmo.settings.set_thermo(['Water'], cache=True)
>>> s1 = tmo.Stream('s1', Water=40, units='kg/hr')
>>> tmo.settings.set_thermo(['Ethanol'], cache=True)
>>> s2 = tmo.Stream('s2', Ethanol=20, units='kg/hr')
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s_mix = tmo.Stream.sum([s1, s2], 's_mix')
>>> s_mix.separate_out(s2)
>>> s_mix.show(flow='kg/hr')
Stream: s_mix
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water  40

Removing empty streams is fine too:

>>> s1.empty(); s_mix.separate_out(s1)
>>> s_mix.show(flow='kg/hr')
Stream: s_mix
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water  40
mix_from(others, energy_balance=True, vle=False, Q=0.0, conserve_phases=False)[source]#

Mix all other streams into this one, ignoring its initial contents.

Notes

When streams at different pressures are mixed, BioSTEAM assumes valves reduce the pressure of the streams being mixed to prevent backflow (pressure needs to decrease in the direction of flow according to Bernoulli’s principle). The outlet pressure will be the minimum pressure of all streams being mixed.

Examples

Mix two streams with the same thermodynamic property package:

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, units='kg/hr')
>>> s2 = s1.copy('s2')
>>> s1.mix_from([s1, s2])
>>> s1.show(flow='kg/hr')
Stream: s1
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water    40
              Ethanol  20

It’s also possible to mix streams with different property packages so long as all chemicals are defined in the mixed stream’s property package:

>>> tmo.settings.set_thermo(['Water'], cache=True)
>>> s1 = tmo.Stream('s1', Water=40, units='kg/hr')
>>> tmo.settings.set_thermo(['Ethanol'], cache=True)
>>> s2 = tmo.Stream('s2', Ethanol=20, units='kg/hr')
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s_mix = tmo.Stream('s_mix')
>>> s_mix.mix_from([s1, s2])
>>> s_mix.show(flow='kg/hr')
Stream: s_mix
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water    40
              Ethanol  20

Mixing empty streams is fine too:

>>> s1.empty(); s2.empty(); s_mix.mix_from([s1, s2])
>>> s_mix.show()
Stream: s_mix
phase: 'l', T: 298.15 K, P: 101325 Pa
flow: 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')
>>> 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')
Stream: s1
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water    10
              Ethanol  1
>>> s2.show(flow='kg/hr')
Stream: s2
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water    10
              Ethanol  9

Link with another stream.

Parameters:
  • other (Stream) –

  • flow (bool, optional) – Whether to link the flow rate data. Defaults to True.

  • phase (bool, optional) – Whether to link the phase. Defaults to True.

  • TP (bool, optional) – Whether to link the temperature and pressure. Defaults to True.

See also

flow_proxy, proxy

Examples

>>> 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.Stream('s2')
>>> s2.link_with(s1)
>>> s1.mol is s2.mol
True
>>> s2.thermal_condition is s1.thermal_condition
True
>>> s1.phase = 'g'
>>> s2.phase
'g'

Unlink stream from other streams.

Examples

>>> 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.Stream('s2')
>>> s2.link_with(s1)
>>> s1.unlink()
>>> s2.mol is s1.mol
False
>>> s1.phases = s2.phases = ('l', 'g')
>>> s2.link_with(s1)
>>> s1.imol.data is s2.imol.data
True
>>> s1.unlink()
>>> s1.imol.data is s2.imol.data
False

MultiStream phases cannot be unlinked:

>>> s1 = tmo.MultiStream(None, phases=('l', 'g'))
>>> s1['g'].unlink()
Traceback (most recent call last):
RuntimeError: phase is locked; stream cannot be unlinked
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.Stream('s1', 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')
Stream: s1
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): 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.Stream('s1', 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')
Stream: s1
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water  2
copy_thermal_condition(other)[source]#

Copy thermal conditions (T and P) of another stream.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=2, units='kg/hr')
>>> s2 = tmo.Stream('s2', Water=1, units='kg/hr', T=300.00)
>>> s1.copy_thermal_condition(s2)
>>> s1.show(flow='kg/hr')
Stream: s1
phase: 'l', T: 300 K, P: 101325 Pa
flow (kg/hr): Water  2
copy_phase(other)[source]#

Copy phase from another stream.

copy_flow(other, 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.

  • remove (bool, optional) – If True, copied chemicals will be removed from stream.

  • exclude (bool, optional) – If True, exclude designated chemicals when copying.

Examples

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.Stream('s2')

Copy all flows:

>>> s2.copy_flow(s1)
>>> s2.show(flow='kg/hr')
Stream: s2
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water    20
              Ethanol  10

Reset and copy just water flow:

>>> s2.empty()
>>> s2.copy_flow(s1, 'Water')
>>> s2.show(flow='kg/hr')
Stream: s2
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water  20

Reset and copy all flows except water:

>>> s2.empty()
>>> s2.copy_flow(s1, 'Water', exclude=True)
>>> s2.show(flow='kg/hr')
Stream: s2
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Ethanol  10

Cut and paste flows:

>>> s2.copy_flow(s1, remove=True)
>>> s2.show(flow='kg/hr')
Stream: s2
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water    20
              Ethanol  10
>>> s1.show()
Stream: s1
phase: 'l', T: 298.15 K, P: 101325 Pa
flow: 0

Its also possible to copy flows from a multistream:

>>> s1.phases = ('g', 'l')
>>> s1.imol['g', 'Water'] = 10
>>> s2.copy_flow(s1, remove=True)
>>> s2.show()
Stream: s2
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kmol/hr): Water  10
>>> s1.show()
MultiStream: s1
phases: ('g', 'l'), T: 298.15 K, P: 101325 Pa
 flow: 0

Copy flows except except water and remove water:

>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, units='kg/hr')
>>> s2 = tmo.Stream('s2')
>>> s2.copy_flow(s1, 'Water', exclude=True, remove=True)
>>> s1.show('wt')
Stream: s1
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water  20
>>> s2.show('wt')
Stream: s2
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Ethanol  10
copy(ID=None, thermo=None)[source]#

Return a copy of the stream.

Examples

Create a copy of a new stream:

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, units='kg/hr')
>>> s1_copy = s1.copy('s1_copy')
>>> s1_copy.show(flow='kg/hr')
Stream: s1_copy
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kg/hr): Water    20
              Ethanol  10

Warning

Prices, and LCA characterization factors are not copied.

flow_proxy(ID=None)[source]#

Return a new stream that shares flow rate data with this one.

See also

link_with, proxy

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, units='kg/hr')
>>> s2 = s1.flow_proxy()
>>> s2.mol is s1.mol
True
proxy(ID=None)[source]#

Return a new stream that shares all data with this one.

See also

link_with, flow_proxy

Warning

Price and characterization factor data is not shared

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, units='kg/hr')
>>> s2 = s1.proxy()
>>> s2.imol is s1.imol and s2.thermal_condition is s1.thermal_condition
True
empty()[source]#

Empty stream flow rates.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, units='kg/hr')
>>> s1.empty()
>>> s1.F_mol
0
property vle: VLE#

An object that can perform vapor-liquid equilibrium on the stream.

property lle: LLE#

An object that can perform liquid-liquid equilibrium on the stream.

property sle: SLE#

An object that can perform solid-liquid equilibrium on the stream.

vlle(T, P)[source]#

Estimate vapor-liquid-liquid equilibrium.

Warning

This method may be as slow as 1 second.

property vle_chemicals: list[Chemical]#

Chemicals cabable of liquid-liquid equilibrium.

property lle_chemicals: list[Chemical]#

Chemicals cabable of vapor-liquid equilibrium.

get_bubble_point(IDs=None)[source]#

Return a BubblePoint object capable of computing bubble points.

Parameters:

IDs (Sequence`[:py:class:`str], optional) – Chemicals that participate in equilibrium. Defaults to all chemicals in equilibrium.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, T=350, units='kg/hr')
>>> s1.get_bubble_point()
BubblePoint([Water, Ethanol])
get_dew_point(IDs=None)[source]#

Return a DewPoint object capable of computing dew points.

Parameters:

IDs (Sequence`[:py:class:`str], optional) – Chemicals that participate in equilibrium. Defaults to all chemicals in equilibrium.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, T=350, units='kg/hr')
>>> s1.get_dew_point()
DewPoint([Water, Ethanol])
bubble_point_at_T(T=None, IDs=None)[source]#

Return a BubblePointResults object with all data on the bubble point at constant temperature.

Parameters:
  • T (float, optional) – Temperature [K].

  • IDs (Sequence`[:py:class:`str], optional) – Chemicals that participate in equilibrium. Defaults to all chemicals in equilibrium.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, T=350, units='kg/hr')
>>> s1.bubble_point_at_T()
BubblePointValues(T=350.00, P=76463, IDs=('Water', 'Ethanol'), z=[0.836 0.164], y=[0.488 0.512])
bubble_point_at_P(P=None, IDs=None)[source]#

Return a BubblePointResults object with all data on the bubble point at constant pressure.

Parameters:

IDs (Sequence`[:py:class:`str], optional) – Chemicals that participate in equilibrium. Defaults to all chemicals in equilibrium.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, T=350, units='kg/hr')
>>> s1.bubble_point_at_P()
BubblePointValues(T=357.14, P=101325, IDs=('Water', 'Ethanol'), z=[0.836 0.164], y=[0.492 0.508])
dew_point_at_T(T=None, IDs=None)[source]#

Return a DewPointResults object with all data on the dew point at constant temperature.

Parameters:

IDs (Sequence`[:py:class:`str], optional) – Chemicals that participate in equilibrium. Defaults to all chemicals in equilibrium.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, T=350, units='kg/hr')
>>> s1.dew_point_at_T()
DewPointValues(T=350.00, P=49058, IDs=('Water', 'Ethanol'), z=[0.836 0.164], x=[0.984 0.016])
dew_point_at_P(P=None, IDs=None)[source]#

Return a DewPointResults object with all data on the dew point at constant pressure.

Parameters:

IDs (Sequence`[:py:class:`str], optional) – Chemicals that participate in equilibrium. Defaults to all chemicals in equilibrium.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, T=350, units='kg/hr')
>>> s1.dew_point_at_P()
DewPointValues(T=368.62, P=101325, IDs=('Water', 'Ethanol'), z=[0.836 0.164], x=[0.983 0.017])
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.Stream('s1', Water=20, Ethanol=10, Methanol=10, units='kmol/hr')
>>> s1.get_normalized_mol(('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.Stream('s1', Water=20, Ethanol=10, Methanol=10, units='kg/hr')
>>> s1.get_normalized_mass(('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.Stream('s1', Water=20, Ethanol=10, Methanol=10, units='m3/hr')
>>> s1.get_normalized_vol(('Water', 'Ethanol'))
array([0.667, 0.333])
get_molar_fraction(IDs)[source]#

Return molar fraction 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.Stream('s1', Water=20, Ethanol=10, Methanol=10, units='kmol/hr')
>>> s1.get_molar_fraction(('Water', 'Ethanol'))
array([0.5 , 0.25])
get_molar_composition(IDs)#

Return molar fraction 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.Stream('s1', Water=20, Ethanol=10, Methanol=10, units='kmol/hr')
>>> s1.get_molar_fraction(('Water', 'Ethanol'))
array([0.5 , 0.25])
get_mass_fraction(IDs)[source]#

Return mass fraction 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.Stream('s1', Water=20, Ethanol=10, Methanol=10, units='kg/hr')
>>> s1.get_mass_fraction(('Water', 'Ethanol'))
array([0.5 , 0.25])
get_mass_composition(IDs)#

Return mass fraction 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.Stream('s1', Water=20, Ethanol=10, Methanol=10, units='kg/hr')
>>> s1.get_mass_fraction(('Water', 'Ethanol'))
array([0.5 , 0.25])
get_volumetric_fraction(IDs)[source]#

Return volumetric fraction 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.Stream('s1', Water=20, Ethanol=10, Methanol=10, units='m3/hr')
>>> s1.get_volumetric_fraction(('Water', 'Ethanol'))
array([0.5 , 0.25])
get_volumetric_composition(IDs)#

Return volumetric fraction 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.Stream('s1', Water=20, Ethanol=10, Methanol=10, units='m3/hr')
>>> s1.get_volumetric_fraction(('Water', 'Ethanol'))
array([0.5 , 0.25])
get_concentration(IDs, units=None)[source]#

Return concentration of given chemicals.

Parameters:
  • IDs (Sequence`[:py:class:`str]) – IDs of chemicals.

  • units (str, optional) – Units of measure. Defaults to kmol/m3.

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol', 'Methanol'], cache=True)
>>> s1 = tmo.Stream('s1', Water=20, Ethanol=10, Methanol=10, units='m3/hr')
>>> s1.get_concentration(['Water', 'Ethanol']) # kg/m3
array([27.673,  4.261])
>>> s1.get_concentration(['Water', 'Ethanol'], 'g/L')
array([498.532, 196.291])
property P_vapor: float#

Vapor pressure of liquid.

receive_vent(other, energy_balance=True, ideal=False)[source]#

Receive vapors from another stream by vapor-liquid equilibrium between a gas and liquid stream assuming only a small amount of chemicals in vapor-liquid equilibrium is present

Examples

The energy balance is performed by default:

>>> import thermosteam as tmo
>>> chemicals = tmo.Chemicals(['Water', 'Ethanol', 'Methanol', tmo.Chemical('N2', phase='g')], cache=True)
>>> tmo.settings.set_thermo(chemicals)
>>> s1 = tmo.Stream('s1', N2=20, units='m3/hr', phase='g', T=330)
>>> s2 = tmo.Stream('s2', Water=10, Ethanol=2, T=330)
>>> s1.receive_vent(s2)
>>> s1.show(flow='kmol/hr')
Stream: s1
phase: 'g', T: 323.12 K, P: 101325 Pa
flow (kmol/hr): Water    0.0799
                Ethanol  0.0887
                N2       0.739

Set energy balance to false to receive vent isothermally:

>>> import thermosteam as tmo
>>> chemicals = tmo.Chemicals(['Water', 'Ethanol', 'Methanol', tmo.Chemical('N2', phase='g')], cache=True)
>>> tmo.settings.set_thermo(chemicals)
>>> s1 = tmo.Stream('s1', N2=20, units='m3/hr', phase='g', T=330)
>>> s2 = tmo.Stream('s2', Water=10, Ethanol=2, T=330)
>>> s1.receive_vent(s2, energy_balance=False)
>>> s1.show(flow='kmol/hr')
Stream: s1
phase: 'g', T: 330 K, P: 101325 Pa
flow (kmol/hr): Water    0.112
                Ethanol  0.123
                N2       0.739
property phases: tuple[str, ...]#

All phases present.

reduce_phases()[source]#

Remove empty phases.

property ID#

Unique identification (str). If set as ‘’, it will choose a default ID.

get_property(name, units=None)#

Return property in requested units.

Parameters:
  • name (str) – Name of property.

  • units (str, optional) – Units of measure. Defaults to the property’s original units of measure.

set_property(name, value, units=None)#

Set property in given units.

Parameters:
  • name (str) – Name of property.

  • value (float) – New value of property.

  • units (str, optional) – Units of measure.

show(layout=None, T=None, P=None, flow=None, composition=None, N=None, IDs=None, sort=None, df=None)[source]#

Print all specifications.

Parameters:
  • layout (str, optional) – Convenience paramater for passing flow, composition, and N. Must have the form {‘c’ or ‘’}{‘wt’, ‘mol’ or ‘vol’}{# or ‘’}. For example: ‘cwt100’ corresponds to compostion=True, flow=’kg/hr’, and N=100.

  • T (str, optional) – Temperature units.

  • P (str, optional) – Pressure units.

  • flow (str, optional) – Flow rate units.

  • composition (bool, optional) – Whether to show composition.

  • N (int, optional) – Number of compounds to display.

  • IDs (Sequence`[:py:class:`str], optional) – IDs of compounds to display. Defaults to all chemicals.

  • sort (bool, optional) – Whether to sort flows in descending order.

  • df (bool, optional) – Whether to return a pandas DataFrame.

Examples

Show a stream’s composition by weight for only the top 2 chemicals with the highest mass fractions:

>>> import biosteam as bst
>>> bst.settings.set_thermo(['Water', 'Ethanol', 'Methanol', 'Propanol'])
>>> stream = bst.Stream('stream', Water=0.5, Ethanol=1.5, Methanol=0.2, Propanol=0.3, units='kg/hr')
>>> stream.show('cwt2s') # Alternatively: stream.show(composition=True, flow='kg/hr', N=2, sort=True)
Stream: stream
phase: 'l', T: 298.15 K, P: 101325 Pa
composition (%): Ethanol  60
                 Water    20
                 ...      20
                 -------  2.5 kg/hr
print(units=None)[source]#

Print in a format that you can use recreate the stream.

Parameters:

units (str, optional) – Units of measure for material flow rates. Defaults to ‘kmol/hr’

Examples

>>> import thermosteam as tmo
>>> tmo.settings.set_thermo(['Water', 'Ethanol'], cache=True)
>>> s1 = tmo.Stream(ID='s1',
...                 Water=20, Ethanol=10, units='kg/hr',
...                 T=298.15, P=101325, phase='l')
>>> s1.print(units='kg/hr')
Stream(ID='s1', phase='l', T=298.15, P=101325, Water=20, Ethanol=10, units='kg/hr')
>>> s1.print() # Units default to kmol/hr
Stream(ID='s1', phase='l', T=298.15, P=101325, Water=1.11, Ethanol=0.2171, units='kmol/hr')