Skip to content

Commit

Permalink
Fix vsc replacement by regulating generator (#2867)
Browse files Browse the repository at this point in the history
Signed-off-by: Hugo KULESZA <hugo.kulesza@rte-france.com>
Signed-off-by: Anne Tilloy <anne.tilloy@rte-france.com>
  • Loading branch information
HugoKulesza authored Jan 23, 2024
1 parent 203bc1b commit 47e62af
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 8 deletions.
5 changes: 5 additions & 0 deletions iidm/iidm-reducer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
<artifactId>powsybl-iidm-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>powsybl-iidm-extensions</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Test dependencies -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package com.powsybl.iidm.reducer;

import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.ActivePowerControlAdder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -209,7 +210,7 @@ private void replaceHvdcLine(HvdcLine hvdcLine, VoltageLevel vl, Terminal termin
if (station.getHvdcType() == HvdcConverterStation.HvdcType.VSC) {
VscConverterStation vscStation = (VscConverterStation) station;
if (vscStation.isVoltageRegulatorOn()) {
replaceHvdcLineByGenerator(hvdcLine, vl, terminal);
replaceHvdcLineByGenerator(hvdcLine, vl, terminal, vscStation);
} else {
replaceHvdcLineByLoad(hvdcLine, vl, terminal);
}
Expand Down Expand Up @@ -242,21 +243,23 @@ private void replaceHvdcLineByLoad(HvdcLine hvdcLine, VoltageLevel vl, Terminal
observers.forEach(o -> o.hvdcLineReplaced(hvdcLine, load));
}

private void replaceHvdcLineByGenerator(HvdcLine hvdcLine, VoltageLevel vl, Terminal terminal) {
private void replaceHvdcLineByGenerator(HvdcLine hvdcLine, VoltageLevel vl, Terminal terminal, VscConverterStation station) {
double maxP = hvdcLine.getMaxP();
GeneratorAdder genAdder = vl.newGenerator()
.setId(hvdcLine.getId())
.setName(hvdcLine.getOptionalName().orElse(null))
.setEnergySource(EnergySource.OTHER)
.setVoltageRegulatorOn(false)
.setVoltageRegulatorOn(true)
.setMaxP(maxP)
.setMinP(-maxP)
.setTargetP(checkP(terminal))
.setTargetQ(checkQ(terminal));
.setTargetP(-checkP(terminal))
.setTargetV(station.getVoltageSetpoint());
fillNodeOrBus(genAdder, terminal);

double p = terminal.getP();
double q = terminal.getQ();
ReactiveLimits stationLimits = station.getReactiveLimits();

HvdcConverterStation<?> converter1 = hvdcLine.getConverterStation1();
HvdcConverterStation<?> converter2 = hvdcLine.getConverterStation2();
hvdcLine.remove();
Expand All @@ -267,6 +270,30 @@ private void replaceHvdcLineByGenerator(HvdcLine hvdcLine, VoltageLevel vl, Term
generator.getTerminal()
.setP(p)
.setQ(q);

if (stationLimits != null) {
if (stationLimits.getKind() == ReactiveLimitsKind.MIN_MAX) {
MinMaxReactiveLimits minMaxLimits = (MinMaxReactiveLimits) stationLimits;
generator.newMinMaxReactiveLimits()
.setMinQ(minMaxLimits.getMinQ())
.setMaxQ(minMaxLimits.getMaxQ())
.add();
} else if (stationLimits.getKind() == ReactiveLimitsKind.CURVE) {
ReactiveCapabilityCurve reactiveCurve = (ReactiveCapabilityCurve) stationLimits;
ReactiveCapabilityCurveAdder curveAdder = generator.newReactiveCapabilityCurve();
reactiveCurve.getPoints().forEach(point ->
curveAdder.beginPoint()
.setP(point.getP())
.setMinQ(point.getMinQ())
.setMaxQ(point.getMaxQ())
.endPoint()
);
curveAdder.add();
}
}

generator.newExtension(ActivePowerControlAdder.class).withParticipate(false).add();

observers.forEach(o -> o.hvdcLineReplaced(hvdcLine, generator));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
package com.powsybl.iidm.reducer;

import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.ActivePowerControl;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
import com.powsybl.iidm.network.test.FictitiousSwitchFactory;
import com.powsybl.iidm.network.test.HvdcTestNetwork;
import com.powsybl.iidm.network.test.ThreeWindingsTransformerNetworkFactory;
import org.junit.jupiter.api.Test;

import java.util.Collections;
import java.util.Iterator;

import static org.junit.jupiter.api.Assertions.*;

Expand Down Expand Up @@ -248,23 +250,35 @@ void testHvdc() {

@Test
void testHvdcReplacement() {
testHvdcReplacementLcc();
testHvdcReplacementVscWithMinMaxReactiveLimits();
tetHvdcReplacementVscWithReactiveCapabilityCurve();
}

private static void testHvdcReplacementLcc() {
NetworkReducerObserverImpl observerLcc = new NetworkReducerObserverImpl();
Network networkLcc = HvdcTestNetwork.createLcc();
assertEquals(0, networkLcc.getLoadCount());
assertEquals(2, networkLcc.getHvdcConverterStationCount());
NetworkReducer reducerLcc = NetworkReducer.builder()
.withNetworkPredicate(IdentifierNetworkPredicate.of("VL1"))
.withObservers(observerLcc)
.build();
.withNetworkPredicate(IdentifierNetworkPredicate.of("VL1"))
.withObservers(observerLcc)
.build();
reducerLcc.reduce(networkLcc);
assertEquals(0, networkLcc.getHvdcLineCount());
assertEquals(1, observerLcc.getHvdcLineReplacedCount());
assertEquals(1, observerLcc.getHvdcLineRemovedCount());
assertEquals(1, networkLcc.getLoadCount());
assertEquals(0, networkLcc.getHvdcConverterStationCount());
}

private static void testHvdcReplacementVscWithMinMaxReactiveLimits() {
NetworkReducerObserverImpl observerVsc = new NetworkReducerObserverImpl();
Network networkVsc = HvdcTestNetwork.createVsc();
VscConverterStation station = networkVsc.getVscConverterStation("C1");
double targetV = station.getVoltageSetpoint();
station.newMinMaxReactiveLimits().setMaxQ(200).setMinQ(-200).add();
double p = station.getTerminal().getP();
assertEquals(0, networkVsc.getGeneratorCount());
assertEquals(2, networkVsc.getHvdcConverterStationCount());
NetworkReducer reducerVsc = NetworkReducer.builder()
Expand All @@ -279,7 +293,37 @@ void testHvdcReplacement() {
Generator gen = networkVsc.getGenerator("L");
assertEquals(300, gen.getMaxP());
assertEquals(-300, gen.getMinP());
assertEquals(-p, gen.getTargetP());
assertTrue(gen.isVoltageRegulatorOn());
assertEquals(targetV, gen.getTargetV());
assertEquals(200, gen.getReactiveLimits(MinMaxReactiveLimits.class).getMaxQ());
assertFalse(gen.getExtension(ActivePowerControl.class).isParticipate());
}

private static void tetHvdcReplacementVscWithReactiveCapabilityCurve() {
NetworkReducerObserverImpl observerVsc2 = new NetworkReducerObserverImpl();
Network networkVsc2 = HvdcTestNetwork.createVsc();
VscConverterStation station2 = networkVsc2.getVscConverterStation("C1");
station2.newReactiveCapabilityCurve()
.beginPoint().setP(0.0).setMinQ(-200).setMaxQ(200).endPoint()
.beginPoint().setP(100.0).setMinQ(-200).setMaxQ(200).endPoint()
.add();
NetworkReducer reducerVsc2 = NetworkReducer.builder()
.withNetworkPredicate(IdentifierNetworkPredicate.of("VL1"))
.withObservers(observerVsc2)
.build();
reducerVsc2.reduce(networkVsc2);
Generator gen2 = networkVsc2.getGenerator("L");
assertEquals(2, gen2.getReactiveLimits(ReactiveCapabilityCurve.class).getPointCount());
Iterator<ReactiveCapabilityCurve.Point> pointIt = gen2.getReactiveLimits(ReactiveCapabilityCurve.class).getPoints().iterator();
ReactiveCapabilityCurve.Point point = pointIt.next();
assertEquals(0.0, point.getP(), 0.001);
assertEquals(-200.0, point.getMinQ(), 0.001);
assertEquals(200.0, point.getMaxQ(), 0.001);
point = pointIt.next();
assertEquals(100.0, point.getP(), 0.001);
assertEquals(-200.0, point.getMinQ(), 0.001);
assertEquals(200.0, point.getMaxQ(), 0.001);
}

@Test
Expand Down

0 comments on commit 47e62af

Please sign in to comment.