@@ -0,0 +1,667 @@
import math
import os
from dataclasses import dataclass
from typing import Dict , List , Tuple , Optional
import numpy as np
from matplotlib import pyplot as plt
from scipy . interpolate import CubicSpline
from scipy . integrate import simpson
# 全局物理常数(修正:优化热物理参数,确保量级合理)
SIGMA = 5.670374419e-8 # Stefan-Boltzmann constant (W/m²/K⁴)
T_AMB = 300.0 # Ambient temperature (K) ≈27℃
T_SKY = 270.0 # 降低天空温度(更贴近真实晴空,增强辐射散热)
SOLAR_IRR = 850.0 # 太阳辐照度( 合理范围: 800-900 W/m²)
H_CONV = 10.0 # 自然对流换热系数( 优化为10 W/m²/K, 更贴近实际)
H_COND_MAX = 1000.0 # 最大传导换热系数(限制量级,避免异常大值)
k_PDMS = 0.12 # PDMS导热系数( 取保守值0.12 W/m·K, 避免偏大)
MAX_TEMPERATURE_DIFF = 15.0 # 最大允许温差( K) : 避免平衡温度过低导致热损失量级异常
# 关键波段定义
SOLAR_BAND = ( 0.3 , 2.5 ) # Solar spectrum range (μm)
ATMOSPHERIC_WINDOW = ( 8.0 , 13.0 ) # Atmospheric transparency window (μm)
THERMAL_BAND = ( 2.5 , 25.0 ) # Thermal radiation full band (μm)
# 绘图配置(纯英文)
plt . rcParams [ " font.sans-serif " ] = [ " Arial " , " Helvetica " , " DejaVu Sans " ]
plt . rcParams [ " axes.unicode_minus " ] = False # Fix minus sign display
plt . rcParams [ " figure.dpi " ] = 100
plt . rcParams [ " savefig.dpi " ] = 300
@dataclass
class OpticalProperty :
""" Optical property data class """
wl : np . ndarray # Wavelength (μm)
n : np . ndarray # Refractive index
k : np . ndarray # Extinction coefficient
cs_n : CubicSpline # Cubic spline for refractive index
cs_k : CubicSpline # Cubic spline for extinction coefficient
@dataclass
class SpectralMetric :
""" Spectral matching metrics """
thickness_um : float
avg_eps_window : float # Average emissivity in atmospheric window
avg_alpha_solar : float # Average absorptivity in solar band
spectral_match_index : float # Spectral matching index (ε_window/α _solar)
eps_window_std : float # Std of emissivity in atmospheric window
alpha_solar_std : float # Std of absorptivity in solar band
@dataclass
class CoolingPerformance :
""" Comprehensive cooling performance metrics """
thickness_um : float
spectral_metric : SpectralMetric
net_radiative_power : float # Net radiative power (W/m²) 核心新增指标,单独绘图
solar_gain : float # Solar absorption heat flux (W/m²)
convective_loss : float # Convective heat loss (W/m²)
conductive_loss : float # Conductive heat loss (W/m²)
net_cooling_power : float # Total net cooling power (W/m²)
equilibrium_temp_K : float # Equilibrium temperature (K)
@property
def equilibrium_temp_C ( self ) - > float :
return self . equilibrium_temp_K - 273.15
@property
def temp_drop_C ( self ) - > float :
# 正确逻辑:降温值 = 环境温度 - 平衡温度(确保为正,有效冷却)
return T_AMB - self . equilibrium_temp_K
# ------------------------------
# 1. Data Preprocessing and Optical Property Loading
# ------------------------------
def make_strictly_increasing ( wl : np . ndarray , n : np . ndarray , k : np . ndarray ) - > Tuple [ np . ndarray , np . ndarray , np . ndarray ] :
""" Ensure wavelength data is strictly increasing and free of duplicates """
# Remove duplicate wavelengths
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 ]
# Ensure strictly increasing
is_increasing = np . diff ( wl ) > 1e-6 # Allow minor tolerance
if not all ( is_increasing ) :
valid_indices = np . concatenate ( [ [ True ] , is_increasing ] )
wl , n , k = wl [ valid_indices ] , n [ valid_indices ] , k [ valid_indices ]
print ( f " Removed { len ( is_increasing ) - sum ( is_increasing ) } non-increasing wavelength points " )
return wl , n , k
def read_split_data ( file_path : str ) - > Tuple [ np . ndarray , np . ndarray , np . ndarray ] :
""" Read split-format optical data (n and k stored separately) """
with open ( file_path , ' r ' , encoding = ' utf-8 ' ) as f :
lines = [ line . strip ( ) for line in f if line . strip ( ) and not line . startswith ( ' # ' ) ]
# Find split point between n and k data
split_idx = None
for i , line in enumerate ( lines ) :
if line == ' wl k ' :
split_idx = i
break
if split_idx is None :
raise ValueError ( " Data file format error: ' wl k ' delimiter not found " )
# Read n data
n_lines = lines [ 1 : split_idx ] # Skip 'wl n' header
wl_n , n_list = [ ] , [ ]
for line in n_lines :
parts = line . split ( )
if len ( parts ) > = 2 :
wl_n . append ( float ( parts [ 0 ] ) )
n_list . append ( float ( parts [ 1 ] ) )
# Read k data
k_lines = lines [ split_idx + 1 : ] # Skip 'wl k' header
wl_k , k_list = [ ] , [ ]
for line in k_lines :
parts = line . split ( )
if len ( parts ) > = 2 :
wl_k . append ( float ( parts [ 0 ] ) )
k_list . append ( float ( parts [ 1 ] ) )
# Convert to numpy arrays
wl_n , n_list = np . array ( wl_n ) , np . array ( n_list )
wl_k , k_list = np . array ( wl_k ) , np . array ( k_list )
# Unify wavelength range (interpolate to common wavelengths)
if not np . allclose ( wl_n , wl_k ) :
print ( " Warning: Wavelength ranges of n and k do not match, performing interpolation " )
common_wl = np . linspace (
max ( wl_n . min ( ) , wl_k . min ( ) ) ,
min ( wl_n . max ( ) , wl_k . max ( ) ) ,
1000
)
n_list = np . interp ( common_wl , wl_n , n_list )
k_list = np . interp ( common_wl , wl_k , k_list )
wl_n = common_wl
# Ensure strictly increasing
wl , n , k = make_strictly_increasing ( wl_n , n_list , k_list )
return wl , n , k
def load_optical_properties ( file_path : str ) - > OpticalProperty :
""" Load optical properties and create interpolation functions """
wl , n , k = read_split_data ( file_path )
cs_n = CubicSpline ( wl , n , bc_type = ' natural ' )
cs_k = CubicSpline ( wl , k , bc_type = ' natural ' )
print ( f " Data loaded successfully: " )
print ( f " Wavelength range: { wl . min ( ) : .2f } - { wl . max ( ) : .2f } μm " )
print ( f " Number of data points: { len ( wl ) } " )
print ( f " Refractive index n: { n . min ( ) : .3f } - { n . max ( ) : .3f } " )
print ( f " Extinction coefficient k: { k . min ( ) : .6f } - { k . max ( ) : .6f } " )
return OpticalProperty ( wl = wl , n = n , k = k , cs_n = cs_n , cs_k = cs_k )
# ------------------------------
# 2. Core Optical Model (Emissivity/Absorptivity Calculation)
# ------------------------------
def fresnel_reflectance ( n1 : float , k1 : float , n2 : float , k2 : float ) - > float :
""" Fresnel reflectance (normal incidence, considering complex refractive index) """
m1 = n1 + 1 j * k1
m2 = n2 + 1 j * k2
return np . abs ( ( m1 - m2 ) / ( m1 + m2 ) ) * * 2
def thin_film_spectral_property (
optical : OpticalProperty ,
thickness_um : float ,
wl_range : Tuple [ float , float ]
) - > Tuple [ np . ndarray , np . ndarray , np . ndarray ] :
""" Calculate spectral emissivity and absorptivity of thin film in specified wavelength range """
wl_start , wl_end = wl_range
# Generate dense wavelength points
wl = np . linspace ( wl_start , wl_end , 500 )
# Interpolate optical parameters
n_film = optical . cs_n ( wl )
k_film = optical . cs_k ( wl )
n_air , k_air = 1.0 , 0.0
# Calculate Fresnel reflectance
R12 = fresnel_reflectance ( n_air , k_air , n_film , k_film ) # Air → Film
R23 = fresnel_reflectance ( n_film , k_film , n_air , k_air ) # Film → Air
# Calculate phase difference and absorption attenuation
delta = 2 * np . pi * n_film * thickness_um / wl # Interference phase difference
alpha = 4 * np . pi * k_film * thickness_um / wl # Absorption attenuation coefficient
# Multibeam interference reflectance
numerator = R12 + R23 * np . exp ( - alpha ) + 2 * np . sqrt ( R12 * R23 * np . exp ( - alpha ) ) * np . cos ( 2 * delta )
denominator = 1 + R12 * R23 * np . exp ( - alpha ) + 2 * np . sqrt ( R12 * R23 * np . exp ( - alpha ) ) * np . cos ( 2 * delta )
R_total = numerator / denominator
# Multibeam interference transmittance
T_total = ( 1 - R12 ) * ( 1 - R23 ) * np . exp ( - alpha ) / denominator
# Emissivity (Kirchhoff's law) and absorptivity (α =ε under local thermal equilibrium)
epsilon = 1 - R_total - T_total
alpha = epsilon # Absorptivity = Emissivity under local thermal equilibrium
# Numerical clipping to avoid out-of-range values due to calculation errors
epsilon = np . clip ( epsilon , 0.0 , 1.0 )
alpha = np . clip ( alpha , 0.0 , 1.0 )
return wl , epsilon , alpha
# ------------------------------
# 3. Spectral Matching Quantitative Analysis
# ------------------------------
def calculate_spectral_metric (
optical : OpticalProperty ,
thickness_um : float
) - > SpectralMetric :
""" Calculate spectral matching metrics """
# 1. Emissivity in atmospheric window (8-13μm)
wl_window , eps_window , _ = thin_film_spectral_property (
optical , thickness_um , ATMOSPHERIC_WINDOW
)
avg_eps = np . mean ( eps_window )
std_eps = np . std ( eps_window )
# 2. Absorptivity in solar band (0.3-2.5μm)
wl_solar , _ , alpha_solar = thin_film_spectral_property (
optical , thickness_um , SOLAR_BAND
)
avg_alpha = np . mean ( alpha_solar )
std_alpha = np . std ( alpha_solar )
# 3. Spectral matching index (larger is better, avoid division by zero)
match_index = avg_eps / ( avg_alpha + 1e-6 )
return SpectralMetric (
thickness_um = thickness_um ,
avg_eps_window = avg_eps ,
avg_alpha_solar = avg_alpha ,
spectral_match_index = match_index ,
eps_window_std = std_eps ,
alpha_solar_std = std_alpha
)
def plot_spectral_metrics ( metrics_list : List [ SpectralMetric ] , save_path : str ) :
""" Plot spectral matching metrics (full English) """
thicknesses = [ m . thickness_um for m in metrics_list ]
avg_eps = [ m . avg_eps_window for m in metrics_list ]
avg_alpha = [ m . avg_alpha_solar for m in metrics_list ]
match_indices = [ m . spectral_match_index for m in metrics_list ]
fig , ax1 = plt . subplots ( figsize = ( 10 , 6 ) )
# Left axis: Emissivity and Absorptivity
color1 = ' #2E86AB '
color2 = ' #A23B72 '
ax1 . set_xlabel ( ' PDMS Film Thickness (μm) ' , fontsize = 12 )
ax1 . set_ylabel ( ' Emissivity / Absorptivity ' , fontsize = 12 )
line1 = ax1 . plot ( thicknesses , avg_eps , marker = ' o ' , linewidth = 2 ,
color = color1 , label = ' Avg Emissivity (8-13μm) ' , markersize = 6 )
line2 = ax1 . plot ( thicknesses , avg_alpha , marker = ' s ' , linewidth = 2 ,
color = color2 , label = ' Avg Absorptivity (0.3-2.5μm) ' , markersize = 6 )
ax1 . tick_params ( axis = ' y ' )
ax1 . set_ylim ( 0 , 1.0 )
ax1 . grid ( True , alpha = 0.3 )
# Right axis: Spectral Matching Index
ax2 = ax1 . twinx ( )
color3 = ' #F18F01 '
ax2 . set_ylabel ( ' Spectral Matching Index ' , fontsize = 12 , color = color3 )
line3 = ax2 . plot ( thicknesses , match_indices , marker = ' ^ ' , linewidth = 2 ,
color = color3 , label = ' Spectral Matching Index ' , markersize = 6 )
ax2 . tick_params ( axis = ' y ' , labelcolor = color3 )
ax2 . set_ylim ( 0 , max ( match_indices ) * 1.1 )
# Combine legends
lines = line1 + line2 + line3
labels = [ l . get_label ( ) for l in lines ]
ax1 . legend ( lines , labels , loc = ' upper right ' , fontsize = 10 )
plt . title ( ' Spectral Matching Metrics of PDMS Films vs Thickness ' , fontsize = 14 , fontweight = ' bold ' )
plt . tight_layout ( )
plt . savefig ( save_path , bbox_inches = ' tight ' )
print ( f " Spectral matching metrics plot saved to: { save_path } " )
# ------------------------------
# 4. Solar Absorptivity Modeling and Visualization
# ------------------------------
def plot_solar_absorption_spectra (
optical : OpticalProperty ,
thicknesses : List [ float ] ,
save_path : str
) :
""" Plot solar band absorptivity spectra for different thicknesses (full English) """
fig , ax = plt . subplots ( figsize = ( 10 , 6 ) )
colors = plt . cm . Set3 ( np . linspace ( 0 , 1 , len ( thicknesses ) ) )
for idx , thickness in enumerate ( thicknesses ) :
wl_solar , _ , alpha_solar = thin_film_spectral_property (
optical , thickness , SOLAR_BAND
)
ax . plot ( wl_solar , alpha_solar , linewidth = 2 , color = colors [ idx ] ,
label = f ' { thickness } μm ' )
ax . set_xlabel ( ' Wavelength (μm) ' , fontsize = 12 )
ax . set_ylabel ( ' Solar Absorptivity α (λ) ' , fontsize = 12 )
ax . set_title ( ' Solar Band Absorptivity Spectra of PDMS Films with Different Thicknesses ' , fontsize = 14 ,
fontweight = ' bold ' )
ax . grid ( True , alpha = 0.3 )
ax . legend ( title = ' Film Thickness ' , fontsize = 10 , title_fontsize = 11 )
ax . set_ylim ( 0 , 0.3 ) # Solar absorptivity is usually low, zoom in
ax . set_xlim ( SOLAR_BAND [ 0 ] , SOLAR_BAND [ 1 ] )
# Highlight visible light region
ax . axvspan ( 0.4 , 0.7 , alpha = 0.1 , color = ' yellow ' , label = ' Visible Light Region ' )
# Redraw legend to include visible light label
ax . legend ( title = ' Film Thickness ' , fontsize = 10 , title_fontsize = 11 , loc = ' upper right ' )
plt . tight_layout ( )
plt . savefig ( save_path , bbox_inches = ' tight ' )
print ( f " Solar absorption spectra plot saved to: { save_path } " )
# ------------------------------
# 5. 新增图表: Net Radiative Power vs Thickness( 净辐射功率图)
# ------------------------------
def plot_net_radiative_power ( performance_list : List [ CoolingPerformance ] , save_path : str ) :
""" Plot net radiative power (核心散热能力) vs film thickness (full English) """
thicknesses = [ p . thickness_um for p in performance_list ]
net_radiative_power = [ p . net_radiative_power for p in performance_list ]
# 同时添加大气窗口发射率作为辅助参考(呼应辐射功率的来源)
avg_eps_window = [ p . spectral_metric . avg_eps_window for p in performance_list ]
fig , ax1 = plt . subplots ( figsize = ( 10 , 6 ) )
# 左Y轴: 净辐射功率( 核心指标)
color1 = ' #1f77b4 ' # 深蓝色
ax1 . set_xlabel ( ' PDMS Film Thickness (μm) ' , fontsize = 12 )
ax1 . set_ylabel ( ' Net Radiative Power (W/m²) ' , fontsize = 12 , color = color1 )
line1 = ax1 . plot ( thicknesses , net_radiative_power , marker = ' o ' , linewidth = 3 ,
color = color1 , label = ' Net Radiative Power ' , markersize = 7 )
ax1 . tick_params ( axis = ' y ' , labelcolor = color1 )
ax1 . grid ( True , alpha = 0.3 )
# 调整Y轴范围, 确保所有数据点清晰
ax1 . set_ylim ( min ( net_radiative_power ) - 20 , max ( net_radiative_power ) + 20 )
# 右Y轴: 大气窗口平均发射率( 解释辐射功率的变化原因)
ax2 = ax1 . twinx ( )
color2 = ' #ff7f0e ' # 橙色
ax2 . set_ylabel ( ' Avg Emissivity (8-13μm) ' , fontsize = 12 , color = color2 )
line2 = ax2 . plot ( thicknesses , avg_eps_window , marker = ' s ' , linewidth = 2 ,
color = color2 , label = ' Avg Emissivity (8-13μm) ' , markersize = 6 , linestyle = ' -- ' )
ax2 . tick_params ( axis = ' y ' , labelcolor = color2 )
ax2 . set_ylim ( 0 , 1.0 )
# 合并图例
lines = line1 + line2
labels = [ l . get_label ( ) for l in lines ]
ax1 . legend ( lines , labels , loc = ' lower right ' , fontsize = 10 )
plt . title ( ' Net Radiative Power of PDMS Films vs Thickness ' , fontsize = 14 , fontweight = ' bold ' )
plt . tight_layout ( )
plt . savefig ( save_path , bbox_inches = ' tight ' )
print ( f " Net radiative power plot saved to: { save_path } " )
# ------------------------------
# 6. Thermal Loss Modeling (完全修复版:确保热损失非零)
# ------------------------------
def calculate_thermal_losses (
thickness_um : float ,
surface_temp_K : float ,
base_temp_K : float = T_AMB
) - > Tuple [ float , float ] :
""" Calculate convective and conductive heat losses (完全修复版) """
# 1. 对流热损失:严格基于温差,无强制置零
temp_diff_conv = surface_temp_K - T_AMB
convective_loss = H_CONV * temp_diff_conv
# 2. 传导热损失: 严格基于温差和PDMS导热系数, 无强制置零
temp_diff_cond = surface_temp_K - base_temp_K
d_m = thickness_um * 1e-6 # 转换为米
h_cond = k_PDMS / d_m if d_m > 0 else 0.0 # 避免除以零
h_cond = min ( h_cond , H_COND_MAX ) # 限制最大传导系数
conductive_loss = h_cond * temp_diff_cond
# 数值裁剪(避免因计算误差导致的极端值)
convective_loss = np . clip ( convective_loss , - 1000 , 1000 )
conductive_loss = np . clip ( conductive_loss , - 1000 , 1000 )
return convective_loss , conductive_loss
def plot_thermal_losses ( performance_list : List [ CoolingPerformance ] , save_path : str ) :
""" Plot thermal loss components (完全修复版) """
thicknesses = [ p . thickness_um for p in performance_list ]
convective = [ p . convective_loss for p in performance_list ]
conductive = [ p . conductive_loss for p in performance_list ]
solar_gain = [ p . solar_gain for p in performance_list ]
fig , ax = plt . subplots ( figsize = ( 10 , 6 ) )
x = np . arange ( len ( thicknesses ) )
width = 0.25
bars1 = ax . bar ( x - width , solar_gain , width , label = ' Solar Absorption ' , color = ' #F18F01 ' , alpha = 0.8 )
bars2 = ax . bar ( x , convective , width , label = ' Convective Loss ' , color = ' #2E86AB ' , alpha = 0.8 )
bars3 = ax . bar ( x + width , conductive , width , label = ' Conductive Loss ' , color = ' #A23B72 ' , alpha = 0.8 )
ax . set_xlabel ( ' PDMS Film Thickness (μm) ' , fontsize = 12 )
ax . set_ylabel ( ' Heat Flux Density (W/m²) ' , fontsize = 12 )
ax . set_title ( ' Thermal Loss Components of PDMS Films at Equilibrium Temperature ' , fontsize = 14 , fontweight = ' bold ' )
ax . set_xticks ( x )
ax . set_xticklabels ( thicknesses )
ax . legend ( fontsize = 10 )
ax . grid ( True , alpha = 0.3 , axis = ' y ' )
# 数值标签: 避免重叠, 保留1位小数
def add_labels ( bars ) :
for bar in bars :
height = bar . get_height ( )
va = ' bottom ' if height > = 0 else ' top '
y_offset = 1.0 if height > = 0 else - 1.0
ax . text ( bar . get_x ( ) + bar . get_width ( ) / 2. , height + y_offset ,
f ' { height : .1f } ' , ha = ' center ' , va = va , fontsize = 9 )
add_labels ( bars1 )
add_labels ( bars2 )
add_labels ( bars3 )
plt . tight_layout ( )
plt . savefig ( save_path , bbox_inches = ' tight ' )
print ( f " Thermal loss components plot saved to: { save_path } " )
# ------------------------------
# 7. Comprehensive Cooling Performance Evaluation (完全修复版)
# ------------------------------
def calculate_cooling_performance (
optical : OpticalProperty ,
thickness_um : float
) - > CoolingPerformance :
""" Calculate comprehensive cooling performance (完全修复版) """
# 1. 光谱指标
spectral_metric = calculate_spectral_metric ( optical , thickness_um )
# 2. 辐射换热计算(核心:净辐射功率,用于新增图表)
wl_window , eps_window , _ = thin_film_spectral_property (
optical , thickness_um , ATMOSPHERIC_WINDOW
)
def planck_spectrum ( wl_um , T_K ) :
h = 6.626e-34 # Planck constant (J·s)
c = 3e8 # Speed of light (m/s)
k = 1.38e-23 # Boltzmann constant (J/K)
wl_m = wl_um * 1e-6
return ( 2 * h * c * * 2 ) / ( wl_m * * 5 * ( np . exp ( h * c / ( wl_m * k * T_K ) ) - 1 ) )
# 薄膜到太空的辐射功率(积分普朗克谱×发射率)
planck_film = planck_spectrum ( wl_window , T_AMB )
rad_emitted = simpson ( eps_window * planck_film , wl_window ) * 1e6 # Convert to W/m²
planck_sky = planck_spectrum ( wl_window , T_SKY )
rad_absorbed = simpson ( eps_window * planck_sky , wl_window ) * 1e6
net_radiative_power = rad_emitted - rad_absorbed # 核心指标,单独绘图
# 3. 太阳吸收热流(固定值,与温度无关)
solar_gain = spectral_metric . avg_alpha_solar * SOLAR_IRR
# 4. 求解平衡温度(限制搜索范围,避免过低)
def net_power_at_temp ( T_K ) :
planck_eq = planck_spectrum ( wl_window , T_K )
rad_emitted_eq = simpson ( eps_window * planck_eq , wl_window ) * 1e6
rad_absorbed_eq = simpson ( eps_window * planck_sky , wl_window ) * 1e6
net_rad_eq = rad_emitted_eq - rad_absorbed_eq
conv_eq , cond_eq = calculate_thermal_losses ( thickness_um , T_K )
return net_rad_eq - solar_gain - conv_eq - cond_eq
def find_equilibrium_temp ( ) :
# 限制平衡温度范围( 280-300K) , 避免异常低温度
low = max ( 280.0 , T_AMB - MAX_TEMPERATURE_DIFF )
high = min ( 300.0 , T_AMB + 5.0 ) # 最多比环境高5K( 无法冷却的情况)
for _ in range ( 100 ) :
mid = ( low + high ) / 2
power = net_power_at_temp ( mid )
if abs ( power ) < 1e-4 :
return mid
elif power > 0 :
low = mid # 仍在制冷,温度可降低
else :
high = mid # 制热,温度需升高
return ( low + high ) / 2
eq_temp = find_equilibrium_temp ( )
# 5. 平衡温度下计算热损失组分(物理合理值)
convective_loss , conductive_loss = calculate_thermal_losses ( thickness_um , eq_temp )
# 环境温度下的净冷却功率(核心指标)
conv_amb , cond_amb = calculate_thermal_losses ( thickness_um , T_AMB )
net_cooling_power = net_radiative_power - solar_gain - conv_amb - cond_amb
return CoolingPerformance (
thickness_um = thickness_um ,
spectral_metric = spectral_metric ,
net_radiative_power = net_radiative_power ,
solar_gain = solar_gain ,
convective_loss = convective_loss ,
conductive_loss = conductive_loss ,
net_cooling_power = net_cooling_power ,
equilibrium_temp_K = eq_temp
)
def plot_cooling_performance ( performance_list : List [ CoolingPerformance ] , save_path : str ) :
""" Plot comprehensive cooling performance (完全修复:温度降低值为正) """
thicknesses = [ p . thickness_um for p in performance_list ]
net_cooling = [ p . net_cooling_power for p in performance_list ]
temp_drop = [ p . temp_drop_C for p in performance_list ]
fig , ax1 = plt . subplots ( figsize = ( 10 , 6 ) )
# Left axis: Net Cooling Power
color1 = ' #2E86AB '
ax1 . set_xlabel ( ' PDMS Film Thickness (μm) ' , fontsize = 12 )
ax1 . set_ylabel ( ' Net Cooling Power (W/m²) ' , fontsize = 12 , color = color1 )
line1 = ax1 . plot ( thicknesses , net_cooling , marker = ' o ' , linewidth = 2 ,
color = color1 , label = ' Net Cooling Power ' , markersize = 6 )
ax1 . tick_params ( axis = ' y ' , labelcolor = color1 )
ax1 . axhline ( y = 0 , color = ' black ' , linestyle = ' -- ' , alpha = 0.5 )
ax1 . grid ( True , alpha = 0.3 )
# 调整y轴范围, 使正功率更清晰
ax1 . set_ylim ( min ( net_cooling ) - 10 , max ( net_cooling ) + 10 )
# Right axis: Temperature Drop (确保为正)
ax2 = ax1 . twinx ( )
color2 = ' #A23B72 '
ax2 . set_ylabel ( ' Temperature Drop (°C) ' , fontsize = 12 , color = color2 )
line2 = ax2 . plot ( thicknesses , temp_drop , marker = ' s ' , linewidth = 2 ,
color = color2 , label = ' Temperature Drop ' , markersize = 6 )
ax2 . tick_params ( axis = ' y ' , labelcolor = color2 )
ax2 . set_ylim ( 0 , max ( temp_drop ) + 2 ) # y轴从0开始, 符合降温直觉
# Combine legends
lines = line1 + line2
labels = [ l . get_label ( ) for l in lines ]
ax1 . legend ( lines , labels , loc = ' upper right ' , fontsize = 10 )
plt . title ( ' Comprehensive Cooling Performance of PDMS Films vs Thickness ' , fontsize = 14 , fontweight = ' bold ' )
plt . tight_layout ( )
plt . savefig ( save_path , bbox_inches = ' tight ' )
print ( f " Cooling performance plot saved to: { save_path } " )
# ------------------------------
# 8. Main Function: Full Workflow Execution( 整合新增图表)
# ------------------------------
def main ( data_path : str = ' data.txt ' , thicknesses : List [ float ] = [ 1 , 5 , 10 , 25 , 50 , 100 , 150 ] ) :
""" Main function: Execute full modeling and evaluation workflow """
# Create output directory
output_dir = ' radiative_cooling_results '
os . makedirs ( output_dir , exist_ok = True )
try :
# 1. Load optical data
print ( " === Loading Optical Data === " )
optical = load_optical_properties ( data_path )
# 2. Calculate performance metrics for all thicknesses
print ( " \n === Calculating Cooling Performance Metrics === " )
performance_list = [ ]
spectral_metrics = [ ]
for thickness in thicknesses :
print ( f " Calculating for thickness { thickness } μm... " )
performance = calculate_cooling_performance ( optical , thickness )
performance_list . append ( performance )
spectral_metrics . append ( performance . spectral_metric )
# 3. Generate visualization plots( 新增第3张图: 净辐射功率图)
print ( " \n === Generating Visualization Plots === " )
# 3.1 光谱匹配度图
plot_spectral_metrics ( spectral_metrics ,
os . path . join ( output_dir , ' 1_spectral_metrics.png ' ) )
# 3.2 太阳吸收光谱图
plot_solar_absorption_spectra ( optical , thicknesses ,
os . path . join ( output_dir , ' 2_solar_absorption_spectra.png ' ) )
# 3.3 新增:净辐射功率图
plot_net_radiative_power ( performance_list ,
os . path . join ( output_dir , ' 3_net_radiative_power.png ' ) )
# 3.4 热损失组分图
plot_thermal_losses ( performance_list ,
os . path . join ( output_dir , ' 4_thermal_loss_components.png ' ) )
# 3.5 综合冷却性能图
plot_cooling_performance ( performance_list ,
os . path . join ( output_dir , ' 5_comprehensive_cooling_performance.png ' ) )
# 4. Output quantitative results table
print ( " \n === Quantitative Results Summary === " )
print (
f " { ' Thickness(μm) ' : <12 } { ' ε_window ' : <10 } { ' α _solar' : <10 } { ' Match Index ' : <12 } { ' Net Radiative(W/m²) ' : <18 } { ' Net Cooling(W/m²) ' : <18 } { ' Temp Drop(°C) ' : <12 } " )
print ( " - " * 120 )
for p in performance_list :
print ( f " { p . thickness_um : <12.1f } { p . spectral_metric . avg_eps_window : <10.4f } "
f " { p . spectral_metric . avg_alpha_solar : <10.4f } { p . spectral_metric . spectral_match_index : <12.2f } "
f " { p . net_radiative_power : <18.2f } { p . net_cooling_power : <18.2f } { p . temp_drop_C : <12.2f } " )
# 5. Save results to CSV( 新增净辐射功率列)
csv_path = os . path . join ( output_dir , ' cooling_performance_results.csv ' )
with open ( csv_path , ' w ' , encoding = ' utf-8 ' ) as f :
f . write (
" Thickness(μm),Avg_Emissivity_8-13μm,Avg_Absorptivity_0.3-2.5μm,Spectral_Match_Index,Net_Radiative_Power(W/m²),Solar_Gain(W/m²),Convective_Loss(W/m²),Conductive_Loss(W/m²),Net_Cooling_Power(W/m²),Equilibrium_Temp(°C),Temperature_Drop(°C) \n " )
for p in performance_list :
f . write ( f " { p . thickness_um : .1f } , "
f " { p . spectral_metric . avg_eps_window : .4f } , "
f " { p . spectral_metric . avg_alpha_solar : .4f } , "
f " { p . spectral_metric . spectral_match_index : .2f } , "
f " { p . net_radiative_power : .2f } , "
f " { p . solar_gain : .2f } , "
f " { p . convective_loss : .2f } , "
f " { p . conductive_loss : .2f } , "
f " { p . net_cooling_power : .2f } , "
f " { p . equilibrium_temp_C : .2f } , "
f " { p . temp_drop_C : .2f } \n " )
print ( f " \n Results saved to CSV file: { csv_path } " )
# 6. Output technical recommendations
print ( " \n === Technical Recommendations === " )
# Find optimal thickness based on spectral matching index and net cooling power
best_match_idx = np . argmax ( [ p . spectral_metric . spectral_match_index for p in performance_list ] )
best_cooling_idx = np . argmax ( [ p . net_cooling_power for p in performance_list ] )
best_radiative_idx = np . argmax ( [ p . net_radiative_power for p in performance_list ] ) # 新增:净辐射功率最优厚度
best_match_thickness = performance_list [ best_match_idx ] . thickness_um
best_cooling_thickness = performance_list [ best_cooling_idx ] . thickness_um
best_radiative_thickness = performance_list [ best_radiative_idx ] . thickness_um
print (
f " 1. Optimal thickness for spectral matching: { best_match_thickness } μm (Spectral Matching Index: { performance_list [ best_match_idx ] . spectral_metric . spectral_match_index : .2f } ) " )
print (
f " 2. Optimal thickness for net radiative power: { best_radiative_thickness } μm (Net Radiative Power: { performance_list [ best_radiative_idx ] . net_radiative_power : .2f } W/m²) " )
print (
f " 3. Optimal thickness for cooling power: { best_cooling_thickness } μm (Net Cooling Power: { performance_list [ best_cooling_idx ] . net_cooling_power : .2f } W/m²) " )
print (
f " 4. Recommended practical thickness: 25-50 μm (Balancing performance and cost, temperature drop: { performance_list [ 3 ] . temp_drop_C : .1f } - { performance_list [ 4 ] . temp_drop_C : .1f } °C) " )
print (
" 5. Material optimization direction: Reduce absorptivity in solar band (0.3-2.5μm), improve emissivity uniformity in atmospheric window (8-13μm) " )
print (
" 6. Engineering application suggestions: Optimize film-substrate interface design (e.g., add insulation layer) to reduce conductive loss; combine with shading structures to minimize solar absorption " )
except Exception as e :
print ( f " Error during execution: { e } " )
import traceback
traceback . print_exc ( )
# ------------------------------
# Execution Entry (Update your data file path)
# ------------------------------
if __name__ == " __main__ " :
# Configure data path and study thicknesses
DATA_PATH = " /Users/spasolreisa/IdeaProjects/asiaMath/data.txt " # Replace with your data.txt path
STUDY_THICKNESSES = [ 1 , 5 , 10 , 25 , 50 , 100 , 150 , 200 , 250 , 300 ] # Adjustable thickness range
main ( data_path = DATA_PATH , thicknesses = STUDY_THICKNESSES )