☰
风电光伏与废弃矿井抽蓄互补调度:Matlab建模与仿真
2026/10/10 11:08:39 网站建设 项目流程

风电、光伏与储能(含废弃矿井小型抽水蓄能)互补调度运行研究,这个方向近几年在新型电力系统领域讨论度一直很高。原因不复杂:风电光伏装机上得飞快,但出力不稳定这个老问题始终绕不开,单纯靠电网调度去平衡越来越吃力,储能就成了调节的刚需。而把电池储能和废弃矿井抽水蓄能放在同一个框架里研究互补调度,关键是想解决一个实际问题——不同储能介质的响应速度、容量规模、成本特性差异很大,怎么配合风电光伏的出力波动,让系统整体运行最经济、最可靠。这篇内容我结合自己做过的Matlab仿真经验,把这个研究方向涉及的建模思路、调度框架、代码实现和常见坑完整拆一遍,希望能帮到正在做相关课题的同行。

1. 项目整体设计与思路拆解

1.1 互补调度的本质是什么

先说清楚“互补调度”这四个字到底在调什么。风电和光伏的出力都有明显的间歇性和随机性,但在时间尺度上恰好存在一定互补关系——白天光伏出力强,夜间风电往往更充沛;晴天风小,阴雨天风反而常来。这种天然的资源互补是第一个层面的“互补”。但光靠风光的自然互补远远不够,因为负荷曲线不配合,比如傍晚光伏骤降、风电还没起来、负荷却处在晚高峰,这时候就需要储能介入。所以第二个层面的“互补”是风光出力和储能调节能力的互补:让储能去弥补风光预测误差和负荷偏差,实现系统功率平衡。

这个研究把储能又进一步拆成电池储能和废弃矿井小型抽水蓄能两类,这就有了第三个层面的互补。电池储能响应速度快(毫秒到秒级)、布置灵活,但容量成本高、循环寿命有限;抽水蓄能响应速度慢一些(分钟级)、功率密度低,但单次循环成本极低、寿命长,适合大容量长时间尺度的能量搬移。把两者放在一个调度模型里互补使用,本质上是在做时间尺度上的分工:抽蓄负责削峰填谷、大能量吞吐,电池负责快速跟踪、平滑短时波动。这个设计思路在实际工程项目里非常常见,比如一些风光基地配套的“新能源+储能”项目中,混合储能方案正在成为主流。

1.2 为什么选择Matlab做这个研究

做这个方向的研究,工具选择其实比较固定。Matlab在电力系统领域的使用率仍然是最高的,原因有三点:第一,Matlab的矩阵运算天然适合电力系统的潮流计算和优化求解;第二,Optimization Toolbox和Global Optimization Toolbox提供了一整套现成的优化算法接口,从线性规划、整数规划到粒子群、遗传算法都有成熟实现;第三,Simulink可以搭物理模型验证控制策略,做风光储联合系统的动态仿真很方便。对于以算法研究和调度策略验证为主要目标的课题,Matlab是最稳妥的选择。

我通常建议代码结构上分成四个模块:数据输入模块(风光出力曲线、负荷曲线、储能参数)、模型构建模块(目标函数、约束条件)、求解模块(优化算法)、结果分析模块(出图、指标统计)。这样分层的好处是后期换算法、改参数都只需要动对应模块,不需要重写整套代码。

1.3 废弃矿井抽水蓄能的建模特殊性

废弃矿井小型抽水蓄能是这两年比较受关注的新概念。原理不复杂:煤矿关闭后会留下大量的巷道和采空区,如果能利用上下两个水平巷道或者矿井之间的落差构成上水库和下水库,就具备修建小型抽水蓄能电站的地理条件。这个方案的现实价值在于,废弃矿井的巷道系统已经存在,改造成本比新建常规抽蓄电站低很多,同时还能解决矿区废弃设施的再利用问题,推动资源枯竭型地区的转型。

