STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
test_layerx_hardware Namespace Reference

Functions

 fake_prep (config, float dt=0.05, float ambient=AMBIENT)
 series (int n=69, float dt=0.05, po=(560.0, 600.0), pf=(565.0, 605.0))
 config ()
 prep (config)
 burn ()
 replayed (prep, burn)
 test_the_replay_keeps_its_old_keys (replayed)
 test_every_kept_array_is_one_value_per_replay_point (replayed)
 test_throat_diameter_is_its_area (replayed)
 test_cstar_efficiency_is_its_breakdown (replayed)
 test_injector_drop_is_line_exit_less_the_dump_and_chamber (replayed)
 test_stations_carry_recession_temperatures_and_load (replayed, config)
 test_station_loads_are_the_solvers_own_barrel_and_throat_loads (replayed)
 test_axial_sidecar_is_rows_of_t_by_columns_of_x (replayed)
 test_erodes_names_the_engines_with_a_receding_wall (config)
 test_a_graphite_only_engine_now_erodes (config, burn)
 test_an_untracked_liner_still_erodes (config, burn)
 test_the_legacy_path_refuses_an_eroding_engine (config)
 _slab_solver (L=0.01, k=0.5, rho=1500.0, cp=1200.0, T0=400.0, dT=100.0)
 test_soak_window_is_three_conduction_times_of_the_slowest_layer (replayed, config)
 test_insulated_slab_soaks_to_its_stored_heat_on_the_fourier_clock ()
 test_soak_dates_a_plateau_when_it_is_reached ()
 test_soak_on_le4_is_an_adiabatic_upper_bound (replayed)
 test_soak_refuses_another_replays_walls (config)
 _solve_capturing (config, monkeypatch, **kw)
 test_chug_sees_the_design_point_by_default (config, monkeypatch)
 test_chug_sees_the_eroded_chamber_when_asked (config, monkeypatch)
 hardware (prep, replayed, burn)
 test_hardware_follows_the_replay_points (hardware, replayed)
 test_eps_lstar_and_contraction_from_the_areas_by_hand (hardware, replayed, config)
 test_liner_left_and_insert_back_face (hardware, replayed, config)
 test_summary_first_point_is_against_as_built (hardware, replayed)
 test_insert_back_face_with_a_declared_case_is_the_bondline (config)
 test_contour_as_built_and_eroded (hardware, replayed, config)
 test_summerfield_and_schmucker_by_hand ()
 test_le4_runs_full_on_the_pad (hardware)
 test_isp_waterfall_closes_and_its_terms_are_the_thrust_identities (hardware, replayed, prep)
 test_isp_ideal_is_cea_by_hand (hardware, replayed, prep)
 test_hardware_never_raises (prep)
 test_line_exit_drops_the_supply_share_with_k0 (config)
 test_line_exit_is_unchanged_for_le4 (config)
 test_a_line_exit_replay_ignores_supply_k (config, burn)
 card (config)
 test_expansion_chamber_is_the_card_at_the_as_built_throat (card, prep)
 test_expansion_chamber_scales_vacuum_velocity_by_cf_vac (card, prep)
 test_expansion_chamber_prices_thrust_on_the_flow_that_burns (card, prep)
 test_expansion_chamber_follows_enginedesign_at_the_eroded_throat (card, prep, replayed)
 test_drawn_throat_is_the_solvers_throat ()
 test_the_phenolic_backing_cools_the_insert_and_shields_the_case (config)

Variables

 ROOT = Path(__file__).resolve().parents[1]
str LE4 = ROOT / "configs" / "ethalox_6800N.yaml"
float PSI = 6894.757293168361
float AMBIENT = 94070.0
 pytestmark = pytest.mark.skipif(not LE4.is_file(), reason="LE4 config (configs/ethalox_6800N.yaml) not in this checkout")
tuple OLD_KEYS

Detailed Description

Layer X hardware read-outs: what the erosion replay keeps, and the hardware geometry built on it.

What these check, and against what:

* The replay keeps the per-step arrays the coupled solver computes (audit 5.2) without touching the
  keys it had. The new arrays are checked against identities that do not go through the code under
  test: the throat diameter against its area, the c* efficiency against its own breakdown, the
  throat station's recession against the old throat-recession key, the net load against its parts.
* An eroding engine is replayed on the coupled solver only (audit 5.3): a graphite-only engine,
  which used to replay through the legacy loop at zero erosion, now erodes; the legacy path refuses.

