18from typing
import Any, Optional, Sequence, Tuple
79 P_inlet_pa: Optional[Sequence[float]] =
None,
80 P_inlet_0_pa: Optional[float] =
None,
81 P_inlet_end_pa: Optional[float] =
None,
82 regulator: Optional[RegulatorModel] =
None,
83) -> Tuple[np.ndarray, np.ndarray]:
84 """Eq. (6.2): regulated outlet = setpoint + SPE x (inlet drop since t = 0).
86 The inlet history is ``P_inlet_pa`` (one value per output point, e.g. the COPV blowdown trace)
87 or, failing that, a straight line from ``P_inlet_0_pa`` to ``P_inlet_end_pa``. With no inlet
88 history there is nothing for the SPE to act on and the curve is the flat setpoint.
90 Raises RegulatorDropout when the inlet falls below outlet + ``regulator.min_differential_pa``.
91 Returns (time_s, P_tank_pa).
93 n_points =
max(2, int(n_points))
94 t = np.linspace(0.0,
max(burn_time_s, 1e-6), n_points)
95 P_set = float(P_set_pa)
98 if P_inlet_pa
is not None:
99 P_in = np.asarray(P_inlet_pa, dtype=float)
100 if P_in.shape != t.shape:
101 raise ValueError(f
"P_inlet_pa has {P_in.size} points; the curve has {t.size}")
102 elif P_inlet_0_pa
is not None and P_inlet_end_pa
is not None:
103 P_in = float(P_inlet_0_pa) + (float(P_inlet_end_pa) - float(P_inlet_0_pa)) * (t / t[-1])
105 return t, np.full_like(t, P_set)
107 P = P_set + float(reg.supply_pressure_effect) * (P_in[0] - P_in)
108 short = P_in - P < float(reg.min_differential_pa)
110 k = int(np.argmax(short))
112 f
"regulator inlet {P_in[k] / _PA_PER_PSI:.0f} psia at t = {t[k]:.2f} s is below outlet "
113 f
"{P[k] / _PA_PER_PSI:.0f} psia + minimum differential "
114 f
"{reg.min_differential_pa / _PA_PER_PSI:.0f} psi: regulation is lost")
119 initial_lox_pa: float,
120 initial_fuel_pa: float,
124 copv_pressure_pa: Optional[Sequence[float]] =
None,
125 copv_initial_pa: Optional[float] =
None,
126 copv_end_pa: Optional[float] =
None,
127 regulator: Optional[RegulatorModel] =
None,
128) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
129 """LOX and fuel regulated manifold curves for Layer 2 / the time solver.
131 Both tanks hang off the same COPV, so both see the same inlet history: ``copv_pressure_pa``
132 (a trace, one value per point) or the ``copv_initial_pa``/``copv_end_pa`` pair. Without either
133 the curves are the flat setpoints.
135 kw = dict(burn_time_s=burn_time_s, n_points=n_points, P_inlet_pa=copv_pressure_pa,
136 P_inlet_0_pa=copv_initial_pa, P_inlet_end_pa=copv_end_pa, regulator=regulator)
Tuple[np.ndarray, np.ndarray, np.ndarray] dome_regulated_tank_pair(float initial_lox_pa, float initial_fuel_pa, float burn_time_s, int n_points=200, *, Optional[Sequence[float]] copv_pressure_pa=None, Optional[float] copv_initial_pa=None, Optional[float] copv_end_pa=None, Optional[RegulatorModel] regulator=None)
Tuple[np.ndarray, np.ndarray] generate_dome_regulated_pressure_curve(float P_set_pa, *, float burn_time_s, int n_points=200, Optional[Sequence[float]] P_inlet_pa=None, Optional[float] P_inlet_0_pa=None, Optional[float] P_inlet_end_pa=None, Optional[RegulatorModel] regulator=None)