但在调度建模层面,废弃矿井抽蓄和常规抽蓄有几点重要差异。首先是容量限制——巷道可用的储水空间有限,单站容量通常只有几十兆瓦级别,属于小型抽蓄,所以调度模型中不需要像常规大型抽蓄那样做复杂的库容分区,但必须精确计算巷道可用容积对应的储能上限。第二是水头变化——矿井巷道的水头变化范围较大,抽水和发电工况的效率会随水头改变,如果想精细建模,需要把效率写成水头的函数,这对粒子群这类启发式算法的求解负担会明显增加。第三是运行约束——抽蓄机组的启停次数、工况转换时间约束在矿井条件下可能更严格,因为巷道的水流通道切换有机械限制。

这些细节决定了废弃矿井抽蓄在调度模型里不能简单地用一个标准抽蓄模型替代,需要单独建一个子模块来处理它的特有限制。

2. 核心模型构建与技术细节解析

2.1 风电和光伏出力曲线的建模方法

在这个研究里,风电和光伏出力曲线可以分两种方式获取。一种是用实际数据——比如从NWP(数值天气预报)系统获得的历史风速和辐照度数据,再通过功率曲线换算成出力。另一种是合成数据——如果没有实测数据,可以用概率分布模型模拟,风速常用双参数Weibull分布,辐照度则用Beta分布或者基于晴空模型的确定性分量加随机扰动。做调度策略研究时,我建议至少准备三组典型日场景:大风光日、弱风光日、常规波动日。因为调度策略在不同场景下的表现差异很大,只跑一组数据说服力不够。

风电出力换算时要注意功率曲线的非线性特征。常见的做法是分段函数近似:

  • 风速低于切入风速时,出力为0
  • 风速在切入风速和额定风速之间时,出力近似按三次方关系增长
  • 风速达到额定风速后,出力保持额定值
  • 风速超过切出风速时,保护性停机

光伏出力模型则要考虑辐照度和温度两个因素。标准模型是:P_pv = P_stc × (G/G_stc) × [1 - β × (T_cell - T_stc)],其中G是实际辐照度,β是温度系数,T_cell是电池板温度。现实中电池板温度往往需要用NOCT模型从环境温度推算,不能直接用环境温度代替,否则夏季正午的光伏出力会被明显高估。

2.2 电池储能模型的SOC递推与寿命损耗

电池储能模块的建模核心是SOC(荷电状态)的递推方程。离散时间步长下,第t时段的SOC由上一时段SOC和本时段的充放电功率共同决定:

SOC(t+1) = SOC(t) - P_bat(t) × Δt / E_cap

其中P_bat为正值时表示放电,负值为充电。这个递推关系看起来简单,但实际写代码时有几个容易踩的坑。第一,充放电效率要分别处理,充电时实际消耗的电量要除以充电效率,放电时实际发出的电量要乘以放电效率,如果混用一个效率值,SOC的累计误差会越来越大。第二,SOC的限幅约束必须放在每个时段的迭代里,不能让求解器把SOC算到0到1之外,否则电池寿命评估就失真了。

另一个值得关注的问题是电池寿命损耗。单纯的SOC递推只解决了“能量从哪来、到哪去”的问题,没有考虑电池老化成本。电池循环寿命取决于放电深度(DOD),深度放电会显著加速容量衰减。在实际调度模型里,我建议在目标函数中加入电池寿命损耗项,用等效循环成本近似。一个实用的简化方法是:已知电池全寿命周期内的总循环次数N和单位容量成本,把每次等效满充循环(EFC)的成本折算进目标函数,让求解器自动权衡“多用电池”和“少用电池”的经济性。这个改动会让调度结果更贴近工程实际。

2.3 废弃矿井抽水蓄能模型的约束集

废弃矿井抽水蓄能模块的建模比电池储能稍微复杂一些。除了常规的功率上下限约束,还需要考虑:

库容约束:上水库(或高位巷道)的水量变化由抽水和发电的流量决定,而巷道容积有限,所以蓄水量的上、下限是硬约束。以小时为调度步长时,蓄水量的变化可以表示为:

