2. 氢储能热电联供微电网的优化调度方法附Matlab实现思路搞微电网优化调度的朋友应该都有这种感觉风电光伏装机容量越大调度模型就越难写弃风弃光、功率波动、负荷不匹配这些问题一个接一个冒出来。这两年氢储能热电联供的概念被反复提起就是因为氢储能同时具备“跨时段平移能量”和“热电联产”两个属性能在源荷不确定性的情况下把电、热、氢三条能量流统一起来做全局优化。这篇文章就围绕氢储能热电联供微电网优化调度这个方向把模型怎么搭、约束怎么列、Matlab代码怎么组织、实际求解时容易踩哪些坑完整梳理一遍。适合正在做微电网调度、综合能源系统课题的研究生以及想从传统电化学储能方案切换到氢储能方案的工程技术人员参考。我默认你已经有Matlab和Yalmip环境也接触过线性规划或者混合整数规划的基本概念。如果没有文章里也会把相关的术语解释清楚。文中的所有参数和代码思路我都尽量采用工程上常用的取法和习惯同时标注哪些地方可以根据自己的数据调整。3. 整体设计与建模思路3.1 为什么选择氢储能热电联供常规微电网里蓄电池负责削峰填谷电锅炉或者燃气锅炉负责供热两条能量路径是分开的。这种方式在系统规模小、负荷类型单一的时候够用但一旦新能源渗透率上来问题就很明显蓄电池的容量和放电持续时间有限遇到连续几天阴雨天气或者持续低温电化学储能的能量密度撑不住电锅炉把高品质电能降级成低品位热能能效损失大燃气锅炉又依赖外部燃料供应碳排放压力下纯电驱和纯气驱都不是最优解法。氢储能不一样的地方在于电解槽可以在风光大发时制氢把多余的电能变成化学能存进储氢罐需要的时候燃料电池再把氢转化成电和热。这个过程中氢既充当了长时间储能媒介又通过燃料电池的热电联产特性同时满足电负荷和热负荷。对于寒冷地区、工业园区这类典型热电负荷并存的场景氢储能热电联供系统能把“电-热-氢”三网耦合在一起调度整体能效和供能可靠性比单一路径高出一个档次。3.2 系统架构和能量流模型从物理结构上看一个典型的氢储能热电联供微电网包含新能源发电单元风电、光伏输出电能为主的不可控电源电解槽消耗电能将水电解为氢气和氧气属于可调电负荷储氢罐储存电解槽产氢同时向燃料电池供氢有容量上下限燃料电池消耗氢气同时输出电功率和热功率热电比由机组特性决定蓄热罐储存燃料电池余热和可能的其他热源缓冲热负荷波动电负荷与热负荷系统服务的对象有各自的时变曲线调度模型的核心任务是在每个调度时段通常取1小时决定风电光伏出力、电解槽输入功率、燃料电池输出功率、储氢罐充放氢速率、蓄热罐充放热速率使得总运行成本最低同时满足所有约束。如果画能量流图建议你实际建模前先画一版会发现这个系统有两条关键的耦合链路。第一条是电链路风电光伏 - 母线 - 电解槽/燃料电池/电负荷母线节点上的功率平衡将四者约束在一起。第二条是氢链路电解槽 - 储氢罐 - 燃料电池氢的产、储、用必须时刻保持平衡并且储氢罐的储氢量有边界。热链路相对独立燃气锅炉作为补充热源燃料电池余热和蓄热罐构成热母线的平衡。三条链路通过燃料电池和电解槽这两个转换设备交织模型本质上是一个多能流耦合的优化问题。3.3 调度策略选型开环优化还是闭环滚动初次接触这个问题的同学常犯一个错误直接用一天的预测数据做一次离线优化得到固定出力计划就不管了。这种方法在理论上能算出全局最优解但实际运行中风电光伏的预测误差、负荷的实际波动都会让“最优计划”迅速失真——光伏预测说中午出100kW实际被云遮了只剩下60kW按原计划走就会出现功率失衡。我建议你在Matlab里先实现确定性日前调度作为基础框架再在它的基础上扩展模型预测控制MPC滚动优化。MPC的思路是每个控制周期进行一次短期优化只执行第一个时段的决策到下一周期重新预测、重新优化。这样做的好处是能不断用最新信息修正误差鲁棒性明显提升代价是求解次数增加计算时间变长。对一个1小时分辨率、24小时调度周期的问题来说即便用滚动优化计算压力也不大完全可以在工程实时性要求内完成。如果课题要求处理好预测不确定性可以在滚动优化的基础上进一步尝试场景法随机规划把风电、光伏、负荷的预测误差用多场景表示目标函数改成期望成本最小化。这部分模型解起来比确定性版本复杂但论文创新点和工程价值更足。下文先以确定性模型为主线场景扩展放在第5章结合代码说明。4. 优化调度模型的核心细节4.1 目标函数成本项的构成氢储能热电联供微电网的调度目标函数我通常写成如下形式以运行成本最小化为目标成本项包含四块向主网购电的成本、向主网售电的收益负成本、电解槽和燃料电池的启停/运行维护成本、碳排放惩罚成本。在Matlab中构建目标函数时建议把成本系数定义成清晰的数据结构方便后续修改。我不太建议把系数散落在代码各处一旦调参数或者做灵敏度分析来回改代码非常容易出错。一个好的习惯是把所有设备参数集中放在一个参数初始化函数中以结构体形式返回后续模型直接引用结构体字段。4.2 电功率平衡与热功率平衡约束电力平衡是微电网模型最基础、也最不能出错的约束。在任意时段t系统必须满足风电出力 光伏出力 购电功率 燃料电池电出力 电负荷 电解槽耗电功率 售电功率这个等式本质上是母线节点的功率守恒。注意这里风电光伏出力并不强制要求全部消纳如果模型允许弃风弃光这两个变量可以带一个“小于等于可用出力”的上限约束实际出力低于上限的部分就是弃电量。这种做法比硬性等式更能反映真实情况也为优化器提供了灵活性——某些极端电价时段少发一点新能源反而整体更经济。热功率平衡约束同样重要燃料电池热出力 蓄热罐放热 燃气锅炉热出力 热负荷 蓄热罐充热这里有个细节蓄热罐的充放热可以同时进行吗物理上不行但线性约束如果只写“蓄热罐热平衡方程”优化器会利用双向同时充放热来制造“免费”的伪最优解。我在实际建模中会引入充放热状态对应的二进制变量把它们互斥约束加进去。同理变电站购电和向电网售电如果不加互斥约束优化器可能同时购电和售电导致解无意义。4.3 氢能子系统的建模氢能核心设备的建模水平直接决定整个优化模型的准确性。电解槽的输入是电输出是氢两者之间的转换效率不是常数但工程上为了保持模型线性通常采用简化效率模型制氢速率 电解槽耗电功率 * 电解槽制氢效率 / 氢气热值燃料电池则相反输入氢输出电和热燃料电池电出力 氢耗量 * 氢气热值 * 发电效率 燃料电池热出力 氢耗量 * 氢气热值 * 产热效率这两个效率之间存在热电比约束燃料电池的产热效率和发电效率此消彼长。你会在文献里看到用固定热电比建模的也有用线性不等式约束热电出力关系的前者简单后者更贴近实际。我建议采用后者因为燃料电池在部分负荷下的热电比变化明显固定热电比模型在低负荷段误差很大。储氢罐的动态方程是储氢量(t1) 储氢量(t) 制氢速率时段时长 - 燃料电池耗氢速率时段时长储氢罐容量有上下限本质上是给储能设备的能量状态做边界约束。氢储能的跨时段转移能力正是通过这个递推方程实现的。注意这里需要给储氢量加初值约束和末值约束否则优化器会把储氢罐的初始能量当作免费资源耗尽或者为了“省成本”在最后一个时段清空储氢罐与实际运行要求不符。4.4 机组出力上下限与爬坡约束所有可控设备都有出力上下限这是模型中最基础的边界约束。有一个容易被忽略的点是电解槽和燃料电池的出力下限往往不是0而是某个最小稳定运行功率。如果允许设备长期运行在极低负荷区间实际设备可能因为达不到最低运行功率而无法正常工作。爬坡约束也很关键它限制相邻时段之间出力的变化量。风电光伏受气象条件影响变化剧烈但电解槽的功率调整速度有限燃料电池的启动和停机时间也不为零。如果模型忽略爬坡约束优化器会计算出相邻时段出力相差极大的“不可行计划”拿到现场根本执行不了。爬坡约束的典型形式是|P(t1) - P(t)| 最大爬坡速率 * 时段时长在混合整数形式下还可以进一步通过状态变量约束限制同一时段内设备只能处于“启动-运行-停机”中的一种状态并设置最小连续运行时间和最小停机时间。这些约束会让模型变成混合整数线性规划求解难度增加但也有对应的求解器和求解技巧可以应对。4.5 不确定性的处理思路风电、光伏、负荷预测的不确定性是调度模型实用化的最大障碍。我见过很多论文假定预测完美把确定性模型做得很精细但工程上完全不可用。处理不确定性主流有三种思路随机规划场景法通过拉丁超立方采样或蒙特卡洛模拟生成多个风电光伏出力场景每个场景对应一套运行时约束目标函数改为所有场景期望成本最小化。这种方法对不确定性的刻画最细致缺点是场景数量增加后模型规模线性增长求解时间变长。鲁棒优化不关心预测值的具体概率分布只要求优化结果在给定不确定集合内都可行。这种方法对数据的要求低抗风险能力强但决策结果偏保守经济性稍差。模型预测控制MPC不确定性在滚动窗口内被持续修正适合在线调度。工程应用最广实现难度适中结合日前计划日内滚动修正两个时间尺度效果最好。对于Matlab实现来说我个人建议先做确定性日前调度再扩展到滚动MPC。这样代码结构不用推翻重来只需要把单次优化包在一个循环里并动态更新预测数据和初始状态。这个扩展方案成本低但成果展示效果很好。5. Matlab代码实现从数据到结果的完整流程5.1 工具箱选型YalmipCPLEX还是Matlab内置求解器实现电力系统优化调度我强烈建议使用Yalmip工具箱。它把模型的数学表达和具体的求解器解耦你只需要用符号变量描述目标函数和约束然后指定用哪个求解器求解剩下的事交给Yalmip。推荐组合是Yalmip CPLEX或Yalmip Gurobi这两个商业求解器处理MILP问题性能优秀校园学者可以申请免费学术许可。如果环境里实在没有CPLEX和Gurobi可以用Matlab自带的linprog和intlinprog求解纯线性规划和混合整数线性规划。两者都能求解但在求解速度和大规模问题上表现有差距。另外需要说明的是Yalmip已经是一个独立的工具箱需要单独下载并添加到Matlab路径。从树立模型到求解代码逻辑分为以下步骤初始化参数结构体构建决策变量写目标函数添加约束条件调用求解器提取并可视化结果5.2 参数初始化与数据结构设计以下是一个参数初始化函数的示例我用一个结构体par承载所有参数调用方式为par.windMax(1)或par.load(1)清晰且有秩序function par initParams() par.H 24; % 调度时段数小时 par.dt 1; % 时段时长小时 par.load ... end这里的...部分请按你自己的实际数据填完整。如果你是第一次建模建议先用典型日的测试数据验证模型逻辑再换成真实数据。我就是用一套有人为构造但数值合理的测试数据先跑了三遍确认无歧义后再切换到真实负荷曲线的。结构体设计有两个小建议。第一所有与设备相关的参数集中在一起例如par.H2结构体放储氢罐容量、初始储氢量、上下限par.FC放燃料电池的效率、热电比、出力上下限。第二需要做灵敏度分析的参数额外集中到一个par.ctrl子结构中方便通过循环批量修改仿真参数。5.3 决策变量构建与约束矩阵写法使用Yalmip时决策变量可以直接用sdpvar定义例如P_wind sdpvar(1, 24, full); % 风电出力 P_pv sdpvar(1, 24, full); % 光伏出力 P_fc sdpvar(1, 24, full); % 燃料电池电出力 P_el sdpvar(1, 24, full); % 电解槽耗电功率 P_buy sdpvar(1, 24, full); % 购电功率 P_sell sdpvar(1, 24, full); % 售电功率 V_h2 sdpvar(1, 25, full); % 储氢量25个点包含初值和各时段末值注意我特意把V_h2定义成1行25列这对应t0到t24的状态点。储氢量动态方程需要同时用到V_h2(t)和V_h2(t1)这种定义方式能避免索引混乱。同样蓄热罐的能量状态变量也建议定义成时段数1列的长度。约束的添加用constraints []开始然后用中括号不断追加。比如电力平衡约束constraints [constraints, P_wind P_pv P_fc P_buy P_load P_el P_sell];这样的写法适合约束数量中等的模型。如果约束数量很大比如加了数百条机组组合约束建议改用for循环逐个添加但效果一样。二进制变量用于描述设备启停状态时会引入混合整数规划u_fc binvar(1, 24, full); % 燃料电池启停状态1表示运行0表示停机 u_el binvar(1, 24, full); % 电解槽启停状态设备出力和状态变量之间需要加限制约束典型的“大M法”写法为F_fc_min * u_fc P_fc F_fc_max * u_fc; F_el_min * u_el P_el F_el_max * u_el;这里的M就是设备出力上限。大M法需要注意M的取值不要过大过大会导致数值稳定性变差。我一般建议M取设备最大出力的1.1倍左右够用且稳定。5.4 目标函数与求解最小化运行成本目标函数在Yalmip中直接表达式即可cost_buy par.price_buy * P_buy; % 购电成本 cost_fuel par.price_fuel * sum(P_fc) * par.dt; % 燃料成本如果有 cost_maint par.price_maint * (P_fc P_el); % 运维成本 objective cost_buy - cost_sell cost_fuel cost_maint carbon_cost;注意Matlab中行向量和列向量的方向价格向量与功率向量做内积时一个是行向量一个是列向量否则维度不匹配会报错。这是我调试Yalmip代码最常遇到的问题之一。求解过程很简单ops sdpsettings(solver, cplex, verbose, 1, debug, 0); result optimize(constraints, objective, ops);solver可以按实际选择的求解器修改成gurobi或intlinprog。debug设成1可以在模型不可行时输出调试信息帮助定位问题约束。求解完成后通过value()函数提取结果。注意sdpvar是一个符号对象必须用value()转换成数值才能绘图或输出这点新手经常遗漏。5.5 结果可视化与调度曲线解读调度结果的可视化建议画三类图。第一类是功率平衡图以柱状图或堆叠面积图展示每个时段的电源出力和负荷消耗能直接看出什么时候购电、什么时候售电、什么时候电解槽满负荷运行。第二类是储氢罐状态图展示储氢量曲线随时间的变化判断氢储能是否发挥了“削峰填谷”的作用。第三类可以画热功率平衡图展示燃料电池热出力、蓄热罐充放热和热负荷的匹配关系。研判调度结果好坏我有一个习惯先看功率平衡是否严格满足将各变量代入平衡方程检查残差是否接近零再看储氢罐是否合理充放应该呈现低谷充电、高峰放电的规律最后看成本和购电策略是否符合电价结构。这三个检查过了模型才算是真正的“通了”。6. 实测运行与问题排查实录6.1 典型日调度结果分析案例我在某模拟项目X中搭建了一个额定风电120kW、光伏80kW、电解槽60kW、燃料电池50kW、储氢罐200kWh的小型微电网模型调度时段为24小时分辨率为1小时。典型日电价结构设定为峰谷电价峰值电价1.2元/kWh谷值电价0.35元/kWh。求解完成后观察到如下典型行为凌晨风电大、电价低此时购电也便宜电解槽在保证氢储量安全的前提下尽量满负荷制氢把多余的电力转化为氢存储白天光伏出力增加但午间热负荷需求也上升燃料电池在中下午时段启动放电、放热储氢罐的能量被释放晚间电价回升风电出力下降此时电网购电成为主要电源燃料电池只承担热负荷中的基本部分。这个调度模式与直觉一致验证了模型的基本正确性。进一步做一组对照实验把储氢罐容量从200kWh扩展到400kWh调度结果中购电成本明显下降因为更多的廉价谷电通过电解制氢-燃料电池发电的路径转移到了峰时段使用峰谷套利的空间变大。6.2 常见求解失败的原因与调试方法模型无解是最让人崩溃的情况。我的排查顺序是先用debug模式检查不可行约束再分别单独测试每个约束组逐步排除问题点。常见的不可行原因有几个。第一个原因是数据不一致。比如风电出力最大值设置比风资源理论出力还小导致功率平衡被锁死。排查方法是检查所有上下限参数是否齐全、是否合理。第二个原因是二进制变量与状态约束冲突。比如设备的启动操作需要对应“关闭-启动”过程但模型缺少状态转移约束优化器可能产生荒谬的启停序列。这种问题要检查启停状态变量是否与出力变量正确耦合。第三个原因是储氢罐初值设置不当。如果初值储氢量过高或过低同时边界约束卡得死系统可能在任何时段都无法同时满足平衡约束。把初值设成容量的一半左右通常能正常求解。第四个原因是模型规模过大导致求解器内存溢出。此时建议缩短调度时间窗如改为12小时滚动优化、简化设备模型去掉启停约束忽略爬坡或者在Yalmip中启用模型降维选项。6.3 调试经验从简化模型开始我有一个深刻教训一开始不要直接加载全工况数据。先把风电光伏负荷都替换成常数或者简单正弦曲线关闭所有二进制变量先跑通纯LP版本的模型然后再逐步打开启停约束、爬坡约束等复杂约束。这样每一步出现问题时都能清晰地追溯到刚加入的约束模块。我为类似项目调试时采用“分治策略”先单独测试热子系统的平衡再单独测试氢子系统的动态方程最后把三个子系统耦合起来一起跑。每走一步验证一次子系统的结果是否符合物理直觉。这里提供一个检查技巧单独把电解槽和燃料电池的效率设为100%此时系统应该退化为一个纯能量转移模型储氢罐的储氢量变化应该与输入电能有严格对应关系。如果这一点对不上说明转换环节的建模有误。6.4 影响优化结果的关键参数实际使用中有几个参数对调度结果的影响特别大建议做灵敏度分析时重点关注。电价结构影响最大。峰谷价差越大氢储能进行“买入-存储-卖出”的套利空间就越多储氢罐在调度中的利用率也越高。如果价差小于储能往返效率损耗带来的成本优化器会选择不用氢储能此时所有设备基本处于闲置状态模型退化为纯购电系统。燃料电池的热电比也值得关注。热电比越高相同氢气消耗量产出的热能越多对热负荷的匹配能力就越强。但热负荷需求不够时热电比高反而导致热能浪费。模型需要权衡产热收益和发电收益。储氢罐容量和初始氢量的设定直接影响优化器的可行域。容量过小跨时段的能量转移能力不足初始氢量过高相当于给了系统一份免费能量会拉低购电成本但这种“收益”不具备可持续性。试验时应该把初始储氢量设置成容量的一半或者采用“镜像周期”的方式用一个完整周期的周期边界条件来消除初值影响。7. 从基础模型到进阶方案7.1 从确定性优化到滚动时域控制对于工程应用而言纯离线调度很难直接落地。我给一位做园区综合能源的开发者做过一轮升级把确定性优化打包成一个子函数命名为solveDispatch(initState, forecastData, params)输入当前储氢量和预测数据输出本时段的设备出力指令。每15分钟或每小时调用一次这个函数只执行第一个时段的结果然后更新储氢量状态和预测数据。这样改代码量不大但模型从“离线计划”变成了“在线控制”实用性大幅提升。7.2 引入多场景随机规划如果课题追求更高的理论深度可以在确定性模型的基础上做场景扩展。生成场景的核心是历史数据的统计特征用风电、光伏、负荷的历史预测误差分布通过拉丁超立方采样生成N个场景再通过场景消减技术或者等概率抽样把场景数量压缩到计算可承受的范围。每个场景下都有一套出力变量和功率平衡约束但第一阶段的决策变量如机组启停状态在各场景间保持一致这就是“两阶段随机规划”的典型形态。在两阶段随机规划中目标函数为所有场景成本的期望值。这需要引入场景概率权重表达式为min Σ ω_s * 场景s运行成本其中ω_s是场景s的概率权重。求解规模会成倍增加合理的场景数量通常在20~50个之间再追求更多对解的提升幅度就很小了。7.3 碳排放约束与绿色调度面向“双碳”目标的应用场景中微电网调度必须考虑碳排放约束。一种做法是在目标函数中增加碳价惩罚项碳成本 碳排放配额之外的实际排放量 * 碳价实际排放主要来源于向主网购电对应的间接碳排放和燃气锅炉的直接碳排放。更严格的做法是设置系统的总碳排放上限作为额外约束加入模型。这样优化器会在经济性和碳排放之间做权衡得到的调度计划通常表现为高峰时段减少购电、低谷时段增加氢储能充能、燃气锅炉只作为兜底热源。这类模型现在发表的论文很多工程上也有实际应用价值。8. 实操心得与避坑指南这套基于氢储能的热电联供型微电网优化调度方法我从搭建模型到做完一整套案例前后花了接近三周时间中间踩了不少坑。有几条经验想特别分享。第一建议在模型设计阶段就明确哪些变量是连续型哪些需要离散化。这决定了问题最终是LP、QP还是MILP直接影响求解器的选择和求解速度。如果不需要精确的启停动作建模可以简化掉二进制变量如果系统不允许同时充电放电就必须引入二进制变量。不要把所有设备都做成MILP求解负担会成倍增加。第二Yalmip的optimize返回诊断信息一定要仔细读取。result.problem0表示求解成功1表示求解失败还有其他值对应不同的求解状态。不要只看目标函数值还要留意求解时间和求解器报告的状态信息。实际工作中我经常遇到模型求解“看起来成功”但某些变量值异常的情况此时要回去查约束是否真的完全满足。第三调度结果一定要做物理合理性检查。数值上优化器可能算出一个“严格满足约束”的解但物理上不可行比如燃料电池一小时之内在最大出力和零出力之间来回切换或者储氢罐状态剧烈震荡。这种解就是典型的数值病态。检查工具很朴素把决策变量的结果画出来肉眼扫一遍看是否符合直觉。最后如果你想在论文或实际报告中展示方法的有效性建议在实验中至少设置三组对照无储能方案、蓄电池储能方案、氢储能热电联供方案。对比这三组的运行成本、碳排放量和新能源消纳率能非常直观地体现氢储能方案的独特优势。我实测下来的数据氢储能方案在寒冷地区热电负荷占比高的场景下综合成本比纯电池方案降低15%以上新能源消纳率提升接近十个百分点这样的结果是很有说服力的。对于后续扩展现在很多研究在尝试把氢储能系统与碳捕集、生物质气化、地热等更多异质能源耦合或者把电解槽的制氢副产品高纯氧气也纳入系统效益核算。这套Matlab模型已经预留了模块化接口扩展新设备时只需要增加对应的参数结构、决策变量和能量平衡约束不需要推翻模型框架。就目前微电网调度从“单一电储能”向“电-热-氢多元耦合”演进的方向看这套方法的工程应用价值还会继续提升。
阅读完成 · 觉得有帮助?