Four decades ago, engineers at NASA Glenn Research Center codified the thermodynamic behavior of thousands of chemical species for their Chemical Equilibrium with Applications (CEA) code. Those empirical polynomials remain the gold standard for combustion simulations, jet engine design, and rocket propellant modeling.
Yet, working with that data today often feels like an archaeology expedition. The official coefficients still circulate in thermo.inp, a rigid, 80-column fixed-width FORTRAN layout that traces its roots straight back to punch cards.
If you have ever tried to slice columns 53 to 65 just to extract a molecular weight, or struggled to evaluate double-precision exponents in modern web services and analytics pipelines, you know the frustration.
Meet pyglenn.
Built by Dr. Reginaldo G. Leão Jr. and released under the MIT license, pyglenn wraps the entire NASA Glenn thermodynamic catalog into an embedded SQLite database and pairs it with a modern, fully typed Python API.
Here is what it does, why it matters, and how you can integrate it into your scientific workflows in minutes.
The 5.7 PPM Trap Most Codes Ignore
NASA polynomials compute dimensionless ratios for heat capacity, enthalpy, and entropy across specific temperature windows:
To recover dimensional units like Joules per mole-Kelvin, you multiply by the universal gas constant, R .
Here lies a subtle pitfall that catches many numerical libraries off guard. The original NASA dataset was calibrated using the CODATA 1986 reference constant ( R=8.314510 J/(mol⋅K) ). When modern software evaluates these polynomials using the current CODATA universal constant ( R=8.31446261815324 J/(mol⋅K) ), every calculation incurs an invisible, systematic shift of roughly 5.7 parts per million.
While 5.7 ppm sounds tiny, high-temperature equilibrium codes can drift significantly over iterative convergence loops. pyglenn tracks this reference constant directly in its database metadata, denormalizing properties with exact historical consistency while preserving the modern constant for universal physical relations.
Zero Configuration, Fully Typed
Unlike older wrappers that require manual database builds or compile external C extensions, pyglenn ships with an optimized thermo.db file containing 2,035 chemical species and 3,795 temperature intervals.
Installation requires only standard tools from PyPI or conda-forge:
# Using pip pip install pyglenn # Or using conda conda install conda-forge::pyglenn The library exposes immutable, frozen dataclasses instead of loose dictionaries. Your IDE autocompletes every field, from heat capacity to molecular weight, with full type safety.
Evaluating properties for oxygen at 1000 K takes five lines of Python:
from pyglenn import ThermochemicalCalculator with ThermochemicalCalculator() as calc: # Exact case-insensitive matching isolates O2 from mixed formulas species = calc.get_available_species('O2', exact_match=True)[0] props = calc.calculate_properties(species.id, 1000.0) print(f"Species: {props.species_name}") print(f"Cp: {props.cp:.2f} J/(mol·K)") print(f"H°: {props.h_relative:.1f} J/mol") print(f"S°: {props.s:.3f} J/(mol·K)") Notice that props.h_relative evaluates absolute enthalpy under the standard NASA convention, meaning that enthalpy at 298.15 K matches the standard heat of formation of the compound.
If you need the sensible enthalpy between 298.15 K and operating temperature, call the dedicated helper:
h_sens = calc.h_sensible_to(species.id, 1000.0) print(f"Sensible enthalpy rise: {h_sens:.1f} J/mol") Evaluating Gas Mixtures Without Headaches
Engineering systems rarely burn pure reactants. We deal with atmospheric air, syngas, and complex exhaust mixtures.
pyglenn includes a Mixture abstraction that computes aggregate properties on both molar and mass bases. You specify the components and their mole fractions, and the engine handles molar mass averaging and property weighting automatically:
from pyglenn import Mixture, ThermochemicalCalculator with ThermochemicalCalculator() as calc: n2 = calc.get_available_species('N2', exact_match=True)[0] o2 = calc.get_available_species('O2', exact_match=True)[0] ar = calc.get_available_species('AR', exact_match=True)[0] # Standard dry atmospheric air composition dry_air = Mixture(( (n2.id, 0.78084), (o2.id, 0.20946), (ar.id, 0.00970), )) props = calc.mixture_properties(dry_air, 500.0) print(f"Mean molar mass: {props.molar_mass * 1000.0:.3f} g/mol") print(f"Air Cp (mass): {props.cp_mass:.2f} J/(kg·K)") print(f"Air H° (mass): {props.h_mass / 1e3:.2f} kJ/kg") The composition validation enforces strict physical checks. If mole fractions fail to sum to 1.0 within numerical precision, or if negative fractions appear, the system flags the error immediately before calculating downstream states.
Fitting Custom Polynomials with Continuity Constraints
What if you have laboratory measurements or quantum chemistry calculations for a novel fuel candidate, and you need to generate valid NASA-7 coefficients for a simulation tool?
pyglenn provides least-squares polynomial regressors inside its fitting module. The algorithm scales temperature coordinates by their geometric mean, preventing the Vandermonde matrix from becoming ill-conditioned across wide ranges.
When fitting multiple temperature intervals, fit_nasa7_multi imposes linear equality constraints at the junction points. This guarantees that heat capacity and its first derivative remain continuous across the entire domain:
import numpy as np from pyglenn.fitting import fit_nasa7_multi # Sample synthetic laboratory data across 300 K to 3000 K temps = np.linspace(300.0, 3000.0, 150) cp_data = 28.0 + 0.015 * temps - 1.2e-6 * temps**2 # Break into low and high temperature intervals at 1000 K intervals = fit_nasa7_multi( temperatures=temps, cp_values=cp_data, breakpoints=[1000.0], t_ref=298.15, h_ref=0.0, ) print(f"Fitted intervals: {len(intervals)}") print(f"Low interval a3: {intervals[0].a3:.6e}") print(f"High interval a3: {intervals[1].a3:.6e}") The resulting coefficients follow the exact NASA CEA convention, placing enthalpy and entropy integration constants into b1 and b2 .
Terminal Diagnostics at Your Fingertips
You do not even need to open a Python shell to inspect a chemical species. The package includes a clean command-line interface:
# Query O2 properties across default temperature points pyglenn query -s O2 # Validate internal database relational integrity pyglenn validate Running pyglenn validate inspects interval ordering, verifies foreign keys, and confirms that temperature coverage remains contiguous.
Where to Go Next
pyglenn bridges four decades of aerospace thermodynamics with modern, reliable Python engineering. It removes the friction of FORTRAN file parsers, prevents subtle gas constant scaling errors, and lets you focus on your actual physics models.
You can inspect the codebase, explore the documentation, or contribute directly on GitHub:
- Repository: github.com/ProfLeao/pyglenn
- Online Documentation: profleao.github.io/pyglenn
- PyPI: pypi.org/project/pyglenn
- Conda-Forge: anaconda.org/conda-forge/pyglenn
