STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
engine.layerx.prepare Namespace Reference

Classes

class  LayerXSettings
class  Check
class  Prepared

Functions

LayerXSettings at_operating_point (LayerXSettings settings, *, Optional[float] lockup_psia=None, Optional[float] fill_psig=None)
Tuple[Optional[float], Optional[float]] _outlet_pair (Any value)
Any feed_twin_setup (**Any changes)
Dict[str, Any] options (LayerXSettings settings)
List[str] _option_problems (LayerXSettings settings)
Optional[Dict[str, str]] gn2_on_lox (Optional[str] pressurant, Any ox_tank, float lockup_pa, *, str test_mode="hotfire", bool acknowledged=False)
Optional[float] _stated_requirement (Any config, str key)
Optional[Dict[str, Any]] vessel_trip (Any node, float safety_factor)
List[Tuple[str, float]] vessel_reliefs (Any diagram, str vessel_id)
Dict[str, Any] expected_tank_rise (Any model, *, float dome_psig, str gas, float bottle_pa, float bottle_K, float bottle_m3, float lockup_pa, float ullage_m3, float expelled_m3, int iterations=12)
Optional[Dict[str, Any]] _burnout_tank_check (Any model, float dome, Any bottle, float copv_psig, float lockup_pa, Dict[str, str] roles, List[Any] tanks, Dict[str, Optional[float]] volumes, Optional[Dict[str, float]] loads, Dict[str, float] rho, LayerXSettings settings, float ambient, Any config, Optional[Dict[str, Dict[str, Any]]] trips=None, Optional[Dict[str, List[Tuple[str, float]]]] reliefs=None)
List[str] _feed_line_gaps (Any prep)
Optional[float] _vehicle_dry_kg (Any config)
Tuple[Dict[str, Any], int, str] swap_pressurant (Dict[str, Any] payload, str gas)
Dict[str, str] _inlet_nodes (Any built)
List[Tuple[str, Any, str]] _dome_regulators (Any model)
List[Dict[str, Any]] dome_knobs (Any model)
Optional[str] default_dome_regulator (Any model)
Optional[float] _knob_lockup (Any model, str regulator, float dome_psig, float supply_pa)
Optional[float] lockup_for_dome (Any model, float dome_psig, float supply_pa, Optional[str] regulator=None)
Optional[float] dome_for_lockup (Any model, float target_pa, float supply_pa, Optional[str] regulator=None)
Prepared prepare (Any config, Any runner, Drawing drawing, LayerXSettings settings, Optional[List[Any]] overrides=None)

Variables

float PSI = 6894.757293168361
tuple TEST_MODES = ("hotfire",)
tuple CHUG_BASES = ("config", "drawing")
tuple FLIGHT_COUPLINGS = ("outer", "inline")
float CHAMBER_TOLERANCE_PSI = 0.02
int NETWORK_TOLERANCE = 1e-6
 _PASSIVE_SYMBOLS = frozenset({"MANIFOLD", "JUNCTION", "TEE", "CROSS"})
dict _COOLPROP_GAS = {"nitrogen": "Nitrogen", "helium": "Helium"}
tuple PRESSURANTS = ("nitrogen", "helium")

Detailed Description

Everything a Layer X burn needs, assembled and checked before anything runs.

A burn takes seconds to a minute, and the ways it can be wrong before it starts
are cheap to find and expensive to discover afterwards. Examples: a drawing
whose tanks hold the wrong propellant, a load that does not fit, a main valve
the DAQ table cannot find, a target tank pressure above the drawing's MAWP. So
preparation does all of the setup work and grades it. The preflight endpoint
returns exactly what a run would start from.

What is decided here
--------------------
* **Which tank is which.** Matched by species against the engine config's
  propellants, never by a tag.
* **The propellant load.** The config's tank masses by default, because the
  load is fixed by rule rather than by a fill level. A drawing fill fraction
  is used only on request.
* **The dome setting.** It is solved from the drawing's own regulators, so the
  tanks lock up at the requested pressure. The tank pressure is the target;
  the dome is the knob that produces it.
* **The engine.** The live config, imported into the twin and calibrated to
  EngineDesign at T-0 (:mod:`engine.layerx.link`).
* **The chamber's ambient pressure.** The site's, from the config's elevation.
  It is not the gauge zero.

Function Documentation

◆ _burnout_tank_check()

Optional[Dict[str, Any]] engine.layerx.prepare._burnout_tank_check ( Any model,
float dome,
Any bottle,
float copv_psig,
float lockup_pa,
Dict[str, str] roles,
List[Any] tanks,
Dict[str, Optional[float]] volumes,
Optional[Dict[str, float]] loads,
Dict[str, float] rho,
LayerXSettings settings,
float ambient,
Any config,
Optional[Dict[str, Dict[str, Any]]] trips = None,
Optional[Dict[str, List[Tuple[str, float]]]] reliefs = None )
protected
Preflight's ``tank_rise`` check: :func:`expected_tank_rise` against the pressure each tank
trips the stand at (:func:`vessel_trip`, absolute, as the twin compares it), the relief valves
on it (:func:`vessel_reliefs`, set across the valve to the gauge zero) and the design's stated
tank cap (read as psia, as ``diag.limits`` reads it until AUDIT D11 is decided). ``warn`` over
any, ``info`` otherwise.

Definition at line 451 of file prepare.py.

References _stated_requirement(), expected_tank_rise(), and max.

Referenced by prepare().

◆ _dome_regulators()

List[Tuple[str, Any, str]] engine.layerx.prepare._dome_regulators ( Any model)
protected
``(symbol id, component, upstream node)`` for every dome-loaded regulator.

Definition at line 665 of file prepare.py.

Referenced by lockup_for_dome(), and prepare().

◆ _feed_line_gaps()

List[str] engine.layerx.prepare._feed_line_gaps ( Any prep)
protected
Per side, what the drawing leaves out of the tank-to-injector path the chug margin and the
line losses are computed on (``diag.stability.drawing_feed``): a path drawn with no line at all
(direct connections), and lines with no usable length or bore (a 0 mm bore is not a line).

Definition at line 517 of file prepare.py.

Referenced by prepare().

◆ _inlet_nodes()

Dict[str, str] engine.layerx.prepare._inlet_nodes ( Any built)
protected

Definition at line 653 of file prepare.py.

Referenced by prepare().

◆ _knob_lockup()

Optional[float] engine.layerx.prepare._knob_lockup ( Any model,
str regulator,
float dome_psig,
float supply_pa )
protected
Tank lockup [Pa abs] with the dial on ``regulator`` alone: a loader through its own outlet into
the dome it loads, any other regulator through its own dome signal (a plain one reads it as its
setpoint). The regulator that sets the tanks is evaluated at zero flow, plus its lockup rise.

Definition at line 702 of file prepare.py.

Referenced by lockup_for_dome().

◆ _option_problems()

List[str] engine.layerx.prepare._option_problems ( LayerXSettings settings)
protected
Values an opt-in choice cannot take (the router validates them too; a script may not).

Definition at line 239 of file prepare.py.

References _outlet_pair().

Referenced by prepare().

◆ _outlet_pair()

Tuple[Optional[float], Optional[float]] engine.layerx.prepare._outlet_pair ( Any value)
protected
``outlet_d_mm`` as ``(LOX, fuel)``: one number is both tanks'.

Definition at line 182 of file prepare.py.

Referenced by _option_problems().

◆ _stated_requirement()

Optional[float] engine.layerx.prepare._stated_requirement ( Any config,
str key )
protected
``design_requirements.<key>`` when the design states it; ``None`` when it is absent or only
the schema's default (pydantic's ``model_fields_set``), which has no source to check against.

Definition at line 327 of file prepare.py.

Referenced by _burnout_tank_check().

◆ _vehicle_dry_kg()

Optional[float] engine.layerx.prepare._vehicle_dry_kg ( Any config)
protected

Definition at line 543 of file prepare.py.

Referenced by prepare().

◆ at_operating_point()

LayerXSettings engine.layerx.prepare.at_operating_point ( LayerXSettings settings,
* ,
Optional[float] lockup_psia = None,
Optional[float] fill_psig = None )
``settings`` burning at this tank lockup [psia] and bottle fill [psig], whatever the rail's
knobs were. The rail writes the dome dial (``dome_psia``) and the fill (``copv_pressure_psia``)
as soon as a person turns either, and both win in :func:`prepare` (over ``tank_pressure_psia``
and ``copv_pressure_psig``): a set-point, optimiser, uncertainty or Hardware candidate that set
only the lockup or the fill burned at the rail's knobs every time, the set point's secant saw a
zero slope, and "use these settings" changed nothing. So the knob that governs what the
candidate sets is cleared with it.

Definition at line 163 of file prepare.py.

◆ default_dome_regulator()

Optional[str] engine.layerx.prepare.default_dome_regulator ( Any model)
The regulator the feed twin's own dome knob drives on this drawing (``hookup.suggest``).

Definition at line 694 of file prepare.py.

Referenced by prepare().

◆ dome_for_lockup()

Optional[float] engine.layerx.prepare.dome_for_lockup ( Any model,
float target_pa,
float supply_pa,
Optional[str] regulator = None )
The dome dial [psig] that locks the tanks up at ``target_pa``. The map is
affine in the dial (loader outlet plus bias plus supply effect), so two
evaluations solve it exactly; a third confirms.

Definition at line 757 of file prepare.py.

