MCM E题一出,我们最关注的往往不是“怎么套算法”,而是这道题到底希望我们交付什么。2026年MCM问题E的被动式太阳能遮阳,听起来是个工程题,实际上是一道典型的“多目标优化+仿真评估”题。凡是涉及能源、建筑、可持续方向的E题,评委真正想看到的是三样东西:物理过程建模是否干净、评价指标是否可解释、方案对比是否有说服力。这篇就把我从题目解读到模型、代码、图表的一整套思路分享出来,适合还在找方向的队伍拿来做脚手架,也适合已经完成一版模型、想查缺补漏的队伍对照检查。
1. 题目核心与出题人真正想考验什么
1.1 先想清楚“被动式”三个字的分量
被动式太阳能遮阳,重点在“被动”。这意味着系统不能依赖传感器、电机、智能控制,而是靠建筑构件本身的形态去调节阳光。常见形式包括水平挑檐、垂直遮阳板、固定角度百叶、外置格栅,甚至绿化遮阳。这不是让我们设计一个自动跟踪太阳的装置,而是要在一个静态或半静态的方案里,通过几何设计、材料选择和布局安排,实现冬夏两季的平衡。
很多队伍一开始容易跑偏,直接上深度学习和人工智能做“预测”,或者设计一套复杂的动态控制策略。评委看到这种东西并不买账,因为E题的核心是可持续性评估和设计决策,不是机器学习调参。你要解决的是一个拥有清晰物理边界的工程优化问题:建筑朝向、遮阳构件的尺寸、角度、位置,这些设计变量是怎么影响能耗和舒适度的。
所以第一步不是写代码,而是把题目里那些模糊的说法拆成可计算的物理量。被动式太阳能遮阳要处理的矛盾是:夏天要挡住强烈的直射阳光,减少空调负荷;冬天又要让低角度的阳光尽可能进入室内,减少采暖负荷。同一个构件,夏天是帮手,冬天可能就成了障碍。这个内在矛盾决定了模型必须带时间维度,不能只看单一时刻的遮阳效果。
1.2 把评价指标转成可对比的数字
美赛评委会看你的模型是否有“可比较的结果”。如果全篇只有“舒适度提升”“能耗降低”这种定性描述,分数一定不高。我们需要把遮阳方案的影响量化成几个核心指标。
| 一级指标 | 二级指标 | 计算方法示例 | 数据需求 |
|---|---|---|---|
| 节能性能 | 夏季制冷负荷削减率 | 对比无遮阳工况与有遮阳工况的累计得热 | 逐时太阳辐射、遮阳系数 |
| 冬季性能 | 采暖期太阳得热保持率 | 有遮阳工况冬季得热/无遮阳工况冬季得热 | 逐时太阳位置与直射辐射 |
| 采光质量 | 有效采光系数 | 遮阳后可见光透过面积占比 | 窗地比、构件几何参数 |
| 舒适度 | 室温超温时数 | 模拟室温超过舒适区间上限小时数 | 建筑热容、墙体和窗户传热系数 |
这些指标不需要很高深的公式,但必须能解释清楚。我的建议是,在正式建模前先自己拟定一套这样的指标体系,然后回到题目原文逐句核对:有没有遗漏题干里强调的维度?比如有些赛题会特别提到“不同国家和地区的气候差异”“建筑密集型城市还是独栋住宅”,这些都会影响指标权重。
1.3 锁定输入输出边界,避免被题目带偏
E题的信息量不小,如果每个细节都做,四天时间根本不够。我见过不少队伍花了一天收集墙体材料库、研究窗户多层玻璃热工参数,结果模型主体还没搭完。正确做法是尽早确定边界条件。
输入侧通常分为三类。气候数据:包括逐时的太阳直射辐射、散射辐射、温度和风速;建筑参数:窗户尺寸、朝向、墙体传热系数、室内热容;遮阳参数:构件类型、悬挑长度、间距、倾角、表面反射率。输出侧则是一组可以用于决策的结果,比如最优遮阳板长度范围、不同朝向房间的建议遮阳策略、全年能耗对比图。
边界之外的东西可以提,但不要建模进去。比如室内人员行为、家电散热,可以简化为固定热源。如果题目没有明确要求做成本分析,就不要自己套一个复杂的经济模型。边界清晰,后面做灵敏度分析才有抓手。
2. 建模思路拆解:从太阳几何到综合目标函数
2.1 先搭太阳几何模型,所有计算的地基
做太阳能遮阳,不可能绕开太阳位置计算。遮阳构件的有效性完全取决于某个时刻太阳从哪个方向照过来,以及构件的投影落在哪里。太阳位置计算有很多现成方案,NASA的SPA算法精度很高,但代码量大;再不行还能用astral库直接读,但我建议自己手写一个简化版,因为美赛论文需要给出完整的数学公式,用黑盒库很难展开写作。
这里给出一套精度够用的简化公式。先计算年积日doy,再利用一个常见的年均赤纬近似式:
delta = 0.006918 - 0.399912 * cos(B) + 0.070257 * sin(B) - 0.006758 * cos(2B) + 0.000907 * sin(2B) - 0.002697 * cos(3B) + 0.00148 * sin(3B)
其中B = 2 * pi / 366 * (doy - 81)。这个公式的误差在1度以内,对遮阳比计算的影响可以忽略。时角H则要考虑当地经度与标准时区中心经度的差:每偏差1度经度,太阳时大约偏移4分钟。
有了赤纬角delta、纬度lat和时角H,太阳高度角alpha就是:
sin(alpha) = sin(lat) * sin(delta) + cos(lat) * cos(delta) * cos(H)
太阳方位角gamma可以用余弦公式计算,注意判断上午还是下午,并修正象限。这两个角度出来后,后面所有遮阳几何遮蔽计算都能接上。队伍里最好安排一个人专门核对公式正负号,我第一次写的时候把纬度正弦和余弦写反,结果北半球的夏天太阳跑到北边去了,数据怎么画都不对。
2.2 遮阳构件的几何遮蔽模型
有了太阳位置,下一步是算“窗户到底被遮了多少”。不同构件类型,投影关系不同。拿最常见的水平遮阳板举例:一块宽度为P的水平板安装在窗户顶部,太阳高度角为alpha,太阳方位角与窗户法向的夹角为phi,那么窗面垂直方向上的遮蔽深度为:
D = P * tan(alpha) / cos(phi)
这个D指遮阳板下沿在窗面上的投影距离。窗户高度为H_win,那么竖直方向的遮蔽比为min(1, D / H_win)。注意cos(phi)不能直接当零处理,接近90度时投影趋于无穷,但实际中太阳高度角较低,或者阳光从侧面斜射,效果往往没那么极端。建议加一个角度阈值,超出可接受范围就裁剪为“侧面无遮蔽”。
垂直遮阳板的计算方式同理,只是把高度角换成方位角差,把P换成垂直板外伸长度。这个模型不复杂,但公式一定要在论文里画图展示清楚。评审一眼就能看出你的几何关系是否扎实。我习惯在论文里放一张“遮阳构件剖面几何关系示意图”,用简单的三角函数标注,不需要渲染得很炫酷,清晰即可。
2.3 建筑得热与室温变化的准稳态模型
遮阳的最终效果要落到建筑能耗或室内温度上。这里推荐一个准稳态热平衡模型,不要一上来就做CFD或者EnergyPlus级别的仿真,美赛四天做不完。简化思路是:窗户得热加上墙体传热、室内热源,减去通风散热,等于室内温度的变化。
对每个时刻t,室内温度变化可以写成:
C_zone * dT/dt = Q_solar(透过窗户的太阳辐射得热) + Q_wall(墙体传热) + Q_int(室内热源) - Q_vent(通风换气耗热) - UA_total * (T_zone - T_out)
其中C_zone是室内等效热容,代表地板、家具和空气共同的热惯性。UA_total是外围护结构的总传热系数乘以面积。太阳辐射得热项要拆成直射和散射两部分:直射部分被遮阳系数削减,散射部分只受构件遮挡系数影响,可以单独计算玻璃的透射率。
这个模型的优点是参数少、物理意义明确、能体现热惯性带来的时间滞后效果。比如白天太阳晒进来的热量,墙体吸收后到傍晚才释放,这种非线性特征是纯稳态模型模拟不出来的。把时间步长设为1小时,用欧拉法迭代,跑一整年的逐时数据没问题。
2.4 综合目标函数:把三个指标揉在一起
模型搭好后,要回答题目最关心的问题:什么样的遮阳方案最好?这时就需要一个目标函数。我的建议是不做加权平均的“综合评分”,容易被人质疑权重怎么来的。更好的做法是把问题展示成多目标优化,然后把非支配解画成帕累托前沿。
但简化版目标函数也可以写,关键是要说清楚权重来源。比如:
Score = w1 * cooling_load / cooling_load_base + w2 * (1 - heating_gain / heating_gain_base) + w3 * daylight_penalty
这里cooling_load_base和heating_gain_base都是无遮阳基准工况的值,用于归一化。daylight_penalty是当遮阳导致室内采光系数低于某个阈值时增加的惩罚项。权重w1, w2, w3可以通过层次分析或者简单专家打分赋值,但在论文里要专门做一段参数敏感性分析,说明权重变化不会改变最优解的区间。
我见过最强的队伍把目标函数做成了“全年不舒适度权重”,不同季节的权重不同,比如夏季过热惩罚大于冬季略微欠热,这就更贴近真实居住体验。这种细节是加分项。
3. 代码实现:从太阳位置到遮阳方案优化
3.1 代码的整体分工
我们队伍的代码一般拆成三个模块:太阳位置计算、遮阳遮蔽与得热模拟、参数扫描与可视化。三个模块分别对应论文的三个核心公式。不要把所有代码都塞进一个脚本里,最后修改起来很痛苦,命名信息量也差。
我提供一个可直接扩展的代码框架,大家可以根据赛题实际情况替换参数。
3.2 太阳位置计算实现
先用纯numpy写一套太阳位置计算函数,不依赖外部天文库,方便论文直接写公式。
import numpy as np def day_of_year(month, day): # 平年近似,闰年可以忽略差异 days_in_month = np.array([31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]) return int(days_in_month[:month-1].sum()) + day def solar_declination(doy): B = 2 * np.pi / 366.0 * (doy - 81) decl = (0.006918 - 0.399912 * np.cos(B) + 0.070257 * np.sin(B) - 0.006758 * np.cos(2*B) + 0.000907 * np.sin(2*B) - 0.002697 * np.cos(3*B) + 0.00148 * np.sin(3*B)) return decl # 弧度 def solar_position(lat_deg, lon_deg, month, day, hour, tz=8): """ 输入: 纬度(度), 经度(度), 月, 日, 小时(真太阳时近似) 输出: 高度角(rad), 方位角(rad) """ doy = day_of_year(month, day) decl = solar_declination(doy) lat = np.radians(lat_deg) # 时角: 以太阳时中午为0,每小时15度 solar_noon_offset_hour = (lon_deg - tz * 15.0) / 15.0 hour_angle = np.radians((hour - 12.0 - solar_noon_offset_hour) * 15.0) sin_alt = (np.sin(lat) * np.sin(decl) + np.cos(lat) * np.cos(decl) * np.cos(hour_angle)) sin_alt = np.clip(sin_alt, -1, 1) alt = np.arcsin(sin_alt) cos_az = ((np.sin(decl) - np.sin(alt) * np.sin(lat)) / (np.cos(alt) * np.cos(lat) + 1e-8)) cos_az = np.clip(cos_az, -1, 1) az = np.arccos(cos_az) # 根据时角方向恢复正负:上午太阳在东,下午在西 if hour_angle < 0: az = -az return alt, az注意,这段代码用的是真太阳时的近似处理,没有做均时差校正。如果题目对时间精度要求高,可以再补一个校正项。实际运行中我发现,忽略均时差导致的误差只在每天清晨和傍晚明显,对月度级能耗评估影响很小,可以接受。
3.3 遮阳遮蔽比与室内得热模拟
这一部分是把几何遮蔽和热模型串起来。我以一个朝南窗户、水平遮阳板为例,逐小时计算整年的遮蔽比和太阳得热。
def shading_ratio_horizontal(window_height, overhang_depth, sun_alt, sun_azimuth, window_normal_azimuth): """ 计算水平遮阳板对矩形窗户的垂直遮蔽比。 window_normal_azimuth: 窗户法向的方位角,南向为0。 """ # 太阳方位与窗户法向的夹角 phi = sun_azimuth - window_normal_azimuth cos_phi = np.cos(phi) # 太阳高度角过低时,直接认为无阴影遮挡限制 if sun_alt <= 0: return 0.0 if abs(cos_phi) < 0.15: # 侧面掠射时按无遮蔽处理,保留一点下限,避免数值异常 projection = overhang_depth * np.tan(sun_alt) / 0.15 else: projection = overhang_depth * np.tan(sun_alt) / cos_phi shading = min(1.0, max(0.0, projection / window_height)) return shading实际的全年得热模拟就是把一年8760个小时全跑一遍:
def annual_heat_gain(climate_data, lat, lon, window_width, window_height, overhang_depth, window_shgc, u_wall, area_wall): total_cooling_energy = 0.0 total_heating_gain = 0.0 for row in climate_data: month, day, hour, temp_out, irradiance_direct, irradiance_diffuse = row sun_alt, sun_az = solar_position(lat, lon, month, day, hour) # 遮蔽比 shade = shading_ratio_horizontal( window_height, overhang_depth, sun_alt, sun_az, window_normal_azimuth=0.0 ) # 直射辐射受遮挡,散射辐射仅部分遮挡 direct_gain = irradiance_direct * window_width * window_height * window_shgc * (1 - shade) diffuse_gain = irradiance_diffuse * window_width * window_height * window_shgc * 0.6 # 墙体传热(简化用温差乘以UA) wall_gain = u_wall * area_wall * (temp_out - 26) total_cooling_energy += max(0, direct_gain + diffuse_gain + wall_gain) total_heating_gain += max(0, -wall_gain - direct_gain) return total_cooling_energy, total_heating_gain这段代码没有做室温动态迭代,而是直接用“等效冷负荷”汇总,优点是代码简单、跑得快,适合参数扫描。如果你想要动态室温曲线,那就把C_zone * dT/dt方程补进去,但扫描方案时会慢很多。我的建议是先用这个简化版本定出大致最优区间,再针对少数候选方案跑一次完整动态模拟,两种结果放到论文里互相验证。
3.4 参数扫描与可视化
被动式遮阳方案的参数空间并不大,无非是遮阳板深度、倾角、间距、材料反射率。对南向窗户,我会对遮阳板深度从0到1.2米做扫描,步长0.05米,画出“夏季制冷负荷”和“冬季采暖得热”的关系曲线,观察是否存在拐点。
depths = np.linspace(0, 1.2, 25) cooling = [] heating = [] for d in depths: c, h = annual_heat_gain(climate_data, lat, lon, window_width=2.0, window_height=1.5, overhang_depth=d, window_shgc=0.6, u_wall=1.0, area_wall=8.0) cooling.append(c) heating.append(h)画图时用双纵轴,左侧是夏季制冷负荷,右侧是冬季采暖得热,x轴是遮阳板深度。这样能直观看到“过了某个深度后,夏季下降变缓但冬季损失加速”,两个趋势交叉的区域就是最优区间。如果队伍想上点难度,可以再做两层正交实验,分析深度和安装倾角的交互效应,用热力图展示。这个图做出来,基本就是论文的结果图了。
4. 论文写作与图表设计要点
4.1 摘要:五句话讲清整个模型链
美赛论文摘要的信息密度决定第一印象。E题这种多阶段建模题,摘要必须按顺序交代清楚:干什么、用什么方法、得到什么结论、方案是否稳健、能为设计决策提供什么建议。不要在摘要里堆算法名字,而是突出“遮阳性能评估模型”和“策略对比结论”。
我建议摘要按这个结构写:第一句点明被动式太阳能遮阳的设计与评估问题;第二句交代基于太阳几何的逐时遮阳计算和建筑热平衡模型;第三句给出关键结果,比如某朝向窗户在当前气候下推荐遮阳板深度为0.6到0.8米,相比无遮阳工况夏季冷负荷减少28%;第四句说明对反射率、朝向的敏感性分析结论;第五句落到实际应用,说明该模型可以推广到多气候区比选。摘要写完后再回头修改,确保每句话都有数据支撑,不出现空洞形容词。
4.2 图表:每张图只让评委看一个结论
评审翻论文的速度可能比想象中快,图表能不能在10秒内传递信息很重要。画图的第一原则是一张图只说一件事。全年温度曲线是一张图,遮阳比随季节变化是另一张图,不要塞在一起。
其次,坐标轴必须有明确单位和刻度范围。很多队伍画出来的图坐标轴数字挤成一团,或者没有图例。我们每次交稿前都会做“盲测”:让一个没参与建模的队友只看图和图注,能不能复述出结论。如果能,图就合格了。
遮阳类题目有几类图是加分项:三维遮阳构件几何示意图、全年8760小时热负荷热力图、不同朝向房间的柱状对比图、帕累托前沿散点图。其中热力图最容易出效果,横轴是月份、纵轴是不同遮阳深度,颜色表示月度累计制冷负荷,一页纸就能看出季节和设计参数的交互关系。
4.3 灵敏度分析与模型鲁棒性:E题评分的重要分水岭
很多队伍模型做得不错,但缺少对“模型结论是否可靠”的验证。被动式遮阳模型里最容易被质疑的参数包括玻璃SHGC值、墙体UA值、室内热容、气候数据来源。这些参数随便改一点,推荐方案会不会就变了?
建议做三层灵敏度分析。第一层是单参数扰动:每次把一个参数上下调10%,观察最优深度区间是否稳定;第二层是极端气候对比:选择连续高温年、连续低温年或典型年数据,看推荐方案是否还能保持优势;第三层是权重扰动:如果用了多目标加权,把夏季和冬季的权重从0.7比0.3调整到0.5比0.5,看最优解排序是否变化。
如果结论在参数扰动下仍然指向同一个区间,论文里就可以底气十足地写“设计建议对参数波动不敏感”。如果敏感度高,也不要慌,把灵敏度图放进来,说明该地区应优先确保某个参数准确,这也是评委喜欢的分析深度。
5. 常见问题与避坑清单
5.1 赛程时间分配:三天半其实很紧张
E题完整工作量比我预想的大,尤其是如果队伍想认真做参数扫描和结果分析。我给出一份可行的时间计划表,来自我带过多届队伍后的经验。
| 时间段 | 任务 | 关键产出 |
|---|---|---|
| 第一天上午 | 解读题目,圈定边界,确定指标体系 | 模型框架图和问题重述 |
| 第一天下午 | 建立太阳几何模型和遮阳几何公式 | 公式推导和示意图 |
| 第二天上午 | 完成代码的太阳位置和遮蔽模块 | 能跑通的初步结果 |
| 第二天下午 | 加入热平衡模型,跑基准工况 | 无遮阳与有遮阳对比图 |
| 第三天上午 | 参数扫描和优化 | 最优区间图和灵敏度热力图 |
| 第三天下午 | 撰写结果分析、模型评价、优缺点 | 论文主体 |
| 第四天上午 | 摘要打磨、英文润色、统一图表 | 完整初稿 |
| 第四天下午 | 内部盲审、查公式错漏、打包提交 | 终稿 |
我见过最可惜的情况是某支队伍第二天晚上还在调太阳位置公式,第三天下午才开始写论文,最后摘要只有两句话。代码跑通不代表工作完成,留出整块时间写“结果解释”才是拿分核心。
5.2 失分点速查:代码、单位和论述脱节
下面这些错误是我在阅卷和模拟评审中反复看到的。
- 单位混乱:辐射量有时用MJ/m²,有时用kWh/m²,图表里却没标注。统一换算成kWh/m²,论文全篇只用一个单位。
- 太阳位置公式符号错误:南半球和北半球混用,或者上午下午方位角没有区分。必须用一组已知日期做验证,比如春分日太阳从正东升起、正西落下。
- 代码和论文脱节:论文里写了一套公式,代码里却是另一套参数,评审对不上。正式提交前把代码里关键变量名和论文符号列一张对照表,既能查错,也方便附录展示。
- 遮阳比计算忽略了散射辐射:直射被遮挡不代表散射也被完全遮挡,忘记区分会导致夏季负荷被高估。
- 结论没有“可操作性”:写“遮阳板越长越好”不如写“推荐深度为0.6米至0.8米区间,夏季冷负荷可降低28%,冬季热损失仅增加9%”。
5.3 现场调试手卡:跑数据前必查的五个点
最后分享一个现场调试检查清单。每支队伍跑年度模拟之前,花十分钟问自己五个问题:太阳高度角在中午是不是最高?太阳方位角在上午是否为负、下午为正?无遮阳工况的夏季得热是否远大于冬季?遮阳板深度为零时结果是否与基准重合?极端深度(比如10米)时夏季得热是否接近零?如果这些逻辑自洽,代码基本可信。如果有一项对不上,多半不是模型的问题,而是符号或单位的问题,赶紧回头查,不要硬往下跑。
说实话,连续带过几届E题队伍之后,我的体会是:漂亮复杂的算法不会让E题自动高分,真正拉开差距的是模型逻辑的完整性和结果解释的深度。被动式太阳能遮阳的物理过程并不难,难的是用一组清晰可复现的公式,把“冬天要阳光、夏天要阴凉”这个矛盾量化成可比较的方案。只要前期把边界定好、把公式验证过、把结果图画明白,这个题目就是一道性价比很高的E题,也是最能体现工程建模基本功的题目。