尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

考虑热电联产储热改造的低碳经济调度Matlab建模与求解

考虑热电联产储热改造的低碳经济调度Matlab建模与求解 做电力系统优化调度的同学几乎都绕不开热电联产机组的调峰困境。前阵子我把“考虑火电机组储热改造的电力系统低碳经济调度”这个题目从头到尾做了一遍从模型设计到Matlab代码实现再到结果分析踩了不少坑也沉淀了不少经验。这篇把整套思路完整拆开来讲包括储热改造为什么能解耦“以热定电”、低碳经济调度的目标函数和约束怎么搭、YalmipCplex的代码怎么组织以及算例结果怎么解读。无论你是正在做毕业设计的学生、刚接触调度建模的工程师还是想在这个方向上找创新点的研究者这篇文章都能给你一套可直接复用的框架。先说结论储热改造的核心价值不是“多了一个储能设备”而是给热电联产机组打开了电出力向下调节的空间从而在不牺牲供热的前提下消纳更多风电。低碳经济调度则是在这个物理改造之上用碳交易机制把碳排放变成成本项让优化算法自动权衡“烧煤发电”和“弃风”之间的经济账。两者叠加才是完整的“灵活性改造低碳运行”闭环。1. 为什么储热改造能和低碳调度凑在一起1.1 热电联产机组的“以热定电”困局理解储热改造先要理解热电联产机组的工作特点。抽汽式供热机组在冬季运行时从中压缸抽出部分蒸汽进入热网加热器这部分抽汽量决定了供热负荷。抽汽量越大进入低压缸做功的蒸汽就越少机组电出力就相应下降——但问题在于供热需求是刚性的尤其夜间居民采暖负荷最高的时候机组必须维持足够的抽汽量电出力下限就被“顶”上去了。这就是业内常说的“以热定电”机组的电出力范围被热负荷挤压最低电出力甚至可能比纯凝工况高出三到五成。于是冬天夜间出现一个很尴尬的场面电负荷低谷、热负荷高峰、风电大发常规火电已经压到最低但热电联产机组因为要保供热电出力降不下来电网为了平衡只能砍风电。北方的“弃风限电”问题很大一部分就出在这里。你可以把这个过程类比成一个烧锅炉供气的场景锅炉蒸汽总量固定一部分蒸汽去供暖一部分推动汽轮机发电。多供暖就得少发电少供暖就得停汽——储热罐的作用就是在这个供需之间加一个“缓冲水池”。1.2 储热罐怎么把“热”和“电”解耦储热改造的工程方案并不神秘在热网加热器入口的抽汽管道上并联一个热水储热罐配合调节阀门和循环泵实现三种运行状态。热负荷低谷时机组多烧一些蒸汽除了满足热网需求外把剩余热量以热水形式存进储热罐这就是“充热”。此时热负荷并没有增加但锅炉出力上去了机组电出力可以维持在一个偏低的水平——因为储热罐相当于替用户“接走”了热量机组不需要为了降电出力而关小锅炉。热负荷高峰时储热罐放热热水直接供给热网此时机组可以适当减少抽汽量电出力下限随之下降给风电腾出空间这就是“放热”。改造之后机组的电出力和热出力不再是一一绑定的关系热负荷曲线由“抽汽储热罐放热”共同满足机组获得了向下调峰的灵活空间。这个空间的大小直接取决于储热罐容量和充放热功率。低碳调度之所以要引入储热改造本质上是把这种物理层面的灵活性转化成调度模型里可量化、可优化的资源——储热罐充放热的时序安排恰恰是低碳经济调度能否跑赢传统调度的关键。2. 低碳经济调度的数学模型目标与约束怎么定2.1 目标函数的三笔账调度模型的目标函数本质上是在算“系统运行一天要花多少钱”。传统经济调度只算煤耗成本低碳经济调度在这个基础上加了两笔账碳交易成本和弃风惩罚成本。第一笔是煤耗成本。纯凝火电机组的煤耗特性通常用二次函数描述但在混合整数线性规划框架里二次函数要么用分段线性近似要么用线性系数简化。工程上我常用分段线性化在拐点处用SOS2约束或二进制变量激活区间。调度精度要求不那么高时直接用线性系数替代误差在几个百分点以内求解速度却快很多。第二笔是碳交易成本。这里要理解配额机制系统会免费发放一定的碳排放配额如果实际排放低于配额可以把盈余卖掉赚钱高于配额则必须去碳市场购买。实际排放与配额的差额乘以碳价就是碳成本。更有意思的是阶梯碳价——超出配额越多碳价单价越高这比单一碳价更能反映“减排越难越贵”的市场逻辑。第三笔是弃风惩罚。风电的边际成本接近零调度模型为了消纳风电通常会在目标函数里加一个弃风惩罚项代表“浪费清洁能源的机会成本”。惩罚系数太小优化算法可能为了省煤耗成本主动弃风惩罚系数太大又会强迫系统不计代价消纳风电导致火电爬坡压力过大。我试过500元/MWh这个量级和煤耗成本、碳成本在一个数量级上比较合理。目标函数写出来就是煤耗成本 Σ(各机组煤耗系数 × 出力)碳交易成本 阶梯碳价函数(实际排放 - 免费配额)弃风惩罚 惩罚系数 × Σ(风电预测出力 - 实际上网出力)储热罐运维成本 运维系数 × Σ(充热功率 放热功率)2.2 CHP机组可行域与储热罐模型热电联产机组的电热耦合关系是模型里第一个容易被写错的点。严格来说抽汽式机组的可行域是一个多边形四个顶点分别对应纯凝最小电出力、纯凝最大电出力、最大抽汽工况下的电出力和热出力组合。工程上常用梯形近似电出力下限随热出力线性下降P ≥ P_min − α1 × H电出力上限随热出力线性下降P ≤ P_max − α2 × H热出力范围0 ≤ H ≤ H_max其中α1和α2是热出力对电出力的修正系数α1 α2这保证梯形上边界比下边界更陡。这样一组线性约束正好能被混合整数线性规划求解器直接处理。储热罐模型是第二个关键点。状态变量是储热量C(t)控制变量是充热功率H_chg和放热功率H_dis。约束包括能量平衡C(t1) C(t) η_chg × H_chg(t) − H_dis(t) / η_dis容量上下限C_min ≤ C(t) ≤ C_max充放热功率上限H_chg ≤ H_chg_max × u_chgH_dis ≤ H_dis_max × u_dis充放互斥u_chg u_dis ≤ 1日循环约束C(24) C(0)保证一天结束后储热量回到起点这里的效率η_chg和η_dis通常不是1充热时热量有损失放热时也有损失。如果忽略效率储热罐等于免费储能优化结果会过度利用储热罐不符合实际。日循环约束也特别重要不加的话算法会让储热罐在调度周期结束时“耗尽热量”从而低估实际用能成本。2.3 系统约束别漏了热功率平衡除了机组和储热罐自身约束系统层面还有几道平衡约束必须同时满足。电功率平衡最简单所有火电出力 风电上网功率 系统电负荷。热功率平衡稍微绕一点CHP机组热出力 储热罐放热功率 热负荷 储热罐充热功率。注意充热在这里被当成“热负荷”处理因为它确实消耗了系统产出的热量。符号搞反是模型无解最常见的原因我调试时就在这上面栽过跟头。此外还有火电机组爬坡约束相邻时段出力变化不能超过爬坡上限旋转备用约束系统需要留出一定备用容量应对负荷波动和风电预测误差。风电预测出力是上限约束实际上网功率不能超过预测值。如果模型里加了备用约束要特别注意风电不确定性场景——保守做法是按预测出力的90%计入可用容量或者干脆把备用约束设在确定性预测场景下。3. Matlab代码实现Yalmip建模与求解器配置3.1 整体框架变量定义与数据准备Matlab环境下我推荐用Yalmip做建模工具箱求解器用Cplex或Gurobi。Yalmip的语法接近数学表达式写约束和读代码都直观适合调度模型的快速迭代。代码的第一步是定义优化变量。这里给出核心的结构T 24; % 调度时段数小时 ngen 3; % 纯凝火电机组数量 nchp 2; % 热电联产机组数量 ntank 1; % 储热罐数量 P sdpvar(ngen, T); % 纯凝机组电出力 Pc sdpvar(nchp, T); % CHP机组电出力 Hc sdpvar(nchp, T); % CHP机组热出力 Pw sdpvar(1, T); % 风电实际上网功率 Hchg sdpvar(ntank, T); % 储热罐充热功率 Hdis sdpvar(ntank, T); % 储热罐放热功率 C sdpvar(ntank, T 1); % 储热罐储热量多一列是为了写循环约束 uchg binvar(ntank, T); % 充热状态1表示正在充热 udis binvar(ntank, T); % 放热状态1表示正在放热数据准备部分需要提前把机组参数、负荷曲线、风电预测出力、热负荷曲线、储热罐参数都定义好。热负荷曲线在冬季典型日的特征是晚上高白天低风电预测出力往往是夜间大白天小这两条曲线的错位恰好是储热罐发挥价值的时间窗口。建议先把这些曲线用Matlab画出来能直观看出改造前弃风发生在几点到几点。3.2 核心约束的Yalmip写法电功率平衡和热功率平衡约束写法如下Constraints []; Constraints [Constraints, sum(P) sum(Pc) sum(Pw) P_load]; Constraints [Constraints, sum(Hc) sum(Hdis) H_load sum(Hchg)]; Constraints [Constraints, 0 Pw P_wind_pred];CHP机组可行域用梯形约束表达for i 1:nchp Constraints [Constraints, ... Pc(i,:) Pmin_chp(i) - alpha1(i) * Hc(i,:)]; Constraints [Constraints, ... Pc(i,:) Pmax_chp(i) - alpha2(i) * Hc(i,:)]; Constraints [Constraints, 0 Hc(i,:) Hmax_chp(i)]; end储热罐约束是模型里最完整的一组这里要特别注意循环索引for k 1:ntank % 能量平衡注意效率系数 Constraints [Constraints, ... C(k,2:T1) C(k,1:T) eta_chg * Hchg(k,:) - Hdis(k,:) / eta_dis]; % 容量上下限 Constraints [Constraints, Cmin(k) C(k,2:T1) Cmax(k)]; % 充放热功率上限与状态互斥 Constraints [Constraints, ... Hchg(k,:) Hchg_max(k) * uchg(k,:), ... Hdis(k,:) Hdis_max(k) * udis(k,:), ... uchg(k,:) udis(k,:) 1]; end % 日循环约束 Constraints [Constraints, C(:,T1) C(:,1)];这里有几个细节C矩阵是ntank行×T1列索引从1到T1C(k,1)是初始储热量由优化自行决定日循环约束保证它等于结束时的储热量。如果把初始储热量固定成某个值会限制调度灵活性除非你明确模拟的是“前一天结束后罐内剩余的热量”。3.3 碳交易成本的分段线性实现阶梯碳价是整个目标函数里最有技术含量的一块。我分享一个不需要二进制变量的实现技巧思路是因为阶梯碳价单价递增λ1 λ2 λ3优化算法在分摊超额排放量时会优先使用低价段。因此可以把超出配额的部分拆成三段连续变量只加非负和上限约束不需要互斥约束。% 碳排放量纯凝与CHP各自排放强度乘以出力 E_total sum(sum(delta_p .* P)) sum(sum(delta_c .* Pc)); % 免费配额 A_quota quota_coef * sum(P_load); % 净排放正为购买负为出售 x_pos sdpvar(1,1); % 超额排放量购买部分 x_neg sdpvar(1,1); % 盈余排放量出售部分 Constraints [Constraints, E_total - A_quota x_pos - x_neg]; Constraints [Constraints, x_pos 0, x_neg 0]; % 三段阶梯碳价变量 x1 sdpvar(1,1); x2 sdpvar(1,1); x3 sdpvar(1,1); Constraints [Constraints, x_pos x1 x2 x3]; Constraints [Constraints, 0 x1 d1, 0 x2 d2, 0 x3]; % 碳交易成本购买用阶梯价出售用基础价 carbon_cost lambda1 * x1 lambda2 * x2 lambda3 * x3 - lambda1 * x_neg;为什么这个写法可行因为λ2比λ1大、λ3比λ2大假设系统超额排放正好是15吨d110、d210那么把x1取满10、x2取5的成本低于x1取5、x2取10的成本。所以算法会自动按“先便宜后贵”的顺序分配分段结果天然正确。这个小技巧至少帮我省了一半的二进制变量。目标函数最后汇总coal_cost sum(sum(a1 .* P b1)) sum(sum(a2 .* Pc b2)); wind_penalty 500 * sum(P_wind_pred - Pw); tank_opex 2 * (sum(sum(Hchg)) sum(sum(Hdis))); Objective coal_cost carbon_cost wind_penalty tank_opex; ops sdpsettings(solver, cplex, verbose, 2, ... cplex.timelimit, 7200, cplex.mip.tolerances.mipgap, 1e-3); sol optimize(Constraints, Objective, ops);如果是学术版Cplex或Gurobi记得提前在Matlab里配置好求解器路径否则Yalmip会报“No solver found”之类的错误。4. 算例分析改造前和改造后到底差多少4.1 测试系统与场景设置为了验证模型我搭了一个典型的24小时调度测试系统3台纯凝火电机组总装机约450MW、2台热电联产机组电出力范围40~200MW和30~150MW热出力上限120MW和100MW、1个200MW风电场外加1个容量200MWh、充放热功率50MW的储热罐。冬季典型日的电负荷峰谷差约200MW热负荷夜间高白天低风电预测出力夜间最大到180MW、白天跌到60MW以下。碳配额系数取0.7吨/MWh基础碳价120元/吨阶梯区间为300吨和600吨阶梯碳价分别为160元/吨和200元/吨。这套参数是参考典型算例设置的实际项目按机组铭牌参数和当地热负荷曲线替换即可。关键是看趋势数值本身会随参数浮动。4.2 改造前后调度结果对比代码跑完把结果整理成一张对比表是最直观的汇报方式指标改造前无储热罐改造后含储热罐系统总成本万元158.6147.2弃风电量MWh18642弃风率%12.42.8碳排放总量t CO262305945CHP机组平均最低电出力MW95.876.4改造后系统总成本下降了11.4万元其中弃风惩罚减少贡献最大。CHP机组在夜间热负荷高峰时段开始“热负荷由储热罐供、电出力往下压”风电上网量明显提升。碳排放下降285吨这部分来自风电替代火电发电量碳交易成本减少的幅度虽然没有弃风惩罚那么显著但在碳价逐年走高的趋势下会成为越来越重的权重项。需要特别说明的是改造后煤耗成本可能降幅有限因为CHP机组为了向储热罐充热总产热量略有增加锅炉侧煤耗增加了一部分。但综合弃风惩罚和碳成本的下降总成本仍然是显著下降的。这正是“低碳经济调度”和单纯“经济调度”的区别煤炭成本只是总成本的一部分碳约束和清洁能源消纳会改变最优解的方向。4.3 碳价与储热容量的敏感性影响做完基础对比敏感性分析是论文和项目报告中必不可少的加分项。我做了两组分析。一组是碳价从80元/吨逐步升到200元/吨。结果符合预期碳价越高调度模型越倾向于压低火电出力、增加风电消纳碳排放总量呈现阶梯式下降。阶梯碳价的影响不是线性的而是存在“跳跃点”——当碳价超过某个临界值系统会付出额外成本调整机组出力组合换来的减排量突然增加。这个临界值可以用模型多跑几组碳价找出来。另一组是储热罐容量从100MWh逐渐增大到500MWh。弃风率从约7%逐步降到接近零但改善幅度递减容量超过300MWh后再增加容量对弃风率的改善就很有限了因为弃风集中在夜间几个时段储热罐只要能把这几个时段的富余热量吸收掉就够了容量再大也“装不满”。这说明储热罐容量存在一个经济最优规模并非越大越好设计时要用调度模型反过来做容量优化。这两组敏感性分析的价值在于它们回答了“改多大、碳价多少才划算”的问题而不只是给出一个固定的调度方案。5. 常见问题与排查技巧实录5.1 模型报“infeasible problem”怎么办模型无解是调度建模里最折磨人的问题。我的排查流程是固定的第一步用Yalmip的check命令检查每条约束是否满足找到冲突范围。第二步把储热罐的日循环约束注释掉跑一次如果变成有解说明是储热量达不到周期约束需要放宽容量或初值。第三步检查热功率平衡的符号。我实战中遇到的经典错误就是把储热罐放热写成了热负荷约束变成“CHP热出力 热负荷 放热”结果放热越多系统越缺热直接矛盾。正确定义后问题立刻消失。顺着这个经验提醒一句建模时统一在代码注释里写明每个变量的正方向尤其是涉及储能设备的。还有一种常见冲突是旋转备用约束和风电上限约束叠加导致的某些时段即使风电不出力、火电满发也可能无法满足备用需求这时候需要拆解约束逐个时段检查是电负荷尖峰还是热负荷尖峰导致的备用不足。5.2 求解太慢的优化手段混合整数线性规划的求解时间随二进制变量数量增长很快。储热罐充放状态本身就需要2×T个二进制变量再叠加机组启停变量24时段问题规模一下就上去了。我的经验是三个手段并行。第一能用连续变量就不用二进制变量。碳交易分段就是典型例子利用价格递增特性省掉了互斥变量。第二给求解器设定合理的mipgap。学术上追求最优解工程上0.1%的gap和最优解的成本差距只有几百块钱但求解时间可能相差数倍。第三提供初始可行解。对类似的调度场景先用上个时段的解热启动当前时段Yalmip里用assign函数把变量初值塞进去能显著缩短Cplex的branch and bound时间。如果24时段全模型实在跑不动可以按“峰谷分段预求解整体修正”的思路把问题拆开先按负荷分为典型峰段和谷段两个子问题分别求初始解再合并为一个整体模型精调。这个方法在项目里是立竿见影的。5.3 数值稳定性和精度问题数值问题是MatlabYalmip环境里很容易被忽略的坑。最容易中招的是量纲失配时间单位是小时功率单位是MW储热罐容量却经常写成了MWh——这本来没问题关键是效率系数、碳价元/吨、煤耗成本元/MWh这些参数的数值跨度可能从个位数到上万目标函数各项数量级差到1000倍以上时求解器的数值稳定性会明显变差。我的做法是把所有价格类参数统一量纲到“万元”级别或者把功率、热量都做标幺化处理。还有一个具体技巧可以放宽Cplex的整数变量求解精度把mipgap设成1e-3甚至5e-3结果在工程上是可用的但求解速度能提升好几倍。最后再说一个我踩过的坑big-M取值。有些约束为了表达逻辑关系会引入大M如果M取得太大比如1e6Yalmip生成的约束矩阵条件数会爆炸导致求解器报数值故障或返回错误解。好的做法是M能取上限值就绝不取一个拍脑袋的大数——比如充热功率上限50MW那“充热功率 ≤ 上限 × 状态”这种约束根本不需要额外大M直接用上限值做M就够了。做这类调度模型我个人的体会是先把物理过程搞透彻再动手写代码。储热罐是充电还是放电、对系统来说是源还是荷这些最基本的符号约定捋不清楚后面所有优化结果都是错的。建模阶段宁可多看几遍热力系统图也别急着敲键盘——一旦约束写错排查的成本远高于重新建模的成本。如果你也在做储能改造、综合能源、低碳调度方向不妨先拿一套熟悉的机组参数把基础模型跑通再加碳交易、加阶梯碳价、加储热罐一步步迭代上去每加一层都验证一次结果这样既不容易出bug也能把每个模块对总成本的贡献看得清清楚楚。
返回列表