Skip to main content

Grid Analysis Advanced

Capabilities

Grid Analysis Advanced

EnerOS v0.44.0 significantly enhances grid analysis capabilities, building state estimation, optimal power flow (OPF), short circuit analysis, electromagnetic transient simulation (EMTP), and other advanced analysis capabilities into kernel services. Agents invoke through a unified API, completing all analysis tasks without external commercial simulation software. The analysis capabilities are provided by the eneros-powerflow and eneros-analysis crates working together.

Analysis Capability Architecture

┌──────────────────────────────────────────────────────────────┐
│                     Analysis Service Layer                    │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐    │
│  │ State    │  │ Optimal  │  │ Short    │  │ EMTP     │    │
│  │ Estimation│  │ Power    │  │ Circuit  │  │ Simulation│   │
│  │   SE     │  │   OPF    │  │   SC     │  │          │    │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬─────┘    │
│       │             │             │             │            │
└───────┼─────────────┼─────────────┼─────────────┼───────────┘
        │             │             │             │
┌───────▼─────────────▼─────────────▼─────────────▼───────────┐
│                     Solver Layer                             │
│  Newton-Raphson / Fast Decoupled / Interior Point /          │
│  Simplex / Trapezoidal / WLS / LAV                           │
└──────────────────────────┬───────────────────────────────────┘

┌──────────────────────────▼───────────────────────────────────┐
│                     Data Layer                               │
│  Topology Model / Device Parameters / Measurement Data /     │
│  Time-Series Database                                        │
└──────────────────────────────────────────────────────────────┘
Analysis TypeSolverTypical DurationOutput
State EstimationWLS / LAV< 50msBus voltage phasors
Load FlowNewton-Raphson / Fast Decoupled< 20msBus voltage, branch power
DC OPFSimplex< 100msGeneration dispatch
AC OPFInterior Point< 500msGeneration + voltage
Short Circuit AnalysisIEC 60909< 30msShort circuit current
EMTPTrapezoidal< 5sTransient waveform
Harmonic AnalysisFrequency scan< 1sHarmonic spectrum

State Estimation

WLS (Weighted Least Squares) based state estimation, fusing SCADA and PMU data. Supports bad data identification and observability analysis.

use eneros_analysis::{StateEstimator, Measurement, Weight, Confidence};
use std::time::Duration;

let estimator = StateEstimator::wls()
    .max_iterations(20)
    .tolerance(1e-6)
    .flat_start(false);

// Input measurements
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 high weight
    Measurement::pmu(bus_id2, 1.01, 0.15, Weight::high()),
];

let result = estimator.estimate(&network, &measurements).await?;

println!("Converged: {}", result.converged);
println!("Iterations: {}", result.iterations);
println!("Residual: {:.4}", result.total_residual);
println!("Max residual: {:.4}", result.max_residual);

for (bus, v) in &result.voltages {
    println!("Bus {}: {:.4} ∠ {:.4}°",
        bus, v.magnitude, v.angle_deg);
}

Bad Data Identification

// Identify bad data based on chi-square test
let bad = estimator.detect_bad_data(&result, Confidence::percent(99))?;

for data in &bad {
    println!("Bad data: bus={}, type={:?}, residual={:.2}, normalized residual={:.2}",
        data.bus_id, data.measurement_type, data.residual, data.normalized_residual);
}

// Re-estimate after removing bad data
let cleaned = estimator.remove_bad_data(&measurements, &bad);
let result2 = estimator.estimate(&network, &cleaned).await?;

Observability Analysis

use eneros_analysis::observability::ObservabilityAnalyzer;

let analyzer = ObservabilityAnalyzer::new();
let obs = analyzer.analyze(&network, &measurements).await?;

println!("Observable: {}", obs.is_observable);
println!("Observable buses: {}/{}", obs.observable_buses, network.bus_count());

if !obs.is_observable {
    for island in &obs.unobservable_islands {
        println!("Unobservable island: {:?}", island.buses);
        println!("Suggested measurements: {:?}", island.suggested_measurements);
    }
}

Optimal Power Flow (OPF)

Supports DC OPF and AC OPF, with multiple objective functions and constraints:

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);

// Add generator cost curves
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),
]));

// Add constraints
solver.add_constraint(Constraint::line_flow(line_id, 100.0));   // Line power upper limit
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!("Converged: {}", result.converged);
println!("Total cost: ${:.2}/h", result.total_cost);
println!("Network losses: {:.2} MW", result.losses);

for (gen, p) in &result.generation {
    println!("Gen {}: {:.2} MW", gen, p);
}

OPF Objective Functions

