Concepts

Summary

TulipaEnergyModel.jl incorporates two fundamental concepts that serve as the foundation of the optimization model:

  • Energy Assets: representation of a physical asset that can produce, consume, store, balance, or convert energy. Some examples of what these assets can represent are:
    • Producer: e.g., wind turbine, solar panel
    • Consumer: e.g., electricity demand, heat demand
    • Storage: e.g., battery, pumped-hydro storage
    • Balancing Hub: e.g., an electricity network that serves as a connection among other energy assets
    • Conversion: e.g., power plants, electrolyzers
  • Flows: representation of the connections among assets, e.g., pipelines, transmission lines, or simply the energy production that goes from one asset to another.

In a nutshell, the model guarantees a balance of energy for the various types of assets while considering the flow limits. It considers a set of representative periods (e.g., days or weeks) for a given timeframe (e.g., a year) the user wants to analyze. Therefore, the model has two types of temporal (time) constraints to consider the different chronology characteristics of the assets:

  • Intra-temporal Constraints: These constraints limit the asset or flow within a representative period. The intra-temporal constraints help to characterize the short-term operational dynamics of the assets. So far, the model considers balance and flow limitations within the representative period, but future developments will include unit commitment, ramping, and reserve constraints.
  • Inter-temporal Constraints: These constraints combine the information of the representative periods and create limitations between them to recover chronological information across the full timeframe. The inter-temporal constraints help to characterize the long-term operational dynamics of the assets. So far, the model uses this type of constraint to model seasonal storage, but future developments will include, for example, maximum or minimum production/consumption for a year (or any timeframe).

The mathematical formulation shows an overview of these constraints and the variables in the model.

