Path: blob/main/latex-templates/templates/nuclear-physics/reactor_kinetics.tex
75 views
unlisted
\documentclass[a4paper, 11pt]{article}1\usepackage[utf8]{inputenc}2\usepackage[T1]{fontenc}3\usepackage{amsmath, amssymb, amsthm}4\usepackage{graphicx}5\usepackage{booktabs}6\usepackage{siunitx}7\usepackage{subcaption}8\usepackage[makestderr]{pythontex}910\newtheorem{definition}{Definition}11\newtheorem{theorem}{Theorem}12\newtheorem{example}{Example}13\newtheorem{remark}{Remark}1415\title{Nuclear Reactor Kinetics: Point Kinetics Model and Delayed Neutron Analysis}16\author{Nuclear Engineering Computation Laboratory}17\date{\today}1819\begin{document}20\maketitle2122\begin{abstract}23This technical report presents comprehensive computational analysis of nuclear reactor kinetics using the point kinetics equations with delayed neutrons. We implement solutions for reactivity transients, analyze the role of delayed neutron precursors in reactor control, and compute reactor periods for various reactivity insertions. The analysis covers prompt criticality, xenon dynamics, and feedback mechanisms essential for safe reactor operation.24\end{abstract}2526\section{Theoretical Framework}2728\begin{definition}[Reactivity]29Reactivity $\rho$ measures the deviation from criticality:30\begin{equation}31\rho = \frac{k_{eff} - 1}{k_{eff}}32\end{equation}33where $k_{eff}$ is the effective multiplication factor.34\end{definition}3536\begin{theorem}[Point Kinetics Equations]37For six delayed neutron groups, the reactor power evolves according to:38\begin{align}39\frac{dn}{dt} &= \frac{\rho - \beta}{\Lambda} n + \sum_{i=1}^{6} \lambda_i C_i + S \\40\frac{dC_i}{dt} &= \frac{\beta_i}{\Lambda} n - \lambda_i C_i41\end{align}42where $n$ is neutron density, $C_i$ are precursor concentrations, $\beta = \sum \beta_i$ is total delayed neutron fraction, $\Lambda$ is mean generation time, and $S$ is external source.43\end{theorem}4445\subsection{Reactor Period}4647\begin{definition}[Stable Period]48The asymptotic reactor period $T$ satisfies the inhour equation:49\begin{equation}50\rho = \frac{\Lambda}{T} + \sum_{i=1}^{6} \frac{\beta_i}{1 + \lambda_i T}51\end{equation}52\end{definition}5354\begin{example}[Reactivity Units]55Reactivity is measured in:56\begin{itemize}57\item \textbf{Dollar} (\$): $\rho/\beta$ (1\$ = one delayed neutron fraction)58\item \textbf{Cent}: 0.01\$ = 0.01$\beta$59\item \textbf{pcm}: $10^{-5}$ (parts per 100,000)60\end{itemize}61For U-235: $\beta \approx 0.0065$, so 1\$ $\approx$ 650 pcm.62\end{example}6364\section{Computational Analysis}6566\begin{pycode}67import numpy as np68from scipy.integrate import odeint, solve_ivp69from scipy.optimize import fsolve70import matplotlib.pyplot as plt71plt.rc('text', usetex=True)72plt.rc('font', family='serif', size=10)7374# Reactor parameters (U-235 thermal)75Lambda = 1e-4 # Mean generation time (s)76beta_total = 0.0065 # Total delayed neutron fraction7778# Six-group delayed neutron data for U-23579beta_i = np.array([0.000215, 0.001424, 0.001274, 0.002568, 0.000748, 0.000273])80lambda_i = np.array([0.0124, 0.0305, 0.111, 0.301, 1.14, 3.01]) # decay constants (1/s)81half_lives_i = np.log(2) / lambda_i # seconds8283# Effective one-group parameters84beta_eff = np.sum(beta_i)85lambda_eff = np.sum(beta_i * lambda_i) / beta_eff8687# Point kinetics equations (6 groups)88def point_kinetics_6group(y, t, rho_func):89"""Six-group point kinetics equations."""90n = y[0]91C = y[1:7]9293rho = rho_func(t)9495dn_dt = (rho - beta_eff) / Lambda * n + np.sum(lambda_i * C)96dC_dt = beta_i / Lambda * n - lambda_i * C9798return np.concatenate([[dn_dt], dC_dt])99100# Simplified one-group kinetics101def point_kinetics_1group(y, t, rho_func):102"""One-group point kinetics equations."""103n, C = y104rho = rho_func(t)105dn_dt = (rho - beta_eff) / Lambda * n + lambda_eff * C106dC_dt = beta_eff / Lambda * n - lambda_eff * C107return [dn_dt, dC_dt]108109# Inhour equation110def inhour_equation(T, rho):111"""Inhour equation for reactor period."""112if abs(T) < 1e-10:113return np.inf114return Lambda / T + np.sum(beta_i / (1 + lambda_i * T)) - rho115116def find_period(rho):117"""Find stable period for given reactivity."""118if rho <= 0:119return np.inf120elif rho >= beta_eff:121return Lambda / (rho - beta_eff) # Prompt critical122else:123# Newton-Raphson to solve inhour equation124T_guess = 1.0 / (lambda_eff * rho / (beta_eff - rho))125T_sol = fsolve(inhour_equation, T_guess, args=(rho,))[0]126return T_sol127128# Initial conditions (equilibrium at n=1)129n0 = 1.0130C0_i = beta_i / Lambda * n0 / lambda_i131y0_6group = np.concatenate([[n0], C0_i])132y0_1group = [n0, beta_eff / Lambda * n0 / lambda_eff]133134# Time arrays135t_short = np.linspace(0, 10, 1000) # seconds136t_long = np.linspace(0, 100, 1000)137138# Reactivity insertions139rho_values = [0.001, 0.003, 0.005] # Below prompt critical140rho_prompt = 0.007 # Above prompt critical141142# Solve for different reactivities143solutions = []144for rho_val in rho_values:145rho_func = lambda t, r=rho_val: r if t > 0 else 0146sol = odeint(point_kinetics_6group, y0_6group, t_short, args=(rho_func,))147solutions.append(sol[:, 0])148149# Prompt supercritical case150t_prompt = np.linspace(0, 0.01, 500) # milliseconds151rho_func_prompt = lambda t: rho_prompt if t > 0 else 0152sol_prompt = odeint(point_kinetics_6group, y0_6group, t_prompt, args=(rho_func_prompt,))153154# Negative reactivity (shutdown)155rho_neg = -0.005156rho_func_neg = lambda t: rho_neg if t > 0 else 0157sol_neg = odeint(point_kinetics_6group, y0_6group, t_long, args=(rho_func_neg,))158159# Ramp reactivity insertion160ramp_rate = 0.0001 # per second161rho_func_ramp = lambda t: min(ramp_rate * t, 0.005) if t > 0 else 0162sol_ramp = odeint(point_kinetics_6group, y0_6group, t_long, args=(rho_func_ramp,))163164# Reactor period vs reactivity165rho_range = np.linspace(0.0001, 0.006, 100)166periods = np.array([find_period(r) for r in rho_range])167168# Temperature feedback169alpha_T = -3e-5 # Temperature coefficient (per K)170def feedback_rho(t, n, rho_ext, T0=300, C_heat=1e6):171"""Reactivity with temperature feedback."""172# Simple heat-up model173T = T0 + n * t / C_heat174return rho_ext + alpha_T * (T - T0)175176# Xenon dynamics (simplified)177sigma_Xe = 2.65e-18 # Xe-135 absorption cross section (cm^2)178Sigma_f = 0.1 # Macroscopic fission cross section (1/cm)179gamma_Xe = 0.003 # Direct yield180gamma_I = 0.061 # Iodine yield (-> Xe-135)181lambda_Xe = 2.09e-5 # Xe-135 decay constant (1/s)182lambda_I = 2.87e-5 # I-135 decay constant (1/s)183184# Equilibrium xenon concentration185def xenon_equilibrium(phi):186"""Equilibrium Xe-135 concentration."""187return (gamma_I + gamma_Xe) * Sigma_f * phi / (lambda_Xe + sigma_Xe * phi)188189# Xenon after shutdown190def xenon_shutdown(t, phi0):191"""Xe-135 concentration after shutdown."""192Xe0 = xenon_equilibrium(phi0)193I0 = gamma_I * Sigma_f * phi0 / lambda_I194195Xe = (Xe0 * np.exp(-lambda_Xe * t) +196I0 * lambda_I / (lambda_Xe - lambda_I) *197(np.exp(-lambda_I * t) - np.exp(-lambda_Xe * t)))198return Xe199200phi0 = 1e14 # Initial flux (n/cm^2/s)201t_xenon = np.linspace(0, 100 * 3600, 500) # 100 hours202Xe_shutdown = xenon_shutdown(t_xenon, phi0)203204# Create visualization205fig = plt.figure(figsize=(12, 10))206gs = fig.add_gridspec(3, 3, hspace=0.35, wspace=0.35)207208# Plot 1: Step reactivity response209ax1 = fig.add_subplot(gs[0, 0])210colors = ['blue', 'green', 'red']211for sol, rho, color in zip(solutions, rho_values, colors):212rho_dollars = rho / beta_eff213ax1.plot(t_short, sol, color=color, lw=1.5,214label=f'{rho*1000:.0f} pcm ({rho_dollars:.2f}\\$)')215ax1.set_xlabel('Time (s)')216ax1.set_ylabel('Relative Power')217ax1.set_title('Step Reactivity Insertion')218ax1.legend(fontsize=7)219ax1.set_yscale('log')220ax1.grid(True, alpha=0.3, which='both')221222# Plot 2: Prompt supercritical223ax2 = fig.add_subplot(gs[0, 1])224ax2.plot(t_prompt * 1000, sol_prompt[:, 0], 'r-', lw=2)225ax2.set_xlabel('Time (ms)')226ax2.set_ylabel('Relative Power')227ax2.set_title(f'Prompt Critical ({rho_prompt*1000:.0f} pcm)')228ax2.set_yscale('log')229ax2.grid(True, alpha=0.3, which='both')230231# Plot 3: Reactor period232ax3 = fig.add_subplot(gs[0, 2])233ax3.semilogy(rho_range / beta_eff, periods, 'b-', lw=2)234ax3.axhline(y=1, color='gray', ls='--', alpha=0.5)235ax3.axvline(x=1, color='r', ls='--', alpha=0.5, label='Prompt critical')236ax3.set_xlabel('Reactivity (\\$)')237ax3.set_ylabel('Stable Period (s)')238ax3.set_title('Reactor Period')239ax3.legend(fontsize=8)240ax3.grid(True, alpha=0.3, which='both')241ax3.set_xlim([0, 1.1])242ax3.set_ylim([0.1, 1000])243244# Plot 4: Shutdown transient245ax4 = fig.add_subplot(gs[1, 0])246ax4.plot(t_long, sol_neg[:, 0], 'b-', lw=2)247ax4.set_xlabel('Time (s)')248ax4.set_ylabel('Relative Power')249ax4.set_title(f'Shutdown ({rho_neg*1000:.0f} pcm)')250ax4.grid(True, alpha=0.3)251252# Plot 5: Delayed neutron groups253ax5 = fig.add_subplot(gs[1, 1])254x_pos = range(len(beta_i))255ax5.bar(x_pos, beta_i * 100, color='blue', alpha=0.7)256ax5.set_xlabel('Precursor Group')257ax5.set_ylabel('$\\beta_i$ (\\%)')258ax5.set_title('Delayed Neutron Fractions')259ax5.set_xticks(x_pos)260ax5.set_xticklabels([1, 2, 3, 4, 5, 6])261ax5.grid(True, alpha=0.3, axis='y')262263# Plot 6: Precursor half-lives264ax6 = fig.add_subplot(gs[1, 2])265ax6.bar(x_pos, half_lives_i, color='green', alpha=0.7)266ax6.set_xlabel('Precursor Group')267ax6.set_ylabel('Half-life (s)')268ax6.set_title('Precursor Decay Half-lives')269ax6.set_xticks(x_pos)270ax6.set_xticklabels([1, 2, 3, 4, 5, 6])271ax6.grid(True, alpha=0.3, axis='y')272273# Plot 7: Ramp insertion274ax7 = fig.add_subplot(gs[2, 0])275ax7.plot(t_long, sol_ramp[:, 0], 'purple', lw=2)276ax7.set_xlabel('Time (s)')277ax7.set_ylabel('Relative Power')278ax7.set_title(f'Ramp Insertion ({ramp_rate*1e6:.0f} pcm/s)')279ax7.grid(True, alpha=0.3)280281# Plot 8: Xenon poisoning after shutdown282ax8 = fig.add_subplot(gs[2, 1])283Xe_norm = Xe_shutdown / xenon_equilibrium(phi0)284ax8.plot(t_xenon / 3600, Xe_norm, 'r-', lw=2)285ax8.axhline(y=1, color='gray', ls='--', alpha=0.5)286ax8.set_xlabel('Time after shutdown (hours)')287ax8.set_ylabel('Xe-135 / Equilibrium')288ax8.set_title('Xenon Transient')289ax8.grid(True, alpha=0.3)290291# Plot 9: Inhour equation components292ax9 = fig.add_subplot(gs[2, 2])293T_range = np.logspace(-1, 3, 200)294295prompt_term = Lambda / T_range296delayed_term = np.sum([beta_i[i] / (1 + lambda_i[i] * T_range[:, np.newaxis])297for i in range(6)], axis=0).flatten()298total = prompt_term + delayed_term299300ax9.loglog(T_range, prompt_term * 1000, 'b--', lw=1.5, label='Prompt')301ax9.loglog(T_range, delayed_term * 1000, 'r--', lw=1.5, label='Delayed')302ax9.loglog(T_range, total * 1000, 'k-', lw=2, label='Total')303ax9.set_xlabel('Period (s)')304ax9.set_ylabel('Reactivity (pcm)')305ax9.set_title('Inhour Equation')306ax9.legend(fontsize=7)307ax9.grid(True, alpha=0.3, which='both')308309plt.savefig('reactor_kinetics_plot.pdf', bbox_inches='tight', dpi=150)310print(r'\begin{center}')311print(r'\includegraphics[width=\textwidth]{reactor_kinetics_plot.pdf}')312print(r'\end{center}')313plt.close()314315# Calculate key values316period_50cent = find_period(0.5 * beta_eff)317prompt_period = Lambda / (rho_prompt - beta_eff)318xe_max_time = t_xenon[np.argmax(Xe_shutdown)] / 3600319xe_max_ratio = np.max(Xe_norm)320\end{pycode}321322\section{Results and Analysis}323324\subsection{Point Kinetics Parameters}325326\begin{pycode}327print(r'\begin{table}[htbp]')328print(r'\centering')329print(r'\caption{Reactor Kinetics Parameters (U-235 Thermal)}')330print(r'\begin{tabular}{lcc}')331print(r'\toprule')332print(r'Parameter & Value & Units \\')333print(r'\midrule')334print(f'Total $\\beta$ & {beta_eff*1000:.2f} & -- ($\\times 10^{{-3}}$) \\\\')335print(f'Mean generation time $\\Lambda$ & {Lambda*1000:.2f} & ms \\\\')336print(f'Effective decay constant & {lambda_eff:.3f} & s$^{{-1}}$ \\\\')337print(f'1 dollar & {beta_eff*1e5:.0f} & pcm \\\\')338print(r'\bottomrule')339print(r'\end{tabular}')340print(r'\end{table}')341\end{pycode}342343\subsection{Delayed Neutron Groups}344345\begin{pycode}346print(r'\begin{table}[htbp]')347print(r'\centering')348print(r'\caption{Six-Group Delayed Neutron Data for U-235}')349print(r'\begin{tabular}{ccccc}')350print(r'\toprule')351print(r'Group & $\beta_i$ & $\lambda_i$ (s$^{-1}$) & $t_{1/2}$ (s) & Precursors \\')352print(r'\midrule')353354precursors = ['Br-87', 'I-137', 'Br-89', 'I-138', 'As-85', 'Br-92']355for i in range(6):356print(f'{i+1} & {beta_i[i]:.6f} & {lambda_i[i]:.4f} & {half_lives_i[i]:.2f} & {precursors[i]} \\\\')357358print(r'\midrule')359print(f'Total & {beta_eff:.6f} & {lambda_eff:.4f} (eff) & -- & -- \\\\')360print(r'\bottomrule')361print(r'\end{tabular}')362print(r'\end{table}')363\end{pycode}364365\subsection{Reactor Periods}366367\begin{remark}368Delayed neutrons are essential for reactor control. Without them, the reactor period would be:369\begin{equation}370T_{prompt} = \frac{\Lambda}{\rho} \approx \frac{10^{-4} \text{ s}}{10^{-3}} = 0.1 \text{ s}371\end{equation}372With delayed neutrons, the effective generation time increases to $\sim$0.1 s, giving manageable periods.373\end{remark}374375Key period values:376\begin{itemize}377\item Period at 50 cents: \py{f"{period_50cent:.1f}"} s378\item Period at prompt critical: \py{f"{prompt_period*1000:.3f}"} ms379\item Prompt period ($\rho > \beta$): determined only by $\Lambda$380\end{itemize}381382\subsection{Xenon Poisoning}383384After shutdown, Xe-135 builds up due to I-135 decay:385\begin{itemize}386\item Maximum xenon at $t = \py{f"{xe_max_time:.1f}"}$ hours after shutdown387\item Peak concentration: \py{f"{xe_max_ratio:.2f}"} times equilibrium388\item This ``xenon dead time'' prevents immediate restart389\end{itemize}390391\section{Safety Analysis}392393\begin{theorem}[Prompt Critical Limit]394Prompt criticality occurs when $\rho = \beta$. Above this threshold:395\begin{equation}396T = \frac{\Lambda}{\rho - \beta}397\end{equation}398For $\rho = 1.1\beta$, $T = 10\Lambda \approx 1$ ms---uncontrollable.399\end{theorem}400401\begin{example}[Control Rod Worth]402A typical control rod worth is 1000--5000 pcm. Safe insertion requires:403\begin{itemize}404\item Maximum rate: $<$ 0.1\$/s for normal operation405\item Shutdown margin: $>$ 1\% $\Delta k/k$ with strongest rod stuck out406\end{itemize}407\end{example}408409\begin{example}[Doppler Feedback]410The prompt negative temperature coefficient:411\begin{equation}412\alpha_T = \frac{d\rho}{dT} \approx -3 \times 10^{-5} \text{ K}^{-1}413\end{equation}414provides inherent stability against power excursions.415\end{example}416417\section{Discussion}418419The point kinetics model reveals critical features of reactor dynamics:420421\begin{enumerate}422\item \textbf{Delayed neutrons}: Increase effective generation time by factor $\beta/(\beta - \rho)$.423\item \textbf{Prompt jump}: Immediate power rise followed by asymptotic period.424\item \textbf{Xenon dynamics}: Creates operational constraints after shutdown.425\item \textbf{Feedback mechanisms}: Doppler and moderator coefficients ensure stability.426\item \textbf{Safety margins}: Reactivity limits prevent prompt criticality.427\end{enumerate}428429\section{Conclusions}430431This computational analysis demonstrates:432\begin{itemize}433\item Total delayed neutron fraction: $\beta = \py{f"{beta_eff*1000:.2f}"} \times 10^{-3}$434\item Mean generation time: $\Lambda = \py{f"{Lambda*1000:.2f}"}$ ms435\item Stable period at 50\textcent: \py{f"{period_50cent:.1f}"} s436\item Xenon peak at \py{f"{xe_max_time:.1f}"} hours post-shutdown437\end{itemize}438439Understanding reactor kinetics is essential for safe operation, transient analysis, and accident prevention in nuclear power plants.440441\section{Further Reading}442\begin{itemize}443\item Duderstadt, J.J., Hamilton, L.J., \textit{Nuclear Reactor Analysis}, Wiley, 1976444\item Stacey, W.M., \textit{Nuclear Reactor Physics}, 3rd Ed., Wiley-VCH, 2018445\item Keepin, G.R., \textit{Physics of Nuclear Kinetics}, Addison-Wesley, 1965446\end{itemize}447448\end{document}449450451