Dane Sabo 943066540c Auto sync: 2025-11-10 18:04:37 (36 files changed)
M  .task/backlog.data

M  .task/completed.data

M  .task/pending.data

M  .task/undo.data

A  Class_Work/nuce2101/exam2/NUCE2101_SABO/Submission.pdf

A  Class_Work/nuce2101/exam2/NUCE2101_SABO/problem1.py

A  Class_Work/nuce2101/exam2/NUCE2101_SABO/problem1_equal_loading.png

A  Class_Work/nuce2101/exam2/NUCE2101_SABO/problem1_unequal_loading.png
2025-11-10 18:04:37 -05:00

322 lines
11 KiB
Python

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
# Problem 1: Two-Loop Reactor System
print("=== Problem 1: Two-Loop Reactor with Steam Generators ===\n")
# Given Parameters
mu = None # Reactor Water Mass Fraction (RWMF) - to be determined or specified
# Base parameters
C_0 = 33.33 # Base Heat Capacity [%-sec/°F]
tau_0 = 0.75 * C_0 # Base Time Constant [sec/(%-sec/°F)] * C_0 = [sec]
# Initial steady state temperature
T_hot_initial = 450 # °F (reactor outlet / hot leg temperature)
T_cold_1_initial = 450 # °F (cold leg 1 temperature)
T_cold_2_initial = 450 # °F (cold leg 2 temperature)
print("Base Parameters:")
print(f"C_0 (Base Heat Capacity) = {C_0:.2f} %-sec/°F")
print(f"tau_0 (Base Time Constant) = {tau_0:.2f} sec")
print(f"\nInitial Steady State:")
print(f"T_hot = {T_hot_initial} °F")
print(f"T_cold_1 = {T_cold_1_initial} °F")
print(f"T_cold_2 = {T_cold_2_initial} °F")
# System parameters as functions of mu (RWMF)
def calculate_system_parameters(mu):
"""
Calculate system parameters based on Reactor Water Mass Fraction (mu)
Parameters:
mu: Reactor Water Mass Fraction (RWMF)
Returns:
dict: Dictionary containing all calculated parameters
"""
# Reactor parameters
tau_r = mu * tau_0 # Reactor time constant [sec]
C_r = mu * C_0 # Reactor heat capacity [%-sec/°F]
# Steam Generator parameters (each)
tau_sg = (1 - mu) * tau_r / 2 # Steam Generator water time constant [sec]
C_sg = (1 - mu) * C_0 / 2 # Steam Generator heat capacity [%-sec/°F]
params = {
"mu": mu,
"tau_r": tau_r,
"C_r": C_r,
"tau_sg": tau_sg,
"C_sg": C_sg,
"C_0": C_0,
"tau_0": tau_0,
}
return params
# Example: Calculate parameters for mu = 0.5 (50% of water in reactor)
if mu is None:
mu_example = 0.5
print(f"\n--- Example with mu = {mu_example} ---")
params = calculate_system_parameters(mu_example)
print(f"\nReactor Parameters:")
print(f" tau_r (Reactor time constant) = {params['tau_r']:.2f} sec")
print(f" C_r (Reactor heat capacity) = {params['C_r']:.2f} %-sec/°F")
print(f"\nSteam Generator Parameters (each):")
print(f" tau_sg (SG water time constant) = {params['tau_sg']:.2f} sec")
print(f" C_sg (SG heat capacity) = {params['C_sg']:.2f} %-sec/°F")
# System description
print(f"\n" + "=" * 60)
print("System Description:")
print("=" * 60)
print(
"""
Two-Loop Reactor System:
- Reactor (hot leg) at T_hot
- Steam Generator 1 with cold leg at T_cold_1
- Steam Generator 2 with cold leg at T_cold_2
- Each loop: pump → reactor → steam generator → back to pump
- Lumped reactor volume with combined hot branches
- Equal mass flow rates in each loop
- Ignore loop transport times
Key Assumptions:
- Each SG + cold loop has same water mass and flow rate
- Reactor and hot branches lumped into single water volume
- System initially at equilibrium (100% power, balanced)
- Constant average temperature maintained
"""
)
# Part A: Differential Equations
print(f"\n" + "=" * 60)
print("Part A: Differential Equations")
print("=" * 60)
def get_differential_equations(mu):
"""
Develop differential equations for T_hot, T_cold1, T_cold2
Key insight: Flow heat capacity rate W = C_0 / (2 * tau_0)
This is the (mass flow rate * specific heat) for each loop
"""
params = calculate_system_parameters(mu)
# Flow heat capacity rate for each loop (same for both loops)
W = C_0 / (2 * tau_0)
print(f"\nFor mu = {mu}:")
print(f"Flow heat capacity rate (each loop): W = {W:.4f} %-sec/°F")
print(f"C_r = {params['C_r']:.2f}, C_sg = {params['C_sg']:.2f}")
print(f"\nDifferential Equations:")
print(f" C_r * dT_hot/dt = P_r - W*(T_hot - T_cold1) - W*(T_hot - T_cold2)")
print(f" C_sg * dT_cold1/dt = W*(T_hot - T_cold1) - Qdot1")
print(f" C_sg * dT_cold2/dt = W*(T_hot - T_cold2) - Qdot2")
print(f"\nwhere:")
print(f" P_r = reactor power (positive for heat generation)")
print(f" Qdot1, Qdot2 = SG heat removal rates (positive for heat removal)")
print(f" W = {W:.4f} %-sec/°F (flow heat capacity rate per loop)")
# Matrix form: dT/dt = A*T + B
print(f"\n--- Matrix Form: dT/dt = A*T + B ---")
# Coefficient matrix A
A = np.array(
[
[-2 * W / params["C_r"], W / params["C_r"], W / params["C_r"]],
[W / params["C_sg"], -W / params["C_sg"], 0],
[W / params["C_sg"], 0, -W / params["C_sg"]],
]
)
print(f"\nMatrix A (coefficients):")
print(f" [{A[0,0]:7.4f} {A[0,1]:7.4f} {A[0,2]:7.4f}]")
print(f" [{A[1,0]:7.4f} {A[1,1]:7.4f} {A[1,2]:7.4f}]")
print(f" [{A[2,0]:7.4f} {A[2,1]:7.4f} {A[2,2]:7.4f}]")
# For general case with P_r, Qdot1, Qdot2
print(f"\nVector B (forcing terms, depends on P_r, Qdot1, Qdot2):")
print(f" [P_r/C_r, -Qdot1/C_sg, -Qdot2/C_sg]^T")
print(
f" [P_r/{params['C_r']:.2f}, -Qdot1/{params['C_sg']:.2f}, -Qdot2/{params['C_sg']:.2f}]^T"
)
return W, params
# Part D: Transient Simulation Setup
print(f"\n" + "=" * 60)
print("Part D: Transient Simulation (0 to 30 seconds)")
print("=" * 60)
def reactor_odes(y, t, W, C_r, C_sg, P_r, Q1, Q2):
"""
ODE system for two-loop reactor
y = [T_hot, T_cold1, T_cold2]
Parameters:
P_r: Reactor power (heat generation rate)
Q1, Q2: Steam generator heat removal rates (Qdot_1, Qdot_2)
"""
T_hot, T_cold1, T_cold2 = y
# Reactor energy balance
dT_hot_dt = (P_r - W * (T_hot - T_cold1) - W * (T_hot - T_cold2)) / C_r
# Steam generator 1 energy balance (Q1 is heat removal rate)
dT_cold1_dt = (W * (T_hot - T_cold1) - Q1) / C_sg
# Steam generator 2 energy balance (Q2 is heat removal rate)
dT_cold2_dt = (W * (T_hot - T_cold2) - Q2) / C_sg
return [dT_hot_dt, dT_cold1_dt, dT_cold2_dt]
def simulate_transient(mu, Q1_percent, Q2_percent, t_max=30):
"""
Simulate reactor transient
Parameters:
mu: Reactor Water Mass Fraction
Q1_percent: Steam generator 1 heat removal rate (% of nominal)
Q2_percent: Steam generator 2 heat removal rate (% of nominal)
t_max: Simulation time (seconds)
"""
params = calculate_system_parameters(mu)
W = C_0 / (2 * tau_0)
# Initial conditions (steady state at 100% power balanced)
T_hot_0 = T_hot_initial
T_cold1_0 = T_cold_1_initial
T_cold2_0 = T_cold_2_initial
y0 = [T_hot_0, T_cold1_0, T_cold2_0]
# Power levels (normalized - 100% = 1.0 in appropriate units)
P_r = 100.0 # Reactor power (heat generation rate)
Q1 = Q1_percent # SG1 heat removal rate
Q2 = Q2_percent # SG2 heat removal rate
# Time array
t = np.linspace(0, t_max, 500)
# Solve ODE system
solution = odeint(
reactor_odes, y0, t, args=(W, params["C_r"], params["C_sg"], P_r, Q1, Q2)
)
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
return t, T_hot, T_cold1, T_cold2, T_ave
# Example: Show how to set up simulations
print("\nSimulation cases to run:")
print("1. mu=0.5, Q1=50%, Q2=50% (equally loaded)")
print("2. mu=0.75, Q1=50%, Q2=50% (equally loaded)")
print("3. mu=0.5, Q1=60%, Q2=40% (unequally loaded)")
print("4. mu=0.75, Q1=60%, Q2=40% (unequally loaded)")
print("\nNote: Percentages are fractions of reactor power (P_r = 100%)")
# Run example simulation
print("\n--- Running Example: mu=0.5, Equal Loading ---")
W_example, params_example = get_differential_equations(0.5)
# Run all simulations and create plots
print("\n" + "=" * 60)
print("Running Simulations and Creating Plots")
print("=" * 60)
# Case 1 & 2: Equally loaded (Q1=50%, Q2=50%)
fig1, axes1 = plt.subplots(2, 2, figsize=(14, 10))
fig1.suptitle(
"Equally Loaded Steam Generators (Q1=50%, Q2=50%)", fontsize=14, fontweight="bold"
)
for idx, mu in enumerate([0.5, 0.75]):
print(f"\nSimulating mu={mu}, Q1=50%, Q2=50%")
t, T_hot, T_cold1, T_cold2, T_ave = simulate_transient(mu, 50.0, 50.0)
# Plot temperatures
ax = axes1[idx, 0]
ax.plot(t, T_hot, "r-", linewidth=2, label="T_hot")
ax.plot(t, T_cold1, "b-", linewidth=2, label="T_cold1")
ax.plot(t, T_cold2, "g-", linewidth=2, label="T_cold2")
ax.plot(t, T_ave, "k--", linewidth=2, label="T_ave")
ax.set_xlabel("Time (sec)", fontsize=10)
ax.set_ylabel("Temperature (°F)", fontsize=10)
ax.set_title(f"mu = {mu} (RWMF)", fontsize=11, fontweight="bold")
ax.grid(True, alpha=0.3)
ax.legend(loc="best")
# Plot temperature differences
ax = axes1[idx, 1]
ax.plot(t, T_hot - T_cold1, "b-", linewidth=2, label="ΔT1 = T_hot - T_cold1")
ax.plot(t, T_hot - T_cold2, "g-", linewidth=2, label="ΔT2 = T_hot - T_cold2")
ax.set_xlabel("Time (sec)", fontsize=10)
ax.set_ylabel("Temperature Difference (°F)", fontsize=10)
ax.set_title(f"Temperature Differences (mu = {mu})", fontsize=11, fontweight="bold")
ax.grid(True, alpha=0.3)
ax.legend(loc="best")
plt.tight_layout()
plt.savefig("problem1_equal_loading.png", dpi=300, bbox_inches="tight")
print("Plot saved: problem1_equal_loading.png")
plt.close()
# Case 3 & 4: Unequally loaded (Q1=60%, Q2=40%)
fig2, axes2 = plt.subplots(2, 2, figsize=(14, 10))
fig2.suptitle(
"Unequally Loaded Steam Generators (Q1=60%, Q2=40%)", fontsize=14, fontweight="bold"
)
for idx, mu in enumerate([0.5, 0.75]):
print(f"\nSimulating mu={mu}, Q1=60%, Q2=40%")
t, T_hot, T_cold1, T_cold2, T_ave = simulate_transient(mu, 60.0, 40.0)
# Plot temperatures
ax = axes2[idx, 0]
ax.plot(t, T_hot, "r-", linewidth=2, label="T_hot")
ax.plot(t, T_cold1, "b-", linewidth=2, label="T_cold1")
ax.plot(t, T_cold2, "g-", linewidth=2, label="T_cold2")
ax.plot(t, T_ave, "k--", linewidth=2, label="T_ave")
ax.set_xlabel("Time (sec)", fontsize=10)
ax.set_ylabel("Temperature (°F)", fontsize=10)
ax.set_title(f"mu = {mu} (RWMF)", fontsize=11, fontweight="bold")
ax.grid(True, alpha=0.3)
ax.legend(loc="best")
# Plot temperature differences
ax = axes2[idx, 1]
ax.plot(t, T_hot - T_cold1, "b-", linewidth=2, label="ΔT1 = T_hot - T_cold1")
ax.plot(t, T_hot - T_cold2, "g-", linewidth=2, label="ΔT2 = T_hot - T_cold2")
ax.set_xlabel("Time (sec)", fontsize=10)
ax.set_ylabel("Temperature Difference (°F)", fontsize=10)
ax.set_title(f"Temperature Differences (mu = {mu})", fontsize=11, fontweight="bold")
ax.grid(True, alpha=0.3)
ax.legend(loc="best")
plt.tight_layout()
plt.savefig("problem1_unequal_loading.png", dpi=300, bbox_inches="tight")
print("Plot saved: problem1_unequal_loading.png")
plt.close()
print("\n" + "=" * 60)
print("Simulation Complete!")
print("=" * 60)