1"""Layer X burns the vehicle, not the GSE drawn beside it (engine/layerx/vehicle.py).
3LE4 (6) drew the rocket on one page and the GSE on another, joined only by quick-disconnects paired
4across the pages. Layer X then found two ethanol tanks (the vehicle's and the GSE transfer tank),
5swapped the GSE K-bottles to helium along with the COPV, and -- with the GSE dome regulator mated
6to the vehicle's dome line -- tripped the LOX tank before T-0. These pin the cut on a small drawing
7of the same shape, and that a one-piece drawing is untouched.
10from __future__
import annotations
16pytest.importorskip(
"feedtwin", reason=
"lib/feedtwin is not installed")
19def _node(nid, typ, label, page, fluid=None, **params):
20 data = {
"componentType": typ,
"label": label,
"page": page,
"options": {},
"params": {
21 k: {
"value": v[0],
"unit": v[1],
"source":
"estimated"}
for k, v
in params.items()}}
24 return {
"id": nid,
"type": typ,
"position": {
"x": 0,
"y": 0},
"data": data}
28 return {
"id": f
"{a}-{b}",
"source": a,
"target": b,
"data": {}}
33 _node(
"eng",
"ENGINE",
"ENG-1",
"Rocket"),
34 _node(
"copv",
"KBOTTLE",
"COPV",
"Rocket",
"nitrogen", pressure=(4000,
"psi"), volume=(4.69,
"L")),
35 _node(
"reg",
"PR",
"DPR",
"Rocket"),
36 _node(
"fut",
"TANK",
"Eth-Tank",
"Rocket",
"ethanol", volume=(8.19,
"L")),
37 _node(
"oxt",
"TANK",
"LOX-Tank",
"Rocket",
"oxygen", volume=(8.19,
"L")),
38 _node(
"fm",
"ROT",
"FM",
"Rocket"),
39 _node(
"om",
"ROT",
"OM",
"Rocket"),
40 _node(
"qv",
"QD",
"QD-FF-B",
"Rocket"),
41 _node(
"rtd",
"RTD",
"OX-RTD",
"Rocket"),
43 _node(
"qg",
"QD",
"QD-FF-A",
"GSE"),
44 _node(
"xfer",
"TANK",
"Fuel Transfer Tank",
"GSE",
"ethanol", volume=(20,
"L")),
45 _node(
"k6",
"KBOTTLE",
"6K-GN2",
"GSE",
"nitrogen", pressure=(6000,
"psi"), volume=(49,
"L")),
47 by = {n[
"id"]: n
for n
in nodes}
48 by[
"qv"][
"data"][
"options"][
"pairedWith"] =
"qg"
49 by[
"rtd"][
"data"][
"attachedTo"] =
"oxt"
50 edges = [
_edge(
"copv",
"reg"),
_edge(
"reg",
"fut"),
_edge(
"reg",
"oxt"),
_edge(
"fut",
"fm"),
_edge(
"fm",
"eng"),
52 return {
"nodes": nodes,
"edges": edges}
61 assert {
"eng",
"copv",
"reg",
"fut",
"oxt",
"fm",
"om",
"qv",
"rtd"} <= v
62 assert not v & {
"qg",
"xfer",
"k6"}
69 cut, ground = vehicle_payload(payload)
70 ids = {n[
"id"]
for n
in cut[
"nodes"]}
71 assert "xfer" not in ids
and "k6" not in ids
and "qg" not in ids
72 assert sorted(ground) == [
"6K-GN2",
"Fuel Transfer Tank"]
73 assert next(n
for n
in cut[
"nodes"]
if n[
"id"] ==
"qv")[
"data"][
"options"][
"pairedWith"] ==
""
74 assert all(e[
"source"]
in ids
and e[
"target"]
in ids
for e
in cut[
"edges"])
76 assert next(n
for n
in payload[
"nodes"]
if n[
"id"] ==
"qv")[
"data"][
"options"][
"pairedWith"] ==
"qg"
83 payload[
"edges"].append(
_edge(
"qv",
"qg"))
84 same, ground = vehicle_payload(payload)
85 assert same
is payload
and ground == []
92 fluid = {nd[
"id"]: nd[
"data"].get(
"fluid")
for nd
in out[
"nodes"]}
93 assert was ==
"nitrogen" and n == 1
94 assert fluid[
"copv"] ==
"helium" and fluid[
"k6"] ==
"nitrogen"
101 assert [t[
"label"]
for t
in s[
"tanks"]] == [
"Eth-Tank",
"LOX-Tank"]
102 assert [b[
"label"]
for b
in s[
"bottles"]] == [
"COPV"]
103 assert {g[
"label"]
for g
in s[
"ground_support"]} == {
"Fuel Transfer Tank",
"6K-GN2"}
_node(nid, typ, label, page, fluid=None, **params)
test_helium_swaps_only_the_vehicle_bottle()
test_the_summary_lists_the_vehicle_and_the_gse_apart()
test_the_vehicle_is_what_lines_join_to_the_engine()
test_a_one_piece_drawing_comes_back_untouched()
test_the_cut_drops_the_gse_and_caps_the_vehicle_half()