Merge remote-tracking branch 'upstream/master' into implement-floating

This commit is contained in:
Philipp Glaum 2024-01-09 14:44:21 +01:00
commit 1903c51f36
87 changed files with 2734 additions and 1016 deletions

1
.gitignore vendored
View File

@ -46,6 +46,7 @@ data/costs_*.csv
dask-worker-space/
publications.jrc.ec.europa.eu/
d1gam3xoknrgr2.cloudfront.net/
*.org

View File

@ -17,7 +17,7 @@ repos:
# Sort package imports alphabetically
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
rev: 5.13.2
hooks:
- id: isort
args: ["--profile", "black", "--filter-files"]
@ -45,13 +45,13 @@ repos:
args: ["--in-place", "--make-summary-multi-line", "--pre-summary-newline"]
- repo: https://github.com/keewis/blackdoc
rev: v0.3.8
rev: v0.3.9
hooks:
- id: blackdoc
# Formatting with "black" coding style
- repo: https://github.com/psf/black
rev: 23.10.1
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 23.12.1
hooks:
# Format Python files
- id: black
@ -67,7 +67,7 @@ repos:
# Do YAML formatting (before the linter checks it for misses)
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.11.0
rev: v2.12.0
hooks:
- id: pretty-format-yaml
args: [--autofix, --indent, "2", --preserve-quotes]

View File

@ -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.8.1
version: 0.9.0
license: MIT
authors:
- family-names: Brown

View File

