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

Functions

Path canonical_config_path (str injector_type)
Dict[str, Any] load_canonical_config (str injector_type)
list available_injectors ()
list available_propellants ()
Dict[str, Any] apply_injector_type (Dict[str, Any] config, str injector_type, *, bool keep_declared_cd=False)
Dict[str, Any] apply_propellant (Dict[str, Any] config, str preset_name)
Dict[str, tuple] _preset_fluid_names ()
Optional[str] infer_preset_from_fluids (Optional[Dict[str, Any]] config)
Dict[str, Any] derive_chamber_gas (Dict[str, Any] config)
None _stamp_propellant_change (Dict[str, Any] cfg, Optional[str] old_preset, str new_preset, Optional[str] inj_type)
Dict[str, Any] _carry_design_intent (Dict[str, Any] old, Dict[str, Any] cfg)
Dict[str, Any] _carry_custom_propellant (Dict[str, Any] old, Dict[str, Any] cfg)
Dict[str, Any] switch_config (Dict[str, Any] config, *, Optional[str] injector_type=None, Optional[str] propellant_preset=None)
Optional[str] design_staleness (Any config)
Optional[str] chamber_staleness (Any config)
Dict[str, Any] _preset_fluids (str name)
Optional[str] preset_fluid_drift (Any config)

Variables

 _log = logging.getLogger(__name__)
 _PROJECT_ROOT = Path(__file__).resolve().parents[2]
str _CANONICAL_DIR = _PROJECT_ROOT / "configs" / "canonical"
float CHAMBER_GAS_REFERENCE_PC_PSI = 430.0
tuple _DESIGN_INTENT_KEYS
float _FLUID_DRIFT_REL = 0.05

Detailed Description

Live config switching for injector type & propellant (UNIFICATION_PLAN Phase 6 — UI exposure).

The goal: injector type and propellant are FIRST-CLASS toggles in the UI, not buried in YAML. When the
user flips either, the config must auto-reconcile to the RIGHT physics:
  * injector type -> LOAD THE CANONICAL CONFIG for that type WHOLESALE (configs/canonical/<type>.yaml).
    The two canonical configs are independent, proven starting guesses that deliberately do NOT stay
    in sync — pintle carries fixed Cd 0.40/0.65 (main physics), impinging carries geometry-Cd 0.60
    (fork physics). Switching types means "load a whole new config with different values for
    everything", which is the point: the Cd that converges for a pintle annulus is nonsense for a
    doublet jet, so each type owns its own coherent block. (apply_injector_type below is the legacy
    in-place patcher, kept for same-type reconciliation and back-compat.)
  * propellant    -> overlay the preset's fluids + CEA identity (preset WINS here — this is a switch,
    not a load-time merge, so stale fluid/CEA values are replaced, not preserved). Cheaper than an
    injector switch: it just autofills propellant identity onto the current geometry.

When a switch leaves the chamber geometry seeded for a different injector/propellant than is now live,
we STAMP design_valid_for and forward mode warns ("needs re-optimization") rather than silently
trusting a stale chamber (design_staleness).

Operates on plain dicts so it composes with the config router's merge/validate flow.

Function Documentation

◆ _carry_custom_propellant()

Dict[str, Any] engine.pipeline.config_switch._carry_custom_propellant ( Dict[str, Any] old,
Dict[str, Any] cfg )
protected
A "custom" propellant has no preset to re-apply: carry its fluids, CEA identity and chamber
gas verbatim, and stamp the canonical's own propellant so the seed reads as stale.

Definition at line 359 of file config_switch.py.

Referenced by switch_config().

◆ _carry_design_intent()

Dict[str, Any] engine.pipeline.config_switch._carry_design_intent ( Dict[str, Any] old,
Dict[str, Any] cfg )
protected
Copy the user's own requirements (thrust, burn time, envelope, tank caps) from the pre-swap
config onto the freshly loaded canonical, and keep its burn-time slots in step.

Definition at line 340 of file config_switch.py.

Referenced by switch_config().

◆ _preset_fluid_names()

Dict[str, tuple] engine.pipeline.config_switch._preset_fluid_names ( )
protected
{preset: (canonical oxidizer name, canonical fuel name)} for every shipped preset.

Definition at line 222 of file config_switch.py.

References available_propellants().

Referenced by infer_preset_from_fluids().

◆ _preset_fluids()

Dict[str, Any] engine.pipeline.config_switch._preset_fluids ( str name)
protected

