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

Fix outdated multi-period usage docs #981

Merged
merged 5 commits into from
Oct 13, 2023
Merged
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
25 changes: 13 additions & 12 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1004,8 +1004,8 @@ mathematical background, like variables and constraints, which are used.

.. _multi_period_mode_label:

Using the multi-period (investment) mode (experimental)
-------------------------------------------------------
Multi-period (investment) mode (experimental)
---------------------------------------------
Sometimes you might be interested in how energy systems could evolve in the longer-term, e.g. until 2045 or 2050 to meet some
carbon neutrality and climate protection or RES and energy efficiency targets.

Expand All @@ -1020,18 +1020,18 @@ only unfolds if you look at long-term investments. Let's see how.
First, you start by defining your energy system as you might have done before, but you

* choose a longer-term time horizon (spanning multiple years, i.e. multiple periods) and
* explicitly define the `periods` attribute of your energy system which maps time steps to the simulated period.
* explicitly define the `periods` attribute of your energy system which lists the time steps for each period.

.. code-block:: python

import pandas as pd
import oemof.solph as solph

my_index = pd.date_range('1/1/2013', periods=17520, freq='H')
periods = {
0: pd.date_range('1/1/2013', periods=8760, freq='H'),
1: pd.date_range('1/1/2014', periods=8760, freq='H'),
}
periods = [
pd.date_range('1/1/2013', periods=8760, freq='H'),
pd.date_range('1/1/2014', periods=8760, freq='H'),
]
my_energysystem = solph.EnergySystem(timeindex=my_index, periods=periods)

If you want to use a multi-period model you have define periods of your energy system explicitly. This way,
Expand All @@ -1057,17 +1057,16 @@ and adjust to your needs:

Returns
-------
periods : dict
pd.date_ranges defining the time stamps for the respective period,
starting with period 0
periods : list
periods for the optimization run
"""
years = sorted(list(set(getattr(datetimeindex, "year"))))
periods = {}
periods = []
filter_series = datetimeindex.to_series()
for number, year in enumerate(years):
start = filter_series.loc[filter_series.index.year == year].min()
end = filter_series.loc[filter_series.index.year == year].max()
periods[number] = pd.date_range(start, end, freq=datetimeindex.freq)
periods.append(pd.date_range(start, end, freq=datetimeindex.freq))

return periods

Expand Down Expand Up @@ -1269,6 +1268,8 @@ Besides the `invest` variable, new variables are introduced as well. These are:
* You can specify periods of different lengths, but the frequency of your timeindex needs to be consistent. Also,
you could use the `timeincrement` attribute of the energy system to model different weightings. Be aware that this
has not yet been tested.
* For now, both, the `timeindex` as well as the `timeincrement` of an energy system have to be defined since they
have to be of the same length for a multi-period model.
* Also please be aware, that periods correspond to years by default. You could also choose
monthly periods, but you would need to be very careful in parameterizing your energy system and your model and also,
this would mean monthly discounting (if applicable) as well as specifying your plants lifetimes in months.
Expand Down
4 changes: 2 additions & 2 deletions docs/whatsnew/v0-5-1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ New features

* Add option to run multi-period (dynamic) investment models with oemof.solph as an experimental feature:
* You can change from standard model to multi-period model by defining the newly introduced `periods`
attribute of your energy system. Be aware that it is experimental as of now. `periods` is a dictionary
mapping the periods you want to model (usually years) to pandas.date_range objects.
attribute of your energy system. Be aware that it is experimental as of now. `periods` is a list
of the periods you want to model (usually years) given as pandas.date_range objects.
* Add attributes `periods` to :class:`oemof.solph._energy_system.EnergySystem`.
* Introduce new Pyomo Sets `PERIODS` and `TIMEINDEX` in :class:`oemof.solph.models.Model`.
* Index all investment-related variables with `PERIODS` and flow variable with `TIMEINDEX`, which
Expand Down
17 changes: 6 additions & 11 deletions src/oemof/solph/_energy_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,11 @@ def __init__(
self._extract_periods_matrix()

def _extract_periods_years(self):
"""Map simulation years to the respective period based on time indices
"""Map years in optimization to respective period based on time indices

Returns
-------
periods_years: dict
the simulation year of the start of each a period,
relative to the start of the optimization run and starting with 0
Attribute `periods_years` of type list is set. It contains
the year of the start of each period, relative to the
start of the optimization run and starting with 0.
"""
periods_years = [0]
if self.periods is not None:
Expand All @@ -195,14 +193,11 @@ def _extract_periods_years(self):

def _extract_periods_matrix(self):
"""Determines a matrix describing the temporal distance to each period.

Attribute `periods_matrix` of type list np.array is set.
Rows represent investment/commissioning periods, columns represent
decommissioning periods. The values describe the temporal distance
between each investment period to each decommissioning period.

Returns
-------
period_distance_matrix: np.array

"""
periods_matrix = []
if self.periods is not None:
Expand Down
2 changes: 1 addition & 1 deletion src/oemof/solph/_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class Investment:
Units lifetime, given in years; only applicable for multi-period
models
age : int, :math:`a`
Units start age, given in years at the beginning of the simulation;
Units start age, given in years at the beginning of the optimization;
only applicable for multi-period models
interest_rate : float, :math:`ir`
Interest rate for calculating annuities when investing in a particular
Expand Down
4 changes: 2 additions & 2 deletions src/oemof/solph/flows/_investment_flow_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ def _create_constraints(self):
&
else:\\
&
P_{old,end}(p)\\
P_{old,end}(p) = 0\\
&\\
&
if \quad p=0:\\
Expand Down Expand Up @@ -529,7 +529,7 @@ def _old_capacity_rule_end(block):

# multiple invests can be decommissioned in the same period
# but only sequential ones, thus a bookkeeping is
# introduced andconstraints are added to equation one
# introduced and constraints are added to equation one
# iteration later.
last_decomm_p = np.nan
# loop over invest periods (values are decomm_periods)
Expand Down
Loading