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
258 lines
13 KiB
JSON
258 lines
13 KiB
JSON
{
|
|
"_comment": [
|
|
"Concretization of the FRET-spec predicates AND the hard safety limits.",
|
|
"Two categories kept distinct:",
|
|
" - operational_deadbands: soft bands around setpoint used by the DRC for",
|
|
" mode transitions (t_avg_in_range etc.). Violating these does not",
|
|
" cause damage, it just triggers a mode change or operator action.",
|
|
" - safety_limits: hard one-sided halfspaces corresponding to physical",
|
|
" damage mechanisms or reactor-trip setpoints. Barrier certificates",
|
|
" and reach-set safety checks should target THESE, not the deadbands.",
|
|
"",
|
|
"The FRET-spec invariants inv1_holds, inv2_holds are concretized as the",
|
|
"conjunction of relevant safety_limits for each mode."
|
|
],
|
|
"_units": {
|
|
"temperatures": "degrees Celsius (SI, internal model units)",
|
|
"n": "normalized power, 1.0 = full power"
|
|
},
|
|
"references": {
|
|
"T_c0": "308.35 C — full-power avg coolant (from pke_params.m)",
|
|
"T_f0": "328.35 C — full-power fuel",
|
|
"T_cold0": "290.0 C — full-power cold leg",
|
|
"T_standby": "275.02 C — hot standby T_avg, defined as T_c0 - 33.33 C (= T_c0 - 60 F)"
|
|
},
|
|
"derived": {
|
|
"T_standby_offset_F": -60.0,
|
|
"T_standby_offset_C": -33.333333333,
|
|
"t_avg_in_range_halfwidth_F": 5.0,
|
|
"t_avg_in_range_halfwidth_C": 2.777777,
|
|
"t_avg_above_min_margin_F": 10.0,
|
|
"t_avg_above_min_margin_C": 5.555555,
|
|
"p_above_crit_threshold_n": 1.0e-4,
|
|
"T_fuel_limit_C": 1200.0,
|
|
"T_c_high_trip_C": 320.0,
|
|
"n_high_trip": 1.15,
|
|
"T_cold_subcooling_margin_C": 15.0
|
|
},
|
|
|
|
"operational_deadbands": {
|
|
"_comment": "Soft bands. Used by the DRC for mode switching, not for safety proofs.",
|
|
"t_avg_above_min": {
|
|
"meaning": "Coolant warmed above cold-start threshold — shutdown may transition to heatup.",
|
|
"concretization": "T_c >= T_standby + 5.556 C (hot-standby + 10 F buffer)",
|
|
"halfspaces": [
|
|
{ "state_index": 9, "coeff": -1.0, "rhs_expr": "-(T_standby + 5.556)" }
|
|
]
|
|
},
|
|
"t_avg_in_range": {
|
|
"meaning": "Average coolant in tight operating band — used for heatup->operation transition.",
|
|
"concretization": "|T_c - T_c0| <= 2.778 C (~5 F deadband)",
|
|
"halfspaces": [
|
|
{ "state_index": 9, "coeff": 1.0, "rhs_expr": "T_c0 + 2.778" },
|
|
{ "state_index": 9, "coeff": -1.0, "rhs_expr": "-(T_c0 - 2.778)" }
|
|
]
|
|
},
|
|
"p_above_crit": {
|
|
"meaning": "Reactor power in the 'power range' instrumentation regime.",
|
|
"concretization": "n >= 1e-4",
|
|
"halfspaces": [
|
|
{ "state_index": 1, "coeff": -1.0, "rhs_expr": "-1.0e-4" }
|
|
]
|
|
}
|
|
},
|
|
|
|
"safety_limits": {
|
|
"_comment": [
|
|
"Hard one-sided halfspaces. Exceeding any of these is damage or trip.",
|
|
"All are asymmetric — the plant is not equally vulnerable on both sides",
|
|
"of the setpoint. Values are representative of a 2-loop Westinghouse-",
|
|
"class PWR; calibrate to specific plant tech specs before defense."
|
|
],
|
|
"fuel_centerline": {
|
|
"meaning": "Fuel centerline temperature below design limit to prevent UO2 melt.",
|
|
"concretization": "T_f <= 1200 C (conservative; actual melt ~2800 C)",
|
|
"halfspaces": [
|
|
{ "state_index": 8, "coeff": 1.0, "rhs_expr": "1200.0" }
|
|
]
|
|
},
|
|
"t_avg_high_trip": {
|
|
"meaning": "High-T_avg reactor trip. Typical PWR: ~612-616 F = 322-324 C.",
|
|
"concretization": "T_c <= 320 C (conservative)",
|
|
"halfspaces": [
|
|
{ "state_index": 9, "coeff": 1.0, "rhs_expr": "320.0" }
|
|
]
|
|
},
|
|
"t_avg_low_trip": {
|
|
"meaning": "Low-T_avg reactor trip. Typical PWR: ~540 F = 282 C.",
|
|
"concretization": "T_c >= 280 C",
|
|
"halfspaces": [
|
|
{ "state_index": 9, "coeff": -1.0, "rhs_expr": "-280.0" }
|
|
]
|
|
},
|
|
"n_high_trip": {
|
|
"meaning": "High-flux reactor trip. Typical PWR: 118%% of rated.",
|
|
"concretization": "n <= 1.15",
|
|
"halfspaces": [
|
|
{ "state_index": 1, "coeff": 1.0, "rhs_expr": "1.15" }
|
|
]
|
|
},
|
|
"n_low_operation": {
|
|
"meaning": "Operation mode is only valid at power (avoids intermediate-range instrumentation).",
|
|
"concretization": "n >= 0.15 (15%% of rated)",
|
|
"halfspaces": [
|
|
{ "state_index": 1, "coeff": -1.0, "rhs_expr": "-0.15" }
|
|
]
|
|
},
|
|
"cold_leg_subcooled": {
|
|
"meaning": "Cold leg stays subcooled with margin against loss-of-pressure events.",
|
|
"concretization": "T_cold <= T_cold0 + 15 (roughly saturation margin at operating pressure)",
|
|
"halfspaces": [
|
|
{ "state_index": 10, "coeff": 1.0, "rhs_expr": "T_cold0 + 15.0" }
|
|
]
|
|
},
|
|
"heatup_rate_upper": {
|
|
"meaning": "Coolant heatup rate does not exceed tech-spec limit + overshoot margin.",
|
|
"concretization": "dT_c/dt = a_f*T_f + a_c*T_c + a_cold*T_cold <= 0.01389 C/s (50 C/hr; tech-spec 28 C/hr + transient overshoot budget)",
|
|
"_derivation": "dT_c/dt is linear in (T_f, T_c, T_cold) from pke_th_rhs.m: a_f=hA/(M_c*c_c)=+0.4587/s, a_c=-(hA+2*W*c_c)/(M_c*c_c)=-0.9587/s, a_cold=2*W*c_c/(M_c*c_c)=+0.5000/s. Coefficients sum to zero by construction (equilibrium when all T's equal).",
|
|
"halfspaces": [
|
|
{ "row": [[8, 0.4587], [9, -0.9587], [10, 0.5000]], "rhs_expr": "0.01389" }
|
|
]
|
|
},
|
|
"heatup_rate_lower": {
|
|
"meaning": "Coolant cooldown rate during heatup doesn't exceed -50 C/hr (flag runaway cooldown).",
|
|
"halfspaces": [
|
|
{ "row": [[8, -0.4587], [9, 0.9587], [10, -0.5000]], "rhs_expr": "0.01389" }
|
|
]
|
|
},
|
|
"prompt_critical_margin_heatup": {
|
|
"meaning": "Total reactivity stays safely below prompt-critical; keeps the prompt-jump PJ reduction valid. Per-mode specialization: for heatup with feedback linearization, rho_total = Kp*(T_ref(t) - T_c). Requiring rho <= 0.5*beta gives T_c >= T_ref - (beta - 0.5*beta)/Kp = T_ref - 32.5. Since T_ref increases monotonically from T_standby up to T_c0, the worst case is at the ramp end: T_c >= T_c0 - 32.5 = 275.85 C. Approximate as a constant halfspace with the worst-case T_ref.",
|
|
"concretization": "T_c >= 275.85 (ensures rho <= 0.5*beta under heatup FL controller)",
|
|
"halfspaces": [
|
|
{ "state_index": 9, "coeff": -1.0, "rhs_expr": "-275.85" }
|
|
],
|
|
"_note": "This is a controller-specific specialization. If the controller or its gain change, recompute. For LQR operation and constant-u scram the margin is trivially satisfied (much larger)."
|
|
},
|
|
"shutdown_margin": {
|
|
"meaning": "Total reactivity is sufficiently negative — reactor safely subcritical regardless of remaining delayed-neutron flux. The actual NRC tech-spec criterion for scram success.",
|
|
"concretization": "rho_total <= -rho_SDM with rho_SDM = 0.01 (1% dk/k, PWR tech-spec floor). With constant u = U_SCRAM = -8*beta = -0.05202 and rho = U_SCRAM + alpha_f*(T_f - T_f0) + alpha_c*(T_c - T_c0), the halfspace is: alpha_f*T_f + alpha_c*T_c <= -rho_SDM - U_SCRAM + alpha_f*T_f0 + alpha_c*T_c0. Linear halfspace in (T_f, T_c).",
|
|
"_derivation": "alpha_f = -2.5e-5/C; alpha_c = -1e-4/C; T_f0 = 328.35 C; T_c0 = 308.35 C (from pke_params: DT_CORE = P0/(W_M*C_C) = 36.7 C, so T_HOT0 = T_COLD0 + DT_CORE = 326.7, T_c0 = (T_HOT0+T_COLD0)/2 = 308.35, T_f0 = T_c0 + P0/HA = 328.35). Concrete RHS: -0.01 + 0.05202 - 0.008209 - 0.030835 = 0.002972. At nominal: LHS = -0.039, |rho| = 5.2% — huge margin over the 1% requirement.",
|
|
"halfspaces": [
|
|
{ "row": [[8, -2.5e-5], [9, -1.0e-4]], "rhs_expr": "-rho_SDM - U_SCRAM + alpha_f*T_f0 + alpha_c*T_c0" }
|
|
],
|
|
"_note": "Replaces 'n <= 1e-4 AND T_f <= T_f0 + 50' as the scram X_exit. The power-threshold framing was structurally awkward: (1) n is nonlinear in the PJ state (n = LAMBDA * sum(LAM_i*C_i) / (BETA - rho)), (2) the conjoined T_f bound was infeasible at 60 s under decay heat (fuel doesn't cool that fast). Reactivity is the physically correct success criterion AND linear in (T_f, T_c). Verified discharged at T = 10, 30, 60 s — see results/reach_scram_pj_result.mat."
|
|
}
|
|
},
|
|
|
|
"mode_invariants": {
|
|
"_comment": [
|
|
"Per-DRC-mode invariants: conjunctions of relevant safety_limits.",
|
|
"This is the target of per-mode reach and barrier analysis."
|
|
],
|
|
"inv1_holds": {
|
|
"meaning": "Heatup mode safety envelope.",
|
|
"conjunction_of": [
|
|
"fuel_centerline",
|
|
"cold_leg_subcooled",
|
|
"heatup_rate_upper",
|
|
"heatup_rate_lower",
|
|
"prompt_critical_margin_heatup"
|
|
],
|
|
"_note": "dT_c/dt is linear in (T_f, T_c, T_cold), so ramp-rate halfspace has 3 nonzero coefficients per row. prompt_critical_margin_heatup proves the PJ reduction's validity condition (beta - rho > 0 with margin) as part of the safety obligation rather than as an unverified premise. DNBR not modeled — would need an augmented correlation-based predicate."
|
|
},
|
|
"inv2_holds": {
|
|
"meaning": "Operation mode safety envelope.",
|
|
"conjunction_of": [
|
|
"fuel_centerline",
|
|
"t_avg_high_trip",
|
|
"t_avg_low_trip",
|
|
"n_high_trip",
|
|
"n_low_operation",
|
|
"cold_leg_subcooled"
|
|
]
|
|
}
|
|
},
|
|
|
|
"mode_boundaries": {
|
|
"_comment": [
|
|
"Per-DRC-mode entry/exit sets and time budgets. Two kinds of modes:",
|
|
" equilibrium: operation, shutdown. Obligation is forever-invariance.",
|
|
" transition: heatup, scram. Obligation is reach-avoid — reach",
|
|
" X_exit within [T_min, T_max] while maintaining X_safe.",
|
|
"",
|
|
"T_max values are demo-reasonable guesses, not tech-spec calibrated.",
|
|
"T_min where given is a physical lower bound from rate limits (heatup",
|
|
"at 28 C/hr implies >= 60F/28 = 2.14 hr minimum for the 60F span)."
|
|
],
|
|
|
|
"q_shutdown": {
|
|
"kind": "equilibrium",
|
|
"obligation": "stay within X_safe forever; transition out only when X_exit becomes true",
|
|
"X_entry_description": "initial DRC state OR post-scram cooled-down state — reasonable hot-standby conditions",
|
|
"X_entry_polytope": {
|
|
"n_range": [1.0e-7, 1.0e-4],
|
|
"T_f_range_C": [270.0, 280.0],
|
|
"T_c_range_C": [270.0, 280.0],
|
|
"T_cold_range_C": [270.0, 280.0]
|
|
},
|
|
"X_safe_predicate": "inv_shutdown_holds (TBD — conservative: stay near T_standby with n subcritical)",
|
|
"X_exit_predicate": "t_avg_above_min (operator has warmed coolant above threshold)",
|
|
"T_max_seconds": null,
|
|
"T_min_seconds": null
|
|
},
|
|
|
|
"q_heatup": {
|
|
"kind": "transition",
|
|
"obligation": "from X_entry, reach X_exit within [T_min, T_max], maintain inv1_holds throughout",
|
|
"X_entry_description": "post-t_avg_above_min: operator has warmed coolant, n pulled toward criticality",
|
|
"X_entry_polytope": {
|
|
"n_range": [5.0e-4, 5.0e-3],
|
|
"T_f_range_C": [275.0, 295.0],
|
|
"T_c_range_C": [281.0, 295.0],
|
|
"T_cold_range_C": [270.0, 281.0]
|
|
},
|
|
"X_safe_predicate": "inv1_holds",
|
|
"X_exit_predicate": "t_avg_in_range AND p_above_crit AND inv1_holds",
|
|
"T_max_seconds": 18000,
|
|
"T_min_seconds": 7714,
|
|
"_T_max_rationale": "5 hr. Tech-spec limit 28 C/hr; 60 F = 33.3 C span; nominal 1.19 hr, allow 4x margin for transient overshoot + settling.",
|
|
"_T_min_rationale": "2 hr 8.6 min. Physical floor: heatup faster than 28 C/hr violates the rate invariant. 60 F / 28 C/hr = 33.3 / 28 = 1.189 hr at tech-spec max; add 30% margin for non-uniform ramp = 2.14 hr."
|
|
},
|
|
|
|
"q_operation": {
|
|
"kind": "equilibrium",
|
|
"obligation": "stay in X_safe forever under bounded Q_sg",
|
|
"X_entry_description": "X_exit(heatup)",
|
|
"X_entry_polytope_ref": "q_heatup.X_exit_predicate",
|
|
"X_safe_predicate": "inv2_holds",
|
|
"X_exit_predicate": "NOT inv2_holds (trigger scram) OR q_operation stays indefinitely",
|
|
"disturbance": {
|
|
"variable": "Q_sg",
|
|
"range_fraction_of_P0": [0.85, 1.00],
|
|
"_rationale": "Grid load-follow envelope. Could be tightened to 0.95-1.00 for steady-state or widened to 0.70-1.00 for aggressive load following."
|
|
},
|
|
"T_max_seconds": null,
|
|
"T_min_seconds": null
|
|
},
|
|
|
|
"q_scram": {
|
|
"kind": "transition",
|
|
"obligation": "from any trip-triggering state, drive reactor to safely-subcritical within T_max",
|
|
"X_entry_description": "any state where inv1_holds or inv2_holds fails during heatup/operation",
|
|
"X_entry_polytope": "union of (X_operation - inv2_holds-satisfying) and (X_heatup - inv1_holds-satisfying) — for demo, take x_op",
|
|
"X_safe_predicate": "fuel_centerline AND cold_leg_subcooled (T_f, T_cold bounds maintained throughout transit; n monotonically non-increasing under U_SCRAM is implied by physics, not enforced as halfspace)",
|
|
"X_exit_predicate": "shutdown_margin",
|
|
"T_max_seconds": 60,
|
|
"T_min_seconds": null,
|
|
"_T_max_rationale": "60 s. NRC requirement typically few seconds to subcritical; 60 s is generous for our lumped model with idealized rod-insertion. Real plants: rods free-fall in ~2-3 s.",
|
|
"_X_exit_history": "v1: 'n <= 1e-4 AND T_f <= T_f0 + 50 C'. Replaced 2026-04-27: power threshold was nonlinear in PJ state, T_f bound was infeasible at 60 s under decay heat. shutdown_margin (rho <= -0.01) is the correct NRC tech-spec criterion and a clean halfspace in (T_f, T_c)."
|
|
}
|
|
},
|
|
|
|
"_placeholder_warning": [
|
|
"Numerical values in safety_limits are representative (2-loop Westinghouse-",
|
|
"class PWR tech-spec ranges) but NOT calibrated to a specific plant.",
|
|
"Calibrate against a real plant's tech specs before defense."
|
|
]
|
|
}
|