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

Classes

class  Setup
class  TankSim
class  BottleSim
class  Trip
class  Sample
class  Session

Functions

frozenset[str] _ground (Model model)
list[str] _bottle_ids (Model model)
tuple[dict[str, str], dict[str, str]] drawn_fills (Model model)
dict[str, list[str]] _pressed_supplies (Model model)
dict[str, str] builtin_rows (StateMachine machine, Model model, Collection[str]|None drawn=None)
str _not_a_liquid_tank (str label, str species, float temperature, Exception exc)
CylindricalTank _bottle_geometry (float volume)
CylindricalTank _tank_geometry (float volume, float diameter)
float _skin_conductance (object node, float air_film, list[str] assumptions)
float _trip_limit (object node, float safety_factor, list[str] assumptions)
tuple[float, float, float] _vessel_wall (object node, float litres, dict[str, Any] defaults, list[str] assumptions, Callable[[], GasFilm]|None estimate=None)

Variables

 AMBIENT = ATMOSPHERE
float MAX_STEP = 0.25
float MAX_COUPLED_CHANGE = 0.04
int _TEMPERATURE_SWEEPS = 12
float _TEMPERATURE_MIN_FLOW = 1.0e-6
float _TEMPERATURE_TOL = 0.05
float _DEW_MARGIN_K = 0.5
float ROOM = 293.15
 MIN_CHAMBER_FLOW = ENGINE_MIN_CHAMBER_FLOW
float COLD_FLOW_S = 0.5
float DRY_MASS = 1.0e-3
int MAX_COUPLING_STEPS = 400
float COUPLING_SAFETY = 1.0
float PAD_HOLD_S = 300.0
float LOW_TANK = 0.10
float LOW_BOTTLE = 0.25
float LEAK_NOTE_KG_S = 0.005
float CHAMBER_TOL = 0.5 * PSI
int CHAMBER_ITERATIONS = 12
float SUPPLY_BAND = 0.005
float DEFAULT_TRAVEL = 0.05
float TICK_BUDGET = 1.0e9
float LIVE_STEP = 0.02
int SUBSTEPS = 4
float CHILLED_BAND = 0.5
float FILL_SUPPLY_T = 293.15
str GSE_CHARGE = "GSE High Press Control"
str GSE_DUMP = "GSE High Press Vent"
 BOTTLE_TYPES = frozenset({"KBOTTLE", "DEWAR"})
float AMBIENT_T = 293.15
float FIBERGLASS_K = 0.04
float CRYOGENIC_K = 150.0
float PRESS_PATH_FD = 1.0e-3
float STORAGE_PROBE = 1.0e-3
float PRESS_PATH_DRAIN_FRACTION = 0.1
int FILL_LINE_ITERATIONS = 4
float FILL_LINE_ROUGHNESS = 1.5e-6
float WARM_WALL_K = 30.0
float HOT_BOTTLE_K = 15.0
float MAX_MASS_STEP = 0.10
float CHARGE_GAMMA = 1.67
float STIR_BAND = 0.02
float MAX_MASS_FRACTION = 0.02
float MAX_TEMPERATURE_FRACTION = 0.03
int STEP_RETRIES = 6
float LIQUID_ROUNDOFF = 1.0e-12
int MAX_VESSEL_STEPS = 200
int LIVE_ITERATIONS = 120
float LIVE_TOL = 1.0e-4
int HISTORY = 4000
float FULL_FRACTION = 0.95
dict TANK_WALL
dict BOTTLE_WALL

Detailed Description

A stand that exists in time.

Everything before this was a calculator with a state label on it: each request
re-solved from scratch with the tanks *pinned* at the regulator's setpoint. So
the tanks were always pressurised, "Fuel Press" changed nothing you could see,
and transducers read pressures that had no business existing. Nothing
accumulated, so nothing behaved.

A session fixes that by holding the thing a stand actually has -- **inventory**.
Each tank is a real vessel with a gas mass, a gas energy, a liquid mass and a
wall temperature, and those integrate forward. That single change is what makes
the sequence mean something:

