Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend user-defined relations to include the index of time #680

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions RELEASE_NOTES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,41 @@ Migration notes
# Re-use the existing data in `scen`, adding the `mode` dimension
expand_dims(scen, "storage_initial", mode="an existing mode")

- The index sets of user-defined relations are extended to include sub-annual time slices, i.e., index of `time`.
This includes sets (``is_relation_upper`` and ``is_relation_lower``) and parameters (``relation_activity``, ``relation_upper``, ``relation_lower``, and ``relation_cost``).
If these items are already populated with data in a Scenario, this data will be incompatible with the MESSAGE GAMS implementation in this release; a :class:`UserWarning` will be emitted when the :class:`.Scenario` is instantiated, and :meth:`~.message_ix.Scenario.solve` will raise a :class:`ValueError`.
(If these items are empty, their dimensions will be updated automatically, and new Scenarios are unaffected.)

Data for these items must be updated as follows:

========================== ============================================
Existing parameter or set Dimension to add
========================== ============================================
``relation_activity`` ``time``
``relation_upper`` ``time``
``relation_lower`` ``time``
``relation_cost`` ``time``
``is_relation_lower`` ``time``
``is_relation_upper`` ``time``
========================== ============================================

For extending the dimensionality of these items, :func:`.expand_dims` can help:

.. code-block:: python

from message_ix import Scenario
from message_ix.util import expand_dims

scen, platform = Scenario.from_url("…")

# Re-use the existing data in `scen`, adding the `time` dimension of "year"
expand_dims(scen, "relation_activity", time="year")

All changes
-----------

- Add a tutorial for Westeros multi-node and different trade possibilities (:pull:`683`).
- Extend user-defined relations to include the index of time (:pull:`680`).
- Add additional oscillation detection mechanism for macro iterations (:pull:`645`, :pull:`676`)
- Adjust default `lpmethod` from "Dual Simplex" (2) to "Barrier" (4); do NOT remove `cplex.opt` file(s) after solving workflow completes (:pull:`657`).
- Adjust :meth:`.Scenario.add_macro` calculations for pandas 1.5.0 (:pull:`656`).
Expand Down
28 changes: 28 additions & 0 deletions message_ix/model/MESSAGE/data_load.gms
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ is_fixed_extraction, is_fixed_stock, is_fixed_new_capacity, is_fixed_capacity, i
fixed_extraction, fixed_stock, fixed_new_capacity, fixed_capacity, fixed_activity, fixed_land
* storage parameters
storage_initial, storage_self_discharge, time_order
* time-related relation parameters and mappings
is_relation_upper_time, is_relation_lower_time, relation_activity_time, relation_upper_time, relation_lower_time, relation_cost_time
;


Expand Down Expand Up @@ -115,6 +117,16 @@ duration_time_rel(time,time2)$( map_time(time,time2) ) = duration_time(time2) /
* making duration_time_rel equal to 1, i.e., a consistent unit for ACT in sub-annual time slices, for parent 'time' not specified in set 'time_relative'
duration_time_rel(time,time2)$( Not time_relative(time) ) = 1 ;

* add the mapping of new time slice-related parameters to existing mappings
* Note: such mapping sets are typically generated at the Java backend, and this one should be added to the existing ones or to a new solution implemented in python.
map_tec_relation(node,relation,tec,year_all,mode,time)$(sum( (node2,year_all2),
relation_activity_time(relation,node2,year_all,node,tec,year_all2,mode,time) ) ) = yes;

* update mapping sets based on new relations defined at the sub-annual time slice level
map_tec(node,tec,year_all)$(sum( (relation,mode,time), map_tec_relation(node,relation,tec,year_all,mode,time) ) ) = yes;
map_tec_mode(node,tec,year_all,mode)$(sum( (relation,time), map_tec_relation(node,relation,tec,year_all,mode,time) ) ) = yes;
map_tec_time(node,tec,year_all,time)$(sum( (relation,mode), map_tec_relation(node,relation,tec,year_all,mode,time) ) ) = yes;

* assign an additional mapping set for technologies to nodes, modes and subannual time slices (for shorter reference)
map_tec_act(node,tec,year_all,mode,time)$( map_tec_time(node,tec,year_all,time) AND
map_tec_mode(node,tec,year_all,mode) ) = yes ;
Expand Down Expand Up @@ -184,6 +196,22 @@ map_time_period(year_all,lvl_temporal,time,time2)$( time_order(lvl_temporal,time
* mapping of sequence of the last sub-annual time slice to the first to create a close the order of time slices
map_time_period(year_all,lvl_temporal,time,time2)$( time_order(lvl_temporal,time) AND
time_order(lvl_temporal,time) = SMAX(time3,time_order(lvl_temporal,time3) ) AND time_order(lvl_temporal,time2) = 1 ) = yes;
* mapping of relations that should be accounted at 'year' even with sub-annual time slices
map_relation_year(relation,node,year_all,time)$(
SUM( (node2,year_all2,tec,mode), relation_activity_time(relation,node,year_all,node2,tec,year_all2,mode,time)
) AND ( duration_time(time) = 1 ) ) = yes;

* including those with only activity at time slice, but relation at 'year' level
map_relation_year(relation,node,year_all,'year')$( is_relation_upper_time(relation,node,year_all,'year') OR
is_relation_lower_time(relation,node,year_all,'year') ) = yes;

* mapping set of relations at 'year' level
relation_year(relation)$( SUM( (node,year_all,time), map_relation_year(relation,node,year_all,time) ) ) = yes;

* mapping of relations that should be accounted at the subannual time slice level
map_relation_time(relation,node,year_all,time)$(
SUM( (node2,year_all2,tec,mode), relation_activity_time(relation,node,year_all,node2,tec,year_all2,mode,time)
) AND NOT relation_year(relation) ) = yes;
*----------------------------------------------------------------------------------------------------------------------*
* sanity checks on the data set *
*----------------------------------------------------------------------------------------------------------------------*
Expand Down
Loading
Loading