ARTICLE DETAIL

资讯详情

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

综合能源系统多能耦合能流计算的Matlab实现与解析

综合能源系统多能耦合能流计算的Matlab实现与解析 综合能源系统的潮流计算这几年确实是热得发烫的方向。尤其是“电-气-热”三类异质能源耦合在一起之后传统的单一电力潮流计算工具根本扛不住必须得有一套能同时描述电能、天然气和热能传输与转换的数学模型和求解算法。我最初接触这个课题是因为手里有个园区级的综合能源规划项目甲方问了一嘴“你们算电的潮流软件能把天然气管网和供热管道一起算了吗”当时就意识到这活儿市面上真没有现成工具必须自己动手在Matlab里搭一套。这套代码的核心价值在于它不是简单地把电力潮流、天然气水力计算、热力水力计算三个程序拼在一起而是真正从“多能耦合”的角度出发把CHP机组、电锅炉、燃气锅炉、压缩机这些耦合设备的输入输出关系作为连接三个能源网络的边界条件建立一个统一求解的联立方程组。整个过程我前前后后迭代了三个版本从最初的顺序求解法到现在的统一求解法踩了不少坑也积累了一些心得。这篇就从头到尾复盘一下这个“计及多能耦合的区域综合能源系统电气热能流计算”Matlab实现是怎么一步步做出来的重点讲清楚背后的数学原理、代码架构和那些文档里不会写的细节。1. 项目整体思路与模型设计拆解1.1 为什么要做“多能耦合”的统一能流计算先说说这个题目里最关键的一个词“多能耦合”。很多人第一次接触综合能源系统容易把它理解成“三个网分别算算完再拼起来”。但实际工程里电网、气网、热网根本不是独立运作的。举个最简单的例子一台热电联产机组CHP它烧天然气发电同时回收余热供给热网。这时候气网里的天然气流量、电网里的有功出力、热网里的供热功率三个物理量被这一台设备“绑”在了一起。如果你只把CHP当成电网里的一个PQ节点或者PV节点来处理那你根本没有考虑天然气供应不足导致CHP出力受限的情况反过来说如果你只算气网又没法精确知道CHP在不同电负荷水平下到底要烧多少气。所以必须把三个网络放在同一个框架里联立求解。再比如电锅炉它在电网里是一个负荷在热网里是一个热源。电网侧的功率波动会直接影响热网侧的供水温度热网侧的热负荷需求又会反过来决定电锅炉从电网抽多少电。这种“双向耦合”的特性决定了传统的“先电后热”或者“先热后电”的分步算法在强耦合场景下很容易发散或者精度不足。1.2 三种能源网络的数学模型框架在搭模型之前一定要把三个网络各自的物理方程理清楚。我用的这套代码里三类网络的建模方式如下电力网络采用经典的交流潮流模型。节点分为PQ节点、PV节点和平衡节点Slack。核心方程是节点有功和无功功率平衡方程即每个节点注入的有功功率等于与该节点相连的所有支路潮流之和。为了兼容后续的统一求解我用了极坐标形式的牛顿-拉夫逊法自变量是节点电压幅值V和相角θ。天然气网络稳态天然气网络的核心是节点流量平衡方程。每个节点的天然气注入流量气源供气、负荷用气要等于所有相连管道流量的代数和。管道流量用经典的Weymouth方程描述它把管道流量与管道两端压力平方差建立关系。在这个模型里节点压力和管道流量是核心未知量。热力网络热力系统我采用的是“质量流量-温度”两阶段模型。水力计算部分根据热负荷需求确定各管道的质量流量一般假设流量已知或者按比例分配热力计算部分求解节点供回水温度。供热管道有温度损耗通常用苏霍夫温降方程描述回水网络则通过节点混合温度方程来建立联系。三种网络单独看都不算复杂复杂的是它们之间的耦合关系。在代码实现里如果只做单网络的潮流计算而不考虑耦合本质上就是把三个“独立的计算器”合到一起但一旦引入耦合设备问题性质就变了。1.3 耦合设备的建模与边界条件处理耦合设备是整个系统中最关键、也最容易出问题的地方。我在这套代码里处理了三种最常见的耦合设备热电联产机组CHP这是电-气-热三网耦合的“枢纽”。它的建模分两部分——发电子系统燃气轮机或内燃机和余热回收子系统。在电网上CHP是一个PV节点通常给定有功出力和机端电压在气网上CHP是一个天然气负荷节点在热网上CHP是一个热源节点。三者之间的关系通过热电比heat-to-power ratio和发电效率来关联。我的代码里采用了变热电比的模型即发热功率 发电功率 × 热电比系数天然气消耗量 发电功率 / 发电效率 × 天然气热值换算系数。燃气锅炉相对简单它是气网负荷和热网热源的“二网耦合”设备。天然气耗量与产热量通过锅炉效率建立关系。电锅炉这是电网负荷和热网热源的“电网-热网”耦合设备。电功率输入与热功率输出之间通过电热转换效率通常接近0.95-0.99关联。它的好处是模型线性很好处理但在高压大容量场景下电锅炉的功率调节速度可能会限制整个系统的响应能力。处理耦合设备的边界条件时我踩过一个比较大的坑如果简单地把CHP的发电功率设为定值就会丢失电气负荷与热负荷之间的耦合关系。实际运行中CHP通常是“以热定电”或者“以电定热”模式。在“以热定电”模式下热负荷决定CHP的产热量进而决定发电量在“以电定热”模式下则反过来。所以代码里我把CHP的控制模式作为一个可配置的参数每次迭代时根据当前热网的热负荷水平和电网友的功率偏差动态更新CHP的出力设定值。1.4 顺序求解与统一求解的选择为什么我最终选了两者结合网上的资料讨论“顺序求解法”和“统一求解法”的文章很多但实际做的时候你会发现纯粹的单向顺序求解在强耦合场景下很难收敛。我第一版代码用的是严格的顺序求解先算电网再把CHP出力传给气网和热网算完气网和热网再把新的天然气耗量带回电网。结果在耦合度较高的情况下迭代次数急剧增加甚至出现震荡发散。后来我改成了“区块统一迭代法”将三个网络的雅可比矩阵块组装成一个大的稀疏矩阵联立求解。核心思想是电网潮流方程、气网节点流量方程、热网节点温度方程再加上耦合设备的输入输出约束方程全部写成一个统一的不等式组F(x) 0然后用牛顿-拉夫逊法联立迭代。这里的x是包含了所有网络未知量的大向量节点电压幅值、相角、气网节点压力、热网节点供回水温度以及耦合设备的出力变量。不过说实话统一求解法对代码结构和初值设置的要求更高雅可比矩阵的组装最容易出错。我在代码里写了一个“自动分块”的逻辑——把电网、气网、热网的雅可比矩阵分别形成然后按照耦合设备的关联节点索引把耦合子矩阵填充到对应位置。这样做的可读性和可维护性远好于把所有公式揉在一起写。2. 电气热能流计算的数学模型解析2.1 电力系统潮流方程的极坐标形式与修正方程电力系统的潮流计算是整个模型的基础因为三个网络中电网的方程是非线性最强的。我用的是经典的牛顿-拉夫逊极坐标形式。对于节点i有功和无功功率平衡方程为P_i V_i × Σ(V_j × (G_ij × cosθ_ij B_ij × sinθ_ij))Q_i V_i × Σ(V_j × (G_ij × sinθ_ij - B_ij × cosθ_ij))其中V_i是节点电压幅值θ_ij是节点i和j的电压相角差G_ij和B_ij是节点导纳矩阵的实部和虚部。这里的P_i和Q_i是节点注入功率对于负荷节点取负值。在牛顿-拉夫逊迭代中需要形成雅可比矩阵J它由四个子块组成∂P/∂θ、∂P/∂V、∂Q/∂θ、∂Q/∂V。初学的时候容易在这些偏导数的推导上卡壳我建议不要手工推导——直接在代码里用“数值微分”替代或者对照教科书公式逐项写。为了求解效率我还是用了解析表达式这个后面在代码实现部分会细说。2.2 天然气网络的Weymouth方程与压缩机模型天然气网络的节点流量方程比电网方程要简单一些但因为Weymouth方程的非线性处理起来也有讲究。管道流量方程Weymouth方程为f_km C_km × s_km × sqrt(s_km × (p_k² - p_m²))其中C_km是管道常数取决于管径、长度、气体组分、温度等s_km是流向符号函数1表示从k流向m-1则相反。这里有个关键细节Weymouth方程里用的是压力的平方差不是压差。所以变量替换时直接把节点压力平方作为未知量是个好选择能显著降低方程的非线性程度。在这套代码里我就是用p²作为状态变量的。如果有压缩机还需要在压缩机所在支路增加一个约束方程通常给定压缩机的增压比或者出口压力再根据压缩机消耗的天然气量如果是燃气驱动压缩机修正节点流量平衡。如果只是电动压缩机它的耗电量还要作为一个电负荷并入电网节点这个细节比较容易漏但对结果影响不小。2.3 热力网络的“水-热”耦合方程与温度损耗建模热力网络的方程是我觉得三个网络里最“绕”的因为它分两层水力工况和热力工况而且两者之间通过质量流量来耦合。水力部分假设管道质量流量已知主要约束是各节点的流量连续性方程流入节点的质量流量等于流出节点的质量流量。实际中供热系统的质量流量通常由循环泵决定所以我在代码里简化处理直接给定各管道的质量流量并且认为全网流量分配比例已知。这样处理在规划分析阶段是可以接受的但在运行优化阶段就需要加入更精细的水力计算了。热力部分核心是节点温度方程热源节点供水温度由热源决定给定值或由热源出力计算回水温度由各负荷节点的回水混合决定。负荷节点供水温度等于上游管道经温降后的温度回水温度给定负荷特性决定。管道温降采用苏霍夫公式T_end T_env (T_start - T_env) × exp(-λ × L / (m × c_p))其中λ是管道热损系数L是管长m是质量流量c_p是水的比热容。热力节点还有一个“混合温度”的概念如果一个节点有多个支路汇入那这个节点的温度是所有汇入支路流量的加权平均温度。这个方程也要写进统一迭代的方程组里否则温度对不上。2.4 耦合设备方程与变量归一化处理上面三类网络方程加起来已经不少了再加上耦合设备方程整个方程组的维数会快速增长。为了减小数值问题我在代码里对变量做了归一化处理。具体做法是电网变量用标幺值p.u.气网变量用MPa作为基准压力热网变量用摄氏度加上一个偏移量。这样做的原因很直接——如果不归一化雅可比矩阵里电压幅值的量级是1左右、压力平方的量级可能到几百、温度的量级是几十到几百数值差异太大容易导致矩阵病态迭代收敛会变得很困难。举个例子假设系统里有30个电网节点、10个气网节点、15个热网节点耦合设备有2台CHP、1台电锅炉、1台燃气锅炉。那么整个联立方程组的未知量维度大概是多少计算一下电网节点中除平衡节点外每个节点有2个未知量V和θ平衡节点只有1个V气网每个节点1个未知量p²热网每个节点有2个未知量供水温度和回水温度每台耦合设备在“以热定电”模式下有1个额外的待求变量——CHP发电量或电锅炉功率。所以总维度可能在100-150左右。这个规模对Matlab来说非常小即使不用稀疏矩阵牛顿-拉夫逊法的求解时间也基本在1秒以内。关键问题不在于规模而在于初值给得不好时迭代能否收敛。3. Matlab代码实现与核心模块详解3.1 程序整体架构与数据流设计我写代码有一个习惯先把数据流画清楚再动手写函数。这套综合能源能流计算的程序我把它分成了五个核心模块数据输入模块input_data.m读取电网、气网、热网的拓扑参数、负荷数据、设备参数。我建议把所有数据放在一个结构体数组里方便后续索引。雅可比矩阵组装模块assemble_jacobian.m根据当前的状态变量值计算整个联立方程组的雅可比矩阵。这是最核心、也最容易出bug的地方。方程残差计算模块compute_residual.m给定一组状态变量计算所有方程左端的残差向量F(x)。牛顿-拉夫逊迭代主程序nr_solver.m负责迭代控制、收敛判据、结果输出。结果可视化与后处理模块plot_results.m输出各节点电压、压力、温度分布以及耦合设备运行工况。上面五个模块核心思想就是把“方程组构建”和“数值求解”分离。不管你的系统拓扑怎么变只要改数据输入模块和雅可比矩阵组装模块中对应的拓扑索引主求解器不需要改动。这五个模块的关系简单说就是主程序调用compute_residual和assemble_jacobian形成残差向量和雅可比矩阵然后解线性方程组得到修正量更新状态变量检查收敛循环。3.2 初值设置与收敛判据最容易踩坑的环节在这一节必须给新手提个醒综合能源能流计算的收敛性很大程度上取决于初值给得怎么样。我刚写完第一版代码时迭代经常发散一度以为是方程写错了。后来排查发现问题出在气网和热网的初值上。电网初值通常好给电压幅值取1.0相角取0这是标准的“平启动”。气网的节点压力初值可以取整个网络统一的基准压力比如2MPa压缩机出口可以适当提高一点。但热网初值必须小心——供水温度初值不能随便给因为温降方程对温度非常敏感。我建议把热源供水温度初值设为设计值比如90°C回水温度初值设为经验值比如50°C其他节点的温度初值按距离热源的远近线性插值这样能大幅提高初始收敛性。收敛判据我采用的是混合判据既要看残差向量的2-范数是否小于阈值也要看状态变量的修正量是否足够小。两个条件同时满足才算收敛。阈值我习惯设两个档位快速校核用1e-4精确计算用1e-8。很多论文里只写了残差判据但实际调试时会发现如果只看修正量会漏掉一些缓慢收敛的场景。所以两个判据同时用会更稳。3.3 统一雅可比矩阵的分块组装方法这是整个代码中技术含量最高的部分我详细说一下思路。假设系统总共有n个待求变量那么雅可比矩阵是n×n的。如果按网络的物理结构分块可以写成如下形式| J_EE J_EG J_EH || J_GE J_GG J_GH || J_HE J_HG J_HH |其中J_EE是电网对电网变量的偏导数J_EG是电网方程对气网变量的偏导数表示气网变量影响电网方程的程度以此类推。注意对于没有直接物理连接的网络对应分块是零矩阵。比如电网方程中热网节点的温度变量一般不直接出现在电网方程里所以J_EH大部分是零除非有电锅炉——电锅炉的耗电功率是热网变量的函数。同理气网方程中电网变量一般也不直接出现除非有燃气压缩机。这个“稀疏性”一定要充分利用因为在Matlab中如果直接构造稠密矩阵100多个变量的矩阵也就几百KB倒是无所谓但如果你要扩展到大系统用稀疏矩阵不仅可以省内存还能大幅提速。具体的组装方法是先把三个网络的内部雅可比矩阵分别算出来就是我们常规潮流计算中的那个雅可比矩阵然后按照状态变量的全局编号把矩阵元素填充到总矩阵的对应位置。跨网络的分块矩阵则通过耦合设备的方程来求偏导数。这一步我建议用matlabFunction或者手写解析表达式不要用数值微分——数值微分在耦合点处精度不够容易导致牛顿法收敛速度变慢。3.4 核心迭代代码与关键参数配置下面是一段简化后的牛顿-拉夫逊迭代代码框架展示的是统一求解法的核心逻辑。真实代码要比这长不少但骨架就是这样的。% 主迭代循环 x x_init; % 初始状态变量 res compute_residual(x, data); % 残差 J assemble_jacobian(x, data); % 雅可比矩阵 iter 0; tol 1e-6; max_iter 50; while norm(res, inf) tol iter max_iter % 求解线性方程组 dx -J \ res; % 更新变量这里可以做阻尼修正防止越界 alpha 1.0; x_new x alpha * dx; % 检查变量是否越界压力不能为负、温度不能在合理范围外等 x_new check_bounds(x_new, data); % 重新计算残差和雅可比矩阵 res compute_residual(x_new, data); J assemble_jacobian(x_new, data); % 如果残差变大做步长缩减 if norm(res, inf) norm(res_old, inf) alpha alpha * 0.5; % 重新迭代... end x x_new; iter iter 1; end这里有几个关键的配置参数我根据实测经验给个参考范围收敛容差tol我常用1e-6到1e-8之间。1e-6基本够工程应用1e-8适合研究对比。最大迭代次数max_iter一般30-50次足够。如果超过50次还没收敛基本可以判定模型初值有问题或者系统本身在当前工况下没有解。阻尼步长alpha这个参数极其重要。牛顿-拉夫逊法在靠近解附近收敛很快但远离解时容易震荡。我在代码里加了自适应阻尼如果当前步导致残差增大就把步长缩短一半。这个技巧在气网压力初值给得不好的时候特别有用。阻尼的复杂度远不止这么简单。热网温度变量也有边界约束——温度不能低于环境温度否则违背热力学第二定律。如果不加边界检查迭代过程中温度变量可能跑到离谱的值导致管道温降方程里的exp函数溢出。所以我写了一个check_bounds函数用投影法强制变量落在物理可行域内。这个函数虽然简单但效果立竿见影大大减少了发散情况。在初值设置环节热网供水温度就用设计值上下浮动回水温度按经验比例给定不要从0开始。3.5 计算结果的数据格式与可视化输出计算完成后数据怎么组织是个“软件工程”问题但对使用体验影响很大。我是这样设计的% 结果结构体 result.电网节点电压幅值 V_mag; % 向量 result.电网节点相角 theta; % 向量度 result.气网节点压力 P_gas; % 向量MPa result.热网节点供水温度 T_supply; % 向量°C result.热网节点回水温度 T_return; % 向量°C result.CHP机组 chp_result; % 结构体电出力、热出力、气耗量等 result.电锅炉 eb_result; % 结构体电功率、热功率 result.迭代次数 iter; % 标量 result.收敛标志 converged; % 布尔量输出到Matlab工作区之后我一般会画四张图第一张是电网电压幅值分布第二张是热网管道沿程温度分布第三张是气网节点压力分布第四张是各能源站耦合设备的能流Sankey图。第四张图对做汇报特别有用能一眼看出能量从气网到电网再到热网的转换路径和损耗量。可视化这块我用了Matlab自带的plot和bar函数没有上第三方库。如果想让图更专业也可以用Sankey图的第三方工具包但自带的足够完成大部分工作。需要提醒的是可视化模块要和计算模块分开这样计算部分在无界面环境下也能正常工作比如用matlab -batch或者打包成独立程序。我最初把图和计算放在同一个脚本里后来被各种图形窗口卡得体验很差拆开之后清爽很多。4. 仿真算例验证与多能流结果分析4.1 算例系统构建与参数设定为了验证代码的正确性我参考了几个公开发表的论文算例自己搭建了一个小型区域综合能源系统。系统的规模是6节点电力网络、4节点天然气网络、6节点热力网络包含一台CHP机组、一台燃气锅炉、一台电锅炉。电力系统的基准容量取100MVA电压等级简化处理天然气网络的基准压力我取2.0MPa热力网络的质量流量根据热负荷需求计算供水温度设计为90°C回水温度设计为50°C。CHP机组参数为额定电功率5MW热电比1.2发电效率42%。电锅炉额定电功率3MW电热转换效率97%。燃气锅炉额定热功率10MW热效率90%。在数据输入时有个细节需要注意热负荷的单位是MW热功率折算成质量流量时要除以供水温度-回水温度和水的比热容。这个换算经常出错建议单独写个小函数专门处理我早先几次算出来的热网流量偏大后来排查发现是单位换算系数少除了一个1000。4.2 典型工况下的能流分布结果以冬季典型工况为例电网总电负荷约为12MW热网总热负荷约为9MW气网总气负荷由CHP和燃气锅炉分摊。在这个工况下CHP机组按“以热定电”模式运行热负荷9MW中CHP承担约5.4MW热出力对应4.5MW电出力燃气锅炉承担剩余3.6MW热出力电锅炉作为备用热源不出力或者低负荷运行。计算结果有几个值得注意的点电网方面由于CHP在当地发电4.5MW外电网的购电量显著减少从原本的12MW降到了约8MW左右扣除损耗。CHP的接入使附近节点的电压幅值略微升高。这个场景说明CHP对配电网的电压支撑作用。气网方面CHP的天然气消耗加上燃气锅炉的消耗使气源节点到末端节点的压力差明显增大。如果不考虑气网约束按最大出力设计的CHP在实际运行中可能因为气网末端压力过低而无法满发。这就是为什么必须做综合能流计算——单一电网潮流算出来是可行的但配上气网约束后可能不可行。热网方面热源供水温度从CHP出口的90°C经过管道传输后末端负荷节点供水温度降到约75°C取决于管道长度和保温效果。回水温度混合后在热源处大约53°C符合预期。这三种结果叠加在一起才能全面回答系统运行是否可行这个问题。4.3 多能流结果对系统运行策略的指导意义算完能流之后不能只停留在“看看数对不对”还要能把结果用起来。我从这套代码的实际工程反馈中总结了几个应用方向第一判断CHP机组的“以热定电”能力是否匹配电网消纳条件。如果热负荷大而电负荷小CHP满发热出力时电出力可能超过本地消纳能力此时要么增加电锅炉蓄热要么压低CHP出力这些都需要能流计算来量化。第二评估气网瓶颈对电力系统运行的影响。气网末端压力如果偏低会导致CHP进气压力不够发电效率下降甚至无法启动。通过能流计算可以在规划阶段就发现气网瓶颈提前增压或扩容。第三热网的供水温度调节会影响电锅炉的耗电量进而影响电网侧潮流。如果热网供水温度提高供热管道温差增大相同热负荷下所需质量流量减小循环泵耗电降低。但同时热损增加热源出力可能要加大。这种权衡关系真的要算一遍能流才看得清楚。在上述算例中如果热网供水温度从90°C降到85°C热负荷不变的情况下质量流量要增加约12%循环泵耗电增加但热网热损减少一些。算下来系统总能耗其实有所上升——这说明运行策略不能靠“拍脑袋”需要有能流计算工具做量化比选。4.4 不同工况对比测试耦合强度对收敛性的影响为了验证代码的鲁棒性我做了一组对比测试在同一拓扑结构下逐渐增大CHP的容量占比即耦合强度观察迭代次数和收敛性的变化。测试结果让我对“顺序求解法”和“统一求解法”的认知更深刻了当CHP容量占比小于20%时顺序求解法和统一求解法都能收敛迭代次数差不多但当CHP容量占比超过40%后顺序求解法开始出现震荡需要人为增加阻尼才能勉强收敛而统一求解法依然保持稳定的二次收敛特性。这说明耦合强度越高跨网络的变量关联越强统一建模的优势越明显。这个特点在写论文时可以作为一个很好的“卖点”来强调用对比数据说话比空喊“统一求解法更好”有说服力得多。5. 常见问题与调试实录5.1 迭代不收敛的三大原因与排查手段我调试这套程序时遇到的不收敛情况绝大多数可以归为三类如果你卡住了按顺序排查大概率能找到问题。第一类是初值超出物理可行域。表现是迭代两三步之后残差突然暴涨变量值跑到离谱的范围。解决方法是做变量边界检查同时给迭代过程加阻尼。我会在调试模式下把每步迭代的状态变量打印出来看是哪个变量先越界的——通常是气道压力变成负值导致的。第二类是雅可比矩阵奇异或接近奇异。表现是解线性方程组时出现警告矩阵接近奇异或者亏秩。这种情况通常是某个耦合设备方程重复或者遗漏导致矩阵行与行之间线性相关。排查方法是检查数据里的耦合设备节点编号是否与网络拓扑一致。我在代码里加了一个雅可比矩阵的稀疏结构可视化函数每次组装后看一眼矩阵的非零分布能快速定位问题行。第三类是系统在实际物理上就没有可行解。比如气源供气压力定死了但末端用气量远大于管道输送能力这时方程组本身无解怎么迭代都不收敛。这种情况就要回头检查参数了不能指望数值方法变出解来。算例中我就遇到过气网负荷翻倍后管道流量达到上限压力平方差出现负数导致Weymouth方程里sqrt函数返回NaN。代码能不能正确“报错”也很重要我在compute_residual里加了复数检测——一旦出现NaN或复数直接返回一个错误标志避免带病迭代。5.2 热网方程常见数值问题与处理技巧热网的温度方程里指数温降公式非常容易出数值问题。一个典型场景当质量流量很小时exp(-λL/(mc_p))的指数部分绝对值很大容易导致温度计算溢出。虽然物理上“小流量大热损”是合理的但数值上很难看。我的处理技巧是当指数小于-20时直接认为管道末端温度等于环境温度避免exp函数溢出。这个近似在物理上是合理的——流量足够小的时候热媒在管道里基本冷却到环境温度了再精确计算意义不大。但这个细节要是没处理好往往导致某次特定工况下代码跑挂排查半天都找不出原因。另外一个比较隐蔽的问题是热网节点的温度混合。当多个支路汇入同一节点时如果某个支路的质量流量是负值表示流体方向是流出节点混合温度方程里的加权系数就可能是负的。这时候必须严格按照“流入为正、流出为负”的约定来组装方程否则物理意义就错了。我在代码里通过支路质量流量的正负号自动判断方向并把出流支路从混合温度方程中剔除——否则会产生“逆流混温”的荒谬结果。5.3 参数灵敏度分析哪些参数最影响最终结果做工程研究不能只知道“能算”还要知道“哪些参数不能拍脑袋”。我基于这套代码做了做了简单的灵敏度分析结论比较清晰天然气网络的管道常数C_km对整体结果影响很大。这个值取决于管径、管长、摩擦系数、气体组分和温度一旦偏差20%末端气压可能偏差百分之十几足以影响CHP能否满发。所以气网参数不能用估算值糊弄。热网管道热损系数λ影响也比较大但这个参数在工程上相对好获取偏差10%对节点温度影响不算致命。CHP的热电比参数是不同厂家设备差异最大的地方而且随着负荷率变化热电比也不是恒定的。如果代码里把它设成常数在低负荷工况下的误差会很明显。我后来把热电比改成了随负荷率线性修正的函数形式效果好了不少。电网里的线路参数在潮流计算中已经属于“常规参数”误差影响相对小。但这并不是说电网参数不重要只是相比气网和热网数据可靠性高一些。综合能源系统的数据获取难度排序大概是电网 热网 气网。气网的可获取性最差所以对气网参数的敏感性分析一定要多做几步。5.4 加速计算的一些实践心得虽然本文算例规模不大但做优化或者蒙特卡洛分析时可能要把能流计算跑几千上万次这时候性能就重要了。我总结三个最有效的加速手段一是向量化计算。尽量避免在Matlab里写for循环来组装雅可比矩阵尤其是电网部分的雅可比矩阵。用矩阵运算一次生成整个雅可比矩阵比循环赋值快几倍。但气网和热网的拓扑比较小手写循环问题不大。更好的做法是预先计算好节点支路关联矩阵然后用矩阵乘法生成雅可比矩阵。二是复用LU分解。在牛顿-拉夫逊迭代中每次都要解同一个矩阵的线性方程组只是矩阵元素在变化。如果变化不大可以尝试对雅可比矩阵做一次LU分解然后在迭代中更新部分元素。不过这个技巧对收敛性有影响我在代码里默认还是每次重新分解只有在做批量场景计算时才用增量更新。三是把主迭代函数写成单独的function避免在脚本环境下逐行解释执行。这样看起来是“小工程”优化但实际提速可以达到30%以上很大了。如果要做更大规模的全系统优化建议把核心计算函数用Matlab Coder转成C或者MEX文件但这是后话了。工程上先在Matlab里把物理模型和算法验证清楚性能问题永远比正确性问题好解决。6. 从这套代码向外看扩展方向与实用建议6.1 松弛求解与Levenberg-Marquardt阻尼的引入刚才说的迭代不收敛有一个比较普适的改进手段我这里单独提一下——引入Levenberg-Marquardt阻尼项。具体做法是在每次迭代求解线性方程组时把雅可比矩阵对角线加一个小常数λdx -(JJ λI) \ (Jres)这样做的好处是即使J是奇异的也总能走向一个残差下降的方向。代价是损失了牛顿法的二次收敛速度只在迭代前期使用后期再切换到标准牛顿法。我在代码里加了自动切换逻辑连续两次迭代残差下降率小于某个阈值时λ自动减小。这个技巧在处理病态系统的初值时特别好用。不过引入阻尼也有代价——参数λ需要调试选得太大收敛会变慢选得太小又起不到稳定作用。我的经验是从λ1e-4开始以10倍为步长逐渐尝试。6.2 动态仿真与优化调度的扩展接口这套稳态能流计算的框架在扩展方向上是开放的。我目前在这套代码基础上接了三个扩展一是时间序列计算把一天24小时的电、气、热负荷曲线输入逐时段做能流计算就能得到系统全天的运行状态变化可以用于评估储能设备的“削峰填谷”效果。二是动态过程简化仿真在稳态计算的基础上把热网管道温降方程中的时间项加进去可以做热网的动态响应分析用于研究热惯性对系统调峰能力的影响。这一块比较偏学术但很有价值。三是与优化算法对接把能流计算嵌入到粒子群或者遗传算法框架里作为内层约束校验可以做“计及能流可行性的容量配置优化”。我实测过把能流计算模块封装成fitness函数后嵌入优化算法调用很方便收敛性也很好。6.3 模型扩展加入储能、新能源与多能市场因素当前代码还没有包含储能装置的动态模型。如果要扩展可以在热网侧加蓄热罐模型在电网侧加电池储能模型甚至在气网侧加储气库模型。储能单元的模型本质上是一个带“状态变量”的时变边界条件蓄热罐的当前储热量影响其最大可充放功率这个在时间序列计算中必须要加。另一个值得扩展的方向是可再生能源接入。光伏和风电在电网里是PQ或者PV节点但它们的不确定性会影响整个多能流系统的运行。可以把光伏出力的概率分布引入能流计算做成“概率多能流”。这个方向这几年发论文很热门。如果想要加入市场因素那还要把能源价格、碳排放约束、需求响应等作为边界条件建模这样的话能流计算就变成了“多能市场均衡”的计算。这个方向比较复杂但也是综合能源系统从理论走向实际运营的必经之路。6.4 对研究者和工程师的实用建议做这类课题的项目我的几个经验是第一一定要先把单网潮流算准再加耦合。不要一开始就奔着“统一求解”去先在同一个代码框架里分别把电网、气网、热网的独立潮流算对确认各部分没问题再合并。这一步能省下你后面调试时间的80%。第二数据要结构化、可配置。最怕的就是把参数硬编码在脚本里改一个系统就要改代码。我建议把所有数据放在一个结构体或者MAT文件里代码只负责读数据、算结果不负责“记参数”。这样同样的代码换个算例系统几分钟就能完成适配。第三结果要能“讲得出来”。在工程汇报或者论文里一张好的能流分布图比一大段解释文字都管用。我强烈建议花时间把可视化模块做好坚持下来你会感谢自己。第四别迷信默认算法。牛顿-拉夫逊法虽然应用广泛但在多能流这种多物理场强耦合问题上研究一下Broyden拟牛顿法或者自适应阻尼算法往往有惊喜。复杂系统的计算稳定比追求“快速二次收敛”更重要。最后再分享一个小经验写这套代码的过程中我自己最明显的一个认知提升是综合能源系统的能流计算难的不是任何单一网络的求解而是跨网络变量的“量纲与量级”统一处理。电压是千伏级、压力是兆帕级、温度是几十度级把这三个量级的未知量塞进同一个线性方程组数值处理上稍微粗糙一点就会导致收敛性急剧恶化。我后来专门写了一个变量归一化模块把电网、气网、热网的所有变量都归一化到0.1到10这个区间范围收敛性立刻发生了质的改善。另外一个小工具经验调试的时候把每一步迭代的残差范数、最大修正量、以及“哪个方程的残差最大”打印出来然后用这个信息定位方程组的薄弱环节比盯着屏幕看变量值变化要高效得多。我见过很多同行调试多能流程序时面对不收敛只会改初值碰运气那个效率太低了。这套Matlab代码目前在我手上作为区域综合能源规划的“底层计算内核”在用后续还会继续迭代。如果你正在做相关课题希望这篇内容能帮你少走一些弯路也期待你踩过的坑能反馈给我一起把这个方向的技术细节打磨得更扎实。
返回列表