\section*{Problem 1}

\subsection*{System Description}

A two-loop reactor system with:
\begin{itemize}
    \item Reactor (lumped hot leg) at temperature $T_{hot}$
    \item Steam Generator 1 with cold leg at $T_{cold1}$
    \item Steam Generator 2 with cold leg at $T_{cold2}$
    \item Equal mass flow rates and water masses in each loop
    \item Reactor Water Mass Fraction (RWMF): $\mu$
\end{itemize}

\textbf{Given parameters:}
\begin{itemize}
    \item Base heat capacity: $C_0 = 33.33$ \%-sec/\degree F
    \item Base time constant: $\tau_0 = 0.75 \times C_0 = 25.00$ sec
    \item Initial temperature: $T_{hot} = T_{cold1} = T_{cold2} = 450$ \degree F
\end{itemize}

\textbf{Derived parameter:}

The flow heat capacity rate per loop is \textit{not directly given} in the problem statement but can be derived from the relationship between time constants and heat capacities:

\[W = \frac{C_0}{2\tau_0} = \frac{33.33}{2 \times 25.00} = 0.6667 \text{ \%-sec/\degree F}\]

This represents the (mass flow rate $\times$ specific heat) for each loop.

\textbf{System parameters as functions of $\mu$:}
\begin{itemize}
    \item Reactor time constant: $\tau_r = \mu \tau_0$
    \item Reactor heat capacity: $C_r = \mu C_0$
    \item Steam generator time constant (each): $\tau_{sg} = \frac{(1-\mu)\tau_r}{2}$
    \item Steam generator heat capacity (each): $C_{sg} = \frac{(1-\mu)C_0}{2}$
\end{itemize}

\subsection*{Part A}

\subsubsection*{Python Code}
\begin{lstlisting}[language=Python,
    basicstyle=\ttfamily\small,
    keywordstyle=\color{blue},
    commentstyle=\color{gray},
    stringstyle=\color{red},
    showstringspaces=false,
    numbers=left,
    numberstyle=\tiny,
    frame=single,
    breaklines=true]
import numpy as np
import sympy as sm

# Given parameters
C_0 = 33.33  # Base heat capacity [%-sec/degF]
tau_0 = 25.00  # Base time constant [sec]
W = C_0 / (2 * tau_0)  # Flow heat capacity rate per loop

def calculate_system_parameters(mu):
    C_r = mu * C_0  # Reactor heat capacity
    C_sg = (1 - mu) * C_0 / 2  # Steam generator heat capacity (each)
    return C_r, C_sg

# Matrix form: dT/dt = A*T + B
def get_matrix_A(C_r, C_sg, W):
    A = np.array([
        [-2*W/C_r,  W/C_r,      W/C_r],
        [W/C_sg,    -W/C_sg,    0],
        [W/C_sg,    0,          -W/C_sg]
    ])
    return A

# Vector B (forcing terms):
# B = [P_r/C_r, -Qdot1/C_sg, -Qdot2/C_sg]^T
\end{lstlisting}

\subsubsection*{Solution}

The energy balance for each component yields differential equations:

\textbf{Reactor energy balance:}
\[C_r \frac{dT_{hot}}{dt} = P_r - W(T_{hot} - T_{cold1}) - W(T_{hot} - T_{cold2})\]

\textbf{Steam Generator 1 energy balance:}
\[C_{sg} \frac{dT_{cold1}}{dt} = W(T_{hot} - T_{cold1}) - \dot{Q}_1\]

\textbf{Steam Generator 2 energy balance:}
\[C_{sg} \frac{dT_{cold2}}{dt} = W(T_{hot} - T_{cold2}) - \dot{Q}_2\]

where:
\begin{itemize}
    \item $P_r$ = reactor power (positive for heat generation)
    \item $\dot{Q}_1, \dot{Q}_2$ = steam generator heat removal rates (positive for heat removal)
    \item $W = \frac{C_0}{2\tau_0} = 0.6667$ \%-sec/\degree F = flow heat capacity rate per loop
\end{itemize}

\textbf{Matrix Form:}

Define the temperature vector: $\mathbf{T} = \begin{bmatrix} T_{hot} \\ T_{cold1} \\ T_{cold2} \end{bmatrix}$

The system can be written as:
\[\boxed{\frac{d\mathbf{T}}{dt} = \mathbf{A} \mathbf{T} + \mathbf{B}}\]

where the coefficient matrix $\mathbf{A}$ is:

\[\mathbf{A} = \begin{bmatrix}
-\frac{2W}{C_r} & \frac{W}{C_r} & \frac{W}{C_r} \\[0.3em]
\frac{W}{C_{sg}} & -\frac{W}{C_{sg}} & 0 \\[0.3em]
\frac{W}{C_{sg}} & 0 & -\frac{W}{C_{sg}}
\end{bmatrix}\]

and the forcing vector $\mathbf{B}$ is:

\[\mathbf{B} = \begin{bmatrix}
\frac{P_r}{C_r} \\[0.3em]
-\frac{\dot{Q}_1}{C_{sg}} \\[0.3em]
-\frac{\dot{Q}_2}{C_{sg}}
\end{bmatrix}\]

\textbf{Numerical example for $\mu = 0.5$:}

With $\mu = 0.5$: $C_r = 16.66$ \%-sec/\degree F, $C_{sg} = 8.33$ \%-sec/\degree F, $W = 0.6667$ \%-sec/\degree F

\[\boxed{\mathbf{A} = \begin{bmatrix}
-0.0800 & 0.0400 & 0.0400 \\
0.0800 & -0.0800 & 0 \\
0.0800 & 0 & -0.0800
\end{bmatrix}}\]

\subsection*{Part B}

\subsubsection*{Python Code}
\begin{lstlisting}[language=Python,
    basicstyle=\ttfamily\small,
    keywordstyle=\color{blue},
    commentstyle=\color{gray},
    stringstyle=\color{red},
    showstringspaces=false,
    numbers=left,
    numberstyle=\tiny,
    frame=single,
    breaklines=true]
# At steady state, dT/dt = 0
# From SG1: 0 = W*(T_hot - T_cold1) - Qdot1
DeltaT1 = Qdot1 / W

# From SG2: 0 = W*(T_hot - T_cold2) - Qdot2
DeltaT2 = Qdot2 / W

# From reactor: P_r = W*DeltaT1 + W*DeltaT2
power_balance = Qdot1 + Qdot2
\end{lstlisting}

\subsubsection*{Solution}

At steady state, all time derivatives are zero ($\frac{dT}{dt} = 0$).

\textbf{From Steam Generator 1 equation:}
\[0 = W(T_{hot} - T_{cold1}) - \dot{Q}_1\]
\[\boxed{\Delta T_1 = T_{hot} - T_{cold1} = \frac{\dot{Q}_1}{W}}\]

\textbf{From Steam Generator 2 equation:}
\[0 = W(T_{hot} - T_{cold2}) - \dot{Q}_2\]
\[\boxed{\Delta T_2 = T_{hot} - T_{cold2} = \frac{\dot{Q}_2}{W}}\]

\textbf{From Reactor equation:}
\[0 = P_r - W\Delta T_1 - W\Delta T_2\]
\[P_r = W\Delta T_1 + W\Delta T_2 = \dot{Q}_1 + \dot{Q}_2\]

This confirms the power balance: reactor power equals total steam generator heat removal rates.

\subsection*{Part C}

\subsubsection*{Python Code}
\begin{lstlisting}[language=Python,
    basicstyle=\ttfamily\small,
    keywordstyle=\color{blue},
    commentstyle=\color{gray},
    stringstyle=\color{red},
    showstringspaces=false,
    numbers=left,
    numberstyle=\tiny,
    frame=single,
    breaklines=true]
# Average reactor temperature (mass-weighted)
def calculate_T_ave(T_hot, T_cold1, T_cold2, mu, C_0):
    C_r = mu * C_0
    C_sg = (1 - mu) * C_0 / 2

    # Mass-weighted average
    T_ave = (C_r*T_hot + C_sg*T_cold1 + C_sg*T_cold2) / C_0

    # Simplified form
    T_ave_simplified = mu*T_hot + (1-mu)*(T_cold1 + T_cold2)/2

    return T_ave_simplified

# For mu = 0.5:
T_ave_50 = 0.5*T_hot + 0.25*T_cold1 + 0.25*T_cold2

# For mu = 0.75:
T_ave_75 = 0.75*T_hot + 0.125*T_cold1 + 0.125*T_cold2
\end{lstlisting}

\subsubsection*{Solution}

The average reactor temperature must be calculated as a \textbf{mass-weighted average}:

\[T_{ave} = \frac{C_r T_{hot} + C_{sg} T_{cold1} + C_{sg} T_{cold2}}{C_r + 2C_{sg}}\]

Since $C_r + 2C_{sg} = \mu C_0 + 2 \cdot \frac{(1-\mu)C_0}{2} = C_0$, this simplifies to:

\[T_{ave} = \frac{C_r T_{hot} + C_{sg} T_{cold1} + C_{sg} T_{cold2}}{C_0}\]

Substituting $C_r = \mu C_0$ and $C_{sg} = \frac{(1-\mu)C_0}{2}$:

\[\boxed{T_{ave} = \mu T_{hot} + \frac{(1-\mu)}{2}(T_{cold1} + T_{cold2})}\]

\textbf{Important:} This formula \textit{depends on $\mu$}!

\textbf{For $\mu = 0.5$:}
\[T_{ave} = \frac{T_{hot}}{2} + \frac{T_{cold1} + T_{cold2}}{4}\]

\textbf{For $\mu = 0.75$:}
\[T_{ave} = \frac{3T_{hot}}{4} + \frac{T_{cold1} + T_{cold2}}{8}\]

\textbf{Note:} When the system is balanced ($P_r = \dot{Q}_1 + \dot{Q}_2$), the mass-weighted average temperature remains constant even during transients, since $\frac{d(C_0 \cdot T_{ave})}{dt} = P_r - \dot{Q}_1 - \dot{Q}_2 = 0$.

\subsection*{Part D}

\subsubsection*{Python Code}
\begin{lstlisting}[language=Python,
    basicstyle=\ttfamily\small,
    keywordstyle=\color{blue},
    commentstyle=\color{gray},
    stringstyle=\color{red},
    showstringspaces=false,
    numbers=left,
    numberstyle=\tiny,
    frame=single,
    breaklines=true]
from scipy.integrate import odeint

def reactor_odes(y, t, W, C_r, C_sg, P_r, Qdot1, Qdot2):
    """
    P_r: Reactor power (heat generation rate)
    Qdot1, Qdot2: SG heat removal rates
    """
    T_hot, T_cold1, T_cold2 = y

    dT_hot_dt = (P_r - W*(T_hot - T_cold1) - W*(T_hot - T_cold2)) / C_r
    dT_cold1_dt = (W*(T_hot - T_cold1) - Qdot1) / C_sg
    dT_cold2_dt = (W*(T_hot - T_cold2) - Qdot2) / C_sg

    return [dT_hot_dt, dT_cold1_dt, dT_cold2_dt]

# Initial conditions at equilibrium
y0 = [450, 450, 450]

# Time array: 0 to 30 seconds
t = np.linspace(0, 30, 500)

# Solve for different cases
solution = odeint(reactor_odes, y0, t, args=(W, C_r, C_sg, P_r, Qdot1, Qdot2))

T_hot = solution[:, 0]
T_cold1 = solution[:, 1]
T_cold2 = solution[:, 2]

# Calculate average temperature (mass-weighted, depends on mu)
T_ave = mu*T_hot + (1-mu)*(T_cold1 + T_cold2)/2
\end{lstlisting}

\subsubsection*{Solution}

Transient simulations were performed for four cases using numerical integration (scipy.integrate.odeint):

\textbf{Cases simulated:}
\begin{enumerate}
    \item $\mu = 0.5$, equally loaded ($\dot{Q}_1 = 50\%$, $\dot{Q}_2 = 50\%$)
    \item $\mu = 0.75$, equally loaded ($\dot{Q}_1 = 50\%$, $\dot{Q}_2 = 50\%$)
    \item $\mu = 0.5$, unequally loaded ($\dot{Q}_1 = 60\%$, $\dot{Q}_2 = 40\%$)
    \item $\mu = 0.75$, unequally loaded ($\dot{Q}_1 = 60\%$, $\dot{Q}_2 = 40\%$)
\end{enumerate}

All cases assume reactor power $P_r = 100\%$ and initial conditions at equilibrium ($T_{hot} = T_{cold1} = T_{cold2} = 450$ \degree F).

\textbf{Note:} Power percentages refer to fraction of total reactor power, not individual SG ratings.

\textbf{Equally Loaded Cases:}

\begin{center}
\includegraphics[width=0.95\textwidth]{../python/problem1_equal_loading.png}
\end{center}

\textbf{Unequally Loaded Cases:}

\begin{center}
\includegraphics[width=0.95\textwidth]{../python/problem1_unequal_loading.png}
\end{center}
