做配电网仿真的朋友应该都跑过经典33节点交流系统的潮流——那是继电保护、故障分析、分布式电源接入研究里的标配算例。但如果把整套网络换成直流,线路只有电阻、节点只谈有功功率,既没有无功平衡也没有相角问题,再拿交流潮流程序硬跑,不仅是绕远路,物理意义也对不上。这篇文章就围绕“33节点直流配电网牛顿拉夫逊法潮流计算MATLAB程序”做逐段解析,从节点导纳矩阵搭建、功率不平衡量计算,到雅可比矩阵组装和迭代收敛判断,把每一段代码背后的原理和调试经验都拆开讲。适合正在做直流配电网、直流微网仿真的研究生,以及想快速上手电力系统潮流计算的MATLAB开发者。
1. 33节点直流配电网潮流算例的定位
1.1 直流网络和交流网络差在哪:不只是把电抗置零
交流配电网潮流里,节点状态量是电压幅值U和相角θ,方程包含有功P和无功Q,线路阻抗是R加jX,雅可比矩阵规模是2(N-1)维。换成直流配电网,稳态下线路就是纯电阻,电容、电感只在动态过程起作用;节点电压是实数,没有相角;功率只剩有功一项。所以整个潮流模型的状态量从两个掉到一个,方程组的维数直接减半。
有人会觉得“把交流程序里的电抗设为0,无功方程删掉不就行了”。理论上是接近的,但实践中有个坑:交流导纳矩阵是复数矩阵G+jB,你把B全部归零,剩下G确实可以用;如果程序里按照复阻抗倒数的思路算导纳,一旦电阻也开根号处理,或者保留了复数运算习惯,数值结果就会出现偏差。更麻烦的是,交流程序中针对无功电压控制、PV节点设计的那套逻辑,在直流里并不存在对应物,留着只会增加出错可能性。所以直流潮流程序应该从一开始就按直流模型重写,而不是打补丁。
| 对比项 | 交流潮流 | 直流潮流 |
|---|---|---|
| 节点状态量 | 电压幅值U + 相角θ | 电压幅值U |
| 线路模型 | 阻抗R+jX | 电阻R(电导G) |
| 功率类型 | 有功P + 无功Q | 有功P |
| 雅可比矩阵维度 | 2(N-1) | (N-1) |
| 典型收敛次数 | 3~5次 | 3~5次 |
| 程序复杂度 | 含无功/PV节点逻辑 | 纯功率平衡 |
1.2 33节点直流网络从哪来:一套经典算例的改造思路
33节点不是天生的直流网络,它来源于经典的交流辐射状配电网算例。这个算例有33个节点、32条支路,总负荷大概在3.7MW量级,结构是一条主馈线加三条分支,拓扑特点非常典型:主干长、分支多、末端电压最低。在做直流配电网研究时,很多人会把交流算例“改造”成直流版本:保留节点编号和拓扑结构,把所有支路参数替换成纯电阻,负荷去掉无功部分只保留有功,这样就能得到一个可直接比较的直流33节点测试系统。
为什么要拿它做基准?因为它足够“像”真实的中压直流配电网:若干条馈线、不同位置的负荷、末端的电压跌落问题一应俱全,而且规模适中。节点太少体现不出算法在矩阵层面的优势,节点太多会让调试阶段的问题排查变得麻烦。33个节点、32条支路,正好能在一台普通笔记本电脑上跑得飞快,又能展示牛顿拉夫逊法处理非线性和多节点耦合的全部细节。
1.3 为什么是牛顿拉夫逊法:和前推回代对比
直流配电网大多是辐射状结构,所以很多人第一反应是用前推回代法:从末端负荷往电源推功率,再从电源往末端推电压,迭代到收敛。这个方法在纯辐射状网络里效率很高,代码也短。但它有两个明显的局限:一是遇到环网结构时处理麻烦,因为前推回代基于树状拓扑遍历,遇到环路必须拆环或者改造成树;二是对含分布式电源、储能这类“功率注入型”节点,支持不够灵活,你很难在一个前推回代程序里自然表达“这个节点是定功率还是定电压”。
牛顿拉夫逊法恰好把这些麻烦都绕开了。它不关心网络拓扑是辐射状还是环状,只需要一个节点导纳矩阵;不关心节点是负荷还是电源,只要在功率平衡方程里把功率值得正负号写对;收敛速度还是二阶的,靠近解的时候残差会指数级掉下来。直流模型的雅可比矩阵是实对称矩阵,相比交流问题少了无功和相角,矩阵条件数通常也更友好,牛顿法在这种场景下几乎不会出幺蛾子。所以尽管前推回代在直流辐射网中也能用,从通用性和可扩展性考虑,牛顿拉夫逊法是更稳的选择。
2. 牛顿拉夫逊法的直流潮流数学模型
2.1 节点功率方程与节点分类:直流潮流的变量表
直流配电网里,节点i的注入功率可以写成基尔霍夫电流定律的矩阵形式:
P_i = U_i × Σ_j G_ij × U_j
其中U_i是节点i电压,G_ij是节点导纳矩阵Y中的元素,也就是i-j支路的电导。当i=j时,G_ii是节点i所有连接支路电导之和(自导纳);当i≠j时,G_ij是负的支路电导(互导纳)。这个方程的本质是:节点i的注入功率等于节点i电压乘以所有流入节点的电流之和,而每条支路电流由两端电压差决定。一句话概括,就是欧姆定律加基尔霍夫电流定律。
方程里每个节点只有U一个未知数,但节点之间通过导纳矩阵耦合。对33节点系统来说,如果1号节点设为平衡节点,剩下32个节点的电压都未知,需要32个功率平衡方程来求解。节点类型在直流潮流里比交流简单得多:
- 平衡节点:电压幅值固定(通常U=1.0pu),功率不事先指定,由潮流结果决定,一般对应并网换流器或主储能电站的定电压控制。
- PQ节点:注入有功功率固定,电压待求,对应恒功率负荷、经变流器接入的分布式电源。
交流潮流里的PV节点(有功固定、电压幅值固定)在直流模型里没有直接对应,因为直流网络没有无功支撑手段;但如果换流器采用定电压控制,它本质上就是一个平衡节点。程序里只需标记节点类型,把平衡节点的行列从待求解集合中剔除,剩下全是PQ节点。
2.2 雅可比矩阵的推导:代码里一行矩阵公式的由来
牛顿拉夫逊法的核心,是把非线性方程在当前位置线性化。要求解的方程是P_spec_i = U_i Σ_j G_ij U_j,把右边的计算值记作P_cal_i,功率偏差ΔP_i = P_spec_i - P_cal_i。我们希望找到一组U,让所有ΔP_i同时为零。在迭代点附近,将P_cal_i对每个节点电压求偏导,得到雅可比矩阵J。
先看非对角元素,当j≠i时:
∂P_i / ∂U_j = U_i × G_ij
再看对角元素,当j=i时:
∂P_i / ∂U_i = Σ_j G_ij U_j + G_ii U_i
第一项可以看成Y*U这个列向量的第i个元素,第二项是U_i乘以G_ii。把这两部分合并成矩阵形式,就是:
J = diag(Y*U) + diag(U)*Y
这里diag(Y*U)把列向量放到对角线上,diag(U)*Y是一个对角矩阵左乘Y,这种写法在MATLAB里可以直接一行代码实现,不用手动逐元素填充。理解它的物理含义:雅可比矩阵相当于在当前电压点下,每个节点的功率对每个节点电压的局部灵敏度。电压调整一点,功率会变多少,牛顿法就是利用这个灵敏度信息去修正猜测电压。
2.3 迭代格式与收敛判据:阻尼因子什么时候有奇效
每轮迭代做的事情可以概括为三步:算功率偏差、解修正方程、更新电压。修正方程是J × ΔU = ΔP,求解ΔU后,电压更新为U_new = U + ΔU。从几何上理解,这就好比你在一个山坡上找最低点,每一步都根据当前点的坡度估计最低点方向,往那个方向迈一步。如果当前位置离最低点不远,这一步基本能踩到;如果离得远,步子太大可能迈过谷底,在另一边兜圈子,这就是发散。
收敛判据通常看两个指标,取更严格的那个:最大功率偏差max|ΔP_i|小于阈值(比如1e-8),或者最大电压修正量max|ΔU_i|小于阈值。注意这里所有量都是标幺值,1e-8在标幺制下是相当高的精度。阈值不能设太大,比如1e-4,那样电压可能还在0.001量级附近摆动,看起来“差不多了”但对后续稳定性分析来说精度不够。我习惯设1e-8,如果网络规模比较大、需要快速迭代,放到1e-6也够用。
阻尼因子是防止发散的一道保险。当迭代初期离解比较远,雅可比矩阵给出的修正量可能过大,导致电压被修正到0.8甚至更低的异常值。此时可以把更新公式改成:
U_new = U + α × ΔU
其中α取0.5到0.9之间。代价是收敛速度稍微放慢,但换来的是稳定性。我遇到重载直流网络时,经常先用α=0.6跑几轮,等ΔP降下来再把α恢复到1.0,这种“先小步后大步”的策略在实际调试中很有效。
3. MATLAB程序逐段拆解:数据、矩阵与迭代
3.1 数据组织:节点表、支路表和标幺值的坑
写程序前先把数据组织好。我习惯用两个矩阵,一个存节点信息,一个存支路信息,都放在脚本开头,方便改参数。节点表每行对应一个节点,列为:节点编号、节点类型标记、有功负荷MW、初始电压标幺值。支路表每行对应一条支路,列为:首端节点号、末端节点号、线路电阻Ω。
clear; clc; % 基准值:电压 12.66 kV,功率 10 MVA U_base = 12.66e3; % 单位:V S_base = 10e6; % 单位:VA Z_base = U_base^2 / S_base; % 阻抗基值,约16.03 Ω % node: [编号 类型(1平衡,2PQ) 有功负荷(MW) 初始电压(pu)] node = [ 1 1 0.00 1.0; 2 2 0.10 1.0; 3 2 0.09 1.0; % ... 按完整33节点数据逐行填写 ]; % branch: [首端 末端 电阻(ohm)] branch = [ 1 2 0.0922; 2 3 0.4930; 3 4 0.3660; % ... 按完整32条支路数据逐行填写 ];这里有个必须强调的单位问题:线路电阻单位是欧姆,必须除以Z_base得到标幺电阻,再取倒数才是标幺电导。如果偷懒直接用欧姆值算电导,整个导纳矩阵的量级会差一个Z_base的倍数,结果电压可能掉到0.5以下,或者迭代干脆发散。我第一次改写交流程序时就在这栽过,查了半天才发现是单位混用。建议在代码注释里明确标注每个变量的单位,尤其标幺值相关的变量名,能省很多调试时间。
负荷功率的符号也值得说。node表第3列存的是“正数表示吸收功率”,但潮流计算里规定“节点注入功率为正”,所以PQ节点的指定功率要取负号。程序里统一写成:
P_spec = -node(:,3) * 1e6 / S_base; % MW转W再转标幺平衡节点的指定功率其实是未知数,这里不需要给它赋有意义的值,因为它在迭代中被排除在外,不影响求解。
3.2 导纳矩阵构建:直流33节点网络的Y矩阵怎么拼
导纳矩阵是牛顿拉夫逊法的地基。直流网络中一条支路就是一根电阻,电导g = 1/R。自导纳是节点上所有支路电导之和,互导纳是负的支路电导。程序遍历所有支路,把电导填到矩阵相应位置即可:
n = size(node, 1); Y = zeros(n, n); g_pu = 1 ./ (branch(:,3) / Z_base); % 每条支路的标幺电导 for k = 1:size(branch, 1) i = branch(k, 1); j = branch(k, 2); Y(i,i) = Y(i,i) + g_pu(k); Y(j,j) = Y(j,j) + g_pu(k); Y(i,j) = Y(i,j) - g_pu(k); Y(j,i) = Y(j,i) - g_pu(k); endY矩阵必须是对称矩阵,Y(i,j)=Y(j,i)。这是网络无向性的体现,如果发现不对称,优先检查支路表里是否有重复编号或漏填写。33节点规模不大,用零矩阵开始、循环累加的方式完全够用,没必要上稀疏矩阵;但如果以后扩到几百个节点,建议把Y改成sparse类型,后面求解线性方程组会用稀疏LU分解,速度和内存都改善不少。
一个调试技巧:构建完Y矩阵后,可以把J矩阵和Y矩阵打印出来,用条件数cond(Y)快速判断网络是否连成一片。如果cond(Y)是10的15次方量级,基本可以确定有孤立节点或者某条支路数据异常,先别急着跑迭代。
3.3 功率不平衡量计算:符号约定最容易错
功率不平衡量是所有迭代步骤里最需要小心的地方。计算式是:
dP = P_spec - P_cal
其中P_spec是节点期望的注入功率,P_cal是当前电压下根据网络方程算出来的实际注入功率。如果dP大于0,说明这个节点目前“注入不足”,电压需要调整让更多功率流进来;如果dP小于0,说明“注入过多”,电压需要反向调整。
U = node(:,4); % 初始电压列向量 non_slack = find(node(:,2) ~= 1); % 非平衡节点编号 tol = 1e-8; max_iter = 30; hist_err = zeros(max_iter, 1); % 记录收敛残差 for iter = 1:max_iter P_cal = U .* (Y * U); % 全网络的功率计算值 dP = P_spec - P_cal; % 功率偏差 dP_eff = dP(non_slack); % 只保留非平衡节点的偏差 % ... 后面接雅可比、修正量计算 end注意P_cal的写法是U点乘(YU),千万不要写成(UY)*U,虽然数学上Y是对称矩阵时等价,但多绕一道矩阵乘法,代码可读性差也容易出错。另外,节点表里的平衡节点如果也有负荷值,dP里虽然会被排除,但最终输出的P_cal可能包含这个负荷,解释结果时会困惑。更稳妥的做法是让平衡节点的负荷填0,或者明确注释“平衡节点的功率由潮流自然决定”。
3.4 雅可比矩阵组装与迭代主循环:用左除而不是求逆
雅可比矩阵用前面推导的矩阵公式一行生成:
J = diag(Y * U) + diag(U) * Y; J_eff = J(non_slack, non_slack); dU = J_eff \ dP_eff; % 左除,避免显式求逆 U(non_slack) = U(non_slack) + dU; hist_err(iter) = max(abs(dP_eff)); if hist_err(iter) < tol break; end end这里有两个关键选择。第一,删掉平衡节点对应的行和列(J_eff),因为平衡节点的电压已知,它的功率偏差不需要参与修正。第二,用反斜杠运算符J_eff \ dP_eff而不是inv(J_eff)乘dP_eff。MATLAB官方文档明确建议用左除解线性方程组,它会根据矩阵结构选择LU分解、Cholesky分解或最小二乘,数值稳定性和速度都优于先求逆再乘法。33节点时差别不明显,但这是一旦换到大系统就必须养成的习惯。
迭代结束后加一个收敛检查:
if iter == max_iter && hist_err(end) > tol warning('达到最大迭代次数仍未收敛,残差 = %.2e', hist_err(end)); end这个提示在调试阶段特别有用。如果程序没有提示,你可能会把没收敛的结果当成正确结果拿去分析,后面所有结论都白费。
3.5 结果输出:电压分布图和收敛曲线一个不能少
潮流计算跑完,第一件事是把节点电压画出来看趋势。代码如下:
figure; bar(1:n, U); xlabel('节点编号'); ylabel('电压幅值 (pu)'); title('直流33节点配电网电压分布'); grid on;电压分布图能直观看出网络“哪里扛不住”:辐射状配电网通常沿馈线方向电压逐渐下降,分支末端压降最深;如果某处电压出现非物理的突变,多半是支路参数或负荷符号错了。收敛残差曲线用semilogy画最合适,因为它把残差按对数刻度显示,能清楚看到二阶收敛时残差指数级下降的过程:
figure; semilogy(1:iter, hist_err(1:iter), 'o-'); xlabel('迭代次数'); ylabel('最大功率偏差 |ΔP| (pu)'); title('牛顿拉夫逊法收敛曲线'); grid on;正常运行下,残差曲线应该是在前期快速下降,最后几轮进入到1e-6以下。如果曲线先下降后反弹,说明迭代过程中出现过路过的震荡区;如果干脆水平不降,问题大了,优先检查初值、负荷符号和导纳矩阵。
4. 仿真结果与收敛行为分析
4.1 直流33节点网络的电压分布特征
用这套程序跑典型负荷水平(总负荷约3.7MW),得到的电压分布通常呈现一个清晰的趋势:1号平衡节点电压被控制在1.0pu,沿主馈线逐级下降,各个分支末端继续往下掉,全网最低电压出现在最长分支的最末端节点附近,一般在0.92到0.98pu之间,具体数值取决于负荷水平和支路电阻。
电压下降的本质就是线路电阻上的压降。直流网络里电流从平衡节点流向各个负荷,流过电阻必然产生I×R压降,离平衡节点越远,累积压降越大。这个趋势在交流配网中也存在,只是交流还有无功压降,问题更复杂。直流网络中如果一个节点电压掉到0.9pu以下,通常说明该节点所在馈线负荷过重或者导线截面偏小,后续要做网络重构或加装DC-DC变换器来抬升电压。
有意思的是,33节点直流网络因为有分支结构,电压分布不是单调从1到33一路下降,而是按馈线分支各自下降。主馈干线经过的几个节点电压相对高,分支末端电压相对低。画出来的bar图会呈现“锯齿状”台阶,这是分支负荷和主干压降叠加的结果,看到这种形状说明程序物理上是对的。
4.2 迭代收敛行为:从残差曲线看二阶收敛
牛顿拉夫逊法在直流潮流里的收敛表现应该相当干净。典型情况是3到6次迭代达到1e-8的精度。残差序列大致如下:
| 迭代次数 | 最大功率偏差(pu) |
|---|---|
| 1 | 3.8e-2 |
| 2 | 5.2e-3 |
| 3 | 1.6e-6 |
| 4 | 4.3e-13 |
注意这是典型的收敛趋势示例,不同负荷水平会略有差异。第1次迭代残差可能并不算特别小,因为初始猜测电压全是1.0,离真实解还有距离;第2次改进一个量级左右;第3次开始残差急剧下跌,这就是二阶收敛的标志。牛顿法一旦进入解的吸引域,误差是按平方速度缩小的,简单说就是“每迭代一次,有效数字翻一倍”。
如果残差不是这个走势,比如从第3次开始震荡、残差在1e-3左右徘徊,多半是雅可比矩阵在迭代过程中出现了接近奇异的情况,或者某些节点电压被修正到了负值,导致后续计算完全失去意义。遇到这种情况,先不急着调算法,把U的中间值打印出来看看,电压有没有出现负数、有没有超过2.0的异常值。
4.3 与交流33节点程序对照:为什么直流版更省计算量
如果你手头有交流33节点的潮流程序,做个对照会很明显:交流版每次迭代要求解的雅可比矩阵是64×64(两个变量乘以32个非平衡节点),直流版只要32×32。矩阵小了四倍,但这不是全部。交流版每个节点要算有功和无功两个方程,两套偏导数公式,迭代过程中还要处理PV节点的无功越限问题;直流版只有一个功率方程,代码量减少一半以上,调试难度也直线下降。
从迭代次数看,交流牛顿法通常也需要3到5次收敛,但每次迭代内部要做的事比直流版多得多。所以直流版程序跑起来不仅代码短,实际计算时间也能快一个数量级。这个对比不是想说交流程序不好,而是提醒你:用对模型,才能用对算法。直流配电网的大量研究场景——直流电压控制、下垂控制、多端直流网络功率分配——都需要一个轻量高效的潮流核,这个直流牛顿法程序正好胜任。
5. 常见问题与调试实录
5.1 不收敛但查不出原因:先看残差曲线形态
程序报不收敛时,很多人第一反应是改迭代次数上限。我建议先看残差曲线,它比任何诊断都直观。如果残差从头到尾都不怎么降,甚至越来越大,大概率是初值或模型的问题;如果残差前两轮降得挺好,后面突然反弹,大概率是修正步长过大。对应处理方式也不同:前者需要检查导纳矩阵和负荷符号,后者加阻尼因子α=0.5~0.8重新跑。
另一个很常见的假不收敛是阈值设置问题。如果阈值设成1e-12,但机器精度极限是1e-10,程序会一直卡在最后一位掉不下去。我习惯先设1e-8,确认结果合理后再试1e-10,不要一上来就追求极限精度。
5.2 雅可比矩阵奇异:孤立节点和漏接支路排查
雅可比矩阵奇异最典型的症状是dU里出现10的16次方量级的巨大修正量,电压瞬间变成负数。排查顺序是:先用rank(Y)检查导纳矩阵秩,如果秩小于节点数,说明网络存在孤立岛,肯定有一条支路数据漏填或节点号写错;再用cond(J_eff)检查条件数,条件数超过1e10就要警惕。
还有一种情况比较隐蔽:几条支路连成一个环,所有节点看似接入网络,但平衡节点和这个环之间没有连接。这时候导纳矩阵本身满足连通性,但非平衡节点的电压没有物理依据可参考,雅可比矩阵也可能奇异。在33节点直流网里,直接把支路表整理成图谱形式,用graph(branch(:,1), branch(:,2))画一遍拓扑,一眼就能看出哪些节点没接上。
5.3 恒功率负荷在低电压下的数值麻烦
恒功率负荷是一个很“刁钻”的模型:电压下降时,为了维持功率不变,电流反而增大,电流增大又进一步造成电压下降。这是一种正反馈。在轻载网络中没问题,但在重载或者末端电压本来就低的工况下,恒功率模型会让初始猜测电压1.0离真实解的距离变大,甚至导致牛顿法在低电压区域找不到收敛点。
处理办法有两个。第一,把恒功率负荷临时改成恒阻抗负荷:RL = U_old² / P,先用恒阻抗跑通,拿到一个合理的电压初值后,再切换回恒功率继续迭代。这种“二阶段启动”在工程上很常用。第二,给恒功率节点加一个电压下限约束,如果迭代中某节点电压掉到0.85以下,就把该节点功率按比例削减,否则这个节点很可能把整个迭代拖垮。当然,这种约束是否合理要看具体应用场景,但至少在调试阶段能帮你判断问题出在算法还是网络本身。
5.4 标幺值混用的典型报错和预防
我见过最多的直流潮流程序错误就是单位混用。节点负荷给了MW,基准功率给了MVA,中间忘记换算;线路电阻给了欧姆,但程序里按照标幺电导取倒数;电压初值给了kV而不是标幺值。这些问题不会让MATLAB直接报错,但会让结果面目全非。
| 现象 | 可能原因 | 检查方法 |
|---|---|---|
| 电压普遍低于0.5 | 电阻标幺值算错 | 检查Z_base,手动验算一条支路 |
| 迭代不收敛,残差震荡 | 负荷符号反了 | 检查P_spec正负号 |
| 电压分布异常,有节点超过1.5 | 平衡节点选错 | 检查node表类型标记 |
| Y矩阵不对称 | 支路表漏填或重复 | 打印Y矩阵第1行和第1列对照 |
预防手段很简单:所有变量在命名时带上单位后缀,比如R_ohm、R_pu、P_mw、P_pu;所有进入迭代的变量强制转成标幺值;迭代和输出都用标幺值,只在最后解释结果时再乘回有名值。这套规范看起来繁琐,但对调试效率的提升是显著的。
6. 实操心得与扩展思路
6.1 几个能少走弯路的实操建议
第一个建议:先跑一个小网络验证代码正确性。我在第一次写直流牛顿法时直接奔着33节点去,结果不收敛也不知道是算法错还是数据错。后来换成一个5节点放射网,手算一遍解析解,程序跑出来完全一致,这才确认核心逻辑正确,再回到33节点就顺畅多了。任何潮流程序都应该先过这一关。
第二个建议:把平衡节点放在VSC换流器接入点,不要放在负荷侧的某个节点。如果平衡节点放在网络中间或末端,潮流计算仍然能收敛,但算出来的功率分布很不直观,因为所有电流变成了从中间往两端流。工程上把平衡节点放在电源侧是习惯,也能让后续结果解释符合直觉。
第三个建议:迭代过程中随时打印关键中间变量,不要等程序跑完再看最终结果。在循环里加一行disp对调试阶段的帮助极大,尤其当你要确认雅可比矩阵的数值变化趋势时。跑完再把disp删掉,不影响最终程序。
6.2 从固定功率到下垂控制:程序的扩展路线
这个基础程序最大的价值在于,它是一个可以持续扩展的框架。直流配电网研究中常遇到两类扩展:一类是加新能源节点,把光伏或风机的功率注入模型写好,节点功率从负号改成正号即可;一类是加储能和下垂控制。下垂控制的物理含义是:换流站根据直流电压偏离基准值的程度自动调整输出功率,数学模型上不再是一个固定的平衡节点或PQ节点,而是一个功率和电压满足线性关系的节点。
在牛顿拉夫逊框架里,这种下垂节点的处理方式是把它作为一种介于平衡和PQ之间的边界条件,要么引入下垂系数k,在功率方程里把电压修正项互相耦合起来;要么把这类节点按两个子问题迭代:先用下垂关系更新功率,再用潮流更新电压,外层交替收敛。理论细节不在此展开,但你已经能看到,基础程序里节点类型、导纳矩阵、雅可比组装这几块是高度模块化的,扩展时不需要推翻重来。
我当时在这个直流潮流程序上做了两个小扩展:一个是分布式电源恒功率注入,一个是储能端定电压控制。前者只需要改负荷数据的正负号,后者就是把某个PQ节点的类型标记改成平衡节点并固定电压,程序核心一行没动。这种“框架稳、接口松”的设计,是牛顿拉夫逊法相比前推回代最大的工程优势。
我自己最初跑这个程序时,把交流33节点数据直接塞进直流代码,结果末端电压掉到很离谱的数值还找不出原因——后来发现是支路电阻标幺值漏换了欧姆到标幺的除法。这种错不亲自调试一遍很难发现。如果这篇文章能帮你节省几个小时找bug的时间,那它就有价值了。后面把直流潮流往下做——下垂控制、储能、多端直流网络功率分配,都值得单独写程序,有机会再逐一拆开聊。