☰
交直流混合系统潮流统一迭代法与Matlab实现
2026/10/28 6:31:49 网站建设 项目流程

交直流混合系统潮流计算里最容易出问题的地方,往往不是牛顿法本身,而是换流站那几行方程怎么塞进雅可比矩阵。我见过不少 Matlab 实现,交流侧老老实实用了标准牛拉法,直流侧单独写了个小循环,两边来回迭代交换边界量,前十几个算例都收敛得挺好,一旦把直流输送功率提上去、受端交流系统变弱,残差就在 1e-3 附近来回跳,改松弛因子、加迭代上限都不管用。把直流状态量和交流状态量合并进同一个方程组、用统一迭代法(也叫联立求解法)一次解出来之后,同样的问题通常三到五步就压下去了。这篇就把这套方法的建模细节完整拆一遍——换流器方程是怎么来的、雅可比矩阵里那几块交叉偏导从哪冒出来、Matlab 里代码怎么组织才不至于写到一半自己都看不懂,以及实测中最常踩的几个坑。适合已经会写基础牛拉法潮流、想把手里的程序扩展到交直流混合系统的读者,也适合正在核对某份算例结果、怀疑自己方程写错的人。

1. 统一迭代法的位置:它到底解决了交替迭代的什么问题

1.1 交替迭代法的收敛边界在哪里

交替迭代的思路很自然:交流系统把换流母线当成一个已知功率注入的负荷节点,直流系统把换流母线的电压幅值当成已知量,两边各自牛顿求解,解完交换边界量,反复直到边界量不再变化。这种做法的好处非常实际——交流潮流代码几乎不用改,直流侧那套方程也是个小规模问题,单独调试、单独验证都方便,代码复用率高。

问题出在耦合强度上。换流母线的有功、无功注入并不是常数,而是直流电压、直流电流、触发角的强非线性函数。交流侧一次迭代改变了换流母线电压,直流侧重算之后功率注入又变了,反过来再影响电压。当直流输送功率相对受端交流系统短路容量比较大时,这个"你来我往"的过程增益会超过 1,表现出来就是残差在某个量级附近振荡,既不上升也不下降。工程上常说的"弱交流系统接入直流"容易算不收敛,指的就是这种情况。

我自己的经验是,短路比在 3 以上、直流功率占受端负荷比例不大的算例,交替迭代一般没什么问题;一旦短路比往 2.5 甚至更低走,或者直流功率接近换流母线短路容量的量级,交替迭代的迭代次数会明显上升,再差一点就直接振荡。这不是代码写错,是方法本身的收敛域限制。

1.2 统一迭代把换流母线变成"非线性负荷"

统一迭代法换了个视角:不把换流母线当成"功率已知的节点",而是把它的功率注入写成直流状态量的函数,直接塞进交流节点功率方程里。这样一来,交流方程里出现了直流未知量,直流方程里出现了交流未知量,整个方程组是一个大的非线性系统,一次牛顿迭代同时更新所有未知量。

这个改动带来的最大好处是牛顿法本身的二次收敛性得以保留。只要初值在收敛域内,残差是平方下降的,4 到 5 步做到 1e-8 是常态,不需要担心"这边收敛了那边又变了"的来回拉扯。代价也很明确:雅可比矩阵不再是纯交流的那个方阵,而是带交叉偏导的分块矩阵,规模变大,而且耦合块的偏导推导比较绕,写错一个符号就可能出现"迭代次数莫名其妙变多"或者"收敛到物理上不合理的解"。

这两条路径没有绝对优劣,选型上我给一个粗略的判断标准,供参考:

判断维度倾向交替迭代倾向统一迭代
受端短路比大于 4小于 3
直流功率占换流母线短路容量比例小于 20%大于 40%
换流站数量1~2 端多端、多落点
是否需要频繁改控制方式不需要需要批量扫描控制组合
代码维护成本低,模块独立高,雅可比耦合紧密
单步计算量小大 30%~60%

1.3 值得投入统一迭代的场景

