# --> Kann in deflex bleiben, das es mit geometries zusammenpasst!!!
# --> DOKU !!!!!
# -*- coding: utf-8 -*-
"""Processing a list of power plants in Germany.
SPDX-FileCopyrightText: 2016-2019 Uwe Krien <krien@uni-bremen.de>
SPDX-License-Identifier: MIT
"""
__copyright__ = "Uwe Krien <krien@uni-bremen.de>"
__license__ = "MIT"
import math
import os
import pandas as pd
from deflex import config as cfg
from deflex import geometries
[docs]def get_grid_capacity(grid, plus, minus):
"""Read the grid capacity from a given region pair from the renpass db."""
tmp_grid = grid.query(
"plus_region_id == {:0d} & ".format(plus)
+ "minus_region_id == {:1d} & ".format(minus)
+ "scenario_name == 'status_quo_2012_distance'"
)
if len(tmp_grid) > 0:
capacity = tmp_grid.capacity_calc.sum()
distance = tmp_grid.distance.iloc[0]
else:
capacity = 0
distance = 0
return capacity, distance
[docs]def add_reverse_direction(df):
"""
Duplicate all entries of a DataFrame with a reverse index. The index must
contain a dash between two sub-strings.
"""
values = df.copy()
def id_inverter(name):
"""Swap the sub-parts of a string left and right of a dash."""
return "-".join([name.split("-")[1], name.split("-")[0]])
df.index = df.index.map(id_inverter)
return pd.DataFrame(pd.concat([values, df]))
[docs]def get_electrical_transmission_default(
rmap=None, power_lines=None, both_directions=False
):
"""
Creates a default set of transmission capacities, distance and efficiency.
The map of the lines must exist in the geometries directory. The default
values are infinity for the capacity, nan for the distance and 1 for the
efficiency.
Parameters
----------
rmap : str
The name of the transmission line map, that is part of deflex.
power_lines : iterable[str]
A list of names of transmission lines. All name must contain a dash
between the id of the regions (FromRegion-ToRegion).
both_directions : bool
If True any line will be replicated in the reverse direction.
Returns
-------
pd.DataFrame
Transmission capacity, distance and efficiency between regions
Examples
--------
>>> df=get_electrical_transmission_default('de21')
>>> df.loc['DE10-DE12', 'capacity']
inf
>>> df.loc['DE10-DE12', 'distance']
nan
>>> df.loc['DE10-DE12', 'efficiency']
1.0
>>> len(df)
39
>>> len(get_electrical_transmission_default('de22'))
40
>>> len(get_electrical_transmission_default('de17'))
31
>>> len(get_electrical_transmission_default('de02'))
1
>>> my_lines=['reg1-reg2', 'reg2-reg3']
>>> df=get_electrical_transmission_default(power_lines=my_lines)
>>> df.loc['reg1-reg2', 'capacity']
inf
>>> df=get_electrical_transmission_default(power_lines=my_lines,
... both_directions=True)
>>> df.loc['reg2-reg1', 'capacity']
inf
"""
if power_lines is None:
power_lines = pd.DataFrame(geometries.deflex_power_lines(rmap)).index
trans = pd.DataFrame()
for length in power_lines:
trans.loc[length, "capacity"] = float("inf")
trans.loc[length, "distance"] = float("nan")
trans.loc[length, "efficiency"] = 1
if both_directions is True:
trans = add_reverse_direction(trans)
return trans
[docs]def get_electrical_transmission_renpass(both_directions=False):
"""
Prepare the transmission capacity and distance between de21 regions from
the renpass database. The original table of the reegis database is
transferred to a csv file, which is part of the reegis package. As renpass
is deprecated it will not change in the future. The index uses the format
'region1-region2'. The distance is taken from centroid to centroid. By
default every region pair exists only once. It is possible to get an entry
in both directions if the parameter `both_directions` is set True.
The capacity calculation is taken from the description of the renpass
package [1]_. The data is taken from the renpass database [2]_.
This function is only valid for the original renpass region set.
Parameters
----------
both_directions : bool
If True any line will be replicated in the reverse direction.
Returns
-------
pd.DataFrame
Transmission capacity and distance between regions
References
----------
.. [1] Wiese, Frauke (2015). „Renewable Energy Pathways Simulation
System – Open Source as an approach to meet challenges in energy
modeling“. Diss. University of Flensburg. URL :
https://www.reiner-lemoine-stiftung.de/pdf/dissertationen/Dissertation_Frauke_Wiese.pdf.
(page 49)
.. [2] Wiese, F.: Renpass - Renewable Energy Pathways Simulation System,
https://github.com/fraukewiese/renpass
Examples
--------
>>> translines=get_electrical_transmission_renpass()
>>> int(translines.loc['DE11-DE17', 'capacity'])
2506
>>> int(translines.loc['DE18-DE17', 'distance'])
119
>>> translines.loc['DE08-DE06']
capacity 7519.040402
distance 257.000000
Name: DE08-DE06, dtype: float64
>>> translines=get_electrical_transmission_renpass(both_directions=True)
>>> int(translines.loc['DE11-DE17', 'capacity'])
2506
>>> int(translines.loc['DE17-DE11', 'capacity'])
2506
"""
# from [1] Wiese, Frauke (2015) (s. above)
security_factor = 0.7
current_max = 2720
grid = pd.read_csv(
os.path.join(
os.path.dirname(__file__), "data", "static",
"renpass_transmission.csv"))
grid["capacity_calc"] = (
grid.circuits
* current_max
* grid.voltage
* security_factor
* math.sqrt(3)
/ 1000
)
pwr_lines = pd.DataFrame(geometries.deflex_power_lines(rmap="de21"))
for idx in pwr_lines.index:
split = idx.split("-")
a = int("110{0}".format(split[0][2:]))
b = int("110{0}".format(split[1][2:]))
# print(a, b)
cap1, dist1 = get_grid_capacity(grid, a, b)
cap2, dist2 = get_grid_capacity(grid, b, a)
if cap1 == 0 and cap2 == 0:
pwr_lines.loc[idx, "capacity"] = 0
pwr_lines.loc[idx, "distance"] = 0
elif cap1 == 0:
pwr_lines.loc[idx, "capacity"] = cap2
pwr_lines.loc[idx, "distance"] = dist2
elif cap2 == 0:
pwr_lines.loc[idx, "capacity"] = cap1
pwr_lines.loc[idx, "distance"] = dist1
# plot_grid(pwr_lines)
df = pwr_lines[["capacity", "distance"]]
if both_directions is True:
df = add_reverse_direction(df)
return df
[docs]def scenario_transmission(table_collection, regions, name):
"""Get power plants for the scenario year
Examples
--------
>>> my_regions=geometries.deflex_regions(rmap="de21") # doctest: +SKIP
>>> pp=scenario_powerplants(dict(), my_regions, 2014, "de21"
... ) # doctest: +SKIP
>>> lines=scenario_transmission(pp, my_regions, "de21") # doctest: +SKIP
>>> int(lines.loc["DE07-DE05", ("electrical", "capacity")]
... ) # doctest: +SKIP
1978
>>> int(lines.loc["DE07-DE05", ("electrical", "distance")]
... ) # doctest: +SKIP
199
>>> float(lines.loc["DE07-DE05", ("electrical", "efficiency")]
... ) # doctest: +SKIP
0.9
>>> cfg.tmp_set("basic", "copperplate", "True")
>>> lines=scenario_transmission(pp, regions, "de21"
... ) # doctest: +SKIP
>>> cfg.tmp_set("basic", "copperplate", "False")
>>> float(lines.loc["DE07-DE05", ("electrical", "capacity")]
... ) # doctest: +SKIP
inf
>>> float(lines.loc["DE07-DE05", ("electrical", "distance")]
... ) # doctest: +SKIP
nan
>>> float(lines.loc["DE07-DE05", ("electrical", "efficiency")]
... ) # doctest: +SKIP
1.0
"""
vs = table_collection["volatile_source"]
# This should be done automatic e.g. if representative point outside the
# landmass polygon.
offshore_regions = geometries.divide_off_and_onshore(regions).offshore
if name in ["de21", "de22"] and not cfg.get("basic", "copperplate"):
elec_trans = get_electrical_transmission_renpass()
general_efficiency = cfg.get("transmission", "general_efficiency")
if general_efficiency is not None:
elec_trans["efficiency"] = general_efficiency
else:
msg = (
"The calculation of the efficiency by distance is not yet "
"implemented"
)
raise NotImplementedError(msg)
else:
elec_trans = get_electrical_transmission_default()
# Set transmission capacity of offshore power lines to installed capacity
# Multiply the installed capacity with 1.1 to get a buffer of 10%.
for offreg in offshore_regions:
elec_trans.loc[elec_trans.index.str.contains(offreg), "capacity"] = (
vs.loc[offreg].sum().sum() * 1.1
)
elec_trans = pd.concat(
[elec_trans], axis=1, keys=["electrical"]
).sort_index(1)
if cfg.get("init", "map") == "de22" and not cfg.get(
"basic", "copperplate"
):
elec_trans.loc["DE22-DE01", ("electrical", "efficiency")] = 0.9999
elec_trans.loc["DE22-DE01", ("electrical", "capacity")] = 9999999
return elec_trans
if __name__ == "__main__":
pass