1. 电转气系统的完整流程与关键物理原理
1.1 电转气到底在转什么
电转气这个词乍一听有点抽象,但把它拆开就很好理解了。所谓"电转气",英文叫 Power to Gas(P2G),核心就是把电能转化成可储存的气体燃料。最常见的路径是:先用多余电能电解水制氢,得到氢气;氢气可以直接作为燃料使用,也可以进一步和二氧化碳反应制成甲烷,也就是合成天然气。这样一来,原本只能沿电网实时传输、无法大规模存储的电能,就变成了可以装进储氢罐、天然气管道甚至地下储气库里的化学能。
我做这个项目时的第一反应是:这不就是一个"电的充电宝"吗?但真正往里挖的时候发现,它的定位比电池更特殊。电池解决的是小时级的削峰填谷,而 P2G 适合的是周级、月级甚至跨季节的能量搬移。风力发电在春秋两季夜间大发时,电网可能吃不下那么多电,这时候把多余电能转成氢气存起来,等到缺电季节再通过燃气轮机或燃料电池发出来,这就把"时间差"补上了。
一个完整的电转气系统通常包含以下几个环节:
- 电力输入:来自风电、光伏或者电网低谷电;
- 电解制氢:通过碱性电解槽、质子交换膜电解槽或固体氧化物电解槽将水分解;
- 气体处理:包括氢气纯化、压缩、干燥;
- 存储与输运:储氢罐、盐穴、天然气管道掺氢;
- 甲烷化(可选):氢气和二氧化碳在催化作用下合成甲烷;
- 终端利用:燃气发电、工业供热、交通燃料或化工原料。
我做的 MATLAB 程序主要覆盖第 1、2、4、6 步的能流计算与运行优化,也就是回答"在多长时间内、给多少电、产多少氢、存多少气、最后怎么用最划算"这类问题。
1.2 为什么偏偏用它来对接新能源
很多人会问:电池不也能储能吗,为什么还要费劲去电解水制氢?
不妨算一笔账。以 100 MW 风电场为例,假设某天夜间负荷低谷时段有 8 小时富余电量,总富余电量约 400 MWh。如果用锂电池储能,按 90% 的往返效率,最终能送回电网约 360 MWh;如果用 P2G,电解效率 68%,发电时要再经过燃气轮机,效率按 45% 算,总效率大约只有 30% 左右,最后能送回电网约 120 MWh。单看效率,P2G 简直被电池按在地上摩擦。
但换个角度看,P2G 有两个电池给不了的特性:
- 容量成本极低。储氢罐扩张容量的边际成本远低于电池模组,而且一旦利用盐穴储气,单位存储成本可以做到每千瓦时几分钱;
- 产业链价值高。氢气本身是工业原料,可以卖给炼油厂、化工厂、加氢站,不做"储能"做"原料"也能盈利。
所以在实际项目中,P2G 不是电池的替代品,而是和电池形成互补。电池负责日常的短时平衡,P2G 负责长周期、大容量的能量转移,两者协同才能把新能源的利用率拉上去。我的 MATLAB 模型在设定目标函数时也验证了这一点:当 P2G 同时考虑"削峰填谷收益"和"氢气销售收入"时,系统的经济性明显改善,而不只是盯着电-氢-电的往返效率。
1.3 效率边界:每一度电都去哪了
做仿真之前,必须先把系统的效率边界画清楚。我在程序里把 P2G 流程拆成了三段来分别计算:
| 环节 | 典型效率范围 | 主要损耗 | 说明 |
|---|---|---|---|
| 电解制氢 | 60%~75% | 电热损耗、欧姆损耗、过电位 | 碱性电解槽偏低,PEM 偏高 |
| 压缩与储氢 | 90%~95% | 压缩机功耗、阀门节流 | 压力越高损耗越大 |
| 甲烷化 | 75%~85% | 反应热排放、产物分离 | 若副产热得以利用则效率更高 |
从电解到最终产甲烷,综合效率通常在 50%~60% 之间;如果不做甲烷化直接使用氢气,流程效率更高一些。另外还要注意,如果模型中考虑了"电转氢再转电",那段效率会非常难看,所以我在做调度优化时会引入"能量价值"而不是单纯"能量效率"作为目标,否则仿真结果会强烈倾向于——不要用 P2G,这显然偏离了实际工程场景。
% 基础P2G系统参数定义(可直接运行) P_wind_max = 100; % 风电场额定容量 MW P_demand = 90; % 电网负荷基线 MW P2G_capacity = 8; % 电转气额定功率 MW eta_elec = 0.68; % 电解槽效率 LHV_H2 = 33.33; % 氢气质量低热值 kWh/kg rho_h2 = 0.0899; % 氢气密度 kg/m3 @ 标准状况 % 模拟24小时风电出力(简化归一化曲线) time = 0:23; P_wind = P_wind_max * (0.25 + 0.55 * exp(-((time - 14)/5).^2) + 0.05 * sin(time/3)); P_surplus = max(0, P_wind - P_demand); % 电网无法消纳的富余电力 % 电转气产氢计算 P_p2g = min(P_surplus, P2G_capacity); % P2G实际输入功率 MW m_H2 = P_p2g * eta_elec ./ LHV_H2 * 1000; % 每小时产氢质量 kg % 结果输出 disp(table(time', round(P_wind',1), round(P_surplus',1), ... round(P_p2g',2), round(m_H2',1), ... 'VariableNames', {'小时','风电出力MW','富余电力MW','P2G输入MW','产氢kg'}));这段代码是整个程序的心脏。P_surplus是电网需求之外的风电出力,P_p2g要再限幅到 P2G 额定功率以内——这一步特别关键,因为工程上电解槽不可能无限接受功率,额定值以内的部分才有意义。算出来的m_H2就是每个小时实际能产出的氢气质量,后面所有储氢、收益分析都基于这一列数据。
2. 用MATLAB做电转气仿真,一开始要想清楚什么
2.1 先分清三种模型层级:能流、状态、经济
我在第一次动手写 MATLAB 程序时踩过一个大坑:一上来就想把所有物理细节塞进代码,结果项目拖了三个星期,跑出来的结果还没法看。后来我把问题拆开才明白,P2G 仿真有三个层级,千万要分清:
- 能流模型:只关注"多少电转换成多少氢",不考虑内部电压电流变化,适用于系统级规划和收益测算;
- 状态模型:关注电解槽温度、压力、电流密度等动态响应,适用于设备级控制和故障分析;
- 经济优化模型:在能流基础上叠加电价、气价、设备投资和运维成本,用于回答"怎么调度最赚钱"。
大多数项目起步都应该从能流模型入手,先把能量账算清楚,再做经济优化。只有当你需要研究电解槽本身的动态特性时,才需要引入状态模型。我见过不少初学者拿热力学建模的思路去搞系统规划,最后满屏幕都是微分方程,连基础的能量守恒都忽略了,这就是模型层级没选对。
2.2 场景选不好,程序写得再好也白搭
仿真场景直接决定你的模型输入和边界条件,我在项目中常用的场景有三种,各有各的难点:
| 场景类型 | 适用目标 | 时间尺度 | 关键输入 |
|---|---|---|---|
| 单日运行仿真 | 验证设备运行逻辑 | 24h | 典型日负荷曲线+风电出力 |
| 月度调度优化 | 制定储氢与售氢计划 | 720h | 分时电价、设备检修计划 |
| 年度规划评估 | 设备容量配置 | 8760h | 全年新能源出力、政策补贴 |
选场景时有个重要原则:你想要什么结论,就选什么时间尺度。如果目标是"这台 8 MW 电解槽一天能产多少氢",把 24 小时风电曲线喂进去跑一遍即可;如果你要论证"储氢罐该建 1000 m³ 还是 3000 m³",那必须用至少一个完整年度的时序数据跑优化,否则风光季节性变化会让容量结论完全失真。
我这次项目做的是月度调度场景,因为电网侧最关心的是"下个月风电大发期怎么安排 P2G 设备运行"。为了保证数据质量,我用了时序生成的方法:先采集全年典型风电出力特性,再用 MATLAB 的datasample做重采样,生成了 30 天、每天 24 点的风电出力序列。这样做的好处是保留了昼夜和季节规律,又引入了合理随机波动。
2.3 程序结构这样搭,后面能省一半时间
写了多年 MATLAB 之后,我深刻体会到:仿真程序拼的不是算法复杂度,而是程序结构。P2G 项目涉及参数、数据、计算逻辑、优化求解、结果展示五大部分,我推荐按下面这种方式组织:
set_params.m:所有系统参数集中定义,包括设备容量、效率、价格,改参数只改这里;load_data.m:负责读取和生成时序数据,统一输出标准化结构体;p2g_core.m:核心计算函数,输入功率序列,输出产氢、储氢量;optimize_dispatch.m:调度优化模块,调用linprog或intlinprog;plot_results.m:统一出图,保存结果。
模块化带来的直接好处就是"改参数不废代码"。我把电解效率从 0.68 改成 0.75 时,只需要动set_params.m里的一个数字,所有计算和出图自动更新。不要图省事把参数写死在各自的脚本里,那后面排查问题会让你怀疑人生。
3. 核心程序实现:P2G能量流计算实例
3.1 参数定义与基本计算逻辑
参数定义永远先于一切。我把set_params.m写成了一段结构清晰的代码,每个参数附注释和单位,这样即使过三个月再回头看也明白当初设定的是什么。
% set_params.m p = struct(); % 电气参数 p.P_wind_max = 100; % 风电场额定功率 MW p.P_p2g_max = 8; % 电转气系统最大输入功率 MW % 电解单元参数 p.eta_elec = 0.68; % 电解槽效率(电力→氢化学能) p.P_elec_min = 0.1; % 电解槽最小运行功率,低于此值停机 p.u. % 储氢参数 p.V_storage = 2000; % 储氢罐容积 m3 p.p_max = 20; % 最大储氢压力 MPa p.p_init = 2; % 初始压力 MPa p.T_storage = 293; % 储罐温度 K % 价格参数(单位:元/kg,元/MWh) p.price_H2 = 35; % 氢气销售价格 p.price_elec = 300; % 电网峰时购电价格(用于对比) p.price_surplus= 80; % 富余风电价格(机会成本) % 气体物性 p.LHV_H2 = 33.33; % 氢气低热值 kWh/kg p.M_H2 = 2.016; % 氢气摩尔质量 g/mol p.R_gas = 4124; % 氢气气体常数 J/(kg·K)这里的p结构体就是全项目的"参数数据库"。之所以用结构体而不是散落的变量名,是为了避免命名冲突,也方便作为参数传递给函数。P_elec_min这个参数很多人会忽略,但它对优化结果影响很大——电解槽不可能无限降负荷运行,低于某个比例就必须停机,程序里要用变量bin_on来约束这一行为。
基础能流计算的核心逻辑在上面第一段代码已经展示过,实际项目里我还会加一层"电解槽效率曲线修正"。效率并不是恒定值,负载率低时效率会偏低,负载率高时热损失占比变小,效率会升高。我通常用一个多项式拟合效率曲线:
% 电解槽效率随负载率变化示例(拟合用) load_ratio = 0:0.1:1; eta_curve = 0.55 + 0.15 * load_ratio - 0.03 * load_ratio.^2; % 查表获取实际效率 eta_actual = interp1(load_ratio, eta_curve, P_p2g / P_p2g_max, 'linear', 'extrap');interp1插值在 MATLAB 里是"效率分段处理"的最好工具。你可以把厂家提供的效率曲线描点做进去,也可以像我这样用多项式生成一条近似的连续曲线。注意插值边界要加'extrap',否则负载率超出范围时会报NaN。
3.2 电解槽与储氢罐约束建模
氢能系统的核心约束无非两类:电解槽的运行区间约束,以及储氢罐的容量/压力约束。
电解槽约束用数学表达就是:
P_p2g_min * bin_on <= P_p2g <= P_p2g_max * bin_onbin_on是 0/1 变量,表示启停状态。这一步在 MATLAB 里用intlinprog处理最合适,因为整数变量天然能表达"要么停机、要么在区间内运行"的逻辑。
储氢罐约束的关键是把压力变化和质量关联起来。理想气体状态方程给了我们一个桥梁:
% 储氢压力更新代码段 T = p.T_storage; % 温度 K R_spec = p.R_gas; % 气体常数 J/(kg·K) V = p.V_storage; % 容积 m3 % 累计产氢质量 m_H2_total P_tank = (m_H2_total * R_spec * T) / (V * p.M_H2 / 1000) / 1e6; % 单位 MPa注意这里我做了一个单位转换的隐蔽操作:M_H2是 g/mol,除以 1000 转成 kg/mol,气体常数乘以温度后除以摩尔质量再乘以质量,再除以容积,得到的是 Pa,所以又除以 1e6 转成 MPa。实际项目里最常见的 bug 就是单位搞混,算出来的储氢压力要么小得离谱要么大得爆炸。我在代码注释里专门标了级别:压力 MPa、温度 K、质量 kg、容积 m³,所有公式推完自己先手算一遍单位再跑程序。
3.3 月度调度优化:一个线性规划实战
做完能流计算后,我加了一层调度优化,用 MATLAB 内置的linprog求解。优化目标设为:在满足电网约束、储氢容量约束的前提下,最大化 P2G 系统一个月内的净收益。
目标函数拆解如下:
- 收益项:卖出氢气的收入
price_H2 * m_H2_sold - 成本项:P2G 消耗电力的成本(如果用的是富余电力,则成本按收购电价计)
- 收益项:如果考虑电网调峰帮助,还可以加上"避免弃风"获得的环境收益
写成矩阵形式:
% 优化目标:最大化收益,linprog默认求最小化,因此取负 % 决策变量 x(1:n) : 每小时P2G耗电量 MWh % 决策变量 x(n+1:2n) : 每小时产氢量 m3 % 决策变量 x(2n+1) : 月末售氢总量 kg n = 24 * 30; % 月度小时数 f = zeros(2*n + 1, 1); % 成本系数:耗电量产生成本 for k = 1:n f(k) = p.price_surplus; % 富余电价当作机会成本 end % 收益系数:售氢量(最后一维)为负值表示从总成本中扣除收益 f(2*n + 1) = -p.price_H2;这里的建模思路是把每个小时的耗电量作为独立决策变量,约束条件则包括:
% 约束矩阵 A*x <= b A = []; b = []; % 1) 每个小时耗电量不能超过P2G额定功率 A = [A; eye(n), zeros(n, n+1)]; b = [b; P_p2g_max * ones(n,1)]; % 2) 产氢量 = 耗电量 * 效率 / 低热值(等式约束用 Aeq) Aeq = [diag(-eta_elec/LHV_H2), eye(n), zeros(n,1)]; beq = zeros(n,1); % 3) 储氢罐累计容量不能超出上限(两项对应每个小时累计产氢-售氢) CumMatrix = tril(ones(n,n)); % 下三角矩阵用于累计求和 A = [A; zeros(n,n), CumMatrix, -ones(n,1)]; b = [b; p.V_storage * p.p_max / (p.R_gas * p.T_storage) * (p.M_H2/1000) * 1e6];这只是一个简化版但可跑的骨架。实际项目里我还会追加"电解槽最小运行时间"约束——氢能设备往往不允许频繁启停,这需要引入额外的整数变量并用intlinprog求解。跑优化时我建议先用小规模数据试一下约束矩阵的维度对不对,再切到全月 720 小时的大规模计算,不然报错会非常难排查。
3.4 可视化:把结果画明白
MATLAB 做数据分析有个杀手级优势,就是出图方便。我每次仿真完必出一张"三合一"图:风电出力与 P2G 输入功率的时序关系、储氢罐压力变化曲线、每小时收益累计曲线。这三条曲线放在一起,基本上就能直观判断调度策略是否合理。
figure('Color', 'w', 'Position', [100 100 1200 800]); subplot(3,1,1); bar(time, P_wind, 'FaceColor', [0.6 0.8 1]); hold on; bar(time, P_p2g, 'FaceColor', [0.9 0.6 0.2]); legend({'风电出力','P2G输入功率'}, 'Location', 'northeast'); xlabel('小时'); ylabel('功率 (MW)'); grid on; title('风电出力与P2G运行区间'); subplot(3,1,2); plot(time, P_tank_seq, 'LineWidth', 2, 'Color', [0.8 0.3 0.3]); xlabel('小时'); ylabel('储氢压力 (MPa)'); grid on; title('储氢罐压力变化'); subplot(3,1,3); plot(time, cumsum(P_p2g .* (p.price_H2 * eta_elec / LHV_H2) - P_p2g * p.price_surplus), ... 'LineWidth', 2, 'Color', [0.1 0.5 0.4]); xlabel('小时'); ylabel('累计收益 (元)'); grid on; title('系统累计净收益');出图有个经验:图例、单位、标题一个别少,不然一张图发出去别人看不懂。我在做数据汇报时深有体会——一张标注清晰的图,顶得上 1000 字的解释。
4. MATLAB实操中的常见坑与排查技巧
4.1 时序数据长度不一致的坑
做月度调度仿真时最容易的首个报错就是矩阵维度不匹配。我有一次用linprog跑优化,明明 720 个小时的变量设置好了,但约束矩阵的维度因为一个zeros函数少了一列,直接崩掉。
排查这类问题的技巧是:在关键节点插入维度检查代码。
assert(size(A, 2) == length(f), 'A矩阵列数不等于决策变量个数'); assert(length(b) == size(A, 1), 'b向量长度不等于A矩阵行数');这两行assert足以拦截大多数矩阵维度错误。别嫌麻烦,大型矩阵建模时维度错一位是家常便饭。我习惯每写完一个约束块就打印一下size(A),看行数列数是否按预期增长。
4.2 效率曲线线性化:精确与速度的选择
非线性效率曲线如果直接进入线性规划,求解器就瘫痪了。这里有个标准做法:分段线性近似。把效率曲线按负载率分成 5~10 段,每段用一个直线方程代替,然后引入 SOS2(Special Ordered Set of Type 2)约束来处理分段插值逻辑。
不过对大多数规划级项目,简单处理就够用:先按额定效率算总产氢量,再乘一个"综合效率修正系数"(比如 0.95)覆盖低效率区的偏差。我这个项目对比过两种做法的差异,结果误差在 3% 以内,对系统规划完全够用。除非你要做设备级详细设计,否则别让非线性效率拖垮整个求解速度。
4.3 求解器选择与收敛问题
MATLAB 优化工具箱里有linprog、intlinprog、fmincon、ga等可选。做 P2G 系统规划时我的选型经验是这样的:
- 纯连续变量线性目标:
linprog,速度最快; - 含有 0/1 启停变量:
intlinprog,能保证全局最优; - 含非线性效率但变量规模小:
fmincon; - 变量规模大且非凸:
ga遗传算法做兜底。
intlinprog我最常用,但它有个陷阱:当整数变量过多时求解时间会爆炸。如果你发现跑了 10 分钟还没出结果,先检查是不是把不必要的变量设成了整数。我试过把 720 个小时的 P2G 功率全部设为整数变量,结果求解器连续跑了 40 分钟还没收敛。后来改成只有启停标志为整数、功率为连续变量,一分钟内就出结果了。
4.4 版本兼容与常见环境问题
MATLAB 从 R2020a 到 R2024b 的语法差异不算大,但有几个坑需要留神。第一是linprog在旧版本中的算法选项名称不一样,新版本用'Algorithm', 'dual-simplex',旧版本可能只认'LargeScale'。第二是中文字符编码问题,脚本里如果有中文注释,在特定区域语言环境下的 MATLAB 里可能乱码,建议统一使用英文注释,或者把脚本保存为 UTF-8 编码。
另外提醒一句,如果你的电脑装了中文操作系统,MATLAB 安装路径里尽量不要出现中文目录,否则某些工具箱加载时会莫名报错。这是老生常谈,但我身边真的有人因此卡了一整天,最后发现只是路径里有"软件"两个字。
5. 从单日仿真到年度规划:提升模型实用性的建议
5.1 步长选择:1小时还是15分钟
P2G 仿真最常见的时间步长是 1 小时,因为电能量计量和现货市场出清多数按小时结算。但如果你想研究电解槽的启停特性对设备寿命的影响,1 小时步长就太粗糙了,需要细化到 15 分钟甚至分钟级。
步长对计算量的影响是指数级的:从 24 小时扩大到 720 小时,计算量增加 30 倍;从 1 小时步长改成 15 分钟步长,计算量再增加 4 倍。我建议的做法是:先在 1 小时步长下把模型调通,确定最优调度方案的整体形状,再在关键时段用插值细化到 15 分钟做局部验证。
5.2 灵敏度分析:哪些参数最影响结论
仿真做多了就会发现,与其花大力气调一个参数的精确值,不如先搞清楚哪些参数对结果影响最大。我在项目里用 MATLAB 的for循环做了一遍参数扫描,结论很清晰:
| 参数 | 变化范围 | 对月收益影响幅度 | 敏感性等级 |
|---|---|---|---|
| 电解槽效率 | 0.60~0.75 | ±40% | 高 |
| 氢气售价 | 25~45 元/kg | ±60% | 极高 |
| 富余电力价格 | 40~120 元/MWh | ±25% | 中 |
| 储氢罐容量 | 1000~3000 m³ | ±10% | 低 |
从这个结果能得出两个实用结论:氢气售价是经济性的第一杠杆,签一个长协供氢合同比优化调度带来的收益提升大得多;储氢罐容量到一定程度后边际收益递减,没必要盲目扩容。做敏感性分析时记得用tiledlayout出一张多子图,把不同参数下的净收益曲线叠在一起看,比盯一个数字直观得多。
5.3 和电力系统规划工具衔接
很多读者做 P2G 仿真不是单纯写论文,而是要和更成熟的电力系统仿真工具对接。MATLAB/Simulink 本身就能做电气部分的动态仿真,加上 Simscape Electrical 之后能模拟电解槽与电网接口的暂态响应。你还可以用 MATLAB 写一个通用的结果导出函数,把 P2G 调度结果输出成 CSV,直接喂给其他生产模拟软件做联合计算。
% 导出P2G调度结果为标准CSV,方便其他工具读取 T_out = table(time', P_p2g', m_H2', P_tank_seq', ... 'VariableNames', {'Hour', 'P2G_MW', 'H2_kg', 'Tank_MPa'}); writetable(T_out, 'p2g_dispatch_result.csv');这个writetable函数兼容性很好,导出的 CSV 用 Excel 和 Python pandas 都能直接读。工程协作中,"能不能把结果顺利交给下游"往往比"模型精度高 0.5%"重要得多。
6. 程序调试、验证与结果可信度把控
6.1 怎么验证仿真结果不是胡算
做仿真的人最怕的是:程序跑通了,但结果不敢信。这里我有一套固定的验证流程,每做一个 P2G 项目都会走一遍:
- 能量守恒校验:输入电量必须等于产氢化学能、系统损失和储存变化之和,误差超过 1% 就说明程序有 bug;
- 边界情况测试:把所有输入参数设成极值,比如风电为零、负荷为零、P2G 满功率,看输出是否在合理范围;
- 对照手算实例:取一个特定小时,手算出产氢量,和程序结果比对。
% 能量守恒校验:输入电能 ≈ 产氢能量 + 损耗 Q_in = sum(P_p2g) * 1e3; % MWh → kWh Q_h2 = sum(m_H2) * LHV_H2; % kg → kWh Q_loss = Q_in * (1 - eta_elec); % 电解热损耗 tolerance = 1e-6; assert(abs(Q_in - Q_h2 - Q_loss) / Q_in < tolerance, '能量不守恒,存在计算错误');这短短几行assert能防住至少一半程序错误。实测中我发现很多人能量守恒不通过,根源是产氢量计算时忘记乘以效率,或者把效率用在了两个不同的地方。出现这种情况不要急着去优化目标函数,先把能量账算平再说。
6.2 场景的典型日曲线怎么构造
时序数据的质量决定仿真结果的可靠度。项目里如果没有现成的实测数据,我推荐用下面的方法在 MATLAB 里合成"合理"的风电出力曲线:
% 基于典型特性生成的合成风电出力 rng(42); % 固定随机种子,保证结果可复现 n = 720; % 30天小时数 P_wind = zeros(n,1); P_wind = max(0, 0.3 + 0.5 * sin((1:n)'/48 * 2 * pi) + 0.2 * randn(n,1)); P_wind = min(P_wind, 1); % 归一化到[0,1] P_wind_seq = P_wind * P_wind_max; % 转换为实际功率 figure; plot((1:n)/24, P_wind_seq); xlabel('天'); ylabel('功率 (MW)'); grid on; title('合成风电出力时序曲线(30天)');这里的关键点是rng(42)固定了随机数种子,这样每次跑出来的曲线完全一致,方便复盘和对比实验。我见过有人忘了设随机种子,跑两次结果不同,然后花了两天时间查"程序不稳定",最后发现只是随机数没固定——这种低级冤枉路咱们就不必走了。
6.3 从代码到报告:结果解释的几个原则
仿真做完之后,解释结果其实是最体现功力的环节。我自己总结出三条原则:
- 看趋势、不看单点:某天的净收益波动大没关系,真正重要的是月累计收益的整体走势;
- 对比基准场景:一定要设一个"无 P2G"的基准场景,不然读者不知道你的调度策略价值在哪里;
- 主动披露假设:把效率、价格、容量等关键假设放在报告附录里,既保护自己也方便别人复现。
我做月度仿真时还会额外输出一张"运行小时数统计表",统计 P2G 设备在多少个小时内处于满载、部分负载、停机状态。这张表能直观反映设备利用率,对设备选型很有参考价值——如果设备大部分时间在空转,说明容量配置偏大,应该考虑缩小 P2G 功率或者增加储氢能力。
7. 一些MATLAB编程上的个人心得
电转气项目的 MATLAB 程序设计,本质上是把"能源系统思维"翻译成"计算代码思维"。我做这个项目最大的体会是:不要一开始就追求算法高深,先把能流逻辑用最直白的方式跑通,再一层层叠加优化和约束。很多人第一次写 P2G 程序就试图搞非线性模型预测控制,结果连基础数据都校验不过关,那样反而走不远。
几个还算实用的编码习惯分享给大家:
- 每个脚本开头都写上"这个文件是干什么的、输入是什么、输出是什么",三个月后再看代码不靠记忆全靠注释;
- 中间计算量大的循环尽量写成向量化代码,P2G 月度仿真的 720 小时循环在 MATLAB 里其实很快,但如果扩展到 8760 小时,向量化就变得至关重要;
- 程序每个阶段的关键结果用
disp打印出来,别一股脑输出几千行,人眼根本看不过来。
如果将来要把模型做深,可以考虑往两个方向扩展:一是把 Simulink 和 Simscape 加进来,实现电解槽与电网接口的电磁暂态仿真;二是引入强化学习或模型预测控制做日内实时调度,取代传统的"离线优化+人工调度"模式。这两个方向都有成熟的 MATLAB 工具箱支持,项目基础打得好的话,扩展起来并不难。
最后说一句大实话:仿真建模这个领域,真正的门槛从来不是工具操作,而是对物理过程的理解和建模思路的清晰。MATLAB 只是一个趁手的工具,帮我们把脑中的系统逻辑变成可以反复试验的计算实验平台。希望这篇文章能帮你把一个"电转气"项目从想法落到代码,再让代码替你说话。