@ -61,9 +61,9 @@ The dataset consists of:
- A grid model based on a modified [GridKit](https://github.com/bdw/GridKit)
extraction of the [ENTSO-E Transmission System
Map](https://www.entsoe.eu/data/map/). The grid model contains 6763 lines
Map](https://www.entsoe.eu/data/map/). The grid model contains 7072 lines
(alternating current lines at and above 220kV voltage level and all high
voltage direct current lines) and 3642 substations.
voltage direct current lines) and 3803 substations.
- The open power plant database
[powerplantmatching](https://github.com/FRESNA/powerplantmatching).
- Electrical demand time series from the
@ -103,6 +103,6 @@ We strongly welcome anyone interested in contributing to this project. If you ha
# Licence
The code in PyPSA-Eur is released as free software under the
[MIT License](https://opensource.org/licenses/MIT), see `LICENSE.txt`.
[MIT License](https://opensource.org/licenses/MIT), see [`doc/licenses.rst`](doc/licenses.rst).
However, different licenses and terms of use may apply to the various
input data.

View File

@ -14,7 +14,7 @@ from snakemake.utils import min_version
min_version("7.7")
if not exists("config/config.yaml"):
if not exists("config/config.yaml") and exists("config/config.default.yaml"):
copyfile("config/config.default.yaml", "config/config.yaml")
@ -125,6 +125,7 @@ rule sync:
shell:
"""
rsync -uvarh --ignore-missing-args --files-from=.sync-send . {params.cluster}
rsync -uvarh --no-g {params.cluster}/resources . || echo "No resources directory, skipping rsync"
rsync -uvarh --no-g {params.cluster}/results . || echo "No results directory, skipping rsync"
rsync -uvarh --no-g {params.cluster}/logs . || echo "No logs directory, skipping rsync"
"""

View File

@ -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.8.1
version: 0.9.0
tutorial: false
logging:
@ -59,6 +59,9 @@ snapshots:
start: "2013-01-01"
end: "2014-01-01"
inclusive: 'left'
resolution: false
segmentation: false
#representative: false
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#enable
enable:
@ -74,6 +77,7 @@ enable:
retrieve_natura_raster: true
custom_busmap: false
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#co2-budget
co2_budget:
2020: 0.701
@ -86,8 +90,10 @@ co2_budget:
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#electricity
electricity:
voltages: [220., 300., 380.]
voltages: [220., 300., 380., 500., 750.]
gaslimit_enable: false
gaslimit: false
co2limit_enable: false
co2limit: 7.75e+7
co2base: 1.487e+9
agg_p_nom_limits: data/agg_p_nom_minmax.csv
@ -110,6 +116,7 @@ electricity:
powerplants_filter: (DateOut >= 2022 or DateOut != DateOut)
custom_powerplants: false
everywhere_powerplants: [nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass]
conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass]
renewable_carriers: [solar, onwind, offwind-ac, offwind-dc, offwind-float, hydro]
@ -124,6 +131,10 @@ electricity:
Onshore: [onwind]
PV: [solar]
autarky:
enable: false
by_country: false
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#atlite
atlite:
default_cutout: europe-2013-era5
@ -135,14 +146,14 @@ atlite:
# module: era5
europe-2013-era5:
module: era5 # in priority order
x: [-12., 35.]
x: [-12., 42.]
y: [33., 72]
dx: 0.3
dy: 0.3
time: ['2013', '2013']
europe-2013-sarah:
module: [sarah, era5] # in priority order
x: [-12., 45.]
x: [-12., 42.]
y: [33., 65]
dx: 0.2
dy: 0.2
@ -158,45 +169,51 @@ renewable:
resource:
method: wind
turbine: Vestas_V112_3MW
add_cutout_windspeed: true
capacity_per_sqkm: 3
# correction_factor: 0.93
corine:
grid_codes: [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 31, 32]
distance: 1000
distance_grid_codes: [1, 2, 3, 4, 5, 6]
luisa: false
# grid_codes: [1111, 1121, 1122, 1123, 1130, 1210, 1221, 1222, 1230, 1241, 1242]
# distance: 1000
# distance_grid_codes: [1111, 1121, 1122, 1123, 1130, 1210, 1221, 1222, 1230, 1241, 1242]
natura: true
excluder_resolution: 100
potential: simple # or conservative
clip_p_max_pu: 1.e-2
offwind-ac:
cutout: europe-2013-era5
resource:
method: wind
turbine: NREL_ReferenceTurbine_5MW_offshore
turbine: NREL_ReferenceTurbine_2020ATB_5.5MW
add_cutout_windspeed: true
capacity_per_sqkm: 2
correction_factor: 0.8855
corine: [44, 255]
luisa: false # [0, 5230]
natura: true
ship_threshold: 400
max_depth: 60
max_shore_distance: 30000
excluder_resolution: 200
potential: simple # or conservative
clip_p_max_pu: 1.e-2
offwind-dc:
cutout: europe-2013-era5
resource:
method: wind
turbine: NREL_ReferenceTurbine_5MW_offshore
turbine: NREL_ReferenceTurbine_2020ATB_5.5MW
add_cutout_windspeed: true
capacity_per_sqkm: 2
correction_factor: 0.8855
corine: [44, 255]
luisa: false # [0, 5230]
natura: true
ship_threshold: 400
max_depth: 60
min_shore_distance: 30000
excluder_resolution: 200
potential: simple # or conservative
clip_p_max_pu: 1.e-2
offwind-float:
cutout: europe-2013-era5
@ -225,12 +242,12 @@ renewable:
orientation:
slope: 35.
azimuth: 180.
capacity_per_sqkm: 1.7
capacity_per_sqkm: 5.1
# correction_factor: 0.854337
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
potential: simple # or conservative
clip_p_max_pu: 1.e-2
hydro:
cutout: europe-2013-era5
@ -254,10 +271,13 @@ lines:
220.: "Al/St 240/40 2-bundle 220.0"
300.: "Al/St 240/40 3-bundle 300.0"
380.: "Al/St 240/40 4-bundle 380.0"
500.: "Al/St 240/40 4-bundle 380.0"
750.: "Al/St 560/50 4-bundle 750.0"
s_max_pu: 0.7
s_nom_max: .inf
max_extension: .inf
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
dynamic_line_rating:
activate: false
@ -270,7 +290,7 @@ lines:
links:
p_max_pu: 1.0
p_nom_max: .inf
max_extension: .inf
max_extension: 30000 #MW
include_tyndp: true
under_construction: 'zero' # 'zero': set capacity to zero, 'remove': remove, 'keep': with full capacity
@ -280,7 +300,7 @@ transformers:
s_nom: 2000.
type: ''
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#load
# docs-load in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#load
load:
power_statistics: true
interpolate_limit: 3
@ -306,6 +326,7 @@ pypsa_eur:
- offwind-float
- solar
- ror
- nuclear
StorageUnit:
- PHS
- hydro
@ -368,8 +389,11 @@ sector:
potential: 0.6
progress:
2020: 0.0
2025: 0.15
2030: 0.3
2035: 0.45
2040: 0.6
2045: 0.8
2050: 1.0
district_heating_loss: 0.15
cluster_heat_buses: false
@ -392,18 +416,27 @@ sector:
v2g: true
land_transport_fuel_cell_share:
2020: 0
2030: 0.05
2040: 0.1
2050: 0.15
2025: 0
2030: 0
2035: 0
2040: 0
2045: 0
2050: 0
land_transport_electric_share:
2020: 0
2030: 0.25
2040: 0.6
2050: 0.85
2025: 0.15
2030: 0.3
2035: 0.45
2040: 0.7
2045: 0.85
2050: 1
land_transport_ice_share:
2020: 1
2025: 0.85
2030: 0.7
2035: 0.55
2040: 0.3
2045: 0.15
2050: 0
transport_fuel_cell_efficiency: 0.5
transport_internal_combustion_efficiency: 0.3
@ -417,18 +450,27 @@ sector:
shipping_hydrogen_liquefaction: false
shipping_hydrogen_share:
2020: 0
2025: 0
2030: 0
2035: 0
2040: 0
2045: 0
2050: 0
shipping_methanol_share:
2020: 0
2025: 0.15
2030: 0.3
2035: 0.5
2040: 0.7
2045: 0.85
2050: 1
shipping_oil_share:
2020: 1
2025: 0.85
2030: 0.7
2035: 0.5
2040: 0.3
2045: 0.15
2050: 0
shipping_methanol_efficiency: 0.46
shipping_oil_efficiency: 0.40
@ -457,6 +499,7 @@ sector:
decentral: 3
central: 180
boilers: true
resistive_heaters: true
oil_boilers: false
biomass_boiler: true
chp: true
@ -465,15 +508,17 @@ sector:
solar_cf_correction: 0.788457 # = >>> 1/1.2683
marginal_cost_storage: 0. #1e-4
methanation: true
helmeth: false
coal_cc: false
dac: true
co2_vent: false
central_heat_vent: false
allam_cycle: false
hydrogen_fuel_cell: true
hydrogen_turbine: false
SMR: true
SMR_cc: true
regional_methanol_demand: false
regional_oil_demand: false
regional_co2_sequestration_potential:
enable: false
attribute: 'conservative estimate Mt'
@ -486,6 +531,7 @@ sector:
co2_sequestration_lifetime: 50
co2_spatial: false
co2network: false
co2_network_cost_factor: 1
cc_fraction: 0.9
hydrogen_underground_storage: true
hydrogen_underground_storage_locations:
@ -493,14 +539,28 @@ sector:
- nearshore # within 50 km of sea
# - offshore
ammonia: false
min_part_load_fischer_tropsch: 0.9
min_part_load_methanolisation: 0.5
min_part_load_fischer_tropsch: 0.7
min_part_load_methanolisation: 0.3
min_part_load_methanation: 0.3
use_fischer_tropsch_waste_heat: true
use_haber_bosch_waste_heat: true
use_methanolisation_waste_heat: true
use_methanation_waste_heat: true
use_fuel_cell_waste_heat: true
use_electrolysis_waste_heat: false
use_electrolysis_waste_heat: true
electricity_distribution_grid: true
electricity_distribution_grid_cost_factor: 1.0
electricity_grid_connection: true
transmission_efficiency:
DC:
efficiency_static: 0.98
efficiency_per_1000km: 0.977
H2 pipeline:
efficiency_per_1000km: 1 # 0.979
compression_per_1000km: 0.019
gas pipeline:
efficiency_per_1000km: 1 #0.977
compression_per_1000km: 0.01
H2_network: true
gas_network: false
H2_retrofit: false
@ -510,6 +570,7 @@ sector:
gas_distribution_grid_cost_factor: 1.0
biomass_spatial: false
biomass_transport: false
biogas_upgrading_cc: false
conventional_generation:
OCGT: gas
biomass_to_liquid: false
@ -560,8 +621,8 @@ industry:
MWh_NH3_per_tNH3: 5.166
MWh_CH4_per_tNH3_SMR: 10.8
MWh_elec_per_tNH3_SMR: 0.7
MWh_H2_per_tNH3_electrolysis: 6.5
MWh_elec_per_tNH3_electrolysis: 1.17
MWh_H2_per_tNH3_electrolysis: 5.93
MWh_elec_per_tNH3_electrolysis: 0.2473
MWh_NH3_per_MWh_H2_cracker: 1.46 # https://github.com/euronion/trace/blob/44a5ff8401762edbef80eff9cfe5a47c8d3c8be4/data/efficiencies.csv
NH3_process_emissions: 24.5
petrochemical_process_emissions: 25.5
@ -610,10 +671,13 @@ costs:
battery: 0.
battery inverter: 0.
emission_prices:
enable: false
co2: 0.
co2_monthly_prices: false
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#clustering
clustering:
focus_weights: false
simplify_network:
to_substations: false
algorithm: kmeans # choose from: [hac, kmeans]
@ -642,14 +706,21 @@ solving:
skip_iterations: true
rolling_horizon: false
seed: 123
custom_extra_functionality: "../data/custom_extra_functionality.py"
# options that go into the optimize function
track_iterations: false
min_iterations: 4
max_iterations: 6
transmission_losses: 0
transmission_losses: 2
linearized_unit_commitment: true
horizon: 365
constraints:
CCL: false
EQ: false
BAU: false
SAFE: false
solver:
name: gurobi
options: gurobi-default
@ -740,6 +811,7 @@ plotting:
H2: "Hydrogen Storage"
lines: "Transmission Lines"
ror: "Run of River"
load: "Load Shedding"
ac: "AC"
dc: "DC"
@ -793,6 +865,7 @@ plotting:
fossil gas: '#e05b09'
natural gas: '#e05b09'
biogas to gas: '#e36311'
biogas to gas CC: '#e51245'
CCGT: '#a85522'
CCGT marginal: '#a85522'
allam: '#B98F76'
@ -894,12 +967,14 @@ plotting:
# heat demand
Heat load: '#cc1f1f'
heat: '#cc1f1f'
heat vent: '#aa3344'
heat demand: '#cc1f1f'
rural heat: '#ff5c5c'
residential rural heat: '#ff7c7c'
services rural heat: '#ff9c9c'
central heat: '#cc1f1f'
urban central heat: '#d15959'
urban central heat vent: '#a74747'
decentral heat: '#750606'
residential urban decentral heat: '#a33c3c'
services urban decentral heat: '#cc1f1f'
@ -962,7 +1037,6 @@ plotting:
Sabatier: '#9850ad'
methanation: '#c44ce6'
methane: '#c44ce6'
helmeth: '#e899ff'
# synfuels
Fischer-Tropsch: '#25c49a'
liquid: '#25c49a'
@ -977,6 +1051,7 @@ plotting:
CO2 sequestration: '#f29dae'
DAC: '#ff5270'
co2 stored: '#f2385a'
co2 sequestered: '#f2682f'
co2: '#f29dae'
co2 vent: '#ffd4dc'
CO2 pipeline: '#f5627f'
@ -1008,3 +1083,4 @@ plotting:
DC: "#8a1caf"
DC-DC: "#8a1caf"
DC link: "#8a1caf"
load: "#dd2e23"

View File

@ -0,0 +1,43 @@
# SPDX-FileCopyrightText: 2017-2023 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: CC0-1.0
run:
name: "entsoe-all"
disable_progressbar: true
shared_resources: false
shared_cutouts: true
scenario:
simpl:
- ''
ll:
- vopt
clusters:
- 39
- 128
- 256
opts:
- ''
sector_opts:
- ''
planning_horizons:
- ''
# TODO add Turkey (TR)
countries: ['AL', 'AT', 'BA', 'BE', 'BG', 'CH', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'GR', 'HR', 'HU', 'IE', 'IT', 'LT', 'LU', 'LV', 'ME', 'MD', 'MK', 'NL', 'NO', 'PL', 'PT', 'RO', 'RS', 'SE', 'SI', 'SK', 'UA']
electricity:
custom_powerplants: true
co2limit: 9.59e+7
co2base: 1.918e+9
lines:
reconnect_crimea: true
enable:
retrieve: true
retrieve_databundle: true
retrieve_sector_databundle: false
retrieve_cost_data: true
retrieve_cutout: true

View File

@ -30,6 +30,9 @@ snapshots:
start: "2013-03-01"
end: "2013-03-08"
sector:
central_heat_vent: true
electricity:
co2limit: 100.e+6

View File

@ -44,6 +44,7 @@ electricity:
sector:
min_part_load_fischer_tropsch: 0
min_part_load_methanolisation: 0
atlite:
default_cutout: be-03-2013-era5
cutouts:

View File

@ -0,0 +1,151 @@
name,GDP_PPP,country
3140,632728.0438507323,MD
3139,806541.9318093687,MD
3142,1392454.6690911907,MD
3152,897871.2903553953,MD
3246,645554.8588933202,MD
7049,1150156.4449477682,MD
1924,162285.16792916053,UA
1970,751970.6071848695,UA
2974,368873.75840156944,UA
2977,294847.85539198935,UA
2979,197988.13680768458,UA
2980,301371.2491126519,UA
3031,56925.21878805953,UA
3032,139395.18279351242,UA
3033,145377.8061037629,UA
3035,52282.83655208812,UA
3036,497950.25890516065,UA
3037,1183293.1987702171,UA
3038,255005.98207636533,UA
3039,224711.50098325178,UA
3040,342959.943226467,UA
3044,69119.31486955672,UA
3045,246273.65986119965,UA
3047,146742.08407299497,UA
3049,107265.7028733467,UA
3050,1126147.985259493,UA
3051,69833.56303043803,UA
3052,67230.88206577855,UA
3053,27019.224685201345,UA
3054,260571.47337292184,UA
3055,88760.94152915622,UA
3056,101368.26196568517,UA
3058,55752.92329667119,UA
3059,89024.37880630122,UA
3062,358411.291265149,UA
3064,75081.64142862396,UA
3065,158101.42949135564,UA
3066,83763.89576442329,UA
3068,173474.51218344545,UA
3069,60327.01572375589,UA
3070,18073.687271955278,UA
3071,249069.43314695224,UA
3072,220707.35700825177,UA
3073,61342.30137462664,UA
3074,254235.98867635374,UA
3077,769558.9832370486,UA
3078,132674.2315809836,UA
3079,1388517.1478032232,UA
3080,1861003.8718246964,UA
3082,140123.73854745473,UA
3083,834887.5595419679,UA
3084,1910795.5590558557,UA
3086,93828.36549170096,UA
3088,347197.65113392205,UA
3089,3754718.141734592,UA
3090,521912.69768585655,UA
3093,232818.05269714879,UA
3095,435376.20361377904,UA
3099,345596.5288937008,UA
3100,175689.10947424968,UA
3105,538438.9311459162,UA
3107,88096.86032871014,UA
3108,79847.68447063807,UA
3109,348504.73449373,UA
3144,71657.0165675802,UA
3146,80342.05037424155,UA
3158,74465.12922576343,UA
3164,3102112.2672631275,UA
3165,65215.04081671433,UA
3166,413924.2225725632,UA
3167,135060.0056434935,UA
3168,54980.442979330146,UA
3170,29584.879122227037,UA
3171,142780.68163047134,UA
3172,40436.63814695243,UA
3173,1253342.1790126422,UA
3174,173842.03139155387,UA
3176,65699.76352408895,UA
3177,143591.75419817626,UA
3178,56434.04525832523,UA
3179,389996.1670051216,UA
3180,138452.84503524794,UA
3181,67402.59500436619,UA
3184,51204.293695376415,UA
3185,46867.82356528432,UA
3186,103892.35612417295,UA
3187,193668.91476930346,UA
3189,54584.176457692694,UA
3190,219077.64942830536,UA
3197,88516.52699983507,UA
3198,298166.8272673622,UA
3199,61334.952541812374,UA
3229,175692.61136747137,UA
3230,106722.62773321665,UA
3236,61542.06264321315,UA
3241,83752.90489164277,UA
4301,48419.52825967164,UA
4305,147759.74280349456,UA
4306,53156.905740992224,UA
4315,218025.78516351627,UA
4317,155240.40554731718,UA
4318,1342144.2459407183,UA
4319,91669.1449633853,UA
4321,85852.49282415409,UA
4347,67938.7698430624,UA
4357,20064.979012172935,UA
4360,47840.51245168512,UA
4361,55580.924388032574,UA
4362,165753.82588729708,UA
4363,46390.2448142152,UA
4365,96265.47592938849,UA
4366,272003.25510057947,UA
4367,80878.50229245829,UA
4370,330072.35444044066,UA
4371,7707066.181975477,UA
4373,2019766.7891575783,UA
4374,985354.331818515,UA
4377,230805.08833664874,UA
4382,125670.67125287943,UA
4383,46914.065511740075,UA
4384,48020.804310510954,UA
4385,55612.34707641123,UA
4387,74558.3475791577,UA
4388,245243.33449409154,UA
4389,95696.56767732685,UA
4391,251085.7523045193,UA
4401,66375.82996856027,UA
4403,111954.41038437477,UA
4405,46911.68560148837,UA
4408,150782.51691456966,UA
4409,112776.7399582134,UA
4410,153076.56860965435,UA
4412,192629.31238456024,UA
4413,181295.3120834606,UA
4414,995694.9413199169,UA
4416,157640.7868989174,UA
4418,77580.20674809469,UA
4420,122320.99275223716,UA
4424,184891.10924920067,UA
4425,84486.75974340564,UA
4431,50485.84380961137,UA
4435,231040.45446464577,UA
4436,81222.18707585508,UA
4438,114819.76472988473,UA
4439,76839.1052178896,UA
4440,135337.0313562152,UA
4441,49159.485269198034,UA
7031,42001.73757065917,UA
7059,159790.48382874,UA
7063,39599.10564971086,UA
1 name GDP_PPP country
2 3140 632728.0438507323 MD
3 3139 806541.9318093687 MD
4 3142 1392454.6690911907 MD
5 3152 897871.2903553953 MD
6 3246 645554.8588933202 MD
7 7049 1150156.4449477682 MD
8 1924 162285.16792916053 UA
9 1970 751970.6071848695 UA
10 2974 368873.75840156944 UA
11 2977 294847.85539198935 UA
12 2979 197988.13680768458 UA
13 2980 301371.2491126519 UA
14 3031 56925.21878805953 UA
15 3032 139395.18279351242 UA
16 3033 145377.8061037629 UA
17 3035 52282.83655208812 UA
18 3036 497950.25890516065 UA
19 3037 1183293.1987702171 UA
20 3038 255005.98207636533 UA
21 3039 224711.50098325178 UA
22 3040 342959.943226467 UA
23 3044 69119.31486955672 UA
24 3045 246273.65986119965 UA
25 3047 146742.08407299497 UA
26 3049 107265.7028733467 UA
27 3050 1126147.985259493 UA
28 3051 69833.56303043803 UA
29 3052 67230.88206577855 UA
30 3053 27019.224685201345 UA
31 3054 260571.47337292184 UA
32 3055 88760.94152915622 UA
33 3056 101368.26196568517 UA
34 3058 55752.92329667119 UA
35 3059 89024.37880630122 UA
36 3062 358411.291265149 UA
37 3064 75081.64142862396 UA
38 3065 158101.42949135564 UA
39 3066 83763.89576442329 UA
40 3068 173474.51218344545 UA
41 3069 60327.01572375589 UA
42 3070 18073.687271955278 UA
43 3071 249069.43314695224 UA
44 3072 220707.35700825177 UA
45 3073 61342.30137462664 UA
46 3074 254235.98867635374 UA
47 3077 769558.9832370486 UA
48 3078 132674.2315809836 UA
49 3079 1388517.1478032232 UA
50 3080 1861003.8718246964 UA
51 3082 140123.73854745473 UA
52 3083 834887.5595419679 UA
53 3084 1910795.5590558557 UA
54 3086 93828.36549170096 UA
55 3088 347197.65113392205 UA
56 3089 3754718.141734592 UA
57 3090 521912.69768585655 UA
58 3093 232818.05269714879 UA
59 3095 435376.20361377904 UA
60 3099 345596.5288937008 UA
61 3100 175689.10947424968 UA
62 3105 538438.9311459162 UA
63 3107 88096.86032871014 UA
64 3108 79847.68447063807 UA
65 3109 348504.73449373 UA
66 3144 71657.0165675802 UA
67 3146 80342.05037424155 UA
68 3158 74465.12922576343 UA
69 3164 3102112.2672631275 UA
70 3165 65215.04081671433 UA
71 3166 413924.2225725632 UA
72 3167 135060.0056434935 UA
73 3168 54980.442979330146 UA
74 3170 29584.879122227037 UA
75 3171 142780.68163047134 UA
76 3172 40436.63814695243 UA
77 3173 1253342.1790126422 UA
78 3174 173842.03139155387 UA
79 3176 65699.76352408895 UA
80 3177 143591.75419817626 UA
81 3178 56434.04525832523 UA
82 3179 389996.1670051216 UA
83 3180 138452.84503524794 UA
84 3181 67402.59500436619 UA
85 3184 51204.293695376415 UA
86 3185 46867.82356528432 UA
87 3186 103892.35612417295 UA
88 3187 193668.91476930346 UA
89 3189 54584.176457692694 UA
90 3190 219077.64942830536 UA
91 3197 88516.52699983507 UA
92 3198 298166.8272673622 UA
93 3199 61334.952541812374 UA
94 3229 175692.61136747137 UA
95 3230 106722.62773321665 UA
96 3236 61542.06264321315 UA
97 3241 83752.90489164277 UA
98 4301 48419.52825967164 UA
99 4305 147759.74280349456 UA
100 4306 53156.905740992224 UA
101 4315 218025.78516351627 UA
102 4317 155240.40554731718 UA
103 4318 1342144.2459407183 UA
104 4319 91669.1449633853 UA
105 4321 85852.49282415409 UA
106 4347 67938.7698430624 UA
107 4357 20064.979012172935 UA
108 4360 47840.51245168512 UA
109 4361 55580.924388032574 UA
110 4362 165753.82588729708 UA
111 4363 46390.2448142152 UA
112 4365 96265.47592938849 UA
113 4366 272003.25510057947 UA
114 4367 80878.50229245829 UA
115 4370 330072.35444044066 UA
116 4371 7707066.181975477 UA
117 4373 2019766.7891575783 UA
118 4374 985354.331818515 UA
119 4377 230805.08833664874 UA
120 4382 125670.67125287943 UA
121 4383 46914.065511740075 UA
122 4384 48020.804310510954 UA
123 4385 55612.34707641123 UA
124 4387 74558.3475791577 UA
125 4388 245243.33449409154 UA
126 4389 95696.56767732685 UA
127 4391 251085.7523045193 UA
128 4401 66375.82996856027 UA
129 4403 111954.41038437477 UA
130 4405 46911.68560148837 UA
131 4408 150782.51691456966 UA
132 4409 112776.7399582134 UA
133 4410 153076.56860965435 UA
134 4412 192629.31238456024 UA
135 4413 181295.3120834606 UA
136 4414 995694.9413199169 UA
137 4416 157640.7868989174 UA
138 4418 77580.20674809469 UA
139 4420 122320.99275223716 UA
140 4424 184891.10924920067 UA
141 4425 84486.75974340564 UA
142 4431 50485.84380961137 UA
143 4435 231040.45446464577 UA
144 4436 81222.18707585508 UA
145 4438 114819.76472988473 UA
146 4439 76839.1052178896 UA
147 4440 135337.0313562152 UA
148 4441 49159.485269198034 UA
149 7031 42001.73757065917 UA
150 7059 159790.48382874 UA
151 7063 39599.10564971086 UA

View File

@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: : 2023- The PyPSA-Eur Authors
#
# SPDX-License-Identifier: MIT
def custom_extra_functionality(n, snapshots, snakemake):
"""
Add custom extra functionality constraints.
"""
pass

View File

@ -1 +1,37 @@
Name,Fueltype,Technology,Set,Country,Capacity,Efficiency,Duration,Volume_Mm3,DamHeight_m,YearCommissioned,Retrofit,lat,lon,projectID,YearDecommissioning
,Name,Fueltype,Technology,Set,Country,Capacity,Efficiency,Duration,Volume_Mm3,DamHeight_m,StorageCapacity_MWh,DateIn,DateRetrofit,DateMothball,DateOut,lat,lon,EIC,projectID
1266,Khmelnitskiy,Nuclear,,PP,UA,1901.8916595755832,,0.0,0.0,0.0,0.0,1988.0,2005.0,,,50.3023,26.6466,[nan],"{'GEO': ['GEO3842'], 'GPD': ['WRI1005111'], 'CARMA': ['CARMA22000']}"
1268,Kaniv,Hydro,Reservoir,PP,UA,452.1656050955414,,0.0,0.0,0.0,0.0,1972.0,2003.0,,,49.76653,31.47165,[nan],"{'GEO': ['GEO43017'], 'GPD': ['WRI1005122'], 'CARMA': ['CARMA21140']}"
1269,Kahovska kakhovka,Hydro,Reservoir,PP,UA,352.45222929936307,,0.0,0.0,0.0,0.0,1955.0,1956.0,,,46.77858,33.36965,[nan],"{'GEO': ['GEO43018'], 'GPD': ['WRI1005118'], 'CARMA': ['CARMA20855']}"
1347,Kharkiv,Natural Gas,Steam Turbine,CHP,UA,494.94274967602314,,0.0,0.0,0.0,0.0,1979.0,1980.0,,,49.9719,36107,[nan],"{'GEO': ['GEO43027'], 'GPD': ['WRI1005126'], 'CARMA': ['CARMA21972']}"
1348,Kremenchuk,Hydro,Reservoir,PP,UA,617.0382165605096,,0.0,0.0,0.0,0.0,1959.0,1960.0,,,49.07759,33.2505,[nan],"{'GEO': ['GEO43019'], 'GPD': ['WRI1005121'], 'CARMA': ['CARMA23072']}"
1377,Krivorozhskaya,Hard Coal,Steam Turbine,PP,UA,2600.0164509342876,,0.0,0.0,0.0,0.0,1965.0,1992.0,,,47.5432,33.6583,[nan],"{'GEO': ['GEO42989'], 'GPD': ['WRI1005100'], 'CARMA': ['CARMA23176']}"
1407,Zmiyevskaya zmiivskaya,Hard Coal,Steam Turbine,PP,UA,2028.3816283884514,,0.0,0.0,0.0,0.0,1960.0,2005.0,,,49.5852,36.5231,[nan],"{'GEO': ['GEO42999'], 'GPD': ['WRI1005103'], 'CARMA': ['CARMA51042']}"
1408,Pridneprovskaya,Hard Coal,Steam Turbine,CHP,UA,1627.3152609570984,,0.0,0.0,0.0,0.0,1959.0,1966.0,,,48.4051,35.1131,[nan],"{'GEO': ['GEO42990'], 'GPD': ['WRI1005102'], 'CARMA': ['CARMA35874']}"
1409,Kurakhovskaya,Hard Coal,Steam Turbine,PP,UA,1371.0015824607397,,0.0,0.0,0.0,0.0,1972.0,2003.0,,,47.9944,37.24022,[nan],"{'GEO': ['GEO42994'], 'GPD': ['WRI1005104'], 'CARMA': ['CARMA23339']}"
1410,Dobrotvorsky,Hard Coal,Steam Turbine,PP,UA,553.1949895604868,,0.0,0.0,0.0,0.0,1960.0,1964.0,,,50.2133,24375,[nan],"{'GEO': ['GEO42992'], 'GPD': ['WRI1005096'], 'CARMA': ['CARMA10971']}"
1422,Zuyevskaya,Hard Coal,Steam Turbine,PP,UA,1147.87960333801,,0.0,0.0,0.0,0.0,1982.0,2007.0,,,48.0331,38.28615,[nan],"{'GEO': ['GEO42995'], 'GPD': ['WRI1005106'], 'CARMA': ['CARMA51083']}"
1423,Zaporozhye,Nuclear,,PP,UA,5705.67497872675,,0.0,0.0,0.0,0.0,1985.0,1996.0,,,47.5119,34.5863,[nan],"{'GEO': ['GEO6207'], 'GPD': ['WRI1005114'], 'CARMA': ['CARMA50875']}"
1424,Trypilska,Hard Coal,Steam Turbine,PP,UA,1659.5849686814602,,0.0,0.0,0.0,0.0,1969.0,1972.0,,,50.1344,30.7468,[nan],"{'GEO': ['GEO43000'], 'GPD': ['WRI1005099'], 'CARMA': ['CARMA46410']}"
1425,Tashlyk,Hydro,Pumped Storage,Store,UA,285.55968954109585,,0.0,0.0,0.0,0.0,2006.0,2007.0,,,47.7968,31.1811,[nan],"{'GEO': ['GEO43025'], 'GPD': ['WRI1005117'], 'CARMA': ['CARMA44696']}"
1426,Starobeshivska,Hard Coal,Steam Turbine,PP,UA,1636.5351774497733,,0.0,0.0,0.0,0.0,1961.0,1967.0,,,47.7997,38.00612,[nan],"{'GEO': ['GEO43003'], 'GPD': ['WRI1005105'], 'CARMA': ['CARMA43083']}"
1427,South,Nuclear,,PP,UA,2852.837489363375,,0.0,0.0,0.0,0.0,1983.0,1989.0,,,47812,31.22,[nan],"{'GEO': ['GEO5475'], 'GPD': ['WRI1005113'], 'CARMA': ['CARMA42555']}"
1428,Rovno rivne,Nuclear,,PP,UA,2695.931427448389,,0.0,0.0,0.0,0.0,1981.0,2006.0,,,51.3245,25.89744,[nan],"{'GEO': ['GEO5174'], 'GPD': ['WRI1005112'], 'CARMA': ['CARMA38114']}"
1429,Ladyzhinska,Hard Coal,Steam Turbine,PP,UA,1659.5849686814602,,0.0,0.0,0.0,0.0,1970.0,1971.0,,,48706,29.2202,[nan],"{'GEO': ['GEO42993'], 'GPD': ['WRI1005098'], 'CARMA': ['CARMA24024']}"
1430,Kiev,Hydro,Pumped Storage,PP,UA,635.8694635681177,,0.0,0.0,0.0,0.0,1964.0,1972.0,,,50.5998,30501,"[nan, nan]","{'GEO': ['GEO43024', 'GEO43023'], 'GPD': ['WRI1005123', 'WRI1005124'], 'CARMA': ['CARMA23516', 'CARMA23517']}"
2450,Cet chisinau,Natural Gas,,PP,MD,306.0,,0.0,0.0,0.0,0.0,,,,,47.027550000000005,28.8801,"[nan, nan]","{'GPD': ['WRI1002985', 'WRI1002984'], 'CARMA': ['CARMA8450', 'CARMA8451']}"
2460,Hydropower che costesti,Hydro,,PP,MD,16.0,,0.0,0.0,0.0,0.0,1978.0,,,,47.8381,27.2246,[nan],"{'GPD': ['WRI1002987'], 'CARMA': ['CARMA9496']}"
2465,Moldavskaya gres,Hard Coal,,PP,MD,2520.0,,0.0,0.0,0.0,0.0,,,,,46.6292,29.9407,[nan],"{'GPD': ['WRI1002989'], 'CARMA': ['CARMA28979']}"
2466,Hydropower dubasari,Hydro,,PP,MD,48.0,,0.0,0.0,0.0,0.0,,,,,47.2778,29123,[nan],"{'GPD': ['WRI1002988'], 'CARMA': ['CARMA11384']}"
2676,Cet nord balti,Natural Gas,,PP,MD,24.0,,0.0,0.0,0.0,0.0,,,,,47.7492,27.8938,[nan],"{'GPD': ['WRI1002986'], 'CARMA': ['CARMA3071']}"
2699,Dniprodzerzhynsk,Hydro,Reservoir,PP,UA,360.3503184713376,,0.0,0.0,0.0,0.0,1963.0,1964.0,,,48.5485,34.541015,[nan],"{'GEO': ['GEO43020'], 'GPD': ['WRI1005119']}"
2707,Burshtynska tes,Hard Coal,Steam Turbine,PP,UA,2212.779958241947,,0.0,0.0,0.0,0.0,1965.0,1984.0,,,49.21038,24.66654,[nan],"{'GEO': ['GEO42991'], 'GPD': ['WRI1005097']}"
2708,Danipro dnieper,Hydro,Reservoir,PP,UA,1484.8407643312103,,0.0,0.0,0.0,0.0,1932.0,1947.0,,,47.86944,35.08611,[nan],"{'GEO': ['GEO43016'], 'GPD': ['WRI1005120']}"
2709,Dniester,Hydro,Pumped Storage,Store,UA,612.7241020616891,,0.0,0.0,0.0,0.0,2009.0,2011.0,,,48.51361,27.47333,[nan],"{'GEO': ['GEO43022'], 'GPD': ['WRI1005116', 'WRI1005115']}"
2710,Kiev,Natural Gas,Steam Turbine,CHP,UA,458.2803237740955,,0.0,0.0,0.0,0.0,1982.0,1984.0,,,50532,30.6625,[nan],"{'GEO': ['GEO42998'], 'GPD': ['WRI1005125']}"
2712,Luganskaya,Hard Coal,Steam Turbine,PP,UA,1060.2903966575996,,0.0,0.0,0.0,0.0,1962.0,1969.0,,,48.74781,39.2624,[nan],"{'GEO': ['GEO42996'], 'GPD': ['WRI1005110']}"
2713,Slavyanskaya,Hard Coal,Steam Turbine,PP,UA,737.5933194139823,,0.0,0.0,0.0,0.0,1971.0,1971.0,,,48872,37.76567,[nan],"{'GEO': ['GEO43002'], 'GPD': ['WRI1005109']}"
2714,Vuhlehirska uglegorskaya,Hard Coal,Steam Turbine,PP,UA,3319.1699373629203,,0.0,0.0,0.0,0.0,1972.0,1977.0,,,48.4633,38.20328,[nan],"{'GEO': ['GEO43001'], 'GPD': ['WRI1005107']}"
2715,Zaporiska,Hard Coal,Steam Turbine,PP,UA,3319.1699373629203,,0.0,0.0,0.0,0.0,1972.0,1977.0,,,47.5089,34.6253,[nan],"{'GEO': ['GEO42988'], 'GPD': ['WRI1005101']}"
3678,Mironovskaya,Hard Coal,,PP,UA,815.0,,0.0,0.0,0.0,0.0,,,,,48.3407,38.4049,[nan],"{'GPD': ['WRI1005108'], 'CARMA': ['CARMA28679']}"
3679,Kramatorskaya,Hard Coal,,PP,UA,120.0,,0.0,0.0,0.0,0.0,1974.0,,,,48.7477,37.5723,[nan],"{'GPD': ['WRI1075856'], 'CARMA': ['CARMA54560']}"
3680,Chernihiv,Hard Coal,,PP,UA,200.0,,0.0,0.0,0.0,0.0,1968.0,,,,51455,31.2602,[nan],"{'GPD': ['WRI1075853'], 'CARMA': ['CARMA8190']}"

1 Name Fueltype Technology Set Country Capacity Efficiency Duration Volume_Mm3 YearCommissioned DamHeight_m Retrofit StorageCapacity_MWh DateIn DateRetrofit DateMothball YearDecommissioning DateOut lat lon EIC projectID
2 1266 Khmelnitskiy Nuclear PP UA 1901.8916595755832 0.0 0.0 0.0 0.0 1988.0 2005.0 50.3023 26.6466 [nan] {'GEO': ['GEO3842'], 'GPD': ['WRI1005111'], 'CARMA': ['CARMA22000']}
3 1268 Kaniv Hydro Reservoir PP UA 452.1656050955414 0.0 0.0 0.0 0.0 1972.0 2003.0 49.76653 31.47165 [nan] {'GEO': ['GEO43017'], 'GPD': ['WRI1005122'], 'CARMA': ['CARMA21140']}
4 1269 Kahovska kakhovka Hydro Reservoir PP UA 352.45222929936307 0.0 0.0 0.0 0.0 1955.0 1956.0 46.77858 33.36965 [nan] {'GEO': ['GEO43018'], 'GPD': ['WRI1005118'], 'CARMA': ['CARMA20855']}
5 1347 Kharkiv Natural Gas Steam Turbine CHP UA 494.94274967602314 0.0 0.0 0.0 0.0 1979.0 1980.0 49.9719 36107 [nan] {'GEO': ['GEO43027'], 'GPD': ['WRI1005126'], 'CARMA': ['CARMA21972']}
6 1348 Kremenchuk Hydro Reservoir PP UA 617.0382165605096 0.0 0.0 0.0 0.0 1959.0 1960.0 49.07759 33.2505 [nan] {'GEO': ['GEO43019'], 'GPD': ['WRI1005121'], 'CARMA': ['CARMA23072']}
7 1377 Krivorozhskaya Hard Coal Steam Turbine PP UA 2600.0164509342876 0.0 0.0 0.0 0.0 1965.0 1992.0 47.5432 33.6583 [nan] {'GEO': ['GEO42989'], 'GPD': ['WRI1005100'], 'CARMA': ['CARMA23176']}
8 1407 Zmiyevskaya zmiivskaya Hard Coal Steam Turbine PP UA 2028.3816283884514 0.0 0.0 0.0 0.0 1960.0 2005.0 49.5852 36.5231 [nan] {'GEO': ['GEO42999'], 'GPD': ['WRI1005103'], 'CARMA': ['CARMA51042']}
9 1408 Pridneprovskaya Hard Coal Steam Turbine CHP UA 1627.3152609570984 0.0 0.0 0.0 0.0 1959.0 1966.0 48.4051 35.1131 [nan] {'GEO': ['GEO42990'], 'GPD': ['WRI1005102'], 'CARMA': ['CARMA35874']}
10 1409 Kurakhovskaya Hard Coal Steam Turbine PP UA 1371.0015824607397 0.0 0.0 0.0 0.0 1972.0 2003.0 47.9944 37.24022 [nan] {'GEO': ['GEO42994'], 'GPD': ['WRI1005104'], 'CARMA': ['CARMA23339']}
11 1410 Dobrotvorsky Hard Coal Steam Turbine PP UA 553.1949895604868 0.0 0.0 0.0 0.0 1960.0 1964.0 50.2133 24375 [nan] {'GEO': ['GEO42992'], 'GPD': ['WRI1005096'], 'CARMA': ['CARMA10971']}
12 1422 Zuyevskaya Hard Coal Steam Turbine PP UA 1147.87960333801 0.0 0.0 0.0 0.0 1982.0 2007.0 48.0331 38.28615 [nan] {'GEO': ['GEO42995'], 'GPD': ['WRI1005106'], 'CARMA': ['CARMA51083']}
13 1423 Zaporozhye Nuclear PP UA 5705.67497872675 0.0 0.0 0.0 0.0 1985.0 1996.0 47.5119 34.5863 [nan] {'GEO': ['GEO6207'], 'GPD': ['WRI1005114'], 'CARMA': ['CARMA50875']}
14 1424 Trypilska Hard Coal Steam Turbine PP UA 1659.5849686814602 0.0 0.0 0.0 0.0 1969.0 1972.0 50.1344 30.7468 [nan] {'GEO': ['GEO43000'], 'GPD': ['WRI1005099'], 'CARMA': ['CARMA46410']}
15 1425 Tashlyk Hydro Pumped Storage Store UA 285.55968954109585 0.0 0.0 0.0 0.0 2006.0 2007.0 47.7968 31.1811 [nan] {'GEO': ['GEO43025'], 'GPD': ['WRI1005117'], 'CARMA': ['CARMA44696']}
16 1426 Starobeshivska Hard Coal Steam Turbine PP UA 1636.5351774497733 0.0 0.0 0.0 0.0 1961.0 1967.0 47.7997 38.00612 [nan] {'GEO': ['GEO43003'], 'GPD': ['WRI1005105'], 'CARMA': ['CARMA43083']}
17 1427 South Nuclear PP UA 2852.837489363375 0.0 0.0 0.0 0.0 1983.0 1989.0 47812 31.22 [nan] {'GEO': ['GEO5475'], 'GPD': ['WRI1005113'], 'CARMA': ['CARMA42555']}
18 1428 Rovno rivne Nuclear PP UA 2695.931427448389 0.0 0.0 0.0 0.0 1981.0 2006.0 51.3245 25.89744 [nan] {'GEO': ['GEO5174'], 'GPD': ['WRI1005112'], 'CARMA': ['CARMA38114']}
19 1429 Ladyzhinska Hard Coal Steam Turbine PP UA 1659.5849686814602 0.0 0.0 0.0 0.0 1970.0 1971.0 48706 29.2202 [nan] {'GEO': ['GEO42993'], 'GPD': ['WRI1005098'], 'CARMA': ['CARMA24024']}
20 1430 Kiev Hydro Pumped Storage PP UA 635.8694635681177 0.0 0.0 0.0 0.0 1964.0 1972.0 50.5998 30501 [nan, nan] {'GEO': ['GEO43024', 'GEO43023'], 'GPD': ['WRI1005123', 'WRI1005124'], 'CARMA': ['CARMA23516', 'CARMA23517']}
21 2450 Cet chisinau Natural Gas PP MD 306.0 0.0 0.0 0.0 0.0 47.027550000000005 28.8801 [nan, nan] {'GPD': ['WRI1002985', 'WRI1002984'], 'CARMA': ['CARMA8450', 'CARMA8451']}
22 2460 Hydropower che costesti Hydro PP MD 16.0 0.0 0.0 0.0 0.0 1978.0 47.8381 27.2246 [nan] {'GPD': ['WRI1002987'], 'CARMA': ['CARMA9496']}
23 2465 Moldavskaya gres Hard Coal PP MD 2520.0 0.0 0.0 0.0 0.0 46.6292 29.9407 [nan] {'GPD': ['WRI1002989'], 'CARMA': ['CARMA28979']}
24 2466 Hydropower dubasari Hydro PP MD 48.0 0.0 0.0 0.0 0.0 47.2778 29123 [nan] {'GPD': ['WRI1002988'], 'CARMA': ['CARMA11384']}
25 2676 Cet nord balti Natural Gas PP MD 24.0 0.0 0.0 0.0 0.0 47.7492 27.8938 [nan] {'GPD': ['WRI1002986'], 'CARMA': ['CARMA3071']}
26 2699 Dniprodzerzhynsk Hydro Reservoir PP UA 360.3503184713376 0.0 0.0 0.0 0.0 1963.0 1964.0 48.5485 34.541015 [nan] {'GEO': ['GEO43020'], 'GPD': ['WRI1005119']}
27 2707 Burshtynska tes Hard Coal Steam Turbine PP UA 2212.779958241947 0.0 0.0 0.0 0.0 1965.0 1984.0 49.21038 24.66654 [nan] {'GEO': ['GEO42991'], 'GPD': ['WRI1005097']}
28 2708 Danipro dnieper Hydro Reservoir PP UA 1484.8407643312103 0.0 0.0 0.0 0.0 1932.0 1947.0 47.86944 35.08611 [nan] {'GEO': ['GEO43016'], 'GPD': ['WRI1005120']}
29 2709 Dniester Hydro Pumped Storage Store UA 612.7241020616891 0.0 0.0 0.0 0.0 2009.0 2011.0 48.51361 27.47333 [nan] {'GEO': ['GEO43022'], 'GPD': ['WRI1005116', 'WRI1005115']}
30 2710 Kiev Natural Gas Steam Turbine CHP UA 458.2803237740955 0.0 0.0 0.0 0.0 1982.0 1984.0 50532 30.6625 [nan] {'GEO': ['GEO42998'], 'GPD': ['WRI1005125']}
31 2712 Luganskaya Hard Coal Steam Turbine PP UA 1060.2903966575996 0.0 0.0 0.0 0.0 1962.0 1969.0 48.74781 39.2624 [nan] {'GEO': ['GEO42996'], 'GPD': ['WRI1005110']}
32 2713 Slavyanskaya Hard Coal Steam Turbine PP UA 737.5933194139823 0.0 0.0 0.0 0.0 1971.0 1971.0 48872 37.76567 [nan] {'GEO': ['GEO43002'], 'GPD': ['WRI1005109']}
33 2714 Vuhlehirska uglegorskaya Hard Coal Steam Turbine PP UA 3319.1699373629203 0.0 0.0 0.0 0.0 1972.0 1977.0 48.4633 38.20328 [nan] {'GEO': ['GEO43001'], 'GPD': ['WRI1005107']}
34 2715 Zaporiska Hard Coal Steam Turbine PP UA 3319.1699373629203 0.0 0.0 0.0 0.0 1972.0 1977.0 47.5089 34.6253 [nan] {'GEO': ['GEO42988'], 'GPD': ['WRI1005101']}
35 3678 Mironovskaya Hard Coal PP UA 815.0 0.0 0.0 0.0 0.0 48.3407 38.4049 [nan] {'GPD': ['WRI1005108'], 'CARMA': ['CARMA28679']}
36 3679 Kramatorskaya Hard Coal PP UA 120.0 0.0 0.0 0.0 0.0 1974.0 48.7477 37.5723 [nan] {'GPD': ['WRI1075856'], 'CARMA': ['CARMA54560']}
37 3680 Chernihiv Hard Coal PP UA 200.0 0.0 0.0 0.0 0.0 1968.0 51455 31.2602 [nan] {'GPD': ['WRI1075853'], 'CARMA': ['CARMA8190']}

View File

@ -1,50 +1,53 @@
https://www.eia.gov/international/data/world/electricity/electricity-generation?pd=2&p=000000000000000000000000000000g&u=1&f=A&v=mapbubble&a=-&i=none&vo=value&t=R&g=000000000000002&l=73-1028i008017kg6368g80a4k000e0ag00gg0004g8g0ho00g000400008&s=315532800000&e=1577836800000&ev=false&
Report generated on: 03-28-2022 11:20:48
"API","","1980","1981","1982","1983","1984","1985","1986","1987","1988","1989","1990","1991","1992","1993","1994","1995","1996","1997","1998","1999","2000","2001","2002","2003","2004","2005","2006","2007","2008","2009","2010","2011","2012","2013","2014","2015","2016","2017","2018","2019","2020"
"","hydroelectricity net generation (billion kWh)","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
"INTL.33-12-EURO-BKWH.A"," Europe","458.018","464.155","459.881","473.685","481.241","476.739","459.535","491.085","534.517","465.365","474.466","475.47","509.041","526.448","531.815","543.743","529.114164","543.845616","562.441501","569.308453","591.206662","587.371195","541.542535","506.19703","544.536443","545.176179","537.335934","540.934407","567.557921","564.244482","619.96477","543.05273","600.46622","631.86431","619.59229","615.53013","629.98906","562.59258","619.31106","610.62616","670.925"
"INTL.33-12-ALB-BKWH.A"," Albania","2.919","3.018","3.093","3.167","3.241","3.315","3.365","3.979","3.713","3.846","2.82","3.483","3.187","3.281","3.733","4.162","5.669","4.978","4.872","5.231","4.548","3.519","3.477","5.117","5.411","5.319","4.951","2.76","3.759","5.201","7.49133","4.09068","4.67775","6.88941","4.67676","5.83605","7.70418","4.47975","8.46648","5.15394","5.281"
"INTL.33-12-AUT-BKWH.A"," Austria","28.501","30.008","29.893","29.577","28.384","30.288","30.496","25.401","35.151","34.641","31.179","31.112","34.483","36.336","35.349","36.696","33.874","35.744","36.792","40.292","41.418","40.05","39.825","32.883","36.394","36.31","35.48","36.732","37.969","40.487","36.466","32.511","41.862","40.138","39.001","35.255","37.954","36.462","35.73","40.43655","45.344"
"INTL.33-12-BEL-BKWH.A"," Belgium","0.274","0.377","0.325","0.331","0.348","0.282","0.339","0.425","0.354","0.3","0.263","0.226","0.338","0.252","0.342","0.335","0.237","0.30195","0.38511","0.338","0.455","0.437","0.356","0.245","0.314","0.285","0.355","0.385","0.406","0.325","0.298","0.193","0.353","0.376","0.289","0.314","0.367","0.268","0.311","0.108","1.29"
"INTL.33-12-BIH-BKWH.A"," Bosnia and Herzegovina","--","--","--","--","--","--","--","--","--","--","--","--","3.374","2.343","3.424","3.607","5.104","4.608","4.511","5.477","5.043","5.129","5.215","4.456","5.919","5.938","5.798","3.961","4.818","6.177","7.946","4.343","4.173","7.164","5.876","5.495","5.585","3.7521","6.35382","6.02019","6.1"
"INTL.33-12-BGR-BKWH.A"," Bulgaria","3.674","3.58","3.018","3.318","3.226","2.214","2.302","2.512","2.569","2.662","1.859","2.417","2.042","1.923","1.453","2.291","2.89","2.726","3.066","2.725","2.646","1.72","2.172","2.999","3.136","4.294","4.196","2.845","2.796","3.435","4.98168","2.84328","3.14622","3.99564","4.55598","5.59845","3.8412","2.79972","5.09553","3.34917","3.37"
"INTL.33-12-HRV-BKWH.A"," Croatia","--","--","--","--","--","--","--","--","--","--","--","--","4.298","4.302","4.881","5.212","7.156","5.234","5.403","6.524","5.794","6.482","5.311","4.827","6.888","6.27","5.94","4.194","5.164","6.663","9.035","4.983","4.789","8.536","8.917","6.327","6.784","5.255","7.62399","5.87268","3.4"
"INTL.33-12-CYP-BKWH.A"," Cyprus","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"
"INTL.33-12-CZE-BKWH.A"," Czech Republic","--","--","--","--","--","--","--","--","--","--","--","--","--","1.355","1.445","1.982","1.949","1.68201","1.382","1.664","1.7404","2.033","2.467","1.369","1.999","2.356","2.525","2.068","2.004","2.405","2.775","1.95","2.107","2.704","1.909","1.779","1.983","1.852","1.615","1.98792","3.4"
"INTL.33-12-DNK-BKWH.A"," Denmark","0.03","0.031","0.028","0.036","0.028","0.027","0.029","0.029","0.032","0.027","0.027","0.026","0.028","0.027","0.033","0.03","0.019","0.019","0.02673","0.031","0.03","0.028","0.032","0.021","0.027","0.023","0.023","0.028","0.026","0.019","0.021","0.017","0.017","0.013","0.015","0.018","0.019","0.018","0.015","0.01584","0.02"
"INTL.33-12-EST-BKWH.A"," Estonia","--","--","--","--","--","--","--","--","--","--","--","--","0.001","0.001","0.003","0.002","0.002","0.003","0.004","0.004","0.005","0.007","0.006","0.013","0.022","0.022","0.014","0.021","0.028","0.032","0.027","0.03","0.042","0.026","0.027","0.027","0.035","0.026","0.015","0.01881","0.04"
"INTL.33-12-FRO-BKWH.A"," Faroe Islands","0.049","0.049","0.049","0.049","0.049","0.049","0.049","0.049","0.062","0.071","0.074","0.074","0.083","0.073","0.075","0.075","0.069564","0.075066","0.076501","0.069453","0.075262","0.075195","0.095535","0.08483","0.093443","0.097986","0.099934","0.103407","0.094921","0.091482","0.06676","0.092","0.099","0.091","0.121","0.132","0.105","0.11","0.107","0.102","0.11"
"INTL.33-12-FIN-BKWH.A"," Finland","10.115","13.518","12.958","13.445","13.115","12.211","12.266","13.658","13.229","12.9","10.75","13.065","14.956","13.341","11.669","12.796","11.742","12.11958","14.9","12.652","14.513","13.073","10.668","9.495","14.919","13.646","11.379","14.035","16.941","12.559","12.743","12.278","16.667","12.672","13.24","16.584","15.634","14.61","13.137","12.31461","15.56"
"INTL.33-12-CSK-BKWH.A"," Former Czechoslovakia","4.8","4.2","3.7","3.9","3.2","4.3","4","4.853","4.355","4.229","3.919","3.119","3.602","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--"
"INTL.33-12-SCG-BKWH.A"," Former Serbia and Montenegro","--","--","--","--","--","--","--","--","--","--","--","--","11.23","10.395","11.016","12.071","14.266","12.636","12.763","13.243","11.88","12.326","11.633","9.752","11.01","11.912","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--"
"INTL.33-12-YUG-BKWH.A"," Former Yugoslavia","27.868","25.044","23.295","21.623","25.645","24.363","27.474","25.98","25.612","23.256","19.601","18.929","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--"
"INTL.33-12-FRA-BKWH.A"," France","68.253","70.358","68.6","67.515","64.01","60.248","60.953","68.623","73.952","45.744","52.796","56.277","68.313","64.3","78.057","72.196","64.43","63.151","61.479","71.832","66.466","73.888","59.992","58.567","59.276","50.965","55.741","57.029","63.017","56.428","61.945","45.184","59.099","71.042","62.993","54.876","60.094","49.389","64.485","56.98242","64.84"
"INTL.33-12-DEU-BKWH.A"," Germany","--","--","--","--","--","--","--","--","--","--","--","14.742","17.223","17.699","19.731","21.562","21.737","17.18343","17.044","19.451","21.515","22.506","22.893","19.071","20.866","19.442","19.808","20.957","20.239","18.841","20.678","17.323","21.331","22.66","19.31","18.664","20.214","19.985","17.815","19.86039","24.75"
"INTL.33-12-DDR-BKWH.A"," Germany, East","1.658","1.718","1.748","1.683","1.748","1.758","1.767","1.726","1.719","1.551","1.389","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--"
"INTL.33-12-DEUW-BKWH.A"," Germany, West","17.125","17.889","17.694","16.713","16.434","15.354","16.526","18.36","18.128","16.482","15.769","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--"
"INTL.33-12-GIB-BKWH.A"," Gibraltar","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"
"INTL.33-12-GRC-BKWH.A"," Greece","3.396","3.398","3.551","2.331","2.852","2.792","3.222","2.768","2.354","1.888","1.751","3.068","2.181","2.26","2.573","3.494","4.305","3.84318","3.68","4.546","3.656","2.076","2.772","4.718","4.625","4.967","5.806","2.565","3.279","5.32","7.431","3.998","4.387","6.337","4.464","5.782","5.543","3.962","5.035","3.9798","3.43"
"INTL.33-12-HUN-BKWH.A"," Hungary","0.111","0.166","0.158","0.153","0.179","0.153","0.152","0.167","0.167","0.156","0.176","0.192","0.156","0.164","0.159","0.161","0.205","0.21384","0.15345","0.179","0.176","0.184","0.192","0.169","0.203","0.2","0.184","0.208","0.211","0.226","0.184","0.216","0.206","0.208","0.294","0.227","0.253","0.214","0.216","0.21681","0.24"
"INTL.33-12-ISL-BKWH.A"," Iceland","3.053","3.085","3.407","3.588","3.738","3.667","3.846","3.918","4.169","4.217","4.162","4.162","4.267","4.421","4.47","4.635","4.724","5.15493","5.565","5.987","6.292","6.512","6.907","7.017","7.063","6.949","7.22","8.31","12.303","12.156","12.51","12.382","12.214","12.747","12.554","13.541","13.092","13.892","13.679","13.32441","12.46"
"INTL.33-12-IRL-BKWH.A"," Ireland","0.833","0.855","0.792","0.776","0.68","0.824","0.91","0.673","0.862","0.684","0.69","0.738","0.809","0.757","0.911","0.706","0.715","0.67122","0.907","0.838","0.838","0.59","0.903","0.592","0.624","0.625","0.717","0.66","0.959","0.893","0.593","0.699","0.795","0.593","0.701","0.798","0.674","0.685","0.687","0.87813","1.21"
"INTL.33-12-ITA-BKWH.A"," Italy","44.997","42.782","41.216","40.96","41.923","40.616","40.626","39.05","40.205","33.647","31.31","41.817","41.778","41.011","44.212","37.404","41.617","41.18697","40.808","44.911","43.763","46.343","39.125","33.303","41.915","35.706","36.624","32.488","41.207","48.647","50.506","45.36477","41.45625","52.24626","57.95955","45.08163","42.00768","35.83701","48.29913","45.31824","47.72"
"INTL.33-12-XKS-BKWH.A"," Kosovo","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","0.075","0.119","0.154","0.104","0.095","0.142","0.149","0.139","0.243","0.177","0.27027","0.2079","0.26"
"INTL.33-12-LVA-BKWH.A"," Latvia","--","--","--","--","--","--","--","--","--","--","--","--","2.498","2.846","3.272","2.908","1.841","2.922","2.99","2.729","2.791","2.805","2.438","2.243","3.078","3.293","2.671","2.706","3.078","3.422","3.488","2.857","3.677","2.838","1.953","1.841","2.523","4.356","2.417","2.08692","2.59"
"INTL.33-12-LTU-BKWH.A"," Lithuania","--","--","--","--","--","--","--","--","--","--","--","--","0.308","0.389","0.447","0.369","0.323","0.291","0.413","0.409","0.336","0.322","0.35","0.323","0.417","0.446193","0.393","0.417","0.398","0.42","0.535","0.475","0.419","0.516","0.395","0.346","0.45","0.597","0.427","0.34254","1.06"
"INTL.33-12-LUX-BKWH.A"," Luxembourg","0.086","0.095","0.084","0.083","0.088","0.071","0.084","0.101","0.097","0.072","0.07","0.083","0.069","0.066","0.117","0.087","0.059","0.082","0.114","0.084","0.119","0.117","0.098","0.078","0.103","0.093","0.11","0.116","0.131","0.105","0.104","0.061","0.095","0.114","0.104","0.095","0.111","0.082","0.089","0.10593","1.09"
"INTL.33-12-MLT-BKWH.A"," Malta","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"
"INTL.33-12-MNE-BKWH.A"," Montenegro","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","1.733","1.271","1.524","2.05","2.723","1.192","1.462","2.479","1.734","1.476","1.825","1.014","2.09187","1.78","1.8"
"INTL.33-12-NLD-BKWH.A"," Netherlands","0","0","0","0","0","0.003","0.003","0.001","0.002","0.037","0.119","0.079","0.119","0.091","0.1","0.087","0.079","0.09108","0.111","0.089","0.141","0.116","0.109","0.071","0.094","0.087","0.105","0.106","0.101","0.097","0.105","0.057","0.104","0.114","0.112","0.093","0.1","0.061","0.072","0.07326","0.05"
"INTL.33-12-MKD-BKWH.A"," North Macedonia","--","--","--","--","--","--","--","--","--","--","--","--","0.817","0.517","0.696","0.793","0.842","0.891","1.072","1.375","1.158","0.62","0.749","1.36","1.467","1.477","1.634","1","0.832","1.257","2.407","1.419","1.031","1.568","1.195","1.846","1.878","1.099","1.773","1.15236","1.24"
"INTL.33-12-NOR-BKWH.A"," Norway","82.717","91.876","91.507","104.704","104.895","101.464","95.321","102.341","107.919","117.369","119.933","109.032","115.505","118.024","110.398","120.315","102.823","108.677","114.546","120.237","140.4","119.258","128.078","104.425","107.693","134.331","118.175","132.319","137.654","124.03","116.257","119.78","141.189","127.551","134.844","136.662","142.244","141.651","138.202","123.66288","141.69"
"INTL.33-12-POL-BKWH.A"," Poland","2.326","2.116","1.528","1.658","1.394","1.833","1.534","1.644","1.775","1.593","1.403","1.411","1.492","1.473","1.716","1.868","1.912","1.941","2.286","2.133","2.085","2.302","2.256","1.654","2.06","2.179","2.022","2.328","2.13","2.351","2.9","2.313","2.02","2.421","2.165","1.814","2.117","2.552","1.949","1.93842","2.93"
"INTL.33-12-PRT-BKWH.A"," Portugal","7.873","4.934","6.82","7.897","9.609","10.512","8.364","9.005","12.037","5.72","9.065","8.952","4.599","8.453","10.551","8.26","14.613","12.97395","12.853","7.213","11.21","13.894","7.722","15.566","9.77","4.684","10.892","9.991","6.73","8.201","15.954","11.423","5.589","13.652","15.471","8.615","15.608","5.79","12.316","8.6526","13.96"
"INTL.33-12-ROU-BKWH.A"," Romania","12.506","12.605","11.731","9.934","11.208","11.772","10.688","11.084","13.479","12.497","10.87","14.107","11.583","12.64","12.916","16.526","15.597","17.334","18.69","18.107","14.63","14.774","15.886","13.126","16.348","20.005","18.172","15.806","17.023","15.379","19.684","14.581","11.945","14.807","18.618","16.467","17.848","14.349","17.48736","15.65289","15.53"
"INTL.33-12-SRB-BKWH.A"," Serbia","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","10.855","9.937","9.468","10.436","11.772","8.58","9.193","10.101","10.893","9.979","10.684","9.061","10.53261","10.07028","9.66"
"INTL.33-12-SVK-BKWH.A"," Slovakia","--","--","--","--","--","--","--","--","--","--","--","--","--","3.432","4.311","4.831","4.185","4.023","4.224","4.429","4.569","4.878","5.215","3.4452","4.059","4.592","4.355","4.406","4","4.324","5.184","3.211","3.687","4.329","3.762","3.701","4.302","4.321","3.506","4.27383","4.67"
"INTL.33-12-SVN-BKWH.A"," Slovenia","--","--","--","--","--","--","--","--","--","--","--","--","3.379","2.974","3.348","3.187","3.616","3.046","3.4","3.684","3.771","3.741","3.265","2.916","4.033","3.426","3.555","3.233","3.978","4.666","4.452","3.506","3.841","4.562","6.011","3.75","4.443","3.814","4.643","4.43421","5.24"
"INTL.33-12-ESP-BKWH.A"," Spain","29.16","21.64","25.99","26.696","31.088","30.895","26.105","27.016","34.76","19.046","25.16","27.01","18.731","24.133","27.898","22.881","39.404","34.43","33.665","22.634","29.274","40.617","22.691","40.643","31.359","18.209","25.699","27.036","23.13","26.147","41.576","30.07","20.192","36.45","38.815","27.656","35.77","18.007","33.743","24.23025","33.34"
"INTL.33-12-SWE-BKWH.A"," Sweden","58.133","59.006","54.369","62.801","67.106","70.095","60.134","70.95","69.016","70.911","71.778","62.603","73.588","73.905","58.508","67.421","51.2226","68.365","74.25","70.974","77.798","78.269","65.696","53.005","59.522","72.075","61.106","65.497","68.378","65.193","66.279","66.047","78.333","60.81","63.227","74.734","61.645","64.651","61.79","64.46583","71.6"
"INTL.33-12-CHE-BKWH.A"," Switzerland","32.481","35.13","35.974","35.069","29.871","31.731","32.576","34.328","35.437","29.477","29.497","31.756","32.373","35.416","38.678","34.817","28.458","33.70257","33.136","39.604","36.466","40.895","34.862","34.471","33.411","30.914","30.649","34.898","35.676","35.366","35.704","32.069","38.218","38.08","37.659","37.879","34.281","33.754","34.637","37.6596","40.62"
"INTL.33-12-TUR-BKWH.A"," Turkey","11.159","12.308","13.81","11.13","13.19","11.822","11.637","18.314","28.447","17.61","22.917","22.456","26.302","33.611","30.28","35.186","40.07","39.41784","41.80671","34.33","30.57","23.77","33.346","34.977","45.623","39.165","43.802","35.492","32.937","35.598","51.423","51.155","56.669","58.225","39.75","65.856","66.686","57.824","59.49","87.99714","77.39"
"INTL.33-12-GBR-BKWH.A"," United Kingdom","3.921","4.369","4.543","4.548","3.992","4.08","4.767","4.13","4.915","4.732","5.119","4.534","5.329","4.237","5.043","4.79","3.359","4.127","5.067","5.283","5.035","4.015","4.74","3.195","4.795","4.873","4.547","5.026","5.094","5.178","3.566","5.655","5.286","4.667","5.832","6.246","5.342","5.836","5.189","5.89941","7.64"
https://www.eia.gov/international/data/world/electricity/electricity-generation?pd=2&p=000000000000000000000000000000g&u=1&f=A&v=mapbubble&a=-&i=none&vo=value&t=R&g=000000000000002&l=73-1028i008017kg6368g80a4k000e0ag00gg0004g8g0ho00g000400008&l=72-00000000000000000000000000080000000000000000000g&s=315532800000&e=1609459200000&ev=false&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Report generated on: 01-06-2023 21:17:46,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
API,,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021
,hydroelectricity net generation (billion kWh),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
INTL.33-12-EURO-BKWH.A, Europe,"458,018","464,155","459,881","473,685","481,241","476,739","459,535","491,085","534,517","465,365","474,466","475,47","509,041","526,448","531,815","543,743","529,114164","543,845616","562,491501","566,861453","588,644662","584,806195","539,051405","503,7067","542,112443","542,974669","535,006084","538,449707","565,143111","561,761402","617,547148","540,926277","598,055253","629,44709","617,111295","613,079848","627,720566217","560,362524","616,5081462","606,5997419","644,1106599","628,1390143"
INTL.33-12-ALB-BKWH.A, Albania,"2,919","3,018","3,093","3,167","3,241","3,315","3,365","3,979","3,713","3,846","2,82","3,483","3,187","3,281","3,733","4,162","5,669","4,978","4,872","5,231","4,548","3,519","3,477","5,117","5,411","5,319","4,951","2,76","3,759","5,201","7,49133","4,09068","4,67775","6,88941","4,67676","5,83605","7,70418","4,47975","8,46648","5,15394","5,281","8,891943"
INTL.33-12-AUT-BKWH.A, Austria,"28,501","30,008","29,893","29,577","28,384","30,288","30,496","25,401","35,151","34,641","31,179","31,112","34,483","36,336","35,349","36,696","33,874","35,744","36,792","40,292","41,418","40,05","39,825","32,883","36,394","36,31","35,48","36,732","37,969","40,487","36,466","32,511","41,862","40,138","39,001","35,255","37,954","36,462","35,73","40,43655","41,9356096","38,75133"
INTL.33-12-BEL-BKWH.A, Belgium,"0,274","0,377","0,325","0,331","0,348","0,282","0,339","0,425","0,354","0,3","0,263","0,226","0,338","0,252","0,342","0,335","0,237","0,30195","0,38511","0,338","0,455","0,437","0,356","0,245","0,314","0,285","0,355","0,385","0,406","0,325","0,298","0,193","0,353","0,376","0,289","0,314","0,367","0,268","0,3135","0,302","0,2669","0,3933"
INTL.33-12-BIH-BKWH.A, Bosnia and Herzegovina,--,--,--,--,--,--,--,--,--,--,--,--,"3,374","2,343","3,424","3,607","5,104","4,608","4,511","5,477","5,043","5,129","5,215","4,456","5,919","5,938","5,798","3,961","4,818","6,177","7,946","4,343","4,173","7,164","5,876","5,495","5,585","3,7521","6,35382","6,02019","4,58","6,722"
INTL.33-12-BGR-BKWH.A, Bulgaria,"3,674","3,58","3,018","3,318","3,226","2,214","2,302","2,512","2,569","2,662","1,859","2,417","2,042","1,923","1,453","2,291","2,89","2,726","3,066","2,725","2,646","1,72","2,172","2,999","3,136","4,294","4,196","2,845","2,796","3,435","4,98168","2,84328","3,14622","3,99564","4,55598","5,59845","3,8412","2,79972","5,09553","2,929499","2,820398","4,819205"
INTL.33-12-HRV-BKWH.A, Croatia,--,--,--,--,--,--,--,--,--,--,--,--,"4,298","4,302","4,881","5,212","7,156","5,234","5,403","6,524","5,794","6,482","5,311","4,827","6,888","6,27","5,94","4,194","5,164","6,663","9,035","4,983","4,789","8,536","8,917","6,327","6,784","5,255","7,62399","5,87268","5,6624","7,1277"
INTL.33-12-CYP-BKWH.A, Cyprus,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
INTL.33-12-CZE-BKWH.A, Czechia,--,--,--,--,--,--,--,--,--,--,--,--,--,"1,355","1,445","1,982","1,949","1,68201","1,382","1,664","1,7404","2,033","2,467","1,369","1,999","2,356","2,525","2,068","2,004","2,405","2,775","1,95","2,107","2,704","1,909","1,779","1,983","1,852","1,615","1,98792","2,143884","2,40852"
INTL.33-12-DNK-BKWH.A, Denmark,"0,03","0,031","0,028","0,036","0,028","0,027","0,029","0,029","0,032","0,027","0,027","0,026","0,028","0,027","0,033","0,03","0,019","0,019","0,02673","0,031","0,03","0,028","0,032","0,021","0,027","0,023","0,023","0,028","0,026","0,019","0,021","0,017","0,017","0,013","0,015","0,01803","0,01927","0,017871","0,0148621","0,0172171","0,017064","0,016295"
INTL.33-12-EST-BKWH.A, Estonia,--,--,--,--,--,--,--,--,--,--,--,--,"0,001","0,001","0,003","0,002","0,002","0,003","0,004","0,004","0,005","0,007","0,006","0,013","0,022","0,022","0,014","0,021","0,028","0,032","0,027","0,029999","0,042","0,026","0,027","0,027","0,035","0,025999","0,0150003","0,0189999","0,03","0,0248"
INTL.33-12-FRO-BKWH.A, Faroe Islands,"0,049","0,049","0,049","0,049","0,049","0,049","0,049","0,049","0,062","0,071","0,074","0,074","0,083","0,073","0,075","0,075","0,069564","0,075066","0,076501","0,069453","0,075262","0,075195","0,095535","0,08483","0,093443","0,097986","0,099934","0,103407","0,094921","0,091482","0,06676","0,092","0,099","0,091","0,121","0,132","0,105","0,11","0,107","0,102","0,11","0,11"
INTL.33-12-FIN-BKWH.A, Finland,"10,115","13,518","12,958","13,445","13,115","12,211","12,266","13,658","13,229","12,9","10,75","13,065","14,956","13,341","11,669","12,796","11,742","12,11958","14,9","12,652","14,513","13,073","10,668","9,495","14,919","13,646","11,379","14,035","16,941","12,559","12,743","12,278001","16,666998","12,672","13,240001","16,583999","15,634127","14,609473","13,1369998","12,2454823","15,883","15,766"
INTL.33-12-CSK-BKWH.A, Former Czechoslovakia,"4,8","4,2","3,7","3,9","3,2","4,3",4,"4,853","4,355","4,229","3,919","3,119","3,602",--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--
INTL.33-12-SCG-BKWH.A, Former Serbia and Montenegro,--,--,--,--,--,--,--,--,--,--,--,--,"11,23","10,395","11,016","12,071","14,266","12,636","12,763","13,243","11,88","12,326","11,633","9,752","11,01","11,912",--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--
INTL.33-12-YUG-BKWH.A, Former Yugoslavia,"27,868","25,044","23,295","21,623","25,645","24,363","27,474","25,98","25,612","23,256","19,601","18,929",--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--
INTL.33-12-FRA-BKWH.A, France,"68,253","70,358","68,6","67,515","64,01","60,248","60,953","68,623","73,952","45,744","52,796","56,277","68,313","64,3","78,057","72,196","64,43","63,151","61,479","71,832","66,466","73,888","59,992","58,567","59,276","50,965","55,741","57,029","63,017","56,428","61,945","45,184","59,099","71,042","62,993","54,876","60,094","49,389","64,485","56,913891","62,06191","58,856657"
INTL.33-12-DEU-BKWH.A, Germany,--,--,--,--,--,--,--,--,--,--,--,"14,742","17,223","17,699","19,731","21,562","21,737","17,18343","17,044","19,451","21,515","22,506","22,893","19,071","20,866","19,442","19,808","20,957","20,239","18,841","20,678","17,323","21,331","22,66","19,31","18,664","20,214","19,985","17,694","19,731","18,322","19,252"
INTL.33-12-DDR-BKWH.A," Germany, East","1,658","1,718","1,748","1,683","1,748","1,758","1,767","1,726","1,719","1,551","1,389",--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--
INTL.33-12-DEUW-BKWH.A," Germany, West","17,125","17,889","17,694","16,713","16,434","15,354","16,526","18,36","18,128","16,482","15,769",--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--
INTL.33-12-GIB-BKWH.A, Gibraltar,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
INTL.33-12-GRC-BKWH.A, Greece,"3,396","3,398","3,551","2,331","2,852","2,792","3,222","2,768","2,354","1,888","1,751","3,068","2,181","2,26","2,573","3,494","4,305","3,84318","3,68","4,546","3,656","2,076","2,772","4,718","4,625","4,967","5,806","2,565","3,279","5,32","7,431","3,998","4,387","6,337","4,464","5,782","5,543","3,962","5,035","3,9798","3,343687","5,909225"
INTL.33-12-HUN-BKWH.A, Hungary,"0,111","0,166","0,158","0,153","0,179","0,153","0,152","0,167","0,167","0,156","0,176","0,192","0,156","0,164","0,159","0,161","0,205","0,21384","0,15345","0,179","0,176","0,184","0,192","0,169","0,203","0,2","0,184","0,208","0,211","0,226","0,184","0,215999","0,205999","0,207999","0,294001","0,226719","0,253308","0,213999","0,216","0,2129999","0,238","0,202379"
INTL.33-12-ISL-BKWH.A, Iceland,"3,053","3,085","3,407","3,588","3,738","3,667","3,846","3,918","4,169","4,217","4,162","4,162","4,267","4,421","4,47","4,635","4,724","5,15493","5,565","5,987","6,292","6,512","6,907","7,017","7,063","6,949","7,22","8,31","12,303","12,156","12,509999","12,381999","12,213999","12,747001","12,554","13,541","13,091609","13,891929","13,679377","13,32911","12,9196201","13,5746171"
INTL.33-12-IRL-BKWH.A, Ireland,"0,833","0,855","0,792","0,776","0,68","0,824","0,91","0,673","0,862","0,684","0,69","0,738","0,809","0,757","0,911","0,706","0,715","0,67122","0,907","0,838","0,838","0,59","0,903","0,592","0,624","0,625","0,717","0,66","0,959","0,893","0,593","0,699","0,795","0,593","0,701","0,798","0,674","0,685","0,687","0,87813","0,932656","0,750122"
INTL.33-12-ITA-BKWH.A, Italy,"44,997","42,782","41,216","40,96","41,923","40,616","40,626","39,05","40,205","33,647","31,31","41,817","41,778","41,011","44,212","37,404","41,617","41,18697","40,808","44,911","43,763","46,343","39,125","33,303","41,915","35,706","36,624","32,488","41,207","48,647","50,506","45,36477","41,45625","52,24626","57,95955","45,08163","42,00768","35,83701","48,29913","45,31824","47,551784","44,739"
INTL.33-12-XKS-BKWH.A, Kosovo,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,"0,075","0,119","0,154","0,104","0,095","0,142","0,149","0,139","0,243","0,177","0,27027","0,2079","0,262826","0,300635"
INTL.33-12-LVA-BKWH.A, Latvia,--,--,--,--,--,--,--,--,--,--,--,--,"2,498","2,846","3,272","2,908","1,841","2,922","2,99","2,729","2,791","2,805","2,438","2,243","3,078","3,293","2,671","2,706","3,078","3,422","3,487998","2,8568","3,677","2,838","1,953","1,841","2,522819","4,355513","2,4170639","2,0958919","2,5840101","2,6889293"
INTL.33-12-LTU-BKWH.A, Lithuania,--,--,--,--,--,--,--,--,--,--,--,--,"0,308","0,389","0,447","0,369","0,323","0,291","0,413","0,409","0,336","0,322","0,35","0,323","0,417","0,446193","0,393","0,417","0,398","0,42","0,535","0,475","0,419","0,516","0,395","0,346","0,45","0,597","0,427","0,34254","0,3006","0,3837"
INTL.33-12-LUX-BKWH.A, Luxembourg,"0,086","0,095","0,084","0,083","0,088","0,071","0,084","0,101","0,097","0,072","0,07","0,083","0,069","0,066","0,117","0,087","0,059","0,082","0,114","0,084","0,119","0,117","0,098","0,078","0,103","0,093","0,11","0,116","0,131","0,105","0,104","0,061","0,095","0,114","0,104","0,095","0,111","0,082","0,089","0,10593","0,091602","0,1068"
INTL.33-12-MLT-BKWH.A, Malta,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
INTL.33-12-MNE-BKWH.A, Montenegro,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,"1,733","1,271","1,524","2,05","2,723","1,192","1,462","2,479","1,734","1,476","1,825","1,014","1,693443","1,262781","0,867637","1,212652"
INTL.33-12-NLD-BKWH.A, Netherlands,0,0,0,0,0,"0,003","0,003","0,001","0,002","0,037","0,119","0,079","0,119","0,091","0,1","0,087","0,079","0,09108","0,111","0,089","0,141","0,116","0,109","0,071","0,094","0,087","0,105","0,106","0,101","0,097","0,105","0,057","0,104389","0,11431","0,112202","0,0927","0,100078","0,060759","0,0723481","0,074182","0,0462851","0,0838927"
INTL.33-12-MKD-BKWH.A, North Macedonia,--,--,--,--,--,--,--,--,--,--,--,--,"0,817","0,517","0,696","0,793","0,842","0,891","1,072","1,375","1,158","0,62","0,749","1,36","1,467","1,477","1,634",1,"0,832","1,257","2,407","1,419","1,031","1,568","1,195","1,846","1,878","1,099","1,773","1,15236","1,277144","1,451623"
INTL.33-12-NOR-BKWH.A, Norway,"82,717","91,876","91,507","104,704","104,895","101,464","95,321","102,341","107,919","117,369","119,933","109,032","115,505","118,024","110,398","120,315","102,823","108,677","114,546","120,237","140,4","119,258","128,078","104,425","107,693","134,331","118,175","132,319","137,654","124,03","116,257","119,78","141,189","127,551","134,844","136,662","142,244","141,651","138,202","123,66288","141,69",144
INTL.33-12-POL-BKWH.A, Poland,"2,326","2,116","1,528","1,658","1,394","1,833","1,534","1,644","1,775","1,593","1,403","1,411","1,492","1,473","1,716","1,868","1,912","1,941","2,286","2,133","2,085","2,302","2,256","1,654","2,06","2,179","2,022","2,328","2,13","2,351","2,9","2,313","2,02","2,421","2,165","1,814","2,117","2,552","1,949","1,93842","2,118337","2,339192"
INTL.33-12-PRT-BKWH.A, Portugal,"7,873","4,934","6,82","7,897","9,609","10,512","8,364","9,005","12,037","5,72","9,065","8,952","4,599","8,453","10,551","8,26","14,613","12,97395","12,853","7,213","11,21","13,894","7,722","15,566","9,77","4,684","10,892","9,991","6,73","8,201","15,954","11,423","5,589","13,652","15,471","8,615","15,608","5,79","12,316","8,6526","12,082581","11,846464"
INTL.33-12-ROU-BKWH.A, Romania,"12,506","12,605","11,731","9,934","11,208","11,772","10,688","11,084","13,479","12,497","10,87","14,107","11,583","12,64","12,916","16,526","15,597","17,334","18,69","18,107","14,63","14,774","15,886","13,126","16,348","20,005","18,172","15,806","17,023","15,379","19,684","14,581","11,945","14,807","18,618","16,467","17,848","14,349","17,48736","15,580622","15,381243","17,376933"
INTL.33-12-SRB-BKWH.A, Serbia,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,"10,855","9,937","9,468","10,436","11,772","8,58","9,193","10,101","10,893","9,979","10,684","9,061","10,53261","9,457175","9,034496","11,284232"
INTL.33-12-SVK-BKWH.A, Slovakia,--,--,--,--,--,--,--,--,--,--,--,--,--,"3,432","4,311","4,831","4,185","4,023","4,224","4,429","4,569","4,878","5,215","3,4452","4,059","4,592","4,355","4,406",4,"4,324","5,184","3,211","3,687","4,329","3,762","3,701","4,302","4,321","3,506","4,27383","4,517","4,17"
INTL.33-12-SVN-BKWH.A, Slovenia,--,--,--,--,--,--,--,--,--,--,--,--,"3,379","2,974","3,348","3,187","3,616","3,046","3,4","3,684","3,771","3,741","3,265","2,916","4,033","3,426","3,555","3,233","3,978","4,666","4,452","3,506","3,841","4,562","6,011","3,75","4,443","3,814","4,643","4,43421","4,93406","4,711944"
INTL.33-12-ESP-BKWH.A, Spain,"29,16","21,64","25,99","26,696","31,088","30,895","26,105","27,016","34,76","19,046","25,16","27,01","18,731","24,133","27,898","22,881","39,404","34,43","33,665","22,634","29,274","40,617","22,691","40,643","31,359","18,209","25,699","27,036","23,13","26,147","41,576","30,07","20,192","36,45","38,815","27,656","35,77","18,007","33,743","24,23025","30,507","29,626"
INTL.33-12-SWE-BKWH.A, Sweden,"58,133","59,006","54,369","62,801","67,106","70,095","60,134","70,95","69,016","70,911","71,778","62,603","73,588","73,905","58,508","67,421","51,2226","68,365","74,25","70,974","77,798","78,269","65,696","53,005","59,522","72,075","61,106","65,497","68,378","65,193","66,279","66,047","78,333","60,81","63,227","74,734","61,645","64,651","61,79","64,46583","71,6","71,086"
INTL.33-12-CHE-BKWH.A, Switzerland,"32,481","35,13","35,974","35,069","29,871","31,731","32,576","34,328","35,437","29,477","29,497","31,756","32,373","35,416","38,678","34,817","28,458","33,70257","33,136","37,104","33,854","38,29","32,323","31,948","30,938","28,664","28,273","32,362","33,214","32,833","33,261","29,906","35,783","35,628","35,122","35,378","31,984","31,47968","32,095881","35,156989","37,867647","36,964485"
INTL.33-12-TUR-BKWH.A, Turkey,"11,159","12,308","13,81","11,13","13,19","11,822","11,637","18,314","28,447","17,61","22,917","22,456","26,302","33,611","30,28","35,186","40,07","39,41784","41,80671","34,33","30,57","23,77","33,346","34,977","45,623","39,165","43,802","35,492","32,937","35,598","51,423001","51,154999","56,668998","58,225","39,750001","65,856","66,685883","57,823851","59,490211","88,2094218","78,094369","55,1755392"
INTL.33-12-GBR-BKWH.A, United Kingdom,"3,921","4,369","4,543","4,548","3,992","4,08","4,767","4,13","4,915","4,732","5,119","4,534","5,329","4,237","5,043","4,79","3,359","4,127","5,117","5,336","5,085","4,055","4,78787","3,22767","4,844","4,92149","4,59315","5,0773","5,14119","5,22792","3,59138","5,69175","5,30965","4,70147","5,8878","6,29727","5,370412217","5,88187","5,44327","5,84628","6,75391","5,0149"
, Eurasia,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
INTL.33-12-MDA-BKWH.A, Moldova,--,--,--,--,--,--,--,--,--,--,--,--,"0,255","0,371","0,275","0,321","0,362","0,378","0,387","0,363","0,392","0,359","0,348","0,358","0,35","0,359","0,365","0,354","0,385","0,354","0,403","0,348","0,266","0,311","0,317","0,265","0,228","0,282","0,27324","0,29799","0,276","0,316"
INTL.33-12-UKR-BKWH.A, Ukraine,--,--,--,--,--,--,--,--,--,--,--,--,"7,725","10,929","11,997","9,853","8,546","9,757","15,756","14,177","11,161","11,912","9,531","9,146","11,635","12,239","12,757","10,042","11,397","11,817","13,02","10,837","10,374","13,663","8,393","5,343","7,594","8,856","10,32372","6,5083","7,5638","10,3326"

Can't render this file because it has a wrong number of fields in line 3.

View File

@ -80,9 +80,9 @@ author = "Tom Brown (KIT, TUB, FIAS), Jonas Hoersch (KIT, FIAS), Fabian Hofmann
# built documents.
#
# The short X.Y version.
version = "0.8"
version = "0.9"
# The full version, including alpha/beta/rc tags.
release = "0.8.1"
release = "0.9.0"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -1,4 +1,5 @@
,Unit,Values,Description
focus_weights,,,Optionally specify the focus weights for the clustering of countries. For instance: `DE: 0.8` will distribute 80% of all nodes to Germany and 20% to the rest of the countries.
simplify_network,,,
-- to_substations,bool,"{'true','false'}","Aggregates all nodes without power injection (positive or negative, i.e. demand or generation) to electrically closest ones"
-- algorithm,str,"One of {kmeans, hac, modularity}",

1 Unit Values Description
2 focus_weights Optionally specify the focus weights for the clustering of countries. For instance: `DE: 0.8` will distribute 80% of all nodes to Germany and 20% to the rest of the countries.
3 simplify_network
4 -- to_substations bool {'true','false'} Aggregates all nodes without power injection (positive or negative, i.e. demand or generation) to electrically closest ones
5 -- algorithm str One of {‘kmeans’, ‘hac’, ‘modularity‘}

View File

@ -1,9 +1,12 @@
,Unit,Values,Description
year,--,"YYYY; e.g. '2030'","Year for which to retrieve cost assumptions of ``resources/costs.csv``."
version,--,"vX.X.X; e.g. 'v0.5.0'","Version of ``technology-data`` repository to use."
rooftop_share,--,float,"Share of rooftop PV when calculating capital cost of solar (joint rooftop and utility-scale PV)."
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``."
marginal_cost,EUR/MWh,"Keys should be in the 'technology' column of ``resources/costs.csv``. Values can be any float.","For the given technologies, assumptions about their marginal operating costs are set to the corresponding value. Optional; overwrites cost assumptions from ``resources/costs.csv``."
emission_prices,,,"Specify exogenous prices for emission types listed in ``network.carriers`` to marginal costs."
-- co2,EUR/t,float,"Exogenous price of carbon-dioxide added to the marginal costs of fossil-fuelled generators according to their carbon intensity. Added through the keyword ``Ep`` in the ``{opts}`` wildcard only in the rule :mod:`prepare_network``."
year,--,YYYY; e.g. '2030',Year for which to retrieve cost assumptions of ``resources/costs.csv``.
version,--,vX.X.X; e.g. 'v0.5.0',Version of ``technology-data`` repository to use.
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``."
marginal_cost,EUR/MWh,Keys should be in the 'technology' column of ``resources/costs.csv``. Values can be any float.,"For the given technologies, assumptions about their marginal operating costs are set to the corresponding value. Optional; overwrites cost assumptions from ``resources/costs.csv``."
emission_prices,,,Specify exogenous prices for emission types listed in ``network.carriers`` to marginal costs.
-- enable,bool,true or false,Add cost for a carbon-dioxide price configured in ``costs: emission_prices: co2`` to ``marginal_cost`` of generators (other emission types listed in ``network.carriers`` possible as well)
-- co2,EUR/t,float,Exogenous price of carbon-dioxide added to the marginal costs of fossil-fuelled generators according to their carbon intensity. Added through the keyword ``Ep`` in the ``{opts}`` wildcard only in the rule :mod:`prepare_network``.
-- co2_monthly_price,bool,true or false,Add monthly cost for a carbon-dioxide price based on historical values built by the rule ``build_monthly_prices``

1 Unit Values Description
2 year -- YYYY; e.g. '2030' Year for which to retrieve cost assumptions of ``resources/costs.csv``.
3 version -- vX.X.X; e.g. 'v0.5.0' Version of ``technology-data`` repository to use.
4 rooftop_share -- float Share of rooftop PV when calculating capital cost of solar (joint rooftop and utility-scale PV).
5 fill_values social_discountrate -- p.u. float Default values if not specified for a technology in ``resources/costs.csv``. Social discount rate to compare costs in different investment periods. 0.02 corresponds to a social discount rate of 2%.
6 capital_cost fill_values EUR/MW -- Keys should be in the 'technology' column of ``resources/costs.csv``. Values can be any float. 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``. Default values if not specified for a technology in ``resources/costs.csv``.
7 marginal_cost capital_cost EUR/MWh 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 marginal operating costs are set to the corresponding value. Optional; overwrites cost assumptions from ``resources/costs.csv``. For the given technologies, assumptions about their capital investment costs are set to the corresponding value. Optional; overwrites cost assumptions from ``resources/costs.csv``.
8 emission_prices marginal_cost EUR/MWh Keys should be in the 'technology' column of ``resources/costs.csv``. Values can be any float. Specify exogenous prices for emission types listed in ``network.carriers`` to marginal costs. For the given technologies, assumptions about their marginal operating costs are set to the corresponding value. Optional; overwrites cost assumptions from ``resources/costs.csv``.
9 -- co2 emission_prices EUR/t float Exogenous price of carbon-dioxide added to the marginal costs of fossil-fuelled generators according to their carbon intensity. Added through the keyword ``Ep`` in the ``{opts}`` wildcard only in the rule :mod:`prepare_network``. Specify exogenous prices for emission types listed in ``network.carriers`` to marginal costs.
10 -- enable bool true or false Add cost for a carbon-dioxide price configured in ``costs: emission_prices: co2`` to ``marginal_cost`` of generators (other emission types listed in ``network.carriers`` possible as well)
11 -- co2 EUR/t float Exogenous price of carbon-dioxide added to the marginal costs of fossil-fuelled generators according to their carbon intensity. Added through the keyword ``Ep`` in the ``{opts}`` wildcard only in the rule :mod:`prepare_network``.
12 -- co2_monthly_price bool true or false Add monthly cost for a carbon-dioxide price based on historical values built by the rule ``build_monthly_prices``

View File

@ -1,6 +1,8 @@
,Unit,Values,Description
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,: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``.
@ -22,6 +24,8 @@ powerplants_filter,--,"use `pandas.query <https://pandas.pydata.org/pandas-docs/
,,,
custom_powerplants,--,"use `pandas.query <https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.query.html>`_ strings here, e.g. ``Country in ['Germany']``",Filter query for the custom powerplant database.
,,,
everywhere_powerplants,--,"Any subset of {nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass}","List of conventional power plants to add to every node in the model with zero initial capacity. To be used in combination with ``extendable_carriers`` to allow for building conventional powerplants irrespective of existing locations."
,,,
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, offwind-float, hydro}",List of renewable generators to include in the model.
@ -34,3 +38,6 @@ estimate_renewable_capacities,,,
-- -- 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,,,
-- enable,bool,true or false,Require each node to be autarkic by removing all lines and links.
-- by_country,bool,true or false,Require each country to be autarkic by removing all cross-border lines and links. ``electricity: autarky`` must be enabled.

1 Unit Values Description
2 voltages kV Any subset of {220., 300., 380.} Voltage levels to consider
3 gaslimit_enable bool true or false Add an overall absolute gas limit configured in ``electricity: gaslimit``.
4 gaslimit MWhth float or false Global gas usage limit
5 co2limit_enable bool true or false Add an overall absolute carbon-dioxide emissions limit configured in ``electricity: co2limit``.
6 co2limit :math:`t_{CO_2-eq}/a` float Cap on total annual system carbon dioxide emissions
7 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.
8 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``.
24
25 custom_powerplants -- use `pandas.query <https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.query.html>`_ strings here, e.g. ``Country in ['Germany']`` Filter query for the custom powerplant database.
26
27 everywhere_powerplants -- Any subset of {nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass} List of conventional power plants to add to every node in the model with zero initial capacity. To be used in combination with ``extendable_carriers`` to allow for building conventional powerplants irrespective of existing locations.
28
29 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.
30
31 renewable_carriers -- Any subset of {solar, onwind, offwind-ac, offwind-dc, offwind-float, hydro} List of renewable generators to include in the model.
38 -- -- Offshore -- Any subset of {offwind-ac, offwind-dc, offwind-float} List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) onshore technology.
39 -- -- Offshore -- {onwind} List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) offshore technology.
40 -- -- PV -- {solar} List of PyPSA-Eur carriers that is considered as (IRENA, OPSD) PV technology.
41 autarky
42 -- enable bool true or false Require each node to be autarkic by removing all lines and links.
43 -- by_country bool true or false Require each country to be autarkic by removing all cross-border lines and links. ``electricity: autarky`` must be enabled.