Definition at line 477 of file config_switch.py.

Referenced by preset_fluid_drift().

◆ _stamp_propellant_change()

None engine.pipeline.config_switch._stamp_propellant_change ( Dict[str, Any] cfg,
Optional[str] old_preset,
str new_preset,
Optional[str] inj_type )
protected
A propellant overlay keeps the EXISTING chamber geometry, which was seeded for the previous
propellant. If the propellant actually changed, record that prior {injector, propellant} as the
design's provenance so forward mode flags the chamber as stale (needs re-optimization). Does not
clobber an existing stamp (the chamber's true provenance is the FIRST mismatch, not the latest).

Definition at line 319 of file config_switch.py.

Referenced by apply_propellant().

◆ apply_injector_type()

Dict[str, Any] engine.pipeline.config_switch.apply_injector_type ( Dict[str, Any] config,
str injector_type,
* ,
bool keep_declared_cd = False )
Switch injector type IN PLACE-ish (returns new dict): replace geometry with the type template
(preserve existing geometry only if the type is unchanged), then set the physics bindings.

``keep_declared_cd``: on a SAME-type call, fill only the discharge keys the config leaves out
and never overwrite one it declares. The live switch path uses it (DEF-04). The load path
(io.load_config) still re-stamps, because three shipped methalox configs carry hand-written
Cd values that have only ever been evaluated after that overwrite.

Definition at line 78 of file config_switch.py.

Referenced by switch_config().

◆ apply_propellant()

Dict[str, Any] engine.pipeline.config_switch.apply_propellant ( Dict[str, Any] config,
str preset_name )
Switch propellant: overlay the preset's fluids + CEA IDENTITY (preset wins — replaces stale
fluid names / CEA names from the previous propellant). Design-owned CEA fields (expansion_ratio,
ranges, n_points, cache_file) and everything else are preserved from the current config.

Definition at line 146 of file config_switch.py.

References _stamp_propellant_change(), derive_chamber_gas(), and infer_preset_from_fluids().

Referenced by switch_config().

◆ available_injectors()

list engine.pipeline.config_switch.available_injectors ( )

Definition at line 68 of file config_switch.py.

◆ available_propellants()

list engine.pipeline.config_switch.available_propellants ( )

Definition at line 73 of file config_switch.py.

Referenced by _preset_fluid_names().

◆ canonical_config_path()

Path engine.pipeline.config_switch.canonical_config_path ( str injector_type)
Path to the canonical starting config for an injector type (validates the type).

Definition at line 39 of file config_switch.py.

Referenced by load_canonical_config().

◆ chamber_staleness()

Optional[str] engine.pipeline.config_switch.chamber_staleness ( Any config)
The "needs re-optimization" half of design_staleness: a sentence when the live
injector/propellant no longer match what the chamber geometry was solved/seeded for
(design_valid_for stamp), else None. Fluid drift is not part of it -- the chamber is still
the right one; the properties want refreshing (preset_fluid_drift).

Definition at line 444 of file config_switch.py.

Referenced by design_staleness().

◆ derive_chamber_gas()

Dict[str, Any] engine.pipeline.config_switch.derive_chamber_gas ( Dict[str, Any] config)
Set spray.smd.chamber_gas_R/T from the CEA table at the design's O/F and target Pc.

The Ingebo Weber number and the evaporation model read one representative chamber gas; a
preset stamps it at the preset's own O/F, which is wrong as soon as the target moves (DEF-11:
3094 K at O/F 1.35 against 3225 K at 1.5). Leaves the config unchanged -- and says so -- when
the table is not on disk (never triggers a multi-minute CEA build from a UI toggle) or the
point lies outside it.

Definition at line 260 of file config_switch.py.

Referenced by apply_propellant(), and switch_config().

◆ design_staleness()

Optional[str] engine.pipeline.config_switch.design_staleness ( Any config)
Return a human-readable warning if the live injector/propellant no longer match what the
chamber geometry was solved/seeded for (chamber_staleness), or if the fluid properties
differ from the propellant preset's (preset_fluid_drift), else None. Accepts a dict or a
PintleEngineConfig. This is the design warning forward mode shows.

Definition at line 435 of file config_switch.py.

References chamber_staleness(), and preset_fluid_drift().

◆ infer_preset_from_fluids()

Optional[str] engine.pipeline.config_switch.infer_preset_from_fluids ( Optional[Dict[str, Any]] config)
The preset whose oxidizer and fuel a preset-less config carries; "custom" when its fluids
match no preset; None when it has no fluids at all.

