Inter-cluster storage math¶
Pre-defined extra math to apply inter-cluster storage math on top of the base mathematical formulation.
This math is only applied if referenced in the config.init.extra_math list as "storage_inter_cluster".
A guide to math documentation¶
If a math component's initial conditions are met (the first if statement), it will be applied to a model.
For each objective, constraint and global expression, a number of sub-conditions then apply (the subsequent, indented if statements) to decide on the specific expression to apply at a given iteration of the component dimensions.
In the expressions, terms in bold font are decision variables and terms in italic font are parameters.
The decision variables and parameters are listed at the end of the page; they also refer back to the global expressions / constraints in which they are used.
Those parameters which are defined over time (timesteps) in the expressions can be defined by a user as a single, time invariant value, or as a timeseries that is loaded from file or dataframe.
Note
For every math component in the documentation, we include the YAML snippet that was used to generate the math in a separate tab.
Download the inter-cluster storage math formulation as a YAML file
Subject to¶
balance_storage¶
UPDATED
Fix the quantity of carrier stored in a storage technology at the end of each timestep based on the net flow of carrier charged and discharged and the quantity of carrier stored at the start of the timestep.
Uses
description: "UPDATED\nFix the quantity of carrier stored in a `storage` technology
at the end of each timestep based on the net flow of carrier charged and discharged
and the quantity of carrier stored at the start of the timestep."
equations:
- expression: "storage == $storage_previous_step -\n sum(flow_out_inc_eff, over=carriers)
+ sum(flow_in_inc_eff, over=carriers)"
sub_expressions:
storage_previous_step:
- where: timesteps==get_val_at_index(timesteps=0) AND NOT cyclic_storage==True
expression: storage_initial * storage_cap
- where: "(\n (timesteps==get_val_at_index(timesteps=0) AND cyclic_storage==True)\n\
\ OR NOT timesteps==get_val_at_index(timesteps=0)\n) AND NOT lookup_cluster_last_timestep"
expression: (1 - storage_loss) ** roll(timestep_resolution, timesteps=1) *
roll(storage, timesteps=1)
- where: lookup_cluster_last_timestep AND NOT
(timesteps==get_val_at_index(timesteps=0) AND NOT cyclic_storage==True)
expression: '0'
foreach:
- nodes
- techs
- timesteps
where: (include_storage==true or base_tech==storage) AND NOT (base_tech==supply
OR base_tech==demand)
balance_storage_inter¶
NEW
Fix the relationship between one day and the next of a storage technology's available stored carrier, according to the previous day's representative storage fluctuations and the excess stored carrier available from all days up to this day.
Uses
description: "NEW\nFix the relationship between one day and the next of a `storage`
technology's available stored carrier, according to the previous day's representative
storage fluctuations and the excess stored carrier available from all days up to
this day."
equations:
- expression: storage_inter_cluster == $storage_previous_step + $storage_intra
sub_expressions:
storage_previous_step:
- where: datesteps==get_val_at_index(datesteps=0) AND NOT cyclic_storage==True
expression: storage_initial
- where: (datesteps==get_val_at_index(datesteps=0) AND cyclic_storage==True)
OR NOT datesteps==get_val_at_index(datesteps=0)
expression: ((1 - storage_loss) ** 24) * roll(storage_inter_cluster,
datesteps=1)
storage_intra:
- where: datesteps==get_val_at_index(datesteps=0) AND NOT cyclic_storage==True
expression: '0'
- where: NOT (datesteps==get_val_at_index(datesteps=0) AND NOT
cyclic_storage==True)
expression: storage[timesteps=$final_step]
slices:
final_step:
- expression: roll(lookup_datestep_last_cluster_timestep, datesteps=1)
foreach:
- nodes
- techs
- datesteps
where: include_storage==True OR base_tech==storage
balance_supply_with_storage¶
UPDATED
Fix the outflow of a supply technology to its consumption of the available source, with a storage buffer to temporally offset the outflow from source consumption.
Uses
description: "UPDATED\nFix the outflow of a `supply` technology to its consumption
of the available source, with a storage buffer to temporally offset the outflow
from source consumption."
equations:
- expression: storage == $storage_previous_step + source_use * source_eff -
flow_out_inc_eff
sub_expressions:
storage_previous_step:
- where: timesteps==get_val_at_index(timesteps=0) AND NOT cyclic_storage==True
expression: storage_initial * storage_cap
- where: "(\n (timesteps==get_val_at_index(timesteps=0) AND cyclic_storage==True)\n\
\ OR NOT timesteps==get_val_at_index(timesteps=0)\n) AND NOT lookup_cluster_last_timestep"
expression: (1 - storage_loss) ** roll(timestep_resolution, timesteps=1) *
roll(storage, timesteps=1)
- where: lookup_cluster_last_timestep AND NOT
(timesteps==get_val_at_index(timesteps=0) AND NOT cyclic_storage==True)
expression: '0'
foreach:
- nodes
- techs
- carriers
- timesteps
where: storage AND base_tech==supply
set_storage_initial¶
UPDATED
Fix the relationship between carrier stored in a storage technology at the start and end of the whole model period.
description: "UPDATED\nFix the relationship between carrier stored in a `storage`
technology at the start and end of the whole model period."
equations:
- expression: storage_inter_cluster[datesteps=$final_step] * ((1 - storage_loss)
** 24) == storage_initial * storage_cap
slices:
final_step:
- expression: get_val_at_index(datesteps=-1)
foreach:
- nodes
- techs
where: storage AND storage_initial AND cyclic_storage==True
storage_inter_max¶
NEW
Set the upper bound of a storage technology's stored carrier across all days in the timeseries.
Uses
description: "NEW\nSet the upper bound of a `storage` technology's stored carrier
across all days in the timeseries."
equations:
- expression: storage_inter_cluster +
storage_intra_cluster_max[clusters=$cluster] <= storage_cap
slices:
cluster:
- expression: lookup_datestep_cluster
foreach:
- nodes
- techs
- datesteps
where: include_storage==True OR base_tech==storage
storage_inter_min¶
NEW
Set the lower bound of a storage technology's stored carrier across all days in the timeseries.
Uses
description: "NEW\nSet the lower bound of a `storage` technology's stored carrier
across all days in the timeseries."
equations:
- expression: storage_inter_cluster * ((1 - storage_loss) ** 24) +
storage_intra_cluster_min[clusters=$cluster] >= 0
slices:
cluster:
- expression: lookup_datestep_cluster
foreach:
- nodes
- techs
- datesteps
where: include_storage==True OR base_tech==storage
storage_intra_max¶
NEW
Set the upper bound of a storage technology's stored carrier within a clustered day
description: "NEW\nSet the upper bound of a `storage` technology's stored carrier
within a clustered day"
equations:
- expression: storage <= storage_intra_cluster_max[clusters=$cluster]
slices:
cluster:
- expression: timestep_cluster
foreach:
- nodes
- techs
- timesteps
where: include_storage==True OR base_tech==storage
storage_intra_min¶
NEW
Set the lower bound of a storage technology's stored carrier within a clustered day
description: "NEW\nSet the lower bound of a `storage` technology's stored carrier
within a clustered day"
equations:
- expression: storage >= storage_intra_cluster_min[clusters=$cluster]
slices:
cluster:
- expression: timestep_cluster
foreach:
- nodes
- techs
- timesteps
where: include_storage==True OR base_tech==storage
Decision Variables¶
storage¶
UPDATED
The virtual carrier stored by any technology using storage in each timestep of a clustered day. Stored carrier can be negative so long as it does not go below the carrier stored in storage_inter_cluster. Only together with storage_inter_cluster does this variable's values gain physical significance.
Used in
Uses
Unit: energy
Default: 0
title: Virtual stored carrier
description: "UPDATED\nThe virtual carrier stored by any technology using storage
in each timestep of a clustered day. Stored carrier can be negative so long as it
does not go below the carrier stored in `storage_inter_cluster`. Only together with
`storage_inter_cluster` does this variable's values gain physical significance."
foreach:
- nodes
- techs
- timesteps
where: include_storage==True OR base_tech==storage
unit: energy
default: 0
storage_inter_cluster¶
NEW
The virtual carrier stored by any technology using storage between days of the entire timeseries. Only together with storage does this variable's values gain physical significance.
Uses
Unit: energy
Default: 0
title: Virtual inter-cluster stored carrier
description: "NEW\nThe virtual carrier stored by any technology using storage between
days of the entire timeseries. Only together with `storage` does this variable's
values gain physical significance."
foreach:
- nodes
- techs
- datesteps
where: include_storage==True OR base_tech==storage
unit: energy
default: 0
bounds:
min: 0
storage_intra_cluster_max¶
NEW
Virtual variable to limit the maximum value of storage in a given representative day.
Used in
Uses
Unit: energy
Default: inf
storage_intra_cluster_min¶
NEW
Virtual variable to limit the minimum value of storage in a given representative day.
Used in
Uses
Unit: energy
Default: -inf
Parameters¶
source_eff¶
Conversion efficiency from the technology from source. Set as value between 1 (no loss) and 0 (all lost).
Used in
Unit: unitless.
Default: 1.0
storage_initial¶
Set stored flow in device at the first timestep, as a fraction of total storage capacity.
Unit: unitless.
Default: 0
storage_loss¶
Rate of storage loss per hour, used to calculate lost stored flow as (1 - storage_loss)^hours_per_timestep.
Used in
Unit: \(\frac{\text{1}}{\text{hour}}\)
Default: 0
timestep_resolution¶
Unit: hours.
Default: 1
Lookup Arrays¶
base_tech¶
Should be the name of one of the abstract base classes, from which some initial parameter defaults will be derived and with which certain base math will be triggered.
Used in
Default: nan
Type: string
cyclic_storage¶
If true, link storage levels in the last model timestep with the first model timestep. inter_cluster_storage custom math must be included if using time clustering and setting this to true.
Default: True
Type: bool
include_storage¶
When true, math will be triggered to allow discontinuous carrier inflow and outflows across timesteps.
Used in
Default: False
Type: bool
lookup_cluster_last_timestep¶
The last timestep of each cluster.
Default: nan
Type: datetime
lookup_datestep_cluster¶
The cluster to which each datestep belongs.
Used in
Default: nan
Type: float
lookup_datestep_last_cluster_timestep¶
The last timestep of each datestep cluster.
Used in
Default: nan
Type: datetime
timestep_cluster¶
The cluster to which each timestep belongs.
Used in
Default: nan
Type: float