* A tank starts **empty and at atmosphere**. Its transducer reads 14.7 psi,
  because that is what a vented tank reads.
* ``Ox Fill`` puts propellant in it. The level rises; the ullage shrinks.
* ``Ox Press`` opens the path from the regulator, gas flows into the ullage, and
  the pressure *climbs over several seconds* the way a real tank does -- fast at
  first into a small ullage, slower as it fills.
* ``Ox Vent`` opens it to atmosphere and it blows down.
* ``Fire`` opens the mains, propellant leaves, and the ullage cools and droops
  because the gas behind it is doing expansion work.

None of that is scripted. It falls out of integrating the vessels against a
network solved at each instant.

How a tick works
----------------
The system is a semi-explicit index-1 DAE: the vessels are differential, the
network is algebraic. Rather than hand the whole thing to a stiff integrator --
which is what Phase 07 did, and what would not converge on an imported
network -- this marches it at a fixed small step, which is what a flight
simulator does and is stable for the same reason:

1. Write each vessel's current pressure into its network boundary node.
2. Solve the network for flows. Pure algebra at frozen vessel state.
3. Hand those flows back to the vessels as inflow and outflow.
4. Advance the vessels by ``dt``.

A tick that fails to converge does not abort the session -- it holds the last
good flows and keeps going, because a stand does not stop existing because one
solve was hard, and the alternative is a simulator that dies mid-sequence.

Function Documentation

◆ _bottle_geometry()

CylindricalTank feedtwin.session.core._bottle_geometry ( float volume)
protected
A cylinder at L/D = 4 holding this volume: the shape of a gas bottle,
which the drawing does not give and the film only needs roughly.

Definition at line 1015 of file core.py.

References max.

Referenced by feedtwin.session.core.Session._build_vessels().

◆ _bottle_ids()

list[str] feedtwin.session.core._bottle_ids ( Model model)
protected
The drawing's bottles, in the order the session builds them.

Definition at line 314 of file core.py.

Referenced by builtin_rows(), and drawn_fills().

◆ _ground()

frozenset[str] feedtwin.session.core._ground ( Model model)
protected
Drawing ids off the vehicle (:attr:`Session.ground`).

Definition at line 306 of file core.py.

Referenced by builtin_rows(), drawn_fills(), and feedtwin.session.core.Session.ground().

◆ _not_a_liquid_tank()

str feedtwin.session.core._not_a_liquid_tank ( str label,
str species,
float temperature,
Exception exc )
protected
Why a tank could not start, in the drawing's terms.

Definition at line 992 of file core.py.

Referenced by feedtwin.session.core.Session._build_vessels().

◆ _pressed_supplies()

dict[str, list[str]] feedtwin.session.core._pressed_supplies ( Model model)
protected
The cart's transfer tanks a table row presses
(:meth:`Session._supply_press`), labels by side (``lox``/``fuel``): a
supply tank with a drawn pressure. Not a dewar: its own circuit holds it,
whatever the table says.

Definition at line 400 of file core.py.

Referenced by builtin_rows().

◆ _skin_conductance()

float feedtwin.session.core._skin_conductance ( object node,
float air_film,
list[str] assumptions )
protected
Overall air-to-wall conductance per unit skin [W/(m^2.K)].

The air film in series with the insulation the drawing declares:
``U = 1 / (1/h_air + t/k)``. A tank that declares no insulation is bare,
and says so in the assumptions when it is a cryogen tank, because the
difference is a factor of six in boil-off.

Definition at line 1055 of file core.py.

Referenced by feedtwin.session.core.Session._build_vessels(), and feedtwin.session.core.Session.apply_thermal().

◆ _tank_geometry()

CylindricalTank feedtwin.session.core._tank_geometry ( float volume,
float diameter )
protected
A barrel of the right volume at the drawing's diameter, 2:1 heads.

Delegates to the library so the drawing reader's static head and this
vessel agree on where the liquid surface is.

Definition at line 1022 of file core.py.

