基于联合储能的配电网优化调度与新能源消纳评估
做配电网调度的朋友应该都有体感新能源渗透率上来以后最麻烦的不是风机光伏本身而是出力一波动节点电压跟着晃弃风弃光数字也跟着涨。我接手的一个模拟项目里就遇到了这样的场景——配电网接了几台常规机组之外还有一片光伏和两台分散的风机晴天午间光伏大发时越限和弃电同时出现夜晚风机出力上来又没有足够的灵活性资源去平衡。当时的目标很明确把“联合储能”加进去配合配电网优化调度同时评估新能源消纳能力能提升多少。这篇文章就把我梳理出的建模思路、Matlab代码实现和评估方法完整展开针对的就是所有正在研究储能参与配电网优化调度、又想把“消纳能力”算清楚的人。1. 联合储能为什么是配电网调度和消纳评估的关键变量1.1 单一储能解决不了的两类时间尺度问题很多人一上来就默认“加个电池储能就万事大吉”实际项目里很快就会发现力不从心。光伏和风电的波动不是单一尺度的秒级到分钟级的波动靠电池硬扛能量密度和功率密度两头都吃紧电池寿命掉得飞快而午间光伏大发、夜间风电高峰这类小时级的能量搬移又需要电池有足够的容量去“削峰填谷”。也就是说配电网里既有高频功率波动又有低频能量转移一个电池很难同时把这两件事做好。我在这里说的“联合储能”指的是把电池储能系统BESS和超级电容SC组合在一起的混合储能系统。电池的能量密度高、持续放电能力强适合承担长时间尺度的能量搬移超级电容功率密度高、响应速度快、循环寿命长适合吸收和释放短时高频冲击。两者并联到同一个配电网节点由调度中心统一协调充放电这就是联合储能在优化调度里的基本形态。1.2 联合储能影响新能源消纳的两条路径新能源消纳能力最终取决于系统的“灵活调节空间”。联合储能对消纳的影响不是单一路径我把它拆成两条看。第一条是时间维度上的平移消纳。午间光伏大发时负荷侧吃不下那么多电能如果没有储能调度员只能被迫弃电有了电池储能把多余的电能存起来晚高峰再放出去本质上是用储能把“发得多但用不完”的电平移到“用得完但发不出”的时刻。这一条主要靠电池储能的容量属性。第二条是空间维度上的阻塞缓解。配电网线路和变压器有容量上限新能源出力峰值时线路潮流可能逼近甚至超过限额导致即使系统整体有消纳能力局部通道也送不出去。这时超级电容的高功率响应能配合电池在短时峰值到来时快速吸收或释放功率避免线路越限相当于把局部通道的“临时拥堵”给疏通了。联合储能的实时功率支撑能力在这条路径上起到关键作用。1.3 为什么评估消纳能力必须和调度一起做很多项目单独算“最大可接入新能源容量”那种算法往往把储能固定在一个保守策略上结果偏悲观。实际上储能怎么充、怎么放、在哪个时段参与调节直接决定了能消纳多少新能源。所以更合理的做法是把联合储能的优化调度嵌入到消纳能力评估里同一个优化框架下既求调度策略又算消纳上限。这也是我下面整篇文章的主线——模型搭建、Matlab实现、评估结果串在一条逻辑上。2. 优化调度模型构建目标函数、潮流约束与储能建模2.1 调度问题到底在优化什么配电网优化调度本质上是一个多时段最优潮流问题。时间尺度一般取24小时步长1小时对于小时级的能量调度够了。需要决策的量包括电网向外部买电的功率、各储能单元的充放电功率、新能源的有功削减量弃电功率、以及必要的机组出力调整。目标函数也不是越复杂越好要平衡物理真实性和可求解性。我在模拟项目中采用了最常见的多目标加权形式最小化日运行总成本包括向主网购电的费用、储能运行维护费用、新能源弃电惩罚。其中弃电惩罚的设置很讲究它是一根“指挥棒”——如果惩罚系数过小优化会倾向于弃掉新能源来减少储能充放损耗如果过大则会出现为了消纳而让储能低效率运行的情况。我习惯把弃电惩罚设为电价的1.5到3倍具体根据弃电率目标和储能成本标定。目标函数写出来是这样[ \min \sum_{t1}^{T} \left( c_t P_{grid,t} c_{om} (P_{ch,t}^B P_{dis,t}^B P_{ch,t}^C P_{dis,t}^C) \lambda_{curt} P_{curt,t} \right) ]其中 (c_t) 是分时购电价(P_{grid,t}) 是购电功率(c_{om}) 是储能运行维护单价上标 (B) 和 (C) 分别代表电池和超级电容(P_{curt,t}) 是弃电功率(\lambda_{curt}) 是弃电惩罚系数。模型里没有强制要求消纳率而是通过惩罚项让优化器自己去权衡这一点从结果里能看出很多有趣的取舍。2.2 潮流模型选择DistFlow线性化还是二阶锥凸松弛配电网潮流是交流潮流直接拿交流潮流方程做24小时优化求解起来很慢。我用的做法是DistFlow方程——一种面向辐射状配电网的支路潮流描述法。完整版DistFlow带二次项是非凸的实际工程中我做了两个可选方案。方案一是线性化DistFlow适用于馈线不长、电压偏差不大、网损占比较小的场景。做法是忽略损耗项并用额定电压近似电压二次项这样每个节点t时段只多出两个线性等式约束和一个不等式约束求解速度极快配合线性目标整个问题就是线性规划。我模拟项目的主力求解配置就是这种。方案二是二阶锥松弛的DistFlow通过引入辅助变量把非凸二次项松弛成二阶锥约束保留网损和电压相关的非线性特征。如果电源波动大、网络重载我建议用这个方案。在Matlab里用Yalmip写起来也就多几行把每个支路约束里的 (l_{ij,t}) 和 (v_{i,t}) 拿来声明一个辅助变量然后用cone或norm调用就能表达二阶锥。代价是求解时间上升但换来了更准确的无功电压描述。线性化DistFlow的典型写法我在代码实现部分会给出。需要注意的是无论哪种方案都要求配电网是辐射状的环网需要先做等效否则DistFlow的一致性条件不成立。2.3 电池和超级电容的分时建模细节联合储能的两个成员在模型里的地位不同约束形式也不同。电池储能采用通用的能量状态SOC模型。对每个时段 (t)[ SOC_{t1} SOC_t - \frac{P_{ch,t}^B \eta_{ch} \Delta t}{E_B} \frac{P_{dis,t}^B \Delta t}{E_B \eta_{dis}} ]这里 (\eta_{ch}) 和 (\eta_{dis}) 是充放电效率我取充电效率0.93、放电效率0.95电池容量 (E_B) 为6 MWh。SOC上下限设置为0.1到0.9避免深度充放电伤害寿命。还需要约束同一时刻不能同时充电和放电用二值变量 (u_t) 控制[ 0 \le P_{ch,t}^B \le u_t P_{ch,\max},\quad 0 \le P_{dis,t}^B \le (1-u_t) P_{dis,\max} ]这个二值约束会把问题变成混合整数线性规划MILP求解时间会上升但对于24小时规模完全可接受。有些论文用“充放电功率差”表示净功率不考虑同充同放虽然简单但物理上是允许储能既买电又卖电的荒谬场景不推荐。超级电容的建模略有不同。它能量密度低、自损耗小、功率密度高我主要用它的快速响应能力所以模型里不再设SOC下限而是设一个“剩余能量比例”(E_{SC,t})初始容量一半允许在20%到90%之间运行。由于超级电容充放电效率接近1它的动态方程没有效率折减[ E_{SC,t1} E_{SC,t} - P_{net,t}^C \Delta t ]其中 (P_{net,t}^C) 是超级电容对外净功率正值为放电。同时给超级电容设更高的功率上限比如3 MW但容量只有0.5 MWh这决定了它只能扛短时冲击不能做长时间搬移。2.4 目标函数中各项成本的量纲怎么平衡刚做这个项目时我犯过一个低级的量纲错误电价单位是元/kWh储能维护成本是元/kW·次弃电惩罚是元/kWh直接相加结果优化器疯狂启停储能因为维护成本相对电价太小而被放大的弃电惩罚又逼着它用力。后来我统一改成“元/MWh”为颗粒度把所有成本折算到一个时间步1小时的等效费用上。举一个具体例子电池充电1 MWh放电0.93 MWh放电这部分可多获取电价差。如果峰谷电价差是0.6元/kWh1 MWh电经过电池后理论上能赚600元电费差但电池损耗、运维成本、SOC衰减折合约150元那这趟“搬移”净收益约450元。这样的核算逻辑要体现在目标函数里否则调度结果永远在“怎么算”上打架。联合储能里的超级电容运维成本更贵不能让它频繁参与小时级能量搬移否则成本会压过收益模型自然会让它闲置。3. 新能源消纳能力评估方法不是拍脑袋3.1 从“消纳率”到“最大消纳空间”大多数项目报告里都有“消纳率”这个指标它等于实际消纳新能源电量除以理论上可发电量。可光看一个数根本看不出系统的瓶颈在哪里。我在项目里做了一个更细的评估不只算总量还逐时段求“最大可消纳空间”。所谓最大可消纳空间是在给定负荷曲线、常规机组出力边界、储能运行约束、线路容量约束下通过优化模型最大化每个时段的消纳量或者等价的最小化弃电量得到的各时段可消纳的新能源出力上界。这个上界与新能源实际出力的差值就是该时段的“缺口空间”。缺口大的时段就是要重点关注的时间区间。这样做的好处是调度策略和消纳能力被放在同一个模型里求解。储能什么时候蓄电、什么时候放电已经由优化器按最优经济性安排好了评估结论不是脱离策略的“理论值”而是“可执行方案下的实际消纳能力”。3.2 基于优化模型的评估流程我在Matlab里的评估流程分四步。第一步输入基础数据配电网拓扑、线路参数、各时段负荷、新能源出力预测曲线、储能参数、分时电价。第二步建立与调度模型完全一致的目标函数和约束集合但把目标函数换成“最大化总消纳量”也就是 (\max \sum_t (P_{new,t}^{avail} - P_{curt,t}))其中 (P_{new,t}^{avail}) 是新能源理论可用出力。这样求解出来的弃电功率 (P_{curt,t}) 就是给定系统配置下的最小弃电。第三步遍历不同新能源配置。比如把光伏装机从5 MW逐步加到10 MW步长0.5 MW每次重复第二步记录总消纳率变化。多数情况下消纳率会先平缓下降然后在某一点出现快速下滑那个拐点对应的装机容量就是“经济消纳上限”。第四步输出瓶颈清单。列出所有时段里出现电压越限或线路潮流的活跃约束这些约束对应的支路和节点就是消纳能力提升的突破口。联合储能如果配置在那附近效果往往比放在远离新能源的节点要好。3.3 评估结果的实用判读节点、时段、网络薄弱位置实际做评估时最容易忽略的是“空间维度”。只看总体消纳率你会觉得系统还有余量但逐节点检查时发现某条10 kV馈线末端电压已经抬升到1.07 pu限流开关也在反复报警。这个节点接入的分布式光伏很少但它下游正好连着长距离轻载线路新能源的穿越潮流让电压严重偏高。联合储能如果在这条馈线末端参与调压比在变电站侧集中配置更管用。时间段上也要细化。我遇到过白天消纳良好但傍晚负荷尖峰期间光伏出力很低风机出力却很大储能因为白天已经充满晚间放不出来造成弃风。后来在模型中给电池SOC增加了“傍晚前必须预留20%容量”的软约束弃风量立刻降了下来。这种经验只有把调度和评估放在一起反复试算才会发现。4. Matlab实现代码结构、求解器调用与核心片段4.1 整体框架数据生成、模型搭建、求解、后处理我用Matlab写的那套代码大致分四个文件数据生成脚本、Yalmip模型构建函数、求解器调度脚本、结果可视化脚本。这样拆的好处是改参数不用翻模型改模型不用动数据。数据生成脚本里定义了所有常量节点数、支路矩阵、线路电阻电抗、负荷曲线、新能源出力曲线、储能参数、电价数组。支路矩阵我习惯用一个N_branch x 4的矩阵每一行是[起点节点终点节点电阻电抗]后续配DistFlow完全靠这个矩阵遍历。模型构建函数是核心输入是数据结构和决策变量集合输出是Yalmip的约束集合和目标函数表达式。求解脚本负责调用optimize并把结果写成结构化变量。可视化脚本则输出弃电曲线、SOC曲线、电压分布、消纳率对比图。4.2 Yalmip建模的关键写法Yalmip本身不求解优化问题它只做建模和转换真正求解要靠底层的求解器。我用的是商业求解器如果没有授权可以用开源求解器替代线性规划模型可以直接用linprogMILP模型就用intlinprog。重点是建模写法直接决定代码的可读性和调试效率。举一个电池SOC约束的Yalmip写法% 决策变量 P_ch_b sdpvar(1, T, full); % 电池充电功率 P_dis_b sdpvar(1, T, full); % 电池放电功率 SOC_b sdpvar(1, T1, full); % 电池SOC多一个端点值 u_b binvar(1, T); % 充放电状态 % 约束 Constraints []; Constraints [Constraints, SOC_b(1) 0.2]; % 初始SOC 20% for t 1:T Constraints [Constraints, SOC_b(t1) SOC_b(t) - ... (P_ch_b(t)*eta_ch - P_dis_b(t)/eta_dis) / E_B]; Constraints [Constraints, 0.1 SOC_b(t) 0.9]; Constraints [Constraints, 0 P_ch_b(t) 0.8*u_b(t)]; Constraints [Constraints, 0 P_dis_b(t) 0.8*(1-u_b(t))]; end这里我用sdpvar(1, T, full)生成一个行向量方便与时序数据相乘。如果把变量定义为(T,1)的列向量后面要到处转置容易搞混。DistFlow线性化的约束在循环里写。每条支路从起点到终点电压和潮流的关系是for t 1:T for k 1:N_branch i branch(k,1); j branch(k,2); r branch(k,3); x branch(k,4); Constraints [Constraints, V(j,t) V(i,t) - 2*(r*P_line(k,t) x*Q_line(k,t))]; end end这个线性化版本在电压接近1 pu时误差足够小工程上可用。如果要用二阶锥松弛需要再加一个辅助变量把支路功率和电压的关系写成锥约束篇幅原因我不展开但Yalmip有cone命令可以直接用。4.3 求解器设置与求解失败排查调用优化之前先把求解器参数设好。我常用的设置是ops sdpsettings(solver, gurobi, verbose, 1, ... debug, 1, gurobi.TimeLimit, 120); result optimize(Constraints, Objective, ops);这里的debug参数很关键。如果模型里面有NaN、Inf或者变量阶数不匹配导致的隐式冲突开debug会给出具体错误位置比翻公式高效得多。求解失败时第一步先查是不是有约束冲突比如SOC初始值和上下限自相矛盾或者某个功率变量范围写反。第二步查量纲把目标函数拆开看权重最大的项是否正常。第三步缩小时间步先用2个时段试跑确认模型结构正确再扩到24小时。我踩过一个非常典型的坑把线路功率上限设成了负数结果约束直接无解报错提示却是“Converged to an infeasible point”。这种时候不要急着改求解器容差先检查约束的符号和初值。4.4 典型代码片段一个可直接跑通的简化调度下面给一个简化但完整的示例只含单节点功率平衡不含潮流用来展示代码骨架。T 24; P_load [.. 24个数值 ..]; P_new [.. 24个数值 ..]; P_grid sdpvar(1, T); P_ch sdpvar(1, T); P_dis sdpvar(1, T); SOC sdpvar(1, T1); u binvar(1, T); Constraints [SOC(1) 0.2]; for t 1:T Constraints [Constraints, P_grid(t) P_dis(t) P_new(t) P_load(t) P_ch(t)]; Constraints [Constraints, SOC(t1) SOC(t) - (P_ch(t)*0.93 - P_dis(t)/0.95)/6]; Constraints [Constraints, 0 P_ch(t) 0.8*u(t)]; Constraints [Constraints, 0 P_dis(t) 0.8*(1-u(t))]; Constraints [Constraints, 0.1 SOC(t) 0.9]; end Objective sum(c_price .* P_grid) ... sum(P_ch P_dis) * 0.01 ... sum(max(0, P_generation_curve - P_dis_new?)); % 示意实际要定义变量 ops sdpsettings(solver, gurobi, verbose, 1); optimize(Constraints, Objective, ops);简化代码里弃电变量需要单独定义别像我示例里这样偷懒直接写maxYalmip对非线性的max支持有限最好引入辅助变量加不等式来线性化。5. 仿真案例与结果分析5.1 测试系统参数设置为了验证方法的有效性我构造了一个典型的10节点辐射状配电网额定电压10 kV总负荷峰值约12 MW线路参数采用标准型号的平均值。新能源部分接了一个5 MW的光伏电站和两台总共3 MW的风机理论日发电量约为24 MWh。联合储能配置为电池容量6 MWh额定功率1.5 MWSOC区间0.1-0.9超级电容容量0.5 MWh额定功率3 MWSOC区间0.2-0.9。分时电价采用当地工商业峰谷电价峰时0.98元/kWh平时0.65元/kWh谷时0.35元/kWh。对比场景设置三组A组无储能B组只有电池储能C组电池超级电容联合储能。三组的负荷曲线、新能源出力曲线、网络参数完全一致只改变储能配置。5.2 三种场景的调度结果对比先说消纳指标。A组无储能时全天累计弃电4.2 MWh弃电率17.5%主要弃电时段集中在午间光伏大发和夜间风电高峰。B组加入电池后弃电量降到2.1 MWh弃电率降到8.8%效果明显这是因为电池把午间多余电量搬到了晚间负荷高峰。C组联合储能后再看结果弃电量进一步降到1.3 MWh弃电率5.4%但额外节省的0.8 MWh并不是电池和超级电容“分摊”出来的——电池的调度结果和B组几乎一致多出来的消纳量基本是超级电容在午间光伏波动明显的区块内通过短时快速充电保住了原本会被弃掉的尖峰电量所以弃电曲线里被削减的主要是光伏出力曲线上的高频毛刺。电压方面A组午间节点电压最高到了1.062 pu已经接近越限阈值B组缓解到1.051 puC组进一步压到1.041 pu而且电压波动幅度明显收窄。这是因为联合储能里超级电容承担了高频波动抑制电池只需要在更从容的时间尺度上处理净负荷变化。运行成本方面A组购电费用加弃电惩罚折算后总成本为18.6万元B组由于储能在峰谷价差套利购电成本下降但维护成本上升总成本约16.9万元C组总成本约16.2万元。联合储能相比单独电池节省的0.7万元中约三分之二来自免于弃电的售电收益三分之一来自更少的电池深度充放电循环造成的寿命损耗——后者在简单模型里看不见只有把寿命折算成本放进去才会露出真实的收益空间。5.3 结果背后的物理解释联合储能不是“电池超容”的简单叠加很多人在读这种结果时会有一个直觉既然电池已经能把弃电率从17.5%压到8.8%超容再加进来只多压了3.4个百分点似乎性价比不高。但仔细看调度细节会发现联合储能的意义不只是多消纳了一部分电量而是让电池的运行曲线变得“更平缓”。B组电池的充放电转换次数为每天9次C组降到每天5次电池的平均充放电深度也从B组的62%降到C组的45%。超级电容的存在让电池可以更少地参与毛刺性的充电调节它只需在能量搬移的大周期上工作大幅延长了电池使用寿命。从系统角度再深挖一层电压越限和潮流越限的“尖峰时刻”往往只有10到20分钟而电池调度步长是1小时无法精细表达这种短时冲击。如果把电池功率上限强行提高去覆盖这个尖峰经济性很差而且电池会频繁过载。超级电容正好补上这个时间尺度的缺口。这就是联合储能的价值——用两种时间尺度的设备去匹配新能源波动的两个频率段物理上互补经济上也是更优的组合。6. 项目落地中的经验教训与实用建议6.1 参数定价对结果影响很大一定要做敏感性分析我最初在目标函数里把弃电惩罚系数固定为电价的两倍结果无论储能加多大弃电率都压不到理想水平。后来改成惩罚系数从0.5倍到5倍扫描发现弃电率随惩罚系数呈明显的饱和曲线——超过3倍后基本不再下降但总成本却一直在涨。这说明过分追求消纳率需要付出额外的储能磨损成本没有经济性的“100%消纳”在生产运营上不可持续。实际项目里应该先给出一个可接受的电价水平和弃电成本再反推最优储能配置。分时电价也一样。峰谷电价差小于0.4元/kWh时电池套利几乎无利可图优化器会倾向于让电池闲置所有消纳改善都靠被迫消纳的惩罚间接驱动。这时候评估出的消纳能力偏低不是因为储能不够而是电价信号不对。调整峰谷价差后电池的主动充放电积极性明显提升消纳能力也随之上升。很多论文的结论对电价参数极其敏感这是读者应用模型时需要小心的点。6.2 不要忽略储能寿命损耗成本纯从运行成本看电池频繁浅充浅放的维护成本很小但真实的电池寿命是随累计吞吐量衰减的。我建议在目标函数中追加一个简单的寿命损耗惩罚项每次充放电按吞吐电量折算成等效循环数再乘上单位循环损耗成本。这样优化器会自动避免无谓的充放电转换效果在联合储能模型中尤其明显——超级电容承载高频分量后电池的等效循环数从每天1.8次降到0.9次。有读者问我超级电容不也有寿命损耗确实有但超级电容循环寿命动辄数十万次在日调度尺度下几乎可以忽略。所以在成本模型里我对超级电容只算运维成本不再算循环损耗这样处理在工程上是合理的简化。6.3 评估结果要和调度策略联动不要“评估一套、调度一套”我在项目早期走了弯路先用一组保守的调度参数算出消纳上限然后在实际操作里用另一套更激进的目标。结果调度执行时频繁触碰电压上限被迫手动弃电实际消纳率比评估值低了6个百分点。后来我把评估模型和调度模型统一评估时输出每一时段对应最优调度给出的储能功率指令让运行人员直接按这个指令执行才真正兑现了理论上的消纳空间。如果你的项目只是要“写一份评估报告”那可以不用管调度联动但如果要真的提高新能源消纳调度策略和评估模型必须同源、同步更新。6.4 后续扩展多时间尺度、不确定性、实时控制这篇博文里的模型是确定性优化新能源出力曲线按预测值给定。实际操作中预测误差会带来风险更进一阶的做法是引入场景法或鲁棒优化把光伏和风电的预测误差生成多个典型场景目标函数改为期望成本最小约束里加入随机变量的区间限制。我后来在模拟项目里试过用20个场景并行的方式求解时间从十几秒涨到几分钟但消纳率指标更稳定不会因为某个时段预测偏差过大而完全失效。另外调度步长从1小时细分到15分钟能把超级电容的秒级影响更真实地表达出来。但那样模型规模会变成96时段MILP求解时间成倍增加对配电网系统的实时控制来说更推荐分层方案上层日调度用1小时步长做经济决策下层实时控制用5分钟或1分钟步长做功率平抑。联合储能里的超级电容在下层控制器里承担主要快速调节任务电池按上层指令跟踪即可。这套分层思路也是当前工程界比较认可的应用方向。最后说一个我自己在项目里反复验证的建议做这类研究一定要把“基础无储能场景”先跑通它的结果就是你所有改进方案的基准线。联合储能效果好不好不看绝对消纳率而看在你给定的网络结构、电价体系、负荷曲线和新能源波动特性下相比基准线多消纳了多少、花了多少成本。只有把这个账算清爽配电网里的储能配置和调度优化才是真正对得起投资的。