主题094:辐射换热在能源系统中的应用

摘要

辐射换热在能源系统中扮演着至关重要的角色,从传统的火力发电到新兴的太阳能利用技术,辐射传热机制贯穿于能源转换、传输和利用的全过程。本主题将系统介绍辐射换热在各类能源系统中的理论基础、数学模型和工程应用,重点探讨太阳能热发电、工业炉窑、燃烧室、核反应堆等典型系统中的辐射换热问题。通过Python仿真程序,我们将模拟太阳能集热器的热性能、炉膛内的辐射传热、高温气体的辐射特性以及能源系统的热效率优化,为理解辐射换热在能源领域的关键作用提供全面的数值实验平台。

关键词

辐射换热,能源系统,太阳能热发电,炉膛传热,燃烧辐射,高温气体,热效率优化,集热器,热管,斯特林发动机


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1. 引言

1.1 辐射换热在能源系统中的重要性

能源系统是现代社会运转的基础,而热能作为最主要的能源形式之一,其转换和利用效率直接影响着能源系统的整体性能。在所有传热方式中,辐射换热在高温能源系统中占据主导地位,因为辐射热流密度与温度的四次方成正比(q∝T4q \propto T^4qT4),在高温条件下辐射传热往往远超传导和对流。

在太阳能热利用领域,太阳辐射是唯一的能量来源。无论是聚光式太阳能发电(CSP)还是太阳能热水器,其核心都是如何高效地捕获太阳辐射能并将其转换为热能。太阳表面温度约5778K,其辐射主要集中在可见光和近红外波段(0.3-3μm),理解这一光谱特性对于设计高效的太阳能集热器至关重要。

在燃烧系统中,火焰温度可达2000K以上,此时辐射传热占总传热量的50-90%。工业炉窑、锅炉、燃气轮机等设备的性能很大程度上取决于对燃烧辐射的准确预测和控制。火焰中的二氧化碳、水蒸气、碳烟等组分都具有强烈的辐射吸收和发射能力,使得燃烧辐射成为一个复杂的多尺度、多物理场耦合问题。

在核能系统中,反应堆堆芯的温度控制和热量导出是确保安全运行的关键。高温下的辐射传热在燃料元件与冷却剂之间、以及堆芯结构内部都起着重要作用。特别是在事故工况下,辐射换热可能是唯一有效的热量传递机制。

1.2 能源系统中的典型辐射换热问题

能源系统中的辐射换热问题具有以下典型特征:

高温环境:能源系统通常涉及高温过程,温度范围从几百K(太阳能集热器)到几千K(燃烧室、核反应堆)。在如此高的温度下,辐射传热成为主导机制。

参与性介质:许多能源系统涉及参与性介质(participating media),如燃烧产物(CO₂、H₂O、碳烟)、等离子体、高温气体等。这些介质既吸收又发射辐射,使得辐射传输问题变得复杂。

复杂几何:能源设备往往具有复杂的几何结构,如炉膛内的管束、太阳能集热器的曲面反射镜、核燃料棒的栅格排列等。这些复杂几何对辐射换热的计算提出了挑战。

光谱依赖性:不同材料对辐射的吸收和发射具有强烈的光谱选择性。例如,太阳能选择性吸收涂层在可见光波段高吸收、在红外波段低发射,这是提高集热效率的关键。

瞬态特性:许多能源系统涉及瞬态过程,如太阳能的日变化、燃烧的不稳定性、反应堆的功率调节等。这要求辐射换热模型能够处理非稳态问题。

1.3 本主题的研究内容

本主题将系统研究辐射换热在能源系统中的应用,主要内容包括:

  1. 太阳能热发电系统:介绍槽式、塔式、碟式三种主要CSP技术,分析集热器的热性能,探讨光谱选择性吸收涂层的设计原理。

  2. 工业炉窑与锅炉:建立炉膛辐射换热的数学模型,分析火焰辐射特性,讨论如何提高炉膛热效率。

  3. 燃烧室辐射传热:研究高温燃烧气体的辐射特性,建立燃烧辐射模型,分析碳烟辐射的影响。

  4. 核反应堆热工:介绍反应堆内的辐射传热机制,分析燃料元件的温度分布,讨论事故工况下的热分析。

  5. 斯特林发动机与热管:探讨辐射换热在热机循环和热管传热中的作用,分析热效率优化策略。

  6. 能源系统优化:通过数值模拟优化能源系统的热性能,包括集热器几何优化、炉膛结构优化、热回收系统设计等。


2. 太阳能热发电系统

2.1 聚光式太阳能发电技术

聚光式太阳能发电(Concentrated Solar Power, CSP)利用反射镜将大面积的太阳光集中到一个小区域,产生高温热能驱动热机发电。根据聚光方式的不同,CSP技术主要分为三类:

槽式系统(Parabolic Trough)

  • 使用抛物线形反射镜将阳光聚焦到位于焦线的真空集热管上
  • 聚光比通常为10-80,集热管温度可达400°C
  • 技术成熟,是目前商业化程度最高的CSP技术
  • 代表电站:美国SEGS系列、西班牙Andasol电站

塔式系统(Solar Power Tower)

  • 使用大量定日镜将阳光反射到中央接收塔顶部
  • 聚光比可达300-1000,接收器温度可达500-1000°C
  • 热效率高,储能能力强
  • 代表电站:美国Ivanpah、摩洛哥Noor Ouarzazate

碟式系统(Dish-Stirling)

  • 使用抛物面碟将阳光聚焦到位于焦点的斯特林发动机上
  • 聚光比最高,可达1000-3000,工作温度可达700-1200°C
  • 热效率最高(可达30%),但规模较小
  • 适合分布式应用

2.2 太阳辐射特性

太阳可近似为温度为Tsun=5778T_{sun} = 5778Tsun=5778 K的黑体,其辐射遵循Planck定律:

Eb,λ(Tsun)=2πhc2λ51exp⁡(hc/λkBTsun)−1E_{b,\lambda}(T_{sun}) = \frac{2\pi h c^2}{\lambda^5} \frac{1}{\exp(hc/\lambda k_B T_{sun}) - 1}Eb,λ(Tsun)=λ52πhc2exp(hc/λkBTsun)11

太阳常数(地球大气层外的太阳辐射通量)为Gsc=1361G_{sc} = 1361Gsc=1361 W/m²。考虑到大气吸收和散射,到达地面的太阳辐射(直射辐射)通常在700-1000 W/m²之间。

太阳辐射的光谱分布对集热器设计至关重要。聚光集热器主要利用直射辐射(DNI, Direct Normal Irradiance),而非聚光集热器可以利用直射和散射辐射。

2.3 集热器热性能分析

集热器的热性能通常用集热效率来表征:

ηcollector=QusefulAaperture⋅GDNI\eta_{collector} = \frac{Q_{useful}}{A_{aperture} \cdot G_{DNI}}ηcollector=AapertureGDNIQuseful

其中有用热功率为:

Quseful=m˙cp(Tout−Tin)Q_{useful} = \dot{m} c_p (T_{out} - T_{in})Quseful=m˙cp(ToutTin)

集热器的热损失主要包括:

对流损失qconv=hconv(Tsurface−Tambient)q_{conv} = h_{conv} (T_{surface} - T_{ambient})qconv=hconv(TsurfaceTambient)

辐射损失qrad=ϵσ(Tsurface4−Tambient4)q_{rad} = \epsilon \sigma (T_{surface}^4 - T_{ambient}^4)qrad=ϵσ(Tsurface4Tambient4)

对于真空集热管,对流损失可以忽略,辐射损失成为主要热损失。

集热效率随工作温度升高而下降,因为热损失与温度的四次方成正比。选择性吸收涂层可以显著降低辐射损失。

2.4 选择性吸收涂层

理想的选择性吸收涂层应具有以下光谱特性:

  • 短波高吸收αsolar≈0.9−0.95\alpha_{solar} \approx 0.9-0.95αsolar0.90.95):高效吸收太阳辐射(0.3-3μm)
  • 长波低发射ϵthermal≈0.05−0.1\epsilon_{thermal} \approx 0.05-0.1ϵthermal0.050.1):减少红外辐射损失(>3μm)

常用的选择性吸收涂层包括:

金属-介质复合涂层:如TiNOx、Mo-Al₂O₃等,利用金属纳米颗粒的表面等离子体共振实现选择性吸收。

半导体-金属 tandem 结构:如Si/Ag、Ge/Ag等,半导体吸收短波,金属反射长波。

多层干涉涂层:利用薄膜干涉原理,设计特定厚度的多层膜系实现光谱选择性。

选择性吸收涂层的性能用选择性比α/ϵ\alpha/\epsilonα/ϵ来评价,高质量涂层的选择性比可达10-20。

2.5 聚光光学设计

聚光器的光学性能用聚光比(Concentration Ratio)来表征:

C=AapertureAreceiverC = \frac{A_{aperture}}{A_{receiver}}C=AreceiverAaperture

几何聚光比与最大可能工作温度相关。根据热力学第二定律,聚光系统的最大理论效率为:

ηmax=1−TambientTreceiver\eta_{max} = 1 - \frac{T_{ambient}}{T_{receiver}}ηmax=1TreceiverTambient

对于理想的聚光系统,接收器温度与聚光比的关系为:

Treceiver,max=TsunC⋅ηopticalCmax4T_{receiver,max} = T_{sun} \sqrt[4]{\frac{C \cdot \eta_{optical}}{C_{max}}}Treceiver,max=Tsun4CmaxCηoptical

其中Cmax=1/sin⁡2(θsun)≈46200C_{max} = 1/\sin^2(\theta_{sun}) \approx 46200Cmax=1/sin2(θsun)46200是最大可能聚光比(对应太阳张角)。

实际聚光器的光学效率受到多种因素影响:

  • 反射镜反射率(通常90-95%)
  • 跟踪精度(影响截断效率)
  • 几何光学误差(镜面形状误差、安装误差)
  • 大气衰减

3. 工业炉窑与锅炉

3.1 炉膛辐射换热基础

工业炉窑和锅炉是能源消耗大户,其热效率直接影响工业生产的能耗水平。炉膛内的传热以辐射为主,特别是在高温燃烧区。

炉膛辐射换热的复杂性主要来自:

非均匀温度场:炉膛内温度分布不均匀,从燃烧器附近的最高温度到出口处的较低温度,温度梯度很大。

参与性介质:燃烧产物(CO₂、H₂O、SO₂等)和悬浮的碳烟颗粒吸收和发射辐射,使得炉膛内的辐射传输成为一个体积过程。

复杂几何:炉膛内有复杂的管束结构(锅炉)、工件装载(热处理炉)等,这些表面对辐射的吸收、反射和散射改变了辐射场的分布。

非灰体特性:实际表面和介质的辐射特性随波长变化,不能简单地用灰体近似。

