AcLoadFlowWithCachingTest.java
/**
* Copyright (c) 2022, 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.ieeecdf.converter.IeeeCdfNetworkFactory;
import com.powsybl.iidm.network.Bus;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.VariantManagerConstants;
import com.powsybl.iidm.network.extensions.*;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
import com.powsybl.iidm.network.test.FourSubstationsNodeBreakerFactory;
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.NetworkCache;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowProvider;
import com.powsybl.openloadflow.network.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Set;
import static com.powsybl.openloadflow.util.LoadFlowAssert.*;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
class AcLoadFlowWithCachingTest {
private LoadFlow.Runner loadFlowRunner;
private LoadFlowParameters parameters;
private OpenLoadFlowParameters parametersExt;
@BeforeEach
void setUp() {
loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
parameters = new LoadFlowParameters();
parametersExt = OpenLoadFlowParameters.create(parameters)
.setNetworkCacheEnabled(true);
NetworkCache.INSTANCE.clear();
}
@Test
void testTargetV() {
var network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
var gen = network.getGenerator("GEN");
var ngen = network.getBusBreakerView().getBus("NGEN");
var nload = network.getBusBreakerView().getBus("NLOAD");
assertEquals(0, NetworkCache.INSTANCE.getEntryCount());
var result = loadFlowRunner.run(network, parameters);
assertEquals(1, NetworkCache.INSTANCE.getEntryCount());
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(4, result.getComponentResults().get(0).getIterationCount());
assertVoltageEquals(24.5, ngen);
assertVoltageEquals(147.578, nload);
gen.setTargetV(24.1);
result = loadFlowRunner.run(network, parameters);
assertEquals(1, NetworkCache.INSTANCE.getEntryCount());
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(2, result.getComponentResults().get(0).getIterationCount());
assertVoltageEquals(24.1, ngen);
assertVoltageEquals(144.402, nload);
result = loadFlowRunner.run(network, parameters);
assertEquals(1, NetworkCache.INSTANCE.getEntryCount());
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(0, result.getComponentResults().get(0).getIterationCount());
}
@Test
void testGeneratorTargetP() {
var network = DistributedSlackNetworkFactory.create();
var g1 = network.getGenerator("g1");
var g2 = network.getGenerator("g2");
var g3 = network.getGenerator("g3");
var g4 = network.getGenerator("g4");
// align active power control of the 3 generators to have understandable results
g1.setMaxP(300);
g2.setMaxP(300);
g3.setMaxP(300);
g4.setMaxP(300);
g1.getExtension(ActivePowerControl.class).setDroop(1);
g2.getExtension(ActivePowerControl.class).setDroop(1);
g3.getExtension(ActivePowerControl.class).setDroop(1);
g4.getExtension(ActivePowerControl.class).setDroop(1);
var result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(3, result.getComponentResults().get(0).getIterationCount());
// mismatch 120 -> + 30 each
assertActivePowerEquals(-130.0, g1.getTerminal()); // 100 -> 130
assertActivePowerEquals(-230.0, g2.getTerminal()); // 200 -> 230
assertActivePowerEquals(-120.0, g3.getTerminal()); // 90 -> 120
assertActivePowerEquals(-120.0, g4.getTerminal()); // 90 -> 120
g1.setTargetP(120); // 100 -> 120
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(2, result.getComponentResults().get(0).getIterationCount());
// mismatch 100 -> + 25 each
assertActivePowerEquals(-145.0, g1.getTerminal()); // 120 -> 125
assertActivePowerEquals(-225.0, g2.getTerminal()); // 220 -> 225
assertActivePowerEquals(-115.0, g3.getTerminal()); // 90 -> 115
assertActivePowerEquals(-115.0, g4.getTerminal()); // 90 -> 115
// check that if target_p > map_p the generator is discarded from active power control
g1.setTargetP(310);
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(2, result.getComponentResults().get(0).getIterationCount());
// mismatch 90 -> + 60 each
assertActivePowerEquals(-310.0, g1.getTerminal()); // unchanged
assertActivePowerEquals(-170.0, g2.getTerminal()); // 200 -> 170
assertActivePowerEquals(-60.0, g3.getTerminal()); // 90 -> 60
assertActivePowerEquals(-60.0, g4.getTerminal()); // 90 -> 60
}
@Test
void testBatteryTargetP() {
var network = DistributedSlackNetworkFactory.createWithBattery();
var b1 = network.getBattery("bat1");
var b2 = network.getBattery("bat2");
var result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(3, result.getComponentResults().get(0).getIterationCount());
assertActivePowerEquals(-2.0, b1.getTerminal());
assertActivePowerEquals(2.983, b2.getTerminal());
b1.setTargetP(4);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(2, result.getComponentResults().get(0).getIterationCount());
assertActivePowerEquals(-4.0, b1.getTerminal());
assertActivePowerEquals(3.016, b2.getTerminal());
}
@Test
void testParameterChange() {
var network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
assertEquals(0, NetworkCache.INSTANCE.getEntryCount());
loadFlowRunner.run(network, parameters);
assertEquals(1, NetworkCache.INSTANCE.getEntryCount());
NetworkCache.Entry entry = NetworkCache.INSTANCE.findEntry(network).orElseThrow();
loadFlowRunner.run(network, parameters);
assertEquals(1, NetworkCache.INSTANCE.getEntryCount());
NetworkCache.Entry entry2 = NetworkCache.INSTANCE.findEntry(network).orElseThrow();
assertSame(entry, entry2); // reuse same cache
// run with different parameters
parameters.setBalanceType(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD);
loadFlowRunner.run(network, parameters);
assertEquals(1, NetworkCache.INSTANCE.getEntryCount());
NetworkCache.Entry entry3 = NetworkCache.INSTANCE.findEntry(network).orElseThrow();
assertNotSame(entry, entry3); // cache has been evicted and recreated
}
@Test
@Disabled("Disabled by default because not reliable, depends on JVM, garbage collector, and machine performance")
void testCacheEvictionBusBreaker() {
int runCount = 10;
for (int i = 0; i < runCount; i++) {
var network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
loadFlowRunner.run(network, parameters);
System.gc();
}
assertTrue(NetworkCache.INSTANCE.getEntryCount() < runCount);
}
@Test
@Disabled("Disabled by default because not reliable, depends on JVM, garbage collector, and machine performance")
void testCacheEvictionNodeBreaker() {
int runCount = 10;
parametersExt.setActionableSwitchesIds(Set.of("S1VL1_LD1_BREAKER"));
for (int i = 0; i < runCount; i++) {
var network = FourSubstationsNodeBreakerFactory.create();
loadFlowRunner.run(network, parameters);
System.gc();
}
assertTrue(NetworkCache.INSTANCE.getEntryCount() < runCount);
}
@Test
void testEntryEviction() {
var network = FourSubstationsNodeBreakerFactory.create();
assertEquals(1, network.getVariantManager().getVariantIds().size());
parametersExt.setActionableSwitchesIds(Set.of("S1VL1_LD1_BREAKER"));
loadFlowRunner.run(network, parameters);
assertEquals(2, network.getVariantManager().getVariantIds().size());
parametersExt.setActionableSwitchesIds(Set.of("S1VL1_TWT_BREAKER"));
loadFlowRunner.run(network, parameters);
assertEquals(2, network.getVariantManager().getVariantIds().size());
}
@Test
void testUnsupportedAttributeChange() {
var network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
var gen = network.getGenerator("GEN");
loadFlowRunner.run(network, parameters);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
gen.setTargetQ(10);
assertNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
}
@Test
void testPropertiesChange() {
var network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
var gen = network.getGenerator("GEN");
loadFlowRunner.run(network, parameters);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
gen.setProperty("foo", "bar");
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
gen.setProperty("foo", "baz");
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
gen.removeProperty("foo");
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
}
@Test
void testVariantChange() {
var network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
loadFlowRunner.run(network, parameters);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
network.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, "v");
assertNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
loadFlowRunner.run(network, parameters);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
network.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, "v", true);
assertNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
loadFlowRunner.run(network, parameters);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
network.getVariantManager().removeVariant("v");
assertNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
}
@Test
void testLoadAddition() {
var network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
loadFlowRunner.run(network, parameters);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
network.getVoltageLevel("VLLOAD").newLoad()
.setId("NEWLOAD")
.setConnectableBus("NLOAD")
.setBus("NLOAD")
.setP0(10)
.setQ0(10)
.add();
assertNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
}
@Test
void testLoadRemoval() {
var network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
loadFlowRunner.run(network, parameters);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
network.getLoad("LOAD").remove();
assertNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
}
@Test
void testShunt() {
var network = ShuntNetworkFactory.create();
var shunt = network.getShuntCompensator("SHUNT");
assertTrue(NetworkCache.INSTANCE.findEntry(network).isEmpty());
loadFlowRunner.run(network, parameters);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
assertActivePowerEquals(0, shunt.getTerminal());
assertReactivePowerEquals(0, shunt.getTerminal());
shunt.setSectionCount(1);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // cache has not been invalidated but updated
loadFlowRunner.run(network, parameters);
assertActivePowerEquals(0, shunt.getTerminal());
assertReactivePowerEquals(-152.826, shunt.getTerminal());
}
@Test
void testShunt2() {
var network = ShuntNetworkFactory.create();
var shunt = network.getShuntCompensator("SHUNT");
assertTrue(NetworkCache.INSTANCE.findEntry(network).isEmpty());
loadFlowRunner.run(network, parameters); // Run a first LF before changing a parameter.
parameters.setShuntCompensatorVoltageControlOn(true);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
loadFlowRunner.run(network, parameters);
assertActivePowerEquals(0, shunt.getTerminal());
assertReactivePowerEquals(-152.826, shunt.getTerminal());
assertEquals(1, shunt.getSectionCount());
shunt.setSectionCount(0);
assertNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // cache has been invalidated
}
@Test
void testShunt3() {
var network = ShuntNetworkFactory.createWithTwoShuntCompensators();
var shunt = network.getShuntCompensator("SHUNT"); // with voltage control capabilities.
assertTrue(NetworkCache.INSTANCE.findEntry(network).isEmpty());
loadFlowRunner.run(network, parameters);
parameters.setShuntCompensatorVoltageControlOn(true);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
loadFlowRunner.run(network, parameters);
assertActivePowerEquals(0, shunt.getTerminal());
assertReactivePowerEquals(-152.826, shunt.getTerminal());
assertEquals(1, shunt.getSectionCount());
shunt.setSectionCount(1);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
}
@Test
void testSwitchOpen() {
var network = NodeBreakerNetworkFactory.create();
var l1 = network.getLine("L1");
var l2 = network.getLine("L2");
parametersExt.setActionableSwitchesIds(Set.of("C"));
assertTrue(NetworkCache.INSTANCE.findEntry(network).isEmpty());
var result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(3, result.getComponentResults().get(0).getIterationCount());
assertActivePowerEquals(301.884, l1.getTerminal1());
assertActivePowerEquals(301.884, l2.getTerminal1());
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
network.getSwitch("C").setOpen(true);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(4, result.getComponentResults().get(0).getIterationCount());
assertActivePowerEquals(0.0993, l1.getTerminal1());
assertActivePowerEquals(607.682, l2.getTerminal1());
}
@Test
void testSwitchClose() {
var network = NodeBreakerNetworkFactory.create();
var l1 = network.getLine("L1");
var l2 = network.getLine("L2");
parametersExt.setActionableSwitchesIds(Set.of("C"));
var c = network.getSwitch("C");
c.setOpen(true);
assertTrue(NetworkCache.INSTANCE.findEntry(network).isEmpty());
var result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(4, result.getComponentResults().get(0).getIterationCount());
assertActivePowerEquals(0.0994, l1.getTerminal1());
assertActivePowerEquals(607.681, l2.getTerminal1());
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
network.getSwitch("C").setOpen(false);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(4, result.getComponentResults().get(0).getIterationCount());
assertActivePowerEquals(301.884, l1.getTerminal1());
assertActivePowerEquals(301.884, l2.getTerminal1());
}
@Test
void testInvalidNetwork() {
var network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
var result = loadFlowRunner.run(network, parameters);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
var gen = network.getGenerator("GEN");
gen.setTargetV(1000);
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.NO_CALCULATION, result.getComponentResults().get(0).getStatus());
}
@Test
@Disabled("To support later")
void testInitiallyInvalidNetwork() {
var network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
var gen = network.getGenerator("GEN");
gen.setTargetV(1000);
var result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.FAILED, result.getComponentResults().get(0).getStatus());
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
gen.setTargetV(24);
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
}
@Test
void testSwitchIssueWithInit() {
var network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
var vlload = network.getVoltageLevel("VLLOAD");
vlload.getBusBreakerView().newBus()
.setId("NLOAD2")
.add();
var br = vlload.getBusBreakerView().newSwitch()
.setId("BR")
.setBus1("NLOAD")
.setBus2("NLOAD2")
.setOpen(true)
.add();
vlload.newLoad()
.setId("LOAD2")
.setBus("NLOAD2")
.setP0(5)
.setQ0(5)
.add();
parametersExt.setActionableSwitchesIds(Set.of("BR"));
assertTrue(NetworkCache.INSTANCE.findEntry(network).isEmpty());
var result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(4, result.getComponentResults().get(0).getIterationCount());
br.setOpen(false);
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(3, result.getComponentResults().get(0).getIterationCount());
br.setOpen(true);
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(1, result.getComponentResults().get(0).getIterationCount());
}
private static void checkVoltageIsDefinedForAllBuses(Network network) {
for (Bus bus : network.getBusView().getBuses()) {
assertFalse(Double.isNaN(bus.getV()));
assertFalse(Double.isNaN(bus.getAngle()));
}
}
@Test
void testUpdateNetworkFix() {
var network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
var result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
checkVoltageIsDefinedForAllBuses(network);
}
@Test
void testUpdateWithMultipleSynchronousComponents() {
Network network = HvdcNetworkFactory.createVsc();
var result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
checkVoltageIsDefinedForAllBuses(network);
var g1 = network.getGenerator("g1");
g1.setTargetV(g1.getTargetV() + 0.1);
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
checkVoltageIsDefinedForAllBuses(network);
}
@Test
void fixCacheInvalidationWhenUpdatingTapPosition() {
Network network = VoltageControlNetworkFactory.createNetworkWithT2wt();
var t2wt = network.getTwoWindingsTransformer("T2wT");
t2wt.getRatioTapChanger()
.setTargetDeadband(0)
.setRegulating(true)
.setTapPosition(0)
.setRegulationTerminal(t2wt.getTerminal2())
.setTargetV(34.0);
parameters.setTransformerVoltageControlOn(true);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
}
@Test
void testSecondaryVoltageControl() {
parametersExt.setSecondaryVoltageControl(true);
var network = IeeeCdfNetworkFactory.create14();
network.newExtension(SecondaryVoltageControlAdder.class)
.newControlZone()
.withName("z1")
.newPilotPoint()
.withTargetV(12.7)
.withBusbarSectionsOrBusesIds(List.of("B10"))
.add()
.newControlUnit()
.withId("B6-G")
.add()
.newControlUnit()
.withId("B8-G")
.add()
.add()
.add();
SecondaryVoltageControl control = network.getExtension(SecondaryVoltageControl.class);
ControlZone z1 = control.getControlZone("z1").orElseThrow();
PilotPoint pilotPoint = z1.getPilotPoint();
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(5, result.getComponentResults().get(0).getIterationCount());
var b10 = network.getBusBreakerView().getBus("B10");
assertVoltageEquals(12.7, b10);
assertReactivePowerEquals(-17.826, network.getGenerator("B6-G").getTerminal());
assertReactivePowerEquals(-17.827, network.getGenerator("B8-G").getTerminal());
// update pilot point target voltage
pilotPoint.setTargetV(12.5);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(3, result.getComponentResults().get(0).getIterationCount());
assertVoltageEquals(12.5, b10);
assertReactivePowerEquals(-11.832, network.getGenerator("B6-G").getTerminal());
assertReactivePowerEquals(-11.832, network.getGenerator("B8-G").getTerminal());
ControlUnit b6g = z1.getControlUnit("B6-G").orElseThrow();
b6g.setParticipate(false);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(1, result.getComponentResults().get(0).getIterationCount());
// there is no re-run of secondary voltage control outer loop, this is expected as pilot point has already reached
// its target voltage and remaining control unit is necessarily aligned.
assertVoltageEquals(12.5, b10);
assertReactivePowerEquals(-11.832, network.getGenerator("B6-G").getTerminal());
assertReactivePowerEquals(-11.832, network.getGenerator("B8-G").getTerminal());
pilotPoint.setTargetV(12.7);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(4, result.getComponentResults().get(0).getIterationCount());
assertVoltageEquals(12.613, b10); // we cannot reach back to 12.7 Kv with only one control unit
assertReactivePowerEquals(-6.771, network.getGenerator("B6-G").getTerminal());
assertReactivePowerEquals(-24.0, network.getGenerator("B8-G").getTerminal());
// get b6 generator back
b6g.setParticipate(true);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
result = loadFlowRunner.run(network, parameters);
assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, result.getComponentResults().get(0).getStatus());
assertEquals(3, result.getComponentResults().get(0).getIterationCount());
assertVoltageEquals(12.7, b10); // we can reach now 12.7 Kv with the 2 control units
assertReactivePowerEquals(-17.822, network.getGenerator("B6-G").getTerminal());
assertReactivePowerEquals(-17.83, network.getGenerator("B8-G").getTerminal());
}
@Test
void testTransfo2VoltageTargetChange() {
var network = VoltageControlNetworkFactory.createNetworkWithT2wt();
var twt = network.getTwoWindingsTransformer("T2wT");
parameters.setTransformerVoltageControlOn(true);
twt.getRatioTapChanger()
.setTargetDeadband(0)
.setRegulating(true)
.setTapPosition(0)
.setRegulationTerminal(twt.getTerminal2())
.setTargetV(30.0);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertEquals(1, twt.getRatioTapChanger().getTapPosition());
twt.getRatioTapChanger().setTargetV(32);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertEquals(2, twt.getRatioTapChanger().getTapPosition());
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
}
@Test
void testTransfo3VoltageTargetChange() {
var network = VoltageControlNetworkFactory.createNetworkWithT3wt();
var twt = network.getThreeWindingsTransformer("T3wT");
twt.getLeg2().getRatioTapChanger()
.setTargetDeadband(0)
.setRegulating(true)
.setTapPosition(0)
.setRegulationTerminal(twt.getLeg2().getTerminal())
.setTargetV(30);
parameters.setTransformerVoltageControlOn(true);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertEquals(1, twt.getLeg2().getRatioTapChanger().getTapPosition());
twt.getLeg2().getRatioTapChanger().setTargetV(26);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertEquals(2, twt.getLeg2().getRatioTapChanger().getTapPosition());
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
}
@Test
void testTransfo2TapPositionChange() {
var network = VoltageControlNetworkFactory.createNetworkWithT2wt();
var twt = network.getTwoWindingsTransformer("T2wT");
assertEquals(0, twt.getRatioTapChanger().getTapPosition());
parametersExt.setActionableTransformersIds(Set.of("T2wT"));
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
twt.getRatioTapChanger().setTapPosition(1);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertEquals(4, result.getComponentResults().get(0).getIterationCount());
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
}
@Test
void testTransfo3TapPositionChange() {
var network = VoltageControlNetworkFactory.createNetworkWithT3wt();
var twt = network.getThreeWindingsTransformer("T3wT");
assertEquals(0, twt.getLeg2().getRatioTapChanger().getTapPosition());
parametersExt.setActionableTransformersIds(Set.of("T3wT"));
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
twt.getLeg2().getRatioTapChanger().setTapPosition(1);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertEquals(3, result.getComponentResults().get(0).getIterationCount());
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
}
@Test
void testCacheInvalidationIssueWhenChangeNotInSameComponent() {
var network = EurostagTutorialExample1Factory.create();
var gen = network.getGenerator("GEN");
var vlgen = network.getVoltageLevel("VLGEN");
vlgen.getBusBreakerView().newBus()
.setId("NEW_BUS")
.add();
var newGen = vlgen.newGenerator()
.setId("NEW_GEN")
.setBus("NEW_BUS")
.setTargetP(10)
.setVoltageRegulatorOn(true)
.setTargetV(24)
.setMinP(0)
.setMaxP(1000)
.add();
assertTrue(NetworkCache.INSTANCE.findEntry(network).isEmpty());
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts());
gen.setTargetV(gen.getTargetV() + 0.1);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
newGen.setTargetV(newGen.getTargetV() + 0.1);
assertNotNull(NetworkCache.INSTANCE.findEntry(network).orElseThrow().getContexts()); // check cache has not been invalidated
}
}