如果你只是做教学演示、验证一个两电平双端系统在某一个工作点下的潮流分布,交替迭代完全够用,代码短、看得清楚。但如果你要做的是控制方式组合的批量扫描、直流功率提升的裕度分析、多端直流系统的运行方式编排,那统一迭代更划算——因为每换一种控制方式,交替迭代可能需要调整松弛策略,而统一迭代只是换掉几个方程和对应的列,主循环一行都不用动。

还有一个细节:统一迭代法收敛之后,雅可比矩阵本身就带着灵敏度信息。想研究"整流侧定功率指令变化 100MW,逆变侧熄弧角会漂多少",直接从雅可比矩阵求逆里取对应元素就行,不需要重复做扰动计算。这个附加价值在交替迭代里是拿不到的。

2. 换流站方程组的推导脉络与它的适用前提

2.1 从触发角到直流电压:理想换流器方程怎么落到代码里

所有教科书上的换流器方程都建立在几条理想化假设之上:换相电抗三相平衡、直流电流平直无纹波、阀导通压降忽略、换流变激磁支路忽略。在这个前提下,一个六脉动换流桥的平均直流电压可以写成理想空载电压减去换相压降:

V_d = (3√2/π) · N · k · V_ac · cos α − (3/π) · N · X_c · I_d

其中 N 是每极串联的六脉动桥数(十二脉动就是 2),k 是换流变变比(归算到交流侧),V_ac 是换流母线电压,α 是触发角,X_c 是归算到阀侧的换相电抗,I_d 是直流电流。前一项是"空载时能撑多高",后一项是"带载后掉多少",直观上和直流电机的电枢反应是一个道理。

真正写代码时,我会把上面这个式子整理成两个常数系数的形式:

V_d = K · V_ac · cos α − d_x · I_d K = (3√2/π) · N · k / V_dB d_x = (3/π) · N · X_c · I_dB / V_dB

这里 V_dB 和 I_dB 分别是直流侧电压、电流基准,K 和 d_x 都变成无量纲量,V_d、I_d 也都成了标幺值。这样做的好处是雅可比矩阵各块量级接近,条件数好看,收敛判据也好统一设。

逆变侧的写法完全对称,只是把触发角换成超前触发角 β,或者换成熄弧角 γ,关系和 β = π − α 一样:

V_d = K · V_ac · cos γ − d_x · I_d

注意:逆变侧这个式子里 V_d 的符号约定要与直流网络方程保持一致。有些代码把逆变侧直流电压写成负值参与求和,有些代码取绝对值然后在线路方程里减,两种都行,但千万不要混用,混用是初学阶段最常见的一类"方程都写对了却算不出正确结果"。

2.2 交流侧有功无功与功率因数角的耦合关系

换流站从交流系统吸收的有功,在忽略换流变铜损和阀损耗的前提下,等于直流侧输送功率:

P_ac = V_d · I_d

无功就没这么简单了。换流器需要吸收无功来维持换相,功率因数角 φ 和直流电压之间有一个很漂亮的关系:

cos φ = V_d / (K · V_ac) = V_d / V_d0

推导过程不复杂:功率因数角的余弦等于(cos α + cos(α+μ))/2,而理想换流器方程里的 V_d/(K·V_ac) 恰好也等于这个平均值。所以只要 V_d 和 V_d0 有了,φ 就定了,不需要额外去算换相角。

有了 φ,无功就好办了:

Q_ac = P_ac · tan φ = P_ac · √(1 − c²) / c,其中 c = V_d / V_d0

这个式子在实际调试时非常好用——整流侧 V_d 接近 V_d0 时 c 接近 1,tanφ 就很小,吸收无功少;逆变侧熄弧角小、直流电压被抬高时,c 接近 1,同样无功小。反过来,直流电压掉下来,tanφ 迅速变大,无功需求暴涨,这也是低电压时换流站容易引发电压崩溃的数学根源。

代码里我会单独封装一个函数来做这件事,顺便处理 c ≥ 1 或者 c ≤ 0.3 的越界情况:

function [Pac, Qac, dPac, dQac] = converter_ac_power(Vd, Id, Vd0) % Vd, Id, Vd0 均为标幺值 Pac = Vd * Id; c = Vd / Vd0; c = min(max(c, 0.25), 0.999); % 限幅,避免 tan 发散 tanphi = sqrt(1 - c^2) / c; Qac = Pac * tanphi; % 解析偏导,供雅可比矩阵使用 dPac_dVd = Id; dPac_dId = Vd; dQac_dVd = Id * (tanphi - 1 / (c * sqrt(1 - c^2))); dQac_dId = Vd * tanphi; end

限幅这一步不要嫌它"不干净"。实际算例里,迭代中间过程出现 V_d 短暂超过 V_d0 是完全正常的,如果不限幅,sqrt 里出个负数就直接 NaN,整个牛顿循环崩掉。加个 0.25~0.999 的夹子,能救回绝大部分中间过程的越界,而对最终收敛点没有任何影响——因为收敛点上 c 一定在正常区间内。

2.3 控制方式组合的配平规则

统一迭代里最容易出错的地方不是方程本身,而是未知量和方程的个数对不上。我给一个通用的配平思路,比背组合表更靠谱。

先把所有可能的未知量列出来:每端换流母线的电压和相角(如果它是 PQ 节点,这两个是交流侧的未知量)、每端换流器的触发角或熄弧角、换流变变比(如果可调)、直流电流、各直流节点的电压。再看每个换流站有哪几个方程:换流器方程一个、控制方式给出的等式一个,多端系统中直流网络方程按节点数算。

以最常见的双端系统为例,假设换流变变比固定,两端换流母线都当 PQ 节点:

未知量:α_R、γ_I、I_d、V_dR、V_dI,共 5 个。 方程:

  1. 整流侧换流器方程 V_dR = K_R·V_acR·cos α_R − d_xR·I_d
  2. 逆变侧换流器方程 V_dI = K_I·V_acI·cos γ_I − d_xI·I_d
  3. 直流线路方程 V_dR − V_dI = R_d·I_d
  4. 整流侧控制方程(定功率 P_dR = V_dR·I_d,或定电流 I_d = I_set)
  5. 逆变侧控制方程(定熄弧角 γ_I = γ_set,或定电压 V_dI = V_set)

刚好配平。但这里有个可以省事的技巧:像 γ_I = γ_set 这种直接把未知量钉死的控制方程,完全可以消元处理——γ_I 直接当已知量代入,未知量降到 4 个,雅可比降一维,速度提升不大但代码可读性明显变好。我在实际项目里对"定熄弧角""定电流"这类只涉及单个变量的控制都做消元,只有"定功率"这种耦合两个变量的才保留在方程组里。

控制端控制方式方程形式可消元
整流定直流电流I_d = I_set是
整流定直流功率P_set = V_d·I_d否
整流定触发角α = α_set是
逆变定熄弧角γ = γ_set是
逆变定直流电压V_d = V_set否
逆变定直流功率P_set = V_d·I_d否
任一端定变比k = k_set是,变比当常数

提示:消元之后记得把该变量从状态向量里删掉,而不是把对应行和列置零。置零会让雅可比奇异,牛顿步长出现 Inf,排查起来非常费时间。

3. 状态量打包与雅可比矩阵的分块

3.1 未知量向量的排列约定

统一迭代的状态向量我习惯按"交流在前、直流在后"排:

x = [θ_1 … θ_nPQ+nPV | V_1 … V_nPQ | α_R | I_d | V_dI …]

具体排列顺序其实无所谓,重要的是在整个程序里保持一致,并且把每个变量在向量里的位置用一个索引结构体记下来。这个做法看着笨,但改方程的时候不用一个个数位置,改起来不容易出错。

idx.th = 1:n_th; idx.V = n_th + (1:n_pq); idx.alpha = base_dc; % 直流状态量起始位置 idx.Id = idx.alpha + 1; idx.Vdc = idx.Id + (1:n_dcnode);

残差向量用同一套顺序,ΔP、ΔQ、然后是直流侧的方程残差。收敛判据取无穷范数,阈值 1e-6 到 1e-8,和纯交流潮流保持一致就行。我一般用 1e-8,因为统一迭代收敛本来就快,收紧一点不影响步数。

3.2 四个分块雅可比各自的来源

雅可比矩阵按"交流方程对交流变量""交流方程对直流变量""直流方程对交流变量""直流方程对直流变量"分成四块:

