Skip to main content

powerio_matrix/
lib.rs

1//! Sparse matrix and graph projections from PowerIO networks.
2//!
3//! Outputs include signed incidence, weighted bus Laplacian, MATPOWER Bp/Bpp,
4//! Y bus, PTDF, LODF, adjacency, LACPF, and petgraph views. Calculations take the
5//! dense [`IndexedNetwork`] view of a [`BalancedNetwork`]. Parsing and emitting
6//! belong to the top level `powerio` facade; this crate owns derived matrix and
7//! graph calculations.
8//!
9//! ```
10//! use powerio_core::Source;
11//! use powerio_matrix::{BuildOptions, IndexedNetwork, calc_bprime_matrix};
12//! use powerio_tx::parse;
13//!
14//! # let case = concat!(env!("CARGO_MANIFEST_DIR"), "/../tests/data/case14.m");
15//! let net = parse(Source::open(case)?)?.into_value();
16//! let g = IndexedNetwork::new(&net);           // dense [0, n) analysis view
17//! let bprime = calc_bprime_matrix(&g, &BuildOptions::default())?;
18//! assert_eq!(bprime.rows(), g.n());            // Bp is n×n
19//! # Ok::<(), Box<dyn std::error::Error>>(())
20//! ```
21//!
22//! # Conventions
23//!
24//! Public DC operators follow PowerModels: an inductive branch has negative
25//! `b`. Their branch by bus incidence matrix `A_pm` gives
26//! `B = A_pmᵀ diag(b) A_pm`, with nonpositive diagonals and nonnegative
27//! off-diagonals. Solver preparation retains its bus by branch factor
28//! `A_s = A_pmᵀ` and uses `w = -b`, so the sparse factor is the positive
29//! M-matrix `L = A_s diag(w) A_sᵀ = -B`. Source bus IDs remain on the model;
30//! [`IndexedNetwork`] maps them to dense indices in `[0, n)`.
31//! `tap == 0` means `tap = 1`. `calc_bprime_matrix` and
32//! `calc_bdoubleprime_matrix` follow MATPOWER `makeB`; Y_bus keeps tap
33//! magnitudes and phase shifts. Branch
34//! terminal admittance is stored per unit. The default public DC formula is
35//! `b = -x/(r² + x²)`. [`BranchSusceptanceFormula::TapAdjustedReactance`] uses
36//! `b = -1/(x·τ)`; both carry phase shift injection. The full reference is in
37//! [the matrix guide](https://eigenergy.github.io/powerio/guide/matrices.html).
38
39// Re-export the balanced model types used by matrix signatures. Parsing,
40// emitting, conversion, and display operations stay on their owning crate and
41// the top level facade. `Error` and `Result` are this crate's own: the variants
42// below are raised here and nowhere in the hub.
43pub use powerio_tx::{
44    BalancedNetwork, Branch, Bus, BusId, BusType, ConnectivityReport, Extras, GenCost, Generator,
45    Hvdc, IndexCore, IndexedNetwork, Load, POWER_MODELS_ANGLE_BOUND_PAD, Shunt, SourceFormat,
46    Storage,
47};
48
49// Internal compatibility paths used throughout the matrix implementation.
50pub(crate) use powerio_tx::{indexed, network};
51
52pub mod diagnostics;
53pub mod error;
54pub use error::{ElementCounts, Error, PiecewiseCostInvalidity, Result, ScenarioMismatch};
55
56/// Compressed sparse row matrix used by the projection calculations.
57pub type SparseMatrix = sprs::CsMat<f64>;
58
59mod ac_jacobian;
60mod acopf;
61mod dc_operators;
62mod dcopf;
63pub mod io;
64pub mod matrix;
65mod opf;
66pub mod pipeline;
67pub mod synth;
68
69pub use ac_jacobian::{PowerFlowJacobian, VoltageCoordinates, calc_power_flow_jacobian};
70pub use acopf::{
71    AcBranchData, AcBusData, AcGeneratorData, AcOpfAssemblyOptions, AcOpfPreparation,
72    AcPfAssemblyOptions, AcPfBusData, AcPfGeneratorData, AcPfPreparation, AcStorageData,
73    NodalAcGeneratorData, PreparedAcBusSpecification, build_ac_opf_preparation,
74    build_ac_pf_preparation,
75};
76pub use dc_operators::{DcOperators, ReferenceConstrainedSystem};
77pub use dcopf::{
78    DcBranchParameters, DcGeneratorParameters, DcOpfAssemblyOptions, DcOpfBundleMetadata,
79    DcOpfBundleOptions, DcOpfMatrices, DcOpfOutputs, DcOpfPreparation, NodalGeneratorParameters,
80    Units, build_dc_opf_preparation, calc_dc_opf_matrices, emit_dcopf_bundle,
81};
82pub use opf::{AnalysisBranchSource, PiecewiseLinearCost, PreparedObjective};
83
84pub use matrix::multiconductor::{
85    AugmentedSystem, DistNode, MulticonductorAdmittance, MulticonductorNodeIndex, NodeRef,
86    calc_multiconductor_admittance_matrix,
87};
88pub use matrix::{
89    BranchSusceptanceFormula, BuildOptions, GroundedIndexMap, MatrixStats, Scheme,
90    SensitivityMatrices, SensitivityMatrixMetadata, SensitivityMetadata, SensitivityOptions,
91    SensitivitySolver, SensitivitySolverPath, ZeroImpedanceRule, ZeroImpedanceSkips,
92    calc_adjacency_matrix, calc_admittance_matrix, calc_bdoubleprime_matrix, calc_bprime_matrix,
93    calc_diagonal, calc_lacpf_matrix, calc_lodf, calc_ptdf, calc_ptdf_lodf,
94    calc_ptdf_lodf_with_options, calc_reference_indicator, calc_susceptance_diagonal,
95    calc_unit_vector, calc_weighted_laplacian, calc_zero_impedance_skips, check_sddm, ground_at,
96    ground_at_each,
97};
98pub use pipeline::{
99    MatrixKind, Pipeline, PipelineOutputs, RhsKind, calc_matrix, calc_matrix_stats_for_kind,
100    calc_zero_impedance_skips_for_kind, sanitize_stem, select_zero_impedance_rule_for_kind,
101};
102
103#[cfg(feature = "gridfm")]
104pub use io::gridfm::{
105    GridfmDataset, GridfmOptions, GridfmOutputs, GridfmSnapshot, GridfmTables, build_gridfm_batch,
106    build_gridfm_dataset, emit_gridfm_batch, emit_gridfm_dataset, number_snapshots,
107    to_gridfm_record_batches, to_gridfm_record_batches_single,
108};