Description
Attribute modification
This topic aims to familiarize contributors with development inside the C++ core. To make the initial step easier and the feedback loop shorter, we start with modification to existing attributes. We walk you through a first example of extending the attribute handling of attribute clock_
in class Transformer
.
Background
the term "clock" refers to the phase displacement between the primary and secondary windings of a three-phase transformer. This phase displacement is crucial for understanding how the transformer will interact with other components in the power system.
Clock Notation in Transformers
The clock notation is a method used to describe the phase displacement. Imagine a clock face where the hour hand represents the high voltage (HV) winding and the minute hand represents the low voltage (LV) winding. The position of the minute hand relative to the hour hand indicates the phase displacement.
Values Between 0 and 12
The values between 0 and 12 correspond to the positions on a clock face, where each hour represents a 30-degree phase shift, which is the amount of angle difference between the secondary side and the primary side of the transformer. For example:
- 0: No phase displacement (0 degrees)
- 1: 30 degrees phase displacement
- 2: 60 degrees phase displacement
- 3: 90 degrees phase displacement
- 6: 180 degrees phase displacement
- 12: 360 degrees phase displacement (which is effectively the same as 0 degrees)
This notation helps in standardizing the description of transformers and ensures compatibility and proper functioning within the electrical grid.
Practical Example
If a transformer has a clock notation of 1, it means that the LV winding leads the HV winding by 30 degrees. If the clock notation is 11, the LV winding lags the HV winding by 30 degrees.
This system is widely used because it provides a simple and intuitive way to understand and communicate the phase relationships in three-phase transformers, which is essential for the design and operation of electrical power systems.
Goal
It is readily clear that the clock attribute is a cyclic variable. Meaning that values outside range
where:
-
$( \phi(h) )$ is the phase displacement in degrees. -
$( h )$ is the clock hour, which takes values from 0 to 12
The function is cyclic because after 12 o'clock, the phase displacement resets to 0 degrees. This cyclic behavior can be represented using modulo arithmetic:
This ensures that the phase displacement wraps around after reaching 360 degrees
The goal of this example is to extend the current clock
handling inside power-grid-model such that it reflect this cyclic nature.
How-to
The source file in speak is power_grid_model_c\power_grid_model\include\power_grid_model\component\transformer.hpp
.
The following code snippet is responsible for the clock_
handling:
// set clock to zero if it is 12
clock_ = static_cast<IntS>(clock_ % 12);
N.B., this already handles the cyclic mapping of clock. However, there is a check prior to this operation:
if (!is_valid_clock(clock_, winding_from_, winding_to_)) {
throw InvalidTransformerClock{id(), clock_};
}
where function is_valid_clock
is defined in power_grid_model_c\power_grid_model\include\power_grid_model\component\transformer_utils.hpp
as:
constexpr bool is_valid_clock(IntS clock, WindingType winding_from, WindingType winding_to) {
using enum WindingType;
bool const clock_in_range = 0 <= clock && clock <= 12;
bool const clock_is_even = (clock % 2) == 0;
bool const is_from_wye = winding_from == wye || winding_from == wye_n;
bool const is_to_wye = winding_to == wye || winding_to == wye_n;
// even clock number is only possible when both sides are wye winding or both sides aren't
// and conversely for odd clock number
bool const correct_clock_winding = (clock_is_even == (is_from_wye == is_to_wye));
return clock_in_range && correct_clock_winding;
}
This eliminates the possibility of having out of range clock values. We can extend the handling by removing this constraint because the %
operator makes sure the mapped clock_
value is always valid.
Steps
Consider the following:
- Follow the C++ setup in the main issue ([Feature] PGM Meet-up 2025-05-21 Hackathons #977)
- Update the
is_valid_clock
function to allow out of range clock values, pay attention to types - Propose a new scheme for the existing
InvalidTransformerClock
exception, including on the Python side - Write necessary unit test for the updated behavior
- Create validation test to check whether the result calculated with transformers initialized with out of range clock are correct
- Update the Python validation w.r.t. transformer clocks
- Update the documentation w.r.t. the updated requirements. See transformer documentation
- Make sure CI passes
Next
Now that you have made a contribution in the core, can you think of more places where the handling of component attributes could be extended? This is of course under the premise that the new handling is conformant to physics. Make your own proposal and try it out!
Metadata
Metadata
Assignees
Type
Projects
Status