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

Classes

class  AssemblyError
class  Assumption
class  AssemblyReport
class  Model

Functions

dict[str, object] diagram_summary (Mapping[str, Any] payload)
dict[str, object] engine_summary (EngineDesign design)
str find_engine_reference (Diagram diagram)
Model assemble_model (Diagram diagram, *, str diagram_id, EngineDesign|None engine=None, str engine_reference="", Chamber|None chamber=None, str cea_cache="", Mapping[str, tuple[str, float]]|None fluid_swap=None, Mapping[str, str]|None gas_swap=None, bool multiphase=False, Mapping[str, object]|None meta=None, bool vehicle_only=False)
Chamber chamber_for (EngineDesign engine, str cea_cache)
Diagram swap_gases (Diagram diagram, Mapping[str, str] swaps)
Diagram swap_fluids (Diagram diagram, Mapping[str, tuple[str, float]] swaps)

Detailed Description

Assembly: a drawing and an engine in, a solvable model out, with a record of
what happened.

Moved here from the feed-twin app (``backend/assembly.py``) when the marching
session became library code. The app keeps the half that reads artifacts out of
its content-addressed store and calls :func:`assemble_model` with what it read;
EngineDesign's Layer X reads its drawings and engines elsewhere and calls the
same function, so both callers get the same network and the same report.

Importing a drawing is not one step, it is four, and each can go wrong in a way
worth naming:

1. **Read** the drawing. Malformed JSON, a line to nowhere, a parameter with no
   provenance -- all refused here, with the field named.
2. **Resolve** what it points at. The engine symbol names a Layer-1 config; that
   config has to be found (by the caller) and has to import.
3. **Build** the network. Symbols become nodes and branches; a tank becomes two
   pressures; the engine becomes an injector face and a chamber.
4. **Fill in** what the drawing did not say -- and record every one of those.

The output is a :class:`Model` and an :class:`AssemblyReport`. The report is the
point. A drawing that omits a bore still solves, and the answer is still worth
having, but it is a *different kind of claim* from one where every number was
measured -- and the difference must never be invisible. So the report carries
what was read, what was assumed, what was refused, and the hash of every artifact
that went in.

That is also what makes a run reproducible: a result names the artifacts by
content, so "which drawing was this" is answerable a year later.

Function Documentation

◆ assemble_model()

Model feedtwin.session.model.assemble_model ( Diagram diagram,
* ,
str diagram_id,
EngineDesign | None engine = None,
str engine_reference = "",
Chamber | None chamber = None,
str cea_cache = "",
Mapping[str, tuple[str, float]] | None fluid_swap = None,
Mapping[str, str] | None gas_swap = None,
bool multiphase = False,
Mapping[str, object] | None meta = None,
bool vehicle_only = False )
Build and audit a model from a drawing already read and an engine already
imported. The half of the feed-twin app's ``assemble`` that needs no
artifact store, so a caller with its own (EngineDesign's Layer X) gets the
same model, the same assumptions and the same report.

Args:
    diagram_id: What the report calls the drawing -- an artifact id, a
        document id, a path. Recorded, never resolved.
    engine_reference: What the report calls the engine. Defaults to the
        engine's own name when an engine is given.
    chamber: A chamber to attach. When omitted and an engine is given, one
        is built from ``cea_cache`` (see :func:`chamber_for`).
    gas_swap: The pressurant replaced, ``{"nitrogen": "helium"}``
        (:func:`swap_gases`): every symbol declaring the one gas declares
        the other. Tanks keep their contents.
    vehicle_only: Cut the ground support away before building
        (:func:`feedtwin.pid.roles.vehicle_only`, ``Setup.ignore_gse``):
        the cart is not simulated and the session's built-in fills stand in
        for it. ``meta`` then carries ``vehicle_only``, ``ground_cut``
        (the labels of the vessels cut) and ``capped`` (the ids of the
        vehicle's disconnects whose mate was cut).

Definition at line 169 of file model.py.

References chamber_for(), swap_fluids(), and swap_gases().

◆ chamber_for()

Chamber feedtwin.session.model.chamber_for ( EngineDesign engine,
str cea_cache )
A chamber for this engine, from a CEA table when one is reachable.

A constant ``c*`` is the fallback and it is a real loss: with it, mixture
ratio still moves during a run but nothing downstream of it responds, which
reads as "O/F drift does not matter here" when it means "this model cannot
see it". So the fallback is named in the warnings rather than taken quietly.

Definition at line 315 of file model.py.

Referenced by assemble_model().

◆ diagram_summary()

dict[str, object] feedtwin.session.model.diagram_summary ( Mapping[str, Any] payload)
A listing-level look at a drawing without building anything.

Definition at line 111 of file model.py.

◆ engine_summary()

dict[str, object] feedtwin.session.model.engine_summary ( EngineDesign design)

Definition at line 143 of file model.py.

◆ find_engine_reference()

str feedtwin.session.model.find_engine_reference ( Diagram diagram)
The engine artifact the drawing points at, if it points at one.

Read from the engine symbol's ``engineConfig`` option. Absent is fine and
common -- the engine stays a pressure boundary and the report says so.

Definition at line 155 of file model.py.

◆ swap_fluids()

Diagram feedtwin.session.model.swap_fluids ( Diagram diagram,
Mapping[str, tuple[str, float]] swaps )
Tank contents replaced, for a cold flow. Temperature travels with the
species -- water at the LOX tank's 90 K is ice.

Definition at line 358 of file model.py.

Referenced by assemble_model().

◆ swap_gases()

Diagram feedtwin.session.model.swap_gases ( Diagram diagram,
Mapping[str, str] swaps )
The pressurant replaced: every symbol that declares a gas in ``swaps``
-- the bottles, and any valve or line labelled with it -- declares the
other instead, keeping its own temperature. Tanks and dewars hold liquids
and are :func:`swap_fluids`'s. The network spreads gases from what is
declared (a K-bottle first), so this is the whole of the change: helium
in the COPV, its press lines and the ullages it fills.

Definition at line 341 of file model.py.

Referenced by assemble_model().