29 monkeypatch: pytest.MonkeyPatch,
33 pressures: float = 1.0,
35 """Every solve from here fails, its flows and free pressures scaled."""
36 nodes = session.model.built.network.nodes
37 real = core.solve_steady
39 def failed(*args: Any, **kwargs: Any) -> Any:
40 result = real(*args, **kwargs)
44 flows={b: f * flows
for b, f
in result.flows.items()},
46 n: p
if nodes[n].is_fixed
else p * pressures
47 for n, p
in result.pressures.items()
51 monkeypatch.setattr(core,
"solve_steady", failed)
55 monkeypatch: pytest.MonkeyPatch,
57 """Ready -> Fire is a new circuit: the last flows are dropped, and a solve
58 that then fails has nothing converged to hold. The tanks stay put."""
59 session = _helium_stand()
62 liquid = {k: sim.state.liquid_mass
for k, sim
in session.tanks.items()}
63 gas = {k: b.state.mass
for k, b
in session.bottles.items()}
65 _break(monkeypatch, session, flows=50.0)
66 session.set_valve(
"FM",
True)
67 session.set_valve(
"OM",
True)
68 sample = session.step(0.02)
70 assert not sample.converged
71 assert "FM" not in session._last_isolated,
"the mains opened: a new circuit"
72 for k, sim
in session.tanks.items():
74 assert sim.state.liquid_mass == pytest.approx(liquid[k], abs=1e-4), k
75 for k, bottle
in session.bottles.items():
76 assert bottle.state.mass == pytest.approx(gas[k], abs=1e-9), k
77 assert session.solver_log[-1].mass_error_kg == pytest.approx(0.0, abs=1e-9)
83 assert session.history[-1].converged
84 for k, sim
in session.tanks.items():
85 assert sim.state.liquid_mass < liquid[k] - 1e-3, k
89 monkeypatch: pytest.MonkeyPatch,
91 """With a good solve behind it a failed tick holds that solve's flows, and
92 its pressures with them -- into the tank's supply clip, the frame, and the
93 value a trapped leg will later be held at."""
94 session = _helium_stand()
95 session.set_valve(
"FP",
True)
96 session.set_valve(
"OP",
True)
99 assert session.history[-1].converged
100 manifold = session.history[-1].pressures[
"MF"]
102 acted: list[float] = []
103 real_move = session._move_vessels
105 def spy(flows, pressures, *rest):
106 acted.append(pressures[
"MF"])
107 return real_move(flows, pressures, *rest)
109 monkeypatch.setattr(session,
"_move_vessels", spy)
110 _break(monkeypatch, session, pressures=3.0)
111 sample = session.step(0.02)
113 assert not sample.converged
114 assert acted
and all(p == pytest.approx(manifold, rel=1e-12)
for p
in acted)
115 assert sample.pressures[
"MF"] == pytest.approx(manifold, rel=1e-12)
116 assert session._trapped[
"MF"] == pytest.approx(manifold, rel=1e-12)