References lockup_for_dome().

Referenced by prepare().

◆ dome_knobs()

List[Dict[str, Any]] engine.layerx.prepare.dome_knobs ( Any model)
Every regulator a dome dial could set, as the feed twin's hookup lists them: ``{id, label,
kind, page, drawn_psia}`` with ``kind`` loader / dome / plain (feedtwin.session.hookup).

Definition at line 682 of file prepare.py.

Referenced by prepare().

◆ expected_tank_rise()

Dict[str, Any] engine.layerx.prepare.expected_tank_rise ( Any model,
* ,
float dome_psig,
str gas,
float bottle_pa,
float bottle_K,
float bottle_m3,
float lockup_pa,
float ullage_m3,
float expelled_m3,
int iterations = 12 )
The tank pressure at burnout the drawing's regulator law predicts before anything burns.

The regulator's outlet climbs as its supply falls (the supply-pressure effect), so the tanks end
the burn above their lockup. This estimates by how much:

* the gas the tanks need: CoolProp density at the end pressure times the ullage the burn ends
  with (the T-0 ullage plus the liquid expelled), less what the T-0 ullage already holds at
  lockup, both at the bottle's temperature;
* the bottle after giving it: its T-0 gas less that, expanded on the T-0 isentrope (a rigid
  vessel with no heat: the largest drop, so the largest rise);
* the tank pressure: the drawing's own regulator law (:func:`lockup_for_dome`) at that supply,
  at zero flow (droop would lower it).

Iterated, since the end pressure prices the gas. Returns ``{end_pa, rise_pa, bottle_end_pa,
gas_kg, converged}``; ``bottle_end_pa`` is ``None`` when the bottle cannot supply it.

Definition at line 403 of file prepare.py.

References lockup_for_dome().

Referenced by _burnout_tank_check().

◆ feed_twin_setup()

Any engine.layerx.prepare.feed_twin_setup ( **Any changes)
The feed twin's Setup, as its cockpit runs the stand, with only what a recorded burn needs
changed on top: no automatic vent at burnout (the trace is read past depletion), a burn's Newton
room and no wall-clock budget (``burn_setup``'s numerics), and the ``changes`` given.

Unlike :func:`feedtwin.session.burn.burn_setup`, the thermal closures are the twin's own (the
cockpit's: collapse, vapour, chilldown, stratification, boiling onset, nucleate boiling, wall
boiling), not switched off: Layer X trusts the twin (2026-10-03, AUDIT D1). ``burn_setup`` keeps
them off for the benchmark Study, whose expectations were set before they existed.

Definition at line 194 of file prepare.py.

References Setup.

Referenced by prepare().

◆ gn2_on_lox()

Optional[Dict[str, str]] engine.layerx.prepare.gn2_on_lox ( Optional[str] pressurant,
Any ox_tank,
float lockup_pa,
* ,
str test_mode = "hotfire",
bool acknowledged = False )
Preflight's nitrogen-over-LOX check: ``{status, detail}``, or ``None`` when it does not apply.

The physical criterion (AUDIT D3-B/C, decided 2026-10-03): nitrogen condenses on liquid oxygen
when its partial pressure in the ullage is above its own saturation pressure at the LOX
temperature, ~52 psia at 90 K. The ullage's nitrogen is the lockup less LOX's vapour pressure
(Dalton, the ullage saturated with oxygen at the surface). Both saturation pressures are
CoolProp's (Bell, Wronski, Quoilin & Lemort, Ind. Eng. Chem. Res. 53(6), 2014). The LOX
temperature is the drawing's oxidiser tank ``temperature``; without one, LOX's normal boiling
point. At or above nitrogen's critical temperature nothing condenses.

