Skip to main content

Multi-period Optimal Power Flow for distribution grids with storage — Pyomo models over pandapower networks

Project description

potpourri

Multi-Period Optimal Power Flow for Distribution Grids with Storage Application

Potpourri — piece of music composed from various popular smaller works or melodies

CI Documentation Status License: MIT

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, EVs, heat pumps, PV, wind). It wraps Pyomo for optimisation modelling over pandapower network objects.

Repository: https://github.com/RWTH-IAEW/opf-potpourri


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
  ├── Windpower_multi_period
  ├── Demand_multi_period
  ├── Sgens_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

Citation

If you use potpourri in your research, please cite it using the metadata in CITATION.cff. A BibTeX entry will be available once a Zenodo DOI is registered for the release.


License

potpourri is released under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

opf_potpourri-0.2.0.tar.gz (62.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

opf_potpourri-0.2.0-py3-none-any.whl (78.2 kB view details)

Uploaded Python 3

File details

Details for the file opf_potpourri-0.2.0.tar.gz.

File metadata

  • Download URL: opf_potpourri-0.2.0.tar.gz
  • Upload date:
  • Size: 62.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.3

File hashes

Hashes for opf_potpourri-0.2.0.tar.gz
Algorithm Hash digest
SHA256 a71db5dfad20464fa6a21f59cc6022409262a5eec205075c5a0b14fc5823382b
MD5 4119c5047db02779d192858a9cc752c6
BLAKE2b-256 aacc7566f6f0afc45b50c70f81ef1f3b2dcc34d0ef02821efcafca8b03474d63

See more details on using hashes here.

File details

Details for the file opf_potpourri-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for opf_potpourri-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3d03783f8ce27c4d6c0f0775a773d0918c2b7dbf288d5f6c575e953356780b10
MD5 e64541f2a6fa99527d9cf9cfd54b9668
BLAKE2b-256 cbe823a08fe9106fddd657fb4b42d5cbd84587c6632c429f057d8ede0ff63c9e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page