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

Classes

class  OutflowSettings

Functions

float point_sink_constant ()
float critical_height (float Q, float accel, float rho_liquid, float rho_gas=0.0, float constant=LS_CONSTANT)
float volume_below (float h, float radius, float head_depth)
float liquid_height (float V, float radius, float head_depth)
Dict[str, Any] onset (Sequence[float] t, Sequence[float] liquid_kg, Sequence[float] mdot, Sequence[float] accel, *, Sequence[float] rho_liquid, Sequence[float] rho_gas, float radius, float head_depth, float constant=LS_CONSTANT)
Tuple[Optional[Mapping[str, Any]], str] _schedule_accel (Mapping[str, Any] result, Optional[Mapping[str, Any]] accel)
List[Dict[str, Any]] outflow_from_run (Any prep, Mapping[str, Any] result, OutflowSettings settings=OutflowSettings(), Optional[Mapping[str, Any]] accel=None)
Dict[str, Any] _row (Any prep, Mapping[str, Any] result, str side, str key, Optional[float] d_mm, OutflowSettings settings, Optional[Mapping[str, Any]] accel)

Variables

str MODEL_NAME = "lubin_springer_dip"
float LS_CONSTANT = 0.69
tuple LS_SOURCE
dict HEADS = {"flat": 0.0, "ellipsoidal_2to1": 0.5, "hemispherical": 1.0}

Detailed Description

Layer X outflow: when each tank outlet starts drawing pressurant (the surface dip), and what is
left in the tank then.

``outflow_from_run(prep, result, settings=OutflowSettings(), accel=None)`` -> ``diagnostics.outflow``
(a list, one row per propellant tank; DATA-CONTRACT 3).

The twin burns each tank to its dry mass (1 g, ``LayerXSettings.dry_kg``): its outlet never draws
gas. A real outlet does, once the liquid over it is shallow enough that the flow converging on the
outlet pulls the surface down into it.

