Skip to content

Commit e5a3281

Browse files
committed
Merge branch 'main' into refining-scenarios
2 parents d4b6071 + 65775df commit e5a3281

File tree

8 files changed

+1527
-110
lines changed

8 files changed

+1527
-110
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ doc/_build
3131

3232
config/config.yaml
3333
config/scenarios.yaml
34+
config/scenarios.automated.yaml
3435

3536
config.yaml
3637
config/config.yaml
@@ -82,3 +83,8 @@ zenodo.org
8283
globalenergymonitor.org/wp-content/uploads/2023/07/Europe-Gas-Tracker-2023-03-v3.xlsx
8384
fnb-gas.de
8485
raw.githubusercontent.com
86+
cutouts
87+
88+
89+
# custom local files
90+
local

Snakefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,9 @@ rule plot_ariadne_variables:
581581
transmission_investment_csv=RESULTS + "ariadne/transmission_investment.csv",
582582
trassenlaenge_csv=RESULTS + "ariadne/trassenlaenge.csv",
583583
Kernnetz_Investment_plot=RESULTS + "ariadne/Kernnetz_Investment_plot.png",
584+
elec_trade=RESULTS + "ariadne/elec-trade-DE.png",
585+
h2_trade=RESULTS + "ariadne/h2-trade-DE.png",
586+
trade_balance=RESULTS + "ariadne/trade-balance-DE.png",
584587
log:
585588
RESULTS + "logs/plot_ariadne_variables.log",
586589
script:

config/config.default.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ solving:
909909
skip_iterations: true
910910
rolling_horizon: false
911911
seed: 123
912-
custom_extra_functionality: "../data/custom_extra_functionality.py"
912+
custom_extra_functionality: "../scripts/pypsa-de/additional_functionality.py"
913913
# io_api: "direct" # Increases performance but only supported for the highs and gurobi solvers
914914
# options that go into the optimize function
915915
track_iterations: false

rules/solve_myopic.smk

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,6 @@ rule solve_sector_network_myopic:
114114
"sector", "co2_sequestration_potential", default=200
115115
),
116116
custom_extra_functionality=input_custom_extra_functionality,
117-
# custom_extra_functionality=os.path.join(
118-
# os.path.dirname(workflow.snakefile), "scripts/pypsa-de/additional_functionality.py"
119-
# ),
120117
energy_year=config_provider("energy", "energy_totals_year"),
121118
input:
122119
network=RESULTS

scripts/pypsa-de/additional_functionality.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
2-
32
import logging
3+
import sys
44

55
import pandas as pd
66
from xarray import DataArray
@@ -51,7 +51,7 @@ def add_capacity_limits(n, investment_year, limits_capacity, sense="maximum"):
5151

5252
lhs = nom.sum()
5353

54-
cname = f"capacity_{sense}-{ct}-{c.name}-{carrier.replace(' ','-')}"
54+
cname = f"capacity_{sense}-{ct}-{c.name}-{carrier.replace(' ', '-')}"
5555

