diff --git a/config/config.default.yaml b/config/config.default.yaml index 6a5c6f3f2..b32031eaf 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -107,7 +107,7 @@ electricity: H2: 168 extendable_carriers: - Generator: [solar, onwind, offwind-ac, offwind-dc, OCGT] + Generator: [solar, onwind, offwind-ac, offwind-dc, offwind-float, OCGT] StorageUnit: [] # battery, H2 Store: [battery, H2] Link: [] # H2 pipeline @@ -117,7 +117,7 @@ electricity: everywhere_powerplants: [nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass] conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass] - renewable_carriers: [solar, onwind, offwind-ac, offwind-dc, hydro] + renewable_carriers: [solar, onwind, offwind-ac, offwind-dc, offwind-float, hydro] estimate_renewable_capacities: enable: true @@ -125,7 +125,7 @@ electricity: year: 2020 expansion_limit: false technology_mapping: - Offshore: [offwind-ac, offwind-dc] + Offshore: [offwind-ac, offwind-dc, offwind-float] Onshore: [onwind] PV: [solar] @@ -193,7 +193,7 @@ renewable: luisa: false # [0, 5230] natura: true ship_threshold: 400 - max_depth: 50 + max_depth: 60 max_shore_distance: 30000 excluder_resolution: 200 clip_p_max_pu: 1.e-2 @@ -209,10 +209,28 @@ renewable: luisa: false # [0, 5230] natura: true ship_threshold: 400 - max_depth: 50 + max_depth: 60 min_shore_distance: 30000 excluder_resolution: 200 clip_p_max_pu: 1.e-2 + 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 + ship_threshold: 400 + excluder_resolution: 200 + min_depth: 60 + max_depth: 1000 + clip_p_max_pu: 1.e-2 solar: cutout: europe-2013-sarah resource: @@ -306,6 +324,7 @@ pypsa_eur: - onwind - offwind-ac - offwind-dc + - offwind-float - solar - ror - nuclear @@ -851,6 +870,7 @@ plotting: CCGT: "Combined-Cycle Gas" offwind-ac: "Offshore Wind (AC)" offwind-dc: "Offshore Wind (DC)" + offwind-float: "Offshore Wind (Floating)" onwind: "Onshore Wind" solar: "Solar" PHS: "Pumped Hydro Storage" @@ -875,6 +895,9 @@ plotting: offwind-dc: "#74c6f2" offshore wind (DC): "#74c6f2" offshore wind dc: "#74c6f2" + offwind-float: "#b5e2fa" + offshore wind (Float): "#b5e2fa" + offshore wind float: "#b5e2fa" # water hydro: '#298c81' hydro reservoir: '#298c81' diff --git a/config/test/config.electricity.yaml b/config/test/config.electricity.yaml index 579644157..979453ccd 100644 --- a/config/test/config.electricity.yaml +++ b/config/test/config.electricity.yaml @@ -32,7 +32,7 @@ electricity: Store: [H2] Link: [H2 pipeline] - renewable_carriers: [solar, onwind, offwind-ac, offwind-dc] + renewable_carriers: [solar, onwind, offwind-ac, offwind-dc, offwind-float] atlite: @@ -53,6 +53,10 @@ renewable: offwind-dc: cutout: be-03-2013-era5 max_depth: false + offwind-float: + cutout: be-03-2013-era5 + max_depth: false + min_depth: false solar: cutout: be-03-2013-era5 diff --git a/config/test/config.myopic.yaml b/config/test/config.myopic.yaml index 5abae36d0..a9335046d 100644 --- a/config/test/config.myopic.yaml +++ b/config/test/config.myopic.yaml @@ -42,7 +42,7 @@ electricity: Store: [H2] Link: [H2 pipeline] - renewable_carriers: [solar, onwind, offwind-ac, offwind-dc] + renewable_carriers: [solar, onwind, offwind-ac, offwind-dc, offwind-float] atlite: default_cutout: be-03-2013-era5 @@ -62,6 +62,10 @@ renewable: offwind-dc: cutout: be-03-2013-era5 max_depth: false + offwind-float: + cutout: be-03-2013-era5 + max_depth: false + min_depth: false solar: cutout: be-03-2013-era5 diff --git a/config/test/config.overnight.yaml b/config/test/config.overnight.yaml index 7fb53e427..b02c0449c 100644 --- a/config/test/config.overnight.yaml +++ b/config/test/config.overnight.yaml @@ -36,7 +36,7 @@ electricity: Store: [H2] Link: [H2 pipeline] - renewable_carriers: [solar, onwind, offwind-ac, offwind-dc] + renewable_carriers: [solar, onwind, offwind-ac, offwind-dc, offwind-float] atlite: default_cutout: be-03-2013-era5 @@ -56,6 +56,10 @@ renewable: offwind-dc: cutout: be-03-2013-era5 max_depth: false + offwind-float: + cutout: be-03-2013-era5 + max_depth: false + min_depth: false solar: cutout: be-03-2013-era5 diff --git a/config/test/config.perfect.yaml b/config/test/config.perfect.yaml index 5d77c9c51..7fbfb6306 100644 --- a/config/test/config.perfect.yaml +++ b/config/test/config.perfect.yaml @@ -39,7 +39,7 @@ electricity: Store: [H2] Link: [H2 pipeline] - renewable_carriers: [solar, onwind, offwind-ac, offwind-dc] + renewable_carriers: [solar, onwind, offwind-ac, offwind-dc, offwind-float] sector: min_part_load_fischer_tropsch: 0 @@ -63,6 +63,10 @@ renewable: offwind-dc: cutout: be-03-2013-era5 max_depth: false + offwind-float: + cutout: be-03-2013-era5 + max_depth: false + min_depth: false solar: cutout: be-03-2013-era5 diff --git a/doc/configtables/electricity.csv b/doc/configtables/electricity.csv index 22a22d57c..fd160a45a 100644 --- a/doc/configtables/electricity.csv +++ b/doc/configtables/electricity.csv @@ -28,14 +28,14 @@ everywhere_powerplants,--,"Any subset of {nuclear, oil, OCGT, CCGT, coal, lignit ,,, conventional_carriers,--,"Any subset of {nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass}","List of conventional power plants to include in the model from ``resources/powerplants.csv``. If an included carrier is also listed in ``extendable_carriers``, the capacity is taken as a lower bound." ,,, -renewable_carriers,--,"Any subset of {solar, onwind, offwind-ac, offwind-dc, hydro}",List of renewable generators to include in the model. +renewable_carriers,--,"Any subset of {solar, onwind, offwind-ac, offwind-dc, offwind-float, hydro}",List of renewable generators to include in the model. estimate_renewable_capacities,,, -- enable,,bool,Activate routine to estimate renewable capacities -- from_opsd,--,bool,Add renewable capacities from `OPSD database `_. The value is depreciated but still can be used. -- year,--,bool,Renewable capacities are based on existing capacities reported by IRENA (IRENASTAT) for the specified year -- expansion_limit,--,float or false,"Artificially limit maximum IRENA capacities to a factor. For example, an ``expansion_limit: 1.1`` means 110% of capacities . If false are chosen, the estimated renewable potentials determine by the workflow are used." -- technology_mapping,,,Mapping between PyPSA-Eur and powerplantmatching technology names --- -- Offshore,--,"Any subset of {offwind-ac, offwind-dc}","List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) onshore technology." +-- -- Offshore,--,"Any subset of {offwind-ac, offwind-dc, offwind-float}","List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) onshore technology." -- -- Offshore,--,{onwind},"List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) offshore technology." -- -- PV,--,{solar},"List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) PV technology." autarky,,, diff --git a/doc/configuration.rst b/doc/configuration.rst index d531ee66a..a6917ecab 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -31,7 +31,7 @@ Top-level configuration .. _run_cf: ``run`` -======= +============= It is common conduct to analyse energy system optimisation models for **multiple scenarios** for a variety of reasons, e.g. assessing their sensitivity towards changing the temporal and/or geographical resolution or investigating how @@ -265,7 +265,7 @@ Define and specify the ``atlite.Cutout`` used for calculating renewable potentia .. literalinclude:: ../config/config.default.yaml :language: yaml :start-at: offwind-dc: - :end-before: solar: + :end-before: offwind-float: .. csv-table:: :header-rows: 1 @@ -273,9 +273,25 @@ Define and specify the ``atlite.Cutout`` used for calculating renewable potentia :file: configtables/offwind-dc.csv .. note:: - both ``offwind-ac`` and ``offwind-dc`` have the same assumption on + Both ``offwind-ac`` and ``offwind-dc`` have the same assumption on ``capacity_per_sqkm`` and ``correction_factor``. +``offwind-float`` +--------------- + +.. literalinclude:: ../config/config.default.yaml + :language: yaml + :start-at: offwind-float: + :end-before: solar: + +.. csv-table:: + :header-rows: 1 + :widths: 22,7,22,33 + :file: configtables/offwind-float.csv + +.. note:: + ``offwind-ac``, ``offwind-dc`` , ``offwind-float`` have the same assumption on + ``capacity_per_sqkm`` and ``correction_factor``. ``solar`` --------------- diff --git a/doc/release_notes.rst b/doc/release_notes.rst index e80a49c84..5a8161486 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -9,6 +9,8 @@ Release Notes Upcoming Release ================ +* Add floating wind technology for water depths below 60m + * Group existing capacities to the earlier grouping_year for consistency with optimized capacities. * Update data bundle: diff --git a/doc/wildcards.rst b/doc/wildcards.rst index 1fd1646f8..16681e3d7 100644 --- a/doc/wildcards.rst +++ b/doc/wildcards.rst @@ -35,8 +35,8 @@ The ``{technology}`` wildcard The ``{technology}`` wildcard specifies for which renewable energy technology to produce availability time series and potentials using the rule :mod:`build_renewable_profiles`. -It can take the values ``onwind``, ``offwind-ac``, ``offwind-dc``, and ``solar`` but **not** ``hydro`` -(since hydroelectric plant profiles are created by a different rule). +It can take the values ``onwind``, ``offwind-ac``, ``offwind-dc``, ``offwind-float``, and ``solar`` but **not** ``hydro`` +(since hydroelectric plant profiles are created by a different rule)`` .. _simpl: diff --git a/rules/build_electricity.smk b/rules/build_electricity.smk index 0c4c4b015..8b06f915d 100644 --- a/rules/build_electricity.smk +++ b/rules/build_electricity.smk @@ -248,7 +248,10 @@ rule build_renewable_profiles: gebco=ancient( lambda w: ( "data/bundle/gebco/GEBCO_2014_2D.nc" - if config_provider("renewable", w.technology)(w).get("max_depth") + if ( + config_provider("renewable", w.technology)(w).get("max_depth") + or config_provider("renewable", w.technology)(w).get("min_depth") + ) else [] ) ), diff --git a/rules/build_sector.smk b/rules/build_sector.smk index bc7cfd427..c2ca80c36 100644 --- a/rules/build_sector.smk +++ b/rules/build_sector.smk @@ -862,7 +862,7 @@ rule build_existing_heating_distribution: def input_profile_offwind(w): return { f"profile_{tech}": resources(f"profile_{tech}.nc") - for tech in ["offwind-ac", "offwind-dc"] + for tech in ["offwind-ac", "offwind-dc", "offwind-float"] if (tech in config_provider("electricity", "renewable_carriers")(w)) } diff --git a/scripts/build_renewable_profiles.py b/scripts/build_renewable_profiles.py index 43297e1da..0aef89bc0 100644 --- a/scripts/build_renewable_profiles.py +++ b/scripts/build_renewable_profiles.py @@ -26,7 +26,7 @@ renewable: {technology}: - cutout: corine: luisa: grid_codes: distance: natura: max_depth: + cutout: corine: luisa: grid_codes: distance: natura: max_depth: min_depth: max_shore_distance: min_shore_distance: capacity_per_sqkm: correction_factor: min_p_max_pu: clip_p_max_pu: resource: @@ -284,6 +284,12 @@ func = functools.partial(np.greater, -params["max_depth"]) excluder.add_raster(snakemake.input.gebco, codes=func, crs=4326, nodata=-1000) + if params.get("min_depth"): + func = functools.partial(np.greater, -params["min_depth"]) + excluder.add_raster( + snakemake.input.gebco, codes=func, crs=4326, nodata=-1000, invert=True + ) + if "min_shore_distance" in params: buffer = params["min_shore_distance"] excluder.add_geometry(snakemake.input.country_shapes, buffer=buffer) diff --git a/scripts/plot_summary.py b/scripts/plot_summary.py index bfe9995fe..8d983ce96 100644 --- a/scripts/plot_summary.py +++ b/scripts/plot_summary.py @@ -60,6 +60,7 @@ def rename_techs(label): "offwind": "offshore wind", "offwind-ac": "offshore wind (AC)", "offwind-dc": "offshore wind (DC)", + "offwind-float": "offshore wind (Float)", "onwind": "onshore wind", "ror": "hydroelectricity", "hydro": "hydroelectricity", diff --git a/scripts/solve_network.py b/scripts/solve_network.py index dbde8813a..9a6384b5c 100644 --- a/scripts/solve_network.py +++ b/scripts/solve_network.py @@ -123,7 +123,7 @@ def check_p_min_p_max(p_nom_max): def _add_land_use_constraint(n): # warning: this will miss existing offwind which is not classed AC-DC and has carrier 'offwind' - for carrier in ["solar", "onwind", "offwind-ac", "offwind-dc"]: + for carrier in ["solar", "onwind", "offwind-ac", "offwind-dc", "offwind-float"]: extendable_i = (n.generators.carrier == carrier) & n.generators.p_nom_extendable n.generators.loc[extendable_i, "p_nom_min"] = 0 @@ -158,7 +158,7 @@ def _add_land_use_constraint_m(n, planning_horizons, config): grouping_years = config["existing_capacities"]["grouping_years_power"] current_horizon = snakemake.wildcards.planning_horizons - for carrier in ["solar", "onwind", "offwind-ac", "offwind-dc"]: + for carrier in ["solar", "onwind", "offwind-ac", "offwind-dc", "offwind-float"]: extendable_i = (n.generators.carrier == carrier) & n.generators.p_nom_extendable n.generators.loc[extendable_i, "p_nom_min"] = 0