Optimization variables

EnergyModelsBase creates a variety of default variables for the individual nodes and edges. These default variables are in general also created when new Nodes or Links are developed. It is not necessary to utilize all of the default variables in the individual nodes. It is however recommended to include in this situation constraints or fixes using either the @constraint macro or alternatively the JuMP function fix(x, value). The latter is the recommended approach.

Note

The majority of the variables in EnergyModelsBase are rate variables. This imples that they are calculated for either an operational period duration of 1, when indexed over operational period $t$ or a strategic period duration of 1, when indexed over strategic period $t_\texttt{inv}$. Typical units for rates are MW for energy streams, tonne/hour for mass streams, tonne/year for strategic emissions, and €/year for operational expenditures. In this example, the duration of an operational period of 1 corresponds to an hour, while the duration of a strategic period of 1 corresponds to a year.

Variables that are energy/mass based have that property highlighted in the documentation below. In the standard implementation of EnergyModelsBase, this is only the case for the level of a Storage node, the change of level of the node, and its installed capacity.

Rate variables can as well be translated to mass/energy variables. As an example, the total quantity that flows into a node $n$ during the operational period $t$ can found by

m[:flow_in][n, t, p] * duration(t)

The multiplication then leads to an energy/mass quantity in stead of an energy/mass flow.

The coupling of strategic and operational periods can be achieved through the function scale_op_sp(t, t_inv). This functions allows for considering the scaling of the operational periods within a strategic period.

Operational cost variables

Operational cost variables are included to account for operational expenditures (OPEX) of the model. These costs are pure dependent on either the use or the installed capacity of a node $n$. All nodes $n$ (except Availability-nodes) have the following variables representing the operational costs of the nodes:

  • $\texttt{opex\_var}[n, t_\texttt{inv}]$: Variable OPEX of node $n$ in strategic period $t_\texttt{inv}$.
  • $\texttt{opex\_fixed}[n, t_\texttt{inv}]$: Fixed OPEX of node $n$ in strategic period $t_\texttt{inv}$.

The variable OPEX is a cost that derives from using a technology. It is calculated using the function constraints_opex_var. In general, it represents unmodelled feed to a process and the associated costs. Examples are catalyst replacement, cooling water or process water. The variable OPEX can also be utilized to provide values for a profit through using a technology.

The fixed OPEX is a cost that is independent of the usage of a technology. Instead, it is only dependent on the installed capacity. It is calculated using the function constraints_opex_fixed. It represents fixed costs like labour cost, maintenance, as well as insurances and taxes.

We also introduce the potential for links with operational costs. By default, links do not introduce new variables. Operational cost variables are only created for a link $l$ if the function has_opex(n::Link) returns true. The following link variables are then declared representing the operational costs of the links:

  • $\texttt{link\_opex\_var}[l, t_\texttt{inv}]$: Variable OPEX of link $l$ in strategic period $t_\texttt{inv}$.
  • $\texttt{link\_opex\_foxed}[l, t_\texttt{inv}]$: Fixed OPEX of link $l$ in strategic period $t_\texttt{inv}$.
Links with OPEX

All links introduced in EnergyModelsBase do not allow for operational costs. If you plan to introduce a link with operational costs, you have to create a new method for the function has_opex for your introduced link.

Capacity variables

Capacity variables focus on both the capacity usage and installed capacity. The capacity variables are also created for all nodes except for Availability nodes. Capacity variables are differentiated between Storage nodes and all other Nodes. The implementation of the capacity variables allows for a time-varying capacity during an operational period for inclusion of variations in the demand in Sink nodes. It is however not possible to invest into a time-varying capacity.

The following capacity variables are created for node types other than Storage:

  • $\texttt{cap\_use}[n, t]$: Absolute capacity usage of node $n$ at operational period $t$, and
  • $\texttt{cap\_inst}[n, t]$: Installed capacity of node $n$ at operational period $t$.

The capacity usage $\texttt{cap\_use}$ is the utilization of the installed capacity. It is declared in absolute values to avoid bilinearities when investing in capacities. It is normally constrained by the variable $\texttt{cap\_inst}$ of the individual nodes, except for Sink nodes.

The capacity variables for Storage nodes differentiate between storage capacity (stored energy in the Storage node) and rate of storage (storage rate of a Storage node). The latter is furthermore differentiated between charging and discharging a Storage node. A key reasoning for this approach is that it is in general possible to invest both in the storage rate (e.g., the AC-DC transformer required in battery storage) as well as the storage capacity (e.g. the number of cells in battery storage). The same holds as well for pumped hydro storage and storage of gases where there is a further differentiation between the maximum charging and discharging rates. The differentiation leads to the following variables for Storage nodes:

  • $\texttt{stor\_level}[n, t]$: Absolute level of energy/mass stored in a Storage node $n$ at operational period $t$ with a typical unit of GWh or t,
  • $\texttt{stor\_level\_inst}[n, t]$: Installed storage capacity in a Storage node $n$ at operational period $t$ , that is the upper bound for the variable $\texttt{stor\_level}[n, t]$, with a typical unit of GWh or t,
  • $\texttt{stor\_charge\_use}[n, t]$: Usage of the charging rate of a Storage node $n$ at operational period $t$ with a typical unit of GW or t/h,
  • $\texttt{stor\_charge\_inst}[n, t]$: Maximum available charging rate of a Storage node $n$ at operational period $t$, that is the upper bound for the variable $\texttt{stor\_charge\_use}[n, t]$, with a typical unit of GW or t/h.
  • $\texttt{stor\_discharge\_use}[n, t]$: Usage of the discharging rate of a Storage node $n$ at operational period $t$ with a typical unit of GW or t/h, and
  • $\texttt{stor\_discharge\_inst}[n, t]$: Maximum available discharging rate of a Storage node $n$ at operational period $t$, that is the upper bound for the variable $\texttt{stor\_discharge\_use}[n, t]$, with a typical unit of GW or t/h.
Note

It is not necessary that a Storage node has a charge and discharge capacity. It is possible to not specify a capacity for charge and discharge. In this instance, the variables for the intalled capacities are omitted and the charge and discharge usage is unlimited.

The storage level is always defined for the end of the operational period it is indexed over. There are in addition two variables for the storage level that behave slightly different:

  • $\texttt{stor\_level\_Δ\_op}[n, t]$: Change of the absolute level of energy/mass stored in a Storage node $n$ in operational period $t$ with a typical unit of GWh or t, and
  • $\texttt{stor\_level\_Δ\_rp}[n, t_{rp}]$: Change of the absolute level of energy/mass stored in a Storage node $n$ in representative period $t_{rp}$ with a typical unit of GWh or t, and
  • $\texttt{stor\_level\_Δ\_sp}[n, t_\texttt{inv}]$: Change of the absolute level of energy/mass stored in a Storage node $n$ in strategic period $t_\texttt{inv}$ with a typical unit of GWh or t.

These variables are introduced to track the change in the storage level in an operational period, a representative period, or an investment period, respectively. They can be considered as helper variables to account for the duration of the operational period as well as the total change within a representative period. $\texttt{stor\_level\_Δ\_rp}$ is only declared if the TimeStructure includes RepresentativePeriods while $\texttt{stor\_level\_Δ\_sp}$ is introduced as an empty SparseVariables container. The application of RepresentativePeriods is explained in How to use TimeStruct.jl. The utilization of $\texttt{stor\_level\_Δ\_sp}$ requires to include in the function variables_node for the given Storage array 𝒩ˢᵘᵇ::Vector{<:NewStorageNode} as, e.g., the following loop

for t_inv ∈ 𝒯ᴵⁿᵛ, n ∈ 𝒩ˢᵘᵇ
    insertvar!(m[:stor_level_Δ_sp], n, t_inv)
end

We also introduce the potential for links with capacities. By default, links do not introduce new variables. The capacity variable is only created for a link $l$ if the function has_capacity(n::Link) returns true. The following link variable ise then declared representing the capacity of links:

  • $\texttt{link\_cap\_inst}[l, t]$: Installed capacity of link $l$ at operational period $t$.
Links with a capacity

All links introduced in EnergyModelsBase do not allow for a capacity limiting the transfer. If you plan to introduce a link with a capacity, you have to create a new method for the function has_capacity for your introduced link.

Inclusions of investments

The variables $\texttt{cap\_inst}$, $\texttt{stor\_charge\_inst}$, $\texttt{stor\_level\_inst}$, $\texttt{stor\_discharge\_inst}$, and $\texttt{link\_cap\_inst}$ are used in EnergyModelsInvestment to allow for investments in capacity of individual nodes.

Flow variables

Flow variables correspond to the input to and output from both technology nodes and links. They are always positive to avoid backflow.

The following flow variables are defined for the nodes:

  • $\texttt{flow\_in}[n, t, p]$ represents the flow rate of resource $p$ into node $n$ at operational period $t$. It is created for subtypes of the types NetworkNode and Sink based on the field input in the composite type.
  • $\texttt{flow\_out}[n, t, p]$ represents the flow rate of resource $p$ out of node $n$ at operational period $t$. It is created for subtypes of the types Source and NetworkNode based on the field output in the composite type.

Links also have corresponding flow variables given by:

  • $\texttt{link\_in}[n, t, p]$ represents the flow rate of resource $p$ into link $l$ at operational period $t$, and
  • $\texttt{link\_out}[n, t, p]$ represents the flow rate of resource $p$ out of link $l$ at operational period $t$.

The resource index $p$ is created based on the intersection of the output of the input node $n_{in}$ and the input of the output node $n_{out}$ through the function EMB.link_res(l::Link). Mathematically, this is given as

$\mathcal{P}^{link} = \mathcal{P}^{n^{out}_{in}} \cap \mathcal{P}^{n^{in}_{out}}.$

It is also possible to create a new method for this function to limit the resources a link can transport.

Emission variables

Emission variables are used for accounting for emissions of the individual technologies. Resources that can be emitted are defined through the type ResourceEmit. Nodes do not necessarily have associated emission variables. Emission variables are only created for a node $n$ if the function has_emissions(n::EMB.Node) returns true. This is the case for all nodes that have EmissionsData within their field data as well as for a RefStorage node if a ResourceEmit is stored. The following node variable is then declared for all emission resource 𝒫ᵉᵐ:

  • $\texttt{emissions\_node}[n, t, p_\texttt{em}]$: Emissions of node $n$ at operational period $t$ of emission resource $p_\texttt{em}$.

Similarly, it is not necessary that links have associated emission variables. Emission variables are only created for a link $l$ if the function has_emissions(n::Link) returns true. The following link variable is then declared for all emission resource 𝒫ᵉᵐ:

  • $\texttt{emissions\_link}[n, t, p_\texttt{em}]$: Emissions of link $l$ at operational period $t$ of emission resource $p_\texttt{em}$.
Links with emissions

All links introduced in EnergyModelsBase do not allow for emissions. If you plan to introduce a link with emissions, you have to create a new method for the function has_emissions for your introduced link.

We have not implemented a similar approach as for nodes. It is however planned to allow for transmission emissions in the near future, similar to the concept employed for process emissions for nodes.

In addition, EnergyModelsBase declares the following variables for the global emissions:

  • $\texttt{emissions\_total}[t, p_\texttt{em}]$: Total emissions of ResourceEmit $p_\texttt{em}$ in operational period $t$, and
  • $\texttt{emissions\_strategic}[t_\texttt{inv}, p_\texttt{em}]$: Total emissions of ResourceEmit $p_\texttt{em}$ in strategic period $t_\texttt{inv}$.

These emission variables introduce limits on the total emissions of a resource through the field emission_limit of an EnergyModel in the function EMB.variables_emission.

Sink variables

Sink nodes are somehow different to the other nodes as they have additional variables associated with them. A key point here is to keep the overall mass balance intact while allowing for both overfulfilling and not meeting the demand. These variables are:

  • $\texttt{sink\_surplus}[n, t]$: Surplus of energy/mass to Sink $n$ at operational period $t$, and
  • $\texttt{sink\_deficit}[n, t]$: Deficit of energy/mass to Sink $n$ at operational period $t$.

The surplus in a sink corresponds to the energy/mass that is supplied to the sink in addition to the demand. The deficit in a sink corresponds to the energy/mass that is not supplied to the sink although the demand is specified. Both variables correspond to slack variables of the optimization problem. They simplify the problem and can make certain types of formulations feasible. It is possible to provide penalties for both surplus and deficits. This is implemented through the field penalty in the RefSource node.

Node types and respective variables

As outlined in the introduction, EnergyModelsBase declares different variables for each Node. These variables are for the individual nodes given in the subsections below.

Source

NetworkNode, except for Storage

Storage

Sink