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

Make varying period lenghts possible #957

Merged
merged 26 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
38addf9
Add periods matrix
nailend Jul 19, 2023
6375e7b
Rework the _old_capacity_rul_end
nailend Jul 19, 2023
ff2b516
Rework _old_storage_capacity_rule_end
nailend Jul 19, 2023
09770b6
Fix f-string in message
nailend Jul 19, 2023
14abc53
Add test for varying period length in multi-period
nailend Jul 19, 2023
79237a8
Black&isort
nailend Jul 19, 2023
fae1c94
Add constraint test for multi period period length
nailend Jul 19, 2023
d22e472
black
nailend Jul 19, 2023
2179b15
Change iterator and remove unused variables
nailend Jul 20, 2023
0c77bf5
Rework inline comments
nailend Jul 20, 2023
143e0b7
Make black happy
nailend Jul 20, 2023
beb13cf
Remove test
nailend Jul 20, 2023
877cc6a
Add whatsnew
nailend Jul 20, 2023
699a8a8
Extend docstring for old_end rule
nailend Jul 20, 2023
a76caa2
Change to f-string
nailend Jul 20, 2023
b247be1
Apply new decommissiong method to SinkDSM
nailend Jul 20, 2023
73f39f9
Move multi-period-length test to multi-period-constraint-test
nailend Jul 20, 2023
27b2867
Reduce test to bus and storage component only
nailend Jul 20, 2023
909c84b
Add SinkDSM components of each approach
nailend Jul 20, 2023
a54a3de
Fix indentation
nailend Jul 20, 2023
10d1dc1
Black
nailend Jul 20, 2023
427233a
Update LP-file for multi-period varying period length
nailend Jul 20, 2023
7f01ec1
Add some info on period-length to usage.rst
nailend Jul 20, 2023
b01a206
Make flake happy
nailend Jul 24, 2023
3350f5a
Change wording
nailend Aug 7, 2023
889a81a
Merge branch 'dev' into features/make-varying-period-lenghts-possible
p-snft Aug 10, 2023
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
6 changes: 3 additions & 3 deletions examples/cellular/cellular.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
"""


from oemof.solph import EnergySystem
from oemof.solph import Model
from oemof.solph import buses
from oemof.solph import components as cmp
from oemof.solph import EnergySystem

from oemof.solph import create_time_index
from oemof.solph import flows
from oemof.solph import processing, views
from oemof.solph import processing
from oemof.solph import views


def main():
Expand Down
12 changes: 9 additions & 3 deletions examples/electrical/lopf.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,17 @@
import pandas as pd
from matplotlib import pyplot as plt
from oemof.network.graph import create_nx_graph
from oemof.solph import EnergySystem, Investment, Model, processing, views
from oemof.solph.components import Sink, Source

from oemof.solph import EnergySystem
from oemof.solph import Investment
from oemof.solph import Model
from oemof.solph import processing
from oemof.solph import views
from oemof.solph.buses.experimental import ElectricalBus
from oemof.solph.flows.experimental import ElectricalLine
from oemof.solph.components import Sink
from oemof.solph.components import Source
from oemof.solph.flows import Flow
from oemof.solph.flows.experimental import ElectricalLine

try:
import pygraphviz as pygz
Expand Down
12 changes: 6 additions & 6 deletions examples/excel_reader/dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,16 @@

"""

import os
import logging
import pandas as pd
import os

import networkx as nx
import pandas as pd
from matplotlib import pyplot as plt
from oemof.network.graph import create_nx_graph
from oemof.tools import logger
from oemof import solph

from oemof.network.graph import create_nx_graph
from matplotlib import pyplot as plt
import networkx as nx
from oemof import solph


def nodes_from_excel(filename):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,16 @@
__copyright__ = "oemof developer group"
__license__ = "MIT"

import numpy as np
import os
import pandas as pd
import time
from datetime import datetime, timedelta
from oemof import solph
import warnings
from datetime import datetime
from datetime import timedelta

import numpy as np
import pandas as pd

from oemof import solph

try:
import matplotlib.pyplot as plt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@

