I am trying to run this loop; however, I am getting a no attribute error in the second portion of my code. Below is the entire code (sorry for the length). When I run the first case (PWR) the code executes normally as expected. However, when I run the second case (BWR) I receive the error even though it is the same exact statement from case one. Is there any fix or explanation for this? Thank you.
import numpy as np
import math
from iapws import IAPWS97
import matplotlib.pyplot as plt
case = int(input('Which case [1 (PWR) or 2 (BWR)]? '))
if case == 1: # PWR
H = 3.8 # m
He = 3.8 # m
Pitch = 1.25 * 10 ** (-2) # m
Gap_t = 0.00006 # m
D_fuel = 0.0082 # m
k_gap = 0.25 # W/m-K
k_c = 21.5 # W/m-K
k_fuel = 3.6 # W/m-K
T0 = float(278 + 273.15) # K
q0_prime = float(330 * 10 ** (2)) # W/m
P0 = 15 # MPa
MF = float(3460) # kg/m^2-s
D_rod = .0095 # m
R_rod = D_rod / 2
R_fuel = D_fuel / 2
R_gap = R_fuel + Gap_t
R_clad = R_rod
Clad_t = D_rod - D_fuel - Gap_t # m
h0_enthalpy = (IAPWS97(T=T0, P=P0).h) * 10 ** (3)
T_sat0 = IAPWS97(P=P0, x=0).T
g = 9.81 # m/s
# geometry properties
heated_p = math.pi * D_rod
wetted_p = math.pi * D_rod
A_f = (Pitch ** 2) - ((1 / 4) * math.pi * (D_rod ** 2))
D_H = (4 * A_f) / heated_p
# grid setup
grid_points = 100
dz = H / grid_points
z_array = np.arange(0, H, dz)
z_arrayplots = np.arange(0, H, dz)
q_HeatFluxList = []
# defining array of q'' values in list
for z in z_array:
heat_fluxA = (q0_prime / (math.pi * D_rod)) * math.sin(math.pi * (z / He))
q_HeatFluxList.append(heat_fluxA)
q_heat_flux = np.array(q_HeatFluxList)
q_prime = np.zeros(len(z_array))
for i in range(0, len(z_array)):
q_prime[i] = q0_prime * math.sin((np.pi * z_array[i]) / He)
# defining array of h values
h_enthalpy_list = []
h_enthalpy_prefactor = ((heated_p * q0_prime * H) / (A_f * MF * (math.pi ** 2) * D_rod))
for z in z_array:
h_enthalpy = (-h_enthalpy_prefactor * math.cos(math.pi * (z / He))) + h_enthalpy_prefactor + h0_enthalpy
h_enthalpy_list.append(h_enthalpy)
h_enthalpy_array_J = np.array(h_enthalpy_list)
h_enthalpy_array = h_enthalpy_array_J * 10 ** (-3)
P_array = np.zeros(len(z_array))
P_array[0] = P0
T_sat = np.zeros(len(z_array))
T_sat[0] = T_sat0
T_f_array = np.zeros(len(z_array))
T_f_array[0] = T0
Re = np.zeros(len(z_array))
Re_f = np.zeros(len(z_array))
Pr = np.zeros(len(z_array))
k_fluid = np.zeros(len(z_array))
x_array = np.zeros(len(z_array))
xe_array = np.zeros(len(z_array))
frictional = np.zeros(len(z_array))
gravitational = np.zeros(len(z_array))
compressibility = np.zeros(len(z_array))
# Pressure Loop PWR
dp = 0.001
for i in range(0, len(z_array) - 1):
rho_f = IAPWS97(P=P_array[i], x=0).rho
vf = IAPWS97(P=P_array[i], x=0).v
vg = IAPWS97(P=P_array[i], x=1).v
hf_enthalpy = IAPWS97(P=P_array[i], x=0).h
hg_enthalpy = IAPWS97(P=P_array[i], x=1).h
muf = (IAPWS97(P=P_array[i], x=0).mu) * 10 ** (-6)
mug = (IAPWS97(P=P_array[i], x=1).mu) * 10 ** (-6)
k_fluid[i] = IAPWS97(P=P_array[i], T=T_f_array[i]).k
Pr[i] = IAPWS97(P=P_array[i], h=h_enthalpy_array[i]).Liquid.Prandt
x_array[i] = 0
xe_array[i] = (h_enthalpy_array[i] - hf_enthalpy) / (hg_enthalpy - hf_enthalpy)
rho_m = 1 / ((x_array[i] * vg) + ((1 - x_array[i]) * vf))
mu_m = 1 / ((x_array[i] / mug) + ((1 - x_array[i]) / muf))
Re[i] = (MF * D_H) / (mu_m * 10 ** 6) # convert mu to Pa/s
f = 0.079 * (Re[i] ** -0.25) * (mu_m / muf)
Tau = (1 / 2) * f * ((MF ** 2) / rho_m)
Re_f[i] = Re[i]
vf_plus_dP = IAPWS97(P=P_array[i] + dp, x=0).v
vf_minus_dP = IAPWS97(P=P_array[i] - dp, x=0).v
ddP_vf = (vf_plus_dP - vf_minus_dP) / (2 * (dp * 10 ** 6))
frictional[i] = (Tau * wetted_p) / A_f
gravitational[i] = g * rho_f
compressibility[i] = (MF ** 2) * (ddP_vf)
dPdz_num = (frictional[i] + gravitational[i]) # Pa/m
dPdz_denom = 1 + compressibility[i] # Pa/m
dPdz = -dPdz_num / dPdz_denom # Pa/m
P_array[i + 1] = P_array[i] + ((dPdz * dz) * 10 ** (-6))
T_f_array[i + 1] = IAPWS97(P=P_array[i + 1], h=h_enthalpy_array[i + 1]).T
T_sat[i + 1] = IAPWS97(P=P_array[i + 1], x=0).T
# final calc for final value of quality and void fraction because loop stops before these
hf_final = IAPWS97(P=P_array[-1], x=0).h
hg_final = IAPWS97(P=P_array[-1], x=1).h
muf_final = (IAPWS97(P=P_array[-1], x=0).mu) * 10 ** (-6)
mug_final = (IAPWS97(P=P_array[-1], x=1).mu) * 10 ** (-6)
k_fluid[-1] = IAPWS97(P=P_array[-1], T=T_f_array[-1]).k
xe_array[-1] = (h_enthalpy_array[-1] - hf_final) / (hg_final - hf_final)
# fuel and clad temps
T_C_Outer = np.zeros(len(z_array))
mu_m_final = 1 / ((x_array[-1] / mug_final) + ((1 - x_array[-1]) / muf_final))
Re_f[-1] = (MF * D_H) / (muf_final * 10 ** 6)
Pr[-1] = IAPWS97(P=P_array[i], h=h_enthalpy_array[i]).Liquid.Prandt
h_HT = 0.023 * (Re_f[0] ** 0.8) * (Pr[0] ** 0.4) * (k_fluid[0] / D_H)
T_C_Outer[0] = (q_heat_flux[0] + (h_HT * T_f_array[0])) / h_HT
for i in range(0, len(z_array) - 1):
h_HT = 0.023 * (Re_f[i + 1] ** 0.8) * (Pr[i + 1] ** 0.4) * (k_fluid[i + 1] / D_H)
T_C_Outer[i + 1] = (q_heat_flux[i + 1] + (h_HT * T_f_array[i + 1])) / h_HT
q_triple_prime = (q_prime * 4) / (np.pi * (D_fuel ** 2))
T_C_Inner = np.zeros(len(z_array))
T_F_Outer = np.zeros(len(z_array))
T_F_Center = np.zeros(len(z_array))
for i in range(0, len(z_array)):
C1 = -((q0_prime * R_clad) / (k_c * heated_p)) * np.sin(np.pi * (z_array[i] / H))
C2 = T_C_Outer[i] - (C1 * np.log(R_clad))
T_C_Inner[i] = (C1 * np.log(R_gap)) + C2
C3 = (k_c / k_gap) * C1
C4 = T_C_Inner[i] - (C3 * np.log(R_gap))
T_F_Outer[i] = (C3 * np.log(R_fuel)) + C4
C6 = T_F_Outer[i] + ((q_triple_prime[i] * (R_fuel ** 2)) / (4 * k_fuel))
T_F_Center[i] = C6
CL_max = np.amax(T_F_Center)
index = np.where(T_F_Center == CL_max)
z_CL_max = z_array[index]
Clad_max = np.amax(T_C_Inner)
index = np.where(T_C_Inner == Clad_max)
z_Clad_max = z_array[index]
plt.figure(1)
plt.plot(T_C_Outer, z_arrayplots, label='Clad Outer Surface Temp')
plt.plot(T_C_Inner, z_arrayplots, label='Clad Inner Surface Temp')
plt.legend(loc='upper left')
plt.xlabel("Temperature [K]")
plt.ylabel("Height z [m]")
plt.savefig("TempClad.png", dpi=600)
plt.figure(2)
plt.plot(T_C_Outer, z_arrayplots, label='Clad Outer Surface Temp')
plt.plot(T_C_Inner, z_arrayplots, label='Clad Inner Surface Temp')
plt.plot(T_F_Outer, z_arrayplots, label='Fuel Outer Surface Temp')
plt.plot(T_F_Center, z_arrayplots, label='Fuel Centerline Temp')
plt.legend(loc='upper left')
plt.xlabel("Temperature [K]")
plt.ylabel("Height z [m]")
plt.savefig("TempFuelAndClad.png", dpi=600)
# radial calcs
T_array_A = [T_F_Center[25], T_F_Outer[25], T_C_Inner[25], T_C_Outer[25]]
T_array_B = [T_F_Center[49], T_F_Outer[49], T_C_Inner[49], T_C_Outer[49]]
T_array_C = [T_F_Center[53], T_F_Outer[53], T_C_Inner[53], T_C_Outer[53]]
r_array = [0, R_fuel, R_gap, R_clad]
plt.figure(3)
plt.plot(r_array, T_array_A, label='z = -H/4 = -0.9 m')
plt.plot(r_array, T_array_B, label='z = 0 m')
plt.plot(r_array, T_array_C, '--', label='z = zmax = 0.108 m')
plt.legend(loc='upper left')
plt.ylabel("Temperature [K]")
plt.xlabel("Radius r [m]")
plt.savefig("TempRadial.png", dpi=600)
# critical heat flux and DNBR
P_array_DNBR = np.delete(P_array, 0)
q_heat_flux_DNBR = np.delete(q_heat_flux, 0)
z_arrayplots_DNBR = np.delete(z_arrayplots, 0)
G_Mlbs = MF * (((2.20462 * 10 ** (-6)) * 3600) / 10.7639)
q_heat_flux_MBtu = q_heat_flux[1:] * 3.41 * (1 / 1000000) * (1 / 10.7639)
P_c = 22.064 # https://nuclearstreet.com/nuclear-power-plants/w/nuclear_power_plants/features-of-pressurized-water-reactors
P_crit = P_array_DNBR / P_c
P1 = 0.5328
P2 = 0.1212
P3 = 1.6151
P4 = 1.4066
P5 = -0.3040
P6 = 0.4843
P7 = -0.3285
P8 = -2.0749
A = P1 * (P_crit ** P2) * (G_Mlbs ** (P5 + (P7 * P_crit)))
C = P3 * (P_crit ** P4) * (G_Mlbs ** (P6 + (P8 * P_crit)))
q_crit_heat_flux_MBtu = (A - xe_array[0]) / (C + ((xe_array[1:] - xe_array[0]) / q_heat_flux_MBtu))
q_crit_heat_flux = q_crit_heat_flux_MBtu * (1 / 3.41) * 1000000 * 10.7639
DNBR = q_crit_heat_flux / q_heat_flux_DNBR
plt.figure(4)
plt.plot(DNBR, z_arrayplots_DNBR)
plt.xlabel("Departure from Nucleate Boiling Ratio")
plt.ylabel("Height z [m]")
plt.savefig("DNBR.png", dpi=600)
plt.figure(5)
plt.plot(P_array, z_arrayplots)
plt.xlabel('Pressure [MPa]')
plt.ylabel('Height z [m]')
plt.savefig("Pressure.png", dpi=600)
plt.figure(6)
plt.plot(T_f_array, z_arrayplots)
plt.xlabel('Temperature [K]')
plt.ylabel('Height z [m]')
plt.savefig("TempBulk.png", dpi=600)
plt.figure(7)
plt.plot(T_F_Outer, z_arrayplots, label='Fuel Outer Surface Temp')
plt.plot(T_F_Center, z_arrayplots, label='Fuel Centerline Temp')
plt.legend(loc='upper left')
plt.xlabel("Temperature [K]")
plt.ylabel("Height z [m]")
plt.savefig("TempFuel.png", dpi=600)
tempdifference = T_C_Outer - T_f_array
print("Max clad vs bulk difference is " + str(np.amax(tempdifference)) + " K")
print("Max coolant temp is " + str(np.amax(T_f_array)) + " K")
print("Min coolant temp is " + str(np.amin(T_f_array)) + " K")
print("Max clad inner temp is " + str(np.amax(T_C_Inner)) + " K")
print("Max clad outer temp is " + str(np.amax(T_C_Outer)) + " K")
print("min clad outer temp is " + str(np.amin(T_C_Outer)) + " K")
print("Max fuel temp is " + str(np.amax(T_F_Center)) + " K")
print("Max fuel outer temp is " + str(np.amax(T_F_Outer)) + " K")
print("Min fuel outer temp is " + str(np.amin(T_F_Outer)) + " K")
print("Max centerline temp occurs at z = " + str(z_CL_max) + "m")
print("Max clad temp occurs at z = " + str(z_Clad_max) + "m")
MDNBR = np.amin(DNBR)
print("MDNBR is " + str(MDNBR))
plt.show()
if case == 2: # BWR
H = 3.8 # m
He = 3.8 # m
Pitch = 1.63 * 10 ** (-2) # m
Gap_t = 0.0001 # m
D_fuel = 0.0104 # m
k_gap = 0.25 # W/m-K
k_c = 21.5 # W/m-K
k_fuel = 3.6 # W/m-K
T0 = float(274 + 273.15) # K
q0_prime = float(410 * 10 ** (2)) # W/m
P0 = 7.5 # MPa
MF = float(2290) # kg/m^2-s
D_rod = .0123 # m
R_rod = D_rod / 2
R_fuel = D_fuel / 2
R_gap = R_fuel + Gap_t
R_clad = R_rod
Clad_t = D_rod - D_fuel - Gap_t # m
h0_enthalpy = (IAPWS97(T=T0, P=P0).h) * 10 ** (3)
T_sat0 = IAPWS97(P=P0, x=0).T
g = 9.81 # m/s
# geometry properties
heated_p = math.pi * D_rod
wetted_p = math.pi * D_rod
A_f = (Pitch ** 2) - ((1 / 4) * math.pi * (D_rod ** 2))
D_H = (4 * A_f) / heated_p
# grid setup
grid_points = 100
dz = H / grid_points
z_array = np.arange(0, H, dz)
z_arrayplots = np.arange(-H / 2, H / 2, dz)
q_HeatFluxList = []
# defining array of q'' values in list
for z in z_array:
heat_fluxA = (q0_prime / (math.pi * D_rod)) * math.sin(math.pi * (z / He))
q_HeatFluxList.append(heat_fluxA)
q_heat_flux = np.array(q_HeatFluxList)
q_prime = np.zeros(len(z_array))
for i in range(0, len(z_array)):
q_prime[i] = q0_prime * math.sin((np.pi * z_array[i]) / He)
# defining array of h values
h_enthalpy_list = []
h_enthalpy_prefactor = ((heated_p * q0_prime * H) / (A_f * MF * (math.pi ** 2) * D_rod))
for z in z_array:
h_enthalpy = (-h_enthalpy_prefactor * math.cos(math.pi * (z / He))) + h_enthalpy_prefactor + h0_enthalpy
h_enthalpy_list.append(h_enthalpy)
h_enthalpy_array_J = np.array(h_enthalpy_list)
h_enthalpy_array = h_enthalpy_array_J * 10 ** (-3)
P_array = np.zeros(len(z_array))
P_array[0] = P0
T_sat = np.zeros(len(z_array))
T_sat[0] = T_sat0
T_f_array = np.zeros(len(z_array))
T_f_array[0] = T0
Re = np.zeros(len(z_array))
Re_f = np.zeros(len(z_array))
Pr = np.zeros(len(z_array))
k_fluid = np.zeros(len(z_array))
x_array = np.zeros(len(z_array))
xe_array = np.zeros(len(z_array))
dxe_array = np.zeros(len(z_array))
frictional = np.zeros(len(z_array))
gravitational = np.zeros(len(z_array))
compressibility = np.zeros(len(z_array))
alpha_array = np.zeros(len(z_array))
# Pressure Loop BWR
dp = 0.001
for i in range(0, len(z_array) - 1):
rho_f = IAPWS97(P=P_array[i], x=0).rho
rho_m = IAPWS97(P=P_array[i], x=xe_array[i]).rho
vf = IAPWS97(P=P_array[i], x=0).v
vg = IAPWS97(P=P_array[i], x=1).v
vfg = vg - vf
hf_enthalpy = IAPWS97(P=P_array[i], x=0).h
hg_enthalpy = IAPWS97(P=P_array[i], x=1).h
hfg = hg_enthalpy - hf_enthalpy
hfg_sat = IAPWS97(P=P0, x=1).h - IAPWS97(P=P0, x=0).h
# vf = IAPWS97(P=P_array[i], x=0).v
# vg_sat = IAPWS97(P=P_array[i], x=1).v
hf_in = IAPWS97(P=P0, T=T0).h
muf = (IAPWS97(P=P_array[i], x=0).mu) * 10 ** (-6)
mum = (IAPWS97(P=P_array[i], x=xe_array[i]).mu) * 10 ** (-6)
mug = (IAPWS97(P=P_array[i], x=1).mu) * 10 ** (-6)
k_fluid[i] = IAPWS97(P=P_array[i], T=T_f_array[i]).k
Pr[i] = IAPWS97(P=P_array[i], h=h_enthalpy_array[i]).Liquid.Prandt
xe_in = (hf_in - hf_enthalpy) / (hfg)
vf_sat = IAPWS97(P=P_array[i], x=xe_array[i])
# vapor quality
if xe_array[i] <= 0: # single phase
Re1p = MF * D_rod / muf
f1p = 0.316 * Re1p ** (-.25)
dp = -(.5 * f1p * MF * 2 * heated_p / (rho_f * A_f) + g / rho_f) * dz
x_array[i] = 0
dxe_array[i] = q0_prime * np.sin(np.pi * z_array[i] / H) / (MF * A_f * hfg_sat) * dz
xe_array = xe_array[i - 1] + dxe_array[i]
# P_array[i]=P[i-1]+dp1p
elif xe_array[i] > 0 and xe_array[i] < 1: # 2 phase
Re2p = MF * D_rod / mum
f2p = 0.046 * Re2p ** (-.2) * (muf / mum ** (-.2))
dp2p = (-MF ** 2 * vfg * dxe_array[i] + .5 * f2p * MF ** 2 * heated_p / (rho_m * A_f) + g * rho_m) * dz
xe_array[i] = (h_enthalpy_array[i] - hf_enthalpy) / (hg_enthalpy - hf_enthalpy)
# Void Fraction
if xe_array[i] <= 0:
alpha_array[0]
elif xe_array[i] > 0 and xe_array[i] < 1:
x_array[i] = xe_array[i]
vfg_sat = vg - vf
rho_m = (vf_sat + vfg_sat * x_array) ** (-1)
rhof = 1 / vf
rhog = 1 / vg
void = (rho_m - rhof) / (rhog - rhof)
alpha_array[void]
print("Void fraction is " + str(np.amax(alpha_array)))
if xe_array[i] <= 0:
alpha_array[0]
elif xe_array[i] > 0 and xe_array[i] < 1:
x_array[i] = xe_array[i]
vfg_sat = vg - vf
rho_m = (vf_sat + vfg_sat * x_array) ** (-1)
rhof = 1 / vf
rhog = 1 / vg
void = (rho_m - rhof) / (rhog - rhof)
alpha_array[void]
print("Void fraction is " + str(np.amax(alpha_array)))
rho_m = 1 / ((x_array[i] * vg) + ((1 - x_array[i]) * vf))
mu_m = 1 / ((x_array[i] / mug) + ((1 - x_array[i]) / muf))
Re[i] = (MF * D_H) / (mu_m * 10 ** 6) # convert mu to Pa/s
f = 0.079 * (Re[i] ** -0.25) * (mu_m / muf)
Tau = (1 / 2) * f * ((MF ** 2) / rho_m)
Re_f[i] = Re[i]
vf_plus_dP = IAPWS97(P=P_array[i] + dp, x=xe_array[i]).v
vf_minus_dP = IAPWS97(P=P_array[i] - dp, x=xe_array[i]).v
ddP_vf = (vf_plus_dP - vf_minus_dP) / (2 * (dp * 10 ** 6))
frictional[i] = (Tau * wetted_p) / A_f
gravitational[i] = g * rho_f
compressibility[i] = (MF ** 2) * (ddP_vf)
dPdz_num = (frictional[i] + gravitational[i]) # Pa/m
dPdz_denom = 1 + compressibility[i] # Pa/m
dPdz = -dPdz_num / dPdz_denom # Pa/m
P_array[i + 1] = P_array[i] + ((dPdz * dz) * 10 ** (-6))
T_f_array[i + 1] = IAPWS97(P=P_array[i + 1], h=h_enthalpy_array[i + 1]).T
T_sat[i + 1] = IAPWS97(P=P_array[i + 1], x=0).T
# final calc for final value of quality and void fraction because loop stops before these
hf_final = IAPWS97(P=P_array[-1], x=0).h
hg_final = IAPWS97(P=P_array[-1], x=1).h
muf_final = (IAPWS97(P=P_array[-1], x=0).mu) * 10 ** (-6)
mug_final = (IAPWS97(P=P_array[-1], x=1).mu) * 10 ** (-6)
k_fluid[-1] = IAPWS97(P=P_array[-1], T=T_f_array[-1]).k
xe_array[-1] = (h_enthalpy_array[-1] - hf_final) / (hg_final - hf_final)
# fuel and clad temps
T_C_Outer = np.zeros(len(z_array))
mu_m_final = 1 / ((x_array[-1] / mug_final) + ((1 - x_array[-1]) / muf_final))
Re_f[-1] = (MF * D_H) / (muf_final * 10 ** 6)
Pr[-1] = IAPWS97(P=P_array[i], h=h_enthalpy_array[i]).Liquid.Prandt
h_HT = 0.023 * (Re_f[0] ** 0.8) * (Pr[0] ** 0.4) * (k_fluid[0] / D_H)
T_C_Outer[0] = (q_heat_flux[0] + (h_HT * T_f_array[0])) / h_HT
for i in range(0, len(z_array) - 1):
h_HT = 0.023 * (Re_f[i + 1] ** 0.8) * (Pr[i + 1] ** 0.4) * (k_fluid[i + 1] / D_H)
T_C_Outer[i + 1] = (q_heat_flux[i + 1] + (h_HT * T_f_array[i + 1])) / h_HT
q_triple_prime = (q_prime * 4) / (np.pi * (D_fuel ** 2))
T_C_Inner = np.zeros(len(z_array))
T_F_Outer = np.zeros(len(z_array))
T_F_Center = np.zeros(len(z_array))
for i in range(0, len(z_array)):
C1 = -((q0_prime * R_clad) / (k_c * heated_p)) * np.sin(np.pi * (z_array[i] / H))
C2 = T_C_Outer[i] - (C1 * np.log(R_clad))
T_C_Inner[i] = (C1 * np.log(R_gap)) + C2
C3 = (k_c / k_gap) * C1
C4 = T_C_Inner[i] - (C3 * np.log(R_gap))
T_F_Outer[i] = (C3 * np.log(R_fuel)) + C4
C6 = T_F_Outer[i] + ((q_triple_prime[i] * (R_fuel ** 2)) / (4 * k_fuel))
T_F_Center[i] = C6
CL_max = np.amax(T_F_Center)
index = np.where(T_F_Center == CL_max)
z_CL_max = z_array[index]
plt.figure(1)
plt.plot(T_C_Outer, z_arrayplots, label='Clad Outer Surface Temp')
plt.plot(T_C_Inner, z_arrayplots, label='Clad Inner Surface Temp')
plt.legend(loc='upper left')
plt.xlabel("Temperature [K]")
plt.ylabel("Height z [m]")
plt.savefig("TempCladBWR.png", dpi=600)
plt.figure(2)
plt.plot(T_C_Outer, z_arrayplots, label='Clad Outer Surface Temp')
plt.plot(T_C_Inner, z_arrayplots, label='Clad Inner Surface Temp')
plt.plot(T_F_Outer, z_arrayplots, label='Fuel Outer Surface Temp')
plt.plot(T_F_Center, z_arrayplots, label='Fuel Centerline Temp')
plt.legend(loc='upper left')
plt.xlabel("Temperature [K]")
plt.ylabel("Height z [m]")
plt.savefig("TempFuelAndCladBWR.png", dpi=600)
# radial calcs
T_array_A = [T_F_Center[25], T_F_Outer[25], T_C_Inner[25], T_C_Outer[25]]
T_array_B = [T_F_Center[49], T_F_Outer[49], T_C_Inner[49], T_C_Outer[49]]
T_array_C = [T_F_Center[53], T_F_Outer[53], T_C_Inner[53], T_C_Outer[53]]
r_array = [0, R_fuel, R_gap, R_clad]
plt.figure(3)
plt.plot(r_array, T_array_A, label='z = -H/4 = -0.9 m')
plt.plot(r_array, T_array_B, label='z = 0 m')
plt.plot(r_array, T_array_C, '--', label='z = zmax = 0.108 m')
plt.legend(loc='upper left')
plt.ylabel("Temperature [K]")
plt.xlabel("Radius r [m]")
plt.savefig("TempRadialBWR.png", dpi=600)
# critical heat flux and DNBR
P_array_DNBR = np.delete(P_array, 0)
q_heat_flux_DNBR = np.delete(q_heat_flux, 0)
z_arrayplots_DNBR = np.delete(z_arrayplots, 0)
G_Mlbs = MF * (((2.20462 * 10 ** (-6)) * 3600) / 10.7639)
q_heat_flux_MBtu = q_heat_flux[1:] * 3.41 * (1 / 1000000) * (1 / 10.7639)
P_c = 22.064 # https://nuclearstreet.com/nuclear-power-plants/w/nuclear_power_plants/features-of-pressurized-water-reactors
P_crit = P_array_DNBR / P_c
P1 = 0.5328
P2 = 0.1212
P3 = 1.6151
P4 = 1.4066
P5 = -0.3040
P6 = 0.4843
P7 = -0.3285
P8 = -2.0749
A = P1 * (P_crit ** P2) * (G_Mlbs ** (P5 + (P7 * P_crit)))
C = P3 * (P_crit ** P4) * (G_Mlbs ** (P6 + (P8 * P_crit)))
q_crit_heat_flux_MBtu = (A - xe_array[0]) / (C + ((xe_array[1:] - xe_array[0]) / q_heat_flux_MBtu))
q_crit_heat_flux = q_crit_heat_flux_MBtu * (1 / 3.41) * 1000000 * 10.7639
DNBR = q_crit_heat_flux / q_heat_flux_DNBR
plt.figure(4)
plt.plot(DNBR, z_arrayplots_DNBR)
plt.xlabel("Onset of Nucleate Boiling Ratio")
plt.ylabel("Height z [m]")
plt.title("Onset of Nucleate Boiling Ratio versus Height")
plt.savefig("ONBR.png", dpi=600)
plt.figure(5)
plt.plot(P_array, z_arrayplots)
plt.xlabel('Pressure [MPa]')
plt.ylabel('Height z [m]')
plt.title('Pressure versus Height')
plt.savefig("PressureBWR.png", dpi=600)
plt.figure(6)
plt.plot(T_f_array, z_arrayplots)
plt.xlabel('Temperature [K]')
plt.ylabel('Height z [m]')
plt.title('Coolant Temperature vs Height')
plt.savefig("TempBulkBWR.png", dpi=600)
plt.figure(7)
plt.plot(T_F_Outer, z_arrayplots, label='Fuel Outer Surface Temp')
plt.plot(T_F_Center, z_arrayplots, label='Fuel Centerline Temp')
plt.legend(loc='upper left')
plt.xlabel("Temperature [K]")
plt.ylabel("Height z [m]")
plt.savefig("TempFuelBWR.png", dpi=600)
# density
plt.figure(8)
plt.plot(Density, z_arrayplots, label='Density')
plt.legend(loc='upper left')
plt.xlabel("Pressure [mPa]")
plt.ylabel("Height z [m]")
plt.savefig("Density", dpi=600)
# quality
plt.figure(9)
plt.plot(x, z_arrayplots, label='Quality')
plt.plot(xe, z_arrayplots, label='Quality')
plt.legend(loc='upper left')
plt.xlabel("Quality")
plt.ylabel("Height z [m]")
plt.savefig("Quality", dpi=600)
# void
plt.figure(10)
plt.plot(alpha, z_arrayplots, label='Void Fraction')
plt.legend(loc='upper left')
plt.xlabel("Void Fraction")
plt.ylabel("Height z [m]")
plt.savefig("Void Fraction", dpi=600)
tempdifference = T_C_Outer - T_f_array
print("Max clad vs bulk difference is " + str(np.amax(tempdifference)) + " C")
print("Max coolant temp is " + str(np.amax(T_f_array) - 273.15) + " C")
print("Max coolant temp is " + str(np.amax(T_f_array)) + " K")
print("Max clad temp is " + str(np.amax(T_C_Inner) - 273.15) + " C")
print("Max clad temp is " + str(np.amax(T_C_Inner)) + " K")
print("Max fuel temp is " + str(np.amax(T_F_Center) - 273.15) + " C")
print("Max fuel temp is " + str(np.amax(T_F_Center)) + " K")
print("Max fuel temp is " + str(np.amax(T_F_Outer) - 273.15) + " C")
print("Max fuel temp is " + str(np.amax(T_F_Outer)) + " K")
print("Max centerline temp occurs at z = " + str(z_CL_max) + "m")
MDNBR = np.amin(DNBR)
print("MDNBR is " + str(MDNBR))
The following code generates numpy 2D lists of r and E values for the specified intervals.
r = np.linspace(3, 14, 10)
E = np.linspace(0.05, 0.75, 10)
r, E = np.meshgrid(r, E)
I am then using the following nested loop to generate output from the function ionisationGamma for each r and E interval value.
for ridx in trange(len(r)):
z = []
for cidx in range(len(r[ridx])):
z.append(ionisationGamma(r[ridx][cidx], E[ridx][cidx]))
Z.append(z)
Z = np.array(Z)
This loop gives me a 2D numpy array Z, which is my output and I am using it for a 3D graph. The problem with it is: it is taking ~6 hours to generate the output for all these intervals as there are so many values due to np.meshgrid. I have just discovered multi-threading in Python and wanted to know how I can implement this by using it. Any help is appreciated.
See below code for ionisationGamma
def ionisationGamma(r, E):
I = complex(0.1, 1.0)
a_soft = 1.0
omega = 0.057
beta = 0.0
dt = 0.1
steps = 10000
Nintervals = 60
N = 3000
xmin = float(-300)
xmax = -xmin
x = [0.0]*N
dx = (xmax - xmin) / (N - 1)
L = dx * N
dk = 2 * M_PI / L
propagator = None
in_, out_, psi0 = None, None, None
in_ = [complex(0.,0.)] * N
psi0 = [complex(0.,0.)] * N
out_ = [[complex(0.,0.)]*N for i in range(steps+1)]
overlap = exp(-r) * (1 + r + (1 / 3) * pow(r, 2))
normC = 1 / (sqrt(2 * (1 + overlap)))
gammai = 0.5
qi = 0.0 + (r / 2)
pi = 0.0
gammai1 = 0.5
gammai2 = 0.5
qi1 = 0.0 - (r / 2)
qi2 = 0.0 + (r / 2)
pi1 = 0.0
pi2 = 0.0
# split initial wavepacket
for i in range(N):
x[i] = xmin + i * dx
out_[0][i] = (normC) * ((pow(gammai1 / M_PI, 1. / 4.) * exp(complex(-(gammai1 / 2.) * pow(x[i] - qi1, 2.), pi1 * (x[i] - qi1)))) + (pow(gammai2 / M_PI, 1. / 4.) * exp(complex(-(gammai2 / 2.) * pow(x[i] - qi2, 2.), pi2 * (x[i] - qi2)))))
in_[i] = (normC) * ((pow(gammai1 / M_PI, 1. / 4.) * exp(complex(-(gammai1 / 2.) * pow(x[i] - qi1, 2.), pi1 * (x[i] - qi1)))) + (pow(gammai2 / M_PI, 1. / 4.) * exp(complex(-(gammai2 / 2.) * pow(x[i] - qi2, 2.), pi2 * (x[i] - qi2)))))
psi0[i] = in_[i]
for l in range(1, steps+1):
for i in range(N):
propagator = exp(complex(0, -potential(x[i], omega, beta, a_soft, r, E, dt, l) * dt / 2.))
in_[i] = propagator * in_[i];
in_ = np.fft.fft(in_, N)
for i in range(N):
k = dk * float(i if i < N / 2 else i - N)
propagator = exp(complex(0, -dt * pow(k, 2) / (2.)))
in_[i] = propagator * in_[i]
in_ = np.fft.ifft(in_, N)
for i in range(N):
propagator = exp(complex(0, -potential(x[i], omega, beta, a_soft, r, E, dt, l) * dt / 2.))
in_[i] = propagator * in_[i]
out_[l][i] = in_[i]
initialGammaCentre = 0.0
finalGammaCentre = 0.0
for i in range(500, 2500 +1):
initialGammaCentre += pow(abs(out_[0][i]), 2) * dx
finalGammaCentre += pow(abs(out_[steps][i]), 2) * dx
ionisationGamma = finalGammaCentre / initialGammaCentre
return ionisationGamma
def potential(x, omega, beta, a_soft, r, E, dt, l):
V = (-1. / sqrt((x - (r / 2)) * (x - (r / 2)) + a_soft * a_soft)) + ((-1. / sqrt((x + (r / 2)) * (x + (r / 2)) + a_soft * a_soft))) + E * x
return V
Since the question is about how to use multiprocessing, the following code will work:
import multiprocessing as mp
if __name__ == '__main__':
with mp.Pool(processes=16) as pool:
Z = pool.starmap(ionisationGamma, arguments)
Z = np.array(Z)
Where the arguments are:
arguments = list()
for ridx in range(len(r)):
for cidx in range(len(r[ridx])):
arguments.append((r[ridx][cidx], E[ridx][cidx]))
I am using starmap instead of map, since you have multiple arguments that you want to unpack. This will divide the arguments iterable over multiple cores, using the ionisationGamma function and the final result will be ordered.
However, I do feel the need to say that the main solution is not really the multiprocessing but the original function code. In ionisationGamma you are using several times the slow python for loops. And it would benefit your code a lot if you could vectorize those operations.
A second observation is that you are using many of those loops separately and it would be nice if you could separate that one big function into multiple smaller functions. Then you can time every function individually and speed up those that are too slow.
What I basically want, is comparing a timevalue (t1 and tuit)(in hours) to determine which method to use to calculate 'S' and 'k' in a function called 'stijghoogteverlaging'. Then a fitted curve can be made with those values.
I tried multiple things, like putting 'return s' underneath both s-methods.
if t1[i] < tuit:
s = Q / (4 * np.pi * k * D) * exp1(S * r**2 / (4 * k * D * t))
return s
else:
s = Q / (4 * np.pi * k * D) * ((exp1(S * r**2 / (4 * k * D * t))) - (exp1(S * r**2 / (4 * k * D * (t - tuit)))))
return s
But then I got a wrong fitted curve as can be seen in the image below.
Now I tried putting only one 'return s', but then it takes forever to calculate and I have to interrupt the kernel.
data = read_csv("pompproef_data.csv", sep = ';')
pb1 = data.iloc[1:,1].values-1.87
pb2 = data.iloc[1:,2].values-1.86
t1 = data.iloc[1:,0].values / (60*24)
volume = 10/1000 #m3
duur = [128,136, 150, 137, 143, 141] #seconden
totaal = np.sum(duur)
debiet = (((len(duur) * volume)/totaal)) * (60*60*24) #m3/d
print(debiet)
print(t1)
print(pb1)
tuit = 15/(24*60)
D = 2.0
Q = debiet
def stijghoogteverlaging(t, k, S):
for i in range(len(t1)):
if t1[i] < tuit:
s = Q / (4 * np.pi * k * D) * exp1(S * r**2 / (4 * k * D * t))
else:
s = Q / (4 * np.pi * k * D) * ((exp1(S * r**2 / (4 * k * D * t))) - (exp1(S * r**2 / (4 * k * D * (t - tuit)))))
return s
r = 4.0 #afstand peilbuis1 tot put
poptpb1, pcovpb1 = curve_fit(stijghoogteverlaging, t1, pb1, p0=[100, 1e-25], maxfev = 10000000)
print('optimale waarde van k voor peilbuis1:', poptpb1[0])
print('optimale waarde van S voor peilbuis1:', poptpb1[1])
tijd = data.iloc[1:,0].values
t = np.linspace(0.00069*(24*60), 0.021*(24*60), 1000)
s1 = stijghoogteverlaging(t, poptpb1[0], poptpb1[1])
plt.plot(tijd, pb1, 'r.', label = 'Gemeten bij 4 meter')
plt.plot(t, s1, 'b', label = 'fitted bij 4 m')
Does anyone have a solution?
Used values for t1 and pb1:
Plot with a wrong fitted curve(time in minutes).
The function stijghoogteverlaging is performing a nonsense operation over and over:
def stijghoogteverlaging(t, k, S):
for i in range(len(t1)):
if t1[i] < tuit:
s = Q / (4 * np.pi * k * D) * exp1(S * r**2 / (4 * k * D * t))
else:
s = Q / (4 * np.pi * k * D) * ((exp1(S * r**2 / (4 * k * D * t))) - (exp1(S * r**2 / (4 * k * D * (t - tuit)))))
return s
You are iterating len(t1) times, and at each iteration, you are computing the full vectorized value of s each and every time. That means that you are computing len(t)**2 values per call, and using a Python for loop as your outer loop to do it. As a minor point, you are accessing the x-data as the global variable t1 instead of the local value t, which gets passed in.
Your function should probably look more like this:
def stijghoogteverlaging(t, k, S):
return np.where(t < tuit,
Q / (4 * np.pi * k * D) * exp1(S * r**2 / (4 * k * D * t)),
Q / (4 * np.pi * k * D) * ((exp1(S * r**2 / (4 * k * D * t))) - (exp1(S * r**2 / (4 * k * D * (t - tuit)))))
)
This computes len(t) * 2 values per call, not len(t)**2, and selects a value from the appropriate result for each value of t.
I keep getting the invalid procedure call or argument error on the definition of sigma2d line.
Any idea how to avoid this code error?
Private Sub CommandButton4_Click()
Application.Range("E19").value = ""
Application.Range("F19").value = ""
S0 = Application.Range("C5").value 'arithmetic average of underlying 1
K = Application.Range("C6").value 'strike
T = Application.Range("C10").value 'maturity
sigma = Application.Range("C8").value 'volatility
r = Application.Range("C8").value 'risk free rate
nsteps = Application.Range("C12").value 'no of timesteps
nsimulations = Application.Range("C13").value ' no of mc simulations
div = Application.Range("C9").value 'dividends
Randomize
Dim M1 As Double, M2 As Double, sigma2d As Double
Dim d1 As Double, d2 As Double, Nd1 As Double, Nd2 As Double
M1 = (Exp((r - div) * T) - 1) / (r - div) * T
v = (2 * Exp((2 * r) - (2 * div) + (sigma * sigma) * T)) * S0 * S0
w = (r - div + (sigma * sigma)) * (2 * r - 2 * q + (sigma * sigma)) * T * T
Z = 2 * S0 * S0 / ((r - div) * T * T)
y = (1 / 2 * (r - div) + sigma * sigma)
h = Exp((r - div) * T) / (r - div + (sigma * sigma))
M2 = (v / w) + Z * (y - h)
M3 = M1 * M1
sigma2d = Log(M2 / M3)
d1 = (Log(M1 / K) + (sigma2d * T) / 2) / sigma * Sqr(T)
d2 = d1 - sigma * Sqr(T)
callArith = Exp(-r * T) * (M1 * Nd1 - K * Nd2)
Application.Range("E19").value = Application.Max(ExactCall, 0)
Are you trying to do the log of a negative number? Set a breakpoint and check variables before that line. Maybe you have an error before that generating a negative.
First check the argument to the Log function is positive.
Failing that, it could be due to a missing reference in the project. This manifests itself in this curious way. Have a look at "Tools", "References" and see if there is one missing.
You can write sigma2d = Vba.Log(M2 / M3) instead but that's only really a short fix since missing references will cause you headaches elsewhere.
One more thing, why not create a function instead, passing in all the variables as function parameters? Your spreadsheet will be more stable if you do that.
(Also, at the end of your code, d1 definition is incorrect. You need brackets around sigma * Sqr(T)).
I think you need a pair of () or do "/T" as you are multiplying by T here:
M1 = (Exp((r - div) * T) - 1) / (r - div) * T