V(t+1) = V(t) + Q_pump(t) × Δt × η_pump - Q_gen(t) × Δt / η_gen

功率耦合约束:抽水工况和发电工况不能同时进行,这是一个0-1整数变量控制的互补约束。在Matlab中用intlinprog或遗传算法处理时,通常引入二进制变量,抽水时该变量为0(或1),发电时相反。

水量-功率转换:这个约束往往被忽略,但它很重要。矿井巷道的水头范围比较大,不同水头下同样的流量对应的功率是不同的,反过来同样功率对应的流量也不同。简化建模时可以取平均水头下的线性关系,但如果想做精确一点的调度,建议至少分段线性化处理。

最小运行时间约束:抽蓄机组频繁切换工况会加速设备磨损,实际调度中通常要求机组在某工况下至少持续运行一定时间。这个约束在数学上是复杂的非线性约束,处理时需要引入额外的二进制变量和逻辑约束。

2.4 目标函数与约束体系的完整数学表达

这个研究的标准目标函数是系统总运行成本最小化,包括几个部分:

min F = Σ [C_grid(t) × P_grid(t) + C_bat_degrad(t) + C_psh_start(t)] × Δt

其中C_grid是购电成本(从主网购电),P_grid是购电功率,C_bat_degrad是电池老化折算成本,C_psh_start是抽蓄机组启停惩罚成本。如果研究还关注碳排放,可以在目标函数里加一个碳成本项,把火电购电量和碳排放关联起来,但这会引入额外的约束和参数,需要课题支持才行。

约束条件体系包括以下各类。功率平衡约束是所有调度模型的基础,系统内所有电源出力加储能充放电,要时刻等于负荷需求,这是硬约束,写代码时通常作为等式约束处理。风电光伏出力上下限约束是保证优化结果不超出物理可行域的必要条件。储能SOC约束与充放电功率约束构成储能运行的可行域。抽蓄库容约束与工况互补约束是抽蓄模块的专属限制。联络线功率约束则是考虑并网通道的传输能力上限。

3. 实操过程与Matlab代码实现

3.1 数据准备与典型场景设计

我先说数据准备。有些同学做这个课题时习惯直接下载公开数据集,但公开数据集的格式和质量千差万别,花在清洗上的时间往往比建模还多。我更推荐用合成数据先跑通整个流程,后续再替换成实测数据。合成数据生成的方式很简单:用Matlab的随机数生成器加上你设定的典型日特征曲线。

比如设计一个“大风光日”场景:光伏出力用0到1之间的Beta分布随机数乘以峰值功率,峰值时刻设在正午12点,风力出力用Weibull分布随机数乘以额定功率,再叠加一个白噪声扰动模拟预测误差。这样生成的曲线虽然不如实测数据真实,但用来验证调度模型逻辑是足够的。

实际案例参考参数:风电场额定容量200MW,光伏电站额定容量100MW,电池储能额定容量50MW/200MWh(2C倍率),废弃矿井抽蓄机组两台5MW机组,上巷道可用库容对应满发4小时的发电量,负荷曲线用典型工业负荷形状。时间步长取1小时,调度周期24小时。这个配置的好处是电池和抽蓄的容量规模在一个数量级,能明显看出不同时间尺度上的互补效果。

3.2 目标函数与约束条件的代码实现

Matlab代码实现时,我通常把所有参数定义在一个结构体里,这样传参方便,也方便统一修改。核心代码逻辑可以拆成下面几个段落。

参数定义部分主要设置风光容量、储能参数、抽蓄参数、负荷曲线数据、分时电价表、预测误差范围等。求解器选择部分,如果约束全是线性的,直接用intlinprog(混合整数线性规划)最稳妥,Matlab自带的linprog和intlinprog性能虽然不算顶级,但胜在开箱即用。如果约束里有非线性项,可以用遗传算法(ga)或粒子群算法(particleswarm)。我之前做过一个方案是把非线性的水头-效率曲线做分段线性近似,然后用intlinprog求解,求解速度明显优于启发式算法,而且结果更稳定。