3.2 火焰辐射特性

火焰辐射是炉膛辐射换热的核心。火焰辐射主要来自:

气体辐射

  • CO₂和H₂O是三原子分子,具有强烈的红外辐射能力
  • 主要辐射波段:CO₂在2.7μm和4.3μm,H₂O在2.7μm和6.3μm
  • 气体辐射是体积过程,与气体温度、浓度、压力和气层厚度有关

碳烟辐射

  • 碳烟是碳氢化合物不完全燃烧产生的微小碳颗粒(直径10-100nm)
  • 碳烟在可见光和红外波段都有强吸收和发射
  • 碳烟浓度和粒径分布对火焰辐射特性影响显著

颗粒辐射

  • 煤粉燃烧产生的飞灰颗粒
  • 液雾燃烧产生的液滴
  • 这些颗粒对辐射有散射和吸收作用

3.3 气体辐射模型

气体辐射的计算比固体表面复杂,因为气体是参与性介质。常用的气体辐射模型包括:

窄谱带模型(Narrow Band Model)
将光谱分成许多窄带,在每个窄带内假设气体辐射特性近似恒定。常用的有Elsasser模型和统计模型。

宽谱带模型(Wide Band Model)
将光谱分成几个宽的吸收带,每个带用指数衰减函数描述。计算效率较高,适用于工程计算。

全谱k分布模型(FSK, Full Spectrum k-distribution)
将光谱重新排列,使得具有相同吸收系数的波数归为一类,大大减少了计算量同时保持了精度。

灰气体加权和模型(WSGGM, Weighted Sum of Gray Gases Model)
将实际气体等效为几种灰气体的加权和,每种灰气体有恒定的吸收系数和权重。这是工程计算中最常用的简化模型。

WSGGM中气体的发射率表示为:

εg=∑i=0nai(Tg)[1−exp⁡(−kipL)]\varepsilon_g = \sum_{i=0}^{n} a_i(T_g) \left[1 - \exp(-k_i p L)\right]εg=i=0nai(Tg)[1exp(kipL)]

其中aia_iai是权重系数,kik_iki是灰气体吸收系数,ppp是气体分压,LLL是平均射线程长。

3.4 炉膛热效率优化

提高炉膛热效率的途径包括:

优化燃烧

  • 保证充分燃烧,减少化学不完全燃烧损失
  • 控制过量空气系数,减少排烟热损失
  • 优化燃烧器设计,提高火焰充满度

增强辐射换热

  • 提高炉膛温度(在材料允许范围内)
  • 增加炉膛黑度(如使用高发射率涂料)
  • 优化炉膛几何,增加角系数

余热回收

  • 空气预热器回收烟气余热
  • 废热锅炉产生蒸汽
  • 有机朗肯循环发电

保温隔热

  • 使用高性能耐火材料
  • 优化炉墙结构,减少散热损失

4. 燃烧室辐射传热

4.1 燃烧室辐射特性

燃烧室是燃气轮机、航空发动机、火箭发动机等设备的核心部件,其内部的辐射传热对壁面热负荷和燃烧稳定性有重要影响。

燃烧室辐射的特点:

高温高压环境:燃气轮机燃烧室温度可达2000-2500K,压力可达10-40atm。高压增强了气体辐射能力。

湍流燃烧:湍流混合和化学反应的相互作用产生复杂的温度和组分分布,影响辐射场。

非平衡辐射:在超音速燃烧或稀薄气体条件下,热力学非平衡效应显著。

辐射-湍流-化学反应相互作用:辐射传热影响温度分布,进而影响化学反应速率和湍流结构,形成多物理场耦合。

4.2 碳烟辐射模型

碳烟是碳氢化合物燃料不完全燃烧的产物,对燃烧室辐射有重要贡献。碳烟辐射建模包括:

碳烟生成模型

  • 经验模型:基于实验数据的相关式
  • 半经验模型:如Moss-Brookes模型
  • 详细机理模型:基于PAH(多环芳烃)化学动力学

碳烟光学特性
碳烟颗粒的辐射特性可以用Mie理论或Rayleigh近似计算。对于小颗粒(d<<λd << \lambdad<<λ),消光效率为:

Qext=8π3d3λIm{m2−1m2+2}Q_{ext} = \frac{8\pi^3 d^3}{\lambda} \text{Im}\left\{\frac{m^2-1}{m^2+2}\right\}Qext=λ8π3d3Im{m2+2m21}

其中mmm是碳烟的复折射率,通常取m=1.57−0.56im = 1.57 - 0.56im=1.570.56i

碳烟辐射计算
碳烟体积分数fvf_vfv与辐射特性相关:

κsoot=C0fvλ\kappa_{soot} = C_0 \frac{f_v}{\lambda}κsoot=C0λfv

其中C0C_0C0是常数,与碳烟光学特性有关。

4.3 辐射传热对燃烧的影响

辐射传热对燃烧过程有多方面影响:

火焰稳定

  • 辐射散热降低火焰温度,影响点火和熄火
  • 壁面辐射反馈可以预热未燃混合气

污染物生成

  • 温度降低有利于减少NOx生成
  • 碳烟辐射散热影响碳烟氧化

热负荷

  • 辐射是燃烧室壁面热负荷的主要来源
  • 准确的辐射预测对冷却设计至关重要

燃烧效率

  • 辐射损失降低燃烧效率
  • 在大型燃烧室中,辐射损失可达总热量的5-10%

5. 核反应堆热工

5.1 反应堆内的辐射传热

核反应堆中,辐射传热在多个环节发挥作用:

燃料元件内部

  • 核燃料(UO₂)的热导率较低,中心温度很高
  • 燃料芯块与包壳之间的气隙传热包括辐射分量
  • 高温下辐射传热显著

堆芯结构

  • 控制棒、结构件之间的辐射换热
  • 在冷却剂流失事故(LOCA)中,辐射是主要传热机制

安全壳

  • 严重事故下,熔融物与混凝土的反应产生高温
  • 辐射传热是安全壳热分析的重要部分

5.2 燃料元件温度分布

燃料元件的温度分布对反应堆安全至关重要。对于圆柱形燃料棒,温度分布满足:

1rddr(rkfdTdr)+q′′′=0\frac{1}{r}\frac{d}{dr}\left(r k_f \frac{dT}{dr}\right) + q''' = 0r1drd(rkfdrdT)+q′′′=0

其中q′′′q'''q′′′是体积热源(由核裂变产生),kfk_fkf是燃料热导率。

边界条件:

  • 中心对称:dT/dr∣r=0=0dT/dr|_{r=0} = 0dT/drr=0=0
  • 表面:−kfdT/dr∣r=R=qsurface′′-k_f dT/dr|_{r=R} = q''_{surface}kfdT/drr=R=qsurface′′

燃料中心最高温度必须低于燃料熔点(UO₂约2800°C),这是反应堆设计的重要约束。

5.3 事故工况分析

在反应堆事故工况下,辐射传热尤为重要:

失水事故(LOCA)

  • 冷却剂流失后,燃料棒温度急剧上升
  • 燃料包壳与蒸汽之间的辐射传热成为主要散热机制
  • 包壳温度升高可能导致锆水反应

熔融物冷却

  • 严重事故下,堆芯熔融物落入下封头
  • 熔融物与冷却水之间的辐射和沸腾传热决定是否能保持容器完整性

氢气风险

  • 锆水反应产生氢气
  • 氢气燃烧或爆炸是安全壳失效的重要风险

6. 斯特林发动机与热管

6.1 斯特林发动机原理

斯特林发动机是一种外燃式热机,通过气体工质(通常是氦气或氢气)的周期性压缩和膨胀实现热能向机械能的转换。

斯特林循环由四个过程组成:

  1. 等温压缩:工质在冷端被压缩,热量QCQ_CQC排出
  2. 等容加热:工质通过回热器被加热
  3. 等温膨胀:工质在热端膨胀,吸收热量QHQ_HQH并对外做功
  4. 等容冷却:工质通过回热器被冷却

理想斯特林循环的热效率为卡诺效率:

ηCarnot=1−TCTH\eta_{Carnot} = 1 - \frac{T_C}{T_H}ηCarnot=1THTC

实际斯特林发动机由于各种损失(传热损失、流动损失、密封损失等),实际效率通常为卡诺效率的30-50%。

6.2 斯特林发动机中的辐射换热

在太阳能斯特林系统中,辐射换热在接收器设计中起关键作用:

腔式接收器

  • 入射辐射在腔体内多次反射,提高吸收率
  • 腔体效应使得实际吸收率接近黑体
  • 腔体开口大小影响光学效率和热损失的平衡

热损失控制

  • 高温接收器的主要热损失是辐射
  • 选择性吸收涂层和透明隔热罩可以减少损失
  • 真空隔热是高温接收器的关键技术

6.3 热管工作原理

热管是一种高效的两相传热器件,利用工质的蒸发和冷凝实现热量的快速传递。

热管由三部分组成:

  1. 蒸发段:工质吸收热量蒸发
  2. 绝热段:蒸汽流动(通常有绝热层)
  3. 冷凝段:蒸汽冷凝释放热量

热管的等效热导率可达铜的数百倍,被誉为"热的超导体"。

6.4 热管中的辐射传热

在高温热管(如碱金属热管用于核反应堆冷却)中,辐射传热不可忽视:

蒸发段

  • 热源与热管外壁之间的辐射换热
  • 在核反应堆应用中,燃料棒与热管之间的辐射是主要传热机制

冷凝段

  • 热管与散热器之间的辐射换热
  • 在空间应用中,热管向太空的辐射散热

内部辐射

  • 高温下,蒸汽和液膜之间的辐射换热
  • 对热管传热极限有影响

7. 能源系统优化设计

7.1 集热器几何优化

太阳能集热器的几何设计直接影响光学效率和热效率:

抛物槽优化

  • 开口宽度与焦距的比值(W/fW/fW/f)影响聚光比和接收角
  • 最优W/fW/fW/f通常在2-3之间
  • 边缘角(rim angle)影响光学效率和拦截效率的平衡

定日镜场布局

  • 塔式系统的定日镜场布局影响土地利用率、阴影遮挡和大气衰减
  • 螺旋式、径向交错式等布局各有优缺点
  • 优化目标包括最大化年发电量、最小化平准化电力成本(LCOE)

接收器设计

  • 外部接收器 vs 腔式接收器
  • 管径、管间距、流动布置的优化
  • 热应力分析和寿命预测

7.2 炉膛结构优化

炉膛结构优化旨在提高热效率、改善温度均匀性、降低污染物排放:

燃烧器布置

  • 燃烧器位置、角度、数量的优化
  • 分级燃烧降低NOx
  • 富氧燃烧提高火焰温度

炉膛几何

  • 炉膛形状影响火焰充满度和辐射角系数
  • 冷壁面(如水冷壁)的布置影响热吸收
  • 出口位置和形状影响烟气流动和传热

