Skip to content

Commit

Permalink
Merge pull request #835 from openego/features/#817-add-new-industrial…
Browse files Browse the repository at this point in the history
…-electricity-demand

Add new industrial electricity demands for eGon100RE
  • Loading branch information
ClaraBuettner committed Jul 28, 2022
2 parents 1a0b1e8 + 1c3617e commit 92af857
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 13 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,8 @@ Changed
`#797 <https://github.com/openego/eGon-data/issues/797>`_
* Add coordinates to non AC buses abroad in eGon100RE
`#803 <https://github.com/openego/eGon-data/issues/803>`_
* Integrate additional industrial electricity demands for eGon100RE
`#817 <https://github.com/openego/eGon-data/issues/817>`_

Bug Fixes
---------
Expand Down
4 changes: 4 additions & 0 deletions src/egon/data/datasets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ demandregio_cts_ind_demand:
schema: 'boundaries'
table: 'vg250_krs'
new_consumers_2035: 'new_largescale_consumers_nep.csv'
new_consumers_2050:
"pes-demand-today": "industrial_energy_demand_per_country_today.csv"
"pes-production-tomorrow": "industrial_production_per_country_tomorrow_2050.csv"
"pes-sector-ratios": "industry_sector_ratios.csv"
wz_definitions:
"CTS": 'CTS_WZ_definition.csv'
"industry": 'ind_WZ_definition.csv'
Expand Down
150 changes: 137 additions & 13 deletions src/egon/data/datasets/demandregio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from disaggregator import data, spatial, config

except ImportError as e:
pass
pass

# will be later imported from another file ###
Base = declarative_base()
Expand All @@ -33,7 +33,7 @@ class DemandRegio(Dataset):
def __init__(self, dependencies):
super().__init__(
name="DemandRegio",
version="0.0.3",
version="0.0.4",
dependencies=dependencies,
tasks=(
clone_and_install,
Expand Down Expand Up @@ -124,7 +124,7 @@ def create_tables():


def data_in_boundaries(df):
""" Select rows with nuts3 code within boundaries, used for testmode
"""Select rows with nuts3 code within boundaries, used for testmode
Parameters
----------
Expand Down Expand Up @@ -160,7 +160,7 @@ def data_in_boundaries(df):


def insert_cts_ind_wz_definitions():
""" Insert demandregio's definitions of CTS and industrial branches
"""Insert demandregio's definitions of CTS and industrial branches
Returns
-------
Expand Down Expand Up @@ -206,7 +206,7 @@ def insert_cts_ind_wz_definitions():


def match_nuts3_bl():
""" Function that maps the federal state to each nuts3 region
"""Function that maps the federal state to each nuts3 region
Returns
-------
Expand All @@ -233,8 +233,129 @@ def match_nuts3_bl():
return df.set_index("nuts")


def adjust_ind_pes(ec_cts_ind):
"""
Adjust electricity demand of industrial consumers due to electrification
of process heat based on assumptions of pypsa-eur-sec.
Parameters
----------
ec_cts_ind : pandas.DataFrame
Industrial demand without additional electrification
Returns
-------
ec_cts_ind : pandas.DataFrame
Industrial demand with additional electrification
"""

pes_path = (
Path(".") / "data_bundle_egon_data" / "pypsa_eur_sec" / "resources"
)

sources = egon.data.config.datasets()["demandregio_cts_ind_demand"][
"sources"
]["new_consumers_2050"]

# Extract today's industrial demand from pypsa-eur-sec
demand_today = pd.read_csv(
pes_path / sources["pes-demand-today"],
header=None,
).transpose()

# Filter data
demand_today[1].fillna("carrier", inplace=True)
demand_today = demand_today[
(demand_today[0] == "DE") | (demand_today[1] == "carrier")
].drop([0, 2], axis="columns")

demand_today = (
demand_today.transpose()
.set_index(0)
.transpose()
.set_index("carrier")
.transpose()
.loc["electricity"]
.astype(float)
)

# Calculate future industrial demand from pypsa-eur-sec
# based on production and energy demands per carrier ('sector ratios')
prod_tomorrow = pd.read_csv(pes_path / sources["pes-production-tomorrow"])

prod_tomorrow = prod_tomorrow[prod_tomorrow["kton/a"] == "DE"].set_index(
"kton/a"
)

sector_ratio = (
pd.read_csv(pes_path / sources["pes-sector-ratios"])
.set_index("MWh/tMaterial")
.loc["elec"]
)

demand_tomorrow = prod_tomorrow.multiply(
sector_ratio.div(1000)
).transpose()["DE"]

# Calculate changes of electrical demand per sector in pypsa-eur-sec
change = pd.DataFrame(
(demand_tomorrow / demand_today)
/ (demand_tomorrow / demand_today).sum()
)

# Drop rows without changes
change = change[~change[0].isnull()]

# Map industrial branches of pypsa-eur-sec to WZ2008 used in demandregio
change["wz"] = change.index.map(
{
"Alumina production": 24,
"Aluminium - primary production": 24,
"Aluminium - secondary production": 24,
"Ammonia": 20,
"Basic chemicals (without ammonia)": 20,
"Cement": 23,
"Ceramics & other NMM": 23,
"Electric arc": 24,
"Food, beverages and tobacco": 10,
"Glass production": 23,
"Integrated steelworks": 24,
"Machinery Equipment": 28,
"Other Industrial Sectors": 32,
"Other chemicals": 20,
"Other non-ferrous metals": 24,
"Paper production": 17,
"Pharmaceutical products etc.": 21,
"Printing and media reproduction": 18,
"Pulp production": 17,
"Textiles and leather": 13,
"Transport Equipment": 29,
"Wood and wood products": 16,
}
)

# Group by WZ2008
shares_per_wz = change.groupby("wz")[0].sum()

# Calculate addtional demands needed to meet future demand of pypsa-eur-sec
addtional_mwh = shares_per_wz.multiply(
demand_tomorrow.sum() * 1000000 - ec_cts_ind.sum().sum()
)

# Calulate overall industrial demand for eGon100RE
final_mwh = addtional_mwh + ec_cts_ind[addtional_mwh.index].sum()

# Linear scale the industrial demands per nuts3 and wz to meet final demand
ec_cts_ind[addtional_mwh.index] *= (
final_mwh / ec_cts_ind[addtional_mwh.index].sum()
)

return ec_cts_ind


def adjust_cts_ind_nep(ec_cts_ind, sector):
""" Add electrical demand of new largescale CTS und industrial consumers
"""Add electrical demand of new largescale CTS und industrial consumers
according to NEP 2021, scneario C 2035. Values per federal state are
linear distributed over all CTS branches and nuts3 regions.
Expand Down Expand Up @@ -351,7 +472,7 @@ def disagg_households_power(


def insert_hh_demand(scenario, year, engine):
""" Calculates electrical demands of private households using demandregio's
"""Calculates electrical demands of private households using demandregio's
disaggregator and insert results into the database.
Parameters
Expand Down Expand Up @@ -391,7 +512,7 @@ def insert_hh_demand(scenario, year, engine):


def insert_cts_ind(scenario, year, engine, target_values):
""" Calculates electrical demands of CTS and industry using demandregio's
"""Calculates electrical demands of CTS and industry using demandregio's
disaggregator, adjusts them according to resulting values of NEP 2021 or
JRC IDEES and insert results into the database.
Expand Down Expand Up @@ -434,6 +555,9 @@ def insert_cts_ind(scenario, year, engine, target_values):
# include new largescale consumers according to NEP 2021
if scenario == "eGon2035":
ec_cts_ind = adjust_cts_ind_nep(ec_cts_ind, sector)
# include new industrial demands due to sector coupling
if (scenario == "eGon100RE") & (sector == "industry"):
ec_cts_ind = adjust_ind_pes(ec_cts_ind)

# Select demands for nuts3-regions in boundaries (needed for testmode)
ec_cts_ind = data_in_boundaries(ec_cts_ind)
Expand All @@ -455,7 +579,7 @@ def insert_cts_ind(scenario, year, engine, target_values):


def insert_household_demand():
""" Insert electrical demands for households according to
"""Insert electrical demands for households according to
demandregio using its disaggregator-tool in MWh
Returns
Expand All @@ -482,7 +606,7 @@ def insert_household_demand():


def insert_cts_ind_demands():
""" Insert electricity demands per nuts3-region in Germany according to
"""Insert electricity demands per nuts3-region in Germany according to
demandregio using its disaggregator-tool in MWh
Returns
Expand Down Expand Up @@ -527,7 +651,7 @@ def insert_cts_ind_demands():


def insert_society_data():
""" Insert population and number of households per nuts3-region in Germany
"""Insert population and number of households per nuts3-region in Germany
according to demandregio using its disaggregator-tool
Returns
Expand Down Expand Up @@ -578,7 +702,7 @@ def insert_society_data():


def insert_timeseries_per_wz(sector, year):
""" Insert normalized electrical load time series for the selected sector
"""Insert normalized electrical load time series for the selected sector
Parameters
----------
Expand Down Expand Up @@ -644,7 +768,7 @@ def insert_timeseries_per_wz(sector, year):


def timeseries_per_wz():
""" Calcultae and insert normalized timeseries per wz for cts and industry
"""Calcultae and insert normalized timeseries per wz for cts and industry
Returns
-------
Expand Down

0 comments on commit 92af857

Please sign in to comment.