Multi-session work bundle on a draft branch. Splits into a clean
sequence of commits later; pushed here so it isn't lost on a reboot.
Reach work
- code/scripts/reach/reach_scram_pj.jl: shutdown_margin halfspace
X_exit (replaces "n <= 1e-4 AND T_f bound" framing); per-step
envelope extraction added.
- code/scripts/reach/reach_scram_pj_fat.jl: per-step envelope
extraction added; shutdown_margin discharge logic mirrored from the
tight scram script. 3 probes (10/30/60s) all discharge from the
fat union polytope.
- code/scripts/reach/reach_scram_full_fat.jl (NEW): full nonlinear
PKE scram reach with fat entry. Hits the stiffness wall at
~1.5 s plant time as expected; saves NaN-tolerant per-step
envelopes. Demonstrates concretely why PJ is the right tool for
the longer-horizon proof.
- code/scripts/reach/reach_heatup_pj.jl: T_REF_START_C constant
(entry-conditioned ramp) replaces T_STANDBY-init that was making
the FL controller command cooling at t=0. Per-step extraction
already in place.
- code/configs/heatup/tight.toml: bumped maxsteps; probe horizon
parameterized.
Hot-standby SOS barrier
- code/scripts/barrier/barrier_sos_2d_shutdown.jl (NEW): mirrors the
operation SOS machinery on the hot-standby thermal projection.
Includes the eps-slack pattern (so feasibility doesn't silently
collapse to B == 0).
- code/scripts/barrier/barrier_sos_2d.jl: refactored to use the same
helper.
- code/src/sos_barrier.jl (NEW): solve_sos_barrier_2d helper module
factoring out the SOS construction; eps-slack with eps_cap=1.0 to
avoid unbounded primal.
Library
- code/src/pke_states.jl (NEW): single source of truth for canonical
initial-condition vectors per DRC mode (op, shutdown, heatup) keyed
off plant + predicates.
- code/scripts/sim/{main_mode_sweep,validate_pj}.jl, code/CLAUDE.md:
migrated to pke_states.
Predicates + invariants
- reachability/predicates.json: new shutdown_margin predicate (1%
dk/k tech-spec floor, expressed as alpha_f*T_f + alpha_c*T_c
halfspace). Used as scram X_exit.
Plot script
- code/scripts/plot/plot_reach_tubes.jl: plot_tubes_scram_pj() with
variant=:fat|:tight knob; plot_tubes_scram_full() for full-PKE
3-panel (T_c, T_f, rho); plot_tubes_heatup_pj() reads results/
not reachability/.
Journal + memory
- journal/entries/2026-04-27-shutdown-sos-and-scram-X_exit.tex (NEW):
long-form entry on the SOS hot-standby barrier and the scram X_exit
refactor.
- journal/journal.tex: input chain updated.
- claude_memory/ — three new session notes:
* 2026-04-27-scram-X_exit-shutdown-margin.md
* 2026-04-28-DICE-2026-conference-intel.md (people, sessions,
strategic notes for the May 12 talk)
* 2026-04-28-path1-sos-pj-sketch.md (sketch of nonlinear-SOS via
polynomial multiply-through; saved for an overnight session)
Docs
- docs/model_cheatsheet.md (NEW): one-page reference of state vector,
dynamics, constants, modes, predicates, sanity numbers — the talk
prep cheatsheet Dane asked for.
- docs/figures/reach_*_tubes.png: regenerated with the new mat data.
- presentations/prelim-presentation/outline.md: revised arc per the
April-28 review pass (cuts: Lyapunov-fails standalone slide,
operation-tube standalone slide, SOS standalone; adds: scopes-of-
control framing, scram on the headline result slide).
- app/predicate_explorer.jl: minor.
Hacker-Split: end-of-session scratch bundle
8.9 KiB
PWR Plant Model Cheatsheet
Quick reference for the 10-state PKE + 3-node thermal-hydraulics model used throughout this demo.
Source of truth: code/src/pke_params.jl (constants + steady state),
code/src/pke_th_rhs.jl (dynamics), code/src/pke_th_rhs_pj.jl
(prompt-jump variant), code/controllers/controllers.jl (control laws).
All values in SI internally; printed/plotted in °F.
State vector
x = [n, C₁, C₂, C₃, C₄, C₅, C₆, T_f, T_c, T_cold] (10 states)
| Symbol | Index | Meaning | Units |
|---|---|---|---|
| n | 1 | Normalized neutron population (n=1 ⇔ full power) | — |
| Cᵢ | 2–7 | Delayed-neutron precursor concentrations (6 groups) | — |
| T_f | 8 | Fuel-pellet bulk temperature | °C |
| T_c | 9 | Average coolant temperature in core (= T_avg) | °C |
| T_cold | 10 | Cold-leg coolant temperature | °C |
Derived (not states):
T_hot = 2·T_c − T_cold(linear coolant profile assumption)P = P₀·n(thermal power)
Inputs:
u= control input (rod-induced reactivity), units of Δk/kQ_sg(t)= bounded disturbance (steam-generator heat removal), W
Reactivity (the coupling between neutronics and thermal)
\rho(x, u) \;=\; u \;+\; \alpha_f\,(T_f - T_{f,0}) \;+\; \alpha_c\,(T_c - T_{c,0})
Three contributions:
u— externally controlled (rod motion)α_f·(T_f − T_f0)— Doppler feedback (negative; fuel heats → more U-238 absorption → less reactivity)α_c·(T_c − T_c0)— moderator-density feedback (negative; coolant heats → less moderation → less reactivity)
Both feedback coefficients are negative — the plant is self-stabilizing.
ODE system (full 10-state)
Neutronics (Point-Kinetic Equations)
\frac{dn}{dt} \;=\; \frac{\rho - \beta}{\Lambda}\,n \;+\; \sum_{i=1}^{6} \lambda_i C_i
\frac{dC_i}{dt} \;=\; \frac{\beta_i}{\Lambda}\,n \;-\; \lambda_i C_i \qquad (i = 1, \ldots, 6)
The first equation has a stiff coefficient 1/Λ ≈ 10⁴ s⁻¹ — this is what makes the full plant unverifiable by direct nonlinear reach.
Thermal-hydraulics (3 lumped nodes)
\frac{dT_f}{dt} \;=\; \frac{P_0\,n \;-\; hA\,(T_f - T_c)}{M_f\,c_f}
\frac{dT_c}{dt} \;=\; \frac{hA\,(T_f - T_c) \;-\; 2\,W\,c_c\,(T_c - T_{\text{cold}})}{M_c\,c_c}
\frac{dT_{\text{cold}}}{dt} \;=\; \frac{2\,W\,c_c\,(T_c - T_{\text{cold}}) \;-\; Q_{sg}}{M_{sg}\,c_c}
Physical chain: fission heat → fuel → coolant → cold leg → SG → back to cold leg.
The factor of 2 in 2·W·c_c·(T_c − T_cold) comes from the linear-profile
assumption: the enthalpy carried by flow at avg T_c from inlet T_cold
to outlet T_hot = 2T_c − T_cold is W·c_c·(T_hot − T_cold) = 2·W·c_c·(T_c − T_cold).
Prompt-jump (PJ) reduction
Set dn/dt = 0 and solve algebraically for n:
n(x) \;=\; \frac{\Lambda \sum_i \lambda_i C_i}{\beta - \rho(x, u)}
State drops 10 → 9 (drop n; reconstruct it from C and ρ). Stiffness gone.
Validity condition: β − ρ > 0 with margin (encoded as the
prompt_critical_margin_* halfspace per mode).
Tikhonov bound: |x(t) − x_PJ(t)| ≤ C·Λ = O(10⁻⁴) — characterized
residual error vs the 10-state plant.
Constants
Neutronics (6-group point-kinetic)
| Symbol | Value | Meaning |
|---|---|---|
| Λ | 1×10⁻⁴ s |
Prompt-neutron generation time |
| β = Σβᵢ | 0.006502 |
Total delayed-neutron fraction (sum of 6 groups) |
| β₁..β₆ | [0.000215, 0.001424, 0.001274, 0.002568, 0.000748, 0.000273] |
Per-group delayed fractions |
| λ₁..λ₆ | [0.0124, 0.0305, 0.111, 0.301, 1.14, 3.01] s⁻¹ |
Precursor decay constants |
(Standard 6-group U-235 thermal-fission values from Keepin.)
Thermal-hydraulic
| Symbol | Value | Meaning |
|---|---|---|
| P₀ | 1×10⁹ W |
Rated thermal power (1 GWth) |
| M_f | 50 000 kg |
Fuel mass (lumped) |
| c_f | 300 J/(kg·K) |
Fuel specific heat |
| M_c | 20 000 kg |
Core coolant mass |
| c_c | 5 450 J/(kg·K) |
Coolant specific heat |
| hA | 5×10⁷ W/K |
Fuel-to-coolant heat-transfer coefficient |
| W | 5 000 kg/s |
Primary coolant mass flow rate |
| M_sg | 30 000 kg |
Steam-generator coolant inventory |
Reactivity feedback coefficients (linearized about full-power op point)
| Symbol | Value | Meaning |
|---|---|---|
| α_f | −2.5×10⁻⁵ /°C |
Fuel/Doppler temperature coefficient |
| α_c | −1×10⁻⁴ /°C |
Moderator/coolant temperature coefficient |
These are linear slopes about the full-power operating point. Trust range: ~±50 °C around T_f0/T_c0. Cold-shutdown extrapolation breaks.
Derived steady-state (full-power equilibrium)
Single free parameter: T_cold0 = 290 °C (full-power cold-leg temp).
Everything else falls out of energy balance:
| Quantity | Derivation | Value |
|---|---|---|
| ΔT_core | P₀ / (W·c_c) |
36.7 °C |
| T_hot0 | T_cold0 + ΔT_core |
326.7 °C |
| T_c0 (= T_avg0) | (T_hot0 + T_cold0) / 2 |
308.35 °C |
| T_f0 | T_c0 + P₀/hA |
328.35 °C |
| n₀ | (definition) | 1.0 |
| C_i0 | βᵢ·n₀ / (λᵢ·Λ) |
(from dC/dt = 0) |
Hot-standby reference
| Quantity | Derivation | Value |
|---|---|---|
| T_standby | T_c0 − 33.33 °C (= T_c0 − 60 °F) |
275.02 °C |
This is the canonical "hot standby" operating point — coolant warm but power below criticality. Defined as a 60 °F offset below full-power T_avg.
Per-mode controllers
| Mode | Control law | Constants | Notes |
|---|---|---|---|
q_shutdown |
u = −5β (constant rod) |
— | Open-loop rod-held |
q_heatup |
u = K_p·(T_ref(t) − T_c) (FL/proportional) |
K_p = 1×10⁻⁴ |
T_ref ramps from T_standby at 28 °C/hr (tech-spec heatup limit) |
q_operation (P) |
u = K_p·(T_avg_ref − T_avg) |
K_p ≈ 1×10⁻⁴ |
Simple proportional T_avg tracker |
q_operation (LQR) |
u = −K_LQR·δx |
gain solved from Riccati | Cached in factory closure |
q_scram |
u = −8β (constant rod, max insertion) |
— | Open-loop rod-held; full negative reactivity |
Heatup ramp rate: dT_ref/dt = 28/3600 ≈ 0.00778 °C/s (28 °C/hr — US PWR tech-spec maximum heatup rate, set by vessel thermal-stress limits).
Key predicates / halfspaces (used by reach analysis)
From reachability/predicates.json:
| Predicate | Concretization | What it discharges |
|---|---|---|
t_avg_above_min |
T_c ≥ T_standby + 5.556 °C (= 280.58 °C) |
Shutdown→heatup transition trigger |
t_avg_in_range |
|T_c − T_c0| ≤ 2.78 °C (= [305.57, 311.13]) |
Heatup→operation transition trigger |
p_above_crit |
n ≥ 1×10⁻⁴ |
"Reactor at-or-above critical" (also part of heatup→operation) |
fuel_centerline |
T_f ≤ 1200 °C |
UO₂ melt prevention |
t_avg_high_trip |
T_c ≤ 320 °C |
Reactor trip limit |
t_avg_low_trip |
T_c ≥ 280 °C |
Reactor trip limit |
n_high_trip |
n ≤ 1.15 |
High-flux trip (118% nominal) |
cold_leg_subcooled |
T_cold ≤ T_cold0 + 15 = 305 °C |
Subcooling margin |
heatup_rate_upper |
0.4587·T_f − 0.9587·T_c + 0.5·T_cold ≤ 0.01389 °C/s |
Coolant heatup ≤ 50 °C/hr (28 + overshoot) |
heatup_rate_lower |
(mirror, lower bound) | Cooldown ≤ 50 °C/hr |
prompt_critical_margin_* |
β − ρ ≥ δ (per-mode form) |
PJ reduction validity |
shutdown_margin |
α_f·T_f + α_c·T_c ≤ 0.00297 |
Scram success: rho ≤ −0.01 (1% Δk/k) |
The dT_c/dt halfspace coefficients above come from differentiating
the T_c ODE: a_f = hA/(M_c·c_c) = 0.4587 /s,
a_c = −(hA + 2W·c_c)/(M_c·c_c) = −0.9587 /s,
a_cold = 2W·c_c/(M_c·c_c) = 0.5 /s. Sums to zero by equilibrium.
Per-mode obligations
| Mode | Kind | Obligation |
|---|---|---|
q_shutdown |
equilibrium | Stay in X_safe forever; transition out when t_avg_above_min becomes true |
q_heatup |
transition | From X_entry, reach X_exit within [T_min=7714, T_max=18000] s, maintain inv1_holds |
q_operation |
equilibrium | Stay in X_safe forever under bounded Q_sg |
q_scram |
transition | From any state, drive to shutdown_margin within T_max=60 s, maintain bounded T |
inv1_holds (heatup safety invariant) = conjunction of fuel_centerline,
cold_leg_subcooled, heatup_rate_upper, heatup_rate_lower,
prompt_critical_margin_heatup.
Sanity numbers (to memorize before the talk)
| Quantity | Value |
|---|---|
| Full-power n | 1.0 |
| Full-power T_avg | 308 °C ≈ 587 °F |
| Hot-standby T_avg | 275 °C ≈ 527 °F |
| Heatup span (standby → operation) | 33 °C ≈ 60 °F |
| Tech-spec heatup rate | 28 °C/hr |
| Nominal heatup time | 33 / 28 = 1.19 hr ≈ 71 min |
| T_min (heatup obligation) | 7 714 s = 2 hr 8 min |
| T_max (heatup obligation) | 18 000 s = 5 hr |
| Stiffness ratio (full plant) | ~10⁵ (Λ⁻¹ ÷ thermal time-constant) |
| Scram rod worth | −8β = −0.052 Δk/k (~5% subcritical) |
| Shutdown-margin requirement | |ρ| ≥ 0.01 = 1% Δk/k |