Core Concepts
GridOverture is built around five key concepts: the Internal Representation, Adapters, Protocols, the Solver Registry, and the Test Case Registry.
Internal Representation (IR)
The IR is GridOverture's solver-agnostic network model. When you call go.load(), the test case data is parsed into this common format. When you call go.run_load_flow(), the IR is translated into the solver's native format, solved, and the results are translated back.
import gridoverture as go
net = go.load("ieee39")
# Access IR data directly
print(net.buses) # DataFrame of all buses
print(net.lines) # DataFrame of all lines/branches
print(net.generators) # DataFrame of all generators
print(net.loads) # DataFrame of all loads
The IR stores:
- Buses — voltage magnitude, angle, type (PQ, PV, slack)
- Lines/Branches — impedance, ratings, tap ratios
- Generators — active/reactive power setpoints, limits
- Loads — active/reactive power demand
- Shunts — susceptance, conductance
The IR is a plain data structure (DataFrames and metadata). It carries no solver state — it's a snapshot of the network topology and parameters.
Adapters
Adapters are the bridge between the IR and a specific solver backend. Each supported solver has an adapter that handles two translations:
- IR to solver — convert the generic network into the solver's native format
- Solver to IR — convert solver results back into a standardized result object
IR Network → [Adapter] → Solver Native Format → [Solve] → Native Results → [Adapter] → IR Results
You rarely interact with adapters directly. The facade functions (go.run_load_flow, go.compare) select the correct adapter based on the solver parameter:
# Behind the scenes, this selects the Veragrid adapter
result = go.run_load_flow(net, solver="veragrid")
# You can also access adapters explicitly
from gridoverture.adapters import get_adapter
adapter = get_adapter("pypsa")
pypsa_net = adapter.to_native(net)
Protocols
GridOverture uses Python Protocol classes to define what capabilities a solver adapter must provide. This ensures type safety without requiring inheritance.
from typing import Protocol
class LoadFlowPort(Protocol):
"""Any solver that can run a load flow must implement this."""
def run_load_flow(self, network: IRNetwork) -> LoadFlowResult: ...
class OPFPort(Protocol):
"""Any solver that can run optimal power flow must implement this."""
def run_opf(self, network: IRNetwork) -> OPFResult: ...
Current protocol support by solver:
| Solver | LoadFlowPort | OPFPort |
|---|---|---|
| andes | Yes | — |
| veragrid | Yes | — |
| pypsa | Yes | Yes (LOPF) |
| pandapower | Yes | Yes (AC OPF) |
| dc | Yes | — |
| pypsa-dc | Yes | — |
| pandapower-dc | Yes | — |
Solver Registry
Solvers are registered at import time. The registry maps solver names to their adapter classes and tracks which protocols each solver supports.
import gridoverture as go
# List all registered solvers
print(go.available_solvers())
# ['andes', 'veragrid', 'pypsa', 'pandapower', 'dc', 'pypsa-dc', 'pandapower-dc']
# Check if a specific solver is available
print(go.solver_available("veragrid"))
# True
A solver only appears in available_solvers() if its Python package is installed. Install the corresponding extra to enable it (e.g., pip install gridoverture[andes]).
Test Case Registry
GridOverture ships with 8 built-in test networks covering a range of system sizes:
import gridoverture as go
# List all available test networks
print(go.available_networks())
# ['ieee14', 'ieee24', 'ieee39', 'ieee57', 'ieee118', 'ieee300', 'uk_29bus', 'wecc240']
# Load a specific network
net = go.load("ieee118")
print(f"Buses: {len(net.buses)}, Lines: {len(net.lines)}")
# Buses: 118, Lines: 186
| Network | Buses | Lines | Description |
|---|---|---|---|
| ieee14 | 14 | 20 | Small test system |
| ieee24 | 24 | 38 | IEEE Reliability Test System |
| ieee39 | 39 | 46 | New England test system |
| ieee57 | 57 | 80 | Medium test system |
| ieee118 | 118 | 186 | Large test system |
| ieee300 | 300 | 411 | Very large test system |
| uk_29bus | 29 | 99 | UK transmission network |
| wecc240 | 240 | 448 | Western US interconnection |
How It All Fits Together
┌─────────────────────────────────────────────────┐
│ Facade API │
│ go.load() / go.run_load_flow() │
│ go.compare() / go.run_opf() │
├─────────────────────────────────────────────────┤
│ Solver Registry │
│ Discovers and routes to solver adapters │
├──────────┬──────────┬──────────┬────────────────┤
│ ANDES │ Veragrid │ PyPSA │ pandapower │
│ Adapter │ Adapter │ Adapter │ Adapter │
├──────────┴──────────┴──────────┴────────────────┤
│ Internal Representation (IR) │
│ Buses, Lines, Generators, Loads, Shunts │
├─────────────────────────────────────────────────┤
│ Test Case Registry │
│ IEEE 14/24/39/57/118/300, UK 29, WECC 240 │
└─────────────────────────────────────────────────┘