prometheus_equilibrium.equilibrium.solver
Equilibrium solvers for Prometheus.
Three concrete solvers are provided, all implementing the same
EquilibriumSolver interface. They share the same inputs
(EquilibriumProblem) and outputs
(EquilibriumSolution) and differ
only in the numerical algorithm used internally.
Solver summary
- MajorSpeciesSolver (recommended — default)
Compressed Newton on major species combined with an analytical minor- species update and a PEP-style outer temperature search. Combines the quadratic convergence of Newton’s method with PEP’s small matrix size and guaranteed temperature convergence. See
MajorSpeciesSolver.- PEPSolver (reference implementation)
Pure Villars-Browne reaction-adjustment method as described in the original NWC Propellant Evaluation Program (Cruise, NWC TP 6037, 1979). Converges linearly; useful as a simpler reference and for validating the more complex Major-Species solver. See
PEPSolver.- GordonMcBrideSolver (comparison / validation)
Modified Lagrange multiplier method from NASA RP-1311 (Gordon & McBride, 1994). The algorithm used by CEA. Kept for direct comparison against RocketCEA output. See
GordonMcBrideSolver.
Algorithm relationships
All three solvers minimise the same objective — Gibbs free energy subject to element-balance constraints — and find the same solution. They differ in how they parameterise and solve the resulting nonlinear system:
Feature |
G-McB |
PEP |
Major-Species |
|---|---|---|---|
Core variables |
π (Lagrange mult) |
nⱼ directly |
π for major |
Matrix size |
(S+cnd+1)² |
S×S |
S×S |
Minor species |
log-space Newton |
Kᵢ/Qᵢ ratio |
analytic from π |
Convergence rate |
quadratic |
linear |
quadratic |
T convergence |
no guarantee |
interval halving |
interval halving |
Condensed phases |
restart loop |
phase deletion |
phase deletion |
where S = number of chemical elements, cnd = number of active condensed phases. For H₂/O₂ combustion (S=2, no condensed phases) the Major-Species and PEP matrix is always 2×2 regardless of the number of candidate product species.
- class prometheus_equilibrium.equilibrium.solver.EquilibriumSolver(max_iterations: int = 50, tolerance: float = 5e-06, capture_history: bool = False, history_stride: int = 1)
Bases:
ABCAbstract base class for all equilibrium solvers.
Concrete implementations must override
solve(). The interface is solver-agnostic: any of the three concrete solvers can be swapped in without changing calling code.Parameters
- max_iterationsint
Maximum inner (composition) iterations before declaring non-convergence.
- tolerancefloat
Convergence threshold for species mole-fraction residuals.
- abstractmethod solve(problem: EquilibriumProblem, guess: Mixture | None = None, log_failure: bool = True) EquilibriumSolution
Run the equilibrium calculation and return the converged state.
Parameters
- problemEquilibriumProblem
Fully specified problem. Call
problem.validate()before passing to catch ill-posed inputs early.- guessMixture, optional
Initial composition guess. If provided, the solver uses these mole amounts as a starting point instead of the default monatomic initialization.
Returns
- EquilibriumSolution
The converged state. Always check
.convergedbefore using results.
- class prometheus_equilibrium.equilibrium.solver.PEPSolver(max_iterations: int = 50, tolerance: float = 5e-06, minor_threshold: float = 0.01, capture_history: bool = False, history_stride: int = 1)
Bases:
_ReactionAdjustmentBase- solve(problem: EquilibriumProblem, guess: Mixture | None = None, log_failure: bool = True) EquilibriumSolution
Run the equilibrium iteration.
- Parameters:
problem – Fully specified equilibrium problem.
guess – Optional initial composition guess.
- Returns:
EquilibriumSolution with the converged composition.
- class prometheus_equilibrium.equilibrium.solver.MajorSpeciesSolver(max_iterations: int = 50, tolerance: float = 5e-06, minor_threshold: float = 0.01, capture_history: bool = False, history_stride: int = 1)
Bases:
_ReactionAdjustmentBaseCompressed Newton + analytical minor-species update.
Combines the best features of the Gordon-McBride and PEP algorithms:
PEP basis selection keeps the Newton system small (S×S for major species only, where S = number of elements).
Newton quadratic convergence on the compressed system instead of PEP’s linear serial corrections.
Analytical minor-species update from the converged element potentials — exact at any mole-fraction scale, no log-space artefacts.
PEP outer temperature search with interval-halving fallback.
- solve(problem: EquilibriumProblem, guess: Mixture | None = None, log_failure: bool = True) EquilibriumSolution
Run the major-species equilibrium iteration.
- Parameters:
problem – Fully specified equilibrium problem.
guess – Optional initial composition guess.
- Returns:
EquilibriumSolution with the converged composition.
- class prometheus_equilibrium.equilibrium.solver.GordonMcBrideSolver(max_iterations: int = 300, tolerance: float = 0.0001, capture_history: bool = False, history_stride: int = 1)
Bases:
EquilibriumSolverGibbs free energy minimisation via modified Lagrange multipliers.
Implements the full algorithm from NASA RP-1311 (Gordon & McBride, 1994), using cpropep and CEA as references.
Algorithm overview
The equilibrium condition for gas-phase species j is:
μⱼ/RT = μⱼ°(T)/RT + ln(nⱼ/n_gas) + ln(P/P°) = Σₖ πₖ·A[j,k]
where πₖ are dimensionless element potentials (Lagrange multipliers in units of RT). At each Newton step the system is linearised, yielding a small augmented matrix whose unknowns are [π, Δnc, Δln(n), Δln(T)]:
π (shape S): solved fresh at each step — not accumulated.
Δnc (shape nc_active): linear corrections to condensed mole amounts.
Δln(n): correction to total gas moles.
Δln(T): temperature correction (HP/SP only).
Matrix size is (S + nc_active + 1) for TP or (S + nc_active + 2) for HP/SP, where S = n_elements and nc_active = currently present condensed species. Gas species are updated analytically from π after each solve.
After each Newton step the condensed phase set is managed:
Remove: any condensed with nⱼ ≤ 0 is deactivated.
Include: any inactive condensed with μ°c/RT < Σₖ πₖ·aₖc is a candidate; the most favourable is activated.
Temperature converges in the same Newton loop as composition (HP/SP), not in a separate outer loop.
- param max_iterations:
Maximum Newton iterations before declaring non-convergence.
- param tolerance:
Convergence threshold: max
abs(nⱼ·Δln(nⱼ)) / n_gas(and similar criteria for condensed, total-moles, and temperature).
- solve(problem: EquilibriumProblem, guess: Mixture | None = None, log_failure: bool = True) EquilibriumSolution
Run the Gordon-McBride iteration and return the converged state.
- Parameters:
problem – Fully specified equilibrium problem.
guess – Optional initial composition guess. If provided, its mole amounts are used as the starting point instead of the default monatomic initialization.
- Returns:
EquilibriumSolution with the converged composition.
- class prometheus_equilibrium.equilibrium.solver.HybridSolver(max_iterations: int = 300, tolerance: float = 0.0001, seed_max_iterations: int | None = None, seed_tolerance: float = 5e-06, capture_history: bool = False, history_stride: int = 1)
Bases:
EquilibriumSolverGordonMcBrideSolver seeded by composition and a temperature estimate.
Algorithm
Seed solve — run
MajorSpeciesSolveron a TP sub-problem atproblem.t_init. The inner Newton loop (S×S matrix) advances the gas composition away from the flat monatomic initial guess toward the chemical equilibrium at that temperature. Only the inner Newton loop runs — no outer temperature search — so the cost is bounded byseed_max_iterations.Temperature correction — with the partial seed composition, compute one Newton step on the energy constraint:
ΔT = −f / f′ where f = H(T_init) − H₀ (HP) f′ = Cₚ(T_init)For the T correction to be accurate, the seed composition must be chemically realistic (close to equilibrium), which requires around 20 inner iterations for 3-element systems. For simple 2-element systems 10–12 iterations are sufficient.
Main solve — pass both the seed composition and the corrected
t_inittoGordonMcBrideSolver. Starting from a composition that is already near the equilibrium products eliminates the poorly-damped “build-up” phase of G-McB’s cold start.
Rationale
G-McB’s first iterations from a flat monatomic initialisation suffer heavy damping (λ ≪ 1) because the Newton step size is enormous: every dominant product (H₂O, CO₂, …) has to grow from ~1/N mole fraction to its true value while simultaneously finding the correct temperature. Convergence history for CH₄/O₂ shows T oscillating over a 700 K range for 19 iterations before entering the quadratic basin.
The key threshold is ~20 inner seed iterations for 3-element systems: below this G-McB still oscillates as if cold; at 20 inner iterations the dominant products are established and G-McB converges in ~6 iterations instead of ~24, giving roughly a 2× wall-clock speedup. For simpler 2-element systems (H₂/O₂) 10–12 iterations suffice and the speedup is smaller because G-McB is already fast.
- param max_iterations:
Maximum Newton iterations for the G-McB main solve.
- param tolerance:
Convergence tolerance for the G-McB main solve.
- param seed_max_iterations:
Maximum inner iterations for the seed TP solve. 20 balances seed cost against G-McB iteration reduction across both 2-element (H₂/O₂) and 3-element (CH₄/O₂, N₂H₄/N₂O₄) propellant systems. Formal convergence of the TP solve is not required.
- param seed_tolerance:
Convergence tolerance for the seed TP solve.
- param capture_history:
Whether to record convergence history (G-McB phase).
- param history_stride:
Only every n-th step is stored.
- solve(problem: EquilibriumProblem, guess: Mixture | None = None, log_failure: bool = True) EquilibriumSolution
Solve by seeding GordonMcBrideSolver with a TP composition from MajorSpeciesSolver.
- Parameters:
problem – Fully specified equilibrium problem.
guess – Optional initial composition guess (forwarded to the TP seed solve rather than to G-McB directly).
log_failure – Whether to log convergence failures from G-McB.
- Returns:
EquilibriumSolutionfrom the G-McB step. Theiterationsfield is the sum of seed TP iterations and G-McB iterations so that total work is reported accurately.