
分布式电源并网以后配电网故障定位的难度比想象中提升了一个量级。最近我在复现一个配电网故障定位仿真时把几个分布式电源DG节点接进了一个10kV辐射状馈线模型结果原来百试百灵的过流矩阵法开始出幺蛾子明明故障发生在线路段2-3定位结果却飘到了4-5甚至直接报盲区。顺着这个现象我把“分布式电源对配电网故障定位的影响”用Python完整搭了一套仿真今天把整个思路、代码和结论都拆开来讲。这个项目适合正在做配电网保护、馈线自动化或电力系统研究的人参考不需要你有很高的编程门槛会基础的Python循环和列表操作再有一点电路概念就能跟着复现出来。项目本身并不追求建立一个完整精确的电磁暂态模型而是用工程上常用的短路电流计算思想把“DG引入后电流走向发生变化”这个核心物理过程用代码形式表现出来。看完之后你会明白为什么加了几个分布式电源原来成熟的定位算法会失效哪些情况下影响大哪些情况下影响小以及在实际工程中该用什么思路规避这些问题。1. 分布式电源并网后故障定位为什么不再“想当然”1.1 传统配电网故障定位的基本逻辑传统配电网是典型的单电源辐射状网络变电站是唯一的电源电能从变电站出发沿开关、线路、分支流向各个负荷。在这种结构下如果线路上发生短路故障短路电流的方向只有一个从变电站流向故障点。这就像一条单向通行的马路某个路段封路后交警只要知道哪些卡口看到的车流异常就能把故障点圈在两个卡口之间。工程上常用的过流矩阵定位法就是把这种思路形式化。它把配电网的开关、节点、线路抽象成一个网络描述矩阵反映各支路之间的上下游关系当某处发生故障馈线终端单元FTU上报哪里出现过流、哪里没有系统形成一个故障信息矩阵。两个矩阵一对照就能锁定故障区段。在DG接入之前这套逻辑非常可靠。因为故障电流路径唯一过流节点一定在故障点上游非过流节点一定在故障点下游边界就是故障区段。哪怕是配电网结构复杂、有多条分支只要网络描述矩阵建得对定位结果一般不会跑偏。1.2 DG 接入改变了什么从单电源到多电源分布式电源接入后配电网不再只有一个电源。光伏、风机、燃气轮机、储能系统都会在电网故障期间向故障点注入电流。如果故障发生在变电站和DG之间的线路上故障点会同时收到来自变电站和多个DG的电流如果故障发生在DG下游DG还会“逆向”向上游送流。不同DG类型的短路电流特性差别很大。直接并网的同步发电机故障电流可以达到额定电流的4到10倍对短路电流分布影响非常明显鼠笼异步电机虽然自身没有励磁但在故障初瞬也会提供一定衰减的短路电流而逆变型DG光伏、储能等由于电力电子装置过流能力有限短路电流通常被限制在额定电流的1.2到2倍左右。但别小看这“一点几倍”它照样可以把原本单向的故障电流变成双向流动把定位逻辑彻底搅乱。我把几种常见DG的故障电流特征整理成了下面的表格方便快速了解差异DG类型短路电流倍数对故障定位的影响特点同步发电机4~10倍额定电流助增明显可能引起更多开关过流异步发电机初期3~5倍随后衰减暂态影响大稳态影响减弱逆变型DG光伏/储能1.2~2倍额定电流电流小但方向反转仍会造成误判1.3 影响故障定位的三条主要路径结合我的项目经验DG对故障定位的影响可以归纳成三个方面。第一故障电流幅值变了。DG向故障点注入电流相当于给故障点增加了额外“援兵”。原来不会过流的某些非故障支路现在可能因为DG助增而过流导致过流节点范围扩大。过流整定值如果仍然按无DG情况设定就可能出现保护误动或拒动。第二故障电流方向变了。这是最要命的一点。传统定位算法默认故障电流全部从变电站单向流向故障点一旦故障点下游的DG反向注入故障点两侧都会出现过流。如果一个定位算法只关心“有没有过流”而不关心“方向是什么”它就会把故障误判到下游很远的位置或者干脆发现所有支路都过流无法区分故障位置。第三网络拓扑的有效性变了。DG是间歇性电源可能随光照、风速和运行方式投切。同一套物理网架在不同的DG投运组合下实际运行拓扑是不同的。如果定位算法仍然使用固定拓扑矩阵运算就会建立在错误的结构上。很多系统在工程现场出现定位偏差不是算法本身有问题而是没有实时更新运行拓扑。本项目的Python仿真主要针对前两条展开重点观察方向反转和过流范围扩大这两类现象。2. Python仿真模型的整体设计思路2.1 配电网电气模型怎么搭仿真第一步是搭一个最简单的配电网模型。为了保证现象足够直观我没有用复杂的真实馈线结构而是用一条6段链式馈线节点0作为变电站母线节点1到节点6依次为线路节点。这样做的目的是让“哪条支路过流、哪条支路反向过流”一目了然。分支型辐射状网络本质上也是多个链式结构的组合原理完全一样代码可以平滑扩展。电气计算采用标幺值。基准电压取10kV基准容量取100MVA。标幺值的好处是数值范围统一不会出现一个支路电流上万安培、另一个只有零点几安培这种难以比较的情况。线路阻抗、DG注入电流全部换算成标幺值后再叠加。我用一个列表保存所有线路每一行代表一条支路格式是起始节点、终止节点、电阻标幺值、电抗标幺值。这里没有单独建负荷模型因为在短路分析中负荷电流相比短路电流很小通常可以忽略。DG则视为故障期间的电流源它在故障时按自身容量和类型向网络注入一定倍数的额定电流。2.2 故障类型与DG模型的选择本项目的故障类型选择三相短路。三相短路是分析故障定位最常用的算例因为它的故障电流最大对过流式定位算法的影响最明显。单相接地短路、两相短路在电气特征上各有特点但“DG提供额外电流并改变方向”这一核心影响是一致的。DG模型采用简化的电流源模型每个DG在故障期间的注入电流大小等于它的额定容量乘以一个短路电流倍数系数k。同步机型k取5.0逆变型k取1.5。这种做法确实省去了内阻抗、控制策略等细节属于教学演示层面的简化。它的优势是代码简单、现象清晰特别适合做机理分析如果你要做工程整定计算就得用电磁暂态仿真软件或者至少用节点阻抗矩阵算一遍完整的故障电流分布。2.3 选型路径叠加法短路电流的标准计算方法是节点阻抗矩阵法原理是用Ybus矩阵求逆得到Zbus再根据故障节点计算各节点电压和支路电流。这个方法精度更高但代码量相对大对新手不太友好。我在项目里换了一种“路径叠加法”。路径叠加法的思路是在辐射状网络中任意一个电源要往故障点送电流路径是唯一的。主电源从变电站出发DG从其接入节点出发各走各的唯一路径抵达故障点。每条支路上最终流过的故障电流等于所有经过这条支路的电源贡献电流的代数和。方向与参考方向一致记为正方向相反记为负。这个模型不精确但对研究“DG在故障点下游会怎样反向送流”这类问题非常合适。它把物理过程拆成一条一条路径每一步都能清晰解释电流从哪来、到哪去。在后面的代码里你会看到每一行累加结果都可以对上网络拓扑。3. Python代码实现全流程3.1 基础参数准备先把网络拓扑、DG配置、系统基准参数写清楚。我的示例网络是0-1-2-3-4-5-6的单链结构每一段线路用一组标幺值电阻和电抗表示。DG配置在节点3和节点6容量分别取2000kVA和5000kVA其中节点6的DG容量更大、k系数取5.0用来模拟同步机型。import numpy as np from collections import defaultdict # 基准值 V_base 10.0 # kV S_base 100.0 # MVA Z_base V_base ** 2 / S_base # 欧姆此处Z_base 1.0 # 线路列表(首端, 末端, 电阻标幺值, 电抗标幺值) lines [ (0, 1, 0.020, 0.140), (1, 2, 0.018, 0.120), (2, 3, 0.015, 0.100), (3, 4, 0.018, 0.110), (4, 5, 0.016, 0.100), (5, 6, 0.014, 0.090) ] # 支路编号对应的节点对用于结果展示 line_nodes [(u, v) for u, v, r, x in lines] # DG配置列表 dg_list [ {node: 3, kva: 2000, k: 1.5}, # 逆变型 {node: 6, kva: 5000, k: 5.0} # 同步机型 ] # 主电源在故障时的注入电流标幺值先设为1.0 I_source 1.0这里需要注意线路阻抗标幺值我写得比较小因为10kV短线路在100MVA基准下本身就不大。DG容量换算成标幺值时2000kVA就是0.02pu再乘以k1.5得到0.03pu5000kVA是0.05pu乘以5.0得到0.25pu。有了这些数值后面电流叠加才有一个清晰的数量级。3.2 路径搜索与故障电流分配接下来实现路径搜索。配电网是辐射状网络所以任意两个节点之间的路径只有一条。我用一个递归函数从电源节点出发向故障节点搜索返回经过的节点序列。这个函数不依赖具体网络参数以后换网络只需改lines列表。# 构建邻接表 graph defaultdict(list) for u, v, r, x in lines: graph[u].append(v) graph[v].append(u) # 递归寻找路径start和end之间最多只有一条路径 def find_path(start, end, visitedNone): if visited is None: visited set() visited.add(start) if start end: return [start] for node in graph[start]: if node not in visited: path find_path(node, end, visited.copy()) if path: return [start] path return None有了路径就能进行电流累加。主电源从节点0开始DG从自身接入节点开始。每一步找到电源到故障节点的路径把路径上经过的支路找出来。方向与支路参考方向相同记为正方向相反记为负。所有电源贡献累加后就得到每条支路的净电流。# 支路参考方向映射 branch_ref {} for i, (u, v, r, x) in enumerate(lines): branch_ref[(u, v)] i def compute_branch_currents(fault_node, dg_list, I_source1.0): # 收集所有电源 sources [{node: 0, I: I_source}] for dg in dg_list: I_dg (dg[kva] / 1000.0) / S_base * dg[k] sources.append({node: dg[node], I: I_dg}) branch_current np.zeros(len(lines)) for src in sources: path find_path(src[node], fault_node) if path is None: continue for a, b in zip(path[:-1], path[1:]): if (a, b) in branch_ref: idx branch_ref[(a, b)] direction 1 elif (b, a) in branch_ref: idx branch_ref[(b, a)] direction -1 else: continue branch_current[idx] direction * src[I] return branch_current这里最关键的一个操作是方向符号。每条支路的参考方向都定义为“从首端流向末端”也就是从变电站流向线路末端。DG从节点6反向流向故障点3时路径是6、5、4、3对应支路5-6、4-5、3-4实际电流方向是节点6到节点5、节点5到节点4、节点4到节点3与参考方向完全相反所以累加时系数是负值。3.3 两种定位判据幅值法 vs 方向法定位判据是本项目对比的核心。我写了两个函数一个只用电流幅值模拟传统过流定位另一个同时使用幅值和方向模拟带方向判据的定位逻辑。I_th 0.01 # 过流阈值标幺值 def locate_by_magnitude(branch_current): over_list [i for i, cur in enumerate(branch_current) if abs(cur) I_th] if len(over_list) 0: return 无过流信息无法定位 if len(over_list) len(branch_current): return 所有支路均过流幅值法无法定位 last_over max(over_list) return f故障位于支路{line_nodes[last_over]}下游附近 def locate_by_direction(branch_current): last_positive None first_negative None for i, cur in enumerate(branch_current): if cur I_th: last_positive i for i, cur in enumerate(branch_current): if cur -I_th: first_negative i break if last_positive is None: return 未发现正向过流无法定位 if first_negative is not None: return f最后一个正向过流支路是{line_nodes[last_positive]}第一个反向过流支路是{line_nodes[first_negative]}故障在其边界附近 return f故障位于支路{line_nodes[last_positive]}下游附近幅值法只看电流绝对值是否超过阈值不关心方向。方向法则关注两个关键边界最靠近电源侧的正向过流支路和最靠近电源侧的反向过流支路。在故障点处正向过流支路的下游端与反向过流支路的上游端正好对应故障附近。从代码可以看出方向法本质上是对过流信息做了一次“去噪”即使故障点下游所有支路都有反向电流只要网络拓扑没有错最后一个正向和第一个反向之间的边界一定锁定在故障点附近。3.4 运行与结果输出下面把三种故障点的情况跑一遍分别在无DG和有DG两种配置下输出定位结果。运行代码时我会打印每条支路的电流幅值和方向方便对照。# 无DG基线 print( 无DG时故障点在节点3 ) cur compute_branch_currents(3, []) for i, c in enumerate(cur): print(f支路{line_nodes[i]}: 电流{c:.3f}) print(幅值法:, locate_by_magnitude(cur)) print(方向法:, locate_by_direction(cur)) print(\n 有DG时故障点在节点3 ) cur compute_branch_currents(3, dg_list) for i, c in enumerate(cur): print(f支路{line_nodes[i]}: 电流{c:.3f}) print(幅值法:, locate_by_magnitude(cur)) print(方向法:, locate_by_direction(cur))围绕这个核心代码你还可以继续扩展可视化。比如用matplotlib画一张支路电流柱状图正值为正向电流、负值为反向电流会在图上非常直观地看到“故障点两侧电流方向不同”的分布规律。画图代码如下import matplotlib.pyplot as plt node_labels [f{u}-{v} for u, v in line_nodes] plt.figure(figsize(8, 4)) plt.bar(node_labels, cur, color[steelblue if c 0 else tomato for c in cur]) plt.axhline(0, colorblack, linewidth0.8) plt.ylabel(故障电流标幺值) plt.title(各支路故障电流分布) plt.grid(axisy, linestyle--, alpha0.6) plt.show()我实际跑下来柱状图里最醒目的就是故障点两边一边全是蓝色正向电流、一边全是红色反向电流。这比自己只看干巴巴的数字更容易理解DG的影响机理。4. 仿真结果DG对故障定位的影响有多大4.1 无DG时的基线结果先看没有DG接入时故障点设在节点3的情况。我运行上面的代码得到的支路电流分布非常干净支路电流标幺值方向0-11.000正向1-21.000正向2-31.000正向3-40.000无4-50.000无5-60.000无幅值法认为故障在支路2-3下游附近方向法给出同样的结论。这个结果符合传统认知故障电流从变电站出发一路经过0-1、1-2、2-3三条支路到故障点后入地下游支路完全没有电流。过流区段的边界在2-3和3-4之间定位清晰。4.2 有DG后的结果对比接入配置好的两个DG后同样在节点3发生三相短路情况就变了。此时节点3故障节点6的DG容量大、电流贡献也大它送出的电流路径是6-5-4-3依次经过支路5-6、4-5、3-4方向与参考方向相反。节点3的另一个2000kVA逆变型DG因为正好在故障节点上其电流直接进故障点不会流经支路所以对支路电流分布影响较小。我把有DG时故障点3的运行结果列在下面支路电流标幺值方向0-10.970正向1-20.970正向2-30.970正向3-4-0.250反向4-5-0.250反向5-6-0.250反向注意2-3支路的电流从1.0变成了0.97因为主电源的1.0和节点6DG的0.25在支路2-3上方向相反、部分抵消。但净电流仍然正向过流阈值I_th设得很低所以它仍被判定为正向过流。真正的关键变化在3-4、4-5、5-6这三条支路它们全部出现了方向相反的故障电流。此时幅值法看到的情况是所有6条支路电流绝对值都超过阈值故障点上游有正向过流故障点下游有反向过流但幅值法只统计“有没有过流”它就会输出“所有支路均过流幅值法无法定位”。这就是DG接入后传统定位算法最典型的表现过流区段被DG反向电流“拉满”定位直接失效。方向法给出的结果则是最后一个正向过流支路是2-3第一个反向过流支路是3-4故障位于这两个支路的边界附近。这实际上就是节点3所在的位置。方向法的定位是正确的说明在DG接入后只要定位算法引入方向信息就能抵抗很大一部分反向电流的干扰。4.3 影响程度与系统参数的关系我在项目里还做了参数敏感性分析调整主电源注入电流和DG容量观察定位结果怎么变化。当DG电流相对主电源电流足够大时连上游共同支路都可能被反向电流“反超”方向法也会失灵。比如主电源注入电流降到0.5DG注入电流达到0.75那么支路1-2上的净电流就是0.5减去0.75结果是-0.25方向变成反向。此时方向法看到的第一个反向支路变成了1-2而不是故障点附近的3-4定位反而被引到上游。这表明影响程度取决于三个核心因素DG容量以及对应的短路电流倍数、DG接入位置、故障点相对位置。具体规律如下DG在故障点上游且路径与主电源一致只会增大故障电流幅值方向不改变对定位影响相对小但过流范围可能扩大。DG在故障点下游并向故障点反向送流会产生反向过流区段对幅值法冲击最大方向法仍能判断。DG容量占比越高、主电源短路容量越低上游共同支路发生电流反转的概率越大方向法也可能失效。这三种情况可以用一句话概括故障点下游的DG才是定位算法的“天敌”。5. 常见问题与实战排查建议5.1 仿真中容易踩的坑这个项目代码量不大但有几个地方很容易出错我逐一记录一下。第一路径搜索的方向写反。find_path函数返回的序列是电源节点到故障节点如果我在累加时把a、b顺序搞反方向符号就会全部出错。建议在代码里先打印一条路径逐手对照线路参考方向再继续累加。第二标幺换算的单位坑。DG容量是kVA除以1000才是MVA再除以基准容量100MVA得到标幺值。如果忘记除1000注入电流会虚高百倍定位结果自然完全失真。这个错误非常隐蔽因为程序不会报错只会在结果上让你摸不着头脑。第三过流阈值设置不合理。I_th设得太大比如0.5可能把一些真实的过流支路滤掉设得太小比如0.001又可能把数值噪声放大。建议先看一遍无DG基准结果让阈值能正确区分“有过流”和“无电流”两种状态。第四忽略DG电流限制。逆变型DG自身过流能力有限代码中k值如果随意取10结果会夸大到失真。不同DG类型要按实际短路特性取值同步机取4~8逆变型取1.2~2是比较合理的区间。5.2 工程实践中如何削弱DG对定位的影响从仿真结论出发工程上至少有四条路可以走。一是引入方向判据。FTU不仅上报“是否过流”还上报“过流方向”定位算法把反向过流单独作为边界条件。这是最直接、成本最低的做法本项目的方向法已经验证了有效性。二是动态更新拓扑。DG投切信息要实时同步到故障定位系统。配电网运行方式发生变化后网络描述矩阵必须重新生成否则算法基于错误拓扑计算结果必然出错。三是按DG类型分别处理。对同步机型DG短路电流很大必须纳入故障电流计算对逆变型DG虽然短路电流受限但方向反转仍然存在不能因为它“电流小”就忽略。四是对于高渗透率场景采用更高级的定位手段。比如基于同步相量量测的广域定位或者行波法定位。这些方法对故障电流方向不敏感抗分布式电源干扰的能力更强。5.3 后续可扩展的方向这个Python仿真框架虽然简单但扩展性很好。你可以把链式网络换成带有更多分支的典型馈线模型或者导入真实的配电网拓扑数据观察更多节点下的定位表现。更深入一些可以把三相短路扩展到单相接地故障重点分析零序电流在DG影响下的变化。也可以把恒定的电流源DG模型换成带内阻抗的电压源模型用节点阻抗矩阵法重新计算故障电流分布这样结果更接近工程实际。我个人在这套仿真里最有价值的收获是理解了“方向反转”这一核心机制。很多关于分布式电源影响配电网保护的论文里反复强调“潮流可能反向”但只有亲手用代码把每一条DG路径的电流累加到支路电流上看到那排负数出现在故障点下游支路上才会真正明白这件事为什么会让传统定位算法失效。建议你在跑完这个项目后再回头去看相关的保护配置规程你会发现那些条文背后都是类似的物理过程。最后再分享一个小技巧做这类仿真时一定要先跑通无DG基线确认定位算法本身没有Bug再逐步把DG接入进来。每增加一个DG就打印一次各支路电流的方向观察哪些支路变化、哪些支路不变。这个习惯能帮你很快定位问题是出在算法逻辑还是出在DG参数设置上。如果遇到结果不合理的情况优先怀疑标幺值换算和方向符号十次里有八次都是这两个地方出问题。