1"""Run full pipeline with ablative and graphite modeling to see thrust performance."""
3from pathlib
import Path
6import matplotlib.pyplot
as plt
8sys.path.insert(0, str(Path(__file__).parent.parent))
14config_path = Path(__file__).parent.parent /
"configs" /
"default.yaml"
15config = load_config(str(config_path))
18config.ablative_cooling.enabled =
True
19config.ablative_cooling.track_geometry_evolution =
True
22if hasattr(config,
'graphite_insert'):
23 config.graphite_insert.enabled =
True
24 print(
"Graphite insert: ENABLED")
26 print(
"Graphite insert: Not configured (check config file)")
29print(
"FULL PIPELINE: ABLATIVE + GRAPHITE MODELING")
38times = np.linspace(0, burn_time, n_points)
43P_tank_O = np.full(n_points, P_tank_O_psi * 6894.76)
44P_tank_F = np.full(n_points, P_tank_F_psi * 6894.76)
46print(f
"\nTest Conditions:")
47print(f
" Burn time: {burn_time:.1f} s")
48print(f
" Time points: {n_points}")
49print(f
" LOX tank pressure: {P_tank_O_psi:.0f} psi (constant)")
50print(f
" Fuel tank pressure: {P_tank_F_psi:.0f} psi (constant)")
52print(f
"\nAblative Configuration:")
53print(f
" Enabled: {config.ablative_cooling.enabled}")
54print(f
" Track geometry: {config.ablative_cooling.track_geometry_evolution}")
55print(f
" Material: {config.ablative_cooling.material_density:.0f} kg/m³")
56print(f
" Heat of ablation: {config.ablative_cooling.heat_of_ablation/1e6:.1f} MJ/kg")
58if hasattr(config,
'graphite_insert')
and config.graphite_insert.enabled:
59 print(f
"\nGraphite Insert Configuration:")
60 print(f
" Enabled: {config.graphite_insert.enabled}")
61 print(f
" Coverage: {config.graphite_insert.coverage_fraction*100:.0f}%")
62 if hasattr(config.graphite_insert,
'initial_thickness'):
63 print(f
" Initial Thickness: {config.graphite_insert.initial_thickness*1000:.2f} mm")
66print(
"RUNNING TIME-SERIES SIMULATION WITH GEOMETRY EVOLUTION...")
70results = runner.evaluate_arrays_with_time(times, P_tank_O, P_tank_F)
72print(f
"\n✅ Simulation complete!")
75thrust_kN = results[
"F"] / 1000.0
77Pc_psi = results[
"Pc"] / 6894.76
78Lstar = results[
"Lstar"]
79A_throat = results[
"A_throat"]
80V_chamber = results[
"V_chamber"]
81recession_chamber = results.get(
"recession_chamber", np.zeros_like(times))
82recession_throat = results.get(
"recession_throat", np.zeros_like(times))
85thrust_loss_pct = (1.0 - results[
"F"][-1] / results[
"F"][0]) * 100
86Lstar_change_pct = (results[
"Lstar"][-1] / results[
"Lstar"][0] - 1.0) * 100
87throat_area_change_pct = (results[
"A_throat"][-1] / results[
"A_throat"][0] - 1.0) * 100
90print(
"THRUST PERFORMANCE SUMMARY")
92print(f
"Initial Thrust: {thrust_kN[0]:.2f} kN")
93print(f
"Final Thrust: {thrust_kN[-1]:.2f} kN")
94print(f
"Thrust Loss: {thrust_loss_pct:.2f}%")
95print(f
"\nInitial Isp: {Isp[0]:.1f} s")
96print(f
"Final Isp: {Isp[-1]:.1f} s")
97print(f
"Isp Loss: {(1.0 - Isp[-1]/Isp[0])*100:.2f}%")
98print(f
"\nInitial Chamber P: {Pc_psi[0]:.1f} psi")
99print(f
"Final Chamber P: {Pc_psi[-1]:.1f} psi")
100print(f
"Chamber P Change: {(Pc_psi[-1]/Pc_psi[0] - 1.0)*100:.2f}%")
101print(f
"\nInitial L*: {Lstar[0]*1000:.1f} mm")
102print(f
"Final L*: {Lstar[-1]*1000:.1f} mm")
103print(f
"L* Change: {Lstar_change_pct:.2f}%")
104print(f
"\nInitial Throat Area: {A_throat[0]*1e6:.2f} mm²")
105print(f
"Final Throat Area: {A_throat[-1]*1e6:.2f} mm²")
106print(f
"Throat Area Change: {throat_area_change_pct:.2f}%")
107print(f
"\nMax Chamber Recession: {np.max(recession_chamber)*1e6:.2f} µm")
108print(f
"Max Throat Recession: {np.max(recession_throat)*1e6:.2f} µm")
111fig, axes = plt.subplots(2, 3, figsize=(18, 12))
112fig.suptitle(
'Ablative + Graphite Pipeline: Thrust Performance', fontsize=16, fontweight=
'bold')
116ax.plot(times, thrust_kN,
'b-', linewidth=2, label=
'Thrust')
117ax.set_xlabel(
'Time (s)')
118ax.set_ylabel(
'Thrust (kN)')
119ax.set_title(
'Thrust vs Time')
120ax.grid(
True, alpha=0.3)
125ax.plot(times, Isp,
'g-', linewidth=2, label=
'Isp')
126ax.set_xlabel(
'Time (s)')
127ax.set_ylabel(
'Specific Impulse (s)')
128ax.set_title(
'Isp vs Time')
129ax.grid(
True, alpha=0.3)
134ax.plot(times, Pc_psi,
'r-', linewidth=2, label=
'Chamber Pressure')
135ax.set_xlabel(
'Time (s)')
136ax.set_ylabel(
'Chamber Pressure (psi)')
137ax.set_title(
'Chamber Pressure vs Time')
138ax.grid(
True, alpha=0.3)
143ax.plot(times, Lstar * 1000,
'm-', linewidth=2, label=
'L*')
144ax.set_xlabel(
'Time (s)')
145ax.set_ylabel(
'L* (mm)')
146ax.set_title(
'Characteristic Length Evolution')
147ax.grid(
True, alpha=0.3)
152ax.plot(times, A_throat * 1e6,
'orange', linewidth=2, label=
'Throat Area')
153ax.set_xlabel(
'Time (s)')
154ax.set_ylabel(
'Throat Area (mm²)')
155ax.set_title(
'Throat Area Evolution')
156ax.grid(
True, alpha=0.3)
161ax.plot(times, recession_chamber * 1e6,
'purple', linewidth=2, label=
'Chamber Recession')
162ax.plot(times, recession_throat * 1e6,
'orange', linewidth=2, label=
'Throat Recession')
163ax.set_xlabel(
'Time (s)')
164ax.set_ylabel(
'Recession (µm)')
165ax.set_title(
'Cumulative Recession')
166ax.grid(
True, alpha=0.3)
172output_path = Path(__file__).parent /
"ablative_graphite_thrust_performance.png"
173plt.savefig(output_path, dpi=150, bbox_inches=
'tight')
174print(f
"\n✅ Plot saved to: {output_path}")
180print(
"SIMULATION COMPLETE")