分块行方向列方向内容
J_AA节点有功/无功方程θ、V传统潮流雅可比,H/N/M/L
J_AD换流母线的 P、Q 方程α、I_d、V_d换流器功率对直流状态的偏导
J_DA换流器方程、直流网络方程θ、V直流电压对换流母线电压的偏导
J_DD换流器方程、直流网络方程直流状态对角块加线路导纳

J_AA 就是传统那套,没什么好讲的。真正需要费心的是 J_AD 和 J_DA。

J_AD 的非零元素只出现在换流母线对应的行上。以整流侧为例,换流母线有功方程是

ΔP = P_spec − (P_load − P_ac) = 0 形式

所以 ∂ΔP/∂α = ∂P_ac/∂α。而 P_ac = V_d·I_d,V_d 又是 α 的函数,链式法则展开:

∂P_ac/∂α = ∂P_ac/∂V_d · ∂V_d/∂α = I_d · (−K·V_ac·sin α) = −I_d·V_d0·sin α

这一项在 α 接近 90° 时最大,接近 0° 时趋近于零。这解释了一个现象:触发角很小的算例,直流侧对交流侧功率的修正能力弱,交替迭代反而更容易收敛;触发角大的算例对耦合更敏感。

∂P_ac/∂I_d = V_d,这个直接。

无功的偏导要绕一点:

∂Q_ac/∂α = ∂Q_ac/∂V_d · ∂V_d/∂α ∂Q_ac/∂V_d = I_d · [tanφ − 1/(c·√(1−c²))]

其中 c = V_d/V_d0。这一项在 c 接近 1 时负得厉害,也就是说电压抬高会显著减少无功需求,物理上对得上。

J_DA 的非零元素出现在换流器方程对应的行、换流母线电压对应的列上:

∂V_d/∂V_ac = K·cos α

直流网络方程里没有交流变量,所以 J_DA 只有换流器方程贡献的这几项。

J_DD 里,换流器方程那一行的元素是:

∂V_d/∂α = −K·V_ac·sin α ∂V_d/∂I_d = −d_x ∂V_d/∂V_d = 1(对角)

直流网络方程那一行就是标准的节点导纳形式,双端系统只有 V_dR 和 V_dI 的系数 1 和 −1,加上 R_d 对 I_d 的偏导。

3.3 解析式写不动的地方用复步微分兜底

上面这些偏导推导本身不难,但一旦加上换流变变比调节、多端直流的均压控制、换相角μ的精确模型,解析偏导的推导量会失控,而且极容易写错。我的做法是:耦合块里结构简单的偏导手写,结构复杂的用复步微分(complex-step differentiation)算。

复步微分的原理是利用解析函数在虚轴上展开时实部不带一阶项:

f'(x) ≈ Im(f(x + i·h)) / h,h 取 1e-20

和传统的差分比,它没有相减抵消,精度能到机器精度,h 取多小都不会有舍入误差。前提是被求导的函数里不能出现 abs、max、min、if 这些破坏解析性的操作——这就和前面加的限幅冲突了。我的处理是:复步微分用的函数版本不加限幅,但要在外面先判断是否越界,越界就退回到更保守的初值或者阻尼步长。

function J = numeric_jac_complex(x, f, n) J = zeros(n, n); h = 1e-20; for k = 1:n xk = x; xk(k) = xk(k) + 1i * h; J(:, k) = imag(f(xk)) / h; end end

这个函数写成通用的,重残差函数一改,雅可比自动跟着改,非常适合在建模阶段快速验证。缺点是慢,n 大了之后循环开销明显,正式跑批量算例时还是得换回解析式。

4. Matlab 实现:从算例数据表到牛顿主循环

4.1 数据表的组织方式

交流侧沿用标准格式:bus 表、branch 表、发电机表。直流侧我单独建两张表,一张是换流站表,一张是直流节点/支路表。

换流站表每行一个换流站,字段包括:交流母线编号、直流节点编号、换流器类型(1 整流、−1 逆变)、十二脉动桥数 N、换流变变比 k、换相电抗 X_c、控制方式编码、控制目标值、触发角上下限。

直流支路表就是标准的 from-to-R 格式,双端系统只有一行。

% 换流站表列定义: % 1 ac_bus 2 dc_node 3 type 4 N 5 k 6 Xc % 7 ctrl_mode 8 ctrl_value 9 alpha_min 10 alpha_max conv = [ ... 5, 1, 1, 2, 1.0, 0.10, 1, 3000, 5, 20; % 整流:定功率 3000MW 9, 2, -1, 2, 1.0, 0.10, 2, 17, 100, 120]; % 逆变:定熄弧角 17°

控制方式用整数编码,1 定功率、2 定熄弧角、3 定电流、4 定电压。这样写的好处是加一种新控制方式只需要加一个 case 分支,不用改主循环。

4.2 残差函数的逐段拆解

残差函数是整个程序的核心,我把它拆成四段:交流节点功率、换流器直流电压、直流网络、控制方程。

function F = residual(x, S) % 解包状态量 th = x(S.idx.th); Vm = x(S.idx.V); alpha = x(S.idx.alpha); Id = x(S.idx.Id); Vd = x(S.idx.Vdc); % 1) 交流节点注入功率 Vc = Vm .* exp(1i * th); Sc = Vc .* conj(S.Ybus * Vc); P = real(Sc); Q = imag(Sc); % 2) 换流站折算到交流侧的 P、Q Pac = zeros(S.nbus, 1); Qac = zeros(S.nbus, 1); for m = 1:S.nconv b = S.conv(m, 1); dn = S.conv(m, 2); Vd0 = S.K(m) * Vm(b); [p, q] = converter_ac_power(Vd(dn), Id, Vd0); Pac(b) = Pac(b) + p; Qac(b) = Qac(b) + q; end % 3) 交流残差:换流母线按“负荷”扣减 dP = S.Psp - (P - Pac); % 注意符号:吸收功率要减去 dQ = S.Qsp - (Q - Qac); % 4) 换流器方程残差 Fconv = zeros(S.nconv, 1); for m = 1:S.nconv b = S.conv(m,1); dn = S.conv(m,2); tp = S.conv(m,3); Vd0 = S.K(m) * Vm(b); if tp > 0 Fconv(m) = Vd(dn) - (Vd0 * cos(alpha(m)) - S.dx(m) * Id); else Fconv(m) = Vd(dn) - (Vd0 * cos(alpha(m)) - S.dx(m) * Id); end end % 5) 直流网络残差 Fdc = S.Gdc * Vd - Id * ones(size(Vd)); % 简化双端形式 Fdc = Vd(1) - Vd(2) - S.Rd * Id; % 6) 控制方程残差 Fctrl = control_residual(x, S); F = [dP(S.pq_pv); dQ(S.pq); Fconv; Fdc; Fctrl]; end

这里有个符号问题值得单独说一句:换流母线从交流系统吸收 P_ac、Q_ac,所以在节点功率方程里它们是"负荷",残差写成 P_sp − (P_calc − P_ac) 还是 P_sp + P_ac − P_calc,取决于你怎么定义 P_sp。如果 P_sp 里已经包含了换流站之外的常规负荷和发电,那就用上面这种减法形式;如果 P_sp 只写了常规负荷,那换流功率就得单独加到注入里。两种写法等价,但团队协作时一定要在文档里写清楚,不然交接代码的人一定会在这里栽跟头。

4.3 牛顿主循环与阻尼策略

主循环本身很短,麻烦的是阻尼和失败回退:

function [x, ok, k] = newton_acdc(x0, S, maxit, tol) x = x0; ok = false; for k = 1:maxit F = residual(x, S); if norm(F, inf) < tol ok = true; return; end J = jacobian_acdc(x, S); dx = -J \ F; % 步长限制:单一状态量单步变化不超过阈值 step_scale = 1.0; for t = 1:length(dx) lim = S.step_limit(t); if abs(dx(t)) > lim step_scale = min(step_scale, lim / abs(dx(t))); end end dx = dx * step_scale; % 回溯线搜索:保证残差单调下降 lam = 1.0; for trial = 1:8 xn = x + lam * dx; Fn = residual(xn, S); if norm(Fn, inf) < norm(F, inf) break; end lam = lam * 0.5; end x = x + lam * dx; end end

