Skip to main content

oxigrid/powerflow/
mod.rs

1//! AC and DC power flow solvers.
2//!
3//! # Usage
4//!
5//! ```rust,ignore
6//! use oxigrid::prelude::*;
7//! let net = PowerNetwork::from_matpower("ieee14.m")?;
8//! let cfg = PowerFlowConfig::default();          // Newton-Raphson, 50 iter, tol 1e-8
9//! let res = net.solve_powerflow(&cfg)?;
10//! assert!(res.converged);
11//! ```
12//!
13//! # Algorithms
14//!
15//! | Method | Struct | Notes |
16//! |--------|--------|-------|
17//! | Newton-Raphson (AC) | `NewtonRaphsonSolver` | Sparse Jacobian, step-size limiting |
18//! | Fast Decoupled (AC) | `FastDecoupledSolver` | Stott & Alsac 1974, B'/B'' matrices |
19//! | DC Approximation   | `DcPowerFlowSolver`   | Linear B'·θ = P, 1 iteration |
20//! | Continuation PF    | `ContinuationSolver`  | P-V curve, voltage stability |
21//!
22//! The `parallel` feature flag activates rayon-based parallel Jacobian construction.
23pub mod acdc_pf;
24pub mod contingency_analysis;
25pub use contingency_analysis::*;
26pub mod continuation;
27pub mod harmonic_pf;
28pub use harmonic_pf::*;
29pub mod harmonic_pf_problem;
30pub use harmonic_pf_problem::{
31    solve_complex_linear, HarmonicBranchData, HarmonicBusData, HarmonicCurrentSource,
32    HarmonicLoadModel, HarmonicOrderResult, HarmonicPfConfig, HarmonicPfProblem, HarmonicPfResult,
33};
34pub mod dc_powerflow;
35pub mod dsse;
36pub mod fast_decoupled;
37pub mod hem;
38pub mod jacobian;
39pub mod newton_raphson;
40pub mod probabilistic;
41pub mod result;
42pub mod sensitivity;
43pub mod sparse_lu;
44pub use dsse::*;
45pub mod state_estimation;
46pub mod timeseries_sim;
47pub mod unbalanced_continuation;
48pub use acdc_pf::*;
49pub use timeseries_sim::{
50    BusTimeSeries, BusTimeSeriesType, GeneratorProfile, ScenarioAnalysis, StorageStrategy,
51    TimeResolution, TimeSeriesConfig, TimeSeriesNetwork, TimeSeriesResult, TimeSeriesSimulator,
52    TimeSeriesStatistics, TimeStepResult,
53};
54pub use unbalanced_continuation::{
55    CollapsePoint, CpfBusType, LoadScalingModel, PvPoint, ThreePhaseBranch, ThreePhaseBus,
56    UnbalancedCpf, UnbalancedCpfConfig, UnbalancedCpfResult,
57};
58
59use crate::error::Result;
60use crate::network::PowerNetwork;
61pub use result::{BranchFlow, PowerFlowResult};
62use serde::{Deserialize, Serialize};
63
64#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
65pub enum PowerFlowMethod {
66    NewtonRaphson,
67    FastDecoupled,
68    DcApproximation,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct PowerFlowConfig {
73    pub method: PowerFlowMethod,
74    pub max_iter: usize,
75    pub tolerance: f64,
76    pub enforce_q_limits: bool,
77}
78
79impl Default for PowerFlowConfig {
80    fn default() -> Self {
81        Self {
82            method: PowerFlowMethod::NewtonRaphson,
83            max_iter: 50,
84            tolerance: 1e-8,
85            enforce_q_limits: false,
86        }
87    }
88}
89
90pub trait PowerFlowSolver {
91    fn solve(&self, network: &PowerNetwork, config: &PowerFlowConfig) -> Result<PowerFlowResult>;
92}
93
94impl PowerNetwork {
95    pub fn solve_powerflow(&self, config: &PowerFlowConfig) -> Result<PowerFlowResult> {
96        match config.method {
97            PowerFlowMethod::NewtonRaphson => {
98                let solver = newton_raphson::NewtonRaphsonSolver;
99                solver.solve(self, config)
100            }
101            PowerFlowMethod::DcApproximation => {
102                let solver = dc_powerflow::DcPowerFlowSolver;
103                solver.solve(self, config)
104            }
105            PowerFlowMethod::FastDecoupled => {
106                let solver = fast_decoupled::FastDecoupledSolver;
107                solver.solve(self, config)
108            }
109        }
110    }
111}