Merge remote-tracking branch 'upstream/master' into implement-floating
1
.gitignore
vendored
@ -46,6 +46,7 @@ data/costs_*.csv
|
||||
|
||||
dask-worker-space/
|
||||
publications.jrc.ec.europa.eu/
|
||||
d1gam3xoknrgr2.cloudfront.net/
|
||||
|
||||
*.org
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
"""
|
||||
|
@ -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"
|
||||
|
43
config/config.entsoe-all.yaml
Normal 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
|
@ -30,6 +30,9 @@ snapshots:
|
||||
start: "2013-03-01"
|
||||
end: "2013-03-08"
|
||||
|
||||
sector:
|
||||
central_heat_vent: true
|
||||
|
||||
electricity:
|
||||
co2limit: 100.e+6
|
||||
|
||||
|
@ -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:
|
||||
|
151
data/GDP_PPP_30arcsec_v3_mapped_default.csv
Normal 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
|
|
11
data/custom_extra_functionality.py
Normal 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
|
@ -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,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.
|
@ -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.
|
||||
|
@ -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,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,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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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."
|
||||
|
|
@ -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."
|
||||
|
|
@ -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."
|
||||
|
|
@ -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."
|
||||
|
|
@ -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.
|
@ -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.
|
@ -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."
|
||||
|
|
@ -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."
|
||||
|
|
@ -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.
|
||||
|
|
@ -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::
|
||||
|
@ -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``:
|
||||
|
BIN
doc/img/base.png
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.8 MiB |
Before Width: | Height: | Size: 789 KiB After Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 227 KiB |
@ -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
|
||||
=================
|
||||
|
||||
|
@ -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
|
||||
===================
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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>`_.
|
||||
|
@ -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``
|
||||
|
@ -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**
|
||||
|
||||
|
@ -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`.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Before Width: | Height: | Size: 728 KiB After Width: | Height: | Size: 636 KiB |
@ -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,
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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"]:
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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."
|
||||
|
@ -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])
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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.")
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
------
|
||||
|
@ -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)
|
||||
|
@ -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
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
159
scripts/determine_availability_matrix_MD_UA.py
Normal 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)
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|