From ad26abdcdae506a8fd250a3a5a002dcf48696a2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Wed, 17 Mar 2021 21:28:42 +0100 Subject: [PATCH 01/58] Add equations for Link's constraints --- src/oemof/solph/custom/link.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index 69e7e423c..ec86f7219 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -97,8 +97,19 @@ class LinkBlock(SimpleBlock): **The following constraints are created:** - TODO: Add description for constraints - TODO: Add tests + .. _Link-equations: + + .. math:: + & + (1) \qquad P_{\mathrm{in},n}(t) = c_n(t) \times P_{\mathrm{out},n}(t) + \quad \forall t \in T, \forall n in {1,2} \\ + & + (2) \qquad + P_{\mathrm{in},1}(t) + + P_{\mathrm{in},2}(t) + = c_1(t) \times P_{\mathrm{out},1}(t) + + c_2(t) \times P_{\mathrm{out},2}(t) + \quad \forall t \in T """ CONSTRAINT_GROUP = True From 9fe83f809f6cf66d9b5779484f8f2d227923cf27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 18 Mar 2021 06:35:22 +0100 Subject: [PATCH 02/58] Remove useless constraint --- src/oemof/solph/custom/link.py | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index ec86f7219..81f550d3c 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -104,12 +104,6 @@ class LinkBlock(SimpleBlock): (1) \qquad P_{\mathrm{in},n}(t) = c_n(t) \times P_{\mathrm{out},n}(t) \quad \forall t \in T, \forall n in {1,2} \\ & - (2) \qquad - P_{\mathrm{in},1}(t) - + P_{\mathrm{in},2}(t) - = c_1(t) \times P_{\mathrm{out},1}(t) - + c_2(t) \times P_{\mathrm{out},2}(t) - \quad \forall t \in T """ CONSTRAINT_GROUP = True @@ -168,27 +162,3 @@ def _input_output_relation(block): noruleinit=True, ) self.relation_build = BuildAction(rule=_input_output_relation) - - def _exclusive_direction_relation(block): - for t in m.TIMESTEPS: - for n, cf in all_conversions.items(): - cf_keys = list(cf.keys()) - expr = ( - m.flow[cf_keys[0][0], n, t] * cf[cf_keys[0]][t] - + m.flow[cf_keys[1][0], n, t] * cf[cf_keys[1]][t] - == m.flow[n, cf_keys[0][1], t] - + m.flow[n, cf_keys[1][1], t] - ) - block.relation_exclusive_direction.add((n, t), expr) - - self.relation_exclusive_direction = Constraint( - [ - (n, t) - for t in m.TIMESTEPS - for n, conversion in all_conversions.items() - ], - noruleinit=True, - ) - self.relation_exclusive_direction_build = BuildAction( - rule=_exclusive_direction_relation - ) From 981d807bf39a8b541319feb2f7eae23f9ddc1ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Fri, 19 Mar 2021 22:40:26 +0100 Subject: [PATCH 03/58] Add link all equations in link documentation Note: Implementation of these equations is still missing. --- src/oemof/solph/custom/link.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index 81f550d3c..2a79a7f43 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -104,6 +104,12 @@ class LinkBlock(SimpleBlock): (1) \qquad P_{\mathrm{in},n}(t) = c_n(t) \times P_{\mathrm{out},n}(t) \quad \forall t \in T, \forall n in {1,2} \\ & + (2) \qquad 0 \le \hat{S} + P_{\mathrm{in},1}(t)/P_{\mathrm{max}} \le 1 + \quad \forall t \in T \\ + & + (3) \qquad 0 \le \hat{S} - P_{\mathrm{in},2}(t)/P_{\mathrm{max}} \le 1 + \quad \forall t \in T \\ + & """ CONSTRAINT_GROUP = True From 8275291fc68a9b52255c9837ad3a65e39998c635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 23 Mar 2021 22:17:01 +0100 Subject: [PATCH 04/58] Implement draft for Link with single binary constraint This still has mayor flaws and does not work. --- src/oemof/solph/custom/link.py | 55 ++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index 2a79a7f43..57e950a7b 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -19,6 +19,7 @@ from oemof.network import network as on from pyomo.core.base.block import SimpleBlock +from pyomo.core import Binary, Set, Var from pyomo.environ import BuildAction from pyomo.environ import Constraint @@ -52,9 +53,10 @@ class Link(on.Transformer): >>> link = solph.custom.Link( ... label="transshipment_link", - ... inputs={bel0: solph.Flow(), bel1: solph.Flow()}, + ... inputs={bel0: solph.Flow(nominal_value=4), + ... bel1: solph.Flow(nominal_value=2)}, ... outputs={bel0: solph.Flow(), bel1: solph.Flow()}, - ... conversion_factors={(bel0, bel1): 0.92, (bel1, bel0): 0.99}) + ... conversion_factors={(bel0, bel1): 0.8, (bel1, bel0): 0.9}) >>> print(sorted([x[1][5] for x in link.conversion_factors.items()])) [0.92, 0.99] @@ -65,7 +67,7 @@ class Link(on.Transformer): ['el0', 'el1'] >>> link.conversion_factors[(bel0, bel1)][3] - 0.92 + 0.8 """ def __init__(self, *args, **kwargs): @@ -104,10 +106,12 @@ class LinkBlock(SimpleBlock): (1) \qquad P_{\mathrm{in},n}(t) = c_n(t) \times P_{\mathrm{out},n}(t) \quad \forall t \in T, \forall n in {1,2} \\ & - (2) \qquad 0 \le \hat{S} + P_{\mathrm{in},1}(t)/P_{\mathrm{max}} \le 1 + (2) \qquad 1 \ge \hat{S} + P_{\mathrm{in},1}(t) + / P_{\mathrm{in},1,\mathrm{max}} \quad \forall t \in T \\ & - (3) \qquad 0 \le \hat{S} - P_{\mathrm{in},2}(t)/P_{\mathrm{max}} \le 1 + (3) \qquad 0 \le \hat{S} - P_{\mathrm{in},2}(t) + / P_{2\mathrm{in},2,\mathrm{max}} \quad \forall t \in T \\ & @@ -140,6 +144,17 @@ def _create(self, group=None): k: v for k, v in n.conversion_factors.items() } + self.LINKS = Set(initialize=[g for g in group]) + self.LINK_1ST_INFLOWS = Set( + initialize=[(list(c)[0][0], n) + for n, c in all_conversions.items()]) + self.LINK_2ND_INFLOWS = Set( + initialize=[(list(c)[1][0], n) + for n, c in all_conversions.items()]) + + # 0: Flows 1 connected; 1: Flows 2 connected + self.direction = Var(self.LINKS, m.TIMESTEPS, within=Binary) + def _input_output_relation(block): for t in m.TIMESTEPS: for n, conversion in all_conversions.items(): @@ -168,3 +183,33 @@ def _input_output_relation(block): noruleinit=True, ) self.relation_build = BuildAction(rule=_input_output_relation) + + def _flow1_rule(block, i, link, t): + """Rule definition for Eq. (2).""" + expr = ( + 1 >= + self.direction[link, t] + + m.flow[i, link, t] + * m.flows[i, link].max[t] + * m.flows[i, link].nominal_value + ) + return expr + + self.flow1 = Constraint( + self.LINK_1ST_INFLOWS, m.TIMESTEPS, rule=_flow1_rule + ) + + def _flow2_rule(block, i, link, t): + """Rule definition for Eq. (3).""" + expr = ( + 0 <= + self.direction[link, t] + - m.flow[i, link, t] + * m.flows[i, link].max[t] + * m.flows[i, link].nominal_value + ) + return expr + + self.flow2 = Constraint( + self.LINK_2ND_INFLOWS, m.TIMESTEPS, rule=_flow2_rule + ) From 79740ee317ec1a0a4b997b669610215821668dfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Wed, 24 Mar 2021 06:38:41 +0100 Subject: [PATCH 05/58] Fix formating --- src/oemof/solph/custom/link.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index 57e950a7b..aeafe8955 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -187,11 +187,11 @@ def _input_output_relation(block): def _flow1_rule(block, i, link, t): """Rule definition for Eq. (2).""" expr = ( - 1 >= - self.direction[link, t] - + m.flow[i, link, t] - * m.flows[i, link].max[t] - * m.flows[i, link].nominal_value + 1 >= (self.direction[link, t] + + m.flow[i, link, t] + * m.flows[i, link].max[t] + * m.flows[i, link].nominal_value + ) ) return expr @@ -202,11 +202,11 @@ def _flow1_rule(block, i, link, t): def _flow2_rule(block, i, link, t): """Rule definition for Eq. (3).""" expr = ( - 0 <= - self.direction[link, t] - - m.flow[i, link, t] - * m.flows[i, link].max[t] - * m.flows[i, link].nominal_value + 0 <= (self.direction[link, t] + - m.flow[i, link, t] + * m.flows[i, link].max[t] + * m.flows[i, link].nominal_value + ) ) return expr From abe7ba30a63ed6831c92db89ad5d4c69013c7af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Wed, 24 Mar 2021 19:23:24 +0100 Subject: [PATCH 06/58] Fix formating --- src/oemof/solph/custom/link.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index aeafe8955..80e155b1f 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -191,7 +191,7 @@ def _flow1_rule(block, i, link, t): + m.flow[i, link, t] * m.flows[i, link].max[t] * m.flows[i, link].nominal_value - ) + ) ) return expr @@ -206,7 +206,7 @@ def _flow2_rule(block, i, link, t): - m.flow[i, link, t] * m.flows[i, link].max[t] * m.flows[i, link].nominal_value - ) + ) ) return expr From 21afe9024e1d8e527c7c344d83e52f264fa4424d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 3 Jun 2021 09:45:42 +0200 Subject: [PATCH 07/58] Set version to "0.4.5.dev0" --- docs/conf.py | 2 +- setup.py | 2 +- src/oemof/solph/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 1cc355703..459c9be43 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -30,7 +30,7 @@ def setup(app): year = "2014-2021" author = "oemof-developer-group" copyright = "{0}, {1}".format(year, author) -version = release = "0.4.4" +version = release = "0.4.5.dev0" pygments_style = "trac" templates_path = ["."] diff --git a/setup.py b/setup.py index f1f25106f..a5eb029a7 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ def read(*names, **kwargs): setup( name="oemof.solph", - version="0.4.4", + version="0.4.5.dev0", license="MIT", description=( "A model generator for energy system modelling and optimisation." diff --git a/src/oemof/solph/__init__.py b/src/oemof/solph/__init__.py index d9f9b3c62..8cf2b6cb1 100644 --- a/src/oemof/solph/__init__.py +++ b/src/oemof/solph/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.4.4" +__version__ = "0.4.5.dev0" from . import constraints # noqa: F401 from . import custom # noqa: F401 From d7ca5aa440d4f8c0f88e464eed3678f6d08e1d14 Mon Sep 17 00:00:00 2001 From: Uwe Krien Date: Thu, 3 Jun 2021 09:48:02 +0200 Subject: [PATCH 08/58] Fix commit_since-badge --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 35448b64b..f2690e2d3 100644 --- a/README.rst +++ b/README.rst @@ -60,7 +60,7 @@ :alt: Supported implementations :target: https://pypi.org/project/oemof.solph -.. |commits-since| image:: https://img.shields.io/github/commits-since/oemof/oemof-solph/v0.4.3/dev +.. |commits-since| image:: https://img.shields.io/github/commits-since/oemof/oemof-solph/v0.4.4/dev :alt: Commits since latest release :target: https://github.com/oemof/oemof-solph/compare/v0.4.4...dev From e4bb02fae18049afe99f78ced9c52e65071cc382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 14 Sep 2021 09:38:05 +0200 Subject: [PATCH 09/58] Create CITATION.cff --- CITATION.cff | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 CITATION.cff diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 000000000..ed0880be9 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,19 @@ +# YAML 1.2 +--- +cff-version: "1.1.0" +doi: "10.5281/zenodo.596235" +license: MIT +message: "If you use this software, please cite it using these metadata." +title: "oemof.solph" +abstract: "The oemof.solph package is part of the Open energy modelling framework (oemof). This an organisational framework to bundle tools for energy (system) modelling. oemof-solph is a model generator for energy system modelling and optimisation." +authors: + - + family-names: Krien + given-names: Uwe + - + family-names: Kaldemeyer + given-names: Cord + - + family-names: Stephan + given-names: "Günther" +... From 480b8a2ced979b2a4576072c45832b2a33cbc95d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 14 Sep 2021 09:46:15 +0200 Subject: [PATCH 10/58] Include CITATION.cff in MANIFEST.in --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index 1791494fd..59a6df7e1 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -10,6 +10,7 @@ include .editorconfig include AUTHORS.rst include CHANGELOG.rst +include CITATION.cff include CONTRIBUTING.rst include LICENSE include README.rst From 3fcbb1d30dced22b22d3f7753b95c14d197a20d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 14 Sep 2021 09:59:50 +0200 Subject: [PATCH 11/58] Add contibutors Added all contributors that have their names added to their GitHub profile. --- CITATION.cff | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index ed0880be9..722b6c280 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -14,6 +14,33 @@ authors: family-names: Kaldemeyer given-names: Cord - - family-names: Stephan - given-names: "Günther" + family-names: "Günther" + given-names: Stephan + - + family-names: "Möller" + given-names: Caroline + - + family-names: "Schönfeldt" + given-names: Patrik + - + family-names: "Röder" + given-names: Johannes + - + family-names: Schachler + given-names: Birgit + - + family-names: Endres + given-names: Julian + - + family-names: Lancien + given-names: Bryan + - + family-names: Kochems + given-names: Johannes + - + family-names: Delfs + given-names: Jens-Olaf + - + family-names: Smalla + given-names: Tjark ... From fc2c20972ab4d6453f6e9c29a9748309a104df25 Mon Sep 17 00:00:00 2001 From: uvchik Date: Mon, 20 Sep 2021 20:21:33 +0200 Subject: [PATCH 12/58] Remove gradient costs due to bugs and implementation errors --- src/oemof/solph/blocks/flow.py | 16 +--------------- src/oemof/solph/network/flow.py | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/oemof/solph/blocks/flow.py b/src/oemof/solph/blocks/flow.py index 4a18d63bf..6a1098785 100644 --- a/src/oemof/solph/blocks/flow.py +++ b/src/oemof/solph/blocks/flow.py @@ -271,18 +271,4 @@ def _objective_expression(self): * m.flows[i, o].variable_costs[t] ) - if m.flows[i, o].positive_gradient["ub"][0] is not None: - for t in m.TIMESTEPS: - gradient_costs += ( - self.positive_gradient[i, o, t] - * m.flows[i, o].positive_gradient["costs"] - ) - - if m.flows[i, o].negative_gradient["ub"][0] is not None: - for t in m.TIMESTEPS: - gradient_costs += ( - self.negative_gradient[i, o, t] - * m.flows[i, o].negative_gradient["costs"] - ) - - return variable_costs + gradient_costs + return variable_costs diff --git a/src/oemof/solph/network/flow.py b/src/oemof/solph/network/flow.py index 99fef9590..bd569fbe8 100644 --- a/src/oemof/solph/network/flow.py +++ b/src/oemof/solph/network/flow.py @@ -52,8 +52,7 @@ class Flow(on.Edge): * `'ub'`: numeric (iterable, scalar or None), the normed *upper bound* on the positive difference (`flow[t-1] < flow[t]`) of two consecutive flow values. - * `'costs``: numeric (scalar or None), the gradient cost per - unit. + * `'costs``: REMOVED! negative_gradient : :obj:`dict`, default: `{'ub': None, 'costs': 0}` @@ -62,8 +61,7 @@ class Flow(on.Edge): * `'ub'`: numeric (iterable, scalar or None), the normed *upper bound* on the negative difference (`flow[t-1] > flow[t]`) of two consecutive flow values. - * `'costs``: numeric (scalar or None), the gradient cost per - unit. + * `'costs``: REMOVED! summed_max : numeric, :math:`f_{sum,max}` Specific maximum value summed over all timesteps. Will be multiplied @@ -142,8 +140,8 @@ def __init__(self, **kwargs): dictionaries = ["positive_gradient", "negative_gradient"] defaults = { "variable_costs": 0, - "positive_gradient": {"ub": None, "costs": 0}, - "negative_gradient": {"ub": None, "costs": 0}, + "positive_gradient": {"ub": None}, + "negative_gradient": {"ub": None}, } keys = [k for k in kwargs if k != "label"] @@ -184,13 +182,24 @@ def __init__(self, **kwargs): if kwargs.get("max") is None: defaults["max"] = 1 + # Check gradient dictionaries for non-valid keys + for gradient_dict in ["negative_gradient", "positive_gradient"]: + if gradient_dict in kwargs: + if list(kwargs[gradient_dict].keys()) != list( + defaults[gradient_dict].keys() + ): + msg = ( + "Only the key 'ub' is allowed for the '{0}' attribute" + ) + raise AttributeError(msg.format(gradient_dict)) + for attribute in set(scalars + sequences + dictionaries + keys): value = kwargs.get(attribute, defaults.get(attribute)) if attribute in dictionaries: setattr( self, attribute, - {"ub": sequence(value["ub"]), "costs": value["costs"]}, + {"ub": sequence(value["ub"])}, ) else: From 601ee11dee6f3b644109fa68a2c8c52c14c26669 Mon Sep 17 00:00:00 2001 From: uvchik Date: Mon, 20 Sep 2021 20:53:57 +0200 Subject: [PATCH 13/58] Remove gradient costs from tests --- tests/constraint_tests.py | 8 ++++---- tests/lp_files/source_with_gradient.lp | 8 -------- tests/test_processing.py | 4 ---- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/tests/constraint_tests.py b/tests/constraint_tests.py index d2e24036f..ed29234bf 100644 --- a/tests/constraint_tests.py +++ b/tests/constraint_tests.py @@ -846,8 +846,8 @@ def test_gradient(self): bel: solph.Flow( nominal_value=999, variable_costs=23, - positive_gradient={"ub": 0.03, "costs": 7}, - negative_gradient={"ub": 0.05, "costs": 8}, + positive_gradient={"ub": 0.03}, + negative_gradient={"ub": 0.05}, ) }, ) @@ -887,7 +887,7 @@ def test_nonconvex_positive_gradient_error(self): nonconvex=solph.NonConvex( positive_gradient={"ub": 0.03, "costs": 7}, ), - positive_gradient={"ub": 0.03, "costs": 7}, + positive_gradient={"ub": 0.03}, ) def test_nonconvex_negative_gradient_error(self): @@ -903,7 +903,7 @@ def test_nonconvex_negative_gradient_error(self): nonconvex=solph.NonConvex( negative_gradient={"ub": 0.03, "costs": 7}, ), - negative_gradient={"ub": 0.03, "costs": 7}, + negative_gradient={"ub": 0.03}, ) def test_investment_limit(self): diff --git a/tests/lp_files/source_with_gradient.lp b/tests/lp_files/source_with_gradient.lp index ddc85d390..aff22b4ec 100644 --- a/tests/lp_files/source_with_gradient.lp +++ b/tests/lp_files/source_with_gradient.lp @@ -2,12 +2,6 @@ min objective: -+8 Flow_negative_gradient(powerplant_electricityBus_0) -+8 Flow_negative_gradient(powerplant_electricityBus_1) -+8 Flow_negative_gradient(powerplant_electricityBus_2) -+7 Flow_positive_gradient(powerplant_electricityBus_0) -+7 Flow_positive_gradient(powerplant_electricityBus_1) -+7 Flow_positive_gradient(powerplant_electricityBus_2) +23 flow(powerplant_electricityBus_0) +23 flow(powerplant_electricityBus_1) +23 flow(powerplant_electricityBus_2) @@ -57,10 +51,8 @@ bounds 0 <= flow(powerplant_electricityBus_0) <= 999 0 <= flow(powerplant_electricityBus_1) <= 999 0 <= flow(powerplant_electricityBus_2) <= 999 - -inf <= Flow_positive_gradient(powerplant_electricityBus_0) <= 29.969999999999999 -inf <= Flow_positive_gradient(powerplant_electricityBus_1) <= 29.969999999999999 -inf <= Flow_positive_gradient(powerplant_electricityBus_2) <= 29.969999999999999 - -inf <= Flow_negative_gradient(powerplant_electricityBus_0) <= 49.950000000000003 -inf <= Flow_negative_gradient(powerplant_electricityBus_1) <= 49.950000000000003 -inf <= Flow_negative_gradient(powerplant_electricityBus_2) <= 49.950000000000003 end diff --git a/tests/test_processing.py b/tests/test_processing.py index 31a63aff5..6914267fb 100644 --- a/tests/test_processing.py +++ b/tests/test_processing.py @@ -99,8 +99,6 @@ def test_flows_with_none_exclusion(self): "nominal_value": 1, "max": 1, "min": 0, - "negative_gradient_costs": 0, - "positive_gradient_costs": 0, "variable_costs": 0, "label": str(b_el2.outputs[demand].label), } @@ -128,9 +126,7 @@ def test_flows_without_none_exclusion(self): "max": 1, "min": 0, "negative_gradient_ub": None, - "negative_gradient_costs": 0, "positive_gradient_ub": None, - "positive_gradient_costs": 0, "variable_costs": 0, "flow": None, "values": None, From 35bce495bb07a50cd815c04f7ea606899eb1a7a5 Mon Sep 17 00:00:00 2001 From: uvchik Date: Mon, 20 Sep 2021 20:56:04 +0200 Subject: [PATCH 14/58] Remove obsolete variable --- src/oemof/solph/blocks/flow.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/oemof/solph/blocks/flow.py b/src/oemof/solph/blocks/flow.py index 6a1098785..93911e39e 100644 --- a/src/oemof/solph/blocks/flow.py +++ b/src/oemof/solph/blocks/flow.py @@ -260,7 +260,6 @@ def _objective_expression(self): m = self.parent_block() variable_costs = 0 - gradient_costs = 0 for i, o in m.FLOWS: if m.flows[i, o].variable_costs[0] is not None: From 8adeb58707a2a65bc70a586e95555f10ca33b137 Mon Sep 17 00:00:00 2001 From: uvchik Date: Thu, 23 Sep 2021 09:32:26 +0200 Subject: [PATCH 15/58] Test the new error message --- tests/flow_tests.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tests/flow_tests.py diff --git a/tests/flow_tests.py b/tests/flow_tests.py new file mode 100644 index 000000000..2a9295d11 --- /dev/null +++ b/tests/flow_tests.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 - + +"""Testing the flows. + +This file is part of project oemof (github.com/oemof/oemof). It's copyrighted +by the contributors recorded in the version control history of the file, +available from its original location oemof/tests/test_components.py + +SPDX-License-Identifier: MIT +""" + +import warnings + +import pytest +from oemof.tools.debugging import SuspiciousUsageWarning + +from oemof.solph import Flow + + +def test_error_in_gradient_attribute(): + msg = "Only the key 'ub' is allowed for the '{0}' attribute" + with pytest.raises(AttributeError, match=msg.format("negative_gradient")): + Flow(negative_gradient={"costs": 5}) + with pytest.raises(AttributeError, match=msg.format("positive_gradient")): + Flow(positive_gradient={"something": 5}) From 4fd8d191f25d04f1405f62601a9d38fa94beaf71 Mon Sep 17 00:00:00 2001 From: uvchik Date: Thu, 23 Sep 2021 09:33:24 +0200 Subject: [PATCH 16/58] Remove missing imports --- tests/flow_tests.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/flow_tests.py b/tests/flow_tests.py index 2a9295d11..48ed86a14 100644 --- a/tests/flow_tests.py +++ b/tests/flow_tests.py @@ -9,10 +9,7 @@ SPDX-License-Identifier: MIT """ -import warnings - import pytest -from oemof.tools.debugging import SuspiciousUsageWarning from oemof.solph import Flow From 2c0ebe56c129c30d99e75c521f04a10a3486d61a Mon Sep 17 00:00:00 2001 From: uvchik Date: Thu, 23 Sep 2021 10:21:12 +0200 Subject: [PATCH 17/58] Remove unused lines --- src/oemof/solph/blocks/flow.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/oemof/solph/blocks/flow.py b/src/oemof/solph/blocks/flow.py index 93911e39e..926c5302e 100644 --- a/src/oemof/solph/blocks/flow.py +++ b/src/oemof/solph/blocks/flow.py @@ -215,8 +215,6 @@ def _positive_gradient_flow_rule(model): self.positive_gradient_constr.add( (inp, out, ts), lhs <= rhs ) - else: - pass # return(Constraint.Skip) self.positive_gradient_constr = Constraint( self.POSITIVE_GRADIENT_FLOWS, m.TIMESTEPS, noruleinit=True @@ -235,8 +233,6 @@ def _negative_gradient_flow_rule(model): self.negative_gradient_constr.add( (inp, out, ts), lhs <= rhs ) - else: - pass # return(Constraint.Skip) self.negative_gradient_constr = Constraint( self.NEGATIVE_GRADIENT_FLOWS, m.TIMESTEPS, noruleinit=True From 07d7d4f96ca73e88ae977f429006a1b42d327e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 4 Nov 2021 09:36:47 +0100 Subject: [PATCH 18/58] Add missing (nick) names to CITATION.cff --- CITATION.cff | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/CITATION.cff b/CITATION.cff index 722b6c280..c6bde4661 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -16,6 +16,11 @@ authors: - family-names: "Günther" given-names: Stephan + - + family-names: Simon + given-names: Hilpert + - + given-names: jnnr - family-names: "Möller" given-names: Caroline @@ -25,22 +30,66 @@ authors: - family-names: "Röder" given-names: Johannes + - + given-names: gplssm + - + given-names: steffenGit - family-names: Schachler given-names: Birgit + - + given-names: cswh + - + given-names: henhuy + - + family-names: Pl + given-names: Franzi - family-names: Endres given-names: Julian + - + family-names: TU + given-names: Fabian + - + given-names: pkassing - family-names: Lancien given-names: Bryan - family-names: Kochems given-names: Johannes + - + given-names: c-koehl + - + given-names: nesnoj + - + given-names: lmilletb + - + given-names: mloenneberga - family-names: Delfs given-names: Jens-Olaf + - + given-names: RD-OTH + - + family-names: Francesco + given-names: Witte + - + given-names: elisapap + - + family-names: Gaudchau + given-names: Elisa - family-names: Smalla given-names: Tjark + - + given-names: escalacjo + - + given-names: ajimenezUCLA + - + given-names: chrisflei + - + given-names: stefansc1 + - + given-names: jakob-wo ... From c691f82b7aaeb5f7cb23456b4fb8bc1de11a3675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 4 Nov 2021 10:15:22 +0100 Subject: [PATCH 19/58] Adhere to code style --- src/oemof/solph/custom/link.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index 80e155b1f..53a78bfeb 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -146,11 +146,11 @@ def _create(self, group=None): self.LINKS = Set(initialize=[g for g in group]) self.LINK_1ST_INFLOWS = Set( - initialize=[(list(c)[0][0], n) - for n, c in all_conversions.items()]) + initialize=[(list(c)[0][0], n) for n, c in all_conversions.items()] + ) self.LINK_2ND_INFLOWS = Set( - initialize=[(list(c)[1][0], n) - for n, c in all_conversions.items()]) + initialize=[(list(c)[1][0], n) for n, c in all_conversions.items()] + ) # 0: Flows 1 connected; 1: Flows 2 connected self.direction = Var(self.LINKS, m.TIMESTEPS, within=Binary) @@ -186,12 +186,11 @@ def _input_output_relation(block): def _flow1_rule(block, i, link, t): """Rule definition for Eq. (2).""" - expr = ( - 1 >= (self.direction[link, t] - + m.flow[i, link, t] - * m.flows[i, link].max[t] - * m.flows[i, link].nominal_value - ) + expr = 1 >= ( + self.direction[link, t] + + m.flow[i, link, t] + * m.flows[i, link].max[t] + * m.flows[i, link].nominal_value ) return expr @@ -201,12 +200,11 @@ def _flow1_rule(block, i, link, t): def _flow2_rule(block, i, link, t): """Rule definition for Eq. (3).""" - expr = ( - 0 <= (self.direction[link, t] - - m.flow[i, link, t] - * m.flows[i, link].max[t] - * m.flows[i, link].nominal_value - ) + expr = 0 <= ( + self.direction[link, t] + - m.flow[i, link, t] + * m.flows[i, link].max[t] + * m.flows[i, link].nominal_value ) return expr From 973cd1e0cb4b9e3b9b37e33bc03e4a471faee762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 4 Nov 2021 10:21:25 +0100 Subject: [PATCH 20/58] Fix link documentation --- src/oemof/solph/custom/link.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index 53a78bfeb..9fcc06806 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -58,7 +58,7 @@ class Link(on.Transformer): ... outputs={bel0: solph.Flow(), bel1: solph.Flow()}, ... conversion_factors={(bel0, bel1): 0.8, (bel1, bel0): 0.9}) >>> print(sorted([x[1][5] for x in link.conversion_factors.items()])) - [0.92, 0.99] + [0.8, 0.9] >>> type(link) From 5e5d46173aeafd1a8db8fe227ce521f5c5f82a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 4 Nov 2021 10:21:37 +0100 Subject: [PATCH 21/58] Fix format of warnings doc --- tests/test_warnings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_warnings.py b/tests/test_warnings.py index 0db626223..78c833146 100644 --- a/tests/test_warnings.py +++ b/tests/test_warnings.py @@ -94,7 +94,7 @@ def test_that_the_transformer_warnings_actually_get_raised(warning_fixture): def test_storage_without_outputs(warning_fixture): - """ GenericStorage doesn't warn correctly about missing outputs.""" + """GenericStorage doesn't warn correctly about missing outputs.""" look_out = network.Bus() msg = ( "Attribute is missing in Node " @@ -109,7 +109,7 @@ def test_storage_without_outputs(warning_fixture): def test_storage_without_inputs(warning_fixture): - """ GenericStorage doesn't warn correctly about missing inputs.""" + """GenericStorage doesn't warn correctly about missing inputs.""" look_out = network.Bus() msg = ( "Attribute is missing in Node " From 0ac2c6f6428e60643f62c1db354c4e50fc632ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 4 Nov 2021 10:23:55 +0100 Subject: [PATCH 22/58] Fix order of imports in Link --- src/oemof/solph/custom/link.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index 9fcc06806..c3d4780ab 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -18,8 +18,10 @@ """ from oemof.network import network as on +from pyomo.core import Binary +from pyomo.core import Set +from pyomo.core import Var from pyomo.core.base.block import SimpleBlock -from pyomo.core import Binary, Set, Var from pyomo.environ import BuildAction from pyomo.environ import Constraint From 750163efdbbb8851c5c8f9ffd340d07a63178b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Wed, 1 Dec 2021 14:49:39 +0100 Subject: [PATCH 23/58] Update license to vanilla MIT --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 29148faa4..c700b3123 100644 --- a/LICENSE +++ b/LICENSE @@ -4,6 +4,6 @@ Copyright (c) 2014-2020, oemof developer group Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From d049faec505f9f18aad0082c93e2b68cf8a5a63f Mon Sep 17 00:00:00 2001 From: Francesco Witte Date: Thu, 2 Dec 2021 10:55:33 +0100 Subject: [PATCH 24/58] Fix links for changelog and issue tracker --- setup.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index a5eb029a7..7c86b3cea 100644 --- a/setup.py +++ b/setup.py @@ -68,11 +68,11 @@ def read(*names, **kwargs): "Topic :: Utilities", ], project_urls={ - "Documentation": "https://oemofsolph.readthedocs.io/", + "Documentation": "https://oemof-solph.readthedocs.io/", "Changelog": ( - "https://oemofsolph.readthedocs.io/en/latest/changelog.html" + "https://oemof-solph.readthedocs.io/en/latest/changelog.html" ), - "Issue Tracker": "https://github.com/uvchik/oemof.solph/issues", + "Issue Tracker": "https://github.com/oemof/oemof-solph/issues", }, keywords=[ # eg: 'keyword1', 'keyword2', 'keyword3', From fa274d20d860e0f5dcf28c88d05faedbbed8d7e3 Mon Sep 17 00:00:00 2001 From: uvchik Date: Tue, 21 Dec 2021 16:46:46 +0100 Subject: [PATCH 25/58] Try to fix readthedocs build --- pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index dc9c5ade2..bbde2c90f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,3 +17,7 @@ exclude = ''' | ci )/ ''' + +[build-system] +requires = ["setuptools<60.0", "wheel"] +build-backend = "setuptools.build_meta" From 610c20c4596498a4472c1521d4fec6453dfe5799 Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Mon, 14 Mar 2022 15:46:34 +0100 Subject: [PATCH 26/58] Fix black test failing --- src/oemof/solph/custom/sink_dsm.py | 44 +++++++------------ tests/constraint_tests.py | 4 +- .../test_piecewiselineartransformer.py | 2 +- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/oemof/solph/custom/sink_dsm.py b/src/oemof/solph/custom/sink_dsm.py index 067e74f32..b980a7ad1 100644 --- a/src/oemof/solph/custom/sink_dsm.py +++ b/src/oemof/solph/custom/sink_dsm.py @@ -2128,13 +2128,10 @@ def c2_constraint_rule(block): + self.dsm_do_shed[g, tt] ) # max capacity at tt - rhs = ( - max( - g.capacity_up[tt] * g.flex_share_up, - g.capacity_down[tt] * g.flex_share_down, - ) - * (self.invest[g] + g.investment.existing) - ) + rhs = max( + g.capacity_up[tt] * g.flex_share_up, + g.capacity_down[tt] * g.flex_share_down, + ) * (self.invest[g] + g.investment.existing) # add constraint block.C2_constraint.add((g, tt), (lhs <= rhs)) @@ -2153,13 +2150,10 @@ def c2_constraint_rule(block): + self.dsm_do_shed[g, tt] ) # max capacity at tt - rhs = ( - max( - g.capacity_up[tt] * g.flex_share_up, - g.capacity_down[tt] * g.flex_share_down, - ) - * (self.invest[g] + g.investment.existing) - ) + rhs = max( + g.capacity_up[tt] * g.flex_share_up, + g.capacity_down[tt] * g.flex_share_down, + ) * (self.invest[g] + g.investment.existing) # add constraint block.C2_constraint.add((g, tt), (lhs <= rhs)) @@ -2178,13 +2172,10 @@ def c2_constraint_rule(block): + self.dsm_do_shed[g, tt] ) # max capacity at tt - rhs = ( - max( - g.capacity_up[tt] * g.flex_share_up, - g.capacity_down[tt] * g.flex_share_down, - ) - * (self.invest[g] + g.investment.existing) - ) + rhs = max( + g.capacity_up[tt] * g.flex_share_up, + g.capacity_down[tt] * g.flex_share_down, + ) * (self.invest[g] + g.investment.existing) # add constraint block.C2_constraint.add((g, tt), (lhs <= rhs)) @@ -4218,13 +4209,10 @@ def dr_logical_constraint_rule(block): ) # maximum capacity eligibly for load shifting - rhs = ( - max( - g.capacity_down[t] * g.flex_share_down, - g.capacity_up[t] * g.flex_share_up, - ) - * (self.invest[g] + g.investment.existing) - ) + rhs = max( + g.capacity_down[t] * g.flex_share_down, + g.capacity_up[t] * g.flex_share_up, + ) * (self.invest[g] + g.investment.existing) # add constraint block.dr_logical_constraint.add((g, t), (lhs <= rhs)) diff --git a/tests/constraint_tests.py b/tests/constraint_tests.py index ed29234bf..0d3d0cc99 100644 --- a/tests/constraint_tests.py +++ b/tests/constraint_tests.py @@ -977,7 +977,7 @@ def test_piecewise_linear_transformer_cc(self): inputs={bgas: solph.Flow(nominal_value=100, variable_costs=1)}, outputs={bel: solph.Flow()}, in_breakpoints=[0, 25, 50, 75, 100], - conversion_function=lambda x: x ** 2, + conversion_function=lambda x: x**2, pw_repn="CC", ) self.compare_lp_files("piecewise_linear_transformer_cc.lp") @@ -991,7 +991,7 @@ def test_piecewise_linear_transformer_dcc(self): inputs={bgas: solph.Flow(nominal_value=100, variable_costs=1)}, outputs={bel: solph.Flow()}, in_breakpoints=[0, 25, 50, 75, 100], - conversion_function=lambda x: x ** 2, + conversion_function=lambda x: x**2, pw_repn="DCC", ) self.compare_lp_files("piecewise_linear_transformer_dcc.lp") diff --git a/tests/test_scripts/test_solph/test_piecewiselineartransformer/test_piecewiselineartransformer.py b/tests/test_scripts/test_solph/test_piecewiselineartransformer/test_piecewiselineartransformer.py index f1812bd00..12e665634 100644 --- a/tests/test_scripts/test_solph/test_piecewiselineartransformer/test_piecewiselineartransformer.py +++ b/tests/test_scripts/test_solph/test_piecewiselineartransformer/test_piecewiselineartransformer.py @@ -43,7 +43,7 @@ def test_pwltf(): # Define conversion function and breakpoints def conv_func(x): - return 0.01 * x ** 2 + return 0.01 * x**2 in_breakpoints = np.arange(0, 110, 25) out_breakpoints = conv_func(in_breakpoints) From ec9569a2be2676ce879feb849d32122c4244db8d Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Thu, 24 Feb 2022 11:57:10 +0100 Subject: [PATCH 27/58] Add option `exclude_attrs` to processing.parameter_as_dict() to filter checked attributes --- src/oemof/solph/processing.py | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/oemof/solph/processing.py b/src/oemof/solph/processing.py index 679a9ae7d..b8ecc2b4d 100644 --- a/src/oemof/solph/processing.py +++ b/src/oemof/solph/processing.py @@ -242,7 +242,9 @@ def meta_results(om, undefined=False): return meta_res -def __separate_attrs(system, get_flows=False, exclude_none=True): +def __separate_attrs( + system, exclude_attrs, get_flows=False, exclude_none=True +): """ Create a dictionary with flow scalars and series. @@ -251,7 +253,15 @@ def __separate_attrs(system, get_flows=False, exclude_none=True): {(node1, node2): {'scalars': {'attr1': scalar, 'attr2': 'text'}, 'sequences': {'attr1': iterable, 'attr2': iterable}}} - om : A solved oemof.solph.Model. + system: + A solved oemof.solph.Model or oemof.solph.Energysystem + exclude_attrs: List[str] + Optional list of additional attributes which shall be excluded from + parameter dict + get_flows: bool + Whether to include flow values or not + exclude_none: bool + If set, scalars and sequences containing None values are excluded Returns ------- @@ -261,7 +271,7 @@ def __separate_attrs(system, get_flows=False, exclude_none=True): def detect_scalars_and_sequences(com): com_data = {"scalars": {}, "sequences": {}} - exclusions = ( + default_exclusions = [ "__", "_", "registry", @@ -273,7 +283,9 @@ def detect_scalars_and_sequences(com): "input", "output", "constraint_group", - ) + ] + # Must be tuple in order to work with `str.startswith()`: + exclusions = tuple(default_exclusions + exclude_attrs) attrs = [ i for i in dir(com) @@ -372,7 +384,7 @@ def remove_nones(com): return data -def parameter_as_dict(system, exclude_none=True): +def parameter_as_dict(system, exclude_none=True, exclude_attrs=None): """ Create a result dictionary containing node parameters. @@ -388,14 +400,23 @@ def parameter_as_dict(system, exclude_none=True): A populated energy system. exclude_none: bool If True, all scalars and sequences containing None values are excluded + exclude_attrs: Optional[List[str]] + Optional list of additional attributes which shall be excluded from + parameter dict Returns ------- dict: Parameters for all nodes and flows """ - flow_data = __separate_attrs(system, True, exclude_none) - node_data = __separate_attrs(system, False, exclude_none) + exclude_attrs = exclude_attrs or [] + + flow_data = __separate_attrs( + system, exclude_attrs, get_flows=True, exclude_none=exclude_none + ) + node_data = __separate_attrs( + system, exclude_attrs, get_flows=False, exclude_none=exclude_none + ) flow_data.update(node_data) return flow_data From fe26015424e2b9c162d1ac08330ea58a9fb9c665 Mon Sep 17 00:00:00 2001 From: henhuy Date: Thu, 3 Mar 2022 09:18:56 +0100 Subject: [PATCH 28/58] Initialized exclude_attrs in __separate_attrs function --- src/oemof/solph/processing.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/oemof/solph/processing.py b/src/oemof/solph/processing.py index b8ecc2b4d..2a2b77856 100644 --- a/src/oemof/solph/processing.py +++ b/src/oemof/solph/processing.py @@ -243,7 +243,7 @@ def meta_results(om, undefined=False): def __separate_attrs( - system, exclude_attrs, get_flows=False, exclude_none=True + system, exclude_attrs=None, get_flows=False, exclude_none=True ): """ Create a dictionary with flow scalars and series. @@ -368,6 +368,8 @@ def remove_nones(com): for ckey, value in list(com["sequences"].items()): if len(value) == 0 or value[0] is None: del com["sequences"][ckey] + + exclude_attrs = exclude_attrs or [] # Check if system is es or om: if system.__class__.__name__ == "EnergySystem": From fe39f4bd01195c5468a35a9959c78a4c8555b448 Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Thu, 3 Mar 2022 09:22:45 +0100 Subject: [PATCH 29/58] Fixed PEP8 W293 --- src/oemof/solph/processing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oemof/solph/processing.py b/src/oemof/solph/processing.py index 2a2b77856..191d666af 100644 --- a/src/oemof/solph/processing.py +++ b/src/oemof/solph/processing.py @@ -368,7 +368,7 @@ def remove_nones(com): for ckey, value in list(com["sequences"].items()): if len(value) == 0 or value[0] is None: del com["sequences"][ckey] - + exclude_attrs = exclude_attrs or [] # Check if system is es or om: From b4df134102ff41c13bf2cf67fd2e4199914adaec Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Thu, 3 Mar 2022 09:45:13 +0100 Subject: [PATCH 30/58] Minor change --- src/oemof/solph/processing.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/oemof/solph/processing.py b/src/oemof/solph/processing.py index 191d666af..9c643a6a7 100644 --- a/src/oemof/solph/processing.py +++ b/src/oemof/solph/processing.py @@ -369,7 +369,8 @@ def remove_nones(com): if len(value) == 0 or value[0] is None: del com["sequences"][ckey] - exclude_attrs = exclude_attrs or [] + if exclude_attrs is None: + exclude_attrs = [] # Check if system is es or om: if system.__class__.__name__ == "EnergySystem": @@ -411,7 +412,8 @@ def parameter_as_dict(system, exclude_none=True, exclude_attrs=None): dict: Parameters for all nodes and flows """ - exclude_attrs = exclude_attrs or [] + if exclude_attrs is None: + exclude_attrs = [] flow_data = __separate_attrs( system, exclude_attrs, get_flows=True, exclude_none=exclude_none From 94d3c33634d09bbeb85764bbf9bb1e13c27a2937 Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Mon, 14 Mar 2022 15:43:40 +0100 Subject: [PATCH 31/58] Added test for excluding attrs in processing.parameter_as_dict function --- tests/test_processing.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_processing.py b/tests/test_processing.py index 6914267fb..9e7642dc1 100644 --- a/tests/test_processing.py +++ b/tests/test_processing.py @@ -238,6 +238,21 @@ def test_nodes_without_none_exclusion(self): param_results[(diesel, None)]["sequences"], pandas.DataFrame() ) + def test_nodes_with_excluded_attrs(self): + diesel = self.es.groups["diesel"] + param_results = processing.parameter_as_dict(self.es, exclude_attrs=["conversion_factors"]) + assert_series_equal( + param_results[(diesel, None)]["scalars"], + pandas.Series( + { + "label": "diesel", + } + ), + ) + assert_frame_equal( + param_results[(diesel, None)]["sequences"], pandas.DataFrame() + ) + def test_parameter_with_node_view(self): param_results = processing.parameter_as_dict( self.es, exclude_none=True From 5a9143813a50650f81ac176ee19c03b2a3b0df32 Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Thu, 24 Feb 2022 11:21:07 +0100 Subject: [PATCH 32/58] Fixed check for callables in processing.parameter_as_dict() --- src/oemof/solph/processing.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/oemof/solph/processing.py b/src/oemof/solph/processing.py index 679a9ae7d..0bcfde447 100644 --- a/src/oemof/solph/processing.py +++ b/src/oemof/solph/processing.py @@ -267,9 +267,7 @@ def detect_scalars_and_sequences(com): "registry", "inputs", "outputs", - "register", "Label", - "from_object", "input", "output", "constraint_group", @@ -277,7 +275,7 @@ def detect_scalars_and_sequences(com): attrs = [ i for i in dir(com) - if not (callable(i) or i.startswith(exclusions)) + if not (callable(getattr(com, i)) or i.startswith(exclusions)) ] for a in attrs: From 200e16253537486761f6f1e9ab63af2972adca75 Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Mon, 14 Mar 2022 16:26:32 +0100 Subject: [PATCH 33/58] Minor change --- tests/test_processing.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_processing.py b/tests/test_processing.py index 9e7642dc1..eeec0c296 100644 --- a/tests/test_processing.py +++ b/tests/test_processing.py @@ -240,7 +240,9 @@ def test_nodes_without_none_exclusion(self): def test_nodes_with_excluded_attrs(self): diesel = self.es.groups["diesel"] - param_results = processing.parameter_as_dict(self.es, exclude_attrs=["conversion_factors"]) + param_results = processing.parameter_as_dict( + self.es, exclude_attrs=["conversion_factors"] + ) assert_series_equal( param_results[(diesel, None)]["scalars"], pandas.Series( From 80cb9860a588730548ed9f0ef42871ebcc385ae9 Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Mon, 14 Mar 2022 16:34:31 +0100 Subject: [PATCH 34/58] Removed optionality of parameter in private function __seperate_attrs --- src/oemof/solph/processing.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/oemof/solph/processing.py b/src/oemof/solph/processing.py index 9c643a6a7..06983609f 100644 --- a/src/oemof/solph/processing.py +++ b/src/oemof/solph/processing.py @@ -243,7 +243,7 @@ def meta_results(om, undefined=False): def __separate_attrs( - system, exclude_attrs=None, get_flows=False, exclude_none=True + system, exclude_attrs, get_flows=False, exclude_none=True ): """ Create a dictionary with flow scalars and series. @@ -256,7 +256,7 @@ def __separate_attrs( system: A solved oemof.solph.Model or oemof.solph.Energysystem exclude_attrs: List[str] - Optional list of additional attributes which shall be excluded from + List of additional attributes which shall be excluded from parameter dict get_flows: bool Whether to include flow values or not @@ -369,9 +369,6 @@ def remove_nones(com): if len(value) == 0 or value[0] is None: del com["sequences"][ckey] - if exclude_attrs is None: - exclude_attrs = [] - # Check if system is es or om: if system.__class__.__name__ == "EnergySystem": components = system.flows() if get_flows else system.nodes From e7de9030f5aca0f0b787d122d9a04abe743a4dbc Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Fri, 25 Mar 2022 11:23:03 +0100 Subject: [PATCH 35/58] Refactored assertion error in Link component into suspicious warning --- src/oemof/solph/custom/link.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index c3d4780ab..3905b260c 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -16,7 +16,9 @@ SPDX-License-Identifier: MIT """ +from warnings import warn +from oemof.tools import debugging from oemof.network import network as on from pyomo.core import Binary from pyomo.core import Set @@ -80,14 +82,21 @@ def __init__(self, *args, **kwargs): for k, v in kwargs.get("conversion_factors", {}).items() } - wrong_args_message = ( - "Component `Link` must have exactly" - + "2 inputs, 2 outputs, and 2" - + "conversion factors connecting these." + msg = ( + "Component `Link` should have exactly " + + "2 inputs, 2 outputs, and 2 " + + "conversion factors connecting these. You are initializing " + + "a `Link`without obeying this specification. " + + "If this is intended and you know what you are doing you can " + + "disable the SuspiciousUsageWarning globally." ) - assert len(self.inputs) == 2, wrong_args_message - assert len(self.outputs) == 2, wrong_args_message - assert len(self.conversion_factors) == 2, wrong_args_message + + if ( + len(self.inputs) != 2 + or len(self.outputs) != 2 + or len(self.conversion_factors) != 2 + ): + warn(msg, debugging.SuspiciousUsageWarning) def constraint_group(self): return LinkBlock From d2e58336c6ab730bd29d5ed79bc8dcd722380794 Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Fri, 25 Mar 2022 11:31:54 +0100 Subject: [PATCH 36/58] Fixed import order --- src/oemof/solph/custom/link.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index 3905b260c..0fc301a78 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -18,8 +18,8 @@ """ from warnings import warn -from oemof.tools import debugging from oemof.network import network as on +from oemof.tools import debugging from pyomo.core import Binary from pyomo.core import Set from pyomo.core import Var From 0514de6f40595c1d98a5f19d96da96d57abc8892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 5 Apr 2022 20:58:56 +0200 Subject: [PATCH 37/58] Add installation of conda using cbc to readme The part about installing solvers is already pretty exhaustive, so I kept this extra info rather short. In particular, there is no information about conda. I assume that people know enough about it or look at other sources if they want to use conda. Implements #835 --- README.rst | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f2690e2d3..37cbf7910 100644 --- a/README.rst +++ b/README.rst @@ -179,6 +179,16 @@ GLPK-solver: http://arnab-deka.com/posts/2010/02/installing-glpk-on-a-mac/ If you install the CBC solver via brew (highly recommended), it should work without additional configuration. +**conda** + +The CBC-solver can also be installed in a `conda` environment. Please note, that it is highly recomended to `use pip after conda `_, so: + +.. code:: console + + conda install -c conda-forge coincbc + pip install oemof.solph + + .. _check_installation_label: Installation test @@ -245,7 +255,7 @@ You are welcome to contribute your own examples via a `pull request Date: Mon, 11 Apr 2022 14:22:56 +0200 Subject: [PATCH 38/58] Added option to (un-)limit directions in Link component --- src/oemof/solph/custom/link.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index c3d4780ab..3eb62d01e 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -38,6 +38,8 @@ class Link(on.Transformer): Keys are the connected tuples (input, output) bus objects. The dictionary values can either be a scalar or an iterable with length of time horizon for simulation. + limit_direction : boolean, default: True + Wether direction constraint should be set for Link component Note: This component is experimental. Use it with care. @@ -79,6 +81,7 @@ def __init__(self, *args, **kwargs): k: sequence(v) for k, v in kwargs.get("conversion_factors", {}).items() } + self.limit_direction = kwargs.get("limit_direction", True) wrong_args_message = ( "Component `Link` must have exactly" @@ -100,6 +103,7 @@ class LinkBlock(SimpleBlock): Note: This component is experimental. Use it with care. **The following constraints are created:** + (Equation 2&3 are only implemented, if `limit_direction` is enabled) .. _Link-equations: @@ -147,11 +151,15 @@ def _create(self, group=None): } self.LINKS = Set(initialize=[g for g in group]) + + directed_conversions = { + n: n.conversion_factors for n in group if n.limit_direction + } self.LINK_1ST_INFLOWS = Set( - initialize=[(list(c)[0][0], n) for n, c in all_conversions.items()] + initialize=[(list(c)[0][0], n) for n, c in directed_conversions.items()] ) self.LINK_2ND_INFLOWS = Set( - initialize=[(list(c)[1][0], n) for n, c in all_conversions.items()] + initialize=[(list(c)[1][0], n) for n, c in directed_conversions.items()] ) # 0: Flows 1 connected; 1: Flows 2 connected From a0ec8c7d05aab2b8f2e05e9c8b45f6395c028212 Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Mon, 11 Apr 2022 16:36:55 +0200 Subject: [PATCH 39/58] Fixed flake8 error --- src/oemof/solph/custom/link.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index 3eb62d01e..f5c73c281 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -156,10 +156,14 @@ def _create(self, group=None): n: n.conversion_factors for n in group if n.limit_direction } self.LINK_1ST_INFLOWS = Set( - initialize=[(list(c)[0][0], n) for n, c in directed_conversions.items()] + initialize=[ + (list(c)[0][0], n) for n, c in directed_conversions.items() + ] ) self.LINK_2ND_INFLOWS = Set( - initialize=[(list(c)[1][0], n) for n, c in directed_conversions.items()] + initialize=[ + (list(c)[1][0], n) for n, c in directed_conversions.items() + ] ) # 0: Flows 1 connected; 1: Flows 2 connected From 2ae97cb241f8a741ea1446ec9d6822d58989a8d7 Mon Sep 17 00:00:00 2001 From: jnnr <32454596+jnnr@users.noreply.github.com> Date: Thu, 24 Nov 2022 11:33:16 +0100 Subject: [PATCH 40/58] Remove limit_direction and related constraints --- src/oemof/solph/custom/link.py | 57 ---------------------------------- 1 file changed, 57 deletions(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index eca9f0e0d..4d3a75297 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -40,8 +40,6 @@ class Link(on.Transformer): Keys are the connected tuples (input, output) bus objects. The dictionary values can either be a scalar or an iterable with length of time horizon for simulation. - limit_direction : boolean, default: True - Wether direction constraint should be set for Link component Note: This component is experimental. Use it with care. @@ -83,7 +81,6 @@ def __init__(self, *args, **kwargs): k: sequence(v) for k, v in kwargs.get("conversion_factors", {}).items() } - self.limit_direction = kwargs.get("limit_direction", True) msg = ( "Component `Link` should have exactly " @@ -112,7 +109,6 @@ class LinkBlock(SimpleBlock): Note: This component is experimental. Use it with care. **The following constraints are created:** - (Equation 2&3 are only implemented, if `limit_direction` is enabled) .. _Link-equations: @@ -121,14 +117,6 @@ class LinkBlock(SimpleBlock): (1) \qquad P_{\mathrm{in},n}(t) = c_n(t) \times P_{\mathrm{out},n}(t) \quad \forall t \in T, \forall n in {1,2} \\ & - (2) \qquad 1 \ge \hat{S} + P_{\mathrm{in},1}(t) - / P_{\mathrm{in},1,\mathrm{max}} - \quad \forall t \in T \\ - & - (3) \qquad 0 \le \hat{S} - P_{\mathrm{in},2}(t) - / P_{2\mathrm{in},2,\mathrm{max}} - \quad \forall t \in T \\ - & """ CONSTRAINT_GROUP = True @@ -161,23 +149,6 @@ def _create(self, group=None): self.LINKS = Set(initialize=[g for g in group]) - directed_conversions = { - n: n.conversion_factors for n in group if n.limit_direction - } - self.LINK_1ST_INFLOWS = Set( - initialize=[ - (list(c)[0][0], n) for n, c in directed_conversions.items() - ] - ) - self.LINK_2ND_INFLOWS = Set( - initialize=[ - (list(c)[1][0], n) for n, c in directed_conversions.items() - ] - ) - - # 0: Flows 1 connected; 1: Flows 2 connected - self.direction = Var(self.LINKS, m.TIMESTEPS, within=Binary) - def _input_output_relation(block): for t in m.TIMESTEPS: for n, conversion in all_conversions.items(): @@ -206,31 +177,3 @@ def _input_output_relation(block): noruleinit=True, ) self.relation_build = BuildAction(rule=_input_output_relation) - - def _flow1_rule(block, i, link, t): - """Rule definition for Eq. (2).""" - expr = 1 >= ( - self.direction[link, t] - + m.flow[i, link, t] - * m.flows[i, link].max[t] - * m.flows[i, link].nominal_value - ) - return expr - - self.flow1 = Constraint( - self.LINK_1ST_INFLOWS, m.TIMESTEPS, rule=_flow1_rule - ) - - def _flow2_rule(block, i, link, t): - """Rule definition for Eq. (3).""" - expr = 0 <= ( - self.direction[link, t] - - m.flow[i, link, t] - * m.flows[i, link].max[t] - * m.flows[i, link].nominal_value - ) - return expr - - self.flow2 = Constraint( - self.LINK_2ND_INFLOWS, m.TIMESTEPS, rule=_flow2_rule - ) From e98bd8a7488eefc7c598d682a760ccb62b1c3bf2 Mon Sep 17 00:00:00 2001 From: jnnr <32454596+jnnr@users.noreply.github.com> Date: Thu, 24 Nov 2022 11:46:24 +0100 Subject: [PATCH 41/58] Add constraint test for link --- tests/constraint_tests.py | 22 ++++++++++ tests/lp_files/link.lp | 85 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 tests/lp_files/link.lp diff --git a/tests/constraint_tests.py b/tests/constraint_tests.py index 0d3d0cc99..120bb329a 100644 --- a/tests/constraint_tests.py +++ b/tests/constraint_tests.py @@ -593,6 +593,28 @@ def test_linear_transformer_chp_invest(self): self.compare_lp_files("linear_transformer_chp_invest.lp") + def test_link(self): + bel0 = solph.Bus(label="bel0") + bel1 = solph.Bus(label="bel1") + + solph.custom.Link( + label="link", + inputs={ + bel0: solph.Flow(nominal_value=4), + bel1: solph.Flow(nominal_value=2) + }, + outputs={ + bel0: solph.Flow(), + bel1: solph.Flow() + }, + conversion_factors={ + (bel0, bel1): 0.8, + (bel1, bel0): 0.9 + } + ) + + self.compare_lp_files("link.lp") + def test_variable_chp(self): """ """ bel = solph.Bus(label="electricityBus") diff --git a/tests/lp_files/link.lp b/tests/lp_files/link.lp new file mode 100644 index 000000000..d3b8de49e --- /dev/null +++ b/tests/lp_files/link.lp @@ -0,0 +1,85 @@ +\* Source Pyomo model name=Model *\ + +min +objective: ++0 ONE_VAR_CONSTANT + +s.t. + +c_e_Bus_balance(bel0_0)_: +-1 flow(bel0_link_0) ++1 flow(link_bel0_0) += 0 + +c_e_Bus_balance(bel0_1)_: +-1 flow(bel0_link_1) ++1 flow(link_bel0_1) += 0 + +c_e_Bus_balance(bel0_2)_: +-1 flow(bel0_link_2) ++1 flow(link_bel0_2) += 0 + +c_e_Bus_balance(bel1_0)_: +-1 flow(bel1_link_0) ++1 flow(link_bel1_0) += 0 + +c_e_Bus_balance(bel1_1)_: +-1 flow(bel1_link_1) ++1 flow(link_bel1_1) += 0 + +c_e_Bus_balance(bel1_2)_: +-1 flow(bel1_link_2) ++1 flow(link_bel1_2) += 0 + +c_e_LinkBlock_relation(link_bel0_bel1_0)_: +-0.80000000000000004 flow(bel0_link_0) ++1 flow(link_bel1_0) += 0 + +c_e_LinkBlock_relation(link_bel0_bel1_1)_: +-0.80000000000000004 flow(bel0_link_1) ++1 flow(link_bel1_1) += 0 + +c_e_LinkBlock_relation(link_bel0_bel1_2)_: +-0.80000000000000004 flow(bel0_link_2) ++1 flow(link_bel1_2) += 0 + +c_e_LinkBlock_relation(link_bel1_bel0_0)_: +-0.90000000000000002 flow(bel1_link_0) ++1 flow(link_bel0_0) += 0 + +c_e_LinkBlock_relation(link_bel1_bel0_1)_: +-0.90000000000000002 flow(bel1_link_1) ++1 flow(link_bel0_1) += 0 + +c_e_LinkBlock_relation(link_bel1_bel0_2)_: +-0.90000000000000002 flow(bel1_link_2) ++1 flow(link_bel0_2) += 0 + +c_e_ONE_VAR_CONSTANT: +ONE_VAR_CONSTANT = 1.0 + +bounds + 0 <= flow(bel0_link_0) <= 4 + 0 <= flow(bel0_link_1) <= 4 + 0 <= flow(bel0_link_2) <= 4 + 0 <= flow(bel1_link_0) <= 2 + 0 <= flow(bel1_link_1) <= 2 + 0 <= flow(bel1_link_2) <= 2 + 0 <= flow(link_bel0_0) <= +inf + 0 <= flow(link_bel0_1) <= +inf + 0 <= flow(link_bel0_2) <= +inf + 0 <= flow(link_bel1_0) <= +inf + 0 <= flow(link_bel1_1) <= +inf + 0 <= flow(link_bel1_2) <= +inf +end From c824de244d56e8bc18b723dc6666667223959363 Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Thu, 8 Dec 2022 16:05:40 +0100 Subject: [PATCH 42/58] Fixed flake8 error --- src/oemof/solph/custom/link.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/oemof/solph/custom/link.py b/src/oemof/solph/custom/link.py index 4d3a75297..69ae0fd9b 100644 --- a/src/oemof/solph/custom/link.py +++ b/src/oemof/solph/custom/link.py @@ -20,9 +20,7 @@ from oemof.network import network as on from oemof.tools import debugging -from pyomo.core import Binary from pyomo.core import Set -from pyomo.core import Var from pyomo.core.base.block import SimpleBlock from pyomo.environ import BuildAction from pyomo.environ import Constraint From 8de147ec26d644e92b242eca983c7fb1b7b3428c Mon Sep 17 00:00:00 2001 From: "RL-INSTITUT\\hendrik.huyskens" Date: Thu, 8 Dec 2022 16:27:59 +0100 Subject: [PATCH 43/58] Fixed links in docs --- CONTRIBUTING.rst | 2 +- docs/whatsnew/v0-3-0.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 5767d3a71..d6b6df763 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -51,7 +51,7 @@ To set up `oemof-solph` for local development: Now you can make your changes locally. -4. When you're done making changes run all the checks and docs builder with `tox `_ one command:: +4. When you're done making changes run all the checks and docs builder with `tox `_ one command:: tox diff --git a/docs/whatsnew/v0-3-0.rst b/docs/whatsnew/v0-3-0.rst index 82029a075..7ada07035 100644 --- a/docs/whatsnew/v0-3-0.rst +++ b/docs/whatsnew/v0-3-0.rst @@ -56,7 +56,7 @@ New features signals. The first supported signal gets emitted, whenever a `node ` is `added ` to an `energy system `. - (`blinker `_) + (`blinker `_) Documentation From 38f6ac941f54a1b2c24f9d81b646e257bd78e474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 8 Dec 2022 21:26:57 +0100 Subject: [PATCH 44/58] Add missing dependency for tox (py) --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index 79a4ca309..a20107d7d 100644 --- a/tox.ini +++ b/tox.ini @@ -25,6 +25,7 @@ setenv = passenv = * deps = + py pytest pytest-travis-fold commands = From 596cf402169272e6f7c4759081af4f0257d886f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 8 Dec 2022 21:28:09 +0100 Subject: [PATCH 45/58] Adhere to Black --- tests/constraint_tests.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/tests/constraint_tests.py b/tests/constraint_tests.py index 120bb329a..dacc50c44 100644 --- a/tests/constraint_tests.py +++ b/tests/constraint_tests.py @@ -601,16 +601,10 @@ def test_link(self): label="link", inputs={ bel0: solph.Flow(nominal_value=4), - bel1: solph.Flow(nominal_value=2) + bel1: solph.Flow(nominal_value=2), }, - outputs={ - bel0: solph.Flow(), - bel1: solph.Flow() - }, - conversion_factors={ - (bel0, bel1): 0.8, - (bel1, bel0): 0.9 - } + outputs={bel0: solph.Flow(), bel1: solph.Flow()}, + conversion_factors={(bel0, bel1): 0.8, (bel1, bel0): 0.9}, ) self.compare_lp_files("link.lp") From 0b6e902657c16bbc22107ee1c3ddf0d93fed1eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Mon, 26 Sep 2022 18:05:57 +0200 Subject: [PATCH 46/58] Cherry pick removal of Node from constraint tests --- tests/constraint_tests.py | 641 ++++++++++++++++++++++---------------- 1 file changed, 380 insertions(+), 261 deletions(-) diff --git a/tests/constraint_tests.py b/tests/constraint_tests.py index dacc50c44..990103f04 100644 --- a/tests/constraint_tests.py +++ b/tests/constraint_tests.py @@ -41,7 +41,6 @@ def setup(self): self.energysystem = solph.EnergySystem( groupings=solph.GROUPINGS, timeindex=self.date_time_index ) - Node.registry = self.energysystem def get_om(self): return solph.Model( @@ -142,100 +141,119 @@ def normalize_to_positive_results(lines): def test_linear_transformer(self): """Constraint test of a Transformer without Investment.""" - bgas = solph.Bus(label="gas") + bgas = solph.buses.Bus(label="gas") - bel = solph.Bus(label="electricity") + bel = solph.buses.Bus(label="electricity") - solph.Transformer( + transformer = solph.components.Transformer( label="powerplantGas", - inputs={bgas: solph.Flow()}, - outputs={bel: solph.Flow(nominal_value=10e10, variable_costs=50)}, + inputs={bgas: solph.flows.Flow()}, + outputs={ + bel: solph.flows.Flow(nominal_value=10e10, variable_costs=50) + }, conversion_factors={bel: 0.58}, ) + self.energysystem.add(bgas, bel, transformer) self.compare_lp_files("linear_transformer.lp") def test_linear_transformer_invest(self): """Constraint test of a Transformer with Investment.""" - bgas = solph.Bus(label="gas") + bgas = solph.buses.Bus(label="gas") - bel = solph.Bus(label="electricity") + bel = solph.buses.Bus(label="electricity") - solph.Transformer( + transformer = solph.components.Transformer( label="powerplant_gas", - inputs={bgas: solph.Flow()}, + inputs={bgas: solph.flows.Flow()}, outputs={ - bel: solph.Flow( + bel: solph.flows.Flow( variable_costs=50, investment=solph.Investment(maximum=1000, ep_costs=20), ) }, conversion_factors={bel: 0.58}, ) + self.energysystem.add(bgas, bel, transformer) self.compare_lp_files("linear_transformer_invest.lp") def test_max_source_min_sink(self): """ """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.Source( + wind = solph.components.Source( label="wind", outputs={ - bel: solph.Flow(nominal_value=54, max=(0.85, 0.95, 0.61)) + bel: solph.flows.Flow(nominal_value=54, max=(0.85, 0.95, 0.61)) }, ) - solph.Sink( + demand = solph.components.Sink( label="minDemand", inputs={ - bel: solph.Flow( + bel: solph.flows.Flow( nominal_value=54, min=(0.84, 0.94, 0.59), variable_costs=14 ) }, ) + self.energysystem.add(bel, wind, demand) self.compare_lp_files("max_source_min_sink.lp") def test_fixed_source_variable_sink(self): """Constraint test with a fixed source and a variable sink.""" - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.Source( + wind = solph.components.Source( label="wind", outputs={ - bel: solph.Flow(fix=[0.43, 0.72, 0.29], nominal_value=10e5) + bel: solph.flows.Flow( + fix=[0.43, 0.72, 0.29], nominal_value=10e5 + ) }, ) - solph.Sink(label="excess", inputs={bel: solph.Flow(variable_costs=40)}) + excess = solph.components.Sink( + label="excess", inputs={bel: solph.flows.Flow(variable_costs=40)} + ) + + self.energysystem.add(bel, wind, excess) self.compare_lp_files("fixed_source_variable_sink.lp") def test_nominal_value_to_zero(self): """If the nominal value is set to zero nothing should happen.""" - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.Source(label="s1", outputs={bel: solph.Flow(nominal_value=0)}) + s1 = solph.components.Source( + label="s1", outputs={bel: solph.flows.Flow(nominal_value=0)} + ) + self.energysystem.add(bel, s1) self.compare_lp_files("nominal_value_to_zero.lp") def test_fixed_source_invest_sink(self): - """Wrong constraints for fixed source + invest sink w. `summed_max`.""" + """ + Wrong constraints for fixed source + invest sink w. + `full_load_time_max`. + """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.Source( + wind = solph.components.Source( label="wind", - outputs={bel: solph.Flow(fix=[12, 16, 14], nominal_value=1000000)}, + outputs={ + bel: solph.flows.Flow(fix=[12, 16, 14], nominal_value=1000000) + }, ) - solph.Sink( + excess = solph.components.Sink( label="excess", inputs={ - bel: solph.Flow( - summed_max=2.3, + bel: solph.flows.Flow( + full_load_time_max=2.3, variable_costs=25, max=0.8, investment=solph.Investment( @@ -244,18 +262,19 @@ def test_fixed_source_invest_sink(self): ) }, ) + self.energysystem.add(bel, wind, excess) self.compare_lp_files("fixed_source_invest_sink.lp") def test_invest_source_fixed_sink(self): """Constraint test with a fixed sink and a dispatch invest source.""" - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.Source( + pv = solph.components.Source( label="pv", outputs={ - bel: solph.Flow( + bel: solph.flows.Flow( max=[45, 83, 65], variable_costs=13, investment=solph.Investment(ep_costs=123), @@ -263,27 +282,35 @@ def test_invest_source_fixed_sink(self): }, ) - solph.Sink( + excess = solph.components.Sink( label="excess", - inputs={bel: solph.Flow(fix=[0.5, 0.8, 0.3], nominal_value=10e4)}, + inputs={ + bel: solph.flows.Flow(fix=[0.5, 0.8, 0.3], nominal_value=10e4) + }, ) + self.energysystem.add(bel, pv, excess) self.compare_lp_files("invest_source_fixed_sink.lp") def test_storage(self): """ """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage_no_invest", - inputs={bel: solph.Flow(nominal_value=16667, variable_costs=56)}, - outputs={bel: solph.Flow(nominal_value=16667, variable_costs=24)}, + inputs={ + bel: solph.flows.Flow(nominal_value=16667, variable_costs=56) + }, + outputs={ + bel: solph.flows.Flow(nominal_value=16667, variable_costs=24) + }, nominal_storage_capacity=10e4, loss_rate=0.13, inflow_conversion_factor=0.97, outflow_conversion_factor=0.86, initial_storage_level=0.4, ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage.lp") @@ -291,12 +318,12 @@ def test_storage_invest_1(self): """All invest variables are coupled. The invest variables of the Flows will be created during the initialisation of the storage e.g. battery """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage1", - inputs={bel: solph.Flow(variable_costs=56)}, - outputs={bel: solph.Flow(variable_costs=24)}, + inputs={bel: solph.flows.Flow(variable_costs=56)}, + outputs={bel: solph.flows.Flow(variable_costs=24)}, nominal_storage_capacity=None, loss_rate=0.13, max_storage_level=0.9, @@ -307,20 +334,26 @@ def test_storage_invest_1(self): outflow_conversion_factor=0.86, investment=solph.Investment(ep_costs=145, maximum=234), ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_invest_1.lp") def test_storage_invest_2(self): """All can be free extended to their own cost.""" - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage2", - inputs={bel: solph.Flow(investment=solph.Investment(ep_costs=99))}, - outputs={bel: solph.Flow(investment=solph.Investment(ep_costs=9))}, + inputs={ + bel: solph.flows.Flow(investment=solph.Investment(ep_costs=99)) + }, + outputs={ + bel: solph.flows.Flow(investment=solph.Investment(ep_costs=9)) + }, investment=solph.Investment(ep_costs=145), initial_storage_level=0.5, ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_invest_2.lp") def test_storage_invest_3(self): @@ -328,26 +361,32 @@ def test_storage_invest_3(self): e.g. PHES with a fixed basin but the pump and the turbine can be adapted """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage3", - inputs={bel: solph.Flow(investment=solph.Investment(ep_costs=99))}, - outputs={bel: solph.Flow(investment=solph.Investment(ep_costs=9))}, + inputs={ + bel: solph.flows.Flow(investment=solph.Investment(ep_costs=99)) + }, + outputs={ + bel: solph.flows.Flow(investment=solph.Investment(ep_costs=9)) + }, nominal_storage_capacity=5000, ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_invest_3.lp") def test_storage_invest_4(self): """Only the storage capacity can be extended.""" - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage4", - inputs={bel: solph.Flow(nominal_value=80)}, - outputs={bel: solph.Flow(nominal_value=100)}, + inputs={bel: solph.flows.Flow(nominal_value=80)}, + outputs={bel: solph.flows.Flow(nominal_value=100)}, investment=solph.Investment(ep_costs=145, maximum=500), ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_invest_4.lp") def test_storage_invest_5(self): @@ -356,85 +395,93 @@ def test_storage_invest_5(self): adapted. The installed capacity of the pump is 10 % bigger than the the capacity of the turbine due to 'invest_relation_input_output=1.1'. """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage5", inputs={ - bel: solph.Flow( + bel: solph.flows.Flow( investment=solph.Investment(ep_costs=99, existing=110) ) }, outputs={ - bel: solph.Flow(investment=solph.Investment(existing=100)) + bel: solph.flows.Flow( + investment=solph.Investment(existing=100) + ) }, invest_relation_input_output=1.1, nominal_storage_capacity=10000, ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_invest_5.lp") def test_storage_invest_6(self): """Like test_storage_invest_5 but there can also be an investment in the basin. """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage6", inputs={ - bel: solph.Flow( + bel: solph.flows.Flow( investment=solph.Investment(ep_costs=99, existing=110) ) }, outputs={ - bel: solph.Flow(investment=solph.Investment(existing=100)) + bel: solph.flows.Flow( + investment=solph.Investment(existing=100) + ) }, invest_relation_input_output=1.1, investment=solph.Investment(ep_costs=145, existing=10000), ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_invest_6.lp") def test_storage_minimum_invest(self): """All invest variables are coupled. The invest variables of the Flows will be created during the initialisation of the storage e.g. battery """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage1", - inputs={bel: solph.Flow()}, - outputs={bel: solph.Flow()}, + inputs={bel: solph.flows.Flow()}, + outputs={bel: solph.flows.Flow()}, investment=solph.Investment( ep_costs=145, minimum=100, maximum=200 ), ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_invest_minimum.lp") def test_storage_unbalanced(self): """Testing a unbalanced storage (e.g. battery).""" - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage1", - inputs={bel: solph.Flow()}, - outputs={bel: solph.Flow()}, + inputs={bel: solph.flows.Flow()}, + outputs={bel: solph.flows.Flow()}, nominal_storage_capacity=1111, initial_storage_level=None, balanced=False, invest_relation_input_capacity=1, invest_relation_output_capacity=1, ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_unbalanced.lp") def test_storage_invest_unbalanced(self): """Testing a unbalanced storage (e.g. battery).""" - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage1", - inputs={bel: solph.Flow()}, - outputs={bel: solph.Flow()}, + inputs={bel: solph.flows.Flow()}, + outputs={bel: solph.flows.Flow()}, nominal_storage_capacity=None, initial_storage_level=0.5, balanced=False, @@ -442,16 +489,21 @@ def test_storage_invest_unbalanced(self): invest_relation_output_capacity=1, investment=solph.Investment(ep_costs=145), ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_invest_unbalanced.lp") def test_storage_fixed_losses(self): """ """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage_no_invest", - inputs={bel: solph.Flow(nominal_value=16667, variable_costs=56)}, - outputs={bel: solph.Flow(nominal_value=16667, variable_costs=24)}, + inputs={ + bel: solph.flows.Flow(nominal_value=16667, variable_costs=56) + }, + outputs={ + bel: solph.flows.Flow(nominal_value=16667, variable_costs=24) + }, nominal_storage_capacity=1e5, loss_rate=0.13, fixed_losses_relative=0.01, @@ -460,6 +512,7 @@ def test_storage_fixed_losses(self): outflow_conversion_factor=0.86, initial_storage_level=0.4, ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_fixed_losses.lp") @@ -467,12 +520,12 @@ def test_storage_invest_1_fixed_losses(self): """All invest variables are coupled. The invest variables of the Flows will be created during the initialisation of the storage e.g. battery """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage1", - inputs={bel: solph.Flow(variable_costs=56)}, - outputs={bel: solph.Flow(variable_costs=24)}, + inputs={bel: solph.flows.Flow(variable_costs=56)}, + outputs={bel: solph.flows.Flow(variable_costs=24)}, nominal_storage_capacity=None, loss_rate=0.13, fixed_losses_relative=0.01, @@ -485,73 +538,78 @@ def test_storage_invest_1_fixed_losses(self): outflow_conversion_factor=0.86, investment=solph.Investment(ep_costs=145, maximum=234), ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_invest_1_fixed_losses.lp") def test_transformer(self): """Constraint test of a LinearN1Transformer without Investment.""" - bgas = solph.Bus(label="gasBus") - bbms = solph.Bus(label="biomassBus") - bel = solph.Bus(label="electricityBus") - bth = solph.Bus(label="thermalBus") + bgas = solph.buses.Bus(label="gasBus") + bbms = solph.buses.Bus(label="biomassBus") + bel = solph.buses.Bus(label="electricityBus") + bth = solph.buses.Bus(label="thermalBus") - solph.Transformer( + transformer = solph.components.Transformer( label="powerplantGasCoal", - inputs={bbms: solph.Flow(), bgas: solph.Flow()}, + inputs={bbms: solph.flows.Flow(), bgas: solph.flows.Flow()}, outputs={ - bel: solph.Flow(variable_costs=50), - bth: solph.Flow(nominal_value=5e10, variable_costs=20), + bel: solph.flows.Flow(variable_costs=50), + bth: solph.flows.Flow(nominal_value=5e10, variable_costs=20), }, conversion_factors={bgas: 0.4, bbms: 0.1, bel: 0.3, bth: 0.5}, ) + self.energysystem.add(bgas, bbms, bel, bth, transformer) + self.compare_lp_files("transformer.lp") def test_transformer_invest(self): """Constraint test of a LinearN1Transformer with Investment.""" - bgas = solph.Bus(label="gasBus") - bcoal = solph.Bus(label="coalBus") - bel = solph.Bus(label="electricityBus") - bth = solph.Bus(label="thermalBus") + bgas = solph.buses.Bus(label="gasBus") + bcoal = solph.buses.Bus(label="coalBus") + bel = solph.buses.Bus(label="electricityBus") + bth = solph.buses.Bus(label="thermalBus") - solph.Transformer( + transformer = solph.components.Transformer( label="powerplant_gas_coal", - inputs={bgas: solph.Flow(), bcoal: solph.Flow()}, + inputs={bgas: solph.flows.Flow(), bcoal: solph.flows.Flow()}, outputs={ - bel: solph.Flow( + bel: solph.flows.Flow( variable_costs=50, investment=solph.Investment(maximum=1000, ep_costs=20), ), - bth: solph.Flow(variable_costs=20), + bth: solph.flows.Flow(variable_costs=20), }, conversion_factors={bgas: 0.58, bcoal: 0.2, bel: 0.3, bth: 0.5}, ) + self.energysystem.add(bgas, bcoal, bel, bth, transformer) self.compare_lp_files("transformer_invest.lp") def test_transformer_invest_with_existing(self): """Constraint test of a LinearN1Transformer with Investment.""" - bgas = solph.Bus(label="gasBus") - bcoal = solph.Bus(label="coalBus") - bel = solph.Bus(label="electricityBus") - bth = solph.Bus(label="thermalBus") + bgas = solph.buses.Bus(label="gasBus") + bcoal = solph.buses.Bus(label="coalBus") + bel = solph.buses.Bus(label="electricityBus") + bth = solph.buses.Bus(label="thermalBus") - solph.Transformer( + transformer = solph.components.Transformer( label="powerplant_gas_coal", - inputs={bgas: solph.Flow(), bcoal: solph.Flow()}, + inputs={bgas: solph.flows.Flow(), bcoal: solph.flows.Flow()}, outputs={ - bel: solph.Flow( + bel: solph.flows.Flow( variable_costs=50, investment=solph.Investment( maximum=1000, ep_costs=20, existing=200 ), ), - bth: solph.Flow(variable_costs=20), + bth: solph.flows.Flow(variable_costs=20), }, conversion_factors={bgas: 0.58, bcoal: 0.2, bel: 0.3, bth: 0.5}, ) + self.energysystem.add(bgas, bcoal, bel, bth, transformer) self.compare_lp_files("transformer_invest_with_existing.lp") @@ -559,37 +617,41 @@ def test_linear_transformer_chp(self): """ Constraint test of a Transformer without Investment (two outputs). """ - bgas = solph.Bus(label="gasBus") - bheat = solph.Bus(label="heatBus") - bel = solph.Bus(label="electricityBus") + bgas = solph.buses.Bus(label="gasBus") + bheat = solph.buses.Bus(label="heatBus") + bel = solph.buses.Bus(label="electricityBus") - solph.Transformer( + transformer = solph.components.Transformer( label="CHPpowerplantGas", - inputs={bgas: solph.Flow(nominal_value=10e10, variable_costs=50)}, - outputs={bel: solph.Flow(), bheat: solph.Flow()}, + inputs={ + bgas: solph.flows.Flow(nominal_value=10e10, variable_costs=50) + }, + outputs={bel: solph.flows.Flow(), bheat: solph.flows.Flow()}, conversion_factors={bel: 0.4, bheat: 0.5}, ) + self.energysystem.add(bgas, bheat, bel, transformer) self.compare_lp_files("linear_transformer_chp.lp") def test_linear_transformer_chp_invest(self): """Constraint test of a Transformer with Investment (two outputs).""" - bgas = solph.Bus(label="gasBus") - bheat = solph.Bus(label="heatBus") - bel = solph.Bus(label="electricityBus") + bgas = solph.buses.Bus(label="gasBus") + bheat = solph.buses.Bus(label="heatBus") + bel = solph.buses.Bus(label="electricityBus") - solph.Transformer( + transformer = solph.components.Transformer( label="chp_powerplant_gas", inputs={ - bgas: solph.Flow( + bgas: solph.flows.Flow( variable_costs=50, investment=solph.Investment(maximum=1000, ep_costs=20), ) }, - outputs={bel: solph.Flow(), bheat: solph.Flow()}, + outputs={bel: solph.flows.Flow(), bheat: solph.flows.Flow()}, conversion_factors={bel: 0.4, bheat: 0.5}, ) + self.energysystem.add(bgas, bheat, bel, transformer) self.compare_lp_files("linear_transformer_chp_invest.lp") @@ -611,57 +673,60 @@ def test_link(self): def test_variable_chp(self): """ """ - bel = solph.Bus(label="electricityBus") - bth = solph.Bus(label="heatBus") - bgas = solph.Bus(label="commodityBus") + bel = solph.buses.Bus(label="electricityBus") + bth = solph.buses.Bus(label="heatBus") + bgas = solph.buses.Bus(label="commodityBus") - solph.components.ExtractionTurbineCHP( + chp1 = solph.components.ExtractionTurbineCHP( label="variable_chp_gas1", - inputs={bgas: solph.Flow(nominal_value=100)}, - outputs={bel: solph.Flow(), bth: solph.Flow()}, + inputs={bgas: solph.flows.Flow(nominal_value=100)}, + outputs={bel: solph.flows.Flow(), bth: solph.flows.Flow()}, conversion_factors={bel: 0.3, bth: 0.5}, conversion_factor_full_condensation={bel: 0.5}, ) - solph.components.ExtractionTurbineCHP( + chp2 = solph.components.ExtractionTurbineCHP( label="variable_chp_gas2", - inputs={bgas: solph.Flow(nominal_value=100)}, - outputs={bel: solph.Flow(), bth: solph.Flow()}, + inputs={bgas: solph.flows.Flow(nominal_value=100)}, + outputs={bel: solph.flows.Flow(), bth: solph.flows.Flow()}, conversion_factors={bel: 0.3, bth: 0.5}, conversion_factor_full_condensation={bel: 0.5}, ) + self.energysystem.add(bel, bth, bgas, chp1, chp2) self.compare_lp_files("variable_chp.lp") def test_generic_invest_limit(self): """ """ - bus = solph.Bus(label="bus_1") + bus = solph.buses.Bus(label="bus_1") - solph.Source( + source_0 = solph.components.Source( label="source_0", outputs={ - bus: solph.Flow( + bus: solph.flows.Flow( investment=solph.Investment(ep_costs=50, space=4) ) }, ) - solph.Source( + source_1 = solph.components.Source( label="source_1", outputs={ - bus: solph.Flow( + bus: solph.flows.Flow( investment=solph.Investment(ep_costs=100, space=1) ) }, ) - solph.Source( + source_2 = solph.components.Source( label="source_2", outputs={ - bus: solph.Flow(investment=solph.Investment(ep_costs=75)) + bus: solph.flows.Flow(investment=solph.Investment(ep_costs=75)) }, ) + self.energysystem.add(bus, source_0, source_1, source_2) + om = self.get_om() om = solph.constraints.additional_investment_flow_limit( @@ -672,26 +737,30 @@ def test_generic_invest_limit(self): def test_emission_constraints(self): """ """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.Source( + source1 = solph.components.Source( label="source1", outputs={ - bel: solph.Flow( + bel: solph.flows.Flow( nominal_value=100, emission_factor=[0.5, -1.0, 2.0] ) }, ) - solph.Source( + source2 = solph.components.Source( label="source2", - outputs={bel: solph.Flow(nominal_value=100, emission_factor=3.5)}, + outputs={ + bel: solph.flows.Flow(nominal_value=100, emission_factor=3.5) + }, ) # Should be ignored because the emission attribute is not defined. - solph.Source( - label="source3", outputs={bel: solph.Flow(nominal_value=100)} + source3 = solph.components.Source( + label="source3", outputs={bel: solph.flows.Flow(nominal_value=100)} ) + self.energysystem.add(bel, source1, source2, source3) + om = self.get_om() solph.constraints.emission_limit(om, limit=777) @@ -700,22 +769,22 @@ def test_emission_constraints(self): def test_flow_count_limit(self): """ """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.Source( + source1 = solph.components.Source( label="source1", outputs={ - bel: solph.Flow( + bel: solph.flows.Flow( nonconvex=solph.NonConvex(), nominal_value=100, emission_factor=[0.5, -1.0, 2.0], ) }, ) - solph.Source( + source2 = solph.components.Source( label="source2", outputs={ - bel: solph.Flow( + bel: solph.flows.Flow( nonconvex=solph.NonConvex(), nominal_value=100, emission_factor=3.5, @@ -724,23 +793,27 @@ def test_flow_count_limit(self): ) # Should be ignored because emission_factor is not defined. - solph.Source( + source3 = solph.components.Source( label="source3", outputs={ - bel: solph.Flow(nonconvex=solph.NonConvex(), nominal_value=100) + bel: solph.flows.Flow( + nonconvex=solph.NonConvex(), nominal_value=100 + ) }, ) # Should be ignored because it is not NonConvex. - solph.Source( + source4 = solph.components.Source( label="source4", outputs={ - bel: solph.Flow( + bel: solph.flows.Flow( emission_factor=1.5, min=0.3, nominal_value=100 ) }, ) + self.energysystem.add(bel, source1, source2, source3, source4) + om = self.get_om() # one of the two flows has to be active @@ -752,21 +825,23 @@ def test_flow_count_limit(self): def test_shared_limit(self): """ """ - b1 = solph.Bus(label="bus") + b1 = solph.buses.Bus(label="bus") storage1 = solph.components.GenericStorage( label="storage1", nominal_storage_capacity=5, - inputs={b1: solph.Flow()}, - outputs={b1: solph.Flow()}, + inputs={b1: solph.flows.Flow()}, + outputs={b1: solph.flows.Flow()}, ) storage2 = solph.components.GenericStorage( label="storage2", nominal_storage_capacity=5, - inputs={b1: solph.Flow()}, - outputs={b1: solph.Flow()}, + inputs={b1: solph.flows.Flow()}, + outputs={b1: solph.flows.Flow()}, ) + self.energysystem.add(b1, storage1, storage2) + model = self.get_om() components = [storage1, storage2] @@ -786,16 +861,20 @@ def test_flow_without_emission_for_emission_constraint(self): """ """ def define_emission_limit(): - bel = solph.Bus(label="electricityBus") - solph.Source( + bel = solph.buses.Bus(label="electricityBus") + source1 = solph.components.Source( label="source1", outputs={ - bel: solph.Flow(nominal_value=100, emission_factor=0.8) + bel: solph.flows.Flow( + nominal_value=100, emission_factor=0.8 + ) }, ) - solph.Source( - label="source2", outputs={bel: solph.Flow(nominal_value=100)} + source2 = solph.components.Source( + label="source2", + outputs={bel: solph.flows.Flow(nominal_value=100)}, ) + self.energysystem.add(bel, source1, source2) om = self.get_om() solph.constraints.emission_limit(om, om.flows, limit=777) @@ -803,50 +882,58 @@ def define_emission_limit(): def test_flow_without_emission_for_emission_constraint_no_error(self): """ """ - bel = solph.Bus(label="electricityBus") - solph.Source( + bel = solph.buses.Bus(label="electricityBus") + source1 = solph.components.Source( label="source1", - outputs={bel: solph.Flow(nominal_value=100, emission_factor=0.8)}, + outputs={ + bel: solph.flows.Flow(nominal_value=100, emission_factor=0.8) + }, ) - solph.Source( - label="source2", outputs={bel: solph.Flow(nominal_value=100)} + source2 = solph.components.Source( + label="source2", outputs={bel: solph.flows.Flow(nominal_value=100)} ) + self.energysystem.add(bel, source1, source2) om = self.get_om() solph.constraints.emission_limit(om, limit=777) def test_equate_variables_constraint(self): """Testing the equate_variables function in the constraint module.""" - bus1 = solph.Bus(label="Bus1") + bus1 = solph.buses.Bus(label="Bus1") storage = solph.components.GenericStorage( label="storage_constraint", invest_relation_input_capacity=0.2, invest_relation_output_capacity=0.2, - inputs={bus1: solph.Flow()}, - outputs={bus1: solph.Flow()}, + inputs={bus1: solph.flows.Flow()}, + outputs={bus1: solph.flows.Flow()}, investment=solph.Investment(ep_costs=145), ) - sink = solph.Sink( + sink = solph.components.Sink( label="Sink", inputs={ - bus1: solph.Flow(investment=solph.Investment(ep_costs=500)) + bus1: solph.flows.Flow( + investment=solph.Investment(ep_costs=500) + ) }, ) - source = solph.Source( + source = solph.components.Source( label="Source", outputs={ - bus1: solph.Flow(investment=solph.Investment(ep_costs=123)) + bus1: solph.flows.Flow( + investment=solph.Investment(ep_costs=123) + ) }, ) + self.energysystem.add(bus1, storage, sink, source) om = self.get_om() solph.constraints.equate_variables( om, - om.InvestmentFlow.invest[source, bus1], - om.InvestmentFlow.invest[bus1, sink], + om.InvestmentFlowBlock.invest[source, bus1], + om.InvestmentFlowBlock.invest[bus1, sink], 2, ) solph.constraints.equate_variables( om, - om.InvestmentFlow.invest[source, bus1], + om.InvestmentFlowBlock.invest[source, bus1], om.GenericInvestmentStorageBlock.invest[storage], ) @@ -854,12 +941,12 @@ def test_equate_variables_constraint(self): def test_gradient(self): """Testing gradient constraints and costs.""" - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.Source( + pp = solph.components.Source( label="powerplant", outputs={ - bel: solph.Flow( + bel: solph.flows.Flow( nominal_value=999, variable_costs=23, positive_gradient={"ub": 0.03}, @@ -867,26 +954,28 @@ def test_gradient(self): ) }, ) + self.energysystem.add(bel, pp) self.compare_lp_files("source_with_gradient.lp") def test_nonconvex_gradient(self): """Testing gradient constraints and costs.""" - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.Source( + pp = solph.components.Source( label="powerplant", outputs={ - bel: solph.Flow( + bel: solph.flows.Flow( nominal_value=999, variable_costs=23, nonconvex=solph.NonConvex( - positive_gradient={"ub": 0.03, "costs": 7}, - negative_gradient={"ub": 0.05, "costs": 8}, + positive_gradient={"ub": 0.03}, + negative_gradient={"ub": 0.05}, ), ) }, ) + self.energysystem.add(bel, pp) self.compare_lp_files("source_with_nonconvex_gradient.lp") @@ -924,21 +1013,24 @@ def test_nonconvex_negative_gradient_error(self): def test_investment_limit(self): """Testing the investment_limit function in the constraint module.""" - bus1 = solph.Bus(label="Bus1") - solph.components.GenericStorage( + bus1 = solph.buses.Bus(label="Bus1") + storage = solph.components.GenericStorage( label="storage_invest_limit", invest_relation_input_capacity=0.2, invest_relation_output_capacity=0.2, - inputs={bus1: solph.Flow()}, - outputs={bus1: solph.Flow()}, + inputs={bus1: solph.flows.Flow()}, + outputs={bus1: solph.flows.Flow()}, investment=solph.Investment(ep_costs=145), ) - solph.Source( + source = solph.components.Source( label="Source", outputs={ - bus1: solph.Flow(investment=solph.Investment(ep_costs=123)) + bus1: solph.flows.Flow( + investment=solph.Investment(ep_costs=123) + ) }, ) + self.energysystem.add(bus1, storage, source) om = self.get_om() solph.constraints.investment_limit(om, limit=900) @@ -946,11 +1038,11 @@ def test_investment_limit(self): def test_min_max_runtime(self): """Testing min and max runtimes for nonconvex flows.""" - bus_t = solph.Bus(label="Bus_T") - solph.Source( + bus_t = solph.buses.Bus(label="Bus_T") + pp = solph.components.Source( label="cheap_plant_min_down_constraints", outputs={ - bus_t: solph.Flow( + bus_t: solph.flows.Flow( nominal_value=10, min=0.5, max=1.0, @@ -965,15 +1057,17 @@ def test_min_max_runtime(self): ) }, ) + + self.energysystem.add(bus_t, pp) self.compare_lp_files("min_max_runtime.lp") def test_activity_costs(self): """Testing activity_costs attribute for nonconvex flows.""" - bus_t = solph.Bus(label="Bus_C") - solph.Source( + bus_t = solph.buses.Bus(label="Bus_C") + pp = solph.components.Source( label="cheap_plant_activity_costs", outputs={ - bus_t: solph.Flow( + bus_t: solph.flows.Flow( nominal_value=10, min=0.5, max=1.0, @@ -982,43 +1076,52 @@ def test_activity_costs(self): ) }, ) + + self.energysystem.add(bus_t, pp) self.compare_lp_files("activity_costs.lp") def test_piecewise_linear_transformer_cc(self): """Testing PiecewiseLinearTransformer using CC formulation.""" - bgas = solph.Bus(label="gasBus") - bel = solph.Bus(label="electricityBus") - solph.custom.PiecewiseLinearTransformer( + bgas = solph.buses.Bus(label="gasBus") + bel = solph.buses.Bus(label="electricityBus") + plt = solph.components.experimental.PiecewiseLinearTransformer( label="pwltf", - inputs={bgas: solph.Flow(nominal_value=100, variable_costs=1)}, - outputs={bel: solph.Flow()}, + inputs={ + bgas: solph.flows.Flow(nominal_value=100, variable_costs=1) + }, + outputs={bel: solph.flows.Flow()}, in_breakpoints=[0, 25, 50, 75, 100], conversion_function=lambda x: x**2, pw_repn="CC", ) + + self.energysystem.add(bgas, bel, plt) self.compare_lp_files("piecewise_linear_transformer_cc.lp") def test_piecewise_linear_transformer_dcc(self): """Testing PiecewiseLinearTransformer using DCC formulation.""" - bgas = solph.Bus(label="gasBus") - bel = solph.Bus(label="electricityBus") - solph.custom.PiecewiseLinearTransformer( + bgas = solph.buses.Bus(label="gasBus") + bel = solph.buses.Bus(label="electricityBus") + plt = solph.components.experimental.PiecewiseLinearTransformer( label="pwltf", - inputs={bgas: solph.Flow(nominal_value=100, variable_costs=1)}, - outputs={bel: solph.Flow()}, + inputs={ + bgas: solph.flows.Flow(nominal_value=100, variable_costs=1) + }, + outputs={bel: solph.flows.Flow()}, in_breakpoints=[0, 25, 50, 75, 100], conversion_function=lambda x: x**2, pw_repn="DCC", ) + self.energysystem.add(bgas, bel, plt) self.compare_lp_files("piecewise_linear_transformer_dcc.lp") def test_maximum_startups(self): """Testing maximum_startups attribute for nonconvex flows.""" - bus_t = solph.Bus(label="Bus_C") - solph.Source( + bus_t = solph.buses.Bus(label="Bus_C") + pp = solph.components.Source( label="cheap_plant_maximum_startups", outputs={ - bus_t: solph.Flow( + bus_t: solph.flows.Flow( nominal_value=10, min=0.5, max=1.0, @@ -1027,15 +1130,16 @@ def test_maximum_startups(self): ) }, ) + self.energysystem.add(bus_t, pp) self.compare_lp_files("maximum_startups.lp") def test_maximum_shutdowns(self): """Testing maximum_shutdowns attribute for nonconvex flows.""" - bus_t = solph.Bus(label="Bus_C") - solph.Source( + bus_t = solph.buses.Bus(label="Bus_C") + pp = solph.components.Source( label="cheap_plant_maximum_shutdowns", outputs={ - bus_t: solph.Flow( + bus_t: solph.flows.Flow( nominal_value=10, min=0.5, max=1.0, @@ -1044,35 +1148,37 @@ def test_maximum_shutdowns(self): ) }, ) + self.energysystem.add(bus_t, pp) self.compare_lp_files("maximum_shutdowns.lp") def test_offsettransformer(self): """Constraint test of a OffsetTransformer.""" - bgas = solph.Bus(label="gasBus") - bth = solph.Bus(label="thermalBus") + bgas = solph.buses.Bus(label="gasBus") + bth = solph.buses.Bus(label="thermalBus") - solph.components.OffsetTransformer( + transformer = solph.components.OffsetTransformer( label="gasboiler", inputs={ - bgas: solph.Flow( + bgas: solph.flows.Flow( nonconvex=solph.NonConvex(), nominal_value=100, min=0.32, ) }, - outputs={bth: solph.Flow()}, + outputs={bth: solph.flows.Flow()}, coefficients=[-17, 0.9], ) + self.energysystem.add(bgas, bth, transformer) self.compare_lp_files("offsettransformer.lp") def test_dsm_module_DIW(self): """Constraint test of SinkDSM with approach=DLR""" - b_elec = solph.Bus(label="bus_elec") - solph.custom.SinkDSM( + b_elec = solph.buses.Bus(label="bus_elec") + sink = solph.components.experimental.SinkDSM( label="demand_dsm", - inputs={b_elec: solph.Flow()}, + inputs={b_elec: solph.flows.Flow()}, demand=[1] * 3, capacity_up=[0.5] * 3, capacity_down=[0.5] * 3, @@ -1084,15 +1190,17 @@ def test_dsm_module_DIW(self): cost_dsm_down_shift=2, shed_eligibility=False, ) + + self.energysystem.add(b_elec, sink) self.compare_lp_files("dsm_module_DIW.lp") def test_dsm_module_DLR(self): """Constraint test of SinkDSM with approach=DLR""" - b_elec = solph.Bus(label="bus_elec") - solph.custom.SinkDSM( + b_elec = solph.buses.Bus(label="bus_elec") + sink = solph.components.experimental.SinkDSM( label="demand_dsm", - inputs={b_elec: solph.Flow()}, + inputs={b_elec: solph.flows.Flow()}, demand=[1] * 3, capacity_up=[0.5] * 3, capacity_down=[0.5] * 3, @@ -1105,15 +1213,16 @@ def test_dsm_module_DLR(self): cost_dsm_down_shift=2, shed_eligibility=False, ) + self.energysystem.add(b_elec, sink) self.compare_lp_files("dsm_module_DLR.lp") def test_dsm_module_oemof(self): """Constraint test of SinkDSM with approach=oemof""" - b_elec = solph.Bus(label="bus_elec") - solph.custom.SinkDSM( + b_elec = solph.buses.Bus(label="bus_elec") + sink = solph.components.experimental.SinkDSM( label="demand_dsm", - inputs={b_elec: solph.Flow()}, + inputs={b_elec: solph.flows.Flow()}, demand=[1] * 3, capacity_up=[0.5, 0.4, 0.5], capacity_down=[0.5, 0.4, 0.5], @@ -1125,15 +1234,16 @@ def test_dsm_module_oemof(self): cost_dsm_down_shift=2, shed_eligibility=False, ) + self.energysystem.add(b_elec, sink) self.compare_lp_files("dsm_module_oemof.lp") def test_dsm_module_DIW_invest(self): """Constraint test of SinkDSM with approach=DLR and investments""" - b_elec = solph.Bus(label="bus_elec") - solph.custom.SinkDSM( + b_elec = solph.buses.Bus(label="bus_elec") + sink = solph.components.experimental.SinkDSM( label="demand_dsm", - inputs={b_elec: solph.Flow()}, + inputs={b_elec: solph.flows.Flow()}, demand=[1] * 3, capacity_up=[0.5] * 3, capacity_down=[0.5] * 3, @@ -1147,15 +1257,16 @@ def test_dsm_module_DIW_invest(self): ep_cost=100, existing=50, minimum=33, maximum=100 ), ) + self.energysystem.add(b_elec, sink) self.compare_lp_files("dsm_module_DIW_invest.lp") def test_dsm_module_DLR_invest(self): """Constraint test of SinkDSM with approach=DLR and investments""" - b_elec = solph.Bus(label="bus_elec") - solph.custom.SinkDSM( + b_elec = solph.buses.Bus(label="bus_elec") + sink = solph.components.experimental.SinkDSM( label="demand_dsm", - inputs={b_elec: solph.Flow()}, + inputs={b_elec: solph.flows.Flow()}, demand=[1] * 3, capacity_up=[0.5] * 3, capacity_down=[0.5] * 3, @@ -1170,15 +1281,16 @@ def test_dsm_module_DLR_invest(self): ep_cost=100, existing=50, minimum=33, maximum=100 ), ) + self.energysystem.add(b_elec, sink) self.compare_lp_files("dsm_module_DLR_invest.lp") def test_dsm_module_oemof_invest(self): """Constraint test of SinkDSM with approach=oemof and investments""" - b_elec = solph.Bus(label="bus_elec") - solph.custom.SinkDSM( + b_elec = solph.buses.Bus(label="bus_elec") + sink = solph.components.experimental.SinkDSM( label="demand_dsm", - inputs={b_elec: solph.Flow()}, + inputs={b_elec: solph.flows.Flow()}, demand=[1] * 3, capacity_up=[0.5, 0.4, 0.5], capacity_down=[0.5, 0.4, 0.5], @@ -1192,18 +1304,19 @@ def test_dsm_module_oemof_invest(self): ep_cost=100, existing=50, minimum=33, maximum=100 ), ) + self.energysystem.add(b_elec, sink) self.compare_lp_files("dsm_module_oemof_invest.lp") def test_nonconvex_investment_storage_without_offset(self): """All invest variables are coupled. The invest variables of the Flows will be created during the initialisation of the storage e.g. battery """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage_non_convex", - inputs={bel: solph.Flow(variable_costs=56)}, - outputs={bel: solph.Flow(variable_costs=24)}, + inputs={bel: solph.flows.Flow(variable_costs=56)}, + outputs={bel: solph.flows.Flow(variable_costs=24)}, nominal_storage_capacity=None, loss_rate=0.13, max_storage_level=0.9, @@ -1216,6 +1329,7 @@ def test_nonconvex_investment_storage_without_offset(self): ep_costs=141, maximum=244, minimum=12, nonconvex=True ), ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_invest_without_offset.lp") @@ -1223,12 +1337,12 @@ def test_nonconvex_investment_storage_with_offset(self): """All invest variables are coupled. The invest variables of the Flows will be created during the initialisation of the storage e.g. battery """ - bel = solph.Bus(label="electricityBus") + bel = solph.buses.Bus(label="electricityBus") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storagenon_convex", - inputs={bel: solph.Flow(variable_costs=56)}, - outputs={bel: solph.Flow(variable_costs=24)}, + inputs={bel: solph.flows.Flow(variable_costs=56)}, + outputs={bel: solph.flows.Flow(variable_costs=24)}, nominal_storage_capacity=None, loss_rate=0.13, max_storage_level=0.9, @@ -1245,17 +1359,18 @@ def test_nonconvex_investment_storage_with_offset(self): maximum=1454, ), ) + self.energysystem.add(bel, storage) self.compare_lp_files("storage_invest_with_offset.lp") def test_nonconvex_invest_storage_all_nonconvex(self): """All invest variables are free and nonconvex.""" - b1 = solph.Bus(label="bus1") + b1 = solph.buses.Bus(label="bus1") - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage_all_nonconvex", inputs={ - b1: solph.Flow( + b1: solph.flows.Flow( investment=solph.Investment( nonconvex=True, minimum=5, @@ -1266,7 +1381,7 @@ def test_nonconvex_invest_storage_all_nonconvex(self): ) }, outputs={ - b1: solph.Flow( + b1: solph.flows.Flow( investment=solph.Investment( nonconvex=True, minimum=8, @@ -1280,18 +1395,19 @@ def test_nonconvex_invest_storage_all_nonconvex(self): nonconvex=True, ep_costs=20, offset=30, minimum=20, maximum=100 ), ) + self.energysystem.add(b1, storage) self.compare_lp_files("storage_invest_all_nonconvex.lp") def test_nonconvex_invest_sink_without_offset(self): - """Non convex invest flow without offset, with minimum.""" - bel = solph.Bus(label="electricityBus") + """Non-convex invest flow without offset, with minimum.""" + bel = solph.buses.Bus(label="electricityBus") - solph.Sink( + sink = solph.components.Sink( label="sink_nonconvex_invest", inputs={ - bel: solph.Flow( - summed_max=2.3, + bel: solph.flows.Flow( + full_load_time_max=2.3, variable_costs=25, max=0.8, investment=solph.Investment( @@ -1300,17 +1416,18 @@ def test_nonconvex_invest_sink_without_offset(self): ) }, ) + self.energysystem.add(bel, sink) self.compare_lp_files("flow_invest_without_offset.lp") def test_nonconvex_invest_source_with_offset(self): - """Non convex invest flow with offset, with minimum.""" - bel = solph.Bus(label="electricityBus") + """Non-convex invest flow with offset, with minimum.""" + bel = solph.buses.Bus(label="electricityBus") - solph.Source( + source = solph.components.Source( label="source_nonconvex_invest", inputs={ - bel: solph.Flow( - summed_max=2.3, + bel: solph.flows.Flow( + full_load_time_max=2.3, variable_costs=25, max=0.8, investment=solph.Investment( @@ -1323,17 +1440,18 @@ def test_nonconvex_invest_source_with_offset(self): ) }, ) + self.energysystem.add(bel, source) self.compare_lp_files("flow_invest_with_offset.lp") def test_nonconvex_invest_source_with_offset_no_minimum(self): - """Non convex invest flow with offset, without minimum.""" - bel = solph.Bus(label="electricityBus") + """Non-convex invest flow with offset, without minimum.""" + bel = solph.buses.Bus(label="electricityBus") - solph.Source( + source = solph.components.Source( label="source_nonconvex_invest", inputs={ - bel: solph.Flow( - summed_max=2.3, + bel: solph.flows.Flow( + full_load_time_max=2.3, variable_costs=25, max=0.8, investment=solph.Investment( @@ -1342,4 +1460,5 @@ def test_nonconvex_invest_source_with_offset_no_minimum(self): ) }, ) + self.energysystem.add(bel, source) self.compare_lp_files("flow_invest_with_offset_no_minimum.lp") From 5ceb3054e19638cf7df29eca6b644b843b49ff1c Mon Sep 17 00:00:00 2001 From: jnnr <32454596+jnnr@users.noreply.github.com> Date: Wed, 21 Dec 2022 17:40:26 +0100 Subject: [PATCH 47/58] Rewind adaptions to solph 0.5 --- tests/constraint_tests.py | 514 +++++++++++++++++++------------------- 1 file changed, 257 insertions(+), 257 deletions(-) diff --git a/tests/constraint_tests.py b/tests/constraint_tests.py index 990103f04..d858616e9 100644 --- a/tests/constraint_tests.py +++ b/tests/constraint_tests.py @@ -141,15 +141,15 @@ def normalize_to_positive_results(lines): def test_linear_transformer(self): """Constraint test of a Transformer without Investment.""" - bgas = solph.buses.Bus(label="gas") + bgas = solph.Bus(label="gas") - bel = solph.buses.Bus(label="electricity") + bel = solph.Bus(label="electricity") - transformer = solph.components.Transformer( + transformer = solph.Transformer( label="powerplantGas", - inputs={bgas: solph.flows.Flow()}, + inputs={bgas: solph.Flow()}, outputs={ - bel: solph.flows.Flow(nominal_value=10e10, variable_costs=50) + bel: solph.Flow(nominal_value=10e10, variable_costs=50) }, conversion_factors={bel: 0.58}, ) @@ -160,15 +160,15 @@ def test_linear_transformer(self): def test_linear_transformer_invest(self): """Constraint test of a Transformer with Investment.""" - bgas = solph.buses.Bus(label="gas") + bgas = solph.Bus(label="gas") - bel = solph.buses.Bus(label="electricity") + bel = solph.Bus(label="electricity") - transformer = solph.components.Transformer( + transformer = solph.Transformer( label="powerplant_gas", - inputs={bgas: solph.flows.Flow()}, + inputs={bgas: solph.Flow()}, outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( variable_costs=50, investment=solph.Investment(maximum=1000, ep_costs=20), ) @@ -181,19 +181,19 @@ def test_linear_transformer_invest(self): def test_max_source_min_sink(self): """ """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - wind = solph.components.Source( + wind = solph.Source( label="wind", outputs={ - bel: solph.flows.Flow(nominal_value=54, max=(0.85, 0.95, 0.61)) + bel: solph.Flow(nominal_value=54, max=(0.85, 0.95, 0.61)) }, ) - demand = solph.components.Sink( + demand = solph.Sink( label="minDemand", inputs={ - bel: solph.flows.Flow( + bel: solph.Flow( nominal_value=54, min=(0.84, 0.94, 0.59), variable_costs=14 ) }, @@ -205,19 +205,19 @@ def test_max_source_min_sink(self): def test_fixed_source_variable_sink(self): """Constraint test with a fixed source and a variable sink.""" - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - wind = solph.components.Source( + wind = solph.Source( label="wind", outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( fix=[0.43, 0.72, 0.29], nominal_value=10e5 ) }, ) - excess = solph.components.Sink( - label="excess", inputs={bel: solph.flows.Flow(variable_costs=40)} + excess = solph.Sink( + label="excess", inputs={bel: solph.Flow(variable_costs=40)} ) self.energysystem.add(bel, wind, excess) @@ -226,10 +226,10 @@ def test_fixed_source_variable_sink(self): def test_nominal_value_to_zero(self): """If the nominal value is set to zero nothing should happen.""" - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - s1 = solph.components.Source( - label="s1", outputs={bel: solph.flows.Flow(nominal_value=0)} + s1 = solph.Source( + label="s1", outputs={bel: solph.Flow(nominal_value=0)} ) self.energysystem.add(bel, s1) self.compare_lp_files("nominal_value_to_zero.lp") @@ -240,19 +240,19 @@ def test_fixed_source_invest_sink(self): `full_load_time_max`. """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - wind = solph.components.Source( + wind = solph.Source( label="wind", outputs={ - bel: solph.flows.Flow(fix=[12, 16, 14], nominal_value=1000000) + bel: solph.Flow(fix=[12, 16, 14], nominal_value=1000000) }, ) - excess = solph.components.Sink( + excess = solph.Sink( label="excess", inputs={ - bel: solph.flows.Flow( + bel: solph.Flow( full_load_time_max=2.3, variable_costs=25, max=0.8, @@ -269,12 +269,12 @@ def test_fixed_source_invest_sink(self): def test_invest_source_fixed_sink(self): """Constraint test with a fixed sink and a dispatch invest source.""" - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - pv = solph.components.Source( + pv = solph.Source( label="pv", outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( max=[45, 83, 65], variable_costs=13, investment=solph.Investment(ep_costs=123), @@ -282,10 +282,10 @@ def test_invest_source_fixed_sink(self): }, ) - excess = solph.components.Sink( + excess = solph.Sink( label="excess", inputs={ - bel: solph.flows.Flow(fix=[0.5, 0.8, 0.3], nominal_value=10e4) + bel: solph.Flow(fix=[0.5, 0.8, 0.3], nominal_value=10e4) }, ) self.energysystem.add(bel, pv, excess) @@ -294,15 +294,15 @@ def test_invest_source_fixed_sink(self): def test_storage(self): """ """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage_no_invest", inputs={ - bel: solph.flows.Flow(nominal_value=16667, variable_costs=56) + bel: solph.Flow(nominal_value=16667, variable_costs=56) }, outputs={ - bel: solph.flows.Flow(nominal_value=16667, variable_costs=24) + bel: solph.Flow(nominal_value=16667, variable_costs=24) }, nominal_storage_capacity=10e4, loss_rate=0.13, @@ -318,12 +318,12 @@ def test_storage_invest_1(self): """All invest variables are coupled. The invest variables of the Flows will be created during the initialisation of the storage e.g. battery """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage1", - inputs={bel: solph.flows.Flow(variable_costs=56)}, - outputs={bel: solph.flows.Flow(variable_costs=24)}, + inputs={bel: solph.Flow(variable_costs=56)}, + outputs={bel: solph.Flow(variable_costs=24)}, nominal_storage_capacity=None, loss_rate=0.13, max_storage_level=0.9, @@ -340,15 +340,15 @@ def test_storage_invest_1(self): def test_storage_invest_2(self): """All can be free extended to their own cost.""" - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage2", inputs={ - bel: solph.flows.Flow(investment=solph.Investment(ep_costs=99)) + bel: solph.Flow(investment=solph.Investment(ep_costs=99)) }, outputs={ - bel: solph.flows.Flow(investment=solph.Investment(ep_costs=9)) + bel: solph.Flow(investment=solph.Investment(ep_costs=9)) }, investment=solph.Investment(ep_costs=145), initial_storage_level=0.5, @@ -361,15 +361,15 @@ def test_storage_invest_3(self): e.g. PHES with a fixed basin but the pump and the turbine can be adapted """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage3", inputs={ - bel: solph.flows.Flow(investment=solph.Investment(ep_costs=99)) + bel: solph.Flow(investment=solph.Investment(ep_costs=99)) }, outputs={ - bel: solph.flows.Flow(investment=solph.Investment(ep_costs=9)) + bel: solph.Flow(investment=solph.Investment(ep_costs=9)) }, nominal_storage_capacity=5000, ) @@ -378,12 +378,12 @@ def test_storage_invest_3(self): def test_storage_invest_4(self): """Only the storage capacity can be extended.""" - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage4", - inputs={bel: solph.flows.Flow(nominal_value=80)}, - outputs={bel: solph.flows.Flow(nominal_value=100)}, + inputs={bel: solph.Flow(nominal_value=80)}, + outputs={bel: solph.Flow(nominal_value=100)}, investment=solph.Investment(ep_costs=145, maximum=500), ) self.energysystem.add(bel, storage) @@ -395,17 +395,17 @@ def test_storage_invest_5(self): adapted. The installed capacity of the pump is 10 % bigger than the the capacity of the turbine due to 'invest_relation_input_output=1.1'. """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage5", inputs={ - bel: solph.flows.Flow( + bel: solph.Flow( investment=solph.Investment(ep_costs=99, existing=110) ) }, outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( investment=solph.Investment(existing=100) ) }, @@ -419,17 +419,17 @@ def test_storage_invest_6(self): """Like test_storage_invest_5 but there can also be an investment in the basin. """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage6", inputs={ - bel: solph.flows.Flow( + bel: solph.Flow( investment=solph.Investment(ep_costs=99, existing=110) ) }, outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( investment=solph.Investment(existing=100) ) }, @@ -443,12 +443,12 @@ def test_storage_minimum_invest(self): """All invest variables are coupled. The invest variables of the Flows will be created during the initialisation of the storage e.g. battery """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage1", - inputs={bel: solph.flows.Flow()}, - outputs={bel: solph.flows.Flow()}, + inputs={bel: solph.Flow()}, + outputs={bel: solph.Flow()}, investment=solph.Investment( ep_costs=145, minimum=100, maximum=200 ), @@ -459,12 +459,12 @@ def test_storage_minimum_invest(self): def test_storage_unbalanced(self): """Testing a unbalanced storage (e.g. battery).""" - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage1", - inputs={bel: solph.flows.Flow()}, - outputs={bel: solph.flows.Flow()}, + inputs={bel: solph.Flow()}, + outputs={bel: solph.Flow()}, nominal_storage_capacity=1111, initial_storage_level=None, balanced=False, @@ -476,12 +476,12 @@ def test_storage_unbalanced(self): def test_storage_invest_unbalanced(self): """Testing a unbalanced storage (e.g. battery).""" - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage1", - inputs={bel: solph.flows.Flow()}, - outputs={bel: solph.flows.Flow()}, + inputs={bel: solph.Flow()}, + outputs={bel: solph.Flow()}, nominal_storage_capacity=None, initial_storage_level=0.5, balanced=False, @@ -494,15 +494,15 @@ def test_storage_invest_unbalanced(self): def test_storage_fixed_losses(self): """ """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage_no_invest", inputs={ - bel: solph.flows.Flow(nominal_value=16667, variable_costs=56) + bel: solph.Flow(nominal_value=16667, variable_costs=56) }, outputs={ - bel: solph.flows.Flow(nominal_value=16667, variable_costs=24) + bel: solph.Flow(nominal_value=16667, variable_costs=24) }, nominal_storage_capacity=1e5, loss_rate=0.13, @@ -520,12 +520,12 @@ def test_storage_invest_1_fixed_losses(self): """All invest variables are coupled. The invest variables of the Flows will be created during the initialisation of the storage e.g. battery """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage1", - inputs={bel: solph.flows.Flow(variable_costs=56)}, - outputs={bel: solph.flows.Flow(variable_costs=24)}, + inputs={bel: solph.Flow(variable_costs=56)}, + outputs={bel: solph.Flow(variable_costs=24)}, nominal_storage_capacity=None, loss_rate=0.13, fixed_losses_relative=0.01, @@ -544,17 +544,17 @@ def test_storage_invest_1_fixed_losses(self): def test_transformer(self): """Constraint test of a LinearN1Transformer without Investment.""" - bgas = solph.buses.Bus(label="gasBus") - bbms = solph.buses.Bus(label="biomassBus") - bel = solph.buses.Bus(label="electricityBus") - bth = solph.buses.Bus(label="thermalBus") + bgas = solph.Bus(label="gasBus") + bbms = solph.Bus(label="biomassBus") + bel = solph.Bus(label="electricityBus") + bth = solph.Bus(label="thermalBus") - transformer = solph.components.Transformer( + transformer = solph.Transformer( label="powerplantGasCoal", - inputs={bbms: solph.flows.Flow(), bgas: solph.flows.Flow()}, + inputs={bbms: solph.Flow(), bgas: solph.Flow()}, outputs={ - bel: solph.flows.Flow(variable_costs=50), - bth: solph.flows.Flow(nominal_value=5e10, variable_costs=20), + bel: solph.Flow(variable_costs=50), + bth: solph.Flow(nominal_value=5e10, variable_costs=20), }, conversion_factors={bgas: 0.4, bbms: 0.1, bel: 0.3, bth: 0.5}, ) @@ -566,20 +566,20 @@ def test_transformer(self): def test_transformer_invest(self): """Constraint test of a LinearN1Transformer with Investment.""" - bgas = solph.buses.Bus(label="gasBus") - bcoal = solph.buses.Bus(label="coalBus") - bel = solph.buses.Bus(label="electricityBus") - bth = solph.buses.Bus(label="thermalBus") + bgas = solph.Bus(label="gasBus") + bcoal = solph.Bus(label="coalBus") + bel = solph.Bus(label="electricityBus") + bth = solph.Bus(label="thermalBus") - transformer = solph.components.Transformer( + transformer = solph.Transformer( label="powerplant_gas_coal", - inputs={bgas: solph.flows.Flow(), bcoal: solph.flows.Flow()}, + inputs={bgas: solph.Flow(), bcoal: solph.Flow()}, outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( variable_costs=50, investment=solph.Investment(maximum=1000, ep_costs=20), ), - bth: solph.flows.Flow(variable_costs=20), + bth: solph.Flow(variable_costs=20), }, conversion_factors={bgas: 0.58, bcoal: 0.2, bel: 0.3, bth: 0.5}, ) @@ -590,22 +590,22 @@ def test_transformer_invest(self): def test_transformer_invest_with_existing(self): """Constraint test of a LinearN1Transformer with Investment.""" - bgas = solph.buses.Bus(label="gasBus") - bcoal = solph.buses.Bus(label="coalBus") - bel = solph.buses.Bus(label="electricityBus") - bth = solph.buses.Bus(label="thermalBus") + bgas = solph.Bus(label="gasBus") + bcoal = solph.Bus(label="coalBus") + bel = solph.Bus(label="electricityBus") + bth = solph.Bus(label="thermalBus") - transformer = solph.components.Transformer( + transformer = solph.Transformer( label="powerplant_gas_coal", - inputs={bgas: solph.flows.Flow(), bcoal: solph.flows.Flow()}, + inputs={bgas: solph.Flow(), bcoal: solph.Flow()}, outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( variable_costs=50, investment=solph.Investment( maximum=1000, ep_costs=20, existing=200 ), ), - bth: solph.flows.Flow(variable_costs=20), + bth: solph.Flow(variable_costs=20), }, conversion_factors={bgas: 0.58, bcoal: 0.2, bel: 0.3, bth: 0.5}, ) @@ -617,16 +617,16 @@ def test_linear_transformer_chp(self): """ Constraint test of a Transformer without Investment (two outputs). """ - bgas = solph.buses.Bus(label="gasBus") - bheat = solph.buses.Bus(label="heatBus") - bel = solph.buses.Bus(label="electricityBus") + bgas = solph.Bus(label="gasBus") + bheat = solph.Bus(label="heatBus") + bel = solph.Bus(label="electricityBus") - transformer = solph.components.Transformer( + transformer = solph.Transformer( label="CHPpowerplantGas", inputs={ - bgas: solph.flows.Flow(nominal_value=10e10, variable_costs=50) + bgas: solph.Flow(nominal_value=10e10, variable_costs=50) }, - outputs={bel: solph.flows.Flow(), bheat: solph.flows.Flow()}, + outputs={bel: solph.Flow(), bheat: solph.Flow()}, conversion_factors={bel: 0.4, bheat: 0.5}, ) self.energysystem.add(bgas, bheat, bel, transformer) @@ -636,19 +636,19 @@ def test_linear_transformer_chp(self): def test_linear_transformer_chp_invest(self): """Constraint test of a Transformer with Investment (two outputs).""" - bgas = solph.buses.Bus(label="gasBus") - bheat = solph.buses.Bus(label="heatBus") - bel = solph.buses.Bus(label="electricityBus") + bgas = solph.Bus(label="gasBus") + bheat = solph.Bus(label="heatBus") + bel = solph.Bus(label="electricityBus") - transformer = solph.components.Transformer( + transformer = solph.Transformer( label="chp_powerplant_gas", inputs={ - bgas: solph.flows.Flow( + bgas: solph.Flow( variable_costs=50, investment=solph.Investment(maximum=1000, ep_costs=20), ) }, - outputs={bel: solph.flows.Flow(), bheat: solph.flows.Flow()}, + outputs={bel: solph.Flow(), bheat: solph.Flow()}, conversion_factors={bel: 0.4, bheat: 0.5}, ) self.energysystem.add(bgas, bheat, bel, transformer) @@ -673,22 +673,22 @@ def test_link(self): def test_variable_chp(self): """ """ - bel = solph.buses.Bus(label="electricityBus") - bth = solph.buses.Bus(label="heatBus") - bgas = solph.buses.Bus(label="commodityBus") + bel = solph.Bus(label="electricityBus") + bth = solph.Bus(label="heatBus") + bgas = solph.Bus(label="commodityBus") - chp1 = solph.components.ExtractionTurbineCHP( + chp1 = solph.ExtractionTurbineCHP( label="variable_chp_gas1", - inputs={bgas: solph.flows.Flow(nominal_value=100)}, - outputs={bel: solph.flows.Flow(), bth: solph.flows.Flow()}, + inputs={bgas: solph.Flow(nominal_value=100)}, + outputs={bel: solph.Flow(), bth: solph.Flow()}, conversion_factors={bel: 0.3, bth: 0.5}, conversion_factor_full_condensation={bel: 0.5}, ) - chp2 = solph.components.ExtractionTurbineCHP( + chp2 = solph.ExtractionTurbineCHP( label="variable_chp_gas2", - inputs={bgas: solph.flows.Flow(nominal_value=100)}, - outputs={bel: solph.flows.Flow(), bth: solph.flows.Flow()}, + inputs={bgas: solph.Flow(nominal_value=100)}, + outputs={bel: solph.Flow(), bth: solph.Flow()}, conversion_factors={bel: 0.3, bth: 0.5}, conversion_factor_full_condensation={bel: 0.5}, ) @@ -698,30 +698,30 @@ def test_variable_chp(self): def test_generic_invest_limit(self): """ """ - bus = solph.buses.Bus(label="bus_1") + bus = solph.Bus(label="bus_1") - source_0 = solph.components.Source( + source_0 = solph.Source( label="source_0", outputs={ - bus: solph.flows.Flow( + bus: solph.Flow( investment=solph.Investment(ep_costs=50, space=4) ) }, ) - source_1 = solph.components.Source( + source_1 = solph.Source( label="source_1", outputs={ - bus: solph.flows.Flow( + bus: solph.Flow( investment=solph.Investment(ep_costs=100, space=1) ) }, ) - source_2 = solph.components.Source( + source_2 = solph.Source( label="source_2", outputs={ - bus: solph.flows.Flow(investment=solph.Investment(ep_costs=75)) + bus: solph.Flow(investment=solph.Investment(ep_costs=75)) }, ) @@ -737,26 +737,26 @@ def test_generic_invest_limit(self): def test_emission_constraints(self): """ """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - source1 = solph.components.Source( + source1 = solph.Source( label="source1", outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( nominal_value=100, emission_factor=[0.5, -1.0, 2.0] ) }, ) - source2 = solph.components.Source( + source2 = solph.Source( label="source2", outputs={ - bel: solph.flows.Flow(nominal_value=100, emission_factor=3.5) + bel: solph.Flow(nominal_value=100, emission_factor=3.5) }, ) # Should be ignored because the emission attribute is not defined. - source3 = solph.components.Source( - label="source3", outputs={bel: solph.flows.Flow(nominal_value=100)} + source3 = solph.Source( + label="source3", outputs={bel: solph.Flow(nominal_value=100)} ) self.energysystem.add(bel, source1, source2, source3) @@ -769,22 +769,22 @@ def test_emission_constraints(self): def test_flow_count_limit(self): """ """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - source1 = solph.components.Source( + source1 = solph.Source( label="source1", outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( nonconvex=solph.NonConvex(), nominal_value=100, emission_factor=[0.5, -1.0, 2.0], ) }, ) - source2 = solph.components.Source( + source2 = solph.Source( label="source2", outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( nonconvex=solph.NonConvex(), nominal_value=100, emission_factor=3.5, @@ -793,20 +793,20 @@ def test_flow_count_limit(self): ) # Should be ignored because emission_factor is not defined. - source3 = solph.components.Source( + source3 = solph.Source( label="source3", outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( nonconvex=solph.NonConvex(), nominal_value=100 ) }, ) # Should be ignored because it is not NonConvex. - source4 = solph.components.Source( + source4 = solph.Source( label="source4", outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( emission_factor=1.5, min=0.3, nominal_value=100 ) }, @@ -825,19 +825,19 @@ def test_flow_count_limit(self): def test_shared_limit(self): """ """ - b1 = solph.buses.Bus(label="bus") + b1 = solph.Bus(label="bus") - storage1 = solph.components.GenericStorage( + storage1 = solph.GenericStorage( label="storage1", nominal_storage_capacity=5, - inputs={b1: solph.flows.Flow()}, - outputs={b1: solph.flows.Flow()}, + inputs={b1: solph.Flow()}, + outputs={b1: solph.Flow()}, ) - storage2 = solph.components.GenericStorage( + storage2 = solph.GenericStorage( label="storage2", nominal_storage_capacity=5, - inputs={b1: solph.flows.Flow()}, - outputs={b1: solph.flows.Flow()}, + inputs={b1: solph.Flow()}, + outputs={b1: solph.Flow()}, ) self.energysystem.add(b1, storage1, storage2) @@ -861,18 +861,18 @@ def test_flow_without_emission_for_emission_constraint(self): """ """ def define_emission_limit(): - bel = solph.buses.Bus(label="electricityBus") - source1 = solph.components.Source( + bel = solph.Bus(label="electricityBus") + source1 = solph.Source( label="source1", outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( nominal_value=100, emission_factor=0.8 ) }, ) - source2 = solph.components.Source( + source2 = solph.Source( label="source2", - outputs={bel: solph.flows.Flow(nominal_value=100)}, + outputs={bel: solph.Flow(nominal_value=100)}, ) self.energysystem.add(bel, source1, source2) om = self.get_om() @@ -882,15 +882,15 @@ def define_emission_limit(): def test_flow_without_emission_for_emission_constraint_no_error(self): """ """ - bel = solph.buses.Bus(label="electricityBus") - source1 = solph.components.Source( + bel = solph.Bus(label="electricityBus") + source1 = solph.Source( label="source1", outputs={ - bel: solph.flows.Flow(nominal_value=100, emission_factor=0.8) + bel: solph.Flow(nominal_value=100, emission_factor=0.8) }, ) - source2 = solph.components.Source( - label="source2", outputs={bel: solph.flows.Flow(nominal_value=100)} + source2 = solph.Source( + label="source2", outputs={bel: solph.Flow(nominal_value=100)} ) self.energysystem.add(bel, source1, source2) om = self.get_om() @@ -898,27 +898,27 @@ def test_flow_without_emission_for_emission_constraint_no_error(self): def test_equate_variables_constraint(self): """Testing the equate_variables function in the constraint module.""" - bus1 = solph.buses.Bus(label="Bus1") - storage = solph.components.GenericStorage( + bus1 = solph.Bus(label="Bus1") + storage = solph.GenericStorage( label="storage_constraint", invest_relation_input_capacity=0.2, invest_relation_output_capacity=0.2, - inputs={bus1: solph.flows.Flow()}, - outputs={bus1: solph.flows.Flow()}, + inputs={bus1: solph.Flow()}, + outputs={bus1: solph.Flow()}, investment=solph.Investment(ep_costs=145), ) - sink = solph.components.Sink( + sink = solph.Sink( label="Sink", inputs={ - bus1: solph.flows.Flow( + bus1: solph.Flow( investment=solph.Investment(ep_costs=500) ) }, ) - source = solph.components.Source( + source = solph.Source( label="Source", outputs={ - bus1: solph.flows.Flow( + bus1: solph.Flow( investment=solph.Investment(ep_costs=123) ) }, @@ -927,13 +927,13 @@ def test_equate_variables_constraint(self): om = self.get_om() solph.constraints.equate_variables( om, - om.InvestmentFlowBlock.invest[source, bus1], - om.InvestmentFlowBlock.invest[bus1, sink], + om.InvestmentFlow.invest[source, bus1], + om.InvestmentFlow.invest[bus1, sink], 2, ) solph.constraints.equate_variables( om, - om.InvestmentFlowBlock.invest[source, bus1], + om.InvestmentFlow.invest[source, bus1], om.GenericInvestmentStorageBlock.invest[storage], ) @@ -941,12 +941,12 @@ def test_equate_variables_constraint(self): def test_gradient(self): """Testing gradient constraints and costs.""" - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - pp = solph.components.Source( + pp = solph.Source( label="powerplant", outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( nominal_value=999, variable_costs=23, positive_gradient={"ub": 0.03}, @@ -960,17 +960,17 @@ def test_gradient(self): def test_nonconvex_gradient(self): """Testing gradient constraints and costs.""" - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - pp = solph.components.Source( + pp = solph.Source( label="powerplant", outputs={ - bel: solph.flows.Flow( + bel: solph.Flow( nominal_value=999, variable_costs=23, nonconvex=solph.NonConvex( - positive_gradient={"ub": 0.03}, - negative_gradient={"ub": 0.05}, + positive_gradient={"ub": 0.03, "costs": 7}, + negative_gradient={"ub": 0.05, "costs": 8}, ), ) }, @@ -1013,19 +1013,19 @@ def test_nonconvex_negative_gradient_error(self): def test_investment_limit(self): """Testing the investment_limit function in the constraint module.""" - bus1 = solph.buses.Bus(label="Bus1") - storage = solph.components.GenericStorage( + bus1 = solph.Bus(label="Bus1") + storage = solph.GenericStorage( label="storage_invest_limit", invest_relation_input_capacity=0.2, invest_relation_output_capacity=0.2, - inputs={bus1: solph.flows.Flow()}, - outputs={bus1: solph.flows.Flow()}, + inputs={bus1: solph.Flow()}, + outputs={bus1: solph.Flow()}, investment=solph.Investment(ep_costs=145), ) - source = solph.components.Source( + source = solph.Source( label="Source", outputs={ - bus1: solph.flows.Flow( + bus1: solph.Flow( investment=solph.Investment(ep_costs=123) ) }, @@ -1038,11 +1038,11 @@ def test_investment_limit(self): def test_min_max_runtime(self): """Testing min and max runtimes for nonconvex flows.""" - bus_t = solph.buses.Bus(label="Bus_T") - pp = solph.components.Source( + bus_t = solph.Bus(label="Bus_T") + pp = solph.Source( label="cheap_plant_min_down_constraints", outputs={ - bus_t: solph.flows.Flow( + bus_t: solph.Flow( nominal_value=10, min=0.5, max=1.0, @@ -1063,11 +1063,11 @@ def test_min_max_runtime(self): def test_activity_costs(self): """Testing activity_costs attribute for nonconvex flows.""" - bus_t = solph.buses.Bus(label="Bus_C") - pp = solph.components.Source( + bus_t = solph.Bus(label="Bus_C") + pp = solph.Source( label="cheap_plant_activity_costs", outputs={ - bus_t: solph.flows.Flow( + bus_t: solph.Flow( nominal_value=10, min=0.5, max=1.0, @@ -1082,14 +1082,14 @@ def test_activity_costs(self): def test_piecewise_linear_transformer_cc(self): """Testing PiecewiseLinearTransformer using CC formulation.""" - bgas = solph.buses.Bus(label="gasBus") - bel = solph.buses.Bus(label="electricityBus") - plt = solph.components.experimental.PiecewiseLinearTransformer( + bgas = solph.Bus(label="gasBus") + bel = solph.Bus(label="electricityBus") + plt = solph.custom.PiecewiseLinearTransformer( label="pwltf", inputs={ - bgas: solph.flows.Flow(nominal_value=100, variable_costs=1) + bgas: solph.Flow(nominal_value=100, variable_costs=1) }, - outputs={bel: solph.flows.Flow()}, + outputs={bel: solph.Flow()}, in_breakpoints=[0, 25, 50, 75, 100], conversion_function=lambda x: x**2, pw_repn="CC", @@ -1100,14 +1100,14 @@ def test_piecewise_linear_transformer_cc(self): def test_piecewise_linear_transformer_dcc(self): """Testing PiecewiseLinearTransformer using DCC formulation.""" - bgas = solph.buses.Bus(label="gasBus") - bel = solph.buses.Bus(label="electricityBus") - plt = solph.components.experimental.PiecewiseLinearTransformer( + bgas = solph.Bus(label="gasBus") + bel = solph.Bus(label="electricityBus") + plt = solph.custom.PiecewiseLinearTransformer( label="pwltf", inputs={ - bgas: solph.flows.Flow(nominal_value=100, variable_costs=1) + bgas: solph.Flow(nominal_value=100, variable_costs=1) }, - outputs={bel: solph.flows.Flow()}, + outputs={bel: solph.Flow()}, in_breakpoints=[0, 25, 50, 75, 100], conversion_function=lambda x: x**2, pw_repn="DCC", @@ -1117,11 +1117,11 @@ def test_piecewise_linear_transformer_dcc(self): def test_maximum_startups(self): """Testing maximum_startups attribute for nonconvex flows.""" - bus_t = solph.buses.Bus(label="Bus_C") - pp = solph.components.Source( + bus_t = solph.Bus(label="Bus_C") + pp = solph.Source( label="cheap_plant_maximum_startups", outputs={ - bus_t: solph.flows.Flow( + bus_t: solph.Flow( nominal_value=10, min=0.5, max=1.0, @@ -1135,11 +1135,11 @@ def test_maximum_startups(self): def test_maximum_shutdowns(self): """Testing maximum_shutdowns attribute for nonconvex flows.""" - bus_t = solph.buses.Bus(label="Bus_C") - pp = solph.components.Source( + bus_t = solph.Bus(label="Bus_C") + pp = solph.Source( label="cheap_plant_maximum_shutdowns", outputs={ - bus_t: solph.flows.Flow( + bus_t: solph.Flow( nominal_value=10, min=0.5, max=1.0, @@ -1153,19 +1153,19 @@ def test_maximum_shutdowns(self): def test_offsettransformer(self): """Constraint test of a OffsetTransformer.""" - bgas = solph.buses.Bus(label="gasBus") - bth = solph.buses.Bus(label="thermalBus") + bgas = solph.Bus(label="gasBus") + bth = solph.Bus(label="thermalBus") - transformer = solph.components.OffsetTransformer( + transformer = solph.OffsetTransformer( label="gasboiler", inputs={ - bgas: solph.flows.Flow( + bgas: solph.Flow( nonconvex=solph.NonConvex(), nominal_value=100, min=0.32, ) }, - outputs={bth: solph.flows.Flow()}, + outputs={bth: solph.Flow()}, coefficients=[-17, 0.9], ) self.energysystem.add(bgas, bth, transformer) @@ -1175,10 +1175,10 @@ def test_offsettransformer(self): def test_dsm_module_DIW(self): """Constraint test of SinkDSM with approach=DLR""" - b_elec = solph.buses.Bus(label="bus_elec") - sink = solph.components.experimental.SinkDSM( + b_elec = solph.Bus(label="bus_elec") + sink = solph.custom.SinkDSM( label="demand_dsm", - inputs={b_elec: solph.flows.Flow()}, + inputs={b_elec: solph.Flow()}, demand=[1] * 3, capacity_up=[0.5] * 3, capacity_down=[0.5] * 3, @@ -1197,10 +1197,10 @@ def test_dsm_module_DIW(self): def test_dsm_module_DLR(self): """Constraint test of SinkDSM with approach=DLR""" - b_elec = solph.buses.Bus(label="bus_elec") - sink = solph.components.experimental.SinkDSM( + b_elec = solph.Bus(label="bus_elec") + sink = solph.custom.SinkDSM( label="demand_dsm", - inputs={b_elec: solph.flows.Flow()}, + inputs={b_elec: solph.Flow()}, demand=[1] * 3, capacity_up=[0.5] * 3, capacity_down=[0.5] * 3, @@ -1219,10 +1219,10 @@ def test_dsm_module_DLR(self): def test_dsm_module_oemof(self): """Constraint test of SinkDSM with approach=oemof""" - b_elec = solph.buses.Bus(label="bus_elec") - sink = solph.components.experimental.SinkDSM( + b_elec = solph.Bus(label="bus_elec") + sink = solph.custom.SinkDSM( label="demand_dsm", - inputs={b_elec: solph.flows.Flow()}, + inputs={b_elec: solph.Flow()}, demand=[1] * 3, capacity_up=[0.5, 0.4, 0.5], capacity_down=[0.5, 0.4, 0.5], @@ -1240,10 +1240,10 @@ def test_dsm_module_oemof(self): def test_dsm_module_DIW_invest(self): """Constraint test of SinkDSM with approach=DLR and investments""" - b_elec = solph.buses.Bus(label="bus_elec") - sink = solph.components.experimental.SinkDSM( + b_elec = solph.Bus(label="bus_elec") + sink = solph.custom.SinkDSM( label="demand_dsm", - inputs={b_elec: solph.flows.Flow()}, + inputs={b_elec: solph.Flow()}, demand=[1] * 3, capacity_up=[0.5] * 3, capacity_down=[0.5] * 3, @@ -1263,10 +1263,10 @@ def test_dsm_module_DIW_invest(self): def test_dsm_module_DLR_invest(self): """Constraint test of SinkDSM with approach=DLR and investments""" - b_elec = solph.buses.Bus(label="bus_elec") - sink = solph.components.experimental.SinkDSM( + b_elec = solph.Bus(label="bus_elec") + sink = solph.custom.SinkDSM( label="demand_dsm", - inputs={b_elec: solph.flows.Flow()}, + inputs={b_elec: solph.Flow()}, demand=[1] * 3, capacity_up=[0.5] * 3, capacity_down=[0.5] * 3, @@ -1287,10 +1287,10 @@ def test_dsm_module_DLR_invest(self): def test_dsm_module_oemof_invest(self): """Constraint test of SinkDSM with approach=oemof and investments""" - b_elec = solph.buses.Bus(label="bus_elec") - sink = solph.components.experimental.SinkDSM( + b_elec = solph.Bus(label="bus_elec") + sink = solph.custom.SinkDSM( label="demand_dsm", - inputs={b_elec: solph.flows.Flow()}, + inputs={b_elec: solph.Flow()}, demand=[1] * 3, capacity_up=[0.5, 0.4, 0.5], capacity_down=[0.5, 0.4, 0.5], @@ -1311,12 +1311,12 @@ def test_nonconvex_investment_storage_without_offset(self): """All invest variables are coupled. The invest variables of the Flows will be created during the initialisation of the storage e.g. battery """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage_non_convex", - inputs={bel: solph.flows.Flow(variable_costs=56)}, - outputs={bel: solph.flows.Flow(variable_costs=24)}, + inputs={bel: solph.Flow(variable_costs=56)}, + outputs={bel: solph.Flow(variable_costs=24)}, nominal_storage_capacity=None, loss_rate=0.13, max_storage_level=0.9, @@ -1337,12 +1337,12 @@ def test_nonconvex_investment_storage_with_offset(self): """All invest variables are coupled. The invest variables of the Flows will be created during the initialisation of the storage e.g. battery """ - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storagenon_convex", - inputs={bel: solph.flows.Flow(variable_costs=56)}, - outputs={bel: solph.flows.Flow(variable_costs=24)}, + inputs={bel: solph.Flow(variable_costs=56)}, + outputs={bel: solph.Flow(variable_costs=24)}, nominal_storage_capacity=None, loss_rate=0.13, max_storage_level=0.9, @@ -1365,12 +1365,12 @@ def test_nonconvex_investment_storage_with_offset(self): def test_nonconvex_invest_storage_all_nonconvex(self): """All invest variables are free and nonconvex.""" - b1 = solph.buses.Bus(label="bus1") + b1 = solph.Bus(label="bus1") - storage = solph.components.GenericStorage( + storage = solph.GenericStorage( label="storage_all_nonconvex", inputs={ - b1: solph.flows.Flow( + b1: solph.Flow( investment=solph.Investment( nonconvex=True, minimum=5, @@ -1381,7 +1381,7 @@ def test_nonconvex_invest_storage_all_nonconvex(self): ) }, outputs={ - b1: solph.flows.Flow( + b1: solph.Flow( investment=solph.Investment( nonconvex=True, minimum=8, @@ -1401,12 +1401,12 @@ def test_nonconvex_invest_storage_all_nonconvex(self): def test_nonconvex_invest_sink_without_offset(self): """Non-convex invest flow without offset, with minimum.""" - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - sink = solph.components.Sink( + sink = solph.Sink( label="sink_nonconvex_invest", inputs={ - bel: solph.flows.Flow( + bel: solph.Flow( full_load_time_max=2.3, variable_costs=25, max=0.8, @@ -1421,12 +1421,12 @@ def test_nonconvex_invest_sink_without_offset(self): def test_nonconvex_invest_source_with_offset(self): """Non-convex invest flow with offset, with minimum.""" - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - source = solph.components.Source( + source = solph.Source( label="source_nonconvex_invest", inputs={ - bel: solph.flows.Flow( + bel: solph.Flow( full_load_time_max=2.3, variable_costs=25, max=0.8, @@ -1445,12 +1445,12 @@ def test_nonconvex_invest_source_with_offset(self): def test_nonconvex_invest_source_with_offset_no_minimum(self): """Non-convex invest flow with offset, without minimum.""" - bel = solph.buses.Bus(label="electricityBus") + bel = solph.Bus(label="electricityBus") - source = solph.components.Source( + source = solph.Source( label="source_nonconvex_invest", inputs={ - bel: solph.flows.Flow( + bel: solph.Flow( full_load_time_max=2.3, variable_costs=25, max=0.8, From 1db90d15bac32ae28ec77c84066d1f524ac0b9a0 Mon Sep 17 00:00:00 2001 From: jnnr <32454596+jnnr@users.noreply.github.com> Date: Wed, 21 Dec 2022 18:03:05 +0100 Subject: [PATCH 48/58] Fix failing lp comparisons --- tests/constraint_tests.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/constraint_tests.py b/tests/constraint_tests.py index d858616e9..a7dcaab89 100644 --- a/tests/constraint_tests.py +++ b/tests/constraint_tests.py @@ -237,7 +237,7 @@ def test_nominal_value_to_zero(self): def test_fixed_source_invest_sink(self): """ Wrong constraints for fixed source + invest sink w. - `full_load_time_max`. + `summed_max`. """ bel = solph.Bus(label="electricityBus") @@ -253,7 +253,7 @@ def test_fixed_source_invest_sink(self): label="excess", inputs={ bel: solph.Flow( - full_load_time_max=2.3, + summed_max=2.3, variable_costs=25, max=0.8, investment=solph.Investment( @@ -659,7 +659,7 @@ def test_link(self): bel0 = solph.Bus(label="bel0") bel1 = solph.Bus(label="bel1") - solph.custom.Link( + link = solph.custom.Link( label="link", inputs={ bel0: solph.Flow(nominal_value=4), @@ -668,6 +668,7 @@ def test_link(self): outputs={bel0: solph.Flow(), bel1: solph.Flow()}, conversion_factors={(bel0, bel1): 0.8, (bel1, bel0): 0.9}, ) + self.energysystem.add(bel0, bel1, link) self.compare_lp_files("link.lp") @@ -1407,7 +1408,7 @@ def test_nonconvex_invest_sink_without_offset(self): label="sink_nonconvex_invest", inputs={ bel: solph.Flow( - full_load_time_max=2.3, + summed_max=2.3, variable_costs=25, max=0.8, investment=solph.Investment( @@ -1427,7 +1428,7 @@ def test_nonconvex_invest_source_with_offset(self): label="source_nonconvex_invest", inputs={ bel: solph.Flow( - full_load_time_max=2.3, + summed_max=2.3, variable_costs=25, max=0.8, investment=solph.Investment( @@ -1451,7 +1452,7 @@ def test_nonconvex_invest_source_with_offset_no_minimum(self): label="source_nonconvex_invest", inputs={ bel: solph.Flow( - full_load_time_max=2.3, + summed_max=2.3, variable_costs=25, max=0.8, investment=solph.Investment( From 5e8bfbfc8c72cb8585066f4cb3b66bd512a662c8 Mon Sep 17 00:00:00 2001 From: jnnr <32454596+jnnr@users.noreply.github.com> Date: Mon, 9 Jan 2023 15:44:17 +0100 Subject: [PATCH 49/58] Remove Node.registry from tests --- tests/solph_tests.py | 7 +-- .../test_connect_invest.py | 11 ++--- .../test_add_constraints.py | 8 ++-- .../test_generic_caes/test_generic_caes.py | 11 ++--- .../test_generic_chp/test_generic_chp.py | 13 +++--- .../test_simple_invest_fixed.py | 2 - .../test_simple_dispatch_one.py | 2 - .../test_simple_model/test_simple_invest.py | 1 - .../test_invest_storage_regression.py | 11 ++--- .../test_storage_investment.py | 25 ++++++++--- .../test_storage_with_tuple_label.py | 27 ++++++++---- .../test_variable_chp/test_variable_chp.py | 43 +++++++++++++------ 12 files changed, 102 insertions(+), 59 deletions(-) diff --git a/tests/solph_tests.py b/tests/solph_tests.py index 8dc447e93..1ca8ee5f1 100644 --- a/tests/solph_tests.py +++ b/tests/solph_tests.py @@ -24,7 +24,6 @@ class TestsGrouping: def setup(self): self.es = EnSys(groupings=solph.GROUPINGS) - Node.registry = self.es def test_investment_flow_grouping(self): """Flows of investment sink should be grouped. @@ -41,12 +40,12 @@ def test_investment_flow_grouping(self): b = solph.Bus(label="Bus") - solph.Source( + source = solph.Source( label="Source", outputs={b: solph.Flow(fix=[12, 16, 14], nominal_value=1000000)}, ) - solph.Sink( + sink = solph.Sink( label="Sink", inputs={ b: solph.Flow( @@ -58,6 +57,8 @@ def test_investment_flow_grouping(self): }, ) + self.es.add(source, sink) + ok_( self.es.groups.get(InvFlow), ( diff --git a/tests/test_scripts/test_solph/test_connect_invest/test_connect_invest.py b/tests/test_scripts/test_solph/test_connect_invest/test_connect_invest.py index 792fc6665..f918d6ba0 100644 --- a/tests/test_scripts/test_solph/test_connect_invest/test_connect_invest.py +++ b/tests/test_scripts/test_solph/test_connect_invest/test_connect_invest.py @@ -35,7 +35,6 @@ def test_connect_invest(): date_time_index = pd.date_range("1/1/2012", periods=24 * 7, freq="H") energysystem = EnergySystem(timeindex=date_time_index) - network.Node.registry = energysystem # Read data file full_filename = os.path.join( @@ -50,17 +49,17 @@ def test_connect_invest(): bel2 = Bus(label="electricity2") # create excess component for the electricity bus to allow overproduction - Sink(label="excess_bel", inputs={bel2: Flow()}) - Source(label="shortage", outputs={bel2: Flow(variable_costs=50000)}) + excess_el = Sink(label="excess_bel", inputs={bel2: Flow()}) + shortage = Source(label="shortage", outputs={bel2: Flow(variable_costs=50000)}) # create fixed source object representing wind power plants - Source( + wind = Source( label="wind", outputs={bel1: Flow(fix=data["wind"], nominal_value=1000000)}, ) # create simple sink object representing the electrical demand - Sink( + demand = Sink( label="demand", inputs={bel1: Flow(fix=data["demand_el"], nominal_value=1)}, ) @@ -90,6 +89,8 @@ def test_connect_invest(): outputs={bel1: Flow(investment=Investment(ep_costs=20))}, ) + energysystem.add(bel1, bel2, excess_el, shortage, wind, demand, storage, line12, line21) + om = Model(energysystem) constraints.equate_variables( diff --git a/tests/test_scripts/test_solph/test_flexible_modelling/test_add_constraints.py b/tests/test_scripts/test_solph/test_flexible_modelling/test_add_constraints.py index 5cfaee4e6..22ad67e17 100644 --- a/tests/test_scripts/test_solph/test_flexible_modelling/test_add_constraints.py +++ b/tests/test_scripts/test_solph/test_flexible_modelling/test_add_constraints.py @@ -35,13 +35,13 @@ def test_add_constraints_example(solver="cbc", nologg=False): # ##### creating an oemof solph optimization model, nothing special here ## # create an energy system object for the oemof solph nodes es = EnergySystem(timeindex=pd.date_range("1/1/2012", periods=4, freq="H")) - Node.registry = es + # add some nodes boil = Bus(label="oil", balanced=False) blig = Bus(label="lignite", balanced=False) b_el = Bus(label="b_el") - Sink( + sink = Sink( label="Sink", inputs={b_el: Flow(nominal_value=40, fix=[0.5, 0.4, 0.3, 1])}, ) @@ -51,13 +51,15 @@ def test_add_constraints_example(solver="cbc", nologg=False): outputs={b_el: Flow(nominal_value=50, variable_costs=25)}, conversion_factors={b_el: 0.39}, ) - Transformer( + pp_lig = Transformer( label="pp_lig", inputs={blig: Flow()}, outputs={b_el: Flow(nominal_value=50, variable_costs=10)}, conversion_factors={b_el: 0.41}, ) + es.add(boil, blig, b_el, sink, pp_oil, pp_lig) + # create the model om = Model(energysystem=es) diff --git a/tests/test_scripts/test_solph/test_generic_caes/test_generic_caes.py b/tests/test_scripts/test_solph/test_generic_caes/test_generic_caes.py index 5d2b23c6d..48a0f3a0b 100644 --- a/tests/test_scripts/test_solph/test_generic_caes/test_generic_caes.py +++ b/tests/test_scripts/test_solph/test_generic_caes/test_generic_caes.py @@ -40,22 +40,21 @@ def test_gen_caes(): # create an energy system idx = pd.date_range("1/1/2017", periods=periods, freq="H") es = EnergySystem(timeindex=idx) - Node.registry = es # resources bgas = Bus(label="bgas") - Source(label="rgas", outputs={bgas: Flow(variable_costs=20)}) + rgas = Source(label="rgas", outputs={bgas: Flow(variable_costs=20)}) # power bel_source = Bus(label="bel_source") - Source( + source_el = Source( label="source_el", outputs={bel_source: Flow(variable_costs=data["price_el_source"])}, ) bel_sink = Bus(label="bel_sink") - Sink( + sink_el = Sink( label="sink_el", inputs={bel_sink: Flow(variable_costs=data["price_el_sink"])}, ) @@ -86,7 +85,7 @@ def test_gen_caes(): } # generic compressed air energy storage (caes) plant - custom.GenericCAES( + caes = custom.GenericCAES( label="caes", electrical_input={bel_source: Flow()}, fuel_input={bgas: Flow()}, @@ -95,6 +94,8 @@ def test_gen_caes(): fixed_costs=0, ) + es.add(bgas, rgas, bel_source, source_el, bel_sink, sink_el, caes) + # create an optimization problem and solve it om = Model(es) diff --git a/tests/test_scripts/test_solph/test_generic_chp/test_generic_chp.py b/tests/test_scripts/test_solph/test_generic_chp/test_generic_chp.py index 5fbe293ff..47fb77925 100644 --- a/tests/test_scripts/test_solph/test_generic_chp/test_generic_chp.py +++ b/tests/test_scripts/test_solph/test_generic_chp/test_generic_chp.py @@ -34,21 +34,20 @@ def test_gen_chp(): # create an energy system idx = pd.date_range("1/1/2017", periods=periods, freq="H") es = solph.EnergySystem(timeindex=idx) - Node.registry = es # resources bgas = solph.Bus(label="bgas") - solph.Source(label="rgas", outputs={bgas: solph.Flow()}) + rgas = solph.Source(label="rgas", outputs={bgas: solph.Flow()}) # heat bth = solph.Bus(label="bth") - solph.Source( + source_th = solph.Source( label="source_th", outputs={bth: solph.Flow(variable_costs=1000)} ) - solph.Sink( + demand_th = solph.Sink( label="demand_th", inputs={bth: solph.Flow(fix=data["demand_th"], nominal_value=200)}, ) @@ -56,14 +55,14 @@ def test_gen_chp(): # power bel = solph.Bus(label="bel") - solph.Sink( + demand_el = solph.Sink( label="demand_el", inputs={bel: solph.Flow(variable_costs=data["price_el"])}, ) # generic chp # (for back pressure characteristics Q_CW_min=0 and back_pressure=True) - solph.components.GenericCHP( + ccet = solph.components.GenericCHP( label="combined_cycle_extraction_turbine", fuel_input={ bgas: solph.Flow(H_L_FG_share_max=data["H_L_FG_share_max"]) @@ -81,6 +80,8 @@ def test_gen_chp(): back_pressure=False, ) + es.add(bgas, rgas, bth, source_th, demand_th, bel, demand_el, ccet) + # create an optimization problem and solve it om = solph.Model(es) diff --git a/tests/test_scripts/test_solph/test_invest_fix_flow/test_simple_invest_fixed.py b/tests/test_scripts/test_solph/test_invest_fix_flow/test_simple_invest_fixed.py index 0a2c4ff37..99b1c04d4 100644 --- a/tests/test_scripts/test_solph/test_invest_fix_flow/test_simple_invest_fixed.py +++ b/tests/test_scripts/test_solph/test_invest_fix_flow/test_simple_invest_fixed.py @@ -31,8 +31,6 @@ def test_dispatch_fix_example(solver="cbc", periods=10): """Invest in a flow with a `fix` sequence containing values > 1.""" - Node.registry = None - filename = os.path.join(os.path.dirname(__file__), "input_data.csv") data = pd.read_csv(filename, sep=",") diff --git a/tests/test_scripts/test_solph/test_simple_model/test_simple_dispatch_one.py b/tests/test_scripts/test_solph/test_simple_model/test_simple_dispatch_one.py index 1088fb5ee..5dbcd3862 100644 --- a/tests/test_scripts/test_solph/test_simple_model/test_simple_dispatch_one.py +++ b/tests/test_scripts/test_solph/test_simple_model/test_simple_dispatch_one.py @@ -29,8 +29,6 @@ def test_dispatch_one_time_step(solver="cbc"): """Create an energy system and optimize the dispatch at least costs.""" # ######################### create energysystem components ################ - Node.registry = None - # resource buses bgas = Bus(label="gas", balanced=False) diff --git a/tests/test_scripts/test_solph/test_simple_model/test_simple_invest.py b/tests/test_scripts/test_solph/test_simple_model/test_simple_invest.py index 7c2b37096..52047b80e 100644 --- a/tests/test_scripts/test_solph/test_simple_model/test_simple_invest.py +++ b/tests/test_scripts/test_solph/test_simple_model/test_simple_invest.py @@ -34,7 +34,6 @@ def test_dispatch_example(solver="cbc", periods=24 * 5): """Create an energy system and optimize the dispatch at least costs.""" - Node.registry = None filename = os.path.join(os.path.dirname(__file__), "input_data.csv") data = pd.read_csv(filename, sep=",") diff --git a/tests/test_scripts/test_solph/test_storage_investment/test_invest_storage_regression.py b/tests/test_scripts/test_solph/test_storage_investment/test_invest_storage_regression.py index 4e071759d..ba09baf6b 100644 --- a/tests/test_scripts/test_solph/test_storage_investment/test_invest_storage_regression.py +++ b/tests/test_scripts/test_solph/test_storage_investment/test_invest_storage_regression.py @@ -27,13 +27,12 @@ def test_regression_investment_storage(solver="cbc"): date_time_index = pd.date_range("1/1/2012", periods=4, freq="H") energysystem = solph.EnergySystem(timeindex=date_time_index) - Node.registry = energysystem # Buses bgas = solph.Bus(label=("natural", "gas")) bel = solph.Bus(label="electricity") - solph.Sink( + demand = solph.Sink( label="demand", inputs={ bel: solph.Flow( @@ -43,10 +42,10 @@ def test_regression_investment_storage(solver="cbc"): ) # Sources - solph.Source(label="rgas", outputs={bgas: solph.Flow()}) + rgas = solph.Source(label="rgas", outputs={bgas: solph.Flow()}) # Transformer - solph.Transformer( + pp_gas = solph.Transformer( label="pp_gas", inputs={bgas: solph.Flow()}, outputs={bel: solph.Flow(nominal_value=300000)}, @@ -54,7 +53,7 @@ def test_regression_investment_storage(solver="cbc"): ) # Investment storage - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage", inputs={ bel: solph.Flow( @@ -75,6 +74,8 @@ def test_regression_investment_storage(solver="cbc"): investment=solph.Investment(ep_costs=50, existing=625046), ) + energysystem.add(bgas, bel, demand, rgas, pp_gas, storage) + # Solve model om = solph.Model(energysystem) om.solve(solver=solver) diff --git a/tests/test_scripts/test_solph/test_storage_investment/test_storage_investment.py b/tests/test_scripts/test_solph/test_storage_investment/test_storage_investment.py index 149fc0840..f584659ea 100644 --- a/tests/test_scripts/test_solph/test_storage_investment/test_storage_investment.py +++ b/tests/test_scripts/test_solph/test_storage_investment/test_storage_investment.py @@ -59,7 +59,6 @@ def test_optimise_storage_size( date_time_index = pd.date_range("1/1/2012", periods=400, freq="H") energysystem = solph.EnergySystem(timeindex=date_time_index) - Node.registry = energysystem full_filename = os.path.join(os.path.dirname(__file__), filename) data = pd.read_csv(full_filename, sep=",") @@ -69,15 +68,15 @@ def test_optimise_storage_size( bel = solph.Bus(label="electricity") # Sinks - solph.Sink(label="excess_bel", inputs={bel: solph.Flow()}) + excess_bel = solph.Sink(label="excess_bel", inputs={bel: solph.Flow()}) - solph.Sink( + demand = solph.Sink( label="demand", inputs={bel: solph.Flow(fix=data["demand_el"], nominal_value=1)}, ) # Sources - solph.Source( + rgas =solph.Source( label="rgas", outputs={ bgas: solph.Flow( @@ -86,12 +85,12 @@ def test_optimise_storage_size( }, ) - solph.Source( + wind = solph.Source( label="wind", outputs={bel: solph.Flow(fix=data["wind"], nominal_value=1000000)}, ) - solph.Source( + pv = solph.Source( label="pv", outputs={bel: solph.Flow(fix=data["pv"], nominal_value=582000)}, ) @@ -106,7 +105,7 @@ def test_optimise_storage_size( # Investment storage epc = economics.annuity(capex=1000, n=20, wacc=0.05) - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label="storage", inputs={bel: solph.Flow(variable_costs=10e10)}, outputs={bel: solph.Flow(variable_costs=10e10)}, @@ -119,6 +118,18 @@ def test_optimise_storage_size( investment=solph.Investment(ep_costs=epc, existing=6851), ) + energysystem.add( + bgas, + bel, + excess_bel, + demand, + rgas, + wind, + pv, + PP_GAS, + storage, + ) + # Solve model om = solph.Model(energysystem) om.receive_duals() diff --git a/tests/test_scripts/test_solph/test_storage_investment/test_storage_with_tuple_label.py b/tests/test_scripts/test_solph/test_storage_investment/test_storage_with_tuple_label.py index 7715df294..663e0c382 100644 --- a/tests/test_scripts/test_solph/test_storage_investment/test_storage_with_tuple_label.py +++ b/tests/test_scripts/test_solph/test_storage_investment/test_storage_with_tuple_label.py @@ -68,7 +68,6 @@ def test_tuples_as_labels_example( date_time_index = pd.date_range("1/1/2012", periods=40, freq="H") energysystem = solph.EnergySystem(timeindex=date_time_index) - Node.registry = energysystem full_filename = os.path.join(os.path.dirname(__file__), filename) data = pd.read_csv(full_filename, sep=",") @@ -78,18 +77,18 @@ def test_tuples_as_labels_example( bel = solph.Bus(label=Label("bus", "electricity", "")) # Sinks - solph.Sink( + excess_el = solph.Sink( label=Label("sink", "electricity", "excess"), inputs={bel: solph.Flow()}, ) - solph.Sink( + demand_el = solph.Sink( label=Label("sink", "electricity", "demand"), inputs={bel: solph.Flow(fix=data["demand_el"], nominal_value=1)}, ) # Sources - solph.Source( + source_gas = solph.Source( label=Label("source", "natural_gas", "commodity"), outputs={ bgas: solph.Flow( @@ -98,12 +97,12 @@ def test_tuples_as_labels_example( }, ) - solph.Source( + wind = solph.Source( label=Label("renewable", "electricity", "wind"), outputs={bel: solph.Flow(fix=data["wind"], nominal_value=1000000)}, ) - solph.Source( + pv = solph.Source( label=Label("renewable", "electricity", "pv"), outputs={ bel: solph.Flow( @@ -114,7 +113,7 @@ def test_tuples_as_labels_example( ) # Transformer - solph.Transformer( + pp_gas = solph.Transformer( label=Label("pp", "electricity", "natural_gas"), inputs={bgas: solph.Flow()}, outputs={bel: solph.Flow(nominal_value=10e10, variable_costs=50)}, @@ -122,7 +121,7 @@ def test_tuples_as_labels_example( ) # Investment storage - solph.components.GenericStorage( + storage = solph.components.GenericStorage( label=Label("storage", "electricity", "battery"), nominal_storage_capacity=204685, inputs={bel: solph.Flow(variable_costs=10e10)}, @@ -135,6 +134,18 @@ def test_tuples_as_labels_example( outflow_conversion_factor=0.8, ) + energysystem.add( + bgas, + bel, + excess_el, + demand_el, + source_gas, + wind, + pv, + pp_gas, + storage, + ) + # Solve model om = solph.Model(energysystem) om.solve(solver=solver) diff --git a/tests/test_scripts/test_solph/test_variable_chp/test_variable_chp.py b/tests/test_scripts/test_solph/test_variable_chp/test_variable_chp.py index b7a07b4e5..3a14b9a23 100644 --- a/tests/test_scripts/test_solph/test_variable_chp/test_variable_chp.py +++ b/tests/test_scripts/test_solph/test_variable_chp/test_variable_chp.py @@ -29,7 +29,6 @@ def test_variable_chp(filename="variable_chp.csv", solver="cbc"): # create time index for 192 hours in May. date_time_index = pd.date_range("5/5/2012", periods=5, freq="H") energysystem = solph.EnergySystem(timeindex=date_time_index) - Node.registry = energysystem # Read data file with heat and electrical demand (192 hours) full_filename = os.path.join(os.path.dirname(__file__), filename) @@ -45,7 +44,7 @@ def test_variable_chp(filename="variable_chp.csv", solver="cbc"): bgas = solph.Bus(label=("natural", "gas")) # create commodity object for gas resource - solph.Source( + source_gas = solph.Source( label=("commodity", "gas"), outputs={bgas: solph.Flow(variable_costs=50)}, ) @@ -57,33 +56,33 @@ def test_variable_chp(filename="variable_chp.csv", solver="cbc"): bth2 = solph.Bus(label=("heat", 2)) # create excess components for the elec/heat bus to allow overproduction - solph.Sink(label=("excess", "bth_2"), inputs={bth2: solph.Flow()}) - solph.Sink(label=("excess", "bth_1"), inputs={bth: solph.Flow()}) - solph.Sink(label=("excess", "bel_2"), inputs={bel2: solph.Flow()}) - solph.Sink(label=("excess", "bel_1"), inputs={bel: solph.Flow()}) + excess_heat_1 = solph.Sink(label=("excess", "bth_1"), inputs={bth: solph.Flow()}) + excess_heat_2 = solph.Sink(label=("excess", "bth_2"), inputs={bth2: solph.Flow()}) + excess_electricity_1 = solph.Sink(label=("excess", "bel_1"), inputs={bel: solph.Flow()}) + excess_electricity_2 = solph.Sink(label=("excess", "bel_2"), inputs={bel2: solph.Flow()}) # create simple sink object for electrical demand for each electrical bus - solph.Sink( + demand_electricity_1 = solph.Sink( label=("demand", "elec1"), inputs={bel: solph.Flow(fix=data["demand_el"], nominal_value=1)}, ) - solph.Sink( + demand_electricity_2 = solph.Sink( label=("demand", "elec2"), inputs={bel2: solph.Flow(fix=data["demand_el"], nominal_value=1)}, ) # create simple sink object for heat demand for each thermal bus - solph.Sink( + demand_heat_1 = solph.Sink( label=("demand", "therm1"), inputs={bth: solph.Flow(fix=data["demand_th"], nominal_value=741000)}, ) - solph.Sink( + demand_heat_2 = solph.Sink( label=("demand", "therm2"), inputs={bth2: solph.Flow(fix=data["demand_th"], nominal_value=741000)}, ) # create a fixed transformer to distribute to the heat_2 and elec_2 buses - solph.Transformer( + fixed_chp = solph.Transformer( label=("fixed_chp", "gas"), inputs={bgas: solph.Flow(nominal_value=10e10)}, outputs={bel2: solph.Flow(), bth2: solph.Flow()}, @@ -91,7 +90,7 @@ def test_variable_chp(filename="variable_chp.csv", solver="cbc"): ) # create a fixed transformer to distribute to the heat and elec buses - solph.components.ExtractionTurbineCHP( + variable_chp = solph.components.ExtractionTurbineCHP( label=("variable_chp", "gas"), inputs={bgas: solph.Flow(nominal_value=10e10)}, outputs={bel: solph.Flow(), bth: solph.Flow()}, @@ -99,6 +98,26 @@ def test_variable_chp(filename="variable_chp.csv", solver="cbc"): conversion_factor_full_condensation={bel: 0.5}, ) + energysystem.add( + bgas, + source_gas, + bel, + bel2, + bth, + bth2, + source_gas, + excess_heat_1, + excess_heat_2, + excess_electricity_1, + excess_electricity_2, + demand_electricity_1, + demand_electricity_2, + demand_heat_1, + demand_heat_2, + fixed_chp, + variable_chp, + ) + ########################################################################## # Optimise the energy system and plot the results ########################################################################## From a7fdc0ee35b11ae16e57b0b6346851e6151df33a Mon Sep 17 00:00:00 2001 From: jnnr <32454596+jnnr@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:25:38 +0100 Subject: [PATCH 50/58] Attempt to fix failing tests by constraining numpy version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 7c86b3cea..edac6d508 100644 --- a/setup.py +++ b/setup.py @@ -81,7 +81,7 @@ def read(*names, **kwargs): install_requires=[ "blinker", "dill", - "numpy", + "numpy < 1.24", "pandas", "pyomo >= 5.7.0, < 5.7.3", "networkx", From 33c09d2abb7e2e5d65be517900383db0df7a7115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Mon, 9 Jan 2023 21:25:31 +0100 Subject: [PATCH 51/58] Adhere to black --- tests/constraint_tests.py | 96 +++++-------------- .../test_connect_invest.py | 8 +- .../test_storage_investment.py | 2 +- .../test_variable_chp/test_variable_chp.py | 16 +++- 4 files changed, 43 insertions(+), 79 deletions(-) diff --git a/tests/constraint_tests.py b/tests/constraint_tests.py index a7dcaab89..2c7fa71bd 100644 --- a/tests/constraint_tests.py +++ b/tests/constraint_tests.py @@ -148,9 +148,7 @@ def test_linear_transformer(self): transformer = solph.Transformer( label="powerplantGas", inputs={bgas: solph.Flow()}, - outputs={ - bel: solph.Flow(nominal_value=10e10, variable_costs=50) - }, + outputs={bel: solph.Flow(nominal_value=10e10, variable_costs=50)}, conversion_factors={bel: 0.58}, ) self.energysystem.add(bgas, bel, transformer) @@ -210,9 +208,7 @@ def test_fixed_source_variable_sink(self): wind = solph.Source( label="wind", outputs={ - bel: solph.Flow( - fix=[0.43, 0.72, 0.29], nominal_value=10e5 - ) + bel: solph.Flow(fix=[0.43, 0.72, 0.29], nominal_value=10e5) }, ) @@ -244,9 +240,7 @@ def test_fixed_source_invest_sink(self): wind = solph.Source( label="wind", - outputs={ - bel: solph.Flow(fix=[12, 16, 14], nominal_value=1000000) - }, + outputs={bel: solph.Flow(fix=[12, 16, 14], nominal_value=1000000)}, ) excess = solph.Sink( @@ -284,9 +278,7 @@ def test_invest_source_fixed_sink(self): excess = solph.Sink( label="excess", - inputs={ - bel: solph.Flow(fix=[0.5, 0.8, 0.3], nominal_value=10e4) - }, + inputs={bel: solph.Flow(fix=[0.5, 0.8, 0.3], nominal_value=10e4)}, ) self.energysystem.add(bel, pv, excess) @@ -298,12 +290,8 @@ def test_storage(self): storage = solph.GenericStorage( label="storage_no_invest", - inputs={ - bel: solph.Flow(nominal_value=16667, variable_costs=56) - }, - outputs={ - bel: solph.Flow(nominal_value=16667, variable_costs=24) - }, + inputs={bel: solph.Flow(nominal_value=16667, variable_costs=56)}, + outputs={bel: solph.Flow(nominal_value=16667, variable_costs=24)}, nominal_storage_capacity=10e4, loss_rate=0.13, inflow_conversion_factor=0.97, @@ -344,12 +332,8 @@ def test_storage_invest_2(self): storage = solph.GenericStorage( label="storage2", - inputs={ - bel: solph.Flow(investment=solph.Investment(ep_costs=99)) - }, - outputs={ - bel: solph.Flow(investment=solph.Investment(ep_costs=9)) - }, + inputs={bel: solph.Flow(investment=solph.Investment(ep_costs=99))}, + outputs={bel: solph.Flow(investment=solph.Investment(ep_costs=9))}, investment=solph.Investment(ep_costs=145), initial_storage_level=0.5, ) @@ -365,12 +349,8 @@ def test_storage_invest_3(self): storage = solph.GenericStorage( label="storage3", - inputs={ - bel: solph.Flow(investment=solph.Investment(ep_costs=99)) - }, - outputs={ - bel: solph.Flow(investment=solph.Investment(ep_costs=9)) - }, + inputs={bel: solph.Flow(investment=solph.Investment(ep_costs=99))}, + outputs={bel: solph.Flow(investment=solph.Investment(ep_costs=9))}, nominal_storage_capacity=5000, ) self.energysystem.add(bel, storage) @@ -405,9 +385,7 @@ def test_storage_invest_5(self): ) }, outputs={ - bel: solph.Flow( - investment=solph.Investment(existing=100) - ) + bel: solph.Flow(investment=solph.Investment(existing=100)) }, invest_relation_input_output=1.1, nominal_storage_capacity=10000, @@ -429,9 +407,7 @@ def test_storage_invest_6(self): ) }, outputs={ - bel: solph.Flow( - investment=solph.Investment(existing=100) - ) + bel: solph.Flow(investment=solph.Investment(existing=100)) }, invest_relation_input_output=1.1, investment=solph.Investment(ep_costs=145, existing=10000), @@ -498,12 +474,8 @@ def test_storage_fixed_losses(self): storage = solph.GenericStorage( label="storage_no_invest", - inputs={ - bel: solph.Flow(nominal_value=16667, variable_costs=56) - }, - outputs={ - bel: solph.Flow(nominal_value=16667, variable_costs=24) - }, + inputs={bel: solph.Flow(nominal_value=16667, variable_costs=56)}, + outputs={bel: solph.Flow(nominal_value=16667, variable_costs=24)}, nominal_storage_capacity=1e5, loss_rate=0.13, fixed_losses_relative=0.01, @@ -623,9 +595,7 @@ def test_linear_transformer_chp(self): transformer = solph.Transformer( label="CHPpowerplantGas", - inputs={ - bgas: solph.Flow(nominal_value=10e10, variable_costs=50) - }, + inputs={bgas: solph.Flow(nominal_value=10e10, variable_costs=50)}, outputs={bel: solph.Flow(), bheat: solph.Flow()}, conversion_factors={bel: 0.4, bheat: 0.5}, ) @@ -750,9 +720,7 @@ def test_emission_constraints(self): ) source2 = solph.Source( label="source2", - outputs={ - bel: solph.Flow(nominal_value=100, emission_factor=3.5) - }, + outputs={bel: solph.Flow(nominal_value=100, emission_factor=3.5)}, ) # Should be ignored because the emission attribute is not defined. @@ -797,9 +765,7 @@ def test_flow_count_limit(self): source3 = solph.Source( label="source3", outputs={ - bel: solph.Flow( - nonconvex=solph.NonConvex(), nominal_value=100 - ) + bel: solph.Flow(nonconvex=solph.NonConvex(), nominal_value=100) }, ) @@ -866,9 +832,7 @@ def define_emission_limit(): source1 = solph.Source( label="source1", outputs={ - bel: solph.Flow( - nominal_value=100, emission_factor=0.8 - ) + bel: solph.Flow(nominal_value=100, emission_factor=0.8) }, ) source2 = solph.Source( @@ -886,9 +850,7 @@ def test_flow_without_emission_for_emission_constraint_no_error(self): bel = solph.Bus(label="electricityBus") source1 = solph.Source( label="source1", - outputs={ - bel: solph.Flow(nominal_value=100, emission_factor=0.8) - }, + outputs={bel: solph.Flow(nominal_value=100, emission_factor=0.8)}, ) source2 = solph.Source( label="source2", outputs={bel: solph.Flow(nominal_value=100)} @@ -911,17 +873,13 @@ def test_equate_variables_constraint(self): sink = solph.Sink( label="Sink", inputs={ - bus1: solph.Flow( - investment=solph.Investment(ep_costs=500) - ) + bus1: solph.Flow(investment=solph.Investment(ep_costs=500)) }, ) source = solph.Source( label="Source", outputs={ - bus1: solph.Flow( - investment=solph.Investment(ep_costs=123) - ) + bus1: solph.Flow(investment=solph.Investment(ep_costs=123)) }, ) self.energysystem.add(bus1, storage, sink, source) @@ -1026,9 +984,7 @@ def test_investment_limit(self): source = solph.Source( label="Source", outputs={ - bus1: solph.Flow( - investment=solph.Investment(ep_costs=123) - ) + bus1: solph.Flow(investment=solph.Investment(ep_costs=123)) }, ) self.energysystem.add(bus1, storage, source) @@ -1087,9 +1043,7 @@ def test_piecewise_linear_transformer_cc(self): bel = solph.Bus(label="electricityBus") plt = solph.custom.PiecewiseLinearTransformer( label="pwltf", - inputs={ - bgas: solph.Flow(nominal_value=100, variable_costs=1) - }, + inputs={bgas: solph.Flow(nominal_value=100, variable_costs=1)}, outputs={bel: solph.Flow()}, in_breakpoints=[0, 25, 50, 75, 100], conversion_function=lambda x: x**2, @@ -1105,9 +1059,7 @@ def test_piecewise_linear_transformer_dcc(self): bel = solph.Bus(label="electricityBus") plt = solph.custom.PiecewiseLinearTransformer( label="pwltf", - inputs={ - bgas: solph.Flow(nominal_value=100, variable_costs=1) - }, + inputs={bgas: solph.Flow(nominal_value=100, variable_costs=1)}, outputs={bel: solph.Flow()}, in_breakpoints=[0, 25, 50, 75, 100], conversion_function=lambda x: x**2, diff --git a/tests/test_scripts/test_solph/test_connect_invest/test_connect_invest.py b/tests/test_scripts/test_solph/test_connect_invest/test_connect_invest.py index f918d6ba0..85d431b89 100644 --- a/tests/test_scripts/test_solph/test_connect_invest/test_connect_invest.py +++ b/tests/test_scripts/test_solph/test_connect_invest/test_connect_invest.py @@ -50,7 +50,9 @@ def test_connect_invest(): # create excess component for the electricity bus to allow overproduction excess_el = Sink(label="excess_bel", inputs={bel2: Flow()}) - shortage = Source(label="shortage", outputs={bel2: Flow(variable_costs=50000)}) + shortage = Source( + label="shortage", outputs={bel2: Flow(variable_costs=50000)} + ) # create fixed source object representing wind power plants wind = Source( @@ -89,7 +91,9 @@ def test_connect_invest(): outputs={bel1: Flow(investment=Investment(ep_costs=20))}, ) - energysystem.add(bel1, bel2, excess_el, shortage, wind, demand, storage, line12, line21) + energysystem.add( + bel1, bel2, excess_el, shortage, wind, demand, storage, line12, line21 + ) om = Model(energysystem) diff --git a/tests/test_scripts/test_solph/test_storage_investment/test_storage_investment.py b/tests/test_scripts/test_solph/test_storage_investment/test_storage_investment.py index f584659ea..f4f465914 100644 --- a/tests/test_scripts/test_solph/test_storage_investment/test_storage_investment.py +++ b/tests/test_scripts/test_solph/test_storage_investment/test_storage_investment.py @@ -76,7 +76,7 @@ def test_optimise_storage_size( ) # Sources - rgas =solph.Source( + rgas = solph.Source( label="rgas", outputs={ bgas: solph.Flow( diff --git a/tests/test_scripts/test_solph/test_variable_chp/test_variable_chp.py b/tests/test_scripts/test_solph/test_variable_chp/test_variable_chp.py index 3a14b9a23..6121109a1 100644 --- a/tests/test_scripts/test_solph/test_variable_chp/test_variable_chp.py +++ b/tests/test_scripts/test_solph/test_variable_chp/test_variable_chp.py @@ -56,10 +56,18 @@ def test_variable_chp(filename="variable_chp.csv", solver="cbc"): bth2 = solph.Bus(label=("heat", 2)) # create excess components for the elec/heat bus to allow overproduction - excess_heat_1 = solph.Sink(label=("excess", "bth_1"), inputs={bth: solph.Flow()}) - excess_heat_2 = solph.Sink(label=("excess", "bth_2"), inputs={bth2: solph.Flow()}) - excess_electricity_1 = solph.Sink(label=("excess", "bel_1"), inputs={bel: solph.Flow()}) - excess_electricity_2 = solph.Sink(label=("excess", "bel_2"), inputs={bel2: solph.Flow()}) + excess_heat_1 = solph.Sink( + label=("excess", "bth_1"), inputs={bth: solph.Flow()} + ) + excess_heat_2 = solph.Sink( + label=("excess", "bth_2"), inputs={bth2: solph.Flow()} + ) + excess_electricity_1 = solph.Sink( + label=("excess", "bel_1"), inputs={bel: solph.Flow()} + ) + excess_electricity_2 = solph.Sink( + label=("excess", "bel_2"), inputs={bel2: solph.Flow()} + ) # create simple sink object for electrical demand for each electrical bus demand_electricity_1 = solph.Sink( From ceb63e55cd92bf36284c1c39a2aacb2dc4cfc32a Mon Sep 17 00:00:00 2001 From: jnnr <32454596+jnnr@users.noreply.github.com> Date: Tue, 10 Jan 2023 10:42:04 +0100 Subject: [PATCH 52/58] Remove unused imports --- tests/constraint_tests.py | 1 - tests/solph_tests.py | 1 - .../test_solph/test_connect_invest/test_connect_invest.py | 1 - .../test_solph/test_flexible_modelling/test_add_constraints.py | 1 - .../test_solph/test_generic_caes/test_generic_caes.py | 1 - .../test_scripts/test_solph/test_generic_chp/test_generic_chp.py | 1 - .../test_solph/test_invest_fix_flow/test_simple_invest_fixed.py | 1 - .../test_solph/test_simple_model/test_simple_dispatch_one.py | 1 - .../test_solph/test_simple_model/test_simple_invest.py | 1 - .../test_storage_investment/test_invest_storage_regression.py | 1 - .../test_storage_investment/test_storage_investment.py | 1 - .../test_storage_investment/test_storage_with_tuple_label.py | 1 - .../test_solph/test_variable_chp/test_variable_chp.py | 1 - 13 files changed, 13 deletions(-) diff --git a/tests/constraint_tests.py b/tests/constraint_tests.py index 2c7fa71bd..5a2117cee 100644 --- a/tests/constraint_tests.py +++ b/tests/constraint_tests.py @@ -18,7 +18,6 @@ import pytest from nose.tools import assert_raises from nose.tools import eq_ -from oemof.network.network import Node from oemof import solph diff --git a/tests/solph_tests.py b/tests/solph_tests.py index 1ca8ee5f1..266f06ab9 100644 --- a/tests/solph_tests.py +++ b/tests/solph_tests.py @@ -13,7 +13,6 @@ from nose.tools import ok_ from oemof.network.energy_system import EnergySystem as EnSys -from oemof.network.network import Node from oemof import solph as solph from oemof.solph import Investment diff --git a/tests/test_scripts/test_solph/test_connect_invest/test_connect_invest.py b/tests/test_scripts/test_solph/test_connect_invest/test_connect_invest.py index 85d431b89..75f66790b 100644 --- a/tests/test_scripts/test_solph/test_connect_invest/test_connect_invest.py +++ b/tests/test_scripts/test_solph/test_connect_invest/test_connect_invest.py @@ -15,7 +15,6 @@ import pandas as pd from nose.tools import eq_ -from oemof.network import network from oemof.solph import Bus from oemof.solph import EnergySystem diff --git a/tests/test_scripts/test_solph/test_flexible_modelling/test_add_constraints.py b/tests/test_scripts/test_solph/test_flexible_modelling/test_add_constraints.py index 22ad67e17..573fc4974 100644 --- a/tests/test_scripts/test_solph/test_flexible_modelling/test_add_constraints.py +++ b/tests/test_scripts/test_solph/test_flexible_modelling/test_add_constraints.py @@ -18,7 +18,6 @@ import pandas as pd from nose.tools import ok_ -from oemof.network.network import Node from pyomo import environ as po from oemof.solph import Bus diff --git a/tests/test_scripts/test_solph/test_generic_caes/test_generic_caes.py b/tests/test_scripts/test_solph/test_generic_caes/test_generic_caes.py index 48a0f3a0b..5d80fc8e4 100644 --- a/tests/test_scripts/test_solph/test_generic_caes/test_generic_caes.py +++ b/tests/test_scripts/test_solph/test_generic_caes/test_generic_caes.py @@ -16,7 +16,6 @@ import pandas as pd from nose.tools import eq_ -from oemof.network.network import Node from oemof.solph import Bus from oemof.solph import EnergySystem diff --git a/tests/test_scripts/test_solph/test_generic_chp/test_generic_chp.py b/tests/test_scripts/test_solph/test_generic_chp/test_generic_chp.py index 47fb77925..2c77733ce 100644 --- a/tests/test_scripts/test_solph/test_generic_chp/test_generic_chp.py +++ b/tests/test_scripts/test_solph/test_generic_chp/test_generic_chp.py @@ -16,7 +16,6 @@ import pandas as pd from nose.tools import eq_ -from oemof.network.network import Node from oemof import solph as solph from oemof.solph import processing diff --git a/tests/test_scripts/test_solph/test_invest_fix_flow/test_simple_invest_fixed.py b/tests/test_scripts/test_solph/test_invest_fix_flow/test_simple_invest_fixed.py index 99b1c04d4..026485abd 100644 --- a/tests/test_scripts/test_solph/test_invest_fix_flow/test_simple_invest_fixed.py +++ b/tests/test_scripts/test_solph/test_invest_fix_flow/test_simple_invest_fixed.py @@ -15,7 +15,6 @@ import os import pandas as pd -from oemof.network.network import Node from oemof.tools import economics from oemof.solph import Bus diff --git a/tests/test_scripts/test_solph/test_simple_model/test_simple_dispatch_one.py b/tests/test_scripts/test_solph/test_simple_model/test_simple_dispatch_one.py index 5dbcd3862..d3b14e043 100644 --- a/tests/test_scripts/test_solph/test_simple_model/test_simple_dispatch_one.py +++ b/tests/test_scripts/test_solph/test_simple_model/test_simple_dispatch_one.py @@ -12,7 +12,6 @@ """ from nose.tools import eq_ -from oemof.network.network import Node from oemof.solph import Bus from oemof.solph import EnergySystem diff --git a/tests/test_scripts/test_solph/test_simple_model/test_simple_invest.py b/tests/test_scripts/test_solph/test_simple_model/test_simple_invest.py index 52047b80e..bbad7b557 100644 --- a/tests/test_scripts/test_solph/test_simple_model/test_simple_invest.py +++ b/tests/test_scripts/test_solph/test_simple_model/test_simple_invest.py @@ -17,7 +17,6 @@ import pandas as pd from nose.tools import eq_ -from oemof.network.network import Node from oemof.tools import economics from oemof.solph import Bus diff --git a/tests/test_scripts/test_solph/test_storage_investment/test_invest_storage_regression.py b/tests/test_scripts/test_solph/test_storage_investment/test_invest_storage_regression.py index ba09baf6b..02e6ed865 100644 --- a/tests/test_scripts/test_solph/test_storage_investment/test_invest_storage_regression.py +++ b/tests/test_scripts/test_solph/test_storage_investment/test_invest_storage_regression.py @@ -12,7 +12,6 @@ import logging import pandas as pd -from oemof.network.network import Node from oemof import solph from oemof.solph import views diff --git a/tests/test_scripts/test_solph/test_storage_investment/test_storage_investment.py b/tests/test_scripts/test_solph/test_storage_investment/test_storage_investment.py index f4f465914..f2826b93a 100644 --- a/tests/test_scripts/test_solph/test_storage_investment/test_storage_investment.py +++ b/tests/test_scripts/test_solph/test_storage_investment/test_storage_investment.py @@ -40,7 +40,6 @@ import pandas as pd from nose.tools import eq_ -from oemof.network.network import Node from oemof.tools import economics from oemof import solph diff --git a/tests/test_scripts/test_solph/test_storage_investment/test_storage_with_tuple_label.py b/tests/test_scripts/test_solph/test_storage_investment/test_storage_with_tuple_label.py index 663e0c382..4805657e1 100644 --- a/tests/test_scripts/test_solph/test_storage_investment/test_storage_with_tuple_label.py +++ b/tests/test_scripts/test_solph/test_storage_investment/test_storage_with_tuple_label.py @@ -40,7 +40,6 @@ import pandas as pd from nose.tools import eq_ -from oemof.network.network import Node from oemof import solph as solph from oemof.solph import processing diff --git a/tests/test_scripts/test_solph/test_variable_chp/test_variable_chp.py b/tests/test_scripts/test_solph/test_variable_chp/test_variable_chp.py index 6121109a1..9518c33bd 100644 --- a/tests/test_scripts/test_solph/test_variable_chp/test_variable_chp.py +++ b/tests/test_scripts/test_solph/test_variable_chp/test_variable_chp.py @@ -17,7 +17,6 @@ import pandas as pd from nose.tools import eq_ -from oemof.network.network import Node from oemof import solph from oemof.solph import views From 4999ff333127c4c18e8b539589badc52f9b21c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 10 Jan 2023 20:33:35 +0100 Subject: [PATCH 53/58] Fix link to codecov.io --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 37cbf7910..33a3eddbb 100644 --- a/README.rst +++ b/README.rst @@ -34,7 +34,7 @@ .. |codecov| image:: https://codecov.io/gh/oemof/oemof-solph/branch/dev/graphs/badge.svg?branch=dev :alt: Coverage Status - :target: https://codecov.io/github/oemof/oemof-solph + :target: https://codecov.io/gh/oemof/oemof-solph .. |codacy| image:: https://api.codacy.com/project/badge/Grade/a6e5cb2dd2694c73895e142e4cf680d5 :target: https://app.codacy.com/gh/oemof/oemof-solph/dashboard From 9b3f034baf6b467a9d361e05cd07e6520d87018b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 10 Jan 2023 20:39:09 +0100 Subject: [PATCH 54/58] Omit custom dir for test coverage calculation --- .coveragerc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.coveragerc b/.coveragerc index e84deab19..bea338f21 100644 --- a/.coveragerc +++ b/.coveragerc @@ -7,7 +7,7 @@ source = src tests parallel = true -omit = *custom* +omit = */custom/* *test* [report] From 0cc96e75bb2fa403429dcc396e920436d00b714d Mon Sep 17 00:00:00 2001 From: jnnr <32454596+jnnr@users.noreply.github.com> Date: Mon, 16 Jan 2023 16:10:57 +0100 Subject: [PATCH 55/58] Write whatsnew file --- docs/changelog.rst | 1 + docs/whatsnew/v0-4-5.rst | 32 +++++++++++++++++--------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index be0a4ef72..dc332779f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -9,6 +9,7 @@ These are new features and improvements of note in each release :backlinks: top +.. include:: whatsnew/v0-4-5.rst .. include:: whatsnew/v0-4-4.rst .. include:: whatsnew/v0-4-2.rst .. include:: whatsnew/v0-4-1.rst diff --git a/docs/whatsnew/v0-4-5.rst b/docs/whatsnew/v0-4-5.rst index 59d23e8dd..e96ce7905 100644 --- a/docs/whatsnew/v0-4-5.rst +++ b/docs/whatsnew/v0-4-5.rst @@ -1,32 +1,34 @@ -v0.4.5 (?) +v0.4.5 (January 16th, 2023) ---------- - -API changes -########### - - New features ############ - -Documentation -############# - +* Allow to exclude attrs from `parameter_as_dict` + `#825 `_ Bug fixes ######### +* Remove not working `gradient_cost` from Flow +* Exclude attrs `from parameter_as_dict` `#824 `_ +* Fixed check for callables in `processing.parameter_as_dict` `#823 `_ +* Refactored assertion error in `Link` component into suspicious warning `#834 `_ +* Remove `Link` limit direction `#896 `_ +* Fix links in setup.py `#803 `_ Testing ####### - -Other changes -############# - - +* `Node.registry` has been removed from `oemof.network`. All nodes have to be + added to the energysystem explicitely. The tests have been adapted. Contributors ############ +* Hendrik Huyskens +* Uwe Krien +* Jann Launer +* Patrik Schönfeld +* Francesco Witte + From bb79021761d50805ee5cbcf08a519e2cb4295f9b Mon Sep 17 00:00:00 2001 From: jnnr <32454596+jnnr@users.noreply.github.com> Date: Thu, 19 Jan 2023 16:40:54 +0100 Subject: [PATCH 56/58] Adapt date of release --- docs/whatsnew/v0-4-5.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/whatsnew/v0-4-5.rst b/docs/whatsnew/v0-4-5.rst index e96ce7905..dd08b62ac 100644 --- a/docs/whatsnew/v0-4-5.rst +++ b/docs/whatsnew/v0-4-5.rst @@ -1,4 +1,4 @@ -v0.4.5 (January 16th, 2023) +v0.4.5 (January 19th, 2023) ---------- New features From a5330f75e1749a6d1268b24761ed65c4aeac60cb Mon Sep 17 00:00:00 2001 From: jnnr <32454596+jnnr@users.noreply.github.com> Date: Thu, 19 Jan 2023 16:41:22 +0100 Subject: [PATCH 57/58] Change version 0.4.5dev to 0.4.5 --- VERSION | 2 +- docs/conf.py | 2 +- setup.py | 2 +- src/oemof/solph/__init__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index d8fdfc4a3..98a433b31 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -__version__ = "0.4.3.dev0" +__version__ = "0.4.5" diff --git a/docs/conf.py b/docs/conf.py index 459c9be43..2c5f3993b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -30,7 +30,7 @@ def setup(app): year = "2014-2021" author = "oemof-developer-group" copyright = "{0}, {1}".format(year, author) -version = release = "0.4.5.dev0" +version = release = "0.4.5" pygments_style = "trac" templates_path = ["."] diff --git a/setup.py b/setup.py index edac6d508..76d49a864 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ def read(*names, **kwargs): setup( name="oemof.solph", - version="0.4.5.dev0", + version="0.4.5", license="MIT", description=( "A model generator for energy system modelling and optimisation." diff --git a/src/oemof/solph/__init__.py b/src/oemof/solph/__init__.py index 8cf2b6cb1..5c165c0ac 100644 --- a/src/oemof/solph/__init__.py +++ b/src/oemof/solph/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.4.5.dev0" +__version__ = "0.4.5" from . import constraints # noqa: F401 from . import custom # noqa: F401 From bd45dca108fed62d0b887e9dc95b072cb36f4b24 Mon Sep 17 00:00:00 2001 From: jnnr <32454596+jnnr@users.noreply.github.com> Date: Mon, 23 Jan 2023 16:49:46 +0100 Subject: [PATCH 58/58] Adapt release date --- docs/whatsnew/v0-4-5.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/whatsnew/v0-4-5.rst b/docs/whatsnew/v0-4-5.rst index dd08b62ac..e57c6209d 100644 --- a/docs/whatsnew/v0-4-5.rst +++ b/docs/whatsnew/v0-4-5.rst @@ -1,5 +1,5 @@ -v0.4.5 (January 19th, 2023) ----------- +v0.4.5 (January 23th, 2023) +--------------------------- New features ############