Basic Capacity Planning

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}\).

(2)#\[\begin{align} \min \quad & \sum_{i=1}^{G} c_i \hspace{-4cm}\\ \text{s.t.}\quad & c_i = \left( FC_{i} \overline{p}_{i} + \sum_{h=1}^{H} VC_i p_{i,h} \right) && \forall h \in [H] \\ & \sum_{i=1}^{G} p_{i,h} \geq ldcm_{o}*h + ldcn_{o} && \forall h \in [H], o=1,2 \\ & 0 \leq p_{i,h} \leq \overline{p}_{i} && \forall i \in [G] , h \in [H] \end{align}\]
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