Definition at line 237 of file config_switch.py.

References _preset_fluid_names().

Referenced by apply_propellant(), and switch_config().

◆ load_canonical_config()

Dict[str, Any] engine.pipeline.config_switch.load_canonical_config ( str injector_type)
Load the canonical starting config for ``injector_type`` as a fully-resolved dict.

Uses the real loader (io.load_config) so the propellant preset is merged exactly as a normal
load would — fluids/CEA identity included — then stamps design_valid_for to this config's own
{injector, propellant} so a fresh canonical load is NOT flagged stale (it is internally coherent).
Lazy import of io avoids an import cycle (io has no dependency on this module).

Definition at line 45 of file config_switch.py.

References canonical_config_path().

Referenced by switch_config().

◆ preset_fluid_drift()

Optional[str] engine.pipeline.config_switch.preset_fluid_drift ( Any config)
A sentence when the config's fluid properties differ from its propellant preset's, else None.

An explicit ``fluids`` block wins over the preset on load (io._deep_merge_preset), so a design
saved before the preset was corrected keeps the old numbers silently. The ethalox preset fixed
LOX cp 2300 -> 1700, bulk modulus 1.5e9 -> 0.94e9 and viscosity 1.8e-4 -> 2.0e-4 J/(kg K), Pa,
Pa s against CoolProp; every ethalox config here (and the LE4 (3) stand's engine) still carries
the old block. Forward performance hardly moves (6870.29 -> 6870.31 N on the stand at 578 psia)
but the stability numbers do: chug gate 1.445 -> 1.420, LOX water hammer 3182 -> 2561 psi,
line quarter-wave 2697 -> 2170 Hz. A measured value may well differ on purpose, so this only
says so; it changes nothing.

Definition at line 486 of file config_switch.py.

References _preset_fluids().

Referenced by design_staleness().

◆ switch_config()

Dict[str, Any] engine.pipeline.config_switch.switch_config ( Dict[str, Any] config,
* ,
Optional[str] injector_type = None,
Optional[str] propellant_preset = None )
Apply an injector and/or propellant switch to a config dict and return the reconciled dict.
Caller validates (PintleEngineConfig(**result)) and stores.

Injector change => LOAD THE CANONICAL config for the new type wholesale (the two configs are
intentionally independent -- see module docstring), then put back what the user chose: the
propellant (named, or read off the fluids -- DEF-02: picking Doublet used to turn an ethalox
design into methalox), the O/F target when it lies inside the new CEA table, and the design
intent in _DESIGN_INTENT_KEYS. A same-type request re-stamps the bindings without touching a
declared Cd. Propellant change => overlay the preset onto whatever geometry is now live.

Definition at line 388 of file config_switch.py.

References _carry_custom_propellant(), _carry_design_intent(), apply_injector_type(), apply_propellant(), derive_chamber_gas(), infer_preset_from_fluids(), and load_canonical_config().

Variable Documentation

◆ _CANONICAL_DIR

str engine.pipeline.config_switch._CANONICAL_DIR = _PROJECT_ROOT / "configs" / "canonical"
protected

Definition at line 36 of file config_switch.py.

◆ _DESIGN_INTENT_KEYS

tuple engine.pipeline.config_switch._DESIGN_INTENT_KEYS
protected
Initial value:
1= (
2 "target_thrust", "target_burn_time", "target_apogee", "target_chamber_pressure_psi",
3 "max_chamber_outer_diameter", "max_nozzle_exit_diameter", "max_engine_length",
4 "max_chamber_length_m", "max_lox_tank_pressure_psi", "max_fuel_tank_pressure_psi",
5)

Definition at line 333 of file config_switch.py.

◆ _FLUID_DRIFT_REL

float engine.pipeline.config_switch._FLUID_DRIFT_REL = 0.05
protected

Definition at line 474 of file config_switch.py.

◆ _log

engine.pipeline.config_switch._log = logging.getLogger(__name__)
protected

Definition at line 34 of file config_switch.py.

◆ _PROJECT_ROOT

engine.pipeline.config_switch._PROJECT_ROOT = Path(__file__).resolve().parents[2]
protected

Definition at line 35 of file config_switch.py.

◆ CHAMBER_GAS_REFERENCE_PC_PSI

float engine.pipeline.config_switch.CHAMBER_GAS_REFERENCE_PC_PSI = 430.0

Definition at line 257 of file config_switch.py.