journal/ directory, LaTeX-based, dated entries, callout boxes for
derivations / decisions / dead ends / limitations, plus an \apass{}
macro for in-line markers when a later deep-pass is needed.
Retroactive A-style entries for 2026-04-17 (controllers, linearization,
LQR, operation-mode linear reach, Lyapunov barrier) and 2026-04-20
(predicates restructure into deadbands+safety+invariants, OL-vs-CL
barrier analysis, mode-obligation taxonomy, heatup-rate-as-halfspace,
mode_boundaries, first Julia nonlinear reach attempt).
Both entries include derivations written out in math, dead-ends I
hit, code snippets with commentary, figure embeds, and terminal
output where it changed what we did next. The goal is invention-log
depth — readable 4 years from now without the git history to help.
journal/README.md documents the conventions. journal.tex aggregates
all entries into one PDF via latexmk.
Kept claude_memory/ separate as per earlier agreement — those are
short AI-context notes, different audience.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
682 lines
30 KiB
TeX
682 lines
30 KiB
TeX
% ---------------------------------------------------------------------------
|
|
% 2026-04-17 — Controllers + linearization + operation-mode linear reach
|
|
% Deep / A-style invention-log entry.
|
|
% ---------------------------------------------------------------------------
|
|
|
|
\session{2026-04-17}{full afternoon, $\sim$5 hr}{Build out the three
|
|
missing DRC controllers (shutdown, heatup, scram), add a numerical
|
|
linearization, design an LQR, and discharge the operation-mode safety
|
|
obligation with a hand-rolled zonotope reach. Try a Lyapunov-ellipsoid
|
|
barrier certificate; find it fundamentally too coarse for this plant.}
|
|
|
|
\section{2026-04-17 — Controllers, linearization, operation-mode reach}
|
|
\label{sec:20260417}
|
|
|
|
\subsection*{Starting state}
|
|
|
|
Coming into this session the repository had:
|
|
\begin{itemize}
|
|
\item A 10-state PKE + thermal-hydraulics plant model
|
|
(\texttt{plant-model/pke\_th\_rhs.m}) and its parameters
|
|
(\texttt{plant-model/pke\_params.m}).
|
|
\item Two controllers: \texttt{ctrl\_null.m} (u=0 baseline) and
|
|
\texttt{ctrl\_operation.m} (plain P on $T_{\mathrm{avg}}$).
|
|
\item A FRET synthesis pipeline producing a discrete controller
|
|
(DRC) with four modes (\texttt{q\_shutdown}, \texttt{q\_heatup},
|
|
\texttt{q\_operation}, \texttt{q\_scram}) and seven transitions.
|
|
\item An empty \texttt{reachability/} directory. The thesis calls
|
|
for per-mode reach analysis; nothing has been done yet.
|
|
\end{itemize}
|
|
|
|
\subsection*{Goal}
|
|
|
|
Move the reachability thrust from zero to a first working artifact.
|
|
To do that, the continuous side needs all four modes' controllers
|
|
built out (can't reach-analyze a mode with no controller), a
|
|
linearization tool (for LQR design and for linear reach set
|
|
propagation), and a choice of reach tool. Build all that, then
|
|
discharge one mode's safety obligation.
|
|
|
|
\subsection*{Plant-model recap (what we're controlling)}
|
|
|
|
The plant is a lumped point-kinetic reactor coupled to a three-node
|
|
thermal loop. State vector $x \in \mathbb{R}^{10}$:
|
|
$$x = \bigl[\,n,\; C_1,\; C_2,\; C_3,\; C_4,\; C_5,\; C_6,\; T_f,\;
|
|
T_c,\; T_{\mathrm{cold}}\,\bigr]^\top$$
|
|
with $n$ normalized power, $C_i$ the six delayed-neutron precursor
|
|
concentrations, $T_f$ fuel temperature, $T_c$ average coolant
|
|
temperature, $T_{\mathrm{cold}}$ cold-leg coolant temperature.
|
|
Hot-leg temperature is algebraic: $T_{\mathrm{hot}} = 2T_c - T_{\mathrm{cold}}$
|
|
(linear coolant profile).
|
|
|
|
\begin{derivation}
|
|
The full RHS $\dot x = f(x, u, w)$ is:
|
|
\begin{align*}
|
|
\rho &= u + \alpha_f(T_f - T_{f0}) + \alpha_c(T_c - T_{c0}) \\
|
|
\dot n &= \frac{\rho - \beta}{\Lambda} n + \sum_{i=1}^{6} \lambda_i C_i \\
|
|
\dot C_i &= \frac{\beta_i}{\Lambda} n - \lambda_i C_i \quad (i = 1,\dots,6) \\
|
|
\dot T_f &= \frac{P_0 n - hA(T_f - T_c)}{M_f c_f} \\
|
|
\dot T_c &= \frac{hA(T_f - T_c) - 2 W c_c (T_c - T_{\mathrm{cold}})}{M_c c_c} \\
|
|
\dot T_{\mathrm{cold}} &= \frac{W c_c (T_{\mathrm{hot}} - T_{\mathrm{cold}}) - Q_{\mathrm{sg}}(t)}{M_{\mathrm{sg}} c_c}
|
|
\end{align*}
|
|
$u$ is external rod-worth reactivity (the control input).
|
|
$Q_{\mathrm{sg}}(t)$ is the steam-generator heat-removal disturbance.
|
|
All other symbols are plant constants (see
|
|
\texttt{plant-model/pke\_params.m} for sourcing; most are representative
|
|
of a 2-loop Westinghouse-class PWR).
|
|
\end{derivation}
|
|
|
|
\subsection*{Part 1: The three new controllers}
|
|
|
|
The DRC has four modes; we had only one mode's continuous controller
|
|
written. Need to fill in shutdown, heatup, and scram.
|
|
|
|
\subsubsection*{Shutdown and scram — trivial, picked for physical defensibility}
|
|
|
|
Both modes are passive: the reactor is parked deeply subcritical, rods
|
|
are fully in, no feedback control is applied. Each is a one-liner.
|
|
|
|
\begin{lstlisting}[language=Matlab,caption={\texttt{plant-model/controllers/ctrl\_shutdown.m}}]
|
|
u = -5 * plant.beta; % ~5 $ subcritical
|
|
\end{lstlisting}
|
|
|
|
\begin{lstlisting}[language=Matlab,caption={\texttt{plant-model/controllers/ctrl\_scram.m}}]
|
|
u = -8 * plant.beta; % ~8 $, typical regulatory 8-10 $ rod worth
|
|
\end{lstlisting}
|
|
|
|
\begin{decision}
|
|
Constants, not feedback laws. Rationale:
|
|
\begin{itemize}
|
|
\item Real shutdown/scram behavior is ``rods fully inserted, worth
|
|
$\sim$5--10~\$, no further action.'' A feedback law would be
|
|
un-physical.
|
|
\item Constants are trivial to reach-analyze. Closed-loop matrix
|
|
$A_{\mathrm{cl}} = A$ (controller adds nothing to dynamics).
|
|
\item At cold-start conditions ($T = T_{\mathrm{cold0}} \approx 290\,^\circ\mathrm{C}$),
|
|
the linearized feedback from $\alpha_f, \alpha_c$ is about
|
|
$+2.79\,\$$ of ``wants-to-be-supercritical'' reactivity. So
|
|
$u = -5\,\$$ gives total $\rho \approx -2.2\,\$$, comfortably
|
|
subcritical with margin for uncertainty. $-8\,\$$ on scram
|
|
gives $\sim$$-5\,\$$ total — conservative.
|
|
\item We could tighten to $-3\,\$$ and still be subcritical at
|
|
warm temperatures, but the thesis wants a safety margin
|
|
robust to any plausible state.
|
|
\end{itemize}
|
|
\end{decision}
|
|
|
|
\subsubsection*{Heatup — the interesting controller}
|
|
|
|
Heatup is the one transition mode that does real control work: drive
|
|
$T_{\mathrm{avg}}$ from hot-standby conditions up to operating
|
|
conditions while keeping the reactor bounded. This one needs design.
|
|
|
|
The structure I landed on:
|
|
\begin{equation}
|
|
u(t, x) = \mathrm{sat}\Bigl(u_{\mathrm{ff}}(x) + K_p\bigl(T_{\mathrm{ref}}(t) - T_c\bigr),\; u_{\min},\; u_{\max}\Bigr)
|
|
\end{equation}
|
|
with three ingredients:
|
|
|
|
\textbf{Feedback linearization.} Cancel the intrinsic temperature
|
|
feedback exactly:
|
|
\begin{equation}
|
|
u_{\mathrm{ff}}(x) = -\alpha_f(T_f - T_{f0}) - \alpha_c(T_c - T_{c0})
|
|
\end{equation}
|
|
so that after substitution into the $\rho$ equation,
|
|
\begin{equation}
|
|
\rho_{\mathrm{total}} = u_{\mathrm{ff}} + K_p(T_{\mathrm{ref}} - T_c) + \underbrace{\alpha_f(T_f - T_{f0}) + \alpha_c(T_c - T_{c0})}_{\text{cancels } u_{\mathrm{ff}}}
|
|
= K_p \cdot e
|
|
\end{equation}
|
|
where $e = T_{\mathrm{ref}} - T_c$. The cancellation is exact only if
|
|
the controller's $(\alpha_f, \alpha_c)$ match the plant's. This is the
|
|
seat of the controller's robustness risk; see \cref{sub:alpha-drift}.
|
|
|
|
\textbf{Ramped reference.}
|
|
\begin{equation}
|
|
T_{\mathrm{ref}}(t) = \min\bigl(T_{\mathrm{start}} + r \cdot t,\; T_{\mathrm{target}}\bigr)
|
|
\end{equation}
|
|
with $r$ = 28~\unit{\celsius/\hour} (\num{7.78e-3}~\unit{\celsius/\second}),
|
|
the tech-spec heatup rate. Clamped at $T_{\mathrm{target}}$ once the
|
|
ramp reaches operating conditions.
|
|
|
|
\textbf{Saturation on $u$.} Cap $|u|$ at $0.5\beta$ on the positive
|
|
side and $5\beta$ on the negative side. The upper cap keeps
|
|
$\rho < \beta$ (the prompt-criticality line) under any plausible
|
|
state, which bounds the neutron-kinetics excursion rate for later
|
|
reach analysis.
|
|
|
|
\begin{deadend}
|
|
\textbf{First-pass heatup controller, before saturation was added.}
|
|
The initial design was just feedback-linearization + P with no
|
|
saturation, starting from an initial condition $n = 10^{-6}$ (decay-heat
|
|
level) at $T_{\mathrm{cold0}} = 290\,^\circ\mathrm{C}$ everywhere.
|
|
|
|
What went wrong: at that cold IC, the feedback terms give about
|
|
$+2.79\,\$$ of positive reactivity. With $u_{\mathrm{ff}}$ cancelling
|
|
those, $u = K_p \cdot e$ with $K_p = \num{1e-4}$. Error grows as
|
|
$T_{\mathrm{ref}}$ ramps away from $T_c$ (which is still cold because
|
|
the reactor has no power to heat it yet). Reactivity builds slowly,
|
|
but because $n$ is tiny, power is tiny; the system takes
|
|
\textbf{about 20 minutes} to generate enough power to heat the coolant,
|
|
during which $T_c$ stays at 290~\unit{\celsius} while $T_{\mathrm{ref}}$
|
|
ramps to 297. Once power catches up, the large accumulated error
|
|
produces a power spike (visible in the first-pass figure: $n$ peaks
|
|
near $0.018 = 1.8\%$), and the thermal mass overshoots
|
|
$T_{\mathrm{target}}$ by about 7~\unit{\celsius} before the controller
|
|
pulls it back.
|
|
|
|
Why it doesn't actually match physics: real plant heatup doesn't
|
|
start from $n \approx 0$. Operators take the reactor critical at
|
|
low power \emph{in shutdown mode}, by slowly withdrawing rods, then
|
|
the DRC transitions to heatup with $n \sim 0.1\,\%$ already
|
|
established. Two fixes landed:
|
|
\begin{enumerate}
|
|
\item Saturation on $u$: prevents the accumulated-error spike.
|
|
\item Start heatup sims from a ``critical-at-low-power'' IC
|
|
($n = 10^{-3}$). \texttt{main\_mode\_sweep.m} uses this IC.
|
|
\end{enumerate}
|
|
|
|
The feedback-linearization controller alone doesn't know any of this
|
|
— it just does what the math says. The fixes are a controller design
|
|
change (saturation) and an IC assumption. A fancier heatup controller
|
|
would also include ramp-rate feedforward, but we don't need it yet.
|
|
\end{deadend}
|
|
|
|
\begin{decision}
|
|
\textbf{No integrator.} We stay with P-only (no PI), even knowing
|
|
there will be structural ramp-tracking lag on the order of
|
|
$r/K_p/\omega_{\mathrm{thermal}}$. Rationale:
|
|
\begin{itemize}
|
|
\item The plant already has strong integrators via thermal mass
|
|
($M_c c_c$, $M_{\mathrm{sg}} c_c$). PI would double-integrate.
|
|
\item PI adds state, turning the 10-state reach problem into 11 states.
|
|
Modest cost by itself.
|
|
\item The dealbreaker: \textbf{anti-windup saturation makes PI a
|
|
hybrid system}. Each saturation region (unsat / low-sat /
|
|
high-sat) is its own continuous mode with its own dynamics.
|
|
Our outer hybrid automaton is the DRC; nesting an inner hybrid
|
|
system inside each DRC mode doubles the verification
|
|
complexity.
|
|
\item The DRC exits heatup on a predicate window
|
|
(\texttt{t\_avg\_in\_range} $\wedge$ \texttt{p\_above\_crit}),
|
|
not on zero steady-state error. So the structural lag is
|
|
acceptable.
|
|
\end{itemize}
|
|
\end{decision}
|
|
|
|
Final controller (after iteration) lives in
|
|
\texttt{plant-model/controllers/ctrl\_heatup.m}. The relevant body:
|
|
|
|
\begin{lstlisting}[language=Matlab,caption={\texttt{ctrl\_heatup.m} body (abbreviated)}]
|
|
Kp = 1e-4;
|
|
T_f = x(8); T_c = x(9); T_avg = T_c;
|
|
u_ff = -plant.alpha_f*(T_f - plant.T_f0) ...
|
|
-plant.alpha_c*(T_avg - plant.T_c0);
|
|
T_ref = min(ref.T_start + ref.ramp_rate * t, ref.T_target);
|
|
e = T_ref - T_avg;
|
|
u_unsat = u_ff + Kp * e;
|
|
u = min(max(u_unsat, -5*plant.beta), 0.5*plant.beta);
|
|
\end{lstlisting}
|
|
|
|
\subsection*{Part 2: Linearization}
|
|
|
|
We need $(A, B, B_w)$ matrices for (a) LQR gain synthesis and (b)
|
|
linear reach set propagation.
|
|
|
|
\begin{derivation}
|
|
Central finite differences on $f(x, u, w)$ at a chosen operating
|
|
point $(x^\star, u^\star, w^\star)$:
|
|
\begin{align*}
|
|
A_{:,k} &\approx \frac{f(x^\star + h_k e_k, u^\star, w^\star) - f(x^\star - h_k e_k, u^\star, w^\star)}{2 h_k} \\
|
|
B &\approx \frac{f(x^\star, u^\star + h_u, w^\star) - f(x^\star, u^\star - h_u, w^\star)}{2 h_u} \\
|
|
B_w &\approx \frac{f(x^\star, u^\star, w^\star + h_w) - f(x^\star, u^\star, w^\star - h_w)}{2 h_w}
|
|
\end{align*}
|
|
with $h_k = \max(\epsilon_{\mathrm{rel}} |x^\star_k|,\; \epsilon_{\mathrm{abs}})$
|
|
to handle the wildly different magnitudes in $x$ (e.g.\ $n \sim 1$
|
|
vs.\ $C_1 \sim 10^2$ vs.\ $T_f \sim 3 \times 10^2$).
|
|
\end{derivation}
|
|
|
|
Validation: simulate the linear model and the nonlinear model in
|
|
parallel under a small $Q_{\mathrm{sg}}$ step and compare deviations
|
|
from $x^\star$. \Cref{fig:linearize-sanity} shows the result.
|
|
|
|
\begin{figure}[h]
|
|
\centering
|
|
\includegraphics[width=0.85\linewidth]{linearize_sanity.png}
|
|
\caption{Linear vs.\ nonlinear sanity check under a 5\% $Q_{\mathrm{sg}}$
|
|
down-step at $t = 30$~\unit{\second}, $u = 0$. Linear (red dashed)
|
|
tracks nonlinear (blue solid) within $4 \times 10^{-4}$ relative
|
|
error at 60~\unit{\second}, improving to $5 \times 10^{-6}$ by
|
|
300~\unit{\second} as the system relaxes. The match is best on $n$
|
|
(tightly coupled), loosest on $C_3$ (slow precursor). Eigenvalues of
|
|
$A$ span $[-65.93, -0.0124]$~\unit{\per\second} — stiffness ratio
|
|
$\sim$5000. Conclusion: linearization is quantitatively trustworthy
|
|
for perturbations around $x^\star$ in a $\pm 50\,^\circ\mathrm{C}$
|
|
window.}
|
|
\label{fig:linearize-sanity}
|
|
\end{figure}
|
|
|
|
The code is a straightforward loop (see
|
|
\texttt{plant-model/pke\_linearize.m}); nothing subtle, but the
|
|
magnitude-aware step size matters — using a uniform $h = 10^{-6}$
|
|
either loses precision on the small states or truncates on the big
|
|
ones.
|
|
|
|
\subsection*{Part 3: LQR controller for operation mode}
|
|
|
|
With $(A, B)$ in hand, design a linear quadratic regulator around the
|
|
operating point.
|
|
|
|
\begin{derivation}
|
|
Solve the continuous-time algebraic Riccati equation (CARE) for
|
|
$X \succeq 0$:
|
|
$$A^\top X + X A - X B R^{-1} B^\top X + Q = 0$$
|
|
then set gain $K = R^{-1} B^\top X$. The closed-loop control law
|
|
$u = -K(x - x^\star)$ minimizes
|
|
$$\int_0^\infty \left[(x - x^\star)^\top Q (x - x^\star) + u^\top R u\right] dt$$
|
|
and guarantees $A_{\mathrm{cl}} = A - BK$ is Hurwitz whenever $(A,B)$
|
|
is stabilizable and $Q \succeq 0$.
|
|
\end{derivation}
|
|
|
|
Weight choices:
|
|
\begin{lstlisting}[language=Matlab,caption={LQR weights, from \texttt{ctrl\_operation\_lqr.m}}]
|
|
Q = diag([1, % n
|
|
1e-3, 1e-3, 1e-3, 1e-3, 1e-3, 1e-3, % precursors C_1..C_6
|
|
1e-2, % T_f
|
|
1e2, % T_c (the primary objective)
|
|
1]); % T_cold
|
|
R = 1e6;
|
|
\end{lstlisting}
|
|
|
|
\begin{decision}
|
|
$Q(9,9) = 10^2$ for $T_c$ is the primary design knob — heavy because
|
|
we care about the coolant average deviation. Precursor weights at
|
|
$10^{-3}$ because they're informational (not directly regulated).
|
|
$T_{\mathrm{cold}}$ at 1 because it's secondary but couples to $T_c$.
|
|
$R = 10^6$ balances so $|u|$ stays in the few-cent range — below prompt,
|
|
above sensor noise. Ballpark numbers; we can retune if the reach tube
|
|
comes out too tight or too loose.
|
|
\end{decision}
|
|
|
|
Head-to-head against plain P on the same 100\% $\to$ 80\%
|
|
$Q_{\mathrm{sg}}$ step (\cref{fig:p-vs-lqr}):
|
|
|
|
\begin{figure}[h]
|
|
\centering
|
|
\includegraphics[width=0.85\linewidth]{mode_sweep_op_P_vs_LQR.png}
|
|
\caption{P vs.\ LQR on operation mode under a 100\%$\to$80\%
|
|
$Q_{\mathrm{sg}}$ step at $t = 30$~\unit{\second}. Plain P
|
|
(\texttt{ctrl\_operation.m}) has a 5~\unit{\degreeFahrenheit} peak
|
|
overshoot and 0.8~\unit{\degreeFahrenheit} steady-state lag. LQR
|
|
(\texttt{ctrl\_operation\_lqr.m}) holds $T_{\mathrm{avg}}$
|
|
essentially at setpoint throughout. Zero extra state in either;
|
|
LQR is just using all ten state measurements instead of one.}
|
|
\label{fig:p-vs-lqr}
|
|
\end{figure}
|
|
|
|
\subsection*{Part 4: Running all modes end-to-end}
|
|
|
|
\texttt{plant-model/main\_mode\_sweep.m} exercises all five controllers
|
|
(null, shutdown, heatup, operation-P, operation-LQR, scram) back-to-back
|
|
from mode-appropriate ICs, and saves figures. The normalized-power
|
|
overview (\cref{fig:power-overview}) captures the whole sweep:
|
|
|
|
\begin{figure}[h]
|
|
\centering
|
|
\includegraphics[width=0.95\linewidth]{mode_sweep_power_overview.png}
|
|
\caption{Normalized power $n(t)$ across the four DRC modes
|
|
plus baseline. \emph{Shutdown} (top left, log scale): $n$ decays
|
|
from $10^{-6}$ to $10^{-12}$ over 10~\unit{\minute}. \emph{Heatup}
|
|
(top right): small power burst around minute 22 as the reactor
|
|
goes critical and heats. \emph{Operation} (bottom left): $Q_{\mathrm{sg}}$
|
|
step at 30~\unit{\second} drops $n$ to 78\% briefly before settling
|
|
at 80\%. \emph{Scram} (bottom right, log scale): $n$ drops $1 \to 10^{-6}$
|
|
via prompt jump + delayed-neutron tail over 10~\unit{\minute}. All
|
|
four behave as textbook would predict.}
|
|
\label{fig:power-overview}
|
|
\end{figure}
|
|
|
|
\subsection*{Part 5: Tool choice for reach analysis}
|
|
|
|
Three candidate tools were evaluated:
|
|
\begin{itemize}
|
|
\item \textbf{CORA} (MATLAB) — mature, stays in the existing
|
|
language, handles linear + nonlinear. Downside: $\sim$0.5~GB
|
|
install, heavy.
|
|
\item \textbf{JuliaReach} — newer, faster for large reach sets,
|
|
rigorous Taylor-model support. Downside: requires porting
|
|
the plant model to Julia.
|
|
\item \textbf{Flow* / SpaceEx} — C++ / no-longer-maintained,
|
|
both add toolchain friction.
|
|
\end{itemize}
|
|
|
|
\begin{decision}
|
|
For this first artifact: \textbf{write the reach tube by hand in pure
|
|
MATLAB}. Rationale: linear reach with bounded disturbance has a clean
|
|
analytic form — matrix exponential on state, augmented-matrix integral
|
|
for the disturbance contribution — that compiles to about 50 lines of
|
|
MATLAB. No toolbox install, no language switch. The result is a
|
|
sound box-shaped over-approximation.
|
|
|
|
If/when we need nonlinear reach, that's the point to stand up
|
|
JuliaReach. (Spoiler for the reader: this did happen in the
|
|
\texttt{2026-04-20-evening} session.)
|
|
\end{decision}
|
|
|
|
\subsection*{Part 6: The zonotope reach propagator}
|
|
|
|
For the LQR-closed-loop linear system
|
|
$\dot{\delta x} = A_{\mathrm{cl}} \delta x + B_w w$ with $\delta x(0) \in X_0$
|
|
(axis-aligned box) and $w \in [w_{\mathrm{lo}}, w_{\mathrm{hi}}]$, the
|
|
analytic solution splits into a homogeneous piece and a disturbance
|
|
integral:
|
|
|
|
\begin{derivation}
|
|
\begin{equation}
|
|
\delta x(t) = e^{A_{\mathrm{cl}} t} \delta x(0)
|
|
+ \int_0^t e^{A_{\mathrm{cl}}(t-s)} B_w w(s)\, ds.
|
|
\end{equation}
|
|
Discretize with step $\Delta t$ and let
|
|
$A_{\Delta} = e^{A_{\mathrm{cl}} \Delta t}$. The disturbance integral
|
|
over one step is
|
|
$$G_\Delta = \int_0^{\Delta t} e^{A_{\mathrm{cl}} s} B_w \, ds.$$
|
|
\textbf{Van Loan's trick (1978):} expand the matrix exponential of an
|
|
augmented matrix,
|
|
\begin{equation}
|
|
\exp\!\left(\begin{bmatrix} A & B_w \\ 0 & 0 \end{bmatrix} \Delta t\right)
|
|
= \begin{bmatrix} e^{A \Delta t} & G_\Delta \\ 0 & 1 \end{bmatrix}.
|
|
\end{equation}
|
|
Read the upper-right block — $G_\Delta$ is exact to machine precision
|
|
without numerical quadrature.
|
|
\end{derivation}
|
|
|
|
Now propagate a box $\delta x \in [c - h,\ c + h]$ (center $c$,
|
|
halfwidth $h$) through the linear map $M$:
|
|
|
|
\begin{derivation}
|
|
If $y = M \delta x$ and $\delta x_j \in [c_j - h_j,\ c_j + h_j]$, then
|
|
$$y_i = \sum_j M_{ij} \delta x_j \quad \Longrightarrow \quad y_i \in \bigl[\,M c \mp |M| h\,\bigr]_i.$$
|
|
The $\pm$ signs of $M_{ij}$ align with opposite corners of the
|
|
input box, so the sum extremum takes the absolute value of each
|
|
coefficient times the halfwidth. Conclusion: box propagation uses
|
|
\emph{elementwise} $|M|$, not signed $M$.
|
|
\end{derivation}
|
|
|
|
\begin{deadend}
|
|
\textbf{First version of \texttt{reach\_linear.m} used signed
|
|
$A_\Delta$ for halfwidth propagation.} Result: the reach tube came
|
|
out suspiciously tight — maximum $|T_c - T_{c0}|$ over 600~\unit{\second}
|
|
was exactly equal to the initial halfwidth, as if the disturbance
|
|
wasn't contributing at all.
|
|
|
|
Diagnosed after about 15~\unit{\minute} of confusion: when I wrote
|
|
$S_{\mathrm{half}} \leftarrow A_\Delta S_{\mathrm{half}} + G_\Delta w_{\mathrm{half}}$
|
|
with \emph{signed} $A_\Delta$, the positive and negative entries of
|
|
$A_\Delta$ across successive steps happened to cancel, so
|
|
$S_{\mathrm{half}}$ stayed near zero. The fix is to use elementwise
|
|
absolute values per the derivation above:
|
|
$$S_{\mathrm{half}} \leftarrow |A_\Delta| S_{\mathrm{half}} + |G_\Delta| w_{\mathrm{half}}.$$
|
|
Once the abs was added the disturbance halfwidth grew monotonically
|
|
as expected, and the reach tube gained a sensible envelope. This is
|
|
a case of ``the bug is easy to catch in the math, harder to catch
|
|
when you copy-pasted from the center-propagation code.''
|
|
\end{deadend}
|
|
|
|
The final propagator is the core of
|
|
\texttt{reachability/reach\_linear.m} (about 50~lines). The per-step
|
|
update is compact:
|
|
|
|
\begin{lstlisting}[language=Matlab,caption={Halfwidth-propagation core of \texttt{reach\_linear.m}}]
|
|
A_step = expm(A_cl * dt);
|
|
A_abs_step = abs(A_step);
|
|
M_aug = expm([A_cl, B_w; zeros(1, n+1)] * dt);
|
|
G_step = M_aug(1:n, n+1);
|
|
G_abs_step = abs(G_step);
|
|
|
|
for k = 2:M
|
|
x_center_now = A_step * x_center_now;
|
|
halfwidth_now = A_abs_step * halfwidth_now;
|
|
S_center = A_step * S_center + G_step * w_mid;
|
|
S_half = A_abs_step * S_half + G_abs_step * w_half;
|
|
|
|
center(:, k) = x_center_now + S_center;
|
|
R_lo(:, k) = center(:, k) - halfwidth_now - S_half;
|
|
R_hi(:, k) = center(:, k) + halfwidth_now + S_half;
|
|
end
|
|
\end{lstlisting}
|
|
|
|
\subsection*{Part 7: Operation-mode reach — discharging the safety obligation}
|
|
|
|
Entry box around $x_{\mathrm{op}}$:
|
|
\begin{itemize}
|
|
\item $n$: $\pm 1\%$ of nominal.
|
|
\item $C_i$: $\pm 0.1\%$ of equilibrium (precursors equilibrate
|
|
fast; tight entry).
|
|
\item $T_f,\ T_c,\ T_{\mathrm{cold}}$: $\pm 0.1$~\unit{\kelvin}.
|
|
\end{itemize}
|
|
Disturbance: $Q_{\mathrm{sg}} \in [0.85 P_0,\ 1.00 P_0]$ — a 15\%
|
|
load-down envelope (grid-following). Horizon: 600~\unit{\second}.
|
|
|
|
The reach envelope on $T_c$ is shown in \cref{fig:reach-tc}.
|
|
|
|
\begin{figure}[h]
|
|
\centering
|
|
\includegraphics[width=0.95\linewidth]{reach_operation_Tc.png}
|
|
\caption{Operation-mode reach tube on $T_{\mathrm{avg}}$, two views.
|
|
\emph{Left:} safety-band scale — reach tube (pink) is barely visible
|
|
because LQR holds it tight against the dashed $\pm 5$~\unit{\celsius}
|
|
safety band. \emph{Right:} zoomed to reveal the actual tube.
|
|
Halfwidth at $t=0$ is 0.1~\unit{\kelvin} (the entry box);
|
|
halfwidth at $t=600$~\unit{\second} is 0.033~\unit{\kelvin}. The
|
|
tube \emph{contracts} on the regulated direction — the signature
|
|
of tight feedback control. Max $|\delta T_c|$ over the horizon:
|
|
0.1~\unit{\kelvin} (the initial halfwidth dominates).}
|
|
\label{fig:reach-tc}
|
|
\end{figure}
|
|
|
|
Per-halfspace margins against \texttt{inv2\_holds} (the operation-mode
|
|
safety envelope):
|
|
|
|
\begin{lstlisting}[style=terminal]
|
|
=== Operation-mode reach vs inv2_holds safety limits ===
|
|
[fuel_centerline] a'x <= 1200.000 | max a'x = 328.934 | margin = +871.066 OK
|
|
[t_avg_high_trip] a'x <= 320.000 | max a'x = 308.449 | margin = +11.551 OK
|
|
[t_avg_low_trip] a'x <= -280.000 | max a'x = -308.249 | margin = +28.249 OK
|
|
[n_high_trip] a'x <= 1.150 | max a'x = 1.012 | margin = +0.138 OK
|
|
[n_low_operation] a'x <= -0.150 | max a'x = -0.842 | margin = +0.692 OK
|
|
[cold_leg_subcooled] a'x <= 305.000 | max a'x = 292.852 | margin = +12.148 OK
|
|
\end{lstlisting}
|
|
|
|
All six safety halfspaces pass. Tightest margin is
|
|
\texttt{n\_high\_trip} — LQR lets $n$ swing up to $\sim$1.01 to
|
|
compensate for load variation, leaving 12\% margin to the high-flux
|
|
trip. Temperatures have 10--870~\unit{\kelvin} margin each.
|
|
\textbf{Operation-mode obligation discharged}, subject to the
|
|
linearization caveat in \cref{sec:limitations-17}.
|
|
|
|
Per-state reach-set evolution (final halfwidth vs.\ initial):
|
|
|
|
\begin{center}
|
|
\small
|
|
\begin{tabular}{l r r r}
|
|
\hline
|
|
state & init halfwidth & final halfwidth & ratio \\
|
|
\hline
|
|
$n$ & $0.010$ & $0.083$ & 8.3$\times$ expand \\
|
|
$C_1 \dots C_6$ & varies & varies & 160--200$\times$ expand \\
|
|
$T_f$ & 0.1~\unit{\kelvin} & 2.08~\unit{\kelvin} & 21$\times$ expand \\
|
|
$\boldsymbol{T_c}$ & $\mathbf{0.1}$~\unit{\kelvin} & $\mathbf{0.033}$~\unit{\kelvin} & $\mathbf{0.33\times}$ \textbf{contract} \\
|
|
$T_{\mathrm{cold}}$ & 0.1~\unit{\kelvin} & 1.47~\unit{\kelvin} & 15$\times$ expand \\
|
|
\hline
|
|
\end{tabular}
|
|
\end{center}
|
|
|
|
$T_c$ \emph{contracts} — LQR drags the regulated direction toward
|
|
setpoint faster than disturbance can push it. Uncontrolled states
|
|
drift. Precursor expansion ($\sim$$200\times$) is immaterial for
|
|
safety (no predicate uses them).
|
|
|
|
\subsection*{Part 8: Lyapunov barrier attempt}
|
|
|
|
A reach tube is a numerical certificate: compute, check. A
|
|
\emph{barrier certificate} is analytic: produce a function $B(x)$ such
|
|
that $B \leq 0$ on the initial set, $B > 0$ on the unsafe set, and
|
|
$\dot B \leq 0$ when $B = 0$. Forward-invariance of the safe set
|
|
follows from the dynamics without iterating them.
|
|
|
|
For linear systems with bounded disturbance, the canonical candidate
|
|
is a Lyapunov quadratic.
|
|
|
|
\begin{derivation}
|
|
Let $V(\delta x) = \delta x^\top P \delta x$ with $P \succ 0$ solving
|
|
$A_{\mathrm{cl}}^\top P + P A_{\mathrm{cl}} + \bar Q = 0$. Along
|
|
trajectories of $\dot{\delta x} = A_{\mathrm{cl}} \delta x + B_w w$:
|
|
\begin{align}
|
|
\dot V &= -\delta x^\top \bar Q \delta x + 2 \delta x^\top P B_w w.
|
|
\end{align}
|
|
Bound each piece. The dissipation term using the generalized
|
|
eigenvalue
|
|
$\mu = \lambda_{\min}\bigl(P^{-1/2} \bar Q P^{-1/2}\bigr)$:
|
|
$$-\delta x^\top \bar Q \delta x \leq -\mu V.$$
|
|
The disturbance kick, Cauchy-Schwarz in the $P$-metric:
|
|
$$2 \delta x^\top P B_w w \leq 2 \bar w \sqrt{B_w^\top P B_w}\sqrt{V}.$$
|
|
Combining:
|
|
$$\dot V \leq -\mu V + 2 \bar w \sqrt{B_w^\top P B_w}\sqrt{V}.$$
|
|
Set $s = \sqrt{V}$, requiring $\dot s \leq 0$:
|
|
$$s \geq \frac{2 \bar w \sqrt{B_w^\top P B_w}}{\mu}
|
|
\quad \Longleftrightarrow \quad V \geq \left(\frac{2 \bar w \sqrt{B_w^\top P B_w}}{\mu}\right)^2 =: c_{\mathrm{inv}}.$$
|
|
The sub-level set $\{ V \leq c_{\mathrm{inv}} \}$ is forward-invariant
|
|
under any admissible disturbance.
|
|
\end{derivation}
|
|
|
|
So the recipe is: solve Lyapunov, compute $c_{\mathrm{inv}}$, compute
|
|
the worst-case deviation of $T_c$ (or any linear functional of state)
|
|
on the resulting ellipsoid, and check whether it fits inside the
|
|
safety slab.
|
|
|
|
\begin{derivation}
|
|
Max of a linear functional $a^\top \delta x$ over the ellipsoid
|
|
$\{\delta x : \delta x^\top P \delta x \leq \gamma\}$:
|
|
$$\max a^\top \delta x = \sqrt{\gamma \cdot a^\top P^{-1} a}.$$
|
|
(Lagrange multipliers: the maximum is achieved at
|
|
$\delta x = \sqrt{\gamma / a^\top P^{-1} a} \cdot P^{-1} a$.)
|
|
\end{derivation}
|
|
|
|
\textbf{Result:} the best quadratic barrier — across a sweep of
|
|
$\bar Q(9,9)$ from 10 to $10^6$ — allows max $|T_c - T_{c0}| \approx 33$~\unit{\kelvin},
|
|
more than six times the 5~\unit{\kelvin} safety band. On the hard
|
|
safety halfspaces (\texttt{inv2\_holds}), it says $n$ could deviate by
|
|
$\pm 1242$~$\times$ nominal — physically meaningless.
|
|
|
|
\begin{limitation}
|
|
\textbf{The quadratic Lyapunov barrier fails on this plant. This is
|
|
a structural finding, not a tuning failure.}
|
|
|
|
The safety spec is anisotropic: a thin slab $|T_c| \leq 5$~\unit{\kelvin}
|
|
in a 10-D state space where $T_c$ is one direction and the other nine
|
|
are precursors / fuel temperature / cold-leg. Any
|
|
quadratic $V$ yields axis-uniform ellipsoidal level sets. To contain
|
|
the disturbance-driven invariant set, the ellipsoid must be \emph{fat
|
|
in the slow directions} (precursors, where Lyapunov dissipation is
|
|
weakest). Projecting that fat ellipsoid back onto $T_c$ yields a
|
|
range much larger than the physical $T_c$ behavior.
|
|
|
|
Confirmed the issue is not controller tuning by running the barrier
|
|
open-loop (no LQR): the bound becomes $\pm 27{,}000{,}000\,n$. LQR
|
|
helps by $\sim$20{,}000$\times$, but still leaves a 3-4 order-of-magnitude
|
|
gap to usability. The ceiling is plant anisotropy: prompt-neutron
|
|
timescale $\Lambda = 10^{-4}$~\unit{\second} vs.\ thermal timescales
|
|
$\sim$10--100~\unit{\second}, a factor-of-$10^4$ spread that forces
|
|
$P$ to be ill-conditioned regardless of controller design.
|
|
|
|
\textbf{Fix:} non-quadratic barrier. Two candidate approaches:
|
|
\begin{itemize}
|
|
\item \textbf{Polytopic barrier:} $B(\delta x) = \max_i (a_i^\top \delta x - b_i)$.
|
|
Piecewise-linear, can match a slab shape directly.
|
|
Requires polyhedral-set tooling.
|
|
\item \textbf{SOS polynomial barrier:} $B$ a polynomial of
|
|
degree $\geq 4$, coefficients found by sum-of-squares
|
|
optimization. Requires an SOS solver (Mosek, SDPT3).
|
|
\end{itemize}
|
|
Neither is implemented; both are in-scope for the thesis chapter.
|
|
The quadratic-Lyapunov failure, stated quantitatively, is the clean
|
|
motivation.
|
|
\end{limitation}
|
|
|
|
\subsection*{Session result}
|
|
|
|
Artifacts landing, in order:
|
|
\begin{enumerate}
|
|
\item \texttt{plant-model/controllers/ctrl\_shutdown.m},
|
|
\texttt{ctrl\_scram.m}, \texttt{ctrl\_heatup.m} (three new
|
|
controllers).
|
|
\item \texttt{plant-model/pke\_linearize.m} and
|
|
\texttt{plant-model/test\_linearize.m}.
|
|
\item \texttt{plant-model/controllers/ctrl\_operation\_lqr.m}.
|
|
\item \texttt{plant-model/main\_mode\_sweep.m}.
|
|
\item \texttt{reachability/reach\_linear.m} and
|
|
\texttt{reachability/reach\_operation.m}.
|
|
\item \texttt{reachability/barrier\_lyapunov.m}.
|
|
\item Eleven figures in \texttt{docs/figures/}.
|
|
\end{enumerate}
|
|
|
|
Key claims established:
|
|
\begin{itemize}
|
|
\item LQR closed-loop operation mode satisfies the safety obligation
|
|
under $\pm 15\%$ $Q_{\mathrm{sg}}$ variation (approximate,
|
|
via linear reach).
|
|
\item Quadratic Lyapunov barrier insufficient on this plant
|
|
(open-loop or closed-loop). Need polytopic or SOS.
|
|
\item LQR adds zero state, dominates plain P by $\sim 5\times$
|
|
on tracking.
|
|
\end{itemize}
|
|
|
|
\subsection*{Limitations recorded at close}
|
|
\label{sec:limitations-17}
|
|
|
|
\begin{limitation}
|
|
All reach results are \emph{approximate}, not sound: they are reach
|
|
tubes of the \emph{linearized} closed-loop. The linearization error
|
|
— the gap between $f_{\mathrm{nl}}(x, u)$ and $(A x + B u)$ — is not
|
|
propagated into the tube. For a real safety claim, either
|
|
(a)~nonlinear reach directly or (b)~linear reach plus Taylor-remainder
|
|
inflation. Neither is done.
|
|
\end{limitation}
|
|
|
|
\begin{limitation}
|
|
\label{sub:alpha-drift}
|
|
The feedback-linearization in \texttt{ctrl\_heatup} assumes exact
|
|
$\alpha_f, \alpha_c$. Real PWRs have $\alpha$ drift: $\sim$20\%
|
|
over burnup; $\sim$10$\times$ across soluble-boron dilution; xenon
|
|
transients worth 2--3~\$. Robust version would treat $\alpha$ as
|
|
parametric interval and propagate through reach.
|
|
\end{limitation}
|
|
|
|
\begin{limitation}
|
|
Saturation in \texttt{ctrl\_heatup} is formally a 3-mode piecewise-affine
|
|
sub-system. Operation-mode LQR is dormant-saturated (trivially); a
|
|
rigorous heatup reach would need explicit region decomposition or a
|
|
dormancy proof.
|
|
\end{limitation}
|
|
|
|
\begin{limitation}
|
|
The model's $\alpha_f, \alpha_c$ are linearized at the hot full-power
|
|
operating point. Trust region is $\pm 50$~\unit{\celsius} around $x^\star$.
|
|
True cold shutdown ($\sim$50~\unit{\celsius}) is out of scope. What
|
|
the DRC calls \texttt{q\_shutdown} we interpret as hot standby
|
|
($\sim$290~\unit{\celsius}).
|
|
\end{limitation}
|
|
|
|
\subsection*{Open at close}
|
|
|
|
\begin{itemize}
|
|
\item Nonlinear reach, at minimum on one mode, to retire the
|
|
soundness asterisk.
|
|
\item Polytopic or SOS barrier to retire the analytic-certificate
|
|
asterisk.
|
|
\item Parametric $\alpha$ uncertainty in the reach machinery.
|
|
\item Heatup reach — ramped reference needs LTV or nonlinear
|
|
treatment.
|
|
\item Shutdown + scram reach (trivial forever-invariance /
|
|
bounded-time respectively, but not yet done).
|
|
\end{itemize}
|