RustPower
RustPower is an ECS-based power flow calculation library written in Rust, specifically designed for high-performance steady-state analysis of electrical power systems. It provides a transactional Python binding and direct solver interfaces for Python libraries such as pandapower.
Key Features
- High-Performance Newton-Raphson Engine: Optimized single-pass $O(\text{nnz})$
dSbus_dVevaluation 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 Interoperability: Direct zero-copy data ingestion from
pandapowernetworks in Python, plus CSV-ZIP and JSON formats. - 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.
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 Ecosystem Interoperability: Delivers pure-native performance while remaining drop-in compatible with established Python workflows. It provides zero-cost data ingestion directly from standard formats like
pandapower, eliminating migration friction for existing pipelines.
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 modeling for switch elements (node-merging or admittance-based).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 viabevy_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) # Enable Jacobian / LU factorization caching
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:
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.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rustpower-0.5.2-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details |
| rustpower-0.5.2-cp310-abi3-manylinux_2_28_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ x86-64 | Details |
| rustpower-0.5.2-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 18.3 MB
Release files / rustpower-0.5.2-cp310-abi3-win_amd64.whl
| Download URL | rustpower-0.5.2-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 5.6 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
47e991d1d0fdea16f133da2f1f06c2380668b217a13a2a413720b2e3e3a06003
|
|
BLAKE2b-256 checksum How to use checksums |
26ca12f3edaac43064a4d55147cf2cbf8d5333ebbee1779cac5b84cd684c11fc
|
| 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.2-cp310-abi3-manylinux_2_28_x86_64.whl
| Download URL | rustpower-0.5.2-cp310-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 7.0 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
1f454ffc33ed7c1ee9b8d71f1e9ecf666f348fae6c5f324b10db37df78c0c427
|
|
BLAKE2b-256 checksum How to use checksums |
0a7241af9ec62c06e7feb0070a2e6887cc7b4324ac9c8e8577ec208feac450c6
|
| 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.2-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | rustpower-0.5.2-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 5.8 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
026d437ff2d15e121413e42b53cd6ec87db0f742118cd7a62735dc9e004a07a9
|
|
BLAKE2b-256 checksum How to use checksums |
4803b205edfc40135bf93c48fe6f2ff5548fc8dc7d6de87d5a97a116d7cc2410
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.9
|