STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
test_pages_and_mates.py
Go to the documentation of this file.
1"""A drawing on two pages, joined where the stand joins: a mated disconnect.
2
3pid-designer draws the vehicle and the GSE cart on separate pages and has no
4off-page connector; the coupling between them is a quick-disconnect on each page,
5paired through ``options.pairedWith``. Read page-blind, the two halves each had a
6free side and the cart could not feed the vehicle. Mated (``_mate_disconnects``),
7their free sides are one place.
8
9Checked by flow: gas from a cart bottle on the GSE page reaches a vent on the
10vehicle page only through the pair, and a drawing that pairs nothing builds
11exactly as before.
12"""
13
14from __future__ import annotations
15
16from typing import Any
17
18import pytest
19from test_pid_drawn_freely import P, line, node
20
21from feedtwin.pid import build_network, read_diagram
22from feedtwin.solve.steady import solve_steady
23
24
25def _two_pages(pair: str = "both") -> Any:
26 """Cart bottle -> QD-G (page GSE) || QD-R -> vent (page Main)."""
27 cart = node(
28 "BANK",
29 "KBOTTLE",
30 "BANK-1",
31 page="GSE",
32 fluidType="nitrogen",
33 params={"pressure": P(300, "psi"), "temperature": P(293, "K")},
34 )
35 qd_g = node("QG", "QD", "QD-GSE", page="GSE", params={"Cv": P(2.0, "Cv")})
36 qd_r = node("QR", "QD", "QD-VEH", page="Main", params={"Cv": P(2.0, "Cv")})
37 vent = node("V", "VENT", "VENT-1", page="Main")
38 if pair in ("both", "gse"):
39 qd_g["data"]["options"] = {"pairedWith": "QR"} # type: ignore[index]
40 if pair in ("both", "vehicle"):
41 qd_r["data"]["options"] = {"pairedWith": "QG"} # type: ignore[index]
42 return {
43 "nodes": [cart, qd_g, qd_r, vent],
44 "edges": [line("b-g", "BANK", "QG"), line("r-v", "QR", "V")],
45 }
46
47
48def _flow(payload: Any) -> tuple[float, Any]:
49 built = build_network(read_diagram(payload, name="two pages"))
50 result = solve_steady(built.network)
51 assert result.converged
52 return result.flows.get("r-v", 0.0), built
53
54
55@pytest.mark.parametrize("pair", ["both", "gse", "vehicle"])
57 flow, built = _flow(_two_pages(pair))
58 assert flow > 0.01, "the cart's gas reaches the vehicle's vent through the pair"
59 assert built.mated == (("QG", "QR"),)
60 assert any("joining pages GSE and Main" in w for w in built.warnings)
61
62
64 """The test can fail: without the pairing nothing crosses."""
65 flow, built = _flow(_two_pages("none"))
66 assert abs(flow) < 1e-9
67 assert built.mated == ()
68
69
71 payload = _two_pages("none")
72 a = build_network(read_diagram(payload, name="x"))
73 for n in payload["nodes"]:
74 n["data"].pop("page", None)
75 b = build_network(read_diagram(payload, name="x"))
76 assert sorted(a.network.branches) == sorted(b.network.branches)
77 assert sorted(a.network.nodes) == sorted(b.network.nodes)
78
79
81 payload = _two_pages("both")
82 payload["nodes"].append(node("Q3", "QD", "QD-3", page="GSE"))
83 payload["nodes"][2]["data"]["options"] = {"pairedWith": "Q3"}
84 flow, built = _flow(payload)
85 assert built.mated == ()
86 assert any("left unmated" in w for w in built.warnings)
87
88
90 """LE4's layout plus its cart on a GSE page: a bank bottle, the table's own
91 `GSE High Press Control` valve, and a paired disconnect onto the COPV. In GN2
92 High Press the bank charges the COPV through the drawing, and the session's
93 built-in charge (which stands in for an undrawn cart) is off -- or the bottle
94 would be filled twice."""
95 from test_pid_drawn_freely import _le4_like, _machine
96
97 from feedtwin.session import Session, assemble_model
98 from feedtwin.session.hookup import binding
99
100 payload: Any = _le4_like()
101 payload["nodes"] += [
102 node(
103 "BANK",
104 "KBOTTLE",
105 "BANK-1",
106 page="GSE",
107 fluid="nitrogen",
108 params={
109 "pressure": P(4500, "psi"),
110 "temperature": P(293, "K"),
111 "volume": P(50, "L"),
112 },
113 ),
114 node(
115 "HPC",
116 "SOL",
117 "GSE High Press Control",
118 page="GSE",
119 params={"Cv": P(0.3, "Cv")},
120 ),
121 node("QG", "QD", "QD-CART", page="GSE", options={"pairedWith": "QV"}),
122 node("QV", "QD", "QD-COPV", page="Main"),
123 ]
124 payload["edges"] += [
125 line("bank-hpc", "BANK", "HPC"),
126 line("hpc-qg", "HPC", "QG"),
127 line("qv-kb", "QV", "KB"),
128 ]
129 model = assemble_model(read_diagram(payload, name="le4+cart"), diagram_id="x")
130 machine = _machine()
131 session = Session(model, machine, binding(model, machine, None))
132 assert session.binding.to_symbol.get("GSE High Press Control") == "HPC"
133 assert any("charged through the drawing" in a for a in session.assumptions)
134
135 session.prime(tank_psi=0.0, copv_psi=1000.0, state="Idle", hold_s=1.0)
136 bank = session.bottles["BANK"] # prime sets every bottle; the cart's is full
137 bank.state = bank.volume.initial_state(
138 pressure=4500 * 6894.757 + 101325.0, temperature=293.15
139 )
140 session.state = "GN2 High Press"
141 copv = session.bottles["KB"]
142 start = copv.pressure
143 for _ in range(100):
144 session.step(0.05)
145 assert not copv.filling, "the built-in charge stands aside"
146 assert copv.pressure > start + 200 * 6894.757, "the drawn cart charged it"
147 assert session.bottles["BANK"].pressure < 4500 * 6894.757 + 101325.0
148
149
151 """A pair a drawn line already joins (LE4's HP-QD-A and HP-QD-B): coupled on
152 the page, as pid-designer reads it, with nothing to say. The twin found no
153 free side to mate and warned the pair was left unmated."""
154 payload = _two_pages("both")
155 payload["edges"].append(line("g-r", "QG", "QR"))
156 flow, built = _flow(payload)
157 assert flow > 0.01, "the cart reaches the vent through the drawn line"
158 assert not [w for w in built.warnings if "unmated" in w], built.warnings
Any _two_pages(str pair="both")
None test_a_drawing_that_pairs_nothing_builds_as_before()
None test_halves_joined_by_their_own_line_are_coupled_and_nothing_is_said()
tuple[float, Any] _flow(Any payload)
None test_a_cart_drawn_on_the_gse_page_charges_the_copv_itself()
None test_unpaired_the_two_pages_are_two_systems()
None test_halves_naming_different_partners_are_left_apart_and_said_so()
None test_a_paired_disconnect_joins_the_cart_page_to_the_vehicle_page(str pair)