电网分析进阶
EnerOS v0.44.0 大幅增强电网分析能力,将状态估计、最优潮流(OPF)、短路分析、电磁暂态仿真(EMTP)等高级分析能力内置为内核服务。Agent 通过统一 API 调用,无需外接商业仿真软件即可完成全部分析任务。分析能力由 eneros-powerflow、eneros-analysis 两个 crate 协同提供。
分析能力架构
┌──────────────────────────────────────────────────────────────┐
│ 分析服务层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 状态估计 │ │ 最优潮流 │ │ 短路分析 │ │ EMTP │ │
│ │ SE │ │ OPF │ │ SC │ │ 仿真 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │ │
└───────┼─────────────┼─────────────┼─────────────┼───────────┘
│ │ │ │
┌───────▼─────────────▼─────────────▼─────────────▼───────────┐
│ 求解器层 │
│ Newton-Raphson / Fast Decoupled / Interior Point / │
│ Simplex / Trapezoidal / WLS / LAV │
└──────────────────────────┬───────────────────────────────────┘
│
┌──────────────────────────▼───────────────────────────────────┐
│ 数据层 │
│ 拓扑模型 / 设备参数 / 量测数据 / 时序数据库 │
└──────────────────────────────────────────────────────────────┘
| 分析类型 | 求解器 | 典型耗时 | 输出 |
|---|
| 状态估计 | WLS / LAV | < 50ms | 节点电压相量 |
| 潮流计算 | Newton-Raphson / Fast Decoupled | < 20ms | 节点电压、支路功率 |
| 直流 OPF | Simplex | < 100ms | 发电分配 |
| 交流 OPF | Interior Point | < 500ms | 发电 + 电压 |
| 短路分析 | IEC 60909 | < 30ms | 短路电流 |
| EMTP | Trapezoidal | < 5s | 暂态波形 |
| 谐波分析 | 频率扫描 | < 1s | 谐波频谱 |
状态估计
基于 WLS(加权最小二乘)的状态估计,融合 SCADA 与 PMU 数据。支持不良数据辨识与可观测性分析。
use eneros_analysis::{StateEstimator, Measurement, Weight, Confidence};
use std::time::Duration;
let estimator = StateEstimator::wls()
.max_iterations(20)
.tolerance(1e-6)
.flat_start(false);
// 输入量测
let measurements = vec![
Measurement::power_injection(bus_id, 50.0, Weight::from_sigma(2.0)),
Measurement::power_flow(line_id, 30.0, Weight::from_sigma(1.5)),
Measurement::voltage_magnitude(bus_id, 1.02, Weight::from_sigma(0.005)),
Measurement::current_magnitude(line_id, 0.45, Weight::from_sigma(0.01)),
Measurement::pmu(bus_id, 1.02, 0.1, Weight::high()), // PMU 高权重
Measurement::pmu(bus_id2, 1.01, 0.15, Weight::high()),
];
let result = estimator.estimate(&network, &measurements).await?;
println!("收敛: {}", result.converged);
println!("迭代次数: {}", result.iterations);
println!("残差: {:.4}", result.total_residual);
println!("最大残差: {:.4}", result.max_residual);
for (bus, v) in &result.voltages {
println!("Bus {}: {:.4} ∠ {:.4}°",
bus, v.magnitude, v.angle_deg);
}
不良数据辨识
// 基于卡方检验辨识不良数据
let bad = estimator.detect_bad_data(&result, Confidence::percent(99))?;
for data in &bad {
println!("不良数据: bus={}, type={:?}, 残差={:.2}, 标准化残差={:.2}",
data.bus_id, data.measurement_type, data.residual, data.normalized_residual);
}
// 移除不良数据后重新估计
let cleaned = estimator.remove_bad_data(&measurements, &bad);
let result2 = estimator.estimate(&network, &cleaned).await?;
可观测性分析
use eneros_analysis::observability::ObservabilityAnalyzer;
let analyzer = ObservabilityAnalyzer::new();
let obs = analyzer.analyze(&network, &measurements).await?;
println!("可观测: {}", obs.is_observable);
println!("可观测母线: {}/{}", obs.observable_buses, network.bus_count());
if !obs.is_observable {
for island in &obs.unobservable_islands {
println!("不可观测岛: {:?}", island.buses);
println!("建议添加量测: {:?}", island.suggested_measurements);
}
}
最优潮流(OPF)
支持直流 OPF 与交流 OPF,多种目标函数与约束:
use eneros_analysis::opf::{OpfSolver, Objective, Method, CostCurve, Constraint};
let solver = OpfSolver::new()
.method(Method::InteriorPoint)
.objective(Objective::MinGenerationCost)
.tolerance(1e-6)
.max_iterations(100);
// 添加发电机成本曲线
solver.add_cost_curve(gen_id, CostCurve::quadratic(0.001, 20.0, 100.0));
solver.add_cost_curve(gen_id2, CostCurve::piecewise(&[
(0.0, 50.0),
(100.0, 55.0),
(200.0, 65.0),
]));
// 添加约束
solver.add_constraint(Constraint::line_flow(line_id, 100.0)); // 线路功率上限
solver.add_constraint(Constraint::voltage_range(bus_id, 0.95, 1.05));
solver.add_constraint(Constraint::gen_range(gen_id, 50.0, 200.0));
let result = solver.solve(&network).await?;
println!("收敛: {}", result.converged);
println!("总成本: ${:.2}/h", result.total_cost);
println!("网损: {:.2} MW", result.losses);
for (gen, p) in &result.generation {
println!("Gen {}: {:.2} MW", gen, p);
}
OPF 目标函数
| 目标 | 公式 | 适用场景 |
|---|
| 最小发电成本 | min ΣC_i(P_i) | 经济调度 |
| 最小网损 | min Σlosses | 网损优化 |
| 最大输电能力 | max P_transfer | TTC/ATC |
| 最小电压偏差 | min Σ|V_i - V_ref| | 电能质量 |
| 最大无功储备 | max Σ(Q_max - Q_i) | 安全裕度 |
OPF 求解器对比
| 求解器 | 类型 | 速度 | 准确率 | 全局最优 |
|---|
| Simplex | 直流 | 极快 | 高 | ✅ |
| Interior Point | 交流 | 快 | 高 | ✅ |
| SQP | 交流 | 中 | 极高 | 局部 |
| Heuristic | 任意 | 慢 | 中 | 近似 |
短路分析
支持 IEC 60909、ANSI/IEEE C37 标准的短路计算,覆盖各类故障类型:
use eneros_analysis::shortage::{ShortCircuit, FaultType, Standard, FaultLocation};
let sc = ShortCircuit::new()
.standard(Standard::IEC60909)
.fault(FaultType::ThreePhase)
.at(FaultLocation::bus(bus_id))
.prefault_voltage(1.0); // 故障前电压
let result = sc.calculate(&network).await?;
println!("故障母线: {}", bus_id);
println!("短路电流 (有效值): {:.2} kA", result.current_kA);
println!("短路容量: {:.2} MVA", result.mva);
println!("峰值电流: {:.2} kA", result.peak_current_kA);
println!("直流分量: {:.2} kA", result.dc_component_kA);
// 各支路贡献
for (line, current) in &result.branch_contributions {
println!("支路 {}: {:.2} kA", line, current);
}
故障类型
| 类型 | 说明 | 典型场景 |
|---|
| 三相短路 | LLL | 最严重故障 |
| 两相短路 | LL | 线路故障 |
| 两相接地 | LLG | 单相接地演化 |
| 单相接地 | LG | 最常见故障(80%+) |
批量短路分析
use eneros_analysis::shortage::BatchShortCircuit;
let batch = BatchShortCircuit::new()
.faults(vec![
Fault::three_phase(bus_1),
Fault::single_phase_to_ground(bus_2),
Fault::line_to_line(bus_3),
])
.parallelism(4);
let results = batch.calculate(&network).await?;
for (i, result) in results.iter().enumerate() {
println!("故障 {}: 短路电流 {:.2} kA", i, result.current_kA);
}
电磁暂态仿真(EMTP)
用于开关操作、雷电过电压等暂态过程分析:
use eneros_analysis::emtp::{EmtpSimulator, SimulationConfig, SimulationEvent, IntegrationMethod};
let sim = EmtpSimulator::new(SimulationConfig {
dt: Duration::from_micros(50), // 50μs 步长
duration: Duration::from_millis(100), // 仿真 100ms
method: IntegrationMethod::Trapezoidal,
tolerance: 1e-6,
output: OutputConfig::all_buses(),
});
// 添加事件
sim.event(SimulationEvent::close_breaker(breaker_id, t0)).await?;
sim.event(SimulationEvent::open_breaker(breaker_id2, t0 + Duration::from_millis(10))).await?;
sim.event(SimulationEvent::lightning_strike(bus_id, 100.0, t0 + Duration::from_millis(20))).await?;
let result = sim.run(&network).await?;
// 提取节点电压波形
let waveform = result.voltage(bus_id);
let peak = waveform.iter().map(|s| s.value).fold(0.0f64, f64::max);
let trough = waveform.iter().map(|s| s.value).fold(0.0f64, f64::min);
println!("过电压峰值: {:.2} kV", peak);
println!("最低电压: {:.2} kV", trough);
// 导出波形为 CSV
result.export_csv("waveforms.csv", ExportOptions::default()).await?;
EMTP 配置参数
| 参数 | 默认值 | 说明 |
|---|
| dt | 50μs | 仿真步长 |
| duration | 100ms | 仿真时长 |
| method | Trapezoidal | 积分方法 |
| tolerance | 1e-6 | 收敛容差 |
| max_iterations | 50 | 单步最大迭代 |
| output | all_buses | 输出节点 |
谐波分析
use eneros_analysis::harmonic::{HarmonicAnalyzer, HarmonicMethod};
let analyzer = HarmonicAnalyzer::new()
.orders(1..=50) // 1-50 次谐波
.method(HarmonicMethod::FrequencyScan)
.scan_step(0.1); // 0.1 Hz 扫描步长
let result = analyzer.analyze(&network).await?;
// 总谐波畸变率
let thd = result.thd(bus_id);
println!("THD: {:.2}%", thd * 100.0);
// 各次谐波分量
for order in 2..=50 {
let mag = result.harmonic_magnitude(bus_id, order);
if mag > 0.001 {
println!("{} 次谐波: {:.2f}%", order, mag * 100.0);
}
}
// 是否超标
let limit = HarmonicLimit::ieee_519();
if result.exceeds(bus_id, &limit) {
println!("警告: {} 母线谐波超标 IEEE 519", bus_id);
}
谐波标准
| 标准 | 适用 | THD 限值 |
|---|
| IEEE 519 | 国际 | 5% |
| GB/T 14549 | 中国 | 5%(380V) |
| IEC 61000 | 国际 | 8% |
分析能力矩阵
| 分析类型 | 求解器 | 典型耗时 | 并行能力 |
|---|
| 状态估计 | WLS / LAV | < 50ms | ✅ |
| 潮流计算 | Newton-Raphson / Fast Decoupled | < 20ms | ✅ |
| 直流 OPF | Simplex | < 100ms | ✅ |
| 交流 OPF | Interior Point | < 500ms | ✅ |
| 短路分析 | IEC 60909 | < 30ms | ✅ 批量 |
| EMTP | Trapezoidal | < 5s(100ms 仿真) | 部分 |
| 谐波分析 | 频率扫描 | < 1s | ✅ |
性能指标
| 操作 | 延迟(1000 节点) | 延迟(10000 节点) |
|---|
| 状态估计 | < 50ms | < 200ms |
| 潮流计算 | < 20ms | < 100ms |
| 直流 OPF | < 100ms | < 500ms |
| 交流 OPF | < 500ms | < 2s |
| 短路分析(单故障) | < 30ms | < 100ms |
| 短路分析(批量 100) | < 1s | < 5s |
| EMTP(100ms 仿真) | < 5s | < 30s |
| 谐波分析(50 次) | < 1s | < 5s |
与其他能力的关系
相关文档