From ddfda01ff12f4e81a8083ec692edcc5a028bc6d9 Mon Sep 17 00:00:00 2001 From: mvogt Date: Wed, 27 Sep 2023 11:32:54 +0200 Subject: [PATCH 1/6] some fixes around the generation of generic coordinates. (cherry picked from commit 3cf392416515b2ed4176742771a913bf5b44ffad) --- pandapower/plotting/generic_geodata.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pandapower/plotting/generic_geodata.py b/pandapower/plotting/generic_geodata.py index 42474a83e..ecb07c6a3 100644 --- a/pandapower/plotting/generic_geodata.py +++ b/pandapower/plotting/generic_geodata.py @@ -142,29 +142,32 @@ def coords_from_igraph(graph, roots, meshed=False, calculate_meshed=False): return list(zip(*layout.coords)) -def coords_from_nxgraph(mg=None): +def coords_from_nxgraph(mg=None, layout_engine='neato'): """ Create a list of generic coordinates from a networkx graph layout. :param mg: The networkx graph on which the coordinates shall be based :type mg: networkx.Graph + :param layout_engine: GraphViz Layout Engine for layouting a network. See https://graphviz.org/docs/layouts/ + :type layout_engine: str :return: coords - list of coordinates from the graph layout """ # workaround for bug in agraph - for u, v in mg.edges(data=False, keys=False): + for u, v in mg.edges(data=False): if 'key' in mg[int(u)][int(v)]: del mg[int(u)][int(v)]['key'] if 'key' in mg[int(u)][int(v)][0]: del mg[int(u)][int(v)][0]['key'] # ToDo: Insert fallback layout for nxgraph - return list(zip(*(list(nx.drawing.nx_agraph.graphviz_layout(mg, prog='neato').values())))) + return list(zip(*(list(nx.drawing.nx_agraph.graphviz_layout(mg, prog=layout_engine).values())))) def create_generic_coordinates(net, mg=None, library="igraph", respect_switches=False, geodata_table="bus_geodata", buses=None, - overwrite=False): + overwrite=False, + layout_engine='neato'): """ This function will add arbitrary geo-coordinates for all buses based on an analysis of branches and rings. It will remove out of service buses/lines from the net. The coordinates will be @@ -174,6 +177,8 @@ def create_generic_coordinates(net, mg=None, library="igraph", :type net: pandapowerNet :param mg: Existing networkx multigraph, if available. Convenience to save computation time. :type mg: networkx.Graph + :param respect_switches: respect switches in a network for generic coordinates + :type respect_switches: bool :param library: "igraph" to use igraph package or "networkx" to use networkx package :type library: str :param geodata_table: table to write the generic geodatas to @@ -182,6 +187,8 @@ def create_generic_coordinates(net, mg=None, library="igraph", :type buses: list :param overwrite: overwrite existing geodata :type overwrite: bool + :param layout_engine: GraphViz Layout Engine for layouting a network. See https://graphviz.org/docs/layouts/ + :type layout_engine: str :return: net - pandapower network with added geo coordinates for the buses :Example: @@ -200,7 +207,7 @@ def create_generic_coordinates(net, mg=None, library="igraph", include_out_of_service=True) else: nxg = copy.deepcopy(mg) - coords = coords_from_nxgraph(nxg) + coords = coords_from_nxgraph(nxg, layout_engine=layout_engine) else: raise ValueError("Unknown library %s - chose 'igraph' or 'networkx'" % library) if len(coords): From 3e5dd89ddf6d9d3b94d4cd53e3b6d7198f1a8f86 Mon Sep 17 00:00:00 2001 From: Roman Bolgaryn Date: Tue, 24 Oct 2023 14:46:59 +0200 Subject: [PATCH 2/6] bugfix powerflow algorithm id for fdxb, fdbx (closes #2142) --- CHANGELOG.rst | 1 + pandapower/pf/runpf_pypower.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6eb76b3f1..ffa31e7a7 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -32,6 +32,7 @@ Change Log - [CHANGED] PowerFactory converter - name :code:`for_name` as :code:`equipment` for all elements; also add to line - [ADDED] option to use a second tap changer for the trafo element - [FIXED] :code:`convert_format.py`: update the attributes of the characteristic objects to match the new characteristic +- [FIXED] fixed the wrong id numbers for pypower powerflow algorithms fdxb and fdbx [2.13.1] - 2023-05-12 diff --git a/pandapower/pf/runpf_pypower.py b/pandapower/pf/runpf_pypower.py index 6972a7739..5b912eb22 100644 --- a/pandapower/pf/runpf_pypower.py +++ b/pandapower/pf/runpf_pypower.py @@ -78,7 +78,7 @@ def _get_options(options, **kwargs): max_iteration = options["max_iteration"] # algorithms implemented within pypower - algorithm_pypower_dict = {'nr': 1, 'fdbx': 2, 'fdxb': 3, 'gs': 4} + algorithm_pypower_dict = {'nr': 1, 'fdxb': 2, 'fdbx': 3, 'gs': 4} ppopt = ppoption(ENFORCE_Q_LIMS=enforce_q_lims, PF_TOL=tolerance_mva, PF_ALG=algorithm_pypower_dict[algorithm], **kwargs) From 02b312ccc0955ef9c201bd47e38a08d4138ae12b Mon Sep 17 00:00:00 2001 From: dlohmeier Date: Thu, 7 Dec 2023 15:09:16 +0100 Subject: [PATCH 3/6] added option to hand over graph in calc_distance_to_bus --- pandapower/topology/graph_searches.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pandapower/topology/graph_searches.py b/pandapower/topology/graph_searches.py index 832641f70..55e002f47 100644 --- a/pandapower/topology/graph_searches.py +++ b/pandapower/topology/graph_searches.py @@ -87,7 +87,7 @@ def connected_components(mg, notravbuses=set()): def calc_distance_to_bus(net, bus, respect_switches=True, nogobuses=None, - notravbuses=None, weight='weight'): + notravbuses=None, weight='weight', g=None): """ Calculates the shortest distance between a source bus and all buses connected to it. @@ -110,6 +110,8 @@ def calc_distance_to_bus(net, bus, respect_switches=True, nogobuses=None, **weight** (string, None) – Edge data key corresponding to the edge weight. + **g** (nx.MultiGraph, None) – MultiGraph of the network. If None, the graph will be created. + OUTPUT: **dist** - Returns a pandas series with containing all distances to the source bus in km. If weight=None dist is the topological distance (int). @@ -120,8 +122,9 @@ def calc_distance_to_bus(net, bus, respect_switches=True, nogobuses=None, dist = top.calc_distance_to_bus(net, 5) """ - g = create_nxgraph(net, respect_switches=respect_switches, nogobuses=nogobuses, - notravbuses=notravbuses) + if g is None: + g = create_nxgraph(net, respect_switches=respect_switches, nogobuses=nogobuses, + notravbuses=notravbuses) return pd.Series(nx.single_source_dijkstra_path_length(g, bus, weight=weight)) From e103bfda0de04107d5e8621b30a522354e2c3c4c Mon Sep 17 00:00:00 2001 From: Roman Bolgaryn Date: Fri, 29 Dec 2023 10:55:25 +0100 Subject: [PATCH 4/6] add some safegueards for numerical issues in TDPF --- CHANGELOG.rst | 1 + pandapower/pf/create_jacobian_tdpf.py | 2 +- pandapower/pypower/newtonpf.py | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b22224b5b..bff6a3fe0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -39,6 +39,7 @@ Change Log - [CHANGED] cim2pp: extracted getting default classes, added generic setting datatypes from CGMES XMI schema - [ADDED] function :code:`getOTDF` to obtain Outage Transfer Distribution Factors, that can be used to analyse outages using the DC approximation of the power system - [ADDED] function :code:`outage_results_OTDF` to obtain the matrix of results for all outage scenarios, with rows as outage scenarios and columns as branch power flows in that scenario +- [FIXED] add some safeguards for TDPF to avoid numerical issues in some cases [2.13.1] - 2023-05-12 diff --git a/pandapower/pf/create_jacobian_tdpf.py b/pandapower/pf/create_jacobian_tdpf.py index efae27ed6..b89eeb010 100644 --- a/pandapower/pf/create_jacobian_tdpf.py +++ b/pandapower/pf/create_jacobian_tdpf.py @@ -115,7 +115,7 @@ def calc_r_theta(t_air_pu, a0, a1, a2, i_square_pu, p_loss_pu): 2019, pp. 1-6, doi: 10.1109/EEEIC.2019.8783234. """ t_rise_pu = a0 + a1 * i_square_pu + a2 * np.square(i_square_pu) - t_air_pu - r_theta_pu = t_rise_pu / p_loss_pu + r_theta_pu = t_rise_pu / np.where(p_loss_pu == 0, 1e-6, p_loss_pu) return r_theta_pu diff --git a/pandapower/pypower/newtonpf.py b/pandapower/pypower/newtonpf.py index a0f836fbf..a2bddb8a2 100644 --- a/pandapower/pypower/newtonpf.py +++ b/pandapower/pypower/newtonpf.py @@ -298,7 +298,8 @@ def newtonpf(Ybus, Sbus, V0, ref, pv, pq, ppci, options, makeYbus=None): if tdpf: # update the R, g, b for the tdpf_lines, and the Y-matrices - branch[tdpf_lines, BR_R] = r = r_ref_pu * (1 + alpha_pu * (T - t_ref_pu)) + # here: limit the change of the R to reflect a realistic range of values for T to avoid numerical issues + branch[tdpf_lines, BR_R] = r = r_ref_pu * (1 + alpha_pu * np.clip(np.nan_to_num(T - t_ref_pu), -50, 250 / T_base)) # todo expansion with SSC and VSC (that are not controllable) Ybus, Yf, Yt = makeYbus(baseMVA, bus, branch) g, b = calc_g_b(r, x) From 28bdec537b52e7fe4ca5946ed250bc5ac3113a5f Mon Sep 17 00:00:00 2001 From: Roman Bolgaryn Date: Wed, 10 Jan 2024 16:49:33 +0100 Subject: [PATCH 5/6] contingency: add option to raise errors if a contingency leads to an error instead of skipping it --- pandapower/contingency/contingency.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandapower/contingency/contingency.py b/pandapower/contingency/contingency.py index eeb185baf..8e1081a2f 100644 --- a/pandapower/contingency/contingency.py +++ b/pandapower/contingency/contingency.py @@ -72,6 +72,7 @@ def run_contingency(net, nminus1_cases, pf_options=None, pf_options_nminus1=None """ # set up the dict for results and relevant variables # ".get" in case the options have been set in pp.set_user_pf_options: + raise_errors = kwargs.get("raise_errors", False) if "recycle" in kwargs: kwargs["recycle"] = False # so that we can be sure it doesn't happen if pf_options is None: pf_options = net.user_pf_options.get("pf_options", net.user_pf_options) if pf_options_nminus1 is None: pf_options_nminus1 = net.user_pf_options.get("pf_options_nminus1", @@ -104,6 +105,8 @@ def run_contingency(net, nminus1_cases, pf_options=None, pf_options_nminus1=None cause_element=element, cause_index=i) except Exception as err: logger.error(f"{element} {i} causes {err}") + if raise_errors: + raise err finally: net[element].at[i, 'in_service'] = True From bbacfa6b73b289f54324f16ee8eac84f5922173b Mon Sep 17 00:00:00 2001 From: Roman Bolgaryn Date: Wed, 10 Jan 2024 16:53:14 +0100 Subject: [PATCH 6/6] changelog --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f1f3785d6..a2153853d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -41,7 +41,7 @@ Change Log - [ADDED] function :code:`getOTDF` to obtain Outage Transfer Distribution Factors, that can be used to analyse outages using the DC approximation of the power system - [ADDED] function :code:`outage_results_OTDF` to obtain the matrix of results for all outage scenarios, with rows as outage scenarios and columns as branch power flows in that scenario - [FIXED] add some safeguards for TDPF to avoid numerical issues in some cases - +- [ADDED] the function :code:`run_contingency` can raise a captured error if parameter :code:`raise_errors` is passed [2.13.1] - 2023-05-12 -------------------------------