This document describes the mathematical optimization model implemented in the provided C++ code (“SCUC”).
Scope note
- The model includes thermal unit commitment, piecewise-linear production costs, startup categories, reserves (with optional shortfall), profiled generators, price-sensitive loads, conventional load curtailment, and a DC network with PTDF base-case limits and LODF N-1 limits (with soft overflow penalties).
All indices are 0-based, consistent with the code.
-
Time steps:
$\mathcal{T}={0,1,\dots,T-1}$ -
Buses:
$\mathcal{B}={0,1,\dots,|\mathcal{B}|-1}$ -
Transmission lines:
$\mathcal{L}={0,1,\dots,|\mathcal{L}|-1}$ -
Thermal generators:
$\mathcal{G}={0,1,\dots,|\mathcal{G}|-1}$ -
Profiled generators:
$\mathcal{P}={0,1,\dots,|\mathcal{P}|-1}$ -
Price-sensitive loads (PSL):
$\mathcal{D}={0,1,\dots,|\mathcal{D}|-1}$ -
Reserve requirement products (each is a spinning requirement time series):
$\mathcal{R}={0,1,\dots,|\mathcal{R}|-1}$ -
Reserve-eligible thermal generators:
Let$\mathcal{G}^{res}\subseteq \mathcal{G}$ be the subset of thermal gens that can provide reserve.
Code builds a mapping:map_res:$\mathcal{G}^{res}\to {0,1,\dots,|\mathcal{G}^{res}|-1}$ and reserve variables are indexed by$i\in{0,\dots,|\mathcal{G}^{res}|-1}$ . -
Relevant N-1 contingency pairs:
The code builds a list of monitored/outage pairs:$\mathcal{Q}\subseteq {(k,\ell)\in\mathcal{L}\times\mathcal{L}: k\neq \ell}$ including$(k,\ell)$ if the contingency list contains outage line$k$ and$|\text{LODF}_{\ell,k}|>\varepsilon$ .
Each pair is indexed by$q\in{0,\dots,|\mathcal{Q}|-1}$ with:- outage line
$k(q)$ - monitored line
$\ell(q)$
- outage line
-
Min/max power:
$P^{min}_g,; P^{max}_g$ -
Ramp limits:
$RU_g,; RD_g$ -
Startup/shutdown power limits (used for tightening):
$P^{SUlim}_g,; P^{SDlim}_g$ -
Minimum up/down times:
$U_g,; D_g \in \mathbb{Z}_{\ge 0}$ -
No-load cost:
$C^{NL}_g$ -
Initial status (integer):
-
init_status_g$> 0$ : unit initially ON for$|init_status_g|$ periods -
init_status_g$< 0$ : unit initially OFF for$|init_status_g|$ periods
-
-
Initial power:
$P^{init}_g$ -
Must-run flag and optional fixed commitment status:
- must-run:
must_run_g$\in{0,1}$ - optional fixed commitment sequence
fix$_{g,t}\in{0,1}$ for some times$t$
- must-run:
Let
- Segment length
$\ell_{g,s}$ and slope$c_{g,s}$ for$s\in\mathcal{S}_g$
Let
- Stage
$k$ has: $Del_{g,k}\in\mathbb{Z}{\ge 0}, \quad C^{SU}{g,k}\ge 0$
- Time-varying bounds: $P^{min}{p,t},; P^{max}{p,t}$
- Linear generation cost:
$C^{prof}_p$
- Demand cap and revenue: $D^{max}{d,t},\quad Rev{d,t}$
- Required amount:
$Req_{r,t}$ - Shortfall penalty (enables shortfall only if positive):
$Pen^{res}_r$
- Nodal demand:
$Load_{t,b}$ - Curtailment penalty:
$Pen^{curt}$
- PTDF matrix:
$PTDF_{\ell,b}$ - LODF matrix:
$LODF_{\ell,k}$ - Line limits and penalties:
- Base-case (normal) limit:
$Lim^{N}_{\ell}$ - Contingency (emergency) limit:
$Lim^{E}_{\ell}$ - Overflow penalty:
$Pen^{flow}_{\ell}$
- Base-case (normal) limit:
- Commitment:
$u_{g,t}\in{0,1}$ - Shutdown:
$w_{g,t}\in{0,1}$ - Power:
$p_{g,t}\ge 0$
-
$v_{g,k,t}\in{0,1}$ for$k\in\mathcal{K}_g$
Define the (implicit) switch-on indicator: $$y_{g,t}\triangleq \sum_{k\in\mathcal{K}g} v{g,k,t}$$
-
$p^{seg}_{g,s,t}\ge 0$ for$s\in\mathcal{S}_g$
Above-min production (not explicit variable in code): $$p^{above}{g,t}\triangleq \sum{s\in\mathcal{S}g} p^{seg}{g,s,t}$$
- Generator reserve:
$r_{i,t}\ge 0$ for$i\in{0,\dots,|\mathcal{G}^{res}|-1}$ - Reserve shortfall (only if $Pen^{res}r>0$): $sh{r,t}\ge 0$
$p^{prof}_{p,t}\ge 0$
$s^{psl}_{d,t}\ge 0$
-
$curt_{b,t}\ge 0$ with bounds:$0 \le curt_{b,t} \le Load_{t,b}$
- Base overflow:
$ov^{base}_{\ell,t}\ge 0$ - Contingency overflow:
$ov^{cont}_{q,t}\ge 0$
Minimize total cost:
For each
For each reserve product
-
If $Pen^{res}r>0$: $$\sum{i} r_{i,t} + sh_{r,t} \ge Req_{r,t}$$
-
If $Pen^{res}r\le 0$: $$\sum{i} r_{i,t} \ge Req_{r,t}$$
Fix a generator
Let initOn_g
If initOn_g
If initOn_g
For
For all
- Startup implies on:
$$y_{g,t} \le u_{g,t}$$ - For
$t\ge 1$ , startup only if was previously off:$$y_{g,t} \le 1-u_{g,t-1}$$ - For
$t\ge 1$ , shutdown only if was previously on:$$w_{g,t} \le u_{g,t-1}$$ - For
$t\ge 1$ , shutdown implies off now:$$w_{g,t}+u_{g,t}\le 1$$
Minimum up-time:
Minimum down-time (equivalent to code’s form):
Define:
$$p^{above}{g,t}=\sum{s\in\mathcal{S}g} p^{seg}{g,s,t}.$$
If
Ramp-up (
Ramp-down (
Initial ramps ($t=0$ ):
Let initOn_g $=\mathbf{1}[init_status_g>0]$ and
$$p^{init,above}_g= \begin{cases} \max(0, P^{init}g-P^{min}g) & \text{if } initOn_g=1 \ 0 & \text{if } initOn_g=0 \end{cases}$$
Then:
$$p^{above}{g,0}+r{g,0}\le p^{init,above}g+RU_g$$
$$p^{above}{g,0}\le RD_g - p^{init,above}_g$$
Let:
Startup limit (all
Shutdown limit (for
If must-run:
fix${g,t}$ is provided:
$$u{g,t}=fix_{g,t} \quad \text{for those } t$$
For
This section describes the exact logic enforced by the code for choosing startup categories.
Assume stages are indexed so that:
Let initOn_g initOn_g
The code adds constraints only for categories
For each time
-
An initial-status allowance term
$L^{init}_{g,k,t}\in{0,1}$ :- If the unit is initially OFF, define
offdur$= initOffDur_g + t$ . - Then: $$L^{init}{g,k,t} = \begin{cases} 1 & \text{if } offdur \in [Del{g,k},, Del_{g,k+1}-1] \ 0 & \text{otherwise} \end{cases}$$
- If initially ON, then
$L^{init}_{g,k,t}=0$ .
- If the unit is initially OFF, define
-
A shutdown window:
$$lb = \max(0,; t-Del_{g,k+1}+1), \qquad ub = t-Del_{g,k}.$$
Then the code enforces:
If the window is empty (i.e.,
Interpretation (code-consistent):
- Selecting startup category
$k$ at time$t$ is permitted if either:- the initial offline duration implies category
$k$ is feasible at time$t$ (via$L^{init}=1$ ), or - there has been at least one shutdown event
$w_{g,i}=1$ in the window$i\in[lb,ub]$ , i.e., a shutdown occurred at a time consistent with being offline for a duration in$[Del_{g,k},,Del_{g,k+1}-1]$ .
- the initial offline duration implies category
The coldest category
For each
For each
For each
The code does not explicitly create net-injection or flow variables; it builds line constraints directly by expanding injections into generator/load variables using PTDF rows.
For bus
For each line
Let
For each pair
This SCUC model chooses:
- thermal unit on/off schedules and dispatch,
- startup categories and costs,
- reserve provision (and optional shortfall),
- profiled generation within availability bounds,
- price-sensitive load served if profitable,
- load curtailment only if necessary (penalized),
- while enforcing base-case and N-1 network limits using PTDF/LODF with soft overflow penalties.