Folds three previously-separate pieces into one preliminary-example repo for the HAHACS thesis: - thesis/ (submodule) → gitea Thesis.git — the PhD proposal - fret-pipeline/ — FRET requirements to AIGER controller (was ~/Documents/fret_processing/; prior single-commit history abandoned per user decision) - plant-model/ — 10-state PKE + lumped T/H PWR model (was ~/Documents/PKE_Playground/; never version-controlled before) - presentations/2026DICE/ (submodule) → gitea 2026DICE.git - reachability/, hardware/ — empty placeholders for Thrust 3 and HIL - docs/architecture.md — how the discrete and continuous layers compose - claude_memory/ — session notes and scratch knowledge pattern Plant model refactored to thesis naming (x, plant, u, ref); pke_th_rhs now takes u as an explicit arg instead of reading rho_ext from the params struct. First two controllers built to the contract u = ctrl_<mode>(t, x, plant, ref): ctrl_null (baseline) and ctrl_operation (stabilizing, proportional on T_avg). Validated under a 100% -> 80% Q_sg step: ctrl_operation reduces steady-state T_avg drift ~47% vs. the unforced plant. Root CLAUDE.md emphasizes that CLAUDE.md files are living documents and that any knowledge not captured before a session ends is lost forever; claude_memory/ holds the session-level notes that haven't stabilized enough to graduate into a CLAUDE.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
77 lines
2.6 KiB
Matlab
77 lines
2.6 KiB
Matlab
function plot_pke_results(t, X, U, plant, Q_sg, plot_title)
|
|
% PLOT_PKE_RESULTS Standard 4-panel plot of PKE + T/H simulation results.
|
|
%
|
|
% Inputs:
|
|
% t - time vector from ODE solver
|
|
% X - state matrix (M x 10): [n, C1..C6, T_f, T_c, T_cold]
|
|
% U - control input trajectory (M x 1): scalar u at each time
|
|
% plant - parameter struct from pke_params()
|
|
% Q_sg - function handle Q_sg(t) used in the simulation
|
|
% plot_title - (optional) string used in the figure name and first subplot
|
|
|
|
if nargin < 6 || isempty(plot_title)
|
|
plot_title = 'PKE + T/H closed-loop';
|
|
end
|
|
|
|
% --- Extract states ---
|
|
n = X(:, 1);
|
|
T_f = X(:, 8);
|
|
T_c = X(:, 9);
|
|
T_cold = X(:, 10);
|
|
T_hot = 2 * T_c - T_cold;
|
|
|
|
% --- Convert temperatures to Fahrenheit for display ---
|
|
CtoF = @(T) T * 9/5 + 32;
|
|
T_f_F = CtoF(T_f);
|
|
T_c_F = CtoF(T_c);
|
|
T_cold_F = CtoF(T_cold);
|
|
T_hot_F = CtoF(T_hot);
|
|
|
|
% --- Derived quantities ---
|
|
power_MW = n * plant.P0 / 1e6;
|
|
Q_sg_MW = arrayfun(Q_sg, t) / 1e6;
|
|
|
|
rho_fb = plant.alpha_f * (T_f - plant.T_f0) + plant.alpha_c * (T_c - plant.T_c0);
|
|
rho_tot = U + rho_fb;
|
|
|
|
% --- Plot ---
|
|
figure('Position', [100 50 1000 950], 'Name', plot_title);
|
|
|
|
% Power & SG demand
|
|
subplot(4, 1, 1);
|
|
plot(t, power_MW, 'b-', 'LineWidth', 1.5); hold on;
|
|
plot(t, Q_sg_MW, 'r--', 'LineWidth', 1.2);
|
|
xlabel('Time [s]'); ylabel('Power [MW_{th}]');
|
|
legend('Reactor Power', 'Q_{sg}', 'Location', 'east');
|
|
title(sprintf('%s — Power and SG Heat Demand', plot_title));
|
|
grid on;
|
|
|
|
% Reactivity: controller u, feedback, total
|
|
subplot(4, 1, 2);
|
|
plot(t, U / plant.beta, 'k-', 'LineWidth', 1.5); hold on;
|
|
plot(t, rho_fb / plant.beta, 'b-.', 'LineWidth', 1.2);
|
|
plot(t, rho_tot / plant.beta, 'm:', 'LineWidth', 1.5);
|
|
xlabel('Time [s]'); ylabel('\rho [$]');
|
|
legend('u (controller)', 'Feedback', 'Total', 'Location', 'east');
|
|
title('Reactivity');
|
|
grid on;
|
|
|
|
% Coolant temperatures
|
|
subplot(4, 1, 3);
|
|
plot(t, T_hot_F, 'r-', 'LineWidth', 1.5); hold on;
|
|
plot(t, T_c_F, 'm--', 'LineWidth', 1.2);
|
|
plot(t, T_cold_F, 'b-', 'LineWidth', 1.5);
|
|
xlabel('Time [s]'); ylabel('Temperature [F]');
|
|
legend('T_{hot}', 'T_{avg}', 'T_{cold}', 'Location', 'east');
|
|
title('Coolant Temperatures');
|
|
grid on;
|
|
|
|
% Fuel temperature
|
|
subplot(4, 1, 4);
|
|
plot(t, T_f_F, 'Color', [0.85 0.33 0.1], 'LineWidth', 1.5);
|
|
xlabel('Time [s]'); ylabel('Temperature [F]');
|
|
title('Fuel Temperature');
|
|
grid on;
|
|
|
|
end
|