写代码时目标函数的形式很关键。intlinprog要求所有表达式是线性的,所以电池寿命成本不能用二次形式,必须做线性化处理——把DOD分成若干档,每档对应一个线性成本系数。抽蓄启停惩罚则通过二进制变量实现,启停一次固定加一个成本项。

下面是目标函数的一个简写示例(实际代码里用矩阵形式):

% 变量顺序: [P_bat; SOC; P_psh_pump; P_psh_gen; V_psh; P_grid; u_pump; u_gen] % 目标函数系数 f = [C_bat_degrad; 0; C_psh_op; C_psh_op; ...; C_grid; C_start_pump; C_start_gen] f = [bat_degrad_cost*ones(N,1); zeros(N,1); ... psh_om_cost*ones(N,1); psh_om_cost*ones(N,1); ... zeros(N,1); grid_price(:); pump_start_cost*ones(N,1); gen_start_cost*ones(N,1)];

约束矩阵部分需要仔细核对每一行的索引对应关系。最容易出错的地方是SOC递推约束对应的那小段矩阵——SOC(t+1)同时关联了SOC(t)和P_bat(t),写的时候要特别小心,索引错一位整个结果就全乱了。

3.3 求解流程与结果验证

求解流程标准化之后大概是这样的:读取数据、构建参数结构体、构造决策变量索引表、逐条添加约束、调用求解器、解析结果、做功率平衡校验、输出图表。

结果验证部分强烈建议做三件事。第一,平衡校验:把每个时段的各类功率加起来,看是否严格等于负荷,如果有偏差,优先检查等式约束的矩阵行是否写对。第二,边界检查:把SOC、库容、功率等变量的结果逐项对照上下限,看有没有贴着边界跑的情况,贴边说明约束在起作用,但如果连续多个时段都贴边,要警惕约束放得太紧。第三,场景对比:把大风光日、弱风光日、常规日的结果放在一起对比,看弃风弃光率、购电成本、储能利用率的差异是否合理。

一个可靠的运行结果是:大风光日弃风弃光率控制在5%以内,弱风光日购电成本显著上升但负荷保证率100%,正常日电池负责小时级波动调节、抽蓄负责4小时以上的能量搬移。如果结果符合这个规律,调度模型的逻辑基本就是对的。

4. 常见问题与排查技巧实录

4.1 求解器报“No feasible solution”怎么办

这个问题我在实际调试中遇到过很多次,而且绝大多数情况下不是模型本身错了,而是约束之间互相矛盾。常见的矛盾来源有三个,我分别说一下。

SOC初始值设置不当是最常见的错误。如果SOC(1)设得过高,后续时段无论如何充电都会越界。建议SOC(1)设为50%,并给SOC终值加一个柔性约束——比如强制SOC(24)不低于初始值,保证日循环的持续性。抽蓄库容初值同理,不要把库容初值设在接近上限的位置。功率平衡约束和联络线约束冲突也经常出现。比如某个时段负荷很低、风光出力很大,但储能和抽蓄都已经在满发充电,无法再多消纳,而此时联络线的购电功率又强制为0,这个约束组合就会导致无解。处理办法是放宽联络线约束,允许极端时段少量购电(或售电),在目标函数里用较高的电价惩罚来引导求解器自动避免这种情况。最后一个常见原因是抽蓄工况二进制变量的互补约束写法不对,导致抽水和发电的变量同时为0时被硬性排除。这类约束要用“u_pump + u_gen <= 1”的形式,而不是等号。

4.2 粒子群算法收敛慢或结果重复性差

如果你选择用粒子群或遗传算法求解,可能遇到收敛慢、每次运行结果差异大的问题。经验处理办法有三个:一是把种群规模和迭代次数从默认值往上调,这直接增加搜索的充分性;二是给决策变量设置合理的上下界,把搜索空间收紧到可行域附近;三是把已知的可行解作为初始种群的一部分植入。比较实用的技巧是先用线性规划版本算出最优目标值,然后把这个解的目标值作为启发式算法的参考上界,把超过该上界的个体直接淘汰,收敛速度会明显提升。

