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

Classes

class  SetpointRequest
class  _State

Functions

Tuple[float, str] target_thrust (Any config, SetpointRequest request)
Tuple[Optional[float], str] design_of_ratio (Any config, Any request)
Dict[str, Any] figures (Dict[str, Any] res, Optional[float] lockup_psia)
Dict[str, Any] _row (str key, str label, str group, Optional[float] value, Optional[float] limit, str direction, str unit, str basis, str hint, *, Optional[float] warn=None, bool soft=False)
List[Dict[str, Any]] _fallback_limits (Dict[str, Any] res, Any prep, Any config, Dict[str, Any] grading)
Tuple[List[Dict[str, Any]], str] grade_limits (Dict[str, Any] res, Any prep, Any config, Dict[str, Any] grading)
Optional[float] _dome_per_1000psi_fill (Any prep, float lockup_psia, float fill_psig)
Dict[str, Optional[str]] _stand_ids (Any prep)
Dict[str, Any] burn_point (Dict[str, Any] args)
bool usable (Optional[Dict[str, Any]] p)
bool feasible (Optional[Dict[str, Any]] p)
Optional[float] _fit_slope (Sequence[Tuple[float, float]] points)
Dict[str, Any] solve (Evaluate evaluate, *, float start_lockup, float start_fill, float max_fill, float target, SetpointRequest request, Tuple[float, float] bounds, Optional[float] first_guess=None, Progress say=lambda s, None f, Callable[[], bool] cancelled=lambda:False, Optional[List[Dict[str, Any]]] seed=None)
List[Dict[str, Any]] _binding_estimate (List[Dict[str, Any]] history, Dict[str, Any] final, float target)
Dict[str, Any] _model_block (float target, str target_source, SetpointRequest request, Dict[str, Any] start, float max_fill, Optional[float] design_of, str of_source)
List[Dict[str, Any]] _changes (Dict[str, Any] before, Dict[str, Any] final, Dict[str, Any] start, int history_n)
float lockup_ceiling_psia (Dict[str, Any] derived)
Dict[str, Any] run_setpoint (Any config, Any drawing, Any settings, List[Any] overrides, SetpointRequest request, *, Optional[Progress] progress=None, Callable[[], bool] cancelled=lambda:False, Optional[int] workers=None, Optional[Evaluate] evaluate=None, Optional[Dict[str, float]] stand=None)

Variables

float PSI = 6894.757293168361
 Progress = Callable[[str, float], None]
float D_SPARE_D_FILL_GUESS = 1.0
float D_THRUST_D_FILL_GUESS = 0.0
float MAX_LOCKUP_STEP = 0.15
list UNMEASURED
 Evaluate = Callable[[List[Tuple[float, Optional[float], bool]]], List[Dict[str, Any]]]

Detailed Description

Set point: the dome dial, lockup and bottle fill that give a target mean thrust.

The old optimiser searched lockup and fill for the most impulse, and the answer was always its cap:
impulse at a fixed load rises steadily with lockup (docs/layerx/AUDIT.md D6, 9.10). The operator's
question is the inverse one -- "which dome and fill give 7.2 kN, and what O/F and tank peak do I get
there" -- and it has a root, not an optimum. This solves it.

**Unknowns.** Tank lockup [psia] (the dome dial follows from it exactly: ``prepare.dome_for_lockup``
is affine in the dial) and the bottle fill [psig].

**Equations.**

1. Mean thrust of the burn (impulse over burn time, on the replay basis by default) equals the
   target, within ``thrust_tol_rel``.
2. With ``solve_fill``: the bottle over lockup at burnout lies between ``margin_psi`` and
   ``margin_psi + margin_tol_psi`` -- the least fill that keeps the margin. The band is one-sided
   (the solve aims at its middle) so an accepted fill never sits under the margin the shared
   limit grades ``bottle_margin`` against.

**Method.** Every point is a whole Layer X burn with the rail's settings: no surrogate, and the
answer is the last burn, never an interpolation.

* Lockup alone (fill held): the current settings and a proportional first guess burn in parallel,
  then Newton steps whose slope is the least-squares slope of mean thrust against lockup over the
  burns so far (with two burns this is the secant method; Press et al., *Numerical Recipes*, 3rd ed.,
  2007, sec. 9.2). On LE4 thrust is linear in lockup (10.0-10.2 N/psi, AUDIT 9.10 3.2), so this is
  three burns.
* Then lockup and fill together: Broyden's method (C. G. Broyden, "A class of methods for solving
  nonlinear simultaneous equations", *Mathematics of Computation* 19(92), 577-593, 1965). Its first
  Jacobian takes the lockup column from the burns above (measured) and the fill column from a stated
  assumption (spare rises 1 psi per psi of fill; fill does not move mean thrust), then each burn
  updates it.

**What it cannot do.** One dome regulator presses both tanks, so the set point cannot move O/F
(AUDIT 9.10 3.1: -0.087 % over 578-625 psia). It reports O/F and its offset from a stated design
O/F and points at Hardware mode (holes, line resistance, a trim orifice). Fuel lead is not modelled:
both mains open together at Fire (AUDIT 9.10 3.6).

**Limits.** Every burn is graded with the shared limits (``engine.layerx.diag.limits.grade`` when it
exists; until then a fallback built on ``optimize.grade`` plus each tank's peak against its MAWP, its
MEOP when given, and the design's cap), and a vessel trip ends the burn and fails it. The set point
is a root, not a search, so a limit does not bend the answer: a solution that breaks one is reported
as infeasible with the lockup where the binding limit is reached (linear through the burns,
labelled an estimate).

Function Documentation

◆ _binding_estimate()

List[Dict[str, Any]] engine.layerx.setpoint._binding_estimate ( List[Dict[str, Any]] history,
Dict[str, Any] final,
float target )
protected
For each limit the answer breaks: the lockup where it is reached, and the mean thrust there,
linear through the burns at the answer's fill. An estimate: not burned.

Definition at line 642 of file setpoint.py.

References _fit_slope(), and usable().

Referenced by run_setpoint().

◆ _changes()

List[Dict[str, Any]] engine.layerx.setpoint._changes ( Dict[str, Any] before,
Dict[str, Any] final,
Dict[str, Any] start,
int history_n )
protected

Definition at line 705 of file setpoint.py.

Referenced by run_setpoint().

◆ _dome_per_1000psi_fill()

Optional[float] engine.layerx.setpoint._dome_per_1000psi_fill ( Any prep,
float lockup_psia,
float fill_psig )
protected
d(dome dial)/d(fill) at this lockup [psi per 1000 psi], from the drawing's regulators on a copy
of the model (the burn's own model is not touched).

Definition at line 312 of file setpoint.py.

References max.

Referenced by burn_point().

◆ _fallback_limits()

List[Dict[str, Any]] engine.layerx.setpoint._fallback_limits ( Dict[str, Any] res,
Any prep,
Any config,
Dict[str, Any] grading )
protected
The limits until ``engine/layerx/diag/limits.py`` exists: ``optimize.grade``'s (bottle margin,
injector stiffness, a tank runs dry, every step solves) and each tank's peak against its MAWP and
the design's cap.

Definition at line 228 of file setpoint.py.

References _row().

Referenced by grade_limits().

◆ _fit_slope()

Optional[float] engine.layerx.setpoint._fit_slope ( Sequence[Tuple[float, float]] points)
protected
Least-squares slope through ``(x, y)``; with two points it is the secant.

Definition at line 420 of file setpoint.py.

Referenced by _binding_estimate(), run_setpoint(), and solve().

◆ _model_block()

Dict[str, Any] engine.layerx.setpoint._model_block ( float target,
str target_source,
SetpointRequest request,
Dict[str, Any] start,
float max_fill,
Optional[float] design_of,
str of_source )
protected

Definition at line 667 of file setpoint.py.

Referenced by run_setpoint().

◆ _row()

Dict[str, Any] engine.layerx.setpoint._row ( str key,
str label,
str group,
Optional[float] value,
Optional[float] limit,
str direction,
str unit,
str basis,
str hint,
* ,
Optional[float] warn = None,
bool soft = False )
protected
One limit in the contract's shape (docs/layerx/DATA-CONTRACT.md 1). ``soft``: grades warn, not bad.

Definition at line 214 of file setpoint.py.

Referenced by _fallback_limits(), and grade_limits().

◆ _stand_ids()

Dict[str, Optional[str]] engine.layerx.setpoint._stand_ids ( Any prep)
protected
The drawing ids the stand settings belong to: the dome loader (the dial), the dome-loaded
regulator (lockup), the bottle (fill).

Definition at line 334 of file setpoint.py.

Referenced by burn_point().

◆ burn_point()

Dict[str, Any] engine.layerx.setpoint.burn_point ( Dict[str, Any] args)
Burn one point, start to finish, in whatever process runs it, and grade it.

``args``: config, drawing, settings, overrides, and optionally lockup_psia, fill_psig, replay,
extra_overrides (drawing restatements for this point only), grading {margin_psi, meop_psi},
index, tag. Never raises: a failure is ``ok: False`` with the error.

Definition at line 350 of file setpoint.py.

References _dome_per_1000psi_fill(), _stand_ids(), figures(), and grade_limits().

◆ design_of_ratio()

Tuple[Optional[float], str] engine.layerx.setpoint.design_of_ratio ( Any config,
Any request )

Definition at line 143 of file setpoint.py.

Referenced by run_setpoint().

◆ feasible()

bool engine.layerx.setpoint.feasible ( Optional[Dict[str, Any]] p)

Definition at line 404 of file setpoint.py.

References usable().

Referenced by run_setpoint().

◆ figures()

Dict[str, Any] engine.layerx.setpoint.figures ( Dict[str, Any] res,
Optional[float] lockup_psia )
A burn's graded figures, flat, on the delivered (replay) basis where there is one. The keys
are the change list's (engine.layerx.diff.FIGURES).

Definition at line 155 of file setpoint.py.

References max.

Referenced by burn_point().

◆ grade_limits()

Tuple[List[Dict[str, Any]], str] engine.layerx.setpoint.grade_limits ( Dict[str, Any] res,
Any prep,
Any config,
Dict[str, Any] grading )
Every limit of one burn: the shared grade when it exists, else the fallback; plus the
request's own MEOP and the vessel trip if the shared grade did not carry them.

Definition at line 272 of file setpoint.py.

References _fallback_limits(), and _row().

Referenced by burn_point().

◆ lockup_ceiling_psia()

float engine.layerx.setpoint.lockup_ceiling_psia ( Dict[str, Any] derived)
The highest lockup the set point searches [psia]: the lowest pressure a tank trips the stand
at, as it is (``derived.tank_mawp_psi`` is absolute: ``prepare.vessel_trip``); ``inf`` when the
drawing rates no tank. It used to add the site's atmosphere on top, searching past the trip.

Definition at line 729 of file setpoint.py.

References min.

Referenced by run_setpoint().

◆ run_setpoint()

Dict[str, Any] engine.layerx.setpoint.run_setpoint ( Any config,
Any drawing,
Any settings,
List[Any] overrides,
SetpointRequest request,
* ,
Optional[Progress] progress = None,
Callable[[], bool] cancelled = lambda: False,
Optional[int] workers = None,
Optional[Evaluate] evaluate = None,
Optional[Dict[str, float]] stand = None )
The set point for ``request`` on this drawing and design.

``evaluate`` replaces the burns, and ``stand`` the preflight's readings of the drawing
(``lockup_psia``, ``fill_psig``, ``max_fill_psig``, ``reference_thrust_N``, ``mawp_cap_psia``):
both for tests, which hand it a closed-form stand.

Definition at line 736 of file setpoint.py.

References _binding_estimate(), _changes(), _fit_slope(), _model_block(), design_of_ratio(), feasible(), lockup_ceiling_psia(), max, min, solve(), target_thrust(), and usable().

◆ solve()

Dict[str, Any] engine.layerx.setpoint.solve ( Evaluate evaluate,
* ,
float start_lockup,
float start_fill,
float max_fill,
float target,
SetpointRequest request,
Tuple[float, float] bounds,
Optional[float] first_guess = None,
Progress say = lambda s,
None f,
Callable[[], bool] cancelled = lambda: False,
Optional[List[Dict[str, Any]]] seed = None )
The root, by whole burns through ``evaluate``. Pure in everything but ``evaluate``, so it is
tested against a closed-form stand.

``evaluate([(lockup, fill, replay), ...])`` burns the points (in parallel when it can) and returns
one :func:`burn_point`-shaped dict each. ``first_guess`` is the second lockup of the opening pair
(burned alongside the starting point); ``None``: proportional to the thrust missing. ``seed``: burns
already made at the starting point (Hardware mode's candidate), used instead of burning it again;
they do not count against ``max_burns``.

Definition at line 433 of file setpoint.py.

References _fit_slope(), max, min, and usable().

Referenced by run_setpoint().

◆ target_thrust()

Tuple[float, str] engine.layerx.setpoint.target_thrust ( Any config,
SetpointRequest request )
The mean thrust to reach and where it came from. Raises ``ValueError`` when there is none.

Definition at line 131 of file setpoint.py.

Referenced by run_setpoint().

◆ usable()

bool engine.layerx.setpoint.usable ( Optional[Dict[str, Any]] p)
A burn whose mean thrust can be used: it ran, passed preflight, did not trip, and reports one.

Definition at line 396 of file setpoint.py.

Referenced by _binding_estimate(), feasible(), run_setpoint(), and solve().

Variable Documentation

◆ D_SPARE_D_FILL_GUESS

float engine.layerx.setpoint.D_SPARE_D_FILL_GUESS = 1.0

Definition at line 62 of file setpoint.py.

◆ D_THRUST_D_FILL_GUESS

float engine.layerx.setpoint.D_THRUST_D_FILL_GUESS = 0.0

Definition at line 63 of file setpoint.py.

◆ Evaluate

engine.layerx.setpoint.Evaluate = Callable[[List[Tuple[float, Optional[float], bool]]], List[Dict[str, Any]]]

Definition at line 411 of file setpoint.py.

◆ MAX_LOCKUP_STEP

float engine.layerx.setpoint.MAX_LOCKUP_STEP = 0.15

Definition at line 67 of file setpoint.py.

◆ Progress

engine.layerx.setpoint.Progress = Callable[[str, float], None]

Definition at line 56 of file setpoint.py.

◆ PSI

float engine.layerx.setpoint.PSI = 6894.757293168361

Definition at line 54 of file setpoint.py.

◆ UNMEASURED

list engine.layerx.setpoint.UNMEASURED
Initial value:
1= [
2 {"key": "regulator.supply_pressure_effect", "where": "drawing PR_D supply_coefficient",
3 "why": "sets the in-burn tank rise, so the lockup for a mean thrust and the tank peak (17 psi/1000 psi "
4 "drawing vs 10 in EngineDesign's 1092 note, AUDIT D9)"},
5 {"key": "regulator.droop", "where": "drawing PR_D droop (He value is a GN2 back-fit tagged measured)",
6 "why": "moves the delivered lockup under flow and the bottle spare (AUDIT D14)"},
7 {"key": "tank.MAWP", "where": "drawing tank MAWP (1000 psi, estimated)", "why": "a limit the answer is graded on"},
8 {"key": "tank.MEOP", "where": "request meop_psi (user-stated 750 psi fuel; LOX unstated)",
9 "why": "a limit the answer is graded on (AUDIT D11)"},
10 {"key": "margin_psi", "where": "request", "why": "assumed 100 psi bottle over lockup at burnout; sets the fill"},
11 {"key": "design_requirements.target_thrust", "where": "config",
12 "why": "the target itself; the YAML says 6500 N, the stated goal is ~7.2 kN (AUDIT 9.10 6)"},
13 {"key": "design_requirements.optimal_of_ratio", "where": "config",
14 "why": "the O/F the offset is reported against (1.5 vs Forward mode's 1.523, AUDIT D12)"},
15 {"key": "nozzle_efficiency", "where": "config (0.95 schema default, no source)",
16 "why": "scales thrust directly, so the lockup for a target (AUDIT D16)"},
17 {"key": "erosion inputs (Bartz coefficient, wall O/F)", "where": "replay",
18 "why": "the replay's mean thrust carries the eroding throat (AUDIT finding 10)"},
19]

Definition at line 71 of file setpoint.py.