streams#

Which stream class to use?#

QSDsan can work with three main stream classes: thermosteam.Stream, SanStream, and WasteStream. Follow this flowchart to decide which class you want to use.

https://lucid.app/publicSegments/view/5aae11af-e8cf-434a-939d-9abe07cb1b82/image.png

Essentially,

thermosteam.Stream

SanStream

WasteStream

Capable of doing LCA?

No

Yes

Yes

Has wastewater-specific properties?

No

No

Yes

Note

Regardless of which stream class you choose, you always use Component and Components instead of thermosteam.Chemical and thermosteam.Chemicals to indicate which components to include in your system, this is true even if you choose to use thermosteam.Stream and all of the components are pure chemicals. Although in that case, it might be more straightforward to use BioSTEAM instead of QSDsan unless you want to include environmental impacts in your analyses.

SanStream#

class qsdsan.SanStream(ID='', flow=(), phase='l', T=298.15, P=101325.0, units='kg/hr', price=0.0, thermo=None, stream_impact_item=None, **component_flows)#

A subclass of thermosteam.Stream with additional attributes for environmental impacts.

Note

Parameters below only include the ones additional to those of thermosteam.Stream.

Parameters:

stream_impact_item (StreamImpactItem) – The StreamImpactItem this stream is linked to.

Examples

WasteStream

add_indicators(ID='', **indicator_CFs)#

Add impact characterization factors for the stream.

Parameters:
  • ID (str) – Alternative ID of the impact item.

  • indicator_CFs (kwargs) – Impact indicators and their characterization factors (CFs), can be in the form of str=float or str=(float, unit).

See also

get_impacts()

property characterization_factors#
copy(new_ID='', copy_price=False, copy_impact_item=False)#

Copy the information of another stream.

There are three functions related to copying: copy, copy_like, and copy_flow, and they have slight differences in using.

Both copy and copy_like makes the new stream the same as the original one (other than that the new stream does not have the cost), but when using copy, you do not need to pre-create the new stream, (i.e., you can just do new_stream = original_stream.copy('new_ID')), but to use copy_like, you need to firstly create the new stream, then new_stream.copy_like(original_stream).

For copy_flow, it is similar to copy_like in that you need to firstly creating the new stream, but unlike copy_flow that copies properties such as temperature, pressure, copy_flow just copies the mass flow information, but you can choose which component to copy.

Parameters:
  • new_ID (str) – ID of the new stream, a default ID will be assigned if not provided.

  • copy_price (bool) – If True, price of the new stream will be set to be the same as the original stream.

  • copy_impact_item (bool) – If True and the original stream has an StreamImpactItem, then a new StreamImpactItem will be created for the new stream and the new impact item will be linked to the original impact item.

copy_flow(other, IDs=Ellipsis, *, remove=False, exclude=False)#

Copy only the mass flow of another stream without creating a new stream.

Parameters:
  • other (obj) – The stream where mass flows will be copied from.

  • IDs=... (Iterable(str), defaults to all components.) – IDs of the components to be copied from.

  • remove=False (bool, optional) – If True, copied components will be removed from the original stream.

  • exclude=False (bool, optional) – If True, exclude designated components when copying.

See also

copy() for the differences between copy, copy_like, and copy_flow.

copy_like(other, copy_price=False, copy_impact_item=False)#

Copy the information of another stream without creating a new stream.

Parameters:
  • other (obj) – The stream where mass flows and stream properties will be copied from.

  • copy_price (bool) – If True, price of the new stream will be set to be the same as the original stream.

  • copy_impact_item (bool) – If True and the original stream has an StreamImpactItem, then a new StreamImpactItem will be created for the new stream and the new impact item will be linked to the original impact item.

See also

copy() for the differences between copy, copy_like, and copy_flow.

static degassing(original_stream, receiving_stream=None, gas_IDs=())#

Remove all the gas components from the original stream, if receiving_stream is given, then the gas components will be transferred to the receiving stream.

If gas_IDs is not provided, then the gas components will be those either have locked_state == “g” or particle_size == “Dissolved gas”.

Parameters:
  • original_stream (None or obj) – The stream where the gas components will be removed.

  • receiving_stream (None or obj) – The stream to receive the gas components.

  • gas_IDs (Iterable(str)) – IDs of the gas components to be removed, will be set according to the component properties if not provided.

static filtering(original_stream, receiving_stream=None, solid_IDs=())#

Remove all the solid components from the original stream, if receiving_stream is given, then the solid components will be transferred to the receiving stream.

If solid_IDs is not provided, then the gas components will be those either have locked_state == “g” or particle_size == “Particulate”.

Parameters:
  • original_stream (None or obj) – The stream where the gas components will be removed.

  • receiving_stream (None or obj) – The stream to receive the gas components.

  • solid_IDs (Iterable(str)) – IDs of the solid components to be removed, will be set according to the component properties if not provided.

flow_proxy(ID=None)#

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

Parameters:

ID (str) – ID of the new proxy stream.

Examples

>>> from qsdsan import set_thermo, SanStream
>>> from qsdsan.utils import create_example_components
>>> cmps = create_example_components()
>>> set_thermo(cmps)
>>> ss1 = SanStream('ss1', Water=100, NaCl=1, price=3.18)
>>> ss2 = ss1.flow_proxy('ss2')
>>> ss2.mol is ss1.mol
True
>>> ss2.thermal_condition is ss1.thermal_condition
False
static from_stream(stream, ID='', **kwargs)#

Cast a thermosteam.Stream or biosteam.utils.MissingStream to SanStream or MissingSanStream.

Note

Price is not copied unless specified.

