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: