42 """CEA ideal numbers at the model's real operating point."""
44 isp_vac = ch.get_Isp(Pc=P, MR=MR, eps=eps)
45 cstar = ch.get_Cstar(Pc=P, MR=MR) * 0.3048
46 cf_vac = isp_vac * G0 / cstar
48 isp_amb = ch.estimate_Ambient_Isp(Pc=P, MR=MR, eps=eps, Pamb=Pa_pa / PSI)[0]
50 isp_amb = float(
"nan")
51 return cf_vac, cstar, isp_vac, isp_amb
54def one_case(runner, ch, P_O_pa, P_F_pa, Pa_pa, eps_override=None):
56 cg = cfg.chamber_geometry
57 if eps_override
is not None:
58 cg.expansion_ratio = eps_override
59 cg.A_exit = eps_override * cg.A_throat
60 res = runner.evaluate(P_O_pa, P_F_pa, P_ambient=Pa_pa)
61 Pc, MR, mdot = res[
"Pc"], res[
"MR"], res[
"mdot_total"]
62 At, Ae, eps = cg.A_throat, cg.A_exit, cg.expansion_ratio
63 eta = (res.get(
"diagnostics")
or {}).get(
"eta_cstar", float(
"nan"))
66 model_Isp = model_F / (mdot * G0)
68 cf_vac, cstar, isp_vac, isp_amb =
cea_refs(ch, Pc, MR, eps, Pa_pa)
69 cfvac_F = cf_vac * Pc * At - Pa_pa * Ae
70 cfvac_Isp = cfvac_F / (mdot * G0)
71 expected_Isp = eta * isp_amb
73 return dict(Pc=Pc, MR=MR, eps=eps, eta=eta, mdot=mdot,
74 model_F=model_F, model_Isp=model_Isp,
75 cfvac_F=cfvac_F, cfvac_Isp=cfvac_Isp,
76 ceiling=isp_amb, expected=expected_Isp,
77 model_err=model_Isp / isp_amb - 1.0,
78 model_vs_expected=model_Isp / expected_Isp - 1.0,
79 cfvac_vs_expected=cfvac_Isp / expected_Isp - 1.0)
91 for name, path
in CONFIGS:
92 cfg = load_config(path)
95 print(f
"\n{'='*120}\n{name} ({path})\n{'='*120}")
97 print(
"\n[A] Operating-point sweep (sea level, design eps):")
98 for po, pf
in [(1305, 974), (1200, 900), (1100, 820), (1000, 750), (900, 680)]:
100 print(
fmt_row(f
"P=({po},{pf})",
one_case(runner, ch, po*PSI, pf*PSI, 101325.0)))
101 except Exception
as e:
102 print(f
" P=({po},{pf}) skipped: {type(e).__name__}: {e}")
104 print(
"\n[B] Expansion-ratio sweep (P=(1305,974), sea level):")
105 base_eps = cfg.chamber_geometry.expansion_ratio
106 for eps
in [3.0, 4.0, 5.0, 6.5, 8.0]:
108 print(
fmt_row(f
"eps={eps}",
one_case(runner, ch, 1305*PSI, 974*PSI, 101325.0, eps_override=eps)))
109 except Exception
as e:
110 print(f
" eps={eps} skipped: {type(e).__name__}: {e}")
111 cfg.chamber_geometry.expansion_ratio = base_eps
112 cfg.chamber_geometry.A_exit = base_eps * cfg.chamber_geometry.A_throat
114 print(
"\n[C] Altitude sweep (P=(1305,974), design eps):")
115 for alt_pa
in [101325.0, 70000.0, 40000.0, 10000.0, 1.0]:
117 print(
fmt_row(f
"Pa={alt_pa/1000:.0f}kPa",
one_case(runner, ch, 1305*PSI, 974*PSI, alt_pa)))
118 except Exception
as e:
119 print(f
" Pa={alt_pa} skipped: {type(e).__name__}: {e}")