Parameters:
  • stream (thermosteam.Stream) – The original stream.

  • ID (str) – ID of the new stream (not applicable for missing streams), default ID will be used if not provided.

  • kwargs ({}) – Additional properties of the new stream.

Examples

For missing streams, but it’s almost always for unit initialization, you don’t really need to interact with this class

>>> import biosteam as bst, qsdsan as qs
>>> ms = bst.utils.MissingStream(source=None, sink=None)
>>> mss = qs.SanStream.from_stream(ms)
>>> mss
<MissingSanStream>

For actual streams

>>> cmps = qs.Components.load_default()
>>> qs.set_thermo(cmps)
>>> s = qs.Stream('s', H2O=100, price=5)
>>> s.show()
Stream: s
 phase: 'l', T: 298.15 K, P: 101325 Pa
 flow (kmol/hr): H2O  100
>>> s.price
5.0
>>> ss = qs.SanStream.from_stream(stream=s, ID='ss', T=350, price=10)
>>> ss.show()
SanStream: ss
 phase: 'l', T: 350 K, P: 101325 Pa
 flow (kmol/hr): H2O  100
>>> ss.price
10.0
get_CF()#

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

Parameters:
  • key – Key of impact indicator.

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

  • units – 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(indicator, time=1, time_unit='hour')#

Calculate the impact of the stream for an indicator for a given time frame, the result will be returned as a float.

Parameters:
  • indicator (obj or str) – ImpactIndicator of interest or its ID/alias.

  • time (float) – Time for the impact to be calculated.

  • time_unit (str) – Unit of the time.

See also

get_impacts()

get_impacts(indicators=(), time=1, time_unit='hour')#

Calculate the impact of the stream for different indicators for a given time frame, results will be returned as a dict.

Parameters:
  • indicators (Iterable) – IDs of the impact indicators to be calculated, all impact indicators linked to the stream will be calculated if not given.

  • time (float) – Time for the impact to be calculated.

  • time_unit (str) – Unit of the time.

Examples

>>> import qsdsan as qs
>>> GWP = qs.ImpactIndicator('GlobalWarming', alias='GWP', unit='kg CO2-eq')
>>> FEC = qs.ImpactIndicator('FossilEnergyConsumption', alias='FEC', unit='MJ')
>>> sys = qs.utils.create_example_system()
>>> ethanol = sys.flowsheet.stream.ethanol
>>> ethanol.add_indicators(GWP=2, FEC=(5000, 'kJ'),)
>>> ethanol.stream_impact_item.show()
StreamImpactItem: ethanol_item [per kg]
Linked to       : ethanol
Price           : None USD
ImpactIndicators:
                              Characterization factors
GlobalWarming (kg CO2-eq)                            2
FossilEnergyConsumption (MJ)                         5
>>> # `get_impact` returns a float
>>> ethanol.get_impact('GWP', time=5, time_unit='day')
240.0
>>> # `get_impacts` returns a dict
>>> ethanol.get_impacts()
{'GlobalWarming': 2, 'FossilEnergyConsumption': 5.0}
property impact_item#

Same as stream_impact_item, has been deprecated.

mix_from(others, **kwargs)#

Update this stream to be a mixture of other streams, initial content of this stream will be ignored.

Parameters:

Examples

>>> import qsdsan as qs
>>> cmps = qs.Components.load_default()
>>> qs.set_thermo(cmps)
>>> s1 = qs.Stream('s1', H2O=100, price=5, units='kg/hr')
>>> s2 = qs.SanStream('s2', S_O2=100, units='kg/hr')
>>> s3 = qs.SanStream('s3')
>>> s3.mix_from((s1, s2))
>>> s3.show()
SanStream: s3
 phase: 'l', T: 298.15 K, P: 101325 Pa
 flow (kmol/hr): S_O2  3.13
                 H2O   5.55
proxy(ID=None)#

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

Note that unlike other properties, the price and stream_impact_item of the two streams are not connected, i.e., the price of the new stream will be the same as the original one upon creation, but then they can be different.

Parameters:

ID (str) – ID of the new proxy stream.

Examples

>>> from qsdsan import set_thermo, SanStream
>>> from qsdsan.utils import create_example_components
>>> cmps = create_example_components()
>>> set_thermo(cmps)
>>> ss1 = SanStream('ss1', Water=100, NaCl=1, price=3.18)
>>> ss2 = ss1.proxy('ss2')
>>> ss2.mol is ss1.mol
True
>>> ss2.thermal_condition is ss1.thermal_condition
True
>>> ss2.price = 5.2335
>>> ss1.price
3.18
set_CF()#

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

Parameters:
  • key – Key of impact indicator.

  • value – Characterization factor value.

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

  • units – 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.

property stream_impact_item#

[StreamImpactItem] The StreamImpactItem this stream is linked to.

to_stream(ID='', **kwargs)#

Cast a SanStream to thermosteam.Stream. Attributes and properties not applicable for thermosteam.Stream will be discarded.

Parameters:
  • cls (obj) – class of the stream to be created.

  • ID (str) – If not provided, will use default ID.

Examples

>>> import qsdsan as qs
>>> cmps = qs.Components.load_default()
>>> qs.set_thermo(cmps)
>>> ss = qs.SanStream('ss', H2O=100, price=5)
>>> ss.show()
SanStream: ss
 phase: 'l', T: 298.15 K, P: 101325 Pa
 flow (kmol/hr): H2O  5.55
>>> ss.price
5.0
>>> s = ss.to_stream(ID='s', T=350, price=10)
>>> s.show()
Stream: s
 phase: 'l', T: 350 K, P: 101325 Pa
 flow (kmol/hr): H2O  5.55
