多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

计及电转气协同的含碳捕集与垃圾焚烧虚拟电厂优化调度建模与实现

计及电转气协同的含碳捕集与垃圾焚烧虚拟电厂优化调度建模与实现 做虚拟电厂优化调度这几年我几乎每个月都会碰到同行在群里问同一个问题垃圾焚烧、碳捕集、电转气这些单元单独看都很“绿”但把它们放进同一个虚拟电厂里到底该怎么配合不少人的模型里各算各的碳捕集出来的二氧化碳直接封存P2G再去外购二氧化碳做原料白白浪费了内部耦合的机会。这篇博文就围绕“计及电转气协同的含碳捕集与垃圾焚烧虚拟电厂优化调度”这个题目把这个模型从设计思路、数学建模到Matlab代码实现完整拆一遍重点讲清楚三件事为什么这几个单元天然适合绑定在一起、目标函数和约束该怎么写、用Yalmip建模时哪些坑是你一定会踩的。适合正在做虚拟电厂、综合能源系统或低碳调度方向的研究生和工程师参考代码思路拿过去改改数据就能跑。1. 方案设计为什么碳捕集、电转气和垃圾焚烧能组成“铁三角”很多人看到这个标题的第一反应是题目里塞了三个技术名词是不是为了显得高级硬凑的还真不是。碳捕集、电转气和垃圾焚烧电厂在物理特性上存在天然的互补关系放在虚拟电厂的框架下它们仨恰好能形成一个“电-碳-气”闭环。理解了这一点后面所有建模工作都顺理成章。1.1 虚拟电厂的功能定位虚拟电厂表面上看是一个“聚合调度”的概念把分布式光伏、风电、燃气轮机、储能、可调负荷这些零散资源打包成一个整体对外只提供一个接口参与电网调度和电力市场。但落到优化调度模型里虚拟电厂真正做的事情是“在满足所有物理约束的前提下让整个系统运行成本最低、碳排放最小”。它不是简单的求和而是要做协调——哪个时段让谁多发电、谁去消纳新能源、谁去捕碳、谁去耗电制造燃气全都要靠优化模型统一决策。加了碳捕集和电转气之后虚拟电厂内部就多了一条完整的“能量-物料”循环链。这条链的价值在于它把一个单纯发绿电的虚拟电厂升级成了一个既能发绿电、又能处理城市固废、还能主动消化自身碳排放的复合系统。这也是为什么这类题目成了近几年电网调度方向的热门研究对象。1.2 P2G与碳捕集电网侧的“碳循环工厂”电转气Power to Gas简称P2G的原理是三句话能讲完的用多余的电把水电解成氢气氢气再和二氧化碳反应生成甲烷甲烷可以直接进天然气管网或供燃气轮机发电。这里的关键在于甲烷化反应需要消耗二氧化碳而碳捕集系统捕到的最纯、最集中、运输成本最低的二氧化碳来源恰恰就在虚拟电厂自身。碳捕集系统需要消耗大量电能来运行包括吸收剂再生、压缩机增压等而P2G也需要大量的电能来电解水。这两个耗电大户放在一起带来一个非常有意思的优化空间新能源大发时段光伏和风电出力超出负荷需求与其弃掉不如分一部分给碳捕集和P2G。碳捕集把火电厂或垃圾焚烧电厂排出的CO2捕集下来P2G把这些CO2和电解产生的氢气合成天然气存储在储气罐里等到电力紧张或气价较高时段再通过燃气轮机发回电能。这个闭环的工程意义在于它把“电”和“碳”两个系统融合成一个整体。传统的虚拟电厂调度碳捕集只是减少对外排放P2G只是增加本地负荷两者互不相关而在这个模型里碳捕集的产碳速度和P2G的耗碳速度必须动态匹配储气罐就是缓冲池。模型优化时不仅要看电功率平衡还要看碳物料的平衡和储气罐的液位约束复杂度一下子从单一能源载体的调度问题升级成了多能源耦合的调度问题。1.3 垃圾焚烧电厂的隐藏价值既是电源又是碳源单独看垃圾焚烧发电它只是城市生活垃圾无害化处理的一种方式。垃圾燃烧产生高温烟气推动汽轮机发电吨垃圾发电量大约在300到400千瓦时效率和煤电没法比但胜在燃料来源稳定、日处理量基本可预测很适合作为虚拟电厂里的基荷电源。但放到碳捕集和P2G这个框架里看垃圾焚烧电厂还有一个隐藏身份——最便捷的二氧化碳供应源。垃圾焚烧烟气的CO2浓度通常在8%到12%之间比燃煤电厂的烟气含量略低但仍然具有捕集经济性。更重要的是城市垃圾每天都在产生垃圾焚烧电厂是365天连续运行的这意味着它能持续稳定地为P2G提供二氧化碳原料不像燃煤机组可能因为调峰停机而中断碳源供应。这样一来三个单元的定位就非常清晰了垃圾焚烧电厂负责“稳定供电稳定供碳”碳捕集系统负责“从烟气中分离高纯度CO2并消耗低谷电力”P2G负责“消纳新能源把CO2变成可储存的燃气”。三者共同服务于虚拟电厂的低碳低成本运行目标。模型选型的核心逻辑就是用垃圾焚烧的连续性去匹配碳捕集的连续性再用P2G的灵活性把碳捕集消耗掉的电力转化为可调度的气态能源。2. 调度模型怎么搭目标函数与核心约束拆解这一节是全文最核心的部分。我不给完整公式矩阵而是按“目标函数→功率平衡→碳捕集模型→P2G模型→碳交易模型”的顺序逐个拆每个模块告诉你为什么这么建模以及最容易被忽略的细节在哪里。2.1 目标函数设计成本、碳排放和弃电惩罚怎么权衡虚拟电厂优化调度的目标函数通常写成单目标最小化把运行成本、碳交易成本和弃新能源惩罚加在一起。参考常见做法目标函数可以拆成以下五个部分燃料成本包括垃圾焚烧电厂、燃气轮机的燃料费用运维成本各单元按出力比例计提的固定运维成本碳捕集运行成本捕集单位CO2所需的能耗成本与捕集量成正比P2G运行成本电解水和甲烷化的维护成本碳交易成本实际碳排放量超过配额时需要购买碳排放权低于配额则可以出售按碳价线性结算弃风弃光惩罚实际上网风电光伏低于预测出力时施加惩罚系数目标函数的形式可以写成各项在所有调度时段内的累加和。值得特别说明的是弃风弃光惩罚系数一定要大于其他发电成本否则优化器会选择“弃掉新能源”而不是“多花钱运行P2G消纳它”整个低碳耦合调度就名存实亡了。实际项目中这个惩罚系数我一般取400元/MWh以上远高于P2G的单位消纳成本确保新能源出力在满足安全约束的前提下尽可能全额上网。2.2 功率平衡约束与碳捕集电厂净出力模型电功率平衡是调度模型最基本的约束但这个模型里的平衡公式比普通虚拟电厂多出几个关键项。某个时间断面的功率平衡可以写成可再生能源出力燃气轮机出力垃圾焚烧出力碳捕集电厂净出力常规电负荷P2G耗电量碳捕集系统耗电量弃电修正量这里特别要注意“碳捕集系统耗电量”这一项。碳捕集不是免费的它是耗电大户捕集一吨CO2大约需要消耗0.2到0.4 MWh电能。这部分电能从哪里来、在什么时段来直接决定了碳捕集系统的运行策略。如果把碳捕集设备挂在火电机组或垃圾焚烧机组上机组本身的出力上限会因捕集能耗而被压缩实际并网净出力远低于锅炉产出的毛出力。因此在变量定义阶段就要把“毛出力”和“净出力”分开处理毛出力是锅炉燃烧产生的总功率净出力等于毛出力减去捕集能耗对应的功率。这个细节在初学阶段特别容易踩坑。很多人直接给机组定义一个“出力变量”既当毛出力又当净出力导致功率平衡约束里缺少捕集能耗项优化结果里碳捕集系统几乎不会运行因为“不需要付出任何代价就能减碳”在数学上是不成立的。2.3 P2G建模能量与物料的双重平衡P2G的建模是整个模型里最有特色的部分因为它同时涉及电力系统和物料系统。从电力侧看P2G是一个可控负荷输入变量是耗电功率从气体侧看它产出的甲烷量与CO2消耗量之间存在化学计量关系。工程上通常用效率简化处理不追求反应动力学的精细建模。P2G的综合效率按电转甲烷的完整链路取0.55到0.65之间。这个效率代表电能转化为甲烷化学能的比率包含电解水效率和甲烷化反应的损耗。实际工程中如果只做电转氢电解效率可以做到0.7到0.8但为了能和CO2直接配对生成甲烷模型里我习惯按提供天然气产品来考虑综合效率取0.6左右。这个参数直接决定P2G的经济可行性效率越低单位天然气的耗电成本越高优化器就越不愿意开启P2G。CO2消耗量的折算也很有讲究。按电转甲烷的化学计量关系理论消耗量大约为0.2吨CO2/MWh。不同论文里这个系数略有出入从0.18到0.22都有推荐做法是直接根据你设定的P2G效率和天然气热值重新推一遍不要在文献里随手抄一个常数因为后续碳平衡约束的计算结果会和一个不匹配的系数相互矛盾。P2G的出力还受储气罐约束限制。储气罐模型通常写成递推形式当前储气量等于上一时段储气量加上本时段P2G产气量减去燃气轮机消耗和对外供气量同时需要约束每个时段的储气量在上下限之间并强制调度周期开始和结束的储气量相等。这个“始末相等”约束非常关键它保证了优化结果不是一个“用完即止”的单程消耗问题而是一个可持续循环的调度方案。2.4 碳交易成本配额怎么给、排放怎么算碳交易机制是将碳排放转化为经济量从而驱动系统主动减排的手段。模型中常见的是基准线配额法碳交易主管部门给虚拟电厂设定一个碳排放配额配额量通常和火电、垃圾焚烧等化石能源机组的发电量挂钩乘以一个基准排放强度。如果实际碳排放量低于配额虚拟电厂可以出售多余配额获得收益反之则需要购买额度形成成本。实际碳排放量计算时要通过碳捕集量进行扣减这里又体现了一次“碳捕集-电转气”协同的价值。如果我们把捕集到的CO2作为原料生产甲烷这个CO2最终又通过燃气轮机燃烧回到了大气严格的碳核算口径下它确实应该算作排放。但在目前的碳市场规模下很多优化调度文献把P2G对CO2的利用视为“循环利用”予以扣减这一块要根据你所在地区的碳核算规则确定边界。模型代码里我建议把“捕集量”“P2G利用量”“实际净排放量”分别列出三个独立的变量这样无论是改成严格核算还是宽松核算都只需调整目标函数里对应的一个系数不必大改约束结构。碳交易成本最终写进目标函数时只有一个线性项碳价乘以实际净排放与配额的差值。碳价参数虽然模型里只是一个常数但它对整个调度策略的影响非常大后面第4章专门对碳价做敏感性分析时会再解释。3. Matlab代码实现从零搭建完整调度框架模型思路理清楚之后Matlab代码实现就是一个“翻译”过程。这个课题用到的建模工具链非常固定Yalmip做建模层CPLEX或Gurobi做求解层。如果你还在用fmincon手写优化代码建议尽早换到Yalmip调度决策问题绝大多数是线性规划或混合整数线性规划Yalmip的矩阵化约束写法能省掉80%的重复代码。3.1 建模工具选型与求解器准备Yalmip是Matlab下的开源优化建模工具箱底层调用商业求解器求解本身不做数值计算。选择CPLEX还是Gurobi看个人许可情况Gurobi近年学术许可比较方便CPLEX老牌稳定。两个求解器对线性规划和混合整数线性规划的求解能力都远超Matlab自带的linprog和intlinprog。遇到大规模问题时建议优先Gurobi实测在含上百个整数变量的调度问题里Gurobi的MIP求解速度通常比CPLEX快30%左右。装好求解器后在命令行输入yalmiptest看到CPLEX或Gurobi前面标了Available说明Yalmip已经能调用它这个检查步骤能省掉后面一半的报错排查时间。3.2 决策变量定义与数据初始化定义决策变量前先把时间断面数T、机组数量和各类参数读入工作区。T一般取24代表24小时日前调度。典型变量定义代码如下T 24; % 调度时段 P_gas sdpvar(1, T); % 燃气轮机出力 P_waste sdpvar(1, T); % 垃圾焚烧发电出力 P_capture_gross sdpvar(1, T); % 碳捕集机组毛出力 P_p2g sdpvar(1, T); % P2G消耗电功率 Q_gas_store sdpvar(1, T1); % 储气罐储量 U_co2_capture sdpvar(1, T); % 碳捕集系统捕集CO2量 P_wind_use sdpvar(1, T); % 实际上网风电 P_pv_use sdpvar(1, T); % 实际上网光伏 P_curtail sdpvar(1, T); % 弃风光电量这套变量设计刻意避免把所有机组整合成一个笼统的“总出力变量”目的就是让功率平衡约束能直观体现碳捕集耗电和P2G耗电这两个独立环节。变量粒度决定了你能做什么分析如果你想知道某个时段碳捕集到底消耗了多少电力这个信息必须从独立变量里拿到。如果共用一个变量后面画图分析时数据得靠手算非常麻烦。3.3 约束构建Yalmip代码里的关键细节约束构建的顺序建议严格遵循功率平衡→机组爬坡→碳捕集→P2G物料平衡→储气罐→碳配额→弃电约束。一个容易出问题的地方是碳捕集净出力和捕集CO2量之间的耦合关系。假设捕集单位CO2消耗的电量为e_ccs那么碳捕集机组的净出力可以写成毛出力减去捕集消耗的电功率% 碳捕集机组净出力 P_capture_net P_capture_gross - e_ccs .* U_co2_capture; % 电功率平衡约束 Constraints [Constraints, ... P_wind_use P_pv_use P_gas P_waste P_capture_net ... P_load P_p2g e_ccs .* U_co2_capture P_curtail];仔细看这条约束会发现等式右侧又出现了一次e_ccs .* U_co2_capture因为碳捕集系统的耗电属于虚拟电厂内部的额外负荷。如果左侧已经扣掉了捕集耗电右侧就不能再加一次反过来如果碳捕集机组用毛出力参与平衡右侧就必须明确加上捕集能耗项。这两种等价写法都可以但混用就会导致功率不平衡这是我刚做这个模型时最常犯的错误。P2G的物料平衡约束也不复杂但单位要特别小心。CO2消耗量和产气量、耗电量之间要按常数系数换算例如% P2G耗电与产气量关系 Q_gas_p2g eta_p2g * P_p2g * 3600 / gas_lhv; % m3/h % CO2消耗量 单位产气CO2消耗比 * 产气量 U_co2_p2g k_co2_gas * Q_gas_p2g; % CO2物料平衡捕集量必须覆盖P2G消耗量 Constraints [Constraints, U_co2_capture U_co2_p2g];储气罐约束加上始末相等条件Constraints [Constraints, Q_gas_store(2:end) Q_gas_store(1:end-1) ... Q_gas_p2g - Q_gas_use]; Constraints [Constraints, Q_gas_store 0, Q_gas_store Q_gas_max]; Constraints [Constraints, Q_gas_store(1) Q_gas_store(end)];这里要强调Q_gas_store定义多取了一位T1是为了让递推约束在索引对齐上更顺手避免出现越界。3.4 目标函数、求解设置与结果后处理目标函数用总成本最小化代码如下Objective sum(fuel_cost om_cost ccs_cost p2g_cost ... carbon_cost curtail_penalty); ops sdpsettings(solver, gurobi, verbose, 2, ... gurobi.MIPGap, 0.001); optimize(Constraints, Objective, ops);求解完成后结果后处理建议用value()提取所有变量存入结构体再统一画图。画图至少要出三张电功率平衡堆叠图看各电源供给结构、储气罐液位变化曲线验证P2G运行的周期耦合、碳排放和碳交易量柱状图看碳捕集效果。这三张图是论文里最常用也是审稿人最爱看的分析维度。我习惯把每个变量都带单位保存成一个表格后续做敏感性分析时直接读表格数据不用反复重跑求解器。4. 常见问题与调试技巧实录4.1 模型报“Infeasible Problem”怎么办这套模型里几乎所有不可行问题都出在约束过紧优先检查三个位置。第一功率平衡约束的等式方向和数据单位是不是一致。第二储气罐始末相等约束如果储气初始容量设得过高而P2G产气能力有限末时段可能无法回到初始值。第三CO2物料平衡碳捕集最大捕集量是否能覆盖P2G的最大消耗量如果捕集能力不足模型直接无解。调试不可行问题的实操技巧是“逐条放宽法”把P2G的CO2消耗量约束先删掉看是否能求解。如果能说明问题出在CO2物料平衡上如果还不能再删储气罐末端约束继续往上游排除。这个方法比盯着报错信息猜半天有效得多我调试过的同类模型基本都能在十分钟内定位到具体冲突约束。4.2 求解速度慢几个立竿见影的处理手段含P2G、碳捕集这类模型的复杂度主要来自储能类变量的时间耦合加上机组启停的整数变量后求解时间会明显增长。如果单个场景跑5分钟还没出结果通常不是求解器能力问题而是模型写法有优化空间。首先要检查是否引入了不必要的整数变量。垃圾焚烧和燃气机组的启停状态如果不是刚性要求可以考虑把启停成本折算进分段出力成本全部改成连续变量MIP变LP后求解速度会快一到两个数量级。如果要保留整数变量就显式设置MIPGap为0.001到0.01之间而不是默认的0工程上1%以内的最优性偏差完全可以接受。还有一个小技巧约束里的非线性项比如效率的分段线性化不要让Yalmip自动检测尽量手动用二进制变量和大M法写出来求解速度会稳定很多。4.3 碳价和P2G效率的敏感性建模分析的关键模型跑通之后很多人只做一次求解画几张图就结束了。但对研究型课题来说敏感性分析才是体现工作量的地方。我强烈建议至少做两个维度的分析。第一个维度是碳价从低到高变化观察P2G消纳量和碳捕集率的响应曲线。碳价低时系统没有动力额外捕碳P2G也主要靠弃电量驱动碳价升高后捕集CO2的经济价值超过运行成本捕集量会快速增长。这个拐点对应的碳价就是整个虚拟电厂的“减排激活阈值”写论文时这个数非常有用。第二个维度是P2G综合效率的变化。效率从0.4到0.7变化时P2G总耗电量和产气量会呈现明显非线性增长。效率低于某个临界值时P2G几乎不会运行全系统走“捕集封存”路线高于临界值后P2G频繁投运碳捕集系统的约束从“是否捕”转变为“捕了够不够用”。推荐做法是写一个循环脚本把碳价或效率参数按步长迭代求解50次左右自动生成二维曲线数据量不多但说服力极强。4.4 常见错误速查表为了让大家快速排查问题我把这个课题中最常出现的几类错误整理成一张速查表。错误现象根本原因解决办法优化结果中碳捕集量恒为0目标函数里捕集成本设置过高或功率平衡没加捕集耗电项核对捕集能耗是否进入功率平衡降低单位捕集成本参数P2G从不启动P2G效率参数设置过低或甲烷售价/燃气价值设置不合理将eta_p2g调整到0.55以上增加P2G产气的收益项储气罐始终处于满罐状态未设置储气价值或燃气机组耗气约束缺失加入燃气轮机耗气与发电的对应关系结果里弃风量仍很大弃电惩罚系数低于P2G消纳成本提高弃电惩罚系数到400元/MWh以上CPLEX报内存不足整数变量过多或约束书写造成Yalmip生成大量辅助变量减少不必要的整数变量检查是否有重复约束定义4.5 数据准备别在入口就翻车最后说一说数据准备。这类模型的输入数据包括负荷曲线、风光预测出力、垃圾到场量、机组参数和碳交易参数。垃圾到场量这一项在实际项目中专门强调一下城市生活垃圾的热值波动很大夏天和冬天差别能达到30%以上。建模时垃圾投入量建议按小时处理而不是全天取一个固定平均值。如果当天有垃圾焚烧电厂停炉检修的情况还要把对应时段的出力上限置为0否则功率平衡约束很可能给出一份“垃圾电厂既检修又发电”的荒谬结果。前期把数据质量检查好比后期改模型改约束省时间得多。参数设置方面给大家一组我调试过多次、能保证模型合理收敛的基准值P2G综合效率取0.6碳捕集效率取0.9捕集单位能耗取0.3 MWh/吨CO2单位垃圾发电量取350 kWh/吨碳交易价格取100元/吨。这组参数不是唯一正确答案不同地区不同项目会有变化但作为第一版跑通模型完全够用跑出来之后再根据实际场景微调。垃圾焚烧烟气CO2浓度取10%体积分数对应吨垃圾CO2生成量大概在0.8吨左右这个值用于计算总排放配额和P2G原料供应上限。最后分享一点我的个人体会代码写完之后最好把碳捕集量和P2G耗电量画在同一张图上你会非常直观地看到两个变量的“镜像关系”——新能源大发时段碳捕集量上升P2G耗电同步上升储气罐液位随之爬升而负荷高峰时段两者同时下降储气罐释放气体供电。看到这张图的时候模型才真正从代码变成了一个活的系统。如果你刚做完类似课题强烈建议花半小时跑一次碳价敏感性分析结果里那个效率拐点比任何文字论述都更有说服力。
返回列表