From 4b6199de42d8547c35b4b35dec482ab23ffb55b3 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Fri, 9 Feb 2024 15:43:27 +0100 Subject: [PATCH 01/14] create a bus for every unique coordinate, not only substations (closes #699) --- rules/postprocess.smk | 6 +++--- scripts/base_network.py | 1 + scripts/build_bus_regions.py | 8 +++++++- scripts/simplify_network.py | 1 + 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/rules/postprocess.smk b/rules/postprocess.smk index 18d65c16..98b90fd1 100644 --- a/rules/postprocess.smk +++ b/rules/postprocess.smk @@ -45,7 +45,7 @@ if config["foresight"] != "perfect": ( LOGS + "plot_power_network/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.log" - ) + ), benchmark: ( BENCHMARKS @@ -74,7 +74,7 @@ if config["foresight"] != "perfect": ( LOGS + "plot_hydrogen_network/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.log" - ) + ), benchmark: ( BENCHMARKS @@ -102,7 +102,7 @@ if config["foresight"] != "perfect": ( LOGS + "plot_gas_network/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.log" - ) + ), benchmark: ( BENCHMARKS diff --git a/scripts/base_network.py b/scripts/base_network.py index 1de3ef96..684ca613 100644 --- a/scripts/base_network.py +++ b/scripts/base_network.py @@ -555,6 +555,7 @@ def _set_countries_and_substations(n, config, country_shapes, offshore_shapes): for b, df in product(("bus0", "bus1"), (n.lines, n.links)): has_connections_b |= ~df.groupby(b).under_construction.min() + buses["onshore_bus"] = onshore_b buses["substation_lv"] = ( lv_b & onshore_b & (~buses["under_construction"]) & has_connections_b ) diff --git a/scripts/build_bus_regions.py b/scripts/build_bus_regions.py index a6500bb0..f9bf287e 100644 --- a/scripts/build_bus_regions.py +++ b/scripts/build_bus_regions.py @@ -135,7 +135,13 @@ if __name__ == "__main__": c_b = n.buses.country == country onshore_shape = country_shapes[country] - onshore_locs = n.buses.loc[c_b & n.buses.substation_lv, ["x", "y"]] + onshore_locs = ( + n.buses.loc[c_b & n.buses.onshore_bus] + .sort_values( + by="substation_lv", ascending=False + ) # preference for substations + .drop_duplicates(subset=["x", "y"], keep="first")[["x", "y"]] + ) onshore_regions.append( gpd.GeoDataFrame( { diff --git a/scripts/simplify_network.py b/scripts/simplify_network.py index 31bc8f4e..cc4ff4f6 100644 --- a/scripts/simplify_network.py +++ b/scripts/simplify_network.py @@ -611,6 +611,7 @@ if __name__ == "__main__": "symbol", "tags", "under_construction", + "onshore_bus", "substation_lv", "substation_off", "geometry", From 8781e690661b064432689511f215eaa48affa7bf Mon Sep 17 00:00:00 2001 From: Tom Brown Date: Fri, 9 Feb 2024 18:36:16 +0100 Subject: [PATCH 02/14] bugfix: coal emissions for industry weren't tracked Also allow industrial coal demand to be regional (so we can include them in regional CO2 constraints). --- config/config.default.yaml | 1 + scripts/prepare_sector_network.py | 39 +++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/config/config.default.yaml b/config/config.default.yaml index 1033d49d..44b54148 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -501,6 +501,7 @@ sector: SMR_cc: true regional_methanol_demand: false regional_oil_demand: false + regional_coal_demand: false regional_co2_sequestration_potential: enable: false attribute: 'conservative estimate Mt' diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index be8aea53..18d1feb0 100755 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -172,6 +172,13 @@ def define_spatial(nodes, options): spatial.coal.nodes = ["EU coal"] spatial.coal.locations = ["EU"] + if options["regional_coal_demand"]: + spatial.coal.demand_locations = nodes + spatial.coal.industry = nodes + " coal for industry" + else: + spatial.coal.demand_locations = ["EU"] + spatial.coal.industry = ["EU coal for industry"] + # lignite spatial.lignite = SimpleNamespace() spatial.lignite.nodes = ["EU lignite"] @@ -3048,19 +3055,41 @@ def add_industry(n, costs): mwh_coal_per_mwh_coke = 1.366 # from eurostat energy balance p_set = ( - industrial_demand["coal"].sum() - + mwh_coal_per_mwh_coke * industrial_demand["coke"].sum() + industrial_demand["coal"] + + mwh_coal_per_mwh_coke * industrial_demand["coke"] ) / nhours + if not options["regional_coal_demand"]: + p_set = p_set.sum() + + n.madd( + "Bus", + spatial.coal.industry, + location=spatial.coal.demand_locations, + carrier="coal for industry", + unit="MWh_LHV", + ) + n.madd( "Load", - spatial.coal.nodes, - suffix=" for industry", - bus=spatial.coal.nodes, + spatial.coal.industry, + bus=spatial.coal.industry, carrier="coal for industry", p_set=p_set, ) + n.madd( + "Link", + spatial.coal.industry, + bus0=spatial.coal.nodes, + bus1=spatial.coal.industry, + bus2="co2 atmosphere", + carrier="coal for industry", + p_nom_extendable=True, + efficiency2=costs.at["coal", "CO2 intensity"], + ) + + def add_waste_heat(n): # TODO options? From 17105b81256a5364739a4a2f4c3e865a3ba3fc95 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 10 Feb 2024 18:17:57 +0000 Subject: [PATCH 03/14] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scripts/prepare_sector_network.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 18d1feb0..5d5e271b 100755 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -3090,7 +3090,6 @@ def add_industry(n, costs): ) - def add_waste_heat(n): # TODO options? From ecedea02d630d49ff14ad54c97c11b919211ea77 Mon Sep 17 00:00:00 2001 From: Tom Brown Date: Mon, 12 Feb 2024 18:17:53 +0100 Subject: [PATCH 04/14] bugfix: include all countries in ammonia production resource This is so that the full EU28 ammonia demand can be correctly subtracted in the build_industry_sector_ratios.py script. No other downstream scripts are affected by this change. --- scripts/build_ammonia_production.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/build_ammonia_production.py b/scripts/build_ammonia_production.py index 1bcdf9ae..bfcfaf02 100644 --- a/scripts/build_ammonia_production.py +++ b/scripts/build_ammonia_production.py @@ -8,6 +8,7 @@ Build historical annual ammonia production per country in ktonNH3/a. import country_converter as coco import pandas as pd +import numpy as np cc = coco.CountryConverter() @@ -30,8 +31,12 @@ if __name__ == "__main__": ammonia.index = cc.convert(ammonia.index, to="iso2") years = [str(i) for i in range(2013, 2018)] - countries = ammonia.index.intersection(snakemake.params.countries) - ammonia = ammonia.loc[countries, years].astype(float) + + ammonia = ammonia[years] + ammonia.replace("--", + np.nan, + inplace=True) + ammonia = ammonia.astype(float) # convert from ktonN to ktonNH3 ammonia *= 17 / 14 From c54626cc1a847ffded57e50cba2330f1f994a4ec Mon Sep 17 00:00:00 2001 From: Tom Brown Date: Mon, 12 Feb 2024 18:19:25 +0100 Subject: [PATCH 05/14] bugfix: correct units of subtracted chlorine and methanol in build_industry_sector_ratios.py. In the config the units are Mt/a, they are multiplied by MWh/t, but what is desired is GWh/a. --- scripts/build_industry_sector_ratios.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/build_industry_sector_ratios.py b/scripts/build_industry_sector_ratios.py index 45705002..805cf3e7 100644 --- a/scripts/build_industry_sector_ratios.py +++ b/scripts/build_industry_sector_ratios.py @@ -408,15 +408,15 @@ def chemicals_industry(): df.loc["methane", sector] -= ammonia_total * params["MWh_CH4_per_tNH3_SMR"] df.loc["elec", sector] -= ammonia_total * params["MWh_elec_per_tNH3_SMR"] - # subtract chlorine demand + # subtract chlorine demand (in MtCl/a) chlorine_total = params["chlorine_production_today"] - df.loc["hydrogen", sector] -= chlorine_total * params["MWh_H2_per_tCl"] - df.loc["elec", sector] -= chlorine_total * params["MWh_elec_per_tCl"] + df.loc["hydrogen", sector] -= chlorine_total * params["MWh_H2_per_tCl"] * 1e3 + df.loc["elec", sector] -= chlorine_total * params["MWh_elec_per_tCl"] * 1e3 - # subtract methanol demand + # subtract methanol demand (in MtMeOH/a) methanol_total = params["methanol_production_today"] - df.loc["methane", sector] -= methanol_total * params["MWh_CH4_per_tMeOH"] - df.loc["elec", sector] -= methanol_total * params["MWh_elec_per_tMeOH"] + df.loc["methane", sector] -= methanol_total * params["MWh_CH4_per_tMeOH"] * 1e3 + df.loc["elec", sector] -= methanol_total * params["MWh_elec_per_tMeOH"] * 1e3 # MWh/t material df.loc[sources, sector] = df.loc[sources, sector] / s_out From 4fa504b0dbd60aa0b410d2bffba4c68e525159ff Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:32:20 +0000 Subject: [PATCH 06/14] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scripts/build_ammonia_production.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/scripts/build_ammonia_production.py b/scripts/build_ammonia_production.py index bfcfaf02..77b33075 100644 --- a/scripts/build_ammonia_production.py +++ b/scripts/build_ammonia_production.py @@ -7,8 +7,8 @@ Build historical annual ammonia production per country in ktonNH3/a. """ import country_converter as coco -import pandas as pd import numpy as np +import pandas as pd cc = coco.CountryConverter() @@ -33,9 +33,7 @@ if __name__ == "__main__": years = [str(i) for i in range(2013, 2018)] ammonia = ammonia[years] - ammonia.replace("--", - np.nan, - inplace=True) + ammonia.replace("--", np.nan, inplace=True) ammonia = ammonia.astype(float) # convert from ktonN to ktonNH3 From 16955d24abec236e757c5f19cf0af003939defbb Mon Sep 17 00:00:00 2001 From: martacki Date: Thu, 15 Feb 2024 16:27:44 +0100 Subject: [PATCH 07/14] data: upload swiss energy totals data for all years --- data/switzerland-new_format-all_years.csv | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 data/switzerland-new_format-all_years.csv diff --git a/data/switzerland-new_format-all_years.csv b/data/switzerland-new_format-all_years.csv new file mode 100644 index 00000000..93123009 --- /dev/null +++ b/data/switzerland-new_format-all_years.csv @@ -0,0 +1,25 @@ +country,item,2010,2011,2012,2013,2014,2015 +CH,total residential,268.2,223.4,243.4,261.3,214.2,229.1 +CH,total residential space,192.2,149.0,168.1,185.5,139.7,154.4 +CH,total residential water,32.2,31.6,31.9,32.2,31.7,31.9 +CH,total residential cooking,9.3,9.3,9.3,9.4,9.5,9.6 +CH,electricity residential,67.9,63.7,65.7,67.6,63.0,64.4 +CH,electricity residential space,15.9,12.8,14.3,15.8,12.3,13.5 +CH,electricity residential water,8.8,8.5,8.5,8.6,8.5,8.6 +CH,electricity residential cooking,4.9,4.9,4.9,4.9,5.0,5.0 +CH,total services,145.9,127.4,136.7,144.0,124.5,132.5 +CH,total services space,80.0,62.2,70.8,77.4,58.3,64.3 +CH,total services water,10.1,10.0,10.1,10.1,10.0,10.0 +CH,total services cooking,2.5,2.4,2.3,2.3,2.4,2.3 +CH,electricity services,60.5,59.2,60.3,61.4,60.3,62.6 +CH,electricity services space,4.0,3.2,3.8,4.2,3.3,3.6 +CH,electricity services water,0.7,0.7,0.7,0.7,0.7,0.7 +CH,electricity services cooking,2.5,2.4,2.3,2.3,2.4,2.3 +CH,total rail,11.5,11.1,11.2,11.4,11.1,11.4 +CH,total road,199.4,200.4,200.4,201.2,202.0,203.1 +CH,electricity road,0.,0.,0.,0.,0.,0. +CH,electricity rail,11.5,11.1,11.2,11.4,11.1,11.4 +CH,total domestic aviation,3.3,3.2,3.4,3.4,3.5,3.5 +CH,total international aviation,58.0,62.0,63.5,64.2,64.5,66.8 +CH,total domestic navigation,1.6,1.6,1.6,1.6,1.6,1.6 +CH,total international navigation,0.,0.,0.,0.,0.,0. From a22b19dcc49639ce927d72ac1bb640c29059fcdf Mon Sep 17 00:00:00 2001 From: martacki Date: Thu, 15 Feb 2024 16:28:24 +0100 Subject: [PATCH 08/14] use new swiss data for building energy totals --- rules/build_sector.smk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/build_sector.smk b/rules/build_sector.smk index c25c8673..d99c39ae 100644 --- a/rules/build_sector.smk +++ b/rules/build_sector.smk @@ -248,7 +248,7 @@ rule build_energy_totals: input: nuts3_shapes=RESOURCES + "nuts3_shapes.geojson", co2="data/bundle-sector/eea/UNFCCC_v23.csv", - swiss="data/bundle-sector/switzerland-sfoe/switzerland-new_format.csv", + swiss="data/switzerland-new_format-all_years.csv", idees="data/bundle-sector/jrc-idees-2015", district_heat_share="data/district_heat_share.csv", eurostat=input_eurostat, From 6196fd689283e25c0be0660bfc313a2fb4f07430 Mon Sep 17 00:00:00 2001 From: martacki Date: Thu, 15 Feb 2024 16:29:29 +0100 Subject: [PATCH 09/14] change default energy totals year to 2013 to comply with default weather year --- config/config.default.yaml | 2 +- doc/release_notes.rst | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/config.default.yaml b/config/config.default.yaml index 1033d49d..ba99e3ba 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -314,7 +314,7 @@ pypsa_eur: # docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#energy energy: - energy_totals_year: 2011 + energy_totals_year: 2013 base_emissions_year: 1990 eurostat_report_year: 2016 emissions: CO2 diff --git a/doc/release_notes.rst b/doc/release_notes.rst index cab8229a..fde06f97 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -113,6 +113,8 @@ Upcoming Release workflows with foresight "myopic" and still needs to be added foresight option "perfect". +* Swiched the energy totals year from 2011 to 2013 to comply with the assumed default weather year. + PyPSA-Eur 0.9.0 (5th January 2024) ================================== From ccbf835976e2cf776f421a5f868158dbe9d42848 Mon Sep 17 00:00:00 2001 From: martacki Date: Fri, 16 Feb 2024 09:49:00 +0100 Subject: [PATCH 10/14] fix typo to make pre-commit.ci happy --- doc/release_notes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index fde06f97..e017b07d 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -113,7 +113,7 @@ Upcoming Release workflows with foresight "myopic" and still needs to be added foresight option "perfect". -* Swiched the energy totals year from 2011 to 2013 to comply with the assumed default weather year. +* Switched the energy totals year from 2011 to 2013 to comply with the assumed default weather year. PyPSA-Eur 0.9.0 (5th January 2024) From c22e47cd58e46b98fb591e5d951652518257e61a Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Fri, 16 Feb 2024 12:07:37 +0100 Subject: [PATCH 11/14] add release note --- doc/release_notes.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index cab8229a..08ec9dd5 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -10,6 +10,11 @@ Release Notes Upcoming Release ================ +* Regions are assigned to all buses with unique coordinates in the network with + a preference given to substations. Previously, only substations had assigned + regions, but this could lead to issues when a high spatial resolution was + applied. + * The default configuration ``config/config.default.yaml`` is now automatically used as a base configuration file and no longer copied to ``config/config.yaml`` on first use. The file ``config/config.yaml`` should be From 67484f9cf0428bf8d8c8e463730db9c0001e064d Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Fri, 16 Feb 2024 12:13:35 +0100 Subject: [PATCH 12/14] remove numpy import, add release ntoe --- doc/release_notes.rst | 4 ++++ rules/build_sector.smk | 2 -- scripts/build_ammonia_production.py | 4 +--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index cab8229a..fc58c899 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -10,6 +10,10 @@ Release Notes Upcoming Release ================ +* Include all countries in ammonia production resource. This is so that the full + EU28 ammonia demand can be correctly subtracted in the rule + :mod:`build_industry_sector_ratios`. + * The default configuration ``config/config.default.yaml`` is now automatically used as a base configuration file and no longer copied to ``config/config.yaml`` on first use. The file ``config/config.yaml`` should be diff --git a/rules/build_sector.smk b/rules/build_sector.smk index c25c8673..35a59008 100644 --- a/rules/build_sector.smk +++ b/rules/build_sector.smk @@ -392,8 +392,6 @@ rule build_salt_cavern_potentials: rule build_ammonia_production: - params: - countries=config["countries"], input: usgs="data/bundle-sector/myb1-2017-nitro.xls", output: diff --git a/scripts/build_ammonia_production.py b/scripts/build_ammonia_production.py index 77b33075..e2cf6a7b 100644 --- a/scripts/build_ammonia_production.py +++ b/scripts/build_ammonia_production.py @@ -7,7 +7,6 @@ Build historical annual ammonia production per country in ktonNH3/a. """ import country_converter as coco -import numpy as np import pandas as pd cc = coco.CountryConverter() @@ -26,6 +25,7 @@ if __name__ == "__main__": header=0, index_col=0, skipfooter=19, + na_values=["--"], ) ammonia.index = cc.convert(ammonia.index, to="iso2") @@ -33,8 +33,6 @@ if __name__ == "__main__": years = [str(i) for i in range(2013, 2018)] ammonia = ammonia[years] - ammonia.replace("--", np.nan, inplace=True) - ammonia = ammonia.astype(float) # convert from ktonN to ktonNH3 ammonia *= 17 / 14 From 7e66c1428d5a538efd0917ed2ff8002e1e9fcfec Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Fri, 16 Feb 2024 12:40:05 +0100 Subject: [PATCH 13/14] add release note --- doc/release_notes.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index cab8229a..ffe1a794 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -10,6 +10,9 @@ Release Notes Upcoming Release ================ +* Bugfix: Correct units of subtracted chlorine and methanol demand in + :mod:`build_industry_sector_ratios`. + * The default configuration ``config/config.default.yaml`` is now automatically used as a base configuration file and no longer copied to ``config/config.yaml`` on first use. The file ``config/config.yaml`` should be From 6d80b332e606c7569e180f8519204a3be30724a4 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Fri, 16 Feb 2024 12:47:01 +0100 Subject: [PATCH 14/14] add release note --- doc/release_notes.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index ee7bd64b..ccb886e6 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -10,6 +10,11 @@ Release Notes Upcoming Release ================ +* Bugfix: The industry coal emissions for industry were not properly tracked. + +* Allow industrial coal demand to be regional so its emissions can be included + in regional emission limits. + * Add new default to overdimension heating in individual buildings. This allows them to cover heat demand peaks e.g. 10% higher than those in the data. The disadvantage of manipulating the costs is that the capacity is then not quite