Skip to content
This repository was archived by the owner on Mar 27, 2025. It is now read-only.

Commit 0abf8b6

Browse files
toniseiboldpre-commit-ci[bot]lindnemi
authored
Restricting powerflow from and to Germany (#231)
* Restricting powerflow from and to Germany --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Micha <michaellindner@pik-potsdam.de>
1 parent 4de2132 commit 0abf8b6

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Changelog
22
- Except for Current Policies force a minimum of 5 GW of electrolysis capacity in Germany
3+
- limit the import/export limit to/from Germany
34
- adjusting capacity factor of solar to match historic data
45
- Rely on DEA investment costs for electrolysis
56
- updated the Kernnetz to use latest data and operate it more flexible

config/config.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#run
66
run:
77

8-
prefix: 241011_fix_trans_projects
8+
prefix: 20241014_restrict_power_flow
9+
910

1011
name:
1112
# - CurrentPolicies
@@ -557,6 +558,14 @@ solving:
557558
2035: 0
558559
2040: 0
559560
2045: 0
561+
limits_power_max: # in GW
562+
DE:
563+
2020: 15
564+
2025: 15
565+
2030: 20
566+
2035: 25
567+
2040: 30
568+
2045: 35
560569
# solver:
561570
# options: gurobi-numeric-focus
562571
# solver_options:

workflow/scripts/additional_functionality.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,66 @@ def add_capacity_limits(n, investment_year, limits_capacity, sense="maximum"):
100100
sys.exit()
101101

102102

103+
def add_power_limits(n, investment_year, limits_power_max):
104+
"""
105+
" Restricts the maximum inflow/outflow of electricity from/to a country.
106+
"""
107+
for ct in limits_power_max:
108+
if investment_year not in limits_power_max[ct].keys():
109+
continue
110+
111+
limit = 1e3 * limits_power_max[ct][investment_year] / 10
112+
113+
logger.info(
114+
f"Adding constraint on electricity import/export from/to {ct} to be < {limit} MW"
115+
)
116+
incoming_line = n.lines.index[
117+
(n.lines.carrier == "AC")
118+
& (n.lines.bus0.str[:2] != ct)
119+
& (n.lines.bus1.str[:2] == ct)
120+
]
121+
outgoing_line = n.lines.index[
122+
(n.lines.carrier == "AC")
123+
& (n.lines.bus0.str[:2] == ct)
124+
& (n.lines.bus1.str[:2] != ct)
125+
]
126+
127+
incoming_link = n.links.index[
128+
(n.links.carrier == "DC")
129+
& (n.links.bus0.str[:2] != ct)
130+
& (n.links.bus1.str[:2] == ct)
131+
]
132+
outgoing_link = n.links.index[
133+
(n.links.carrier == "DC")
134+
& (n.links.bus0.str[:2] == ct)
135+
& (n.links.bus1.str[:2] != ct)
136+
]
137+
138+
# iterate over snapshots - otherwise exporting of postnetwork fails since
139+
# the constraints are time dependent
140+
for t in n.snapshots:
141+
incoming_line_p = n.model["Line-s"].loc[t, incoming_line]
142+
outgoing_line_p = n.model["Line-s"].loc[t, outgoing_line]
143+
incoming_link_p = n.model["Link-p"].loc[t, incoming_link]
144+
outgoing_link_p = n.model["Link-p"].loc[t, outgoing_link]
145+
146+
lhs = (
147+
incoming_link_p.sum()
148+
- outgoing_link_p.sum()
149+
+ incoming_line_p.sum()
150+
- outgoing_line_p.sum()
151+
) / 10
152+
# divide by 10 to avoid numerical issues
153+
154+
cname_upper = f"Power-import-limit-{ct}-{t}"
155+
cname_lower = f"Power-export-limit-{ct}-{t}"
156+
157+
n.model.add_constraints(lhs <= limit, name=cname_upper)
158+
n.model.add_constraints(lhs >= -limit, name=cname_lower)
159+
160+
# not adding to network as the shadow prices are not needed
161+
162+
103163
def h2_import_limits(n, investment_year, limits_volume_max):
104164

105165
for ct in limits_volume_max["h2_import"]:
@@ -615,6 +675,8 @@ def additional_functionality(n, snapshots, snakemake):
615675
n, investment_year, constraints["limits_capacity_max"], "maximum"
616676
)
617677

678+
add_power_limits(n, investment_year, constraints["limits_power_max"])
679+
618680
if int(snakemake.wildcards.clusters) != 1:
619681
h2_import_limits(n, investment_year, constraints["limits_volume_max"])
620682

0 commit comments

Comments
 (0)