
简介面向电力系统专业学生与科研人员的极坐标牛顿-拉夫逊法潮流计算9节点MATLAB程序资源解决的是极坐标形式下潮流方程组的构建、雅可比矩阵计算与迭代收敛问题适合课程设计、毕业设计或入门的仿真分析。资源包共6个文件、约160KB其中4个m脚本分别承担电气数据初始化、雅可比矩阵构建、修正方程求解与不平衡量计算等核心环节另有PDF与DOCX算例信息说明可对照教材公式理解算法细节。程序基于经典牛顿-拉夫逊算法框架覆盖从初值设定、迭代修正到结果输出的完整流程。已有279人学习浏览。通过该程序可清晰看到极坐标牛拉法的编程实现结合算例文档能快速复现9节点系统的潮流计算结果也可修改节点或负荷数据开展扩展实验是掌握潮流计算原理与MATLAB编程的良好参考。1. 拿到九节点牛拉法先别急着写迭代做极坐标牛拉法潮流计算时最常卡住人的通常不是牛顿法本身而是极坐标下的雅可比矩阵到底怎么摆有功方程对谁求导、无功方程对谁求导、PV节点砍掉哪一行、修正量里出现的到底是 ΔV 还是 ΔV/V。九节点系统规模不大但已经能完整暴露这些符号和维度问题所以用 MATLAB 写一套极坐标牛拉法 9 节点程序非常适合用来把潮流计算的“方程-雅可比-迭代”这条主线一次理顺。这篇面向电气专业课程设计、毕业设计以及刚接手小系统潮流程序的工程师讲清楚极坐标下的功率方程、雅可比子矩阵形成规则、九节点数据组织、迭代发散时从哪里下手。看完可以直接在 MATLAB 里复现一套能跑通的骨架再遇到其他节点系统只需要替换数据。2. 极坐标下的牛拉法功率方程与雅可比子矩阵规则2.1 极坐标下的功率不平衡量为什么好写极坐标牛拉法潮流计算中节点 i 的注入功率用电压幅值 V 和相角 δ 表示。对任意节点 i有功和无功注入可以写成对全部节点求和的形式Pi Vi * Σ Vj * (Gij * cos(δi-δj) Bij * sin(δi-δj)) Qi Vi * Σ Vj * (Gij * sin(δi-δj) - Bij * cos(δi-δj))其中 Gij 和 Bij 是节点导纳矩阵 Y 的实部和虚部。潮流计算要求的是找到一组 V 和 δ让上面计算出来的注入功率等于该节点给定的净注入功率 Psp 和 Qsp。净注入功率是发电机出力减去负荷即 Psp Pg - PlQsp Qg - Ql全部采用标幺值。于是定义不平衡量ΔPi Psp_i - Pi_calc ΔQi Qsp_i - Qi_calc迭代的目标就是把这些不平衡量压到接近零。直角坐标法要同时保留电压实部和虚部两组变量极坐标法把未知量压缩成相角 δ 和幅值 V对 PQ 节点保留有功和无功两个方程对 PV 节点只保留有功方程平衡节点两个方程都不进入修正方程。这样形成的修正方程规模变成 2×PQ节点数 PV节点数比直角坐标少一组方程。以常见的 IEEE 9 节点三机系统为例若取母线 1 为平衡节点、母线 2 和 3 为 PV 节点则修正方程只有 2×6 2 14 维在 MATLAB 里是一个几乎瞬时求解的小规模线性系统。极坐标形式下功率方程的三角函数直接对应导纳矩阵元素形成雅可比时每一块的物理含义都很明确这是工业潮流程序大量采用极坐标形式的原因之一。实际工程里BPA、PSS/E 等商用程序的内核也普遍使用极坐标或混合坐标而不是直角坐标。2.2 雅可比四个子块的对角项与非对角项极坐标牛拉法的修正方程通常写成如下分块形式[ ΔP ] [ H N ] [ Δδ ] [ ΔQ ] [ J L ] [ ΔV/V ]这里第二个未知量采用 ΔV/V 而不是直接采用 ΔV原因是 V 乘以导纳再乘以电压自然落在功率量纲上雅可比各子块表达式更整齐而且解出 ΔV/V 后电压修正量通过 ΔV V .* (ΔV/V) 得到。四个子块的定义和常用表达式如下表i 为行节点k 为列节点δik δi - δk。子块物理含义对角项 (ik)非对角项 (i≠k)HΔP / Δδ-(Qi Vi²·Bii)-Vi·Vk·(Gik·sinδik - Bik·cosδik)NΔP / (ΔV/V)Pi Vi²·GiiVi·Vk·(Gik·cosδik Bik·sinδik)JΔQ / ΔδPi - Vi²·GiiVi·Vk·(Gik·cosδik Bik·sinδik)LΔQ / (ΔV/V)Qi - Vi²·BiiVi·Vk·(Gik·sinδik - Bik·cosδik)注意 H 和 J 的非对角项不相等H 的表达式里是 sin 减 cosJ 的表达式里是 cos 加 sin极坐标雅可比不对称这一点和直角坐标不同。最容易写错的两处一是 δik 的方向统一用 δi - δk不要一会儿 i-k 一会儿 k-i二是 G 和 B 的符号导纳矩阵中线路充电电容对应正的 B变压器支路电抗对应负的 B代入公式时不要额外加负号。若按上面的式子装配符号自然正确若自己再“优化”一遍符号往往会把 H 和 L 的正负弄反导致迭代直接发散。装配时可以用双重循环遍历所有节点对也可以利用 MATLAB 的向量化一次算整个子块。小算例中双重循环可读性更好九节点规模下耗时可以忽略。需要裁剪的行列对应关系是ΔP 只对参与迭代的节点计算即除了平衡节点之外的所有节点ΔQ 只对 PQ 节点计算相角修正量对应参与迭代的全部节点电压幅值修正量只对应 PQ 节点。用 MATLAB 的索引表达就是取 H(inte, inte)、N(inte, pq)、J(pq, inte)、L(pq, pq)其中 inte 是除平衡节点外所有节点的集合pq 是纯 PQ 节点集合。2.3 形成修正方程时的节点类型裁剪上面的裁剪关系可以用一个具体的 MATLAB 索引片段说明inte [pq; pv]; % 参与角度修正的节点PQ PV neq 2*length(pq) length(pv); dF [dP(inte); dQ(pq)]; % 右侧不平衡向量 JAC [H(inte, inte), N(inte, pq); J(pq, inte), L(pq, pq)]; dX JAC \ (-dF); % 解出 [Δδ; ΔV/V]这里把不平衡向量 dF 显式写成 dP(inte) 和 dQ(pq) 的拼接而不是直接用全部节点的 dP 和 dQ就是为了避免把平衡节点的无功方程和 PV 节点的无功不平衡量塞进修正方程。PV 节点虽然不参与无功修正但它的有功不平衡量仍然有效所以 dP 里要保留 PV 节点。平衡节点的相角作为参考不动所以它的 ΔP、ΔQ 都不进入 dF角度修正列也不对应平衡节点。解出的 dX 前一段是角度修正量 Δδ后一段是电压相对修正量 ΔV/V。给实际电压赋值时不能直接把后一段加到 V 上而要V(pq) V(pq) dX(后半段) .* V(pq)。这一步漏乘 V 是九节点程序里一个非常典型的错误表现出来的现象是迭代后期收敛变慢或者电压波形左右震荡而不是一开始就发散。3. 用 MATLAB 组织九节点牛拉法主迭代骨架3.1 从节点数据和支路数据到节点导纳矩阵写极坐标牛拉法 9 节点 MATLAB 程序数据组织建议分成两个矩阵bus和branch。bus的每一行是母线信息列依次为编号、节点类型、电压初值、相角初值、有功出力、无功出力、有功负荷、无功负荷branch的每一行是支路信息列依次为首端节点、末端节点、电阻、电抗、充电电纳的一半。充电电纳写成 B/2 而不是全电纳这样两端各加一次 B/2 就自然形成 π 型等值电路。一种常见做法是直接用经典 IEEE 9 节点三机系统作为算例三台发电机分别接在母线 1、2、3其中母线 1 为平衡节点母线 2 和 3 为 PV 节点负荷集中在母线 4 到 9。录入时注意发电机出力和负荷都要折算到基准容量下bus矩阵里保存原始有名值或标幺值都可以关键是后续算 Psp 和 Qsp 时做一次统一除以基准容量的处理。支路数据中三个变压器支路电阻为零、电抗不为零这正好可以检验程序是否把变压器支路和线路支路按同一方式处理若程序对零电阻支路出现除零就要在导纳计算时采用复数除法y 1 / (R 1j*X)而不是拆开算倒数。下面这段代码构造九节点系统的节点导纳矩阵baseMVA 100; n size(bus, 1); Y zeros(n); for k 1:size(branch, 1) f branch(k, 1); t branch(k, 2); z branch(k, 3) 1j * branch(k, 4); y 1 / z; Y(f, f) Y(f, f) y 1j * branch(k, 5); Y(t, t) Y(t, t) y 1j * branch(k, 5); Y(f, t) Y(f, t) - y; Y(t, f) Y(t, f) - y; end G real(Y); B imag(Y);逐行说明每个非对角线支路先计算串联导纳 y对角线累加 y 和充电电纳1j*branch(k,5)非对角线累加 -y。如果支路是变压器且没有充电电纳branch(k,5)为 0自然不影响结果。这里没有写变压器变比是因为九节点系统中的三台升压变压器通常按标幺值变比 1:1 处理如果你的实际系统带非标称变比需要额外读入变比并给 Y(f,t) 乘上复数变比折算系数那是另一个话题九节点基准算例中不需要。构造完成后可以用full(Y)检查对称性正常情况下 Y 是对称矩阵若不对称先检查支路首末端是否录入颠倒。3.2 主迭代循环、雅可比装配与电压修正主迭代循环直接对照 2.2 节的子块公式装配雅可比。关键点是每次迭代要根据当前 V 和 delta 重新计算 Pcal 和 Qcal再重新装配 H、N、J、L不能沿用上一轮的雅可比。牛拉法每一步都用最新运行点重新线性化这是它二阶收敛特性的来源九节点程序迭代四次左右即可达到 1e-10 的精度如果改成固定雅可比只更新右侧收敛速度会退化到类似定雅可比迭代这是两个不同的算法不要混用。下面给出一段可直接运行的迭代骨架变量命名与上面的数据格式保持一致type bus(:, 2); pq find(type 3); pv find(type 2); ref find(type 1); inte [pq; pv]; V bus(:, 3); delta deg2rad(bus(:, 4)); Psp (bus(:, 5) - bus(:, 7)) / baseMVA; Qsp (bus(:, 6) - bus(:, 8)) / baseMVA; tol 1e-10; maxIter 20; for iter 1:maxIter Pcal zeros(n, 1); Qcal zeros(n, 1); for i 1:n for j 1:n d delta(i) - delta(j); Pcal(i) Pcal(i) V(i) * V(j) * (G(i,j) * cos(d) B(i,j) * sin(d)); Qcal(i) Qcal(i) V(i) * V(j) * (G(i,j) * sin(d) - B(i,j) * cos(d)); end end dP Psp - Pcal; dQ Qsp - Qcal; dF [dP(inte); dQ(pq)]; if max(abs(dF)) tol break; end H zeros(n); N zeros(n); J zeros(n); L zeros(n); for i 1:n for k 1:n if i k H(i,i) -(Qcal(i) V(i)^2 * B(i,i)); N(i,i) Pcal(i) V(i)^2 * G(i,i); J(i,i) Pcal(i) - V(i)^2 * G(i,i); L(i,i) Qcal(i) - V(i)^2 * B(i,i); else d delta(i) - delta(k); H(i,k) -V(i)*V(k) * (G(i,k)*sin(d) - B(i,k)*cos(d)); N(i,k) V(i)*V(k) * (G(i,k)*cos(d) B(i,k)*sin(d)); J(i,k) V(i)*V(k) * (G(i,k)*cos(d) B(i,k)*sin(d)); L(i,k) V(i)*V(k) * (G(i,k)*sin(d) - B(i,k)*cos(d)); end end end JAC [H(inte, inte), N(inte, pq); J(pq, inte), L(pq, pq)]; dX JAC \ (-dF); dDelta zeros(n, 1); dV zeros(n, 1); dDelta(inte) dX(1:length(inte)); dV(pq) dX(length(inte)1:end) .* V(pq); delta delta dDelta; V V dV; end逻辑说明内层双重循环先算所有节点的注入功率再算 dF。收敛判断放在解方程之前因为初次迭代的 dF 往往已经能反映出数据录入是否离谱若初始不平衡量就超过 0.5先检查负荷和出力是否漏除了基准容量。装配雅可比时对角项使用当前迭代点的 Pcal 和 Qcal而不是使用规格化的 Psp这是牛顿法“在当前点线性化”的基本要求。最后解出来的 dX 拆成两段第一段是角度修正量第二段是相对电压修正量乘上 V(pq) 后才得到真实电压增量。3.3 收敛判据与迭代控制参数九节点程序的收敛判据常用两种一种只看不平衡向量的最大绝对值另一种同时看最大电压修正量。前者更接近功率方程本身的残差推荐作为主判据后者可以作为辅助观察项防止出现电压已经在两个值之间来回跳动但残差恰好很小的情况。骨架中用的是max(abs(dF)) tol其中 dF 由 dP(inte) 和 dQ(pq) 拼接而成单位是标幺功率。阈值取 1e-8 足够工程使用取 1e-10 可以看到牛拉法典型的二次收敛过程适合课程设计展示迭代次数。参数常用取值说明收敛阈值 tol1e-8 ~ 1e-10标幺值过小没有实际意义且会暴露浮点噪声最大迭代次数 maxIter15 ~ 30牛拉法正常 3~5 次收敛超过 10 次基本是数据或雅可比问题电压初值 V01.0PQ 节点平启动PV 节点取给定电压幅值相角初值0全部节点从零相角启动PV 节点无功越限Qmax/Qmin 由数据给出越限后转为 PQ 节点重新迭代见第 5 章如果迭代次数在 6 到 10 次之间缓慢收敛最常见的原因是把 ΔV/V 当成 ΔV 使用或者 PV 节点的无功方程错误地参与了修正导致迭代方向被带偏。如果第一次迭代 dF 就出现 NaN优先检查 Y 矩阵是否出现除零或复数导纳求解错误。4. 九节点系统数据准备、初值设置与发散排查4.1 九节点公共算例的数据口径极坐标牛拉法 9 节点 MATLAB 程序中最常用的验证对象是经典三机九节点测试系统。这个算例包含三个发电机节点和六个负荷节点三条变压器支路连接发电机升压侧三条线路组成一个环形网络负荷水平适中既不会像重载系统那样容易发散又能检验程序对 PV 节点和变压器支路的处理。母线编号习惯上从 1 到 9其中母线 1 为平衡节点母线 2 和 3 为 PV 节点母线 4 到 9 全部为 PQ 节点。一份典型的数据口径如下表单位均为标幺值基准容量取 100 MVA母线类型电压初值Pg (p.u.)Qg (p.u.)Pl (p.u.)Ql (p.u.)1平衡1.0400.720.27002PV1.0251.630.07003PV1.0250.85-0.11004PQ1.000000.900.305PQ1.000001.000.356PQ1.00000007PQ1.000000.600.108PQ1.000001.000.359PQ1.000001.250.50注意这里 Pg 和 Pl 都已经是标幺值实际录入时如果从原始有名值转换要统一除以基准容量。支路数据中三条变压器支路分别为 1-4、2-8、3-9电阻为零电抗分别为 0.0576、0.0625、0.0586三条线路支路为 4-5、4-6、6-9、5-7、7-8、8-9每条线路的充电电纳按半模型录成 B/2。不同文献里的负荷数值可能有微小差异这不会影响程序正确性只要整个算例内部自洽即可。4.2 初值选择与 PV 节点无功越限处理极坐标牛拉法对电压初值不敏感平启动就是最稳妥的选择所有 PQ 节点电压幅值取 1.0相角取 0PV 节点直接取给定的电压幅值。九节点系统负荷不重平启动后通常 3~4 次牛顿迭代就能收敛。相比之下直角坐标法对初值更敏感这也是极坐标形式在实际程序中更常见的原因之一。如果系统包含弱环网、串联补偿线路或重负荷节点平启动可能不收敛这时可以先做一次高斯-赛德尔迭代得到一组初值再交给牛拉法九节点基准算例不需要这种处理。PV 节点在迭代过程中可能出现无功越限即计算出来的 Qcal 超过发电机无功上限或低于下限。处理方法分两步第一步检测出越限的 PV 节点把它从 PV 集合移到 PQ 集合电压幅值固定在越限值上无功注入强制设为限值第二步重新进入迭代让该节点的电压幅值重新作为未知量参与修正。工程中常见做法是每次迭代后检查一次发现越限就做一次类型切换然后继续迭代而不是中止计算。九节点算例的 PV 节点无功一般不会越限但程序里预留这个逻辑换成其他算例时会省很多调试时间。4.3 发散时先查这四类问题九节点规模的潮流程序发散几乎都可以归到下面几类原因。与其反复调初值不如按这张表逐项排查现象最可能原因处理办法第一次迭代 dF 就出现 NaNY 矩阵有零阻抗支路或复数导纳赋值错误检查支路 R 和 X 是否录入顺序颠倒检查 Y 对角线是否包含 1j*B/2迭代次数超过 10 次电压振荡ΔV/V 被当成 ΔV 使用修正电压更新语句给相对修正量乘上当前 V两侧电压严重不对称但功率残差很小雅可比中 H 和 J 的符号错误G、B 代入符号不对按 2.2 节表格逐项核对尤其是 sin 和 cos 前的正负号PV 节点电压脱离给定值PV 节点的 ΔQ 错误地进入了 dF确认 dF 只取 dQ(pq)PV 节点只保留 dP 约束其他容易被忽略的问题包括负荷和发电机的单位不统一比如一个用 MW 一个用 p.u.变压器支路充电电纳写成了全电纳而不是半电纳MATLAB 中角度用度而雅可比公式里用了弧度导致三角函数计算结果离谱。九节点系统的数值规模小出现这些问题时直接打印中间变量比用调试器更高效。5. 从九节点骨架延伸到通用求解器的三个实用改造把九节点程序改成通用求解器的第一个常用改造是支持 PV/PQ 节点动态切换。实现方式是在每次迭代收敛检查之后增加一段检测代码Qgen Qcal(pv) bus(pv, 8) / baseMVA; viol find(Qgen Qmax | Qgen Qmin); if ~isempty(viol) bus(pv(viol), 2) 3; pv find(bus(:, 2) 2); pq find(bus(:, 2) 3); inte [pq; pv]; % 把越限节点电压固定到限值Qsp 设为限值后继续迭代 end这个改造的价值在于很多实际系统的 PV 节点在重负荷下都会触碰到无功上限如果不切换类型牛拉法会一直尝试把电压拉回给定值导致迭代不收敛或收敛到一个无意义的运行点。第二个实用技巧是加一段功率平衡校验用来验证程序和导纳矩阵是否正确。在迭代结束后计算全网损耗Sloss sum(V .* conj(Y * V)); Pgen sum(bus(:, 5)) / baseMVA; Pload sum(bus(:, 7)) / baseMVA; if abs(real(Sloss) - (Pgen - Pload)) 1e-6 disp(功率不平衡检查导纳矩阵或数据录入); end这段代码利用节点注入复功率之和等于网损的物理关系对九节点算例通常能精确到 1e-10 量级。若对不上问题几乎都出在数据录入阶段而不是迭代算法本身。第三个改造是稀疏化处理。九节点用全矩阵没有问题但把Y、JAC改成sparse结构之后同样的代码可以直接支撑到几百节点的规模。改造量很小构造 Y 时用sparse索引赋值装配雅可比时对 JAC 用sparse索引解方程仍写JAC \ dFMATLAB 会自动选择适合稀疏矩阵的线性求解器。把 case9 换成 case30 或 case57只需要替换 bus 和 branch 矩阵再用max(abs(dF))校验一次收敛残差整个改造就完成了。本文还有配套的精品资源点击获取