diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index aadf308a3..bde343801 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -31,6 +31,15 @@ Output: - Node voltage magnitude and angle - Power flow through branches +See [Power flow algorithms](#power-flow-algorithms) for detailed documentation on the calculation methods. + +##### Regulated power flow + +For most power flow calculations, the grid is fixed as the user dictates. However, in practice, the grid often contains regulators for certain components. +When including those regulators in the calculations, the grid may be optimized according to the power flow results and the behaviour of the regulators. + +See [Regulated power flow calculations](#regulated-power-flow-calculations) for detailed documentation on regulated power flow calculations. + #### State estimation State estimation is a statistical calculation method that determines the most probable state of the grid, based on @@ -561,6 +570,36 @@ There are 4 types of fault situations that can occur in the grid, along with the - Two phase: ab, bc, ac - Two phase to ground: ab, bc, ac +### Regulated power flow calculations + +```warning +At the time of writing, this feature is still experimental and is not yet publicly available. +``` + +Regulated power flow calculations are disabled by default. + +At the time of writing, the following regulated power flow calculation types are implemented. +Please refer to their respective sections for detailed documentation. + +| Regulation type | Setting | Enum values | +| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | +| [Automatic tap changing](#power-flow-with-automatic-tap-changing) | {py:meth}`tap_changing_strategy ` | {py:class}`TapChangingStrategy ` | + +#### Power flow with automatic tap changing + +```warning +At the time of writing, this feature is still experimental and is not yet publicly available. +``` + +Some of the most important regulators in the grid affect the tap position of transformers. These {hoverxreftooltip}`user_manual/components:transformer-tap-regulator`s are + +| Algorithm | Default | Speed | Algorithm call | +| ------------------------------------------------------------ | -------- | -------- | ----------------------------------------------------------------------------------------------------------- | +| No automatic tap changing (regular power flow) | ✔ | ✔ | {py:class}`TapChangingStrategy.newton_raphson ` | +| Optimize tap position for any value in the voltage band | | ✔ | {py:class}`TapChangingStrategy.any_valid_tap ` | +| Optimize tap position for lower voltage in the voltage band | | | {py:class}`TapChangingStrategy.min_voltage_tap ` | +| Optimize tap position for higher voltage in the voltage band | | | {py:class}`TapChangingStrategy.max_voltage_tap ` | + ## Batch Calculations Usually, a single power-flow or state estimation calculation would not be enough to get insights in the grid. diff --git a/docs/user_manual/components.md b/docs/user_manual/components.md index 1403ea830..d3edfed80 100644 --- a/docs/user_manual/components.md +++ b/docs/user_manual/components.md @@ -16,16 +16,16 @@ The base type for all power-grid-model components. #### Input -| name | data type | unit | description | required | update | -| ---- | --------- | ---- | -------------------------------------------------------------------------------------------------------------------------------- | :------: | :----------------------------------------------------------------------------: | +| 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`. | ✔ | ❌ (id needs to be specified in the update query, but cannot be changed) | #### Steady state output and Short circuit output -| name | data type | unit | description | -| ----------- | --------- | ---- | -------------------------------------------------------------------------------------------------------------------------------- | +| 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 | +| `energized` | `int8_t` | - | Indicates if a component is energized, i.e. connected to a source | ## Node @@ -114,17 +114,17 @@ 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 zero | -| `x1` | `double` | ohm (Ω) | positive-sequence serial reactance | ✔ | ❌ | `r1` and `x1` cannot be both zero | -| `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 zero | -| `x0` | `double` | ohm (Ω) | zero-sequence serial reactance | ✨ only for asymmetric calculations | ❌ | `r0` and `x0` cannot be both zero | -| `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` | +| 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 @@ -184,16 +184,16 @@ levels. An example of usage of transformer is given in [Transformer Examples](.. | `tap_pos` | `int8_t` | - | current position of tap changer | ✔ | ✔ | `(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 zero | ❌ | `(tap_min <= tap_nom <= tap_max)` or `(tap_min >= tap_nom >= tap_max)` | +| `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 zero | ❌ | | -| `x_grounding_from` | `double` | ohm (Ω) | grounding reactance at from-side, if relevant | ❌ default zero | ❌ | | -| `r_grounding_to` | `double` | ohm (Ω) | grounding resistance at to-side, if relevant | ❌ default zero | ❌ | | -| `x_grounding_to` | `double` | ohm (Ω) | grounding reactance at to-side, if relevant | ❌ default zero | ❌ | | +| `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 @@ -304,7 +304,7 @@ voltage levels. An example of usage of three-winding transformer is given in [Tr | `tap_pos` | `int8_t` | - | current position of tap changer | ✔ | ✔ | `(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 zero | ❌ | `(tap_min <= tap_nom <= tap_max)` or `(tap_min >= tap_nom >= tap_max)` | +| `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` | @@ -318,12 +318,12 @@ voltage levels. An example of usage of three-winding transformer is given in [Tr | `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 zero | ❌ | | -| `x_grounding_1` | `double` | ohm (Ω) | grounding reactance at side 1, if relevant | ❌ default zero | ❌ | | -| `r_grounding_2` | `double` | ohm (Ω) | grounding resistance at side 2, if relevant | ❌ default zero | ❌ | | -| `x_grounding_2` | `double` | ohm (Ω) | grounding reactance at side 2, if relevant | ❌ default zero | ❌ | | -| `r_grounding_3` | `double` | ohm (Ω) | grounding resistance at side 3, if relevant | ❌ default zero | ❌ | | -| `x_grounding_3` | `double` | ohm (Ω) | grounding reactance at side 3, if relevant | ❌ default zero | ❌ | +| `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 @@ -342,7 +342,7 @@ The calculation of series and shunt admittance from `uk`, `pk`, `i0` and `p0` is * 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 +`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`. @@ -384,13 +384,13 @@ with an internal impedance. The impedance is specified by convention as short ci | 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` | +| `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. +`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, @@ -405,7 +405,7 @@ $$ where $s_{\text{base}}$ is a constant value determined by the solver, and $\frac{r}{x}$ indicates `rx_ratio` as input. -- for zero sequence, +- for zero-sequence, $$ \begin{eqnarray} @@ -533,7 +533,6 @@ a `node`. | --------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------- | :--------------------------------: | :------: | :----------: | | `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: @@ -590,9 +589,9 @@ Because of this distribution, at least one appliance is required to be connected ##### 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` | +| 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 @@ -617,13 +616,13 @@ the meaning of `RealValueInput` is different, as shown in the table below. Valid combinations of `power_sigma`, `p_sigma` and `q_sigma` are: | `power_sigma` | `p_sigma` | `q_sigma` | result | -|:-------------:|:---------:|:---------:|:--------:| -| x | x | x | ✔ | -| x | x | | ❌ | +| :-----------: | :-------: | :-------: | :------: | +| x | x | x | ✔ | +| x | x | | ❌ | | x | | x | ❌ | | x | | | ✔ | -| | x | x | ✔ | -| | x | | ❌ | +| | x | x | ✔ | +| | x | | ❌ | | | | x | ❌ | | | | | ❌ | @@ -657,9 +656,9 @@ $$ ## Fault * type name: `fault` -* * base: {hoverxreftooltip}`user_manual/components:base` +* base: {hoverxreftooltip}`user_manual/components:base` -`fault` defines a short circuit location in the grid. At this moment a fault can only happen at a `node`. +`fault` defines a short circuit location in the grid. At the time of writing, a fault can only happen at a `node`. #### Input @@ -669,8 +668,8 @@ $$ | `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 | ✔ | | +| `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 @@ -695,15 +694,97 @@ A `fault` has no steady state output. | `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. | +| `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. +At the time of writing, 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 overloads 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 optimizes the voltage on the control side such that it is in the chosen voltage band. +To optimize for the voltage at a given point in the grid on the control side that is at a greater distance from the transformer, an additional line drop compensation impedance can be provided to take the loss during transport into account. +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 measurement. + +#### Input + +| name | data type | unit | description | required | update | valid values | +| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------- | :----------------------------: | :------: | :----------: | +| `control_side` | {py:class}`BranchSide ` or {py:class}`Branch3Side ` (see below) | - | the type of the transformer_tap_regulator | ✨ only for steady state | ✔ | | +| `u_set` | `double` | volt (V) | the voltage setpoint (at the center of the band) | ✔ | ✔ | `>= 0` | +| `u_band` | `double` | volt (V) | the width of the voltage band | ✔ | ✔ | `> 0` (see below) | +| `line_drop_compensation_r` | `double` | ohm (Ω) | compensation for voltage drop 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. + +- The `control_side` supports {py:class}`BranchSide ` if it regulates a {hoverxreftooltip}`user_manual/components:transformer` and {py:class}`Branch3Side ` if it regulates a {hoverxreftooltip}`user_manual/components:three-winding-transformer`. +- The rated voltage at the `tap_side` must be greater than or equal to the rated voltage at the `control_side`. +- The voltage band must be sufficiently large, i.e., it must be greater than the largest change in voltage due to a change in tap position. This means, that + $$U_{\text{band}} >= \frac{\text{tap_size}/u_\text{tap_side}}{\left(1 + \left(\left|\text{tap_min}\right| - \left|\text{tap_nom}\right|\right)\frac{\text{tap_size}}{\text{u_tap_side}}\right)^2}u_{\text{control_side}}$$ +- 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. This means, that + $$\left|z_comp\right|\left|I_{\text{node}}| << \frac{\text{tap_size}/u_\text{tap_side}}{\left(1 + \left(\left|\text{tap_max}\right| - \left|\text{tap_nom}\right|\right)\frac{\text{tap_size}}{\text{u_tap_side}}\right)^2}u_{\text{control_side}}$$ + +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 + +##### Line drop compensation + +The transformer tap regulator tries to optimize the voltage in a specified virtual location in the grid, according to the folowing model. + +``` +tap_side control_side part of grid where regulated voltage is desired +------^\oo -*------------------virtual_line------* + | U_node, I_node Z_comp U_control + | | + regulator <=================================/ +``` + +absolute value of the voltage at the node, compensated with the specified line drop compensation impedance. + +$$ +U_{\text{control}} = \left|\underline{U}_{\text{node}} - \underline{I}_{\text{node}} Z_{\text{compensation}}\right| +$$ +where $\underline{U}_{\text{node}}$ and $\underline{I}_{\text{node}}$ are the "measured" voltage and current phasors at the control side and may be obtained from a regular power flow calculation. diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp index 5cf263e40..5e1c1847b 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp @@ -470,7 +470,7 @@ inline auto i_pu(std::vector const& solver_output, Idx2D const case to: return branch_output.i_t; default: - throw MissingCaseForEnumError("adjust_transformer", control_side); + throw MissingCaseForEnumError{"adjust_transformer", control_side}; } } @@ -489,7 +489,7 @@ inline auto i_pu(std::vector const& solver_output, Idx2DBranch case side_3: return branch_outputs[math_id.pos[2]].i_f; default: - throw MissingCaseForEnumError("adjust_transformer", control_side); + throw MissingCaseForEnumError{"adjust_transformer", control_side}; } }