ObjectiveFormulaApplicable Scenarios
Minimum generation costmin ΣC_i(P_i)Economic dispatch
Minimum network lossesmin ΣlossesLoss optimization
Maximum transmission capacitymax P_transferTTC/ATC
Minimum voltage deviationmin Σ|V_i - V_ref|Power quality
Maximum reactive reservemax Σ(Q_max - Q_i)Safety margin

OPF Solver Comparison

SolverTypeSpeedAccuracyGlobal Optimum
SimplexDCVery fastHigh
Interior PointACFastHigh
SQPACMediumVery highLocal
HeuristicAnySlowMediumApproximate

Short Circuit Analysis

Supports short circuit calculation complying with IEC 60909 and ANSI/IEEE C37 standards, covering various fault types:

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);   // Pre-fault voltage

let result = sc.calculate(&network).await?;

println!("Fault bus: {}", bus_id);
println!("Short circuit current (RMS): {:.2} kA", result.current_kA);
println!("Short circuit capacity: {:.2} MVA", result.mva);
println!("Peak current: {:.2} kA", result.peak_current_kA);
println!("DC component: {:.2} kA", result.dc_component_kA);

// Branch contributions
for (line, current) in &result.branch_contributions {
    println!("Branch {}: {:.2} kA", line, current);
}

Fault Types

TypeDescriptionTypical Scenarios
Three-phase short circuitLLLMost severe fault
Line-to-line short circuitLLLine fault
Double line-to-groundLLGSingle-phase ground evolution
Single line-to-groundLGMost common fault (80%+)

Batch Short Circuit Analysis

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!("Fault {}: short circuit current {:.2} kA", i, result.current_kA);
}

Electromagnetic Transient Simulation (EMTP)

Used for analyzing transient processes such as switching operations and lightning overvoltage:

use eneros_analysis::emtp::{EmtpSimulator, SimulationConfig, SimulationEvent, IntegrationMethod};

let sim = EmtpSimulator::new(SimulationConfig {
    dt: Duration::from_micros(50),                // 50μs step
    duration: Duration::from_millis(100),         // Simulate 100ms
    method: IntegrationMethod::Trapezoidal,
    tolerance: 1e-6,
    output: OutputConfig::all_buses(),
});

// Add events
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?;

// Extract bus voltage waveform
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!("Overvoltage peak: {:.2} kV", peak);
println!("Lowest voltage: {:.2} kV", trough);

// Export waveform as CSV
result.export_csv("waveforms.csv", ExportOptions::default()).await?;

EMTP Configuration Parameters

ParameterDefaultDescription
dt50μsSimulation step
duration100msSimulation duration
methodTrapezoidalIntegration method
tolerance1e-6Convergence tolerance
max_iterations50Max iterations per step
outputall_busesOutput buses

Harmonic Analysis

use eneros_analysis::harmonic::{HarmonicAnalyzer, HarmonicMethod};

let analyzer = HarmonicAnalyzer::new()
    .orders(1..=50)                              // 1st-50th harmonics
    .method(HarmonicMethod::FrequencyScan)
    .scan_step(0.1);                             // 0.1 Hz scan step

let result = analyzer.analyze(&network).await?;

// Total harmonic distortion
let thd = result.thd(bus_id);
println!("THD: {:.2}%", thd * 100.0);

// Individual harmonic components
for order in 2..=50 {
    let mag = result.harmonic_magnitude(bus_id, order);
    if mag > 0.001 {
        println!("{}-th harmonic: {:.2f}%", order, mag * 100.0);
    }
}

// Whether exceeding limit
let limit = HarmonicLimit::ieee_519();
if result.exceeds(bus_id, &limit) {
    println!("Warning: {} bus harmonics exceed IEEE 519", bus_id);
}

Harmonic Standards

StandardApplicableTHD Limit
IEEE 519International5%
GB/T 14549China5% (380V)
IEC 61000International8%

Analysis Capability Matrix

Analysis TypeSolverTypical DurationParallelism
State EstimationWLS / LAV< 50ms
Load FlowNewton-Raphson / Fast Decoupled< 20ms
DC OPFSimplex< 100ms
AC OPFInterior Point< 500ms
Short Circuit AnalysisIEC 60909< 30ms✅ Batch
EMTPTrapezoidal< 5s (100ms simulation)Partial
Harmonic AnalysisFrequency scan< 1s

Performance Metrics

OperationLatency (1000 buses)Latency (10000 buses)
State Estimation< 50ms< 200ms
Load Flow< 20ms< 100ms
DC OPF< 100ms< 500ms
AC OPF< 500ms< 2s
Short Circuit Analysis (single fault)< 30ms< 100ms
Short Circuit Analysis (batch 100)< 1s< 5s
EMTP (100ms simulation)< 5s< 30s
Harmonic Analysis (50th order)< 1s< 5s

Relationship with Other Capabilities