diff --git a/core.py b/core.py index 6c40479..d658e07 100644 --- a/core.py +++ b/core.py @@ -2,7 +2,7 @@ import math import ezdxf import numpy as np from typing import List - +from loguru import logger gCAD = None gMSP = None gCount = 1 @@ -28,6 +28,7 @@ class Parameter: ac_or_dc: str # 交流或直流标识,"AC" 或 "DC",默认 "AC" z_0: float # 雷电波阻抗,默认 300 z_c: float # 导线波阻抗,默认 251 + u_50: float # 50%击穿电压,-1表示自动计算 def rg_line_function_factory(_rg, ground_angel): # 返回一个地面捕雷线的直线方程 @@ -187,13 +188,16 @@ def solve_circle_line_intersection( return [_x, _y] -def min_i(string_len, u_ph, altitude: float = 0, z_0: float = 300, z_c: float = 251): +def min_i(string_len, u_ph, altitude: float = 0, z_0: float = 300, z_c: float = 251, u_50: float = None): # 海拔修正 if altitude > 1000: k_a = math.exp((altitude - 1000) / 8150) # 气隙海拔修正 else: k_a = 1 - u_50 = 1 / k_a * (530 * string_len + 35) # 50045 上附录的公式,实际应该用负极性电压的公式 + # 只有在u_50未提供时才使用公式计算 + if u_50 is None: + u_50 = 1 / k_a * (530 * string_len + 35) # 50045 上附录的公式,实际应该用负极性电压的公式 + logger.info(f"50%击穿电压为: {u_50}kV") # u_50 = 1 / k_a * (533 * string_len + 132) # 串放电路径 1000m海拔 # u_50 = 1 / k_a * (477 * string_len + 99) # 串放电路径 2000m海拔 # u_50 = 615 * string_len # 导线对塔身放电 1000m海拔 diff --git a/main-batch.py b/main-batch.py index cf864a2..292bb8f 100644 --- a/main-batch.py +++ b/main-batch.py @@ -49,10 +49,13 @@ def read_parameter(toml_file_path) -> Parameter: para.h_arm = toml_parameter["h_arm"] para.altitude = toml_parameter["altitude"] para.rated_voltage = toml_parameter["rated_voltage"] + para.z_0 = toml_parameter.get("z_0", 300) # 雷电波阻抗 + para.z_c = toml_parameter.get("z_c", 251) # 导线波阻抗 toml_advance = toml_dict["advance"] para.ng = toml_advance["ng"] # 地闪密度 para.Ip_a = toml_advance["Ip_a"] # 概率密度曲线系数a para.Ip_b = toml_advance["Ip_b"] # 概率密度曲线系数b + para.u_50 = toml_advance.get("u_50", -1) # 50%击穿电压,-1表示自动计算 toml_optional = toml_dict["optional"] para.voltage_n = toml_optional["voltage_n"] # 工作电压分成多少份来计算 para.max_i = toml_optional["max_i"] @@ -152,7 +155,9 @@ def egm(): i_max = 0 insulator_c_len = para.insulator_c_len # i_min = min_i(insulator_c_len, u_ph / 1.732) - i_min = min_i(insulator_c_len, u_ph, para.altitude) + # u_50: -1表示自动计算,其他值表示使用提供的值 + u_50_value = para.u_50 if para.u_50 > 0 else None + i_min = min_i(insulator_c_len, u_ph, para.altitude, para.z_0, para.z_c, u_50_value) _min_i = i_min # 尝试的最小电流 _max_i = para.max_i # 尝试的最大电流 # cad.draw(i_min, u_ph, rs_x, rs_y, rc_x, rc_y, rg_x, rg_y, rg_type, 2) diff --git a/main.py b/main.py index 05bbbbe..7883b25 100644 --- a/main.py +++ b/main.py @@ -56,10 +56,13 @@ def read_parameter(toml_file_path) -> Parameter: para.altitude = toml_parameter["altitude"] para.rated_voltage = toml_parameter["rated_voltage"] para.ac_or_dc = toml_parameter.get("ac_or_dc", "AC") # 交流或直流标识,默认AC + para.z_0 = toml_parameter.get("z_0", 300) # 雷电波阻抗 + para.z_c = toml_parameter.get("z_c", 251) # 导线波阻抗 toml_advance = toml_dict["advance"] para.ng = toml_advance["ng"] # 地闪密度 para.Ip_a = toml_advance["Ip_a"] # 概率密度曲线系数a para.Ip_b = toml_advance["Ip_b"] # 概率密度曲线系数b + para.u_50 = toml_advance.get("u_50", -1) # 50%击穿电压,-1表示自动计算 toml_optional = toml_dict["optional"] para.voltage_n = toml_optional["voltage_n"] # 工作电压分成多少份来计算 para.max_i = toml_optional["max_i"] @@ -175,7 +178,9 @@ def run_egm(para: Parameter, animation=None) -> dict: insulator_c_len = para.insulator_c_len # i_min = min_i(insulator_c_len, u_ph / 1.732) # TODO 需要考虑交、直流 - i_min = min_i(insulator_c_len, u_ph, para.altitude, para.z_0, para.z_c) + # u_50: -1表示自动计算,其他值表示使用提供的值 + u_50_value = para.u_50 if para.u_50 > 0 else None + i_min = min_i(insulator_c_len, u_ph, para.altitude, para.z_0, para.z_c, u_50_value) _min_i = i_min # 尝试的最小电流 _max_i = para.max_i # 尝试的最大电流 # cad.draw(i_min, u_ph, rs_x, rs_y, rc_x, rc_y, rg_x, rg_y, rg_type, 2) diff --git a/webui/src/components/ParameterForm.vue b/webui/src/components/ParameterForm.vue index 2584720..d03f5da 100644 --- a/webui/src/components/ParameterForm.vue +++ b/webui/src/components/ParameterForm.vue @@ -249,6 +249,26 @@ + +
+ +
+
+
+ + 自定义50%击穿电压值,默认-1表示使用公式计算 + +
+
@@ -405,7 +425,8 @@ const defaultParams: AllParameters = { advance: { ng: -1, Ip_a: -1, - Ip_b: -1 + Ip_b: -1, + u_50: -1 }, optional: { voltage_n: 3, @@ -422,6 +443,8 @@ const animationRef = ref | null>(null) const fileInput = ref(null) // 雷电流概率密度系数设置开关 const showIpCoefficients = ref(false) +// 50%击穿电压设置开关 +const showU50 = ref(false) const voltageOptions = [ '110kV', '220kV', '330kV', '500kV', '750kV','1000kV', @@ -457,6 +480,17 @@ watch( } ) +// 监听50%击穿电压开关 +watch( + showU50, + (show) => { + if (!show) { + // 关闭时重置为 -1(使用公式计算) + params.advance.u_50 = -1 + } + } +) + // 雷暴日与地闪密度相互转换,公式:ng = 0.023 * td^3 // 标志位避免循环更新 let isUpdatingFromWatch = false diff --git a/webui/src/types/index.ts b/webui/src/types/index.ts index c7c9ef7..33c75c7 100644 --- a/webui/src/types/index.ts +++ b/webui/src/types/index.ts @@ -23,6 +23,7 @@ export interface AdvanceParameter { ng: number // 地闪密度 (次/(km²·a)) Ip_a: number // 雷电流概率密度曲线系数a Ip_b: number // 雷电流概率密度曲线系数b + u_50: number // 50%击穿电压 (kV),-1表示自动计算 } export interface OptionalParameter { diff --git a/webview_app.py b/webview_app.py index defb604..d719bd4 100644 --- a/webview_app.py +++ b/webview_app.py @@ -329,6 +329,7 @@ class EGMWebApp: para.ng = float(advance_data.get('ng', -1)) para.Ip_a = float(advance_data.get('Ip_a', -1)) para.Ip_b = float(advance_data.get('Ip_b', -1)) + para.u_50 = float(advance_data.get('u_50', -1)) para.voltage_n = int(optional_data.get('voltage_n', 3)) para.max_i = float(optional_data.get('max_i', 200))