Obsidian/Class_Work/nuce2101/exam2/python/problem1_verification.py
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

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")