AcLoadFlowVscTest.java
/**
* Copyright (c) 2019, 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.openloadflow.ac;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.HvdcAngleDroopActivePowerControl;
import com.powsybl.iidm.network.extensions.HvdcAngleDroopActivePowerControlAdder;
import com.powsybl.iidm.network.extensions.HvdcOperatorActivePowerRangeAdder;
import com.powsybl.loadflow.LoadFlow;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.loadflow.LoadFlowResult;
import com.powsybl.math.matrix.DenseMatrixFactory;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowProvider;
import com.powsybl.openloadflow.network.HvdcNetworkFactory;
import com.powsybl.openloadflow.network.SlackBusSelectionMode;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static com.powsybl.openloadflow.util.LoadFlowAssert.*;
import static com.powsybl.openloadflow.util.LoadFlowAssert.assertActivePowerEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
class AcLoadFlowVscTest {
@Test
void test() {
Network network = HvdcNetworkFactory.createVsc();
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowParameters parameters = new LoadFlowParameters()
.setUseReactiveLimits(false)
.setDistributedSlack(false);
OpenLoadFlowParameters.create(parameters)
.setSlackBusSelectionMode(SlackBusSelectionMode.MOST_MESHED);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
Bus bus1 = network.getBusView().getBus("vl1_0");
assertVoltageEquals(390, bus1);
assertAngleEquals(0, bus1);
Bus bus2 = network.getBusView().getBus("vl2_0");
assertVoltageEquals(385, bus2);
assertAngleEquals(0.117616, bus2);
Bus bus3 = network.getBusView().getBus("vl3_0");
assertVoltageEquals(383, bus3);
assertAngleEquals(0, bus3);
Generator g1 = network.getGenerator("g1");
assertActivePowerEquals(-102.56, g1.getTerminal());
assertReactivePowerEquals(-615.918, g1.getTerminal());
VscConverterStation cs2 = network.getVscConverterStation("cs2");
assertActivePowerEquals(50.00, cs2.getTerminal());
assertReactivePowerEquals(598.228, cs2.getTerminal());
VscConverterStation cs3 = network.getVscConverterStation("cs3");
assertActivePowerEquals(-49.35, cs3.getTerminal());
assertReactivePowerEquals(-10.0, cs3.getTerminal());
Line l12 = network.getLine("l12");
assertActivePowerEquals(102.563, l12.getTerminal1());
assertReactivePowerEquals(615.918, l12.getTerminal1());
assertActivePowerEquals(-99.999, l12.getTerminal2());
assertReactivePowerEquals(-608.228, l12.getTerminal2());
}
@Test
void testRegulatingTerminal() {
Network network = HvdcNetworkFactory.createVsc();
network.getGenerator("g1").setTargetQ(50).setVoltageRegulatorOn(false);
VscConverterStation vscConverterStation = network.getVscConverterStation("cs2");
vscConverterStation.setRegulatingTerminal(network.getGenerator("g1").getTerminal()).setVoltageSetpoint(390);
vscConverterStation.setVoltageRegulatorOn(true); //FIXME
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowParameters parameters = new LoadFlowParameters().setUseReactiveLimits(false)
.setDistributedSlack(false);
OpenLoadFlowParameters.create(parameters)
.setSlackBusSelectionMode(SlackBusSelectionMode.MOST_MESHED);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
Bus bus1 = network.getBusView().getBus("vl1_0");
assertVoltageEquals(390.0, bus1);
}
@Test
void testRegulatingTerminal2() {
Network network = HvdcNetworkFactory.createVsc();
network.getGenerator("g1").setTargetV(390);
VscConverterStation vscConverterStation = network.getVscConverterStation("cs2");
vscConverterStation.setRegulatingTerminal(network.getVscConverterStation("cs3").getTerminal()).setVoltageSetpoint(400); // will be discarded.
vscConverterStation.setVoltageRegulatorOn(true); //FIXME
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowParameters parameters = new LoadFlowParameters()
.setUseReactiveLimits(false)
.setDistributedSlack(false);
OpenLoadFlowParameters.create(parameters)
.setSlackBusSelectionMode(SlackBusSelectionMode.MOST_MESHED);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
Bus bus1 = network.getBusView().getBus("vl1_0");
assertVoltageEquals(390.0, bus1);
}
@Test
void testHvdcAcEmulation() {
Network network = HvdcNetworkFactory.createVsc();
network.getHvdcLine("hvdc23").newExtension(HvdcAngleDroopActivePowerControlAdder.class)
.withDroop(180)
.withP0(0.f)
.withEnabled(true)
.add();
network.newLine()
.setId("l23")
.setBus1("b2")
.setBus2("b3")
.setR(1)
.setX(3)
.add();
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowParameters parameters = new LoadFlowParameters().setHvdcAcEmulation(true);
OpenLoadFlowParameters.create(parameters)
.setSlackBusSelectionMode(SlackBusSelectionMode.MOST_MESHED);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
VscConverterStation cs2 = network.getVscConverterStation("cs2");
assertActivePowerEquals(-4.9634, cs2.getTerminal());
assertReactivePowerEquals(360.034, cs2.getTerminal());
VscConverterStation cs3 = network.getVscConverterStation("cs3");
assertActivePowerEquals(5.0286, cs3.getTerminal());
assertReactivePowerEquals(226.984, cs3.getTerminal());
}
@Test
void testHvdcAcEmulation2() {
Network network = HvdcNetworkFactory.createWithHvdcInAcEmulation();
network.getHvdcLine("hvdc34").newExtension(HvdcAngleDroopActivePowerControlAdder.class)
.withDroop(180)
.withP0(0.f)
.withEnabled(true)
.add();
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowParameters parameters = new LoadFlowParameters();
parameters.setBalanceType(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD).setHvdcAcEmulation(true);
OpenLoadFlowParameters.create(parameters)
.setSlackBusSelectionMode(SlackBusSelectionMode.MOST_MESHED);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
VscConverterStation cs3 = network.getVscConverterStation("cs3");
assertActivePowerEquals(-0.114, cs3.getTerminal());
assertReactivePowerEquals(-4.226, cs3.getTerminal());
VscConverterStation cs4 = network.getVscConverterStation("cs4");
assertActivePowerEquals(0.1166, cs4.getTerminal());
assertReactivePowerEquals(-3.600, cs4.getTerminal());
network.getVscConverterStation("cs3").setVoltageRegulatorOn(false);
network.getVscConverterStation("cs4").setVoltageRegulatorOn(false);
LoadFlowResult result2 = loadFlowRunner.run(network, parameters);
assertTrue(result2.isFullyConverged());
assertActivePowerEquals(-0.089, cs3.getTerminal());
assertReactivePowerEquals(0.0, cs3.getTerminal());
assertActivePowerEquals(0.0914, cs4.getTerminal());
assertReactivePowerEquals(0.0, cs4.getTerminal());
}
@Test
void testHvdcAcEmulationNonSupported() {
Network network = HvdcNetworkFactory.createVsc();
network.getHvdcLine("hvdc23").newExtension(HvdcAngleDroopActivePowerControlAdder.class)
.withDroop(180)
.withP0(0.f)
.withEnabled(true)
.add();
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowParameters parameters = new LoadFlowParameters().setHvdcAcEmulation(true);
OpenLoadFlowParameters.create(parameters)
.setSlackBusSelectionMode(SlackBusSelectionMode.MOST_MESHED);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
VscConverterStation cs2 = network.getVscConverterStation("cs2");
assertActivePowerEquals(50.0, cs2.getTerminal());
assertReactivePowerEquals(598.227, cs2.getTerminal());
VscConverterStation cs3 = network.getVscConverterStation("cs3");
assertActivePowerEquals(-49.35, cs3.getTerminal());
assertReactivePowerEquals(-10.0, cs3.getTerminal());
}
@Test
void testHvdcDisconnectedAtOneSide() {
Network network = HvdcNetworkFactory.createVsc();
network.getVscConverterStation("cs3").getTerminal().disconnect();
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowParameters parameters = new LoadFlowParameters()
.setUseReactiveLimits(false)
.setDistributedSlack(false);
OpenLoadFlowParameters.create(parameters)
.setSlackBusSelectionMode(SlackBusSelectionMode.MOST_MESHED);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
Bus bus1 = network.getBusView().getBus("vl1_0");
assertVoltageEquals(390, bus1);
assertAngleEquals(0, bus1);
Bus bus2 = network.getBusView().getBus("vl2_0");
assertVoltageEquals(385, bus2);
assertAngleEquals(0.18116, bus2);
Bus bus3 = network.getBusView().getBus("vl3_0");
assertVoltageEquals(Double.NaN, bus3);
assertAngleEquals(Double.NaN, bus3);
Generator g1 = network.getGenerator("g1");
assertActivePowerEquals(-102.56, g1.getTerminal());
assertReactivePowerEquals(-632.700, g1.getTerminal());
VscConverterStation cs2 = network.getVscConverterStation("cs2");
assertActivePowerEquals(0.00, cs2.getTerminal());
assertReactivePowerEquals(614.750, cs2.getTerminal());
VscConverterStation cs3 = network.getVscConverterStation("cs3");
assertActivePowerEquals(Double.NaN, cs3.getTerminal());
assertReactivePowerEquals(Double.NaN, cs3.getTerminal());
Line l12 = network.getLine("l12");
assertActivePowerEquals(52.65, l12.getTerminal1());
assertReactivePowerEquals(632.700, l12.getTerminal1());
assertActivePowerEquals(-50.00, l12.getTerminal2());
assertReactivePowerEquals(-624.750, l12.getTerminal2());
}
@Test
void testVscConverterWithoutHvdcLineNpe() {
Network network = HvdcNetworkFactory.createVsc();
network.getHvdcLine("hvdc23").remove();
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowResult result = loadFlowRunner.run(network);
assertTrue(result.isFullyConverged());
}
@Test
void testHvdcPowerAcEmulation() {
Network network = HvdcNetworkFactory.createHvdcLinkedByTwoLinesAndSwitch();
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowResult result = loadFlowRunner.run(network, new LoadFlowParameters());
assertTrue(result.isFullyConverged());
// AC Emulation takes into account cable loss
assertActivePowerEquals(198.158, network.getHvdcConverterStation("cs2").getTerminal());
assertActivePowerEquals(-193.799, network.getHvdcConverterStation("cs3").getTerminal());
assertActivePowerEquals(-304.359, network.getGenerator("g1").getTerminal());
assertActivePowerEquals(300.0, network.getLoad("l4").getTerminal());
}
@Test
void testHvdcPowerAcEmulationWithoutR() {
Network network = HvdcNetworkFactory.createHvdcLinkedByTwoLinesAndSwitch();
network.getHvdcLine("hvdc23").setR(0d); //Removing resistance to ignore cable loss
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowResult result = loadFlowRunner.run(network, new LoadFlowParameters());
assertTrue(result.isFullyConverged());
assertActivePowerEquals(198.158, network.getHvdcConverterStation("cs2").getTerminal());
assertActivePowerEquals(-193.822, network.getHvdcConverterStation("cs3").getTerminal());
assertActivePowerEquals(-304.335, network.getGenerator("g1").getTerminal());
assertActivePowerEquals(300.0, network.getLoad("l4").getTerminal());
}
@Test
void testHvdcDirectionChangeAcEmulation() {
Network network = HvdcNetworkFactory.createHvdcInAcEmulationInSymetricNetwork();
network.getHvdcLine("hvdc12").setR(0.1d);
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowParameters parameters = new LoadFlowParameters().setHvdcAcEmulation(true);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
double pg2 = network.getGenerator("g2").getTerminal().getP();
double pg1 = network.getGenerator("g1").getTerminal().getP();
double pcs1 = network.getVscConverterStation("cs1").getTerminal().getP();
double pcs2 = network.getVscConverterStation("cs2").getTerminal().getP();
// Test basic energy conservation terms
assertEquals(0.0, pg2, DELTA_POWER, "g2 should be off");
assertTrue(-pg1 >= 5.99999, "g1 generates power for all loads");
assertTrue(-pg1 <= 6.06, "reasonable loss");
assertTrue(pcs1 > 0, "Power enters at cs1");
assertTrue(pcs2 < 0, "Power delivered by cs2");
assertTrue(Math.abs(pcs1) > Math.abs(pcs2), "Loss at HVDC output");
// Test if removing line resistance increases the power transit
network.getHvdcLine("hvdc12").setR(0d);
result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
double pcs1r0 = network.getVscConverterStation("cs1").getTerminal().getP();
double pcs2r0 = network.getVscConverterStation("cs2").getTerminal().getP();
assertTrue(pcs1r0 > 0, "Power enters at cs1");
assertTrue(pcs2r0 < 0, "Power delivered by cs2");
assertTrue(Math.abs(pcs2r0 + pcs1r0) < Math.abs(pcs2 - pcs1)); // Check that loss with R=0 is lower than loss with R!=0
// Reverse power flow direction
network.getHvdcLine("hvdc12").setR(0.1d);
network.getGenerator("g2").setTargetP(5);
network.getGenerator("g1").setTargetP(0);
result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
pg2 = network.getGenerator("g2").getTerminal().getP();
pg1 = network.getGenerator("g1").getTerminal().getP();
pcs1 = network.getVscConverterStation("cs1").getTerminal().getP();
pcs2 = network.getVscConverterStation("cs2").getTerminal().getP();
// Test basic energy conservation terms in symetric network
// (active power is not a close enough symetric as in first run for some reason - so we can't compare b1 and b2 values for all termnals)
assertEquals(0.0, pg1, DELTA_POWER, "g1 should be off");
assertTrue(-pg2 >= 5.99999, "g2 generates power for all loads");
assertTrue(-pg2 <= 6.06, "reasonable loss");
assertTrue(pcs2 > 0, "Power enters at cs2");
assertTrue(pcs1 < 0, "Power delivered by cs1");
assertTrue(Math.abs(pcs2) > Math.abs(pcs1), "Loss at HVDC output");
// Test if removing line resistance increases the power transit in symetric network
network.getHvdcLine("hvdc12").setR(0d);
result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
pcs1r0 = network.getVscConverterStation("cs1").getTerminal().getP();
pcs2r0 = network.getVscConverterStation("cs2").getTerminal().getP();
assertTrue(pcs2r0 > 0, "Power enters at cs2");
assertTrue(pcs1r0 < 0, "Power delivered by cs1");
assertTrue(Math.abs(pcs2r0 + pcs1r0) < Math.abs(pcs2 - pcs1)); // Check that loss with R=0 is lower than loss with R!=0
}
@Test
void testLccOpenAtOneSide() {
Network network = HvdcNetworkFactory.createHvdcLinkedByTwoLinesAndSwitch(HvdcConverterStation.HvdcType.LCC);
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowResult result = loadFlowRunner.run(network);
assertTrue(result.isFullyConverged());
// generator g1 expected to deliver enough power for the load
assertActivePowerEquals(-304.400, network.getGenerator("g1").getTerminal());
assertActivePowerEquals(300.00, network.getLoad("l4").getTerminal());
assertActivePowerEquals(-195.600, network.getHvdcConverterStation("cs2").getTerminal());
assertActivePowerEquals(200.00, network.getHvdcConverterStation("cs3").getTerminal());
Line l34 = network.getLine("l34");
l34.getTerminals().stream().forEach(Terminal::disconnect);
result = loadFlowRunner.run(network);
assertTrue(result.isFullyConverged()); // note that for LCC test the smaller component is flagged as NO_CALCULATION
assertActivePowerEquals(-300.00, network.getGenerator("g1").getTerminal());
assertActivePowerEquals(300.00, network.getLoad("l4").getTerminal());
assertTrue(Double.isNaN(network.getHvdcConverterStation("cs2").getTerminal().getP())); // FIXME
assertTrue(Double.isNaN(network.getHvdcConverterStation("cs3").getTerminal().getP()));
}
@Test
void testVscOpenAtOneSide() {
Network network = HvdcNetworkFactory.createHvdcLinkedByTwoLinesAndSwitch(HvdcConverterStation.HvdcType.VSC);
LoadFlowParameters parameters = new LoadFlowParameters()
.setHvdcAcEmulation(false);
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
// generator g1 expected to deliver enough power for the load
assertActivePowerEquals(-304.400, network.getGenerator("g1").getTerminal());
assertActivePowerEquals(300.00, network.getLoad("l4").getTerminal());
assertActivePowerEquals(-195.600, network.getHvdcConverterStation("cs2").getTerminal());
assertActivePowerEquals(200.00, network.getHvdcConverterStation("cs3").getTerminal());
Line l34 = network.getLine("l34");
l34.getTerminals().stream().forEach(Terminal::disconnect);
result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertActivePowerEquals(-300.00, network.getGenerator("g1").getTerminal());
assertActivePowerEquals(300.00, network.getLoad("l4").getTerminal());
assertActivePowerEquals(0.0, network.getHvdcConverterStation("cs2").getTerminal());
assertActivePowerEquals(0.0, network.getHvdcConverterStation("cs3").getTerminal());
}
@Test
void testHvdcAndGenerator() {
Network network = HvdcNetworkFactory.createWithHvdcAndGenerator();
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowResult result = loadFlowRunner.run(network, new LoadFlowParameters());
assertTrue(result.isFullyConverged());
assertActivePowerEquals(-1.956, network.getVscConverterStation("cs3").getTerminal());
assertActivePowerEquals(2.0, network.getVscConverterStation("cs4").getTerminal());
assertActivePowerEquals(-2.0, network.getGenerator("g4").getTerminal());
assertActivePowerEquals(-2.047, network.getGenerator("g1").getTerminal());
}
@Test
void testVscVoltageControlWithZeroTargetP() {
Network network = HvdcNetworkFactory.createHvdcLinkedByTwoLinesAndSwitch(HvdcConverterStation.HvdcType.VSC);
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
// Set specific voltage setPoints to the stations
double vcs2 = 397;
double vcs3 = 401;
network.getVscConverterStation("cs2").setVoltageSetpoint(vcs2);
network.getVscConverterStation("cs3").setVoltageSetpoint(vcs3);
// shut down active power flow in HVDC
network.getHvdcLine("hvdc23").setActivePowerSetpoint(0);
network.getHvdcLine("hvdc23").getExtension(HvdcAngleDroopActivePowerControl.class).setDroop(0).setP0(0);
LoadFlowParameters p = new LoadFlowParameters();
// without AC emulation
p.setHvdcAcEmulation(false);
LoadFlowResult result = loadFlowRunner.run(network, p);
assertTrue(result.isFullyConverged());
assertActivePowerEquals(0, network.getVscConverterStation("cs2").getTerminal());
assertVoltageEquals(vcs2, network.getVscConverterStation("cs2").getTerminal().getBusView().getBus());
assertActivePowerEquals(0, network.getVscConverterStation("cs3").getTerminal());
assertVoltageEquals(vcs3, network.getVscConverterStation("cs3").getTerminal().getBusView().getBus());
// with AC emulation
p.setHvdcAcEmulation(true);
result = loadFlowRunner.run(network, p);
assertTrue(result.isFullyConverged());
assertActivePowerEquals(0, network.getVscConverterStation("cs2").getTerminal());
assertVoltageEquals(vcs2, network.getVscConverterStation("cs2").getTerminal().getBusView().getBus());
assertActivePowerEquals(0, network.getVscConverterStation("cs3").getTerminal());
assertVoltageEquals(vcs3, network.getVscConverterStation("cs3").getTerminal().getBusView().getBus());
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testVscVoltageControlWithOneSideDisconnected(boolean withFictiveLoad) {
Network network = HvdcNetworkFactory.createHvdcLinkedByTwoLinesAndSwitch(HvdcConverterStation.HvdcType.VSC);
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
// Set specific voltage setPoints to the stations
double vcs2 = 397;
double vcs3 = 401;
network.getVscConverterStation("cs2").setVoltageSetpoint(vcs2);
network.getVscConverterStation("cs3").setVoltageSetpoint(vcs3);
if (withFictiveLoad) {
// Add a fictive load to the bus that will be disconnected
network.getBusBreakerView().getBus("b3").getVoltageLevel().newLoad()
.setId("fictiveLoad")
.setBus("b3")
.setConnectableBus("b3")
.setP0(5)
.setQ0(2)
.setFictitious(true)
.add();
}
LoadFlowParameters p = new LoadFlowParameters();
LoadFlowResult result = loadFlowRunner.run(network, p);
assertTrue(result.isFullyConverged());
// Just test that the HVDC is open - no need for more precision
assertTrue(network.getVscConverterStation("cs2").getTerminal().getP() > 100);
assertVoltageEquals(vcs2, network.getVscConverterStation("cs2").getTerminal().getBusView().getBus());
// Disconnect line at HVDCoutput
Line l34 = network.getLine("l34");
l34.getTerminals().stream().forEach(Terminal::disconnect);
// without AC emulation
p.setHvdcAcEmulation(false);
result = loadFlowRunner.run(network, p);
assertTrue(result.isFullyConverged());
assertActivePowerEquals(0, network.getVscConverterStation("cs2").getTerminal());
assertVoltageEquals(vcs2, network.getVscConverterStation("cs2").getTerminal().getBusView().getBus());
// with AC emulation
p.setHvdcAcEmulation(true);
result = loadFlowRunner.run(network, p);
assertActivePowerEquals(0, network.getVscConverterStation("cs2").getTerminal());
assertVoltageEquals(vcs2, network.getVscConverterStation("cs2").getTerminal().getBusView().getBus());
}
@Test
void testAcEmuWithOperationalLimits() {
Network network = HvdcNetworkFactory.createHvdcLinkedByTwoLinesAndSwitch(HvdcConverterStation.HvdcType.VSC);
// without limit p=195
network.getHvdcLine("hvdc23")
.newExtension(HvdcOperatorActivePowerRangeAdder.class)
.withOprFromCS2toCS1(180)
.withOprFromCS1toCS2(170)
.add();
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowParameters p = new LoadFlowParameters();
p.setHvdcAcEmulation(true);
LoadFlowResult result = loadFlowRunner.run(network, p);
assertTrue(result.isFullyConverged());
// Active flow capped at limit. Output has losses (due to VSC stations)
assertEquals(170, network.getHvdcConverterStation("cs2").getTerminal().getP(), DELTA_POWER);
assertEquals(-166.263, network.getHvdcConverterStation("cs3").getTerminal().getP(), DELTA_POWER);
// now invert power direction
HvdcAngleDroopActivePowerControl activePowerControl = network.getHvdcLine("hvdc23").getExtension(HvdcAngleDroopActivePowerControl.class);
activePowerControl.setP0(-activePowerControl.getP0());
result = loadFlowRunner.run(network, p);
assertTrue(result.isFullyConverged());
// Active flow capped at other direction's limit. Output has losses (due to VSC stations)
assertEquals(-176.042, network.getHvdcConverterStation("cs2").getTerminal().getP(), DELTA_POWER);
assertEquals(180, network.getHvdcConverterStation("cs3").getTerminal().getP(), DELTA_POWER);
}
@Test
void testAcEmuAndPMax() {
Network network = HvdcNetworkFactory.createHvdcLinkedByTwoLinesAndSwitch(HvdcConverterStation.HvdcType.VSC);
// without limit p=195
network.getHvdcLine("hvdc23")
.setMaxP(170);
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowParameters p = new LoadFlowParameters();
p.setHvdcAcEmulation(true);
LoadFlowResult result = loadFlowRunner.run(network, p);
assertTrue(result.isFullyConverged());
// Active flow capped at limit. Output has losses (due to VSC stations)
assertActivePowerEquals(170, network.getHvdcConverterStation("cs2").getTerminal());
assertActivePowerEquals(-166.263, network.getHvdcConverterStation("cs3").getTerminal());
// now invert power direction
HvdcAngleDroopActivePowerControl activePowerControl = network.getHvdcLine("hvdc23").getExtension(HvdcAngleDroopActivePowerControl.class);
activePowerControl.setP0(-activePowerControl.getP0());
result = loadFlowRunner.run(network, p);
assertTrue(result.isFullyConverged());
assertActivePowerEquals(-166.263, network.getHvdcConverterStation("cs2").getTerminal());
assertActivePowerEquals(170, network.getHvdcConverterStation("cs3").getTerminal());
}
@Test
void testDcLoadFlowWithHvdcAcEmulation2() {
Network network = HvdcNetworkFactory.createVsc();
network.newLine() // in order to have only one synchronous component for the moment.
.setId("l23")
.setVoltageLevel1("vl2")
.setBus1("b2")
.setVoltageLevel2("vl3")
.setBus2("b3")
.setR(1)
.setX(3)
.setG1(0)
.setG2(0)
.setB1(0)
.setB2(0)
.add();
HvdcAngleDroopActivePowerControl hvdcAngleDroopActivePowerControl = network.getHvdcLine("hvdc23").newExtension(HvdcAngleDroopActivePowerControlAdder.class)
.withDroop(180)
.withP0(0.f)
.withEnabled(true)
.add();
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowParameters parameters = new LoadFlowParameters()
.setDc(true);
OpenLoadFlowParameters olfParams = OpenLoadFlowParameters.create(parameters)
.setSlackBusSelectionMode(SlackBusSelectionMode.MOST_MESHED);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
VscConverterStation cs2 = network.getVscConverterStation("cs2");
assertActivePowerEquals(8.102, cs2.getTerminal()); // 0MW + 180 MW/deg * 0.04501deg
assertAngleEquals(0.0, cs2.getTerminal().getBusView().getBus());
VscConverterStation cs3 = network.getVscConverterStation("cs3");
assertActivePowerEquals(-8.102, cs3.getTerminal());
assertAngleEquals(-0.04501, cs3.getTerminal().getBusView().getBus());
// Now with a non null P0
hvdcAngleDroopActivePowerControl.setP0(10);
result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertActivePowerEquals(16.482, cs2.getTerminal()); // 10MW + 180 MW/deg * 0.036008deg
assertAngleEquals(0.0, cs2.getTerminal().getBusView().getBus());
assertActivePowerEquals(-16.482, cs3.getTerminal());
assertAngleEquals(-0.036008, cs3.getTerminal().getBusView().getBus());
result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertActivePowerEquals(16.482, cs2.getTerminal()); // 10MW + 180 MW/deg * 0.036008deg
assertAngleEquals(0.0, cs2.getTerminal().getBusView().getBus());
assertActivePowerEquals(-16.482, cs3.getTerminal());
assertAngleEquals(-0.036008, cs3.getTerminal().getBusView().getBus());
// Add another HVDC line connected the other way arround to make sure all equation terms are run
// (the equations on the slack bus are not run)
network.getVoltageLevel("vl2")
.newVscConverterStation()
.setId("cs2Bis")
.setConnectableBus("b2")
.setBus("b2")
.setVoltageRegulatorOn(true)
.setVoltageSetpoint(385)
.setReactivePowerSetpoint(100)
.setLossFactor(1.1f)
.add();
network.getVoltageLevel("vl3")
.newVscConverterStation()
.setId("cs3Bis")
.setConnectableBus("b3")
.setBus("b3")
.setVoltageRegulatorOn(true)
.setVoltageSetpoint(383)
.setReactivePowerSetpoint(100)
.setLossFactor(0.2f)
.add();
network.newHvdcLine()
.setId("hvdc32")
.setConverterStationId1("cs3Bis")
.setConverterStationId2("cs2Bis")
.setNominalV(400)
.setR(0.1)
.setActivePowerSetpoint(50)
.setConvertersMode(HvdcLine.ConvertersMode.SIDE_1_RECTIFIER_SIDE_2_INVERTER)
.setMaxP(500)
.add();
network.getHvdcLine("hvdc32").newExtension(HvdcAngleDroopActivePowerControlAdder.class)
.withDroop(180)
.withP0(0.f)
.withEnabled(true)
.add();
result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertActivePowerEquals(15.578, cs2.getTerminal()); // 10MW + 180 MW/deg * 0.030988deg
assertAngleEquals(0.0, cs2.getTerminal().getBusView().getBus());
assertActivePowerEquals(-15.578, cs3.getTerminal());
assertAngleEquals(-0.030988, cs3.getTerminal().getBusView().getBus());
assertActivePowerEquals(5.578, network.getVscConverterStation("cs2Bis").getTerminal()); // 0MW + 180 MW/deg * 0.030988deg
}
}