步长限制里,相角和电压角的限制可以给宽一点(0.5 rad),电压幅值限制给 0.1 p.u.,触发角限制给 5°。这些数值不是拍脑袋,而是根据物理量的合理变化范围定的:一次牛顿迭代把某个母线电压从 1.0 拉到 0.3,那基本可以断定这一步是错的,限制住反而能走回来。

线搜索我一般只做 8 次折半,够用了。做太多次反而会掩盖问题——如果一个方向走 8 次都降不下来残差,那说明雅可比写错了或者初值离得太远,继续缩步长只是拖延时间。

4.4 解析雅可比与数值雅可比的交叉校验

写完解析雅可比,一定要和复步微分的结果对一遍。做法很简单:随机给一个非收敛点的状态向量,两个雅可比都算出来,逐元素比较相对误差,超过 1e-6 就打印出位置和两个值。

Jnum = numeric_jac_complex(x, @(xx) residual(xx, S), length(x)); Jana = jacobian_acdc(x, S); err = abs(Jana - Jnum) ./ max(abs(Jnum), 1e-8); [r, c] = find(err > 1e-6); for i = 1:length(r) fprintf('J(%d,%d) 解析=%g 数值=%g 相对误差=%g\n', ... r(i), c(i), Jana(r(i),c(i)), Jnum(r(i),c(i)), err(r(i),c(i))); end

这一步我在每个新算例上都会做,尤其是刚改完控制方程的时候。它能把"符号写反""漏了一个偏导项"这类问题在收敛失败之前就抓出来,比事后看着发散曲线猜原因高效得多。

5. 收敛异常时的排查链路与实测经验

5.1 初值给不好,第一步就发散

统一迭代对初值的敏感度比交替迭代高,因为所有变量绑在一起,一个变量的坏初值会污染整个系统。我的初值策略是分层给:

交流侧老规矩,电压幅值全给 1.0,相角全给 0,PV 节点电压按设定值给。直流侧要讲究一些:直流电压初值取额定值,直流电流初值按额定功率除以额定电压算,整流侧触发角初值给 15°,逆变侧熄弧角初值给 17°。

如果算例本身输送功率不高,这套初值基本都能一次收敛。如果输送功率接近极限,或者受端系统很弱,我会先做一个"降功率预计算":把直流功率指令打到额定值的 60%,解出来,再把结果作为 100% 功率的初值。这个技巧在多端直流里尤其有用,逐个直流节点往上推,比直接硬解稳得多。

还有一种情况是逆变侧定熄弧角、整流侧定功率,但触发角的初值给得太小(比如 5°)。这时候第一次迭代算出来的直流电压偏高,交流侧折算的无功偏小,节点电压被抬高,第二次迭代触发角又被拉得很低,来回几下就发散了。改成 15° 起步,问题消失。这类现象看着玄,其实就是方程在初值附近太"陡"。

5.2 标幺化基准不统一导致的假不收敛

这个坑我踩过好几次,而且症状特别迷惑:残差从 1e-1 降到 1e-3 就没法再降,迭代到 20 次依然卡着,看起来像是雅可比奇异,实际上是基准不一致。

常见的三种不一致:

第一种,直流侧电压基准和交流侧电压基准随手取的,导致换流器方程里的 K 值算出来是几百而不是个位数,雅可比矩阵里耦合块和主块量级差三四个数量级,条件数恶化。第二种,直流功率基准取了 100MW 而交流侧是 100MVA,两边功率换算出错。第三种,换相电抗 X_c 一边用有名值一边用标幺值,d_x 算出来的量级不对。

排查办法很土但有效:收敛失败时把 K、d_x、计算出的 V_d0 都打印出来,和手算的设计值对一下。十二脉动、500kV 直流、换流变变比 1.0 的典型情况下,K 应该在 1.0 到 2.0 这个量级,d_x 在 0.03 到 0.08 p.u. 这个量级。如果打印出来差了十倍,那八成是基准没统一,先把基准理清楚再谈收敛。

