First-principles 1D thermal / hydraulic / structural solver for regeneratively-cooled liquid rocket engine chambers — real-gas combustion, real-fluid coolant properties, coupled Bartz–Gnielinski–Chen heat transfer, and seven independent design margins that either pass or don't. No curve-fit shortcuts, no black box.
Most of the tools available to a university propulsion team are one of two things: a CEA-only performance spreadsheet that never touches the wall, or a single-point 1D model that assumes constant coolant properties and reports one number for the whole chamber. Neither catches a throat that dry-boils, a rib that fatigues in 40 cycles, or a channel that seizes 6× over its pressure budget.
Hot-wall temperature and thermal stress peak at the throat because heat flux tracks At/A to the 0.9 power. Coolant-side film coefficient is lowest exactly where the tube is narrowest for structural reasons. Two-phase boiling, if it happens, happens downstream of the throat where bulk temperature has climbed — and dryout there is a wall-burnthrough event, not a performance hit.
Every run produces: max hot-wall temperature vs. melt/service limit, max thermal hoop stress vs. 0.67σy(T), coolant ΔP vs. 25% of inlet pressure, max coolant velocity vs. an erosion limit, coolant-wall and bulk temperature vs. coking limits, critical-heat-flux margin, and estimated low-cycle-fatigue life via Coffin–Manson. All seven, every station, every run.
Inputs flow forward through combustion → gas dynamics → a per-station coupled solve → structural margins. The same physics core is exposed at three speeds, because a 4000-point optimizer sweep and a single certified design case have very different runtime budgets.
| Path | Used by | Notes |
|---|---|---|
run_analysis_stream | Live UI (WS) | Full-fidelity, streams per-station |
run_analysis / _march | /api/analyze, tests | Full-fidelity, single shot |
run_batch_analysis_fast | Optimizer sweep | Vectorised, documented simplifications |
Counter-current cooling (the default, and the harder case) integrates the coolant energy balance backward from the nozzle exit while the gas-side march runs forward from the chamber — the two loops meet through the fixed-point iteration at each station, not through a global relaxation sweep.
Numbered the way the solver actually walks through them — gas side, through the wall, into the coolant, and out as a pressure drop and a stress. Every correlation is cited; none of the constants are guessed.
The WebGL nozzle view is colour-mapped directly from solver arrays (heat flux, Twg, Twc, thermal stress) — the same numbers driving the Plotly traces beside it, streamed station-by-station over a WebSocket as the march runs.
The shipped default (45 kN, RP-1/LOX, 90 channels, CuCrZr) is under-cooled. That's deliberate: a tool that always shows green checkmarks in its own screenshots is a tool you can't trust. Below is the actual margins table from the run captured above.
| Check | Value | Limit | Units | Ratio | Status |
|---|---|---|---|---|---|
| Max hot-wall temp Twg | 1.18k | 1.35k | K | 1.14 | PASS |
| Max thermal stress | 575.10M | 93.26M | Pa | 0.16 | FAIL |
| Coolant ΔP (w/ SF) | 7.69M | 2.00M | Pa | 0.26 | FAIL |
| Max coolant velocity | 67.17 | 80.00 | m/s | 1.19 | PASS |
| Coolant-wall temp Twc | 820.86 | 700.00 | K | 0.85 | FAIL |
| Coolant bulk temp | 645.26 | 560.00 | K | 0.87 | FAIL |
| Estimated LCF life | 387.56 | 100.00 | cycles | 3.88 | PASS |
Regression coverage (test_margin_agreement.py) sweeps a grid of channel geometries through both the vectorised optimizer surrogate and the full march, and asserts the two never flip a pass/fail decision and agree on total ΔP within 15% — the fast path used for a 4000-point sweep is checked against the slow path used for the final number.
Sweep channel count, height, width, rib width, wall thickness and coolant flow rate; pre-filter anything that fails packing (channels + ribs exceeding the throat circumference); vectorised-batch solve every survivor; then let differential evolution refine continuously past the grid.
Two known gaps, left out on purpose rather than papered over with a guessed constant.
The Kutateladze/Zuber pool-boiling bound used today is a conservative stand-in — it has no mass-flux (G) term, so it doesn't capture forced-convection CHF enhancement. The correct upgrade is Katto–Ohno (1984), a five-regime correlation whose constants sit behind paywalled primary literature. Rather than guess coefficients for a safety-critical wall-burnthrough margin, it's left out until a verifiable source (textbook table or the original paper) is in hand.
Combustion products are equilibrated once, at chamber conditions, and expanded with frozen composition (constant γ, T₀) — standard practice, and conservative for Isp. True shifting equilibrium would re-run a Cantera SP-flash at every station, which changes Isp, which changes required ṁ, which cascades through the entire coupled solve. Real, but high blast-radius; not added silently.
Every heat-transfer and pressure-drop correlation traces to one of these.
Sutton, G.P. & Biblarz, O., Rocket Propulsion Elements, 9th ed., Wiley, 2016 — Bartz hot-gas film coefficient (Eq. 8-24).
Gnielinski, V. (1976), New equations for heat and mass transfer in turbulent pipe and channel flow, Int. Chem. Eng. 16, 359–368.
Chen, J.C. (1966), Correlation for Boiling Heat Transfer to Saturated Fluids in Convective Flow, Ind. Eng. Chem. Process Des. Dev. 5(3), 322–329. doi:10.1021/i260019a023
Chisholm, D. (1973), Pressure gradients due to friction during the flow of evaporating two-phase mixtures in smooth tubes and channels, Int. J. Heat Mass Transfer 16, 347–358. doi:10.1016/0017-9310(73)90063-X