Merge pull request #918 from PyPSA/fneum/cp-from-ariadne2

Merge from `ariadne2`
This commit is contained in:
Fabian Neumann 2024-02-07 18:56:58 +01:00 committed by GitHub
commit 682ff4fee3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 51 additions and 27 deletions

View File

@ -357,6 +357,7 @@ existing_capacities:
grouping_years_power: [1980, 1985, 1990, 1995, 2000, 2005, 2010, 2015, 2020, 2025, 2030] grouping_years_power: [1980, 1985, 1990, 1995, 2000, 2005, 2010, 2015, 2020, 2025, 2030]
grouping_years_heat: [1980, 1985, 1990, 1995, 2000, 2005, 2010, 2015, 2019] # these should not extend 2020 grouping_years_heat: [1980, 1985, 1990, 1995, 2000, 2005, 2010, 2015, 2019] # these should not extend 2020
threshold_capacity: 10 threshold_capacity: 10
default_heating_lifetime: 20
conventional_carriers: conventional_carriers:
- lignite - lignite
- coal - coal
@ -482,6 +483,7 @@ sector:
resistive_heaters: true resistive_heaters: true
oil_boilers: false oil_boilers: false
biomass_boiler: true biomass_boiler: true
overdimension_individual_heating: 1.1 #to cover demand peaks bigger than data
chp: true chp: true
micro_chp: false micro_chp: false
solar_thermal: true solar_thermal: true

View File

@ -3,4 +3,5 @@ grouping_years_power ,--,A list of years,Intervals to group existing capacities
grouping_years_heat ,--,A list of years below 2020,Intervals to group existing capacities for heat grouping_years_heat ,--,A list of years below 2020,Intervals to group existing capacities for heat
threshold_capacity ,MW,float,Capacities generators and links of below threshold are removed during add_existing_capacities threshold_capacity ,MW,float,Capacities generators and links of below threshold are removed during add_existing_capacities
default_heating_lifetime ,years,int,Default lifetime for heating technologies
conventional_carriers ,--,"Any subset of {uranium, coal, lignite, oil} ",List of conventional power plants to include in the sectoral network conventional_carriers ,--,"Any subset of {uranium, coal, lignite, oil} ",List of conventional power plants to include in the sectoral network

1 Unit Values Description
3 grouping_years_heat -- A list of years below 2020 Intervals to group existing capacities for heat
4 threshold_capacity MW float Capacities generators and links of below threshold are removed during add_existing_capacities
5 conventional_carriers default_heating_lifetime -- years Any subset of {uranium, coal, lignite, oil} int List of conventional power plants to include in the sectoral network Default lifetime for heating technologies
6 conventional_carriers -- Any subset of {uranium, coal, lignite, oil} List of conventional power plants to include in the sectoral network
7

View File

@ -10,7 +10,7 @@ BASt emobility statistics,emobility/,unknown,http://www.bast.de/DE/Verkehrstechn
BDEW heating profile,heat_load_profile_BDEW.csv,unknown,https://github.com/oemof/demandlib BDEW heating profile,heat_load_profile_BDEW.csv,unknown,https://github.com/oemof/demandlib
heating profiles for Aarhus,heat_load_profile_DK_AdamJensen.csv,unknown,Adam Jensen MA thesis at Aarhus University heating profiles for Aarhus,heat_load_profile_DK_AdamJensen.csv,unknown,Adam Jensen MA thesis at Aarhus University
co2 budgets,co2_budget.csv,CC BY 4.0,https://arxiv.org/abs/2004.11009 co2 budgets,co2_budget.csv,CC BY 4.0,https://arxiv.org/abs/2004.11009
existing heating potentials,existing_infrastructure/existing_heating_raw.csv,unknown,https://ec.europa.eu/energy/studies/mapping-and-analyses-current-and-future-2020-2030-heatingcooling-fuel-deployment_en?redir=1 existing heating potentials,existing_infrastructure/existing_heating_raw.csv,unknown,https://energy.ec.europa.eu/publications/mapping-and-analyses-current-and-future-2020-2030-heatingcooling-fuel-deployment-fossilrenewables-1_en
IRENA existing VRE capacities,existing_infrastructure/{solar|onwind|offwind}_capcity_IRENA.csv,unknown,https://www.irena.org/Statistics/Download-Data IRENA existing VRE capacities,existing_infrastructure/{solar|onwind|offwind}_capcity_IRENA.csv,unknown,https://www.irena.org/Statistics/Download-Data
USGS ammonia production,myb1-2017-nitro.xls,unknown,https://www.usgs.gov/centers/nmic/nitrogen-statistics-and-information USGS ammonia production,myb1-2017-nitro.xls,unknown,https://www.usgs.gov/centers/nmic/nitrogen-statistics-and-information
hydrogen salt cavern potentials,h2_salt_caverns_GWh_per_sqkm.geojson,CC BY 4.0,https://doi.org/10.1016/j.ijhydene.2019.12.161 https://doi.org/10.20944/preprints201910.0187.v1 hydrogen salt cavern potentials,h2_salt_caverns_GWh_per_sqkm.geojson,CC BY 4.0,https://doi.org/10.1016/j.ijhydene.2019.12.161 https://doi.org/10.20944/preprints201910.0187.v1

