Skip to content

Commit

Permalink
Merge pull request #248 from pypsa-meets-earth/fix_bm_potentials
Browse files Browse the repository at this point in the history
Fix biomass potentials
  • Loading branch information
hazemakhalek authored Dec 4, 2023
2 parents 8d13969 + 17cfcbb commit 18f7a3a
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 69 deletions.
1 change: 0 additions & 1 deletion Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ rule prepare_sector_network:
gshp_cop="resources/demand/heat/gshp_cop_{demand}_s{simpl}_{clusters}_{planning_horizons}.csv",
solar_thermal="resources/demand/heat/solar_thermal_{demand}_s{simpl}_{clusters}_{planning_horizons}.csv",
district_heat_share="resources/demand/heat/district_heat_share_{demand}_s{simpl}_{clusters}_{planning_horizons}.csv",
biomass_potentials="data/temp_hard_coded/biomass_potentials_s_37.csv",
biomass_transport_costs="data/temp_hard_coded/biomass_transport_costs.csv",
shapes_path=pypsaearth(
"resources/bus_regions/regions_onshore_elec_s{simpl}_{clusters}.geojson"
Expand Down
2 changes: 2 additions & 0 deletions config.default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ sector:
transport_internal_combustion_efficiency: 0.3

biomass_transport: true # biomass transport between nodes
solid_biomass_potential: 2 # TWh/a, Potential of whole modelled area
biogas_potential: 0.5 # TWh/a, Potential of whole modelled area

efficiency_heat_oil_to_elec: 0.9
efficiency_heat_biomass_to_elec: 0.9
Expand Down
31 changes: 20 additions & 11 deletions config.pypsa-earth.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: CC0-1.0

version: 0.2.2
version: 0.2.3
tutorial: false

logging:
Expand All @@ -17,7 +17,7 @@ enable:
retrieve_cost_data: true # true: retrieves cost data from technology data and saves in resources/costs.csv, false: uses cost data in data/costs.csv
download_osm_data: true # If 'true', OpenStreetMap data will be downloaded for the above given countries
build_natura_raster: true # If True, than an exclusion raster will be build
build_cutout: true
build_cutout: false
# If "build_cutout" : true, then environmental data is extracted according to `snapshots` date range and `countries`
# requires cds API key https://cds.climate.copernicus.eu/api-how-to
# More information https://atlite.readthedocs.io/en/latest/introduction.html#datasets
Expand Down Expand Up @@ -61,7 +61,7 @@ cluster_options:
algorithm: kmeans # choose from: [hac, kmeans]
feature: solar+onwind-time # only for hac. choose from: [solar+onwind-time, solar+onwind-cap, solar-time, solar-cap, solar+offwind-cap] etc.
exclude_carriers: []
remove_stubs: false
remove_stubs: true
remove_stubs_across_borders: true
p_threshold_drop_isolated: 20 # [MW] isolated buses are being discarded if bus mean power is below the specified threshold
p_threshold_merge_isolated: 300 # [MW] isolated buses are being merged into a single isolated bus if bus mean power is below the specified threshold
Expand All @@ -85,22 +85,28 @@ cluster_options:
efficiency: mean

build_shape_options:
gadm_layer_id: 2 # GADM level area used for the gadm_shapes. Codes are country-dependent but roughly: 0: country, 1: region/county-like, 2: municipality-like
gadm_layer_id: 1 # GADM level area used for the gadm_shapes. Codes are country-dependent but roughly: 0: country, 1: region/county-like, 2: municipality-like
update_file: false # When true, all the input files are downloaded again and replace the existing files
out_logging: true # When true, logging is printed to console
year: 2020 # reference year used to derive shapes, info on population and info on GDP
nprocesses: 5 # number of processes to be used in build_shapes
nprocesses: 3 # number of processes to be used in build_shapes
nchunks: 3 # number of data chuncks for build_shapes. If not specified or smaller than nprocesses, specified as nprocesses
worldpop_method: "standard" # "standard" pulls from web 1kmx1km raster, "api" pulls from API 100mx100m raster, false (not "false") no pop addition to shape which is useful when generating only cutout
gdp_method: "standard" # "standard" pulls from web 1x1km raster, false (not "false") no gdp addition to shape which useful when generating only cutout
contended_flag: "set_by_country" # "set_by_country" assigns the contended areas to the countries according to the GADM database, "drop" drops these contended areas from the model

clean_osm_data_options: # osm = OpenStreetMap
names_by_shapes: true # Set the country name based on the extended country shapes
threshold_voltage: 35000 # [V] assets below that voltage threshold will not be used (cable, line, generator, etc.)
threshold_voltage: 51000 # [V] assets below that voltage threshold will not be used (cable, line, generator, etc.)
tag_substation: "transmission" # Filters only substations with 'transmission' tag, ('distribution' also available)
add_line_endings: true # When "True", then line endings are added to the dataset of the substations
generator_name_method: OSM # Methodology to specify the name to the generator. Options: OSM (name as by OSM dataset), closest_city (name by the closest city)
use_custom_lines: "OSM_only" # Use OSM (OSM_only), customized (custom_only), or both data sets (add_custom)
path_custom_lines: false # If exists, provide the specific absolute path of the custom file e.g. (...\data\custom_lines.geojson)
use_custom_substations: "OSM_only" # Use OSM (OSM_only), customized (custom_only), or both data sets (add_custom)
path_custom_substations: false # If exists, provide the specific absolute path of the custom file e.g. (...\data\custom_substations.geojson)
use_custom_cables: "OSM_only" # Use OSM (OSM_only), customized (custom_only), or both data sets (add_custom)
path_custom_cables: false # If exists, provide the specific absolute path of the custom file e.g. (...\data\custom_cables.geojson)

build_osm_network: # Options of the build_osm_network script; osm = OpenStreetMap
group_close_buses: true # When "True", close buses are merged and guarantee the voltage matching among line endings
Expand All @@ -110,8 +116,8 @@ build_osm_network: # Options of the build_osm_network script; osm = OpenStreetM
force_ac: false # When true, it forces all components (lines and substation) to be AC-only. To be used if DC assets create problem.

base_network:
min_voltage_substation_offshore: 35000 # [V] minimum voltage of the offshore substations
min_voltage_rebase_voltage: 35000 # [V] minimum voltage in base network
min_voltage_substation_offshore: 51000 # [V] minimum voltage of the offshore substations
min_voltage_rebase_voltage: 51000 # [V] minimum voltage in base network

load_options:
ssp: "ssp2-2.6" # shared socio-economic pathway (GDP and population growth) scenario to consider
Expand All @@ -125,7 +131,9 @@ electricity:
co2limit: 72.0e+6 # European default, 0.05 * 3.1e9*0.5, needs to be adjusted for Africa
co2base: 72.0e+6 # European default, adjustment to Africa necessary
agg_p_nom_limits: data/agg_p_nom_minmax.csv
hvdc_as_lines: true # should HVDC lines be modeled as `Line` or as `Link` component?
hvdc_as_lines: false # should HVDC lines be modeled as `Line` or as `Link` component?
automatic_emission: false
automatic_emission_base_year: 1990 # 1990 is taken as default. Any year from 1970 to 2018 can be selected.

operational_reserve: # like https://genxproject.github.io/GenX/dev/core/#Reserves
activate: false
Expand Down Expand Up @@ -293,6 +301,7 @@ renewable:
carriers: [ror, PHS, hydro]
PHS_max_hours: 6
hydro_max_hours: "energy_capacity_totals_by_country" # not active
hydro_max_hours_default: 6.0 # (optional, default 6) Default value of max_hours for hydro when NaN values are found
clip_min_inflow: 1.0
extendable: true
normalization:
Expand Down Expand Up @@ -341,8 +350,8 @@ monte_carlo:
# Key: add below the pypsa object for the monte_carlo sampling, "network" is only allowed for filtering!
# Value: currently supported format [l_bound, u_bound] or empty [], represent multiplication factors for the object
loads_t.p_set: [0.9, 1.1]
generators_t.p_max_pu.loc[:, n.generators.carrier == "wind"]: [0.9, 1.1]
generators_t.p_max_pu.loc[:, n.generators.carrier == "solar"]: [0.9, 1.1]
# generators_t.p_max_pu.loc[:, n.generators.carrier == "wind"]: [0.9, 1.1]
# generators_t.p_max_pu.loc[:, n.generators.carrier == "solar"]: [0.9, 1.1]


solving:
Expand Down
38 changes: 0 additions & 38 deletions data/temp_hard_coded/biomass_potentials_s_37.csv

This file was deleted.

36 changes: 17 additions & 19 deletions scripts/prepare_sector_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,18 +481,16 @@ def add_biomass(n, costs):
print("adding biomass")

# TODO get biomass potentials dataset and enable spatially resolved potentials
biomass_potentials = pd.read_csv(snakemake.input.biomass_potentials, index_col=0)

# if options["biomass_transport"]:
# biomass_potentials_spatial = biomass_potentials.rename(
# index=lambda x: x + " solid biomass"
# )
# else:
# biomass_potentials_spatial = biomass_potentials.sum()
biomass_potentials_spatial = biomass_potentials.sum() / len(biomass_potentials)
print(
"Solid Biomass potentials are not spatially resolved, the dummy value is the average solid Biomass of European countries"
)
# Get biomass and biogas potentials from config and convert from TWh to MWh
biomass_pot = snakemake.config["sector"]["solid_biomass_potential"] * 1e6 # MWh
biogas_pot = snakemake.config["sector"]["biogas_potential"] * 1e6 # MWh
print("Biomass and Biogas potential fetched from config")

# Convert from total to nodal potentials,
biomass_pot_spatial = biomass_pot / len(spatial.biomass.nodes)
biogas_pot_spatial = biogas_pot / len(spatial.gas.biogas)
print("Biomass potentials spatially resolved equally across all nodes")

n.add("Carrier", "biogas")
n.add("Carrier", "solid biomass")
Expand All @@ -513,19 +511,19 @@ def add_biomass(n, costs):
spatial.gas.biogas,
bus=spatial.gas.biogas,
carrier="biogas",
e_nom=biomass_potentials["biogas"].sum(),
e_nom=biogas_pot_spatial,
marginal_cost=costs.at["biogas", "fuel"],
e_initial=biomass_potentials["biogas"].sum(),
e_initial=biogas_pot_spatial,
)