Referenced by feedtwin.session.core.Session._build_vessels().

◆ _trip_limit()

float feedtwin.session.core._trip_limit ( object node,
float safety_factor,
list[str] assumptions )
protected
Absolute pressure a vessel trips the stand at, or 0 for no limit.

The drawing says what the vessel will take as a burst pressure -- what a
team that built it knows -- and the stand stops at that over a stated
factor of safety. An older drawing carrying an MAWP trips at the MAWP.

Both are read as the drawing reads them (feedtwin.model.pressure): bare
"psi" is gauge, so ``.si`` is already absolute. The safety factor divides
what the wall carries -- the pressure across it, gauge -- not the absolute.

Definition at line 1082 of file core.py.

References max.

Referenced by feedtwin.session.core.Session._build_vessels().

◆ _vessel_wall()

tuple[float, float, float] feedtwin.session.core._vessel_wall ( object node,
float litres,
dict[str, Any] defaults,
list[str] assumptions,
Callable[[], GasFilm] | None estimate = None )
protected
``(wall_mass, wall_capacity, wall_conductance)`` for one vessel.

From the drawing where it says; from the scaled defaults where it does
not, with a note. Reading the three separately, so a drawing that weighed
the vessel but has no idea of its film coefficient still gets credit for
the number it knows.

Definition at line 1108 of file core.py.

References max, and read().

Referenced by feedtwin.session.core.Session._build_vessels().

◆ builtin_rows()

dict[str, str] feedtwin.session.core.builtin_rows ( StateMachine machine,
Model model,
Collection[str] | None drawn = None )
The table's rows the session reads by name and acts on itself with no
valve wired to them, with what each does: the built-in COPV charge and
dump, and the cart's press on a transfer tank
(:meth:`Session._supply_press`). Such a row is not "wired to nothing" --
renaming or dropping it stops what it does, and an editor must say so.

Only where the session would act on ``model``: the charge and dump while
a vehicle bottle's fill is not drawn (a cart drawn charging it charges it
through its own valves, and an unwired GSE High Press Control then
charges nothing), the press while a transfer tank of the row's side has a
drawn pressure. Rocket only, give it the cut model: the cart's fill went
with the cart. ``drawn``: the vessels the drawing fills, when a session
has found them already (:attr:`Session.builtin`); else found here.

Definition at line 419 of file core.py.

References _bottle_ids(), _ground(), _pressed_supplies(), and drawn_fills().

Referenced by feedtwin.session.core.Session.builtin().

◆ drawn_fills()

tuple[dict[str, str], dict[str, str]] feedtwin.session.core.drawn_fills ( Model model)
The vessels the drawing itself fills, each with what fills it:
``(tanks, bottles)``, vessel id -> supply id.

Tanks a drawn dewar reaches, and bottles another drawn bottle or dewar
reaches, through the drawing's lines and valves (open or shut -- a valve
is how the fill is commanded, not whether it exists) without passing
through another vessel -- from another page of the drawing, which is
where pid-designer puts the cart. Two flight bottles manifolded together
on the vehicle page are not one filling the other. A cart's own tank and
bottles are supplies and never listed. The session's built-in fill steps
aside for every one (:attr:`Session._drawn_fill`).

Definition at line 324 of file core.py.

References _bottle_ids(), and _ground().

Referenced by feedtwin.session.core.Session._find_drawn_fills(), and builtin_rows().

Variable Documentation

◆ _DEW_MARGIN_K

float feedtwin.session.core._DEW_MARGIN_K = 0.5
protected

Definition at line 135 of file core.py.

◆ _TEMPERATURE_MIN_FLOW

float feedtwin.session.core._TEMPERATURE_MIN_FLOW = 1.0e-6
protected

Definition at line 126 of file core.py.

◆ _TEMPERATURE_SWEEPS

int feedtwin.session.core._TEMPERATURE_SWEEPS = 12
protected

Definition at line 124 of file core.py.

◆ _TEMPERATURE_TOL