受热面布置

  • 管束的节距、排列方式(顺排/叉排)
  • 吹灰系统的布置
  • 防结渣、防腐蚀设计

7.3 热回收系统设计

余热回收是提高能源系统效率的重要手段:

换热器设计

  • 类型选择:管壳式、板式、回转式等
  • 传热面积和流动布置优化
  • 考虑积灰、腐蚀、磨损等因素

有机朗肯循环(ORC)

  • 利用中低温余热发电
  • 工质选择(R245fa、Pentane等)
  • 蒸发温度、冷凝温度的优化

热电联产(CHP)

  • 同时生产电力和热能
  • 总能效可达80%以上
  • 适用于工业过程和区域供热

8. Python仿真程序设计

8.1 程序架构

本主题的Python仿真程序包含以下模块:

  1. 太阳辐射模块:计算太阳位置、大气衰减、集热器光学效率
  2. 集热器模块:模拟槽式、塔式集热器的热性能
  3. 炉膛模块:计算炉膛内的辐射传热和燃烧
  4. 燃烧室模块:模拟高温燃烧气体的辐射特性
  5. 优化模块:实现集热器和炉膛的几何优化
  6. 可视化模块:绘制温度场、热流分布、效率曲线等

8.2 仿真案例设计

程序包含以下仿真案例:

案例1:槽式集热器性能分析

  • 计算不同工作温度下的集热效率
  • 分析热损失组成(对流、辐射)
  • 优化选择性吸收涂层参数

案例2:定日镜场光学模拟

  • 模拟定日镜场的聚光效果
  • 计算接收器上的能流分布
  • 分析阴影和遮挡损失

案例3:炉膛辐射传热

  • 建立简化炉膛模型
  • 计算气体和壁面之间的辐射换热
  • 分析炉膛热效率

案例4:燃烧气体辐射特性

  • 计算CO₂和H₂O的辐射特性
  • 分析温度、压力、气层厚度的影响
  • 对比不同辐射模型

案例5:斯特林发动机循环分析

  • 模拟理想斯特林循环
  • 分析各种损失对效率的影响
  • 优化工作参数

案例6:能源系统综合优化

  • 多目标优化(效率、成本、环境影响)
  • 敏感性分析
  • 帕累托前沿分析

8.3 代码实现要点

数值方法

  • 蒙特卡洛方法模拟辐射传输
  • 有限体积法求解能量方程
  • 优化算法(遗传算法、粒子群优化)

物理模型

  • 太阳辐射模型(ASHRAE、Bird模型)
  • 气体辐射模型(WSGGM、窄谱带模型)
  • 表面辐射模型(角系数计算)

计算效率

  • 向量化运算
  • 并行计算(多线程、GPU加速)
  • 自适应网格

附录:Python代码

完整的Python仿真程序见同目录下的 run_simulation.py 文件。程序包含上述所有案例的实现,可直接运行生成仿真结果。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
主题094:辐射换热在能源系统中的应用
Python仿真程序