>>> s.price
10.0

MissingSanStream#

class qsdsan.MissingSanStream(source=None, sink=None)#

A subclass of biosteam.MissingStream, create a special object that acts as a dummy until replaced by an actual SanStream.

Note

Users usually do not need to interact with this class.

property impact_item#

Same as stream_impact_item, has been deprecated.

materialize_connection(ID='')#

Disconnect this missing stream from any unit operations and replace it with a material stream.

WasteStream#

class qsdsan.WasteStream(ID='', flow=(), phase='l', T=298.15, P=101325.0, units='kg/hr', price=0.0, thermo=None, pH=7.0, SAlk=2.5, COD=None, BOD=None, uBOD=None, ThOD=None, cnBOD=None, TC=None, TOC=None, TN=None, TKN=None, TP=None, TK=None, TMg=None, TCa=None, dry_mass=None, charge=None, ratios=None, stream_impact_item=None, additional_properties={}, **component_flows)#

A subclass of SanStream with additional attributes and methods for wastewater.

Note

[1] Parameters below only include the ones additional to those of thermosteam.Stream.

[2] Properties not defined during during initiation will be calculated using WasteStream.composite().

Parameters:
  • pH (float) – pH of the stream, unitless.

  • SAlk (float) – Alkalinity, in meq/L (or mmol HCO3-/L). Assumed to be mainly bicarbonate.

  • COD (float) – Chemical oxygen demand, in mg/L.

  • BOD (float) – Biochemical oxygen demand, in mg/L, same as BOD5.

  • uBOD (float) – Ultimate biochemical oxygen demand, in mg/L.

  • cnBOD (float) – Carbonaceous nitrogenous BOD, in mg/L. Biochemical oxygen demand including nitrification.

  • ThOD (float) – Theoretical oxygen demand, in mg/L.

  • TC (float) – Total carbon, in mg/L.

  • TOC (float) – Total organic carbon, in mg/L.

  • TN (float) – Total nitrogen, in mg/L.

  • TKN (float) – Total Kjeldahl nitrogen, in mg/L.

  • TP (float) – Total phosphorus, in mg/L.

  • TK (float) – Total potassium, in mg/L.

  • TMg (float) – Total magnesium, in mg/L.

  • TCa (float) – Total calcium, in mg/L.

  • dry_mass (float) – Total solids, dry mass of dissolved and suspended solids, in mg/L.

  • charge (float) – TO BE IMPLEMENTED

  • ratios (float) – TO BE IMPLEMENTED

  • stream_impact_item (StreamImpactItem) – The StreamImpactItem this stream is linked to.

  • additional_properties (dict) – Additional properties (e.g., turbidity).

  • component_flows (dict) – Component flow data.

Examples

WasteStream

property BOD#

[float] Biochemical oxygen demand in mg/L. Same as BOD5.

property BOD5#

[float] 5-day biochemical oxygen demand, in mg/L. Same as BOD.

property COD#

[float] Chemical oxygen demand in mg/L.

property Conc#

[property_array] Mass concentrations, in mg/L (g/m3), same as conc.

property SAlk#

[float] Alkalinity, in meq/L (or mmol HCO3-/L). Assumed to be mainly bicarbonate.

property TC#

[float] Total carbon, in mg/L.

property TCa#

[float] Total calcium, in mg/L.

property TK#

[float] Total potassium, in mg/L.

property TKN#

[float] Total Kjeldahl nitrogen, in mg/L.

property TMg#

[float] Total magnesium, in mg/L.

property TN#

[float] Total nitrogen, in mg/L.

property TOC#

[float] Total organic carbon, in mg/L.

property TP#

[float] Total phosphorus, in mg/L.

property ThOD#

[float] Theoretical oxygen demand, in mg/L.

classmethod bodbased_inf_model(ID='', flow_tot=0.0, units=('L/hr', 'mg/L'), phase='l', T=298.15, P=101325.0, price=0.0, thermo=None, pH=7.0, SAlk=10.0, ratios=None, BOD=250.0, TKN=40.0, TP=10.0, iVSS_TSS=0.75, iSNH_STKN=0.9, iSBOD_BOD=0.25, iSBOD_SCOD=0.5, iBOD_COD=0.58, S_N2=18.0, S_NH4=25.0, S_NO2=0.0, S_NO3=0.0, S_PO4=8.0, S_Ca=140.0, S_Mg=50.0, S_K=28.0, S_CAT=3.0, S_AN=12.0, C_B=40.0, S_CH3OH=0.0, S_Ac=0.0, S_Prop=0.0, X_OHO_PHA=0.0, X_GAO_PHA=0.0, X_PAO_PHA=0.0, X_GAO_Gly=0.0, X_PAO_Gly=0.0, X_U_OHO_E=0.0, X_U_PAO_E=0.0, X_OHO=0.0, X_AOO=0.0, X_NOO=0.0, X_AMO=0.0, X_PAO=0.0, X_PRO=0.0, X_ACO=0.0, X_HMO=0.0, X_MEOLO=0.0, X_FO=0.0, X_FePO4=0.0, X_AlPO4=0.0, X_FeOH=0.0, X_AlOH=0.0, X_MAP=0.0, X_HAP=0.0, X_HDP=0.0, X_PAO_PP=0.0, X_MgCO3=0.0, X_CaCO3=0.0, DO=0.0, S_H2=0.0, S_CH4=0.0)#

Create a waste stream using the BOD influent characterization model, requires the default component set (can be created by load_default())

Normal attributes of the waste streams (e.g., phase, T, Pa, price) can be passed as usual.