如果你发现结果波动严重影响结论,还有一个更彻底的方案:改用Yalmip工具箱配合外部求解器(如Gurobi、CPLEX)。Yalmip的建模语法比直接写intlinprog的矩阵要直观得多,尤其是处理复杂的约束逻辑时,开发效率高一个量级。学术论文要求结果可复现的话,用商业求解器是更稳妥的选择。

4.3 储能SOC“锯齿形”波动的处理

调度结果的SOC曲线经常出现高频锯齿形波动,看起来像是在频繁充放电。这个现象的本质是电价波动驱动套利行为——每个时段电价高低不同,求解器发现低买高卖有利润,就会让电池频繁切换充放电状态。但从工程角度看,电池不能这样跑,每次切换都有寿命损耗。

处理方式有两种。一种是在目标函数里加大充放电切换惩罚项,这个需要引入二进制变量记录充放电状态的变化,会让模型变复杂。另一种更简单的方式是设置充放电死区——功率绝对值小于某个阈值的操作忽略不计,并将该时段的充放电功率强制归零。这个方法实现简单,实测效果不错;缺点是可能损失少量经济性,但对工程而言可以接受。

4.4 热门词“matlab 2026b”相关环境问题的快速排查

这几年Matlab版本更新频繁,很多人习惯用新版“matlab 2026b”跑仿真,但新版在优化工具箱上有时会有默认求解器的行为变化,导致老代码跑出不一样的结果。我的建议是,学术研究以可复现性优先,锁定一个稳定版本(比如R2022b之后任何版本均可),并在代码开头加一段版本检查:

% 版本检查,确保优化工具箱可用 assert(license('test', 'Optimization_Toolbox') == 1, '需要 Optimization Toolbox 许可证');

另外,如果你要在Linux服务器上跑长时间仿真,注意Matlab的并行计算工具箱在多核环境下要显式开启并行池(parpool),否则大量循环会浪费宝贵的计算资源。首次启动parpool的时间往往很长,建议放到仿真循环外初始化。

5. 结果分析方法与论文级图表绘制

5.1 功率平衡曲线与储能充放电时序

做结果分析时,最有说服力的图第一张是系统功率平衡图。横轴为小时序列,纵轴为功率,用堆叠面积图展示风电出力、光伏出力、放电功率(正值)、充电功率(负值)和购电功率之间的关系,负荷曲线用黑线叠加。这张图最大价值在于直观检验所有时段的功率平衡是否严格满足,也能看出储能的调节作用是否合理。

第二张是储能SOC和抽蓄库容的时序图。重点关注SOC曲线是否保持在合理区间,库容曲线是否体现了“低谷蓄水-高峰放水”的日循环规律。如果库容曲线长时间不动,说明抽蓄没有被合理利用,可能是容量设置过大或者电价激励不足。

第三张是不同场景下各项经济指标和运行指标的对比表。建议汇总成表,包括弃风弃光率、平均购电电价、储能等效循环次数、抽蓄启停次数等,方便做敏感性分析。

5.2 灵敏度分析的关键参数选择

调度研究的深度很大程度上体现在灵敏度分析。建议优先做三个参数的敏感性分析。负荷峰谷差加大的时候,看看储能配置容量对总成本的影响是不是非线性上升,以此评估最优配置。分时电价峰谷价差收窄时,储能套利空间缩小,这时候电池和抽蓄的利用率会下降,系统是否还能维持经济运行,要看结构调整的余量。风电渗透率提升时,弃风率和辅助服务需求的增长情况,可以用来论证储能建设的必要性。

做灵敏度分析时有个小技巧:不要单独改变某一个参数,而是把两个关键参数同时扫描,画二维的等值线图或三维曲面图。比如横轴是风光配比,纵轴是储能容量倍率,颜色是系统总成本,这样一张图就能看出最优方案是否存在以及是否敏感。这种图在论文里很容易打动审稿人,也能给工程决策提供更丰富的信息。

