diff --git a/config/plotting.default.yaml b/config/plotting.default.yaml index a2d7405123..6683f97e47 100644 --- a/config/plotting.default.yaml +++ b/config/plotting.default.yaml @@ -75,6 +75,10 @@ plotting: - offwind-dc - offwind-ac - offwind-float + - wave-shallow + - wave-nearshore + - wave-farshore + - offsolar - ror - hydro - PHS @@ -374,6 +378,10 @@ plotting: offwind-dc: "Offshore Wind (DC)" offwind-float: "Offshore Wind (Floating)" onwind: "Onshore Wind" + wave-shallow: "WEC Shallow" + wave-nearshore: "WEC Nearshore" + wave-farshore: "WEC Farshore" + offsolar: "Offshore Solar (Floating)" solar: "Solar" PHS: "Pumped Hydro Storage" hydro: "Reservoir & Dam" @@ -406,6 +414,10 @@ plotting: offwind-float: "#b5e2fa" offshore wind (Float): "#b5e2fa" offshore wind float: "#b5e2fa" + # wave + wave-shallow: "#216406" + wave-nearshore: "#24961a" + wave-farshore: "#4ce766" # water hydro: '#298c81' hydro reservoir: '#298c81' @@ -418,6 +430,7 @@ plotting: solar: "#f9d002" solar PV: "#f9d002" solar-hsat: "#fdb915" + offsolar: "#f2620f" solar thermal: '#ffbf2b' residential rural solar thermal: '#f1c069' services rural solar thermal: '#eabf61' diff --git a/config/test/config.electricity.yaml b/config/test/config.electricity.yaml index 7e13435c5f..08f91e70b8 100644 --- a/config/test/config.electricity.yaml +++ b/config/test/config.electricity.yaml @@ -29,12 +29,12 @@ electricity: co2limit: 100.e+6 extendable_carriers: - Generator: [solar, solar-hsat, onwind, offwind-ac, offwind-dc, offwind-float, OCGT, CCGT, nuclear] + Generator: [solar, solar-hsat, onwind, offwind-ac, offwind-dc, offwind-float, OCGT, CCGT, nuclear, wave-farshore, wave-nearshore, wave-shallow, offsolar] StorageUnit: [battery] Store: [H2] Link: [H2 pipeline] - renewable_carriers: [solar, solar-hsat, onwind, offwind-ac, offwind-dc, offwind-float] + renewable_carriers: [solar, solar-hsat, onwind, offwind-ac, offwind-dc, offwind-float, wave-farshore, wave-nearshore, wave-shallow, offsolar] estimate_renewable_capacities: enable: true from_powerplantmatching: true @@ -62,6 +62,17 @@ renewable: offwind-float: max_depth: false min_depth: false + wave-farshore: + max_depth: false + min_depth: false + wave-nearshore: + max_depth: false + min_depth: false + wave-shallow: + max_depth: false + offsolar: + max_depth: false + min_depth: false clustering: exclude_carriers: ["OCGT", "offwind-ac", "coal"] diff --git a/pixi.toml b/pixi.toml index 0b67610ed6..dc95109684 100644 --- a/pixi.toml +++ b/pixi.toml @@ -176,4 +176,4 @@ pytest = ">=8.4.2" [environments] doc = { features = ["doc"], no-default-feature = true } -test = ["test"] +test = ["test"] \ No newline at end of file diff --git a/scripts/add_electricity.py b/scripts/add_electricity.py index 84fd226dfd..abe18bd1b0 100755 --- a/scripts/add_electricity.py +++ b/scripts/add_electricity.py @@ -515,7 +515,7 @@ def attach_wind_and_solar( ds = ds.stack(bus_bin=["bus", "bin"]) supcar = car.split("-", 2)[0] - if supcar == "offwind": + if supcar == {"offwind", "wave", "offsolar"}: distance = ds["average_distance"].to_pandas() distance.index = distance.index.map(flatten) submarine_cost = costs.at[car + "-connection-submarine", "capital_cost"] @@ -528,21 +528,22 @@ def attach_wind_and_solar( # Take 'offwind-float' capital cost for 'float', and 'offwind' capital cost for the rest ('ac' and 'dc') midcar = car.split("-", 2)[1] - if midcar == "float": + if supcar == "offwind" and midcar != "float": capital_cost = ( - costs.at[car, "capital_cost"] + costs.at["offwind", "capital_cost"] + costs.at[car + "-station", "capital_cost"] + connection_cost ) else: capital_cost = ( - costs.at["offwind", "capital_cost"] + costs.at[car, "capital_cost"] + costs.at[car + "-station", "capital_cost"] + connection_cost ) logger.info( f"Added connection cost of {connection_cost.min():0.0f}-{connection_cost.max():0.0f} Eur/MW/a to {car}" ) + else: capital_cost = costs.at[car, "capital_cost"] diff --git a/scripts/build_renewable_profiles.py b/scripts/build_renewable_profiles.py index 0ea3119dc8..16df460a5a 100644 --- a/scripts/build_renewable_profiles.py +++ b/scripts/build_renewable_profiles.py @@ -128,7 +128,7 @@ resource = params["resource"] # pv panel params / wind turbine params resource["show_progress"] = not noprogress - tech = next(t for t in ["panel", "turbine"] if t in resource) + tech = next(t for t in ["panel", "turbine", "converter"] if t in resource) models = resource[tech] if not isinstance(models, dict): models = {0: models} @@ -151,7 +151,11 @@ regions = gpd.read_file(snakemake.input.distance_regions) # do not pull up, set_index does not work if geo dataframe is empty regions = regions.set_index("name").rename_axis("bus") - if snakemake.wildcards.technology.startswith("offwind"): + if ( + snakemake.wildcards.technology.startswith("offwind") + or snakemake.wildcards.technology.startswith("wave") + or snakemake.wildcards.technology.startswith("offsolar") + ): # for offshore regions, the shortest distance to the shoreline is used offshore_regions = availability.coords["bus"].values regions = regions.loc[offshore_regions] diff --git a/scripts/plot_summary.py b/scripts/plot_summary.py index 8cda4a6f02..34d2681f7f 100644 --- a/scripts/plot_summary.py +++ b/scripts/plot_summary.py @@ -19,7 +19,6 @@ # consolidate and rename - preferred_order = pd.Index( [ "transmission lines", @@ -33,10 +32,15 @@ "offshore wind", "offshore wind (AC)", "offshore wind (DC)", + "offshore floating wind", + "wave farshore", + "wave nearshore", + "wave shallow", "solar PV", "solar thermal", "solar rooftop", "solar", + "floating solar", "building retrofitting", "ground heat pump", "air heat pump", diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index d9434ef76e..605574d11c 100755 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -355,7 +355,7 @@ def add_lifetime_wind_solar(n, costs): """ Add lifetime for solar and wind generators. """ - for carrier in ["solar", "onwind", "offwind"]: + for carrier in ["solar", "onwind", "offwind", "wave", "offsolar"]: gen_i = n.generators.index.str.contains(carrier) n.generators.loc[gen_i, "lifetime"] = costs.at[carrier, "lifetime"] @@ -492,15 +492,15 @@ def update_wind_solar_costs( # Take 'offwind-float' capital cost for 'float', and 'offwind' capital cost for the rest ('ac' and 'dc') midtech = tech.split("-", 2)[1] - if midtech == "float": + if tech == "offwind" and midtech != "float": capital_cost = ( - costs.at[tech, "capital_cost"] + costs.at["offwind", "capital_cost"] + costs.at[tech + "-station", "capital_cost"] + connection_cost ) else: capital_cost = ( - costs.at["offwind", "capital_cost"] + costs.at[tech, "capital_cost"] + costs.at[tech + "-station", "capital_cost"] + connection_cost ) diff --git a/scripts/solve_network.py b/scripts/solve_network.py index 4b6429b47c..f0b43f7819 100644 --- a/scripts/solve_network.py +++ b/scripts/solve_network.py @@ -165,6 +165,10 @@ def add_land_use_constraint(n: pypsa.Network, planning_horizons: str) -> None: "offwind-ac", "offwind-dc", "offwind-float", + "offsolar", + "wave-shallow", + "wave-nearshore", + "wave-farshore", ]: ext_i = (n.generators.carrier == carrier) & ~n.generators.p_nom_extendable grouper = n.generators.loc[ext_i].index.str.replace( @@ -1244,6 +1248,7 @@ def extra_functionality( """ config = n.config constraints = config["solving"].get("constraints", {}) + if constraints["BAU"] and n.generators.p_nom_extendable.any(): add_BAU_constraints(n, config) if constraints["SAFE"] and n.generators.p_nom_extendable.any(): @@ -1258,9 +1263,9 @@ def extra_functionality( if EQ_o := constraints["EQ"]: add_EQ_constraints(n, EQ_o.replace("EQ", "")) - if {"solar-hsat", "solar"}.issubset( + if {"solar-hsat", "solar", "offsolar"}.issubset( config["electricity"]["renewable_carriers"] - ) and {"solar-hsat", "solar"}.issubset( + ) and {"solar-hsat", "solar", "offsolar"}.issubset( config["electricity"]["extendable_carriers"]["Generator"] ): add_solar_potential_constraints(n, config)