Parameters:
  • ID (str) – ID of the stream.

  • flow_tot (float) – Total flowrates.

  • units (tuple(str, str)) – Unit of the flowrate and component concentrations.

Examples

>>> from qsdsan import Components, WasteStream, set_thermo
>>> cmps = Components.load_default()
>>> set_thermo(cmps)
>>> ws = WasteStream.bodbased_inf_model('ws_bodinf', flow_tot=100)
>>> ws.show()
WasteStream: ws_bodinf
 phase: 'l', T: 298.15 K, P: 101325 Pa
 flow (g/hr): S_F        8.72
              S_U_Inf    3.78
              C_B_Subst  4
              X_B_Subst  22.7
              X_U_Inf    3.94
              X_Ig_ISS   4.93
              S_NH4      2.5
              S_PO4      0.8
              S_K        2.8
              S_Ca       14
              S_Mg       5
              S_CO3      12
              S_N2       1.8
              S_CAT      0.3
              S_AN       1.2
              ...
 WasteStream-specific properties:
  pH         : 7.0
  Alkalinity : 10.0 mg/L
  COD        : 431.0 mg/L
  BOD        : 250.0 mg/L
  TC         : 264.9 mg/L
  TOC        : 137.9 mg/L
  TN         : 40.0 mg/L
  TP         : 10.0 mg/L
  TK         : 28.0 mg/L
 Component concentrations (mg/L):
  S_F          87.2
  S_U_Inf      37.8
  C_B_Subst    40.0
  X_B_Subst    226.7
  X_U_Inf      39.4
  X_Ig_ISS     49.3
  S_NH4        25.0
  S_PO4        8.0
  S_K          28.0
  S_Ca         140.0
  S_Mg         50.0
  S_CO3        120.0
  S_N2         18.0
  S_CAT        3.0
  S_AN         12.0
  ...

References

[1] Hydromantis. GPS-X Technical Reference - v8.0. Hydromantis Environmental Software Solutions, Inc. 2019. https://www.hydromantis.com/help/GPS-X/docs/8.0/Technical/index.html

property cnBOD#

[float] Carbonaceous nitrogenous BOD, in mg/L. Biochemical oxygen demand including nitrification.

classmethod codbased_inf_model(ID='', flow_tot=0.0, units=('L/hr', 'mg/L'), phase='l', T=298.15, P=101325.0, price=0.0, thermo=None, pH=7.0, SAlk=10.0, ratios=None, COD=430.0, TKN=40.0, TP=10.0, iVSS_TSS=0.75, iSNH_STKN=0.9, iSCOD_COD=0.25, iSBOD_SCOD=0.5, iBOD_COD=0.58, S_NH4=25.0, S_NO2=0.0, S_NO3=0.0, S_PO4=8.0, S_Ca=140.0, S_Mg=50.0, S_K=28.0, S_CAT=3.0, S_AN=12.0, S_N2=18.0, C_B=40.0, S_CH3OH=0.0, S_Ac=0.0, S_Prop=0.0, X_OHO_PHA=0.0, X_GAO_PHA=0.0, X_PAO_PHA=0.0, X_GAO_Gly=0.0, X_PAO_Gly=0.0, X_U_OHO_E=0.0, X_U_PAO_E=0.0, X_OHO=0.0, X_AOO=0.0, X_NOO=0.0, X_AMO=0.0, X_PAO=0.0, X_PRO=0.0, X_ACO=0.0, X_HMO=0.0, X_MEOLO=0.0, X_FO=0.0, X_FePO4=0.0, X_AlPO4=0.0, X_FeOH=0.0, X_AlOH=0.0, X_MAP=0.0, X_HAP=0.0, X_HDP=0.0, X_PAO_PP=0.0, X_MgCO3=0.0, X_CaCO3=0.0, DO=0.0, S_H2=0.0, S_CH4=0.0)#

Create a waste stream using the COD-based influent characterization model, requires the default component set (can be created by load_default())

Normal attributes of the waste streams (e.g., phase, T, Pa, price) can be passed as usual.

Parameters:
  • ID (str) – ID of the stream.

  • flow_tot (float) – Total flowrates.

  • units (tuple(str, str)) – Unit of the flowrate and component concentrations.

Examples

>>> from qsdsan import Components, WasteStream, set_thermo
>>> cmps = Components.load_default()
>>> set_thermo(cmps)
>>> ws = WasteStream.codbased_inf_model('ws_codinf', flow_tot=100)
>>> ws.show()
WasteStream: ws_codinf
 phase: 'l', T: 298.15 K, P: 101325 Pa
 flow (g/hr): S_F        7.5
              S_U_Inf    3.25
              C_B_Subst  4
              X_B_Subst  22.7
              X_U_Inf    5.58
              X_Ig_ISS   5.23
              S_NH4      2.5
              S_PO4      0.8
              S_K        2.8
              S_Ca       14
              S_Mg       5
              S_CO3      12
              S_N2       1.8
              S_CAT      0.3
              S_AN       1.2
              ...
 WasteStream-specific properties:
  pH         : 7.0
  Alkalinity : 10.0 mg/L
  COD        : 430.0 mg/L
  BOD        : 249.4 mg/L
  TC         : 265.0 mg/L
  TOC        : 137.6 mg/L
  TN         : 40.0 mg/L
  TP         : 10.0 mg/L
  TK         : 28.0 mg/L
 Component concentrations (mg/L):
  S_F          75.0
  S_U_Inf      32.5
  C_B_Subst    40.0
  X_B_Subst    226.7
  X_U_Inf      55.8
  X_Ig_ISS     52.3
  S_NH4        25.0
  S_PO4        8.0
  S_K          28.0
  S_Ca         140.0
  S_Mg         50.0
  S_CO3        120.0
  S_N2         18.0
  S_CAT        3.0
  S_AN         12.0
  ...