1 description file/folder licence source
10 BDEW heating profile heat_load_profile_BDEW.csv unknown https://github.com/oemof/demandlib
11 heating profiles for Aarhus heat_load_profile_DK_AdamJensen.csv unknown Adam Jensen MA thesis at Aarhus University
12 co2 budgets co2_budget.csv CC BY 4.0 https://arxiv.org/abs/2004.11009
13 existing heating potentials existing_infrastructure/existing_heating_raw.csv unknown https://ec.europa.eu/energy/studies/mapping-and-analyses-current-and-future-2020-2030-heatingcooling-fuel-deployment_en?redir=1 https://energy.ec.europa.eu/publications/mapping-and-analyses-current-and-future-2020-2030-heatingcooling-fuel-deployment-fossilrenewables-1_en
14 IRENA existing VRE capacities existing_infrastructure/{solar|onwind|offwind}_capcity_IRENA.csv unknown https://www.irena.org/Statistics/Download-Data
15 USGS ammonia production myb1-2017-nitro.xls unknown https://www.usgs.gov/centers/nmic/nitrogen-statistics-and-information
16 hydrogen salt cavern potentials h2_salt_caverns_GWh_per_sqkm.geojson CC BY 4.0 https://doi.org/10.1016/j.ijhydene.2019.12.161 https://doi.org/10.20944/preprints201910.0187.v1

View File