A burn over the line is a ``warn``, never a ``fail``: the team compares helium and nitrogen on
the same drawing (the user, 2026-10-20: "we want the option to compare both ... not to fight
over it"), so the run goes ahead and says what it leaves out. The twin models neither the
condensation into the propellant nor on the cold wall, so its pressurant use and tank pressure
read optimistic. ``acknowledged`` (``ack_gn2_condensation``) is kept so saved settings still
load; it no longer changes the status. This replaces a warning above nitrogen's critical pressure (492.5 psia), which said nothing
for a 300-490 psia nitrogen lockup that condenses just the same.

Definition at line 266 of file prepare.py.

Referenced by prepare().

◆ lockup_for_dome()

Optional[float] engine.layerx.prepare.lockup_for_dome ( Any model,
float dome_psig,
float supply_pa,
Optional[str] regulator = None )
Tank lockup [Pa abs] the drawing's regulators deliver for a dome dial
setting and a bottle pressure: the loader evaluated against the bottle the
way the session does each tick, then the dome-loaded unit at zero flow plus
its seat's lockup rise. ``None`` when the drawing has no dome-loaded unit.

Definition at line 729 of file prepare.py.

References _dome_regulators(), and _knob_lockup().

Referenced by dome_for_lockup(), expected_tank_rise(), and prepare().

◆ options()

Dict[str, Any] engine.layerx.prepare.options ( LayerXSettings settings)
The opt-in choices with ``None`` resolved to today's behaviour: what a run actually did.
Recorded as ``provenance.derived.options`` so a saved run says it, whatever the defaults
become.

Definition at line 214 of file prepare.py.

Referenced by prepare().

◆ prepare()

Prepared engine.layerx.prepare.prepare ( Any config,
Any runner,
Drawing drawing,
LayerXSettings settings,
Optional[List[Any]] overrides = None )
Read, match, size, calibrate and check. Never raises for a problem a
person can fix: that becomes a ``fail`` check naming it.

Definition at line 772 of file prepare.py.

References _burnout_tank_check(), _dome_regulators(), _feed_line_gaps(), _inlet_nodes(), _option_problems(), _vehicle_dry_kg(), default_dome_regulator(), dome_for_lockup(), dome_knobs(), feed_twin_setup(), gn2_on_lox(), lockup_for_dome(), max, options(), swap_pressurant(), vessel_reliefs(), and vessel_trip().

◆ swap_pressurant()

Tuple[Dict[str, Any], int, str] engine.layerx.prepare.swap_pressurant ( Dict[str, Any] payload,
str gas )
``payload`` with the bottle's gas replaced by ``gas`` wherever the drawing holds it (the
bottle, regulators, press lines' valves and vents): a copy, the count, and the gas it was.

Definition at line 606 of file prepare.py.

Referenced by prepare().

◆ vessel_reliefs()

List[Tuple[str, float]] engine.layerx.prepare.vessel_reliefs ( Any diagram,
str vessel_id )
``(label, set pressure [Pa, across the valve])`` for every relief valve with a drawn
``set_pressure`` that sees ``vessel_id``'s pressure: drawn onto it, or behind manifolds and
junctions only (LE4 (3)'s COPV-RV sits on COPV-MFLD). Not one behind a valve or a regulator.

Definition at line 378 of file prepare.py.

Referenced by prepare().

◆ vessel_trip()

Optional[Dict[str, Any]] engine.layerx.prepare.vessel_trip ( Any node,
float safety_factor )
The pressure the feed twin trips the stand at for this vessel, as the twin computes it
(``feedtwin.session.core._trip_limit``, which ``Session._check_limits`` compares the vessel's
absolute pressure with): the drawing's ``burst_pressure`` over ``Setup.burst_safety_factor``
across the wall when it gives one, else its ``MAWP``. Both are read as the drawing reads them
(ADR 0004: a bare psi is gauge, so ``.si`` is already absolute).

``{trip_psia, basis, rating_psig, safety_factor, source, words}``: ``trip_psia`` is absolute,
``basis`` ``burst`` or ``MAWP``, ``rating_psig`` the drawn number. ``None`` when the drawing
rates the vessel by neither: the twin then checks nothing.

Definition at line 340 of file prepare.py.

References max.

Referenced by prepare().

Variable Documentation

◆ _COOLPROP_GAS

dict engine.layerx.prepare._COOLPROP_GAS = {"nitrogen": "Nitrogen", "helium": "Helium"}
protected

Definition at line 448 of file prepare.py.

◆ _PASSIVE_SYMBOLS

engine.layerx.prepare._PASSIVE_SYMBOLS = frozenset({"MANIFOLD", "JUNCTION", "TEE", "CROSS"})
protected

Definition at line 375 of file prepare.py.

◆ CHAMBER_TOLERANCE_PSI

float engine.layerx.prepare.CHAMBER_TOLERANCE_PSI = 0.02

Definition at line 45 of file prepare.py.

◆ CHUG_BASES

tuple engine.layerx.prepare.CHUG_BASES = ("config", "drawing")

Definition at line 40 of file prepare.py.

◆ FLIGHT_COUPLINGS

tuple engine.layerx.prepare.FLIGHT_COUPLINGS = ("outer", "inline")

Definition at line 41 of file prepare.py.

◆ NETWORK_TOLERANCE

int engine.layerx.prepare.NETWORK_TOLERANCE = 1e-6

Definition at line 54 of file prepare.py.

◆ PRESSURANTS

tuple engine.layerx.prepare.PRESSURANTS = ("nitrogen", "helium")

Definition at line 603 of file prepare.py.

◆ PSI

float engine.layerx.prepare.PSI = 6894.757293168361

Definition at line 34 of file prepare.py.

◆ TEST_MODES

tuple engine.layerx.prepare.TEST_MODES = ("hotfire",)

Definition at line 38 of file prepare.py.