33 t = [-0.1, -0.05, 0.0, 0.05, 0.1, 0.15, 0.2, 0.25]
35 fire = [
False,
False,
False,
True,
True,
True,
True,
True]
36 ramp =
lambda a, b: [a + (b - a) * k / (n - 1)
for k
in range(n)]
37 side =
lambda p: {
"tank_psia": ramp(p, p + 3.0),
"stiffness": [0.0] * 3 + [0.31, 0.32, 0.33, 0.34, 0.35],
38 "mdot": [0.0] * 3 + [1.9] * 5,
"liquid_K": [90.1] * n,
"fill_fraction": ramp(0.95, 0.9)}
39 series = {
"t": t,
"dt": [0.05] * n,
"firing": fire,
"converged": [
True] * n,
"copv_psia": ramp(4500.0, 4300.0),
40 "copv_mass_kg": ramp(0.2, 0.19),
"copv_wall_K": [293.15] * n,
41 "regulators": {
"PR_D": {
"label":
"PR-DOME",
"outlet_psia": ramp(578.0, 580.0)}},
42 "instruments": {
"PT_OXU": {
"tag":
"PT-OX-UP",
"type":
"PT",
"unit":
"psia",
"values": ramp(578.0, 579.0)},
43 "TC_OXD": {
"tag":
"TC-OX-DN",
"type":
"TC",
"unit":
"K",
"values": [90.0] * n}},
44 "ox": side(578.0),
"fuel": side(578.1),
45 "chamber": {
"pc_psia": [0.0] * 3 + [395.0, 396.0, 397.0, 398.0, 399.0],
"thrust_N": [0.0] * 3 + [6900.0] * 5,
46 "extrapolated": [0.0] * n}}
47 fire_t = [t[i]
for i
in range(n)
if fire[i]]
50 "delivered": {
"t": fire_t,
"pc_psia": [394.0, 396.5, 397.0, 397.5, 401.25],
"thrust_N": [6800.0, 6950.0, 7000.0, 7100.0, 7250.5],
51 "chug_margin": [1.3, 1.31, 1.32, 1.33, 1.34],
"summary": {
"chug_margin_min": 1.3}},
52 "replay": {
"available":
True,
"t": [0.05, 0.15, 0.25],
"index": [3, 5, 7],
"eta_cstar": [0.91, 0.912, 0.913],
53 "A_throat_m2": [1.79e-3, 1.80e-3, 1.81e-3]},
54 "network": {
"t": t,
"nodes": {
"MF2": {
"label":
"press manifold",
"kind":
"manifold",
"side":
"gas",
55 "p_psia": ramp(580.0, 582.0),
"T_K": ramp(280.0, 270.0)}},
56 "branches": {
"l_ox1": {
"kind":
"line",
"from":
"OXT",
"to":
"MVO",
"side":
"ox",
57 "mdot": [0.0] * 3 + [1.9] * 5,
"dp_psi": [0.0] * 3 + [4.0] * 5},
58 "MVO": {
"kind":
"valve",
"from":
"MVO.in",
"to":
"MVO.out",
"side":
"ox",
59 "mdot": [0.0] * 3 + [1.9] * 5,
"dp_psi": [0.0] * 3 + [1.2] * 5,
60 "state": [0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0],
"cv": 26.1}}},
62 "regulator": {
"t": t,
"inlet_psia": ramp(4500.0, 4300.0),
"wide_open": [
False] * n,
"cv": 0.8,
63 "model": {
"name":
"x",
"inputs": {
"a": {
"value": 1.0}}}},
64 "ladder": {
"t": t,
"ox": {
"elements": [{
"id":
"MVO",
"label":
"LOX main",
"kind":
"valve",
65 "dp_psi": [0.0] * 3 + [1.2] * 5,
"share": [0.0] * 3 + [0.01] * 5}],
66 "total_psi": [0.0] * 3 + [180.0] * 5}},
67 "stability": {
"basis":
"config",
"t": [0.05, 0.15, 0.25],
"index": [3, 5, 7],
"margin": [1.3, 1.35, 1.4],
68 "worst": {
"t": 0.05,
"margin": 1.3},
69 "nyquist": {
"t": 0.05,
"omega": [1.0, 2.0, 3.0],
"re": [0.1, 0.2, 0.3],
"im": [0.0, 0.1, 0.2]}},
70 "hardware": {
"t": [0.05, 0.25],
"throat_d_mm": [47.81, 48.72],
71 "separation": {
"ratio": [1.1, 1.05],
"summerfield": [
False,
False]},
72 "contour": {
"x_mm": [0.0, 1.0, 2.0],
"frames": {
"t": [0.05],
"r_mm": [[1.0, 2.0, 3.0]]}}},
73 "start": {
"t": [0.0, 0.001, 0.002],
"pc_psia": [14.7, 50.0, 120.0]},
74 "vv": {
"mass": {
"ox": {
"error_pct": 0.0}}},
76 "provenance": {
"config_sha256":
"abc",
"drawing": {
"name":
"copv_study_he",
"sha256":
"def"}},
169 pq = pytest.importorskip(
"pyarrow.parquet")
171 table = pq.read_table(io.BytesIO(to_parquet(r)))
172 back = read_csv(to_csv(r))
173 assert table.column_names == list(back)
174 for name
in table.column_names:
175 assert table.column(name).to_pylist() == back[name][1], name
176 assert table.schema.field(name).metadata[b
"unit"].
decode() == back[name][0]
177 meta = table.schema.metadata
178 assert meta[b
"config_sha256"] == b
"abc"
179 assert "diagnostics.start" in json.loads(meta[b
"columns_skipped"])
191 return {
"x_mm": [0.0, 40.0, 80.0],
"t": [0.05, 0.25],
192 "q_MW_m2": [[1.0, 8.0, 3.0], [1.5, 9.5, 2.0]],
"T_wall_K": [[600.0, 1800.0, 900.0], [800.0, 2300.0, 950.0]],
193 "basis":
"test stations",
194 "profile": {
"x_mm": [0.0, 50.0],
"q_MW_m2": [[1.0, 2.0], [1.1, 2.1]]}}
200 z = zipfile.ZipFile(io.BytesIO(blob))
201 assert {
"pc_t.csv",
"thrust_t.csv",
"heatflux_xt.csv",
"loads.json",
"README.txt"} <= set(z.namelist())
202 pc = read_csv(z.read(
"pc_t.csv").
decode())
203 assert pc[
"pc_psia"][0] ==
"psia" and pc[
"pc_psia"][1] == r[
"delivered"][
"pc_psia"]
204 assert pc[
"t"][1] == r[
"delivered"][
"t"]
205 assert pc[
"pc_Pa"][0] ==
"Pa" and pc[
"pc_Pa"][1][-1] == pytest.approx(401.25 * PSI, rel=1e-15)
206 thrust = read_csv(z.read(
"thrust_t.csv").
decode())
207 assert thrust[
"thrust_N"][1] == r[
"delivered"][
"thrust_N"]
208 loads = json.loads(z.read(
"loads.json"))
209 assert loads[
"chamber_pressure"][
"peak"] == {
"value": 401.25,
"t": 0.25,
"value_Pa": 401.25 * PSI}
210 assert loads[
"thrust"][
"peak"][
"value"] == 7250.5
and "erosion replay" in loads[
"thrust"][
"source"]
211 assert loads[
"tank_pressure"][
"ox"][
"value"] ==
max(r[
"series"][
"ox"][
"tank_psia"])
212 assert loads[
"bottle_pressure"][
"value"] == 4500.0
213 assert loads[
"heat_flux"][
"peak"] == {
"value": 9.5,
"t": 0.25,
"x_mm": 40.0}
214 assert loads[
"wall_temperature"][
"peak"][
"value"] == 2300.0
215 heat = read_csv(z.read(
"heatflux_xt.csv").
decode())
216 assert len(heat[
"t"][1]) == 2 * 3
217 assert heat[
"q_MW_m2"][1] == [1.0, 8.0, 3.0, 1.5, 9.5, 2.0]
and heat[
"x_mm"][0] ==
"mm"
218 assert heat[
"T_wall_K"][1][4] == 2300.0
and heat[
"t"][1] == [0.05] * 3 + [0.25] * 3
219 assert "heatflux_profile_xt.csv" in z.namelist()
220 readme = z.read(
"README.txt").
decode()
221 assert "psia" in readme
and "MW/m^2" in readme
and "from the Fire command" in readme
222 assert blob == fea_bundle(r,
_sidecar()),
"the same run must zip to the same bytes"