热电联产机组联合优化控制:储热罐+电锅炉实现风电最大化消纳

发布时间:2026/9/11 7:18:56
热电联产机组联合优化控制:储热罐+电锅炉实现风电最大化消纳 每年供暖季一过做电力调度和新能源消纳项目的人基本上都要忙活一阵。原因很简单热电厂一旦背上供热任务发电曲线就被“绑架”了风电来了也送不出去只能眼睁睁看着弃风。最近我把一套“风电最大化消纳的热电联产机组联合优化控制”完整跑了下来从模型搭建到Matlab代码实现再到多场景对比踩了不少坑也攒了不少经验。这篇就围绕这个项目把整套思路、模型细节、代码要点和调试心得一次讲清楚给正在做电力系统优化调度、热电联产或者新能源消纳方向的朋友一个可以直接参考的底稿。这个项目解决的是什么问题呢一句话概括就是在保证热负荷供需平衡的前提下通过协调火电机组、热电联产机组、储热罐和电锅炉最大限度提高风电并网功率、降低弃风率。适合的人群很明确电气工程和能源动力方向的研究生、做电网调度或综合能源系统规划的工程师以及想快速上手Yalmip建模做优化调度的同学。内容不追求顶刊级别那么复杂的模型而是先把主干逻辑打通让你能跑通结果、看懂输出、知道接下来往哪个方向加复杂度。1. 项目概述与整体思路1.1 “以热定电”到底卡在哪里国内“三北”地区的供暖期长热电厂承担着主要的供热任务。传统热电联产机组运行时电出力和热出力之间存在强耦合关系简单说就是你让它多发点热它必须跟着多发点电这个电没法“只发一部分”。这就导致一个问题冬季夜间热负荷依然很大机组为了供热被迫维持较高电出力而此时电网负荷恰恰处于低谷风电又在夜间往往是大发时段风电上网空间被高电出力的热电机组挤占电网只能选择弃风。这就是业内常说的“以热定电”困局。很多人第一次接触这个概念时不太理解我常用一个类比来解释热电联产机组就像一个既要做饭又要发传单的兼职员工他接了一个做100份盒饭的活就必须同时跑出去发对应数量的传单没得商量。风电则像一个只发传单不干活的人想多干点活但兼职员工已经占了太多发传单的份额只能闲着。所以问题的根源不在风电本身而在热电耦合约束。这种强耦合会让电网的可调空间变得非常小。常规火电可以压低出力到额定容量的40%左右部分深度调峰机组能压到30%但热电机组在供热期最小电出力往往被抬到额定容量的60%到70%。你在调度台前看着风电曲线往上涨热电机组的最小技术出力却纹丝不动那种无力感做过调度的人应该都懂。1.2 打破热电耦合的三条主流路线要想把风电消纳空间撑开工程上主要有三种手段思路都是直接或间接“解耦”热电关系。第一种是加储热罐。储热罐的作用相当于一个热量缓冲池在热负荷较低的时段让热电机组多发一些热存进罐里同时多发一些电来给风电让路在热负荷较高的时段再从罐里放热减轻机组供热压力。这么一来机组的电出力和热负荷就不需要时时绑定了灵活性大大增加。第二种是上电锅炉。电锅炉直接消耗电能转化为热能它提供了一条全新的“电转热”通道。风电大发、电网难以消纳时把多余风电引到电锅炉电变成热热再进入热网或储热系统相当于给风电找了一个消纳出口。第三种是火电深度调峰。通过改造机组燃烧系统或运行方式把常规火电机组的最小技术出力压得更低从根源上腾出空间但设备改造周期长、投资大而且对机组寿命有一定影响。这个项目选择的是“储热罐电锅炉”联合方案也是目前工程上性价比最高、实施难度相对较低的配置。比较关键的地方在于这两者不是各干各的而是需要在一个优化框架下统一调度否则容易出现储热罐在放热、电锅炉也在发热的“打架”局面。这个统一调度的任务就是这套联合优化控制模型要解决的问题。1.3 整体方案架构这个项目的整体架构可以分三层理解。数据层负责输入一整天的预测数据包括电负荷预测曲线、热负荷预测曲线、风电出力预测曲线以及机组参数如额定容量、爬坡速率、热效率、储热罐容量和充放热功率上限等。模型层是核心用Matlab结合Yalmip工具箱搭建混合整数线性规划模型决策变量涵盖常规火电机组电出力、热电联产机组电出力和热出力、储热罐充放热功率、电锅炉消耗电功率、风电机组实际并网功率以及部分机组的启停状态0-1变量。输出层则输出各机组出力计划、储热罐调度策略、电锅炉运行计划、弃风率以及总运行成本等结果并用图的形式直观呈现风电消纳效果。整个方案最核心的设计哲学是不改变物理设备结构只靠优化调度策略就能显著提升风电消纳空间。这一点在实际工程中非常有吸引力——调度系统改造比设备改造便宜太多了。2. 优化模型的搭建目标函数与约束条件2.1 目标函数弃风惩罚与经济性怎么权衡建模的第一步是确定目标函数。这个项目的目标当然是最大化风电消纳但直接写“最大化风电并网功率”在数学上会带来一个不太好处理的问题目标函数和约束条件之间的主导关系不够清晰而且完全不计成本地消纳风电可能导致系统运行经济性极差。实际建模中更常用的做法是把风电消纳目标通过“弃风惩罚成本”的形式放进目标函数。也就是说目标函数由两部分组成系统运行成本和弃风惩罚成本。系统运行成本包括常规火电机组和热电联产机组的煤耗成本、启停成本和电锅炉购电成本弃风惩罚成本则是理论可用风电功率与实际并网功率之差的线性函数乘上一个惩罚系数。这样处理的好处一是数学表达简洁弃风惩罚项是线性的可以直接嵌入混合整数线性规划框架二是权重可调把惩罚系数设得足够大优化器就会优先消纳风电而在风电不足或电网无法消纳时又能自动在成本和消纳之间做一个平衡。 提示惩罚系数的取值直接影响结果。我测试的时候发现惩罚系数设为煤耗单价的5到10倍时风电消纳效果最好且不会出现因为过度追求消纳导致成本异常攀升的情况。系数太小则模型会“觉得”弃风比调机组更划算系数过大则可能出现某些极端工况下调度方案不够平滑。2.2 核心约束条件逐条拆解约束条件是模型的骨架任何一条写错都可能导致无解或结果不合理。我把这个项目里最关键的几条约束逐一说明。电功率平衡约束是最基础的等式约束指任意时刻所有电源出力之和必须等于电负荷与电锅炉耗电功率之和。注意这里电锅炉作为一个用电负荷出现在等式右侧这是电锅炉参与风电消纳的关键机制。热功率平衡约束同样重要指任意时刻热电机组热出力加上储热罐放热功率减去充热功率再加上电锅炉产热功率必须等于热负荷。储热罐的充放热状态在这里体现出解耦作用——热量不再是“即产即用”有了存储空间。热电联产机组耦合约束是这个模型的灵魂描述机组电出力和热出力之间的可行域。严格来说抽汽式热电联产机组的可行域是一个由多个顶点围成的多边形区域工程上常常对这个多边形做线性化处理。简化处理时常用两条不等式描述电出力大于等于某一条关于热出力的线性下限小于等于某一条关于热出力的线性上限。风电出力约束表示实际并网功率不得超过预测可用功率同时不能小于零。这个约束看似简单却是弃风量计算的依据。常规火电机组约束包括出力上下限约束和爬坡约束爬坡约束描述机组在相邻两个时段之间电出力变化量的上限。热电联产机组同样需要爬坡约束这里项目简化处理为只约束电出力的爬坡工程中更精细的模型还可以考虑热出力爬坡。储热罐约束包括充放热功率上限、储热罐储热量上下限和储热量动态平衡方程即上一时段储热量加上本时段充热量减去放热量等于当前时段储热量。很多人容易漏掉的是储热罐不能同时充热和放热这条约束可以用一个0-1变量配合大M法实现也可以用两个非负变量加一个互补约束的线性化形式实现。电锅炉约束比较简单电锅炉消耗电功率乘以制热效率等于产热功率功率有上下限且锅炉有启停状态0-1变量停机时功率为零。2.3 求解器选型为什么用混合整数线性规划整套模型中的0-1变量主要来自机组启停状态和储热罐充放热状态互斥条件这让模型成为一个混合整数线性规划问题。MILP模型在Matlab里有好几种求解路径直接用内置的intlinprog、用Yalmip调用外部求解器或者用国产求解器。我强烈建议用YalmipRm求解器Cplex或Gurobi的组合。原因很简单Yalmip把Matlab和求解器之间的接口封装得很干净你不需要记忆Cplex底层的复杂调用接口只需用标准语法定义变量、目标函数和约束最后一句话就能调用求解器。Cplex和Gurobi求解中小规模的MILP问题性能很好像这里24个时段、几十个变量的问题求解时间基本在几秒以内。时间尺度的选择也很关键。这个项目采用24小时调度周期、1小时为时间步长共24个时段。如果你想看到更细的波动效果可以改成15分钟一个时段即96个时段模型规模会相应扩大但求解器依然能够胜任。3. Matlab代码实现与关键细节3.1 数据准备仿真场景怎么搭仿真数据的质量直接决定结果的可靠性很多第一次做这个项目的人上来就写代码结果输出一堆完全不符合物理规律的数据回头查半天才发现问题出在输入数据上。我建议先把数据整理成结构体或表格便于统一管理。典型的数据包括电负荷数据、热负荷数据、风电预测出力数据以及各类机组参数。表1给出一组示例数据方便对照验证。参数名称数值单位常规火电机组额定功率300MW常规火电机组最小出力150MW热电联产机组额定电功率200MW热电联产机组最小电出力100MW热电联产机组最大热出力150MWth储热罐容量300MWth储热罐最大充放热功率50MWth/h电锅炉额定功率40MW电锅炉制热效率0.95-风电装机容量300MW风电场数据建议实测曲线或标准测试系统数据。如果手头没有实测数据可以用一个正弦基函数叠加随机波动来生成但注意风电夜间大发的特征要保留否则很难体现消纳矛盾。电负荷和热负荷曲线要有典型日特征电负荷通常在上午和傍晚出现两个高峰热负荷则比较平缓且夜间略高。数据做好后先画出来看一眼确认符合基本物理规律再进模型。3.2 Yalmip建模核心代码建模部分我直接给出核心代码骨架结构是标准的Yalmip三步走定义变量、写目标函数、加约束、调用求解器。% 定义变量 P_c sdpvar(1, T); % 常规火电出力 P_chp sdpvar(1, T); % 热电联产电出力 H_chp sdpvar(1, T); % 热电联产热出力 P_w sdpvar(1, T); % 风电实际并网功率 P_eb sdpvar(1, T); % 电锅炉耗电功率 H_eb sdpvar(1, T); % 电锅炉产热功率 Q_s sdpvar(1, T); % 储热罐储热量 H_ch sdpvar(1, T); % 储热罐充热功率 H_dis sdpvar(1, T); % 储热罐放热功率 u_chp binvar(1, T); % 储热罐充放热状态标志目标函数的构建是整个建模过程里最能体现设计思想的部分。煤耗成本用出力的二次函数描述这个项目为了兼容线性规划框架做了分段线性化处理。当然如果你手头的求解器支持二次规划也可以用quadprog直接求解二次成本函数精度更高。弃风惩罚项则用预测可用风电功率减去实际并网功率来计算。% 目标函数运行成本 弃风惩罚 coal_cost sum(a1 * P_c.^2 b1 * P_c c1); chp_cost sum(a2 * P_chp.^2 b2 * P_chp c2); curtail_penalty lambda * sum(P_w_pred - P_w); objective coal_cost chp_cost curtail_penalty;约束条件的添加是整个程序中代码量最大、最容易出错的部分。以电功率平衡约束为例注意把电锅炉耗电功率放在负荷侧这是很多人容易忽略的细节。热功率平衡约束则要体现储热罐的充放热状态和电锅炉的产热贡献。constraints []; % 电功率平衡发电侧 负荷侧(电负荷 电锅炉) for t 1:T constraints [constraints, P_c(t) P_chp(t) P_w(t) P_load(t) P_eb(t)]; end % 热功率平衡热源侧(热电机组 储热放热 电锅炉) 热负荷 储热充热 for t 1:T constraints [constraints, H_chp(t) H_dis(t) H_eb(t) H_load(t) H_ch(t)]; end热电联产机组的电热耦合约束是这个项目里最需要深入理解的部分。在简化模型里可以用两条线性不等式来描述电出力随热出力变化的范围再加上电出力和热出力各自的上下限。实现时我用矩阵形式一次性添加整段时段的约束这样代码更简洁求解效率也更高。储热罐的动态平衡约束要特别注意时序关系即下一时段的储热量由当前时段储热量、本时段充热量和放热量共同决定这是连接各时段的关键纽带写错会导致整条储热曲线失真。% 储热罐动态约束 for t 2:T constraints [constraints, Q_s(t) Q_s(t-1) H_ch(t) * eta_ch - H_dis(t) / eta_dis]; end求解调用的写法非常简单注意设置求解器的输出参数以便后续判断求解状态和提取结果。这个项目用Cplex作为求解器Yalmip会自动识别。求解完成后记得检查求解状态是否为0即成功求解这非常重要。3.3 结果可视化把消纳效果画出来跑完模型之后可视化是让结果“看得见”的关键一步。我通常画三张图第一张是电功率平衡图用堆叠面积图展示各类电源出力构成能直观看出风电在不同时段的消纳情况第二张是热功率平衡图重点显示储热罐的充放热过程第三张是风电消纳对比图把预测可用风电和实际并网风电画在一起两条曲线中间的面积就是弃风量。figure; area([P_c; P_chp; P_w]); legend(常规火电, 热电联产, 风电); xlabel(时段/h); ylabel(功率/MW);画图时有个技巧把电负荷曲线也画在同一张图上做参考可以更清楚地看到风电挤占负荷空间的情况。另外弃风率可以直接作为分析结论在实际项目汇报和论文写作中弃风率通常是评审最关心的指标我只在代码里把弃风率计算出来公式就是1减去实际并网电量与预测可用电量之比乘以百分之百。4. 三组仿真场景的对比分析4.1 场景一无解耦措施基准场景第一个场景不启用储热罐和电锅炉相当于传统“以热定电”的基准工况。这种方式把热电联产机组的热出力直接等同于热负荷需求热出力曲线是一条跟随热负荷变化的平滑曲线机组的电出力则被热出力牢牢锁定几乎没有下调空间。此时如果风电预测出力在夜间达到较高水平超出系统消纳能力的那部分只能被舍弃。仿真结果中基准场景的弃风率通常在20%到30%之间具体数值取决于风电装机容量和热负荷水平。电功率平衡图上能明显看到夜间时段风电出力曲线被“削平”实际并网功率始终维持在一个较低水平而常规火电却仍在较高出力区间运行整个系统呈现出“低谷时段火电不减、风电被弃”的不合理状态。这里反映出的问题很有代表性即便火电已经压到了最小技术出力热电机组的最小电出力依然过高导致系统整体下调能力不足。这也验证了题目里说的“风电最大化消纳”为什么必须是“联合优化”——单靠火电调整根本解决不了热电机组的耦合约束问题。4.2 场景二仅配置储热罐第二个场景启用储热罐但不启用电锅炉。优化模型开始发挥作用储热罐在白天热负荷相对较低、电价相对便宜的时段充热在夜间供热需求高或风电大发时段放热从而允许热电机组在夜间降低热出力、进而降低电出力为风电腾出并网空间。仿真结果显示弃风率从基准场景的20%到30%下降到10%到15%左右。储热罐的储热量曲线呈现出明显的“白天蓄能、夜间释能”特征热电机组在夜间的最小电出力有明显下降。这说明储热罐单独作用时已经能有效缓解热电机组对风电空间的挤压。不过储热罐也有它的局限性。它的本质是“平移热量”并不能凭空创造风电消纳空间只能把热电机组白天多发的那部分热存起来留到夜间放。当夜间热负荷特别高、风电同时大发时储热罐容量有限放热速度也受功率上限约束消纳效果会遇到瓶颈。4.3 场景三储热罐与电锅炉联合优化第三个场景同时启用储热罐和电锅炉也是这个项目要呈现的完整方案。电锅炉的引入让系统在夜间出现一个“主动用电负荷”风电大发时可以直接把电引到电锅炉变成热为风电开辟了一条全新消纳通道效果立竿见影。联合优化下的结果改善非常明显。典型日的弃风率可以降到5%到8%某些风电资源较好、热负荷适中的日子甚至可以实现零弃风。电功率平衡图上夜间时段电锅炉的耗电功率曲线与风电出力曲线有明显的联动关系风电出力越高电锅炉耗电越大。电锅炉的功率上限决定它的消纳“天花板”如果风电场容量很大单台电锅炉可能不够用需要进一步扩大电锅炉容量或增加储热容量。对比维度基准场景储热罐储热罐电锅炉弃风率20%-30%10%-15%5%-8%系统运行成本中略降略升热电机组灵活性无中高对风电跟踪能力弱中强运行成本方面储热罐方案因为优化空间集中在“少烧煤、多存热”上成本相比基准场景略有下降电锅炉方案虽然消耗了电能看起来“多花了钱”但考虑到这部分电能是弃风电力边际成本极低实际系统总体经济性反而更优。这在项目结果分析时要想明白否则很容易被表面成本数据误导。4.4 多场景分析带来的结论三组场景跑完之后结论其实已经很清晰了。储热罐解决问题的方式是“平移”它在时间维度上转移热量通过改变热电机组的运行点来腾出空间效果受限于储热容量和充放热功率电锅炉解决问题的方式是“增量”它在空间维度上新增了一条电转热的消纳通道效果受限于电锅炉容量和电网能够承受的额外用电负荷。二者联合起来时间维度上的灵活性和空间维度上的消纳能力形成互补风电最大化消纳的目标才真正落地。这个结论不是我拍脑袋想出来的而是我从三组场景的数值对比里看出来的。所以我也建议你自己跑完项目之后不要只看最终弃风率把场景二和场景三的储热曲线、电锅炉曲线放在一起对比看你会有更直观的感受。5. 常见问题与排查心得5.1 模型报无可行解先别急着调求解器第一次跑这个模型时我花了很多时间在排查“无可行解”的问题上。后来发现无可行解90%以上来自约束条件自相矛盾而不是求解器或代码语法的问题。常见的原因主要有三个。热功率平衡约束写反了充放热方向。储热罐放热是增加供给侧充热是增加需求侧如果方向搞反会让模型在物理上不可能满足平衡直接导致无可行解。排查时把约束打印出来人工核对一次问题很快就暴露了。储热罐的初始储热量和末端储热量衔接不当。我习惯加上一个循环约束让调度周期末的储热量等于初始储热量这样模型才有长期可持续性。但如果初始储热量设置得过高而储热罐容量又有限模型可能找不到任何一条可行路径这时候把初始储热量调低或放宽末端约束就行。机组组合中的0-1变量和出力上下限约束冲突。比如某台机组在某个时段被要求停机但另一条约束又强制它的出力大于零这就会产生矛盾。这个问题在大型系统里很隐蔽排查时可以用Yalmip的diagnostic功能定位涉嫌约束冲突的变量和约束序号。5.2 结果合理但“不好看”的排查方向有时模型能解出来结果也满足约束但看起来就是不符合物理直觉。我遇到过一个典型情况电锅炉在风电出力很小的时候也在运行明显不对看起来很不合理。排查之后发现根本不是模型的问题而是电锅炉的启停0-1变量没有被定义把它当成了连续变量处理优化器为了让目标函数更小会让电锅炉在小功率运行和完全停机之间“取一个折中”的值这个值在物理上没有任何意义。解决方法很简单电锅炉必须用0-1变量控制启停状态停机时功率强制为零。另外储热罐的充放热互斥约束也容易忽略如果不加互斥约束模型可能出现同一时段既充热又放热的“循环倒热”现象这在数学上是个可行解但物理上是完全错误的。排查时检查储热罐的充放热功率曲线是否存在同时大于零的时段即可。5.3 求解时间变长和收敛异常中小规模的MILP问题求解很快但如果你把时间粒度细化到15分钟、场景扩展到多日连续调度或者给机组增加启停成本等复杂约束模型规模会急剧扩大求解时间可能从几秒暴涨到几分钟甚至更久。遇到这种情况建议先检查模型中整数变量的数量MILP的求解时间很大程度上取决于0-1变量的规模。其次可以调整求解器的MIP gap容差Cplex默认的绝对gap很小你可以在求解时设置相对gap比如1%这样求解速度会明显提升而结果精度依然在可接受范围内。再一个技巧是给变量设置合理的初始值减少分支定界搜索的初段计算量。这个项目我用下来最深的体会是数据驱动模型调试。每次修改模型或参数之后不要只看最终目标函数值而是把每一类最优解都画出来用眼睛检查一遍。模型可以帮你快速找到最优解但最优解是否物理上合理最终还得靠人的判断。最后再分享一个小经验。Matlab和Yalmip的环境配置是很多新手第一道坎建议直接用较新版本的Matlab安装Yalmip和Cplex或Gurobi之后先跑一个简单的线性规划例程验证环境是否正常再启动项目代码。另外所有输入数据统一用标准单位MW、MWh标幺值虽然可以简化计算但在前期调试时不容易发现量纲错误还是用有名值更稳妥。调度优化这个东西模型和代码各占一半把数据管好了后面就顺了。