import numpy as np
import pandas as pd
from oemof import solph
from oemof.tools import economics

from oemof import solph

try:
import matplotlib.pyplot as plt
except ImportError:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@

import numpy as np
import pandas as pd
from oemof import solph
from oemof.tools import economics

from oemof import solph

try:
import matplotlib.pyplot as plt
except ImportError:
Expand Down
3 changes: 2 additions & 1 deletion examples/start_and_shutdown_costs/startup_shutdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
`MIT license <https://github.com/oemof/oemof-solph/blob/dev/LICENSE>`_

"""
import matplotlib.pyplot as plt
import pandas as pd

from oemof import solph
import matplotlib.pyplot as plt


def main():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
import warnings

import pandas as pd

# Default logger of oemof
from oemof.tools import economics
from oemof.tools import logger
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
import warnings

import pandas as pd

# Default logger of oemof
from oemof.tools import economics
from oemof.tools import logger
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@
import warnings

import pandas as pd

# Default logger of oemof
from oemof.tools import economics
from oemof.tools import logger
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
import warnings

import pandas as pd

# Default logger of oemof
from oemof.tools import economics
from oemof.tools import logger
Expand Down
15 changes: 9 additions & 6 deletions examples/storage_level_constraint/storage_level_constraint.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import pandas as pd
from oemof.solph import Bus, EnergySystem, Flow, Model
from oemof.solph.components import GenericStorage, Source, Sink
from oemof.solph.processing import results

import matplotlib.pyplot as plt
import pandas as pd

from oemof.solph import Bus
from oemof.solph import EnergySystem
from oemof.solph import Flow
from oemof.solph import Model
from oemof.solph.components import GenericStorage
from oemof.solph.components import Sink
from oemof.solph.components import Source
from oemof.solph.constraints import storage_level_constraint

from oemof.solph.processing import results

es = EnergySystem(
timeindex=pd.date_range("2022-01-01", freq="1H", periods=24),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
pip install oemof.solph
"""
import pandas as pd

from oemof import solph

