# Components The attributes of components are listed below. ## Base * type name: `base` The base type for all power-grid-model components. #### Input | name | data type | unit | description | required | update | | ---- | --------- | ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------: | :----------------------------------------------------------------------------: | | `id` | `int32_t` | - | ID of a component. The ID should be unique across all components within the same scenario, e.g., you cannot have a node with `id=5` and another line with `id=5`. | ✔ | ❌ (see below) | If a component update is uniform and is updating all the elements with the same component type, IDs can be omitted or set to `nan`s. In any other case, the IDs need to be present in the update dataset, but cannot be changed. Uniform component updates are ones that update the same number of component of the same type across scenarios. By definition, a dense update is always uniform, hence the IDs can always be optional; whereas for a sparse update, the IDs can only be optional if the index pointer is given as an arithmetic sequence of all elements (i.e. a sparse representation of a dense buffer). An example of the usage of optional IDs is given in [Power Flow Example](./Power%20Flow%20Example.ipynb) #### Steady state output and Short circuit output | name | data type | unit | description | | ----------- | --------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------- | | `id` | `int32_t` | - | ID of a component, the ID should be unique across all components, e.g., you cannot have a node with `id=5` and a line with `id=5`. | | `energized` | `int8_t` | - | Indicates if a component is energized, i.e. connected to a source | ## Node * type name: `node` * base: {hoverxreftooltip}`user_manual/components:base` `node` is a point in the grid. Physically a node can be a busbar, a joint, or other similar component. #### Input | name | data type | unit | description | required | update | valid values | | --------- | --------- | -------- | ----------------------- | :------: | :------: | :----------: | | `u_rated` | `double` | volt (V) | rated line-line voltage | ✔ | ❌ | `> 0` | #### Steady state output | name | data type | unit | description | | --------- | ----------------- | -------------------------- | ----------------------------------------------------------------------------------------------- | | `u_pu` | `RealValueOutput` | - | per-unit voltage magnitude | | `u_angle` | `RealValueOutput` | rad | voltage angle | | `u` | `RealValueOutput` | volt (V) | voltage magnitude, line-line for symmetric calculation, line-neutral for asymmetric calculation | | `p` | `RealValueOutput` | watt (W) | active power injection | | `q` | `RealValueOutput` | volt-ampere-reactive (var) | reactive power injection | ```{note} The `p` and `q` output of injection follows the `generator` reference direction as mentioned in {hoverxreftooltip}`user_manual/data-model:Reference Direction` ``` #### Short circuit output | name | data type | unit | description | | --------- | ----------------- | -------- | -------------------------------- | | `u_pu` | `RealValueOutput` | - | per-unit voltage magnitude | | `u_angle` | `RealValueOutput` | rad | voltage angle | | `u` | `RealValueOutput` | volt (V) | voltage magnitude (line-neutral) | ## Branch * type name: `branch` * base: {hoverxreftooltip}`user_manual/components:base` `branch` is the abstract base type for the component which connects two *different* nodes. For each branch two switches are always defined at from- and to-side of the branch. In reality such switches may not exist. For example, a cable usually permanently connects two joints. In this case, the attribute `from_status` and `to_status` is always 1. #### Input | name | data type | unit | description | required | update | valid values | | ------------- | --------- | ---- | ------------------------------ | :------: | :------: | :-------------: | | `from_node` | `int32_t` | - | ID of node at from-side | ✔ | ❌ | a valid node ID | | `to_node` | `int32_t` | - | ID of node at to-side | ✔ | ❌ | a valid node ID | | `from_status` | `int8_t` | - | connection status at from-side | ✔ | ✔ | `0` or `1` | | `to_status` | `int8_t` | - | connection status at to-side | ✔ | ✔ | `0` or `1` | #### Steady state output | name | data type | unit | description | | --------- | ----------------- | -------------------------- | -------------------------------------------------------- | | `p_from` | `RealValueOutput` | watt (W) | active power flowing into the branch at from-side | | `q_from` | `RealValueOutput` | volt-ampere-reactive (var) | reactive power flowing into the branch at from-side | | `i_from` | `RealValueOutput` | ampere (A) | current at from-side | | `s_from` | `RealValueOutput` | volt-ampere (VA) | apparent power flowing at from-side | | `p_to` | `RealValueOutput` | watt (W) | active power flowing into the branch at to-side | | `q_to` | `RealValueOutput` | volt-ampere-reactive (var) | reactive power flowing into the branch at to-side | | `i_to` | `RealValueOutput` | ampere (A) | current at to-side | | `s_to` | `RealValueOutput` | volt-ampere (VA) | apparent power flowing at to-side | | `loading` | `double` | - | relative loading of the line, `1.0` meaning 100% loaded. | #### Short circuit output | name | data type | unit | description | | -------------- | ----------------- | ---------- | -------------------------- | | `i_from` | `RealValueOutput` | ampere (A) | current at from-side | | `i_from_angle` | `RealValueOutput` | rad | current angle at from-side | | `i_to` | `RealValueOutput` | ampere (A) | current at to-side | | `i_to_angle` | `RealValueOutput` | rad | current angle at to-side | ### Line * type name: `line` `line` is a {hoverxreftooltip}`user_manual/components:branch` with specified serial impedance and shunt admittance. A cable is also modeled as `line`. A `line` can only connect two nodes with the same rated voltage. If `i_n` is not provided, `loading` of line will be a `nan` value. #### Input | name | data type | unit | description | required | update | valid values | | ------ | --------- | ---------- | ------------------------------------------ | :---------------------------------------: | :------: | :--------------------------------: | | `r1` | `double` | ohm (Ω) | positive-sequence serial resistance | ✔ | ❌ | `r1` and `x1` cannot be both `0.0` | | `x1` | `double` | ohm (Ω) | positive-sequence serial reactance | ✔ | ❌ | `r1` and `x1` cannot be both `0.0` | | `c1` | `double` | farad (F) | positive-sequence shunt capacitance | ✔ | ❌ | | | `tan1` | `double` | - | positive-sequence shunt loss factor (tan𝛿) | ✔ | ❌ | | | `r0` | `double` | ohm (Ω) | zero-sequence serial resistance | ✨ only for asymmetric calculations | ❌ | `r0` and `x0` cannot be both `0.0` | | `x0` | `double` | ohm (Ω) | zero-sequence serial reactance | ✨ only for asymmetric calculations | ❌ | `r0` and `x0` cannot be both `0.0` | | `c0` | `double` | farad (F) | zero-sequence shunt capacitance | ✨ only for asymmetric calculations | ❌ | | | `tan0` | `double` | - | zero-sequence shunt loss factor (tan𝛿) | ✨ only for asymmetric calculations | ❌ | | | `i_n` | `double` | ampere (A) | rated current | ❌ | ❌ | `> 0` | ```{note} In case of short circuit calculations, the zero-sequence parameters are required only if any of the faults in any of the scenarios within a batch are not three-phase faults (i.e. `fault_type` is not `FaultType.three_phase`). ``` #### Electric Model `line` is described by a $\pi$ model, where $$ \begin{eqnarray} & Z_{\text{series}} = r + \mathrm{j}x \\ & Y_{\text{shunt}} = \frac{2 \pi fc}{\tan \delta +\mathrm{j}} \end{eqnarray} $$ ### Link * type name: `link` `link` is a {hoverxreftooltip}`user_manual/components:branch` which usually represents a short internal cable/connection between two busbars inside a substation. It has a very high admittance (small impedance) which is set to a fixed per-unit value (equivalent to 10e6 siemens for 10kV network). Therefore, it is chosen by design that no sensors can be coupled to a `link`. There is no additional attribute for `link`. #### Electric Model: `link` is modeled by a constant reactance $Y_{\text{series}}$, where $$ \begin{eqnarray} Y_{\text{series}} = (1 + \mathrm{j}) \cdot 10^6 \,\mathrm{p.u.} \end{eqnarray} $$ ### Transformer `transformer` is a {hoverxreftooltip}`user_manual/components:branch` which connects two nodes with possibly different voltage levels. An example of usage of transformer is given in [Transformer Examples](../examples/Transformer%20Examples.ipynb) #### Input | name | data type | unit | description | required | update | valid values | | ------------------ | ----------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------: | :------: | :--------------------------------------------------------------------: | | `u1` | `double` | volt (V) | rated voltage at from-side | ✔ | ❌ | `> 0` | | `u2` | `double` | volt (V) | rated voltage at to-side | ✔ | ❌ | `> 0` | | `sn` | `double` | volt-ampere (VA) | rated power | ✔ | ❌ | `> 0` | | `uk` | `double` | - | relative short circuit voltage, `0.1` means 10% | ✔ | ❌ | `>= pk / sn` and `> 0` and `< 1` | | `pk` | `double` | watt (W) | short circuit (copper) loss | ✔ | ❌ | `>= 0` | | `i0` | `double` | - | relative no-load current | ✔ | ❌ | `>= p0 / sn` and `< 1` | | `p0` | `double` | watt (W) | no-load (iron) loss | ✔ | ❌ | `>= 0` | | `winding_from` | {py:class}`WindingType ` | - | from-side winding type | ✔ | ❌ | | | `winding_to` | {py:class}`WindingType ` | - | to-side winding type | ✔ | ❌ | | | `clock` | `int8_t` | - | clock number of phase shift.
Even number is not possible if one side is Y(N) winding and the other side is not Y(N) winding.
Odd number is not possible, if both sides are Y(N) winding or both sides are not Y(N) winding. | ✔ | ❌ | `>= 0` and `<= 12` | | `tap_side` | {py:class}`BranchSide ` | - | side of tap changer | ✔ | ❌ | | | `tap_pos` | `int8_t` | - | current position of tap changer | ❌ default `tap_nom`, if no `tap_nom` default `0` | ✔ | `(tap_min <= tap_pos <= tap_max)` or `(tap_min >= tap_pos >= tap_max)` | | `tap_min` | `int8_t` | - | position of tap changer at minimum voltage | ✔ | ❌ | | | `tap_max` | `int8_t` | - | position of tap changer at maximum voltage | ✔ | ❌ | | | `tap_nom` | `int8_t` | - | nominal position of tap changer | ❌ default `0` | ❌ | `(tap_min <= tap_nom <= tap_max)` or `(tap_min >= tap_nom >= tap_max)` | | `tap_size` | `double` | volt (V) | size of each tap of the tap changer | ✔ | ❌ | `>= 0` | | `uk_min` | `double` | - | relative short circuit voltage at minimum tap | ❌ default same as `uk` | ❌ | `>= pk_min / sn` and `> 0` and `< 1` | | `uk_max` | `double` | - | relative short circuit voltage at maximum tap | ❌ default same as `uk` | ❌ | `>= pk_max / sn` and `> 0` and `< 1` | | `pk_min` | `double` | watt (W) | short circuit (copper) loss at minimum tap | ❌ default same as `pk` | ❌ | `>= 0` | | `pk_max` | `double` | watt (W) | short circuit (copper) loss at maximum tap | ❌ default same as `pk` | ❌ | `>= 0` | | `r_grounding_from` | `double` | ohm (Ω) | grounding resistance at from-side, if relevant | ❌ default `0` | ❌ | | | `x_grounding_from` | `double` | ohm (Ω) | grounding reactance at from-side, if relevant | ❌ default `0` | ❌ | | | `r_grounding_to` | `double` | ohm (Ω) | grounding resistance at to-side, if relevant | ❌ default `0` | ❌ | | | `x_grounding_to` | `double` | ohm (Ω) | grounding reactance at to-side, if relevant | ❌ default `0` | ❌ | | ```{note} It can happen that `tap_min > tap_max`. In this case the winding voltage is decreased if the tap position is increased. ``` #### Electric Model `transformer` is described by a $\pi$ model, where $Z_{\text{series}}$ can be computed as $$ \begin{eqnarray} & |Z_{\text{series}}| = \frac{u_k}{z_{\text{base}}} \\ & \mathrm{Re}(Z_{\text{series}}) = \frac{p_k / s_n}{z_{\text{base}}} \\ & \mathrm{Im}(Z_{\text{series}}) = \sqrt{|Z_{\text{series}}|^2-\mathrm{Re}(Z_{\text{series}})^2} \\ \end{eqnarray} $$ and $Y_{\text{shunt}}$ can be computed as $$ \begin{eqnarray} & |Y_{\text{shunt}}| = \frac{i_0}{y_{\text{base}}} \\ & \mathrm{Re}(Y_{\text{shunt}}) = \frac{s_n / p_0}{y_{\text{base}}} \\ & \mathrm{Im}(Y_{\text{shunt}}) = -\sqrt{|Y_{\text{shunt}}|^2-\mathrm{Re}(Y_{\text{shunt}})^2} \\ \end{eqnarray} $$ where $z_{\text{base}} = 1 / y_{\text{base}} = {u_{\text{2, rated}}}^2 / s_{\text{base}}$. Here, $s_{\text{base}}$ is a constant value determined by the solver and $u_{\text{2, rated}}$ is rated voltage at `to_node`. ### Generic Branch * type name: `generic_branch` `generic_branch` is a {hoverxreftooltip}`user_manual/components:branch` that connects two nodes, potentially at different voltage levels. Depending on the choice of parameters, it behaves either as a line or as a transformer. The advantage is that the input parameters are based directly on the electrical equivalent circuit model. The PI model can be used to avoid the need to convert parameters into transformer model data. Another use case is modeling a line when connecting two nodes with approximately the same voltage levels (in that case, the off-nominal ratio must be given to adapt the electrical parameters). #### Input | name | data type | unit | description | required | update | valid values | | ------- | --------- | ---------------- | ----------------------------- | :--------------------: | :------: | :-------------: | | `r1` | `double` | ohm | positive-sequence resistance | ✔ | ❌ | | | `x1` | `double` | ohm | positive-sequence reactance | ✔ | ❌ | | | `g1` | `double` | siemens | positive-sequence conductance | ✔ | ❌ | | | `b1` | `double` | siemens | positive-sequence susceptance | ✔ | ❌ | | | `k` | `double` | - | off-nominal ratio | ❌ default `1.0` | ❌ | `> 0` | | `theta` | `double` | radian | angle shift | ❌ default `0.0` | ❌ | | | `sn` | `double` | volt-ampere (VA) | rated power | ❌ default `0.0` | ❌ | `>= 0` | ```{note} The impedance (`r1`, `x1`) and admittance (`g1`, `b1`) attributes are calculated with reference to the "to" side of the branch. ``` ```{note} To model a three-winding transformer using the `generic_branch`, the MVA method must be applied. This means the user needs to calculate three equivalent `generic_branch` components and define an additional node to represent the common winding connection point. In rare cases, this method can result in negative electrical equivalent circuit elements. Therefore, the input parameters are not checked for negative values. ``` ```{warning} The parameter `k` represents the **off-nominal ratio**, not the nominal voltage ratio. This means that `k` must be explicitly provided by the user, particularly in cases involving a tap changer or a voltage transformer. The program does not automatically calculate `k` based on the nominal voltage levels of the connected nodes. ``` ```{warning} Asymmetric calculation is not supported for `generic_branch`. ``` #### Electric Model `generic_branch` is described by a PI model, where $$ \begin{eqnarray} & Y_{\text{series}} = \frac{1}{r + \mathrm{j}x} \\ & Y_{\text{shunt}} = g + \mathrm{j}b \\ & N = k \cdot e^{\mathrm{j} \theta} \\ \end{eqnarray} $$ ## Branch3 * type name: `branch3` * base: {hoverxreftooltip}`user_manual/components:base` `branch3` is the abstract base type for the component which connects three *different* nodes. For each branch3 three switches are always defined at side 1, 2, or 3 of the branch. In reality such switches may not exist. #### Input | name | data type | unit | description | required | update | valid values | | ---------- | --------- | ---- | --------------------------- | :------: | :------: | :-------------: | | `node_1` | `int32_t` | - | ID of node at side 1 | ✔ | ❌ | a valid node ID | | `node_2` | `int32_t` | - | ID of node at side 2 | ✔ | ❌ | a valid node ID | | `node_3` | `int32_t` | - | ID of node at side 3 | ✔ | ❌ | a valid node ID | | `status_1` | `int8_t` | - | connection status at side 1 | ✔ | ✔ | `0` or `1` | | `status_2` | `int8_t` | - | connection status at side 2 | ✔ | ✔ | `0` or `1` | | `status_3` | `int8_t` | - | connection status at side 3 | ✔ | ✔ | `0` or `1` | #### Steady state output | name | data type | unit | description | | --------- | ----------------- | -------------------------- | ---------------------------------------------------------- | | `p_1` | `RealValueOutput` | watt (W) | active power flowing into the branch at side 1 | | `q_1` | `RealValueOutput` | volt-ampere-reactive (var) | reactive power flowing into the branch at side 1 | | `i_1` | `RealValueOutput` | ampere (A) | current at side 1 | | `s_1` | `RealValueOutput` | volt-ampere (VA) | apparent power flowing at side 1 | | `p_2` | `RealValueOutput` | watt (W) | active power flowing into the branch at side 2 | | `q_2` | `RealValueOutput` | volt-ampere-reactive (var) | reactive power flowing into the branch at side 2 | | `i_2` | `RealValueOutput` | ampere (A) | current at side 2 | | `s_2` | `RealValueOutput` | volt-ampere (VA) | apparent power flowing at side 2 | | `p_3` | `RealValueOutput` | watt (W) | active power flowing into the branch at side 3 | | `q_3` | `RealValueOutput` | volt-ampere-reactive (var) | reactive power flowing into the branch at side 3 | | `i_3` | `RealValueOutput` | ampere (A) | current at side 3 | | `s_3` | `RealValueOutput` | volt-ampere (VA) | apparent power flowing at side 3 | | `loading` | `double` | - | relative loading of the branch, `1.0` meaning 100% loaded. | #### Short circuit output | name | data type | unit | description | | ----------- | ----------------- | ---------- | ----------------------- | | `i_1` | `RealValueOutput` | ampere (A) | current at side 1 | | `i_1_angle` | `RealValueOutput` | rad | current angle at side 1 | | `i_2` | `RealValueOutput` | ampere (A) | current at side 2 | | `i_2_angle` | `RealValueOutput` | rad | current angle at side 2 | | `i_3` | `RealValueOutput` | ampere (A) | current at side 3 | | `i_3_angle` | `RealValueOutput` | rad | current angle at side 3 | ### Three-Winding Transformer `three_winding_transformer` is a {hoverxreftooltip}`user_manual/components:branch3` connects three nodes with possibly different voltage levels. An example of usage of three-winding transformer is given in [Transformer Examples](../examples/Transformer%20Examples.ipynb). #### Input | name | data type | unit | description | required | update | valid values | | --------------- | ----------------------------------------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------- | :------------------------------: | :------: | :--------------------------------------------------------------------: | | `u1` | `double` | volt (V) | rated voltage at side 1 | ✔ | ❌ | `> 0` | | `u2` | `double` | volt (V) | rated voltage at side 2 | ✔ | ❌ | `> 0` | | `u3` | `double` | volt (V) | rated voltage at side 3 | ✔ | ❌ | `> 0` | | `sn_1` | `double` | volt-ampere (VA) | rated power at side 1 | ✔ | ❌ | `> 0` | | `sn_2` | `double` | volt-ampere (VA) | rated power at side 2 | ✔ | ❌ | `> 0` | | `sn_3` | `double` | volt-ampere (VA) | rated power at side 3 | ✔ | ❌ | `> 0` | | `uk_12` | `double` | - | relative short circuit voltage across side 1-2, `0.1` means 10% | ✔ | ❌ | `>= pk_12 / min(sn_1, sn_2)` and `> 0` and `< 1` | | `uk_13` | `double` | - | relative short circuit voltage across side 1-3, `0.1` means 10% | ✔ | ❌ | `>= pk_13 / min(sn_1, sn_3)` and `> 0` and `< 1` | | `uk_23` | `double` | - | relative short circuit voltage across side 2-3, `0.1` means 10% | ✔ | ❌ | `>= pk_23 / min(sn_2, sn_3)` and `> 0` and `< 1` | | `pk_12` | `double` | watt (W) | short circuit (copper) loss across side 1-2 | ✔ | ❌ | `>= 0` | | `pk_13` | `double` | watt (W) | short circuit (copper) loss across side 1-3 | ✔ | ❌ | `>= 0` | | `pk_23` | `double` | watt (W) | short circuit (copper) loss across side 2-3 | ✔ | ❌ | `>= 0` | | `i0` | `double` | - | relative no-load current with respect to side 1 | ✔ | ❌ | `>= p0 / sn` and `< 1` | | `p0` | `double` | watt (W) | no-load (iron) loss | ✔ | ❌ | `>= 0` | | `winding_1` | {py:class}`WindingType ` | - | side 1 winding type | ✔ | ❌ | | | `winding_2` | {py:class}`WindingType ` | - | side 2 winding type | ✔ | ❌ | | | `winding_3` | {py:class}`WindingType ` | - | side 3 winding type | ✔ | ❌ | | | `clock_12` | `int8_t` | - | clock number of phase shift across side 1-2, odd number is only allowed for Dy(n) or Y(N)d configuration. | ✔ | ❌ | `>= 0` and `<= 12` | | `clock_13` | `int8_t` | - | clock number of phase shift across side 1-3, odd number is only allowed for Dy(n) or Y(N)d configuration. | ✔ | ❌ | `>= 0` and `<= 12` | | `tap_side` | {py:class}`Branch3Side ` | - | side of tap changer | ✔ | ❌ | `side_1` or `side_2` or `side_3` | | `tap_pos` | `int8_t` | - | current position of tap changer | ❌ default `tap_nom`, if no `tap_nom` default `0` | ✔ | `(tap_min <= tap_pos <= tap_max)` or `(tap_min >= tap_pos >= tap_max)` | | `tap_min` | `int8_t` | - | position of tap changer at minimum voltage | ✔ | ❌ | | | `tap_max` | `int8_t` | - | position of tap changer at maximum voltage | ✔ | ❌ | | | `tap_nom` | `int8_t` | - | nominal position of tap changer | ❌ default `0` | ❌ | `(tap_min <= tap_nom <= tap_max)` or `(tap_min >= tap_nom >= tap_max)` | | `tap_size` | `double` | volt (V) | size of each tap of the tap changer | ✔ | ❌ | `> 0` | | `uk_12_min` | `double` | - | relative short circuit voltage at minimum tap, across side 1-2 | ❌ default same as `uk_12` | ❌ | `>= pk_12_min / min(sn_1, sn_2)` and `> 0` and `< 1` | | `uk_12_max` | `double` | - | relative short circuit voltage at maximum tap, across side 1-2 | ❌ default same as `uk_12` | ❌ | `>= pk_12_max / min(sn_1, sn_2)` and `> 0` and `< 1` | | `pk_12_min` | `double` | watt (W) | short circuit (copper) loss at minimum tap, across side 1-2 | ❌ default same as `pk_12` | ❌ | `>= 0` | | `pk_12_max` | `double` | watt (W) | short circuit (copper) loss at maximum tap, across side 1-2 | ❌ default same as `pk_12` | ❌ | `>= 0` | | `uk_13_min` | `double` | - | relative short circuit voltage at minimum tap, across side 1-3 | ❌ default same as `uk_13` | ❌ | `>= pk_13_min / min(sn_1, sn_3)` and `> 0` and `< 1` | | `uk_13_max` | `double` | - | relative short circuit voltage at maximum tap, across side 1-3 | ❌ default same as `uk_13` | ❌ | `>= pk_13_max / min(sn_1, sn_3)` and `> 0` and `< 1` | | `pk_13_min` | `double` | watt (W) | short circuit (copper) loss at minimum tap, across side 1-3 | ❌ default same as `pk_13` | ❌ | `>= 0` | | `pk_13_max` | `double` | watt (W) | short circuit (copper) loss at maximum tap, across side 1-3 | ❌ default same as `pk_13` | ❌ | `>= 0` | | `uk_23_min` | `double` | - | relative short circuit voltage at minimum tap, across side 2-3 | ❌ default same as `uk_23` | ❌ | `>= pk_23_min / min(sn_2, sn_3)` and `> 0` and `< 1` | | `uk_23_max` | `double` | - | relative short circuit voltage at maximum tap, across side 2-3 | ❌ default same as `uk_23` | ❌ | `>= pk_23_max / min(sn_2, sn_3)` and `> 0` and `< 1` | | `pk_23_min` | `double` | watt (W) | short circuit (copper) loss at minimum tap, across side 2-3 | ❌ default same as `pk_23` | ❌ | `>= 0` | | `pk_23_max` | `double` | watt (W) | short circuit (copper) loss at maximum tap, across side 2-3 | ❌ default same as `pk_23` | ❌ | `>= 0` | | `r_grounding_1` | `double` | ohm (Ω) | grounding resistance at side 1, if relevant | ❌ default `0` | ❌ | | | `x_grounding_1` | `double` | ohm (Ω) | grounding reactance at side 1, if relevant | ❌ default `0` | ❌ | | | `r_grounding_2` | `double` | ohm (Ω) | grounding resistance at side 2, if relevant | ❌ default `0` | ❌ | | | `x_grounding_2` | `double` | ohm (Ω) | grounding reactance at side 2, if relevant | ❌ default `0` | ❌ | | | `r_grounding_3` | `double` | ohm (Ω) | grounding resistance at side 3, if relevant | ❌ default `0` | ❌ | | | `x_grounding_3` | `double` | ohm (Ω) | grounding reactance at side 3, if relevant | ❌ default `0` | ❌ | ```{note} It can happen that `tap_min > tap_max`. In this case the winding voltage is decreased if the tap position is increased. ``` #### Electric Model `three_winding_transformer` is modelled as 3 transformers of `pi` model each connected together in star configuration. However, there are only 2 `pi` "legs": One at `side_1` and one in the centre of star. The values between windings (for e.g., `uk_12` or `pk_23`) are converted from delta to corresponding star configuration values. The calculation of series and shunt admittance from `uk`, `pk`, `i0` and `p0` is same as mentioned in {hoverxreftooltip}`user_manual/components:transformer`. ## Appliance * type name: `appliance` * base: {hoverxreftooltip}`user_manual/components:base` `appliance` is an abstract user which is coupled to a `node`. For each `appliance`, a switch is defined between the `appliance` and the `node`. The reference direction for power flows is mentioned in {hoverxreftooltip}`user_manual/data-model:Reference Direction`. #### Input | name | data type | unit | description | required | update | valid values | | -------- | --------- | ---- | ----------------------------- | :------: | :------: | :-------------: | | `node` | `int32_t` | - | ID of the coupled node | ✔ | ❌ | a valid node ID | | `status` | `int8_t` | - | connection status to the node | ✔ | ✔ | `0` or `1` | #### Steady state output | name | data type | unit | description | | ---- | ----------------- | -------------------------- | -------------- | | `p` | `RealValueOutput` | watt (W) | active power | | `q` | `RealValueOutput` | volt-ampere-reactive (var) | reactive power | | `i` | `RealValueOutput` | ampere (A) | current | | `s` | `RealValueOutput` | volt-ampere (VA) | apparent power | | `pf` | `RealValueOutput` | - | power factor | #### Short circuit output | name | data type | unit | description | | --------- | ----------------- | ---------- | ------------- | | `i` | `RealValueOutput` | ampere (A) | current | | `i_angle` | `RealValueOutput` | rad | current angle | ### Source * type name: `source` * {hoverxreftooltip}`user_manual/data-model:Reference Direction`: generator `source` is an {hoverxreftooltip}`user_manual/components:appliance` representing the external network with a [Thévenin's equivalence](https://en.wikipedia.org/wiki/Th%C3%A9venin%27s_theorem). It has an infinite voltage source with an internal impedance. The impedance is specified by convention as short circuit power. #### Input | name | data type | unit | description | required | update | valid values | | ------------- | --------- | ---------------- | -------------------------------------------------- | :--------------------------: | :------: | :----------: | | `u_ref` | `double` | - | reference voltage in per-unit | ✨ only for power flow | ✔ | `> 0` | | `u_ref_angle` | `double` | rad | reference voltage angle | ❌ default `0.0` | ✔ | | | `sk` | `double` | volt-ampere (VA) | short circuit power | ❌ default `1e10` | ❌ | `> 0` | | `rx_ratio` | `double` | - | R to X ratio | ❌ default `0.1` | ❌ | `>= 0` | | `z01_ratio` | `double` | - | zero-sequence to positive sequence impedance ratio | ❌ default `1.0` | ❌ | `> 0` | #### Electric Model `source` is modeled by an internal constant impedance $r+\mathrm{j}x$ with positive sequence and zero-sequence. Its value can be computed using following equations: - for positive sequence, $$ \begin{eqnarray} & z_{\text{source}} = \frac{s_{\text{base}}}{s_k} \\ & x_1 = z_{\text{source}} \sqrt{1+ \left(\frac{r}{x}\right)^2} \\ & r_1 = x_1 \cdot \left(\frac{r}{x}\right) \end{eqnarray} $$ where $s_{\text{base}}$ is a constant value determined by the solver, and $\frac{r}{x}$ indicates `rx_ratio` as input. - for zero-sequence, $$ \begin{eqnarray} & z_{\text{source,0}} = z_{\text{source}} \cdot \frac{z_0}{z_1}\\ & x_0 = z_{\text{source,0}} \sqrt{1 + \left(\frac{r}{x}\right)^2}\\ & r_0 = x_0 \cdot \left(\frac{r}{x}\right) \end{eqnarray} $$ ### Generic Load and Generator * type name: `generic_load_gen` `generic_load_gen` is an abstract load/generation {hoverxreftooltip}`user_manual/components:appliance` which contains only the type of the load/generation with response to voltage. | name | data type | unit | description | required | update | | ------ | ----------------------------------------------------------- | ---- | ----------------------------------------------- | :------: | :------: | | `type` | {py:class}`LoadGenType ` | - | type of load/generator with response to voltage | ✔ | ❌ | #### Load/Generator Concrete Types There are four concrete types of load/generator. They share similar attributes: specified active/reactive power. However, the reference direction and meaning of `RealValueInput` is different, as shown in the table below. | type name | reference direction | meaning of `RealValueInput` | | ----------- | ------------------- | --------------------------- | | `sym_load` | load | `double` | | `sym_gen` | generator | `double` | | `asym_load` | load | `double[3]` | | `asym_gen` | generator | `double[3]` | ##### Input | name | data type | unit | description | required | update | | ------------- | ---------------- | -------------------------- | ------------------------ | :--------------------------: | :------: | | `p_specified` | `RealValueInput` | watt (W) | specified active power | ✨ only for power flow | ✔ | | `q_specified` | `RealValueInput` | volt-ampere-reactive (var) | specified reactive power | ✨ only for power flow | ✔ | ##### Electric model `generic_load_gen` is modelled by using the so-called ZIP load model in power-grid-model, where a load/generator is represented as a composition of constant power (P), constant current (I) and constant impedance (Z). The injection of each ZIP model type can be computed as follows: - for a constant impedance (Z) load/generator, $$ \begin{eqnarray} S = S_{\text{specified}} \cdot \bar{u}^2 \end{eqnarray} $$ - for a constant current (I) load/generator, $$ \begin{eqnarray} S = S_{\text{specified}} \cdot \bar{u} \end{eqnarray} $$ - for a constant power (P) load/generator:, $$ \begin{eqnarray} S = S_{\text{specified}} \end{eqnarray} $$ where $\bar{u}$ is the calculated node voltage. ### Shunt * type name: `shunt` * {hoverxreftooltip}`user_manual/data-model:Reference Direction`: load `shunt` is an {hoverxreftooltip}`user_manual/components:appliance` with a fixed admittance (impedance). It behaves similar to a load/generator with type `const_impedance`. #### Input | name | data type | unit | description | required | update | | ---- | --------- | ----------- | ----------------------------------- | :--------------------------------------: | :------: | | `g1` | `double` | siemens (S) | positive-sequence shunt conductance | ✔ | ✔ | | `b1` | `double` | siemens (S) | positive-sequence shunt susceptance | ✔ | ✔ | | `g0` | `double` | siemens (S) | zero-sequence shunt conductance | ✨ only for asymmetric calculation | ✔ | | `b0` | `double` | siemens (S) | zero-sequence shunt susceptance | ✨ only for asymmetric calculation | ✔ | ```{note} In case of short circuit calculations, the zero-sequence parameters are required only if any of the faults in any of the scenarios within a batch are not three-phase faults (i.e. `fault_type` is not `FaultType.three_phase`). ``` #### Electric Model `shunt` is modelled by a fixed admittance which equals to $g + \mathrm{j}b$. ## Sensor * type name: `sensor` * base: {hoverxreftooltip}`user_manual/components:base` `sensor` is an abstract type for all the sensor types. A sensor does not have any physical meaning. Rather, it provides measurement data for the state estimation algorithm. The state estimator uses the data to evaluate the state of the grid with the highest probability. #### Input | name | data type | unit | description | required | update | valid values | | ----------------- | --------- | ---- | ------------------------- | :------: | :------: | :---------------: | | `measured_object` | `int32_t` | - | ID of the measured object | ✔ | ❌ | a valid object ID | #### Output A sensor only has output for state estimation. For other calculation types, sensor output is undefined. ### Generic Voltage Sensor * type name: `generic_voltage_sensor` `generic_voltage_sensor` is an abstract class for symmetric and asymmetric voltage sensor and derived from {hoverxreftooltip}`user_manual/components:sensor`. It measures the magnitude and (optionally) the angle of the voltage of a `node`. #### Input | name | data type | unit | description | required | update | valid values | | --------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------- | :--------------------------------: | :------: | :----------: | | `u_sigma` | `double` | volt (V) | standard deviation of the measurement error. Usually this is the absolute measurement error range divided by 3. | ✨ only for state estimation | ✔ | `> 0` | #### Voltage Sensor Concrete Types There are two concrete types of voltage sensor. They share similar attributes: the meaning of `RealValueInput` is different, as shown in the table below. In a `sym_voltage_sensor` the measured voltage is a line-to-line voltage. In a `asym_voltage_sensor` the measured voltage is a 3-phase line-to-ground voltage. | type name | meaning of `RealValueInput` | | --------------------- | --------------------------- | | `sym_voltage_sensor` | `double` | | `asym_voltage_sensor` | `double[3]` | ##### Input | name | data type | unit | description | required | update | valid values | | ------------------ | ---------------- | -------- | -------------------------------------------------------------------- | :--------------------------------: | :------: | :----------: | | `u_measured` | `RealValueInput` | volt (V) | measured voltage magnitude | ✨ only for state estimation | ✔ | `> 0` | | `u_angle_measured` | `RealValueInput` | rad | measured voltage angle (only possible with phasor measurement units) | ❌ | ✔ | | ##### Steady state output ```{note} A sensor only has output for state estimation. For other calculation types, sensor output is undefined. ``` | name | data type | unit | description | | ------------------ | ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------ | | `u_residual` | `RealValueOutput` | volt (V) | residual value between measured voltage magnitude and calculated voltage magnitude | | `u_angle_residual` | `RealValueOutput` | rad | residual value between measured voltage angle and calculated voltage angle (only possible with phasor measurement units) | #### Electric Model `generic_voltage_sensor` is modeled by following equations: $$ \begin{eqnarray} & u_{\text{residual}} = u_{\text{measured}} - u_{\text{state}} \\ & \theta_{\text{residual}} = \theta_{\text{measured}} - \theta_{\text{state}} \end{eqnarray} $$ ### Generic Power Sensor * type name: `generic_power_sensor` `power_sensor` is an abstract class for symmetric and asymmetric power sensor and is derived from {hoverxreftooltip}`user_manual/components:sensor`. It measures the active/reactive power flow of a terminal. The terminal is either connecting an `appliance` and a `node`, or connecting the from/to end of a `branch` (except `link`) and a `node`. In case of a terminal between an `appliance` and a `node`, the power {hoverxreftooltip}`user_manual/data-model:Reference Direction` in the measurement data is the same as the reference direction of the `appliance`. For example, if a `power_sensor` is measuring a `source`, a positive `p_measured` indicates that the active power flows from the source to the node. ```{note} 1. Due to the high admittance of a `link` it is chosen that a power sensor cannot be coupled to a `link`, even though a link is a `branch` 2. The node injection power sensor gets placed on a node. In the state estimation result, the power from this injection is distributed equally among the connected appliances at that node. Because of this distribution, at least one appliance is required to be connected to the node where an injection sensor is placed for it to function. ``` ##### Input | name | data type | unit | description | required | update | valid values | | ------------------------ | ----------------------------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------: | :------: | :--------------------------------------------------: | | `measured_terminal_type` | {py:class}`MeasuredTerminalType ` | - | indicate if it measures an `appliance` or a `branch` | ✔ | ❌ | the terminal type should match the `measured_object` | | `power_sigma` | `double` | volt-ampere (VA) | standard deviation of the measurement error. Usually this is the absolute measurement error range divided by 3. See {hoverxreftooltip}`user_manual/components:Power Sensor Concrete Types`. | ✨ in certain cases for state estimation. See the explanation for [concrete types](#power-sensor-concrete-types) below. | ✔ | `> 0` | #### Power Sensor Concrete Types There are two concrete types of power sensor. They share similar attributes: the meaning of `RealValueInput` is different, as shown in the table below. | type name | meaning of `RealValueInput` | | ------------------- | --------------------------- | | `sym_power_sensor` | `double` | | `asym_power_sensor` | `double[3]` | ##### Input | name | data type | unit | description | required | update | | ------------ | ---------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | :---------------------------------: | :------: | | `p_measured` | `RealValueInput` | watt (W) | measured active power | ✨ only for state estimation | ✔ | | `q_measured` | `RealValueInput` | volt-ampere-reactive (var) | measured reactive power | ✨ only for state estimation | ✔ | | `p_sigma` | `RealValueInput` | watt (W) | standard deviation of the active power measurement error. Usually this is the absolute measurement error range divided by 3. | ❌ see the explanation below. | ✔ | `> 0` | | `q_sigma` | `RealValueInput` | volt-ampere-reactive (var) | standard deviation of the reactive power measurement error. Usually this is the absolute measurement error range divided by 3. | ❌ see the explanation below. | ✔ | `> 0` | Valid combinations of `power_sigma`, `p_sigma` and `q_sigma` are: | `power_sigma` | `p_sigma` | `q_sigma` | result | | :-----------: | :-------: | :-------: | :------: | | ✔ | ✔ | ✔ | ✔ | | ✔ | ✔ | | ❌ | | ✔ | | ✔ | ❌ | | ✔ | | | ✔ | | | ✔ | ✔ | ✔ | | | ✔ | | ❌ | | | | ✔ | ❌ | | | | | ❌ | ```{note} 1. If both `p_sigma` and `q_sigma` are provided, they represent the standard deviation of the active and reactive power, respectively, and the value of `power_sigma` is ignored. Any infinite component invalidates the entire measurement. 2. If neither `p_sigma` nor `q_sigma` are provided, `power_sigma` represents the standard deviation of the apparent power. 3. Providing only one of `p_sigma` and `q_sigma` results in undefined behaviour. ``` See the documentation on [state estimation calculation methods](calculations.md#state-estimation-algorithms) for details per method on how the variances are taken into account for both the active and reactive power and for the individual phases. ##### Steady state output ```{note} A sensor only has output for state estimation. For other calculation types, sensor output is undefined. ``` | name | data type | unit | description | | ------------ | ----------------- | -------------------------- | ---------------------------------------------------------------------------- | | `p_residual` | `RealValueOutput` | watt (W) | residual value between measured active power and calculated active power | | `q_residual` | `RealValueOutput` | volt-ampere-reactive (var) | residual value between measured reactive power and calculated reactive power | #### Electric Model `Generic Power Sensor` is modeled by following equations: $$ \begin{eqnarray} & p_{\text{residual}} = p_{\text{measured}} - p_{\text{state}} \\ & q_{\text{residual}} = q_{\text{measured}} - q_{\text{state}} \end{eqnarray} $$ ## Fault * type name: `fault` * base: {hoverxreftooltip}`user_manual/components:base` `fault` defines a short circuit location in the grid. A fault can only happen at a `node`. #### Input | name | data type | unit | description | required | update | valid values | | -------------- | --------------------------------------------------------- | ------- | --------------------------------------------------- | :----------------------------------------------------------------------------------------: | :------: | :---------------: | | `status` | `int8_t` | - | whether the fault is active | ✔ | ✔ | `0` or `1` | | `fault_type` | {py:class}`FaultType ` | - | the type of the fault | ✨ only for short circuit | ✔ | | | `fault_phase` | {py:class}`FaultPhase ` | - | the phase(s) of the fault | ❌ default `FaultPhase.default_value` (see [below](#default-values-for-fault_phase)) | ✔ | | | `fault_object` | `int32_t` | - | ID of the component where the short circuit happens | ✔ | ✔ | A valid `node` ID | | `r_f` | `double` | ohm (Ω) | short circuit resistance | ❌ default `0.0` | ✔ | | | `x_f` | `double` | ohm (Ω) | short circuit reactance | ❌ default `0.0` | ✔ | | ```{note} Multiple faults may exist within one calculation. Currently, all faults in one scenario are required to have the same `fault_type` and `fault_phase`. Across scenarios in a batch, the `fault_type` and `fault_phase` may differ. ``` ```{note} If any of the faults in any of the scenarios within a batch are not `three_phase` (i.e. `fault_type` is not `FaultType.three_phase`), the calculation is treated as asymmetric. ``` #### Steady state output A `fault` has no steady state output. #### Short circuit output | name | data type | unit | description | | ----------- | ----------------- | ---------- | ------------- | | `i_f` | `RealValueOutput` | ampere (A) | current | | `i_f_angle` | `RealValueOutput` | rad | current angle | #### Electric Model Four types of short circuit fault are included in power-grid-model. | `fault_type` | `fault_phase` | description | | ---------------------------------- | ---------------- | ---------------------------------------------------------------------- | | `FaultType.three_phase` | `FaultPhase.abc` | Three phases are connected with fault impedance. | | `FaultType.single_phase_to_ground` | `FaultPhase.a` | One phase is grounded with fault impedance, and other phases are open. | | `FaultType.two_phase` | `FaultPhase.bc` | Two phases are connected with fault impedance. | | `FaultType.two_phase_to_ground` | `FaultPhase.bc` | Two phases are connected with fault impedance then grounded. | In case the `fault_phase` is not specified or is equal to `FaultPhase.default_value`, the power-grid-model assumes the following fault phases for different values of `fault_type`. ## Regulator * type name: `regulator` * base: {hoverxreftooltip}`user_manual/components:base` `regulator` is an abstract regulator that is coupled to a given `regulated_object`. For each `regulator`, a switch is defined between the `regulator` and the `regulated_object`. Which object types are supported as `regulated_object` is regulator type-dependent. #### Input | name | data type | unit | description | required | update | valid values | | ------------------ | --------- | ---- | ----------------------------------------- | :------: | :------: | :-------------------------: | | `regulated_object` | `int32_t` | - | ID of the regulated object | ✔ | ❌ | a valid regulated object ID | | `status` | `int8_t` | - | connection status to the regulated object | ✔ | ✔ | `0` or `1` | ### Transformer tap regulator * type name: `transformer_tap_regulator` * base: {hoverxreftooltip}`user_manual/components:regulator` `transformer_tap_regulator` defines a regulator for transformers in the grid. A transformer tap regulator regulates a component that is either a {hoverxreftooltip}`user_manual/components:transformer` or a {hoverxreftooltip}`user_manual/components:Three-Winding Transformer`. The transformer tap regulator changes the `tap_pos` of the transformer it regulates in the range set by the user via `tap_min` and `tap_max` (i.e., `(tap_min <= tap_pos <= tap_max)` or `(tap_min >= tap_pos >= tap_max)`). It regulates the tap position so that the voltage on the control side is in the chosen voltage band. Other points further into the grid on the control side, away from the transformer, can also be regulated by providing the cumulative impedance across branches to that point as an additional line drop compensation. This line drop compensation only affects the controlled voltage and does not have any impact on the actual grid. It may therefore be treated as a virtual impedance in the grid. ```{note} The regulator outputs the optimal tap position of the transformer. The actual grid state is not changed after calculations are done. ``` #### Input | name | data type | unit | description | required | update | valid values | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------- | :--------------------------: | :------: | :--------------------------------------------------------------: | | `control_side` | {py:class}`BranchSide ` if the regulated object is a {hoverxreftooltip}`user_manual/components:transformer` and {py:class}`Branch3Side ` if it the regulated object is a {hoverxreftooltip}`user_manual/components:Three-Winding Transformer` | - | the controlled side of the transformer | ✨ only for power flow | ❌ | `control_side` should be the relatively further side to a source | | `u_set` | `double` | volt (V) | the voltage setpoint (at the center of the band) | ✨ only for power flow | ✔ | `>= 0` | | `u_band` | `double` | volt (V) | the width of the voltage band ($=2*\left(\Delta U\right)_{\text{acceptable}}$) | ✨ only for power flow | ✔ | `> 0` (see below) | | `line_drop_compensation_r` | `double` | ohm (Ω) | compensation for voltage drop due to resistance during transport (see [below](#line-drop-compensation)) | ❌ default `0.0` | ✔ | `>= 0` | | `line_drop_compensation_x` | `double` | ohm (Ω) | compensation for voltage drop due to reactance during transport (see [below](#line-drop-compensation)) | ❌ default `0.0` | ✔ | `>= 0` | The following additional requirements exist on the input parameters. - Depending on the resultant voltage being transformed, the voltage band must be sufficiently large: At zero line drop compensation if the expected resultant voltages are in the proximity of the rated transformer voltages, it is recommended to have the $u_{band} >= \frac{u_2}{1+ u_1 / \text{tap}_{\text{size}}}$ - The line drop compensation is small, in the sense that its product with the typical current through the transformer is much smaller (in absolute value) than the smallest change in voltage due to a change in tap position. - The `control_side` of a transformer regulator should be on the relatively further side to a source in the connected grid. These requirements make sure no edge cases with undefined behavior are encountered. Typical real-world power grids already satisfy these requirements and they should therefore not cause any problems. #### Steady state output | name | data type | unit | description | | --------- | --------- | ---- | -------------------- | | `tap_pos` | `int8_t` | - | optimal tap position | #### Short circuit output A `transformer_tap_regulator` has no short circuit output. #### Electric Model The transformer tap regulator itself does not have a direct contribution to the grid state. Instead, it regulates the tap position of the regulated object until the voltage at the control side is in the specified voltage band: $$ \begin{eqnarray} U_{\text{control}} \in \left[U_{\text{set}} - \frac{U_{\text{band}}}{2}, U_{\text{set}} + \frac{U_{\text{band}}}{2}\right] \end{eqnarray} $$ ##### Line drop compensation The transformer tap regulator tries to regulate the voltage in a specified virtual location in the grid, according to the folowing model. ```txt tap_side control_side part of grid where voltage is to be regulated ------^\oo -*---------------------virtual_impedance----* | U_node, I_transformer Z_comp U_control | | regulator <=======================================/ ``` The control voltage is the voltage at the node, compensated with the voltage drop corresponding to the specified line drop compensation. $$ \begin{eqnarray} & Z_{\text{compensation}} = r_{\text{compensation}} + \mathrm{j} x_{\text{compensation}} \\ & U_{\text{control}} = \left|\underline{U}_{\text{node}} - \underline{I}_{\text{transformer,out}} \cdot \underline{Z}_{\text{compensation}}\right| = \left|\underline{U}_{\text{node}} + \underline{I}_{\text{transformer}} \cdot \underline{Z}_{\text{compensation}}\right| \end{eqnarray} $$ where $\underline{U}_{\text{node}}$ and $\underline{I}_{\text{transformer}}$ are the calculated voltage and current phasors at the control side and may be obtained from a regular power flow calculation. The plus sign in the last equality follows from canceling minus signs from the current direction convention and the compensation direction. For example, if we want to regulate the voltage at `load_7` in the following grid, the line drop compensation impedance is the approximate impedance of `line_5`. ```txt node_1 --- transformer_4 --- node_2 --- line_5 --- node_3 | | | source_6 | load_7 transformer_tap_regulator_8 ```