ARTICLE DETAIL

资讯详情

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

热电联产+电转气+碳捕集:综合能源系统优化建模与Matlab实现

热电联产+电转气+碳捕集:综合能源系统优化建模与Matlab实现 对于一个做综合能源系统优化的人来说最难回答的问题往往不是模型怎么建而是花这么多功夫把电转气和碳捕集接进热电联产系统到底图什么。这两套系统单拎出来都不便宜电转气设备效率低、成本高碳捕集系统自身就要消耗大量能量看起来是亏本买卖。但把它们放进同一个综合能源系统里事情就变得有意思了——P2G消耗的电力可以消纳弃风弃光产出的甲烷直接进天然气网而CCS捕下来的CO2又能给P2G当原料。这就不再是单纯的成本项而是一个能把系统碳排放、弃电量、燃料成本和机组灵活性同时盘活的设计。这篇博文要写的就是这类项目里最核心的建模和优化部分怎么把CHP热电联产、P2G电转气、CCS碳捕集这三大模块写成可求解的数学优化模型再在Matlab里用Yalmip这类工具把它跑起来。我会从问题动机讲起逐个拆设备的建模方程给出可以直接改着用的代码框架最后分享一些我在调这个模型时真实踩过的坑。适合正在做综合能源系统调度优化、写相关论文需要复现案例、或者刚接触P2G与CCS建模想找条明确路径的读者。1. 为什么要同时改造CHPP2G与CCS的互补逻辑1.1 以热定电造成的灵活性僵局传统热电联产机组最大的问题就是电出力被热出力绑住了。冬季供暖需求高机组必须满负荷产热电出力跟着被顶上去可再生能源想并网都没地方放于是出现了大量的弃风弃光。更麻烦的是CHP机组的调节范围很窄你不可能让它只产热不产电电和热在机组内部是强耦合的。我给很多朋友讲这个系统的价值时最爱用的一个类比是传统CHP就像一个只卖套餐的食堂电和热永远绑在一起卖你想多买点热就得被迫接受一堆电而用户真正要的是能按需点单。引入P2G和CCS之后这个僵局被打开了口子。P2G本质上是给电力负荷加了一个灵活的用电大户当电多的时候把多余电能转成天然气存起来CCS则是在机组排放侧加了一个可调的阀门通过改变烟气分流比例让CHP机组可以相对解耦地调整电出力与热出力。1.2 P2G给系统灵活性CCS给P2G提供原料这两套系统的互补关系比很多初始接触这个方向的人想的要紧密。P2G的化学反应分两步第一步是电解水制氢第二步是氢和二氧化碳反应生成甲烷即甲烷化。第二步正好需要二氧化碳而碳捕集系统的产物恰好就是高纯度CO2。也就是说CCS捕下来的CO2不再是需要封存或运输的负担而是直接作为P2G的原料形成一个CHP排碳 → CCS捕碳 → P2G用碳产气 → 天然气又回到CHP的内部碳循环。这个闭环带来的实际收益有两层。第一层是经济账系统不需要额外购买大量工业CO2作为P2G原料碳捕集得到的CO2也省去了封存环节的费用第二层是减排账经过CCS捕集后系统实际排放到大气中的碳大幅减少在碳配额或碳交易价格较高的场景下这部分减排价值相当可观。1.3 系统边界确定建模之前我建议先把系统边界画清楚。我在项目中采用的是常见的园区级综合能源系统架构电网外部购电/售电、天然气网外部购气、CHP机组、P2G设备、CCS装置、储气罐、储热罐、电负荷与热负荷。优化调度的目标是找到未来24小时内各设备的最佳运行点让总运行成本最小同时满足能量平衡和碳排放约束。注意这里没有把光伏、风电单独列为研究对象而是把它们的出力曲线作为已知输入这样处理的好处是把重点聚焦在P2G和CCS对CHP系统本身的改造上避免模型过载。2. 各设备建模方程先把物理过程写成数学表达式2.1 CHP电热可行域CHP机组建模最常见的做法是忽略启停细节直接用电热可行域feasible operation region来描述。这种模型在调度尺度下精度足够而且能保持线性约束结构。我给出一组我实际用的约束方程电出力范围为[ P_{chp}^{min} \le P_{chp}(t) \le P_{chp}^{max} ]热出力范围随电出力变化[ H_{chp}(t) \ge k_{h}^{min1} P_{chp}(t) b_{h}^{min1} ][ H_{chp}(t) \le k_{h}^{max} P_{chp}(t) b_{h}^{max} ]爬坡约束[ -P_{chp}^{ramp} \le P_{chp}(t)-P_{chp}(t-1) \le P_{chp}^{ramp} ]其中燃料消耗量为[ F_{chp}(t) \alpha_{chp} P_{chp}(t) \beta_{chp} H_{chp}(t) \gamma_{chp} ]这套可行域模型把CHP的电热耦合关系用几条线性边界刻画在Yalmip里实现非常直接。实际调试时我会用厂家给的运行数据做最小二乘拟合来定这些系数而不是拍脑袋赋值。2.2 P2G的电能-气体-碳流转换P2G建模核心是三条转换关系电转氢、氢加CO2产甲烷、以及这个过程消耗的CO2量。由于甲烷化的完整动态过程非常复杂调度模型中一般用准静态的能量转换效率来替代。输入电功率约束[ 0 \le P_{p2g}(t) \le P_{p2g}^{max} ]产气速率按热值折算为天然气功率[ G_{p2g}(t) \eta_{p2g} P_{p2g}(t) ]CO2消耗量[ C_{p2g}(t) \epsilon_{CO2} G_{p2g}(t) ]这里的 (\eta_{p2g}) 是整个P2G环节电解甲烷化的综合效率工程上取值在55%到65%之间比较合理。(\epsilon_{CO2}) 表示生产单位热值的天然气所消耗的CO2质量化学计量上是每生产1MWh热值的甲烷大约需要约0.18吨CO2。这两个参数非常关键后面优化结果对它们的敏感性很高。2.3 CCS的分流捕集与能耗CCS建模有一个绕不开的细节捕集CO2需要消耗能量主要是再沸器蒸汽和电耗这部分能量不能取之无源必须由系统自己承担。我采用的是基于分流率的捕集模型烟气分流至CCS的比例为[ \lambda_{ccs}(t) \in [0, 1] ]CCS捕集到的CO2量[ C_{ccs}(t) \eta_{ccs} \lambda_{ccs}(t) \cdot C_{chp}(t) ]其中CHP烟气中的CO2总量与燃料消耗量成正比[ C_{chp}(t) \xi_{CO2} F_{chp}(t) ]捕集能耗为[ E_{ccs}(t) \mu_{ccs} C_{ccs}(t) ]这里的 (\eta_{ccs}) 是捕集率单级胺法一般取0.85~0.9(\mu_{ccs}) 是单位捕集能耗工业数据大致在0.2~0.3 MWh/tCO2之间包含热耗与电耗。注意捕集到的CO2有两个去向一部分直接送给P2G当原料一部分如果有多余可以做封存处理假设封存成本按单位重量计。这个分流逻辑在代码里要用两行约束严格控制物料平衡。特别提醒如果系统里加了CCS但没加P2G那么捕集下来的CO2只能封存或外售这时的模型就是单纯的减排系统。而加上了P2G之后CO2能直接物尽其用这也是我建议两者联合建模的根本原因。2.4 储能、气网和电平衡约束储能部分我用的是通用能量型储能模型。储热罐状态方程为[ S_{hs}(t1) S_{hs}(t) \eta_{ch} H_{ch}(t) - \frac{H_{disch}(t)}{\eta_{disch}} - S_{hs}^{loss} ]储气罐同理只是参数换成气网侧的容量与效率。这里有个容易被忽略的点储气罐和储热罐的荷电状态初值与末值通常要相等否则24小时滚动优化会占未来便宜导致结果不可信。最后是能量平衡约束。电平衡可以写成[ P_{buy}(t) P_{chp}(t) P_{dis}(t) P_{load}(t) P_{p2g}(t) P_{ch}(t) E_{ccs}(t) ]热平衡为[ H_{chp}(t) H_{disch}(t) H_{load}(t) H_{ch}(t) ]气平衡为[ F_{buy}(t) G_{p2g}(t) G_{dis}(t) F_{chp}(t) G_{ch}(t) ]这三条平衡方程是整个系统的电路板布线所有设备的连接关系都体现在这里。如果某个设备在仿真里出现凭空产电或无中生有的热量十有八九是平衡方程漏了一项。3. Matlab实现架构数据结构与Yalmip建模模板3.1 用struct还是用class我为什么用类很多初学Matlab的人会习惯性把所有变量堆到一个大struct里一个24小时调度算例倒也能跑但是一旦设备数量增多、或者要切换不同的求解目标代码维护就会变得很痛苦。我在这个项目里采用的是简单的类封装classdef每个设备一个类内部只存放参数、决策变量、约束句柄和数据输出方法。这样做的好处是约束与设备一一对应排查问题方便场景扩展时不用改主程序加设备就像插卡。我也要说明这个项目的规模用不上完整的面向对象架构设计但按设备拆分成几个类文件确实能极大提升可读性。下面是类的骨架示例classdef CHPUnit handle properties name % 机组名称 Pmax, Pmin % 电出力上下限 Hmax, Hmin % 热出力上下限 alpha, beta, gamma % 燃料消耗系数 ramp % 爬坡速率 end properties (SetAccess private) P, H, F % 决策变量的时间序列 end methods function obj CHPUnit(para) % 构造函数从结构体para读入参数 obj.Pmax para.Pmax; % ... 略去赋值 end function define(obj, T) % 创建决策变量 obj.P sdpvar(T, 1); obj.H sdpvar(T, 1); obj.F sdpvar(T, 1); end function cons getConstraints(obj) % 返回本设备全部约束 cons [ obj.Pmin obj.P obj.Pmax; obj.H obj.Hmin ... ]; % 实际约束随模型而定 end end end注意这里我故意没把约束写全因为不同文献的CHP可行域差异很大。你在复用这份代码时最关键的是把设备参数和约束系数与自己的研究对象对齐而不是直接照搬数值。3.2 Yalmip约束搭建顺序用Yalmip建模有一个我非常推荐的顺序先定义所有决策变量再分设备写各自约束然后写耦合平衡约束最后写目标函数。顺序不对最容易出的问题是变量维度没对齐sdpvar定义成列向量后面却按矩阵去索引报错会让人抓狂。我习惯先把时间尺度T这里取24作为全局常量所有sdpvar都定义成T×1的列向量。然后按这样的分组来组织约束CHP机组约束组P2G设备约束组CCS设备约束组储能约束组电/热/气平衡约束组外购能源上限约束组。每一组约束用一个cell数组收集最终用[vcat]的方式拼接成一个约束向量。这样中间任何一个环节出了问题都能通过缩小约束范围快速定位。3.3 求解器接入与结果导出Matlab里调度优化问题最成熟的选择是Yalmip加外部求解器常用的是Gurobi或Cplex。如果你没有商业求解器也可以用开源求解器如SCIP做混合整数问题但求解速度会慢不少。在Yalmip中的调用非常简单optimize(Constraints, Objective, ops); ops sdpsettings(solver, gurobi, verbose, 1, ... debug, 1, gurobi.MIPGap, 0.005);其中MIPGap设置为0.5%通常就能满足工程需求没必要强行追求到0.01%而让求解时间暴涨几个量级。结果出来后我一般用value()批量提取各设备出力序列直接写入结构体并绘图对比。4. 优化模型的完整数学表述与代码落地4.1 目标函数拆解这个系统的优化目标我设置为最小化总日运行成本包括以下几项购电成本(\sum C_{buy}(t) P_{buy}(t))采用分时电价购气成本(\sum C_{gas}(t) F_{buy}(t))碳捕集运行维护成本与捕集量成正比碳交易成本或以碳税形式排放减去捕集后再排放的部分按碳价计P2G设备维护成本按输入电功率比例折算售电收益如果允许余电上网则作为负成本项。目标函数写出来就是[ \min \sum_{t} \left[ \pi_{buy}(t) P_{buy}(t) \pi_{gas}(t) F_{buy}(t) \pi_{CO2} E_{net}(t) C_{om}(t) \right] ]其中 (E_{net}(t)) 是净碳排放量[ E_{net}(t) C_{chp}(t) - C_{ccs}(t) ]如果管网不允许反向送电则去掉售电项。我做的算例是允许余电上网的因为P2G存在容量上限某些极端场景下系统还是会有多余电力。4.2 线性化与凸化处理整套模型最需要注意的非线性项出在CHP燃料消耗方程和CCS捕集能耗上。如果系数是常数方程本身就是线性的没有问题但如果想更精确地模拟机组效率随负荷变化而取为二次函数就必须做线性化处理。我踩过的坑是一开始用二次函数拟合CHP燃料消耗直接用二次约束丢给求解器结果Gurobi默认是不接受二次等式约束的Yalmip层面虽然能报一些转化错误但排查半天才发现问题出在数学模型本身。最后我改用分段线性化把负荷范围切成4~6段每段用线性函数近似精度完全够求解速度还更快。分段线性化在Matlab里的一个实现方式是用临时布尔变量激活各段也可以用Yalmip内置的binvar加implies来写分段逻辑。不过更省事的做法是直接用pwf或自己构造MCCormick包络这个对于24小时尺度的调度完全够用。4.3 一个24小时调度算例的代码骨架下面我给出一个经过简化的核心代码骨架适合在此基础上扩展。这里出现的是24小时调度算例的关键逻辑实际项目里数据用EXCEL或MAT文件读入即可。% 主程序IES_P2G_CCS_24h.m T 24; % 1. 读入基础数据略 % 2. 创建设备对象 chp CHPUnit(para_chp); chp.define(T); p2g P2GUnit(para_p2g); p2g.define(T); ccs CCSUnit(para_ccs); ccs.define(T); hs HeatStorage(para_hs); hs.define(T); gs GasStorage(para_gs); gs.define(T); % 3. 决策变量公共耦合变量 P_buy sdpvar(T,1); F_buy sdpvar(T,1); E_net sdpvar(T,1); % 4. 约束分组 Constraints []; % 设备自身约束 Constraints [Constraints, chp.getConstraints()]; Constraints [Constraints, p2g.getConstraints()]; Constraints [Constraints, ccs.getConstraints()]; % 耦合平衡约束 Constraints [Constraints, P_buy chp.P ... P_load p2g.P ...]; Constraints [Constraints, chp.H hs.H_dis H_load hs.H_ch]; Constraints [Constraints, F_buy p2g.G gs.G_dis chp.F gs.G_ch]; % CO2物料平衡CCS捕集量必须等于P2G消耗量加封存量 Constraints [Constraints, ccs.C_out p2g.C_use C_store]; % 5. 目标函数 Objective sum(pi_buy .* P_buy pi_gas .* F_buy pi_co2 .* E_net); % 6. 求解 ops sdpsettings(solver, gurobi, verbose, 1); optimize(Constraints, Objective, ops); % 7. 结果提取与绘图 P_chp_opt value(chp.P);这段代码的意义更多在于展示组织方式而不是让你直接跑通。实际项目里你要根据第2节给出的详细方程把getConstraints里的内容逐条补全。补充一个实用的知识点碳平衡约束里 (C_{ccs}(t) C_{p2g}(t) C_{store}(t))其中 (C_{store}) 是要额外付封存成本的那部分CO2。 P2G产气量与CO2需求之间有严格的化学计量关系模型里务必用等式约束不能用不等式放水。5. 仿真结果怎么解读成本、碳排与弃电量之间的拉扯5.1 基准场景的能流分配我先跑了一个基准场景参数设置如下P2G容量50MW综合效率60%CCS捕集率90%单位捕集能耗0.25 MWh/tCO2天然气管网用欧洲典型26元/GJ电价则是分时电价结构。结果中最有意思的电量流向是凌晨风电出力高、电价低、热负荷温和此时P2G毫不含糊地把便宜电买进来转成天然气到了白天热负荷攀升CHP机组的电出力跟着热负荷被顶高此时CCS分流比例显著上调因为系统里的多余电能少了需要靠捕集来压低等效碳排放。我本来预期CCS高捕集率一定会大幅拉高运行成本但结果却是在电价低谷时段捕集能耗带来的成本增加部分被P2G产气后降低购气成本给对冲了。这个现象正是CCSP2G联合建模的价值所在没有P2G的CCS系统捕下来的碳无处可用捕集能耗纯属净成本而有了P2G之后这部分CO2变成原料相当于每吨碳卖给了天然气链。5.2 P2G容量扫描把P2G容量从20MW依次扫到120MW观察总日运行成本的变化呈现的是一个典型的先降后升U型曲线。容量太小时半夜多余电能无法被充分消纳弃电惩罚依然很重容量太大时P2G设备本身在大部分时段处于低负载率运行维护成本与投资折旧大于它带来的消纳收益。这个扫描结果给项目决策的启示很直接P2G容量的最优值不是拍脑袋定的它取决于当地电网的弃电曲线形状和电价低谷时段的持续时间。如果你的园区弃电时段很短但强度很大那么小容量高负载率反而比大容量更经济。5.3 碳捕集率与系统经济性的取舍碳捕集率是CCS系统的核心调节参数。将捕集率从60%扫到95%系统净碳排放线性下降但日运行成本并非线性上升而是呈现一个加速上升的趋势。原因是捕集能耗与捕集量成正比捕集率越高需要的能耗越大而且高捕集率下烟气里CO2浓度变稀单位能耗还会额外增加。我在结果分析中参考碳排放交易价格做了一张成本变化表当碳价超过一定阈值后较高捕集率反而成为经济最优。这就意味着CCS捕集率不必锁定在单一值在动态电价和碳价下它本身就是值得纳入优化的连续决策变量。6. 踩坑记录非线性项、数值病态与参数陷阱6.1 单位不统一导致的量纲错误这是我在调试中最尴尬的一个问题。CHP的燃料消耗方程用的是kW作为功率单位而天然气购买的计价单位是GJP2G产气量我偷懒用了m³结果目标函数里三项相加出现功率、能量、体积三类单位直接相加的荒谬情况。Yalmip不会帮你查单位求解器更是来者不拒最后出来的最优解完全不能看。解决方案其实很土统一能量单位。我最后约定系统中一切能量流都用MW功率和MWh能量天然气统一按热值折算成天然气功率MW参与平衡二氧化碳统一按吨计量。建议你在项目一开始就建立一个单位转换表贴在代码注释里别靠记忆。6.2 24小时周期储能初末值约束储能设备初末值相等这个约束我最初觉得理所当然实际上手时却经常忘记处理储气罐。储气罐SOC一旦不闭合求解器就会利用第一天初始状态低、最后时刻状态高这种漏洞把廉价气存在罐里让最终成本表面上好看实际上违背了日化调度的基本假设。加入SOC末值等于初值的等式约束后结果总成本通常会上升这是正常的。千万别为了让结果更好看而放松这个约束否则论文评审一算能量平衡就能发现问题。6.3 CO2来源假设的现实性检验我在模型初版里假设CCS捕集的所有CO2都恰好等于P2G所需不需要额外补充。跑出来系统自给自足、零外购CO2看起来很完美。但仔细一算CHP机组运行在低负荷时烟气产量小捕集量不足以喂饱满载的P2G。这时模型会把P2G产气量压下来这本身没问题只是你要意识到现实中P2G装置可能需要外购CO2或配备储碳罐建模时是否允许外购CO2会显著影响最优结果。我还试过把CO2外购价格设为0结果P2G在各时段都满负荷运行因为天然气侧收益掩盖了CO2成本。这个现象提醒我CO2价格这个参数比P2G本体效率对结果更敏感做敏感性分析时一定要把它放进去。回到最初的问题——为什么要把P2G和CCS一起放进CHP系统我的体会是这两套设备本身都不是改善系统经济性的独立武器它们的价值只能通过耦合来兑现。P2G需要碳源CCS需要碳去向CHP需要灵活性和减排空间三者正好互相补位。而建模的难点不在于单个方程多复杂而在于把这些跨时间尺度、跨能量形态的约束正确地咬合在一起。Matlab加Yalmip的组合胜在调试周期短、可视化和敏感性分析方便很适合研究阶段的场景对比。如果你也在做类似的系统我的建议是先把第2节的方程一项项对照着在代码里实现然后再考虑加惩罚项、改目标函数或者过渡到多目标优化基础模型不打牢后面每一步都是空中楼阁。
返回列表