From 734a541568c3cc40d1687da5e398ac309513f506 Mon Sep 17 00:00:00 2001 From: mfleschutz Date: Fri, 6 May 2022 18:34:06 +0200 Subject: [PATCH] Fix bug in yields table --- README.md | 16 +++++++++------ doc/images/draf_architecture.svg | 2 +- draf/components/component_templates.py | 4 +++- draf/core/case_study.py | 5 ++--- draf/core/scenario.py | 3 +-- draf/plotting/cs_plotting.py | 27 ++++++++++++++++++++------ draf/prep/param_funcs.py | 3 +++ 7 files changed, 41 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index f98e888..0ad0d3e 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ It uses the power of ([mixed integer]) [linear programming] optimization, [`pand - Electricity prices via [`elmada`] - Carbon emission factors via [`elmada`] - Standard load profiles from [BDEW] - - PV profiles via [`gsee`] (In Germany, using weather data from [DWD]) + - PV profiles via [`GSEE`] (In Germany, using weather data from [DWD]) - [`DataBase`](draf/prep/data_base.py) - for scientific data such as cost or efficiency factors. - **Scenario generation tools:** Easily build individual scenarios or sensitivity analyses. - **Multi-objective mathematical optimization** with support of different model languages and solvers: @@ -100,7 +100,9 @@ Copyright (c) 2022 Markus Fleschutz License: [LGPL v3] The development of `draf` was initiated by [Markus Fleschutz] in 2017 and continued in a cooperative PhD between the [MeSSO Research Group] of the [Munster Technological University], Ireland and the [Energy System Analysis Research Group] of the [Karlsruhe University of Applied Sciences], Germany. -Thank you [Markus Bohlayer], [Adrian Bürger], and [Andre Leippi] for your valuable feedback. +This Project was supported by the Federal Ministry for Economic Affairs and Climate Action (BMWK) on the basis of a decision by the German Bundestag and by the MTU Risam scholarship scheme. + +Thank you [Dr. Markus Bohlayer], [Dr. Ing. Adrian Bürger], [Andre Leippi], [Dr. Ing. Marco Braun], and [Dr. Michael D. Murphy] for your valuable feedback. MTU_HKA_Logo @@ -108,27 +110,29 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI [`elmada`]: https://github.com/DrafProject/elmada -[`gsee`]: https://github.com/renewables-ninja/gsee +[`GSEE`]: https://github.com/renewables-ninja/gsee [`GurobiPy`]: https://pypi.org/project/gurobipy [`matplotlib`]: https://matplotlib.org [`pandas`]: https://pandas.pydata.org [`plotly`]: https://plotly.com [`Pyomo`]: https://github.com/Pyomo/pyomo [`seaborn`]: https://seaborn.pydata.org -[Adrian Bürger]: https://scholar.google.de/citations?user=UcLkLlEAAAAJ [anaconda]: https://www.anaconda.com/products/individual [Andre Leippi]: https://www.linkedin.com/in/andre-leippi-3187a81a7 [BDEW]: https://www.bdew.de +[Dr. Ing. Adrian Bürger]: https://www.linkedin.com/in/adrian-b%C3%BCrger-251205236/ +[Dr. Ing. Marco Braun]: https://www.h-ka.de/en/about-hka/organization-people/staff-search/person/marco-braun +[Dr. Markus Bohlayer]: https://www.linkedin.com/in/markus-bohlayer +[Dr. Michael D. Murphy]: https://www.linkedin.com/in/michael-d-murphy-16134118 [DWD]: https://www.dwd.de [Energy System Analysis Research Group]: https://www.h-ka.de/en/ikku/energy-system-analysis [Karlsruhe University of Applied Sciences]: https://www.h-ka.de/en [LGPL v3]: https://www.gnu.org/licenses/lgpl-3.0.de.html [linear programming]: https://en.wikipedia.org/wiki/Linear_programming -[Markus Bohlayer]: https://scholar.google.com/citations?user=hH1FQVsAAAAJ [Markus Fleschutz]: https://mfleschutz.github.io [MeSSO Research Group]: https://messo.cit.ie [miniconda]: https://docs.conda.io/en/latest/miniconda.html [Mittelmann benchmark]: http://plato.asu.edu/ftp/milp.html [mixed integer]: https://en.wikipedia.org/wiki/Integer_programming [Munster Technological University]: https://www.mtu.ie -[xarray]: http://xarray.pydata.org/en/stable +[xarray]: http://xarray.pydata.org/en/stable \ No newline at end of file diff --git a/doc/images/draf_architecture.svg b/doc/images/draf_architecture.svg index a0bb054..0bda4ff 100644 --- a/doc/images/draf_architecture.svg +++ b/doc/images/draf_architecture.svg @@ -1,4 +1,4 @@ -
CaseStudy
CaseStudy
Scenario
Scenario
Scenario
Scenario
Literature
Literature
Model
Model

User
User
Results
Results
CaseStudy
Plotter
CaseStudy...
ScenarioPlotter
ScenarioPlotter
Solver
Solver
Internet
Internet
TimeSeries
Prepper
TimeSeries...
Juypter
note-
book
Juypter...
Technology
parameters
Technology...
Time
series data
Time...
Optimizer
Optimizer
Demand
Analyzer
Demand...
PeakLoad Analyzer
PeakLoad A...
Constraints
Constraints
Variables
Variables
Obj. Func.
Obj. Func.
Parameters
Parameters
Dimensions
Dimensions
Meta data
Meta data
Variable definitions
Variable de...
Collectors
Collectors
Component
templates
Component...

Model
generator

Model...
Scenario definitions
Scenario definitions
User-defined components
User-defined components
DataBase
DataBase
Scenario
generator
Scenario...
Viewer does not support full SVG 1.1
\ No newline at end of file +
CaseStudy
CaseStudy
Scenario
Scenario
Scenario
Scenario
Scenario
Scenario
Literature
Literature

User
User
CaseStudy
Plotter
CaseStudy...
ScenarioPlotter
ScenarioPlotter
Solver
Solver
Internet
Internet
TimeSeries
Prepper
TimeSeries...
Juypter
note-
book
Juypter...
Technology
parameters
Technology...
Time
series data
Time...
Optimizer
Optimizer
DemandAnalyzer
DemandAnalyzer
PeakLoadAnalyzer
PeakLoadAnalyzer
Component
templates
Component...

Model
generator

Model...
Scenario definitions
Scenario definitions
User-defined components
User-defined components
DataBase
DataBase
Scenario
generator
Scenario...

Data

Data
Model
Model
Results
Results
Dimensions
Dimensions
Parameters
Parameters
Variable definitions
Variable def...
Collectors
Collectors
Meta
data
Meta...

Logic

Logic
Obj. func.
Obj. func.
Constraints
Constraints
Variables
Variables
Text is not SVG - cannot display
\ No newline at end of file diff --git a/draf/components/component_templates.py b/draf/components/component_templates.py index 4896c9a..3d4372f 100644 --- a/draf/components/component_templates.py +++ b/draf/components/component_templates.py @@ -474,7 +474,9 @@ def get_C(): data=0.5, doc="Ratio of reaching the ideal COP (exergy efficiency)", src="@Arat_2017", - ) # Cox_2022 used 0.45 (https://doi.org/10.1016/j.apenergy.2021.118499) + # Cox_2022 used 0.45: https://doi.org/10.1016/j.apenergy.2021.118499 + # but roughly 0.5 in recent real operation of high temperature HP: https://www.waermepumpe.de/fileadmin/user_upload/waermepumpe/01_Verband/Webinare/Vortrag_Wilk_AIT_02062020.pdf + ) sc.param("dQ_HP_CAPx_", data=self.dQ_CAPx, doc="Existing heating capacity", unit="kW_th") sc.param( "dQ_HP_max_", data=1e5, doc="Big-M number (upper bound for CAPn + CAPx)", unit="kW_th" diff --git a/draf/core/case_study.py b/draf/core/case_study.py index bda661b..addb176 100644 --- a/draf/core/case_study.py +++ b/draf/core/case_study.py @@ -218,7 +218,7 @@ def add_scen( based_on: Optional[str] = "REF", based_on_last: bool = False, components: Optional[List[Component]] = None, - custom_model: Optional[Callable] = None + custom_model: Optional[Callable] = None, ) -> Scenario: """Add a Scenario with a name, a describing doc-string and a link to a model. @@ -256,7 +256,7 @@ def add_scen( consider_invest=self.consider_invest, mdl_language=self.mdl_language, obj_vars=self.obj_vars, - custom_model=custom_model + custom_model=custom_model, ) else: if components is not None: @@ -485,7 +485,6 @@ def set_model( def _optimize_parallel( self, scens: Optional[Iterable] = None, optimize_kwargs: Optional[Dict] = None ): - @ray.remote def optimize_scenario(sc): sc.optimize(**optimize_kwargs) diff --git a/draf/core/scenario.py b/draf/core/scenario.py index a7ac633..b396f16 100644 --- a/draf/core/scenario.py +++ b/draf/core/scenario.py @@ -663,8 +663,7 @@ def save_results(self) -> None: pickle.dump(self, f, protocol=pickle.HIGHEST_PROTOCOL) logger.info(f"Saved scenario results to {fp}") - - def save(self, name:Optional[str]=None) -> None: + def save(self, name: Optional[str] = None) -> None: """Saves the scenario to a pickle-file.""" date_time = self._get_now_string() diff --git a/draf/plotting/cs_plotting.py b/draf/plotting/cs_plotting.py index bc10321..0573510 100644 --- a/draf/plotting/cs_plotting.py +++ b/draf/plotting/cs_plotting.py @@ -119,7 +119,8 @@ def yields_table(self, gradient: bool = False, nyears_for_irr: int = 15) -> pdSt ("", "C_invAnn"): cs.get_ent("C_TOT_invAnn_"), ("", "C_op"): cs.get_ent("C_TOT_op_"), ("", "EAC"): -cs.get_diff("C_TOT_") / cs.get_diff("CE_TOT_") * 1e6, - ("", "PP"): (cs.get_ent("C_TOT_inv_") / cs.get_diff("C_TOT_op_")).replace( + ("", "PP"): cs.get_ent("C_TOT_inv_") + / ((cs.get_diff("C_TOT_op_") + cs.get_diff("C_TOT_RMI_"))).replace( np.inf, np.nan # infinity is not supported by background gradient ), } @@ -943,25 +944,39 @@ def capas(self, include_capx: bool = True, subplot_x_anchors=(0.79, 0.91)) -> go unit1 = cs.REF_scen.get_unit("C_TOT_inv_") ser, unit1 = hp.auto_fmt(ser, unit1) fig.add_trace( - go.Bar(y=ser.index.tolist(), x=ser.values, xaxis="x2", yaxis="y2", orientation="h") + go.Bar( + y=ser.index.tolist(), + x=ser.values, + xaxis="x2", + yaxis="y2", + orientation="h", + marker_color="grey", + ) ) ser = pd.Series(cs.get_ent("C_TOT_op_")) unit2 = cs.REF_scen.get_unit("C_TOT_op_") ser, unit2 = hp.auto_fmt(ser, unit2) fig.add_trace( - go.Bar(y=ser.index.tolist(), x=ser.values, xaxis="x3", yaxis="y3", orientation="h") + go.Bar( + y=ser.index.tolist(), + x=ser.values, + xaxis="x3", + yaxis="y3", + orientation="h", + marker_color="grey", + ) ) margin = 0.01 - domain1 = (0, subplot_x_anchors[0]-margin) - domain2 = (subplot_x_anchors[0]+margin, subplot_x_anchors[1] - margin ) + domain1 = (0, subplot_x_anchors[0] - margin) + domain2 = (subplot_x_anchors[0] + margin, subplot_x_anchors[1] - margin) domain3 = (subplot_x_anchors[1] + margin, 1) capx_adder = " (decision variables in bold)" if include_capx else "" fig.update_layout( margin=dict(t=5, l=5, r=5, b=5), - xaxis=dict(domain=domain1, title=f"Capacity (kW or kWh) of component{capx_adder}"), + xaxis=dict(domain=domain1, title=f"Capacity of component (kW or kWh){capx_adder}"), xaxis2=dict(domain=domain2, anchor="y2", title=f"C_inv ({unit1})", side="top"), yaxis2=dict(anchor="x2", showticklabels=False), xaxis3=dict(domain=domain3, anchor="y3", title=f"C_op ({unit2})", side="top"), diff --git a/draf/prep/param_funcs.py b/draf/prep/param_funcs.py index 8f6d701..5e190fd 100644 --- a/draf/prep/param_funcs.py +++ b/draf/prep/param_funcs.py @@ -71,6 +71,9 @@ def c_HP_inv_(estimated_size=100) -> ParDat: """ assert 0 < estimated_size < 200 value = 1520.7 * estimated_size**-0.363 + + # see also Kosmadakis.2020 (https://doi.org/hsn7) for newer data + return ParDat(name="c_HP_inv_", data=value, doc="CAPEX", src="@Wolf_2017", unit="€/kW_el")