Passed
Pull Request — dev (#930)
by
unknown
01:36
created

insert_gas_neigbours_eGon100RE()   A

Complexity

Conditions 1

Size

Total Lines 40
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 40
rs 10
c 0
b 0
f 0
cc 1
nop 0
1
"""Module containing code dealing with crossbording gas pipelines for eGon100RE
2
3
In this module the crossbordering pipelines for H2 and CH4, exclusively
4
between Germany and its neighbouring countries, in eGon100RE are
5
defined and inserted in the database.
6
7
Dependecies (pipeline)
8
======================
9
  * :dataset: PypsaEurSec, GasNodesandPipes, HydrogenBusEtrago,
10
    ElectricalNeighbours
11
12
Resulting tables
13
================
14
  * grid.egon_etrago_link is completed
15
16
"""
17
18
import pandas as pd
19
20
from egon.data import config, db
21
from egon.data.datasets.gas_neighbours.gas_abroad import (
22
    insert_gas_grid_capacities,
23
)
24
from egon.data.datasets.pypsaeursec import read_network
25
26
countries = [
27
    "AT",
28
    "BE",
29
    "CH",
30
    "CZ",
31
    "DK",
32
    "FR",
33
    "LU",
34
    "NL",
35
    "NO",
36
    "PL",
37
]
38
39
40
def insert_gas_neigbours_eGon100RE():
41
    """Insert missing gas crossbordering grid capacities for eGon100RE
42
43
    This function insert the crossbordering pipelines for H2 and CH4,
44
    exclusively between Germany and its neighbouring countries,
45
    for eGon100RE in the database by executing the following steps:
46
      * call of the the function
47
        :py:func:`define_DE_crossbording_pipes_geom_eGon100RE`, that
48
        defines the crossbordering pipelines (H2 and CH4) between
49
        Germany and its neighbouring countries
50
      * call of the the function
51
        :py:func:`read_DE_crossbordering_cap_from_pes`, that calculates
52
        the crossbordering total exchange capactities for H2 and CH4
53
        between Germany and its neighbouring countries based on the
54
        pypsa-eur-sec results
55
      * call of the the function
56
        :py:func:`calculate_crossbordering_gas_grid_capacities_eGon100RE`,
57
        that attributes to each crossbordering pipeline (H2 and CH4)
58
        between Germany and its neighbouring countries its capacity
59
      * insertion of the H2 and CH4 pipelines between Germany and its
60
        neighbouring countries in the database with function
61
        :py:func:`insert_gas_grid_capacities`
62
63
    Returns
64
    -------
65
    None
66
67
    """
68
69
    DE_pipe_capacities_list = define_DE_crossbording_pipes_geom_eGon100RE()
70
    cap_DE = read_DE_crossbordering_cap_from_pes()
71
72
    Crossbordering_pipe_capacities_list = (
73
        calculate_crossbordering_gas_grid_capacities_eGon100RE(
74
            cap_DE, DE_pipe_capacities_list
75
        )
76
    )
77
78
    insert_gas_grid_capacities(
79
        Crossbordering_pipe_capacities_list, "eGon100RE"
80
    )
81
82
83
def define_DE_crossbording_pipes_geom_eGon100RE(scn_name="eGon100RE"):
84
    """Define the missing crossbordering gas pipelines in eGon100RE
85
86
    This function defines the crossbordering pipelines (for H2 and CH4)
87
    between Germany and its neighbouring countries. These pipelines
88
    are defined as links and there are copied from the corresponding
89
    CH4 crossbering pipelines from eGon2035.
90
91
    Parameters
92
    ----------
93
    scn_name : str
94
        Name of the scenario
95
96
    Returns
97
    -------
98
    gas_pipelines_list_DE : pandas.DataFrame
99
        List of the crossbordering H2 and CH4 pipelines between
100
        Germany and its neighbouring countries in eGon100RE, with
101
        geometry (geom and topo) but no capacity.
102
103
    """
104
    sources = config.datasets()["gas_neighbours"]["sources"]
105
106
    gas_pipelines_list = db.select_geodataframe(
107
        f"""
108
        SELECT * FROM grid.egon_etrago_link
109
        WHERE ("bus0" IN (
110
                        SELECT bus_id FROM 
111
                        {sources['buses']['schema']}.{sources['buses']['table']}
112
                        WHERE country != 'DE'
113
                        AND carrier = 'CH4'
114
                        AND scn_name = 'eGon2035')
115
                    AND "bus1" IN (SELECT bus_id FROM 
116
                        {sources['buses']['schema']}.{sources['buses']['table']}
117
                        WHERE country = 'DE'
118
                        AND carrier = 'CH4' 
119
                        AND scn_name = 'eGon2035'))
120
                OR ("bus0" IN (
121
                        SELECT bus_id FROM 
122
                        {sources['buses']['schema']}.{sources['buses']['table']}
123
                        WHERE country = 'DE'
124
                        AND carrier = 'CH4'
125
                        AND scn_name = 'eGon2035')
126
                AND "bus1" IN (
127
                        SELECT bus_id FROM 
128
                        {sources['buses']['schema']}.{sources['buses']['table']}
129
                        WHERE country != 'DE'
130
                        AND carrier = 'CH4' 
131
                        AND scn_name = 'eGon2035'))
132
        AND scn_name = 'eGon2035'
133
        AND carrier = 'CH4'
134
        """,
135
        epsg=4326,
136
    )
137
138
    # Insert bus0 and bus1
139
    gas_pipelines_list = gas_pipelines_list[
140
        ["bus0", "bus1", "length", "geom", "topo"]
141
    ].rename(columns={"bus0": "bus0_2035", "bus1": "bus1_2035"})
142
143
    gas_nodes_list_2035 = db.select_geodataframe(
144
        f"""
145
        SELECT * FROM {sources['buses']['schema']}.{sources['buses']['table']}
146
        WHERE scn_name = 'eGon2035'
147
        AND carrier = 'CH4'
148
        """,
149
        epsg=4326,
150
    )
151
152
    busID_table = gas_nodes_list_2035[["geom", "bus_id", "country"]].rename(
153
        columns={"bus_id": "bus_id_CH4_2035"}
154
    )
155
    gas_pipelines_list_DE = pd.DataFrame(
156
        columns=["length", "geom", "topo", "bus0", "bus1", "carrier"]
157
    )
158
159
    for carrier in ["H2", "CH4"]:
160
        if carrier == "CH4":
161
            carrier_bus_DE = carrier
162
        elif carrier == "H2":
163
            carrier_bus_DE = "H2_grid"
164
165
        busID_table_DE = db.assign_gas_bus_id(
166
            busID_table[busID_table["country"] == "DE"],
167
            scn_name,
168
            carrier_bus_DE,
0 ignored issues
show
introduced by
The variable carrier_bus_DE does not seem to be defined for all execution paths.
Loading history...
169
        ).set_index("bus_id_CH4_2035")
170
171
        gas_nodes_abroad_100RE = db.select_geodataframe(
172
            f"""
173
            SELECT * FROM grid.egon_etrago_bus
174
            WHERE scn_name = 'eGon100RE'
175
            AND carrier = '{carrier_bus_DE}'
176
            AND country != 'DE'
177
            """,
178
            epsg=4326,
179
        )
180
181
        buses = busID_table[busID_table["country"] != "DE"]
182
        buses["bus_id"] = 0
183
184
        # Select bus_id from db
185
        for i, row in buses.iterrows():
186
            distance = gas_nodes_abroad_100RE.set_index(
187
                "bus_id"
188
            ).geom.distance(row.geom)
189
            buses.loc[i, "bus_id"] = distance[
190
                distance == distance.min()
191
            ].index.values[0]
192
193
        buses = buses.set_index("bus_id_CH4_2035")
194
195
        bus0 = []
196
        bus1 = []
197
        country = []
198
199
        for b0 in gas_pipelines_list["bus0_2035"].to_list():
200
            if b0 in busID_table_DE.index.to_list():
201
                bus0.append(int(busID_table_DE.loc[b0, "bus_id"]))
202
            else:
203
                bus0.append(int(buses.loc[b0, "bus_id"]))
204
                country.append(buses.loc[b0, "country"])
205
        for b1 in gas_pipelines_list["bus1_2035"].to_list():
206
            if b1 in busID_table_DE.index.to_list():
207
                bus1.append(int(busID_table_DE.loc[b1, "bus_id"]))
208
            else:
209
                bus1.append(int(buses.loc[b1, "bus_id"]))
210
                country.append(buses.loc[b1, "country"])
211
212
        gas_pipelines_list["bus0"] = bus0
213
        gas_pipelines_list["bus1"] = bus1
214
        gas_pipelines_list["country"] = country
215
216
        # Insert carrier
217
        if carrier == "CH4":
218
            carrier_pipes = carrier
219
        elif carrier == "H2":
220
            carrier_pipes = "H2_retrofit"
221
        gas_pipelines_list["carrier"] = carrier_pipes
0 ignored issues
show
introduced by
The variable carrier_pipes does not seem to be defined for all execution paths.
Loading history...
222
223
        gas_pipelines_list_DE = gas_pipelines_list_DE.append(
224
            gas_pipelines_list, ignore_index=True
225
        )
226
227
    gas_pipelines_list_DE["scn_name"] = scn_name
228
229
    # Select next id value
230
    new_id = db.next_etrago_id("link")
231
    gas_pipelines_list_DE["link_id"] = range(
232
        new_id, new_id + len(gas_pipelines_list_DE)
233
    )
234
    gas_pipelines_list_DE["link_id"] = gas_pipelines_list_DE["link_id"].astype(
235
        int
236
    )
237
    gas_pipelines_list_DE = gas_pipelines_list_DE.drop(
238
        columns={"bus0_2035", "bus1_2035"}
239
    )
240
241
    return gas_pipelines_list_DE
242
243
244
def read_DE_crossbordering_cap_from_pes():
245
    """Read gas pipelines crossbordering capacities from pes run
246
247
    This function calculates the crossbordering total exchange
248
    capactities for H2 and CH4 between Germany and its neighbouring
249
    countries based on the pypsa-eur-sec results.
250
251
    Returns
252
    -------
253
    DE_pipe_capacities_list : pandas.DataFrame
254
        List of the H2 and CH4 exchange capacity for each neighbouring
255
        country of Germany.
256
257
    """
258
    n = read_network()
259
260
    DE_pipe_capacities_list_H2 = n.links[
261
        (n.links["carrier"] == "H2 pipeline retrofitted")
262
        & ((n.links["bus0"] == "DE0 0 H2") | (n.links["bus1"] == "DE0 0 H2"))
263
    ]
264
265
    DE_pipe_capacities_list_CH4 = n.links[
266
        (n.links["carrier"] == "gas pipeline")
267
        & ((n.links["bus0"] == "DE0 0 gas") | (n.links["bus1"] == "DE0 0 gas"))
268
    ]
269
270
    pipe_capacities_list = pd.DataFrame(
271
        columns=["p_nom", "carrier", "country_code"]
272
    )
273
    for DE_pipe_capacities_list in [
274
        DE_pipe_capacities_list_H2,
275
        DE_pipe_capacities_list_CH4,
276
    ]:
277
278
        DE_pipe_capacities_list = DE_pipe_capacities_list[
279
            ["bus0", "bus1", "p_nom_opt", "carrier"]
280
        ].rename(columns={"p_nom_opt": "p_nom"})
281
282
        DE_pipe_capacities_list[
283
            "country_code"
284
        ] = DE_pipe_capacities_list.apply(
285
            lambda row: str(sorted([row.bus0[:2], row.bus1[:2]])), axis=1
286
        )
287
288
        DE_pipe_capacities_list = DE_pipe_capacities_list.drop(
289
            columns=[
290
                "bus0",
291
                "bus1",
292
            ]
293
        )
294
295
        DE_pipe_capacities_list = DE_pipe_capacities_list.groupby(
296
            ["country_code"], as_index=False
297
        ).agg({"p_nom": "sum", "carrier": "first"})
298
299
        pipe_capacities_list = pipe_capacities_list.append(
300
            DE_pipe_capacities_list, ignore_index=True
301
        )
302
303
    map_countries = {
304
        "['AT', 'DE']": "AT",
305
        "['BE', 'DE']": "BE",
306
        "['CH', 'DE']": "CH",
307
        "['CZ', 'DE']": "CZ",
308
        "['DE', 'DK']": "DK",
309
        "['DE', 'FR']": "FR",
310
        "['DE', 'LU']": "LU",
311
        "['DE', 'NL']": "NL",
312
        "['DE', 'NO']": "NO",
313
        "['DE', 'PL']": "PL",
314
    }
315
316
    pipe_capacities_list["country_code"] = pipe_capacities_list[
317
        "country_code"
318
    ].replace(map_countries)
319
    pipe_capacities_list["carrier"] = pipe_capacities_list["carrier"].replace(
320
        {
321
            "H2 pipeline retrofitted": "H2_retrofit",
322
            "gas pipeline": "CH4",
323
        }
324
    )
325
326
    return pipe_capacities_list
327
328
329
def calculate_crossbordering_gas_grid_capacities_eGon100RE(
330
    cap_DE, DE_pipe_capacities_list
331
):
332
    """Attribute gas crossbordering grid capacities for eGon100RE
333
334
    This function attributes to each crossbordering pipeline (H2 and
335
    CH4) between Germany and its neighbouring countries its capacity.
336
337
    Parameters
338
    ----------
339
    cap_DE : pandas.DataFrame
340
        List of the H2 and CH4 exchange capacity for each neighbouring
341
        country of Germany.
342
    DE_pipe_capacities_list : pandas.DataFrame
343
        List of the crossbordering for H2 and CH4 pipelines between
344
        Germany and its neighbouring countries in eGon100RE, with
345
        geometry (geom and topo) but no capacity.
346
347
    Returns
348
    -------
349
    Crossbordering_pipe_capacities_list : pandas.DataFrame
350
        List of the crossbordering H2 and CH4 pipelines between
351
        Germany and its neighbouring countries in eGon100RE.
352
353
    """
354
355
    Crossbordering_pipe_capacities_list = pd.DataFrame(
356
        columns=[
357
            "length",
358
            "geom",
359
            "topo",
360
            "bus0",
361
            "bus1",
362
            "carrier",
363
            "scn_name",
364
            "link_id",
365
            "p_nom",
366
        ]
367
    )
368
369
    for carrier in ["CH4", "H2_retrofit"]:
370
        p_nom = []
371
        cap = cap_DE[cap_DE["carrier"] == carrier].set_index("country_code")
372
        pipe_capacities_list = DE_pipe_capacities_list[
373
            DE_pipe_capacities_list["carrier"] == carrier
374
        ]
375
376
        for c in pipe_capacities_list["country"].to_list():
377
            n_links = len(
378
                pipe_capacities_list[
379
                    pipe_capacities_list["country"] == c
380
                ].index
381
            )
382
            p_nom.append(cap.at[c, "p_nom"] / n_links)
383
384
        pipe_capacities_list["p_nom"] = p_nom
385
        pipe_capacities_list = pipe_capacities_list.drop(columns={"country"})
386
        Crossbordering_pipe_capacities_list = (
387
            Crossbordering_pipe_capacities_list.append(pipe_capacities_list)
388
        )
389
390
    return Crossbordering_pipe_capacities_list
391