症状可能原因快速验证
残差卡在 1e-3 不降雅可比量级悬殊打印各分块范数对比
残差单调下降但只到 1e-4收敛判据的基准值不统一检查 dP 是标幺还是有名
迭代 2 步后 NaN根号内负数或除零给 tanφ、cosφ 加限幅
迭代次数突然从 4 变 15某块偏导符号反了复步微分交叉校验
收敛但功率不平衡换流功率的加减号方向错手工核算换流母线功率平衡

5.3 换流器方程越界与工程化的限幅

理想换流器方程在数学上对所有 α 都成立,物理上却只在 α 处于 5° 到 90°(整流)、γ 处于 15° 到 25°(逆变)这个区间内合理。迭代中间过程中 α 跑到负值或者超过 90° 是完全可能的,一旦跑出去,cos α 变号,直流电压跟着变号,整个方程组就乱套了。

我的处理是在残差函数里对 α 做软限幅:不直接把 α 钳死在边界上(那样会破坏牛顿法的收敛性),而是在越界时给残差加一个惩罚项。惩罚项的系数不能太大,取 1e2 量级,够把解拉回来,又不至于让雅可比病态。

另一个容易忽略的点是 I_d 的符号。直流电流在双端系统里只有一个方向,理论上不会变号,但迭代中间过程完全可能算出负值。负的 I_d 代进 P_ac = V_d·I_d 会让换流站变成"发电",注入功率符号反转,收敛点就跑偏了。我的做法是在残差里对 I_d 做下界保护,低于 0.05 p.u. 时加惩罚,同时给电流的牛顿步长限制在 0.2 p.u. 以内。

提示:这些限幅和惩罚都是为了让迭代"不跑飞",不是在修正模型。收敛之后一定要把惩罚项的输出打出来看,如果收敛点上惩罚项还非零,说明解本身是越界的,这时候要回头检查算例参数,别急着相信结果。

5.4 结果校验:不能只看残差降下去了

统一迭代收敛快,但它也会收敛到"数学上正确、物理上荒谬"的解,尤其是控制方式组合不当的时候。我一般做三层校验。

第一层,残差本身,要求无穷范数小于 1e-8,这个最基本。

第二层,功率平衡。每个换流母线的交流侧注入有功应该和直流侧输送功率对上,误差在 1e-4 p.u. 以内。所有换流站的直流功率总和,等于直流网络损耗加上两端有功之差。这一层能抓出符号错误和基准错误。

第三层,物理合理性。触发角应该落在 5° 到 20° 之间(正常整流运行),熄弧角 15° 到 20° 之间,换流母线电压偏差不超过 ±5%,功率因数角整流侧在 15° 到 25° 之间、逆变侧在 20° 到 30° 之间。任何一条越界,我都会停下来看看是不是控制方式选错了——比如整流侧定功率、逆变侧也定功率,两端功率指令不匹配,数学上照样能收敛,但解出来直流电流是个奇怪的数。

还有一个小技巧,是我自己常用来看结果质量的方法:把雅可比矩阵在收敛点再算一遍,看它的条件数。条件数在 1e4 以内基本正常,超过 1e6 就说明某些状态量的灵敏度太强,解虽然收敛但对参数扰动极其敏感,这种工作点在工程上其实没法用,得在报告里标注出来。

前面这套东西在双端系统上跑通之后,扩展到多端直流主要是三件事:直流网络方程从一行变成一个真正的节点导纳方程组、控制方式组合的配平规则要重新算、初值要用分步抬高功率的方式给。雅可比的分块结构反而不用大改,因为 J_AD 和 J_DA 永远是"换流站本地耦合",只有 J_DD 会随直流节点数增长。这也是统一迭代法在代码结构上比交替迭代舒服的地方——耦合关系是局部的,扩展起来不牵一发动全身。

最后分享一个我调参时的习惯:把所有状态量的迭代轨迹存下来,收敛失败时画出每个状态量随迭代次数的变化曲线,通常一眼就能看出哪个变量在抖。抖得最厉害的那个,八成就是方程写错位置的那个。这个习惯帮我抓出过好几次"把逆变侧方程写进了整流侧行号"的低级错误,比对着代码一行行找快得多。

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

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

立即咨询