n.madd(
"Store",
spatial.biomass.nodes,
bus=spatial.biomass.nodes,
carrier="solid biomass",
e_nom=biomass_potentials_spatial["solid biomass"],
e_nom=biomass_pot_spatial,
marginal_cost=costs.at["solid biomass", "fuel"],
e_initial=biomass_potentials_spatial["solid biomass"],
e_initial=biomass_pot_spatial,
)

biomass_gen = "biomass EOP"
Expand Down Expand Up @@ -2323,12 +2321,12 @@ def add_rail_transport(n, costs):
"prepare_sector_network",
simpl="",
clusters="4",
ll="c1",
opts="Co2L",
ll="c1.0",
opts="Co2L1.0",
planning_horizons="2030",
sopts="144H",
sopts="2000H",
discountrate="0.071",
demand="AB",
demand="DF",
)

# Load population layout
Expand Down
2 changes: 2 additions & 0 deletions test/config.test1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ sector:
industry_util_factor: 0.7

biomass_transport: true # biomass transport between nodes
solid_biomass_potential: 2 # TWh/a, Potential of whole modelled area
biogas_potential: 0.5 # TWh/a, Potential of whole modelled area
efficiency_heat_oil_to_elec: 0.9
efficiency_heat_biomass_to_elec: 0.9
efficiency_heat_gas_to_elec: 0.9
Expand Down

0 comments on commit 18f7a3a

Please sign in to comment.