4
.github/workflows/ci.yaml
vendored
@ -19,7 +19,7 @@ on:
|
||||
- cron: "0 5 * * TUE"
|
||||
|
||||
env:
|
||||
DATA_CACHE_NUMBER: 1
|
||||
DATA_CACHE_NUMBER: 2
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@ -31,7 +31,7 @@ jobs:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- macos-latest
|
||||
# - windows-latest
|
||||
- windows-latest
|
||||
inhouse:
|
||||
- stable
|
||||
- master
|
||||
|
16
.gitignore
vendored
@ -2,6 +2,8 @@
|
||||
#
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
master
|
||||
|
||||
.snakemake*
|
||||
.ipynb_checkpoints
|
||||
__pycache__
|
||||
@ -37,18 +39,16 @@ dconf
|
||||
/data/links_p_nom.csv
|
||||
/data/*totals.csv
|
||||
/data/biomass*
|
||||
/data/bundle-sector/emobility/
|
||||
/data/bundle-sector/eea*
|
||||
/data/bundle-sector/jrc*
|
||||
/data/bundle/emobility/
|
||||
/data/bundle/eea*
|
||||
/data/bundle/jrc*
|
||||
/data/heating/
|
||||
/data/bundle-sector/eurostat*
|
||||
/data/bundle/eurostat*
|
||||
/data/odyssee/
|
||||
/data/transport_data.csv
|
||||
/data/bundle-sector/switzerland*
|
||||
/data/.nfs*
|
||||
/data/bundle-sector/Industrial_Database.csv
|
||||
/data/retro/tabula-calculator-calcsetbuilding.csv
|
||||
/data/bundle-sector/nuts*
|
||||
/data/retro/*
|
||||
/data/bundle/nuts*
|
||||
data/gas_network/scigrid-gas/
|
||||
data/costs_*.csv
|
||||
|
||||
|
@ -5,7 +5,7 @@ exclude: "^LICENSES"
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.5.0
|
||||
rev: v4.6.0
|
||||
hooks:
|
||||
- id: check-merge-conflict
|
||||
- id: end-of-file-fixer
|
||||
@ -51,7 +51,7 @@ repos:
|
||||
|
||||
# Formatting with "black" coding style
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 24.3.0
|
||||
rev: 24.4.2
|
||||
hooks:
|
||||
# Format Python files
|
||||
- id: black
|
||||
@ -67,14 +67,14 @@ repos:
|
||||
|
||||
# Do YAML formatting (before the linter checks it for misses)
|
||||
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
|
||||
rev: v2.12.0
|
||||
rev: v2.13.0
|
||||
hooks:
|
||||
- id: pretty-format-yaml
|
||||
args: [--autofix, --indent, "2", --preserve-quotes]
|
||||
|
||||
# Format Snakemake rule / workflow files
|
||||
- repo: https://github.com/snakemake/snakefmt
|
||||
rev: v0.10.0
|
||||
rev: v0.10.2
|
||||
hooks:
|
||||
- id: snakefmt
|
||||
|
||||
@ -87,6 +87,6 @@ repos:
|
||||
|
||||
# Check for FSFE REUSE compliance (licensing)
|
||||
- repo: https://github.com/fsfe/reuse-tool
|
||||
rev: v3.0.1
|
||||
rev: v3.0.2
|
||||
hooks:
|
||||
- id: reuse
|
||||
|
@ -30,7 +30,3 @@ License: CC0-1.0
|
||||
Files: borg-it
|
||||
Copyright: 2017-2024 The PyPSA-Eur Authors
|
||||
License: CC0-1.0
|
||||
|
||||
Files: graphics/*
|
||||
Copyright: 2017-2024 The PyPSA-Eur Authors
|
||||
License: CC-BY-4.0
|
||||
|
@ -6,7 +6,7 @@ cff-version: 1.1.0
|
||||
message: "If you use this package, please cite it in the following way."
|
||||
title: "PyPSA-Eur: An open sector-coupled optimisation model of the European energy system"
|
||||
repository: https://github.com/pypsa/pypsa-eur
|
||||
version: 0.10.0
|
||||
version: 0.11.0
|
||||
license: MIT
|
||||
authors:
|
||||
- family-names: Brown
|
||||
|
@ -80,7 +80,7 @@ all greenhouse gas emitters except waste management and land use.
|
||||
This diagram gives an overview of the sectors and the links between
|
||||
them:
|
||||
|
||||
![sector diagram](graphics/multisector_figure.png)
|
||||
![sector diagram](doc/img/multisector_figure.png)
|
||||
|
||||
Each of these sectors is built up on the transmission network nodes
|
||||
from [PyPSA-Eur](https://github.com/PyPSA/pypsa-eur):
|
||||
|
10
Snakefile
@ -8,7 +8,7 @@ from os.path import normpath, exists
|
||||
from shutil import copyfile, move, rmtree
|
||||
from snakemake.utils import min_version
|
||||
|
||||
min_version("8.5")
|
||||
min_version("8.11")
|
||||
|
||||
from scripts._helpers import path_provider, copy_default_files, get_scenarios, get_rdir
|
||||
|
||||
@ -24,9 +24,11 @@ run = config["run"]
|
||||
scenarios = get_scenarios(run)
|
||||
RDIR = get_rdir(run)
|
||||
|
||||
logs = path_provider("logs/", RDIR, run["shared_resources"])
|
||||
benchmarks = path_provider("benchmarks/", RDIR, run["shared_resources"])
|
||||
resources = path_provider("resources/", RDIR, run["shared_resources"])
|
||||
shared_resources = run["shared_resources"]["policy"]
|
||||
exclude_from_shared = run["shared_resources"]["exclude"]
|
||||
logs = path_provider("logs/", RDIR, shared_resources, exclude_from_shared)
|
||||
benchmarks = path_provider("benchmarks/", RDIR, shared_resources, exclude_from_shared)
|
||||
resources = path_provider("resources/", RDIR, shared_resources, exclude_from_shared)
|
||||
|
||||
CDIR = "" if run["shared_cutouts"] else RDIR
|
||||
RESULTS = "results/" + RDIR
|
||||
|
@ -3,7 +3,7 @@
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#top-level-configuration
|
||||
version: 0.10.0
|
||||
version: 0.11.0
|
||||
tutorial: false
|
||||
|
||||
logging:
|
||||
@ -20,12 +20,15 @@ remote:
|
||||
|
||||
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#run
|
||||
run:
|
||||
prefix: ""
|
||||
name: ""
|
||||
scenarios:
|
||||
enable: false
|
||||
file: config/scenarios.yaml
|
||||
disable_progressbar: false
|
||||
shared_resources: false
|
||||
shared_resources:
|
||||
policy: false
|
||||
exclude: []
|
||||
shared_cutouts: true
|
||||
|
||||
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#foresight
|
||||
@ -37,17 +40,15 @@ scenario:
|
||||
simpl:
|
||||
- ''
|
||||
ll:
|
||||
- v1.5
|
||||
- vopt
|
||||
clusters:
|
||||
- 37
|
||||
- 128
|
||||
- 256
|
||||
- 512
|
||||
- 1024
|
||||
opts:
|
||||
- ''
|
||||
sector_opts:
|
||||
- Co2L0-3H-T-H-B-I-A-dist1
|
||||
- ''
|
||||
planning_horizons:
|
||||
# - 2020
|
||||
# - 2030
|
||||
@ -68,13 +69,9 @@ enable:
|
||||
retrieve: auto
|
||||
prepare_links_p_nom: false
|
||||
retrieve_databundle: true
|
||||
retrieve_sector_databundle: true
|
||||
retrieve_cost_data: true
|
||||
build_cutout: false
|
||||
retrieve_irena: false
|
||||
retrieve_cutout: true
|
||||
build_natura_raster: false
|
||||
retrieve_natura_raster: true
|
||||
custom_busmap: false
|
||||
drop_leap_day: true
|
||||
|
||||
@ -97,7 +94,6 @@ electricity:
|
||||
co2limit_enable: false
|
||||
co2limit: 7.75e+7
|
||||
co2base: 1.487e+9
|
||||
agg_p_nom_limits: data/agg_p_nom_minmax.csv
|
||||
|
||||
operational_reserve:
|
||||
activate: false
|
||||
@ -110,17 +106,17 @@ electricity:
|
||||
H2: 168
|
||||
|
||||
extendable_carriers:
|
||||
Generator: [solar, onwind, offwind-ac, offwind-dc, OCGT]
|
||||
Generator: [solar, solar-hsat, onwind, offwind-ac, offwind-dc, offwind-float, OCGT, CCGT]
|
||||
StorageUnit: [] # battery, H2
|
||||
Store: [battery, H2]
|
||||
Link: [] # H2 pipeline
|
||||
|
||||
powerplants_filter: (DateOut >= 2023 or DateOut != DateOut) and not (Country == 'Germany' and Fueltype == 'Nuclear')
|
||||
custom_powerplants: false
|
||||
everywhere_powerplants: [nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass]
|
||||
everywhere_powerplants: []
|
||||
|
||||
conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass]
|
||||
renewable_carriers: [solar, onwind, offwind-ac, offwind-dc, hydro]
|
||||
renewable_carriers: [solar, solar-hsat, onwind, offwind-ac, offwind-dc, offwind-float, hydro]
|
||||
|
||||
estimate_renewable_capacities:
|
||||
enable: true
|
||||
@ -128,7 +124,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]
|
||||
|
||||
@ -196,7 +192,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
|
||||
@ -212,10 +208,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:
|
||||
@ -231,6 +245,21 @@ renewable:
|
||||
natura: true
|
||||
excluder_resolution: 100
|
||||
clip_p_max_pu: 1.e-2
|
||||
solar-hsat:
|
||||
cutout: europe-2013-sarah
|
||||
resource:
|
||||
method: pv
|
||||
panel: CSi
|
||||
orientation:
|
||||
slope: 35.
|
||||
azimuth: 180.
|
||||
tracking: horizontal
|
||||
capacity_per_sqkm: 4.43 # 15% higher land usage acc. to NREL
|
||||
corine: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 26, 31, 32]
|
||||
luisa: false # [1111, 1121, 1122, 1123, 1130, 1210, 1221, 1222, 1230, 1241, 1242, 1310, 1320, 1330, 1410, 1421, 1422, 2110, 2120, 2130, 2210, 2220, 2230, 2310, 2410, 2420, 3210, 3320, 3330]
|
||||
natura: true
|
||||
excluder_resolution: 100
|
||||
clip_p_max_pu: 1.e-2
|
||||
hydro:
|
||||
cutout: europe-2013-era5
|
||||
carriers: [ror, PHS, hydro]
|
||||
@ -263,7 +292,7 @@ lines:
|
||||
max_extension: 20000 #MW
|
||||
length_factor: 1.25
|
||||
reconnect_crimea: true
|
||||
under_construction: 'zero' # 'zero': set capacity to zero, 'remove': remove, 'keep': with full capacity
|
||||
under_construction: 'keep' # 'zero': set capacity to zero, 'remove': remove, 'keep': with full capacity
|
||||
dynamic_line_rating:
|
||||
activate: false
|
||||
cutout: europe-2013-era5
|
||||
@ -309,6 +338,8 @@ pypsa_eur:
|
||||
- onwind
|
||||
- offwind-ac
|
||||
- offwind-dc
|
||||
- offwind-float
|
||||
- solar-hsat
|
||||
- solar
|
||||
- ror
|
||||
- nuclear
|
||||
@ -359,8 +390,8 @@ solar_thermal:
|
||||
|
||||
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#existing-capacities
|
||||
existing_capacities:
|
||||
grouping_years_power: [1960, 1965, 1970, 1975, 1980, 1985, 1990, 1995, 2000, 2005, 2010, 2015, 2020, 2025, 2030]
|
||||
grouping_years_heat: [1980, 1985, 1990, 1995, 2000, 2005, 2010, 2015, 2019] # these should not extend 2020
|
||||
grouping_years_power: [1895, 1920, 1950, 1955, 1960, 1965, 1970, 1975, 1980, 1985, 1990, 1995, 2000, 2005, 2010, 2015, 2020, 2025, 2030]
|
||||
grouping_years_heat: [1980, 1985, 1990, 1995, 2000, 2005, 2010, 2015, 2020] # heat grouping years >= baseyear will be ignored
|
||||
threshold_capacity: 10
|
||||
default_heating_lifetime: 20
|
||||
conventional_carriers:
|
||||
@ -401,7 +432,6 @@ sector:
|
||||
bev_availability: 0.5
|
||||
bev_energy: 0.05
|
||||
bev_charge_efficiency: 0.9
|
||||
bev_plug_to_wheel_efficiency: 0.2
|
||||
bev_charge_rate: 0.011
|
||||
bev_avail_max: 0.95
|
||||
bev_avail_mean: 0.8
|
||||
@ -430,8 +460,9 @@ sector:
|
||||
2040: 0.3
|
||||
2045: 0.15
|
||||
2050: 0
|
||||
transport_fuel_cell_efficiency: 0.5
|
||||
transport_internal_combustion_efficiency: 0.3
|
||||
transport_electric_efficiency: 53.19 # 1 MWh_el = 53.19*100 km
|
||||
transport_fuel_cell_efficiency: 30.003 # 1 MWh_H2 = 30.003*100 km
|
||||
transport_ice_efficiency: 16.0712 # 1 MWh_oil = 16.0712 * 100 km
|
||||
agriculture_machinery_electric_share: 0
|
||||
agriculture_machinery_oil_share: 1
|
||||
agriculture_machinery_fuel_efficiency: 0.7
|
||||
@ -515,7 +546,11 @@ sector:
|
||||
regional_coal_demand: false
|
||||
regional_co2_sequestration_potential:
|
||||
enable: false
|
||||
attribute: 'conservative estimate Mt'
|
||||
attribute:
|
||||
- conservative estimate Mt
|
||||
- conservative estimate GAS Mt
|
||||
- conservative estimate OIL Mt
|
||||
- conservative estimate aquifer Mt
|
||||
include_onshore: false
|
||||
min_size: 3
|
||||
max_size: 25
|
||||
@ -533,7 +568,7 @@ sector:
|
||||
- nearshore # within 50 km of sea
|
||||
# - offshore
|
||||
ammonia: false
|
||||
min_part_load_fischer_tropsch: 0.7
|
||||
min_part_load_fischer_tropsch: 0.5
|
||||
min_part_load_methanolisation: 0.3
|
||||
min_part_load_methanation: 0.3
|
||||
use_fischer_tropsch_waste_heat: true
|
||||
@ -556,6 +591,8 @@ sector:
|
||||
gas pipeline:
|
||||
efficiency_per_1000km: 1 #0.977
|
||||
compression_per_1000km: 0.01
|
||||
electricity distribution grid:
|
||||
efficiency_static: 0.97
|
||||
H2_network: true
|
||||
gas_network: false
|
||||
H2_retrofit: false
|
||||
@ -656,6 +693,9 @@ industry:
|
||||
2040: 0.12
|
||||
2045: 0.16
|
||||
2050: 0.20
|
||||
HVC_environment_sequestration_fraction: 0.
|
||||
waste_to_energy: false
|
||||
waste_to_energy_cc: false
|
||||
sector_ratios_fraction_future:
|
||||
2020: 0.0
|
||||
2025: 0.1
|
||||
@ -674,6 +714,7 @@ industry:
|
||||
methanol_production_today: 1.5
|
||||
MWh_elec_per_tMeOH: 0.167
|
||||
MWh_CH4_per_tMeOH: 10.25
|
||||
MWh_MeOH_per_tMeOH: 5.528
|
||||
hotmaps_locate_missing: false
|
||||
reference_year: 2015
|
||||
|
||||
@ -681,8 +722,7 @@ industry:
|
||||
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#costs
|
||||
costs:
|
||||
year: 2030
|
||||
version: v0.8.1
|
||||
rooftop_share: 0.14 # based on the potentials, assuming (0.1 kW/m2 and 10 m2/person)
|
||||
version: v0.9.0
|
||||
social_discountrate: 0.02
|
||||
fill_values:
|
||||
FOM: 0
|
||||
@ -754,11 +794,28 @@ solving:
|
||||
# io_api: "direct" # Increases performance but only supported for the highs and gurobi solvers
|
||||
# options that go into the optimize function
|
||||
track_iterations: false
|
||||
min_iterations: 4
|
||||
max_iterations: 6
|
||||
min_iterations: 2
|
||||
max_iterations: 3
|
||||
transmission_losses: 2
|
||||
linearized_unit_commitment: true
|
||||
horizon: 365
|
||||
post_discretization:
|
||||
enable: false
|
||||
line_unit_size: 1700
|
||||
line_threshold: 0.3
|
||||
link_unit_size:
|
||||
DC: 2000
|
||||
H2 pipeline: 1200
|
||||
gas pipeline: 1500
|
||||
link_threshold:
|
||||
DC: 0.3
|
||||
H2 pipeline: 0.3
|
||||
gas pipeline: 0.3
|
||||
|
||||
agg_p_nom_limits:
|
||||
agg_offwind: false
|
||||
include_existing: false
|
||||
file: data/agg_p_nom_minmax.csv
|
||||
|
||||
constraints:
|
||||
CCL: false
|
||||
@ -772,7 +829,7 @@ solving:
|
||||
|
||||
solver_options:
|
||||
highs-default:
|
||||
# refer to https://ergo-code.github.io/HiGHS/options/definitions.html#solver
|
||||
# refer to https://ergo-code.github.io/HiGHS/dev/options/definitions/
|
||||
threads: 4
|
||||
solver: "ipm"
|
||||
run_crossover: "off"
|
||||
@ -793,7 +850,6 @@ solving:
|
||||
PreDual: 0
|
||||
GURO_PAR_BARDENSETHRESH: 200
|
||||
gurobi-numeric-focus:
|
||||
name: gurobi
|
||||
NumericFocus: 3 # Favour numeric stability over speed
|
||||
method: 2 # barrier
|
||||
crossover: 0 # do not use crossover
|
||||
@ -805,7 +861,6 @@ solving:
|
||||
threads: 8
|
||||
Seed: 123
|
||||
gurobi-fallback: # Use gurobi defaults
|
||||
name: gurobi
|
||||
crossover: 0
|
||||
method: 2 # barrier
|
||||
BarHomogeneous: 1 # Use homogeneous barrier if standard does not converge
|
||||
@ -859,6 +914,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"
|
||||
@ -883,6 +939,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'
|
||||
@ -894,6 +953,7 @@ plotting:
|
||||
# solar
|
||||
solar: "#f9d002"
|
||||
solar PV: "#f9d002"
|
||||
solar-hsat: "#fdb915"
|
||||
solar thermal: '#ffbf2b'
|
||||
residential rural solar thermal: '#f1c069'
|
||||
services rural solar thermal: '#eabf61'
|
||||
@ -995,6 +1055,7 @@ plotting:
|
||||
BEV charger: '#baf238'
|
||||
V2G: '#e5ffa8'
|
||||
land transport EV: '#baf238'
|
||||
land transport demand: '#38baf2'
|
||||
Li ion: '#baf238'
|
||||
# hot water storage
|
||||
water tanks: '#e69487'
|
||||
@ -1099,6 +1160,7 @@ plotting:
|
||||
methanolisation: '#83d6d5'
|
||||
methanol: '#468c8b'
|
||||
shipping methanol: '#468c8b'
|
||||
industry methanol: '#468c8b'
|
||||
# co2
|
||||
CC: '#f29dae'
|
||||
CCS: '#f29dae'
|
||||
@ -1140,3 +1202,6 @@ plotting:
|
||||
DC-DC: "#8a1caf"
|
||||
DC link: "#8a1caf"
|
||||
load: "#dd2e23"
|
||||
waste CHP: '#e3d37d'
|
||||
waste CHP CC: '#e3d3ff'
|
||||
HVC to air: 'k'
|
||||
|
@ -5,7 +5,8 @@
|
||||
run:
|
||||
name: "entsoe-all"
|
||||
disable_progressbar: true
|
||||
shared_resources: false
|
||||
shared_resources:
|
||||
policy: false
|
||||
shared_cutouts: true
|
||||
|
||||
scenario:
|
||||
@ -38,6 +39,5 @@ lines:
|
||||
enable:
|
||||
retrieve: true
|
||||
retrieve_databundle: true
|
||||
retrieve_sector_databundle: false
|
||||
retrieve_cost_data: true
|
||||
retrieve_cutout: true
|
@ -8,14 +8,15 @@ tutorial: true
|
||||
run:
|
||||
name: "test-elec" # use this to keep track of runs with different settings
|
||||
disable_progressbar: true
|
||||
shared_resources: "test"
|
||||
shared_resources:
|
||||
policy: "test"
|
||||
shared_cutouts: true
|
||||
|
||||
scenario:
|
||||
clusters:
|
||||
- 5
|
||||
opts:
|
||||
- Co2L-24h
|
||||
- ''
|
||||
|
||||
countries: ['BE']
|
||||
|
||||
@ -24,6 +25,7 @@ snapshots:
|
||||
end: "2013-03-08"
|
||||
|
||||
electricity:
|
||||
co2limit_enable: true
|
||||
co2limit: 100.e+6
|
||||
|
||||
extendable_carriers:
|
||||
@ -32,7 +34,7 @@ electricity:
|
||||
Store: [H2]
|
||||
Link: [H2 pipeline]
|
||||
|
||||
renewable_carriers: [solar, onwind, offwind-ac, offwind-dc]
|
||||
renewable_carriers: [solar, solar-hsat, onwind, offwind-ac, offwind-dc, offwind-float]
|
||||
|
||||
|
||||
atlite:
|
||||
@ -53,12 +55,20 @@ 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
|
||||
solar-hsat:
|
||||
cutout: be-03-2013-era5
|
||||
|
||||
|
||||
clustering:
|
||||
exclude_carriers: ["OCGT", "offwind-ac", "coal"]
|
||||
temporal:
|
||||
resolution_elec: 24h
|
||||
|
||||
lines:
|
||||
dynamic_line_rating:
|
||||
|
@ -7,7 +7,8 @@ tutorial: true
|
||||
run:
|
||||
name: "test-sector-myopic"
|
||||
disable_progressbar: true
|
||||
shared_resources: "test"
|
||||
shared_resources:
|
||||
policy: "test"
|
||||
shared_cutouts: true
|
||||
|
||||
foresight: myopic
|
||||
@ -18,7 +19,7 @@ scenario:
|
||||
clusters:
|
||||
- 5
|
||||
sector_opts:
|
||||
- 24h-T-H-B-I-A-dist1
|
||||
- ''
|
||||
planning_horizons:
|
||||
- 2030
|
||||
- 2040
|
||||
@ -34,7 +35,6 @@ sector:
|
||||
central_heat_vent: true
|
||||
|
||||
electricity:
|
||||
co2limit: 100.e+6
|
||||
|
||||
extendable_carriers:
|
||||
Generator: [OCGT]
|
||||
@ -42,7 +42,10 @@ electricity:
|
||||
Store: [H2]
|
||||
Link: [H2 pipeline]
|
||||
|
||||
renewable_carriers: [solar, onwind, offwind-ac, offwind-dc]
|
||||
renewable_carriers: [solar, solar-hsat, onwind, offwind-ac, offwind-dc, offwind-float]
|
||||
|
||||
estimate_renewable_capacities:
|
||||
enable: false
|
||||
|
||||
atlite:
|
||||
default_cutout: be-03-2013-era5
|
||||
@ -62,8 +65,18 @@ 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
|
||||
solar-hsat:
|
||||
cutout: be-03-2013-era5
|
||||
|
||||
clustering:
|
||||
temporal:
|
||||
resolution_sector: 24h
|
||||
|
||||
industry:
|
||||
St_primary_fraction:
|
||||
|
@ -7,7 +7,8 @@ tutorial: true
|
||||
run:
|
||||
name: "test-sector-overnight"
|
||||
disable_progressbar: true
|
||||
shared_resources: "test"
|
||||
shared_resources:
|
||||
policy: "test"
|
||||
shared_cutouts: true
|
||||
|
||||
|
||||
@ -17,7 +18,7 @@ scenario:
|
||||
clusters:
|
||||
- 5
|
||||
sector_opts:
|
||||
- CO2L0-24h-T-H-B-I-A-dist1
|
||||
- ''
|
||||
planning_horizons:
|
||||
- 2030
|
||||
|
||||
@ -28,7 +29,6 @@ snapshots:
|
||||
end: "2013-03-08"
|
||||
|
||||
electricity:
|
||||
co2limit: 100.e+6
|
||||
|
||||
extendable_carriers:
|
||||
Generator: [OCGT]
|
||||
@ -36,7 +36,7 @@ electricity:
|
||||
Store: [H2]
|
||||
Link: [H2 pipeline]
|
||||
|
||||
renewable_carriers: [solar, onwind, offwind-ac, offwind-dc]
|
||||
renewable_carriers: [solar, solar-hsat, onwind, offwind-ac, offwind-dc, offwind-float]
|
||||
|
||||
atlite:
|
||||
default_cutout: be-03-2013-era5
|
||||
@ -56,13 +56,28 @@ 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
|
||||
solar-hsat:
|
||||
cutout: be-03-2013-era5
|
||||
|
||||
clustering:
|
||||
temporal:
|
||||
resolution_sector: 24h
|
||||
|
||||
sector:
|
||||
gas_network: true
|
||||
H2_retrofit: true
|
||||
|
||||
industry:
|
||||
HVC_environment_sequestration_fraction: 0.5
|
||||
waste_to_energy: true
|
||||
waste_to_energy_cc: true
|
||||
|
||||
solving:
|
||||
solver:
|
||||
name: glpk
|
||||
|
@ -7,7 +7,8 @@ tutorial: true
|
||||
run:
|
||||
name: "test-sector-perfect"
|
||||
disable_progressbar: true
|
||||
shared_resources: "test"
|
||||
shared_resources:
|
||||
policy: "test"
|
||||
shared_cutouts: true
|
||||
|
||||
foresight: perfect
|
||||
@ -18,7 +19,7 @@ scenario:
|
||||
clusters:
|
||||
- 5
|
||||
sector_opts:
|
||||
- 8760h-T-H-B-I-A-dist1
|
||||
- ''
|
||||
planning_horizons:
|
||||
- 2030
|
||||
- 2040
|
||||
@ -31,7 +32,6 @@ snapshots:
|
||||
end: "2013-03-08"
|
||||
|
||||
electricity:
|
||||
co2limit: 100.e+6
|
||||
|
||||
extendable_carriers:
|
||||
Generator: [OCGT]
|
||||
@ -39,7 +39,7 @@ electricity:
|
||||
Store: [H2]
|
||||
Link: [H2 pipeline]
|
||||
|
||||
renewable_carriers: [solar, onwind, offwind-ac, offwind-dc]
|
||||
renewable_carriers: [solar, solar-hsat, onwind, offwind-ac, offwind-dc, offwind-float]
|
||||
|
||||
sector:
|
||||
min_part_load_fischer_tropsch: 0
|
||||
@ -63,8 +63,18 @@ 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
|
||||
solar-hsat:
|
||||
cutout: be-03-2013-era5
|
||||
|
||||
clustering:
|
||||
temporal:
|
||||
resolution_sector: 8760h
|
||||
|
||||
industry:
|
||||
St_primary_fraction:
|
||||
|
@ -12,14 +12,15 @@ run:
|
||||
enable: true
|
||||
file: "config/test/scenarios.yaml"
|
||||
disable_progressbar: true
|
||||
shared_resources: base
|
||||
shared_resources:
|
||||
policy: base
|
||||
shared_cutouts: true
|
||||
|
||||
scenario:
|
||||
clusters:
|
||||
- 5
|
||||
opts:
|
||||
- Co2L-24H
|
||||
- ''
|
||||
|
||||
countries: ['BE']
|
||||
|
||||
|
@ -1,31 +1,33 @@
|
||||
country,carrier,min,max
|
||||
DE,onwind,0.1,
|
||||
DE,offwind-ac,0.1,
|
||||
DE,offwind-dc,0.1,
|
||||
DE,solar,0.2,
|
||||
LU,onwind,,
|
||||
LU,solar,,
|
||||
NL,onwind,,
|
||||
NL,offwind-ac,,
|
||||
NL,offwind-dc,,
|
||||
NL,solar,,
|
||||
GB,onwind,,
|
||||
GB,offwind-ac,,
|
||||
GB,offwind-dc,,
|
||||
GB,solar,,
|
||||
IE,onwind,,
|
||||
IE,offwind-ac,,
|
||||
IE,offwind-dc,,
|
||||
IE,solar,,
|
||||
FR,onwind,,
|
||||
FR,offwind-ac,,
|
||||
FR,offwind-dc,,
|
||||
FR,solar,,
|
||||
DK,onwind,,
|
||||
DK,offwind-ac,,
|
||||
DK,offwind-dc,,
|
||||
DK,solar,,
|
||||
BE,onwind,,
|
||||
BE,offwind-ac,,
|
||||
BE,offwind-dc,,
|
||||
BE,solar,,
|
||||
,,2030,2030,2040,2040,2050,2050
|
||||
,,min,max,min,max,min,max
|
||||
country,carrier,,,,,,
|
||||
DE,onwind,0.1,,0.1,,0.1,
|
||||
DE,offwind-ac,0.1,,0.1,,0.1,
|
||||
DE,offwind-dc,0.1,,0.1,,0.1,
|
||||
DE,solar,0.2,,0.2,,0.2,
|
||||
LU,onwind,,,,,,
|
||||
LU,solar,,,,,,
|
||||
NL,onwind,,,,,,
|
||||
NL,offwind-ac,,,,,,
|
||||
NL,offwind-dc,,,,,,
|
||||
NL,solar,,,,,,
|
||||
GB,onwind,,,,,,
|
||||
GB,offwind-ac,,,,,,
|
||||
GB,offwind-dc,,,,,,
|
||||
GB,solar,,,,,,
|
||||
IE,onwind,,,,,,
|
||||
IE,offwind-ac,,,,,,
|
||||
IE,offwind-dc,,,,,,
|
||||
IE,solar,,,,,,
|
||||
FR,onwind,,,,,,
|
||||
FR,offwind-ac,,,,,,
|
||||
FR,offwind-dc,,,,,,
|
||||
FR,solar,,,,,,
|
||||
DK,onwind,,,,,,
|
||||
DK,offwind-ac,,,,,,
|
||||
DK,offwind-dc,,,,,,
|
||||
DK,solar,,,,,,
|
||||
BE,onwind,,,,,,
|
||||
BE,offwind-ac,,,,,,
|
||||
BE,offwind-dc,,,,,,
|
||||
BE,solar,,,,,,
|
||||
|
|
27
data/ch_cantons.csv
Normal file
@ -0,0 +1,27 @@
|
||||
Canton,HASC,NUTS
|
||||
Aargau,CH.AG,CH033
|
||||
Appenzell Inner Rhodes,CH.AI,CH054
|
||||
Appenzell Outer Rhodes,CH.AR,CH053
|
||||
Basel-Landschaft,CH.BL,CH032
|
||||
Basel-Stadt,CH.BS,CH031
|
||||
Bern,CH.BE,CH021
|
||||
Fribourg,CH.FR,CH022
|
||||
Geneva,CH.GE,CH013
|
||||
Glarus,CH.GL,CH051
|
||||
Graubünden,CH.GR,CH056
|
||||
Jura,CH.JU,CH025
|
||||
Lucerne,CH.LU,CH061
|
||||
Neuchâtel,CH.NE,CH024
|
||||
Nidwalden,CH.NW,CH065
|
||||
Obwalden,CH.OW,CH064
|
||||
Sankt Gallen,CH.SG,CH055
|
||||
Schaffhausen,CH.SH,CH052
|
||||
Schwyz,CH.SZ,CH063
|
||||
Solothurn,CH.SO,CH023
|
||||
Thurgau,CH.TG,CH057
|
||||
Ticino,CH.TI,CH07
|
||||
Uri,CH.UR,CH062
|
||||
Valais,CH.VS,CH012
|
||||
Vaud,CH.VD,CH011
|
||||
Zug,CH.ZG,CH066
|
||||
Zurich,CH.ZH,CH04
|
|
@ -1,34 +0,0 @@
|
||||
Country/area,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022
|
||||
Albania,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Austria,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Belgium,,,,,,,,,,31.5,196.5,196.5,381.0,707.7,707.7,712.0,712.2,877.2,1185.9,1555.5,2261.8,2261.8,2261.8
|
||||
Bosnia Herzg,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Bulgaria,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Croatia,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Czechia,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Denmark,49.95,49.95,213.95,423.35,423.35,423.35,423.35,423.35,423.35,660.85,867.85,871.45,921.85,1271.05,1271.05,1271.05,1271.05,1263.8,1700.8,1700.8,1700.8,2305.6,2305.6
|
||||
Estonia,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Finland,,,,,,,,,24.0,24.0,26.3,26.3,26.3,26.3,26.3,32.0,32.0,72.7,72.7,73.0,73.0,73.0,73.0
|
||||
France,,,,,,,,,,,,,,,,,,2.0,2.0,2.0,2.0,2.0,482.0
|
||||
Germany,,,,,,,,,,35.0,80.0,188.0,268.0,508.0,994.0,3283.0,4132.0,5406.0,6393.0,7555.0,7787.0,7787.0,8129.0
|
||||
Greece,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Hungary,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Ireland,,,,,25.2,25.2,25.2,25.2,25.2,25.2,25.2,25.2,25.2,25.2,25.2,25.2,25.2,25.2,25.2,25.2,25.2,25.2,25.2
|
||||
Italy,,,,,,,,,,,,,,,,,,,,,,,30.0
|
||||
Latvia,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Lithuania,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Luxembourg,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Montenegro,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Netherlands,,,,,,,108.0,108.0,228.0,228.0,228.0,228.0,228.0,228.0,228.0,357.0,957.0,957.0,957.0,957.0,2459.5,2459.5,2571.0
|
||||
North Macedonia,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Norway,,,,,,,,,,2.3,2.3,2.3,2.3,2.3,2.3,2.3,2.3,2.3,2.3,2.3,2.3,6.3,66.3
|
||||
Poland,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Portugal,,,,,,,,,,,,1.86,2.0,2.0,2.0,2.0,,,,,25.0,25.0,25.0
|
||||
Romania,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Serbia,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Slovakia,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Slovenia,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Spain,,,,,,,,,,,,,,5.0,5.0,5.0,5.0,5.0,5.0,5.0,5.0,5.0,5.0
|
||||
Sweden,13.0,22.0,22.0,22.0,22.0,22.0,22.0,131.0,133.0,163.0,163.0,163.0,163.0,212.0,213.0,213.0,203.0,203.0,203.0,203.0,203.0,193.0,193.0
|
||||
Switzerland,,,,,,,,,,,,,,,,,,,,,,,
|
||||
UK,4.0,4.0,4.0,64.0,124.0,214.0,304.0,394.0,596.2,951.0,1341.0,1838.0,2995.0,3696.0,4501.0,5093.0,5293.0,6988.0,8181.0,9888.0,10383.0,11255.0,13928.0
|
|
@ -1,34 +0,0 @@
|
||||
Country/area,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022
|
||||
Albania,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Austria,50.0,67.0,109.0,322.0,581.0,825.22,968.27,991.16,991.97,1000.99,1015.83,1105.97,1337.15,1674.54,2110.28,2488.73,2730.0,2886.7,3132.71,3224.12,3225.98,3407.81,3735.81
|
||||
Belgium,14.0,26.0,31.0,67.0,96.0,167.0,212.0,276.0,324.0,576.5,715.5,872.5,985.9,1061.3,1225.0,1469.3,1621.6,1902.2,2119.0,2308.0,2410.9,2686.6,2989.6
|
||||
Bosnia Herzg,,,,,,,,,,,,0.3,0.3,0.3,0.3,0.3,0.3,0.3,51.0,87.0,87.0,135.0,135.0
|
||||
Bulgaria,,,,,1.0,8.0,27.0,30.0,114.0,333.0,488.0,541.0,677.0,683.0,699.0,699.0,699.0,698.39,698.92,703.12,702.8,704.38,704.38
|
||||
Croatia,,,,,6.0,6.0,17.0,17.0,17.0,70.0,79.0,130.0,180.0,254.0,339.0,418.0,483.0,576.1,586.3,646.3,801.3,986.9,1042.9
|
||||
Czechia,2.0,,6.4,10.6,16.5,22.0,43.5,113.8,150.0,193.0,213.0,213.0,258.0,262.0,278.0,281.0,282.0,308.21,316.2,339.41,339.42,339.41,339.41
|
||||
Denmark,2340.07,2447.2,2680.58,2696.57,2700.36,2704.49,2712.35,2700.86,2739.52,2821.24,2933.98,3080.53,3240.09,3547.87,3615.35,3805.92,3974.09,4225.15,4421.86,4409.74,4566.23,4715.24,4782.24
|
||||
Estonia,,,1.0,3.0,7.0,31.0,31.0,50.0,77.0,104.0,108.0,180.0,266.0,248.0,275.0,300.0,310.0,311.8,310.0,316.0,317.0,315.0,315.0
|
||||
Finland,38.0,39.0,43.0,52.0,82.0,82.0,86.0,110.0,119.0,123.0,170.7,172.7,230.7,420.7,600.7,973.0,1533.0,1971.3,1968.3,2211.0,2513.0,3184.0,5541.0
|
||||
France,38.0,66.0,138.0,218.0,358.0,690.0,1412.0,2223.0,3403.0,4582.0,5912.0,6758.02,7607.5,8155.96,9201.42,10298.18,11566.56,13497.35,14898.14,16424.85,17512.0,18737.98,20637.98
|
||||
Germany,6095.0,8754.0,12001.0,14381.0,16419.0,18248.0,20474.0,22116.0,22794.0,25697.0,26823.0,28524.0,30711.0,32969.0,37620.0,41297.0,45303.0,50174.0,52328.0,53187.0,54414.0,56046.0,58165.0
|
||||
Greece,226.0,270.0,287.0,371.0,470.0,491.0,749.0,846.0,1022.0,1171.0,1298.0,1640.0,1753.0,1809.0,1978.0,2091.0,2370.0,2624.0,2877.5,3589.0,4119.25,4649.13,4879.13
|
||||
Hungary,,1.0,1.0,3.0,3.0,17.0,33.0,61.0,134.0,203.0,293.0,331.0,325.0,329.0,329.0,329.0,329.0,329.0,329.0,323.0,323.0,324.0,324.0
|
||||
Ireland,116.5,122.9,134.8,210.3,311.2,468.1,651.3,715.3,917.1,1226.1,1365.2,1559.4,1679.15,1898.1,2258.05,2425.95,2776.45,3293.95,3648.65,4101.25,4281.5,4313.84,4593.84
|
||||
Italy,363.0,664.0,780.0,874.0,1127.0,1635.0,1902.0,2702.0,3525.0,4879.0,5794.0,6918.0,8102.0,8542.0,8683.0,9137.0,9384.0,9736.58,10230.25,10679.46,10870.62,11253.73,11749.73
|
||||
Latvia,2.0,2.0,22.0,26.0,26.0,26.0,26.0,26.0,28.0,29.0,30.0,36.0,59.0,65.89,68.92,68.17,69.91,77.11,78.17,78.07,78.07,77.13,136.13
|
||||
Lithuania,,,,,1.0,1.0,31.0,47.0,54.0,98.0,133.0,202.0,275.0,279.0,288.0,436.0,509.0,518.0,533.0,534.0,540.0,671.0,814.0
|
||||
Luxembourg,14.0,13.9,13.9,20.5,34.9,34.9,34.9,34.9,42.92,42.93,43.73,44.53,58.33,58.33,58.34,63.79,119.69,119.69,122.89,135.79,152.74,136.44,165.44
|
||||
Montenegro,,,,,,,,,,,,,,,,,,72.0,72.0,118.0,118.0,118.0,118.0
|
||||
Netherlands,447.0,486.0,672.0,905.0,1075.0,1224.0,1453.0,1641.0,1921.0,1994.0,2009.0,2088.0,2205.0,2485.0,2637.0,3033.84,3300.12,3245.0,3436.11,3527.16,4188.38,5309.87,6176.0
|
||||
North Macedonia,,,,,,,,,,,,,,,37.0,37.0,37.0,37.0,37.0,37.0,37.0,37.0,37.0
|
||||
Norway,13.0,13.0,97.0,97.0,152.0,265.0,284.0,348.0,395.0,420.7,422.7,509.7,702.7,815.7,856.7,864.7,880.7,1204.7,1707.7,2911.7,4027.7,5042.7,5067.7
|
||||
Poland,4.0,19.0,32.0,35.0,40.0,121.0,172.0,306.0,526.0,709.0,1108.0,1800.0,2564.0,3429.0,3836.0,4886.0,5747.0,5759.36,5766.08,5837.76,6298.25,6967.34,7987.34
|
||||
Portugal,83.0,125.0,190.0,268.0,553.0,1064.0,1681.0,2201.0,2857.0,3326.0,3796.0,4254.35,4409.55,4607.95,4854.56,4934.84,5124.1,5124.1,5172.36,5222.75,5097.26,5402.33,5430.33
|
||||
Romania,,,,,,1.0,1.0,3.0,5.0,15.0,389.0,988.0,1822.0,2773.0,3244.0,3130.0,3025.0,3029.8,3032.26,3037.52,3012.53,3014.96,3014.96
|
||||
Serbia,,,,,,,,,,,,,0.5,0.5,0.5,10.4,17.0,25.0,227.0,398.0,398.0,398.0,398.0
|
||||
Slovakia,,,,3.0,3.0,5.0,5.0,5.0,5.0,3.0,3.0,3.0,3.0,5.0,3.0,3.0,3.0,4.0,3.0,4.0,4.0,4.0,4.0
|
||||
Slovenia,,,,,,,,,,,,,2.0,2.0,3.0,3.0,3.0,3.3,3.3,3.3,3.3,3.33,3.33
|
||||
Spain,2206.0,3397.0,4891.0,5945.0,8317.0,9918.0,11722.0,14820.0,16555.0,19176.0,20693.0,21529.0,22789.0,22953.0,22920.0,22938.0,22985.0,23119.48,23400.06,25585.08,26814.19,27902.65,29302.84
|
||||
Sweden,196.0,273.0,335.0,395.0,453.0,500.0,563.0,692.0,956.0,1312.0,1854.0,2601.0,3443.0,3982.0,4875.0,5606.0,6232.0,6408.0,7097.0,8478.0,9773.0,11923.0,14364.0
|
||||
Switzerland,3.0,5.0,5.0,5.0,9.0,12.0,12.0,12.0,14.0,18.0,42.0,46.0,49.0,60.0,60.0,60.0,75.0,75.0,75.0,75.0,87.0,87.0,87.0
|
||||
UK,431.0,490.0,531.0,678.0,809.0,1351.0,1651.0,2083.0,2849.8,3468.0,4080.0,4758.0,6035.0,7586.0,8573.0,9212.0,10833.0,12597.0,13425.0,13999.0,14075.0,14492.0,14832.0
|
|
@ -1,34 +0,0 @@
|
||||
Country/area,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022
|
||||
Albania,,0.1,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.3,0.4,0.56,0.68,0.76,0.87,1.05,1.0,1.0,1.0,14.0,21.0,23.0,28.6
|
||||
Austria,5.0,7.0,9.0,23.0,27.0,18.49,19.61,21.42,27.0,45.56,85.27,169.88,333.09,620.78,779.76,931.56,1089.53,1262.01,1447.94,1694.4,2034.74,2773.91,3538.91
|
||||
Belgium,,,1.0,1.0,1.0,2.0,2.0,20.0,62.0,386.0,1006.6,1978.6,2646.6,2901.6,3015.0,3131.6,3328.8,3620.6,4000.0,4636.6,5572.8,6012.4,6898.4
|
||||
Bosnia Herzg,,,,0.1,0.2,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.35,1.34,7.17,8.17,14.12,16.0,18.15,22.35,34.89,56.51,107.47
|
||||
Bulgaria,,,,,,,,0.03,0.1,2.0,25.0,154.0,921.99,1038.54,1028.92,1027.89,1029.89,1030.7,1033.06,1044.39,1100.21,1274.71,1948.36
|
||||
Croatia,,,,,,,,,,0.3,0.3,0.3,4.0,19.0,33.0,47.8,55.8,60.0,67.7,84.8,108.5,138.3,182.3
|
||||
Czechia,0.1,0.1,0.2,0.3,0.4,0.59,0.84,3.96,39.5,464.6,1727.0,1913.0,2022.0,2063.5,2067.4,2074.9,2067.9,2075.44,2081.05,2110.67,2171.96,2246.09,2627.09
|
||||
Denmark,1.0,1.0,2.0,2.0,2.0,3.0,3.0,3.0,3.0,5.0,7.0,17.0,402.0,571.0,607.0,782.11,850.95,906.35,998.0,1080.0,1304.29,1704.04,3122.04
|
||||
Estonia,,,,,,,,,,0.1,0.1,0.2,0.38,1.5,3.34,6.5,10.0,15.0,31.9,120.6,207.67,394.77,534.77
|
||||
Finland,2.0,3.0,3.0,3.0,4.0,4.0,5.0,5.0,6.0,6.0,7.0,7.0,8.0,9.0,11.0,17.0,39.0,82.0,140.0,222.0,318.0,425.0,590.6
|
||||
France,7.0,7.0,8.0,9.0,11.0,13.0,15.0,26.0,80.0,277.0,1044.0,3003.57,4358.75,5277.29,6034.42,7137.52,7702.08,8610.44,9638.88,10738.39,11812.2,14436.97,17036.97
|
||||
Germany,114.0,195.0,260.0,435.0,1105.0,2056.0,2899.0,4170.0,6120.0,10564.0,18004.0,25914.0,34075.0,36708.0,37898.0,39222.0,40677.0,42291.0,45156.0,48912.0,53669.0,59371.0,66662.0
|
||||
Greece,,1.0,1.0,1.0,1.0,1.0,5.0,9.0,12.0,46.0,202.0,612.0,1536.0,2579.0,2596.0,2604.0,2604.0,2605.53,2651.57,2833.79,3287.72,4277.42,5557.42
|
||||
Hungary,,,,,,,,0.4,1.0,1.0,2.0,4.0,12.0,35.0,89.0,172.0,235.0,344.0,728.0,1400.0,2131.0,2968.0,2988.0
|
||||
Ireland,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Italy,19.0,20.0,22.0,26.0,31.0,34.0,45.0,110.0,483.0,1264.0,3592.0,13131.0,16785.0,18185.0,18594.0,18901.0,19283.0,19682.29,20107.59,20865.28,21650.04,22594.26,25076.56
|
||||
Latvia,,,,,,,,,,,,,,,,,0.69,0.69,1.96,3.3,5.1,7.16,56.16
|
||||
Lithuania,,,,,,,,,0.1,0.1,0.1,0.3,7.0,68.0,69.0,69.0,70.0,70.08,72.0,73.0,80.0,84.0,397.0
|
||||
Luxembourg,,0.16,1.59,14.17,23.56,23.58,23.7,23.93,24.56,26.36,29.45,40.67,74.65,95.02,109.93,116.27,121.9,128.1,130.62,159.74,186.64,277.16,319.16
|
||||
Montenegro,,,,,,,,,,,,,,,,,,,,,2.57,2.57,22.2
|
||||
Netherlands,13.0,21.0,26.0,46.0,50.0,51.0,53.0,54.0,59.0,69.0,90.0,149.0,287.0,650.0,1007.0,1526.26,2135.02,2910.89,4608.0,7226.0,11108.43,14910.69,18848.69
|
||||
North Macedonia,,,,,,,,,,,,2.0,4.0,7.0,15.0,17.0,16.7,16.7,16.7,16.71,84.93,84.93,84.93
|
||||
Norway,6.0,6.0,6.0,7.0,7.0,7.0,8.0,8.0,8.3,8.7,9.1,9.5,10.0,11.0,13.0,15.0,26.7,44.9,53.11,102.53,141.53,186.53,302.53
|
||||
Poland,,,,,,,,,,,,1.11,1.3,2.39,27.15,107.78,187.25,287.09,561.98,1539.26,3954.96,7415.52,11166.52
|
||||
Portugal,1.0,1.0,1.0,2.0,2.0,2.0,3.0,24.0,59.0,115.0,134.0,169.6,235.6,293.6,412.6,441.75,493.05,539.42,617.85,832.74,1010.07,1474.78,2364.78
|
||||
Romania,,,,,,,,,0.1,0.1,0.1,1.0,41.0,761.0,1293.0,1326.0,1372.0,1374.13,1385.82,1397.71,1382.54,1393.92,1413.92
|
||||
Serbia,,,,,,0.1,0.2,0.4,0.9,1.2,1.3,1.5,3.1,4.7,6.0,9.0,11.0,10.0,11.0,11.0,11.5,11.94,11.94
|
||||
Slovakia,,,,,,,,,,,19.0,496.0,513.0,533.0,533.0,533.0,533.0,528.0,472.0,590.0,535.0,537.0,537.0
|
||||
Slovenia,1.0,1.0,,,,0.05,0.19,0.59,1.0,4.0,12.0,57.0,142.0,187.0,223.0,238.0,233.0,246.8,246.8,277.88,369.78,461.16,632.16
|
||||
Spain,1.0,3.0,6.0,10.0,19.0,37.0,113.0,476.0,3365.0,3403.0,3851.0,4260.0,4545.0,4665.0,4672.0,4677.0,4687.0,4696.0,4730.7,8772.02,10100.42,13678.4,18176.73
|
||||
Sweden,3.0,3.0,3.0,4.0,4.0,4.0,5.0,6.0,8.0,9.0,11.0,12.0,24.0,43.0,60.0,104.0,153.0,231.0,411.0,698.0,1090.0,1587.0,2587.0
|
||||
Switzerland,16.0,18.0,20.0,22.0,24.0,28.0,30.0,37.0,49.0,79.0,125.0,223.0,437.0,756.0,1061.0,1394.0,1664.0,1906.0,2173.0,2498.0,2973.0,3655.0,4339.92
|
||||
UK,2.0,3.0,4.0,6.0,8.0,11.0,14.0,18.0,23.0,27.0,95.0,1000.0,1753.0,2937.0,5528.0,9601.0,11914.0,12760.0,13059.0,13345.0,13579.0,13965.0,14660.0
|
|
@ -1,25 +0,0 @@
|
||||
hour,weekday,weekend
|
||||
0,0.9181438689,0.9421512708
|
||||
1,0.9172359071,0.9400891069
|
||||
2,0.9269464481,0.9461062015
|
||||
3,0.9415047932,0.9535084941
|
||||
4,0.9656299507,0.9651094993
|
||||
5,1.0221166443,0.9834676747
|
||||
6,1.1553090493,1.0124171051
|
||||
7,1.2093411031,1.0446615927
|
||||
8,1.1470295942,1.088203419
|
||||
9,1.0877191341,1.1110334576
|
||||
10,1.0418327372,1.0926752822
|
||||
11,1.0062977133,1.055488209
|
||||
12,0.9837030359,1.0251266112
|
||||
13,0.9667570278,0.9990015154
|
||||
14,0.9548320932,0.9782897278
|
||||
15,0.9509232061,0.9698167237
|
||||
16,0.9636973319,0.974288587
|
||||
17,0.9799372563,0.9886456216
|
||||
18,1.0046501848,1.0084159643
|
||||
19,1.0079452419,1.0171243296
|
||||
20,0.9860566481,0.9994722379
|
||||
21,0.9705228074,0.982761591
|
||||
22,0.9586485819,0.9698167237
|
||||
23,0.9335023778,0.9515079292
|
|
31
data/hydro_capacities.csv
Normal file
@ -0,0 +1,31 @@
|
||||
Country,p_nom_discharge[GW],p_nom_store[GW],E_store[TWh],InflowHourlyAvg[GWh]
|
||||
AT,13.08,3.8,3.2,4.02
|
||||
BE,1.42,1.31,0,0.04
|
||||
BA,2.05,0.62,2.5,0.71
|
||||
BG,3.13,0.86,4,0.53
|
||||
HR,2,0.61,2.8,0.57
|
||||
CZ,2.21,0.68,1.5,0.24
|
||||
DK,0.01,0,0,0
|
||||
EE,0.01,0,0,0
|
||||
FI,3.2,0,5.5,1.59
|
||||
FR,25.37,6.99,9.8,7.82
|
||||
DE,11.26,6.8,0.3,1.93
|
||||
GB,4.43,2.74,0,0.46
|
||||
GR,3.24,0.7,2.3,0.26
|
||||
HU,0.06,0,0.1,0.02
|
||||
IE,0.53,0.29,0,0.08
|
||||
IT,21.88,7.55,7.9,5.19
|
||||
LV,1.58,0,1.8,0.3
|
||||
LT,0.88,0.76,0.2,0.05
|
||||
LU,1.13,1.29,0,0
|
||||
NL,0.04,0,0,0.01
|
||||
NO,30.51,1.35,84.4,14
|
||||
PL,2.35,1.4,1.6,0.23
|
||||
PT,5.72,1.03,2.6,1.37
|
||||
RO,6.55,0.09,12.1,1.95
|
||||
RS,2.14,0.61,0,1.18
|
||||
SK,2.52,0.92,2.2,0.49
|
||||
SI,1.25,0.18,2.2,0.36
|
||||
ES,18.55,2.75,18.4,2.61
|
||||
SE,16.41,0.1,33.8,7.8
|
||||
CH,13.3,4.03,8.4,4.29
|
|
@ -1,31 +0,0 @@
|
||||
ct,TWh
|
||||
AT,
|
||||
BA,
|
||||
BE,
|
||||
BG,
|
||||
CH,
|
||||
CZ,
|
||||
DE,4500
|
||||
DK,700
|
||||
EE,
|
||||
ES,350
|
||||
FI,
|
||||
FR,
|
||||
GB,1050
|
||||
GR,120
|
||||
HR,
|
||||
HU,
|
||||
IE,
|
||||
IT,
|
||||
LT,
|
||||
LU,
|
||||
LV,
|
||||
NL,150
|
||||
NO,
|
||||
PL,120
|
||||
PT,400
|
||||
RO,
|
||||
RS,
|
||||
SE,
|
||||
SI,
|
||||
SK,
|
|
21
doc/conf.py
@ -34,10 +34,10 @@ sys.path.insert(0, os.path.abspath("../scripts"))
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
#'sphinx.ext.autodoc',
|
||||
"sphinx.ext.autodoc",
|
||||
#'sphinx.ext.autosummary',
|
||||
"myst_parser",
|
||||
"sphinx.ext.autosectionlabel",
|
||||
# "sphinx.ext.autosectionlabel",
|
||||
"sphinx.ext.intersphinx",
|
||||
"sphinx.ext.todo",
|
||||
"sphinx.ext.mathjax",
|
||||
@ -50,6 +50,19 @@ extensions = [
|
||||
"sphinx.ext.imgconverter", # for SVG conversion
|
||||
]
|
||||
|
||||
autodoc_mock_imports = [
|
||||
"atlite",
|
||||
"snakemake",
|
||||
"pycountry",
|
||||
"rioxarray",
|
||||
"country_converter",
|
||||
"tabula",
|
||||
"memory_profiler",
|
||||
"powerplantmatching",
|
||||
"rasterio",
|
||||
"dask.distributed",
|
||||
]
|
||||
|
||||
autodoc_default_flags = ["members"]
|
||||
autosummary_generate = True
|
||||
|
||||
@ -80,9 +93,9 @@ author = "Tom Brown (KIT, TUB, FIAS), Jonas Hoersch (KIT, FIAS), Fabian Hofmann
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = "0.10"
|
||||
version = "0.11"
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = "0.10.0"
|
||||
release = "0.11.0"
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
@ -1,2 +1,2 @@
|
||||
,Unit,Values,Description
|
||||
co2_budget,--,Dictionary with planning horizons as keys.,CO2 budget as a fraction of 1990 emissions. Overwritten if ``CO2Lx`` or ``cb`` are set in ``{sector_opts}`` wildcard"doc/configtables/othertoplevel.csv
|
||||
co2_budget,--,Dictionary with planning horizons as keys.,CO2 budget as a fraction of 1990 emissions. Overwritten if ``Co2Lx`` or ``cb`` are set in ``{sector_opts}`` wildcard"doc/configtables/othertoplevel.csv
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 174.
|
@ -1,7 +1,6 @@
|
||||
,Unit,Values,Description
|
||||
year,--,YYYY; e.g. '2030',Year for which to retrieve cost assumptions of ``resources/costs.csv``.
|
||||
version,--,vX.X.X or <user>/<repo>/vX.X.X; e.g. 'v0.5.0',Version of ``technology-data`` repository to use. If this string is of the form <user>/<repo>/<version> then costs are instead retrieved from ``github.com/<user>/<repo>`` at the <version> tag.
|
||||
rooftop_share,--,float,Share of rooftop PV when calculating capital cost of solar (joint rooftop and utility-scale PV).
|
||||
social_discountrate,p.u.,float,Social discount rate to compare costs in different investment periods. 0.02 corresponds to a social discount rate of 2%.
|
||||
fill_values,--,float,Default values if not specified for a technology in ``resources/costs.csv``.
|
||||
capital_cost,EUR/MW,Keys should be in the 'technology' column of ``resources/costs.csv``. Values can be any float.,"For the given technologies, assumptions about their capital investment costs are set to the corresponding value. Optional; overwrites cost assumptions from ``resources/costs.csv``."
|
||||
|
|
@ -2,10 +2,9 @@
|
||||
voltages,kV,"Any subset of {220., 300., 380.}",Voltage levels to consider
|
||||
gaslimit_enable,bool,true or false,Add an overall absolute gas limit configured in ``electricity: gaslimit``.
|
||||
gaslimit,MWhth,float or false,Global gas usage limit
|
||||
co2limit_enable,bool,true or false,Add an overall absolute carbon-dioxide emissions limit configured in ``electricity: co2limit``.
|
||||
co2limit_enable,bool,true or false,Add an overall absolute carbon-dioxide emissions limit configured in ``electricity: co2limit`` in :mod:`prepare_network`. **Warning:** This option should currently only be used with electricity-only networks, not for sector-coupled networks..
|
||||
co2limit,:math:`t_{CO_2-eq}/a`,float,Cap on total annual system carbon dioxide emissions
|
||||
co2base,:math:`t_{CO_2-eq}/a`,float,Reference value of total annual system carbon dioxide emissions if relative emission reduction target is specified in ``{opts}`` wildcard.
|
||||
agg_p_nom_limits,file,path,Reference to ``.csv`` file specifying per carrier generator nominal capacity constraints for individual countries if ``'CCL'`` is in ``{opts}`` wildcard. Defaults to ``data/agg_p_nom_minmax.csv``.
|
||||
operational_reserve,,,Settings for reserve requirements following `GenX <https://genxproject.github.io/GenX/dev/core/#Reserves>`_
|
||||
,,,
|
||||
-- activate,bool,true or false,Whether to take operational reserve requirements into account during optimisation
|
||||
@ -28,14 +27,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
|
||||
-- enable,,bool,Activate routine to estimate renewable capacities in rule :mod:`add_electricity`. This option should not be used in combination with pathway planning ``foresight: myopic`` or ``foresight: perfect`` as renewable capacities are added differently in :mod:`add_existing_baseyear`.
|
||||
-- from_opsd,--,bool,Add renewable capacities from `OPSD database <https://data.open-power-system-data.org/renewable_power_plants/2020-08-25>`_. 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,,,
|
||||
|
Can't render this file because it has a wrong number of fields in line 5.
|
@ -2,12 +2,8 @@
|
||||
enable,str or bool,"{auto, true, false}","Switch to include (true) or exclude (false) the retrieve_* rules of snakemake into the workflow; 'auto' sets true|false based on availability of an internet connection to prevent issues with snakemake failing due to lack of internet connection."
|
||||
prepare_links_p_nom,bool,"{true, false}","Switch to retrieve current HVDC projects from `Wikipedia <https://en.wikipedia.org/wiki/List_of_HVDC_projects>`_"
|
||||
retrieve_databundle,bool,"{true, false}","Switch to retrieve databundle from zenodo via the rule :mod:`retrieve_databundle` or whether to keep a custom databundle located in the corresponding folder."
|
||||
retrieve_sector_databundle,bool,"{true, false}","Switch to retrieve sector databundle from zenodo via the rule :mod:`retrieve_sector_databundle` or whether to keep a custom databundle located in the corresponding folder."
|
||||
retrieve_cost_data,bool,"{true, false}","Switch to retrieve technology cost data from `technology-data repository <https://github.com/PyPSA/technology-data>`_."
|
||||
build_cutout,bool,"{true, false}","Switch to enable the building of cutouts via the rule :mod:`build_cutout`."
|
||||
retrieve_irena,bool,"{true, false}",Switch to enable the retrieval of ``existing_capacities`` from IRENASTAT with :mod:`retrieve_irena`.
|
||||
retrieve_cutout,bool,"{true, false}","Switch to enable the retrieval of cutouts from zenodo with :mod:`retrieve_cutout`."
|
||||
build_natura_raster,bool,"{true, false}","Switch to enable the creation of the raster ``natura.tiff`` via the rule :mod:`build_natura_raster`."
|
||||
retrieve_natura_raster,bool,"{true, false}","Switch to enable the retrieval of ``natura.tiff`` from zenodo with :mod:`retrieve_natura_raster`."
|
||||
custom_busmap,bool,"{true, false}","Switch to enable the use of custom busmaps in rule :mod:`cluster_network`. If activated the rule looks for provided busmaps at ``data/custom_busmap_elec_s{simpl}_{clusters}.csv`` which should have the same format as ``resources/busmap_elec_s{simpl}_{clusters}.csv``, i.e. the index should contain the buses of ``networks/elec_s{simpl}.nc``."
|
||||
drop_leap_day,bool,"{true, false}","Switch to drop February 29 from all time-dependent data in leap years"
|
||||
|
|
@ -16,6 +16,9 @@ petrochemical_process _emissions,MtCO2/a,float,The emission of petrochemical pro
|
||||
HVC_primary_fraction,--,float,The fraction of high value chemicals (HVC) produced via primary route
|
||||
HVC_mechanical_recycling _fraction,--,float,The fraction of high value chemicals (HVC) produced using mechanical recycling
|
||||
HVC_chemical_recycling _fraction,--,float,The fraction of high value chemicals (HVC) produced using chemical recycling
|
||||
HVC_environment_sequestration_fraction,--,float,The fraction of high value chemicals (HVC) put into landfill resulting in additional carbon sequestration. The default value is 0.
|
||||
waste_to_energy,--,bool,Switch to enable expansion of waste to energy CHPs for conversion of plastics. Default is false.
|
||||
waste_to_energy_cc,--,bool,Switch to enable expansion of waste to energy CHPs for conversion of plastics with carbon capture. Default is false.
|
||||
,,,
|
||||
sector_ratios_fraction_future,--,Dictionary with planning horizons as keys.,The fraction of total progress in fuel and process switching achieved in the industry sector.
|
||||
basic_chemicals_without_NH3_production_today,Mt/a,float,"The amount of basic chemicals produced without ammonia (= 86 Mtethylene-equiv - 17 MtNH3)."
|
||||
@ -29,5 +32,6 @@ MWh_H2_per_tCl,MWhH2/tCl,float,"The energy amount of hydrogen needed to produce
|
||||
methanol_production _today,MtMeOH/a,float,"The amount of methanol produced. From `DECHEMA (2017) <https://dechema.de/dechema_media/Downloads/Positionspapiere/Technology_study_Low_carbon_energy_and_feedstock_for_the_European_chemical_industry-p-20002750.pdf>`_, page 62"
|
||||
MWh_elec_per_tMeOH,MWh/tMeOH,float,"The energy amount of electricity needed to produce a ton of methanol. From `DECHEMA (2017) <https://dechema.de/dechema_media/Downloads/Positionspapiere/Technology_study_Low_carbon_energy_and_feedstock_for_the_European_chemical_industry-p-20002750.pdf>`_, Table 14, page 65"
|
||||
MWh_CH4_per_tMeOH,MWhCH4/tMeOH,float,"The energy amount of methane needed to produce a ton of methanol. From `DECHEMA (2017) <https://dechema.de/dechema_media/Downloads/Positionspapiere/Technology_study_Low_carbon_energy_and_feedstock_for_the_European_chemical_industry-p-20002750.pdf>`_, Table 14, page 65"
|
||||
MWh_MeOH_per_tMeOH,LHV,float,"The energy amount per ton of methanol. From `DECHEMA (2017) <https://dechema.de/dechema_media/Downloads/Positionspapiere/Technology_study_Low_carbon_energy_and_feedstock_for_the_European_chemical_industry-p-20002750.pdf>`_, page 74."
|
||||
hotmaps_locate_missing,--,"{true,false}",Locate industrial sites without valid locations based on city and countries.
|
||||
reference_year,year,YYYY,The year used as the baseline for industrial energy demand and production. Data extracted from `JRC-IDEES 2015 <https://data.jrc.ec.europa.eu/dataset/jrc-10110-10001>`_
|
||||
|
|
@ -1,14 +1,12 @@
|
||||
description,file/folder,licence,source
|
||||
JRC IDEES database,jrc-idees-2015/,CC BY 4.0,https://ec.europa.eu/jrc/en/potencia/jrc-idees
|
||||
urban/rural fraction,urban_percent.csv,unknown,unknown
|
||||
JRC biomass potentials,biomass/,unknown,https://doi.org/10.2790/39014
|
||||
JRC ENSPRESO biomass potentials,remote,CC BY 4.0,https://data.jrc.ec.europa.eu/dataset/74ed5a04-7d74-4807-9eab-b94774309d9f
|
||||
EEA emission statistics,eea/UNFCCC_v23.csv,EEA standard re-use policy,https://www.eea.europa.eu/data-and-maps/data/national-emissions-reported-to-the-unfccc-and-to-the-eu-greenhouse-gas-monitoring-mechanism-16
|
||||
Eurostat Energy Balances,eurostat-energy_balances-*/,Eurostat,https://ec.europa.eu/eurostat/web/energy/data/energy-balances
|
||||
Swiss energy statistics from Swiss Federal Office of Energy,switzerland-sfoe/,unknown,http://www.bfe.admin.ch/themen/00526/00541/00542/02167/index.html?dossier_id=02169
|
||||
BASt emobility statistics,emobility/,unknown,http://www.bast.de/DE/Verkehrstechnik/Fachthemen/v2-verkehrszaehlung/Stundenwerte.html?nn=626916
|
||||
BDEW heating profile,heat_load_profile_BDEW.csv,unknown,https://github.com/oemof/demandlib
|
||||
heating profiles for Aarhus,heat_load_profile_DK_AdamJensen.csv,unknown,Adam Jensen MA thesis at Aarhus University
|
||||
co2 budgets,co2_budget.csv,CC BY 4.0,https://arxiv.org/abs/2004.11009
|
||||
existing heating potentials,existing_infrastructure/existing_heating_raw.csv,unknown,https://energy.ec.europa.eu/publications/mapping-and-analyses-current-and-future-2020-2030-heatingcooling-fuel-deployment-fossilrenewables-1_en
|
||||
IRENA existing VRE capacities,existing_infrastructure/{solar|onwind|offwind}_capcity_IRENA.csv,unknown,https://www.irena.org/Statistics/Download-Data
|
||||
|
|
@ -5,10 +5,8 @@
|
||||
"naturalearth/*",,,,,http://www.naturalearthdata.com/about/terms-of-use/
|
||||
"NUTS_2013 _60M_SH/*","x","x",,"x",https://ec.europa.eu/eurostat/web/gisco/geodata/reference-data/administrative-units-statistical-units
|
||||
"cantons.csv","x",,"x",,https://en.wikipedia.org/wiki/Data_codes_for_Switzerland
|
||||
"eia_hydro_annual_generation.csv","x",,,,https://www.eia.gov/about/copyrights_reuse.php
|
||||
"GEBCO_2014_2D.nc","x",,,,https://www.gebco.net/data_and_products/gridded_bathymetry_data/documents/gebco_2014_historic.pdf
|
||||
"gebco/GEBCO_2014_2D.nc","x",,,,https://www.gebco.net/data_and_products/gridded_bathymetry_data/documents/gebco_2014_historic.pdf
|
||||
"hydro_capacities.csv","x",,,,
|
||||
"je-e-21.03.02.xls","x","x",,,https://www.bfs.admin.ch/bfs/en/home/fso/swiss-federal-statistical-office/terms-of-use.html
|
||||
"nama_10r_3 gdp.tsv.gz","x",,,"x",https://ec.europa.eu/eurostat/about/policies/copyright
|
||||
"nama_10r_3 popgdp.tsv.gz","x",,,"x",https://ec.europa.eu/eurostat/about/policies/copyright
|
||||
"time_series_60min _singleindex_filtered.csv","x",,,,https://data.open-power-system-data.org/time_series/2019-06-05/README.md
|
||||
|
|
@ -4,4 +4,4 @@ time_shift_for_large_gaps,string,string,"Periods which are used for copying time
|
||||
manual_adjustments,bool,"{true, false}","Whether to adjust the load data manually according to the function in :func:`manual_adjustment`."
|
||||
scaling_factor,--,float,"Global correction factor for the load time series."
|
||||
fixed_year,--,Year or False,"To specify a fixed year for the load time series that deviates from the snapshots' year"
|
||||
supplement_synthetic,bool,"{true, false}","Whether to supplement missing data for selected time period should be supplemented by synthetic data from https://zenodo.org/record/10820928."
|
||||
supplement_synthetic,bool,"{true, false}","Whether to supplement missing data for selected time period should be supplemented by synthetic data from https://zenodo.org/records/10820928."
|
||||
|
|
@ -1,8 +1,11 @@
|
||||
,Unit,Values,Description
|
||||
name,--,str/list,"Specify a name for your run. Results will be stored under this name. If ``scenario: enable:`` is set to ``true``, the name must contain a subset of scenario names defined in ``scenario: file:``. If the name is 'all', all defined scenarios will be run."
|
||||
prefix,--,str,"Prefix for the run name which is used as a top-layer directory name in the results and resources folders."
|
||||
scenarios,,,
|
||||
-- enable,bool,"{true, false}","Switch to select whether workflow should generate scenarios based on ``file``."
|
||||
-- file,str,,"Path to the scenario yaml file. The scenario file contains config overrides for each scenario. In order to be taken account, ``run: scenarios`` has to be set to ``true`` and ``run: name`` has to be a subset of top level keys given in the scenario file. In order to automatically create a `scenario.yaml` file based on a combination of settings, alter and use the ``config/create_scenarios.py`` script in the ``config`` directory."
|
||||
disable_progressbar,bool,"{true, false}","Switch to select whether progressbar should be disabled."
|
||||
shared_resources,bool/str,,"Switch to select whether resources should be shared across runs. If a string is passed, this is used as a subdirectory name for shared resources. If set to 'base', only resources before creating the elec.nc file are shared."
|
||||
shared_resources,,,
|
||||
-- policy,bool/str,,"Boolean switch to select whether resources should be shared across runs. If a string is passed, this is used as a subdirectory name for shared resources. If set to 'base', only resources before creating the elec.nc file are shared."
|
||||
-- exclude,str,"For the case shared_resources=base, specify additional files that should not be shared across runs."
|
||||
shared_cutouts,bool,"{true, false}","Switch to select whether cutouts should be shared across runs."
|
||||
|
Can't render this file because it has a wrong number of fields in line 10.
|
@ -1,6 +1,6 @@
|
||||
Trigger, Description, Definition, Status
|
||||
``nH``, i.e. ``2H``-``6H``, "Resample the time-resolution by averaging over every ``n`` snapshots, ``prepare_network``: `average_every_nhours() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L110>`_ and its `caller <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L146>`__)", In active use
|
||||
``Co2L``, Add an overall absolute carbon-dioxide emissions limit configured in ``electricity: co2limit``. If a float is appended an overall emission limit relative to the emission level given in ``electricity: co2base`` is added (e.g. ``Co2L0.05`` limits emissisions to 5% of what is given in ``electricity: co2base``), ``prepare_network``: `add_co2limit() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L19>`_ and its `caller <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L154>`__, In active use
|
||||
``nH``, i.e. ``2h``-``6h``, "Resample the time-resolution by averaging over every ``n`` snapshots, ``prepare_network``: `average_every_nhours() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L110>`_ and its `caller <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L146>`__)", In active use
|
||||
``Co2L`` + ``n``, Add an overall absolute carbon-dioxide emissions limit of ``n`` times of the 1990 base emissions (e.g. ``Co2L0.05`` limits emissisions to 5% of what is calculated in the rule :mod:``prepare_sector_network`` in the function ``co2_emissions_year()``),:mod:``prepare_sector_network`` in the function ``co2_emissions_year()`` , In active use
|
||||
``carrier+{c|p|m}factor``,"Alter the capital cost (``c``), installable potential (``p``) or marginal costs (``m``) of a carrier by a factor. Example: ``solar+c0.5`` reduces the capital cost of solar to 50\% of original values.", ``prepare_network``, In active use
|
||||
``T``,Add land transport sector,,In active use
|
||||
``H``,Add heating sector,,In active use
|
||||
|
|
@ -24,7 +24,6 @@ bev_dsm,--,"{true, false}",Add the option for battery electric vehicles (BEV) to
|
||||
bev_availability,--,float,The share for battery electric vehicles (BEV) that are able to do demand side management (DSM)
|
||||
bev_energy,--,float,The average size of battery electric vehicles (BEV) in MWh
|
||||
bev_charge_efficiency,--,float,Battery electric vehicles (BEV) charge and discharge efficiency
|
||||
bev_plug_to_wheel _efficiency,km/kWh,float,The distance battery electric vehicles (BEV) can travel in km per kWh of energy charge in battery. Base value comes from `Tesla Model S <https://www.fueleconomy.gov/feg/>`_
|
||||
bev_charge_rate,MWh,float,The power consumption for one electric vehicle (EV) in MWh. Value derived from 3-phase charger with 11 kW.
|
||||
bev_avail_max,--,float,The maximum share plugged-in availability for passenger electric vehicles.
|
||||
bev_avail_mean,--,float,The average share plugged-in availability for passenger electric vehicles.
|
||||
@ -32,14 +31,15 @@ v2g,--,"{true, false}",Allows feed-in to grid from EV battery
|
||||
land_transport_fuel_cell _share,--,Dictionary with planning horizons as keys.,The share of vehicles that uses fuel cells in a given year
|
||||
land_transport_electric _share,--,Dictionary with planning horizons as keys.,The share of vehicles that uses electric vehicles (EV) in a given year
|
||||
land_transport_ice _share,--,Dictionary with planning horizons as keys.,The share of vehicles that uses internal combustion engines (ICE) in a given year. What is not EV or FCEV is oil-fuelled ICE.
|
||||
transport_fuel_cell _efficiency,--,float,The H2 conversion efficiencies of fuel cells in transport
|
||||
transport_internal _combustion_efficiency,--,float,The oil conversion efficiencies of internal combustion engine (ICE) in transport
|
||||
transport_electric_efficiency,MWh/100km,float,The conversion efficiencies of electric vehicles in transport
|
||||
transport_fuel_cell_efficiency,MWh/100km,float,The H2 conversion efficiencies of fuel cells in transport
|
||||
transport_ice_efficiency,MWh/100km,float,The oil conversion efficiencies of internal combustion engine (ICE) in transport
|
||||
agriculture_machinery _electric_share,--,float,The share for agricultural machinery that uses electricity
|
||||
agriculture_machinery _oil_share,--,float,The share for agricultural machinery that uses oil
|
||||
agriculture_machinery _fuel_efficiency,--,float,The efficiency of electric-powered machinery in the conversion of electricity to meet agricultural needs.
|
||||
agriculture_machinery _electric_efficiency,--,float,The efficiency of oil-powered machinery in the conversion of oil to meet agricultural needs.
|
||||
Mwh_MeOH_per_MWh_H2,LHV,float,"The energy amount of the produced methanol per energy amount of hydrogen. From `DECHEMA (2017) <https://dechema.de/dechema_media/Downloads/Positionspapiere/Technology_study_Low_carbon_energy_and_feedstock_for_the_European_chemical_industry-p-20002750.pdf>`_, page 64."
|
||||
MWh_MeOH_per_tCO2,LHV,float,"The energy amount of the produced methanol per ton of CO2. From `DECHEMA (2017) <https://dechema.de/dechema_media/Downloads/Positionspapiere/Technology_study_Low_carbon_energy_and_feedstock_for_the_European_chemical_industry-p-20002750.pdf>`_, page 64."
|
||||
MWh_MeOH_per_tCO2,LHV,float,"The energy amount of the produced methanol per ton of CO2. From `DECHEMA (2017) <https://dechema.de/dechema_media/Downloads/Positionspapiere/Technology_study_Low_carbon_energy_and_feedstock_for_the_European_chemical_industry-p-20002750.pdf>`_, page 66."
|
||||
MWh_MeOH_per_MWh_e,LHV,float,"The energy amount of the produced methanol per energy amount of electricity. From `DECHEMA (2017) <https://dechema.de/dechema_media/Downloads/Positionspapiere/Technology_study_Low_carbon_energy_and_feedstock_for_the_European_chemical_industry-p-20002750.pdf>`_, page 64."
|
||||
shipping_hydrogen _liquefaction,--,"{true, false}",Whether to include liquefaction costs for hydrogen demand in shipping.
|
||||
,,,
|
||||
@ -90,7 +90,7 @@ regional_methanol_demand,--,"{true, false}",Spatially resolve methanol demand. S
|
||||
regional_oil_demand,--,"{true, false}",Spatially resolve oil demand. Set to true if regional CO2 constraints needed.
|
||||
regional_co2 _sequestration_potential,,,
|
||||
-- enable,--,"{true, false}",Add option for regionally-resolved geological carbon dioxide sequestration potentials based on `CO2StoP <https://setis.ec.europa.eu/european-co2-storage-database_en>`_.
|
||||
-- attribute,--,string,Name of the attribute for the sequestration potential
|
||||
-- attribute,--,string or list,Name (or list of names) of the attribute(s) for the sequestration potential
|
||||
-- include_onshore,--,"{true, false}",Add options for including onshore sequestration potentials
|
||||
-- min_size,Gt ,float,Any sites with lower potential than this value will be excluded
|
||||
-- max_size,Gt ,float,The maximum sequestration potential for any one site.
|
||||
@ -143,7 +143,7 @@ limit_max_growth,,,
|
||||
-- factor,p.u.,float,The maximum growth factor of a carrier (e.g. 1.3 allows 30% larger than max historic growth)
|
||||
-- max_growth,,,
|
||||
-- -- {carrier},GW,float,The historic maximum growth of a carrier
|
||||
-- max_relative_growth,
|
||||
-- max_relative_growth,,,
|
||||
-- -- {carrier},p.u.,float,The historic maximum relative growth of a carrier
|
||||
,,,
|
||||
enhanced_geothermal,,,
|
||||
|
Can't render this file because it has a wrong number of fields in line 146.
|
@ -4,7 +4,7 @@ options,,,
|
||||
-- load_shedding,bool/float,"{'true','false', float}","Add generators with very high marginal cost to simulate load shedding and avoid problem infeasibilities. If load shedding is a float, it denotes the marginal cost in EUR/kWh."
|
||||
-- noisy_costs,bool,"{'true','false'}","Add random noise to marginal cost of generators by :math:`\mathcal{U}(0.009,0,011)` and capital cost of lines and links by :math:`\mathcal{U}(0.09,0,11)`."
|
||||
-- skip_iterations,bool,"{'true','false'}","Skip iterating, do not update impedances of branches. Defaults to true."
|
||||
-- rolling_horizon,bool,"{'true','false'}","Whether to optimize the network in a rolling horizon manner, where the snapshot range is split into slices of size `horizon` which are solved consecutively."
|
||||
-- rolling_horizon,bool,"{'true','false'}","Switch for rule :mod:`solve_operations_network` whether to optimize the network in a rolling horizon manner, where the snapshot range is split into slices of size `horizon` which are solved consecutively. This setting has currently no effect on sector-coupled networks."
|
||||
-- seed,--,int,Random seed for increased deterministic behaviour.
|
||||
-- custom_extra_functionality,--,str,Path to a Python file with custom extra functionality code to be injected into the solving rules of the workflow relative to ``rules`` directory.
|
||||
-- io_api,string,"{'lp','mps','direct'}",Passed to linopy and determines the API used to communicate with the solver. With the ``'lp'`` and ``'mps'`` options linopy passes a file to the solver; with the ``'direct'`` option (only supported for HIGHS and Gurobi) linopy uses an in-memory python API resulting in better performance.
|
||||
@ -14,13 +14,25 @@ options,,,
|
||||
-- transmission_losses,int,[0-9],"Add piecewise linear approximation of transmission losses based on n tangents. Defaults to 0, which means losses are ignored."
|
||||
-- linearized_unit_commitment,bool,"{'true','false'}",Whether to optimise using the linearized unit commitment formulation.
|
||||
-- horizon,--,int,Number of snapshots to consider in each iteration. Defaults to 100.
|
||||
-- post_discretization,,,
|
||||
-- -- enable,bool,"{'true','false'}",Switch to enable post-discretization of the network. Disabled by default.
|
||||
-- -- line_unit_size,MW,float,Discrete unit size of lines in MW.
|
||||
-- -- line_threshold,,float,The threshold relative to the discrete line unit size beyond which to round up to the next unit.
|
||||
-- -- link_unit_size,MW,float,Discrete unit size of links in MW by carrier (given in dictionary style).
|
||||
-- -- -- {carrier},,,
|
||||
-- -- link_threshold,,float,The threshold relative to the discrete link unit size beyond which to round up to the next unit by carrier (given in dictionary style).
|
||||
-- -- -- {carrier},,,
|
||||
agg_p_nom_limits,,,Configure per carrier generator nominal capacity constraints for individual countries if ``'CCL'`` is in ``{opts}`` wildcard.
|
||||
-- agg_offwind,bool,"{'true','false'}",Aggregate together all the types of offwind when writing the constraint. Default is false.
|
||||
-- include_existing,bool,"{'true','false'}",Take existing capacities into account when writing the constraint. Default is false.
|
||||
-- file,file,path,Reference to ``.csv`` file specifying per carrier generator nominal capacity constraints for individual countries and planning horizons. Defaults to ``data/agg_p_nom_minmax.csv``.
|
||||
constraints ,,,
|
||||
-- CCL,bool,"{'true','false'}",Add minimum and maximum levels of generator nominal capacity per carrier for individual countries. These can be specified in the file linked at ``electricity: agg_p_nom_limits`` in the configuration. File defaults to ``data/agg_p_nom_minmax.csv``.
|
||||
-- EQ,bool/string,"{'false',`n(c| )``; i.e. ``0.5``-``0.7c``}",Require each country or node to on average produce a minimal share of its total consumption itself. Example: ``EQ0.5c`` demands each country to produce on average at least 50% of its consumption; ``EQ0.5`` demands each node to produce on average at least 50% of its consumption.
|
||||
-- BAU,bool,"{'true','false'}",Add a per-``carrier`` minimal overall capacity; i.e. at least ``40GW`` of ``OCGT`` in Europe; configured in ``electricity: BAU_mincapacities``
|
||||
-- SAFE,bool,"{'true','false'}",Add a capacity reserve margin of a certain fraction above the peak demand to which renewable generators and storage do *not* contribute. Ignores network.
|
||||
solver,,,
|
||||
-- name,--,"One of {'gurobi', 'cplex', 'cbc', 'glpk', 'ipopt'}; potentially more possible",Solver to use for optimisation problems in the workflow; e.g. clustering and linear optimal power flow.
|
||||
-- name,--,"One of {'gurobi', 'cplex', 'highs', 'cbc', 'glpk'}; potentially more possible",Solver to use for optimisation problems in the workflow; e.g. clustering and linear optimal power flow.
|
||||
-- options,--,Key listed under ``solver_options``.,Link to specific parameter settings.
|
||||
solver_options,,dict,Dictionaries with solver-specific parameter settings.
|
||||
mem,MB,int,Estimated maximum memory requirement for solving networks.
|
||||
|
|
@ -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
|
||||
@ -90,9 +90,9 @@ For each wildcard, a **list of values** is provided. The rule
|
||||
``results/networks/elec_s{simpl}_{clusters}_ec_l{ll}_{opts}.nc`` for **all
|
||||
combinations** of the provided wildcard values as defined by Python's
|
||||
`itertools.product(...)
|
||||
<https://docs.python.org/2/library/itertools.html#itertools.product>`_ function
|
||||
<https://docs.python.org/2/library/itertools.html#itertools.product>`__ function
|
||||
that snakemake's `expand(...) function
|
||||
<https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#targets>`_
|
||||
<https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#targets>`__
|
||||
uses.
|
||||
|
||||
An exemplary dependency graph (starting from the simplification rules) then looks like this:
|
||||
@ -129,7 +129,7 @@ An exemplary dependency graph (starting from the simplification rules) then look
|
||||
``snapshots``
|
||||
=============
|
||||
|
||||
Specifies the temporal range to build an energy system model for as arguments to `pandas.date_range <https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.date_range.html>`_
|
||||
Specifies the temporal range to build an energy system model for as arguments to `pandas.date_range <https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.date_range.html>`__
|
||||
|
||||
.. literalinclude:: ../config/config.default.yaml
|
||||
:language: yaml
|
||||
@ -174,7 +174,7 @@ Switches for some rules and optional features.
|
||||
:file: configtables/co2_budget.csv
|
||||
|
||||
.. note::
|
||||
this parameter is over-ridden if ``CO2Lx`` or ``cb`` is set in
|
||||
this parameter is over-ridden if ``Co2Lx`` or ``cb`` is set in
|
||||
sector_opts.
|
||||
|
||||
.. _electricity_cf:
|
||||
@ -197,7 +197,7 @@ Switches for some rules and optional features.
|
||||
``atlite``
|
||||
==========
|
||||
|
||||
Define and specify the ``atlite.Cutout`` used for calculating renewable potentials and time-series. All options except for ``features`` are directly used as `cutout parameters <https://atlite.readthedocs.io/en/latest/ref_api.html#cutout>`_.
|
||||
Define and specify the ``atlite.Cutout`` used for calculating renewable potentials and time-series. All options except for ``features`` are directly used as `cutout parameters <https://atlite.readthedocs.io/en/latest/ref_api.html#cutout>`__.
|
||||
|
||||
.. literalinclude:: ../config/config.default.yaml
|
||||
:language: yaml
|
||||
@ -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``
|
||||
---------------
|
||||
|
||||
@ -427,7 +443,7 @@ overwrite the existing values.
|
||||
:widths: 22,7,22,33
|
||||
:file: configtables/biomass.csv
|
||||
|
||||
The list of available biomass is given by the category in `ENSPRESO_BIOMASS <https://cidportal.jrc.ec.europa.eu/ftp/jrc-opendata/ENSPRESO/ENSPRESO_BIOMASS.xlsx>`_, namely:
|
||||
The list of available biomass is given by the category in `ENSPRESO_BIOMASS <https://cidportal.jrc.ec.europa.eu/ftp/jrc-opendata/ENSPRESO/ENSPRESO_BIOMASS.xlsx>`__, namely:
|
||||
|
||||
- Agricultural waste
|
||||
- Manure solid, liquid
|
||||
@ -534,9 +550,6 @@ The list of available biomass is given by the category in `ENSPRESO_BIOMASS <htt
|
||||
:widths: 22,7,22,33
|
||||
:file: configtables/costs.csv
|
||||
|
||||
.. note::
|
||||
``rooftop_share:`` are based on the potentials, assuming
|
||||
(0.1 kW/m2 and 10 m2/person)
|
||||
|
||||
.. _clustering_cf:
|
||||
|
||||
@ -564,7 +577,7 @@ The list of available biomass is given by the category in `ENSPRESO_BIOMASS <htt
|
||||
.. _adjustments_cf:
|
||||
|
||||
``adjustments``
|
||||
=============
|
||||
===============
|
||||
|
||||
.. literalinclude:: ../config/config.default.yaml
|
||||
:language: yaml
|
||||
|
@ -35,3 +35,15 @@ including our own are reviewed by a second person before they are incorporated i
|
||||
If you are unfamiliar with pull requests, the GitHub help pages have a nice `guide <https://help.github.com/en/articles/about-pull-requests>`_.
|
||||
|
||||
To ask and answer general usage questions, join the `PyPSA mailing list <https://groups.google.com/forum/#!forum/pypsa>`_.
|
||||
|
||||
Contributing to the documentation
|
||||
====================================
|
||||
|
||||
We strive to keep documentation useful and up to date for all PyPSA users. If you encounter an area where documentation is not available or insufficient, we very much welcome your contribution. Here is How To:
|
||||
|
||||
#. Install the conda environment for documentation from the `PyPSA repository <https://github.com/PyPSA/PyPSA/blob/master/environment_docs.yml>`_.
|
||||
(Here is `how to install a conda environment <https://pypsa-eur.readthedocs.io/en/latest/installation.html#install-python-dependencies>`_.)
|
||||
#. Make your changes in the corresponding .rst file under ``pypsa-eur/doc``.
|
||||
#. Compile your changes by running the following command in your terminal in the ``doc`` folder: ``make html``
|
||||
You may encounter some warnings, but end up with a message such as ``build succeeded, XX warnings.``. html files to review your changes can then be found under ``doc/_build/html``.
|
||||
#. Contribute your documentation in a pull request (`here is a guide <https://help.github.com/en/articles/about-pull-requests>`_).
|
||||
|
@ -8,7 +8,7 @@ Techno-Economic Assumptions
|
||||
############################
|
||||
|
||||
The database of cost assumptions is retrieved from the repository
|
||||
`PyPSA/technology-data <https://github.com/pypsa/technology-data>`_ and then
|
||||
`PyPSA/technology-data <https://github.com/pypsa/technology-data>`__ and then
|
||||
saved to a file ``resources/costs_{year}.csv``. The ``config/config.yaml`` provides options
|
||||
to choose a reference year and use a specific version of the repository.
|
||||
|
||||
@ -30,7 +30,7 @@ years compiled from various sources, namely for
|
||||
- carbon-dioxide intensity.
|
||||
|
||||
Many values are taken from a database published by the Danish Energy Agency (`DEA
|
||||
<https://ens.dk/en/our-services/projections-and-models/technology-data>`_).
|
||||
<https://ens.dk/en/our-services/projections-and-models/technology-data>`__).
|
||||
|
||||
|
||||
The given overnight capital costs are annualised to net present costs
|
||||
|
@ -166,13 +166,13 @@ Options
|
||||
|
||||
The total carbon budget for the entire transition path can be indicated in the
|
||||
`sector_opts
|
||||
<https://github.com/PyPSA/pypsa-eur-sec/blob/f13902510010b734c510c38c4cae99356f683058/config.default.yaml#L25>`_
|
||||
<https://github.com/PyPSA/pypsa-eur-sec/blob/f13902510010b734c510c38c4cae99356f683058/config.default.yaml#L25>`__
|
||||
in ``config/config.yaml``. The carbon budget can be split among the
|
||||
``planning_horizons`` following an exponential or beta decay. E.g. ``'cb40ex0'``
|
||||
splits a carbon budget equal to 40 Gt :math:`_{CO_2}` following an exponential
|
||||
decay whose initial linear growth rate r is zero. They can also follow some
|
||||
user-specified path, if defined `here
|
||||
<https://github.com/PyPSA/pypsa-eur-sec/blob/413254e241fb37f55b41caba7264644805ad8e97/config.default.yaml#L56>`_.
|
||||
<https://github.com/PyPSA/pypsa-eur-sec/blob/413254e241fb37f55b41caba7264644805ad8e97/config.default.yaml#L56>`__.
|
||||
The paper `Speed of technological transformations required in Europe to achieve
|
||||
different climate goals (2022) <https://doi.org/10.1016/j.joule.2022.04.016>`__
|
||||
defines CO_2 budgets corresponding to global temperature increases (1.5C – 2C)
|
||||
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 533 KiB After Width: | Height: | Size: 533 KiB |
Before Width: | Height: | Size: 269 KiB After Width: | Height: | Size: 269 KiB |
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 2.3 MiB |
Before Width: | Height: | Size: 227 KiB After Width: | Height: | Size: 224 KiB |
Before Width: | Height: | Size: 290 KiB After Width: | Height: | Size: 290 KiB |
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
Before Width: | Height: | Size: 523 KiB After Width: | Height: | Size: 523 KiB |
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
Before Width: | Height: | Size: 801 KiB After Width: | Height: | Size: 801 KiB |
BIN
doc/img/workflow.png
Normal file
After Width: | Height: | Size: 710 KiB |
@ -74,23 +74,23 @@ greenhouse gas emitters except waste management, agriculture, forestry and land
|
||||
use. The diagram below gives an overview of the sectors and the links between
|
||||
them:
|
||||
|
||||
.. image:: ../graphics/multisector_figure.png
|
||||
.. image:: img/multisector_figure.png
|
||||
:width: 70%
|
||||
:align: center
|
||||
|
||||
.. note::
|
||||
You can find showcases of the model's capabilities in the Supplementary Materials of the
|
||||
Joule paper `The potential role of a hydrogen network in Europe
|
||||
<https://doi.org/10.1016/j.joule.2023.06.016>`_, the Supplementary Materials of another `paper in Joule with a
|
||||
<https://doi.org/10.1016/j.joule.2023.06.016>`__, the Supplementary Materials of another `paper in Joule with a
|
||||
description of the industry sector
|
||||
<https://doi.org/10.1016/j.joule.2022.04.016>`_, or in `a 2021 presentation
|
||||
at EMP-E <https://nworbmot.org/energy/brown-empe.pdf>`_.
|
||||
<https://doi.org/10.1016/j.joule.2022.04.016>`__, or in `a 2021 presentation
|
||||
at EMP-E <https://nworbmot.org/energy/brown-empe.pdf>`__.
|
||||
The sector-coupled extension of PyPSA-Eur was
|
||||
initially described in the paper `Synergies of sector coupling and transmission
|
||||
reinforcement in a cost-optimised, highly renewable European energy system
|
||||
<https://arxiv.org/abs/1801.05290>`_ (2018) but it differs by being based on the
|
||||
<https://arxiv.org/abs/1801.05290>`__ (2018) but it differs by being based on the
|
||||
higher resolution electricity transmission model `PyPSA-Eur
|
||||
<https://github.com/PyPSA/pypsa-eur>`_ rather than a one-node-per-country model,
|
||||
<https://github.com/PyPSA/pypsa-eur>`__ rather than a one-node-per-country model,
|
||||
and by including biomass, industry, industrial feedstocks, aviation, shipping,
|
||||
better carbon management, carbon capture and usage/sequestration, and gas
|
||||
networks.
|
||||
@ -99,8 +99,8 @@ About
|
||||
=====
|
||||
|
||||
PyPSA-Eur is designed to be imported into the open energy system modelling
|
||||
framework `PyPSA <https://www.pypsa.org>`_ for which `documentation
|
||||
<https://pypsa.readthedocs.io>`_ is available as well. However, since the
|
||||
framework `PyPSA <https://www.pypsa.org>`__ for which `documentation
|
||||
<https://pypsa.readthedocs.io>`__ is available as well. However, since the
|
||||
workflow is modular, it should be easy to adapt the data workflow to other
|
||||
modelling frameworks.
|
||||
|
||||
@ -114,28 +114,28 @@ of the individual parts.
|
||||
PyPSA-Eur is under active development and has several
|
||||
:doc:`limitations` which
|
||||
you should understand before using the model. The Github repository
|
||||
`issues <https://github.com/PyPSA/pypsa-eur/issues>`_ collect known
|
||||
`issues <https://github.com/PyPSA/pypsa-eur/issues>`__ collect known
|
||||
topics we are working on. Please feel free to help or make suggestions.
|
||||
|
||||
This project is currently maintained by the `Department of Digital
|
||||
Transformation in Energy Systems <https://www.tu.berlin/en/ensys>`_ at the
|
||||
`Technische Universität Berlin <https://www.tu.berlin>`_. Previous versions were
|
||||
developed within the `IAI <http://www.iai.kit.edu>`_ at the `Karlsruhe Institute
|
||||
of Technology (KIT) <http://www.kit.edu/english/index.php>`_ which was funded by
|
||||
the `Helmholtz Association <https://www.helmholtz.de/en/>`_, and by the
|
||||
Transformation in Energy Systems <https://www.tu.berlin/en/ensys>`__ at the
|
||||
`Technische Universität Berlin <https://www.tu.berlin>`__. Previous versions were
|
||||
developed within the `IAI <http://www.iai.kit.edu>`__ at the `Karlsruhe Institute
|
||||
of Technology (KIT) <http://www.kit.edu/english/index.php>`__ which was funded by
|
||||
the `Helmholtz Association <https://www.helmholtz.de/en/>`__, and by the
|
||||
`Renewable Energy Group
|
||||
<https://fias.uni-frankfurt.de/physics/schramm/renewable-energy-system-and-network-analysis/>`_
|
||||
at `FIAS <https://fias.uni-frankfurt.de/>`_ to carry out simulations for the
|
||||
`CoNDyNet project <http://condynet.de/>`_, financed by the `German Federal
|
||||
Ministry for Education and Research (BMBF) <https://www.bmbf.de/en/index.html>`_
|
||||
<https://fias.uni-frankfurt.de/physics/schramm/renewable-energy-system-and-network-analysis/>`__
|
||||
at `FIAS <https://fias.uni-frankfurt.de/>`__ to carry out simulations for the
|
||||
`CoNDyNet project <http://condynet.de/>`__, financed by the `German Federal
|
||||
Ministry for Education and Research (BMBF) <https://www.bmbf.de/en/index.html>`__
|
||||
as part of the `Stromnetze Research Initiative
|
||||
<http://forschung-stromnetze.info/projekte/grundlagen-und-konzepte-fuer-effiziente-dezentrale-stromnetze/>`_.
|
||||
<http://forschung-stromnetze.info/projekte/grundlagen-und-konzepte-fuer-effiziente-dezentrale-stromnetze/>`__.
|
||||
|
||||
|
||||
Workflow
|
||||
========
|
||||
|
||||
.. image:: ../graphics/workflow.png
|
||||
.. image:: img/workflow.png
|
||||
:class: full-width
|
||||
:align: center
|
||||
|
||||
@ -153,10 +153,10 @@ to reading this documentation.
|
||||
|
||||
- Documentation of `PyPSA <https://pypsa.readthedocs.io>`__, the package for
|
||||
modelling energy systems which PyPSA-Eur uses under the hood.
|
||||
- Course on `Energy Systems <https://nworbmot.org/courses/es-22/>`_ given at
|
||||
Technical University of Berlin by `Prof. Dr. Tom Brown <https://nworbmot.org>`_.
|
||||
- Course on `Data Science for Energy System Modelling <https://fneum.github.io/data-science-for-esm/intro.html>`_
|
||||
given at Technical University of Berlin by `Dr. Fabian Neumann <https://neumann.fyi>`_.
|
||||
- Course on `Energy Systems <https://nworbmot.org/courses/es-22/>`__ given at
|
||||
Technical University of Berlin by `Prof. Dr. Tom Brown <https://nworbmot.org>`__.
|
||||
- Course on `Data Science for Energy System Modelling <https://fneum.github.io/data-science-for-esm/intro.html>`__
|
||||
given at Technical University of Berlin by `Dr. Fabian Neumann <https://neumann.fyi>`__.
|
||||
|
||||
|
||||
Citing PyPSA-Eur
|
||||
|
@ -15,7 +15,7 @@ directory in which the commands following the ``%`` should be entered.
|
||||
Clone the Repository
|
||||
====================
|
||||
|
||||
First of all, clone the `PyPSA-Eur repository <https://github.com/PyPSA/pypsa-eur>`_ using the version control system ``git`` in the command line.
|
||||
First of all, clone the `PyPSA-Eur repository <https://github.com/PyPSA/pypsa-eur>`__ using the version control system ``git`` in the command line.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
@ -30,11 +30,11 @@ Install Python Dependencies
|
||||
===============================
|
||||
|
||||
PyPSA-Eur relies on a set of other Python packages to function.
|
||||
We recommend using the package manager `mamba <https://mamba.readthedocs.io/en/latest/>`_ to install them and manage your environments.
|
||||
For instructions for your operating system follow the ``mamba`` `installation guide <https://mamba.readthedocs.io/en/latest/installation/mamba-installation.html>`_.
|
||||
We recommend using the package manager `mamba <https://mamba.readthedocs.io/en/latest/>`__ to install them and manage your environments.
|
||||
For instructions for your operating system follow the ``mamba`` `installation guide <https://mamba.readthedocs.io/en/latest/installation/mamba-installation.html>`__.
|
||||
You can also use ``conda`` equivalently.
|
||||
|
||||
The package requirements are curated in the `envs/environment.yaml <https://github.com/PyPSA/pypsa-eur/blob/master/envs/environment.yaml>`_ file.
|
||||
The package requirements are curated in the `envs/environment.yaml <https://github.com/PyPSA/pypsa-eur/blob/master/envs/environment.yaml>`__ file.
|
||||
The environment can be installed and activated using
|
||||
|
||||
.. code:: bash
|
||||
@ -59,16 +59,16 @@ Install a Solver
|
||||
PyPSA passes the PyPSA-Eur network model to an external solver for performing the optimisation.
|
||||
PyPSA is known to work with the free software
|
||||
|
||||
- `HiGHS <https://highs.dev/>`_
|
||||
- `Cbc <https://projects.coin-or.org/Cbc#DownloadandInstall>`_
|
||||
- `GLPK <https://www.gnu.org/software/glpk/>`_ (`WinGLKP <http://winglpk.sourceforge.net/>`_)
|
||||
- `Ipopt <https://coin-or.github.io/Ipopt/INSTALL.html>`_
|
||||
- `HiGHS <https://highs.dev/>`__
|
||||
- `Cbc <https://projects.coin-or.org/Cbc#DownloadandInstall>`__
|
||||
- `GLPK <https://www.gnu.org/software/glpk/>`__ (`WinGLKP <http://winglpk.sourceforge.net/>`__)
|
||||
- `SCIP <https://scipopt.github.io/PySCIPOpt/docs/html/index.html>`__
|
||||
|
||||
and the non-free, commercial software (for some of which free academic licenses are available)
|
||||
|
||||
- `Gurobi <https://www.gurobi.com/documentation/quickstart.html>`_
|
||||
- `CPLEX <https://www.ibm.com/products/ilog-cplex-optimization-studio>`_
|
||||
- `FICO Xpress Solver <https://www.fico.com/de/products/fico-xpress-solver>`_
|
||||
- `Gurobi <https://www.gurobi.com/documentation/quickstart.html>`__
|
||||
- `CPLEX <https://www.ibm.com/products/ilog-cplex-optimization-studio>`__
|
||||
- `FICO Xpress Solver <https://www.fico.com/de/products/fico-xpress-solver>`__
|
||||
|
||||
For installation instructions of these solvers for your operating system, follow the links above.
|
||||
Commercial solvers such as Gurobi and CPLEX currently significantly outperform open-source solvers for large-scale problems, and
|
||||
@ -76,11 +76,11 @@ it might be the case that you can only retrieve solutions by using a commercial
|
||||
Nevertheless, you can still use open-source solvers for smaller problems.
|
||||
|
||||
.. seealso::
|
||||
`Instructions how to install a solver in the documentation of PyPSA <https://pypsa.readthedocs.io/en/latest/installation.html#getting-a-solver-for-linear-optimisation>`_
|
||||
`Instructions how to install a solver in the documentation of PyPSA <https://pypsa.readthedocs.io/en/latest/installation.html#getting-a-solver-for-linear-optimisation>`__
|
||||
|
||||
.. note::
|
||||
The rules :mod:`cluster_network` and :mod:`simplify_network` solve a mixed-integer quadratic optimisation problem for clustering.
|
||||
The open-source solvers HiGHS, Cbc and GlPK cannot handle this. A fallback to SCIP is implemented in this case.
|
||||
The open-source solvers HiGHS, Cbc and GlPK cannot handle this. A fallback to SCIP is implemented in this case, which is included in the standard environment specifications.
|
||||
For an open-source solver setup install in your ``conda`` environment on OSX/Linux. To install the default solver Gurobi, run
|
||||
|
||||
.. code:: bash
|
||||
@ -88,7 +88,7 @@ Nevertheless, you can still use open-source solvers for smaller problems.
|
||||
mamba activate pypsa-eur
|
||||
mamba install -c gurobi gurobi
|
||||
|
||||
Additionally, you need to setup your `Gurobi license <https://www.gurobi.com/solutions/licensing/>`_.
|
||||
Additionally, you need to setup your `Gurobi license <https://www.gurobi.com/solutions/licensing/>`__.
|
||||
|
||||
|
||||
.. _defaultconfig:
|
||||
|
@ -14,7 +14,7 @@
|
||||
<iframe width="832" height="468" src="https://www.youtube.com/embed/ty47YU1_eeQ" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
|
||||
.. note::
|
||||
Find the introductory slides `here <https://docs.google.com/presentation/d/e/2PACX-1vQGQZD7KIVdocRZzRVu8Uk-JC_ltEow5zjtIarhyws46IMJpaqGuux695yincmJA_i5bVEibEs7z2eo/pub?start=false&loop=true&delayms=3000>`_.
|
||||
Find the introductory slides `here <https://docs.google.com/presentation/d/e/2PACX-1vQGQZD7KIVdocRZzRVu8Uk-JC_ltEow5zjtIarhyws46IMJpaqGuux695yincmJA_i5bVEibEs7z2eo/pub?start=false&loop=true&delayms=3000>`__.
|
||||
|
||||
.. warning::
|
||||
The video only introduces the electricity-only part of PyPSA-Eur.
|
||||
@ -23,7 +23,7 @@ Workflow
|
||||
=========
|
||||
|
||||
The generation of the model is controlled by the open workflow management system
|
||||
`Snakemake <https://snakemake.github.io/>`_. In a nutshell, the ``Snakefile``
|
||||
`Snakemake <https://snakemake.github.io/>`__. In a nutshell, the ``Snakefile``
|
||||
declares for each script in the ``scripts`` directory a rule which describes
|
||||
which files the scripts consume and produce (their corresponding input and
|
||||
output files). The ``snakemake`` tool then runs the scripts in the correct order
|
||||
@ -35,7 +35,7 @@ For instance, an invocation to
|
||||
|
||||
.. code:: bash
|
||||
|
||||
.../pypsa-eur % snakemake -call results/networks/elec_s_128_ec_lvopt_Co2L-3H.nc
|
||||
.../pypsa-eur % snakemake -call results/networks/elec_s_128_ec_lvopt_.nc
|
||||
|
||||
follows this dependency graph
|
||||
|
||||
@ -50,13 +50,13 @@ preceding rules which another rule takes as input data.
|
||||
|
||||
.. note::
|
||||
The dependency graph was generated using
|
||||
``snakemake --dag results/networks/elec_s_128_ec_lvopt_Co2L-3H.nc -F | sed -n "/digraph/,/}/p" | dot -Tpng -o doc/img/intro-workflow.png``
|
||||
``snakemake --dag results/networks/elec_s_128_ec_lvopt_.nc -F | sed -n "/digraph/,/}/p" | dot -Tpng -o doc/img/intro-workflow.png``
|
||||
|
||||
For the use of ``snakemake``, it makes sense to familiarize yourself quickly
|
||||
with the `basic tutorial
|
||||
<https://snakemake.readthedocs.io/en/stable/tutorial/basics.html>`_ and then
|
||||
<https://snakemake.readthedocs.io/en/stable/tutorial/basics.html>`__ and then
|
||||
read carefully through the documentation of the `command line interface
|
||||
<https://snakemake.readthedocs.io/en/stable/executing/cli.html>`_, noting the
|
||||
<https://snakemake.readthedocs.io/en/stable/executing/cli.html>`__, noting the
|
||||
arguments ``-j``, ``-c``, ``-f``, ``-F``, ``-n``, ``-r``, ``--dag`` and ``-t``
|
||||
in particular.
|
||||
|
||||
@ -64,10 +64,10 @@ Scenarios, Configuration and Modification
|
||||
=========================================
|
||||
|
||||
It is easy to run PyPSA-Eur for multiple scenarios using the `wildcards feature
|
||||
<https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#wildcards>`_
|
||||
<https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#wildcards>`__
|
||||
of ``snakemake``. Wildcards allow to generalise a rule to produce all files that
|
||||
follow a `regular expression
|
||||
<https://en.wikipedia.org/wiki/Regular_expression>`_ pattern, which defines
|
||||
<https://en.wikipedia.org/wiki/Regular_expression>`__ pattern, which defines
|
||||
a particular scenario. One can think of a wildcard as a parameter that shows
|
||||
up in the input/output file names and thereby determines which rules to run,
|
||||
what data to retrieve and what files to produce. Details are explained in
|
||||
@ -97,5 +97,5 @@ System Requirements
|
||||
|
||||
Building the model with the scripts in this repository runs on a regular computer.
|
||||
But optimising for investment and operation decisions across many scenarios requires a strong interior-point solver
|
||||
like `Gurobi <http://www.gurobi.com/>`_ or `CPLEX <https://www.ibm.com/analytics/cplex-optimizer>`_ with more memory.
|
||||
like `Gurobi <http://www.gurobi.com/>`__ or `CPLEX <https://www.ibm.com/analytics/cplex-optimizer>`__ with more memory.
|
||||
Open-source solvers like `HiGHS <https://highs.dev>` can also be used for smaller problems.
|
||||
|
@ -10,12 +10,12 @@ Licenses
|
||||
|
||||
PyPSA-Eur is released under multiple licenses:
|
||||
|
||||
* All original source code is licensed as free software under `MIT <LICENSES/MIT.txt>`_.
|
||||
* The documentation is licensed under `CC-BY-4.0 <LICENSES/CC-BY-4.0.txt>`_.
|
||||
* Configuration files are mostly licensed under `CC0-1.0 <LICENSES/CC0-1.0.txt>`_.
|
||||
* Data files are licensed under `CC-BY-4.0 <LICENSES/CC-BY-4.0.txt>`_.
|
||||
* All original source code is licensed as free software under `MIT <LICENSES/MIT.txt>`__.
|
||||
* The documentation is licensed under `CC-BY-4.0 <LICENSES/CC-BY-4.0.txt>`__.
|
||||
* Configuration files are mostly licensed under `CC0-1.0 <LICENSES/CC0-1.0.txt>`__.
|
||||
* Data files are licensed under `CC-BY-4.0 <LICENSES/CC-BY-4.0.txt>`__.
|
||||
|
||||
See the individual files and the `dep5 <.reuse/dep5>`_ file for license details.
|
||||
See the individual files and the `dep5 <.reuse/dep5>`__ file for license details.
|
||||
|
||||
Additionally, different licenses and terms of use also apply to the various
|
||||
input data for both electricity-only and sector-coupled modelling exercises,
|
||||
@ -26,18 +26,15 @@ Electricity Systems Databundle
|
||||
|
||||
.. note::
|
||||
More details are included in `the description of the
|
||||
data bundles on zenodo <https://zenodo.org/record/3517935#.XbGeXvzRZGo>`_.
|
||||
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
:file: configtables/licenses.csv
|
||||
data bundles on zenodo <https://zenodo.org/record/3517935#.XbGeXvzRZGo>`__.
|
||||
|
||||
* BY: Attribute Source
|
||||
* NC: Non-Commercial Use Only
|
||||
* SA: Share Alike
|
||||
|
||||
Sector-Coupled Systems Databundle
|
||||
=================================
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
:file: configtables/licenses.csv
|
||||
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
|
@ -19,7 +19,7 @@ improving the approximations.
|
||||
This list of limitations is incomplete and will be added to over time.
|
||||
|
||||
.. seealso::
|
||||
See also the `GitHub repository issues <https://github.com/PyPSA/pypsa-eur/issues>`_.
|
||||
See also the `GitHub repository issues <https://github.com/PyPSA/pypsa-eur/issues>`__.
|
||||
|
||||
- **Electricity transmission network topology:**
|
||||
The grid data is based on a map of the ENTSO-E area that is known
|
||||
|
@ -15,19 +15,17 @@ Instead we provide separate data bundles which can be obtained
|
||||
using the ``retrieve*`` rules (:ref:`data`).
|
||||
Having downloaded the necessary data,
|
||||
|
||||
- :mod:`build_shapes` generates GeoJSON files with shapes of the countries, exclusive economic zones and `NUTS3 <https://en.wikipedia.org/wiki/Nomenclature_of_Territorial_Units_for_Statistics>`_ areas.
|
||||
- :mod:`build_cutout` prepares smaller weather data portions from `ERA5 <https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5>`_ for cutout ``europe-2013-era5`` and SARAH for cutout ``europe-2013-sarah``.
|
||||
- :mod:`build_shapes` generates GeoJSON files with shapes of the countries, exclusive economic zones and `NUTS3 <https://en.wikipedia.org/wiki/Nomenclature_of_Territorial_Units_for_Statistics>`__ areas.
|
||||
- :mod:`build_cutout` prepares smaller weather data portions from `ERA5 <https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5>`__ for cutout ``europe-2013-era5`` and SARAH for cutout ``europe-2013-sarah``.
|
||||
|
||||
With these and the externally extracted ENTSO-E online map topology
|
||||
(``data/entsoegridkit``), it can build a base PyPSA network with the following rules:
|
||||
|
||||
- :mod:`base_network` builds and stores the base network with all buses, HVAC lines and HVDC links, while
|
||||
- :mod:`build_bus_regions` determines `Voronoi cells <https://en.wikipedia.org/wiki/Voronoi_diagram>`_ for all substations.
|
||||
- :mod:`base_network` builds and stores the base network with all buses, HVAC lines and HVDC links, and determines `Voronoi cells <https://en.wikipedia.org/wiki/Voronoi_diagram>`__ for all substations.
|
||||
|
||||
Then the process continues by calculating conventional power plant capacities, potentials, and per-unit availability time series for variable renewable energy carriers and hydro power plants with the following rules:
|
||||
|
||||
- :mod:`build_powerplants` for today's thermal power plant capacities using `powerplantmatching <https://github.com/FRESNA/powerplantmatching>`_ allocating these to the closest substation for each powerplant,
|
||||
- :mod:`build_natura_raster` for rasterising NATURA2000 natural protection areas,
|
||||
- :mod:`build_powerplants` for today's thermal power plant capacities using `powerplantmatching <https://github.com/FRESNA/powerplantmatching>`__ allocating these to the closest substation for each powerplant,
|
||||
- :mod:`build_ship_raster` for building shipping traffic density,
|
||||
- :mod:`build_renewable_profiles` for the hourly capacity factors and installation potentials constrained by land-use in each substation's Voronoi cell for PV, onshore and offshore wind, and
|
||||
- :mod:`build_hydro_profile` for the hourly per-unit hydro power availability time series.
|
||||
@ -35,13 +33,6 @@ Then the process continues by calculating conventional power plant capacities, p
|
||||
The central rule :mod:`add_electricity` then ties all the different data inputs
|
||||
together into a detailed PyPSA network stored in ``networks/elec.nc``.
|
||||
|
||||
.. _busregions:
|
||||
|
||||
Rule ``build_bus_regions``
|
||||
=============================
|
||||
|
||||
.. automodule:: build_bus_regions
|
||||
|
||||
.. _cutout:
|
||||
|
||||
Rule ``build_cutout``
|
||||
@ -55,14 +46,6 @@ Rule ``prepare_links_p_nom``
|
||||
|
||||
.. automodule:: prepare_links_p_nom
|
||||
|
||||
.. _natura:
|
||||
|
||||
Rule ``build_natura_raster``
|
||||
===============================
|
||||
|
||||
.. automodule:: build_natura_raster
|
||||
|
||||
|
||||
.. _base:
|
||||
|
||||
Rule ``base_network``
|
||||
|
@ -25,12 +25,12 @@ Rule ``retrieve_cutout``
|
||||
.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.6382570.svg
|
||||
:target: https://doi.org/10.5281/zenodo.6382570
|
||||
|
||||
Cutouts are spatio-temporal subsets of the European weather data from the `ECMWF ERA5 <https://software.ecmwf.int/wiki/display/CKB/ERA5+data+documentation>`_ reanalysis dataset and the `CMSAF SARAH-2 <https://wui.cmsaf.eu/safira/action/viewDoiDetails?acronym=SARAH_V002>`_ solar surface radiation dataset for the year 2013.
|
||||
They have been prepared by and are for use with the `atlite <https://github.com/PyPSA/atlite>`_ tool. You can either generate them yourself using the ``build_cutouts`` rule or retrieve them directly from `zenodo <https://doi.org/10.5281/zenodo.6382570>`__ through the rule ``retrieve_cutout``.
|
||||
Cutouts are spatio-temporal subsets of the European weather data from the `ECMWF ERA5 <https://software.ecmwf.int/wiki/display/CKB/ERA5+data+documentation>`__ reanalysis dataset and the `CMSAF SARAH-2 <https://wui.cmsaf.eu/safira/action/viewDoiDetails?acronym=SARAH_V002>`__ solar surface radiation dataset for the year 2013.
|
||||
They have been prepared by and are for use with the `atlite <https://github.com/PyPSA/atlite>`__ tool. You can either generate them yourself using the ``build_cutouts`` rule or retrieve them directly from `zenodo <https://doi.org/10.5281/zenodo.6382570>`__ through the rule ``retrieve_cutout``.
|
||||
The :ref:`tutorial` uses a smaller cutout than required for the full model (30 MB), which is also automatically downloaded.
|
||||
|
||||
.. note::
|
||||
To download cutouts yourself from the `ECMWF ERA5 <https://software.ecmwf.int/wiki/display/CKB/ERA5+data+documentation>`_ you need to `set up the CDS API <https://cds.climate.copernicus.eu/api-how-to>`_.
|
||||
To download cutouts yourself from the `ECMWF ERA5 <https://software.ecmwf.int/wiki/display/CKB/ERA5+data+documentation>`__ you need to `set up the CDS API <https://cds.climate.copernicus.eu/api-how-to>`__.
|
||||
|
||||
|
||||
**Relevant Settings**
|
||||
@ -47,43 +47,17 @@ The :ref:`tutorial` uses a smaller cutout than required for the full model (30 M
|
||||
|
||||
**Outputs**
|
||||
|
||||
- ``cutouts/{cutout}``: weather data from either the `ERA5 <https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5>`_ reanalysis weather dataset or `SARAH-2 <https://wui.cmsaf.eu/safira/action/viewProduktSearch>`_ satellite-based historic weather data.
|
||||
- ``cutouts/{cutout}``: weather data from either the `ERA5 <https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5>`__ reanalysis weather dataset or `SARAH-2 <https://wui.cmsaf.eu/safira/action/viewProduktSearch>`__ satellite-based historic weather data.
|
||||
|
||||
.. seealso::
|
||||
For details see :mod:`build_cutout` and read the `atlite documentation <https://atlite.readthedocs.io>`_.
|
||||
For details see :mod:`build_cutout` and read the `atlite documentation <https://atlite.readthedocs.io>`__.
|
||||
|
||||
|
||||
Rule ``retrieve_natura_raster``
|
||||
================================
|
||||
|
||||
.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.4706686.svg
|
||||
:target: https://doi.org/10.5281/zenodo.4706686
|
||||
|
||||
This rule, as a substitute for :mod:`build_natura_raster`, downloads an already rasterized version (`natura.tiff <https://zenodo.org/record/4706686/files/natura.tiff>`_) of `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas to reduce computation times. The file is placed into the ``resources`` sub-directory.
|
||||
|
||||
**Relevant Settings**
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
enable:
|
||||
build_natura_raster:
|
||||
|
||||
.. seealso::
|
||||
Documentation of the configuration file ``config/config.yaml`` at
|
||||
:ref:`toplevel_cf`
|
||||
|
||||
**Outputs**
|
||||
|
||||
- ``resources/natura.tiff``: Rasterized version of `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas to reduce computation times.
|
||||
|
||||
.. seealso::
|
||||
For details see :mod:`build_natura_raster`.
|
||||
|
||||
|
||||
Rule ``retrieve_electricity_demand``
|
||||
====================================
|
||||
|
||||
This rule downloads hourly electric load data for each country from the `OPSD platform <https://data.open-power-system-data.org/time_series/2019-06-05/time_series_60min_singleindex.csv>`_.
|
||||
This rule downloads hourly electric load data for each country from the `OPSD platform <https://data.open-power-system-data.org/time_series/2019-06-05/time_series_60min_singleindex.csv>`__.
|
||||
|
||||
**Relevant Settings**
|
||||
|
||||
@ -97,7 +71,7 @@ None.
|
||||
Rule ``retrieve_cost_data``
|
||||
================================
|
||||
|
||||
This rule downloads techno-economic assumptions from the `technology-data repository <https://github.com/pypsa/technology-data>`_.
|
||||
This rule downloads techno-economic assumptions from the `technology-data repository <https://github.com/pypsa/technology-data>`__.
|
||||
|
||||
**Relevant Settings**
|
||||
|
||||
@ -118,15 +92,10 @@ This rule downloads techno-economic assumptions from the `technology-data reposi
|
||||
|
||||
- ``resources/costs.csv``
|
||||
|
||||
Rule ``retrieve_irena``
|
||||
================================
|
||||
|
||||
.. automodule:: retrieve_irena
|
||||
|
||||
Rule ``retrieve_ship_raster``
|
||||
================================
|
||||
|
||||
This rule downloads data on global shipping traffic density from the `World Bank Data Catalogue <https://datacatalog.worldbank.org/search/dataset/0037580/Global-Shipping-Traffic-Density>`_.
|
||||
This rule downloads data on global shipping traffic density from the `World Bank Data Catalogue <https://datacatalog.worldbank.org/search/dataset/0037580/Global-Shipping-Traffic-Density>`__.
|
||||
|
||||
**Relevant Settings**
|
||||
|
||||
@ -135,14 +104,3 @@ None.
|
||||
**Outputs**
|
||||
|
||||
- ``data/shipdensity_global.zip``
|
||||
|
||||
|
||||
Rule ``retrieve_sector_databundle``
|
||||
====================================
|
||||
|
||||
.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.5546516.svg
|
||||
:target: https://doi.org/10.5281/zenodo.5546516
|
||||
|
||||
In addition to the databundle required for electricity-only studies,
|
||||
another databundle is required for modelling sector-coupled systems.
|
||||
The size of this data bundle is around 640 MB.
|
||||
|
@ -7,8 +7,15 @@
|
||||
Building Sector-Coupled Networks
|
||||
##########################################
|
||||
|
||||
.. warning::
|
||||
This part of the documentation is under development.
|
||||
The preparation process of the sector-coupled version of the PyPSA-Eur energy system model consists of a group of ``snakemake`` rules which are briefly outlined and explained in detail in the sections below.
|
||||
|
||||
Not all data dependencies are shipped with the git repository.
|
||||
Instead we provide separate data bundles which can be obtained
|
||||
using the ``retrieve*`` rules (:ref:`data`).
|
||||
Having downloaded the necessary data,
|
||||
|
||||
- :mod:`add_brownfield` builds and stores the base network with all buses, HVAC lines and HVDC links, while
|
||||
|
||||
|
||||
Rule ``add_brownfield``
|
||||
==============================================================================
|
||||
@ -176,6 +183,11 @@ Rule ``cluster_gas_network``
|
||||
|
||||
.. automodule:: cluster_gas_network
|
||||
|
||||
Rule ``time_aggregation``
|
||||
==============================================================================
|
||||
|
||||
.. automodule:: time_aggregation
|
||||
|
||||
Rule ``prepare_sector_network``
|
||||
==============================================================================
|
||||
|
||||
|
@ -12,11 +12,11 @@ Simplifying Electricity Networks
|
||||
The simplification ``snakemake`` rules prepare **approximations** of the full model, for which it is computationally viable to co-optimize generation, storage and transmission capacities.
|
||||
|
||||
- :mod:`simplify_network` transforms the transmission grid to a 380 kV only equivalent network, while
|
||||
- :mod:`cluster_network` uses a `k-means <https://en.wikipedia.org/wiki/K-means_clustering>`_ based clustering technique to partition the network into a given number of zones and then reduce the network to a representation with one bus per zone.
|
||||
- :mod:`cluster_network` uses a `k-means <https://en.wikipedia.org/wiki/K-means_clustering>`__ based clustering technique to partition the network into a given number of zones and then reduce the network to a representation with one bus per zone.
|
||||
|
||||
The simplification and clustering steps are described in detail in the paper
|
||||
|
||||
- Jonas Hörsch and Tom Brown. `The role of spatial scale in joint optimisations of generation and transmission for European highly renewable scenarios <https://arxiv.org/abs/1705.07617>`_), *14th International Conference on the European Energy Market*, 2017. `arXiv:1705.07617 <https://arxiv.org/abs/1705.07617>`_, `doi:10.1109/EEM.2017.7982024 <https://doi.org/10.1109/EEM.2017.7982024>`_.
|
||||
- Jonas Hörsch and Tom Brown. `The role of spatial scale in joint optimisations of generation and transmission for European highly renewable scenarios <https://arxiv.org/abs/1705.07617>`__), *14th International Conference on the European Energy Market*, 2017. `arXiv:1705.07617 <https://arxiv.org/abs/1705.07617>`__, `doi:10.1109/EEM.2017.7982024 <https://doi.org/10.1109/EEM.2017.7982024>`__.
|
||||
|
||||
After simplification and clustering of the network, additional components may be appended in the rule :mod:`add_extra_components` and the network is prepared for solving in :mod:`prepare_network`.
|
||||
|
||||
|
@ -9,19 +9,19 @@
|
||||
Spatial resolution
|
||||
##########################################
|
||||
|
||||
The default nodal resolution of the model follows the electricity generation and transmission model `PyPSA-Eur <https://github.com/PyPSA/pypsa-eur>`_, which clusters down the electricity transmission substations in each European country based on the k-means algorithm (See `cluster_network <https://pypsa-eur.readthedocs.io/en/latest/simplification/cluster_network.html#rule-cluster-network>`_ for a complete explanation). This gives nodes which correspond to major load and generation centres (typically cities).
|
||||
The default nodal resolution of the model follows the electricity generation and transmission model `PyPSA-Eur <https://github.com/PyPSA/pypsa-eur>`__, which clusters down the electricity transmission substations in each European country based on the k-means algorithm (See `cluster_network <https://pypsa-eur.readthedocs.io/en/latest/simplification/cluster_network.html#rule-cluster-network>`__ for a complete explanation). This gives nodes which correspond to major load and generation centres (typically cities).
|
||||
|
||||
The total number of nodes for Europe is set in the ``config/config.yaml`` file under ``clusters``. The number of nodes can vary between 37, the number of independent countries / synchronous areas, and several hundred. With 200-300 nodes the model needs 100-150 GB RAM to solve with a commercial solver like Gurobi.
|
||||
|
||||
Exemplary unsolved network clustered to 512 nodes:
|
||||
|
||||
.. image:: ../graphics/elec_s_512.png
|
||||
.. image:: img/elec_s_512.png
|
||||
|
||||
Exemplary unsolved network clustered to 37 nodes:
|
||||
|
||||
.. image:: ../graphics/elec_s_37.png
|
||||
.. image:: img/elec_s_37.png
|
||||
|
||||
The total number of nodes for Europe is set in the ``config/config.yaml`` file under `clusters <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L20>`_. The number of nodes can vary between 37, the number of independent countries/synchronous areas, and several hundred. With 200-300 nodes, the model needs 100-150 GB RAM to solve with a commercial solver like Gurobi.
|
||||
The total number of nodes for Europe is set in the ``config/config.yaml`` file under `clusters <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L20>`__. The number of nodes can vary between 37, the number of independent countries/synchronous areas, and several hundred. With 200-300 nodes, the model needs 100-150 GB RAM to solve with a commercial solver like Gurobi.
|
||||
Not all of the sectors are at the full nodal resolution, and some demand for some sectors is distributed to nodes using heuristics that need to be corrected. Some networks are copper-plated to reduce computational times.
|
||||
|
||||
Here are some examples of how spatial resolution is set for different sectors in PyPSA-Eur-Sec:
|
||||
@ -37,18 +37,18 @@ Here are some examples of how spatial resolution is set for different sectors in
|
||||
• Electricity demand in industry: Modeled as nodal, based on the location of industrial facilities from HotMaps database.
|
||||
|
||||
• Industry demand (heat, chemicals, etc.) : Modeled as nodal, distributed in each country based on locations of industry from HotMaps database.
|
||||
• Hydrogen network: Modeled as nodal (if activated in the `config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L260>`_ file).
|
||||
• Hydrogen network: Modeled as nodal (if activated in the `config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L260>`__ file).
|
||||
|
||||
• Methane network: It can be modeled as a single node for Europe or it can be nodally resolved if activated in the `config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L266>`_. One node can be considered reasonable since future demand is expected to be low and no bottlenecks are expected. Also, the nodally resolved methane grid is based on SciGRID_gas data.
|
||||
• Methane network: It can be modeled as a single node for Europe or it can be nodally resolved if activated in the `config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L266>`__. One node can be considered reasonable since future demand is expected to be low and no bottlenecks are expected. Also, the nodally resolved methane grid is based on SciGRID_gas data.
|
||||
|
||||
• Solid biomass: It can be modeled as a single node for Europe or it can be nodally resolved if activated in the `config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L270>`_. Nodal modeling includes modeling biomass potential per country (given per country, then distributed by population density within) and the transport of solid biomass between countries.
|
||||
• Solid biomass: It can be modeled as a single node for Europe or it can be nodally resolved if activated in the `config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L270>`__. Nodal modeling includes modeling biomass potential per country (given per country, then distributed by population density within) and the transport of solid biomass between countries.
|
||||
|
||||
• CO2: It can be modeled as a single node for Europe or it can be nodally resolved with CO2 transport pipelines if activated in the `config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L248>`_. It should mentioned that in single node mode a transport and storage cost is added for sequestered CO2, the cost of which can be adjusted in the `config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L247>`_.
|
||||
• CO2: It can be modeled as a single node for Europe or it can be nodally resolved with CO2 transport pipelines if activated in the `config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L248>`__. It should mentioned that in single node mode a transport and storage cost is added for sequestered CO2, the cost of which can be adjusted in the `config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L247>`__.
|
||||
|
||||
• Carbonaceous fuels: Modeled as a single node for Europe by default, since transport costs for liquids are low and no bottlenecks are expected. Can be regionally resolved in configuration.
|
||||
|
||||
**Electricity distribution network**
|
||||
|
||||
Contrary to the transmission grid, the grid topology at the distribution level (at and below 110 kV) is not included due to the very high computational burden. However, a link per node can be used (if activated in the `Config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L257>`_ file) to represent energy transferred between distribution and transmission levels at every node. In essence, the total energy capacity connecting the transmission grid and the low-voltage level is optimized. The cost assumptions for this link can be adjusted in Config file `options <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L258>`_ , and is currently assumed to be 500 Eur/kW.
|
||||
Contrary to the transmission grid, the grid topology at the distribution level (at and below 110 kV) is not included due to the very high computational burden. However, a link per node can be used (if activated in the `Config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L257>`__ file) to represent energy transferred between distribution and transmission levels at every node. In essence, the total energy capacity connecting the transmission grid and the low-voltage level is optimized. The cost assumptions for this link can be adjusted in Config file `options <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L258>`__ , and is currently assumed to be 500 Eur/kW.
|
||||
|
||||
Rooftop PV, heat pumps, resistive heater, home batteries chargers for passenger EVs, as well as individual heating technologies (heat pumps and resistive heaters) are connected to low-voltage level. All the remaining generation and storage technologies are connected to the transmission grid. In practice, this means that the distribution grid capacity is only extended if it is necessary to balance the mismatch between local generation and demand.
|
||||
|
@ -11,14 +11,14 @@ An initial orientation to the supply and demand options in the model
|
||||
PyPSA-Eur-Sec can be found in the description of the model
|
||||
PyPSA-Eur-Sec-30 in the paper `Synergies of sector coupling and
|
||||
transmission reinforcement in a cost-optimised, highly renewable
|
||||
European energy system <https://arxiv.org/abs/1801.05290>`_ (2018).
|
||||
European energy system <https://arxiv.org/abs/1801.05290>`__ (2018).
|
||||
The latest version of PyPSA-Eur-Sec differs by including biomass,
|
||||
industry, industrial feedstocks, aviation, shipping, better carbon
|
||||
management, carbon capture and usage/sequestration, and gas networks.
|
||||
|
||||
The basic supply (left column) and demand (right column) options in the model are described in this figure:
|
||||
|
||||
.. image:: ../graphics/multisector_figure.png
|
||||
.. image:: img/multisector_figure.png
|
||||
|
||||
.. _Electricity supply and demand:
|
||||
|
||||
@ -26,13 +26,13 @@ Electricity supply and demand
|
||||
=============================
|
||||
|
||||
Electricity supply and demand follows the electricity generation and
|
||||
transmission model `PyPSA-Eur <https://github.com/PyPSA/pypsa-eur>`_,
|
||||
transmission model `PyPSA-Eur <https://github.com/PyPSA/pypsa-eur>`__,
|
||||
except that hydrogen storage is integrated into the hydrogen supply,
|
||||
demand and network, and PyPSA-Eur-Sec includes CHPs.
|
||||
|
||||
Unlike PyPSA-Eur, PyPSA-Eur-Sec does not distribution electricity demand for industry according to population and GDP, but uses the
|
||||
geographical data from the `Hotmaps Industrial Database
|
||||
<https://gitlab.com/hotmaps/industrial_sites/industrial_sites_Industrial_Database>`_.
|
||||
<https://gitlab.com/hotmaps/industrial_sites/industrial_sites_Industrial_Database>`__.
|
||||
|
||||
Also unlike PyPSA-Eur, PyPSA-Eur-Sec subtracts existing electrified heating from the existing electricity demand, so that power-to-heat can be optimised separately.
|
||||
|
||||
@ -44,7 +44,7 @@ Heat demand
|
||||
===========
|
||||
|
||||
Building heating in residential and services sectors is resolved regionally, both for individual buildings and district heating systems, which include different supply options (see :ref:`heat-supply`.)
|
||||
Annual heat demands per country are retrieved from `JRC-IDEES <https://op.europa.eu/en/publication-detail/-/publication/989282db-ad65-11e7-837e-01aa75ed71a1/language-en>`_ and split into space and water heating. For space heating, the annual demands are converted to daily values based on the population-weighted Heating Degree Day (HDD) using the `atlite tool <https://github.com/PyPSA/atlite>`_, where space heat demand is proportional to the difference between the daily average ambient temperature (read from `ERA5 <https://doi.org/10.1002/qj.3803>`_) and a threshold temperature above which space heat demand is zero. A threshold temperature of 15 °C is assumed by default. The daily space heat demand is distributed to the hours of the day following heat demand profiles from `BDEW <https://github.com/oemof/demandlib>`_. These differ for weekdays and weekends/holidays and between residential and services demand.
|
||||
Annual heat demands per country are retrieved from `JRC-IDEES <https://op.europa.eu/en/publication-detail/-/publication/989282db-ad65-11e7-837e-01aa75ed71a1/language-en>`__ and split into space and water heating. For space heating, the annual demands are converted to daily values based on the population-weighted Heating Degree Day (HDD) using the `atlite tool <https://github.com/PyPSA/atlite>`__, where space heat demand is proportional to the difference between the daily average ambient temperature (read from `ERA5 <https://doi.org/10.1002/qj.3803>`__) and a threshold temperature above which space heat demand is zero. A threshold temperature of 15 °C is assumed by default. The daily space heat demand is distributed to the hours of the day following heat demand profiles from `BDEW <https://github.com/oemof/demandlib>`__. These differ for weekdays and weekends/holidays and between residential and services demand.
|
||||
|
||||
*Space heating*
|
||||
|
||||
@ -54,11 +54,11 @@ The space heating demand can be exogenously reduced by retrofitting measures tha
|
||||
:language: yaml
|
||||
:lines: 205
|
||||
|
||||
Co-optimsing of building renovation is also possible, if it is activated in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L222>`_.
|
||||
Co-optimsing of building renovation is also possible, if it is activated in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L222>`__.
|
||||
Renovation of the thermal envelope reduces the space heating demand and is optimised at each node for every heat bus. Renovation measures through additional insulation material and replacement of energy inefficient windows are considered.
|
||||
In a first step, costs per energy savings are estimated in `build_retro_cost.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/build_retro_cost.py>`_. They depend on the insulation condition of the building stock and costs for renovation of the building elements. In a second step, for those cost per energy savings two possible renovation strengths are determined: a moderate renovation with lower costs, a lower maximum possible space heat savings, and an ambitious renovation with associated higher costs and higher efficiency gains. They are added by step-wise linearisation in form of two additional generations in `prepare_sector_network.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/prepare_sector_network.py>`_.
|
||||
In a first step, costs per energy savings are estimated in `build_retro_cost.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/build_retro_cost.py>`__. They depend on the insulation condition of the building stock and costs for renovation of the building elements. In a second step, for those cost per energy savings two possible renovation strengths are determined: a moderate renovation with lower costs, a lower maximum possible space heat savings, and an ambitious renovation with associated higher costs and higher efficiency gains. They are added by step-wise linearisation in form of two additional generations in `prepare_sector_network.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/prepare_sector_network.py>`__.
|
||||
Further information are given in the publication :
|
||||
`Mitigating heat demand peaks in buildings in a highly renewable European energy system, (2021) <https://arxiv.org/abs/2012.01831>`_.
|
||||
`Mitigating heat demand peaks in buildings in a highly renewable European energy system, (2021) <https://arxiv.org/abs/2012.01831>`__.
|
||||
|
||||
*Water heating*
|
||||
|
||||
@ -66,17 +66,17 @@ Hot water demand is assumed to be constant throughout the year.
|
||||
|
||||
*Urban and rural heating*
|
||||
|
||||
For every country, heat demand is split between low and high population density areas. These country-level totals are then distributed to each region in proportion to their rural and urban populations respectively. Urban areas with dense heat demand can be supplied with large-scale district heating systems. The percentage of urban heat demand that can be supplied by district heating networks as well as lump-sum losses in district heating systems is exogenously determined in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L153>`_.
|
||||
For every country, heat demand is split between low and high population density areas. These country-level totals are then distributed to each region in proportion to their rural and urban populations respectively. Urban areas with dense heat demand can be supplied with large-scale district heating systems. The percentage of urban heat demand that can be supplied by district heating networks as well as lump-sum losses in district heating systems is exogenously determined in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L153>`__.
|
||||
|
||||
*Cooling demand*
|
||||
|
||||
Cooling is electrified and is included in the electricity demand. Cooling demand is assumed to remain at current levels. An example of regional distribution of the total heat demand for network 181 regions is depicted below.
|
||||
|
||||
.. image:: ../graphics/demand-map-heat.png
|
||||
.. image:: img/demand-map-heat.png
|
||||
|
||||
As below figure shows, the current total heat demand in Europe is similar to the total electricity demand but features much more pronounced seasonal variations. The current total building heating demand in Europe adds up to 3084 TWh/a of which 78% occurs in urban areas.
|
||||
|
||||
.. image:: ../graphics/Heat_and_el_demand_timeseries.png
|
||||
.. image:: img/Heat_and_el_demand_timeseries.png
|
||||
|
||||
In practice, in PyPSA-Eur-Sec, there are heat demand buses to which the corresponding heat demands are added.
|
||||
|
||||
@ -96,41 +96,41 @@ Different supply options are available depending on whether demand is met centra
|
||||
|
||||
**Urban central heat**
|
||||
|
||||
For large-scale district heating systems the following options are available: combined heat and power (CHP) plants consuming gas or biomass from waste and residues with and without carbon capture (CC), large-scale air-sourced heat pumps, gas and oil boilers, resistive heaters, and fuel cell CHPs. Additionally, waste heat from the `Fischer-Tropsch <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L255>`_ and `Sabatier <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L240>`_ processes for the production of synthetic hydrocarbons can supply district heating systems. For more detailed explanation of these processes, see :ref:`Oil-based products supply` and :ref:`Methane supply`.
|
||||
For large-scale district heating systems the following options are available: combined heat and power (CHP) plants consuming gas or biomass from waste and residues with and without carbon capture (CC), large-scale air-sourced heat pumps, gas and oil boilers, resistive heaters, and fuel cell CHPs. Additionally, waste heat from the `Fischer-Tropsch <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L255>`__ and `Sabatier <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L240>`__ processes for the production of synthetic hydrocarbons can supply district heating systems. For more detailed explanation of these processes, see :ref:`Oil-based products supply` and :ref:`Methane supply`.
|
||||
|
||||
**Residential and Urban decentral heat**
|
||||
|
||||
Supply options in individual buildings include gas and oil boilers, air- and ground-sourced heat pumps, resistive heaters, and solar thermal collectors.
|
||||
Ground-source heat pumps are only allowed in rural areas because of space constraints. Thus, only air- source heat pumps are allowed in urban areas. This is a conservative assumption, since there are many possible sources of low-temperature heat that could be tapped in cities (e.g. waste water, ground water, or natural bodies of water). Costs, lifetimes and efficiencies for these technologies are retrieved from the `technology-data repository <https://github.com/PyPSA/technology-data>`_.
|
||||
Ground-source heat pumps are only allowed in rural areas because of space constraints. Thus, only air- source heat pumps are allowed in urban areas. This is a conservative assumption, since there are many possible sources of low-temperature heat that could be tapped in cities (e.g. waste water, ground water, or natural bodies of water). Costs, lifetimes and efficiencies for these technologies are retrieved from the `technology-data repository <https://github.com/PyPSA/technology-data>`__.
|
||||
|
||||
Below are more detailed explanations for each heating supply component, all of which are modelled as `links <https://pypsa.readthedocs.io/en/latest/components.html?highlight=distribution#link>`_ in PyPSA-Eur-Sec.
|
||||
Below are more detailed explanations for each heating supply component, all of which are modelled as `links <https://pypsa.readthedocs.io/en/latest/components.html?highlight=distribution#link>`__ in PyPSA-Eur-Sec.
|
||||
|
||||
.. _Large-scale CHP:
|
||||
|
||||
**Large-scale CHP**
|
||||
|
||||
Large Combined Heat and Power plants are included in the model if it is specified in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L235>`_.
|
||||
Large Combined Heat and Power plants are included in the model if it is specified in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L235>`__.
|
||||
|
||||
CHPs are based on back pressure plants operating with a fixed ratio of electricity to heat output. The efficiencies of each are given on the back pressure line, where the back pressure coefficient cb is the electricity output divided by the heat output. (For a more complete explanation of the operation of CHPs refer to the study by Dahl et al. : `Cost sensitivity of optimal sector-coupled district heating production systems <https://arxiv.org/pdf/1804.07557.pdf>`_.
|
||||
CHPs are based on back pressure plants operating with a fixed ratio of electricity to heat output. The efficiencies of each are given on the back pressure line, where the back pressure coefficient cb is the electricity output divided by the heat output. (For a more complete explanation of the operation of CHPs refer to the study by Dahl et al. : `Cost sensitivity of optimal sector-coupled district heating production systems <https://arxiv.org/pdf/1804.07557.pdf>`__.
|
||||
|
||||
PyPSA-Eur-Sec includes CHP plants fueled by methane and solid biomass from waste and residues. Hydrogen fuel cells also produce both electricity and heat.
|
||||
|
||||
The methane CHP is modeled on the Danish Energy Agency (DEA) “Gas turbine simple cycle (large)” while the solid biomass CHP is based on the DEA’s “09b Wood Pellets Medium”. For biomass CHP, cb = `0.46 <https://ens.dk/sites/ens.dk/files/Statistik/technology_data_catalogue_for_el_and_dh_-_0009.pdf#page=156>`_ , whereas for gas CHP, cb = `1 <https://ens.dk/sites/ens.dk/files/Statistik/technology_data_catalogue_for_el_and_dh_-_0009.pdf#page=64>`_.
|
||||
The methane CHP is modeled on the Danish Energy Agency (DEA) “Gas turbine simple cycle (large)” while the solid biomass CHP is based on the DEA’s “09b Wood Pellets Medium”. For biomass CHP, cb = `0.46 <https://ens.dk/sites/ens.dk/files/Statistik/technology_data_catalogue_for_el_and_dh_-_0009.pdf#page=156>`__ , whereas for gas CHP, cb = `1 <https://ens.dk/sites/ens.dk/files/Statistik/technology_data_catalogue_for_el_and_dh_-_0009.pdf#page=64>`__.
|
||||
|
||||
NB: The old PyPSA-Eur-Sec-30 model assumed an extraction plant (like the DEA coal CHP) for gas which has flexible production of heat and electricity within the feasibility diagram of Figure 4 in the study by `Brown et al. <https://arxiv.org/abs/1801.05290>`_ We have switched to the DEA back pressure plants since these are more common for smaller plants for biomass, and because the extraction plants were on the back pressure line for 99.5% of the time anyway. The plants were all changed to back pressure in PyPSA-Eur-Sec v0.4.0.
|
||||
NB: The old PyPSA-Eur-Sec-30 model assumed an extraction plant (like the DEA coal CHP) for gas which has flexible production of heat and electricity within the feasibility diagram of Figure 4 in the study by `Brown et al. <https://arxiv.org/abs/1801.05290>`__ We have switched to the DEA back pressure plants since these are more common for smaller plants for biomass, and because the extraction plants were on the back pressure line for 99.5% of the time anyway. The plants were all changed to back pressure in PyPSA-Eur-Sec v0.4.0.
|
||||
|
||||
**Micro-CHP**
|
||||
|
||||
PyPSA-Eur-Sec allows individual buildings to make use of `micro gas CHPs <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L236>`_ that are assumed to be installed at the distribution grid level.
|
||||
PyPSA-Eur-Sec allows individual buildings to make use of `micro gas CHPs <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L236>`__ that are assumed to be installed at the distribution grid level.
|
||||
|
||||
**Heat pumps**
|
||||
|
||||
The coefficient of performance (COP) of air- and ground-sourced heat pumps depends on the ambient or soil temperature respectively. Hence, the COP is a time-varying parameter (refer to `Config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L206>`_ file). Generally, the COP will be lower during winter when temperatures are low. Because the ambient temperature is more volatile than the soil temperature, the COP of ground-sourced heat pumps is less variable. Moreover, the COP depends on the difference between the source and sink temperatures:
|
||||
The coefficient of performance (COP) of air- and ground-sourced heat pumps depends on the ambient or soil temperature respectively. Hence, the COP is a time-varying parameter (refer to `Config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L206>`__ file). Generally, the COP will be lower during winter when temperatures are low. Because the ambient temperature is more volatile than the soil temperature, the COP of ground-sourced heat pumps is less variable. Moreover, the COP depends on the difference between the source and sink temperatures:
|
||||
|
||||
.. math::
|
||||
\Delta T = T_{sink} − T_{source}
|
||||
|
||||
For the sink water temperature Tsink we assume 55 °C [`Config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L207>`_ file]. For the time- and location-dependent source temperatures Tsource, we rely on the `ERA5 <https://doi.org/10.1002/qj.3803>`_ reanalysis weather data. The temperature differences are converted into COP time series using results from a regression analysis performed in the study by `Stafell et al. <https://pubs.rsc.org/en/content/articlelanding/2012/EE/c2ee22653g>`_. For air-sourced heat pumps (ASHP), we use the function:
|
||||
For the sink water temperature Tsink we assume 55 °C [`Config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L207>`__ file]. For the time- and location-dependent source temperatures Tsource, we rely on the `ERA5 <https://doi.org/10.1002/qj.3803>`__ reanalysis weather data. The temperature differences are converted into COP time series using results from a regression analysis performed in the study by `Stafell et al. <https://pubs.rsc.org/en/content/articlelanding/2012/EE/c2ee22653g>`__. For air-sourced heat pumps (ASHP), we use the function:
|
||||
|
||||
.. math::
|
||||
COP (\Delta T) = 6.81 - 0.121\Delta T + 0.000630\Delta T^2
|
||||
@ -142,44 +142,44 @@ for ground-sourced heat pumps (GSHP), we use the function:
|
||||
|
||||
**Resistive heaters**
|
||||
|
||||
Can be activated in Config from the `boilers <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L232>`_ option.
|
||||
Resistive heaters produce heat with a fixed conversion efficiency (refer to `Technology-data repository <https://github.com/PyPSA/technology-data>`_ ).
|
||||
Can be activated in Config from the `boilers <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L232>`__ option.
|
||||
Resistive heaters produce heat with a fixed conversion efficiency (refer to `Technology-data repository <https://github.com/PyPSA/technology-data>`__ ).
|
||||
|
||||
**Gas, oil, and biomass boilers**
|
||||
|
||||
Can be activated in Config from the `boilers <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L232>`_ , `oil boilers <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L233>`_ , and `biomass boiler <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L234>`_ option.
|
||||
Can be activated in Config from the `boilers <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L232>`__ , `oil boilers <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L233>`__ , and `biomass boiler <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L234>`__ option.
|
||||
Similar to resistive heaters, boilers have a fixed efficiency and produce heat using gas, oil or biomass.
|
||||
|
||||
**Solar thermal collectors**
|
||||
|
||||
Can be activated in the config file from the `solar_thermal <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L237>`_ option.
|
||||
Solar thermal profiles are built based on weather data and also have the `options <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L134>`_ for setting the sky model and the orientation of the panel in the config file, which are then used by the atlite tool to calculate the solar resource time series.
|
||||
Can be activated in the config file from the `solar_thermal <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L237>`__ option.
|
||||
Solar thermal profiles are built based on weather data and also have the `options <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L134>`__ for setting the sky model and the orientation of the panel in the config file, which are then used by the atlite tool to calculate the solar resource time series.
|
||||
|
||||
**Waste heat from Fuel Cells, Methanation and Fischer-Tropsch plants**
|
||||
|
||||
Waste heat from `fuel cells <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L256>`_ in addition to processes like `Fischer-Tropsch <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L255>`_, methanation, and Direct Air Capture (DAC) is dumped into district heating networks.
|
||||
Waste heat from `fuel cells <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L256>`__ in addition to processes like `Fischer-Tropsch <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L255>`__, methanation, and Direct Air Capture (DAC) is dumped into district heating networks.
|
||||
|
||||
**Existing heating capacities and decommissioning**
|
||||
|
||||
For the myopic transition paths, capacities already existing for technologies supplying heat are retrieved from `“Mapping and analyses of the current and future (2020 - 2030)” <https://ec.europa.eu/energy/en/studies/mapping-and-analyses-current-and-future-2020-2030-heatingcooling-fuel-deployment>`_ . For the sake of simplicity, coal, oil and gas boiler capacities are assimilated to gas boilers. Besides that, existing capacities for heat resistors, air-sourced and ground-sourced heat pumps are included in the model. For heating capacities, 25% of existing capacities in 2015 are assumed to be decommissioned in every 5-year time step after 2020.
|
||||
For the myopic transition paths, capacities already existing for technologies supplying heat are retrieved from `“Mapping and analyses of the current and future (2020 - 2030)” <https://ec.europa.eu/energy/en/studies/mapping-and-analyses-current-and-future-2020-2030-heatingcooling-fuel-deployment>`__ . For the sake of simplicity, coal, oil and gas boiler capacities are assimilated to gas boilers. Besides that, existing capacities for heat resistors, air-sourced and ground-sourced heat pumps are included in the model. For heating capacities, 25% of existing capacities in 2015 are assumed to be decommissioned in every 5-year time step after 2020.
|
||||
|
||||
**Thermal Energy Storage**
|
||||
|
||||
Activated in Config from the `tes <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L228>`_ option.
|
||||
Activated in Config from the `tes <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L228>`__ option.
|
||||
|
||||
Thermal energy can be stored in large water pits associated with district heating systems and individual thermal energy storage (TES), i.e., small water tanks. Water tanks are modelled as `stores <https://pypsa.readthedocs.io/en/latest/components.html?highlight=distribution#store, which are connected to heat demand buses through water charger/discharger links>`_.
|
||||
A thermal energy density of 46.8 kWh :math:`_{th}`/m3 is assumed, corresponding to a temperature difference of 40 K. The decay of thermal energy in the stores: 1- :math:`e^{-1/24τ}` is assumed to have a time constant of τ=180 days for central TES and τ=3 days for individual TES, both modifiable through `tes_tau <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L229>`_ in config file. Charging and discharging efficiencies are 90% due to pipe losses.
|
||||
Thermal energy can be stored in large water pits associated with district heating systems and individual thermal energy storage (TES), i.e., small water tanks. Water tanks are modelled as `stores <https://pypsa.readthedocs.io/en/latest/components.html?highlight=distribution#store, which are connected to heat demand buses through water charger/discharger links>`__.
|
||||
A thermal energy density of 46.8 kWh :math:`_{th}`/m3 is assumed, corresponding to a temperature difference of 40 K. The decay of thermal energy in the stores: 1- :math:`e^{-1/24τ}` is assumed to have a time constant of τ=180 days for central TES and τ=3 days for individual TES, both modifiable through `tes_tau <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L229>`__ in config file. Charging and discharging efficiencies are 90% due to pipe losses.
|
||||
|
||||
**Retrofitting of the thermal envelope of buildings**
|
||||
|
||||
Co-optimising building renovation is only enabled if in the `config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L222>`_ file. To reduce the computational burden,
|
||||
Co-optimising building renovation is only enabled if in the `config <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L222>`__ file. To reduce the computational burden,
|
||||
default setting is set as false.
|
||||
|
||||
Renovation of the thermal envelope reduces the space heating demand and is
|
||||
optimised at each node for every heat bus. Renovation measures through additional
|
||||
insulation material and replacement of energy inefficient windows are considered.
|
||||
|
||||
In a first step, costs per energy savings are estimated in the `build_retro_cost.py <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/build_retro_cost.py>`_ script.
|
||||
In a first step, costs per energy savings are estimated in the `build_retro_cost.py <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/build_retro_cost.py>`__ script.
|
||||
They depend on the insulation condition of the building stock and costs for
|
||||
renovation of the building elements.
|
||||
In a second step, for those cost per energy savings two possible renovation
|
||||
@ -187,12 +187,12 @@ strengths are determined: a moderate renovation with lower costs and lower
|
||||
maximum possible space heat savings, and an ambitious renovation with associated
|
||||
higher costs and higher efficiency gains. They are added by step-wise
|
||||
linearisation in form of two additional generations in
|
||||
the `prepare_sector_network.py <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/prepare_sector_network.py#L1600>`_ script.
|
||||
the `prepare_sector_network.py <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/prepare_sector_network.py#L1600>`__ script.
|
||||
|
||||
Settings in the ``config/config.yaml`` concerning the endogenously optimisation of building
|
||||
renovation include `cost factor <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L223>`_, `interest rate <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L224>`_, `annualised cost <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L225>`_, `tax weighting <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L226>`_, and `construction index <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L227>`_.
|
||||
renovation include `cost factor <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L223>`__, `interest rate <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L224>`__, `annualised cost <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L225>`__, `tax weighting <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L226>`__, and `construction index <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L227>`__.
|
||||
|
||||
Further information are given in the study by Zeyen et al. : `Mitigating heat demand peaks in buildings in a highly renewable European energy system, (2021) <https://arxiv.org/abs/2012.01831>`_.
|
||||
Further information are given in the study by Zeyen et al. : `Mitigating heat demand peaks in buildings in a highly renewable European energy system, (2021) <https://arxiv.org/abs/2012.01831>`__.
|
||||
|
||||
.. _Hydrogen demand:
|
||||
|
||||
@ -200,7 +200,7 @@ Hydrogen demand
|
||||
=============================
|
||||
|
||||
Hydrogen is consumed in the industry sector (see :ref:`Industry demand`) to produce ammonia (see :ref:`Chemicals Industry`) and direct reduced iron (DRI) (see :ref:`Iron and Steel`). Hydrogen is also consumed to produce synthetic methane (see :ref:`Methane supply`) and liquid hydrocarbons (see :ref:`Oil-based products supply`) which have multiple uses in industry and other sectors.
|
||||
Hydrogen is also used for transport applications (see :ref:`Transportation`), where it is exogenously fixed. It is used in `heavy-duty land transport <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L181>`_ and as liquified hydrogen in the shipping sector (see :ref:`Shipping`). Furthermore, stationary fuel cells may re-electrify hydrogen (with waste heat as a byproduct) to balance renewable fluctuations (see :ref:`Electricity supply and demand`). The waste heat from the stationary fuel cells can be used in `district-heating systems <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L256>`_.
|
||||
Hydrogen is also used for transport applications (see :ref:`Transportation`), where it is exogenously fixed. It is used in `heavy-duty land transport <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L181>`__ and as liquified hydrogen in the shipping sector (see :ref:`Shipping`). Furthermore, stationary fuel cells may re-electrify hydrogen (with waste heat as a byproduct) to balance renewable fluctuations (see :ref:`Electricity supply and demand`). The waste heat from the stationary fuel cells can be used in `district-heating systems <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L256>`__.
|
||||
|
||||
.. _Hydrogen supply:
|
||||
|
||||
@ -220,7 +220,7 @@ combined with a water-gas shift reaction
|
||||
CO + H_2O \xrightarrow{} CO_2 + H_2
|
||||
|
||||
|
||||
SMR is included `here <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L245>`_.
|
||||
SMR is included `here <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L245>`__.
|
||||
PyPSA-Eur-Sec allows this route of :math:`H_2` production with and without [carbon capture (CC)] (see :ref:`Carbon dioxide capture, usage and sequestration (CCU/S)`). These routes are often referred to as blue and grey hydrogen. Here, methane input can be both of fossil or synthetic origin.
|
||||
|
||||
Green hydrogen can be produced by electrolysis to split water into hydrogen and oxygen
|
||||
@ -234,12 +234,12 @@ For the electrolysis, alkaline electrolysers are chosen since they have lower co
|
||||
|
||||
**Transport**
|
||||
|
||||
Hydrogen is transported by pipelines. :math:`H_2` pipelines are endogenously generated, either via a greenfield :math:`H_2` network, or by `retrofitting natural gas pipelines <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L262>`_). Retrofitting is implemented in such a way that for every unit of decommissioned gas pipeline, a share (60% is used in the study by `Neumann et al. <https://arxiv.org/abs/2207.05816>`_) of its nominal capacity (exogenously determined in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L266>`_.) is available for hydrogen transport. When the gas network is not resolved, this input denotes the potential for gas pipelines repurposed into hydrogen pipelines.
|
||||
Hydrogen is transported by pipelines. :math:`H_2` pipelines are endogenously generated, either via a greenfield :math:`H_2` network, or by `retrofitting natural gas pipelines <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L262>`__). Retrofitting is implemented in such a way that for every unit of decommissioned gas pipeline, a share (60% is used in the study by `Neumann et al. <https://arxiv.org/abs/2207.05816>`__) of its nominal capacity (exogenously determined in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L266>`__.) is available for hydrogen transport. When the gas network is not resolved, this input denotes the potential for gas pipelines repurposed into hydrogen pipelines.
|
||||
New pipelines can be built additionally on all routes where there currently is a gas or electricity network connection. These new pipelines will be built where no sufficient retrofitting options are available. The capacities of new and repurposed pipelines are a result of the optimisation.
|
||||
|
||||
**Storage**
|
||||
|
||||
Hydrogen can be stored in overground steel tanks or `underground salt caverns <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L250>`_. For the latter, energy storage capacities in every country are limited to the potential estimation for onshore salt caverns within `50 km <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L251>`_ of shore to avoid environmental issues associated with brine solution disposal. Underground storage potentials for hydrogen in European salt caverns is acquired from `Caglayan et al. <https://doi.org/10.1016/j.ijhydene.2019.12.161>`_
|
||||
Hydrogen can be stored in overground steel tanks or `underground salt caverns <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L250>`__. For the latter, energy storage capacities in every country are limited to the potential estimation for onshore salt caverns within `50 km <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L251>`__ of shore to avoid environmental issues associated with brine solution disposal. Underground storage potentials for hydrogen in European salt caverns is acquired from `Caglayan et al. <https://doi.org/10.1016/j.ijhydene.2019.12.161>`__
|
||||
|
||||
.. _Methane demand:
|
||||
|
||||
@ -253,7 +253,7 @@ Methane is used in individual and large-scale gas boilers, in CHP plants with an
|
||||
Methane supply
|
||||
===================================
|
||||
|
||||
In addition to methane from fossil origins, the model also considers biogenic and synthetic sources. `The gas network can either be modelled, or it can be assumed that gas transport is not limited <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L261>`_. If gas infrastructure is regionally resolved, fossil gas can enter the system only at existing and planned LNG terminals, pipeline entry-points, and intra- European gas extraction sites, which are retrieved from the SciGRID Gas IGGIELGN dataset and the GEM Wiki.
|
||||
In addition to methane from fossil origins, the model also considers biogenic and synthetic sources. `The gas network can either be modelled, or it can be assumed that gas transport is not limited <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L261>`__. If gas infrastructure is regionally resolved, fossil gas can enter the system only at existing and planned LNG terminals, pipeline entry-points, and intra- European gas extraction sites, which are retrieved from the SciGRID Gas IGGIELGN dataset and the GEM Wiki.
|
||||
Biogas can be upgraded to methane.
|
||||
Synthetic methane can be produced by processing hydrogen and captures :math:`CO_2` in the Sabatier reaction
|
||||
|
||||
@ -269,13 +269,13 @@ The existing European gas transmission network is represented based on the SciGR
|
||||
|
||||
The following figure shows the unclustered European gas transmission network based on the SciGRID Gas IGGIELGN dataset. Pipelines are color-coded by estimated capacities. Markers indicate entry-points, sites of fossil resource extraction, and LNG terminals.
|
||||
|
||||
.. image:: ../graphics/gas_pipeline_figure.png
|
||||
.. image:: img/gas_pipeline_figure.png
|
||||
|
||||
.. _Biomass supply:
|
||||
|
||||
Biomass Supply
|
||||
=====================
|
||||
Biomass supply potentials for each European country are taken from the `JRC ENSPRESO database <http://data.europa.eu/89h/74ed5a04-7d74-4807-9eab-b94774309d9f>`_ where data is available for various years (2010, 2020, 2030, 2040 and 2050) and scenarios (low, medium, high). No biomass import from outside Europe is assumed. More information on the data set can be found `here <https://publications.jrc.ec.europa.eu/repository/handle/JRC98626>`_.
|
||||
Biomass supply potentials for each European country are taken from the `JRC ENSPRESO database <http://data.europa.eu/89h/74ed5a04-7d74-4807-9eab-b94774309d9f>`__ where data is available for various years (2010, 2020, 2030, 2040 and 2050) and scenarios (low, medium, high). No biomass import from outside Europe is assumed. More information on the data set can be found `here <https://publications.jrc.ec.europa.eu/repository/handle/JRC98626>`__.
|
||||
|
||||
.. _Biomass demand:
|
||||
|
||||
@ -283,19 +283,19 @@ Biomass demand
|
||||
=====================
|
||||
|
||||
|
||||
Biomass supply potentials for every NUTS2 region are taken from the `JRC ENSPRESO database <http://data.europa.eu/89h/74ed5a04-7d74-4807-9eab-b94774309d9f>`_ where data is available for various years (2010, 2020, 2030, 2040 and 2050) and different availability scenarios (low, medium, high). No biomass import from outside Europe is assumed. More information on the data set can be found `here <https://publications.jrc.ec.europa.eu/repository/handle/JRC98626>`_. The data for NUTS2 regions is mapped to PyPSA-Eur-Sec model regions in proportion to the area overlap.
|
||||
Biomass supply potentials for every NUTS2 region are taken from the `JRC ENSPRESO database <http://data.europa.eu/89h/74ed5a04-7d74-4807-9eab-b94774309d9f>`__ where data is available for various years (2010, 2020, 2030, 2040 and 2050) and different availability scenarios (low, medium, high). No biomass import from outside Europe is assumed. More information on the data set can be found `here <https://publications.jrc.ec.europa.eu/repository/handle/JRC98626>`__. The data for NUTS2 regions is mapped to PyPSA-Eur-Sec model regions in proportion to the area overlap.
|
||||
|
||||
|
||||
The desired scenario can be selected in the PyPSA-Eur-Sec `configuration <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L108>`_. The script for building the biomass potentials from the JRC ENSPRESO data base is located `here <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/build_biomass_potentials.py#L43>`_. Consult the script to see the keywords that specify the scenario options.
|
||||
The desired scenario can be selected in the PyPSA-Eur-Sec `configuration <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L108>`__. The script for building the biomass potentials from the JRC ENSPRESO data base is located `here <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/build_biomass_potentials.py#L43>`__. Consult the script to see the keywords that specify the scenario options.
|
||||
|
||||
|
||||
The `configuration <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L108>`_ also allows the user to define how the various types of biomass are used in the model by using the following categories: biogas, solid biomass, and not included. Feedstocks categorized as biogas, typically manure and sludge waste, are available to the model as biogas, which can be upgraded to biomethane. Feedstocks categorized as solid biomass, e.g. secondary forest residues or municipal waste, are available for combustion in combined-heat-and power (CHP) plants and for medium temperature heat (below 500 °C) applications in industry. It can also converted to gas or liquid fuels.
|
||||
The `configuration <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L108>`__ also allows the user to define how the various types of biomass are used in the model by using the following categories: biogas, solid biomass, and not included. Feedstocks categorized as biogas, typically manure and sludge waste, are available to the model as biogas, which can be upgraded to biomethane. Feedstocks categorized as solid biomass, e.g. secondary forest residues or municipal waste, are available for combustion in combined-heat-and power (CHP) plants and for medium temperature heat (below 500 °C) applications in industry. It can also converted to gas or liquid fuels.
|
||||
|
||||
|
||||
Feedstocks labeled as not included are ignored by the model.
|
||||
|
||||
|
||||
A `typical use case for biomass <https://arxiv.org/abs/2109.09563>`_ would be the medium availability scenario for 2030 where only residues from agriculture and forestry as well as biodegradable municipal waste are considered as energy feedstocks. Fuel crops are avoided because they compete with scarce land for food production, while primary wood, as well as wood chips and pellets, are avoided because of concerns about sustainability. See the supporting materials of the `paper <https://www.sciencedirect.com/science/article/pii/S1364032117302034>`_ for more details.
|
||||
A `typical use case for biomass <https://arxiv.org/abs/2109.09563>`__ would be the medium availability scenario for 2030 where only residues from agriculture and forestry as well as biodegradable municipal waste are considered as energy feedstocks. Fuel crops are avoided because they compete with scarce land for food production, while primary wood, as well as wood chips and pellets, are avoided because of concerns about sustainability. See the supporting materials of the `paper <https://www.sciencedirect.com/science/article/pii/S1364032117302034>`__ for more details.
|
||||
|
||||
|
||||
*Solid biomass conversion and use*
|
||||
@ -303,19 +303,19 @@ A `typical use case for biomass <https://arxiv.org/abs/2109.09563>`_ would be th
|
||||
Solid biomass can be used directly to provide process heat up to 500˚C in the industry. It can also be burned in CHP plants and boilers associated with heating systems. These technologies are described elsewhere (see :ref:`Large-scale CHP` and :ref:`Industry demand`).
|
||||
|
||||
|
||||
Solid biomass can be converted to syngas if the option is enabled in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L274>`_. In this case the model will enable the technology BioSNG both with and without the option for carbon capture (see `Technology-data repository <https://github.com/PyPSA/technology-data>`_).
|
||||
Solid biomass can be converted to syngas if the option is enabled in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L274>`__. In this case the model will enable the technology BioSNG both with and without the option for carbon capture (see `Technology-data repository <https://github.com/PyPSA/technology-data>`__).
|
||||
|
||||
|
||||
Liquefaction of solid biomass `can be enabled <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L273>`_ allowing the model to convert it into liquid hydrocarbons that can replace conventional oil products. This technology also comes with and without carbon capture (see `Technology-data repository <https://github.com/PyPSA/technology-data>`_).
|
||||
Liquefaction of solid biomass `can be enabled <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L273>`__ allowing the model to convert it into liquid hydrocarbons that can replace conventional oil products. This technology also comes with and without carbon capture (see `Technology-data repository <https://github.com/PyPSA/technology-data>`__).
|
||||
|
||||
|
||||
*Transport of solid biomass*
|
||||
|
||||
The transport of solid biomass can either be assumed unlimited between countries or it can be associated with a country specific cost per MWh/km. In the config file these options are toggled `here <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L270>`_. If the option is off, use of solid biomass is transport. If it is turned on, a biomass transport network will be `created <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/prepare_sector_network.py#L1803>`_ between all nodes. This network resembles road transport of biomass and the cost of transportation is a variable cost which is proportional to distance and a country specific cost per MWh/km. The latter is `estimated <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/build_biomass_transport_costs.py>`_ from the country specific costs per ton/km used in the publication `“The JRC-EU-TIMES model. Bioenergy potentials for EU and neighbouring countries” <https://publications.jrc.ec.europa.eu/repository/handle/JRC98626>`_.
|
||||
The transport of solid biomass can either be assumed unlimited between countries or it can be associated with a country specific cost per MWh/km. In the config file these options are toggled `here <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L270>`__. If the option is off, use of solid biomass is transport. If it is turned on, a biomass transport network will be `created <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/prepare_sector_network.py#L1803>`__ between all nodes. This network resembles road transport of biomass and the cost of transportation is a variable cost which is proportional to distance and a country specific cost per MWh/km. The latter is `estimated <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/build_biomass_transport_costs.py>`__ from the country specific costs per ton/km used in the publication `“The JRC-EU-TIMES model. Bioenergy potentials for EU and neighbouring countries” <https://publications.jrc.ec.europa.eu/repository/handle/JRC98626>`__.
|
||||
|
||||
*Biogas transport and use*
|
||||
|
||||
Biogas will be aggregated into a common European resources if a gas network is not modelled explicitly, i.e., the `gas_network <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L261>`_ option is set to false. If, on the other hand, a gas network is included, the biogas potential will be associated with each node of origin.
|
||||
Biogas will be aggregated into a common European resources if a gas network is not modelled explicitly, i.e., the `gas_network <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L261>`__ option is set to false. If, on the other hand, a gas network is included, the biogas potential will be associated with each node of origin.
|
||||
The model can only use biogas by first upgrading it to natural gas quality [see :ref:`Methane supply`] (bio methane) which is fed into the general gas network.
|
||||
|
||||
.. _Oil-based products demand:
|
||||
@ -338,7 +338,7 @@ Oil-based products can be either of fossil origin or synthetically produced by c
|
||||
𝑛CO+(2𝑛+1)H_2 → C_{n}H_{2n + 2} +𝑛H_2O
|
||||
|
||||
|
||||
with costs as included from the `technology-data repository <https://github.com/PyPSA/technology-data/blob/master/latex_tables/tables_in_latex.pdf>`_. The waste heat from the Fischer-Tropsch process is supplied to `district heating networks <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L255>`_. The share of fossil and synthetic oil is an optimisation result depending on the techno-economic assumptions.
|
||||
with costs as included from the `technology-data repository <https://github.com/PyPSA/technology-data/blob/master/latex_tables/tables_in_latex.pdf>`__. The waste heat from the Fischer-Tropsch process is supplied to `district heating networks <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L255>`__. The share of fossil and synthetic oil is an optimisation result depending on the techno-economic assumptions.
|
||||
|
||||
|
||||
*Oil-based transport*
|
||||
@ -361,41 +361,41 @@ The Subsection overview below provides a general description of the modelling ap
|
||||
|
||||
Greenhouse gas emissions associated with industry can be classified into energy-related and process-related emissions. Today, fossil fuels are used for process heat energy in the chemicals industry, but also as a non-energy feedstock for chemicals like ammonia ( :math:`NH_3`), ethylene ( :math:`C_2H_4`) and methanol ( :math:`CH_3OH`). Energy-related emissions can be curbed by using low-emission energy sources. The only option to reduce process-related emissions is by using an alternative manufacturing process or by assuming a certain rate of recycling so that a lower amount of virgin material is needed.
|
||||
|
||||
The overarching modelling procedure can be described as follows. First, the energy demands and process emissions for every unit of material output are estimated based on data from the `JRC-IDEES database <https://data.europa.eu/doi/10.2760/182725>`_ and the fuel and process switching described in the subsequent sections. Second, the 2050 energy demands and process emissions are calculated using the per-unit-of-material ratios based on the industry transformations and the `country-level material production in 2015 <https://data.europa.eu/doi/10.2760/182725>`_, assuming constant material demand.
|
||||
The overarching modelling procedure can be described as follows. First, the energy demands and process emissions for every unit of material output are estimated based on data from the `JRC-IDEES database <https://data.europa.eu/doi/10.2760/182725>`__ and the fuel and process switching described in the subsequent sections. Second, the 2050 energy demands and process emissions are calculated using the per-unit-of-material ratios based on the industry transformations and the `country-level material production in 2015 <https://data.europa.eu/doi/10.2760/182725>`__, assuming constant material demand.
|
||||
|
||||
Missing or too coarsely aggregated data in the JRC-IDEES database is supplemented with additional datasets: `Eurostat energy balances <https://ec.europa.eu/eurostat/web/energy/data/energy-balances>`_, `United States <https://www.usgs.gov/media/files/%20nitrogen-2017-xlsx>`_, `Geological Survey <https://www.usgs.gov/media/files/%20nitrogen-2017-xlsx>`_ for ammonia production, `DECHEMA <https://dechema.de/dechema_media/Downloads/Positionspapiere/Technology_study_Low_carbon_energy_and_feedstock_for_the_European_chemical_industry.pdf>`_ for methanol and chlorine, and `national statistics from Switzerland <https://www.bfe.admin.ch/bfe/de/home/versorgung/statistik-und-geodaten/energiestatistiken.html>`_.
|
||||
Missing or too coarsely aggregated data in the JRC-IDEES database is supplemented with additional datasets: `Eurostat energy balances <https://ec.europa.eu/eurostat/web/energy/data/energy-balances>`__, `United States <https://www.usgs.gov/media/files/%20nitrogen-2017-xlsx>`__, `Geological Survey <https://www.usgs.gov/media/files/%20nitrogen-2017-xlsx>`__ for ammonia production, `DECHEMA <https://dechema.de/dechema_media/Downloads/Positionspapiere/Technology_study_Low_carbon_energy_and_feedstock_for_the_European_chemical_industry.pdf>`__ for methanol and chlorine, and `national statistics from Switzerland <https://www.bfe.admin.ch/bfe/de/home/versorgung/statistik-und-geodaten/energiestatistiken.html>`__.
|
||||
|
||||
|
||||
Where there are fossil and electrified alternatives for the same process (e.g. in glass manufacture or drying), we assume that the process is completely electrified. Current electricity demands (lighting, air compressors, motor drives, fans, pumps) will remain electric. Processes that require temperatures below 500 °C are supplied with solid biomass, since we assume that residues and wastes are not suitable for high-temperature applications. We see solid biomass use primarily in the pulp and paper industry, where it is already widespread, and in food, beverages and tobacco, where it replaces natural gas. Industries which require high temperatures (above 500 °C), such as metals, chemicals and non-metallic minerals are either electrified where suitable processes already exist, or the heat is provided with synthetic methane.
|
||||
|
||||
Hydrogen for high-temperature process heat is not part of the model currently.
|
||||
|
||||
Where process heat is required, our approach depends on the necessary temperature. For example, due to the high share of high-temperature process heat demand (see `Naegler et al. <https://doi.org/10.1002/er.3436>`_ and `Rehfeldt el al. <https://link.springer.com/article/10.1007/s12053-017-9571-y>`_), we disregard geothermal and solar thermal energy as sources for process heat since they cannot attain high-temperature heat.
|
||||
Where process heat is required, our approach depends on the necessary temperature. For example, due to the high share of high-temperature process heat demand (see `Naegler et al. <https://doi.org/10.1002/er.3436>`__ and `Rehfeldt el al. <https://link.springer.com/article/10.1007/s12053-017-9571-y>`__), we disregard geothermal and solar thermal energy as sources for process heat since they cannot attain high-temperature heat.
|
||||
|
||||
The following figure shows the final consumption of energy and non-energy feedstocks in industry today in comparison to the scenario in 2050 assumed in `Neumann et al <https://arxiv.org/abs/2207.05816>`_.
|
||||
The following figure shows the final consumption of energy and non-energy feedstocks in industry today in comparison to the scenario in 2050 assumed in `Neumann et al <https://arxiv.org/abs/2207.05816>`__.
|
||||
|
||||
.. image:: ../graphics/fec_industry_today_tomorrow.png
|
||||
.. image:: img/fec_industry_today_tomorrow.png
|
||||
|
||||
|
||||
The following figure shows the process emissions in industry today (top bar) and in 2050 without
|
||||
carbon capture (bottom bar) assumed in `Neumann et al <https://arxiv.org/abs/2207.05816>`_.
|
||||
carbon capture (bottom bar) assumed in `Neumann et al <https://arxiv.org/abs/2207.05816>`__.
|
||||
|
||||
|
||||
|
||||
|
||||
.. image:: ../graphics/process-emissions.png
|
||||
.. image:: img/process-emissions.png
|
||||
|
||||
|
||||
Inside each country the industrial demand is then distributed using the `Hotmaps Industrial Database <https://zenodo.org/record/4687147#.YvOaxhxBy5c>`_, which is illustrated in the figure below. This open database includes georeferenced industrial sites of energy-intensive industry sectors in EU28, including cement, basic chemicals, glass, iron and steel, non-ferrous metals, non-metallic minerals, paper, and refineries subsectors. The use of this spatial dataset enables the calculation of regional and process-specific energy demands. This approach assumes that there will be no significant migration of energy-intensive industries.
|
||||
Inside each country the industrial demand is then distributed using the `Hotmaps Industrial Database <https://zenodo.org/records/4687147#.YvOaxhxBy5c>`__, which is illustrated in the figure below. This open database includes georeferenced industrial sites of energy-intensive industry sectors in EU28, including cement, basic chemicals, glass, iron and steel, non-ferrous metals, non-metallic minerals, paper, and refineries subsectors. The use of this spatial dataset enables the calculation of regional and process-specific energy demands. This approach assumes that there will be no significant migration of energy-intensive industries.
|
||||
|
||||
.. image:: ../graphics/hotmaps.png
|
||||
.. image:: img/hotmaps.png
|
||||
|
||||
|
||||
.. _Iron and Steel:
|
||||
|
||||
**Iron and Steel**
|
||||
|
||||
Two alternative routes are used today to manufacture steel in Europe. The primary route (integrated steelworks) represents 60% of steel production, while the secondary route (electric arc furnaces, EAF), represents the other 40% `(Lechtenböhmer et. al) <https://doi.org/10.1016/j.energy.2016.07.110>`_.
|
||||
Two alternative routes are used today to manufacture steel in Europe. The primary route (integrated steelworks) represents 60% of steel production, while the secondary route (electric arc furnaces, EAF), represents the other 40% `(Lechtenböhmer et. al) <https://doi.org/10.1016/j.energy.2016.07.110>`__.
|
||||
|
||||
The primary route uses blast furnaces in which coke is used to reduce iron ore into molten iron, which is then converted into steel:
|
||||
|
||||
@ -415,9 +415,9 @@ The primary route uses blast furnaces in which coke is used to reduce iron ore i
|
||||
FeO + CO \xrightarrow{} Fe + CO_2
|
||||
|
||||
|
||||
The primary route of steelmaking implies large process emissions of 0.22 t :math:`_{CO_2}` /t of steel, amounting to 7% of global greenhouse gas emissions `(Vogl et. al) <https://doi.org/10.1016/j.joule.2021.09.007>`_.
|
||||
The primary route of steelmaking implies large process emissions of 0.22 t :math:`_{CO_2}` /t of steel, amounting to 7% of global greenhouse gas emissions `(Vogl et. al) <https://doi.org/10.1016/j.joule.2021.09.007>`__.
|
||||
|
||||
In the secondary route, electric arc furnaces are used to melt scrap metal. This limits the :math:`CO_2` emissions to the burning of graphite electrodes `(Friedrichsen et. al) <https://www.umweltbundesamt.de/en/publikationen/comparative-analysis-of-options-potential-for>`_, and reduces process emissions to 0.03 t :math:`_{CO_2}` /t of steel.
|
||||
In the secondary route, electric arc furnaces are used to melt scrap metal. This limits the :math:`CO_2` emissions to the burning of graphite electrodes `(Friedrichsen et. al) <https://www.umweltbundesamt.de/en/publikationen/comparative-analysis-of-options-potential-for>`__, and reduces process emissions to 0.03 t :math:`_{CO_2}` /t of steel.
|
||||
|
||||
We assume that the primary route can be replaced by a third route in 2050, using direct reduced iron (DRI) and subsequent processing in an EAF.
|
||||
|
||||
@ -433,10 +433,10 @@ We assume that the primary route can be replaced by a third route in 2050, using
|
||||
FeO + H_2 \xrightarrow{} Fe + H_2O
|
||||
|
||||
|
||||
This circumvents the process emissions associated with the use of coke. For hydrogen- based DRI, we assume energy requirements of 1.7 MWh :math:`_{H_2}` /t steel `(Vogl et. al) <https://doi.org/10.1016/j.jclepro.2018.08.279>`_ and 0.322 MWh :math:`_{el}`/t steel `(HYBRIT 2016) <https://dh5k8ug1gwbyz.cloudfront.net/uploads/2021/02/Hybrit-broschure-engelska.pdf>`_.
|
||||
This circumvents the process emissions associated with the use of coke. For hydrogen- based DRI, we assume energy requirements of 1.7 MWh :math:`_{H_2}` /t steel `(Vogl et. al) <https://doi.org/10.1016/j.jclepro.2018.08.279>`__ and 0.322 MWh :math:`_{el}`/t steel `(HYBRIT 2016) <https://dh5k8ug1gwbyz.cloudfront.net/uploads/2021/02/Hybrit-broschure-engelska.pdf>`__.
|
||||
|
||||
|
||||
The share of steel produced via the primary route is exogenously set in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L279>`_. The share of steel obtained via hydrogen-based DRI plus EAF is also set exogenously in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L287>`_. The remaining share is manufactured through the secondary route using scrap metal in EAF. Bioenergy as alternative to coke in blast furnaces is not considered in the model (`Mandova et.al <https://doi.org/10.1016/j.biombioe.2018.04.021>`_, `Suopajärvi et.al <https://doi.org/10.1016/j.apenergy.2018.01.060>`_).
|
||||
The share of steel produced via the primary route is exogenously set in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L279>`__. The share of steel obtained via hydrogen-based DRI plus EAF is also set exogenously in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L287>`__. The remaining share is manufactured through the secondary route using scrap metal in EAF. Bioenergy as alternative to coke in blast furnaces is not considered in the model (`Mandova et.al <https://doi.org/10.1016/j.biombioe.2018.04.021>`__, `Suopajärvi et.al <https://doi.org/10.1016/j.apenergy.2018.01.060>`__).
|
||||
|
||||
For the remaining subprocesses in this sector, the following transformations are assumed. Methane is used as energy source for the smelting process. Activities associated with furnaces, refining and rolling, and product finishing are electrified assuming the current efficiency values for these cases. These transformations result in changes in process emissions as outlined in the process emissions figure presented in the industry overview section (see :ref:`Overview`).
|
||||
|
||||
@ -446,28 +446,27 @@ For the remaining subprocesses in this sector, the following transformations are
|
||||
|
||||
The chemicals industry includes a wide range of diverse industries, including the production of basic organic compounds (olefins, alcohols, aromatics), basic inorganic compounds (ammonia, chlorine), polymers (plastics), and end-user products (cosmetics, pharmaceutics).
|
||||
|
||||
The chemicals industry consumes large amounts of fossil-fuel based feedstocks (see `Levi et. al <https://pubs.acs.org/doi/10.1021/acs.est.7b04573>`_), which can also be produced from renewables as outlined for hydrogen (see :ref:`Hydrogen supply`), for methane (see :ref:`Methane supply`), and for oil-based products (see :ref:`Oil-based products supply`). The ratio between synthetic and fossil-based fuels used in the industry is an endogenous result of the optimisation.
|
||||
The chemicals industry consumes large amounts of fossil-fuel based feedstocks (see `Levi et. al <https://pubs.acs.org/doi/10.1021/acs.est.7b04573>`__), which can also be produced from renewables as outlined for hydrogen (see :ref:`Hydrogen supply`), for methane (see :ref:`Methane supply`), and for oil-based products (see :ref:`Oil-based products supply`). The ratio between synthetic and fossil-based fuels used in the industry is an endogenous result of the optimisation.
|
||||
|
||||
The basic chemicals consumption data from the `JRC IDEES <https://op.europa.eu/en/publication-detail/-/publication/989282db-ad65-11e7-837e-01aa75ed71a1/language-en>`_ database comprises high- value chemicals (ethylene, propylene and BTX), chlorine, methanol and ammonia. However, it is necessary to separate out these chemicals because their current and future production routes are different.
|
||||
The basic chemicals consumption data from the `JRC IDEES <https://op.europa.eu/en/publication-detail/-/publication/989282db-ad65-11e7-837e-01aa75ed71a1/language-en>`__ database comprises high- value chemicals (ethylene, propylene and BTX), chlorine, methanol and ammonia. However, it is necessary to separate out these chemicals because their current and future production routes are different.
|
||||
|
||||
Statistics for the production of ammonia, which is commonly used as a fertilizer, are taken from the `USGS <https://www.usgs.gov/media/files/nitrogen-2017-xlsx>`_ for every country. Ammonia can be made from hydrogen and nitrogen using the Haber-Bosch process.
|
||||
Statistics for the production of ammonia, which is commonly used as a fertilizer, are taken from the `USGS <https://www.usgs.gov/media/files/nitrogen-2017-xlsx>`__ for every country. Ammonia can be made from hydrogen and nitrogen using the Haber-Bosch process.
|
||||
|
||||
.. math::
|
||||
N_2 + 3H_2 \xrightarrow{} 2NH_3
|
||||
|
||||
|
||||
|
||||
The Haber-Bosch process is not explicitly represented in the model, such that demand for ammonia enters the model as a demand for hydrogen ( 6.5 MWh :math:`_{H_2}` / t :math:`_{NH_3}` ) and electricity ( 1.17 MWh :math:`_{el}` /t :math:`_{NH_3}` ) (see `Wang et. al <https://doi.org/10.1016/j.joule.2018.04.017>`_). Today, natural gas dominates in Europe as the source for the hydrogen used in the Haber-Bosch process, but the model can choose among the various hydrogen supply options described in the hydrogen section (see :ref:`Hydrogen supply`)
|
||||
The Haber-Bosch process is not explicitly represented in the model, such that demand for ammonia enters the model as a demand for hydrogen ( 6.5 MWh :math:`_{H_2}` / t :math:`_{NH_3}` ) and electricity ( 1.17 MWh :math:`_{el}` /t :math:`_{NH_3}` ) (see `Wang et. al <https://doi.org/10.1016/j.joule.2018.04.017>`__). Today, natural gas dominates in Europe as the source for the hydrogen used in the Haber-Bosch process, but the model can choose among the various hydrogen supply options described in the hydrogen section (see :ref:`Hydrogen supply`)
|
||||
|
||||
The total production and specific energy consumption of chlorine and methanol is taken from a `DECHEMA report <https://dechema.de/dechema_media/Downloads/Positionspapiere/Technology_study_Low_carbon_energy_and_feedstock_for_the_European_chemical_industry.pdf>`_. According to this source, the production of chlorine amounts to 9.58 MtCl/a, which is assumed to require electricity at 3.6 MWh :math:`_{el}`/t of chlorine and yield hydrogen at 0.937 MWh :math:`_{H_2}`/t of chlorine in the chloralkali process. The production of methanol adds up to 1.5 MtMeOH/a, requiring electricity at 0.167 MWh :math:`_{el}`/t of methanol and methane at 10.25 MWh :math:`_{CH_4}`/t of methanol.
|
||||
The total production and specific energy consumption of chlorine and methanol is taken from a `DECHEMA report <https://dechema.de/dechema_media/Downloads/Positionspapiere/Technology_study_Low_carbon_energy_and_feedstock_for_the_European_chemical_industry.pdf>`__. According to this source, the production of chlorine amounts to 9.58 MtCl/a, which is assumed to require electricity at 3.6 MWh :math:`_{el}`/t of chlorine and yield hydrogen at 0.937 MWh :math:`_{H_2}`/t of chlorine in the chloralkali process. The production of methanol adds up to 1.5 MtMeOH/a. Low-carbon methanol production (or methanolisation) by hydrogenation of :math:`CO_2` requires hydrogen at 6.299 MWh :math:`_{H_2}`/t of methanol, carbon dioxide at 1.373 t :math:`_{CO_2}`/t of methanol and electricity at 1.5 MWh :math:`_{el}`/t of methanol. The energy content of methanol is 5.528 MWh :math:`_{MeOH}`/t of methanol. These values are set exogenously in the config file.
|
||||
|
||||
|
||||
The production of ammonia, methanol, and chlorine production is deducted from the JRC IDEES basic chemicals, leaving the production totals of high-value chemicals. For this, we assume that the liquid hydrocarbon feedstock comes from synthetic or fossil- origin naphtha (14 MWh :math:`_{naphtha}`/t of HVC, similar to `Lechtenböhmer et al <https://doi.org/10.1016/j.energy.2016.07.110>`_), ignoring the methanol-to-olefin route. Furthermore, we assume the following transformations of the energy-consuming processes in the production of plastics: the final energy consumption in steam processing is converted to methane since requires temperature above 500 °C (4.1 MWh :math:`_{CH_4}` /t of HVC, see `Rehfeldt et al. <https://doi.org/10.1007/s12053-017-9571-y>`_); and the remaining processes are electrified using the current efficiency of microwave for high-enthalpy heat processing, electric furnaces, electric process cooling and electric generic processes (2.85 MWh :math:`_{el}`/t of HVC).
|
||||
The production of ammonia, methanol, and chlorine production is deducted from the JRC IDEES basic chemicals, leaving the production totals of high-value chemicals. For this, we assume that the liquid hydrocarbon feedstock comes from synthetic or fossil- origin naphtha (14 MWh :math:`_{naphtha}`/t of HVC, similar to `Lechtenböhmer et al <https://doi.org/10.1016/j.energy.2016.07.110>`__), ignoring the methanol-to-olefin route. Furthermore, we assume the following transformations of the energy-consuming processes in the production of plastics: the final energy consumption in steam processing is converted to methane since requires temperature above 500 °C (4.1 MWh :math:`_{CH_4}` /t of HVC, see `Rehfeldt et al. <https://doi.org/10.1007/s12053-017-9571-y>`__); and the remaining processes are electrified using the current efficiency of microwave for high-enthalpy heat processing, electric furnaces, electric process cooling and electric generic processes (2.85 MWh :math:`_{el}`/t of HVC).
|
||||
|
||||
The process emissions from feedstock in the chemical industry are as high as 0.369 t :math:`_{CO_2}`/t of ethylene equivalent. We consider process emissions for all the material output, which is a conservative approach since it assumes that all plastic-embedded :math:`CO_2` will eventually be released into the atmosphere. However, plastic disposal in landfilling will avoid, or at least delay, associated :math:`CO_2` emissions.
|
||||
|
||||
Circular economy practices drastically reduce the amount of primary feedstock needed for the production of plastics in the model (see `Kullmann et al. <https://doi.org/10.1016/j.energy.2022.124660>`_, `Meys et al. (2021) <https://doi.org/10.1126/science.abg9853>`_, `Meys et al. (2020) <https://doi.org/10/gmxv6z>`_, `Gu et al. <https://doi.org/10/gf8n9w>`_) and consequently, also the energy demands and level of process emission. The percentage of plastics that are assumed to be mechanically recycled can be selected in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/776596ab9ac6a6cc93422ccfd0383abeffb0baa9/config.default.yaml#L315>`_, as well as
|
||||
the percentage that is chemically recycled, see `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/776596ab9ac6a6cc93422ccfd0383abeffb0baa9/config.default.yaml#L316>`_ The energy consumption for those recycling processes are respectively 0.547 MWh :math:`_{el}`/t of HVC (as indicated in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/776596ab9ac6a6cc93422ccfd0383abeffb0baa9/config.default.yaml#L318>`_) (`Meys et al. (2020) <https://doi.org/10/gmxv6z>`_), and 6.9 MWh :math:`_{el}`/t of HVC (as indicated in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/776596ab9ac6a6cc93422ccfd0383abeffb0baa9/config.default.yaml#L319>`_) based on pyrolysis and electric steam cracking (see `Materials Economics <https://materialeconomics.com/publications/industrial-transformation-2050>`_ report).
|
||||
Circular economy practices drastically reduce the amount of primary feedstock needed for the production of plastics in the model (see `Kullmann et al. <https://doi.org/10.1016/j.energy.2022.124660>`__, `Meys et al. (2021) <https://doi.org/10.1126/science.abg9853>`__, `Meys et al. (2020) <https://doi.org/10/gmxv6z>`__, `Gu et al. <https://doi.org/10/gf8n9w>`__) and consequently, also the energy demands and level of process emission. The percentage of plastics that are assumed to be mechanically recycled can be selected in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/776596ab9ac6a6cc93422ccfd0383abeffb0baa9/config.default.yaml#L315>`__, as well as
|
||||
the percentage that is chemically recycled, see `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/776596ab9ac6a6cc93422ccfd0383abeffb0baa9/config.default.yaml#L316>`__ The energy consumption for those recycling processes are respectively 0.547 MWh :math:`_{el}`/t of HVC (as indicated in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/776596ab9ac6a6cc93422ccfd0383abeffb0baa9/config.default.yaml#L318>`__) (`Meys et al. (2020) <https://doi.org/10/gmxv6z>`__), and 6.9 MWh :math:`_{el}`/t of HVC (as indicated in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/776596ab9ac6a6cc93422ccfd0383abeffb0baa9/config.default.yaml#L319>`__) based on pyrolysis and electric steam cracking (see `Materials Economics <https://materialeconomics.com/publications/industrial-transformation-2050>`__ report).
|
||||
|
||||
|
||||
**Non-metallic Mineral Products**
|
||||
@ -476,7 +475,7 @@ This subsector includes the manufacturing of cement, ceramics, and glass.
|
||||
|
||||
*Cement*
|
||||
|
||||
Cement is used in construction to make concrete. The production of cement involves high energy consumption and large process emissions. The calcination of limestone to chemically reactive calcium oxide, also known as lime, involves process emissions of 0.54 t :math:`_{CO_2}` /t cement (see `Akhtar et al. <https://doi.org/10.1109/CITCON.2013.6525276>`_.
|
||||
Cement is used in construction to make concrete. The production of cement involves high energy consumption and large process emissions. The calcination of limestone to chemically reactive calcium oxide, also known as lime, involves process emissions of 0.54 t :math:`_{CO_2}` /t cement (see `Akhtar et al. <https://doi.org/10.1109/CITCON.2013.6525276>`__.
|
||||
|
||||
|
||||
.. math::
|
||||
@ -487,16 +486,16 @@ Additionally, :math:`CO_2` is emitted from the combustion of fossil fuels to pro
|
||||
|
||||
Cement process emissions can be captured assuming a capture rate of 90%. Whether emissions are captured is decided by the model taking into account the capital costs of carbon capture modules. The electricity and heat demand of process emission carbon capture is currently ignored. For net-zero emission scenarios, the remaining process emissions need to be compensated by negative emissions.
|
||||
|
||||
With the exception of electricity demand and biomass demand for low-temperature heat (0.06 MWh/t and 0.2 MWh/t), the final energy consumption of this subsector is assumed to be supplied by methane (0.52 MWh/t), which is capable of delivering the required high-temperature heat. This implies a switch from burning solid fuels to burning gas which will require adjustments of the `kilns <10.1109/CITCON.2013.6525276>`_. The share of fossil vs. synthetic methane consumed is a result of the optimisation
|
||||
With the exception of electricity demand and biomass demand for low-temperature heat (0.06 MWh/t and 0.2 MWh/t), the final energy consumption of this subsector is assumed to be supplied by methane (0.52 MWh/t), which is capable of delivering the required high-temperature heat. This implies a switch from burning solid fuels to burning gas which will require adjustments of the `kilns <10.1109/CITCON.2013.6525276>`__. The share of fossil vs. synthetic methane consumed is a result of the optimisation
|
||||
|
||||
|
||||
*Ceramics*
|
||||
|
||||
The ceramics sector is assumed to be fully electrified based on the current efficiency of already electrified processes which include microwave drying and sintering of raw materials, electric kilns for primary production processes, electric furnaces for the `product finishing <https://data.europa.eu/doi/10.2760/182725>`_. In total, the final electricity consumption is 0.44 MWh/t of ceramic. The manufacturing of ceramics includes process emissions of 0.03 t :math:`_{CO_2}`/t of ceramic. For a detailed overview of the ceramics industry sector see `Furszyfer Del Rio et al <https://doi.org/10.1016/j.rser.2021.111885>`_.
|
||||
The ceramics sector is assumed to be fully electrified based on the current efficiency of already electrified processes which include microwave drying and sintering of raw materials, electric kilns for primary production processes, electric furnaces for the `product finishing <https://data.europa.eu/doi/10.2760/182725>`__. In total, the final electricity consumption is 0.44 MWh/t of ceramic. The manufacturing of ceramics includes process emissions of 0.03 t :math:`_{CO_2}`/t of ceramic. For a detailed overview of the ceramics industry sector see `Furszyfer Del Rio et al <https://doi.org/10.1016/j.rser.2021.111885>`__.
|
||||
|
||||
*Glass*
|
||||
|
||||
The production of glass is assumed to be fully electrified based on the current efficiency of electric melting tanks and electric annealing which adds up to an electricity demand of 2.07 MWh :math:`_{el}`/t of `glass <https://doi.org/10/f9df2m>`_. The manufacturing of glass incurs process emissions of 0.1 t :math:`_{CO_2}`/t of glass. Potential efficiency improvements, which according to `Lechtenböhmer et al <https://doi.org/10/f9df2m>`_ could reduce energy demands to 0.85 MW :math:`_{el}`/t of glass, have not been considered. For a detailed overview of the glass industry sector see `Furszyfer Del Rio et al <https://doi.org/10.1016/j.rser.2021.111885>`_.
|
||||
The production of glass is assumed to be fully electrified based on the current efficiency of electric melting tanks and electric annealing which adds up to an electricity demand of 2.07 MWh :math:`_{el}`/t of `glass <https://doi.org/10/f9df2m>`__. The manufacturing of glass incurs process emissions of 0.1 t :math:`_{CO_2}`/t of glass. Potential efficiency improvements, which according to `Lechtenböhmer et al <https://doi.org/10/f9df2m>`__ could reduce energy demands to 0.85 MW :math:`_{el}`/t of glass, have not been considered. For a detailed overview of the glass industry sector see `Furszyfer Del Rio et al <https://doi.org/10.1016/j.rser.2021.111885>`__.
|
||||
|
||||
|
||||
**Non-ferrous Metals**
|
||||
@ -511,75 +510,77 @@ The primary route involves two energy-intensive processes: the production of alu
|
||||
2Al_2O_3 +3C \xrightarrow{} 4Al+3CO_2
|
||||
|
||||
|
||||
The primary route requires high-enthalpy heat (2.3 MWh/t) to produce alumina which is supplied by methane and causes process emissions of 1.5 t :math:`_{CO_2}`/t aluminium. According to `Friedrichsen et al. <http://www.umweltbundesamt.de/en/publikationen/comparative-analysis-of-options-potential-for>`_, inert anodes might become commercially available by 2030 that would eliminate the process emissions, but they are not included in the model. Assuming all subprocesses are electrified, the primary route requires 15.4 MWh :math:`_{el}`/t of aluminium.
|
||||
The primary route requires high-enthalpy heat (2.3 MWh/t) to produce alumina which is supplied by methane and causes process emissions of 1.5 t :math:`_{CO_2}`/t aluminium. According to `Friedrichsen et al. <http://www.umweltbundesamt.de/en/publikationen/comparative-analysis-of-options-potential-for>`__, inert anodes might become commercially available by 2030 that would eliminate the process emissions, but they are not included in the model. Assuming all subprocesses are electrified, the primary route requires 15.4 MWh :math:`_{el}`/t of aluminium.
|
||||
|
||||
In the secondary route, scrap aluminium is remelted. The energy demand for this process is only 10% of the primary route and there are no associated process emissions. Assuming all subprocesses are electrified, the secondary route requires 1.7 MWh/t of aluminium. The share of aliminum manufactured by the primary and secondary route can be selected in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L297>`_]
|
||||
In the secondary route, scrap aluminium is remelted. The energy demand for this process is only 10% of the primary route and there are no associated process emissions. Assuming all subprocesses are electrified, the secondary route requires 1.7 MWh/t of aluminium. The share of aliminum manufactured by the primary and secondary route can be selected in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L297>`__]
|
||||
|
||||
For the other non-ferrous metals, we assume the electrification of the entire manufacturing process with an average electricity demand of 3.2 MWh :math:`_{el}`/t lead equivalent.
|
||||
|
||||
**Other Industry Subsectors**
|
||||
|
||||
The remaining industry subsectors include (a) pulp, paper, printing, (b) food, beverages, tobacco, (c) textiles and leather, (d) machinery equipment, (e) transport equipment, (f) wood and wood products, (g) others. Low- and mid-temperature process heat in these industries is assumed to be `supplied by biomass <https://doi.org/10.1016/j.rser.2021.110856>`_ while the remaining processes are electrified. None of the subsectors involve process emissions.
|
||||
The remaining industry subsectors include (a) pulp, paper, printing, (b) food, beverages, tobacco, (c) textiles and leather, (d) machinery equipment, (e) transport equipment, (f) wood and wood products, (g) others. Low- and mid-temperature process heat in these industries is assumed to be `supplied by biomass <https://doi.org/10.1016/j.rser.2021.110856>`__ while the remaining processes are electrified. None of the subsectors involve process emissions.
|
||||
|
||||
|
||||
Agriculture demand
|
||||
=========================
|
||||
|
||||
Energy demands for the agriculture, forestry and fishing sector per country are taken from the `JRC-IDEES database <http://data.europa.eu/89h/jrc-10110-10001>`_. Missing countries are filled with `Eurostat data <https://ec.europa.eu/eurostat/web/energy/data/energy-balances>`_. Agricultural energy demands are split into electricity (lighting, ventilation, specific electricity uses, electric pumping devices), heat (specific heat uses, low enthalpy heat), and machinery oil (motor drives, farming machine drives, diesel-fueled pumping devices). Heat demand is assigned at “services rural heat” buses. Time series for demands are assumed to be constant and distributed inside countries by population.
|
||||
Energy demands for the agriculture, forestry and fishing sector per country are taken from the `JRC-IDEES database <http://data.europa.eu/89h/jrc-10110-10001>`__. Missing countries are filled with `Eurostat data <https://ec.europa.eu/eurostat/web/energy/data/energy-balances>`__. Agricultural energy demands are split into electricity (lighting, ventilation, specific electricity uses, electric pumping devices), heat (specific heat uses, low enthalpy heat), and machinery oil (motor drives, farming machine drives, diesel-fueled pumping devices). Heat demand is assigned at “services rural heat” buses. Time series for demands are assumed to be constant and distributed inside countries by population.
|
||||
|
||||
.. _Transportation:
|
||||
|
||||
Transportation
|
||||
=========================
|
||||
Annual energy demands for land transport, aviation and shipping for every country are retrieved from `JRC-IDEES data set <http://data.europa.eu/89h/jrc-10110-10001>`_. Below, the details of how each of these categories are treated is explained.
|
||||
Annual energy demands for land transport, aviation and shipping for every country are retrieved from `JRC-IDEES data set <http://data.europa.eu/89h/jrc-10110-10001>`__. Below, the details of how each of these categories are treated is explained.
|
||||
|
||||
.. _Land transport:
|
||||
|
||||
**Land transport**
|
||||
|
||||
Both road and rail transport is combined as `land transport demand <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/build_transport_demand.py#L74>`_ although electrified rail transport is excluded because that demand is included in the current electricity demand.
|
||||
Both road and rail transport is combined as `land transport demand <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/build_transport_demand.py#L74>`__ although electrified rail transport is excluded because that demand is included in the current electricity demand.
|
||||
|
||||
The most important settings for land transport are the exogenously fixed fuel mix (an option enabling the endogeous optimization of transport electrification is planned but not yet implemented). In the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L181>`_, the share of battery electric vehicles (BEV) and hydrogen fuel cell vehicles (FCEV) can be set. The remaining percentage will be treated as internal combustion engines (ICE) that consume oil products.
|
||||
The most important settings for land transport are the exogenously fixed fuel mix (an option enabling the endogeous optimization of transport electrification is planned but not yet implemented). In the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L181>`__, the share of battery electric vehicles (BEV) and hydrogen fuel cell vehicles (FCEV) can be set. The remaining percentage will be treated as internal combustion engines (ICE) that consume oil products.
|
||||
|
||||
*Battery Electric vehicles (BEV)*
|
||||
|
||||
For the electrified land transport, country-specific factors are computed by comparing the `current car final energy consumption per km in <https://www.sciencedirect.com/science/article/pii/S0360544216310295>`_ (average for Europe 0.7 kWh/km) to the 0.18 kWh/km value assumed for battery-to-wheels efficiency in EVs. The characteristic `weekly profile <https://www.bast.de/DE/Verkehrstechnik/Fachthemen/v2-verkehrszaehlung/zaehl_node.html>`_ provided by the German Federal Highway Research Institute (BASt) is used to obtain hourly time series for European countries taking into account the corresponding local times. Furthermore, a temperature dependence is included in the time series to account for heating/cooling demand in transport. For temperatures `below <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L166>`_/`above <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L165>`_ certain threshold values, e.g. 15 °C/20 °C, `temperature coefficients <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L169>`_ of typically 0.98%/°C and 0.63%/°C are assumed, based on the `paper <https://www.sciencedirect.com/science/article/pii/S036054421831288X>`_.
|
||||
For the electrified land transport, country-specific factors are computed by comparing the `current car final energy consumption per km in <https://www.sciencedirect.com/science/article/pii/S0360544216310295>`__ (average for Europe 0.7 kWh/km) to the 0.18 kWh/km value assumed for battery-to-wheels efficiency in EVs. The characteristic `weekly profile <https://www.bast.de/DE/Verkehrstechnik/Fachthemen/v2-verkehrszaehlung/zaehl_node.html>`__ provided by the German Federal Highway Research Institute (BASt) is used to obtain hourly time series for European countries taking into account the corresponding local times. Furthermore, a temperature dependence is included in the time series to account for heating/cooling demand in transport. For temperatures `below <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L166>`__/`above <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L165>`__ certain threshold values, e.g. 15 °C/20 °C, `temperature coefficients <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L169>`__ of typically 0.98%/°C and 0.63%/°C are assumed, based on the `paper <https://www.sciencedirect.com/science/article/pii/S036054421831288X>`__.
|
||||
|
||||
For BEVs the user can define the `storage energy capacity <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L173>`_, `charging power capacity <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L176>`_, and `charging efficiency <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L174>`_.
|
||||
For BEVs the user can define the `storage energy capacity <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L173>`__, `charging power capacity <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L176>`__, and `charging efficiency <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L174>`__.
|
||||
|
||||
For BEV, smart charging is an option. A `certain share <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L172>`_ of the BEV fleet can shift their charging time. The BEV state of charge is forced to be higher than a `set percentage <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L163>`_, e.g. 75%, every day at a `specified hour <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L164>`_, e.g., 7 am, to ensure that the batteries are sufficiently charged for peak usage in the morning and they not behave as seasonal storage. They also have the option to participate in vehicle-to-grid (V2G) services to facilitate system operation if that `is enabled <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L179>`_.
|
||||
For BEV, smart charging is an option. A `certain share <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L172>`__ of the BEV fleet can shift their charging time. The BEV state of charge is forced to be higher than a `set percentage <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L163>`__, e.g. 75%, every day at a `specified hour <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L164>`__, e.g., 7 am, to ensure that the batteries are sufficiently charged for peak usage in the morning and they not behave as seasonal storage. They also have the option to participate in vehicle-to-grid (V2G) services to facilitate system operation if that `is enabled <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L179>`__.
|
||||
|
||||
The battery cost of BEV is not included in the model since it is assumed that BEV owners buy them to primarily satisfy their mobility needs.
|
||||
|
||||
*Hydrogen fuel cell vehicles (FCEV)*
|
||||
|
||||
The share of all land transport that is specified to be be FCEV will be converted to a demand for hydrogen (see :ref:`Hydrogen supply`) using the `FCEV efficiency
|
||||
<https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L191>`_.
|
||||
<https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L191>`__.
|
||||
|
||||
FCEVs are typically used to simulate demand for transport that is hard to electrify directly, e.g. heavy construction machinery. But it may also be used to investigate a more widespread adoption of the technology.
|
||||
|
||||
*Internal combustion engine vehicles (ICE)*
|
||||
|
||||
All land transport that is not specified to be either BEV or FCEV will be treated as conventional ICEs. The transport demand is converted to a demand for oil products (see :ref:`Oil-based products supply`) using the `ICE efficiency
|
||||
<https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L192>`_.
|
||||
<https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L192>`__.
|
||||
|
||||
.. _Aviation:
|
||||
|
||||
**Aviation**
|
||||
|
||||
The `demand for aviation <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/prepare_sector_network.py#L2193>`_ includes international and domestic use. It is modelled as an oil demand since aviation consumes kerosene. This can be produced synthetically or have fossil-origin (see :ref:`Oil-based products supply`).
|
||||
The `demand for aviation <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/prepare_sector_network.py#L2193>`__ includes international and domestic use. It is modelled as an oil demand since aviation consumes kerosene. This can be produced synthetically or have fossil-origin (see :ref:`Oil-based products supply`).
|
||||
|
||||
.. _Shipping:
|
||||
|
||||
**Shipping**
|
||||
|
||||
Shipping energy demand is covered by a combination of oil and hydrogen. Other fuel options, like methanol or ammonia, are currently not included in PyPSA-Eur-Sec. The share of shipping that is assumed to be supplied by hydrogen can be selected in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L198>`_.
|
||||
Shipping energy demand is covered by a combination of oil, hydrogen and methanol. Other fuel options, like ammonia, are currently not included in PyPSA-Eur-Sec. The share of shipping that is assumed to be supplied by hydrogen or methanol can be selected in the `config file <https://github.com/PyPSA/pypsa-eur/blob/master/config/config.default.yaml#L475>`__.
|
||||
|
||||
To estimate the `hydrogen demand <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/prepare_sector_network.py#L2090>`_, the average fuel efficiency of the fleet is used in combination with the efficiency of the fuel cell defined in the technology-data repository. The average fuel efficiency is set in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L196>`_.
|
||||
To estimate the `hydrogen demand <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/prepare_sector_network.py#L2090>`__, the average fuel efficiency of the fleet is used in combination with the efficiency of the fuel cell defined in the technology-data repository. The average fuel efficiency is set in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L196>`__.
|
||||
|
||||
The consumed hydrogen comes from the general hydrogen bus where it can be produced by SMR, SMR+CC or electrolysers (see :ref:`Hydrogen supply`). The fraction that is not converted into hydrogen use oil products, i.e. is connected to the general oil bus.
|
||||
|
||||
The energy demand for liquefaction of the hydrogen used for shipping can be `included <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L197>`_. If this option is selected, liquifaction will happen at the `node where the shipping demand occurs <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/prepare_sector_network.py#L2064>`_.
|
||||
The energy demand for liquefaction of the hydrogen used for shipping can be `included <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L197>`__. If this option is selected, liquifaction will happen at the `node where the shipping demand occurs <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/scripts/prepare_sector_network.py#L2064>`__.
|
||||
|
||||
The consumed methanol comes from the general methanol bus where it is produced through methanolisation (see :ref:`Chemicals Industry`).
|
||||
|
||||
.. _Carbon dioxide capture, usage and sequestration (CCU/S):
|
||||
|
||||
@ -600,12 +601,12 @@ For the following point source emissions, carbon capture is applicable:
|
||||
|
||||
• CHP plants using biomass or methane
|
||||
|
||||
• `Coal power plants <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L242>`_.
|
||||
• `Coal power plants <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L242>`__.
|
||||
|
||||
Point source emissions are captured assuming a capture rate, e.g. 90%, which can be specified in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L249>`_. The electricity and heat demand of process emission carbon capture
|
||||
Point source emissions are captured assuming a capture rate, e.g. 90%, which can be specified in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L249>`__. The electricity and heat demand of process emission carbon capture
|
||||
is currently ignored.
|
||||
|
||||
DAC (if `included <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L243>`_) includes the adsorption phase where electricity and heat consumptionsare required to assist the adsorption process and regenerate the adsorbent. It also includes the drying and compression of :math:`CO_2` prior to storage which consumes electricity and rejects heat.
|
||||
DAC (if `included <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L243>`__) includes the adsorption phase where electricity and heat consumptionsare required to assist the adsorption process and regenerate the adsorbent. It also includes the drying and compression of :math:`CO_2` prior to storage which consumes electricity and rejects heat.
|
||||
|
||||
*Carbon dioxide usage*
|
||||
|
||||
@ -614,8 +615,8 @@ naphtha). If captured carbon is used, the :math:`CO_2` emissions of the syntheti
|
||||
|
||||
*Carbon dioxide sequestration*
|
||||
|
||||
Captured :math:`CO_2` can also be sequestered underground up to an annual sequestration limit of 200 Mt :math:`_{CO_2}`/a. This limit can be chosen in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L246>`_. As stored carbon dioxide is modelled as a single node for Europe, :math:`CO_2` transport constraints are neglected. Since :math:`CO_2` sequestration is an immature technology, the cost assumption is defined in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L247>`_.
|
||||
Captured :math:`CO_2` can also be sequestered underground up to an annual sequestration limit of 200 Mt :math:`_{CO_2}`/a. This limit can be chosen in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L246>`__. As stored carbon dioxide is modelled as a single node for Europe, :math:`CO_2` transport constraints are neglected. Since :math:`CO_2` sequestration is an immature technology, the cost assumption is defined in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L247>`__.
|
||||
|
||||
*Carbon dioxide transport*
|
||||
|
||||
Carbon dioxide can be modelled as a single node for Europe (in this case, :math:`CO_2` transport constraints are neglected). A network for modelling the transport of :math:`CO_2` among the different nodes can also be created if selected in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L248>`_.
|
||||
Carbon dioxide can be modelled as a single node for Europe (in this case, :math:`CO_2` transport constraints are neglected). A network for modelling the transport of :math:`CO_2` among the different nodes can also be created if selected in the `config file <https://github.com/PyPSA/pypsa-eur-sec/blob/3daff49c9999ba7ca7534df4e587e1d516044fc3/config.default.yaml#L248>`__.
|
||||
|
@ -7,8 +7,8 @@
|
||||
Support
|
||||
#######################
|
||||
|
||||
* In case of code-related **questions**, please post on `stack overflow <https://stackoverflow.com/questions/tagged/pypsa>`_.
|
||||
* For non-programming related and more general questions please refer to the `mailing list <https://groups.google.com/group/pypsa>`_.
|
||||
* To **discuss** with other PyPSA users, organise projects, share news, and get in touch with the community you can use the `discord server <https://discord.gg/AnuJBk23FU>`_.
|
||||
* For **bugs and feature requests**, please use the `issue tracker <https://github.com/PyPSA/pypsa-eur/issues>`_.
|
||||
* We strongly welcome anyone interested in providing **contributions** to this project. If you have any ideas, suggestions or encounter problems, feel invited to file issues or make pull requests on `Github <https://github.com/PyPSA/PyPSA>`_. For further information on how to contribute, please refer to :ref:`contributing`.
|
||||
* In case of code-related **questions**, please post on `stack overflow <https://stackoverflow.com/questions/tagged/pypsa>`__.
|
||||
* For non-programming related and more general questions please refer to the `mailing list <https://groups.google.com/group/pypsa>`__.
|
||||
* To **discuss** with other PyPSA users, organise projects, share news, and get in touch with the community you can use the `discord server <https://discord.gg/AnuJBk23FU>`__.
|
||||
* For **bugs and feature requests**, please use the `issue tracker <https://github.com/PyPSA/pypsa-eur/issues>`__.
|
||||
* We strongly welcome anyone interested in providing **contributions** to this project. If you have any ideas, suggestions or encounter problems, feel invited to file issues or make pull requests on `Github <https://github.com/PyPSA/PyPSA>`__. For further information on how to contribute, please refer to :ref:`contributing`.
|
||||
|
137
doc/tutorial.rst
@ -32,10 +32,9 @@ configuration, execute
|
||||
.. code:: bash
|
||||
:class: full-width
|
||||
|
||||
snakemake -call results/test-elec/networks/elec_s_6_ec_lcopt_Co2L-24H.nc --configfile config/test/config.electricity.yaml
|
||||
snakemake -call results/test-elec/networks/elec_s_6_ec_lcopt_.nc --configfile config/test/config.electricity.yaml
|
||||
|
||||
This configuration is set to download a reduced data set via the rules :mod:`retrieve_databundle`,
|
||||
:mod:`retrieve_natura_raster`, :mod:`retrieve_cutout`.
|
||||
This configuration is set to download a reduced cutout via the rule :mod:`retrieve_cutout`.
|
||||
For more information on the data dependencies of PyPSA-Eur, continue reading :ref:`data`.
|
||||
|
||||
How to configure runs?
|
||||
@ -115,9 +114,9 @@ clustered down to 6 buses and every 24 hours aggregated to one snapshot. The com
|
||||
|
||||
.. code:: bash
|
||||
|
||||
snakemake -call results/test-elec/networks/elec_s_6_ec_lcopt_Co2L-24H.nc --configfile config/test/config.electricity.yaml
|
||||
snakemake -call results/test-elec/networks/elec_s_6_ec_lcopt_.nc --configfile config/test/config.electricity.yaml
|
||||
|
||||
orders ``snakemake`` to run the rule :mod:`solve_network` that produces the solved network and stores it in ``results/networks`` with the name ``elec_s_6_ec_lcopt_Co2L-24H.nc``:
|
||||
orders ``snakemake`` to run the rule :mod:`solve_network` that produces the solved network and stores it in ``results/networks`` with the name ``elec_s_6_ec_lcopt_.nc``:
|
||||
|
||||
.. literalinclude:: ../rules/solve_electricity.smk
|
||||
:start-at: rule solve_network:
|
||||
@ -133,32 +132,31 @@ This triggers a workflow of multiple preceding jobs that depend on each rule's i
|
||||
graph[bgcolor=white, margin=0];
|
||||
node[shape=box, style=rounded, fontname=sans, fontsize=10, penwidth=2];
|
||||
edge[penwidth=2, color=grey];
|
||||
0[label = "solve_network", color = "0.39 0.6 0.85", style="rounded"];
|
||||
1[label = "prepare_network\nll: copt\nopts: Co2L-24H", color = "0.29 0.6 0.85", style="rounded"];
|
||||
2[label = "add_extra_components", color = "0.28 0.6 0.85", style="rounded"];
|
||||
3[label = "cluster_network\nclusters: 6", color = "0.19 0.6 0.85", style="rounded"];
|
||||
4[label = "simplify_network\nsimpl: ", color = "0.01 0.6 0.85", style="rounded"];
|
||||
5[label = "add_electricity", color = "0.49 0.6 0.85", style="rounded"];
|
||||
6[label = "build_renewable_profiles\ntechnology: solar", color = "0.21 0.6 0.85", style="rounded"];
|
||||
7[label = "base_network", color = "0.27 0.6 0.85", style="rounded"];
|
||||
8[label = "build_shapes", color = "0.26 0.6 0.85", style="rounded"];
|
||||
9[label = "retrieve_databundle", color = "0.59 0.6 0.85", style="rounded"];
|
||||
10[label = "retrieve_natura_raster", color = "0.47 0.6 0.85", style="rounded"];
|
||||
11[label = "build_bus_regions", color = "0.13 0.6 0.85", style="rounded"];
|
||||
12[label = "retrieve_cutout\ncutout: be-03-2013-era5", color = "0.36 0.6 0.85", style="rounded,dashed"];
|
||||
13[label = "build_renewable_profiles\ntechnology: onwind", color = "0.21 0.6 0.85", style="rounded"];
|
||||
14[label = "build_renewable_profiles\ntechnology: offwind-ac", color = "0.21 0.6 0.85", style="rounded"];
|
||||
15[label = "build_ship_raster", color = "0.00 0.6 0.85", style="rounded"];
|
||||
16[label = "retrieve_ship_raster", color = "0.51 0.6 0.85", style="rounded,dashed"];
|
||||
17[label = "build_renewable_profiles\ntechnology: offwind-dc", color = "0.21 0.6 0.85", style="rounded"];
|
||||
18[label = "build_line_rating", color = "0.05 0.6 0.85", style="rounded"];
|
||||
19[label = "retrieve_cost_data\nyear: 2030", color = "0.15 0.6 0.85", style="rounded"];
|
||||
20[label = "build_powerplants", color = "0.54 0.6 0.85", style="rounded"];
|
||||
21[label = "build_electricity_demand", color = "0.52 0.6 0.85", style="rounded"];
|
||||
22[label = "retrieve_electricity_demand", color = "0.22 0.6 0.85", style="rounded"];
|
||||
23[label = "copy_config", color = "0.44 0.6 0.85", style="rounded"];
|
||||
0[label = "solve_network", color = "0.21 0.6 0.85", style="rounded"];
|
||||
1[label = "prepare_network\nll: copt\nopts: ", color = "0.51 0.6 0.85", style="rounded"];
|
||||
2[label = "add_extra_components", color = "0.43 0.6 0.85", style="rounded"];
|
||||
3[label = "cluster_network\nclusters: 6", color = "0.17 0.6 0.85", style="rounded"];
|
||||
4[label = "simplify_network\nsimpl: ", color = "0.49 0.6 0.85", style="rounded"];
|
||||
5[label = "add_electricity", color = "0.26 0.6 0.85", style="rounded"];
|
||||
6[label = "build_renewable_profiles\ntechnology: solar", color = "0.02 0.6 0.85", style="rounded"];
|
||||
7[label = "base_network", color = "0.35 0.6 0.85", style="rounded"];
|
||||
8[label = "build_shapes", color = "0.62 0.6 0.85", style="rounded"];
|
||||
9[label = "retrieve_databundle", color = "0.24 0.6 0.85", style="rounded"];
|
||||
10[label = "retrieve_cutout\ncutout: be-03-2013-era5", color = "0.36 0.6 0.85", style="rounded"];
|
||||
11[label = "build_renewable_profiles\ntechnology: solar-hsat", color = "0.02 0.6 0.85", style="rounded"];
|
||||
12[label = "build_renewable_profiles\ntechnology: onwind", color = "0.02 0.6 0.85", style="rounded"];
|
||||
13[label = "build_renewable_profiles\ntechnology: offwind-ac", color = "0.02 0.6 0.85", style="rounded"];
|
||||
14[label = "build_ship_raster", color = "0.08 0.6 0.85", style="rounded"];
|
||||
15[label = "retrieve_ship_raster", color = "0.28 0.6 0.85", style="rounded"];
|
||||
16[label = "build_renewable_profiles\ntechnology: offwind-dc", color = "0.02 0.6 0.85", style="rounded"];
|
||||
17[label = "build_renewable_profiles\ntechnology: offwind-float", color = "0.02 0.6 0.85", style="rounded"];
|
||||
18[label = "build_line_rating", color = "0.07 0.6 0.85", style="rounded"];
|
||||
19[label = "retrieve_cost_data\nyear: 2030", color = "0.47 0.6 0.85", style="rounded"];
|
||||
20[label = "build_powerplants", color = "0.11 0.6 0.85", style="rounded"];
|
||||
21[label = "build_electricity_demand", color = "0.05 0.6 0.85", style="rounded"];
|
||||
22[label = "retrieve_electricity_demand", color = "0.58 0.6 0.85", style="rounded"];
|
||||
23[label = "retrieve_synthetic_electricity_demand", color = "0.11 0.6 0.85", style="rounded"];
|
||||
1 -> 0
|
||||
23 -> 0
|
||||
2 -> 1
|
||||
19 -> 1
|
||||
3 -> 2
|
||||
@ -167,55 +165,55 @@ This triggers a workflow of multiple preceding jobs that depend on each rule's i
|
||||
19 -> 3
|
||||
5 -> 4
|
||||
19 -> 4
|
||||
11 -> 4
|
||||
7 -> 4
|
||||
6 -> 5
|
||||
11 -> 5
|
||||
12 -> 5
|
||||
13 -> 5
|
||||
14 -> 5
|
||||
16 -> 5
|
||||
17 -> 5
|
||||
7 -> 5
|
||||
18 -> 5
|
||||
19 -> 5
|
||||
11 -> 5
|
||||
20 -> 5
|
||||
9 -> 5
|
||||
21 -> 5
|
||||
8 -> 5
|
||||
7 -> 6
|
||||
9 -> 6
|
||||
10 -> 6
|
||||
8 -> 6
|
||||
11 -> 6
|
||||
12 -> 6
|
||||
10 -> 6
|
||||
8 -> 7
|
||||
9 -> 8
|
||||
8 -> 11
|
||||
7 -> 11
|
||||
9 -> 11
|
||||
8 -> 11
|
||||
10 -> 11
|
||||
7 -> 12
|
||||
9 -> 12
|
||||
8 -> 12
|
||||
10 -> 12
|
||||
7 -> 13
|
||||
9 -> 13
|
||||
10 -> 13
|
||||
14 -> 13
|
||||
8 -> 13
|
||||
11 -> 13
|
||||
12 -> 13
|
||||
7 -> 14
|
||||
9 -> 14
|
||||
10 -> 14
|
||||
10 -> 13
|
||||
15 -> 14
|
||||
8 -> 14
|
||||
11 -> 14
|
||||
12 -> 14
|
||||
16 -> 15
|
||||
12 -> 15
|
||||
10 -> 14
|
||||
7 -> 16
|
||||
9 -> 16
|
||||
14 -> 16
|
||||
8 -> 16
|
||||
10 -> 16
|
||||
7 -> 17
|
||||
9 -> 17
|
||||
10 -> 17
|
||||
15 -> 17
|
||||
14 -> 17
|
||||
8 -> 17
|
||||
11 -> 17
|
||||
12 -> 17
|
||||
10 -> 17
|
||||
7 -> 18
|
||||
12 -> 18
|
||||
10 -> 18
|
||||
7 -> 20
|
||||
22 -> 21
|
||||
23 -> 21
|
||||
}
|
||||
|
||||
|
|
||||
@ -227,27 +225,27 @@ In the terminal, this will show up as a list of jobs to be run:
|
||||
Building DAG of jobs...
|
||||
Job stats:
|
||||
job count
|
||||
--------------------------- -------
|
||||
------------------------------------- -------
|
||||
add_electricity 1
|
||||
add_extra_components 1
|
||||
base_network 1
|
||||
build_bus_regions 1
|
||||
build_electricity_demand 1
|
||||
build_line_rating 1
|
||||
build_powerplants 1
|
||||
build_renewable_profiles 4
|
||||
build_renewable_profiles 6
|
||||
build_shapes 1
|
||||
build_ship_raster 1
|
||||
cluster_network 1
|
||||
copy_config 1
|
||||
prepare_network 1
|
||||
retrieve_cost_data 1
|
||||
retrieve_cutout 1
|
||||
retrieve_databundle 1
|
||||
retrieve_electricity_demand 1
|
||||
retrieve_natura_raster 1
|
||||
retrieve_ship_raster 1
|
||||
retrieve_synthetic_electricity_demand 1
|
||||
simplify_network 1
|
||||
solve_network 1
|
||||
total 22
|
||||
total 24
|
||||
|
||||
|
||||
``snakemake`` then runs these jobs in the correct order.
|
||||
@ -256,16 +254,15 @@ A job (here ``simplify_network``) will display its attributes and normally some
|
||||
|
||||
.. code:: bash
|
||||
|
||||
[Mon Feb 19 17:06:17 2024]
|
||||
rule simplify_network:
|
||||
input: resources/test/networks/elec.nc, data/costs_2030.csv, resources/test/regions_onshore.geojson, resources/test/regions_offshore.geojson
|
||||
output: resources/test/networks/elec_s.nc, resources/test/regions_onshore_elec_s.geojson, resources/test/regions_offshore_elec_s.geojson, resources/test/busmap_elec_s.csv, resources/test/connection_costs_s.csv
|
||||
log: logs/test-elec/simplify_network/elec_s.log
|
||||
input: resources/test/networks/elec.nc, resources/test/costs_2030.csv, resources/test/regions_onshore.geojson, resources/test/regions_offshore.geojson
|
||||
output: resources/test/networks/elec_s.nc, resources/test/regions_onshore_elec_s.geojson, resources/test/regions_offshore_elec_s.geojson, resources/test/busmap_elec_s.csv
|
||||
log: logs/test/simplify_network/elec_s.log
|
||||
jobid: 4
|
||||
benchmark: benchmarks/test-elec/simplify_network/elec_s
|
||||
reason: Missing output files: resources/test/regions_offshore_elec_s.geojson, resources/test/busmap_elec_s.csv, resources/test/regions_onshore_elec_s.geojson, resources/test/networks/elec_s.nc; Input files updated by another job: resources/test/regions_offshore.geojson, resources/test/networks/elec.nc, resources/test/regions_onshore.geojson, data/costs_2030.csv
|
||||
benchmark: benchmarks/test/simplify_network/elec_s
|
||||
reason: Forced execution
|
||||
wildcards: simpl=
|
||||
resources: tmpdir=/tmp, mem_mb=12000, mem_mib=11445
|
||||
resources: tmpdir=<TBD>, mem_mb=12000, mem_mib=11445
|
||||
|
||||
Once the whole worktree is finished, it should state so in the terminal.
|
||||
|
||||
@ -283,7 +280,7 @@ For example, you can explore the evolution of the PyPSA networks by running
|
||||
#. ``snakemake resources/networks/elec.nc -call --configfile config/test/config.electricity.yaml``
|
||||
#. ``snakemake resources/networks/elec_s.nc -call --configfile config/test/config.electricity.yaml``
|
||||
#. ``snakemake resources/networks/elec_s_6.nc -call --configfile config/test/config.electricity.yaml``
|
||||
#. ``snakemake resources/networks/elec_s_6_ec_lcopt_Co2L-24H.nc -call --configfile config/test/config.electricity.yaml``
|
||||
#. ``snakemake resources/networks/elec_s_6_ec_lcopt_.nc -call --configfile config/test/config.electricity.yaml``
|
||||
|
||||
To run all combinations of wildcard values provided in the ``config/config.yaml`` under ``scenario:``,
|
||||
you can use the collection rule ``solve_elec_networks``.
|
||||
@ -321,6 +318,6 @@ Jupyter Notebooks).
|
||||
|
||||
import pypsa
|
||||
|
||||
n = pypsa.Network("results/networks/elec_s_6_ec_lcopt_Co2L-24H.nc")
|
||||
n = pypsa.Network("results/networks/elec_s_6_ec_lcopt_.nc")
|
||||
|
||||
For inspiration, read the `examples section in the PyPSA documentation <https://pypsa.readthedocs.io/en/latest/examples-basic.html>`_.
|
||||
For inspiration, read the `examples section in the PyPSA documentation <https://pypsa.readthedocs.io/en/latest/examples-basic.html>`__.
|
||||
|
@ -9,7 +9,7 @@ Validation
|
||||
|
||||
The PyPSA-Eur model workflow provides a built-in mechanism for validation. This allows users to contrast the outcomes of network optimization against the historical behaviour of the European power system. The snakemake rule ``validate_elec_networks`` enables this by generating comparative figures that encapsulate key data points such as dispatch carrier, cross-border flows, and market prices per price zone.
|
||||
|
||||
These comparisons utilize data from the 2019 ENTSO-E Transparency Platform. To enable this, an ENTSO-E API key must be inserted into the ``config.yaml`` file. Detailed steps for this process can be found in the user guide `here <https://transparency.entsoe.eu/content/static_content/Static%20content/web%20api/Guide.html>`_.
|
||||
These comparisons utilize data from the 2019 ENTSO-E Transparency Platform. To enable this, an ENTSO-E API key must be inserted into the ``config.yaml`` file. Detailed steps for this process can be found in the user guide `here <https://transparency.entsoe.eu/content/static_content/Static%20content/web%20api/Guide.html>`__.
|
||||
|
||||
Once the API key is set, the validation workflow can be triggered by running the following command:
|
||||
|
||||
@ -29,11 +29,11 @@ Results
|
||||
|
||||
By the time of writing the comparison with the historical data shows partially accurate, partially improvable results. The following figures show the comparison of the dispatch of the different carriers.
|
||||
|
||||
.. image:: ../graphics/validation_seasonal_operation_area_elec_s_37_ec_lv1.0_Ept.png
|
||||
.. image:: img/validation_seasonal_operation_area_elec_s_37_ec_lv1.0_Ept.png
|
||||
:width: 100%
|
||||
:align: center
|
||||
|
||||
.. image:: ../graphics/validation_production_bar_elec_s_37_ec_lv1.0_Ept.png
|
||||
.. image:: img/validation_production_bar_elec_s_37_ec_lv1.0_Ept.png
|
||||
:width: 100%
|
||||
:align: center
|
||||
|
||||
|
@ -17,7 +17,7 @@ what data to retrieve and what files to produce.
|
||||
|
||||
.. note::
|
||||
Detailed explanations of how wildcards work in ``snakemake`` can be found in the
|
||||
`relevant section of the documentation <https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#wildcards>`_.
|
||||
`relevant section of the documentation <https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#wildcards>`__.
|
||||
|
||||
.. _cutout_wc:
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -101,7 +101,7 @@ The ``{opts}`` wildcard
|
||||
The ``{opts}`` wildcard is used for electricity-only studies. It triggers
|
||||
optional constraints, which are activated in either :mod:`prepare_network` or
|
||||
the :mod:`solve_network` step. It may hold multiple triggers separated by ``-``,
|
||||
i.e. ``Co2L-3H`` contains the ``Co2L`` trigger and the ``3H`` switch. There are
|
||||
i.e. ``Co2L-3h`` contains the ``Co2L`` trigger and the ``3h`` switch. There are
|
||||
currently:
|
||||
|
||||
|
||||
@ -121,7 +121,7 @@ The ``{sector_opts}`` wildcard
|
||||
|
||||
# Co2Lx specifies the CO2 target in x% of the 1990 values; default will give default (5%);
|
||||
# Co2L0p25 will give 25% CO2 emissions; Co2Lm0p05 will give 5% negative emissions
|
||||
# xH is the temporal resolution; 3H is 3-hourly, i.e. one snapshot every 3 hours
|
||||
# xH is the temporal resolution; 3h is 3-hourly, i.e. one snapshot every 3 hours
|
||||
# single letters are sectors: T for land transport, H for building heating,
|
||||
# B for biomass supply, I for industry, shipping and aviation,
|
||||
# A for agriculture, forestry and fishing
|
||||
|
@ -4,58 +4,61 @@
|
||||
|
||||
name: pypsa-eur
|
||||
channels:
|
||||
- bioconda
|
||||
- http://conda.anaconda.org/gurobi
|
||||
- conda-forge
|
||||
- bioconda
|
||||
- gurobi
|
||||
- defaults
|
||||
dependencies:
|
||||
- _libgcc_mutex=0.1
|
||||
- _openmp_mutex=4.5
|
||||
- affine=2.4.0
|
||||
- alsa-lib=1.2.10
|
||||
- alsa-lib=1.2.11
|
||||
- ampl-mp=3.1.0
|
||||
- amply=0.1.6
|
||||
- appdirs=1.4.4
|
||||
- argparse-dataclass=2.0.0
|
||||
- asttokens=2.4.1
|
||||
- atk-1.0=2.38.0
|
||||
- atlite=0.2.12
|
||||
- attr=2.5.1
|
||||
- attrs=23.2.0
|
||||
- aws-c-auth=0.7.15
|
||||
- aws-c-cal=0.6.9
|
||||
- aws-c-common=0.9.12
|
||||
- aws-c-compression=0.2.17
|
||||
- aws-c-event-stream=0.4.1
|
||||
- aws-c-http=0.8.0
|
||||
- aws-c-io=0.14.3
|
||||
- aws-c-mqtt=0.10.1
|
||||
- aws-c-s3=0.5.0
|
||||
- aws-c-sdkutils=0.1.14
|
||||
- aws-checksums=0.1.17
|
||||
- aws-crt-cpp=0.26.1
|
||||
- aws-sdk-cpp=1.11.242
|
||||
- azure-core-cpp=1.10.3
|
||||
- aws-c-auth=0.7.22
|
||||
- aws-c-cal=0.6.14
|
||||
- aws-c-common=0.9.19
|
||||
- aws-c-compression=0.2.18
|
||||
- aws-c-event-stream=0.4.2
|
||||
- aws-c-http=0.8.1
|
||||
- aws-c-io=0.14.8
|
||||
- aws-c-mqtt=0.10.4
|
||||
- aws-c-s3=0.5.9
|
||||
- aws-c-sdkutils=0.1.16
|
||||
- aws-checksums=0.1.18
|
||||
- aws-crt-cpp=0.26.9
|
||||
- aws-sdk-cpp=1.11.329
|
||||
- azure-core-cpp=1.11.1
|
||||
- azure-identity-cpp=1.6.0
|
||||
- azure-storage-blobs-cpp=12.10.0
|
||||
- azure-storage-common-cpp=12.5.0
|
||||
- beautifulsoup4=4.12.3
|
||||
- blosc=1.21.5
|
||||
- bokeh=3.3.4
|
||||
- bottleneck=1.3.7
|
||||
- branca=0.7.1
|
||||
- bokeh=3.4.1
|
||||
- bottleneck=1.3.8
|
||||
- branca=0.7.2
|
||||
- brotli=1.1.0
|
||||
- brotli-bin=1.1.0
|
||||
- brotli-python=1.1.0
|
||||
- bzip2=1.0.8
|
||||
- c-ares=1.26.0
|
||||
- c-blosc2=2.13.2
|
||||
- c-ares=1.28.1
|
||||
- c-blosc2=2.14.4
|
||||
- ca-certificates=2024.2.2
|
||||
- cads-api-client=1.0.3
|
||||
- cairo=1.18.0
|
||||
- cartopy=0.22.0
|
||||
- cdsapi=0.6.1
|
||||
- cartopy=0.23.0
|
||||
- cdsapi=0.7.0
|
||||
- certifi=2024.2.2
|
||||
- cffi=1.16.0
|
||||
- cfgv=3.3.1
|
||||
- cfitsio=4.3.1
|
||||
- cfitsio=4.4.0
|
||||
- cftime=1.6.3
|
||||
- charset-normalizer=3.3.2
|
||||
- click=8.1.7
|
||||
@ -65,37 +68,40 @@ dependencies:
|
||||
- coin-or-cbc=2.10.10
|
||||
- coin-or-cgl=0.60.7
|
||||
- coin-or-clp=1.17.8
|
||||
- coin-or-osi=0.108.8
|
||||
- coin-or-utils=2.11.9
|
||||
- coin-or-osi=0.108.10
|
||||
- coin-or-utils=2.11.11
|
||||
- coincbc=2.10.10
|
||||
- colorama=0.4.6
|
||||
- conda-inject=1.3.1
|
||||
- configargparse=1.7
|
||||
- connection_pool=0.0.3
|
||||
- contourpy=1.2.0
|
||||
- contourpy=1.2.1
|
||||
- country_converter=1.2
|
||||
- cppad=20240000.2
|
||||
- cppad=20240000.4
|
||||
- cycler=0.12.1
|
||||
- cytoolz=0.12.3
|
||||
- dask=2024.2.0
|
||||
- dask-core=2024.2.0
|
||||
- dask=2024.5.1
|
||||
- dask-core=2024.5.1
|
||||
- dask-expr=1.1.1
|
||||
- datrie=0.8.2
|
||||
- dbus=1.13.6
|
||||
- decorator=5.1.1
|
||||
- deprecation=2.1.0
|
||||
- descartes=1.1.0
|
||||
- distlib=0.3.8
|
||||
- distributed=2024.2.0
|
||||
- distributed=2024.5.1
|
||||
- distro=1.9.0
|
||||
- docutils=0.20.1
|
||||
- docutils=0.21.2
|
||||
- dpath=2.1.6
|
||||
- entsoe-py=0.6.6
|
||||
- entsoe-py=0.6.7
|
||||
- et_xmlfile=1.1.0
|
||||
- exceptiongroup=1.2.0
|
||||
- executing=2.0.1
|
||||
- expat=2.5.0
|
||||
- filelock=3.13.1
|
||||
- fiona=1.9.5
|
||||
- folium=0.15.1
|
||||
- expat=2.6.2
|
||||
- filelock=3.14.0
|
||||
- fiona=1.9.6
|
||||
- fmt=10.2.1
|
||||
- folium=0.16.0
|
||||
- font-ttf-dejavu-sans-mono=2.37
|
||||
- font-ttf-inconsolata=3.000
|
||||
- font-ttf-source-code-pro=2.038
|
||||
@ -103,56 +109,59 @@ dependencies:
|
||||
- fontconfig=2.14.2
|
||||
- fonts-conda-ecosystem=1
|
||||
- fonts-conda-forge=1
|
||||
- fonttools=4.49.0
|
||||
- fonttools=4.52.1
|
||||
- freetype=2.12.1
|
||||
- freexl=2.0.0
|
||||
- fribidi=1.0.10
|
||||
- fsspec=2024.2.0
|
||||
- gdal=3.8.4
|
||||
- gdk-pixbuf=2.42.10
|
||||
- geographiclib=1.52
|
||||
- fsspec=2024.5.0
|
||||
- gdal=3.8.5
|
||||
- gdk-pixbuf=2.42.12
|
||||
- geographiclib=2.0
|
||||
- geojson-rewind=1.1.0
|
||||
- geopandas=0.14.3
|
||||
- geopandas-base=0.14.3
|
||||
- geopandas=0.14.4
|
||||
- geopandas-base=0.14.4
|
||||
- geopy=2.4.1
|
||||
- geos=3.12.1
|
||||
- geotiff=1.7.1
|
||||
- gettext=0.21.1
|
||||
- geotiff=1.7.3
|
||||
- gettext=0.22.5
|
||||
- gettext-tools=0.22.5
|
||||
- gflags=2.2.2
|
||||
- giflib=5.2.1
|
||||
- giflib=5.2.2
|
||||
- gitdb=4.0.11
|
||||
- gitpython=3.1.42
|
||||
- glib=2.78.4
|
||||
- glib-tools=2.78.4
|
||||
- glog=0.6.0
|
||||
- gitpython=3.1.43
|
||||
- glib=2.80.2
|
||||
- glib-tools=2.80.2
|
||||
- glog=0.7.0
|
||||
- glpk=5.0
|
||||
- gmp=6.3.0
|
||||
- graphite2=1.3.13
|
||||
- graphviz=9.0.0
|
||||
- gst-plugins-base=1.22.9
|
||||
- gstreamer=1.22.9
|
||||
- graphviz=11.0.0
|
||||
- gst-plugins-base=1.24.3
|
||||
- gstreamer=1.24.3
|
||||
- gtk2=2.24.33
|
||||
- gts=0.7.6
|
||||
- harfbuzz=8.3.0
|
||||
- gurobi=11.0.2
|
||||
- harfbuzz=8.5.0
|
||||
- hdf4=4.2.15
|
||||
- hdf5=1.14.3
|
||||
- humanfriendly=10.0
|
||||
- icu=73.2
|
||||
- identify=2.5.35
|
||||
- idna=3.6
|
||||
- importlib-metadata=7.0.1
|
||||
- importlib_metadata=7.0.1
|
||||
- importlib_resources=6.1.1
|
||||
- identify=2.5.36
|
||||
- idna=3.7
|
||||
- immutables=0.20
|
||||
- importlib-metadata=7.1.0
|
||||
- importlib_metadata=7.1.0
|
||||
- importlib_resources=6.4.0
|
||||
- iniconfig=2.0.0
|
||||
- ipopt=3.14.14
|
||||
- ipython=8.21.0
|
||||
- ipopt=3.14.16
|
||||
- ipython=8.24.0
|
||||
- jedi=0.19.1
|
||||
- jinja2=3.1.3
|
||||
- joblib=1.3.2
|
||||
- jinja2=3.1.4
|
||||
- joblib=1.4.2
|
||||
- json-c=0.17
|
||||
- jsonschema=4.21.1
|
||||
- jsonschema=4.22.0
|
||||
- jsonschema-specifications=2023.12.1
|
||||
- jupyter_core=5.7.1
|
||||
- jupyter_core=5.7.2
|
||||
- kealib=1.5.3
|
||||
- keyutils=1.6.1
|
||||
- kiwisolver=1.4.5
|
||||
@ -161,46 +170,48 @@ dependencies:
|
||||
- lcms2=2.16
|
||||
- ld_impl_linux-64=2.40
|
||||
- lerc=4.0.0
|
||||
- libabseil=20230802.1
|
||||
- libaec=1.1.2
|
||||
- libarchive=3.7.2
|
||||
- libarrow=15.0.0
|
||||
- libarrow-acero=15.0.0
|
||||
- libarrow-dataset=15.0.0
|
||||
- libarrow-flight=15.0.0
|
||||
- libarrow-flight-sql=15.0.0
|
||||
- libarrow-gandiva=15.0.0
|
||||
- libarrow-substrait=15.0.0
|
||||
- libabseil=20240116.2
|
||||
- libaec=1.1.3
|
||||
- libarchive=3.7.4
|
||||
- libarrow=16.1.0
|
||||
- libarrow-acero=16.1.0
|
||||
- libarrow-dataset=16.1.0
|
||||
- libarrow-substrait=16.1.0
|
||||
- libasprintf=0.22.5
|
||||
- libasprintf-devel=0.22.5
|
||||
- libblas=3.9.0
|
||||
- libboost-headers=1.84.0
|
||||
- libboost-headers=1.85.0
|
||||
- libbrotlicommon=1.1.0
|
||||
- libbrotlidec=1.1.0
|
||||
- libbrotlienc=1.1.0
|
||||
- libcap=2.69
|
||||
- libcblas=3.9.0
|
||||
- libclang=15.0.7
|
||||
- libclang13=15.0.7
|
||||
- libclang-cpp15=15.0.7
|
||||
- libclang13=18.1.5
|
||||
- libcrc32c=1.1.2
|
||||
- libcups=2.3.3
|
||||
- libcurl=8.5.0
|
||||
- libdeflate=1.19
|
||||
- libcurl=8.8.0
|
||||
- libdeflate=1.20
|
||||
- libedit=3.1.20191231
|
||||
- libev=4.33
|
||||
- libevent=2.1.12
|
||||
- libexpat=2.5.0
|
||||
- libexpat=2.6.2
|
||||
- libffi=3.4.2
|
||||
- libflac=1.4.3
|
||||
- libgcc-ng=13.2.0
|
||||
- libgcrypt=1.10.3
|
||||
- libgd=2.3.3
|
||||
- libgdal=3.8.4
|
||||
- libgdal=3.8.5
|
||||
- libgettextpo=0.22.5
|
||||
- libgettextpo-devel=0.22.5
|
||||
- libgfortran-ng=13.2.0
|
||||
- libgfortran5=13.2.0
|
||||
- libglib=2.78.4
|
||||
- libglib=2.80.2
|
||||
- libgomp=13.2.0
|
||||
- libgoogle-cloud=2.12.0
|
||||
- libgpg-error=1.47
|
||||
- libgrpc=1.60.1
|
||||
- libgoogle-cloud=2.24.0
|
||||
- libgoogle-cloud-storage=2.24.0
|
||||
- libgpg-error=1.49
|
||||
- libgrpc=1.62.2
|
||||
- libhwloc=2.9.3
|
||||
- libiconv=1.17
|
||||
- libjpeg-turbo=3.0.0
|
||||
@ -208,27 +219,26 @@ dependencies:
|
||||
- liblapack=3.9.0
|
||||
- liblapacke=3.9.0
|
||||
- libllvm15=15.0.7
|
||||
- libllvm18=18.1.6
|
||||
- libnetcdf=4.9.2
|
||||
- libnghttp2=1.58.0
|
||||
- libnl=3.9.0
|
||||
- libnsl=2.0.1
|
||||
- libnuma=2.0.16
|
||||
- libogg=1.3.4
|
||||
- libopenblas=0.3.26
|
||||
- libopenblas=0.3.27
|
||||
- libopus=1.3.1
|
||||
- libparquet=15.0.0
|
||||
- libpng=1.6.42
|
||||
- libpq=16.2
|
||||
- libprotobuf=4.25.1
|
||||
- libre2-11=2023.06.02
|
||||
- librsvg=2.56.3
|
||||
- libparquet=16.1.0
|
||||
- libpng=1.6.43
|
||||
- libpq=16.3
|
||||
- libprotobuf=4.25.3
|
||||
- libre2-11=2023.09.01
|
||||
- librsvg=2.58.0
|
||||
- librttopo=1.1.0
|
||||
- libscotch=7.0.4
|
||||
- libsndfile=1.2.2
|
||||
- libspatialindex=1.9.3
|
||||
- libspatialite=5.1.0
|
||||
- libspral=2023.09.07
|
||||
- libsqlite=3.45.1
|
||||
- libspral=2024.01.18
|
||||
- libsqlite=3.45.3
|
||||
- libssh2=1.11.0
|
||||
- libstdcxx-ng=13.2.0
|
||||
- libsystemd0=255
|
||||
@ -237,101 +247,104 @@ dependencies:
|
||||
- libutf8proc=2.8.0
|
||||
- libuuid=2.38.1
|
||||
- libvorbis=1.3.7
|
||||
- libwebp=1.3.2
|
||||
- libwebp-base=1.3.2
|
||||
- libwebp=1.4.0
|
||||
- libwebp-base=1.4.0
|
||||
- libxcb=1.15
|
||||
- libxcrypt=4.4.36
|
||||
- libxkbcommon=1.6.0
|
||||
- libxml2=2.12.5
|
||||
- libxkbcommon=1.7.0
|
||||
- libxml2=2.12.7
|
||||
- libxslt=1.1.39
|
||||
- libzip=1.10.1
|
||||
- libzlib=1.2.13
|
||||
- linopy=0.3.4
|
||||
- linopy=0.3.9
|
||||
- locket=1.0.0
|
||||
- lxml=5.1.0
|
||||
- lxml=5.2.2
|
||||
- lz4=4.3.3
|
||||
- lz4-c=1.9.4
|
||||
- lzo=2.10
|
||||
- mapclassify=2.6.1
|
||||
- markupsafe=2.1.5
|
||||
- matplotlib=3.8.3
|
||||
- matplotlib-base=3.8.3
|
||||
- matplotlib-inline=0.1.6
|
||||
- matplotlib=3.8.4
|
||||
- matplotlib-base=3.8.4
|
||||
- matplotlib-inline=0.1.7
|
||||
- memory_profiler=0.61.0
|
||||
- metis=5.1.0
|
||||
- minizip=4.0.4
|
||||
- mpg123=1.32.4
|
||||
- msgpack-python=1.0.7
|
||||
- mumps-include=5.6.2
|
||||
- mumps-seq=5.6.2
|
||||
- minizip=4.0.5
|
||||
- mpfr=4.2.1
|
||||
- mpg123=1.32.6
|
||||
- msgpack-python=1.0.8
|
||||
- multiurl=0.3.1
|
||||
- mumps-include=5.7.1
|
||||
- mumps-seq=5.7.1
|
||||
- munkres=1.1.4
|
||||
- mysql-common=8.0.33
|
||||
- mysql-libs=8.0.33
|
||||
- nbformat=5.9.2
|
||||
- ncurses=6.4
|
||||
- mysql-common=8.3.0
|
||||
- mysql-libs=8.3.0
|
||||
- nbformat=5.10.4
|
||||
- ncurses=6.5
|
||||
- netcdf4=1.6.5
|
||||
- networkx=3.2.1
|
||||
- networkx=3.3
|
||||
- nodeenv=1.8.0
|
||||
- nomkl=1.0
|
||||
- nspr=4.35
|
||||
- nss=3.98
|
||||
- nss=3.100
|
||||
- numexpr=2.9.0
|
||||
- numpy=1.26.4
|
||||
- openjdk=21.0.2
|
||||
- openjpeg=2.5.0
|
||||
- openjdk=22.0.1
|
||||
- openjpeg=2.5.2
|
||||
- openpyxl=3.1.2
|
||||
- openssl=3.2.1
|
||||
- orc=1.9.2
|
||||
- packaging=23.2
|
||||
- pandas=2.2.0
|
||||
- pango=1.50.14
|
||||
- parso=0.8.3
|
||||
- partd=1.4.1
|
||||
- openssl=3.3.0
|
||||
- orc=2.0.1
|
||||
- packaging=24.0
|
||||
- pandas=2.2.2
|
||||
- pango=1.52.2
|
||||
- parso=0.8.4
|
||||
- partd=1.4.2
|
||||
- patsy=0.5.6
|
||||
- pcre2=10.42
|
||||
- pcre2=10.43
|
||||
- pexpect=4.9.0
|
||||
- pickleshare=0.7.5
|
||||
- pillow=10.2.0
|
||||
- pillow=10.3.0
|
||||
- pip=24.0
|
||||
- pixman=0.43.2
|
||||
- pkgutil-resolve-name=1.3.10
|
||||
- plac=1.4.2
|
||||
- platformdirs=4.2.0
|
||||
- pluggy=1.4.0
|
||||
- plac=1.4.3
|
||||
- platformdirs=4.2.2
|
||||
- pluggy=1.5.0
|
||||
- ply=3.11
|
||||
- poppler=24.02.0
|
||||
- poppler=24.04.0
|
||||
- poppler-data=0.4.12
|
||||
- postgresql=16.2
|
||||
- powerplantmatching=0.5.11
|
||||
- pre-commit=3.6.2
|
||||
- progressbar2=4.3.2
|
||||
- proj=9.3.1
|
||||
- postgresql=16.3
|
||||
- powerplantmatching=0.5.15
|
||||
- pre-commit=3.7.1
|
||||
- progressbar2=4.4.2
|
||||
- proj=9.4.0
|
||||
- prompt-toolkit=3.0.42
|
||||
- psutil=5.9.8
|
||||
- pthread-stubs=0.4
|
||||
- ptyprocess=0.7.0
|
||||
- pulp=2.7.0
|
||||
- pulseaudio-client=16.1
|
||||
- pulp=2.8.0
|
||||
- pulseaudio-client=17.0
|
||||
- pure_eval=0.2.2
|
||||
- py-cpuinfo=9.0.0
|
||||
- pyarrow=15.0.0
|
||||
- pyarrow=16.1.0
|
||||
- pyarrow-core=16.1.0
|
||||
- pyarrow-hotfix=0.6
|
||||
- pycountry=22.3.5
|
||||
- pycparser=2.21
|
||||
- pygments=2.17.2
|
||||
- pycparser=2.22
|
||||
- pygments=2.18.0
|
||||
- pyomo=6.6.1
|
||||
- pyparsing=3.1.1
|
||||
- pyparsing=3.1.2
|
||||
- pyproj=3.6.1
|
||||
- pypsa=0.27.0
|
||||
- pypsa=0.28.0
|
||||
- pyqt=5.15.9
|
||||
- pyqt5-sip=12.12.2
|
||||
- pyscipopt=4.4.0
|
||||
- pyscipopt=5.0.1
|
||||
- pyshp=2.3.1
|
||||
- pysocks=1.7.1
|
||||
- pytables=3.9.2
|
||||
- pytest=8.0.0
|
||||
- python=3.11.8
|
||||
- python-dateutil=2.8.2
|
||||
- pytest=8.2.1
|
||||
- python=3.11.9
|
||||
- python-dateutil=2.9.0
|
||||
- python-fastjsonschema=2.19.1
|
||||
- python-tzdata=2024.1
|
||||
- python-utils=3.8.2
|
||||
@ -340,71 +353,74 @@ dependencies:
|
||||
- pyxlsb=1.0.10
|
||||
- pyyaml=6.0.1
|
||||
- qt-main=5.15.8
|
||||
- rasterio=1.3.9
|
||||
- rdma-core=50.0
|
||||
- re2=2023.06.02
|
||||
- rasterio=1.3.10
|
||||
- re2=2023.09.01
|
||||
- readline=8.2
|
||||
- referencing=0.33.0
|
||||
- requests=2.31.0
|
||||
- referencing=0.35.1
|
||||
- requests=2.32.2
|
||||
- reretry=0.11.8
|
||||
- rioxarray=0.15.1
|
||||
- rpds-py=0.18.0
|
||||
- rioxarray=0.15.5
|
||||
- rpds-py=0.18.1
|
||||
- rtree=1.2.0
|
||||
- s2n=1.4.3
|
||||
- scikit-learn=1.4.1.post1
|
||||
- scip=8.1.0
|
||||
- scipy=1.12.0
|
||||
- s2n=1.4.15
|
||||
- scikit-learn=1.5.0
|
||||
- scip=9.0.1
|
||||
- scipy=1.13.1
|
||||
- scotch=7.0.4
|
||||
- seaborn=0.13.2
|
||||
- seaborn-base=0.13.2
|
||||
- setuptools=69.1.0
|
||||
- setuptools-scm=8.0.4
|
||||
- setuptools_scm=8.0.4
|
||||
- shapely=2.0.2
|
||||
- setuptools=70.0.0
|
||||
- setuptools-scm=8.1.0
|
||||
- setuptools_scm=8.1.0
|
||||
- shapely=2.0.4
|
||||
- sip=6.7.12
|
||||
- six=1.16.0
|
||||
- smart_open=6.4.0
|
||||
- smart_open=7.0.4
|
||||
- smmap=5.0.0
|
||||
- snakemake-minimal=7.32.4
|
||||
- snappy=1.1.10
|
||||
- snakemake-interface-common=1.17.2
|
||||
- snakemake-interface-executor-plugins=9.1.1
|
||||
- snakemake-interface-report-plugins=1.0.0
|
||||
- snakemake-interface-storage-plugins=3.2.2
|
||||
- snakemake-minimal=8.11.6
|
||||
- snappy=1.2.0
|
||||
- snuggs=1.4.7
|
||||
- sortedcontainers=2.4.0
|
||||
- soupsieve=2.5
|
||||
- sqlite=3.45.1
|
||||
- spdlog=1.13.0
|
||||
- sqlite=3.45.3
|
||||
- stack_data=0.6.2
|
||||
- statsmodels=0.14.1
|
||||
- statsmodels=0.14.2
|
||||
- stopit=1.1.2
|
||||
- tabula-py=2.7.0
|
||||
- tabulate=0.9.0
|
||||
- tbb=2021.11.0
|
||||
- tblib=3.0.0
|
||||
- threadpoolctl=3.3.0
|
||||
- threadpoolctl=3.5.0
|
||||
- throttler=1.2.2
|
||||
- tiledb=2.20.0
|
||||
- tiledb=2.23.0
|
||||
- tk=8.6.13
|
||||
- toml=0.10.2
|
||||
- tomli=2.0.1
|
||||
- toolz=0.12.1
|
||||
- toposort=1.10
|
||||
- tornado=6.3.3
|
||||
- tqdm=4.66.2
|
||||
- traitlets=5.14.1
|
||||
- typing-extensions=4.9.0
|
||||
- typing_extensions=4.9.0
|
||||
- tornado=6.4
|
||||
- tqdm=4.66.4
|
||||
- traitlets=5.14.3
|
||||
- typing-extensions=4.11.0
|
||||
- typing_extensions=4.11.0
|
||||
- tzcode=2024a
|
||||
- tzdata=2024a
|
||||
- ucx=1.15.0
|
||||
- ukkonen=1.0.1
|
||||
- unidecode=1.3.8
|
||||
- unixodbc=2.3.12
|
||||
- uriparser=0.9.7
|
||||
- uriparser=0.9.8
|
||||
- urllib3=2.2.1
|
||||
- validators=0.22.0
|
||||
- virtualenv=20.25.0
|
||||
- validators=0.28.2
|
||||
- virtualenv=20.26.2
|
||||
- wcwidth=0.2.13
|
||||
- wheel=0.42.0
|
||||
- wheel=0.43.0
|
||||
- wrapt=1.16.0
|
||||
- xarray=2024.2.0
|
||||
- xarray=2024.5.0
|
||||
- xcb-util=0.4.0
|
||||
- xcb-util-image=0.4.0
|
||||
- xcb-util-keysyms=0.4.0
|
||||
@ -418,7 +434,7 @@ dependencies:
|
||||
- xorg-kbproto=1.0.7
|
||||
- xorg-libice=1.1.1
|
||||
- xorg-libsm=1.2.4
|
||||
- xorg-libx11=1.8.7
|
||||
- xorg-libx11=1.8.9
|
||||
- xorg-libxau=1.0.11
|
||||
- xorg-libxdmcp=1.1.3
|
||||
- xorg-libxext=1.3.4
|
||||
@ -432,7 +448,7 @@ dependencies:
|
||||
- xorg-xextproto=7.3.0
|
||||
- xorg-xf86vidmodeproto=2.3.1
|
||||
- xorg-xproto=7.0.31
|
||||
- xyzservices=2023.10.1
|
||||
- xyzservices=2024.4.0
|
||||
- xz=5.2.6
|
||||
- yaml=0.2.5
|
||||
- yte=1.5.4
|
||||
@ -440,7 +456,13 @@ dependencies:
|
||||
- zipp=3.17.0
|
||||
- zlib=1.2.13
|
||||
- zlib-ng=2.0.7
|
||||
- zstd=1.5.5
|
||||
- zstd=1.5.6
|
||||
- pip:
|
||||
- highspy==1.5.3
|
||||
- oauthlib==3.2.2
|
||||
- requests-oauthlib==1.3.1
|
||||
- snakemake-executor-plugin-cluster-generic==1.0.9
|
||||
- snakemake-executor-plugin-slurm==0.5.1
|
||||
- snakemake-executor-plugin-slurm-jobstep==0.2.1
|
||||
- snakemake-storage-plugin-http==0.2.3
|
||||
- tsam==2.3.1
|
||||
|
@ -1,6 +1,6 @@
|
||||
# SPDX-FileCopyrightText: : 2017-2024 The PyPSA-Eur Authors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
name: pypsa-eur
|
||||
channels:
|
||||
@ -11,7 +11,7 @@ dependencies:
|
||||
- pip
|
||||
|
||||
- atlite>=0.2.9
|
||||
- pypsa>=0.26.1
|
||||
- pypsa>=0.28
|
||||
- linopy
|
||||
- dask
|
||||
|
||||
@ -20,12 +20,12 @@ dependencies:
|
||||
- openpyxl!=3.1.1
|
||||
- pycountry
|
||||
- seaborn
|
||||
- snakemake-minimal>=8.5
|
||||
- snakemake-minimal>=8.11
|
||||
- memory_profiler
|
||||
- yaml
|
||||
- pytables
|
||||
- lxml
|
||||
- powerplantmatching>=0.5.5,!=0.5.9
|
||||
- powerplantmatching>=0.5.15
|
||||
- numpy
|
||||
- pandas>=2.1
|
||||
- geopandas>=0.11.0
|
||||
|
Before Width: | Height: | Size: 543 KiB |
Before Width: | Height: | Size: 975 KiB |
Before Width: | Height: | Size: 664 KiB |
@ -86,7 +86,9 @@ rule base_network:
|
||||
offshore_shapes=resources("offshore_shapes.geojson"),
|
||||
europe_shape=resources("europe_shape.geojson"),
|
||||
output:
|
||||
resources("networks/base.nc"),
|
||||
base_network=resources("networks/base.nc"),
|
||||
regions_onshore=resources("regions_onshore.geojson"),
|
||||
regions_offshore=resources("regions_offshore.geojson"),
|
||||
log:
|
||||
logs("base_network.log"),
|
||||
benchmark:
|
||||
@ -109,7 +111,7 @@ rule build_shapes:
|
||||
nuts3=ancient("data/bundle/NUTS_2013_60M_SH/data/NUTS_RG_60M_2013.shp"),
|
||||
nuts3pop=ancient("data/bundle/nama_10r_3popgdp.tsv.gz"),
|
||||
nuts3gdp=ancient("data/bundle/nama_10r_3gdp.tsv.gz"),
|
||||
ch_cantons=ancient("data/bundle/ch_cantons.csv"),
|
||||
ch_cantons=ancient("data/ch_cantons.csv"),
|
||||
ch_popgdp=ancient("data/bundle/je-e-21.03.02.xls"),
|
||||
output:
|
||||
country_shapes=resources("country_shapes.geojson"),
|
||||
@ -127,27 +129,6 @@ rule build_shapes:
|
||||
"../scripts/build_shapes.py"
|
||||
|
||||
|
||||
rule build_bus_regions:
|
||||
params:
|
||||
countries=config_provider("countries"),
|
||||
input:
|
||||
country_shapes=resources("country_shapes.geojson"),
|
||||
offshore_shapes=resources("offshore_shapes.geojson"),
|
||||
base_network=resources("networks/base.nc"),
|
||||
output:
|
||||
regions_onshore=resources("regions_onshore.geojson"),
|
||||
regions_offshore=resources("regions_offshore.geojson"),
|
||||
log:
|
||||
logs("build_bus_regions.log"),
|
||||
threads: 1
|
||||
resources:
|
||||
mem_mb=1000,
|
||||
conda:
|
||||
"../envs/environment.yaml"
|
||||
script:
|
||||
"../scripts/build_bus_regions.py"
|
||||
|
||||
|
||||
if config["enable"].get("build_cutout", False):
|
||||
|
||||
rule build_cutout:
|
||||
@ -172,27 +153,6 @@ if config["enable"].get("build_cutout", False):
|
||||
"../scripts/build_cutout.py"
|
||||
|
||||
|
||||
if config["enable"].get("build_natura_raster", False):
|
||||
|
||||
rule build_natura_raster:
|
||||
input:
|
||||
natura=ancient("data/bundle/natura/Natura2000_end2015.shp"),
|
||||
cutout=lambda w: "cutouts/"
|
||||
+ CDIR
|
||||
+ config_provider("atlite", "default_cutout")(w)
|
||||
+ ".nc",
|
||||
output:
|
||||
resources("natura.tiff"),
|
||||
resources:
|
||||
mem_mb=5000,
|
||||
log:
|
||||
logs("build_natura_raster.log"),
|
||||
conda:
|
||||
"../envs/environment.yaml"
|
||||
script:
|
||||
"../scripts/build_natura_raster.py"
|
||||
|
||||
|
||||
rule build_ship_raster:
|
||||
input:
|
||||
ship_density="data/shipdensity_global.zip",
|
||||
@ -220,7 +180,7 @@ rule determine_availability_matrix_MD_UA:
|
||||
wdpa="data/WDPA.gpkg",
|
||||
wdpa_marine="data/WDPA_WDOECM_marine.gpkg",
|
||||
gebco=lambda w: (
|
||||
"data/bundle/GEBCO_2014_2D.nc"
|
||||
"data/bundle/gebco/GEBCO_2014_2D.nc"
|
||||
if config_provider("renewable", w.technology)(w).get("max_depth")
|
||||
else []
|
||||
),
|
||||
@ -233,7 +193,7 @@ rule determine_availability_matrix_MD_UA:
|
||||
offshore_shapes=resources("offshore_shapes.geojson"),
|
||||
regions=lambda w: (
|
||||
resources("regions_onshore.geojson")
|
||||
if w.technology in ("onwind", "solar")
|
||||
if w.technology in ("onwind", "solar", "solar-hsat")
|
||||
else resources("regions_offshore.geojson")
|
||||
),
|
||||
cutout=lambda w: "cutouts/"
|
||||
@ -276,7 +236,7 @@ rule build_renewable_profiles:
|
||||
base_network=resources("networks/base.nc"),
|
||||
corine=ancient("data/bundle/corine/g250_clc06_V18_5.tif"),
|
||||
natura=lambda w: (
|
||||
resources("natura.tiff")
|
||||
"data/bundle/natura/natura.tiff"
|
||||
if config_provider("renewable", w.technology, "natura")(w)
|
||||
else []
|
||||
),
|
||||
@ -287,8 +247,11 @@ rule build_renewable_profiles:
|
||||
),
|
||||
gebco=ancient(
|
||||
lambda w: (
|
||||
"data/bundle/GEBCO_2014_2D.nc"
|
||||
if config_provider("renewable", w.technology)(w).get("max_depth")
|
||||
"data/bundle/gebco/GEBCO_2014_2D.nc"
|
||||
if (
|
||||
config_provider("renewable", w.technology)(w).get("max_depth")
|
||||
or config_provider("renewable", w.technology)(w).get("min_depth")
|
||||
)
|
||||
else []
|
||||
)
|
||||
),
|
||||
@ -301,7 +264,7 @@ rule build_renewable_profiles:
|
||||
offshore_shapes=resources("offshore_shapes.geojson"),
|
||||
regions=lambda w: (
|
||||
resources("regions_onshore.geojson")
|
||||
if w.technology in ("onwind", "solar")
|
||||
if w.technology in ("onwind", "solar", "solar-hsat")
|
||||
else resources("regions_offshore.geojson")
|
||||
),
|
||||
cutout=lambda w: "cutouts/"
|
||||
@ -360,7 +323,6 @@ rule build_hydro_profile:
|
||||
+ ".nc",
|
||||
output:
|
||||
profile=resources("profile_hydro.nc"),
|
||||
eia_hydro=resources("eia_hydro_stats.csv"),
|
||||
log:
|
||||
logs("build_hydro_profile.log"),
|
||||
resources:
|
||||
@ -423,6 +385,7 @@ rule add_electricity:
|
||||
electricity=config_provider("electricity"),
|
||||
conventional=config_provider("conventional"),
|
||||
costs=config_provider("costs"),
|
||||
foresight=config_provider("foresight"),
|
||||
drop_leap_day=config_provider("enable", "drop_leap_day"),
|
||||
input:
|
||||
unpack(input_profile_tech),
|
||||
@ -438,7 +401,7 @@ rule add_electricity:
|
||||
),
|
||||
regions=resources("regions_onshore.geojson"),
|
||||
powerplants=resources("powerplants.csv"),
|
||||
hydro_capacities=ancient("data/bundle/hydro_capacities.csv"),
|
||||
hydro_capacities=ancient("data/hydro_capacities.csv"),
|
||||
geth_hydro_capacities="data/geth2015_hydro_capacities.csv",
|
||||
unit_commitment="data/unit_commitment.csv",
|
||||
fuel_price=lambda w: (
|
||||
@ -488,7 +451,6 @@ rule simplify_network:
|
||||
regions_onshore=resources("regions_onshore_elec_s{simpl}.geojson"),
|
||||
regions_offshore=resources("regions_offshore_elec_s{simpl}.geojson"),
|
||||
busmap=resources("busmap_elec_s{simpl}.csv"),
|
||||
connection_costs=resources("connection_costs_s{simpl}.csv"),
|
||||
log:
|
||||
logs("simplify_network/elec_s{simpl}.log"),
|
||||
benchmark:
|
||||
|
@ -287,12 +287,13 @@ rule build_energy_totals:
|
||||
energy=config_provider("energy"),
|
||||
input:
|
||||
nuts3_shapes=resources("nuts3_shapes.geojson"),
|
||||
co2="data/bundle-sector/eea/UNFCCC_v23.csv",
|
||||
co2="data/bundle/eea/UNFCCC_v23.csv",
|
||||
swiss="data/switzerland-new_format-all_years.csv",
|
||||
swiss_transport="data/gr-e-11.03.02.01.01-cc.csv",
|
||||
idees="data/bundle-sector/jrc-idees-2015",
|
||||
idees="data/bundle/jrc-idees-2015",
|
||||
district_heat_share="data/district_heat_share.csv",
|
||||
eurostat="data/eurostat/eurostat-energy_balances-april_2023_edition",
|
||||
eurostat="data/eurostat/Balances-April2023",
|
||||
eurostat_households="data/eurostat/eurostat-household_energy_balances-february_2024.csv",
|
||||
output:
|
||||
energy_name=resources("energy_totals.csv"),
|
||||
co2_name=resources("co2_totals.csv"),
|
||||
@ -338,10 +339,10 @@ rule build_biomass_potentials:
|
||||
"https://zenodo.org/records/10356004/files/ENSPRESO_BIOMASS.xlsx",
|
||||
keep_local=True,
|
||||
),
|
||||
nuts2="data/bundle-sector/nuts/NUTS_RG_10M_2013_4326_LEVL_2.geojson", # https://gisco-services.ec.europa.eu/distribution/v2/nuts/download/#nuts21
|
||||
nuts2="data/bundle/nuts/NUTS_RG_10M_2013_4326_LEVL_2.geojson", # https://gisco-services.ec.europa.eu/distribution/v2/nuts/download/#nuts21
|
||||
regions_onshore=resources("regions_onshore_elec_s{simpl}_{clusters}.geojson"),
|
||||
nuts3_population=ancient("data/bundle/nama_10r_3popgdp.tsv.gz"),
|
||||
swiss_cantons=ancient("data/bundle/ch_cantons.csv"),
|
||||
swiss_cantons=ancient("data/ch_cantons.csv"),
|
||||
swiss_population=ancient("data/bundle/je-e-21.03.02.xls"),
|
||||
country_shapes=resources("country_shapes.geojson"),
|
||||
output:
|
||||
@ -416,7 +417,7 @@ rule build_sequestration_potentials:
|
||||
|
||||
rule build_salt_cavern_potentials:
|
||||
input:
|
||||
salt_caverns="data/bundle-sector/h2_salt_caverns_GWh_per_sqkm.geojson",
|
||||
salt_caverns="data/bundle/h2_salt_caverns_GWh_per_sqkm.geojson",
|
||||
regions_onshore=resources("regions_onshore_elec_s{simpl}_{clusters}.geojson"),
|
||||
regions_offshore=resources("regions_offshore_elec_s{simpl}_{clusters}.geojson"),
|
||||
output:
|
||||
@ -436,7 +437,7 @@ rule build_salt_cavern_potentials:
|
||||
|
||||
rule build_ammonia_production:
|
||||
input:
|
||||
usgs="data/bundle-sector/myb1-2017-nitro.xls",
|
||||
usgs="data/bundle/myb1-2017-nitro.xls",
|
||||
output:
|
||||
ammonia_production=resources("ammonia_production.csv"),
|
||||
threads: 1
|
||||
@ -458,7 +459,7 @@ rule build_industry_sector_ratios:
|
||||
ammonia=config_provider("sector", "ammonia", default=False),
|
||||
input:
|
||||
ammonia_production=resources("ammonia_production.csv"),
|
||||
idees="data/bundle-sector/jrc-idees-2015",
|
||||
idees="data/bundle/jrc-idees-2015",
|
||||
output:
|
||||
industry_sector_ratios=resources("industry_sector_ratios.csv"),
|
||||
threads: 1
|
||||
@ -508,8 +509,8 @@ rule build_industrial_production_per_country:
|
||||
countries=config_provider("countries"),
|
||||
input:
|
||||
ammonia_production=resources("ammonia_production.csv"),
|
||||
jrc="data/bundle-sector/jrc-idees-2015",
|
||||
eurostat="data/eurostat/eurostat-energy_balances-april_2023_edition",
|
||||
jrc="data/bundle/jrc-idees-2015",
|
||||
eurostat="data/eurostat/Balances-April2023",
|
||||
output:
|
||||
industrial_production_per_country=resources(
|
||||
"industrial_production_per_country.csv"
|
||||
@ -564,7 +565,10 @@ rule build_industrial_distribution_key:
|
||||
input:
|
||||
regions_onshore=resources("regions_onshore_elec_s{simpl}_{clusters}.geojson"),
|
||||
clustered_pop_layout=resources("pop_layout_elec_s{simpl}_{clusters}.csv"),
|
||||
hotmaps_industrial_database="data/bundle-sector/Industrial_Database.csv",
|
||||
hotmaps_industrial_database=storage(
|
||||
"https://gitlab.com/hotmaps/industrial_sites/industrial_sites_Industrial_Database/-/raw/master/data/Industrial_Database.csv",
|
||||
keep_local=True,
|
||||
),
|
||||
output:
|
||||
industrial_distribution_key=resources(
|
||||
"industrial_distribution_key_elec_s{simpl}_{clusters}.csv"
|
||||
@ -652,7 +656,7 @@ rule build_industrial_energy_demand_per_country_today:
|
||||
countries=config_provider("countries"),
|
||||
industry=config_provider("industry"),
|
||||
input:
|
||||
jrc="data/bundle-sector/jrc-idees-2015",
|
||||
jrc="data/bundle/jrc-idees-2015",
|
||||
industrial_production_per_country=resources(
|
||||
"industrial_production_per_country.csv"
|
||||
),
|
||||
@ -704,7 +708,7 @@ rule build_retro_cost:
|
||||
countries=config_provider("countries"),
|
||||
input:
|
||||
building_stock="data/retro/data_building_stock.csv",
|
||||
data_tabula="data/bundle-sector/retro/tabula-calculator-calcsetbuilding.csv",
|
||||
data_tabula="data/bundle/retro/tabula-calculator-calcsetbuilding.csv",
|
||||
air_temperature=resources("temp_air_total_elec_s{simpl}_{clusters}.nc"),
|
||||
u_values_PL="data/retro/u_values_poland.csv",
|
||||
tax_w="data/retro/electricity_taxes_eu.csv",
|
||||
@ -780,8 +784,8 @@ rule build_transport_demand:
|
||||
"pop_weighted_energy_totals_s{simpl}_{clusters}.csv"
|
||||
),
|
||||
transport_data=resources("transport_data.csv"),
|
||||
traffic_data_KFZ="data/bundle-sector/emobility/KFZ__count",
|
||||
traffic_data_Pkw="data/bundle-sector/emobility/Pkw__count",
|
||||
traffic_data_KFZ="data/bundle/emobility/KFZ__count",
|
||||
traffic_data_Pkw="data/bundle/emobility/Pkw__count",
|
||||
temp_air_total=resources("temp_air_total_elec_s{simpl}_{clusters}.nc"),
|
||||
output:
|
||||
transport_demand=resources("transport_demand_s{simpl}_{clusters}.csv"),
|
||||
@ -856,10 +860,44 @@ rule build_existing_heating_distribution:
|
||||
"../scripts/build_existing_heating_distribution.py"
|
||||
|
||||
|
||||
rule time_aggregation:
|
||||
params:
|
||||
time_resolution=config_provider("clustering", "temporal", "resolution_sector"),
|
||||
drop_leap_day=config_provider("enable", "drop_leap_day"),
|
||||
solver_name=config_provider("solving", "solver", "name"),
|
||||
input:
|
||||
network=resources("networks/elec_s{simpl}_{clusters}_ec_l{ll}_{opts}.nc"),
|
||||
hourly_heat_demand_total=lambda w: (
|
||||
resources("hourly_heat_demand_total_elec_s{simpl}_{clusters}.nc")
|
||||
if config_provider("sector", "heating")(w)
|
||||
else []
|
||||
),
|
||||
solar_thermal_total=lambda w: (
|
||||
resources("solar_thermal_total_elec_s{simpl}_{clusters}.nc")
|
||||
if config_provider("sector", "solar_thermal")(w)
|
||||
else []
|
||||
),
|
||||
output:
|
||||
snapshot_weightings=resources(
|
||||
"snapshot_weightings_elec_s{simpl}_{clusters}_ec_l{ll}_{opts}.csv"
|
||||
),
|
||||
threads: 1
|
||||
resources:
|
||||
mem_mb=5000,
|
||||
log:
|
||||
logs("time_aggregation_elec_s{simpl}_{clusters}_ec_l{ll}_{opts}.log"),
|
||||
benchmark:
|
||||
benchmarks("time_aggregation_elec_s{simpl}_{clusters}_ec_l{ll}_{opts}")
|
||||
conda:
|
||||
"../envs/environment.yaml"
|
||||
script:
|
||||
"../scripts/time_aggregation.py"
|
||||
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
@ -895,7 +933,6 @@ rule build_egs_potentials:
|
||||
rule prepare_sector_network:
|
||||
params:
|
||||
time_resolution=config_provider("clustering", "temporal", "resolution_sector"),
|
||||
drop_leap_day=config_provider("enable", "drop_leap_day"),
|
||||
co2_budget=config_provider("co2_budget"),
|
||||
conventional_carriers=config_provider(
|
||||
"existing_capacities", "conventional_carriers"
|
||||
@ -916,6 +953,9 @@ rule prepare_sector_network:
|
||||
unpack(input_profile_offwind),
|
||||
**rules.cluster_gas_network.output,
|
||||
**rules.build_gas_input_locations.output,
|
||||
snapshot_weightings=resources(
|
||||
"snapshot_weightings_elec_s{simpl}_{clusters}_ec_l{ll}_{opts}.csv"
|
||||
),
|
||||
retro_cost=lambda w: (
|
||||
resources("retro_cost_elec_s{simpl}_{clusters}.csv")
|
||||
if config_provider("sector", "retrofitting", "retro_endogen")(w)
|
||||
@ -940,7 +980,7 @@ rule prepare_sector_network:
|
||||
else []
|
||||
),
|
||||
network=resources("networks/elec_s{simpl}_{clusters}_ec_l{ll}_{opts}.nc"),
|
||||
eurostat="data/eurostat/eurostat-energy_balances-april_2023_edition",
|
||||
eurostat="data/eurostat/Balances-April2023",
|
||||
pop_weighted_energy_totals=resources(
|
||||
"pop_weighted_energy_totals_s{simpl}_{clusters}.csv"
|
||||
),
|
||||
@ -953,7 +993,7 @@ rule prepare_sector_network:
|
||||
avail_profile=resources("avail_profile_s{simpl}_{clusters}.csv"),
|
||||
dsm_profile=resources("dsm_profile_s{simpl}_{clusters}.csv"),
|
||||
co2_totals_name=resources("co2_totals.csv"),
|
||||
co2="data/bundle-sector/eea/UNFCCC_v23.csv",
|
||||
co2="data/bundle/eea/UNFCCC_v23.csv",
|
||||
biomass_potentials=lambda w: (
|
||||
resources(
|
||||
"biomass_potentials_s{simpl}_{clusters}_"
|
||||
|
@ -199,6 +199,7 @@ rule make_summary:
|
||||
energy=RESULTS + "csvs/energy.csv",
|
||||
supply=RESULTS + "csvs/supply.csv",
|
||||
supply_energy=RESULTS + "csvs/supply_energy.csv",
|
||||
nodal_supply_energy=RESULTS + "csvs/nodal_supply_energy.csv",
|
||||
prices=RESULTS + "csvs/prices.csv",
|
||||
weighted_prices=RESULTS + "csvs/weighted_prices.csv",
|
||||
market_values=RESULTS + "csvs/market_values.csv",
|
||||
@ -229,8 +230,8 @@ rule plot_summary:
|
||||
costs=RESULTS + "csvs/costs.csv",
|
||||
energy=RESULTS + "csvs/energy.csv",
|
||||
balances=RESULTS + "csvs/supply_energy.csv",
|
||||
eurostat="data/eurostat/eurostat-energy_balances-april_2023_edition",
|
||||
co2="data/bundle-sector/eea/UNFCCC_v23.csv",
|
||||
eurostat="data/eurostat/Balances-April2023",
|
||||
co2="data/bundle/eea/UNFCCC_v23.csv",
|
||||
output:
|
||||
costs=RESULTS + "graphs/costs.pdf",
|
||||
energy=RESULTS + "graphs/energy.pdf",
|
||||
|
@ -14,23 +14,27 @@ if config["enable"]["retrieve"] is False:
|
||||
|
||||
if config["enable"]["retrieve"] and config["enable"].get("retrieve_databundle", True):
|
||||
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",
|
||||
"eea/UNFCCC_v23.csv",
|
||||
"nuts/NUTS_RG_10M_2013_4326_LEVL_2.geojson",
|
||||
"myb1-2017-nitro.xls",
|
||||
"emobility/KFZ__count",
|
||||
"emobility/Pkw__count",
|
||||
"h2_salt_caverns_GWh_per_sqkm.geojson",
|
||||
"natura/natura.tiff",
|
||||
"gebco/GEBCO_2014_2D.nc",
|
||||
]
|
||||
|
||||
if not config.get("tutorial", False):
|
||||
datafiles.extend(["natura/Natura2000_end2015.shp", "GEBCO_2014_2D.nc"])
|
||||
|
||||
rule retrieve_databundle:
|
||||
output:
|
||||
protected(expand("data/bundle/{file}", file=datafiles)),
|
||||
expand("data/bundle/{file}", file=datafiles),
|
||||
directory("data/bundle/jrc-idees-2015"),
|
||||
log:
|
||||
"logs/retrieve_databundle.log",
|
||||
resources:
|
||||
@ -41,23 +45,23 @@ if config["enable"]["retrieve"] and config["enable"].get("retrieve_databundle",
|
||||
script:
|
||||
"../scripts/retrieve_databundle.py"
|
||||
|
||||
|
||||
if config["enable"].get("retrieve_irena"):
|
||||
|
||||
rule retrieve_irena:
|
||||
rule retrieve_eurostat_data:
|
||||
output:
|
||||
offwind="data/existing_infrastructure/offwind_capacity_IRENA.csv",
|
||||
onwind="data/existing_infrastructure/onwind_capacity_IRENA.csv",
|
||||
solar="data/existing_infrastructure/solar_capacity_IRENA.csv",
|
||||
directory("data/eurostat/Balances-April2023"),
|
||||
log:
|
||||
"logs/retrieve_irena.log",
|
||||
resources:
|
||||
mem_mb=1000,
|
||||
"logs/retrieve_eurostat_data.log",
|
||||
retries: 2
|
||||
conda:
|
||||
"../envs/retrieve.yaml"
|
||||
script:
|
||||
"../scripts/retrieve_irena.py"
|
||||
"../scripts/retrieve_eurostat_data.py"
|
||||
|
||||
rule retrieve_eurostat_household_data:
|
||||
output:
|
||||
"data/eurostat/eurostat-household_energy_balances-february_2024.csv",
|
||||
log:
|
||||
"logs/retrieve_eurostat_household_data.log",
|
||||
retries: 2
|
||||
script:
|
||||
"../scripts/retrieve_eurostat_household_data.py"
|
||||
|
||||
|
||||
if config["enable"]["retrieve"] and config["enable"].get("retrieve_cutout", True):
|
||||
@ -65,7 +69,7 @@ if config["enable"]["retrieve"] and config["enable"].get("retrieve_cutout", True
|
||||
rule retrieve_cutout:
|
||||
input:
|
||||
storage(
|
||||
"https://zenodo.org/record/6382570/files/{cutout}.nc",
|
||||
"https://zenodo.org/records/6382570/files/{cutout}.nc",
|
||||
),
|
||||
output:
|
||||
protected("cutouts/" + CDIR + "{cutout}.nc"),
|
||||
@ -97,64 +101,6 @@ if config["enable"]["retrieve"] and config["enable"].get("retrieve_cost_data", T
|
||||
"../scripts/retrieve_cost_data.py"
|
||||
|
||||
|
||||
if config["enable"]["retrieve"] and config["enable"].get(
|
||||
"retrieve_natura_raster", True
|
||||
):
|
||||
|
||||
rule retrieve_natura_raster:
|
||||
input:
|
||||
storage(
|
||||
"https://zenodo.org/record/4706686/files/natura.tiff",
|
||||
keep_local=True,
|
||||
),
|
||||
output:
|
||||
resources("natura.tiff"),
|
||||
log:
|
||||
logs("retrieve_natura_raster.log"),
|
||||
resources:
|
||||
mem_mb=5000,
|
||||
retries: 2
|
||||
run:
|
||||
copyfile(input[0], output[0])
|
||||
validate_checksum(output[0], input[0])
|
||||
|
||||
|
||||
if config["enable"]["retrieve"] and config["enable"].get(
|
||||
"retrieve_sector_databundle", True
|
||||
):
|
||||
datafiles = [
|
||||
"eea/UNFCCC_v23.csv",
|
||||
"switzerland-sfoe/switzerland-new_format.csv",
|
||||
"nuts/NUTS_RG_10M_2013_4326_LEVL_2.geojson",
|
||||
"myb1-2017-nitro.xls",
|
||||
"Industrial_Database.csv",
|
||||
"emobility/KFZ__count",
|
||||
"emobility/Pkw__count",
|
||||
"h2_salt_caverns_GWh_per_sqkm.geojson",
|
||||
]
|
||||
|
||||
rule retrieve_sector_databundle:
|
||||
output:
|
||||
protected(expand("data/bundle-sector/{files}", files=datafiles)),
|
||||
protected(directory("data/bundle-sector/jrc-idees-2015")),
|
||||
log:
|
||||
"logs/retrieve_sector_databundle.log",
|
||||
retries: 2
|
||||
conda:
|
||||
"../envs/retrieve.yaml"
|
||||
script:
|
||||
"../scripts/retrieve_sector_databundle.py"
|
||||
|
||||
rule retrieve_eurostat_data:
|
||||
output:
|
||||
directory("data/eurostat/eurostat-energy_balances-april_2023_edition"),
|
||||
log:
|
||||
"logs/retrieve_eurostat_data.log",
|
||||
retries: 2
|
||||
script:
|
||||
"../scripts/retrieve_eurostat_data.py"
|
||||
|
||||
|
||||
if config["enable"]["retrieve"]:
|
||||
datafiles = [
|
||||
"IGGIELGN_LNGs.geojson",
|
||||
@ -217,11 +163,11 @@ if config["enable"]["retrieve"]:
|
||||
rule retrieve_ship_raster:
|
||||
input:
|
||||
storage(
|
||||
"https://zenodo.org/record/6953563/files/shipdensity_global.zip",
|
||||
"https://zenodo.org/records/10973944/files/shipdensity_global.zip",
|
||||
keep_local=True,
|
||||
),
|
||||
output:
|
||||
protected("data/shipdensity_global.zip"),
|
||||
"data/shipdensity_global.zip",
|
||||
log:
|
||||
"logs/retrieve_ship_raster.log",
|
||||
resources:
|
||||
@ -239,7 +185,7 @@ if config["enable"]["retrieve"]:
|
||||
rule download_copernicus_land_cover:
|
||||
input:
|
||||
storage(
|
||||
"https://zenodo.org/record/3939050/files/PROBAV_LC100_global_v3.0.1_2019-nrt_Discrete-Classification-map_EPSG-4326.tif",
|
||||
"https://zenodo.org/records/3939050/files/PROBAV_LC100_global_v3.0.1_2019-nrt_Discrete-Classification-map_EPSG-4326.tif",
|
||||
),
|
||||
output:
|
||||
"data/Copernicus_LC100_global_v3.0.1_2019-nrt_Discrete-Classification-map_EPSG-4326.tif",
|
||||
@ -303,7 +249,7 @@ if config["enable"]["retrieve"]:
|
||||
zip="data/WDPA_shp.zip",
|
||||
folder=directory("data/WDPA"),
|
||||
output:
|
||||
gpkg=protected("data/WDPA.gpkg"),
|
||||
gpkg="data/WDPA.gpkg",
|
||||
run:
|
||||
shell("cp {input} {params.zip}")
|
||||
shell("unzip -o {params.zip} -d {params.folder}")
|
||||
@ -328,7 +274,7 @@ if config["enable"]["retrieve"]:
|
||||
zip="data/WDPA_WDOECM_marine.zip",
|
||||
folder=directory("data/WDPA_WDOECM_marine"),
|
||||
output:
|
||||
gpkg=protected("data/WDPA_WDOECM_marine.gpkg"),
|
||||
gpkg="data/WDPA_WDOECM_marine.gpkg",
|
||||
run:
|
||||
shell("cp {input} {params.zip}")
|
||||
shell("unzip -o {params.zip} -d {params.folder}")
|
||||
|
@ -26,9 +26,6 @@ rule add_existing_baseyear:
|
||||
existing_heating_distribution=resources(
|
||||
"existing_heating_distribution_elec_s{simpl}_{clusters}_{planning_horizons}.csv"
|
||||
),
|
||||
existing_solar="data/existing_infrastructure/solar_capacity_IRENA.csv",
|
||||
existing_onwind="data/existing_infrastructure/onwind_capacity_IRENA.csv",
|
||||
existing_offwind="data/existing_infrastructure/offwind_capacity_IRENA.csv",
|
||||
output:
|
||||
RESULTS
|
||||
+ "prenetworks-brownfield/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
|
||||
|
@ -25,9 +25,6 @@ rule add_existing_baseyear:
|
||||
"existing_heating_distribution_elec_s{simpl}_{clusters}_{planning_horizons}.csv"
|
||||
),
|
||||
existing_heating="data/existing_infrastructure/existing_heating_raw.csv",
|
||||
existing_solar="data/existing_infrastructure/solar_capacity_IRENA.csv",
|
||||
existing_onwind="data/existing_infrastructure/onwind_capacity_IRENA.csv",
|
||||
existing_offwind="data/existing_infrastructure/offwind_capacity_IRENA.csv",
|
||||
output:
|
||||
RESULTS
|
||||
+ "prenetworks-brownfield/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
|
||||
@ -35,7 +32,8 @@ rule add_existing_baseyear:
|
||||
planning_horizons=config["scenario"]["planning_horizons"][0], #only applies to baseyear
|
||||
threads: 1
|
||||
resources:
|
||||
mem_mb=2000,
|
||||
mem_mb=config_provider("solving", "mem_mb"),
|
||||
runtime=config_provider("solving", "runtime", default="24h"),
|
||||
log:
|
||||
logs(
|
||||
"add_existing_baseyear_elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.log"
|
||||
|
@ -59,10 +59,15 @@ def get_rdir(run):
|
||||
RDIR = run["name"] + "/"
|
||||
else:
|
||||
RDIR = ""
|
||||
|
||||
prefix = run.get("prefix", "")
|
||||
if prefix:
|
||||
RDIR = f"{prefix}/{RDIR}"
|
||||
|
||||
return RDIR
|
||||
|
||||
|
||||
def get_run_path(fn, dir, rdir, shared_resources):
|
||||
def get_run_path(fn, dir, rdir, shared_resources, exclude_from_shared):
|
||||
"""
|
||||
Dynamically provide paths based on shared resources and filename.
|
||||
|
||||
@ -82,6 +87,8 @@ def get_run_path(fn, dir, rdir, shared_resources):
|
||||
- If string is "base", special handling for shared "base" resources (see notes).
|
||||
- If random string other than "base", this folder is used instead of the `rdir` keyword.
|
||||
- If boolean, directly specifies if the resource is shared.
|
||||
exclude_from_shared: list
|
||||
List of filenames to exclude from shared resources. Only relevant if shared_resources is "base".
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -99,10 +106,12 @@ def get_run_path(fn, dir, rdir, shared_resources):
|
||||
existing_wildcards = set(re.findall(pattern, fn))
|
||||
irrelevant_wildcards = {"technology", "year", "scope", "kind"}
|
||||
no_relevant_wildcards = not existing_wildcards - irrelevant_wildcards
|
||||
no_elec_rule = not fn.startswith("networks/elec") and not fn.startswith(
|
||||
"add_electricity"
|
||||
not_shared_rule = (
|
||||
not fn.startswith("networks/elec")
|
||||
and not fn.startswith("add_electricity")
|
||||
and not any(fn.startswith(ex) for ex in exclude_from_shared)
|
||||
)
|
||||
is_shared = no_relevant_wildcards and no_elec_rule
|
||||
is_shared = no_relevant_wildcards and not_shared_rule
|
||||
rdir = "" if is_shared else rdir
|
||||
elif isinstance(shared_resources, str):
|
||||
rdir = shared_resources + "/"
|
||||
@ -116,7 +125,7 @@ def get_run_path(fn, dir, rdir, shared_resources):
|
||||
return f"{dir}{rdir}{fn}"
|
||||
|
||||
|
||||
def path_provider(dir, rdir, shared_resources):
|
||||
def path_provider(dir, rdir, shared_resources, exclude_from_shared):
|
||||
"""
|
||||
Returns a partial function that dynamically provides paths based on shared
|
||||
resources and the filename.
|
||||
@ -127,7 +136,13 @@ def path_provider(dir, rdir, shared_resources):
|
||||
A partial function that takes a filename as input and
|
||||
returns the path to the file based on the shared_resources parameter.
|
||||
"""
|
||||
return partial(get_run_path, dir=dir, rdir=rdir, shared_resources=shared_resources)
|
||||
return partial(
|
||||
get_run_path,
|
||||
dir=dir,
|
||||
rdir=rdir,
|
||||
shared_resources=shared_resources,
|
||||
exclude_from_shared=exclude_from_shared,
|
||||
)
|
||||
|
||||
|
||||
def get_opt(opts, expr, flags=None):
|
||||
@ -702,7 +717,7 @@ def update_config_from_wildcards(config, w, inplace=True):
|
||||
|
||||
def get_checksum_from_zenodo(file_url):
|
||||
parts = file_url.split("/")
|
||||
record_id = parts[parts.index("record") + 1]
|
||||
record_id = parts[parts.index("records") + 1]
|
||||
filename = parts[-1]
|
||||
|
||||
response = requests.get(f"https://zenodo.org/api/records/{record_id}", timeout=30)
|
||||
@ -741,7 +756,7 @@ def validate_checksum(file_path, zenodo_url=None, checksum=None):
|
||||
>>> validate_checksum("/path/to/file", checksum="md5:abc123...")
|
||||
>>> validate_checksum(
|
||||
... "/path/to/file",
|
||||
... zenodo_url="https://zenodo.org/record/12345/files/example.txt",
|
||||
... zenodo_url="https://zenodo.org/records/12345/files/example.txt",
|
||||
... )
|
||||
|
||||
If the checksum is invalid, an AssertionError will be raised.
|
||||
|
@ -40,8 +40,8 @@ def add_brownfield(n, n_p, year):
|
||||
# CO2 or global EU values since these are already in n
|
||||
n_p.mremove(c.name, c.df.index[c.df.lifetime == np.inf])
|
||||
|
||||
# remove assets whose build_year + lifetime < year
|
||||
n_p.mremove(c.name, c.df.index[c.df.build_year + c.df.lifetime < year])
|
||||
# remove assets whose build_year + lifetime <= year
|
||||
n_p.mremove(c.name, c.df.index[c.df.build_year + c.df.lifetime <= year])
|
||||
|
||||
# remove assets if their optimized nominal capacity is lower than a threshold
|
||||
# since CHP heat Link is proportional to CHP electric Link, make sure threshold is compatible
|
||||
@ -107,20 +107,16 @@ def add_brownfield(n, n_p, year):
|
||||
# already retrofitted capacity from gas -> H2
|
||||
already_retrofitted = (
|
||||
n.links.loc[h2_retrofitted_fixed_i, "p_nom"]
|
||||
.rename(lambda x: x.split("-2")[0].replace(fr, to))
|
||||
.rename(lambda x: x.split("-2")[0].replace(fr, to) + f"-{year}")
|
||||
.groupby(level=0)
|
||||
.sum()
|
||||
)
|
||||
remaining_capacity = (
|
||||
pipe_capacity
|
||||
- CH4_per_H2
|
||||
* already_retrofitted.reindex(index=pipe_capacity.index).fillna(0)
|
||||
)
|
||||
remaining_capacity = pipe_capacity - CH4_per_H2 * already_retrofitted.reindex(
|
||||
index=pipe_capacity.index
|
||||
).fillna(0)
|
||||
n.links.loc[gas_pipes_i, "p_nom"] = remaining_capacity
|
||||
else:
|
||||
new_pipes = n.links.carrier.isin(pipe_carrier) & (
|
||||
n.links.build_year == year
|
||||
)
|
||||
new_pipes = n.links.carrier.isin(pipe_carrier) & (n.links.build_year == year)
|
||||
n.links.loc[new_pipes, "p_nom"] = 0.0
|
||||
n.links.loc[new_pipes, "p_nom_min"] = 0.0
|
||||
|
||||
@ -136,22 +132,20 @@ def disable_grid_expansion_if_limit_hit(n):
|
||||
minimum and extendable is turned off; the corresponding global
|
||||
constraint is then dropped.
|
||||
"""
|
||||
cols = {"cost": "capital_cost", "volume": "length"}
|
||||
for limit_type in ["cost", "volume"]:
|
||||
glcs = n.global_constraints.query(
|
||||
f"type == 'transmission_expansion_{limit_type}_limit'"
|
||||
)
|
||||
types = {"expansion_cost": "capital_cost", "volume_expansion": "length"}
|
||||
for limit_type in types:
|
||||
glcs = n.global_constraints.query(f"type == 'transmission_{limit_type}_limit'")
|
||||
|
||||
for name, glc in glcs.iterrows():
|
||||
total_expansion = (
|
||||
(
|
||||
n.lines.query("s_nom_extendable")
|
||||
.eval(f"s_nom_min * {cols[limit_type]}")
|
||||
.eval(f"s_nom_min * {types[limit_type]}")
|
||||
.sum()
|
||||
)
|
||||
+ (
|
||||
n.links.query("carrier == 'DC' and p_nom_extendable")
|
||||
.eval(f"p_nom_min * {cols[limit_type]}")
|
||||
.eval(f"p_nom_min * {types[limit_type]}")
|
||||
.sum()
|
||||
)
|
||||
).sum()
|
||||
@ -201,6 +195,7 @@ def adjust_renewable_profiles(n, input_profiles, params, year):
|
||||
for carrier in params["carriers"]:
|
||||
if carrier == "hydro":
|
||||
continue
|
||||
|
||||
with xr.open_dataset(getattr(input_profiles, "profile_" + carrier)) as ds:
|
||||
if ds.indexes["bus"].empty or "year" not in ds.indexes:
|
||||
continue
|
||||
|
@ -46,7 +46,7 @@ Inputs
|
||||
------
|
||||
|
||||
- ``resources/costs.csv``: The database of cost assumptions for all included technologies for specific years from various sources; e.g. discount rate, lifetime, investment (CAPEX), fixed operation and maintenance (FOM), variable operation and maintenance (VOM), fuel costs, efficiency, carbon-dioxide intensity.
|
||||
- ``data/bundle/hydro_capacities.csv``: Hydropower plant store/discharge power capacities, energy storage capacity, and average hourly inflow by country.
|
||||
- ``data/hydro_capacities.csv``: Hydropower plant store/discharge power capacities, energy storage capacity, and average hourly inflow by country.
|
||||
|
||||
.. image:: img/hydrocapacities.png
|
||||
:scale: 34 %
|
||||
@ -230,10 +230,9 @@ def load_costs(tech_costs, config, max_hours, Nyears=1.0):
|
||||
costs.at["OCGT", "co2_emissions"] = costs.at["gas", "co2_emissions"]
|
||||
costs.at["CCGT", "co2_emissions"] = costs.at["gas", "co2_emissions"]
|
||||
|
||||
costs.at["solar", "capital_cost"] = (
|
||||
config["rooftop_share"] * costs.at["solar-rooftop", "capital_cost"]
|
||||
+ (1 - config["rooftop_share"]) * costs.at["solar-utility", "capital_cost"]
|
||||
)
|
||||
costs.at["solar", "capital_cost"] = costs.at["solar-utility", "capital_cost"]
|
||||
|
||||
costs = costs.rename({"solar-utility single-axis tracking": "solar-hsat"})
|
||||
|
||||
def costs_for_storage(store, link1, link2=None, max_hours=1.0):
|
||||
capital_cost = link1["capital_cost"] + max_hours * store["capital_cost"]
|
||||
@ -271,7 +270,6 @@ def load_powerplants(ppl_fn):
|
||||
"bioenergy": "biomass",
|
||||
"ccgt, thermal": "CCGT",
|
||||
"hard coal": "coal",
|
||||
"natural gas": "OCGT",
|
||||
}
|
||||
return (
|
||||
pd.read_csv(ppl_fn, index_col=0, dtype={"bus": "str"})
|
||||
@ -450,8 +448,6 @@ def attach_conventional_generators(
|
||||
fuel_price=None,
|
||||
):
|
||||
carriers = list(set(conventional_carriers) | set(extendable_carriers["Generator"]))
|
||||
add_missing_carriers(n, carriers)
|
||||
add_co2_emissions(n, costs, carriers)
|
||||
|
||||
# Replace carrier "natural gas" with the respective technology (OCGT or
|
||||
# CCGT) to align with PyPSA names of "carriers" and avoid filtering "natural
|
||||
@ -467,6 +463,11 @@ def attach_conventional_generators(
|
||||
)
|
||||
ppl["efficiency"] = ppl.efficiency.fillna(ppl.efficiency_r)
|
||||
|
||||
# reduce carriers to those in power plant dataset
|
||||
carriers = list(set(carriers) & set(ppl.carrier.unique()))
|
||||
add_missing_carriers(n, carriers)
|
||||
add_co2_emissions(n, costs, carriers)
|
||||
|
||||
if unit_commitment is not None:
|
||||
committable_attrs = ppl.carrier.isin(unit_commitment).to_frame("committable")
|
||||
for attr in unit_commitment.index:
|
||||
@ -883,12 +884,19 @@ if __name__ == "__main__":
|
||||
|
||||
estimate_renewable_caps = params.electricity["estimate_renewable_capacities"]
|
||||
if estimate_renewable_caps["enable"]:
|
||||
if params.foresight != "overnight":
|
||||
logger.info(
|
||||
"Skipping renewable capacity estimation because they are added later "
|
||||
"in rule `add_existing_baseyear` with foresight mode 'myopic'."
|
||||
)
|
||||
else:
|
||||
tech_map = estimate_renewable_caps["technology_mapping"]
|
||||
expansion_limit = estimate_renewable_caps["expansion_limit"]
|
||||
year = estimate_renewable_caps["year"]
|
||||
|
||||
if estimate_renewable_caps["from_opsd"]:
|
||||
attach_OPSD_renewables(n, tech_map)
|
||||
|
||||
estimate_renewable_capacities(
|
||||
n, year, tech_map, expansion_limit, params.countries
|
||||
)
|
||||
|
@ -13,6 +13,7 @@ from types import SimpleNamespace
|
||||
import country_converter as coco
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import powerplantmatching as pm
|
||||
import pypsa
|
||||
import xarray as xr
|
||||
from _helpers import (
|
||||
@ -55,19 +56,27 @@ def add_build_year_to_new_assets(n, baseyear):
|
||||
c.pnl[attr] = c.pnl[attr].rename(columns=rename)
|
||||
|
||||
|
||||
def add_existing_renewables(df_agg):
|
||||
def add_existing_renewables(df_agg, costs):
|
||||
"""
|
||||
Append existing renewables to the df_agg pd.DataFrame with the conventional
|
||||
power plants.
|
||||
"""
|
||||
carriers = {"solar": "solar", "onwind": "onwind", "offwind": "offwind-ac"}
|
||||
tech_map = {"solar": "PV", "onwind": "Onshore", "offwind": "Offshore"}
|
||||
|
||||
for tech in ["solar", "onwind", "offwind"]:
|
||||
carrier = carriers[tech]
|
||||
countries = snakemake.config["countries"] # noqa: F841
|
||||
irena = pm.data.IRENASTAT().powerplant.convert_country_to_alpha2()
|
||||
irena = irena.query("Country in @countries")
|
||||
irena = irena.groupby(["Technology", "Country", "Year"]).Capacity.sum()
|
||||
|
||||
df = pd.read_csv(snakemake.input[f"existing_{tech}"], index_col=0).fillna(0.0)
|
||||
irena = irena.unstack().reset_index()
|
||||
|
||||
for carrier, tech in tech_map.items():
|
||||
df = (
|
||||
irena[irena.Technology.str.contains(tech)]
|
||||
.drop(columns=["Technology"])
|
||||
.set_index("Country")
|
||||
)
|
||||
df.columns = df.columns.astype(int)
|
||||
df.index = cc.convert(df.index, to="iso2")
|
||||
|
||||
# calculate yearly differences
|
||||
df.insert(loc=0, value=0.0, column="1999")
|
||||
@ -97,12 +106,16 @@ def add_existing_renewables(df_agg):
|
||||
|
||||
for year in nodal_df.columns:
|
||||
for node in nodal_df.index:
|
||||
name = f"{node}-{tech}-{year}"
|
||||
name = f"{node}-{carrier}-{year}"
|
||||
capacity = nodal_df.loc[node, year]
|
||||
if capacity > 0.0:
|
||||
df_agg.at[name, "Fueltype"] = tech
|
||||
df_agg.at[name, "Fueltype"] = carrier
|
||||
df_agg.at[name, "Capacity"] = capacity
|
||||
df_agg.at[name, "DateIn"] = year
|
||||
df_agg.at[name, "lifetime"] = costs.at[carrier, "lifetime"]
|
||||
df_agg.at[name, "DateOut"] = (
|
||||
year + costs.at[carrier, "lifetime"] - 1
|
||||
)
|
||||
df_agg.at[name, "cluster_bus"] = node
|
||||
|
||||
|
||||
@ -150,7 +163,7 @@ def add_power_capacities_installed_before_baseyear(n, grouping_years, costs, bas
|
||||
|
||||
technology_to_drop = ["Pv", "Storage Technologies"]
|
||||
|
||||
# drop unused fueltyps and technologies
|
||||
# drop unused fueltypes and technologies
|
||||
df_agg.drop(df_agg.index[df_agg.Fueltype.isin(fueltype_to_drop)], inplace=True)
|
||||
df_agg.drop(df_agg.index[df_agg.Technology.isin(technology_to_drop)], inplace=True)
|
||||
df_agg.Fueltype = df_agg.Fueltype.map(rename_fuel)
|
||||
@ -167,10 +180,6 @@ def add_power_capacities_installed_before_baseyear(n, grouping_years, costs, bas
|
||||
)
|
||||
df_agg.loc[biomass_i, "DateOut"] = df_agg.loc[biomass_i, "DateOut"].fillna(dateout)
|
||||
|
||||
# drop assets which are already phased out / decommissioned
|
||||
phased_out = df_agg[df_agg["DateOut"] < baseyear].index
|
||||
df_agg.drop(phased_out, inplace=True)
|
||||
|
||||
# assign clustered bus
|
||||
busmap_s = pd.read_csv(snakemake.input.busmap_s, index_col=0).squeeze()
|
||||
busmap = pd.read_csv(snakemake.input.busmap, index_col=0).squeeze()
|
||||
@ -185,10 +194,25 @@ def add_power_capacities_installed_before_baseyear(n, grouping_years, costs, bas
|
||||
df_agg["cluster_bus"] = df_agg.bus.map(clustermaps)
|
||||
|
||||
# include renewables in df_agg
|
||||
add_existing_renewables(df_agg)
|
||||
add_existing_renewables(df_agg, costs)
|
||||
|
||||
# drop assets which are already phased out / decommissioned
|
||||
phased_out = df_agg[df_agg["DateOut"] < baseyear].index
|
||||
df_agg.drop(phased_out, inplace=True)
|
||||
|
||||
older_assets = (df_agg.DateIn < min(grouping_years)).sum()
|
||||
if older_assets:
|
||||
logger.warning(
|
||||
f"There are {older_assets} assets with build year "
|
||||
f"before first power grouping year {min(grouping_years)}. "
|
||||
"These assets are dropped and not considered."
|
||||
"Consider to redefine the grouping years to keep them."
|
||||
)
|
||||
to_drop = df_agg[df_agg.DateIn < min(grouping_years)].index
|
||||
df_agg.drop(to_drop, inplace=True)
|
||||
|
||||
df_agg["grouping_year"] = np.take(
|
||||
grouping_years, np.digitize(df_agg.DateIn, grouping_years, right=True)
|
||||
grouping_years[::-1], np.digitize(df_agg.DateIn, grouping_years[::-1])
|
||||
)
|
||||
|
||||
# calculate (adjusted) remaining lifetime before phase-out (+1 because assuming
|
||||
@ -228,6 +252,7 @@ def add_power_capacities_installed_before_baseyear(n, grouping_years, costs, bas
|
||||
]
|
||||
suffix = "-ac" if generator == "offwind" else ""
|
||||
name_suffix = f" {generator}{suffix}-{grouping_year}"
|
||||
name_suffix_by = f" {generator}{suffix}-{baseyear}"
|
||||
asset_i = capacity.index + name_suffix
|
||||
if generator in ["solar", "onwind", "offwind"]:
|
||||
# to consider electricity grid connection costs or a split between
|
||||
@ -257,11 +282,11 @@ def add_power_capacities_installed_before_baseyear(n, grouping_years, costs, bas
|
||||
|
||||
# for offshore the splitting only includes coastal regions
|
||||
inv_ind = [
|
||||
i for i in inv_ind if (i + name_suffix) in n.generators.index
|
||||
i for i in inv_ind if (i + name_suffix_by) in n.generators.index
|
||||
]
|
||||
|
||||
p_max_pu = n.generators_t.p_max_pu[
|
||||
[i + name_suffix for i in inv_ind]
|
||||
[i + name_suffix_by for i in inv_ind]
|
||||
]
|
||||
p_max_pu.columns = [i + name_suffix for i in inv_ind]
|
||||
|
||||
@ -281,15 +306,13 @@ def add_power_capacities_installed_before_baseyear(n, grouping_years, costs, bas
|
||||
)
|
||||
|
||||
else:
|
||||
p_max_pu = n.generators_t.p_max_pu[
|
||||
capacity.index + f" {generator}{suffix}-{baseyear}"
|
||||
]
|
||||
p_max_pu = n.generators_t.p_max_pu[capacity.index + name_suffix_by]
|
||||
|
||||
if not new_build.empty:
|
||||
n.madd(
|
||||
"Generator",
|
||||
new_capacity.index,
|
||||
suffix=" " + name_suffix,
|
||||
suffix=name_suffix,
|
||||
bus=new_capacity.index,
|
||||
carrier=generator,
|
||||
p_nom=new_capacity,
|
||||
@ -352,13 +375,20 @@ def add_power_capacities_installed_before_baseyear(n, grouping_years, costs, bas
|
||||
)
|
||||
else:
|
||||
key = "central solid biomass CHP"
|
||||
central_heat = n.buses.query(
|
||||
"carrier == 'urban central heat'"
|
||||
).location.unique()
|
||||
heat_buses = new_capacity.index.map(
|
||||
lambda i: i + " urban central heat" if i in central_heat else ""
|
||||
)
|
||||
|
||||
n.madd(
|
||||
"Link",
|
||||
new_capacity.index,
|
||||
suffix=name_suffix,
|
||||
bus0=spatial.biomass.df.loc[new_capacity.index]["nodes"].values,
|
||||
bus1=new_capacity.index,
|
||||
bus2=new_capacity.index + " urban central heat",
|
||||
bus2=heat_buses,
|
||||
carrier=generator,
|
||||
p_nom=new_capacity / costs.at[key, "efficiency"],
|
||||
capital_cost=costs.at[key, "fixed"]
|
||||
@ -402,7 +432,7 @@ def add_heating_capacities_installed_before_baseyear(
|
||||
linear decommissioning of heating capacities from 2020 to 2045 is
|
||||
currently assumed heating capacities split between residential and
|
||||
services proportional to heating load in both 50% capacities
|
||||
in rural busess 50% in urban buses
|
||||
in rural buses 50% in urban buses
|
||||
"""
|
||||
logger.debug(f"Adding heating capacities installed before {baseyear}")
|
||||
|
||||
@ -410,8 +440,6 @@ def add_heating_capacities_installed_before_baseyear(
|
||||
snakemake.input.existing_heating_distribution, header=[0, 1], index_col=0
|
||||
)
|
||||
|
||||
techs = existing_heating.columns.get_level_values(1).unique()
|
||||
|
||||
for name in existing_heating.columns.get_level_values(0).unique():
|
||||
name_type = "central" if name == "urban central" else "decentral"
|
||||
|
||||
@ -434,12 +462,25 @@ def add_heating_capacities_installed_before_baseyear(
|
||||
else:
|
||||
efficiency = costs.at[costs_name, "efficiency"]
|
||||
|
||||
for i, grouping_year in enumerate(grouping_years):
|
||||
if int(grouping_year) + default_lifetime <= int(baseyear):
|
||||
continue
|
||||
valid_grouping_years = pd.Series(
|
||||
[
|
||||
int(grouping_year)
|
||||
for grouping_year in grouping_years
|
||||
if int(grouping_year) + default_lifetime > int(baseyear)
|
||||
and int(grouping_year) < int(baseyear)
|
||||
]
|
||||
)
|
||||
|
||||
# installation is assumed to be linear for the past default_lifetime years
|
||||
ratio = (int(grouping_year) - int(grouping_years[i - 1])) / default_lifetime
|
||||
# get number of years of each interval
|
||||
_years = (
|
||||
valid_grouping_years.diff()
|
||||
.shift(-1)
|
||||
.fillna(baseyear - valid_grouping_years.iloc[-1])
|
||||
)
|
||||
# Installation is assumed to be linear for the past
|
||||
ratios = _years / _years.sum()
|
||||
|
||||
for ratio, grouping_year in zip(ratios, valid_grouping_years):
|
||||
|
||||
n.madd(
|
||||
"Link",
|
||||
|
@ -246,6 +246,7 @@ if __name__ == "__main__":
|
||||
attach_hydrogen_pipelines(n, costs, extendable_carriers)
|
||||
|
||||
sanitize_carriers(n, snakemake.config)
|
||||
if "location" in n.buses:
|
||||
sanitize_locations(n)
|
||||
|
||||
n.meta = dict(snakemake.config, **dict(wildcards=dict(snakemake.wildcards)))
|
||||
|
@ -5,10 +5,7 @@
|
||||
|
||||
# coding: utf-8
|
||||
"""
|
||||
Creates the network topology from a `ENTSO-E map extract.
|
||||
|
||||
<https://github.com/PyPSA/GridKit/tree/master/entsoe>`_ (March 2022) as a PyPSA
|
||||
network.
|
||||
Creates the network topology from an `ENTSO-E map extract <https://github.com/PyPSA/GridKit/tree/master/entsoe>`_ (March 2022) as a PyPSA network.
|
||||
|
||||
Relevant Settings
|
||||
-----------------
|
||||
@ -59,8 +56,19 @@ Outputs
|
||||
.. image:: img/base.png
|
||||
:scale: 33 %
|
||||
|
||||
- ``resources/regions_onshore.geojson``:
|
||||
|
||||
.. image:: img/regions_onshore.png
|
||||
:scale: 33 %
|
||||
|
||||
- ``resources/regions_offshore.geojson``:
|
||||
|
||||
.. image:: img/regions_offshore.png
|
||||
:scale: 33 %
|
||||
|
||||
Description
|
||||
-----------
|
||||
Creates the network topology from an ENTSO-E map extract, and create Voronoi shapes for each bus representing both onshore and offshore regions.
|
||||
"""
|
||||
|
||||
import logging
|
||||
@ -75,11 +83,11 @@ import shapely
|
||||
import shapely.prepared
|
||||
import shapely.wkt
|
||||
import yaml
|
||||
from _helpers import configure_logging, get_snapshots, set_scenario_config
|
||||
from _helpers import REGION_COLS, configure_logging, get_snapshots, set_scenario_config
|
||||
from packaging.version import Version, parse
|
||||
from scipy import spatial
|
||||
from scipy.sparse import csgraph
|
||||
from shapely.geometry import LineString, Point
|
||||
from shapely.geometry import LineString, Point, Polygon
|
||||
|
||||
PD_GE_2_2 = parse(pd.__version__) >= Version("2.2")
|
||||
|
||||
@ -264,14 +272,15 @@ def _add_links_from_tyndp(buses, links, links_tyndp, europe_shape):
|
||||
if links_tyndp.empty:
|
||||
return buses, links
|
||||
|
||||
tree = spatial.KDTree(buses[["x", "y"]])
|
||||
tree_buses = buses.query("carrier=='AC'")
|
||||
tree = spatial.KDTree(tree_buses[["x", "y"]])
|
||||
_, ind0 = tree.query(links_tyndp[["x1", "y1"]])
|
||||
ind0_b = ind0 < len(buses)
|
||||
links_tyndp.loc[ind0_b, "bus0"] = buses.index[ind0[ind0_b]]
|
||||
ind0_b = ind0 < len(tree_buses)
|
||||
links_tyndp.loc[ind0_b, "bus0"] = tree_buses.index[ind0[ind0_b]]
|
||||
|
||||
_, ind1 = tree.query(links_tyndp[["x2", "y2"]])
|
||||
ind1_b = ind1 < len(buses)
|
||||
links_tyndp.loc[ind1_b, "bus1"] = buses.index[ind1[ind1_b]]
|
||||
ind1_b = ind1 < len(tree_buses)
|
||||
links_tyndp.loc[ind1_b, "bus1"] = tree_buses.index[ind1[ind1_b]]
|
||||
|
||||
links_tyndp_located_b = (
|
||||
links_tyndp["bus0"].notnull() & links_tyndp["bus1"].notnull()
|
||||
@ -561,7 +570,7 @@ def _set_countries_and_substations(n, config, country_shapes, offshore_shapes):
|
||||
buses["substation_lv"] = (
|
||||
lv_b & onshore_b & (~buses["under_construction"]) & has_connections_b
|
||||
)
|
||||
buses["substation_off"] = (offshore_b | (hv_b & onshore_b)) & (
|
||||
buses["substation_off"] = ((hv_b & offshore_b) | (hv_b & onshore_b)) & (
|
||||
~buses["under_construction"]
|
||||
)
|
||||
|
||||
@ -698,6 +707,22 @@ def _adjust_capacities_of_under_construction_branches(n, config):
|
||||
return n
|
||||
|
||||
|
||||
def _set_shapes(n, country_shapes, offshore_shapes):
|
||||
# Write the geodataframes country_shapes and offshore_shapes to the network.shapes component
|
||||
country_shapes = gpd.read_file(country_shapes).rename(columns={"name": "idx"})
|
||||
country_shapes["type"] = "country"
|
||||
offshore_shapes = gpd.read_file(offshore_shapes).rename(columns={"name": "idx"})
|
||||
offshore_shapes["type"] = "offshore"
|
||||
all_shapes = pd.concat([country_shapes, offshore_shapes], ignore_index=True)
|
||||
n.madd(
|
||||
"Shape",
|
||||
all_shapes.index,
|
||||
geometry=all_shapes.geometry,
|
||||
idx=all_shapes.idx,
|
||||
type=all_shapes["type"],
|
||||
)
|
||||
|
||||
|
||||
def base_network(
|
||||
eg_buses,
|
||||
eg_converters,
|
||||
@ -758,9 +783,150 @@ def base_network(
|
||||
|
||||
n = _adjust_capacities_of_under_construction_branches(n, config)
|
||||
|
||||
_set_shapes(n, country_shapes, offshore_shapes)
|
||||
|
||||
return n
|
||||
|
||||
|
||||
def voronoi_partition_pts(points, outline):
|
||||
"""
|
||||
Compute the polygons of a voronoi partition of `points` within the polygon
|
||||
`outline`. Taken from
|
||||
https://github.com/FRESNA/vresutils/blob/master/vresutils/graph.py.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
points : Nx2 - ndarray[dtype=float]
|
||||
outline : Polygon
|
||||
Returns
|
||||
-------
|
||||
polygons : N - ndarray[dtype=Polygon|MultiPolygon]
|
||||
"""
|
||||
points = np.asarray(points)
|
||||
|
||||
if len(points) == 1:
|
||||
polygons = [outline]
|
||||
else:
|
||||
xmin, ymin = np.amin(points, axis=0)
|
||||
xmax, ymax = np.amax(points, axis=0)
|
||||
xspan = xmax - xmin
|
||||
yspan = ymax - ymin
|
||||
|
||||
# to avoid any network positions outside all Voronoi cells, append
|
||||
# the corners of a rectangle framing these points
|
||||
vor = spatial.Voronoi(
|
||||
np.vstack(
|
||||
(
|
||||
points,
|
||||
[
|
||||
[xmin - 3.0 * xspan, ymin - 3.0 * yspan],
|
||||
[xmin - 3.0 * xspan, ymax + 3.0 * yspan],
|
||||
[xmax + 3.0 * xspan, ymin - 3.0 * yspan],
|
||||
[xmax + 3.0 * xspan, ymax + 3.0 * yspan],
|
||||
],
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
polygons = []
|
||||
for i in range(len(points)):
|
||||
poly = Polygon(vor.vertices[vor.regions[vor.point_region[i]]])
|
||||
|
||||
if not poly.is_valid:
|
||||
poly = poly.buffer(0)
|
||||
|
||||
with np.errstate(invalid="ignore"):
|
||||
poly = poly.intersection(outline)
|
||||
|
||||
polygons.append(poly)
|
||||
|
||||
return polygons
|
||||
|
||||
|
||||
def build_bus_shapes(n, country_shapes, offshore_shapes, countries):
|
||||
country_shapes = gpd.read_file(country_shapes).set_index("name")["geometry"]
|
||||
offshore_shapes = gpd.read_file(offshore_shapes)
|
||||
offshore_shapes = offshore_shapes.reindex(columns=REGION_COLS).set_index("name")[
|
||||
"geometry"
|
||||
]
|
||||
|
||||
onshore_regions = []
|
||||
offshore_regions = []
|
||||
|
||||
for country in countries:
|
||||
c_b = n.buses.country == country
|
||||
|
||||
onshore_shape = country_shapes[country]
|
||||
onshore_locs = (
|
||||
n.buses.loc[c_b & n.buses.onshore_bus]
|
||||
.sort_values(
|
||||
by="substation_lv", ascending=False
|
||||
) # preference for substations
|
||||
.drop_duplicates(subset=["x", "y"], keep="first")[["x", "y"]]
|
||||
)
|
||||
onshore_regions.append(
|
||||
gpd.GeoDataFrame(
|
||||
{
|
||||
"name": onshore_locs.index,
|
||||
"x": onshore_locs["x"],
|
||||
"y": onshore_locs["y"],
|
||||
"geometry": voronoi_partition_pts(
|
||||
onshore_locs.values, onshore_shape
|
||||
),
|
||||
"country": country,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
if country not in offshore_shapes.index:
|
||||
continue
|
||||
offshore_shape = offshore_shapes[country]
|
||||
offshore_locs = n.buses.loc[c_b & n.buses.substation_off, ["x", "y"]]
|
||||
offshore_regions_c = gpd.GeoDataFrame(
|
||||
{
|
||||
"name": offshore_locs.index,
|
||||
"x": offshore_locs["x"],
|
||||
"y": offshore_locs["y"],
|
||||
"geometry": voronoi_partition_pts(offshore_locs.values, offshore_shape),
|
||||
"country": country,
|
||||
}
|
||||
)
|
||||
offshore_regions_c = offshore_regions_c.loc[offshore_regions_c.area > 1e-2]
|
||||
offshore_regions.append(offshore_regions_c)
|
||||
|
||||
shapes = pd.concat(onshore_regions, ignore_index=True)
|
||||
|
||||
return onshore_regions, offshore_regions, shapes, offshore_shapes
|
||||
|
||||
|
||||
def append_bus_shapes(n, shapes, type):
|
||||
"""
|
||||
Append shapes to the network. If shapes with the same component and type
|
||||
already exist, they will be removed.
|
||||
|
||||
Parameters:
|
||||
n (pypsa.Network): The network to which the shapes will be appended.
|
||||
shapes (geopandas.GeoDataFrame): The shapes to be appended.
|
||||
**kwargs: Additional keyword arguments used in `n.madd`.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
remove = n.shapes.query("component == 'Bus' and type == @type").index
|
||||
n.mremove("Shape", remove)
|
||||
|
||||
offset = n.shapes.index.astype(int).max() + 1 if not n.shapes.empty else 0
|
||||
shapes = shapes.rename(lambda x: int(x) + offset)
|
||||
n.madd(
|
||||
"Shape",
|
||||
shapes.index,
|
||||
geometry=shapes.geometry,
|
||||
idx=shapes.name,
|
||||
component="Bus",
|
||||
type=type,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if "snakemake" not in globals():
|
||||
from _helpers import mock_snakemake
|
||||
@ -784,5 +950,22 @@ if __name__ == "__main__":
|
||||
snakemake.config,
|
||||
)
|
||||
|
||||
onshore_regions, offshore_regions, shapes, offshore_shapes = build_bus_shapes(
|
||||
n,
|
||||
snakemake.input.country_shapes,
|
||||
snakemake.input.offshore_shapes,
|
||||
snakemake.params.countries,
|
||||
)
|
||||
|
||||
shapes.to_file(snakemake.output.regions_onshore)
|
||||
append_bus_shapes(n, shapes, "onshore")
|
||||
|
||||
if offshore_regions:
|
||||
shapes = pd.concat(offshore_regions, ignore_index=True)
|
||||
shapes.to_file(snakemake.output.regions_offshore)
|
||||
append_bus_shapes(n, shapes, "offshore")
|
||||
else:
|
||||
offshore_shapes.to_frame().to_file(snakemake.output.regions_offshore)
|
||||
|
||||
n.meta = snakemake.config
|
||||
n.export_to_netcdf(snakemake.output[0])
|
||||
n.export_to_netcdf(snakemake.output.base_network)
|
||||
|
@ -12,12 +12,11 @@ import logging
|
||||
import geopandas as gpd
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from _helpers import configure_logging, set_scenario_config
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
AVAILABLE_BIOMASS_YEARS = [2010, 2020, 2030, 2040, 2050]
|
||||
|
||||
from _helpers import configure_logging, set_scenario_config
|
||||
|
||||
|
||||
def build_nuts_population_data(year=2013):
|
||||
pop = pd.read_csv(
|
||||
|
@ -17,20 +17,27 @@ assuming as an approximation energy content of wood pellets
|
||||
@author: bw0928
|
||||
"""
|
||||
|
||||
import platform
|
||||
|
||||
import pandas as pd
|
||||
import tabula as tbl
|
||||
|
||||
ENERGY_CONTENT = 4.8 # unit MWh/t (wood pellets)
|
||||
system = platform.system()
|
||||
encoding = "cp1252" if system == "Windows" else None
|
||||
|
||||
|
||||
def get_countries():
|
||||
pandas_options = dict(skiprows=range(6), header=None, index_col=0)
|
||||
pandas_options = dict(
|
||||
skiprows=range(6), header=None, index_col=0, encoding=encoding
|
||||
)
|
||||
|
||||
return tbl.read_pdf(
|
||||
str(snakemake.input.transport_cost_data),
|
||||
pages="145",
|
||||
multiple_tables=False,
|
||||
pandas_options=pandas_options,
|
||||
encoding=encoding,
|
||||
)[0].index
|
||||
|
||||
|
||||
@ -41,6 +48,7 @@ def get_cost_per_tkm(page, countries):
|
||||
sep=" |,",
|
||||
engine="python",
|
||||
index_col=False,
|
||||
encoding=encoding,
|
||||
)
|
||||
|
||||
sc = tbl.read_pdf(
|
||||
@ -48,6 +56,7 @@ def get_cost_per_tkm(page, countries):
|
||||
pages=page,
|
||||
multiple_tables=False,
|
||||
pandas_options=pandas_options,
|
||||
encoding=encoding,
|
||||
)[0]
|
||||
sc.index = countries
|
||||
sc.columns = sc.columns.str.replace("€", "EUR")
|
||||
|
@ -1,184 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# SPDX-FileCopyrightText: : 2017-2024 The PyPSA-Eur Authors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""
|
||||
Creates Voronoi shapes for each bus representing both onshore and offshore
|
||||
regions.
|
||||
|
||||
Relevant Settings
|
||||
-----------------
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
countries:
|
||||
|
||||
.. seealso::
|
||||
Documentation of the configuration file ``config/config.yaml`` at
|
||||
:ref:`toplevel_cf`
|
||||
|
||||
Inputs
|
||||
------
|
||||
|
||||
- ``resources/country_shapes.geojson``: confer :ref:`shapes`
|
||||
- ``resources/offshore_shapes.geojson``: confer :ref:`shapes`
|
||||
- ``networks/base.nc``: confer :ref:`base`
|
||||
|
||||
Outputs
|
||||
-------
|
||||
|
||||
- ``resources/regions_onshore.geojson``:
|
||||
|
||||
.. image:: img/regions_onshore.png
|
||||
:scale: 33 %
|
||||
|
||||
- ``resources/regions_offshore.geojson``:
|
||||
|
||||
.. image:: img/regions_offshore.png
|
||||
:scale: 33 %
|
||||
|
||||
Description
|
||||
-----------
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import geopandas as gpd
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import pypsa
|
||||
from _helpers import REGION_COLS, configure_logging, set_scenario_config
|
||||
from scipy.spatial import Voronoi
|
||||
from shapely.geometry import Polygon
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def voronoi_partition_pts(points, outline):
|
||||
"""
|
||||
Compute the polygons of a voronoi partition of `points` within the polygon
|
||||
`outline`. Taken from
|
||||
https://github.com/FRESNA/vresutils/blob/master/vresutils/graph.py.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
points : Nx2 - ndarray[dtype=float]
|
||||
outline : Polygon
|
||||
Returns
|
||||
-------
|
||||
polygons : N - ndarray[dtype=Polygon|MultiPolygon]
|
||||
"""
|
||||
points = np.asarray(points)
|
||||
|
||||
if len(points) == 1:
|
||||
polygons = [outline]
|
||||
else:
|
||||
xmin, ymin = np.amin(points, axis=0)
|
||||
xmax, ymax = np.amax(points, axis=0)
|
||||
xspan = xmax - xmin
|
||||
yspan = ymax - ymin
|
||||
|
||||
# to avoid any network positions outside all Voronoi cells, append
|
||||
# the corners of a rectangle framing these points
|
||||
vor = Voronoi(
|
||||
np.vstack(
|
||||
(
|
||||
points,
|
||||
[
|
||||
[xmin - 3.0 * xspan, ymin - 3.0 * yspan],
|
||||
[xmin - 3.0 * xspan, ymax + 3.0 * yspan],
|
||||
[xmax + 3.0 * xspan, ymin - 3.0 * yspan],
|
||||
[xmax + 3.0 * xspan, ymax + 3.0 * yspan],
|
||||
],
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
polygons = []
|
||||
for i in range(len(points)):
|
||||
poly = Polygon(vor.vertices[vor.regions[vor.point_region[i]]])
|
||||
|
||||
if not poly.is_valid:
|
||||
poly = poly.buffer(0)
|
||||
|
||||
with np.errstate(invalid="ignore"):
|
||||
poly = poly.intersection(outline)
|
||||
|
||||
polygons.append(poly)
|
||||
|
||||
return polygons
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if "snakemake" not in globals():
|
||||
from _helpers import mock_snakemake
|
||||
|
||||
snakemake = mock_snakemake("build_bus_regions")
|
||||
configure_logging(snakemake)
|
||||
set_scenario_config(snakemake)
|
||||
|
||||
countries = snakemake.params.countries
|
||||
|
||||
n = pypsa.Network(snakemake.input.base_network)
|
||||
|
||||
country_shapes = gpd.read_file(snakemake.input.country_shapes).set_index("name")[
|
||||
"geometry"
|
||||
]
|
||||
offshore_shapes = gpd.read_file(snakemake.input.offshore_shapes)
|
||||
offshore_shapes = offshore_shapes.reindex(columns=REGION_COLS).set_index("name")[
|
||||
"geometry"
|
||||
]
|
||||
|
||||
onshore_regions = []
|
||||
offshore_regions = []
|
||||
|
||||
for country in countries:
|
||||
c_b = n.buses.country == country
|
||||
|
||||
onshore_shape = country_shapes[country]
|
||||
onshore_locs = (
|
||||
n.buses.loc[c_b & n.buses.onshore_bus]
|
||||
.sort_values(
|
||||
by="substation_lv", ascending=False
|
||||
) # preference for substations
|
||||
.drop_duplicates(subset=["x", "y"], keep="first")[["x", "y"]]
|
||||
)
|
||||
onshore_regions.append(
|
||||
gpd.GeoDataFrame(
|
||||
{
|
||||
"name": onshore_locs.index,
|
||||
"x": onshore_locs["x"],
|
||||
"y": onshore_locs["y"],
|
||||
"geometry": voronoi_partition_pts(
|
||||
onshore_locs.values, onshore_shape
|
||||
),
|
||||
"country": country,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
if country not in offshore_shapes.index:
|
||||
continue
|
||||
offshore_shape = offshore_shapes[country]
|
||||
offshore_locs = n.buses.loc[c_b & n.buses.substation_off, ["x", "y"]]
|
||||
offshore_regions_c = gpd.GeoDataFrame(
|
||||
{
|
||||
"name": offshore_locs.index,
|
||||
"x": offshore_locs["x"],
|
||||
"y": offshore_locs["y"],
|
||||
"geometry": voronoi_partition_pts(offshore_locs.values, offshore_shape),
|
||||
"country": country,
|
||||
}
|
||||
)
|
||||
offshore_regions_c = offshore_regions_c.loc[offshore_regions_c.area > 1e-2]
|
||||
offshore_regions.append(offshore_regions_c)
|
||||
|
||||
pd.concat(onshore_regions, ignore_index=True).to_file(
|
||||
snakemake.output.regions_onshore
|
||||
)
|
||||
if offshore_regions:
|
||||
pd.concat(offshore_regions, ignore_index=True).to_file(
|
||||
snakemake.output.regions_offshore
|
||||
)
|
||||
else:
|
||||
offshore_shapes.to_frame().to_file(snakemake.output.regions_offshore)
|
@ -9,7 +9,6 @@ Build heat demand time series using heating degree day (HDD) approximation.
|
||||
import atlite
|
||||
import geopandas as gpd
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import xarray as xr
|
||||
from _helpers import get_snapshots, set_scenario_config
|
||||
from dask.distributed import Client, LocalCluster
|
||||
|
@ -129,7 +129,7 @@ def copy_timeslice(load, cntry, start, stop, delta, fn_load=None):
|
||||
load.loc[start:stop, cntry] = load.loc[
|
||||
start - delta : stop - delta, cntry
|
||||
].values
|
||||
elif fn_load is not None:
|
||||
elif fn_load is not None and cntry in load:
|
||||
duration = pd.date_range(freq="h", start=start - delta, end=stop - delta)
|
||||
load_raw = load_timeseries(fn_load, duration, [cntry])
|
||||
load.loc[start:stop, cntry] = load_raw.loc[
|
||||
@ -311,6 +311,8 @@ if __name__ == "__main__":
|
||||
logger.info("Supplement missing data with synthetic data.")
|
||||
fn = snakemake.input.synthetic
|
||||
synthetic_load = pd.read_csv(fn, index_col=0, parse_dates=True)
|
||||
# "UA" does not appear in synthetic load data
|
||||
countries = list(set(countries) - set(["UA"]))
|
||||
synthetic_load = synthetic_load.loc[snapshots, countries]
|
||||
load = load.combine_first(synthetic_load)
|
||||
|
||||
|
@ -8,7 +8,6 @@ Build total energy demands per country using JRC IDEES, eurostat, and EEA data.
|
||||
|
||||
import logging
|
||||
import multiprocessing as mp
|
||||
import os
|
||||
from functools import partial
|
||||
|
||||
import country_converter as coco
|
||||
@ -125,7 +124,6 @@ def build_eurostat(input_eurostat, countries, nprocesses=1, disable_progressbar=
|
||||
df = pd.concat([temp, df.loc[~int_avia]])
|
||||
|
||||
# Fill in missing data on "Domestic aviation" for each country.
|
||||
domestic_avia = df.index.get_level_values(4) == "Domestic aviation"
|
||||
for country in countries:
|
||||
slicer = idx[country, :, :, :, "Domestic aviation"]
|
||||
# For the Total and Fossil energy columns, fill in zeros with
|
||||
@ -142,6 +140,7 @@ def build_eurostat(input_eurostat, countries, nprocesses=1, disable_progressbar=
|
||||
"Domestic navigation": "Domestic Navigation",
|
||||
"International maritime bunkers": "Bunkers",
|
||||
"UK": "GB",
|
||||
"EL": "GR",
|
||||
}
|
||||
columns_rename = {"Total": "Total all products"}
|
||||
df.rename(index=index_rename, columns=columns_rename, inplace=True)
|
||||
@ -395,13 +394,12 @@ def build_idees(countries):
|
||||
names=["country", "year"],
|
||||
)
|
||||
|
||||
# efficiency kgoe/100km -> ktoe/100km so that after conversion TWh/100km
|
||||
totals.loc[:, "passenger car efficiency"] /= 1e6
|
||||
# convert ktoe to TWh
|
||||
exclude = totals.columns.str.fullmatch("passenger cars")
|
||||
totals.loc[:, ~exclude] *= 11.63 / 1e3
|
||||
|
||||
# convert TWh/100km to kWh/km
|
||||
totals.loc[:, "passenger car efficiency"] *= 10
|
||||
|
||||
return totals
|
||||
|
||||
|
||||
@ -768,9 +766,8 @@ def build_transport_data(countries, population, idees):
|
||||
|
||||
transport_data = transport_data.combine_first(fill_values)
|
||||
|
||||
# collect average fuel efficiency in kWh/km
|
||||
|
||||
transport_data["average fuel efficiency"] = idees["passenger car efficiency"]
|
||||
# collect average fuel efficiency in MWh/100km, taking passengar car efficiency in TWh/100km
|
||||
transport_data["average fuel efficiency"] = idees["passenger car efficiency"] * 1e6
|
||||
|
||||
missing = transport_data.index[transport_data["average fuel efficiency"].isna()]
|
||||
if not missing.empty:
|
||||
@ -854,6 +851,7 @@ def rescale_idees_from_eurostat(
|
||||
"total passenger cars",
|
||||
"total other road passenger",
|
||||
"total light duty road freight",
|
||||
"total heavy duty road freight",
|
||||
],
|
||||
"elec": [
|
||||
"electricity road",
|
||||
@ -891,6 +889,7 @@ def rescale_idees_from_eurostat(
|
||||
navigation = [
|
||||
"total domestic navigation",
|
||||
]
|
||||
# international navigation is already read in from the eurostat data directly
|
||||
|
||||
for country in idees_countries:
|
||||
filling_years = [(2015, slice(2016, 2021)), (2000, slice(1990, 1999))]
|
||||
@ -940,9 +939,68 @@ def rescale_idees_from_eurostat(
|
||||
energy.loc[slicer_source, navigation].squeeze(axis=0),
|
||||
).values
|
||||
|
||||
# set the total of agriculture/road to the sum of all agriculture/road categories (corresponding to the IDEES data)
|
||||
rows = idx[country, :]
|
||||
cols = [
|
||||
"total agriculture electricity",
|
||||
"total agriculture heat",
|
||||
"total agriculture machinery",
|
||||
]
|
||||
energy.loc[rows, "total agriculture"] = energy.loc[rows, cols].sum(axis=1)
|
||||
|
||||
cols = [
|
||||
"total passenger cars",
|
||||
"total other road passenger",
|
||||
"total light duty road freight",
|
||||
"total heavy duty road freight",
|
||||
]
|
||||
energy.loc[rows, "total road"] = energy.loc[rows, cols].sum(axis=1)
|
||||
|
||||
return energy
|
||||
|
||||
|
||||
def update_residential_from_eurostat(energy):
|
||||
"""
|
||||
Updates energy balances for residential from disaggregated data from
|
||||
Eurostat.
|
||||
"""
|
||||
eurostat_households = pd.read_csv(snakemake.input.eurostat_households)
|
||||
|
||||
# Column mapping for energy type
|
||||
nrg_type = {
|
||||
"total residential": ("FC_OTH_HH_E", "TOTAL"),
|
||||
"total residential space": ("FC_OTH_HH_E_SH", "TOTAL"),
|
||||
"total residential water": ("FC_OTH_HH_E_WH", "TOTAL"),
|
||||
"total residential cooking": ("FC_OTH_HH_E_CK", "TOTAL"),
|
||||
"electricity residential": ("FC_OTH_HH_E", "E7000"),
|
||||
"electricity residential space": ("FC_OTH_HH_E_SH", "E7000"),
|
||||
"electricity residential water": ("FC_OTH_HH_E_WH", "E7000"),
|
||||
"electricity residential cooking": ("FC_OTH_HH_E_CK", "E7000"),
|
||||
}
|
||||
|
||||
for nrg_name, (code, siec) in nrg_type.items():
|
||||
|
||||
# Select energy balance type, rename columns and countries to match IDEES data,
|
||||
# convert TJ to TWh, and drop XK data already since included in RS data
|
||||
col_to_rename = {"geo": "country", "TIME_PERIOD": "year", "OBS_VALUE": nrg_name}
|
||||
idx_to_rename = {v: k for k, v in idees_rename.items()}
|
||||
drop_geo = ["EU27_2020", "EA20", "XK"]
|
||||
nrg_data = eurostat_households.query(
|
||||
"nrg_bal == @code and siec == @siec and geo not in @drop_geo and OBS_VALUE > 0"
|
||||
).copy()
|
||||
nrg_data.rename(columns=col_to_rename, inplace=True)
|
||||
nrg_data = nrg_data.set_index(["country", "year"])[nrg_name] / 3.6e3
|
||||
nrg_data.rename(index=idx_to_rename, inplace=True)
|
||||
|
||||
# update energy balance from household-specific eurostat data
|
||||
idx = nrg_data.index.intersection(energy.index)
|
||||
energy.loc[idx, nrg_name] = nrg_data[idx]
|
||||
|
||||
logger.info(
|
||||
"Updated energy balances for residential using disaggregate final energy consumption data in Households from Eurostat"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if "snakemake" not in globals():
|
||||
from _helpers import mock_snakemake
|
||||
@ -976,6 +1034,8 @@ if __name__ == "__main__":
|
||||
logger.info("Extrapolate IDEES data based on eurostat for years 2015-2021.")
|
||||
energy = rescale_idees_from_eurostat(idees_countries, energy, eurostat)
|
||||
|
||||
update_residential_from_eurostat(energy)
|
||||
|
||||
energy.to_csv(snakemake.output.energy_name)
|
||||
|
||||
# use rescaled idees data to calculate district heat share
|
||||
|
@ -55,7 +55,6 @@ def build_existing_heating():
|
||||
nodal_heating = nodal_heating.multiply(pop_layout.fraction, axis=0)
|
||||
|
||||
district_heat_info = pd.read_csv(snakemake.input.district_heat_share, index_col=0)
|
||||
dist_fraction = district_heat_info["district fraction of node"]
|
||||
urban_fraction = district_heat_info["urban fraction"]
|
||||
|
||||
energy_layout = pd.read_csv(
|
||||
|
@ -139,7 +139,10 @@ def approximate_missing_eia_stats(eia_stats, runoff_fn, countries):
|
||||
runoff.index = runoff.index.astype(int)
|
||||
|
||||
# fix outliers; exceptional floods in 1977-1979 in ES & PT
|
||||
runoff.loc[1978, ["ES", "PT"]] = runoff.loc[1979, ["ES", "PT"]]
|
||||
if "ES" in runoff:
|
||||
runoff.loc[1978, "ES"] = runoff.loc[1979, "ES"]
|
||||
if "PT" in runoff:
|
||||
runoff.loc[1978, "PT"] = runoff.loc[1979, "PT"]
|
||||
|
||||
runoff_eia = runoff.loc[eia_stats.index]
|
||||
|
||||
@ -198,8 +201,6 @@ if __name__ == "__main__":
|
||||
fn = snakemake.input.era5_runoff
|
||||
eia_stats = approximate_missing_eia_stats(eia_stats, fn, countries)
|
||||
|
||||
eia_stats.to_csv(snakemake.output.eia_hydro)
|
||||
|
||||
contained_years = pd.date_range(freq="YE", **snakemake.params.snapshots).year
|
||||
norm_year = config_hydro.get("eia_norm_year")
|
||||
missing_years = contained_years.difference(eia_stats.index)
|
||||
|
@ -68,6 +68,7 @@ index = [
|
||||
"heat",
|
||||
"naphtha",
|
||||
"ammonia",
|
||||
"methanol",
|
||||
"process emission",
|
||||
"process emission from feedstock",
|
||||
]
|
||||
@ -303,7 +304,7 @@ def chemicals_industry():
|
||||
# There are Solids, Refinery gas, LPG, Diesel oil, Residual fuel oil,
|
||||
# Other liquids, Naphtha, Natural gas for feedstock.
|
||||
# Naphta represents 47%, methane 17%. LPG (18%) solids, refinery gas,
|
||||
# diesel oil, residual fuel oils and other liquids are asimilated to Naphtha
|
||||
# diesel oil, residual fuel oils and other liquids are assimilated to Naphtha
|
||||
|
||||
s_fec = idees["fec"][13:22]
|
||||
assert s_fec.index[0] == subsector
|
||||
@ -313,7 +314,7 @@ def chemicals_industry():
|
||||
df.loc["methane", sector] += s_fec["Natural gas"]
|
||||
|
||||
# LPG and other feedstock materials are assimilated to naphtha
|
||||
# since they will be produced through Fischer-Tropsh process
|
||||
# since they will be produced through Fischer-Tropsch process
|
||||
sel = [
|
||||
"Solids",
|
||||
"Refinery gas",
|
||||
@ -456,8 +457,7 @@ def chemicals_industry():
|
||||
|
||||
sector = "Methanol"
|
||||
df[sector] = 0.0
|
||||
df.loc["methane", sector] = params["MWh_CH4_per_tMeOH"]
|
||||
df.loc["elec", sector] = params["MWh_elec_per_tMeOH"]
|
||||
df.loc["methanol", sector] = params["MWh_MeOH_per_tMeOH"]
|
||||
|
||||
# Other chemicals
|
||||
|
||||
|
@ -51,11 +51,14 @@ def build_industry_sector_ratios_intermediate():
|
||||
|
||||
intermediate_sector_ratios = {}
|
||||
for ct, group in today_sector_ratios.T.groupby(level=0):
|
||||
today_sector_ratios_ct = (
|
||||
group.droplevel(0)
|
||||
.T.reindex_like(future_sector_ratios)
|
||||
.fillna(future_sector_ratios)
|
||||
)
|
||||
today_sector_ratios_ct = group.droplevel(0).T.reindex_like(future_sector_ratios)
|
||||
missing_mask = today_sector_ratios_ct.isna().all()
|
||||
today_sector_ratios_ct.loc[:, missing_mask] = future_sector_ratios.loc[
|
||||
:, missing_mask
|
||||
]
|
||||
today_sector_ratios_ct.loc[:, ~missing_mask] = today_sector_ratios_ct.loc[
|
||||
:, ~missing_mask
|
||||
].fillna(0)
|
||||
intermediate_sector_ratios[ct] = (
|
||||
today_sector_ratios_ct * (1 - fraction_future)
|
||||
+ future_sector_ratios * fraction_future
|
||||
|
@ -55,7 +55,6 @@ import re
|
||||
import atlite
|
||||
import geopandas as gpd
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import pypsa
|
||||
import xarray as xr
|
||||
from _helpers import configure_logging, get_snapshots, set_scenario_config
|
||||
|
@ -1,118 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# SPDX-FileCopyrightText: : 2017-2024 The PyPSA-Eur Authors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""
|
||||
Rasters the vector data of the `Natura 2000.
|
||||
|
||||
<https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas onto all
|
||||
cutout regions.
|
||||
|
||||
Relevant Settings
|
||||
-----------------
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
renewable:
|
||||
{technology}:
|
||||
cutout:
|
||||
|
||||
.. seealso::
|
||||
Documentation of the configuration file ``config/config.yaml`` at
|
||||
:ref:`renewable_cf`
|
||||
|
||||
Inputs
|
||||
------
|
||||
|
||||
- ``data/bundle/natura/Natura2000_end2015.shp``: `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas.
|
||||
|
||||
.. image:: img/natura.png
|
||||
:scale: 33 %
|
||||
|
||||
Outputs
|
||||
-------
|
||||
|
||||
- ``resources/natura.tiff``: Rasterized version of `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas to reduce computation times.
|
||||
|
||||
.. image:: img/natura.png
|
||||
:scale: 33 %
|
||||
|
||||
Description
|
||||
-----------
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import atlite
|
||||
import geopandas as gpd
|
||||
import rasterio as rio
|
||||
from _helpers import configure_logging, set_scenario_config
|
||||
from rasterio.features import geometry_mask
|
||||
from rasterio.warp import transform_bounds
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def determine_cutout_xXyY(cutout_name):
|
||||
"""
|
||||
Determine the full extent of a cutout.
|
||||
|
||||
Since the coordinates of the cutout data are given as the
|
||||
center of the grid cells, the extent of the cutout is
|
||||
calculated by adding/subtracting half of the grid cell size.
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
cutout_name : str
|
||||
Path to the cutout.
|
||||
|
||||
Returns
|
||||
-------
|
||||
A list of extent coordinates in the order [x, X, y, Y].
|
||||
"""
|
||||
cutout = atlite.Cutout(cutout_name)
|
||||
assert cutout.crs.to_epsg() == 4326
|
||||
x, X, y, Y = cutout.extent
|
||||
dx, dy = cutout.dx, cutout.dy
|
||||
return [x - dx / 2.0, X + dx / 2.0, y - dy / 2.0, Y + dy / 2.0]
|
||||
|
||||
|
||||
def get_transform_and_shape(bounds, res):
|
||||
left, bottom = [(b // res) * res for b in bounds[:2]]
|
||||
right, top = [(b // res + 1) * res for b in bounds[2:]]
|
||||
shape = int((top - bottom) // res), int((right - left) / res)
|
||||
transform = rio.Affine(res, 0, left, 0, -res, top)
|
||||
return transform, shape
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if "snakemake" not in globals():
|
||||
from _helpers import mock_snakemake
|
||||
|
||||
snakemake = mock_snakemake("build_natura_raster")
|
||||
configure_logging(snakemake)
|
||||
set_scenario_config(snakemake)
|
||||
|
||||
x, X, y, Y = determine_cutout_xXyY(snakemake.input.cutout)
|
||||
bounds = transform_bounds(4326, 3035, x, y, X, Y)
|
||||
transform, out_shape = get_transform_and_shape(bounds, res=100)
|
||||
|
||||
# adjusted boundaries
|
||||
shapes = gpd.read_file(snakemake.input.natura).to_crs(3035)
|
||||
raster = ~geometry_mask(shapes.geometry, out_shape, transform)
|
||||
raster = raster.astype(rio.uint8)
|
||||
|
||||
with rio.open(
|
||||
snakemake.output[0],
|
||||
"w",
|
||||
driver="GTiff",
|
||||
dtype=rio.uint8,
|
||||
count=1,
|
||||
transform=transform,
|
||||
crs=3035,
|
||||
compress="lzw",
|
||||
width=raster.shape[1],
|
||||
height=raster.shape[0],
|
||||
) as dst:
|
||||
dst.write(raster, indexes=1)
|