光热电站前期设计阶段,储热容量是最难拍板的一个参数。我现在还记着几年前做项目对接时,对方拿着设计院给的“按汽轮机额定功率配置6小时储热”建议,问我们能不能直接照这个走。我当时就问了一句:你们上网电价曲线什么形状?配了储热之后是白天停机晚上发电,还是白天边发边储?对方愣了一下,然后我们花了两周把容量配置问题和调度问题捆在一起重新建模,结果最优容量比6小时少了1.5小时,但项目IRR反而提升了。这件事给我的教训是:光热电站的储热容量优化,本质上不是算“热容量”的数学题,而是算“调度经济性”的博弈题。这篇内容就围绕这个主题展开,说一下我在做光热电站储热容量优化配置代码时用到的方法、踩过的坑,以及可以直接复用的建模思路。
1. 为什么储热容量是“算”出来的,不是“拍”出来的
1.1 光热电站的储热到底在扮演什么角色
光热电站和光伏最大的区别,就是它能用熔盐或者其他介质把太阳能以热能形式存下来,而不是直接变成电。一个典型的光热电站包括集热场、换热系统、储热系统、汽轮发电机组和辅助系统。白天集热场吸收太阳辐射加热导热油或熔盐,一部分热能直接送去发电,另一部分存进储热罐;到了晚上或者多云时段,再从储热罐放出热量维持发电。
这个概念说出来大家都懂,但真正做项目时,储热容量的影响远比“晚上能多发几个小时”要大。储热容量改变了电站一天之内的可调度范围,也改变了它参与电网调峰、跟踪负荷的能力。换句话说,储热容量决定了光热电站是“靠天吃饭”的电源,还是能主动选择发电时段的电源。
用一个生活化类比:储热罐像一个“热力充电宝”。充电宝容量大小直接决定你能把多少能量搬到晚上用。买小了,晚高峰发不了多久,白天的热量可能被弃掉;买大了,罐子和配套换热器投资沉在里面,一年可能只用满几次。更关键的是,充电宝容量还会影响你的使用习惯——容量大的时候你会喜欢早上充满、晚上慢慢放,容量小的时候你只敢在电价最高那几个小时放,运行逻辑完全不同。所以在代码里把储热容量当作一个独立常数塞进去跑调度,本身就是错的。
1.2 调度经济性:储热容量设计的“裁判”
调度经济性这个说法,听起来有点绕,但落到项目上就是一句话:在给定的电价机制和并网要求下,光热电站通过调整自身发电时段、出力大小和启动停机策略,能获得的最大净收益是多少。储热容量不是越大越好,也不是越小越好,而是要让投资成本增量与运行收益增量之间取得平衡。
很多人做容量优化时,第一反应是最大化年发电量。这在固定上网电价、没有任何峰谷差异的模型里成立,但现实中的电价曲线往往有峰谷平之分,有些地方还要求光热电站参与早晚高峰调节。如果只追求发电量,储热容量可能会配得很大,但多出来的电量都落在平价甚至谷价时段,收益上不去,投资却实打实花出去了。反过来,如果储热容量配得太小,高峰时段能转移过来的电量有限,电站只能低价卖电,收益又少一块。
从代码角度看,调度经济性体现在目标函数的运行收益项里,但这项值不是独立存在的,它依赖于储热容量给调度模型提供的“自由度”。容量变量通过约束条件改变了可行域的形状,进而改变了最优运行策略。这就是为什么我们在代码里要把容量变量和运行变量放在同一个优化问题里求解,而不是先定容量再算调度。
1.3 容量决策与运行决策必须联立求解
把容量优化和调度优化拆成两层的做法,在工程上很常见:外层枚举或者启发式搜索容量,内层对每个容量做一次全周期调度优化。听起来逻辑通顺,但实际跑起来问题很多。外层容量稍微变一点,内层最优调度的“策略形状”就会变,收益曲线往往不是凸的,甚至会有几个局部最优峰。你用断点枚举或者简单的智能算法去搜,很容易卡在局部最优里。
举个例子,容量取5小时的时候,最优调度可能是中午边发边充,晚高峰满发;容量取6小时的时候,由于白天光场产热不够把罐子充满,最优调度变成了白天少发、集中储热,晚高峰继续满发。这两种模式的边际收益不一样,反映到目标函数上就是非线性跳跃。如果外层只按固定步长枚举,比如4、5、6、7小时,很可能漏掉5.5小时附近那个更优区间。
所以在代码实现上,我更倾向于把容量变量作为决策变量放进约束里,让求解器在全局可行域内同时搜索容量和运行策略。这样一来,储热容量不是“先定好再用”,而是“算出来的”,它与调度经济性形成了一个整体优化问题的两个侧面。这也是本文后续所有建模思路的出发点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 优化建模:先把目标函数写对
2.1 目标函数:成本与收益之间的“平衡账”
储热容量优化配置的目标函数,往大了说是项目全生命周期净收益最大化,往小了说可以写成等年值成本最小化。我习惯用等年值形式,因为光热电站项目周期长,储热设备寿命和电站主体寿命不一定一致,直接用一次性投资对比收益很吃亏。
等年值化的核心是把投资成本折算到每一年,再和年度运行收益放在同一个时间刻度上比较。公式可以写成:
min C_CRF × c_tes × E_tes + c_om × E_tes
