catalysis: common calculations in catalytic testing

Code author: Peter Kraus

Includes functions to calculate the reactant- and product-based conversion(), atom-based selectivity(), catalytic_yield(), and atom_balance().

Functions

atom_balance([xin, xout, rin, rout, ...])

Calculates the atom balance of an element \(\text{el}\) between the inlet and outlet mixtures.

catalytic_yield(feedstock[, xin, xout, rin, ...])

Calculates the catalytic yield \(Y_p\), defined as the product of conversion and selectivity.

conversion(feedstock[, xin, xout, rin, ...])

Calculates the conversion of feedstock \(f\) into other products \(p\).

selectivity(feedstock[, xout, rout, ...])

Calculates product-based atomic selectivities of all species \(s\), excluding the feedstock \(f\).

Names of compounds within the specified mixtures are parsed to SMILES, and the cross-matching of the feestock, internal standard, and the components of xin and xout (or rin and rout) is performed using these SMILES.

Note

This module assumes that the provided inlet and outlet compositions, whether mole fractions or molar rates, contain all species. This implies that the atomic balance of the inlet and outlet is near unity. If multiple inlet/outlet streams are present in the experiment, they need to be appropriately combined into a single namespace, e.g. using functions in the dgpost.transform.rates before using the functions in this module.

dgpost.transform.catalysis.conversion(feedstock, xin=None, xout=None, rin=None, rout=None, element=None, type='product', standard='N2', product=None, output=None)

Calculates the conversion of feedstock \(f\) into other products \(p\). The feedstock must be a species present in the inlet. By default, a product-based carbon conversion (\(\text{el} = \text{C}\)), using data from the outlet, is computed.

The product-based conversion \(X_p\) is calculated using the outlet mole fractions \(x_\text{out}(s)\) of species \(s\), or the outlet molar rates \(\dot{n}_\text{out}(s)\). It is calculated on an elemental basis by considering the number of atoms of a certain element, \(n_\text{el}\), as:

\[X_{p, \text{el}} = \frac{\sum_{s} n_\text{el}(s) x_\text{out}(s) - n_\text{el}(f) x_\text{out}(f)} {\sum_{s} n_\text{el}(s) x_\text{out}(s)} = \frac{\sum_{s} n_\text{el}(s) \dot{n}_\text{out}(s) - n_\text{el}(f) \dot{n}_\text{out}(f)} {\sum_{s} n_\text{el}(s) \dot{n}_\text{out}(s)}\]

Which requires the feedstock \(f\) to be quantified in the outlet composition.

If the outlet composition of \(f\) is not defined or not suitable, the user should request a “mixed” conversion \(X_m\), which is calculated using:

\[X_{m, \text{el}} = \frac{\sum_{p}^{p\ne f} n_\text{el}(p) x_\text{out}(p) f_e} {n_\text{el}(f) x_\text{in}(f)} = \frac{\sum_{p}^{p\ne f} n_\text{el}(p) \dot{n}_\text{out}(s)} {n_\text{el}(f) \dot{n}_\text{in}(f)}\]

Here, the expansion factor \(f_e\) is introduced, which is defined as the expansion ratio of the internal standard in the mixture: \(f_e = x_\text{out}(\text{i.s.}) / x_\text{in}(\text{i.s.})\). The internal standard is set to N2 by default. When molar rates \(\dot{n}\) are used, accounting for expansion in this way is not necessary.

Note

Calculating mixed conversion \(X_m\) using inlet mole fraction of feedstock is not ideal and should be avoided, as the value is strongly convoluted with the atom_balance() of the mixtures.

Finally, the calculation of reactant-based (or feedstock-based) conversion, \(X_r\), proceeds as follows:

\[X_{r} = \frac{x_\text{in}(f) - x_\text{out}(f) f_e}{x_\text{in}(f)} = \frac{\dot{n}_\text{in}(f) - \dot{n}_\text{out}(f)}{\dot{n}_\text{in}(f)}\]

The selection of the element \(\text{el}\) is meaningless for the reactant -based conversion.

Warning

Note that the calculated values of \(X_p\), \(X_m\), and \(X_r\) will differ from one another in cases where the atomic balances of the inlet and outlet mixtures are different from unity!

Parameters:
  • feedstock (str) – Name of the feedstock. Parsed into SMILES and matched against xin and xout.

  • xin (Optional[dict[str, Quantity]]) – A dictionary containing the composition of the inlet mixture with the names of the chemicals as str keys. Has to be supplied with xout. Cannot be supplied with rin or rout.

  • xout (Optional[dict[str, Quantity]]) – A dictionary containing the composition of the outlet mixture with the names of the chemicals as str keys. Has to be supplied with xin. Cannot be supplied with rin or rout.

  • rin (Optional[dict[str, Quantity]]) – A dictionary containing the molar rates of species in the inlet mixture with the names of the chemicals as str keys. Has to be supplied with rout. Cannot be supplied with xin or xout.

  • rout (Optional[dict[str, Quantity]]) – A dictionary containing the molar rates of species in the outlet mixture with the names of the chemicals as str keys. Has to be supplied with rin. Cannot be supplied with xin or xout.

  • element (Optional[str]) – Name of the element for determining conversion. If not specified, set to the highest-priority (C > H > O) element in feedstock.

  • type (str) – Conversion type. Can be one of {"reactant", "product", "mixed"}, selecting the conversion calculation algorithm.

  • product (Optional[bool]) – Deprecated. Switches between reactant and product-based conversion.

  • standard (str) – Internal standard for normalizing the compositions. By default set to “N2”. Only used when xin and xout are supplied.

  • output (Optional[str]) – A str name of the output variable.

