potpourri
Multi-Period Optimal Power Flow for Distribution Grids with Storage Application
Potpourri — piece of music composed from various popular smaller works or melodies
potpourri is a Python library for AC/DC Optimal Power Flow (OPF) in distribution grids, with support for multi-period planning and flexible resources (batteries, heat pumps, PV, wind). It wraps Pyomo for optimisation modelling over pandapower network objects.
Documentation
The project documentation is built with MkDocs.
To serve the documentation locally:
pip install -e .[docs]
mkdocs serve # usually available at http://127.0.0.1:8000/
Installation
Requires Python 3.9–3.12 and Conda (or Mamba).
conda env create -f environment.yaml
conda activate potpourri_env
pip install -e .
To update an existing environment:
conda env update -f environment.yaml --prune
A Dockerfile is provided for a fully containerised setup with IPOPT 3.14.16 compiled from source, CBC, and SHOT solvers.
Quick start
Single-period AC OPF
import simbench as sb
from potpourri.models.ACOPF_base import ACOPF
net = sb.get_simbench_net("1-LV-rural1--0-sw")
opf = ACOPF(net)
opf.add_OPF()
opf.add_voltage_deviation_objective()
opf.solve(solver="ipopt", print_solver_output=False)
# results available in net.res_bus, net.res_line, net.res_sgen, ...
print(opf.net.res_bus[["vm_pu", "va_degree"]])
Multi-period AC OPF with battery storage
import simbench as sb
from potpourri.models_multi_period.ACOPF_multi_period import ACOPF_multi_period
from potpourri.technologies.battery import Battery_multi_period
net = sb.get_simbench_net("1-LV-urban6--0-sw")
opf = ACOPF_multi_period(net, toT=96, fromT=0) # 96 × 15 min = 1 day
battery = Battery_multi_period(opf.net, T=96, scenario=1)
battery.get_all(opf.model)
opf.add_OPF()
opf.add_voltage_deviation_objective()
opf.solve(solver="ipopt")
See scripts/ for runnable examples covering each feature area.
Architecture
Single-period models (src/potpourri/models/)
Basemodel creates ConcreteModel, maps pandapower → Pyomo sets/params, solve()
├── AC full AC power flow (KCL/KVL, voltage magnitudes, reactive power)
├── DC linearised DC power flow (no reactive power)
└── OPF operational constraints (P/Q limits, line loading, voltage bounds)
ACOPF = AC + OPF (multiple inheritance)
DCOPF = DC + OPF
HC_ACOPF = ACOPF + binary variables for hosting-capacity analysis
Multi-period models (src/potpourri/models_multi_period/)
Basemodel_multi_period adds time index T, integrates SimBench profiles
└── ACOPF_multi_period (AC_multi_period + OPF_multi_period)
Flexibility_multi_period abstract base for all flexible devices
├── Battery_multi_period
├── Heatpump_multi_period
├── PV_multi_period
├── Sgens_multi_period
│ └── Windpower_multi_period
├── Demand_multi_period
├── Shunts_multi_period
└── Generator_multi_period
Flexible devices are composed, not inherited — each is instantiated separately and attaches its own Pyomo Sets/Params/Vars/Constraints to the parent model.
Data flow
pandapower net
→ Basemodel.__init__() pp.runpp(), extract admittance data
→ create_model() Pyomo ConcreteModel + sets/params/vars
→ add_OPF() unfix controllable vars, add limits/objectives
→ .solve(solver) SolverFactory → NLP/MIP
→ pyo_to_net() write solution back to net.res_*
External dependencies
| Package | Role |
|---|---|
pandapower >= 2.13 |
Network data model, initial power flow |
pyomo >= 6.7 |
Optimisation modelling |
simbench >= 1.4 |
Benchmark networks and time-series profiles |
numpy, pandas |
Numerical / data processing |
matplotlib |
Plotting |
Solvers
potpourri does not bundle any solvers. Install at least one before
calling solve().
| Solver | Type | Install |
|---|---|---|
| IPOPT | NLP — AC OPF | conda install -c conda-forge ipopt |
| GLPK | LP / MIP — DC OPF | conda install -c conda-forge glpk |
| CBC | LP / MIP | conda install -c conda-forge coincbc |
| Gurobi | LP / MIP / NLP | pip install gurobipy (licence required) |
| NEOS | Remote (free) | opf.solve(solver='neos', neos_opt='ipopt') |
IPOPT and GLPK are included automatically when you create the environment
from environment.yaml.
Development
pip install -e ".[dev]" # installs ruff, pytest, pytest-cov, pre-commit
ruff check . # lint
ruff format . # format
pytest # run tests
pytest -m "not integration" # skip solver-dependent tests
Analysis and example scripts are in scripts/. See scripts/README.md
for an overview of what each example demonstrates.
Authors
- Steffen Kortmann — IAEW, RWTH Aachen University
- Andreas Bong — IAEW, RWTH Aachen University
- Simon Braun — IAEW, RWTH Aachen University
- Alexander Och — IAEW, RWTH Aachen University
- Farah Nasr — IAEW, RWTH Aachen University
- Philip Kvesic — IAEW, RWTH Aachen University
- Nina Stumberger — IAEW, RWTH Aachen University
Metadata
Release files for opf-potpourri 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| opf_potpourri-0.5.0.tar.gz | 125.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| opf_potpourri-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 269.6 kB
Release files / opf_potpourri-0.5.0.tar.gz
| Download URL | opf_potpourri-0.5.0.tar.gz |
|---|---|
| Size | 125.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0c6fec54cde494977ee950cd9621c06cf3f6cdfcf753eab60cdd4fa0df14fc4c
|
|
BLAKE2b-256 checksum How to use checksums |
c25274657f2dbdad47703a4b8a42c5fa39508b90f13dee916152df199c66015e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / opf_potpourri-0.5.0-py3-none-any.whl
| Download URL | opf_potpourri-0.5.0-py3-none-any.whl |
|---|---|
| Size | 144.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fce9833213713d87f4af2764af5ab22aba2335cc96d9ebe6541158378939ca15
|
|
BLAKE2b-256 checksum How to use checksums |
e5098f4a642c455269dd1d3e40586853cf5f2dccebfc4721d6905697b705f7c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|