{ "cells": [ { "cell_type": "markdown", "metadata": { "collapsed": "true" }, "source": [ "#### Imports" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from datetime import timedelta\n", "import json\n", "import pprint\n", "from copy import deepcopy\n", "\n", "import cufflinks\n", "from matplotlib import pyplot as plt\n", "import numpy as np\n", "from numpy.polynomial import Polynomial\n", "import pandas as pd\n", "from tqdm.notebook import tqdm\n", "\n", "from pyrecoy.assets import Heatpump, Eboiler, GasBoiler\n", "from pyrecoy.colors import *\n", "from pyrecoy.converters import *\n", "from pyrecoy.financial import calculate_eb_ode, get_tax_tables, get_tax_rate, get_grid_tariffs_electricity\n", "from pyrecoy.framework import TimeFramework, CaseStudy\n", "from pyrecoy.plotting import ebitda_bar_chart, npv_bar_chart\n", "from pyrecoy.reports import CaseReport, ComparisonReport, BusinessCaseReport, SingleFigureComparison\n", "from pyrecoy.sensitivity import SensitivityAnalysis\n", "\n", "%load_ext autoreload\n", "%autoreload 2" ] }, { "cell_type": "markdown", "metadata": { "collapsed": "true" }, "source": [ "#### Development backlog" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* SDE++\n", "* aFRR (can improve the optimisation case)\n", "* Simple payback time (relevant for ENCORE, because its the main metric)\n", "* APX inkoop toevoegen (baseload inkopen, bijv. 30%)\n", "* Add explanations/conclusions to analysis/graph --> Create report-like output\n", "* Graphs\n", " * EBITDA vs. baseline (earnings vs baseline)\n", "* Show COP curves in different cases, just for illustration\n", "* Energy report --> Check + add gas\n", "* Fix comparison reports\n", "* Model verification" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Meeting Notes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Meeting 25-11-2020" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* aFRR can help optimisation case\n", "* SDE++ should be included\n", "* Tsource sensitivity really gives interesting insights\n", "* Sensitivities should be verified (especially CO2, Tsink, Tsource, time period)\n", "* AP TNO: Update/verify COP curve\n", "* AP TNO: Update CAPEX\n", "* AP Mark: \n", " * Create graphs on COP curve with different Tsource, Tsink\n", " * Generate table and output in .csv (send it to Andrew)\n", "* Investigate opportunity to lower the COP and negative electricity prices\n", " * Technically feasible, but not really needed/possible to do it in this project\n", "* Could be interesting to run this model on a usecase with higher delta T\n", "* Conclusion: Finalize this model, but not add too much extra complexity, next steps is to go towards industrial partners with the results" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# ENCORE : Heatpump Optimisation Framework\n", "\n", "***\n", "© Mark Kremer \n", "July 2020\n", "##### Cases\n", "In this model, 3 cases are compared:\n", "* **Baseline** : All heat is supplied by steam turbine\n", "* **Heatpump case** : All heat is supplied by heatpump\n", "* **Hybrid case** : Steam turbine and heatpump run in hybrid mode, and are optimised on costs in real-time" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Loading config" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "class Config():\n", " start = '2019-01-01'\n", " end = '2019-12-31'\n", " \n", " hp_vdg_e_power = 23.3 # MW\n", " hp_ndg_e_power = 7.7 # MW\n", " hp_min_load = 0.3\n", " hp_lifetime = 25\n", " hp_capex = 200_000 # EUR/MWth\n", " hp_opex = 0.01 # in % of CAPEX\n", " hp_devex = 0.005 # in % of CAPEX\n", " \n", " gb_power = 35 # MW\n", " gb_efficiency = 0.9\n", " \n", " tax_bracket_g = 4 \n", " tax_bracket_e = 4\n", " \n", " include_transport_costs = False\n", " grid_operator = 'Liander'\n", " connection_type = 'TS/MS'\n", " \n", " discount_rate = 0.1\n", " project_duration = 15\n", "\n", " forecast = 'ForeNeg'\n", " gas_price_multiplier = 1\n", " e_price_multiplier = 1\n", " e_price_volatility_multiplier = 1\n", " co2_price_multiplier = 1\n", " tsource_delta = 0\n", " energy_tax_multiplier = 1\n", " \n", "c = Config()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "class Store():\n", " pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Model set-up" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def load_demand_data(c, s):\n", " demand = pd.read_csv('data/smurfit_demand_preprocessed.csv', delimiter=';', decimal=',')\n", " dt_index = pd.date_range(\n", " start=s.time_fw.start,\n", " end=s.time_fw.start + timedelta(days=365), freq='1T',\n", " closed='left',\n", " tz='Europe/Amsterdam')\n", " demand.index = dt_index\n", " demand['Total demand'] = demand['MW (VDG)'] + demand['MW (NDG)']\n", " demand = demand[c.start:c.end]\n", " return demand" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def setup_model(c):\n", " s = Store()\n", " s.time_fw = TimeFramework(start=c.start, end=c.end)\n", "\n", " s.baseline = CaseStudy(time_fw=s.time_fw, freq='1T', name='Baseline')\n", " s.hpcase = CaseStudy(time_fw=s.time_fw, freq='1T', name='Heatpump only', forecast='mipf')\n", " s.optcase1 = CaseStudy(time_fw=s.time_fw, freq='1T', name='Optimisation', forecast='mipf')\n", " s.optcase2 = CaseStudy(time_fw=s.time_fw, freq='1T', name='Optimisation 2', forecast='mipf')\n", " \n", " s.cases = list(CaseStudy.get_instances().values())\n", " s.optcases = [s.hpcase, s.optcase1, s.optcase2]\n", " \n", " s.demand = load_demand_data(c, s)\n", " return s\n", "\n", "s = setup_model(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Load in data" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "def increase_volatility_by_factor(col, factor):\n", " mean = col.mean()\n", " diff_to_mean = col - mean\n", " new_diff = diff_to_mean * factor\n", " return mean + new_diff\n", "\n", "def increase_by_factor(col, factor):\n", " mean = col.mean()\n", " diff_to_mean = col - mean\n", " \n", " cond = diff_to_mean > 0\n", " diff_to_mean[cond] *= factor\n", " diff_to_mean[~cond] /= factor\n", " return mean + diff_to_mean" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "def load_data(c, s):\n", " for case in [s.baseline, s.optcase1, s.optcase2]:\n", " case.add_gasprices()\n", " case.add_co2prices(perMWh=True)\n", " \n", " case.data['Gas prices (€/MWh)'] = increase_by_factor(case.data['Gas prices (€/MWh)'], c.gas_price_multiplier)\n", " case.data['CO2 prices (€/MWh)'] = increase_by_factor(case.data['CO2 prices (€/MWh)'], c.co2_price_multiplier)\n", " \n", " for case in s.optcases:\n", " case.data['NEG'] = increase_by_factor(case.data['NEG'], c.e_price_multiplier)\n", " case.data['ForeNeg'] = increase_by_factor(case.data['ForeNeg'], c.e_price_multiplier)\n", " case.data['DAM'] = increase_by_factor(case.data['DAM'], c.e_price_multiplier)\n", " \n", " case.data['NEG'] = increase_volatility_by_factor(case.data['NEG'], c.e_price_volatility_multiplier)\n", " case.data['ForeNeg'] = increase_volatility_by_factor(case.data['ForeNeg'], c.e_price_volatility_multiplier)\n", " \n", " s.demand[['Tsource (VDG)', 'Tsource (NDG)']] += c.tsource_delta\n", " for case in s.cases:\n", " case.data = pd.concat([case.data, s.demand], axis=1) \n", "\n", " s.eb_ode_g = get_tax_rate('gas', 2020, 4)['EB+ODE'] * c.energy_tax_multiplier\n", " s.eb_ode_e = get_tax_rate('electricity', 2020, 4)['EB+ODE'] * c.energy_tax_multiplier\n", " s.grid_fees = get_grid_tariffs_electricity(c.grid_operator, 2020, c.connection_type)\n", " s.grid_fee_per_MWh = s.grid_fees['kWh tarief'] * 1000\n", " return s\n", "\n", "s = load_data(c, s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Assets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### COP curve" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "def cop_curve(Tsink, Tsource):\n", " Tsink += 273\n", " Tsource += 273\n", "\n", " c1 = 0.267 * Tsink / (Tsink - Tsource)\n", " c2 = 0.333 * Tsink / (Tsink - Tsource)\n", " \n", " return Polynomial([c2, c1])" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "heatpump = Heatpump(\n", " name='Heatpump',\n", " max_th_power=1,\n", " min_th_power=0,\n", " cop_curve=cop_curve\n", ")" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "import itertools\n", "\n", "source_Ts = np.arange(25, 75)\n", "sink_Ts = np.arange(80, 170)\n", "\n", "df = pd.DataFrame(columns=list(sink_Ts), index=list(source_Ts))\n", "for sourceT, sinkT in itertools.product(source_Ts, sink_Ts):\n", " df.loc[sourceT, sinkT] = heatpump.get_cop(heat_output=0.5, Tsink=sinkT, Tsource=sourceT)\n", " \n", "#df.to_csv('cops_at_50perc_load.csv', sep=';', decimal=',')" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "application/vnd.plotly.v1+json": { "config": { "linkText": "Export to plot.ly", "plotlyServerURL": "https://plot.ly", "showLink": true }, "data": [ { "line": { "color": "rgba(70, 165, 121, 1.0)", "dash": "solid", "shape": "linear", "width": 1.3 }, "mode": "lines", "name": "None", "text": "", "type": "scatter", "x": [ 0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31, 0.32, 0.33, 0.34, 0.35000000000000003, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41000000000000003, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47000000000000003, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.5700000000000001, 0.58, 0.59, 0.6, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.6900000000000001, 0.7000000000000001, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.8, 0.81, 0.8200000000000001, 0.8300000000000001, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.9, 0.91, 0.92, 0.93, 0.9400000000000001, 0.9500000000000001, 0.96, 0.97, 0.98, 0.99 ], "y": [ 1.786090909090909, 1.800411818181818, 1.8147327272727272, 1.8290536363636363, 1.8433745454545454, 1.8576954545454545, 1.8720163636363636, 1.8863372727272727, 1.9006581818181816, 1.9149790909090907, 1.9292999999999998, 1.943620909090909, 1.957941818181818, 1.9722627272727271, 1.9865836363636362, 2.0009045454545453, 2.015225454545454, 2.0295463636363635, 2.0438672727272724, 2.0581881818181818, 2.0725090909090906, 2.08683, 2.101150909090909, 2.115471818181818, 2.129792727272727, 2.1441136363636364, 2.1584345454545453, 2.1727554545454546, 2.1870763636363635, 2.2013972727272724, 2.2157181818181817, 2.2300390909090906, 2.24436, 2.258680909090909, 2.273001818181818, 2.287322727272727, 2.3016436363636363, 2.315964545454545, 2.3302854545454545, 2.3446063636363634, 2.3589272727272728, 2.3732481818181816, 2.387569090909091, 2.40189, 2.4162109090909087, 2.430531818181818, 2.4448527272727274, 2.4591736363636363, 2.473494545454545, 2.4878154545454545, 2.5021363636363634, 2.5164572727272727, 2.5307781818181816, 2.545099090909091, 2.55942, 2.573740909090909, 2.588061818181818, 2.6023827272727273, 2.6167036363636362, 2.631024545454545, 2.6453454545454544, 2.6596663636363633, 2.6739872727272727, 2.6883081818181815, 2.702629090909091, 2.7169499999999998, 2.731270909090909, 2.745591818181818, 2.7599127272727273, 2.774233636363636, 2.7885545454545455, 2.8028754545454544, 2.8171963636363637, 2.8315172727272726, 2.8458381818181815, 2.860159090909091, 2.87448, 2.888800909090909, 2.903121818181818, 2.9174427272727272, 2.9317636363636366, 2.9460845454545455, 2.9604054545454543, 2.9747263636363637, 2.9890472727272726, 3.003368181818182, 3.0176890909090908, 3.0320099999999996, 3.046330909090909, 3.0606518181818183, 3.074972727272727, 3.089293636363636, 3.1036145454545454, 3.1179354545454547, 3.1322563636363636, 3.1465772727272725, 3.1608981818181814, 3.1752190909090907, 3.18954, 3.203860909090909 ] } ], "layout": { "autosize": true, "legend": { "bgcolor": "#F5F6F9", "font": { "color": "#4D5663" } }, "paper_bgcolor": "#F5F6F9", "plot_bgcolor": "#F5F6F9", "template": { "data": { "bar": [ { "error_x": { "color": "#2a3f5f" }, "error_y": { "color": "#2a3f5f" }, "marker": { "line": { "color": "#E5ECF6", "width": 0.5 } }, "type": "bar" } ], "barpolar": [ { "marker": { "line": { "color": "#E5ECF6", "width": 0.5 } }, "type": "barpolar" } ], "carpet": [ { "aaxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "baxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "type": "carpet" } ], "choropleth": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "choropleth" } ], "contour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "contour" } ], "contourcarpet": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "contourcarpet" } ], "heatmap": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmap" } ], "heatmapgl": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmapgl" } ], "histogram": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "histogram" } ], "histogram2d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2d" } ], "histogram2dcontour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2dcontour" } ], "mesh3d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "mesh3d" } ], "parcoords": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "parcoords" } ], "pie": [ { "automargin": true, "type": "pie" } ], "scatter": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter" } ], "scatter3d": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter3d" } ], "scattercarpet": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattercarpet" } ], "scattergeo": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergeo" } ], "scattergl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergl" } ], "scattermapbox": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattermapbox" } ], "scatterpolar": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolar" } ], "scatterpolargl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolargl" } ], "scatterternary": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterternary" } ], "surface": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "surface" } ], "table": [ { "cells": { "fill": { "color": "#EBF0F8" }, "line": { "color": "white" } }, "header": { "fill": { "color": "#C8D4E3" }, "line": { "color": "white" } }, "type": "table" } ] }, "layout": { "annotationdefaults": { "arrowcolor": "#2a3f5f", "arrowhead": 0, "arrowwidth": 1 }, "coloraxis": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "colorscale": { "diverging": [ [ 0, "#8e0152" ], [ 0.1, "#c51b7d" ], [ 0.2, "#de77ae" ], [ 0.3, "#f1b6da" ], [ 0.4, "#fde0ef" ], [ 0.5, "#f7f7f7" ], [ 0.6, "#e6f5d0" ], [ 0.7, "#b8e186" ], [ 0.8, "#7fbc41" ], [ 0.9, "#4d9221" ], [ 1, "#276419" ] ], "sequential": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "sequentialminus": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ] }, "colorway": [ "#636efa", "#EF553B", "#00cc96", "#ab63fa", "#FFA15A", "#19d3f3", "#FF6692", "#B6E880", "#FF97FF", "#FECB52" ], "font": { "color": "#2a3f5f" }, "geo": { "bgcolor": "white", "lakecolor": "white", "landcolor": "#E5ECF6", "showlakes": true, "showland": true, "subunitcolor": "white" }, "hoverlabel": { "align": "left" }, "hovermode": "closest", "mapbox": { "style": "light" }, "paper_bgcolor": "white", "plot_bgcolor": "#E5ECF6", "polar": { "angularaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "radialaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "scene": { "xaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "yaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "zaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" } }, "shapedefaults": { "line": { "color": "#2a3f5f" } }, "ternary": { "aaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "baxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "caxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "title": { "x": 0.05 }, "xaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 }, "yaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 } } }, "title": { "font": { "color": "#4D5663" }, "text": "Heatpump COP curve" }, "xaxis": { "autorange": true, "gridcolor": "#E1E5ED", "range": [ 0, 0.99 ], "showgrid": true, "tickfont": { "color": "#4D5663" }, "title": { "font": { "color": "#4D5663" }, "text": "Thermal load in %" }, "type": "linear", "zerolinecolor": "#E1E5ED" }, "yaxis": { "autorange": true, "gridcolor": "#E1E5ED", "range": [ 1.707325909090909, 3.282625909090909 ], "showgrid": true, "tickfont": { "color": "#4D5663" }, "title": { "font": { "color": "#4D5663" }, "text": "COP" }, "type": "linear", "zerolinecolor": "#E1E5ED" } } }, "image/png": "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", "text/html": [ "
\n", " \n", " \n", "
\n", " \n", "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "sourceT = 63\n", "sinkT = 140\n", "loads = np.arange(0, 1, 0.01)\n", "\n", "series = pd.Series(index=loads, dtype='float')\n", "for load in loads:\n", " series[load] = heatpump.get_cop(heat_output=load, Tsink=sinkT, Tsource=sourceT)\n", " \n", "series.iplot(title='Heatpump COP curve', yTitle='COP', xTitle='Thermal load in %', colors=recoygreen)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create and assign assets" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "def create_and_assign_assets(c, s):\n", " heatpump_vdg = Heatpump(\n", " name='Heatpump VDG',\n", " max_th_power=c.hp_vdg_e_power,\n", " min_th_power=c.hp_vdg_e_power * c.hp_min_load,\n", " cop_curve=cop_curve\n", " )\n", "\n", " heatpump_ndg = Heatpump(\n", " name='Heatpump NDG',\n", " max_th_power=c.hp_ndg_e_power,\n", " min_th_power=c.hp_ndg_e_power * c.hp_min_load,\n", " cop_curve=cop_curve\n", " )\n", "\n", " capex_vdg = c.hp_capex*(heatpump_vdg.max_th_power) \n", " capex_ndg = c.hp_capex*(heatpump_ndg.max_th_power)\n", " heatpump_vdg.set_financials(capex=capex_vdg, opex=c.hp_opex*capex_vdg, devex=c.hp_devex*capex_vdg, lifetime=25)\n", " heatpump_ndg.set_financials(capex=capex_ndg, opex=c.hp_opex*capex_ndg, devex=c.hp_devex*capex_ndg, lifetime=25)\n", "\n", " gasboiler = GasBoiler(\n", " name='Gasboiler',\n", " max_th_output=c.gb_power,\n", " efficiency=c.gb_efficiency\n", " )\n", " gasboiler.set_financials(capex=0, opex=0, devex=0, lifetime=25)\n", " \n", " s.baseline.add_asset(gasboiler)\n", " s.hpcase.add_asset(heatpump_vdg)\n", " s.hpcase.add_asset(heatpump_ndg)\n", " s.optcase1.add_asset(heatpump_vdg)\n", " s.optcase1.add_asset(heatpump_ndg)\n", " s.optcase1.add_asset(gasboiler)\n", " s.optcase2.add_asset(heatpump_vdg)\n", " s.optcase2.add_asset(heatpump_ndg)\n", " s.optcase2.add_asset(gasboiler)\n", " return s\n", "\n", "s = create_and_assign_assets(c, s)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Gas prices (€/MWh)CO2 prices (€/ton)CO2 prices (€/MWh)Tsource (VDG)Tsink (VDG)MW (VDG)Tsource (NDG)Tsink (NDG)MW (NDG)Total demand
count525600.000000525600.000000525600.000000525600.000000525600.000000525600.000000525600.000000525600.000000525600.000000525600.000000
mean13.53874524.8640184.68314463.658798138.63767417.63671262.176305145.3516455.82382423.460537
std3.6447792.1425740.4038276.42277314.3285805.12325210.25255514.8960561.6916976.814125
min7.53000018.7000003.52000025.31000082.4800000.00000013.540000106.3300000.0000000.000000
25%10.38000023.6700004.46000064.892000126.07400017.01400063.516000131.5515005.61200022.676000
50%12.85000025.0800004.72000064.991000142.45000019.89200064.313000148.4900006.54000026.441000
75%15.60000026.2900004.95000065.076000151.73000020.81900065.546000158.1000006.88000027.690000
max22.67000029.7700005.61000070.070000166.02000023.25000073.470000172.0500007.65000030.900000
\n", "
" ], "text/plain": [ " Gas prices (€/MWh) CO2 prices (€/ton) CO2 prices (€/MWh) \\\n", "count 525600.000000 525600.000000 525600.000000 \n", "mean 13.538745 24.864018 4.683144 \n", "std 3.644779 2.142574 0.403827 \n", "min 7.530000 18.700000 3.520000 \n", "25% 10.380000 23.670000 4.460000 \n", "50% 12.850000 25.080000 4.720000 \n", "75% 15.600000 26.290000 4.950000 \n", "max 22.670000 29.770000 5.610000 \n", "\n", " Tsource (VDG) Tsink (VDG) MW (VDG) Tsource (NDG) \\\n", "count 525600.000000 525600.000000 525600.000000 525600.000000 \n", "mean 63.658798 138.637674 17.636712 62.176305 \n", "std 6.422773 14.328580 5.123252 10.252555 \n", "min 25.310000 82.480000 0.000000 13.540000 \n", "25% 64.892000 126.074000 17.014000 63.516000 \n", "50% 64.991000 142.450000 19.892000 64.313000 \n", "75% 65.076000 151.730000 20.819000 65.546000 \n", "max 70.070000 166.020000 23.250000 73.470000 \n", "\n", " Tsink (NDG) MW (NDG) Total demand \n", "count 525600.000000 525600.000000 525600.000000 \n", "mean 145.351645 5.823824 23.460537 \n", "std 14.896056 1.691697 6.814125 \n", "min 106.330000 0.000000 0.000000 \n", "25% 131.551500 5.612000 22.676000 \n", "50% 148.490000 6.540000 26.441000 \n", "75% 158.100000 6.880000 27.690000 \n", "max 172.050000 7.650000 30.900000 " ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.baseline.data.describe()" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "heatpump = Heatpump(\n", " name='Heatpump',\n", " max_th_power=1,\n", " min_th_power=0,\n", " cop_curve=cop_curve\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Optimization" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Strategies" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "def baseline_sim(case):\n", " gasboiler = list(case.assets.values())[0]\n", " data = case.data\n", " demand = (data['MW (VDG)'] + data['MW (NDG)']).to_list()\n", "\n", " minutes = iter(range(len(case.data)))\n", " th_output = [0] * len(case.data)\n", " gas_input = [0] * len(case.data)\n", "\n", " for m in minutes:\n", " th_output[m], gas_input[m] = gasboiler.set_heat_output(demand[m])\n", "\n", " data['output_MW_th'] = np.array(th_output)\n", " data['output_MWh_th'] = np.array(data['output_MW_th']/60)\n", " data['gb_input_MW'] = np.array(gas_input)\n", " data['gb_input_MWh'] = np.array(data['gb_input_MW']/60)\n", " case.data = data.round(5)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "def hponly(case):\n", " hp_vdg = case.assets['Heatpump VDG']\n", " hp_ndg = case.assets['Heatpump NDG']\n", " demand_vdg = case.data['MW (VDG)'].to_list()\n", " demand_ndg = case.data['MW (NDG)'].to_list()\n", " Tsink_vdg = case.data['Tsink (VDG)'].to_list()\n", " Tsink_ndg = case.data['Tsink (NDG)'].to_list()\n", " Tsource_vdg = case.data['Tsource (VDG)'].to_list()\n", " Tsource_ndg = case.data['Tsource (NDG)'].to_list()\n", "\n", " hp_vdg_input = [0] * len(case.data)\n", " hp_ndg_input = [0] * len(case.data)\n", " hp_vdg_output = [0] * len(case.data)\n", " hp_ndg_output = [0] * len(case.data)\n", "\n", " minutes = iter(range(len(case.data)))\n", " for m in minutes:\n", " demand = demand_vdg[m]\n", " if demand != 0:\n", " hp_vdg_output[m], hp_vdg_input[m] = hp_vdg.set_heat_output(\n", " heat_output=demand,\n", " Tsink=Tsink_vdg[m],\n", " Tsource=Tsource_vdg[m]\n", " )\n", "\n", " demand = demand_ndg[m]\n", " if demand != 0:\n", " hp_ndg_output[m], hp_ndg_input[m] = hp_ndg.set_heat_output(\n", " heat_output=demand_ndg[m],\n", " Tsink=Tsink_ndg[m],\n", " Tsource=Tsource_ndg[m]\n", " )\n", "\n", " case.data['hp_output_MW'] = np.array(hp_vdg_output) + np.array(hp_ndg_output)\n", " case.data['hp_input_MW'] = np.array(hp_vdg_input) + np.array(hp_ndg_input)\n", "\n", " for col in case.data.columns:\n", " if col.endswith('MW'):\n", " case.data[col + 'h'] = case.data[col] / 60\n", "\n", " case.data = case.data.round(3)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "def strategy(case, decimals, tolerance, s):\n", " gb = case.assets['Gasboiler']\n", " hp_vdg = case.assets['Heatpump VDG']\n", " hp_ndg = case.assets['Heatpump NDG']\n", " demand_vdg = case.data['MW (VDG)'].round(decimals).to_list()\n", " demand_ndg = case.data['MW (NDG)'].round(decimals).to_list()\n", " Tsink_vdg = case.data['Tsink (VDG)'].round(decimals).to_list()\n", " Tsink_ndg = case.data['Tsink (NDG)'].round(decimals).to_list()\n", " Tsource_vdg = case.data['Tsource (VDG)'].round(decimals).to_list()\n", " Tsource_ndg = case.data['Tsource (NDG)'].round(decimals).to_list()\n", " fore_neg = case.data[c.forecast].fillna(999).round(decimals).to_list()\n", " gas_prices = case.data['Gas prices (€/MWh)'].round(decimals).to_list()\n", " co2_prices = case.data['CO2 prices (€/MWh)'].round(decimals).to_list()\n", " eb_ode_g = s.eb_ode_g\n", " eb_ode_e = s.eb_ode_e\n", " \n", " gb_input = [0] * len(case.data)\n", " gb_output = [0] * len(case.data)\n", "\n", " minutes = range(len(case.data))\n", " hp_output = [0] * len(case.data)\n", " hp_input = [0] * len(case.data)\n", "\n", " for m in tqdm(minutes):\n", " dem_vgd = demand_vdg[m]\n", " if dem_vgd != 0:\n", " hp_vdg_input, hp_vdg_output = hp_vdg.set_opt_load(\n", " electricity_cost=fore_neg[m] + eb_ode_e,\n", " alt_heat_price=gas_prices[m] + co2_prices[m] + eb_ode_g/case.assets['Gasboiler'].efficiency,\n", " demand=dem_vgd,\n", " Tsink=Tsink_vdg[m],\n", " Tsource=Tsource_vdg[m],\n", " tolerance=tolerance\n", " )\n", " else:\n", " hp_vdg_input, hp_vdg_output = (0, 0)\n", "\n", " dem_ngd = demand_ndg[m]\n", " if dem_ngd != 0:\n", " hp_ndg_input, hp_ndg_output = hp_ndg.set_opt_load(\n", " electricity_cost=fore_neg[m] + eb_ode_e,\n", " alt_heat_price=(gas_prices[m] + co2_prices[m] + eb_ode_g)/case.assets['Gasboiler'].efficiency,\n", " demand=dem_ngd,\n", " Tsink=Tsink_ndg[m],\n", " Tsource=Tsource_ndg[m],\n", " tolerance=tolerance\n", " )\n", " else:\n", " hp_ndg_input, hp_ndg_output = (0, 0)\n", "\n", " hp_out = hp_vdg_output + hp_ndg_output\n", " hp_output[m] = hp_out\n", " hp_input[m] = hp_vdg_input + hp_ndg_input\n", " remaining_demand = max(dem_vgd+dem_ngd-hp_out, 0)\n", " gb_output[m], gb_input[m] = gb.set_heat_output(remaining_demand)\n", "\n", " case.data['hp_output_MW'] = np.array(hp_output)\n", " case.data['hp_input_MW'] = np.array(hp_input)\n", " case.data['gb_output_MW'] = np.array(gb_output)\n", " case.data['gb_input_MW'] = np.array(gb_input)\n", "\n", " for col in case.data.columns:\n", " if col.endswith('MW'):\n", " case.data[col + 'h'] = case.data[col] / 60\n", "\n", " case.data = case.data.round(5)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "def cost_function(th_load, cop, electricity_cost, alt_heat_price, demand):\n", " return (\n", " th_load / cop * electricity_cost\n", " + (demand - th_load) * alt_heat_price\n", " )" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "def strategy_(case, decimals, s):\n", " gb = case.assets['Gasboiler']\n", " hp_vdg = case.assets['Heatpump VDG']\n", " hp_ndg = case.assets['Heatpump NDG']\n", " demand_vdg = case.data['MW (VDG)'].round(decimals).to_list()\n", " demand_ndg = case.data['MW (NDG)'].round(decimals).to_list()\n", " Tsink_vdg = case.data['Tsink (VDG)'].round(decimals).to_list()\n", " Tsink_ndg = case.data['Tsink (NDG)'].round(decimals).to_list()\n", " Tsource_vdg = case.data['Tsource (VDG)'].round(decimals).to_list()\n", " Tsource_ndg = case.data['Tsource (NDG)'].round(decimals).to_list()\n", " fore_neg = case.data[c.forecast].fillna(999).round(decimals).to_list()\n", " gas_prices = case.data['Gas prices (€/MWh)'].round(decimals).to_list()\n", " co2_prices = case.data['CO2 prices (€/MWh)'].round(decimals).to_list()\n", " eb_ode_g = s.eb_ode_g\n", " eb_ode_e = s.eb_ode_e\n", " \n", " gb_input = [0] * len(case.data)\n", " gb_output = [0] * len(case.data)\n", "\n", " minutes = range(len(case.data))\n", " hp_output = [0] * len(case.data)\n", " hp_input = [0] * len(case.data)\n", "\n", " for m in tqdm(minutes):\n", " dem_vgd = demand_vdg[m]\n", " if dem_vgd != 0:\n", " max_load = min(hp_vdg.max_th_power, dem_vgd)\n", " min_load = hp_vdg.min_th_power\n", " Tsink = Tsink_vdg[m]\n", " Tsource = Tsource_vdg[m]\n", " cop_max_load = hp_vdg.get_cop(heat_output=max_load, Tsink=Tsink, Tsource=Tsource)\n", " cop_min_load = hp_vdg.get_cop(heat_output=min_load, Tsink=Tsink_vdg[m], Tsource=Tsource_vdg[m])\n", " \n", " cost_full_load = cost_function(\n", " th_load=max_load,\n", " cop=cop_max_load,\n", " electricity_cost=fore_neg[m] + eb_ode_e,\n", " alt_heat_price=gas_prices[m] + co2_prices[m] + eb_ode_g/case.assets['Gasboiler'].efficiency,\n", " demand=dem_vgd\n", " )\n", " \n", " cost_min_load = cost_function(\n", " th_load=min_load,\n", " cop=cop_min_load,\n", " electricity_cost=fore_neg[m] + eb_ode_e,\n", " alt_heat_price=gas_prices[m] + co2_prices[m] + eb_ode_g/case.assets['Gasboiler'].efficiency,\n", " demand=dem_vgd\n", " )\n", " \n", " if cost_full_load < cost_min_load:\n", " hp_vdg_input, hp_vdg_output = hp_vdg.set_heat_output(max_load, Tsink, Tsource)\n", " else:\n", " hp_vdg_input, hp_vdg_output = hp_vdg.set_heat_output(min_load, Tsink, Tsource)\n", " else:\n", " hp_vdg_input, hp_vdg_output = (0, 0)\n", "\n", " dem_ngd = demand_ndg[m]\n", " if dem_ngd != 0:\n", " max_load = min(hp_ndg.max_th_power, dem_ngd)\n", " min_load = hp_ndg.min_th_power\n", " Tsink = Tsink_ndg[m]\n", " Tsource = Tsource_ndg[m]\n", " cop_max_load = hp_ndg.get_cop(heat_output=max_load, Tsink=Tsink, Tsource=Tsource)\n", " cop_min_load = hp_ndg.get_cop(heat_output=min_load, Tsink=Tsink, Tsource=Tsource)\n", " \n", " cost_full_load = cost_function(\n", " th_load=max_load,\n", " cop=cop_max_load,\n", " electricity_cost=fore_neg[m] + eb_ode_e,\n", " alt_heat_price=gas_prices[m] + co2_prices[m] + eb_ode_g/case.assets['Gasboiler'].efficiency,\n", " demand=dem_ngd\n", " )\n", " \n", " cost_min_load = cost_function(\n", " th_load=min_load,\n", " cop=cop_min_load,\n", " electricity_cost=fore_neg[m] + eb_ode_e,\n", " alt_heat_price=gas_prices[m] + co2_prices[m] + eb_ode_g/case.assets['Gasboiler'].efficiency,\n", " demand=dem_vgd\n", " )\n", " \n", " if cost_full_load <= cost_min_load:\n", " hp_ndg_input, hp_ndg_output = hp_ndg.set_heat_output(max_load, Tsink=Tsink, Tsource=Tsource)\n", " else:\n", " hp_ndg_input, hp_ndg_output = hp_ndg.set_heat_output(min_load, Tsink=Tsink, Tsource=Tsource)\n", " else:\n", " hp_ndg_input, hp_ndg_output = (0, 0)\n", "\n", " hp_out = hp_vdg_output + hp_ndg_output\n", " hp_output[m] = hp_out\n", " hp_input[m] = hp_vdg_input + hp_ndg_input\n", " remaining_demand = max(dem_vgd+dem_ngd-hp_out, 0)\n", " gb_output[m], gb_input[m] = gb.set_heat_output(remaining_demand)\n", "\n", " case.data['hp_output_MW'] = np.array(hp_output)\n", " case.data['hp_input_MW'] = np.array(hp_input)\n", " case.data['gb_output_MW'] = np.array(gb_output)\n", " case.data['gb_input_MW'] = np.array(gb_input)\n", "\n", " for col in case.data.columns:\n", " if col.endswith('MW'):\n", " case.data[col + 'h'] = case.data[col] / 60\n", "\n", " case.data = case.data.round(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Run optimisation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Wall time: 1.93 s\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "c:\\users\\mekre\\onedrive - recoy\\work\\code\\python\\_packages\\pyrecoy\\pyrecoy\\assets.py:253: UserWarning:\n", "\n", "Chosen heat output is out of range [6.99 - 23.3]. Heat output is being limited to the closest boundary.\n", "\n", "c:\\users\\mekre\\onedrive - recoy\\work\\code\\python\\_packages\\pyrecoy\\pyrecoy\\assets.py:253: UserWarning:\n", "\n", "Chosen heat output is out of range [2.31 - 7.7]. Heat output is being limited to the closest boundary.\n", "\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Wall time: 13.6 s\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "24cab81d4f1e493f86a78d3287d8e049", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(FloatProgress(value=0.0, max=525600.0), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def run_optimisation(c, s):\n", " s.baseline.assign_algorithm(baseline_sim)\n", " %time s.baseline.run()\n", " \n", " s.hpcase.assign_algorithm(hponly)\n", " %time s.hpcase.run()\n", " \n", " s.optcase1.assign_algorithm(strategy)\n", " %time s.optcase1.run(decimals=0, tolerance=1, s=s)\n", "\n", " s.optcase2.assign_algorithm(strategy_)\n", " %time s.optcase2.run(decimals=2, s=s)\n", " return s\n", "\n", "s = run_optimisation(c, s)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.optcase1.data.columns" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.optcase1.data['hp_input_MW']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.optcase2.data['hp_input_MW']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Financials" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# SDE++\n", "# ..." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def collect_cashflows(c, s):\n", " s.hpcase.generate_electr_market_results(nom_col='hp_input_MWh', real_col='hp_input_MWh')\n", " s.optcase1.generate_electr_market_results(nom_col=None, real_col='hp_input_MWh')\n", " s.optcase2.generate_electr_market_results(nom_col=None, real_col='hp_input_MWh')\n", " \n", " for case in [s.baseline, s.optcase1, s.optcase2]:\n", " case.add_gas_costs(gasvolumes_col='gb_input_MWh')\n", " case.add_co2_costs(volume_cols='gb_input_MWh', fuel='gas')\n", " case.add_eb_ode(commodity='gas', tax_bracket=c.tax_bracket_g)\n", " \n", " for case in [s.hpcase, s.optcase1, s.optcase2]:\n", " case.add_eb_ode(commodity='electricity', tax_bracket=c.tax_bracket_e)\n", " case.add_grid_costs(\n", " power_MW_col='hp_input_MW',\n", " grid_operator=c.grid_operator,\n", " year=2020, \n", " connection_type=c.connection_type\n", " )\n", " \n", " return s\n", "\n", "s = collect_cashflows(c, s)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def calculate_financials(c, s):\n", " for case in s.cases:\n", " case.calculate_ebitda()\n", "\n", " for case in [s.optcase1, s.optcase2]:\n", " case.calculate_business_case(\n", " project_duration=c.project_duration, \n", " discount_rate=c.discount_rate, \n", " baseline=s.baseline\n", " )\n", " \n", " return s\n", "\n", "s = calculate_financials(c, s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualisations" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.demand['Total demand'].resample('H').mean().iplot(title='Heat demand by Hour in MW', yTitle='MW', colors=recoygreen)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.demand[['Tsource (VDG)', 'Tsink (VDG)', 'Tsource (NDG)', 'Tsink (NDG)']].plot(kind='box')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.optcase1.data.columns" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "test_hp = Heatpump(\n", " name='Heatpump for Testing',\n", " max_th_power=1,\n", " min_th_power=0.3,\n", " cop_curve=cop_curve\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Tsrc_vdg, Tsnk_vdg, Tsrc_ndg, Tsnk_ndg = s.demand[['Tsource (VDG)', 'Tsink (VDG)', 'Tsource (NDG)', 'Tsink (NDG)']].mean().to_list()\n", "mean_gas_price = (s.optcase1.data['Gas prices (€/MWh)'].mean() \n", " + s.eb_ode_g \n", " + s.optcase1.data['CO2 prices (€/MWh)'].mean()\n", " )\n", "\n", "max_gas_price = (s.optcase1.data['Gas prices (€/MWh)'].max() \n", " + s.eb_ode_g \n", " + s.optcase1.data['CO2 prices (€/MWh)'].max()\n", " )\n", "\n", "min_gas_price = (s.optcase1.data['Gas prices (€/MWh)'].min() \n", " + s.eb_ode_g \n", " + s.optcase1.data['CO2 prices (€/MWh)'].min()\n", " )\n", "\n", "Tsrc_vdg_min, Tsnk_vdg_min, Tsrc_ndg_min, Tsnk_ndg_min = s.demand[['Tsource (VDG)', 'Tsink (VDG)', 'Tsource (NDG)', 'Tsink (NDG)']].min().to_list()\n", "Tsrc_vdg_max, Tsnk_vdg_max, Tsrc_ndg_max, Tsnk_ndg_max = s.demand[['Tsource (VDG)', 'Tsink (VDG)', 'Tsource (NDG)', 'Tsink (NDG)']].max().to_list()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def create_load_trace(gas_price, Tsnk, Tsrc, name):\n", " loads = []\n", " eprices = list(range(500))\n", " for eprice in eprices:\n", " _, load = test_hp.set_opt_load(\n", " electricity_cost=eprice + s.eb_ode_e,\n", " alt_heat_price=gas_price / 0.9,\n", " demand=1, \n", " Tsink=Tsnk,\n", " Tsource=Tsrc\n", " )\n", " loads.append(load)\n", " trace = go.Scatter(x=eprices, y=loads, name=name)\n", " return trace" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import plotly.graph_objects as go\n", "import numpy as np\n", "\n", "fig = go.Figure()\n", "\n", "configs = {\n", " 'mean': [mean_gas_price, Tsnk_vdg, Tsrc_vdg],\n", " 'unfav_gas': [min_gas_price, Tsnk_vdg, Tsrc_vdg],\n", " 'fav_gas': [max_gas_price, Tsnk_vdg, Tsrc_vdg],\n", " 'unfav_all': [min_gas_price, Tsnk_vdg_max, Tsrc_vdg_min],\n", " 'fav_all': [max_gas_price, Tsnk_vdg_min, Tsrc_vdg_max],\n", "}\n", "\n", "for name, config in configs.items():\n", " trace = create_load_trace(*config, name)\n", " fig.add_trace(trace)\n", "\n", "fig.update_layout(title='Switch prices for different configurations')\n", "fig.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "date = '2019-01-01'\n", "s.baseline.data[['Total demand', 'output_MW_th', 'gb_input_MW']].abs().loc[date, :].iplot(\n", " subplots=True, \n", " title=f'Baseline case on {date}',\n", " subplot_titles=['Total demand', 'Steam boiler output (MW)', 'Steam boiler input (MW)'],\n", " legend=False,\n", " dimensions=(1000, 500)\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.hpcase.data[['Total demand', 'hp_output_MW', 'hp_input_MW']].abs().loc[date, :].iplot(\n", " subplots=True, \n", " title=f'Heatpump case on {date}', \n", " subplot_titles=['Total demand', 'Heatpump output(MW)', 'Heatpump input (MW)'],\n", " legend=False,\n", " dimensions=(1000, 500)\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig = s.optcase1.data[['Total demand', 'hp_output_MW', 'hp_input_MW', 'gb_output_MW', 'gb_input_MW', 'NEG', 'Gas prices (€/MWh)']].loc[date, :].iplot(\n", " subplots=True, \n", " title=f'Hybrid case on {date}',\n", " subplot_titles=['Total demand (MW)', 'Heatpump output (MW)', 'Heatpump input (MW)', 'Steam boiler output (MW)', 'Steam boiler input (MW)', 'Imbalance price (€/MWh)', 'Gas price (€/MWh)'],\n", " legend=False,\n", " dimensions=(1000, 600)\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "report = ComparisonReport(\n", " cases=s.optcases, \n", " kind='electr_market_results',\n", ")\n", "report.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "casereport = ComparisonReport(cases = s.cases, kind='ebitda_calc')\n", "casereport.show(presentation_format=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "BusinessCaseReport(s.optcase1).show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#price chart\n", "from copy import deepcopy\n", "\n", "data = deepcopy(s.baseline.data)\n", "data = data[data.columns[:2]]\n", "data[data.columns[1]] = MWh_gas_to_tonnes_CO2(data[data.columns[1]])\n", "data = data.rename(columns={\"CO2 prices (€/ton)\": \"CO2 prices (€/MWh)\"})\n", "\n", "data.resample('D').mean().iplot(dimensions=(800, 300), title='Gasprices vs. CO2 prices')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "_source_output = s.optcase1.data[['hp_output_MWh', 'gb_output_MWh']].resample('M').sum()\n", "_total_output = _source_output.sum(axis=1)\n", "_data = _source_output.divide(_total_output, axis=0).rename(\n", " columns={'hp_output_MWh':'Heat pump', 'gb_output_MWh':'Gasboiler'}\n", ") * 100\n", "\n", "_data.iplot(\n", " kind='bar',\n", " barmode='stack',\n", " colors=[recoydarkblue, recoygreen],\n", " title='Hybrid case: Heat production per Month by Source in % share',\n", " yTitle='Share of production in %',\n", " dimensions=(600, 400)\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "report = ComparisonReport(s.cases, kind='capex').report\n", "report = report[report.index.str.contains('CAPEX')].T\n", "report.iplot(\n", " kind='bar', \n", " barmode='relative',\n", " colors=recoycolors,\n", " title='CAPEX by Casestudy',\n", " yTitle='CAPEX in €',\n", " dimensions=(600, 400)\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cashflow_report = ComparisonReport(cases = s.cases, kind='cashflows')\n", "\n", "fig = cashflow_report.report.T.iplot(\n", " kind='bar',\n", " barmode='relative',\n", " colors=recoycolors,\n", " title='OPEX breakdown',\n", " asFigure=True,\n", " yTitle='€',\n", " dimensions=(600, 400)\n", ")\n", "\n", "ebitda_report = ComparisonReport(cases=s.cases, kind='ebitda_calc')\n", "scat = go.Scatter(\n", " mode='markers',\n", " y=ebitda_report.report.loc['EBITDA (€)', :].values, \n", " x=ebitda_report.report.columns, \n", " line=go.scatter.Line(color=recoydarkgrey),\n", " marker=dict(\n", " color=recoydarkgrey,\n", " size=20,\n", " line=dict(\n", " color=recoydarkgrey,\n", " width=3\n", " ),\n", " symbol='line-ew'\n", " ),\n", " name='EBITDA (€)'\n", ")\n", "fig.add_trace(scat)\n", "fig" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "SingleFigureComparison(s.optcases, 'npv', label='NPV').report.iplot(\n", " kind='bar',\n", " title='NPV by Casestudy in €',\n", " colors=recoygreen,\n", " dimensions=(600, 400)\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(SingleFigureComparison(s.optcases, 'irr', label='IRR').report * 100).iplot(\n", " kind='bar',\n", " title='IRR by Casestudy in %',\n", " colors=recoygreen,\n", " dimensions=(600, 400)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sensitivity analysis" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have agreed that for the sensitivity analysis we will vary the following key assumptions in the flex-model:\n", "1. Market prices of gas and electricity. We will use the actual prices for 2019, the actual prices for 2020 and two simulated years based on the prices in 2019 +30% and 2019 -30% . __Check 2018 results__\n", "2. __aFRR prices +/- 30%__\n", "3. CAPEX __(add +100% scenario's, CAPEX is w/out integration costs - integration costs might be very high.)__\n", "4. CO2 price __(larger impacts expected, check calculations, try higher levels of 50-100-150€/ton average)__\n", "5. Tsource +/- 10 degrees Celsius __Verify results__\n", "6. __Tsink__ \n", " * +/- 10 degrees celcius\n", " * Roam off the peak / lower pressure\n", " * Stabalize / running average per hour/ 2 hours\n", "7. __A scenario with a constraint on grid capacity and a scenario without grid capacity as a constraint__\n", "8. Energy Tax and ODE +/- 30%" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def setup():\n", " _c = Config()\n", " s = setup_model(c=_c)\n", " return s\n", "\n", "def routine(c, s):\n", " s = load_data(c=c, s=s)\n", " s = create_and_assign_assets(c=c, s=s)\n", " s = run_optimisation(c=c, s=s)\n", " s = collect_cashflows(c=c, s=s)\n", " s = calculate_financials(c=c, s=s)\n", " return s" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#%time _s = setup()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#%time result = routine(c, _s)\n", "#npv = result.hpcase.npv\n", "#npv" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sensitivity: Heat Pump CAPEX" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "_s = setup()\n", "configs = {}\n", "values = [c.hp_capex * mult for mult in [0.7, 1, 1.3]]\n", "for value in values:\n", " _c = Config()\n", " _c.hp_capex = value\n", " configs[value] = _c" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "sens1 = SensitivityAnalysis(_s, routine, configs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "output1 = sens1.single_kpi_overview('npv', case_names=['Heatpump only', 'Optimisation'])\n", "output1.iplot(\n", " mode='lines+markers',\n", " symbol='circle-dot',\n", " size=10,\n", " xTitle='CAPEX (€)',\n", " yTitle='NPV in €',\n", " yrange=[0, output1.max().max()*1.1],\n", " title='Sensitivity: Heat Pump CAPEX (€)',\n", " colors=[recoygreen, recoyyellow],\n", " dimensions=(600, 400)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sensitivity: CO2 prices" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "_s = setup()\n", "configs = {}\n", "values = [0.7, 1, 1.3]\n", "for value in values:\n", " _c = Config()\n", " _c.co2_price_multiplier = value\n", " configs[value] = _c" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "sens4 = SensitivityAnalysis(_s, routine, configs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "output = sens4.single_kpi_overview('irr', case_names=['Heatpump only', 'Optimisation'])\n", "output.iplot(\n", " mode='lines+markers',\n", " symbol='circle-dot',\n", " size=10,\n", " xTitle='CO2 price factor',\n", " yTitle='NPV in €',\n", " yrange=[0, output.max().max()*1.1],\n", " title='Sensitivity: CO2 prices',\n", " colors=[recoygreen, recoyyellow],\n", " dimensions=(600, 400)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sensitivity: Gas prices" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "_s = setup()\n", "configs = {}\n", "values = [0.7, 1, 1.3]\n", "for value in values:\n", " _c = Config()\n", " _c.gas_price_multiplier = value\n", " configs[value] = _c" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "sens3 = SensitivityAnalysis(_s, routine, configs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "output = sens3.single_kpi_overview('npv', case_names=['Heatpump only', 'Optimisation'])\n", "output.iplot(\n", " mode='lines+markers',\n", " symbol='circle-dot',\n", " size=10,\n", " xTitle='Gas price factor',\n", " yTitle='NPV in €',\n", " yrange=[0, output.max().max()*1.1],\n", " title='Sensitivity: Gas prices',\n", " colors=[recoygreen, recoyyellow],\n", " dimensions=(600, 400)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sensitivity: Electricity prices" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "_s = setup()\n", "configs = {}\n", "values = [0.7, 1, 1.3]\n", "for value in values:\n", " _c = Config()\n", " _c.e_price_multiplier = value\n", " configs[value] = _c" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "sens5 = SensitivityAnalysis(_s, routine, configs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "output = sens5.single_kpi_overview('npv', case_names=['Heatpump only', 'Optimisation'])\n", "output.iplot(\n", " mode='lines+markers',\n", " symbol='circle-dot',\n", " size=10,\n", " xTitle='Electricity price factor',\n", " yTitle='NPV in €',\n", " yrange=[0, output.max().max()*1.1],\n", " title='Sensitivity: Electricity prices',\n", " colors=[recoygreen, recoyyellow],\n", " dimensions=(600, 400)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sensitivity: Electricity price volatility" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "_s = setup()\n", "configs = {}\n", "values = [0.7, 1, 1.3]\n", "for value in values:\n", " _c = Config()\n", " _c.e_price_volatility_multiplier = value\n", " configs[value] = _c" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "sens6 = SensitivityAnalysis(_s, routine, configs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "output = sens6.single_kpi_overview('npv', case_names=['Heatpump only', 'Optimisation'])\n", "output.iplot(\n", " mode='lines+markers',\n", " symbol='circle-dot',\n", " size=10,\n", " xTitle='Volatility factor',\n", " yTitle='NPV in €',\n", " yrange=[0, output.max().max()*1.1],\n", " title='Sensitivity: E-price volatility',\n", " colors=[recoygreen, recoyyellow],\n", " dimensions=(600, 400)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sensitivity: Energy tax" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "_s = setup()\n", "configs = {}\n", "values = [0.7, 1, 1.3]\n", "for value in values:\n", " _c = Config()\n", " _c.energy_tax_multiplier = value\n", " configs[value] = _c" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "sens8 = SensitivityAnalysis(_s, routine, configs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "output = sens8.single_kpi_overview('npv', case_names=['Heatpump only', 'Optimisation'])\n", "output.iplot(\n", " mode='lines+markers',\n", " symbol='circle-dot',\n", " size=10,\n", " xTitle='Factor',\n", " yTitle='NPV in €',\n", " yrange=[0, output.max().max()*1.1],\n", " title='Sensitivity: Energy taxes',\n", " colors=[recoygreen, recoyyellow],\n", " dimensions=(600, 400)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sensitivity: Tsource" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "_s = setup()\n", "configs = {}\n", "values = [-10, 0, 10]\n", "for value in values:\n", " _c = Config()\n", " _c.tsource_delta = value\n", " configs[value] = _c" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "sens7 = SensitivityAnalysis(_s, routine, configs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "output = sens7.single_kpi_overview('npv', case_names=['Heatpump only', 'Optimisation'])\n", "output.iplot(\n", " mode='lines+markers',\n", " symbol='circle-dot',\n", " size=10,\n", " xTitle='Tsource delta',\n", " yTitle='NPV in €',\n", " yrange=[0, output.max().max()*1.1],\n", " title='Sensitivity: Tsource',\n", " colors=[recoygreen, recoyyellow],\n", " dimensions=(600, 400)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sensitivity: Time period" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def routine2(c, s):\n", " s = setup_model(c=c)\n", " s = load_data(c=c, s=s)\n", " s = create_and_assign_assets(c=c, s=s)\n", " s = run_optimisation(c=c, s=s)\n", " s = collect_cashflows(c=c, s=s)\n", " s = calculate_financials(c=c, s=s)\n", " return s" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "configs = {}\n", "start_values = ['2018-01-01', '2019-01-01', '2019-11-01']\n", "\n", "for value in start_values:\n", " _c = Config()\n", " _c.start = value\n", " _c.end = (pd.to_datetime(value) + timedelta(days=364)).strftime('%Y-%m-%d')\n", " configs[value] = _c" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "sens2 = SensitivityAnalysis(_s, routine2, configs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "result2 = sens2.single_kpi_overview('npv', case_names=['Heatpump only', 'Optimisation'])\n", "result2.iplot(\n", " mode='lines+markers',\n", " symbol='circle-dot',\n", " size=10,\n", " xTitle='Start date',\n", " yTitle='NPV in €',\n", " yrange=[0, result2.max().max()*1.1],\n", " title='Sensitivity: Modelled time period',\n", " colors=[recoygreen, recoyyellow],\n", " dimensions=(600, 400)\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3.7.6 64-bit ('py38': conda)", "language": "python", "name": "python37664bitpy38condad5f9d6fa326845b3840837eaa94b771b" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" }, "toc-autonumbering": true, "toc-showmarkdowntxt": false, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "02721ae635a34afe94d7735f7cf72c56": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "24cab81d4f1e493f86a78d3287d8e049": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_57209fe141214d8ba670b292c49ae966", "IPY_MODEL_e8600ad8df9e4fdfb3b0307b05f12a9e" ], "layout": "IPY_MODEL_02721ae635a34afe94d7735f7cf72c56" } }, "3fe1649dd3c946409b2e3d4c7c7b6447": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "54ab12a25f774ddb871e923a825f2fb8": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": { "description_width": "initial" } }, "57209fe141214d8ba670b292c49ae966": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "FloatProgressModel", "state": { "description": " 8%", "layout": "IPY_MODEL_7b5fa1be63f341e4ada3303f3d1e687c", "max": 525600, "style": "IPY_MODEL_54ab12a25f774ddb871e923a825f2fb8", "value": 44504 } }, "7b5fa1be63f341e4ada3303f3d1e687c": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "94f430f7ac2a43d2ba688b156744f3aa": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "e8600ad8df9e4fdfb3b0307b05f12a9e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "layout": "IPY_MODEL_3fe1649dd3c946409b2e3d4c7c7b6447", "style": "IPY_MODEL_94f430f7ac2a43d2ba688b156744f3aa", "value": " 44504/525600 [00:38<11:48, 678.91it/s]" } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }