Skip to content

Commit ac4ecf9

Browse files
Merge pull request #826 from PowerGridModel/feature/step-up-transformer-tap-changer-support
Step-up transformer tap changer support: feature branch
2 parents 208a620 + e911275 commit ac4ecf9

File tree

62 files changed

+1226
-1246
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1226
-1246
lines changed

docs/user_manual/calculations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ Power flow calculations that take the behavior of these regulators into account
628628

629629
The following control logic is used:
630630

631-
- Regulated transformers are ranked according to how close they are to {hoverxreftooltip}`sources <user_manual/components:source>` in terms of the amount of transformers inbetween.
631+
- Regulated transformers are ranked according to how close they are to {hoverxreftooltip}`sources <user_manual/components:source>` in terms of the amount of regulated transformers inbetween.
632632
- Transformers are regulated in order according to their ranks.
633633
- Initialize all transformers to their starting tap position (see {hoverxreftooltip}`user_manual/calculations:Initialization and exploitation of regulated transformers`)
634634
- Find the optimal state using the following procedure

power_grid_model_c/power_grid_model/include/power_grid_model/common/exception.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,13 @@ class AutomaticTapCalculationError : public PowerGridError {
196196
}
197197
};
198198

199+
class AutomaticTapInputError : public PowerGridError {
200+
public:
201+
AutomaticTapInputError(std::string const& msg) {
202+
append_msg("Automatic tap changer has invalid configuration. " + msg); // NOSONAR
203+
}
204+
};
205+
199206
class IDWrongType : public PowerGridError {
200207
public:
201208
explicit IDWrongType(ID id) { append_msg("Wrong type for object with id " + detail::to_string(id) + '\n'); }

power_grid_model_c/power_grid_model/include/power_grid_model/main_core/input.hpp

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -137,28 +137,8 @@ inline void add_component(MainModelState<ComponentContainer>& state, ForwardIter
137137
}
138138
}();
139139

140-
if (regulated_object_idx.group == get_component_type_index<Transformer>(state)) {
141-
auto const& regulated_object = get_component<Transformer>(state, regulated_object_idx);
142-
143-
auto const non_tap_side =
144-
regulated_object.tap_side() == BranchSide::from ? BranchSide::to : BranchSide::from;
145-
if (get_component<Node>(state, regulated_object.node(regulated_object.tap_side())).u_rated() <
146-
get_component<Node>(state, regulated_object.node(non_tap_side)).u_rated()) {
147-
throw AutomaticTapCalculationError(id);
148-
}
149-
} else if (regulated_object_idx.group == get_component_type_index<ThreeWindingTransformer>(state)) {
150-
auto const& regulated_object = get_component<ThreeWindingTransformer>(state, regulated_object_idx);
151-
auto const tap_side_u_rated =
152-
get_component<Node>(state, regulated_object.node(regulated_object.tap_side())).u_rated();
153-
for (auto const side : branch3_sides) {
154-
if (side == regulated_object.tap_side()) {
155-
continue;
156-
}
157-
if (tap_side_u_rated < get_component<Node>(state, regulated_object.node(side)).u_rated()) {
158-
throw AutomaticTapCalculationError(id);
159-
}
160-
}
161-
} else {
140+
if (regulated_object_idx.group != get_component_type_index<Transformer>(state) &&
141+
regulated_object_idx.group != get_component_type_index<ThreeWindingTransformer>(state)) {
162142
throw InvalidRegulatedObject(input.regulated_object, Component::name);
163143
}
164144

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

Lines changed: 162 additions & 65 deletions
Large diffs are not rendered by default.

src/power_grid_model/_core/error_handling.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from power_grid_model._core.power_grid_core import power_grid_core as pgc
1515
from power_grid_model.errors import (
1616
AutomaticTapCalculationError,
17+
AutomaticTapInputError,
1718
ConflictID,
1819
ConflictVoltage,
1920
IDNotFound,
@@ -71,6 +72,8 @@
7172
_AUTOMATIC_TAP_CALCULATION_ERROR_RE = re.compile(
7273
r"Automatic tap changing regulator with tap_side at LV side is not supported. Found at id (-?\d+)\n"
7374
)
75+
_AUTOMATIC_TAP_INPUT_ERROR_RE = re.compile(r"Automatic tap changer has invalid configuration")
76+
7477
_ID_WRONG_TYPE_RE = re.compile(r"Wrong type for object with id (-?\d+)\n")
7578
_INVALID_CALCULATION_METHOD_RE = re.compile(r"The calculation method is invalid for this calculation!")
7679
_INVALID_SHORT_CIRCUIT_PHASE_OR_TYPE_RE = re.compile(r"short circuit type") # multiple different flavors
@@ -95,6 +98,7 @@
9598
_INVALID_MEASURED_OBJECT_RE: InvalidMeasuredObject,
9699
_INVALID_REGULATED_OBJECT_RE: InvalidRegulatedObject,
97100
_AUTOMATIC_TAP_CALCULATION_ERROR_RE: AutomaticTapCalculationError,
101+
_AUTOMATIC_TAP_INPUT_ERROR_RE: AutomaticTapInputError,
98102
_ID_WRONG_TYPE_RE: IDWrongType,
99103
_INVALID_CALCULATION_METHOD_RE: InvalidCalculationMethod,
100104
_INVALID_SHORT_CIRCUIT_PHASE_OR_TYPE_RE: InvalidShortCircuitPhaseOrType,

src/power_grid_model/errors.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ class AutomaticTapCalculationError(PowerGridError):
9797
"""Automatic tap changer with tap at LV side is unsupported for automatic tap changing calculation."""
9898

9999

100+
class AutomaticTapInputError(PowerGridError):
101+
"""Automatic tap changer has invalid configuration."""
102+
103+
100104
class InvalidShortCircuitPhaseOrType(PowerGridError):
101105
"""Invalid (combination of) short circuit types and phase(s) provided."""
102106

src/power_grid_model/validation/validation.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,7 @@ def validate_regulator(data: SingleDataset, component: ComponentType) -> list[Va
950950
def validate_transformer_tap_regulator(data: SingleDataset) -> list[ValidationError]:
951951
errors = validate_regulator(data, ComponentType.transformer_tap_regulator)
952952
errors += _all_boolean(data, ComponentType.transformer_tap_regulator, "status")
953+
errors += _all_unique(data, ComponentType.transformer_tap_regulator, "regulated_object")
953954
errors += _all_valid_enum_values(
954955
data, ComponentType.transformer_tap_regulator, "control_side", [BranchSide, Branch3Side]
955956
)

tests/cpp_unit_tests/test_optimizer.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ static_assert(std::convertible_to<decltype(stub_const_dataset_update), ConstData
146146

147147
constexpr auto strategies = [] {
148148
using enum OptimizerStrategy;
149-
return std::array{any, global_minimum, global_maximum, local_minimum, local_maximum};
149+
return std::array{any, local_maximum, local_minimum, global_maximum, global_minimum};
150150
}();
151151

152152
constexpr auto calculation_methods = [] {

0 commit comments

Comments
 (0)