try:
Expand Down
21 changes: 21 additions & 0 deletions src/oemof/solph/_energy_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ def __init__(
warnings.warn(msg, debugging.SuspiciousUsageWarning)
self.periods = periods
self._extract_periods_years()
self._extract_periods_matrix()

def _extract_periods_years(self):
"""Map simulation years to the respective period based on time indices
Expand All @@ -192,6 +193,26 @@ def _extract_periods_years(self):

self.periods_years = periods_years

def _extract_periods_matrix(self):
"""Determines a matrix describing the temporal distance to each period.
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:
period_years = np.array(self.periods_years)
for k, v in enumerate(period_years):
row = period_years - v
row = np.where(row < 0, 0, row)
periods_matrix.append(row)
nailend marked this conversation as resolved.
Show resolved Hide resolved
self.periods_matrix = np.array(periods_matrix)


def create_time_index(
year: int = None,
Expand Down
5 changes: 2 additions & 3 deletions src/oemof/solph/_groupings.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@

from oemof.network import groupings as groupings

from oemof.solph.flows._invest_non_convex_flow_block import (
InvestNonConvexFlowBlock,
)
from oemof.solph.flows._invest_non_convex_flow_block import \
InvestNonConvexFlowBlock
from oemof.solph.flows._investment_flow_block import InvestmentFlowBlock
from oemof.solph.flows._non_convex_flow_block import NonConvexFlowBlock
from oemof.solph.flows._simple_flow_block import SimpleFlowBlock
Expand Down
5 changes: 2 additions & 3 deletions src/oemof/solph/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@
from oemof.solph import processing
from oemof.solph.buses._bus import BusBlock
from oemof.solph.components._transformer import TransformerBlock
from oemof.solph.flows._invest_non_convex_flow_block import (
InvestNonConvexFlowBlock,
)
from oemof.solph.flows._invest_non_convex_flow_block import \
InvestNonConvexFlowBlock
from oemof.solph.flows._investment_flow_block import InvestmentFlowBlock
from oemof.solph.flows._non_convex_flow_block import NonConvexFlowBlock
from oemof.solph.flows._simple_flow_block import SimpleFlowBlock
Expand Down
80 changes: 66 additions & 14 deletions src/oemof/solph/components/_generic_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import numbers
from warnings import warn

import numpy as np
from oemof.network import network
from oemof.tools import debugging
from oemof.tools import economics
Expand Down Expand Up @@ -1232,24 +1233,75 @@ def _old_storage_capacity_rule_end(block):
" Value for {} is missing.".format(n)
)
raise ValueError(msg)
# get the period matrix describing the temporal distance
# between all period combinations. Row indexes indicating
# the investment period, column indexes the decommissioning
# period.
periods_matrix = m.es.periods_matrix
# matrix = np.where(matrix == 0, np.nan, matrix)

# get the index of the minimum value in each row greater
# equal than the lifetime. This value equals the
# decommissioning period if not zero. The index of this
# value represents the investment period.
decomm_periods = np.argmin(
np.where(
(periods_matrix >= lifetime),
periods_matrix,
np.inf,
),
axis=1,
)

# first period doesn't have any decommissioning
expr = self.old_end[n, 0] == 0
self.old_rule_end.add((n, 0), expr)

# all periods not in decomm_periods have no decommissioning
for p in m.PERIODS:
# No shutdown in first period
if p == 0:
if p not in decomm_periods and p != 0:
expr = self.old_end[n, p] == 0
self.old_rule_end.add((n, p), expr)
nailend marked this conversation as resolved.
Show resolved Hide resolved
elif lifetime <= m.es.periods_years[p]:
# Obtain commissioning period
comm_p = 0
for k, v in enumerate(m.es.periods_years):
if m.es.periods_years[p] - lifetime - v < 0:
# change of sign is detected
comm_p = k - 1
break
expr = self.old_end[n, p] == self.invest[n, comm_p]
self.old_rule_end.add((n, p), expr)

# multiple invests can decommission in the same period
nailend marked this conversation as resolved.
Show resolved Hide resolved
# but only sequential ones, thus a memory is introduced and
nailend marked this conversation as resolved.
Show resolved Hide resolved
# constraints are added to equation one iteration later.
last_decomm_p = np.nan
# loop over invest periods (values are decomm_periods)
for invest_p, decomm_p in enumerate(decomm_periods):
# Add constraint of iteration before
# (skipped in first iteration)
if (decomm_p != last_decomm_p) and (
last_decomm_p is not np.nan
):
#
expr = self.old_end[n, last_decomm_p] == expr
self.old_rule_end.add((n, last_decomm_p), expr)

# no decommissioning if decomm_p is zero
if decomm_p == 0:
# overwrite decomm_p memory with nan to avoid
# chaining invest periods in next iteration
last_decomm_p = 0

# if decomm_p is the same as the last one chain invest
# period
elif decomm_p == last_decomm_p:
expr += self.invest[n, invest_p]
# overwrite decomm_p memory
last_decomm_p = decomm_p

# if decomm_p is not zero, not the same as the last one,
# and it's not the first period
else:
expr = self.old_end[n, p] == 0
self.old_rule_end.add((n, p), expr)
expr = self.invest[n, invest_p]
# overwrite decomm_p memory
last_decomm_p = decomm_p

if last_decomm_p != 0:
# Add constraint of last iteration
expr = self.old_end[n, last_decomm_p] == expr
self.old_rule_end.add((n, last_decomm_p), expr)
nailend marked this conversation as resolved.
Show resolved Hide resolved

self.old_rule_end = Constraint(
self.INVESTSTORAGES, m.PERIODS, noruleinit=True
Expand Down
4 changes: 2 additions & 2 deletions src/oemof/solph/flows/_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ def __init__(
the_attr = eval(attr)
if the_attr is not None:
raise AttributeError(
"If {} is set in a flow (except InvestmentFlow), "
f"If {attr} is set in a flow (except InvestmentFlow), "
"nominal_value must be set as well.\n"
"Otherwise, it won't have any effect.".format(attr)
"Otherwise, it won't have any effect."
)
# minimum will be set even without nominal limit

Expand Down
Loading
Loading