This commit is contained in:
2025-11-22 18:08:14 +08:00
parent af9a0f6c3c
commit 634343a2ff
9 changed files with 1347 additions and 1 deletions

View File

@@ -0,0 +1,157 @@
import importlib.util
import math
import os
from dataclasses import dataclass
from typing import Dict, List, Tuple
import numpy as np
from matplotlib import pyplot as plt
plt.rcParams["font.sans-serif"] = ["DejaVu Sans", "Arial", "Helvetica"]
plt.rcParams["axes.unicode_minus"] = False
SIGMA = 5.670374419e-8
THICKNESSES = [1, 5, 10, 25, 50, 100] # µm
T_AMB = 300.0 # K (≈27 ℃)
T_SKY = 280.0 # Clear dry sky equivalent radiation temperature
SOLAR_IRR = 900.0 # W/m^2, clear sky noon
H_CONV = 8.0 # W/m^2/K, natural convection + light wind
def load_emissivity_module():
here = os.path.dirname(os.path.abspath(__file__))
target = os.path.join(here, "question1_pdms_emissivity.py")
spec = importlib.util.spec_from_file_location("q1", target)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module) # type: ignore[arg-type]
return module
def solar_absorptance(thickness_um: float) -> float:
"""
Empirical assumption: In PDMS silver-coated system, visible light absorption
is determined by thin film scattering and internal losses.
At 1 µm, α≈0.05, absorption increases by 0.01 for every 10 µm increase in thickness, capped at 0.15.
"""
return min(0.05 + 0.001 * thickness_um, 0.15)
@dataclass
class CoolingResult:
thickness_um: float
eps_window: float
alpha_solar: float
net_power_at_amb: float
eq_temp_K: float
@property
def eq_temp_C(self) -> float:
return self.eq_temp_K - 273.15
@property
def delta_T(self) -> float:
return self.eq_temp_K - T_AMB
def net_cooling_power(temp_K: float, emissivity: float, alpha_s: float) -> float:
radiative = emissivity * SIGMA * (temp_K**4 - T_SKY**4)
solar_gain = alpha_s * SOLAR_IRR
convective = H_CONV * (temp_K - T_AMB)
return -solar_gain - convective + radiative
def solve_equilibrium(emissivity: float, alpha_s: float) -> float:
low, high = 250.0, 330.0
f_low = net_cooling_power(low, emissivity, alpha_s)
f_high = net_cooling_power(high, emissivity, alpha_s)
if f_low * f_high > 0:
# No sign change, return endpoint with smaller energy consumption
return low if abs(f_low) < abs(f_high) else high
for _ in range(80):
mid = 0.5 * (low + high)
f_mid = net_cooling_power(mid, emissivity, alpha_s)
if abs(f_mid) < 1e-4:
return mid
if f_low * f_mid <= 0:
high, f_high = mid, f_mid
else:
low, f_low = mid, f_mid
return 0.5 * (low + high)
def evaluate() -> Tuple[List[CoolingResult], str]:
q1 = load_emissivity_module()
emissivity_data = q1.compute_emissivity(THICKNESSES)
results: List[CoolingResult] = []
for d in THICKNESSES:
eps_window = emissivity_data.window_avg[d]
alpha_s = solar_absorptance(d)
net_amb = net_cooling_power(T_AMB, eps_window, alpha_s)
eq_temp = solve_equilibrium(eps_window, alpha_s)
results.append(
CoolingResult(
thickness_um=d,
eps_window=eps_window,
alpha_solar=alpha_s,
net_power_at_amb=net_amb,
eq_temp_K=eq_temp,
)
)
outdir = os.path.join(os.path.dirname(__file__), "outputs")
os.makedirs(outdir, exist_ok=True)
csv_path = os.path.join(outdir, "question2_cooling_summary.csv")
with open(csv_path, "w", encoding="utf-8") as f:
f.write("thickness_um,eps_8_13,alpha_solar,net_power_amb_Wm2,eq_temp_C,delta_T_C\n")
for res in results:
f.write(
f"{res.thickness_um},{res.eps_window:.4f},{res.alpha_solar:.3f},"
f"{res.net_power_at_amb:.2f},{res.eq_temp_C:.2f},{res.delta_T:.2f}\n"
)
fig_path = os.path.join(outdir, "question2_cooling_results.png")
plot_results(results, fig_path)
return results, csv_path
def plot_results(results: List[CoolingResult], fig_path: str) -> None:
thickness = [r.thickness_um for r in results]
net_power = [r.net_power_at_amb for r in results]
delta_T = [r.delta_T for r in results]
fig, ax1 = plt.subplots(figsize=(9, 5))
ax1.bar(thickness, net_power, width=4, alpha=0.6, label="Net Cooling Power @T_amb")
ax1.set_xlabel("PDMS Film Thickness (µm)")
ax1.set_ylabel("Net Cooling Power (W/m²)")
ax1.axhline(0, color="black", linewidth=0.8)
ax2 = ax1.twinx()
ax2.plot(thickness, delta_T, color="tab:red", marker="o", label="Equilibrium Temperature Difference")
ax2.set_ylabel("Equilibrium Temperature Difference (K)")
lines, labels = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax1.legend(lines + lines2, labels + labels2, loc="upper right")
fig.tight_layout()
plt.savefig(fig_path, dpi=300)
plt.close(fig)
def main():
results, csv_path = evaluate()
print(f"Results written to: {csv_path}")
for r in results:
print(
f"d={r.thickness_um:>3} um, eps_8_13={r.eps_window:.2f}, alpha_sol={r.alpha_solar:.2f}, "
f"q_net(T_amb)={r.net_power_at_amb:.1f} W/m2, T_eq={r.eq_temp_C:.1f} °C "
f"(DeltaT={r.delta_T:.1f} K)"
)
if __name__ == "__main__":
main()