STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
feedtwin.session.burn Namespace Reference

Classes

class  BurnPlan
class  T0
class  BurnTrip
class  BurnEnd
class  Probes
class  BurnTrace

Functions

Setup burn_setup (**Any changes)
Session open_session (Model model, StateMachine machine, *, Setup|None setup=None, Hookup|None hookup=None)
list[str] press_valves (Session session)
bool prime_at_t0 (Session session, BurnPlan plan)
float|None regulator_lockup (Session session, str tank_id, float|None inlet=None, *, bool loaded_dome=False, bool place=False)
tuple[float, str] reachable_lockup (Session session, float lockup)
T0 jump_to_t0 (Session session, *, float copv_psi, float fill_fraction, float hold_s=PAD_HOLD_S, str ready_state="Ready", float fallback_psi=550.0, Mapping[str, float]|None loads=None)
BurnEnd burn (Session session, BurnPlan plan, Recorder record, *, Callable[[], bool] cancelled=lambda:False)
Probes find_probes (Session session)
BurnTrace run_burn (Session session, BurnPlan plan, *, Callable[[], bool] cancelled=lambda:False, Recorder|None also=None, bool network=False)
dict[str, Any] network_dict (BurnTrace trace)
dict[str, Any]|None trip_record (BurnTrace trace)
BurnPlan plan_with (BurnPlan plan, **Any changes)

Variables

 Recorder = Callable[[float, Sample, bool], None]
str OPENED = "session_opened"
tuple TANK_FIELDS
dict[str, Any] network_record = network_dict

Detailed Description

A burn, from T-0 to a dry tank, as one call.

The feed-twin COPV study was the first thing to fly a whole burn headless: build
a session, put it at T-0 directly, settle it to regulator lockup with the mains
shut, record a lead-in, command Fire and step until a tank runs dry. That
sequence lives here now, unchanged, so the study and EngineDesign's Layer X
burn the same way -- and a number either of them quotes means the same thing.

What this is not
----------------
It is not a rehearsal of the pad. :func:`prime_at_t0` sets the T-0 state
directly rather than flying fills and presses, because pressing the tanks draws
on the bottle a burn is usually asked about: an undersized COPV would then fail
for two reasons at once and the trace could not say which. See
:meth:`~feedtwin.session.core.Session.prime`.

Numerics
--------
:func:`burn_setup` is the study's setting: no latency budget, a generous Newton
allowance, and the cockpit's newer thermal closures (stratified surface layer,
boiling onset, nucleate regime) off, because the expectations in
``docs/PHYSICS-BENCHMARK.md`` 2.x were set without them. Turn them on
deliberately, with a fresh baseline.

Function Documentation

◆ burn()

BurnEnd feedtwin.session.burn.burn ( Session session,
BurnPlan plan,
Recorder record,
* ,
Callable[[], bool] cancelled = lambda: False )
Lead-in, then Fire until a tank runs dry, a vessel trips, or the horizon
passes.

The clock reads seconds from the Fire command: negative through the
lead-in, zero at ignition. ``record`` sees every step, the one that trips
included; nothing after it. A tripped session returns its frozen frame on
every later step (:meth:`Session.step`), so carrying on to the horizon would
integrate one instant's thrust for the rest of the burn -- 99,478 N.s
instead of ~24,000 on the LE4 audit's restated fuel tank (AUDIT.md 5.2).

Definition at line 557 of file burn.py.

References max, and record().

◆ burn_setup()

Setup feedtwin.session.burn.burn_setup ( **Any changes)
The study's numerics, with ``changes`` on top.

A study wants the opposite of a cockpit: never fold a tick to save wall
clock, and give Newton room. The thermal closures the cockpit grew after the
benchmark expectations were set stay off, so those numbers keep meaning what
they meant.

Definition at line 45 of file burn.py.

◆ find_probes()

Probes feedtwin.session.burn.find_probes ( Session session)
Read the probe points off a built session.

Definition at line 720 of file burn.py.

Referenced by run_burn().

◆ jump_to_t0()