The replay here runs on LE4 (``configs/ethalox_6800N.yaml``) at synthetic line-exit pressures
through a minimal stand-in for ``Prepared``: the replay reads only the runner, the as-built
throat, the step and the ambient from it, and a twin burn would cost a minute per test.

Function Documentation

◆ _slab_solver()

test_layerx_hardware._slab_solver ( L = 0.01,
k = 0.5,
rho = 1500.0,
cp = 1200.0,
T0 = 400.0,
dT = 100.0 )
protected
A coupled solver reduced to one wall station: a single constant-property slab whose
temperature is the first Fourier mode of an insulated slab, T0 + dT cos(pi y / L).

Definition at line 242 of file test_layerx_hardware.py.

Referenced by test_insulated_slab_soaks_to_its_stored_heat_on_the_fourier_clock(), and test_soak_dates_a_plateau_when_it_is_reached().

◆ _solve_capturing()

test_layerx_hardware._solve_capturing ( config,
monkeypatch,
** kw )
protected
Run the coupled solver on a short burn and record the geometry each stability call saw.

Definition at line 347 of file test_layerx_hardware.py.

Referenced by test_chug_sees_the_design_point_by_default(), and test_chug_sees_the_eroded_chamber_when_asked().

◆ burn()

test_layerx_hardware.burn ( )

Definition at line 75 of file test_layerx_hardware.py.

References series().

◆ card()

test_layerx_hardware.card ( config)

Definition at line 639 of file test_layerx_hardware.py.

◆ config()

test_layerx_hardware.config ( void )

Definition at line 65 of file test_layerx_hardware.py.

◆ fake_prep()

◆ hardware()

test_layerx_hardware.hardware ( prep,
replayed,
burn )

Definition at line 403 of file test_layerx_hardware.py.

◆ prep()

test_layerx_hardware.prep ( config)

Definition at line 70 of file test_layerx_hardware.py.

References fake_prep().

◆ replayed()

test_layerx_hardware.replayed ( prep,
burn )

Definition at line 80 of file test_layerx_hardware.py.

◆ series()

test_layerx_hardware.series ( int n = 69,
float dt = 0.05,
po = (560.0, 600.0),
pf = (565.0, 605.0) )

◆ test_a_graphite_only_engine_now_erodes()

test_layerx_hardware.test_a_graphite_only_engine_now_erodes ( config,
burn )
Liner off, graphite on: the replay used to pass ``track_ablative_geometry=None``, which the
runner read from the liner alone, and replayed this engine at 0.000 % throat growth.

Definition at line 210 of file test_layerx_hardware.py.

References fake_prep().

◆ test_a_line_exit_replay_ignores_supply_k()

test_layerx_hardware.test_a_line_exit_replay_ignores_supply_k ( config,
burn )
End to end: the replay's chug margin on a design that carries supply_K is the one on the same
design without it (both through the line-exit copy).

Definition at line 625 of file test_layerx_hardware.py.

References fake_prep(), and series().

◆ test_an_untracked_liner_still_erodes()

test_layerx_hardware.test_an_untracked_liner_still_erodes ( config,
burn )

Definition at line 222 of file test_layerx_hardware.py.

References fake_prep().

◆ test_axial_sidecar_is_rows_of_t_by_columns_of_x()

test_layerx_hardware.test_axial_sidecar_is_rows_of_t_by_columns_of_x ( replayed)

Definition at line 181 of file test_layerx_hardware.py.

◆ test_chug_sees_the_design_point_by_default()

test_layerx_hardware.test_chug_sees_the_design_point_by_default ( config,
monkeypatch )
Default off: every step's chug analysis runs on the as-built throat and volume, as it did
before the flag existed (time_varying_solver.py passed self.config).

Definition at line 368 of file test_layerx_hardware.py.

References _solve_capturing().

◆ test_chug_sees_the_eroded_chamber_when_asked()

test_layerx_hardware.test_chug_sees_the_eroded_chamber_when_asked ( config,
monkeypatch )
On: each step's chug loop sees that step's A_t and V, so its L* = V/A_t is the eroded one.

Definition at line 380 of file test_layerx_hardware.py.

References _solve_capturing().

◆ test_contour_as_built_and_eroded()

test_layerx_hardware.test_contour_as_built_and_eroded ( hardware,
replayed,
config )

Definition at line 485 of file test_layerx_hardware.py.

◆ test_cstar_efficiency_is_its_breakdown()

test_layerx_hardware.test_cstar_efficiency_is_its_breakdown ( replayed)
eta_c* = eta_vap * eta_mix * eta_HL (engine/pipeline/combustion_eff.py): the breakdown the
replay keeps must multiply back to the efficiency the chamber solve used.

Definition at line 117 of file test_layerx_hardware.py.

◆ test_drawn_throat_is_the_solvers_throat()

test_layerx_hardware.test_drawn_throat_is_the_solvers_throat ( )
The narrowest drawn wall must be D_t0 + 2 s_throat, the solver's throat: with the insert's
downstream half left as built, the drawing kept the as-built throat while the run reported the
throat area growing (2026-10-03).

Definition at line 717 of file test_layerx_hardware.py.

◆ test_eps_lstar_and_contraction_from_the_areas_by_hand()

test_layerx_hardware.test_eps_lstar_and_contraction_from_the_areas_by_hand ( hardware,
replayed,
config )

Definition at line 421 of file test_layerx_hardware.py.

◆ test_erodes_names_the_engines_with_a_receding_wall()

test_layerx_hardware.test_erodes_names_the_engines_with_a_receding_wall ( config)

Definition at line 201 of file test_layerx_hardware.py.

◆ test_every_kept_array_is_one_value_per_replay_point()

test_layerx_hardware.test_every_kept_array_is_one_value_per_replay_point ( replayed)

Definition at line 101 of file test_layerx_hardware.py.

◆ test_expansion_chamber_follows_enginedesign_at_the_eroded_throat()

test_layerx_hardware.test_expansion_chamber_follows_enginedesign_at_the_eroded_throat ( card,
prep,
replayed )
At the replay's eroded throat and EngineDesign's own flows, the plain card's thrust runs high
(it keeps the as-built eps); the expansion-scaled card closes most of it (audit D4-B).

Definition at line 699 of file test_layerx_hardware.py.

◆ test_expansion_chamber_is_the_card_at_the_as_built_throat()

test_layerx_hardware.test_expansion_chamber_is_the_card_at_the_as_built_throat ( card,
prep )

Definition at line 645 of file test_layerx_hardware.py.

◆ test_expansion_chamber_prices_thrust_on_the_flow_that_burns()

test_layerx_hardware.test_expansion_chamber_prices_thrust_on_the_flow_that_burns ( card,
prep )
Off the card's O/F range the excess propellant passes the throat unburned (CardChamber's
``burning``). With the Cf_vac ratio forced to 1 the expansion chamber must be the card's, at any
throat and any O/F: it priced thrust on the total flow instead (O/F 20 at a 0.1 % larger throat:
2489 N against the card's 0 on LE4 (3)'s card).

Definition at line 679 of file test_layerx_hardware.py.

◆ test_expansion_chamber_scales_vacuum_velocity_by_cf_vac()

test_layerx_hardware.test_expansion_chamber_scales_vacuum_velocity_by_cf_vac ( card,
prep )
Throat 4 % larger in area, exit fixed: v_vac x Cf_vac(eps0/1.04)/Cf_vac(eps0), from the table;
chamber pressure and flows untouched.

Definition at line 660 of file test_layerx_hardware.py.

◆ test_hardware_follows_the_replay_points()

test_layerx_hardware.test_hardware_follows_the_replay_points ( hardware,
replayed )

Definition at line 414 of file test_layerx_hardware.py.

◆ test_hardware_never_raises()

test_layerx_hardware.test_hardware_never_raises ( prep)

Definition at line 584 of file test_layerx_hardware.py.

◆ test_injector_drop_is_line_exit_less_the_dump_and_chamber()

test_layerx_hardware.test_injector_drop_is_line_exit_less_the_dump_and_chamber ( replayed)
dp_injector is below line exit - Pc by exactly the Borda dump EngineDesign keeps at the line
exit: positive, and a few percent of the drop (the 6.8 kN LOX dump is ~26 psi at ~140 psi).

Definition at line 128 of file test_layerx_hardware.py.

◆ test_insert_back_face_with_a_declared_case_is_the_bondline()

test_layerx_hardware.test_insert_back_face_with_a_declared_case_is_the_bondline ( config)
With a case behind the insert the station's back face is the case's outer face; the insert's
own back face is the graphite/case interface. LE4 declares none, where the two are the same node.

Definition at line 462 of file test_layerx_hardware.py.

References fake_prep(), and series().

◆ test_insulated_slab_soaks_to_its_stored_heat_on_the_fourier_clock()

test_layerx_hardware.test_insulated_slab_soaks_to_its_stored_heat_on_the_fourier_clock ( )
Insulated slab, first mode only: T(L, t) = T0 - dT exp(-pi^2 alpha t / L^2) (Carslaw &
Jaeger 1959, ch. III). The back face rises from T0 - dT to T0, reaching 95 % of the rise at
t = ln(20) L^2 / (pi^2 alpha); energy is conserved, so the peak is the capacity-weighted mean.

Definition at line 275 of file test_layerx_hardware.py.

References _slab_solver().

◆ test_isp_ideal_is_cea_by_hand()

test_layerx_hardware.test_isp_ideal_is_cea_by_hand ( hardware,
replayed,
prep )
The ideal is CEA's shifting-equilibrium Isp: checked against rocketcea itself at two points
(vacuum Isp and c* from CEA, less the ambient term p_a eps c*/(Pc g0)), not through the table.

Definition at line 569 of file test_layerx_hardware.py.

◆ test_isp_waterfall_closes_and_its_terms_are_the_thrust_identities()

test_layerx_hardware.test_isp_waterfall_closes_and_its_terms_are_the_thrust_identities ( hardware,
replayed,
prep )

Definition at line 549 of file test_layerx_hardware.py.

◆ test_le4_runs_full_on_the_pad()

test_layerx_hardware.test_le4_runs_full_on_the_pad ( hardware)
Pad, He: p_e/p_a ~1.0-1.1 against Summerfield's 0.4 and Schmucker's ~0.41 (audit 9.2 s5).

Definition at line 538 of file test_layerx_hardware.py.

◆ test_line_exit_drops_the_supply_share_with_k0()

test_layerx_hardware.test_line_exit_drops_the_supply_share_with_k0 ( config)
supply_K is the supply's share of K0. The line exit zeroes K0, so the drop left is the exit
dump alone and holds no supply share; left in, the chug loop subtracted a supply drop from the
dump (audit D7: gate 1.330 -> 1.248 after a feed-fit write, nothing physical changed).

Definition at line 596 of file test_layerx_hardware.py.

◆ test_line_exit_is_unchanged_for_le4()

test_layerx_hardware.test_line_exit_is_unchanged_for_le4 ( config)
LE4 carries supply_K 0, so the D7 fix leaves its line-exit copy (and the baseline) as it was.

Definition at line 615 of file test_layerx_hardware.py.

◆ test_liner_left_and_insert_back_face()

test_layerx_hardware.test_liner_left_and_insert_back_face ( hardware,
replayed,
config )

Definition at line 440 of file test_layerx_hardware.py.

References min.

◆ test_soak_dates_a_plateau_when_it_is_reached()

test_layerx_hardware.test_soak_dates_a_plateau_when_it_is_reached ( )

Definition at line 294 of file test_layerx_hardware.py.

References _slab_solver().

◆ test_soak_on_le4_is_an_adiabatic_upper_bound()

test_layerx_hardware.test_soak_on_le4_is_an_adiabatic_upper_bound ( replayed)

Definition at line 301 of file test_layerx_hardware.py.

References max.

◆ test_soak_refuses_another_replays_walls()

test_layerx_hardware.test_soak_refuses_another_replays_walls ( config)
The runner keeps only its last coupled solve. The soak-back runs on it only when it is the
replay asked about: same end time and same end throat; a replay that ended elsewhere, or at the
same time on another throat (another pass of the same burn), is refused, not soaked.

Definition at line 328 of file test_layerx_hardware.py.

References fake_prep(), and series().

◆ test_soak_window_is_three_conduction_times_of_the_slowest_layer()

test_layerx_hardware.test_soak_window_is_three_conduction_times_of_the_slowest_layer ( replayed,
config )
3 L^2/alpha, alpha = k/(rho cp), L the liner left at the station that receded least
(LE4's 12.7 mm phenolic liner is ~900 s; the 6 mm graphite ~0.4 s).

Definition at line 255 of file test_layerx_hardware.py.

References max, and min.

◆ test_station_loads_are_the_solvers_own_barrel_and_throat_loads()

test_layerx_hardware.test_station_loads_are_the_solvers_own_barrel_and_throat_loads ( replayed)
The station read-out (``_station_report``) against the barrel and throat loads the solver
already reported through its own path (``_wall_report``: q_conv/q_rad/q_chem_throat,
q_conv/q_rad_chamber). The throat is the same quantity both ways. At the barrel the station's
convection is the *blown* one the liner takes, the old key the unblown Bartz value: their ratio
is the pyrolysis-blowing reduction, a little under 1 (0.9931 at t = 0.05 s in audit 9.2).

Definition at line 165 of file test_layerx_hardware.py.

◆ test_stations_carry_recession_temperatures_and_load()

test_layerx_hardware.test_stations_carry_recession_temperatures_and_load ( replayed,
config )

Definition at line 137 of file test_layerx_hardware.py.

◆ test_summary_first_point_is_against_as_built()

test_layerx_hardware.test_summary_first_point_is_against_as_built ( hardware,
replayed )
The first replay point has already eroded (the walls start at Fire): its A_t over as built is
the replay's own throat_area_ratio[0], a little above 1 (audit 9.2: 0.027 % on the He burn).

Definition at line 453 of file test_layerx_hardware.py.

◆ test_summerfield_and_schmucker_by_hand()

test_layerx_hardware.test_summerfield_and_schmucker_by_hand ( )

Definition at line 517 of file test_layerx_hardware.py.

◆ test_the_legacy_path_refuses_an_eroding_engine()

test_layerx_hardware.test_the_legacy_path_refuses_an_eroding_engine ( config)

Definition at line 230 of file test_layerx_hardware.py.

References fake_prep().

◆ test_the_phenolic_backing_cools_the_insert_and_shields_the_case()

test_layerx_hardware.test_the_phenolic_backing_cools_the_insert_and_shields_the_case ( config)
LE4's insert sits in the liner's phenolic out to the 304 case (~46 mm). Over a burn:

* the case stays at ambient: the phenolic's penetration depth sqrt(alpha t) is ~0.7 mm;
* the phenolic still draws ~k dT / sqrt(pi alpha t) ~0.4 MW/m2 from a ~2000 K insert, which a 6 mm
  graphite slab (rho c t ~7.7 kJ/m2K) feels as ~100-200 K over 3 s: the insert runs cooler and its
  throat erodes less than the adiabatic upper bound (no case declared, nothing behind the insert).

Definition at line 737 of file test_layerx_hardware.py.

References fake_prep(), max, and series().

◆ test_the_replay_keeps_its_old_keys()

test_layerx_hardware.test_the_replay_keeps_its_old_keys ( replayed)

Definition at line 90 of file test_layerx_hardware.py.

◆ test_throat_diameter_is_its_area()

test_layerx_hardware.test_throat_diameter_is_its_area ( replayed)

Definition at line 111 of file test_layerx_hardware.py.

Variable Documentation

◆ AMBIENT

float test_layerx_hardware.AMBIENT = 94070.0

Definition at line 35 of file test_layerx_hardware.py.

◆ LE4

str test_layerx_hardware.LE4 = ROOT / "configs" / "ethalox_6800N.yaml"

Definition at line 33 of file test_layerx_hardware.py.

◆ OLD_KEYS

tuple test_layerx_hardware.OLD_KEYS
Initial value:
1= (
2 "available", "t", "index", "inlet_O_psia", "inlet_F_psia", "pc_psia", "thrust_N", "mdot_O", "mdot_F",
3 "mr", "isp_s", "cstar", "eta_cstar", "gamma", "A_throat_m2", "throat_area_ratio", "recession_throat_mm",
4 "recession_chamber_mm", "eps", "p_exit_psia", "t_exit_K", "gamma_exit", "tc_K", "Lstar_m",
5 "heat_flux_throat_MW_m2", "heat_flux_chamber_MW_m2", "T_graphite_surface_K", "T_liner_surface_K",
6 "char_depth_peak_mm", "chug_margin", "throat_ablation", "liner_ablation",
7)

Definition at line 40 of file test_layerx_hardware.py.

◆ PSI

float test_layerx_hardware.PSI = 6894.757293168361

Definition at line 34 of file test_layerx_hardware.py.

◆ pytestmark

test_layerx_hardware.pytestmark = pytest.mark.skipif(not LE4.is_file(), reason="LE4 config (configs/ethalox_6800N.yaml) not in this checkout")

Definition at line 37 of file test_layerx_hardware.py.

◆ ROOT

test_layerx_hardware.ROOT = Path(__file__).resolve().parents[1]

Definition at line 32 of file test_layerx_hardware.py.