View File

@ -5,7 +5,7 @@
"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_generation _2000_2014.csv","x",,,,https://www.eia.gov/about/copyrights_reuse.php
"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
"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

1 Files BY NC SA Mark Changes Detail
5 naturalearth/* http://www.naturalearthdata.com/about/terms-of-use/
6 NUTS_2013 _60M_SH/* x x x https://ec.europa.eu/eurostat/web/gisco/geodata/reference-data/administrative-units-statistical-units
7 cantons.csv x x https://en.wikipedia.org/wiki/Data_codes_for_Switzerland
8 EIA_hydro_generation _2000_2014.csv eia_hydro_annual_generation.csv x https://www.eia.gov/about/copyrights_reuse.php
9 GEBCO_2014_2D.nc x https://www.gebco.net/data_and_products/gridded_bathymetry_data/documents/gebco_2014_historic.pdf
10 hydro_capacities.csv x
11 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

View File

@ -5,6 +5,7 @@ s_nom_max,MW,"float","Global upper limit for the maximum capacity of each extend
max_extension,MW,"float","Upper limit for the extended capacity of each extendable line."
length_factor,--,float,"Correction factor to account for the fact that buses are *not* connected by lines through air-line distance."
under_construction,--,"One of {'zero': set capacity to zero, 'remove': remove completely, 'keep': keep with full capacity}","Specifies how to handle lines which are currently under construction."
reconnect_crimea,--,"true or false","Whether to reconnect Crimea to the Ukrainian grid"
dynamic_line_rating,,,
-- activate,bool,"true or false","Whether to take dynamic line rating into account"
-- cutout,--,"Should be a folder listed in the configuration ``atlite: cutouts:`` (e.g. 'europe-2013-era5') or reference an existing folder in the directory ``cutouts``. Source module must be ERA5.","Specifies the directory where the relevant weather data ist stored."

1 Unit Values Description
5 max_extension MW float Upper limit for the extended capacity of each extendable line.
6 length_factor -- float Correction factor to account for the fact that buses are *not* connected by lines through air-line distance.
7 under_construction -- One of {'zero': set capacity to zero, 'remove': remove completely, 'keep': keep with full capacity} Specifies how to handle lines which are currently under construction.
8 reconnect_crimea -- true or false Whether to reconnect Crimea to the Ukrainian grid
9 dynamic_line_rating
10 -- activate bool true or false Whether to take dynamic line rating into account
11 -- cutout -- Should be a folder listed in the configuration ``atlite: cutouts:`` (e.g. 'europe-2013-era5') or reference an existing folder in the directory ``cutouts``. Source module must be ERA5. Specifies the directory where the relevant weather data ist stored.

View File

@ -7,10 +7,10 @@ capacity_per_sqkm,:math:`MW/km^2`,float,"Allowable density of wind turbine place
correction_factor,--,float,"Correction factor for capacity factor time series."
excluder_resolution,m,float,"Resolution on which to perform geographical elibility analysis."
corine,--,"Any *realistic* subset of the `CORINE Land Cover code list <http://www.eea.europa.eu/data-and-maps/data/corine-land-cover-2006-raster-1/corine-land-cover-classes-and/clc_legend.csv/at_download/file>`_","Specifies areas according to CORINE Land Cover codes which are generally eligible for AC-connected offshore wind turbine placement."
luisa,--,"Any subset of the `LUISA Base Map codes in Annex 1 <https://publications.jrc.ec.europa.eu/repository/bitstream/JRC124621/technical_report_luisa_basemap_2018_v7_final.pdf>`_","Specifies areas according to the LUISA Base Map codes which are generally eligible for AC-connected offshore wind turbine placement."
natura,bool,"{true, false}","Switch to exclude `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas. Area is excluded if ``true``."
ship_threshold,--,float,"Ship density threshold from which areas are excluded."
max_depth,m,float,"Maximum sea water depth at which wind turbines can be build. Maritime areas with deeper waters are excluded in the process of calculating the AC-connected offshore wind potential."
min_shore_distance,m,float,"Minimum distance to the shore below which wind turbines cannot be build. Such areas close to the shore are excluded in the process of calculating the AC-connected offshore wind potential."
max_shore_distance,m,float,"Maximum distance to the shore above which wind turbines cannot be build. Such areas close to the shore are excluded in the process of calculating the AC-connected offshore wind potential."
potential,--,"One of {'simple', 'conservative'}","Method to compute the maximal installable potential for a node; confer :ref:`renewableprofiles`"
clip_p_max_pu,p.u.,float,"To avoid too small values in the renewables` per-unit availability time series values below this threshold are set to zero."

1 Unit Values Description
7 correction_factor -- float Correction factor for capacity factor time series.
8 excluder_resolution m float Resolution on which to perform geographical elibility analysis.
9 corine -- Any *realistic* subset of the `CORINE Land Cover code list <http://www.eea.europa.eu/data-and-maps/data/corine-land-cover-2006-raster-1/corine-land-cover-classes-and/clc_legend.csv/at_download/file>`_ Specifies areas according to CORINE Land Cover codes which are generally eligible for AC-connected offshore wind turbine placement.
10 luisa -- Any subset of the `LUISA Base Map codes in Annex 1 <https://publications.jrc.ec.europa.eu/repository/bitstream/JRC124621/technical_report_luisa_basemap_2018_v7_final.pdf>`_ Specifies areas according to the LUISA Base Map codes which are generally eligible for AC-connected offshore wind turbine placement.
11 natura bool {true, false} Switch to exclude `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas. Area is excluded if ``true``.
12 ship_threshold -- float Ship density threshold from which areas are excluded.
13 max_depth m float Maximum sea water depth at which wind turbines can be build. Maritime areas with deeper waters are excluded in the process of calculating the AC-connected offshore wind potential.
14 min_shore_distance m float Minimum distance to the shore below which wind turbines cannot be build. Such areas close to the shore are excluded in the process of calculating the AC-connected offshore wind potential.
15 max_shore_distance m float Maximum distance to the shore above which wind turbines cannot be build. Such areas close to the shore are excluded in the process of calculating the AC-connected offshore wind potential.
potential -- One of {'simple', 'conservative'} Method to compute the maximal installable potential for a node; confer :ref:`renewableprofiles`
16 clip_p_max_pu p.u. float To avoid too small values in the renewables` per-unit availability time series values below this threshold are set to zero.

View File

@ -7,10 +7,10 @@ capacity_per_sqkm,:math:`MW/km^2`,float,"Allowable density of wind turbine place
correction_factor,--,float,"Correction factor for capacity factor time series."
excluder_resolution,m,float,"Resolution on which to perform geographical elibility analysis."
corine,--,"Any *realistic* subset of the `CORINE Land Cover code list <http://www.eea.europa.eu/data-and-maps/data/corine-land-cover-2006-raster-1/corine-land-cover-classes-and/clc_legend.csv/at_download/file>`_","Specifies areas according to CORINE Land Cover codes which are generally eligible for AC-connected offshore wind turbine placement."
luisa,--,"Any subset of the `LUISA Base Map codes in Annex 1 <https://publications.jrc.ec.europa.eu/repository/bitstream/JRC124621/technical_report_luisa_basemap_2018_v7_final.pdf>`_","Specifies areas according to the LUISA Base Map codes which are generally eligible for DC-connected offshore wind turbine placement."
natura,bool,"{true, false}","Switch to exclude `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas. Area is excluded if ``true``."
ship_threshold,--,float,"Ship density threshold from which areas are excluded."
max_depth,m,float,"Maximum sea water depth at which wind turbines can be build. Maritime areas with deeper waters are excluded in the process of calculating the AC-connected offshore wind potential."
min_shore_distance,m,float,"Minimum distance to the shore below which wind turbines cannot be build."
max_shore_distance,m,float,"Maximum distance to the shore above which wind turbines cannot be build."
potential,--,"One of {'simple', 'conservative'}","Method to compute the maximal installable potential for a node; confer :ref:`renewableprofiles`"
clip_p_max_pu,p.u.,float,"To avoid too small values in the renewables` per-unit availability time series values below this threshold are set to zero."

1 Unit Values Description
7 correction_factor -- float Correction factor for capacity factor time series.
8 excluder_resolution m float Resolution on which to perform geographical elibility analysis.
9 corine -- Any *realistic* subset of the `CORINE Land Cover code list <http://www.eea.europa.eu/data-and-maps/data/corine-land-cover-2006-raster-1/corine-land-cover-classes-and/clc_legend.csv/at_download/file>`_ Specifies areas according to CORINE Land Cover codes which are generally eligible for AC-connected offshore wind turbine placement.
10 luisa -- Any subset of the `LUISA Base Map codes in Annex 1 <https://publications.jrc.ec.europa.eu/repository/bitstream/JRC124621/technical_report_luisa_basemap_2018_v7_final.pdf>`_ Specifies areas according to the LUISA Base Map codes which are generally eligible for DC-connected offshore wind turbine placement.
11 natura bool {true, false} Switch to exclude `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas. Area is excluded if ``true``.
12 ship_threshold -- float Ship density threshold from which areas are excluded.
13 max_depth m float Maximum sea water depth at which wind turbines can be build. Maritime areas with deeper waters are excluded in the process of calculating the AC-connected offshore wind potential.
14 min_shore_distance m float Minimum distance to the shore below which wind turbines cannot be build.
15 max_shore_distance m float Maximum distance to the shore above which wind turbines cannot be build.
potential -- One of {'simple', 'conservative'} Method to compute the maximal installable potential for a node; confer :ref:`renewableprofiles`
16 clip_p_max_pu p.u. float To avoid too small values in the renewables` per-unit availability time series values below this threshold are set to zero.

View File

@ -8,8 +8,11 @@ corine,,,
-- grid_codes,--,"Any subset of the `CORINE Land Cover code list <http://www.eea.europa.eu/data-and-maps/data/corine-land-cover-2006-raster-1/corine-land-cover-classes-and/clc_legend.csv/at_download/file>`_","Specifies areas according to CORINE Land Cover codes which are generally eligible for wind turbine placement."
-- distance,m,float,"Distance to keep from areas specified in ``distance_grid_codes``"
-- distance_grid_codes,--,"Any subset of the `CORINE Land Cover code list <http://www.eea.europa.eu/data-and-maps/data/corine-land-cover-2006-raster-1/corine-land-cover-classes-and/clc_legend.csv/at_download/file>`_","Specifies areas according to CORINE Land Cover codes to which wind turbines must maintain a distance specified in the setting ``distance``."
luisa,,,
-- grid_codes,--,"Any subset of the `LUISA Base Map codes in Annex 1 <https://publications.jrc.ec.europa.eu/repository/bitstream/JRC124621/technical_report_luisa_basemap_2018_v7_final.pdf>`_","Specifies areas according to the LUISA Base Map codes which are generally eligible for wind turbine placement."
-- distance,m,float,"Distance to keep from areas specified in ``distance_grid_codes``"
-- distance_grid_codes,--,"Any subset of the `LUISA Base Map codes in Annex 1 <https://publications.jrc.ec.europa.eu/repository/bitstream/JRC124621/technical_report_luisa_basemap_2018_v7_final.pdf>`_","Specifies areas according to the LUISA Base Map codes to which wind turbines must maintain a distance specified in the setting ``distance``."
natura,bool,"{true, false}","Switch to exclude `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas. Area is excluded if ``true``."
potential,--,"One of {'simple', 'conservative'}","Method to compute the maximal installable potential for a node; confer :ref:`renewableprofiles`"
clip_p_max_pu,p.u.,float,"To avoid too small values in the renewables` per-unit availability time series values below this threshold are set to zero."
correction_factor,--,float,"Correction factor for capacity factor time series."
excluder_resolution,m,float,"Resolution on which to perform geographical elibility analysis."

1 Unit Values Description
8 -- grid_codes -- Any subset of the `CORINE Land Cover code list <http://www.eea.europa.eu/data-and-maps/data/corine-land-cover-2006-raster-1/corine-land-cover-classes-and/clc_legend.csv/at_download/file>`_ Specifies areas according to CORINE Land Cover codes which are generally eligible for wind turbine placement.
9 -- distance m float Distance to keep from areas specified in ``distance_grid_codes``
10 -- distance_grid_codes -- Any subset of the `CORINE Land Cover code list <http://www.eea.europa.eu/data-and-maps/data/corine-land-cover-2006-raster-1/corine-land-cover-classes-and/clc_legend.csv/at_download/file>`_ Specifies areas according to CORINE Land Cover codes to which wind turbines must maintain a distance specified in the setting ``distance``.
11 luisa
12 -- grid_codes -- Any subset of the `LUISA Base Map codes in Annex 1 <https://publications.jrc.ec.europa.eu/repository/bitstream/JRC124621/technical_report_luisa_basemap_2018_v7_final.pdf>`_ Specifies areas according to the LUISA Base Map codes which are generally eligible for wind turbine placement.
13 -- distance m float Distance to keep from areas specified in ``distance_grid_codes``
14 -- distance_grid_codes -- Any subset of the `LUISA Base Map codes in Annex 1 <https://publications.jrc.ec.europa.eu/repository/bitstream/JRC124621/technical_report_luisa_basemap_2018_v7_final.pdf>`_ Specifies areas according to the LUISA Base Map codes to which wind turbines must maintain a distance specified in the setting ``distance``.
15 natura bool {true, false} Switch to exclude `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas. Area is excluded if ``true``.
potential -- One of {'simple', 'conservative'} Method to compute the maximal installable potential for a node; confer :ref:`renewableprofiles`
16 clip_p_max_pu p.u. float To avoid too small values in the renewables` per-unit availability time series values below this threshold are set to zero.
17 correction_factor -- float Correction factor for capacity factor time series.
18 excluder_resolution m float Resolution on which to perform geographical elibility analysis.

View File

@ -3,10 +3,10 @@ Trigger, Description, Definition, Status
``nSEG``; e.g. ``4380SEG``,"Apply time series segmentation with `tsam <https://tsam.readthedocs.io/en/latest/index.html>`_ package to ``n`` adjacent snapshots of varying lengths based on capacity factors of varying renewables, hydro inflow and load.", ``prepare_network``: apply_time_segmentation(), 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
``Ep``,Add cost for a carbon-dioxide price configured in ``costs: emission_prices: co2`` to ``marginal_cost`` of generators (other emission types listed in ``network.carriers`` possible as well), ``prepare_network``: `add_emission_prices() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L24>`_ and its `caller <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/prepare_network.py#L158>`__, In active use
``Ept``, Add monthly cost for a carbon-dioxide price based on historical values built by the rule ``build_monthly_prices``, In active use
``Ept``,Add monthly cost for a carbon-dioxide price based on historical values built by the rule ``build_monthly_prices``, In active use,
``CCL``,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``., ``solve_network``, In active use
``EQ``, "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.", ``solve_network``, In active use
``ATK``, "Require each node to be autarkic. Example: ``ATK`` removes all lines and links. ``ATKc`` removes all cross-border lines and links.", ``prepare_network``, In active use
``EQ``,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., ``solve_network``, In active use
``ATK``,Require each node to be autarkic. Example: ``ATK`` removes all lines and links. ``ATKc`` removes all cross-border lines and links., ``prepare_network``, In active use
``BAU``,Add a per-``carrier`` minimal overall capacity; i.e. at least ``40GW`` of ``OCGT`` in Europe; configured in ``electricity: BAU_mincapacities``, ``solve_network``: `add_opts_constraints() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/solve_network.py#L66>`__, Untested
``SAFE``,Add a capacity reserve margin of a certain fraction above the peak demand to which renewable generators and storage do *not* contribute. Ignores network., ``solve_network`` `add_opts_constraints() <https://github.com/PyPSA/pypsa-eur/blob/6b964540ed39d44079cdabddee8333f486d0cd63/scripts/solve_network.py#L73>`__, Untested
``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

Can't render this file because it has a wrong number of fields in line 6.

View File

@ -62,7 +62,8 @@ tes,--,"{true, false}",Add option for storing thermal energy in large water pits
tes_tau,,,The time constant used to calculate the decay of thermal energy in thermal energy storage (TES): 1- :math:`e^{-1/24τ}`.
-- decentral,days,float,The time constant in decentralized thermal energy storage (TES)
-- central,days,float,The time constant in centralized thermal energy storage (TES)
boilers,--,"{true, false}",Add option for transforming electricity into heat using resistive heater
boilers,--,"{true, false}",Add option for transforming gas into heat using gas boilers
resistive_heaters,--,"{true, false}",Add option for transforming electricity into heat using resistive heaters (independently from gas boilers)
oil_boilers,--,"{true, false}",Add option for transforming oil into heat using boilers
biomass_boiler,--,"{true, false}",Add option for transforming biomass into heat using boilers
chp,--,"{true, false}",Add option for using Combined Heat and Power (CHP)
@ -71,7 +72,6 @@ solar_thermal,--,"{true, false}",Add option for using solar thermal to generate
solar_cf_correction,--,float,The correction factor for the value provided by the solar thermal profile calculations
marginal_cost_storage,currency/MWh ,float,The marginal cost of discharging batteries in distributed grids
methanation,--,"{true, false}",Add option for transforming hydrogen and CO2 into methane using methanation.
helmeth,--,"{true, false}",Add option for transforming power into gas using HELMETH (Integrated High-Temperature ELectrolysis and METHanation for Effective Power to Gas Conversion)
coal_cc,--,"{true, false}",Add option for coal CHPs with carbon capture
dac,--,"{true, false}",Add option for Direct Air Capture (DAC)
co2_vent,--,"{true, false}",Add option for vent out CO2 from storages to the atmosphere.
@ -80,6 +80,8 @@ hydrogen_fuel_cell,--,"{true, false}",Add option to include hydrogen fuel cell f
hydrogen_turbine,--,"{true, false}",Add option to include hydrogen turbine for re-electrification. Assuming OCGT technology costs
SMR,--,"{true, false}",Add option for transforming natural gas into hydrogen and CO2 using Steam Methane Reforming (SMR)
SMR CC,--,"{true, false}",Add option for transforming natural gas into hydrogen and CO2 using Steam Methane Reforming (SMR) and Carbon Capture (CC)
regional_methanol_demand,--,"{true, false}",Spatially resolve methanol demand. Set to true if regional CO2 constraints needed.
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
@ -89,9 +91,11 @@ regional_co2 _sequestration_potential,,,
-- years_of_storage,years,float,The years until potential exhausted at optimised annual rate
co2_sequestration_potential,MtCO2/a,float,The potential of sequestering CO2 in Europe per year
co2_sequestration_cost,currency/tCO2,float,The cost of sequestering a ton of CO2
co2_sequestration_lifetime,years,int,The lifetime of a CO2 sequestration site
co2_spatial,--,"{true, false}","Add option to spatially resolve carrier representing stored carbon dioxide. This allows for more detailed modelling of CCUTS, e.g. regarding the capturing of industrial process emissions, usage as feedstock for electrofuels, transport of carbon dioxide, and geological sequestration sites."
,,,
co2network,--,"{true, false}",Add option for planning a new carbon dioxide transmission network
co2_network_cost_factor,p.u.,float,The cost factor for the capital cost of the carbon dioxide transmission network
,,,
cc_fraction,--,float,The default fraction of CO2 captured with post-combustion capture
hydrogen_underground _storage,--,"{true, false}",Add options for storing hydrogen underground. Storage potential depends regionally.
@ -108,6 +112,11 @@ electricity_distribution _grid,--,"{true, false}",Add a simplified representatio
electricity_distribution _grid_cost_factor,,,Multiplies the investment cost of the electricity distribution grid
,,,
electricity_grid _connection,--,"{true, false}",Add the cost of electricity grid connection for onshore wind and solar
transmission_efficiency,,,Section to specify transmission losses or compression energy demands of bidirectional links. Splits them into two capacity-linked unidirectional links.
-- {carrier},--,str,The carrier of the link.
-- -- efficiency_static,p.u.,float,Length-independent transmission efficiency.
-- -- efficiency_per_1000km,p.u. per 1000 km,float,Length-dependent transmission efficiency ($\eta^{\text{length}}$)
-- -- compression_per_1000km,p.u. per 1000 km,float,Length-dependent electricity demand for compression ($\eta \cdot \text{length}$) implemented as multi-link to local electricity bus.
H2_network,--,"{true, false}",Add option for new hydrogen pipelines
gas_network,--,"{true, false}","Add existing natural gas infrastructure, incl. LNG terminals, production and entry-points. The existing gas network is added with a lossless transport model. A length-weighted `k-edge augmentation algorithm <https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.connectivity.edge_augmentation.k_edge_augmentation.html#networkx.algorithms.connectivity.edge_augmentation.k_edge_augmentation>`_ can be run to add new candidate gas pipelines such that all regions of the model can be connected to the gas network. When activated, all the gas demands are regionally disaggregated as well."
H2_retrofit,--,"{true, false}",Add option for retrofiting existing pipelines to transport hydrogen.
@ -118,6 +127,14 @@ gas_distribution_grid _cost_factor,,,Multiplier for the investment cost of the g
,,,
biomass_spatial,--,"{true, false}",Add option for resolving biomass demand regionally
biomass_transport,--,"{true, false}",Add option for transporting solid biomass between nodes
biogas_upgrading_cc,--,"{true, false}",Add option to capture CO2 from biomass upgrading
conventional_generation,,,Add a more detailed description of conventional carriers. Any power generation requires the consumption of fuel from nodes representing that fuel.
biomass_to_liquid,--,"{true, false}",Add option for transforming solid biomass into liquid fuel with the same properties as oil
biosng,--,"{true, false}",Add option for transforming solid biomass into synthesis gas with the same properties as natural gas
limit_max_growth,,,
-- enable,--,"{true, false}",Add option to limit the maximum growth of a carrier
-- 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,
-- -- {carrier},p.u.,float,The historic maximum relative growth of a carrier

Can't render this file because it has a wrong number of fields in line 139.

View File

@ -1,4 +1,6 @@
,Unit,Values,Description
start,--,"str or datetime-like; e.g. YYYY-MM-DD","Left bound of date range"
end,--,"str or datetime-like; e.g. YYYY-MM-DD","Right bound of date range"
start,--,str or datetime-like; e.g. YYYY-MM-DD,Left bound of date range
end,--,str or datetime-like; e.g. YYYY-MM-DD,Right bound of date range
inclusive,--,"One of {'neither', 'both', left, right}","Make the time interval closed to the ``left``, ``right``, or both sides ``both`` or neither side ``None``."
resolution ,--,"{false,``nH``; i.e. ``2H``-``6H``}",Resample the time-resolution by averaging over every ``n`` snapshots
segmentation,--,"{false,``n``; e.g. ``4380``}","Apply time series segmentation with `tsam <https://tsam.readthedocs.io/en/latest/index.html>`_ package to ``n`` adjacent snapshots of varying lengths based on capacity factors of varying renewables, hydro inflow and load."

1 Unit Values Description
2 start -- str or datetime-like; e.g. YYYY-MM-DD Left bound of date range
3 end -- str or datetime-like; e.g. YYYY-MM-DD Right bound of date range
4 inclusive -- One of {'neither', 'both', ‘left’, ‘right’} Make the time interval closed to the ``left``, ``right``, or both sides ``both`` or neither side ``None``.
5 resolution -- {false,``nH``; i.e. ``2H``-``6H``} Resample the time-resolution by averaging over every ``n`` snapshots
6 segmentation -- {false,``n``; e.g. ``4380``} Apply time series segmentation with `tsam <https://tsam.readthedocs.io/en/latest/index.html>`_ package to ``n`` adjacent snapshots of varying lengths based on capacity factors of varying renewables, hydro inflow and load.

View File

@ -9,7 +9,7 @@ resource,,,
capacity_per_sqkm,:math:`MW/km^2`,float,"Allowable density of solar panel placement."
correction_factor,--,float,"A correction factor for the capacity factor (availability) time series."
corine,--,"Any subset of the `CORINE Land Cover code list <http://www.eea.europa.eu/data-and-maps/data/corine-land-cover-2006-raster-1/corine-land-cover-classes-and/clc_legend.csv/at_download/file>`_","Specifies areas according to CORINE Land Cover codes which are generally eligible for solar panel placement."
luisa,--,"Any subset of the `LUISA Base Map codes in Annex 1 <https://publications.jrc.ec.europa.eu/repository/bitstream/JRC124621/technical_report_luisa_basemap_2018_v7_final.pdf>`_","Specifies areas according to the LUISA Base Map codes which are generally eligible for solar panel placement."
natura,bool,"{true, false}","Switch to exclude `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas. Area is excluded if ``true``."
potential,--,"One of {'simple', 'conservative'}","Method to compute the maximal installable potential for a node; confer :ref:`renewableprofiles`"
clip_p_max_pu,p.u.,float,"To avoid too small values in the renewables` per-unit availability time series values below this threshold are set to zero."
excluder_resolution,m,float,"Resolution on which to perform geographical elibility analysis."

1 Unit Values Description
9 capacity_per_sqkm :math:`MW/km^2` float Allowable density of solar panel placement.
10 correction_factor -- float A correction factor for the capacity factor (availability) time series.
11 corine -- Any subset of the `CORINE Land Cover code list <http://www.eea.europa.eu/data-and-maps/data/corine-land-cover-2006-raster-1/corine-land-cover-classes-and/clc_legend.csv/at_download/file>`_ Specifies areas according to CORINE Land Cover codes which are generally eligible for solar panel placement.
12 luisa -- Any subset of the `LUISA Base Map codes in Annex 1 <https://publications.jrc.ec.europa.eu/repository/bitstream/JRC124621/technical_report_luisa_basemap_2018_v7_final.pdf>`_ Specifies areas according to the LUISA Base Map codes which are generally eligible for solar panel placement.
13 natura bool {true, false} Switch to exclude `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas. Area is excluded if ``true``.
potential -- One of {'simple', 'conservative'} Method to compute the maximal installable potential for a node; confer :ref:`renewableprofiles`
14 clip_p_max_pu p.u. float To avoid too small values in the renewables` per-unit availability time series values below this threshold are set to zero.
15 excluder_resolution m float Resolution on which to perform geographical elibility analysis.

View File

@ -6,12 +6,18 @@ options,,,
-- 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."
-- 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.
-- track_iterations,bool,"{'true','false'}",Flag whether to store the intermediate branch capacities and objective function values are recorded for each iteration in ``network.lines['s_nom_opt_X']`` (where ``X`` labels the iteration)
-- min_iterations,--,int,Minimum number of solving iterations in between which resistance and reactence (``x/r``) are updated for branches according to ``s_nom_opt`` of the previous run.
-- max_iterations,--,int,Maximum number of solving iterations in between which resistance and reactence (``x/r``) are updated for branches according to ``s_nom_opt`` of the previous run.
-- 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.
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.
-- options,--,Key listed under ``solver_options``.,Link to specific parameter settings.

1 Unit Values Description
6 -- skip_iterations bool {'true','false'} Skip iterating, do not update impedances of branches. Defaults to true.
7 -- 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.
8 -- seed -- int Random seed for increased deterministic behaviour.
9 -- 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.
10 -- track_iterations bool {'true','false'} Flag whether to store the intermediate branch capacities and objective function values are recorded for each iteration in ``network.lines['s_nom_opt_X']`` (where ``X`` labels the iteration)
11 -- min_iterations -- int Minimum number of solving iterations in between which resistance and reactence (``x/r``) are updated for branches according to ``s_nom_opt`` of the previous run.
12 -- max_iterations -- int Maximum number of solving iterations in between which resistance and reactence (``x/r``) are updated for branches according to ``s_nom_opt`` of the previous run.
13 -- transmission_losses int [0-9] Add piecewise linear approximation of transmission losses based on n tangents. Defaults to 0, which means losses are ignored.
14 -- linearized_unit_commitment bool {'true','false'} Whether to optimise using the linearized unit commitment formulation.
15 -- horizon -- int Number of snapshots to consider in each iteration. Defaults to 100.
16 constraints
17 -- 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``.
18 -- 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.
19 -- 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``
20 -- 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.
21 solver
22 -- 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.
23 -- options -- Key listed under ``solver_options``. Link to specific parameter settings.

View File

@ -399,7 +399,7 @@ overwrite the existing values.
.. literalinclude:: ../config/config.default.yaml
:language: yaml
:start-after: type:
:start-after: # docs-load
:end-before: # docs
.. csv-table::

View File

@ -41,7 +41,7 @@ Perfect foresight scenarios
.. warning::
Perfect foresight is currently implemented as a first test version.
Perfect foresight is currently implemented as an experimental test version.
For running perfect foresight scenarios, you can adjust the
``config/config.perfect.yaml``:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 789 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 227 KiB

View File

@ -35,6 +35,8 @@ PyPSA-Eur: A Sector-Coupled Open Optimisation Model of the European Energy Syste
:target: https://stackoverflow.com/questions/tagged/pypsa
:alt: Stackoverflow
|
PyPSA-Eur is an open model dataset of the European energy system at the
transmission network level that covers the full ENTSO-E area. It covers demand
and supply for all energy sectors. From version v0.8.0, PyPSA-Eur includes all
@ -116,7 +118,7 @@ of the individual parts.
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.ensys.tu-berlin.de>`_ at 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
@ -185,7 +187,7 @@ For sector-coupling studies: ::
pages = "1--25"
year = "2023",
eprint = "2207.05816",
doi = "10.1016/j.joule.2022.04.016",
doi = "10.1016/j.joule.2023.06.016",
}
For sector-coupling studies with pathway optimisation: ::
@ -209,24 +211,6 @@ If you want to cite a specific PyPSA-Eur version, each release of PyPSA-Eur is s
:target: https://doi.org/10.5281/zenodo.3520874
Pre-Built Networks as a Dataset
===============================
There are pre-built networks available as a dataset on Zenodo as well for every release of PyPSA-Eur.
.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.3601881.svg
:target: https://doi.org/10.5281/zenodo.3601881
The included ``.nc`` files are PyPSA network files which can be imported with PyPSA via:
.. code:: python
import pypsa
filename = "elec_s_1024_ec.nc" # example
n = pypsa.Network(filename)
Operating Systems
=================

View File

@ -89,8 +89,8 @@ Folder Structure
- ``results``: Stores the solved PyPSA network data, summary files and plots.
- ``logs``: Stores log files.
- ``benchmarks``: Stores ``snakemake`` benchmarks.
- ``test``: Includes the test configuration files used for continuous integration.
- ``doc``: Includes the documentation of PyPSA-Eur.
- ``graphics``: Includes some graphics for the documentation of PyPSA-Eur.
System Requirements
===================

View File

@ -94,6 +94,13 @@ Rule ``build_electricity_demand``
.. automodule:: build_electricity_demand
.. _monthlyprices:
Rule ``build_monthly_prices``
=============================
.. automodule:: build_monthly_prices
.. _ship:
Rule ``build_ship_raster``
@ -102,6 +109,12 @@ Rule ``build_ship_raster``
.. automodule:: build_ship_raster
.. _availabilitymatrixmdua:
Rule ``determine_availability_matrix_MD_UA``
============================================
.. automodule:: determine_availability_matrix_MD_UA
.. _renewableprofiles:

View File

@ -10,37 +10,235 @@ Release Notes
Upcoming Release
================
* Add floating wind to PyPSA-Eur
* Updated Global Energy Monitor LNG terminal data to March 2023 version.
* For industry distribution, use EPRTR as fallback if ETS data is not available.
* The minimum capacity for renewable generators when using the myopic option has been fixed.
* Add option for heat vents in district heating (``sector:
central_heat_vent:``). The combination of must-run conditions for some
power-to-X processes, waste heat usage enabled and decreasing heating demand,
can lead to infeasibilities in pathway optimisation for some investment
periods since larger Fischer-Tropsch capacities are needed in early years but
the waste heat exceeds the heat demand in later investment periods.
(https://github.com/PyPSA/pypsa-eur/pull/791).
* Files downloaded from zenodo are now write-protected to prevent accidental re-download.
* Allow possibility to go from copperplated to regionally resolved methanol and
oil demand with switches ``sector: regional_methanol_demand: true`` and
``sector: regional_oil_demand: true``. This allows nodal/regional CO2
constraints to be applied (https://github.com/PyPSA/pypsa-eur/pull/827).
* Files extracted from sector-coupled data bundle have been moved from ``data/`` to ``data/sector-bundle``.
* Allow retrofitting of existing gas boilers to hydrogen boilers in pathway
optimisation.
* New feature multi-decade optimisation with perfect foresight.
* Add option to add time-varying CO2 emission prices (electricity-only, ``costs:
emission_prices: co2_monthly_prices: true``). This is linked to the new
``{opts}`` wildcard option ``Ept``.
* Network clustering can now consider efficiency classes when aggregating
carriers. The option ``clustering: consider_efficiency_classes:`` aggregates
each carriers into the top 10-quantile (high), the bottom 90-quantile (low),
and everything in between (medium).
* Added option ``conventional: dynamic_fuel_price:`` to consider the monthly
fluctuating fuel prices for conventional generators. Refer to the CSV file
``data/validation/monthly_fuel_price.csv``.
* For hydro-electricity, add switches ``flatten_dispatch`` to consider an upper
limit for the hydro dispatch. The limit is given by the average capacity
factor plus the buffer given in ``flatten_dispatch_buffer``.
* Extend options for waste heat usage from Haber-Bosch, methanolisation and
methanation (https://github.com/PyPSA/pypsa-eur/pull/834).
* Add new ``sector_opts`` wildcard option "nowasteheat" to disable all waste
heat usage (https://github.com/PyPSA/pypsa-eur/pull/834).
* Add new rule ``retrieve_irena`` to automatically retrieve up-to-date values
for existing renewables capacities (https://github.com/PyPSA/pypsa-eur/pull/756).
* Print Irreducible Infeasible Subset (IIS) if model is infeasible. Only for
solvers with IIS support (https://github.com/PyPSA/pypsa-eur/pull/841).
* More wildcard options now have a corresponding config entry. If the wildcard
is given, then its value is used. If the wildcard is not given but the options
in config are enabled, then the value from config is used. If neither is
given, the options are skipped (https://github.com/PyPSA/pypsa-eur/pull/827).
* Validate downloads from Zenodo using MD5 checksums. This identifies corrupted
or incomplete downloads (https://github.com/PyPSA/pypsa-eur/pull/821).
* Add rule ``sync`` to synchronise with a remote machine using the ``rsync``
library. Configuration settings are found under ``remote:``.
**Breaking Changes**
* Remove all negative loads on the ``co2 atmosphere`` bus representing emissions
for e.g. fixed fossil demands for transport oil. Instead these are handled
more transparently with a fixed transport oil demand and a link taking care of
the emissions to the ``co2 atmosphere`` bus. This is also a preparation for
endogenous transport optimisation, where demand will be subject to
optimisation (e.g. fuel switching in the transport sector)
(https://github.com/PyPSA/pypsa-eur/pull/827).
* Process emissions from steam crackers (i.e. naphtha processing for HVC) are
now piped from the consumption link to the process emissions bus where the
model can decide about carbon capture. Previously the process emissions for
naphtha were a fixed load (https://github.com/PyPSA/pypsa-eur/pull/827).
* Distinguish between stored and sequestered CO2. Stored CO2 is stored
overground in tanks and can be used for CCU (e.g. methanolisation).
Sequestered CO2 is stored underground and can no longer be used for CCU. This
distinction is made because storage in tanks is more expensive than
underground storage. The link that connects stored and sequestered CO2 is
unidirectional (https://github.com/PyPSA/pypsa-eur/pull/844).
* Files extracted from sector-coupled data bundle have been moved from ``data/``
to ``data/sector-bundle``.
* Split configuration to enable SMR and SMR CC (``sector: smr:`` and ``sector:
smr_cc:``) (https://github.com/PyPSA/pypsa-eur/pull/757).
* Add separate option to add resistive heaters to the technology choices
(``sector: resistive_heaters:``). Previously they were always added when
boilers were added (https://github.com/PyPSA/pypsa-eur/pull/808).
* Remove HELMETH option (``sector: helmeth:``).
* Remove "conservative" renewable potentials estimation option
(https://github.com/PyPSA/pypsa-eur/pull/838).
* With this release we stop posting updates to the network pre-builts.
**Changes**
* Updated Global Energy Monitor LNG terminal data to March 2023 version
(https://github.com/PyPSA/pypsa-eur/pull/707).
* For industry distribution, use EPRTR as fallback if ETS data is not available
(https://github.com/PyPSA/pypsa-eur/pull/721).
* It is now possible to specify years for biomass potentials which do not exist
in the JRC-ENSPRESO database, e.g. 2037. These are linearly interpolated.
in the JRC-ENSPRESO database, e.g. 2037. These are linearly interpolated
(https://github.com/PyPSA/pypsa-eur/pull/744).
* In pathway mode, the biomass potential is linked to the investment year.
* In pathway mode, the biomass potential is linked to the investment year
(https://github.com/PyPSA/pypsa-eur/pull/744).
* Rule ``purge`` now initiates a dialog to confirm if purge is desired.
* Increase allowed deployment density of solar to 5.1 MW/sqkm by default.
* Rule ``retrieve_irena`` get updated values for renewables capacities.
* Default to full electrification of land transport by 2050.
* Split configuration to enable SMR and SMR CC.
* Provide exogenous transition settings in 5-year steps.
* The ``mock_snakemake`` function can now be used with a Snakefile from a different directory using the new ``root_dir`` argument.
* Default to approximating transmission losses in HVAC lines
(``transmission_losses: 2``).
* Use electrolysis waste heat by default.
* Set minimum part loads for PtX processes to 30% for methanolisation and
methanation, and to 70% for Fischer-Tropsch synthesis.
* Add VOM as marginal cost to PtX processes
(https://github.com/PyPSA/pypsa-eur/pull/830).
* Add pelletizing costs for biomass boilers (https://github.com/PyPSA/pypsa-eur/pull/833).
* Update default offshore wind turbine model to "NREL Reference 2020 ATB 5.5 MW"
(https://github.com/PyPSA/pypsa-eur/pull/832).
* Switch to using hydrogen and electricity inputs for Haber-Bosch from
https://github.com/PyPSA/technology-data (https://github.com/PyPSA/pypsa-eur/pull/831).
* The configuration setting for country focus weights when clustering the
network has been moved from ``focus_weights:`` to ``clustering:
focus_weights:``. Backwards compatibility to old config files is maintained
(https://github.com/PyPSA/pypsa-eur/pull/794).
* The ``mock_snakemake`` function can now be used with a Snakefile from a
different directory using the new ``root_dir`` argument
(https://github.com/PyPSA/pypsa-eur/pull/771).
* Rule ``purge`` now initiates a dialog to confirm if purge is desired
(https://github.com/PyPSA/pypsa-eur/pull/745).
* Files downloaded from zenodo are now write-protected to prevent accidental
re-download (https://github.com/PyPSA/pypsa-eur/pull/730).
* Performance improvements for rule ``build_ship_raster``
(https://github.com/PyPSA/pypsa-eur/pull/845).
* Improve time logging in :mod:`build_renewable_profiles`
(https://github.com/PyPSA/pypsa-eur/pull/837).
* In myopic pathway optimisation, disable power grid expansion if line volume
already hit (https://github.com/PyPSA/pypsa-eur/pull/840).
* JRC-ENSPRESO data is now downloaded from a Zenodo mirror because the link was
unreliable (https://github.com/PyPSA/pypsa-eur/pull/801).
* Add focus weights option for clustering to documentation
(https://github.com/PyPSA/pypsa-eur/pull/781).
* Add proxy for biomass transport costs if no explicit biomass transport network
is considered (https://github.com/PyPSA/pypsa-eur/pull/711).
**Bugs and Compatibility**
* A bug preventing custom powerplants specified in ``data/custom_powerplants.csv`` was fixed. (https://github.com/PyPSA/pypsa-eur/pull/732)
* The minimum PyPSA version is now 0.26.1.
* Update to ``tsam>=0.2.3`` for performance improvents in temporal clustering.
* Pin ``snakemake`` version to below 8.0.0, as the new version is not yet
supported. The next release will switch to the requirement ``snakemake>=8``.
* Bugfix: Add coke and coal demand for integrated steelworks
(https://github.com/PyPSA/pypsa-eur/pull/718).
* Bugfix: Make :mod:`build_renewable_profiles` consider subsets of cutout time
scope (https://github.com/PyPSA/pypsa-eur/pull/709).
* Bugfix: In :mod:`simplify network`, remove 'underground' column to avoid
consense error (https://github.com/PyPSA/pypsa-eur/pull/714).
* Bugfix: Fix in :mod:`add_existing_baseyear` to account for the case when there
is no rural heating demand for some nodes in network
(https://github.com/PyPSA/pypsa-eur/pull/706).
* Bugfix: The unit of the capital cost of Haber-Bosch plants was corrected
(https://github.com/PyPSA/pypsa-eur/pull/829).
* The minimum capacity for renewable generators when using the myopic option has
been fixed (https://github.com/PyPSA/pypsa-eur/pull/728).
* Compatibility for running with single node and single country
(https://github.com/PyPSA/pypsa-eur/pull/839).
* A bug preventing the addition of custom powerplants specified in
``data/custom_powerplants.csv`` was fixed.
(https://github.com/PyPSA/pypsa-eur/pull/732)
* Fix nodal fraction in :mod:`add_existing_year` when using distributed
generators (https://github.com/PyPSA/pypsa-eur/pull/798).
* Bugfix: District heating without progress caused division by zero
(https://github.com/PyPSA/pypsa-eur/pull/796).
* Bugfix: Drop duplicates in :mod:`build_industrial_distribution_keys`, which
can occur through the geopandas ``.sjoin()`` function if a point is located on
a border (https://github.com/PyPSA/pypsa-eur/pull/726).
* For network clustering fall back to ``ipopt`` when ``highs`` is designated
solver (https://github.com/PyPSA/pypsa-eur/pull/795).
* Fix typo in buses definition for oil boilers in ``add_industry`` in
:mod:`prepare_sector_network` (https://github.com/PyPSA/pypsa-eur/pull/812).
* Resolve code issues for endogenous building retrofitting. Select correct
sector names, address deprecations, distinguish between district heating,
decentral heating in urban areas or rural areas for floor area calculations
(https://github.com/PyPSA/pypsa-eur/pull/808).
* Addressed various deprecations.
PyPSA-Eur 0.8.1 (27th July 2023)
@ -166,6 +364,8 @@ PyPSA-Eur 0.8.1 (27th July 2023)
(https://github.com/PyPSA/pypsa-eur/pull/672)
* Addressed deprecation warnings for ``pandas=2.0``. ``pandas=2.0`` is now minimum requirement.
PyPSA-Eur 0.8.0 (18th March 2023)
=================================
@ -1427,8 +1627,4 @@ Release Process
* Make a `GitHub release <https://github.com/PyPSA/pypsa-eur-sec/releases>`_, which automatically triggers archiving to the `zenodo code repository <https://doi.org/10.5281/zenodo.3520874>`_ with `MIT license <https://opensource.org/licenses/MIT>`_.
* Create pre-built networks for ``config.default.yaml`` by running ``snakemake -call prepare_sector_networks``.
* Upload pre-built networks to `zenodo data repository <https://doi.org/10.5281/zenodo.3601881>`_ with `CC BY 4.0 <https://creativecommons.org/licenses/by/4.0/>`_ license.
* Send announcement on the `PyPSA mailing list <https://groups.google.com/forum/#!forum/pypsa>`_.

View File

@ -22,11 +22,11 @@ Rule ``retrieve_databundle``
Rule ``retrieve_cutout``
============================
.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.3517949.svg
:target: https://doi.org/10.5281/zenodo.3517949
.. 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.3517949>`__ through the rule ``retrieve_cutout``.
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::
@ -91,7 +91,7 @@ None.
**Outputs**
- ``data/load_raw.csv``
- ``resources/load_raw.csv``
Rule ``retrieve_cost_data``

View File

@ -45,7 +45,7 @@ Here are some examples of how spatial resolution is set for different sectors in
• 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>`_.
Liquid hydrocarbons: Modeled as a single node for Europe, since transport costs for liquids are low and no bottlenecks are expected.
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**

View File

@ -25,7 +25,7 @@ full model, which allows the user to explore most of its functionalities on a
local machine. The tutorial will cover examples on how to configure and
customise the PyPSA-Eur model and run the ``snakemake`` workflow step by step
from network creation to the solved network. The configuration for the tutorial
is located at ``test/config.electricity.yaml``. It includes parts deviating from
is located at ``config/test/config.electricity.yaml``. It includes parts deviating from
the default config file ``config/config.default.yaml``. To run the tutorial with this
configuration, execute
@ -96,7 +96,7 @@ open-source solver GLPK.
:start-at: solver:
:end-before: plotting:
Note, that ``test/config.electricity.yaml`` only includes changes relative to
Note, that ``config/test/config.electricity.yaml`` only includes changes relative to
the default configuration. There are many more configuration options, which are
documented at :ref:`config`.

View File

@ -1,10 +1,11 @@
# SPDX-FileCopyrightText: : 2017-2023 The PyPSA-Eur Authors
# SPDX-FileCopyrightText: : 2017-2024 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: CC0-1.0
name: pypsa-eur
channels:
- bioconda
- gurobi
- http://conda.anaconda.org/gurobi
- conda-forge
- defaults
@ -12,94 +13,96 @@ dependencies:
- _libgcc_mutex=0.1
- _openmp_mutex=4.5
- affine=2.4.0
- alsa-lib=1.2.9
- alsa-lib=1.2.10
- ampl-mp=3.1.0
- amply=0.1.6
- anyio=3.7.1
- anyio=4.2.0
- appdirs=1.4.4
- argon2-cffi=21.3.0
- argon2-cffi=23.1.0
- argon2-cffi-bindings=21.2.0
- asttokens=2.2.1
- async-lru=2.0.3
- arrow=1.3.0
- asttokens=2.4.1
- async-lru=2.0.4
- atk-1.0=2.38.0
- atlite=0.2.11
- atlite=0.2.12
- attr=2.5.1
- attrs=23.1.0
- aws-c-auth=0.7.0
- aws-c-cal=0.6.0
- aws-c-common=0.8.23
- attrs=23.2.0
- aws-c-auth=0.7.8
- aws-c-cal=0.6.9
- aws-c-common=0.9.10
- aws-c-compression=0.2.17
- aws-c-event-stream=0.3.1
- aws-c-http=0.7.11
- aws-c-io=0.13.28
- aws-c-mqtt=0.8.14
- aws-c-s3=0.3.13
- aws-c-sdkutils=0.1.11
- aws-checksums=0.1.16
- aws-crt-cpp=0.20.3
- aws-sdk-cpp=1.10.57
- babel=2.12.1
- backcall=0.2.0
- backports=1.0
- backports.functools_lru_cache=1.6.5
- aws-c-event-stream=0.3.2
- aws-c-http=0.7.15
- aws-c-io=0.13.36
- aws-c-mqtt=0.10.0
- aws-c-s3=0.4.7
- aws-c-sdkutils=0.1.13
- aws-checksums=0.1.17
- aws-crt-cpp=0.25.1
- aws-sdk-cpp=1.11.210
- babel=2.14.0
- beautifulsoup4=4.12.2
- bleach=6.0.0
- blosc=1.21.4
- bokeh=3.2.1
- boost-cpp=1.78.0
- bleach=6.1.0
- blosc=1.21.5
- bokeh=3.3.2
- bottleneck=1.3.7
- branca=0.6.0
- brotli=1.0.9
- brotli-bin=1.0.9
- brotli-python=1.0.9
- branca=0.7.0
- brotli=1.1.0
- brotli-bin=1.1.0
- brotli-python=1.1.0
- bzip2=1.0.8
- c-ares=1.19.1
- c-blosc2=2.10.0
- ca-certificates=2023.7.22
- cairo=1.16.0
- cartopy=0.21.1
- c-ares=1.24.0
- c-blosc2=2.12.0
- ca-certificates=2023.11.17
- cached-property=1.5.2
- cached_property=1.5.2
- cairo=1.18.0
- cartopy=0.22.0
- cdsapi=0.6.1
- certifi=2023.7.22
- cffi=1.15.1
- cfitsio=4.2.0
- cftime=1.6.2
- charset-normalizer=3.2.0
- click=8.1.6
- certifi=2023.11.17
- cffi=1.16.0
- cfitsio=4.3.1
- cftime=1.6.3
- charset-normalizer=3.3.2
- click=8.1.7
- click-plugins=1.1.1
- cligj=0.7.2
- cloudpickle=2.2.1
- cloudpickle=3.0.0
- 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
- coincbc=2.10.10
- colorama=0.4.6
- comm=0.1.3
- comm=0.1.4
- configargparse=1.7
- connection_pool=0.0.3
- contourpy=1.1.0
- country_converter=1.0.0
- curl=8.2.0
- cycler=0.11.0
- contourpy=1.2.0
- country_converter=1.2
- cycler=0.12.1
- cytoolz=0.12.2
- dask=2023.7.1
- dask-core=2023.7.1
- dask=2023.12.1
- dask-core=2023.12.1
- datrie=0.8.2
- dbus=1.13.6
- debugpy=1.6.7
- debugpy=1.8.0
- decorator=5.1.1
- defusedxml=0.7.1
- deprecation=2.1.0
- descartes=1.1.0
- distributed=2023.7.1
- distributed=2023.12.1
- distro=1.8.0
- docutils=0.20.1
- dpath=2.1.6
- entrypoints=0.4
- entsoe-py=0.5.10
- entsoe-py=0.6.1
- et_xmlfile=1.1.0
- exceptiongroup=1.1.2
- executing=1.2.0
- exceptiongroup=1.2.0
- executing=2.0.1
- expat=2.5.0
- filelock=3.12.2
- fiona=1.9.4
- flit-core=3.9.0
- folium=0.14.0
- fiona=1.9.5
- folium=0.15.1
- font-ttf-dejavu-sans-mono=2.37
- font-ttf-inconsolata=3.000
- font-ttf-source-code-pro=2.038
@ -107,165 +110,184 @@ dependencies:
- fontconfig=2.14.2
- fonts-conda-ecosystem=1
- fonts-conda-forge=1
- fonttools=4.41.1
- fonttools=4.47.0
- fqdn=1.5.1
- freetype=2.12.1
- freexl=1.0.6
- freexl=2.0.0
- fribidi=1.0.10
- fsspec=2023.6.0
- gdal=3.7.0
- fsspec=2023.12.2
- gdal=3.7.3
- gdk-pixbuf=2.42.10
- geographiclib=1.52
- geojson-rewind=1.0.2
- geopandas=0.13.2
- geopandas-base=0.13.2
- geopy=2.3.0
- geos=3.11.2
- geojson-rewind=1.1.0
- geopandas=0.14.1
- geopandas-base=0.14.1
- geopy=2.4.1
- geos=3.12.1
- geotiff=1.7.1
- gettext=0.21.1
- gflags=2.2.2
- giflib=5.2.1
- gitdb=4.0.10
- gitpython=3.1.32
- glib=2.76.4
- glib-tools=2.76.4
- gitdb=4.0.11
- gitpython=3.1.40
- glib=2.78.3
- glib-tools=2.78.3
- glog=0.6.0
- gmp=6.2.1
- glpk=5.0
- gmp=6.3.0
- graphite2=1.3.13
- graphviz=8.1.0
- gst-plugins-base=1.22.5
- gstreamer=1.22.5
- graphviz=9.0.0
- gst-plugins-base=1.22.8
- gstreamer=1.22.8
- gtk2=2.24.33
- gts=0.7.6
- harfbuzz=7.3.0
- gurobi=11.0.0
- harfbuzz=8.3.0
- hdf4=4.2.15
- hdf5=1.14.1
- hdf5=1.14.3
- humanfriendly=10.0
- icu=72.1
- idna=3.4
- importlib-metadata=6.8.0
- importlib_metadata=6.8.0
- importlib_resources=6.0.0
- icu=73.2
- idna=3.6
- importlib-metadata=7.0.1
- importlib_metadata=7.0.1
- importlib_resources=6.1.1
- iniconfig=2.0.0
- ipopt=3.14.12
- ipykernel=6.24.0
- ipython=8.14.0
- ipython_genutils=0.2.0
- ipywidgets=8.0.7
- jedi=0.18.2
- ipopt=3.14.13
- ipykernel=6.28.0
- ipython=8.19.0
- ipywidgets=8.1.1
- isoduration=20.11.0
- jedi=0.19.1
- jinja2=3.1.2
- joblib=1.3.0
- json-c=0.16
- joblib=1.3.2
- json-c=0.17
- json5=0.9.14
- jsonschema=4.18.4
- jsonschema-specifications=2023.7.1
- jsonpointer=2.4
- jsonschema=4.20.0
- jsonschema-specifications=2023.12.1
- jsonschema-with-format-nongpl=4.20.0
- jupyter=1.0.0
- jupyter-lsp=2.2.0
- jupyter_client=8.3.0
- jupyter-lsp=2.2.1
- jupyter_client=8.6.0
- jupyter_console=6.6.3
- jupyter_core=5.3.1
- jupyter_events=0.6.3
- jupyter_server=2.7.0
- jupyter_server_terminals=0.4.4
- jupyterlab=4.0.3
- jupyterlab_pygments=0.2.2
- jupyterlab_server=2.24.0
- jupyterlab_widgets=3.0.8
- kealib=1.5.1
- jupyter_core=5.6.1
- jupyter_events=0.9.0
- jupyter_server=2.12.1
- jupyter_server_terminals=0.5.1
- jupyterlab=4.0.10
- jupyterlab_pygments=0.3.0
- jupyterlab_server=2.25.2
- jupyterlab_widgets=3.0.9
- kealib=1.5.3
- keyutils=1.6.1
- kiwisolver=1.4.4
- krb5=1.21.1
- kiwisolver=1.4.5
- krb5=1.21.2
- lame=3.100
- lcms2=2.15
- lcms2=2.16
- ld_impl_linux-64=2.40
- lerc=4.0.0
- libabseil=20230125.3
- libaec=1.0.6
- libarchive=3.6.2
- libarrow=12.0.1
- libabseil=20230802.1
- libaec=1.1.2
- libarchive=3.7.2
- libarrow=14.0.2
- libarrow-acero=14.0.2
- libarrow-dataset=14.0.2
- libarrow-flight=14.0.2
- libarrow-flight-sql=14.0.2
- libarrow-gandiva=14.0.2
- libarrow-substrait=14.0.2
- libblas=3.9.0
- libbrotlicommon=1.0.9
- libbrotlidec=1.0.9
- libbrotlienc=1.0.9
- libcap=2.67
- libboost-headers=1.84.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
- libcrc32c=1.1.2
- libcups=2.3.3
- libcurl=8.2.0
- libdeflate=1.18
- libcurl=8.5.0
- libdeflate=1.19
- libedit=3.1.20191231
- libev=4.33
- libevent=2.1.12
- libexpat=2.5.0
- libffi=3.4.2
- libflac=1.4.3
- libgcc-ng=13.1.0
- libgcrypt=1.10.1
- libgcc-ng=13.2.0
- libgcrypt=1.10.3
- libgd=2.3.3
- libgdal=3.7.0
- libgfortran-ng=13.1.0
- libgfortran5=13.1.0
- libglib=2.76.4
- libgomp=13.1.0
- libgdal=3.7.3
- libgfortran-ng=13.2.0
- libgfortran5=13.2.0
- libglib=2.78.3
- libgomp=13.2.0
- libgoogle-cloud=2.12.0
- libgpg-error=1.47
- libgrpc=1.56.2
- libgrpc=1.59.3
- libhwloc=2.9.1
- libiconv=1.17
- libjpeg-turbo=2.1.5.1
- libjpeg-turbo=3.0.0
- libkml=1.3.0
- liblapack=3.9.0
- liblapacke=3.9.0
- libllvm15=15.0.7
- libnetcdf=4.9.2
- libnghttp2=1.52.0
- libnsl=2.0.0
- libnghttp2=1.58.0
- libnl=3.9.0
- libnsl=2.0.1
- libnuma=2.0.16
- libogg=1.3.4
- libopenblas=0.3.23
- libopenblas=0.3.25
- libopus=1.3.1
- libparquet=14.0.2
- libpng=1.6.39
- libpq=15.3
- libprotobuf=4.23.3
- librsvg=2.56.1
- libpq=16.1
- libprotobuf=4.24.4
- libre2-11=2023.06.02
- librsvg=2.56.3
- librttopo=1.1.0
- libsndfile=1.2.0
- libsndfile=1.2.2
- libsodium=1.0.18
- libspatialindex=1.9.3
- libspatialite=5.0.1
- libsqlite=3.42.0
- libspatialite=5.1.0
- libspral=2023.08.02
- libsqlite=3.44.2
- libssh2=1.11.0
- libstdcxx-ng=13.1.0
- libsystemd0=253
- libthrift=0.18.1
- libtiff=4.5.1
- libtool=2.4.7
- libstdcxx-ng=13.2.0
- libsystemd0=255
- libthrift=0.19.0
- libtiff=4.6.0
- libutf8proc=2.8.0
- libuuid=2.38.1
- libvorbis=1.3.7
- libwebp=1.3.1
- libwebp-base=1.3.1
- libwebp=1.3.2
- libwebp-base=1.3.2
- libxcb=1.15
- libxkbcommon=1.5.0
- libxml2=2.11.4
- libxcrypt=4.4.36
- libxkbcommon=1.6.0
- libxml2=2.11.6
- libxslt=1.1.37
- libzip=1.9.2
- libzip=1.10.1
- libzlib=1.2.13
- linopy=0.3.2
- locket=1.0.0
- lxml=4.9.3
- lz4=4.3.2
- lz4-c=1.9.4
- lzo=2.10
- mapclassify=2.5.0
- mapclassify=2.6.1
- markupsafe=2.1.3
- matplotlib=3.5.3
- matplotlib-base=3.5.3
- matplotlib=3.8.2
- matplotlib-base=3.8.2
- matplotlib-inline=0.1.6
- memory_profiler=0.61.0
- metis=5.1.1
- mistune=3.0.0
- mpg123=1.31.3
- msgpack-python=1.0.5
- metis=5.1.0
- minizip=4.0.4
- mistune=3.0.2
- mpg123=1.32.3
- msgpack-python=1.0.7
- mumps-include=5.2.1
- mumps-seq=5.2.1
- munch=4.0.0
@ -273,200 +295,202 @@ dependencies:
- mysql-common=8.0.33
- mysql-libs=8.0.33
- nbclient=0.8.0
- nbconvert=7.7.2
- nbconvert-core=7.7.2
- nbconvert-pandoc=7.7.2
- nbformat=5.9.1
- nbconvert=7.14.0
- nbconvert-core=7.14.0
- nbconvert-pandoc=7.14.0
- nbformat=5.9.2
- ncurses=6.4
- nest-asyncio=1.5.6
- netcdf4=1.6.4
- networkx=3.1
- nest-asyncio=1.5.8
- netcdf4=1.6.5
- networkx=3.2.1
- nomkl=1.0
- notebook=7.0.0
- notebook=7.0.6
- notebook-shim=0.2.3
- nspr=4.35
- nss=3.89
- numexpr=2.8.4
- numpy=1.25.1
- openjdk=17.0.3
- nss=3.96
- numexpr=2.8.8
- numpy=1.26.2
- openjdk=21.0.1
- openjpeg=2.5.0
- openpyxl=3.1.2
- openssl=3.1.1
- orc=1.9.0
- overrides=7.3.1
- packaging=23.1
- pandas=2.0.3
- openssl=3.2.0
- orc=1.9.2
- overrides=7.4.0
- packaging=23.2
- pandas=2.1.4
- pandoc=3.1.3
- pandocfilters=1.5.0
- pango=1.50.14
- parso=0.8.3
- partd=1.4.0
- patsy=0.5.3
- pcre2=10.40
- partd=1.4.1
- patsy=0.5.5
- pcre2=10.42
- pexpect=4.8.0
- pickleshare=0.7.5
- pillow=10.0.0
- pip=23.2.1
- pixman=0.40.0
- pillow=10.2.0
- pip=23.3.2
- pixman=0.42.2
- pkgutil-resolve-name=1.3.10
- plac=1.3.5
- platformdirs=3.9.1
- pluggy=1.2.0
- plac=1.4.2
- platformdirs=4.1.0
- pluggy=1.3.0
- ply=3.11
- pooch=1.7.0
- poppler=23.05.0
- poppler=23.12.0
- poppler-data=0.4.12
- postgresql=15.3
- powerplantmatching=0.5.7
- progressbar2=4.2.0
- proj=9.2.1
- prometheus_client=0.17.1
- prompt-toolkit=3.0.39
- prompt_toolkit=3.0.39
- psutil=5.9.5
- postgresql=16.1
- powerplantmatching=0.5.8
- progressbar2=4.3.2
- proj=9.3.0
- prometheus_client=0.19.0
- prompt-toolkit=3.0.42
- prompt_toolkit=3.0.42
- psutil=5.9.7
- pthread-stubs=0.4
- ptyprocess=0.7.0
- pulp=2.7.0
- pulseaudio-client=16.1
- pure_eval=0.2.2
- py-cpuinfo=9.0.0
- pyarrow=12.0.1
- pyarrow=14.0.2
- pyarrow-hotfix=0.6
- pycountry=22.3.5
- pycparser=2.21
- pygments=2.15.1
- pygments=2.17.2
- pyomo=6.6.1
- pyparsing=3.1.0
- pyproj=3.6.0
- pyqt=5.15.7
- pyqt5-sip=12.11.0
- pyparsing=3.1.1
- pyproj=3.6.1
- pypsa=0.26.2
- pyqt=5.15.9
- pyqt5-sip=12.12.2
- pyshp=2.3.1
- pysocks=1.7.1
- pytables=3.8.0
- pytest=7.4.0
- python=3.10.12
- pytables=3.9.2
- pytest=7.4.4
- python=3.11.7
- python-dateutil=2.8.2
- python-fastjsonschema=2.18.0
- python-fastjsonschema=2.19.1
- python-json-logger=2.0.7
- python-tzdata=2023.3
- python-utils=3.7.0
- python_abi=3.10
- pytz=2023.3
- python-tzdata=2023.4
- python-utils=3.8.1
- python_abi=3.11
- pytz=2023.3.post1
- pyxlsb=1.0.10
- pyyaml=6.0
- pyzmq=25.1.0
- pyyaml=6.0.1
- pyzmq=25.1.2
- qt-main=5.15.8
- qtconsole=5.4.3
- qtconsole-base=5.4.3
- qtpy=2.3.1
- rasterio=1.3.8
- rdma-core=28.9
- re2=2023.03.02
- qtconsole-base=5.5.1
- qtpy=2.4.1
- rasterio=1.3.9
- rdma-core=49.0
- re2=2023.06.02
- readline=8.2
- referencing=0.30.0
- referencing=0.32.0
- requests=2.31.0
- reretry=0.11.8
- rfc3339-validator=0.1.4
- rfc3986-validator=0.1.1
- rioxarray=0.14.1
- rpds-py=0.9.2
- rtree=1.0.1
- s2n=1.3.46
- scikit-learn=1.3.0
- scipy=1.11.1
- rioxarray=0.15.0
- rpds-py=0.16.2
- rtree=1.1.0
- s2n=1.4.1
- scikit-learn=1.3.2
- scipy=1.11.4
- scotch=6.0.9
- seaborn=0.12.2
- seaborn-base=0.12.2
- seaborn=0.13.0
- seaborn-base=0.13.0
- send2trash=1.8.2
- setuptools=68.0.0
- setuptools-scm=7.1.0
- setuptools_scm=7.1.0
- shapely=2.0.1
- sip=6.7.10
- setuptools=69.0.3
- setuptools-scm=8.0.4
- setuptools_scm=8.0.4
- shapely=2.0.2
- sip=6.7.12
- six=1.16.0
- smart_open=6.3.0
- smmap=3.0.5
- snakemake-minimal=7.30.2
- smart_open=6.4.0
- smmap=5.0.0
- snakemake-minimal=7.32.4
- snappy=1.1.10
- sniffio=1.3.0
- snuggs=1.4.7
- sortedcontainers=2.4.0
- soupsieve=2.3.2.post1
- sqlite=3.42.0
- soupsieve=2.5
- sqlite=3.44.2
- stack_data=0.6.2
- statsmodels=0.14.0
- statsmodels=0.14.1
- stopit=1.1.2
- tabula-py=2.6.0
- tabula-py=2.7.0
- tabulate=0.9.0
- tblib=1.7.0
- terminado=0.17.1
- tblib=3.0.0
- terminado=0.18.0
- threadpoolctl=3.2.0
- throttler=1.2.1
- tiledb=2.13.2
- throttler=1.2.2
- tiledb=2.18.2
- tinycss2=1.2.1
- tk=8.6.12
- tk=8.6.13
- toml=0.10.2
- tomli=2.0.1
- toolz=0.12.0
- toposort=1.10
- tornado=6.3.2
- tqdm=4.65.0
- traitlets=5.9.0
- typing-extensions=4.7.1
- typing_extensions=4.7.1
- tornado=6.3.3
- tqdm=4.66.1
- traitlets=5.14.1
- types-python-dateutil=2.8.19.14
- typing-extensions=4.9.0
- typing_extensions=4.9.0
- typing_utils=0.1.0
- tzcode=2023c
- tzdata=2023c
- ucx=1.14.1
- unicodedata2=15.0.0
- unidecode=1.3.6
- unixodbc=2.3.10
- urllib3=2.0.4
- wcwidth=0.2.6
- tzcode=2023d
- tzdata=2023d
- ucx=1.15.0
- unidecode=1.3.7
- unixodbc=2.3.12
- uri-template=1.3.0
- uriparser=0.9.7
- urllib3=2.1.0
- validators=0.22.0
- wcwidth=0.2.12
- webcolors=1.13
- webencodings=0.5.1
- websocket-client=1.6.1
- wheel=0.41.0
- widgetsnbextension=4.0.8
- wrapt=1.15.0
- xarray=2023.7.0
- websocket-client=1.7.0
- wheel=0.42.0
- widgetsnbextension=4.0.9
- wrapt=1.16.0
- xarray=2023.12.0
- xcb-util=0.4.0
- xcb-util-image=0.4.0
- xcb-util-keysyms=0.4.0
- xcb-util-renderutil=0.3.9
- xcb-util-wm=0.4.1
- xerces-c=3.2.4
- xkeyboard-config=2.39
- xerces-c=3.2.5
- xkeyboard-config=2.40
- xlrd=2.0.1
- xorg-fixesproto=5.0
- xorg-inputproto=2.3.2
- xorg-kbproto=1.0.7
- xorg-libice=1.1.1
- xorg-libsm=1.2.4
- xorg-libx11=1.8.6
- xorg-libx11=1.8.7
- xorg-libxau=1.0.11
- xorg-libxdmcp=1.1.3
- xorg-libxext=1.3.4
- xorg-libxfixes=5.0.3
- xorg-libxi=1.7.10
- xorg-libxrender=0.9.11
- xorg-libxt=1.3.0
- xorg-libxtst=1.2.3
- xorg-recordproto=1.14.2
- xorg-renderproto=0.11.1
- xorg-xextproto=7.3.0
- xorg-xf86vidmodeproto=2.3.1
- xorg-xproto=7.0.31
- xyzservices=2023.7.0
- xyzservices=2023.10.1
- xz=5.2.6
- yaml=0.2.5
- yte=1.5.1
- zeromq=4.3.4
- yte=1.5.4
- zeromq=4.3.5
- zict=3.0.0
- zipp=3.16.2
- zipp=3.17.0
- zlib=1.2.13
- zlib-ng=2.0.7
- zstd=1.5.2
- zstd=1.5.5
- pip:
- gurobipy==10.0.2
- linopy==0.2.2
- pypsa==0.25.1
- tsam==2.3.0
- validators==0.20.0
- highspy==1.5.3
- tsam==2.3.1

View File

@ -11,6 +11,8 @@ dependencies:
- pip
- atlite>=0.2.9
- pypsa>=0.26.1
- linopy
- dask
# Dependencies of the workflow itself
@ -18,23 +20,24 @@ dependencies:
- openpyxl!=3.1.1
- pycountry
- seaborn
- snakemake-minimal>=7.7.0
# snakemake 8 introduced a number of breaking changes which the workflow has yet to be made compatible with
- snakemake-minimal>=7.7.0,<8.0.0
- memory_profiler
- yaml
- pytables
- lxml
- powerplantmatching>=0.5.5
- numpy
- pandas>=1.4
- pandas>=2.1
- geopandas>=0.11.0
- xarray<=2023.8.0
- xarray>=2023.11.0
- rioxarray
- netcdf4
- networkx
- scipy
- shapely>=2.0
- pyomo
- matplotlib<3.6
- matplotlib
- proj
- fiona
- country_converter
@ -44,6 +47,7 @@ dependencies:
- tabula-py
- pyxlsb
- graphviz
- ipopt
# Keep in conda environment when calling ipython
- ipython
@ -56,4 +60,3 @@ dependencies:
- pip:
- tsam>=2.3.1
- pypsa>=0.25.2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 728 KiB

After

Width:  |  Height:  |  Size: 636 KiB

View File

@ -20,11 +20,11 @@ if config["enable"].get("prepare_links_p_nom", False):
rule build_electricity_demand:
params:
snapshots=config["snapshots"],
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
countries=config["countries"],
load=config["load"],
input:
ancient("data/load_raw.csv"),
ancient(RESOURCES + "load_raw.csv"),
output:
RESOURCES + "load.csv",
log:
@ -41,6 +41,7 @@ rule build_powerplants:
params:
powerplants_filter=config["electricity"]["powerplants_filter"],
custom_powerplants=config["electricity"]["custom_powerplants"],
everywhere_powerplants=config["electricity"]["everywhere_powerplants"],
countries=config["countries"],
input:
base_network=RESOURCES + "networks/base.nc",
@ -61,7 +62,7 @@ rule build_powerplants:
rule base_network:
params:
countries=config["countries"],
snapshots=config["snapshots"],
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
lines=config["lines"],
links=config["links"],
transformers=config["transformers"],
@ -144,7 +145,7 @@ if config["enable"].get("build_cutout", False):
rule build_cutout:
params:
snapshots=config["snapshots"],
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
cutouts=config["atlite"]["cutouts"],
input:
regions_onshore=RESOURCES + "regions_onshore.geojson",
@ -206,10 +207,62 @@ rule build_ship_raster:
"../scripts/build_ship_raster.py"
rule determine_availability_matrix_MD_UA:
input:
copernicus="data/Copernicus_LC100_global_v3.0.1_2019-nrt_Discrete-Classification-map_EPSG-4326.tif",
wdpa="data/WDPA.gpkg",
wdpa_marine="data/WDPA_WDOECM_marine.gpkg",
gebco=lambda w: (
"data/bundle/GEBCO_2014_2D.nc"
if "max_depth" in config["renewable"][w.technology].keys()
else []
),
ship_density=lambda w: (
RESOURCES + "shipdensity_raster.tif"
if "ship_threshold" in config["renewable"][w.technology].keys()
else []
),
country_shapes=RESOURCES + "country_shapes.geojson",
offshore_shapes=RESOURCES + "offshore_shapes.geojson",
regions=lambda w: (
RESOURCES + "regions_onshore.geojson"
if w.technology in ("onwind", "solar")
else RESOURCES + "regions_offshore.geojson"
),
cutout=lambda w: "cutouts/"
+ CDIR
+ config["renewable"][w.technology]["cutout"]
+ ".nc",
output:
availability_matrix=RESOURCES + "availability_matrix_MD-UA_{technology}.nc",
availability_map=RESOURCES + "availability_matrix_MD-UA_{technology}.png",
log:
LOGS + "determine_availability_matrix_MD_UA_{technology}.log",
threads: ATLITE_NPROCESSES
resources:
mem_mb=ATLITE_NPROCESSES * 5000,
conda:
"../envs/environment.yaml"
script:
"../scripts/determine_availability_matrix_MD_UA.py"
# Optional input when having Ukraine (UA) or Moldova (MD) in the countries list
if {"UA", "MD"}.intersection(set(config["countries"])):
opt = {
"availability_matrix_MD_UA": RESOURCES
+ "availability_matrix_MD-UA_{technology}.nc"
}
else:
opt = {}
rule build_renewable_profiles:
params:
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
renewable=config["renewable"],
input:
**opt,
base_network=RESOURCES + "networks/base.nc",
corine=ancient("data/bundle/corine/g250_clc06_V18_5.tif"),
natura=lambda w: (
@ -217,6 +270,11 @@ rule build_renewable_profiles:
if config["renewable"][w.technology]["natura"]
else []
),
luisa=lambda w: (
"data/LUISA_basemap_020321_50m.tif"
if config["renewable"][w.technology].get("luisa")
else []
),
gebco=ancient(
lambda w: (
"data/bundle/GEBCO_2014_2D.nc"
@ -229,7 +287,7 @@ rule build_renewable_profiles:
),
ship_density=lambda w: (
RESOURCES + "shipdensity_raster.tif"
if "ship_threshold" in config["renewable"][w.technology].keys()
if config["renewable"][w.technology].get("ship_threshold", False)
else []
),
country_shapes=RESOURCES + "country_shapes.geojson",
@ -301,6 +359,8 @@ rule build_hydro_profile:
if config["lines"]["dynamic_line_rating"]["activate"]:
rule build_line_rating:
params:
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
input:
base_network=RESOURCES + "networks/base.nc",
cutout="cutouts/"
@ -358,6 +418,7 @@ rule add_electricity:
else [],
load=RESOURCES + "load.csv",
nuts3_shapes=RESOURCES + "nuts3_shapes.geojson",
ua_md_gdp="data/GDP_PPP_30arcsec_v3_mapped_default.csv",
output:
RESOURCES + "networks/elec.nc",
log:
@ -377,7 +438,9 @@ rule simplify_network:
params:
simplify_network=config["clustering"]["simplify_network"],
aggregation_strategies=config["clustering"].get("aggregation_strategies", {}),
focus_weights=config.get("focus_weights", None),
focus_weights=config["clustering"].get(
"focus_weights", config.get("focus_weights")
),
renewable_carriers=config["electricity"]["renewable_carriers"],
max_hours=config["electricity"]["max_hours"],
length_factor=config["lines"]["length_factor"],
@ -412,7 +475,9 @@ rule cluster_network:
cluster_network=config["clustering"]["cluster_network"],
aggregation_strategies=config["clustering"].get("aggregation_strategies", {}),
custom_busmap=config["enable"].get("custom_busmap", False),
focus_weights=config.get("focus_weights", None),
focus_weights=config["clustering"].get(
"focus_weights", config.get("focus_weights")
),
renewable_carriers=config["electricity"]["renewable_carriers"],
conventional_carriers=config["electricity"].get("conventional_carriers", []),
max_hours=config["electricity"]["max_hours"],
@ -473,13 +538,20 @@ rule add_extra_components:
rule prepare_network:
params:
snapshots={
"resolution": config["snapshots"].get("resolution", False),
"segmentation": config["snapshots"].get("segmentation", False),
},
links=config["links"],
lines=config["lines"],
co2base=config["electricity"]["co2base"],
co2limit_enable=config["electricity"].get("co2limit_enable", False),
co2limit=config["electricity"]["co2limit"],
gaslimit_enable=config["electricity"].get("gaslimit_enable", False),
gaslimit=config["electricity"].get("gaslimit"),
max_hours=config["electricity"]["max_hours"],
costs=config["costs"],
autarky=config["electricity"].get("autarky", {}),
input:
RESOURCES + "networks/elec_s{simpl}_{clusters}_ec.nc",
tech_costs=COSTS,

View File

@ -67,8 +67,6 @@ rule build_simplified_population_layouts:
"../scripts/build_clustered_population_layouts.py"
if config["sector"]["gas_network"] or config["sector"]["H2_retrofit"]:
rule build_gas_network:
input:
gas_network="data/gas_network/scigrid-gas/data/IGGIELGN_PipeSegments.geojson",
@ -83,21 +81,19 @@ if config["sector"]["gas_network"] or config["sector"]["H2_retrofit"]:
script:
"../scripts/build_gas_network.py"
rule build_gas_input_locations:
input:
lng=HTTP.remote(
gem=HTTP.remote(
"https://globalenergymonitor.org/wp-content/uploads/2023/07/Europe-Gas-Tracker-2023-03-v3.xlsx",
keep_local=True,
),
entry="data/gas_network/scigrid-gas/data/IGGIELGN_BorderPoints.geojson",
production="data/gas_network/scigrid-gas/data/IGGIELGN_Productions.geojson",
regions_onshore=RESOURCES
+ "regions_onshore_elec_s{simpl}_{clusters}.geojson",
regions_offshore=RESOURCES
+ "regions_offshore_elec_s{simpl}_{clusters}.geojson",
storage="data/gas_network/scigrid-gas/data/IGGIELGN_Storages.geojson",
regions_onshore=RESOURCES + "regions_onshore_elec_s{simpl}_{clusters}.geojson",
regions_offshore=RESOURCES + "regions_offshore_elec_s{simpl}_{clusters}.geojson",
output:
gas_input_nodes=RESOURCES
+ "gas_input_locations_s{simpl}_{clusters}.geojson",
gas_input_nodes=RESOURCES + "gas_input_locations_s{simpl}_{clusters}.geojson",
gas_input_nodes_simplified=RESOURCES
+ "gas_input_locations_s{simpl}_{clusters}_simplified.csv",
resources:
@ -109,13 +105,12 @@ if config["sector"]["gas_network"] or config["sector"]["H2_retrofit"]:
script:
"../scripts/build_gas_input_locations.py"
rule cluster_gas_network:
input:
cleaned_gas_network=RESOURCES + "gas_network.csv",
regions_onshore=RESOURCES
+ "regions_onshore_elec_s{simpl}_{clusters}.geojson",
regions_offshore=RESOURCES
+ "regions_offshore_elec_s{simpl}_{clusters}.geojson",
regions_onshore=RESOURCES + "regions_onshore_elec_s{simpl}_{clusters}.geojson",
regions_offshore=RESOURCES + "regions_offshore_elec_s{simpl}_{clusters}.geojson",
output:
clustered_gas_network=RESOURCES + "gas_network_elec_s{simpl}_{clusters}.csv",
resources:
@ -127,21 +122,10 @@ if config["sector"]["gas_network"] or config["sector"]["H2_retrofit"]:
script:
"../scripts/cluster_gas_network.py"
gas_infrastructure = {
**rules.cluster_gas_network.output,
**rules.build_gas_input_locations.output,
}
if not (config["sector"]["gas_network"] or config["sector"]["H2_retrofit"]):
# this is effecively an `else` statement which is however not liked by snakefmt
gas_infrastructure = {}
rule build_heat_demands:
params:
snapshots=config["snapshots"],
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
input:
pop_layout=RESOURCES + "pop_layout_{scope}.nc",
regions_onshore=RESOURCES + "regions_onshore_elec_s{simpl}_{clusters}.geojson",
@ -163,7 +147,7 @@ rule build_heat_demands:
rule build_temperature_profiles:
params:
snapshots=config["snapshots"],
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
input:
pop_layout=RESOURCES + "pop_layout_{scope}.nc",
regions_onshore=RESOURCES + "regions_onshore_elec_s{simpl}_{clusters}.geojson",
@ -215,7 +199,7 @@ rule build_cop_profiles:
rule build_solar_thermal_profiles:
params:
snapshots=config["snapshots"],
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
solar_thermal=config["solar_thermal"],
input:
pop_layout=RESOURCES + "pop_layout_{scope}.nc",
@ -269,7 +253,7 @@ rule build_biomass_potentials:
biomass=config["biomass"],
input:
enspreso_biomass=HTTP.remote(
"https://cidportal.jrc.ec.europa.eu/ftp/jrc-opendata/ENSPRESO/ENSPRESO_BIOMASS.xlsx",
"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
@ -678,7 +662,7 @@ rule build_shipping_demand:
rule build_transport_demand:
params:
snapshots=config["snapshots"],
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
sector=config["sector"],
input:
clustered_pop_layout=RESOURCES + "pop_layout_elec_s{simpl}_{clusters}.csv",
@ -722,7 +706,8 @@ rule prepare_sector_network:
input:
**build_retro_cost_output,
**build_biomass_transport_costs_output,
**gas_infrastructure,
**rules.cluster_gas_network.output,
**rules.build_gas_input_locations.output,
**build_sequestration_potentials_output,
network=RESOURCES + "networks/elec_s{simpl}_{clusters}_ec_l{ll}_{opts}.nc",
energy_totals_name=RESOURCES + "energy_totals.csv",

View File

@ -2,6 +2,16 @@
#
# SPDX-License-Identifier: MIT
import os, sys, glob
helper_source_path = [match for match in glob.glob("**/_helpers.py", recursive=True)]
for path in helper_source_path:
path = os.path.dirname(os.path.abspath(path))
sys.path.insert(0, os.path.abspath(path))
from _helpers import validate_checksum
def memory(w):
factor = 3.0
@ -23,6 +33,13 @@ def memory(w):
return int(factor * (10000 + 195 * int(w.clusters)))
def input_custom_extra_functionality(w):
path = config["solving"]["options"].get("custom_extra_functionality", False)
if path:
return workflow.source_path(path)
return []
# Check if the workflow has access to the internet by trying to access the HEAD of specified url
def has_internet_access(url="www.zenodo.org") -> bool:
import http.client as http_client