T0 feedtwin.session.burn.jump_to_t0 ( Session session,
* ,
float copv_psi,
float fill_fraction,
float hold_s = PAD_HOLD_S,
str ready_state = "Ready",
float fallback_psi = 550.0,
Mapping[str, float] | None loads = None )
The cockpit's shortcut past the pad: loaded, charged, pressed, in Ready.

The initial condition the study and Layer X burn from
(:meth:`Session.prime`: tanks loaded to ``fill_fraction``, a LOX wall
chilled by ``hold_s`` on the pad, the bottle at ``copv_psi``), with the
tanks at the lockup *this stand's regulators* give at the knobs as they
are set (:func:`regulator_lockup`), not at a number chosen here. Ready
shuts the press valves, as the table has it; what the tanks then do while
the stand waits for Fire is the stand's own physics.

Nothing about the stand changes: the knobs, the settings and the drawing
stay as they are. The pad itself (fills, chilldown, presses) is skipped,
which is the point; fly it from Idle for the transients it carries.
Tanks fed by regulators that lock up at different pressures are primed at
the lowest of them and the note says so. Never above the bottle nor below
atmosphere (:func:`reachable_lockup`): a bottle under the lockup leaves
the regulator wide open, and a lockup under the air is a shut regulator.

The tanks hold what a fire is loaded with: ``loads`` [kg] per tank, or the
engine's fire load (:meth:`Session.fire_loads`) -- never a fraction of the
tank drawn, which on LE4 (6) is a third more LOX than the vehicle carries.
``fill_fraction`` is for a tank neither names.

Definition at line 404 of file burn.py.

References max, min, reachable_lockup(), and regulator_lockup().

◆ network_dict()

dict[str, Any] feedtwin.session.burn.network_dict ( BurnTrace trace)
The trace's network as the Layer X result's ``network`` block
(EngineDesign/docs/layerx/DATA-CONTRACT.md section 2).

Pressures psia (absolute), drops psi, temperatures K, flows kg/s, on the
trace's own clock. Node values are the step's last network solve -- a vessel
node is the boundary that solve used, not the post-step vessel state (the
block's ``basis`` says so). A burn recorded without :attr:`Probes.network`
gives ``{"available": False, "error": ...}`` rather than raising.

Definition at line 925 of file burn.py.

◆ open_session()

Session feedtwin.session.burn.open_session ( Model model,
StateMachine machine,
* ,
Setup | None setup = None,
Hookup | None hookup = None )
A session on ``model``, its valves bound to ``machine`` by label.

A model is consumed by the session that runs it: the session writes node
pressures, the pinned chamber node and propagated temperatures into the
model's network as it steps. A second session on the same model starts from
the first one's end state, and on an engine-coupled stand that is a chamber
closure that fails from the first fire step (41 of 51 steps held, measured).
So this refuses a model it has already opened. Assemble a fresh one per run
(:func:`~feedtwin.session.model.assemble_model` is cheap).

Definition at line 80 of file burn.py.

◆ plan_with()

BurnPlan feedtwin.session.burn.plan_with ( BurnPlan plan,
**Any changes )
``plan`` with ``changes``. A frozen dataclass rebuilt with ``replace``,
so a field added later is carried rather than dropped.

Definition at line 968 of file burn.py.

◆ press_valves()

list[str] feedtwin.session.burn.press_valves ( Session session)
Drawing ids of the valves that press the propellant tanks.

The table's press actuators, minus the fill and GSE lines that share the
word. In ``Ready`` the table shuts them, so a tank whose ullage is
collapsing drifts below lockup while it waits -- physical, and what an
operator tops up before going to Ready. A burn wants the tank *at* lockup at
T-0, so the settle holds these open and releases them after.

Definition at line 176 of file burn.py.

Referenced by prime_at_t0().

◆ prime_at_t0()

bool feedtwin.session.burn.prime_at_t0 ( Session session,
BurnPlan plan )
Put the session at T-0: loaded, at lockup, bottle charged, mains shut.

Returns whether the settle converged. When it did not, the session's
assumptions say by how much, because a trace that opens off its datum reads
as a violent drop-and-recovery at ignition.

Definition at line 194 of file burn.py.

References max, min, press_valves(), reachable_lockup(), and regulator_lockup().

Referenced by run_burn().

◆ reachable_lockup()

tuple[float, str] feedtwin.session.burn.reachable_lockup ( Session session,
float lockup )
Where tanks pressed toward ``lockup`` [Pa abs] off the vehicle's bottle
land, and a note when that is not ``lockup`` (empty when it is).

:func:`regulator_lockup` is the regulator's law at zero flow, dome + bias
- S x inlet, and nothing in that law stops at the inlet. A regulator
delivers no more than its inlet: with the bottle under the lockup it stands
wide open and the tanks end at the bottle (T-0 primed LE4 (3) at 579 psig
off a 400 psig COPV). Nor does it pull a vacuum: a lockup under atmosphere
-- a dome turned to zero against the supply effect -- is a shut regulator,
and the tanks stay at atmosphere (it primed them at 9.6 psia).

Definition at line 353 of file burn.py.

References max.

Referenced by jump_to_t0(), and prime_at_t0().

◆ regulator_lockup()

float | None feedtwin.session.burn.regulator_lockup ( Session session,
str tank_id,
float | None inlet = None,
* ,
bool loaded_dome = False,
bool place = False )
Where the regulator feeding ``tank_id`` locks up, right now [Pa abs].

``inlet`` [Pa abs]: where it would lock up with the bottle at this
pressure instead -- a charged COPV, or an empty one, to show the range a
tank sees as the bottle blows down. Default: the bottle as it is.
``loaded_dome``: with the dome as its knob sets it, though the dome line
is shut (:meth:`Session.peek_signals`).

Moves nothing, unless ``place``: T-0 has always evaluated it through the
step's :meth:`Session.signals`, which also put each valve where the state
commands it and took the dome as it stands -- what a stand put at T-0
starts from. Its two callers there keep that, so burns are unchanged.

Walks upstream from the tank's ullage to the first regulator in the
network (dome loaders are lifted out of it, so this is the unit that
presses the tank), then evaluates its own law at zero flow: the session's
knob and dome signals, and the bottle behind it at its present pressure,
which is what the supply-pressure effect reads. ``None`` when no regulator
feeds the tank -- a stand pressed straight off a bottle has no lockup.

Definition at line 275 of file burn.py.

References max.

Referenced by jump_to_t0(), and prime_at_t0().

◆ run_burn()

BurnTrace feedtwin.session.burn.run_burn ( Session session,
BurnPlan plan,
* ,
Callable[[], bool] cancelled = lambda: False,
Recorder | None also = None,
bool network = False )
Prime, settle, burn, and return the whole trace.

``also`` is called alongside the trace's own recorder -- for progress, or a
caller that wants its own columns. ``network`` records the whole network
as well (:attr:`Probes.network`); off, the trace is what it always was.

Definition at line 894 of file burn.py.

References find_probes(), and prime_at_t0().

◆ trip_record()

dict[str, Any] | None feedtwin.session.burn.trip_record ( BurnTrace trace)
The Layer X result's ``tripped`` block, or ``None`` when nothing tripped.

``{vessel, label, kind, t, p_psia, mawp_psia, message}``: absolute psia, on
the trace's clock. ``mawp_psia`` is the pressure the stand trips at, which is
the drawing's MAWP or its burst pressure over the safety factor.

Definition at line 947 of file burn.py.

Variable Documentation

◆ network_record

dict[str, Any] feedtwin.session.burn.network_record = network_dict

Definition at line 944 of file burn.py.

◆ OPENED

str feedtwin.session.burn.OPENED = "session_opened"

Definition at line 77 of file burn.py.

◆ Recorder

feedtwin.session.burn.Recorder = Callable[[float, Sample, bool], None]

Definition at line 42 of file burn.py.

◆ TANK_FIELDS

tuple feedtwin.session.burn.TANK_FIELDS
Initial value:
1= (
2 "liquid_mass_kg",
3 "ullage_temperature_K",
4 "liquid_temperature_K",
5 "fill_fraction",
6 "wall_temperature_K",
7 "surface_temperature_K",
8)

Definition at line 767 of file burn.py.