Skip to content

[FEATURE] PGM Meet-up 2025-05-21 hackathon: attribute modification in C++ core #987

@Jerry-Jinfeng-Guo

Description

@Jerry-Jinfeng-Guo

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 $[0, 12]$ can be remapped back to this range to maintain a continuous domain. Mathematically, the cyclic clock function $( \phi )$ can be defined as follows:

$[ \phi(h) = 30h ]$

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:

$[ \phi(h) = 30h \mod 360 ]$

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

No one assigned

    Labels

    good first issueIndicates a good issue for first-time contributorsimprovementImprovement on internal implementation

    Type

    Projects

    Status

    Q2 2025

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions