Component

class qsdsan.Component(ID, cache=False, search_ID=None, chemical=None, formula=None, phase=None, measured_as=None, i_C=None, i_N=None, i_P=None, i_K=None, i_Mg=None, i_Ca=None, i_mass=None, i_charge=None, i_COD=None, i_NOD=None, f_BOD5_COD=None, f_uBOD_COD=None, f_Vmass_Totmass=None, description=None, particle_size=None, degradability=None, organic=None, **chemical_properties)

A subclass of thermosteam.Chemical with additional attributes and methods for waste treatment.

At a minimum, ID, particle_size, degradability, and organic should be provided.

Parameters:
  • ID (str) – ID for the component, must be unique.

  • search_ID (str) – A name/identifier looked up in the database to build the component. An explicit search_ID that is not found raises a LookupError; a bare ID that is not found falls back to a blank component to fill in manually. Passing a thermosteam.Chemical object to search_ID raises a TypeError.

  • chemical (thermosteam.Chemical) – A pre-built chemical object to build the component from. A name string passed to chemical is accepted as an alias for search_ID. Giving both a Chemical object and a search_ID raises a ValueError.

  • formula (str) – Formula for the component, formula from the database will be used if the component is constructed from the database and it has a formula in the database.

  • phase (str) – If provided, this component will be assumed to only exist in the given phase.

  • i_C (float) – Carbon content of the component, [g C/g measure unit].

  • i_N (float) – Nitrogen content of the component, [g N/g measure unit].

  • i_P (float) – Phosphorus content of the component, [g P/g measure unit].

  • i_K (float) – Potassium content of the component, [g K/g measure unit].

  • i_Mg (float) – Magnesium content of the component, [g Mg/g measure unit].

  • i_Ca (float) – Calcium content of the component, [g Ca/g measure unit].

  • i_mass (float) – Mass content of the component, [g Component/g measure unit].

  • i_charge (float) – Charge content of the component, [mol +/g measure unit]. Positive values indicate cations and negative values indicate anions.

  • i_COD (float) – COD content, calculated based on measured_as, organic, and formula if not given.

  • i_NOD (float) – Nitrogenous oxygen demand, calculated based on measured_as, degradability, and formula if not given.

  • f_BOD5_COD (float) – BOD5 fraction in COD of the component, unitless.

  • f_uBOD_COD (float) – Ultimate BOD fraction in COD of the component, unitless.

  • f_Vmass_Totmass (float) – Volatile fraction of the mass of the component, unitless.

  • description (str) – Description of the component.

  • measured_as (str) – The unit as which the component is measured. Can be left as blank or chosen from ‘COD’, or a constituent element of the component.

  • particle_size (str) – Size of the component based on the type. Must be chosen from ‘Dissolved gas’, ‘Soluble’, ‘Colloidal’, or ‘Particulate’.

  • degradability (str) – Degradability of the Component. Must be chosen from ‘Readily’, ‘Slowly’, or ‘Undegradable’.

  • organic (bool) – True (organic) or False (inorganic).

  • chemical_properties (kwargs) – Will be passed to thermosteam.Chemical.

  • note:: (..) –

    [1] Element contents like i_C, i_N, i_P, i_K, i_Mg, and i_Ca will be calculated based on formula and measured_as if given; and the content value will be 1 if the component is measured as this element.

    [2] For fractions including f_BOD5_COD, f_uBOD_COD, and f_Vmass_Totmass, their values must be within [0, 1].

    [3] If no formula or MW is provided, then MW of this component is assumed to 1 to avoid ZeroDivisionError exception in calculation.

    [4] Molar flowrate of a component, if not given, will always be calculated using the mass flowrate data and the MW of this component. If measured_as is not None, i.e., the mass flowrate data is interpreted in the measured_as unit, the calculated molar flowrate would be inaccurate unless user adjusts the MW value accordingly. However, this is irrelevant if the component itself does not have a sensible MW anyway.

Examples

