From a850d271b8916d7233f46ffe71e30147f2e93a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Mon, 30 Sep 2024 19:48:32 +0200 Subject: [PATCH 01/34] Remove travis.yml travis.ci is no longer used as a service --- .travis.yml | 55 ----------------------------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 4d8e2957..00000000 --- a/.travis.yml +++ /dev/null @@ -1,55 +0,0 @@ -language: python - -matrix: - include: - - python: 3.6 - - python: 3.7 - dist: xenial - - -# To install packages which are not on pip -#before_install: -# - sudo apt-get install ... -#addons: -# apt: -# update: true - -# command to install dependencies -install: - - pip install -r tests/test_requirements.txt - - pip install -e . - - pip install pytest-cov - - pip install coveralls - -# commands to run tests -script: - - flake8 - - pylint */*.py - - pytest --cov=src/oemof/thermal tests/ -#jobs: -# include: -# - stage: "Tests" # naming the Tests stage -# name: "Linting Tests" # names the first Tests stage job -# script: flake8 -# script: pylint -# for later stages -# - script: ./integration-tests -# name: "Integration Tests" # names the second Tests stage job -# - stage: deploy -# name: "Deploy to GCP" -# script: ./deploy - -# blocklist -#branches: -# except: -# - branch_name1 -# - branch_name2 - -# safelist -#branches: -# only: -# - branch_name1 -# - branch_name2 - -after_success: - - coveralls From 2946de85aede16ac89a41449f52034831f85ef55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Mon, 30 Sep 2024 19:50:07 +0200 Subject: [PATCH 02/34] Remove year from LICENSE file --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 6a1dd2bb..88ee8e0f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 oemof developing group +Copyright (c) oemof developing 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 From c9591e0646dcd5343560b96f377f1105b2f39fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Mon, 30 Sep 2024 20:12:07 +0200 Subject: [PATCH 03/34] Merge setup infos in pyproject.toml --- VERSION | 1 - pyproject.toml | 47 +++++++++++++++++++++++++++++++++++++++++++++++ setup.cfg | 2 -- setup.py | 29 ----------------------------- 4 files changed, 47 insertions(+), 32 deletions(-) delete mode 100644 VERSION create mode 100644 pyproject.toml delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/VERSION b/VERSION deleted file mode 100644 index 14402fdf..00000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.0.7.dev" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..58c49900 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,47 @@ +[build-system] +requires = ["flit_core >=3.2,<4"] +build-backend = "flit_core.buildapi" + +[tool.flit.sdist] +include = [ + "LICENSE", + "README.rst", + "docs/", + "examples/", + "src/", + "tests/", +] + +[project] +name = "oemof.thermal" +dynamic = ["version"] +description = "Thermal energy components for the open energy modelling framework." +readme = "README.rst" +authors = [ + {name = "oemof developer group", email = "contact@oemof.org"}, +] +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: MIT License", + "Operating System :: Unix", + "Operating System :: POSIX", + "Operating System :: Microsoft :: Windows", + "Operating System :: MacOS", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Topic :: Utilities", +] + +requires-python = ">=3.10" +dependencies = [ + 'oemof.network < 0.5', + 'oemof.solph', + 'matplotlib', + 'pvlib', + 'numpy >= 1.16.5', + 'pandas >= 0.18.0' +] +license = {text = "MIT"} diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 11e9ec40..00000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[metadata] -description-file = README.rst \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index 7032ca2f..00000000 --- a/setup.py +++ /dev/null @@ -1,29 +0,0 @@ -#! /usr/bin/env python -# -*- encoding: utf-8 -*- - -from setuptools import find_packages, setup -import os - - -def read(fname): - return open(os.path.join(os.path.dirname(__file__), fname)).read() - - -setup(name='oemof.thermal', - version='0.0.7.dev', - author='oemof developer group', - author_email='contact@oemof.org', - description=( - 'Thermal energy components for ' - 'the open energy modelling framework.' - ), - url='https://github.com/oemof/oemof-thermal', - long_description=read('README.rst'), - long_description_content_type="text/x-rst", - packages=["oemof"] + ["oemof." + p for p in find_packages("src/oemof")], - package_dir={"": "src"}, - install_requires=['oemof.solph', - 'matplotlib', - 'pvlib', - 'numpy >= 1.16.5', - 'pandas >= 0.18.0']) From 6783f256afce866b06b70ee79941b89e4dfb9756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Mon, 30 Sep 2024 20:12:34 +0200 Subject: [PATCH 04/34] Ignore .venv --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 135b2adb..61d921f1 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ __pycache__/ # Distribution / packaging .Python env/ +.venv/ venv/ build/ develop-eggs/ From 0c77a6940109455cdefb9156b904e4ab9c3dc935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Mon, 30 Sep 2024 20:57:31 +0200 Subject: [PATCH 05/34] Adapt for oemof.network v0.5 --- pyproject.toml | 1 - src/oemof/thermal/facades.py | 289 +++++++++++++++++------------------ 2 files changed, 140 insertions(+), 150 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 58c49900..41530bf9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,6 @@ classifiers = [ requires-python = ">=3.10" dependencies = [ - 'oemof.network < 0.5', 'oemof.solph', 'matplotlib', 'pvlib', diff --git a/src/oemof/thermal/facades.py b/src/oemof/thermal/facades.py index 6d0600cc..2ecbe48e 100644 --- a/src/oemof/thermal/facades.py +++ b/src/oemof/thermal/facades.py @@ -26,29 +26,28 @@ import warnings from collections import deque -from oemof.thermal.stratified_thermal_storage import calculate_storage_dimensions,\ - calculate_capacities, calculate_losses +from oemof.thermal.stratified_thermal_storage import ( + calculate_storage_dimensions, + calculate_capacities, + calculate_losses, +) from oemof.thermal.concentrating_solar_power import csp_precalc from oemof.thermal.solar_thermal_collector import flat_plate_precalc from oemof.network.energy_system import EnergySystem from oemof.network.network import Node from oemof.tools.debugging import SuspiciousUsageWarning -try: - from oemof.solph import ( - Flow, - Investment, - sequence, - ) - from oemof.solph.components import ( - GenericStorage, - Transformer, - Source, - ) -except ImportError: # solph <= v0.4 - from oemof.solph import Flow, Investment, Transformer, Source - from oemof.solph.components import GenericStorage - from oemof.solph.plumbing import sequence + +from oemof.solph import ( + Flow, + Investment, + sequence, +) +from oemof.solph.components import ( + GenericStorage, + Transformer, + Source, +) def add_subnodes(n, **kwargs): @@ -66,9 +65,8 @@ class Facade(Node): raises an error if he doesn't find them. """ - def __init__(self, *args, **kwargs): - """ - """ + def __init__(self, *_, **kwargs): + """ """ self.mapped_type = type(self) @@ -76,12 +74,10 @@ def __init__(self, *args, **kwargs): required = kwargs.pop("_facade_requires_", []) - super().__init__(*args, **kwargs) + super().__init__(label=kwargs.get("label")) self.subnodes = [] - EnergySystem.signals[EnergySystem.add].connect( - add_subnodes, sender=self - ) + EnergySystem.signals[EnergySystem.add].connect(add_subnodes, sender=self) for r in required: if r in kwargs: @@ -95,7 +91,7 @@ def __init__(self, *args, **kwargs): ) def _nominal_value(self): - """ Returns None if self.expandable ist True otherwise it returns + """Returns None if self.expandable ist True otherwise it returns the capacity """ if self.expandable is True: @@ -122,9 +118,7 @@ def _investment(self): "storage_capacity_potential", float("+inf"), ), - minimum=getattr( - self, "minimum_storage_capacity", 0 - ), + minimum=getattr(self, "minimum_storage_capacity", 0), existing=getattr(self, "storage_capacity", 0), ) else: @@ -132,9 +126,7 @@ def _investment(self): else: self.investment = Investment( ep_costs=self.capacity_cost, - maximum=getattr( - self, "capacity_potential", float("+inf") - ), + maximum=getattr(self, "capacity_potential", float("+inf")), existing=getattr(self, "capacity", 0), ) else: @@ -147,7 +139,7 @@ def update(self): class StratifiedThermalStorage(GenericStorage, Facade): - r""" Stratified thermal storage unit. + r"""Stratified thermal storage unit. Parameters ---------- @@ -218,34 +210,42 @@ class StratifiedThermalStorage(GenericStorage, Facade): """ def __init__( - self, - label=None, - inputs=None, - outputs=None, - nominal_storage_capacity=None, - initial_storage_level=None, - investment=None, - invest_relation_input_output=None, - invest_relation_input_capacity=None, - invest_relation_output_capacity=None, - min_storage_level=0.0, - max_storage_level=1.0, - balanced=True, - loss_rate=0, - fixed_losses_relative=0, - fixed_losses_absolute=0, - inflow_conversion_factor=1, - outflow_conversion_factor=1, - custom_attributes=None, - **kwargs + self, + label=None, + inputs=None, + outputs=None, + nominal_storage_capacity=None, + initial_storage_level=None, + investment=None, + invest_relation_input_output=None, + invest_relation_input_capacity=None, + invest_relation_output_capacity=None, + min_storage_level=0.0, + max_storage_level=1.0, + balanced=True, + loss_rate=0, + fixed_losses_relative=0, + fixed_losses_absolute=0, + inflow_conversion_factor=1, + outflow_conversion_factor=1, + custom_attributes=None, + **kwargs, ): + kwargs.update( + { + "_facade_requires_": [ + "bus", + "diameter", + "temp_h", + "temp_c", + "temp_env", + "u_value", + ] + } + ) Facade.__init__( self, - _facade_requires_=[ - "bus", "diameter", - "temp_h", "temp_c", "temp_env", - "u_value"], - **kwargs + **kwargs, ) with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=SuspiciousUsageWarning) @@ -275,8 +275,8 @@ def __init__( self.height = kwargs.get("height") self.water_properties = { - 'heat_capacity': kwargs.get("heat_capacity"), - 'density': kwargs.get("density") + "heat_capacity": kwargs.get("heat_capacity"), + "density": kwargs.get("density"), } self.capacity = kwargs.get("capacity") @@ -289,13 +289,9 @@ def __init__( "storage_capacity_potential", float("+inf") ) - self.capacity_potential = kwargs.get( - "capacity_potential", float("+inf") - ) + self.capacity_potential = kwargs.get("capacity_potential", float("+inf")) - self.minimum_storage_capacity = kwargs.get( - "minimum_storage_capacity", 0 - ) + self.minimum_storage_capacity = kwargs.get("minimum_storage_capacity", 0) self.expandable = bool(kwargs.get("expandable", False)) @@ -316,7 +312,11 @@ def __init__( self.temp_h, self.temp_c, self.temp_env, - **{key: value for key, value in self.water_properties.items() if value is not None} + **{ + key: value + for key, value in self.water_properties.items() + if value is not None + }, ) self.loss_rate = losses[0] @@ -328,8 +328,7 @@ def __init__( self.build_solph_components() def build_solph_components(self): - """ - """ + """ """ self.inflow_conversion_factor = sequence(self.efficiency) self.outflow_conversion_factor = sequence(self.efficiency) @@ -349,9 +348,9 @@ def build_solph_components(self): for attr in ["invest_relation_input_output"]: if getattr(self, attr) is None: raise AttributeError( - ( - "You need to set attr " "`{}` " "for component {}" - ).format(attr, self.label) + ("You need to set attr " "`{}` " "for component {}").format( + attr, self.label + ) ) # set capacity costs at one of the flows @@ -361,13 +360,13 @@ def build_solph_components(self): maximum=self.capacity_potential, existing=self.capacity, ), - **self.input_parameters + **self.input_parameters, ) # set investment, but no costs (as relation input / output = 1) fo = Flow( investment=Investment(), variable_costs=self.marginal_cost, - **self.output_parameters + **self.output_parameters, ) # required for correct grouping in oemof.solph.components self._invest_group = True @@ -378,16 +377,18 @@ def build_solph_components(self): self.volume, self.temp_h, self.temp_c, - **{key: value for key, value in self.water_properties.items() if value is not None} + **{ + key: value + for key, value in self.water_properties.items() + if value is not None + }, ) - fi = Flow( - nominal_value=self._nominal_value(), **self.input_parameters - ) + fi = Flow(nominal_value=self._nominal_value(), **self.input_parameters) fo = Flow( nominal_value=self._nominal_value(), variable_costs=self.marginal_cost, - **self.output_parameters + **self.output_parameters, ) self.inputs.update({self.bus: fi}) @@ -398,7 +399,7 @@ def build_solph_components(self): class ParabolicTroughCollector(Transformer, Facade): - r""" Parabolic trough collector unit + r"""Parabolic trough collector unit Parameters ---------- @@ -450,20 +451,12 @@ class ParabolicTroughCollector(Transformer, Facade): ... ) """ - def __init__(self, *args, **kwargs): + def __init__(self, **kwargs): - kwargs.update( - { - "_facade_requires_": [ - "longitude" - ] - } - ) - Facade.__init__(self, *args, **kwargs) + kwargs.update({"_facade_requires_": ["longitude"]}) + Facade.__init__(self, **kwargs) Transformer.__init__(self) - self.label = kwargs.get("label") - self.heat_bus = kwargs.get("heat_bus") self.electrical_bus = kwargs.get("electrical_bus") @@ -518,36 +511,57 @@ def __init__(self, *args, **kwargs): if self.irradiance_method == "horizontal": heat = csp_precalc( - self.latitude, self.longitude, - self.collector_tilt, self.collector_azimuth, self.cleanliness, - self.eta_0, self.c_1, self.c_2, - self.temp_collector_inlet, self.temp_collector_outlet, + self.latitude, + self.longitude, + self.collector_tilt, + self.collector_azimuth, + self.cleanliness, + self.eta_0, + self.c_1, + self.c_2, + self.temp_collector_inlet, + self.temp_collector_outlet, self.temp_amb, - self.a_1, self.a_2, self.a_3, self.a_4, self.a_5, self.a_6, + self.a_1, + self.a_2, + self.a_3, + self.a_4, + self.a_5, + self.a_6, loss_method=self.loss_method, irradiance_method=self.irradiance_method, - E_dir_hor=self.irradiance + E_dir_hor=self.irradiance, ) if self.irradiance_method == "normal": heat = csp_precalc( - self.latitude, self.longitude, - self.collector_tilt, self.collector_azimuth, self.cleanliness, - self.eta_0, self.c_1, self.c_2, - self.temp_collector_inlet, self.temp_collector_outlet, + self.latitude, + self.longitude, + self.collector_tilt, + self.collector_azimuth, + self.cleanliness, + self.eta_0, + self.c_1, + self.c_2, + self.temp_collector_inlet, + self.temp_collector_outlet, self.temp_amb, - self.a_1, self.a_2, self.a_3, self.a_4, self.a_5, self.a_6, + self.a_1, + self.a_2, + self.a_3, + self.a_4, + self.a_5, + self.a_6, loss_method=self.loss_method, irradiance_method=self.irradiance_method, - dni=self.irradiance + dni=self.irradiance, ) - self.collectors_heat = heat['collector_heat'] + self.collectors_heat = heat["collector_heat"] self.build_solph_components() def build_solph_components(self): - """ - """ + """ """ if self.expandable: raise NotImplementedError( @@ -557,32 +571,28 @@ def build_solph_components(self): inflow = Source( label=self.label + "-inflow", outputs={ - self: Flow(nominal_value=self.aperture_area, - max=self.collectors_heat) + self: Flow(nominal_value=self.aperture_area, max=self.collectors_heat) }, ) self.conversion_factors.update( { - self.electrical_bus: sequence(self.electrical_consumption - * (1 - self.additional_losses)), + self.electrical_bus: sequence( + self.electrical_consumption * (1 - self.additional_losses) + ), self.heat_bus: sequence(1 - self.additional_losses), - inflow: sequence(1) + inflow: sequence(1), } ) - self.inputs.update( - {self.electrical_bus: Flow()} - ) - self.outputs.update( - {self.heat_bus: Flow()} - ) + self.inputs.update({self.electrical_bus: Flow()}) + self.outputs.update({self.heat_bus: Flow()}) self.subnodes = (inflow,) class SolarThermalCollector(Transformer, Facade): - r""" Solar thermal collector unit + r"""Solar thermal collector unit Parameters: ----------- @@ -629,20 +639,12 @@ class SolarThermalCollector(Transformer, Facade): ) """ - def __init__(self, *args, **kwargs): + def __init__(self, **kwargs): - kwargs.update( - { - "_facade_requires_": [ - "longitude" - ] - } - ) - Facade.__init__(self, *args, **kwargs) + kwargs.update({"_facade_requires_": ["longitude"]}) + Facade.__init__(self, **kwargs) Transformer.__init__(self) - self.label = kwargs.get("label") - self.heat_out_bus = kwargs.get("heat_out_bus") self.electricity_in_bus = kwargs.get("electricity_in_bus") @@ -694,15 +696,14 @@ def __init__(self, *args, **kwargs): self.temp_amb, ) - self.collectors_eta_c = data['eta_c'] + self.collectors_eta_c = data["eta_c"] - self.collectors_heat = data['collectors_heat'] + self.collectors_heat = data["collectors_heat"] self.build_solph_components() def build_solph_components(self): - """ - """ + """ """ if self.expandable: raise NotImplementedError( @@ -712,31 +713,21 @@ def build_solph_components(self): inflow = Source( label=self.label + "-inflow", outputs={ - self: Flow(nominal_value=self.aperture_area, - max=self.collectors_heat) + self: Flow(nominal_value=self.aperture_area, max=self.collectors_heat) }, ) self.conversion_factors.update( { - self.electricity_in_bus: sequence(self.electrical_consumption - * (1 - self.peripheral_losses)), + self.electricity_in_bus: sequence( + self.electrical_consumption * (1 - self.peripheral_losses) + ), self.heat_out_bus: sequence(1 - self.peripheral_losses), - inflow: sequence(1) + inflow: sequence(1), } ) - self.inputs.update( - { - self.electricity_in_bus: Flow( - ) - } - ) - self.outputs.update( - { - self.heat_out_bus: Flow( - ) - } - ) + self.inputs.update({self.electricity_in_bus: Flow()}) + self.outputs.update({self.heat_out_bus: Flow()}) self.subnodes = (inflow,) From 9954fcff1b35bfc21e9d273f9771e9325c55f5b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 8 Oct 2024 20:59:33 +0200 Subject: [PATCH 06/34] Fix version number format --- src/oemof/thermal/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oemof/thermal/__init__.py b/src/oemof/thermal/__init__.py index e6537d98..1cea80e6 100644 --- a/src/oemof/thermal/__init__.py +++ b/src/oemof/thermal/__init__.py @@ -1,4 +1,4 @@ -__version__ = '0.0.7.dev' +__version__ = '0.0.7.dev0' __project__ = 'oemof.thermal' from . import absorption_heatpumps_and_chillers From 28d74a7797354306660b620e5e7ebcbad30f9b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 8 Oct 2024 21:00:17 +0200 Subject: [PATCH 07/34] Update sdist list --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 41530bf9..12912108 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,8 @@ include = [ "examples/", "src/", "tests/", + ".flake8", + ".pylintrc", ] [project] From 1edab40001f160bf75dd93751c245b279b5039f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 8 Oct 2024 21:03:01 +0200 Subject: [PATCH 08/34] Blacken code style --- src/oemof/thermal/__init__.py | 16 +- .../thermal/concentrating_solar_power.py | 7 +- src/oemof/thermal/facades.py | 25 +- src/oemof/thermal/solar_thermal_collector.py | 2 +- tests/test_constraints.py | 339 ++++++------- tests/test_functions.py | 472 ++++++++++-------- 6 files changed, 449 insertions(+), 412 deletions(-) diff --git a/src/oemof/thermal/__init__.py b/src/oemof/thermal/__init__.py index 1cea80e6..1c7bd549 100644 --- a/src/oemof/thermal/__init__.py +++ b/src/oemof/thermal/__init__.py @@ -1,13 +1,15 @@ __version__ = '0.0.7.dev0' __project__ = 'oemof.thermal' -from . import absorption_heatpumps_and_chillers -from . import compression_heatpumps_and_chillers -from . import facades -from . import stratified_thermal_storage -from . import cogeneration -from . import concentrating_solar_power -from . import solar_thermal_collector +from . import ( + absorption_heatpumps_and_chillers, + cogeneration, + compression_heatpumps_and_chillers, + concentrating_solar_power, + facades, + solar_thermal_collector, + stratified_thermal_storage, +) __all__ = [ "absorption_heatpumps_and_chillers", diff --git a/src/oemof/thermal/concentrating_solar_power.py b/src/oemof/thermal/concentrating_solar_power.py index 4f3eed54..6ee456ee 100644 --- a/src/oemof/thermal/concentrating_solar_power.py +++ b/src/oemof/thermal/concentrating_solar_power.py @@ -12,11 +12,12 @@ """ -import pvlib -import pandas as pd -import numpy as np import warnings +import numpy as np +import pandas as pd +import pvlib + def csp_precalc(lat, long, collector_tilt, collector_azimuth, cleanliness, eta_0, c_1, c_2, diff --git a/src/oemof/thermal/facades.py b/src/oemof/thermal/facades.py index 2ecbe48e..253183b7 100644 --- a/src/oemof/thermal/facades.py +++ b/src/oemof/thermal/facades.py @@ -26,27 +26,18 @@ import warnings from collections import deque -from oemof.thermal.stratified_thermal_storage import ( - calculate_storage_dimensions, - calculate_capacities, - calculate_losses, -) -from oemof.thermal.concentrating_solar_power import csp_precalc -from oemof.thermal.solar_thermal_collector import flat_plate_precalc from oemof.network.energy_system import EnergySystem from oemof.network.network import Node - +from oemof.solph import Flow, Investment, sequence +from oemof.solph.components import GenericStorage, Source, Transformer from oemof.tools.debugging import SuspiciousUsageWarning -from oemof.solph import ( - Flow, - Investment, - sequence, -) -from oemof.solph.components import ( - GenericStorage, - Transformer, - Source, +from oemof.thermal.concentrating_solar_power import csp_precalc +from oemof.thermal.solar_thermal_collector import flat_plate_precalc +from oemof.thermal.stratified_thermal_storage import ( + calculate_capacities, + calculate_losses, + calculate_storage_dimensions, ) diff --git a/src/oemof/thermal/solar_thermal_collector.py b/src/oemof/thermal/solar_thermal_collector.py index 81e5b5c3..882d86f3 100644 --- a/src/oemof/thermal/solar_thermal_collector.py +++ b/src/oemof/thermal/solar_thermal_collector.py @@ -12,8 +12,8 @@ """ -import pvlib import pandas as pd +import pvlib def flat_plate_precalc( diff --git a/tests/test_constraints.py b/tests/test_constraints.py index ed893f82..d896e1b2 100644 --- a/tests/test_constraints.py +++ b/tests/test_constraints.py @@ -15,19 +15,17 @@ import re from difflib import unified_diff +import oemof.solph as solph import pandas as pd - -from oemof.thermal import facades -from oemof.network.network import Node from oemof.solph import helpers -import oemof.solph as solph +from oemof.thermal import facades logging.disable(logging.INFO) def chop_trailing_whitespace(lines): - return [re.sub(r'\s*$', '', line) for line in lines] + return [re.sub(r"\s*$", "", line) for line in lines] def remove(pattern, lines): @@ -38,23 +36,20 @@ def remove(pattern, lines): def normalize_to_positive_results(lines): negative_result_indices = [ - n for n, line in enumerate(lines) - if re.match("^= -", line)] + n for n, line in enumerate(lines) if re.match("^= -", line) + ] equation_start_indices = [ - [n for n in reversed(range(0, nri)) - if re.match('.*:$', lines[n])][0] + 1 - for nri in negative_result_indices] - for (start, end) in zip( - equation_start_indices, - negative_result_indices): + [n for n in reversed(range(0, nri)) if re.match(".*:$", lines[n])][0] + 1 + for nri in negative_result_indices + ] + for start, end in zip(equation_start_indices, negative_result_indices): for n in range(start, end): lines[n] = ( - '-' - if lines[n] and lines[n][0] == '+' - else '+' - if lines[n] - else lines[n]) + lines[n][1:] - lines[end] = '= ' + lines[end][3:] + "-" + if lines[n] and lines[n][0] == "+" + else "+" if lines[n] else lines[n] + ) + lines[n][1:] + lines[end] = "= " + lines[end][3:] return lines @@ -72,35 +67,35 @@ def compare_lp_files(lp_file_1, lp_file_2, ignored=None): unified_diff( lines_1, lines_2, - fromfile=os.path.relpath( - lp_file_1.name), - tofile=os.path.basename( - lp_file_2.name), - lineterm="" + fromfile=os.path.relpath(lp_file_1.name), + tofile=os.path.basename(lp_file_2.name), + lineterm="", ) - )) + ) + ) class TestConstraints: @classmethod def setup_class(cls): - cls.objective_pattern = re.compile(r'^objective.*(?=s\.t\.)', - re.DOTALL | re.MULTILINE) + cls.objective_pattern = re.compile( + r"^objective.*(?=s\.t\.)", re.DOTALL | re.MULTILINE + ) - cls.date_time_index = pd.date_range('1/1/2012', periods=3, freq='H') + cls.date_time_index = pd.date_range("1/1/2012", periods=3, freq="H") - cls.tmpdir = helpers.extend_basic_path('tmp') + cls.tmpdir = helpers.extend_basic_path("tmp") logging.info(cls.tmpdir) @classmethod def setup_method(self): - self.energysystem = solph.EnergySystem(groupings=solph.GROUPINGS, - timeindex=self.date_time_index) + self.energysystem = solph.EnergySystem( + groupings=solph.GROUPINGS, timeindex=self.date_time_index + ) def get_om(self): - return solph.Model(self.energysystem, - timeindex=self.energysystem.timeindex) + return solph.Model(self.energysystem, timeindex=self.energysystem.timeindex) def compare_to_reference_lp(self, ref_filename, my_om=None): if my_om is None: @@ -108,184 +103,192 @@ def compare_to_reference_lp(self, ref_filename, my_om=None): else: om = my_om - tmp_filename = ref_filename.replace('.lp', '') + '_tmp.lp' + tmp_filename = ref_filename.replace(".lp", "") + "_tmp.lp" new_filepath = os.path.join(self.tmpdir, tmp_filename) - om.write(new_filepath, io_options={'symbolic_solver_labels': True}) + om.write(new_filepath, io_options={"symbolic_solver_labels": True}) - ref_filepath = os.path.join(os.path.dirname(__file__), 'lp_files', ref_filename) + ref_filepath = os.path.join(os.path.dirname(__file__), "lp_files", ref_filename) with open(new_filepath) as new_file: with open(ref_filepath) as ref_file: compare_lp_files(new_file, ref_file) def test_stratified_thermal_storage_facade(self): - """Constraint test of a StratifiedThermalStorage without investment. - """ - bus_heat = solph.Bus(label='bus_heat') + """Constraint test of a StratifiedThermalStorage without investment.""" + bus_heat = solph.Bus(label="bus_heat") self.energysystem.add(bus_heat) - self.energysystem.add(facades.StratifiedThermalStorage( - label='thermal_storage', - bus=bus_heat, - diameter=10, - height=30, - temp_h=95, - temp_c=60, - temp_env=10, - u_value=0.5, - min_storage_level=0.975, - max_storage_level=0.025, - capacity=2, - efficiency=1, - marginal_cost=0.0001 - )) - - self.compare_to_reference_lp('stratified_thermal_storage.lp') + self.energysystem.add( + facades.StratifiedThermalStorage( + label="thermal_storage", + bus=bus_heat, + diameter=10, + height=30, + temp_h=95, + temp_c=60, + temp_env=10, + u_value=0.5, + min_storage_level=0.975, + max_storage_level=0.025, + capacity=2, + efficiency=1, + marginal_cost=0.0001, + ) + ) + + self.compare_to_reference_lp("stratified_thermal_storage.lp") def test_stratified_thermal_storage_invest_option_1_facade(self): """ Constraint test of a StratifiedThermalStorage with investment. Ratio between capacity and storage_capacity is fixed. """ - bus_heat = solph.Bus(label='bus_heat') + bus_heat = solph.Bus(label="bus_heat") self.energysystem.add(bus_heat) - self.energysystem.add(facades.StratifiedThermalStorage( - label='thermal_storage', - bus=bus_heat, - diameter=10, - temp_h=95, - temp_c=60, - temp_env=10, - u_value=0.5, - expandable=True, - capacity_cost=0, - storage_capacity_cost=400, - minimum_storage_capacity=1, - invest_relation_input_capacity=1 / 6, - min_storage_level=0.975, - max_storage_level=0.025, - efficiency=1, - marginal_cost=0.0001 - )) - - self.compare_to_reference_lp('stratified_thermal_storage_invest_option_1.lp') + self.energysystem.add( + facades.StratifiedThermalStorage( + label="thermal_storage", + bus=bus_heat, + diameter=10, + temp_h=95, + temp_c=60, + temp_env=10, + u_value=0.5, + expandable=True, + capacity_cost=0, + storage_capacity_cost=400, + minimum_storage_capacity=1, + invest_relation_input_capacity=1 / 6, + min_storage_level=0.975, + max_storage_level=0.025, + efficiency=1, + marginal_cost=0.0001, + ) + ) + + self.compare_to_reference_lp("stratified_thermal_storage_invest_option_1.lp") def test_stratified_thermal_storage_invest_option_2_facade(self): """ Constraint test of a StratifiedThermalStorage with investment. Ratio between capacity and storage_capacity is left open. """ - bus_heat = solph.Bus(label='bus_heat') + bus_heat = solph.Bus(label="bus_heat") self.energysystem.add(bus_heat) - self.energysystem.add(facades.StratifiedThermalStorage( - label='thermal_storage', - bus=bus_heat, - diameter=10, - temp_h=95, - temp_c=60, - temp_env=10, - u_value=0.5, - expandable=True, - capacity_cost=50, - storage_capacity_cost=400, - minimum_storage_capacity=1, - min_storage_level=0.975, - max_storage_level=0.025, - efficiency=1, - marginal_cost=0.0001 - )) - - self.compare_to_reference_lp('stratified_thermal_storage_invest_option_2.lp') + self.energysystem.add( + facades.StratifiedThermalStorage( + label="thermal_storage", + bus=bus_heat, + diameter=10, + temp_h=95, + temp_c=60, + temp_env=10, + u_value=0.5, + expandable=True, + capacity_cost=50, + storage_capacity_cost=400, + minimum_storage_capacity=1, + min_storage_level=0.975, + max_storage_level=0.025, + efficiency=1, + marginal_cost=0.0001, + ) + ) + + self.compare_to_reference_lp("stratified_thermal_storage_invest_option_2.lp") def test_csp_collector_facade(self): - """Constraint test of a csp collector. - """ - bus_heat = solph.Bus(label='bus_heat') - bus_el = solph.Bus(label='bus_el') + """Constraint test of a csp collector.""" + bus_heat = solph.Bus(label="bus_heat") + bus_el = solph.Bus(label="bus_el") self.energysystem.add(bus_heat, bus_el) d = { - 'Datum': [ - '01.02.2003 09:00', '01.02.2003 10:00', '01.02.2003 11:00'], - 'E_dir_hor': [43.1, 152.7, 76.9], - 't_amb': [22.2, 23.2, 24.1]} + "Datum": ["01.02.2003 09:00", "01.02.2003 10:00", "01.02.2003 11:00"], + "E_dir_hor": [43.1, 152.7, 76.9], + "t_amb": [22.2, 23.2, 24.1], + } input_data = pd.DataFrame(data=d) - input_data['Datum'] = pd.to_datetime(input_data['Datum']) - input_data.set_index('Datum', inplace=True) - input_data.index = input_data.index.tz_localize(tz='Asia/Muscat') - - self.energysystem.add(facades.ParabolicTroughCollector( - label='solar_collector', - heat_bus=bus_heat, - electrical_bus=bus_el, - electrical_consumption=0.05, - additional_losses=0.2, - aperture_area=1000, - loss_method='Janotte', - irradiance_method='horizontal', - latitude=23.614328, - longitude=58.545284, - collector_tilt=10, - collector_azimuth=180, - cleanliness=0.9, - a_1=-0.00159, - a_2=0.0000977, - eta_0=0.816, - c_1=0.0622, - c_2=0.00023, - temp_collector_inlet=435, - temp_collector_outlet=500, - temp_amb=input_data['t_amb'], - irradiance=input_data['E_dir_hor'], - )) - - self.compare_to_reference_lp('csp_collector.lp') + input_data["Datum"] = pd.to_datetime(input_data["Datum"]) + input_data.set_index("Datum", inplace=True) + input_data.index = input_data.index.tz_localize(tz="Asia/Muscat") + + self.energysystem.add( + facades.ParabolicTroughCollector( + label="solar_collector", + heat_bus=bus_heat, + electrical_bus=bus_el, + electrical_consumption=0.05, + additional_losses=0.2, + aperture_area=1000, + loss_method="Janotte", + irradiance_method="horizontal", + latitude=23.614328, + longitude=58.545284, + collector_tilt=10, + collector_azimuth=180, + cleanliness=0.9, + a_1=-0.00159, + a_2=0.0000977, + eta_0=0.816, + c_1=0.0622, + c_2=0.00023, + temp_collector_inlet=435, + temp_collector_outlet=500, + temp_amb=input_data["t_amb"], + irradiance=input_data["E_dir_hor"], + ) + ) + + self.compare_to_reference_lp("csp_collector.lp") def test_solar_thermal_collector_facade(self): """ Constraint test of a solar thermal collector. """ - bus_heat = solph.Bus(label='bus_heat') - bus_el = solph.Bus(label='bus_el') + bus_heat = solph.Bus(label="bus_heat") + bus_el = solph.Bus(label="bus_el") self.energysystem.add(bus_heat, bus_el) d = { - 'Datum': [ - '01.02.2003 09:00', '01.02.2003 10:00', '01.02.2003 11:00'], - 'global_horizontal_W_m2': [47, 132, 131], - 'diffuse_horizontal_W_m2': [37.57155865, 69.72163199, 98.85021832], - 'temp_amb': [4, 6, 8]} + "Datum": ["01.02.2003 09:00", "01.02.2003 10:00", "01.02.2003 11:00"], + "global_horizontal_W_m2": [47, 132, 131], + "diffuse_horizontal_W_m2": [37.57155865, 69.72163199, 98.85021832], + "temp_amb": [4, 6, 8], + } input_data = pd.DataFrame(data=d) - input_data['Datum'] = pd.to_datetime(input_data['Datum']) - input_data.set_index('Datum', inplace=True) - input_data.index = input_data.index.tz_localize(tz='Europe/Berlin') - - self.energysystem.add(facades.SolarThermalCollector( - label='solar_collector', - heat_out_bus=bus_heat, - electricity_in_bus=bus_el, - electrical_consumption=0.02, - peripheral_losses=0.05, - aperture_area=1000, - latitude=52.2443, - longitude=10.5594, - collector_tilt=10, - collector_azimuth=20, - eta_0=0.73, - a_1=1.7, - a_2=0.016, - temp_collector_inlet=20, - delta_temp_n=10, - irradiance_global=input_data['global_horizontal_W_m2'], - irradiance_diffuse=input_data['diffuse_horizontal_W_m2'], - temp_amb=input_data['temp_amb'], - )) - - self.compare_to_reference_lp('solar_thermal_collector.lp') + input_data["Datum"] = pd.to_datetime(input_data["Datum"]) + input_data.set_index("Datum", inplace=True) + input_data.index = input_data.index.tz_localize(tz="Europe/Berlin") + + self.energysystem.add( + facades.SolarThermalCollector( + label="solar_collector", + heat_out_bus=bus_heat, + electricity_in_bus=bus_el, + electrical_consumption=0.02, + peripheral_losses=0.05, + aperture_area=1000, + latitude=52.2443, + longitude=10.5594, + collector_tilt=10, + collector_azimuth=20, + eta_0=0.73, + a_1=1.7, + a_2=0.016, + temp_collector_inlet=20, + delta_temp_n=10, + irradiance_global=input_data["global_horizontal_W_m2"], + irradiance_diffuse=input_data["diffuse_horizontal_W_m2"], + temp_amb=input_data["temp_amb"], + ) + ) + + self.compare_to_reference_lp("solar_thermal_collector.lp") diff --git a/tests/test_functions.py b/tests/test_functions.py index 0e316652..7ed02678 100644 --- a/tests/test_functions.py +++ b/tests/test_functions.py @@ -1,67 +1,62 @@ import os + import numpy as np import pandas as pd import pytest from pytest import approx +import oemof.thermal.absorption_heatpumps_and_chillers as ac import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chllr import oemof.thermal.concentrating_solar_power as csp -import oemof.thermal.absorption_heatpumps_and_chillers as ac from oemof.thermal.cogeneration import allocate_emissions -from oemof.thermal.stratified_thermal_storage import (calculate_storage_u_value, - calculate_storage_dimensions, - calculate_capacities, - calculate_losses) -from oemof.thermal.solar_thermal_collector import (flat_plate_precalc, - calc_eta_c_flate_plate) +from oemof.thermal.solar_thermal_collector import ( + calc_eta_c_flate_plate, + flat_plate_precalc, +) +from oemof.thermal.stratified_thermal_storage import ( + calculate_capacities, + calculate_losses, + calculate_storage_dimensions, + calculate_storage_u_value, +) def test_cop_calculation_hp(): cops_HP = cmpr_hp_chllr.calc_cops( - temp_high=[40], - temp_low=[12], - quality_grade=0.4, - mode='heat_pump') + temp_high=[40], temp_low=[12], quality_grade=0.4, mode="heat_pump" + ) assert cops_HP == [4.473571428571428] def test_calc_cops_with_Series_01(): - ambient_temp_each_hour = {'01:00': 12, '02:00': 12, '03:00': 12} + ambient_temp_each_hour = {"01:00": 12, "02:00": 12, "03:00": 12} temp_l_series = pd.Series(ambient_temp_each_hour) cops_HP = cmpr_hp_chllr.calc_cops( - temp_high=[40], - temp_low=temp_l_series, - quality_grade=0.4, - mode='heat_pump') + temp_high=[40], temp_low=temp_l_series, quality_grade=0.4, mode="heat_pump" + ) assert cops_HP == [4.473571428571428, 4.473571428571428, 4.473571428571428] def test_calc_cops_with_Series_02(): - set_temp_each_hour = {'01:00': 40, '02:00': 40, '03:00': 40} + set_temp_each_hour = {"01:00": 40, "02:00": 40, "03:00": 40} temp_h_series = pd.Series(set_temp_each_hour) cops_HP = cmpr_hp_chllr.calc_cops( - temp_high=temp_h_series, - temp_low=[12], - quality_grade=0.4, - mode='heat_pump') + temp_high=temp_h_series, temp_low=[12], quality_grade=0.4, mode="heat_pump" + ) assert cops_HP == [4.473571428571428, 4.473571428571428, 4.473571428571428] def test_cop_calculation_hp_list_input_01(): cops_HP = cmpr_hp_chllr.calc_cops( - temp_high=[40, 40], - temp_low=[12], - quality_grade=0.4, - mode='heat_pump') + temp_high=[40, 40], temp_low=[12], quality_grade=0.4, mode="heat_pump" + ) assert cops_HP == [4.473571428571428, 4.473571428571428] def test_cop_calculation_hp_list_input_02(): cops_HP = cmpr_hp_chllr.calc_cops( - temp_high=[40], - temp_low=[12, 12], - quality_grade=0.4, - mode='heat_pump') + temp_high=[40], temp_low=[12, 12], quality_grade=0.4, mode="heat_pump" + ) assert cops_HP == [4.473571428571428, 4.473571428571428] @@ -70,9 +65,10 @@ def test_cop_calculation_airsource_hp_with_icing_01(): temp_high=[40], temp_low=[1.3], quality_grade=0.5, - mode='heat_pump', + mode="heat_pump", temp_threshold_icing=2, - factor_icing=0.8) + factor_icing=0.8, + ) assert cops_ASHP == [3.236692506459949] @@ -81,18 +77,17 @@ def test_cop_calculation_airsource_hp_with_icing_02(): temp_high=[40], temp_low=[2.3], quality_grade=0.5, - mode='heat_pump', + mode="heat_pump", temp_threshold_icing=2, - factor_icing=0.8) + factor_icing=0.8, + ) assert cops_ASHP == [4.15318302387268] def test_cop_calculation_chiller(): cops_chiller = cmpr_hp_chllr.calc_cops( - temp_high=[35], - temp_low=[17], - quality_grade=0.45, - mode='chiller') + temp_high=[35], temp_low=[17], quality_grade=0.45, mode="chiller" + ) assert cops_chiller == [7.25375] @@ -103,9 +98,10 @@ def test_raised_exception_01(): temp_high=[40], temp_low=12, # ERROR - temp_low has to be a list! quality_grade=0.4, - mode='heat_pump', + mode="heat_pump", temp_threshold_icing=2, - factor_icing=0.8) + factor_icing=0.8, + ) def test_raised_exception_02(): @@ -115,9 +111,10 @@ def test_raised_exception_02(): temp_high=40, # ERROR - temp_high has to be a list! temp_low=[12], quality_grade=0.4, - mode='heat_pump', + mode="heat_pump", temp_threshold_icing=2, - factor_icing=0.8) + factor_icing=0.8, + ) def test_raised_exception_03(): @@ -129,79 +126,80 @@ def test_raised_exception_03(): temp_low=[12, 10], # ERROR - len(temp_low) has # to be 1 or equal to len(temp_high) quality_grade=0.4, - mode='heat_pump', + mode="heat_pump", temp_threshold_icing=2, - factor_icing=0.8) + factor_icing=0.8, + ) def test_raised_exception_04(): - """Test if an exception is raised if ... """ + """Test if an exception is raised if ...""" with pytest.raises(ValueError): cmpr_hp_chllr.calc_cops( temp_high=[39], temp_low=[17], quality_grade=0.4, - mode='chiller', + mode="chiller", temp_threshold_icing=2, - factor_icing=0.8) + factor_icing=0.8, + ) def test_raised_exception_05(): - """Test if an exception is raised if ... """ + """Test if an exception is raised if ...""" with pytest.raises(ValueError): cmpr_hp_chllr.calc_cops( temp_high=[39], temp_low=[17], quality_grade=0.4, - mode='chiller', + mode="chiller", temp_threshold_icing=2, - factor_icing=0.8) + factor_icing=0.8, + ) def test_calc_max_Q_dot_chill(): - nominal_conditions = { - 'nominal_Q_chill': 20, - 'nominal_el_consumption': 5} + nominal_conditions = {"nominal_Q_chill": 20, "nominal_el_consumption": 5} actual_cop = [4.5] - max_Q_chill = cmpr_hp_chllr.calc_max_Q_dot_chill(nominal_conditions, - cops=actual_cop) + max_Q_chill = cmpr_hp_chllr.calc_max_Q_dot_chill( + nominal_conditions, cops=actual_cop + ) assert max_Q_chill == [1.125] def test_raised_exceptions_05(): with pytest.raises(TypeError): actual_cop = 4.5 # ERROR - has to be of type list! - nom_cond = {'nominal_Q_chill': 20, 'nominal_el_consumption': 5} - cmpr_hp_chllr.calc_max_Q_dot_chill(nominal_conditions=nom_cond, - cops=actual_cop) + nom_cond = {"nominal_Q_chill": 20, "nominal_el_consumption": 5} + cmpr_hp_chllr.calc_max_Q_dot_chill(nominal_conditions=nom_cond, cops=actual_cop) def test_calc_max_Q_dot_heat(): - nom_cond = { - 'nominal_Q_hot': 20, - 'nominal_el_consumption': 5} + nom_cond = {"nominal_Q_hot": 20, "nominal_el_consumption": 5} actual_cop = [4.5] - max_Q_hot = cmpr_hp_chllr.calc_max_Q_dot_heat(nominal_conditions=nom_cond, - cops=actual_cop) + max_Q_hot = cmpr_hp_chllr.calc_max_Q_dot_heat( + nominal_conditions=nom_cond, cops=actual_cop + ) assert max_Q_hot == [1.125] def test_calc_chiller_quality_grade(): nom_cond = { - 'nominal_Q_chill': 20, - 'nominal_el_consumption': 5, - 't_high_nominal': 35, - 't_low_nominal': 7} + "nominal_Q_chill": 20, + "nominal_el_consumption": 5, + "t_high_nominal": 35, + "t_low_nominal": 7, + } q_grade = cmpr_hp_chllr.calc_chiller_quality_grade(nominal_conditions=nom_cond) assert q_grade == 0.39978582902016785 def test_calculate_storage_u_value(): params = { - 's_iso': 50, # mm - 'lamb_iso': 0.05, # W/(m*K) - 'alpha_inside': 1, # W/(m2*K) - 'alpha_outside': 1 # W/(m2*K) + "s_iso": 50, # mm + "lamb_iso": 0.05, # W/(m*K) + "alpha_inside": 1, # W/(m2*K) + "alpha_outside": 1, # W/(m2*K) } u_value = calculate_storage_u_value(**params) @@ -210,8 +208,8 @@ def test_calculate_storage_u_value(): def test_calculate_storage_dimensions(): params = { - 'height': 10, # m - 'diameter': 10, # m + "height": 10, # m + "diameter": 10, # m } volume, surface = calculate_storage_dimensions(**params) @@ -220,9 +218,9 @@ def test_calculate_storage_dimensions(): def test_calculate_capacities(): params = { - 'volume': 1000, # m3 - 'temp_h': 100, # deg C - 'temp_c': 50, # deg C + "volume": 1000, # m3 + "temp_h": 100, # deg C + "temp_c": 50, # deg C } nominal_storage_capacity = calculate_capacities(**params) @@ -231,96 +229,96 @@ def test_calculate_capacities(): def test_calculate_losses(): params = { - 'u_value': 1, # W/(m2*K) - 'diameter': 10, # m - 'temp_h': 100, # deg C - 'temp_c': 50, # deg C - 'temp_env': 10, # deg C + "u_value": 1, # W/(m2*K) + "diameter": 10, # m + "temp_h": 100, # deg C + "temp_c": 50, # deg C + "temp_env": 10, # deg C } loss_rate, fixed_losses_relative, fixed_losses_absolute = calculate_losses(**params) - assert loss_rate == 0.0003531819182021882\ - and fixed_losses_relative == 0.00028254553456175054\ + assert ( + loss_rate == 0.0003531819182021882 + and fixed_losses_relative == 0.00028254553456175054 and fixed_losses_absolute == 0.010210176124166827 + ) def test_allocate_emissions(): emissions_dict = {} - for method in ['iea', 'efficiency', 'finnish']: + for method in ["iea", "efficiency", "finnish"]: emissions_dict[method] = allocate_emissions( total_emissions=200, eta_el=0.3, eta_th=0.5, method=method, eta_el_ref=0.525, - eta_th_ref=0.82 + eta_th_ref=0.82, ) result = { - 'iea': (75.0, 125.0), - 'efficiency': (125.0, 75.0), - 'finnish': (96.7551622418879, 103.24483775811208)} + "iea": (75.0, 125.0), + "efficiency": (125.0, 75.0), + "finnish": (96.7551622418879, 103.24483775811208), + } assert emissions_dict == result def test_allocate_emission_series(): emissions_dict = {} - for method in ['iea', 'efficiency', 'finnish']: + for method in ["iea", "efficiency", "finnish"]: emissions_dict[method] = allocate_emissions( total_emissions=pd.Series([200, 200]), eta_el=pd.Series([0.3, 0.3]), eta_th=pd.Series([0.5, 0.5]), method=method, eta_el_ref=pd.Series([0.525, 0.525]), - eta_th_ref=pd.Series([0.82, 0.82]) + eta_th_ref=pd.Series([0.82, 0.82]), ) default = { - 'iea': ( - pd.Series([75.0, 75.0]), - pd.Series([125.0, 125.0]) - ), - 'efficiency': ( - pd.Series([125.0, 125.0]), - pd.Series([75.0, 75.0]) - ), - 'finnish': ( + "iea": (pd.Series([75.0, 75.0]), pd.Series([125.0, 125.0])), + "efficiency": (pd.Series([125.0, 125.0]), pd.Series([75.0, 75.0])), + "finnish": ( pd.Series([96.7551622418879, 96.7551622418879]), - pd.Series([103.24483775811208, 103.24483775811208]) - )} + pd.Series([103.24483775811208, 103.24483775811208]), + ), + } for key in default: for em_result, em_default in zip(emissions_dict[key], default[key]): - assert em_result.equals(em_default),\ - f"Result \n{em_result} does not match default \n{em_default}" + assert em_result.equals( + em_default + ), f"Result \n{em_result} does not match default \n{em_default}" def test_calculation_of_collector_irradiance(): s = pd.Series([10, 20, 30], index=[1, 2, 3]) res = csp.calc_collector_irradiance(s, 0.9) result = pd.Series( - [8.5381496824546242, 17.0762993649092484, 25.614449047363873], - index=[1, 2, 3]) + [8.5381496824546242, 17.0762993649092484, 25.614449047363873], index=[1, 2, 3] + ) assert res.values == approx(result.values) def test_calculation_iam_for_single_value(): - res = csp.calc_iam(-0.00159, 0.0000977, 0, 0, 0, 0, 50, 'Janotte') + res = csp.calc_iam(-0.00159, 0.0000977, 0, 0, 0, 0, 50, "Janotte") assert res == 0.8352499999999999 def test_calculation_iam_andasol(): - res = csp.calc_iam(-8.65e-4, 8.87e-4, -5.425e-5, 1.665e-6, -2.309e-8, - 1.197e-10, 50, 'Andasol') + res = csp.calc_iam( + -8.65e-4, 8.87e-4, -5.425e-5, 1.665e-6, -2.309e-8, 1.197e-10, 50, "Andasol" + ) assert res == 0.5460625000000001 def test_calculation_iam_for_a_series(): s = pd.Series([10, 20, 30], index=[1, 2, 3]) - res = csp.calc_iam(-0.00159, 0.0000977, 0, 0, 0, 0, s, 'Janotte') + res = csp.calc_iam(-0.00159, 0.0000977, 0, 0, 0, 0, s, "Janotte") result = pd.Series([1.00613, 0.99272, 0.95977], index=[1, 2, 3]) assert res.eq(result).all() @@ -332,19 +330,30 @@ def test_csp_different_timeindex(): E_dir_hor = pd.Series([30, 40], index=[1, 2]) t_amb = pd.Series([30, 40], index=[2, 3]) with pytest.raises(IndexError): - csp.csp_precalc(20, 60, - 10, 180, 0.9, - 0.78, 0.816, 0.0622, - 235, 300, t_amb, - -8.65e-4, 8.87e-4, - loss_method='Janotte', - E_dir_hor=E_dir_hor) + csp.csp_precalc( + 20, + 60, + 10, + 180, + 0.9, + 0.78, + 0.816, + 0.0622, + 235, + 300, + t_amb, + -8.65e-4, + 8.87e-4, + loss_method="Janotte", + E_dir_hor=E_dir_hor, + ) def test_csp_wrong_loss_method(): with pytest.raises(ValueError): - df = pd.DataFrame(data={'date': [1, 2], 'E_dir_hor': [ - 30, 40], 't_amb': [30, 40]}) + df = pd.DataFrame( + data={"date": [1, 2], "E_dir_hor": [30, 40], "t_amb": [30, 40]} + ) latitude = 23.614328 longitude = 58.545284 collector_tilt = 10 @@ -357,107 +366,131 @@ def test_csp_wrong_loss_method(): c_2 = 0.0622 temp_collector_inlet = 235 temp_collector_outlet = 300 - csp.csp_precalc(latitude, longitude, - collector_tilt, collector_azimuth, cleanliness, - eta_0, c_1, c_2, - temp_collector_inlet, temp_collector_outlet, df['t_amb'], - a_1, a_2, a_3=0, a_4=0, a_5=0, a_6=0, - loss_method='quatsch') + csp.csp_precalc( + latitude, + longitude, + collector_tilt, + collector_azimuth, + cleanliness, + eta_0, + c_1, + c_2, + temp_collector_inlet, + temp_collector_outlet, + df["t_amb"], + a_1, + a_2, + a_3=0, + a_4=0, + a_5=0, + a_6=0, + loss_method="quatsch", + ) def test_eta_janotte(): s = pd.Series([50], index=[1]) - res = csp.calc_eta_c(0.816, 0.0622, 0.00023, 0.95, 235, 300, 30, s, - 'Janotte') + res = csp.calc_eta_c(0.816, 0.0622, 0.00023, 0.95, 235, 300, 30, s, "Janotte") result = pd.Series([0.22028124999999987], index=[1]) assert res.eq(result).all() def test_eta_andasol(): s = pd.Series([100], index=[1]) - res = csp.calc_eta_c(0.816, 64, 0.00023, 0.95, 235, 300, 30, s, - 'Andasol') + res = csp.calc_eta_c(0.816, 64, 0.00023, 0.95, 235, 300, 30, s, "Andasol") result = pd.Series([0.13519999999999988], index=[1]) assert res.eq(result).all() def test_flat_plate_precalc(): d = { - 'Datum': [ - '01.01.2003 12:00', '01.01.2003 13:00'], - 'global_horizontal_W_m2': [112, 129], - 'diffuse_horizontal_W_m2': [100.3921648, 93.95959036], - 'temp_amb': [9, 10]} + "Datum": ["01.01.2003 12:00", "01.01.2003 13:00"], + "global_horizontal_W_m2": [112, 129], + "diffuse_horizontal_W_m2": [100.3921648, 93.95959036], + "temp_amb": [9, 10], + } input_data = pd.DataFrame(data=d) - input_data['Datum'] = pd.to_datetime(input_data['Datum']) - input_data.set_index('Datum', inplace=True) - input_data.index = input_data.index.tz_localize(tz='Europe/Berlin') + input_data["Datum"] = pd.to_datetime(input_data["Datum"]) + input_data.set_index("Datum", inplace=True) + input_data.index = input_data.index.tz_localize(tz="Europe/Berlin") params = { - 'lat': 52.2443, - 'long': 10.5594, - 'collector_tilt': 10, - 'collector_azimuth': 20, - 'eta_0': 0.73, - 'a_1': 1.7, - 'a_2': 0.016, - 'temp_collector_inlet': 20, - 'delta_temp_n': 10, - 'irradiance_global': input_data['global_horizontal_W_m2'], - 'irradiance_diffuse': input_data['diffuse_horizontal_W_m2'], - 'temp_amb': input_data['temp_amb'] + "lat": 52.2443, + "long": 10.5594, + "collector_tilt": 10, + "collector_azimuth": 20, + "eta_0": 0.73, + "a_1": 1.7, + "a_2": 0.016, + "temp_collector_inlet": 20, + "delta_temp_n": 10, + "irradiance_global": input_data["global_horizontal_W_m2"], + "irradiance_diffuse": input_data["diffuse_horizontal_W_m2"], + "temp_amb": input_data["temp_amb"], } # Save return value from flat_plate_precalc(...) as data data = flat_plate_precalc(**params) # Data frame containing separately calculated results - results = pd.DataFrame({'eta_c': [0.32003169094533845, 0.34375125091055275], - 'collectors_heat': [33.37642124, 35.95493984]}) + results = pd.DataFrame( + { + "eta_c": [0.32003169094533845, 0.34375125091055275], + "collectors_heat": [33.37642124, 35.95493984], + } + ) - assert data['eta_c'].values == approx(results['eta_c'].values) and \ - data['collectors_heat'].values == approx(results['collectors_heat'].values) + assert data["eta_c"].values == approx(results["eta_c"].values) and data[ + "collectors_heat" + ].values == approx(results["collectors_heat"].values) def test_calc_eta_c_flate_plate(): - temp_amb = pd.DataFrame({'date': ['1970-01-01 00:00:00.000000001+01:00'], - 'temp_amb': [9]}) - temp_amb.set_index('date', inplace=True) - - collector_irradiance = pd.DataFrame({'date': ['1970-01-01 00:00:00.000000001+01:00'], - 'poa_global': 99.84226497618872}) - collector_irradiance.set_index('date', inplace=True) + temp_amb = pd.DataFrame( + {"date": ["1970-01-01 00:00:00.000000001+01:00"], "temp_amb": [9]} + ) + temp_amb.set_index("date", inplace=True) + + collector_irradiance = pd.DataFrame( + { + "date": ["1970-01-01 00:00:00.000000001+01:00"], + "poa_global": 99.84226497618872, + } + ) + collector_irradiance.set_index("date", inplace=True) params = { - 'eta_0': 0.73, - 'a_1': 1.7, - 'a_2': 0.016, - 'temp_collector_inlet': 20, - 'delta_temp_n': 10, - 'temp_amb': temp_amb['temp_amb'], - 'collector_irradiance': collector_irradiance['poa_global'] + "eta_0": 0.73, + "a_1": 1.7, + "a_2": 0.016, + "temp_collector_inlet": 20, + "delta_temp_n": 10, + "temp_amb": temp_amb["temp_amb"], + "collector_irradiance": collector_irradiance["poa_global"], } data = calc_eta_c_flate_plate(**params) - assert data.values == approx(0.30176452266786186) # Adjust this value + assert data.values == approx(0.30176452266786186) # Adjust this value def test_calc_characteristic_temp_Kuehn(): """Test characteristic temperature calculation for chiller 'Kuehn'.""" filename_charpara = os.path.join( os.path.dirname(__file__), - '../examples/absorption_heatpump_and_chiller/' - 'data/characteristic_parameters.csv') + "../examples/absorption_heatpump_and_chiller/" + "data/characteristic_parameters.csv", + ) charpara = pd.read_csv(filename_charpara) - chiller_name = 'Kuehn' + chiller_name = "Kuehn" ddt = ac.calc_characteristic_temp( t_hot=[85, 85], t_cool=[30], t_chill=[15], - coef_a=charpara[(charpara['name'] == chiller_name)]['a'].values[0], - coef_e=charpara[(charpara['name'] == chiller_name)]['e'].values[0], - method='kuehn_and_ziegler') + coef_a=charpara[(charpara["name"] == chiller_name)]["a"].values[0], + coef_e=charpara[(charpara["name"] == chiller_name)]["e"].values[0], + method="kuehn_and_ziegler", + ) assert ddt == [37, 37] @@ -465,19 +498,21 @@ def test_calc_characteristic_temp_Braod_01(): """Test characteristic temperature calculation for chiller 'Broad_01'.""" filename_charpara = os.path.join( os.path.dirname(__file__), - '../examples/absorption_heatpump_and_chiller/' - 'data/characteristic_parameters.csv') + "../examples/absorption_heatpump_and_chiller/" + "data/characteristic_parameters.csv", + ) charpara = pd.read_csv(filename_charpara) - chiller_name = 'Broad_01' + chiller_name = "Broad_01" n = 2 ddt = ac.calc_characteristic_temp( t_hot=[85] * n, t_cool=[30], t_chill=[15], - coef_a=charpara[(charpara['name'] == chiller_name)]['a'].values[0], - coef_e=charpara[(charpara['name'] == chiller_name)]['e'].values[0], - method='kuehn_and_ziegler') + coef_a=charpara[(charpara["name"] == chiller_name)]["a"].values[0], + coef_e=charpara[(charpara["name"] == chiller_name)]["e"].values[0], + method="kuehn_and_ziegler", + ) assert ddt == [61.45, 61.45] @@ -485,19 +520,21 @@ def test_calc_characteristic_temp_Braod_02(): """Test characteristic temperature calculation for chiller 'Broad_02'.""" filename_charpara = os.path.join( os.path.dirname(__file__), - '../examples/absorption_heatpump_and_chiller/' - 'data/characteristic_parameters.csv') + "../examples/absorption_heatpump_and_chiller/" + "data/characteristic_parameters.csv", + ) charpara = pd.read_csv(filename_charpara) - chiller_name = 'Broad_02' + chiller_name = "Broad_02" n = 2 ddt = ac.calc_characteristic_temp( t_hot=[85] * n, t_cool=[30], t_chill=[15], - coef_a=charpara[(charpara['name'] == chiller_name)]['a'].values[0], - coef_e=charpara[(charpara['name'] == chiller_name)]['e'].values[0], - method='kuehn_and_ziegler') + coef_a=charpara[(charpara["name"] == chiller_name)]["a"].values[0], + coef_e=charpara[(charpara["name"] == chiller_name)]["e"].values[0], + method="kuehn_and_ziegler", + ) assert ddt == [87.625, 87.625] @@ -505,19 +542,21 @@ def test_calc_characteristic_temp_Rotartica(): """Test characteristic temperature calculation for chiller 'Rotartica'.""" filename_charpara = os.path.join( os.path.dirname(__file__), - '../examples/absorption_heatpump_and_chiller/' - 'data/characteristic_parameters.csv') + "../examples/absorption_heatpump_and_chiller/" + "data/characteristic_parameters.csv", + ) charpara = pd.read_csv(filename_charpara) - chiller_name = 'Rotartica' + chiller_name = "Rotartica" n = 2 ddt = ac.calc_characteristic_temp( t_hot=[85] * n, t_cool=[30], t_chill=[15], - coef_a=charpara[(charpara['name'] == chiller_name)]['a'].values[0], - coef_e=charpara[(charpara['name'] == chiller_name)]['e'].values[0], - method='kuehn_and_ziegler') + coef_a=charpara[(charpara["name"] == chiller_name)]["a"].values[0], + coef_e=charpara[(charpara["name"] == chiller_name)]["e"].values[0], + method="kuehn_and_ziegler", + ) assert ddt == [approx(32.125), approx(32.125)] @@ -525,19 +564,21 @@ def test_calc_characteristic_temp_Safarik(): """Test characteristic temperature calculation for chiller 'Safarik'.""" filename_charpara = os.path.join( os.path.dirname(__file__), - '../examples/absorption_heatpump_and_chiller/' - 'data/characteristic_parameters.csv') + "../examples/absorption_heatpump_and_chiller/" + "data/characteristic_parameters.csv", + ) charpara = pd.read_csv(filename_charpara) - chiller_name = 'Safarik' + chiller_name = "Safarik" n = 2 ddt = ac.calc_characteristic_temp( t_hot=[85] * n, t_cool=[30], t_chill=[15], - coef_a=charpara[(charpara['name'] == chiller_name)]['a'].values[0], - coef_e=charpara[(charpara['name'] == chiller_name)]['e'].values[0], - method='kuehn_and_ziegler') + coef_a=charpara[(charpara["name"] == chiller_name)]["a"].values[0], + coef_e=charpara[(charpara["name"] == chiller_name)]["e"].values[0], + method="kuehn_and_ziegler", + ) assert ddt == [approx(54.64), approx(54.64)] @@ -550,27 +591,24 @@ def test_calc_characteristic_temp_input_list_single_entry(): t_chill=[15], coef_a=2.5, coef_e=1.8, - method='kuehn_and_ziegler') + method="kuehn_and_ziegler", + ) assert ddt == [37] def test_calc_heat_flux_evaporator(): """Test calculation of cooling capacity for chiller 'Broad_01'.""" Q_dots_evap = ac.calc_heat_flux( - ddts=[50], - coef_s=24.121, - coef_r=-553.194, - method='kuehn_and_ziegler') + ddts=[50], coef_s=24.121, coef_r=-553.194, method="kuehn_and_ziegler" + ) assert Q_dots_evap == [652.856] def test_calc_heat_flux_generator(): """Test calculation of driving heat for chiller 'Broad_02'.""" Q_dots_gen = ac.calc_heat_flux( - ddts=[110], - coef_s=10.807, - coef_r=-603.85, - method='kuehn_and_ziegler') + ddts=[110], coef_s=10.807, coef_r=-603.85, method="kuehn_and_ziegler" + ) assert Q_dots_gen == [584.92] @@ -583,7 +621,8 @@ def test_raised_exception_argument_type_01(): t_chill=[15], coef_a=2.5, coef_e=1.8, - method='kuehn_and_ziegler') + method="kuehn_and_ziegler", + ) def test_raised_exception_argument_type_02(): @@ -595,7 +634,8 @@ def test_raised_exception_argument_type_02(): t_chill=[15], coef_a=2.5, coef_e=1.8, - method='kuehn_and_ziegler') + method="kuehn_and_ziegler", + ) def test_raised_exception_argument_type_03(): @@ -607,7 +647,8 @@ def test_raised_exception_argument_type_03(): t_chill=15, coef_a=2.5, coef_e=1.8, - method='kuehn_and_ziegler') + method="kuehn_and_ziegler", + ) def test_raised_exception_argument_length_01(): @@ -619,7 +660,8 @@ def test_raised_exception_argument_length_01(): t_chill=[15] * 2, coef_a=2.5, coef_e=1.8, - method='kuehn_and_ziegler') + method="kuehn_and_ziegler", + ) def test_raised_exception_argument_length_02(): @@ -631,7 +673,8 @@ def test_raised_exception_argument_length_02(): t_chill=[15] * 3, coef_a=2.5, coef_e=1.8, - method='kuehn_and_ziegler') + method="kuehn_and_ziegler", + ) def test_raised_exception_method_selection_01(): @@ -643,14 +686,11 @@ def test_raised_exception_method_selection_01(): t_chill=[15], coef_a=2.5, coef_e=1.8, - method='shaken_not_stirred') + method="shaken_not_stirred", + ) def test_raised_exception_method_selection_02(): """Test if an exception is raised if unknown method name is passed.""" with pytest.raises(ValueError): - ac.calc_heat_flux( - ddts=25, - coef_s=0.42, - coef_r=0.9, - method='shaken_not_stirred') + ac.calc_heat_flux(ddts=25, coef_s=0.42, coef_r=0.9, method="shaken_not_stirred") From 4109fcbf54b0a6551cef9b63a390d8149400c3e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 8 Oct 2024 21:09:03 +0200 Subject: [PATCH 09/34] Fix sphinx config --- docs/conf.py | 199 ++++++++++++++++++++++++++------------------------- 1 file changed, 103 insertions(+), 96 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index ae363705..f7b69f3b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,12 +20,12 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath("..")) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' rst_prolog = """ .. role:: py(code) @@ -38,119 +38,118 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.autosummary', - 'sphinx.ext.viewcode', - 'sphinx.ext.imgmath', - 'sphinx.ext.napoleon' + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.viewcode", + "sphinx.ext.imgmath", + "sphinx.ext.napoleon", ] numpydoc_show_class_members = False # -autoclass_content = 'both' +autoclass_content = "both" # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'oemof.thermal' -copyright = u'2014-2019, oemof developer group' -author = u'oemof developer group' +project = "oemof.thermal" +copyright = "2014-2019, oemof developer group" +author = "oemof developer group" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '' +version = "" # The full version, including alpha/beta/rc tags. -release = '' +release = "" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build', 'whatsnew/*'] +exclude_patterns = ["_build", "whatsnew/*"] # The reST default role (used for this markup: `text`) to use for all # documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -#html_theme = 'bizstyle' +# html_theme = 'bizstyle' html_theme = "sphinx_rtd_theme" -html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = { -# "sidebarwidth": "25em", -# "documentwidth":"50em", -# "pagewidth": "75em", -# } +# html_theme_options = { +# "sidebarwidth": "25em", +# "documentwidth":"50em", +# "pagewidth": "75em", +# } # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, @@ -160,51 +159,51 @@ # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -#html_extra_path = [] +# html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'oemof_doc' +htmlhelp_basename = "oemof_doc" # -- Options for LaTeX output --------------------------------------------- @@ -212,10 +211,8 @@ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. #'preamble': '', } @@ -224,29 +221,34 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ('index', 'oemof_thermal.tex', u'oemof.thermal documentation', - u'oemof developer group', 'manual'), + ( + "index", + "oemof_thermal.tex", + "oemof.thermal documentation", + "oemof developer group", + "manual", + ), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output --------------------------------------- @@ -254,12 +256,11 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'oemof', u'oemof.thermal documentation', - [u'oemof developer group'], 1) + ("index", "oemof", "oemof.thermal documentation", ["oemof developer group"], 1) ] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------- @@ -268,89 +269,95 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'oemof.thermal', u'oemof.thermal documentation', - u'Author', 'oemof developer group', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "oemof.thermal", + "oemof.thermal documentation", + "Author", + "oemof developer group", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# texinfo_no_detailmenu = False # -- Options for Epub output ---------------------------------------------- # Bibliographic Dublin Core info. -epub_title = u'oemof.thermal' -epub_author = u'oemof developer group' -epub_publisher = u'oemof developer group' -epub_copyright = u'2019, oemof developer group' +epub_title = "oemof.thermal" +epub_author = "oemof developer group" +epub_publisher = "oemof developer group" +epub_copyright = "2019, oemof developer group" # The basename for the epub file. It defaults to the project name. -#epub_basename = u'pahesmf' +# epub_basename = u'pahesmf' # The HTML theme for the epub output. Since the default themes are not optimized # for small screen space, using the same theme for HTML and epub output is # usually not wise. This defaults to 'epub', a theme designed to save visual # space. -#epub_theme = 'epub' +# epub_theme = 'epub' # The language of the text. It defaults to the language option # or en if the language is not set. -#epub_language = '' +# epub_language = '' # The scheme of the identifier. Typical schemes are ISBN or URL. -#epub_scheme = '' +# epub_scheme = '' # The unique identifier of the text. This can be a ISBN number # or the project homepage. -#epub_identifier = '' +# epub_identifier = '' # A unique identification for the text. -#epub_uid = '' +# epub_uid = '' # A tuple containing the cover image and cover page html template filenames. -#epub_cover = () +# epub_cover = () # A sequence of (type, uri, title) tuples for the guide element of content.opf. -#epub_guide = () +# epub_guide = () # HTML files that should be inserted before the pages created by sphinx. # The format is a list of tuples containing the path and title. -#epub_pre_files = [] +# epub_pre_files = [] # HTML files shat should be inserted after the pages created by sphinx. # The format is a list of tuples containing the path and title. -#epub_post_files = [] +# epub_post_files = [] # A list of files that should not be packed into the epub file. -epub_exclude_files = ['search.html'] +epub_exclude_files = ["search.html"] # The depth of the table of contents in toc.ncx. -#epub_tocdepth = 3 +# epub_tocdepth = 3 # Allow duplicate toc entries. -#epub_tocdup = True +# epub_tocdup = True # Choose between 'default' and 'includehidden'. -#epub_tocscope = 'default' +# epub_tocscope = 'default' # Fix unsupported image types using the PIL. -#epub_fix_images = False +# epub_fix_images = False # Scale large images. -#epub_max_image_width = 0 +# epub_max_image_width = 0 # How to display URL addresses: 'footnote', 'no', or 'inline'. -#epub_show_urls = 'inline' +# epub_show_urls = 'inline' # If false, no index is generated. -#epub_use_index = True +# epub_use_index = True From 29cf5ad8bf5b23e992177a523928e82be4605cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 8 Oct 2024 21:19:21 +0200 Subject: [PATCH 10/34] Fix format of docs I also deleted files that had no content and were not included in the docs. --- docs/_pics/README.rst | 12 -- docs/examples.rst | 12 +- ...on_compression_heat_pumps_and_chillers.rst | 4 +- docs/validation_concentrating_solar_power.rst | 6 - docs/validation_solar_thermal_collector.rst | 8 -- docs/whats_new/v0-0-4.rst | 2 +- docs/whats_new/v0-0-7.rst | 2 +- .../compression_heatpumps_and_chillers.py | 114 ++++++++++-------- 8 files changed, 73 insertions(+), 87 deletions(-) delete mode 100644 docs/_pics/README.rst delete mode 100644 docs/validation_concentrating_solar_power.rst delete mode 100644 docs/validation_solar_thermal_collector.rst diff --git a/docs/_pics/README.rst b/docs/_pics/README.rst deleted file mode 100644 index 507d2531..00000000 --- a/docs/_pics/README.rst +++ /dev/null @@ -1,12 +0,0 @@ -Handling figures and images ----------------------------- - -Requirements towards formats of images have to be met with regard to chosen download: - -- **pdf**: png, jpeg, pdf -- **html**: please check your browser compatibility -- **epub**: png, jpeg, gif, svg - -In order to match the compatibility of every download source, png should be preferred. Please ensure a resolution of 300 - 600 dpi as a guide value. - -If your original image is a vector graphics (e.g. svg), it is advised to upload the original file to keep it possible to make adaptions at a later point in time. diff --git a/docs/examples.rst b/docs/examples.rst index 3e9c07c0..6fd58b2a 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -32,7 +32,7 @@ In addition to that, the example provides a manual on using the 'calc_cops' func to get the COPs of a heat pump, by plotting the temperature dependency of the COP, and COPs of an exemplary ground-source heat pump (GSHP) using the soil temperature as low temperature heat reservoir. -The Examples can be found `here `_. +The Examples can be found `at compression_heatpumps_and_chiller `_. **Absorption Chiller** @@ -40,7 +40,7 @@ The first example shows the behaviour of the coefficient of performance and heat for different cooling water temperatures based on the characteristic equation method. The second example underlines the dependence of the temperature of the cooling water on the cooling capacity. -The Examples can be found `here `_. +The Examples can be found `at absorption_heatpumps_and_chiller `_. **Concentrating solar power (CSP)** @@ -50,7 +50,7 @@ The collector's efficiency and irradiance can be calculated with two different l An application is presented which models a csp plant to meet an electrical demand. The plant itself consists of a parabolic trough collector field, a turbine, and a storage. -The Examples can be found `here `_. +The Examples can be found `at concentrating_solar_power `_. **Solar thermal collector** @@ -58,7 +58,7 @@ In these examples the functionality of the solar thermal collector is shown. Once with a fixed collector size (aperture area), once with a fixed collector size using the facade and another time with a collector size to be invested. It also provides plots which can be called by the flat_plate_collector_example.py. -The Examples can be found `here `_. +The Examples can be found `at solar_thermal_collector `_. **Stratified thermal storage** @@ -68,12 +68,12 @@ to specify a storage in a model that optimizes operation with oemof-solph. Furth Furthermore the examples show how to invest into nominal_storage_capacity and capacity (charging/discharging power) with a fixed ratio and independently with no fixed ratio. -The Examples can be found `here `_. +The Examples can be found `at stratified_thermal_storage `_. **Cogeneration** We further provide an example on different emission allocation methods in cogeneration. -This Example can be found `here `_. +This Example can be found `at cogeneration `_. List of available models diff --git a/docs/validation_compression_heat_pumps_and_chillers.rst b/docs/validation_compression_heat_pumps_and_chillers.rst index fa570b3e..4f05a6b2 100644 --- a/docs/validation_compression_heat_pumps_and_chillers.rst +++ b/docs/validation_compression_heat_pumps_and_chillers.rst @@ -11,7 +11,7 @@ The validation of the compression heat pump and chiller has been conducted withi `_. Monitored data of the two components in combination with PV without storage has been provided by Universidad Politécnica de Madrid (UPM). An open access publication containing further description of the data and experiments done -in [2] is planned for November 2020. +in [2]_ is planned for November 2020. Both, heat pump and chiller, are working with air to air technology. The set of data contains amongst others external and internal temperatures of the components and a calculated Coefficient of performance (COP) / Energy Efficiency Ratio (EER) value. The code used for the validation can @@ -54,7 +54,7 @@ temperature hub as well as the relation between residuals and monitored coeffici Results of the chiller ______________________ -Typical EER of chillers used for cooling are around 4 to 5 [1]. By adhering to these reference values we conclude +Typical EER of chillers used for cooling are around 4 to 5 [1]_. By adhering to these reference values we conclude that EERs with quality grades ranging from 0.25 to 0.4 give fitting results. The RMSE for the validated quality grades presents the standard deviation of the residuals. Among the range of quality diff --git a/docs/validation_concentrating_solar_power.rst b/docs/validation_concentrating_solar_power.rst deleted file mode 100644 index 277b4cf0..00000000 --- a/docs/validation_concentrating_solar_power.rst +++ /dev/null @@ -1,6 +0,0 @@ -.. _validation_csp_label: - -~~~~~~~~~~~~~~~~~~~~~~~~~ -Concentrating solar power -~~~~~~~~~~~~~~~~~~~~~~~~~ - diff --git a/docs/validation_solar_thermal_collector.rst b/docs/validation_solar_thermal_collector.rst deleted file mode 100644 index b153a1a6..00000000 --- a/docs/validation_solar_thermal_collector.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. _validation_solar_thermal_collector_label: - -~~~~~~~~~~~~~~~~~~~~~~~ -Solar thermal collector -~~~~~~~~~~~~~~~~~~~~~~~ - - - diff --git a/docs/whats_new/v0-0-4.rst b/docs/whats_new/v0-0-4.rst index 40c8322a..8ff88a00 100644 --- a/docs/whats_new/v0-0-4.rst +++ b/docs/whats_new/v0-0-4.rst @@ -1,5 +1,5 @@ v0.0.4 (October 14, 2020) -============= +========================= New features ------------ diff --git a/docs/whats_new/v0-0-7.rst b/docs/whats_new/v0-0-7.rst index cca984b7..9f474fe0 100644 --- a/docs/whats_new/v0-0-7.rst +++ b/docs/whats_new/v0-0-7.rst @@ -1,5 +1,5 @@ v0.0.7.dev (???) -============= +================ API Changes ----------- diff --git a/src/oemof/thermal/compression_heatpumps_and_chillers.py b/src/oemof/thermal/compression_heatpumps_and_chillers.py index 06f455e9..b7cb6148 100644 --- a/src/oemof/thermal/compression_heatpumps_and_chillers.py +++ b/src/oemof/thermal/compression_heatpumps_and_chillers.py @@ -14,9 +14,9 @@ import pandas as pd -def calc_cops(mode, temp_high, temp_low, quality_grade, temp_threshold_icing=2, - factor_icing=None): - +def calc_cops( + mode, temp_high, temp_low, quality_grade, temp_threshold_icing=2, factor_icing=None +): r""" Calculates the Coefficient of Performance (COP) of heat pumps and chillers based on the Carnot efficiency (ideal process) and a scale-down factor. @@ -51,7 +51,7 @@ def calc_cops(mode, temp_high, temp_low, quality_grade, temp_threshold_icing=2, quality_grade : numerical value Factor that scales down the efficiency of the real heat pump (or chiller) process from the ideal process (Carnot efficiency), where - a factor of 1 means teh real process is equal to the ideal one. + a factor of 1 means teh real process is equal to the ideal one. factor_icing: numerical value Sets the relative COP drop caused by icing, where 1 stands for no efficiency-drop. @@ -73,14 +73,15 @@ def calc_cops(mode, temp_high, temp_low, quality_grade, temp_threshold_icing=2, raise TypeError("Argument 'temp_low' is not of type list or pd.Series!") if not isinstance(temp_high, (list, pd.Series)): - raise TypeError("Argument 'temp_high' is not of " - "type list or pd.Series!") + raise TypeError("Argument 'temp_high' is not of " "type list or pd.Series!") if len(temp_high) != len(temp_low): if (len(temp_high) != 1) and ((len(temp_low) != 1)): - raise IndexError("Arguments 'temp_low' and 'temp_high' " - "have to be of same length or one has " - "to be of length 1 !") + raise IndexError( + "Arguments 'temp_low' and 'temp_high' " + "have to be of same length or one has " + "to be of length 1 !" + ) # if factor_icing is not None and consider_icing is False: # raise ValueError('Argument factor_icing can not be used without ' @@ -105,11 +106,15 @@ def calc_cops(mode, temp_high, temp_low, quality_grade, temp_threshold_icing=2, # Calculate COPs depending on selected mode (without icing). if factor_icing is None: if mode == "heat_pump": - cops = [quality_grade * t_h / (t_h - t_l) for - t_h, t_l in zip(list_temp_high_K, list_temp_low_K)] + cops = [ + quality_grade * t_h / (t_h - t_l) + for t_h, t_l in zip(list_temp_high_K, list_temp_low_K) + ] elif mode == "chiller": - cops = [quality_grade * t_l / (t_h - t_l) for - t_h, t_l in zip(list_temp_high_K, list_temp_low_K)] + cops = [ + quality_grade * t_l / (t_h - t_l) + for t_h, t_l in zip(list_temp_high_K, list_temp_low_K) + ] # Calculate COPs of a heat pump and lower COP when icing occurs. elif factor_icing is not None: @@ -122,8 +127,9 @@ def calc_cops(mode, temp_high, temp_low, quality_grade, temp_threshold_icing=2, if t_l >= temp_threshold_icing + 273.15: cops = cops + [quality_grade * t_h / (t_h - t_l)] elif mode == "chiller": - raise ValueError("Argument 'factor_icing' has " - "to be None for mode='chiller'!") + raise ValueError( + "Argument 'factor_icing' has " "to be None for mode='chiller'!" + ) return cops @@ -165,50 +171,54 @@ def calc_max_Q_dot_chill(nominal_conditions, cops): if not isinstance(cops, list): raise TypeError("Argument 'cops' is not of type list!") - nominal_cop = (nominal_conditions['nominal_Q_chill'] / nominal_conditions[ - 'nominal_el_consumption']) + nominal_cop = ( + nominal_conditions["nominal_Q_chill"] + / nominal_conditions["nominal_el_consumption"] + ) max_Q_chill = [actual_cop / nominal_cop for actual_cop in cops] return max_Q_chill def calc_max_Q_dot_heat(nominal_conditions, cops): r""" - Calculates the maximal heating capacity (relative value) of a - heat pump. - - Note - ---- - This function assumes the heating capacity of a heat pump can exceed - the rated nominal capacity (e.g., from the technical specification - sheet). That means: The value of :py:obj:`max_Q_hot` can be greater - than 1. - Make sure your actual heat pump is capable of doing so. - If not, use 1 for the maximal heating capacity. + Calculates the maximal heating capacity (relative value) of a + heat pump. + + Note + ---- + This function assumes the heating capacity of a heat pump can exceed + the rated nominal capacity (e.g., from the technical specification + sheet). That means: The value of :py:obj:`max_Q_hot` can be greater + than 1. + Make sure your actual heat pump is capable of doing so. + If not, use 1 for the maximal heating capacity. .. calc_max_Q_dot_heat-equations: :math:`\dot{Q}_\mathrm{hot, max} = \frac{COP_\mathrm{actual}}{COP_\mathrm{nominal}}` - Parameters - ---------- - nominal_conditions : dict - Dictionary describing one operating point (e.g., operation - under STC) of the heat pump by its - heating capacity, its electricity consumption and its COP - ('nominal_Q_hot', 'nominal_el_consumption' and 'nominal_cop') - cops : list of numerical values - Actual COP - - Returns - ------- - max_Q_hot : list of numerical values - Maximal heating capacity (relative value). Value is equal or - greater than 0 and can be greater than 1. - - """ - nominal_cop = (nominal_conditions['nominal_Q_hot'] / nominal_conditions[ - 'nominal_el_consumption']) + Parameters + ---------- + nominal_conditions : dict + Dictionary describing one operating point (e.g., operation + under STC) of the heat pump by its + heating capacity, its electricity consumption and its COP + ('nominal_Q_hot', 'nominal_el_consumption' and 'nominal_cop') + cops : list of numerical values + Actual COP + + Returns + ------- + max_Q_hot : list of numerical values + Maximal heating capacity (relative value). Value is equal or + greater than 0 and can be greater than 1. + + """ + nominal_cop = ( + nominal_conditions["nominal_Q_hot"] + / nominal_conditions["nominal_el_consumption"] + ) max_Q_hot = [actual_cop / nominal_cop for actual_cop in cops] return max_Q_hot @@ -244,9 +254,11 @@ def calc_chiller_quality_grade(nominal_conditions): Quality grade """ - t_h = nominal_conditions['t_high_nominal'] + 273.15 - t_l = nominal_conditions['t_low_nominal'] + 273.15 - nominal_cop = (nominal_conditions['nominal_Q_chill'] / nominal_conditions[ - 'nominal_el_consumption']) + t_h = nominal_conditions["t_high_nominal"] + 273.15 + t_l = nominal_conditions["t_low_nominal"] + 273.15 + nominal_cop = ( + nominal_conditions["nominal_Q_chill"] + / nominal_conditions["nominal_el_consumption"] + ) q_grade = nominal_cop / (t_l / (t_h - t_l)) return q_grade From 71cbe20d9462954c8e9e623e3d2c3ce0f96ce60b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 8 Oct 2024 21:23:10 +0200 Subject: [PATCH 11/34] List sphinx in docs requirements --- docs/requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/requirements.txt b/docs/requirements.txt index d6e1198b..46ae74e9 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,3 @@ -e . +sphinx>=1.3 +sphinx-rtd-theme From a2a5281557e48242e3434bb5b1e673661be6d7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 8 Oct 2024 21:23:35 +0200 Subject: [PATCH 12/34] Copy tox.ini from solph --- tox.ini | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 tox.ini diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..bbbaac9c --- /dev/null +++ b/tox.ini @@ -0,0 +1,140 @@ +[tox] +envlist = + clean, + check, + docs, + py39, + py310, + py311, + py3-nocov, + report + +[gh-actions] +python = + 3.9: py39 + 3.10: py310 + 3.11: py311 + +[testenv] +basepython = + docs: {env:TOXPYTHON:python3} + {bootstrap,clean,check,report,codecov,coveralls}: {env:TOXPYTHON:python3} +setenv = + PYTHONPATH={toxinidir}/tests + PYTHONUNBUFFERED=yes +passenv = + * +deps = + py + pytest +commands = + {posargs:pytest -vv --ignore=src} + +ignore_basepython_conflict = True + +[testenv:bootstrap] +deps = + jinja2 + matrix +skip_install = true +commands = + python ci/bootstrap.py --no-env + +[testenv:check] +deps = + docutils + check-manifest + flake8 + twine + pygments + isort +skip_install = true +commands = + python -m build . + twine check dist/oemof* + check-manifest {toxinidir} + flake8 src tests + isort --check-only --profile black --diff src tests + + +[testenv:docs] +usedevelop = true +deps = + -r{toxinidir}/docs/requirements.txt +commands = + sphinx-build {posargs:-E} -W -b html docs dist/docs + sphinx-build -b linkcheck docs dist/docs + +[testenv:coveralls] +deps = + coveralls +skip_install = true +commands = + coveralls [] + +[testenv:codecov] +deps = + codecov +skip_install = true +commands = + codecov [] + +[testenv:report] +deps = coverage +skip_install = true +commands = + coverage report + coverage html + +[testenv:clean] +commands = coverage erase +skip_install = true +deps = coverage + +[testenv:py310] +basepython = {env:TOXPYTHON:python3.10} +setenv = + {[testenv]setenv} +usedevelop = true +commands = + {posargs:pytest --cov --cov-report=term-missing -vv} +deps = + {[testenv]deps} + pytest-cov + +[testenv:py311] +basepython = {env:TOXPYTHON:python3.11} +setenv = + {[testenv]setenv} +usedevelop = true +commands = + {posargs:pytest --cov --cov-report=term-missing -vv} +deps = + {[testenv]deps} + pytest-cov + + +[testenv:py39] +basepython = {env:TOXPYTHON:python3.9} +setenv = + {[testenv]setenv} +usedevelop = true +commands = + {posargs:pytest --cov --cov-report=term-missing -vv} +deps = + {[testenv]deps} + pytest-cov + +[testenv:py38] +basepython = {env:TOXPYTHON:python3.8} +setenv = + {[testenv]setenv} +usedevelop = true +commands = + {posargs:pytest --cov --cov-report=term-missing -vv} +deps = + {[testenv]deps} + pytest-cov + +[testenv:py3-nocov] +basepython = {env:TOXPYTHON:python3} From bafeb20d856ab8bf650c2b968b1efc2bbfa1fd81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 8 Oct 2024 21:24:41 +0200 Subject: [PATCH 13/34] Copy GitHub workflows from solph Taken from oemof-solph commit 0b03a258fd6973ccd36bde9b4d1be285b87d81e7. --- .github/workflows/codeql.yml | 44 ++++++++++++++++++++++++ .github/workflows/lint.yml | 38 +++++++++++++++++++++ .github/workflows/packaging.yml | 40 ++++++++++++++++++++++ .github/workflows/tox_checks.yml | 57 +++++++++++++++++++++++++++++++ .github/workflows/tox_pytests.yml | 44 ++++++++++++++++++++++++ 5 files changed, 223 insertions(+) create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/packaging.yml create mode 100644 .github/workflows/tox_checks.yml create mode 100644 .github/workflows/tox_pytests.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..624ae6f2 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,44 @@ +name: "CodeQL" + +on: + push: + branches: + - dev + - master + - 'release/**' + pull_request: + branches: [ "dev" ] + schedule: + - cron: "23 2 * * 2" + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ python ] + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + queries: +security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..3e5f7315 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,38 @@ +name: Black + +on: + push: + branches: + - master + - dev + - 'release/**' + pull_request: + +jobs: + run-linters: + name: Run linters + runs-on: ubuntu-latest + + steps: + - name: Check out Git repository + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.9 + + - name: Install Python dependencies + run: pip install black flake8 + + - name: Run linters + uses: samuelmeuli/lint-action@v1 + with: + github_token: ${{ secrets.github_token }} + # Enable linters + black: true + flake8: false + # Mark the following line true if you want linters to attempt to autocorrect your code + auto_fix: false + git_name: "Greene Lab Linter" + git_email: "csgreene@upenn.edu" diff --git a/.github/workflows/packaging.yml b/.github/workflows/packaging.yml new file mode 100644 index 00000000..a09540cf --- /dev/null +++ b/.github/workflows/packaging.yml @@ -0,0 +1,40 @@ +name: packaging + +on: + # Make sure packaging process is not broken + push: + branches: + - master + - dev + - 'release/**' + pull_request: + # Make a package for release + release: + types: [published] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: [3.9] + + steps: + - uses: actions/checkout@v1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools setuptools_scm twine wheel build + - name: Create packages + run: python -m build . + - name: Run twine check + run: twine check dist/* + - uses: actions/upload-artifact@v4 + with: + name: tox-gh-actions-dist + path: dist diff --git a/.github/workflows/tox_checks.yml b/.github/workflows/tox_checks.yml new file mode 100644 index 00000000..5553b0ac --- /dev/null +++ b/.github/workflows/tox_checks.yml @@ -0,0 +1,57 @@ +# NB: this name is used in the status badge +name: tox checks + +on: + push: + branches: + - master + - dev + - 'release/**' + pull_request: + + workflow_dispatch: + schedule: + - cron: "0 5 * * 6" # 5:00 UTC every Saturday + +jobs: + lint: + name: ${{ matrix.toxenv }} + runs-on: ubuntu-latest + + strategy: + matrix: + toxenv: + - clean + - check + - docs + + steps: + - name: Update package list + run: sudo apt update + - name: Install LaTeX + run: sudo apt install dvipng rubber texlive-latex-extra + - name: Git clone + uses: actions/checkout@v2 + + - name: Set up Python ${{ env.default_python || '3.9' }} + uses: actions/setup-python@v5 + with: + python-version: "${{ env.default_python || '3.9' }}" + + - name: Pip cache + uses: actions/cache@v2 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ matrix.toxenv }}-${{ hashFiles('tox.ini', 'setup.py') }} + restore-keys: | + ${{ runner.os }}-pip-${{ matrix.toxenv }}- + ${{ runner.os }}-pip- + + - name: Install dependencies + run: | + python -m pip install -U pip + python -m pip install -U setuptools wheel build + python -m pip install -U tox + + - name: Run ${{ matrix.toxenv }} + run: python -m tox -e ${{ matrix.toxenv }} diff --git a/.github/workflows/tox_pytests.yml b/.github/workflows/tox_pytests.yml new file mode 100644 index 00000000..a28cb482 --- /dev/null +++ b/.github/workflows/tox_pytests.yml @@ -0,0 +1,44 @@ +name: tox pytests + +on: + push: + branches: + - master + - dev + - 'release/**' + pull_request: + + workflow_dispatch: + schedule: + - cron: "0 5 * * 6" # 5:00 UTC every Saturday + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.9, "3.10", "3.11"] + + steps: + - uses: actions/checkout@v1 + - name: Install cbc + run: sudo apt install coinor-cbc + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install tox tox-gh-actions coverage coveralls + - name: Test with tox + run: tox + + - name: Check test coverage + run: coverage report -m --fail-under=${{ matrix.vcs == 'bzr' && 84 || 85 }} + + - name: Report to coveralls + run: coveralls + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COVERALLS_SERVICE_NAME: github From 6c719810c23472ebf8aac5843122bf0099c01b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 8 Oct 2024 21:27:39 +0200 Subject: [PATCH 14/34] Adhere to Black --- .../absorption_chiller.py | 147 +++++++------ ...ng_cap_dependence_on_cooling_water_temp.py | 106 +++++----- examples/check_examples.py | 73 +++++-- .../emission_allocation_methods.py | 24 ++- .../airsource_heatpump_const_max_output.py | 168 ++++++++------- .../airsource_heatpump_variable_max_output.py | 195 ++++++++++-------- .../chiller_cop.py | 44 +++- .../chiller_cop_as_TimeSeries.py | 45 +++- ...op_dependence_on_temperature_difference.py | 187 ++++++++++------- .../groundsource_heatpump.py | 133 +++++++----- .../csp_collector_plot.py | 118 +++++++---- .../csp_collector_plot_andasol.py | 131 ++++++++---- .../concentrating_solar_power/csp_facade.py | 110 ++++++---- .../concentrating_solar_power/csp_plant.py | 159 +++++++++----- examples/solar_thermal_collector/_plots.py | 21 +- .../flat_plate_collector.py | 76 +++---- .../flat_plate_collector_facade.py | 69 ++++--- .../flat_plate_collector_investment.py | 76 +++---- .../investment_fixed_ratio_facade.py | 105 ++++++---- .../investment_fixed_ratio_generic_storage.py | 138 +++++++------ .../investment_independent_facade.py | 98 +++++---- .../investment_independent_generic_storage.py | 139 +++++++------ .../model_validation.py | 132 ++++++------ .../operation_facade.py | 80 +++---- .../operation_generic_storage.py | 152 +++++++------- examples/stratified_thermal_storage/plots.py | 192 +++++++++-------- pyproject.toml | 4 + src/oemof/thermal/__init__.py | 4 +- .../absorption_heatpumps_and_chillers.py | 88 ++++---- src/oemof/thermal/cogeneration.py | 53 +++-- .../compression_heatpumps_and_chillers.py | 15 +- .../thermal/concentrating_solar_power.py | 179 ++++++++++------ src/oemof/thermal/facades.py | 42 ++-- src/oemof/thermal/solar_thermal_collector.py | 28 +-- .../thermal/stratified_thermal_storage.py | 32 ++- tests/test_constraints.py | 31 ++- tests/test_functions.py | 42 +++- 37 files changed, 2050 insertions(+), 1386 deletions(-) diff --git a/examples/absorption_heatpump_and_chiller/absorption_chiller.py b/examples/absorption_heatpump_and_chiller/absorption_chiller.py index 89b68867..739827cd 100644 --- a/examples/absorption_heatpump_and_chiller/absorption_chiller.py +++ b/examples/absorption_heatpump_and_chiller/absorption_chiller.py @@ -1,4 +1,3 @@ - # import absorption_heatpumps_and_chillers as abs_hp_chiller import oemof.thermal.absorption_heatpumps_and_chillers as abs_hp_chiller import oemof.solph as solph @@ -6,24 +5,29 @@ import os import matplotlib.pyplot as plt + def absorption_chiller_example(): - solver = 'cbc' + solver = "cbc" debug = False number_of_time_steps = 48 solver_verbose = True - date_time_index = pd.date_range('1/1/2012', periods=number_of_time_steps, - freq='H') + date_time_index = pd.date_range( + "1/1/2012", periods=number_of_time_steps, freq="H" + ) energysystem = solph.EnergySystem(timeindex=date_time_index) # Read data file - filename_data = os.path.join(os.path.dirname(__file__), 'data/AC_example.csv') + filename_data = os.path.join( + os.path.dirname(__file__), "data/AC_example.csv" + ) data = pd.read_csv(filename_data) - filename_charpara = os.path.join(os.path.dirname(__file__), - 'data/characteristic_parameters.csv') + filename_charpara = os.path.join( + os.path.dirname(__file__), "data/characteristic_parameters.csv" + ) charpara = pd.read_csv(filename_charpara) - chiller_name = 'Kuehn' + chiller_name = "Kuehn" # Buses with three different temperature levels b_th_high = solph.Bus(label="hot") @@ -31,22 +35,31 @@ def absorption_chiller_example(): b_th_low = solph.Bus(label="chilled") energysystem.add(b_th_high, b_th_low) - energysystem.add(solph.components.Source( - label='driving_heat', - outputs={b_th_high: solph.Flow(variable_costs=0)})) - energysystem.add(solph.components.Source( - label='cooling_shortage', - outputs={b_th_low: solph.Flow(variable_costs=20)})) + energysystem.add( + solph.components.Source( + label="driving_heat", + outputs={b_th_high: solph.Flow(variable_costs=0)}, + ) + ) + energysystem.add( + solph.components.Source( + label="cooling_shortage", + outputs={b_th_low: solph.Flow(variable_costs=20)}, + ) + ) # energysystem.add(solph.components.Sink( # label='dry_cooling_tower', # inputs={b_th_medium: solph.Flow(variable_costs=0)})) - energysystem.add(solph.components.Sink( - label='cooling_demand', - inputs={b_th_low: solph.Flow(fix=1, nominal_value=35)})) + energysystem.add( + solph.components.Sink( + label="cooling_demand", + inputs={b_th_low: solph.Flow(fix=1, nominal_value=35)}, + ) + ) # Mean cooling water temperature in degC (dry cooling tower) temp_difference = 4 - t_cooling = [t + temp_difference for t in data['air_temperature']] + t_cooling = [t + temp_difference for t in data["air_temperature"]] n = len(t_cooling) # Pre-Calculations @@ -54,42 +67,51 @@ def absorption_chiller_example(): t_hot=[85], t_cool=t_cooling, t_chill=[15] * n, - coef_a=charpara[(charpara['name'] == chiller_name)]['a'].values[0], - coef_e=charpara[(charpara['name'] == chiller_name)]['e'].values[0], - method='kuehn_and_ziegler') + coef_a=charpara[(charpara["name"] == chiller_name)]["a"].values[0], + coef_e=charpara[(charpara["name"] == chiller_name)]["e"].values[0], + method="kuehn_and_ziegler", + ) Q_dots_evap = abs_hp_chiller.calc_heat_flux( ddts=ddt, - coef_s=charpara[(charpara['name'] == chiller_name)]['s_E'].values[0], - coef_r=charpara[(charpara['name'] == chiller_name)]['r_E'].values[0], - method='kuehn_and_ziegler') + coef_s=charpara[(charpara["name"] == chiller_name)]["s_E"].values[0], + coef_r=charpara[(charpara["name"] == chiller_name)]["r_E"].values[0], + method="kuehn_and_ziegler", + ) Q_dots_gen = abs_hp_chiller.calc_heat_flux( ddts=ddt, - coef_s=charpara[(charpara['name'] == chiller_name)]['s_G'].values[0], - coef_r=charpara[(charpara['name'] == chiller_name)]['r_G'].values[0], - method='kuehn_and_ziegler') + coef_s=charpara[(charpara["name"] == chiller_name)]["s_G"].values[0], + coef_r=charpara[(charpara["name"] == chiller_name)]["r_G"].values[0], + method="kuehn_and_ziegler", + ) COPs = [Qevap / Qgen for Qgen, Qevap in zip(Q_dots_gen, Q_dots_evap)] nominal_Q_dots_evap = 10 actual_value = [Q_e / nominal_Q_dots_evap for Q_e in Q_dots_evap] # Absorption Chiller - energysystem.add(solph.components.Transformer( - label="AC", - inputs={b_th_high: solph.Flow()}, - outputs={b_th_low: solph.Flow(nominal_value=nominal_Q_dots_evap, - max=actual_value, - variable_costs=5)}, - conversion_factors={b_th_low: COPs})) + energysystem.add( + solph.components.Transformer( + label="AC", + inputs={b_th_high: solph.Flow()}, + outputs={ + b_th_low: solph.Flow( + nominal_value=nominal_Q_dots_evap, + max=actual_value, + variable_costs=5, + ) + }, + conversion_factors={b_th_low: COPs}, + ) + ) model = solph.Model(energysystem) - model.solve(solver=solver, solve_kwargs={'tee': solver_verbose}) + model.solve(solver=solver, solve_kwargs={"tee": solver_verbose}) - energysystem.results['main'] = solph.processing.results(model) - energysystem.results['meta'] = solph.processing.meta_results(model) + energysystem.results["main"] = solph.processing.results(model) + energysystem.results["meta"] = solph.processing.meta_results(model) energysystem.dump(dpath=None, filename=None) - # **************************************************************************** # ********** PART 2 - Processing the results ********************************* # **************************************************************************** @@ -97,44 +119,43 @@ def absorption_chiller_example(): energysystem = solph.EnergySystem() energysystem.restore(dpath=None, filename=None) - results = energysystem.results['main'] + results = energysystem.results["main"] - high_temp_bus = solph.views.node(results, 'hot') - low_temp_bus = solph.views.node(results, 'chilled') + high_temp_bus = solph.views.node(results, "hot") + low_temp_bus = solph.views.node(results, "chilled") string_results = solph.views.convert_keys_to_strings( - energysystem.results['main']) - AC_output = string_results[ - 'AC', 'chilled']['sequences'].values - demand_cooling = string_results[ - 'chilled', 'cooling_demand']['sequences'].values - ASHP_input = string_results[ - 'hot', 'AC']['sequences'].values - + energysystem.results["main"] + ) + AC_output = string_results["AC", "chilled"]["sequences"].values + demand_cooling = string_results["chilled", "cooling_demand"][ + "sequences" + ].values + ASHP_input = string_results["hot", "AC"]["sequences"].values fig2, axs = plt.subplots(3, 1, figsize=(8, 5), sharex=True) - axs[0].plot(AC_output, label='cooling output') - axs[0].plot(demand_cooling, linestyle='--', label='cooling demand') - axs[1].plot(COPs, linestyle='-.') - axs[2].plot(data['air_temperature']) - axs[0].set_title('Cooling capacity and demand') - axs[1].set_title('Coefficient of Performance') - axs[2].set_title('Air Temperature') + axs[0].plot(AC_output, label="cooling output") + axs[0].plot(demand_cooling, linestyle="--", label="cooling demand") + axs[1].plot(COPs, linestyle="-.") + axs[2].plot(data["air_temperature"]) + axs[0].set_title("Cooling capacity and demand") + axs[1].set_title("Coefficient of Performance") + axs[2].set_title("Air Temperature") axs[0].legend() axs[0].grid() axs[1].grid() axs[2].grid() - axs[0].set_ylabel('Cooling capacity in kW') - axs[1].set_ylabel('COP') - axs[2].set_ylabel('Temperature in $°$C') - axs[2].set_xlabel('Time in h') + axs[0].set_ylabel("Cooling capacity in kW") + axs[1].set_ylabel("COP") + axs[2].set_ylabel("Temperature in $°$C") + axs[2].set_xlabel("Time in h") plt.tight_layout() plt.show() - print('********* Main results *********') - print(high_temp_bus['sequences'].sum(axis=0)) - print(low_temp_bus['sequences'].sum(axis=0)) + print("********* Main results *********") + print(high_temp_bus["sequences"].sum(axis=0)) + print(low_temp_bus["sequences"].sum(axis=0)) if __name__ == "__main__": diff --git a/examples/absorption_heatpump_and_chiller/cooling_cap_dependence_on_cooling_water_temp.py b/examples/absorption_heatpump_and_chiller/cooling_cap_dependence_on_cooling_water_temp.py index 11e76dda..bbef1f77 100644 --- a/examples/absorption_heatpump_and_chiller/cooling_cap_dependence_on_cooling_water_temp.py +++ b/examples/absorption_heatpump_and_chiller/cooling_cap_dependence_on_cooling_water_temp.py @@ -1,4 +1,3 @@ - import oemof.thermal.absorption_heatpumps_and_chillers as abs_hp_chiller import matplotlib.pyplot as plt import os @@ -6,10 +5,11 @@ def cooling_cap_example(): - filename = os.path.join(os.path.dirname(__file__), - 'data/characteristic_parameters.csv') + filename = os.path.join( + os.path.dirname(__file__), "data/characteristic_parameters.csv" + ) charpara = pd.read_csv(filename) - chiller_name = 'Kuehn' + chiller_name = "Kuehn" t_cooling = [23, 25, 27, 29, 31, 33, 35, 36, 37, 38, 39, 40] @@ -17,67 +17,79 @@ def cooling_cap_example(): t_hot=[75], t_cool=t_cooling, t_chill=[15], - coef_a=charpara[(charpara['name'] == chiller_name)]['a'].values[0], - coef_e=charpara[(charpara['name'] == chiller_name)]['e'].values[0], - method='kuehn_and_ziegler') + coef_a=charpara[(charpara["name"] == chiller_name)]["a"].values[0], + coef_e=charpara[(charpara["name"] == chiller_name)]["e"].values[0], + method="kuehn_and_ziegler", + ) Q_dots_evap_75 = abs_hp_chiller.calc_heat_flux( ddts=ddt_75, - coef_s=charpara[(charpara['name'] == chiller_name)]['s_E'].values[0], - coef_r=charpara[(charpara['name'] == chiller_name)]['r_E'].values[0], - method='kuehn_and_ziegler') + coef_s=charpara[(charpara["name"] == chiller_name)]["s_E"].values[0], + coef_r=charpara[(charpara["name"] == chiller_name)]["r_E"].values[0], + method="kuehn_and_ziegler", + ) Q_dots_gen_75 = abs_hp_chiller.calc_heat_flux( ddts=ddt_75, - coef_s=charpara[(charpara['name'] == chiller_name)]['s_G'].values[0], - coef_r=charpara[(charpara['name'] == chiller_name)]['r_G'].values[0], - method='kuehn_and_ziegler') - COPs_75 = [Qevap / Qgen for Qgen, Qevap in zip(Q_dots_gen_75, Q_dots_evap_75)] + coef_s=charpara[(charpara["name"] == chiller_name)]["s_G"].values[0], + coef_r=charpara[(charpara["name"] == chiller_name)]["r_G"].values[0], + method="kuehn_and_ziegler", + ) + COPs_75 = [ + Qevap / Qgen for Qgen, Qevap in zip(Q_dots_gen_75, Q_dots_evap_75) + ] ddt_80 = abs_hp_chiller.calc_characteristic_temp( t_hot=[80], t_cool=t_cooling, t_chill=[15], - coef_a=charpara[(charpara['name'] == chiller_name)]['a'].values[0], - coef_e=charpara[(charpara['name'] == chiller_name)]['e'].values[0], - method='kuehn_and_ziegler') + coef_a=charpara[(charpara["name"] == chiller_name)]["a"].values[0], + coef_e=charpara[(charpara["name"] == chiller_name)]["e"].values[0], + method="kuehn_and_ziegler", + ) Q_dots_evap_80 = abs_hp_chiller.calc_heat_flux( ddts=ddt_80, - coef_s=charpara[(charpara['name'] == chiller_name)]['s_E'].values[0], - coef_r=charpara[(charpara['name'] == chiller_name)]['r_E'].values[0], - method='kuehn_and_ziegler') - + coef_s=charpara[(charpara["name"] == chiller_name)]["s_E"].values[0], + coef_r=charpara[(charpara["name"] == chiller_name)]["r_E"].values[0], + method="kuehn_and_ziegler", + ) fig1 = plt.figure(figsize=(8, 6)) fig1.set_size_inches(8, 6, forward=True) ax1 = fig1.add_subplot(111) - ax1.grid(axis='y') + ax1.grid(axis="y") - line1 = ax1.plot(t_cooling, - Q_dots_evap_80, - linestyle='dotted', - marker='d', - color='black', - label='Cooling capacity ($80°$C driving heat)') - line2 = ax1.plot(t_cooling, - Q_dots_evap_75, - linestyle='dashed', - marker='d', - color='black', - label='Cooling capacity ($75°$C driving heat)') - plt.ylabel('Cooling capacity in kW') + line1 = ax1.plot( + t_cooling, + Q_dots_evap_80, + linestyle="dotted", + marker="d", + color="black", + label="Cooling capacity ($80°$C driving heat)", + ) + line2 = ax1.plot( + t_cooling, + Q_dots_evap_75, + linestyle="dashed", + marker="d", + color="black", + label="Cooling capacity ($75°$C driving heat)", + ) + plt.ylabel("Cooling capacity in kW") ax2 = fig1.add_subplot(111, sharex=ax1, frameon=False) - line3 = ax2.plot(t_cooling, - COPs_75, - linestyle='-', - marker='o', - color='black', - label='COP ($75°$C driving heat)') + line3 = ax2.plot( + t_cooling, + COPs_75, + linestyle="-", + marker="o", + color="black", + label="COP ($75°$C driving heat)", + ) ax2.yaxis.tick_right() - ax2.yaxis.set_label_position('right') - plt.ylabel('COP') - plt.xlabel('Cooling water temperature in $°$C') - plt.title('Chiller performance at varying cooling water temperatures') - ax2.legend(loc='upper right') - ax1.legend(loc='lower left') + ax2.yaxis.set_label_position("right") + plt.ylabel("COP") + plt.xlabel("Cooling water temperature in $°$C") + plt.title("Chiller performance at varying cooling water temperatures") + ax2.legend(loc="upper right") + ax1.legend(loc="lower left") ax2.set_ylim(0.4, 0.8) ax1.set_ylim(0, 24) diff --git a/examples/check_examples.py b/examples/check_examples.py index 13dc1bcc..6efbd39b 100644 --- a/examples/check_examples.py +++ b/examples/check_examples.py @@ -1,30 +1,65 @@ +from absorption_heatpump_and_chiller.absorption_chiller import ( + absorption_chiller_exaple, +) +from absorption_heatpump_and_chiller.cooling_cap_dependence_on_cooling_water_temp import ( + cooling_cap_example, +) -from absorption_heatpump_and_chiller.absorption_chiller import absorption_chiller_exaple -from absorption_heatpump_and_chiller.cooling_cap_dependence_on_cooling_water_temp import cooling_cap_example +from cogeneration.emission_allocation_methods import ( + emission_allocation_example, +) -from cogeneration.emission_allocation_methods import emission_allocation_example - -from compression_heatpump_and_chiller.airsource_heatpump_const_max_output import airource_hp_const_example -from compression_heatpump_and_chiller.airsource_heatpump_variable_max_output import airource_hp_variable_example -from compression_heatpump_and_chiller.chiller_cop import chiller_cop_const_example -from compression_heatpump_and_chiller.chiller_cop_as_TimeSeries import chiller_cop_timeseries_example -from compression_heatpump_and_chiller.groundsource_heatpump import groundsource_hp_example +from compression_heatpump_and_chiller.airsource_heatpump_const_max_output import ( + airource_hp_const_example, +) +from compression_heatpump_and_chiller.airsource_heatpump_variable_max_output import ( + airource_hp_variable_example, +) +from compression_heatpump_and_chiller.chiller_cop import ( + chiller_cop_const_example, +) +from compression_heatpump_and_chiller.chiller_cop_as_TimeSeries import ( + chiller_cop_timeseries_example, +) +from compression_heatpump_and_chiller.groundsource_heatpump import ( + groundsource_hp_example, +) from concentrating_solar_power.csp_collector_plot import csp_collector_example -from concentrating_solar_power.csp_collector_plot_andasol import csp_andasol_example +from concentrating_solar_power.csp_collector_plot_andasol import ( + csp_andasol_example, +) from concentrating_solar_power.csp_facade import csp_facade_example from concentrating_solar_power.csp_plant import csp_plant_example -from solar_thermal_collector.flat_plate_collector import flat_plate_collector_example -from solar_thermal_collector.flat_plate_collector_facade import flat_plate_collector_facade_example -from solar_thermal_collector.flat_plate_collector_investment import flat_plate_collector_investment_example +from solar_thermal_collector.flat_plate_collector import ( + flat_plate_collector_example, +) +from solar_thermal_collector.flat_plate_collector_facade import ( + flat_plate_collector_facade_example, +) +from solar_thermal_collector.flat_plate_collector_investment import ( + flat_plate_collector_investment_example, +) -from stratified_thermal_storage.operation_generic_storage import operation_example -from stratified_thermal_storage.operation_facade import operation_facade_example -from stratified_thermal_storage.investment_fixed_ratio_facade import fixed_ratio_invest_facade_example -from stratified_thermal_storage.investment_fixed_ratio_generic_storage import fixed_ratio_invest_example -from stratified_thermal_storage.investment_independent_facade import invest_independent_facade_example -from stratified_thermal_storage.investment_independent_generic_storage import invest_independent_example +from stratified_thermal_storage.operation_generic_storage import ( + operation_example, +) +from stratified_thermal_storage.operation_facade import ( + operation_facade_example, +) +from stratified_thermal_storage.investment_fixed_ratio_facade import ( + fixed_ratio_invest_facade_example, +) +from stratified_thermal_storage.investment_fixed_ratio_generic_storage import ( + fixed_ratio_invest_example, +) +from stratified_thermal_storage.investment_independent_facade import ( + invest_independent_facade_example, +) +from stratified_thermal_storage.investment_independent_generic_storage import ( + invest_independent_example, +) # absorption_chiller_example() diff --git a/examples/cogeneration/emission_allocation_methods.py b/examples/cogeneration/emission_allocation_methods.py index 1e1d55a2..34511a6f 100644 --- a/examples/cogeneration/emission_allocation_methods.py +++ b/examples/cogeneration/emission_allocation_methods.py @@ -10,40 +10,42 @@ from oemof.thermal.cogeneration import allocate_emissions + def emission_allocation_example(): emissions_dict = {} - for method in ['iea', 'efficiency', 'finnish']: + for method in ["iea", "efficiency", "finnish"]: emissions_dict[method] = allocate_emissions( total_emissions=200, # Arbitrary units. Assume [kgCO2]. eta_el=0.3, eta_th=0.5, method=method, eta_el_ref=0.525, - eta_th_ref=0.82 + eta_th_ref=0.82, ) - df = pd.DataFrame(emissions_dict, index=['el', 'th']).T + df = pd.DataFrame(emissions_dict, index=["el", "th"]).T print(df) # Example plot fig, ax = plt.subplots() - df.loc[:, 'el'] *= -1 + df.loc[:, "el"] *= -1 bars = df.plot.barh(stacked=True, ax=ax) - for i, (el, th) in enumerate(zip(df['el'], df['th'])): - ax.text(el, i, round(-el), ha='left') - ax.text(th, i, round(th), ha='right') + for i, (el, th) in enumerate(zip(df["el"], df["th"])): + ax.text(el, i, round(-el), ha="left") + ax.text(th, i, round(th), ha="right") ax.axvline(0) - ax.set_ylabel('Method') - ax.set_xlabel('Allocated emissions [kgCO2]') - plt.title('allocated to electricity', loc='left') - plt.title('allocated to heat', loc='right') + ax.set_ylabel("Method") + ax.set_xlabel("Allocated emissions [kgCO2]") + plt.title("allocated to electricity", loc="left") + plt.title("allocated to heat", loc="right") fig.tight_layout() plt.show() + if __name__ == "__main__": emission_allocation_example() diff --git a/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py b/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py index 65838ac1..c1afd0b1 100644 --- a/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py +++ b/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py @@ -13,68 +13,84 @@ import matplotlib.pyplot as plt import numpy as np + def airource_hp_const_example(): # Set paths - data_path = os.path.join(os.path.dirname(__file__), 'data/ASHP_example.csv') + data_path = os.path.join( + os.path.dirname(__file__), "data/ASHP_example.csv" + ) # Read input data data = pd.read_csv(data_path) # Set up an energy system model - solver = 'cbc' + solver = "cbc" number_of_time_steps = 24 solver_verbose = False - date_time_index = pd.date_range('1/1/2012', periods=number_of_time_steps, - freq='H') + date_time_index = pd.date_range( + "1/1/2012", periods=number_of_time_steps, freq="H" + ) energysystem = solph.EnergySystem(timeindex=date_time_index) - b_el = solph.Bus(label="electricity") b_heat = solph.Bus(label="heat") energysystem.add(b_el, b_heat) - energysystem.add(solph.components.Source( - label='grid_el', - outputs={b_el: solph.Flow(variable_costs=10)})) - - energysystem.add(solph.components.Source( - label='backup_heating', - outputs={b_heat: solph.Flow(variable_costs=10)})) - - energysystem.add(solph.components.Sink( - label='demand', - inputs={b_heat: solph.Flow(fix=data['demand_heat'], - nominal_value=1)})) + energysystem.add( + solph.components.Source( + label="grid_el", outputs={b_el: solph.Flow(variable_costs=10)} + ) + ) + + energysystem.add( + solph.components.Source( + label="backup_heating", + outputs={b_heat: solph.Flow(variable_costs=10)}, + ) + ) + + energysystem.add( + solph.components.Sink( + label="demand", + inputs={ + b_heat: solph.Flow(fix=data["demand_heat"], nominal_value=1) + }, + ) + ) temp_threshold_icing = 2 # Precalculation of COPs cops_ASHP = cmpr_hp_chiller.calc_cops( temp_high=[40], - temp_low=data['ambient_temperature'], + temp_low=data["ambient_temperature"], quality_grade=0.4, - mode='heat_pump', + mode="heat_pump", temp_threshold_icing=temp_threshold_icing, - factor_icing=0.8) + factor_icing=0.8, + ) # Air-Source Heat Pump - energysystem.add(solph.components.Transformer( - label="ASHP", - inputs={b_el: solph.Flow()}, - outputs={b_heat: solph.Flow(nominal_value=25, variable_costs=5)}, - conversion_factors={b_heat: cops_ASHP})) + energysystem.add( + solph.components.Transformer( + label="ASHP", + inputs={b_el: solph.Flow()}, + outputs={b_heat: solph.Flow(nominal_value=25, variable_costs=5)}, + conversion_factors={b_heat: cops_ASHP}, + ) + ) # Create and solve the optimization model model = solph.Model(energysystem) - model.solve(solver=solver, solve_kwargs={'tee': solver_verbose}) + model.solve(solver=solver, solve_kwargs={"tee": solver_verbose}) # Get results - energysystem.results['main'] = solph.processing.results(model) - energysystem.results['meta'] = solph.processing.meta_results(model) + energysystem.results["main"] = solph.processing.results(model) + energysystem.results["meta"] = solph.processing.meta_results(model) energysystem.dump(dpath=None, filename=None) @@ -82,64 +98,74 @@ def airource_hp_const_example(): energysystem = solph.EnergySystem() energysystem.restore(dpath=None, filename=None) - results = energysystem.results['main'] + results = energysystem.results["main"] - electricity_bus = solph.views.node(results, 'electricity') - heat_bus = solph.views.node(results, 'heat') + electricity_bus = solph.views.node(results, "electricity") + heat_bus = solph.views.node(results, "heat") string_results = solph.views.convert_keys_to_strings( - energysystem.results['main']) - ASHP_output = string_results[ - 'ASHP', 'heat']['sequences'].values - demand_h = string_results[ - 'heat', 'demand']['sequences'].values - ASHP_input = string_results[ - 'electricity', 'ASHP']['sequences'].values + energysystem.results["main"] + ) + ASHP_output = string_results["ASHP", "heat"]["sequences"].values + demand_h = string_results["heat", "demand"]["sequences"].values + ASHP_input = string_results["electricity", "ASHP"]["sequences"].values # Example plot fig, axs = plt.subplots(3, 1, figsize=(8, 5), sharex=True) - axs[0].plot(ASHP_output, label='heat output') - axs[0].plot(demand_h, linestyle='--', label='heat demand') - axs[1].plot(cops_ASHP, linestyle='-.') - axs[2].plot([-1, number_of_time_steps], - [temp_threshold_icing, temp_threshold_icing], - linestyle='--', - color='red', - label='threshold temperature') - axs[2].text(x=number_of_time_steps - 1, - y=temp_threshold_icing, - s='threshold temperature', - ha='right', - va='center', - color='red', - fontsize=10, - bbox=dict(facecolor='white', edgecolor='white', alpha=1.0)) - axs[2].plot(data['ambient_temperature'], label='ambient temperature') - axs[0].set_title('Heat Output and Demand') - axs[1].set_title('Coefficient of Performance') - axs[2].set_title('Source Temperature (Ambient)') + axs[0].plot(ASHP_output, label="heat output") + axs[0].plot(demand_h, linestyle="--", label="heat demand") + axs[1].plot(cops_ASHP, linestyle="-.") + axs[2].plot( + [-1, number_of_time_steps], + [temp_threshold_icing, temp_threshold_icing], + linestyle="--", + color="red", + label="threshold temperature", + ) + axs[2].text( + x=number_of_time_steps - 1, + y=temp_threshold_icing, + s="threshold temperature", + ha="right", + va="center", + color="red", + fontsize=10, + bbox=dict(facecolor="white", edgecolor="white", alpha=1.0), + ) + axs[2].plot(data["ambient_temperature"], label="ambient temperature") + axs[0].set_title("Heat Output and Demand") + axs[1].set_title("Coefficient of Performance") + axs[2].set_title("Source Temperature (Ambient)") axs[0].legend() axs[0].grid() axs[1].grid() axs[2].grid() axs[0].set_xlim(0, number_of_time_steps) - axs[0].set_ylabel('Heat flow in kW') - axs[1].set_ylabel('COP') - axs[2].set_ylabel('Temperature in $°$C') - axs[2].set_xlabel('Time in h') + axs[0].set_ylabel("Heat flow in kW") + axs[1].set_ylabel("COP") + axs[2].set_ylabel("Temperature in $°$C") + axs[2].set_xlabel("Time in h") plt.tight_layout() plt.show() - print('********* Main results *********') - print("Total electricity consumption: {:2.1f}".format( - ASHP_input.sum(axis=0)[0])) - print("Total heat output: {:2.1f}".format( - ASHP_output.sum(axis=0)[0])) - print("Average Coefficient of Performance (COP): {:2.2f}".format( - np.mean(cops_ASHP))) - print("Seasonal Performance Factor (SPF): {:2.2f}".format( - ASHP_output.sum(axis=0)[0] / ASHP_input.sum(axis=0)[0])) + print("********* Main results *********") + print( + "Total electricity consumption: {:2.1f}".format( + ASHP_input.sum(axis=0)[0] + ) + ) + print("Total heat output: {:2.1f}".format(ASHP_output.sum(axis=0)[0])) + print( + "Average Coefficient of Performance (COP): {:2.2f}".format( + np.mean(cops_ASHP) + ) + ) + print( + "Seasonal Performance Factor (SPF): {:2.2f}".format( + ASHP_output.sum(axis=0)[0] / ASHP_input.sum(axis=0)[0] + ) + ) if __name__ == "__main__": diff --git a/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py b/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py index c2eb04e2..6fed5761 100644 --- a/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py +++ b/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py @@ -18,18 +18,21 @@ def airource_hp_variable_example(): # Set paths - data_path = os.path.join(os.path.dirname(__file__), 'data/ASHP_example.csv') + data_path = os.path.join( + os.path.dirname(__file__), "data/ASHP_example.csv" + ) # Read input data data = pd.read_csv(data_path) # Set up an energy system model - solver = 'cbc' + solver = "cbc" number_of_time_steps = 24 solver_verbose = False - date_time_index = pd.date_range('1/1/2012', periods=number_of_time_steps, - freq='H') + date_time_index = pd.date_range( + "1/1/2012", periods=number_of_time_steps, freq="H" + ) energysystem = solph.EnergySystem(timeindex=date_time_index) @@ -39,55 +42,70 @@ def airource_hp_variable_example(): energysystem.add(b_el, b_heat) - energysystem.add(solph.components.Source( - label='el_grid', - outputs={b_el: solph.Flow(variable_costs=10)})) - - energysystem.add(solph.components.Source( - label='backup_heating', - outputs={b_heat: solph.Flow(variable_costs=10)})) - - energysystem.add(solph.components.Sink( - label='demand', - inputs={b_heat: solph.Flow(fix=data['demand_heat'], - nominal_value=1)})) + energysystem.add( + solph.components.Source( + label="el_grid", outputs={b_el: solph.Flow(variable_costs=10)} + ) + ) + + energysystem.add( + solph.components.Source( + label="backup_heating", + outputs={b_heat: solph.Flow(variable_costs=10)}, + ) + ) + + energysystem.add( + solph.components.Sink( + label="demand", + inputs={ + b_heat: solph.Flow(fix=data["demand_heat"], nominal_value=1) + }, + ) + ) temp_threshold_icing = 2 # Precalculation of COPs cops_ASHP = cmpr_hp_chiller.calc_cops( temp_high=[40], - temp_low=data['ambient_temperature'], + temp_low=data["ambient_temperature"], quality_grade=0.4, - mode='heat_pump', + mode="heat_pump", temp_threshold_icing=temp_threshold_icing, - factor_icing=0.8) + factor_icing=0.8, + ) # Define operation condition for nominal output - nominal_conditions = {'nominal_Q_hot': 25, - 'nominal_el_consumption': 7} + nominal_conditions = {"nominal_Q_hot": 25, "nominal_el_consumption": 7} - - max_Q_dot_heating = cmpr_hp_chiller.calc_max_Q_dot_heat(nominal_conditions, - cops_ASHP) + max_Q_dot_heating = cmpr_hp_chiller.calc_max_Q_dot_heat( + nominal_conditions, cops_ASHP + ) # Air-Source Heat Pump - energysystem.add(solph.components.Transformer( - label="ASHP", - inputs={b_el: solph.Flow()}, - outputs={b_heat: solph.Flow( - nominal_value=nominal_conditions['nominal_Q_hot'], - max=max_Q_dot_heating, - variable_costs=5)}, - conversion_factors={b_heat: cops_ASHP})) + energysystem.add( + solph.components.Transformer( + label="ASHP", + inputs={b_el: solph.Flow()}, + outputs={ + b_heat: solph.Flow( + nominal_value=nominal_conditions["nominal_Q_hot"], + max=max_Q_dot_heating, + variable_costs=5, + ) + }, + conversion_factors={b_heat: cops_ASHP}, + ) + ) # Create and solve the optimization model model = solph.Model(energysystem) - model.solve(solver=solver, solve_kwargs={'tee': solver_verbose}) + model.solve(solver=solver, solve_kwargs={"tee": solver_verbose}) # Get results - energysystem.results['main'] = solph.processing.results(model) - energysystem.results['meta'] = solph.processing.meta_results(model) + energysystem.results["main"] = solph.processing.results(model) + energysystem.results["meta"] = solph.processing.meta_results(model) energysystem.dump(dpath=None, filename=None) @@ -95,74 +113,85 @@ def airource_hp_variable_example(): energysystem = solph.EnergySystem() energysystem.restore(dpath=None, filename=None) - results = energysystem.results['main'] + results = energysystem.results["main"] - electricity_bus = solph.views.node(results, 'electricity') - heat_bus = solph.views.node(results, 'heat') + electricity_bus = solph.views.node(results, "electricity") + heat_bus = solph.views.node(results, "heat") string_results = solph.views.convert_keys_to_strings( - energysystem.results['main']) - ASHP_output = string_results[ - 'ASHP', 'heat']['sequences'].values - demand_h = string_results[ - 'heat', 'demand']['sequences'].values - ASHP_input = string_results[ - 'electricity', 'ASHP']['sequences'].values + energysystem.results["main"] + ) + ASHP_output = string_results["ASHP", "heat"]["sequences"].values + demand_h = string_results["heat", "demand"]["sequences"].values + ASHP_input = string_results["electricity", "ASHP"]["sequences"].values # Absolute values of maximal heating capacity - max_Q_dot_heating_abs = [nominal_conditions['nominal_Q_hot'] * max_heating for - max_heating in max_Q_dot_heating] + max_Q_dot_heating_abs = [ + nominal_conditions["nominal_Q_hot"] * max_heating + for max_heating in max_Q_dot_heating + ] # Example plot fig, axs = plt.subplots(3, 1, figsize=(8, 5), sharex=True) - axs[0].plot(max_Q_dot_heating_abs, - linestyle='-.', - label='max heat output') - axs[0].plot(ASHP_output, label='actual heat output') - axs[0].plot(demand_h, linestyle='--', label='heat demand') - axs[1].plot(cops_ASHP, linestyle='-.') - axs[2].plot([-1, number_of_time_steps], - [temp_threshold_icing, temp_threshold_icing], - linestyle='--', - color='red', - label='threshold temperature') - axs[2].text(x=number_of_time_steps - 1, - y=temp_threshold_icing, - s='threshold temperature', - ha='right', - va='center', - color='red', - fontsize=10, - bbox=dict(facecolor='white', edgecolor='white', alpha=0.9)) - axs[2].plot(data['ambient_temperature']) - axs[0].set_title('Heat Output and Demand') - axs[1].set_title('Coefficient of Performance') - axs[2].set_title('Source Temperature (Ambient)') + axs[0].plot(max_Q_dot_heating_abs, linestyle="-.", label="max heat output") + axs[0].plot(ASHP_output, label="actual heat output") + axs[0].plot(demand_h, linestyle="--", label="heat demand") + axs[1].plot(cops_ASHP, linestyle="-.") + axs[2].plot( + [-1, number_of_time_steps], + [temp_threshold_icing, temp_threshold_icing], + linestyle="--", + color="red", + label="threshold temperature", + ) + axs[2].text( + x=number_of_time_steps - 1, + y=temp_threshold_icing, + s="threshold temperature", + ha="right", + va="center", + color="red", + fontsize=10, + bbox=dict(facecolor="white", edgecolor="white", alpha=0.9), + ) + axs[2].plot(data["ambient_temperature"]) + axs[0].set_title("Heat Output and Demand") + axs[1].set_title("Coefficient of Performance") + axs[2].set_title("Source Temperature (Ambient)") axs[0].legend() axs[0].grid() axs[1].grid() axs[2].grid() axs[0].set_xlim(0, number_of_time_steps) - axs[0].set_ylabel('Heat flow in kW') - axs[1].set_ylabel('COP') - axs[2].set_ylabel('Temperature in $°$C') - axs[2].set_xlabel('Time in h') + axs[0].set_ylabel("Heat flow in kW") + axs[1].set_ylabel("COP") + axs[2].set_ylabel("Temperature in $°$C") + axs[2].set_xlabel("Time in h") plt.tight_layout() plt.show() # print('********* Main results *********') # print(electricity_bus['sequences'].sum(axis=0)) # print(heat_bus['sequences'].sum(axis=0)) - print('********* Main results *********') - print("Total electricity consumption: {:2.1f}".format( - ASHP_input.sum(axis=0)[0])) - print("Total heat output: {:2.1f}".format( - ASHP_output.sum(axis=0)[0])) - print("Average Coefficient of Performance (COP): {:2.2f}".format( - np.mean(cops_ASHP))) - print("Seasonal Performance Factor (SPF): {:2.2f}".format( - ASHP_output.sum(axis=0)[0] / ASHP_input.sum(axis=0)[0])) + print("********* Main results *********") + print( + "Total electricity consumption: {:2.1f}".format( + ASHP_input.sum(axis=0)[0] + ) + ) + print("Total heat output: {:2.1f}".format(ASHP_output.sum(axis=0)[0])) + print( + "Average Coefficient of Performance (COP): {:2.2f}".format( + np.mean(cops_ASHP) + ) + ) + print( + "Seasonal Performance Factor (SPF): {:2.2f}".format( + ASHP_output.sum(axis=0)[0] / ASHP_input.sum(axis=0)[0] + ) + ) + if __name__ == "__main__": airource_hp_variable_example() diff --git a/examples/compression_heatpump_and_chiller/chiller_cop.py b/examples/compression_heatpump_and_chiller/chiller_cop.py index 008a6372..4fdf3094 100644 --- a/examples/compression_heatpump_and_chiller/chiller_cop.py +++ b/examples/compression_heatpump_and_chiller/chiller_cop.py @@ -10,18 +10,42 @@ import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller + def chiller_cop_const_example(): # Ambient temperatures in degC for a single day (24h) - temp_ambient = [24, 24, 24, 25, 25, 25, - 26, 27, 28, 29, 31, 32, - 35, 34, 27, 26, 25, 24, - 24, 24, 24, 24, 24, 23] - - cops_chiller = cmpr_hp_chiller.calc_cops(temp_high=temp_ambient, - temp_low=[18], - quality_grade=0.3, - mode='chiller') - + temp_ambient = [ + 24, + 24, + 24, + 25, + 25, + 25, + 26, + 27, + 28, + 29, + 31, + 32, + 35, + 34, + 27, + 26, + 25, + 24, + 24, + 24, + 24, + 24, + 24, + 23, + ] + + cops_chiller = cmpr_hp_chiller.calc_cops( + temp_high=temp_ambient, + temp_low=[18], + quality_grade=0.3, + mode="chiller", + ) print("") print("Coefficients of Performance (COP):") diff --git a/examples/compression_heatpump_and_chiller/chiller_cop_as_TimeSeries.py b/examples/compression_heatpump_and_chiller/chiller_cop_as_TimeSeries.py index f1a5612c..93fc9776 100644 --- a/examples/compression_heatpump_and_chiller/chiller_cop_as_TimeSeries.py +++ b/examples/compression_heatpump_and_chiller/chiller_cop_as_TimeSeries.py @@ -11,25 +11,49 @@ import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller import pandas as pd + def chiller_cop_timeseries_example(): # Ambient temperatures in degC for a single day (24h) - temp_ambient = [24, 24, 24, 25, 25, 25, - 26, 27, 28, 29, 31, 32, - 35, 34, 27, 26, 25, 24, - 24, 24, 24, 24, 24, 23] + temp_ambient = [ + 24, + 24, + 24, + 25, + 25, + 25, + 26, + 27, + 28, + 29, + 31, + 32, + 35, + 34, + 27, + 26, + 25, + 24, + 24, + 24, + 24, + 24, + 24, + 23, + ] - timestamps = pd.date_range('20200101', periods=24, freq='H') + timestamps = pd.date_range("20200101", periods=24, freq="H") # Convert temp_ambient to pandas DataFrame df_temp_ambient = pd.DataFrame(temp_ambient, timestamps) # Convert temp_ambient to pandas Series series_temp_ambient = pd.Series(temp_ambient, timestamps) - cops_chiller = cmpr_hp_chiller.calc_cops(temp_high=series_temp_ambient, - temp_low=[18], - quality_grade=0.3, - mode='chiller') - + cops_chiller = cmpr_hp_chiller.calc_cops( + temp_high=series_temp_ambient, + temp_low=[18], + quality_grade=0.3, + mode="chiller", + ) print("") print("Coefficients of Performance (COP):") @@ -39,5 +63,6 @@ def chiller_cop_timeseries_example(): t += 1 print("") + if __name__ == "__main__": chiller_cop_timeseries_example() diff --git a/examples/compression_heatpump_and_chiller/cop_dependence_on_temperature_difference.py b/examples/compression_heatpump_and_chiller/cop_dependence_on_temperature_difference.py index 98cd7ff1..e6663106 100644 --- a/examples/compression_heatpump_and_chiller/cop_dependence_on_temperature_difference.py +++ b/examples/compression_heatpump_and_chiller/cop_dependence_on_temperature_difference.py @@ -27,113 +27,148 @@ def cop_temperature_example(): # COPs of ax exemplary heat pump for domestic hot water # (sink temperature below 100 degC) - cops['temperature_difference'] = temp_difference + cops["temperature_difference"] = temp_difference list_temp_low = [temp_high - temp_diff for temp_diff in temp_difference] cops[temp_high] = cmpr_hp_chiller.calc_cops( temp_high=[temp_high], temp_low=list_temp_low, quality_grade=0.35, - mode='heat_pump') + mode="heat_pump", + ) # COPs of ax exemplary hight temperature heat pump for industrial applications # (sink temperature above 100 degC and higher quality grade) - cops['temperature_difference_industrial'] = temp_difference_industrial - temp_l_ind = [temp_high_industrial - temp_diff for - temp_diff in temp_difference_industrial] + cops["temperature_difference_industrial"] = temp_difference_industrial + temp_l_ind = [ + temp_high_industrial - temp_diff + for temp_diff in temp_difference_industrial + ] cops[temp_high_industrial] = cmpr_hp_chiller.calc_cops( temp_high=[temp_high_industrial], temp_low=temp_l_ind, quality_grade=0.45, - mode='heat_pump') + mode="heat_pump", + ) # COPs for varying quality grades cops_q_grade = pd.DataFrame() - cops_q_grade['temperature_diff'] = temperature_diff_q_grade - list_temp_low_q_grade = [temp_high - temp_diff_q for - temp_diff_q in temperature_diff_q_grade] + cops_q_grade["temperature_diff"] = temperature_diff_q_grade + list_temp_low_q_grade = [ + temp_high - temp_diff_q for temp_diff_q in temperature_diff_q_grade + ] for q in quality_grades: - list_temp_low = [temp_high - temp_diff_q for - temp_diff_q in temperature_diff_q_grade] + list_temp_low = [ + temp_high - temp_diff_q for temp_diff_q in temperature_diff_q_grade + ] cops_q_grade[q] = cmpr_hp_chiller.calc_cops( temp_high=[temp_high], temp_low=list_temp_low_q_grade, quality_grade=q, - mode='heat_pump') + mode="heat_pump", + ) # Example plot fig1 = plt.figure(figsize=(8, 6)) fig1.set_size_inches(8, 6, forward=True) axs = fig1.add_subplot(111) - plt.plot(cops['temperature_difference_industrial'], - cops[temp_high_industrial], - linestyle='-', - color='red', - label='COP of a high temperature heat pump') - plt.plot(cops['temperature_difference'], - cops[temp_high], - linestyle='-', - color='blue', - label='COP of a heat pump for domestic hot water') + plt.plot( + cops["temperature_difference_industrial"], + cops[temp_high_industrial], + linestyle="-", + color="red", + label="COP of a high temperature heat pump", + ) + plt.plot( + cops["temperature_difference"], + cops[temp_high], + linestyle="-", + color="blue", + label="COP of a heat pump for domestic hot water", + ) for q in quality_grades: - plt.plot(cops_q_grade['temperature_diff'], - cops_q_grade[q], - linestyle='dotted', - color='grey') + plt.plot( + cops_q_grade["temperature_diff"], + cops_q_grade[q], + linestyle="dotted", + color="grey", + ) axs.set_ylim(0, 12) axs.set_xlim(0, 145) - plt.title('COP Dependence on Temperature Difference') - plt.xlabel('Temperature Difference in K') - plt.ylabel('Coefficient of Performance (COP)') - plt.legend(loc='upper right') + plt.title("COP Dependence on Temperature Difference") + plt.xlabel("Temperature Difference in K") + plt.ylabel("Coefficient of Performance (COP)") + plt.legend(loc="upper right") bbox_props = dict(boxstyle="round", fc="w", ec="1.0", alpha=0.9) - textcol = '0.3' + textcol = "0.3" textsize = 10 - axs.text(47, 7.2, "100%", - ha="center", - va="center", - size=textsize, - rotation=-60, - color=textcol, - bbox=bbox_props) - axs.text(57, 5.85, "(Carnot)", - ha="center", - va="center", - size=textsize, - rotation=-52, - color=textcol, - bbox=bbox_props) - axs.text(30, 9.1, "quality grade", - ha="center", - va="center", - size=textsize, - rotation=-76, - color=textcol, - bbox=bbox_props) - axs.text(39, 6.8, "80%", - ha="center", - va="center", - size=textsize, - rotation=-70, - color=textcol, - bbox=bbox_props) - axs.text(12, 5.7, "20%", - ha="center", - va="center", - size=textsize, - rotation=-70, - color=textcol, - bbox=bbox_props) - axs.annotate('quality grade 45%,\nT_sink 110 degC', - xy=(97, 1.8), - xytext=(95, 4), - arrowprops=dict(arrowstyle="->", - connectionstyle="arc3")) - axs.annotate('quality grade 35%,\nT_sink 65 degC', - xy=(40, 3), - xytext=(4, 0.6), - arrowprops=dict(arrowstyle="->", - connectionstyle="arc3")) + axs.text( + 47, + 7.2, + "100%", + ha="center", + va="center", + size=textsize, + rotation=-60, + color=textcol, + bbox=bbox_props, + ) + axs.text( + 57, + 5.85, + "(Carnot)", + ha="center", + va="center", + size=textsize, + rotation=-52, + color=textcol, + bbox=bbox_props, + ) + axs.text( + 30, + 9.1, + "quality grade", + ha="center", + va="center", + size=textsize, + rotation=-76, + color=textcol, + bbox=bbox_props, + ) + axs.text( + 39, + 6.8, + "80%", + ha="center", + va="center", + size=textsize, + rotation=-70, + color=textcol, + bbox=bbox_props, + ) + axs.text( + 12, + 5.7, + "20%", + ha="center", + va="center", + size=textsize, + rotation=-70, + color=textcol, + bbox=bbox_props, + ) + axs.annotate( + "quality grade 45%,\nT_sink 110 degC", + xy=(97, 1.8), + xytext=(95, 4), + arrowprops=dict(arrowstyle="->", connectionstyle="arc3"), + ) + axs.annotate( + "quality grade 35%,\nT_sink 65 degC", + xy=(40, 3), + xytext=(4, 0.6), + arrowprops=dict(arrowstyle="->", connectionstyle="arc3"), + ) # plt.savefig('cop_dependence_on_temp_difference.png', dpi=300) plt.show() diff --git a/examples/compression_heatpump_and_chiller/groundsource_heatpump.py b/examples/compression_heatpump_and_chiller/groundsource_heatpump.py index f9f7fe00..1f0089d9 100644 --- a/examples/compression_heatpump_and_chiller/groundsource_heatpump.py +++ b/examples/compression_heatpump_and_chiller/groundsource_heatpump.py @@ -12,21 +12,23 @@ import matplotlib.pyplot as plt - def groundsource_hp_example(): # Set paths - data_path = os.path.join(os.path.dirname(__file__), 'data/GSHP_example.csv') + data_path = os.path.join( + os.path.dirname(__file__), "data/GSHP_example.csv" + ) # Read input data data = pd.read_csv(data_path) # Set up an energy system model - solver = 'cbc' + solver = "cbc" number_of_time_steps = 24 solver_verbose = False - date_time_index = pd.date_range('1/1/2012', periods=number_of_time_steps, - freq='H') + date_time_index = pd.date_range( + "1/1/2012", periods=number_of_time_steps, freq="H" + ) energysystem = solph.EnergySystem(timeindex=date_time_index) @@ -38,47 +40,66 @@ def groundsource_hp_example(): energysystem.add(b_el, b_th_high, b_th_low) - energysystem.add(solph.components.Source( - label='el_grid', - outputs={b_el: solph.Flow(variable_costs=10)})) + energysystem.add( + solph.components.Source( + label="el_grid", outputs={b_el: solph.Flow(variable_costs=10)} + ) + ) - energysystem.add(solph.components.Source( - label='backup_heating', - outputs={b_th_high: solph.Flow(variable_costs=10)})) + energysystem.add( + solph.components.Source( + label="backup_heating", + outputs={b_th_high: solph.Flow(variable_costs=10)}, + ) + ) # Borehole that acts as heat source for the heat pump with # limited extraction heat flow rate - energysystem.add(solph.components.Source( - label='ambient', - outputs={b_th_low: solph.Flow(nominal_value=30)})) - - energysystem.add(solph.components.Sink( - label='demand', - inputs={b_th_high: solph.Flow(fix=data['demand_heat'], - nominal_value=1)})) + energysystem.add( + solph.components.Source( + label="ambient", outputs={b_th_low: solph.Flow(nominal_value=30)} + ) + ) + + energysystem.add( + solph.components.Sink( + label="demand", + inputs={ + b_th_high: solph.Flow(fix=data["demand_heat"], nominal_value=1) + }, + ) + ) # Precalculation of COPs cops_GSHP = cmpr_hp_chiller.calc_cops( temp_high=[40], - temp_low=data['ground_temperature'], + temp_low=data["ground_temperature"], quality_grade=0.4, - mode='heat_pump') + mode="heat_pump", + ) # Ground-Source Heat Pump - energysystem.add(solph.components.Transformer( - label="GSHP", - inputs={b_el: solph.Flow(), b_th_low: solph.Flow()}, - outputs={b_th_high: solph.Flow(nominal_value=25, variable_costs=5)}, - conversion_factors={b_el: [1 / cop for cop in cops_GSHP], - b_th_low: [(cop - 1) / cop for cop in cops_GSHP]})) + energysystem.add( + solph.components.Transformer( + label="GSHP", + inputs={b_el: solph.Flow(), b_th_low: solph.Flow()}, + outputs={ + b_th_high: solph.Flow(nominal_value=25, variable_costs=5) + }, + conversion_factors={ + b_el: [1 / cop for cop in cops_GSHP], + b_th_low: [(cop - 1) / cop for cop in cops_GSHP], + }, + ) + ) # Create and solve the optimization model model = solph.Model(energysystem) - model.solve(solver=solver, solve_kwargs={'tee': solver_verbose}) + model.solve(solver=solver, solve_kwargs={"tee": solver_verbose}) # Get results - energysystem.results['main'] = solph.processing.results(model) - energysystem.results['meta'] = solph.processing.meta_results(model) + energysystem.results["main"] = solph.processing.results(model) + energysystem.results["meta"] = solph.processing.meta_results(model) energysystem.dump(dpath=None, filename=None) @@ -86,48 +107,46 @@ def groundsource_hp_example(): energysystem = solph.EnergySystem() energysystem.restore(dpath=None, filename=None) - results = energysystem.results['main'] + results = energysystem.results["main"] - electricity_bus = solph.views.node(results, 'electricity') - heat_bus = solph.views.node(results, 'heat') + electricity_bus = solph.views.node(results, "electricity") + heat_bus = solph.views.node(results, "heat") string_results = solph.views.convert_keys_to_strings( - energysystem.results['main']) - GSHP_output = string_results[ - 'GSHP', 'heat']['sequences'].values - demand_h = string_results[ - 'heat', 'demand']['sequences'].values - GSHP_input = string_results[ - 'electricity', 'GSHP']['sequences'].values - env_heat = string_results[ - 'ambient', 'heat_low_temp']['sequences'].values + energysystem.results["main"] + ) + GSHP_output = string_results["GSHP", "heat"]["sequences"].values + demand_h = string_results["heat", "demand"]["sequences"].values + GSHP_input = string_results["electricity", "GSHP"]["sequences"].values + env_heat = string_results["ambient", "heat_low_temp"]["sequences"].values # Example plot fig2, axs = plt.subplots(3, 1, figsize=(8, 5), sharex=True) - axs[0].plot(GSHP_output, label='heat output') - axs[0].plot(demand_h, linestyle='--', label='heat demand') - axs[0].plot(env_heat, label='heat from environment') - axs[1].plot(cops_GSHP, linestyle='-.') - axs[2].plot(data['ground_temperature']) - axs[0].set_title('Heat Output and Demand') - axs[1].set_title('Coefficient of Performance') - axs[2].set_title('Ground Temperature') + axs[0].plot(GSHP_output, label="heat output") + axs[0].plot(demand_h, linestyle="--", label="heat demand") + axs[0].plot(env_heat, label="heat from environment") + axs[1].plot(cops_GSHP, linestyle="-.") + axs[2].plot(data["ground_temperature"]) + axs[0].set_title("Heat Output and Demand") + axs[1].set_title("Coefficient of Performance") + axs[2].set_title("Ground Temperature") axs[0].legend() axs[0].grid() axs[1].grid() axs[2].grid() - axs[0].set_ylabel('Heat flow in kW') - axs[1].set_ylabel('COP') - axs[2].set_ylabel('Temperature in degC') - axs[2].set_xlabel('Time in h') + axs[0].set_ylabel("Heat flow in kW") + axs[1].set_ylabel("COP") + axs[2].set_ylabel("Temperature in degC") + axs[2].set_xlabel("Time in h") plt.tight_layout() plt.show() - print('********* Main results *********') - print(electricity_bus['sequences'].sum(axis=0)) - print(heat_bus['sequences'].sum(axis=0)) + print("********* Main results *********") + print(electricity_bus["sequences"].sum(axis=0)) + print(heat_bus["sequences"].sum(axis=0)) print("heat from environment:", env_heat.sum()) + if __name__ == "__main__": groundsource_hp_example() diff --git a/examples/concentrating_solar_power/csp_collector_plot.py b/examples/concentrating_solar_power/csp_collector_plot.py index 45e96007..1aa582b1 100644 --- a/examples/concentrating_solar_power/csp_collector_plot.py +++ b/examples/concentrating_solar_power/csp_collector_plot.py @@ -5,6 +5,7 @@ The collectors efficiency and irradiance are calculated depending on the default loss method. """ + import os import matplotlib.pyplot as plt @@ -16,8 +17,8 @@ def csp_collector_example(): # Set paths base_path = os.path.dirname(os.path.abspath(os.path.join(__file__))) - data_path = os.path.join(base_path, 'data') - results_path = os.path.join(base_path, 'results') + data_path = os.path.join(base_path, "data") + results_path = os.path.join(base_path, "results") if not os.path.exists(results_path): os.mkdir(results_path) @@ -25,23 +26,29 @@ def csp_collector_example(): # Precalculation # Read input data - dataframe = pd.read_csv(os.path.join(data_path, 'data_Muscat_22_8.csv')) - dataframe['Datum'] = pd.to_datetime(dataframe['Datum']) - dataframe.set_index('Datum', inplace=True) - dataframe.index = dataframe.index.tz_localize(tz='Asia/Muscat') - - df_temp_amb_series = pd.read_csv(os.path.join(data_path, 'data_Muscat_22_8_midday.csv')) - df_temp_amb_series['Datum'] = pd.to_datetime(df_temp_amb_series['Datum']) - df_temp_amb_series.set_index('Datum', inplace=True) - df_temp_amb_series.index = df_temp_amb_series.index.tz_localize(tz='Asia/Muscat') - - temp_amb_series = pd.read_csv(os.path.join(data_path, 'temp_ambience.csv'))['t_amb'] + dataframe = pd.read_csv(os.path.join(data_path, "data_Muscat_22_8.csv")) + dataframe["Datum"] = pd.to_datetime(dataframe["Datum"]) + dataframe.set_index("Datum", inplace=True) + dataframe.index = dataframe.index.tz_localize(tz="Asia/Muscat") + + df_temp_amb_series = pd.read_csv( + os.path.join(data_path, "data_Muscat_22_8_midday.csv") + ) + df_temp_amb_series["Datum"] = pd.to_datetime(df_temp_amb_series["Datum"]) + df_temp_amb_series.set_index("Datum", inplace=True) + df_temp_amb_series.index = df_temp_amb_series.index.tz_localize( + tz="Asia/Muscat" + ) + + temp_amb_series = pd.read_csv( + os.path.join(data_path, "temp_ambience.csv") + )["t_amb"] # Parameters for the precalculation periods = 24 latitude = 23.614328 longitude = 58.545284 - timezone = 'Asia/Muscat' + timezone = "Asia/Muscat" collector_tilt = 10 collector_azimuth = 180 cleanliness = 0.9 @@ -55,26 +62,39 @@ def csp_collector_example(): # Plot showing the difference between a constant efficiency without considering # cleaniness for the heat of the collector during a day - data_precalc = csp_precalc(latitude, longitude, - collector_tilt, collector_azimuth, cleanliness, - eta_0, c_1, c_2, - temp_collector_inlet, temp_collector_outlet, - dataframe['t_amb'], - a_1, a_2, - E_dir_hor=dataframe['E_dir_hor']) - - heat_calc = data_precalc['collector_heat'] - irradiance_on_collector = (data_precalc['collector_irradiance'] - / (cleanliness**1.5)) + data_precalc = csp_precalc( + latitude, + longitude, + collector_tilt, + collector_azimuth, + cleanliness, + eta_0, + c_1, + c_2, + temp_collector_inlet, + temp_collector_outlet, + dataframe["t_amb"], + a_1, + a_2, + E_dir_hor=dataframe["E_dir_hor"], + ) + + heat_calc = data_precalc["collector_heat"] + irradiance_on_collector = data_precalc["collector_irradiance"] / ( + cleanliness**1.5 + ) heat_compare = irradiance_on_collector * eta_0 t = list(range(1, 25)) # Example plot fig, ax = plt.subplots() - ax.plot(t, heat_calc, label='CSP precalculation') - ax.plot(t, heat_compare, label='constant efficiency') - ax.set(xlabel='time [h]', ylabel='Q_coll [W/m2]', - title='Heat of the collector') + ax.plot(t, heat_calc, label="CSP precalculation") + ax.plot(t, heat_compare, label="constant efficiency") + ax.set( + xlabel="time [h]", + ylabel="Q_coll [W/m2]", + title="Heat of the collector", + ) ax.grid() ax.legend() @@ -83,25 +103,39 @@ def csp_collector_example(): # day df_result = pd.DataFrame() for i in range(len(temp_amb_series)): - df_temp_amb_series['t_amb'] = temp_amb_series[i] + df_temp_amb_series["t_amb"] = temp_amb_series[i] data_precalc_temp_amb = csp_precalc( - latitude, longitude, - collector_tilt, collector_azimuth, cleanliness, - eta_0, c_1, c_2, - temp_collector_inlet, temp_collector_outlet, - df_temp_amb_series['t_amb'], - a_1, a_2, - E_dir_hor=df_temp_amb_series['E_dir_hor']) + latitude, + longitude, + collector_tilt, + collector_azimuth, + cleanliness, + eta_0, + c_1, + c_2, + temp_collector_inlet, + temp_collector_outlet, + df_temp_amb_series["t_amb"], + a_1, + a_2, + E_dir_hor=df_temp_amb_series["E_dir_hor"], + ) df_result = df_result.append(data_precalc_temp_amb, ignore_index=True) fig, ax = plt.subplots() - ax.plot(temp_amb_series, df_result['eta_c'], - label='efficiency depending on ambient temperature') - ax.plot(temp_amb_series, [eta_0] * 24, label='constant efficiency') + ax.plot( + temp_amb_series, + df_result["eta_c"], + label="efficiency depending on ambient temperature", + ) + ax.plot(temp_amb_series, [eta_0] * 24, label="constant efficiency") ax.set_ylim(0, 1) - ax.set(xlabel='ambient temperature [°C]', ylabel='eta_collector', - title='collectors efficiency') + ax.set( + xlabel="ambient temperature [°C]", + ylabel="eta_collector", + title="collectors efficiency", + ) ax.grid() ax.legend() plt.show() diff --git a/examples/concentrating_solar_power/csp_collector_plot_andasol.py b/examples/concentrating_solar_power/csp_collector_plot_andasol.py index cbc1c158..45afa8fe 100644 --- a/examples/concentrating_solar_power/csp_collector_plot_andasol.py +++ b/examples/concentrating_solar_power/csp_collector_plot_andasol.py @@ -5,6 +5,7 @@ The collectors efficiency and irradiance are calculated depending on the loss method 'Andasol'. """ + import os import matplotlib.pyplot as plt @@ -16,8 +17,8 @@ def csp_andasol_example(): # Set paths base_path = os.path.dirname(os.path.abspath(os.path.join(__file__))) - data_path = os.path.join(base_path, 'data') - results_path = os.path.join(base_path, 'results') + data_path = os.path.join(base_path, "data") + results_path = os.path.join(base_path, "results") if not os.path.exists(results_path): os.mkdir(results_path) @@ -25,23 +26,29 @@ def csp_andasol_example(): # Precalculation # Read input data - dataframe = pd.read_csv(os.path.join(data_path, 'data_Muscat_22_8.csv')) - dataframe['Datum'] = pd.to_datetime(dataframe['Datum']) - dataframe.set_index('Datum', inplace=True) - dataframe.index = dataframe.index.tz_localize(tz='Asia/Muscat') - - df_temp_amb_series = pd.read_csv(os.path.join(data_path, 'data_Muscat_22_8_midday.csv')) - df_temp_amb_series['Datum'] = pd.to_datetime(df_temp_amb_series['Datum']) - df_temp_amb_series.set_index('Datum', inplace=True) - df_temp_amb_series.index = df_temp_amb_series.index.tz_localize(tz='Asia/Muscat') - - temp_amb_series = pd.read_csv(os.path.join(data_path, 'temp_ambience.csv'))['t_amb'] + dataframe = pd.read_csv(os.path.join(data_path, "data_Muscat_22_8.csv")) + dataframe["Datum"] = pd.to_datetime(dataframe["Datum"]) + dataframe.set_index("Datum", inplace=True) + dataframe.index = dataframe.index.tz_localize(tz="Asia/Muscat") + + df_temp_amb_series = pd.read_csv( + os.path.join(data_path, "data_Muscat_22_8_midday.csv") + ) + df_temp_amb_series["Datum"] = pd.to_datetime(df_temp_amb_series["Datum"]) + df_temp_amb_series.set_index("Datum", inplace=True) + df_temp_amb_series.index = df_temp_amb_series.index.tz_localize( + tz="Asia/Muscat" + ) + + temp_amb_series = pd.read_csv( + os.path.join(data_path, "temp_ambience.csv") + )["t_amb"] # Parameters for the precalculation periods = 24 latitude = 23.614328 longitude = 58.545284 - timezone = 'Asia/Muscat' + timezone = "Asia/Muscat" collector_tilt = 10 collector_azimuth = 180 cleanliness = 0.9 @@ -60,27 +67,44 @@ def csp_andasol_example(): # Plot showing the difference between a constant efficiency without considering # cleaniness for the heat of the collector during a day - data_precalc = csp_precalc(latitude, longitude, - collector_tilt, collector_azimuth, cleanliness, - eta_0, c_1, c_2, - temp_collector_inlet, temp_collector_outlet, - dataframe['t_amb'], - a_1, a_2, a_3, a_4, a_5, a_6, - loss_method='Andasol', - E_dir_hor=dataframe['E_dir_hor']) - - heat_calc = data_precalc['collector_heat'] - irradiance_on_collector = (data_precalc['collector_irradiance'] - / (cleanliness**1.5)) + data_precalc = csp_precalc( + latitude, + longitude, + collector_tilt, + collector_azimuth, + cleanliness, + eta_0, + c_1, + c_2, + temp_collector_inlet, + temp_collector_outlet, + dataframe["t_amb"], + a_1, + a_2, + a_3, + a_4, + a_5, + a_6, + loss_method="Andasol", + E_dir_hor=dataframe["E_dir_hor"], + ) + + heat_calc = data_precalc["collector_heat"] + irradiance_on_collector = data_precalc["collector_irradiance"] / ( + cleanliness**1.5 + ) heat_compare = irradiance_on_collector * eta_0 t = list(range(1, 25)) # Example plot fig, ax = plt.subplots() - ax.plot(t, heat_calc, label='CSP precalculation') - ax.plot(t, heat_compare, label='constant efficiency') - ax.set(xlabel='time (h)', ylabel='Q_coll [W/m2]', - title='Heat of the collector') + ax.plot(t, heat_calc, label="CSP precalculation") + ax.plot(t, heat_compare, label="constant efficiency") + ax.set( + xlabel="time (h)", + ylabel="Q_coll [W/m2]", + title="Heat of the collector", + ) ax.grid() ax.legend() @@ -89,29 +113,48 @@ def csp_andasol_example(): # day df_result = pd.DataFrame() for i in range(len(temp_amb_series)): - df_temp_amb_series['t_amb'] = temp_amb_series[i] + df_temp_amb_series["t_amb"] = temp_amb_series[i] data_precalc_temp_amb = csp_precalc( - latitude, longitude, - collector_tilt, collector_azimuth, cleanliness, - eta_0, c_1, c_2, - temp_collector_inlet, temp_collector_outlet, - df_temp_amb_series['t_amb'], - a_1, a_2, a_3, a_4, a_5, a_6, - loss_method='Andasol', - E_dir_hor=df_temp_amb_series['E_dir_hor']) + latitude, + longitude, + collector_tilt, + collector_azimuth, + cleanliness, + eta_0, + c_1, + c_2, + temp_collector_inlet, + temp_collector_outlet, + df_temp_amb_series["t_amb"], + a_1, + a_2, + a_3, + a_4, + a_5, + a_6, + loss_method="Andasol", + E_dir_hor=df_temp_amb_series["E_dir_hor"], + ) df_result = df_result.append(data_precalc_temp_amb, ignore_index=True) fig, ax = plt.subplots() - ax.plot(temp_amb_series, df_result['eta_c'], - label='efficiency depending on ambient temperature') - ax.plot(temp_amb_series, [eta_0] * 24, label='constant efficiency') + ax.plot( + temp_amb_series, + df_result["eta_c"], + label="efficiency depending on ambient temperature", + ) + ax.plot(temp_amb_series, [eta_0] * 24, label="constant efficiency") ax.set_ylim(0, 1) - ax.set(xlabel='ambient temperature [°C]', ylabel='eta_collector', - title='collectors efficiency') + ax.set( + xlabel="ambient temperature [°C]", + ylabel="eta_collector", + title="collectors efficiency", + ) ax.grid() ax.legend() plt.show() + if __name__ == "__main__": csp_andasol_example() diff --git a/examples/concentrating_solar_power/csp_facade.py b/examples/concentrating_solar_power/csp_facade.py index bfd8a6fc..9344bbfa 100644 --- a/examples/concentrating_solar_power/csp_facade.py +++ b/examples/concentrating_solar_power/csp_facade.py @@ -8,6 +8,7 @@ SPDX-License-Identifier: MIT """ + import os import pandas as pd import matplotlib.pyplot as plt @@ -17,17 +18,17 @@ from oemof import solph from oemof.tools import economics + def csp_facade_example(): # Set paths base_path = os.path.dirname(os.path.abspath(os.path.join(__file__))) - results_path = os.path.join(base_path, 'results') - data_path = os.path.join(base_path, 'data') + results_path = os.path.join(base_path, "results") + data_path = os.path.join(base_path, "data") if not os.path.exists(results_path): os.mkdir(results_path) - # Set up an energy system model periods = 50 latitude = 23.614328 @@ -44,14 +45,15 @@ def csp_facade_example(): temp_collector_outlet = 500 # Read input data - input_data = pd.read_csv(os.path.join(data_path, 'data_csp_plant.csv')).head(periods) - input_data['Datum'] = pd.to_datetime(input_data['Datum']) - input_data.set_index('Datum', inplace=True) - input_data.index = input_data.index.tz_localize(tz='Asia/Muscat') + input_data = pd.read_csv( + os.path.join(data_path, "data_csp_plant.csv") + ).head(periods) + input_data["Datum"] = pd.to_datetime(input_data["Datum"]) + input_data.set_index("Datum", inplace=True) + input_data.index = input_data.index.tz_localize(tz="Asia/Muscat") date_time_index = input_data.index - date_time_index.freq = 'H' - + date_time_index.freq = "H" # oemof_system @@ -67,19 +69,19 @@ def csp_facade_example(): size_collector = 1000 # Busses - bth = solph.Bus(label='thermal') - bel = solph.Bus(label='electricity') + bth = solph.Bus(label="thermal") + bel = solph.Bus(label="electricity") # Collector collector = facades.ParabolicTroughCollector( - label='solar_collector', + label="solar_collector", heat_bus=bth, electrical_bus=bel, electrical_consumption=elec_consumption, additional_losses=additional_losses, aperture_area=size_collector, - loss_method='Janotte', - irradiance_method='horizontal', + loss_method="Janotte", + irradiance_method="horizontal", latitude=latitude, longitude=longitude, collector_tilt=collector_tilt, @@ -92,72 +94,92 @@ def csp_facade_example(): c_2=c_2, temp_collector_inlet=temp_collector_inlet, temp_collector_outlet=temp_collector_outlet, - temp_amb=input_data['t_amb'], - irradiance=input_data['E_dir_hor']) + temp_amb=input_data["t_amb"], + irradiance=input_data["E_dir_hor"], + ) # Sources and sinks el_grid = solph.components.Source( - label='grid', - outputs={bel: solph.Flow(variable_costs=costs_electricity)}) + label="grid", + outputs={bel: solph.Flow(variable_costs=costs_electricity)}, + ) backup = solph.components.Source( - label='backup', - outputs={bth: solph.Flow(variable_costs=backup_costs)}) + label="backup", outputs={bth: solph.Flow(variable_costs=backup_costs)} + ) consumer = solph.components.Sink( - label='demand', - inputs={bel: solph.Flow( - fix=input_data['ES_load_actual_entsoe_power_statistics'], - nominal_value=1)}) + label="demand", + inputs={ + bel: solph.Flow( + fix=input_data["ES_load_actual_entsoe_power_statistics"], + nominal_value=1, + ) + }, + ) - excess = solph.components.Sink( - label='excess', - inputs={bth: solph.Flow()}) + excess = solph.components.Sink(label="excess", inputs={bth: solph.Flow()}) # Transformer and storages turbine = solph.components.Transformer( - label='turbine', + label="turbine", inputs={bth: solph.Flow()}, outputs={bel: solph.Flow()}, - conversion_factors={bel: conversion_factor_turbine}) + conversion_factors={bel: conversion_factor_turbine}, + ) storage = solph.components.GenericStorage( - label='storage_th', + label="storage_th", inputs={bth: solph.Flow()}, outputs={bth: solph.Flow()}, loss_rate=cap_loss, inflow_conversion_factor=conversion_storage, outflow_conversion_factor=conversion_storage, - investment=solph.Investment(ep_costs=costs_storage)) + investment=solph.Investment(ep_costs=costs_storage), + ) # Build the system and solve the problem energysystem = solph.EnergySystem(timeindex=date_time_index) - energysystem.add(bth, bel, el_grid, backup, excess, consumer, storage, turbine, - collector) + energysystem.add( + bth, + bel, + el_grid, + backup, + excess, + consumer, + storage, + turbine, + collector, + ) # Create and solve the optimization model model = solph.Model(energysystem) - model.solve(solver='cbc', solve_kwargs={'tee': True}) + model.solve(solver="cbc", solve_kwargs={"tee": True}) # Get results results = solph.processing.results(model) - collector_inflow = solph.views.node( - results, 'solar_collector-inflow')['sequences'] - thermal_bus = solph.views.node(results, 'thermal')['sequences'] - electricity_bus = solph.views.node(results, 'electricity')['sequences'] + collector_inflow = solph.views.node(results, "solar_collector-inflow")[ + "sequences" + ] + thermal_bus = solph.views.node(results, "thermal")["sequences"] + electricity_bus = solph.views.node(results, "electricity")["sequences"] df = pd.DataFrame() df = df.append(collector_inflow) - df = df.join(thermal_bus, lsuffix='_1') - df = df.join(electricity_bus, lsuffix='_1') - df.to_csv(os.path.join(results_path, 'facade_results.csv')) + df = df.join(thermal_bus, lsuffix="_1") + df = df.join(electricity_bus, lsuffix="_1") + df.to_csv(os.path.join(results_path, "facade_results.csv")) # Example plot fig, ax = plt.subplots() - ax.plot(list(range(periods)), thermal_bus[(('solar_collector', 'thermal'), 'flow')][:-1]) - ax.set(xlabel='time [h]', ylabel='Q_coll [W]', - title='Heat of the collector') + ax.plot( + list(range(periods)), + thermal_bus[(("solar_collector", "thermal"), "flow")][:-1], + ) + ax.set( + xlabel="time [h]", ylabel="Q_coll [W]", title="Heat of the collector" + ) ax.grid() plt.show() diff --git a/examples/concentrating_solar_power/csp_plant.py b/examples/concentrating_solar_power/csp_plant.py index 3b3383e4..38d65a6e 100644 --- a/examples/concentrating_solar_power/csp_plant.py +++ b/examples/concentrating_solar_power/csp_plant.py @@ -21,8 +21,8 @@ def csp_plant_example(): # Set paths base_path = os.path.dirname(os.path.abspath(os.path.join(__file__))) - results_path = os.path.join(base_path, 'results') - data_path = os.path.join(base_path, 'data') + results_path = os.path.join(base_path, "results") + data_path = os.path.join(base_path, "data") if not os.path.exists(results_path): os.mkdir(results_path) @@ -47,28 +47,42 @@ def csp_plant_example(): # It is necessary, to set a timeindex, so the pvlib is able to process the data # Here, the given column 'Datum' is convertet to a datetime and this is used as # index: - dataframe = pd.read_csv(os.path.join(data_path, 'data_csp_plant.csv')).head(periods) - dataframe['Datum'] = pd.to_datetime(dataframe['Datum']) - dataframe.set_index('Datum', inplace=True) + dataframe = pd.read_csv( + os.path.join(data_path, "data_csp_plant.csv") + ).head(periods) + dataframe["Datum"] = pd.to_datetime(dataframe["Datum"]) + dataframe.set_index("Datum", inplace=True) # For some pandas version, it is necessary to set the frequence of the df: - dataframe = dataframe.asfreq('H') + dataframe = dataframe.asfreq("H") # The time of the input data is given locally, so it has to be adapted to the # correct timezone: - dataframe.index = dataframe.index.tz_localize(tz='Asia/Muscat') + dataframe.index = dataframe.index.tz_localize(tz="Asia/Muscat") # Precalculation - data_precalc = csp_precalc(latitude, longitude, - collector_tilt, collector_azimuth, cleanliness, - eta_0, c_1, c_2, - temp_collector_inlet, temp_collector_outlet, - dataframe['t_amb'], - a_1, a_2, - E_dir_hor=dataframe['E_dir_hor']) - - data_precalc['ES_load_actual_entsoe_power_statistics'] = list( - dataframe['ES_load_actual_entsoe_power_statistics'].iloc[:periods]) - - data_precalc.to_csv(os.path.join(results_path, 'results_csp_plant_precalc.csv')) + data_precalc = csp_precalc( + latitude, + longitude, + collector_tilt, + collector_azimuth, + cleanliness, + eta_0, + c_1, + c_2, + temp_collector_inlet, + temp_collector_outlet, + dataframe["t_amb"], + a_1, + a_2, + E_dir_hor=dataframe["E_dir_hor"], + ) + + data_precalc["ES_load_actual_entsoe_power_statistics"] = list( + dataframe["ES_load_actual_entsoe_power_statistics"].iloc[:periods] + ) + + data_precalc.to_csv( + os.path.join(results_path, "results_csp_plant_precalc.csv") + ) # Regular oemof_system @@ -84,90 +98,121 @@ def csp_plant_example(): size_collector = 1000 # Busses - bth = solph.Bus(label='thermal') - bel = solph.Bus(label='electricity') - bcol = solph.Bus(label='solar') + bth = solph.Bus(label="thermal") + bel = solph.Bus(label="electricity") + bcol = solph.Bus(label="solar") # Sources and sinks col_heat = solph.components.Source( - label='collector_heat', - outputs={bcol: solph.Flow( - fix=data_precalc['collector_heat'], - nominal_value=size_collector)}) + label="collector_heat", + outputs={ + bcol: solph.Flow( + fix=data_precalc["collector_heat"], + nominal_value=size_collector, + ) + }, + ) el_grid = solph.components.Source( - label='grid', - outputs={bel: solph.Flow(variable_costs=costs_electricity)}) + label="grid", + outputs={bel: solph.Flow(variable_costs=costs_electricity)}, + ) backup = solph.components.Source( - label='backup', - outputs={bth: solph.Flow(variable_costs=backup_costs)}) + label="backup", outputs={bth: solph.Flow(variable_costs=backup_costs)} + ) consumer = solph.components.Sink( - label='demand', - inputs={bel: solph.Flow( - fix=data_precalc['ES_load_actual_entsoe_power_statistics'], - nominal_value=1)}) + label="demand", + inputs={ + bel: solph.Flow( + fix=data_precalc["ES_load_actual_entsoe_power_statistics"], + nominal_value=1, + ) + }, + ) ambience_sol = solph.components.Sink( - label='ambience_sol', - inputs={bcol: solph.Flow()}) + label="ambience_sol", inputs={bcol: solph.Flow()} + ) # Transformer and storages collector = solph.components.Transformer( - label='collector', - inputs={ - bcol: solph.Flow(), - bel: solph.Flow()}, + label="collector", + inputs={bcol: solph.Flow(), bel: solph.Flow()}, outputs={bth: solph.Flow()}, conversion_factors={ bcol: 1, bel: elec_consumption * (1 - additional_losses), - bth: 1 - additional_losses}) + bth: 1 - additional_losses, + }, + ) turbine = solph.components.Transformer( - label='turbine', + label="turbine", inputs={bth: solph.Flow()}, outputs={bel: solph.Flow()}, - conversion_factors={bel: conversion_factor_turbine}) + conversion_factors={bel: conversion_factor_turbine}, + ) storage = solph.components.GenericStorage( - label='storage_th', + label="storage_th", inputs={bth: solph.Flow()}, outputs={bth: solph.Flow()}, loss_rate=cap_loss, inflow_conversion_factor=conversion_storage, outflow_conversion_factor=conversion_storage, - investment=solph.Investment(ep_costs=costs_storage)) + investment=solph.Investment(ep_costs=costs_storage), + ) # Build the system and solve the problem dataframe.index.freq = pd.infer_freq(dataframe.index) date_time_index = dataframe.index energysystem = solph.EnergySystem(timeindex=date_time_index) - energysystem.add(bth, bcol, bel, col_heat, el_grid, backup, consumer, - ambience_sol, collector, turbine, storage) + energysystem.add( + bth, + bcol, + bel, + col_heat, + el_grid, + backup, + consumer, + ambience_sol, + collector, + turbine, + storage, + ) # Create and solve the optimization model model = solph.Model(energysystem) - model.solve(solver='cbc', solve_kwargs={'tee': True}) + model.solve(solver="cbc", solve_kwargs={"tee": True}) # Get results results = solph.processing.results(model) - electricity_bus = solph.views.node(results, 'electricity')['sequences'] - thermal_bus = solph.views.node(results, 'thermal')['sequences'] - solar_bus = solph.views.node(results, 'solar')['sequences'] + electricity_bus = solph.views.node(results, "electricity")["sequences"] + thermal_bus = solph.views.node(results, "thermal")["sequences"] + solar_bus = solph.views.node(results, "solar")["sequences"] df = pd.merge( - pd.merge(electricity_bus, thermal_bus, left_index=True, right_index=True), - solar_bus, left_index=True, right_index=True) - df.to_csv(os.path.join(results_path, 'csp_plant_results.csv')) + pd.merge( + electricity_bus, thermal_bus, left_index=True, right_index=True + ), + solar_bus, + left_index=True, + right_index=True, + ) + df.to_csv(os.path.join(results_path, "csp_plant_results.csv")) # Example plot fig, ax = plt.subplots() - ax.plot(list(range(periods)), thermal_bus[(('collector', 'thermal'), 'flow')][:-1]) - ax.set(xlabel='time [h]', ylabel='Q_coll [W]', - title='Heat of the collector') + ax.plot( + list(range(periods)), + thermal_bus[(("collector", "thermal"), "flow")][:-1], + ) + ax.set( + xlabel="time [h]", ylabel="Q_coll [W]", title="Heat of the collector" + ) ax.grid() plt.show() diff --git a/examples/solar_thermal_collector/_plots.py b/examples/solar_thermal_collector/_plots.py index 94816002..389c4231 100644 --- a/examples/solar_thermal_collector/_plots.py +++ b/examples/solar_thermal_collector/_plots.py @@ -5,31 +5,32 @@ import os import matplotlib.pyplot as plt + def plot_collector_heat(data_precalc, periods, eta_0): - ''' + """ Plot showing the difference between a constant efficiency and the efficiency depending on the ambient temperature for the same irradiance and hour of the day. - ''' + """ - heat_calc = data_precalc['collectors_heat'] - irradiance_on_collector = data_precalc['col_ira'] + heat_calc = data_precalc["collectors_heat"] + irradiance_on_collector = data_precalc["col_ira"] heat_compare = irradiance_on_collector * eta_0 t = list(range(1, periods + 1)) fig, ax = plt.subplots() - ax.plot(t, heat_calc, label='Solar thermal precalculation') - ax.plot(t, heat_compare, label='constant efficiency') + ax.plot(t, heat_calc, label="Solar thermal precalculation") + ax.plot(t, heat_compare, label="constant efficiency") ax.set( - xlabel='time in h', - ylabel='Q_coll in W/m2', - title='Heat of the collector', + xlabel="time in h", + ylabel="Q_coll in W/m2", + title="Heat of the collector", ) ax.grid() ax.legend() base_path = os.path.dirname(os.path.abspath(os.path.join(__file__))) - plt.savefig(os.path.join(base_path, 'results/compare_precalculations.png')) + plt.savefig(os.path.join(base_path, "results/compare_precalculations.png")) plt.show() return diff --git a/examples/solar_thermal_collector/flat_plate_collector.py b/examples/solar_thermal_collector/flat_plate_collector.py index 7342cbec..394c3a5b 100644 --- a/examples/solar_thermal_collector/flat_plate_collector.py +++ b/examples/solar_thermal_collector/flat_plate_collector.py @@ -18,11 +18,12 @@ from ._plots import plot_collector_heat + def flat_plate_collector_example(): # Set paths base_path = os.path.dirname(os.path.abspath(os.path.join(__file__))) - data_path = os.path.join(base_path, 'data') - results_path = os.path.join(base_path, 'results') + data_path = os.path.join(base_path, "data") + results_path = os.path.join(base_path, "results") if not os.path.exists(results_path): os.mkdir(results_path) @@ -39,17 +40,18 @@ def flat_plate_collector_example(): delta_temp_n = 10 # Read input data - input_data = pd.read_csv(os.path.join(data_path, 'data_flat_collector.csv')).head(periods) - input_data['Datum'] = pd.to_datetime(input_data['Datum']) - input_data.set_index('Datum', inplace=True) - input_data.index = input_data.index.tz_localize(tz='Europe/Berlin') - input_data = input_data.asfreq('H') + input_data = pd.read_csv( + os.path.join(data_path, "data_flat_collector.csv") + ).head(periods) + input_data["Datum"] = pd.to_datetime(input_data["Datum"]) + input_data.set_index("Datum", inplace=True) + input_data.index = input_data.index.tz_localize(tz="Europe/Berlin") + input_data = input_data.asfreq("H") demand_df = pd.read_csv( - os.path.join(base_path, 'data', 'heat_demand.csv'), - sep=',' + os.path.join(base_path, "data", "heat_demand.csv"), sep="," ) - demand = list(demand_df['heat_demand'].iloc[:periods]) + demand = list(demand_df["heat_demand"].iloc[:periods]) # Precalculation # - calculate global irradiance on the collector area @@ -65,17 +67,15 @@ def flat_plate_collector_example(): a_2, temp_collector_inlet, delta_temp_n, - irradiance_global=input_data['global_horizontal_W_m2'], - irradiance_diffuse=input_data['diffuse_horizontal_W_m2'], - temp_amb=input_data['temp_amb'], + irradiance_global=input_data["global_horizontal_W_m2"], + irradiance_diffuse=input_data["diffuse_horizontal_W_m2"], + temp_amb=input_data["temp_amb"], ) precalc_data.to_csv( - os.path.join(results_path, 'flat_plate_precalcs.csv'), - sep=';' + os.path.join(results_path, "flat_plate_precalcs.csv"), sep=";" ) - # regular oemof system # # Parameters for the energy system @@ -89,17 +89,17 @@ def flat_plate_collector_example(): size_collector = 10 # m2 # busses - bth = solph.Bus(label='thermal') - bel = solph.Bus(label='electricity') - bcol = solph.Bus(label='solar') + bth = solph.Bus(label="thermal") + bel = solph.Bus(label="electricity") + bcol = solph.Bus(label="solar") # source for collector heat. # - actual_value is the precalculated collector heat - collector_heat = solph.components.Source( - label='collector_heat', + label="collector_heat", outputs={ bcol: solph.Flow( - fix=precalc_data['collectors_heat'], + fix=precalc_data["collectors_heat"], nominal_value=size_collector, ) }, @@ -107,36 +107,37 @@ def flat_plate_collector_example(): # sources and sinks el_grid = solph.components.Source( - label='grid', outputs={bel: solph.Flow(variable_costs=costs_electricity)} + label="grid", + outputs={bel: solph.Flow(variable_costs=costs_electricity)}, ) backup = solph.components.Source( - label='backup', outputs={bth: solph.Flow(variable_costs=backup_costs)} + label="backup", outputs={bth: solph.Flow(variable_costs=backup_costs)} ) consumer = solph.components.Sink( - label='demand', + label="demand", inputs={bth: solph.Flow(fix=demand, nominal_value=1)}, ) collector_excess_heat = solph.components.Sink( - label='collector_excess_heat', inputs={bcol: solph.Flow()} + label="collector_excess_heat", inputs={bcol: solph.Flow()} ) # transformer and storage collector = solph.components.Transformer( - label='collector', + label="collector", inputs={bcol: solph.Flow(), bel: solph.Flow()}, outputs={bth: solph.Flow()}, conversion_factors={ bcol: 1, bel: elec_consumption * (1 - peripheral_losses), - bth: 1 - peripheral_losses + bth: 1 - peripheral_losses, }, ) storage = solph.components.GenericStorage( - label='storage', + label="storage", inputs={bth: solph.Flow()}, outputs={bth: solph.Flow()}, loss_rate=storage_loss_rate, @@ -164,18 +165,23 @@ def flat_plate_collector_example(): # Create and solve the optimization model model = solph.Model(energysystem) - model.solve(solver='cbc', solve_kwargs={'tee': True}) + model.solve(solver="cbc", solve_kwargs={"tee": True}) # Get results results = solph.processing.results(model) - electricity_bus = solph.views.node(results, 'electricity')['sequences'] - thermal_bus = solph.views.node(results, 'thermal')['sequences'] - solar_bus = solph.views.node(results, 'solar')['sequences'] + electricity_bus = solph.views.node(results, "electricity")["sequences"] + thermal_bus = solph.views.node(results, "thermal")["sequences"] + solar_bus = solph.views.node(results, "solar")["sequences"] df = pd.merge( - pd.merge(electricity_bus, thermal_bus, left_index=True, right_index=True), - solar_bus, left_index=True, right_index=True) - df.to_csv(os.path.join(results_path, 'flat_plate_results.csv')) + pd.merge( + electricity_bus, thermal_bus, left_index=True, right_index=True + ), + solar_bus, + left_index=True, + right_index=True, + ) + df.to_csv(os.path.join(results_path, "flat_plate_results.csv")) # Example plot plot_collector_heat(precalc_data, periods, eta_0) diff --git a/examples/solar_thermal_collector/flat_plate_collector_facade.py b/examples/solar_thermal_collector/flat_plate_collector_facade.py index e1c6e25a..e8127870 100644 --- a/examples/solar_thermal_collector/flat_plate_collector_facade.py +++ b/examples/solar_thermal_collector/flat_plate_collector_facade.py @@ -15,11 +15,12 @@ from oemof import solph from oemof.tools import economics + def flat_plate_collector_facade_example(): # Set paths base_path = os.path.dirname(os.path.abspath(os.path.join(__file__))) - data_path = os.path.join(base_path, 'data') - results_path = os.path.join(base_path, 'results') + data_path = os.path.join(base_path, "data") + results_path = os.path.join(base_path, "results") if not os.path.exists(results_path): os.mkdir(results_path) @@ -45,28 +46,28 @@ def flat_plate_collector_facade_example(): size_collector = 10 # m2 # Read input data - input_data = pd.read_csv(os.path.join(data_path, 'data_flat_collector.csv')).head(periods) - input_data['Datum'] = pd.to_datetime(input_data['Datum']) - input_data.set_index('Datum', inplace=True) - input_data.index = input_data.index.tz_localize(tz='Europe/Berlin') - input_data = input_data.asfreq('H') + input_data = pd.read_csv( + os.path.join(data_path, "data_flat_collector.csv") + ).head(periods) + input_data["Datum"] = pd.to_datetime(input_data["Datum"]) + input_data.set_index("Datum", inplace=True) + input_data.index = input_data.index.tz_localize(tz="Europe/Berlin") + input_data = input_data.asfreq("H") demand_df = pd.read_csv( - os.path.join(data_path, 'heat_demand.csv'), - sep=',' + os.path.join(data_path, "heat_demand.csv"), sep="," ) - demand = list(demand_df['heat_demand'].iloc[:periods]) - + demand = list(demand_df["heat_demand"].iloc[:periods]) # Set up an energy system model # Busses - bth = solph.Bus(label='thermal') - bel = solph.Bus(label='electricity') + bth = solph.Bus(label="thermal") + bel = solph.Bus(label="electricity") # Collector collector = facades.SolarThermalCollector( - label='solar_collector', + label="solar_collector", heat_out_bus=bth, electricity_in_bus=bel, electrical_consumption=elec_consumption, @@ -81,31 +82,33 @@ def flat_plate_collector_facade_example(): a_2=a_2, temp_collector_inlet=temp_collector_inlet, delta_temp_n=delta_temp_n, - irradiance_global=input_data['global_horizontal_W_m2'], - irradiance_diffuse=input_data['diffuse_horizontal_W_m2'], - temp_amb=input_data['temp_amb']) + irradiance_global=input_data["global_horizontal_W_m2"], + irradiance_diffuse=input_data["diffuse_horizontal_W_m2"], + temp_amb=input_data["temp_amb"], + ) # Sources and sinks el_grid = solph.components.Source( - label='grid', outputs={bel: solph.Flow(variable_costs=costs_electricity)} + label="grid", + outputs={bel: solph.Flow(variable_costs=costs_electricity)}, ) backup = solph.components.Source( - label='backup', outputs={bth: solph.Flow(variable_costs=backup_costs)} + label="backup", outputs={bth: solph.Flow(variable_costs=backup_costs)} ) consumer = solph.components.Sink( - label='demand', + label="demand", inputs={bth: solph.Flow(fix=demand, nominal_value=1)}, ) collector_excess_heat = solph.components.Sink( - label='collector_excess_heat', inputs={bth: solph.Flow()} + label="collector_excess_heat", inputs={bth: solph.Flow()} ) # Storage storage = solph.components.GenericStorage( - label='storage', + label="storage", inputs={bth: solph.Flow()}, outputs={bth: solph.Flow()}, loss_rate=storage_loss_rate, @@ -131,20 +134,21 @@ def flat_plate_collector_facade_example(): # Create and solve the optimization model model = solph.Model(energysystem) - model.solve(solver='cbc', solve_kwargs={'tee': True}) + model.solve(solver="cbc", solve_kwargs={"tee": True}) # Get results results = solph.processing.results(model) - collector_inflow = solph.views.node( - results, 'solar_collector-inflow')['sequences'] - thermal_bus = solph.views.node(results, 'thermal')['sequences'] - electricity_bus = solph.views.node(results, 'electricity')['sequences'] + collector_inflow = solph.views.node(results, "solar_collector-inflow")[ + "sequences" + ] + thermal_bus = solph.views.node(results, "thermal")["sequences"] + electricity_bus = solph.views.node(results, "electricity")["sequences"] df = pd.DataFrame() df = df.append(collector_inflow) - df = df.join(thermal_bus, lsuffix='_1') - df = df.join(electricity_bus, lsuffix='_1') - df.to_csv(os.path.join(results_path, 'facade_results.csv')) + df = df.join(thermal_bus, lsuffix="_1") + df = df.join(electricity_bus, lsuffix="_1") + df.to_csv(os.path.join(results_path, "facade_results.csv")) # Example plot heat_calc = collector_inflow @@ -153,9 +157,8 @@ def flat_plate_collector_facade_example(): fig, ax = plt.subplots() ax.plot(t, heat_calc[:-1]) ax.set( - xlabel='time in h', - ylabel='Q_coll in W', - title='Heat of the collector') + xlabel="time in h", ylabel="Q_coll in W", title="Heat of the collector" + ) ax.grid() plt.show() diff --git a/examples/solar_thermal_collector/flat_plate_collector_investment.py b/examples/solar_thermal_collector/flat_plate_collector_investment.py index 7c35ac64..9bc0108f 100644 --- a/examples/solar_thermal_collector/flat_plate_collector_investment.py +++ b/examples/solar_thermal_collector/flat_plate_collector_investment.py @@ -18,11 +18,12 @@ from ._plots import plot_collector_heat + def flat_plate_collector_investment_example(): # Set paths base_path = os.path.dirname(os.path.abspath(os.path.join(__file__))) - data_path = os.path.join(base_path, 'data') - results_path = os.path.join(base_path, 'results') + data_path = os.path.join(base_path, "data") + results_path = os.path.join(base_path, "results") if not os.path.exists(results_path): os.mkdir(results_path) @@ -39,17 +40,18 @@ def flat_plate_collector_investment_example(): delta_temp_n = 10 # Read input data - input_data = pd.read_csv(os.path.join(data_path, 'data_flat_collector.csv')).head(periods) - input_data['Datum'] = pd.to_datetime(input_data['Datum']) - input_data.set_index('Datum', inplace=True) - input_data.index = input_data.index.tz_localize(tz='Europe/Berlin') - input_data = input_data.asfreq('H') + input_data = pd.read_csv( + os.path.join(data_path, "data_flat_collector.csv") + ).head(periods) + input_data["Datum"] = pd.to_datetime(input_data["Datum"]) + input_data.set_index("Datum", inplace=True) + input_data.index = input_data.index.tz_localize(tz="Europe/Berlin") + input_data = input_data.asfreq("H") demand_df = pd.read_csv( - os.path.join(data_path, 'heat_demand.csv'), - sep=',' + os.path.join(data_path, "heat_demand.csv"), sep="," ) - demand = list(demand_df['heat_demand'].iloc[:periods]) + demand = list(demand_df["heat_demand"].iloc[:periods]) # Precalculation # - calculate global irradiance on the collector area @@ -65,17 +67,15 @@ def flat_plate_collector_investment_example(): a_2, temp_collector_inlet, delta_temp_n, - irradiance_global=input_data['global_horizontal_W_m2'], - irradiance_diffuse=input_data['diffuse_horizontal_W_m2'], - temp_amb=input_data['temp_amb'], + irradiance_global=input_data["global_horizontal_W_m2"], + irradiance_diffuse=input_data["diffuse_horizontal_W_m2"], + temp_amb=input_data["temp_amb"], ) precalc_data.to_csv( - os.path.join(results_path, 'flate_plate_precalcs.csv'), - sep=';' + os.path.join(results_path, "flate_plate_precalcs.csv"), sep=";" ) - # Regular oemof system # Parameters for the energy system @@ -89,17 +89,17 @@ def flat_plate_collector_investment_example(): conversion_storage = 0.98 # Busses - bth = solph.Bus(label='thermal') - bel = solph.Bus(label='electricity') - bcol = solph.Bus(label='solar') + bth = solph.Bus(label="thermal") + bel = solph.Bus(label="electricity") + bcol = solph.Bus(label="solar") # Source for collector heat. # - actual_value is the precalculated collector heat - collector_heat = solph.components.Source( - label='collector_heat', + label="collector_heat", outputs={ bcol: solph.Flow( - fix=precalc_data['collectors_heat'], + fix=precalc_data["collectors_heat"], investment=solph.Investment(ep_costs=costs_collector), ) }, @@ -107,36 +107,37 @@ def flat_plate_collector_investment_example(): # Sources and sinks el_grid = solph.components.Source( - label='grid', outputs={bel: solph.Flow(variable_costs=costs_electricity)} + label="grid", + outputs={bel: solph.Flow(variable_costs=costs_electricity)}, ) backup = solph.components.Source( - label='backup', outputs={bth: solph.Flow(variable_costs=backup_costs)} + label="backup", outputs={bth: solph.Flow(variable_costs=backup_costs)} ) consumer = solph.components.Sink( - label='demand', + label="demand", inputs={bth: solph.Flow(fix=demand, nominal_value=1)}, ) collector_excess_heat = solph.components.Sink( - label='collector_excess_heat', inputs={bcol: solph.Flow()} + label="collector_excess_heat", inputs={bcol: solph.Flow()} ) # Transformer and storage collector = solph.components.Transformer( - label='collector', + label="collector", inputs={bcol: solph.Flow(), bel: solph.Flow()}, outputs={bth: solph.Flow()}, conversion_factors={ bcol: 1, bel: elec_consumption * (1 - peripheral_losses), - bth: 1 - peripheral_losses + bth: 1 - peripheral_losses, }, ) storage = solph.components.GenericStorage( - label='storage', + label="storage", inputs={bth: solph.Flow()}, outputs={bth: solph.Flow()}, loss_rate=storage_loss_rate, @@ -164,18 +165,23 @@ def flat_plate_collector_investment_example(): # Create and solve the optimization model model = solph.Model(energysystem) - model.solve(solver='cbc', solve_kwargs={'tee': True}) + model.solve(solver="cbc", solve_kwargs={"tee": True}) # Get results results = solph.processing.results(model) - electricity_bus = solph.views.node(results, 'electricity')['sequences'] - thermal_bus = solph.views.node(results, 'thermal')['sequences'] - solar_bus = solph.views.node(results, 'solar')['sequences'] + electricity_bus = solph.views.node(results, "electricity")["sequences"] + thermal_bus = solph.views.node(results, "thermal")["sequences"] + solar_bus = solph.views.node(results, "solar")["sequences"] df = pd.merge( - pd.merge(electricity_bus, thermal_bus, left_index=True, right_index=True), - solar_bus, left_index=True, right_index=True) - df.to_csv(os.path.join(results_path, 'flat_plate_results.csv')) + pd.merge( + electricity_bus, thermal_bus, left_index=True, right_index=True + ), + solar_bus, + left_index=True, + right_index=True, + ) + df.to_csv(os.path.join(results_path, "flat_plate_results.csv")) # Example plot plot_collector_heat(precalc_data, periods, eta_0) diff --git a/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py b/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py index e6f605f8..df5cb450 100644 --- a/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py +++ b/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py @@ -9,8 +9,7 @@ from oemof.thermal.stratified_thermal_storage import calculate_storage_u_value from oemof.thermal import facades -from oemof.solph import (processing, Bus, Flow, - Model, EnergySystem) +from oemof.solph import processing, Bus, Flow, Model, EnergySystem from oemof.solph.components import Source, Sink @@ -18,22 +17,24 @@ def fixed_ratio_invest_facade_example(): # Set paths data_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), - 'data/stratified_thermal_storage.csv') + "data/stratified_thermal_storage.csv", + ) # Read input data - input_data = pd.read_csv(data_path, index_col=0, header=0)['var_value'] + input_data = pd.read_csv(data_path, index_col=0, header=0)["var_value"] # Precalculation u_value = calculate_storage_u_value( - input_data['s_iso'], - input_data['lamb_iso'], - input_data['alpha_inside'], - input_data['alpha_outside']) + input_data["s_iso"], + input_data["lamb_iso"], + input_data["alpha_inside"], + input_data["alpha_outside"], + ) # Set up an energy system model - solver = 'cbc' + solver = "cbc" periods = 100 - datetimeindex = pd.date_range('1/1/2019', periods=periods, freq='H') + datetimeindex = pd.date_range("1/1/2019", periods=periods, freq="H") demand_timeseries = np.zeros(periods) demand_timeseries[-5:] = 1 heat_feedin_timeseries = np.zeros(periods) @@ -41,70 +42,86 @@ def fixed_ratio_invest_facade_example(): energysystem = EnergySystem(timeindex=datetimeindex) - bus_heat = Bus(label='bus_heat') + bus_heat = Bus(label="bus_heat") heat_source = Source( - label='heat_source', - outputs={bus_heat: Flow( - nominal_value=1, - fix=heat_feedin_timeseries)}) + label="heat_source", + outputs={bus_heat: Flow(nominal_value=1, fix=heat_feedin_timeseries)}, + ) shortage = Source( - label='shortage', - outputs={bus_heat: Flow(variable_costs=1e6)}) + label="shortage", outputs={bus_heat: Flow(variable_costs=1e6)} + ) - excess = Sink( - label='excess', - inputs={bus_heat: Flow()}) + excess = Sink(label="excess", inputs={bus_heat: Flow()}) heat_demand = Sink( - label='heat_demand', - inputs={bus_heat: Flow( - nominal_value=1, - fix=demand_timeseries)}) + label="heat_demand", + inputs={bus_heat: Flow(nominal_value=1, fix=demand_timeseries)}, + ) thermal_storage = facades.StratifiedThermalStorage( - label='thermal_storage', + label="thermal_storage", bus=bus_heat, - diameter=input_data['diameter'], # TODO: setting to zero should give an error - temp_h=input_data['temp_h'], - temp_c=input_data['temp_c'], - temp_env=input_data['temp_env'], + diameter=input_data[ + "diameter" + ], # TODO: setting to zero should give an error + temp_h=input_data["temp_h"], + temp_c=input_data["temp_c"], + temp_env=input_data["temp_env"], u_value=u_value, expandable=True, capacity_cost=0, storage_capacity_cost=400, minimum_storage_capacity=1, # TODO: setting to zero should give an error! invest_relation_input_capacity=1 / 6, - min_storage_level=input_data['min_storage_level'], - max_storage_level=input_data['max_storage_level'], - efficiency=input_data['efficiency'], - marginal_cost=0.0001 + min_storage_level=input_data["min_storage_level"], + max_storage_level=input_data["max_storage_level"], + efficiency=input_data["efficiency"], + marginal_cost=0.0001, ) - energysystem.add(bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage) + energysystem.add( + bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage + ) # Create and solve the optimization model optimization_model = Model(energysystem) - optimization_model.solve(solver=solver, - solve_kwargs={'tee': False, 'keepfiles': False}) + optimization_model.solve( + solver=solver, solve_kwargs={"tee": False, "keepfiles": False} + ) # Get results results = processing.results(optimization_model) string_results = processing.convert_keys_to_strings(results) - sequences = {k: v['sequences'] for k, v in string_results.items()} + sequences = {k: v["sequences"] for k, v in string_results.items()} df = pd.concat(sequences, axis=1) # Print storage sizing - built_storage_capacity = results[thermal_storage, None]['scalars']['invest'] - initial_storage_capacity = results[thermal_storage, None]['scalars']['init_content'] - maximum_heat_flow_charging = results[bus_heat, thermal_storage]['scalars']['invest'] - - dash = '-' * 50 + built_storage_capacity = results[thermal_storage, None]["scalars"][ + "invest" + ] + initial_storage_capacity = results[thermal_storage, None]["scalars"][ + "init_content" + ] + maximum_heat_flow_charging = results[bus_heat, thermal_storage]["scalars"][ + "invest" + ] + + dash = "-" * 50 print(dash) - print('{:>32s}{:>15.3f}'.format('Invested capacity [MW]', maximum_heat_flow_charging)) - print('{:>32s}{:>15.3f}'.format('Invested storage capacity [MWh]', built_storage_capacity)) + print( + "{:>32s}{:>15.3f}".format( + "Invested capacity [MW]", maximum_heat_flow_charging + ) + ) + print( + "{:>32s}{:>15.3f}".format( + "Invested storage capacity [MWh]", built_storage_capacity + ) + ) print(dash) + if __name__ == "__main__": fixed_ratio_invest_facade_example() diff --git a/examples/stratified_thermal_storage/investment_fixed_ratio_generic_storage.py b/examples/stratified_thermal_storage/investment_fixed_ratio_generic_storage.py index 3d0e37ad..756e7e79 100644 --- a/examples/stratified_thermal_storage/investment_fixed_ratio_generic_storage.py +++ b/examples/stratified_thermal_storage/investment_fixed_ratio_generic_storage.py @@ -9,10 +9,11 @@ import pandas as pd import numpy as np -from oemof.thermal.stratified_thermal_storage import (calculate_storage_u_value, - calculate_losses) -from oemof.solph import (Bus, Flow, - Investment, Model, EnergySystem) +from oemof.thermal.stratified_thermal_storage import ( + calculate_storage_u_value, + calculate_losses, +) +from oemof.solph import Bus, Flow, Investment, Model, EnergySystem from oemof.solph.components import GenericStorage, Source, Sink from oemof.solph import processing @@ -21,53 +22,54 @@ def fixed_ratio_invest_example(): # Set paths data_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), - 'data/stratified_thermal_storage.csv') + "data/stratified_thermal_storage.csv", + ) # Read input data - input_data = pd.read_csv(data_path, index_col=0, header=0)['var_value'] + input_data = pd.read_csv(data_path, index_col=0, header=0)["var_value"] # Precalculation u_value = calculate_storage_u_value( - input_data['s_iso'], - input_data['lamb_iso'], - input_data['alpha_inside'], - input_data['alpha_outside']) + input_data["s_iso"], + input_data["lamb_iso"], + input_data["alpha_inside"], + input_data["alpha_outside"], + ) loss_rate, fixed_losses_relative, fixed_losses_absolute = calculate_losses( u_value, - input_data['diameter'], - input_data['temp_h'], - input_data['temp_c'], - input_data['temp_env']) - + input_data["diameter"], + input_data["temp_h"], + input_data["temp_c"], + input_data["temp_env"], + ) def print_parameters(): parameter = { - 'EQ-cost [Eur/]': 0, - 'U-value [W/(m2*K)]': u_value, - 'Loss rate [-]': loss_rate, - 'Fixed relative losses [-]': fixed_losses_relative, - 'Fixed absolute losses [MWh]': fixed_losses_absolute, + "EQ-cost [Eur/]": 0, + "U-value [W/(m2*K)]": u_value, + "Loss rate [-]": loss_rate, + "Fixed relative losses [-]": fixed_losses_relative, + "Fixed absolute losses [MWh]": fixed_losses_absolute, } - dash = '-' * 50 + dash = "-" * 50 print(dash) - print('{:>32s}{:>15s}'.format('Parameter name', 'Value')) + print("{:>32s}{:>15s}".format("Parameter name", "Value")) print(dash) for name, param in parameter.items(): - print('{:>32s}{:>15.5f}'.format(name, param)) + print("{:>32s}{:>15.5f}".format(name, param)) print(dash) - print_parameters() # Set up an energy system model - solver = 'cbc' + solver = "cbc" periods = 100 - datetimeindex = pd.date_range('1/1/2019', periods=periods, freq='H') + datetimeindex = pd.date_range("1/1/2019", periods=periods, freq="H") demand_timeseries = np.zeros(periods) demand_timeseries[-5:] = 1 heat_feedin_timeseries = np.zeros(periods) @@ -75,69 +77,81 @@ def print_parameters(): energysystem = EnergySystem(timeindex=datetimeindex) - bus_heat = Bus(label='bus_heat') + bus_heat = Bus(label="bus_heat") heat_source = Source( - label='heat_source', - outputs={bus_heat: Flow( - nominal_value=1, - fix=heat_feedin_timeseries)}) + label="heat_source", + outputs={bus_heat: Flow(nominal_value=1, fix=heat_feedin_timeseries)}, + ) shortage = Source( - label='shortage', - outputs={bus_heat: Flow(variable_costs=1e6)}) + label="shortage", outputs={bus_heat: Flow(variable_costs=1e6)} + ) - excess = Sink( - label='excess', - inputs={bus_heat: Flow()}) + excess = Sink(label="excess", inputs={bus_heat: Flow()}) heat_demand = Sink( - label='heat_demand', - inputs={bus_heat: Flow( - nominal_value=1, - fix=demand_timeseries)}) + label="heat_demand", + inputs={bus_heat: Flow(nominal_value=1, fix=demand_timeseries)}, + ) thermal_storage = GenericStorage( - label='thermal_storage', - inputs={bus_heat: Flow( - investment=Investment())}, - outputs={bus_heat: Flow( - investment=Investment(), - variable_costs=0.0001)}, - min_storage_level=input_data['min_storage_level'], - max_storage_level=input_data['max_storage_level'], + label="thermal_storage", + inputs={bus_heat: Flow(investment=Investment())}, + outputs={ + bus_heat: Flow(investment=Investment(), variable_costs=0.0001) + }, + min_storage_level=input_data["min_storage_level"], + max_storage_level=input_data["max_storage_level"], loss_rate=loss_rate, fixed_losses_relative=fixed_losses_relative, fixed_losses_absolute=fixed_losses_absolute, - inflow_conversion_factor=input_data['inflow_conversion_factor'], - outflow_conversion_factor=input_data['outflow_conversion_factor'], + inflow_conversion_factor=input_data["inflow_conversion_factor"], + outflow_conversion_factor=input_data["outflow_conversion_factor"], invest_relation_input_output=1, invest_relation_input_capacity=1 / 6, - investment=Investment(ep_costs=400, minimum=1) + investment=Investment(ep_costs=400, minimum=1), ) - energysystem.add(bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage) + energysystem.add( + bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage + ) # Create and solve the optimization model optimization_model = Model(energysystem) - optimization_model.solve(solver=solver, - solve_kwargs={'tee': False, 'keepfiles': False}) + optimization_model.solve( + solver=solver, solve_kwargs={"tee": False, "keepfiles": False} + ) # Get results results = processing.results(optimization_model) string_results = processing.convert_keys_to_strings(results) - sequences = {k: v['sequences'] for k, v in string_results.items()} + sequences = {k: v["sequences"] for k, v in string_results.items()} df = pd.concat(sequences, axis=1) # Print storage sizing - built_storage_capacity = results[thermal_storage, None]['scalars']['invest'] - initial_storage_capacity = results[thermal_storage, None]['scalars']['init_content'] - maximum_heat_flow_charging = results[bus_heat, thermal_storage]['scalars']['invest'] - - dash = '-' * 50 + built_storage_capacity = results[thermal_storage, None]["scalars"][ + "invest" + ] + initial_storage_capacity = results[thermal_storage, None]["scalars"][ + "init_content" + ] + maximum_heat_flow_charging = results[bus_heat, thermal_storage]["scalars"][ + "invest" + ] + + dash = "-" * 50 print(dash) - print('{:>32s}{:>15.3f}'.format('Invested capacity [MW]', maximum_heat_flow_charging)) - print('{:>32s}{:>15.3f}'.format('Invested storage capacity [MWh]', built_storage_capacity)) + print( + "{:>32s}{:>15.3f}".format( + "Invested capacity [MW]", maximum_heat_flow_charging + ) + ) + print( + "{:>32s}{:>15.3f}".format( + "Invested storage capacity [MWh]", built_storage_capacity + ) + ) print(dash) diff --git a/examples/stratified_thermal_storage/investment_independent_facade.py b/examples/stratified_thermal_storage/investment_independent_facade.py index fd6df21e..c879a765 100644 --- a/examples/stratified_thermal_storage/investment_independent_facade.py +++ b/examples/stratified_thermal_storage/investment_independent_facade.py @@ -12,8 +12,7 @@ from oemof.thermal.stratified_thermal_storage import calculate_storage_u_value from oemof.thermal import facades -from oemof.solph import (processing, Bus, Flow, - Model, EnergySystem) +from oemof.solph import processing, Bus, Flow, Model, EnergySystem from oemof.solph.components import Source, Sink @@ -21,22 +20,24 @@ def invest_independent_facade_example(): # Set paths data_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), - 'data/stratified_thermal_storage.csv') + "data/stratified_thermal_storage.csv", + ) # Read input data - input_data = pd.read_csv(data_path, index_col=0, header=0)['var_value'] + input_data = pd.read_csv(data_path, index_col=0, header=0)["var_value"] # Precalculation u_value = calculate_storage_u_value( - input_data['s_iso'], - input_data['lamb_iso'], - input_data['alpha_inside'], - input_data['alpha_outside']) + input_data["s_iso"], + input_data["lamb_iso"], + input_data["alpha_inside"], + input_data["alpha_outside"], + ) # Set up an energy system model - solver = 'cbc' + solver = "cbc" periods = 100 - datetimeindex = pd.date_range('1/1/2019', periods=periods, freq='H') + datetimeindex = pd.date_range("1/1/2019", periods=periods, freq="H") demand_timeseries = np.zeros(periods) demand_timeseries[-5:] = 1 heat_feedin_timeseries = np.zeros(periods) @@ -44,68 +45,77 @@ def invest_independent_facade_example(): energysystem = EnergySystem(timeindex=datetimeindex) - bus_heat = Bus(label='bus_heat') + bus_heat = Bus(label="bus_heat") heat_source = Source( - label='heat_source', - outputs={bus_heat: Flow( - nominal_value=1, - fix=heat_feedin_timeseries)}) + label="heat_source", + outputs={bus_heat: Flow(nominal_value=1, fix=heat_feedin_timeseries)}, + ) shortage = Source( - label='shortage', - outputs={bus_heat: Flow(variable_costs=1e6)}) + label="shortage", outputs={bus_heat: Flow(variable_costs=1e6)} + ) - excess = Sink( - label='excess', - inputs={bus_heat: Flow()}) + excess = Sink(label="excess", inputs={bus_heat: Flow()}) heat_demand = Sink( - label='heat_demand', - inputs={bus_heat: Flow( - nominal_value=1, - fix=demand_timeseries)}) + label="heat_demand", + inputs={bus_heat: Flow(nominal_value=1, fix=demand_timeseries)}, + ) thermal_storage = facades.StratifiedThermalStorage( - label='thermal_storage', + label="thermal_storage", bus=bus_heat, - diameter=input_data['diameter'], # TODO: setting to zero should give an error - temp_h=input_data['temp_h'], - temp_c=input_data['temp_c'], - temp_env=input_data['temp_env'], + diameter=input_data[ + "diameter" + ], # TODO: setting to zero should give an error + temp_h=input_data["temp_h"], + temp_c=input_data["temp_c"], + temp_env=input_data["temp_env"], u_value=u_value, expandable=True, capacity_cost=50, storage_capacity_cost=400, minimum_storage_capacity=1, # TODO: setting to zero should give an error! - min_storage_level=input_data['min_storage_level'], - max_storage_level=input_data['max_storage_level'], - efficiency=input_data['efficiency'], - marginal_cost=0.0001 + min_storage_level=input_data["min_storage_level"], + max_storage_level=input_data["max_storage_level"], + efficiency=input_data["efficiency"], + marginal_cost=0.0001, ) - energysystem.add(bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage) + energysystem.add( + bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage + ) # Create and solve the optimization model optimization_model = Model(energysystem) - optimization_model.solve(solver=solver, - solve_kwargs={'tee': False, 'keepfiles': False}) + optimization_model.solve( + solver=solver, solve_kwargs={"tee": False, "keepfiles": False} + ) # Get results results = processing.results(optimization_model) string_results = processing.convert_keys_to_strings(results) - sequences = {k: v['sequences'] for k, v in string_results.items()} + sequences = {k: v["sequences"] for k, v in string_results.items()} df = pd.concat(sequences, axis=1) # Print storage sizing - built_storage_capacity = results[thermal_storage, None]['scalars']['invest'] - initial_storage_capacity = results[thermal_storage, None]['scalars']['init_content'] - built_capacity = results[bus_heat, thermal_storage]['scalars']['invest'] - - dash = '-' * 50 + built_storage_capacity = results[thermal_storage, None]["scalars"][ + "invest" + ] + initial_storage_capacity = results[thermal_storage, None]["scalars"][ + "init_content" + ] + built_capacity = results[bus_heat, thermal_storage]["scalars"]["invest"] + + dash = "-" * 50 print(dash) - print('{:>32s}{:>15.3f}'.format('Invested capacity [MW]', built_capacity)) - print('{:>32s}{:>15.3f}'.format('Invested storage capacity [MWh]', built_storage_capacity)) + print("{:>32s}{:>15.3f}".format("Invested capacity [MW]", built_capacity)) + print( + "{:>32s}{:>15.3f}".format( + "Invested storage capacity [MWh]", built_storage_capacity + ) + ) print(dash) diff --git a/examples/stratified_thermal_storage/investment_independent_generic_storage.py b/examples/stratified_thermal_storage/investment_independent_generic_storage.py index 92e36454..2cad95fd 100644 --- a/examples/stratified_thermal_storage/investment_independent_generic_storage.py +++ b/examples/stratified_thermal_storage/investment_independent_generic_storage.py @@ -10,10 +10,11 @@ import pandas as pd import numpy as np -from oemof.thermal.stratified_thermal_storage import (calculate_storage_u_value, - calculate_losses) -from oemof.solph import (processing, Bus, Flow, - Investment, Model, EnergySystem) +from oemof.thermal.stratified_thermal_storage import ( + calculate_storage_u_value, + calculate_losses, +) +from oemof.solph import processing, Bus, Flow, Investment, Model, EnergySystem from oemof.solph.components import GenericStorage, Source, Sink @@ -21,53 +22,54 @@ def invest_independent_example(): # Set paths data_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), - 'data/stratified_thermal_storage.csv') + "data/stratified_thermal_storage.csv", + ) # Read input data - input_data = pd.read_csv(data_path, index_col=0, header=0)['var_value'] + input_data = pd.read_csv(data_path, index_col=0, header=0)["var_value"] # Precalculation u_value = calculate_storage_u_value( - input_data['s_iso'], - input_data['lamb_iso'], - input_data['alpha_inside'], - input_data['alpha_outside']) + input_data["s_iso"], + input_data["lamb_iso"], + input_data["alpha_inside"], + input_data["alpha_outside"], + ) loss_rate, fixed_losses_relative, fixed_losses_absolute = calculate_losses( u_value, - input_data['diameter'], - input_data['temp_h'], - input_data['temp_c'], - input_data['temp_env']) - + input_data["diameter"], + input_data["temp_h"], + input_data["temp_c"], + input_data["temp_env"], + ) def print_parameters(): parameter = { - 'EQ-cost [Eur/]': 0, - 'U-value [W/(m2*K)]': u_value, - 'Loss rate [-]': loss_rate, - 'Fixed relative losses [-]': fixed_losses_relative, - 'Fixed absolute losses [MWh]': fixed_losses_absolute, + "EQ-cost [Eur/]": 0, + "U-value [W/(m2*K)]": u_value, + "Loss rate [-]": loss_rate, + "Fixed relative losses [-]": fixed_losses_relative, + "Fixed absolute losses [MWh]": fixed_losses_absolute, } - dash = '-' * 50 + dash = "-" * 50 print(dash) - print('{:>32s}{:>15s}'.format('Parameter name', 'Value')) + print("{:>32s}{:>15s}".format("Parameter name", "Value")) print(dash) for name, param in parameter.items(): - print('{:>32s}{:>15.5f}'.format(name, param)) + print("{:>32s}{:>15.5f}".format(name, param)) print(dash) - print_parameters() # Set up an energy system model - solver = 'cbc' + solver = "cbc" periods = 100 - datetimeindex = pd.date_range('1/1/2019', periods=periods, freq='H') + datetimeindex = pd.date_range("1/1/2019", periods=periods, freq="H") demand_timeseries = np.zeros(periods) demand_timeseries[-5:] = 1 heat_feedin_timeseries = np.zeros(periods) @@ -75,69 +77,82 @@ def print_parameters(): energysystem = EnergySystem(timeindex=datetimeindex) - bus_heat = Bus(label='bus_heat') + bus_heat = Bus(label="bus_heat") heat_source = Source( - label='heat_source', - outputs={bus_heat: Flow( - nominal_value=1, - fix=heat_feedin_timeseries)}) + label="heat_source", + outputs={bus_heat: Flow(nominal_value=1, fix=heat_feedin_timeseries)}, + ) shortage = Source( - label='shortage', - outputs={bus_heat: Flow(variable_costs=1e6)}) + label="shortage", outputs={bus_heat: Flow(variable_costs=1e6)} + ) - excess = Sink( - label='excess', - inputs={bus_heat: Flow()}) + excess = Sink(label="excess", inputs={bus_heat: Flow()}) heat_demand = Sink( - label='heat_demand', - inputs={bus_heat: Flow( - nominal_value=1, - fix=demand_timeseries)}) + label="heat_demand", + inputs={bus_heat: Flow(nominal_value=1, fix=demand_timeseries)}, + ) thermal_storage = GenericStorage( - label='thermal_storage', - inputs={bus_heat: Flow( - investment=Investment(ep_costs=50))}, - outputs={bus_heat: Flow( - investment=Investment(), - variable_costs=0.0001)}, - min_storage_level=input_data['min_storage_level'], - max_storage_level=input_data['max_storage_level'], + label="thermal_storage", + inputs={bus_heat: Flow(investment=Investment(ep_costs=50))}, + outputs={ + bus_heat: Flow(investment=Investment(), variable_costs=0.0001) + }, + min_storage_level=input_data["min_storage_level"], + max_storage_level=input_data["max_storage_level"], loss_rate=loss_rate, fixed_losses_relative=fixed_losses_relative, fixed_losses_absolute=fixed_losses_absolute, - inflow_conversion_factor=input_data['inflow_conversion_factor'], - outflow_conversion_factor=input_data['outflow_conversion_factor'], + inflow_conversion_factor=input_data["inflow_conversion_factor"], + outflow_conversion_factor=input_data["outflow_conversion_factor"], invest_relation_input_output=1, - investment=Investment(ep_costs=400, minimum=1) + investment=Investment(ep_costs=400, minimum=1), ) - energysystem.add(bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage) + energysystem.add( + bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage + ) # Create and solve the optimization model optimization_model = Model(energysystem) - optimization_model.solve(solver=solver, - solve_kwargs={'tee': False, 'keepfiles': False}) + optimization_model.solve( + solver=solver, solve_kwargs={"tee": False, "keepfiles": False} + ) # Get results results = processing.results(optimization_model) string_results = processing.convert_keys_to_strings(results) - sequences = {k: v['sequences'] for k, v in string_results.items()} + sequences = {k: v["sequences"] for k, v in string_results.items()} df = pd.concat(sequences, axis=1) # Print storage sizing - built_storage_capacity = results[thermal_storage, None]['scalars']['invest'] - initial_storage_capacity = results[thermal_storage, None]['scalars']['init_content'] - maximum_heat_flow_charging = results[bus_heat, thermal_storage]['scalars']['invest'] - - dash = '-' * 50 + built_storage_capacity = results[thermal_storage, None]["scalars"][ + "invest" + ] + initial_storage_capacity = results[thermal_storage, None]["scalars"][ + "init_content" + ] + maximum_heat_flow_charging = results[bus_heat, thermal_storage]["scalars"][ + "invest" + ] + + dash = "-" * 50 print(dash) - print('{:>32s}{:>15.3f}'.format('Invested capacity [MW]', maximum_heat_flow_charging)) - print('{:>32s}{:>15.3f}'.format('Invested storage capacity [MWh]', built_storage_capacity)) + print( + "{:>32s}{:>15.3f}".format( + "Invested capacity [MW]", maximum_heat_flow_charging + ) + ) + print( + "{:>32s}{:>15.3f}".format( + "Invested storage capacity [MWh]", built_storage_capacity + ) + ) print(dash) + if __name__ == "__main__": invest_independent_example() diff --git a/examples/stratified_thermal_storage/model_validation.py b/examples/stratified_thermal_storage/model_validation.py index 5cac21e3..a6d4d4d7 100644 --- a/examples/stratified_thermal_storage/model_validation.py +++ b/examples/stratified_thermal_storage/model_validation.py @@ -6,7 +6,7 @@ from oemof.thermal.stratified_thermal_storage import ( # noqa calculate_storage_u_value, calculate_storage_dimensions, - calculate_capacities + calculate_capacities, ) from oemof.thermal import facades @@ -21,72 +21,73 @@ EnergySystem, ) + def model_validation(): data_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), - './data/validation_data.csv') - - input_data = pd.read_csv(data_path, index_col=0, header=0)['var_value'] + "./data/validation_data.csv", + ) + input_data = pd.read_csv(data_path, index_col=0, header=0)["var_value"] def run_storage_model(initial_storage_level, temp_h, temp_c): data_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), - './data/validation_data.csv') + "./data/validation_data.csv", + ) - input_data = pd.read_csv(data_path, index_col=0, header=0)['var_value'] + input_data = pd.read_csv(data_path, index_col=0, header=0)["var_value"] u_value = calculate_storage_u_value( - input_data['s_iso'], - input_data['lamb_iso'], - input_data['alpha_inside'], - input_data['alpha_outside']) + input_data["s_iso"], + input_data["lamb_iso"], + input_data["alpha_inside"], + input_data["alpha_outside"], + ) # Set up an energy system model periods = 10 - datetimeindex = pd.date_range('1/1/2019', periods=periods, freq='H') + datetimeindex = pd.date_range("1/1/2019", periods=periods, freq="H") demand_timeseries = np.zeros(periods) heat_feedin_timeseries = np.zeros(periods) energysystem = EnergySystem(timeindex=datetimeindex) - bus_heat = Bus(label='bus_heat') + bus_heat = Bus(label="bus_heat") heat_source = Source( - label='heat_source', - outputs={bus_heat: Flow( - nominal_value=1, - fix=heat_feedin_timeseries)}) + label="heat_source", + outputs={ + bus_heat: Flow(nominal_value=1, fix=heat_feedin_timeseries) + }, + ) shortage = Source( - label='shortage', - outputs={bus_heat: Flow(variable_costs=1e6)}) + label="shortage", outputs={bus_heat: Flow(variable_costs=1e6)} + ) - excess = Sink( - label='excess', - inputs={bus_heat: Flow()}) + excess = Sink(label="excess", inputs={bus_heat: Flow()}) heat_demand = Sink( - label='heat_demand', - inputs={bus_heat: Flow( - nominal_value=1, - fix=demand_timeseries)}) + label="heat_demand", + inputs={bus_heat: Flow(nominal_value=1, fix=demand_timeseries)}, + ) thermal_storage = facades.StratifiedThermalStorage( - label='thermal_storage', + label="thermal_storage", bus=bus_heat, - diameter=input_data['diameter'], - height=input_data['height'], + diameter=input_data["diameter"], + height=input_data["height"], temp_h=temp_h, temp_c=temp_c, - temp_env=input_data['temp_env'], + temp_env=input_data["temp_env"], u_value=u_value, # W/(m2*K) - min_storage_level=input_data['min_storage_level'], - max_storage_level=input_data['max_storage_level'], + min_storage_level=input_data["min_storage_level"], + max_storage_level=input_data["max_storage_level"], initial_storage_level=initial_storage_level, - capacity=input_data['maximum_heat_flow_charging'], + capacity=input_data["maximum_heat_flow_charging"], efficiency=1, - marginal_cost=0.0001 + marginal_cost=0.0001, ) energysystem.add( @@ -95,77 +96,86 @@ def run_storage_model(initial_storage_level, temp_h, temp_c): shortage, excess, heat_demand, - thermal_storage) + thermal_storage, + ) # create and solve the optimization model optimization_model = Model(energysystem) - optimization_model.write('storage_model_facades.lp', - io_options={'symbolic_solver_labels': True}) - optimization_model.solve(solver='cbc', solve_kwargs={'tee': False}) + optimization_model.write( + "storage_model_facades.lp", + io_options={"symbolic_solver_labels": True}, + ) + optimization_model.solve(solver="cbc", solve_kwargs={"tee": False}) - energysystem.results['main'] = solph.processing.results(optimization_model) - string_results = solph.views.convert_keys_to_strings(energysystem.results['main']) + energysystem.results["main"] = solph.processing.results( + optimization_model + ) + string_results = solph.views.convert_keys_to_strings( + energysystem.results["main"] + ) # Get time series of level (state of charge) of the thermal energy storage - TES_soc = (string_results['thermal_storage', 'None']['sequences']) + TES_soc = string_results["thermal_storage", "None"]["sequences"] # Save results to csv file TES_soc.to_csv("./data/storage_soc_calculated.csv") return + initial_storage_level = input_data["initial_storage_level"] - initial_storage_level = input_data['initial_storage_level'] - - run_storage_model(initial_storage_level=input_data['initial_storage_level'], - temp_h=input_data['temp_h'], - temp_c=input_data['temp_c']) + run_storage_model( + initial_storage_level=input_data["initial_storage_level"], + temp_h=input_data["temp_h"], + temp_c=input_data["temp_c"], + ) volume, surface = calculate_storage_dimensions( - input_data['height'], - input_data['diameter']) + input_data["height"], input_data["diameter"] + ) # Max capacity in MWh nominal_storage_capacity = calculate_capacities( - volume, - input_data['temp_h'], - input_data['temp_c']) + volume, input_data["temp_h"], input_data["temp_c"] + ) # Get measurement data - filename = './data/storage_soc_measured.csv' + filename = "./data/storage_soc_measured.csv" level_meas = pd.read_csv(filename, header=0) # Get simulation results (hourly values) - filename = './data/storage_soc_calculated.csv' + filename = "./data/storage_soc_calculated.csv" TES_soc_df = pd.read_csv(filename, header=0) # Convert to list - TES_soc_hourly = TES_soc_df['storage_content'].values + TES_soc_hourly = TES_soc_df["storage_content"].values # Convert simulation data to relative values in % - TES_soc_relative = [soc / nominal_storage_capacity * 100 for soc in - TES_soc_hourly] + TES_soc_relative = [ + soc / nominal_storage_capacity * 100 for soc in TES_soc_hourly + ] end_step = 7 # Make list with time steps for x-axes in plot t_meas = np.arange(0, (len(level_meas) / 4), 0.25) - plt.style.use('ggplot') + plt.style.use("ggplot") fig, ax = plt.subplots() # Plot horizontal line (initial level) - init_level = level_meas['level'][0] - plt.plot([init_level] * end_step, '--', color='gray') + init_level = level_meas["level"][0] + plt.plot([init_level] * end_step, "--", color="gray") # Plot simulation data TES_soc_relative_list = [initial_storage_level * 100] [TES_soc_relative_list.append(TES_soc_relative[i]) for i in range(10)] - plt.plot(TES_soc_relative_list[:end_step], - label="storage level (simulation)") + plt.plot( + TES_soc_relative_list[:end_step], label="storage level (simulation)" + ) # Plot measurement data - plt.plot(t_meas, level_meas['level'], label="storage level (measurement)") + plt.plot(t_meas, level_meas["level"], label="storage level (measurement)") plt.legend() ax.set_xlabel("Time in h") diff --git a/examples/stratified_thermal_storage/operation_facade.py b/examples/stratified_thermal_storage/operation_facade.py index 9faff86a..62b686a0 100644 --- a/examples/stratified_thermal_storage/operation_facade.py +++ b/examples/stratified_thermal_storage/operation_facade.py @@ -14,46 +14,48 @@ calculate_storage_u_value, ) + def operation_facade_example(): # Set paths data_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), - 'data', 'stratified_thermal_storage.csv') + "data", + "stratified_thermal_storage.csv", + ) # Read input data - input_data = pd.read_csv(data_path, index_col=0, header=0)['var_value'] + input_data = pd.read_csv(data_path, index_col=0, header=0)["var_value"] # Precalculation u_value = calculate_storage_u_value( - input_data['s_iso'], - input_data['lamb_iso'], - input_data['alpha_inside'], - input_data['alpha_outside']) - + input_data["s_iso"], + input_data["lamb_iso"], + input_data["alpha_inside"], + input_data["alpha_outside"], + ) def print_parameters(): parameter = { - 'U-value [W/(m2*K)]': u_value, + "U-value [W/(m2*K)]": u_value, } - dash = '-' * 50 + dash = "-" * 50 print(dash) - print('{:>32s}{:>15s}'.format('Parameter name', 'Value')) + print("{:>32s}{:>15s}".format("Parameter name", "Value")) print(dash) for name, param in parameter.items(): - print('{:>32s}{:>15.5f}'.format(name, param)) + print("{:>32s}{:>15.5f}".format(name, param)) print(dash) - print_parameters() # Set up an energy system model - solver = 'cbc' + solver = "cbc" periods = 100 - datetimeindex = pd.date_range('1/1/2019', periods=periods, freq='H') + datetimeindex = pd.date_range("1/1/2019", periods=periods, freq="H") demand_timeseries = np.zeros(periods) demand_timeseries[-5:] = 1 heat_feedin_timeseries = np.zeros(periods) @@ -61,45 +63,43 @@ def print_parameters(): energysystem = EnergySystem(timeindex=datetimeindex) - bus_heat = Bus(label='bus_heat') + bus_heat = Bus(label="bus_heat") heat_source = Source( - label='heat_source', - outputs={bus_heat: Flow( - nominal_value=1, - fix=heat_feedin_timeseries)}) + label="heat_source", + outputs={bus_heat: Flow(nominal_value=1, fix=heat_feedin_timeseries)}, + ) shortage = Source( - label='shortage', - outputs={bus_heat: Flow(variable_costs=1e6)}) + label="shortage", outputs={bus_heat: Flow(variable_costs=1e6)} + ) - excess = Sink( - label='excess', - inputs={bus_heat: Flow()}) + excess = Sink(label="excess", inputs={bus_heat: Flow()}) heat_demand = Sink( - label='heat_demand', - inputs={bus_heat: Flow( - nominal_value=1, - fix=demand_timeseries)}) + label="heat_demand", + inputs={bus_heat: Flow(nominal_value=1, fix=demand_timeseries)}, + ) thermal_storage = facades.StratifiedThermalStorage( - label='thermal_storage', + label="thermal_storage", bus=bus_heat, - diameter=input_data['diameter'], - height=input_data['height'], - temp_h=input_data['temp_h'], - temp_c=input_data['temp_c'], - temp_env=input_data['temp_env'], + diameter=input_data["diameter"], + height=input_data["height"], + temp_h=input_data["temp_h"], + temp_c=input_data["temp_c"], + temp_env=input_data["temp_env"], u_value=u_value, - min_storage_level=input_data['min_storage_level'], - max_storage_level=input_data['max_storage_level'], - capacity=input_data['maximum_heat_flow_charging'], - efficiency=input_data['efficiency'], - marginal_cost=0.0001 + min_storage_level=input_data["min_storage_level"], + max_storage_level=input_data["max_storage_level"], + capacity=input_data["maximum_heat_flow_charging"], + efficiency=input_data["efficiency"], + marginal_cost=0.0001, ) - energysystem.add(bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage) + energysystem.add( + bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage + ) # Create and solve the optimization model optimization_model = Model(energysystem) diff --git a/examples/stratified_thermal_storage/operation_generic_storage.py b/examples/stratified_thermal_storage/operation_generic_storage.py index fdebecc6..090d5331 100644 --- a/examples/stratified_thermal_storage/operation_generic_storage.py +++ b/examples/stratified_thermal_storage/operation_generic_storage.py @@ -17,69 +17,70 @@ from oemof.solph import processing, Bus, Flow, Model, EnergySystem from oemof.solph.components import GenericStorage, Source, Sink + def operation_example(): # Set paths data_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), - 'data', 'stratified_thermal_storage.csv') + "data", + "stratified_thermal_storage.csv", + ) # Read input data - input_data = pd.read_csv(data_path, index_col=0, header=0)['var_value'] + input_data = pd.read_csv(data_path, index_col=0, header=0)["var_value"] # Precalculation u_value = calculate_storage_u_value( - input_data['s_iso'], - input_data['lamb_iso'], - input_data['alpha_inside'], - input_data['alpha_outside']) + input_data["s_iso"], + input_data["lamb_iso"], + input_data["alpha_inside"], + input_data["alpha_outside"], + ) volume, surface = calculate_storage_dimensions( - input_data['height'], - input_data['diameter'] + input_data["height"], input_data["diameter"] ) nominal_storage_capacity = calculate_capacities( - volume, - input_data['temp_h'], - input_data['temp_c']) + volume, input_data["temp_h"], input_data["temp_c"] + ) loss_rate, fixed_losses_relative, fixed_losses_absolute = calculate_losses( u_value, - input_data['diameter'], - input_data['temp_h'], - input_data['temp_c'], - input_data['temp_env']) - + input_data["diameter"], + input_data["temp_h"], + input_data["temp_c"], + input_data["temp_env"], + ) def print_parameters(): parameter = { - 'U-value [W/(m2*K)]': u_value, - 'Volume [m3]': volume, - 'Surface [m2]': surface, - 'Nominal storage capacity [MWh]': nominal_storage_capacity, - 'Loss rate [-]': loss_rate, - 'Fixed relative losses [-]': fixed_losses_relative, - 'Fixed absolute losses [MWh]': fixed_losses_absolute, + "U-value [W/(m2*K)]": u_value, + "Volume [m3]": volume, + "Surface [m2]": surface, + "Nominal storage capacity [MWh]": nominal_storage_capacity, + "Loss rate [-]": loss_rate, + "Fixed relative losses [-]": fixed_losses_relative, + "Fixed absolute losses [MWh]": fixed_losses_absolute, } - dash = '-' * 50 + dash = "-" * 50 print(dash) - print('{:>32s}{:>15s}'.format('Parameter name', 'Value')) + print("{:>32s}{:>15s}".format("Parameter name", "Value")) print(dash) for name, param in parameter.items(): - print('{:>32s}{:>15.5f}'.format(name, param)) + print("{:>32s}{:>15.5f}".format(name, param)) print(dash) - print_parameters() # Set up an energy system model - solver = 'cbc' + solver = "cbc" periods = 100 - datetimeindex = pd.date_range('1/1/2019', periods=periods, freq='H') + datetimeindex = pd.date_range("1/1/2019", periods=periods, freq="H") demand_timeseries = np.zeros(periods) demand_timeseries[-5:] = 1 heat_feedin_timeseries = np.zeros(periods) @@ -87,81 +88,94 @@ def print_parameters(): energysystem = EnergySystem(timeindex=datetimeindex) - bus_heat = Bus(label='bus_heat') + bus_heat = Bus(label="bus_heat") heat_source = Source( - label='heat_source', - outputs={bus_heat: Flow( - nominal_value=1, - fix=heat_feedin_timeseries)}) + label="heat_source", + outputs={bus_heat: Flow(nominal_value=1, fix=heat_feedin_timeseries)}, + ) shortage = Source( - label='shortage', - outputs={bus_heat: Flow(variable_costs=1e6)}) + label="shortage", outputs={bus_heat: Flow(variable_costs=1e6)} + ) - excess = Sink( - label='excess', - inputs={bus_heat: Flow()}) + excess = Sink(label="excess", inputs={bus_heat: Flow()}) heat_demand = Sink( - label='heat_demand', - inputs={bus_heat: Flow( - nominal_value=1, - fix=demand_timeseries)}) + label="heat_demand", + inputs={bus_heat: Flow(nominal_value=1, fix=demand_timeseries)}, + ) thermal_storage = GenericStorage( - label='thermal_storage', - inputs={bus_heat: Flow( - nominal_value=input_data['maximum_heat_flow_charging'])}, - outputs={bus_heat: Flow( - nominal_value=input_data['maximum_heat_flow_discharging'], - variable_costs=0.0001 - )}, + label="thermal_storage", + inputs={ + bus_heat: Flow( + nominal_value=input_data["maximum_heat_flow_charging"] + ) + }, + outputs={ + bus_heat: Flow( + nominal_value=input_data["maximum_heat_flow_discharging"], + variable_costs=0.0001, + ) + }, nominal_storage_capacity=nominal_storage_capacity, - min_storage_level=input_data['min_storage_level'], - max_storage_level=input_data['max_storage_level'], + min_storage_level=input_data["min_storage_level"], + max_storage_level=input_data["max_storage_level"], loss_rate=loss_rate, fixed_losses_relative=fixed_losses_relative, fixed_losses_absolute=fixed_losses_absolute, - inflow_conversion_factor=input_data['inflow_conversion_factor'], - outflow_conversion_factor=input_data['outflow_conversion_factor'], + inflow_conversion_factor=input_data["inflow_conversion_factor"], + outflow_conversion_factor=input_data["outflow_conversion_factor"], ) - energysystem.add(bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage) + energysystem.add( + bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage + ) # Create and solve the optimization model optimization_model = Model(energysystem) - optimization_model.solve(solver=solver, - solve_kwargs={'tee': False, 'keepfiles': False}) + optimization_model.solve( + solver=solver, solve_kwargs={"tee": False, "keepfiles": False} + ) # Get results results = processing.results(optimization_model) string_results = processing.convert_keys_to_strings(results) - sequences = {k: v['sequences'] for k, v in string_results.items()} + sequences = {k: v["sequences"] for k, v in string_results.items()} df = pd.concat(sequences, axis=1) # Example plot fig, (ax1, ax2) = plt.subplots(2, 1) - df[[('shortage', 'bus_heat', 'flow'), - ('heat_source', 'bus_heat', 'flow'), - ('thermal_storage', 'bus_heat', 'flow')]].plot.area(ax=ax1, stacked=True, color=['y', 'b', 'k']) + df[ + [ + ("shortage", "bus_heat", "flow"), + ("heat_source", "bus_heat", "flow"), + ("thermal_storage", "bus_heat", "flow"), + ] + ].plot.area(ax=ax1, stacked=True, color=["y", "b", "k"]) - (-df[('bus_heat', 'thermal_storage', 'flow')]).plot.area(ax=ax1, color='g', ylim=(-2, 2)) + (-df[("bus_heat", "thermal_storage", "flow")]).plot.area( + ax=ax1, color="g", ylim=(-2, 2) + ) - df[('bus_heat', 'heat_demand', 'flow')].plot(ax=ax1, linestyle='-', marker='o', color='r') + df[("bus_heat", "heat_demand", "flow")].plot( + ax=ax1, linestyle="-", marker="o", color="r" + ) - df[('thermal_storage', 'None', 'storage_content')].plot.area(ax=ax2) + df[("thermal_storage", "None", "storage_content")].plot.area(ax=ax2) - ax1.set_title('Heat flow to and from heat bus') + ax1.set_title("Heat flow to and from heat bus") ax1.set_ylim(-2, 2) - ax1.legend(loc='center left', bbox_to_anchor=(1.0, 0.5)) + ax1.legend(loc="center left", bbox_to_anchor=(1.0, 0.5)) - ax2.set_title('Storage content') - ax2.set_xlabel('Timesteps') - ax2.legend(loc='center left', bbox_to_anchor=(1.0, 0.5)) + ax2.set_title("Storage content") + ax2.set_xlabel("Timesteps") + ax2.legend(loc="center left", bbox_to_anchor=(1.0, 0.5)) plt.tight_layout() plt.show() + if __name__ == "__main__": operation_example() diff --git a/examples/stratified_thermal_storage/plots.py b/examples/stratified_thermal_storage/plots.py index 8c6c31c2..9d3b1934 100644 --- a/examples/stratified_thermal_storage/plots.py +++ b/examples/stratified_thermal_storage/plots.py @@ -19,121 +19,139 @@ from oemof.solph import processing, views, Bus, Flow, Model, EnergySystem from oemof.solph.components import GenericStorage + def plots(): # Set paths data_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), - 'data', 'stratified_thermal_storage.csv') + "data", + "stratified_thermal_storage.csv", + ) - input_data = pd.read_csv(data_path, index_col=0, header=0)['var_value'] + input_data = pd.read_csv(data_path, index_col=0, header=0)["var_value"] u_value = calculate_storage_u_value( - input_data['s_iso'], - input_data['lamb_iso'], - input_data['alpha_inside'], - input_data['alpha_outside'] + input_data["s_iso"], + input_data["lamb_iso"], + input_data["alpha_inside"], + input_data["alpha_outside"], ) volume, surface = calculate_storage_dimensions( - input_data['height'], - input_data['diameter'] + input_data["height"], input_data["diameter"] ) nominal_storage_capacity = calculate_capacities( - volume, - input_data['temp_h'], - input_data['temp_c'] + volume, input_data["temp_h"], input_data["temp_c"] ) loss_rate, fixed_losses_relative, fixed_losses_absolute = calculate_losses( u_value, - input_data['diameter'], - input_data['temp_h'], - input_data['temp_c'], - input_data['temp_env'], + input_data["diameter"], + input_data["temp_h"], + input_data["temp_c"], + input_data["temp_env"], ) - def print_results(): parameter = { - 'U-value [W/(m2*K)]': u_value, - 'Volume [m3]': volume, - 'Surface [m2]': surface, - 'Nominal storage capacity [MWh]': nominal_storage_capacity, - 'Loss rate [-]': loss_rate, - 'Fixed relative losses [-]': fixed_losses_relative, - 'Fixed absolute losses [MWh]': fixed_losses_absolute, + "U-value [W/(m2*K)]": u_value, + "Volume [m3]": volume, + "Surface [m2]": surface, + "Nominal storage capacity [MWh]": nominal_storage_capacity, + "Loss rate [-]": loss_rate, + "Fixed relative losses [-]": fixed_losses_relative, + "Fixed absolute losses [MWh]": fixed_losses_absolute, } - dash = '-' * 50 + dash = "-" * 50 print(dash) - print('{:>32s}{:>15s}'.format('Parameter name', 'Value')) + print("{:>32s}{:>15s}".format("Parameter name", "Value")) print(dash) for name, param in parameter.items(): - print('{:>32s}{:>15.5f}'.format(name, param)) + print("{:>32s}{:>15.5f}".format(name, param)) print(dash) - print_results() # Set up an energy system model - solver = 'cbc' + solver = "cbc" periods = 800 - datetimeindex = pd.date_range('1/1/2019', periods=periods, freq='H') + datetimeindex = pd.date_range("1/1/2019", periods=periods, freq="H") energysystem = EnergySystem(timeindex=datetimeindex) storage_list = [] - bus_simple_thermal_storage = Bus(label='bus_simple_thermal_storage', balanced=False) + bus_simple_thermal_storage = Bus( + label="bus_simple_thermal_storage", balanced=False + ) energysystem.add(bus_simple_thermal_storage) - storage_list.append(GenericStorage( - label='simple_thermal_storage', - inputs={bus_simple_thermal_storage: Flow( - nominal_value=input_data['maximum_heat_flow_charging'], - variable_costs=0.0001)}, - outputs={bus_simple_thermal_storage: Flow( - nominal_value=input_data['maximum_heat_flow_discharging'], - variable_costs=0.0001)}, - nominal_storage_capacity=nominal_storage_capacity, - min_storage_level=input_data['min_storage_level'], - max_storage_level=input_data['max_storage_level'], - initial_storage_level=27 / nominal_storage_capacity, - loss_rate=0.001, - inflow_conversion_factor=1., - outflow_conversion_factor=1., - balanced=False - )) + storage_list.append( + GenericStorage( + label="simple_thermal_storage", + inputs={ + bus_simple_thermal_storage: Flow( + nominal_value=input_data["maximum_heat_flow_charging"], + variable_costs=0.0001, + ) + }, + outputs={ + bus_simple_thermal_storage: Flow( + nominal_value=input_data["maximum_heat_flow_discharging"], + variable_costs=0.0001, + ) + }, + nominal_storage_capacity=nominal_storage_capacity, + min_storage_level=input_data["min_storage_level"], + max_storage_level=input_data["max_storage_level"], + initial_storage_level=27 / nominal_storage_capacity, + loss_rate=0.001, + inflow_conversion_factor=1.0, + outflow_conversion_factor=1.0, + balanced=False, + ) + ) for i, nominal_storage_capacity in enumerate([30, 65, 90]): - bus_i = Bus(label=f'bus_{i}', balanced=False) + bus_i = Bus(label=f"bus_{i}", balanced=False) energysystem.add(bus_i) - storage_list.append(GenericStorage( - label=f'stratified_thermal_storage_{nominal_storage_capacity}_MWh', - inputs={bus_i: Flow( - nominal_value=input_data['maximum_heat_flow_charging'], - variable_costs=0.0001)}, - outputs={bus_i: Flow( - nominal_value=input_data['maximum_heat_flow_discharging'], - variable_costs=0.0001)}, - nominal_storage_capacity=nominal_storage_capacity, - min_storage_level=input_data['min_storage_level'], - max_storage_level=input_data['max_storage_level'], - initial_storage_level=27 / nominal_storage_capacity, - loss_rate=loss_rate, - fixed_losses_relative=fixed_losses_relative, - fixed_losses_absolute=fixed_losses_absolute, - inflow_conversion_factor=1., - outflow_conversion_factor=1., - balanced=False - )) + storage_list.append( + GenericStorage( + label=f"stratified_thermal_storage_{nominal_storage_capacity}_MWh", + inputs={ + bus_i: Flow( + nominal_value=input_data["maximum_heat_flow_charging"], + variable_costs=0.0001, + ) + }, + outputs={ + bus_i: Flow( + nominal_value=input_data[ + "maximum_heat_flow_discharging" + ], + variable_costs=0.0001, + ) + }, + nominal_storage_capacity=nominal_storage_capacity, + min_storage_level=input_data["min_storage_level"], + max_storage_level=input_data["max_storage_level"], + initial_storage_level=27 / nominal_storage_capacity, + loss_rate=loss_rate, + fixed_losses_relative=fixed_losses_relative, + fixed_losses_absolute=fixed_losses_absolute, + inflow_conversion_factor=1.0, + outflow_conversion_factor=1.0, + balanced=False, + ) + ) energysystem.add(*storage_list) @@ -144,16 +162,19 @@ def print_results(): # Get results results = processing.results(optimization_model) - storage_content = views.node_weight_by_type(results, GenericStorage)\ - .reset_index(drop=True) + storage_content = views.node_weight_by_type( + results, GenericStorage + ).reset_index(drop=True) - storage_content.columns = storage_content.columns\ - .set_levels([k.label for k in storage_content.columns.levels[0]], level=0) + storage_content.columns = storage_content.columns.set_levels( + [k.label for k in storage_content.columns.levels[0]], level=0 + ) - losses = - storage_content.iloc[1:, :].reset_index(drop=True)\ - + storage_content.iloc[:-1, :].reset_index(drop=True) + losses = -storage_content.iloc[1:, :].reset_index( + drop=True + ) + storage_content.iloc[:-1, :].reset_index(drop=True) - losses.columns = losses.columns.set_levels(['losses'], level=1) + losses.columns = losses.columns.set_levels(["losses"], level=1) storage_content = storage_content.iloc[:-1, :] @@ -164,30 +185,29 @@ def print_results(): # Plot storage_content vs. time fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) storage_content.plot(ax=ax1) - ax1.set_title('Storage content') - ax1.set_xlabel('Timesteps') - ax1.set_ylabel('Storage content [MWh]') + ax1.set_title("Storage content") + ax1.set_xlabel("Timesteps") + ax1.set_ylabel("Storage content [MWh]") ax1.grid(alpha=0.3) ax1.get_legend().remove() # Plot losses vs storage content for storage_label in (storage.label for storage in storage_list): ax2.scatter( - storage_df[(storage_label, 'storage_content')], - storage_df[(storage_label, 'losses')], + storage_df[(storage_label, "storage_content")], + storage_df[(storage_label, "losses")], label=storage_label, - s=1 + s=1, ) ax2.set_xlim(0, 27.2) ax2.set_ylim(0, 0.035) - ax2.set_title('Losses vs. storage content') - ax2.set_xlabel('Storage content [MWh]') - ax2.set_ylabel('Losses [MW]') + ax2.set_title("Losses vs. storage content") + ax2.set_xlabel("Storage content [MWh]") + ax2.set_ylabel("Losses [MW]") ax2.grid(alpha=0.3) - ax2.legend(markerscale=8, loc='center left', bbox_to_anchor=(1.0, 0.5)) + ax2.legend(markerscale=8, loc="center left", bbox_to_anchor=(1.0, 0.5)) plt.tight_layout() - plt.savefig('compare_storage_models.svg') - + plt.savefig("compare_storage_models.svg") if __name__ == "__main__": diff --git a/pyproject.toml b/pyproject.toml index 12912108..3747d0f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,3 +46,7 @@ dependencies = [ 'pandas >= 0.18.0' ] license = {text = "MIT"} + +[tool.black] +line-length = 79 +target-version = ['py39', 'py310', 'py311'] diff --git a/src/oemof/thermal/__init__.py b/src/oemof/thermal/__init__.py index 1c7bd549..7cdb57f2 100644 --- a/src/oemof/thermal/__init__.py +++ b/src/oemof/thermal/__init__.py @@ -1,5 +1,5 @@ -__version__ = '0.0.7.dev0' -__project__ = 'oemof.thermal' +__version__ = "0.0.7.dev0" +__project__ = "oemof.thermal" from . import ( absorption_heatpumps_and_chillers, diff --git a/src/oemof/thermal/absorption_heatpumps_and_chillers.py b/src/oemof/thermal/absorption_heatpumps_and_chillers.py index f051f1ed..a5d5ff43 100644 --- a/src/oemof/thermal/absorption_heatpumps_and_chillers.py +++ b/src/oemof/thermal/absorption_heatpumps_and_chillers.py @@ -13,7 +13,6 @@ def calc_characteristic_temp(t_hot, t_cool, t_chill, coef_a, coef_e, method): - r""" Calculates the characteristic temperature difference. @@ -73,14 +72,11 @@ def calc_characteristic_temp(t_hot, t_cool, t_chill, coef_a, coef_e, method): """ if not isinstance(t_hot, (list)): - raise TypeError("Argument 't_hot' is not of " - "type list!") + raise TypeError("Argument 't_hot' is not of " "type list!") if not isinstance(t_cool, (list)): - raise TypeError("Argument 't_cool' is not of " - "type list!") + raise TypeError("Argument 't_cool' is not of " "type list!") if not isinstance(t_chill, (list)): - raise TypeError("Argument 't_chill' is not of " - "type list!") + raise TypeError("Argument 't_chill' is not of " "type list!") lengths = [len(t_hot), len(t_cool), len(t_chill)] length = max(lengths) @@ -91,7 +87,9 @@ def calc_characteristic_temp(t_hot, t_cool, t_chill, coef_a, coef_e, method): elif len(t_hot) == length: list_t_g = t_hot else: - raise ValueError("Length of argument 't_hot' does not to match requirements") + raise ValueError( + "Length of argument 't_hot' does not to match requirements" + ) # External mean temperature at absorber/condenser (ac) if len(t_cool) == 1: @@ -99,7 +97,9 @@ def calc_characteristic_temp(t_hot, t_cool, t_chill, coef_a, coef_e, method): elif len(t_cool) == length: list_t_ac = t_cool else: - raise ValueError("Length of argument 't_cool' does not to match requirements") + raise ValueError( + "Length of argument 't_cool' does not to match requirements" + ) # External mean temperature at evaporator (e) if len(t_chill) == 1: @@ -107,50 +107,58 @@ def calc_characteristic_temp(t_hot, t_cool, t_chill, coef_a, coef_e, method): elif len(t_chill) == length: list_t_e = t_chill else: - raise ValueError("Length of argument 't_chill' does not to match requirements") - - if method == 'kuehn_and_ziegler': - ddts = [t_g - coef_a * t_ac + coef_e * t_e for - t_g, t_ac, t_e in zip(list_t_g, list_t_ac, list_t_e)] + raise ValueError( + "Length of argument 't_chill' does not to match requirements" + ) + + if method == "kuehn_and_ziegler": + ddts = [ + t_g - coef_a * t_ac + coef_e * t_e + for t_g, t_ac, t_e in zip(list_t_g, list_t_ac, list_t_e) + ] else: - raise ValueError("Unrecognized input for argument 'method'. " - "Possible options: 'kuehn_and_ziegler'.") + raise ValueError( + "Unrecognized input for argument 'method'. " + "Possible options: 'kuehn_and_ziegler'." + ) return ddts def calc_heat_flux(ddts, coef_s, coef_r, method): r""" - Calculates the heat flux at external heat exchanger. + Calculates the heat flux at external heat exchanger. - .. calc_heat_flux-equations: + .. calc_heat_flux-equations: - :math:`\dot{Q} = s \cdot \Delta\Delta T + r` + :math:`\dot{Q} = s \cdot \Delta\Delta T + r` - Parameters - ---------- - ddt : numeric - Characteristic temperature difference [K] + Parameters + ---------- + ddt : numeric + Characteristic temperature difference [K] - coeff_s : numeric - Characteristic parameter [-] + coeff_s : numeric + Characteristic parameter [-] - coeff_r : numeric - Characteristic parameter [-] + coeff_r : numeric + Characteristic parameter [-] - method : string - Method to calculate characteristic temperature difference + method : string + Method to calculate characteristic temperature difference - Returns - ------- - Q_dots : numeric - Heat flux [W] + Returns + ------- + Q_dots : numeric + Heat flux [W] - """ - if method == 'kuehn_and_ziegler': + """ + if method == "kuehn_and_ziegler": Q_dots = [coef_s * ddt + coef_r for ddt in ddts] else: - raise ValueError("Unrecognized input for argument 'method'. " - "Possible options: 'kuehn_and_ziegler'.") + raise ValueError( + "Unrecognized input for argument 'method'. " + "Possible options: 'kuehn_and_ziegler'." + ) return Q_dots @@ -190,8 +198,8 @@ def define_AC_specs(Q_dots_evap, Q_dots_gen): """ AC_specs = { - 'COPs': [Q_e / Q_g for Q_e, Q_g in zip(Q_dots_evap, Q_dots_gen)], - 'Q_chill_max': [Q_e / max(Q_dots_evap) for Q_e in Q_dots_evap], - 'Q_chill_nominal': max(Q_dots_evap) + "COPs": [Q_e / Q_g for Q_e, Q_g in zip(Q_dots_evap, Q_dots_gen)], + "Q_chill_max": [Q_e / max(Q_dots_evap) for Q_e in Q_dots_evap], + "Q_chill_nominal": max(Q_dots_evap), } return AC_specs diff --git a/src/oemof/thermal/cogeneration.py b/src/oemof/thermal/cogeneration.py index 2174a951..897f42a4 100644 --- a/src/oemof/thermal/cogeneration.py +++ b/src/oemof/thermal/cogeneration.py @@ -74,27 +74,46 @@ def allocate_emissions(total_emissions, eta_el, eta_th, method, **kwargs): [in CO2 equivalents]. """ - if method == 'iea': - allocated_emissions_electricity = total_emissions * eta_el * 1 / (eta_el + eta_th) - allocated_emissions_heat = total_emissions * eta_th * 1 / (eta_el + eta_th) - - elif method == 'efficiency': - allocated_emissions_electricity = total_emissions * eta_th * 1 / (eta_el + eta_th) - allocated_emissions_heat = total_emissions * eta_el * 1 / (eta_el + eta_th) - - elif method == 'finnish': - if kwargs is not None and kwargs.keys() >= {'eta_el_ref', 'eta_th_ref'}: - eta_el_ref = kwargs.get('eta_el_ref') - eta_th_ref = kwargs.get('eta_th_ref') + if method == "iea": + allocated_emissions_electricity = ( + total_emissions * eta_el * 1 / (eta_el + eta_th) + ) + allocated_emissions_heat = ( + total_emissions * eta_th * 1 / (eta_el + eta_th) + ) + + elif method == "efficiency": + allocated_emissions_electricity = ( + total_emissions * eta_th * 1 / (eta_el + eta_th) + ) + allocated_emissions_heat = ( + total_emissions * eta_el * 1 / (eta_el + eta_th) + ) + + elif method == "finnish": + if kwargs is not None and kwargs.keys() >= { + "eta_el_ref", + "eta_th_ref", + }: + eta_el_ref = kwargs.get("eta_el_ref") + eta_th_ref = kwargs.get("eta_th_ref") else: - raise ValueError('Must specify eta_el_ref, eta_th_ref when using finnish method.') + raise ValueError( + "Must specify eta_el_ref, eta_th_ref when using finnish method." + ) pee = 1 - 1 / ((eta_el / eta_el_ref) + (eta_th / eta_th_ref)) - allocated_emissions_electricity = total_emissions * (1 - pee) * (eta_el / eta_el_ref) - allocated_emissions_heat = total_emissions * (1 - pee) * (eta_th / eta_th_ref) + allocated_emissions_electricity = ( + total_emissions * (1 - pee) * (eta_el / eta_el_ref) + ) + allocated_emissions_heat = ( + total_emissions * (1 - pee) * (eta_th / eta_th_ref) + ) else: - raise ValueError(f"Method '{method}' is not available. " - "Please choose from ['iea', finnish', 'efficiency']") + raise ValueError( + f"Method '{method}' is not available. " + "Please choose from ['iea', finnish', 'efficiency']" + ) return allocated_emissions_electricity, allocated_emissions_heat diff --git a/src/oemof/thermal/compression_heatpumps_and_chillers.py b/src/oemof/thermal/compression_heatpumps_and_chillers.py index b7cb6148..0c16180f 100644 --- a/src/oemof/thermal/compression_heatpumps_and_chillers.py +++ b/src/oemof/thermal/compression_heatpumps_and_chillers.py @@ -15,7 +15,12 @@ def calc_cops( - mode, temp_high, temp_low, quality_grade, temp_threshold_icing=2, factor_icing=None + mode, + temp_high, + temp_low, + quality_grade, + temp_threshold_icing=2, + factor_icing=None, ): r""" Calculates the Coefficient of Performance (COP) of heat pumps and chillers @@ -70,10 +75,14 @@ def calc_cops( """ # Check if input arguments have proper type and length if not isinstance(temp_low, (list, pd.Series)): - raise TypeError("Argument 'temp_low' is not of type list or pd.Series!") + raise TypeError( + "Argument 'temp_low' is not of type list or pd.Series!" + ) if not isinstance(temp_high, (list, pd.Series)): - raise TypeError("Argument 'temp_high' is not of " "type list or pd.Series!") + raise TypeError( + "Argument 'temp_high' is not of " "type list or pd.Series!" + ) if len(temp_high) != len(temp_low): if (len(temp_high) != 1) and ((len(temp_low) != 1)): diff --git a/src/oemof/thermal/concentrating_solar_power.py b/src/oemof/thermal/concentrating_solar_power.py index 6ee456ee..abbb3565 100644 --- a/src/oemof/thermal/concentrating_solar_power.py +++ b/src/oemof/thermal/concentrating_solar_power.py @@ -19,13 +19,28 @@ import pvlib -def csp_precalc(lat, long, collector_tilt, collector_azimuth, cleanliness, - eta_0, c_1, c_2, - temp_collector_inlet, temp_collector_outlet, temp_amb, - a_1, a_2, a_3=0, a_4=0, a_5=0, a_6=0, - loss_method='Janotte', - irradiance_method='horizontal', - **kwargs): +def csp_precalc( + lat, + long, + collector_tilt, + collector_azimuth, + cleanliness, + eta_0, + c_1, + c_2, + temp_collector_inlet, + temp_collector_outlet, + temp_amb, + a_1, + a_2, + a_3=0, + a_4=0, + a_5=0, + a_6=0, + loss_method="Janotte", + irradiance_method="horizontal", + **kwargs, +): r""" Calculates collectors efficiency and irradiance according to [1] and the heat of the thermal collector. For the calculation of irradiance pvlib [2] @@ -134,84 +149,109 @@ def csp_precalc(lat, long, collector_tilt, collector_azimuth, cleanliness, https://doi.org/10.21105/joss.00884 """ - if loss_method not in ['Janotte', 'Andasol']: - raise ValueError( - "loss_method should be 'Janotte' or 'Andasol'") + if loss_method not in ["Janotte", "Andasol"]: + raise ValueError("loss_method should be 'Janotte' or 'Andasol'") - if irradiance_method not in ['normal', 'horizontal']: + if irradiance_method not in ["normal", "horizontal"]: raise ValueError( - "irradiance_method should be 'normal' or 'horizontal'") + "irradiance_method should be 'normal' or 'horizontal'" + ) - required_dict = {'horizontal': 'E_dir_hor', 'normal': 'dni'} + required_dict = {"horizontal": "E_dir_hor", "normal": "dni"} irradiance_required = required_dict[irradiance_method] if irradiance_required not in kwargs: raise AttributeError( - f"'{irradiance_required}' necessary for {irradiance_method} is not provided") + f"'{irradiance_required}' necessary for {irradiance_method} is not provided" + ) - if loss_method == 'Andasol' and (c_2 != 0): - warnings.warn( - "Parameter c_2 is not used for loss method 'Andasol'") + if loss_method == "Andasol" and (c_2 != 0): + warnings.warn("Parameter c_2 is not used for loss method 'Andasol'") - if loss_method == 'Andasol' and (a_3 == 0 or a_4 == 0 or a_5 == 0 or a_6 == 0): + if loss_method == "Andasol" and ( + a_3 == 0 or a_4 == 0 or a_5 == 0 or a_6 == 0 + ): warnings.warn( - "Parameters a_3 to a_6 are required for loss method 'Andasol'") + "Parameters a_3 to a_6 are required for loss method 'Andasol'" + ) irradiance = kwargs.get(irradiance_required) if not temp_amb.index.equals(irradiance.index): - raise IndexError(f"Index of temp_amb and {irradiance_required} have to be the same.") + raise IndexError( + f"Index of temp_amb and {irradiance_required} have to be the same." + ) # Creation of a df with 2 columns - data = pd.DataFrame({'irradiance': irradiance, - 't_amb': temp_amb}) + data = pd.DataFrame({"irradiance": irradiance, "t_amb": temp_amb}) # Calculation of geometrical position of collector with the pvlib solarposition = pvlib.solarposition.get_solarposition( - time=data.index, - latitude=lat, - longitude=long) + time=data.index, latitude=lat, longitude=long + ) # Calculation of the tracking data with the pvlib tracking_data = pvlib.tracking.singleaxis( - solarposition['apparent_zenith'], solarposition['azimuth'], - axis_tilt=collector_tilt, axis_azimuth=collector_azimuth) + solarposition["apparent_zenith"], + solarposition["azimuth"], + axis_tilt=collector_tilt, + axis_azimuth=collector_azimuth, + ) # Calculation of the irradiance which hits the collectors surface irradiance_on_collector = calc_irradiance( - tracking_data['surface_tilt'], tracking_data['surface_azimuth'], - solarposition['apparent_zenith'], solarposition['azimuth'], - data['irradiance'], irradiance_method) + tracking_data["surface_tilt"], + tracking_data["surface_azimuth"], + solarposition["apparent_zenith"], + solarposition["azimuth"], + data["irradiance"], + irradiance_method, + ) # Calculation of the irradiance which reaches the collector after all # losses (cleanliness) collector_irradiance = calc_collector_irradiance( - irradiance_on_collector, cleanliness) + irradiance_on_collector, cleanliness + ) # Calculation of the incidence angle modifier iam = calc_iam( - a_1, a_2, a_3, a_4, a_5, a_6, tracking_data['aoi'], loss_method) + a_1, a_2, a_3, a_4, a_5, a_6, tracking_data["aoi"], loss_method + ) # Calculation of the collectors efficiency eta_c = calc_eta_c( - eta_0, c_1, c_2, iam, temp_collector_inlet, temp_collector_outlet, - data['t_amb'], collector_irradiance, loss_method) + eta_0, + c_1, + c_2, + iam, + temp_collector_inlet, + temp_collector_outlet, + data["t_amb"], + collector_irradiance, + loss_method, + ) # Calculation of the collectors heat - collector_heat = calc_heat_coll( - eta_c, collector_irradiance) + collector_heat = calc_heat_coll(eta_c, collector_irradiance) # Writing the results in the output df - data['collector_irradiance'] = collector_irradiance - data['eta_c'] = eta_c - data['collector_heat'] = collector_heat + data["collector_irradiance"] = collector_irradiance + data["eta_c"] = eta_c + data["collector_heat"] = collector_heat return data -def calc_irradiance(surface_tilt, surface_azimuth, apparent_zenith, azimuth, - irradiance, irradiance_method): +def calc_irradiance( + surface_tilt, + surface_azimuth, + apparent_zenith, + azimuth, + irradiance, + irradiance_method, +): r""" Parameters @@ -241,16 +281,17 @@ def calc_irradiance(surface_tilt, surface_azimuth, apparent_zenith, azimuth, Irradiance which hits collectors surface. """ - if irradiance_method == 'horizontal': + if irradiance_method == "horizontal": poa_horizontal_ratio = pvlib.irradiance.poa_horizontal_ratio( - surface_tilt, surface_azimuth, apparent_zenith, azimuth) + surface_tilt, surface_azimuth, apparent_zenith, azimuth + ) poa_horizontal_ratio[poa_horizontal_ratio < 0] = 0 irradiance_on_collector = irradiance * poa_horizontal_ratio - elif irradiance_method == 'normal': + elif irradiance_method == "normal": irradiance_on_collector = pvlib.irradiance.beam_component( - surface_tilt, surface_azimuth, apparent_zenith, azimuth, - irradiance) + surface_tilt, surface_azimuth, apparent_zenith, azimuth, irradiance + ) return irradiance_on_collector @@ -319,18 +360,33 @@ def calc_iam(a_1, a_2, a_3, a_4, a_5, a_6, aoi, loss_method): Incidence angle modifier: series of numeric """ - if loss_method == 'Janotte': + if loss_method == "Janotte": iam = 1 - a_1 * abs(aoi) - a_2 * aoi**2 - if loss_method == 'Andasol': - iam = (1 - a_1 * abs(aoi) - a_2 * aoi**2 - a_3 * aoi**3 - a_4 * aoi**4 - - a_5 * aoi**5 - a_6 * aoi**6) + if loss_method == "Andasol": + iam = ( + 1 + - a_1 * abs(aoi) + - a_2 * aoi**2 + - a_3 * aoi**3 + - a_4 * aoi**4 + - a_5 * aoi**5 + - a_6 * aoi**6 + ) return iam -def calc_eta_c(eta_0, c_1, c_2, iam, - temp_collector_inlet, temp_collector_outlet, temp_amb, - collector_irradiance, loss_method): +def calc_eta_c( + eta_0, + c_1, + c_2, + iam, + temp_collector_inlet, + temp_collector_outlet, + temp_amb, + collector_irradiance, + loss_method, +): r""" Calculates collectors efficiency depending on the loss method @@ -381,12 +437,17 @@ def calc_eta_c(eta_0, c_1, c_2, iam, """ - if loss_method == 'Janotte': - delta_temp = (temp_collector_inlet + temp_collector_outlet) / 2 - temp_amb - eta_c = eta_0 * iam - c_1 * delta_temp / collector_irradiance - c_2\ - * delta_temp ** 2 / collector_irradiance - - if loss_method == 'Andasol': + if loss_method == "Janotte": + delta_temp = ( + temp_collector_inlet + temp_collector_outlet + ) / 2 - temp_amb + eta_c = ( + eta_0 * iam + - c_1 * delta_temp / collector_irradiance + - c_2 * delta_temp**2 / collector_irradiance + ) + + if loss_method == "Andasol": eta_c = eta_0 * iam - c_1 / collector_irradiance eta_c[eta_c < 0] = 0 diff --git a/src/oemof/thermal/facades.py b/src/oemof/thermal/facades.py index 253183b7..9d0a8f5a 100644 --- a/src/oemof/thermal/facades.py +++ b/src/oemof/thermal/facades.py @@ -68,7 +68,9 @@ def __init__(self, *_, **kwargs): super().__init__(label=kwargs.get("label")) self.subnodes = [] - EnergySystem.signals[EnergySystem.add].connect(add_subnodes, sender=self) + EnergySystem.signals[EnergySystem.add].connect( + add_subnodes, sender=self + ) for r in required: if r in kwargs: @@ -109,7 +111,9 @@ def _investment(self): "storage_capacity_potential", float("+inf"), ), - minimum=getattr(self, "minimum_storage_capacity", 0), + minimum=getattr( + self, "minimum_storage_capacity", 0 + ), existing=getattr(self, "storage_capacity", 0), ) else: @@ -117,7 +121,9 @@ def _investment(self): else: self.investment = Investment( ep_costs=self.capacity_cost, - maximum=getattr(self, "capacity_potential", float("+inf")), + maximum=getattr( + self, "capacity_potential", float("+inf") + ), existing=getattr(self, "capacity", 0), ) else: @@ -280,9 +286,13 @@ def __init__( "storage_capacity_potential", float("+inf") ) - self.capacity_potential = kwargs.get("capacity_potential", float("+inf")) + self.capacity_potential = kwargs.get( + "capacity_potential", float("+inf") + ) - self.minimum_storage_capacity = kwargs.get("minimum_storage_capacity", 0) + self.minimum_storage_capacity = kwargs.get( + "minimum_storage_capacity", 0 + ) self.expandable = bool(kwargs.get("expandable", False)) @@ -339,9 +349,9 @@ def build_solph_components(self): for attr in ["invest_relation_input_output"]: if getattr(self, attr) is None: raise AttributeError( - ("You need to set attr " "`{}` " "for component {}").format( - attr, self.label - ) + ( + "You need to set attr " "`{}` " "for component {}" + ).format(attr, self.label) ) # set capacity costs at one of the flows @@ -362,7 +372,9 @@ def build_solph_components(self): # required for correct grouping in oemof.solph.components self._invest_group = True else: - self.volume = calculate_storage_dimensions(self.height, self.diameter)[0] + self.volume = calculate_storage_dimensions( + self.height, self.diameter + )[0] self.nominal_storage_capacity = calculate_capacities( self.volume, @@ -375,7 +387,9 @@ def build_solph_components(self): }, ) - fi = Flow(nominal_value=self._nominal_value(), **self.input_parameters) + fi = Flow( + nominal_value=self._nominal_value(), **self.input_parameters + ) fo = Flow( nominal_value=self._nominal_value(), variable_costs=self.marginal_cost, @@ -562,7 +576,9 @@ def build_solph_components(self): inflow = Source( label=self.label + "-inflow", outputs={ - self: Flow(nominal_value=self.aperture_area, max=self.collectors_heat) + self: Flow( + nominal_value=self.aperture_area, max=self.collectors_heat + ) }, ) @@ -704,7 +720,9 @@ def build_solph_components(self): inflow = Source( label=self.label + "-inflow", outputs={ - self: Flow(nominal_value=self.aperture_area, max=self.collectors_heat) + self: Flow( + nominal_value=self.aperture_area, max=self.collectors_heat + ) }, ) diff --git a/src/oemof/thermal/solar_thermal_collector.py b/src/oemof/thermal/solar_thermal_collector.py index 882d86f3..8edc65e6 100644 --- a/src/oemof/thermal/solar_thermal_collector.py +++ b/src/oemof/thermal/solar_thermal_collector.py @@ -28,7 +28,7 @@ def flat_plate_precalc( delta_temp_n, irradiance_global, irradiance_diffuse, - temp_amb + temp_amb, ): r""" Calculates collectors heat, efficiency and irradiance @@ -86,9 +86,9 @@ def flat_plate_precalc( # Creation of a df with 3 columns data = pd.DataFrame( { - 'ghi': irradiance_global, - 'dhi': irradiance_diffuse, - 'temp_amb': temp_amb + "ghi": irradiance_global, + "dhi": irradiance_diffuse, + "temp_amb": temp_amb, } ) @@ -105,20 +105,20 @@ def flat_plate_precalc( ) dni = pvlib.irradiance.dni( - ghi=data['ghi'], dhi=data['dhi'], zenith=solposition['apparent_zenith'] + ghi=data["ghi"], dhi=data["dhi"], zenith=solposition["apparent_zenith"] ) total_irradiation = pvlib.irradiance.get_total_irradiance( surface_tilt=collector_tilt, surface_azimuth=collector_azimuth, - solar_zenith=solposition['apparent_zenith'], - solar_azimuth=solposition['azimuth'], + solar_zenith=solposition["apparent_zenith"], + solar_azimuth=solposition["azimuth"], dni=dni.fillna(0), # fill NaN values with '0' - ghi=data['ghi'], - dhi=data['dhi'], + ghi=data["ghi"], + dhi=data["dhi"], ) - data['col_ira'] = total_irradiation['poa_global'] + data["col_ira"] = total_irradiation["poa_global"] eta_c = calc_eta_c_flate_plate( eta_0, @@ -126,11 +126,11 @@ def flat_plate_precalc( a_2, temp_collector_inlet, delta_temp_n, - data['temp_amb'], - total_irradiation['poa_global'], + data["temp_amb"], + total_irradiation["poa_global"], ) - data['eta_c'] = eta_c - collectors_heat = eta_c * total_irradiation['poa_global'] + data["eta_c"] = eta_c + collectors_heat = eta_c * total_irradiation["poa_global"] data["collectors_heat"] = collectors_heat return data diff --git a/src/oemof/thermal/stratified_thermal_storage.py b/src/oemof/thermal/stratified_thermal_storage.py index 4ca46e03..63e120c0 100644 --- a/src/oemof/thermal/stratified_thermal_storage.py +++ b/src/oemof/thermal/stratified_thermal_storage.py @@ -42,7 +42,9 @@ def calculate_storage_u_value(s_iso, lamb_iso, alpha_inside, alpha_outside): u_value : numeric Thermal transmittance (U-value) [W/(m2*K)] """ - denominator = 1 / alpha_inside + s_iso * 1e-3 / lamb_iso + 1 / alpha_outside + denominator = ( + 1 / alpha_inside + s_iso * 1e-3 / lamb_iso + 1 / alpha_outside + ) u_value = 1 / denominator return u_value @@ -74,8 +76,8 @@ def calculate_storage_dimensions(height, diameter): surface : numeric Total surface of storage [m2] """ - volume = 0.25 * np.pi * diameter ** 2 * height - surface = np.pi * diameter * height + 0.5 * np.pi * diameter ** 2 + volume = 0.25 * np.pi * diameter**2 * height + surface = np.pi * diameter * height + 0.5 * np.pi * diameter**2 return volume, surface @@ -118,7 +120,9 @@ def calculate_capacities( Maximum amount of stored thermal energy [MWh] """ - nominal_storage_capacity = volume * heat_capacity * density * (temp_h - temp_c) + nominal_storage_capacity = ( + volume * heat_capacity * density * (temp_h - temp_c) + ) nominal_storage_capacity *= 1 / 3600 # J to Wh nominal_storage_capacity *= 1e-6 # Wh to MWh @@ -192,19 +196,31 @@ def calculate_losses( nominal storage capacity between two consecutive timesteps [MWh] """ loss_rate = ( - 4 * u_value * 1 / (diameter * density * heat_capacity) * time_increment + 4 + * u_value + * 1 + / (diameter * density * heat_capacity) + * time_increment * 3600 # Ws to Wh ) fixed_losses_relative = ( - 4 * u_value * (temp_c - temp_env) - * 1 / ((diameter * density * heat_capacity) * (temp_h - temp_c)) + 4 + * u_value + * (temp_c - temp_env) + * 1 + / ((diameter * density * heat_capacity) * (temp_h - temp_c)) * time_increment * 3600 # Ws to Wh ) fixed_losses_absolute = ( - 0.25 * u_value * np.pi * diameter ** 2 * (temp_h + temp_c - 2 * temp_env) * time_increment + 0.25 + * u_value + * np.pi + * diameter**2 + * (temp_h + temp_c - 2 * temp_env) + * time_increment ) fixed_losses_absolute *= 1e-6 # Wh to MWh diff --git a/tests/test_constraints.py b/tests/test_constraints.py index d896e1b2..b2f9c19e 100644 --- a/tests/test_constraints.py +++ b/tests/test_constraints.py @@ -39,7 +39,8 @@ def normalize_to_positive_results(lines): n for n, line in enumerate(lines) if re.match("^= -", line) ] equation_start_indices = [ - [n for n in reversed(range(0, nri)) if re.match(".*:$", lines[n])][0] + 1 + [n for n in reversed(range(0, nri)) if re.match(".*:$", lines[n])][0] + + 1 for nri in negative_result_indices ] for start, end in zip(equation_start_indices, negative_result_indices): @@ -95,7 +96,9 @@ def setup_method(self): ) def get_om(self): - return solph.Model(self.energysystem, timeindex=self.energysystem.timeindex) + return solph.Model( + self.energysystem, timeindex=self.energysystem.timeindex + ) def compare_to_reference_lp(self, ref_filename, my_om=None): if my_om is None: @@ -109,7 +112,9 @@ def compare_to_reference_lp(self, ref_filename, my_om=None): om.write(new_filepath, io_options={"symbolic_solver_labels": True}) - ref_filepath = os.path.join(os.path.dirname(__file__), "lp_files", ref_filename) + ref_filepath = os.path.join( + os.path.dirname(__file__), "lp_files", ref_filename + ) with open(new_filepath) as new_file: with open(ref_filepath) as ref_file: @@ -170,7 +175,9 @@ def test_stratified_thermal_storage_invest_option_1_facade(self): ) ) - self.compare_to_reference_lp("stratified_thermal_storage_invest_option_1.lp") + self.compare_to_reference_lp( + "stratified_thermal_storage_invest_option_1.lp" + ) def test_stratified_thermal_storage_invest_option_2_facade(self): """ @@ -200,7 +207,9 @@ def test_stratified_thermal_storage_invest_option_2_facade(self): ) ) - self.compare_to_reference_lp("stratified_thermal_storage_invest_option_2.lp") + self.compare_to_reference_lp( + "stratified_thermal_storage_invest_option_2.lp" + ) def test_csp_collector_facade(self): """Constraint test of a csp collector.""" @@ -210,7 +219,11 @@ def test_csp_collector_facade(self): self.energysystem.add(bus_heat, bus_el) d = { - "Datum": ["01.02.2003 09:00", "01.02.2003 10:00", "01.02.2003 11:00"], + "Datum": [ + "01.02.2003 09:00", + "01.02.2003 10:00", + "01.02.2003 11:00", + ], "E_dir_hor": [43.1, 152.7, 76.9], "t_amb": [22.2, 23.2, 24.1], } @@ -258,7 +271,11 @@ def test_solar_thermal_collector_facade(self): self.energysystem.add(bus_heat, bus_el) d = { - "Datum": ["01.02.2003 09:00", "01.02.2003 10:00", "01.02.2003 11:00"], + "Datum": [ + "01.02.2003 09:00", + "01.02.2003 10:00", + "01.02.2003 11:00", + ], "global_horizontal_W_m2": [47, 132, 131], "diffuse_horizontal_W_m2": [37.57155865, 69.72163199, 98.85021832], "temp_amb": [4, 6, 8], diff --git a/tests/test_functions.py b/tests/test_functions.py index 7ed02678..865f71ae 100644 --- a/tests/test_functions.py +++ b/tests/test_functions.py @@ -32,7 +32,10 @@ def test_calc_cops_with_Series_01(): ambient_temp_each_hour = {"01:00": 12, "02:00": 12, "03:00": 12} temp_l_series = pd.Series(ambient_temp_each_hour) cops_HP = cmpr_hp_chllr.calc_cops( - temp_high=[40], temp_low=temp_l_series, quality_grade=0.4, mode="heat_pump" + temp_high=[40], + temp_low=temp_l_series, + quality_grade=0.4, + mode="heat_pump", ) assert cops_HP == [4.473571428571428, 4.473571428571428, 4.473571428571428] @@ -41,7 +44,10 @@ def test_calc_cops_with_Series_02(): set_temp_each_hour = {"01:00": 40, "02:00": 40, "03:00": 40} temp_h_series = pd.Series(set_temp_each_hour) cops_HP = cmpr_hp_chllr.calc_cops( - temp_high=temp_h_series, temp_low=[12], quality_grade=0.4, mode="heat_pump" + temp_high=temp_h_series, + temp_low=[12], + quality_grade=0.4, + mode="heat_pump", ) assert cops_HP == [4.473571428571428, 4.473571428571428, 4.473571428571428] @@ -171,7 +177,9 @@ def test_raised_exceptions_05(): with pytest.raises(TypeError): actual_cop = 4.5 # ERROR - has to be of type list! nom_cond = {"nominal_Q_chill": 20, "nominal_el_consumption": 5} - cmpr_hp_chllr.calc_max_Q_dot_chill(nominal_conditions=nom_cond, cops=actual_cop) + cmpr_hp_chllr.calc_max_Q_dot_chill( + nominal_conditions=nom_cond, cops=actual_cop + ) def test_calc_max_Q_dot_heat(): @@ -190,7 +198,9 @@ def test_calc_chiller_quality_grade(): "t_high_nominal": 35, "t_low_nominal": 7, } - q_grade = cmpr_hp_chllr.calc_chiller_quality_grade(nominal_conditions=nom_cond) + q_grade = cmpr_hp_chllr.calc_chiller_quality_grade( + nominal_conditions=nom_cond + ) assert q_grade == 0.39978582902016785 @@ -236,7 +246,9 @@ def test_calculate_losses(): "temp_env": 10, # deg C } - loss_rate, fixed_losses_relative, fixed_losses_absolute = calculate_losses(**params) + loss_rate, fixed_losses_relative, fixed_losses_absolute = calculate_losses( + **params + ) assert ( loss_rate == 0.0003531819182021882 and fixed_losses_relative == 0.00028254553456175054 @@ -297,7 +309,8 @@ def test_calculation_of_collector_irradiance(): s = pd.Series([10, 20, 30], index=[1, 2, 3]) res = csp.calc_collector_irradiance(s, 0.9) result = pd.Series( - [8.5381496824546242, 17.0762993649092484, 25.614449047363873], index=[1, 2, 3] + [8.5381496824546242, 17.0762993649092484, 25.614449047363873], + index=[1, 2, 3], ) assert res.values == approx(result.values) @@ -310,7 +323,14 @@ def test_calculation_iam_for_single_value(): def test_calculation_iam_andasol(): res = csp.calc_iam( - -8.65e-4, 8.87e-4, -5.425e-5, 1.665e-6, -2.309e-8, 1.197e-10, 50, "Andasol" + -8.65e-4, + 8.87e-4, + -5.425e-5, + 1.665e-6, + -2.309e-8, + 1.197e-10, + 50, + "Andasol", ) assert res == 0.5460625000000001 @@ -390,7 +410,9 @@ def test_csp_wrong_loss_method(): def test_eta_janotte(): s = pd.Series([50], index=[1]) - res = csp.calc_eta_c(0.816, 0.0622, 0.00023, 0.95, 235, 300, 30, s, "Janotte") + res = csp.calc_eta_c( + 0.816, 0.0622, 0.00023, 0.95, 235, 300, 30, s, "Janotte" + ) result = pd.Series([0.22028124999999987], index=[1]) assert res.eq(result).all() @@ -693,4 +715,6 @@ def test_raised_exception_method_selection_01(): def test_raised_exception_method_selection_02(): """Test if an exception is raised if unknown method name is passed.""" with pytest.raises(ValueError): - ac.calc_heat_flux(ddts=25, coef_s=0.42, coef_r=0.9, method="shaken_not_stirred") + ac.calc_heat_flux( + ddts=25, coef_s=0.42, coef_r=0.9, method="shaken_not_stirred" + ) From 95890b3fd50418fe9f2fa81051dd4285905fda5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Tue, 8 Oct 2024 21:29:19 +0200 Subject: [PATCH 15/34] Adhere to Black --- docs/conf.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index f7b69f3b..0dfaf096 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -256,7 +256,13 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ("index", "oemof", "oemof.thermal documentation", ["oemof developer group"], 1) + ( + "index", + "oemof", + "oemof.thermal documentation", + ["oemof developer group"], + 1, + ) ] # If true, show URL addresses after external links. From a4744bc38ca39e1e3df1775ef36aacb54be45cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 15:42:00 +0200 Subject: [PATCH 16/34] Align python requirement with target version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3747d0f5..136e5104 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ classifiers = [ "Topic :: Utilities", ] -requires-python = ">=3.10" +requires-python = ">=3.9" dependencies = [ 'oemof.solph', 'matplotlib', From f6093b6265df7d0e1401ad350a91d6b6c5a77ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 15:51:10 +0200 Subject: [PATCH 17/34] Remove flake8 file --- .flake8 | 4 ---- pyproject.toml | 1 - 2 files changed, 5 deletions(-) delete mode 100644 .flake8 diff --git a/.flake8 b/.flake8 deleted file mode 100644 index d9472f59..00000000 --- a/.flake8 +++ /dev/null @@ -1,4 +0,0 @@ -[flake8] -exclude = meta/migrations/ -ignore = E265, W503 -max-line-length = 100 diff --git a/pyproject.toml b/pyproject.toml index 136e5104..474fe025 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,6 @@ include = [ "examples/", "src/", "tests/", - ".flake8", ".pylintrc", ] From 8621465f43d6b055277798de738b35a744c48293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 15:53:23 +0200 Subject: [PATCH 18/34] Adapt pyproject.toml --- pyproject.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 474fe025..9e08f5d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,6 +11,7 @@ include = [ "src/", "tests/", ".pylintrc", + "tox.ini", ] [project] @@ -49,3 +50,7 @@ license = {text = "MIT"} [tool.black] line-length = 79 target-version = ['py39', 'py310', 'py311'] + +[tool.isort] +force_single_line = true +line_length = 79 From 893e0863f593837cff753debb85a888674419ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 16:14:23 +0200 Subject: [PATCH 19/34] Fix import orders --- .../absorption_chiller.py | 8 ++- ...ng_cap_dependence_on_cooling_water_temp.py | 6 +- examples/check_examples.py | 18 ++---- .../emission_allocation_methods.py | 2 +- .../airsource_heatpump_const_max_output.py | 8 ++- .../airsource_heatpump_variable_max_output.py | 8 ++- .../chiller_cop_as_TimeSeries.py | 3 +- ...op_dependence_on_temperature_difference.py | 5 +- .../groundsource_heatpump.py | 6 +- .../concentrating_solar_power/csp_facade.py | 8 +-- .../concentrating_solar_power/csp_plant.py | 5 +- examples/solar_thermal_collector/_plots.py | 1 + .../flat_plate_collector.py | 2 +- .../flat_plate_collector_facade.py | 8 ++- .../flat_plate_collector_investment.py | 2 +- .../investment_fixed_ratio_facade.py | 15 +++-- .../investment_fixed_ratio_generic_storage.py | 21 ++++--- .../investment_independent_facade.py | 15 +++-- .../investment_independent_generic_storage.py | 22 +++++--- .../model_validation.py | 27 +++++---- .../operation_facade.py | 11 +++- .../operation_generic_storage.py | 23 +++++--- examples/stratified_thermal_storage/plots.py | 19 ++++--- pyproject.toml | 1 + src/oemof/thermal/__init__.py | 16 +++--- .../absorption_heatpumps_and_chillers.py | 9 +-- src/oemof/thermal/cogeneration.py | 36 +++++++----- .../compression_heatpumps_and_chillers.py | 6 +- .../thermal/concentrating_solar_power.py | 6 +- src/oemof/thermal/facades.py | 56 +++++++++++-------- src/oemof/thermal/solar_thermal_collector.py | 12 ++-- .../thermal/stratified_thermal_storage.py | 15 +++-- tests/test_functions.py | 12 ++-- 33 files changed, 239 insertions(+), 173 deletions(-) diff --git a/examples/absorption_heatpump_and_chiller/absorption_chiller.py b/examples/absorption_heatpump_and_chiller/absorption_chiller.py index 739827cd..b160ae1d 100644 --- a/examples/absorption_heatpump_and_chiller/absorption_chiller.py +++ b/examples/absorption_heatpump_and_chiller/absorption_chiller.py @@ -1,9 +1,11 @@ # import absorption_heatpumps_and_chillers as abs_hp_chiller -import oemof.thermal.absorption_heatpumps_and_chillers as abs_hp_chiller -import oemof.solph as solph -import pandas as pd import os + import matplotlib.pyplot as plt +import oemof.solph as solph +import pandas as pd + +import oemof.thermal.absorption_heatpumps_and_chillers as abs_hp_chiller def absorption_chiller_example(): diff --git a/examples/absorption_heatpump_and_chiller/cooling_cap_dependence_on_cooling_water_temp.py b/examples/absorption_heatpump_and_chiller/cooling_cap_dependence_on_cooling_water_temp.py index bbef1f77..cfaec66c 100644 --- a/examples/absorption_heatpump_and_chiller/cooling_cap_dependence_on_cooling_water_temp.py +++ b/examples/absorption_heatpump_and_chiller/cooling_cap_dependence_on_cooling_water_temp.py @@ -1,8 +1,10 @@ -import oemof.thermal.absorption_heatpumps_and_chillers as abs_hp_chiller -import matplotlib.pyplot as plt import os + +import matplotlib.pyplot as plt import pandas as pd +import oemof.thermal.absorption_heatpumps_and_chillers as abs_hp_chiller + def cooling_cap_example(): filename = os.path.join( diff --git a/examples/check_examples.py b/examples/check_examples.py index 6efbd39b..0c3d49d5 100644 --- a/examples/check_examples.py +++ b/examples/check_examples.py @@ -4,11 +4,9 @@ from absorption_heatpump_and_chiller.cooling_cap_dependence_on_cooling_water_temp import ( cooling_cap_example, ) - from cogeneration.emission_allocation_methods import ( emission_allocation_example, ) - from compression_heatpump_and_chiller.airsource_heatpump_const_max_output import ( airource_hp_const_example, ) @@ -24,14 +22,12 @@ from compression_heatpump_and_chiller.groundsource_heatpump import ( groundsource_hp_example, ) - from concentrating_solar_power.csp_collector_plot import csp_collector_example from concentrating_solar_power.csp_collector_plot_andasol import ( csp_andasol_example, ) from concentrating_solar_power.csp_facade import csp_facade_example from concentrating_solar_power.csp_plant import csp_plant_example - from solar_thermal_collector.flat_plate_collector import ( flat_plate_collector_example, ) @@ -41,13 +37,6 @@ from solar_thermal_collector.flat_plate_collector_investment import ( flat_plate_collector_investment_example, ) - -from stratified_thermal_storage.operation_generic_storage import ( - operation_example, -) -from stratified_thermal_storage.operation_facade import ( - operation_facade_example, -) from stratified_thermal_storage.investment_fixed_ratio_facade import ( fixed_ratio_invest_facade_example, ) @@ -60,7 +49,12 @@ from stratified_thermal_storage.investment_independent_generic_storage import ( invest_independent_example, ) - +from stratified_thermal_storage.operation_facade import ( + operation_facade_example, +) +from stratified_thermal_storage.operation_generic_storage import ( + operation_example, +) # absorption_chiller_example() cooling_cap_example() diff --git a/examples/cogeneration/emission_allocation_methods.py b/examples/cogeneration/emission_allocation_methods.py index 34511a6f..4998f18d 100644 --- a/examples/cogeneration/emission_allocation_methods.py +++ b/examples/cogeneration/emission_allocation_methods.py @@ -5,8 +5,8 @@ """ -import pandas as pd import matplotlib.pyplot as plt +import pandas as pd from oemof.thermal.cogeneration import allocate_emissions diff --git a/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py b/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py index c1afd0b1..9c0cc0b0 100644 --- a/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py +++ b/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py @@ -7,11 +7,13 @@ """ import os -import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller -import oemof.solph as solph -import pandas as pd + import matplotlib.pyplot as plt import numpy as np +import oemof.solph as solph +import pandas as pd + +import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller def airource_hp_const_example(): diff --git a/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py b/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py index 6fed5761..9aea6cde 100644 --- a/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py +++ b/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py @@ -9,11 +9,13 @@ """ import os -import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller -import oemof.solph as solph -import pandas as pd + import matplotlib.pyplot as plt import numpy as np +import oemof.solph as solph +import pandas as pd + +import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller def airource_hp_variable_example(): diff --git a/examples/compression_heatpump_and_chiller/chiller_cop_as_TimeSeries.py b/examples/compression_heatpump_and_chiller/chiller_cop_as_TimeSeries.py index 93fc9776..55d5e39b 100644 --- a/examples/compression_heatpump_and_chiller/chiller_cop_as_TimeSeries.py +++ b/examples/compression_heatpump_and_chiller/chiller_cop_as_TimeSeries.py @@ -8,9 +8,10 @@ oemof.solph.transformer. """ -import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller import pandas as pd +import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller + def chiller_cop_timeseries_example(): # Ambient temperatures in degC for a single day (24h) diff --git a/examples/compression_heatpump_and_chiller/cop_dependence_on_temperature_difference.py b/examples/compression_heatpump_and_chiller/cop_dependence_on_temperature_difference.py index e6663106..eb30d6c5 100644 --- a/examples/compression_heatpump_and_chiller/cop_dependence_on_temperature_difference.py +++ b/examples/compression_heatpump_and_chiller/cop_dependence_on_temperature_difference.py @@ -5,9 +5,10 @@ This example plots the temperature dependency of the COP. """ -import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller -import pandas as pd import matplotlib.pyplot as plt +import pandas as pd + +import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller def cop_temperature_example(): diff --git a/examples/compression_heatpump_and_chiller/groundsource_heatpump.py b/examples/compression_heatpump_and_chiller/groundsource_heatpump.py index 1f0089d9..691850e9 100644 --- a/examples/compression_heatpump_and_chiller/groundsource_heatpump.py +++ b/examples/compression_heatpump_and_chiller/groundsource_heatpump.py @@ -6,10 +6,12 @@ """ import os -import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller + +import matplotlib.pyplot as plt import oemof.solph as solph import pandas as pd -import matplotlib.pyplot as plt + +import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller def groundsource_hp_example(): diff --git a/examples/concentrating_solar_power/csp_facade.py b/examples/concentrating_solar_power/csp_facade.py index 9344bbfa..e1673dac 100644 --- a/examples/concentrating_solar_power/csp_facade.py +++ b/examples/concentrating_solar_power/csp_facade.py @@ -10,13 +10,13 @@ """ import os -import pandas as pd -import matplotlib.pyplot as plt +import matplotlib.pyplot as plt +import pandas as pd +from oemof.tools import economics -from oemof.thermal import facades from oemof import solph -from oemof.tools import economics +from oemof.thermal import facades def csp_facade_example(): diff --git a/examples/concentrating_solar_power/csp_plant.py b/examples/concentrating_solar_power/csp_plant.py index 38d65a6e..81573994 100644 --- a/examples/concentrating_solar_power/csp_plant.py +++ b/examples/concentrating_solar_power/csp_plant.py @@ -8,14 +8,13 @@ """ import os +import matplotlib.pyplot as plt import pandas as pd +from oemof.tools import economics from oemof import solph -from oemof.tools import economics from oemof.thermal.concentrating_solar_power import csp_precalc -import matplotlib.pyplot as plt - def csp_plant_example(): # Set paths diff --git a/examples/solar_thermal_collector/_plots.py b/examples/solar_thermal_collector/_plots.py index 389c4231..eaf2e35c 100644 --- a/examples/solar_thermal_collector/_plots.py +++ b/examples/solar_thermal_collector/_plots.py @@ -3,6 +3,7 @@ """ import os + import matplotlib.pyplot as plt diff --git a/examples/solar_thermal_collector/flat_plate_collector.py b/examples/solar_thermal_collector/flat_plate_collector.py index 394c3a5b..17ba066c 100644 --- a/examples/solar_thermal_collector/flat_plate_collector.py +++ b/examples/solar_thermal_collector/flat_plate_collector.py @@ -11,9 +11,9 @@ import os import pandas as pd +from oemof.tools import economics from oemof import solph -from oemof.tools import economics from oemof.thermal.solar_thermal_collector import flat_plate_precalc from ._plots import plot_collector_heat diff --git a/examples/solar_thermal_collector/flat_plate_collector_facade.py b/examples/solar_thermal_collector/flat_plate_collector_facade.py index e8127870..1a0c017c 100644 --- a/examples/solar_thermal_collector/flat_plate_collector_facade.py +++ b/examples/solar_thermal_collector/flat_plate_collector_facade.py @@ -9,12 +9,14 @@ SPDX-License-Identifier: GPL-3.0-or-later """ import os -import pandas as pd + import matplotlib.pyplot as plt -from oemof.thermal import facades -from oemof import solph +import pandas as pd from oemof.tools import economics +from oemof import solph +from oemof.thermal import facades + def flat_plate_collector_facade_example(): # Set paths diff --git a/examples/solar_thermal_collector/flat_plate_collector_investment.py b/examples/solar_thermal_collector/flat_plate_collector_investment.py index 9bc0108f..41acae9d 100644 --- a/examples/solar_thermal_collector/flat_plate_collector_investment.py +++ b/examples/solar_thermal_collector/flat_plate_collector_investment.py @@ -11,9 +11,9 @@ import os import pandas as pd +from oemof.tools import economics from oemof import solph -from oemof.tools import economics from oemof.thermal.solar_thermal_collector import flat_plate_precalc from ._plots import plot_collector_heat diff --git a/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py b/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py index df5cb450..0b1aef13 100644 --- a/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py +++ b/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py @@ -3,14 +3,19 @@ """ import os -import pandas as pd + import numpy as np +import pandas as pd +from oemof.solph import Bus +from oemof.solph import EnergySystem +from oemof.solph import Flow +from oemof.solph import Model +from oemof.solph import processing +from oemof.solph.components import Sink +from oemof.solph.components import Source -from oemof.thermal.stratified_thermal_storage import calculate_storage_u_value from oemof.thermal import facades - -from oemof.solph import processing, Bus, Flow, Model, EnergySystem -from oemof.solph.components import Source, Sink +from oemof.thermal.stratified_thermal_storage import calculate_storage_u_value def fixed_ratio_invest_facade_example(): diff --git a/examples/stratified_thermal_storage/investment_fixed_ratio_generic_storage.py b/examples/stratified_thermal_storage/investment_fixed_ratio_generic_storage.py index 756e7e79..8942a893 100644 --- a/examples/stratified_thermal_storage/investment_fixed_ratio_generic_storage.py +++ b/examples/stratified_thermal_storage/investment_fixed_ratio_generic_storage.py @@ -6,16 +6,21 @@ """ import os -import pandas as pd -import numpy as np -from oemof.thermal.stratified_thermal_storage import ( - calculate_storage_u_value, - calculate_losses, -) -from oemof.solph import Bus, Flow, Investment, Model, EnergySystem -from oemof.solph.components import GenericStorage, Source, Sink +import numpy as np +import pandas as pd +from oemof.solph import Bus +from oemof.solph import EnergySystem +from oemof.solph import Flow +from oemof.solph import Investment +from oemof.solph import Model from oemof.solph import processing +from oemof.solph.components import GenericStorage +from oemof.solph.components import Sink +from oemof.solph.components import Source + +from oemof.thermal.stratified_thermal_storage import calculate_losses +from oemof.thermal.stratified_thermal_storage import calculate_storage_u_value def fixed_ratio_invest_example(): diff --git a/examples/stratified_thermal_storage/investment_independent_facade.py b/examples/stratified_thermal_storage/investment_independent_facade.py index c879a765..a6c973d0 100644 --- a/examples/stratified_thermal_storage/investment_independent_facade.py +++ b/examples/stratified_thermal_storage/investment_independent_facade.py @@ -6,14 +6,19 @@ """ import os -import pandas as pd + import numpy as np +import pandas as pd +from oemof.solph import Bus +from oemof.solph import EnergySystem +from oemof.solph import Flow +from oemof.solph import Model +from oemof.solph import processing +from oemof.solph.components import Sink +from oemof.solph.components import Source -from oemof.thermal.stratified_thermal_storage import calculate_storage_u_value from oemof.thermal import facades - -from oemof.solph import processing, Bus, Flow, Model, EnergySystem -from oemof.solph.components import Source, Sink +from oemof.thermal.stratified_thermal_storage import calculate_storage_u_value def invest_independent_facade_example(): diff --git a/examples/stratified_thermal_storage/investment_independent_generic_storage.py b/examples/stratified_thermal_storage/investment_independent_generic_storage.py index 2cad95fd..e59ea9bc 100644 --- a/examples/stratified_thermal_storage/investment_independent_generic_storage.py +++ b/examples/stratified_thermal_storage/investment_independent_generic_storage.py @@ -7,15 +7,21 @@ """ import os -import pandas as pd -import numpy as np -from oemof.thermal.stratified_thermal_storage import ( - calculate_storage_u_value, - calculate_losses, -) -from oemof.solph import processing, Bus, Flow, Investment, Model, EnergySystem -from oemof.solph.components import GenericStorage, Source, Sink +import numpy as np +import pandas as pd +from oemof.solph import Bus +from oemof.solph import EnergySystem +from oemof.solph import Flow +from oemof.solph import Investment +from oemof.solph import Model +from oemof.solph import processing +from oemof.solph.components import GenericStorage +from oemof.solph.components import Sink +from oemof.solph.components import Source + +from oemof.thermal.stratified_thermal_storage import calculate_losses +from oemof.thermal.stratified_thermal_storage import calculate_storage_u_value def invest_independent_example(): diff --git a/examples/stratified_thermal_storage/model_validation.py b/examples/stratified_thermal_storage/model_validation.py index a6d4d4d7..014e25cc 100644 --- a/examples/stratified_thermal_storage/model_validation.py +++ b/examples/stratified_thermal_storage/model_validation.py @@ -1,25 +1,24 @@ import os + import matplotlib.pyplot as plt -import pandas as pd import numpy as np import oemof.solph as solph +import pandas as pd +from oemof.solph import Bus +from oemof.solph import EnergySystem +from oemof.solph import Flow +from oemof.solph import Model +from oemof.solph.components import Sink +from oemof.solph.components import Source + +from oemof.thermal import facades from oemof.thermal.stratified_thermal_storage import ( # noqa - calculate_storage_u_value, - calculate_storage_dimensions, calculate_capacities, ) -from oemof.thermal import facades - -from oemof.solph.components import ( - Source, - Sink, -) -from oemof.solph import ( - Bus, - Flow, - Model, - EnergySystem, +from oemof.thermal.stratified_thermal_storage import ( + calculate_storage_dimensions, ) +from oemof.thermal.stratified_thermal_storage import calculate_storage_u_value def model_validation(): diff --git a/examples/stratified_thermal_storage/operation_facade.py b/examples/stratified_thermal_storage/operation_facade.py index 62b686a0..cbd70ea2 100644 --- a/examples/stratified_thermal_storage/operation_facade.py +++ b/examples/stratified_thermal_storage/operation_facade.py @@ -4,11 +4,16 @@ """ import os -import pandas as pd + import numpy as np +import pandas as pd +from oemof.solph import Bus # noqa +from oemof.solph import EnergySystem +from oemof.solph import Flow +from oemof.solph import Model +from oemof.solph.components import Sink +from oemof.solph.components import Source -from oemof.solph import Bus, Flow, Model, EnergySystem # noqa -from oemof.solph.components import Sink, Source from oemof.thermal import facades from oemof.thermal.stratified_thermal_storage import ( # noqa calculate_storage_u_value, diff --git a/examples/stratified_thermal_storage/operation_generic_storage.py b/examples/stratified_thermal_storage/operation_generic_storage.py index 090d5331..3a8c986b 100644 --- a/examples/stratified_thermal_storage/operation_generic_storage.py +++ b/examples/stratified_thermal_storage/operation_generic_storage.py @@ -4,18 +4,25 @@ """ import os -import pandas as pd -import numpy as np -import matplotlib.pyplot as plt +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +from oemof.solph import Bus +from oemof.solph import EnergySystem +from oemof.solph import Flow +from oemof.solph import Model +from oemof.solph import processing +from oemof.solph.components import GenericStorage +from oemof.solph.components import Sink +from oemof.solph.components import Source + +from oemof.thermal.stratified_thermal_storage import calculate_capacities +from oemof.thermal.stratified_thermal_storage import calculate_losses from oemof.thermal.stratified_thermal_storage import ( - calculate_storage_u_value, calculate_storage_dimensions, - calculate_capacities, - calculate_losses, ) -from oemof.solph import processing, Bus, Flow, Model, EnergySystem -from oemof.solph.components import GenericStorage, Source, Sink +from oemof.thermal.stratified_thermal_storage import calculate_storage_u_value def operation_example(): diff --git a/examples/stratified_thermal_storage/plots.py b/examples/stratified_thermal_storage/plots.py index 9d3b1934..e9ae3b4b 100644 --- a/examples/stratified_thermal_storage/plots.py +++ b/examples/stratified_thermal_storage/plots.py @@ -6,18 +6,23 @@ """ import os -import pandas as pd -import matplotlib.pyplot as plt +import matplotlib.pyplot as plt +import pandas as pd +from oemof.solph import Bus +from oemof.solph import EnergySystem +from oemof.solph import Flow +from oemof.solph import Model +from oemof.solph import processing +from oemof.solph import views +from oemof.solph.components import GenericStorage +from oemof.thermal.stratified_thermal_storage import calculate_capacities +from oemof.thermal.stratified_thermal_storage import calculate_losses from oemof.thermal.stratified_thermal_storage import ( - calculate_storage_u_value, calculate_storage_dimensions, - calculate_capacities, - calculate_losses, ) -from oemof.solph import processing, views, Bus, Flow, Model, EnergySystem -from oemof.solph.components import GenericStorage +from oemof.thermal.stratified_thermal_storage import calculate_storage_u_value def plots(): diff --git a/pyproject.toml b/pyproject.toml index 9e08f5d0..f907aba7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,5 +52,6 @@ line-length = 79 target-version = ['py39', 'py310', 'py311'] [tool.isort] +profile = "black" force_single_line = true line_length = 79 diff --git a/src/oemof/thermal/__init__.py b/src/oemof/thermal/__init__.py index 7cdb57f2..0f76c415 100644 --- a/src/oemof/thermal/__init__.py +++ b/src/oemof/thermal/__init__.py @@ -1,15 +1,13 @@ __version__ = "0.0.7.dev0" __project__ = "oemof.thermal" -from . import ( - absorption_heatpumps_and_chillers, - cogeneration, - compression_heatpumps_and_chillers, - concentrating_solar_power, - facades, - solar_thermal_collector, - stratified_thermal_storage, -) +from . import absorption_heatpumps_and_chillers +from . import cogeneration +from . import compression_heatpumps_and_chillers +from . import concentrating_solar_power +from . import facades +from . import solar_thermal_collector +from . import stratified_thermal_storage __all__ = [ "absorption_heatpumps_and_chillers", diff --git a/src/oemof/thermal/absorption_heatpumps_and_chillers.py b/src/oemof/thermal/absorption_heatpumps_and_chillers.py index a5d5ff43..1ab63934 100644 --- a/src/oemof/thermal/absorption_heatpumps_and_chillers.py +++ b/src/oemof/thermal/absorption_heatpumps_and_chillers.py @@ -3,9 +3,9 @@ """ This module is designed to hold functions for calculating absorption chillers. -This file is part of project oemof (github.com/oemof/oemof-thermal). It's copyrighted -by the contributors recorded in the version control history of the file, -available from its original location: +This file is part of project oemof (github.com/oemof/oemof-thermal). It's +copyrighted by the contributors recorded in the version control history of the +file, available from its original location: oemof-thermal/src/oemof/thermal/absorption_heatpumps_and_chillers.py SPDX-License-Identifier: MIT @@ -23,7 +23,8 @@ def calc_characteristic_temp(t_hot, t_cool, t_chill, coef_a, coef_e, method): Parameters ---------- t_hot : numeric - External arithmetic mean fluid temperature of hot water at heat exchanger (generator) [K] + External arithmetic mean fluid temperature of hot water at heat + exchanger (generator) [K] t_cool : numeric External arithmetic mean fluid temperature of cooling water at diff --git a/src/oemof/thermal/cogeneration.py b/src/oemof/thermal/cogeneration.py index 897f42a4..029f56ae 100644 --- a/src/oemof/thermal/cogeneration.py +++ b/src/oemof/thermal/cogeneration.py @@ -1,12 +1,13 @@ # -*- coding: utf-8 """ -This module is designed to hold functions for pre- and postprocessing for combined heat -and power plants. +This module is designed to hold functions for pre- and postprocessing for +combined heat and power plants. -This file is part of project oemof (github.com/oemof/oemof-thermal). It's copyrighted -by the contributors recorded in the version control history of the file, -available from its original location: oemof-thermal/src/oemof/thermal/chp.py +This file is part of project oemof (github.com/oemof/oemof-thermal). It's +copyrighted by the contributors recorded in the version control history of the +file, available from its original location: +oemof-thermal/src/oemof/thermal/chp.py SPDX-License-Identifier: MIT """ @@ -14,8 +15,8 @@ def allocate_emissions(total_emissions, eta_el, eta_th, method, **kwargs): r""" - Function to allocate emissions caused in cogeneration to the products electrical energy - and heat according to specified method. + Function to allocate emissions caused in cogeneration to the products + electrical energy and heat according to specified method. .. allocate_emissions-equations: @@ -39,17 +40,19 @@ def allocate_emissions(total_emissions, eta_el, eta_th, method, **kwargs): with - :math:`PEE = 1 - \frac{1}{\frac{\eta_{th}}{\eta_{th,ref}}+\frac{\eta_{el}}{\eta_{el,ref}}}`. + :math:`PEE = 1 - \frac{1}{\frac{\eta_{th}}{\eta_{th,ref}}+\frac{\eta_{el}} {\eta_{el,ref}}}`. Reference: Mauch, W., Corradini, R., Wiesmeyer, K., Schwentzek, M. (2010). - Allokationsmethoden für spezifische CO2-Emissionen von Strom und Waerme aus KWK-Anlagen. + Allokationsmethoden für spezifische CO2-Emissionen von Strom und Waerme + aus KWK-Anlagen. Energiewirtschaftliche Tagesfragen, 55(9), 12–14. Parameters ---------- total_emissions : numeric - Total absolute emissions to be allocated to electricity and heat [in CO2 equivalents]. + Total absolute emissions to be allocated to electricity and heat + [in CO2 equivalents]. eta_el : numeric Electrical efficiency of the cogeneration [-]. @@ -58,16 +61,18 @@ def allocate_emissions(total_emissions, eta_el, eta_th, method, **kwargs): Thermal efficiency of the cogeneration [-]. method : str - Specification of method to use. Choose from ['iea', finnish', 'efficiency']. + Specification of method to use. Choose from + ['iea', finnish', 'efficiency']. **kwargs - For the finnish method, `eta_el_ref` and `eta_th_ref` have to be passed. + For the finnish method, `eta_el_ref` and `eta_th_ref` have to be + passed. Returns ------- allocated_emissions_electricity : numeric - total emissions allocated to electricity according to specified `method` - [in CO2 equivalents]. + total emissions allocated to electricity according to specified + `method` [in CO2 equivalents]. allocated_emissions_heat : numeric total emissions allocated to heat according to specified `method` @@ -99,7 +104,8 @@ def allocate_emissions(total_emissions, eta_el, eta_th, method, **kwargs): eta_th_ref = kwargs.get("eta_th_ref") else: raise ValueError( - "Must specify eta_el_ref, eta_th_ref when using finnish method." + "Must specify eta_el_ref, eta_th_ref" + " when using finnish method." ) pee = 1 - 1 / ((eta_el / eta_el_ref) + (eta_th / eta_th_ref)) diff --git a/src/oemof/thermal/compression_heatpumps_and_chillers.py b/src/oemof/thermal/compression_heatpumps_and_chillers.py index 0c16180f..514710ab 100644 --- a/src/oemof/thermal/compression_heatpumps_and_chillers.py +++ b/src/oemof/thermal/compression_heatpumps_and_chillers.py @@ -4,9 +4,9 @@ This module provides functions to calculate compression heat pumps and compression chillers. -This file is part of project oemof (github.com/oemof/oemof-thermal). It's copyrighted -by the contributors recorded in the version control history of the file, -available from its original location: +This file is part of project oemof (github.com/oemof/oemof-thermal). It's +copyrighted by the contributors recorded in the version control history of the +file, available from its original location: oemof-thermal/src/oemof/thermal/compression_heatpumps_and_chillers.py SPDX-License-Identifier: MIT diff --git a/src/oemof/thermal/concentrating_solar_power.py b/src/oemof/thermal/concentrating_solar_power.py index abbb3565..c9b1ad94 100644 --- a/src/oemof/thermal/concentrating_solar_power.py +++ b/src/oemof/thermal/concentrating_solar_power.py @@ -3,9 +3,9 @@ """ This module is designed to hold functions which are necessary for the CSP. -This file is part of project oemof (github.com/oemof/oemof-thermal). It's copyrighted -by the contributors recorded in the version control history of the file, -available from its original location: +This file is part of project oemof (github.com/oemof/oemof-thermal). It's +copyrighted by the contributors recorded in the version control history of the +file, available from its original location: oemof-thermal/src/oemof/thermal/concentrating_solar_power.py SPDX-License-Identifier: MIT diff --git a/src/oemof/thermal/facades.py b/src/oemof/thermal/facades.py index 9d0a8f5a..b9a13f44 100644 --- a/src/oemof/thermal/facades.py +++ b/src/oemof/thermal/facades.py @@ -5,14 +5,17 @@ `_ Facade's are classes providing a simplified view on more complex classes. -More specifically, the :class:`Facade` s in this module inherit from `oemof.solph`'s generic -classes to serve as more concrete and energy specific interface. - -The concept of the facades has been derived from oemof.tabular. The idea is to be able to -instantiate a :class:`Facade` using only keyword arguments. Under the hood the :class:`Facade` then -uses these arguments to construct an `oemof.solph` component and sets it up to be easily used in an -:class:`EnergySystem`. Usually, a subset of the attributes of the parent class remains while another -part can be addressed by more specific or simpler attributes. +More specifically, the :class:`Facade` s in this module inherit from +`oemof.solph`'s generic classes to serve as more concrete and energy specific +interface. + +The concept of the facades has been derived from oemof.tabular. The idea is to +be able to instantiate a :class:`Facade` using only keyword arguments. Under +the hood the :class:`Facade` then uses these arguments to construct an +`oemof.solph` component and sets it up to be easily used in an +:class:`EnergySystem`. Usually, a subset of the attributes of the parent class +remains while another part can be addressed by more specific or simpler +attributes. **Note** The mathematical notation is as follows: @@ -28,15 +31,19 @@ from oemof.network.energy_system import EnergySystem from oemof.network.network import Node -from oemof.solph import Flow, Investment, sequence -from oemof.solph.components import GenericStorage, Source, Transformer +from oemof.solph import Flow +from oemof.solph import Investment +from oemof.solph import sequence +from oemof.solph.components import GenericStorage +from oemof.solph.components import Source +from oemof.solph.components import Transformer from oemof.tools.debugging import SuspiciousUsageWarning from oemof.thermal.concentrating_solar_power import csp_precalc from oemof.thermal.solar_thermal_collector import flat_plate_precalc +from oemof.thermal.stratified_thermal_storage import calculate_capacities +from oemof.thermal.stratified_thermal_storage import calculate_losses from oemof.thermal.stratified_thermal_storage import ( - calculate_capacities, - calculate_losses, calculate_storage_dimensions, ) @@ -182,9 +189,9 @@ class StratifiedThermalStorage(GenericStorage, Facade): more information on possible parameters) - The attribute :attr:`nominal_storage_capacity` of the base class :class:`GenericStorage` - should not be passed because it is determined internally from :attr:`height` - and :attr:`parameter`. + The attribute :attr:`nominal_storage_capacity` of the base class + :class:`GenericStorage` should not be passed because it is determined + internally from :attr:`height` and :attr:`parameter`. Examples --------- @@ -411,9 +418,11 @@ class ParabolicTroughCollector(Transformer, Facade): heat_bus: oemof.solph.Bus An oemof bus instance in which absorbs the collectors heat. electrical_bus: oemof.solph.Bus - An oemof bus instance which provides electrical energy to the collector. + An oemof bus instance which provides electrical energy to the + collector. electrical_consumption: numeric - Specifies how much electrical energy is used per provided thermal energy. + Specifies how much electrical energy is used per provided thermal + energy. additional_losses: numeric Specifies how much thermal energy is lost in peripheral parts like pipes and pumps. @@ -606,17 +615,19 @@ class SolarThermalCollector(Transformer, Facade): heat_out_bus: oemof.solph.Bus An oemof bus instance which absorbs the collectors heat. electrical_in_bus: oemof.solph.Bus - An oemof bus instance which provides electrical energy to the collector. + An oemof bus instance which provides electrical energy to the + collector. electrical_consumption: numeric - Specifies how much electrical energy is used per provided thermal energy. + Specifies how much electrical energy is used per provided thermal + energy. peripheral_losses: numeric Specifies how much thermal energy is lost in peripheral parts like pipes and pumps as percentage of provided thermal energy. aperture_area: numeric Specifies the size of the collector as surface area. - See the API of flat_plate_precalc in oemof.thermal.solar_thermal_collector for - the other parameters. + See the API of flat_plate_precalc in oemof.thermal.solar_thermal_collector + for the other parameters. Example: ---------- @@ -714,7 +725,8 @@ def build_solph_components(self): if self.expandable: raise NotImplementedError( - "Investment for solar thermal collector facade has not been implemented yet." + "Investment for solar thermal collector" + " facade has not been implemented yet." ) inflow = Source( diff --git a/src/oemof/thermal/solar_thermal_collector.py b/src/oemof/thermal/solar_thermal_collector.py index 8edc65e6..814889d0 100644 --- a/src/oemof/thermal/solar_thermal_collector.py +++ b/src/oemof/thermal/solar_thermal_collector.py @@ -1,11 +1,12 @@ # -*- coding: utf-8 """ -This module is designed to hold functions for calculating a solar thermal collector. +This module is designed to hold functions for calculating a solar thermal +collector. -This file is part of project oemof (github.com/oemof/oemof-thermal). It's copyrighted -by the contributors recorded in the version control history of the file, -available from its original location: +This file is part of project oemof (github.com/oemof/oemof-thermal). It's +copyrighted by the contributors recorded in the version control history of the +file, available from its original location: oemof-thermal/src/oemof/thermal/solar_thermal_collector.py SPDX-License-Identifier: MIT @@ -50,7 +51,8 @@ def flat_plate_precalc( The tilt of the collector. collector_azimuth: numeric - The azimuth of the collector. Azimuth according to pvlib in decimal degrees East of North. + The azimuth of the collector. Azimuth according to pvlib in decimal + degrees East of North. eta_0: numeric Optical efficiency of the collector. diff --git a/src/oemof/thermal/stratified_thermal_storage.py b/src/oemof/thermal/stratified_thermal_storage.py index 63e120c0..318c2f3e 100644 --- a/src/oemof/thermal/stratified_thermal_storage.py +++ b/src/oemof/thermal/stratified_thermal_storage.py @@ -1,11 +1,12 @@ # -*- coding: utf-8 """ -This module is designed to hold functions for calculating stratified thermal storages. +This module is designed to hold functions for calculating stratified thermal +storages. -This file is part of project oemof (github.com/oemof/oemof-thermal). It's copyrighted -by the contributors recorded in the version control history of the file, -available from its original location: +This file is part of project oemof (github.com/oemof/oemof-thermal). It's +copyrighted by the contributors recorded in the version control history of the +file, available from its original location: oemof-thermal/src/oemof/thermal/stratified_thermal_storage.py SPDX-License-Identifier: MIT @@ -32,10 +33,12 @@ def calculate_storage_u_value(s_iso, lamb_iso, alpha_inside, alpha_outside): Thermal conductivity of isolation layer [W/(m*K)] alpha_inside : numeric - Heat transfer coefficient at the inner surface of the storage [W/(m2*K)] + Heat transfer coefficient at the inner surface of the storage + [W/(m2*K)] alpha_outside : numeric - Heat transfer coefficient at the outer surface of the storage [W/(m2*K)] + Heat transfer coefficient at the outer surface of the storage + [W/(m2*K)] Returns ------- diff --git a/tests/test_functions.py b/tests/test_functions.py index 865f71ae..47a799c8 100644 --- a/tests/test_functions.py +++ b/tests/test_functions.py @@ -9,16 +9,14 @@ import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chllr import oemof.thermal.concentrating_solar_power as csp from oemof.thermal.cogeneration import allocate_emissions -from oemof.thermal.solar_thermal_collector import ( - calc_eta_c_flate_plate, - flat_plate_precalc, -) +from oemof.thermal.solar_thermal_collector import calc_eta_c_flate_plate +from oemof.thermal.solar_thermal_collector import flat_plate_precalc +from oemof.thermal.stratified_thermal_storage import calculate_capacities +from oemof.thermal.stratified_thermal_storage import calculate_losses from oemof.thermal.stratified_thermal_storage import ( - calculate_capacities, - calculate_losses, calculate_storage_dimensions, - calculate_storage_u_value, ) +from oemof.thermal.stratified_thermal_storage import calculate_storage_u_value def test_cop_calculation_hp(): From 2365aefbd07c07adc104b0c8473351af35beea98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 16:15:38 +0200 Subject: [PATCH 20/34] Ignore line lenght in flake8 check Flake8 also checks comments, but Black does not enforce this. I would allow long comments for now. --- tox.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tox.ini b/tox.ini index bbbaac9c..eb4c1743 100644 --- a/tox.ini +++ b/tox.ini @@ -138,3 +138,6 @@ deps = [testenv:py3-nocov] basepython = {env:TOXPYTHON:python3} + +[flake8] +extend-ignore = E501 From 1d7cc15e657a94838d5e67652837a49fff59d864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 16:16:08 +0200 Subject: [PATCH 21/34] Ignore vscode directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 61d921f1..179b09a5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ __pycache__/ .Python env/ .venv/ +.vscode/ venv/ build/ develop-eggs/ From ac9337b632169a7f9271c0886137dfa70eaa830c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 16:53:32 +0200 Subject: [PATCH 22/34] Fix links in documentation --- docs/compression_heat_pumps_and_chillers.rst | 2 +- docs/examples.rst | 4 ++-- docs/getting_started.rst | 4 ++-- src/oemof/thermal/facades.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/compression_heat_pumps_and_chillers.rst b/docs/compression_heat_pumps_and_chillers.rst index 5d466511..1a710c97 100644 --- a/docs/compression_heat_pumps_and_chillers.rst +++ b/docs/compression_heat_pumps_and_chillers.rst @@ -166,7 +166,7 @@ Do NOT use this function to determine the input for `calc_cops()`! References __________ -.. [1] VDE ETG Energietechnik, VDE-Studie "Potenziale für Strom im Wärmemarkt bis 2050 - Wärmeversorgung in flexiblen Energieversorgungssystemen mit hohen Anteilen an erneuerbaren Energien". 2015. (http://www.energiedialog2050.de/BASE/DOWNLOADS/VDE_ST_ETG_Warmemarkt_RZ-web.pdf) +.. [1] VDE ETG Energietechnik, VDE-Studie "Potenziale für Strom im Wärmemarkt bis 2050 - Wärmeversorgung in flexiblen Energieversorgungssystemen mit hohen Anteilen an erneuerbaren Energien". 2015. .. [2] C. Arpagaus, Hochtemperatur-Wärmepumpen - Marktübersicht, Stand der Technik und Anwendungsbeispiele. Berlin, Offenbach: VDE-Verlag, 2019. diff --git a/docs/examples.rst b/docs/examples.rst index 6fd58b2a..14e7a368 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -32,7 +32,7 @@ In addition to that, the example provides a manual on using the 'calc_cops' func to get the COPs of a heat pump, by plotting the temperature dependency of the COP, and COPs of an exemplary ground-source heat pump (GSHP) using the soil temperature as low temperature heat reservoir. -The Examples can be found `at compression_heatpumps_and_chiller `_. +The Examples can be found `at compression_heatpumps_and_chiller `_. **Absorption Chiller** @@ -40,7 +40,7 @@ The first example shows the behaviour of the coefficient of performance and heat for different cooling water temperatures based on the characteristic equation method. The second example underlines the dependence of the temperature of the cooling water on the cooling capacity. -The Examples can be found `at absorption_heatpumps_and_chiller `_. +The Examples can be found `at absorption_heatpumps_and_chiller `_. **Concentrating solar power (CSP)** diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 4a52c41d..8ec41f2c 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -87,5 +87,5 @@ enhancements. Or you can contribute a new approach that helps to model thermal e systems. If you want to contribute, fork the project at github, develop your features on a new branch and finally open a pull request to merge your contribution to oemof.thermal. -As oemof.thermal is part of the oemof developer group we use the same developer rules, described -`here `_. +As oemof.thermal is part of the oemof developer group we use the same developer rules, +described in the `oemof documentation `_. diff --git a/src/oemof/thermal/facades.py b/src/oemof/thermal/facades.py index b9a13f44..905f8183 100644 --- a/src/oemof/thermal/facades.py +++ b/src/oemof/thermal/facades.py @@ -2,7 +2,7 @@ """ Adapted from `oemof.tabular's facades -`_ +`_ Facade's are classes providing a simplified view on more complex classes. More specifically, the :class:`Facade` s in this module inherit from From cfa706697c09cb1d0e2313f1373454f37d898a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 17:12:53 +0200 Subject: [PATCH 23/34] Remove unused variables --- .../absorption_heatpump_and_chiller/absorption_chiller.py | 4 +--- .../cooling_cap_dependence_on_cooling_water_temp.py | 6 +++--- examples/cogeneration/emission_allocation_methods.py | 2 +- .../airsource_heatpump_const_max_output.py | 2 +- .../airsource_heatpump_variable_max_output.py | 5 +---- .../groundsource_heatpump.py | 3 +-- examples/concentrating_solar_power/csp_collector_plot.py | 4 +--- .../concentrating_solar_power/csp_collector_plot_andasol.py | 6 ++---- examples/concentrating_solar_power/csp_facade.py | 2 +- examples/concentrating_solar_power/csp_plant.py | 2 +- examples/solar_thermal_collector/_plots.py | 2 +- .../solar_thermal_collector/flat_plate_collector_facade.py | 2 +- .../investment_fixed_ratio_facade.py | 5 ----- .../investment_fixed_ratio_generic_storage.py | 3 --- .../investment_independent_facade.py | 3 --- .../investment_independent_generic_storage.py | 4 ---- examples/stratified_thermal_storage/model_validation.py | 2 +- examples/stratified_thermal_storage/operation_facade.py | 3 --- examples/stratified_thermal_storage/plots.py | 2 +- src/oemof/thermal/compression_heatpumps_and_chillers.py | 4 ++-- 20 files changed, 19 insertions(+), 47 deletions(-) diff --git a/examples/absorption_heatpump_and_chiller/absorption_chiller.py b/examples/absorption_heatpump_and_chiller/absorption_chiller.py index b160ae1d..0664491c 100644 --- a/examples/absorption_heatpump_and_chiller/absorption_chiller.py +++ b/examples/absorption_heatpump_and_chiller/absorption_chiller.py @@ -10,7 +10,6 @@ def absorption_chiller_example(): solver = "cbc" - debug = False number_of_time_steps = 48 solver_verbose = True @@ -133,9 +132,8 @@ def absorption_chiller_example(): demand_cooling = string_results["chilled", "cooling_demand"][ "sequences" ].values - ASHP_input = string_results["hot", "AC"]["sequences"].values - fig2, axs = plt.subplots(3, 1, figsize=(8, 5), sharex=True) + _, axs = plt.subplots(3, 1, figsize=(8, 5), sharex=True) axs[0].plot(AC_output, label="cooling output") axs[0].plot(demand_cooling, linestyle="--", label="cooling demand") axs[1].plot(COPs, linestyle="-.") diff --git a/examples/absorption_heatpump_and_chiller/cooling_cap_dependence_on_cooling_water_temp.py b/examples/absorption_heatpump_and_chiller/cooling_cap_dependence_on_cooling_water_temp.py index cfaec66c..bece0f81 100644 --- a/examples/absorption_heatpump_and_chiller/cooling_cap_dependence_on_cooling_water_temp.py +++ b/examples/absorption_heatpump_and_chiller/cooling_cap_dependence_on_cooling_water_temp.py @@ -59,7 +59,7 @@ def cooling_cap_example(): ax1 = fig1.add_subplot(111) ax1.grid(axis="y") - line1 = ax1.plot( + ax1.plot( t_cooling, Q_dots_evap_80, linestyle="dotted", @@ -67,7 +67,7 @@ def cooling_cap_example(): color="black", label="Cooling capacity ($80°$C driving heat)", ) - line2 = ax1.plot( + ax1.plot( t_cooling, Q_dots_evap_75, linestyle="dashed", @@ -77,7 +77,7 @@ def cooling_cap_example(): ) plt.ylabel("Cooling capacity in kW") ax2 = fig1.add_subplot(111, sharex=ax1, frameon=False) - line3 = ax2.plot( + ax2.plot( t_cooling, COPs_75, linestyle="-", diff --git a/examples/cogeneration/emission_allocation_methods.py b/examples/cogeneration/emission_allocation_methods.py index 4998f18d..3f7fd332 100644 --- a/examples/cogeneration/emission_allocation_methods.py +++ b/examples/cogeneration/emission_allocation_methods.py @@ -32,7 +32,7 @@ def emission_allocation_example(): # Example plot fig, ax = plt.subplots() df.loc[:, "el"] *= -1 - bars = df.plot.barh(stacked=True, ax=ax) + df.plot.barh(stacked=True, ax=ax) for i, (el, th) in enumerate(zip(df["el"], df["th"])): ax.text(el, i, round(-el), ha="left") diff --git a/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py b/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py index 9c0cc0b0..1a7d7a0a 100644 --- a/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py +++ b/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py @@ -113,7 +113,7 @@ def airource_hp_const_example(): ASHP_input = string_results["electricity", "ASHP"]["sequences"].values # Example plot - fig, axs = plt.subplots(3, 1, figsize=(8, 5), sharex=True) + _, axs = plt.subplots(3, 1, figsize=(8, 5), sharex=True) axs[0].plot(ASHP_output, label="heat output") axs[0].plot(demand_h, linestyle="--", label="heat demand") axs[1].plot(cops_ASHP, linestyle="-.") diff --git a/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py b/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py index 9aea6cde..c7334238 100644 --- a/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py +++ b/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py @@ -117,9 +117,6 @@ def airource_hp_variable_example(): results = energysystem.results["main"] - electricity_bus = solph.views.node(results, "electricity") - heat_bus = solph.views.node(results, "heat") - string_results = solph.views.convert_keys_to_strings( energysystem.results["main"] ) @@ -134,7 +131,7 @@ def airource_hp_variable_example(): ] # Example plot - fig, axs = plt.subplots(3, 1, figsize=(8, 5), sharex=True) + _, axs = plt.subplots(3, 1, figsize=(8, 5), sharex=True) axs[0].plot(max_Q_dot_heating_abs, linestyle="-.", label="max heat output") axs[0].plot(ASHP_output, label="actual heat output") axs[0].plot(demand_h, linestyle="--", label="heat demand") diff --git a/examples/compression_heatpump_and_chiller/groundsource_heatpump.py b/examples/compression_heatpump_and_chiller/groundsource_heatpump.py index 691850e9..0b40179c 100644 --- a/examples/compression_heatpump_and_chiller/groundsource_heatpump.py +++ b/examples/compression_heatpump_and_chiller/groundsource_heatpump.py @@ -119,11 +119,10 @@ def groundsource_hp_example(): ) GSHP_output = string_results["GSHP", "heat"]["sequences"].values demand_h = string_results["heat", "demand"]["sequences"].values - GSHP_input = string_results["electricity", "GSHP"]["sequences"].values env_heat = string_results["ambient", "heat_low_temp"]["sequences"].values # Example plot - fig2, axs = plt.subplots(3, 1, figsize=(8, 5), sharex=True) + _, axs = plt.subplots(3, 1, figsize=(8, 5), sharex=True) axs[0].plot(GSHP_output, label="heat output") axs[0].plot(demand_h, linestyle="--", label="heat demand") axs[0].plot(env_heat, label="heat from environment") diff --git a/examples/concentrating_solar_power/csp_collector_plot.py b/examples/concentrating_solar_power/csp_collector_plot.py index 1aa582b1..02673e34 100644 --- a/examples/concentrating_solar_power/csp_collector_plot.py +++ b/examples/concentrating_solar_power/csp_collector_plot.py @@ -45,10 +45,8 @@ def csp_collector_example(): )["t_amb"] # Parameters for the precalculation - periods = 24 latitude = 23.614328 longitude = 58.545284 - timezone = "Asia/Muscat" collector_tilt = 10 collector_azimuth = 180 cleanliness = 0.9 @@ -123,7 +121,7 @@ def csp_collector_example(): df_result = df_result.append(data_precalc_temp_amb, ignore_index=True) - fig, ax = plt.subplots() + _, ax = plt.subplots() ax.plot( temp_amb_series, df_result["eta_c"], diff --git a/examples/concentrating_solar_power/csp_collector_plot_andasol.py b/examples/concentrating_solar_power/csp_collector_plot_andasol.py index 45afa8fe..b28b0b8c 100644 --- a/examples/concentrating_solar_power/csp_collector_plot_andasol.py +++ b/examples/concentrating_solar_power/csp_collector_plot_andasol.py @@ -45,10 +45,8 @@ def csp_andasol_example(): )["t_amb"] # Parameters for the precalculation - periods = 24 latitude = 23.614328 longitude = 58.545284 - timezone = "Asia/Muscat" collector_tilt = 10 collector_azimuth = 180 cleanliness = 0.9 @@ -97,7 +95,7 @@ def csp_andasol_example(): t = list(range(1, 25)) # Example plot - fig, ax = plt.subplots() + _, ax = plt.subplots() ax.plot(t, heat_calc, label="CSP precalculation") ax.plot(t, heat_compare, label="constant efficiency") ax.set( @@ -138,7 +136,7 @@ def csp_andasol_example(): df_result = df_result.append(data_precalc_temp_amb, ignore_index=True) - fig, ax = plt.subplots() + _, ax = plt.subplots() ax.plot( temp_amb_series, df_result["eta_c"], diff --git a/examples/concentrating_solar_power/csp_facade.py b/examples/concentrating_solar_power/csp_facade.py index e1673dac..a1c51aa2 100644 --- a/examples/concentrating_solar_power/csp_facade.py +++ b/examples/concentrating_solar_power/csp_facade.py @@ -172,7 +172,7 @@ def csp_facade_example(): df.to_csv(os.path.join(results_path, "facade_results.csv")) # Example plot - fig, ax = plt.subplots() + _, ax = plt.subplots() ax.plot( list(range(periods)), thermal_bus[(("solar_collector", "thermal"), "flow")][:-1], diff --git a/examples/concentrating_solar_power/csp_plant.py b/examples/concentrating_solar_power/csp_plant.py index 81573994..9a9e264e 100644 --- a/examples/concentrating_solar_power/csp_plant.py +++ b/examples/concentrating_solar_power/csp_plant.py @@ -204,7 +204,7 @@ def csp_plant_example(): df.to_csv(os.path.join(results_path, "csp_plant_results.csv")) # Example plot - fig, ax = plt.subplots() + _, ax = plt.subplots() ax.plot( list(range(periods)), thermal_bus[(("collector", "thermal"), "flow")][:-1], diff --git a/examples/solar_thermal_collector/_plots.py b/examples/solar_thermal_collector/_plots.py index eaf2e35c..a2d206d0 100644 --- a/examples/solar_thermal_collector/_plots.py +++ b/examples/solar_thermal_collector/_plots.py @@ -19,7 +19,7 @@ def plot_collector_heat(data_precalc, periods, eta_0): heat_compare = irradiance_on_collector * eta_0 t = list(range(1, periods + 1)) - fig, ax = plt.subplots() + _, ax = plt.subplots() ax.plot(t, heat_calc, label="Solar thermal precalculation") ax.plot(t, heat_compare, label="constant efficiency") ax.set( diff --git a/examples/solar_thermal_collector/flat_plate_collector_facade.py b/examples/solar_thermal_collector/flat_plate_collector_facade.py index 1a0c017c..4950f9dd 100644 --- a/examples/solar_thermal_collector/flat_plate_collector_facade.py +++ b/examples/solar_thermal_collector/flat_plate_collector_facade.py @@ -156,7 +156,7 @@ def flat_plate_collector_facade_example(): heat_calc = collector_inflow t = list(range(1, periods + 1)) - fig, ax = plt.subplots() + _, ax = plt.subplots() ax.plot(t, heat_calc[:-1]) ax.set( xlabel="time in h", ylabel="Q_coll in W", title="Heat of the collector" diff --git a/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py b/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py index 0b1aef13..faa4b6f6 100644 --- a/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py +++ b/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py @@ -100,15 +100,10 @@ def fixed_ratio_invest_facade_example(): results = processing.results(optimization_model) string_results = processing.convert_keys_to_strings(results) sequences = {k: v["sequences"] for k, v in string_results.items()} - df = pd.concat(sequences, axis=1) - # Print storage sizing built_storage_capacity = results[thermal_storage, None]["scalars"][ "invest" ] - initial_storage_capacity = results[thermal_storage, None]["scalars"][ - "init_content" - ] maximum_heat_flow_charging = results[bus_heat, thermal_storage]["scalars"][ "invest" ] diff --git a/examples/stratified_thermal_storage/investment_fixed_ratio_generic_storage.py b/examples/stratified_thermal_storage/investment_fixed_ratio_generic_storage.py index 8942a893..f6c5f0c1 100644 --- a/examples/stratified_thermal_storage/investment_fixed_ratio_generic_storage.py +++ b/examples/stratified_thermal_storage/investment_fixed_ratio_generic_storage.py @@ -138,9 +138,6 @@ def print_parameters(): built_storage_capacity = results[thermal_storage, None]["scalars"][ "invest" ] - initial_storage_capacity = results[thermal_storage, None]["scalars"][ - "init_content" - ] maximum_heat_flow_charging = results[bus_heat, thermal_storage]["scalars"][ "invest" ] diff --git a/examples/stratified_thermal_storage/investment_independent_facade.py b/examples/stratified_thermal_storage/investment_independent_facade.py index a6c973d0..f82c986a 100644 --- a/examples/stratified_thermal_storage/investment_independent_facade.py +++ b/examples/stratified_thermal_storage/investment_independent_facade.py @@ -108,9 +108,6 @@ def invest_independent_facade_example(): built_storage_capacity = results[thermal_storage, None]["scalars"][ "invest" ] - initial_storage_capacity = results[thermal_storage, None]["scalars"][ - "init_content" - ] built_capacity = results[bus_heat, thermal_storage]["scalars"]["invest"] dash = "-" * 50 diff --git a/examples/stratified_thermal_storage/investment_independent_generic_storage.py b/examples/stratified_thermal_storage/investment_independent_generic_storage.py index e59ea9bc..69da13f4 100644 --- a/examples/stratified_thermal_storage/investment_independent_generic_storage.py +++ b/examples/stratified_thermal_storage/investment_independent_generic_storage.py @@ -132,15 +132,11 @@ def print_parameters(): results = processing.results(optimization_model) string_results = processing.convert_keys_to_strings(results) sequences = {k: v["sequences"] for k, v in string_results.items()} - df = pd.concat(sequences, axis=1) # Print storage sizing built_storage_capacity = results[thermal_storage, None]["scalars"][ "invest" ] - initial_storage_capacity = results[thermal_storage, None]["scalars"][ - "init_content" - ] maximum_heat_flow_charging = results[bus_heat, thermal_storage]["scalars"][ "invest" ] diff --git a/examples/stratified_thermal_storage/model_validation.py b/examples/stratified_thermal_storage/model_validation.py index 014e25cc..476da7b8 100644 --- a/examples/stratified_thermal_storage/model_validation.py +++ b/examples/stratified_thermal_storage/model_validation.py @@ -160,7 +160,7 @@ def run_storage_model(initial_storage_level, temp_h, temp_c): t_meas = np.arange(0, (len(level_meas) / 4), 0.25) plt.style.use("ggplot") - fig, ax = plt.subplots() + _, ax = plt.subplots() # Plot horizontal line (initial level) init_level = level_meas["level"][0] diff --git a/examples/stratified_thermal_storage/operation_facade.py b/examples/stratified_thermal_storage/operation_facade.py index cbd70ea2..0ace2c97 100644 --- a/examples/stratified_thermal_storage/operation_facade.py +++ b/examples/stratified_thermal_storage/operation_facade.py @@ -106,9 +106,6 @@ def print_parameters(): bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage ) - # Create and solve the optimization model - optimization_model = Model(energysystem) - if __name__ == "__main__": operation_facade_example() diff --git a/examples/stratified_thermal_storage/plots.py b/examples/stratified_thermal_storage/plots.py index e9ae3b4b..99ac2673 100644 --- a/examples/stratified_thermal_storage/plots.py +++ b/examples/stratified_thermal_storage/plots.py @@ -188,7 +188,7 @@ def print_results(): storage_df = storage_df.reindex(sorted(storage_df.columns), axis=1) # Plot storage_content vs. time - fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) + _, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) storage_content.plot(ax=ax1) ax1.set_title("Storage content") ax1.set_xlabel("Timesteps") diff --git a/src/oemof/thermal/compression_heatpumps_and_chillers.py b/src/oemof/thermal/compression_heatpumps_and_chillers.py index 514710ab..5f0ff373 100644 --- a/src/oemof/thermal/compression_heatpumps_and_chillers.py +++ b/src/oemof/thermal/compression_heatpumps_and_chillers.py @@ -105,11 +105,11 @@ def calc_cops( length = max([len(temp_high), len(temp_low)]) if len(temp_high) == 1: list_temp_high_K = [temp_high[0] + 273.15] * length - elif len(temp_high) == length: + else: # len(temp_high) == length: list_temp_high_K = [t + 273.15 for t in temp_high] if len(temp_low) == 1: list_temp_low_K = [temp_low[0] + 273.15] * length - elif len(temp_low) == length: + else: # len(temp_low) == length: list_temp_low_K = [t + 273.15 for t in temp_low] # Calculate COPs depending on selected mode (without icing). From 939b80d74c1dd5e37d1cec8916c054a11a6c40c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 17:18:43 +0200 Subject: [PATCH 24/34] Remove unused variables --- .../airsource_heatpump_const_max_output.py | 5 ----- .../cop_dependence_on_temperature_difference.py | 3 --- examples/stratified_thermal_storage/operation_facade.py | 2 -- 3 files changed, 10 deletions(-) diff --git a/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py b/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py index 1a7d7a0a..10170b32 100644 --- a/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py +++ b/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py @@ -100,11 +100,6 @@ def airource_hp_const_example(): energysystem = solph.EnergySystem() energysystem.restore(dpath=None, filename=None) - results = energysystem.results["main"] - - electricity_bus = solph.views.node(results, "electricity") - heat_bus = solph.views.node(results, "heat") - string_results = solph.views.convert_keys_to_strings( energysystem.results["main"] ) diff --git a/examples/compression_heatpump_and_chiller/cop_dependence_on_temperature_difference.py b/examples/compression_heatpump_and_chiller/cop_dependence_on_temperature_difference.py index eb30d6c5..c26c6160 100644 --- a/examples/compression_heatpump_and_chiller/cop_dependence_on_temperature_difference.py +++ b/examples/compression_heatpump_and_chiller/cop_dependence_on_temperature_difference.py @@ -58,9 +58,6 @@ def cop_temperature_example(): temp_high - temp_diff_q for temp_diff_q in temperature_diff_q_grade ] for q in quality_grades: - list_temp_low = [ - temp_high - temp_diff_q for temp_diff_q in temperature_diff_q_grade - ] cops_q_grade[q] = cmpr_hp_chiller.calc_cops( temp_high=[temp_high], temp_low=list_temp_low_q_grade, diff --git a/examples/stratified_thermal_storage/operation_facade.py b/examples/stratified_thermal_storage/operation_facade.py index 0ace2c97..e3c55e43 100644 --- a/examples/stratified_thermal_storage/operation_facade.py +++ b/examples/stratified_thermal_storage/operation_facade.py @@ -10,7 +10,6 @@ from oemof.solph import Bus # noqa from oemof.solph import EnergySystem from oemof.solph import Flow -from oemof.solph import Model from oemof.solph.components import Sink from oemof.solph.components import Source @@ -58,7 +57,6 @@ def print_parameters(): print_parameters() # Set up an energy system model - solver = "cbc" periods = 100 datetimeindex = pd.date_range("1/1/2019", periods=periods, freq="H") demand_timeseries = np.zeros(periods) From a7ca9766c628653f972dbe999ea24f8f7fca86c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 17:20:04 +0200 Subject: [PATCH 25/34] Remove unused variables --- .../stratified_thermal_storage/investment_fixed_ratio_facade.py | 2 -- .../investment_independent_generic_storage.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py b/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py index faa4b6f6..e22d6211 100644 --- a/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py +++ b/examples/stratified_thermal_storage/investment_fixed_ratio_facade.py @@ -98,8 +98,6 @@ def fixed_ratio_invest_facade_example(): # Get results results = processing.results(optimization_model) - string_results = processing.convert_keys_to_strings(results) - sequences = {k: v["sequences"] for k, v in string_results.items()} # Print storage sizing built_storage_capacity = results[thermal_storage, None]["scalars"][ "invest" diff --git a/examples/stratified_thermal_storage/investment_independent_generic_storage.py b/examples/stratified_thermal_storage/investment_independent_generic_storage.py index 69da13f4..467883b9 100644 --- a/examples/stratified_thermal_storage/investment_independent_generic_storage.py +++ b/examples/stratified_thermal_storage/investment_independent_generic_storage.py @@ -130,8 +130,6 @@ def print_parameters(): # Get results results = processing.results(optimization_model) - string_results = processing.convert_keys_to_strings(results) - sequences = {k: v["sequences"] for k, v in string_results.items()} # Print storage sizing built_storage_capacity = results[thermal_storage, None]["scalars"][ From 2acef73328b775c9f671e0cb316710ef27b5ed71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 17:21:51 +0200 Subject: [PATCH 26/34] Remove unused variables --- .../airsource_heatpump_variable_max_output.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py b/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py index c7334238..c38eab96 100644 --- a/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py +++ b/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py @@ -115,8 +115,6 @@ def airource_hp_variable_example(): energysystem = solph.EnergySystem() energysystem.restore(dpath=None, filename=None) - results = energysystem.results["main"] - string_results = solph.views.convert_keys_to_strings( energysystem.results["main"] ) From ab59cfc4c7cd2cd939f7326a6101cee249a88d3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 20:37:21 +0200 Subject: [PATCH 27/34] Require a label for Facades This works around the problem that labels might be set inconsistently because of multi-inheritence. --- src/oemof/thermal/facades.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/oemof/thermal/facades.py b/src/oemof/thermal/facades.py index 905f8183..8577afff 100644 --- a/src/oemof/thermal/facades.py +++ b/src/oemof/thermal/facades.py @@ -63,7 +63,7 @@ class Facade(Node): raises an error if he doesn't find them. """ - def __init__(self, *_, **kwargs): + def __init__(self, label, **kwargs): """ """ self.mapped_type = type(self) @@ -72,7 +72,7 @@ def __init__(self, *_, **kwargs): required = kwargs.pop("_facade_requires_", []) - super().__init__(label=kwargs.get("label")) + super().__init__(label=label) self.subnodes = [] EnergySystem.signals[EnergySystem.add].connect( @@ -249,6 +249,7 @@ def __init__( ) Facade.__init__( self, + label=label, **kwargs, ) with warnings.catch_warnings(): @@ -469,7 +470,7 @@ def __init__(self, **kwargs): kwargs.update({"_facade_requires_": ["longitude"]}) Facade.__init__(self, **kwargs) - Transformer.__init__(self) + Transformer.__init__(self, label=kwargs.get("label")) self.heat_bus = kwargs.get("heat_bus") @@ -661,7 +662,7 @@ def __init__(self, **kwargs): kwargs.update({"_facade_requires_": ["longitude"]}) Facade.__init__(self, **kwargs) - Transformer.__init__(self) + Transformer.__init__(self, label=kwargs.get("label")) self.heat_out_bus = kwargs.get("heat_out_bus") From b60d34d9795f64789f8ec907fc0205c450ed1bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 20:48:57 +0200 Subject: [PATCH 28/34] Adapt constraint tests for multi-period invests --- ...atified_thermal_storage_invest_option_1.lp | 46 +++++++++---------- ...atified_thermal_storage_invest_option_2.lp | 46 +++++++++---------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/tests/lp_files/stratified_thermal_storage_invest_option_1.lp b/tests/lp_files/stratified_thermal_storage_invest_option_1.lp index 3226de26..426eb06d 100644 --- a/tests/lp_files/stratified_thermal_storage_invest_option_1.lp +++ b/tests/lp_files/stratified_thermal_storage_invest_option_1.lp @@ -25,50 +25,50 @@ c_e_BusBlock_balance(bus_heat_2)_: = 0 c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_0)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage) +-1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) +1 flow(bus_heat_thermal_storage_0) <= 0 c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_1)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage) +-1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) +1 flow(bus_heat_thermal_storage_1) <= 0 c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_2)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage) +-1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) +1 flow(bus_heat_thermal_storage_2) <= 0 c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_0)_: --1 InvestmentFlowBlock_invest(thermal_storage_bus_heat) +-1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) +1 flow(thermal_storage_bus_heat_0) <= 0 c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_1)_: --1 InvestmentFlowBlock_invest(thermal_storage_bus_heat) +-1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) +1 flow(thermal_storage_bus_heat_1) <= 0 c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_2)_: --1 InvestmentFlowBlock_invest(thermal_storage_bus_heat) +-1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) +1 flow(thermal_storage_bus_heat_2) <= 0 c_u_GenericInvestmentStorageBlock_init_content_limit(thermal_storage)_: +1 GenericInvestmentStorageBlock_init_content(thermal_storage) --1 GenericInvestmentStorageBlock_invest(thermal_storage) +-1 GenericInvestmentStorageBlock_invest(thermal_storage_0) <= 0 c_e_GenericInvestmentStorageBlock_balance_first(thermal_storage)_: +0.99982340904089895 GenericInvestmentStorageBlock_init_content(thermal_storage) --0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage) +-0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) +1 flow(bus_heat_thermal_storage_0) -1 flow(thermal_storage_bus_heat_0) = 0.0053014376029327757 c_e_GenericInvestmentStorageBlock_balance(thermal_storage_1)_: --0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage) +-0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage_0) +0.99982340904089895 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) +1 flow(bus_heat_thermal_storage_1) @@ -76,7 +76,7 @@ c_e_GenericInvestmentStorageBlock_balance(thermal_storage_1)_: = 0.0053014376029327757 c_e_GenericInvestmentStorageBlock_balance(thermal_storage_2)_: --0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage) +-0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage_0) +0.99982340904089895 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) +1 flow(bus_heat_thermal_storage_2) @@ -89,42 +89,42 @@ c_e_GenericInvestmentStorageBlock_balanced_cstr(thermal_storage)_: = 0 c_e_GenericInvestmentStorageBlock_power_coupled(thermal_storage)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage) -+1 InvestmentFlowBlock_invest(thermal_storage_bus_heat) +-1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) ++1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) = 0 c_e_GenericInvestmentStorageBlock_storage_capacity_inflow(thermal_storage)_: --0.16666666666666666 GenericInvestmentStorageBlock_invest(thermal_storage) -+1 InvestmentFlowBlock_invest(bus_heat_thermal_storage) +-0.16666666666666666 GenericInvestmentStorageBlock_invest(thermal_storage_0) ++1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) = 0 c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_0)_: --0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage) +-0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage_0) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) <= 0 c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_1)_: --0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage) +-0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage_0) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) <= 0 c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_2)_: --0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage) +-0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage_0) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) <= 0 c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_0)_: -+0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage) ++0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) <= 0 c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_1)_: -+0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage) ++0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) <= 0 c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_2)_: -+0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage) ++0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) <= 0 @@ -138,11 +138,11 @@ bounds 0 <= flow(thermal_storage_bus_heat_0) <= +inf 0 <= flow(thermal_storage_bus_heat_1) <= +inf 0 <= flow(thermal_storage_bus_heat_2) <= +inf - 0 <= InvestmentFlowBlock_invest(bus_heat_thermal_storage) <= +inf - 0 <= InvestmentFlowBlock_invest(thermal_storage_bus_heat) <= +inf + 0 <= InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) <= +inf + 0 <= InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) <= +inf 0 <= GenericInvestmentStorageBlock_storage_content(thermal_storage_0) <= +inf 0 <= GenericInvestmentStorageBlock_storage_content(thermal_storage_1) <= +inf 0 <= GenericInvestmentStorageBlock_storage_content(thermal_storage_2) <= +inf - 1 <= GenericInvestmentStorageBlock_invest(thermal_storage) <= +inf + 1 <= GenericInvestmentStorageBlock_invest(thermal_storage_0) <= +inf 0 <= GenericInvestmentStorageBlock_init_content(thermal_storage) <= +inf end \ No newline at end of file diff --git a/tests/lp_files/stratified_thermal_storage_invest_option_2.lp b/tests/lp_files/stratified_thermal_storage_invest_option_2.lp index fc20e009..fda4256e 100644 --- a/tests/lp_files/stratified_thermal_storage_invest_option_2.lp +++ b/tests/lp_files/stratified_thermal_storage_invest_option_2.lp @@ -2,8 +2,8 @@ min objective: -+400 GenericInvestmentStorageBlock_invest(thermal_storage) -+50 InvestmentFlowBlock_invest(bus_heat_thermal_storage) ++400 GenericInvestmentStorageBlock_invest(thermal_storage_0) ++50 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) +0.0001 flow(thermal_storage_bus_heat_0) +0.0001 flow(thermal_storage_bus_heat_1) +0.0001 flow(thermal_storage_bus_heat_2) @@ -26,50 +26,50 @@ c_e_BusBlock_balance(bus_heat_2)_: = 0 c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_0)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage) +-1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) +1 flow(bus_heat_thermal_storage_0) <= 0 c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_1)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage) +-1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) +1 flow(bus_heat_thermal_storage_1) <= 0 c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_2)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage) +-1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) +1 flow(bus_heat_thermal_storage_2) <= 0 c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_0)_: --1 InvestmentFlowBlock_invest(thermal_storage_bus_heat) +-1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) +1 flow(thermal_storage_bus_heat_0) <= 0 c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_1)_: --1 InvestmentFlowBlock_invest(thermal_storage_bus_heat) +-1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) +1 flow(thermal_storage_bus_heat_1) <= 0 c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_2)_: --1 InvestmentFlowBlock_invest(thermal_storage_bus_heat) +-1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) +1 flow(thermal_storage_bus_heat_2) <= 0 c_u_GenericInvestmentStorageBlock_init_content_limit(thermal_storage)_: +1 GenericInvestmentStorageBlock_init_content(thermal_storage) --1 GenericInvestmentStorageBlock_invest(thermal_storage) +-1 GenericInvestmentStorageBlock_invest(thermal_storage_0) <= 0 c_e_GenericInvestmentStorageBlock_balance_first(thermal_storage)_: +0.99982340904089895 GenericInvestmentStorageBlock_init_content(thermal_storage) --0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage) +-0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) +1 flow(bus_heat_thermal_storage_0) -1 flow(thermal_storage_bus_heat_0) = 0.0053014376029327757 c_e_GenericInvestmentStorageBlock_balance(thermal_storage_1)_: --0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage) +-0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage_0) +0.99982340904089895 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) +1 flow(bus_heat_thermal_storage_1) @@ -77,7 +77,7 @@ c_e_GenericInvestmentStorageBlock_balance(thermal_storage_1)_: = 0.0053014376029327757 c_e_GenericInvestmentStorageBlock_balance(thermal_storage_2)_: --0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage) +-0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage_0) +0.99982340904089895 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) +1 flow(bus_heat_thermal_storage_2) @@ -90,37 +90,37 @@ c_e_GenericInvestmentStorageBlock_balanced_cstr(thermal_storage)_: = 0 c_e_GenericInvestmentStorageBlock_power_coupled(thermal_storage)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage) -+1 InvestmentFlowBlock_invest(thermal_storage_bus_heat) +-1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) ++1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) = 0 c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_0)_: --0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage) +-0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage_0) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) <= 0 c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_1)_: --0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage) +-0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage_0) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) <= 0 c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_2)_: --0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage) +-0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage_0) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) <= 0 c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_0)_: -+0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage) ++0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) <= 0 c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_1)_: -+0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage) ++0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) <= 0 c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_2)_: -+0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage) ++0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) <= 0 @@ -134,11 +134,11 @@ bounds 0 <= flow(thermal_storage_bus_heat_0) <= +inf 0 <= flow(thermal_storage_bus_heat_1) <= +inf 0 <= flow(thermal_storage_bus_heat_2) <= +inf - 0 <= InvestmentFlowBlock_invest(bus_heat_thermal_storage) <= +inf - 0 <= InvestmentFlowBlock_invest(thermal_storage_bus_heat) <= +inf + 0 <= InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) <= +inf + 0 <= InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) <= +inf 0 <= GenericInvestmentStorageBlock_storage_content(thermal_storage_0) <= +inf 0 <= GenericInvestmentStorageBlock_storage_content(thermal_storage_1) <= +inf 0 <= GenericInvestmentStorageBlock_storage_content(thermal_storage_2) <= +inf - 1 <= GenericInvestmentStorageBlock_invest(thermal_storage) <= +inf + 1 <= GenericInvestmentStorageBlock_invest(thermal_storage_0) <= +inf 0 <= GenericInvestmentStorageBlock_init_content(thermal_storage) <= +inf end \ No newline at end of file From 597d87134734312e05e2161a13f16202b4e27183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 21:05:59 +0200 Subject: [PATCH 29/34] Pin pvlib to v0.9.0 The CSP facade needs poa_horizontal_ratio, which is no longer available in more recent versions of pvlib. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f907aba7..1dc9ac71 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ requires-python = ">=3.9" dependencies = [ 'oemof.solph', 'matplotlib', - 'pvlib', + 'pvlib <= 0.9.0', 'numpy >= 1.16.5', 'pandas >= 0.18.0' ] From 29f0162223f5e68754ea6a1ac671dbecc8f13176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 21:07:05 +0200 Subject: [PATCH 30/34] Update lpfiles of constraint tests --- tests/lp_files/csp_collector.lp | 48 +++--- tests/lp_files/solar_thermal_collector.lp | 46 +++--- tests/lp_files/stratified_thermal_storage.lp | 62 +++++--- ...atified_thermal_storage_invest_option_1.lp | 145 ++++++++++-------- ...atified_thermal_storage_invest_option_2.lp | 141 +++++++++-------- 5 files changed, 243 insertions(+), 199 deletions(-) diff --git a/tests/lp_files/csp_collector.lp b/tests/lp_files/csp_collector.lp index 3406863a..bb763fa4 100644 --- a/tests/lp_files/csp_collector.lp +++ b/tests/lp_files/csp_collector.lp @@ -1,6 +1,6 @@ \* Source Pyomo model name=Model *\ -min +min objective: +0 ONE_VAR_CONSTANT @@ -30,47 +30,45 @@ c_e_BusBlock_balance(bus_heat_2)_: +1 flow(solar_collector_bus_heat_2) = 0 -c_e_TransformerBlock_relation(solar_collector_bus_el_bus_heat_0)_: -+0.80000000000000004 flow(bus_el_solar_collector_0) --0.040000000000000008 flow(solar_collector_bus_heat_0) -= 0 - -c_e_TransformerBlock_relation(solar_collector_bus_el_bus_heat_1)_: -+0.80000000000000004 flow(bus_el_solar_collector_1) --0.040000000000000008 flow(solar_collector_bus_heat_1) +c_e_ConverterBlock_relation(solar_collector_solar_collector_inflow_bus_heat_0)_: +-1 flow(solar_collector_bus_heat_0) ++0.8 flow(solar_collector_inflow_solar_collector_0) = 0 -c_e_TransformerBlock_relation(solar_collector_bus_el_bus_heat_2)_: -+0.80000000000000004 flow(bus_el_solar_collector_2) --0.040000000000000008 flow(solar_collector_bus_heat_2) +c_e_ConverterBlock_relation(solar_collector_bus_el_bus_heat_0)_: ++0.8 flow(bus_el_solar_collector_0) +-0.04000000000000001 flow(solar_collector_bus_heat_0) = 0 -c_e_TransformerBlock_relation(solar_collector_solar_collector_inflow_bus_heat_0)_: --1 flow(solar_collector_bus_heat_0) -+0.80000000000000004 flow(solar_collector_inflow_solar_collector_0) +c_e_ConverterBlock_relation(solar_collector_solar_collector_inflow_bus_heat_1)_: +-1 flow(solar_collector_bus_heat_1) ++0.8 flow(solar_collector_inflow_solar_collector_1) = 0 -c_e_TransformerBlock_relation(solar_collector_solar_collector_inflow_bus_heat_1)_: --1 flow(solar_collector_bus_heat_1) -+0.80000000000000004 flow(solar_collector_inflow_solar_collector_1) +c_e_ConverterBlock_relation(solar_collector_bus_el_bus_heat_1)_: ++0.8 flow(bus_el_solar_collector_1) +-0.04000000000000001 flow(solar_collector_bus_heat_1) = 0 -c_e_TransformerBlock_relation(solar_collector_solar_collector_inflow_bus_heat_2)_: +c_e_ConverterBlock_relation(solar_collector_solar_collector_inflow_bus_heat_2)_: -1 flow(solar_collector_bus_heat_2) -+0.80000000000000004 flow(solar_collector_inflow_solar_collector_2) ++0.8 flow(solar_collector_inflow_solar_collector_2) = 0 -c_e_ONE_VAR_CONSTANT: -ONE_VAR_CONSTANT = 1.0 +c_e_ConverterBlock_relation(solar_collector_bus_el_bus_heat_2)_: ++0.8 flow(bus_el_solar_collector_2) +-0.04000000000000001 flow(solar_collector_bus_heat_2) += 0 bounds + 1 <= ONE_VAR_CONSTANT <= 1 0 <= flow(bus_el_solar_collector_0) <= +inf 0 <= flow(bus_el_solar_collector_1) <= +inf 0 <= flow(bus_el_solar_collector_2) <= +inf 0 <= flow(solar_collector_bus_heat_0) <= +inf 0 <= flow(solar_collector_bus_heat_1) <= +inf 0 <= flow(solar_collector_bus_heat_2) <= +inf - 0 <= flow(solar_collector_inflow_solar_collector_0) <= 0 - 0 <= flow(solar_collector_inflow_solar_collector_1) <= 75650.812223268294 - 0 <= flow(solar_collector_inflow_solar_collector_2) <= 0 + 0 <= flow(solar_collector_inflow_solar_collector_0) <= 0.0 + 0 <= flow(solar_collector_inflow_solar_collector_1) <= 75650.8122232683 + 0 <= flow(solar_collector_inflow_solar_collector_2) <= 0.0 end diff --git a/tests/lp_files/solar_thermal_collector.lp b/tests/lp_files/solar_thermal_collector.lp index 2259355a..bac524f9 100644 --- a/tests/lp_files/solar_thermal_collector.lp +++ b/tests/lp_files/solar_thermal_collector.lp @@ -1,6 +1,6 @@ \* Source Pyomo model name=Model *\ -min +min objective: +0 ONE_VAR_CONSTANT @@ -30,47 +30,45 @@ c_e_BusBlock_balance(bus_heat_2)_: +1 flow(solar_collector_bus_heat_2) = 0 -c_e_TransformerBlock_relation(solar_collector_bus_el_bus_heat_0)_: -+0.94999999999999996 flow(bus_el_solar_collector_0) --0.019 flow(solar_collector_bus_heat_0) -= 0 - -c_e_TransformerBlock_relation(solar_collector_bus_el_bus_heat_1)_: -+0.94999999999999996 flow(bus_el_solar_collector_1) --0.019 flow(solar_collector_bus_heat_1) +c_e_ConverterBlock_relation(solar_collector_solar_collector_inflow_bus_heat_0)_: +-1 flow(solar_collector_bus_heat_0) ++0.95 flow(solar_collector_inflow_solar_collector_0) = 0 -c_e_TransformerBlock_relation(solar_collector_bus_el_bus_heat_2)_: -+0.94999999999999996 flow(bus_el_solar_collector_2) --0.019 flow(solar_collector_bus_heat_2) +c_e_ConverterBlock_relation(solar_collector_bus_el_bus_heat_0)_: ++0.95 flow(bus_el_solar_collector_0) +-0.019 flow(solar_collector_bus_heat_0) = 0 -c_e_TransformerBlock_relation(solar_collector_solar_collector_inflow_bus_heat_0)_: --1 flow(solar_collector_bus_heat_0) -+0.94999999999999996 flow(solar_collector_inflow_solar_collector_0) +c_e_ConverterBlock_relation(solar_collector_solar_collector_inflow_bus_heat_1)_: +-1 flow(solar_collector_bus_heat_1) ++0.95 flow(solar_collector_inflow_solar_collector_1) = 0 -c_e_TransformerBlock_relation(solar_collector_solar_collector_inflow_bus_heat_1)_: --1 flow(solar_collector_bus_heat_1) -+0.94999999999999996 flow(solar_collector_inflow_solar_collector_1) +c_e_ConverterBlock_relation(solar_collector_bus_el_bus_heat_1)_: ++0.95 flow(bus_el_solar_collector_1) +-0.019 flow(solar_collector_bus_heat_1) = 0 -c_e_TransformerBlock_relation(solar_collector_solar_collector_inflow_bus_heat_2)_: +c_e_ConverterBlock_relation(solar_collector_solar_collector_inflow_bus_heat_2)_: -1 flow(solar_collector_bus_heat_2) -+0.94999999999999996 flow(solar_collector_inflow_solar_collector_2) ++0.95 flow(solar_collector_inflow_solar_collector_2) = 0 -c_e_ONE_VAR_CONSTANT: -ONE_VAR_CONSTANT = 1.0 +c_e_ConverterBlock_relation(solar_collector_bus_el_bus_heat_2)_: ++0.95 flow(bus_el_solar_collector_2) +-0.019 flow(solar_collector_bus_heat_2) += 0 bounds + 1 <= ONE_VAR_CONSTANT <= 1 0 <= flow(bus_el_solar_collector_0) <= +inf 0 <= flow(bus_el_solar_collector_1) <= +inf 0 <= flow(bus_el_solar_collector_2) <= +inf 0 <= flow(solar_collector_bus_heat_0) <= +inf 0 <= flow(solar_collector_bus_heat_1) <= +inf 0 <= flow(solar_collector_bus_heat_2) <= +inf - 0 <= flow(solar_collector_inflow_solar_collector_0) <= 0 + 0 <= flow(solar_collector_inflow_solar_collector_0) <= 0.0 0 <= flow(solar_collector_inflow_solar_collector_1) <= 14566.653922252568 - 0 <= flow(solar_collector_inflow_solar_collector_2) <= 35868.680625337023 + 0 <= flow(solar_collector_inflow_solar_collector_2) <= 35868.68062533702 end diff --git a/tests/lp_files/stratified_thermal_storage.lp b/tests/lp_files/stratified_thermal_storage.lp index 578f9b26..b6bcd583 100644 --- a/tests/lp_files/stratified_thermal_storage.lp +++ b/tests/lp_files/stratified_thermal_storage.lp @@ -23,35 +23,50 @@ c_e_BusBlock_balance(bus_heat_2)_: +1 flow(thermal_storage_bus_heat_2) = 0 -c_e_GenericStorageBlock_balance(thermal_storage_0)_: --0.99982340904089895 GenericStorageBlock_storage_content(thermal_storage_0) -+1 GenericStorageBlock_storage_content(thermal_storage_1) --1 flow(bus_heat_thermal_storage_0) -+1 flow(thermal_storage_bus_heat_0) +c_e_GenericStorageBlock_losses(thermal_storage_0)_: ++0.00017659095910105282 GenericStorageBlock_storage_content(thermal_storage_0) +-1 GenericStorageBlock_storage_losses(thermal_storage_0) = -0.028863382504856223 -c_e_GenericStorageBlock_balance(thermal_storage_1)_: --0.99982340904089895 GenericStorageBlock_storage_content(thermal_storage_1) -+1 GenericStorageBlock_storage_content(thermal_storage_2) --1 flow(bus_heat_thermal_storage_1) -+1 flow(thermal_storage_bus_heat_1) +c_e_GenericStorageBlock_losses(thermal_storage_1)_: ++0.00017659095910105282 GenericStorageBlock_storage_content(thermal_storage_1) +-1 GenericStorageBlock_storage_losses(thermal_storage_1) = -0.028863382504856223 -c_e_GenericStorageBlock_balance(thermal_storage_2)_: --0.99982340904089895 GenericStorageBlock_storage_content(thermal_storage_2) -+1 GenericStorageBlock_storage_content(thermal_storage_3) --1 flow(bus_heat_thermal_storage_2) -+1 flow(thermal_storage_bus_heat_2) +c_e_GenericStorageBlock_losses(thermal_storage_2)_: ++0.00017659095910105282 GenericStorageBlock_storage_content(thermal_storage_2) +-1 GenericStorageBlock_storage_losses(thermal_storage_2) = -0.028863382504856223 +c_e_GenericStorageBlock_balance(thermal_storage_0)_: ++1 flow(bus_heat_thermal_storage_0) +-1 flow(thermal_storage_bus_heat_0) ++1 GenericStorageBlock_storage_content(thermal_storage_0) +-1 GenericStorageBlock_storage_content(thermal_storage_1) +-1 GenericStorageBlock_storage_losses(thermal_storage_0) += 0 + +c_e_GenericStorageBlock_balance(thermal_storage_1)_: ++1 flow(bus_heat_thermal_storage_1) +-1 flow(thermal_storage_bus_heat_1) ++1 GenericStorageBlock_storage_content(thermal_storage_1) +-1 GenericStorageBlock_storage_content(thermal_storage_2) +-1 GenericStorageBlock_storage_losses(thermal_storage_1) += 0 + +c_e_GenericStorageBlock_balance(thermal_storage_2)_: ++1 flow(bus_heat_thermal_storage_2) +-1 flow(thermal_storage_bus_heat_2) ++1 GenericStorageBlock_storage_content(thermal_storage_2) +-1 GenericStorageBlock_storage_content(thermal_storage_3) +-1 GenericStorageBlock_storage_losses(thermal_storage_2) += 0 + c_e_GenericStorageBlock_balanced_cstr(thermal_storage)_: -1 GenericStorageBlock_storage_content(thermal_storage_0) +1 GenericStorageBlock_storage_content(thermal_storage_3) = 0 -c_e_ONE_VAR_CONSTANT: -ONE_VAR_CONSTANT = 1.0 - bounds 0 <= flow(bus_heat_thermal_storage_0) <= 2 0 <= flow(bus_heat_thermal_storage_1) <= 2 @@ -59,8 +74,11 @@ bounds 0 <= flow(thermal_storage_bus_heat_0) <= 2 0 <= flow(thermal_storage_bus_heat_1) <= 2 0 <= flow(thermal_storage_bus_heat_2) <= 2 - 91.06370721026974 <= GenericStorageBlock_storage_content(thermal_storage_0) <= 2.3349668515453779 - 91.06370721026974 <= GenericStorageBlock_storage_content(thermal_storage_1) <= 2.3349668515453779 - 91.06370721026974 <= GenericStorageBlock_storage_content(thermal_storage_2) <= 2.3349668515453779 - 91.06370721026974 <= GenericStorageBlock_storage_content(thermal_storage_3) <= 2.3349668515453779 + 91.06370721026974 <= GenericStorageBlock_storage_content(thermal_storage_0) <= 2.334966851545378 + 91.06370721026974 <= GenericStorageBlock_storage_content(thermal_storage_1) <= 2.334966851545378 + 91.06370721026974 <= GenericStorageBlock_storage_content(thermal_storage_2) <= 2.334966851545378 + 91.06370721026974 <= GenericStorageBlock_storage_content(thermal_storage_3) <= 2.334966851545378 + -inf <= GenericStorageBlock_storage_losses(thermal_storage_0) <= +inf + -inf <= GenericStorageBlock_storage_losses(thermal_storage_1) <= +inf + -inf <= GenericStorageBlock_storage_losses(thermal_storage_2) <= +inf end diff --git a/tests/lp_files/stratified_thermal_storage_invest_option_1.lp b/tests/lp_files/stratified_thermal_storage_invest_option_1.lp index 426eb06d..446699f5 100644 --- a/tests/lp_files/stratified_thermal_storage_invest_option_1.lp +++ b/tests/lp_files/stratified_thermal_storage_invest_option_1.lp @@ -1,11 +1,11 @@ \* Source Pyomo model name=Model *\ -min +min objective: -+400 GenericInvestmentStorageBlock_invest(thermal_storage) +0.0001 flow(thermal_storage_bus_heat_0) +0.0001 flow(thermal_storage_bus_heat_1) +0.0001 flow(thermal_storage_bus_heat_2) ++400 GenericInvestmentStorageBlock_invest(thermal_storage_0) s.t. @@ -24,113 +24,125 @@ c_e_BusBlock_balance(bus_heat_2)_: +1 flow(thermal_storage_bus_heat_2) = 0 -c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_0)_: +c_e_InvestmentFlowBlock_total_rule(thermal_storage_bus_heat_0)_: ++1 InvestmentFlowBlock_total(thermal_storage_bus_heat_0) +-1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) += 0 + +c_e_InvestmentFlowBlock_total_rule(bus_heat_thermal_storage_0)_: ++1 InvestmentFlowBlock_total(bus_heat_thermal_storage_0) -1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) -+1 flow(bus_heat_thermal_storage_0) += 0 + +c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_0_0)_: ++1 flow(thermal_storage_bus_heat_0) +-1 InvestmentFlowBlock_total(thermal_storage_bus_heat_0) <= 0 -c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_1)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) -+1 flow(bus_heat_thermal_storage_1) +c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_0_1)_: ++1 flow(thermal_storage_bus_heat_1) +-1 InvestmentFlowBlock_total(thermal_storage_bus_heat_0) <= 0 -c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_2)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) -+1 flow(bus_heat_thermal_storage_2) +c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_0_2)_: ++1 flow(thermal_storage_bus_heat_2) +-1 InvestmentFlowBlock_total(thermal_storage_bus_heat_0) <= 0 -c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_0)_: --1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) -+1 flow(thermal_storage_bus_heat_0) +c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_0_0)_: ++1 flow(bus_heat_thermal_storage_0) +-1 InvestmentFlowBlock_total(bus_heat_thermal_storage_0) <= 0 -c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_1)_: --1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) -+1 flow(thermal_storage_bus_heat_1) +c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_0_1)_: ++1 flow(bus_heat_thermal_storage_1) +-1 InvestmentFlowBlock_total(bus_heat_thermal_storage_0) <= 0 -c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_2)_: --1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) -+1 flow(thermal_storage_bus_heat_2) +c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_0_2)_: ++1 flow(bus_heat_thermal_storage_2) +-1 InvestmentFlowBlock_total(bus_heat_thermal_storage_0) <= 0 +c_e_GenericInvestmentStorageBlock_total_storage_rule(thermal_storage_0)_: +-1 GenericInvestmentStorageBlock_invest(thermal_storage_0) ++1 GenericInvestmentStorageBlock_total(thermal_storage_0) += 0 + c_u_GenericInvestmentStorageBlock_init_content_limit(thermal_storage)_: -+1 GenericInvestmentStorageBlock_init_content(thermal_storage) -1 GenericInvestmentStorageBlock_invest(thermal_storage_0) ++1 GenericInvestmentStorageBlock_init_content(thermal_storage) <= 0 c_e_GenericInvestmentStorageBlock_balance_first(thermal_storage)_: -+0.99982340904089895 GenericInvestmentStorageBlock_init_content(thermal_storage) --0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage_0) --1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) -+1 flow(bus_heat_thermal_storage_0) --1 flow(thermal_storage_bus_heat_0) -= 0.0053014376029327757 +-1 flow(bus_heat_thermal_storage_0) ++1 flow(thermal_storage_bus_heat_0) ++0.0002522727987158487 GenericInvestmentStorageBlock_invest(thermal_storage_0) +-0.999823409040899 GenericInvestmentStorageBlock_init_content(thermal_storage) ++1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) += -0.005301437602932776 -c_e_GenericInvestmentStorageBlock_balance(thermal_storage_1)_: --0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage_0) -+0.99982340904089895 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) --1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) -+1 flow(bus_heat_thermal_storage_1) --1 flow(thermal_storage_bus_heat_1) -= 0.0053014376029327757 +c_e_GenericInvestmentStorageBlock_balance(thermal_storage_0_1)_: +-1 flow(bus_heat_thermal_storage_1) ++1 flow(thermal_storage_bus_heat_1) ++0.0002522727987158487 GenericInvestmentStorageBlock_total(thermal_storage_0) +-0.999823409040899 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) ++1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) += -0.005301437602932776 -c_e_GenericInvestmentStorageBlock_balance(thermal_storage_2)_: --0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage_0) -+0.99982340904089895 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) --1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) -+1 flow(bus_heat_thermal_storage_2) --1 flow(thermal_storage_bus_heat_2) -= 0.0053014376029327757 +c_e_GenericInvestmentStorageBlock_balance(thermal_storage_0_2)_: +-1 flow(bus_heat_thermal_storage_2) ++1 flow(thermal_storage_bus_heat_2) ++0.0002522727987158487 GenericInvestmentStorageBlock_total(thermal_storage_0) +-0.999823409040899 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) ++1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) += -0.005301437602932776 c_e_GenericInvestmentStorageBlock_balanced_cstr(thermal_storage)_: -1 GenericInvestmentStorageBlock_init_content(thermal_storage) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) = 0 -c_e_GenericInvestmentStorageBlock_power_coupled(thermal_storage)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) -+1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) +c_e_GenericInvestmentStorageBlock_power_coupled(thermal_storage_0)_: ++1 InvestmentFlowBlock_total(thermal_storage_bus_heat_0) +-1 InvestmentFlowBlock_total(bus_heat_thermal_storage_0) = 0 -c_e_GenericInvestmentStorageBlock_storage_capacity_inflow(thermal_storage)_: --0.16666666666666666 GenericInvestmentStorageBlock_invest(thermal_storage_0) -+1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) +c_e_GenericInvestmentStorageBlock_storage_capacity_inflow(thermal_storage_0)_: ++1 InvestmentFlowBlock_total(bus_heat_thermal_storage_0) +-0.16666666666666666 GenericInvestmentStorageBlock_total(thermal_storage_0) = 0 -c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_0)_: --0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage_0) +c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_0_0)_: +-0.025 GenericInvestmentStorageBlock_total(thermal_storage_0) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) <= 0 -c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_1)_: --0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage_0) +c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_0_1)_: +-0.025 GenericInvestmentStorageBlock_total(thermal_storage_0) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) <= 0 -c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_2)_: --0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage_0) +c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_0_2)_: +-0.025 GenericInvestmentStorageBlock_total(thermal_storage_0) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) <= 0 -c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_0)_: -+0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage_0) +c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_0_0)_: ++0.975 GenericInvestmentStorageBlock_total(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) <= 0 -c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_1)_: -+0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage_0) +c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_0_1)_: ++0.975 GenericInvestmentStorageBlock_total(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) <= 0 -c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_2)_: -+0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage_0) +c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_0_2)_: ++0.975 GenericInvestmentStorageBlock_total(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) <= 0 -c_e_ONE_VAR_CONSTANT: -ONE_VAR_CONSTANT = 1.0 - bounds 0 <= flow(bus_heat_thermal_storage_0) <= +inf 0 <= flow(bus_heat_thermal_storage_1) <= +inf @@ -138,11 +150,14 @@ bounds 0 <= flow(thermal_storage_bus_heat_0) <= +inf 0 <= flow(thermal_storage_bus_heat_1) <= +inf 0 <= flow(thermal_storage_bus_heat_2) <= +inf - 0 <= InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) <= +inf + 1 <= GenericInvestmentStorageBlock_invest(thermal_storage_0) <= +inf + 0 <= InvestmentFlowBlock_total(thermal_storage_bus_heat_0) <= +inf + 0 <= InvestmentFlowBlock_total(bus_heat_thermal_storage_0) <= +inf 0 <= InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) <= +inf + 0 <= InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) <= +inf + 0 <= GenericInvestmentStorageBlock_total(thermal_storage_0) <= +inf + 0 <= GenericInvestmentStorageBlock_init_content(thermal_storage) <= +inf 0 <= GenericInvestmentStorageBlock_storage_content(thermal_storage_0) <= +inf 0 <= GenericInvestmentStorageBlock_storage_content(thermal_storage_1) <= +inf 0 <= GenericInvestmentStorageBlock_storage_content(thermal_storage_2) <= +inf - 1 <= GenericInvestmentStorageBlock_invest(thermal_storage_0) <= +inf - 0 <= GenericInvestmentStorageBlock_init_content(thermal_storage) <= +inf -end \ No newline at end of file +end diff --git a/tests/lp_files/stratified_thermal_storage_invest_option_2.lp b/tests/lp_files/stratified_thermal_storage_invest_option_2.lp index fda4256e..f26ee90b 100644 --- a/tests/lp_files/stratified_thermal_storage_invest_option_2.lp +++ b/tests/lp_files/stratified_thermal_storage_invest_option_2.lp @@ -1,12 +1,12 @@ \* Source Pyomo model name=Model *\ -min +min objective: -+400 GenericInvestmentStorageBlock_invest(thermal_storage_0) +50 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) +0.0001 flow(thermal_storage_bus_heat_0) +0.0001 flow(thermal_storage_bus_heat_1) +0.0001 flow(thermal_storage_bus_heat_2) ++400 GenericInvestmentStorageBlock_invest(thermal_storage_0) s.t. @@ -25,120 +25,135 @@ c_e_BusBlock_balance(bus_heat_2)_: +1 flow(thermal_storage_bus_heat_2) = 0 -c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_0)_: +c_e_InvestmentFlowBlock_total_rule(thermal_storage_bus_heat_0)_: +-1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) ++1 InvestmentFlowBlock_total(thermal_storage_bus_heat_0) += 0 + +c_e_InvestmentFlowBlock_total_rule(bus_heat_thermal_storage_0)_: -1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) -+1 flow(bus_heat_thermal_storage_0) ++1 InvestmentFlowBlock_total(bus_heat_thermal_storage_0) += 0 + +c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_0_0)_: ++1 flow(thermal_storage_bus_heat_0) +-1 InvestmentFlowBlock_total(thermal_storage_bus_heat_0) <= 0 -c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_1)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) -+1 flow(bus_heat_thermal_storage_1) +c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_0_1)_: ++1 flow(thermal_storage_bus_heat_1) +-1 InvestmentFlowBlock_total(thermal_storage_bus_heat_0) <= 0 -c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_2)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) -+1 flow(bus_heat_thermal_storage_2) +c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_0_2)_: ++1 flow(thermal_storage_bus_heat_2) +-1 InvestmentFlowBlock_total(thermal_storage_bus_heat_0) <= 0 -c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_0)_: --1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) -+1 flow(thermal_storage_bus_heat_0) +c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_0_0)_: ++1 flow(bus_heat_thermal_storage_0) +-1 InvestmentFlowBlock_total(bus_heat_thermal_storage_0) <= 0 -c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_1)_: --1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) -+1 flow(thermal_storage_bus_heat_1) +c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_0_1)_: ++1 flow(bus_heat_thermal_storage_1) +-1 InvestmentFlowBlock_total(bus_heat_thermal_storage_0) <= 0 -c_u_InvestmentFlowBlock_max(thermal_storage_bus_heat_2)_: --1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) -+1 flow(thermal_storage_bus_heat_2) +c_u_InvestmentFlowBlock_max(bus_heat_thermal_storage_0_2)_: ++1 flow(bus_heat_thermal_storage_2) +-1 InvestmentFlowBlock_total(bus_heat_thermal_storage_0) <= 0 +c_e_GenericInvestmentStorageBlock_total_storage_rule(thermal_storage_0)_: +-1 GenericInvestmentStorageBlock_invest(thermal_storage_0) ++1 GenericInvestmentStorageBlock_total(thermal_storage_0) += 0 + c_u_GenericInvestmentStorageBlock_init_content_limit(thermal_storage)_: -+1 GenericInvestmentStorageBlock_init_content(thermal_storage) -1 GenericInvestmentStorageBlock_invest(thermal_storage_0) ++1 GenericInvestmentStorageBlock_init_content(thermal_storage) <= 0 c_e_GenericInvestmentStorageBlock_balance_first(thermal_storage)_: -+0.99982340904089895 GenericInvestmentStorageBlock_init_content(thermal_storage) --0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage_0) --1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) -+1 flow(bus_heat_thermal_storage_0) --1 flow(thermal_storage_bus_heat_0) -= 0.0053014376029327757 +-1 flow(bus_heat_thermal_storage_0) ++1 flow(thermal_storage_bus_heat_0) ++0.0002522727987158487 GenericInvestmentStorageBlock_invest(thermal_storage_0) +-0.999823409040899 GenericInvestmentStorageBlock_init_content(thermal_storage) ++1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) += -0.005301437602932776 -c_e_GenericInvestmentStorageBlock_balance(thermal_storage_1)_: --0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage_0) -+0.99982340904089895 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) --1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) -+1 flow(bus_heat_thermal_storage_1) --1 flow(thermal_storage_bus_heat_1) -= 0.0053014376029327757 +c_e_GenericInvestmentStorageBlock_balance(thermal_storage_0_1)_: +-1 flow(bus_heat_thermal_storage_1) ++1 flow(thermal_storage_bus_heat_1) ++0.0002522727987158487 GenericInvestmentStorageBlock_total(thermal_storage_0) +-0.999823409040899 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) ++1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) += -0.005301437602932776 -c_e_GenericInvestmentStorageBlock_balance(thermal_storage_2)_: --0.00025227279871584872 GenericInvestmentStorageBlock_invest(thermal_storage_0) -+0.99982340904089895 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) --1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) -+1 flow(bus_heat_thermal_storage_2) --1 flow(thermal_storage_bus_heat_2) -= 0.0053014376029327757 +c_e_GenericInvestmentStorageBlock_balance(thermal_storage_0_2)_: +-1 flow(bus_heat_thermal_storage_2) ++1 flow(thermal_storage_bus_heat_2) ++0.0002522727987158487 GenericInvestmentStorageBlock_total(thermal_storage_0) +-0.999823409040899 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) ++1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) += -0.005301437602932776 c_e_GenericInvestmentStorageBlock_balanced_cstr(thermal_storage)_: -1 GenericInvestmentStorageBlock_init_content(thermal_storage) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) = 0 -c_e_GenericInvestmentStorageBlock_power_coupled(thermal_storage)_: --1 InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) -+1 InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) +c_e_GenericInvestmentStorageBlock_power_coupled(thermal_storage_0)_: ++1 InvestmentFlowBlock_total(thermal_storage_bus_heat_0) +-1 InvestmentFlowBlock_total(bus_heat_thermal_storage_0) = 0 -c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_0)_: --0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage_0) +c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_0_0)_: +-0.025 GenericInvestmentStorageBlock_total(thermal_storage_0) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) <= 0 -c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_1)_: --0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage_0) +c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_0_1)_: +-0.025 GenericInvestmentStorageBlock_total(thermal_storage_0) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) <= 0 -c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_2)_: --0.025000000000000001 GenericInvestmentStorageBlock_invest(thermal_storage_0) +c_u_GenericInvestmentStorageBlock_max_storage_content(thermal_storage_0_2)_: +-0.025 GenericInvestmentStorageBlock_total(thermal_storage_0) +1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) <= 0 -c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_0)_: -+0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage_0) +c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_0_0)_: ++0.975 GenericInvestmentStorageBlock_total(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_0) <= 0 -c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_1)_: -+0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage_0) +c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_0_1)_: ++0.975 GenericInvestmentStorageBlock_total(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_1) <= 0 -c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_2)_: -+0.97499999999999998 GenericInvestmentStorageBlock_invest(thermal_storage_0) +c_u_GenericInvestmentStorageBlock_min_storage_content(thermal_storage_0_2)_: ++0.975 GenericInvestmentStorageBlock_total(thermal_storage_0) -1 GenericInvestmentStorageBlock_storage_content(thermal_storage_2) <= 0 -c_e_ONE_VAR_CONSTANT: -ONE_VAR_CONSTANT = 1.0 - bounds + 0 <= InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) <= +inf + 0 <= InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) <= +inf 0 <= flow(bus_heat_thermal_storage_0) <= +inf 0 <= flow(bus_heat_thermal_storage_1) <= +inf 0 <= flow(bus_heat_thermal_storage_2) <= +inf 0 <= flow(thermal_storage_bus_heat_0) <= +inf 0 <= flow(thermal_storage_bus_heat_1) <= +inf 0 <= flow(thermal_storage_bus_heat_2) <= +inf - 0 <= InvestmentFlowBlock_invest(bus_heat_thermal_storage_0) <= +inf - 0 <= InvestmentFlowBlock_invest(thermal_storage_bus_heat_0) <= +inf + 1 <= GenericInvestmentStorageBlock_invest(thermal_storage_0) <= +inf + 0 <= InvestmentFlowBlock_total(thermal_storage_bus_heat_0) <= +inf + 0 <= InvestmentFlowBlock_total(bus_heat_thermal_storage_0) <= +inf + 0 <= GenericInvestmentStorageBlock_total(thermal_storage_0) <= +inf + 0 <= GenericInvestmentStorageBlock_init_content(thermal_storage) <= +inf 0 <= GenericInvestmentStorageBlock_storage_content(thermal_storage_0) <= +inf 0 <= GenericInvestmentStorageBlock_storage_content(thermal_storage_1) <= +inf 0 <= GenericInvestmentStorageBlock_storage_content(thermal_storage_2) <= +inf - 1 <= GenericInvestmentStorageBlock_invest(thermal_storage_0) <= +inf - 0 <= GenericInvestmentStorageBlock_init_content(thermal_storage) <= +inf -end \ No newline at end of file +end From 6015e625aaf8a3056d1a0ff8388c476c98073d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 21:18:29 +0200 Subject: [PATCH 31/34] Make constraint test independent from line sorting This is because Pyomo has no reproducible line order. --- tests/test_constraints.py | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/test_constraints.py b/tests/test_constraints.py index b2f9c19e..71150543 100644 --- a/tests/test_constraints.py +++ b/tests/test_constraints.py @@ -13,7 +13,8 @@ import logging import os import re -from difflib import unified_diff + +from pyomo.repn.tests.lp_diff import lp_diff import oemof.solph as solph import pandas as pd @@ -54,26 +55,25 @@ def normalize_to_positive_results(lines): return lines -def compare_lp_files(lp_file_1, lp_file_2, ignored=None): - lines_1 = remove(ignored, chop_trailing_whitespace(lp_file_1.readlines())) - lines_2 = remove(ignored, chop_trailing_whitespace(lp_file_2.readlines())) - - lines_1 = normalize_to_positive_results(lines_1) - lines_2 = normalize_to_positive_results(lines_2) - - if not lines_1 == lines_2: - raise AssertionError( - "Failed matching lp_file_1 with lp_file_2:\n" - + "\n".join( - unified_diff( - lines_1, - lines_2, - fromfile=os.path.relpath(lp_file_1.name), - tofile=os.path.basename(lp_file_2.name), - lineterm="", - ) - ) - ) +def compare_lp_files(lp_file_1, lp_file_2): + r"""Compare lp-files to check constraints generated within solph.""" + exp = lp_file_1.read() + gen = lp_file_2.read() + + # lp_diff returns two arrays of strings with cleaned lp syntax + # It automatically prints the diff + exp_diff, gen_diff = lp_diff(exp, gen) + + # sometimes, 0.0 is printed, sometimes 0, harmonise that + exp_diff = [line + " ".replace(" 0.0 ", " 0 ") for line in exp_diff] + gen_diff = [line + " ".replace(" 0.0 ", " 0 ") for line in gen_diff] + + assert len(exp_diff) == len(gen_diff) + + # Created the LP files do not have a reproducible + # order of the lines. Thus, we sort the lines. + for exp, gen in zip(sorted(exp_diff), sorted(gen_diff)): + assert exp == gen, "Failed matching expected with generated lp file." class TestConstraints: From 131c95032a8ddabe99b8cbe44dc085d594e02e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Thu, 10 Oct 2024 21:21:07 +0200 Subject: [PATCH 32/34] Fix import order --- tests/test_constraints.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_constraints.py b/tests/test_constraints.py index 71150543..fa7b7ba2 100644 --- a/tests/test_constraints.py +++ b/tests/test_constraints.py @@ -14,11 +14,10 @@ import os import re -from pyomo.repn.tests.lp_diff import lp_diff - import oemof.solph as solph import pandas as pd from oemof.solph import helpers +from pyomo.repn.tests.lp_diff import lp_diff from oemof.thermal import facades From d284d71e8e7d4416e4d0f12523760551c86a0a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Fri, 11 Oct 2024 10:39:25 +0200 Subject: [PATCH 33/34] Rename Transformer to Converter Following the renaming in solph. --- docs/compression_heat_pumps_and_chillers.rst | 2 +- docs/concentrating_solar_power.rst | 8 ++++---- docs/examples.rst | 2 +- docs/solar_thermal_collector.rst | 8 ++++---- .../absorption_chiller.py | 2 +- .../airsource_heatpump_const_max_output.py | 4 ++-- .../airsource_heatpump_variable_max_output.py | 4 ++-- .../compression_heatpump_and_chiller/chiller_cop.py | 4 ++-- .../chiller_cop_as_TimeSeries.py | 4 ++-- .../groundsource_heatpump.py | 2 +- examples/concentrating_solar_power/csp_facade.py | 4 ++-- examples/concentrating_solar_power/csp_plant.py | 6 +++--- .../solar_thermal_collector/flat_plate_collector.py | 4 ++-- .../flat_plate_collector_investment.py | 4 ++-- src/oemof/thermal/facades.py | 10 +++++----- 15 files changed, 34 insertions(+), 34 deletions(-) diff --git a/docs/compression_heat_pumps_and_chillers.rst b/docs/compression_heat_pumps_and_chillers.rst index 1a710c97..ea9e1a06 100644 --- a/docs/compression_heat_pumps_and_chillers.rst +++ b/docs/compression_heat_pumps_and_chillers.rst @@ -12,7 +12,7 @@ _____ This module was developed to provide COP calculations based on temperatures for energy system optimizations with oemof.solph. -A time series of pre-calculated COPs can be used as input for a transformer +A time series of pre-calculated COPs can be used as input for a Converter (an oemof.solph component) in an energy system optimization. Discover more possibilities to use this module with our examples: https://github.com/oemof/oemof-thermal/tree/dev/examples diff --git a/docs/concentrating_solar_power.rst b/docs/concentrating_solar_power.rst index 8557963c..28eba0b3 100644 --- a/docs/concentrating_solar_power.rst +++ b/docs/concentrating_solar_power.rst @@ -16,8 +16,8 @@ system optimizations with oemof.solph. In https://github.com/oemof/oemof-thermal/tree/dev/examples you can find an example on how to use the modul to calculate a CSP power plant. -A time series of pre-calculated heat flows can be used as input for a source -(an oemof.solph component), and a transformer (an oemof.solph component) can be +A time series of pre-calculated heat flows can be used as input for a Source +(an oemof.solph component), and a Converter (an oemof.solph component) can be used to hold electrical power consumption and further thermal losses of the collector in an energy system optimization. In addition, you will find an example which compares this precalculation with @@ -175,7 +175,7 @@ calculated with a fix efficiency. The results of this precalculation can be used in an oemof energy system model as output of a source component. To model the behaviour of a collector, it can be -complemented with a transformer, which holds the electrical consumption of pumps +complemented with a Converter, which holds the electrical consumption of pumps and peripheral heat losses (see the the example csp_plant_collector.py). ParabolicTroughCollector facade @@ -193,7 +193,7 @@ class of the facade module for all parameters which have to be provided. See example_csp_facade.py for an application example. It models the same system as the csp_plant_example.py, but uses the ParabolicTroughCollector facade -instead of separate source and transformer. +instead of separate Source and Converter. .. code-block:: python diff --git a/docs/examples.rst b/docs/examples.rst index 14e7a368..afedd88e 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -23,7 +23,7 @@ __________________________ An example provides an "how to" on the use of the 'calc_cops' function to get the coefficients of performance (COP) of an exemplary air-source heat pump (ASHP). It also shows how to use the -pre-calculated COPs in a solph.Transformer. +pre-calculated COPs in a solph.Converter. Furthermore, the maximal possible heat output of the heat pump is pre-calculated and varies with the temperature levels of the heat reservoirs. In the example the ambient air is used as low temperature heat reservoir. diff --git a/docs/solar_thermal_collector.rst b/docs/solar_thermal_collector.rst index 19ec2a10..9bd68988 100644 --- a/docs/solar_thermal_collector.rst +++ b/docs/solar_thermal_collector.rst @@ -17,8 +17,8 @@ In https://github.com/oemof/oemof-thermal/tree/dev/examples you can find an example, how to use the modul to calculate a system with flat plate collector, storage and backup to provide a given heat demand. -The time series of the pre-calculated heat is output of a source (an oemof.solph -component) representing the collector, and a transformer (an oemof.solph component) +The time series of the pre-calculated heat is output of a Source (an oemof.solph +component) representing the collector, and a Converter (an oemof.solph component) is used to hold electrical power consumption and further thermal losses of the collector in an energy system optimization. In addition, you will find a plot, which compares this precalculation with a calculation with a constant efficiency. @@ -138,7 +138,7 @@ function in comparison to the heat calculated with a fix efficiency. The results of this precalculation can be used in an oemof energy system model as output of a source component. To model the behaviour of a collector, it can be -complemented with a transformer, which holds the electrical consumption of pumps +complemented with a Converter, which holds the electrical consumption of pumps and peripheral heat losses (see the the examples flat_plate_collector_example.py and flat_plate_collector_example_investment.py). @@ -157,7 +157,7 @@ class of the facade module for all parameters which have to be provided. See flat_plate_collector_example_facade.py for an application example. It models the same system as the flat_plate_collector_example.py, but uses the SolarThermalCollector facade -instead of separate source and transformer. +instead of separate Source and Converter. .. code-block:: python diff --git a/examples/absorption_heatpump_and_chiller/absorption_chiller.py b/examples/absorption_heatpump_and_chiller/absorption_chiller.py index 0664491c..01ceb14d 100644 --- a/examples/absorption_heatpump_and_chiller/absorption_chiller.py +++ b/examples/absorption_heatpump_and_chiller/absorption_chiller.py @@ -90,7 +90,7 @@ def absorption_chiller_example(): # Absorption Chiller energysystem.add( - solph.components.Transformer( + solph.components.Converter( label="AC", inputs={b_th_high: solph.Flow()}, outputs={ diff --git a/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py b/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py index 10170b32..5cd5a59f 100644 --- a/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py +++ b/examples/compression_heatpump_and_chiller/airsource_heatpump_const_max_output.py @@ -1,7 +1,7 @@ """ Example on how to use the 'calc_cops' function to get the COPs of an exemplary air-source heat pump (ASHP) and use the -pre-calculated COPs in a solph.Transformer. +pre-calculated COPs in a solph.Converter. We use the ambient air as low temperature heat reservoir. """ @@ -78,7 +78,7 @@ def airource_hp_const_example(): # Air-Source Heat Pump energysystem.add( - solph.components.Transformer( + solph.components.Converter( label="ASHP", inputs={b_el: solph.Flow()}, outputs={b_heat: solph.Flow(nominal_value=25, variable_costs=5)}, diff --git a/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py b/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py index c38eab96..510df8d4 100644 --- a/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py +++ b/examples/compression_heatpump_and_chiller/airsource_heatpump_variable_max_output.py @@ -1,7 +1,7 @@ """ Example on how to use the 'calc_cops' function to get the COPs of an exemplary air-source heat pump (ASHP) and use the -pre-calculated COPs in a solph.Transformer. +pre-calculated COPs in a solph.Converter. Furthermore, the maximal possible heat output of the heat pump is pre-calculated and varies with the temperature levels of the heat reservoirs. @@ -87,7 +87,7 @@ def airource_hp_variable_example(): # Air-Source Heat Pump energysystem.add( - solph.components.Transformer( + solph.components.Converter( label="ASHP", inputs={b_el: solph.Flow()}, outputs={ diff --git a/examples/compression_heatpump_and_chiller/chiller_cop.py b/examples/compression_heatpump_and_chiller/chiller_cop.py index 4fdf3094..c35e1071 100644 --- a/examples/compression_heatpump_and_chiller/chiller_cop.py +++ b/examples/compression_heatpump_and_chiller/chiller_cop.py @@ -4,8 +4,8 @@ We use the ambient air as heat sink (high temperature reservoir). The input is a list to show how the function can be applied on several time steps. The -output is a list as well and may serve as input (conversion_factor) for a -oemof.solph.transformer. +output is a list as well and may serve as input (conversion_factor) for an +oemof.solph.Converter. """ import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller diff --git a/examples/compression_heatpump_and_chiller/chiller_cop_as_TimeSeries.py b/examples/compression_heatpump_and_chiller/chiller_cop_as_TimeSeries.py index 55d5e39b..8d313aea 100644 --- a/examples/compression_heatpump_and_chiller/chiller_cop_as_TimeSeries.py +++ b/examples/compression_heatpump_and_chiller/chiller_cop_as_TimeSeries.py @@ -4,8 +4,8 @@ We use the ambient air as heat sink (high temperature reservoir). The input is a list to show how the function can be applied on several time steps. The -output is a list as well and may serve as input (conversion_factor) for a -oemof.solph.transformer. +output is a list as well and may serve as input (conversion_factor) for an +oemof.solph.Converter. """ import pandas as pd diff --git a/examples/compression_heatpump_and_chiller/groundsource_heatpump.py b/examples/compression_heatpump_and_chiller/groundsource_heatpump.py index 0b40179c..a3205349 100644 --- a/examples/compression_heatpump_and_chiller/groundsource_heatpump.py +++ b/examples/compression_heatpump_and_chiller/groundsource_heatpump.py @@ -82,7 +82,7 @@ def groundsource_hp_example(): # Ground-Source Heat Pump energysystem.add( - solph.components.Transformer( + solph.components.Converter( label="GSHP", inputs={b_el: solph.Flow(), b_th_low: solph.Flow()}, outputs={ diff --git a/examples/concentrating_solar_power/csp_facade.py b/examples/concentrating_solar_power/csp_facade.py index a1c51aa2..fe95a6ed 100644 --- a/examples/concentrating_solar_power/csp_facade.py +++ b/examples/concentrating_solar_power/csp_facade.py @@ -120,8 +120,8 @@ def csp_facade_example(): excess = solph.components.Sink(label="excess", inputs={bth: solph.Flow()}) - # Transformer and storages - turbine = solph.components.Transformer( + # Converter and storages + turbine = solph.components.Converter( label="turbine", inputs={bth: solph.Flow()}, outputs={bel: solph.Flow()}, diff --git a/examples/concentrating_solar_power/csp_plant.py b/examples/concentrating_solar_power/csp_plant.py index 9a9e264e..af31c8d1 100644 --- a/examples/concentrating_solar_power/csp_plant.py +++ b/examples/concentrating_solar_power/csp_plant.py @@ -135,8 +135,8 @@ def csp_plant_example(): label="ambience_sol", inputs={bcol: solph.Flow()} ) - # Transformer and storages - collector = solph.components.Transformer( + # Converter and storages + collector = solph.components.Converter( label="collector", inputs={bcol: solph.Flow(), bel: solph.Flow()}, outputs={bth: solph.Flow()}, @@ -147,7 +147,7 @@ def csp_plant_example(): }, ) - turbine = solph.components.Transformer( + turbine = solph.components.Converter( label="turbine", inputs={bth: solph.Flow()}, outputs={bel: solph.Flow()}, diff --git a/examples/solar_thermal_collector/flat_plate_collector.py b/examples/solar_thermal_collector/flat_plate_collector.py index 17ba066c..95a28575 100644 --- a/examples/solar_thermal_collector/flat_plate_collector.py +++ b/examples/solar_thermal_collector/flat_plate_collector.py @@ -124,8 +124,8 @@ def flat_plate_collector_example(): label="collector_excess_heat", inputs={bcol: solph.Flow()} ) - # transformer and storage - collector = solph.components.Transformer( + # converter and storage + collector = solph.components.Converter( label="collector", inputs={bcol: solph.Flow(), bel: solph.Flow()}, outputs={bth: solph.Flow()}, diff --git a/examples/solar_thermal_collector/flat_plate_collector_investment.py b/examples/solar_thermal_collector/flat_plate_collector_investment.py index 41acae9d..a231cbf7 100644 --- a/examples/solar_thermal_collector/flat_plate_collector_investment.py +++ b/examples/solar_thermal_collector/flat_plate_collector_investment.py @@ -124,8 +124,8 @@ def flat_plate_collector_investment_example(): label="collector_excess_heat", inputs={bcol: solph.Flow()} ) - # Transformer and storage - collector = solph.components.Transformer( + # Converter and storage + collector = solph.components.Converter( label="collector", inputs={bcol: solph.Flow(), bel: solph.Flow()}, outputs={bth: solph.Flow()}, diff --git a/src/oemof/thermal/facades.py b/src/oemof/thermal/facades.py index 8577afff..9580c8d4 100644 --- a/src/oemof/thermal/facades.py +++ b/src/oemof/thermal/facades.py @@ -36,7 +36,7 @@ from oemof.solph import sequence from oemof.solph.components import GenericStorage from oemof.solph.components import Source -from oemof.solph.components import Transformer +from oemof.solph.components import Converter from oemof.tools.debugging import SuspiciousUsageWarning from oemof.thermal.concentrating_solar_power import csp_precalc @@ -411,7 +411,7 @@ def build_solph_components(self): self._set_flows() -class ParabolicTroughCollector(Transformer, Facade): +class ParabolicTroughCollector(Converter, Facade): r"""Parabolic trough collector unit Parameters @@ -470,7 +470,7 @@ def __init__(self, **kwargs): kwargs.update({"_facade_requires_": ["longitude"]}) Facade.__init__(self, **kwargs) - Transformer.__init__(self, label=kwargs.get("label")) + Converter.__init__(self, label=kwargs.get("label")) self.heat_bus = kwargs.get("heat_bus") @@ -608,7 +608,7 @@ def build_solph_components(self): self.subnodes = (inflow,) -class SolarThermalCollector(Transformer, Facade): +class SolarThermalCollector(Converter, Facade): r"""Solar thermal collector unit Parameters: @@ -662,7 +662,7 @@ def __init__(self, **kwargs): kwargs.update({"_facade_requires_": ["longitude"]}) Facade.__init__(self, **kwargs) - Transformer.__init__(self, label=kwargs.get("label")) + Converter.__init__(self, label=kwargs.get("label")) self.heat_out_bus = kwargs.get("heat_out_bus") From 56e35efb2fb7282c68dd1e39b647d9b80ecfef6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Sch=C3=B6nfeldt?= Date: Fri, 11 Oct 2024 10:59:01 +0200 Subject: [PATCH 34/34] Fix import order --- src/oemof/thermal/facades.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oemof/thermal/facades.py b/src/oemof/thermal/facades.py index 9580c8d4..f540dbc0 100644 --- a/src/oemof/thermal/facades.py +++ b/src/oemof/thermal/facades.py @@ -34,9 +34,9 @@ from oemof.solph import Flow from oemof.solph import Investment from oemof.solph import sequence +from oemof.solph.components import Converter from oemof.solph.components import GenericStorage from oemof.solph.components import Source -from oemof.solph.components import Converter from oemof.tools.debugging import SuspiciousUsageWarning from oemof.thermal.concentrating_solar_power import csp_precalc