☰
MATLAB下IEEE33节点配电网潮流计算与故障仿真全攻略
2026/10/13 4:15:41 网站建设 项目流程

做配电网方向的人,几乎都会遇到 IEEE33 节点配电网这个标准算例。我第一次在 MATLAB 里跑通这个模型的潮流计算时,心里的成就感很真实——但说实话它折腾了我好几个晚上,尤其是后面加上故障仿真那一步,各种矩阵报错、收敛失败让人头大。这篇笔记就把从模型参数整理、潮流计算到故障仿真的完整路径拆开讲清楚,把我踩过的坑和验证方法一起整理出来。如果你想用 MATLAB 快速上手一个既经典又不至于太小的配电网仿真项目,这篇文章应该能帮你省下不少时间。

IEEE33 节点模型的用处远不止课程作业:分布式电源接入分析、配电网重构、故障定位算法、储能选址,很多研究都要先在这张网上跑通基础仿真。学会它,等于拿到了一套通用的配电网实验平台。

1. IEEE33 节点模型:这张网到底长什么样

1.1 网络拓扑与基础参数

IEEE33 节点配电网是一个典型的放射状(辐射状)网络,包含 33 个节点、32 条常闭支路,外加 5 条联络开关支路,正常运行时联络开关是断开的。系统由单个电源经变电站母线供电,在仿真中通常把节点 1 设为平衡节点(V = 1.0 pu)。

基准电压通常取 12.66 kV,基准功率取 10 MVA。系统总负荷在常见资料中约为 5084 kW + 2547 kvar 的量级,也就是 5 MVA 左右,各节点负荷分布并不均匀,越往线路末端,电压跌落越明显。

这个算例最大的价值在于:它不算大到难以处理,33 个节点用手算加代码完全能搞定;但也不像 3 节点或者 5 节点那样简单到失去实际意义。它包含了主干线、分支线、轻载重载混合、末端低电压等真实配电网的典型特征,所以学术界和工程界都拿它当默认实验平台。

注意:网上流传的 IEEE33 节点参数表有多个版本,支路阻抗和负荷数据可能有细微差异。做仿真前最好固定使用同一份数据来源,否则结果无法对标文献。

1.2 建模仿真前必须理清的数据结构

在 MATLAB 中建模,我习惯用两个结构化数组来组织数据,比直接用稀疏矩阵直观得多:

  • bus 数组,每行对应一个节点,字段包括:节点编号、有功负荷(kW)、无功负荷(kvar)、电压初始值(pu)、节点类型。
  • branch 数组,每行对应一条支路,字段包括:首端节点、末端节点、电阻(Ω)、电抗(Ω)、是否联络开关。

对于 IEEE33,前 32 条支路是常闭线路,后面 5 条支路对应联络开关,潮流计算时必须把它们剔除,否则网络就不是放射状了,前推回代法会直接失效。

单位问题尤其要注意。原始参数表里电阻、电抗用的是欧姆,负荷用的是 kW / kvar,而潮流计算内部通常用标幺值。很多新手第一次跑出来电压全在 1.0 pu 附近、和文献对不上,八成是标幺换算系数除错了。正确做法是把功率基准取 10 MVA,电压基准取 12.66 kV,阻抗基准就等于 U_base^2 / S_base,大约 16 Ω,然后把欧姆值除以 16 得到标幺。

2. 潮流计算:给整个系统做一次稳态体检

2.1 为什么配电网潮流用前推回代法更顺手

输电网潮流计算首选牛顿-拉夫逊法,因为输电网 R/X 比小、电压刚性,雅可比矩阵条件数好。但配电网不一样,R/X 比经常大于 1,节点电压对无功的敏感度反常,直接套用快速解耦法很容易不收敛。

前推回代法(Backward/Forward Sweep)专门为放射状网络设计,算法逻辑和配电网的物理结构天然对应:

  • 回代过程:从末端节点往根节点方向,根据当前电压和节点负荷,逐条支路累加计算支路电流。
  • 前推过程:从根节点往末端方向,用最新算出的电流和支路阻抗,逐节点更新电压。
  • 两步交替迭代,直到所有节点电压变化量小于收敛阈值。

这种方法的优势在于不需要求导、不需要构造雅可比矩阵、内存占用小,而且对初值不敏感。它甚至可以直接在原始单位下运行,只要统一单位就行。对 IEEE33 这种规模,迭代 10 次以内就能收敛。

有句话我说过很多次:在配电网仿真里,能不用牛顿法就别硬用,前推回代它不香吗。