View File

@ -5,7 +5,6 @@
localrules:
copy_config,
copy_conda_env,
if config["foresight"] != "perfect":
@ -86,7 +85,7 @@ rule make_summary:
params:
foresight=config["foresight"],
costs=config["costs"],
snapshots=config["snapshots"],
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
scenario=config["scenario"],
RDIR=RDIR,
input:

View File

@ -2,6 +2,9 @@
#
# SPDX-License-Identifier: MIT
import requests
from datetime import datetime, timedelta
if config["enable"].get("retrieve", "auto") == "auto":
config["enable"]["retrieve"] = has_internet_access()
@ -74,6 +77,7 @@ if config["enable"]["retrieve"] and config["enable"].get("retrieve_cutout", True
retries: 2
run:
move(input[0], output[0])
validate_checksum(output[0], input[0])
if config["enable"]["retrieve"] and config["enable"].get("retrieve_cost_data", True):
@ -110,7 +114,7 @@ if config["enable"]["retrieve"] and config["enable"].get(
static=True,
),
output:
protected(RESOURCES + "natura.tiff"),
RESOURCES + "natura.tiff",
log:
LOGS + "retrieve_natura_raster.log",
resources:
@ -118,6 +122,7 @@ if config["enable"]["retrieve"] and config["enable"].get(
retries: 2
run:
move(input[0], output[0])
validate_checksum(output[0], input[0])
if config["enable"]["retrieve"] and config["enable"].get(
@ -157,13 +162,12 @@ if config["enable"]["retrieve"] and config["enable"].get(
"../scripts/retrieve_sector_databundle.py"
if config["enable"]["retrieve"] and (
config["sector"]["gas_network"] or config["sector"]["H2_retrofit"]
):
if config["enable"]["retrieve"]:
datafiles = [
"IGGIELGN_LNGs.geojson",
"IGGIELGN_BorderPoints.geojson",
"IGGIELGN_Productions.geojson",
"IGGIELGN_Storages.geojson",
"IGGIELGN_PipeSegments.geojson",
]
@ -195,7 +199,7 @@ if config["enable"]["retrieve"]:
static=True,
),
output:
"data/load_raw.csv",
RESOURCES + "load_raw.csv",
log:
LOGS + "retrieve_electricity_demand.log",
resources:
@ -223,6 +227,122 @@ if config["enable"]["retrieve"]:
retries: 2
run:
move(input[0], output[0])
validate_checksum(output[0], input[0])
if config["enable"]["retrieve"]:
# Downloading Copernicus Global Land Cover for land cover and land use:
# Website: https://land.copernicus.eu/global/products/lc
rule download_copernicus_land_cover:
input:
HTTP.remote(
"zenodo.org/record/3939050/files/PROBAV_LC100_global_v3.0.1_2019-nrt_Discrete-Classification-map_EPSG-4326.tif",
static=True,
),
output:
"data/Copernicus_LC100_global_v3.0.1_2019-nrt_Discrete-Classification-map_EPSG-4326.tif",
run:
move(input[0], output[0])
validate_checksum(output[0], input[0])
if config["enable"]["retrieve"]:
# Downloading LUISA Base Map for land cover and land use:
# Website: https://ec.europa.eu/jrc/en/luisa
rule retrieve_luisa_land_cover:
input:
HTTP.remote(
"jeodpp.jrc.ec.europa.eu/ftp/jrc-opendata/LUISA/EUROPE/Basemaps/LandUse/2018/LATEST/LUISA_basemap_020321_50m.tif",
static=True,
),
output:
"data/LUISA_basemap_020321_50m.tif",
run:
move(input[0], output[0])
if config["enable"]["retrieve"]:
# Some logic to find the correct file URL
# Sometimes files are released delayed or ahead of schedule, check which file is currently available
def check_file_exists(url):
response = requests.head(url)
return response.status_code == 200
# Basic pattern where WDPA files can be found
url_pattern = (
"https://d1gam3xoknrgr2.cloudfront.net/current/WDPA_{bYYYY}_Public_shp.zip"
)
# 3-letter month + 4 digit year for current/previous/next month to test
current_monthyear = datetime.now().strftime("%b%Y")
prev_monthyear = (datetime.now() - timedelta(30)).strftime("%b%Y")
next_monthyear = (datetime.now() + timedelta(30)).strftime("%b%Y")
# Test prioritised: current month -> previous -> next
for bYYYY in [current_monthyear, prev_monthyear, next_monthyear]:
if check_file_exists(url := url_pattern.format(bYYYY=bYYYY)):
break
else:
# If None of the three URLs are working
url = False
assert (
url
), f"No WDPA files found at {url_pattern} for bY='{current_monthyear}, {prev_monthyear}, or {next_monthyear}'"
# Downloading protected area database from WDPA
# extract the main zip and then merge the contained 3 zipped shapefiles
# Website: https://www.protectedplanet.net/en/thematic-areas/wdpa
rule download_wdpa:
input:
HTTP.remote(
url,
static=True,
keep_local=True,
),
params:
zip="data/WDPA_shp.zip",
folder=directory("data/WDPA"),
output:
gpkg=protected("data/WDPA.gpkg"),
run:
shell("cp {input} {params.zip}")
shell("unzip -o {params.zip} -d {params.folder}")
for i in range(3):
# vsizip is special driver for directly working with zipped shapefiles in ogr2ogr
layer_path = (
f"/vsizip/{params.folder}/WDPA_{bYYYY}_Public_shp_{i}.zip"
)
print(f"Adding layer {i+1} of 3 to combined output file.")
shell("ogr2ogr -f gpkg -update -append {output.gpkg} {layer_path}")
rule download_wdpa_marine:
# Downloading Marine protected area database from WDPA
# extract the main zip and then merge the contained 3 zipped shapefiles
# Website: https://www.protectedplanet.net/en/thematic-areas/marine-protected-areas
input:
HTTP.remote(
f"d1gam3xoknrgr2.cloudfront.net/current/WDPA_WDOECM_{bYYYY}_Public_marine_shp.zip",
static=True,
keep_local=True,
),
params:
zip="data/WDPA_WDOECM_marine.zip",
folder=directory("data/WDPA_WDOECM_marine"),
output:
gpkg=protected("data/WDPA_WDOECM_marine.gpkg"),
run:
shell("cp {input} {params.zip}")
shell("unzip -o {params.zip} -d {params.folder}")
for i in range(3):
# vsizip is special driver for directly working with zipped shapefiles in ogr2ogr
layer_path = f"/vsizip/{params.folder}/WDPA_WDOECM_{bYYYY}_Public_marine_shp_{i}.zip"
print(f"Adding layer {i+1} of 3 to combined output file.")
shell("ogr2ogr -f gpkg -update -append {output.gpkg} {layer_path}")
if config["enable"]["retrieve"]:

View File

@ -11,6 +11,7 @@ rule solve_network:
co2_sequestration_potential=config["sector"].get(
"co2_sequestration_potential", 200
),
custom_extra_functionality=input_custom_extra_functionality,
input:
network=RESOURCES + "networks/elec_s{simpl}_{clusters}_ec_l{ll}_{opts}.nc",
config=RESULTS + "config.yaml",

View File

@ -88,6 +88,7 @@ rule solve_sector_network_myopic:
co2_sequestration_potential=config["sector"].get(
"co2_sequestration_potential", 200
),
custom_extra_functionality=input_custom_extra_functionality,
input:
network=RESULTS
+ "prenetworks-brownfield/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",

View File

@ -11,6 +11,7 @@ rule solve_sector_network:
co2_sequestration_potential=config["sector"].get(
"co2_sequestration_potential", 200
),
custom_extra_functionality=input_custom_extra_functionality,
input:
network=RESULTS
+ "prenetworks/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",

View File

@ -118,6 +118,7 @@ rule solve_sector_network_perfect:
co2_sequestration_potential=config["sector"].get(
"co2_sequestration_potential", 200
),
custom_extra_functionality=input_custom_extra_functionality,
input:
network=RESULTS
+ "prenetworks-brownfield/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_brownfield_all_years.nc",

View File

@ -17,7 +17,7 @@ rule build_electricity_production:
The data is used for validation of the optimization results.
"""
params:
snapshots=config["snapshots"],
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
countries=config["countries"],
output:
RESOURCES + "historical_electricity_production.csv",
@ -35,7 +35,7 @@ rule build_cross_border_flows:
The data is used for validation of the optimization results.
"""
params:
snapshots=config["snapshots"],
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
countries=config["countries"],
input:
network=RESOURCES + "networks/base.nc",
@ -55,7 +55,7 @@ rule build_electricity_prices:
The data is used for validation of the optimization results.
"""
params:
snapshots=config["snapshots"],
snapshots={k: config["snapshots"][k] for k in ["start", "end", "inclusive"]},
countries=config["countries"],
output:
RESOURCES + "historical_electricity_prices.csv",

View File

@ -4,13 +4,16 @@
# SPDX-License-Identifier: MIT
import contextlib
import hashlib
import logging
import os
import re
import urllib
from pathlib import Path
import pandas as pd
import pytz
import requests
import yaml
from pypsa.components import component_attrs, components
from pypsa.descriptors import Dict
@ -21,6 +24,35 @@ logger = logging.getLogger(__name__)
REGION_COLS = ["geometry", "name", "x", "y", "country"]
def get_opt(opts, expr, flags=None):
"""
Return the first option matching the regular expression.
The regular expression is case-insensitive by default.
"""
if flags is None:
flags = re.IGNORECASE
for o in opts:
match = re.match(expr, o, flags=flags)
if match:
return match.group(0)
return None
def find_opt(opts, expr):
"""
Return if available the float after the expression.
"""
for o in opts:
if expr in o:
m = re.findall("[0-9]*\.?[0-9]+$", o)
if len(m) > 0:
return True, float(m[0])
else:
return True, None
return False, None
# Define a context manager to temporarily mute print statements
@contextlib.contextmanager
def mute_print():
@ -318,3 +350,63 @@ def update_config_with_sector_opts(config, sector_opts):
if o.startswith("CF+"):
l = o.split("+")[1:]
update_config(config, parse(l))
def get_checksum_from_zenodo(file_url):
parts = file_url.split("/")
record_id = parts[parts.index("record") + 1]
filename = parts[-1]
response = requests.get(f"https://zenodo.org/api/records/{record_id}", timeout=30)
response.raise_for_status()
data = response.json()
for file in data["files"]:
if file["key"] == filename:
return file["checksum"]
return None
def validate_checksum(file_path, zenodo_url=None, checksum=None):
"""
Validate file checksum against provided or Zenodo-retrieved checksum.
Calculates the hash of a file using 64KB chunks. Compares it against a
given checksum or one from a Zenodo URL.
Parameters
----------
file_path : str
Path to the file for checksum validation.
zenodo_url : str, optional
URL of the file on Zenodo to fetch the checksum.
checksum : str, optional
Checksum (format 'hash_type:checksum_value') for validation.
Raises
------
AssertionError
If the checksum does not match, or if neither `checksum` nor `zenodo_url` is provided.
Examples
--------
>>> validate_checksum("/path/to/file", checksum="md5:abc123...")
>>> validate_checksum(
... "/path/to/file",
... zenodo_url="https://zenodo.org/record/12345/files/example.txt",
... )
If the checksum is invalid, an AssertionError will be raised.
"""
assert checksum or zenodo_url, "Either checksum or zenodo_url must be provided"
if zenodo_url:
checksum = get_checksum_from_zenodo(zenodo_url)
hash_type, checksum = checksum.split(":")
hasher = hashlib.new(hash_type)
with open(file_path, "rb") as f:
for chunk in iter(lambda: f.read(65536), b""): # 64kb chunks
hasher.update(chunk)
calculated_checksum = hasher.hexdigest()
assert (
calculated_checksum == checksum
), "Checksum is invalid. This may be due to an incomplete download. Delete the file and re-execute the rule."

View File

@ -120,6 +120,31 @@ def add_brownfield(n, n_p, year):
n.links.loc[new_pipes, "p_nom_min"] = 0.0
def disable_grid_expansion_if_LV_limit_hit(n):
if not "lv_limit" in n.global_constraints.index:
return
total_expansion = (
n.lines.eval("s_nom_min * length").sum()
+ n.links.query("carrier == 'DC'").eval("p_nom_min * length").sum()
).sum()
lv_limit = n.global_constraints.at["lv_limit", "constant"]
# allow small numerical differences
if lv_limit - total_expansion < 1:
logger.info(f"LV is already reached, disabling expansion and LV limit")
extendable_acs = n.lines.query("s_nom_extendable").index
n.lines.loc[extendable_acs, "s_nom_extendable"] = False
n.lines.loc[extendable_acs, "s_nom"] = n.lines.loc[extendable_acs, "s_nom_min"]
extendable_dcs = n.links.query("carrier == 'DC' and p_nom_extendable").index
n.links.loc[extendable_dcs, "p_nom_extendable"] = False
n.links.loc[extendable_dcs, "p_nom"] = n.links.loc[extendable_dcs, "p_nom_min"]
n.global_constraints.drop("lv_limit", inplace=True)
if __name__ == "__main__":
if "snakemake" not in globals():
from _helpers import mock_snakemake
@ -150,5 +175,7 @@ if __name__ == "__main__":
add_brownfield(n, n_p, year)
disable_grid_expansion_if_LV_limit_hit(n)
n.meta = dict(snakemake.config, **dict(wildcards=dict(snakemake.wildcards)))
n.export_to_netcdf(snakemake.output[0])

View File

@ -84,6 +84,7 @@ It further adds extendable ``generators`` with **zero** capacity for
import logging
from itertools import product
from typing import Dict, List
import geopandas as gpd
import numpy as np
@ -255,6 +256,7 @@ 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"})
@ -279,11 +281,13 @@ def shapes_to_shapes(orig, dest):
return transfer
def attach_load(n, regions, load, nuts3_shapes, countries, scaling=1.0):
def attach_load(n, regions, load, nuts3_shapes, ua_md_gdp, countries, scaling=1.0):
substation_lv_i = n.buses.index[n.buses["substation_lv"]]
regions = gpd.read_file(regions).set_index("name").reindex(substation_lv_i)
opsd_load = pd.read_csv(load, index_col=0, parse_dates=True).filter(items=countries)
ua_md_gdp = pd.read_csv(ua_md_gdp, dtype={"name": "str"}).set_index("name")
logger.info(f"Load data scaled with scalling factor {scaling}.")
opsd_load *= scaling
@ -291,6 +295,7 @@ def attach_load(n, regions, load, nuts3_shapes, countries, scaling=1.0):
def upsample(cntry, group):
l = opsd_load[cntry]
if len(group) == 1:
return pd.DataFrame({group.index[0]: l})
nuts3_cntry = nuts3.loc[nuts3.country == cntry]
@ -305,6 +310,9 @@ def attach_load(n, regions, load, nuts3_shapes, countries, scaling=1.0):
# relative factors 0.6 and 0.4 have been determined from a linear
# regression on the country to continent load data
factors = normed(0.6 * normed(gdp_n) + 0.4 * normed(pop_n))
if cntry in ["UA", "MD"]:
# overwrite factor because nuts3 provides no data for UA+MD
factors = normed(ua_md_gdp.loc[group.index, "GDP_PPP"].squeeze())
return pd.DataFrame(
factors.values * l.values[:, np.newaxis],
index=l.index,
@ -710,7 +718,17 @@ def attach_extendable_generators(n, costs, ppl, carriers):
)
def attach_OPSD_renewables(n, tech_map):
def attach_OPSD_renewables(n: pypsa.Network, tech_map: Dict[str, List[str]]) -> None:
"""
Attach renewable capacities from the OPSD dataset to the network.
Args:
- n: The PyPSA network to attach the capacities to.
- tech_map: A dictionary mapping fuel types to carrier names.
Returns:
- None
"""
tech_string = ", ".join(sum(tech_map.values(), []))
logger.info(f"Using OPSD renewable capacities for carriers {tech_string}.")
@ -735,7 +753,26 @@ def attach_OPSD_renewables(n, tech_map):
n.generators.p_nom_min.update(gens.bus.map(caps).dropna())
def estimate_renewable_capacities(n, year, tech_map, expansion_limit, countries):
def estimate_renewable_capacities(
n: pypsa.Network, year: int, tech_map: dict, expansion_limit: bool, countries: list
) -> None:
"""
Estimate a different between renewable capacities in the network and
reported country totals from IRENASTAT dataset. Distribute the difference
with a heuristic.
Heuristic: n.generators_t.p_max_pu.mean() * n.generators.p_nom_max
Args:
- n: The PyPSA network.
- year: The year of optimisation.
- tech_map: A dictionary mapping fuel types to carrier names.
- expansion_limit: Boolean value from config file
- countries: A list of country codes to estimate capacities for.
Returns:
- None
"""
if not len(countries) or not len(tech_map):
return
@ -752,7 +789,10 @@ def estimate_renewable_capacities(n, year, tech_map, expansion_limit, countries)
for ppm_technology, techs in tech_map.items():
tech_i = n.generators.query("carrier in @techs").index
if ppm_technology in capacities.index.get_level_values("Technology"):
stats = capacities.loc[ppm_technology].reindex(countries, fill_value=0.0)
else:
stats = pd.Series(0.0, index=countries)
country = n.generators.bus[tech_i].map(n.buses.country)
existent = n.generators.p_nom[tech_i].groupby(country).sum()
missing = stats - existent
@ -825,6 +865,7 @@ if __name__ == "__main__":
snakemake.input.regions,
snakemake.input.load,
snakemake.input.nuts3_shapes,
snakemake.input.ua_md_gdp,
params.countries,
params.scaling_factor,
)

View File

@ -88,7 +88,9 @@ def add_existing_renewables(df_agg):
]
cfs = n.generators_t.p_max_pu[gens].mean()
cfs_key = cfs / cfs.sum()
nodal_fraction.loc[n.generators.loc[gens, "bus"]] = cfs_key.values
nodal_fraction.loc[n.generators.loc[gens, "bus"]] = cfs_key.groupby(
n.generators.loc[gens, "bus"]
).sum()
nodal_df = df.loc[n.buses.loc[elec_buses, "country"]]
nodal_df.index = elec_buses
@ -303,7 +305,7 @@ def add_power_capacities_installed_before_baseyear(n, grouping_years, costs, bas
else:
bus0 = vars(spatial)[carrier[generator]].nodes
if "EU" not in vars(spatial)[carrier[generator]].locations:
bus0 = bus0.intersection(capacity.index + " gas")
bus0 = bus0.intersection(capacity.index + " " + carrier[generator])
# check for missing bus
missing_bus = pd.Index(bus0).difference(n.buses.index)

View File

@ -366,6 +366,25 @@ def _apply_parameter_corrections(n, parameter_corrections):
df.loc[inds, attr] = r[inds].astype(df[attr].dtype)
def _reconnect_crimea(lines):
logger.info("Reconnecting Crimea to the Ukrainian grid.")
lines_to_crimea = pd.DataFrame(
{
"bus0": ["3065", "3181", "3181"],
"bus1": ["3057", "3055", "3057"],
"v_nom": [300, 300, 300],
"num_parallel": [1, 1, 1],
"length": [140, 120, 140],
"carrier": ["AC", "AC", "AC"],
"underground": [False, False, False],
"under_construction": [False, False, False],
},
index=["Melitopol", "Liubymivka left", "Luibymivka right"],
)
return pd.concat([lines, lines_to_crimea])
def _set_electrical_parameters_lines(lines, config):
v_noms = config["electricity"]["voltages"]
linetypes = config["lines"]["types"]
@ -450,12 +469,12 @@ def _remove_dangling_branches(branches, buses):
)
def _remove_unconnected_components(network):
def _remove_unconnected_components(network, threshold=6):
_, labels = csgraph.connected_components(network.adjacency_matrix(), directed=False)
component = pd.Series(labels, index=network.buses.index)
component_sizes = component.value_counts()
components_to_remove = component_sizes.iloc[1:]
components_to_remove = component_sizes.loc[component_sizes < threshold]
logger.info(
f"Removing {len(components_to_remove)} unconnected network components with less than {components_to_remove.max()} buses. In total {components_to_remove.sum()} buses."
@ -541,7 +560,7 @@ def _set_countries_and_substations(n, config, country_shapes, offshore_shapes):
~buses["under_construction"]
)
c_nan_b = buses.country.isnull()
c_nan_b = buses.country == "na"
if c_nan_b.sum() > 0:
c_tag = _get_country(buses.loc[c_nan_b])
c_tag.loc[~c_tag.isin(countries)] = np.nan
@ -699,15 +718,19 @@ def base_network(
lines = _load_lines_from_eg(buses, eg_lines)
transformers = _load_transformers_from_eg(buses, eg_transformers)
if config["lines"].get("reconnect_crimea", True) and "UA" in config["countries"]:
lines = _reconnect_crimea(lines)
lines = _set_electrical_parameters_lines(lines, config)
transformers = _set_electrical_parameters_transformers(transformers, config)
links = _set_electrical_parameters_links(links, config, links_p_nom)
converters = _set_electrical_parameters_converters(converters, config)
snapshots = snakemake.params.snapshots
n = pypsa.Network()
n.name = "PyPSA-Eur"
n.set_snapshots(pd.date_range(freq="h", **config["snapshots"]))
n.set_snapshots(pd.date_range(freq="h", **snapshots))
n.madd("Carrier", ["AC", "DC"])
n.import_components_from_dataframe(buses, "Bus")

View File

@ -134,7 +134,7 @@ def disaggregate_nuts0(bio):
# get population in nuts2
pop_nuts2 = pop.loc[pop.index.str.len() == 4]
by_country = pop_nuts2.total.groupby(pop_nuts2.ct).sum()
pop_nuts2["fraction"] = pop_nuts2.total / pop_nuts2.ct.map(by_country)
pop_nuts2.loc[:, "fraction"] = pop_nuts2.total / pop_nuts2.ct.map(by_country)
# distribute nuts0 data to nuts2 by population
bio_nodal = bio.loc[pop_nuts2.ct]
@ -263,7 +263,7 @@ if __name__ == "__main__":
df.to_csv(snakemake.output.biomass_potentials_all)
grouper = {v: k for k, vv in params["classes"].items() for v in vv}
df = df.groupby(grouper, axis=1).sum()
df = df.T.groupby(grouper).sum().T
df *= 1e6 # TWh/a to MWh/a
df.index.name = "MWh/a"

View File

@ -25,10 +25,7 @@ if __name__ == "__main__":
cutout = atlite.Cutout(snakemake.input.cutout)
clustered_regions = (
gpd.read_file(snakemake.input.regions_onshore)
.set_index("name")
.buffer(0)
.squeeze()
gpd.read_file(snakemake.input.regions_onshore).set_index("name").buffer(0)
)
I = cutout.indicatormatrix(clustered_regions)

View File

@ -31,7 +31,7 @@ Relevant Settings
Inputs
------
- ``data/load_raw.csv``:
- ``resources/load_raw.csv``:
Outputs
-------
@ -81,7 +81,7 @@ def load_timeseries(fn, years, countries, powerstatistics=True):
return s[: -len(pattern)]
return (
pd.read_csv(fn, index_col=0, parse_dates=[0])
pd.read_csv(fn, index_col=0, parse_dates=[0], date_format="%Y-%m-%dT%H:%M:%SZ")
.tz_localize(None)
.filter(like=pattern)
.rename(columns=rename)
@ -155,7 +155,7 @@ def copy_timeslice(load, cntry, start, stop, delta, fn_load=None):
].values
def manual_adjustment(load, fn_load, powerstatistics):
def manual_adjustment(load, fn_load, powerstatistics, countries):
"""
Adjust gaps manual for load data from OPSD time-series package.
@ -278,6 +278,14 @@ def manual_adjustment(load, fn_load, powerstatistics):
load, "LU", "2019-02-05 20:00", "2019-02-06 19:00", Delta(weeks=-1)
)
if "UA" in countries:
copy_timeslice(
load, "UA", "2013-01-25 14:00", "2013-01-28 21:00", Delta(weeks=1)
)
copy_timeslice(
load, "UA", "2013-10-28 03:00", "2013-10-28 20:00", Delta(weeks=1)
)
return load
@ -298,8 +306,22 @@ if __name__ == "__main__":
load = load_timeseries(snakemake.input[0], years, countries, powerstatistics)
if "UA" in countries:
# attach load of UA (best data only for entsoe transparency)
load_ua = load_timeseries(snakemake.input[0], "2018", ["UA"], False)
snapshot_year = str(snapshots.year.unique().item())
time_diff = pd.Timestamp("2018") - pd.Timestamp(snapshot_year)
load_ua.index -= (
time_diff # hack indices (currently, UA is manually set to 2018)
)
load["UA"] = load_ua
# attach load of MD (no time-series available, use 2020-totals and distribute according to UA):
# https://www.iea.org/data-and-statistics/data-browser/?country=MOLDOVA&fuel=Energy%20consumption&indicator=TotElecCons
if "MD" in countries:
load["MD"] = 6.2e6 * (load_ua / load_ua.sum())
if snakemake.params.load["manual_adjustments"]:
load = manual_adjustment(load, snakemake.input[0], powerstatistics)
load = manual_adjustment(load, snakemake.input[0], powerstatistics, countries)
if load.empty:
logger.warning("Build electricity demand time series is empty.")

View File

@ -189,12 +189,12 @@ def idees_per_country(ct, year, base_dir):
ct_totals["total residential water"] = df.at["Water heating"]
assert df.index[23] == "Electricity"
ct_totals["electricity residential water"] = df[23]
ct_totals["electricity residential water"] = df.iloc[23]
ct_totals["total residential cooking"] = df["Cooking"]
assert df.index[30] == "Electricity"
ct_totals["electricity residential cooking"] = df[30]
ct_totals["electricity residential cooking"] = df.iloc[30]
df = pd.read_excel(fn_residential, "RES_summary", index_col=0)[year]
@ -202,13 +202,13 @@ def idees_per_country(ct, year, base_dir):
ct_totals["total residential"] = df[row]
assert df.index[47] == "Electricity"
ct_totals["electricity residential"] = df[47]
ct_totals["electricity residential"] = df.iloc[47]
assert df.index[46] == "Derived heat"
ct_totals["derived heat residential"] = df[46]
ct_totals["derived heat residential"] = df.iloc[46]
assert df.index[50] == "Thermal uses"
ct_totals["thermal uses residential"] = df[50]
ct_totals["thermal uses residential"] = df.iloc[50]
# services
@ -222,12 +222,12 @@ def idees_per_country(ct, year, base_dir):
ct_totals["total services water"] = df["Hot water"]
assert df.index[24] == "Electricity"
ct_totals["electricity services water"] = df[24]
ct_totals["electricity services water"] = df.iloc[24]
ct_totals["total services cooking"] = df["Catering"]
assert df.index[31] == "Electricity"
ct_totals["electricity services cooking"] = df[31]
ct_totals["electricity services cooking"] = df.iloc[31]
df = pd.read_excel(fn_tertiary, "SER_summary", index_col=0)[year]
@ -235,13 +235,13 @@ def idees_per_country(ct, year, base_dir):
ct_totals["total services"] = df[row]
assert df.index[50] == "Electricity"
ct_totals["electricity services"] = df[50]
ct_totals["electricity services"] = df.iloc[50]
assert df.index[49] == "Derived heat"
ct_totals["derived heat services"] = df[49]
ct_totals["derived heat services"] = df.iloc[49]
assert df.index[53] == "Thermal uses"
ct_totals["thermal uses services"] = df[53]
ct_totals["thermal uses services"] = df.iloc[53]
# agriculture, forestry and fishing
@ -282,28 +282,28 @@ def idees_per_country(ct, year, base_dir):
ct_totals["total two-wheel"] = df["Powered 2-wheelers (Gasoline)"]
assert df.index[19] == "Passenger cars"
ct_totals["total passenger cars"] = df[19]
ct_totals["total passenger cars"] = df.iloc[19]
assert df.index[30] == "Battery electric vehicles"
ct_totals["electricity passenger cars"] = df[30]
ct_totals["electricity passenger cars"] = df.iloc[30]
assert df.index[31] == "Motor coaches, buses and trolley buses"
ct_totals["total other road passenger"] = df[31]
ct_totals["total other road passenger"] = df.iloc[31]
assert df.index[39] == "Battery electric vehicles"
ct_totals["electricity other road passenger"] = df[39]
ct_totals["electricity other road passenger"] = df.iloc[39]
assert df.index[41] == "Light duty vehicles"
ct_totals["total light duty road freight"] = df[41]
ct_totals["total light duty road freight"] = df.iloc[41]
assert df.index[49] == "Battery electric vehicles"
ct_totals["electricity light duty road freight"] = df[49]
ct_totals["electricity light duty road freight"] = df.iloc[49]
row = "Heavy duty vehicles (Diesel oil incl. biofuels)"
ct_totals["total heavy duty road freight"] = df[row]
assert df.index[61] == "Passenger cars"
ct_totals["passenger car efficiency"] = df[61]
ct_totals["passenger car efficiency"] = df.iloc[61]
df = pd.read_excel(fn_transport, "TrRail_ene", index_col=0)[year]
@ -312,39 +312,39 @@ def idees_per_country(ct, year, base_dir):
ct_totals["electricity rail"] = df["Electricity"]
assert df.index[15] == "Passenger transport"
ct_totals["total rail passenger"] = df[15]
ct_totals["total rail passenger"] = df.iloc[15]
assert df.index[16] == "Metro and tram, urban light rail"
assert df.index[19] == "Electric"
assert df.index[20] == "High speed passenger trains"
ct_totals["electricity rail passenger"] = df[[16, 19, 20]].sum()
ct_totals["electricity rail passenger"] = df.iloc[[16, 19, 20]].sum()
assert df.index[21] == "Freight transport"
ct_totals["total rail freight"] = df[21]
ct_totals["total rail freight"] = df.iloc[21]
assert df.index[23] == "Electric"
ct_totals["electricity rail freight"] = df[23]
ct_totals["electricity rail freight"] = df.iloc[23]
df = pd.read_excel(fn_transport, "TrAvia_ene", index_col=0)[year]
assert df.index[6] == "Passenger transport"
ct_totals["total aviation passenger"] = df[6]
ct_totals["total aviation passenger"] = df.iloc[6]
assert df.index[10] == "Freight transport"
ct_totals["total aviation freight"] = df[10]
ct_totals["total aviation freight"] = df.iloc[10]
assert df.index[7] == "Domestic"
ct_totals["total domestic aviation passenger"] = df[7]
ct_totals["total domestic aviation passenger"] = df.iloc[7]
assert df.index[8] == "International - Intra-EU"
assert df.index[9] == "International - Extra-EU"
ct_totals["total international aviation passenger"] = df[[8, 9]].sum()
ct_totals["total international aviation passenger"] = df.iloc[[8, 9]].sum()
assert df.index[11] == "Domestic and International - Intra-EU"
ct_totals["total domestic aviation freight"] = df[11]
ct_totals["total domestic aviation freight"] = df.iloc[11]
assert df.index[12] == "International - Extra-EU"
ct_totals["total international aviation freight"] = df[12]
ct_totals["total international aviation freight"] = df.iloc[12]
ct_totals["total domestic aviation"] = (
ct_totals["total domestic aviation freight"]
@ -364,7 +364,7 @@ def idees_per_country(ct, year, base_dir):
df = pd.read_excel(fn_transport, "TrRoad_act", index_col=0)[year]
assert df.index[85] == "Passenger cars"
ct_totals["passenger cars"] = df[85]
ct_totals["passenger cars"] = df.iloc[85]
return pd.Series(ct_totals, name=ct)

View File

@ -23,11 +23,10 @@ def read_scigrid_gas(fn):
return df
def build_gem_lng_data(lng_fn):
df = pd.read_excel(lng_fn[0], sheet_name="LNG terminals - data")
def build_gem_lng_data(fn):
df = pd.read_excel(fn[0], sheet_name="LNG terminals - data")
df = df.set_index("ComboID")
remove_status = ["Cancelled"]
remove_country = ["Cyprus", "Turkey"]
remove_terminal = ["Puerto de la Luz LNG Terminal", "Gran Canaria LNG Terminal"]
@ -42,9 +41,50 @@ def build_gem_lng_data(lng_fn):
return gpd.GeoDataFrame(df, geometry=geometry, crs="EPSG:4326")
def build_gas_input_locations(lng_fn, entry_fn, prod_fn, countries):
def build_gem_prod_data(fn):
df = pd.read_excel(fn[0], sheet_name="Gas extraction - main")
df = df.set_index("GEM Unit ID")
remove_country = ["Cyprus", "Türkiye"]
remove_fuel_type = ["oil"]
df = df.query(
"Status != 'shut in' \
& 'Fuel type' != 'oil' \
& Country != @remove_country \
& ~Latitude.isna() \
& ~Longitude.isna()"
).copy()
p = pd.read_excel(fn[0], sheet_name="Gas extraction - production")
p = p.set_index("GEM Unit ID")
p = p[p["Fuel description"] == "gas"]
capacities = pd.DataFrame(index=df.index)
for key in ["production", "production design capacity", "reserves"]:
cap = (
p.loc[p["Production/reserves"] == key, "Quantity (converted)"]
.groupby("GEM Unit ID")
.sum()
.reindex(df.index)
)
# assume capacity such that 3% of reserves can be extracted per year (25% quantile)
annualization_factor = 0.03 if key == "reserves" else 1.0
capacities[key] = cap * annualization_factor
df["mcm_per_year"] = (
capacities["production"]
.combine_first(capacities["production design capacity"])
.combine_first(capacities["reserves"])
)
geometry = gpd.points_from_xy(df["Longitude"], df["Latitude"])
return gpd.GeoDataFrame(df, geometry=geometry, crs="EPSG:4326")
def build_gas_input_locations(gem_fn, entry_fn, sto_fn, countries):
# LNG terminals
lng = build_gem_lng_data(lng_fn)
lng = build_gem_lng_data(gem_fn)
# Entry points from outside the model scope
entry = read_scigrid_gas(entry_fn)
@ -55,25 +95,30 @@ def build_gas_input_locations(lng_fn, entry_fn, prod_fn, countries):
| (entry.from_country == "NO") # malformed datapoint # entries from NO to GB
]
sto = read_scigrid_gas(sto_fn)
remove_country = ["RU", "UA", "TR", "BY"]
sto = sto.query("country_code != @remove_country")
# production sites inside the model scope
prod = read_scigrid_gas(prod_fn)
prod = prod.loc[
(prod.geometry.y > 35) & (prod.geometry.x < 30) & (prod.country_code != "DE")
]
prod = build_gem_prod_data(gem_fn)
mcm_per_day_to_mw = 437.5 # MCM/day to MWh/h
mcm_per_year_to_mw = 1.199 # MCM/year to MWh/h
mtpa_to_mw = 1649.224 # mtpa to MWh/h
lng["p_nom"] = lng["CapacityInMtpa"] * mtpa_to_mw
entry["p_nom"] = entry["max_cap_from_to_M_m3_per_d"] * mcm_per_day_to_mw
prod["p_nom"] = prod["max_supply_M_m3_per_d"] * mcm_per_day_to_mw
mcm_to_gwh = 11.36 # MCM to GWh
lng["capacity"] = lng["CapacityInMtpa"] * mtpa_to_mw
entry["capacity"] = entry["max_cap_from_to_M_m3_per_d"] * mcm_per_day_to_mw
prod["capacity"] = prod["mcm_per_year"] * mcm_per_year_to_mw
sto["capacity"] = sto["max_cushionGas_M_m3"] * mcm_to_gwh
lng["type"] = "lng"
entry["type"] = "pipeline"
prod["type"] = "production"
sto["type"] = "storage"
sel = ["geometry", "p_nom", "type"]
sel = ["geometry", "capacity", "type"]
return pd.concat([prod[sel], entry[sel], lng[sel]], ignore_index=True)
return pd.concat([prod[sel], entry[sel], lng[sel], sto[sel]], ignore_index=True)
if __name__ == "__main__":
@ -83,7 +128,7 @@ if __name__ == "__main__":
snakemake = mock_snakemake(
"build_gas_input_locations",
simpl="",
clusters="37",
clusters="128",
)
logging.basicConfig(level=snakemake.config["logging"]["level"])
@ -104,9 +149,9 @@ if __name__ == "__main__":
countries = regions.index.str[:2].unique().str.replace("GB", "UK")
gas_input_locations = build_gas_input_locations(
snakemake.input.lng,
snakemake.input.gem,
snakemake.input.entry,
snakemake.input.production,
snakemake.input.storage,
countries,
)
@ -116,9 +161,13 @@ if __name__ == "__main__":
gas_input_nodes.to_file(snakemake.output.gas_input_nodes, driver="GeoJSON")
ensure_columns = ["lng", "pipeline", "production", "storage"]
gas_input_nodes_s = (
gas_input_nodes.groupby(["bus", "type"])["p_nom"].sum().unstack()
gas_input_nodes.groupby(["bus", "type"])["capacity"]
.sum()
.unstack()
.reindex(columns=ensure_columns)
)
gas_input_nodes_s.columns.name = "p_nom"
gas_input_nodes_s.columns.name = "capacity"
gas_input_nodes_s.to_csv(snakemake.output.gas_input_nodes_simplified)

View File

@ -31,10 +31,7 @@ if __name__ == "__main__":
cutout = atlite.Cutout(snakemake.input.cutout).sel(time=time)
clustered_regions = (
gpd.read_file(snakemake.input.regions_onshore)
.set_index("name")
.buffer(0)
.squeeze()
gpd.read_file(snakemake.input.regions_onshore).set_index("name").buffer(0)
)
I = cutout.indicatormatrix(clustered_regions)

View File

@ -26,7 +26,7 @@ Relevant Settings
Inputs
------
- ``data/bundle/EIA_hydro_generation_2000_2014.csv``: Hydroelectricity net generation per country and year (`EIA <https://www.eia.gov/beta/international/data/browser/#/?pa=000000000000000000000000000000g&c=1028i008006gg6168g80a4k000e0ag00gg0004g800ho00g8&ct=0&ug=8&tl_id=2-A&vs=INTL.33-12-ALB-BKWH.A&cy=2014&vo=0&v=H&start=2000&end=2016>`_)
- ``data/bundle/eia_hydro_annual_generation.csv``: Hydroelectricity net generation per country and year (`EIA <https://www.eia.gov/beta/international/data/browser/#/?pa=000000000000000000000000000000g&c=1028i008006gg6168g80a4k000e0ag00gg0004g800ho00g8&ct=0&ug=8&tl_id=2-A&vs=INTL.33-12-ALB-BKWH.A&cy=2014&vo=0&v=H&start=2000&end=2016>`_)
.. image:: img/hydrogeneration.png
:scale: 33 %
@ -72,12 +72,14 @@ cc = coco.CountryConverter()
def get_eia_annual_hydro_generation(fn, countries):
# in billion kWh/a = TWh/a
df = pd.read_csv(fn, skiprows=2, index_col=1, na_values=[" ", "--"]).iloc[1:, 1:]
df = pd.read_csv(
fn, skiprows=2, index_col=1, na_values=[" ", "--"], decimal=","
).iloc[1:, 1:]
df.index = df.index.str.strip()
former_countries = {
"Former Czechoslovakia": dict(
countries=["Czech Republic", "Slovakia"], start=1980, end=1992
countries=["Czechia", "Slovakia"], start=1980, end=1992
),
"Former Serbia and Montenegro": dict(
countries=["Serbia", "Montenegro"], start=1992, end=2005

View File

@ -130,7 +130,7 @@ def build_nodal_distribution_key(hotmaps, regions, countries):
if not facilities.empty:
emissions = facilities["Emissions_ETS_2014"].fillna(
hotmaps["Emissions_EPRTR_2014"]
hotmaps["Emissions_EPRTR_2014"].dropna()
)
if emissions.sum() == 0:
key = pd.Series(1 / len(facilities), facilities.index)

View File

@ -119,7 +119,7 @@ def calculate_line_rating(n, cutout):
.apply(lambda x: int(re.findall(r"(\d+)-bundle", x)[0]))
)
# Set default number of bundles per line
relevant_lines["n_bundle"].fillna(1, inplace=True)
relevant_lines["n_bundle"] = relevant_lines["n_bundle"].fillna(1)
R *= relevant_lines["n_bundle"]
R = calculate_resistance(T=353, R_ref=R)
Imax = cutout.line_rating(shapes, R, D=0.0218, Ts=353, epsilon=0.8, alpha=0.8)
@ -146,8 +146,10 @@ if __name__ == "__main__":
)
configure_logging(snakemake)
snapshots = snakemake.params.snapshots
n = pypsa.Network(snakemake.input.base_network)
time = pd.date_range(freq="h", **snakemake.config["snapshots"])
time = pd.date_range(freq="h", **snapshots)
cutout = atlite.Cutout(snakemake.input.cutout).sel(time=time)
da = calculate_line_rating(n, cutout)

View File

@ -6,11 +6,8 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue May 16 10:37:35 2023.
This script extracts monthly fuel prices of oil, gas, coal and lignite,
as well as CO2 prices
This script extracts monthly fuel prices of oil, gas, coal and lignite, as well
as CO2 prices.
Inputs
------

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: : 2017-2023 The PyPSA-Eur Authors
# SPDX-FileCopyrightText: : 2017-2024 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: MIT
@ -10,6 +10,7 @@ Retrieves conventional powerplant capacities and locations from
these to buses and creates a ``.csv`` file. It is possible to amend the
powerplant database with custom entries provided in
``data/custom_powerplants.csv``.
Lastly, for every substation, powerplants with zero-initial capacity can be added for certain fuel types automatically.
Relevant Settings
-----------------
@ -19,6 +20,7 @@ Relevant Settings
electricity:
powerplants_filter:
custom_powerplants:
everywhere_powerplants:
.. seealso::
Documentation of the configuration file ``config/config.yaml`` at
@ -44,6 +46,7 @@ Description
-----------
The configuration options ``electricity: powerplants_filter`` and ``electricity: custom_powerplants`` can be used to control whether data should be retrieved from the original powerplants database or from custom amendmends. These specify `pandas.query <https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.query.html>`_ commands.
In addition the configuration option ``electricity: everywhere_powerplants`` can be used to place powerplants with zero-initial capacity of certain fuel types at all substations.
1. Adding all powerplants from custom:
@ -73,10 +76,18 @@ The configuration options ``electricity: powerplants_filter`` and ``electricity:
powerplants_filter: Country not in ['Germany'] and YearCommissioned <= 2015
custom_powerplants: YearCommissioned <= 2015
4. Adding powerplants at all substations for 4 conventional carrier types:
.. code:: yaml
everywhere_powerplants: ['Natural Gas', 'Coal', 'nuclear', 'OCGT']
"""
import itertools
import logging
import numpy as np
import pandas as pd
import powerplantmatching as pm
import pypsa
@ -97,6 +108,45 @@ def add_custom_powerplants(ppl, custom_powerplants, custom_ppl_query=False):
)
def add_everywhere_powerplants(ppl, substations, everywhere_powerplants):
# Create a dataframe with "everywhere_powerplants" of stated carriers at the location of all substations
everywhere_ppl = (
pd.DataFrame(
itertools.product(substations.index.values, everywhere_powerplants),
columns=["substation_index", "Fueltype"],
).merge(
substations[["x", "y", "country"]],
left_on="substation_index",
right_index=True,
)
).drop(columns="substation_index")
# PPL uses different columns names compared to substations dataframe -> rename
everywhere_ppl = everywhere_ppl.rename(
columns={"x": "lon", "y": "lat", "country": "Country"}
)
# Add default values for the powerplants
everywhere_ppl["Name"] = (
"Automatically added everywhere-powerplant " + everywhere_ppl.Fueltype
)
everywhere_ppl["Set"] = "PP"
everywhere_ppl["Technology"] = everywhere_ppl["Fueltype"]
everywhere_ppl["Capacity"] = 0.0
# Assign plausible values for the commissioning and decommissioning years
# required for multi-year models
everywhere_ppl["DateIn"] = ppl["DateIn"].min()
everywhere_ppl["DateOut"] = ppl["DateOut"].max()
# NaN values for efficiency will be replaced by the generic efficiency by attach_conventional_generators(...) in add_electricity.py later
everywhere_ppl["Efficiency"] = np.nan
return pd.concat(
[ppl, everywhere_ppl], sort=False, ignore_index=True, verify_integrity=True
)
def replace_natural_gas_technology(df):
mapping = {"Steam Turbine": "CCGT", "Combustion Engine": "OCGT"}
tech = df.Technology.replace(mapping).fillna("CCGT")
@ -149,6 +199,11 @@ if __name__ == "__main__":
if countries_wo_ppl := set(countries) - set(ppl.Country.unique()):
logging.warning(f"No powerplants known in: {', '.join(countries_wo_ppl)}")
# Add "everywhere powerplants" to all bus locations
ppl = add_everywhere_powerplants(
ppl, n.buses.query("substation_lv"), snakemake.params.everywhere_powerplants
)
substations = n.buses.query("substation_lv")
ppl = ppl.dropna(subset=["lat", "lon"])
ppl = map_country_bus(ppl, substations)

View File

@ -26,21 +26,9 @@ Relevant settings
renewable:
{technology}:
cutout:
corine:
grid_codes:
distance:
natura:
max_depth:
min_depth:
max_shore_distance:
min_shore_distance:
capacity_per_sqkm:
correction_factor:
potential:
min_p_max_pu:
clip_p_max_pu:
resource:
cutout: corine: luisa: grid_codes: distance: natura: max_depth: min_depth:
max_shore_distance: min_shore_distance: capacity_per_sqkm:
correction_factor: min_p_max_pu: clip_p_max_pu: resource:
.. seealso::
Documentation of the configuration file ``config/config.yaml`` at
@ -49,21 +37,37 @@ Relevant settings
Inputs
------
- ``data/bundle/corine/g250_clc06_V18_5.tif``: `CORINE Land Cover (CLC) <https://land.copernicus.eu/pan-european/corine-land-cover>`_ inventory on `44 classes <https://wiki.openstreetmap.org/wiki/Corine_Land_Cover#Tagging>`_ of land use (e.g. forests, arable land, industrial, urban areas).
- ``data/bundle/corine/g250_clc06_V18_5.tif``: `CORINE Land Cover (CLC)
<https://land.copernicus.eu/pan-european/corine-land-cover>`_ inventory on `44
classes <https://wiki.openstreetmap.org/wiki/Corine_Land_Cover#Tagging>`_ of
land use (e.g. forests, arable land, industrial, urban areas) at 100m
resolution.
.. image:: img/corine.png
:scale: 33 %
- ``data/bundle/GEBCO_2014_2D.nc``: A `bathymetric <https://en.wikipedia.org/wiki/Bathymetry>`_ data set with a global terrain model for ocean and land at 15 arc-second intervals by the `General Bathymetric Chart of the Oceans (GEBCO) <https://www.gebco.net/data_and_products/gridded_bathymetry_data/>`_.
- ``data/LUISA_basemap_020321_50m.tif``: `LUISA Base Map
<https://publications.jrc.ec.europa.eu/repository/handle/JRC124621>`_ land
coverage dataset at 50m resolution similar to CORINE. For codes in relation to
CORINE land cover, see `Annex 1 of the technical documentation
<https://publications.jrc.ec.europa.eu/repository/bitstream/JRC124621/technical_report_luisa_basemap_2018_v7_final.pdf>`_.
- ``data/bundle/GEBCO_2014_2D.nc``: A `bathymetric
<https://en.wikipedia.org/wiki/Bathymetry>`_ data set with a global terrain
model for ocean and land at 15 arc-second intervals by the `General
Bathymetric Chart of the Oceans (GEBCO)
<https://www.gebco.net/data_and_products/gridded_bathymetry_data/>`_.
.. image:: img/gebco_2019_grid_image.jpg
:scale: 50 %
**Source:** `GEBCO <https://www.gebco.net/data_and_products/images/gebco_2019_grid_image.jpg>`_
**Source:** `GEBCO
<https://www.gebco.net/data_and_products/images/gebco_2019_grid_image.jpg>`_
- ``resources/natura.tiff``: confer :ref:`natura`
- ``resources/offshore_shapes.geojson``: confer :ref:`shapes`
- ``resources/regions_onshore.geojson``: (if not offshore wind), confer :ref:`busregions`
- ``resources/regions_onshore.geojson``: (if not offshore wind), confer
:ref:`busregions`
- ``resources/regions_offshore.geojson``: (if offshore wind), :ref:`busregions`
- ``"cutouts/" + params["renewable"][{technology}]['cutout']``: :ref:`cutout`
- ``networks/base.nc``: :ref:`base`
@ -129,25 +133,26 @@ Description
This script functions at two main spatial resolutions: the resolution of the
network nodes and their `Voronoi cells
<https://en.wikipedia.org/wiki/Voronoi_diagram>`_, and the resolution of the
cutout grid cells for the weather data. Typically the weather data grid is
finer than the network nodes, so we have to work out the distribution of
generators across the grid cells within each Voronoi cell. This is done by
taking account of a combination of the available land at each grid cell and the
capacity factor there.
cutout grid cells for the weather data. Typically the weather data grid is finer
than the network nodes, so we have to work out the distribution of generators
across the grid cells within each Voronoi cell. This is done by taking account
of a combination of the available land at each grid cell and the capacity factor
there.
First the script computes how much of the technology can be installed at each
cutout grid cell and each node using the `GLAES
<https://github.com/FZJ-IEK3-VSA/glaes>`_ library. This uses the CORINE land use data,
Natura2000 nature reserves and GEBCO bathymetry data.
cutout grid cell and each node using the `atlite
<https://github.com/pypsa/atlite>`_ library. This uses the CORINE land use data,
LUISA land use data, Natura2000 nature reserves, GEBCO bathymetry data, and
shipping lanes.
.. image:: img/eligibility.png
:scale: 50 %
:align: center
To compute the layout of generators in each node's Voronoi cell, the
installable potential in each grid cell is multiplied with the capacity factor
at each grid cell. This is done since we assume more generators are installed
at cells with a higher capacity factor.
To compute the layout of generators in each node's Voronoi cell, the installable
potential in each grid cell is multiplied with the capacity factor at each grid
cell. This is done since we assume more generators are installed at cells with a
higher capacity factor.
.. image:: img/offwinddc-gridcell.png
:scale: 50 %
@ -165,20 +170,14 @@ at cells with a higher capacity factor.
:scale: 50 %
:align: center
This layout is then used to compute the generation availability time series
from the weather data cutout from ``atlite``.
This layout is then used to compute the generation availability time series from
the weather data cutout from ``atlite``.
Two methods are available to compute the maximal installable potential for the
node (`p_nom_max`): ``simple`` and ``conservative``:
- ``simple`` adds up the installable potentials of the individual grid cells.
If the model comes close to this limit, then the time series may slightly
overestimate production since it is assumed the geographical distribution is
proportional to capacity factor.
- ``conservative`` assertains the nodal limit by increasing capacities
proportional to the layout until the limit of an individual grid cell is
reached.
The maximal installable potential for the node (`p_nom_max`) is computed by
adding up the installable potentials of the individual grid cells. If the model
comes close to this limit, then the time series may slightly overestimate
production since it is assumed the geographical distribution is proportional to
capacity factor.
"""
import functools
import logging
@ -211,10 +210,7 @@ if __name__ == "__main__":
resource = params["resource"] # pv panel params / wind turbine params
correction_factor = params.get("correction_factor", 1.0)
capacity_per_sqkm = params["capacity_per_sqkm"]
p_nom_max_meth = params.get("potential", "conservative")
if isinstance(params.get("corine", {}), list):
params["corine"] = {"grid_codes": params["corine"]}
snapshots = snakemake.params.snapshots
if correction_factor != 1.0:
logger.info(f"correction_factor is set as {correction_factor}")
@ -224,7 +220,7 @@ if __name__ == "__main__":
else:
client = None
sns = pd.date_range(freq="h", **snakemake.config["snapshots"])
sns = pd.date_range(freq="h", **snapshots)
cutout = atlite.Cutout(snakemake.input.cutout).sel(time=sns)
regions = gpd.read_file(snakemake.input.regions)
assert not regions.empty, (
@ -241,18 +237,31 @@ if __name__ == "__main__":
if params["natura"]:
excluder.add_raster(snakemake.input.natura, nodata=0, allow_no_overlap=True)
corine = params.get("corine", {})
if "grid_codes" in corine:
codes = corine["grid_codes"]
excluder.add_raster(snakemake.input.corine, codes=codes, invert=True, crs=3035)
if corine.get("distance", 0.0) > 0.0:
codes = corine["distance_grid_codes"]
buffer = corine["distance"]
for dataset in ["corine", "luisa"]:
kwargs = {"nodata": 0} if dataset == "luisa" else {}
settings = params.get(dataset, {})
if not settings:
continue
if dataset == "luisa" and res > 50:
logger.info(
"LUISA data is available at 50m resolution, "
f"but coarser {res}m resolution is used."
)
if isinstance(settings, list):
settings = {"grid_codes": settings}
if "grid_codes" in settings:
codes = settings["grid_codes"]
excluder.add_raster(
snakemake.input.corine, codes=codes, buffer=buffer, crs=3035
snakemake.input[dataset], codes=codes, invert=True, crs=3035, **kwargs
)
if settings.get("distance", 0.0) > 0.0:
codes = settings["distance_grid_codes"]
buffer = settings["distance"]
excluder.add_raster(
snakemake.input[dataset], codes=codes, buffer=buffer, crs=3035, **kwargs
)
if "ship_threshold" in params:
if params.get("ship_threshold"):
shipping_threshold = (
params["ship_threshold"] * 8760 * 6
) # approximation because 6 years of data which is hourly collected
@ -284,15 +293,22 @@ if __name__ == "__main__":
snakemake.input.country_shapes, buffer=buffer, invert=True
)
kwargs = dict(nprocesses=nprocesses, disable_progressbar=noprogress)
if noprogress:
logger.info("Calculate landuse availabilities...")
logger.info("Calculate landuse availability...")
start = time.time()
kwargs = dict(nprocesses=nprocesses, disable_progressbar=noprogress)
availability = cutout.availabilitymatrix(regions, excluder, **kwargs)
duration = time.time() - start
logger.info(f"Completed availability calculation ({duration:2.2f}s)")
else:
availability = cutout.availabilitymatrix(regions, excluder, **kwargs)
logger.info(f"Completed landuse availability calculation ({duration:2.2f}s)")
# For Moldova and Ukraine: Overwrite parts not covered by Corine with
# externally determined available areas
if "availability_matrix_MD_UA" in snakemake.input.keys():
availability_MDUA = xr.open_dataarray(
snakemake.input["availability_matrix_MD_UA"]
)
availability.loc[availability_MDUA.coords] = availability_MDUA
area = cutout.grid.to_crs(3035).area / 1e6
area = xr.DataArray(
@ -303,8 +319,19 @@ if __name__ == "__main__":
func = getattr(cutout, resource.pop("method"))
if client is not None:
resource["dask_kwargs"] = {"scheduler": client}
logger.info("Calculate average capacity factor...")
start = time.time()
capacity_factor = correction_factor * func(capacity_factor=True, **resource)
layout = capacity_factor * area * capacity_per_sqkm
duration = time.time() - start
logger.info(f"Completed average capacity factor calculation ({duration:2.2f}s)")
logger.info("Calculate weighted capacity factor time series...")
start = time.time()
profile, capacities = func(
matrix=availability.stack(spatial=["y", "x"]),
layout=layout,
@ -314,18 +341,14 @@ if __name__ == "__main__":
**resource,
)
logger.info(f"Calculating maximal capacity per bus (method '{p_nom_max_meth}')")
if p_nom_max_meth == "simple":
p_nom_max = capacity_per_sqkm * availability @ area
elif p_nom_max_meth == "conservative":
max_cap_factor = capacity_factor.where(availability != 0).max(["x", "y"])
p_nom_max = capacities / max_cap_factor
else:
raise AssertionError(
'Config key `potential` should be one of "simple" '
f'(default) or "conservative", not "{p_nom_max_meth}"'
duration = time.time() - start
logger.info(
f"Completed weighted capacity factor time series calculation ({duration:2.2f}s)"
)
logger.info(f"Calculating maximal capacity per bus")
p_nom_max = capacity_per_sqkm * availability @ area
logger.info("Calculate average distances.")
layoutmatrix = (layout * availability).stack(spatial=["y", "x"])

18
scripts/build_retro_cost.py Normal file → Executable file
View File

@ -533,16 +533,16 @@ def prepare_temperature_data():
"""
temperature = xr.open_dataarray(snakemake.input.air_temperature).to_pandas()
d_heat = (
temperature.groupby(temperature.columns.str[:2], axis=1)
temperature.T.groupby(temperature.columns.str[:2])
.mean()
.resample("1D")
.T.resample("1D")
.mean()
< t_threshold
).sum()
temperature_average_d_heat = (
temperature.groupby(temperature.columns.str[:2], axis=1)
temperature.T.groupby(temperature.columns.str[:2])
.mean()
.apply(
.T.apply(
lambda x: get_average_temperature_during_heating_season(x, t_threshold=15)
)
)
@ -610,7 +610,7 @@ def calculate_costs(u_values, l, cost_retro, window_assumptions):
cost_retro.loc[x.name[3], "cost_var"]
* 100
* float(l)
* l_weight.loc[x.name[3]][0]
* l_weight.loc[x.name[3]].iloc[0]
+ cost_retro.loc[x.name[3], "cost_fix"]
)
* x.A_element
@ -720,6 +720,7 @@ def map_to_lstrength(l_strength, df):
.swaplevel(axis=1)
.dropna(axis=1)
)
return pd.concat([df.drop([2, 3], axis=1, level=1), l_strength_df], axis=1)
@ -800,6 +801,7 @@ def calculate_heat_losses(u_values, data_tabula, l_strength, temperature_factor)
* data_tabula.A_envelope
/ data_tabula.A_C_Ref
)
heat_transfer_perm2 = pd.concat(
[
heat_transfer_perm2,
@ -836,9 +838,9 @@ def calculate_heat_losses(u_values, data_tabula, l_strength, temperature_factor)
F_red_temp = map_to_lstrength(l_strength, F_red_temp)
Q_ht = (
heat_transfer_perm2.groupby(level=1, axis=1)
heat_transfer_perm2.T.groupby(level=1)
.sum()
.mul(F_red_temp.droplevel(0, axis=1))
.T.mul(F_red_temp.droplevel(0, axis=1))
.mul(temperature_factor.reindex(heat_transfer_perm2.index, level=0), axis=0)
)
@ -878,7 +880,7 @@ def calculate_gain_utilisation_factor(heat_transfer_perm2, Q_ht, Q_gain):
Calculates gain utilisation factor nu.
"""
# time constant of the building tau [h] = c_m [Wh/(m^2K)] * 1 /(H_tr_e+H_tb*H_ve) [m^2 K /W]
tau = c_m / heat_transfer_perm2.groupby(level=1, axis=1).sum()
tau = c_m / heat_transfer_perm2.T.groupby(axis=1).sum().T
alpha = alpha_H_0 + (tau / tau_H_0)
# heat balance ratio
gamma = (1 / Q_ht).mul(Q_gain.sum(axis=1), axis=0)

View File

@ -174,8 +174,8 @@ def nuts3(country_shapes, nuts3, nuts3pop, nuts3gdp, ch_cantons, ch_popgdp):
pd.MultiIndex.from_tuples(pop.pop("unit,geo\\time").str.split(","))
)
.loc["THS"]
.applymap(lambda x: pd.to_numeric(x, errors="coerce"))
.fillna(method="bfill", axis=1)
.map(lambda x: pd.to_numeric(x, errors="coerce"))
.bfill(axis=1)
)["2014"]
gdp = pd.read_table(nuts3gdp, na_values=[":"], delimiter=" ?\t", engine="python")
@ -184,8 +184,8 @@ def nuts3(country_shapes, nuts3, nuts3pop, nuts3gdp, ch_cantons, ch_popgdp):
pd.MultiIndex.from_tuples(gdp.pop("unit,geo\\time").str.split(","))
)
.loc["EUR_HAB"]
.applymap(lambda x: pd.to_numeric(x, errors="coerce"))
.fillna(method="bfill", axis=1)
.map(lambda x: pd.to_numeric(x, errors="coerce"))
.bfill(axis=1)
)["2014"]
cantons = pd.read_csv(ch_cantons)

