Basic Capacity Planning#
Capacity planning is the process of figuring out the optimal amount of electricity generation capacity needed to reliably meet future demand within a power grid.
1. Load packages
We are using the gurobipy package to formulate a mathematical model and solve it.
import gurobipy as gp
from gurobipy import GRB
import numpy as np
import matplotlib.pyplot as plt
2. Define parameters
Symbol |
Description |
Data |
---|---|---|
G |
Number of generators |
2 |
H |
Number of hours |
8760 |
O |
Number of segments in piecewise load duration curve |
2 |
\(FC_i\) |
Fixed cost |
[140, 120] |
\(VC_i\) |
Variable cost |
[0.0238, 0.0336] |
\(ldcm_o\) |
slope of piecewise load duration curve in GW |
[-0.003, -0.0004427] |
\(ldcn_o\) |
intercepts of piecewise load duration curve in GW |
[15, 8.728] |
# high cap (HC) and low cap (LC) cost functions
# in M$/GW
G = 2
H = 8760
fixed = [140, 120] # HC LC
varia = [0.0238, 0.0336] # HC LC
# piecewise load duration curve in GW
ldc_m = [-0.003, -0.0004427] # slope
ldc_n = [15, 8.628] # intercepts
3. Define mathematical model
Objective function:
Minimize the sum cost \(c_i\), which depends on the capacity \(\overline{p}_{i}\) and production \(p_{i,h}\) of each generator i.
Decision variables:
\(p_{i,h}\) production of generator i in hour h.
\(\overline{p}_{i}\) capacity of generator i.
Constraints:
The cost \(c_i\) is equal to the fixed cost \(FC_{i}\) multiplied by the capacity \(\overline{p}_{i}\) and the variable cost \(VC_{i}\) multiplied by the production \(p_i\).
The sum of capacity \(\overline{p}_{i}\) needs to be greater equal to the load duration curve.
The output of each generator \(p_i\) has to greater equal to \(0\) and cannot exceed \(\overline{p}_{i}\).
m = gp.Model()
m.setParam('OutputFlag', 0)
cost = m.addVars(G, name="cost") # $
cap = m.addVars(G, name="cap") # installed capacity in GW
p = m.addVars(G, H, name="p") # hourly generator utilization
for i in range(G):
# compute total cost
m.addConstr(cost[i] == fixed[i]*cap[i] + varia[i]*sum(p[i,h] for h in range(H)))
for h in range(H):
m.addConstr(p[i,h] <= cap[i])
for h in range(H):
for o in range(G):
# production must at least meet demand
m.addConstr(sum(p[i,h] for i in range(G)) >= ldc_m[o]*h + ldc_n[o])
m.setObjective(cost.sum(), GRB.MINIMIZE)
m.optimize()
Set parameter Username
Academic license - for non-commercial use only - expires 2025-11-15
4. Inspect the solution
print(f"High cap generation capacity in GW: {m.getVarByName('cap[0]').X:.2f}")
print(f"Low cap generation capacity in GW: {m.getVarByName('cap[1]').X:.2f}")
High cap generation capacity in GW: 8.88
Low cap generation capacity in GW: 6.12