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#
|
Get elemental mass fractions for a gas solution. |
|
Get per-species contributions to each element in the mixture. |
|
Get elemental mass fractions for combined gas streams. |
|
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). Usecompute_element_balancewhen you want to know the weight of each element in the mixture; usecompute_element_contributionswhen 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 (
listofstr, 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
- 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.6gives{"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). Usecompute_element_contributionswhen you want to know which species carry a particular element; usecompute_element_balancewhen 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 (
listofstr, 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
- 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 (
listoftuple[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 (
listofstr, 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 (
listoftuple[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 (
listofstr, 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 tobloc.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