347 lines
15 KiB
Python
347 lines
15 KiB
Python
import numpy as np
|
||
import matplotlib.pyplot as plt
|
||
from scipy.interpolate import CubicSpline
|
||
from scipy.integrate import simpson
|
||
|
||
|
||
# -----------------------------
|
||
# 1. 材料级:PDMS光学性能计算(你的模型核心逻辑,修复变量定义错误)
|
||
# -----------------------------
|
||
def make_strictly_increasing(wl, n, k):
|
||
# 去除重复点并确保波长严格递增
|
||
unique_wl, indices = np.unique(wl, return_index=True)
|
||
if len(unique_wl) != len(wl):
|
||
print(f"Removed {len(wl) - len(unique_wl)} duplicate wavelength points")
|
||
wl, n, k = wl[indices], n[indices], k[indices]
|
||
# 确保严格递增
|
||
is_increasing = np.diff(wl) > 0
|
||
if not all(is_increasing):
|
||
valid_indices = np.concatenate([[True], is_increasing])
|
||
wl, n, k = wl[valid_indices], n[valid_indices], k[valid_indices]
|
||
return wl, n, k
|
||
|
||
|
||
def read_split_data(file_path):
|
||
with open(file_path, 'r', encoding='utf-8') as f:
|
||
lines = [line.strip() for line in f if line.strip() and not line.startswith('#')]
|
||
split_idx = None
|
||
for i, line in enumerate(lines):
|
||
if line == 'wl k':
|
||
split_idx = i
|
||
break
|
||
if split_idx is None:
|
||
raise ValueError("未找到'wl k'表头,请检查数据格式!")
|
||
n_lines = lines[1:split_idx]
|
||
wl_n, n_list = [], []
|
||
for line in n_lines:
|
||
parts = line.split()
|
||
if len(parts) != 2:
|
||
continue # 跳过格式错误的行
|
||
wl, n_val = parts
|
||
wl_n.append(float(wl)), n_list.append(float(n_val))
|
||
k_lines = lines[split_idx + 1:]
|
||
wl_k, k_list = [], []
|
||
for line in k_lines:
|
||
parts = line.split()
|
||
if len(parts) != 2:
|
||
continue # 跳过格式错误的行
|
||
wl, k_val = parts
|
||
wl_k.append(float(wl)), k_list.append(float(k_val))
|
||
# 转换为numpy数组
|
||
wl_n, n_list = np.array(wl_n), np.array(n_list)
|
||
wl_k, k_list = np.array(wl_k), np.array(k_list)
|
||
# 确保n和k的波长完全一致
|
||
assert np.allclose(wl_n, wl_k), "n和k的波长列表不一致!"
|
||
# 排序
|
||
sorted_idx = np.argsort(wl_n)
|
||
return wl_n[sorted_idx], n_list[sorted_idx], k_list[sorted_idx]
|
||
|
||
|
||
def fresnel_reflectance(n1, k1, n2, k2):
|
||
m1, m2 = n1 + 1j * k1, n2 + 1j * k2
|
||
return np.abs((m1 - m2) / (m1 + m2)) ** 2
|
||
|
||
|
||
def thin_film_optical_properties(n_film, k_film, d, wl):
|
||
"""修复denominator未定义的错误,完整计算R_total和T_total"""
|
||
R12 = fresnel_reflectance(1.0, 0.0, n_film, k_film) # 空气→薄膜
|
||
R23 = fresnel_reflectance(n_film, k_film, 1.0, 0.0) # 薄膜→空气
|
||
delta = 2 * np.pi * n_film * d / wl # 干涉相位差
|
||
alpha_abs = 4 * np.pi * k_film * d / wl # 吸收衰减系数
|
||
|
||
# 计算分母(关键修复:补充denominator的定义)
|
||
denominator = 1 + R12 * R23 * np.exp(-alpha_abs) + 2 * np.sqrt(R12 * R23 * np.exp(-alpha_abs)) * np.cos(2 * delta)
|
||
|
||
# 总反射率
|
||
numerator_R = R12 + R23 * np.exp(-alpha_abs) + 2 * np.sqrt(R12 * R23 * np.exp(-alpha_abs)) * np.cos(2 * delta)
|
||
R_total = numerator_R / denominator
|
||
|
||
# 总透射率(修复后)
|
||
T_total = (1 - R12) * (1 - R23) * np.exp(-alpha_abs) / denominator
|
||
|
||
# 吸收率=发射率(热平衡下)
|
||
alpha_total = 1 - R_total - T_total
|
||
return alpha_total, R_total, T_total # alpha_total即ε(发射率)
|
||
|
||
|
||
# -----------------------------
|
||
# 2. 数据读取与预处理
|
||
# -----------------------------
|
||
# 替换为你的data.txt实际路径(确保正确)
|
||
DATA_PATH = '/Users/spasolreisa/IdeaProjects/asiaMath/data.txt'
|
||
wl_all, n_all, k_all = read_split_data(DATA_PATH)
|
||
wl_all, n_all, k_all = make_strictly_increasing(wl_all, n_all, k_all)
|
||
print(f"数据读取成功:波长范围 {wl_all.min():.2f}–{wl_all.max():.2f} μm,共{len(wl_all)}个数据点")
|
||
|
||
# 三次样条插值
|
||
cs_n = CubicSpline(wl_all, n_all)
|
||
cs_k = CubicSpline(wl_all, k_all)
|
||
|
||
# 定义PDMS厚度和计算波长范围
|
||
thicknesses = [0.5, 1.0, 1.5, 2.0]
|
||
wl_fine = np.linspace(wl_all.min(), wl_all.max(), 500) # 细化解析度
|
||
|
||
# -----------------------------
|
||
# 3. 预计算材料级关键参数(ε和α)
|
||
# -----------------------------
|
||
# 存储平均发射率(8-13μm,黑体辐射加权)和平均太阳吸收率(0.3-2.5μm,太阳光谱加权)
|
||
avg_eps_dict = {} # 平均发射率 ε_avg
|
||
avg_alpha_dict = {} # 平均太阳吸收率 α_avg
|
||
|
||
|
||
# 定义权重光谱(辐射冷却+太阳吸收关键波段)
|
||
def planck_spectrum(wl, T):
|
||
"""普朗克黑体光谱(8-13μm波段权重)"""
|
||
wl_m = wl * 1e-6 # 转换为米
|
||
c1 = 3.7418e8 # 第一辐射常数 (W·μm⁴/m²)
|
||
c2 = 14388 # 第二辐射常数 (μm·K)
|
||
return c1 / (wl_m ** 5 * (np.exp(c2 / (wl * T)) - 1))
|
||
|
||
|
||
def solar_spectrum_am15(wl):
|
||
"""AM1.5太阳光谱(0.3-2.5μm波段权重)"""
|
||
spectrum = np.zeros_like(wl)
|
||
mask = (wl >= 0.3) & (wl <= 2.5)
|
||
wl_masked = wl[mask]
|
||
# 经验拟合AM1.5标准光谱
|
||
spectrum[mask] = np.where(
|
||
wl_masked < 0.5, 800 + 400 * wl_masked,
|
||
np.where(wl_masked < 1.0, 1000 - 200 * (wl_masked - 0.5),
|
||
np.where(wl_masked < 1.5, 900 - 100 * (wl_masked - 1.0),
|
||
750 - 200 * (wl_masked - 1.5)))
|
||
)
|
||
return spectrum
|
||
|
||
|
||
# 计算各厚度的平均ε和α
|
||
for d in thicknesses:
|
||
print(f"\n正在计算厚度 {d} μm 的光学性能...")
|
||
|
||
# -----------------------------
|
||
# 计算平均发射率 ε_avg(8-13μm,黑体辐射加权)
|
||
# -----------------------------
|
||
if wl_all.min() <= 13 and wl_all.max() >= 8:
|
||
wl_rad = np.linspace(8, 13, 300) # 辐射冷却核心波段
|
||
n_rad = cs_n(wl_rad)
|
||
k_rad = cs_k(wl_rad)
|
||
eps_rad, _, _ = thin_film_optical_properties(n_rad, k_rad, d, wl_rad)
|
||
planck_weight = planck_spectrum(wl_rad, T=298) # 25℃黑体光谱权重
|
||
# 加权平均
|
||
eps_avg = simpson(eps_rad * planck_weight, wl_rad) / simpson(planck_weight, wl_rad)
|
||
else:
|
||
print(f"警告:数据未覆盖8-13μm波段,使用全波段平均发射率替代")
|
||
n_film = cs_n(wl_fine)
|
||
k_film = cs_k(wl_fine)
|
||
eps_full, _, _ = thin_film_optical_properties(n_film, k_film, d, wl_fine)
|
||
eps_avg = np.mean(eps_full)
|
||
avg_eps_dict[d] = eps_avg
|
||
|
||
# -----------------------------
|
||
# 计算平均太阳吸收率 α_avg(0.3-2.5μm,太阳光谱加权)
|
||
# -----------------------------
|
||
if wl_all.min() <= 2.5 and wl_all.max() >= 0.3:
|
||
wl_solar = np.linspace(0.3, 2.5, 300) # 太阳光谱波段
|
||
n_solar = cs_n(wl_solar)
|
||
k_solar = cs_k(wl_solar)
|
||
alpha_solar, _, _ = thin_film_optical_properties(n_solar, k_solar, d, wl_solar)
|
||
solar_weight = solar_spectrum_am15(wl_solar) # AM1.5太阳光谱权重
|
||
# 加权平均
|
||
alpha_avg = simpson(alpha_solar * solar_weight, wl_solar) / simpson(solar_weight, wl_solar)
|
||
else:
|
||
print(f"警告:数据未覆盖0.3-2.5μm太阳波段,使用PDMS典型值α=0.08")
|
||
alpha_avg = 0.08 # PDMS在太阳波段的典型吸收率(低吸收)
|
||
avg_alpha_dict[d] = alpha_avg
|
||
|
||
# -----------------------------
|
||
# 4. 系统级:净冷却功率计算(解答思路核心逻辑)
|
||
# -----------------------------
|
||
# 系统物理参数(可根据实际场景调整)
|
||
sigma = 5.67e-8 # 斯特藩-玻尔兹曼常数 (W/m²·K⁴)
|
||
G_sun_list = [500, 700, 900, 1100] # 不同太阳辐照强度(对应多云到晴天)
|
||
T_amb_list = np.linspace(293, 318, 6) # 环境温度(20-45℃,转换为开尔文)
|
||
v_wind = 1.5 # 风速 (m/s)
|
||
h_conv = 5.6 + 3.1 * v_wind # 对流换热系数(经验公式,W/m²·K)
|
||
|
||
|
||
def net_cooling_power(eps, alpha, T_s, T_amb, G_sun, h_conv, sigma):
|
||
"""净冷却功率公式:P_net = 辐射散热 - 太阳吸收热 - 对流换热损失"""
|
||
# 辐射散热(向宇宙太空)
|
||
rad散热 = eps * sigma * T_s ** 4
|
||
# 太阳吸收热(从太阳光获取的热量)
|
||
solar吸热 = alpha * G_sun
|
||
# 对流换热损失(向环境散热/吸热)
|
||
conv损失 = h_conv * (T_s - T_amb)
|
||
# 环境辐射吸收(从环境获取的辐射热)
|
||
amb_rad吸热 = eps * sigma * T_amb ** 4
|
||
# 净冷却功率(正值表示主动冷却,负值表示吸热)
|
||
return rad散热 - solar吸热 - conv损失 - amb_rad吸热
|
||
|
||
|
||
def solve_surface_temperature(eps, alpha, T_amb, G_sun, h_conv, sigma):
|
||
"""迭代求解PDMS薄膜表面温度T_s(净冷却功率=0时的热平衡温度)"""
|
||
T_s_guess = T_amb - 5 # 初始猜测(比环境低5℃)
|
||
tol = 1e-3 # 收敛精度
|
||
max_iter = 100 # 最大迭代次数
|
||
for _ in range(max_iter):
|
||
P_net = net_cooling_power(eps, alpha, T_s_guess, T_amb, G_sun, h_conv, sigma)
|
||
# 数值微分求导(牛顿迭代法,确保收敛)
|
||
dP_dT = (net_cooling_power(eps, alpha, T_s_guess + 1e-4, T_amb, G_sun, h_conv, sigma) -
|
||
net_cooling_power(eps, alpha, T_s_guess - 1e-4, T_amb, G_sun, h_conv, sigma)) / (2e-4)
|
||
if abs(dP_dT) < 1e-6:
|
||
break # 避免除以零
|
||
# 更新猜测值
|
||
T_s_new = T_s_guess - P_net / dP_dT
|
||
# 限制温度范围(物理合理值)
|
||
T_s_new = max(250, min(T_amb + 5, T_s_new))
|
||
# 检查收敛
|
||
if abs(T_s_new - T_s_guess) < tol:
|
||
return T_s_new
|
||
T_s_guess = T_s_new
|
||
return T_s_guess # 若未收敛,返回最后一次猜测值
|
||
|
||
|
||
# -----------------------------
|
||
# 5. 全链条分析:材料性能→系统冷却性能
|
||
# -----------------------------
|
||
# 存储各厚度的系统级结果
|
||
system_results = {}
|
||
for d in thicknesses:
|
||
eps = avg_eps_dict[d]
|
||
alpha = avg_alpha_dict[d]
|
||
# 初始化结果矩阵(太阳辐照×环境温度)
|
||
P_net_matrix = np.zeros((len(G_sun_list), len(T_amb_list)))
|
||
T_s_matrix = np.zeros((len(G_sun_list), len(T_amb_list)))
|
||
# 遍历所有太阳辐照和环境温度组合
|
||
for i, G_sun in enumerate(G_sun_list):
|
||
for j, T_amb in enumerate(T_amb_list):
|
||
# 求解表面温度
|
||
T_s = solve_surface_temperature(eps, alpha, T_amb, G_sun, h_conv, sigma)
|
||
T_s_matrix[i, j] = T_s
|
||
# 计算净冷却功率
|
||
P_net = net_cooling_power(eps, alpha, T_s, T_amb, G_sun, h_conv, sigma)
|
||
P_net_matrix[i, j] = P_net
|
||
# 存储结果
|
||
system_results[d] = {
|
||
"eps_avg": eps,
|
||
"alpha_avg": alpha,
|
||
"P_net": P_net_matrix,
|
||
"T_s": T_s_matrix
|
||
}
|
||
|
||
# -----------------------------
|
||
# 6. 结果可视化(全链条分析图表)
|
||
# -----------------------------
|
||
plt.rcParams['font.sans-serif'] = ['Arial'] # 统一字体
|
||
plt.rcParams['axes.unicode_minus'] = False # 支持负号
|
||
|
||
# 图1:材料级性能(平均ε和α随厚度变化)
|
||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
|
||
thicknesses_arr = np.array(thicknesses)
|
||
|
||
# 平均发射率
|
||
ax1.bar(thicknesses_arr - 0.08, [system_results[d]["eps_avg"] for d in thicknesses],
|
||
width=0.15, label='Avg Emissivity (8-13μm)', color='darkred', alpha=0.8)
|
||
ax1.set_xlabel('PDMS Thickness (μm)', fontsize=12)
|
||
ax1.set_ylabel('Emissivity', fontsize=12)
|
||
ax1.set_title('Average Emissivity (Radiative Cooling Window)', fontsize=14, fontweight='bold')
|
||
ax1.grid(True, alpha=0.3)
|
||
ax1.set_ylim(0, 1.05)
|
||
|
||
# 平均太阳吸收率
|
||
ax2.bar(thicknesses_arr - 0.08, [system_results[d]["alpha_avg"] for d in thicknesses],
|
||
width=0.15, label='Avg Solar Absorptivity (0.3-2.5μm)', color='darkblue', alpha=0.8)
|
||
ax2.set_xlabel('PDMS Thickness (μm)', fontsize=12)
|
||
ax2.set_ylabel('Absorptivity', fontsize=12)
|
||
ax2.set_title('Average Solar Absorptivity', fontsize=14, fontweight='bold')
|
||
ax2.grid(True, alpha=0.3)
|
||
ax2.set_ylim(0, 0.2) # 限制范围,更清晰
|
||
|
||
plt.tight_layout()
|
||
plt.savefig('material_performance.png', dpi=300, bbox_inches='tight')
|
||
|
||
# 图2:系统级性能(净冷却功率随环境温度变化,选最优厚度)
|
||
# 最优厚度:ε/α比值最大(平衡高发射和低吸收)
|
||
optimal_d = max(thicknesses, key=lambda x: system_results[x]["eps_avg"] / (system_results[x]["alpha_avg"] + 0.01))
|
||
print(
|
||
f"\n最优厚度:{optimal_d} μm(ε={system_results[optimal_d]['eps_avg']:.4f}, α={system_results[optimal_d]['alpha_avg']:.4f})")
|
||
|
||
fig, ax = plt.subplots(figsize=(12, 6))
|
||
T_amb_c = T_amb_list - 273.15 # 转换为摄氏度
|
||
colors = ['red', 'orange', 'green', 'blue']
|
||
|
||
for i, G_sun in enumerate(G_sun_list):
|
||
P_net = system_results[optimal_d]["P_net"][i, :]
|
||
ax.plot(T_amb_c, P_net, marker='o', markersize=6, linewidth=2,
|
||
color=colors[i], label=f'Solar Irradiance = {G_sun} W/m²')
|
||
|
||
ax.set_xlabel('Ambient Temperature (°C)', fontsize=12)
|
||
ax.set_ylabel('Net Cooling Power (W/m²)', fontsize=12)
|
||
ax.set_title(f'Net Cooling Power vs Ambient Temperature (PDMS Thickness = {optimal_d} μm)',
|
||
fontsize=14, fontweight='bold')
|
||
ax.grid(True, alpha=0.3)
|
||
ax.legend(fontsize=11)
|
||
# 添加零线(区分冷却/吸热)
|
||
ax.axhline(y=0, color='black', linestyle='--', alpha=0.5, label='Zero Cooling Power')
|
||
plt.tight_layout()
|
||
plt.savefig('net_cooling_power.png', dpi=300, bbox_inches='tight')
|
||
|
||
# 图3:表面温度随环境温度变化
|
||
fig, ax = plt.subplots(figsize=(12, 6))
|
||
for i, G_sun in enumerate(G_sun_list):
|
||
T_s = system_results[optimal_d]["T_s"][i, :] - 273.15 # 转换为摄氏度
|
||
ax.plot(T_amb_c, T_s, marker='s', markersize=6, linewidth=2,
|
||
color=colors[i], label=f'Solar Irradiance = {G_sun} W/m²')
|
||
|
||
ax.set_xlabel('Ambient Temperature (°C)', fontsize=12)
|
||
ax.set_ylabel('PDMS Surface Temperature (°C)', fontsize=12)
|
||
ax.set_title(f'Surface Temperature vs Ambient Temperature (PDMS Thickness = {optimal_d} μm)',
|
||
fontsize=14, fontweight='bold')
|
||
ax.grid(True, alpha=0.3)
|
||
ax.legend(fontsize=11)
|
||
# 添加环境温度参考线(y=x)
|
||
ax.plot(T_amb_c, T_amb_c, color='black', linestyle='--', alpha=0.5, label='Ambient Temperature')
|
||
plt.tight_layout()
|
||
plt.savefig('surface_temperature.png', dpi=300, bbox_inches='tight')
|
||
|
||
plt.show()
|
||
|
||
# -----------------------------
|
||
# 7. 关键结果输出(量化分析)
|
||
# -----------------------------
|
||
print("\n" + "=" * 60)
|
||
print("材料-系统全链条关键结果")
|
||
print("=" * 60)
|
||
for d in thicknesses:
|
||
print(f"\n厚度 {d} μm:")
|
||
print(f" - 平均发射率(8-13μm): {system_results[d]['eps_avg']:.4f}")
|
||
print(f" - 平均太阳吸收率(0.3-2.5μm): {system_results[d]['alpha_avg']:.4f}")
|
||
print(f" - 最优工况净冷却功率(T_amb=30℃, G_sun=900 W/m²): {system_results[d]['P_net'][2, 2]:.2f} W/m²")
|
||
print(f" - 对应表面温度: {system_results[d]['T_s'][2, 2] - 273.15:.2f} ℃")
|
||
|
||
print("\n" + "=" * 60)
|
||
print("结论:PDMS薄膜的最优厚度为 {} μm,在典型工况下(30℃环境、900 W/m²太阳辐照)".format(optimal_d))
|
||
print("可实现 {:.2f} W/m² 的净冷却功率,表面温度比环境低 {:.2f} ℃".format(
|
||
system_results[optimal_d]['P_net'][2, 2],
|
||
30 - (system_results[optimal_d]['T_s'][2, 2] - 273.15)
|
||
))
|
||
print("=" * 60) |