🚀FastSE
A collection of power system computation modules
sparse matrix + aot/jit + klu + custom improved ordering + python = efficiency in computation and development!
🌟Features
- ⚡Jitted and KLU-powered state estimation
- ⚡Jitted and KLU-powered power flow
- ⚡Jitted and KLU-powered continuation power flow
- ⚡Jitted and KLU-powered temperature-dependent power flow
- :crab:Rust-powered network routing for operational resilience
Installation
To install, simply run pip install fastSE in your command prompt.
How to use
Here is one simple example. solve_se_lm is a high-level function which
computes derivatives, assemble them as sparse matrix and then calculate the
estimates using sparse matrix solver. All the low-level functions could also
be imported and used individually.
from fastse import StateEstimator, StateEstimationInput
from fastse import bdd_validation
from scipy.sparse import csr_matrix
import numpy as np
import time
# A 5 bus example from Prof. Overbye's textbook
# node impedance
Ybus = np.array([[3.729 - 49.720j, 0.000 + 0.000j, 0.000 + 0.000j,
0.000 + 0.000j, -3.729 + 49.720j],
[0.000 + 0.000j, 2.678 - 28.459j, 0.000 + 0.000j,
-0.893 + 9.920j, -1.786 + 19.839j],
[0.000 + 0.000j, 0.000 + 0.000j, 7.458 - 99.441j,
-7.458 + 99.441j, 0.000 + 0.000j],
[0.000 + 0.000j, -0.893 + 9.920j, -7.458 + 99.441j,
11.922 - 147.959j, -3.571 + 39.679j],
[-3.729 + 49.720j, -1.786 + 19.839j, 0.000 + 0.000j,
-3.571 + 39.679j, 9.086 - 108.578j]])
Ybus = csr_matrix(Ybus)
# branch impedance
Yf = np.array([[ 3.729-49.720j, 0.000 +0.000j, 0.000 +0.000j, 0.000 +0.000j,
-3.729+49.720j],
[ 0.000 +0.000j, -0.893 +9.920j, 0.000 +0.000j, 0.893 -9.060j,
0.000 +0.000j],
[ 0.000 +0.000j, -1.786+19.839j, 0.000 +0.000j, 0.000 +0.000j,
1.786-19.399j],
[ 0.000 +0.000j, 0.000 +0.000j, 7.458-99.441j, -7.458+99.441j,
0.000 +0.000j],
[ 0.000 +0.000j, 0.000 +0.000j, 0.000 +0.000j, -3.571+39.679j,
3.571-39.459j]])
Yf = csr_matrix(Yf)
Yt = np.array([[-3.729+49.720j, 0.000 +0.000j, 0.000 +0.000j, 0.000 +0.000j,
3.729-49.720j],
[ 0.000 +0.000j, 0.893 -9.060j, 0.000 +0.000j, -0.893 +9.920j,
0.000 +0.000j],
[ 0.000 +0.000j, 1.786-19.399j, 0.000 +0.000j, 0.000 +0.000j,
-1.786+19.839j],
[ 0.000 +0.000j, 0.000 +0.000j, -7.458+99.441j, 7.458-99.441j,
0.000 +0.000j],
[ 0.000 +0.000j, 0.000 +0.000j, 0.000 +0.000j, 3.571-39.459j,
-3.571+39.679j]])
Yt = csr_matrix(Yt)
# branch from and to bus
f = np.array([0, 3, 4, 2, 4])
t = np.array([4, 1, 1, 3, 3])
# slack, pv and pq buses
slack = np.array([0]) # The slack bus does not have to be the 0-indexed bus
pq = np.array([1, 3, 4])
pv = np.array([2])
# measurements
se_input = StateEstimationInput()
se_input.p_inj = np.array([ 3.948e+00, -8.000e+00, 4.400e+00, -6.507e-06, -1.407e-05])
se_input.p_inj_idx = np.arange(len(se_input.p_inj))
se_input.p_inj_weight = np.full(len(se_input.p_inj), 0.01)
se_input.q_inj = np.array([ 1.143e+00, -2.800e+00, 2.975e+00, 6.242e-07, 1.957e-06])
se_input.q_inj_idx = np.arange(len(se_input.q_inj))
se_input.q_inj_weight = np.full(len(se_input.q_inj), 0.01)
se_input.vm_m = np.array([0.834, 1.019, 0.974])
se_input.vm_m_idx = pq
se_input.vm_m_weight = np.full(len(se_input.vm_m), 0.01)
# First time will be slow due to compilation
start = time.time()
estimator = StateEstimator()
v_sol, err, converged, results = estimator.solve_se_lm(se_input, Ybus, Yf, Yt, f, t, slack, pq, pv, flat=True)
print("compilation + execution time:", time.time() - start)
bdd_validation(results, m=len(se_input.measurements), n=Ybus.shape[0] + len(pq) + len(pv))
# But then it will be very performant
start = time.time()
v_sol, err, converged, results = estimator.solve_se_lm(se_input, Ybus, Yf, Yt, f, t, slack, pq, pv, flat=True)
print("Execution time:", time.time() - start)
# Start from previous solution (set flat = False)
start = time.time()
v_sol, err, converged, results = estimator.solve_se_lm(se_input, Ybus, Yf, Yt, f, t, slack, pq, pv, flat=False)
print("Execution time:", time.time() - start)
# False data injection
se_input.vm_m[1] -= 0.025
se_input.vm_m[2] += 0.025
v_sol, err, converged, results = estimator.solve_se_lm(se_input, Ybus, Yf, Yt, f, t, slack, pq, pv)
print("-------------After False Data Injection-------------")
bdd_validation(results, m=len(se_input.measurements), n=Ybus.shape[0] + len(pq) + len(pv))
References
Temperature Dependent Power Flow (Temperature Dependent Load Flow)
S. Frank, J. Sexauer and S. Mohagheghi, "Temperature-Dependent Power Flow," in IEEE Transactions on Power Systems, vol. 28, no. 4, pp. 4007-4018, Nov. 2013, doi: 10.1109/TPWRS.2013.2266409.
Rahman, Mahbubur et al. “Power handling capabilities of transmission systems using a temperature-dependent power flow.” Electric Power Systems Research (2019): n. pag.
Acknowledge
This work was supported by the U.S. Department of Energy (DOE) under award DE-OE0000895 and the Sandia National Laboratories’ directed R&D project #222444.
Metadata
Release files for fastSE 0.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| fastSE-0.3.2.tar.gz | 232.2 kB | Without provenance | Details for fastSE-0.3.2.tar.gz |
Release files / fastSE-0.3.2.tar.gz
| Download URL | fastSE-0.3.2.tar.gz |
|---|---|
| Size | 232.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e93a472d7a59d8908651cf883ab63d09ce03927202a92be578e1e6200c909655
|
|
BLAKE2b-256 checksum How to use checksums |
4667630ff340799f55f9e2baf47a0011e4452140f5d9974f93a49986f2d1465f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.9.7
|
Security for fastSE 0.3.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.