References

[1] Hydromantis. GPS-X Technical Reference - v8.0. Hydromantis Environmental Software Solutions, Inc. 2019. https://www.hydromantis.com/help/GPS-X/docs/8.0/Technical/index.html

classmethod codstates_inf_model(ID='', flow_tot=0.0, units=('L/hr', 'mg/L'), phase='l', T=298.15, P=101325.0, price=0.0, thermo=None, pH=7.0, SAlk=10.0, ratios=None, COD=430.0, TKN=40.0, TP=10.0, iVSS_TSS=0.75, iSNH_STKN=0.9, S_NH4=25.0, S_NO2=0.0, S_NO3=0.0, S_PO4=8.0, S_Ca=140.0, S_Mg=50.0, S_K=28.0, S_CAT=3.0, S_AN=12.0, S_N2=18.0, frSUInf=0.05, frSF=0.2, frXCUInf=0.13, frSUE=0.0, frSCH3OH=0.0, frSAc=0.0, frSProp=0.0, frXOHO=0.0, frXAOO=0.0, frXNOO=0.0, frXAMO=0.0, frXPAO=0.0, frXPRO=0.0, frXACO=0.0, frXHMO=0.0, frXMEOLO=0.0, frXFO=0.0, frXOHO_PHA=0.0, frXGAO_PHA=0.0, frXPAO_PHA=0.0, frXGAO_Gly=0.0, frXPAO_Gly=0.0, frXU_OHO_E=0.0, frXU_PAO_E=0.0, X_FePO4=0.0, X_AlPO4=0.0, X_FeOH=0.0, X_AlOH=0.0, X_MAP=0.0, X_HAP=0.0, X_HDP=0.0, X_PAO_PP=0.0, X_MgCO3=0.0, X_CaCO3=0.0, DO=0.0, S_H2=0.0, S_CH4=0.0)#

Create a waste stream using the COD states influent characterization model, requires the default component set (can be created by load_default())

Normal attributes of the waste streams (e.g., phase, T, Pa, price) can be passed as usual.

Parameters:
  • ID (str) – ID of the stream.

  • flow_tot (float) – Total flowrates.

  • units (tuple(str, str)) – Unit of the flowrate and component concentrations.

Examples

>>> from qsdsan import Components, WasteStream, set_thermo
>>> cmps = Components.load_default()
>>> set_thermo(cmps)
>>> ws = WasteStream.codstates_inf_model('ws_codstates', flow_tot=100)
>>> ws.show()
WasteStream: ws_codstates
 phase: 'l', T: 298.15 K, P: 101325 Pa
 flow (g/hr): S_F        8.6
              S_U_Inf    2.15
              C_B_Subst  4
              X_B_Subst  22.7
              X_U_Inf    5.59
              X_Ig_ISS   5.23
              S_NH4      2.5
              S_PO4      0.8
              S_K        2.8
              S_Ca       14
              S_Mg       5
              S_CO3      12
              S_N2       1.8
              S_CAT      0.3
              S_AN       1.2
              ...
 WasteStream-specific properties:
  pH         : 7.0
  Alkalinity : 10.0 mg/L
  COD        : 430.0 mg/L
  BOD        : 221.8 mg/L
  TC         : 265.0 mg/L
  TOC        : 137.6 mg/L
  TN         : 40.0 mg/L
  TP         : 10.0 mg/L
  TK         : 28.0 mg/L
 Component concentrations (mg/L):
  S_F          86.0
  S_U_Inf      21.5
  C_B_Subst    40.0
  X_B_Subst    226.6
  X_U_Inf      55.9
  X_Ig_ISS     52.3
  S_NH4        25.0
  S_PO4        8.0
  S_K          28.0
  S_Ca         140.0
  S_Mg         50.0
  S_CO3        120.0
  S_N2         18.0
  S_CAT        3.0
  S_AN         12.0
  ...

References

[1] Hydromantis. GPS-X Technical Reference - v8.0. Hydromantis Environmental Software Solutions, Inc. 2019. https://www.hydromantis.com/help/GPS-X/docs/8.0/Technical/index.html

composite(variable, flow=False, exclude_gas=True, subgroup=None, particle_size=None, degradability=None, organic=None, volatile=None, specification=None, unit=None)#

Calculate select composite variable with the provided constraints.

Parameters:
  • variable (str) – The composite variable to calculate. One of the followings: (“COD”, “BOD5”, “BOD”, “uBOD”, “NOD”, “ThOD”, “cnBOD”, “C”, “N”, “P”, “K”, “Mg”, “Ca”, “solids”, “charge”).

  • flow (bool) – Whether to return the composite variable in terms of flow or concentration. The default is concentration.

  • exclude_gas (bool) – Whether to exclude dissolved gas species in calculations of oxygen demand or nitrogen variables.

  • subgroup (tuple(str or obj), optional) – Iterable of CompiledComponents (or their IDs) which the composite variable will be calculated for.

  • particle_size ("g", "s", "c", or "x", optional) – Dissolved gas (“g”), soluble (“s”), colloidal (“c”), particulate (“x”). The default is None.

  • degradability ("rb", "sb", "b" or "u", optional) – Readily biodegradable (“rb”), slowly biodegradable (“sb”), biodegradable (“b”), or undegradable (“u”). The default is None.

  • organic (bool, optional) – Organic (True) or inorganic (False). The default is None.

  • volatile (bool, optional) – Volatile (True) or involatile (False). The default is None.

  • specification (str, optional) –

    A group of Component defined through Component.define_group().

    If using the default components (through Components.load_default()) or a subgroup of these default components, the specification can be one of (“S_VFA”, “X_Stor”, “X_ANO”, “X_Bio”, “S_NOx”, “X_PAO_PP”).

    You can also use CompileComponents.define_group() to define your own specification groups.

    The composite variable will be calculated for the intersection of all designated constrains (i.e., subgroup, particle_size, degradability, organic, volatile, and specification).

  • unit (str) – The unit that the result will be returned in. If not provided, result will be in mg/L for concentration and kg/hr for flow, except for charge (mmol/L for concentration, kmol/hr for flow).