2.2 前推回代法的 MATLAB 实现框架

下面给出我常用的骨架代码,重点看流程,而不是把它当成可以直接运行的完整成品。

function [V, iter] = bf_powerflow(bus, branch, baseMVA, basekV, tol) % bus: [编号, P负荷(kW), Q负荷(kvar), 电压初值(pu)] % branch: [首端, 末端, R(ohm), X(ohm), 是否联络开关] n = size(bus, 1); V = bus(:, 4); % 初始电压都设为 1.0 pu closed = branch(:, 5) == 0; % 只保留常闭支路 br = branch(closed, :); m = size(br, 1); % 建立子节点链表:对每条支路,末端节点是哪个 for iter = 1:50 V_old = V; % ---- 回代:计算支路电流 ---- I = zeros(m, 1); % 先初始化各节点注入电流为负荷电流 I_load = conj(bus(:, 2) + 1j * bus(:, 3)) ./ (conj(V) * baseMVA * 1000 / (basekV^2)); % 从末端往前逐支路累加 for k = m:-1:1 endNode = br(k, 2); I(k) = I_load(endNode); end % 上面简化了,实际要把子节点电流累加到父支路上 % ---- 前推:更新节点电压 ---- for k = 1:m startNode = br(k, 1); endNode = br(k, 2); Z = (br(k, 3) + 1j * br(k, 4)) * baseMVA / (basekV^2); V(endNode) = V(startNode) - Z * I(k); end if max(abs(V - V_old)) < tol break; end end end

这里我把回代的累加逻辑简化了,真实实现通常要先把每个节点的子节点列表建好,然后按拓扑倒序累加功率或电流。你可以从根节点用深度优先搜索给节点排一个先序遍历顺序,逆序就是回代顺序。

一个更简单的写法是:从末端节点开始,找它对应的父节点,把该节点负荷电流加到父支路电流上,然后递归向上。MATLAB 里用 for 循环从末端编号往 1 编号扫一遍就能完成累加,但要注意支路编号的排序必须保证父节点编号小于子节点编号,否则方向会乱。

2.3 潮流结果怎么验证对不对

潮流跑完之后,先别急着做故障分析,核对以下几项:

  • 节点 18 的电压应在 0.90~0.91 pu 附近(不同数据版本略有浮动)。
  • 总网损大约在 0.20 MW 量级,可以由平衡节点功率减去总负荷得到。
  • 平衡节点输出的有功功率等于总负荷加网损,无功功率也是自然平衡出来的。

如果节点 18 电压高了 0.05 pu,先查是不是把负荷单位填错了。我第一版程序跑出来末端电压 0.98,检查半天发现是 kvar 数据当成 kW 用了,两个一除顿时对上了。

把电压分布画成折线图是很好的习惯,横轴按节点编号排列,纵轴电压幅值。IEEE33 的电压剖面有明显的“下垂”趋势,末端最低,部分分支节点会比主干相邻节点更低。这条曲线是你后面所有故障分析、网损分析、分布式电源接入分析的基线。

3. 故障仿真:当短路发生时,系统怎么响应

3.1 从潮流结果到故障分析怎么过渡

潮流计算给出的是故障前稳态,也就是系统正常运行时的电压分布。故障仿真要回答的问题是:在某一节点发生短路时,短路电流多大、各节点电压跌到多少、哪些节点受影响最严重。

核心工具是节点阻抗矩阵 Zbus。有了网络参数就能直接构建,步骤是:

  • 从每条支路的阻抗出发,用支路追加法或者直接求导纳矩阵的逆,得到完整的 Zbus。
  • Zbus 的对角元素 Zkk 就是故障点在故障前看到的系统等值阻抗。
  • 故障点短路电流标幺值大约等于 V0(k) / (Zkk + Zf),其中 V0(k) 是故障前节点电压,Zf 是过渡电阻。

这个公式非常实用。你不需要真的解一遍短路电流就大概能猜出数值——这就是阻抗矩阵的威力。

然后,各节点故障后的电压可以通过 V = V0 - Zbus(:, k) * If 来计算,Zbus 第 k 列乘以故障电流后再从故障前电压上扣掉。所有节点的电压变化一次计算就全部得到,不用逐节点迭代。

3.2 各类短路故障的边界条件

配电网中短路类型很多,常见的是三相短路、两相短路、两相接地短路、单相接地短路。对称的三相短路最简单,直接用正序网络就能算。不对称故障必须引入对称分量法,把三相系统分解成正序、负序、零序三组分量。