float feedtwin.session.core._TEMPERATURE_TOL = 0.05
protected

Definition at line 128 of file core.py.

◆ AMBIENT

feedtwin.session.core.AMBIENT = ATMOSPHERE

Definition at line 98 of file core.py.

◆ AMBIENT_T

float feedtwin.session.core.AMBIENT_T = 293.15

Definition at line 470 of file core.py.

◆ BOTTLE_TYPES

feedtwin.session.core.BOTTLE_TYPES = frozenset({"KBOTTLE", "DEWAR"})

Definition at line 303 of file core.py.

◆ BOTTLE_WALL

dict feedtwin.session.core.BOTTLE_WALL
Initial value:
1= {
2 "kg_per_litre": 60.0 / 44.0,
3 "capacity": 500.0,
4 "hA_ref": (20.0, 4.687),
5 "basis": "steel K-bottle, ~60 kg at 44 L water volume; hA 20 W/K at 4.687 L "
6 "scaled as V^(2/3). A composite cylinder is far lighter -- declare it",
7}

Definition at line 1046 of file core.py.

◆ CHAMBER_ITERATIONS

int feedtwin.session.core.CHAMBER_ITERATIONS = 12

Definition at line 231 of file core.py.

◆ CHAMBER_TOL

float feedtwin.session.core.CHAMBER_TOL = 0.5 * PSI

Definition at line 230 of file core.py.

◆ CHARGE_GAMMA

float feedtwin.session.core.CHARGE_GAMMA = 1.67

Definition at line 508 of file core.py.

◆ CHILLED_BAND

float feedtwin.session.core.CHILLED_BAND = 0.5

Definition at line 291 of file core.py.

◆ COLD_FLOW_S

float feedtwin.session.core.COLD_FLOW_S = 0.5

Definition at line 147 of file core.py.

◆ COUPLING_SAFETY

float feedtwin.session.core.COUPLING_SAFETY = 1.0

Definition at line 198 of file core.py.

◆ CRYOGENIC_K

float feedtwin.session.core.CRYOGENIC_K = 150.0

Definition at line 474 of file core.py.

◆ DEFAULT_TRAVEL

float feedtwin.session.core.DEFAULT_TRAVEL = 0.05

Definition at line 247 of file core.py.

◆ DRY_MASS

float feedtwin.session.core.DRY_MASS = 1.0e-3

Definition at line 149 of file core.py.

◆ FIBERGLASS_K

float feedtwin.session.core.FIBERGLASS_K = 0.04

Definition at line 472 of file core.py.

◆ FILL_LINE_ITERATIONS

int feedtwin.session.core.FILL_LINE_ITERATIONS = 4

Definition at line 489 of file core.py.

◆ FILL_LINE_ROUGHNESS

float feedtwin.session.core.FILL_LINE_ROUGHNESS = 1.5e-6

Definition at line 492 of file core.py.

◆ FILL_SUPPLY_T

float feedtwin.session.core.FILL_SUPPLY_T = 293.15

Definition at line 294 of file core.py.

◆ FULL_FRACTION

float feedtwin.session.core.FULL_FRACTION = 0.95

Definition at line 566 of file core.py.

◆ GSE_CHARGE

str feedtwin.session.core.GSE_CHARGE = "GSE High Press Control"

Definition at line 300 of file core.py.

◆ GSE_DUMP

str feedtwin.session.core.GSE_DUMP = "GSE High Press Vent"

Definition at line 301 of file core.py.

◆ HISTORY

int feedtwin.session.core.HISTORY = 4000

Definition at line 560 of file core.py.

◆ HOT_BOTTLE_K

float feedtwin.session.core.HOT_BOTTLE_K = 15.0

Definition at line 498 of file core.py.

◆ LEAK_NOTE_KG_S

float feedtwin.session.core.LEAK_NOTE_KG_S = 0.005

Definition at line 219 of file core.py.

◆ LIQUID_ROUNDOFF

float feedtwin.session.core.LIQUID_ROUNDOFF = 1.0e-12

