STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
report_pressure_budget_breakdown.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2"""Print tank→chamber pressure budget per propellant stream from a runner.evaluate call.
3
4Model used in ``impinging`` / ``pintle`` injectors::
5
6 P_injector = P_tank − ΔP_feed
7 ΔP_injector = max(0, P_injector − Pc)
8
9Therefore::
10
11 P_tank − Pc = ΔP_feed + ΔP_injector
12
13``delta_p_remaining`` is the closure residual::
14
15 (P_tank − Pc) − ΔP_feed − ΔP_injector
16
17which should be ~0 Pa when diagnostics are consistent.
18
19Fraction of total tank-to-chamber drop::
20
21 f_feed = ΔP_feed / (P_tank − Pc)
22 f_injector = ΔP_injector / (P_tank − Pc)
23
24Example::
25
26 python scripts/report_pressure_budget_breakdown.py \\
27 --config configs/impinging_lox_ch4_8000N.yaml \\
28 --po-psi 566.8 --pf-psi 780.1 --silent
29"""
30
31from __future__ import annotations
32
33import argparse
34import sys
35from pathlib import Path
36
37ROOT = Path(__file__).resolve().parents[1]
38sys.path.insert(0, str(ROOT))
39
40PSI_PER_PA = 1.0 / 6894.76
41
42from engine.core.runner import PintleEngineRunner # noqa: E402
43from engine.pipeline.io import load_config # noqa: E402
44
45
46def _fmt_pa_psi(pa: float) -> str:
47 return f"{pa:,.2f} Pa ({pa * PSI_PER_PA:.3f} psi)"
48
49
51 name: str,
52 p_tank_pa: float,
53 pc_pa: float,
54 d_inj: float | None,
55 d_feed: float | None,
56) -> None:
57 d_inj = float(d_inj or 0.0)
58 d_feed = float(d_feed or 0.0)
59 d_tot = p_tank_pa - pc_pa
60 d_rem = d_tot - d_feed - d_inj
61
62 print(f"\n=== {name} ===")
63 print(f" P_tank: {_fmt_pa_psi(p_tank_pa)}")
64 print(f" Pc: {_fmt_pa_psi(pc_pa)}")
65 print(f" ΔP_total (tank−Pc): {_fmt_pa_psi(d_tot)}")
66 print(f" ΔP_feed: {_fmt_pa_psi(d_feed)}")
67 print(f" ΔP_injector: {_fmt_pa_psi(d_inj)}")
68 print(f" ΔP_remaining: {_fmt_pa_psi(d_rem)} (should be ~0)")
69
70 if d_tot > 0:
71 f_feed = d_feed / d_tot
72 f_inj = d_inj / d_tot
73 print(f"\n Share of (P_tank − Pc):")
74 print(f" Feed system: {100.0 * f_feed:.2f}%")
75 print(f" Injector element: {100.0 * f_inj:.2f}%")
76 else:
77 print("\n (ΔP_total ≤ 0 — fractions undefined.)")
78
79
80def main() -> None:
81 ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
82 ap.add_argument("--config", type=str, required=True, help="Engine YAML path")
83 ap.add_argument("--po-psi", type=float, required=True, help="LOX tank pressure [psi]")
84 ap.add_argument("--pf-psi", type=float, required=True, help="Fuel tank pressure [psi]")
85 ap.add_argument("--silent", action="store_true", help="Quiet runner.evaluate logging")
86 args = ap.parse_args()
87
88 cfg = load_config(args.config)
89 runner = PintleEngineRunner(cfg)
90 po_pa = float(args.po_psi) / PSI_PER_PA
91 pf_pa = float(args.pf_psi) / PSI_PER_PA
92
93 ev = runner.evaluate(po_pa, pf_pa, silent=args.silent)
94 diag = ev.get("diagnostics") or {}
95 inj = ev.get("injector_pressure") or {}
96 pc = float(ev["Pc"])
97
98 dpo_inj = inj.get("delta_p_injector_O", diag.get("delta_p_injector_O"))
99 dpf_inj = inj.get("delta_p_injector_F", diag.get("delta_p_injector_F"))
100 dpo_fd = inj.get("delta_p_feed_O", diag.get("delta_p_feed_O"))
101 dpf_fd = inj.get("delta_p_feed_F", diag.get("delta_p_feed_F"))
102
103 print("\nPressure budget (from evaluate diagnostics)")
104 print(f"Config: {args.config}")
105
106 _stream_breakdown("LOX (oxidizer)", po_pa, pc, dpo_inj, dpo_fd)
107 _stream_breakdown("Fuel", pf_pa, pc, dpf_inj, dpf_fd)
108
109
110if __name__ == "__main__":
111 main()
None _stream_breakdown(str name, float p_tank_pa, float pc_pa, float|None d_inj, float|None d_feed)