Skip to content

Commit

Permalink
Three-winding transformers creation (#739)
Browse files Browse the repository at this point in the history
Signed-off-by: Coline PILOQUET <[email protected]>
  • Loading branch information
colinepiloquet authored Apr 30, 2024
1 parent 0329bac commit 3e8d9b7
Show file tree
Hide file tree
Showing 10 changed files with 553 additions and 33 deletions.
1 change: 1 addition & 0 deletions docs/reference/network.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ Network elements can be created or removed using the following methods:
:nosignatures:

Network.create_2_windings_transformers
Network.create_3_windings_transformers
Network.create_batteries
Network.create_busbar_sections
Network.create_buses
Expand Down
40 changes: 39 additions & 1 deletion docs/user_guide/network.rst
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ Let's now create some buses inside those voltage levels:
network.create_buses(id=['B1', 'B2'], voltage_level_id=['VL1', 'VL2'])


Let's connect thoses buses with a line:
Let's connect these buses with a line:

.. testcode::

Expand All @@ -347,6 +347,44 @@ You can now run a loadflow to check our network actually works !
>>> str(res[0].status)
'ComponentStatus.CONVERGED'

Now let's see how to add a three-winding transformer to the network. First, let's add two voltage levels and their associated buses to the substation `S1`.

.. testcode::

voltage_levels = pd.DataFrame.from_records(index='id', data=[
{'substation_id': 'S1', 'id': 'VL3', 'topology_kind': 'BUS_BREAKER', 'nominal_v': 225},
{'substation_id': 'S1', 'id': 'VL4', 'topology_kind': 'BUS_BREAKER', 'nominal_v': 90},
])
network.create_voltage_levels(voltage_levels)
network.create_buses(id=['B3', 'B4'], voltage_level_id=['VL3', 'VL4'])

Now let's add a three-winding transformer between VL1, VL2 and VL3:

.. testcode::

network.create_3_windings_transformers(id='T1', rated_u0 = 225, voltage_level1_id='VL1', bus1_id='B1',
voltage_level2_id='VL3', bus2_id='B3',
voltage_level3_id='VL4', bus3_id='B4',
b1=1e-6, g1=1e-6, r1=0.5, x1=10, rated_u1=400,
b2=1e-6, g2=1e-6, r2=0.5, x2=10, rated_u2=225,
b3=1e-6, g3=1e-6, r3=0.5, x3=10, rated_u3=90)

You can add a ratio tap changer on the leg 1 of the three-winding transformer with:

.. testcode::

rtc_df = pd.DataFrame.from_records(
index='id',
columns=['id', 'target_deadband', 'target_v', 'on_load', 'low_tap', 'tap', 'side'],
data=[('T1', 2, 200, False, 0, 1, 'ONE')])
steps_df = pd.DataFrame.from_records(
index='id',
columns=['id', 'b', 'g', 'r', 'x', 'rho'],
data=[('T1', 2, 2, 1, 1, 0.5),
('T1', 2, 2, 1, 1, 0.5),
('T1', 2, 2, 1, 1, 0.8)])
network.create_ratio_tap_changers(rtc_df, steps_df)

For more details and examples about network elements creations,
please refer to the API reference :doc:`documentation </reference/network>`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public final class NetworkElementAdders {
Map.entry(LINE, new LineDataframeAdder()),
Map.entry(STATIC_VAR_COMPENSATOR, new SvcDataframeAdder()),
Map.entry(TWO_WINDINGS_TRANSFORMER, new TwtDataframeAdder()),
Map.entry(THREE_WINDINGS_TRANSFORMER, new ThreeWindingsTransformerDataframeAdder()),
Map.entry(LOAD, new LoadDataframeAdder()),
Map.entry(VSC_CONVERTER_STATION, new VscStationDataframeAdder()),
Map.entry(LCC_CONVERTER_STATION, new LccStationDataframeAdder()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public class PhaseTapChangerDataframeAdder implements NetworkElementAdder {
SeriesMetadata.booleans("regulating"),
SeriesMetadata.strings("regulated_side"),
SeriesMetadata.ints("low_tap"),
SeriesMetadata.ints("tap")
SeriesMetadata.ints("tap"),
SeriesMetadata.strings("side")
);

private static final List<SeriesMetadata> STEPS_METADATA = List.of(
Expand Down Expand Up @@ -71,6 +72,7 @@ private static class PhaseTapChangerSeries {
private final DoubleSeries targetValues;
private final IntSeries regulating;
private final StringSeries regulatedSide;
private final StringSeries sides;

private final Map<String, TIntArrayList> stepsIndexes;
private final DoubleSeries g;
Expand All @@ -89,6 +91,7 @@ private static class PhaseTapChangerSeries {
this.targetValues = tapChangersDf.getDoubles("target_value");
this.regulating = tapChangersDf.getInts("regulating");
this.regulatedSide = tapChangersDf.getStrings("regulated_side");
this.sides = tapChangersDf.getStrings("side");

this.stepsIndexes = getStepsIndexes(stepsDf);
this.g = stepsDf.getDoubles("g");
Expand All @@ -101,20 +104,33 @@ private static class PhaseTapChangerSeries {

void create(Network network, int row) {
String transformerId = ids.get(row);
TwoWindingsTransformer transformer = network.getTwoWindingsTransformer(transformerId);
if (transformer == null) {
throw new PowsyblException("Transformer " + transformerId + " does not exist.");
TwoWindingsTransformer twoWindingsTransformer = network.getTwoWindingsTransformer(transformerId);
PhaseTapChangerAdder adder;
if (twoWindingsTransformer == null) {
ThreeWindingsTransformer threeWindingsTransformer = network.getThreeWindingsTransformer(transformerId);
if (threeWindingsTransformer == null) {
throw new PowsyblException("Transformer " + transformerId + " does not exist.");
}
if (sides == null) {
throw new PowsyblException("Side is missing: cannot add a ratio tap changer on a three-winding transformer.");
}
ThreeSides side = ThreeSides.valueOf(sides.get(row));
adder = threeWindingsTransformer.getLeg(side).newPhaseTapChanger();
if (regulatedSide != null) {
setRegulatedSide(threeWindingsTransformer, adder, regulatedSide.get(row));
}
} else {
adder = twoWindingsTransformer.newPhaseTapChanger();
if (regulatedSide != null) {
setRegulatedSide(twoWindingsTransformer, adder, regulatedSide.get(row));
}
}
PhaseTapChangerAdder adder = transformer.newPhaseTapChanger();
applyIfPresent(regulationModes, row, PhaseTapChanger.RegulationMode.class, adder::setRegulationMode);
applyIfPresent(targetDeadband, row, adder::setTargetDeadband);
applyIfPresent(targetValues, row, adder::setRegulationValue);
applyIfPresent(lowTaps, row, adder::setLowTapPosition);
applyIfPresent(taps, row, adder::setTapPosition);
applyBooleanIfPresent(regulating, row, adder::setRegulating);
if (regulatedSide != null) {
setRegulatedSide(transformer, adder, regulatedSide.get(row));
}

TIntArrayList steps = stepsIndexes.get(transformerId);
if (steps != null) {
Expand All @@ -132,14 +148,20 @@ void create(Network network, int row) {
}
adder.add();
}
}

private static void setRegulatedSide(TwoWindingsTransformer transformer, PhaseTapChangerAdder adder, String regulatedSideStr) {
if (regulatedSideStr.isEmpty()) {
return;
private static void setRegulatedSide(ThreeWindingsTransformer transformer, PhaseTapChangerAdder adder, String regulatedSideStr) {
if (!regulatedSideStr.isEmpty()) {
ThreeSides regulatedSide = ThreeSides.valueOf(regulatedSideStr);
adder.setRegulationTerminal(transformer.getTerminal(regulatedSide));
}
}

private static void setRegulatedSide(TwoWindingsTransformer transformer, PhaseTapChangerAdder adder, String regulatedSideStr) {
if (!regulatedSideStr.isEmpty()) {
TwoSides regulatedSide = TwoSides.valueOf(regulatedSideStr);
adder.setRegulationTerminal(transformer.getTerminal(regulatedSide));
}
}
TwoSides regulatedSide = TwoSides.valueOf(regulatedSideStr);
adder.setRegulationTerminal(transformer.getTerminal(regulatedSide));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public class RatioTapChangerDataframeAdder implements NetworkElementAdder {
SeriesMetadata.doubles("target_v"),
SeriesMetadata.doubles("target_deadband"),
SeriesMetadata.booleans("regulating"),
SeriesMetadata.strings("regulated_side")
SeriesMetadata.strings("regulated_side"),
SeriesMetadata.strings("side")
);

private static final List<SeriesMetadata> STEPS_METADATA = List.of(
Expand All @@ -58,6 +59,7 @@ private static class RatioTapChangerSeries {
private final DoubleSeries targetDeadband;
private final IntSeries regulating;
private final StringSeries regulatedSide;
private final StringSeries sides;

private final Map<String, TIntArrayList> stepsIndexes;
private final DoubleSeries g;
Expand All @@ -75,6 +77,7 @@ private static class RatioTapChangerSeries {
this.targetDeadband = tapChangersDf.getDoubles("target_deadband");
this.regulating = tapChangersDf.getInts("regulating");
this.regulatedSide = tapChangersDf.getStrings("regulated_side");
this.sides = tapChangersDf.getStrings("side");

this.stepsIndexes = getStepsIndexes(stepsDf);
this.g = stepsDf.getDoubles("g");
Expand All @@ -86,20 +89,33 @@ private static class RatioTapChangerSeries {

void create(Network network, int row) {
String transformerId = ids.get(row);
TwoWindingsTransformer transformer = network.getTwoWindingsTransformer(transformerId);
if (transformer == null) {
throw new PowsyblException("Transformer " + transformerId + " does not exist.");
RatioTapChangerAdder adder;
TwoWindingsTransformer twoWindingsTransformer = network.getTwoWindingsTransformer(transformerId);
if (twoWindingsTransformer == null) {
ThreeWindingsTransformer threeWindingsTransformer = network.getThreeWindingsTransformer(transformerId);
if (threeWindingsTransformer == null) {
throw new PowsyblException("Transformer " + transformerId + " does not exist.");
}
if (sides == null) {
throw new PowsyblException("Side is missing: cannot add a ratio tap changer on a three-winding transformer.");
}
ThreeSides side = ThreeSides.valueOf(sides.get(row));
adder = threeWindingsTransformer.getLeg(side).newRatioTapChanger();
if (regulatedSide != null) {
setRegulatedSide(threeWindingsTransformer, adder, regulatedSide.get(row));
}
} else {
adder = twoWindingsTransformer.newRatioTapChanger();
if (regulatedSide != null) {
setRegulatedSide(twoWindingsTransformer, adder, regulatedSide.get(row));
}
}
RatioTapChangerAdder adder = transformer.newRatioTapChanger();
applyIfPresent(targetDeadband, row, adder::setTargetDeadband);
applyIfPresent(targetV, row, adder::setTargetV);
applyBooleanIfPresent(onLoad, row, adder::setLoadTapChangingCapabilities);
applyIfPresent(lowTaps, row, adder::setLowTapPosition);
applyIfPresent(taps, row, adder::setTapPosition);
applyBooleanIfPresent(regulating, row, adder::setRegulating);
if (regulatedSide != null) {
setRegulatedSide(transformer, adder, regulatedSide.get(row));
}

TIntArrayList steps = stepsIndexes.get(transformerId);
if (steps != null) {
Expand All @@ -116,14 +132,20 @@ void create(Network network, int row) {
}
adder.add();
}
}

private static void setRegulatedSide(TwoWindingsTransformer transformer, RatioTapChangerAdder adder, String regulatedSideStr) {
if (regulatedSideStr.isEmpty()) {
return;
private static void setRegulatedSide(TwoWindingsTransformer transformer, RatioTapChangerAdder adder, String regulatedSideStr) {
if (!regulatedSideStr.isEmpty()) {
TwoSides regulatedSide = TwoSides.valueOf(regulatedSideStr);
adder.setRegulationTerminal(transformer.getTerminal(regulatedSide));
}
}

private static void setRegulatedSide(ThreeWindingsTransformer transformer, RatioTapChangerAdder adder, String regulatedSideStr) {
if (!regulatedSideStr.isEmpty()) {
ThreeSides regulatedSide = ThreeSides.valueOf(regulatedSideStr);
adder.setRegulationTerminal(transformer.getTerminal(regulatedSide));
}
}
TwoSides regulatedSide = TwoSides.valueOf(regulatedSideStr);
adder.setRegulationTerminal(transformer.getTerminal(regulatedSide));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* Copyright (c) 2024, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.dataframe.network.adders;

import com.powsybl.dataframe.SeriesMetadata;
import com.powsybl.dataframe.update.UpdatingDataframe;
import com.powsybl.iidm.network.Network;

import java.util.Collections;
import java.util.List;

/**
* @author Coline Piloquet <coline.piloquet at rte-france.com>
*/
public class ThreeWindingsTransformerDataframeAdder extends AbstractSimpleAdder {

private static final List<SeriesMetadata> METADATA = List.of(
SeriesMetadata.stringIndex("id"),
SeriesMetadata.strings("name"),
SeriesMetadata.doubles("rated_u0"),
SeriesMetadata.doubles("r1"),
SeriesMetadata.doubles("x1"),
SeriesMetadata.doubles("g1"),
SeriesMetadata.doubles("b1"),
SeriesMetadata.doubles("rated_u1"),
SeriesMetadata.doubles("rated_s1"),
SeriesMetadata.strings("voltage_level1_id"),
SeriesMetadata.ints("node1"),
SeriesMetadata.strings("bus1_id"),
SeriesMetadata.strings("connectable_bus1_id"),
SeriesMetadata.doubles("r2"),
SeriesMetadata.doubles("x2"),
SeriesMetadata.doubles("g2"),
SeriesMetadata.doubles("b2"),
SeriesMetadata.doubles("rated_u2"),
SeriesMetadata.doubles("rated_s2"),
SeriesMetadata.strings("voltage_level2_id"),
SeriesMetadata.ints("node2"),
SeriesMetadata.strings("bus2_id"),
SeriesMetadata.strings("connectable_bus2_id"),
SeriesMetadata.doubles("r3"),
SeriesMetadata.doubles("x3"),
SeriesMetadata.doubles("g3"),
SeriesMetadata.doubles("b3"),
SeriesMetadata.doubles("rated_u3"),
SeriesMetadata.doubles("rated_s3"),
SeriesMetadata.strings("voltage_level3_id"),
SeriesMetadata.ints("node3"),
SeriesMetadata.strings("bus3_id"),
SeriesMetadata.strings("connectable_bus3_id")
);

@Override
public List<List<SeriesMetadata>> getMetadata() {
return Collections.singletonList(METADATA);
}

@Override
public void addElements(Network network, UpdatingDataframe dataframe) {
ThreeWindingsTransformerSeries series = new ThreeWindingsTransformerSeries(dataframe);
for (int row = 0; row < dataframe.getRowCount(); row++) {
series.create(network, row).add();
}
}

}
Loading

0 comments on commit 3e8d9b7

Please sign in to comment.