diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a2153853d..0c607d2b8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -42,6 +42,7 @@ Change Log - [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 +- [FIXED] bugfix for tap dependent impedance characteristics so that not all characteristics columns are necessary [2.13.1] - 2023-05-12 ------------------------------- diff --git a/pandapower/build_branch.py b/pandapower/build_branch.py index d194e71ad..8cac7cfa9 100644 --- a/pandapower/build_branch.py +++ b/pandapower/build_branch.py @@ -498,6 +498,7 @@ def _get_vk_values(trafo_df, characteristic, trafotype="2W"): # must cast to float64 unfortunately, because numpy.vstack casts arrays to object because it doesn't know pandas.NA, np.isnan fails all_characteristic_idx = np.vstack([get_trafo_values( trafo_df, f"{c}_characteristic").astype(np.float64) for c in char_columns]).T + index_column = {c: i for i, c in enumerate(char_columns)} # now we check if any trafos that have tap_dependent_impedance have all of the characteristics missing all_missing = np.isnan(all_characteristic_idx).all(axis=1) & tap_dependent_impedance if np.any(all_missing): @@ -512,7 +513,7 @@ def _get_vk_values(trafo_df, characteristic, trafotype="2W"): if use_tap_dependent_impedance and vk_var in char_columns: vals += (_calc_tap_dependent_value( trafo_df, tap_pos, vk_value, vk_var, tap_dependent_impedance, - characteristic, all_characteristic_idx[:, c]),) + characteristic, all_characteristic_idx[:, index_column[vk_var]]),) else: vals += (vk_value,) diff --git a/pandapower/test/loadflow/test_results.py b/pandapower/test/loadflow/test_results.py index 14b5ed03a..1f5058ed0 100644 --- a/pandapower/test/loadflow/test_results.py +++ b/pandapower/test/loadflow/test_results.py @@ -363,6 +363,48 @@ def test_undefined_tap_dependent_impedance_characteristics(): pp.runpp(net) +def test_undefined_tap_dependent_impedance_characteristics_trafo3w(): + # if some characteristic per 1 trafo are undefined, but at least 1 is defined -> OK + # if all characteristic per 1 trafo are undefined -> raise error + net = create_net() + add_trafo_connection(net, 1, "3W") + add_trafo_connection(net, 1, "3W") + net2 = create_net() + add_trafo_connection(net2, 1, "3W") + add_trafo_connection(net2, 1, "3W") + + pp.control.create_trafo_characteristics(net, 'trafo3w', [0, 1], 'vk_mv_percent', [[-2, -1, 0, 1, 2], [-2, -1, 0, 1, 2]], [[0.7, 0.9, 1, 1.1, 1.3], [0.7, 0.9, 1, 1.1, 1.3]]) + pp.control.create_trafo_characteristics(net, 'trafo3w', [0, 1], 'vkr_mv_percent', [[-2, -1, 0, 1, 2], [-2, -1, 0, 1, 2]], [[0.3, 0.45, 0.5, 0.55, 0.7], [0.3, 0.45, 0.5, 0.55, 0.7]]) + + pp.control.Characteristic(net2, [-2, -1, 0, 1, 2], [0.7, 0.9, 1, 1.1, 1.3]) + pp.control.Characteristic(net2, [-2, -1, 0, 1, 2], [0.3, 0.45, 0.5, 0.55, 0.7]) + + pp.control.TapDependentImpedance(net2, [0], 0, trafotable="trafo3w", output_variable="vk_mv_percent") + pp.control.TapDependentImpedance(net2, [0], 1, trafotable="trafo3w", output_variable="vkr_mv_percent") + pp.control.TapDependentImpedance(net2, [1], 0, trafotable="trafo3w", output_variable="vk_mv_percent") + pp.control.TapDependentImpedance(net2, [1], 1, trafotable="trafo3w", output_variable="vkr_mv_percent") + + pp.runpp(net) + pp.runpp(net2, run_control=True) + assert_res_equal(net, net2) + + net.trafo3w.at[0, "vk_mv_percent_characteristic"] = None + pp.runpp(net) + net2.controller.at[0, "in_service"] = False + pp.runpp(net2, run_control=True) + assert_res_equal(net, net2) + + net.trafo3w.at[0, "vkr_mv_percent_characteristic"] = None + net2.controller.at[1, "in_service"] = False + with pytest.raises(UserWarning): + pp.runpp(net) + + net.trafo3w.at[0, "tap_dependent_impedance"] = False + pp.runpp(net) + pp.runpp(net2, run_control=True) + assert_res_equal(net, net2) + + def test_ext_grid(result_test_network, v_tol=1e-6, va_tol=1e-2, i_tol=1e-6, s_tol=5e-3, l_tol=1e-3): net = result_test_network runpp_with_consistency_checks(net, calculate_voltage_angles=True)