Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add n largest district heating systems as subnodes #147

Open
wants to merge 34 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
083e6ab
added new script for DH modifications
cpschau Jun 12, 2024
6a9286c
function for update of urban heat loads
cpschau Jun 14, 2024
dbc2c37
Preserve aggregate DH demand
cpschau Jun 17, 2024
8f3d743
add subnodes and loads
cpschau Jul 31, 2024
1778dc1
load chps, change function header
cpschau Aug 6, 2024
b69cd06
merge main
cpschau Aug 19, 2024
77f0bdd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 19, 2024
4df060c
Merge branch 'main' into add_subnodes
lkstrp Aug 19, 2024
7bc5749
changed data source to Fernwärmeatlas; changed script structure; incl…
cpschau Aug 20, 2024
9944878
fixed nodal EB with gas boiler; fixed snakemake issues
cpschau Aug 21, 2024
c7ec368
changed input for add_brownfield
cpschau Aug 21, 2024
1fbecbc
geolocations from file instead of geocoding
cpschau Aug 21, 2024
c97e56e
added links and stores except from heat pumps; adapted snakemake inpu…
cpschau Aug 23, 2024
fe47933
add ASHP
cpschau Aug 27, 2024
c081ff4
fix bugs for heat pump integration
cpschau Aug 27, 2024
abf8fc1
Merge remote-tracking branch 'origin/main' into add_subnodes
cpschau Sep 16, 2024
e799e12
Merge remote-tracking branch 'origin/main' into add_subnodes
cpschau Sep 17, 2024
f5e8d2b
adjustments to cop netcdf and existing heating distribution
cpschau Sep 18, 2024
cd75664
fix extension of existing_heating df
cpschau Sep 19, 2024
5b9ed82
fix snakemake issue for existing heating
cpschau Sep 19, 2024
2d6949e
dirty fix for workflow and optional output
cpschau Sep 20, 2024
1a2ed80
match CHP by LAU shapes
cpschau Sep 24, 2024
913da0b
added industry heat load
cpschau Sep 24, 2024
8dbb0cd
make workflow run after merge
cpschau Oct 22, 2024
ade4e85
add heat vent and remove load shedder
cpschau Oct 23, 2024
ce3d85b
fix workflow
cpschau Nov 14, 2024
1901d24
uncomment get_data
cpschau Nov 14, 2024
e76741b
add type hints and docstrings; clean-up unused code snippets; simplif…
cpschau Dec 2, 2024
f5d4363
change variable name row to subnode
cpschau Dec 2, 2024
892ead0
add fernwaermeatlas data
cpschau Dec 2, 2024
11b3ec9
change docstring to numpy
cpschau Dec 12, 2024
c1aaae8
add comments
cpschau Dec 12, 2024
57aa50c
another docstring conversion to numpy format
cpschau Dec 13, 2024
af60c52
one more numpy docstring
cpschau Dec 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#run
run:
prefix: 202413costupdate
prefix: 20242008_dh_subnodes_off
name:
# - CurrentPolicies
- KN2045_Bal_v4
Expand Down Expand Up @@ -279,6 +279,7 @@ sector:
2040: 0.6
2045: 0.8
2050: 1.0
add_subnodes: false
central_heat_vent: true
co2_spatial: true
biomass_spatial: true
Expand Down
167 changes: 167 additions & 0 deletions data/fernwaermeatlas/cities_geolocations.geojson

Large diffs are not rendered by default.

Binary file added data/fernwaermeatlas/fernwaermeatlas.xlsx
Binary file not shown.
190 changes: 164 additions & 26 deletions workflow/Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ rule retrieve_ariadne_database:

def input_profile_offwind(w):
return {
f"profile_{tech}": resources(f"profile_{tech}.nc")
f"profile_{tech}": resources("profile_{clusters}_" + tech + ".nc")
for tech in ["offwind-ac", "offwind-dc", "offwind-float"]
if (tech in config["electricity"]["renewable_carriers"])
if (tech in config_provider("electricity", "renewable_carriers")(w))
}


Expand All @@ -130,7 +130,7 @@ use rule prepare_sector_network from pypsaeur with:
if k != "district_heat_share"
},
district_heat_share=resources(
"district_heat_share_elec_s{simpl}_{clusters}_{planning_horizons}-modified.csv"
"district_heat_share_base_s_{clusters}_{planning_horizons}-modified.csv"
),


Expand Down Expand Up @@ -170,13 +170,15 @@ rule build_mobility_demand:
leitmodelle=config_provider("iiasa_database", "leitmodelle"),
input:
ariadne=resources("ariadne_database.csv"),
clustered_pop_layout=resources("pop_layout_elec_s{simpl}_{clusters}.csv"),
clustered_pop_layout=resources("pop_layout_base_s_{clusters}.csv"),
output:
mobility_demand=resources(
"mobility_demand_aladin_{simpl}_{clusters}_{planning_horizons}.csv"
"mobility_demand_aladin_{clusters}_{planning_horizons}.csv"
),
resources:
mem_mb=1000,
log:
logs("build_mobility_demand_{clusters}_{planning_horizons}.log"),
script:
"scripts/build_mobility_demand.py"

Expand All @@ -196,6 +198,53 @@ rule build_egon_data:
"scripts/build_egon_data.py"


baseyear_value = config["scenario"]["planning_horizons"][0]


rule add_district_heating_subnodes:
params:
district_heating=config_provider("sector", "district_heating"),
baseyear=config_provider("scenario", "planning_horizons", 0),
input:
network=RESULTS
+ "prenetworks/base_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
heating_technologies_nuts3=resources("heating_technologies_nuts3.geojson"),
nuts3=resources("nuts3_shapes.geojson"),
regions_onshore=resources(
"regions_onshore_base_s_{clusters}.geojson"
),
fernwaermeatlas="data/fernwaermeatlas/fernwaermeatlas.xlsx",
cities="data/fernwaermeatlas/cities_geolocations.geojson",
cop_profiles=resources("cop_profiles_base_s_{clusters}_{planning_horizons}.nc"),
existing_heating_distribution=resources(
f"existing_heating_distribution_base_s_{{clusters}}_{baseyear_value}.csv"
),
lau=storage(
"https://gisco-services.ec.europa.eu/distribution/v2/lau/download/ref-lau-2021-01m.geojson.zip",
keep_local=True,
),
output:
network=RESULTS
+ "prenetworks/base-extended_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
district_heating_subnodes=resources(
"district_heating_subnodes_base_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.geojson"
),
cop_profiles_extended=resources(
"cop_profiles_base-extended_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc"
),
existing_heating_distribution_extended=(
resources(
"existing_heating_distribution_base-extended_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.csv"
)
if baseyear_value != "{planning_horizons}"
else []
),
resources:
mem_mb=1000,
script:
"scripts/add_district_heating_subnodes.py"


ruleorder: modify_district_heat_share > build_district_heat_share


