Numerical-Simulation/HW3/main.py
2024-10-18 20:03:55 -05:00

722 lines
34 KiB
Python

# main.py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
import case1
import case2
import common
import Bar
bar1 = Bar.Bar(
radius=0.1,
k=0.5,
h=0.25
)
bar2 = Bar.Bar(
radius=0.1,
k=2,
h=0.25
)
data_dict = {}
data_dict["k_ratios"] = np.array([1/16, 1/8, 1/4, 1/2, 1, 2, 4, 8, 16])
data_dict["x_bar_values"] = np.array([1/2, 2/np.pi])
data_dict["length"] = 1
def section_1():
'''Analytical solutions with varying k_ratio'''
print("Section 1: Analytical")
l = data_dict["length"]
# Calculate the results for every k ratio for x_bar_1
x_bar_1 = data_dict["x_bar_values"][0]
data_dict["section1"] = {}
data_dict["section1"]["x_bar_1"] = {}
data_dict["section1"]["x_bar_1"]["x_values_fine"] = np.linspace(0, l, 50)
data_dict["section1"]["x_bar_1"]["x_values_fine"] = np.sort(np.append(data_dict["section1"]["x_bar_1"]["x_values_fine"], x_bar_1))
data_dict["section1"]["x_bar_1"]["x_values_course"] = np.linspace(0, l, 9)
data_dict["section1"]["x_bar_1"]["x_values_course"] = np.sort(np.append(data_dict["section1"]["x_bar_1"]["x_values_course"], x_bar_1))
results = []
results_course = []
for k_ratio in data_dict["k_ratios"]:
Bar.set_k_ratio(k_ratio, bar1, bar2) # Set the k value of bar2 = k*bar1
result = case1.get_analytical_datapoints(data_dict["section1"]["x_bar_1"]["x_values_fine"],
bar1=bar1,
bar2=bar2,
x_bar=x_bar_1,
l=l)
result_course = case1.get_analytical_datapoints(data_dict["section1"]["x_bar_1"]["x_values_course"],
bar1=bar1,
bar2=bar2,
x_bar=x_bar_1,
l=l)
results.append(result)
results_course.append(result_course)
data_dict["section1"]["x_bar_1"]["temp_results"] = np.array(results)
df_x_bar_1 = pd.DataFrame(results_course, index=[f'k2/k1 = {a}' for a in data_dict["k_ratios"]], columns=[f'x = {x:.3f}' for x in data_dict["section1"]["x_bar_1"]["x_values_course"]])
print("Analytical Temperature Results x_bar = 0.5:")
print(df_x_bar_1.to_string())
print("\n" * 2)
# Plotting x_bar_1
plt.figure(figsize=(10, 6))
for idx, k_ratio in enumerate(data_dict["k_ratios"]):
plt.plot(data_dict["section1"]["x_bar_1"]["x_values_fine"], data_dict["section1"]["x_bar_1"]["temp_results"][idx], label=f'k2/k1 = {k_ratio}')
plt.axvline(x=x_bar_1, color='r', linestyle='--', label='x_bar')
plt.xlabel('Position (cm)')
plt.ylabel('Temperature (°C)')
plt.legend()
plt.grid(True)
plt.savefig('images/section1/x_bar_1/analytical_temperature_vs_position.png', dpi=300)
#plt.show()
plt.clf()
# Calculate the temperature results for every k ratio for x_bar_1
x_bar_2 = data_dict["x_bar_values"][1]
data_dict["section1"]["x_bar_2"] = {}
data_dict["section1"]["x_bar_2"]["x_values_fine"] = np.linspace(0, l, 50)
data_dict["section1"]["x_bar_2"]["x_values_fine"] = np.sort(np.append(data_dict["section1"]["x_bar_2"]["x_values_fine"], x_bar_2))
data_dict["section1"]["x_bar_2"]["x_values_course"] = np.linspace(0, l, 9)
data_dict["section1"]["x_bar_2"]["x_values_course"] = np.sort(np.append(data_dict["section1"]["x_bar_2"]["x_values_course"], x_bar_2))
results = []
results_course = []
for k_ratio in data_dict["k_ratios"]:
Bar.set_k_ratio(k_ratio, bar1, bar2)
result = case1.get_analytical_datapoints(data_dict["section1"]["x_bar_2"]["x_values_fine"],
bar1=bar1,
bar2=bar2,
x_bar=x_bar_2,
l=l)
result_course = case1.get_analytical_datapoints(data_dict["section1"]["x_bar_2"]["x_values_course"],
bar1=bar1,
bar2=bar2,
x_bar=x_bar_2,
l=l)
results.append(result)
results_course.append(result_course)
data_dict["section1"]["x_bar_2"]["temp_results"] = np.array(results)
df_x_bar_2 = pd.DataFrame(results_course, index=[f'k2/k1 = {a}' for a in data_dict["k_ratios"]], columns=[f'x = {x:.3f}' for x in data_dict["section1"]["x_bar_2"]["x_values_course"]])
print("Analytical Temperature Results x_bar = 2/pi:")
print(df_x_bar_2.to_string())
print("\n" * 2)
# Plotting x_bar_2
plt.figure(figsize=(10, 6))
for idx, k_ratio in enumerate(data_dict["k_ratios"]):
plt.plot(data_dict["section1"]["x_bar_2"]["x_values_fine"], data_dict["section1"]["x_bar_2"]["temp_results"][idx], label=f'k2/k1 = {k_ratio}')
plt.axvline(x=x_bar_2, color='r', linestyle='--', label='x_bar')
plt.xlabel('Position (cm)')
plt.ylabel('Temperature (°C)')
plt.legend()
plt.grid(True)
plt.savefig('images/section1/x_bar_2/analytical_temperature_vs_position.png', dpi=300)
#plt.show()
plt.clf()
# Calculate the analytical heat convection leaving the rod at x=l for varying k ratio
results_1 = []
results_2 = []
for k_ratio in data_dict["k_ratios"]:
Bar.set_k_ratio(k_ratio, bar1, bar2)
result_1 = case1.get_analytical_heat_convection(x=l,
bar1=bar1,
bar2=bar2,
x_bar=x_bar_1,
l=l)
result_2 = case1.get_analytical_heat_convection(x=l,
bar1=bar1,
bar2=bar2,
x_bar=x_bar_2,
l=l)
results_1.append([result_1])
results_2.append([result_2])
data_dict["section1"]["x_bar_1"]["heat_results"] = np.array(results_1)
data_dict["section1"]["x_bar_2"]["heat_results"] = np.array(results_2)
df_x_bar_1 = pd.DataFrame(results_1, index=[f'k2/k1 = {a}' for a in data_dict["k_ratios"]], columns=["Heat Convection"])
df_x_bar_2 = pd.DataFrame(results_2, index=[f'k2/k1 = {a}' for a in data_dict["k_ratios"]], columns=["Heat Convection"])
print("Analytical Heat Convection Results x_bar = 0.5:")
print(df_x_bar_1.to_string())
print("\n" * 2)
print("Analytical Heat Convection Results x_bar = 2/pi:")
print(df_x_bar_2.to_string())
print("\n" * 2)
# Plotting x_bar_1 heat convection
plt.figure(figsize=(10, 6))
plt.plot(data_dict["k_ratios"], data_dict["section1"]["x_bar_1"]["heat_results"], label=f'Heat Convection')
plt.xlabel('k2/k1')
plt.ylabel('Q_Dot (W)')
plt.legend()
plt.grid(True)
plt.savefig('images/section1/x_bar_1/analytical_heat_convection_vs_k_ratio.png', dpi=300)
#plt.show()
plt.clf()
# Plotting x_bar_2 heat convection
plt.figure(figsize=(10, 6))
plt.plot(data_dict["k_ratios"], data_dict["section1"]["x_bar_2"]["heat_results"], label=f'Heat Convection')
plt.xlabel('k2/k1')
plt.ylabel('Q_Dot (W)')
plt.legend()
plt.grid(True)
plt.savefig('images/section1/x_bar_2/analytical_heat_convection_vs_k_ratio.png', dpi=300)
#plt.show()
plt.clf()
def section_2():
'''FDM and FEM with varying k_ratio'''
print("Section 2: FDM and FEM with Varying k_ratio")
l = data_dict["length"]
data_dict["section2"] = {}
data_dict["section2"]["num_sections"] = 8
# Calculate the results for every k ratio for x_bar_1
x_bar_1 = data_dict["x_bar_values"][0]
# For every k_ratio, calculate the FDM and FEM temperature results
fdm_results = []
fem_results = []
x_fdm = []
x_fem = []
for k_ratio in data_dict["k_ratios"]:
Bar.set_k_ratio(k_ratio, bar1, bar2) # Set the k value of bar2 = k*bar1
fdm_temps, x_fdm = case1.solve(bar1=bar1,
bar2=bar2,
num_sections=data_dict["section2"]["num_sections"],
x_bar=x_bar_1,
l=l,
method="FDM")
fem_temps, x_fem = case1.solve(bar1=bar1,
bar2=bar2,
num_sections=data_dict["section2"]["num_sections"],
x_bar=x_bar_1,
l=l,
method="FEM")
fdm_results.append(fdm_temps)
fem_results.append(fem_temps)
data_dict["section2"]["x_bar_1"] = {}
data_dict["section2"]["x_bar_1"]["x_values"] = x_fdm # fdm and fem use same x_values
data_dict["section2"]["x_bar_1"]["fdm_results"] = np.array(fdm_results)
data_dict["section2"]["x_bar_1"]["fem_results"] = np.array(fem_results)
df_fdm = pd.DataFrame(fdm_results, index=[f'k2/k1 = {a}' for a in data_dict["k_ratios"]], columns=[f'x = {x:.3f}' for x in x_fdm])
df_fem = pd.DataFrame(fem_results, index=[f'k2/k1 = {a}' for a in data_dict["k_ratios"]], columns=[f'x = {x:.3f}' for x in x_fem])
print("FDM Temperature Results x_bar = 0.5:")
print(df_fdm.to_string())
print("\n" * 2)
print("FEM Temperature Results x_bar = 0.5:")
print(df_fem.to_string())
print("\n" * 2)
# Now that the data is gathered for FDM and FEM, plot it
# Plotting x_bar_1, FDM
plt.figure(figsize=(10, 6))
for idx, k_ratio in enumerate(data_dict["k_ratios"]):
plt.plot(data_dict["section2"]["x_bar_1"]["x_values"], data_dict["section2"]["x_bar_1"]["fdm_results"][idx], label=f'k2/k1 = {k_ratio}')
plt.axvline(x=x_bar_1, color='r', linestyle='--', label='x_bar')
plt.xlabel('Position (cm)')
plt.ylabel('Temperature (°C)')
plt.legend()
plt.grid(True)
plt.savefig('images/section2/x_bar_1/fdm_temperature_vs_position.png', dpi=300)
#plt.show()
plt.clf()
# Plotting x_bar_1, FEM
plt.figure(figsize=(10, 6))
for idx, k_ratio in enumerate(data_dict["k_ratios"]):
plt.plot(data_dict["section2"]["x_bar_1"]["x_values"], data_dict["section2"]["x_bar_1"]["fem_results"][idx], label=f'k2/k1 = {k_ratio}')
plt.axvline(x=x_bar_1, color='r', linestyle='--', label='x_bar')
plt.xlabel('Position (cm)')
plt.ylabel('Temperature (°C)')
plt.legend()
plt.grid(True)
plt.savefig('images/section2/x_bar_1/fem_temperature_vs_position.png', dpi=300)
#plt.show()
plt.clf()
# Calculate the results for every k ratio for x_bar_2
x_bar_2 = data_dict["x_bar_values"][1]
# For every k_ratio, calculate the FDM and FEM temperature results
fdm_results = []
fem_results = []
x_fdm = []
x_fem = []
for k_ratio in data_dict["k_ratios"]:
Bar.set_k_ratio(k_ratio, bar1, bar2) # Set the k value of bar2 = k*bar1
fdm_temps, x_fdm = case1.solve(bar1=bar1,
bar2=bar2,
num_sections=data_dict["section2"]["num_sections"],
x_bar=x_bar_2,
l=l,
method="FDM")
fem_temps, x_fem = case1.solve(bar1=bar1,
bar2=bar2,
num_sections=data_dict["section2"]["num_sections"],
x_bar=x_bar_2,
l=l,
method="FEM")
fdm_results.append(fdm_temps)
fem_results.append(fem_temps)
data_dict["section2"]["x_bar_2"] = {}
data_dict["section2"]["x_bar_2"]["x_values"] = x_fdm # fdm and fem use same x_values
data_dict["section2"]["x_bar_2"]["fdm_results"] = np.array(fdm_results)
data_dict["section2"]["x_bar_2"]["fem_results"] = np.array(fem_results)
df_fdm = pd.DataFrame(fdm_results, index=[f'k2/k1 = {a}' for a in data_dict["k_ratios"]], columns=[f'x = {x:.3f}' for x in x_fdm])
df_fem = pd.DataFrame(fem_results, index=[f'k2/k1 = {a}' for a in data_dict["k_ratios"]], columns=[f'x = {x:.3f}' for x in x_fem])
print("FDM Temperature Results x_bar = 2/pi:")
print(df_fdm.to_string())
print("\n" * 2)
print("FEM Temperature Results x_bar = 2/pi:")
print(df_fem.to_string())
print("\n" * 2)
# Plotting x_bar_2, FDM
plt.figure(figsize=(10, 6))
for idx, k_ratio in enumerate(data_dict["k_ratios"]):
plt.plot(data_dict["section2"]["x_bar_2"]["x_values"], data_dict["section2"]["x_bar_2"]["fdm_results"][idx], label=f'k2/k1 = {k_ratio}')
plt.axvline(x=x_bar_2, color='r', linestyle='--', label='x_bar')
plt.xlabel('Position (cm)')
plt.ylabel('Temperature (°C)')
plt.legend()
plt.grid(True)
plt.savefig('images/section2/x_bar_2/fdm_temperature_vs_position.png', dpi=300)
#plt.show()
plt.clf()
# Plotting x_bar_2, FEM
plt.figure(figsize=(10, 6))
for idx, k_ratio in enumerate(data_dict["k_ratios"]):
plt.plot(data_dict["section2"]["x_bar_2"]["x_values"], data_dict["section2"]["x_bar_2"]["fem_results"][idx], label=f'k2/k1 = {k_ratio}')
plt.axvline(x=x_bar_2, color='r', linestyle='--', label='x_bar')
plt.xlabel('Position (cm)')
plt.ylabel('Temperature (°C)')
plt.legend()
plt.grid(True)
plt.savefig('images/section2/x_bar_2/fem_temperature_vs_position.png', dpi=300)
#plt.show()
plt.clf()
# After calculating temperature values, extract the heat convection at x=l
# x_bar_1
# for every k ratio, calculate the heat convection from fdm and fem temp results
fdm_heat_results = []
fem_heat_results = []
for i, k_ratio in enumerate(data_dict["k_ratios"]):
Bar.set_k_ratio(k_ratio, bar1, bar2) # Set the k value of bar2 = k*bar1
dx = data_dict["section2"]["x_bar_1"]["x_values"][-1] - data_dict["section2"]["x_bar_1"]["x_values"][-2]
(fdm_t0, fdm_t1) = data_dict["section2"]["x_bar_1"]["fdm_results"][i][-2:]
fdm_heat_result = common.fdm_heat_extraction(fdm_t0, fdm_t1, dx, bar2, order=2)
fdm_heat_results.append(fdm_heat_result)
(fem_t0, fem_t1) = data_dict["section2"]["x_bar_1"]["fem_results"][i][-2:]
fem_heat_result = common.fem_heat_extraction(fem_t0, fem_t1, dx, bar2)
fem_heat_results.append(fem_heat_result)
data_dict["section2"]["x_bar_1"]["fdm_heat_results"] = np.array(fdm_heat_results)
data_dict["section2"]["x_bar_1"]["fem_heat_results"] = np.array(fem_heat_results)
df_fdm = pd.DataFrame(fdm_heat_results, index=[f'k2/k1 = {a}' for a in data_dict["k_ratios"]], columns=["Heat Convection"])
df_fem = pd.DataFrame(fem_heat_results, index=[f'k2/k1 = {a}' for a in data_dict["k_ratios"]], columns=["Heat Convection"])
print("FDM Heat Convection Results x_bar = 0.5:")
print(df_fdm.to_string())
print("\n" * 2)
print("FEM Heat Convection Results x_bar = 0.5:")
print(df_fem.to_string())
print("\n" * 2)
# x_bar_2
# for every k ratio, calculate the heat convection from fdm and fem temp results
fdm_heat_results = []
fem_heat_results = []
for i, k_ratio in enumerate(data_dict["k_ratios"]):
Bar.set_k_ratio(k_ratio, bar1, bar2) # Set the k value of bar2 = k*bar1
dx = data_dict["section2"]["x_bar_2"]["x_values"][-1] - data_dict["section2"]["x_bar_2"]["x_values"][-2]
(fdm_t0, fdm_t1) = data_dict["section2"]["x_bar_2"]["fdm_results"][i][-2:]
fdm_heat_result = common.fdm_heat_extraction(fdm_t0, fdm_t1, dx, bar2, order=2)
fdm_heat_results.append(fdm_heat_result)
(fem_t0, fem_t1) = data_dict["section2"]["x_bar_2"]["fem_results"][i][-2:]
fem_heat_result = common.fem_heat_extraction(fem_t0, fem_t1, dx, bar2)
fem_heat_results.append(fem_heat_result)
data_dict["section2"]["x_bar_2"]["fdm_heat_results"] = np.array(fdm_heat_results)
data_dict["section2"]["x_bar_2"]["fem_heat_results"] = np.array(fem_heat_results)
df_fdm = pd.DataFrame(fdm_heat_results, index=[f'k2/k1 = {a}' for a in data_dict["k_ratios"]], columns=["Heat Convection"])
df_fem = pd.DataFrame(fem_heat_results, index=[f'k2/k1 = {a}' for a in data_dict["k_ratios"]], columns=["Heat Convection"])
print("FDM Heat Convection Results x_bar = 2/pi:")
print(df_fdm.to_string())
print("\n" * 2)
print("FEM Heat Convection Results x_bar = 2/pi:")
print(df_fem.to_string())
print("\n" * 2)
# Plotting x_bar_1 heat convection
plt.figure(figsize=(10, 6))
plt.plot(data_dict["k_ratios"], data_dict["section2"]["x_bar_1"]["fdm_heat_results"], label=f'FDM Heat Convection')
plt.plot(data_dict["k_ratios"], data_dict["section2"]["x_bar_1"]["fem_heat_results"], label=f'FEM Heat Convection')
#plt.plot(data_dict["k_ratios"], data_dict["section1"]["x_bar_1"]["heat_results"], label=f'Analytical Heat Convection')
plt.xlabel('k2/k1')
plt.ylabel('Q_Dot (W)')
plt.legend()
plt.grid(True)
plt.savefig('images/section2/x_bar_1/heat_convection_vs_k_ratio.png', dpi=300)
#plt.show()
plt.clf()
# Plotting x_bar_2 heat convection
plt.figure(figsize=(10, 6))
plt.plot(data_dict["k_ratios"], data_dict["section2"]["x_bar_2"]["fdm_heat_results"], label=f'FDM Heat Convection')
plt.plot(data_dict["k_ratios"], data_dict["section2"]["x_bar_2"]["fem_heat_results"], label=f'FEM Heat Convection')
#plt.plot(data_dict["k_ratios"], data_dict["section1"]["x_bar_2"]["heat_results"], label=f'Analytical Heat Convection')
plt.xlabel('k2/k1')
plt.ylabel('Q_Dot (W)')
plt.legend()
plt.grid(True)
plt.savefig('images/section2/x_bar_2/heat_convection_vs_k_ratio.png', dpi=300)
#plt.show()
plt.clf()
def section_3():
'''Convergence of FDM and FEM of interface temperature and heat convection'''
print("Section 3: Convergence of FDM and FEM with Varying k Ratio")
l = data_dict["length"]
data_dict["section3"] = {}
data_dict["section3"]["num_sections"] = [4, 8, 16, 32, 64, 128]
for k, x_bar_1 in enumerate(data_dict["x_bar_values"]):
# Calculate the number of rows needed for two columns of subplots
num_k_ratios = len(data_dict["k_ratios"])
num_rows = math.ceil(num_k_ratios / 2)
# Define the figure for temperature convergence (two columns)
fig_temp, axs_temp = plt.subplots(num_rows, 2, figsize=(15, 5 * num_rows))
# Define the figure for heat convergence (two columns)
fig_heat, axs_heat = plt.subplots(num_rows, 2, figsize=(15, 5 * num_rows))
# Flatten the axs arrays for easier indexing
axs_temp = axs_temp.flatten()
axs_heat = axs_heat.flatten()
# For every k ratio, iterate through every number of points, calculate convergence (compared to analytical and extrapolated), print and add a subplot
for idx, k_ratio in enumerate(data_dict["k_ratios"]):
Bar.set_k_ratio(k_ratio, bar1, bar2) # Set the k value of bar2 = k*bar1
# Get the analytical data
analy_interface_temp = case1.get_analytical_datapoints([x_bar_1], bar1, bar2, x_bar_1, l)
analy_heat = case1.get_analytical_heat_convection(l, bar1, bar2, x_bar_1, l)
# Setup data arrays
fdm_interface_temps = []
fem_interface_temps = []
fdm_extrap_temps = [None, None]
fem_extrap_temps = [None, None]
fdm_heats = []
fem_heats = []
fdm_extrap_heats = [None, None]
fem_extrap_heats = [None, None]
fdm_interface_temp_errors = []
fem_interface_temp_errors = []
fdm_interface_temp_betas = [[None]]
fem_interface_temp_betas = [[None]]
fdm_heat_errors = []
fem_heat_errors = []
fdm_heat_betas = [[None]]
fem_heat_betas = [[None]]
fdm_interface_temp_extrap_errors = [None, None]
fem_interface_temp_extrap_errors = [None, None]
fdm_interface_temp_extrap_betas = [None, None]
fem_interface_temp_extrap_betas = [None, None]
fdm_heat_extrap_errors = [None, None]
fem_heat_extrap_errors = [None, None]
fdm_heat_extrap_betas = [None, None]
fem_heat_extrap_betas = [None, None]
# Get the fdm and fem data
dx = 0
for i, num_sections in enumerate(data_dict["section3"]["num_sections"]):
fdm_temps, x_fdm = case1.solve(bar1=bar1,bar2=bar2,num_sections=num_sections,x_bar=x_bar_1,l=l,method="FDM")
fem_temps, x_fem = case1.solve(bar1=bar1,bar2=bar2,num_sections=num_sections,x_bar=x_bar_1,l=l,method="FEM")
# Get the interface temperature
fdm_interface_temp = fdm_temps[num_sections // 2]
fem_interface_temp = fem_temps[num_sections // 2]
fdm_interface_temps.append(fdm_interface_temp)
fem_interface_temps.append(fem_interface_temp)
# Get the 2 last temperature to calculate heat convection
dx_prev = dx
dx = x_fdm[-1] - x_fdm[-2]
(fdm_t0, fdm_t1) = fdm_temps[-2:]
fdm_heat = common.fdm_heat_extraction(fdm_t0, fdm_t1, dx, bar2, order=2)
(fem_t0, fem_t1) = fem_temps[-2:]
fem_heat = common.fem_heat_extraction(fem_t0, fem_t1, dx, bar2)
fdm_heats.append(fdm_heat)
fem_heats.append(fem_heat)
# Calculated the Richardson extrpolation of interface temperature and heat convection
if i >= 2:
fdm_extrap_temp = common.calc_extrapolated(fdm_interface_temps[-3], fdm_interface_temps[-2], fdm_interface_temps[-1])
fem_extrap_temp = common.calc_extrapolated(fem_interface_temps[-3], fem_interface_temps[-2], fem_interface_temps[-1])
fdm_extrap_heat = common.calc_extrapolated(fdm_heats[-3], fdm_heats[-2], fdm_heats[-1])
fem_extrap_heat = common.calc_extrapolated(fem_heats[-3], fem_heats[-2], fem_heats[-1])
fdm_extrap_temps.append(fdm_extrap_temp)
fem_extrap_temps.append(fem_extrap_temp)
fdm_extrap_heats.append(fdm_extrap_heat)
fem_extrap_heats.append(fem_extrap_heat)
# Calculate the errors in reference to extrapolated values
fdm_interface_temp_extrap_error = common.calc_error(fdm_extrap_temp, fdm_interface_temp)
fem_interface_temp_extrap_error = common.calc_error(fem_extrap_temp, fem_interface_temp)
fdm_heat_extrap_error = common.calc_error(fdm_extrap_heat, fdm_heat)
fem_heat_extrap_error = common.calc_error(fem_extrap_heat, fem_heat)
fdm_interface_temp_extrap_errors.append(fdm_interface_temp_extrap_error)
fem_interface_temp_extrap_errors.append(fem_interface_temp_extrap_error)
fdm_heat_extrap_errors.append(fdm_heat_extrap_error)
fem_heat_extrap_errors.append(fem_heat_extrap_error)
# Calculate the betas in reference to extrapolated values
fdm_interface_temp_extrap_beta = common.calc_beta(fdm_extrap_temp, fdm_interface_temps[-1], fdm_interface_temps[-2], dx, dx_prev)
fem_interface_temp_extrap_beta = common.calc_beta(fem_extrap_temp, fem_interface_temps[-1], fem_interface_temps[-2], dx, dx_prev)
fdm_heat_extrap_beta = common.calc_beta(fdm_extrap_heat, fdm_heats[-1], fdm_heats[-2], dx, dx_prev)
fem_heat_extrap_beta = common.calc_beta(fem_extrap_heat, fem_heats[-1], fem_heats[-2], dx, dx_prev)
fdm_interface_temp_extrap_betas.append(fdm_interface_temp_extrap_beta)
fem_interface_temp_extrap_betas.append(fem_interface_temp_extrap_beta)
fdm_heat_extrap_betas.append(fdm_heat_extrap_beta)
fem_heat_extrap_betas.append(fem_heat_extrap_beta)
# Calculate the error and convergence rates for fdm temp, fem temp, fdm heat, and fem heat
fdm_interface_temp_error = common.calc_error(analy_interface_temp, fdm_interface_temp)
fem_interface_temp_error = common.calc_error(analy_interface_temp, fem_interface_temp)
fdm_heat_error = common.calc_error(analy_heat, fdm_heat)
fem_heat_error = common.calc_error(analy_heat, fem_heat)
fdm_interface_temp_errors.append(fdm_interface_temp_error)
fem_interface_temp_errors.append(fem_interface_temp_error)
fdm_heat_errors.append(fdm_heat_error)
fem_heat_errors.append(fem_heat_error)
if i >= 1: # if i == 0 then we cannot calculate convergence
fdm_interface_temp_beta = common.calc_beta(analy_interface_temp, fdm_interface_temps[-1], fdm_interface_temps[-2], dx, dx_prev)
fem_interface_temp_beta = common.calc_beta(analy_interface_temp, fem_interface_temps[-1], fem_interface_temps[-2], dx, dx_prev)
fdm_heat_beta = common.calc_beta(analy_heat, fdm_heats[-1], fdm_heats[-2], dx, dx_prev)
fem_heat_beta = common.calc_beta(analy_heat, fem_heats[-1], fem_heats[-2], dx, dx_prev)
fdm_interface_temp_betas.append(fdm_interface_temp_beta)
fem_interface_temp_betas.append(fem_interface_temp_beta)
fdm_heat_betas.append(fdm_heat_beta)
fem_heat_betas.append(fem_heat_beta)
# Print the interface temps for this k ratio
table_data = []
for i in range(len(data_dict["section3"]["num_sections"])):
table_data.append([
analy_interface_temp[0], # True T
fdm_interface_temps[i], # fdm result
fdm_extrap_temps[i],
fdm_interface_temp_errors[i][0], # fdm % error in reference to analytical
fdm_interface_temp_betas[i][0], # fdm beta
fdm_interface_temp_extrap_errors[i], # fdm % error in reference to extrapolated value
fdm_interface_temp_extrap_betas[i], # fdm beta
fem_interface_temps[i], # fem result
fem_extrap_temps[i],
fem_interface_temp_errors[i][0], # fem % error
fem_interface_temp_betas[i][0], # fem beta
fem_interface_temp_extrap_errors[i], # fem extrap % error
fem_interface_temp_extrap_betas[i], # fem beta
])
columns = ['True T', 'FDM T', 'FDM Extrap T', 'FDM Exact % Error', 'FDM Exact B', 'FDM Extrap % Error', 'FDM Extrap B', 'FEM T', 'FEM Extrap T', 'FEM Exact % Error', 'FEM Exact B', 'FEM Extrap % Error', 'FEM Extrap B']
df = pd.DataFrame(table_data, index=[f'N = {i}' for i in data_dict["section3"]["num_sections"]], columns=columns)
print(f"Convergence of FDM and FEM Temperature at x_bar = {x_bar_1:.3f} and k_ratio = {k_ratio}")
print(df.to_string())
print("\n" * 2)
# Print the heat convection results for this k ratio
table_data = []
for i in range(len(data_dict["section3"]["num_sections"])):
table_data.append([
analy_heat, # True Q
fdm_heats[i], # fdm result
fdm_extrap_heats[i], # fdm extrapolated heat
fdm_heat_errors[i], # fdm % error in reference to analytical
fdm_heat_betas[i], # fdm beta in reference to analytical
fdm_heat_extrap_errors[i], # fdm % error in reference to extrapolated value
fdm_heat_extrap_betas[i], # fdm beta
fem_heats[i], # fem result
fem_extrap_heats[i], # fem extrapolated heat
fem_heat_errors[i], # fem % error
fem_heat_betas[i], # fem beta
fem_heat_extrap_errors[i], # fem % error
fem_heat_extrap_betas[i] # fem beta
])
columns = ['True Q', 'FDM Q', 'FDM Extrap Q', 'FDM Exact % Error', 'FDM Exact B', 'FDM Extrap % Error', 'FDM Extrap B', 'FEM Q', 'FEM Extrap Q', 'FEM Exact % Error', 'FEM Exact B', 'FEM Extrap % Error', 'FEM Extrap B']
df = pd.DataFrame(table_data, index=[f'N = {i}' for i in data_dict["section3"]["num_sections"]], columns=columns)
print(f"Convergence of FDM and FEM Heat Convection with x_bar = {x_bar_1:.3f} and k_ratio = {k_ratio}")
print(df.to_string())
print("\n" * 2)
# Add a subplot of the interface temp convergence for this k ratio
ax_temp = axs_temp[idx]
# Data to plot for temperature convergence
num_sections = data_dict["section3"]["num_sections"]
fdm_exact_errors = [e[0] for e in fdm_interface_temp_errors]
fem_exact_errors = [e[0] for e in fem_interface_temp_errors]
fdm_extrap_errors = fdm_interface_temp_extrap_errors
fem_extrap_errors = fem_interface_temp_extrap_errors
# Plotting temperature lines
ax_temp.plot(num_sections, fdm_exact_errors, label="FDM Exact")
ax_temp.plot(num_sections, fem_exact_errors, label="FEM Exact")
ax_temp.plot(num_sections, fdm_extrap_errors, label="FDM Extrap")
ax_temp.plot(num_sections, fem_extrap_errors, label="FEM Extrap")
ax_temp.set_xscale("log")
ax_temp.set_yscale("log")
ax_temp.set_xlabel("Number of Sections (N)")
ax_temp.set_ylabel("% Error")
ax_temp.set_title(f"k_ratio = {k_ratio}")
ax_temp.grid(True)
ax_temp.legend()
# Add a subplot of the heat convergence for this k ratio
ax_heat = axs_heat[idx]
# Data to plot for heat convergence
fdm_exact_heat_errors = fdm_heat_errors
fem_exact_heat_errors = fem_heat_errors
fdm_extrap_heat_errors = fdm_heat_extrap_errors
fem_extrap_heat_errors = fem_heat_extrap_errors
# Plotting heat lines
ax_heat.plot(num_sections, fdm_exact_heat_errors, label="FDM Exact")
ax_heat.plot(num_sections, fem_exact_heat_errors, label="FEM Exact")
ax_heat.plot(num_sections, fdm_extrap_heat_errors, label="FDM Extrap")
ax_heat.plot(num_sections, fem_extrap_heat_errors, label="FEM Extrap")
ax_heat.set_xscale("log")
ax_heat.set_yscale("log")
ax_heat.set_xlabel("Number of Sections (N)")
ax_heat.set_ylabel("% Error")
ax_heat.set_title(f"k_ratio = {k_ratio}")
ax_heat.grid(True)
ax_heat.legend()
# Hide any unused subplots (in case of an odd number of k_ratios)
for i in range(num_k_ratios, len(axs_temp)):
fig_temp.delaxes(axs_temp[i])
fig_heat.delaxes(axs_heat[i])
# Adjust layout for better spacing
fig_temp.tight_layout(rect=[0, 0.03, 1, 0.95])
fig_heat.tight_layout(rect=[0, 0.03, 1, 0.95])
# Save the plots
if k == 0:
fig_temp.savefig("images/section3/x_bar_1/temp_convergences.png", dpi=300)
fig_heat.savefig("images/section3/x_bar_1/heat_convergences.png", dpi=300)
else:
fig_temp.savefig("images/section3/x_bar_2/temp_convergences.png", dpi=300)
fig_heat.savefig("images/section3/x_bar_2/heat_convergences.png", dpi=300)
def main():
# Make directories for plots
import os
import shutil
base_dir = "images"
sub_dirs = ["section1", "section2", "section3"]
nested_dirs = ["x_bar_1", "x_bar_2"]
# Create the base directory if it doesn't exist
if not os.path.exists(base_dir):
os.mkdir(base_dir)
# Create or clear subdirectories and their nested directories
for sub_dir in sub_dirs:
section_path = os.path.join(base_dir, sub_dir)
if os.path.exists(section_path):
# Remove all contents of the directory
shutil.rmtree(section_path)
# Create the section directory
os.makedirs(section_path)
# Create nested directories within each section
for nested_dir in nested_dirs:
nested_path = os.path.join(section_path, nested_dir)
os.makedirs(nested_path)
# import sys
# # Redirect all print statements to a file
# sys.stdout = open("output.txt", "w", encoding="utf-8")
section_1() # Analytical solutions
section_2() # FDM and FEM temperature and heat convection
section_3() # Convergence of FDM and FEM temperature and heat convection
# # Restore original stdout and close the file
# sys.stdout.close()
# sys.stdout = sys.__stdout__
if __name__ == "__main__":
main()