Chemical Oxygen Demand (COD)

cod_test_stoichiometry

qsdsan.utils.cod_test_stoichiometry(atoms, charge=0, MW=None, missing_handling='elemental')

Return a dictionary of stoichiometric coefficients of the oxidation reaction by dichromate, given a dictionary of a molecule’s constituent atoms and their counts, as well as the number of negative charge, if any.

This function is based on the oxidation of organic materials by dichromate in an acid solution, as in a typical COD test of water or wastewater samples. Only C, H, O, N, S, P are considered active in the reaction.

Parameters:
  • atoms (dict[str, int or float]) – Dictionary of atoms and their counts, [-].

  • charge (int or float) – Charge of the molecule.

  • MW (float, optional) – Molecular weight of chemical, used only if missing_handling is ‘Ash’, [g/mol]

  • missing_handling (str, optional) – How to handle compounds which do not appear in the stoichiometric reaction below. If ‘elemental’, return those atoms in the monatomic state; if ‘ash’, converts all missing atoms to ‘Ash’ in the output at a MW of 1 g/mol, [-]

Returns:

  • stoichiometry (dict[str, float]) – Stoichiometric coefficients of the redox reaction. May include the following keys for complete oxidation: ‘H2O’, ‘CO2’, ‘NH4+’, ‘SO4-2’, ‘PO4-3’; if missing_handling is ‘elemental’ can include the other elements; if missing_handling is ‘ash’, Ash will be present in the output if the compounds whose reactions are not included here. ‘Cr2O7-2’ is always present, with negative values indicating dichromate is required/consumed. [-]

  • .. note::

    The stoichiometry is given by:

    \[C_n H_a O_b N_c S_d P_e^{f-} + xCr_2O_7^{2-} + (8x+c-2d-3e+f)H^{+} -> nCO_2 + 2xCr^{3+} + cNH_4^{+} + dSO_4^{2-} + ePO_4^{3-} + (b+7x-2n-4d-4e)H_2O\]
    \[x = \frac{4n+a-2b-3c+6d+5e+f}{6}\]

    Also included in the results is the moles of Cr2O7-2 required per mole of the mixture of the molecule.

    All products are in aqueous solution.

    Atoms not in [‘C’, ‘H’, ‘N’, ‘O’, ‘S’, ‘P’] are returned as pure species; i.e. sodium hydroxide produces water and pure Na.

Examples

>>> # Acetate in COD test:
>>> cod_test_stoichiometry({'C': 2, 'H':3, 'O':2}, -1)
{'Cr2O7-2': -1.3333333333333333,
 'H+': -11.666666666666666,
 'Cr+3': 2.6666666666666665,
 'CO2': 2,
 'H2O': 7.333333333333332}

compute_stream_COD

qsdsan.utils.compute_stream_COD(stream, units='mg/L')

Compute the chemical oxygen demand (COD) of a given stream by summing the COD of each component in the stream using:

\[COD [\frac{kg}{m^3}] = mol_{component} [\frac{kmol}{m^3}] * \frac{g O_2}{mol\ component}\]

get_bmp_stoichiometry

qsdsan.utils.get_bmp_stoichiometry(component, **replace)

Compute the theoretical biochemical methane potential (BMP) in mol \(CH_4\)/mol chemical of a given component as in:

\[C_vH_wO_xN_yS_z + \frac{4v-w-2x+3y+2z}{2}H2O -> \frac{4v+w-2x-3y-2z}{8}CH4 + \frac{(4v-w+2x+3y+2z)}{8}CO2 + yNH_3 + zH_2S\]

For organic components, elements other than “C”, “H”, “O”, “N”, and “S” will be turned into “Ash” with a molecular weight of 1 g/mol.

For inorganic components, all dict values will be 0.

Parameters:
  • component (obj) – The component whose COD will be calculated.

  • replace (dict) – Alternative IDs of the reactant/product components, e.g., if S_O2 is the ID of dissolved oxygen instead of O2, then can pass replace={‘O2’: ‘S_O2’}.

Examples

>>> from qsdsan import Component
>>> from qsdsan.utils import get_bmp_stoichiometry
>>> Glucose = Component('Glucose', organic=True, particle_size='Soluble',
...                     degradability='Readily')
>>> get_bmp_stoichiometry(Glucose)
{'Glucose': -1.0, 'H2O': -0.0, 'CH4': 3.0, 'CO2': 3.0, 'NH3': 0.0, 'H2S': 0.0}

get_cod_stoichiometry

qsdsan.utils.get_cod_stoichiometry(component, aqueous=False, **replace)

Get the molar stoichiometry for the theoretical chemical oxygen demand (COD) of a given component.

COD stoichiometry is consistent with qsdsan.utils.cod_test_stoichiometry() other than the oxidant is O2 rather than Cr2O7-2,

