diff --git a/src/main/java/com/powsybl/openloadflow/network/BusState.java b/src/main/java/com/powsybl/openloadflow/network/BusState.java index 751d064cb4..867f1f7c03 100644 --- a/src/main/java/com/powsybl/openloadflow/network/BusState.java +++ b/src/main/java/com/powsybl/openloadflow/network/BusState.java @@ -24,6 +24,7 @@ public class BusState extends BusDcState { private final double shuntG; private final double controllerShuntB; private final double controllerShuntG; + private final double svcShuntB; private final Map generatorsControlType; public BusState(LfBus bus) { @@ -40,6 +41,8 @@ public BusState(LfBus bus) { LfShunt shunt = bus.getShunt().orElse(null); shuntB = shunt != null ? shunt.getB() : Double.NaN; shuntG = shunt != null ? shunt.getG() : Double.NaN; + LfShunt svcShunt = bus.getSvcShunt().orElse(null); + svcShuntB = svcShunt != null ? svcShunt.getB() : Double.NaN; this.generatorsControlType = bus.getGenerators().stream().collect(Collectors.toMap(LfGenerator::getId, LfGenerator::getGeneratorControlType)); } @@ -66,6 +69,9 @@ public void restore() { if (!Double.isNaN(shuntG)) { element.getShunt().orElseThrow().setG(shuntG); } + if (!Double.isNaN(svcShuntB)) { + element.getSvcShunt().orElseThrow().setB(svcShuntB); + } element.getGenerators().forEach(g -> g.setGeneratorControlType(generatorsControlType.get(g.getId()))); } diff --git a/src/main/java/com/powsybl/openloadflow/network/LfContingency.java b/src/main/java/com/powsybl/openloadflow/network/LfContingency.java index fee69af920..7c09da5ada 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfContingency.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfContingency.java @@ -176,6 +176,13 @@ public void apply(LoadFlowParameters.BalanceType balanceType) { } else { bus.setGenerationTargetQ(bus.getGenerationTargetQ() - generator.getTargetQ()); } + if (generator instanceof LfStaticVarCompensator) { + ((LfStaticVarCompensator) generator).getStandByAutomatonShunt().ifPresent(svcShunt -> { + // it means that the generator in contingency is a static var compensator with an active stand by automaton shunt + shuntsShift.put(svcShunt, new AdmittanceShift(0, svcShunt.getB())); + svcShunt.setB(0); + }); + } } for (LfBus bus : generatorBuses) { if (bus.getGenerators().stream().noneMatch(gen -> gen.getGeneratorControlType() == LfGenerator.GeneratorControlType.VOLTAGE)) { diff --git a/src/main/java/com/powsybl/openloadflow/network/LfNetwork.java b/src/main/java/com/powsybl/openloadflow/network/LfNetwork.java index e7166ec83d..c05c454634 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfNetwork.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfNetwork.java @@ -230,6 +230,11 @@ public void addBus(LfBus bus) { shuntsByIndex.add(shunt); shunt.getOriginalIds().forEach(id -> shuntsById.put(id, shunt)); }); + bus.getSvcShunt().ifPresent(shunt -> { + shunt.setNum(shuntCount++); + shuntsByIndex.add(shunt); + shunt.getOriginalIds().forEach(id -> shuntsById.put(id, shunt)); + }); bus.getGenerators().forEach(gen -> generatorsById.put(gen.getId(), gen)); } diff --git a/src/main/java/com/powsybl/openloadflow/network/LfStandbyAutomatonShunt.java b/src/main/java/com/powsybl/openloadflow/network/LfStandbyAutomatonShunt.java index 76c5b05d6d..343fcfa394 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfStandbyAutomatonShunt.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfStandbyAutomatonShunt.java @@ -21,7 +21,7 @@ public final class LfStandbyAutomatonShunt extends AbstractLfShunt { private final LfStaticVarCompensator svc; - private final double b; + private double b; private LfStandbyAutomatonShunt(LfStaticVarCompensator svc) { super(svc.getBus().getNetwork()); @@ -56,7 +56,12 @@ public double getB() { @Override public void setB(double b) { - throw createUnsupportedForStandbyAutomatonShuntException(); + if (b != this.b) { + this.b = b; + for (LfNetworkListener listener : getNetwork().getListeners()) { + listener.onShuntSusceptanceChange(this, b); + } + } } private static UnsupportedOperationException createUnsupportedForStandbyAutomatonShuntException() { diff --git a/src/main/java/com/powsybl/openloadflow/network/LfStaticVarCompensator.java b/src/main/java/com/powsybl/openloadflow/network/LfStaticVarCompensator.java index 5969fbe82c..1305f751ed 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfStaticVarCompensator.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfStaticVarCompensator.java @@ -50,4 +50,8 @@ public double getHighVoltageThreshold() { double getB0(); Optional getStandByAutomaton(); + + Optional getStandByAutomatonShunt(); + + void setStandByAutomatonShunt(LfShunt standByAutomatonShunt); } diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java b/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java index 835eb06b26..d75de4e34e 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java @@ -241,6 +241,7 @@ void addStaticVarCompensator(StaticVarCompensator staticVarCompensator, LfNetwor } if (lfSvc.getB0() != 0) { svcShunt = LfStandbyAutomatonShunt.create(lfSvc); + lfSvc.setStandByAutomatonShunt(svcShunt); } } } diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/ContingencyTripping.java b/src/main/java/com/powsybl/openloadflow/network/impl/ContingencyTripping.java index ea20e07006..1f21a58c59 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/ContingencyTripping.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/ContingencyTripping.java @@ -72,6 +72,7 @@ public static ContingencyTripping createContingencyTripping(Network network, Ide case GENERATOR: case LOAD: case SHUNT_COMPENSATOR: + case STATIC_VAR_COMPENSATOR: return ContingencyTripping.createInjectionTripping(network, (Injection) identifiable); case THREE_WINDINGS_TRANSFORMER: return ContingencyTripping.createThreeWindingsTransformerTripping(network, (ThreeWindingsTransformer) identifiable); diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/LfStaticVarCompensatorImpl.java b/src/main/java/com/powsybl/openloadflow/network/impl/LfStaticVarCompensatorImpl.java index 852cd873fa..8f89ff0d0b 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/LfStaticVarCompensatorImpl.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/LfStaticVarCompensatorImpl.java @@ -14,6 +14,7 @@ import com.powsybl.iidm.network.extensions.VoltagePerReactivePowerControl; import com.powsybl.openloadflow.network.LfNetwork; import com.powsybl.openloadflow.network.LfNetworkParameters; +import com.powsybl.openloadflow.network.LfShunt; import com.powsybl.openloadflow.network.LfStaticVarCompensator; import com.powsybl.openloadflow.util.PerUnit; import org.slf4j.Logger; @@ -43,6 +44,8 @@ public final class LfStaticVarCompensatorImpl extends AbstractLfGenerator implem private double b0 = 0.0; + private LfShunt standByAutomatonShunt; + private LfStaticVarCompensatorImpl(StaticVarCompensator svc, LfNetwork network, AbstractLfBus bus, LfNetworkParameters parameters, LfNetworkLoadingReport report) { super(network, 0); @@ -177,4 +180,14 @@ public double getB0() { public Optional getStandByAutomaton() { return Optional.ofNullable(standByAutomaton); } + + @Override + public Optional getStandByAutomatonShunt() { + return Optional.ofNullable(standByAutomatonShunt); + } + + @Override + public void setStandByAutomatonShunt(LfShunt standByAutomatonShunt) { + this.standByAutomatonShunt = standByAutomatonShunt; + } } diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/PropagatedContingency.java b/src/main/java/com/powsybl/openloadflow/network/impl/PropagatedContingency.java index c183505b12..5568ffc65f 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/PropagatedContingency.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/PropagatedContingency.java @@ -15,6 +15,8 @@ import com.powsybl.openloadflow.graph.GraphConnectivity; import com.powsybl.openloadflow.network.*; import com.powsybl.openloadflow.util.PerUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.*; import java.util.stream.Collectors; @@ -25,6 +27,8 @@ */ public class PropagatedContingency { + protected static final Logger LOGGER = LoggerFactory.getLogger(PropagatedContingency.class); + private final Contingency contingency; private final int index; @@ -152,6 +156,7 @@ private void complete(boolean shuntCompensatorVoltageControlOn, boolean slackDis break; case GENERATOR: + case STATIC_VAR_COMPENSATOR: generatorIdsToLose.add(connectable.getId()); break; @@ -167,7 +172,7 @@ private void complete(boolean shuntCompensatorVoltageControlOn, boolean slackDis throw new UnsupportedOperationException("Shunt compensator '" + shunt.getId() + "' with voltage control on: not supported yet"); } double nominalV = shunt.getTerminal().getVoltageLevel().getNominalV(); - shuntIdsToShift.put(shunt.getId(), new AdmittanceShift(-shunt.getG() * nominalV * nominalV / PerUnit.SB, + shuntIdsToShift.put(shunt.getId(), new AdmittanceShift(shunt.getG() * nominalV * nominalV / PerUnit.SB, shunt.getB() * nominalV * nominalV / PerUnit.SB)); break; @@ -248,6 +253,10 @@ private static Identifiable getIdentifiable(Network network, ContingencyEleme identifiable = network.getGenerator(element.getId()); identifiableType = "Generator"; break; + case STATIC_VAR_COMPENSATOR: + identifiable = network.getStaticVarCompensator(element.getId()); + identifiableType = "Static var compensator"; + break; case LOAD: identifiable = network.getLoad(element.getId()); identifiableType = "Load"; @@ -343,6 +352,7 @@ public Optional toLfContingency(LfNetwork network) { && busesLoadShift.isEmpty() && generators.isEmpty() && hvdcs.isEmpty()) { + LOGGER.debug("Contingency '{}' has no impact", contingency.getId()); return Optional.empty(); } diff --git a/src/main/java/com/powsybl/openloadflow/sensi/AbstractSensitivityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sensi/AbstractSensitivityAnalysis.java index 97d5796544..70f350f5ed 100644 --- a/src/main/java/com/powsybl/openloadflow/sensi/AbstractSensitivityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sensi/AbstractSensitivityAnalysis.java @@ -752,7 +752,8 @@ public void checkContingencies(LfNetwork lfNetwork, List if (contingency.getBranchIdsToOpen().isEmpty() && contingency.getHvdcIdsToOpen().isEmpty() && contingency.getGeneratorIdsToLose().isEmpty() - && contingency.getBusIdsToShift().isEmpty()) { + && contingency.getBusIdsToShift().isEmpty() + && contingency.getShuntIdsToShift().isEmpty()) { LOGGER.warn("Contingency '{}' has no impact", contingency.getContingency().getId()); } } diff --git a/src/main/java/com/powsybl/openloadflow/sensi/AcSensitivityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sensi/AcSensitivityAnalysis.java index 9e0a33c396..cbdc920e88 100644 --- a/src/main/java/com/powsybl/openloadflow/sensi/AcSensitivityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sensi/AcSensitivityAnalysis.java @@ -34,7 +34,6 @@ import com.powsybl.sensitivity.SensitivityFactorReader; import com.powsybl.sensitivity.SensitivityResultWriter; import com.powsybl.sensitivity.SensitivityVariableSet; -import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.tuple.Pair; import java.util.*; @@ -143,17 +142,6 @@ private void calculatePostContingencySensitivityValues(List contingencies) { - super.checkContingencies(lfNetwork, contingencies); - - for (PropagatedContingency contingency : contingencies) { - if (!contingency.getShuntIdsToShift().isEmpty()) { - throw new NotImplementedException("Shunt Contingencies are not yet supported in AC mode."); - } - } - } - private static boolean runLoadFlow(AcLoadFlowContext context, boolean throwsExceptionIfNoConvergence) { AcLoadFlowResult result = new AcloadFlowEngine(context) .run(); diff --git a/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowSvcTest.java b/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowSvcTest.java index e21761c43d..4b1d95fa0c 100644 --- a/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowSvcTest.java +++ b/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowSvcTest.java @@ -16,6 +16,7 @@ import com.powsybl.openloadflow.OpenLoadFlowParameters; import com.powsybl.openloadflow.OpenLoadFlowProvider; import com.powsybl.openloadflow.network.SlackBusSelectionMode; +import com.powsybl.openloadflow.network.VoltageControlNetworkFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -46,61 +47,11 @@ class AcLoadFlowSvcTest { private LoadFlowParameters parameters; private Network createNetwork() { - Network network = Network.create("svc", "test"); - Substation s1 = network.newSubstation() - .setId("S1") - .add(); - Substation s2 = network.newSubstation() - .setId("S2") - .add(); - VoltageLevel vl1 = s1.newVoltageLevel() - .setId("vl1") - .setNominalV(400) - .setTopologyKind(TopologyKind.BUS_BREAKER) - .add(); - bus1 = vl1.getBusBreakerView().newBus() - .setId("b1") - .add(); - vl1.newGenerator() - .setId("g1") - .setConnectableBus("b1") - .setBus("b1") - .setTargetP(101.3664) - .setTargetV(390) - .setMinP(0) - .setMaxP(150) - .setVoltageRegulatorOn(true) - .add(); - VoltageLevel vl2 = s2.newVoltageLevel() - .setId("vl2") - .setNominalV(400) - .setTopologyKind(TopologyKind.BUS_BREAKER) - .add(); - bus2 = vl2.getBusBreakerView().newBus() - .setId("b2") - .add(); - vl2.newLoad() - .setId("ld1") - .setConnectableBus("b2") - .setBus("b2") - .setP0(101) - .setQ0(150) - .add(); - svc1 = vl2.newStaticVarCompensator() - .setId("svc1") - .setConnectableBus("b2") - .setBus("b2") - .setRegulationMode(StaticVarCompensator.RegulationMode.OFF) - .setBmin(-0.008) - .setBmax(0.008) - .add(); - l1 = network.newLine() - .setId("l1") - .setBus1("b1") - .setBus2("b2") - .setR(1) - .setX(3) - .add(); + Network network = VoltageControlNetworkFactory.createWithStaticVarCompensator(); + bus1 = network.getBusBreakerView().getBus("b1"); + bus2 = network.getBusBreakerView().getBus("b2"); + svc1 = network.getStaticVarCompensator("svc1"); + l1 = network.getLine("l1"); return network; } diff --git a/src/test/java/com/powsybl/openloadflow/network/LfStandbyAutomatonShuntTest.java b/src/test/java/com/powsybl/openloadflow/network/LfStandbyAutomatonShuntTest.java index 4b8a0b195d..6f56d42231 100644 --- a/src/test/java/com/powsybl/openloadflow/network/LfStandbyAutomatonShuntTest.java +++ b/src/test/java/com/powsybl/openloadflow/network/LfStandbyAutomatonShuntTest.java @@ -39,7 +39,6 @@ void test() { assertFalse(shunt.isVoltageControlEnabled()); assertFalse(shunt.hasVoltageControlCapability()); assertNotNull(assertThrows(UnsupportedOperationException.class, () -> shunt.setG(0))); - assertNotNull(assertThrows(UnsupportedOperationException.class, () -> shunt.setB(0))); assertNotNull(assertThrows(UnsupportedOperationException.class, () -> shunt.setVoltageControl(null))); assertNotNull(assertThrows(UnsupportedOperationException.class, () -> shunt.setVoltageControlCapability(true))); assertNotNull(assertThrows(UnsupportedOperationException.class, () -> shunt.setVoltageControlEnabled(true))); diff --git a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java index 8c9434659c..5e0ff0799d 100644 --- a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java +++ b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java @@ -913,4 +913,72 @@ public static Network createWithShuntSharedRemoteControl() { return network; } + + /** + * SVC test case. + * + * g1 ld1 + * | | + * b1---------b2 + * l1 | + * svc1 + */ + public static Network createWithStaticVarCompensator() { + Network network = Network.create("svc", "test"); + Substation s1 = network.newSubstation() + .setId("S1") + .add(); + Substation s2 = network.newSubstation() + .setId("S2") + .add(); + VoltageLevel vl1 = s1.newVoltageLevel() + .setId("vl1") + .setNominalV(400) + .setTopologyKind(TopologyKind.BUS_BREAKER) + .add(); + vl1.getBusBreakerView().newBus() + .setId("b1") + .add(); + vl1.newGenerator() + .setId("g1") + .setConnectableBus("b1") + .setBus("b1") + .setTargetP(101.3664) + .setTargetV(390) + .setMinP(0) + .setMaxP(150) + .setVoltageRegulatorOn(true) + .add(); + VoltageLevel vl2 = s2.newVoltageLevel() + .setId("vl2") + .setNominalV(400) + .setTopologyKind(TopologyKind.BUS_BREAKER) + .add(); + vl2.getBusBreakerView().newBus() + .setId("b2") + .add(); + vl2.newLoad() + .setId("ld1") + .setConnectableBus("b2") + .setBus("b2") + .setP0(101) + .setQ0(150) + .add(); + vl2.newStaticVarCompensator() + .setId("svc1") + .setConnectableBus("b2") + .setBus("b2") + .setRegulationMode(StaticVarCompensator.RegulationMode.OFF) + .setBmin(-0.008) + .setBmax(0.008) + .add(); + network.newLine() + .setId("l1") + .setBus1("b1") + .setBus2("b2") + .setR(1) + .setX(3) + .add(); + return network; + } } diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java index e684b2ee5c..15c28a869e 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java @@ -16,6 +16,7 @@ import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.extensions.HvdcAngleDroopActivePowerControlAdder; import com.powsybl.iidm.network.extensions.LoadDetailAdder; +import com.powsybl.iidm.network.extensions.StandbyAutomatonAdder; import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; import com.powsybl.iidm.network.test.FourSubstationsNodeBreakerFactory; import com.powsybl.iidm.xml.test.MetrixTutorialSixBusesFactory; @@ -2590,4 +2591,68 @@ void testLineDisconnectedOnOneSideContingency() { assertEquals(260.005, postContingencyResult.getNetworkResult().getBranchResult("l34").getQ1(), LoadFlowAssert.DELTA_POWER); assertEquals(1, result.getPostContingencyResults().size()); } + + @Test + void testStaticVarCompensatorContingency() { + Network network = VoltageControlNetworkFactory.createWithStaticVarCompensator(); + network.getStaticVarCompensator("svc1").setVoltageSetpoint(385).setRegulationMode(StaticVarCompensator.RegulationMode.VOLTAGE); + List monitors = createAllBranchesMonitors(network); + List contingencies = List.of(new Contingency("svc1", new StaticVarCompensatorContingency("svc1"))); + SecurityAnalysisParameters parameters = new SecurityAnalysisParameters(); + + // test AC + SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, parameters, Reporter.NO_OP); + + // compare with a simple load low + network.getStaticVarCompensator("svc1").getTerminal().disconnect(); + LoadFlow.run(network, parameters.getLoadFlowParameters()); + + PostContingencyResult postContingencyResult = getPostContingencyResult(result, "svc1"); + assertEquals(network.getLine("l1").getTerminal1().getP(), postContingencyResult.getNetworkResult().getBranchResult("l1").getP1(), LoadFlowAssert.DELTA_POWER); + assertEquals(network.getLine("l1").getTerminal2().getP(), postContingencyResult.getNetworkResult().getBranchResult("l1").getP2(), LoadFlowAssert.DELTA_POWER); + assertEquals(network.getLine("l1").getTerminal1().getQ(), postContingencyResult.getNetworkResult().getBranchResult("l1").getQ1(), LoadFlowAssert.DELTA_POWER); + assertEquals(network.getLine("l1").getTerminal2().getQ(), postContingencyResult.getNetworkResult().getBranchResult("l1").getQ2(), LoadFlowAssert.DELTA_POWER); + } + + @Test + void testStaticVarCompensatorContingencyWithStandByAutomaton() { + Network network = VoltageControlNetworkFactory.createWithStaticVarCompensator(); + StaticVarCompensator svc1 = network.getStaticVarCompensator("svc1"); + svc1.setVoltageSetpoint(385).setRegulationMode(StaticVarCompensator.RegulationMode.VOLTAGE); + svc1.newExtension(StandbyAutomatonAdder.class) + .withHighVoltageThreshold(400) + .withLowVoltageThreshold(380) + .withLowVoltageSetpoint(385) + .withHighVoltageSetpoint(395) + .withB0(-0.001f) + .withStandbyStatus(true) + .add(); + List monitors = createAllBranchesMonitors(network); + List contingencies = List.of(new Contingency("svc1", new StaticVarCompensatorContingency("svc1")), + new Contingency("ld1", new LoadContingency("ld1"))); + SecurityAnalysisParameters parameters = new SecurityAnalysisParameters(); + + // test AC + SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, parameters, Reporter.NO_OP); + + // compare with a simple load low + network.getStaticVarCompensator("svc1").getTerminal().disconnect(); + LoadFlow.run(network); + + PostContingencyResult postContingencyResult = getPostContingencyResult(result, "svc1"); + assertEquals(network.getLine("l1").getTerminal1().getP(), postContingencyResult.getNetworkResult().getBranchResult("l1").getP1(), LoadFlowAssert.DELTA_POWER); + assertEquals(network.getLine("l1").getTerminal2().getP(), postContingencyResult.getNetworkResult().getBranchResult("l1").getP2(), LoadFlowAssert.DELTA_POWER); + assertEquals(network.getLine("l1").getTerminal1().getQ(), postContingencyResult.getNetworkResult().getBranchResult("l1").getQ1(), LoadFlowAssert.DELTA_POWER); + assertEquals(network.getLine("l1").getTerminal2().getQ(), postContingencyResult.getNetworkResult().getBranchResult("l1").getQ2(), LoadFlowAssert.DELTA_POWER); + + // test restore. + network.getStaticVarCompensator("svc1").getTerminal().connect(); + network.getLoad("ld1").getTerminal().disconnect(); + LoadFlow.run(network); + PostContingencyResult postContingencyResult2 = getPostContingencyResult(result, "ld1"); + assertEquals(network.getLine("l1").getTerminal1().getP(), postContingencyResult2.getNetworkResult().getBranchResult("l1").getP1(), LoadFlowAssert.DELTA_POWER); + assertEquals(network.getLine("l1").getTerminal2().getP(), postContingencyResult2.getNetworkResult().getBranchResult("l1").getP2(), LoadFlowAssert.DELTA_POWER); + assertEquals(network.getLine("l1").getTerminal1().getQ(), postContingencyResult2.getNetworkResult().getBranchResult("l1").getQ1(), LoadFlowAssert.DELTA_POWER); + assertEquals(network.getLine("l1").getTerminal2().getQ(), postContingencyResult2.getNetworkResult().getBranchResult("l1").getQ2(), LoadFlowAssert.DELTA_POWER); + } } diff --git a/src/test/java/com/powsybl/openloadflow/sensi/ac/AcSensitivityAnalysisContingenciesTest.java b/src/test/java/com/powsybl/openloadflow/sensi/ac/AcSensitivityAnalysisContingenciesTest.java index 5493c6602d..589d5f6fa1 100644 --- a/src/test/java/com/powsybl/openloadflow/sensi/ac/AcSensitivityAnalysisContingenciesTest.java +++ b/src/test/java/com/powsybl/openloadflow/sensi/ac/AcSensitivityAnalysisContingenciesTest.java @@ -11,6 +11,7 @@ import com.powsybl.contingency.*; import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.extensions.HvdcAngleDroopActivePowerControlAdder; +import com.powsybl.iidm.network.extensions.StandbyAutomatonAdder; import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.openloadflow.OpenLoadFlowParameters; @@ -1194,7 +1195,7 @@ void testPredefinedResults4() { } @Test - void testRestoreAfterContingencyOnHvdc() { + void testRestoContingencyOnHvdc() { Network network = HvdcNetworkFactory.createWithHvdcInAcEmulation(); network.getGeneratorStream().forEach(gen -> gen.setMaxP(2 * gen.getMaxP())); network.getHvdcLine("hvdc34").newExtension(HvdcAngleDroopActivePowerControlAdder.class) @@ -1210,7 +1211,7 @@ void testRestoreAfterContingencyOnHvdc() { Stream.of("l12", "l25", "l56").map(network::getBranch).collect(Collectors.toList())); List contingencies = List.of(new Contingency("hvdc34", new HvdcLineContingency("hvdc34")), - new Contingency("l45", new BranchContingency("l45"))); + new Contingency("l45", new BranchContingency("l45"))); SensitivityAnalysisResult result = sensiRunner.run(network, factors, contingencies, Collections.emptyList(), sensiParameters); @@ -1218,4 +1219,51 @@ void testRestoreAfterContingencyOnHvdc() { assertEquals(0.356, result.getBranchFlow1SensitivityValue("l45", "g1", "l25", SensitivityVariableType.INJECTION_ACTIVE_POWER), LoadFlowAssert.DELTA_POWER); assertEquals(-0.144, result.getBranchFlow1SensitivityValue("l45", "g1", "l56", SensitivityVariableType.INJECTION_ACTIVE_POWER), LoadFlowAssert.DELTA_POWER); } + + @Test + void testStaticVarCompensatorContingency() { + Network network = VoltageControlNetworkFactory.createWithStaticVarCompensator(); + network.getStaticVarCompensator("svc1").setVoltageSetpoint(385).setRegulationMode(StaticVarCompensator.RegulationMode.VOLTAGE); + List contingencies = List.of(new Contingency("svc1", new StaticVarCompensatorContingency("svc1"))); + SensitivityAnalysisParameters parameters = new SensitivityAnalysisParameters(); + List factors = List.of(createBusVoltagePerTargetV("b2", "g1"), createBusVoltagePerTargetV("b2", "g1", "svc1")); + SensitivityAnalysisResult result = sensiRunner.run(network, factors, contingencies, Collections.emptyList(), parameters); + assertEquals(385.0, result.getBusVoltageFunctionReferenceValue("b2"), LoadFlowAssert.DELTA_V); + assertEquals(388.582, result.getBusVoltageFunctionReferenceValue("svc1", "b2"), LoadFlowAssert.DELTA_V); + } + + @Test + void testSaWithShuntContingency() { + Network network = VoltageControlNetworkFactory.createWithShuntSharedRemoteControl(); + network.getShuntCompensatorStream().forEach(shuntCompensator -> { + shuntCompensator.setSectionCount(10).setVoltageRegulatorOn(false); + }); + List contingencies = List.of(new Contingency("SHUNT2", new ShuntCompensatorContingency("SHUNT2"))); + SensitivityAnalysisParameters parameters = new SensitivityAnalysisParameters(); + List factors = List.of(createBusVoltagePerTargetV("b4", "g1"), createBusVoltagePerTargetV("b4", "g1", "SHUNT2")); + SensitivityAnalysisResult result = sensiRunner.run(network, factors, contingencies, Collections.emptyList(), parameters); + assertEquals(402.101, result.getBusVoltageFunctionReferenceValue("b4"), LoadFlowAssert.DELTA_V); + assertEquals(404.793, result.getBusVoltageFunctionReferenceValue("SHUNT2", "b4"), LoadFlowAssert.DELTA_V); + } + + @Test + void testStaticVarCompensatorContingency2() { + Network network = VoltageControlNetworkFactory.createWithStaticVarCompensator(); + StaticVarCompensator svc1 = network.getStaticVarCompensator("svc1"); + svc1.setVoltageSetpoint(385).setRegulationMode(StaticVarCompensator.RegulationMode.VOLTAGE); + svc1.newExtension(StandbyAutomatonAdder.class) + .withHighVoltageThreshold(400) + .withLowVoltageThreshold(380) + .withLowVoltageSetpoint(385) + .withHighVoltageSetpoint(395) + .withB0(-0.001f) + .withStandbyStatus(true) + .add(); + List contingencies = List.of(new Contingency("svc1", new StaticVarCompensatorContingency("svc1"))); + SensitivityAnalysisParameters parameters = new SensitivityAnalysisParameters(); + List factors = List.of(createBusVoltagePerTargetV("b2", "g1"), createBusVoltagePerTargetV("b2", "g1", "svc1")); + SensitivityAnalysisResult result = sensiRunner.run(network, factors, contingencies, Collections.emptyList(), parameters); + assertEquals(387.415, result.getBusVoltageFunctionReferenceValue("b2"), LoadFlowAssert.DELTA_V); + assertEquals(388.582, result.getBusVoltageFunctionReferenceValue("svc1", "b2"), LoadFlowAssert.DELTA_V); + } }