5656
if cname in n.global_constraints.index:
5757
logger.warning(
@@ -163,7 +163,7 @@ def h2_import_limits(n, investment_year, limits_volume_max):
163163
for ct in limits_volume_max["h2_import"]:
164164
limit = limits_volume_max["h2_import"][ct][investment_year] * 1e6
165165

166-
logger.info(f"limiting H2 imports in {ct} to {limit/1e6} TWh/a")
166+
logger.info(f"limiting H2 imports in {ct} to {limit / 1e6} TWh/a")
167167
pipeline_carrier = [
168168
"H2 pipeline",
169169
"H2 pipeline (Kernnetz)",
@@ -234,7 +234,7 @@ def h2_production_limits(n, investment_year, limits_volume_min, limits_volume_ma
234234
limit_upper = limits_volume_max["electrolysis"][ct][investment_year] * 1e6
235235

236236
logger.info(
237-
f"limiting H2 electrolysis in DE between {limit_lower/1e6} and {limit_upper/1e6} TWh/a"
237+
f"limiting H2 electrolysis in DE between {limit_lower / 1e6} and {limit_upper / 1e6} TWh/a"
238238
)
239239

240240
production = n.links[
@@ -283,7 +283,7 @@ def electricity_import_limits(n, investment_year, limits_volume_max):
283283
for ct in limits_volume_max["electricity_import"]:
284284
limit = limits_volume_max["electricity_import"][ct][investment_year] * 1e6
285285

286-
logger.info(f"limiting electricity imports in {ct} to {limit/1e6} TWh/a")
286+
logger.info(f"limiting electricity imports in {ct} to {limit / 1e6} TWh/a")
287287

288288
incoming_line = n.lines.index[
289289
(n.lines.carrier == "AC")
@@ -386,7 +386,7 @@ def add_co2limit_country(n, limit_countries, snakemake, debug=False):
386386
]
387387

388388
logger.info(
389-
f"For {ct} adding following link carriers to port {port} CO2 constraint: {n.links.loc[links,'carrier'].unique()}"
389+
f"For {ct} adding following link carriers to port {port} CO2 constraint: {n.links.loc[links, 'carrier'].unique()}"
390390
)
391391

392392
if port == "0":
@@ -614,7 +614,7 @@ def add_h2_derivate_limit(n, investment_year, limits_volume_max):
614614
for ct in limits_volume_max["h2_derivate_import"]:
615615
limit = limits_volume_max["h2_derivate_import"][ct][investment_year] * 1e6
616616

617-
logger.info(f"limiting H2 derivate imports in {ct} to {limit/1e6} TWh/a")
617+
logger.info(f"limiting H2 derivate imports in {ct} to {limit / 1e6} TWh/a")
618618

619619
incoming = n.links.loc[
620620
[

scripts/pypsa-de/export_ariadne_variables.py

Lines changed: 93 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,11 +2331,49 @@ def get_final_energy(
23312331
# straightforward for the other categories
23322332
# !!! TODO this assert is temporarily disabled because of https://github.com/PyPSA/pypsa-eur/issues/985
23332333

2334+
central_heat_withdrawal = (
2335+
n.statistics.withdrawal(
2336+
bus_carrier=["urban central heat"],
2337+
**kwargs,
2338+
)
2339+
.filter(
2340+
like=region,
2341+
)
2342+
.groupby("carrier")
2343+
.sum()
2344+
.multiply(MWh2PJ)
2345+
)
2346+
2347+
var["Final Energy|Carbon Dioxide Removal|Heat"] = decentral_heat_withdrawal.get(
2348+
"DAC", 0
2349+
) + central_heat_withdrawal.get("DAC", 0)
2350+
2351+
electricity = (
2352+
n.statistics.withdrawal(
2353+
bus_carrier="AC",
2354+
**kwargs,
2355+
)
2356+
.filter(
2357+
like=region,
2358+
)
2359+
.groupby("carrier")
2360+
.sum()
2361+
.multiply(MWh2PJ)
2362+
)
2363+
2364+
var["Final Energy|Carbon Dioxide Removal|Electricity"] = electricity.get("DAC", 0)
2365+
2366+
var["Final Energy|Carbon Dioxide Removal"] = (
2367+
var["Final Energy|Carbon Dioxide Removal|Electricity"]
2368+
+ var["Final Energy|Carbon Dioxide Removal|Heat"]
2369+
)
2370+
23342371
var["Final Energy|Electricity"] = (
23352372
var["Final Energy|Agriculture|Electricity"]
23362373
+ var["Final Energy|Residential and Commercial|Electricity"]
23372374
+ var["Final Energy|Transportation|Electricity"]
23382375
+ var["Final Energy|Industry excl Non-Energy Use|Electricity"]
2376+
+ var["Final Energy|Carbon Dioxide Removal|Electricity"]
23392377
)
23402378

23412379
var["Final Energy|Solids"] = (
@@ -2385,6 +2423,7 @@ def get_final_energy(
23852423
var["Final Energy|Agriculture|Heat"]
23862424
+ var["Final Energy|Residential and Commercial|Heat"]
23872425
+ var["Final Energy|Industry excl Non-Energy Use|Heat"]
2426+
+ var["Final Energy|Carbon Dioxide Removal|Heat"]
23882427
)
23892428
# var["Final Energy|Solar"] = \
23902429
var["Final Energy|Hydrogen"] = (
@@ -2410,30 +2449,6 @@ def get_final_energy(
24102449

24112450
var["Final Energy|Waste"] = waste_withdrawal.get("HVC to air", 0)
24122451

2413-
var["Final Energy|Carbon Dioxide Removal|Heat"] = decentral_heat_withdrawal.get(
2414-
"DAC", 0
2415-
)
2416-
2417-
electricity = (
2418-
n.statistics.withdrawal(
2419-
bus_carrier="AC",
2420-
**kwargs,
2421-
)
2422-
.filter(
2423-
like=region,
2424-
)
2425-
.groupby("carrier")
2426-
.sum()
2427-
.multiply(MWh2PJ)
2428-
)
2429-
2430-
var["Final Energy|Carbon Dioxide Removal|Electricity"] = electricity.get("DAC", 0)
2431-
2432-
var["Final Energy|Carbon Dioxide Removal"] = (
2433-
var["Final Energy|Carbon Dioxide Removal|Electricity"]
2434-
+ var["Final Energy|Carbon Dioxide Removal|Heat"]
2435-
)
2436-
24372452
var["Final Energy incl Non-Energy Use incl Bunkers"] = (
24382453
var["Final Energy|Industry"]
24392454
+ var["Final Energy|Residential and Commercial"]
@@ -2897,6 +2912,7 @@ def get_emissions(n, region, _energy_totals, industry_demand):
28972912
+ var["Emissions|Gross Fossil CO2|Energy|Supply|Hydrogen"]
28982913
+ var["Emissions|Gross Fossil CO2|Energy|Supply|Liquids"]
28992914
+ var["Emissions|Gross Fossil CO2|Energy|Supply|Solids"]
2915+
+ var["Emissions|Gross Fossil CO2|Energy|Supply|Gases"]
29002916
)
29012917

29022918
var["Emissions|Gross Fossil CO2|Energy"] = (
@@ -2927,12 +2943,6 @@ def get_emissions(n, region, _energy_totals, industry_demand):
29272943
var["Emissions|CO2|Energy"] + var["Emissions|CO2|Industrial Processes"]
29282944
)
29292945

2930-
var["Emissions|Gross Fossil CO2|Energy|Supply"] = (
2931-
var["Emissions|Gross Fossil CO2|Energy|Supply|Electricity"]
2932-
+ var["Emissions|Gross Fossil CO2|Energy|Supply|Heat"]
2933-
+ var["Emissions|Gross Fossil CO2|Energy|Supply|Hydrogen"]
2934-
)
2935-
29362946
emission_difference = var["Emissions|CO2"] - (
29372947
var["Emissions|CO2|Energy and Industrial Processes"]
29382948
+ var["Emissions|CO2|Energy|Demand|Bunkers"]
@@ -4174,72 +4184,92 @@ def get_trade(n, region):
41744184
var = pd.Series()
41754185

41764186
def get_export_import_links(n, region, carriers):
4177-
exporting = n.links.index[
4187+
# note: links can also used bidirectional if efficiency=1 (e.g. "H2 pipeline retrofitted")
4188+
outgoing = n.links.index[
41784189
(n.links.carrier.isin(carriers))
41794190
& (n.links.bus0.str[:2] == region)
41804191
& (n.links.bus1.str[:2] != region)
41814192
]
41824193

4183-
importing = n.links.index[
4194+
incoming = n.links.index[
41844195
(n.links.carrier.isin(carriers))
41854196
& (n.links.bus0.str[:2] != region)
41864197
& (n.links.bus1.str[:2] == region)
41874198
]
41884199

41894200
exporting_p = (
4190-
n.links_t.p0.loc[:, exporting]
4201+
# if p0 > 0 (=clip(lower=0)) system is withdrawing from bus0 (DE) and feeding into bus1 (non-DE) -> export
4202+
n.links_t.p0.loc[:, outgoing]
41914203
.clip(lower=0)
41924204
.multiply(n.snapshot_weightings.generators, axis=0)
41934205
.values.sum()
4194-
- n.links_t.p0.loc[:, importing]
4195-
.clip(upper=0)
4206+
+
4207+
# if p1 > 0 system is withdrawing from bus1 (DE) and feeding into bus0 (non-DE) -> export
4208+
n.links_t.p1.loc[:, incoming]
4209+
.clip(lower=0)
41964210
.multiply(n.snapshot_weightings.generators, axis=0)
41974211
.values.sum()
41984212
)
4213+
41994214
importing_p = (
4200-
n.links_t.p0.loc[:, importing]
4201-
.clip(lower=0)
4215+
# if p1 < 0 (=clip(upper=0)) system is feeding into bus1 (DE) and withdrawing from bus0 (non-DE) -> import (with negative sign here)
4216+
n.links_t.p1.loc[:, incoming]
4217+
.clip(upper=0)
42024218
.multiply(n.snapshot_weightings.generators, axis=0)
42034219
.values.sum()
4204-
- n.links_t.p0.loc[:, exporting]
4220+
* -1
4221+
+
4222+
# if p0 < 0 (=clip(upper=0)) system is feeding into bus0 (DE) and withdrawing from bus1 (non-DE) -> import (with negative sign here)
4223+
n.links_t.p0.loc[:, outgoing]
42054224
.clip(upper=0)
42064225
.multiply(n.snapshot_weightings.generators, axis=0)
42074226
.values.sum()
4227+
* -1
42084228
)
42094229

42104230
return exporting_p, importing_p
42114231

42124232
# Trade|Secondary Energy|Electricity|Volume
4213-
exporting_ac = n.lines.index[
4233+
outgoing_ac = n.lines.index[
42144234
(n.lines.carrier == "AC")
42154235
& (n.lines.bus0.str[:2] == region)
42164236
& (n.lines.bus1.str[:2] != region)
42174237
]
42184238

4219-
importing_ac = n.lines.index[
4239+
incoming_ac = n.lines.index[
42204240
(n.lines.carrier == "AC")
42214241
& (n.lines.bus0.str[:2] != region)
42224242
& (n.lines.bus1.str[:2] == region)
42234243
]
4244+
42244245
exporting_p_ac = (
4225-
n.lines_t.p0.loc[:, exporting_ac]
4246+
# if p0 > 0 (=clip(lower=0)) system is withdrawing from bus0 (DE) and feeding into bus1 (non-DE) -> export
4247+
n.lines_t.p0.loc[:, outgoing_ac]
42264248
.clip(lower=0)
42274249
.multiply(n.snapshot_weightings.generators, axis=0)
42284250
.values.sum()
4229-
- n.lines_t.p0.loc[:, importing_ac]
4230-
.clip(upper=0)
4251+
+
4252+
# if p1 > 0 system is withdrawing from bus1 (DE) and feeding into bus0 (non-DE) -> export
4253+
n.lines_t.p1.loc[:, incoming_ac]
4254+
.clip(lower=0)
42314255
.multiply(n.snapshot_weightings.generators, axis=0)
42324256
.values.sum()
42334257
)
4258+
42344259
importing_p_ac = (
4235-
n.lines_t.p0.loc[:, importing_ac]
4236-
.clip(lower=0)
4260+
# if p1 < 0 (=clip(upper=0)) system is feeding into bus1 (DE) and withdrawing from bus0 (non-DE) -> import (with negative sign here)
4261+
n.lines_t.p1.loc[:, incoming_ac]
4262+
.clip(upper=0)
42374263
.multiply(n.snapshot_weightings.generators, axis=0)
42384264
.values.sum()
4239-
- n.lines_t.p0.loc[:, exporting_ac]
4265+
* -1
4266+
+
4267+
# if p0 < 0 (=clip(upper=0)) system is feeding into bus0 (DE) and withdrawing from bus1 (non-DE) -> import (with negative sign here)
4268+
n.lines_t.p0.loc[:, outgoing_ac]
42404269
.clip(upper=0)
42414270
.multiply(n.snapshot_weightings.generators, axis=0)
42424271
.values.sum()
4272+
* -1
42434273
)
42444274

42454275
exports_dc, imports_dc = get_export_import_links(n, region, ["DC"])
@@ -5141,6 +5171,23 @@ def get_data(
51415171
var["Investment|Energy Supply|Hydrogen|Fossil"] = var[
51425172
"Investment|Energy Supply|Hydrogen|Gas"
51435173
]
5174+
# For internal use only and translated directly to TWh
5175+
var["Demand|Electricity"] = (
5176+
var.reindex(
5177+
[
5178+
"Secondary Energy|Electricity|Storage Losses",
5179+
"Secondary Energy Input|Electricity|Heat",
5180+
"Secondary Energy Input|Electricity|Hydrogen",
5181+
"Secondary Energy Input|Electricity|Liquids",
5182+
"Final Energy|Industry|Electricity",
5183+
"Final Energy|Agriculture|Electricity",
5184+
"Final Energy|Residential and Commercial|Electricity",
5185+
"Final Energy|Transportation|Electricity",
5186+
"Final Energy|Carbon Dioxide Removal|Electricity",
5187+
]
5188+
).sum()
5189+
/ 3.6
5190+
)
51445191

51455192
data = []
51465193
for v in var.index:

0 commit comments

Comments
 (0)