Equilibrium thermodynamic property tables for hydrogen-fuelled gas turbine cycle analysis, validated against NASA CEA and exportable to pyCycle's tabular format. Hydrogen is the only fuel implemented so far; sustainable aviation fuels, ammonia and methane are on the roadmap below.
Status: early development. Table generation, interpolated lookup, validation against NASA CEA, and pyCycle and CSV/JSON export adapters are complete for hydrogen-air, including a pure-air (zero equivalence ratio) row for unburned engine sections. T-MATS export, further fuels and a stable public API are not yet implemented.
Engine cycle analysis tools such as pyCycle and T-MATS offer a fast tabular thermodynamics path, but the tables they ship with are prepared for conventional kerosene. Anyone modelling a hydrogen-burning engine has to generate an equivalent dataset first. Both tools provide example scripts for doing so, so the work is not blocked; it is instead repeated from scratch in each thesis and paper, and the resulting tables are generally used without a published statement of how far they depart from a reference solution.
h2thermo aims to close that gap: a documented, openly licensed generator whose
output is validated against NASA CEA across the operating envelope, with the
residual error measured rather than assumed.
The package depends on Cantera, which is most reliably installed through Conda:
conda env create -f environment.yml
conda activate ct-env
pip install -e ".[dev]"from h2thermo import adiabatic_flame_temperature, equilibrium_properties
# Adiabatic flame temperature of stoichiometric hydrogen-air at 1 atm.
flame_temperature = adiabatic_flame_temperature(
inlet_temperature=298.15, pressure=101325.0, equivalence_ratio=1.0
)
print(f"{flame_temperature:.1f} K")
# Product properties at a prescribed combustor state.
state = equilibrium_properties(
temperature=1800.0, pressure=20.0e5, equivalence_ratio=0.6
)
print(f"cp = {state.cp:.1f} J/(kg K), gamma = {state.gamma:.4f}")Generating a table and querying it:
import numpy as np
from h2thermo import GridSpecification, ThermoInterpolator, ThermoTable
grid = GridSpecification(
temperature=np.linspace(500.0, 3000.0, 30),
pressure=np.geomspace(1.0e5, 60.0e5, 12),
equivalence_ratio=np.linspace(0.2, 1.0, 12),
)
table = ThermoTable.generate(grid)
table.save("data/generated/h2_air_table.npz")
interpolator = ThermoInterpolator(table)
# A single state, or many at once.
state = interpolator.lookup(1837.0, 13.7e5, 0.63)
states = interpolator.lookup(
np.linspace(1000.0, 2500.0, 1000), 20.0e5, 0.6
)Exporting for other tools:
from h2thermo.export.generic import write_csv_table, write_json_table
from h2thermo.export.pycycle import write_pycycle_table
write_csv_table(table, "data/generated/h2_air_table.csv")
write_json_table(table, "data/generated/h2_air_table.json")
write_pycycle_table(table, "data/generated/h2_air_table.pkl")| Input | Supported | Compared against CEA |
|---|---|---|
| Fuel | Hydrogen (further fuels planned) | Hydrogen |
| Temperature | 200 to 3000 K | 300 to 2900 K |
| Pressure | 10 kPa to 60 bar | 10 kPa to 60 bar |
| Equivalence ratio | 0 to 1.0 (0 = pure oxidizer, no fuel) | 0.2 to 1.0 |
The solver returns results across the whole supported envelope. Outside the compared range the agreement with CEA reported below has not been established, so the temperature extremes should be treated as unverified.
Outputs are the equilibrium composition and the corresponding specific enthalpy, entropy, frozen and equilibrium specific heats, ratio of specific heats, isentropic exponent, mean molecular weight and density, all in SI units on a mass basis.
Equilibrium compositions are obtained by Gibbs free energy minimisation using
Cantera's solver, which follows the same thermodynamic principle as NASA CEA.
The h2o2.yaml mechanism distributed with Cantera is used; it is based on the
hydrogen kinetics of Burke et al. (2012) and includes the dissociation species
that matter at high temperature. All species are treated as ideal gases, the
phase model h2o2.yaml defines in Cantera; the internal consistency check
against rho = pM/(RT) in docs/validation.md holds to
machine precision across the whole supported envelope, up to 60 bar.
Both definitions are provided. cp and cv hold the composition fixed, while
cp_equilibrium and cv_equilibrium include the heat capacity contributed by
shifting dissociation. Below 2000 K they agree to within one per cent; at
2900 K and 1 bar the equilibrium value is more than three times the frozen one.
Frozen values suit fast flows such as a turbine, equilibrium values suit a
combustor, and real behaviour lies between them.
Since the isentropic exponent of a reacting mixture is not the ratio of its
specific heats, it is reported separately as isentropic_exponent.
Properties are validated against NASA CEA over 200 reference states spanning 300 to 2900 K, 10 kPa to 60 bar and equivalence ratios from 0.2 to 1.0. Mean molecular weight and density agree to within 0.06 per cent, entropy to within 0.04 per cent and frozen specific heat to within 0.15 per cent. Internal consistency checks on element conservation and the equation of state hold to machine precision.
Interpolation adds well under 0.05 per cent on top of that, an order of magnitude below the agreement with CEA. The pure-air state, not covered by the hydrogen-combustion reference set above, is checked directly against pyCycle's own reference table instead; agreement is within 1 per cent across the range an inlet or compressor actually operates in, and CEA was used to confirm that a larger gap at temperatures no unburned air ever reaches comes from pyCycle's own table, not from h2thermo.
Known limitation: the h2o2.yaml mechanism treats nitrogen as inert, so
no nitric oxide forms. The measured effect on bulk properties is two orders
of magnitude below the CEA agreement above, acceptable for property tables
but not for emissions modelling.
Full results are in docs/validation.md, including the known limitations in detail, the pure-air cross-validation against pyCycle's own table, and a live end-to-end pyCycle run whose combustor exit temperature agrees with an independent Cantera solve to 0.011%.
The test suite currently has 2,291 cases, covering the comparisons above:
pytest- Hydrogen-air property tables with validation against NASA CEA (complete)
- Interpolated lookup (complete)
- Frozen and equilibrium specific heats (complete)
- Export adapters: pyCycle (complete, including a live end-to-end cycle
run --
pip install -e ".[pycycle]", see docs/validation.md section 7) and CSV/JSON (complete,h2thermo.export.generic); T-MATS remaining, see docs/decisions.md for why it is scoped separately - Additional fuels: sustainable aviation fuels, ammonia, methane
- Packaging and documentation (complete: CITATION.cff, CONTRIBUTING.md, v0.1.0)
- Burke, M. P., Chaos, M., Ju, Y., Dryer, F. L., Klippenstein, S. J. (2012). Comprehensive H2/O2 kinetic model for high-pressure combustion. International Journal of Chemical Kinetics, 44(7), 444-474.
- Goodwin, D. G., Moffat, H. K., Speth, R. L. et al. Cantera: An object-oriented software toolkit for chemical kinetics, thermodynamics, and transport processes. https://cantera.org
See CITATION.cff for citation metadata, or use GitHub's "Cite this repository" button on the repository page.
See CONTRIBUTING.md for the development setup, workflow and code style this project follows.
Released under the MIT License. See LICENSE.