Returns:

value – The estimated value of the composite variable in the desired unit.

Return type:

float

Examples

>>> from qsdsan import set_thermo, Components, WasteStream
>>> cmps = Components.load_default()
>>> set_thermo(cmps)
>>> ws = WasteStream.codstates_inf_model('ws', flow_tot=1000, pH=6.8, COD=500, TP=11)
>>> # To calculate the particulate BOD (i.e., xBOD) concentration of the WasteStream object,
>>> # you just need to specify the composite variable as "BOD", and particle size as "x"
>>> ws.composite('BOD', particle_size='x') 
152.83...
>>> # You can also adjust the unit you want the result to be in
>>> ws.composite('BOD', particle_size='x', unit='g/L') 
0.15283...
>>> # To return the particulate BOD mass flow of the WasteStream object,
>>> # set "flow=True"
>>> ws.composite('BOD', flow=True, particle_size='x') 
0.15283
>>> # Unit for flow rate can also be specified
>>> ws.composite('BOD', flow=True, particle_size='x', unit='kg/d') 
3.66791...
>>> # Biomass COD
>>> ws.composite('COD', specification='X_Bio')
0.0
>>> # Nitrogen as nitrate/nitrite
>>> ws.composite('N', specification='S_NOx')
0.0
>>> # Soluble TKN, note that the `TKN` attribute is pre-defined in the default components
>>> # as all components that are not "S_N2", "S_NO2", and "S_NO3"
>>> # For your own components, you can pre-define the group using
>>> # the `define_group` function (e.g., `cmps.define_group`)
>>> ws.composite('N', subgroup=cmps.TKN, particle_size='s') 
27.77...
>>> ws.composite('C', organic=True) 
160.00...
>>> ws.composite('solids', particle_size='s') 
947.49...

See also

CompiledComponents.define_group()

property conc#

[property_array] Mass concentrations, in mg/L (g/m3).

copy(new_ID='', copy_price=False, copy_impact_item=False, ws_properties=True)#

Copy the information of another stream.

There are three functions related to copying: copy, copy_like, and copy_flow, and they have slight differences in using.

Both copy and copy_like makes the new stream the same as the original one (other than that the new stream does not have the cost), but when using copy, you do now need to pre-create the new stream, (i.e., you can just do new_stream = original_stream.copy('new_ID')), but to use copy_like, you need to firstly create the new stream, then new_stream.copy_like(original_stream).

For copy_flow, it is similar to copy_like in that you need to firstly creating the new stream, but unlike copy_flow that copies properties such as temperature, pressure, copy_flow just copies the mass flow information, but you can choose which component to copy.

Parameters:
  • new_ID (str) – ID of the new stream, a default ID will be assigned if not provided.

  • copy_price (bool) – If True, price of the new stream will be set to be the same as the original stream.

  • copy_impact_item (bool) – If True and the original stream has an StreamImpactItem, then a new StreamImpactItem will be created for the new stream and the new impact item will be linked to the original impact item.

  • ws_properties (bool) – Whether to copy wastewater-related properties to the new stream.

copy_like(other, copy_price=False, copy_impact_item=False)#

Copy the information of another stream without creating a new stream.

Parameters:
  • other (obj) – The stream where mass flows and stream properties will be copied from.

  • copy_price (bool) – If True, price of the new stream will be set to be the same as the original stream.

  • copy_impact_item (bool) – If True and the original stream has an StreamImpactItem, then a new StreamImpactItem will be created for the new stream and the new impact item will be linked to the original impact item.

See also

copy() for the differences between copy, copy_like, and copy_flow.

property density#

[float] Density of the stream, in g/L (kg/m3).

property dry_mass#

[float] Total solids, dry mass of dissolved and suspended solids, in mg/L.

static from_stream(stream, ID='', **kwargs)#

Cast a thermosteam.Stream or biosteam.utils.MissingStream to WasteStream or MissingWasteStream.

Note

Price is not copied unless specified.

Parameters:
  • stream (thermosteam.Stream) – The original stream.

  • ID (str) – ID of the new stream (not applicable for missing streams), default ID will be used if not provided.

  • kwargs ({}) – Additional properties of the new stream.

Examples

For missing streams, but it’s almost always for unit initialization, you don’t really need to interact with this class

>>> import biosteam as bst, qsdsan as qs
>>> ms = bst.utils.MissingStream(source=None, sink=None)
>>> mws = qs.WasteStream.from_stream(ms)
>>> mws
<MissingWasteStream>

For actual streams

>>> cmps = qs.Components.load_default()
>>> qs.set_thermo(cmps)
>>> s = qs.Stream('s', H2O=100, price=5)
>>> s.show()
Stream: s
 phase: 'l', T: 298.15 K, P: 101325 Pa
 flow (kmol/hr): H2O  100
