@@ -100,6 +100,66 @@ def add_capacity_limits(n, investment_year, limits_capacity, sense="maximum"):
100
100
sys .exit ()
101
101
102
102
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
+
103
163
def h2_import_limits (n , investment_year , limits_volume_max ):
104
164
105
165
for ct in limits_volume_max ["h2_import" ]:
@@ -615,6 +675,8 @@ def additional_functionality(n, snapshots, snakemake):
615
675
n , investment_year , constraints ["limits_capacity_max" ], "maximum"
616
676
)
617
677
678
+ add_power_limits (n , investment_year , constraints ["limits_power_max" ])
679
+
618
680
if int (snakemake .wildcards .clusters ) != 1 :
619
681
h2_import_limits (n , investment_year , constraints ["limits_volume_max" ])
620
682
0 commit comments