三相短路的边界条件是对称的,故障点三相电压为零,短路电流可以直接用 Zkk 计算。

单相接地(最常见)的边界条件是故障相电压为零、另外两相电流为零,计算时要在序网络里把正序、负序、零序网络串接起来,短路电流公式变为 3 * E / (Z1 + Z2 + Z0 + 3Zf)。

教学仿真中,如果你的重点是想看“配电网哪段最容易出问题”“故障对电压分布的影响有多大”,可以先从三相短路和单相接地两种极端情况入手。其中三相短路通常短路电流最大,单相接地则因为零序阻抗影响,电流相对偏小。

3.3 用 MATLAB 计算故障电流的核心逻辑

故障计算模块可以独立写成函数,输入 Zbus 和故障前电压,返回故障点电流和全网电压变化:

function [If, V_post] = fault_calc(Zbus, V0, k, faultType, Zf) % faultType: '3ph' 三相短路, 'SLG' 单相接地 Zkk = Zbus(k, k); switch faultType case '3ph' If = V0(k) / (Zkk + Zf); V_post = V0 - Zbus(:, k) * If; case 'SLG' % 简化序网:正序、负序阻抗近似相等,零序需要单独构建 % 这里只给出概念性算式 Z1 = Zkk; Z2 = Zkk; % 配电网中常取 Z2 = Z1 Z0 = get_zero_seq_impedance(k); % 需要额外准备零序数据 If = 3 * V0(k) / (Z1 + Z2 + Z0 + 3 * Zf); % 后续电压恢复需要按序分量合成 end end

写到这里必须说明:零序网络的构建在配电网里比输电网麻烦,因为零序电流需要有接地回路。很多简化教材直接让 Z0 = 3 * Z1 来近似,但对带中性点不接地系统的配电网这种近似可能失真。做研究时,建议按你的系统参数单独构建零序阻抗矩阵。

3.4 故障位置和过渡电阻的影响

用同样的故障类型,分别在节点 18(末端)、节点 2(首端附近)做三相短路,短路电流差异很大。

按照前面的公式,I_base = 10 MVA / (√3 × 12.66 kV) ≈ 456 A。如果末端节点 Zkk 标幺值约 0.9,三相短路电流标幺值约为 1.1,折算成有名值只有 500 A 左右。但在靠近电源的节点,Zkk 可能只有 0.1,短路电流能冲到 10 倍标幺值,也就是四千多安培的量级。

过渡电阻的影响更直观。Zf 从 0 增加到 10 Ω(标幺约 0.6),故障点短路电流明显下降,故障节点电压跌落也没那么深。这和实际情况一致:非金属性短路很难触发保护的动作阈值,也是现场故障定位最难搞的部分。你的仿真里把 Zf 设成一个可扫描的参数,就能画出一条“过渡电阻-短路电流”曲线,对理解保护定值非常有帮助。

4. 从零把项目搭起来:完整的 MATLAB 实操路径

4.1 模块划分与主程序结构

整个项目我建议拆成五个模块:

  • 数据模块:bus 和 branch 参数表,固化成一个脚本或 .mat 文件。
  • 潮流模块:前推回代法函数。
  • 故障模块:Zbus 构建 + 故障电流计算。
  • 扫描模块:遍历多个故障节点、多个故障类型。
  • 可视化模块:电压分布图、电流柱状图、故障影响对比图。

主程序只负责按顺序调用这些模块,并打印关键结果。这样做最大的好处是,后面你换成 IEEE123 节点或自己生成一个随机配电网,只需要替换数据模块,潮流和故障代码基本不用改。

主程序的伪代码如下:

% 主脚本 bus = ieee33_bus_data(); branch = ieee33_branch_data(); [V, iter] = bf_powerflow(bus, branch, 10, 12.66, 1e-6); fprintf('潮流迭代次数: %d\n', iter); Zbus = build_zbus(branch, 10, 12.66); fault_nodes = [5 10 18 25 33]; for k = fault_nodes [If, V_post] = fault_calc(Zbus, V, k, '3ph', 0); fprintf('节点 %d 三相短路电流: %.2f A\n', k, abs(If) * 456); end

这样整个项目的流程就非常清晰了,换数据、换故障点、换故障类型都只是改参数的事。

4.2 标幺值换算和单位处理

再强调一次单位换算,因为这是最容易出错的点。

基准电流:

I_base = S_base / (√3 × U_base) = 10e6 / (1.732 × 12660) ≈ 456 A

基准阻抗:

Z_base = U_base^2 / S_base = 12660^2 / 10e6 ≈ 16 Ω

任何支路阻抗用欧姆值除以 16 就得到标幺值,任何电流用安培值除以 456 就得到标幺值。反过来,故障电流算出来后再乘以 456 就能得到实际安培数。

我有个习惯:在代码开头把 baseMVA、basekV、I_base 作为全局常量定义好,注释里写明换算关系。这样不管程序跑到哪里,只要看到单位异常都能回头查。

4.3 结果可视化:让数据变成信息

仿真的最终目的不只是得到数字,而是要看趋势。我通常画三张图:

第一张:正常潮流下的电压分布折线图,一目了然看出哪些节点电压偏低。

第二张:在关键节点(比如 18、25、33)分别做三相短路,画出各节点故障后的电压恢复曲线,横轴故障点位置、纵轴电压幅度。

第三张:用柱状图对比不同节点同类型短路的短路电流,能直观看出越靠近电源短路电流越大。

figure; bar(fault_nodes, current_values); xlabel('故障节点编号'); ylabel('短路电流 (A)'); title('不同位置三相短路电流对比');

这三张图放在一起,基本就是课程设计或小论文的完整结果展示了。

5. 避坑清单:这些坑我替你踩过了

5.1 潮流不收敛,先别怀疑算法

前推回代法本身收敛性极好,IEEE33 上一两轮迭代就能收敛到 1e-6。如果不收敛,问题几乎都在数据上。

三种高频原因:

  • 联络开关没有剔除,网络出现环,前推回代直接乱套。
  • 负荷单位填错,kW / kvar 混用,导致功率标准差几个数量级。
  • 支路方向定义不一致,有些支路首端编号大于末端编号,回代顺序全乱。

解决方法是写个自检函数:在跑潮流之前先检查每个节点是否只有一个父节点、是否有孤立节点、是否所有常闭支路都连通成一个树形网络。这个自检虽然费点时间,但能省下几小时的调试时间。

5.2 Zbus 奇异或元素异常

构建 Zbus 时如果导纳矩阵奇异,常见原因是潮流计算里剔除了联络开关,但 Zbus 构建时没有剔除,导致网络里多出了闭环回路。反过来,如果有节点没有任何支路连接(孤立节点),Zbus 对应行列也会异常。

一个实用技巧:Zbus 构建前先打印网络的连通性,用图论函数看看是不是只有 1 个连通分量。IEEE33 正常网络应该是 1 个连通分量,去掉联络开关后依然如此。

5.3 非对称故障的零序网络处理

单相接地故障的仿真是最容易翻车的。零序阻抗不仅和线路参数有关,还和中性点接地方式、变压器接线方式有关。很多开源代码里直接把 Z0 = 3 * Z1 代进去,这只适用于特定场景。

我的建议是:如果只是做教学演示,可以明确注明“零序网络采用近似值”,结果当作趋势参考,不要当作精确值。如果做科研,必须把所有接地阻抗、变压器连接方式建模进去,这已经是另一个深度的话题了。

6. 项目扩展:一张网能塞进多少玩法

把 IEEE33 节点的潮流和故障仿真跑通之后,这个平台能做的事情会超出你最初的预期。

最自然的扩展是接入分布式电源。在 IEEE33 的多个节点上加上光伏或风机的输出功率,前推回代法只需要把 DG 出力的负值当作负负荷加入节点的注入功率,迭代规则完全不变。你会发现 DG 接入后末端电压被抬起来了,甚至可能出现过电压问题——这正是当前配电网研究的热点。

其次是配电网重构。把联络开关组合优化当作决策变量,以网损最小为目标函数,用遗传算法、粒子群算法等来搜索开关组合。IEEE33 因为有 5 个联络开关,正好构成一个经典的重构优化问题。

最后是故障定位。你在第 3 章做的故障仿真,本质上就是给故障定位算法提供“标签数据”:不同节点、不同故障类型、不同过渡电阻下,电压和电流会呈现不同的模式。很多基于神经网络的配电网故障定位研究,训练数据就来自这类仿真模型。

我在实际使用中体会最深的一点是:仿真做得好的前提不是代码多花哨,而是对模型的物理意义理解透。当你能看着 Zbus 的对角元素就大致预判短路电流的量级,看着电压剖面就知道哪一段线路最薄弱,这时候你的 MATLAB 脚本已经不只是工具,而是一套可以反复验证想法的实验平台。后面换更大的算例,思路也是一样的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询