"""
Generator Variables and Parameters Module
=========================================
EELT7030 — Operation and Expansion Planning of Electric Power Systems
Federal University of Paraná (UFPR)
Author
------
Augusto Mathias Adams <augusto.adams@ufpr.br>
Summary
-------
This module defines the **sets**, **parameters**, and **decision variables**
for the generator subsystem of the MDI optimization model.
It provides the necessary data-to-model mapping between structured input
(`GeneratorData`) and symbolic Pyomo model components.
Description
-----------
Two main functions are provided:
1. **`generator_add_sets_and_params()`**
Initializes all sets, mappings, and scalar parameters from structured
input data. It ensures consistency between the data schema and the
model’s symbolic representation.
2. **`generator_add_variables()`**
Defines the Pyomo decision variables representing generation levels
and investment states.
The structure follows the standard formulation of generation expansion
and operation problems, enabling full reproducibility and modular
integration within larger system models.
Mathematical Representation
----------------------------
**Decision variables**
\[
\begin{align}
P_{g,t,p} &\ge 0 &\quad& \text{Power generated by unit } g \text{ at time } t, \text{ level } p \\
y_{g,t} &\in \{0,1\} &\quad& \text{Investment decision for unit } g \text{ at time } t \\
x_{g,t} &\in \{0,1\} &\quad& \text{Operational state (existing) of unit } g \text{ at time } t
\end{align}
\]
**Parameters**
\[
\begin{align}
p^{\max}_g &: \text{Maximum generation capacity of unit } g \\
c^{op}_g &: \text{Variable operational cost of unit } g \\
c^{inv}_g &: \text{Investment cost of unit } g \\
\text{state}_g &: \text{Initial operational status (built or not)} \\
h_p &: \text{Duration (hours) of demand level } p
\end{align}
\]
Functions
---------
generator_add_sets_and_params(m, data)
Initializes all sets and parameters in the model based on structured input.
generator_add_variables(m)
Defines decision variables for generation, investment, and operational state.
Notes
-----
- The resulting model components are compliant with the naming conventions
used throughout the MDI package.
- Demand values (`m.d`) are retained in their dictionary structure for
compatibility with subsequent constraint and objective definitions.
- The binary variables `gen_y` and `gen_x` can be relaxed to continuous
domains for convex approximations or LP relaxations.
References
----------
[1] CEPEL. *DESSEM — Manual de Metodologia*, 2023.
[2] Unsihuay Vila, C. *Introdução aos Sistemas de Energia Elétrica*, Lecture Notes,
EELT7030/UFPR, 2023.
Module Dependencies
-------------------
- **Internal:** ``GeneratorDataTypes``
- **External:** ``pyomo.environ`` (RangeSet, Set, Param, Var, NonNegativeReals, Binary)
"""
from pyomo.environ import (
RangeSet, Set, Param, Var, NonNegativeReals, Binary, ConcreteModel
)
from .GeneratorDataTypes import GeneratorData
[docs]
def generator_add_sets_and_params(m: ConcreteModel,
data: GeneratorData) -> ConcreteModel:
"""
Initialize generator-related sets and parameters in the model.
This function converts structured data into Pyomo components,
including time, unit, and demand level sets, as well as the
associated economic and technical parameters for each generator.
Parameters
----------
m : pyomo.environ.ConcreteModel
Pyomo model instance to which the sets and parameters will be added.
data : GeneratorData
Structured generator data object containing all relevant
attributes (units, demand, horizon, and level hours).
Returns
-------
pyomo.environ.ConcreteModel
The model with newly created sets, parameters, and demand data.
Notes
-----
The following components are created:
- Sets:
- ``T``: time periods (1..horizon)
- ``P``: load levels
- ``GU``: generator units
- Parameters:
- ``gen_pmax``: maximum generation capacity (MW)
- ``gen_c_op``: variable operational cost (R$/MWh)
- ``gen_c_inv``: investment cost (R$/MW)
- ``gen_state``: initial availability status (binary)
- ``level_hours``: duration of each load level (hours)
"""
# Horizon and base collections
T = data.horizon
U = list(data.units.keys())
P = list(data.demand.keys())
level_hours = data.level_hours
# Time, units, and load-level sets
if not hasattr(m, "T"):
m.T = RangeSet(1, T)
if not hasattr(m, "P"):
m.P = Set(initialize=P)
if not hasattr(m, "level_hours"):
m.level_hours = level_hours
m.GU = Set(initialize=U) # Generator Units
# Demand data (non-symbolic dictionary structure)
if not hasattr(m, "d"):
m.d = data.demand
# Generator parameters
m.gen_pmax = Param(m.GU, initialize={u: data.units[u].p_max for u in U})
m.gen_c_op = Param(m.GU, initialize={u: data.units[u].c_op for u in U})
m.gen_c_inv = Param(m.GU, initialize={u: data.units[u].c_inv for u in U})
m.gen_state = Param(m.GU, initialize={u: data.units[u].state for u in U})
m.gen_include_cap = Param(m.GU, initialize={u: data.units[u].include_cap for u in U})
return m
[docs]
def generator_add_variables(m: ConcreteModel) -> ConcreteModel:
"""
Define decision variables for the generator subsystem.
Creates Pyomo decision variables representing generation output,
investment decisions, and cumulative operational existence for
each generator, time period, and load level.
Parameters
----------
m : pyomo.environ.ConcreteModel
Pyomo model instance containing the sets previously defined
by ``generator_add_sets_and_params``.
Returns
-------
pyomo.environ.ConcreteModel
The same model, extended with generator-related decision variables.
Notes
-----
The following variables are created:
- ``gen_P[g,t,p]`` — Power generated by unit *g* at time *t* and level *p* (MW).
Domain: :math:`\\mathbb{R}_+`
- ``gen_y[g,t]`` — Binary investment decision (1 if built at *t*, 0 otherwise).
Domain: :math:`\\{0,1\\}`
- ``gen_x[g,t]`` — Binary variable representing existing or active capacity at *t*.
Domain: :math:`\\{0,1\\}`
"""
# Generated power by unit, time, and level
m.gen_P = Var(m.GU, m.T, m.P, within=NonNegativeReals)
# Binary investment and operational decision variables
m.gen_y = Var(m.GU, m.T, within=Binary) # investment decision
m.gen_x = Var(m.GU, m.T, within=Binary) # cumulative existence
return m