From 5194cad3ef2cd588b613688b1bbe001347bcdc07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 22 Aug 2024 09:47:20 +0200 Subject: [PATCH 1/7] Remove tansitional "Transformer" wrapper It was agreed to provide them for solph v0.5 but remove them with v0.6. --- docs/whatsnew/v0-6-0.rst | 3 ++ src/oemof/solph/components/__init__.py | 4 --- src/oemof/solph/components/_converter.py | 30 ------------------- .../solph/components/_offset_converter.py | 28 ----------------- .../test_components/test_offset_converter.py | 2 +- tests/test_solph_network_classes.py | 15 ---------- 6 files changed, 4 insertions(+), 78 deletions(-) diff --git a/docs/whatsnew/v0-6-0.rst b/docs/whatsnew/v0-6-0.rst index 339fae4d9..006a5f31d 100644 --- a/docs/whatsnew/v0-6-0.rst +++ b/docs/whatsnew/v0-6-0.rst @@ -10,6 +10,9 @@ API changes 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. +* Tansitional wrappers that still allowed to use "Transformer" and + "OffsetTransformer" have been removed. Use of the new names + ("Converter" and "OffsetConverter") is now obligatory. New features ############ diff --git a/src/oemof/solph/components/__init__.py b/src/oemof/solph/components/__init__.py index e53a0659e..53021185e 100644 --- a/src/oemof/solph/components/__init__.py +++ b/src/oemof/solph/components/__init__.py @@ -11,13 +11,11 @@ from . import experimental from ._converter import Converter -from ._converter import Transformer from ._extraction_turbine_chp import ExtractionTurbineCHP from ._generic_chp import GenericCHP from ._generic_storage import GenericStorage from ._link import Link from ._offset_converter import OffsetConverter -from ._offset_converter import OffsetTransformer from ._offset_converter import slope_offset_from_nonconvex_input from ._offset_converter import slope_offset_from_nonconvex_output from ._sink import Sink @@ -31,9 +29,7 @@ "GenericStorage", "OffsetConverter", "Link", - "OffsetTransformer", "Sink", - "Transformer", "Source", "slope_offset_from_nonconvex_input", "slope_offset_from_nonconvex_output", diff --git a/src/oemof/solph/components/_converter.py b/src/oemof/solph/components/_converter.py index ab660ea02..255fd0111 100644 --- a/src/oemof/solph/components/_converter.py +++ b/src/oemof/solph/components/_converter.py @@ -21,8 +21,6 @@ """ -from warnings import warn - from oemof.network import Node from pyomo.core import BuildAction from pyomo.core import Constraint @@ -138,34 +136,6 @@ def constraint_group(self): return ConverterBlock -# --- BEGIN: To be removed for versions >= v0.6 --- -class Transformer(Converter): - def __init__( - self, - label=None, - inputs=None, - outputs=None, - conversion_factors=None, - custom_attributes=None, - ): - super().__init__( - label=label, - inputs=inputs, - outputs=outputs, - conversion_factors=conversion_factors, - custom_attributes=custom_attributes, - ) - warn( - "solph.components.Transformer has been renamed to" - " solph.components.Converter. The transitional wrapper" - " will be deleted in the future.", - FutureWarning, - ) - - -# --- END --- - - class ConverterBlock(ScalarBlock): r"""Block for the linear relation of nodes with type :class:`~oemof.solph.components._converter.ConverterBlock` diff --git a/src/oemof/solph/components/_offset_converter.py b/src/oemof/solph/components/_offset_converter.py index b078c9ced..403bae9df 100644 --- a/src/oemof/solph/components/_offset_converter.py +++ b/src/oemof/solph/components/_offset_converter.py @@ -378,34 +378,6 @@ def plot_partload(self, bus, tstep): return fig, ax -# --- BEGIN: To be removed for versions >= v0.6 --- -class OffsetTransformer(OffsetConverter): - def __init__( - self, - inputs, - outputs, - label=None, - coefficients=None, - custom_attributes=None, - ): - super().__init__( - label=label, - inputs=inputs, - outputs=outputs, - coefficients=coefficients, - custom_attributes=custom_attributes, - ) - warn( - "solph.components.OffsetTransformer has been renamed to" - " solph.components.OffsetConverter. The transitional wrapper" - " will be deleted in the future.", - FutureWarning, - ) - - -# --- END --- - - class OffsetConverterBlock(ScalarBlock): r"""Block for the relation of nodes with type :class:`~oemof.solph.components._offset_converter.OffsetConverter` diff --git a/tests/test_components/test_offset_converter.py b/tests/test_components/test_offset_converter.py index 997a1140c..f3d7d2e09 100644 --- a/tests/test_components/test_offset_converter.py +++ b/tests/test_components/test_offset_converter.py @@ -223,7 +223,7 @@ def test_wrong_number_of_coefficients(): bus1 = solph.Bus() bus2 = solph.Bus() with pytest.raises(ValueError, match="Two coefficients"): - solph.components.OffsetTransformer( + solph.components.OffsetConverter( inputs={ bus1: solph.Flow(nominal_value=2, nonconvex=solph.NonConvex()) }, diff --git a/tests/test_solph_network_classes.py b/tests/test_solph_network_classes.py index 71726a286..7feae7ea3 100644 --- a/tests/test_solph_network_classes.py +++ b/tests/test_solph_network_classes.py @@ -72,21 +72,6 @@ def test_converter_missing_input_create_empty_dict(self): assert converter.inputs == {} -def test_transformer_wrapper(): - # two warnings: Wrapper and no inputs/outputs - with pytest.warns(FutureWarning): - with pytest.warns(SuspiciousUsageWarning): - solph.components.Transformer() - - -def test_offset_transformer_wrapper(): - with pytest.warns(FutureWarning): - solph.components.OffsetTransformer( - inputs={solph.Bus("bus"): solph.Flow(nonconvex=solph.NonConvex())}, - outputs={}, - ) - - def test_wrong_combination_invest_and_nominal_value(): msg = "For backward compatibility, the option investment overwrites" with pytest.raises(AttributeError, match=msg): From cd0b8b5303795c4722e05598a06e70d2c25f1d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 22 Aug 2024 09:58:02 +0200 Subject: [PATCH 2/7] Remove transitional wrappers for Flow agruments It was agreed to provide them for solph v0.5 but remove them with v0.6. --- docs/whatsnew/v0-6-0.rst | 4 ++++ src/oemof/solph/flows/_flow.py | 31 ----------------------------- tests/test_flows/test_flow_class.py | 20 ------------------- tests/test_solph_network_classes.py | 12 ----------- 4 files changed, 4 insertions(+), 63 deletions(-) diff --git a/docs/whatsnew/v0-6-0.rst b/docs/whatsnew/v0-6-0.rst index 006a5f31d..2a96e2b1c 100644 --- a/docs/whatsnew/v0-6-0.rst +++ b/docs/whatsnew/v0-6-0.rst @@ -13,6 +13,10 @@ API changes * Tansitional wrappers that still allowed to use "Transformer" and "OffsetTransformer" have been removed. Use of the new names ("Converter" and "OffsetConverter") is now obligatory. +* Tansitional wrappers that still allowed to use "investment", + "summed_min", and "summed_max" as arguments to initialise a Flow + have been removed. Use of the new names ("nominal_value", + "full_load_time_min", and "full_load_time_max") is now obligatory. New features ############ diff --git a/src/oemof/solph/flows/_flow.py b/src/oemof/solph/flows/_flow.py index 6ed8e97ab..d642f8d32 100644 --- a/src/oemof/solph/flows/_flow.py +++ b/src/oemof/solph/flows/_flow.py @@ -137,11 +137,6 @@ def __init__( lifetime=None, age=None, fixed_costs=None, - # --- BEGIN: To be removed for versions >= v0.6 --- - investment=None, - summed_max=None, - summed_min=None, - # --- END --- custom_attributes=None, ): # TODO: Check if we can inherit from pyomo.core.base.var _VarData @@ -150,32 +145,6 @@ def __init__( # is created. E.g. create the variable in the energy system and # populate with information afterwards when creating objects. - # --- BEGIN: The following code can be removed for versions >= v0.6 --- - if investment is not None: - msg = ( - "For backward compatibility," - " the option investment overwrites the option nominal_value." - + " Both options cannot be set at the same time." - ) - if nominal_value is not None: - raise AttributeError(msg) - else: - warn(msg, FutureWarning) - nominal_value = investment - - msg = ( - "\nThe parameter '{0}' is deprecated and will be removed " - + "in version v0.6.\nUse the parameter '{1}', " - + "to avoid this warning and future problems. " - ) - if summed_max is not None: - warn(msg.format("summed_max", "full_load_time_max"), FutureWarning) - full_load_time_max = summed_max - if summed_min is not None: - warn(msg.format("summed_min", "full_load_time_min"), FutureWarning) - full_load_time_min = summed_min - # --- END --- - super().__init__() if custom_attributes is not None: diff --git a/tests/test_flows/test_flow_class.py b/tests/test_flows/test_flow_class.py index f59c907b6..42859f6f8 100644 --- a/tests/test_flows/test_flow_class.py +++ b/tests/test_flows/test_flow_class.py @@ -9,32 +9,12 @@ SPDX-License-Identifier: MIT """ -import warnings - import pytest from oemof.solph import NonConvex from oemof.solph.flows import Flow -def test_summed_max_future_warning(): - """Can be removed with v0.6.""" - msg = "The parameter 'summed_max' is deprecated and will be removed" - with warnings.catch_warnings(record=True) as w: - Flow(nominal_value=1, summed_max=2) - assert len(w) == 1 - assert msg in str(w[-1].message) - - -def test_summed_min_future_warning(): - """Can be removed with v0.6.""" - msg = "The parameter 'summed_min' is deprecated and will be removed" - with warnings.catch_warnings(record=True) as w: - Flow(nominal_value=1, summed_min=2) - assert len(w) == 1 - assert msg in str(w[-1].message) - - def test_source_with_full_load_time_max(): Flow(nominal_value=1, full_load_time_max=2) diff --git a/tests/test_solph_network_classes.py b/tests/test_solph_network_classes.py index 7feae7ea3..e3febfd2d 100644 --- a/tests/test_solph_network_classes.py +++ b/tests/test_solph_network_classes.py @@ -72,18 +72,6 @@ def test_converter_missing_input_create_empty_dict(self): assert converter.inputs == {} -def test_wrong_combination_invest_and_nominal_value(): - msg = "For backward compatibility, the option investment overwrites" - with pytest.raises(AttributeError, match=msg): - solph.flows.Flow(investment=solph.Investment(), nominal_value=4) - - -def test_invest_attribute_warning(): - msg = "For backward compatibility, the option investment overwrites" - with pytest.warns(FutureWarning, match=msg): - solph.flows.Flow(investment=solph.Investment()) - - def test_fixed_costs_warning(): msg = ( "Be aware that the fixed costs attribute is only\n" From 0463b4dc226ac40662d030227a6251be0aa94b40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 22 Aug 2024 11:30:03 +0200 Subject: [PATCH 3/7] Add removal hint for OffsetConverter coefficients --- .../solph/components/_offset_converter.py | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/oemof/solph/components/_offset_converter.py b/src/oemof/solph/components/_offset_converter.py index 403bae9df..84570b866 100644 --- a/src/oemof/solph/components/_offset_converter.py +++ b/src/oemof/solph/components/_offset_converter.py @@ -151,30 +151,26 @@ def __init__( custom_properties=custom_attributes, ) + # --- BEGIN: To be removed for versions >= v0.7 --- # this part is used for the transition phase from the old # OffsetConverter API to the new one. It calcualtes the # conversion_factors and normed_offsets from the coefficients and the # outputs information on min and max. - if ( - coefficients is not None - and conversion_factors is None - and normed_offsets is None - ): + if coefficients is not None: + if conversion_factors is not None or normed_offsets is not None: + msg = ( + "The deprecated argument `coefficients` cannot be used " + "in combination with its replacements " + "(`conversion_factors` and `normed_offsets`)." + ) + raise TypeError(msg) + normed_offsets, conversion_factors = ( self.normed_offset_and_conversion_factors_from_coefficients( coefficients ) ) - - elif coefficients is not None and ( - conversion_factors is not None or normed_offsets is not None - ): - msg = ( - "The deprecated argument `coefficients` cannot be used in " - "combination with its replacements (`conversion_factors` and " - "`normed_offsets`)." - ) - raise TypeError(msg) + # --- END --- _reference_flow = [v for v in self.inputs.values() if v.nonconvex] _reference_flow += [v for v in self.outputs.values() if v.nonconvex] @@ -252,6 +248,7 @@ def __init__( def constraint_group(self): return OffsetConverterBlock + # --- BEGIN: To be removed for versions >= v0.7 --- def normed_offset_and_conversion_factors_from_coefficients( self, coefficients ): @@ -318,6 +315,8 @@ def normed_offset_and_conversion_factors_from_coefficients( return normed_offsets, conversion_factors + # --- END --- + def plot_partload(self, bus, tstep): """Create a matplotlib figure of the flow to nonconvex flow relation. From 2ffc0becda88b702d0c5d72b5b2045ba054552a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 22 Aug 2024 15:41:21 +0200 Subject: [PATCH 4/7] Remove argument "invest" from GenericStorage --- .../solph/components/_generic_storage.py | 15 --------- tests/test_components.py | 33 ------------------- 2 files changed, 48 deletions(-) diff --git a/src/oemof/solph/components/_generic_storage.py b/src/oemof/solph/components/_generic_storage.py index 62a04dc87..9a1dfd6c2 100644 --- a/src/oemof/solph/components/_generic_storage.py +++ b/src/oemof/solph/components/_generic_storage.py @@ -169,7 +169,6 @@ def __init__( outputs=None, nominal_storage_capacity=None, initial_storage_level=None, - investment=None, invest_relation_input_output=None, invest_relation_input_capacity=None, invest_relation_output_capacity=None, @@ -199,20 +198,6 @@ def __init__( outputs=outputs, custom_properties=custom_attributes, ) - # --- BEGIN: The following code can be removed for versions >= v0.6 --- - if investment is not None: - msg = ( - "For backward compatibility," - " the option investment overwrites the option" - + " nominal_storage_capacity." - + " Both options cannot be set at the same time." - ) - if nominal_storage_capacity is not None: - raise AttributeError(msg) - else: - warn(msg, FutureWarning) - nominal_storage_capacity = investment - # --- END --- self.nominal_storage_capacity = None self.investment = None diff --git a/tests/test_components.py b/tests/test_components.py index f66230bfc..b1e7e0cac 100644 --- a/tests/test_components.py +++ b/tests/test_components.py @@ -42,28 +42,6 @@ def test_generic_storage_1(): ) -def test_generic_storage_2(): - """Nominal value defined with investment model.""" - bel = Bus() - with pytest.raises( - AttributeError, - match="For backward compatibility, the option investment overwrites", - ): - components.GenericStorage( - label="storage3", - nominal_storage_capacity=45, - inputs={bel: Flow(variable_costs=10e10)}, - outputs={bel: Flow(variable_costs=10e10)}, - loss_rate=0.00, - initial_storage_level=0, - invest_relation_input_capacity=1 / 6, - invest_relation_output_capacity=1 / 6, - inflow_conversion_factor=1, - outflow_conversion_factor=0.8, - investment=Investment(ep_costs=23), - ) - - def test_generic_storage_3(): """Nominal value defined with investment model.""" bel = Bus() @@ -148,17 +126,6 @@ def test_generic_storage_with_convex_invest_offset(): ) -def test_generic_storage_invest_warning(): - with pytest.warns(FutureWarning): - bel = Bus() - components.GenericStorage( - label="storage7", - inputs={bel: Flow()}, - outputs={bel: Flow()}, - investment=Investment(), - ) - - def test_generic_storage_with_invest_and_fixed_losses_absolute(): """ Storage with fixed losses in the investment mode but no minimum or existing From d9c972ee9aca4baf9993abd578499fdb5785dbf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 22 Aug 2024 15:43:34 +0200 Subject: [PATCH 5/7] Remove docstring for argument "invest" of GenericStorage --- src/oemof/solph/components/_generic_storage.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/oemof/solph/components/_generic_storage.py b/src/oemof/solph/components/_generic_storage.py index 9a1dfd6c2..0366c7a69 100644 --- a/src/oemof/solph/components/_generic_storage.py +++ b/src/oemof/solph/components/_generic_storage.py @@ -103,12 +103,6 @@ class GenericStorage(Node): To set different values in every time step use a sequence. max_storage_level : numeric (iterable or scalar), :math:`c_{max}(t)` see: min_storage_level - investment : :class:`oemof.solph.options.Investment` object - Object indicating if a nominal_value of the flow is determined by - the optimization problem. Note: This will refer all attributes to an - investment variable instead of to the nominal_storage_capacity. The - 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, starting from time point :math:`t_{1}`. From 4e745f0c3a67cc95131db7d6570c47a72bc9bd25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 17 Dec 2024 14:12:13 +0100 Subject: [PATCH 6/7] Fix code removal comments --- src/oemof/solph/components/_generic_storage.py | 2 +- tests/test_components/test_storage.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/oemof/solph/components/_generic_storage.py b/src/oemof/solph/components/_generic_storage.py index cbbd25a17..81d41ba54 100644 --- a/src/oemof/solph/components/_generic_storage.py +++ b/src/oemof/solph/components/_generic_storage.py @@ -215,7 +215,7 @@ def __init__( warn(msg, FutureWarning) nominal_storage_capacity = investment # --- END --- - # --- BEGIN: The following code can be removed for versions >= v0.6 --- + # --- BEGIN: The following code can be removed for versions >= v0.7 --- if nominal_storage_capacity is not None: msg = ( "For backward compatibility," diff --git a/tests/test_components/test_storage.py b/tests/test_components/test_storage.py index ec6494456..4c45d4871 100644 --- a/tests/test_components/test_storage.py +++ b/tests/test_components/test_storage.py @@ -346,7 +346,7 @@ def test_invest_content_maximum(): ) -# --- BEGIN: The following code can be removed for versions >= v0.6 --- +# --- BEGIN: The following code can be removed for versions >= v0.7 --- def test_capacity_keyword_wrapper_warning(): with pytest.warns(FutureWarning, match="nominal_storage_capacity"): bus = solph.Bus() From 05885631b9dee67f2dec5bbf65aba8356482b6be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 17 Dec 2024 14:23:44 +0100 Subject: [PATCH 7/7] Adhere to Black --- .../solph/components/_generic_storage.py | 222 +++++++++--------- 1 file changed, 111 insertions(+), 111 deletions(-) diff --git a/src/oemof/solph/components/_generic_storage.py b/src/oemof/solph/components/_generic_storage.py index 46caed3a1..31493e6b9 100644 --- a/src/oemof/solph/components/_generic_storage.py +++ b/src/oemof/solph/components/_generic_storage.py @@ -44,117 +44,117 @@ class GenericStorage(Node): r""" - Component `GenericStorage` to model with basic characteristics of storages. - - The GenericStorage is designed for one input and one output. - - Parameters - ---------- - nominal_capacity : numeric, :math:`E_{nom}` or - :class:`oemof.solph.options.Investment` object - Absolute nominal capacity of the storage, fixed value or - object describing parameter of investment optimisations. - invest_relation_input_capacity : numeric (iterable or scalar) or None, :math:`r_{cap,in}` - Ratio between the investment variable of the input Flow and the - investment variable of the storage: - :math:`\dot{E}_{in,invest} = E_{invest} \cdot r_{cap,in}` - invest_relation_output_capacity : numeric (iterable or scalar) or None, :math:`r_{cap,out}` - Ratio between the investment variable of the output Flow and the - investment variable of the storage: - :math:`\dot{E}_{out,invest} = E_{invest} \cdot r_{cap,out}` - invest_relation_input_output : numeric (iterable or scalar) or None, :math:`r_{in,out}` - Ratio between the investment variable of the output Flow and the - investment variable of the input flow. This ratio used to fix the - flow investments to each other. - Values < 1 set the input flow lower than the output and > 1 will - set the input flow higher than the output flow. If None no relation - will be set: - :math:`\dot{E}_{in,invest} = \dot{E}_{out,invest} \cdot r_{in,out}` - initial_storage_level : numeric, :math:`c(-1)` - The relative storage content in the timestep before the first - time step of optimization (between 0 and 1). - - Note: When investment mode is used in a multi-period model, - `initial_storage_level` is not supported. - Storage output is forced to zero until the storage unit is invested in. - balanced : boolean - Couple storage level of first and last time step. - (Total inflow and total outflow are balanced.) - loss_rate : numeric (iterable or scalar) - The relative loss of the storage content per hour. - fixed_losses_relative : numeric (iterable or scalar), :math:`\gamma(t)` - Losses per hour that are independent of the storage content but - proportional to nominal storage capacity. - - Note: Fixed losses are not supported in investment mode. - fixed_losses_absolute : numeric (iterable or scalar), :math:`\delta(t)` - Losses per hour that are independent of storage content and independent - of nominal storage capacity. - - Note: Fixed losses are not supported in investment mode. - inflow_conversion_factor : numeric (iterable or scalar), :math:`\eta_i(t)` - The relative conversion factor, i.e. efficiency associated with the - inflow of the storage. - outflow_conversion_factor : numeric (iterable or scalar), :math:`\eta_o(t)` - see: inflow_conversion_factor - min_storage_level : numeric (iterable or scalar), :math:`c_{min}(t)` - The normed minimum storage content as fraction of the - nominal storage capacity or the capacity that has been invested into - (between 0 and 1). - To set different values in every time step use a sequence. - max_storage_level : numeric (iterable or scalar), :math:`c_{max}(t)` - see: min_storage_level - storage_costs : numeric (iterable or scalar), :math:`c_{storage}(t)` - 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 - invest_relation_input_capacity defined - lifetime_outflow : int, :math:`n_{in}` - Determine the lifetime of an outflow; only applicable for multi-period - models which can invest in storage capacity and have an - invest_relation_output_capacity defined - - Notes - ----- - The following sets, variables, constraints and objective parts are created - * :py:class:`~oemof.solph.components._generic_storage.GenericStorageBlock` - (if no Investment object present) - * :py:class:`~oemof.solph.components._generic_storage.GenericInvestmentStorageBlock` - (if Investment object present) - - Examples - -------- - Basic usage examples of the GenericStorage with a random selection of - attributes. See the Flow class for all Flow attributes. - - >>> from oemof import solph - - >>> my_bus = solph.buses.Bus('my_bus') - - >>> my_storage = solph.components.GenericStorage( - ... label='storage', - ... nominal_capacity=1000, - ... inputs={my_bus: solph.flows.Flow(nominal_capacity=200, variable_costs=10)}, - ... outputs={my_bus: solph.flows.Flow(nominal_capacity=200)}, - ... loss_rate=0.01, - ... initial_storage_level=0, - ... max_storage_level = 0.9, - ... inflow_conversion_factor=0.9, - ... outflow_conversion_factor=0.93) - - >>> my_investment_storage = solph.components.GenericStorage( - ... label='storage', - ... nominal_capacity=solph.Investment(ep_costs=50), - ... inputs={my_bus: solph.flows.Flow()}, - ... outputs={my_bus: solph.flows.Flow()}, - ... loss_rate=0.02, - ... initial_storage_level=None, - ... invest_relation_input_capacity=1/6, - ... invest_relation_output_capacity=1/6, - ... inflow_conversion_factor=1, - ... outflow_conversion_factor=0.8) + Component `GenericStorage` to model with basic characteristics of storages. + + The GenericStorage is designed for one input and one output. + + Parameters + ---------- + nominal_capacity : numeric, :math:`E_{nom}` or + :class:`oemof.solph.options.Investment` object + Absolute nominal capacity of the storage, fixed value or + object describing parameter of investment optimisations. + invest_relation_input_capacity : numeric (iterable or scalar) or None, :math:`r_{cap,in}` + Ratio between the investment variable of the input Flow and the + investment variable of the storage: + :math:`\dot{E}_{in,invest} = E_{invest} \cdot r_{cap,in}` + invest_relation_output_capacity : numeric (iterable or scalar) or None, :math:`r_{cap,out}` + Ratio between the investment variable of the output Flow and the + investment variable of the storage: + :math:`\dot{E}_{out,invest} = E_{invest} \cdot r_{cap,out}` + invest_relation_input_output : numeric (iterable or scalar) or None, :math:`r_{in,out}` + Ratio between the investment variable of the output Flow and the + investment variable of the input flow. This ratio used to fix the + flow investments to each other. + Values < 1 set the input flow lower than the output and > 1 will + set the input flow higher than the output flow. If None no relation + will be set: + :math:`\dot{E}_{in,invest} = \dot{E}_{out,invest} \cdot r_{in,out}` + initial_storage_level : numeric, :math:`c(-1)` + The relative storage content in the timestep before the first + time step of optimization (between 0 and 1). + + Note: When investment mode is used in a multi-period model, + `initial_storage_level` is not supported. + Storage output is forced to zero until the storage unit is invested in. + balanced : boolean + Couple storage level of first and last time step. + (Total inflow and total outflow are balanced.) + loss_rate : numeric (iterable or scalar) + The relative loss of the storage content per hour. + fixed_losses_relative : numeric (iterable or scalar), :math:`\gamma(t)` + Losses per hour that are independent of the storage content but + proportional to nominal storage capacity. + + Note: Fixed losses are not supported in investment mode. + fixed_losses_absolute : numeric (iterable or scalar), :math:`\delta(t)` + Losses per hour that are independent of storage content and independent + of nominal storage capacity. + + Note: Fixed losses are not supported in investment mode. + inflow_conversion_factor : numeric (iterable or scalar), :math:`\eta_i(t)` + The relative conversion factor, i.e. efficiency associated with the + inflow of the storage. + outflow_conversion_factor : numeric (iterable or scalar), :math:`\eta_o(t)` + see: inflow_conversion_factor + min_storage_level : numeric (iterable or scalar), :math:`c_{min}(t)` + The normed minimum storage content as fraction of the + nominal storage capacity or the capacity that has been invested into + (between 0 and 1). + To set different values in every time step use a sequence. + max_storage_level : numeric (iterable or scalar), :math:`c_{max}(t)` + see: min_storage_level + storage_costs : numeric (iterable or scalar), :math:`c_{storage}(t)` + 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 + invest_relation_input_capacity defined + lifetime_outflow : int, :math:`n_{in}` + Determine the lifetime of an outflow; only applicable for multi-period + models which can invest in storage capacity and have an + invest_relation_output_capacity defined + + Notes + ----- + The following sets, variables, constraints and objective parts are created + * :py:class:`~oemof.solph.components._generic_storage.GenericStorageBlock` + (if no Investment object present) + * :py:class:`~oemof.solph.components._generic_storage.GenericInvestmentStorageBlock` + (if Investment object present) + + Examples + -------- + Basic usage examples of the GenericStorage with a random selection of + attributes. See the Flow class for all Flow attributes. + + >>> from oemof import solph + + >>> my_bus = solph.buses.Bus('my_bus') + + >>> my_storage = solph.components.GenericStorage( + ... label='storage', + ... nominal_capacity=1000, + ... inputs={my_bus: solph.flows.Flow(nominal_capacity=200, variable_costs=10)}, + ... outputs={my_bus: solph.flows.Flow(nominal_capacity=200)}, + ... loss_rate=0.01, + ... initial_storage_level=0, + ... max_storage_level = 0.9, + ... inflow_conversion_factor=0.9, + ... outflow_conversion_factor=0.93) + + >>> my_investment_storage = solph.components.GenericStorage( + ... label='storage', + ... nominal_capacity=solph.Investment(ep_costs=50), + ... inputs={my_bus: solph.flows.Flow()}, + ... outputs={my_bus: solph.flows.Flow()}, + ... loss_rate=0.02, + ... initial_storage_level=None, + ... invest_relation_input_capacity=1/6, + ... invest_relation_output_capacity=1/6, + ... inflow_conversion_factor=1, + ... outflow_conversion_factor=0.8) """ # noqa: E501 def __init__(