A package to run the optimisation-based representative period models described in this working paper.
Fill in once testing has been setup.
using Pkg
pkg"registry add https://github.com/Spine-tools/SpineJuliaRegistry"
pkg"add SpinePeriods"
Assuming you have a working SpineOpt database:
-
Load the SpineOpt periods template from
src/representative_periods_template.json
into your SpineOpt database. -
Setup your
model
object; specifymodel_start
andmodel_end
as well asroll_forward
- which determines the candidate periods for the model. In short, whatever SpineOpt would see as optimization windows, SpinePeriods sees as candidate periods. -
Create a
representative_period
object (only onerepresentative_period
object is needed; if you create two or more, only one of them will be used and you wouldn't know which one.) -
Specify the value of the
representative_period_method
parameter for yourrepresentative_period
object, which determines the method for the representative periods model. Two values are possible:representative_periods
simply selects representative periods.representative_periods_ordering
also orders representative periods throughout the optimisation horizon so that long term storage arbitrage can be modeled (see this section of the SpineOpt documentation).
The two methods are described in this working paper where they are referred to as ORDF and ORDO respectively.
-
Specify the value of the
representative_periods
andrepresentative_blocks
parameters for yourrepresentative_period
object:representative_periods
is the number of representative periods to be selected (and ordered).representative_blocks
is the discretisation level of the duration curves used for therepresentative_periods_ordering
method, i.e. not relevant for therepresentative_periods
method. Higher leads to more accuracy; lower reduces problem size and speeds up computation.
-
Specify the value of the
for_rolling
Boolean parameter for yourrepresentative_period
object, which determines whether or not the output of SpinePeriods should be a SpineOpt DB ready to run a rolling horizon optimization on the selected representative periods (as if they were successive). -
Create
unit__representative_period
,node__representative_period
andunit__node__representative_period
relationships between yourrepresentative_period
object, and theunit
s andnode
s that you want to include in the representative periods model. The relationships you create determine the parameter values used to select (and order) representative periods according to the table below.relationship parameter unit__representative_period
unit_availability_factor
for theunit
node__representative_period
demand
for thenode
unit__node__representative_period
unit_capacity
for both theunit__from_node
andunit__to_node
-
Optionally specify
representative_period_weight
for the above relationships. This determines the weight SpinePeriods will assign to the corresponding parameter value in the optimisation model. It defaults to 1. -
You're ready to go! From Julia:
using SpinePeriods db_url_in = "sqlite:///<path_to_your_input_database>" db_url_out = "sqlite:///<path_to_your_output_database>" json_out = "<path_to_your_output_file>.json" run_spine_periods( db_url_in, db_url_out, # replace this with `json_out` to write results to a JSON file with_optimizer=optimizer_with_attributes( HiGHS.Optimizer, "output_flag" => true, "mip_rel_gap" => 0.01, "time_limit" => 600.0 ) )
-
Let SpinePeriods cook. The output database will be a copy of the input with a few additions/modifications depending on the value of the
for_rolling
parameter:-
If
for rolling
isfalse
:- One
temporal_block
object for each selected representative period will be created. Thesetemporal_block
s will also be associated to eachunit
andnode
included in your representative periods model (according to step 6 above) viaunits_on__temporal_block
andnode__temporal_block
, respectively. - The value of
roll_forward
will be set tonull
. - For each
temporal_block
originally associated to anyunit
s andnode
s included your representative periods model (as per step 6 above), if the value ofblock_end
is a duration then it will be adjusted to reflect the fact that the model won't be rolling anymore. - Finally, if you selected the
representative_periods_ordering
method, then for eachtemporal_block
originally associated to anyunit
s andnode
s included in your representative periods model (as per step 6 above), the value of therepresentative_periods_mapping
parameter will be set to amap
that SpineOpt will like.
- One
-
If
for rolling
istrue
:- The value of
model_start
for your model object will be set to the start of the first representative period selected. - The value of
roll_forward
will be set to an array of duration values, thus allowing SpineOpt to roll over the selected representative periods. - Finally, if you selected the
representative_periods_ordering
method, then the value of therepresentative_windows_mapping
parameter for yourmodel
object will be set to amap
from window start to representative window start.
- The value of
In either case, the database will be ready to be used by SpineOpt.
-
- Selecting and ordering periods of lengths smaller than days (e.g. hours) could make Julia crash. This should not be the case when only selecting periods.
- Similarly, selecting (and ordering) from several years could lead to Julia crashing if the optimisation problem becomes too large.
See CONTRIBUTING.md
SpinePeriods is licensed under GNU Lesser General Public License version 3.0 or later.