From 6d070a19e07cf8cfc6fa0f43d9cdff3cc7297d11 Mon Sep 17 00:00:00 2001 From: Philipp Glaum Date: Thu, 28 Jul 2022 10:38:24 +0200 Subject: [PATCH 01/10] initial ship raster implementation --- Snakefile | 19 ++ config.default.yaml | 4 + config_float.yaml | 333 ++++++++++++++++++++++++++++ scripts/build_renewable_profiles.py | 5 + scripts/build_ship_raster.py | 63 ++++++ 5 files changed, 424 insertions(+) create mode 100755 config_float.yaml create mode 100644 scripts/build_ship_raster.py diff --git a/Snakefile b/Snakefile index ce2b9889a..ceef901a2 100644 --- a/Snakefile +++ b/Snakefile @@ -185,6 +185,22 @@ if config['enable'].get('retrieve_natura_raster', True): run: move(input[0], output[0]) +if config['enable'].get('build_ship_raster', False): + rule build_ship_raster: + input: + ship_density="data/bundle/shipdensity/shipdensity_global.zip", + cutouts=expand("cutouts/{cutouts}.nc", **config['atlite']) + output: "resources/europe_shipdensity_raster.nc" + log: "logs/build_ship_raster.log" + script: "scripts/build_ship_raster.py" + + +if config['enable'].get('retrieve_ship_raster', True): + rule retrieve_ship_raster: + input: HTTP.remote("https://tubcloud.tu-berlin.de/s/P9HArMwKbTH48Tf", keep_local=True, static=True) + output: "resources/europe_shipdensity_raster.nc" + run: move(input[0], output[0]) + rule build_renewable_profiles: input: base_network="networks/base.nc", @@ -195,6 +211,9 @@ rule build_renewable_profiles: gebco=lambda w: ("data/bundle/GEBCO_2014_2D.nc" if "max_depth" in config["renewable"][w.technology].keys() else []), + ship_density= lambda w: ("resources/europe_shipdensity_raster.nc" + if "ship_threshold" in config["renewable"][w.technology].keys() + else []), country_shapes='resources/country_shapes.geojson', offshore_shapes='resources/offshore_shapes.geojson', regions=lambda w: ("resources/regions_onshore.geojson" diff --git a/config.default.yaml b/config.default.yaml index b37297af1..924d5f852 100755 --- a/config.default.yaml +++ b/config.default.yaml @@ -30,6 +30,8 @@ enable: retrieve_cutout: true build_natura_raster: false retrieve_natura_raster: true + build_ship_raster: false + retrieve_ship_raster: true custom_busmap: false electricity: @@ -134,6 +136,7 @@ renewable: # until done more rigorously in #153 corine: [44, 255] natura: true + ship_threshold: 400 max_depth: 50 max_shore_distance: 30000 potential: simple # or conservative @@ -151,6 +154,7 @@ renewable: # until done more rigorously in #153 corine: [44, 255] natura: true + ship_threshold: 400 max_depth: 50 min_shore_distance: 30000 potential: simple # or conservative diff --git a/config_float.yaml b/config_float.yaml new file mode 100755 index 000000000..d99764d44 --- /dev/null +++ b/config_float.yaml @@ -0,0 +1,333 @@ +# SPDX-FileCopyrightText: : 2017-2020 The PyPSA-Eur Authors +# +# SPDX-License-Identifier: CC0-1.0 + +version: 0.4.0 +tutorial: false + +logging: + level: INFO + format: '%(levelname)s:%(name)s:%(message)s' + +summary_dir: results + +scenario: + simpl: [''] + ll: ['copt'] + clusters: [100] + opts: [Co2L-24H] + +countries: ['BE','DE', 'DK', 'GB', 'NL', 'NO'] + +clustering: + simplify: + to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) + +snapshots: + start: "2013-01-01" + end: "2014-01-01" + closed: 'left' # end is not inclusive + +enable: + prepare_links_p_nom: false + retrieve_databundle: true + build_cutout: false + retrieve_cutout: false + build_natura_raster: false + retrieve_natura_raster: true + custom_busmap: false + split_offshore_regions: true #splits big offshore regions into smaller regions + build_ship_raster: true + retrieve_ship_raster: true + +electricity: + voltages: [220., 300., 380.] + co2limit: 7.75e+7 # 0.05 * 3.1e9*0.5 + co2base: 1.487e+9 + agg_p_nom_limits: data/agg_p_nom_minmax.csv + + extendable_carriers: + Generator: [] + StorageUnit: [] # battery, H2 + Store: [battery, H2] + Link: [] + + max_hours: + battery: 6 + H2: 168 + + powerplants_filter: false # use pandas query strings here, e.g. Country not in ['Germany'] + custom_powerplants: false # use pandas query strings here, e.g. Country in ['Germany'] + conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass] + renewable_capacities_from_OPSD: [] # onwind, offwind, solar + + # estimate_renewable_capacities_from_capacity_stats: + # # Wind is the Fueltype in ppm.data.Capacity_stats, onwind, offwind-{ac,dc} the carrier in PyPSA-Eur + # Wind: [onwind, offwind-ac, offwind-dc] + # Solar: [solar] + +atlite: + nprocesses: 1 + show_progress: false + cutouts: + # use 'base' to determine geographical bounds and time span from config + # base: + # module: era5 + europe-2013-era5: + module: era5 # in priority order + dx: 0.3 + dy: 0.3 + time: ['2013', '2013'] + + +renewable: + onwind: + cutout: europe-2013-era5 + resource: + method: wind + turbine: Vestas_V112_3MW + capacity_per_sqkm: 3 # ScholzPhd Tab 4.3.1: 10MW/km^2 + # correction_factor: 0.93 + corine: + # Scholz, Y. (2012). Renewable energy based electricity supply at low costs: + # development of the REMix model and application for Europe. ( p.42 / p.28) + grid_codes: [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 31, 32] + distance: 1000 + distance_grid_codes: [1, 2, 3, 4, 5, 6] + natura: true + potential: simple # or conservative + clip_p_max_pu: 1.e-2 + offwind-ac: + cutout: europe-2013-era5 + resource: + method: wind + turbine: NREL_ReferenceTurbine_2020ATB_12MW_offshore + capacity_per_sqkm: 2 + correction_factor: 0.8855 + # proxy for wake losses + # from 10.1016/j.energy.2018.08.153 + # until done more rigorously in #153 + #corine: [44, 255] + natura: true + max_depth: 60 + max_shore_distance: 30000 + potential: simple # or conservative + clip_p_max_pu: 1.e-2 + calculate_topology_cost: true + offwind-dc: + cutout: europe-2013-era5 + resource: + method: wind + turbine: NREL_ReferenceTurbine_2020ATB_12MW_offshore + capacity_per_sqkm: 2 + correction_factor: 0.8855 + # proxy for wake losses + # from 10.1016/j.energy.2018.08.153 + # until done more rigorously in #153 + #corine: [44, 255] + natura: true + max_depth: 60 + min_shore_distance: 30000 + potential: simple # or conservative + clip_p_max_pu: 1.e-2 + calculate_topology_cost: true + offwind-float: + cutout: europe-2013-era5 + resource: + method: wind + turbine: NREL_ReferenceTurbine_5MW_offshore + # ScholzPhd Tab 4.3.1: 10MW/km^2 + capacity_per_sqkm: 2 + correction_factor: 0.8855 + # proxy for wake losses + # from 10.1016/j.energy.2018.08.153 + # until done more rigorously in #153 + #corine: [44, 255] + natura: true + min_depth: 60 + potential: simple # or conservative + clip_p_max_pu: 1.e-2 + solar: + cutout: europe-2013-era5 + resource: + method: pv + panel: CSi + orientation: + slope: 35. + azimuth: 180. + capacity_per_sqkm: 1.7 # ScholzPhd Tab 4.3.1: 170 MW/km^2 + # Correction factor determined by comparing uncorrected area-weighted full-load hours to those + # published in Supplementary Data to + # Pietzcker, Robert Carl, et al. "Using the sun to decarbonize the power + # sector: The economic potential of photovoltaics and concentrating solar + # power." Applied Energy 135 (2014): 704-720. + # This correction factor of 0.854337 may be in order if using reanalysis data. + # for discussion refer to https://github.com/PyPSA/pypsa-eur/pull/304 + # correction_factor: 0.854337 + corine: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 26, 31, 32] + natura: true + potential: simple # or conservative + clip_p_max_pu: 1.e-2 + hydro: + cutout: europe-2013-era5 + carriers: [ror, PHS, hydro] + PHS_max_hours: 6 + hydro_max_hours: "energy_capacity_totals_by_country" # one of energy_capacity_totals_by_country, estimate_by_large_installations or a float + clip_min_inflow: 1.0 + +lines: + types: + 220.: "Al/St 240/40 2-bundle 220.0" + 300.: "Al/St 240/40 3-bundle 300.0" + 380.: "Al/St 240/40 4-bundle 380.0" + s_max_pu: 0.7 + s_nom_max: .inf + length_factor: 1.25 + under_construction: 'zero' # 'zero': set capacity to zero, 'remove': remove, 'keep': with full capacity + +links: + p_max_pu: 1.0 + p_nom_max: .inf + include_tyndp: true + under_construction: 'zero' # 'zero': set capacity to zero, 'remove': remove, 'keep': with full capacity + +transformers: + x: 0.1 + s_nom: 2000. + type: '' + +load: + power_statistics: True # only for files from <2019; set false in order to get ENTSOE transparency data + interpolate_limit: 3 # data gaps up until this size are interpolated linearly + time_shift_for_large_gaps: 1w # data gaps up until this size are copied by copying from + manual_adjustments: true # false + scaling_factor: 1.0 + +costs: + year: 2030 + discountrate: 0.07 # From a Lion Hirth paper, also reflects average of Noothout et al 2016 + USD2013_to_EUR2013: 0.7532 # [EUR/USD] ECB: https://www.ecb.europa.eu/stats/exchange/eurofxref/html/eurofxref-graph-usd.en.html + marginal_cost: # EUR/MWh + solar: 0.01 + onwind: 0.015 + offwind-ac: 0.015 + offwind-dc: 0.015 + hydro: 0. + H2: 0. + electrolysis: 0. + fuel cell: 0. + battery: 0. + battery inverter: 0. + emission_prices: # in currency per tonne emission, only used with the option Ep + co2: 0. + +solving: + options: + formulation: kirchhoff + load_shedding: false + noisy_costs: true + min_iterations: 4 + max_iterations: 6 + clip_p_max_pu: 0.01 + skip_iterations: false + track_iterations: false + #nhours: 10 + solver: + name: gurobi + threads: 4 + method: 2 # barrier + crossover: 0 + BarConvTol: 1.e-5 + FeasibilityTol: 1.e-6 + AggFill: 0 + PreDual: 0 + GURO_PAR_BARDENSETHRESH: 200 + # solver: + # name: cplex + # threads: 4 + # lpmethod: 4 # barrier + # solutiontype: 2 # non basic solution, ie no crossover + # barrier.convergetol: 1.e-5 + # feasopt.tolerance: 1.e-6 + +plotting: + map: + figsize: [7, 7] + boundaries: [-10.2, 29, 35, 72] + p_nom: + bus_size_factor: 5.e+4 + linewidth_factor: 3.e+3 + + costs_max: 800 + costs_threshold: 1 + + energy_max: 15000. + energy_min: -10000. + energy_threshold: 50. + + vre_techs: ["onwind", "offwind-ac", "offwind-dc", "solar", "ror"] + conv_techs: ["OCGT", "CCGT", "Nuclear", "Coal"] + storage_techs: ["hydro+PHS", "battery", "H2"] + load_carriers: ["AC load"] + AC_carriers: ["AC line", "AC transformer"] + link_carriers: ["DC line", "Converter AC-DC"] + tech_colors: + "onwind" : "#235ebc" + "onshore wind" : "#235ebc" + 'offwind' : "#6895dd" + 'offwind-ac' : "#6895dd" + 'offshore wind' : "#6895dd" + 'offshore wind ac' : "#6895dd" + 'offwind-dc' : "#74c6f2" + 'offshore wind dc' : "#74c6f2" + "hydro" : "#08ad97" + "hydro+PHS" : "#08ad97" + "PHS" : "#08ad97" + "hydro reservoir" : "#08ad97" + 'hydroelectricity' : '#08ad97' + "ror" : "#4adbc8" + "run of river" : "#4adbc8" + 'solar' : "#f9d002" + 'solar PV' : "#f9d002" + 'solar thermal' : '#ffef60' + 'biomass' : '#0c6013' + 'solid biomass' : '#06540d' + 'biogas' : '#23932d' + 'waste' : '#68896b' + 'geothermal' : '#ba91b1' + "OCGT" : "#d35050" + "gas" : "#d35050" + "natural gas" : "#d35050" + "CCGT" : "#b20101" + "nuclear" : "#ff9000" + "coal" : "#707070" + "lignite" : "#9e5a01" + "oil" : "#262626" + "H2" : "#ea048a" + "hydrogen storage" : "#ea048a" + "battery" : "#b8ea04" + "Electric load" : "#f9d002" + "electricity" : "#f9d002" + "lines" : "#70af1d" + "transmission lines" : "#70af1d" + "AC-AC" : "#70af1d" + "AC line" : "#70af1d" + "links" : "#8a1caf" + "HVDC links" : "#8a1caf" + "DC-DC" : "#8a1caf" + "DC link" : "#8a1caf" + nice_names: + OCGT: "Open-Cycle Gas" + CCGT: "Combined-Cycle Gas" + offwind-ac: "Offshore Wind (AC)" + offwind-dc: "Offshore Wind (DC)" + onwind: "Onshore Wind" + solar: "Solar" + PHS: "Pumped Hydro Storage" + hydro: "Reservoir & Dam" + battery: "Battery Storage" + H2: "Hydrogen Storage" + lines: "Transmission Lines" + ror: "Run of River" diff --git a/scripts/build_renewable_profiles.py b/scripts/build_renewable_profiles.py index 49e481ca6..675dc6f9b 100644 --- a/scripts/build_renewable_profiles.py +++ b/scripts/build_renewable_profiles.py @@ -241,6 +241,11 @@ codes = corine["distance_grid_codes"] buffer = corine["distance"] excluder.add_raster(snakemake.input.corine, codes=codes, buffer=buffer, crs=3035) + + if "ship_threshold" in config: + shipping_threshold=config["ship_threshold"]*8760*6 # approximation because 6 years of data which is hourly collected + func = functools.partial(np.less,shipping_threshold) + excluder.add_raster(snakemake.input.ship_density, codes=func, crs=4326, allow_no_overlap=True) if "max_depth" in config: # lambda not supported for atlite + multiprocessing diff --git a/scripts/build_ship_raster.py b/scripts/build_ship_raster.py new file mode 100644 index 000000000..12ad64a66 --- /dev/null +++ b/scripts/build_ship_raster.py @@ -0,0 +1,63 @@ +# SPDX-FileCopyrightText: : 2017-2022 The PyPSA-Eur Authors +# +# SPDX-License-Identifier: MIT + +""" +Transforms the global ship density data from https://datacatalog.worldbank.org/search/dataset/0037580/Global-Shipping-Traffic-Density to the size of the considered cutout. The global ship density raster is later used for the exclusion when calculating the offshore potentials. + +Relevant Settings +----------------- + +.. code:: yaml + + renewable: + {technology}: + cutout: + +.. seealso:: + Documentation of the configuration file ``config.yaml`` at + :ref:`renewable_cf` + +Inputs +------ + +- ``data/bundle/shipdensity/shipdensity_global.zip``: `Global ship density from `. + +Outputs +------- + +- ``resources/natura.tiff``: Reduced version of `Global ship density from Date: Thu, 28 Jul 2022 15:21:21 +0200 Subject: [PATCH 02/10] fix raster format error due to import --- scripts/build_ship_raster.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/build_ship_raster.py b/scripts/build_ship_raster.py index 12ad64a66..d34a1c105 100644 --- a/scripts/build_ship_raster.py +++ b/scripts/build_ship_raster.py @@ -51,13 +51,13 @@ cutouts = snakemake.input.cutouts xs, Xs, ys, Ys = zip(*(determine_cutout_xXyY(cutout) for cutout in cutouts)) - + with zipfile.ZipFile(snakemake.input.ship_density) as zip_f: zip_f.extract("shipdensity_global.tif") - ship_density=xarray.open_dataarray("shipdensity_global.tif", engine="rasterio") + ship_density=xarray.open_rasterio("shipdensity_global.tif") os.remove("shipdensity_global.tif") - ship_density=ship_density.drop("band").sel(x=slice(min(xs),max(Xs)), y=slice(max(Ys),min(ys))) - + ship_density=ship_density.drop(["band"]).sel(x=slice(min(xs),max(Xs)), y=slice(max(Ys),min(ys))) + ship_density.to_netcdf(snakemake.output[0]) From 4db62fa0c6cda6b1b8dd9c511b06ffd78dbbcf12 Mon Sep 17 00:00:00 2001 From: Philipp Glaum Date: Fri, 29 Jul 2022 11:52:33 +0200 Subject: [PATCH 03/10] place holder in snakefile for path to ship_raster --- Snakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Snakefile b/Snakefile index ceef901a2..346c8fff0 100644 --- a/Snakefile +++ b/Snakefile @@ -197,7 +197,7 @@ if config['enable'].get('build_ship_raster', False): if config['enable'].get('retrieve_ship_raster', True): rule retrieve_ship_raster: - input: HTTP.remote("https://tubcloud.tu-berlin.de/s/P9HArMwKbTH48Tf", keep_local=True, static=True) + input: HTTP.remote("path-to-file", keep_local=True, static=True) output: "resources/europe_shipdensity_raster.nc" run: move(input[0], output[0]) From 2b5fefc7db50f91e234b15e38ad2e6d7683961e8 Mon Sep 17 00:00:00 2001 From: Philipp Glaum Date: Fri, 29 Jul 2022 11:52:55 +0200 Subject: [PATCH 04/10] update test config --- test/config.test1.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/config.test1.yaml b/test/config.test1.yaml index ab741ccdb..71cc69032 100755 --- a/test/config.test1.yaml +++ b/test/config.test1.yaml @@ -30,6 +30,8 @@ enable: retrieve_cutout: true build_natura_raster: false retrieve_natura_raster: true + build_ship_raster: false + retrieve_ship_raster: true custom_busmap: false electricity: @@ -86,6 +88,7 @@ renewable: # correction_factor: 0.93 corine: [44, 255] natura: true + ship_threshold: 400 max_shore_distance: 30000 potential: simple # or conservative clip_p_max_pu: 1.e-2 @@ -99,6 +102,7 @@ renewable: # correction_factor: 0.93 corine: [44, 255] natura: true + ship_threshold: 400 min_shore_distance: 30000 potential: simple # or conservative clip_p_max_pu: 1.e-2 From 9cebf95fc0a612a93df9a9ec38be0cc2ce88d24c Mon Sep 17 00:00:00 2001 From: Philipp Glaum Date: Fri, 29 Jul 2022 12:03:50 +0200 Subject: [PATCH 05/10] update tutorial config --- config.tutorial.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config.tutorial.yaml b/config.tutorial.yaml index 99e7836b9..8f7e227a1 100755 --- a/config.tutorial.yaml +++ b/config.tutorial.yaml @@ -31,6 +31,8 @@ enable: retrieve_cutout: true build_natura_raster: false retrieve_natura_raster: true + build_ship_raster: false + retrieve_ship_raster: true custom_busmap: false electricity: @@ -87,6 +89,7 @@ renewable: # correction_factor: 0.93 corine: [44, 255] natura: true + ship_threshold: 400 max_shore_distance: 30000 potential: simple # or conservative clip_p_max_pu: 1.e-2 @@ -100,6 +103,7 @@ renewable: # correction_factor: 0.93 corine: [44, 255] natura: true + ship_threshold: 400 min_shore_distance: 30000 potential: simple # or conservative clip_p_max_pu: 1.e-2 From ebf54a7c9d9ac8b95015d75f7ca0fba4553bfa45 Mon Sep 17 00:00:00 2001 From: Philipp Glaum Date: Fri, 29 Jul 2022 12:11:46 +0200 Subject: [PATCH 06/10] update configtables in the documentation --- doc/configtables/offwind-ac.csv | 1 + doc/configtables/offwind-dc.csv | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/configtables/offwind-ac.csv b/doc/configtables/offwind-ac.csv index def73e4cd..d478011df 100644 --- a/doc/configtables/offwind-ac.csv +++ b/doc/configtables/offwind-ac.csv @@ -6,6 +6,7 @@ resource,,, capacity_per_sqkm,:math:`MW/km^2`,float,"Allowable density of wind turbine placement." corine,--,"Any *realistic* subset of the `CORINE Land Cover code list `_","Specifies areas according to CORINE Land Cover codes which are generally eligible for AC-connected offshore wind turbine placement." natura,bool,"{true, false}","Switch to exclude `Natura 2000 `_ natural protection areas. Area is excluded if ``true``." +ship_threshold,--,float,"Ship density threshold from which areas are excluded." max_depth,m,float,"Maximum sea water depth at which wind turbines can be build. Maritime areas with deeper waters are excluded in the process of calculating the AC-connected offshore wind potential." min_shore_distance,m,float,"Minimum distance to the shore below which wind turbines cannot be build. Such areas close to the shore are excluded in the process of calculating the AC-connected offshore wind potential." potential,--,"One of {'simple', 'conservative'}","Method to compute the maximal installable potential for a node; confer :ref:`renewableprofiles`" diff --git a/doc/configtables/offwind-dc.csv b/doc/configtables/offwind-dc.csv index 17edafcae..67bda165f 100644 --- a/doc/configtables/offwind-dc.csv +++ b/doc/configtables/offwind-dc.csv @@ -6,6 +6,7 @@ resource,,, capacity_per_sqkm,:math:`MW/km^2`,float,"Allowable density of wind turbine placement." corine,--,"Any *realistic* subset of the `CORINE Land Cover code list `_","Specifies areas according to CORINE Land Cover codes which are generally eligible for AC-connected offshore wind turbine placement." natura,bool,"{true, false}","Switch to exclude `Natura 2000 `_ natural protection areas. Area is excluded if ``true``." +ship_threshold,--,float,"Ship density threshold from which areas are excluded." max_depth,m,float,"Maximum sea water depth at which wind turbines can be build. Maritime areas with deeper waters are excluded in the process of calculating the AC-connected offshore wind potential." min_shore_distance,m,float,"Minimum distance to the shore below which wind turbines cannot be build. Such areas close to the shore are excluded in the process of calculating the AC-connected offshore wind potential." potential,--,"One of {'simple', 'conservative'}","Method to compute the maximal installable potential for a node; confer :ref:`renewableprofiles`" From 1009e2a0f666cbf413d4f528a243292df4ad5ced Mon Sep 17 00:00:00 2001 From: Philipp Glaum Date: Fri, 29 Jul 2022 13:43:13 +0200 Subject: [PATCH 07/10] delete config_float --- config_float.yaml | 333 ---------------------------------------------- 1 file changed, 333 deletions(-) delete mode 100755 config_float.yaml diff --git a/config_float.yaml b/config_float.yaml deleted file mode 100755 index d99764d44..000000000 --- a/config_float.yaml +++ /dev/null @@ -1,333 +0,0 @@ -# SPDX-FileCopyrightText: : 2017-2020 The PyPSA-Eur Authors -# -# SPDX-License-Identifier: CC0-1.0 - -version: 0.4.0 -tutorial: false - -logging: - level: INFO - format: '%(levelname)s:%(name)s:%(message)s' - -summary_dir: results - -scenario: - simpl: [''] - ll: ['copt'] - clusters: [100] - opts: [Co2L-24H] - -countries: ['BE','DE', 'DK', 'GB', 'NL', 'NO'] - -clustering: - simplify: - to_substations: false # network is simplified to nodes with positive or negative power injection (i.e. substations or offwind connections) - -snapshots: - start: "2013-01-01" - end: "2014-01-01" - closed: 'left' # end is not inclusive - -enable: - prepare_links_p_nom: false - retrieve_databundle: true - build_cutout: false - retrieve_cutout: false - build_natura_raster: false - retrieve_natura_raster: true - custom_busmap: false - split_offshore_regions: true #splits big offshore regions into smaller regions - build_ship_raster: true - retrieve_ship_raster: true - -electricity: - voltages: [220., 300., 380.] - co2limit: 7.75e+7 # 0.05 * 3.1e9*0.5 - co2base: 1.487e+9 - agg_p_nom_limits: data/agg_p_nom_minmax.csv - - extendable_carriers: - Generator: [] - StorageUnit: [] # battery, H2 - Store: [battery, H2] - Link: [] - - max_hours: - battery: 6 - H2: 168 - - powerplants_filter: false # use pandas query strings here, e.g. Country not in ['Germany'] - custom_powerplants: false # use pandas query strings here, e.g. Country in ['Germany'] - conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass] - renewable_capacities_from_OPSD: [] # onwind, offwind, solar - - # estimate_renewable_capacities_from_capacity_stats: - # # Wind is the Fueltype in ppm.data.Capacity_stats, onwind, offwind-{ac,dc} the carrier in PyPSA-Eur - # Wind: [onwind, offwind-ac, offwind-dc] - # Solar: [solar] - -atlite: - nprocesses: 1 - show_progress: false - cutouts: - # use 'base' to determine geographical bounds and time span from config - # base: - # module: era5 - europe-2013-era5: - module: era5 # in priority order - dx: 0.3 - dy: 0.3 - time: ['2013', '2013'] - - -renewable: - onwind: - cutout: europe-2013-era5 - resource: - method: wind - turbine: Vestas_V112_3MW - capacity_per_sqkm: 3 # ScholzPhd Tab 4.3.1: 10MW/km^2 - # correction_factor: 0.93 - corine: - # Scholz, Y. (2012). Renewable energy based electricity supply at low costs: - # development of the REMix model and application for Europe. ( p.42 / p.28) - grid_codes: [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 31, 32] - distance: 1000 - distance_grid_codes: [1, 2, 3, 4, 5, 6] - natura: true - potential: simple # or conservative - clip_p_max_pu: 1.e-2 - offwind-ac: - cutout: europe-2013-era5 - resource: - method: wind - turbine: NREL_ReferenceTurbine_2020ATB_12MW_offshore - capacity_per_sqkm: 2 - correction_factor: 0.8855 - # proxy for wake losses - # from 10.1016/j.energy.2018.08.153 - # until done more rigorously in #153 - #corine: [44, 255] - natura: true - max_depth: 60 - max_shore_distance: 30000 - potential: simple # or conservative - clip_p_max_pu: 1.e-2 - calculate_topology_cost: true - offwind-dc: - cutout: europe-2013-era5 - resource: - method: wind - turbine: NREL_ReferenceTurbine_2020ATB_12MW_offshore - capacity_per_sqkm: 2 - correction_factor: 0.8855 - # proxy for wake losses - # from 10.1016/j.energy.2018.08.153 - # until done more rigorously in #153 - #corine: [44, 255] - natura: true - max_depth: 60 - min_shore_distance: 30000 - potential: simple # or conservative - clip_p_max_pu: 1.e-2 - calculate_topology_cost: true - offwind-float: - cutout: europe-2013-era5 - resource: - method: wind - turbine: NREL_ReferenceTurbine_5MW_offshore - # ScholzPhd Tab 4.3.1: 10MW/km^2 - capacity_per_sqkm: 2 - correction_factor: 0.8855 - # proxy for wake losses - # from 10.1016/j.energy.2018.08.153 - # until done more rigorously in #153 - #corine: [44, 255] - natura: true - min_depth: 60 - potential: simple # or conservative - clip_p_max_pu: 1.e-2 - solar: - cutout: europe-2013-era5 - resource: - method: pv - panel: CSi - orientation: - slope: 35. - azimuth: 180. - capacity_per_sqkm: 1.7 # ScholzPhd Tab 4.3.1: 170 MW/km^2 - # Correction factor determined by comparing uncorrected area-weighted full-load hours to those - # published in Supplementary Data to - # Pietzcker, Robert Carl, et al. "Using the sun to decarbonize the power - # sector: The economic potential of photovoltaics and concentrating solar - # power." Applied Energy 135 (2014): 704-720. - # This correction factor of 0.854337 may be in order if using reanalysis data. - # for discussion refer to https://github.com/PyPSA/pypsa-eur/pull/304 - # correction_factor: 0.854337 - corine: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 26, 31, 32] - natura: true - potential: simple # or conservative - clip_p_max_pu: 1.e-2 - hydro: - cutout: europe-2013-era5 - carriers: [ror, PHS, hydro] - PHS_max_hours: 6 - hydro_max_hours: "energy_capacity_totals_by_country" # one of energy_capacity_totals_by_country, estimate_by_large_installations or a float - clip_min_inflow: 1.0 - -lines: - types: - 220.: "Al/St 240/40 2-bundle 220.0" - 300.: "Al/St 240/40 3-bundle 300.0" - 380.: "Al/St 240/40 4-bundle 380.0" - s_max_pu: 0.7 - s_nom_max: .inf - length_factor: 1.25 - under_construction: 'zero' # 'zero': set capacity to zero, 'remove': remove, 'keep': with full capacity - -links: - p_max_pu: 1.0 - p_nom_max: .inf - include_tyndp: true - under_construction: 'zero' # 'zero': set capacity to zero, 'remove': remove, 'keep': with full capacity - -transformers: - x: 0.1 - s_nom: 2000. - type: '' - -load: - power_statistics: True # only for files from <2019; set false in order to get ENTSOE transparency data - interpolate_limit: 3 # data gaps up until this size are interpolated linearly - time_shift_for_large_gaps: 1w # data gaps up until this size are copied by copying from - manual_adjustments: true # false - scaling_factor: 1.0 - -costs: - year: 2030 - discountrate: 0.07 # From a Lion Hirth paper, also reflects average of Noothout et al 2016 - USD2013_to_EUR2013: 0.7532 # [EUR/USD] ECB: https://www.ecb.europa.eu/stats/exchange/eurofxref/html/eurofxref-graph-usd.en.html - marginal_cost: # EUR/MWh - solar: 0.01 - onwind: 0.015 - offwind-ac: 0.015 - offwind-dc: 0.015 - hydro: 0. - H2: 0. - electrolysis: 0. - fuel cell: 0. - battery: 0. - battery inverter: 0. - emission_prices: # in currency per tonne emission, only used with the option Ep - co2: 0. - -solving: - options: - formulation: kirchhoff - load_shedding: false - noisy_costs: true - min_iterations: 4 - max_iterations: 6 - clip_p_max_pu: 0.01 - skip_iterations: false - track_iterations: false - #nhours: 10 - solver: - name: gurobi - threads: 4 - method: 2 # barrier - crossover: 0 - BarConvTol: 1.e-5 - FeasibilityTol: 1.e-6 - AggFill: 0 - PreDual: 0 - GURO_PAR_BARDENSETHRESH: 200 - # solver: - # name: cplex - # threads: 4 - # lpmethod: 4 # barrier - # solutiontype: 2 # non basic solution, ie no crossover - # barrier.convergetol: 1.e-5 - # feasopt.tolerance: 1.e-6 - -plotting: - map: - figsize: [7, 7] - boundaries: [-10.2, 29, 35, 72] - p_nom: - bus_size_factor: 5.e+4 - linewidth_factor: 3.e+3 - - costs_max: 800 - costs_threshold: 1 - - energy_max: 15000. - energy_min: -10000. - energy_threshold: 50. - - vre_techs: ["onwind", "offwind-ac", "offwind-dc", "solar", "ror"] - conv_techs: ["OCGT", "CCGT", "Nuclear", "Coal"] - storage_techs: ["hydro+PHS", "battery", "H2"] - load_carriers: ["AC load"] - AC_carriers: ["AC line", "AC transformer"] - link_carriers: ["DC line", "Converter AC-DC"] - tech_colors: - "onwind" : "#235ebc" - "onshore wind" : "#235ebc" - 'offwind' : "#6895dd" - 'offwind-ac' : "#6895dd" - 'offshore wind' : "#6895dd" - 'offshore wind ac' : "#6895dd" - 'offwind-dc' : "#74c6f2" - 'offshore wind dc' : "#74c6f2" - "hydro" : "#08ad97" - "hydro+PHS" : "#08ad97" - "PHS" : "#08ad97" - "hydro reservoir" : "#08ad97" - 'hydroelectricity' : '#08ad97' - "ror" : "#4adbc8" - "run of river" : "#4adbc8" - 'solar' : "#f9d002" - 'solar PV' : "#f9d002" - 'solar thermal' : '#ffef60' - 'biomass' : '#0c6013' - 'solid biomass' : '#06540d' - 'biogas' : '#23932d' - 'waste' : '#68896b' - 'geothermal' : '#ba91b1' - "OCGT" : "#d35050" - "gas" : "#d35050" - "natural gas" : "#d35050" - "CCGT" : "#b20101" - "nuclear" : "#ff9000" - "coal" : "#707070" - "lignite" : "#9e5a01" - "oil" : "#262626" - "H2" : "#ea048a" - "hydrogen storage" : "#ea048a" - "battery" : "#b8ea04" - "Electric load" : "#f9d002" - "electricity" : "#f9d002" - "lines" : "#70af1d" - "transmission lines" : "#70af1d" - "AC-AC" : "#70af1d" - "AC line" : "#70af1d" - "links" : "#8a1caf" - "HVDC links" : "#8a1caf" - "DC-DC" : "#8a1caf" - "DC link" : "#8a1caf" - nice_names: - OCGT: "Open-Cycle Gas" - CCGT: "Combined-Cycle Gas" - offwind-ac: "Offshore Wind (AC)" - offwind-dc: "Offshore Wind (DC)" - onwind: "Onshore Wind" - solar: "Solar" - PHS: "Pumped Hydro Storage" - hydro: "Reservoir & Dam" - battery: "Battery Storage" - H2: "Hydrogen Storage" - lines: "Transmission Lines" - ror: "Run of River" From ba7a5363e7b5440f1de6dd0ff6252536d5346d98 Mon Sep 17 00:00:00 2001 From: Philipp Glaum Date: Fri, 29 Jul 2022 14:56:00 +0200 Subject: [PATCH 08/10] update Fabians review comments --- Snakefile | 4 ++-- scripts/build_renewable_profiles.py | 4 ++-- scripts/build_ship_raster.py | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Snakefile b/Snakefile index 346c8fff0..6aaa95472 100644 --- a/Snakefile +++ b/Snakefile @@ -52,7 +52,7 @@ datafiles = ['ch_cantons.csv', 'je-e-21.03.02.xls', 'eez/World_EEZ_v8_2014.shp', 'hydro_capacities.csv', 'naturalearth/ne_10m_admin_0_countries.shp', 'NUTS_2013_60M_SH/data/NUTS_RG_60M_2013.shp', 'nama_10r_3popgdp.tsv.gz', - 'nama_10r_3gdp.tsv.gz', 'corine/g250_clc06_V18_5.tif'] + 'nama_10r_3gdp.tsv.gz', 'corine/g250_clc06_V18_5.tif', 'shipdensity/shipdensity_global.zip'] if not config.get('tutorial', False): @@ -197,7 +197,7 @@ if config['enable'].get('build_ship_raster', False): if config['enable'].get('retrieve_ship_raster', True): rule retrieve_ship_raster: - input: HTTP.remote("path-to-file", keep_local=True, static=True) + input: HTTP.remote("https://sandbox.zenodo.org/record/1089563/files/europe_shipdensity_raster.nc", keep_local=True, static=True) output: "resources/europe_shipdensity_raster.nc" run: move(input[0], output[0]) diff --git a/scripts/build_renewable_profiles.py b/scripts/build_renewable_profiles.py index 675dc6f9b..bcc1549bd 100644 --- a/scripts/build_renewable_profiles.py +++ b/scripts/build_renewable_profiles.py @@ -243,8 +243,8 @@ excluder.add_raster(snakemake.input.corine, codes=codes, buffer=buffer, crs=3035) if "ship_threshold" in config: - shipping_threshold=config["ship_threshold"]*8760*6 # approximation because 6 years of data which is hourly collected - func = functools.partial(np.less,shipping_threshold) + shipping_threshold=config["ship_threshold"] * 8760 * 6 # approximation because 6 years of data which is hourly collected + func = functools.partial(np.less, shipping_threshold) excluder.add_raster(snakemake.input.ship_density, codes=func, crs=4326, allow_no_overlap=True) if "max_depth" in config: diff --git a/scripts/build_ship_raster.py b/scripts/build_ship_raster.py index d34a1c105..b5f9e9dad 100644 --- a/scripts/build_ship_raster.py +++ b/scripts/build_ship_raster.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: : 2017-2022 The PyPSA-Eur Authors +# SPDX-FileCopyrightText: : 2022 The PyPSA-Eur Authors # # SPDX-License-Identifier: MIT @@ -26,7 +26,7 @@ Outputs ------- -- ``resources/natura.tiff``: Reduced version of `Global ship density from Date: Fri, 29 Jul 2022 15:12:19 +0200 Subject: [PATCH 09/10] add release note --- 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 04c41a812..e02e643e6 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -10,7 +10,7 @@ Release Notes Upcoming Release ================ -* new feature +* Add functionality to consider shipping routes when calculating the available area for offshore technologies. Data for the shipping density comes from the `Global Shipping Traffic Density dataset ` PyPSA-Eur 0.5.0 (27th July 2022) ===================================== From ca183ba89ee65ebe6500c23bdbb5ca57ed79e9b0 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Tue, 2 Aug 2022 15:56:47 +0200 Subject: [PATCH 10/10] add zenodo dataset for download --- Snakefile | 30 +++++++++++++++--------------- config.default.yaml | 2 -- config.tutorial.yaml | 2 -- test/config.test1.yaml | 2 -- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/Snakefile b/Snakefile index 6aaa95472..448034486 100644 --- a/Snakefile +++ b/Snakefile @@ -52,7 +52,7 @@ datafiles = ['ch_cantons.csv', 'je-e-21.03.02.xls', 'eez/World_EEZ_v8_2014.shp', 'hydro_capacities.csv', 'naturalearth/ne_10m_admin_0_countries.shp', 'NUTS_2013_60M_SH/data/NUTS_RG_60M_2013.shp', 'nama_10r_3popgdp.tsv.gz', - 'nama_10r_3gdp.tsv.gz', 'corine/g250_clc06_V18_5.tif', 'shipdensity/shipdensity_global.zip'] + 'nama_10r_3gdp.tsv.gz', 'corine/g250_clc06_V18_5.tif'] if not config.get('tutorial', False): @@ -185,21 +185,21 @@ if config['enable'].get('retrieve_natura_raster', True): run: move(input[0], output[0]) -if config['enable'].get('build_ship_raster', False): - rule build_ship_raster: - input: - ship_density="data/bundle/shipdensity/shipdensity_global.zip", - cutouts=expand("cutouts/{cutouts}.nc", **config['atlite']) - output: "resources/europe_shipdensity_raster.nc" - log: "logs/build_ship_raster.log" - script: "scripts/build_ship_raster.py" +rule retrieve_ship_raster: + input: HTTP.remote("https://zenodo.org/record/6953563/files/shipdensity_global.zip", keep_local=True, static=True) + output: "data/shipdensity_global.zip" + run: move(input[0], output[0]) -if config['enable'].get('retrieve_ship_raster', True): - rule retrieve_ship_raster: - input: HTTP.remote("https://sandbox.zenodo.org/record/1089563/files/europe_shipdensity_raster.nc", keep_local=True, static=True) - output: "resources/europe_shipdensity_raster.nc" - run: move(input[0], output[0]) +rule build_ship_raster: + input: + ship_density="data/shipdensity_global.zip", + cutouts=expand("cutouts/{cutouts}.nc", **config['atlite']) + output: "resources/shipdensity_raster.nc" + log: "logs/build_ship_raster.log" + benchmark: "benchmarks/build_ship_raster" + script: "scripts/build_ship_raster.py" + rule build_renewable_profiles: input: @@ -211,7 +211,7 @@ rule build_renewable_profiles: gebco=lambda w: ("data/bundle/GEBCO_2014_2D.nc" if "max_depth" in config["renewable"][w.technology].keys() else []), - ship_density= lambda w: ("resources/europe_shipdensity_raster.nc" + ship_density= lambda w: ("resources/shipdensity_raster.nc" if "ship_threshold" in config["renewable"][w.technology].keys() else []), country_shapes='resources/country_shapes.geojson', diff --git a/config.default.yaml b/config.default.yaml index b287b87b2..83f1cfd81 100755 --- a/config.default.yaml +++ b/config.default.yaml @@ -30,8 +30,6 @@ enable: retrieve_cutout: true build_natura_raster: false retrieve_natura_raster: true - build_ship_raster: false - retrieve_ship_raster: true custom_busmap: false electricity: diff --git a/config.tutorial.yaml b/config.tutorial.yaml index 5f81dbae3..ed2f9bf0e 100755 --- a/config.tutorial.yaml +++ b/config.tutorial.yaml @@ -31,8 +31,6 @@ enable: retrieve_cutout: true build_natura_raster: false retrieve_natura_raster: true - build_ship_raster: false - retrieve_ship_raster: true custom_busmap: false electricity: diff --git a/test/config.test1.yaml b/test/config.test1.yaml index 4ed1e904f..2f25b6eb6 100755 --- a/test/config.test1.yaml +++ b/test/config.test1.yaml @@ -30,8 +30,6 @@ enable: retrieve_cutout: true build_natura_raster: false retrieve_natura_raster: true - build_ship_raster: false - retrieve_ship_raster: true custom_busmap: false electricity: