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
218 lines
7.9 KiB
Python
218 lines
7.9 KiB
Python
import numpy as np
|
|
|
|
# Two-group cross-section data
|
|
cross_sections = {
|
|
"fast": {
|
|
"D": 1.4, # Diffusion constant [cm]
|
|
"Sigma_a": 0.010, # Absorption [cm^-1]
|
|
"Sigma_s": 0.050, # Scattering from fast to thermal [cm^-1]
|
|
"nu_Sigma_f": 0.000, # Neutrons per fission times fission cross section [cm^-1]
|
|
"chi": 1, # Neutron group distribution (fission spectrum)
|
|
"v": 1.8e7, # Average group velocity [cm/sec]
|
|
},
|
|
"thermal": {
|
|
"D": 0.35, # Diffusion constant [cm]
|
|
"Sigma_a": 0.080, # Absorption [cm^-1]
|
|
"Sigma_s": 0.0, # Scattering from thermal to fast [cm^-1]
|
|
"nu_Sigma_f": 0.125, # Neutrons per fission times fission cross section [cm^-1]
|
|
"chi": 0, # Neutron group distribution (fission spectrum)
|
|
"v": 2.2e5, # Average group velocity [cm/sec]
|
|
},
|
|
"scattering": {
|
|
"fast_to_thermal": 0.050, # Sigma_s^(1->2) [cm^-1]
|
|
"thermal_to_fast": 0.0, # Sigma_s^(2->1) [cm^-1]
|
|
},
|
|
}
|
|
|
|
# Easy access shortcuts
|
|
D_fast = cross_sections["fast"]["D"]
|
|
D_thermal = cross_sections["thermal"]["D"]
|
|
Sigma_a_fast = cross_sections["fast"]["Sigma_a"]
|
|
Sigma_a_thermal = cross_sections["thermal"]["Sigma_a"]
|
|
Sigma_s_fast = cross_sections["fast"]["Sigma_s"] # Scattering from fast to thermal
|
|
Sigma_s_thermal = cross_sections["thermal"][
|
|
"Sigma_s"
|
|
] # Scattering from thermal to fast
|
|
nu_Sigma_f_fast = cross_sections["fast"]["nu_Sigma_f"]
|
|
nu_Sigma_f_thermal = cross_sections["thermal"]["nu_Sigma_f"]
|
|
chi_fast = cross_sections["fast"]["chi"]
|
|
chi_thermal = cross_sections["thermal"]["chi"]
|
|
v_fast = cross_sections["fast"]["v"]
|
|
v_thermal = cross_sections["thermal"]["v"]
|
|
|
|
print("Two-Group Cross-Section Data Loaded")
|
|
print(f"Fast Group: D={D_fast} cm, Sigma_a={Sigma_a_fast} cm^-1, v={v_fast:.2e} cm/s")
|
|
print(
|
|
f"Thermal Group: D={D_thermal} cm, Sigma_a={Sigma_a_thermal} cm^-1, v={v_thermal:.2e} cm/s"
|
|
)
|
|
|
|
# Problem 2A: Calculate k_inf using Four-Factor Formula
|
|
# k_inf = epsilon * p * f * eta
|
|
# where:
|
|
# epsilon = fast fission factor (neutrons from fast fission per thermal fission)
|
|
# p = resonance escape probability (fraction of fast neutrons reaching thermal)
|
|
# f = thermal utilization factor (thermal neutrons absorbed in fuel vs total)
|
|
# eta = reproduction factor (neutrons produced per thermal neutron absorbed in fuel)
|
|
|
|
# Fast fission factor: epsilon = 1 (no fast fissions since nu_Sigma_f_fast = 0)
|
|
epsilon = 1.0
|
|
|
|
# Resonance escape probability: fraction of fast neutrons that scatter to thermal
|
|
# p = Sigma_s_fast / (Sigma_a_fast + Sigma_s_fast)
|
|
p = Sigma_s_fast / (Sigma_a_fast + Sigma_s_fast)
|
|
|
|
# Thermal utilization factor: f = 1 (single-region, all absorptions in "fuel")
|
|
f = 1.0
|
|
|
|
# Reproduction factor: eta = nu*Sigma_f / Sigma_a (thermal group)
|
|
eta = nu_Sigma_f_thermal / Sigma_a_thermal
|
|
|
|
# Four-Factor Formula
|
|
k_inf = epsilon * p * f * eta
|
|
|
|
print(f"\n=== Problem 2A: k_infinity (Four-Factor Formula) ===")
|
|
print(f"epsilon (fast fission factor) = {epsilon:.4f}")
|
|
print(f"p (resonance escape probability) = {p:.4f}")
|
|
print(f"f (thermal utilization) = {f:.4f}")
|
|
print(f"eta (reproduction factor) = {eta:.4f}")
|
|
print(f"k_inf = epsilon * p * f * eta = {k_inf:.4f}")
|
|
|
|
# Problem 2B: Calculate diffusion lengths
|
|
import sympy as sm
|
|
|
|
# Define buckling as a symbol
|
|
B_squared = sm.Symbol("B^2", positive=True)
|
|
|
|
# Calculate diffusion lengths
|
|
# L^2_fast = D_fast / Sigma_total_fast
|
|
# where Sigma_total_fast = Sigma_a_fast + Sigma_s_fast (removal from fast group)
|
|
Sigma_total_fast = Sigma_a_fast + Sigma_s_fast
|
|
L_squared_fast = D_fast / Sigma_total_fast
|
|
|
|
# L^2_th = D_th / Sigma_a_th
|
|
L_squared_th = D_thermal / Sigma_a_thermal
|
|
|
|
print(f"\n=== Problem 2B: Diffusion Lengths ===")
|
|
print(f"L_fast = {np.sqrt(L_squared_fast):.3f} cm")
|
|
print(f"L_thermal = {np.sqrt(L_squared_th):.3f} cm")
|
|
print(f"\nL^2_fast = {L_squared_fast:.3f} cm^2")
|
|
print(f"L^2_thermal = {L_squared_th:.3f} cm^2")
|
|
|
|
# k_eff equation as function of buckling (for reference):
|
|
# k_eff = k_inf / [(L^2_fast * B^2 + 1)(L^2_th * B^2 + 1)]
|
|
# At criticality: k_eff = 1
|
|
k_eff_expr = k_inf / ((L_squared_fast * B_squared + 1) * (L_squared_th * B_squared + 1))
|
|
|
|
print(f"\nCriticality relation:")
|
|
print(f"k_eff = k_inf / [(L^2_fast * B^2 + 1)(L^2_thermal * B^2 + 1)]")
|
|
print(
|
|
f"k_eff = {k_inf:.4f} / [({L_squared_fast:.3f}*B^2 + 1)({L_squared_th:.3f}*B^2 + 1)]"
|
|
)
|
|
|
|
# Problem 2C: Geometric buckling for rectangular solid
|
|
print(f"\n=== Problem 2C: Geometric Buckling ===")
|
|
print(f"For a rectangular solid with dimensions L_x, L_y, L_z")
|
|
print(f"with flux going to zero at the boundaries (bare reactor):")
|
|
print(f"\nB^2 = (pi/L_x)^2 + (pi/L_y)^2 + (pi/L_z)^2")
|
|
print(f"\nThis is the geometric buckling for the fundamental mode.")
|
|
|
|
# Example calculation with symbolic dimensions
|
|
L_x, L_y, L_z = sm.symbols("L_x L_y L_z", positive=True)
|
|
B_squared_geometric = (sm.pi / L_x) ** 2 + (sm.pi / L_y) ** 2 + (sm.pi / L_z) ** 2
|
|
print(f"\nSymbolic expression:")
|
|
print(f"B^2 = {B_squared_geometric}")
|
|
|
|
# Problem 2D: Critical height of trough
|
|
print(f"\n=== Problem 2D: Critical Height of Trough ===")
|
|
print(f"Given: Width L_x = 150 cm, Length L_y = 200 cm")
|
|
print(f"Find: Height L_z for criticality (k_eff = 1)")
|
|
|
|
# Given dimensions
|
|
L_x_val = 150 # cm
|
|
L_y_val = 200 # cm
|
|
|
|
# At criticality: k_eff = 1 = k_inf / [(L²_fast * B² + 1)(L²_thermal * B² + 1)]
|
|
# Rearranging: (L²_fast * B² + 1)(L²_thermal * B² + 1) = k_inf
|
|
# where: B² = (π/L_x)² + (π/L_y)² + (π/L_z)²
|
|
|
|
# Define L_z as unknown
|
|
L_z_sym = sm.Symbol("L_z", positive=True)
|
|
|
|
# Buckling with known dimensions and unknown height
|
|
B_sq = (sm.pi / L_x_val) ** 2 + (sm.pi / L_y_val) ** 2 + (sm.pi / L_z_sym) ** 2
|
|
|
|
# Criticality equation: k_inf = (L²_fast * B² + 1)(L²_thermal * B² + 1)
|
|
criticality_eq = (L_squared_fast * B_sq + 1) * (L_squared_th * B_sq + 1) - k_inf
|
|
|
|
# Solve for L_z
|
|
L_z_solutions = sm.solve(criticality_eq, L_z_sym)
|
|
|
|
# Filter for positive real solutions
|
|
L_z_critical = None
|
|
for sol in L_z_solutions:
|
|
if sol.is_real and sol > 0:
|
|
L_z_critical = float(sol)
|
|
break
|
|
|
|
if L_z_critical:
|
|
print(f"\nCritical height L_z = {L_z_critical:.2f} cm")
|
|
|
|
# Verify by calculating k_eff
|
|
B_sq_check = (
|
|
(np.pi / L_x_val) ** 2 + (np.pi / L_y_val) ** 2 + (np.pi / L_z_critical) ** 2
|
|
)
|
|
k_eff_check = k_inf / (
|
|
(L_squared_fast * B_sq_check + 1) * (L_squared_th * B_sq_check + 1)
|
|
)
|
|
print(f"\nVerification: k_eff = {k_eff_check:.6f} (should be 1.0)")
|
|
print(f"Geometric buckling B^2 = {B_sq_check:.6f} cm^-2")
|
|
else:
|
|
print("No positive real solution found!")
|
|
|
|
# Problem 2E: Prompt criticality
|
|
print(f"\n=== Problem 2E: Prompt Critical Height ===")
|
|
BETA = 640e-5 # Delayed neutron fraction
|
|
print(f"Beta (delayed neutron fraction) = {BETA:.6f}")
|
|
|
|
# Prompt criticality occurs when k_eff = 1/(1-beta)
|
|
k_eff_prompt = 1 / (1 - BETA)
|
|
print(f"Prompt critical k_eff = 1/(1-beta) = {k_eff_prompt:.6f}")
|
|
|
|
# Solve for height at prompt criticality
|
|
# k_eff_prompt = k_inf / [(L²_fast * B² + 1)(L²_thermal * B² + 1)]
|
|
# Rearranging: (L²_fast * B² + 1)(L²_thermal * B² + 1) = k_inf / k_eff_prompt
|
|
|
|
L_z_prompt_sym = sm.Symbol("L_z_prompt", positive=True)
|
|
B_sq_prompt = (
|
|
(sm.pi / L_x_val) ** 2 + (sm.pi / L_y_val) ** 2 + (sm.pi / L_z_prompt_sym) ** 2
|
|
)
|
|
|
|
prompt_crit_eq = (L_squared_fast * B_sq_prompt + 1) * (
|
|
L_squared_th * B_sq_prompt + 1
|
|
) - k_inf / k_eff_prompt
|
|
|
|
L_z_prompt_solutions = sm.solve(prompt_crit_eq, L_z_prompt_sym)
|
|
|
|
# Filter for positive real solutions
|
|
L_z_prompt = None
|
|
for sol in L_z_prompt_solutions:
|
|
if sol.is_real and sol > 0:
|
|
L_z_prompt = float(sol)
|
|
break
|
|
|
|
if L_z_prompt:
|
|
print(f"\nPrompt critical height L_z = {L_z_prompt:.2f} cm")
|
|
|
|
# Verify
|
|
B_sq_prompt_check = (
|
|
(np.pi / L_x_val) ** 2 + (np.pi / L_y_val) ** 2 + (np.pi / L_z_prompt) ** 2
|
|
)
|
|
k_eff_prompt_check = k_inf / (
|
|
(L_squared_fast * B_sq_prompt_check + 1)
|
|
* (L_squared_th * B_sq_prompt_check + 1)
|
|
)
|
|
print(f"\nVerification: k_eff = {k_eff_prompt_check:.6f}")
|
|
print(f"Difference from delayed critical: {L_z_prompt - L_z_critical:.2f} cm")
|
|
else:
|
|
print("No positive real solution found!")
|