Skip to main content

RustPower

Crates.io Docs.rs CI RustPower is an ECS-based power flow calculation library designed primarily for native Rust applications and high-performance steady-state analysis of electrical power systems. Its Python bindings provide a transactional grid API and a numerical solver interface for seamless replacement of the Newton-Raphson solver using pandapower's ppc/ppci matrices and vectors.

Key Features

  • High-Performance Newton-Raphson Engine: Optimized single-pass $O(\text{nnz})$ dSbus_dV evaluation and branch-free symbolic Jacobian filling (fill_jacobian_ultimate).
  • DCPF Solver & Warm-Start Initialization: Built-in DC power flow calculation and DCPF-initialized Newton-Raphson for accelerated convergence on stressed networks.
  • Iwamoto Optimal Multiplier: Robust nonlinear solver using optimal deceleration step size $\mu$ to ensure convergence on ill-conditioned or heavily-loaded grids.
  • Standard 2-Port Branch Modeling: Rigorous $\Pi$-equivalent model for lines and transformers with complex tap ratios and phase shifts.
  • Stateful Jacobian & Solver Caching (NewtonCache): Reuses symbolic LU factorization and sparsity patterns across consecutive iterations.
  • Modular ECS Architecture: Built on Bevy ECS for data-oriented composability, custom plugins, and zero heap allocation during hot iteration loops.
  • Seamless Pandapower Solver Integration: Use the Python NewtonSolver interface to replace the numerical Newton-Raphson solve using matrices and vectors prepared by pandapower through ppc/ppci. Pandapower retains model preparation and the surrounding workflow.
  • Zero-Copy NumPy Interface & Zero-Allocation Result Extraction: The Python interface accesses contiguous complex128 input buffers directly and writes results into pre-allocated NumPy output arrays with extract_results(), avoiding intermediate array copies at this interface. The solver still allocates and owns its internal matrices, vectors, and workspaces.
  • Basic Network Data Conversion: Import supported basic elements from live pandapower networks, CSV-ZIP files, and JSON into RustPower's native ECS model.
  • Multiple High-Performance Solvers: Supports RSparse, Faer, and SuiteSparse KLU backends.
  • Apache Arrow & Parquet Archiving: High-performance state persistence powered by bevy_archive 0.5.0.

Pandapower Integration Scope

The Python solver interface and the network importer serve different purposes. NewtonSolver operates on externally prepared numerical data, allowing pandapower workflows to use RustPower for the numerical solve. See the solver integration report for this interface and its benchmarks.

Rust array indexing and this solver's sparse matrix indices use usize, a pointer-sized unsigned integer (64 bits on 64-bit platforms). NumPy/SciPy commonly supply signed int32 or int64 indices, so setup converts those index arrays into owned usize buffers. The zero-copy interface claim applies to compatible numerical buffers, not these integer index arrays.

For repeated solves, reuse the solver context and NumPy output arrays. extract_results() provides direct, zero-allocation output into caller-owned buffers after a solve, including voltages and cached power injections. These claims describe array access and result extraction at the Python interface, not an allocation-free solver. Context setup converts and copies data into solver-owned storage, and internal workspaces are allocated as needed.

PowerGrid.from_pandapower() converts supported basic network elements into RustPower's own ECS model. Its AC power-flow results have been validated against pandapower on selected IEEE benchmark systems. This conversion does not provide full compatibility with every pandapower element model, parameter, option, controller, or analysis feature. Networks with switches require an explicit switch_model="merge" (Type A) or "admittance" (Type B); no model is chosen automatically. RustPower's primary focus is native Rust modeling and simulation; see the Python API guide for the distinction and current switch limitations.


Performance Comparison

RustPower is designed for extreme performance and memory efficiency. Below is a comparison between established standards and RustPower on the hot loop (caches Ybus and solver data for an invariant topology).

Core Solve Time (Newton-Raphson, Hot Loop)

  • Tested on Intel i7-10700K@4.7GHz with 32GB DDR4-3000 under Windows 11 with identical iteration counts at flat start initial condition:
Case Pandapower 3.5.4 (PyPI, Numba) LightSim2Grid 1.0.0 (PyPI, KLU) RustPower 0.5.2 (Python, KLU) RustPower (Rust Native, KLU)
IEEE 39 15.1 ms 0.035 ms 0.044 ms 0.023 ms
IEEE 118 17.1 ms 0.095 ms 0.080 ms 0.059 ms
PEGASE 9241 244.1 ms 22.9 ms 21.0 ms 20.0 ms
  • On Intel Core Ultra 7 288V@5.1GHz, 32GB LPDDR5X-8533 under CachyOS / Linux 7.x:
