109 lines
4.1 KiB
Python
109 lines
4.1 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
# SPDX-FileCopyrightText: : 2020-2023 The PyPSA-Eur Authors
|
||
|
#
|
||
|
# SPDX-License-Identifier: MIT
|
||
|
"""
|
||
|
Builds table of existing heat generation capacities for initial planning
|
||
|
horizon.
|
||
|
"""
|
||
|
import pandas as pd
|
||
|
import sys
|
||
|
from pypsa.descriptors import Dict
|
||
|
import numpy as np
|
||
|
import country_converter as coco
|
||
|
|
||
|
cc = coco.CountryConverter()
|
||
|
|
||
|
|
||
|
def build_existing_heating():
|
||
|
# retrieve existing heating capacities
|
||
|
techs = [
|
||
|
"gas boiler",
|
||
|
"oil boiler",
|
||
|
"resistive heater",
|
||
|
"air heat pump",
|
||
|
"ground heat pump",
|
||
|
]
|
||
|
|
||
|
existing_heating = pd.read_csv(snakemake.input.existing_heating,
|
||
|
index_col=0,
|
||
|
header=0)
|
||
|
|
||
|
# data for Albania, Montenegro and Macedonia not included in database existing_heating.loc["Albania"] = np.nan
|
||
|
existing_heating.loc["Montenegro"] = np.nan
|
||
|
existing_heating.loc["Macedonia"] = np.nan
|
||
|
|
||
|
existing_heating.fillna(0.0, inplace=True)
|
||
|
|
||
|
# convert GW to MW
|
||
|
existing_heating *= 1e3
|
||
|
|
||
|
existing_heating.index = cc.convert(existing_heating.index, to="iso2")
|
||
|
|
||
|
# coal and oil boilers are assimilated to oil boilers
|
||
|
existing_heating["oil boiler"] = existing_heating["oil boiler"] + existing_heating["coal boiler"]
|
||
|
existing_heating.drop(["coal boiler"], axis=1, inplace=True)
|
||
|
|
||
|
# distribute technologies to nodes by population
|
||
|
pop_layout = pd.read_csv(snakemake.input.clustered_pop_layout,
|
||
|
index_col=0)
|
||
|
|
||
|
nodal_heating = existing_heating.loc[pop_layout.ct]
|
||
|
nodal_heating.index = pop_layout.index
|
||
|
nodal_heating = nodal_heating.multiply(pop_layout.fraction, axis=0)
|
||
|
|
||
|
district_heat_info = pd.read_csv(snakemake.input.district_heat_share,
|
||
|
index_col=0)
|
||
|
dist_fraction = district_heat_info["district fraction of node"]
|
||
|
urban_fraction = district_heat_info["urban fraction"]
|
||
|
|
||
|
energy_layout = pd.read_csv(snakemake.input.clustered_pop_energy_layout,
|
||
|
index_col=0)
|
||
|
|
||
|
uses = ["space", "water"]
|
||
|
sectors = ["residential", "services"]
|
||
|
|
||
|
nodal_sectoral_totals = pd.DataFrame(dtype=float)
|
||
|
|
||
|
for sector in sectors:
|
||
|
nodal_sectoral_totals[sector] = energy_layout[[f"total {sector} {use}" for use in uses]].sum(axis=1)
|
||
|
|
||
|
nodal_sectoral_fraction = nodal_sectoral_totals.div(nodal_sectoral_totals.sum(axis=1),
|
||
|
axis=0)
|
||
|
|
||
|
|
||
|
nodal_heat_name_fraction = pd.DataFrame(dtype=float)
|
||
|
|
||
|
nodal_heat_name_fraction["urban central"] = dist_fraction
|
||
|
|
||
|
for sector in sectors:
|
||
|
|
||
|
nodal_heat_name_fraction[f"{sector} rural"] = nodal_sectoral_fraction[sector]*(1 - urban_fraction)
|
||
|
nodal_heat_name_fraction[f"{sector} urban decentral"] = nodal_sectoral_fraction[sector]*(urban_fraction - dist_fraction)
|
||
|
|
||
|
|
||
|
nodal_heat_name_tech = pd.concat({name : nodal_heating .multiply(nodal_heat_name_fraction[name],
|
||
|
axis=0) for name in nodal_heat_name_fraction.columns},
|
||
|
axis=1,
|
||
|
names=["heat name","technology"])
|
||
|
|
||
|
|
||
|
#move all ground HPs to rural, all air to urban
|
||
|
|
||
|
for sector in sectors:
|
||
|
nodal_heat_name_tech[(f"{sector} rural","ground heat pump")] += (nodal_heat_name_tech[("urban central","ground heat pump")]*nodal_sectoral_fraction[sector]
|
||
|
+ nodal_heat_name_tech[(f"{sector} urban decentral","ground heat pump")])
|
||
|
nodal_heat_name_tech[(f"{sector} urban decentral","ground heat pump")] = 0.
|
||
|
|
||
|
nodal_heat_name_tech[(f"{sector} urban decentral","air heat pump")] += nodal_heat_name_tech[(f"{sector} rural","air heat pump")]
|
||
|
nodal_heat_name_tech[(f"{sector} rural","air heat pump")] = 0.
|
||
|
|
||
|
nodal_heat_name_tech[("urban central","ground heat pump")] = 0.
|
||
|
|
||
|
nodal_heat_name_tech.to_csv(snakemake.output.existing_heating_distribution)
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
|
||
|
build_existing_heating()
|