add release notes, minor code improvements
This commit is contained in:
parent
d98ad95332
commit
2183e742b2
@ -28,6 +28,24 @@ Upcoming Release
|
|||||||
|
|
||||||
* Cluster residential and services heat buses by default. Can be disabled with ``cluster_heat_buses: false``.
|
* Cluster residential and services heat buses by default. Can be disabled with ``cluster_heat_buses: false``.
|
||||||
|
|
||||||
|
* Bugfix: Do not reduce district heat share when building population-weighted
|
||||||
|
energy statistics. Previously the district heating share was being multiplied
|
||||||
|
by the population weighting, reducing the DH share with multiple nodes.
|
||||||
|
|
||||||
|
* Move building of daily heat profile to its own rule
|
||||||
|
:mod:`build_hourly_heat_demand` from :mod:`prepare_sector_network`.
|
||||||
|
|
||||||
|
* In :mod:`build_energy_totals`, district heating shares are now reported in a
|
||||||
|
separate file.
|
||||||
|
|
||||||
|
* Move calculation of district heating share to its own rule
|
||||||
|
:mod:`build_district_heat_share`.
|
||||||
|
|
||||||
|
* Move building of distribution of existing heating to own rule
|
||||||
|
:mod:`build_existing_heating_distribution`. This makes the distribution of
|
||||||
|
existing heating to urban/rural, residential/services and spatially more
|
||||||
|
transparent.
|
||||||
|
|
||||||
|
|
||||||
PyPSA-Eur 0.9.0 (5th January 2024)
|
PyPSA-Eur 0.9.0 (5th January 2024)
|
||||||
==================================
|
==================================
|
||||||
|
@ -20,6 +20,12 @@ Rule ``add_existing_baseyear``
|
|||||||
|
|
||||||
.. automodule:: add_existing_baseyear
|
.. automodule:: add_existing_baseyear
|
||||||
|
|
||||||
|
Rule ``build_existing_heating_distribution``
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
.. automodule:: build_existing_heating_distribution
|
||||||
|
|
||||||
|
|
||||||
Rule ``build_ammonia_production``
|
Rule ``build_ammonia_production``
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
@ -60,10 +66,20 @@ Rule ``build_gas_network``
|
|||||||
|
|
||||||
.. automodule:: build_gas_network
|
.. automodule:: build_gas_network
|
||||||
|
|
||||||
Rule ``build_heat_demand``
|
Rule ``build_daily_heat_demand``
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
.. automodule:: build_heat_demand
|
.. automodule:: build_daily_heat_demand
|
||||||
|
|
||||||
|
Rule ``build_hourly_heat_demand``
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
.. automodule:: build_hourly_heat_demand
|
||||||
|
|
||||||
|
Rule ``build_district_heat_share``
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
.. automodule:: build_district_heat_share
|
||||||
|
|
||||||
Rule ``build_industrial_distribution_key``
|
Rule ``build_industrial_distribution_key``
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
@ -28,9 +28,10 @@ rule solve_sector_network:
|
|||||||
+ "logs/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}_memory.log",
|
+ "logs/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}_memory.log",
|
||||||
python=RESULTS
|
python=RESULTS
|
||||||
+ "logs/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}_python.log",
|
+ "logs/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}_python.log",
|
||||||
threads: config["solving"]["solver_options"][config["solving"]["solver"]["options"]].get(
|
threads:
|
||||||
"threads", 4
|
config["solving"]["solver_options"][
|
||||||
)
|
config["solving"]["solver"]["options"]
|
||||||
|
].get("threads", 4)
|
||||||
resources:
|
resources:
|
||||||
mem_mb=config["solving"]["mem"],
|
mem_mb=config["solving"]["mem"],
|
||||||
walltime=config["solving"].get("walltime", "12:00:00"),
|
walltime=config["solving"].get("walltime", "12:00:00"),
|
||||||
|
@ -451,7 +451,7 @@ def add_heating_capacities_installed_before_baseyear(
|
|||||||
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"],
|
||||||
p_nom=existing_heating[(name, f"{heat_pump_type} heat pump")][nodes] * ratio / costs.at[costs_name, "efficiency"],
|
p_nom=existing_heating.loc[nodes, (name, f"{heat_pump_type} heat pump")] * ratio / costs.at[costs_name, "efficiency"],
|
||||||
build_year=int(grouping_year),
|
build_year=int(grouping_year),
|
||||||
lifetime=costs.at[costs_name, "lifetime"],
|
lifetime=costs.at[costs_name, "lifetime"],
|
||||||
)
|
)
|
||||||
@ -470,7 +470,7 @@ def add_heating_capacities_installed_before_baseyear(
|
|||||||
* costs.at[f"{name_type} resistive heater", "fixed"]
|
* costs.at[f"{name_type} resistive heater", "fixed"]
|
||||||
),
|
),
|
||||||
p_nom=(
|
p_nom=(
|
||||||
existing_heating[(name, "resistive heater")][nodes]
|
existing_heating.loc[nodes, (name, "resistive heater")]
|
||||||
* ratio
|
* ratio
|
||||||
/ costs.at[f"{name_type} resistive heater", "efficiency"]
|
/ costs.at[f"{name_type} resistive heater", "efficiency"]
|
||||||
),
|
),
|
||||||
@ -493,7 +493,7 @@ def add_heating_capacities_installed_before_baseyear(
|
|||||||
* costs.at[f"{name_type} gas boiler", "fixed"]
|
* costs.at[f"{name_type} gas boiler", "fixed"]
|
||||||
),
|
),
|
||||||
p_nom=(
|
p_nom=(
|
||||||
existing_heating[(name, "gas boiler")][nodes]
|
existing_heating.loc[nodes, (name, "gas boiler")]
|
||||||
* ratio
|
* ratio
|
||||||
/ costs.at[f"{name_type} gas boiler", "efficiency"]
|
/ costs.at[f"{name_type} gas boiler", "efficiency"]
|
||||||
),
|
),
|
||||||
@ -514,7 +514,7 @@ def add_heating_capacities_installed_before_baseyear(
|
|||||||
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"],
|
||||||
p_nom= (
|
p_nom= (
|
||||||
existing_heating[(name, "oil boiler")][nodes]
|
existing_heating.loc[nodes, (name, "oil boiler")]
|
||||||
* ratio
|
* ratio
|
||||||
/ costs.at["decentral oil boiler", "efficiency"]),
|
/ costs.at["decentral oil boiler", "efficiency"]),
|
||||||
build_year=int(grouping_year),
|
build_year=int(grouping_year),
|
||||||
|
@ -18,7 +18,8 @@ if __name__ == "__main__":
|
|||||||
from _helpers import mock_snakemake
|
from _helpers import mock_snakemake
|
||||||
|
|
||||||
snakemake = mock_snakemake(
|
snakemake = mock_snakemake(
|
||||||
"build_heat_demands",
|
"build_daily_heat_demands",
|
||||||
|
scope="total",
|
||||||
simpl="",
|
simpl="",
|
||||||
clusters=48,
|
clusters=48,
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# SPDX-FileCopyrightText: : 2020-2023 The PyPSA-Eur Authors
|
# SPDX-FileCopyrightText: : 2020-2024 The PyPSA-Eur Authors
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
"""
|
"""
|
||||||
@ -21,9 +21,10 @@ if __name__ == "__main__":
|
|||||||
from _helpers import mock_snakemake
|
from _helpers import mock_snakemake
|
||||||
|
|
||||||
snakemake = mock_snakemake(
|
snakemake = mock_snakemake(
|
||||||
"build_heat_demands",
|
"build_district_heat_share",
|
||||||
simpl="",
|
simpl="",
|
||||||
clusters=48,
|
clusters=48,
|
||||||
|
planning_horizons="2050",
|
||||||
)
|
)
|
||||||
|
|
||||||
investment_year = int(snakemake.wildcards.planning_horizons[-4:])
|
investment_year = int(snakemake.wildcards.planning_horizons[-4:])
|
||||||
@ -68,10 +69,10 @@ if __name__ == "__main__":
|
|||||||
f"resulting in new average share of {dist_fraction_node.mean():.2%}"
|
f"resulting in new average share of {dist_fraction_node.mean():.2%}"
|
||||||
)
|
)
|
||||||
|
|
||||||
df = pd.DataFrame(dtype=float)
|
df = pd.DataFrame({
|
||||||
|
"original district heat share": district_heat_share,
|
||||||
df["original district heat share"] = district_heat_share
|
"district fraction of node": dist_fraction_node,
|
||||||
df["district fraction of node"] = dist_fraction_node
|
"urban fraction": urban_fraction
|
||||||
df["urban fraction"] = urban_fraction
|
}, dtype=float)
|
||||||
|
|
||||||
df.to_csv(snakemake.output.district_heat_share)
|
df.to_csv(snakemake.output.district_heat_share)
|
||||||
|
@ -583,10 +583,10 @@ def build_district_heat_share(countries, idees):
|
|||||||
# Missing district heating share
|
# Missing district heating share
|
||||||
dh_share = pd.read_csv(
|
dh_share = pd.read_csv(
|
||||||
snakemake.input.district_heat_share, index_col=0, usecols=[0, 1]
|
snakemake.input.district_heat_share, index_col=0, usecols=[0, 1]
|
||||||
)
|
).div(100).squeeze()
|
||||||
# make conservative assumption and take minimum from both data sets
|
# make conservative assumption and take minimum from both data sets
|
||||||
district_heat_share = pd.concat(
|
district_heat_share = pd.concat(
|
||||||
[district_heat_share, dh_share.reindex(index=district_heat_share.index) / 100], axis=1
|
[district_heat_share, dh_share.reindex_like(district_heat_share)], axis=1
|
||||||
).min(axis=1)
|
).min(axis=1)
|
||||||
|
|
||||||
district_heat_share.name = "district heat share"
|
district_heat_share.name = "district heat share"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# SPDX-FileCopyrightText: : 2020-2023 The PyPSA-Eur Authors
|
# SPDX-FileCopyrightText: : 2020-2024 The PyPSA-Eur Authors
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
"""
|
"""
|
||||||
@ -7,8 +7,6 @@ Builds table of existing heat generation capacities for initial planning
|
|||||||
horizon.
|
horizon.
|
||||||
"""
|
"""
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import sys
|
|
||||||
from pypsa.descriptors import Dict
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import country_converter as coco
|
import country_converter as coco
|
||||||
|
|
||||||
@ -17,19 +15,13 @@ cc = coco.CountryConverter()
|
|||||||
|
|
||||||
def build_existing_heating():
|
def build_existing_heating():
|
||||||
# retrieve existing heating capacities
|
# 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,
|
existing_heating = pd.read_csv(snakemake.input.existing_heating,
|
||||||
index_col=0,
|
index_col=0,
|
||||||
header=0)
|
header=0)
|
||||||
|
|
||||||
# data for Albania, Montenegro and Macedonia not included in database existing_heating.loc["Albania"] = np.nan
|
# 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["Montenegro"] = np.nan
|
||||||
existing_heating.loc["Macedonia"] = np.nan
|
existing_heating.loc["Macedonia"] = np.nan
|
||||||
|
|
||||||
@ -104,5 +96,14 @@ def build_existing_heating():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
if "snakemake" not in globals():
|
||||||
|
from _helpers import mock_snakemake
|
||||||
|
|
||||||
|
snakemake = mock_snakemake(
|
||||||
|
"build_existing_heating_distribution",
|
||||||
|
simpl="",
|
||||||
|
clusters=48,
|
||||||
|
planning_horizons=2050,
|
||||||
|
)
|
||||||
|
|
||||||
build_existing_heating()
|
build_existing_heating()
|
||||||
|
@ -6,19 +6,19 @@
|
|||||||
Build hourly heat demand time series from daily ones.
|
Build hourly heat demand time series from daily ones.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pandas as pd
|
|
||||||
import xarray as xr
|
|
||||||
from _helpers import generate_periodic_profiles, update_config_with_sector_opts
|
|
||||||
from itertools import product
|
from itertools import product
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
import xarray as xr
|
||||||
|
from _helpers import generate_periodic_profiles
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if "snakemake" not in globals():
|
if "snakemake" not in globals():
|
||||||
from _helpers import mock_snakemake
|
from _helpers import mock_snakemake
|
||||||
|
|
||||||
snakemake = mock_snakemake(
|
snakemake = mock_snakemake(
|
||||||
"build_heat_demands",
|
"build_hourly_heat_demands",
|
||||||
|
scope="total",
|
||||||
simpl="",
|
simpl="",
|
||||||
clusters=48,
|
clusters=48,
|
||||||
)
|
)
|
||||||
@ -58,12 +58,6 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
heat_demand.index.name="snapshots"
|
heat_demand.index.name="snapshots"
|
||||||
|
|
||||||
print(heat_demand)
|
ds = heat_demand.stack().to_xarray()
|
||||||
|
|
||||||
print(heat_demand.stack())
|
|
||||||
|
|
||||||
ds = heat_demand.stack().to_xarray()#xr.Dataset.from_dataframe(heat_demand)
|
|
||||||
|
|
||||||
print(ds)
|
|
||||||
|
|
||||||
ds.to_netcdf(snakemake.output.heat_demand)
|
ds.to_netcdf(snakemake.output.heat_demand)
|
||||||
|
@ -1654,7 +1654,7 @@ def build_heat_demand(n):
|
|||||||
heat_demand[name] = (
|
heat_demand[name] = (
|
||||||
heat_demand_shape[name] / heat_demand_shape[name].sum()
|
heat_demand_shape[name] / heat_demand_shape[name].sum()
|
||||||
).multiply(pop_weighted_energy_totals[f"total {sector} {use}"]) * 1e6
|
).multiply(pop_weighted_energy_totals[f"total {sector} {use}"]) * 1e6
|
||||||
electric_heat_supply[f"{sector} {use}"] = (
|
electric_heat_supply[name] = (
|
||||||
heat_demand_shape[name] / heat_demand_shape[name].sum()
|
heat_demand_shape[name] / heat_demand_shape[name].sum()
|
||||||
).multiply(pop_weighted_energy_totals[f"electricity {sector} {use}"]) * 1e6
|
).multiply(pop_weighted_energy_totals[f"electricity {sector} {use}"]) * 1e6
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user