Case Pandapower 3.5.4 (PyPI, Numba) LightSim2Grid 1.0.0 (PyPI, KLU) RustPower 0.5.2 (Python, KLU) RustPower (Rust Native, KLU)
IEEE 39 4.36 ms 0.017 ms 0.021 ms 0.014 ms
IEEE 118 5.18 ms 0.051 ms 0.040 ms 0.031 ms
PEGASE 9241 147.19 ms 13.67 ms 11.53 ms 11.36 ms

Note: Python columns reflect end-to-end execution within the Python runtime using official package builds.

RustPower achieves native C++-grade performance with sub-millisecond execution on IEEE benchmark grids, scaling to solve the 9241-bus PEGASE system in just 11.3 ms on a modern laptop.

Key Advantages

  • Low Memory Footprint: For the 9,241-bus PEGASE system, RustPower peaks at only ~34 MB of RAM (a 15× reduction compared to the 500+ MB footprint of pandapower frameworks). This allows thousands of parallel grid simulations (e.g., N-1 screening, Monte Carlo, RL environments) to run concurrently on standard hardware or resource-constrained cloud containers without thrashing memory bandwidth.
  • Memory Safety & Zero Allocation: Leveraging Rust's compile-time ownership guarantees, RustPower eliminates segmentation faults, data races, and memory leaks by design. Combined with our ECS architecture, the core power flow iteration loop operates with zero heap allocations.
  • Seamless Numerical Solver Replacement & Direct Array I/O: The Python NewtonSolver interface lets existing pandapower workflows replace the numerical Newton-Raphson stage using ppc/ppci data while retaining pandapower's model conversion and workflow control. Zero-copy access to compatible NumPy buffers and zero-allocation extraction into pre-allocated arrays avoid intermediate array creation in the result transfer path. Importing a network into RustPower's ECS model is a separate path with a defined subset of supported elements and parameters.

Plugin-Based Architecture

RustPower leverages the Bevy Plugin System, allowing users to extend the solver with custom logic without modifying the core:

  • BasePFPlugin: Core power flow pipeline (structure init, matrix builder, Newton-Raphson).
  • DcpfNewtonPfPlugin: Solves DC power flow to initialize bus voltage angles prior to AC power flow.
  • IwamotoPlugin: Implements Iwamoto's optimal step-size multiplier method for robust convergence under extreme load conditions.
  • QLimPlugin: Automatically enforces generator reactive power limits by dynamically switching PV buses to PQ during the iteration process.
  • SwitchPluginTypeA / SwitchPluginTypeB: Optional bus-bus switch modeling (exact node merging or admittance approximation). Both include LineSwitchPlugin, which also works independently for line-terminal switching.
  • TimeSeriesDefaultPlugins: Quasi-static time-series simulations with scheduled events.
  • ArchivePlugin: High-performance ECS state persistence system.

High-Performance Data Archiving

RustPower features a unique Archive System (based on bevy_archive 0.5.0):

  • Custom Arrow & Parquet Integration: Columnar snapshot storage for high-performance time-series data and grid state persistence.
  • Multi-Format Persistence: Save and restore full network state into Apache Parquet (.parquet / .zip), TOML, or CSV.

Installation

Rust Crate

Add RustPower to your Cargo.toml:

[dependencies]
rustpower = "0.5.2"

Available features:

  • rsparse (default): Fast native pure-Rust sparse solver.
  • arrow (default): Apache Arrow and Parquet snapshot support via bevy_archive.
  • faer: High-performance portable linear algebra solver.
  • klu: SuiteSparse KLU direct sparse solver (statically or dynamically linked).
  • python: Python C-extension module bindings (PyO3).

Python Package

pip install rustpower

Usage Examples

Python API

import rustpower as rp
import pandapower.networks as nw

# 1. Load network from pandapower or a CSV-ZIP case file
net = nw.case118()
grid = rp.PowerGrid.from_pandapower(net)
# Or: grid = rp.PowerGrid("cases/IEEE118/data.zip")

# 2. Configure solver options (optional)
grid.enable_cache(True)       # Already enabled by default; reuses symbolic caches
grid.enable_dcpf_init(True)   # Enable DCPF angle initialization for faster convergence
# grid.enable_iwamoto(True)   # Use Iwamoto optimal multiplier for ill-conditioned cases

# 3. Solve power flow
report = grid.solve(tol=1e-8, max_iter=20)

if report.converged:
    print(f"Converged in {report.iterations} iterations, time: {report.runtime_ms:.2f} ms")
    print(grid.res_bus.head())
    print(grid.res_line.head())
    print(grid.res_trafo.head())

# 4. Fast parameter updates (warm-start incremental path)
load = grid.load(bus=10)
if load:
    load.p_mw = 100.0
grid.solve()  # Runs incremental solve reusing cached matrix topology

# 5. Transactional topology editing
with grid.edit() as e:
    new_bus_id, _ = e.add_bus(vn_kv=110.0, name="Substation_C")
    e.add_line(from_bus=10, to_bus=new_bus_id, length_km=15.0)
    e.add_load(bus=new_bus_id, p_mw=25.0, q_mvar=5.0)
