尧图精选

考虑垃圾焚烧与碳捕集-电转气协同的虚拟电厂优化调度模型

🕒 发布时间:2026/10/2 9:53:53 📁 来源:尧图网络
做了这么多年电力系统优化调度说实话一开始看到这个题目我第一反应是“这又是把三个热点硬凑一锅”。但真正把模型搭起来、跑通数据之后我得承认自己之前有点想当然了。垃圾焚烧、碳捕集CCS和电转气P2G这三样东西放在虚拟电厂VPP的框架下不是简单的“拼盘”而是一条真正能循环起来的碳–能–气链条。这篇博文就基于我最近在Matlab里完整复现并改进的一套调度模型从数学建模、代码实现到算例结果把关键细节和踩过的坑一次性说清楚。这套东西适合谁看如果你是做园区级综合能源、电网调度、或者正在研究“双碳”目标下虚拟电厂优化控制的可以参考的东西不少。哪怕你只是需要一份能跑的Matlab调度模型做毕设或课题起步这篇的代码思路和数据结构也能帮你少走弯路。我会尽量把公式背后的物理含义讲透而不是让读者对着符号发呆。1. 这个组合的缘起弃风弃光、碳配额和垃圾围城的三重夹击先讲讲我为什么要碰这个题目。传统虚拟电厂通常就是聚合风电、光伏、储能和可调负荷做一个简单的经济调度目标就是“成本最小化”。但最近两年项目里遇到的实际约束越来越多新能源渗透率一高电网调峰能力有限弃风弃光成了常态碳配额又逐年收紧火电和垃圾焚烧机组要考虑碳排放成本而城市固废处理量逐年增长垃圾焚烧发电厂的产能虽然稳定但热值波动、环保约束和电价考核之间的矛盾越来越突出。这三件事单独处理都不难难的是它们放在一起时彼此之间的时序耦合和能量流动关系。电转气P2G在这里面起的不是锦上添花的作用它是把整个系统“缝合”起来的关键一环。垃圾焚烧机组尽管做了烟气净化仍然会产生大量二氧化碳这部分碳捕集下来之后去哪里如果只是封存成本高而且收益为零。而P2G过程恰恰需要消耗二氧化碳先用风电或光伏的富余电力电解水制氢再和捕集到的CO₂通过甲烷化反应生成合成天然气SNG注入储气罐或者直接供给燃气机组。这样原本要花钱处理的碳变成了燃料原本要弃掉的电变成了气一举两得。我把这个问题的核心矛盾总结为两点一是时间解耦垃圾焚烧和风电的出力曲线天然不匹配P2G相当于一个“时间转移器”把无法就地消纳的电能存进燃气系统二是碳解耦碳捕集装置如果单独运行能耗很高反而会拉低系统经济性但和P2G协同后捕集出来的CO₂直接被消耗掉既不产生储运成本又减少了碳交易市场的配额支出。有了这两个解耦模型的价值就不是“多装了几台设备”那么简单了而是真正意义上的多能互补。2. 虚拟电厂的能源架构垃圾焚烧怎么和电转气、碳捕集串成一条链在写任何代码之前先把物理架构理清楚。我这个模型里的虚拟电厂包含如下单元垃圾焚烧发电机组、含碳捕集装置的火电机组、风电场、光伏电站可以有但算例里我主要用了风电、电转气系统电解槽甲烷化反应器储氢/储气罐、燃气轮机、以及储能电池。电网侧允许从外部网购电也允许VPP向外部售电这是一个典型的并网型虚拟电厂。从能量流向上看这条链的骨架是这样的可再生能源出力首先满足电负荷富余电力进入电解槽制氢氢气一部分直接进入储氢罐另一部分和碳捕集系统捕集到的CO₂进入甲烷化反应器生成合成天然气合成天然气进入储气罐可以在气价高或电力短缺时启动燃气轮机补电也可以对外销售。垃圾焚烧机组和火电机组发出的电并入母线它们的烟气经碳捕集装置处理后捕集的CO₂按一定比例分配给P2G系统和外运封存。为什么不把碳捕集装置单独放在垃圾焚烧机组上而是放在火电侧这是我踩过的一个选择坑后来看文献才意识到不是设计失误而是有讲究的。垃圾焚烧机的烟气成分复杂CO₂浓度相对较低捕集能耗会偏高而火电机组烟气量大且CO₂浓度稳定捕集装置的单位能耗更低。但垃圾焚烧机组的碳排放来源是“生物质化石”的混合政策上往往给与部分零碳处理如果在模型里一刀切地按化石碳计费会高估它的碳成本。所以更合理的做法是火电侧上燃烧后捕集装置捕获的CO₂和垃圾焚烧烟气中的CO₂一起进入一个“碳汇集节点”再统一分配给P2G使用。这样既控制了模型复杂度又符合工程直觉。从时序耦合角度我要特别强调储气罐的缓冲作用。碳捕集装置运行受电出力影响很大——捕集能耗一般占机组发电量的15%到25%这部分电如果来自本机组就形成了一个“发电量越高、净出力反而不一定越大”的回环关系。而P2G的耗电又和弃风时段强相关。如果中间没有储气容量这两个过程必须在每个调度时段内部严格对齐模型就会变得极其僵硬。加入储气罐后碳捕集的CO₂可以提前存储P2G的合成气也可以晚些再释放调度自由度大幅提升。在Matlab建模里这体现为储气罐的库存状态方程约束和一个简单的线性平衡方程但它的经济效益提升非常明显具体数值在算例部分会说。3. 优化模型的数学形式目标、约束和P2G与碳捕集的耦合条件这一节是模型的核心我尽量用公式加解释的方式来写方便读者在Matlab里直接转化。3.1 目标函数不只是成本最小还要打上弃风和碳价的烙印模型采用确定性日前调度时间尺度取24小时也可以扩展为96点15分钟粒度后面说。目标函数是最小化系统总运行成本包含以下部分min Σₜ ( C_fuel(t) C_om(t) C_start(t) C_carbon(t) C_p2g(t) C_curtail(t) C_grid(t) )其中各项含义如下C_fuel是火电和燃气轮机的燃料成本用二次函数近似并做分段线性化C_om是各机组与储能、P2G设备的运维成本按电量线性折算C_start是机组启停成本用二进制变量建模C_carbon是碳排放成本采用基准线法——政府给虚拟电厂分配免费配额实际排放超过配额的部分需要到碳市场购买小于配额则可出售获利等效于在目标函数里引入了一个随碳价波动的线性项C_p2g是P2G系统消耗电量的成本注意这里的电价是内部结算价我会在算例里取弃风惩罚电价的1.2倍用来体现“消纳弃风但不鼓励亏本制氢”的导向C_curtail是弃风惩罚成本取一个较高的惩罚系数让模型尽量把风光出力都用掉C_grid是联络线购售电成本购电为正、售电为负。这里有一个很多人容易忽略的点碳配额到底是按日结算还是按运行期结算如果按年结算日前调度模型就必须引入对未来碳盈亏的预期变成一个随机优化或滚动优化问题。为了不让模型失去确定性线性规划的形式我把碳排放配额处理为“日配额”即把年配额按日历日平均分配。实际项目和许多文献也都是这么处理的简化但可解释。碳价我设为每吨CO₂人民币60元这个数值参考了全国碳排放权交易市场的近期区间读者可以按自己的场景调整。3.2 功率平衡与机组约束模型的骨架电功率平衡是硬约束每时段的系统总出力加上外部购电等于电负荷加电解槽耗电、碳捕集装置耗电和储能充电功率Σ P_gen(i,t) P_wind(t) − P_curtail(t) P_sell(t) − P_buy(t) P_discharge(t) L_e(t) P_P2G(t) P_CCS(t) P_charge(t)这里P_wind是一个给定的预测出力曲线P_curtail是弃风量二者之差是实际并网风电。P_gen(i,t)包括火电、垃圾焚烧和燃气轮机的出力。P_P2G是电解槽消耗功率P_CCS是碳捕集装置消耗功率。火电机组约束包括上下限、爬坡速率、最小启停时间和启停状态逻辑。垃圾焚烧机组比较特殊它属于“必须处理固废”的机组有上下出力限但为了保证垃圾处理量出力下限一般设得比较高而且启动成本相对较低但在一天里的调度时段不允许频繁启停我直接把它当作持续在线机组处理了。储能电池用荷电状态方程建模充放电效率和容量约束都在标准范围内。燃气轮机的燃料来自P2G系统的储气罐所以它的出力上限不是固定的而是取决于当期储气量的可用能量这一点在后文的耦合约束里会体现。风电场我只给了出力上限模型可以选择弃风。我没有给风电机组建模燃料成本和运维成本的细节因为它的运维成本很小基本可以并入弃风惩罚的逻辑用一个很小的正系数表示即可。3.3 CCS与P2G的耦合约束这套模型的灵魂碳捕集装置的建模是整个模型最需要小心的地方。捕集过程消耗电力捕集到的CO₂分为三路供给P2G的甲烷化反应、直接封存、以及由于装置能力限制而放空的部分称为“逃逸碳”。为了线性表示我用两个简化假设捕集率是常数即进入捕集装置的烟气中固定比例被捕获捕集能耗和捕集CO₂量成正比。设火电机组出力P_fire(t)对应的基础排放量为e_f * P_fire(t)e_f是排放强度kgCO₂/kWh。捕集量E_cap(t) η_cap * e_f * P_fire(t)捕集能耗P_CCS(t) λ_cap * E_cap(t)。这里η_cap取0.85λ_cap取0.2 MWh/tCO₂近似燃气烟气胺法捕集能耗水平。垃圾焚烧机组的排放量同样计算但假设部分排放按生物源处理免配额设为E_wte(t)。全系统实际需购买配额的排放量为E_total(t) (1 − η_cap)·e_f·P_fire(t) 被豁免后的WtE排放 燃气轮机燃烧合成气的排放这个如果SNG被视为绿气可以给与零碳优惠我在算例里做了两种版本P2G系统的建模分两步。第一步电解水用富余电力制氢电解效率η_ele产氢量H_H2(t) η_ele * P_P2G(t) / HHV_H2。第二步甲烷化氢气和CO₂按4:1的摩尔比反应生成甲烷这里CO₂消耗量Q_CO2(t)和产气量Q_SNG(t)的关系为Q_SNG(t) 0.25·χ·H_H2(t) / 4 化简后……这里不铺陈复杂的摩尔质量换算直接给工程系数每标准立方甲烷需要2.5标方氢气和1.25kgCO₂左右我把这个系数整理成了一个常数矩阵在代码里直接用避免每次写单位转换。甲烷化反应不是100%完全取转化率χ0.8。未反应的氢气可以回收到储氢罐但储氢罐容量有限所以在目标函数里我隐含设置了一个氢富余惩罚项防止模型产生“疯狂制氢存着玩”的极端解。CO₂的分配也需要加约束E_cap(t)的一部分直接送去封存一部分进入甲烷化。由于封存成本较高模型在有P2G需求的情况下会自动优先把CO₂供给甲烷化这不需要额外惩罚项成本结构自然驱动。储气罐的库存平衡是一个关键约束V_sng(t) V_sng(t−1) Q_in(t) − Q_gasturbine(t) − Q_sale(t)其中V_sng是储气量折算为能量MWhQ_in是甲烷化注入量Q_gasturbine是燃气轮机消耗量Q_sale是对外售气量。V_sng有上下限初始库存设为上限的50%。燃气轮机的出力范围和储气量之间是耦合的即燃气轮机在t时段的出力不能超过当期可用天然气能量上限。这其实是整个模型里唯一让我觉得“有虚拟电厂实感”的约束——气、电、碳三种能量形态通过这一行数学约束互相牵制。4. 求解策略与代码落地从YALMIP到CPLEX的完整接线Matlab里做这种混合整数线性规划MILP调度模型首选方案是YALMIP作为建模层CPLEX或Gurobi作为求解层。为什么不用Matlab自带的intlinprog因为模型一旦加入了分段线性化和启停二进制变量约束矩阵的规模很容易破万intlinprog在处理这种带大量二进制变量的问题时求解速度和解的稳定性都不如专业商用求解器。我在本地用的是CPLEX 12.10学术版许可完全够用。先说代码结构。我把整个项目分成四个文件data_input.xlsx系统参数表包括机组参数、预测负荷、风电出力、气价、碳价、P2G和CCS参数、储气罐参数。所有参数集中在一张excel里方便批量改场景。build_model.m主构建脚本读取参数定义所有决策变量和约束设置目标函数调用YALMIP求解。这个文件是整个程序的龙骨。plot_results.m结果可视化脚本画机组出力图、储能SOC曲线、碳流平衡图和弃风处理情况。calc_metric.m计算成本明细、碳排放明细、弃风率、P2G产气量等统计指标的小函数。在这里贴一段build_model.m的核心片段展示YALMIP变量的定义和几条耦合约束的写法完整的代码量太长不适合粘贴在博文里但这段足够让读者理解写作模式%% 决策变量 Pg sdpvar(T, N_fire, full); % 火电出力 Pg_wte sdpvar(T, 1, full); % 垃圾焚烧出力 Pg_gt sdpvar(T, 1, full); % 燃气轮机出力 Pg_wind sdpvar(T, 1, full); % 实际并网风电 Pcur sdpvar(T, 1, full); % 弃风量 Pp2g sdpvar(T, 1, full); % 电转气耗电 Pccs sdpvar(T, 1, full); % 碳捕集耗电 Ecap sdpvar(T, 1, full); % 捕集CO2量 Vsng sdpvar(T, 1, full); % 储气量 u_fire binvar(T, N_fire, full); % 火电启停状态 u_gt binvar(T, 1, full); % 燃气轮机启停状态 %% 目标函数 Objective sum(fuel_cost) sum(om_cost) sum(start_cost) ... sum(carbon_cost) sum(p2g_cost) sum(curtail_penalty) ... sum(grid_cost); %% 耦合约束P2G耗CO2与捕集量的分配 Constraint [Constraint, CO2_p2g Ecap, CO2_p2g 0]; Constraint [Constraint, Ecap eta_cap * emiss_fire * sum(Pg,2) eta_cap * emiss_wte * Pg_wte]; %% 储气罐库存平衡 Constraint [Constraint, Vsng(2:end) Vsng(1:end-1) Qsng_in(2:end) - Qgt(2:end) - Qsale(2:end)]; Constraint [Constraint, Vsng Vsng_min, Vsng Vsng_max];这里的Qsng_in、Qgt都是辅助变量等于P2G产气量折算成能量、燃气轮机消耗量折算成能量。用时间索引向量化表达会让Matlab跑起来快得多建议读者不要用for循环逐时段添加约束而是用矩阵形式批量构造1000多个时段的模型也能在几秒内完成初始化。求解器配置方面我给几个实用参数cplex求解MILP的MIP gap我设为0.001relativegap设太小会导致求解时间爆炸设到0.001已经能满足调度精度。整数变量数量大约在100个以内CPLEX通常一两分钟内收敛如果用Gurobi可以开LGMethod2加速整数节点的搜索。另外YALMIP在构建大规模模型时内存占用很夸张建议用assign方法给变量赋初始值避免部分参数变化时模型重建时间过长。5. 算例测试与结果复盘协同调度相比各自为政到底赢在哪参数设好以后我设计了三个场景做对比。场景A是“无协同”各单元独立运行碳捕集装置固定捕集后直接封存P2G固定消耗夜间风电制气且不上网储能独立充放。场景B是“半协同”加入碳捕集封存与P2G的CO₂共享但不允许燃气轮机和储气罐参与电力平衡。场景C是完整协同也就是本文模型的全部功能。所有场景采用同一套风电曲线、同一套负荷曲线和相同的设备容量只是约束条件不同。主要结果如下表典型夏季日指标场景A独立场景B碳共享场景C完整协同总运行成本万元186.4174.2161.8弃风率14.2%9.8%4.6%碳配额购买量t15201063842P2G产气量MWh等效076210购电成本万元71.266.058.7场景C的收益主要体现在三个地方。第一弃风率从14.2%压到4.6%这部分原本被浪费的电能转化为合成天然气减少了从电网高价购电的压力。第二碳配额购买量从1520吨降到842吨碳市场的碳价60元/吨对应节省成本约4万元占成本下降的六分之一左右其余成本下降来自燃料替代和低电价时段购电。第三储气罐的存在让燃气轮机可以在晚高峰时段可靠补电替代了部分高价火电。单独看这个数据可能会觉得“效果也就这样”但如果把碳价调高到120元/吨、或者严重弃风场景下协同的优势会放大很多。我做了一组敏感性测试当风电出力预测值提高30%但负荷不变时场景A的弃风率飙升至27%而场景C仅升到11%。原因是P2G的耗电能力成了一块灵活的动态负荷它专门“咬住”富余风电不放相当于给新能源装了一个功率自适应的大容量缓冲器。碳捕集甲烷化的联合运行又把本来要付钱处理的碳变成了可交易、可自用的能源资产。时序出力图上有个细节很有意思在凌晨3点到5点的低负荷时段火电机组并没有因为负荷低而大幅压出力反而维持在一个较高水平——因为此时的CO₂排放被碳捕集装置高效捕获后供给P2G合成天然气整个“发电—捕碳—制气”回路的经济性在低电价时段反而最优。这和传统调度的直觉相违背但正是这个模型的核心价值它让我们看到加入碳循环后机组的最优运行区间会变化不能再死守“负荷低谷压出力”的旧经验。6. 代码调试笔记那些在论文里看不到的坑和参数敏感点模型构建过程中我踩了至少七个值得记录的坑挑重要的几个说这些细节在论文里通常只会用一两个注脚带过但实际会浪费你大半天时间。第一个坑是CO₂质量流量和能量流量的单位不统一。我在参数表里把捕集量定义成吨、甲烷化消耗定义成标方、储气量又定义成MWh结果第一次求解出来的储气量平衡差了整整一个数量级。后来我统一采用“MWh等效”作为全系统的能量单位定义1 MWh_SNG对应大约0.18吨CO₂这样一个常数表就把所有单位转换搞定了模型代码也干净很多。第二个坑是P2G的产气速率和储气罐容量的时间尺度匹配。默认参数下电解槽8小时就能把储气罐充满导致后半天燃气轮机无气可用调度结果非常激进。后来我给储气罐容量乘以2.5结果模型开始大量利用凌晨弃风制气并在傍晚发电这才出现了合理的“制气—储气—发电”日循环。提醒做类似模型的朋友储气罐容量不是越大越好太小则P2G作用受限太大则投资成本不合理必须先做一次简单的容量敏感性扫描。第三个坑是启停成本对垃圾焚烧机组的影响。我最初把垃圾焚烧机组的启动成本设为零结果模型在晚间负荷低时频繁关停它第二天早上又重启这在实际中完全不可行。固废焚烧机组一旦停炉重新起炉需要耗费大量的辅助燃料且环保手续麻烦所以在模型里我加了一个最小在线时间约束一旦开启至少连续运行12个小时。这个约束把垃圾焚烧机组变成了“准基荷机组”P2G和储气罐转而承担了更多的调节任务整体经济性反而更好。顺带说一句很多新手做虚拟电厂调度时只盯着成本函数的形式忽略了机组运行的实际物理限制这是模型脱离工程实际的最常见原因。第四个坑是YALMIP的收敛性警告。模型里储气罐平衡约束涉及前后时段的库存状态如果初始库存设置比上限还高或者容量下限设为负值求解器会报“infeasible”但提示信息很隐晦。排查方法是先用check命令逐条验证约束的可行性而不是看求解器返回的原始状态码。我建议读者在build_model脚本末尾加上一段自动检查out check(Constraint); if any(out -1e-5) find(out -1e-5) error(约束不可行); end这一行代码在调试早期能帮你省下大量时间。第五个坑是碳价和弃风惩罚系数的相对大小。如果弃风惩罚设置为500元/MWh碳价设为60元/吨模型会优先用一切手段消纳风电哪怕P2G能耗高也无所谓反过来如果碳价太高模型可能不惜多发电来多捕集CO₂去卖碳配额产生“为了捕碳而发电”的荒谬解。这两个参数的比值直接决定模型的平衡点。我测试下来弃风惩罚系数取200元/MWh时模型既不会让弃风蔓延也不会过度激励P2G耗电是一个比较合理的基准值。7. 关于这个模型还能怎么延伸的一点个人想法模型跑通之后我按不同方向尝试过几个扩展这里分享一些心得。第一个是时间粒度细化。从24点小时级细化到96点15分钟级弃风的模拟精度明显提升但储气罐的储量波动会变得更碎求解时间从2分钟涨到了约18分钟。如果你不是为了发论文而是做工程可行性分析小时级完全够用只有需要研究调频或爬坡市场参与时才值得细化。第二个是引入随机性。风电预测出力在日前调度里通常是已知曲线但实际并网功率有波动。我试过用滚动优化配合模型预测控制MPC框架每个小时更新一次风电预测并将前一时段的实际数据反馈进模型效果很好。代价是YALMIP模型要重建上百次对代码的内存管理提出了很高要求。如果读者有兴趣可以从“场景缩减两阶段随机规划”的方向做因为确定性模型作为基准解已经很成熟了升级到随机版本文献对比度也会更好。第三个是加入绿氢交易或碳交易收益的阶梯定价。当前模型里碳价是常数实际碳市场的配额拍卖价格是波动且分层的。把这个线性项改成阶梯线性项需要引入整数变量判断碳价区间虽然模型复杂度增加但更贴近真实市场结算规则。这个扩展对研究碳市场与虚拟电厂联动机制的读者会很有价值。我自己最满意的地方是这个模型把“碳”从一个被动的约束项变成了一个主动的收益项。以前做调度模型碳排放永远写在一个惩罚项里模型想尽办法逃避排放现在碳捕集捕下来的CO₂可以和P2G合成甲烷变成了调度决策的正反馈激励。这种思想上的转变比任何一行代码都更有意义。最后还是那句话代码只是载体关键是能不能把物理过程的关系看懂、用数学语言说清楚。你如果搭建过程中遇到具体的报错或者想把Gurobi、Piessolver这些换成开源求解器欢迎在评论区把现象贴出来我们可以一起讨论排查思路。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →