Skip to content

Commit

Permalink
attach_GEM_renewables: attach to correct resource class
Browse files Browse the repository at this point in the history
  • Loading branch information
fneum committed Jan 6, 2025
1 parent b9ae6b0 commit 454f473
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 20 deletions.
6 changes: 3 additions & 3 deletions config/config.default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ electricity:
year: 2020
expansion_limit: false
technology_mapping:
Offshore: [offwind-ac, offwind-dc, offwind-float]
Onshore: [onwind]
PV: [solar]
Offshore: offwind-ac
Onshore: onwind
PV: solar

autarky:
enable: false
Expand Down
6 changes: 3 additions & 3 deletions doc/configtables/electricity.csv
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ estimate_renewable_capacities,,,
-- 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, offwind-float}","List of PyPSA-Eur carriers that is considered as (IRENA, GEM) onshore technology."
-- -- Offshore,--,{onwind},"List of PyPSA-Eur carriers that is considered as (IRENA, GEM) offshore technology."
-- -- PV,--,{solar},"List of PyPSA-Eur carriers that is considered as (IRENA, GEM) PV technology."
-- -- Offshore,--,"{onwind}","PyPSA-Eur carrier that is considered for existing onshore wind capacities (IRENA, GEM)."
-- -- Offshore,--,"Any of {offwind-ac, offwind-dc, offwind-float}","PyPSA-Eur carrier that is considered for existing offshore wind technology (IRENA, GEM)."
-- -- PV,--,{solar},"PyPSA-Eur carrier that is considered for existing solar PV capacities (IRENA, GEM)."
autarky,,,
-- enable,bool,true or false,Require each node to be autarkic by removing all lines and links.
-- by_country,bool,true or false,Require each country to be autarkic by removing all cross-border lines and links. ``electricity: autarky`` must be enabled.
8 changes: 8 additions & 0 deletions rules/build_electricity.smk
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,13 @@ def input_profile_tech(w):
}


def input_class_regions(w):
return {
f"class_regions_{tech}": resources(f"regions_by_class_{{clusters}}_{tech}.geojson")
for tech in config_provider("electricity", "renewable_carriers")(w)
}


def input_conventional(w):
return {
f"conventional_{carrier}_{attr}": fn
Expand Down Expand Up @@ -679,6 +686,7 @@ rule add_electricity:
exclude_carriers=config_provider("clustering", "exclude_carriers"),
input:
unpack(input_profile_tech),
unpack(input_class_regions),
unpack(input_conventional),
base_network=resources("networks/base_s_{clusters}.nc"),
tech_costs=lambda w: resources(
Expand Down
28 changes: 14 additions & 14 deletions scripts/add_electricity.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@

import numpy as np
import pandas as pd
import geopandas as gpd
import powerplantmatching as pm
import pypsa
import xarray as xr
Expand All @@ -126,7 +127,6 @@
set_scenario_config,
update_p_nom_max,
)
from powerplantmatching.export import map_country_bus
from pypsa.clustering.spatial import DEFAULT_ONE_PORT_STRATEGIES, normed_or_uniform

idx = pd.IndexSlice
Expand Down Expand Up @@ -771,29 +771,29 @@ def attach_GEM_renewables(n: pypsa.Network, tech_map: dict[str, list[str]]) -> N
Returns:
- None
"""
tech_string = ", ".join(sum(tech_map.values(), []))
tech_string = ", ".join(tech_map.values())
logger.info(f"Using GEM renewable capacities for carriers {tech_string}.")

df = pm.data.GEM().powerplant.convert_country_to_alpha2()
technology_b = ~df.Technology.isin(["Onshore", "Offshore"])
df["Fueltype"] = df.Fueltype.where(technology_b, df.Technology).replace(
{"Solar": "PV"}
)
df = df.query("Fueltype in @tech_map")
df = df.dropna(subset=["lat", "lon"])

for fueltype, carriers in tech_map.items():
gens = n.generators[lambda df: df.carrier.isin(carriers)]
buses = n.buses.loc[gens.bus.unique()]
gens_per_bus = gens.groupby("bus").p_nom.count()
for fueltype, carrier in tech_map.items():

# assuming equal distribution of capacities per generator at each bus
caps = map_country_bus(df.query("Fueltype == @fueltype"), buses)
caps = caps.groupby(["bus"]).Capacity.sum()
caps = caps / gens_per_bus.reindex(caps.index, fill_value=1)
fn = snakemake.input.get(f"class_regions_{carrier}")
class_regions = gpd.read_file(fn)

n.generators.update({"p_nom": gens.bus.map(caps).dropna()})
n.generators.update({"p_nom_min": gens.bus.map(caps).dropna()})
df_fueltype = df.query("Fueltype == @fueltype")
geometry = gpd.points_from_xy(df_fueltype.lon, df_fueltype.lat)
caps = gpd.GeoDataFrame(df_fueltype, geometry=geometry, crs=4326)
caps = caps.sjoin(class_regions)
caps = caps.groupby(["bus", "bin"]).Capacity.sum()
caps.index = caps.index.map(flatten) + " " + carrier

n.generators.update({"p_nom": caps.dropna()})
n.generators.update({"p_nom_min": caps.dropna()})


def estimate_renewable_capacities(
Expand Down

0 comments on commit 454f473

Please sign in to comment.