58 design = R._forward(config, P_TANK, AMBIENT)
59 d, point, _ = R._solve_holes(config,
_lengths(config), (design[
"thrust_N"], design[
"of"]), P_TANK, AMBIENT)
61 assert d[side] == pytest.approx(getattr(config.injector.geometry, side).d_jet, rel=1e-5)
66 design = R._forward(config, P_TANK, AMBIENT)
67 lossy =
_feed(config, (1.27, 2.86))
68 before = R._forward(lossy, P_TANK, AMBIENT)
69 assert before[
"thrust_N"] < design[
"thrust_N"] - 100.0
70 d, point, _ = R._solve_holes(lossy, lengths, (design[
"thrust_N"], design[
"of"]), P_TANK, AMBIENT)
71 assert point[
"thrust_N"] == pytest.approx(design[
"thrust_N"], rel=1e-3)
72 assert point[
"of"] == pytest.approx(design[
"of"], rel=1e-3)
74 old =
PintleEngineRunner(copy.deepcopy(config)).evaluate(P_TANK, P_TANK, P_ambient=AMBIENT, silent=
True)
75 new =
PintleEngineRunner(R._with_holes(lossy, d, lengths)).evaluate(P_TANK, P_TANK, P_ambient=AMBIENT, silent=
True)
76 for side, k
in ((
"oxidizer",
"O"), (
"fuel",
"F")):
77 assert new[f
"mdot_{k}"] == pytest.approx(old[f
"mdot_{k}"], rel=2e-3)
78 dp_old = old[
"injector_pressure"][f
"delta_p_injector_{k}"]
79 dp_new = new[
"injector_pressure"][f
"delta_p_injector_{k}"]
80 expected = (new[f
"mdot_{k}"] / old[f
"mdot_{k}"]) * (old[f
"Cd_{k}"] / new[f
"Cd_{k}"]) * math.sqrt(dp_old / dp_new)
81 got = (d[side] / getattr(config.injector.geometry, side).d_jet) ** 2
82 assert got == pytest.approx(expected, rel=5e-3), side
84 assert new_lod(lossy, d, lengths, side) * d[side] == pytest.approx(lengths[side], rel=1e-9)
93 design = R._forward(config, P_TANK, AMBIENT)
94 light =
_feed(config, (0.2, 1.0))
95 d, _, _ = R._solve_holes(light, lengths, (design[
"thrust_N"], design[
"of"]), P_TANK, AMBIENT)
96 rows = R._changes(config, R._with_holes(light, d, lengths), lengths)
97 holes = [r
for r
in rows
if r[
"item"].endswith(
"orifice diameter")]
98 assert all(r[
"to"] < r[
"from"]
for r
in holes)
99 assert all(r[
"fabrication"].startswith(
"new plate")
for r
in holes)
102@pytest.mark.parametrize("no, inch", [(51, 0.0670), (53, 0.0595), (60, 0.0400)])
125 drawing = {d.name: d
for d
in DrawingStore(
None).list()}[GN2]
126 settings =
LayerXSettings(drawing_id=drawing.id, tank_pressure_psia=STUDY_LOCKUP_PSIA, ack_gn2_condensation=
True, replay=
False)
127 res = R.run_reconcile(config, drawing, settings, [], R.ReconcileRequest(max_passes=4))
128 assert res[
"converged"]
129 target = res[
"design"][
"thrust_N"]
133 assert res[
"before_burn"][
"mean_thrust_N"] < 0.985 * target
134 assert res[
"after_burn"][
"mean_thrust_N"] == pytest.approx(target, rel=3e-3)
135 assert res[
"after"][
"thrust_N"] == pytest.approx(target, rel=1e-3)
136 assert abs(res[
"after_burn"][
"of_mean"] - res[
"design"][
"of"]) < abs(res[
"before_burn"][
"of_mean"] - res[
"design"][
"of"])
137 upd = res[
"design_update"]
138 assert set(upd) >= {
"injector",
"feed_system",
"discharge"}
139 assert upd[
"feed_system"][
"oxidizer"][
"derived_from"][
"by"] ==
"Layer X injector reconcile"