ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

计及N-k安全约束的含光热电站电力系统优化调度Matlab实现

计及N-k安全约束的含光热电站电力系统优化调度Matlab实现 做电力系统调度的朋友应该都有体会论文里把模型写清楚是一回事真要在Matlab里把代码跑起来、把结果调合理完全是另一回事。尤其带安全约束的优化调度约束一多矩阵动不动就几百上千行稍不注意就出现“约束冲突无解”或者“结果奇奇怪怪但不知道哪里错了”的情况。我之前正好完整复现过一个“计及N-k安全约束的含光热电站电力系统优化调度模型”支持IEEE14节点和IEEE118节点两种算例系统这里把建模思路、关键代码逻辑和踩坑经验一并写下来给大家做个参考。这篇内容适合正在做电力系统优化调度、新能源消纳、光热电站调度策略相关课题的研究生也适合刚接触N-k安全约束、想用Matlab快速实现一个可跑通算例的工程师。文章不会从拉格朗日松弛讲起而是从“这个模型到底在解决什么问题”“约束是怎么一步步加进去的”“代码该怎么组织”这几个角度展开尽量让每个细节都可落地。1. 问题定位与整体思路为什么偏偏是N-k约束和光热1.1 调度模型里加N-k约束本质上是在买“保险”传统经济调度一般只考虑系统正常运行状态约束是潮流方程、机组出力上下限、爬坡速率这些。但电网实际运行里线路或者发电机组随时可能跳闸如果调度结果在某个元件故障后直接导致潮流越限甚至电压失稳那这个调度方案在工程上是不合格的。N-k安全约束的含义是系统在任意k个元件退出运行后仍能通过调整发电出力维持安全运行。k1就是N-1是最常见的校核标准k2就是N-2对应更严酷的双重故障场景。把这类约束嵌入优化调度模型得到的调度方案就不是“最优但脆弱”的方案而是“牺牲一点经济性、换取较强鲁棒性”的方案。这里要特别注意N-k约束不是简单地把故障场景下的潮流约束加入模型就完事。对于大规模系统全部N-2场景的数量是组合爆炸级别的118节点系统全枚举N-2根本不现实。所以实际代码里一般会采用“预想事故集生成 关键故障筛选 主子问题迭代”的思路这个后面展开讲。1.2 光热电站在这类模型里的定位是什么光热电站CSP跟光伏、风电不一样的地方在于它自带储热系统。光伏和风电出力“靠天吃饭”不具备可调度性光热电站可以通过储热罐把白天多余的热能存下来等到晚间或者负荷高峰期再释放出来发电等于给了调度员一个灵活调节的杠杆。在计及N-k安全约束的模型里光热电站电力系统的作用体现在两个层面。第一故障发生后系统出现功率缺额光热电站的储热系统可以在短时间内快速增加出力充当旋转备用和事故备用的补充。第二光热电站的调节能力可以让其他常规机组在调度点位上留出更多裕量间接降低了故障场景下需要调整的幅度。所以建模时不能把光热电站简单当成一个“带上下限的电源”至少要考虑光场集热、储热罐充放热、发电功率转换这三段环节的能量平衡关系储热罐的容量和充放热速率都要作为约束进入模型。1.3 为什么选IEEE14和IEEE118节点系统做验证IEEE14节点系统规模小约束数量和变量数量都处于“人脑还能追踪”的范围适合调试模型逻辑。比如N-1场景总共也就几十个N-2场景也还能枚举方便检查约束到底有没有写错。IEEE118节点系统则更接近实际规模线路和机组数量上来了求解难度和计算时间也上来了适合做算法效率和实用性的验证。我自己实测下来同样一套代码IEEE14节点用默认参数求解只要几秒IEEE118节点可能要几十秒甚至几分钟具体取决于N-k的k值、故障筛选策略还有求解器配置。这两套系统一组合既能验证小系统的正确性又能检验大系统的求解效率作为论文算例或者工程预研是够用的。2. 数学模型与约束构建目标函数、决策变量和关键约束2.1 决策变量怎么设计不仅有机组出力还有光热电站的储放热状态整个调度模型是一个混合整数线性规划问题。决策变量分三类第一类是常规火电机组的开停状态和出力水平第二类是光热电站的发电功率、集热功率、储热罐充放热功率第三类是N-k故障场景下各节点电压相角、线路潮流、负荷削减量这些状态变量。需要强调一点故障场景下的变量跟正常场景下的变量是有耦合关系的。常规机组在故障后的调整出力要在爬坡约束允许的范围内光热电站的储放热功率调整也要受储热罐实际储热量的限制。这个耦合关系如果漏掉计算出来的“故障后可调范围”就没有任何物理意义。具体到变量定义我用的是这样的逻辑以IEEE118节点为例% 正常场景变量 Pg sdpvar(nGen, T); % 常规机组出力 on binvar(nGen, T); % 机组开停状态 Pcsp sdpvar(nCsp, T); % 光热电站发电功率 Pstore sdpvar(nCsp, T); % 储热罐充放热功率正放负充 % N-k故障场景变量 Pg_f cell(nContingency, 1); % 各故障场景下的机组出力 theta_f cell(nContingency, 1); % 各故障场景下的节点相角2.2 目标函数运行成本、弃光惩罚和负荷削减惩罚怎么权衡目标函数我采用了最小化总运行成本的模式包括四部分常规机组燃料成本、开停机成本、光热电站运行维护成本、弃光惩罚成本以及故障场景下的负荷削减惩罚成本。这里引入一个权重参数将正常场景成本与故障场景惩罚成本统一量纲实际调试中发现惩罚系数设置在100到1000之间比较合适太低会导致模型“宁可切负荷也不调整出力”太高则会让模型过于保守。燃料成本一般用二次函数表示在MILP里需要分段线性化% 分段线性化燃料成本 for i 1:nGen for t 1:T for s 1:nSeg g_seg(i,t,s) sdpvar(1,1); Cost Cost coef(i,s) * g_seg(i,t,s); end end end每段出力有上下限约束所有段出力之和等于机组总出力这样就保证了开停机状态下成本的连续性和凸性。刚开始做的时候很多人图省事直接用线性成本结果调度结果会频繁出现机组在最小技术出力附近“颠簸”的现象就是因为没有处理好成本函数的凸性。2.3 常规约束功率平衡、爬坡、机组最小开停机时间功率平衡约束是每个时段所有机组出力加光热出力之和等于负荷这是最基本的约束。爬坡约束要区分正常场景和故障场景正常场景爬坡约束和故障场景爬坡约束是独立的因为故障发生之后机组调整出力要在一个时间段内完成不能瞬时跳变。最小开停机时间约束属于“写了容易调试麻烦”的类型。基于状态变量的递推关系可以用一组线性不等式表示但时间粒度越小约束数量越多。我的代码里默认T24时段最小开停机时间设置为2小时这个约束对求解时间影响不算大但如果T扩大到96时段这个约束的数量会直线上升需要特别注意。2.4 光热电站建模三段式能量平衡不能省光热电站的建模是核心难点也是最容易出错的地方。我采用的是“光场—储热—发电”三段式模型。第一步光场接收太阳辐射能转化热能。这里用DNI数据乘上集热面积和效率得到集热功率这个功率上限受光照条件限制是外部给定参数。第二步热能进入储热罐。储热罐相当于一个能量缓冲池能量平衡关系是储热罐当前储热量 上一时段储热量 充热功率 - 放热功率 - 热损耗其中热损耗通常简化成储热量的固定百分比。第三步储热罐放出热能驱动汽轮机发电。发电功率等于放热功率乘以热电转换效率并且有最小技术出力和最大出力限制。% 储热罐能量平衡 for t 2:T Qstore(t) Qstore(t-1) eta_in * Pstore_in(t) - ... (1/eta_out) * Pstore_out(t) - loss * Qstore(t-1); end这里有个细节充热功率和放热功率在数学上应该是两个非负变量不能用一个有符号变量代替否则优化器会利用“同时充放热”的伪操作来打擦边球导致储热罐实际没有存储热量但模型计算有收益。严格来说要加互斥约束或者使用两变量建模我为了省事是加了一个隐性约束让充放热不同时为正实测下来可以用。2.5 N-k安全约束的数学表达和场景生成这是整个模型最核心的部分。N-k约束的本质是对每一个预想故障场景存在一个可行的调整方案让系统在故障后仍满足潮流约束、机组出力约束和爬坡约束。我把故障场景分成了两类处理。第一类是线路故障对应节点导纳矩阵变化第二类是发电机故障对应机组出力上限变为0。两种故障的处理方式不太一样线路故障会改变潮流分布发电机故障主要造成功率缺额。N-k场景生成的关键问题是数量控制。IEEE14节点下所有线路和发电机的N-2组合数量不算特别多可以全枚举IEEE118节点下就必须做筛选。我的做法是先用正常场景的最优潮流结果计算各线路的负载率找出负载率排名前N条的线路作为关键故障候选集再在候选集内枚举k重组合。这个策略在工程上比较常用好处是计算量可控坏处是理论上存在漏掉某些极端组合的风险这也是近似算法的通病。故障场景下的约束表达最直接的是直流潮流方程% 故障场景下的潮流约束 for k 1:nCtrl Pgf Pg_f{k}; thetaf theta_f{k}; % 节点功率平衡 Bf * thetaf Pgf - Pd Pcurtail_f{k}; % 线路潮流限值 -Fmax Bf_line * thetaf Fmax; end直流潮流是线性约束可以直接放进MILP求解。如果要用交流潮流问题是高度非线性的正常模型直接变NLP求解难度不在一个量级。我这套代码选择了直流潮流主要原因是为了保证模型的线性结构在论文里说明这一点是重要的前提假设。2.6 为什么说这本质上是“鲁棒优化”的雏形把N-k约束和优化目标放在一起看你会发现这个模型其实是在构造一个“正常场景最优所有故障场景可行”的解。这和鲁棒优化的思路很像只是这里的不确定集是离散的故障场景集合而不是连续的不确定参数区间。理解这一点对后续扩展很重要。比如你想把N-k约束从“事后校验”变成“在线滚动优化”需要引入Benders分解或者列约束生成算法把故障场景约束作为子问题迭代添加到主问题中。实际上MATLAB代码里如果能用YALMIP的鲁棒优化工具箱可以一定程度上自动化这个过程但##更底层的#逻辑还是需要自己懂。3. 求解方案与Matlab实现路径从工具箱选型到代码结构3.1 求解器选择Gurobi还是CPLEXYALMIP怎么配这个模型是MILP问题需要用商业求解器。我在代码里使用了YALMIP作为建模语言分别测试过Gurobi和CPLEX两个求解器。实测结果求解器IEEE14节点求解时间IEEE118节点求解时间稳定性Gurobi0.8s约40s高CPLEX1.2s约55s高两个求解器都能收敛到相同的最优值Gurobi整体快一些尤其是大系统下优势更明显。YALMIP的好处是切换求解器只需要改一个参数ops sdpsettings(solver, gurobi, verbose, 2); % 或者 ops sdpsettings(solver, cplex, verbose, 2);3.2 代码整体结构数据准备、建模、求解、分析四层分离写这类优化代码最忌讳把所有逻辑堆在一个脚本里我自己的代码结构是这样组织的main_IEEE14.m/main_IEEE118.m入口脚本负责加载数据、设置参数、调用核心函数、展示结果data_IEEE14.m/data_IEEE118.m数据定义包括节点数据、线路数据、机组参数、光热电站参数、负荷曲线build_model.m核心建模函数输入系统数据和参数输出YALMIP优化模型solve_model.m调用求解器并处理结果plot_results.m可视化输出这个结构的优点是换算例系统时只需要改数据文件建模和求解代码完全复用调试时也可以在build_model里设置断点逐段检查约束矩阵是否生成正确。build_model.m的核心流程大致是function model build_model(data, params) % 1. 定义变量 % 2. 构建目标函数 % 3. 添加常规约束 % 4. 添加光热电站约束 % 5. 生成N-k故障场景 % 6. 添加故障场景约束 % 7. 返回模型 end3.3 用YALMIP表达分段线性化细节决定成败分段线性化的实现看起来简单实际有几个容易踩的坑。第一个坑是断点坐标要包含机组的最大/最小技术出力点否则线性化出来的成本函数在端点附近不连续。第二个坑是每段的斜率必须是递增的这样才能保证成本函数是凸函数。如果原始数据不满足这个条件需要先进行数据预处理用凸包近似处理。% 分段线性化 function cost_seg piecewise_linear(P, breakpoints, slopes) % P: 机组出力sdpvar % breakpoints: 分段点 % slopes: 各段斜率 end3.4 迭代求解N-k场景约束避免一次性全部塞入如果一开始就把所有N-2场景都加入模型IEEE118系统的约束矩阵会膨胀到难以承受。我的做法是采用两阶段迭代% 主循环 scenario_set initial_scenarios; while ~converged % 求解当前场景集下的优化模型 [Pg, obj] solve_master(scenario_set); % 校验全部候选场景寻找被违反的故障场景 [violated, info] check_all_scenarios(Pg); if isempty(violated) converged true; else % 将违反最严重的场景加入场景集 scenario_set [scenario_set; worst_case(violated, info)]; end end这个方法的核心思想是“不需要一次性考虑所有约束只在迭代过程中逐步补上被违反的约束”。实测下来有些在初始集合里看起来不会出问题的场景在加入后反而被排除最终收敛需要的迭代次数大概在3到8轮之间。4. 算例设置与结果分析IEEE14和IEEE118节点4.1 数据准备光热电站接入哪个节点有讲究IEEE14节点系统的原始数据里没有光热电站需要自己选节点接入。我的做法是把光热电站当成一个可调电源接到某节点同时把该节点的原负荷适当调增。选择接入节点的原则有两个一是尽量靠近负荷中心这样可以减少故障场景下远距离送电的压力二是选择对系统稳定影响相对小的节点避免光热电站接入后出现无功支撑不足的问题。IEEE118节点系统我接入了两座光热电站分别位于电气距离较远的两个区域这样能够观察光热电站对整个系统不同区域安全裕量的影响。4.2 关键结果对比有/无N-k约束、有/无光热电站为了把模型效果展示清楚我这里列举一组典型的IEEE118节点算例结果均为T24时段场景正常场景总成本是否含N-1安全裕量是否含N-2安全裕量无N-k约束、无光热100.0基准部分场景越限大量场景越限含N-k约束、无光热108.5全部通过部分通过含N-k约束、含光热106.8全部通过全部通过表格里的成本做了归一化。“无N-k约束、无光热”的方案成本最低但调度方案在N-1故障场景下就有线路潮流越限的情况加了N-k约束之后成本上升约8.5%换来了可靠性。引入光热电站之后成本只比无光热版本上升了约6.8%却额外通过了N-2校核。这说明光热电站的储热能力让系统在应对双故障时有了更大的出力调节窗口。4.3 光热电站出力的“削峰填谷”能力如何体现对比有无光热电站的调度结果能明显看到光热电站出力的时间平移特性。白天9:00-16:00光照充足光热电站一边发电一边往储热罐里充热傍晚17:00-21:00负荷高峰期储热罐释放热量光热电站出力上升到接近额定功率正好替代了一部分高成本火电出力。这个时间平移特性在故障场景下也发挥了作用。夜间光照为零光热电站无法直接集热但储热罐有存量依然可以支撑短时间的高出力。调度模型需要考虑这个特点避免在白天就提前把所有储热耗尽。4.4 故障筛选策略的效果验证针对IEEE118节点系统我对比了“全枚举N-1 候选集N-2”和“仅全枚举N-1”两种策略的差异。全枚举N-1一共涉及约186个预想场景候选集N-2由负载率前15的线路两两组合产生大约105个场景。两种策略在最终调度结果上的差异很小成本差异不到1%但求解时间差异很大。全枚举N-2场景的话模型规模直接翻几倍求解时间可能超过半小时用候选集策略能把总求解时间控制在5分钟以内。这再次说明在大规模系统里无脑枚举所有N-k场景是不现实的“关键场景筛选迭代校核”才是工程上可行的路径。5. 调试经验与避坑指南那些花了三天才绕过去的坑5.1 约束冲突模型“无解”时的定位方法模型一上来就报infeasible是最常见的问题。这时候不要急着删约束用YALMIP的optimize返回值逐步排查。diagnostics optimize(constraints, objective, ops); if diagnostics.problem ~ 0 % 获取冲突信息 check(constraints); endcheck(constraints)会逐一输出每个约束的残差值残差显著非零的那个约束就是infeasible的来源。我调试时最常遇到的问题是储热罐能量平衡约束写错符号充热当成放热导致能量不平衡约束与发电功率约束互相矛盾。5.2 数值范围问题量纲不统一导致求解器“发疯”电力系统数据里功率是MW级别成本是$/MWh储热罐存储量是MWh如果不注意量纲统一约束矩阵里会出现系数相差好几个数量级的行导致求解器数值稳定性极差。我的处理方式是在数据准备阶段统一单位所有功率统一为MW能量统一为MWh成本统一为$。另外需要对大数和小数做一个缩放比如爬坡率参数在归一化后一般在0.1到0.5之间不在这个范围内的参数就要仔细检查。5.3 故障场景下的爬坡约束容易忽略的隐含耦合故障场景下的机组出力调整不是无条件的。假设调度方案里某机组正常出力是300MW故障后要把出力升到350MW这50MW的调整必须在一定时间内完成受到机组爬坡速率的限制。我之前漏了故障场景下的爬坡约束只加了故障后的出力上下限结果系统给出的故障后调整方案在物理上根本无法实现。加上故障场景爬坡约束之后模型才真正变得“可执行”。5.4 直流潮流的局限性线路有功越限只是“必要条件”最后必须提醒直流潮流的N-k校核是一个线性近似只检查有功潮流越限忽略了无功功率和电压约束。在实际工程里线路有功在N-1范围内系统也可能因为电压失稳或者无功不足出问题。所以这套模型更适合用在对安全约束的“初步筛选”上真正的N-k安全校核还需要用交流潮流或者更精细的稳态/动态分析工具来验证。6. 从复现到扩展这套模型还能往哪些方向延伸6.1 从确定性N-k到概率性故障校核传统N-k约束假设每个故障场景等概率发生没有区分不同元件的故障概率。实际上老旧线路的故障概率远高于新线路发电机的故障概率也受服役年限、运行状态影响。一种自然的扩展是给每个故障场景赋一个概率权重把安全约束改造成机会约束Pr(系统安全运行) ≥ 1 - ε这会让模型从MILP变成更复杂的混合整数非线性问题求解难度大幅上升但在工程决策上有意义。6.2 从离线调度到滚动优化当前模型是离线求一个24小时调度方案。实际运行中负荷预测和光热电站的DNI预测会有误差离线方案直接拿来用可能效果不理想。一个可行的扩展方向是改成模型预测控制或者滚动时域优化每隔一小时滚动更新一次未来24小时的调度方案每次求解时只执行第一个时段的决策结果。此时N-k约束仍然可以在每个滚动窗口内嵌入只是在计算时间上要更抠门。6.3 从单目标到多目标经济性和安全性的帕累托权衡这个模型本质上是把经济性和安全性通过目标函数的加权系数绑定在一起了。如果想评估两者之间的真实权衡关系可以改成多目标优化框架求解帕累托前沿再结合决策偏好选择合适的调度方案。IEEE14节点系统因为规模小做多目标优化的计算成本不高很适合作为算法研究的测试床。6.4 与新能源不确定性建模的深度融合光热电站虽然自带储热但它的集热功率受DNI显著影响本质上仍是一个不确定电源。当前模型用确定性DNI曲线没有考虑预测误差。如果想把光热电站的不确定性也纳入模型可以在N-k安全约束的基础上叠加蒙特卡洛场景模拟或者用分布鲁棒优化构造DNI不确定集。这类扩展跟N-k约束并不冲突反而可以统一在一个“双层不确定性”框架下处理。我的实操心得把整个模型从公式推导到代码落地、从14节点调通再到118节点跑出合理结果前后花了两周多的时间。回头总结最值得强调的几点是一是光热电站的储热罐建模一定要用充/放两个独立变量否则能量平衡会被优化器钻空子二是N-k场景一定要做筛选不要试图全枚举尤其118节点系统关键故障候选集策略带来的时间节省非常显著三是故障场景下的爬坡约束很多人会漏掉但缺了它整个N-k校核就缺了灵魂。如果你现在正卡在“模型infeasible但不知道哪里错”这个阶段听我一句劝先把约束数量砍到最少只保留功率平衡和机组出力上下限跑通了再逐步加约束每加一组就用check()去检验。这样看上去笨但实际上是定位模型错误最快的路。这套代码后续可以扩展的方向很多我自己下一步准备把概率故障校核加进去。也希望做相关课题的朋友多交流光热电站的储热容量、熔盐系统参数、DNI曲线整理这些都是可以让模型更贴近实际的细节值得持续打磨。
返回列表