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
211 lines
6.6 KiB
Python
211 lines
6.6 KiB
Python
import sympy as sm
|
|
import numpy as np
|
|
|
|
print("="*70)
|
|
print("Problem 1: SymPy Verification")
|
|
print("="*70)
|
|
|
|
# Define symbols
|
|
T_hot, T_cold1, T_cold2 = sm.symbols('T_hot T_cold1 T_cold2')
|
|
P_r, Qdot1, Qdot2 = sm.symbols('P_r Qdot_1 Qdot_2', positive=True)
|
|
C_r, C_sg, W = sm.symbols('C_r C_sg W', positive=True)
|
|
C_0, tau_0, mu = sm.symbols('C_0 tau_0 mu', positive=True)
|
|
t = sm.symbols('t', positive=True)
|
|
|
|
print("\n--- Part A: Derive Differential Equations ---")
|
|
|
|
# Energy balance equations
|
|
print("\nReactor energy balance:")
|
|
reactor_eq = sm.Eq(C_r * sm.Derivative(T_hot, t),
|
|
P_r - W*(T_hot - T_cold1) - W*(T_hot - T_cold2))
|
|
print(f"C_r * dT_hot/dt = P_r - W*(T_hot - T_cold1) - W*(T_hot - T_cold2)")
|
|
print(reactor_eq)
|
|
|
|
print("\nSteam Generator 1 energy balance:")
|
|
sg1_eq = sm.Eq(C_sg * sm.Derivative(T_cold1, t),
|
|
W*(T_hot - T_cold1) - Qdot1)
|
|
print(f"C_sg * dT_cold1/dt = W*(T_hot - T_cold1) - Qdot1")
|
|
print(sg1_eq)
|
|
|
|
print("\nSteam Generator 2 energy balance:")
|
|
sg2_eq = sm.Eq(C_sg * sm.Derivative(T_cold2, t),
|
|
W*(T_hot - T_cold2) - Qdot2)
|
|
print(f"C_sg * dT_cold2/dt = W*(T_hot - T_cold2) - Qdot2")
|
|
print(sg2_eq)
|
|
|
|
# Expand and simplify to get matrix form
|
|
print("\n--- Expanding to Matrix Form: dT/dt = A*T + B ---")
|
|
|
|
# Reactor equation expanded
|
|
reactor_rhs = P_r - W*T_hot + W*T_cold1 - W*T_hot + W*T_cold2
|
|
reactor_rhs_simplified = sm.expand(reactor_rhs)
|
|
print(f"\nReactor RHS expanded:")
|
|
print(f" = P_r - 2W*T_hot + W*T_cold1 + W*T_cold2")
|
|
print(f" = {reactor_rhs_simplified}")
|
|
|
|
dT_hot_dt = reactor_rhs_simplified / C_r
|
|
print(f"\ndT_hot/dt = {dT_hot_dt}")
|
|
|
|
# SG1 equation expanded
|
|
sg1_rhs = W*T_hot - W*T_cold1 - Qdot1
|
|
dT_cold1_dt = sg1_rhs / C_sg
|
|
print(f"\ndT_cold1/dt = {dT_cold1_dt}")
|
|
|
|
# SG2 equation expanded
|
|
sg2_rhs = W*T_hot - W*T_cold2 - Qdot2
|
|
dT_cold2_dt = sg2_rhs / C_sg
|
|
print(f"\ndT_cold2/dt = {dT_cold2_dt}")
|
|
|
|
# Extract coefficient matrix A
|
|
print("\n--- Constructing Matrix A ---")
|
|
A_symbolic = sm.Matrix([
|
|
[sm.diff(dT_hot_dt, T_hot), sm.diff(dT_hot_dt, T_cold1), sm.diff(dT_hot_dt, T_cold2)],
|
|
[sm.diff(dT_cold1_dt, T_hot), sm.diff(dT_cold1_dt, T_cold1), sm.diff(dT_cold1_dt, T_cold2)],
|
|
[sm.diff(dT_cold2_dt, T_hot), sm.diff(dT_cold2_dt, T_cold1), sm.diff(dT_cold2_dt, T_cold2)]
|
|
])
|
|
|
|
print("\nMatrix A (symbolic):")
|
|
sm.pprint(A_symbolic)
|
|
|
|
# Extract forcing vector B
|
|
print("\n--- Constructing Vector B ---")
|
|
# B contains the terms without T_hot, T_cold1, T_cold2
|
|
B_symbolic = sm.Matrix([
|
|
P_r/C_r,
|
|
-Qdot1/C_sg,
|
|
-Qdot2/C_sg
|
|
])
|
|
|
|
print("\nVector B (symbolic):")
|
|
sm.pprint(B_symbolic)
|
|
|
|
# Verify: dT/dt = A*T + B
|
|
T_vector = sm.Matrix([T_hot, T_cold1, T_cold2])
|
|
dT_dt_vector = sm.Matrix([dT_hot_dt, dT_cold1_dt, dT_cold2_dt])
|
|
|
|
reconstructed = A_symbolic * T_vector + B_symbolic
|
|
|
|
print("\n--- Verification: A*T + B = dT/dt ---")
|
|
print("Checking if A*T + B equals our derived dT/dt...")
|
|
|
|
for i in range(3):
|
|
diff = sm.simplify(reconstructed[i] - dT_dt_vector[i])
|
|
if diff == 0:
|
|
print(f" Row {i+1}: ✓ VERIFIED")
|
|
else:
|
|
print(f" Row {i+1}: ✗ ERROR - Difference: {diff}")
|
|
|
|
# Numerical example for mu = 0.5
|
|
print("\n" + "="*70)
|
|
print("Numerical Example: mu = 0.5")
|
|
print("="*70)
|
|
|
|
C_0_val = 33.33
|
|
tau_0_val = 25.00
|
|
W_val = C_0_val / (2 * tau_0_val)
|
|
mu_val = 0.5
|
|
|
|
C_r_val = mu_val * C_0_val
|
|
C_sg_val = (1 - mu_val) * C_0_val / 2
|
|
|
|
print(f"\nC_0 = {C_0_val:.2f} %-sec/°F")
|
|
print(f"tau_0 = {tau_0_val:.2f} sec")
|
|
print(f"W = {W_val:.4f} %-sec/°F")
|
|
print(f"C_r = {C_r_val:.2f} %-sec/°F")
|
|
print(f"C_sg = {C_sg_val:.2f} %-sec/°F")
|
|
|
|
# Substitute numerical values
|
|
A_numerical = A_symbolic.subs([(C_r, C_r_val), (C_sg, C_sg_val), (W, W_val)])
|
|
print("\nMatrix A (numerical for mu=0.5):")
|
|
sm.pprint(A_numerical)
|
|
print("\nAs float matrix:")
|
|
A_float = np.array(A_numerical).astype(float)
|
|
print(A_float)
|
|
|
|
print("\n--- Part B: Steady State Analysis ---")
|
|
|
|
# At steady state, dT/dt = 0, so A*T + B = 0
|
|
# This means A*T = -B
|
|
|
|
print("\nAt steady state: A*T_ss + B = 0")
|
|
print("Solving for temperature differences...")
|
|
|
|
# From SG1: 0 = W*T_hot - W*T_cold1 - Qdot1
|
|
# Rearranging: W*(T_hot - T_cold1) = Qdot1
|
|
DeltaT1 = Qdot1 / W
|
|
print(f"\nFrom SG1: W*(T_hot - T_cold1) = Qdot1")
|
|
print(f"ΔT1 = T_hot - T_cold1 = {DeltaT1}")
|
|
|
|
# From SG2: 0 = W*T_hot - W*T_cold2 - Qdot2
|
|
# Rearranging: W*(T_hot - T_cold2) = Qdot2
|
|
DeltaT2 = Qdot2 / W
|
|
print(f"\nFrom SG2: W*(T_hot - T_cold2) = Qdot2")
|
|
print(f"ΔT2 = T_hot - T_cold2 = {DeltaT2}")
|
|
|
|
# From reactor: 0 = P_r - W*DeltaT1 - W*DeltaT2
|
|
power_balance = sm.simplify(P_r - W*DeltaT1 - W*DeltaT2)
|
|
print(f"\nPower balance check:")
|
|
print(f"P_r - W*ΔT1 - W*ΔT2 = {power_balance}")
|
|
print(f"Therefore: P_r = Qdot1 + Qdot2 ✓")
|
|
|
|
print("\n--- Part C: Average Temperature ---")
|
|
|
|
# Given formula
|
|
T_ave_given = T_hot/2 + (T_cold1 + T_cold2)/4
|
|
|
|
print(f"\nGiven: T_ave = T_hot/2 + (T_cold1 + T_cold2)/4")
|
|
print(f"T_ave = {T_ave_given}")
|
|
|
|
# Mass-weighted average
|
|
T_ave_mass_weighted = (C_r*T_hot + C_sg*T_cold1 + C_sg*T_cold2) / (C_r + 2*C_sg)
|
|
|
|
print(f"\nMass-weighted: T_ave = (C_r*T_hot + C_sg*T_cold1 + C_sg*T_cold2)/(C_r + 2*C_sg)")
|
|
|
|
# Substitute C_r = mu*C_0 and C_sg = (1-mu)*C_0/2
|
|
T_ave_mass_weighted_sub = T_ave_mass_weighted.subs([
|
|
(C_r, mu*C_0),
|
|
(C_sg, (1-mu)*C_0/2)
|
|
])
|
|
T_ave_mass_weighted_simplified = sm.simplify(T_ave_mass_weighted_sub)
|
|
|
|
print(f"\nSubstituting C_r = mu*C_0, C_sg = (1-mu)*C_0/2:")
|
|
print(f"T_ave = {T_ave_mass_weighted_simplified}")
|
|
|
|
# Check if they're equal
|
|
print(f"\nChecking if given formula equals mass-weighted formula...")
|
|
difference = sm.simplify(T_ave_given - T_ave_mass_weighted_simplified)
|
|
print(f"Difference: {difference}")
|
|
|
|
if difference == 0:
|
|
print("✓ VERIFIED: Both formulas are equivalent!")
|
|
else:
|
|
print("✗ WARNING: Formulas differ!")
|
|
print(f"Given formula gives: {T_ave_given}")
|
|
print(f"Mass-weighted gives: {T_ave_mass_weighted_simplified}")
|
|
|
|
# Time derivative of total energy
|
|
print("\n--- Energy Conservation ---")
|
|
total_energy = C_r*T_hot + C_sg*T_cold1 + C_sg*T_cold2
|
|
|
|
dE_dt = sm.diff(total_energy, t)
|
|
print(f"\nTotal system energy: E = C_r*T_hot + C_sg*T_cold1 + C_sg*T_cold2")
|
|
print(f"dE/dt = {dE_dt}")
|
|
|
|
# Substitute the differential equations
|
|
dE_dt_expanded = (C_r*dT_hot_dt + C_sg*dT_cold1_dt + C_sg*dT_cold2_dt)
|
|
dE_dt_simplified = sm.simplify(dE_dt_expanded)
|
|
|
|
print(f"\nSubstituting the differential equations:")
|
|
print(f"dE/dt = {dE_dt_simplified}")
|
|
print(f"\nTherefore: dE/dt = P_r - Qdot1 - Qdot2")
|
|
print(f"When P_r = Qdot1 + Qdot2 (balanced), dE/dt = 0 ✓")
|
|
|
|
print("\n" + "="*70)
|
|
print("Verification Complete!")
|
|
print("="*70)
|
|
print("\nSummary:")
|
|
print("✓ Matrix form correctly derived")
|
|
print("✓ Steady-state equations verified")
|
|
print("✓ Average temperature formula needs clarification")
|
|
print("✓ Energy conservation verified")
|