短路计算程序_python3:从手算到代码,电力系统分析的第一块硬骨头

发布时间:2026/10/14 11:05:37
短路计算程序_python3:从手算到代码,电力系统分析的第一块硬骨头
简介这份资源是一套面向电力系统方向学生与工程师的短路电流计算工具采用Python3实现支持按需添加任意节点并配有交互式界面用于评估设备承受短路电流的能力、辅助保护系统设计。压缩包共3个文件以2个py脚本和1个txt参数文件为主整体约18KB主程序承载短路计算的核心算法与逻辑界面脚本负责参数输入与结果展示文本文件则存放线路电阻、电抗等基础参数便于按实际电网规格替换。目前已有888人学习下载说明其在电力系统短路计算学习中具有一定参考价值。读者可借此理解三相短路、两相短路、单相接地短路等典型场景的计算思路掌握节点电压、线路阻抗、发电机容量等参数的录入方式并参考其数值计算与可视化组织方法快速搭建自己的短路分析流程适合作为课程设计、毕业设计或工程入门阶段的实践参考。1. 短路计算程序_python3从手算到代码电力系统分析的第一块硬骨头做电气设计或者电力系统分析的人迟早会撞上短路计算这道坎。手算一次两条母线的短路电流还能忍一旦节点数上到十几二十个阻抗矩阵手推就变成了体力活错一个符号整条线路的结果全废。短路计算程序_python3 这个方向本质就是用 Python 把节点阻抗矩阵的构建、故障点注入、电压电流求解这条链路自动化让原本半天的活压缩到几秒钟而且改一个参数就能重跑。它适合两类人一类是电气专业的在校生或刚入行的工程师需要反复验证手算结果另一类是做继电保护整定、设备选型的从业者需要快速批量算出不同运行方式下的短路电流。这篇文章不讲空泛的电力系统理论只讲怎么用 Python 把这件事跑通参数怎么设哪里容易翻车。2. 短路计算的核心链路从单线图到节点阻抗矩阵2.1 为什么用节点阻抗法而不是回路电流法短路计算的主流方法有两类回路电流法和节点阻抗法。回路电流法需要先选独立回路对于环网和多重回路回路选择本身就容易出错而且每改一次网络结构就要重新选回路。节点阻抗法的思路更直接把网络抽象成节点和支路构建节点导纳矩阵求逆得到节点阻抗矩阵故障点的短路电流就是故障前电压除以故障点自阻抗。这个方法的优势在于网络结构变化时只需要改导纳矩阵的对应元素不需要重新推导公式。我一般会推荐节点阻抗法作为 Python 实现的首选原因有三个。第一矩阵操作在 NumPy 里就是几行代码不需要手写复杂的回路搜索逻辑。第二节点阻抗矩阵的物理意义清晰对角元素就是各节点的自阻抗非对角元素是互阻抗调试时可以直接对照手算结果。第三扩展性强后面要加发电机模型、变压器变比调整、负荷影响都是在导纳矩阵上做文章不用推翻整个框架。节点阻抗法的数学基础是对网络列写节点电压方程 I Y·U其中 Y 是节点导纳矩阵U 是节点电压列向量I 是节点注入电流列向量。求逆得 U Z·IZ Y⁻¹ 就是节点阻抗矩阵。当节点 k 发生三相短路时相当于在节点 k 注入一个电流 -I_f使得节点 k 的电压降为零。由此可以推出短路电流 I_f U_k(0) / Z_kk其中 U_k(0) 是故障前节点 k 的电压Z_kk 是节点阻抗矩阵的第 k 个对角元素。这个公式是整个程序的核心后面所有的代码都是围绕它展开的。理解了这个公式再看代码就不会觉得是在看黑匣子。2.2 用 NumPy 构建节点导纳矩阵的最小实现节点导纳矩阵的构建规则很固定对角元素 Y_ii 等于连接在节点 i 上所有支路导纳之和非对角元素 Y_ij 等于节点 i 和节点 j 之间支路导纳的负值。如果两个节点之间没有直接支路Y_ij 为零。对于变压器支路需要考虑变比的影响导纳要折算到某一侧。下面是一个最小可运行的实现支持纯线路网络和带变压器的网络。代码里用字典描述支路每条支路包含首节点、末节点、阻抗和可选的变比。import numpy as np def build_ybus(nodes, branches): 构建节点导纳矩阵 nodes: 节点名称列表如 [N1, N2, N3] branches: 支路列表每条为 dict: {from: N1, to: N2, z: 0.10.3j, tap: 1.0} tap 为变比默认为 1.0表示无变压器 n len(nodes) idx {name: i for i, name in enumerate(nodes)} ybus np.zeros((n, n), dtypecomplex) for br in branches: i idx[br[from]] j idx[br[to]] z br[z] tap br.get(tap, 1.0) y 1.0 / z if tap 1.0: # 普通线路 ybus[i, i] y ybus[j, j] y ybus[i, j] - y ybus[j, i] - y else: # 变压器支路变比折算到 from 侧 ybus[i, i] y / (tap * tap) ybus[j, j] y ybus[i, j] - y / tap ybus[j, i] - y / tap return ybus # 示例三个节点两条线路一台变压器 nodes [N1, N2, N3] branches [ {from: N1, to: N2, z: 0.05 0.15j}, {from: N2, to: N3, z: 0.08 0.24j, tap: 1.05}, ] ybus build_ybus(nodes, branches) print(节点导纳矩阵) print(ybus)这段代码的逻辑说明build_ybus接收节点列表和支路列表返回一个复数矩阵。对于普通线路导纳直接加到对角元素互导纳取负。对于变压器支路变比 tap 折算到 from 侧对角元素除以 tap 的平方互导纳除以 tap。这个折算方式对应的是变压器 π 型等值电路是电力系统分析里的标准做法。参数说明z是支路阻抗单位是标幺值或欧姆取决于整个系统是否采用标幺制。tap是变压器变比如果变压器在 from 侧则 tap 等于 from 侧额定电压除以 to 侧额定电压。如果变压器在 to 侧需要把 from 和 to 对调或者把 tap 取倒数。这个细节很容易搞反后面避坑章节会专门讲。2.3 从导纳矩阵到短路电流求逆与故障注入有了节点导纳矩阵下一步就是求逆得到节点阻抗矩阵然后根据故障节点计算短路电流。这里有一个关键点导纳矩阵在纯线路网络中通常是非奇异的可以直接求逆。但如果网络中有孤立节点或者某些节点没有对地支路导纳矩阵可能接近奇异求逆结果会不稳定。实际工程中发电机和负荷的等值阻抗会提供对地支路保证矩阵可逆。def calc_short_circuit(nodes, branches, fault_node, prefault_voltage1.0): 计算指定节点三相短路电流 fault_node: 故障节点名称 prefault_voltage: 故障前电压标幺值默认 1.0 返回短路电流标幺值节点阻抗矩阵 ybus build_ybus(nodes, branches) zbus np.linalg.inv(ybus) idx {name: i for i, name in enumerate(nodes)} k idx[fault_node] zkk zbus[k, k] if abs(zkk) 1e-12: raise ValueError(f节点 {fault_node} 的自阻抗接近零检查网络是否孤立) ik prefault_voltage / zkk return ik, zbus # 继续上面的示例 ik, zbus calc_short_circuit(nodes, branches, N2) print(fN2 节点短路电流标幺值{abs(ik):.4f}) print(节点阻抗矩阵) print(zbus)这段代码的逻辑说明先调用build_ybus构建导纳矩阵再用np.linalg.inv求逆得到阻抗矩阵。从阻抗矩阵中取出故障节点的自阻抗 Z_kk短路电流等于故障前电压除以 Z_kk。故障前电压默认取 1.0 标幺值实际工程中可以根据运行方式调整比如取 1.05 或 0.95。参数说明prefault_voltage是故障前节点电压标幺值。如果系统有多个电压等级需要先做标幺化处理把所有阻抗折算到同一基准。fault_node是故障节点名称必须出现在nodes列表中否则会报 KeyError。zkk的模值如果接近零说明该节点与网络其他部分隔离需要检查支路连接。这个最小实现已经能跑通基本的短路计算但离工程可用还有距离。比如没有考虑发电机次暂态电抗、没有处理多电压等级标幺化、没有输出各节点电压分布。这些会在后面的章节逐步补全。3. 参数怎么设标幺制、基准值与变压器变比的处理3.1 标幺制下的基准值选择与折算电力系统短路计算几乎都用标幺制原因是不同电压等级的阻抗数值差异太大用有名值计算容易出错。标幺制的核心是选基准功率 S_base 和基准电压 U_base然后所有阻抗都折算成标幺值。基准功率通常取 100 MVA 或 1000 MVA基准电压取各电压等级的额定电压。折算公式是Z_base U_base² / S_baseZ_pu Z_actual / Z_base。对于变压器如果两侧基准电压比不等于变压器额定变比还需要修正。这个修正很容易被忽略导致结果偏差百分之几到百分之十几。我一般会在程序里加一个基准值管理模块把各电压等级的基准电压和基准功率统一管理支路阻抗输入时直接给有名值程序自动折算。这样做的好处是输入数据更直观不用手动算标幺值。class BaseManager: def __init__(self, s_base100.0): self.s_base s_base # MVA self.voltage_bases {} # 电压等级名称 - kV def add_voltage_level(self, name, kv): self.voltage_bases[name] kv def z_base(self, level_name): kv self.voltage_bases[level_name] return kv * kv / self.s_base def to_pu(self, z_ohm, level_name): return z_ohm / self.z_base(level_name) # 示例两个电压等级 bm BaseManager(s_base100.0) bm.add_voltage_level(HV, 220.0) bm.add_voltage_level(LV, 10.5) z_line_ohm 5.0 15.0j # 高压侧线路有名值 z_line_pu bm.to_pu(z_line_ohm, HV) print(f高压侧线路标幺值{z_line_pu})这段代码的逻辑说明BaseManager管理基准功率和各电压等级的基准电压。z_base计算某一电压等级的基准阻抗to_pu把有名值折算成标幺值。实际使用时每条支路标注它所在的电压等级程序自动完成折算。参数说明s_base是基准功率单位 MVA全系统统一。voltage_bases是各电压等级的基准电压单位 kV通常取该等级的额定电压。z_ohm是支路阻抗有名值单位欧姆。折算后的标幺值是无量纲的可以直接填入导纳矩阵。3.2 变压器变比在导纳矩阵中的两种折算方式变压器变比的处理是短路计算里最容易翻车的地方之一。变比 tap 的定义方式有两种一种是 tap 等于高压侧电压除以低压侧电压另一种是 tap 等于低压侧电压除以高压侧电压。不同的教材和软件用的定义不一样如果搞反了短路电流会差很多。在导纳矩阵中变压器通常用 π 型等值电路表示。假设变压器连接节点 i 和节点 j变比 tap 定义在 i 侧则导纳矩阵的修正项为Y_ii y / tap²Y_jj yY_ij - y / tapY_ji - y / tap。其中 y 是变压器漏抗的倒数。如果变比定义在 j 侧则修正项变为Y_ii yY_jj y / tap²Y_ij - y / tapY_ji - y / tap。注意互导纳的符号和位置。我一般会在程序里强制约定变比 tap 始终定义在 from 侧如果实际变压器在 to 侧就把 from 和 to 对调。这样代码里只有一套逻辑不容易出错。def add_transformer(ybus, i, j, z, tap, tap_sidefrom): 向导纳矩阵添加变压器支路 tap_side: from 表示变比定义在 i 侧to 表示定义在 j 侧 y 1.0 / z if tap_side from: ybus[i, i] y / (tap * tap) ybus[j, j] y ybus[i, j] - y / tap ybus[j, i] - y / tap else: ybus[i, i] y ybus[j, j] y / (tap * tap) ybus[i, j] - y / tap ybus[j, i] - y / tap return ybus这段代码的逻辑说明add_transformer根据变比定义侧的不同分别处理导纳矩阵的修正项。tap_sidefrom时变比折算到 i 侧i 侧对角元素除以 tap²。tap_sideto时变比折算到 j 侧j 侧对角元素除以 tap²。互导纳始终除以 tap但位置和符号要对应。参数说明i和j是节点索引z是变压器漏抗标幺值tap是变比。tap_side必须与输入数据的定义一致否则结果会错。实际工程中变压器铭牌上的变比通常是高压侧额定电压除以低压侧额定电压如果 from 侧是高压侧则 tap_sidefrom。3.3 发电机和负荷等值阻抗的接入方式短路计算中发电机用次暂态电抗 X_d 等值负荷一般忽略或者用等值阻抗表示。发电机等值阻抗接在发电机节点和参考节点之间相当于在导纳矩阵的对角元素上增加 1/(jX_d)。负荷等值阻抗接在负荷节点和参考节点之间同样增加对角元素。参考节点的处理有两种方式一种是选一个节点作为参考节点在导纳矩阵中删除该节点对应的行和列然后求逆另一种是保留所有节点在参考节点上加一个大导纳或者直接接地。我一般用第一种方式因为矩阵维度小求逆更快而且物理意义清晰。def add_generator(ybus, node_idx, x_double_prime): 添加发电机次暂态电抗 ybus[node_idx, node_idx] 1.0 / (1j * x_double_prime) return ybus def add_load(ybus, node_idx, z_load): 添加负荷等值阻抗 ybus[node_idx, node_idx] 1.0 / z_load return ybus这段代码的逻辑说明add_generator在发电机节点上增加对地导纳导纳值等于次暂态电抗的倒数。add_load类似增加负荷等值导纳。这两个函数都只修改对角元素不影响互导纳。参数说明x_double_prime是发电机次暂态电抗标幺值通常取 0.1 到 0.3。z_load是负荷等值阻抗标幺值如果负荷用恒功率模型短路计算中一般忽略因为短路时电压降低负荷电流远小于短路电流。4. 避坑与排查短路计算程序最容易翻车的五个地方4.1 导纳矩阵奇异导致求逆结果发散现象程序运行后短路电流出现极大值或者 NaN节点阻抗矩阵元素异常大。原因网络中存在孤立节点或者某个节点没有任何对地支路导致导纳矩阵奇异。纯线路网络中如果所有节点都没有对地导纳导纳矩阵的行列式为零求逆会失败。解决检查每个节点是否至少连接一条支路或者是否有发电机、负荷等对地支路。可以在求逆前检查矩阵条件数如果条件数过大说明矩阵接近奇异。代码里加一个判断cond np.linalg.cond(ybus) if cond 1e12: raise ValueError(导纳矩阵条件数过大检查网络是否孤立)4.2 变压器变比方向搞反导致短路电流偏差现象短路电流与手算结果对不上偏差在百分之几到百分之几十之间。原因变比 tap 的定义侧与代码中的折算方式不一致。比如实际变压器在 to 侧但代码按 from 侧处理导致导纳矩阵修正项错误。解决统一约定变比定义侧输入数据时明确标注。如果变压器在 to 侧把 from 和 to 对调或者把 tap 取倒数。建议在数据录入阶段就做好转换不要留到计算阶段。4.3 标幺化时基准电压选错导致阻抗折算错误现象不同电压等级的支路阻抗标幺值差异异常短路电流分布不合理。原因基准电压选的是平均额定电压而不是额定电压或者变压器两侧基准电压比与变比不匹配。解决基准电压取各电压等级的额定电压不要取平均额定电压。如果变压器变比与基准电压比不一致需要修正变压器漏抗标幺值。修正公式是Z_pu_new Z_pu_old × (U_base_old / U_base_new)²。4.4 故障前电压取 1.0 但实际运行方式不是额定电压现象短路电流与现场录波数据对不上偏差在百分之几。原因故障前电压取 1.0 标幺值但实际运行中节点电压可能高于或低于额定值比如 1.05 或 0.95。解决根据实际运行方式调整prefault_voltage参数。如果做继电保护整定一般取最大运行方式下的电压比如 1.05如果做设备选型取最严重情况比如 1.1。4.5 复数矩阵求逆的数值稳定性问题现象矩阵求逆结果与手算结果有微小偏差节点数越多偏差越大。原因NumPy 的np.linalg.inv用的是 LU 分解对于病态矩阵数值误差会放大。解决对于节点数较多的网络可以用np.linalg.solve代替np.linalg.inv直接求解线性方程组避免显式求逆。如果必须求逆可以用scipy.linalg.inv并检查条件数。# 推荐做法直接求解不显式求逆 # 对于短路计算只需要故障节点的自阻抗 # 可以通过求解 Y * x e_k 得到 Z_kk e_k np.zeros(len(nodes), dtypecomplex) e_k[k] 1.0 z_column np.linalg.solve(ybus, e_k) zkk z_column[k]这段代码的逻辑说明np.linalg.solve直接求解 Y·x e_k得到阻抗矩阵的第 k 列其中第 k 个元素就是 Z_kk。这种方法比显式求逆数值稳定性更好而且只需要一列计算量更小。参数说明e_k是单位向量第 k 个元素为 1其余为 0。z_column是阻抗矩阵的第 k 列zkk是故障节点自阻抗。5. 进阶技巧批量计算与结果验证5.1 批量扫描不同故障节点和运行方式实际工程中往往需要计算多个故障节点的短路电流或者在不同运行方式下重复计算。手动改参数效率太低我一般会写一个批量扫描函数把故障节点列表和运行方式列表作为输入输出一个结果表格。def batch_short_circuit(nodes, branches, fault_nodes, voltages): 批量计算多个故障节点在不同故障前电压下的短路电流 返回DataFrame 或字典列表 results [] for fn in fault_nodes: for v in voltages: ik, _ calc_short_circuit(nodes, branches, fn, v) results.append({ fault_node: fn, prefault_voltage: v, ik_pu: abs(ik), ik_ka: abs(ik) * 100.0 / (np.sqrt(3) * 230.0) # 示例折算 }) return results # 示例 fault_nodes [N1, N2, N3] voltages [0.95, 1.0, 1.05] results batch_short_circuit(nodes, branches, fault_nodes, voltages) for r in results: print(r)这段代码的逻辑说明batch_short_circuit遍历故障节点和故障前电压的组合调用calc_short_circuit计算短路电流把结果整理成字典列表。ik_ka是把标幺值折算成有名值折算公式是 I_base S_base / (√3 × U_base)这里用 230 kV 作为示例基准电压。参数说明fault_nodes是故障节点名称列表voltages是故障前电压列表。ik_pu是短路电流标幺值ik_ka是短路电流有名值单位 kA。实际使用时基准电压要根据电压等级调整。5.2 用已知算例验证程序正确性程序写完后必须用已知算例验证。我一般会找一个手算过的简单网络比如三节点两线路手算节点阻抗矩阵和短路电流然后与程序结果对比。如果偏差在 1% 以内说明程序逻辑正确。下面是一个验证用的算例三节点网络节点 1 和节点 2 之间线路阻抗 0.1 0.3j节点 2 和节点 3 之间线路阻抗 0.2 0.6j节点 1 接发电机次暂态电抗 0.2j节点 3 发生三相短路。# 验证算例 nodes_v [N1, N2, N3] branches_v [ {from: N1, to: N2, z: 0.1 0.3j}, {from: N2, to: N3, z: 0.2 0.6j}, ] ybus_v build_ybus(nodes_v, branches_v) # 添加发电机 ybus_v[0, 0] 1.0 / (1j * 0.2) zbus_v np.linalg.inv(ybus_v) print(验证算例节点阻抗矩阵) print(zbus_v) ik_v, _ calc_short_circuit(nodes_v, branches_v, N3) print(fN3 短路电流标幺值{abs(ik_v):.4f})这段代码的逻辑说明先构建导纳矩阵再添加发电机次暂态电抗然后求逆得到阻抗矩阵最后计算 N3 节点短路电流。手算结果可以通过节点阻抗矩阵验证如果程序输出的 Z_33 与手算一致说明程序正确。参数说明发电机次暂态电抗 0.2j 是标幺值线路阻抗也是标幺值。如果手算结果与程序结果偏差较大检查导纳矩阵的构建是否正确特别是发电机接入方式。5.3 输出各节点电压分布用于继电保护整定短路计算不仅需要故障点电流还需要各节点电压分布用于继电保护整定和灵敏度校验。故障后各节点电压可以通过 U Z · I 计算其中 I 是故障点注入电流列向量只有故障节点有非零元素。def post_fault_voltages(nodes, branches, fault_node, prefault_voltage1.0): 计算故障后各节点电压 ybus build_ybus(nodes, branches) zbus np.linalg.inv(ybus) idx {name: i for i, name in enumerate(nodes)} k idx[fault_node] zkk zbus[k, k] ik prefault_voltage / zkk # 故障点注入电流列向量 i_inj np.zeros(len(nodes), dtypecomplex) i_inj[k] -ik # 故障后电压 故障前电压 Z * I_inj u_pre np.ones(len(nodes), dtypecomplex) * prefault_voltage u_post u_pre zbus i_inj return u_post # 示例 u_post post_fault_voltages(nodes, branches, N2) for name, u in zip(nodes, u_post): print(f{name} 故障后电压{abs(u):.4f} pu)这段代码的逻辑说明post_fault_voltages先计算短路电流然后构建故障点注入电流列向量最后用叠加原理计算故障后各节点电压。故障前电压假设各节点均为prefault_voltage故障后电压等于故障前电压加上阻抗矩阵乘以注入电流。参数说明i_inj是注入电流列向量故障节点为 -ik其余为零。u_pre是故障前电压列向量各节点相同。u_post是故障后电压列向量模值用于继电保护整定。这个技巧在实际工程中很实用因为继电保护整定不仅需要短路电流还需要各节点的残余电压用于判断保护范围。我一般会把故障后电压和短路电流一起输出方便后续分析。写短路计算程序这几年最大的教训是不要相信手算但也不要完全相信代码。每次改完网络结构先用简单算例验证再上实际数据。参数录入阶段多花十分钟检查变比和基准值比后面调试两小时划算。希望帮到你。本文还有配套的精品资源点击获取