@ -66,6 +66,7 @@ boilers,--,"{true, false}",Add option for transforming gas into heat using gas b
resistive_heaters,--,"{true, false}",Add option for transforming electricity into heat using resistive heaters (independently from 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 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 biomass_boiler,--,"{true, false}",Add option for transforming biomass into heat using boilers
overdimension_individual_heating,--,"float",Add option for overdimensioning individual heating systems by a certain factor. This allows them to cover heat demand peaks e.g. 10% higher than those in the data with a setting of 1.1.
chp,--,"{true, false}",Add option for using Combined Heat and Power (CHP) chp,--,"{true, false}",Add option for using Combined Heat and Power (CHP)
micro_chp,--,"{true, false}",Add option for using Combined Heat and Power (CHP) for decentral areas. micro_chp,--,"{true, false}",Add option for using Combined Heat and Power (CHP) for decentral areas.
solar_thermal,--,"{true, false}",Add option for using solar thermal to generate heat. solar_thermal,--,"{true, false}",Add option for using solar thermal to generate heat.

1 Unit Values Description
66 resistive_heaters -- {true, false} Add option for transforming electricity into heat using resistive heaters (independently from gas boilers)
67 oil_boilers -- {true, false} Add option for transforming oil into heat using boilers
68 biomass_boiler -- {true, false} Add option for transforming biomass into heat using boilers
69 overdimension_individual_heating -- float Add option for overdimensioning individual heating systems by a certain factor. This allows them to cover heat demand peaks e.g. 10% higher than those in the data with a setting of 1.1.
70 chp -- {true, false} Add option for using Combined Heat and Power (CHP)
71 micro_chp -- {true, false} Add option for using Combined Heat and Power (CHP) for decentral areas.
72 solar_thermal -- {true, false} Add option for using solar thermal to generate heat.

View File

@ -10,6 +10,19 @@ Release Notes
Upcoming Release Upcoming Release
================ ================
* Add new default to overdimension heating in individual buildings. This allows
them to cover heat demand peaks e.g. 10% higher than those in the data. The
disadvantage of manipulating the costs is that the capacity is then not quite
right. This way at least the costs are right.
* Add option to specify to set a default heating lifetime for existing heating
(``existing_capacities: default_heating_lifetime:``).
* Correctly source the existing heating technologies for buildings since the
source URL has changed. It represents the year 2012 and is only for
buildings, not district heating. So the capacities for urban central are now
set to zero from this source.
* Remove long-deprecated function ``attach_extendable_generators`` in :mod:`add_electricity`. * Remove long-deprecated function ``attach_extendable_generators`` in :mod:`add_electricity`.
* The filtering of power plants in the ``config.default.yaml`` has been updated regarding phased-out power plants in 2023. * The filtering of power plants in the ``config.default.yaml`` has been updated regarding phased-out power plants in 2023.

View File

@ -402,13 +402,6 @@ def add_heating_capacities_installed_before_baseyear(
""" """
logger.debug(f"Adding heating capacities installed before {baseyear}") logger.debug(f"Adding heating capacities installed before {baseyear}")
# Add existing heating capacities, data comes from the study
# "Mapping and analyses of the current and future (2020 - 2030)
# heating/cooling fuel deployment (fossil/renewables) "
# https://ec.europa.eu/energy/studies/mapping-and-analyses-current-and-future-2020-2030-heatingcooling-fuel-deployment_en?redir=1
# file: "WP2_DataAnnex_1_BuildingTechs_ForPublication_201603.xls" -> "existing_heating_raw.csv".
# TODO start from original file
existing_heating = pd.read_csv( existing_heating = pd.read_csv(
snakemake.input.existing_heating_distribution, header=[0, 1], index_col=0 snakemake.input.existing_heating_distribution, header=[0, 1], index_col=0
) )
@ -436,7 +429,7 @@ def add_heating_capacities_installed_before_baseyear(
if int(grouping_year) + default_lifetime <= int(baseyear): if int(grouping_year) + default_lifetime <= int(baseyear):
continue continue
# installation is assumed to be linear for the past 25 years (default lifetime) # installation is assumed to be linear for the past default_lifetime years
ratio = (int(grouping_year) - int(grouping_years[i - 1])) / default_lifetime ratio = (int(grouping_year) - int(grouping_years[i - 1])) / default_lifetime
n.madd( n.madd(
@ -543,12 +536,6 @@ def add_heating_capacities_installed_before_baseyear(
], ],
) )
# drop assets which are at the end of their lifetime
links_i = n.links[(n.links.build_year + n.links.lifetime <= baseyear)].index
logger.info("Removing following links because at end of their lifetime:")
logger.info(links_i)
n.mremove("Link", links_i)
if __name__ == "__main__": if __name__ == "__main__":
if "snakemake" not in globals(): if "snakemake" not in globals():
@ -605,7 +592,9 @@ if __name__ == "__main__":
.to_pandas() .to_pandas()
.reindex(index=n.snapshots) .reindex(index=n.snapshots)
) )
default_lifetime = snakemake.params.costs["fill_values"]["lifetime"] default_lifetime = snakemake.params.existing_capacities[
"default_heating_lifetime"
]
add_heating_capacities_installed_before_baseyear( add_heating_capacities_installed_before_baseyear(
n, n,
baseyear, baseyear,

View File

@ -16,6 +16,14 @@ cc = coco.CountryConverter()
def build_existing_heating(): def build_existing_heating():
# retrieve existing heating capacities # retrieve existing heating capacities
# Add existing heating capacities, data comes from the study
# "Mapping and analyses of the current and future (2020 - 2030)
# heating/cooling fuel deployment (fossil/renewables) "
# https://energy.ec.europa.eu/publications/mapping-and-analyses-current-and-future-2020-2030-heatingcooling-fuel-deployment-fossilrenewables-1_en
# file: "WP2_DataAnnex_1_BuildingTechs_ForPublication_201603.xls" -> "existing_heating_raw.csv".
# data is for buildings only (i.e. NOT district heating) and represents the year 2012
# TODO start from original file
existing_heating = pd.read_csv( existing_heating = pd.read_csv(
snakemake.input.existing_heating, index_col=0, header=0 snakemake.input.existing_heating, index_col=0, header=0
) )
@ -67,17 +75,17 @@ def build_existing_heating():
nodal_sectoral_totals.sum(axis=1), axis=0 nodal_sectoral_totals.sum(axis=1), axis=0
) )
nodal_heat_name_fraction = pd.DataFrame(dtype=float) nodal_heat_name_fraction = pd.DataFrame(index=district_heat_info.index, dtype=float)
nodal_heat_name_fraction["urban central"] = dist_fraction nodal_heat_name_fraction["urban central"] = 0.0
for sector in sectors: for sector in sectors:
nodal_heat_name_fraction[f"{sector} rural"] = nodal_sectoral_fraction[ nodal_heat_name_fraction[f"{sector} rural"] = nodal_sectoral_fraction[
sector sector
] * (1 - urban_fraction) ] * (1 - urban_fraction)
nodal_heat_name_fraction[f"{sector} urban decentral"] = nodal_sectoral_fraction[ nodal_heat_name_fraction[f"{sector} urban decentral"] = (
sector nodal_sectoral_fraction[sector] * urban_fraction
] * (urban_fraction - dist_fraction) )
nodal_heat_name_tech = pd.concat( nodal_heat_name_tech = pd.concat(
{ {

View File

@ -1680,6 +1680,8 @@ def add_heat(n, costs):
heat_demand = build_heat_demand(n) heat_demand = build_heat_demand(n)
overdim_factor = options["overdimension_individual_heating"]
district_heat_info = pd.read_csv(snakemake.input.district_heat_share, index_col=0) district_heat_info = pd.read_csv(snakemake.input.district_heat_share, index_col=0)
dist_fraction = district_heat_info["district fraction of node"] dist_fraction = district_heat_info["district fraction of node"]
urban_fraction = district_heat_info["urban fraction"] urban_fraction = district_heat_info["urban fraction"]
@ -1814,7 +1816,8 @@ def add_heat(n, costs):
carrier=f"{name} {heat_pump_type} heat pump", carrier=f"{name} {heat_pump_type} heat pump",
efficiency=efficiency, efficiency=efficiency,
capital_cost=costs.at[costs_name, "efficiency"] capital_cost=costs.at[costs_name, "efficiency"]
* costs.at[costs_name, "fixed"], * costs.at[costs_name, "fixed"]
* overdim_factor,
p_nom_extendable=True, p_nom_extendable=True,
lifetime=costs.at[costs_name, "lifetime"], lifetime=costs.at[costs_name, "lifetime"],
) )
@ -1883,7 +1886,9 @@ def add_heat(n, costs):
bus1=nodes + f" {name} heat", bus1=nodes + f" {name} heat",
carrier=name + " resistive heater", carrier=name + " resistive heater",
efficiency=costs.at[key, "efficiency"], efficiency=costs.at[key, "efficiency"],
capital_cost=costs.at[key, "efficiency"] * costs.at[key, "fixed"], capital_cost=costs.at[key, "efficiency"]
* costs.at[key, "fixed"]
* overdim_factor,
p_nom_extendable=True, p_nom_extendable=True,
lifetime=costs.at[key, "lifetime"], lifetime=costs.at[key, "lifetime"],
) )
@ -1901,7 +1906,9 @@ def add_heat(n, costs):
carrier=name + " gas boiler", carrier=name + " gas boiler",
efficiency=costs.at[key, "efficiency"], efficiency=costs.at[key, "efficiency"],
efficiency2=costs.at["gas", "CO2 intensity"], efficiency2=costs.at["gas", "CO2 intensity"],
capital_cost=costs.at[key, "efficiency"] * costs.at[key, "fixed"], capital_cost=costs.at[key, "efficiency"]
* costs.at[key, "fixed"]
* overdim_factor,
lifetime=costs.at[key, "lifetime"], lifetime=costs.at[key, "lifetime"],
) )
@ -1915,7 +1922,8 @@ def add_heat(n, costs):
bus=nodes + f" {name} heat", bus=nodes + f" {name} heat",
carrier=name + " solar thermal", carrier=name + " solar thermal",
p_nom_extendable=True, p_nom_extendable=True,
capital_cost=costs.at[name_type + " solar thermal", "fixed"], capital_cost=costs.at[name_type + " solar thermal", "fixed"]
* overdim_factor,
p_max_pu=solar_thermal[nodes], p_max_pu=solar_thermal[nodes],
lifetime=costs.at[name_type + " solar thermal", "lifetime"], lifetime=costs.at[name_type + " solar thermal", "lifetime"],
) )
@ -2348,7 +2356,8 @@ def add_biomass(n, costs):
carrier=name + " biomass boiler", carrier=name + " biomass boiler",
efficiency=costs.at["biomass boiler", "efficiency"], efficiency=costs.at["biomass boiler", "efficiency"],
capital_cost=costs.at["biomass boiler", "efficiency"] capital_cost=costs.at["biomass boiler", "efficiency"]
* costs.at["biomass boiler", "fixed"], * costs.at["biomass boiler", "fixed"]
* options["overdimension_individual_heating"],
marginal_cost=costs.at["biomass boiler", "pelletizing cost"], marginal_cost=costs.at["biomass boiler", "pelletizing cost"],
lifetime=costs.at["biomass boiler", "lifetime"], lifetime=costs.at["biomass boiler", "lifetime"],
) )
@ -2806,7 +2815,8 @@ def add_industry(n, costs):
efficiency=costs.at["decentral oil boiler", "efficiency"], efficiency=costs.at["decentral oil boiler", "efficiency"],
efficiency2=costs.at["oil", "CO2 intensity"], efficiency2=costs.at["oil", "CO2 intensity"],
capital_cost=costs.at["decentral oil boiler", "efficiency"] capital_cost=costs.at["decentral oil boiler", "efficiency"]
* costs.at["decentral oil boiler", "fixed"], * costs.at["decentral oil boiler", "fixed"]
* options["overdimension_individual_heating"],
lifetime=costs.at["decentral oil boiler", "lifetime"], lifetime=costs.at["decentral oil boiler", "lifetime"],
) )