View File

@ -42,8 +42,8 @@ Description
"""
import logging
import os
import zipfile
from pathlib import Path
import rioxarray
from _helpers import configure_logging
@ -62,11 +62,13 @@ if __name__ == "__main__":
xs, Xs, ys, Ys = zip(*(determine_cutout_xXyY(cutout) for cutout in cutouts))
with zipfile.ZipFile(snakemake.input.ship_density) as zip_f:
zip_f.extract("shipdensity_global.tif")
with rioxarray.open_rasterio("shipdensity_global.tif") as ship_density:
ship_density = ship_density.drop(["band"]).sel(
resources = Path(snakemake.output[0]).parent
fn = "shipdensity_global.tif"
zip_f.extract(fn, resources)
with rioxarray.open_rasterio(resources / fn) as ship_density:
ship_density = ship_density.drop_vars(["band"]).sel(
x=slice(min(xs), max(Xs)), y=slice(max(Ys), min(ys))
)
ship_density.rio.to_raster(snakemake.output[0])
os.remove("shipdensity_global.tif")
(resources / fn).unlink()

View File

@ -33,10 +33,7 @@ if __name__ == "__main__":
cutout = atlite.Cutout(snakemake.input.cutout).sel(time=time)
clustered_regions = (
gpd.read_file(snakemake.input.regions_onshore)
.set_index("name")
.buffer(0)
.squeeze()
gpd.read_file(snakemake.input.regions_onshore).set_index("name").buffer(0)
)
I = cutout.indicatormatrix(clustered_regions)

View File

@ -31,10 +31,7 @@ if __name__ == "__main__":
cutout = atlite.Cutout(snakemake.input.cutout).sel(time=time)
clustered_regions = (
gpd.read_file(snakemake.input.regions_onshore)
.set_index("name")
.buffer(0)
.squeeze()
gpd.read_file(snakemake.input.regions_onshore).set_index("name").buffer(0)
)
I = cutout.indicatormatrix(clustered_regions)

View File

@ -16,7 +16,6 @@ Relevant Settings
clustering:
cluster_network:
aggregation_strategies:
focus_weights:
solving:
@ -237,7 +236,7 @@ def distribute_clusters(n, n_clusters, focus_weights=None, solver_name="cbc"):
n_clusters >= len(N) and n_clusters <= N.sum()
), f"Number of clusters must be {len(N)} <= n_clusters <= {N.sum()} for this selection of countries."
if focus_weights is not None:
if isinstance(focus_weights, dict):
total_focus = sum(list(focus_weights.values()))
assert (
@ -271,7 +270,7 @@ def distribute_clusters(n, n_clusters, focus_weights=None, solver_name="cbc"):
)
opt = po.SolverFactory(solver_name)
if not opt.has_capability("quadratic_objective"):
if solver_name == "appsi_highs" or not opt.has_capability("quadratic_objective"):
logger.warning(
f"The configured solver `{solver_name}` does not support quadratic objectives. Falling back to `ipopt`."
)
@ -466,9 +465,13 @@ if __name__ == "__main__":
params = snakemake.params
solver_name = snakemake.config["solving"]["solver"]["name"]
solver_name = "appsi_highs" if solver_name == "highs" else solver_name
n = pypsa.Network(snakemake.input.network)
# remove integer outputs for compatibility with PyPSA v0.26.0
n.generators.drop("n_mod", axis=1, inplace=True, errors="ignore")
exclude_carriers = params.cluster_network["exclude_carriers"]
aggregate_carriers = set(n.generators.carrier) - set(exclude_carriers)
conventional_carriers = set(params.conventional_carriers)

View File

@ -0,0 +1,159 @@
# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: : 2017-2023 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: MIT
"""
Create land elibility analysis for Ukraine and Moldova with different datasets.
"""
import functools
import logging
import time
import atlite
import fiona
import geopandas as gpd
import matplotlib.pyplot as plt
import numpy as np
from _helpers import configure_logging
from atlite.gis import shape_availability
from rasterio.plot import show
logger = logging.getLogger(__name__)
def get_wdpa_layer_name(wdpa_fn, layer_substring):
"""
Get layername from file "wdpa_fn" whose name contains "layer_substring".
"""
l = fiona.listlayers(wdpa_fn)
return [_ for _ in l if layer_substring in _][0]
if __name__ == "__main__":
if "snakemake" not in globals():
from _helpers import mock_snakemake
snakemake = mock_snakemake(
"determine_availability_matrix_MD_UA", technology="solar"
)
configure_logging(snakemake)
nprocesses = None # snakemake.config["atlite"].get("nprocesses")
noprogress = not snakemake.config["atlite"].get("show_progress", True)
config = snakemake.config["renewable"][snakemake.wildcards.technology]
cutout = atlite.Cutout(snakemake.input.cutout)
regions = (
gpd.read_file(snakemake.input.regions).set_index("name").rename_axis("bus")
)
buses = regions.index
excluder = atlite.ExclusionContainer(crs=3035, res=100)
corine = config.get("corine", {})
if "grid_codes" in corine:
# Land cover codes to emulate CORINE results
if snakemake.wildcards.technology == "solar":
codes = [20, 30, 40, 50, 60, 90, 100]
elif snakemake.wildcards.technology == "onwind":
codes = [20, 30, 40, 60, 100]
elif snakemake.wildcards.technology == "offwind-ac":
codes = [80, 200]
elif snakemake.wildcards.technology == "offwind-dc":
codes = [80, 200]
else:
assert False, "technology not supported"
excluder.add_raster(
snakemake.input.copernicus, codes=codes, invert=True, crs="EPSG:4326"
)
if "distance" in corine and corine.get("distance", 0.0) > 0.0:
# Land cover codes to emulate CORINE results
if snakemake.wildcards.technology == "onwind":
codes = [50]
else:
assert False, "technology not supported"
buffer = corine["distance"]
excluder.add_raster(
snakemake.input.copernicus, codes=codes, buffer=buffer, crs="EPSG:4326"
)
if config["natura"]:
wdpa_fn = (
snakemake.input.wdpa_marine
if "offwind" in snakemake.wildcards.technology
else snakemake.input.wdpa
)
layer = get_wdpa_layer_name(wdpa_fn, "polygons")
wdpa = gpd.read_file(
wdpa_fn,
bbox=regions.geometry,
layer=layer,
).to_crs(3035)
if not wdpa.empty:
excluder.add_geometry(wdpa.geometry)
layer = get_wdpa_layer_name(wdpa_fn, "points")
wdpa_pts = gpd.read_file(
wdpa_fn,
bbox=regions.geometry,
layer=layer,
).to_crs(3035)
wdpa_pts = wdpa_pts[wdpa_pts["REP_AREA"] > 1]
wdpa_pts["buffer_radius"] = np.sqrt(wdpa_pts["REP_AREA"] / np.pi) * 1000
wdpa_pts = wdpa_pts.set_geometry(
wdpa_pts["geometry"].buffer(wdpa_pts["buffer_radius"])
)
if not wdpa_pts.empty:
excluder.add_geometry(wdpa_pts.geometry)
if "max_depth" in config:
# lambda not supported for atlite + multiprocessing
# use named function np.greater with partially frozen argument instead
# and exclude areas where: -max_depth > grid cell depth
func = functools.partial(np.greater, -config["max_depth"])
excluder.add_raster(snakemake.input.gebco, codes=func, crs=4236, nodata=-1000)
if "min_shore_distance" in config:
buffer = config["min_shore_distance"]
excluder.add_geometry(snakemake.input.country_shapes, buffer=buffer)
if "max_shore_distance" in config:
buffer = config["max_shore_distance"]
excluder.add_geometry(
snakemake.input.country_shapes, buffer=buffer, invert=True
)
if "ship_threshold" in config:
shipping_threshold = config["ship_threshold"] * 8760 * 6
func = functools.partial(np.less, shipping_threshold)
excluder.add_raster(
snakemake.input.ship_density, codes=func, crs=4326, allow_no_overlap=True
)
kwargs = dict(nprocesses=nprocesses, disable_progressbar=noprogress)
if noprogress:
logger.info("Calculate landuse availabilities...")
start = time.time()
availability = cutout.availabilitymatrix(regions, excluder, **kwargs)
duration = time.time() - start
logger.info(f"Completed availability calculation ({duration:2.2f}s)")
else:
availability = cutout.availabilitymatrix(regions, excluder, **kwargs)
regions_geometry = regions.to_crs(3035).geometry
band, transform = shape_availability(regions_geometry, excluder)
fig, ax = plt.subplots(figsize=(4, 8))
gpd.GeoSeries(regions_geometry.unary_union).plot(ax=ax, color="none")
show(band, transform=transform, cmap="Greens", ax=ax)
plt.axis("off")
plt.savefig(snakemake.output.availability_map, bbox_inches="tight", dpi=500)
# Limit results only to buses for UA and MD
buses = regions.loc[regions["country"].isin(["UA", "MD"])].index.values
availability = availability.sel(bus=buses)
# Save and plot for verification
availability.to_netcdf(snakemake.output.availability_matrix)

View File

@ -446,6 +446,10 @@ def calculate_metrics(n, label, metrics):
if "CO2Limit" in n.global_constraints.index:
metrics.at["co2_shadow", label] = n.global_constraints.at["CO2Limit", "mu"]
if "co2_sequestration_limit" in n.global_constraints.index:
metrics.at["co2_storage_shadow", label] = n.global_constraints.at[
"co2_sequestration_limit", "mu"
]
return metrics

View File

@ -28,6 +28,16 @@ idx = pd.IndexSlice
opt_name = {"Store": "e", "Line": "s", "Transformer": "s"}
def reindex_columns(df, cols):
investments = cols.levels[3]
if len(cols.names) != len(df.columns.levels):
df = pd.concat([df] * len(investments), axis=1)
df.columns = cols
df = df.reindex(cols, axis=1)
return df
def calculate_costs(n, label, costs):
investments = n.investment_periods
cols = pd.MultiIndex.from_product(
@ -39,7 +49,8 @@ def calculate_costs(n, label, costs):
],
names=costs.columns.names[:3] + ["year"],
)
costs = costs.reindex(cols, axis=1)
costs = reindex_columns(costs, cols)
for c in n.iterate_components(
n.branch_components | n.controllable_one_port_components ^ {"Load"}
@ -176,7 +187,7 @@ def calculate_capacities(n, label, capacities):
],
names=capacities.columns.names[:3] + ["year"],
)
capacities = capacities.reindex(cols, axis=1)
capacities = reindex_columns(capacities, cols)
for c in n.iterate_components(
n.branch_components | n.controllable_one_port_components ^ {"Load"}
@ -229,7 +240,7 @@ def calculate_energy(n, label, energy):
],
names=energy.columns.names[:3] + ["year"],
)
energy = energy.reindex(cols, axis=1)
energy = reindex_columns(energy, cols)
for c in n.iterate_components(n.one_port_components | n.branch_components):
if c.name in n.one_port_components:
@ -336,7 +347,7 @@ def calculate_supply_energy(n, label, supply_energy):
],
names=supply_energy.columns.names[:3] + ["year"],
)
supply_energy = supply_energy.reindex(cols, axis=1)
supply_energy = reindex_columns(supply_energy, cols)
bus_carriers = n.buses.carrier.unique()
@ -604,7 +615,7 @@ def calculate_price_statistics(n, label, price_statistics):
price_statistics.at["mean", label] = n.buses_t.marginal_price[buses].mean().mean()
price_statistics.at["standard_deviation", label] = (
n.buses_t.marginal_price[buses].droplevel(0).unstack().std()
n.buses_t.marginal_price[buses].std().std()
)
return price_statistics

View File

@ -31,7 +31,7 @@ def rename_techs_tyndp(tech):
tech = rename_techs(tech)
if "heat pump" in tech or "resistive heater" in tech:
return "power-to-heat"
elif tech in ["H2 Electrolysis", "methanation", "helmeth", "H2 liquefaction"]:
elif tech in ["H2 Electrolysis", "methanation", "H2 liquefaction"]:
return "power-to-gas"
elif tech == "H2":
return "H2 storage"
@ -495,7 +495,7 @@ def plot_ch4_map(network):
# make a fake MultiIndex so that area is correct for legend
fossil_gas.index = pd.MultiIndex.from_product([fossil_gas.index, ["fossil gas"]])
methanation_i = n.links[n.links.carrier.isin(["helmeth", "Sabatier"])].index
methanation_i = n.links.query("carrier == 'Sabatier'").index
methanation = (
abs(
n.links_t.p1.loc[:, methanation_i].mul(

View File

@ -122,7 +122,6 @@ preferred_order = pd.Index(
"gas boiler",
"gas",
"natural gas",
"helmeth",
"methanation",
"ammonia",
"hydrogen storage",
@ -453,7 +452,6 @@ def plot_carbon_budget_distribution(input_eurostat):
sns.set()
sns.set_style("ticks")
plt.style.use("seaborn-ticks")
plt.rcParams["xtick.direction"] = "in"
plt.rcParams["ytick.direction"] = "in"
plt.rcParams["xtick.labelsize"] = 20

View File

@ -63,7 +63,7 @@ import re
import numpy as np
import pandas as pd
import pypsa
from _helpers import configure_logging
from _helpers import configure_logging, find_opt, get_opt
from add_electricity import load_costs, update_transmission_costs
from pypsa.descriptors import expand_series
@ -296,42 +296,42 @@ if __name__ == "__main__":
set_line_s_max_pu(n, snakemake.params.lines["s_max_pu"])
for o in opts:
m = re.match(r"^\d+h$", o, re.IGNORECASE)
if m is not None:
n = average_every_nhours(n, m.group(0))
break
# temporal averaging
nhours_config = snakemake.params.snapshots.get("resolution", False)
nhours_wildcard = get_opt(opts, r"^\d+h$")
nhours = nhours_wildcard or nhours_config
if nhours:
n = average_every_nhours(n, nhours)
for o in opts:
m = re.match(r"^\d+seg$", o, re.IGNORECASE)
if m is not None:
# segments with package tsam
time_seg_config = snakemake.params.snapshots.get("segmentation", False)
time_seg_wildcard = get_opt(opts, r"^\d+seg$")
time_seg = time_seg_wildcard or time_seg_config
if time_seg:
solver_name = snakemake.config["solving"]["solver"]["name"]
n = apply_time_segmentation(n, m.group(0)[:-3], solver_name)
break
n = apply_time_segmentation(n, time_seg.replace("seg", ""), solver_name)
for o in opts:
if "Co2L" in o:
m = re.findall("[0-9]*\.?[0-9]+$", o)
if len(m) > 0:
co2limit = float(m[0]) * snakemake.params.co2base
Co2L_config = snakemake.params.co2limit_enable
Co2L_wildcard, co2limit_wildcard = find_opt(opts, "Co2L")
if Co2L_wildcard or Co2L_config:
if co2limit_wildcard is not None:
co2limit = co2limit_wildcard * snakemake.params.co2base
add_co2limit(n, co2limit, Nyears)
logger.info("Setting CO2 limit according to wildcard value.")
else:
add_co2limit(n, snakemake.params.co2limit, Nyears)
logger.info("Setting CO2 limit according to config value.")
break
for o in opts:
if "CH4L" in o:
m = re.findall("[0-9]*\.?[0-9]+$", o)
if len(m) > 0:
limit = float(m[0]) * 1e6
add_gaslimit(n, limit, Nyears)
CH4L_config = snakemake.params.gaslimit_enable
CH4L_wildcard, gaslimit_wildcard = find_opt(opts, "CH4L")
if CH4L_wildcard or CH4L_config:
if gaslimit_wildcard is not None:
gaslimit = gaslimit_wildcard * 1e6
add_gaslimit(n, gaslimit, Nyears)
logger.info("Setting gas usage limit according to wildcard value.")
else:
add_gaslimit(n, snakemake.params.gaslimit, Nyears)
logger.info("Setting gas usage limit according to config value.")
break
for o in opts:
if "+" not in o:
@ -352,21 +352,26 @@ if __name__ == "__main__":
sel = c.df.carrier.str.contains(carrier)
c.df.loc[sel, attr] *= factor
for o in opts:
if "Ept" in o:
emission_prices = snakemake.params.costs["emission_prices"]
Ept_config = emission_prices.get("co2_monthly_prices", False)
Ept_wildcard = "Ept" in opts
Ep_config = emission_prices.get("enable", False)
Ep_wildcard, co2_wildcard = find_opt(opts, "Ep")
if Ept_wildcard or Ept_config:
logger.info(
"Setting time dependent emission prices according spot market price"
)
add_dynamic_emission_prices(n)
elif "Ep" in o:
m = re.findall("[0-9]*\.?[0-9]+$", o)
if len(m) > 0:
logger.info("Setting emission prices according to wildcard value.")
add_emission_prices(n, dict(co2=float(m[0])))
elif Ep_wildcard or Ep_config:
if co2_wildcard is not None:
logger.info("Setting CO2 prices according to wildcard value.")
add_emission_prices(n, dict(co2=co2_wildcard))
else:
logger.info("Setting emission prices according to config value.")
add_emission_prices(n, snakemake.params.costs["emission_prices"])
break
logger.info("Setting CO2 prices according to config value.")
add_emission_prices(
n, dict(co2=snakemake.params.costs["emission_prices"]["co2"])
)
ll_type, factor = snakemake.wildcards.ll[0], snakemake.wildcards.ll[1:]
set_transmission_limit(n, ll_type, factor, costs, Nyears)
@ -379,10 +384,12 @@ if __name__ == "__main__":
p_nom_max_ext=snakemake.params.links.get("max_extension", np.inf),
)
if "ATK" in opts:
enforce_autarky(n)
elif "ATKc" in opts:
enforce_autarky(n, only_crossborder=True)
autarky_config = snakemake.params.autarky
if "ATK" in opts or autarky_config.get("enable", False):
only_crossborder = False
if "ATKc" in opts or autarky_config.get("by_country", False):
only_crossborder = True
enforce_autarky(n, only_crossborder=only_crossborder)
n.meta = dict(snakemake.config, **dict(wildcards=dict(snakemake.wildcards)))
n.export_to_netcdf(snakemake.output[0])

766
scripts/prepare_sector_network.py Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@ import logging
import tarfile
from pathlib import Path
from _helpers import configure_logging, progress_retrieve
from _helpers import configure_logging, progress_retrieve, validate_checksum
logger = logging.getLogger(__name__)
@ -65,6 +65,8 @@ if __name__ == "__main__":
disable_progress = snakemake.config["run"].get("disable_progressbar", False)
progress_retrieve(url, tarball_fn, disable=disable_progress)
validate_checksum(tarball_fn, url)
logger.info("Extracting databundle.")
tarfile.open(tarball_fn).extractall(to_fn)

View File

@ -11,7 +11,7 @@ import logging
import zipfile
from pathlib import Path
from _helpers import progress_retrieve
from _helpers import progress_retrieve, validate_checksum
logger = logging.getLogger(__name__)
@ -35,6 +35,8 @@ if __name__ == "__main__":
disable_progress = snakemake.config["run"].get("disable_progressbar", False)
progress_retrieve(url, zip_fn, disable=disable_progress)
validate_checksum(zip_fn, url)
logger.info("Extracting databundle.")
zipfile.ZipFile(zip_fn).extractall(to_fn)

View File

@ -13,7 +13,7 @@ logger = logging.getLogger(__name__)
import tarfile
from pathlib import Path
from _helpers import configure_logging, progress_retrieve
from _helpers import configure_logging, progress_retrieve, validate_checksum
if __name__ == "__main__":
if "snakemake" not in globals():
@ -34,6 +34,8 @@ if __name__ == "__main__":
disable_progress = snakemake.config["run"].get("disable_progressbar", False)
progress_retrieve(url, tarball_fn, disable=disable_progress)
validate_checksum(tarball_fn, url)
logger.info("Extracting databundle.")
tarfile.open(tarball_fn).extractall(to_fn)

View File

@ -536,6 +536,9 @@ if __name__ == "__main__":
n = pypsa.Network(snakemake.input.network)
Nyears = n.snapshot_weightings.objective.sum() / 8760
# remove integer outputs for compatibility with PyPSA v0.26.0
n.generators.drop("n_mod", axis=1, inplace=True, errors="ignore")
n, trafo_map = simplify_network_to_380(n)
technology_costs = load_costs(

View File

@ -26,15 +26,18 @@ Additionally, some extra constraints specified in :mod:`solve_network` are added
the workflow for all scenarios in the configuration file (``scenario:``)
based on the rule :mod:`solve_network`.
"""
import importlib
import logging
import os
import re
import sys
import numpy as np
import pandas as pd
import pypsa
import xarray as xr
from _benchmark import memory_logger
from _helpers import configure_logging, update_config_with_sector_opts
from _helpers import configure_logging, get_opt, update_config_with_sector_opts
from pypsa.descriptors import get_activity_mask
logger = logging.getLogger(__name__)
@ -179,9 +182,6 @@ def add_co2_sequestration_limit(n, config, limit=200):
"""
Add a global constraint on the amount of Mt CO2 that can be sequestered.
"""
n.carriers.loc["co2 stored", "co2_absorptions"] = -1
n.carriers.co2_absorptions = n.carriers.co2_absorptions.fillna(0)
limit = limit * 1e6
for o in opts:
if "seq" not in o:
@ -199,10 +199,10 @@ def add_co2_sequestration_limit(n, config, limit=200):
n.madd(
"GlobalConstraint",
names,
sense="<=",
constant=limit,
type="primary_energy",
carrier_attribute="co2_absorptions",
sense=">=",
constant=-limit,
type="operational_limit",
carrier_attribute="co2 sequestered",
investment_period=periods,
)
@ -350,7 +350,7 @@ def prepare_network(
# http://journal.frontiersin.org/article/10.3389/fenrg.2015.00055/full
# TODO: retrieve color and nice name from config
n.add("Carrier", "load", color="#dd2e23", nice_name="Load shedding")
buses_i = n.buses.query("carrier == 'AC'").index
buses_i = n.buses.index
if not np.isscalar(load_shedding):
# TODO: do not scale via sign attribute (use Eur/MWh instead of Eur/kWh)
load_shedding = 1e2 # Eur/kWh
@ -393,7 +393,7 @@ def prepare_network(
if snakemake.params["sector"]["limit_max_growth"]["enable"]:
n = add_max_growth(n, config)
if n.stores.carrier.eq("co2 stored").any():
if n.stores.carrier.eq("co2 sequestered").any():
limit = co2_sequestration_potential
add_co2_sequestration_limit(n, config, limit=limit)
@ -687,6 +687,35 @@ def add_battery_constraints(n):
n.model.add_constraints(lhs == 0, name="Link-charger_ratio")
def add_lossy_bidirectional_link_constraints(n):
if not n.links.p_nom_extendable.any() or not "reversed" in n.links.columns:
return
n.links["reversed"] = n.links.reversed.fillna(0).astype(bool)
carriers = n.links.loc[n.links.reversed, "carrier"].unique()
forward_i = n.links.query(
"carrier in @carriers and ~reversed and p_nom_extendable"
).index
def get_backward_i(forward_i):
return pd.Index(
[
re.sub(r"-(\d{4})$", r"-reversed-\1", s)
if re.search(r"-\d{4}$", s)
else s + "-reversed"
for s in forward_i
]
)
backward_i = get_backward_i(forward_i)
lhs = n.model["Link-p_nom"].loc[backward_i]
rhs = n.model["Link-p_nom"].loc[forward_i]
n.model.add_constraints(lhs == rhs, name="Link-bidirectional_sync")
def add_chp_constraints(n):
electric = (
n.links.index.str.contains("urban central")
@ -745,9 +774,13 @@ def add_pipe_retrofit_constraint(n):
"""
Add constraint for retrofitting existing CH4 pipelines to H2 pipelines.
"""
gas_pipes_i = n.links.query("carrier == 'gas pipeline' and p_nom_extendable").index
if "reversed" not in n.links.columns:
n.links["reversed"] = False
gas_pipes_i = n.links.query(
"carrier == 'gas pipeline' and p_nom_extendable and ~reversed"
).index
h2_retrofitted_i = n.links.query(
"carrier == 'H2 pipeline retrofitted' and p_nom_extendable"
"carrier == 'H2 pipeline retrofitted' and p_nom_extendable and ~reversed"
).index
if h2_retrofitted_i.empty or gas_pipes_i.empty:
@ -773,25 +806,47 @@ def extra_functionality(n, snapshots):
"""
opts = n.opts
config = n.config
if "BAU" in opts and n.generators.p_nom_extendable.any():
constraints = config["solving"].get("constraints", {})
if (
"BAU" in opts or constraints.get("BAU", False)
) and n.generators.p_nom_extendable.any():
add_BAU_constraints(n, config)
if "SAFE" in opts and n.generators.p_nom_extendable.any():
if (
"SAFE" in opts or constraints.get("SAFE", False)
) and n.generators.p_nom_extendable.any():
add_SAFE_constraints(n, config)
if "CCL" in opts and n.generators.p_nom_extendable.any():
if (
"CCL" in opts or constraints.get("CCL", False)
) and n.generators.p_nom_extendable.any():
add_CCL_constraints(n, config)
reserve = config["electricity"].get("operational_reserve", {})
if reserve.get("activate"):
add_operational_reserve_margin(n, snapshots, config)
for o in opts:
if "EQ" in o:
add_EQ_constraints(n, o)
EQ_config = constraints.get("EQ", False)
EQ_wildcard = get_opt(opts, r"^EQ+[0-9]*\.?[0-9]+(c|)")
EQ_o = EQ_wildcard or EQ_config
if EQ_o:
add_EQ_constraints(n, EQ_o.replace("EQ", ""))
add_battery_constraints(n)
add_lossy_bidirectional_link_constraints(n)
add_pipe_retrofit_constraint(n)
if n._multi_invest:
add_carbon_constraint(n, snapshots)
add_carbon_budget_constraint(n, snapshots)
add_retrofit_gas_boiler_constraint(n, snapshots)
if snakemake.params.custom_extra_functionality:
source_path = snakemake.params.custom_extra_functionality
assert os.path.exists(source_path), f"{source_path} does not exist"
sys.path.append(os.path.dirname(source_path))
module_name = os.path.splitext(os.path.basename(source_path))[0]
module = importlib.import_module(module_name)
custom_extra_functionality = getattr(module, module_name)
custom_extra_functionality(n, snapshots, snakemake)
def solve_network(n, config, solving, opts="", **kwargs):
set_of_options = solving["solver"]["options"]
@ -809,6 +864,9 @@ def solve_network(n, config, solving, opts="", **kwargs):
)
kwargs["assign_all_duals"] = cf_solving.get("assign_all_duals", False)
if kwargs["solver_name"] == "gurobi":
logging.getLogger("gurobipy").setLevel(logging.CRITICAL)
rolling_horizon = cf_solving.pop("rolling_horizon", False)
skip_iterations = cf_solving.pop("skip_iterations", False)
if not n.lines.s_nom_extendable.any():
@ -839,6 +897,9 @@ def solve_network(n, config, solving, opts="", **kwargs):
f"Solving status '{status}' with termination condition '{condition}'"
)
if "infeasible" in condition:
labels = n.model.compute_infeasibilities()
logger.info("Labels:\n" + labels)
n.model.print_infeasibilities()
raise RuntimeError("Solving status 'infeasible'")
return n