grid.solve()  # Automatically triggers topology rebuild

Rust ECS Examples

1. Basic Power Flow

Run with: cargo run --example basic_powerflow

use std::env;
use rustpower::io::pandapower::load_csv_zip;
use rustpower::prelude::*;
use ecs::post_processing::PostProcessing;

fn main() {
    let dir = env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".to_string());
    let zipfile = format!("{}/cases/IEEE118/data.zip", dir);
    let net = load_csv_zip(&zipfile).expect("Failed to load case zip");

    // Initialize the ECS application with default plugins
    let mut pf_net = default_app();
    pf_net.world_mut().insert_resource(PPNetwork(net));
    pf_net.update(); // Initializes and solves power flow

    // Retrieve results
    let results = pf_net.world().get_resource::<PowerFlowResult>().unwrap();
    assert!(results.converged);
    println!("Converged in {} iterations", results.iterations);

    // Post-process and print results
    pf_net.post_process();
    pf_net.print_res_bus();
}

2. DCPF-Initialized Power Flow

Run with: cargo run --example dcpf_example

use rustpower::prelude::{
    default_app,
    ecs::dcpf::{DcpfNewtonPfPlugin, DcpfSolverActive},
    PPNetwork, PowerFlowResult,
};

let mut pf_net = default_app();
pf_net.add_plugins(DcpfNewtonPfPlugin);
pf_net.world_mut().insert_resource(DcpfSolverActive);
pf_net.world_mut().insert_resource(PPNetwork(net));
pf_net.update();

3. Iwamoto Optimal Multiplier Solver

Run with: cargo run --example iwamoto_example

use rustpower::prelude::{
    default_app,
    CustomSolverActive, IwamotoPlugin, PPNetwork, PowerFlowResult,
};

let mut pf_net = default_app();
pf_net.add_plugins(IwamotoPlugin);
pf_net.world_mut().insert_resource(CustomSolverActive);
pf_net.world_mut().insert_resource(PPNetwork(net));
pf_net.update();

Additional examples available in the examples/ directory:

  • archive_example.rs: TOML-based state restoration.
  • arrow_archive_example.rs: Apache Arrow / Parquet snapshot serialization.

License

This project is licensed under the MPLv2 License. See the LICENSE file for more details.


Contributions

Contributions are welcome! Feel free to open an issue or submit a pull request to help improve the library.


Authors

  • Tianshi Cheng

Acknowledgements

This project draws inspiration from:

Special thanks to:
T. Cheng, T. Duan, and V. Dinavahi, "ECS-Grid: Data-Oriented Real-Time Simulation Platform for Cyber-Physical Power Systems," IEEE Transactions on Industrial Informatics, vol. 19, no. 11, pp. 11128-11138, 2023.

Although ECS-Grid is a more complex electromagnetic transient (EMT) simulation system, its design philosophy and methodologies greatly influenced the development of this steady-state power flow solver.

Metadata

Release files for rustpower 0.5.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for rustpower 0.5.3
File Interpreter ABI Platform
rustpower-0.5.3-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
rustpower-0.5.3-cp310-abi3-manylinux_2_28_x86_64.whl CPython 3.10 abi3 Linux glibc 2.28+ x86-64 Details
rustpower-0.5.3-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details

Total release size: 18.9 MB

Release files / rustpower-0.5.3-cp310-abi3-win_amd64.whl

Download URL rustpower-0.5.3-cp310-abi3-win_amd64.whl
Size 5.7 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
4b2b54762ab9770a6094d550118f93df2845147968a23690c6ebfca19bbf69ad
BLAKE2b-256 checksum
How to use checksums
0a12e7ed7d785236bd7c3bce55dd10aae36ec360c1982229aea39cd4c2560126
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.9

Release files / rustpower-0.5.3-cp310-abi3-manylinux_2_28_x86_64.whl

Download URL rustpower-0.5.3-cp310-abi3-manylinux_2_28_x86_64.whl
Size 7.2 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
eb7fbfaf538dec94bab9f0327c51b0bdeec33b738aef312be7e4a2c6e448fa43
BLAKE2b-256 checksum
How to use checksums
9817865cf5107a636cfa9b27540571bb98d022d72cdab0988fb5b5d4980ae8e8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.9

Release files / rustpower-0.5.3-cp310-abi3-macosx_11_0_arm64.whl

Download URL rustpower-0.5.3-cp310-abi3-macosx_11_0_arm64.whl
Size 6.0 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
8f4379874ddba465daa589b478a1342a0dffb35c771998ec7819459bac7109a7
BLAKE2b-256 checksum
How to use checksums
7129830678408ca994dd2f0f065f6e77255cec1fab162b6c3961603be4fb4e51
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.9

Release history Release notifications | RSS feed

This release

0.5.3 This release

3 release files

0.5.2

3 release files

0.5.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page