Component

copy(new_ID, **data)

Return a new Component object with the same settings with alternative data set by kwargs.

Note that aliases will not be copied.

property degradability

[str] Degradability of the Component. Must be chosen from ‘Readily’, ‘Slowly’, or ‘Undegradable’.

property description

[str] Description of the component.

property f_BOD5_COD

BOD5 fraction in COD of the component, unitless. Must be within [0, 1] and must be less than or equal to f_uBOD_COD.

property f_Vmass_Totmass

[float] Volatile fraction of the mass of the component, unitless. Must be within [0, 1].

property f_uBOD_COD

[float] Ultimate BOD fraction in COD of the component, unitless. Must be within [0, 1] and must be larger than or equal to f_BOD5_COD.

property formula

[str] Chemical atomic formula.

classmethod from_chemical(ID, chemical=None, formula=None, phase=None, measured_as=None, i_C=None, i_N=None, i_P=None, i_K=None, i_Mg=None, i_Ca=None, i_mass=None, i_charge=None, i_COD=None, i_NOD=None, f_BOD5_COD=None, f_uBOD_COD=None, f_Vmass_Totmass=None, description=None, particle_size=None, degradability=None, organic=None, **data)

Return a new Component from a thermosteam.Chemical object.

This is a thin wrapper around the Component constructor, which accepts the same chemical keyword directly. That is, Component.from_chemical(ID, chemical, ...) is equivalent to Component(ID, chemical=chemical, ...); both validate the particle_size/degradability/organic inputs at creation.

Note

This method is retained for backward compatibility. For a database name lookup, prefer Component(ID, search_ID='name', ...); and Component.from_chemical(ID, chemical=obj_or_name, ...) is equivalent to Component(ID, chemical=obj_or_name, ...).

E.g., do

S_O = Component(ID='S_O', search_ID='O2', ...)

instead of

S_O = Component.from_chemical(ID='S_O', chemical='O2', ...)

Examples

