整合
This commit is contained in:
157
org/other/question2_pdms_cooling.py
Normal file
157
org/other/question2_pdms_cooling.py
Normal 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()
|
||||
Reference in New Issue
Block a user