>>> s.price
5.0
>>> ws = qs.WasteStream.from_stream(stream=s, ID='ws', T=250, price=8)
>>> ws.show()
WasteStream: ws
 phase: 'l', T: 250 K, P: 101325 Pa
 flow (g/hr): H2O  1.8e+06
 WasteStream-specific properties:
  pH         : 7.0
 Component concentrations (mg/L):
  H2O          992181.4
>>> ws.price
8.0
get_ISS()#

[float] Inorganic/involatile suspended solids, in mg/L.

get_TDS(include_colloidal=True)#

Total dissolved solids (TDS).

Parameters:

include_colloidal (bool, optional) – Whether to include colloidal components as TDS. The default is True.

Returns:

TDS – In mg/L.

Return type:

float

get_TSS(include_colloidal=False)#

Total suspended solids (TSS).

Parameters:

include_colloidal (bool, optional) – Whether to include colloidal components as TSS. The default is False.

Returns:

TSS – In mg/L.

Return type:

float

get_VSS(include_colloidal=False)#

[float] Volatile suspended solids, in mg/L.

get_mass_concentration(unit='g/m3', IDs=None)#

Get mass concentrations in given unit.

Parameters:
  • unit (str, optional) – Unit of measure. The default is ‘g/m3’.

  • IDs (Iterable[str], optional) – IDs of components. When not specified, returns mass concentrations of all components in thermo.

property iconc#

[Indexer] Mass concentrations, in mg/L (g/m3).

mix_from(others, **kwargs)#

Update this stream to be a mixture of other streams, initial content of this stream will be ignored.

Parameters:

Note

Price and impact item are not included.

Examples

>>> import qsdsan as qs
>>> cmps = qs.Components.load_default()
>>> qs.set_thermo(cmps)
>>> s = qs.Stream('s', H2O=100, price=5, units='kg/hr')
>>> ss = qs.SanStream('ss', S_O2=100, units='kg/hr')
>>> ws = qs.WasteStream('ws')
>>> ws.mix_from((s, ss))
>>> ws.show()
WasteStream: ws
 phase: 'l', T: 298.15 K, P: 101325 Pa
 flow (g/hr): S_O2  1e+05
              H2O   1e+05
 WasteStream-specific properties:
  pH         : 7.0
 Component concentrations (mg/L):
  S_O2         450614.6
  H2O          450614.6
property pH#

[float] pH, unitless.

proxy(ID=None)#

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

Note that unlike other properties, the price of the two streams are not connected, i.e., the price of the new stream will be the same as the original one upon creation, but then they can be different.

Parameters:

ID (str) – ID of the new proxy stream.

Examples

>>> from qsdsan import set_thermo, WasteStream
>>> from qsdsan.utils import create_example_components
>>> cmps = create_example_components()
>>> set_thermo(cmps)
>>> ws1 = WasteStream('ws1', Water=100, NaCl=1)
>>> ws2 = ws1.proxy('ws2')
>>> ws2.mol is ws1.mol
True
>>> # Note that concentration is always calculated (mass/vol) upon request,
>>> # so `ws2.conc is ws1.conc` will return False
>>> import numpy as np
>>> np.all(list(ws2.conc==ws1.conc))
True
>>> ws1.imol['Water'] = 10000
>>> np.all(list(ws2.conc==ws1.conc))
True
property ratios#

The ratios used for estimating waste stream composition based on user input upon initialization. Only meaningful for creating a WasteStream object from scratch. If not used or specified, default as None.

property scope#

A tracker of the wastestream’s time-series data during dynamic simulation.

set_flow_by_concentration(flow_tot, concentrations, units=('L/hr', 'mg/L'), bulk_liquid_ID='H2O', atol=1e-05, maxiter=50)#

Set the mass flows of the liquid WasteStream by specifying total volumetric flow and concentrations as well as identifying the component that constitutes the bulk liquid.

Parameters:
  • flow_tot (float) – Total volumetric flow of the WasteStream.

  • concentrations (dict[str, float] | property_array(Stream.iconc)) – Concentrations of components.

  • units (Iterable[str]) – The first indicates the unit for the input total flow, the second indicates the unit for the input concentrations.

  • bulk_liquid_ID (str, optional) – ID of the Component that constitutes the bulk liquid, e.g., the solvent. The default is ‘H2O’.

  • atol (float, optional) – The absolute tolerance of error in estimated WasteStream density. The default is 1e-5 kg/L.

  • maxiter (int, optional) – The maximum number of iterations to estimate the flow of the bulk-liquid component and overall density of the WasteStream. The default is 50.

show(layout=None, T='K', P='Pa', flow='g/hr', composition=False, N=15, stream_info=True, details=True, concentrations='mg/L')#

Print information related to this WasteStream.