Definition at line 543 of file core.py.

◆ LIVE_ITERATIONS

int feedtwin.session.core.LIVE_ITERATIONS = 120

Definition at line 551 of file core.py.

◆ LIVE_STEP

float feedtwin.session.core.LIVE_STEP = 0.02

Definition at line 264 of file core.py.

◆ LIVE_TOL

float feedtwin.session.core.LIVE_TOL = 1.0e-4

Definition at line 556 of file core.py.

◆ LOW_BOTTLE

float feedtwin.session.core.LOW_BOTTLE = 0.25

Definition at line 214 of file core.py.

◆ LOW_TANK

float feedtwin.session.core.LOW_TANK = 0.10

Definition at line 211 of file core.py.

◆ MAX_COUPLED_CHANGE

float feedtwin.session.core.MAX_COUPLED_CHANGE = 0.04

Definition at line 115 of file core.py.

◆ MAX_COUPLING_STEPS

int feedtwin.session.core.MAX_COUPLING_STEPS = 400

Definition at line 161 of file core.py.

◆ MAX_MASS_FRACTION

float feedtwin.session.core.MAX_MASS_FRACTION = 0.02

Definition at line 517 of file core.py.

◆ MAX_MASS_STEP

float feedtwin.session.core.MAX_MASS_STEP = 0.10

Definition at line 503 of file core.py.

◆ MAX_STEP

float feedtwin.session.core.MAX_STEP = 0.25

Definition at line 104 of file core.py.

◆ MAX_TEMPERATURE_FRACTION

float feedtwin.session.core.MAX_TEMPERATURE_FRACTION = 0.03

Definition at line 527 of file core.py.

◆ MAX_VESSEL_STEPS

int feedtwin.session.core.MAX_VESSEL_STEPS = 200

Definition at line 546 of file core.py.

◆ MIN_CHAMBER_FLOW

feedtwin.session.core.MIN_CHAMBER_FLOW = ENGINE_MIN_CHAMBER_FLOW

Definition at line 142 of file core.py.

◆ PAD_HOLD_S

float feedtwin.session.core.PAD_HOLD_S = 300.0

Definition at line 208 of file core.py.

◆ PRESS_PATH_DRAIN_FRACTION

float feedtwin.session.core.PRESS_PATH_DRAIN_FRACTION = 0.1

Definition at line 486 of file core.py.

◆ PRESS_PATH_FD

float feedtwin.session.core.PRESS_PATH_FD = 1.0e-3

Definition at line 477 of file core.py.

◆ ROOM

float feedtwin.session.core.ROOM = 293.15

Definition at line 137 of file core.py.

◆ STEP_RETRIES

int feedtwin.session.core.STEP_RETRIES = 6

Definition at line 533 of file core.py.

◆ STIR_BAND

float feedtwin.session.core.STIR_BAND = 0.02

Definition at line 512 of file core.py.

◆ STORAGE_PROBE

float feedtwin.session.core.STORAGE_PROBE = 1.0e-3

Definition at line 482 of file core.py.

◆ SUBSTEPS

int feedtwin.session.core.SUBSTEPS = 4

Definition at line 287 of file core.py.

◆ SUPPLY_BAND

float feedtwin.session.core.SUPPLY_BAND = 0.005

Definition at line 239 of file core.py.

◆ TANK_WALL

dict feedtwin.session.core.TANK_WALL
Initial value:
1= {
2 "kg_per_litre": 8.0 / 17.5,
3 "capacity": 900.0,
4 "hA_ref": (12.0, 17.5),
5 "basis": "aluminium tank, 8 kg at 17.5 L; hA 12 W/K at 17.5 L scaled as V^(2/3)",
6}

Definition at line 1040 of file core.py.

◆ TICK_BUDGET

float feedtwin.session.core.TICK_BUDGET = 1.0e9

Definition at line 258 of file core.py.

◆ WARM_WALL_K

float feedtwin.session.core.WARM_WALL_K = 30.0

Definition at line 495 of file core.py.