STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
code_constants.py
Go to the documentation of this file.
1"""Physics constants and hardcoded design assumptions that live in code, not in a config field.
2
3The UI's Parameters workspace ("In code" section, ``GET /api/config/parameters`` ->
4``backend/routers/config.py``) reads ``CODE_CONSTANTS`` so every number that shapes a result but
5has no ``Param``/schema-field provenance is at least visible, per CLAUDE.md's "every number
6describing hardware carries a provenance" rule -- this module is the register for the numbers that
7don't yet.
8
9Each entry is a physics constant, a named lookup table, or a hardcoded threshold read straight out
10of the current source (not a schema field's Python default, and not a config-editable
11``design_requirements``/``Setup`` value, even one with no dedicated UI field -- those already have a
12YAML path and are excluded here to avoid duplicating the Configuration tab). ``where`` is
13``path/module.py:function_or_symbol`` (never a line number: lines move). ``affects_results`` is
14True when the constant is on the live default path for at least one shipped injector/propellant
15combination; False when it only feeds a diagnostic, a report-only model, or a legacy/inactive path.
16
17Scope (2026-09-26, after the overnight physics pass in wave1_layer1/combustion/injector/
18thermal_chamber.md and report_wave2a.json): engine/core, engine/pipeline,
19engine/optimizer/layers/layer1_static_optimization.py, engine/core/injectors/layout.py,
20ui/flight_sim.py. Excludes unit conversions (PSI, IN, RANKINE_PER_KELVIN, ...), array/grid sizes and
21solver iteration counts/tolerances (MACH_SOLVER_MAX_ITERATIONS, PC_BRACKET_SCAN_POINTS, ...).
22
23See also: docs/hidden-physical-parameters.md (parameters with a config path but no form field --
24a different, overlapping list) and tests/test_code_constants.py (schema + existence check).
25"""
26
27from __future__ import annotations
28
29from typing import Any, Dict, List
30
31CODE_CONSTANTS: List[Dict[str, Any]] = [
32 # ------------------------------------------------------------------ Propellants ---
33 {
34 "name": "_FLUID_THERMO_FALLBACKS",
35 "value": "{lox:(1140,213000,90.2,154.6), methane:(422.6,510000,111.7,190.6), ethanol:(789,838000,351.4,514.0), rp1:(810,246000,489.0,678.0), ipa:(786,665500,355.6,508.3), n2o:(1220,376000,184.7,309.5), h2:(70.8,446000,20.3,33.15), n2:(806,199000,77.36,126.2)}",
36 "where": "engine/pipeline/stability/analysis.py:_FLUID_THERMO_FALLBACKS",
37 "meaning": "Density/L_vap/Tboil/Tcrit per propellant, used when CoolProp has no state for the stability model.",
38 "category": "Propellants",
39 "affects_results": True,
40 },
41 {
42 "name": "_GENERIC_THERMO",
43 "value": "{fuel:(800,300000,450,600), oxidizer:(1140,213000,90.2,154.6)}",
44 "where": "engine/pipeline/stability/analysis.py:_GENERIC_THERMO",
45 "meaning": "Generic fuel/oxidizer thermo fallback when the propellant name matches no table row.",
46 "category": "Propellants",
47 "affects_results": False,
48 },
49 {
50 "name": "DEFAULT_LOX_DENS_KG_M3",
51 "value": "1140.0",
52 "where": "engine/pipeline/constants.py:DEFAULT_LOX_DENS_KG_M3",
53 "meaning": "Fallback LOX density when a fluid object has none; feeds default Cd/Re fallback paths.",
54 "category": "Propellants",
55 "affects_results": False,
56 },
57 {
58 "name": "DEFAULT_FUEL_DENS_KG_M3 / DEFAULT_FUEL_BOILING_POINT_K",
59 "value": "810.0 kg/m3 / 489.0 K",
60 "where": "engine/pipeline/constants.py:DEFAULT_FUEL_DENS_KG_M3",
61 "meaning": "RP-1-like fallback fuel density and boiling point when a fluid object is incomplete.",
62 "category": "Propellants",
63 "affects_results": False,
64 },
65 # ------------------------------------------------------------------ Injector ---
66 {
67 "name": "IMPINGEMENT_LD_TARGET_DEFAULT",
68 "value": "4.0",
69 "where": "engine/core/injectors/layout.py:IMPINGEMENT_LD_TARGET_DEFAULT",
70 "meaning": "Target axial standoff L/d (impingement height over mean jet diameter) Layer 1 aims for.",
71 "category": "Injector",
72 "affects_results": True,
73 },
74 {
75 "name": "IMPINGEMENT_LD_TOL_UNDERIVED",
76 "value": "1.0",
77 "where": "engine/core/injectors/layout.py:IMPINGEMENT_LD_TOL_UNDERIVED",
78 "meaning": "Half-width of the standoff L/d search band when spacing is not derived and no band is given.",
79 "category": "Injector",
80 "affects_results": True,
81 },
82 {
83 "name": "_COS_FLOOR",
84 "value": "0.10",
85 "where": "engine/core/injectors/layout.py:_COS_FLOOR",
86 "meaning": "Floor on |cos(theta)| sizing an inclined hole's footprint, so a near-90 deg jet is finite.",
87 "category": "Injector",
88 "affects_results": True,
89 },
90 {
91 "name": "DRILL_LD_PRACTICE_MAX",
92 "value": "10.0",
93 "where": "engine/core/injectors/layout.py:DRILL_LD_PRACTICE_MAX",
94 "meaning": "Twist-drill practice limit (L/d); past this a shop reaches for gundrill/EDM (warning only).",
95 "category": "Injector",
96 "affects_results": False,
97 },
98 {
99 "name": "ORIFICE_LD_MIN",
100 "value": "4.0",
101 "where": "engine/core/injectors/layout.py:ORIFICE_LD_MIN",
102 "meaning": "SP-8089 3.1.2.2 minimum hole L/d for a jet that leaves concentric with the hole (warning).",
103 "category": "Injector",
104 "affects_results": False,
105 },
106 {
107 "name": "DRILL_ENTRY_MAX_OFF_SQUARE_DEG",
108 "value": "10.0",
109 "where": "engine/core/injectors/layout.py:DRILL_ENTRY_MAX_OFF_SQUARE_DEG",
110 "meaning": "Solid-carbide drill's max off-square entry angle before a flat must be milled first (warning).",
111 "category": "Injector",
112 "affects_results": False,
113 },
114 {
115 "name": "FACE_HEATING_INCLUDED_DEG",
116 "value": "90.0",
117 "where": "engine/core/injectors/layout.py:FACE_HEATING_INCLUDED_DEG",
118 "meaning": "SP-8089 p.26: included angle above which the injector face sees high heat flux (warning).",
119 "category": "Injector",
120 "affects_results": False,
121 },
122 {
123 "name": "FREE_JET_MAX_D",
124 "value": "7.0",
125 "where": "engine/core/injectors/layout.py:FREE_JET_MAX_D",
126 "meaning": "SP-8089 3.1.1.1.4: max impingement distance along the jet, in orifice diameters; hard gate.",
127 "category": "Injector",
128 "affects_results": True,
129 },
130 {
131 "name": "CORE_FRAC_WARN",
132 "value": "0.25",
133 "where": "engine/core/injectors/layout.py:CORE_FRAC_WARN",
134 "meaning": "Chamber cross-section fraction inside the impingement circle below which spray feeds a core.",
135 "category": "Injector",
136 "affects_results": False,
137 },
138 {
139 "name": "EXIT_LAND_DEFAULT",
140 "value": "0.0005",
141 "where": "engine/core/injectors/layout.py:EXIT_LAND_DEFAULT",
142 "meaning": "Assumed metal left around a drilled exit on a contoured face when plate.exit_land is unset [m].",
143 "category": "Injector",
144 "affects_results": True,
145 },
146 {
147 "name": "PLATE_THICKNESS_DEFAULT",
148 "value": "0.0127",
149 "where": "engine/core/injectors/layout.py:PLATE_THICKNESS_DEFAULT",
150 "meaning": "Assumed injector plate thickness (0.5 in) when layer1_injector_plate_thickness_m is unset.",
151 "category": "Injector",
152 "affects_results": True,
153 },
154 {
155 "name": "MANIFOLD_Q_FRAC",
156 "value": "0.05",
157 "where": "engine/core/injectors/layout.py:MANIFOLD_Q_FRAC",
158 "meaning": "Channel velocity head allowed as a fraction of injector dp; above it the layout flags 'bad'.",
159 "category": "Injector",
160 "affects_results": False,
161 },
162 {
163 "name": "PLATE_YIELD_FACTOR",
164 "value": "1.5",
165 "where": "engine/core/injectors/layout.py:PLATE_YIELD_FACTOR",
166 "meaning": "Factor on declared plate yield strength the injector plate-bending check allows (assumed).",
167 "category": "Injector",
168 "affects_results": False,
169 },
170 {
171 "name": "PLATE_POISSON_DEFAULT",
172 "value": "0.3",
173 "where": "engine/core/injectors/layout.py:PLATE_POISSON_DEFAULT",
174 "meaning": "Plate Poisson ratio for the plate-bending check when injector.plate.poisson_ratio is unset.",
175 "category": "Injector",
176 "affects_results": False,
177 },
178 {
179 "name": "layout consistency check: plate vs. Cd L/d mismatch",
180 "value": "0.25",
181 "where": "engine/core/injectors/layout.py:layout_from_config",
182 "meaning": "L/d difference between the drawn plate and the Cd model's L/d that triggers a mismatch warning.",
183 "category": "Injector",
184 "affects_results": False,
185 },
186 {
187 "name": "igniter clearance check: center-clear vs. keepout ratio",
188 "value": "1.2",
189 "where": "engine/core/injectors/layout.py:layout_from_config",
190 "meaning": "A declared center-clear diameter over 1.2x the igniter's keepout diameter raises an error.",
191 "category": "Injector",
192 "affects_results": False,
193 },
194 {
195 "name": "INJECTOR_DISCHARGE_BASELINES",
196 "value": "{pintle: Cd_inf O=0.40 F=0.65 (fixed); impinging: Cd_inf O=F=0.60 (geometry-scaled)}",
197 "where": "engine/core/dispatch.py:INJECTOR_DISCHARGE_BASELINES",
198 "meaning": "Discharge-Cd values stamped onto discharge.{oxidizer,fuel} whenever the UI switches injector type.",
199 "category": "Injector",
200 "affects_results": True,
201 },
202 {
203 "name": "_GEOMETRY_CD_PARAMS['cd_small_hole_exponent']",
204 "value": "0.20",
205 "where": "engine/core/dispatch.py:_GEOMETRY_CD_PARAMS",
206 "meaning": "Small-hole Cd exponent re-stamped on every switch to impinging; contradicts the 0.0 config default.",
207 "category": "Injector",
208 "affects_results": True,
209 },
210 {
211 "name": "INJECTOR_GEOMETRY_TEMPLATES",
212 "value": "pintle: 14 LOX orifices d=2.72mm; impinging: 20+20 elements d=2mm, 50/60 deg",
213 "where": "engine/core/dispatch.py:INJECTOR_GEOMETRY_TEMPLATES",
214 "meaning": "Starting injector.geometry block stamped in whenever the UI switches injector type.",
215 "category": "Injector",
216 "affects_results": True,
217 },
218 {
219 "name": "turbulence intensity correlation (pipe flow, Re^-0.125)",
220 "value": "0.16 * Re^-0.125, clipped [0.02, 0.3] per stream / [0.02, 0.35] mixed; length scale 0.07*d_hyd",
221 "where": "engine/core/injectors/impinging.py:ImpingingInjector.solve",
222 "meaning": "Fully-developed pipe turbulence intensity estimate; feeds pintle spray penetration, else diagnostic-only.",
223 "category": "Injector",
224 "affects_results": True,
225 },
226 # ------------------------------------------------------------------ Discharge & Cd ---
227 {
228 "name": "INLET_GEOMETRY_CD",
229 "value": "{sharp:0.80, chamfered:0.84, conical:0.86, rounded_light:0.85, rounded:0.88, bellmouth:0.95}",
230 "where": "engine/core/discharge.py:INLET_GEOMETRY_CD",
231 "meaning": "Short-tube (L/d 2-5) Cd by named inlet treatment, Huzel & Huang practitioner table.",
232 "category": "Discharge & Cd",
233 "affects_results": True,
234 },
235 {
236 "name": "INLET_GEOMETRY_RD",
237 "value": "{sharp:0.0, chamfered:0.03, conical:0.04, rounded_light:0.05, rounded:0.125, bellmouth:0.20}",
238 "where": "engine/core/discharge.py:INLET_GEOMETRY_RD",
239 "meaning": "Inlet rounding r/d nominally achieved by each named inlet treatment, for the continuous Cd model.",
240 "category": "Discharge & Cd",
241 "affects_results": True,
242 },
243 {
244 "name": "cd_from_inlet_radius_ratio fit constants",
245 "value": "cd_sharp=0.80, cd_max=0.96, k=7.622",
246 "where": "engine/core/discharge.py:cd_from_inlet_radius_ratio",
247 "meaning": "Saturating-exponential fit of short-tube Cd vs inlet rounding r/d through 3 practitioner anchors.",
248 "category": "Discharge & Cd",
249 "affects_results": True,
250 },
251 {
252 "name": "LICHTAROWICZ_A / LICHTAROWICZ_B",
253 "value": "0.827 / 0.0085",
254 "where": "engine/core/discharge.py:LICHTAROWICZ_A",
255 "meaning": "Lichtarowicz (1965) sharp-inlet long-orifice Cd_u = A - B*(L/d), valid L/d 2-10.",
256 "category": "Discharge & Cd",
257 "affects_results": True,
258 },
259 {
260 "name": "LICHTAROWICZ_LD_MAX",
261 "value": "10.0",
262 "where": "engine/core/discharge.py:LICHTAROWICZ_LD_MAX",
263 "meaning": "Longest L/d covered by the Lichtarowicz data; past this the fit's slope is extrapolated.",
264 "category": "Discharge & Cd",
265 "affects_results": True,
266 },
267 {
268 "name": "COUNTERBORE_ENTRANCE_K",
269 "value": "0.5",
270 "where": "engine/core/discharge.py:COUNTERBORE_ENTRANCE_K",
271 "meaning": "Idelchik sharp-inlet loss coefficient for a plenum-to-counterbore entrance (plenum-back plates).",
272 "category": "Discharge & Cd",
273 "affects_results": True,
274 },
275 {
276 "name": "cd_length_factor 'piecewise' thin-plate blend",
277 "value": "0.7625 + 0.11875 * (L/d) below L/d=2 (so sharp*0.7625 = 0.61 thin-plate anchor)",
278 "where": "engine/core/discharge.py:cd_length_factor",
279 "meaning": "Legacy (opt-in) Cd-vs-L/d curve's blend to the thin-plate value below L/d 2; unsourced.",
280 "category": "Discharge & Cd",
281 "affects_results": False,
282 },
283 {
284 "name": "cd_length_factor 'piecewise' friction roll-off",
285 "value": "1.0 - 0.012 * (L/d - 5), floored at 0.85, flat over L/d 2-5",
286 "where": "engine/core/discharge.py:cd_length_factor",
287 "meaning": "Legacy (opt-in) Cd-vs-L/d curve's decline above L/d 5 (1.2%/L/d); unsourced.",
288 "category": "Discharge & Cd",
289 "affects_results": False,
290 },
291 {
292 "name": "NURICK_CC0 / NURICK_RD_GAIN",
293 "value": "0.62 / 11.4",
294 "where": "engine/core/discharge.py:NURICK_CC0",
295 "meaning": "Nurick (1976) vena-contracta Cc0 and its inlet-rounding gain; feeds the cavitation report only.",
296 "category": "Discharge & Cd",
297 "affects_results": False,
298 },
299 {
300 "name": "cd_inf_from_inlet_geometry physical cap",
301 "value": "0.98",
302 "where": "engine/core/discharge.py:cd_inf_from_inlet_geometry",
303 "meaning": "Hard ceiling on any inlet/L-d/counterbore-combined Cd, so no orifice reports above 0.98.",
304 "category": "Discharge & Cd",
305 "affects_results": True,
306 },
307 # ------------------------------------------------------------------ Combustion efficiency ---
308 {
309 "name": "WATSON_EXPONENT",
310 "value": "0.38",
311 "where": "engine/pipeline/combustion_physics.py:WATSON_EXPONENT",
312 "meaning": "Watson (1943) exponent for latent heat vs. reduced temperature, used in the drop evaporation march.",
313 "category": "Combustion efficiency",
314 "affects_results": True,
315 },
316 {
317 "name": "spray_vaporization_march: Ranz-Marshall Nu correlation",
318 "value": "Nu = 2.0 + 0.6 * Re_f^0.5 * Pr^(1/3)",
319 "where": "engine/pipeline/combustion_physics.py:spray_vaporization_march",
320 "meaning": "Ranz-Marshall droplet Nusselt-number correlation driving the d^2-law evaporation rate.",
321 "category": "Combustion efficiency",
322 "affects_results": True,
323 },
324 {
325 "name": "spray_vaporization_march: Putnam drag correction",
326 "value": "phi = 1 + Re^(2/3)/6 for Re < 1000, else 0.424*Re/24",
327 "where": "engine/pipeline/combustion_physics.py:spray_vaporization_march",
328 "meaning": "Putnam's drag-coefficient correction to Stokes drag on an evaporating drop, by Reynolds regime.",
329 "category": "Combustion efficiency",
330 "affects_results": True,
331 },
332 {
333 "name": "spray_vaporization_march: 1/3-rule film temperature",
334 "value": "T_f = T_s + (T_c - T_s) / 3",
335 "where": "engine/pipeline/combustion_physics.py:spray_vaporization_march",
336 "meaning": "Film-property reference temperature (1/3-rule) for a drop's boundary-layer gas properties.",
337 "category": "Combustion efficiency",
338 "affects_results": True,
339 },
340 {
341 "name": "_V_FLOOR",
342 "value": "1.0e-3 m/s",
343 "where": "engine/pipeline/combustion_physics.py:_V_FLOOR",
344 "meaning": "Velocity floor for a drop stalled at the injector face, so the march never divides by zero.",
345 "category": "Combustion efficiency",
346 "affects_results": True,
347 },
348 {
349 "name": "legacy gasification: vapor-diffusivity correlation",
350 "value": "D_M_REF=5e-5 m2/s at D_M_T_REF=1500 K, D_M_P_REF=2.5e6 Pa; D ~ (T/Tref)^1.75 * (Pref/P)",
351 "where": "engine/pipeline/physics_constants.py:D_M_REF",
352 "meaning": "Reference vapor diffusivity and its T/P scaling for the legacy single-drop gasification helper.",
353 "category": "Combustion efficiency",
354 "affects_results": False,
355 },
356 {
357 "name": "legacy gasification: U_SLIP_CAP / D_MIN_GASIFICATION",
358 "value": "50.0 m/s / 1e-6 m",
359 "where": "engine/pipeline/physics_constants.py:U_SLIP_CAP",
360 "meaning": "Slip-velocity cap and minimum drop size for the legacy gasification helper (progress diagnostic only).",
361 "category": "Combustion efficiency",
362 "affects_results": False,
363 },
364 {
365 "name": "CARBON_OXIDISERS reaction enthalpies",
366 "value": "H2O:+10.93MJ/kg, CO2:+14.36MJ/kg, OH:+5.67MJ/kg, O2:-9.20MJ/kg, O:-29.95MJ/kg (per kg carbon)",
367 "where": "engine/pipeline/thermal/graphite_cooling.py:CARBON_OXIDISERS",
368 "meaning": "JANAF heats of reaction per kg carbon consumed, for each graphite-throat oxidiser species.",
369 "category": "Combustion efficiency",
370 "affects_results": True,
371 },
372 # ------------------------------------------------------------------ Chamber & nozzle ---
373 {
374 "name": "PC_CHOKE_FLOOR_PA",
375 "value": "2.0 * 101325.0 Pa (2 atm)",
376 "where": "engine/core/chamber_solver.py:PC_CHOKE_FLOOR_PA",
377 "meaning": "Floor of the chamber-pressure search: below it the sonic-throat demand model breaks down.",
378 "category": "Chamber & nozzle",
379 "affects_results": True,
380 },
381 {
382 "name": "PC_MIN_TOTAL_DROP_FRAC",
383 "value": "0.02",
384 "where": "engine/core/chamber_solver.py:PC_MIN_TOTAL_DROP_FRAC",
385 "meaning": "Minimum feed+injector pressure drop (as a fraction of tank pressure) allowed in the Pc search.",
386 "category": "Chamber & nozzle",
387 "affects_results": True,
388 },
389 {
390 "name": "Rao contour throat arc radii",
391 "value": "upstream 1.5 * R_t, downstream 0.382 * R_t",
392 "where": "engine/core/nozzle_solver.py:rao",
393 "meaning": "Standard Rao parabolic-bell throat entrance/exit circular-arc radii, as multiples of throat radius.",
394 "category": "Chamber & nozzle",
395 "affects_results": True,
396 },
397 {
398 "name": "NOZZLE_ANGLES_TABLE",
399 "value": "theta_n/theta_e by expansion ratio (4-100) and bell percent (60-100%), parabola-angle chart",
400 "where": "engine/core/nozzle_angles.py:NOZZLE_ANGLES_TABLE",
401 "meaning": "Rao nozzle entrance/exit half-angle lookup table used to draw the bell contour.",
402 "category": "Chamber & nozzle",
403 "affects_results": True,
404 },
405 {
406 "name": "_LAYER1_BELL_FRACTION",
407 "value": "0.8",
408 "where": "engine/optimizer/layers/layer1_static_optimization.py:_LAYER1_BELL_FRACTION",
409 "meaning": "Fraction of a full-length Rao bell Layer 1 draws and uses for the engine-length gate.",
410 "category": "Chamber & nozzle",
411 "affects_results": True,
412 },
413 {
414 "name": "_layer1_chamber_od_floor_m: minimum contraction ratio",
415 "value": "1.05",
416 "where": "engine/optimizer/layers/layer1_static_optimization.py:_layer1_chamber_od_floor_m",
417 "meaning": "Floor on D/Dt used to size the smallest chamber OD worth searching, when dt_ratio_min is looser.",
418 "category": "Chamber & nozzle",
419 "affects_results": True,
420 },
421 {
422 "name": "_layer1_chamber_mass_kg: Roark fixed-edge closure-plate coefficient",
423 "value": "0.75",
424 "where": "engine/optimizer/layers/layer1_static_optimization.py:_layer1_chamber_mass_kg",
425 "meaning": "Roark Table 11.2 fixed-edge round-plate stress coefficient sizing the injector-face closure mass term.",
426 "category": "Chamber & nozzle",
427 "affects_results": True,
428 },
429 {
430 "name": "_LAYER1_DEFAULT_EXIT_PRESSURE_INSIDE_QUAD",
431 "value": "0.35",
432 "where": "engine/optimizer/layers/layer1_static_optimization.py:_LAYER1_DEFAULT_EXIT_PRESSURE_INSIDE_QUAD",
433 "meaning": "Default weight on the quadratic penalty keeping the nozzle exit pressure near ambient.",
434 "category": "Chamber & nozzle",
435 "affects_results": True,
436 },
437 {
438 "name": "_DERIVE_AT_SLOPE_DEFAULT / MIN / MAX",
439 "value": "0.35 / 0.12 / 1.20",
440 "where": "engine/optimizer/layers/layer1_static_optimization.py:_DERIVE_AT_SLOPE_DEFAULT",
441 "meaning": "Measured dlnF/dlnAt slope (ethalox impinging) and its clamp band for deriving throat area.",
442 "category": "Chamber & nozzle",
443 "affects_results": True,
444 },
445 # ------------------------------------------------------------------ Thermal protection ---
446 {
447 "name": "BARTZ_OMEGA",
448 "value": "0.6",
449 "where": "engine/pipeline/thermal/gas_side.py:BARTZ_OMEGA",
450 "meaning": "Bartz boundary-layer viscosity-temperature exponent (H&H eq. 4-14) in the property correction.",
451 "category": "Thermal protection",
452 "affects_results": True,
453 },
454 {
455 "name": "bartz_h leading coefficient",
456 "value": "0.026",
457 "where": "engine/pipeline/thermal/gas_side.py:bartz_h",
458 "meaning": "Leading empirical coefficient of the Bartz gas-side heat-transfer correlation (H&H eq. 4-13).",
459 "category": "Thermal protection",
460 "affects_results": True,
461 },
462 {
463 "name": "THROAT_RC_OVER_RT",
464 "value": "0.5 * (1.5 + 0.382)",
465 "where": "engine/pipeline/thermal/gas_side.py:THROAT_RC_OVER_RT",
466 "meaning": "Bartz's throat radius-of-curvature term, taken as the mean of the drawn contour's two arc radii.",
467 "category": "Thermal protection",
468 "affects_results": True,
469 },
470 {
471 "name": "LECKNER_T_MAX",
472 "value": "2500.0 K",
473 "where": "engine/pipeline/thermal/gas_side.py:LECKNER_T_MAX",
474 "meaning": "Temperature above which Leckner's emissivity pressure correction is held fixed (fit range limit).",
475 "category": "Thermal protection",
476 "affects_results": True,
477 },
478 {
479 "name": "BEAM_LENGTH_COEFF / CYLINDER_BEAM_LENGTH_OVER_D",
480 "value": "3.6 / 0.95",
481 "where": "engine/pipeline/thermal/gas_side.py:BEAM_LENGTH_COEFF",
482 "meaning": "Mean gas radiation beam length: 3.6*V/A general enclosure, capped at 0.95x local bore diameter.",
483 "category": "Thermal protection",
484 "affects_results": True,
485 },
486 {
487 "name": "_LECKNER_H2O / _LECKNER_CO2 emissivity coefficients",
488 "value": "3x3 (H2O) and 3x4 (CO2) polynomial coefficient matrices",
489 "where": "engine/pipeline/thermal/gas_side.py:_LECKNER_H2O",
490 "meaning": "Leckner (Modest Table 11.3) zero-pressure gas emissivity polynomial fit coefficients for H2O/CO2.",
491 "category": "Thermal protection",
492 "affects_results": True,
493 },
494 {
495 "name": "gas_absorptivity: Hottel scaling exponents",
496 "value": "n_H2O=0.45, n_CO2=0.65",
497 "where": "engine/pipeline/thermal/gas_side.py:gas_absorptivity",
498 "meaning": "Hottel's temperature-scaling exponents converting gas emissivity to wall-emission absorptivity.",
499 "category": "Thermal protection",
500 "affects_results": True,
501 },
502 {
503 "name": "R_GAS / MW_C",
504 "value": "8.314462618 J/(mol K) / 12.0107 kg/kmol",
505 "where": "engine/pipeline/thermal/graphite_cooling.py:MW_C",
506 "meaning": "Universal gas constant and carbon molar mass used to stoichiometrically size graphite recession.",
507 "category": "Thermal protection",
508 "affects_results": True,
509 },
510 {
511 "name": "calculate_throat_heuristic_multiplier defaults",
512 "value": "fallback 1.3, velocity exponent 0.8, pressure exponent 0.2, turbulence_enhancement 1.1, clamp [1.2, 2.5]",
513 "where": "engine/pipeline/thermal/graphite_cooling.py:calculate_throat_heuristic_multiplier",
514 "meaning": "Heuristic throat-vs-chamber recession multiplier still used on runner.py's legacy time-varying path.",
515 "category": "Thermal protection",
516 "affects_results": True,
517 },
518 {
519 "name": "calculate_local_recession_rate: pyrolysis-to-gas surface temperature blend",
520 "value": "T_surface = pyrolysis_temp + 0.1*(T_gas - pyrolysis_temp), capped at 0.95*T_gas",
521 "where": "engine/pipeline/thermal/ablative_geometry.py:calculate_local_recession_rate",
522 "meaning": "Heuristic interpolation for an ablative surface's temperature above pyrolysis, on the legacy path.",
523 "category": "Thermal protection",
524 "affects_results": True,
525 },
526 {
527 "name": "calculate_local_recession_rate defaults",
528 "value": "blowing_efficiency=0.8, char_layer_conductivity=0.2 W/(m K), char_layer_thickness=0.001 m",
529 "where": "engine/pipeline/thermal/ablative_geometry.py:calculate_local_recession_rate",
530 "meaning": "Assumed char-layer properties for the legacy (non-liner_response) ablative recession calculation.",
531 "category": "Thermal protection",
532 "affects_results": True,
533 },
534 # ------------------------------------------------------------------ Stability ---
535 {
536 "name": "DEFAULT_OVERLAP",
537 "value": "{1L:0.70, 2L:0.45, 3L:0.30, 1T:0.40, 2T:0.30, 1R:0.35, 3T:0.25, 1T1R:0.25}",
538 "where": "engine/pipeline/stability/acoustic.py:DEFAULT_OVERLAP",
539 "meaning": "Assumed, uncalibrated mode-shape/heat-release overlap per acoustic mode driving the HF gate.",
540 "category": "Stability",
541 "affects_results": True,
542 },
543 {
544 "name": "TRANSVERSE_EIGENVALUES",
545 "value": "{1T:1.84118, 2T:3.05424, 1R:3.83171, 3T:4.20119, 1T1R:5.33144}",
546 "where": "engine/pipeline/stability/core.py:TRANSVERSE_EIGENVALUES",
547 "meaning": "Zeros of J'_m (velocity-boundary Bessel roots) setting transverse acoustic mode frequencies.",
548 "category": "Stability",
549 "affects_results": True,
550 },
551 {
552 "name": "sensitive_time_lag: chi default",
553 "value": "0.5",
554 "where": "engine/pipeline/stability/core.py:sensitive_time_lag",
555 "meaning": "Default sensitive-lag fraction chi (tau_sens = chi*tau_vap); the model's single largest uncertainty.",
556 "category": "Stability",
557 "affects_results": True,
558 },
559 {
560 "name": "stability_score display mapping",
561 "value": "clip((margin - 0.85) / 0.45, 0, 1)",
562 "where": "engine/pipeline/stability/analysis.py:stability_score",
563 "meaning": "Fixed linear map from the limiting gain-margin gate to the reported 0-1 stability score.",
564 "category": "Stability",
565 "affects_results": False,
566 },
567 {
568 "name": "_TUBE_E_STAINLESS",
569 "value": "193.0e9 Pa",
570 "where": "engine/pipeline/stability/analysis.py:_TUBE_E_STAINLESS",
571 "meaning": "Assumed 300-series stainless Young's modulus for a feed tube whose material isn't configured.",
572 "category": "Feed & tanks",
573 "affects_results": True,
574 },
575 {
576 "name": "_liquid_bulk_modulus generic fallback",
577 "value": "1.5e9 Pa",
578 "where": "engine/pipeline/stability/analysis.py:_liquid_bulk_modulus",
579 "meaning": "Generic liquid bulk modulus used for water-hammer/line-frequency when CoolProp has no state.",
580 "category": "Feed & tanks",
581 "affects_results": True,
582 },
583 {
584 "name": "_drop: assumed injector/feed pressure-drop fractions",
585 "value": "delta_p_injector = 0.30 * Pc; delta_p_feed = 0.10 * Pc",
586 "where": "engine/pipeline/stability/analysis.py:_drop",
587 "meaning": "Assumed injector and feed pressure-drop fractions of Pc when the solver reports none, for the chug gate.",
588 "category": "Stability",
589 "affects_results": True,
590 },
591 {
592 "name": "_feed_geometry: assumed feed line length",
593 "value": "0.305 m",
594 "where": "engine/pipeline/stability/analysis.py:_feed_geometry",
595 "meaning": "Assumed tank-outlet-to-manifold feed length for the chug inertance when feed_system.length is unset.",
596 "category": "Feed & tanks",
597 "affects_results": True,
598 },
599 {
600 "name": "_feed_geometry: assumed feed inlet diameter",
601 "value": "0.0127 m",
602 "where": "engine/pipeline/stability/analysis.py:_feed_geometry",
603 "meaning": "Assumed feed-line bore for the chug inertance when the feed system declares no area at all.",
604 "category": "Feed & tanks",
605 "affects_results": True,
606 },
607 {
608 "name": "_chamber_dims: assumed chamber length / diameter",
609 "value": "0.18 m / 0.1 m",
610 "where": "engine/pipeline/stability/analysis.py:_chamber_dims",
611 "meaning": "Assumed chamber length and diameter for the acoustic-mode model when no geometry has been solved.",
612 "category": "Stability",
613 "affects_results": True,
614 },
615 {
616 "name": "build_stability_inputs: assumed nozzle-entrance Mach number",
617 "value": "0.2",
618 "where": "engine/pipeline/stability/analysis.py:build_stability_inputs",
619 "meaning": "Assumed mean Mach at the nozzle entrance (sets convective/nozzle acoustic damping) if not derivable.",
620 "category": "Stability",
621 "affects_results": True,
622 },
623 # ------------------------------------------------------------------ Feed & tanks ---
624 {
625 "name": "FEED_LINE_D_3_8_IN_NOMINAL_M and dual-line equivalents",
626 "value": "(3/8) * 25.4e-3 m nominal bore; dual-line equivalent d_inlet = d * sqrt(2)",
627 "where": "engine/pipeline/constants.py:FEED_LINE_D_3_8_IN_NOMINAL_M",
628 "meaning": "Reference 3/8 in tube bore and its twin-parallel-line equivalent diameter for feed_system presets.",
629 "category": "Feed & tanks",
630 "affects_results": True,
631 },
632 # ------------------------------------------------------------------ Vehicle & flight ---
633 {
634 "name": "GAMMA_AIR / R_AIR",
635 "value": "1.4 / 287.05287 J/(kg K)",
636 "where": "engine/pipeline/vehicle_drag.py:R_AIR",
637 "meaning": "Air specific-heat ratio and gas constant (US Standard Atmosphere 1976) for the drag build-up.",
638 "category": "Vehicle & flight",
639 "affects_results": True,
640 },
641 {
642 "name": "isa_troposphere: US Standard Atmosphere 1976 constants",
643 "value": "T0=288.15K, lapse=0.0065 K/m to 11000m, then 216.65K isothermal to 20000m",
644 "where": "engine/pipeline/vehicle_drag.py:isa_troposphere",
645 "meaning": "Sea-level temperature, lapse rate and tropopause/stratosphere boundaries for the flight atmosphere.",
646 "category": "Vehicle & flight",
647 "affects_results": True,
648 },
649 {
650 "name": "isa_troposphere: Sutherland's law constants",
651 "value": "mu = 1.458e-6 * T^1.5 / (T + 110.4)",
652 "where": "engine/pipeline/vehicle_drag.py:isa_troposphere",
653 "meaning": "Sutherland's law coefficients for air viscosity, feeding the drag build-up's Reynolds number.",
654 "category": "Vehicle & flight",
655 "affects_results": True,
656 },
657 {
658 "name": "skin_friction_cf: turbulent Cf formula",
659 "value": "1.48e-2 below Re=1e4, else 1 / (1.50*ln(Re) - 5.6)^2",
660 "where": "engine/pipeline/vehicle_drag.py:skin_friction_cf",
661 "meaning": "Niskanen (2013) eq. 3.81 fully-turbulent flat-plate friction coefficient vs. Reynolds number.",
662 "category": "Vehicle & flight",
663 "affects_results": True,
664 },
665 {
666 "name": "skin_friction_cf: compressibility correction",
667 "value": "c_turb = 1 - 0.1*M^2 (M<1.1), else 1/(1+0.15*M^2)^0.58",
668 "where": "engine/pipeline/vehicle_drag.py:skin_friction_cf",
669 "meaning": "Niskanen eq. 3.82/3.83 compressibility correction to turbulent skin friction, subsonic/supersonic.",
670 "category": "Vehicle & flight",
671 "affects_results": True,
672 },
673 {
674 "name": "base_cd",
675 "value": "0.12 + 0.13*M^2 for M<=1, else 0.25/M",
676 "where": "engine/pipeline/vehicle_drag.py:base_cd",
677 "meaning": "Niskanen eq. 3.94 base-drag coefficient vs. Mach number for the aft end of the vehicle.",
678 "category": "Vehicle & flight",
679 "affects_results": True,
680 },
681 {
682 "name": "nose_pressure_cd: stagnation coefficient",
683 "value": "0.8 * sin(phi)^2",
684 "where": "engine/pipeline/vehicle_drag.py:nose_pressure_cd",
685 "meaning": "Niskanen eq. 3.86 subsonic nose pressure-drag coefficient from the local half-angle phi.",
686 "category": "Vehicle & flight",
687 "affects_results": True,
688 },
689 {
690 "name": "_STONEY_FN3",
691 "value": "von Karman / LV-Haack wave-drag Cd vs Mach (0.9-3.0), fineness-3 nose, tabulated",
692 "where": "engine/pipeline/vehicle_drag.py:_STONEY_FN3",
693 "meaning": "Stoney (NASA TR R-100) transonic/supersonic nose wave-drag table, as OpenRocket tabulates it.",
694 "category": "Vehicle & flight",
695 "affects_results": True,
696 },
697 {
698 "name": "setup_flight: engine/propulsion inertia proxy geometry",
699 "value": "engine_r=0.6*rocket_radius, engine_h=0.3 m, prop_r=0.8*rocket_radius, prop_h=0.5 m",
700 "where": "ui/flight_sim.py:setup_flight",
701 "meaning": "Assumed engine/propulsion-system envelope used to estimate moment of inertia when none is modeled.",
702 "category": "Vehicle & flight",
703 "affects_results": True,
704 },
705 {
706 "name": "setup_flight: cm_wo_motor fallback",
707 "value": "motor_position + 1.5 m",
708 "where": "ui/flight_sim.py:setup_flight",
709 "meaning": "Assumed rocket center-of-mass without the motor when config.rocket.cm_wo_motor is unset.",
710 "category": "Vehicle & flight",
711 "affects_results": True,
712 },
713 {
714 "name": "burn_analysis: throat-growth warning threshold",
715 "value": "20.0 %",
716 "where": "engine/pipeline/burn_analysis.py:analyze_burn_degradation",
717 "meaning": "Throat-area growth over a burn above which the burn-progression report flags a warning.",
718 "category": "Vehicle & flight",
719 "affects_results": False,
720 },
721 # ------------------------------------------------------------------ Optimizer ---
722 {
723 "name": "_layer1_valley_escape_tier thresholds",
724 "value": "tier 3: evals>5000 & stagnation>1000; tier 2: >3000 & >500; tier 1: >1500 & >300",
725 "where": "engine/optimizer/layers/layer1_static_optimization.py:_layer1_valley_escape_tier",
726 "meaning": "Evaluation-count and stagnation thresholds that boost CMA-ES sigma while no feasible design exists.",
727 "category": "Optimizer",
728 "affects_results": True,
729 },
730 {
731 "name": "valley escape sigma boost_factors",
732 "value": "block/refresh path [1.0, 1.5, 2.0, 3.0]; legacy path [1.0, 2.0, 4.0, 8.0]",
733 "where": "engine/optimizer/layers/layer1_static_optimization.py:_layer1_valley_escape_tier",
734 "meaning": "CMA-ES step-size multipliers applied per valley-escape tier to jump out of an infeasible plateau.",
735 "category": "Optimizer",
736 "affects_results": True,
737 },
738 {
739 "name": "_LAYER1_DEFAULT_MIN_STABILITY_MARGIN",
740 "value": "1.2",
741 "where": "engine/optimizer/layers/layer1_static_optimization.py:_LAYER1_DEFAULT_MIN_STABILITY_MARGIN",
742 "meaning": "Default chug gain-margin requirement Layer 1 signs off against when none is configured.",
743 "category": "Optimizer",
744 "affects_results": True,
745 },
746 {
747 "name": "_LAYER1_DEFAULT_INFEASIBILITY_GATE_EPS",
748 "value": "0.002",
749 "where": "engine/optimizer/layers/layer1_static_optimization.py:_LAYER1_DEFAULT_INFEASIBILITY_GATE_EPS",
750 "meaning": "Slack added to feasibility gates so a design sitting exactly on a limit still scores feasible.",
751 "category": "Optimizer",
752 "affects_results": True,
753 },
754 {
755 "name": "_LAYER1_DEFAULT_MOMENTUM_LOG_DEADBAND_REL",
756 "value": "0.0",
757 "where": "engine/optimizer/layers/layer1_static_optimization.py:_LAYER1_DEFAULT_MOMENTUM_LOG_DEADBAND_REL",
758 "meaning": "Default dead-band (relative, log space) around the momentum-ratio target before the term penalizes.",
759 "category": "Optimizer",
760 "affects_results": True,
761 },
762 {
763 "name": "_LAYER1_DEFAULT_DP_O_BAND / _LAYER1_DEFAULT_DP_F_BAND",
764 "value": "(0.20, 0.40)",
765 "where": "engine/optimizer/layers/layer1_static_optimization.py:_LAYER1_DEFAULT_DP_O_BAND",
766 "meaning": "Default injector dp/Pc band per side; a config's 0.15-0.35 is silently widened to this exact band.",
767 "category": "Optimizer",
768 "affects_results": True,
769 },
770]