Parameters:
  • layout (str) – Shorthand to pass composition, flow, and N information. Should be in the form of {‘c’ or ‘’}{‘wt’, ‘mol’ or ‘vol’}{# or ‘’}. For example: ‘cwt100’ corresponds to composition=True, flow=’kg/hr’, and N=100; ‘mol’ corresponds to composition=False, flow=’kmol/hr’, and N=None. Specifying layout will ignore flow, composition, and N.

  • T (str, optional) – The unit for temperature. The default is ‘K’.

  • P (float, optional) – The unit for pressure. The default is ‘Pa’.

  • flow (str, optional) – The unit for the flow. The default is ‘kg/hr’.

  • composition (bool, optional) – Whether to show flow information of different Component objects in this waste stream as a percentage. The default is False.

  • N (int, optional) – Number of components to print out, when left as None, the number depends on the default of thermosteam. The default is 15.

  • stream_info (bool, optional) – Whether to print stream-specific information. The default is True.

  • details (bool, optional) – Whether to show the all composite variables of this waste stream. The default is True.

classmethod sludge_inf_model(ID='', flow_tot=0.0, units=('L/hr', 'mg/L'), phase='l', T=298.15, P=101325.0, price=0.0, thermo=None, pH=7.0, SAlk=10.0, ratios=None, TSS=10000.0, TKN=750.0, TP=250.0, S_NH4=100.0, S_PO4=50.0, iVSS_TSS=0.65, iscCOD_COD=0.01, iSNH_STKN=0.9, frXUInf_VSS=0.4, frXUE_VSS=0.3, frXOHO_VSS=0.2, frXAOO_VSS=0.01, frXNOO_VSS=0.01, frXPAO_VSS=0.01, frCB_scCOD=0.1, frSU_scCOD=0.8, S_Ca=140.0, S_Mg=50.0, S_K=28.0, S_CAT=3.0, S_AN=12.0, S_N2=18.0, frXACO_VSS=0.0, frXHMO_VSS=0.0, frXPRO_VSS=0.0, frXFO_VSS=0.0, frXMEOLO_VSS=0.0, frXAMO_VSS=0.0, frXOHO_PHA_VSS=0.0, frXGAO_PHA_VSS=0.0, frXPAO_PHA_VSS=0.0, frXGAO_Gly_VSS=0.0, frXPAO_Gly_VSS=0.0, frSCH3OH_scCOD=0.0, frSAc_scCOD=0.0, frSProp_scCOD=0.0, S_NO2=0.0, S_NO3=0.0, X_PAO_PP=0.0, X_FeOH=0.0, X_AlOH=0.0, X_FePO4=0.0, X_AlPO4=0.0, X_MAP=0.0, X_HAP=0.0, X_HDP=0.0, X_MgCO3=0.0, X_CaCO3=0.0, DO=0.0, S_H2=0.0, S_CH4=0.0)#

Create a waste stream using the sludge influent characterization model, requires the default component set (can be created by load_default())

Normal attributes of the waste streams (e.g., phase, T, Pa, price) can be passed as usual.

Parameters:
  • ID (str) – ID of the stream.

  • flow_tot (float) – Total flowrates.

  • units (tuple(str, str)) – Unit of the flowrate and component concentrations.

Examples

>>> from qsdsan import Components, WasteStream, set_thermo
>>> cmps = Components.load_default()
>>> set_thermo(cmps)
>>> ws = WasteStream.sludge_inf_model('ws_sludgeinf', flow_tot=100)
>>> ws.show()
WasteStream: ws_sludgeinf
 phase: 'l', T: 298.15 K, P: 101325 Pa
 flow (g/hr): S_F        1.08
              S_U_Inf    8.65
              C_B_Subst  1.08
              X_B_Subst  81.9
              X_OHO      192
              X_AOO      9.62
              X_NOO      9.62
              X_PAO      9.62
              X_U_Inf    468
              X_U_OHO_E  285
              X_U_PAO_E  14.3
              X_Ig_ISS   298
              S_NH4      10
              S_PO4      5
              S_K        2.8
              ...
 WasteStream-specific properties:
  pH         : 7.0
  Alkalinity : 10.0 mg/L
  COD        : 10814.4 mg/L
  BOD        : 1744.3 mg/L
  TC         : 4246.5 mg/L
  TOC        : 3702.2 mg/L
  TN         : 750.0 mg/L
  TP         : 250.0 mg/L
  TK         : 52.9 mg/L
 Component concentrations (mg/L):
  S_F          10.8
  S_U_Inf      86.5
  C_B_Subst    10.8
  X_B_Subst    819.0
  X_OHO        1924.0
  X_AOO        96.2
  X_NOO        96.2
  X_PAO        96.2
  X_U_Inf      4680.0
  X_U_OHO_E    2852.0
  X_U_PAO_E    142.6
  X_Ig_ISS     2980.6
  S_NH4        100.0
  S_PO4        50.0
  S_K          28.0
  ...

References

[1] Hydromantis. GPS-X Technical Reference - v8.0. Hydromantis Environmental Software Solutions, Inc. 2019. https://www.hydromantis.com/help/GPS-X/docs/8.0/Technical/index.html

property uBOD#

[float] Ultimate biochemical oxygen demand, in mg/L.

MissingWasteStream#

class qsdsan.MissingWasteStream(source=None, sink=None)#

A subclass of MissingSanStream, create a special object that acts as a dummy until replaced by an actual WasteStream.

Note

Users usually do not need to interact with this class.

property BOD#

[float] Biochemical oxygen demand, same as BOD5.

property BOD5#

[float] 5-day biochemical oxygen demand, same as BOD.

property COD#

[float] Chemical oxygen demand.

property SAlk#

[float] Alkalinity.

property TC#

[float] Total carbon.

property TCa#

[float] Total calcium.

property TK#

[float] Total potassium.

property TKN#

[float] Total Kjeldahl nitrogen.

property TMg#

[float] Total magnesium.

property TN#

[float] Total nitrogen.

property TOC#

[float] Total organic carbon.

property TP#

[float] Total phosphorus.

property ThOD#

[float] Theoretical oxygen demand.

property additional_property#

[dict] Additional properties (e.g., turbidity).

property cnBOD#

[float] Carbonaceous nitrogenous BOD.

property density#

[float] Density of the stream, in mg/L (kg/m3).

property dry_mass#

[float] Total solids.

materialize_connection(ID='')#

Disconnect this missing stream from any unit operations and replace it with a material stream.

property pH#

[float] pH, unitless.

property uBOD#

[float] Ultimate biochemical oxygen demand.