WoodburyDcSecurityAnalysisWithActionsTest.java
/**
* Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/)
* 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.sa;
import com.powsybl.action.*;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.contingency.*;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.PhaseTapChanger;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.network.NodeBreakerNetworkFactory;
import com.powsybl.openloadflow.network.PhaseControlFactory;
import com.powsybl.openloadflow.network.SlackBusSelectionMode;
import com.powsybl.openloadflow.network.VoltageControlNetworkFactory;
import com.powsybl.openloadflow.util.LoadFlowAssert;
import com.powsybl.security.SecurityAnalysisParameters;
import com.powsybl.security.SecurityAnalysisResult;
import com.powsybl.security.condition.TrueCondition;
import com.powsybl.security.monitor.StateMonitor;
import com.powsybl.security.results.BranchResult;
import com.powsybl.security.results.OperatorStrategyResult;
import com.powsybl.security.strategy.OperatorStrategy;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import java.util.List;
import java.util.concurrent.CompletionException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.powsybl.openloadflow.util.LoadFlowAssert.DELTA_POWER;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author Pierre Arvy {@literal <pierre.arvy at artelys.com>}
*/
class WoodburyDcSecurityAnalysisWithActionsTest extends AbstractOpenSecurityAnalysisTest {
private LoadFlowParameters parameters;
private SecurityAnalysisParameters securityAnalysisParameters;
@BeforeEach
public void setUpWoodburyDcSa() {
securityAnalysisParameters = new SecurityAnalysisParameters();
// configure sa to use Woodbury dc sa
parameters = new LoadFlowParameters();
parameters.setDc(true);
securityAnalysisParameters.setLoadFlowParameters(parameters);
OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters();
openSecurityAnalysisParameters.setDcFastMode(true);
securityAnalysisParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testFastSaDcPhaseTapChangerTapPositionChangeAdmittanceOnlyAlphaNull(boolean dcFastMode) {
Network network = PhaseControlFactory.createWithOneT2wtTwoLines();
// no alpha modification with pst actions
network.getTwoWindingsTransformer("PS1")
.getPhaseTapChanger()
.getStep(0)
.setAlpha(0);
List<StateMonitor> monitors = createAllBranchesMonitors(network);
List<Contingency> contingencies = List.of(new Contingency("L1", new BranchContingency("L1")));
List<Action> actions = List.of(new PhaseTapChangerTapPositionAction("pstAbsChange", "PS1", false, 0),
new PhaseTapChangerTapPositionAction("pstRelChange", "PS1", true, -1));
List<OperatorStrategy> operatorStrategies = List.of(
new OperatorStrategy("strategyTapAbsChange", ContingencyContext.specificContingency("L1"), new TrueCondition(), List.of("pstAbsChange")),
new OperatorStrategy("strategyTapRelChange", ContingencyContext.specificContingency("L1"), new TrueCondition(), List.of("pstRelChange")));
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
assertNotNull(result);
OperatorStrategyResult resultAbs = getOperatorStrategyResult(result, "strategyTapAbsChange");
BranchResult brAbsL2 = resultAbs.getNetworkResult().getBranchResult("L2");
BranchResult brAbsPS1 = resultAbs.getNetworkResult().getBranchResult("PS1");
OperatorStrategyResult resultRel = getOperatorStrategyResult(result, "strategyTapRelChange");
BranchResult brRelL2 = resultRel.getNetworkResult().getBranchResult("L2");
BranchResult brRelPS1 = resultRel.getNetworkResult().getBranchResult("PS1");
// Apply contingency by hand
network.getLine("L1").getTerminal1().disconnect();
network.getLine("L1").getTerminal2().disconnect();
// Apply remedial action
network.getTwoWindingsTransformer("PS1").getPhaseTapChanger().setTapPosition(0);
loadFlowRunner.run(network, parameters);
// Compare results on the line L2
assertEquals(network.getLine("L2").getTerminal1().getP(), brAbsL2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal2().getP(), brAbsL2.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal1().getP(), brRelL2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal2().getP(), brRelL2.getP2(), LoadFlowAssert.DELTA_POWER);
// Compare results on the t2wt PS1
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal1().getP(), brAbsPS1.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal2().getP(), brAbsPS1.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal1().getP(), brRelPS1.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal2().getP(), brRelPS1.getP2(), LoadFlowAssert.DELTA_POWER);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testFastSaDcPhaseTapChangerTapPositionChangeAdmittanceOnlyAlphaNonNull(boolean dcFastMode) {
Network network = PhaseControlFactory.createWithOneT2wtTwoLines();
// no alpha modification with pst actions
network.getTwoWindingsTransformer("PS1")
.getPhaseTapChanger()
.getStep(1)
.setAlpha(-5);
List<StateMonitor> monitors = createAllBranchesMonitors(network);
List<Contingency> contingencies = List.of(new Contingency("L1", new BranchContingency("L1")));
List<Action> actions = List.of(new PhaseTapChangerTapPositionAction("pstAbsChange", "PS1", false, 0),
new PhaseTapChangerTapPositionAction("pstRelChange", "PS1", true, -1));
List<OperatorStrategy> operatorStrategies = List.of(
new OperatorStrategy("strategyTapAbsChange", ContingencyContext.specificContingency("L1"), new TrueCondition(), List.of("pstAbsChange")),
new OperatorStrategy("strategyTapRelChange", ContingencyContext.specificContingency("L1"), new TrueCondition(), List.of("pstRelChange")));
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
assertNotNull(result);
OperatorStrategyResult resultAbs = getOperatorStrategyResult(result, "strategyTapAbsChange");
BranchResult brAbsL2 = resultAbs.getNetworkResult().getBranchResult("L2");
BranchResult brAbsPS1 = resultAbs.getNetworkResult().getBranchResult("PS1");
OperatorStrategyResult resultRel = getOperatorStrategyResult(result, "strategyTapRelChange");
BranchResult brRelL2 = resultRel.getNetworkResult().getBranchResult("L2");
BranchResult brRelPS1 = resultRel.getNetworkResult().getBranchResult("PS1");
// Apply contingency by hand
network.getLine("L1").getTerminal1().disconnect();
network.getLine("L1").getTerminal2().disconnect();
// Apply remedial action
network.getTwoWindingsTransformer("PS1").getPhaseTapChanger().setTapPosition(0);
loadFlowRunner.run(network, parameters);
// Compare results on the line L2
assertEquals(network.getLine("L2").getTerminal1().getP(), brAbsL2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal2().getP(), brAbsL2.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal1().getP(), brRelL2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal2().getP(), brRelL2.getP2(), LoadFlowAssert.DELTA_POWER);
// Compare results on the t2wt PS1
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal1().getP(), brAbsPS1.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal2().getP(), brAbsPS1.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal1().getP(), brRelPS1.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal2().getP(), brRelPS1.getP2(), LoadFlowAssert.DELTA_POWER);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testSaDcPhaseTapChangerTapPositionChangeAlphaOnly(boolean dcFastMode) {
Network network = PhaseControlFactory.createWithOneT2wtTwoLines();
network.getTwoWindingsTransformer("PS1")
.getPhaseTapChanger()
.getStep(0)
.setX(100);
List<StateMonitor> monitors = createAllBranchesMonitors(network);
List<Contingency> contingencies = List.of(new Contingency("L1", new BranchContingency("L1")));
List<Action> actions = List.of(new PhaseTapChangerTapPositionAction("pstAbsChange", "PS1", false, 0),
new PhaseTapChangerTapPositionAction("pstRelChange", "PS1", true, -1));
List<OperatorStrategy> operatorStrategies = List.of(
new OperatorStrategy("strategyTapAbsChange", ContingencyContext.specificContingency("L1"), new TrueCondition(), List.of("pstAbsChange")),
new OperatorStrategy("strategyTapRelChange", ContingencyContext.specificContingency("L1"), new TrueCondition(), List.of("pstRelChange")));
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
assertNotNull(result);
OperatorStrategyResult resultAbs = getOperatorStrategyResult(result, "strategyTapAbsChange");
BranchResult brAbsL2 = resultAbs.getNetworkResult().getBranchResult("L2");
BranchResult brAbsPS1 = resultAbs.getNetworkResult().getBranchResult("PS1");
OperatorStrategyResult resultRel = getOperatorStrategyResult(result, "strategyTapRelChange");
BranchResult brRelL2 = resultRel.getNetworkResult().getBranchResult("L2");
BranchResult brRelPS1 = resultRel.getNetworkResult().getBranchResult("PS1");
// Apply contingency by hand
network.getLine("L1").getTerminal1().disconnect();
network.getLine("L1").getTerminal2().disconnect();
// Apply remedial action
network.getTwoWindingsTransformer("PS1").getPhaseTapChanger().setTapPosition(0);
loadFlowRunner.run(network, parameters);
// Compare results on the line L2
assertEquals(network.getLine("L2").getTerminal1().getP(), brAbsL2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal2().getP(), brAbsL2.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal1().getP(), brRelL2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal2().getP(), brRelL2.getP2(), LoadFlowAssert.DELTA_POWER);
// Compare results on the t2wt PS1
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal1().getP(), brAbsPS1.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal2().getP(), brAbsPS1.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal1().getP(), brRelPS1.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal2().getP(), brRelPS1.getP2(), LoadFlowAssert.DELTA_POWER);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testSaDcPhaseTapChangerTapPositionChangeWithConnectivityBreak(boolean fastDcMode) {
Network network = PhaseControlFactory.createNetworkWith3Buses();
List<StateMonitor> monitors = createAllBranchesMonitors(network);
List<Contingency> contingencies = List.of(new Contingency("L23", new BranchContingency("L23")));
List<Action> actions = List.of(new PhaseTapChangerTapPositionAction("pstAbsChange", "PS1", false, 0),
new PhaseTapChangerTapPositionAction("pstRelChange", "PS1", true, -1));
List<OperatorStrategy> operatorStrategies = List.of(
new OperatorStrategy("strategyTapAbsChange", ContingencyContext.specificContingency("L23"), new TrueCondition(), List.of("pstAbsChange")),
new OperatorStrategy("strategyTapRelChange", ContingencyContext.specificContingency("L23"), new TrueCondition(), List.of("pstRelChange")));
OpenLoadFlowParameters.create(parameters)
.setSlackBusId("VL2_0")
.setSlackBusSelectionMode(SlackBusSelectionMode.NAME);
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(fastDcMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
assertNotNull(result);
OperatorStrategyResult resultAbs = getOperatorStrategyResult(result, "strategyTapAbsChange");
BranchResult brAbsPS1 = resultAbs.getNetworkResult().getBranchResult("PS1");
BranchResult brAbsL12 = resultAbs.getNetworkResult().getBranchResult("L12");
OperatorStrategyResult resultRel = getOperatorStrategyResult(result, "strategyTapRelChange");
BranchResult brRelPS1 = resultRel.getNetworkResult().getBranchResult("PS1");
BranchResult brRelL12 = resultAbs.getNetworkResult().getBranchResult("L12");
// Apply contingency by hand
network.getLine("L23").getTerminal1().disconnect();
network.getLine("L23").getTerminal2().disconnect();
// Apply remedial action
network.getTwoWindingsTransformer("PS1").getPhaseTapChanger().setTapPosition(0);
loadFlowRunner.run(network, parameters);
// Compare results on the line L12
assertEquals(network.getLine("L12").getTerminal1().getP(), brAbsL12.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L12").getTerminal2().getP(), brAbsL12.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L12").getTerminal1().getP(), brRelL12.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L12").getTerminal2().getP(), brRelL12.getP2(), LoadFlowAssert.DELTA_POWER);
// Compare results on the t2wt PS1
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal1().getP(), brAbsPS1.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal2().getP(), brAbsPS1.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal1().getP(), brRelPS1.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal2().getP(), brRelPS1.getP2(), LoadFlowAssert.DELTA_POWER);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testSaDcPhaseTapChangerTapPositionChange(boolean dcFastMode) {
Network network = PhaseControlFactory.createWithOneT2wtTwoLines();
List<StateMonitor> monitors = createAllBranchesMonitors(network);
List<Contingency> contingencies = List.of(new Contingency("L1", new BranchContingency("L1")));
List<Action> actions = List.of(new PhaseTapChangerTapPositionAction("pstAbsChange", "PS1", false, 0));
List<OperatorStrategy> operatorStrategies = List.of(
new OperatorStrategy("strategyTapAbsChange", ContingencyContext.specificContingency("L1"), new TrueCondition(), List.of("pstAbsChange")));
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
assertNotNull(result);
OperatorStrategyResult resultAbs = getOperatorStrategyResult(result, "strategyTapAbsChange");
BranchResult brAbsL2 = resultAbs.getNetworkResult().getBranchResult("L2");
BranchResult brAbsPS1 = resultAbs.getNetworkResult().getBranchResult("PS1");
// Apply contingency by hand
network.getLine("L1").getTerminal1().disconnect();
network.getLine("L1").getTerminal2().disconnect();
// Apply remedial action
network.getTwoWindingsTransformer("PS1").getPhaseTapChanger().setTapPosition(0);
loadFlowRunner.run(network, parameters);
// Compare results on the line L2
assertEquals(network.getLine("L2").getTerminal1().getP(), brAbsL2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal2().getP(), brAbsL2.getP2(), LoadFlowAssert.DELTA_POWER);
// Compare results on the t2wt PS1
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal1().getP(), brAbsPS1.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal2().getP(), brAbsPS1.getP2(), LoadFlowAssert.DELTA_POWER);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testFastSaDcOneContingencyTwoTapPositionChange(boolean dcFastMode) {
Network network = PhaseControlFactory.createWithTwoT2wtTwoLines();
List<StateMonitor> monitors = createAllBranchesMonitors(network);
List<Contingency> contingencies = List.of(new Contingency("L1", new BranchContingency("L1")));
List<Action> actions = List.of(new PhaseTapChangerTapPositionAction("pst1Change", "PS1", false, 0),
new PhaseTapChangerTapPositionAction("pst2Change", "PS2", false, 2));
List<OperatorStrategy> operatorStrategies = List.of(
new OperatorStrategy("strategyTapChange", ContingencyContext.specificContingency("L1"), new TrueCondition(), List.of("pst1Change", "pst2Change")));
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
assertNotNull(result);
OperatorStrategyResult resultAbs = getOperatorStrategyResult(result, "strategyTapChange");
BranchResult brL2 = resultAbs.getNetworkResult().getBranchResult("L2");
BranchResult brPS1 = resultAbs.getNetworkResult().getBranchResult("PS1");
BranchResult brPS2 = resultAbs.getNetworkResult().getBranchResult("PS2");
// Apply contingency by hand
network.getLine("L1").getTerminal1().disconnect();
network.getLine("L1").getTerminal2().disconnect();
// Apply remedial actions
network.getTwoWindingsTransformer("PS1").getPhaseTapChanger().setTapPosition(0);
network.getTwoWindingsTransformer("PS2").getPhaseTapChanger().setTapPosition(2);
loadFlowRunner.run(network, parameters);
// Compare results on remaining branches
assertEquals(network.getLine("L2").getTerminal1().getP(), brL2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal2().getP(), brL2.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal1().getP(), brPS1.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal2().getP(), brPS1.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS2").getTerminal1().getP(), brPS2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS2").getTerminal2().getP(), brPS2.getP2(), LoadFlowAssert.DELTA_POWER);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testFastSaDcTwoContingenciesOneTapPositionChange(boolean dcFastMode) {
Network network = PhaseControlFactory.createWithTwoT2wtTwoLines();
List<StateMonitor> monitors = createAllBranchesMonitors(network);
List<Contingency> contingencies = List.of(new Contingency("L1+PS2", List.of(new BranchContingency("L1"), new BranchContingency("PS2"))));
List<Action> actions = List.of(new PhaseTapChangerTapPositionAction("pst1Change", "PS1", false, 0));
List<OperatorStrategy> operatorStrategies = List.of(new OperatorStrategy("strategyTapChange", ContingencyContext.specificContingency("L1+PS2"), new TrueCondition(), List.of("pst1Change")));
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
assertNotNull(result);
OperatorStrategyResult resultAbs = getOperatorStrategyResult(result, "strategyTapChange");
BranchResult brL2 = resultAbs.getNetworkResult().getBranchResult("L2");
BranchResult brPS1 = resultAbs.getNetworkResult().getBranchResult("PS1");
// Apply contingencies by hand
network.getLine("L1").getTerminal1().disconnect();
network.getLine("L1").getTerminal2().disconnect();
network.getTwoWindingsTransformer("PS2").getTerminal1().disconnect();
network.getTwoWindingsTransformer("PS2").getTerminal2().disconnect();
// Apply remedial action
network.getTwoWindingsTransformer("PS1").getPhaseTapChanger().setTapPosition(0);
loadFlowRunner.run(network, parameters);
// Compare results on remaining branches
assertEquals(network.getLine("L2").getTerminal1().getP(), brL2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal2().getP(), brL2.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal1().getP(), brPS1.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal2().getP(), brPS1.getP2(), LoadFlowAssert.DELTA_POWER);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testFastSaDcN2ContingencyOneTapPositionChange(boolean dcFastMode) {
Network network = PhaseControlFactory.createWithOneT2wtTwoLines();
// add load which will be lost by contingency
network.getVoltageLevel("VL2").newLoad()
.setId("LD3")
.setConnectableBus("B2")
.setBus("B2")
.setP0(50.0)
.setQ0(25.0)
.add();
List<StateMonitor> monitors = createAllBranchesMonitors(network);
List<Contingency> contingencies = List.of(new Contingency("L1+LD3", List.of(new BranchContingency("L1"), new LoadContingency("LD3"))));
List<Action> actions = List.of(new PhaseTapChangerTapPositionAction("pstChange", "PS1", false, 0));
List<OperatorStrategy> operatorStrategies = List.of(
new OperatorStrategy("strategyTapChange", ContingencyContext.specificContingency("L1+LD3"), new TrueCondition(), List.of("pstChange")));
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
assertNotNull(result);
OperatorStrategyResult resultAbs = getOperatorStrategyResult(result, "strategyTapChange");
BranchResult brAbsL2 = resultAbs.getNetworkResult().getBranchResult("L2");
BranchResult brAbsPS1 = resultAbs.getNetworkResult().getBranchResult("PS1");
// Apply contingencies by hand
network.getLine("L1").disconnect();
network.getLoad("LD3").disconnect();
// Apply remedial action
network.getTwoWindingsTransformer("PS1").getPhaseTapChanger().setTapPosition(0);
loadFlowRunner.run(network, parameters);
// Compare results on the line L2
assertEquals(network.getLine("L2").getTerminal1().getP(), brAbsL2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L2").getTerminal2().getP(), brAbsL2.getP2(), LoadFlowAssert.DELTA_POWER);
// Compare results on the t2wt PS1
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal1().getP(), brAbsPS1.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("PS1").getTerminal2().getP(), brAbsPS1.getP2(), LoadFlowAssert.DELTA_POWER);
}
// Test on fast DC only. The limitation is specific to fast dc
@Test
void testFastDcSaWithUnsupportedAction() {
Network network = PhaseControlFactory.createWithOneT2wtTwoLines();
List<StateMonitor> monitors = createAllBranchesMonitors(network);
List<Contingency> contingencies = List.of(new Contingency("contingencyLD2", List.of(new LoadContingency("LD2"))));
List<Action> actions = List.of(new GeneratorActionBuilder().withId("genActionG1").withGeneratorId("G1").withActivePowerRelativeValue(true).withActivePowerValue(1).build());
List<OperatorStrategy> operatorStrategies = List.of(new OperatorStrategy("strategyTapChange", ContingencyContext.specificContingency("contingencyLD2"), new TrueCondition(), List.of("genActionG1")));
CompletionException thrown = assertThrows(CompletionException.class,
() -> runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, operatorStrategies, actions, ReportNode.NO_OP));
assertTrue(thrown.getCause().getMessage().contains("For now, only PhaseTapChangerTapPositionAction, TerminalsConnectionAction and SwitchAction are allowed in fast DC Security Analysis"));
}
// Test on fast DC only. The limitation is specific to fast dc
@Test
void testFastDcSaWithTransformerEnabled() {
Network network = PhaseControlFactory.createWithOneT2wtTwoLines();
List<Contingency> contingencies = List.of(new Contingency("L1", new BranchContingency("L1")));
List<Action> actions = List.of(new TerminalsConnectionAction("closePS1", "PS1", false));
List<OperatorStrategy> operatorStrategies = List.of(new OperatorStrategy("strategyClosePS1", ContingencyContext.specificContingency("L1"), new TrueCondition(), List.of("closePS1")));
List<StateMonitor> monitors = List.of();
CompletionException thrown = assertThrows(CompletionException.class,
() -> runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, operatorStrategies, actions, ReportNode.NO_OP));
assertTrue(thrown.getCause().getMessage().contains("For now, TerminalsConnectionAction enabling a transformer is not allowed in WoodburyDcSecurityAnalysis"));
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testDcSaTransformerDisconnectionAction(boolean dcFastMode) {
Network network = PhaseControlFactory.createWithOneT2wtTwoLines();
List<Contingency> contingencies = List.of(new Contingency("L1", new BranchContingency("L1")));
List<Action> actions = List.of(new TerminalsConnectionAction("openPS1", "PS1", true));
List<OperatorStrategy> operatorStrategies = List.of(new OperatorStrategy("strategyOpenPS1", ContingencyContext.specificContingency("L1"), new TrueCondition(), List.of("openPS1")));
List<StateMonitor> monitors = createAllBranchesMonitors(network);
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
// Verify pst disconnection is well handled in Woodbury computation, when alpha of opened pst is null
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
assertEquals(100.0, getOperatorStrategyResult(result, "strategyOpenPS1").getNetworkResult().getBranchResult("L2").getP1(), LoadFlowAssert.DELTA_POWER);
// Same when alpha of opened pst is not null
network.getTwoWindingsTransformer("PS1").getPhaseTapChanger().setTapPosition(2);
result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, operatorStrategies, actions, ReportNode.NO_OP);
assertEquals(100.0, getOperatorStrategyResult(result, "strategyOpenPS1").getNetworkResult().getBranchResult("L2").getP1(), LoadFlowAssert.DELTA_POWER);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testDcSaActionBreakingConnectivityByOpeningLine(boolean dcFastMode) {
Network network = PhaseControlFactory.createNetworkWith3Buses();
List<StateMonitor> monitors = createAllBranchesMonitors(network);
// contingency does not break connectivity
List<Contingency> contingencies = List.of(new Contingency("PS1", new BranchContingency("PS1")));
// action does break connectivity
List<Action> actions = List.of(new TerminalsConnectionAction("openL23", "L23", true));
List<OperatorStrategy> operatorStrategies = List.of(
new OperatorStrategy("strategyOpenL23", ContingencyContext.specificContingency("PS1"), new TrueCondition(), List.of("openL23")));
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
assertEquals(100.0, getOperatorStrategyResult(result, "strategyOpenL23").getNetworkResult().getBranchResult("L12").getP1(), LoadFlowAssert.DELTA_POWER);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testDcSaActionBreakingConnectivityByOpeningSwitchAndTransformer(boolean dcFastMode) {
Network network = VoltageControlNetworkFactory.createNetworkWith2T2wtAndSwitch();
List<StateMonitor> monitors = createAllBranchesMonitors(network);
// contingency does not break connectivity
List<Contingency> contingencies = List.of(new Contingency("LOAD_3", new LoadContingency("LOAD_3")));
// actions removes bus 3 from main connected component
List<Action> actions = List.of(new TerminalsConnectionAction("openT2wT", "T2wT", true), new SwitchAction("openSWITCH", "SWITCH", true));
List<OperatorStrategy> operatorStrategies = List.of(new OperatorStrategy("strategyOpen", ContingencyContext.specificContingency("LOAD_3"),
new TrueCondition(), List.of("openT2wT", "openSWITCH")));
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
OperatorStrategyResult operatorStrategyResult = getOperatorStrategyResult(result, "strategyOpen");
BranchResult brL12 = operatorStrategyResult.getNetworkResult().getBranchResult("LINE_12");
BranchResult brT2wT2 = operatorStrategyResult.getNetworkResult().getBranchResult("T2wT2");
BranchResult brL15 = operatorStrategyResult.getNetworkResult().getBranchResult("LINE_15");
// Apply contingency/remedial action by hand and run LF
network.getLoad("LOAD_3").disconnect();
network.getTwoWindingsTransformer("T2wT").disconnect();
network.getSwitch("SWITCH").setOpen(true);
loadFlowRunner.run(network, parameters);
// Compare results of DC SA and LF
assertEquals(network.getLine("LINE_12").getTerminal1().getP(), brL12.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("LINE_12").getTerminal2().getP(), brL12.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("T2wT2").getTerminal1().getP(), brT2wT2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("T2wT2").getTerminal2().getP(), brT2wT2.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("LINE_15").getTerminal1().getP(), brL15.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("LINE_15").getTerminal2().getP(), brL15.getP2(), LoadFlowAssert.DELTA_POWER);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testDcSaActionAndContingencyBreakingConnectivityTogether(boolean dcFastMode) {
Network network = VoltageControlNetworkFactory.createNetworkWith2T2wtAndSwitch();
List<StateMonitor> monitors = createAllBranchesMonitors(network);
List<Contingency> contingencies = List.of(new Contingency("T2wT2+GEN_5", new BranchContingency("T2wT2"), new GeneratorContingency("GEN_5")));
// action will break connectivity when it is applied with the contingency
List<Action> actions = List.of(new TerminalsConnectionAction("openLINE_12", "LINE_12", true));
List<OperatorStrategy> operatorStrategies = List.of(
new OperatorStrategy("strategyOpenLINE_12", ContingencyContext.specificContingency("T2wT2+GEN_5"), new TrueCondition(), List.of("openLINE_12")));
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
assertEquals(2, getOperatorStrategyResult(result, "strategyOpenLINE_12").getNetworkResult().getBranchResult("LINE_15").getP1(), LoadFlowAssert.DELTA_POWER);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testDcSaActionsBreakingConnectivityAndChangingTapPosition(boolean dcFastMode) {
Network network = VoltageControlNetworkFactory.createWithGeneratorRemoteControl();
// add pst on tr2 to modify its tap
network.getTwoWindingsTransformer("tr2").newPhaseTapChanger()
.setTapPosition(1)
.setRegulationTerminal(network.getTwoWindingsTransformer("tr2").getTerminal2())
.setRegulationMode(PhaseTapChanger.RegulationMode.FIXED_TAP)
.setRegulationValue(200)
.beginStep()
.setAlpha(-5)
.setRho(1.0)
.setR(0.0)
.setX(50)
.setG(0.0)
.setB(0.0)
.endStep()
.beginStep()
.setAlpha(0.0)
.setRho(1.0)
.setR(0.0)
.setX(100)
.setG(0.0)
.setB(0.0)
.endStep()
.add();
// add parallel line to the pst to verify flows repartition
network.newLine()
.setId("l42")
.setBus1("b4")
.setBus2("b2")
.setR(0)
.setX(100.0)
.add();
List<StateMonitor> monitors = createAllBranchesMonitors(network);
// contingency breaks connectivity
List<Contingency> contingencies = List.of(new Contingency("tr3", new BranchContingency("tr3")));
// actions break connectivity and modify tap position
List<Action> actions = List.of(new PhaseTapChangerTapPositionAction("changeTr2", "tr2", false, 0),
new TerminalsConnectionAction("openTr1", "tr1", true));
List<OperatorStrategy> operatorStrategies = List.of(new OperatorStrategy("strategy2Actions", ContingencyContext.specificContingency("tr3"),
new TrueCondition(), List.of("openTr1", "changeTr2")));
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
OperatorStrategyResult operatorStrategyResult = getOperatorStrategyResult(result, "strategy2Actions");
BranchResult brTr2 = operatorStrategyResult.getNetworkResult().getBranchResult("tr2");
BranchResult brL42 = operatorStrategyResult.getNetworkResult().getBranchResult("l42");
// Apply contingency/action by hand and run LF
network.getTwoWindingsTransformer("tr1").disconnect();
network.getTwoWindingsTransformer("tr2").getPhaseTapChanger().setTapPosition(0);
network.getTwoWindingsTransformer("tr3").disconnect();
loadFlowRunner.run(network, parameters);
// Compare results of DC SA and LF
assertEquals(network.getTwoWindingsTransformer("tr2").getTerminal1().getP(), brTr2.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("tr2").getTerminal2().getP(), brTr2.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("l42").getTerminal1().getP(), brL42.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("l42").getTerminal2().getP(), brL42.getP2(), LoadFlowAssert.DELTA_POWER);
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testDcSaActionRestoringConnectivityByClosingLine(boolean dcFastMode) {
Network network = PhaseControlFactory.createNetworkWith3Buses();
// open L12 to restore connectivity by closing it
network.getLine("L12").disconnect();
List<StateMonitor> monitors = createAllBranchesMonitors(network);
List<Contingency> contingencies = List.of(new Contingency("PS1", new BranchContingency("PS1")));
List<Action> actions = List.of(new TerminalsConnectionAction("closeL12", "L12", false));
List<OperatorStrategy> operatorStrategies = List.of(new OperatorStrategy("strategyCloseL12", ContingencyContext.specificContingency("PS1"), new TrueCondition(), List.of("closeL12")));
securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class)
.setDcFastMode(dcFastMode);
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
assertNotNull(result);
OperatorStrategyResult operatorStrategyResult = getOperatorStrategyResult(result, "strategyCloseL12");
BranchResult brL12 = operatorStrategyResult.getNetworkResult().getBranchResult("L12");
BranchResult brL23 = operatorStrategyResult.getNetworkResult().getBranchResult("L23");
// Apply contingency/action by hand and run LF
network.getTwoWindingsTransformer("PS1").disconnect();
network.getLine("L12").connect();
loadFlowRunner.run(network, parameters);
// Compare results of fast DC SA and LF
assertEquals(network.getLine("L12").getTerminal1().getP(), brL12.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L12").getTerminal2().getP(), brL12.getP2(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L23").getTerminal1().getP(), brL23.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getLine("L23").getTerminal2().getP(), brL23.getP2(), LoadFlowAssert.DELTA_POWER);
}
// Test on fast DC only: default DC provides different results than those obtained with LF
@Test
void testFastDcSaActionRestoringConnectivityByClosingSwitch() {
Network network = VoltageControlNetworkFactory.createNetworkWith2T2wtAndSwitch();
// open switch to restore connectivity by closing it
network.getSwitch("SWITCH").setOpen(true);
List<StateMonitor> monitors = createAllBranchesMonitors(network);
List<Contingency> contingencies = List.of(new Contingency("LINE_15+GEN_5", new BranchContingency("LINE_15"), new GeneratorContingency("GEN_5")));
List<Action> actions = List.of(new SwitchAction("closeSWITCH", "SWITCH", false));
List<OperatorStrategy> operatorStrategies = List.of(new OperatorStrategy("strategyCloseSWITCH", ContingencyContext.specificContingency("LINE_15+GEN_5"), new TrueCondition(), List.of("closeSWITCH")));
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, ReportNode.NO_OP);
OperatorStrategyResult resultAbs = getOperatorStrategyResult(result, "strategyCloseSWITCH");
BranchResult brL12 = resultAbs.getNetworkResult().getBranchResult("LINE_12");
BranchResult brT2wT = resultAbs.getNetworkResult().getBranchResult("T2wT");
BranchResult brT2wT2 = resultAbs.getNetworkResult().getBranchResult("T2wT2");
// Apply contingency/action by hand and run LF
network.getLine("LINE_15").disconnect();
network.getGenerator("GEN_5").disconnect();
network.getSwitch("SWITCH").setOpen(false);
loadFlowRunner.run(network, parameters);
// Compare results of fast DC SA and LF
assertEquals(network.getLine("LINE_12").getTerminal1().getP(), brL12.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("T2wT").getTerminal1().getP(), brT2wT.getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(network.getTwoWindingsTransformer("T2wT2").getTerminal1().getP(), brT2wT2.getP1(), LoadFlowAssert.DELTA_POWER);
}
@Test
void testDcSaPhaseTapChangerTapPositionChangeNoViolationDetectedOnRemovedBranchOnOneSide() {
Network network = NodeBreakerNetworkFactory.createWith4Bars();
// add small limits on disabled lines to verify there is no violation detected
network.getLine("L3").newCurrentLimits1().setPermanentLimit(0.1).add();
network.getLine("L3").newCurrentLimits2().setPermanentLimit(0.1).add();
network.getLine("L4").newCurrentLimits1().setPermanentLimit(0.1).add();
network.getLine("L4").newCurrentLimits2().setPermanentLimit(0.1).add();
setSlackBusId(parameters, "VL1_0");
SecurityAnalysisParameters securityParameters = new SecurityAnalysisParameters();
securityParameters.setLoadFlowParameters(parameters);
// this contingency will disable L4 on side 1 and L5 on side 2
List<Contingency> contingencies = Stream.of("BBS3")
.map(id -> new Contingency(id, new BusbarSectionContingency(id)))
.collect(Collectors.toList());
List<StateMonitor> monitors = createAllBranchesMonitors(network);
// the action has no real effect on the flow, we add it to verify operator strategy result
List<Action> actions = List.of(new PhaseTapChangerTapPositionAction("pstChange", "PS1", false, 0));
List<OperatorStrategy> operatorStrategies = List.of(new OperatorStrategy("strategyPstChange", ContingencyContext.specificContingency("BBS3"), new TrueCondition(), List.of("pstChange")));
SecurityAnalysisResult resultDefaultDcSa = runSecurityAnalysis(network, contingencies, monitors, securityParameters,
operatorStrategies, actions, ReportNode.NO_OP);
OperatorStrategyResult operatorStrategyResult = getOperatorStrategyResult(resultDefaultDcSa, "strategyPstChange");
assertEquals(200.0, operatorStrategyResult.getNetworkResult().getBranchResult("PS1").getP1(), DELTA_POWER);
assertEquals(-200.0, operatorStrategyResult.getNetworkResult().getBranchResult("PS1").getP2(), DELTA_POWER);
assertEquals(0, operatorStrategyResult.getLimitViolationsResult().getLimitViolations().size());
// in default dc mode, branch results with 0 flow are created for disabled branches on one side
assertEquals(5, operatorStrategyResult.getNetworkResult().getBranchResults().size());
// set dc sa mode
OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters();
openSecurityAnalysisParameters.setDcFastMode(true);
securityParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters);
SecurityAnalysisResult resultFastDcSa = runSecurityAnalysis(network, contingencies, monitors, securityParameters,
operatorStrategies, actions, ReportNode.NO_OP);
operatorStrategyResult = getOperatorStrategyResult(resultFastDcSa, "strategyPstChange");
assertEquals(200.0, operatorStrategyResult.getNetworkResult().getBranchResult("PS1").getP1(), DELTA_POWER);
assertEquals(-200.0, operatorStrategyResult.getNetworkResult().getBranchResult("PS1").getP2(), DELTA_POWER);
assertEquals(0, operatorStrategyResult.getLimitViolationsResult().getLimitViolations().size());
// in fast dc mode, no branch result is created for disabled branches on one side
assertEquals(1, operatorStrategyResult.getNetworkResult().getBranchResults().size());
}
}