From 52de4c2378088cc1411f35948a75c374c10bd78d Mon Sep 17 00:00:00 2001 From: CarlosEpia Date: Mon, 7 Aug 2023 15:33:03 +0200 Subject: [PATCH 01/24] add plot_carrier to the etrago methods --- etrago/tools/network.py | 3 +++ etrago/tools/plot.py | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/etrago/tools/network.py b/etrago/tools/network.py index 88a1696e..a3938c3e 100644 --- a/etrago/tools/network.py +++ b/etrago/tools/network.py @@ -65,6 +65,7 @@ heat_stores, hydrogen_stores, plot_clusters, + plot_carrier, plot_gas_generation, plot_gas_summary, plot_grid, @@ -291,6 +292,8 @@ def __init__( plot_grid = plot_grid plot_clusters = plot_clusters + + plot_carrier = plot_carrier plot_gas_generation = plot_gas_generation diff --git a/etrago/tools/plot.py b/etrago/tools/plot.py index 0bacc770..6fc92185 100644 --- a/etrago/tools/plot.py +++ b/etrago/tools/plot.py @@ -2227,7 +2227,7 @@ def flexibility_usage( fig_e.savefig(pre_path + f"stored_e_{flexibility}") -def plot_carrier(network, carrier_links=["AC"], carrier_buses=["AC"]): +def plot_carrier(etrago, carrier_links=["AC"], carrier_buses=["AC"]): """ Parameters ---------- @@ -2245,7 +2245,7 @@ def plot_carrier(network, carrier_links=["AC"], carrier_buses=["AC"]): None. """ - + network = etrago.network colors = coloring() line_colors = "lightblue" From 3f39fc4e79aecdfad43e90e55a62ee5f8cdb1d78 Mon Sep 17 00:00:00 2001 From: CarlosEpia Date: Thu, 28 Sep 2023 16:13:33 +0200 Subject: [PATCH 02/24] include etrago tutorial release0.9.0 --- doc/eTraGo_tutorial_release0.9.0.ipynb | 469 +++++++++++++++++++++++++ 1 file changed, 469 insertions(+) create mode 100644 doc/eTraGo_tutorial_release0.9.0.ipynb diff --git a/doc/eTraGo_tutorial_release0.9.0.ipynb b/doc/eTraGo_tutorial_release0.9.0.ipynb new file mode 100644 index 00000000..bde00d78 --- /dev/null +++ b/doc/eTraGo_tutorial_release0.9.0.ipynb @@ -0,0 +1,469 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"HSF\"\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "#
Abschlussworkshop eGon 2023
\n", + "\n", + "##
Session eTraGo: electric Transmission Grid optimization
\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# Agenda \n", + "\n", + "\n", + "* [Important links](#links)\n", + "* [Installation](#install)\n", + "* [General procedure](#general)\n", + "* [Use case: eGon2035 scenario optimization](#useCase)\n", + "* [Outputs](#outputs)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Important links \n", + "\n", + "* __[eTraGo Source Code](https://github.com/openego/eTraGo)__\n", + "* __[eTraGo Documentation](http://etrago.readthedocs.io/)__\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Installation \n", + "The current eTraGo version and the python package jupyter are required to use this notebook. Install these with\n", + "\n", + "`pip install eTraGo`\n", + "\n", + "`pip install jupyterlab`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# General procedure\n", + "\n", + "1. Choose parameter settings (args) in appl.py.\n", + "2. Run appl.py or etrago(args).\n", + "3. Evaluate results.\n", + "\n", + "\n", + "# Use case: eGon2035 scenario optimization\n", + "\n", + "\n", + "## Minimal example\n", + "\n", + "1. Where and how much AC/DC network transmission capacity is required?\n", + "2. Optimal distribution of different storage technologies\n", + "3. System costs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%capture\n", + "# enable jupyter interactive plotting\n", + "%matplotlib notebook\n", + "from ipywidgets import *\n", + "%matplotlib inline\n", + "\n", + "#import plotting function\n", + "from etrago.tools.plot import plot_carrier" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "### Import required general and eTraGo specific python packages" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%capture\n", + "import datetime\n", + "import os\n", + "import os.path\n", + "\n", + "import numpy as np\n", + "\n", + "__copyright__ = (\n", + " \"Flensburg University of Applied Sciences, \"\n", + " \"Europa-Universität Flensburg, Centre for Sustainable Energy Systems, \"\n", + " \"DLR-Institute for Networked Energy Systems\"\n", + ")\n", + "__license__ = \"GNU Affero General Public License Version 3 (AGPL-3.0)\"\n", + "__author__ = (\n", + " \"ulfmueller, lukasol, wolfbunke, mariusves, s3pp, ClaraBuettner, \"\n", + " \"CarlosEpia, KathiEsterl, fwitte, gnn, pieterhexen, AmeliaNadal\"\n", + ")\n", + "\n", + "if \"READTHEDOCS\" not in os.environ:\n", + " # Sphinx does not run this code.\n", + " # Do not import internal packages directly\n", + "\n", + " from etrago import Etrago\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define parameters to run eTraGo" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "args = {\n", + " # Setup and Configuration:\n", + " \"db\": \"egon-data\", # database session\n", + " \"gridversion\": None, # None for model_draft or Version number\n", + " \"method\": { # Choose method and settings for optimization\n", + " \"type\": \"lopf\", # type of optimization, currently only 'lopf'\n", + " \"n_iter\": 1, # abort criterion of iterative optimization, 'n_iter' or 'threshold'\n", + " \"pyomo\": True, # set if pyomo is used for model building\n", + " },\n", + " \"pf_post_lopf\": {\n", + " \"active\": True, # choose if perform a pf after lopf\n", + " \"add_foreign_lopf\": True, # keep results of lopf for foreign DC-links\n", + " \"q_allocation\": \"p_nom\", # allocate reactive power via 'p_nom' or 'p'\n", + " },\n", + " \"start_snapshot\": 1,\n", + " \"end_snapshot\": 15,\n", + " \"solver\": \"gurobi\", # glpk, cplex or gurobi\n", + " \"solver_options\": {\n", + " \"BarConvTol\": 1.0e-5,\n", + " \"FeasibilityTol\": 1.0e-5,\n", + " \"method\": 2,\n", + " \"crossover\": 0,\n", + " \"logFile\": \"solver_etrago.log\",\n", + " \"threads\": 7,\n", + " },\n", + " \"model_formulation\": \"kirchhoff\", # angles or kirchhoff\n", + " \"scn_name\": \"eGon2035\", # scenario: eGon2035 or eGon100RE\n", + " # Scenario variations:\n", + " \"scn_extension\": None, # None or array of extension scenarios\n", + " \"scn_decommissioning\": None, # None or decommissioning scenario\n", + " # Export options:\n", + " \"lpfile\": False, # save pyomo's lp file: False or /path/to/lpfile.lp\n", + " \"csv_export\": \"results\", # save results as csv: False or /path/tofolder\n", + " # Settings:\n", + " \"extendable\": {\n", + " \"extendable_components\": [\n", + " \"as_in_db\"\n", + " ], # Array of components to optimize\n", + " \"upper_bounds_grid\": { # Set upper bounds for grid expansion\n", + " # lines in Germany\n", + " \"grid_max_D\": None, # relative to existing capacity\n", + " \"grid_max_abs_D\": { # absolute capacity per voltage level\n", + " \"380\": {\"i\": 1020, \"wires\": 4, \"circuits\": 4},\n", + " \"220\": {\"i\": 1020, \"wires\": 4, \"circuits\": 4},\n", + " \"110\": {\"i\": 1020, \"wires\": 4, \"circuits\": 2},\n", + " \"dc\": 0,\n", + " },\n", + " # border crossing lines\n", + " \"grid_max_foreign\": 4, # relative to existing capacity\n", + " \"grid_max_abs_foreign\": None, # absolute capacity per voltage level\n", + " },\n", + " },\n", + " \"generator_noise\": 789456, # apply generator noise, False or seed number\n", + " \"extra_functionality\": {}, # Choose function name or {}\n", + " # Spatial Complexity:\n", + " \"network_clustering_ehv\": False, # clustering of HV buses to EHV buses\n", + " \"network_clustering\": {\n", + " \"active\": True, # choose if clustering is activated\n", + " \"method\": \"kmedoids-dijkstra\", # choose clustering method: kmeans or kmedoids-dijkstra\n", + " \"n_clusters_AC\": 60, # total number of resulting AC nodes (DE+foreign)\n", + " \"cluster_foreign_AC\": False, # take foreign AC buses into account, True or False\n", + " \"method_gas\": \"kmedoids-dijkstra\", # choose clustering method: kmeans or kmedoids-dijkstra\n", + " \"n_clusters_gas\": 17, # total number of resulting CH4 nodes (DE+foreign)\n", + " \"cluster_foreign_gas\": False, # take foreign CH4 buses into account, True or False\n", + " \"k_elec_busmap\": False, # False or path/to/busmap.csv\n", + " \"k_gas_busmap\": False, # False or path/to/ch4_busmap.csv\n", + " \"bus_weight_tocsv\": None, # None or path/to/bus_weight.csv\n", + " \"bus_weight_fromcsv\": None, # None or path/to/bus_weight.csv\n", + " \"gas_weight_tocsv\": None, # None or path/to/gas_bus_weight.csv\n", + " \"gas_weight_fromcsv\": None, # None or path/to/gas_bus_weight.csv\n", + " \"line_length_factor\": 1, # Factor to multiply distance between new buses for new line lengths\n", + " \"remove_stubs\": False, # remove stubs bevore kmeans clustering\n", + " \"use_reduced_coordinates\": False, # If True, do not average cluster coordinates\n", + " \"random_state\": 42, # random state for replicability of clustering results\n", + " \"n_init\": 10, # affects clustering algorithm, only change when neccesary\n", + " \"max_iter\": 100, # affects clustering algorithm, only change when neccesary\n", + " \"tol\": 1e-6, # affects clustering algorithm, only change when neccesary\n", + " \"CPU_cores\": 7, # number of cores used during clustering, \"max\" for all cores available.\n", + " },\n", + " \"sector_coupled_clustering\": {\n", + " \"active\": True, # choose if clustering is activated\n", + " \"carrier_data\": { # select carriers affected by sector coupling\n", + " \"central_heat\": {\n", + " \"base\": [\"CH4\", \"AC\"],\n", + " \"strategy\": \"simultaneous\", # select strategy to cluster other sectors\n", + " },\n", + " },\n", + " },\n", + " \"disaggregation\": None, # None, 'mini' or 'uniform'\n", + " # Temporal Complexity:\n", + " \"snapshot_clustering\": {\n", + " \"active\": False, # choose if clustering is activated\n", + " \"method\": \"segmentation\", # 'typical_periods' or 'segmentation'\n", + " \"extreme_periods\": None, # consideration of extreme timesteps; e.g. 'append'\n", + " \"how\": \"daily\", # type of period - only relevant for 'typical_periods'\n", + " \"storage_constraints\": \"soc_constraints\", # additional constraints for storages - only relevant for 'typical_periods'\n", + " \"n_clusters\": 5, # number of periods - only relevant for 'typical_periods'\n", + " \"n_segments\": 5, # number of segments - only relevant for segmentation\n", + " },\n", + " \"skip_snapshots\": 5, # False or number of snapshots to skip\n", + " \"temporal_disaggregation\": {\n", + " \"active\": False, # choose if temporally full complex dispatch optimization should be conducted\n", + " \"no_slices\": 8, # number of subproblems optimization is divided into\n", + " },\n", + " # Simplifications:\n", + " \"branch_capacity_factor\": {\"HV\": 0.5, \"eHV\": 0.7}, # p.u. branch derating\n", + " \"load_shedding\": True, # meet the demand at value of loss load cost\n", + " \"foreign_lines\": {\n", + " \"carrier\": \"AC\", # 'DC' for modeling foreign lines as links\n", + " \"capacity\": \"osmTGmod\", # 'osmTGmod', 'tyndp2020', 'ntc_acer' or 'thermal_acer'\n", + " },\n", + " \"comments\": None,\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import the network" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "#etrago = Etrago(args, json_path=None)\n", + "#etrago.build_network_from_db()\n", + "\n", + "etrago.network.buses.carrier.value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "plot_carrier(etrago.network, carrier_links=[\"AC\", \"DC\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "plot_carrier(etrago.network, carrier_links=[\"CH4\"], carrier_buses=[\"CH4\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "### Cluster electrical network and attached technologies" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%capture\n", + "#etrago.adjust_network()\n", + "#etrago.spatial_clustering()\n", + "#etrago.spatial_clustering_gas()\n", + "etrago2 = Etrago(csv_folder_name = \"/home/carlos/Documents/Ego-n/etrago_presentation/before_lopf_60\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "plot_carrier(etrago2.network, carrier_links=[\"AC\", \"DC\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Cluster gas network and attached technologies" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "plot_carrier(etrago2.network, carrier_links=[\"CH4\"], carrier_buses=[\"CH4\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Reduce temporal complexity" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "etrago2.network.snapshots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "etrago2.skip_snapshots()\n", + "etrago2.network.snapshots" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Run linear optimal power flow" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago2.lopf()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "etrago2.plot_grid(line_colors= \"expansion_abs\", bus_colors= \"storage_expansion\", bus_sizes= 0.000001)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "etrago2.calc_results()\n", + "etrago2.results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "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.10.11" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 734d970488fc38fb405a375aa637275b4ba6cc8c Mon Sep 17 00:00:00 2001 From: CarlosEpia Date: Fri, 29 Sep 2023 10:25:08 +0200 Subject: [PATCH 03/24] using black and isort --- etrago/tools/network.py | 4 ++-- etrago/tools/plot.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/etrago/tools/network.py b/etrago/tools/network.py index a3938c3e..b623c7c0 100644 --- a/etrago/tools/network.py +++ b/etrago/tools/network.py @@ -64,8 +64,8 @@ flexibility_usage, heat_stores, hydrogen_stores, - plot_clusters, plot_carrier, + plot_clusters, plot_gas_generation, plot_gas_summary, plot_grid, @@ -292,7 +292,7 @@ def __init__( plot_grid = plot_grid plot_clusters = plot_clusters - + plot_carrier = plot_carrier plot_gas_generation = plot_gas_generation diff --git a/etrago/tools/plot.py b/etrago/tools/plot.py index 6fc92185..23cb7274 100644 --- a/etrago/tools/plot.py +++ b/etrago/tools/plot.py @@ -25,7 +25,6 @@ import logging import os -from etrago.tools.execute import import_gen_from_links from matplotlib import pyplot as plt from matplotlib.legend_handler import HandlerPatch from matplotlib.patches import Circle, Ellipse @@ -35,6 +34,8 @@ import numpy as np import pandas as pd +from etrago.tools.execute import import_gen_from_links + cartopy_present = True try: import cartopy.crs as ccrs From a73f8656dfa52ffeee0d77eade6c17dad2df11a2 Mon Sep 17 00:00:00 2001 From: CarlosEpia Date: Thu, 5 Oct 2023 16:37:27 +0200 Subject: [PATCH 04/24] include link to init for db --- doc/eTraGo_tutorial_release0.9.0.ipynb | 469 ------------ doc/eTraGo_tutorial_release0.9.ipynb | 961 +++++++++++++++++++++++++ 2 files changed, 961 insertions(+), 469 deletions(-) delete mode 100644 doc/eTraGo_tutorial_release0.9.0.ipynb create mode 100644 doc/eTraGo_tutorial_release0.9.ipynb diff --git a/doc/eTraGo_tutorial_release0.9.0.ipynb b/doc/eTraGo_tutorial_release0.9.0.ipynb deleted file mode 100644 index bde00d78..00000000 --- a/doc/eTraGo_tutorial_release0.9.0.ipynb +++ /dev/null @@ -1,469 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\"HSF\"\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "#
Abschlussworkshop eGon 2023
\n", - "\n", - "##
Session eTraGo: electric Transmission Grid optimization
\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "# Agenda \n", - "\n", - "\n", - "* [Important links](#links)\n", - "* [Installation](#install)\n", - "* [General procedure](#general)\n", - "* [Use case: eGon2035 scenario optimization](#useCase)\n", - "* [Outputs](#outputs)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Important links \n", - "\n", - "* __[eTraGo Source Code](https://github.com/openego/eTraGo)__\n", - "* __[eTraGo Documentation](http://etrago.readthedocs.io/)__\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Installation \n", - "The current eTraGo version and the python package jupyter are required to use this notebook. Install these with\n", - "\n", - "`pip install eTraGo`\n", - "\n", - "`pip install jupyterlab`" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# General procedure\n", - "\n", - "1. Choose parameter settings (args) in appl.py.\n", - "2. Run appl.py or etrago(args).\n", - "3. Evaluate results.\n", - "\n", - "\n", - "# Use case: eGon2035 scenario optimization\n", - "\n", - "\n", - "## Minimal example\n", - "\n", - "1. Where and how much AC/DC network transmission capacity is required?\n", - "2. Optimal distribution of different storage technologies\n", - "3. System costs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "%%capture\n", - "# enable jupyter interactive plotting\n", - "%matplotlib notebook\n", - "from ipywidgets import *\n", - "%matplotlib inline\n", - "\n", - "#import plotting function\n", - "from etrago.tools.plot import plot_carrier" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "### Import required general and eTraGo specific python packages" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "%%capture\n", - "import datetime\n", - "import os\n", - "import os.path\n", - "\n", - "import numpy as np\n", - "\n", - "__copyright__ = (\n", - " \"Flensburg University of Applied Sciences, \"\n", - " \"Europa-Universität Flensburg, Centre for Sustainable Energy Systems, \"\n", - " \"DLR-Institute for Networked Energy Systems\"\n", - ")\n", - "__license__ = \"GNU Affero General Public License Version 3 (AGPL-3.0)\"\n", - "__author__ = (\n", - " \"ulfmueller, lukasol, wolfbunke, mariusves, s3pp, ClaraBuettner, \"\n", - " \"CarlosEpia, KathiEsterl, fwitte, gnn, pieterhexen, AmeliaNadal\"\n", - ")\n", - "\n", - "if \"READTHEDOCS\" not in os.environ:\n", - " # Sphinx does not run this code.\n", - " # Do not import internal packages directly\n", - "\n", - " from etrago import Etrago\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Define parameters to run eTraGo" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "args = {\n", - " # Setup and Configuration:\n", - " \"db\": \"egon-data\", # database session\n", - " \"gridversion\": None, # None for model_draft or Version number\n", - " \"method\": { # Choose method and settings for optimization\n", - " \"type\": \"lopf\", # type of optimization, currently only 'lopf'\n", - " \"n_iter\": 1, # abort criterion of iterative optimization, 'n_iter' or 'threshold'\n", - " \"pyomo\": True, # set if pyomo is used for model building\n", - " },\n", - " \"pf_post_lopf\": {\n", - " \"active\": True, # choose if perform a pf after lopf\n", - " \"add_foreign_lopf\": True, # keep results of lopf for foreign DC-links\n", - " \"q_allocation\": \"p_nom\", # allocate reactive power via 'p_nom' or 'p'\n", - " },\n", - " \"start_snapshot\": 1,\n", - " \"end_snapshot\": 15,\n", - " \"solver\": \"gurobi\", # glpk, cplex or gurobi\n", - " \"solver_options\": {\n", - " \"BarConvTol\": 1.0e-5,\n", - " \"FeasibilityTol\": 1.0e-5,\n", - " \"method\": 2,\n", - " \"crossover\": 0,\n", - " \"logFile\": \"solver_etrago.log\",\n", - " \"threads\": 7,\n", - " },\n", - " \"model_formulation\": \"kirchhoff\", # angles or kirchhoff\n", - " \"scn_name\": \"eGon2035\", # scenario: eGon2035 or eGon100RE\n", - " # Scenario variations:\n", - " \"scn_extension\": None, # None or array of extension scenarios\n", - " \"scn_decommissioning\": None, # None or decommissioning scenario\n", - " # Export options:\n", - " \"lpfile\": False, # save pyomo's lp file: False or /path/to/lpfile.lp\n", - " \"csv_export\": \"results\", # save results as csv: False or /path/tofolder\n", - " # Settings:\n", - " \"extendable\": {\n", - " \"extendable_components\": [\n", - " \"as_in_db\"\n", - " ], # Array of components to optimize\n", - " \"upper_bounds_grid\": { # Set upper bounds for grid expansion\n", - " # lines in Germany\n", - " \"grid_max_D\": None, # relative to existing capacity\n", - " \"grid_max_abs_D\": { # absolute capacity per voltage level\n", - " \"380\": {\"i\": 1020, \"wires\": 4, \"circuits\": 4},\n", - " \"220\": {\"i\": 1020, \"wires\": 4, \"circuits\": 4},\n", - " \"110\": {\"i\": 1020, \"wires\": 4, \"circuits\": 2},\n", - " \"dc\": 0,\n", - " },\n", - " # border crossing lines\n", - " \"grid_max_foreign\": 4, # relative to existing capacity\n", - " \"grid_max_abs_foreign\": None, # absolute capacity per voltage level\n", - " },\n", - " },\n", - " \"generator_noise\": 789456, # apply generator noise, False or seed number\n", - " \"extra_functionality\": {}, # Choose function name or {}\n", - " # Spatial Complexity:\n", - " \"network_clustering_ehv\": False, # clustering of HV buses to EHV buses\n", - " \"network_clustering\": {\n", - " \"active\": True, # choose if clustering is activated\n", - " \"method\": \"kmedoids-dijkstra\", # choose clustering method: kmeans or kmedoids-dijkstra\n", - " \"n_clusters_AC\": 60, # total number of resulting AC nodes (DE+foreign)\n", - " \"cluster_foreign_AC\": False, # take foreign AC buses into account, True or False\n", - " \"method_gas\": \"kmedoids-dijkstra\", # choose clustering method: kmeans or kmedoids-dijkstra\n", - " \"n_clusters_gas\": 17, # total number of resulting CH4 nodes (DE+foreign)\n", - " \"cluster_foreign_gas\": False, # take foreign CH4 buses into account, True or False\n", - " \"k_elec_busmap\": False, # False or path/to/busmap.csv\n", - " \"k_gas_busmap\": False, # False or path/to/ch4_busmap.csv\n", - " \"bus_weight_tocsv\": None, # None or path/to/bus_weight.csv\n", - " \"bus_weight_fromcsv\": None, # None or path/to/bus_weight.csv\n", - " \"gas_weight_tocsv\": None, # None or path/to/gas_bus_weight.csv\n", - " \"gas_weight_fromcsv\": None, # None or path/to/gas_bus_weight.csv\n", - " \"line_length_factor\": 1, # Factor to multiply distance between new buses for new line lengths\n", - " \"remove_stubs\": False, # remove stubs bevore kmeans clustering\n", - " \"use_reduced_coordinates\": False, # If True, do not average cluster coordinates\n", - " \"random_state\": 42, # random state for replicability of clustering results\n", - " \"n_init\": 10, # affects clustering algorithm, only change when neccesary\n", - " \"max_iter\": 100, # affects clustering algorithm, only change when neccesary\n", - " \"tol\": 1e-6, # affects clustering algorithm, only change when neccesary\n", - " \"CPU_cores\": 7, # number of cores used during clustering, \"max\" for all cores available.\n", - " },\n", - " \"sector_coupled_clustering\": {\n", - " \"active\": True, # choose if clustering is activated\n", - " \"carrier_data\": { # select carriers affected by sector coupling\n", - " \"central_heat\": {\n", - " \"base\": [\"CH4\", \"AC\"],\n", - " \"strategy\": \"simultaneous\", # select strategy to cluster other sectors\n", - " },\n", - " },\n", - " },\n", - " \"disaggregation\": None, # None, 'mini' or 'uniform'\n", - " # Temporal Complexity:\n", - " \"snapshot_clustering\": {\n", - " \"active\": False, # choose if clustering is activated\n", - " \"method\": \"segmentation\", # 'typical_periods' or 'segmentation'\n", - " \"extreme_periods\": None, # consideration of extreme timesteps; e.g. 'append'\n", - " \"how\": \"daily\", # type of period - only relevant for 'typical_periods'\n", - " \"storage_constraints\": \"soc_constraints\", # additional constraints for storages - only relevant for 'typical_periods'\n", - " \"n_clusters\": 5, # number of periods - only relevant for 'typical_periods'\n", - " \"n_segments\": 5, # number of segments - only relevant for segmentation\n", - " },\n", - " \"skip_snapshots\": 5, # False or number of snapshots to skip\n", - " \"temporal_disaggregation\": {\n", - " \"active\": False, # choose if temporally full complex dispatch optimization should be conducted\n", - " \"no_slices\": 8, # number of subproblems optimization is divided into\n", - " },\n", - " # Simplifications:\n", - " \"branch_capacity_factor\": {\"HV\": 0.5, \"eHV\": 0.7}, # p.u. branch derating\n", - " \"load_shedding\": True, # meet the demand at value of loss load cost\n", - " \"foreign_lines\": {\n", - " \"carrier\": \"AC\", # 'DC' for modeling foreign lines as links\n", - " \"capacity\": \"osmTGmod\", # 'osmTGmod', 'tyndp2020', 'ntc_acer' or 'thermal_acer'\n", - " },\n", - " \"comments\": None,\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Import the network" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "#etrago = Etrago(args, json_path=None)\n", - "#etrago.build_network_from_db()\n", - "\n", - "etrago.network.buses.carrier.value_counts()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "plot_carrier(etrago.network, carrier_links=[\"AC\", \"DC\"])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "plot_carrier(etrago.network, carrier_links=[\"CH4\"], carrier_buses=[\"CH4\"])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "### Cluster electrical network and attached technologies" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "%%capture\n", - "#etrago.adjust_network()\n", - "#etrago.spatial_clustering()\n", - "#etrago.spatial_clustering_gas()\n", - "etrago2 = Etrago(csv_folder_name = \"/home/carlos/Documents/Ego-n/etrago_presentation/before_lopf_60\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "plot_carrier(etrago2.network, carrier_links=[\"AC\", \"DC\"])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Cluster gas network and attached technologies" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "plot_carrier(etrago2.network, carrier_links=[\"CH4\"], carrier_buses=[\"CH4\"])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Reduce temporal complexity" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "etrago2.network.snapshots" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "etrago2.skip_snapshots()\n", - "etrago2.network.snapshots" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Run linear optimal power flow" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "etrago2.lopf()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "etrago2.plot_grid(line_colors= \"expansion_abs\", bus_colors= \"storage_expansion\", bus_sizes= 0.000001)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "etrago2.calc_results()\n", - "etrago2.results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/doc/eTraGo_tutorial_release0.9.ipynb b/doc/eTraGo_tutorial_release0.9.ipynb new file mode 100644 index 00000000..e7cdc9e6 --- /dev/null +++ b/doc/eTraGo_tutorial_release0.9.ipynb @@ -0,0 +1,961 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "__copyright__ = (\n", + " \"Flensburg University of Applied Sciences, \"\n", + " \"Europa-Universität Flensburg, Centre for Sustainable Energy Systems, \"\n", + " \"DLR-Institute for Networked Energy Systems\"\n", + ")\n", + "__license__ = \"GNU Affero General Public License Version 3 (AGPL-3.0)\"\n", + "__author__ = (\n", + " \"ulfmueller, lukasol, wolfbunke, mariusves, s3pp, ClaraBuettner, \"\n", + " \"CarlosEpia, KathiEsterl, fwitte, gnn, pieterhexen, AmeliaNadal\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"HSF\"\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Introduction to eTraGo" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Important links\n", + "\n", + "* __[eTraGo Source Code](https://github.com/openego/eTraGo)__\n", + "* __[eTraGo Documentation](http://etrago.readthedocs.io/)__\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Installation\n", + "The current eTraGo version as well as the python packages jupyterlab and contextily are required to use this notebook. Install these with\n", + "\n", + "`pip install eTraGo`\n", + "\n", + "`pip install jupyterlab contextily`" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Import required general and eTraGo specific python packages" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%capture\n", + "# enable jupyter interactive plotting\n", + "%matplotlib widget\n", + "\n", + "# import Etrago API class\n", + "from etrago import Etrago\n", + "\n", + "# import plotting function\n", + "from etrago.tools.plot import plot_carrier\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define parameters to run eTraGo" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "args = {\n", + " # Setup:\n", + " \"db\": \"egon-data\", # database session\n", + " \"scn_name\": \"eGon2035\", # scenario: eGon2035, eGon100RE, eGon2035_lowflex, eGon100RE_lowflex\n", + " \"start_snapshot\": 1,\n", + " \"end_snapshot\": 15,\n", + " \"gridversion\": None, # Currently not needed\n", + " \"branch_capacity_factor\": {\"HV\": 0.5, \"eHV\": 0.7}, # p.u. branch rating\n", + " \"foreign_lines\": {\n", + " \"carrier\": \"AC\", # 'DC' for modeling foreign lines as links\n", + " \"capacity\": \"osmTGmod\", # 'osmTGmod', 'tyndp2020', 'ntc_acer' or 'thermal_acer'\n", + " },\n", + " \"scn_extension\": None, # None or array of extension scenarios (currently not provided, but needed once new lines from NEP are set up)\n", + " \"scn_decommissioning\": None, # None or decommissioning scenario (currently not provided)\n", + " \n", + " # Optimisation and powerflow:\n", + " \"method\": { # Choose method and settings for optimization\n", + " \"type\": \"lopf\", # type of optimization, currently only 'lopf'\n", + " \"n_iter\": 1, # abort criterion of iterative optimization, 'n_iter' or 'threshold'\n", + " \"pyomo\": True, # set if pyomo is used for model building\n", + " },\n", + " \"solver\": \"gurobi\", # glpk, cplex or gurobi\n", + " \"solver_options\": {\n", + " \"BarConvTol\": 1.0e-5,\n", + " \"FeasibilityTol\": 1.0e-5,\n", + " \"method\": 2,\n", + " \"crossover\": 0,\n", + " \"logFile\": \"solver_etrago.log\",\n", + " \"threads\": 4,\n", + " },\n", + " \"model_formulation\": \"kirchhoff\", # formulation of the LPF problem (all are equivalent)\n", + " \"extendable\": {\n", + " \"extendable_components\": [\n", + " \"as_in_db\"\n", + " ], # Array of components to optimize\n", + " \"upper_bounds_grid\": { # Set upper bounds for grid expansion\n", + " # lines in Germany\n", + " \"grid_max_D\": None, # relative to existing capacity\n", + " \"grid_max_abs_D\": { # absolute capacity per voltage level\n", + " \"380\": {\"i\": 1020, \"wires\": 4, \"circuits\": 4},\n", + " \"220\": {\"i\": 1020, \"wires\": 4, \"circuits\": 4},\n", + " \"110\": {\"i\": 1020, \"wires\": 4, \"circuits\": 2},\n", + " \"dc\": 0,\n", + " },\n", + " # border crossing lines\n", + " \"grid_max_foreign\": 4, # relative to existing capacity\n", + " \"grid_max_abs_foreign\": None, # absolute capacity per voltage level\n", + " },\n", + " },\n", + " \"generator_noise\": 789456, # a small random noise to the marginal costs of each generator in order to prevent an optima plateau\n", + " \"extra_functionality\": {}, # Choose function name (e.g. \"min_renewable_share\" or \"cross_border_flow\") or {} \n", + " \"load_shedding\": False, # helpful when debugging - a very expensive generator is added to each bus \n", + " \"lpfile\": False, # save pyomo's lp file: False or /path/to/lpfile.lp\n", + " \"csv_export\": \"results\", # save results as csv: False or /path/tofolder\n", + " \"pf_post_lopf\": {\n", + " \"active\": True, # choose if a pf should be performed after the lopf\n", + " \"add_foreign_lopf\": True, # keep results of lopf for foreign DC-links\n", + " \"q_allocation\": \"p_nom\", # allocate reactive power via 'p_nom' or 'p'\n", + " },\n", + " \n", + " # Spatial complexity reduction and disaggregation:\n", + " \"network_clustering_ehv\": False, # clustering of HV buses to EHV buses\n", + " \"network_clustering\": {\n", + " \"active\": True, # choose if clustering is activated\n", + " \"method\": \"kmedoids-dijkstra\", # choose clustering method: kmeans or kmedoids-dijkstra\n", + " \"n_clusters_AC\": 60, # total number of resulting AC nodes (DE+foreign)\n", + " \"cluster_foreign_AC\": False, # take foreign AC buses into account, True or False\n", + " \"method_gas\": \"kmedoids-dijkstra\", # choose clustering method: kmeans or kmedoids-dijkstra\n", + " \"n_clusters_gas\": 17, # total number of resulting CH4 nodes (DE+foreign)\n", + " \"cluster_foreign_gas\": False, # take foreign CH4 buses into account, True or False\n", + " \"k_elec_busmap\": False, # False or path/to/busmap.csv\n", + " \"k_gas_busmap\": False, # False or path/to/ch4_busmap.csv\n", + " \"bus_weight_tocsv\": None, # None or path/to/bus_weight.csv\n", + " \"bus_weight_fromcsv\": None, # None or path/to/bus_weight.csv\n", + " \"gas_weight_tocsv\": None, # None or path/to/gas_bus_weight.csv\n", + " \"gas_weight_fromcsv\": None, # None or path/to/gas_bus_weight.csv\n", + " \"line_length_factor\": 1, # Factor to multiply distance between new buses for new line lengths\n", + " \"remove_stubs\": False, # remove stubs bevore kmeans clustering\n", + " \"use_reduced_coordinates\": False, # If True, do not average cluster coordinates\n", + " \"random_state\": 42, # random state for replicability of clustering results\n", + " \"n_init\": 10, # affects clustering algorithm, only change when neccesary\n", + " \"max_iter\": 100, # affects clustering algorithm, only change when neccesary\n", + " \"tol\": 1e-6, # affects clustering algorithm, only change when neccesary\n", + " \"CPU_cores\": 4, # number of cores used during clustering, \"max\" for all cores available.\n", + " },\n", + " \"sector_coupled_clustering\": {\n", + " \"active\": True, # choose if clustering is activated\n", + " \"carrier_data\": { # select carriers affected by sector coupling\n", + " \"central_heat\": {\n", + " \"base\": [\"CH4\", \"AC\"],\n", + " \"strategy\": \"simultaneous\", # select strategy to cluster other sectors\n", + " },\n", + " },\n", + " },\n", + " \"disaggregation\": None, # None or 'uniform'\n", + " \n", + " # Temporal complexity reduction and disaggregation:\n", + " \"snapshot_clustering\": {\n", + " \"active\": False, # choose if clustering is activated\n", + " \"method\": \"segmentation\", # 'typical_periods' or 'segmentation'\n", + " \"extreme_periods\": None, # consideration of extreme timesteps; e.g. 'append'\n", + " \"how\": \"daily\", # type of period - only relevant for 'typical_periods'\n", + " \"storage_constraints\": \"soc_constraints\", # additional constraints for storages - only relevant for 'typical_periods'\n", + " \"n_clusters\": 5, # number of periods - only relevant for 'typical_periods'\n", + " \"n_segments\": 5, # number of segments - only relevant for segmentation\n", + " },\n", + " \"skip_snapshots\": 5, # False or number of snapshots to skip\n", + " \"temporal_disaggregation\": {\n", + " \"active\": False, # choose if temporally full complex dispatch optimization should be conducted\n", + " \"no_slices\": 8, # number of subproblems optimization is divided into\n", + " },\n", + "\n", + " # Other\n", + " \"comments\": None,\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Import and export of the network and data structure\n", + "\n", + "The network can either be imported from a local database or from an online repository.\n", + "\n", + "Follow the instructions [here](https://github.com/openego/eTraGo/tree/features/release-0.9.0#input-data) to get the data-base." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "etrago = Etrago(args, json_path=None)\n", + "etrago.build_network_from_db()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After importing the network from the database, call `adjust_network` to adjust the network imported from the database according to given input-parameters, e.g. add load shedding, set generator noise, set foreign lines to links." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%capture\n", + "etrago.adjust_network()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Etrago uses pypsa's data structure:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# the pypsa network is stored in:\n", + "etrago.network" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.network.buses.head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.network.buses.carrier.value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "etrago.plot_carrier(carrier_links=[\"AC\", \"DC\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "etrago.plot_carrier(carrier_links=[\"CH4\"], carrier_buses=[\"CH4\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To export and import an Etrago network to csv files, you can do the following:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "path_export = \"etrago_network\"\n", + "\n", + "# export\n", + "etrago.export_to_csv(path_export)\n", + "\n", + "# import\n", + "path_import = \"etrago_network\"\n", + "etrago_import = Etrago(csv_folder_name=path_import)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Spatial clustering" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following arguments define the settings for the spatial clustering:\n", + "\n", + "```\n", + "args = { \n", + " # Spatial complexity reduction and disaggregation:\n", + " \"network_clustering_ehv\": False, # clustering of HV buses to EHV buses\n", + " \"network_clustering\": {\n", + " \"active\": True, # choose if clustering is activated\n", + " \"method\": \"kmedoids-dijkstra\", # choose clustering method: kmeans or kmedoids-dijkstra\n", + " \"n_clusters_AC\": 60, # total number of resulting AC nodes (DE+foreign)\n", + " \"cluster_foreign_AC\": False, # take foreign AC buses into account, True or False\n", + " \"exclusion_area\": [\"Cuxhaven\", \"Bremerhaven\", \"Wesermarsch\", \"Osterholz\", \"Bremen\"], # False, path to shapefile or list of nuts names of not cluster area\n", + " \"method_gas\": \"kmedoids-dijkstra\", # choose clustering method: kmeans or kmedoids-dijkstra\n", + " \"n_clusters_gas\": 17, # total number of resulting CH4 nodes (DE+foreign)\n", + " \"cluster_foreign_gas\": False, # take foreign CH4 buses into account, True or False\n", + " \"k_elec_busmap\": False, # False or path/to/busmap.csv\n", + " \"k_gas_busmap\": False, # False or path/to/ch4_busmap.csv\n", + " \"bus_weight_tocsv\": None, # None or path/to/bus_weight.csv\n", + " \"bus_weight_fromcsv\": None, # None or path/to/bus_weight.csv\n", + " \"gas_weight_tocsv\": None, # None or path/to/gas_bus_weight.csv\n", + " \"gas_weight_fromcsv\": None, # None or path/to/gas_bus_weight.csv\n", + " \"line_length_factor\": 1, # Factor to multiply distance between new buses for new line lengths\n", + " \"remove_stubs\": False, # remove stubs bevore kmeans clustering\n", + " \"use_reduced_coordinates\": False, # If True, do not average cluster coordinates\n", + " \"random_state\": 42, # random state for replicability of clustering results\n", + " \"n_init\": 10, # affects clustering algorithm, only change when neccesary\n", + " \"max_iter\": 100, # affects clustering algorithm, only change when neccesary\n", + " \"tol\": 1e-6, # affects clustering algorithm, only change when neccesary\n", + " \"CPU_cores\": 8, # number of cores used during clustering, \"max\" for all cores available.\n", + " },\n", + " \"sector_coupled_clustering\": {\n", + " \"active\": True, # choose if clustering is activated\n", + " \"carrier_data\": { # select carriers affected by sector coupling\n", + " \"central_heat\": {\n", + " \"base\": [\"CH4\", \"AC\"],\n", + " \"strategy\": \"simultaneous\", # select strategy to cluster other sectors\n", + " },\n", + " },\n", + " },\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### EHV clustering" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.args[\"network_clustering_ehv\"] = True\n", + "etrago.ehv_clustering()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.plot_carrier(carrier_links=[\"AC\", \"DC\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Network clustering" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Run clustering of electrical network:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "%%capture\n", + "etrago.spatial_clustering()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "etrago.plot_carrier(carrier_links=[\"AC\", \"DC\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.plot_clusters()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.plot_carrier(carrier_links=[\"CH4\"], carrier_buses=[\"CH4\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Which bus in the original network corresponds to which bus in the clustered network as well as the original network is stored in `etrago.busmap`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# A copy of the main element of the network is stored in:\n", + "etrago.busmap[\"orig_network\"]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "pd.Series(etrago.busmap[\"busmap\"]).head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Run clustering of the gas network and attached technologies:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%capture\n", + "etrago.spatial_clustering_gas()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.plot_carrier(carrier_links=[\"CH4\"], carrier_buses=[\"CH4\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.plot_clusters(carrier=\"CH4\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.plot_carrier(carrier_links=[\"central_resistive_heater\", \"central_heat_pump\"], carrier_buses=[\"AC\", \"central_heat\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Reduce temporal complexity" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Implemented are:\n", + "\n", + "**Downsampling**\n", + "\n", + "* time-based method\n", + "* groups of consecutive time steps are represented by one time step\n", + "* for each group, one time step is assumed to be representative\n", + "* this representative time step is weighted according to the number of time steps in its group\n", + "\n", + "**Segmentation**\n", + "\n", + "* property-based determination of representative time steps\n", + "* time steps are divided into a certain number of clusters so that similar time steps belong to the same clusters\n", + "* clusters can have different sizes, i.e. represent segments of different length\n", + "* only consecutive time steps are placed in the same clusters\n", + "* for each cluster, a representative time step is defined and weithed based on the number of assigned time steps\n", + "\n", + "**Typical periods**\n", + "\n", + "* typical periods are identified based on time-dependent attributes\n", + "* first, the original time series is divided into time periods of equal length\n", + "* then, the time periods are clustered and representative time periods are selected, which are called typical periods\n", + "* to model storage behavior correctly, additional constraints are required\n", + "\n", + "In case of 'typical periods' and 'segmentation' all load p_set time series as wenn as all renewables p_max_pu time series are used to determine clusters.\n", + "\n", + "The following arguments define the settings for the temporal complexity reduction:\n", + "\n", + "```\n", + "args = { \n", + " # Temporal complexity reduction and disaggregation:\n", + " \"snapshot_clustering\": {\n", + " \"active\": False, # choose if clustering is activated\n", + " \"method\": \"segmentation\", # 'typical_periods' or 'segmentation'\n", + " \"extreme_periods\": None, # consideration of extreme timesteps; e.g. 'append'\n", + " \"how\": \"daily\", # type of period - only relevant for 'typical_periods'\n", + " \"storage_constraints\": \"soc_constraints\", # additional constraints for storages - only relevant for 'typical_periods'\n", + " \"n_clusters\": 5, # number of periods - only relevant for 'typical_periods'\n", + " \"n_segments\": 5, # number of segments - only relevant for 'segmentation'\n", + " },\n", + " \"skip_snapshots\": 5, # Downsampling: False or number of snapshots to skip\n", + " \"temporal_disaggregation\": {\n", + " \"active\": False, # choose if temporally full complex dispatch optimization should be conducted\n", + " \"no_slices\": 8, # number of subproblems optimization is divided into\n", + " },\n", + "}\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 'typical_periods' and 'segmentation' are called by the following function\n", + "#etrago.snapshot_clustering()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.network.loads_t.p_set.sum(axis=1).to_frame(\"load_p_set\").plot(figsize=(8, 3))\n", + "plt.tight_layout()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "etrago.network.snapshots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# run downsampling\n", + "etrago.skip_snapshots()\n", + "etrago.network.snapshots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.network.loads_t.p_set.sum(axis=1).to_frame(\"load_p_set\").plot(figsize=(8, 3))\n", + "plt.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Weight of each snapshot is given in:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.network.snapshot_weightings" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run linear optimal power flow" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following arguments define the settings for the optimisation:\n", + "\n", + "```\n", + "args = {\n", + " \"method\": { # Choose method and settings for optimization\n", + " \"type\": \"lopf\", # type of optimization, currently only 'lopf'\n", + " \"n_iter\": 1, # abort criterion of iterative optimization, 'n_iter' or 'threshold'\n", + " \"pyomo\": True, # set if pyomo is used for model building\n", + " },\n", + " \"solver\": \"glpk\", # glpk, cplex or gurobi\n", + " \"solver_options\": {},\n", + " \"model_formulation\": \"kirchhoff\", # formulation of the LPF problem (all are equivalent)\n", + " \"extendable\": {\n", + " \"extendable_components\": [\n", + " \"as_in_db\"\n", + " ], # Array of components to optimize\n", + " \"upper_bounds_grid\": { # Set upper bounds for grid expansion\n", + " # lines in Germany\n", + " \"grid_max_D\": None, # relative to existing capacity\n", + " \"grid_max_abs_D\": { # absolute capacity per voltage level\n", + " \"380\": {\"i\": 1020, \"wires\": 4, \"circuits\": 4},\n", + " \"220\": {\"i\": 1020, \"wires\": 4, \"circuits\": 4},\n", + " \"110\": {\"i\": 1020, \"wires\": 4, \"circuits\": 2},\n", + " \"dc\": 0,\n", + " },\n", + " # border crossing lines\n", + " \"grid_max_foreign\": 4, # relative to existing capacity\n", + " \"grid_max_abs_foreign\": None, # absolute capacity per voltage level\n", + " },\n", + " },\n", + " \"generator_noise\": 789456, # a small random noise to the marginal costs of each generator in order to prevent an optima plateau\n", + " \"extra_functionality\": {}, # Choose function name (e.g. \"min_renewable_share\" or \"cross_border_flow\") or {} \n", + " \"load_shedding\": False, # helpful when debugging - a very expensive generator is added to each bus \n", + " \"lpfile\": False, # save pyomo's lp file: False or /path/to/lpfile.lp\n", + " \"csv_export\": \"results\", # save results as csv: False or /path/tofolder\n", + " \"pf_post_lopf\": {\n", + " \"active\": True, # choose if a pf should be performed after the lopf\n", + " \"add_foreign_lopf\": True, # keep results of lopf for foreign DC-links\n", + " \"q_allocation\": \"p_nom\", # allocate reactive power via 'p_nom' or 'p'\n", + " },\n", + "}\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#path = \"before_lopf\"\n", + "#etrago.export_to_csv(path)\n", + "#etrago = Etrago(csv_folder_name=path)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Extendable storage units:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.network.storage_units[etrago.network.storage_units.p_nom_extendable].loc[\n", + " :, [\"p_nom\", \"p_nom_min\", \"p_nom_max\", \"p_nom_extendable\", \"carrier\", \"marginal_cost\", \"capital_cost\"]].head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.network.storage_units[etrago.network.storage_units.p_nom_extendable].carrier.unique()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.network.storage_units.carrier.unique()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Extendable stores:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.network.stores[etrago.network.stores.e_nom_extendable].loc[\n", + " :, [\"e_nom\", \"e_nom_min\", \"e_nom_max\", \"e_nom_extendable\", \"carrier\", \"marginal_cost\", \"capital_cost\"]].head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.network.stores[etrago.network.stores.e_nom_extendable].carrier.unique()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.network.stores.carrier.unique()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Extendable lines:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.network.lines[etrago.network.lines.s_nom_extendable].loc[\n", + " :, [\"s_nom\", \"s_nom_min\", \"s_nom_max\", \"s_nom_extendable\", \"carrier\", \"v_nom\", \"capital_cost\", \"country\"]].head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "etrago.lopf()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After the optimisation you can run the following to:\n", + "\n", + "* conduct LOPF with full complex time series for dispatch disaggregation\n", + "\n", + "```\n", + " etrago.dispatch_disaggregation()\n", + "```\n", + "\n", + "* run power flow to obtain reactive power flows over lines\n", + "\n", + "```\n", + " etrago.pf_post_lopf()\n", + "```\n", + "\n", + "* conduct spatial disaggregation of clustered results\n", + "\n", + "```\n", + " etrago.disaggregation()\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "etrago.plot_grid(line_colors=\"expansion_abs\", bus_colors=\"storage_expansion\", bus_sizes= 0.000001)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "etrago.calc_results()\n", + "etrago.results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from etrago.tools.plot import curtailment, nodal_gen_dispatch, flexibility_usage" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "nodal_gen_dispatch(etrago.network)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "curtailment(etrago.network, carrier=\"wind_onshore\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "flexibility_usage(etrago, \"heat\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "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.10.11" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From ad0ca7dd8b31f55ae8aa01659704a6ade34b38b1 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Mon, 30 Oct 2023 11:45:33 +0100 Subject: [PATCH 05/24] Remove ',' at the end of a list This is not working in json files and results into errors --- etrago/args.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etrago/args.json b/etrago/args.json index e64c7b53..606fc142 100644 --- a/etrago/args.json +++ b/etrago/args.json @@ -54,7 +54,7 @@ "delete_dispensable_ac_buses": true, "network_clustering_ehv": { "active": false, - "busmap": false, + "busmap": false }, "network_clustering": { "active": true, @@ -77,7 +77,7 @@ "n_init": 10, "max_iter": 100, "tol": 1e-6, - "CPU_cores": 4, + "CPU_cores": 4 }, "sector_coupled_clustering": { "active": true, From e0b71632c0620c13a2351d6848e98a8691d47132 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Mon, 30 Oct 2023 11:46:21 +0100 Subject: [PATCH 06/24] Add missing closing bracket --- etrago/args.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/etrago/args.json b/etrago/args.json index 606fc142..c5cf7626 100644 --- a/etrago/args.json +++ b/etrago/args.json @@ -88,7 +88,8 @@ "AC" ], "strategy": "simultaneous" - }, + } + } }, "disaggregation": null, "snapshot_clustering": { From 398e1d022f43545425b704581ffd3fbfa3c78f05 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Mon, 30 Oct 2023 11:46:56 +0100 Subject: [PATCH 07/24] Set temporal_disaggregatin to false There are only two snapshots selected, so the temporal disaggregation with 8 slices can not work --- etrago/args.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/etrago/args.json b/etrago/args.json index c5cf7626..48c0afba 100644 --- a/etrago/args.json +++ b/etrago/args.json @@ -99,12 +99,12 @@ "how": "daily", "storage_constraints": "soc_constraints", "n_clusters": 5, - "n_segments": 5, + "n_segments": 5 }, "skip_snapshots": 5, "temporal_disaggregation": { - "active": true, - "no_slices": 8, + "active": false, + "no_slices": 8 }, "branch_capacity_factor": { "HV": 0.5, From e59ca084b5ab09f9a572cfba0b01dc30481b4354 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Mon, 30 Oct 2023 15:24:59 +0100 Subject: [PATCH 08/24] Exclude combination of snapshot_clustering and segmentation --- etrago/tools/utilities.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/etrago/tools/utilities.py b/etrago/tools/utilities.py index 47d05c64..6e1f3b0e 100755 --- a/etrago/tools/utilities.py +++ b/etrago/tools/utilities.py @@ -2421,8 +2421,14 @@ def check_args(etrago): ), "gridversion does not exist" if etrago.args["snapshot_clustering"]["active"]: + # Assert that skip_snapshots and snapshot_clustering are not combined + # more information: https://github.com/openego/eTraGo/issues/691 + assert etrago.args["skip_snapshots"] is False, ( + "eTraGo does not support combining snapshot_clustering and" + " skip_snapshots. Please update your settings and choose either" + " snapshot_clustering or skip_snapshots." + ) # typical periods - if etrago.args["snapshot_clustering"]["method"] == "typical_periods": # typical days From 3bc40f033ed86bc2aa93a80d2961d066e1642894 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Mon, 30 Oct 2023 15:26:08 +0100 Subject: [PATCH 09/24] Fix storing results of snapshot cllustering --- etrago/cluster/snapshot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etrago/cluster/snapshot.py b/etrago/cluster/snapshot.py index a476e93a..7ceee474 100644 --- a/etrago/cluster/snapshot.py +++ b/etrago/cluster/snapshot.py @@ -664,7 +664,7 @@ def run( segm_hoursperperiod=network.snapshots.size, ) - if not segmentation: + if segmentation: pd.DataFrame( timeseries.reset_index(), columns=["dates", "SegmentNo", "SegmentDuration"], From d4755387d1d3539e5ff3c39ff83d599949a837fb Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Mon, 30 Oct 2023 15:29:29 +0100 Subject: [PATCH 10/24] Fix checking if results should be stored after the optimisation --- etrago/tools/execute.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etrago/tools/execute.py b/etrago/tools/execute.py index 838a66a2..5fa4fc2e 100755 --- a/etrago/tools/execute.py +++ b/etrago/tools/execute.py @@ -393,7 +393,7 @@ def lopf(self): z = (y - x) / 60 logger.info("Time for LOPF [min]: {}".format(round(z, 2))) - if not self.args["csv_export"]: + if self.args["csv_export"]: path = self.args["csv_export"] if self.args["temporal_disaggregation"]["active"] is True: path = path + "/temporally_reduced" From 03ab18ad6ada33276944b5a1cb7d54b74466e87f Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Tue, 14 Nov 2023 14:54:58 +0100 Subject: [PATCH 11/24] Fix dc_loading for line loading plot --- etrago/tools/plot.py | 61 +++++++++++++------------------------------- 1 file changed, 18 insertions(+), 43 deletions(-) diff --git a/etrago/tools/plot.py b/etrago/tools/plot.py index 11bee6b3..8999551c 100644 --- a/etrago/tools/plot.py +++ b/etrago/tools/plot.py @@ -25,7 +25,6 @@ import logging import os -from etrago.tools.execute import import_gen_from_links from matplotlib import pyplot as plt from matplotlib.legend_handler import HandlerPatch from matplotlib.patches import Circle, Ellipse @@ -35,6 +34,8 @@ import numpy as np import pandas as pd +from etrago.tools.execute import import_gen_from_links + cartopy_present = True try: import cartopy.crs as ccrs @@ -1584,54 +1585,28 @@ def calc_dc_loading(network, timesteps): DC line loading in MW """ - # Aviod covering of bidirectional links - network.links["linked_to"] = 0 - for i, row in network.links.iterrows(): - if not ( - network.links.index[ - (network.links.bus0 == row["bus1"]) - & (network.links.bus1 == row["bus0"]) - & (network.links.length == row["length"]) - ] - ).empty: - links_df = network.links.index[ - (network.links.bus0 == row["bus1"]) - & (network.links.bus1 == row["bus0"]) - & (network.links.length == row["length"]) - ] - - network.links.at[i, "linked_to"] = links_df.values[0] + dc_links = network.links.loc[network.links.carrier == "DC", :] - network.links.linked_to = network.links.linked_to.astype(str) # Set p_nom_max and line_loading for one directional links link_load = network.links_t.p0[ - network.links.index[network.links.linked_to == "0"] + network.links.index[ # (network.links.linked_to == "0") + # & + (network.links.carrier == "DC") + ] ] - p_nom_opt_max = network.links.p_nom_opt[network.links.linked_to == "0"] - - # Set p_nom_max and line_loading for bidirectional links - for i, row in network.links[network.links.linked_to != "0"].iterrows(): - load = pd.DataFrame( - index=network.links_t.p0.index, columns=["to", "from"] - ) - load["to"] = network.links_t.p0[row["linked_to"]] - load["from"] = network.links_t.p0[i] - link_load[i] = load.abs().max(axis=1) - p_nom_opt_max[i] = max( - row.p_nom_opt, - network.links.p_nom_opt[ - network.links.index == row["linked_to"] - ].values[0], + dc_load = pd.Series(index=network.links.index, data=0.0) + dc_load.loc[dc_links.index] = ( + ( + mul_weighting(network, link_load) + .loc[network.snapshots[timesteps]] + .abs() + .sum()[dc_links.index] + / dc_links.p_nom_opt ) - dc_load = ( - mul_weighting(network, link_load) - .loc[network.snapshots[timesteps]] - .abs() - .sum()[network.links.index] - / p_nom_opt_max - ).dropna() - dc_load.loc[network.links.carrier != "DC"] = 0 + .fillna(0) + .values + ) return dc_load From a1a9d09ce3e7e38db6e0c9f4a61be9c614bbd6e6 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Tue, 14 Nov 2023 14:59:59 +0100 Subject: [PATCH 12/24] Remove commented lines --- etrago/tools/plot.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/etrago/tools/plot.py b/etrago/tools/plot.py index 8999551c..27dbf56d 100644 --- a/etrago/tools/plot.py +++ b/etrago/tools/plot.py @@ -1587,12 +1587,8 @@ def calc_dc_loading(network, timesteps): """ dc_links = network.links.loc[network.links.carrier == "DC", :] - # Set p_nom_max and line_loading for one directional links link_load = network.links_t.p0[ - network.links.index[ # (network.links.linked_to == "0") - # & - (network.links.carrier == "DC") - ] + network.links.index[network.links.carrier == "DC"] ] dc_load = pd.Series(index=network.links.index, data=0.0) From ac240d1bc674b2a317361b4d92e458180e01a413 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Tue, 14 Nov 2023 15:32:28 +0100 Subject: [PATCH 13/24] Upgrade version number --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 7cfa7ab3..efd38cd8 100755 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ def read(*names, **kwargs): ) ), long_description_content_type="text/x-rst", - version="0.8.0", + version="0.9.0", url="https://github.com/openego/eTraGo", license="GNU Affero General Public License Version 3 (AGPL-3.0)", packages=find_packages(), From a0e4588348912f37eebe14a52d70505230187daf Mon Sep 17 00:00:00 2001 From: CarlosEpia Date: Tue, 14 Nov 2023 16:47:13 +0100 Subject: [PATCH 14/24] include link to new tutorial jupiter notebook --- doc/howToUse.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/howToUse.rst b/doc/howToUse.rst index 918fc3c8..20f97f2c 100644 --- a/doc/howToUse.rst +++ b/doc/howToUse.rst @@ -55,4 +55,5 @@ Examples and tutorial notebooks **eTraGo version 0.5.1:** `etrago_OpenMod_Zuerich18 `_. -**eTraGo version 0.9:** Tutorial notebook will be available in the next release. +**eTraGo version 0.9:** +`eTraGo_eGon_final_workshop `_. From 5ad35850eec391b2a0fa98a932fd5bdb9b1a67eb Mon Sep 17 00:00:00 2001 From: CarlosEpia Date: Thu, 16 Nov 2023 14:39:43 +0100 Subject: [PATCH 15/24] fix osm problem --- etrago/tools/plot.py | 63 ++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/etrago/tools/plot.py b/etrago/tools/plot.py index 27dbf56d..e325268e 100644 --- a/etrago/tools/plot.py +++ b/etrago/tools/plot.py @@ -1721,7 +1721,7 @@ def calc_network_expansion(network, method="abs", ext_min=0.1): return network, extension_lines, extension_links -def plot_background_grid(network, ax, geographical_boundaries): +def plot_background_grid(network, ax, geographical_boundaries, osm): """Plots grid topology in background of other network.plot Parameters @@ -1732,6 +1732,9 @@ def plot_background_grid(network, ax, geographical_boundaries): axes of plot geographical_boundaries : list Set georaphical boundaries for the plots + osm : False or dict. + False if not osm background map is required or dictionary with + x, y and zoom information. Returns ------- @@ -1740,21 +1743,8 @@ def plot_background_grid(network, ax, geographical_boundaries): """ link_widths = pd.Series(index=network.links.index, data=0) link_widths.loc[network.links.carrier == "DC"] = 0.3 - - if cartopy_present: - network.plot( - ax=ax, - line_colors="grey", - link_colors="grey", - bus_sizes=0, - line_widths=0.5, - link_widths=link_widths, - geomap=True, - projection=ccrs.PlateCarree(), - color_geomap=True, - boundaries=geographical_boundaries, - ) - else: + + if osm is not False: network.plot( ax=ax, line_colors="grey", @@ -1764,6 +1754,30 @@ def plot_background_grid(network, ax, geographical_boundaries): link_widths=link_widths, geomap=False, ) + else: + if cartopy_present: + network.plot( + ax=ax, + line_colors="grey", + link_colors="grey", + bus_sizes=0, + line_widths=0.5, + link_widths=link_widths, + geomap=True, + projection=ccrs.PlateCarree(), + color_geomap=True, + boundaries=geographical_boundaries, + ) + else: + network.plot( + ax=ax, + line_colors="grey", + link_colors="grey", + bus_sizes=0, + line_widths=0.5, + link_widths=link_widths, + geomap=False, + ) def demand_side_management(self, buses, snapshots, agg="5h", used=False): @@ -2412,7 +2426,7 @@ def plot_grid( link_widths = link_colors.apply(lambda x: 10 if x != 0 else 0) line_widths = 10 label = "line loading in p.u." - plot_background_grid(network, ax, geographical_boundaries) + plot_background_grid(network, ax, geographical_boundaries, osm) # Only active flow direction is displayed! flow = pd.Series(1, index=network.branches().index, dtype="float64") flow.iloc[flow.index.get_level_values("component") == "Line"] = ( @@ -2451,14 +2465,14 @@ def plot_grid( label = "v_nom in kV" line_colors = network.lines.v_nom link_colors = pd.Series(data=0, index=network.links.index) - plot_background_grid(network, ax, geographical_boundaries) + plot_background_grid(network, ax, geographical_boundaries, osm) elif line_colors == "expansion_abs": title = "Network expansion" label = "network expansion in GVA" all_network, line_colors, link_colors = calc_network_expansion( network, method="abs", ext_min=ext_min ) - plot_background_grid(all_network, ax, geographical_boundaries) + plot_background_grid(all_network, ax, geographical_boundaries, osm) if ext_width is not False: line_widths = line_colors / ext_width @@ -2480,7 +2494,7 @@ def plot_grid( all_network, line_colors, link_colors = calc_network_expansion( network, method="rel", ext_min=ext_min ) - plot_background_grid(all_network, ax, geographical_boundaries) + plot_background_grid(all_network, ax, geographical_boundaries, osm) if ext_width is not False: line_widths = 0.5 + (line_colors / ext_width) link_widths = link_colors.apply( @@ -2500,11 +2514,11 @@ def plot_grid( if ext_width is not False: line_widths = 0.5 + (line_colors / ext_width) link_colors = pd.Series(data=0, index=network.links.index) - plot_background_grid(network, ax, geographical_boundaries) + plot_background_grid(network, ax, geographical_boundaries, osm) elif line_colors == "dlr": title = "Dynamic line rating" label = "TWh above nominal capacity" - plot_background_grid(network, ax, geographical_boundaries) + plot_background_grid(network, ax, geographical_boundaries, osm) # calc min capacity per line in the given period: Since lines with # different original voltage level could be aggregated during the @@ -2537,7 +2551,7 @@ def plot_grid( label = "" line_colors = "grey" link_colors = "grey" - plot_background_grid(network, ax, geographical_boundaries) + plot_background_grid(network, ax, geographical_boundaries, osm) link_widths = 0 line_widths = 0 @@ -2673,7 +2687,7 @@ def plot_grid( else: logger.warning("bus_color {} undefined".format(bus_colors)) - if cartopy_present: + if (cartopy_present & (osm is False)): ll = network.plot( line_colors=line_colors, link_colors=link_colors, @@ -2703,7 +2717,6 @@ def plot_grid( flow=flow, title=title, geomap=False, - boundaries=geographical_boundaries, ) l3 = None From f37cf8d5be802c12a51746563b2bdac63ac325d2 Mon Sep 17 00:00:00 2001 From: CarlosEpia Date: Thu, 16 Nov 2023 14:42:26 +0100 Subject: [PATCH 16/24] using black --- etrago/tools/plot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etrago/tools/plot.py b/etrago/tools/plot.py index e325268e..57c3e146 100644 --- a/etrago/tools/plot.py +++ b/etrago/tools/plot.py @@ -1743,7 +1743,7 @@ def plot_background_grid(network, ax, geographical_boundaries, osm): """ link_widths = pd.Series(index=network.links.index, data=0) link_widths.loc[network.links.carrier == "DC"] = 0.3 - + if osm is not False: network.plot( ax=ax, @@ -2687,7 +2687,7 @@ def plot_grid( else: logger.warning("bus_color {} undefined".format(bus_colors)) - if (cartopy_present & (osm is False)): + if cartopy_present & (osm is False): ll = network.plot( line_colors=line_colors, link_colors=link_colors, From 70eebdcb65fd732ccd5f01fca946d97802b1fddf Mon Sep 17 00:00:00 2001 From: CarlosEpia Date: Fri, 17 Nov 2023 14:47:29 +0100 Subject: [PATCH 17/24] avoid cretion of temporary file --- etrago/cluster/spatial.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/etrago/cluster/spatial.py b/etrago/cluster/spatial.py index 37dbb75e..58ae193b 100755 --- a/etrago/cluster/spatial.py +++ b/etrago/cluster/spatial.py @@ -422,7 +422,6 @@ def busmap_by_shortest_path(etrago, fromlvl, tolvl, cpu_cores=4): chunksize = ceil(len(ppaths) / cpu_cores) container = p.starmap(shortest_path, gen(ppaths, chunksize, M)) df = pd.concat(container) - dump(df, open("df.p", "wb")) # post processing df.sort_index(inplace=True) @@ -654,7 +653,6 @@ def dijkstras_algorithm(buses, connections, medoid_idx, cpu_cores): chunksize = ceil(len(ppathss) / cpu_cores) container = p.starmap(shortest_path, gen(ppathss, chunksize, M)) df = pd.concat(container) - dump(df, open("df.p", "wb")) # assignment of data points to closest k-medoids centers df["path_length"] = pd.to_numeric(df["path_length"]) From bdbc1abd0e3e189a3ed2dfad72ca1c1ce29265fb Mon Sep 17 00:00:00 2001 From: CarlosEpia Date: Fri, 17 Nov 2023 14:51:25 +0100 Subject: [PATCH 18/24] delete unnecessary imports --- etrago/cluster/spatial.py | 1 - 1 file changed, 1 deletion(-) diff --git a/etrago/cluster/spatial.py b/etrago/cluster/spatial.py index 58ae193b..139f948e 100755 --- a/etrago/cluster/spatial.py +++ b/etrago/cluster/spatial.py @@ -25,7 +25,6 @@ if "READTHEDOCS" not in os.environ: from itertools import product from math import ceil - from pickle import dump import logging import multiprocessing as mp From f1bfac2d574c45cf3b75bdadac76c022794320c5 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Mon, 20 Nov 2023 17:03:18 +0100 Subject: [PATCH 19/24] Set geographical boundaries correctly when osm is used If the osm map is used as a background grid, the crs is updated. In order to avoid conflicts with the geographical_boundaries, these are now overwritten by the transformed coordinates from the osm parameter. --- etrago/tools/plot.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/etrago/tools/plot.py b/etrago/tools/plot.py index 57c3e146..184744ff 100644 --- a/etrago/tools/plot.py +++ b/etrago/tools/plot.py @@ -116,7 +116,7 @@ def plot_osm(x, y, zoom, alpha=0.4): ) plotter.plot(ax, alpha=alpha) # ax.plot(x, y, "ro-") - return fig, ax + return fig, ax, extent.xrange, extent.yrange def coloring(): @@ -1124,7 +1124,7 @@ def nodal_gen_dispatch( if osm is not False: if set_epsg_network.counter == 0: set_epsg_network(network) - fig, ax = plot_osm(osm["x"], osm["y"], osm["zoom"]) + fig, ax, xrange, yrange = plot_osm(osm["x"], osm["y"], osm["zoom"]) elif (osm is False) and cartopy_present: fig, ax = plt.subplots( subplot_kw={"projection": ccrs.PlateCarree()}, figsize=(5, 5) @@ -1753,6 +1753,7 @@ def plot_background_grid(network, ax, geographical_boundaries, osm): line_widths=0.5, link_widths=link_widths, geomap=False, + boundaries=geographical_boundaries, ) else: if cartopy_present: @@ -2370,8 +2371,8 @@ def plot_grid( False, it could be assinged like this: {"H2": 50, "heat": 0.1, "battery": 10} geographical_boundaries : list, optional - Set georaphical boundaries for the plots The default is - [-2.5, 16, 46.8, 58] + Set georaphical boundaries for the plots. This parameter is overwritten + when osm is used. The default is [-2.5, 16, 46.8, 58] Returns ------- @@ -2397,7 +2398,8 @@ def plot_grid( if osm is not False: if network.srid == 4326: set_epsg_network(network) - fig, ax = plot_osm(osm["x"], osm["y"], osm["zoom"]) + fig, ax, xrange, yrange = plot_osm(osm["x"], osm["y"], osm["zoom"]) + geographical_boundaries = [xrange[0], xrange[1], yrange[0], yrange[1]] elif (osm is False) and cartopy_present: fig, ax = plt.subplots( @@ -2717,6 +2719,7 @@ def plot_grid( flow=flow, title=title, geomap=False, + boundaries=geographical_boundaries, ) l3 = None From a941eb9c2145725a00a55316bac0e2c5b58037ff Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Tue, 21 Nov 2023 09:37:30 +0100 Subject: [PATCH 20/24] Update version number --- doc/conf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 5fc0bd67..05f1f462 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -105,7 +105,7 @@ # General information about the project. project = u'eTraGo' -copyright = u'2015-2018, Flensburg University of Applied Sciences, Europa-Universität Flensburg, Centre for Sustainable Energy Systems, DLR-Institute for Networked Energy Systems' +copyright = u'2015-2023, Flensburg University of Applied Sciences, Europa-Universität Flensburg, Centre for Sustainable Energy Systems, DLR-Institute for Networked Energy Systems' author = u'ulfmueller, lukasol, wolfbunke, mariusves, s3pp' # The version info for the project you're documenting, acts as replacement for @@ -113,9 +113,9 @@ # built documents. # # The short X.Y version. -version = '0.6.1' +version = '0.9' # The full version, including alpha/beta/rc tags. -release = '0.6.1' +release = '0.9.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From 5d3c2c745576912eaa879d710b4fec2bfab501ba Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Tue, 21 Nov 2023 09:37:53 +0100 Subject: [PATCH 21/24] Add release day --- doc/whatsnew/v0_9_0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whatsnew/v0_9_0.rst b/doc/whatsnew/v0_9_0.rst index 5fb2fdf5..46918765 100644 --- a/doc/whatsnew/v0_9_0.rst +++ b/doc/whatsnew/v0_9_0.rst @@ -1,4 +1,4 @@ -Release 0.9.0 (XXXXX, 2023) +Release 0.9.0 (November 21, 2023) ++++++++++++++++++++++++++++ Added features From 58b953fa3a2a51e30855d9ee73e9758b8699a2a6 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Tue, 21 Nov 2023 13:35:02 +0100 Subject: [PATCH 22/24] Exculde jupyter notebook from rtd checks --- doc/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index 05f1f462..e0c84c90 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -132,7 +132,7 @@ # 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', 'eTraGo_tutorial_release0.9.ipynb'] # The reST default role (used for this markup: `text`) to use for all # documents. From 459c44342597d557166da31633854145d9b4127f Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Mon, 4 Dec 2023 14:02:23 +0100 Subject: [PATCH 23/24] Fix name of key for spatial clustering --- etrago/tools/network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etrago/tools/network.py b/etrago/tools/network.py index 6a3f3c3a..f1716ee2 100644 --- a/etrago/tools/network.py +++ b/etrago/tools/network.py @@ -199,7 +199,7 @@ def __init__( csv_folder_name, name, ignore_standard_types ) - if self.args["disaggregation"] is not None: + if self.args["spatial_disaggregation"] is not None: self.disaggregated_network = Network( csv_folder_name + "/disaggregated_network", name, From fcc7e1135aa8ba2b8563baad60a3fdf0c639ffc3 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Tue, 5 Dec 2023 13:24:33 +0100 Subject: [PATCH 24/24] Look for "H2_grid" carrier in network.buses Before this change, the H2_grid nodes were not clustered at all since "H2" was never in the list of carriers --- etrago/cluster/gas.py | 2 +- etrago/tools/network.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/etrago/cluster/gas.py b/etrago/cluster/gas.py index cca92bbf..249048a8 100644 --- a/etrago/cluster/gas.py +++ b/etrago/cluster/gas.py @@ -350,7 +350,7 @@ def gas_postprocessing(etrago, busmap, medoid_idx=None): + "_result.csv" ) - if "H2" in etrago.network.buses.carrier.unique(): + if "H2_grid" in etrago.network.buses.carrier.unique(): busmap = get_h2_clusters(etrago, busmap) # Add all other buses to busmap diff --git a/etrago/tools/network.py b/etrago/tools/network.py index f1716ee2..ae44c390 100644 --- a/etrago/tools/network.py +++ b/etrago/tools/network.py @@ -354,7 +354,7 @@ def build_network_from_db(self): self.decommissioning() - if "H2" in self.network.buses.carrier: + if "H2_grid" in self.network.buses.carrier.unique(): self.add_ch4_h2_correspondence() logger.info("Imported network from db")