new script to interpolate industry sector ratios today to tomorrow

For each country we gradually switch industry processes from today's
specific energy carrier usage per ton material output to the
best-in-class energy consumption of tomorrow in the
industry_sector_ratios.csv.

This is done on a per-country basis. The ratio of today to tomorrow's
energy consumption is set with the
config["industry"]["sector_ratios_fraction_future"] parameter.
This commit is contained in:
Tom Brown 2024-02-14 18:15:18 +01:00 committed by Fabian Neumann
parent 7f3ad792a9
commit e14bae345b
4 changed files with 123 additions and 9 deletions

View File

@ -636,6 +636,14 @@ industry:
2040: 0.12
2045: 0.16
2050: 0.20
sector_ratios_fraction_future:
2020: 0.0
2025: 0.1
2030: 0.3
2035: 0.5
2040: 0.7
2045: 0.9
2050: 1.0
basic_chemicals_without_NH3_production_today: 69. #Mt/a, = 86 Mtethylene-equiv - 17 MtNH3
HVC_production_today: 52.
MWh_elec_per_tHVC_mechanical_recycling: 0.547

View File

@ -433,6 +433,30 @@ rule build_industry_sector_ratios:
"../scripts/build_industry_sector_ratios.py"
rule build_industry_sector_ratios_intermediate:
params:
industry=config["industry"],
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",
output:
industry_sector_ratios=RESOURCES + "industry_sector_ratios_{planning_horizons}.csv",
threads: 1
resources:
mem_mb=1000,
log:
LOGS + "build_industry_sector_ratios_{planning_horizons}.log",
benchmark:
BENCHMARKS + "build_industry_sector_ratios_{planning_horizons}"
conda:
"../envs/environment.yaml"
script:
"../scripts/build_industry_sector_ratios_intermediate.py"
rule build_industrial_production_per_country:
params:
industry=config["industry"],
@ -535,7 +559,7 @@ rule build_industrial_production_per_node:
rule build_industrial_energy_demand_per_node:
input:
industry_sector_ratios=RESOURCES + "industry_sector_ratios.csv",
industry_sector_ratios=RESOURCES + "industry_sector_ratios_{planning_horizons}.csv",
industrial_production_per_node=RESOURCES
+ "industrial_production_elec_s{simpl}_{clusters}_{planning_horizons}.csv",
industrial_energy_demand_per_node_today=RESOURCES

View File

@ -19,23 +19,28 @@ if __name__ == "__main__":
planning_horizons=2030,
)
# import EU ratios df as csv
# import ratios
fn = snakemake.input.industry_sector_ratios
industry_sector_ratios = pd.read_csv(fn, index_col=0)
sector_ratios = pd.read_csv(fn,
header=[0,1],
index_col=0)
# material demand per node and industry (kton/a)
# material demand per node and industry (Mton/a)
fn = snakemake.input.industrial_production_per_node
nodal_production = pd.read_csv(fn, index_col=0)
nodal_production = pd.read_csv(fn, index_col=0) / 1e3
# energy demand today to get current electricity
fn = snakemake.input.industrial_energy_demand_per_node_today
nodal_today = pd.read_csv(fn, index_col=0)
# final energy consumption per node and industry (TWh/a)
nodal_df = nodal_production.dot(industry_sector_ratios.T)
nodal_sector_ratios = pd.concat({node: sector_ratios[node[:2]] for node in nodal_production.index},
axis=1)
# convert GWh to TWh and ktCO2 to MtCO2
nodal_df *= 0.001
nodal_production_stacked = nodal_production.stack()
nodal_production_stacked.index.names = [None,None]
# final energy consumption per node and industry (TWh/a)
nodal_df = (nodal_sector_ratios.multiply(nodal_production_stacked)).T.groupby(level=0).sum()
rename_sectors = {
"elec": "electricity",

View File

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: : 2020-2024 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: MIT
"""
Build specific energy consumption by carrier and industries and by country,
that interpolates between the current average energy consumption (from 2015-2020)
and the ideal future best-in-class consumption.
"""
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
production = production.unstack().swaplevel()
# in MWh/t
future_sector_ratios = pd.read_csv(snakemake.input.industry_sector_ratios,
index_col=0)
production.index.names = [None,None]
today_sector_ratios = demand.div(production, axis=1)
today_sector_ratios.drop(columns=today_sector_ratios.columns[today_sector_ratios.isna().all()],
inplace=True)
rename = pd.Series(today_sector_ratios.index,
today_sector_ratios.index)
rename["waste"] = "biomass"
rename["electricity"] = "elec"
rename["solid"] = "coke"
rename["gas"] = "methane"
rename["other"] = "biomass"
rename["liquid"] = "naphtha"
today_sector_ratios.rename(rename,
inplace=True)
fraction_future = get(params["sector_ratios_fraction_future"], year)
intermediate_sector_ratios = {}
for ct in today_sector_ratios.columns.unique(level=0):
intermediate_sector_ratio = future_sector_ratios.copy()
intermediate_sector_ratio.loc[today_sector_ratios[ct].index,today_sector_ratios[ct].columns] = (fraction_future*intermediate_sector_ratio.loc[today_sector_ratios[ct].index,today_sector_ratios[ct].columns]
+ (1 - fraction_future)*today_sector_ratios[ct])
intermediate_sector_ratios[ct] = intermediate_sector_ratio
intermediate_sector_ratios = pd.concat(intermediate_sector_ratios, axis=1)
intermediate_sector_ratios.to_csv(snakemake.output.industry_sector_ratios)
if __name__ == "__main__":
if "snakemake" not in globals():
from _helpers import mock_snakemake
snakemake = mock_snakemake("build_industry_sector_ratios_intermediate")
year = int(snakemake.wildcards.planning_horizons[-4:])
params = snakemake.params.industry
build_industry_sector_ratios_intermediate()