Returns:

ret – A dict containing the calculated conversion with output as its key.

Return type:

dict[str, pint.Quantity]

dgpost.transform.catalysis.selectivity(feedstock, xout=None, rout=None, element=None, output=None)

Calculates product-based atomic selectivities of all species \(s\), excluding the feedstock \(f\). The sum of selectivities is normalised to unity. Works with both mole fractions \(x\) as well as molar production rates \(\dot{n}\):

\[S_\text{el}(p) = \frac{\sum_{p}^{p \ne f} n_\text{el}(p) x_\text{out}(p)} {\sum_{s} n_\text{el}(s) x_\text{out}(s)} = \frac{\sum_{p}^{p \ne f} n_\text{el}(p) \dot{n}_\text{out}(p)} {\sum_{s} n_\text{el}(s) \dot{n}_\text{out}(s)}\]

Only the outlet fractions/rates are considered. The sum on in the numerator runs over all products \(p\) (i.e. \(p \ne f\)), while the sum in the denominator runs over all species \(s\). The value \(n_\text{el}(s)\) is the number of atoms of element \(\text{el}\) in species \(s\).

Note

The selectivity calculation assumes that all products have been determined; it provides no information about the mass or atomic balance.

Note

When molar rates \(\dot{n}\) are used, only creation rates (i.e. where \(\dot{n}(p) > 0\)) are used for calculation of selectivity.

Parameters:
  • feedstock (str) – Name of the feedstock. Parsed into SMILES and matched against the specified inlet and outlet species

  • xout (Optional[dict[str, Quantity]]) – Prefix of the columns determining the outlet composition.

  • rout (Optional[dict[str, Quantity]]) – Prefix of the columns determining the outlet molar rates.

  • element (Optional[str]) – The element for determining conversion. If not specified, set from feedstock using dgpost.transform.chemhelpers.default_element().

  • output (Optional[str]) – A str prefix for the output variables.

Returns:

ret – A dict containing the calculated selectivities using output as the prefix for each key.

Return type:

dict[str, pint.Quantity]

dgpost.transform.catalysis.catalytic_yield(feedstock, xin=None, xout=None, rin=None, rout=None, element=None, standard='N2', type='product', output=None)

Calculates the catalytic yield \(Y_p\), defined as the product of conversion and selectivity. By default, uses product-based conversion of feedstock for an internal consistency with selectivity. The sum of all yields is equal to the conversion. Implicitly runs conversion() and selectivity() on the pd.DataFrame:

\[Y_{p, \text{el}}(s) = X_{p, \text{el}}(s) \times S_{p, \text{el}}(s)\]

Where \(s\) is the product species, and the subscript \(p\) denotes it is a product-based quantity, with respect to element \(\text{el}\).

Parameters:
  • xin (Optional[dict[str, Quantity]]) – Prefix of the columns determining the inlet composition.

  • xout (Optional[dict[str, Quantity]]) – Prefix of the columns determining the outlet composition.

  • feedstock (str) – Name of the feedstock. Parsed into SMILES and matched against xin and xout.

  • element (Optional[str]) – The element for determining conversion. If not specified, set from feedstock using dgpost.transform.chemhelpers.default_element().

  • standard (str) – Internal standard for normalizing the compositions. By default set to “N2”.

  • type (str) – Select conversion calculation algorithm, see conversion().

  • output (Optional[str]) – A str prefix for the output variables.

Returns:

ret – A dict containing the calculated yields using output as the prefix for each key.

Return type:

dict[str, pint.Quantity]

dgpost.transform.catalysis.atom_balance(xin=None, xout=None, rin=None, rout=None, element='C', standard='N2', output=None)

Calculates the atom balance of an element \(\text{el}\) between the inlet and outlet mixtures. The total number of atoms of the specified element is compared between between the inlet and outlet, normalized by an internal standard if necessary:

\[\text{atbal}_\text{el} = \frac{\sum_s n_\text{el}(s) x_\text{out}(s) f_e} {\sum_s n_\text{el}(s) x_\text{in}(s)} = \frac{\sum_s n_\text{el}(s) \dot{n}_\text{out}(s)} {\sum_s n_\text{el}(s) \dot{n}_\text{in}(s)}\]

Here the sum runs over all species \(s\), \(n_\text{el}(s)\) is the number of atoms of element \(\text{el}\) in \(s\), and \(f_e\) is the expansion factor calculated using the internal standard as \(f_e = x_\text{out}(\text{i.s.}) / x_\text{in}(\text{i.s.})\).

Parameters:
  • xin (Optional[dict[str, Quantity]]) – Prefix of the columns determining the inlet composition as a mole fraction.

  • xout (Optional[dict[str, Quantity]]) – Prefix of the columns determining the outlet composition as a mole fraction.

  • rin (Optional[dict[str, Quantity]]) – Prefix of the columns determining the inlet composition as a molar rate.

  • rout (Optional[dict[str, Quantity]]) – Prefix of the columns determining the outlet composition as a molar rate.

  • element (str) – The element for determining conversion. If not specified, set to "C".

  • standard (str) – Internal standard for normalizing flows. By default set to "N2".

  • output (Optional[str]) – A str prefix for the output variables.

Returns:

ret – A dict containing the calculated atomic balance using output as the key.

Return type:

dict[str, pint.Quantity]