本程序模拟辐射换热在各类能源系统中的应用,包括:
1. 槽式集热器性能分析
2. 定日镜场光学模拟
3. 炉膛辐射传热
4. 燃烧气体辐射特性
5. 斯特林发动机循环分析
6. 能源系统综合优化
"""

import numpy as np
import matplotlib
matplotlib.use('Agg')  # 使用非交互式后端
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, Rectangle, FancyBboxPatch, Polygon, Arc
from matplotlib.collections import PatchCollection
import matplotlib.patches as mpatches
from scipy.integrate import quad, odeint, solve_ivp
from scipy.interpolate import interp1d, griddata
from scipy.optimize import minimize_scalar, minimize, differential_evolution
from scipy.special import j0, j1, erf
import warnings
warnings.filterwarnings('ignore')

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

# 物理常数
sigma = 5.670374419e-8  # Stefan-Boltzmann常数 [W/(m²·K⁴)]
h_planck = 6.62607015e-34  # Planck常数 [J·s]
c_light = 2.99792458e8  # 光速 [m/s]
k_B = 1.380649e-23  # Boltzmann常数 [J/K]

# =============================================================================
# 第一部分:太阳辐射模块
# =============================================================================

class SolarRadiation:
    """太阳辐射计算类"""
    
    def __init__(self):
        self.T_sun = 5778  # 太阳表面温度 [K]
        self.R_sun = 6.96e8  # 太阳半径 [m]
        self.D_earth_sun = 1.496e11  # 日地平均距离 [m]
        self.G_sc = 1361  # 太阳常数 [W/m²]
        
    def planck_distribution(self, wavelength, T):
        """
        计算Planck黑体辐射分布
        
        参数:
            wavelength: 波长 [m] 或 [μm]
            T: 温度 [K]
        返回:
            光谱辐射力 [W/(m²·m)] 或 [W/(m²·μm)]
        """
        # 如果波长以μm输入,转换为m
        if np.max(wavelength) < 1e-3:
            lam = wavelength
            unit_factor = 1.0
        else:
            lam = wavelength * 1e-6
            unit_factor = 1e-6
            
        # Planck定律
        c1 = 2 * np.pi * h_planck * c_light**2  # 第一辐射常数
        c2 = h_planck * c_light / k_B  # hc/k [m·K]
        
        E = c1 / (lam**5 * (np.exp(c2 / (lam * T)) - 1))
        return E * unit_factor
    
    def solar_spectrum(self, wavelength):
        """太阳辐射光谱分布"""
        return self.planck_distribution(wavelength, self.T_sun)
    
    def atmospheric_transmittance(self, wavelength, air_mass=1.5):
        """
        简化的大气透过率模型(基于Bird模型简化)
        
        参数:
            wavelength: 波长 [μm]
            air_mass: 大气质量数
        返回:
            透过率 [-]
        """
        # 简化模型:考虑主要吸收带
        tau = np.ones_like(wavelength)
        
        # 臭氧吸收(紫外-可见)
        tau_o3 = np.exp(-0.1 * air_mass * np.exp(-((wavelength - 0.6)/0.3)**2))
        
        # 水汽吸收(近红外)
        tau_h2o = np.exp(-0.3 * air_mass * (
            np.exp(-((wavelength - 0.94)/0.1)**2) +
            np.exp(-((wavelength - 1.13)/0.1)**2) +
            np.exp(-((wavelength - 1.38)/0.15)**2)
        ))
        
        # 散射(瑞利散射 + 米散射)
        tau_rayleigh = np.exp(-0.1 * air_mass / (wavelength**4 + 0.01))
        
        tau = tau_o3 * tau_h2o * tau_rayleigh
        return tau
    
    def direct_normal_irradiance(self, wavelength, air_mass=1.5):
        """
        计算直射辐射光谱
        
        参数:
            wavelength: 波长 [μm]
            air_mass: 大气质量数
        返回:
            DNI光谱 [W/(m²·μm)]
        """
        G_extraterrestrial = self.solar_spectrum(wavelength)
        tau_atm = self.atmospheric_transmittance(wavelength, air_mass)
        
        # 日地距离修正(简化)
        distance_factor = (self.R_sun / self.D_earth_sun)**2
        
        return G_extraterrestrial * tau_atm * distance_factor
    
    def total_dni(self, air_mass=1.5):
        """计算总DNI(积分整个光谱)"""
        wavelengths = np.linspace(0.3, 3.0, 1000)  # 0.3-3.0 μm
        dni_spectrum = self.direct_normal_irradiance(wavelengths, air_mass)
        dni_total = np.trapezoid(dni_spectrum, wavelengths)
        return dni_total


# =============================================================================
# 第二部分:集热器模块
# =============================================================================

class SelectiveCoating:
    """选择性吸收涂层模型"""
    
    def __init__(self, alpha_solar=0.95, epsilon_thermal=0.10):
        """
        初始化选择性涂层
        
        参数:
            alpha_solar: 太阳吸收率 [-]
            epsilon_thermal: 热发射率 [-]
        """
        self.alpha_solar = alpha_solar
        self.epsilon_thermal = epsilon_thermal
        self.selectivity = alpha_solar / epsilon_thermal
        
    def spectral_absorptance(self, wavelength):
        """
        光谱吸收率分布(简化模型)
        
        参数:
            wavelength: 波长 [μm]
        返回:
            光谱吸收率 [-]
        """
        # 简化模型:短波高吸收,长波低吸收
        # 过渡波长设为2.5 μm
        lam = np.atleast_1d(wavelength)
        alpha = np.where(lam < 2.5, 
                        self.alpha_solar,
                        self.epsilon_thermal + 
                        (self.alpha_solar - self.epsilon_thermal) * 
                        np.exp(-(lam - 2.5)**2 / 0.5))
        return alpha
    
    def spectral_emissivity(self, wavelength, T):
        """
        光谱发射率(根据Kirchhoff定律,等于吸收率)
        
        参数:
            wavelength: 波长 [μm]
            T: 温度 [K]
        返回:
            光谱发射率 [-]
        """
        return self.spectral_absorptance(wavelength)
    
    def total_emissivity(self, T):
        """
        计算总发射率(温度相关)
        
        参数:
            T: 温度 [K]
        返回:
            总发射率 [-]
        """
        # 简化:发射率随温度略有增加
        epsilon = self.epsilon_thermal * (1 + 0.0002 * (T - 300))
        return min(epsilon, 1.0)


class ParabolicTroughCollector:
    """抛物槽式集热器模型"""
    
    def __init__(self, 
                 aperture_width=5.0,  # 开口宽度 [m]
                 focal_length=1.5,    # 焦距 [m]
                 length=100.0,        # 集热器长度 [m]
                 receiver_diameter=0.07,  # 接收管外径 [m]
                 coating=None,        # 选择性涂层
                 reflectance=0.93,    # 反射镜反射率
                 intercept_factor=0.95):  # 拦截因子
        """
        初始化抛物槽集热器
        """
        self.W = aperture_width
        self.f = focal_length
        self.L = length
        self.D_receiver = receiver_diameter
        self.coating = coating if coating else SelectiveCoating()
        self.rho_mirror = reflectance
        self.gamma_intercept = intercept_factor
        
        # 计算几何参数
        self.rim_angle = 2 * np.arctan(self.W / (4 * self.f))
        self.concentration_ratio = self.W / (np.pi * self.D_receiver)
        
    def optical_efficiency(self, incident_angle=0):
        """
        计算光学效率
        
        参数:
            incident_angle: 入射角 [rad]
        返回:
            光学效率 [-]
        """
        # 余弦损失
        cos_factor = np.cos(incident_angle)
        
        # 光学效率 = 反射率 × 拦截因子 × 余弦因子 × 吸收率
        eta_optical = (self.rho_mirror * 
                      self.gamma_intercept * 
                      cos_factor * 
                      self.coating.alpha_solar)
        
        return eta_optical
    
    def heat_loss(self, T_receiver, T_ambient, wind_speed=2.0):
        """
        计算热损失
        
        参数:
            T_receiver: 接收管温度 [K]
            T_ambient: 环境温度 [K]
            wind_speed: 风速 [m/s]
        返回:
            热损失 [W/m]
        """
        # 接收管周长
        perimeter = np.pi * self.D_receiver
        
        # 对流换热系数(简化关联式)
        h_conv = 5.0 + 2.5 * wind_speed  # [W/(m²·K)]
        
        # 对流热损失
        q_conv = h_conv * (T_receiver - T_ambient)  # [W/m²]
        
        # 辐射热损失
        epsilon = self.coating.total_emissivity(T_receiver)
        q_rad = epsilon * sigma * (T_receiver**4 - T_ambient**4)  # [W/m²]
        
        # 总热损失(单位长度)
        q_loss = (q_conv + q_rad) * perimeter  # [W/m]
        
        return q_loss, q_conv * perimeter, q_rad * perimeter
    
    def thermal_efficiency(self, T_in, T_out, T_ambient, DNI, 
                          mass_flow_rate, wind_speed=2.0, incident_angle=0):
        """
        计算集热效率
        
        参数:
            T_in: 进口温度 [K]
            T_out: 出口温度 [K]
            T_ambient: 环境温度 [K]
            DNI: 直射辐射 [W/m²]
            mass_flow_rate: 质量流量 [kg/s]
            wind_speed: 风速 [m/s]
            incident_angle: 入射角 [rad]
        返回:
            效率字典
        """
        # 平均工作温度
        T_avg = (T_in + T_out) / 2
        
        # 入射太阳能
        Q_incident = DNI * self.W * self.L * np.cos(incident_angle)
        
        # 光学效率
        eta_optical = self.optical_efficiency(incident_angle)
        
        # 热损失
        q_loss_total, q_conv, q_rad = self.heat_loss(T_avg, T_ambient, wind_speed)
        Q_loss = q_loss_total * self.L
        
        # 计算有用热功率(光学收益 - 热损失)
        Q_absorbed = Q_incident * eta_optical  # 吸收的太阳辐射
        Q_useful = Q_absorbed - Q_loss  # 有用热功率
        
        # 确保有用功率不为负
        if Q_useful < 0:
            Q_useful = 0
        
        # 集热效率
        eta_thermal = Q_useful / Q_incident
        
        return {
            'eta_thermal': eta_thermal,
            'eta_optical': eta_optical,
            'eta_net': eta_thermal,  # 净效率等于热效率
            'Q_useful': Q_useful,
            'Q_incident': Q_incident,
            'Q_loss': Q_loss,
            'q_conv': q_conv * self.L,
            'q_rad': q_rad * self.L
        }


# =============================================================================
# 第三部分:炉膛辐射模块
# =============================================================================

class GasRadiation:
    """气体辐射模型(WSGGM简化模型)"""
    
    def __init__(self):
        # 灰气体参数(简化)
        self.k_gray = [0.0, 0.5, 5.0, 50.0]  # 吸收系数 [1/(m·atm)]
        self.a_coeff = [
            [0.3, 0.4, 0.2, 0.1],  # 300K
            [0.25, 0.45, 0.22, 0.08],  # 1000K
            [0.2, 0.5, 0.22, 0.08],  # 1500K
            [0.15, 0.55, 0.22, 0.08]   # 2000K
        ]
        self.T_ref = [300, 1000, 1500, 2000]
        
    def get_weights(self, T):
        """获取温度相关的权重系数"""
        if T <= self.T_ref[0]:
            return self.a_coeff[0]
        elif T >= self.T_ref[-1]:
            return self.a_coeff[-1]
        else:
            # 线性插值
            for i in range(len(self.T_ref) - 1):
                if self.T_ref[i] <= T <= self.T_ref[i+1]:
                    f = (T - self.T_ref[i]) / (self.T_ref[i+1] - self.T_ref[i])
                    a = [self.a_coeff[i][j] + f * (self.a_coeff[i+1][j] - self.a_coeff[i][j])
                         for j in range(len(self.k_gray))]
                    return a
        return self.a_coeff[0]
    
    def emissivity(self, T, P_total, x_co2, x_h2o, L):
        """
        计算气体发射率(WSGGM模型)
        
        参数:
            T: 气体温度 [K]
            P_total: 总压 [atm]
            x_co2: CO2摩尔分数
            x_h2o: H2O摩尔分数
            L: 平均射线程长 [m]
        返回:
            发射率 [-]
        """
        # 等效分压
        p_co2 = x_co2 * P_total
        p_h2o = x_h2o * P_total
        p_mean = (p_co2 + p_h2o) / 2  # 简化处理
        
        # 获取权重
        a = self.get_weights(T)
        
        # 计算发射率
        eps = 0.0
        for i, k in enumerate(self.k_gray):
            eps += a[i] * (1 - np.exp(-k * p_mean * L))
        
        return eps
    
    def absorptivity(self, T_gas, T_surface, P_total, x_co2, x_h2o, L):
        """
        计算气体吸收率(简化:假设等于发射率)
        """
        return self.emissivity(T_gas, P_total, x_co2, x_h2o, L)


class FurnaceRadiation:
    """炉膛辐射换热模型"""
    
    def __init__(self, 
                 furnace_height=10.0,  # 炉膛高度 [m]
                 furnace_width=5.0,    # 炉膛宽度 [m]
                 furnace_depth=5.0,    # 炉膛深度 [m]
                 wall_emissivity=0.8,  # 壁面发射率
                 gas_model=None):
        """
        初始化炉膛模型
        """
        self.H = furnace_height
        self.W = furnace_width
        self.D = furnace_depth
        self.epsilon_wall = wall_emissivity
        self.gas = gas_model if gas_model else GasRadiation()
        
        # 炉膛表面积
        self.A_floor = self.W * self.D
        self.A_roof = self.W * self.D
        self.A_side = 2 * self.H * self.D
        self.A_front = 2 * self.H * self.W
        self.A_total = 2 * (self.A_floor + self.A_side + self.A_front)
        
        # 平均射线程长(简化)
        self.L_mean = 0.9 * (4 * self.H * self.W * self.D / self.A_total)
        
    def calculate_heat_transfer(self, 
                                T_gas,          # 气体平均温度 [K]
                                T_wall,         # 壁面温度 [K]
                                P_total=1.0,    # 总压 [atm]
                                x_co2=0.12,     # CO2摩尔分数
                                x_h2o=0.15,     # H2O摩尔分数
                                include_soot=False,
                                f_soot=1e-6):   # 碳烟体积分数
        """
        计算炉膛辐射换热
        
        返回:
            换热结果字典
        """
        # 气体发射率
        eps_gas = self.gas.emissivity(T_gas, P_total, x_co2, x_h2o, self.L_mean)
        
        # 碳烟贡献(简化)
        if include_soot:
            # 碳烟吸收系数
            k_soot = 1500 * f_soot * T_gas / 1000  # 简化模型
            eps_soot = 1 - np.exp(-k_soot * self.L_mean)
            # 合并(简化处理)
            eps_total = eps_gas + eps_soot - eps_gas * eps_soot
        else:
            eps_total = eps_gas
            eps_soot = 0.0
        
        # 气体有效发射率(考虑壁面反射)
        eps_eff = 1 / (1/eps_total + 1/self.epsilon_wall - 1)
        
        # 辐射换热热流
        q_rad = eps_eff * sigma * (T_gas**4 - T_wall**4)
        
        # 总换热量
        Q_rad = q_rad * self.A_total
        
        return {
            'q_rad': q_rad,
            'Q_rad': Q_rad,
            'eps_gas': eps_gas,
            'eps_soot': eps_soot,
            'eps_total': eps_total,
            'eps_eff': eps_eff,
            'L_mean': self.L_mean
        }


# =============================================================================
# 第四部分:斯特林发动机模块
# =============================================================================

class StirlingEngine:
    """斯特林发动机模型"""
    
    def __init__(self,
                 T_hot=800.0,      # 热端温度 [°C]
                 T_cold=50.0,      # 冷端温度 [°C]
                 working_fluid='helium',
                 regenerator_eff=0.90):
        """
        初始化斯特林发动机
        """
        self.T_H = T_hot + 273.15  # 转换为K
        self.T_C = T_cold + 273.15
        self.regenerator_eff = regenerator_eff
        
        # 工质属性(简化)
        if working_fluid == 'helium':
            self.gamma = 1.67
            self.R = 2077
            self.k = 0.15
        elif working_fluid == 'hydrogen':
            self.gamma = 1.41
            self.R = 4124
            self.k = 0.18
        else:  # air
            self.gamma = 1.4
            self.R = 287
            self.k = 0.026
            
    def carnot_efficiency(self):
        """计算卡诺效率"""
        return 1 - self.T_C / self.T_H
    
    def ideal_stirling_efficiency(self):
        """
        理想斯特林循环效率
        (假设完全回热,效率等于卡诺效率)
        """
        return self.carnot_efficiency()
    
    def actual_efficiency(self, 
                         pressure_loss=0.05,      # 流动压力损失
                         heat_loss=0.10,          # 热损失
                         mechanical_loss=0.03,    # 机械损失
                         seal_loss=0.02):         # 密封损失
        """
        计算实际效率(考虑各种损失)
        """
        eta_carnot = self.carnot_efficiency()
        
        # 回热器损失
        eta_regenerator = eta_carnot * self.regenerator_eff
        
        # 综合效率
        eta_actual = (eta_regenerator * 
                     (1 - pressure_loss) * 
                     (1 - heat_loss) * 
                     (1 - mechanical_loss) * 
                     (1 - seal_loss))
        
        return {
            'eta_carnot': eta_carnot,
            'eta_regenerator': eta_regenerator,
            'eta_actual': eta_actual,
            'losses': {
                'regenerator': eta_carnot - eta_regenerator,
                'pressure': eta_regenerator * pressure_loss,
                'heat': eta_regenerator * heat_loss,
                'mechanical': eta_regenerator * mechanical_loss,
                'seal': eta_regenerator * seal_loss
            }
        }
    
    def power_output(self, Q_in, efficiency=None):
        """
        计算功率输出
        
        参数:
            Q_in: 输入热功率 [W]
            efficiency: 效率(如果为None则计算实际效率)
        返回:
            功率 [W]
        """
        if efficiency is None:
            eff_data = self.actual_efficiency()
            efficiency = eff_data['eta_actual']
        
        return Q_in * efficiency


# =============================================================================
# 第五部分:可视化函数
# =============================================================================

def create_animation_frames(func, frames, output_prefix):
    """创建动画帧"""
    for i, frame_data in enumerate(frames):
        func(frame_data, f"{output_prefix}_frame_{i:03d}.png")


# =============================================================================
# 案例1:槽式集热器性能分析
# =============================================================================

def case1_trough_collector_performance():
    """案例1:槽式集热器性能分析"""
    print("\n" + "="*70)
    print("案例1:槽式集热器性能分析")
    print("="*70)
    
    # 创建太阳辐射对象
    solar = SolarRadiation()
    
    # 创建不同性能的涂层
    coatings = {
        '高性能涂层': SelectiveCoating(alpha_solar=0.95, epsilon_thermal=0.05),
        '中性能涂层': SelectiveCoating(alpha_solar=0.92, epsilon_thermal=0.10),
        '低性能涂层': SelectiveCoating(alpha_solar=0.90, epsilon_thermal=0.20)
    }
    
    # 创建集热器
    collectors = {}
    for name, coating in coatings.items():
        collectors[name] = ParabolicTroughCollector(
            aperture_width=5.0,
            focal_length=1.5,
            length=100.0,
            receiver_diameter=0.07,
            coating=coating,
            reflectance=0.93,
            intercept_factor=0.95
        )
    
    # 计算不同工作温度下的效率
    T_ambient = 298.15  # 25°C
    DNI = 900  # W/m²
    wind_speed = 2.0  # m/s
    mass_flow_rate = 2.0  # kg/s
    
    T_out_range = np.linspace(100, 450, 20) + 273.15  # 100-450°C
    T_in = 50 + 273.15  # 50°C
    
    results = {name: {'T': [], 'eta': [], 'Q_loss': [], 'q_rad': [], 'q_conv': []} 
               for name in collectors.keys()}
    
    for name, collector in collectors.items():
        for T_out in T_out_range:
            eff_data = collector.thermal_efficiency(
                T_in, T_out, T_ambient, DNI, mass_flow_rate, wind_speed
            )
            results[name]['T'].append(T_out - 273.15)
            results[name]['eta'].append(eff_data['eta_thermal'] * 100)
            results[name]['Q_loss'].append(eff_data['Q_loss'] / 1000)  # kW
            results[name]['q_rad'].append(eff_data['q_rad'] / 1000)
            results[name]['q_conv'].append(eff_data['q_conv'] / 1000)
    
    # 绘制结果
    fig, axes = plt.subplots(2, 2, figsize=(14, 10))
    
    # 图1:效率随温度变化
    ax1 = axes[0, 0]
    colors = ['#e74c3c', '#3498db', '#2ecc71']
    for i, (name, data) in enumerate(results.items()):
        ax1.plot(data['T'], data['eta'], 'o-', color=colors[i], 
                linewidth=2, markersize=4, label=name)
    ax1.set_xlabel('出口温度 [°C]', fontsize=11)
    ax1.set_ylabel('集热效率 [%]', fontsize=11)
    ax1.set_title('集热效率随工作温度变化', fontsize=12, fontweight='bold')
    ax1.legend(loc='best', fontsize=9)
    ax1.grid(True, alpha=0.3)
    ax1.set_xlim([100, 450])
    ax1.set_ylim([40, 85])
    
    # 图2:热损失组成
    ax2 = axes[0, 1]
    T_plot = results['中性能涂层']['T']
    q_rad = results['中性能涂层']['q_rad']
    q_conv = results['中性能涂层']['q_conv']
    
    ax2.fill_between(T_plot, 0, q_rad, alpha=0.6, color='#e74c3c', label='辐射损失')
    ax2.fill_between(T_plot, q_rad, np.array(q_rad) + np.array(q_conv), 
                     alpha=0.6, color='#3498db', label='对流损失')
    ax2.plot(T_plot, np.array(q_rad) + np.array(q_conv), 'k-', linewidth=2, label='总热损失')
    ax2.set_xlabel('出口温度 [°C]', fontsize=11)
    ax2.set_ylabel('热损失 [kW]', fontsize=11)
    ax2.set_title('热损失组成分析(中性能涂层)', fontsize=12, fontweight='bold')
    ax2.legend(loc='best', fontsize=9)
    ax2.grid(True, alpha=0.3)
    
    # 图3:太阳辐射光谱
    ax3 = axes[1, 0]
    wavelengths = np.linspace(0.3, 3.0, 500)
    E_sun = solar.solar_spectrum(wavelengths)
    E_bb_300 = solar.planck_distribution(wavelengths, 300)
    E_bb_400 = solar.planck_distribution(wavelengths, 400 + 273.15)
    
    ax3.plot(wavelengths, E_sun / 1e6, 'b-', linewidth=2, label='太阳辐射 (5778K)')
    ax3.plot(wavelengths, E_bb_300 / 1e6, 'r--', linewidth=1.5, label='黑体300K')
    ax3.plot(wavelengths, E_bb_400 / 1e6, 'g--', linewidth=1.5, label='黑体673K')
    ax3.axvline(x=2.5, color='k', linestyle=':', alpha=0.5, label='过渡波长')
    ax3.set_xlabel('波长 [μm]', fontsize=11)
    ax3.set_ylabel('光谱辐射力 [W/(m²·μm)]', fontsize=11)
    ax3.set_title('太阳辐射与集热器辐射光谱对比', fontsize=12, fontweight='bold')
    ax3.legend(loc='best', fontsize=9)
    ax3.grid(True, alpha=0.3)
    ax3.set_yscale('log')
    
    # 图4:选择性涂层光谱特性
    ax4 = axes[1, 1]
    coating_high = coatings['高性能涂层']
    coating_low = coatings['低性能涂层']
    
    alpha_high = coating_high.spectral_absorptance(wavelengths)
    alpha_low = coating_low.spectral_absorptance(wavelengths)
    
    ax4.plot(wavelengths, alpha_high, 'r-', linewidth=2, label='高性能涂层')
    ax4.plot(wavelengths, alpha_low, 'b--', linewidth=2, label='低性能涂层')
    ax4.axvline(x=2.5, color='k', linestyle=':', alpha=0.5)
    ax4.set_xlabel('波长 [μm]', fontsize=11)
    ax4.set_ylabel('光谱吸收率/发射率 [-]', fontsize=11)
    ax4.set_title('选择性吸收涂层光谱特性', fontsize=12, fontweight='bold')
    ax4.legend(loc='best', fontsize=9)
    ax4.grid(True, alpha=0.3)
    ax4.set_ylim([0, 1])
    
    plt.tight_layout()
    plt.savefig('case1_trough_collector.png', dpi=150, bbox_inches='tight')
    plt.close()
    
    print("✓ 案例1完成,结果保存至 case1_trough_collector.png")
    
    # 打印关键结果
    print("\n关键结果:")
    for name, data in results.items():
        eta_100 = data['eta'][0]
        eta_400 = data['eta'][-1]
        print(f"  {name}: 100°C时效率={eta_100:.1f}%, 400°C时效率={eta_400:.1f}%")
    
    return results


# =============================================================================
# 案例2:定日镜场光学模拟
# =============================================================================

def case2_heliostat_field():
    """案例2:定日镜场光学模拟"""
    print("\n" + "="*70)
    print("案例2:定日镜场光学模拟")
    print("="*70)
    
    # 定日镜场参数
    tower_height = 80.0  # 塔高 [m]
    receiver_height = 15.0  # 接收器高度 [m]
    receiver_diameter = 3.0  # 接收器直径 [m]
    
    # 生成定日镜场布局(径向交错布局)
    n_rings = 8
    heliostats = []
    
    for ring in range(1, n_rings + 1):
        radius = 50 + ring * 30  # 半径 [m]
        n_heliostats = int(2 * np.pi * radius / 15)  # 每环定日镜数量
        
        for i in range(n_heliostats):
            angle = 2 * np.pi * i / n_heliostats
            if ring % 2 == 1:
                angle += np.pi / n_heliostats  # 交错排列
            
            x = radius * np.cos(angle)
            y = radius * np.sin(angle)
            heliostats.append({'x': x, 'y': y, 'ring': ring})
    
    # 计算每个定日镜的余弦效率
    sun_elevation = np.radians(45)  # 太阳高度角
    sun_azimuth = np.radians(0)     # 太阳方位角
    
    # 太阳方向向量
    sun_dir = np.array([
        np.cos(sun_elevation) * np.sin(sun_azimuth),
        np.cos(sun_elevation) * np.cos(sun_azimuth),
        np.sin(sun_elevation)
    ])
    
    for h in heliostats:
        # 定日镜到接收器的向量
        to_receiver = np.array([0, 0, tower_height + receiver_height/2]) - \
                     np.array([h['x'], h['y'], 0])
        to_receiver = to_receiver / np.linalg.norm(to_receiver)
        
        # 反射方向(入射方向 + 反射方向 = 2 * 法向)
        normal = sun_dir + to_receiver
        normal = normal / np.linalg.norm(normal)
        
        # 余弦效率
        h['cosine_eff'] = np.dot(sun_dir, normal)
        
        # 到接收器的距离
        h['distance'] = np.sqrt(h['x']**2 + h['y']**2 + tower_height**2)
        
        # 大气衰减(简化模型)
        h['atm_transmittance'] = np.exp(-0.0001 * h['distance'])
        
        # 综合光学效率
        h['optical_eff'] = h['cosine_eff'] * h['atm_transmittance'] * 0.93  # 反射率
    
    # 计算接收器上的能流分布(简化)
    n_theta = 36
    n_z = 20
    theta = np.linspace(0, 2*np.pi, n_theta)
    z = np.linspace(0, receiver_height, n_z)
    THETA, Z = np.meshgrid(theta, z)
    
    # 初始化能流分布
    flux = np.zeros_like(THETA)
    
    # 简化的能流计算(高斯分布叠加)
    for h in heliostats:
        if h['cosine_eff'] > 0:
            # 计算反射光在接收器上的落点
            # 简化:假设反射光汇聚到接收器中心附近
            sigma_spot = 0.5 + 0.001 * h['distance']  # 光斑尺寸随距离增加
            
            # 添加高斯分布贡献
            for i in range(n_z):
                for j in range(n_theta):
                    r = receiver_diameter / 2
                    dist = np.sqrt(r**2 + (z[i] - receiver_height/2)**2)
                    flux[i, j] += (h['optical_eff'] * 
                                  np.exp(-dist**2 / (2 * sigma_spot**2)))
    
    # 归一化
    flux = flux / np.max(flux) if np.max(flux) > 0 else flux
    
    # 绘制结果
    fig, axes = plt.subplots(2, 2, figsize=(14, 12))
    
    # 图1:定日镜场布局
    ax1 = axes[0, 0]
    x_pos = [h['x'] for h in heliostats]
    y_pos = [h['y'] for h in heliostats]
    effs = [h['optical_eff'] for h in heliostats]
    
    scatter = ax1.scatter(x_pos, y_pos, c=effs, cmap='RdYlGn', 
                         s=30, vmin=0.4, vmax=0.9)
    ax1.plot(0, 0, 'r^', markersize=20, label='接收塔')
    
    # 添加同心圆表示距离
    for r in [100, 200, 300]:
        circle = Circle((0, 0), r, fill=False, linestyle='--', alpha=0.3)
        ax1.add_patch(circle)
    
    ax1.set_xlabel('东-西方向 [m]', fontsize=11)
    ax1.set_ylabel('南-北方向 [m]', fontsize=11)
    ax1.set_title('定日镜场布局与光学效率', fontsize=12, fontweight='bold')
    ax1.set_aspect('equal')
    ax1.grid(True, alpha=0.3)
    cbar1 = plt.colorbar(scatter, ax=ax1)
    cbar1.set_label('光学效率', fontsize=10)
    
    # 图2:效率随距离变化
    ax2 = axes[0, 1]
    distances = [h['distance'] for h in heliostats]
    cosine_effs = [h['cosine_eff'] for h in heliostats]
    atm_effs = [h['atm_transmittance'] for h in heliostats]
    
    ax2.scatter(distances, cosine_effs, c='blue', alpha=0.5, s=20, label='余弦效率')
    ax2.scatter(distances, atm_effs, c='red', alpha=0.5, s=20, label='大气透过率')
    
    # 拟合曲线
    dist_sorted = np.sort(np.unique(distances))
    cos_fit = np.maximum(0.4, 1 - 0.0005 * (dist_sorted - 100))
    atm_fit = np.exp(-0.0001 * dist_sorted)
    
    ax2.plot(dist_sorted, cos_fit, 'b-', linewidth=2, label='余弦效率趋势')
    ax2.plot(dist_sorted, atm_fit, 'r-', linewidth=2, label='大气透过率趋势')
    
    ax2.set_xlabel('到接收器距离 [m]', fontsize=11)
    ax2.set_ylabel('效率 [-]', fontsize=11)
    ax2.set_title('效率随距离变化', fontsize=12, fontweight='bold')
    ax2.legend(loc='best', fontsize=9)
    ax2.grid(True, alpha=0.3)
    ax2.set_ylim([0.3, 1.0])
    
    # 图3:接收器能流分布(极坐标)
    ax3 = axes[1, 0]
    im = ax3.contourf(THETA, Z, flux, levels=20, cmap='hot')
    ax3.set_xlabel('方位角 [rad]', fontsize=11)
    ax3.set_ylabel('高度 [m]', fontsize=11)
    ax3.set_title('接收器能流分布', fontsize=12, fontweight='bold')
    cbar3 = plt.colorbar(im, ax=ax3)
    cbar3.set_label('相对能流密度', fontsize=10)
    
    # 图4:损失分析饼图
    ax4 = axes[1, 1]
    
    # 计算平均损失
    avg_cos = np.mean([h['cosine_eff'] for h in heliostats])
    avg_atm = np.mean([h['atm_transmittance'] for h in heliostats])
    reflectance = 0.93
    intercept = 0.95
    
    total_eff = avg_cos * avg_atm * reflectance * intercept
    
    losses = {
        '余弦损失': 1 - avg_cos,
        '大气衰减': avg_cos * (1 - avg_atm),
        '反射损失': avg_cos * avg_atm * (1 - reflectance),
        '拦截损失': avg_cos * avg_atm * reflectance * (1 - intercept),
        '有效': total_eff
    }
    
    colors_pie = ['#e74c3c', '#f39c12', '#f1c40f', '#95a5a6', '#2ecc71']
    wedges, texts, autotexts = ax4.pie(losses.values(), labels=losses.keys(),
                                        autopct='%1.1f%%', colors=colors_pie,
                                        startangle=90)
    ax4.set_title('光学损失分析', fontsize=12, fontweight='bold')
    
    plt.tight_layout()
    plt.savefig('case2_heliostat_field.png', dpi=150, bbox_inches='tight')
    plt.close()
    
    print("✓ 案例2完成,结果保存至 case2_heliostat_field.png")
    
    # 打印关键结果
    print(f"\n关键结果:")
    print(f"  定日镜总数: {len(heliostats)}")
    print(f"  平均光学效率: {total_eff:.3f}")
    print(f"  主要损失: 余弦损失 ({(1-avg_cos)*100:.1f}%), 大气衰减 ({(1-avg_atm)*100:.1f}%)")
    
    return heliostats, flux


# =============================================================================
# 案例3:炉膛辐射传热
# =============================================================================

def case3_furnace_radiation():
    """案例3:炉膛辐射传热"""
    print("\n" + "="*70)
    print("案例3:炉膛辐射传热")
    print("="*70)
    
    # 创建炉膛模型
    furnace = FurnaceRadiation(
        furnace_height=10.0,
        furnace_width=5.0,
        furnace_depth=5.0,
        wall_emissivity=0.8
    )
    
    # 计算不同工况下的辐射换热
    T_gas_range = np.linspace(1000, 2000, 20)  # 气体温度 [K]
    T_wall = 800  # 壁面温度 [K]
    
    # 不同工况
    cases = {
        '天然气燃烧 (CO₂=8%, H₂O=16%)': {'x_co2': 0.08, 'x_h2o': 0.16, 'P': 1.0},
        '煤燃烧 (CO₂=12%, H₂O=10%)': {'x_co2': 0.12, 'x_h2o': 0.10, 'P': 1.0},
        '富氧燃烧 (CO₂=20%, H₂O=40%)': {'x_co2': 0.20, 'x_h2o': 0.40, 'P': 1.0},
        '高压工况 (P=10atm)': {'x_co2': 0.08, 'x_h2o': 0.16, 'P': 10.0}
    }
    
    results = {}
    for case_name, params in cases.items():
        results[case_name] = {
            'T_gas': [],
            'q_rad': [],
            'Q_rad': [],
            'eps_gas': []
        }
        
        for T_gas in T_gas_range:
            result = furnace.calculate_heat_transfer(
                T_gas, T_wall, 
                P_total=params['P'],
                x_co2=params['x_co2'],
                x_h2o=params['x_h2o']
            )
            results[case_name]['T_gas'].append(T_gas)
            results[case_name]['q_rad'].append(result['q_rad'] / 1000)  # kW/m²
            results[case_name]['Q_rad'].append(result['Q_rad'] / 1000)  # kW
            results[case_name]['eps_gas'].append(result['eps_gas'])
    
    # 绘制结果
    fig, axes = plt.subplots(2, 2, figsize=(14, 10))
    
    # 图1:辐射热流随气体温度的变化
    ax1 = axes[0, 0]
    colors = ['#e74c3c', '#3498db', '#2ecc71', '#9b59b6']
    for i, (case_name, data) in enumerate(results.items()):
        ax1.plot(data['T_gas'], data['q_rad'], 'o-', color=colors[i],
                linewidth=2, markersize=4, label=case_name)
    ax1.set_xlabel('气体温度 [K]', fontsize=11)
    ax1.set_ylabel('辐射热流 [kW/m²]', fontsize=11)
    ax1.set_title('炉膛辐射热流随温度变化', fontsize=12, fontweight='bold')
    ax1.legend(loc='best', fontsize=8)
    ax1.grid(True, alpha=0.3)
    
    # 图2:气体发射率
    ax2 = axes[0, 1]
    for i, (case_name, data) in enumerate(results.items()):
        ax2.plot(data['T_gas'], data['eps_gas'], 's-', color=colors[i],
                linewidth=2, markersize=4, label=case_name)
    ax2.set_xlabel('气体温度 [K]', fontsize=11)
    ax2.set_ylabel('气体发射率 [-]', fontsize=11)
    ax2.set_title('气体发射率随温度变化', fontsize=12, fontweight='bold')
    ax2.legend(loc='best', fontsize=8)
    ax2.grid(True, alpha=0.3)
    ax2.set_ylim([0, 1])
    
    # 图3:炉膛几何示意图
    ax3 = axes[1, 0]
    
    # 绘制炉膛截面
    furnace_rect = Rectangle((0, 0), furnace.W, furnace.H, 
                             linewidth=2, edgecolor='black', 
                             facecolor='lightgray', alpha=0.5)
    ax3.add_patch(furnace_rect)
    
    # 绘制火焰(用渐变表示温度)
    n_flames = 5
    for i in range(n_flames):
        y = furnace.H * (0.2 + 0.6 * i / (n_flames - 1))
        intensity = 0.3 + 0.7 * (1 - abs(i - n_flames/2) / (n_flames/2))
        flame = Circle((furnace.W/2, y), 0.8, 
                      facecolor=plt.cm.hot(intensity), 
                      edgecolor='none', alpha=0.6)
        ax3.add_patch(flame)
    
    # 标注
    ax3.annotate('燃烧器', xy=(furnace.W/2, 0.5), fontsize=10, ha='center',
                bbox=dict(boxstyle='round', facecolor='yellow', alpha=0.7))
    ax3.annotate('烟气出口', xy=(furnace.W, furnace.H-0.5), fontsize=10, ha='center',
                bbox=dict(boxstyle='round', facecolor='lightblue', alpha=0.7))
    
    ax3.set_xlim([-0.5, furnace.W + 0.5])
    ax3.set_ylim([-0.5, furnace.H + 0.5])
    ax3.set_aspect('equal')
    ax3.set_xlabel('宽度 [m]', fontsize=11)
    ax3.set_ylabel('高度 [m]', fontsize=11)
    ax3.set_title('炉膛几何示意图', fontsize=12, fontweight='bold')
    ax3.grid(True, alpha=0.3)
    
    # 图4:不同CO2/H2O比例的影响
    ax4 = axes[1, 1]
    
    x_co2_range = np.linspace(0.05, 0.25, 10)
    x_h2o = 0.15
    T_gas = 1500
    
    eps_values = []
    for x_co2 in x_co2_range:
        eps = furnace.gas.emissivity(T_gas, 1.0, x_co2, x_h2o, furnace.L_mean)
        eps_values.append(eps)
    
    ax4.plot(x_co2_range * 100, eps_values, 'bo-', linewidth=2, markersize=6)
    ax4.set_xlabel('CO₂浓度 [%]', fontsize=11)
    ax4.set_ylabel('气体发射率 [-]', fontsize=11)
    ax4.set_title(f'CO₂浓度对发射率的影响 (T={T_gas}K, H₂O={x_h2o*100:.0f}%)', 
                 fontsize=12, fontweight='bold')
    ax4.grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('case3_furnace_radiation.png', dpi=150, bbox_inches='tight')
    plt.close()
    
    print("✓ 案例3完成,结果保存至 case3_furnace_radiation.png")
    
    # 打印关键结果
    print(f"\n关键结果(T_gas=1500K时):")
    for case_name, data in results.items():
        idx = 10  # 约1500K
        print(f"  {case_name}: 热流={data['q_rad'][idx]:.1f} kW/m², 发射率={data['eps_gas'][idx]:.3f}")
    
    return results


# =============================================================================
# 案例4:燃烧气体辐射特性
# =============================================================================

def case4_combustion_gas_radiation():
    """案例4:燃烧气体辐射特性"""
    print("\n" + "="*70)
    print("案例4:燃烧气体辐射特性")
    print("="*70)
    
    gas = GasRadiation()
    
    # 参数范围
    T_range = np.linspace(1000, 2500, 30)  # 温度 [K]
    P_range = [1, 5, 10, 20]  # 压力 [atm]
    L_range = np.linspace(0.1, 5.0, 20)  # 气层厚度 [m]
    
    # 固定组分(天然气燃烧产物)
    x_co2 = 0.08
    x_h2o = 0.16
    
    # 计算发射率
    results = {
        'temperature': {},
        'pressure': {},
        'path_length': {}
    }
    
    # 1. 温度影响(固定P=1atm, L=1m)
    results['temperature']['T'] = T_range
    results['temperature']['eps'] = [gas.emissivity(T, 1.0, x_co2, x_h2o, 1.0) 
                                      for T in T_range]
    
    # 2. 压力影响(固定T=1500K, L=1m)
    results['pressure']['P'] = P_range
    results['pressure']['eps'] = [gas.emissivity(1500, P, x_co2, x_h2o, 1.0) 
                                   for P in P_range]
    
    # 3. 气层厚度影响(固定T=1500K, P=1atm)
    results['path_length']['L'] = L_range
    results['path_length']['eps'] = [gas.emissivity(1500, 1.0, x_co2, x_h2o, L) 
                                      for L in L_range]
    
    # 绘制结果
    fig, axes = plt.subplots(2, 2, figsize=(14, 10))
    
    # 图1:温度对发射率的影响
    ax1 = axes[0, 0]
    ax1.plot(results['temperature']['T'], results['temperature']['eps'], 
            'r-o', linewidth=2, markersize=5)
    ax1.set_xlabel('温度 [K]', fontsize=11)
    ax1.set_ylabel('发射率 [-]', fontsize=11)
    ax1.set_title(f'温度对气体发射率的影响 (CO₂={x_co2*100:.0f}%, H₂O={x_h2o*100:.0f}%)', 
                 fontsize=12, fontweight='bold')
    ax1.grid(True, alpha=0.3)
    ax1.set_ylim([0, 1])
    
    # 图2:压力对发射率的影响
    ax2 = axes[0, 1]
    ax2.bar(results['pressure']['P'], results['pressure']['eps'], 
           color=['#3498db', '#2ecc71', '#f39c12', '#e74c3c'], alpha=0.7, width=3)
    ax2.set_xlabel('压力 [atm]', fontsize=11)
    ax2.set_ylabel('发射率 [-]', fontsize=11)
    ax2.set_title(f'压力对气体发射率的影响 (T=1500K)', 
                 fontsize=12, fontweight='bold')
    ax2.grid(True, alpha=0.3, axis='y')
    ax2.set_ylim([0, 1])
    
    # 图3:气层厚度对发射率的影响
    ax3 = axes[1, 0]
    ax3.plot(results['path_length']['L'], results['path_length']['eps'], 
            'g-s', linewidth=2, markersize=5)
    ax3.set_xlabel('气层厚度 [m]', fontsize=11)
    ax3.set_ylabel('发射率 [-]', fontsize=11)
    ax3.set_title(f'气层厚度对发射率的影响 (T=1500K)', 
                 fontsize=12, fontweight='bold')
    ax3.grid(True, alpha=0.3)
    ax3.set_ylim([0, 1])
    
    # 图4:CO2和H2O的发射率对比
    ax4 = axes[1, 1]
    
    # 单独CO2
    eps_co2 = [gas.emissivity(T, 1.0, 0.15, 0, 1.0) for T in T_range]
    # 单独H2O
    eps_h2o = [gas.emissivity(T, 1.0, 0, 0.30, 1.0) for T in T_range]
    # 混合
    eps_mix = [gas.emissivity(T, 1.0, 0.08, 0.16, 1.0) for T in T_range]
    
    ax4.plot(T_range, eps_co2, 'b-o', linewidth=2, markersize=4, label='CO₂ (15%)')
    ax4.plot(T_range, eps_h2o, 'r-s', linewidth=2, markersize=4, label='H₂O (30%)')
    ax4.plot(T_range, eps_mix, 'g-^', linewidth=2, markersize=4, label='混合 (CO₂8%+H₂O16%)')
    
    ax4.set_xlabel('温度 [K]', fontsize=11)
    ax4.set_ylabel('发射率 [-]', fontsize=11)
    ax4.set_title('CO₂和H₂O发射率对比', fontsize=12, fontweight='bold')
    ax4.legend(loc='best', fontsize=9)
    ax4.grid(True, alpha=0.3)
    ax4.set_ylim([0, 1])
    
    plt.tight_layout()
    plt.savefig('case4_combustion_gas.png', dpi=150, bbox_inches='tight')
    plt.close()
    
    print("✓ 案例4完成,结果保存至 case4_combustion_gas.png")
    
    # 打印关键结果
    print(f"\n关键结果:")
    print(f"  T=1500K, P=1atm, L=1m时发射率: {gas.emissivity(1500, 1.0, x_co2, x_h2o, 1.0):.3f}")
    print(f"  T=1500K, P=10atm, L=1m时发射率: {gas.emissivity(1500, 10.0, x_co2, x_h2o, 1.0):.3f}")
    print(f"  压力增加10倍,发射率增加约{(gas.emissivity(1500, 10.0, x_co2, x_h2o, 1.0)/gas.emissivity(1500, 1.0, x_co2, x_h2o, 1.0)-1)*100:.0f}%")
    
    return results


# =============================================================================
# 案例5:斯特林发动机循环分析
# =============================================================================

def case5_stirling_engine():
    """案例5:斯特林发动机循环分析"""
    print("\n" + "="*70)
    print("案例5:斯特林发动机循环分析")
    print("="*70)
    
    # 创建斯特林发动机模型
    engines = {
        '高温型 (800°C/50°C)': StirlingEngine(T_hot=800, T_cold=50, 
                                              working_fluid='helium', 
                                              regenerator_eff=0.95),
        '中温型 (600°C/50°C)': StirlingEngine(T_hot=600, T_cold=50, 
                                              working_fluid='helium', 
                                              regenerator_eff=0.90),
        '低温型 (400°C/30°C)': StirlingEngine(T_hot=400, T_cold=30, 
                                              working_fluid='air', 
                                              regenerator_eff=0.85)
    }
    
    # 计算效率
    results = {}
    for name, engine in engines.items():
        results[name] = engine.actual_efficiency()
    
    # 绘制结果
    fig, axes = plt.subplots(2, 2, figsize=(14, 10))
    
    # 图1:效率对比
    ax1 = axes[0, 0]
    engine_names = list(results.keys())
    eta_carnot = [results[name]['eta_carnot'] * 100 for name in engine_names]
    eta_actual = [results[name]['eta_actual'] * 100 for name in engine_names]
    
    x = np.arange(len(engine_names))
    width = 0.35
    
    bars1 = ax1.bar(x - width/2, eta_carnot, width, label='卡诺效率', 
                   color='#3498db', alpha=0.8)
    bars2 = ax1.bar(x + width/2, eta_actual, width, label='实际效率', 
                   color='#e74c3c', alpha=0.8)
    
    ax1.set_ylabel('效率 [%]', fontsize=11)
    ax1.set_title('斯特林发动机效率对比', fontsize=12, fontweight='bold')
    ax1.set_xticks(x)
    ax1.set_xticklabels(['高温型', '中温型', '低温型'], fontsize=10)
    ax1.legend(loc='best', fontsize=9)
    ax1.grid(True, alpha=0.3, axis='y')
    
    # 添加数值标签
    for bars in [bars1, bars2]:
        for bar in bars:
            height = bar.get_height()
            ax1.annotate(f'{height:.1f}%',
                        xy=(bar.get_x() + bar.get_width() / 2, height),
                        xytext=(0, 3), textcoords="offset points",
                        ha='center', va='bottom', fontsize=8)
    
    # 图2:损失分解(以高温型为例)
    ax2 = axes[0, 1]
    
    losses = results['高温型 (800°C/50°C)']['losses']
    loss_labels = list(losses.keys())
    loss_values = [v * 100 for v in losses.values()]
    
    # 计算百分比
    total_loss = sum(loss_values)
    loss_percentages = [v / (results['高温型 (800°C/50°C)']['eta_carnot'] * 100) * 100 
                       for v in loss_values]
    
    colors_loss = ['#e74c3c', '#f39c12', '#f1c40f', '#95a5a6']
    wedges, texts, autotexts = ax2.pie(loss_percentages, labels=loss_labels,
                                        autopct='%1.1f%%', colors=colors_loss,
                                        startangle=90)
    ax2.set_title('高温型斯特林发动机损失分解', fontsize=12, fontweight='bold')
    
    # 图3:P-V图(理想斯特林循环)
    ax3 = axes[1, 0]
    
    # 简化的斯特林循环P-V图
    V_min = 0.001  # 最小体积 [m³]
    V_max = 0.005  # 最大体积 [m³]
    
    # 等温过程参数
    T_H = 800 + 273.15
    T_C = 50 + 273.15
    m = 0.001  # 工质质量 [kg]
    R = 2077   # He气体常数
    
    # 计算压力
    V = np.linspace(V_min, V_max, 100)
    P_H = m * R * T_H / V  # 高温等温线
    P_C = m * R * T_C / V  # 低温等温线
    
    # 绘制循环
    V_cycle = [V_min, V_max, V_max, V_min, V_min]
    P_cycle = [m*R*T_H/V_min, m*R*T_H/V_max, m*R*T_C/V_max, m*R*T_C/V_min, m*R*T_H/V_min]
    
    ax3.fill(V_cycle, P_cycle, alpha=0.3, color='green', label='循环功')
    ax3.plot(V, P_H/1e5, 'r-', linewidth=2, label=f'等温膨胀 (T={T_H-273.15:.0f}°C)')
    ax3.plot(V, P_C/1e5, 'b-', linewidth=2, label=f'等温压缩 (T={T_C-273.15:.0f}°C)')
    ax3.plot(V_cycle, np.array(P_cycle)/1e5, 'g--', linewidth=2, label='斯特林循环')
    
    ax3.set_xlabel('体积 [m³]', fontsize=11)
    ax3.set_ylabel('压力 [bar]', fontsize=11)
    ax3.set_title('理想斯特林循环P-V图', fontsize=12, fontweight='bold')
    ax3.legend(loc='best', fontsize=9)
    ax3.grid(True, alpha=0.3)
    
    # 图4:回热器效率对总效率的影响
    ax4 = axes[1, 1]
    
    regen_eff_range = np.linspace(0.7, 0.99, 20)
    eta_vs_regen = []
    
    for eff in regen_eff_range:
        engine = StirlingEngine(T_hot=800, T_cold=50, 
                               working_fluid='helium', 
                               regenerator_eff=eff)
        result = engine.actual_efficiency()
        eta_vs_regen.append(result['eta_actual'] * 100)
    
    ax4.plot(regen_eff_range * 100, eta_vs_regen, 'b-', linewidth=2)
    ax4.axhline(y=results['高温型 (800°C/50°C)']['eta_carnot'] * 100, 
               color='r', linestyle='--', linewidth=2, label='卡诺效率')
    ax4.set_xlabel('回热器效率 [%]', fontsize=11)
    ax4.set_ylabel('发动机总效率 [%]', fontsize=11)
    ax4.set_title('回热器效率对发动机性能的影响', fontsize=12, fontweight='bold')
    ax4.legend(loc='best', fontsize=9)
    ax4.grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('case5_stirling_engine.png', dpi=150, bbox_inches='tight')
    plt.close()
    
    print("✓ 案例5完成,结果保存至 case5_stirling_engine.png")
    
    # 打印关键结果
    print(f"\n关键结果:")
    for name, data in results.items():
        print(f"  {name}:")
        print(f"    卡诺效率: {data['eta_carnot']*100:.1f}%")
        print(f"    实际效率: {data['eta_actual']*100:.1f}%")
        print(f"    效率比: {data['eta_actual']/data['eta_carnot']*100:.1f}%")
    
    return results


# =============================================================================
# 案例6:能源系统综合优化
# =============================================================================

def case6_system_optimization():
    """案例6:能源系统综合优化"""
    print("\n" + "="*70)
    print("案例6:能源系统综合优化")
    print("="*70)
    
    # 太阳能集热系统优化
    print("\n--- 太阳能集热系统优化 ---")
    
    # 优化目标:在给定DNI和温度要求下,最大化集热效率
    def objective_trough(params):
        """优化目标函数(负效率,用于最小化)"""
        focal_length, coating_alpha, coating_eps = params
        
        # 约束检查
        if not (0.5 <= focal_length <= 3.0):
            return 100
        if not (0.85 <= coating_alpha <= 0.98):
            return 100
        if not (0.03 <= coating_eps <= 0.25):
            return 100
        if coating_alpha / coating_eps < 5:  # 选择性比约束
            return 100
        
        coating = SelectiveCoating(alpha_solar=coating_alpha, 
                                  epsilon_thermal=coating_eps)
        collector = ParabolicTroughCollector(
            aperture_width=5.0,
            focal_length=focal_length,
            length=100.0,
            receiver_diameter=0.07,
            coating=coating
        )
        
        T_in = 50 + 273.15
        T_out = 350 + 273.15
        T_ambient = 298.15
        DNI = 900
        
        eff_data = collector.thermal_efficiency(
            T_in, T_out, T_ambient, DNI, 2.0, 2.0
        )
        
        # 返回负效率(用于最小化)
        return -eff_data['eta_thermal'] * 100
    
    # 使用网格搜索进行优化
    print("  正在优化槽式集热器参数...")
    
    best_eff = -100
    best_params = None
    
    focal_range = np.linspace(0.8, 2.5, 10)
    alpha_range = np.linspace(0.88, 0.97, 5)
    eps_range = np.linspace(0.04, 0.20, 5)
    
    for f in focal_range:
        for alpha in alpha_range:
            for eps in eps_range:
                params = [f, alpha, eps]
                eff = -objective_trough(params)
                if eff > best_eff:
                    best_eff = eff
                    best_params = params
    
    print(f"  最优参数: 焦距={best_params[0]:.2f}m, 吸收率={best_params[1]:.3f}, 发射率={best_params[2]:.3f}")
    print(f"  最优效率: {best_eff:.2f}%")
    
    # 炉膛系统优化
    print("\n--- 炉膛系统优化 ---")
    
    # 帕累托前沿分析:效率 vs 成本
    designs = []
    
    # 不同炉膛温度设计
    for T_gas in [1200, 1400, 1600, 1800]:
        furnace = FurnaceRadiation(
            furnace_height=10.0,
            furnace_width=5.0,
            furnace_depth=5.0,
            wall_emissivity=0.8
        )
        
        result = furnace.calculate_heat_transfer(
            T_gas, 800, 1.0, 0.08, 0.16
        )
        
        # 简化成本模型(高温材料成本更高)
        cost = 100 + 0.05 * T_gas  # 相对成本
        
        designs.append({
            'T_gas': T_gas,
            'efficiency': result['eps_eff'],
            'heat_flux': result['q_rad'],
            'cost': cost
        })
    
    # 绘制帕累托前沿
    fig, axes = plt.subplots(2, 2, figsize=(14, 10))
    
    # 图1:帕累托前沿(效率-成本)
    ax1 = axes[0, 0]
    effs = [d['efficiency'] for d in designs]
    costs = [d['cost'] for d in designs]
    temps = [d['T_gas'] for d in designs]
    
    scatter = ax1.scatter(costs, effs, c=temps, cmap='hot', s=200, edgecolors='black')
    
    # 标注
    for i, d in enumerate(designs):
        ax1.annotate(f"{d['T_gas']}K", (d['cost'], d['efficiency']), 
                    textcoords="offset points", xytext=(5, 5), fontsize=9)
    
    ax1.set_xlabel('相对成本 [-]', fontsize=11)
    ax1.set_ylabel('有效发射率 [-]', fontsize=11)
    ax1.set_title('炉膛设计帕累托前沿', fontsize=12, fontweight='bold')
    ax1.grid(True, alpha=0.3)
    cbar1 = plt.colorbar(scatter, ax=ax1)
    cbar1.set_label('炉膛温度 [K]', fontsize=10)
    
    # 图2:集热器焦距优化
    ax2 = axes[0, 1]
    
    focal_lengths = np.linspace(0.5, 3.0, 30)
    efficiencies_focal = []
    
    for f in focal_lengths:
        params = [f, 0.95, 0.10]
        eff = -objective_trough(params)
        efficiencies_focal.append(eff)
    
    ax2.plot(focal_lengths, efficiencies_focal, 'b-', linewidth=2)
    ax2.axvline(x=best_params[0], color='r', linestyle='--', 
               linewidth=2, label=f'最优值 f={best_params[0]:.2f}m')
    ax2.set_xlabel('焦距 [m]', fontsize=11)
    ax2.set_ylabel('集热效率 [%]', fontsize=11)
    ax2.set_title('焦距对集热效率的影响', fontsize=12, fontweight='bold')
    ax2.legend(loc='best', fontsize=9)
    ax2.grid(True, alpha=0.3)
    
    # 图3:选择性比优化
    ax3 = axes[1, 0]
    
    selectivity_range = np.linspace(5, 25, 20)
    efficiencies_sel = []
    
    for sel in selectivity_range:
        # 固定吸收率,调整发射率
        alpha = 0.95
        eps = alpha / sel
        if eps < 0.03:
            eps = 0.03
        
        params = [1.5, alpha, eps]
        eff = -objective_trough(params)
        efficiencies_sel.append(eff)
    
    ax3.plot(selectivity_range, efficiencies_sel, 'g-', linewidth=2)
    ax3.set_xlabel('选择性比 α/ε [-]', fontsize=11)
    ax3.set_ylabel('集热效率 [%]', fontsize=11)
    ax3.set_title('选择性比对集热效率的影响', fontsize=12, fontweight='bold')
    ax3.grid(True, alpha=0.3)
    
    # 图4:综合优化结果雷达图
    ax4 = axes[1, 1]
    
    categories = ['效率', '成本', '可靠性', '维护性', '环保性']
    N = len(categories)
    
    # 三种方案
    values_csp = [0.85, 0.60, 0.75, 0.70, 0.90]  # 太阳能
    values_furnace = [0.70, 0.80, 0.85, 0.75, 0.50]  # 炉膛
    values_stirling = [0.75, 0.50, 0.65, 0.60, 0.85]  # 斯特林
    
    angles = np.linspace(0, 2 * np.pi, N, endpoint=False).tolist()
    values_csp += values_csp[:1]
    values_furnace += values_furnace[:1]
    values_stirling += values_stirling[:1]
    angles += angles[:1]
    
    ax4 = plt.subplot(2, 2, 4, polar=True)
    ax4.plot(angles, values_csp, 'o-', linewidth=2, label='太阳能CSP', color='#e74c3c')
    ax4.fill(angles, values_csp, alpha=0.25, color='#e74c3c')
    ax4.plot(angles, values_furnace, 's-', linewidth=2, label='工业炉膛', color='#3498db')
    ax4.fill(angles, values_furnace, alpha=0.25, color='#3498db')
    ax4.plot(angles, values_stirling, '^-', linewidth=2, label='斯特林', color='#2ecc71')
    ax4.fill(angles, values_stirling, alpha=0.25, color='#2ecc71')
    
    ax4.set_xticks(angles[:-1])
    ax4.set_xticklabels(categories, fontsize=10)
    ax4.set_ylim([0, 1])
    ax4.set_title('能源系统综合评估', fontsize=12, fontweight='bold', pad=20)
    ax4.legend(loc='upper right', bbox_to_anchor=(1.3, 1.0), fontsize=9)
    
    plt.tight_layout()
    plt.savefig('case6_system_optimization.png', dpi=150, bbox_inches='tight')
    plt.close()
    
    print("✓ 案例6完成,结果保存至 case6_system_optimization.png")
    
    return designs, best_params


# =============================================================================
# 主程序
# =============================================================================

def main():
    """主函数:运行所有案例"""
    print("\n" + "="*70)
    print("主题094:辐射换热在能源系统中的应用")
    print("Python仿真程序")
    print("="*70)
    
    # 运行所有案例
    results1 = case1_trough_collector_performance()
    results2 = case2_heliostat_field()
    results3 = case3_furnace_radiation()
    results4 = case4_combustion_gas_radiation()
    results5 = case5_stirling_engine()
    results6 = case6_system_optimization()
    
    print("\n" + "="*70)
    print("所有案例仿真完成!")
    print("="*70)
    print("\n生成的图像文件:")
    print("  1. case1_trough_collector.png - 槽式集热器性能分析")
    print("  2. case2_heliostat_field.png - 定日镜场光学模拟")
    print("  3. case3_furnace_radiation.png - 炉膛辐射传热")
    print("  4. case4_combustion_gas.png - 燃烧气体辐射特性")
    print("  5. case5_stirling_engine.png - 斯特林发动机循环分析")
    print("  6. case6_system_optimization.png - 能源系统综合优化")
    print("\n" + "="*70)


if __name__ == "__main__":
    main()

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