Skip to content

Commit 1564bba

Browse files
authored
Merge pull request PowerGridModel#1279 from PowerGridModel/feature/unique-id-in-trafo-reg-side-error-message
Report unique ID in trafrmer regulate side error message
2 parents 2095f64 + 1db504a commit 1564bba

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,11 @@ inline auto get_edge_weights(TransformerGraph const& graph) -> TrafoGraphEdgePro
358358

359359
// Throw error at the end with all problematic transformer IDs
360360
if (!trafo_ids_invalid_reg_side.empty()) {
361+
// Remove duplicates (e.g., from three-winding transformers with multiple edges)
362+
std::ranges::sort(trafo_ids_invalid_reg_side);
363+
auto [first, last] = std::ranges::unique(trafo_ids_invalid_reg_side);
364+
trafo_ids_invalid_reg_side.erase(first, last);
365+
361366
std::ostringstream error_msg;
362367
error_msg << "The following transformer(s) are being controlled from non-source side towards source side:\n";
363368
error_msg << " Transformer IDs: ";

tests/cpp_unit_tests/test_tap_position_optimizer.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,50 @@ TEST_CASE("Test Transformer ranking") {
649649
CHECK(error_msg.find("Transformer ID: 50") == std::string::npos);
650650
}
651651
}
652+
653+
SUBCASE("Three-winding transformer with wrong regulated side - unique report ID test") {
654+
// Test that a three-winding transformer with multiple invalid edges reports its ID only once
655+
// ========Test Grid========
656+
// [source 0]
657+
// |
658+
// [3w-trafo 10] (WRONG: controlled from side_1, which points towards source)
659+
// / | |
660+
// [node 1] [node 2] [node 3]
661+
662+
TestState state;
663+
std::vector<NodeInput> const nodes{{.id = 0, .u_rated = 150e3},
664+
{.id = 1, .u_rated = 10e3},
665+
{.id = 2, .u_rated = 10e3},
666+
{.id = 3, .u_rated = 10e3}};
667+
main_core::add_component<Node>(state.components, nodes, 50.0);
668+
669+
// Three-winding transformer with tap on side_1, controlled from side_1 (towards source - wrong)
670+
std::vector<ThreeWindingTransformerInput> const transformers3w{
671+
get_transformer3w(10, 0, 1, 2, Branch3Side::side_1, 0)};
672+
main_core::add_component<ThreeWindingTransformer>(state.components, transformers3w, 50.0);
673+
674+
std::vector<SourceInput> const sources{SourceInput{.id = 20, .node = 0, .status = IntS{1}, .u_ref = 1.0}};
675+
main_core::add_component<Source>(state.components, sources, 50.0);
676+
677+
std::vector<TransformerTapRegulatorInput> const regulators{
678+
get_regulator(30, 10, ControlSide::side_1) // Wrong: controlling towards source
679+
};
680+
main_core::add_component<TransformerTapRegulator>(state.components, regulators, 50.0);
681+
682+
state.components.set_construction_complete();
683+
684+
// Should throw error mentioning transformer 10 only once (even though it has multiple edges)
685+
try {
686+
pgm_tap::rank_transformers(state);
687+
FAIL("Expected AutomaticTapInputError to be thrown");
688+
} catch (AutomaticTapInputError const& e) {
689+
std::string const error_msg = e.what();
690+
// Check complete error message - ID 10 should appear only once
691+
CHECK(error_msg == "Automatic tap changer has invalid configuration. The following transformer(s) are "
692+
"being controlled from non-source side towards "
693+
"source side:\n Transformer IDs: 10");
694+
}
695+
}
652696
}
653697

654698
namespace optimizer::tap_position_optimizer::test {

0 commit comments

Comments
 (0)