5.3 从仿真到论文的图表处理习惯

投稿或写报告时,图的字体、线宽、颜色这些细节经常被忽略。我的经验是:Matlab导出图之前先把字体统一设置为Times New Roman或Arial,字号控制在8到10磅之间;线条加粗到1.5磅以上;坐标轴要有完整的单位标注。图片导出用 exportgraphics 函数,设置300dpi分辨率,输出为PNG或PDF格式。这些细节虽然小,但能省掉很多改稿时间。

6. 实际运行效果与个人经验分享

6.1 一组典型算例的结果呈现

用前面说的配置跑一组实际算例,结果大致符合预期。大风光日,200MW风电加100MW光伏满发叠加的时候,弃风弃光率如果不加储能大约在12%到18%之间。加入电池和抽蓄联合调蓄之后,弃风弃光率降到5%以下,系统购电成本也显著下降,因为储能把多余的绿电搬移到了晚高峰时段。电池和抽蓄的分工也很清晰:电池的SOC曲线波动频率高,但每次幅度不大,负责的是小时级波动;抽蓄的库容曲线则是平滑的“V”形——白天光伏高峰抽水蓄能,傍晚到夜间放水发电,负责的是跨时段能量搬移。这种时间尺度上的分工,正是混合储能互补的价值所在。

6.2 我在实际调试中踩过的几个坑

第一个坑是抽蓄模块的效率参数。最初我用固定的效率值,仿真跑了三轮发现库容曲线有不自然的突跳,排查到最后是抽水流量和发电功率的换算关系没写对。后来我把效率参数改成水头的函数,并加了一个效率插值表,问题才彻底解决。具体的做法是预先算好不同水头下的效率数据,形成一个二维查找表,用Matlab的interp1做插值,这样既不会拖慢求解速度,又能保证精度。

第二个坑是电池寿命成本模型。最开始我用线性电池老化成本替代时,调度结果里电池几乎每个时段都在充放电,SOC频繁大幅波动。后来我意识到这是因为线性成本函数没有体现DOD越深损耗越大的非线性关系,求解器当然会倾向“浅充浅放、频繁操作”,因为每次操作的成本一样。换成分段线性化成本函数之后,结果才变得合理——电池更愿意做深度充放,而不是高频小幅操作。

第三个坑是初值灵敏度。粒子群算法初始种群如果随机分布不当,很容易让抽蓄机组一上来就处于不合理的工况,导致大量个体在早期被罚掉。解决办法是植入了几个已知可行解作为初始种群个体,这样种群一开始就在“正确的方向上”,收敛快得多。

6.3 这个项目还能怎么扩展

如果你读完这份内容想往下做,我建议几个扩展方向。把确定性优化升级为鲁棒优化或随机优化,考虑风光预测误差的不确定性,研究鲁棒调度策略的保守度与经济性权衡。在现有基础上加入常规火电机组的启停和爬坡约束,把模型扩展为含传统电源的多能源互补系统。利用Matlab的Simulink搭建电池和抽蓄的电磁暂态模型,把调度层给出的功率指令在物理层做验证,研究跨层协同。把调度方法从集中式优化扩展到分布式优化,参考多智能体一致性算法,研究多园区独立微电网的协同调度问题。这些方向都有成熟的工具支持,在Matlab环境下可以逐步演进。

我做这个课题最大的体会是:调度模型的价值不在数学复杂度,而在于模型假设是否贴合工程实际、约束体系是否真实反映设备物理极限,以及结果是否能指导实际运行。很多初次接触的同学容易把精力放在花哨的算法上,却忽略了风光预测数据的质量、储能寿命模型的准确性这些基础环节,最后仿真结果看起来很漂亮,实际却很难落地。希望这份内容能帮你少走几条弯路,把时间花在真正重要的地方。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询