Another essential concept in the model is the flexible time resolution, which allows for each asset to be considered in a single timestep (e.g., 1, 2, 3...) or in a range of timesteps (e.g., 1:3, meaning that the asset's variable represents the value of timesteps 1, 2, and 3). This concept allows the modelling of different dynamics depending on the asset; for instance, electricity assets can be modeled hourly, whereas hydrogen assets can be modeled in a 6-hour resolution (avoiding creating unnecessary constraints and variables).

The following sections explain these concepts in more detail.

Flexible Connection of Energy Assets

In energy system modeling, it is becoming common to have hybrid assets like storage + renewable (e.g., battery + solar), electrolyzer + renewable (e.g., electrolyzer + wind), or renewable + hydro (e.g., solar + hydro) that are located at the same site and share a common connection point to the grid. The standard method of modeling these assets requires extra variables and constraints for them to function correctly. For example, flows from the grid are not allowed, as they either avoid charging from the grid or require green hydrogen production. Therefore, hybrid connections typically require an additional node to regulate this connection with the grid.

The representation of the energy system in TulipaEnergyModel.jl is based on Graph Theory, which deals with the connection between vertices by edges. This representation provides a more flexible framework to model energy assets in the system as vertices and flows between energy assets as edges. By connecting assets directly to each other (i.e., without having a node in between), we reduce the number of variables and constraints needed to represent hybrid configurations, thus reducing the model size.

Consider the following example to demonstrate the benefits of using a graph theory approach. In the classic connection approach, the nodes play a crucial role in modeling. For instance, every asset must be connected to a node with balance constraints. When a storage asset and a renewable asset are in a hybrid connection like the one described before, a connection point is needed to connect the hybrid configuration to the rest of the system. Therefore, to consider the hybrid configuration of a storage asset and a renewable asset, we must introduce a node (i.e., a connection point) between these assets and the external power grid (i.e., a balance point), as shown in the following figure:

Classic connection

In this system, the phs storage asset charges and discharges from the connection point, while the wind turbine produces power that goes directly to the connection point. This connection point is connected to the external power grid through a transmission line that leads to a balance hub that connects to other assets. Essentially, the connection point acts as a balancing hub point for the assets in this hybrid configuration. Furthermore, these hybrid configurations impose an extra constraint to avoid storage charges from the power grid.

Let's consider the modeling approach in TulipaEnergyModel.jl. As nodes are no longer needed to connect assets, we can connect them directly to each other, as shown in the figure below:

Flexible connection

By implementing this approach, we can reduce the number of variables and constraints involved. For example, the balance constraint in the intermediate node and the extra constraint to avoid the storage charging from the power grid are no longer needed. Additionally, we can eliminate the variable determining the flow between the intermediate node and the power grid, because the flow from phs to balance can directly link to the external grid. The section comparison of different modeling approaches shows the quantification of these reductions.

This example of a phs and a wind asset is useful for illustrating the advantages of this modeling approach and will be reused in the following sections. However, please keep in mind that there are other applications of hybrid configurations, such as battery-solar, hydro-solar, and electrolyzer-wind.

Flexible Time Resolution

One of the core features of TulipaEnergyModel.jl is that it can handle different time resolutions on the assets and the flows. Typically, the time resolution in an energy model is hourly, like in the following figure where we have a 6-hour energy system:

Hourly Time Resolution

Therefore, for this simple example, we can determine the number of constraints and variables in the optimization problem:

  • Number of variables: 42 since we have six connections among assets (i.e., 6 flows x 6 hours = 36 variables) and one storage asset (i.e., 1 storage level x 6 h = 6 variables)

  • Number of constraints: 72, which are:

    • 24 from the maximum output limit of the assets that produce, convert, or discharge energy (i.e., H2, wind, ccgt, and phs) for each hour (i.e., 4 assets x 6 h = 24 constraints)
    • 6 from the maximum input limit of the storage or charging limit for the phs
    • 6 from the maximum storage level limit for the phs
    • 12 from the import and export limits for the transmission line between the balance hub and the demand
    • 24 from the energy balance on the consumer, hub, conversion, and storage assets (i.e., demand, balance, ccgt, and phs) for each hour (i.e., 4 assets x 6 h = 24 constraints)

Depending on the input data and the level of detail you want to model, hourly resolution in all the variables might not be necessary. TulipaEnergyModel.jl can have different time resolutions for each asset and flow to simplify the optimization problem and approximate hourly representation. This feature is useful for large-scale energy systems that involve multiple sectors, as detailed granularity is not always necessary due to the unique temporal dynamics of each sector. For instance, we can use hourly resolution for the electricity sector and six-hour resolution for the hydrogen sector. We can couple multiple sectors, each with its own temporal resolution.

Let's explore the flexibility of time resolution with a few examples.

The following table shows the user input data for the definition of asset time resolution. Please note that the values presented in this example are just for illustrative purposes and do not represent a realistic case.

2×4 DataFrame
Rowassetrep_periodspecificationpartition
String7Int64String7Int64
1H21uniform6
2phs1uniform6

The table shows that the H2 producer and the phs storage have a uniform definition of 6 hours. This definition means we want to represent the H2 production profile and the storage level of the phs every six hours.

The same time resolution can be specified for the flows, for example (again, the values are for illustrative purposes and do not represent a realistic case):

5×5 DataFrame
Rowfrom_assetto_assetrep_periodspecificationpartition
String7String7Int64String7String7
1H2ccgt1uniform6
2windbalance1math1x2+1x4
3windphs1uniform3
4phsbalance1math1x4+1x2
5balancedemand1uniform3

The table shows a uniform definition for the flow from the hydrogen producer (H2) to the conversion asset (ccgt) of 6 hours, from the wind producer (wind) to the storage (phs) of 3 hours, and from the balance hub (balance) to the consumer (demand) of 3 hours, too. In addition, the flow from the wind producer (wind) to the balance hub (balance) is defined using the math specification of 1x2+1x4, meaning that there are two time blocks, one of two hours (i.e., 1:2) and another of four hours (i.e., 3:6). Finally, the flow from the storage (phs) to the balance hub (balance) is defined using the math specification of 1x4+1x2, meaning that there are two time blocks, one of four hours (i.e., 1:4) and another of two hours (i.e., 5:6).

The following figure illustrates these definitions on the example system.

Variable Time Resolution

So, let's recap:

  • The hydrogen producer (H2) is in a 6-hour resolution represented by the range 1:6, meaning that the balance of the hydrogen produced is for every 6 hours.
  • The flow from the hydrogen producer to the ccgt power plant (H2,ccgt) is also in a 6-hour resolution 1:6.
  • The flow from the ccgt power plant to the balance hub (ccgt, balance) has hourly resolution [1,2,3,4,5,6].
  • The ccgt is a conversion plant that takes hydrogen to produce electricity. Since both sectors have different time resolutions, the energy balance in the conversion asset is defined in the lowest resolution connecting to the asset. In this case, the energy balance in the ccgt is defined every 6 hours, i.e., in the range 1:6.
  • The wind producer has an hourly profile of electricity production, so the resolution of the asset is hourly.
  • The wind producer output has two connections, one to the balance hub and the other to the pumped-hydro storage (phs) with different resolutions:
    • The flow from the wind producer to the phs storage (wind, phs) has a uniform resolution of two blocks from hours 1 to 3 (i.e., 1:3) and from hours 4 to 6 (i.e., 4:6).
    • The flow from the wind producer to the balance hub (wind, balance) has a variable resolution of two blocks, too, but from hours 1 to 2 (i.e., 1:2) and from hours 3 to 6 (i.e., 3:6).
  • The phs is in a 6-hour resolution represented by the range 1:6, meaning the storage balance is determined every 6 hours.
  • The flow from the phs to the balance (phs, balance) represents the discharge of the phs. This flow has a variable resolution of two blocks from hours 1 to 4 (i.e., 1:4) and from hours 5 to 6 (i.e., 5:6), which differs from the one defined for the charging flow from the wind asset.
  • The demand consumption has hourly input data with one connection to the balance hub:
    • The flow from the balance hub to the demand (balance, demand) has a uniform resolution of 3 hours; therefore, it has two blocks, one from hours 1 to 3 (i.e., 1:3) and the other from hours 4 to 6 (i.e., 4:6).
  • The balance hub integrates all the different assets with their different resolutions. The lowest resolution of all connections determines the balance equation for this asset. Therefore, the resulting resolution is into two blocks, one from hours 1 to 4 (i.e., 1:4) and the other from hours 5 to 6 (i.e., 5:6).

Note: This example demonstrates that different time resolutions can be assigned to each asset and flow in the model. Additionally, the resolutions do not need to be uniform and can vary throughout the horizon.

The complete input data for this example can be found here.

Due to the flexible resolution, we must explicitly state how the constraints are constructed. For each constraint, three things need to be considered:

  • Whether it is type power or type energy.
    • type power: highest resolution
    • type energy: lowest resolution (multiplied by durations)
  • How the resolution is determined (regardless of whether it is highest or lowest): the incoming flows, the outgoing flows, or a combination of both.
  • How the related parameters are treated. We use two methods of aggregation, sum or mean.

Below is the table outlining the details for each type of constraint. Note min means highest resolution, and max means lowest resolution.

NameVariables involvedParameters involvedConstraint typeResolution of the constraintsParameter aggregation
Consumer Balanceinputs, outputsdemandpowermin(incoming flows, outgoing flows)mean
Storage Balanceinputs, outputs, storage levelinflowsenergymax(asset, min(incoming flows, outgoing flows))sum
Hub Balanceinputs, outputs-powermin(incoming flows, outgoing flows)-
Conversion Balanceinputs, outputs-energymax(incoming flows, outgoing flows)-
Producers Capacity Constraintsoutputsproductionpowermin(outgoing flows)mean
Storage Capacity Constraints (outgoing)outputs-powermin(outgoing flows)-
Conversion Capacity Constraints (outgoing)outputs-powermin(outgoing flows)-
Conversion Capacity Constraints (incoming)inputs-powermin(incoming flows)-
Storage Capacity Constraints (incoming)inputs-powermin(incoming flows)-
Transport Capacity Constraints (upper bounds)flowcapacitypowerif it connects two hubs or demands then max(hub a,hub b), otherwise its ownmean
Transport Capacity Constraints (lower bounds)flowcapacitypowerif it connects two hubs or demands then max(hub a,hub b), otherwise its ownmean

For this basic example, we can describe the balance and capacity constraints in the model. For the sake of simplicity, we consider only the intra-temporal constraints, the representative period index is dropped from the equations, and there are no investment variables in the equations.

Energy Balance Constraints

In the following sections, we lay out all the balance constraints of this example.

Storage Balance

As shown in the table, the resolution of the storage balance is energy, which is calculated by max(asset, min(incoming flows, outgoing flows)). The resolutions of the incoming and outgoing flows of the storage are 1:3, 4:6, 1:4, and 5:6, resulting in a minimum resolution of 2. The resolution of the storage is 6. Then, max(asset, min(incoming flows, outgoing flows)) becomes max(6, min(3, (4, 2))) which results in 6, and thus this balance is for every 6 hours. The charging and discharging flows are multiplied by their durations to account for the energy in the range 1:6.

\[\begin{aligned} & \text{storage\_balance}_{\text{phs},1:6}: \\ & \qquad v^{\text{intra-storage}}_{\text{phs},1:6} = 3 \cdot p^{\text{eff}}_{(\text{wind},\text{phs})} \cdot v^{\text{flow}}_{(\text{wind},\text{phs}),1:3} + 3 \cdot p^{\text{eff}}_{(\text{wind},\text{phs})} \cdot v^{\text{flow}}_{(\text{wind},\text{phs}),4:6} \\ & \qquad \quad - \frac{4}{p^{\text{eff}}_{(\text{phs},\text{balance})}} \cdot v^{\text{flow}}_{(\text{phs},\text{balance}),1:4} - \frac{2}{p^{\text{eff}}_{(\text{phs},\text{balance})}} \cdot v^{\text{flow}}_{(\text{phs},\text{balance}),5:6} \\ \end{aligned}\]

Consumer Balance

The flows coming from the balancing hub are defined every 3 hours. Therefore, the flows impose the lowest resolution and the demand is balanced every 3 hours. The input demand is aggregated as the mean of the hourly values in the input data. As with the storage balance, the flows are multiplied by their durations.

\[\begin{aligned} & \text{consumer\_balance}_{\text{demand},1:3}: \\ & \qquad v^{\text{flow}}_{(\text{balance},\text{demand}),1:3} = p^{\text{peak demand}}_{\text{demand}} \cdot \frac{\sum_{b=1}^{3} p^{\text{demand profile}}_{\text{demand},b}}{3} \\ & \text{consumer\_balance}_{\text{demand},4:6}: \\ & \qquad v^{\text{flow}}_{(\text{balance},\text{demand}),4:6} = p^{\text{peak demand}}_{\text{demand}} \cdot \frac{\sum_{b=4}^{6} p^{\text{demand profile}}_{\text{demand},b}}{3} \\ \end{aligned}\]

Hub Balance

The hub balance is quite interesting because it integrates several flow resolutions. Remember that we didn't define any specific time resolution for this asset. Therefore, the highest resolution of all incoming and outgoing flows in the horizon implies that the hub balance must be imposed for all 6 blocks. The balance must account for each flow variable's duration in each block.

\[\begin{aligned} & \text{hub\_balance}_{\text{balance},1:1}: \\ & \qquad v^{\text{flow}}_{(\text{balance},\text{demand}),1:3} = v^{\text{flow}}_{(\text{ccgt},\text{balance}), 1:1} + v^{\text{flow}}_{(\text{wind},\text{balance}),1:2} + v^{\text{flow}}_{(\text{phs},\text{balance}),1:4} \\ & \text{hub\_balance}_{\text{balance},2:2}: \\ & \qquad v^{\text{flow}}_{(\text{balance},\text{demand}),1:3} = v^{\text{flow}}_{(\text{ccgt},\text{balance}), 2:2} + v^{\text{flow}}_{(\text{wind},\text{balance}),1:2} + v^{\text{flow}}_{(\text{phs},\text{balance}),1:4} \\ & \text{hub\_balance}_{\text{balance},3:3}: \\ & \qquad v^{\text{flow}}_{(\text{balance},\text{demand}),1:3} = v^{\text{flow}}_{(\text{ccgt},\text{balance}), 3:3} + v^{\text{flow}}_{(\text{wind},\text{balance}),3:6} + v^{\text{flow}}_{(\text{phs},\text{balance}),1:4} \\ & \text{hub\_balance}_{\text{balance},4:4}: \\ & \qquad v^{\text{flow}}_{(\text{balance},\text{demand}),4:6} = v^{\text{flow}}_{(\text{ccgt},\text{balance}), 4:4} + v^{\text{flow}}_{(\text{wind},\text{balance}),3:6} + v^{\text{flow}}_{(\text{phs},\text{balance}),1:4}\\ & \text{hub\_balance}_{\text{balance},5:5}: \\ & \qquad v^{\text{flow}}_{(\text{balance},\text{demand}),4:6} = v^{\text{flow}}_{(\text{ccgt},\text{balance}), 5:5} + v^{\text{flow}}_{(\text{wind},\text{balance}),3:6} + v^{\text{flow}}_{(\text{phs},\text{balance}),5:6} \\ & \text{hub\_balance}_{\text{balance},6:6}: \\ & \qquad v^{\text{flow}}_{(\text{balance},\text{demand}),4:6} = v^{\text{flow}}_{(\text{ccgt},\text{balance}), 6:6} + v^{\text{flow}}_{(\text{wind},\text{balance}),3:6} + v^{\text{flow}}_{(\text{phs},\text{balance}),5:6} \\ \end{aligned}\]

Conversion Balance

The flows connected to the CCGT conversion unit have different resolutions, too. In this case, the hydrogen imposes the lowest resolution; therefore, the energy balance in this asset is also every 6 hours.

\[\begin{aligned} & \text{conversion\_balance}_{\text{ccgt},1:6}: \\ & \qquad 6 \cdot p^{\text{eff}}_{(\text{H2},\text{ccgt})} \cdot v^{\text{flow}}_{(\text{H2},\text{ccgt}),1:6} = \frac{1}{p^{\text{eff}}_{(\text{ccgt},\text{balance})}} \sum_{b=1}^{6} v^{\text{flow}}_{(\text{ccgt},\text{balance}),b} \\ \end{aligned}\]

Capacity Constraints

All capacity constraints are defined in the highest resolution to guarantee that the flows are below the limits of each asset capacity.

Storage Capacity Constraints

Since the storage unit only has one input and output, the capacity limit constraints are in the same resolution as the individual flows. Therefore, the constraints for the outputs of the storage (i.e., discharging capacity limit) are:

\[\begin{aligned} & \text{max\_output\_flows\_limit}_{\text{phs},1:4}: \\ & \qquad v^{\text{flow}}_{(\text{phs},\text{balance}),1:4} \leq p^{\text{init capacity}}_{\text{phs}} \\ & \text{max\_output\_flows\_limit}_{\text{phs},5:6}: \\ & \qquad v^{\text{flow}}_{(\text{phs},\text{balance}),5:6} \leq p^{\text{init capacity}}_{\text{phs}} \\ \end{aligned}\]

And the constraints for the inputs of the storage (i.e., charging capacity limit) are:

\[\begin{aligned} & \text{max\_input\_flows\_limit}_{\text{phs},1:3}: \\ & \qquad v^{\text{flow}}_{(\text{wind},\text{phs}),1:3} \leq p^{\text{init capacity}}_{\text{phs}} \\ & \text{max\_input\_flows\_limit}_{\text{phs},4:6}: \\ & \qquad v^{\text{flow}}_{(\text{wind},\text{phs}),4:6} \leq p^{\text{init capacity}}_{\text{phs}} \\ \end{aligned}\]

Conversion Capacity Constraints

Similarly, each outflow is limited to the ccgt capacity for the conversion unit.

\[\begin{aligned} & \text{max\_output\_flows\_limit}_{\text{ccgt},b}: \\ & \qquad v^{\text{flow}}_{(\text{ccgt},\text{balance}),b} \leq p^{\text{init capacity}}_{\text{ccgt}} \quad \forall b \in [1,6] \\ \end{aligned}\]

Producer Capacity Constraints

The wind producer asset is interesting because the output flows are in different resolutions, i.e., 1:2, 3:6, 1:3, and 4:6. The highest resolution is 1:2, 3, and 4:6. Therefore, the constraints are as follows:

\[\begin{aligned} & \text{max\_output\_flows\_limit}_{\text{wind},1:2}: \\ & \qquad v^{\text{flow}}_{(\text{wind},\text{balance}),1:2} + v^{\text{flow}}_{(\text{wind},\text{phs}),1:3} \leq \frac{p^{\text{init capacity}}_{\text{wind}}}{2} \cdot \sum_{b=1}^{2} p^{\text{availability profile}}_{\text{wind},b} \\ & \text{max\_output\_flows\_limit}_{\text{wind},3}: \\ & \qquad v^{\text{flow}}_{(\text{wind},\text{balance}),3:6} + v^{\text{flow}}_{(\text{wind},\text{phs}),1:3} \leq p^{\text{init capacity}}_{\text{wind}} \cdot p^{\text{availability profile}}_{\text{wind},3} \\ & \text{max\_output\_flows\_limit}_{\text{wind},4:6}: \\ & \qquad v^{\text{flow}}_{(\text{wind},\text{balance}),3:6} + v^{\text{flow}}_{(\text{wind},\text{phs}),4:6} \leq \frac{p^{\text{init capacity}}_{\text{wind}}}{2} \cdot \sum_{b=5}^{6} p^{\text{availability profile}}_{\text{wind},b} \\ \end{aligned}\]

Since the flow variables $v^{\text{flow}}_{(\text{wind}, \text{balance}),1:2}$ and $v^{\text{flow}}_{(\text{wind}, \text{balance}),1:3}$ represent power, the first constraint sets the upper bound of the power for both timestep 1 and 2, by assuming an average capacity across these two timesteps. The same applies to the other two constraints.

The hydrogen (H2) producer capacity limit is straightforward, since both the asset and the flow definitions are in the same time resolution:

\[\begin{aligned} & \text{max\_output\_flows\_limit}_{\text{H2},1:6}: \\ & \qquad v^{\text{flow}}_{(\text{H2},\text{ccgt}),1:6} \leq p^{\text{init capacity}}_{\text{H2}} \cdot p^{\text{availability profile}}_{\text{H2},1:6} \\ \end{aligned}\]

Transport Capacity Constraints

For the connection from the hub to the demand, there are associated transmission capacity constraints, which are in the same resolution as the flow:

\[\begin{aligned} & \text{max\_transport\_flows\_limit}_{(\text{balance},\text{demand}),1:3}: \\ & \qquad v^{\text{flow}}_{(\text{balance},\text{demand}),1:3} \leq p^{\text{init export capacity}}_{(\text{balance},\text{demand})} \\ & \text{max\_transport\_flows\_limit}_{(\text{balance},\text{demand}),4:6}: \\ & \qquad v^{\text{flow}}_{(\text{balance},\text{demand}),4:6} \leq p^{\text{init export capacity}}_{(\text{balance},\text{demand})} \\ \end{aligned}\]

\[\begin{aligned} & \text{min\_transport\_flows\_limit}_{(\text{balance},\text{demand}),1:3}: \\ & \qquad v^{\text{flow}}_{(\text{balance},\text{demand}),1:3} \geq - p^{\text{init import capacity}}_{(\text{balance},\text{demand})} \\ & \text{min\_transport\_flows\_limit}_{(\text{balance},\text{demand}),4:6}: \\ & \qquad v^{\text{flow}}_{(\text{balance},\text{demand}),4:6} \geq - p^{\text{init import capacity}}_{(\text{balance},\text{demand})} \\ \end{aligned}\]

Storage Level limits

Since the system has a storage asset, we must limit the maximum storage level. The phs time resolution is defined for every 6 hours, so we only have one constraint.

\[\begin{aligned} & \text{max\_storage\_level\_limit}_{\text{phs},1:6}: \\ & \qquad v^{\text{intra-storage}}_{\text{phs},1:6} \leq p^{\text{init storage capacity}}_{\text{phs}} \end{aligned}\]

Comparison of Different Modeling Approaches

This section quantifies the advantages of the flexible connection and flexible time resolution in the TulipaEnergyModel.jl modeling approach. So, let us consider three different approaches based on the same example:

  1. Classic approach with hourly resolution: This approach needs an extra asset, node, to create the hybrid operation of the phs and wind assets.
  2. Flexible connection with hourly resolution: This approach uses the flexible connection to represent the hybrid operation of the phs and wind assets.
  3. Flexible connection and flexible time: This approach uses both features, the flexible connection and the flexible time resolution.

Note: The flexibility of TulipaEnergyModel.jl allows any of these three modeling approaches.

The table below shows the constraints and variables for each approach over a 6-hour horizon. These results show the potential of flexible connections and time resolution for reducing the size of the optimization model.

Modeling approachNº VariablesNº ConstraintsObjective Function
Classic approach with hourly resolution488428.4365
Flexible connection with hourly resolution427228.4365
Flexible connection and time resolution162928.4587

By comparing the classic approach with the other methods, we can analyze their differences:

  • The flexible connection with hourly resolution reduces 6 variables ($12.5\%$) and 12 constraints ($\approx 14\%$). Notice that we include the 6 extra constraints related to not allowing charging from the grid, although these constraints can also be modeled as bounds. Finally, the objective function value is the same, since we use an hourly time resolution in both cases.
  • The combination of features reduces 32 variables ($\approx 67\%$) and 55 constraints ($\approx 65\%$) with an approximation error of $\approx 0.073\%$.

The level of reduction and approximation error will depend on the case study. Some cases that would benefit from this feature include:

  • Coupling different energy sectors with various dynamics. For instance, methane, hydrogen, and heat sectors can be represented in energy models with lower resolutions (e.g., 4, 6, or 12h) than the electricity sector, usually modeled in higher resolutions (e.g., 1h, 30 min).

  • Having high resolutions for all assets in a large-scale case study may not be necessary. For example, if analyzing a European case study focusing on a specific country like The Netherlands, hourly details for distant countries (such as Portugal and Spain) may not be required. However, one would still want to consider their effect on The Netherlands without causing too much computational burden. In such cases, flexible time resolution can maintain hourly details in the focus country, while reducing the detail in distant countries by increasing their resolution (to two hours or more). This reduction allows a broader scope without over-burdening computation.

Seasonal Storage Modeling

The inter-temporal constraints in the mathematical formulation for energy storage assets allow us to model seasonal storage. To better understand how this feature works in TulipaEnergyModel.jl, there is an example in the folder test/inputs/Storage.

Let's first look at this feature's most relevant input data, starting with the assets-data file. Here, we show only the storage assets and the appropriate columns for this example, but all the input data can be found in the previously mentioned folder.

2×6 DataFrame
Rownametypeinitial_capacityis_seasonalinitial_storage_capacityinitial_storage_level
String7String15Int64BoolInt64Int64
1batterystorage10false200
2phsstorage100true48002400

The is_seasonal parameter determines whether or not the storage asset uses the inter-temporal constraints. The phs is the only storage asset with this type of constraint and inter-storage level variable (i.e., $s^{\text{inter}}_{\text{phs},p}$), and has 100MW capacity and 4800MWh of storage capacity (i.e., 48h discharge duration). The battery will only consider intra-temporal constraints with intra-storage level variables (i.e., $s^{\text{intra}}_{\text{battery},k,b_k}$), and has 10MW capacity with 20MWh of storage capacity (i.e., 2h discharge duration).

The rep-periods-data file has information on the representative periods in the example. We have three representative periods, each with 24 timesteps and hourly resolution, representing a day. The figure below shows the availability profile of the renewable energy sources in the example.

3×3 DataFrame
Rowidnum_timestepsresolution
Int64Int64Float64
11241.0
22241.0
33241.0

availability-profiles

The rep-periods-mapping relates each representative period with the periods in the timeframe. We have seven periods in this case, meaning the timeframe is a week. Each value in the file indicates the weight of each representative period in the timeframe period. Notice that each period is composed of a linear combination of the representative periods. For more details on obtaining the representative periods and the weights, please look at TulipaClustering.jl. For the sake of readability, we show here the information in the file in tabular form:

7×4 DataFrame
Rowperiodk=1k=2k=3
Int64Float64Float64Float64
110.01.00.0
220.20.70.1
330.00.80.2
440.30.60.1
550.10.60.3
660.10.30.6
770.80.20.0

The file assets-timeframe-partitions has the information on how often we want to evaluate the inter-temporal constraints that combine the information of the representative periods. In this example, we define a uniform distribution of one period, meaning that we will check the inter-storage level every day of the week timeframe.

1×3 DataFrame
Rowassetspecificationpartition
String3String7Int64
1phsuniform1

Note: For the sake of simplicity, we show how using three representative days can recover part of the chronological information of one week. The same method can be applied to more representative periods to analyze the seasonality across a year or longer timeframe.

Now let's solve the example and explore the results:

using TulipaEnergyModel

# input_dir should be the path to the Storage example
energy_problem = run_scenario(input_dir)
EnergyProblem:
  - Time for reading the data (in seconds): 6.728687151
  - Model created!
    - Time for creating the model (in seconds): 3.677861093
    - Number of variables: 727
    - Number of constraints for variable bounds: 727
    - Number of structural constraints: 957
  - Model solved! 
    - Time for solving the model (in seconds): 1.289920525
    - Termination status: OPTIMAL
    - Objective value: 2359.439239411546

Since the battery is not seasonal, it only has results for the intra-storage level of each representative period, as shown in the following figure:

Battery-intra-storage-level

Since the phs is defined as seasonal, it has results for only the inter-storage level. Since we defined the period partition as 1, we get results for each period (i.e., day). We can see that the inter-temporal constraints in the model keep track of the storage level through the whole timeframe definition (i.e., week).

PHS-inter-storage-level

In this example, we have demonstrated how to partially recover the chronological information of a storage asset with a longer discharge duration (such as 48 hours) than the representative period length (24 hours). This feature enables us to model both short- and long-term storage in TulipaEnergyModel.jl.

You can follow the hydrothermal dispatch tutorial for a more comprehensive example of seasonal storage use in the model.