bloc.balance.elemental_balance#

Elemental balance calculations for reactor systems.

This module provides lightweight wrappers around Cantera’s elemental_mass_fraction to compute element balances for single or multiple gas streams.

Two complementary views are available:

  • compute_element_balance()element-level view: returns the mass fraction of every element in the mixture (e.g. 75 % C, 25 % H by mass). Values sum to 1.0 over all elements.

  • compute_element_contributions()species-level view: for each element, returns the percentage carried by every species (e.g. 80 % of C comes from C2H2, 20 % from CH4). Values sum to 100 % for each element independently.

Functions#

compute_element_balance

Get elemental mass fractions for a gas solution (sums to 1.0 over elements).

compute_element_contributions

Get per-species contributions to each element (sums to 100 % per element).

compute_combined_element_balance

Get elemental mass fractions for combined gas streams.

compute_element_balance_summary

Compare inlet and outlet elemental mass fractions (for reactor validation).

Examples

Compute and visualize elemental contributions for a reactor outlet:

>>> import cantera as ct
>>> import matplotlib.pyplot as plt
>>> from bloc.balance.elemental_balance import (
...     compute_element_balance_summary,
...     compute_element_contributions,
... )
>>>
>>> # Setup inlet and outlet gas states
>>> gas_inlet = ct.Solution("gri30.yaml")
>>> gas_inlet.TPX = 300, 1e5, "CH4:1.0"
>>>
>>> gas_outlet = ct.Solution("gri30.yaml")
>>> gas_outlet.TPX = 1500, 1e5, "CH4:0.15, C2H2:0.30, H2:0.50, C2H4:0.05"
>>>
>>> # Compute element balance summary
>>> summary = compute_element_balance_summary(
...     inlet_streams=[(gas_inlet, 0.001)],  # 1 g/s CH4
...     gas_outlet=gas_outlet,
...     elements=["H", "C"],
... )
>>>
>>> # Extract and plot hydrogen contributions
>>> h_inlet = summary["H"]["inlet"]
>>> h_outlet = summary["H"]["outlet"]
>>>
>>> fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
>>>
>>> # Inlet contributions
>>> species_in = list(h_inlet.keys())
>>> values_in = list(h_inlet.values())
>>> ax1.barh(species_in, values_in, color="steelblue")
>>> ax1.set_xlabel("H contribution (mol_H/mol_total)")
>>> ax1.set_title(f"Inlet H Distribution")
>>> ax1.grid(axis="x", alpha=0.3)
>>>
>>> # Outlet contributions
>>> species_out = list(h_outlet.keys())
>>> values_out = list(h_outlet.values())
>>> ax2.barh(species_out, values_out, color="coral")
>>> ax2.set_xlabel("H contribution (mol_H/mol_total)")
>>> ax2.set_title(f"Outlet H Distribution")
>>> ax2.grid(axis="x", alpha=0.3)
>>>
>>> # Add balance ratio as text
>>> balance = summary["H"]["balance"]
>>> fig.suptitle(f"Hydrogen Balance: {balance:.1%}", fontsize=14, fontweight="bold")
>>> plt.tight_layout()
>>> plt.show()

Compute percentage contributions (similar to calculation note):

>>> # Get percentage contributions
>>> contrib = compute_element_contributions(gas_outlet, elements=["C"])
>>> for species, pct in contrib["C"].items():
...     print(f"{species:10s}: {pct:5.1f}%")
...
C2H2      : 66.7%
CH4       : 16.7%
C2H4      : 11.1%

Functions#

compute_element_balance(gas[, elements])

Get elemental mass fractions for a gas solution.

compute_element_contributions(gas[, elements, ...])

Get per-species contributions to each element in the mixture.

compute_combined_element_balance(streams[, elements])

Get elemental mass fractions for combined gas streams.

compute_element_balance_summary(inlet_streams, gas_outlet)

Compare inlet and outlet elemental contributions for reactor validation.

Module Contents#

bloc.balance.elemental_balance.compute_element_balance(gas, elements=None)#

Get elemental mass fractions for a gas solution.

Element-level view – answers “how is the total mass distributed across elements?”. Returns the mass fraction of each element in the mixture (kg_element / kg_total). The values sum to 1.0 over all elements, giving a global picture of the elemental composition.

For instance, pure CH4 yields {"C": 0.749, "H": 0.251} because 74.9 % of its mass is carbon and 25.1 % is hydrogen.

This is complementary to compute_element_contributions(), which takes the opposite perspective: for a given element, it breaks down the contribution of every species (summing to 100 % per element). Use compute_element_balance when you want to know the weight of each element in the mixture; use compute_element_contributions when you want to know which species carry a particular element.

Uses Cantera’s built-in elemental_mass_fraction() method.

Parameters:
  • gas (cantera.Solution) – Gas solution at specified T, P, X conditions.

  • elements (list of str, optional) – Elements to track. If None, returns all elements present in the gas.

Returns:

{element: mass_fraction} where mass_fraction is kg_element / kg_total. Values sum to 1.0 over all elements in the gas.

Return type:

dict

Examples

>>> import cantera as ct
>>> gas = ct.Solution("gri30.yaml")
>>> gas.TPX = 300, 1e5, "CH4:1.0"
>>> balance = compute_element_balance(gas, elements=["H", "C"])
>>> balance["C"]
0.749  # 74.9% of the mass is carbon
>>> balance["H"]
0.251  # 25.1% of the mass is hydrogen
>>> # C + H = 1.0 because CH4 only contains these two elements
>>> sum(balance.values())
1.0

