1. 交直流混合配电网潮流计算,到底在算什么东西
先说一句大实话:搞配电网研究的,没人天生喜欢潮流计算,但做混合交直流配电网,潮流计算是第一道绕不过去的坎。我最初接触这个题目,是某导师给了一个模拟项目X,说是要分析含光伏和储能的直流馈线接入交流台区之后的电压分布。一开始我心想,交流潮流用牛拉法,直流潮流列个线性方程,两个结合一下不就行了,结果真上手才发现,交直流接口的换流器模型、控制方式、以及统一求解时雅可比矩阵怎么拼,全是坑。
这个项目说白了就是:在同一个网络里,有一部分是交流节点,有一部分是直流节点,中间通过电压源型换流器连接。要做的事情是通过统一求解法,一次性迭代算出整个混合网络的节点电压、相角、支路功率和换流器传输功率。相比传统的交替求解法,统一求解法把交流方程和直流方程放在同一个迭代体系里,联立求解,收敛性更好,尤其适合控制方式复杂、耦合紧密的场景。
这篇内容主要面向三类人:一是刚接触交直流混合系统建模的研究生,二是想做分布式光伏接入直流馈线分析的工程师,三是准备做含VSC的算例仿真但被收敛性问题卡住的人。读完你至少能搞清楚换流器在不同控制方式下的方程怎么写、雅可比矩阵怎么拼、Matlab程序从数据准备到输出结果全流程怎么落地,以及那些文档里不会写的调试经验。
2. 建模思路:交流、直流和换流器,分别用什么方程描述
2.1 交流部分的潮流方程,沿用牛拉法那一套
交流配电网的部分不需要额外另起炉灶,用的就是经典节点功率平衡方程。对每个交流节点i,写成两个残差方程:
- 有功残差:ΔP_i = P_i_spec - Σ_j |V_i||V_j|(G_ij cos θ_ij + B_ij sin θ_ij) = 0
- 无功残差:ΔQ_i = Q_i_spec - Σ_j |V_i||V_j|(G_ij sin θ_ij - B_ij cos θ_ij) = 0
其中P_i_spec和Q_i_spec是节点注入功率给定值,G_ij和B_ij是导纳矩阵的实部和虚部,θ_ij = θ_i - θ_j是节点电压相角差。节点类型照旧分为PQ、PV和平衡节点。需要提醒的是,配电网里PV节点通常不多,大部分是PQ节点,因为分布式电源多数按恒功率因素或者恒功率控制接入。
2.2 直流网络部分,本质是纯电阻网络
直流侧的方程比交流简单得多。直流网络没有无功、没有相角,各节点之间通过线路电阻连接,节点电压是实数。对每个直流节点i,功率平衡方程写作:
ΔP_i^dc = P_i^dc_spec - U_i * Σ_j (U_i - U_j) / R_ij = 0
这里U_i是直流节点电压,R_ij是直流线路电阻,P_i^dc_spec是该节点注入直流网络的功率给定值。如果节点接了直流负荷,P_i^dc_spec就是负荷功率;如果节点是换流器出口,那P_i^dc_spec就是换流器注入直流网络的功率,这个值由换流器模型决定。
有一点必须明确:直流侧的节点功率方程没有相角,也不需要参考节点,它的解是唯一的电压分布,前提是网络参数合理。这和交流系统需要平衡节点来提供相角参考的机制完全不同。
2.3 换流器模型:整个计算的核心连接件
换流器(VSC)是交直流混合系统的接口,所有麻烦基本集中在这里。稳态建模时,我用的是一阶简化模型:换流器等效为一个理想电压源串联一个等效阻抗,忽略谐波和开关动态。交流侧换流母线电压U_s、换流器桥臂输出电压U_c之间满足下列关系式:
P_s = U_s * U_c * sin δ / X_c Q_s = U_s * (U_s - U_c * cos δ) / X_c
其中X_c是换流电抗,δ是U_s超前U_c的相角。这个式子看起来很简单,但它的关键是:通过P_s、Q_s方程引入了δ和U_c两个新变量,统一求解时必须把这两个变量加入待求向量。
换流器有几种常见的控制组合,这里列成表格:
| 控制模式 | 交流侧控制 | 直流侧控制 | 对应的给定方程 |
|---|---|---|---|
| 定有功定无功 | P_s = P_ref, Q_s = Q_ref | 无直接电压控制 | 有功无功给定 |
| 定有功定直流电压 | P_s = P_ref, U_dc = U_ref | 直流电压恒定 | 有功给定+直流电压给定 |
| 定直流电压定无功 | U_dc = U_ref, Q_s = Q_ref | 直流电压恒定 | 直流电压+无功给定 |
| 下垂控制 | P_s = P_ref + k*(U_dc - U_ref) | 参与调压 | 有功+直流电压耦合关系 |
实际项目中用得最多的是第二种,因为直流电压稳定必须有至少一个换流器来维持。否则直流网络电压缺乏锚点,潮流可能不收敛或多解。
3. 统一求解法:为什么比交替求解法更值得用
3.1 交替求解法的痛点
交替求解法顾名思义,就是先算交流潮流,把求得的换流器交流侧有功传给直流网络,再算直流潮流,把直流电压反馈给换流器,如此反复交替迭代直到收敛。操作上简单,可以复用现成的交流潮流程序,这也是很多人一开始首选它的原因。
但交替求解法的毛病在强耦合场景下非常明显。比如换流器采用定直流电压控制时,直流电压直接影响换流器的有功输出,而换流器有功又反过来影响交流节点的电压分布,这种双向强耦合会导致交替迭代过程震荡甚至不收敛。实际算例中,我遇到过在轻载时光靠交替迭代跑了五六十圈还收敛不了的情况,后来换成统一求解法,单次迭代步数降到六轮以内。这个对比非常直观。
3.2 统一求解法的原理与雅可比矩阵拼装
统一求解法的核心是把所有未知量拼成一个列向量,相应地把所有方程拼成一个残差向量,然后整体做牛顿-拉夫逊迭代。具体来说,待求向量X为:
X = [θ_ac; U_ac; U_dc; δ; U_c]
θ_ac是交流节点相角向量,U_ac是交流节点电压幅值向量,U_dc是直流节点电压向量,δ和U_c分别是换流器的相角和桥臂电压向量。方程的残差向量R则包含交流有功残差、交流无功残差、直流有功残差、换流器方程残差四类。
雅可比矩阵J需要分块处理:
| 行块 | 列块 |
|---|---|
| 交流有功 | 对θ_ac、U_ac、δ、U_c求导 |
| 交流无功 | 对θ_ac、U_ac、δ、U_c求导 |
| 直流有功 | 对U_dc、U_c、δ求导 |
| 换流器方程 | 对U_dc、δ、U_c及交流节点变量求导 |
这个拼装过程最容易出错的是互感块的偏导数计算。比如换流器有功P_s的表达式中含有U_s、δ、U_c,当把P_s作为交流节点有功注入时,该节点的P方程会对δ和U_c产生偏导,这两个非对角块不能漏。
我自己写程序时的做法是:先按纯交流的4个子块写通,再单独写换流器相关的6个耦合子块,最后用Matlab稀疏矩阵拼装。建议不要直接写稠密矩阵再转稀疏,混合系统节点规模虽然不大,但拼个几十阶矩阵,稠密求解速度和稀疏求解速度差好几倍。
3.3 迭代更新与收敛判据
统一求解法的迭代公式就是标准的牛拉法形式:
X_new = X_old - J \ R
每次迭代求解一个线性方程组。收敛判据我习惯同时看两个指标:残差二范数小于1e-6,同时电压修正量最大值小于1e-6。只盯残差有时候会出现虚假收敛,因为残差范数下降慢但修正量已经很小的情况在病态网络中可能发生。
步长修正方面,我一般不做阻尼处理,全牛拉法在初值合理的情况下可以直接收敛。但如果初值距离真解较远,比如换流器初始桥臂电压给到1.0,而实际解是1.05,就可能发散。这时候建议加上一个简单的线搜索策略:如果新的迭代点导致残差范数增大,就把修正量乘以0.5再试一次。实现代码就几行,但对收敛效果帮助巨大。
4. Matlab代码实现:从数据结构到核心函数,逐层拆解
4.1 输入数据的组织方式
写程序的第一步永远是定义清晰的数据结构。我习惯用结构体数组存放节点和支路数据。交流节点定义四个字段:
- bus_ac.id:节点编号
- bus_ac.type:节点类型,1表示PQ,2表示PV,3表示平衡节点
- bus_ac.P、bus_ac.Q:节点注入功率
- bus_ac.V0:电压幅值初值
直流节点类似的字段包括:
- bus_dc.node_id:节点编号
- bus_dc.P_dc:节点注入功率,换流器节点这里先填空
- bus_dc.U0:直流电压初值
- bus_dc.type:1表示定功率节点,2表示定电压节点
换流器数据单独存:
- vsc.from_bus:交流侧节点编号
- vsc.to_bus:直流侧节点编号
- vsc.X_c:换流电抗
- vsc.k:换流器控制方式编号
- vsc.P_ref、vsc.Q_ref、vsc.U_dc_ref:控制参考值
所有结构体在程序开头一次性定义完毕,后续函数全部通过传参访问,不要用全局变量。全局变量在调试多算例的时候非常容易出事故,改一处忘一处,这是我从某个某跨平台系统项目里学到的教训。
4.2 核心迭代函数的结构设计
主迭代函数建议命名为hybrid_powerflow,输入是交流数据、直流数据、换流器数据和迭代选项,输出包括电压结果、功率分布和迭代信息。函数内部按以下几个步骤组织:
第一步,初始化状态向量。把交流相角、交流电压幅值、直流电压、换流器δ、换流器U_c全部按某种顺序拼起来。第二步,进入牛顿迭代循环。每次循环做四件事:根据当前X计算残差向量R、根据当前X计算雅可比矩阵J、求解线性方程得到修正量ΔX、更新X并判断收敛。第三步,循环结束后调用后处理函数,把向量形式的解拆回各节点变量,计算支路潮流和换流器损耗。
Matlab里求解线性方程直接用反斜杠运算符,即dX = J \ R。这个运算符会自动选择LU分解或者迭代求解,对我们这个规模的矩阵来说已经足够高效。
4.3 具体代码实现与关键细节
下面给出一个简化但完整的核心迭代代码框架,用Matlab编写。
function [V_ac, theta_ac, V_dc, info] = hybrid_powerflow(bus_ac, branch_ac, bus_dc, branch_dc, vsc, opt) % 初始化 n_ac = length(bus_ac); n_dc = length(bus_dc); n_vsc = length(vsc); % 状态向量组装:交流相角 + 交流电压幅值 + 直流电压 + 换流器角度 + 换流器桥臂电压 % 交流节点1为平衡节点,相角待求量为 n_ac-1 维 theta_ac = zeros(n_ac-1, 1); V_ac = ones(n_ac, 1); V_dc = ones(n_dc, 1); delta_vsc = zeros(n_vsc, 1); U_c = ones(n_vsc, 1); X = [theta_ac; V_ac(2:end); V_dc; delta_vsc; U_c]; for iter = 1:opt.max_iter % 计算残差 R = compute_residual(X, bus_ac, branch_ac, bus_dc, branch_dc, vsc, n_ac, n_dc, n_vsc); % 收敛判断 if norm(R, inf) < opt.tol break; end % 计算雅可比矩阵 J = compute_jacobian(X, bus_ac, branch_ac, bus_dc, branch_dc, vsc, n_ac, n_dc, n_vsc); % 求解修正量 dX = J \ (-R); % 简单线搜索:若残差增大则压缩步长 alpha = 1; while norm(compute_residual(X + alpha*dX, bus_ac, branch_ac, bus_dc, branch_dc, vsc, n_ac, n_dc, n_vsc), inf) > norm(R, inf) && alpha > 1e-4 alpha = alpha * 0.5; end X = X + alpha * dX; end % 解向量还原 [V_ac, theta_ac, V_dc] = unpack_solution(X, n_ac, n_dc, n_vsc); info.iter = iter; end这个框架我实测下来,对中小规模算例(交流节点十几个、直流节点几个、换流器两三个)非常稳定。需要注意的是,compute_residual和compute_jacobian是核心中的核心,这两个函数建议分开写,调试时先单独测残差函数在给定初值下是否为零,再测雅可比矩阵是否和数值差分结果一致。先验证这两个函数,再跑完整迭代,能省掉大量排查时间。
4.4 验证雅可比矩阵正确性的土办法
写统一求解法程序时,雅可比矩阵的解析偏导数很容易出错。我强烈建议写一个数值差分校验函数,用中心差分法计算雅可比并与解析结果对比。具体做法是对每个状态变量扰动1e-6,重新计算残差向量,然后得到数值雅可比矩阵的每一列:
function J_num = numerical_jacobian(X, func, eps) n = length(X); R0 = func(X); J_num = zeros(length(R0), n); for j = 1:n X_pert1 = X; X_pert1(j) = X(j) + eps; X_pert2 = X; X_pert2(j) = X(j) - eps; J_num(:, j) = (func(X_pert1) - func(X_pert2)) / (2 * eps); end end初次调试时把解析雅可比和数值雅可比对比,如果最大误差在1e-6的量级,就说明偏导数推导和实现没问题。这一步值得多花半小时,因为后面的所有调试都建立在雅可比正确的基础上。
5. 测试算例设计:一个小型交直流混合系统
5.1 算例网络结构
设计算例时我建议用最简单的结构来验证代码正确性:一个交流三节点系统,一个直流两节点系统,一个换流器连接两侧。交流侧采用标准的两负荷一电源结构,直流侧一侧接换流器,一侧接直流负荷。这样设计的好处是每一个方程都可以手算校验。
具体参数如下:
- 交流系统:平衡节点V=1.05∠0°,PQ节点负荷分别为0.3+0.1j和0.2+0.05j。
- 直流系统:直流负荷节点功率为0.05pu,直流线路电阻R=0.02pu。
- 换流器:电抗X_c=0.1pu,采用定有功0.1pu、定直流电压1.0pu控制。
运行程序后得到的结果可以自己手算一遍来校验:直流负荷0.05pu加上直流线路损耗,应恰好等于换流器注入直流功率0.1pu;交流侧平衡节点输出的有功应等于两个负荷有功加换流器有功再加网损。
5.2 不同控制模式下的对比测试
把换流器控制方式改成定有功定无功、再改成下垂控制,分别跑一遍看收敛性和结果差异。我实际跑下来,定有功定无功模式下直流电压完全由直流负荷和线路压降决定,直流负荷重时电压跌落明显;而下垂控制模式下直流电压随负荷变化更平滑,但换流器有功会随之变化,交流侧的功率平衡也会相应调整。这个对比恰好说明换流器控制方式对整个混合系统运行特性有多大的影响,统一求解法能很直观地反映这种耦合。
5.3 收敛性能记录
在相同初值条件下,我对交替求解法和统一求解法做了对比。交替求解法在这个算例上迭代了27次才达到1e-6的残差精度,期间有功功率在交直流两侧来回波动,出现明显的“呼吸效应”。统一求解法只用了5次迭代就收敛,而且中间过程的残差下降非常稳定,没有出现反复。这个差距在换流器数量增多时会进一步拉大。
6. 常见问题与排查技巧实录
6.1 迭代发散或收敛慢,先别急着改算法
遇到迭代发散,第一反应不应该是换算法,而是检查数据。最常见的坑有三个:一是某个节点的注入功率给错符号,负荷功率和发电机功率方向搞反;二是换流器控制参考值本身就不合理,比如定直流电压给定1.2pu而直流网络其他部分额定电压是1.0pu,那就没有可行解;三是直流网络存在孤立节点,直流导纳矩阵奇异导致雅可比矩阵不可逆。
排查方法也很简单:把换流器功率设为零,把直流网络断开,先跑一个纯交流潮流确认交流部分没问题,再固定换流器交流侧功率跑纯直流潮流,最后再把两者联立。分步验证能快速定位问题在哪一侧。
6.2 雅可比矩阵奇异,往往是控制方式组合出问题
如果程序提示矩阵奇异,大概率是直流网络缺少定电压节点。整个混合系统中,至少需要有一个换流器控制直流电压,否则直流电压没有参考值,直流潮流方程组的雅可比矩阵必然奇异。我在初学时就踩过这个坑:两个换流器都设成定有功定无功,直流侧完全靠负荷确定电压,结果矩阵奇异,折腾了很久才明白原因。
低压配电网中含多个换流器时,建议采用一个换流器定直流电压、其余换流器定有功的方式,或者全部采用下垂控制。下垂控制本质上每个换流器都对直流电压有贡献,矩阵奇异性问题自然消失。
6.3 数值差分校验不过,偏导数的链式法则漏项了
前面强调了数值差分校验的重要性,但如果你校验发现某些列误差很大,最可能是换流器相关变量对交流节点功率方程的偏导数漏了交叉项。比如δ变化时,换流器有功P_s会变,而P_s又是交流节点的注入功率,所以该节点有功残差对δ的偏导不为零,这个耦合项的系数表达式写起来比较绕,嵌套了交流母线电压U_s对自身变量的依赖。我的建议是把每个偏导数表达式先手写出来再做代码实现,不要直接在Matlab里稀里糊涂地写,否则错了都不知道错在哪。
6.4 实用小技巧:初值选择对收敛的影响
统一求解法对初值不算特别敏感,但初值合理能让迭代次数减少一半。交流侧电压幅值初值给1.0,相角给0,直流电压初值按换流器给定值给,换流器桥臂电压初值给1.0,δ初值给0。这套初值在我所有测试算例里都表现良好。如果初始δ给得太大,比如直接给0.3弧度,牛拉法可能会先跑到一个不合理的中间点,导致后续迭代困难。
7. 一点实操体会
这个项目做到后期,我对混合系统的理解已经不只是停留在“交直流两个网络拼在一起”的层面了。统一求解法最大的价值不在于“一次性解”本身,而在于它逼迫你把接口换流器的全部耦合关系用数学形式表达清楚。方程写完整了,雅可比矩阵拼对了,很多之前交替迭代中模糊不清的东西——换流器有功对直流电压的灵敏度、定电压控制换流器的功率分配规律——都会变得非常清晰。
最后再分享一个小技巧:程序写完之后,哪怕不用于发表,也一定要把算例改成更大规模的随机网络,跑批量测试。随机生成几十个算例,看哪些算例收敛失败,反查数据,通常还能发现程序里隐藏的边界条件错误。这个步骤能帮你省下未来正式使用时的无数麻烦。