22 geom = getattr(getattr(cfg,
"injector",
None),
"geometry",
None)
28 "n_O": int(ox.n_elements),
29 "n_F": int(fu.n_elements),
30 "d_O_mm": float(ox.d_jet) * 1000.0,
31 "d_F_mm": float(fu.d_jet) * 1000.0,
32 "spacing_O_mm": float(ox.spacing) * 1000.0,
33 "spacing_F_mm": float(fu.spacing) * 1000.0,
34 "imp_deg_O": float(ox.impingement_angle),
35 "imp_deg_F": float(fu.impingement_angle),
84 ap = argparse.ArgumentParser(description=__doc__)
85 ap.add_argument(
"--config", type=str, default=str(ROOT /
"configs/impinging_lox_ch4_8000N.yaml"))
86 ap.add_argument(
"--layer1-max-iterations", type=int, default=120)
87 ap.add_argument(
"--layer1-cma-restarts", type=int, default=1)
88 ap.add_argument(
"--w-geom-ao-af-momentum", type=float, default=2800.0)
89 ap.add_argument(
"--w-mom-list", type=float, nargs=
"+", default=[300.0, 1000.0])
90 args = ap.parse_args()
92 base = load_config(args.config)
93 rows: List[Dict[str, Any]] = []
96 f
"\n=== Long Layer-1 comparison ===\n"
97 f
"config={args.config}\n"
98 f
"W_geom_ao_af_momentum={args.w_geom_ao_af_momentum:g}\n"
99 f
"W_MOM values={args.w_mom_list}\n"
100 f
"layer1_max_iterations={args.layer1_max_iterations}\n"
101 f
"layer1_cma_restarts={args.layer1_cma_restarts}\n"
104 for w_mom
in args.w_mom_list:
105 cfg = copy.deepcopy(base)
106 req = cfg.design_requirements.model_dump()
107 req[
"W_MOM"] = float(w_mom)
108 req[
"W_geom_ao_af_momentum"] = float(args.w_geom_ao_af_momentum)
111 "mode":
"optimizer_controlled",
112 "max_lox_pressure_psi": float(req[
"max_lox_tank_pressure_psi"]),
113 "max_fuel_pressure_psi": float(req[
"max_fuel_tank_pressure_psi"]),
116 print(f
"\n--- Starting run W_MOM={w_mom:g} ---\n")
118 opt_cfg, results = run_layer1_optimization(
122 target_burn_time=float(req.get(
"target_burn_time", 6.0)),
123 tolerances={
"thrust": 0.10,
"apogee": 0.15},
124 pressure_config=pcfg,
126 layer1_max_iterations=int(args.layer1_max_iterations),
127 layer1_cma_restarts=int(args.layer1_cma_restarts),
129 perf = results.get(
"performance")
or {}
130 rows.append(
_collect(float(w_mom), opt_cfg, perf))
132 print(
"\n" +
"=" * 100)
133 print(
"SUMMARY TABLE")
136 f
"{'W_MOM':>8} {'F[N]':>10} {'MR':>8} {'R':>8} {'dP_O/Pc':>10} {'dP_F/Pc':>10} "
137 f
"{'AoAf':>8} {'exp_R1':>8} {'P_O_psi':>10} {'P_F_psi':>10} {'dp_oors':>8}"
143 f
"{r['W_MOM']:>8g} {_f(r['F']):>10.2f} {_f(r['MR']):>8.4f} {_f(r['R']):>8.4f} "
144 f
"{_f(r['dP_O_Pc']):>10.4f} {_f(r['dP_F_Pc']):>10.4f} "
145 f
"{_f(r['AoAf_geom']):>8.4f} {_f(r['expected_AO_AF_R1']):>8.4f} "
146 f
"{_f(r['P_O_psi']):>10.2f} {_f(r['P_F_psi']):>10.2f} {str(r['injector_dp_oors']):>8}"
149 print(
"\n--- Injector geometry ---\n")
152 f
"W_MOM={r['W_MOM']:g}: n_O={r.get('n_O')} d_O={_f(r.get('d_O_mm')):.4f} mm "
153 f
"spacing_O={_f(r.get('spacing_O_mm')):.4f} mm imp_O={_f(r.get('imp_deg_O')):.2f}° | "
154 f
"n_F={r.get('n_F')} d_F={_f(r.get('d_F_mm')):.4f} mm "
155 f
"spacing_F={_f(r.get('spacing_F_mm')):.4f} mm imp_F={_f(r.get('imp_deg_F')):.2f}°"
158 scored = [(
_score(r), r[
"W_MOM"], r)
for r
in rows]
159 scored.sort(key=
lambda x: x[0])
160 best_score, best_w, best_row = scored[0]
161 print(
"\n" +
"=" * 100)
162 print(
"COMPROMISE VERDICT (weighted distance to R≈1, MR≈3.5, F≈8000 N, fuel ΔP/Pc ≤ ~1.2)")
164 for s, wm, rr
in scored:
165 print(f
" W_MOM={wm:g} composite_score={s:.6f}")
167 f
"\nBest compromise by this scalar: **W_MOM = {best_w:g}** "
168 f
"(score={best_score:.6f}). Inspect row above for thrust / ΔP trade-offs.\n"