From 8798b3e2035eb287c324b8a5f02bcb075fc83569 Mon Sep 17 00:00:00 2001 From: Fabian Date: Tue, 6 Sep 2022 16:40:00 +0200 Subject: [PATCH] line-rating: adjust config keys --- scripts/add_electricity.py | 46 +++++++++++++++++++++++++----------- scripts/build_line_rating.py | 6 ++--- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/scripts/add_electricity.py b/scripts/add_electricity.py index 8d77b30a..9e8a24c1 100755 --- a/scripts/add_electricity.py +++ b/scripts/add_electricity.py @@ -546,18 +546,20 @@ def estimate_renewable_capacities(n, config): logger.info(f"Reducing capacity expansion limit to {expansion_limit*100:.2f}% of installed capacity.") n.generators.loc[tech_i, 'p_nom_max'] = float(expansion_limit) * n.generators.loc[tech_i, 'p_nom_min'] -def attach_line_rating(n, fn, s_max_pu_factor,dlr_factor, line_clipping): - s_max = xr.open_dataarray(fn).to_pandas().transpose() - n.lines_t.s_max_pu = (s_max / n.lines.s_nom[s_max.columns]) * dlr_factor #only considers overhead lines - # account for maximal voltage angles of maximally 30 degree. - if line_clipping: +def attach_line_rating(n, rating, s_max_pu, correction_factor, max_voltage_difference, max_line_rating): + # TODO: Only considers overhead lines + n.lines_t.s_max_pu = (rating / n.lines.s_nom[rating.columns]) * correction_factor + if max_voltage_difference: x_pu = n.lines.type.map(n.line_types["x_per_length"])*n.lines.length/(n.lines.v_nom**2) - s_max_pu_cap = (np.pi / (6 * x_pu * n.lines.s_nom)).clip(lower=1) # need to clip here as cap values might be below 1 -> would mean the line cannot be operated at actual given pessimistic ampacity - n.lines_t.s_max_pu = n.lines_t.s_max_pu.clip(upper=s_max_pu_cap, lower=1, axis=1) - n.lines_t.s_max_pu*=s_max_pu_factor + # need to clip here as cap values might be below 1 + # -> would mean the line cannot be operated at actual given pessimistic ampacity + s_max_pu_cap = (np.pi / (6 * x_pu * n.lines.s_nom)).clip(lower=1) + n.lines_t.s_max_pu = n.lines_t.s_max_pu.clip(lower=1, upper=s_max_pu_cap, axis=1) + if max_line_rating: + n.lines_t.s_max_pu = n.lines_t.s_max_pu.clip(upper=max_line_rating) + n.lines_t.s_max_pu *= s_max_pu - def add_nice_carrier_names(n, config): carrier_i = n.carriers.index nice_names = (pd.Series(config['plotting']['nice_names']) @@ -605,11 +607,27 @@ if __name__ == "__main__": update_p_nom_max(n) - if snakemake.config["lines"]["line_rating"]: - s_max_pu_factor = snakemake.config["lines"]["s_max_pu"] #factor mainly used for N-1 security - dlr_factor=snakemake.config["lines"]["dlr_factor"] #factor due to overestimation of the wind speed in hourly averaged wind data - line_clipping=snakemake.config["lines"]["line_clipping"] - attach_line_rating(n, snakemake.input.line_rating, s_max_pu_factor, dlr_factor, line_clipping) + line_rating_config = snakemake.config["lines"]["dynamic_line_rating"] + if line_rating_config["activate"]: + rating = xr.open_dataarray(snakemake.input.line_rating).to_pandas().transpose() + s_max_pu = snakemake.config["lines"]["s_max_pu"] + correction_factor = line_rating_config['correction_factor'] + max_voltage_difference = line_rating_config['max_voltage_difference'] + max_line_rating = line_rating_config['max_line_rating'] + + if "DLR" in snakemake.wildcards['opts']: + opts = snakemake.wildcards['opts'].split("-") + max_line_rating = float([opt[3:] for opt in opts if "DLR" in opt ].pop()) + logger.info(f"Adjusting maximal relative line rating to {max_line_rating}.") + + attach_line_rating( + n, + rating, + s_max_pu, + correction_factor, + max_voltage_difference, + max_line_rating + ) add_nice_carrier_names(n, snakemake.config) diff --git a/scripts/build_line_rating.py b/scripts/build_line_rating.py index 966d03c6..fa97b251 100755 --- a/scripts/build_line_rating.py +++ b/scripts/build_line_rating.py @@ -84,7 +84,7 @@ def calculate_resistance(T, R_ref, T_ref=293, alpha=0.00403): return R -def calculate_line_rating(n): +def calculate_line_rating(n, cutout): """ Calculates the maximal allowed power flow in each line for each time step considering the maximal temperature. @@ -102,7 +102,6 @@ def calculate_line_rating(n): y = n.buses.y shapes = [Line([Point(x[b0], y[b0]), Point(x[b1], y[b1])]) for (b0, b1) in buses] shapes = gpd.GeoSeries(shapes, index=relevant_lines.index) - cutout = atlite.Cutout(snakemake.input.cutout) if relevant_lines.r_pu.eq(0).all(): # Overwrite standard line resistance with line resistance obtained from line type r_per_length = n.line_types["r_per_length"] @@ -146,6 +145,7 @@ if __name__ == "__main__": configure_logging(snakemake) n = pypsa.Network(snakemake.input.base_network) + cutout = atlite.Cutout(snakemake.input.cutout) - da = calculate_line_rating(n) + da = calculate_line_rating(n, cutout) da.to_netcdf(snakemake.output[0])