From 52831a911029ed497b08766f6ed17441f408e912 Mon Sep 17 00:00:00 2001 From: petersalemink95 Date: Mon, 27 Jan 2025 16:04:24 +0100 Subject: [PATCH 1/7] fix for inf loop Signed-off-by: petersalemink95 --- .../optimizer/tap_position_optimizer.hpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp index 3bbcce84e..76778315f 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp @@ -899,18 +899,23 @@ class TapPositionOptimizerImpl, StateCalculator, adjust_transformer(regulator, state, result, update_data, search, options) || tap_changed; } if (tap_changed) { + iterations_per_rank[rank_index + 1] = 0; // NOSONAR + iterations_per_rank[rank_index] += 1; // NOSONAR break; } - iterations_per_rank[++rank_index] = 0; // NOSONAR + ++rank_index; + // iterations_per_rank[++rank_index] = 0; // NOSONAR } if (tap_changed) { - if (static_cast(++iterations_per_rank[rank_index]) > - 2 * max_tap_ranges_per_rank[rank_index]) { + if (static_cast(iterations_per_rank[rank_index]) > 2 * max_tap_ranges_per_rank[rank_index]) { throw MaxIterationReached{"TapPositionOptimizer::iterate"}; } update_state(update_data); result = calculate_(state, method); ++total_iterations; + if (total_iterations > 50) { // TODO: remove - only for debug purpose + throw MaxIterationReached{" 15 TapPositionOptimizer::iterate"}; + } } } From b4fafc280f77784c9339e17b863bc08a94d9f3f8 Mon Sep 17 00:00:00 2001 From: petersalemink95 Date: Mon, 27 Jan 2025 17:10:45 +0100 Subject: [PATCH 2/7] validation test Signed-off-by: petersalemink95 --- .../input.json | 59 +++++++++++++++++++ .../input.json.license | 3 + .../params.json | 10 ++++ .../params.json.license | 3 + .../sym_output.json | 7 +++ .../sym_output.json.license | 3 + 6 files changed, 85 insertions(+) create mode 100644 tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/input.json create mode 100644 tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/input.json.license create mode 100644 tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/params.json create mode 100644 tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/params.json.license create mode 100644 tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/sym_output.json create mode 100644 tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/sym_output.json.license diff --git a/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/input.json b/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/input.json new file mode 100644 index 000000000..3b748a1cc --- /dev/null +++ b/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/input.json @@ -0,0 +1,59 @@ +{ + "version": "1.0", + "type": "input", + "is_batch": false, + "attributes": {}, + "data": { + "node": [ + {"id": 0, "u_rated": 10000}, + {"id": 1, "u_rated": 10000}, + {"id": 2, "u_rated": 10000}, + {"id": 3, "u_rated": 10000}, + {"id": 4, "u_rated": 10000}, + {"id": 5, "u_rated": 10000}, + {"id": 6, "u_rated": 10000}, + {"id": 7, "u_rated": 400}, + {"id": 8, "u_rated": 400}, + {"id": 9, "u_rated": 400}, + {"id": 10, "u_rated": 400} + ], + "line": [ + {"id": 11, "from_node": 0, "to_node": 1, "from_status": 1, "to_status": 1, "r1": 0.005, "x1": 0.5, "c1": 0, "tan1": 0}, + {"id": 12, "from_node": 0, "to_node": 2, "from_status": 1, "to_status": 1, "r1": 0.1, "x1": 0.6, "c1": 0, "tan1": 0}, + {"id": 13, "from_node": 3, "to_node": 5, "from_status": 1, "to_status": 1, "r1": 0.005, "x1": 0.5, "c1": 0, "tan1": 0}, + {"id": 14, "from_node": 4, "to_node": 6, "from_status": 1, "to_status": 1, "r1": 0.003, "x1": 0.3, "c1": 0, "tan1": 0}, + {"id": 15, "from_node": 7, "to_node": 9, "from_status": 1, "to_status": 1, "r1": 0.005, "x1": 0.5, "c1": 0, "tan1": 0}, + {"id": 16, "from_node": 8, "to_node": 9, "from_status": 1, "to_status": 1, "r1": 0.005, "x1": 0.6, "c1": 0, "tan1": 0} + ], + "transformer": [ + {"id": 17, "from_node": 1, "to_node": 3, "from_status": 1, "to_status": 1, "u1": 10000, "u2": 10000, "sn": 300000, "uk": 0.0005, "pk": 1000, "i0": 0, "p0": 0, "winding_from": 2, "winding_to": 1, "clock": 5, "tap_side": 0, "tap_pos": 0, "tap_min": -10, "tap_max": 10, "tap_size": 100}, + {"id": 18, "from_node": 2, "to_node": 4, "from_status": 1, "to_status": 1, "u1": 10000, "u2": 10000, "sn": 300000, "uk": 0.0005, "pk": 1000, "i0": 0, "p0": 0, "winding_from": 2, "winding_to": 1, "clock": 5, "tap_side": 0, "tap_pos": 0, "tap_min": -10, "tap_max": 10, "tap_size": 100}, + {"id": 19, "from_node": 5, "to_node": 7, "from_status": 1, "to_status": 1, "u1": 10000, "u2": 400, "sn": 300000, "uk": 0.0005, "pk": 1000, "i0": 0, "p0": 0, "winding_from": 2, "winding_to": 1, "clock": 5, "tap_side": 0, "tap_pos": 0, "tap_min": -10, "tap_max": 10, "tap_size": 20}, + {"id": 20, "from_node": 6, "to_node": 8, "from_status": 1, "to_status": 1, "u1": 10000, "u2": 400, "sn": 300000, "uk": 0.0005, "pk": 1000, "i0": 0, "p0": 0, "winding_from": 2, "winding_to": 1, "clock": 5, "tap_side": 0, "tap_pos": 0, "tap_min": -10, "tap_max": 10, "tap_size": 20}, + {"id": 21, "from_node": 9, "to_node": 10, "from_status": 1, "to_status": 1, "u1": 400, "u2": 400, "sn": 300000, "uk": 0.0005, "pk": 1000, "i0": 0, "p0": 0, "winding_from": 2, "winding_to": 1, "clock": 5, "tap_side": 0, "tap_pos": 0, "tap_min": -10, "tap_max": 10, "tap_size": 20} + ], + "source": [ + {"id": 22, "node": 0, "status": 1, "u_ref": 1} + ], + "sym_load": [ + {"id": 23, "node": 0, "status": 1, "type": 0, "p_specified": 100000, "q_specified": 10000}, + {"id": 24, "node": 1, "status": 1, "type": 0, "p_specified": 100000, "q_specified": 10000}, + {"id": 25, "node": 2, "status": 1, "type": 0, "p_specified": 100000, "q_specified": 10000}, + {"id": 26, "node": 3, "status": 1, "type": 0, "p_specified": 100000, "q_specified": 10000}, + {"id": 27, "node": 4, "status": 1, "type": 0, "p_specified": 100000, "q_specified": 10000}, + {"id": 28, "node": 5, "status": 1, "type": 0, "p_specified": 100000, "q_specified": 10000}, + {"id": 29, "node": 6, "status": 1, "type": 0, "p_specified": 100000, "q_specified": 10000}, + {"id": 30, "node": 7, "status": 1, "type": 0, "p_specified": 100000, "q_specified": 10000}, + {"id": 31, "node": 8, "status": 1, "type": 0, "p_specified": 100000, "q_specified": 10000}, + {"id": 32, "node": 9, "status": 1, "type": 0, "p_specified": 100000, "q_specified": 10000}, + {"id": 33, "node": 10, "status": 1, "type": 0, "p_specified": 100000, "q_specified": 10000} + ], + "transformer_tap_regulator": [ + {"id": 34, "regulated_object": 17, "status": 1, "control_side": 1, "u_set": 10000, "u_band": 300}, + {"id": 35, "regulated_object": 18, "status": 1, "control_side": 1, "u_set": 10000, "u_band": 300}, + {"id": 36, "regulated_object": 19, "status": 1, "control_side": 1, "u_set": 400, "u_band": 5}, + {"id": 37, "regulated_object": 20, "status": 1, "control_side": 1, "u_set": 400, "u_band": 5}, + {"id": 38, "regulated_object": 21, "status": 1, "control_side": 1, "u_set": 400, "u_band": 5} + ] + } +} \ No newline at end of file diff --git a/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/input.json.license b/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/input.json.license new file mode 100644 index 000000000..2fcbfaeb5 --- /dev/null +++ b/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/input.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Contributors to the Power Grid Model project + +SPDX-License-Identifier: MPL-2.0 \ No newline at end of file diff --git a/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/params.json b/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/params.json new file mode 100644 index 000000000..c3482bcef --- /dev/null +++ b/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/params.json @@ -0,0 +1,10 @@ +{ + "calculation_method": "newton_raphson", + "tap_changing_strategy": "any_valid_tap", + "rtol": 1e-05, + "atol": 1e-05, + "fail": { + "raises": "MaxIterationReached", + "reason": "TapPositionOptimizer::iterate" + } +} \ No newline at end of file diff --git a/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/params.json.license b/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/params.json.license new file mode 100644 index 000000000..2fcbfaeb5 --- /dev/null +++ b/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/params.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Contributors to the Power Grid Model project + +SPDX-License-Identifier: MPL-2.0 \ No newline at end of file diff --git a/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/sym_output.json b/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/sym_output.json new file mode 100644 index 000000000..682b959f0 --- /dev/null +++ b/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/sym_output.json @@ -0,0 +1,7 @@ +{ + "version": "1.0", + "type": "sym_output", + "is_batch": false, + "attributes": {}, + "data": {} +} \ No newline at end of file diff --git a/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/sym_output.json.license b/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/sym_output.json.license new file mode 100644 index 000000000..2fcbfaeb5 --- /dev/null +++ b/tests/data/power_flow/automatic-tap-regulator/auto-tap-changer-meshed-any-max-iter/sym_output.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Contributors to the Power Grid Model project + +SPDX-License-Identifier: MPL-2.0 \ No newline at end of file From f8c88bf879ab4b839a180e3c0f217abfb0cc69be Mon Sep 17 00:00:00 2001 From: petersalemink95 Date: Mon, 27 Jan 2025 17:26:07 +0100 Subject: [PATCH 3/7] clean-up Signed-off-by: petersalemink95 --- .../power_grid_model/optimizer/tap_position_optimizer.hpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp index 76778315f..95f03de62 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp @@ -899,12 +899,11 @@ class TapPositionOptimizerImpl, StateCalculator, adjust_transformer(regulator, state, result, update_data, search, options) || tap_changed; } if (tap_changed) { - iterations_per_rank[rank_index + 1] = 0; // NOSONAR - iterations_per_rank[rank_index] += 1; // NOSONAR + iterations_per_rank[rank_index + 1] = 0; + iterations_per_rank[rank_index] += 1; break; } ++rank_index; - // iterations_per_rank[++rank_index] = 0; // NOSONAR } if (tap_changed) { if (static_cast(iterations_per_rank[rank_index]) > 2 * max_tap_ranges_per_rank[rank_index]) { @@ -913,9 +912,6 @@ class TapPositionOptimizerImpl, StateCalculator, update_state(update_data); result = calculate_(state, method); ++total_iterations; - if (total_iterations > 50) { // TODO: remove - only for debug purpose - throw MaxIterationReached{" 15 TapPositionOptimizer::iterate"}; - } } } From 257a1cb6e44e2300bc9c5d31cfc92a74eea6ce5d Mon Sep 17 00:00:00 2001 From: petersalemink95 Date: Tue, 28 Jan 2025 08:36:04 +0100 Subject: [PATCH 4/7] match c++ exception with Python Signed-off-by: petersalemink95 --- .../include/power_grid_model/common/exception.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/common/exception.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/common/exception.hpp index e0db9e154..14218306b 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/common/exception.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/common/exception.hpp @@ -135,7 +135,7 @@ class IterationDiverge : public PowerGridError { class MaxIterationReached : public IterationDiverge { public: MaxIterationReached(std::string const& msg = "") { - append_msg("Maximum iterations reached, no solution. " + msg + "\n"); + append_msg("Maximum number of iterations reached" + msg + "\n"); } }; From b4174d36a3707b27dc28083a7fdc35e33c237c10 Mon Sep 17 00:00:00 2001 From: petersalemink95 Date: Tue, 28 Jan 2025 08:45:56 +0100 Subject: [PATCH 5/7] add error to tests Signed-off-by: petersalemink95 --- tests/unit/utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit/utils.py b/tests/unit/utils.py index 7d246e3fd..c28739da6 100644 --- a/tests/unit/utils.py +++ b/tests/unit/utils.py @@ -30,6 +30,7 @@ PowerGridError, PowerGridSerializationError, SparseMatrixError, + MaxIterationReached ) from power_grid_model.utils import json_deserialize, json_deserialize_from_file, json_serialize_to_file @@ -60,6 +61,7 @@ PowerGridSerializationError, AssertionError, OSError, + MaxIterationReached, ) } From 44c5272dda4612e9dd7a140fbe91d94c8b96be5d Mon Sep 17 00:00:00 2001 From: petersalemink95 Date: Tue, 28 Jan 2025 08:48:59 +0100 Subject: [PATCH 6/7] linter Signed-off-by: petersalemink95 --- tests/unit/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/utils.py b/tests/unit/utils.py index c28739da6..3c9ef8a92 100644 --- a/tests/unit/utils.py +++ b/tests/unit/utils.py @@ -25,12 +25,12 @@ InvalidMeasuredObject, InvalidRegulatedObject, InvalidTransformerClock, + MaxIterationReached, NotObservableError, PowerGridBatchError, PowerGridError, PowerGridSerializationError, SparseMatrixError, - MaxIterationReached ) from power_grid_model.utils import json_deserialize, json_deserialize_from_file, json_serialize_to_file From 4bf2a28f4d8849838e7abe54ae8e38e1e443bcf3 Mon Sep 17 00:00:00 2001 From: petersalemink95 Date: Tue, 28 Jan 2025 09:26:17 +0100 Subject: [PATCH 7/7] ++ instead of +=1 Signed-off-by: petersalemink95 --- .../power_grid_model/optimizer/tap_position_optimizer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp index 95f03de62..1da69591c 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp @@ -900,7 +900,7 @@ class TapPositionOptimizerImpl, StateCalculator, } if (tap_changed) { iterations_per_rank[rank_index + 1] = 0; - iterations_per_rank[rank_index] += 1; + ++iterations_per_rank[rank_index]; break; } ++rank_index;