Skip to main content

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
info

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:

  1. IR to solver — convert the generic network into the solver's native format
  2. 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:

SolverLoadFlowPortOPFPort
andesYes
veragridYes
pypsaYesYes (LOPF)
pandapowerYesYes (AC OPF)
dcYes
pypsa-dcYes
pandapower-dcYes

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
warning

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
NetworkBusesLinesDescription
ieee141420Small test system
ieee242438IEEE Reliability Test System
ieee393946New England test system
ieee575780Medium test system
ieee118118186Large test system
ieee300300411Very large test system
uk_29bus2999UK transmission network
wecc240240448Western 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 │
└─────────────────────────────────────────────────┘

Next Steps