>>> from qsdsan import Component
>>> Struvite = Component.from_chemical('Struvite',
...                                    chemical='MagnesiumAmmoniumPhosphate',
...                                    formula='NH4MgPO4·H12O6',
...                                    phase='l', particle_size='Particulate',
...                                    degradability='Undegradable', organic=False)
>>> Struvite.show(chemical_info=True)
Component: Struvite (phase_ref='l') at phase='l'
[Names]  CAS: 7785-21-9
         InChI: Mg.H3N.H3O4P/c;;1-5(...
         InChI_key: MXZRMHIULZDAKC-U...
         common_name: 7785-21-9
         iupac_name: ('azanium;magne...
         pubchemid: 1.7873e+05
         smiles: [NH4+].[O-]P(=O)([O...
         formula: NH4MgPO4·H12O6
[Groups] Dortmund: <Empty>
         UNIFAC: <Empty>
         PSRK: <Empty>
         NIST: <Empty>
[Data]   MW: 245.41 g/mol
         Tm: None
         Tb: None
         Tt: None
         Tc: None
         Pt: None
         Pc: None
         Vc: None
         Hf: None
         S0: 0 J/K/mol
         LHV: None
         HHV: None
         Hfus: 0 J/mol
         Sfus: None
         omega: None
         dipole: None
         similarity_variable: 0.080108
         iscyclic_aliphatic: 0
         combustion: None
Component-specific properties:
[Others] measured_as: None
         description: None
         particle_size: Particulate
         degradability: Undegradable
         organic: False
         i_C: 0 g C/g
         i_N: 0.057076 g N/g
         i_P: 0.12621 g P/g
         i_K: 0 g K/g
         i_Mg: 0.09904 g Mg/g
         i_Ca: 0 g Ca/g
         i_mass: 1 g mass/g
         i_charge: 0 mol +/g
         i_COD: 0 g COD/g
         i_NOD: 0 g NOD/g
         f_BOD5_COD: 0
         f_uBOD_COD: 0
         f_Vmass_Totmass: 0
         chem_MW: 245.41
get_missing_properties(properties=None)

Return a list of all missing thermodynamic properties.

property i_C

[float] Carbon content of the component, [g C/g measure unit].

property i_COD

[float] COD content, calculated based on measured_as, organic, and formula if not given.

property i_Ca

[float] Calcium content of the component, [g Ca/g measure unit].

property i_K

[float] Potassium content of the component, [g K/g measure unit].

property i_Mg

[float] Magnesium content of the component, [g Mg/g measure unit].

property i_N

[float] Nitrogen content of the component, [g N/g measure unit].

property i_NOD

[float] Nitrogenous oxygen demand, calculated based on measured_as, degradability, and formula if not given.

property i_P

[float] Phosphorus content of the component, [g P/g measure unit].

property i_charge

[float] Charge content of the component, [mol +/g measure unit]. Positive values indicate cations and negative values indicate anions.

property i_mass

[float] Mass content of the component, [g Component/g measure unit].

property measured_as

[str] The unit as which the component is measured. Can be left as blank or chosen from ‘COD’, or a constituent element of the component.

property organic

[bool] True (organic) or False (inorganic).

property particle_size

[str] Size of the component based on the type. Must be chosen from ‘Dissolved gas’, ‘Soluble’, ‘Colloidal’, or ‘Particulate’.

show(chemical_info=False)

Show component properties.

Parameters:

chemical_info (bool) – Whether to show properties associated with the corresponding Chemical object of the Component. The default is False.

Components

class qsdsan.Components(components, cache=False)

A subclass of thermosteam.Chemicals, contains Component objects as attributes.

Examples

Component

append(component)

Append a Component

static append_combustion_components(components, alt_IDs={}, try_default_compile=True, **default_compile_kwargs)

Return a new Components object with the given components and those needed for combustion reactions (complete oxidation with O2), namely O2, CO2 (for C), H2O (for H), N2 (for N), P4O10 (for P), and SO2 (for S).

If the combustion components are already in the given collection, they will NOT be overwritten.

Parameters:
  • components (Iterable(obj)) – The original components to be appended.

  • alt_IDs (dict) – Alternative IDs for the combustion components to be added as aliases, e.g., if “S_O2” is used instead of “O2”, then pass {‘O2’: ‘S_O2’}.

  • default_compile (bool) – Whether to try default compile when some components are missing key properties for compiling.

  • default_compile_kwargs (dict) – Keyword arguments to pass to default_compile if needed.

Examples

>>> from qsdsan import Components
>>> cmps = Components.load_default()
>>> cmps
CompiledComponents([S_H2, S_CH4, S_CH3OH, S_Ac, S_Prop, S_F, S_U_Inf, S_U_E, C_B_Subst, C_B_BAP, C_B_UAP, C_U_Inf, X_B_Subst, X_OHO_PHA, X_GAO_PHA, X_PAO_PHA, X_GAO_Gly, X_PAO_Gly, X_OHO, X_AOO, X_NOO, X_AMO, X_PAO, X_MEOLO, X_FO, X_ACO, X_HMO, X_PRO, X_U_Inf, X_U_OHO_E, X_U_PAO_E, X_Ig_ISS, X_MgCO3, X_CaCO3, X_MAP, X_HAP, X_HDP, X_FePO4, X_AlPO4, X_AlOH, X_FeOH, X_PAO_PP_Lo, X_PAO_PP_Hi, S_NH4, S_NO2, S_NO3, S_PO4, S_K, S_Ca, S_Mg, S_CO3, S_N2, S_O2, S_CAT, S_AN, H2O])
>>> CH4 = cmps.S_CH4.copy('CH4', phase='g')
>>> cmps = Components.append_combustion_components([*cmps, CH4], alt_IDs=dict(O2='S_O2'))
>>> cmps
CompiledComponents([S_H2, S_CH4, S_CH3OH, S_Ac, S_Prop, S_F, S_U_Inf, S_U_E, C_B_Subst, C_B_BAP, C_B_UAP, C_U_Inf, X_B_Subst, X_OHO_PHA, X_GAO_PHA, X_PAO_PHA, X_GAO_Gly, X_PAO_Gly, X_OHO, X_AOO, X_NOO, X_AMO, X_PAO, X_MEOLO, X_FO, X_ACO, X_HMO, X_PRO, X_U_Inf, X_U_OHO_E, X_U_PAO_E, X_Ig_ISS, X_MgCO3, X_CaCO3, X_MAP, X_HAP, X_HDP, X_FePO4, X_AlPO4, X_AlOH, X_FeOH, X_PAO_PP_Lo, X_PAO_PP_Hi, S_NH4, S_NO2, S_NO3, S_PO4, S_K, S_Ca, S_Mg, S_CO3, S_N2, S_O2, S_CAT, S_AN, H2O, CH4, CO2, N2, P4O10, SO2])
>>> cmps.O2 is cmps.S_O2
True
compile(skip_checks=False, ignore_inaccurate_molar_weight=False, adjust_MW_to_measured_as=False)

Cast as a CompiledComponents object.

Parameters:
  • skip_checks (bool) – Whether to skip checks for missing component properties.

  • ignore_inaccurate_molar_weight (bool) – Components defined with a measured_as basis (e.g. as COD or an element) do not have a molecular weight consistent with that basis, so molar and volumetric calculations with them are inaccurate. Compilation raises an error in that case unless this is set to True. Set to True when you only need mass-based quantities.

  • adjust_MW_to_measured_as (bool) – For measured_as components that have a chemical formula, set to True to adjust their MW (to chem_MW / i_mass) so molar and volumetric calculations are correct. Components without a formula keep MW = 1 and still require ignore_inaccurate_molar_weight=True.

copy()

Return a copy.

default_compile(lock_state_at='l', soluble_ref='Urea', gas_ref='CO2', particulate_ref='Stearin', ignore_inaccurate_molar_weight=False, adjust_MW_to_measured_as=False)

Auto-fill of the missing properties of the components and compile, boiling point (Tb) and molar volume (V) will be copied from the reference component, the remaining missing properties will be copied from those of water.

Parameters:
  • lock_state_at (str) – Lock the state of components at a certain phase, can be ‘g’, ‘l’, ‘s’, or left as empty to avoid locking state. Components that have already been locked will not be affected.

  • soluble_ref (obj or str) – Reference component (or chemical ID) for those with particle_size == ‘Soluble’.

  • gas_ref (obj or str) – Reference component (or chemical ID) for those with particle_size == ‘Dissolved gas’.

  • particulate_ref (obj or str) – Reference component (or chemical ID) for those with particle_size == ‘Particulate’.

  • ignore_inaccurate_molar_weight (bool) – Default is False, need to be manually set to True if having components with measured_as attributes. This is to alert the users that calculations for attributes using molecular weight will be inacurate, unless all components have sensible MWs and adjust_MW_to_measured_as is set to True.

  • adjust_MW_to_measured_as (bool) – Default is False. Manually set it to True to adjust the MW data of components with measured_as attributes and chemical formulas. This is to enable correct calculations of component molar flows when possible. For components without a sensible MW, their MWs will remain 1 by default. This is pertinent for calculations of molar flows and any thermodynamic property of a stream.

Examples

>>> from qsdsan import Component, Components, Stream, set_thermo
>>> X = Component('X', phase='s', measured_as='COD', i_COD=0, description='Biomass',
...               organic=True, particle_size='Particulate', degradability='Readily')
>>> X_inert = Component('X_inert', phase='s', description='Inert biomass', i_COD=0,
...                     organic=True, particle_size='Particulate', degradability='Undegradable')
>>> Substrate = Component('Substrate', phase='s', measured_as='COD', i_mass=18.3/300,
...                       organic=True, particle_size='Particulate', degradability='Readily')
>>> cmps = Components([X, X_inert, Substrate])
>>> # As none of the components above has a chemical formula, i.e., no sensible MW,
>>> # simply set `ignore_inaccurate_molar_weight` to True to bypass error.
>>> cmps.default_compile(ignore_inaccurate_molar_weight=True)
>>> cmps
CompiledComponents([X, X_inert, Substrate])
>>> Ac = Component('Ac', search_ID='CH3COOH', particle_size='Soluble',
...                degradability='Readily', organic=True)
>>> Ac_as_COD = Component('Ac_as_COD', search_ID='CH3COOH', measured_as='COD',
...                       particle_size='Soluble', degradability='Readily', organic=True)
>>> Acs = Components([Ac, Ac_as_COD])
>>> Acs.default_compile(ignore_inaccurate_molar_weight=True,
...                     adjust_MW_to_measured_as=False)
>>> set_thermo(Acs)
>>> # Create a WasteStream object with 1 kmol/hr of each acetic acid component,
>>> # knowing 1 mol acetate is equivalent to 2 mol of O2 demand
>>> s1 = Stream('s1', Ac=60.052, Ac_as_COD=2 * 32, units='kg/hr')
>>> s1.mass
sparse([60.052, 64.   ])
>>> # However, the calculated molar flow is inaccurate because the MW for Ac_as_COD
>>> # is inconsistent with its `measured_as`. This also affects the
>>> # calculation of other thermodynamic properties.
>>> s1.mol
sparse([1.   , 1.066])
>>> s1.vol
sparse([0.05 , 0.054])
>>> # To fix the molar flow calculation, simply set `adjust_MW_to_measured_as` to True when compile.
>>> Acs_MW_adjusted = Components([Ac, Ac_as_COD])
>>> Acs_MW_adjusted.default_compile(adjust_MW_to_measured_as=True)
>>> set_thermo(Acs_MW_adjusted)
>>> s2 = Stream('s2', Ac=60.052, Ac_as_COD=2 * 32, units='kg/hr')
>>> s2.mol
sparse([1., 1.])
>>> s2.vol
sparse([0.05, 0.05])
extend(components)

Extend with more Component objects.

classmethod from_chemicals(chemicals, **data)

Return a new Components from a thermosteam.Chemicals or thermosteam.CompiledChemicals object.

Parameters:

Examples

>>> import qsdsan as qs
>>> chems = qs.Chemicals((qs.Chemical('Water'), qs.Chemical('Ethanol')))
>>> data = {'Water': {'particle_size': 'Soluble',
...                   'degradability': 'Undegradable',
...                   'organic': False},
...         'Ethanol': {'particle_size': 'Soluble',
...                     'degradability': 'Readily',
...                     'organic': False}}
>>> cmps = qs.Components.from_chemicals(chems, **data)
>>> cmps
Components([Water, Ethanol])
classmethod load_default(use_default_data=True, store_data=False, default_compile=True)

Create and return a Components or CompiledComponents object containing all default Component objects based on Reiger et al.

Parameters:
  • use_default_data (bool, optional) – Whether to use default cache data. The default is True.

  • store_data (bool, optional) – Whether to store the default data as cache. The default is True.

  • default_compile (bool, optional) – Whether to compile the default Components. The default is True.

Returns:

Note

[1] Component-specific properties are defined in ./data/component.cvs.

[2] When default_compile is True, all essential chemical-specific properties (except molar volume model and normal boiling temperature) that are missing will be defaulted to those of water.

[3] When default_compile is True, missing molar volume models will be defaulted according to particle sizes: particulate or colloidal -> copy from NaCl, soluble -> copy from urea, dissolved gas -> copy from CO2.

[4] When default_compile is True, missing normal boiling temperature will be defaulted according to particle sizes: particulate or colloidal -> copy from NaCl, soluble -> copy from urea, dissolved gas -> copy from CO2.

See also

default_compile()

References

[1] Rieger, L.; Gillot, S.; Langergraber, G.; Ohtsuki, T.; Shaw, A.; Tak´cs, I.; Winkler, S. Guidelines for Using Activated Sludge Models; IWA Publishing, 2012. https://doi.org/10.2166/9781780401164.

classmethod load_from_file(path_or_df, index_col=None, use_default_data=False, store_data=False)

Create and return a Components objects based on properties defined in a datasheet.

Parameters:
  • path_or_df (str or pandas.DataFrame) – File path, the file should end with “.cvs”, “.xls”, or “xlsx”.

  • index_col (None or int) – Index column of the pandas.DataFrame.

  • use_default_data (bool) – Whether to use the cached default components.

  • store_data (bool) – Whether to store this as the default components.

Return type:

A Components object that contains all created Component objects.

Note

The Components object needs to be compiled before it is used in simulation.

CompiledComponents

class qsdsan.CompiledComponents(components, cache=None)

A subclass of thermosteam.CompiledChemicals, contains Component objects as attributes.

Examples

Component

property aliases

All of the aliases of the components.

property biomass

[list] Biomass components.

compile(skip_checks=False, ignore_inaccurate_molar_weight=False)

Do nothing, CompiledComponents have already been compiled.

copy()

Return a copy.

property gases

[list] Gas components.

get_IDs_from_array(array)

Get the IDs of a group of components based on the 1/0 or True/False array.

Parameters:

array (Iterable(1/0)) – 1D collection of 1/0 or True/False with the same length as the IDs.

Examples

>>> from qsdsan import Components
>>> cmps = Components.load_default()
>>> cmps.get_IDs_from_array(cmps.g)
('S_H2', 'S_CH4', 'S_N2', 'S_O2')
get_array_from_IDs(IDs)

Generate a numpy array in the same shape as CompiledComponents.IDs, where the values would be 1 for components whose IDs are in the given ID iterable and 0 for components not in the given ID iterable.

Parameters:

IDs (Iterable(str)) – IDs of select components within this qsdsan.CompiledComponents.

Examples

>>> from qsdsan import Components
>>> cmps = Components.load_default()
>>> IDs = ('S_H2', 'S_CH4', 'S_N2', 'S_O2')
>>> cmps.get_array_from_IDs(IDs)
array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0])
index(ID)

Return index of specified component.

indices(IDs)

Return indices of multiple components.

property inorganic_solids

[list] Inorganic solids (particulate & inorganic, all undegradable) components.

property inorganics

[list] Inorganic components.

property names

All of the names and aliases of the components.

property organic_solids

[list] Organic solids (particulate & organic) components.

refresh_constants()

Refresh constant arrays of Components objects, including all chemical and component-specific properties.

remove_alias(component, alias)

Remove the alias of a component.

Parameters:
  • component (str or obj) – The component (or the ID of which) whose alias will be removed.

  • alias (str) – The alias of the component to be removed.

Examples

>>> from qsdsan.utils import create_example_components
>>> cmps = create_example_components()
>>> cmps.H2O is cmps.Water
True
>>> cmps.remove_alias(cmps.H2O, 'Water')
>>> cmps.Water
Traceback (most recent call last):
AttributeError: 'CompiledComponents' object has no attribute 'Water'
remove_synonym(component, alias)

Remove the alias of a component.

Parameters:
  • component (str or obj) – The component (or the ID of which) whose alias will be removed.

  • alias (str) – The alias of the component to be removed.

Examples

>>> from qsdsan.utils import create_example_components
>>> cmps = create_example_components()
>>> cmps.H2O is cmps.Water
True
>>> cmps.remove_alias(cmps.H2O, 'Water')
>>> cmps.Water
Traceback (most recent call last):
AttributeError: 'CompiledComponents' object has no attribute 'Water'
property solids

[list] Solids (particulate) components.

subgroup(IDs)

Create a new subgroup of Component objects.

property substrates

[list] Substrate components.