Skip to content

Commit

Permalink
Merge pull request #1094 from oemof/fix/storage_costs-for-initial-level
Browse files Browse the repository at this point in the history
Fix/storage costs for initial level
  • Loading branch information
p-snft authored Aug 19, 2024
2 parents fa5b7fb + 4ae6233 commit 2d02102
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 11 deletions.
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ These are new features and improvements of note in each release
:backlinks: top


.. include:: whatsnew/v0-6-0.rst
.. include:: whatsnew/v0-5-4.rst
.. include:: whatsnew/v0-5-3.rst
.. include:: whatsnew/v0-5-2.rst
Expand Down
38 changes: 38 additions & 0 deletions docs/whatsnew/v0-6-0.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
v0.6.0
------

API changes
###########

* Costs for energy storage are now defined for N-1 points in time
(initial time step is neglected). This is because with a balanced
storage, content of the initial and the first time step (which is
effectively the same) had double weight before. Also, if the
initial storage level is defined, the costs just offset the
objective value without changing anything else.

New features
############


Documentation
#############

Bug fixes
#########


Other changes
#############


Known issues
############

* Incompatible to numpy >= 2.0.0. This is because of Pyomo, but we have to
enforce a lower version in our package.

Contributors
############

* Patrik Schönfeldt
13 changes: 7 additions & 6 deletions src/oemof/solph/components/_generic_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ class GenericStorage(Node):
nominal_storage_capacity should not be set (or set to None) if an
investment object is used.
storage_costs : numeric (iterable or scalar), :math:`c_{storage}(t)`
Cost (per energy) for having energy in the storage.
Cost (per energy) for having energy in the storage, starting from
time point :math:`t_{1}`.
lifetime_inflow : int, :math:`n_{in}`
Determine the lifetime of an inflow; only applicable for multi-period
models which can invest in storage capacity and have an
Expand Down Expand Up @@ -423,7 +424,7 @@ class GenericStorageBlock(ScalarBlock):
* :attr: `storage_costs` not 0
.. math::
\sum_{t \in \textrm{TIMESTEPS}} c_{storage}(t) \cdot E(t)
\sum_{t \in \textrm{TIMEPOINTS} > 0} c_{storage}(t) \cdot E(t)
*Multi-period model*
Expand Down Expand Up @@ -616,12 +617,12 @@ def _objective_expression(self):

for n in self.STORAGES:
if n.storage_costs[0] is not None:
storage_costs += (
self.storage_content[n, 0] * n.storage_costs[0]
)
# We actually want to iterate over all TIMEPOINTS except the
# 0th. As integers are used for the index, this is equicalent
# to iterating over the TIMESTEPS with one offset.
for t in m.TIMESTEPS:
storage_costs += (
self.storage_content[n, t + 1] * n.storage_costs[t + 1]
self.storage_content[n, t + 1] * n.storage_costs[t]
)

self.storage_costs = Expression(expr=storage_costs)
Expand Down
2 changes: 1 addition & 1 deletion tests/constraint_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ def test_storage(self):
},
nominal_storage_capacity=1e5,
loss_rate=0.13,
storage_costs=0.1,
storage_costs=[0.1, 0.2, 0.3, 0.4],
inflow_conversion_factor=0.97,
outflow_conversion_factor=0.86,
initial_storage_level=0.4,
Expand Down
6 changes: 2 additions & 4 deletions tests/lp_files/storage.lp
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@

min
objective:
+4000.0 ONE_VAR_CONSTANT
+56 flow(electricityBus_storage_no_invest_0)
+56 flow(electricityBus_storage_no_invest_1)
+56 flow(electricityBus_storage_no_invest_2)
+24 flow(storage_no_invest_electricityBus_0)
+24 flow(storage_no_invest_electricityBus_1)
+24 flow(storage_no_invest_electricityBus_2)
+0.1 GenericStorageBlock_storage_content(storage_no_invest_1)
+0.1 GenericStorageBlock_storage_content(storage_no_invest_2)
+0.1 GenericStorageBlock_storage_content(storage_no_invest_3)
+0.2 GenericStorageBlock_storage_content(storage_no_invest_2)
+0.3 GenericStorageBlock_storage_content(storage_no_invest_3)

s.t.

Expand Down Expand Up @@ -72,7 +71,6 @@ c_e_GenericStorageBlock_balanced_cstr(storage_no_invest)_:
= 40000.0

bounds
1 <= ONE_VAR_CONSTANT <= 1
0 <= flow(electricityBus_storage_no_invest_0) <= 16667
0 <= flow(electricityBus_storage_no_invest_1) <= 16667
0 <= flow(electricityBus_storage_no_invest_2) <= 16667
Expand Down

0 comments on commit 2d02102

Please sign in to comment.