Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify Industry Sector Ratios #293

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Changelog
- Modify industry sector ratios for Germany to reach climate neutrality by 2045 in the industrial sector.
- Restricting the maximum capacity of CurrentPolicies and minus scenarios to the 'uba Projektionsbericht'
- Restricting Fischer Tropsch capacity addition with config[solving][limit_DE_FT_cap]
- Except for Current Policies force a minimum of 5 GW of electrolysis capacity in Germany
Expand Down
71 changes: 39 additions & 32 deletions config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#run
run:
prefix: 20241121-fix-missing-gas-capa
prefix: 20241202-modify-sector-ratios

name:
# - CurrentPolicies
Expand Down Expand Up @@ -62,7 +62,7 @@ scenario:
ll:
- vopt
clusters:
- 27 #current options: 27, 49
- 49 #current options: 27, 49
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please revert this before merging

opts:
- ''
sector_opts:
Expand Down Expand Up @@ -206,38 +206,38 @@ clustering:
# print(fw.div(fw.sum()).subtract(5e-5).round(4).to_dict().__repr__().replace(",","\n"))
focus_weights:
# 27 nodes: 8 for Germany, 3 for Italy, 2 each for Denmark, UK and Spain, 1 per each of other 10 "Stromnachbarn"
'DE': 0.2966
'AT': 0.0370
'BE': 0.0370
'CH': 0.0370
'CZ': 0.0370
'DK': 0.0741
'FR': 0.0370
'GB': 0.0741
'LU': 0.0370
'NL': 0.0370
'NO': 0.0370
'PL': 0.0370
'SE': 0.0370
'ES': 0.0741
'IT': 0.1111
# 'DE': 0.2966
# 'AT': 0.0370
# 'BE': 0.0370
# 'CH': 0.0370
# 'CZ': 0.0370
# 'DK': 0.0741
# 'FR': 0.0370
# 'GB': 0.0741
# 'LU': 0.0370
# 'NL': 0.0370
# 'NO': 0.0370
# 'PL': 0.0370
# 'SE': 0.0370
# 'ES': 0.0741
# 'IT': 0.1111
# high spatial resolution: change clusters to 49
# 49 nodes: 30 for Germany, 3 for Italy, 2 each for Denmark, UK and Spain, 1 per each of other 10 "Stromnachbarn"
# 'DE': 0.6124
# 'AT': 0.0204
# 'BE': 0.0204
# 'CH': 0.0204
# 'CZ': 0.0204
# 'DK': 0.0408
# 'FR': 0.0204
# 'GB': 0.0408
# 'LU': 0.0204
# 'NL': 0.0204
# 'NO': 0.0204
# 'PL': 0.0204
# 'SE': 0.0204
# 'ES': 0.0408
# 'IT': 0.0612
'DE': 0.6124
'AT': 0.0204
'BE': 0.0204
'CH': 0.0204
'CZ': 0.0204
'DK': 0.0408
'FR': 0.0204
'GB': 0.0408
'LU': 0.0204
'NL': 0.0204
'NO': 0.0204
'PL': 0.0204
'SE': 0.0204
'ES': 0.0408
'IT': 0.0612
temporal:
resolution_sector: 365H

Expand Down Expand Up @@ -349,6 +349,13 @@ sector:

# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#industry
industry:
sector_ratios_fraction_future_DE:
2020: 0.0
2025: 0.1
2030: 0.3
2035: 0.6
2040: 0.9
2045: 1.0
ammonia: false
St_primary_fraction:
2020: 0.6
Expand Down
39 changes: 39 additions & 0 deletions workflow/Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,45 @@ use rule build_industrial_production_per_node from pypsaeur with:
),


rule modify_sector_ratios:
params:
future_DE=config_provider("industry", "sector_ratios_fraction_future_DE"),
input:
industry_sector_ratios=resources("industry_sector_ratios.csv"),
industrial_energy_demand_per_country_today=resources(
"industrial_energy_demand_per_country_today.csv"
),
industrial_production_per_country=resources(
"industrial_production_per_country.csv"
),
sector_ratios=resources("industry_sector_ratios_{planning_horizons}.csv"),
output:
sector_ratios_modified=resources(
"industry_sector_ratios_{planning_horizons}-modified.csv"
),
resources:
mem_mb=2000,
log:
logs("modify_industry_sector_ratios_{planning_horizons}}.log"),
script:
"scripts/modify_sector_ratios.py"


ruleorder: modify_sector_ratios > build_industry_sector_ratios_intermediate


use rule build_industrial_energy_demand_per_node from pypsaeur with:
input:
**{
k: v
for k, v in rules.build_industrial_energy_demand_per_node.input.items()
if k != "industry_sector_ratios"
},
industry_sector_ratios=resources(
"industry_sector_ratios_{planning_horizons}-modified.csv"
),


rule build_wasserstoff_kernnetz:
params:
kernnetz=config_provider("wasserstoff_kernnetz"),
Expand Down
5 changes: 3 additions & 2 deletions workflow/scripts/build_scenarios.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,9 @@ def write_to_scenario_yaml(input, output, scenarios, df):
df.loc[:, fallback_reference_scenario, :], planning_horizons
)


if reference_scenario.startswith("KN2045plus"): # Still waiting for REMIND uploads
if reference_scenario.startswith(
"KN2045plus"
): # Still waiting for REMIND uploads
fallback_reference_scenario = reference_scenario

co2_budget_source = config[scenario]["co2_budget_DE_source"]
Expand Down
119 changes: 119 additions & 0 deletions workflow/scripts/modify_sector_ratios.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: : 2020-2024 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: MIT
"""
Overwrite the sector ratios for Germany to represent climate neutrality in 2045 already compared to 2050 for the rest of Europe.

Relevant Settings
-----------------

.. code:: yaml

industry:
sector_ratios_fraction_future_DE:

Inputs
------

- ``resources/industry_sector_ratios.csv``
- ``resources/industrial_energy_demand_per_country_today.csv``
- ``resources/industrial_production_per_country.csv``

Outputs
-------

- ``resources/industry_sector_ratios_{planning_horizons}-modified.csv``

"""
import os
import sys

paths = ["workflow/submodules/pypsa-eur/scripts", "../submodules/pypsa-eur/scripts"]
for path in paths:
sys.path.insert(0, os.path.abspath(path))

import numpy as np
import pandas as pd
from prepare_sector_network import get


def build_industry_sector_ratios_intermediate():

# in TWh/a
demand = pd.read_csv(
snakemake.input.industrial_energy_demand_per_country_today,
header=[0, 1],
index_col=0,
)

# in Mt/a
production = (
pd.read_csv(snakemake.input.industrial_production_per_country, index_col=0)
/ 1e3
).stack()
production.index.names = [None, None]

# in MWh/t
future_sector_ratios = pd.read_csv(
snakemake.input.industry_sector_ratios, index_col=0
)

today_sector_ratios = demand.div(production, axis=1).replace([np.inf, -np.inf], 0)

today_sector_ratios.dropna(how="all", axis=1, inplace=True)

rename = {
"waste": "biomass",
"electricity": "elec",
"solid": "coke",
"gas": "methane",
"other": "biomass",
"liquid": "naphtha",
}
today_sector_ratios = today_sector_ratios.rename(rename).groupby(level=0).sum()

# custom DE pathway
fraction_DE = get(snakemake.params.future_DE, year)

intermediate_sector_ratios_DE = {}

DE_sector_ratios = today_sector_ratios.loc[:, "DE"].reindex_like(
future_sector_ratios
)
missing_mask = DE_sector_ratios.isna().all()
DE_sector_ratios.loc[:, missing_mask] = future_sector_ratios.loc[:, missing_mask]
DE_sector_ratios.loc[:, ~missing_mask] = DE_sector_ratios.loc[
:, ~missing_mask
].fillna(future_sector_ratios)
intermediate_sector_ratios_DE["DE"] = (
DE_sector_ratios * (1 - fraction_DE) + future_sector_ratios * fraction_DE
)
# make dictionary to dataframe
intermediate_sector_ratios_DE = pd.concat(intermediate_sector_ratios_DE, axis=1)

# read in original sector ratios
intermediate_sector_ratios = pd.read_csv(
snakemake.input.sector_ratios, header=[0, 1], index_col=0
)

# update DE sector ratios
intermediate_sector_ratios.loc[:, "DE"] = intermediate_sector_ratios_DE["DE"].values

intermediate_sector_ratios.to_csv(snakemake.output.sector_ratios_modified)


if __name__ == "__main__":
if "snakemake" not in globals():

from _helpers import mock_snakemake

snakemake = mock_snakemake(
"modify_sector_ratios",
planning_horizons="2045",
run="KN2045_Bal_v4",
)

year = int(snakemake.wildcards.planning_horizons)

build_industry_sector_ratios_intermediate()
Loading