Author: Shankar Karki
GitHub: @shankarkarki
Status: 🔨 Active Development
This project formulates and solves the AC Optimal Power Flow (AC OPF) problem from scratch on IEEE standard test systems, applies Second Order Cone (SOC) relaxation to obtain provable upper bounds, and computes the optimality gap to quantify solution quality.
The goal is not to use existing power systems tools as a black box — but to formulate the nonlinear problem explicitly, understand why it is hard to solve globally, and apply convex relaxation techniques from the optimization literature to certify solution quality.
Most industry tools (PLEXOS, PROMOD, NEMDE) use the DC approximation of power flow:
P = B · θ (linear)
This linearization:
- Assumes all voltage magnitudes = 1.0 per unit (flat voltage profile)
- Ignores reactive power Q entirely
- Ignores real transmission losses
- Works reasonably well for lightly loaded transmission networks
But DC approximation breaks down when:
- Networks are heavily loaded or congested
- Voltage violations need to be tracked
- Reactive power management matters
- Distribution networks (unbalanced, high R/X ratio)
- High renewable penetration causes significant voltage variation
Full AC OPF preserves all physics — but introduces nonlinearity and nonconvexity.
The AC power flow equations at each bus i are:
These are nonlinear (products of voltages) and nonconvex (trigonometric terms, multiple local optima possible).
When embedded as constraints in an optimization problem, local solvers like IPOPT can find a locally optimal solution — but cannot prove it is globally optimal. There may exist a cheaper feasible solution that the solver never finds.
The optimality gap quantifies the uncertainty between:
Lower bound = best feasible AC solution found (local solver)
Upper bound = SOC relaxation optimal value (global, convex)
Gap = (Upper - Lower) / Upper × 100%
- Gap = 0% → local solution is proven globally optimal
- Gap > 0% → solution may be suboptimal, gap quantifies worst case
A key theoretical result (Lavaei & Low, 2012) shows that SOC relaxation is exact (gap = 0%) for many practical networks — meaning the local solution IS globally optimal. This project verifies this result empirically across multiple IEEE test systems.
Step 1: Load IEEE standard test system (pandapower)
↓
Step 2: Solve AC OPF using IPOPT (local nonlinear solver)
→ Variables: |V|, θ, Pg, Qg at each bus
→ Objective: minimize generation cost Σ(ai·Pgi² + bi·Pgi)
→ Constraints: AC power balance, voltage limits, line limits
→ Result: locally optimal cost C_local
↓
Step 3: Formulate SOC Relaxation
→ Introduce lifted variables: Wii = Vi², Wij = ViVj·cos(θij), Rij = ViVj·sin(θij)
→ Power flow equations become linear in W, R
→ Enforce SOC constraint: Wij² + Rij² ≤ Wii·Wjj (convex)
→ Solve with convex solver (HiGHS/ECOS)
→ Result: globally optimal upper bound C_SOC
↓
Step 4: Compute optimality gap
→ Gap = (C_SOC - C_local) / C_SOC × 100%
↓
Step 5: Analyze across IEEE 9, 14, 30, 57 bus systems
→ Identify where relaxation is tight (gap = 0%)
→ Identify where relaxation is loose (gap > 0%)
→ Explain physically why gap emerges under congestion
Decision variables:
-
$|V_i|$ — voltage magnitude at bus i -
$\theta_i$ — voltage angle at bus i -
$P_{g,i}$ ,$Q_{g,i}$ — active and reactive power generation at bus i
Objective:
Constraints:
Active power balance (nonlinear equality):
Reactive power balance (nonlinear equality):
Voltage limits:
Generator limits:
Line thermal limits:
Introduce lifted variables:
Power flow equations become linear:
The exact constraint linking W and R is:
Relaxing equality to inequality gives the SOC constraint:
This is a convex second order cone constraint — the relaxed problem is now a convex SOCP solvable to global optimality.
| System | Buses | Generators | Lines | Source |
|---|---|---|---|---|
| IEEE 9-bus | 9 | 3 | 9 | pandapower.networks.case9() |
| IEEE 14-bus | 14 | 5 | 20 | pandapower.networks.case14() |
| IEEE 30-bus | 30 | 6 | 41 | pandapower.networks.case30() |
| IEEE 57-bus | 57 | 7 | 80 | pandapower.networks.case57() |
All cases validated against PGLIB-OPF benchmarks.
ac-opf-relaxation/
├── README.md ← you are here
├── requirements.txt ← dependencies
├── src/
│ ├── __init__.py
│ ├── network_loader.py ← load and parse IEEE test cases
│ ├── ac_opf.py ← AC OPF formulation in Pyomo + IPOPT
│ ├── soc_relaxation.py ← SOC relaxation formulation
│ ├── dc_opf.py ← DC OPF for baseline comparison
│ └── gap_analysis.py ← compute and compare optimality gaps
├── results/
│ ├── gap_table.csv ← summary results across test cases
│ └── figures/ ← voltage profiles, gap charts
└── data/ ← auto-populated by pandapower
# Clone repository
git clone https://github.com/shankarkarki/ac-opf-relaxation.git
cd ac-opf-relaxation
# Install Python dependencies
pip install -r requirements.txt
# Install IPOPT (nonlinear solver) via conda (recommended)
conda install -c conda-forge ipopt
# OR via idaes (if no conda)
pip install idaes-pse
idaes get-extensions# Step 1: Verify installation
python src/network_loader.py
# Step 2: Solve AC OPF on IEEE 9-bus
python src/ac_opf.py --case 9
# Step 3: Solve SOC relaxation
python src/soc_relaxation.py --case 9
# Step 4: Compute optimality gap across all cases
python src/gap_analysis.pyBeing updated as development progresses.
| System | AC OPF Cost | SOC Bound | Gap (%) | AC OPF Time (s) |
|---|---|---|---|---|
| IEEE 9-bus | — | — | — | — |
| IEEE 14-bus | — | — | — | — |
| IEEE 30-bus | — | — | — | — |
| IEEE 57-bus | — | — | — | — |
-
Lavaei & Low (2012) — Zero duality gap in optimal power flow problem. IEEE Transactions on Power Systems. — Seminal paper proving SOC relaxation is exact under certain conditions.
-
Molzahn & Hiskens (2019) — A Survey of Relaxations and Approximations of the Power Flow Equations. Foundations and Trends in Electric Energy Systems. — Comprehensive survey of all relaxation approaches.
-
Jabr (2006) — Radial distribution load flow using conic programming. IEEE Transactions on Power Systems. — Original SOC relaxation formulation.
-
PGLIB-OPF Benchmark Library — https://github.com/power-grid-lib/pglib-opf — Standard benchmark for AC OPF research.
-
MATPOWER — https://matpower.org — Reference implementation for power flow and OPF.
- Project structure and README
- network_loader.py — IEEE case loading and parsing
- ac_opf.py — Full AC OPF in Pyomo + IPOPT
- soc_relaxation.py — SOC relaxation formulation
- dc_opf.py — DC OPF baseline
- gap_analysis.py — Gap computation across test cases
- Results table and figures
- Validation against PGLIB-OPF benchmarks
- Blog post writeup
MIT License — free to use, modify and distribute with attribution.