ARTICLE DETAIL

资讯详情

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

配电网分布式光伏与储能选址定容:基于Matlab和MatPower的双层优化模型

配电网分布式光伏与储能选址定容:基于Matlab和MatPower的双层优化模型 配电网里塞进分布式光伏和储能这两年已经是常规操作了。但真正做规划项目的时候会发现最难回答的问题往往不是“要不要装”而是“装在哪、装多大、怎么和运行配合”。这篇博客聊的就是这个问题用Matlab和MatPower搭一个配电网光伏储能双层优化配置模型在IEEE33节点系统上做选址定容。全文会把数学建模、代码架构、参数设置、求解流程和调试经验一并写下来给正在做同类研究、写毕业论文或者做实际规划方案的朋友作参考。这篇文章不是把一堆公式扔给你就完事。我会把每个环节的“为什么”都讲清楚为什么双层比单层合适为什么上层用粒子群、下层用MatPower为什么IEEE33节点适合做测试平台储能SOC约束怎么处理才不会让结果失真。如果你已经会基本的Matlab操作、了解潮流计算的基本概念就可以直接跟着思路走。1. 为什么选址定容要用双层优化1.1 单层模型的尴尬投资决策和运行调度被绑在一起很多刚接触这个方向的同学第一反应是把光伏和储能的位置、容量、以及全年8760小时的运行状态全部塞进一个优化模型一次性求解不就行了理论上可以但实际一跑就发现坑很多。第一个问题是时间尺度不匹配。选址定容是年度的投资决策储能充放电是小时级的运行决策。如果把两个时间尺度揉进同一个模型变量维度会爆炸式增长。假设有33个节点每个节点可以装光伏和储能光容量变量就几十个再乘上8760小时的运行变量规模直接到上百万级。一般的非线性规划求解器根本吃不消就算勉强能算收敛性和解的可解释性也都很差。第二个问题是目标函数相互干扰。投资成本是“一次性花多少钱”运行成本是“每年花多少钱”两者要通过等年值或者折现才能比较。如果放在一个目标函数里权重怎么给都会引入主观性而且很容易出现“为了省5%的网损多花三倍的投资”这种明显不合理的结果。我见过不少单层模型跑出来的最优方案是全网每个节点都装一点点光伏工程上完全没法落地。第三个问题更现实单层模型通常假设运行策略是完美最优的但实际运行中调度员根本做不到理想化。比如储能什么时候充、什么时候放这是需要独立建模的调度问题不应该和投资决策糊在一起。1.2 双层模型的分工逻辑投资决策在上层运行调度在下层双层优化把问题拆成了两个层级各干各的活。上层负责选址定容对应的是规划人员的工作决定在哪些节点安装光伏和储能分别装多大容量。它的输入是系统的基础数据输出是一个具体的“配置方案”。上层并不关心具体哪一天几点几分储能充了多少电它只关心这个方案在全生命周期内划不划算。下层负责运行调度对应的是调度人员的工作给定上层的配置方案后按典型日的时序数据优化出每一天的储能充放电计划、光伏出力分配、以及从上级电网买多少电。下层的优化结果会反馈给上层作为上层评估这个配置方案优劣的依据。这种分层结构最大的优势是逻辑清晰。上层不需要知道下层的每一个细节只需要拿到下层返回的年度运行成本、网损等指标就能判断这个选址定容方案好不好。下层也不负责为投资决策背书只需在给定设备条件下把运行成本降到最低。两层各算各的账再通过迭代交互收敛符合实际的规划-运行流程。拿生活类比一下就很好懂上层是“在哪里开工厂、工厂建多大”下层是“工厂建成后怎么排班生产最省钱”。建厂的时候不可能把所有可能的排班组合全枚举一遍而是先定厂址和产能再在运营层面对每个生产计划做模拟评估反馈给决策层调整建厂方案。1.3 本文选型思路PSO加MatPower为什么不用商用求解器硬解确定用双层模型之后还有一道选择题上下两层用什么算法求解上层是离散决策变量节点编号和连续变量容量混合而且目标函数不可导因为下层返回的运行成本是个隐函数没有显式梯度。这类问题最成熟的做法就是元启发式算法粒子群PSO、遗传算法GA、鲸鱼算法、灰狼算法都有人用。我一般默认选PSO因为它参数少、实现简单、工程上最不容易出幺蛾子。后面会详细讲PSO怎么编码和调参。下层是一个典型的经济调度加最优潮流问题可以采用数学规划方法精确求解。这个环节我最常用的工具就是MatPower加Matlab优化工具箱。MatPower是Matlab生态里做电力系统潮流计算最成熟的开源工具包函数封装得很干净调用一次潮流计算就一行runpf非常适合在优化迭代里反复调用。大部分商业求解器要求你把配电网的潮流方程全部转化成二阶锥或线性约束建模工作量很大而且调试困难。用MatPower在迭代中做潮流验证虽然速度不算极快但胜在准确、省事、不容易出错。2. 数学模型目标函数、约束与关键参数2.1 上层选址定容的目标函数与投资年值折算上层目标函数的基本思路是把整个寿命周期内的投资成本和运行成本折算成年值再叠加起来比较。用公式表达大致是min F_upper C_pv_inv C_ess_inv C_om C_loss_annual C_elec_annual其中C_pv_inv表示光伏投资的等年值成本。C_ess_inv表示储能投资的等年值成本。C_om表示年均运维成本。C_loss_annual表示年均网损费用。C_elec_annual表示年均购电费用。这里有个关键概念叫等年值折算。光伏和储能的寿命不一样储能电池可能只有10年光伏组件能用20到25年不能直接把投资额相加就完事。工程上一般用资本回收系数CRF把总投资的现值换算成每年等额支付的钱。公式是CRF r * (1 r)^n / ((1 r)^n - 1)假设折现率r取6%光伏寿命n取20年算一下CRF约等于0.0872。也就是说如果光伏总投资是100万元折算到每年相当于8.72万元。储能如果寿命按10年算CRF大约是0.1359。这个折算逻辑很关键很多论文里只写了“投资成本”没有注明折算方式结果不同方案之间根本没法公平比较。光伏投资按下式折算C_pv_inv CRF_pv * c_pv * Σ S_pv,i其中c_pv是光伏单位容量投资价格元/kWS_pv,i是第i个候选节点安装的光伏容量。储能投资要分能量和功率两部分C_ess_inv CRF_ess * (c_ess_e * Σ E_ess,i c_ess_p * Σ P_ess,i)这里的c_ess_e是储能单位能量容量价格元/kWhE_ess,i是安装的储能容量c_ess_p是储能PCS单位功率价格元/kWP_ess,i是储能功率上限。为什么要分开算因为储能系统由电池堆和变流器构成电池堆的成本按容量算变流器按功率算它们寿命和造价都不一样混在一起会算错账。运维成本按初始投资的一定比例估算。光伏年运维费率一般取1%左右储能因为有电池维护、温控系统取2%左右。这类参数不同文献差异很大实际做项目时按当地历史运维数据调整。2.2 下层运行调度的目标函数与储能SOC约束下层运行调度的目标是在给定光伏和储能配置下最小化一个典型日的运行成本。典型日不是随便挑一天而是用负荷曲线和光伏出力的典型模式来代表整个年度通常选夏季大负荷日、冬季大负荷日、过渡季普通日等场景按天数加权汇总成年值。下层的日运行成本包含三个部分min F_lower Σ_t ( c_buy,t * P_buy,t c_curtail * P_curtail,t c_bat_deg * |P_bat,t| )第一项是从上级电网购电的成本。P_buy,t是时刻t从根节点买入的有功功率c_buy,t是分时电价。第二项是弃光惩罚。光伏出力超过逆变器上限或者电网消纳能力时被迫切掉这部分电量以惩罚系数计入成本。弃光惩罚的用意很直白光伏装机不是越大越好如果装到大量弃光经济性反而会变差。第三项是储能寿命损耗成本。电池每充放一次都在消耗循环寿命如果模型不惩罚充放电量优化器会把储能当成免费工具结果往往是每天满充满放严重高估储能收益。加一个很小的电池退化系数就能让结果贴近工程实际。储能的运行约束是下层模型的核心尤其是SOC约束SOC_t SOC_{t-1} η_ch * P_ch,t * Δt / E_ess - P_dis,t * Δt / (η_dis * E_ess)其中SOC是荷电状态η_ch和η_dis分别是充电和放电效率P_ch和P_dis分别是充放电功率E_ess是储能容量。充电时SOC上升放电时SOC下降。这个递推关系把不同时段耦合在一起是储能调度和普通发电机调度最大的区别。同时必须限制SOC的上下限一般取0.1到0.9。这个限制非常重要。很多人调模型时发现储能收益虚高查来查去最后发现是SOC下限设成了0。实际电池在SOC过低时内阻增大、寿命快速衰减而且过度放电有安全隐患所以一定要留出保护区间。2.3 潮流约束与电压、支路容量校验下层优化得到的运行计划必须满足系统潮流约束这也是MatPower发挥作用的地方。配电网的潮流方程是非线性的以极坐标形式表示为P_i V_i Σ_j V_j (G_ij cosθ_ij B_ij sinθ_ij) Q_i V_i Σ_j V_j (G_ij sinθ_ij - B_ij cosθ_ij)P_i和Q_i是节点注入有功和无功V_i是节点电压幅值G_ij和B_ij是导纳矩阵的实部和虚部θ_ij是节点间的相角差。在MatPower中这套方程被封装在内部不需要自己手写雅可比矩阵直接调用runpf即可。电压约束写为0.95 ≤ V_i ≤ 1.05单位是标幺值。在IEEE33这样的配电网中如果不接入任何分布式电源重负荷时末端节点电压可能掉到0.90左右这就是需要光伏和储能改善的痛点。支路容量约束通过潮流计算结果的支路电流和视在功率来判断越限时返回惩罚项。潮流校验放在下层调度的最后一步先用经济调度算出各时段的储能充放电功率和光伏出力再把它转成各节点的注入功率调用runpf算潮流从结果中读取网损、节点电压和支路负载率。如果潮流越限就对上层返回惩罚值。这种“调度-潮流校验”分离的做法比直接做带约束最优潮流简单很多而且能直观看出方案在哪个时段、哪个节点出了问题调试效率高太多。3. MatlabMatPower实现方案架构3.1 为什么选MatPower它与自带潮流函数比强在哪Matlab自带的Simscape Electrical模块也可以搭建配电网模型甚至可以做电磁暂态仿真但那套工具更适合动态分析放进优化迭代里速度太慢。而且Simscape的模型是基于物理拓扑的每次改节点注入功率都要重新修改模块参数很不适合批量迭代。MatPower走的是矩阵化数据格式整个电网就一张表改一个参数就是改表的某个位置天然适配优化算法批量调用。MatPower最强的地方有三点第一内置了多种潮流算法包括牛顿法、PQ分解法、Gauss-Seidel法通过mpoption切换遇到难收敛的网络可以换算法第二数据格式标准化用的是case结构体里面包含bus、branch、gen三大矩阵这是Matlab矩阵运算的强项第三它有配套的opf函数内置内点法求解器如果不用也不影响单独调用runpf做潮流校验。实际对比下来MatPower跑一次IEEE33节点的交流潮流非常快单次运行在几十毫秒量级。这个速度决定了双层迭代的次数上限一次潮流计算几十毫秒一个方案要跑24个时段的潮流那就是一两秒的量级再乘上粒子群里的几十个粒子和上百轮迭代整个计算时间从几分钟到几十分钟不等。如果没有MatPower这个轻量级工具换成每次调用外部求解器计算时间会翻好几倍。3.2 代码模块划分与数据流向整个项目的代码不复杂但如果不做好模块划分几个文件攒下来就乱成一锅粥。我的习惯是严格分五个模块每个模块一个函数文件第一个模块是参数定义文件把所有经济参数、系统参数、算法参数集中放在一起。包括投资单价、寿命、折现率、分时电价、PV和ESS的技术约束、PSO的粒子数、迭代次数等。参数集中管理的关键好处是调试时不需要到处翻文件改一个参数全工程生效。第二个模块是系统初始化模块。负责生成IEEE33节点的mpc结构体加载负荷曲线和光伏出力曲线建立候选安装节点集合。第三个模块是上层PSO模块。负责种群初始化、计算适应度、更新粒子的位置和速度。每个粒子的解码结果会输出给下层模块。第四个模块是下层运行调度模块。输入是上层传来的配置方案输出是该方案下的日运行成本、网损、SOC曲线、最低电压等运行指标。第五个模块是主程序。负责把前面四个模块串起来控制迭代循环保存每一轮的中间结果生成最终输出。数据流向非常清晰主程序调用PSO模块生成粒子粒子通过解码得到配置方案配置方案传给下层模块做运行调度和潮流校验下层模块返回的指标被主程序换成适应度值再回传给PSO模块更新粒子位置直到收敛。3.3 关键函数mpc结构体、runpf与mpoptionMatPower的核心数据结构是mpc结构体它有bus、branch、gen、baseMVA四个关键字段。bus矩阵描述节点信息常用列包括BUS_I节点编号BUS_TYPE节点类型1为PQ节点2为PV节点3为平衡节点PD和QD有功和无功负荷Vm和Va电压幅值和相角初值baseKV基准电压branch矩阵描述支路信息常用列包括F_BUS和T_BUS首端和末端节点编号BR_R、BR_X、BR_B电阻、电抗和电纳RATE_A支路容量上限gen矩阵描述发电机信息常用列包括GEN_BUS发电机所在节点PG和QG有功和无功出力VG电压幅值设定PMIN、PMAX、QMIN、QMAX出力上下限在配电网里加入光伏时最稳妥的做法不是往gen矩阵里加行而是把它表现为一个负的有功负荷同时把逆变器的无功出力按功率因数折算成对应的无功负荷。这样做的好处是节点类型不用改始终是PQ节点潮流计算不会因为PV节点无功越限而反复调整。调用潮流的代码基本是这样mpc_modified loadcase(case33); % 修改节点注入功率例如节点18加500kW光伏功率因数0.95 mpc_modified.bus(18, PD) mpc_modified.bus(18, PD) - 500; mpc_modified.bus(18, QD) mpc_modified.bus(18, QD) - 500 * tan(acos(0.95)); opt mpoption(OUT_ALL, 0, VERBOSE, 0); results runpf(mpc_modified, opt);option里OUT_ALL设为0是为了关掉MatPower的屏幕输出。优化迭代中要跑成百上千次潮流如果每次都打印一遍结果不仅刷屏而且拖慢速度。求完潮流之后从results结构体读取信息bus_va、bus_vm是电压branch里可以取网损gen矩阵里的平衡节点有功就是购电功率。4. IEEE33节点算例搭建与参数设置4.1 IEEE33是什么为什么拿它当测试平台IEEE33节点系统是配电网研究领域使用最广泛的标准测试系统之一。节点编号从1到33其中1号节点是根节点连接上级电网电压等级为12.66kV基准容量取10MVA。系统总负荷约3715kW加2300kvar有32条支路和5条联络开关支路整体呈辐射状运行。这个系统之所以受欢迎有三个原因。第一数据公开且经典。它来自实际配电馈线的简化模型线路参数、负荷分布都有标准数值论文之间可以公平横向对比。第二规模适中。33个节点对于教学、算法验证、模型测试来说不算大调试方便但同时又具备配电网的关键特征比如线路较长导致末端电压偏低。第三问题特征明显。在最大负荷状态下不做任何优化时末端节点电压可能跌破0.90的标幺值线损也比较高这就给了光伏和储能优化配置一个很清楚的目标。实践中最常用到的输出指标就是“接入前后末端电压改善程度”和“网损下降率”。一台500kW的光伏若安装在末端节点附近对末端电压的提升效果立竿见影这是选址定容中的典型验证。4.2 光伏时序出力与负荷曲线建模光伏出力不是恒定功率它随着光照强度、温度、云层遮挡实时变化。在规划模型中不需要精确到分钟级的波动一般用一个典型日的小时级归一化出力曲线表示。假设光伏在12到13点出力最强按标幺值近似描述时段归一化出力系数06:00-07:000.1008:00-09:000.3510:00-11:000.7812:00-13:000.9514:00-15:000.8016:00-17:000.4018:00-19:000.10其他时段0这个曲线是基于晴朗夏季白天的典型出力形态。实际项目里更严谨的做法是对当地一整年的历史光照数据做聚类分析比如用K-means把光照曲线聚类成晴天、多云、阴天三类再按各类天数加权。没有实测数据时按这个典型曲线建模也足够做方案比选。负荷曲线同理。IEEE33的总负荷是3715kW峰值实际运行时一天的负荷系数在0.5到1.0之间波动。可以取一组典型日负荷系数结合系统基础负荷生成各时段系统总负荷P_load,t C_load,t * P_peakC_load,t的典型值在夜间低谷时段为0.55左右午间为0.75左右晚高峰时段达到0.95以上。配电网规划中用典型日曲线代替全年8760点计算量能缩小两个数量级且不影响方案排序的准确性。4.3 储能模型参数与分时电价设定储能模型参数要区分能量型参数和功率型参数。以一个400kW/800kWh的储能系统为例额定功率P_ess为400kW额定容量E_ess为800kWh充电效率η_ch为0.95放电效率η_dis为0.95SOC运行范围0.1到0.9单次循环寿命损耗成本约0.2元/kWh这个SOC范围意味着实际可用的能量只有容量的80%也就是640kWh。在优化模型中千万别直接用额定容量去算可用电量不然储能收益会被明显高估。分时电价是储能套利的直接动力。用一个典型的三段式峰谷电价谷段23:00至次日08:000.3元/kWh平段11:00至18:00以及21:00至23:000.6元/kWh峰段08:00至11:00以及18:00至21:001.0元/kWh谷时充电、峰时放电每度电的价差是0.7元扣除充放电效率损耗和电池退化成本之后仍有可观的套利空间。但储能的实际收益必须减去效率损耗。比如充1kWh电实际放出来的只有0.95乘以0.95约等于0.9025kWh。也就是说即使峰谷价差0.7元实际有效价差只有0.63元左右。很多初版模型算出的储能收益偏高就是漏了效率链的折损。4.4 候选安装节点与PSO编码设计IEEE33有33个节点不代表每个节点都要纳入候选集。对现有配电网络来说改造条件往往受限有的节点没有足够的空地有的节点变压器容量已经接近上限有的节点业主不同意安装。工程化一点的处理方式是先做一次基于电压灵敏度的筛选选出对电压支撑效果较好、改造条件允许的节点作为候选集再在候选集中优化。实际算例中一般选8到12个候选节点例如节点8、18、22、25、33这些负荷较重或者处于线路末端的节点。候选节点少搜索空间就小PSO收敛明显更快。PSO粒子编码是上层实现的关键。一个粒子的向量可以设计为[光伏候选节点编号1到Npv 光伏容量1到Npv 储能候选节点编号1到Ness 储能容量1到Ness]光伏节点和容量一一对应储能同理。粒子维度等于2倍的光伏安装点数加上2倍的储能安装点数。对所有变量统一做归一化处理位置更新后再取整和映射到候选节点集合。还要处理几个实际问题一是光伏和储能可能装在同一节点这种组合常见且合理因为储能可以平抑光伏出力波动但编码时要保证容量不超出现场条件二是同一节点光伏容量和储能容量要设上限防止算法给出“在单节点装10MW光伏”这种脱离实际的解三是对位置变量要做去重检查同一个节点不能重复出现在同一类设备的选址列表里。PSO参数方面常用的设置是种群规模30最大迭代次数50到100惯性权重从0.9线性递减到0.4个体学习因子和群体学习因子都取1.5。这些参数不是拍脑袋定的是经过多次试算的经验值。惯性权重从大调到小前期保证全局搜索能力后期增强局部收敛精度避免了早期就陷入局部最优的问题。5. 双层求解流程与结果分析思路5.1 PSO求解上层的完整流程PSO求解上层的完整流程我按顺序展开。第一步初始化种群。随机生成30个粒子每个粒子是一组选址定容方案。位置和速度都在给定范围内初始化。特别提醒初值最好不要完全随机可以把“末端节点多装光伏、负荷中心装储能”这种启发式经验掺进去生成一两个质量较高的初始方案这样能明显加快收敛。第二步计算适应度。对每个粒子解码得到光伏和储能配置方案调用下层模块计算该方案下的运行成本和潮流指标再结合投资成本计算总适应度。第三步更新个体最优和全局最优。每个粒子的当前适应度与自己历史最优比取更小的作为个体最优所有粒子中的最优个体更新为全局最优。第四步更新速度和位置。速度更新公式为v_i(k1) w * v_i(k) c1 * r1 * (pbest_i - x_i(k)) c2 * r2 * (gbest - x_i(k))位置更新为x_i(k1) x_i(k) v_i(k1)其中w是惯性权重c1和c2是学习因子r1和r2是在0到1之间的随机数pbest是粒子的历史最优gbest是全局最优。更新之后要检查新的位置是否在允许范围内是否违反候选节点重复限制。如果违反做边界修正或者重新初始化该维度。第五步判断终止条件。达到最大迭代次数后停止输出全局最优粒子作为选址定容最终方案。5.2 下层调度优化的实现细节下层模块接收到一个配置方案后先确定该方案下光伏在各时段的出力上限、储能充放电功率上限和能量容量然后开始求解日运行成本最小化问题。由于下层的目标函数包含SOC的时序变量和分时电价适合用线性规划或者二次规划求解。我经常直接使用Matlab的linprog或者通过YALMIP调内置求解器。如果不想引入额外工具箱直接用fmincon加线性约束也可以因为目标函数是线性的约束主要是线性等式和不等式求解难度不大。求解过程中最关键的是正确处理SOC的时序递推。要把24个时段的SOC都设置成决策变量并用“当前时段SOC等于上一时段SOC加充电量减放电量”这样的等式约束串联起来。同时加上SOC上下限约束、充放电功率约束、以及光伏出力和系统功率平衡约束。求解完成之后得到一个完整的充放电计划和SOC轨迹。接下来把各时段的光伏出力和储能有功注入翻译成节点注入功率更新mpc结构体调用runpf逐时段做潮流校验。注意充电和放电的符号光伏发电节点有功负荷减去光伏出力储能放电节点有功负荷减去放电功率储能充电节点有功负荷加上充电功率每个时段潮流计算完成后从results结构体中提取当前时段的网损、节点最低电压、支路最大负载率。如果潮流不收敛或者电压越限就对该方案记一次违规并在适应度中叠加惩罚项。这个“经济调度加潮流校验”的组合既能保证调度方案的可行性又能把潮流非线性约束从优化模型里“拆”出来大大降低求解难度。5.3 适应度计算、惩罚函数与迭代终止条件上层的适应度是整个模型的核心信息流。单个方案的总适应度不是简单的投资加运行而是要把投资折成年值、把典型日运行成本折算成年值再叠加罚函数。适应度表达式如下F C_inv_annual 365 * F_lower_daily C_loss_annual F_penalty需要特别说明的是用365乘日运行成本是近似做法。更严谨的方法是用不同类型典型日的数量加权求和比如夏季日120天、冬季日120天、过渡季125天。如果有多个典型日下层模块会对每个典型日均做一次调度优化然后将结果加权合计。这种处理比简单乘365准确得多但也相应增加了计算量。惩罚函数用来处理不可行解。当上限层给出的方案导致潮流不收敛或者电压越限时不能简单丢弃这个粒子不用因为这样会浪费大量计算资源。更合理的方式是给这个粒子一个很大的适应度值让它在竞争中自然被淘汰。惩罚函数的基本思路是F_penalty C_punish * (违规程度1 违规程度2 ...)电压越限越严重惩罚越大潮流不收敛则直接加一个极大的常数并将其记为不可行解。实测中罚系数一般取1e6到1e8量级太小的话不可行解可能混进最优解太大则会掩盖正常解法间差异导致搜索方向丢失。迭代终止条件也不一定非要用最大迭代次数。如果全局最优解连续10代都没有改进基本可以认为已经收敛提前退出能节省大量时间。我的做法是在主循环里加一个计数器连续无改进代数超过设定值就终止同时把最大迭代次数设为硬上限防止极端情况下卡死。5.4 结果分析选址方案、网损、电压与SOC曲线结果分析是整个项目最能体现价值的环节。算例跑完以后最直接的结果是一张选址定容方案表例如安装位置设备类型安装容量节点18光伏500 kW节点22光伏400 kW节点25储能300 kW / 600 kWh节点33光伏300 kW方案确定后要从多个维度评估它到底好不好。第一看网损改善。IEEE33原始系统的网损在不同负荷水平下差异较大。在重负荷场景下未接入DG时网损可能达到200kW以上接入合适的光伏储能后能降到100kW以下降幅通常能达到30%以上。这个数据是判断模型是否有效的关键证据。第二看电压改善。对比接入前后各节点电压分布重点关注最低电压节点。一般情况下末端节点电压能从0.90左右提升到0.95以上。如果只装光伏不装储能白天电压改善明显但晚高峰负荷最大时光伏没出力电压问题依旧存在。这恰恰说明了储能的价值在晚高峰放电能持续提供电压支撑。第三看储能SOC轨迹。合理的储能SOC曲线应该是谷时充电、峰时放电SOC在0.1到0.9的范围内平滑变化一天结束回到接近初始值这样才能保证每天的调度策略可持续。如果SOC曲线出现频繁的锯齿状跳变往往说明目标函数里缺少充放电次数或者退化成本的约束需要回去检查参数。第四看经济性指标。总投资等年值、年运行成本、年购电费用、光储联合方案和纯光伏方案的对比这些数据能说明储能在系统里到底起到了什么作用。注意储能配置未必越大越好因为电池成本高如果套利收益和降损收益抵不过投资成本最优方案可能只配光伏不配储能或者配置很小的储能容量。真实算例里这种结论经常出现不代表模型有问题恰恰证明模型是诚实的。6. 常见问题与调试实录6.1 MatPower潮流不收敛或电压越限怎么处理跑双层优化的前期阶段遇到最多的问题是runpf返回success等于0也就是潮流不收敛。这种问题在IEEE33这种算例里很罕见毕竟系统规模和网络参数都很标准但一旦出现往往原因是节点注入功率改得离谱。比如某个候选节点的光伏容量设到了几千千瓦远超该节点附近线路和变压器的承受能力潮流肯定算不出来。处理办法其实很简单。第一批量调用runpf时不要直接硬算先用mpoption调整算法参数例如把最大迭代次数从默认值改大、把潮流计算精度适当放宽。第二检查每个节点注入功率是否在合理范围尤其注意储能充电时节点负荷会瞬时增大很多倍可能把该节点电压拉低到不可收敛的范围。第三对不可行方案不要强求收敛直接用惩罚函数处理并跳过潮流结果。还有个实用技巧是给每个节点设置初始电压。配电网正常情况下所有节点电压都在0.95到1.05之间但MatPower默认的平启动可能让某些弱节点电压从0.9开始迭代加大计算难度。可以先把根节点设为参考其他节点电压初值设为1.0功率注入为零先算一次空载潮流再把实际注入功率代入往往能提高收敛的成功率。6.2 储能SOC曲线振荡调度结果不合理的根因如果储能SOC曲线出现一个小时内从0.2跳到0.9、又马上跌回0.3的情况基本可以断定下层调度模型出了问题。最常见的原因是充电和放电功率同时大于零。在优化模型中充放电功率虽然是两个独立变量但如果不加二者互斥的约束求解器可能为了追求目标函数值的微小下降安排储能在同一时段又充电又放电导致SOC剧烈波动。解决方法是加一个非线性的互斥约束P_ch * P_dis 0但这个约束让问题变成非线性。更简单的方法是引入充放电状态变量充电状态为1时放电功率强制为0用0到1的整数变量表示。如果嫌整数求解慢退一步可以给充放电功率加一个很小的惩罚系数。大多数情况下加上电池退化成本后求解器自然会避免无意义的充放电循环。另一个导致SOC异常的原因是初始SOC设置不当。初始SOC应取中间值比如0.5同时要约束一天结束后SOC回到接近初始值。如果不加“SOC末态等于初态”的约束模型会把一天结束时SOC放空或者充满得到的结果没法长期循环使用。6.3 双层计算量太大如何加速双层优化的计算量问题是所有做这个方向的人都会撞上的墙。上层粒子群有30个粒子、迭代50代下层每个方案要跑24个时段的潮流总共就是30乘以50乘以24等于36000次潮流计算。每次潮流虽然只要几十毫秒但累计起来就是很可观的耗时如果再算上经济调度优化整体时间可能长达数小时。加速手段我亲测有效的有几个。第一用典型日代替全年8760小时这个前面已经讲过是最直接的降维手段。第二引入计算缓存。如果两个粒子解出来的配置方案在某个候选节点上的容量完全一致那么这些重复方案完全可以跳过重复的下层优化直接复用缓存结果。在粒子群后期会有大量粒子围绕全局最优附近重复概率很高缓存能节省30%以上的计算量。第三使用并行计算。Matlab的parfor可以轻松把多个粒子的适应度计算并行化。不同的粒子之间相互独立给parfor不需要改太多代码只要把循环里的随机数种子处理干净避免并行时破坏随机性。普通四核八线程的机器就能提速三到五倍。第四降低调度优化的求解精度。不能用普通精度的求解器跑到底。先设松一点的容差快速筛掉明显差的方案最后几代再用高精度重新求解候选最优方案这样可以大幅减少总计算时间。6.4 粒子群早熟与选址结果不稳定PSO最常被吐槽的问题是早熟收敛也就是迭代不到20代就停在某个局部最优解附近每次运行得到的选址结果都不太一样。这种情况在配电网优化里很常见因为目标函数地形非常崎岖多个局部最优解之间差别不大。我踩过几次坑之后形成了一套组合拳。第一种群规模不能太小至少30个粒子如果候选节点多建议增加到50。第二惯性权重必须递减从0.9逐渐降到0.4让粒子前期大步探索、后期小步收敛。第三把大约10%的粒子在每次迭代时重新随机初始化这个“变异”操作在很大程度上防止种群过早聚集。第四每次运行不是跑一次就收工而是连续跑多次把多次运行的最优解汇总比较选适应度最低的一次。工程上宁可多花时间多跑几遍也不要在单次运行结果上轻易下结论。关于PSO和下层求解器的交互还要特别注意数值精度问题。下层返回的适应度如果在小数点后几位有微小变化PSO的速度更新会把这种噪声当成梯度信号导致粒子乱跳。我的一般做法是把适应度值做取整处理例如保留到小数点后两位消除无意义的细微抖动模型稳定性会明显提升。最后分享一个实操中的体会做这类双层优化项目真正耗时间的往往不是写代码跑模型而是花在结果合理性检查上。每次跑完一组算例都先问自己三个问题选址位置符不符合工程直觉网损下降幅度是不是在合理范围内SOC曲线是不是符合“谷充峰放”的预期。模型输出违背工程直觉的时候优先怀疑参数设置和约束遗漏不要一头扎进算法调参里出不来。能复现合理的物理结果这个模型才算真正立住了。
返回列表