Expand All @@ -204,13 +253,13 @@ rule modify_district_heat_share:
district_heating=config_provider("sector", "district_heating"),
input:
heating_technologies_nuts3=resources("heating_technologies_nuts3.geojson"),
regions_onshore=resources("regions_onshore_elec_s{simpl}_{clusters}.geojson"),
regions_onshore=resources("regions_onshore_base_s_{clusters}.geojson"),
district_heat_share=resources(
"district_heat_share_elec_s{simpl}_{clusters}_{planning_horizons}.csv"
"district_heat_share_base_s_{clusters}_{planning_horizons}.csv"
),
output:
district_heat_share=resources(
"district_heat_share_elec_s{simpl}_{clusters}_{planning_horizons}-modified.csv"
"district_heat_share_base_s_{clusters}_{planning_horizons}-modified.csv"
),
resources:
mem_mb=1000,
Expand Down Expand Up @@ -243,30 +292,49 @@ rule modify_prenetwork:
land_transport_electric_share=config_provider(
"sector", "land_transport_electric_share"
),
onshore_nep_force=config_provider("onshore_nep_force"),
offshore_nep_force=config_provider("offshore_nep_force"),
shipping_methanol_efficiency=config_provider(
"sector", "shipping_methanol_efficiency"
),
shipping_oil_efficiency=config_provider("sector", "shipping_oil_efficiency"),
shipping_methanol_share=config_provider("sector", "shipping_methanol_share"),
mwh_meoh_per_tco2=config_provider("sector", "MWh_MeOH_per_tCO2"),
input:
costs_modifications="ariadne-data/costs_{planning_horizons}-modifications.csv",
network=RESULTS
+ "prenetworks-brownfield/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
+ "prenetworks-brownfield/base_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
wkn=(
resources("wasserstoff_kernnetz_elec_s{simpl}_{clusters}.csv")
resources("wasserstoff_kernnetz_base_s_{clusters}.csv")
if config_provider("wasserstoff_kernnetz", "enable")
else []
),
costs=resources("costs_{planning_horizons}.csv"),
aladin_demand=resources(
"mobility_demand_aladin_{simpl}_{clusters}_{planning_horizons}.csv"
"mobility_demand_aladin_{clusters}_{planning_horizons}.csv"
),
transport_data=resources("transport_data_s{simpl}_{clusters}.csv"),
transport_data=resources("transport_data_s_{clusters}.csv"),
biomass_potentials=resources(
"biomass_potentials_s{simpl}_{clusters}_{planning_horizons}.csv"
"biomass_potentials_s_{clusters}_{planning_horizons}.csv"
),
industrial_demand=resources(
"industrial_energy_demand_elec_s{simpl}_{clusters}_{planning_horizons}.csv"
"industrial_energy_demand_base_s_{clusters}_{planning_horizons}.csv"
),
pop_weighted_energy_totals=resources(
"pop_weighted_energy_totals_s_{clusters}.csv"
),
shipping_demand=resources("shipping_demand_s_{clusters}.csv"),
regions_onshore=resources("regions_onshore_base_s_{clusters}.geojson"),
regions_offshore=resources("regions_offshore_base_s_{clusters}.geojson"),
offshore_connection_points="ariadne-data/offshore_connection_points.csv",
output:
network=RESULTS
+ "prenetworks-final/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
+ "prenetworks-final/base_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
resources:
mem_mb=1000,
log:
RESULTS
+ "logs/modify_prenetwork_base_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.log",
script:
"scripts/modify_prenetwork.py"

Expand All @@ -291,7 +359,7 @@ use rule solve_sector_network_myopic from pypsaeur with:
if k != "network"
},
network=RESULTS
+ "prenetworks-final/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
+ "prenetworks-final/base_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
co2_totals_name=resources("co2_totals.csv"),


Expand Down Expand Up @@ -328,24 +396,94 @@ rule retrieve_mastr:


rule build_existing_chp_de:
params:
add_district_heating_subnodes=config_provider(
"sector", "district_heating", "add_subnodes"
),
input:
mastr_biomass="data/mastr/bnetza_open_mastr_2023-08-08_B_biomass.csv",
mastr_combustion="data/mastr/bnetza_open_mastr_2023-08-08_B_combustion.csv",
plz_mapping=storage(
"https://raw.githubusercontent.com/WZBSocialScienceCenter/plz_geocoord/master/plz_geocoord.csv",
keep_local=True,
),
busmap=resources("networks/base.nc"),
regions=resources("regions_onshore_base_s_{clusters}.geojson"),
district_heating_subnodes=(
resources(
"district_heating_subnodes_base_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.geojson"
)
if config["sector"]["district_heating"].get("add_subnodes", True)
else []
),
output:
german_chp=resources("german_chp.csv"),
german_chp=resources(
"german_chp_base_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.csv"
),
script:
"scripts/build_existing_chp_de.py"


