prometheus_equilibrium.equilibrium.performance

Rocket performance calculations (Frozen and Shifting equilibrium).

Classes

PerformanceSolver([solver])

Calculates rocket performance by isentropic nozzle expansion.

RocketPerformanceResult(chamber, throat, ...)

Complete rocket performance results from chamber to exit.

class prometheus_equilibrium.equilibrium.performance.RocketPerformanceResult(chamber: EquilibriumSolution, throat: EquilibriumSolution, exit: EquilibriumSolution, cstar: float, isp_actual: float, isp_vac: float, isp_sl: float, area_ratio: float, pressure_ratio: float, shifting: bool, profile: List[EquilibriumSolution] = None)

Bases: object

Complete rocket performance results from chamber to exit.

chamber: EquilibriumSolution
throat: EquilibriumSolution
exit: EquilibriumSolution
cstar: float
isp_actual: float
isp_vac: float
isp_sl: float
area_ratio: float
pressure_ratio: float
shifting: bool
profile: List[EquilibriumSolution] = None
class prometheus_equilibrium.equilibrium.performance.RocketPerformanceComparison(shifting: RocketPerformanceResult, frozen: RocketPerformanceResult, ambient_pressure: float)

Bases: object

Paired rocket performance results for shifting and frozen expansion.

shifting: RocketPerformanceResult
frozen: RocketPerformanceResult
ambient_pressure: float
class prometheus_equilibrium.equilibrium.performance.PerformanceSolver(solver: EquilibriumSolver | None = None)

Bases: object

Calculates rocket performance by isentropic nozzle expansion.

Wraps an EquilibriumSolver to perform the full chamber → throat → exit calculation sequence for both shifting and frozen equilibrium assumptions.

The recommended entry point for scripting is solve_from_mixture(), which accepts a PropellantMixture directly and handles product-species lookup, H₀ assembly, and problem construction internally. For lower-level control, solve() and solve_pair() accept a pre-built EquilibriumProblem.

solver

The underlying equilibrium solver instance. Defaults to GordonMcBrideSolver.

Example

perf = PerformanceSolver()
result = perf.solve_from_mixture(
    mixture, db, p_chamber=70e5, area_ratio=10.0
)
print(f"c*  = {result.shifting.cstar:.1f} m/s")
print(f"Isp = {result.shifting.isp_vac:.1f} m/s  (vacuum, shifting)")
solve(problem: EquilibriumProblem, pe_pa: float | None = None, area_ratio: float | None = None, shifting: bool = True, ambient_pressure: float = 101325.0) RocketPerformanceResult

Calculate performance from chamber to a fixed exit pressure or area ratio.

solve_pair(problem: EquilibriumProblem, pe_pa: float | None = None, area_ratio: float | None = None, ambient_pressure: float = 101325.0) RocketPerformanceComparison

Solve both shifting and frozen expansions for the same chamber case.

Parameters:
  • problem – Chamber equilibrium problem (typically HP).

  • pe_pa – Optional exit pressure in Pa.

  • area_ratio – Optional nozzle area ratio Ae/At.

  • ambient_pressure – Ambient back pressure in Pa for actual Isp.

Returns:

Paired results for shifting and frozen expansion states.

Raises:

ValueError – If neither pe_pa nor area_ratio is provided.

solve_from_mixture(mixture, db, p_chamber: float, pe_pa: float | None = None, area_ratio: float | None = None, max_atoms: int = 20, t_init: float = 3500.0, ambient_pressure: float = 101325.0) RocketPerformanceComparison

Convenience entry point: solve rocket performance from a PropellantMixture.

Handles all boilerplate — product-species lookup, H₀ assembly, and EquilibriumProblem construction — so the caller only needs to supply the mixture, the species database, and the operating conditions.

Parameters:
  • mixture – A PropellantMixture returned by mix() or expand(). Carries reactants [mol/kg], enthalpy [J/kg], and elements.

  • db – Loaded SpeciesDatabase. Used to look up candidate product species for the element set.

  • p_chamber – Chamber pressure [Pa].

  • pe_pa – Exit pressure [Pa]. One of pe_pa or area_ratio must be provided.

  • area_ratio – Nozzle exit-to-throat area ratio Ae/At. One of pe_pa or area_ratio must be provided.

  • max_atoms – Maximum atom count for product-species candidates passed to db.get_species. Lower values exclude large molecules and speed up the solve. Default 20.

  • t_init – Initial temperature guess for the chamber Newton iteration [K]. Default 3500 K.

  • ambient_pressure – Back pressure [Pa] for the actual-Isp calculation. Default 101 325 Pa (1 atm).

Returns:

RocketPerformanceComparison with paired shifting and frozen results. Key fields on each RocketPerformanceResult:

  • cstar — characteristic velocity c* [m/s]

  • isp_vac — vacuum specific impulse [m/s]

  • isp_sl — sea-level specific impulse [m/s]

  • isp_actual — specific impulse at ambient_pressure [m/s]

  • area_ratio — nozzle area ratio Ae/At

  • chamberEquilibriumSolution at the chamber

  • throat — solution at the throat

  • exit — solution at the nozzle exit

Raises:
  • ValueError – If neither pe_pa nor area_ratio is given.

  • RuntimeError – If the chamber solve does not converge.

Example

from prometheus_equilibrium.equilibrium import SpeciesDatabase, PerformanceSolver
from prometheus_equilibrium.propellants import PropellantDatabase

db = SpeciesDatabase(
    nasa7_path="prometheus/thermo_data/nasa7.json",
    nasa9_path="prometheus/thermo_data/nasa9.json",
)
db.load()

prop_db = PropellantDatabase(
    "prometheus/propellants/propellants.toml"
)
prop_db.load()

mixture = prop_db.mix([
    ("AMMONIUM_PERCHLORATE",   0.68),
    ("ALUMINUM_PURE_CRYSTALINE", 0.18),
    ("HTPB_R_45HT",             0.14),
])

result = PerformanceSolver().solve_from_mixture(
    mixture, db, p_chamber=70e5, area_ratio=10.0
)
print(f"c*  = {result.shifting.cstar:.1f} m/s")
print(f"Isp = {result.shifting.isp_vac:.1f} m/s  (vacuum, shifting)")
print(f"Isp = {result.frozen.isp_vac:.1f} m/s  (vacuum, frozen)")