For organic components, elements other than “C”, “H”, “O”, “N”, “S”, and “P” will be turned into “Ash” with a molecular weight of 1 g/mol.

For inorganic components, all dict values will be 0.

If aqueous == False, the stoichiometry is given by:

\[C_nH_aO_bN_cS_dP_e + \frac{2n+0.5a-b-1.5c+3d+2.5e}{2}O_2 -> nCO_2 + \frac{a-3c-2d}{2}H_2O + cNH_3 + dH_2SO_4 + \frac{e}{4}P_4O_{10}\]

otherwise:

\[C_nH_aO_bN_cS_dP_e + \frac{2n+0.5a-b-1.5c+3d+2.5e}{2}O_2 + (c-2d-3e)H^+ -> nCO_2 + \frac{a-3c-2d-3e}{2}H_2O + cNH_4^+ + dSO_4^{2-} + ePO_4^{3-}\]
Parameters:
  • component (obj) – The component whose COD will be calculated.

  • aqueous (bool) – Whether the reaction will happen in aqueous phase.

  • replace (dict) – Alternative IDs of the reactant/product components, e.g., if S_O2 is the ID of dissolved oxygen instead of O2, then can pass replace={‘O2’: ‘S_O2’}.

Examples

>>> from qsdsan import Component
>>> from qsdsan.utils import get_cod_stoichiometry
>>> Glucose = Component('Glucose', organic=True, particle_size='Soluble',
...                     degradability='Readily')
>>> get_cod_stoichiometry(Glucose)
{'Glucose': -1.0,
 'O2': -6.0,
 'CO2': 6,
 'H2O': 6.0,
 'NH3': 0.0,
 'H2SO4': 0.0,
 'P4O10': 0.0}

get_digestion_rxns

qsdsan.utils.get_digestion_rxns(components, X_biogas, X_growth, biomass_ID, biodegradability=1.0)

Generate anaerobic digestion (AD) and biomass growth reactions for a given set of components.

AD stoichiometry is based on qsdsan.utils.get_bmp_stoichiometry() and biodegradabilities of the components as indicated in biodegradability.

Biomass growth is purely based on mass balance, thus can potentially result in loss of atom balance.

No reactions will be generated for inorganic components.

Parameters:
  • components (Iterable(obj)) – Set of components.

  • X_biogas (float) – Fraction of the organic components that is used for AD.

  • X_growth (float) – Fraction of the organic components that is used for biomass growth.

  • biomass_ID (str) – ID of the biomass (should be included in the components).

  • biodegradability (float or dict) – Biodegradabilities of the components. When given as a float, all organic components will be assumed to have the same biodegradability; when given as a dict, the keys should be the IDs of components and values the corresponding biodegradabilities, components without corresponding biodegradabilities will be assumed unbiodegradable.

Examples

>>> from qsdsan import Component, Components, set_thermo
>>> from qsdsan.utils import create_example_components, get_digestion_rxns
>>> example_cmps = create_example_components()
>>> NH3 = Component('NH3', phase='g', organic=False, particle_size='Dissolved gas',
...                 degradability='Undegradable')
>>> H2S = Component('H2S', phase='g', organic=False, particle_size='Dissolved gas',
...                 degradability='Undegradable')
>>> P4O10 = Component('P4O10', phase='s',
...                   organic=False, particle_size='Particulate',
...                   degradability='Undegradable')
>>> Biomass = Component('Biomass', phase='s', formula='CH1.8O0.5N0.2',
...                     organic=True, particle_size='Particulate',
...                     degradability='Slowly')
>>> Ash = Component('Ash', phase='s', MW=1,
...                 organic=False, particle_size='Particulate',
...                 degradability='Undegradable')
>>> for i in (P4O10, Biomass, Ash):
...    i.copy_models_from(example_cmps.NaCl, ('V',))
>>> for i in (Biomass, Ash): i.default() 
{...
>>> cmps = Components([*example_cmps, NH3, H2S, P4O10, Biomass, Ash])
>>> cmps.compile()
>>> set_thermo(cmps)
>>> cmps
CompiledComponents([H2O, CO2, N2O, NaCl, H2SO4, CH4, Methanol, Ethanol, NH3, H2S, P4O10, Biomass, Ash])
>>> rxns = get_digestion_rxns(cmps, X_biogas=0.9, X_growth=0.07,
...                           biomass_ID='Biomass', biodegradability=0.87)
>>> rxns 
ParallelReaction (by mol):
index  stoichiometry                              reactant    X[%]
[0]    Methanol -> 0.5 H2O + 0.25 CO2 + 0.75 CH4  Methanol   78.30
[1]    Ethanol -> 0.5 CO2 + 1.5 CH4               Ethanol    78.30
[2]    Methanol -> 1.3 Biomass                    Methanol    6.09
[3]    Ethanol -> 1.87 Biomass                    Ethanol     6.09