See also

compute_element_contributions

Per-species breakdown for each element.

bloc.balance.elemental_balance.compute_element_contributions(gas, elements=None, min_mole_fraction=1e-12)#

Get per-species contributions to each element in the mixture.

Species-level view – answers “for a given element, which species carry it?”. For every tracked element, shows what percentage of that element each species accounts for. The percentages sum to 100 % for each element independently.

For instance, a mixture of CH4:0.2, C2H2:0.4, H2:0.6 gives {"C": {"C2H2": 80.0, "CH4": 20.0}}, meaning 80 % of the carbon atoms come from C2H2 and 20 % from CH4.

This is complementary to compute_element_balance(), which takes the opposite perspective: it returns the overall mass fraction of each element in the mixture (summing to 1.0 over all elements). Use compute_element_contributions when you want to know which species carry a particular element; use compute_element_balance when you want to know the weight of each element in the mixture.

Parameters:
  • gas (cantera.Solution) – Gas solution at specified T, P, X conditions.

  • elements (list of str, optional) – Elements to track. If None, returns all elements present in the gas.

  • min_mole_fraction (float, optional) – Minimum mole fraction to include a species (default: 1e-12).

Returns:

{element: {species: percentage}} where percentage is the fraction of that element coming from each species (0-100 %). For a given element, the sum of all species percentages equals 100 %.

Return type:

dict

Examples

>>> import cantera as ct
>>> gas = ct.Solution("gri30.yaml")
>>> gas.TPX = 300, 1e5, "CH4:0.2, C2H2:0.4, H2:0.6"
>>> contributions = compute_element_contributions(gas, elements=["C"])
>>> contributions["C"]
{"C2H2": 80.0, "CH4": 20.0}  # 80% of C from C2H2, 20% from CH4
>>> # Percentages sum to 100% for each element
>>> sum(contributions["C"].values())
100.0

See also

compute_element_balance

Overall elemental mass fractions of the mixture.

bloc.balance.elemental_balance.compute_combined_element_balance(streams, elements=None)#

Get elemental mass fractions for combined gas streams.

Computes mass-flow-weighted average of elemental mass fractions.

Parameters:
  • streams (list of tuple[cantera.Solution, float]) – List of (gas_state, mass_flow_rate) tuples. Each gas state should be at the respective T, P, X conditions. Mass flow rate in kg/s.

  • elements (list of str, optional) – Elements to track. If None, returns all elements present in the first stream.

Returns:

{element: mass_fraction} where mass_fraction is kg_element / kg_total.

Return type:

dict

Examples

>>> balance = compute_combined_element_balance(
...     streams=[(gas_torch, 0.001), (gas_2nd_inj, 0.0005)], elements=["H", "C"]
... )
>>> balance["H"]
0.150  # 15.0% hydrogen by mass in combined stream
bloc.balance.elemental_balance.compute_element_balance_summary(inlet_streams, gas_outlet, elements=None, min_mole_fraction=1e-12, n_C_min=300)#

Compare inlet and outlet elemental contributions for reactor validation.

Returns per-species molar contributions (n_element * X_species) and balance ratio based on elemental mass fractions.

Parameters:
  • inlet_streams (list of tuple[cantera.Solution, float]) – List of (gas_state, mass_flow_rate) tuples for inlet streams. Example: [(gas_torch_input, qm_torch), (gas_2nd_inj, qm_2nd_inj)]

  • gas_outlet (cantera.Solution) – Reactor outlet gas state.

  • elements (list of str, optional) – Elements to track. If None, returns all elements present in the first inlet stream.

  • min_mole_fraction (float, optional) – Minimum mole fraction to include a species (default: 1e-12).

  • n_C_min (int, optional) – Minimum number of carbon atoms to consider a species as solid (default: 300). This is passed to bloc.carbon_utils.get_solid_carbon_species() to identify which species should be labelled “considered solid” in the Calculation Note.

Returns:

Structure: {element: {"inlet": {species: n_elem*X}, "outlet": {species: n_elem*X}, "balance": ratio, "n_atoms": {species: n_atoms}, "solid_species": {species: is_solid}}} where n_elem*X is the molar contribution (mol_element/mol_total), balance = Y_out / Y_in (mass fraction ratio), n_atoms gives the number of atoms of that element in each species, and solid_species indicates whether each species is considered solid (True) or gaseous (False).

Return type:

dict

Examples

>>> summary = compute_element_balance_summary(
...     inlet_streams=[(gas_torch, 0.001), (gas_2nd_inj, 0.0005)],
...     gas_outlet=gas_outlet,
...     elements=["H", "C"],
... )
>>> summary["H"]["inlet"]["CH4"]
3.76  # 4 H atoms * 0.94 mole fraction
>>> summary["H"]["n_atoms"]["CH4"]
4  # CH4 has 4 hydrogen atoms
>>> summary["H"]["solid_species"]["CH4"]
False  # CH4 is not a solid species
>>> summary["C"]["solid_species"]["BIN25CJ"]
True  # BIN25CJ is considered solid (>= 300 carbon atoms)
>>> summary["H"]["balance"]
1.011  # 101.1% mass balance