The model: Lubin & Springer (1967)
----------------------------------
B. T. Lubin and G. S. Springer, "The formation of a dip on the surface of a liquid draining from a
tank", J. Fluid Mech. 29(2), 385-390, 1967. With no swirl, a dip forms over a bottom outlet, and
gas is drawn into it, when the liquid height over the outlet falls to

    h_c = 0.69 (Q^2 / g')^(1/5),        g' = g (1 - rho_gas / rho_liquid)

``Q`` the volumetric outflow and ``g`` the specific force along the tank axis. Independent of the
outlet diameter and of the initial height. The constant and the form ``0.69 (Q^2/g)^(1/5)`` are as
restated by M. Wollen and C. Ostoich, "Design of a low gravity vane liquid acquisition device for
cryogenic liquids ...", TFAWS 2024, paper TFAWS24-CR-1 ("Classic analytical result by Lubin and
Springer"; checked against the slides). The buoyancy factor ``1 - rho_gas/rho_liquid`` on ``g`` is
this module's (the restatement has none; the paper's own text was not available to check): it is
the reduced gravity of a gas-over-liquid surface, and on LE4 (helium at ~600 psia over LOX) it moves
``h_c`` by under 0.2 %. The constant is also what the point-sink analysis behind it gives: with the
surface over a hemispherical sink of velocity
``Q/(2 pi z^2)``, Bernoulli gives ``h = z + Q^2/(8 pi^2 g' z^4)``, which has no solution for ``h``
below its minimum ``h_c = 1.25 (Q^2/(2 pi^2 g'))^(1/5) = 0.688 (Q^2/g')^(1/5)``
(``point_sink_constant``; tested). **The constant 0.574 quoted in docs/layer-x.md could not be
verified against the paper and is not used**; it would put the dip 17 % lower.

What the run has to supply, and does not have
---------------------------------------------
* **Outlet diameter**: the drawing's line leaving the tank (its bore is the outlet).
  It does not enter ``h_c``; it sets the outlet Froude number and the check that ``h_c`` is large
  against the outlet (the sink approximation).
* **Tank diameter**: the drawing's (estimated, "not measured").
* **Bottom head shape**: not drawn. ``flat`` (default) puts the most liquid under ``h_c`` and is the
  upper bound on the residual; ``hemispherical`` the least; ``ellipsoidal_2to1`` between. The row
  carries all three.
* **Swirl** raises the onset height (a vortex instead of a dip). Not modelled.

The residual at onset is an upper bound on the unusable propellant: past the onset the outlet draws
gas with the liquid rather than stopping at once.

Function Documentation

◆ _row()

Dict[str, Any] engine.layerx.diag.outflow._row ( Any prep,
Mapping[str, Any] result,
str side,
str key,
Optional[float] d_mm,
OutflowSettings settings,
Optional[Mapping[str, Any]] accel )
protected

Definition at line 179 of file outflow.py.

References _schedule_accel(), liquid_height(), max, and onset().

Referenced by outflow_from_run().

◆ _schedule_accel()

Tuple[Optional[Mapping[str, Any]], str] engine.layerx.diag.outflow._schedule_accel ( Mapping[str, Any] result,
Optional[Mapping[str, Any]] accel )
protected

Definition at line 156 of file outflow.py.

Referenced by _row().

◆ critical_height()

float engine.layerx.diag.outflow.critical_height ( float Q,
float accel,
float rho_liquid,
float rho_gas = 0.0,
float constant = LS_CONSTANT )
Lubin & Springer's dip height [m] for a volumetric outflow ``Q`` [m^3/s] at specific force
``accel`` [m/s^2].

Definition at line 76 of file outflow.py.

Referenced by onset().

◆ liquid_height()

float engine.layerx.diag.outflow.liquid_height ( float V,
float radius,
float head_depth )
Inverse of :func:`volume_below` (bisection: monotone).

Definition at line 100 of file outflow.py.

References max, and volume_below().

Referenced by _row(), and onset().

◆ onset()

Dict[str, Any] engine.layerx.diag.outflow.onset ( Sequence[float] t,
Sequence[float] liquid_kg,
Sequence[float] mdot,
Sequence[float] accel,
* ,
Sequence[float] rho_liquid,
Sequence[float] rho_gas,
float radius,
float head_depth,
float constant = LS_CONSTANT )
First instant the liquid height falls to the dip height, interpolated between steps.
Inputs are per step over the firing steps (mdot > 0).

Definition at line 118 of file outflow.py.

References critical_height(), and liquid_height().

Referenced by _row().

◆ outflow_from_run()

List[Dict[str, Any]] engine.layerx.diag.outflow.outflow_from_run ( Any prep,
Mapping[str, Any] result,
OutflowSettings settings = OutflowSettings(),
Optional[Mapping[str, Any]] accel = None )
``diagnostics.outflow`` rows. Never raises.

Definition at line 166 of file outflow.py.

References _row().

◆ point_sink_constant()

float engine.layerx.diag.outflow.point_sink_constant ( )
1.25 (2 pi^2)^(-1/5): the minimum of ``h(z) = z + Q^2/(8 pi^2 g z^4)`` over ``(Q^2/g)^(1/5)``.

Definition at line 71 of file outflow.py.

◆ volume_below()

float engine.layerx.diag.outflow.volume_below ( float h,
float radius,
float head_depth )
Liquid volume [m^3] up to height ``h`` over the outlet in a vertical cylinder of ``radius``
with a semi-ellipsoidal bottom head of depth ``head_depth`` (0 = flat, radius = hemisphere).
In the head, the cross-section at height y is ``pi R^2 (2 b y - y^2)/b^2``.

Definition at line 86 of file outflow.py.

Referenced by liquid_height().

Variable Documentation

◆ HEADS

dict engine.layerx.diag.outflow.HEADS = {"flat": 0.0, "ellipsoidal_2to1": 0.5, "hemispherical": 1.0}

Definition at line 64 of file outflow.py.

◆ LS_CONSTANT

float engine.layerx.diag.outflow.LS_CONSTANT = 0.69

Definition at line 59 of file outflow.py.

◆ LS_SOURCE

tuple engine.layerx.diag.outflow.LS_SOURCE
Initial value:
1= ("Lubin & Springer, 'The formation of a dip on the surface of a liquid draining from a tank', "
2 "J. Fluid Mech. 29(2) 385-390 (1967): h_c = 0.69 (Q^2/g)^(1/5), no swirl, as restated by Wollen & "
3 "Ostoich (TFAWS 2024, TFAWS24-CR-1) and as the point-sink analysis gives it (0.688); g reduced by "
4 "the buoyancy factor (1 - rho_g/rho_l) here (not from the restatement; < 0.2 % on h_c for LE4)")

Definition at line 60 of file outflow.py.

◆ MODEL_NAME

str engine.layerx.diag.outflow.MODEL_NAME = "lubin_springer_dip"

Definition at line 58 of file outflow.py.