STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
closure.py
Go to the documentation of this file.
1"""Closure logic: solve branch flows with spray constraints.
2
3The impinging branch routes through the accelerator (engine/accel) when enabled
4(the default). The Python injector models below run for everything it doesn't
5cover — pintle, coaxial, a missing numba, or ``ED_ACCEL=off``. Dispatch is pure
6capability routing: ``accel.solve`` returns ``None`` for any config it can't
7handle and the Python model runs.
8
9This native fast-path matters for performance even with the Layer-1 single-call
10``ed_evaluate`` seam: ~30% of CMA candidates don't converge in the single-call native
11path and fall back to ``runner.evaluate`` → ``chamber_solver`` → here, whose Brent
12residual solves the injector many times. Keeping that native keeps the fallback fast.
13
14Accelerator↔Python parity is enforced by tests/test_numba_ab_parity.py, which
15diffs both live on the same inputs — there is no runtime self-check.
16"""
17
18import os
19from typing import Tuple, Dict, Any, Optional
20
21from engine.pipeline.config_schemas import PintleEngineConfig
22from engine.core.injectors import get_injector_model
23
24# Warm the JIT on import so the first evaluation does not pay compile/load cost.
25try:
26 from engine import accel as _accel
27 if _accel.enabled():
28 _accel.warmup()
29except Exception: # pragma: no cover - never let warmup break import
30 pass
31
32
34 P_tank_O: float,
35 P_tank_F: float,
36 Pc: float,
37 config: PintleEngineConfig,
38) -> Optional[Tuple[float, float, Dict[str, Any]]]:
39 """Accelerated (mdot_O, mdot_F, diagnostics), or None if the accelerator is
40 disabled or can't handle this config (caller falls back to the Python model).
41
42 Parity is enforced by the A/B suite, not a runtime self-check (capability
43 dispatch). Strict mode (``ED_REQUIRE_ACCEL=1``, the CI
44 parity job) makes a *genuine* accelerator failure raise instead of silently
45 falling back to Python, which would report a false green. A config the kernel
46 simply doesn't handle (``solve`` returns None) still falls back quietly.
47 """
48 from engine import accel
49 if not accel.enabled():
50 if accel.require():
51 raise RuntimeError("strict mode set but the accelerator is not enabled/available")
52 return None
53 return accel.solve(config, P_tank_O, P_tank_F, Pc)
54
55
57 P_tank_O: float,
58 P_tank_F: float,
59 Pc: float,
60 config: PintleEngineConfig,
61) -> Tuple[float, float, Dict[str, Any]]:
62 """Solve injector branch flows: returns (mdot_O, mdot_F, diagnostics)."""
63 native = _try_native_flows(P_tank_O, P_tank_F, Pc, config)
64 if native is not None:
65 return native
66 return get_injector_model(config).solve(P_tank_O, P_tank_F, Pc)
Tuple[float, float, Dict[str, Any]] flows(float P_tank_O, float P_tank_F, float Pc, PintleEngineConfig config)
Definition closure.py:61
Optional[Tuple[float, float, Dict[str, Any]]] _try_native_flows(float P_tank_O, float P_tank_F, float Pc, PintleEngineConfig config)
Definition closure.py:38