CapacityCostLink

CapacityCostLink links model the transport of energy between two nodes with capacity-dependent operational costs applied to a specified resource. Unlike standard Direct links, they enable cost modeling based on maximum capacity utilization over defined time periods. This is useful for applications such as transmission networks, pipelines, or interconnectors where usage fees scale with peak capacity demands.

In addition, they only allow the transport of a single, specified Resource.

CapacityCostLink is implemented as equivalent to an abstract type Link. Hence, it utilizes the same functions declared in EnergyModelsBase.

CapacityCostLink has the following standard fields, equivalent to a Direct link:

  • id :
    The field id is only used for providing a name to the link.
  • from::Node :
    The node from which there is flow into the link.
  • to::Node :
    The node to which there is flow out of the link.
  • formulation::Formulation :
    The used formulation of links. If not specified, a Linear link is assumed.
    Different formulations

    The current implementation of links does not provide another formulation. Our aim is in a later stage to allow the user to switch fast through different formulations to increase or decrese the complexity of the model.

The following additional fields are included for CapacityCostLink links:

  • cap::TimeProfile :
    The maximum transport capacity of the link for the cap_resource. If the link should contain investments through the application of EnergyModelsInvestments, it is important to note that you can only use FixedProfile or StrategicProfile for the capacity, but not RepresentativeProfile or OperationalProfile. In addition, all values have to be non-negative.

  • cap_price::TimeProfile :
    The price per unit of maximum capacity usage over the sub-periods. This value is averaged over sub-periods as defined by cap_price_periods. All values have to be non-negative.

    Price values

    The value given in cap_price is interpreted on the strategic-period scale (e.g., if a strategic-period duration of 1 corresponds to 1 year, then the natural unit is €/GW/year). Capacity costs are calculated per sub-period and then summed over the strategic period. This means a constant value (e.g., €/GW/year) is effectively applied once for each sub-period (based on the peak within that sub-period), and is not automatically scaled by sub-period duration.

    Example: With cap_price = 100 €/GW/year, cap_price_periods = 12, and a peak usage of 1 GW in each month, the model computes a total cost of 12 × 100 = 1200 €/year.

    To achieve seasonal/monthly peak charges, define multiple cap_price_periods and provide cap_price values that represent the intended charge per sub-period (or scale the values accordingly).

    It is planned to change this behavior in the future. The change corresponds to a breaking change as we change the behavior of the model.

  • cap_price_periods::Union{Int64, Vector{<:Number}} :
    The number of sub-periods within a year for which the capacity cost is calculated (if specifying an Int64) or the duration of the individual sub periods (if specifying a Vector{<:Number}). This allows modeling of varying peak demands across seasons. The value must be positive if your are using an Int64 (and hence specifiy the number of periods) or all values of be positive and summing up to the specified scaling factor between operational and strategic period durations (the parameter op_per_strat) if you are using a Vector{<:Number}.

    Number of sub-periods

    For investment periods with many operational periods, consider increasing the number of cap_price_periods. The CapacityCostLink capacity constraints couple operational periods and can significantly increase solve time. Splitting the horizon into multiple sub-periods reduces this coupling and often makes the problem much easier to solve. In some cases, this also means using more than one capacity price period even if capacity costs occur only annually in reality, depending on model size and complexity.

  • cap_resource::Resource :
    The Resource for which capacity-dependent costs are applied. This Resource is the only transported Resource by a CapacityCostLink.

  • data::Vector{<:ExtensionData}:
    An entry for providing additional data to the model. In the current version, it is used for providing additional investment data when EnergyModelsInvestments is used.

In the following mathematical equations, we use the name for variables and functions used in the model. Variables are in general represented as

$\texttt{var\_example}[index_1, index_2]$

with square brackets, while functions are represented as

$func\_example(index_1, index_2)$

with paranthesis.

CapacityCostLink utilizes standard variables from the Link type, as described on the page Optimization variables:

Two additional variables track capacity utilization and associated costs over sub-periods:

  • $\texttt{ccl\_cap\_use\_max}[l, t_{sub}]$: Maximum capacity usage in sub-period $t_{sub}$ for link $l$.
  • $\texttt{ccl\_cap\_use\_cost}[l, t_{sub}]$: Operational cost in sub-period $t_{sub}$ for link $l$.

The applied standard constraint for capacity installed is:

\[\texttt{link\_cap\_inst}[l, t] = capacity(l, t)\]

and the no-loss constraint

\[\texttt{link\_out}[l, t, p] = \texttt{link\_in}[l, t, p] \quad \forall p \in inputs(l)\]

All additional constraints are created within a new method for the function create_link.

The capacity utilization constraint tracks the maximum usage within each sub-period:

\[\texttt{link\_in}[l, t, cap\_resource(l)] \leq \texttt{ccl\_cap\_use\_max}[l, t_{sub}]\]

The capacity cost is calculated as:

\[\texttt{ccl\_cap\_use\_cost}[l, t_{sub}] = \texttt{ccl\_cap\_use\_max}[l, t_{sub}] \times \overline{cap\_price}(l, t_{sub})\]

where $\overline{cap\_price}$ is the average capacity price over the sub-period calculated as:

\[\overline{cap\_price}(l, t_{sub}) = \frac{\sum_{t \in t_{sub}} cap\_price(l, t) \times duration(t)}{\sum_{t \in t_{sub}} duration(t)}\]

Finally, costs are aggregated to each strategic period:

\[\texttt{link\_opex\_var}[l, t_{inv}] = \sum_{t_{sub} \in t_{inv}} \texttt{ccl\_cap\_use\_cost}[l, t_{sub}]\]

In addition, the energy flow of the constrained resource should not exceed the maximum capacity, which is included through the following constraint:

\[\texttt{flow\_in}[l, t, cap\_resource(l)] \leq \texttt{link\_cap\_inst}[l, t]\]