use rule add_existing_baseyear from pypsaeur with:
params:
**{k: v for k, v in rules.add_existing_baseyear.params.items()},
add_district_heating_subnodes=config_provider(
"sector", "district_heating", "add_subnodes"
),
input:
**{
k: v
for k, v in rules.add_existing_baseyear.input.items()
if k != "network"
and k != "cop_profiles"
and k != "existing_heating_distribution"
},
network=(
RESULTS
+ "prenetworks/base-extended_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc"
if config["sector"]["district_heating"].get("add_subnodes", True)
else RESULTS
+ "prenetworks/base_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc"
),
cop_profiles=(
resources(
"cop_profiles_base-extended_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc"
)
if config["sector"]["district_heating"].get("add_subnodes", True)
else resources("cop_profiles_base_s_{clusters}_{planning_horizons}.nc")
),
custom_powerplants=resources(
"german_chp_base_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.csv"
),
existing_heating_distribution=(
resources(
"existing_heating_distribution_base-extended_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.csv"
)
if config["sector"]["district_heating"].get("add_subnodes", True)
else resources(
"existing_heating_distribution_base_s_{clusters}_{planning_horizons}.csv"
)
),


def input_profile_tech_brownfield(w):
return {
f"profile_{tech}": resources("profile_{clusters}_" + tech + ".nc")
for tech in config_provider("electricity", "renewable_carriers")(w)
if tech != "hydro"
}


use rule add_brownfield from pypsaeur with:
input:
**rules.add_existing_baseyear.input,
custom_powerplants=resources("german_chp.csv"),
unpack(input_profile_tech_brownfield),
**{k: v for k, v in rules.add_brownfield.input.items() if k != "network"},
network=(
RESULTS
+ "prenetworks/base-extended_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc"
if config["sector"]["district_heating"].get("add_subnodes", True)
else RESULTS
+ "prenetworks/base_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc"
),


use rule build_existing_heating_distribution from pypsaeur with:
Expand Down Expand Up @@ -438,11 +576,11 @@ rule cluster_wasserstoff_kernnetz:
kernnetz=config_provider("wasserstoff_kernnetz"),
input:
cleaned_h2_network=resources("wasserstoff_kernnetz.csv"),
regions_onshore=resources("regions_onshore_elec_s{simpl}_{clusters}.geojson"),
regions_offshore=resources("regions_offshore_elec_s{simpl}_{clusters}.geojson"),
regions_onshore=resources("regions_onshore_base_s_{clusters}.geojson"),
regions_offshore=resources("regions_offshore_base_s_{clusters}.geojson"),
output:
clustered_h2_network=resources(
"wasserstoff_kernnetz_elec_s{simpl}_{clusters}.csv"
"wasserstoff_kernnetz_base_s_{clusters}.csv"
),
script:
"scripts/cluster_wasserstoff_kernnetz.py"
Expand Down Expand Up @@ -476,14 +614,14 @@ rule export_ariadne_variables:
template=resources("template_ariadne_database.xlsx"),
industry_demands=expand(
resources(
"industrial_energy_demand_elec_s{simpl}_{clusters}_{planning_horizons}.csv"
"industrial_energy_demand_base_s_{clusters}_{planning_horizons}.csv"
),
**config["scenario"],
allow_missing=True,
),
networks=expand(
RESULTS
+ "postnetworks/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
+ "postnetworks/base_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
**config["scenario"],
allow_missing=True,
),
Expand Down Expand Up @@ -587,7 +725,7 @@ rule build_scenarios:
rule check_sector_ratios:
input:
network=RESULTS
+ "postnetworks/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
+ "postnetworks/base_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
log:
"logs/check_sector_ratios.log",
script:
Expand Down
Loading