From 72b5783a5799e357351b76760ce6855d53d7b011 Mon Sep 17 00:00:00 2001 From: p-arvy Date: Fri, 13 Dec 2024 12:36:10 +0100 Subject: [PATCH 1/4] Add TUs to be verified by future developments Signed-off-by: p-arvy --- ...buryDcSecurityAnalysisWithActionsTest.java | 203 +++++++++++++++++- 1 file changed, 198 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysisWithActionsTest.java b/src/test/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysisWithActionsTest.java index 54a708400c..73b4b0970f 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysisWithActionsTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysisWithActionsTest.java @@ -7,9 +7,7 @@ */ package com.powsybl.openloadflow.sa; -import com.powsybl.action.Action; -import com.powsybl.action.GeneratorActionBuilder; -import com.powsybl.action.PhaseTapChangerTapPositionAction; +import com.powsybl.action.*; import com.powsybl.commons.report.ReportNode; import com.powsybl.contingency.BranchContingency; import com.powsybl.contingency.Contingency; @@ -18,6 +16,8 @@ import com.powsybl.iidm.network.Network; import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.openloadflow.OpenLoadFlowParameters; +import com.powsybl.openloadflow.network.FourBusNetworkFactory; +import com.powsybl.openloadflow.network.NodeBreakerNetworkFactory; import com.powsybl.openloadflow.network.PhaseControlFactory; import com.powsybl.openloadflow.network.SlackBusSelectionMode; import com.powsybl.openloadflow.util.LoadFlowAssert; @@ -35,6 +35,8 @@ import java.util.List; import java.util.concurrent.CompletionException; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.*; @@ -436,7 +438,6 @@ void testFastSaDcN2ContingencyOneTapPositionChange(boolean dcFastMode) { 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 testFastDcSaWithActionNotOnPst() { Network network = PhaseControlFactory.createWithOneT2wtTwoLines(); @@ -447,6 +448,198 @@ void testFastDcSaWithActionNotOnPst() { CompletionException thrown = assertThrows(CompletionException.class, () -> runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, operatorStrategies, actions, ReportNode.NO_OP)); - assertTrue(thrown.getCause().getMessage().contains("For now, only PhaseTapChangerTapPositionAction is allowed in WoodburyDcSecurityAnalysis")); + assertTrue(thrown.getCause().getMessage().contains("For now, only PhaseTapChangerTapPositionAction and TerminalsConnectionAction are allowed in WoodburyDcSecurityAnalysis")); } + + @Test + void testFastSaDcLineDisconnectionAction() { + Network network = FourBusNetworkFactory.create(); + List contingencies = Stream.of("l14") + .map(id -> new Contingency(id, new BranchContingency(id))) + .collect(Collectors.toList()); + + List actions = List.of(new TerminalsConnectionAction("openLine", "l13", true)); + List operatorStrategies = List.of(new OperatorStrategy("strategyL1", ContingencyContext.specificContingency("l14"), new TrueCondition(), List.of("openLine"))); + List monitors = createAllBranchesMonitors(network); + + LoadFlowParameters parameters = new LoadFlowParameters(); + parameters.setDistributedSlack(true); + parameters.setDc(true); + SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); + securityAnalysisParameters.setLoadFlowParameters(parameters); + OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters(); + openSecurityAnalysisParameters.setDcFastMode(true); + securityAnalysisParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters); + + SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, + operatorStrategies, actions, ReportNode.NO_OP); + + OperatorStrategyResult resultStratL1 = getOperatorStrategyResult(result, "strategyL1"); + BranchResult brl12 = resultStratL1.getNetworkResult().getBranchResult("l12"); + BranchResult brl23 = resultStratL1.getNetworkResult().getBranchResult("l23"); + BranchResult brl34 = resultStratL1.getNetworkResult().getBranchResult("l34"); + + assertEquals(2.0, brl12.getP1(), LoadFlowAssert.DELTA_POWER); + assertEquals(3.0, brl23.getP1(), LoadFlowAssert.DELTA_POWER); + assertEquals(-1.0, brl34.getP1(), LoadFlowAssert.DELTA_POWER); + } + + @Test + void testFastSaDcTransformerDisconnectionAction() { + Network network = PhaseControlFactory.createWithOneT2wtTwoLines(); + List contingencies = List.of(new Contingency("L1", new BranchContingency("L1"))); + List actions = List.of(new TerminalsConnectionAction("openPS1", "PS1", true)); + List operatorStrategies = List.of( + new OperatorStrategy("strategyOpenPS1", ContingencyContext.specificContingency("L1"), new TrueCondition(), List.of("openPS1"))); + List monitors = createAllBranchesMonitors(network); + + LoadFlowParameters parameters = new LoadFlowParameters(); + parameters.setDc(true); + SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); + securityAnalysisParameters.setLoadFlowParameters(parameters); + OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters(); + openSecurityAnalysisParameters.setDcFastMode(true); + securityAnalysisParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters); + + // 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(0); + result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, + operatorStrategies, actions, ReportNode.NO_OP); + assertEquals(100.0, getOperatorStrategyResult(result, "strategyOpenPS1").getNetworkResult().getBranchResult("L2").getP1(), LoadFlowAssert.DELTA_POWER); + } + + @Test + void testFastSaDcTransformerDisconnectionActionBreakingConnectivity() { + Network network = PhaseControlFactory.createNetworkWith3Buses(); + network.getTwoWindingsTransformer("PS1").getPhaseTapChanger().setTapPosition(0); + List monitors = createAllBranchesMonitors(network); + List contingencies = List.of(new Contingency("LD3", new LoadContingency("LD3"))); + List actions = List.of(new TerminalsConnectionAction("openL23", "L23", true)); + List operatorStrategies = List.of( + new OperatorStrategy("strategyOpenL23", ContingencyContext.specificContingency("LD3"), new TrueCondition(), List.of("openL23"))); + + SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); + LoadFlowParameters parameters = new LoadFlowParameters(); + parameters.setDc(true); + parameters.setDistributedSlack(true); + securityAnalysisParameters.setLoadFlowParameters(parameters); + OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters(); + openSecurityAnalysisParameters.setDcFastMode(true); + securityAnalysisParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters); + + SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, + operatorStrategies, actions, ReportNode.NO_OP); + assertEquals(100.0, getOperatorStrategyResult(result, "strategyOpenL23").getNetworkResult().getBranchResult("PS1").getP1(), LoadFlowAssert.DELTA_POWER); + } + + @Test + void testFastSaDcLineConnectionAction() { + Network network = FourBusNetworkFactory.create(); + network.getLine("l23").getTerminal1().disconnect(); + network.getLine("l23").getTerminal2().disconnect(); + List contingencies = Stream.of("l14") + .map(id -> new Contingency(id, new BranchContingency(id))) + .collect(Collectors.toList()); + + List actions = List.of(new TerminalsConnectionAction("closeLine", "l23", false)); + List operatorStrategies = List.of(new OperatorStrategy("strategyL1", ContingencyContext.specificContingency("l14"), new TrueCondition(), List.of("closeLine"))); + List monitors = createAllBranchesMonitors(network); + + LoadFlowParameters parameters = new LoadFlowParameters(); + parameters.setDistributedSlack(true); + parameters.setDc(true); + SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); + securityAnalysisParameters.setLoadFlowParameters(parameters); + OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters(); + openSecurityAnalysisParameters.setDcFastMode(true); + securityAnalysisParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters); + + SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, + operatorStrategies, actions, ReportNode.NO_OP); + OperatorStrategyResult dcStrategyResult = getOperatorStrategyResult(result, "strategyL1"); + + assertEquals(0.333, dcStrategyResult.getNetworkResult().getBranchResult("l12").getP1(), LoadFlowAssert.DELTA_POWER); + assertEquals(1.333, dcStrategyResult.getNetworkResult().getBranchResult("l23").getP1(), LoadFlowAssert.DELTA_POWER); + assertEquals(-1.0, dcStrategyResult.getNetworkResult().getBranchResult("l34").getP1(), LoadFlowAssert.DELTA_POWER); + } + + @Test + void testFastSaDcTransformerConnectionAction() { + // TODO : problem to update a value that is not present here... Big change expected + // FIXME : when a t2wt is added by the closing of an action, seems very problematic... + Network network = PhaseControlFactory.createWithOneT2wtTwoLines(); + List contingencies = List.of(new Contingency("L1", new BranchContingency("L1"))); + List actions = List.of(new TerminalsConnectionAction("closePS1", "PS1", false)); + List operatorStrategies = List.of( + new OperatorStrategy("strategyClosePS1", ContingencyContext.specificContingency("L1"), new TrueCondition(), List.of("closePS1"))); + List monitors = createAllBranchesMonitors(network); + + LoadFlowParameters parameters = new LoadFlowParameters(); + parameters.setDc(true); + SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); + securityAnalysisParameters.setLoadFlowParameters(parameters); + OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters(); + openSecurityAnalysisParameters.setDcFastMode(false); + securityAnalysisParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters); + + network.getTwoWindingsTransformer("PS1").getTerminal1().disconnect(); + network.getTwoWindingsTransformer("PS1").getTerminal2().disconnect(); + SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, + operatorStrategies, actions, ReportNode.NO_OP); + assertEquals(50.0, getOperatorStrategyResult(result, "strategyClosePS1").getNetworkResult().getBranchResult("L2").getP1(), LoadFlowAssert.DELTA_POWER); + } + + @Test + void testDcSecurityAnalysisWithOperatorStrategy() { + Network network = NodeBreakerNetworkFactory.create3Bars(); + network.getSwitch("C1").setOpen(true); + network.getLineStream().forEach(line -> { + if (line.getCurrentLimits1().isPresent()) { + line.getCurrentLimits1().orElseThrow().setPermanentLimit(310); + } + if (line.getCurrentLimits2().isPresent()) { + line.getCurrentLimits2().orElseThrow().setPermanentLimit(310); + } + }); + + List contingencies = Stream.of("L3") + .map(id -> new Contingency(id, new BranchContingency(id))) + .collect(Collectors.toList()); + + // FIXME : add the cases with connectivity modification due to the actions + List actions = List.of(new SwitchAction("action1", "C1", false)); + List operatorStrategies = List.of(new OperatorStrategy("strategyL3", ContingencyContext.specificContingency("L3"), new TrueCondition(), List.of("action1"))); + List monitors = createAllBranchesMonitors(network); + + LoadFlowParameters parameters = new LoadFlowParameters(); + parameters.setDistributedSlack(false); + parameters.setDc(true); + setSlackBusId(parameters, "VL2_0"); + SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); + securityAnalysisParameters.setLoadFlowParameters(parameters); + + // verify pre contingency results + SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, + operatorStrategies, actions, ReportNode.NO_OP); + assertEquals(400.0, result.getPreContingencyResult().getNetworkResult().getBranchResult("L1").getP1(), LoadFlowAssert.DELTA_POWER); + assertEquals(100.0, result.getPreContingencyResult().getNetworkResult().getBranchResult("L2").getP1(), LoadFlowAssert.DELTA_POWER); + assertEquals(100.0, result.getPreContingencyResult().getNetworkResult().getBranchResult("L3").getP1(), LoadFlowAssert.DELTA_POWER); + + // compare post contingency/action results with load flow + network.getLine("L3").disconnect(); + network.getSwitch("C1").setOpen(false); + loadFlowRunner.run(network, parameters); + + // Compare results on the line L2 + assertEquals(network.getLine("L2").getTerminal1().getP(), getOperatorStrategyResult(result, "strategyL3").getNetworkResult().getBranchResult("L2").getP1(), LoadFlowAssert.DELTA_POWER); + assertEquals(network.getLine("L1").getTerminal1().getP(), getOperatorStrategyResult(result, "strategyL3").getNetworkResult().getBranchResult("L1").getP1(), LoadFlowAssert.DELTA_POWER); + } + + + // FIXME : cases with actions that modify the connectivity (i.e. add network or remove some part are) are not yet handled } From ff34773cdddae1140ea2f66be336f82828980356 Mon Sep 17 00:00:00 2001 From: p-arvy Date: Fri, 13 Dec 2024 13:09:42 +0100 Subject: [PATCH 2/4] Add ComputedSwitchBranchElement and relative calculation in WoodburyEngine Signed-off-by: p-arvy --- .../fastdc/ComputedSwitchBranchElement.java | 32 ++++++ .../dc/fastdc/WoodburyEngine.java | 103 ++++++++++++------ .../sa/WoodburyDcSecurityAnalysis.java | 59 ++++++---- 3 files changed, 134 insertions(+), 60 deletions(-) create mode 100644 src/main/java/com/powsybl/openloadflow/dc/fastdc/ComputedSwitchBranchElement.java diff --git a/src/main/java/com/powsybl/openloadflow/dc/fastdc/ComputedSwitchBranchElement.java b/src/main/java/com/powsybl/openloadflow/dc/fastdc/ComputedSwitchBranchElement.java new file mode 100644 index 0000000000..7c326e0da8 --- /dev/null +++ b/src/main/java/com/powsybl/openloadflow/dc/fastdc/ComputedSwitchBranchElement.java @@ -0,0 +1,32 @@ +/** + * 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.dc.fastdc; + +import com.powsybl.openloadflow.dc.equations.ClosedBranchSide1DcFlowEquationTerm; +import com.powsybl.openloadflow.dc.equations.DcEquationType; +import com.powsybl.openloadflow.dc.equations.DcVariableType; +import com.powsybl.openloadflow.equations.EquationSystem; +import com.powsybl.openloadflow.network.ElementType; +import com.powsybl.openloadflow.network.LfBranch; + +/** + * @author Pierre Arvy {@literal } + */ +public final class ComputedSwitchBranchElement extends ComputedElement { + + private final boolean enabled; + + public ComputedSwitchBranchElement(LfBranch lfBranch, boolean enabled, EquationSystem equationSystem) { + super(lfBranch, equationSystem.getEquationTerm(ElementType.BRANCH, lfBranch.getNum(), ClosedBranchSide1DcFlowEquationTerm.class)); + this.enabled = enabled; + } + + public boolean isEnabled() { + return enabled; + } +} diff --git a/src/main/java/com/powsybl/openloadflow/dc/fastdc/WoodburyEngine.java b/src/main/java/com/powsybl/openloadflow/dc/fastdc/WoodburyEngine.java index bc090d1e21..de7a0b8a1b 100644 --- a/src/main/java/com/powsybl/openloadflow/dc/fastdc/WoodburyEngine.java +++ b/src/main/java/com/powsybl/openloadflow/dc/fastdc/WoodburyEngine.java @@ -38,26 +38,26 @@ public class WoodburyEngine { private final DenseMatrix contingenciesStates; - private final List tapPositionChangeElements; + private final List actionElements; - private final DenseMatrix tapPositionChangeStates; + private final DenseMatrix actionsStates; public WoodburyEngine(DcEquationSystemCreationParameters creationParameters, List contingencyElements, DenseMatrix contingenciesStates) { this.creationParameters = Objects.requireNonNull(creationParameters); this.contingencyElements = Objects.requireNonNull(contingencyElements); this.contingenciesStates = Objects.requireNonNull(contingenciesStates); - this.tapPositionChangeElements = Collections.emptyList(); - this.tapPositionChangeStates = DenseMatrix.EMPTY; + this.actionElements = Collections.emptyList(); + this.actionsStates = DenseMatrix.EMPTY; } public WoodburyEngine(DcEquationSystemCreationParameters creationParameters, List contingencyElements, - DenseMatrix contingenciesStates, List tapPositionChangeElements, DenseMatrix tapPositionChangeStates) { + DenseMatrix contingenciesStates, List actionElements, DenseMatrix actionsStates) { this.creationParameters = Objects.requireNonNull(creationParameters); this.contingencyElements = Objects.requireNonNull(contingencyElements); this.contingenciesStates = Objects.requireNonNull(contingenciesStates); - this.tapPositionChangeElements = Objects.requireNonNull(tapPositionChangeElements); - this.tapPositionChangeStates = Objects.requireNonNull(tapPositionChangeStates); + this.actionElements = Objects.requireNonNull(actionElements); + this.actionsStates = Objects.requireNonNull(actionsStates); } /** @@ -145,7 +145,7 @@ private double calculatePower(PiModel piModel) { * Compute the flow transfer factors needed to calculate the post-contingency state values. */ private void setAlphas(DenseMatrix states, int columnState) { - if (contingencyElements.size() == 1 && tapPositionChangeElements.isEmpty()) { + if (contingencyElements.size() == 1 && actionElements.isEmpty()) { ComputedContingencyElement element = contingencyElements.iterator().next(); LfBranch lfBranch = element.getLfBranch(); ClosedBranchSide1DcFlowEquationTerm p1 = element.getLfBranchEquation(); @@ -155,25 +155,41 @@ private void setAlphas(DenseMatrix states, int columnState) { - contingenciesStates.get(p1.getPh2Var().getRow(), element.getComputedElementIndex())); double b = states.get(p1.getPh1Var().getRow(), columnState) - states.get(p1.getPh2Var().getRow(), columnState); element.setAlphaForWoodburyComputation(b / a); - } else if (contingencyElements.isEmpty() && tapPositionChangeElements.size() == 1) { - ComputedTapPositionChangeElement element = tapPositionChangeElements.iterator().next(); + } else if (contingencyElements.isEmpty() && actionElements.size() == 1) { + // TODO : case when there is only one switching action, for now, works only when there is only one action on pst + ComputedElement element = actionElements.iterator().next(); LfBranch lfBranch = element.getLfBranch(); ClosedBranchSide1DcFlowEquationTerm p1 = element.getLfBranchEquation(); + double newAlpha = 0d; + double oldPower = 0d; + double newPower = 0d; + if (element instanceof ComputedTapPositionChangeElement) { + TapPositionChange tapPositionChange = ((ComputedTapPositionChangeElement) element).getTapPositionChange(); + PiModel newPiModel = tapPositionChange.getNewPiModel(); + newAlpha = newPiModel.getA1(); + oldPower = calculatePower(lfBranch); + newPower = calculatePower(newPiModel); + } else if (element instanceof ComputedSwitchBranchElement) { + if (((ComputedSwitchBranchElement) element).isEnabled()) { + newPower = calculatePower(lfBranch); + } else { + oldPower = calculatePower(lfBranch); + } + } + // we solve a*alpha = b - PiModel newPiModel = element.getTapPositionChange().getNewPiModel(); - double deltaX = 1d / (calculatePower(lfBranch) - calculatePower(newPiModel)); - double a = deltaX - (tapPositionChangeStates.get(p1.getPh1Var().getRow(), element.getComputedElementIndex()) - - tapPositionChangeStates.get(p1.getPh2Var().getRow(), element.getComputedElementIndex())); + double deltaX = 1d / (oldPower - newPower); + double a = deltaX - (actionsStates.get(p1.getPh1Var().getRow(), element.getComputedElementIndex()) + - actionsStates.get(p1.getPh2Var().getRow(), element.getComputedElementIndex())); - double newAlpha = newPiModel.getA1(); double b = states.get(p1.getPh1Var().getRow(), columnState) - states.get(p1.getPh2Var().getRow(), columnState) + newAlpha; element.setAlphaForWoodburyComputation(b / a); } else { // set local indexes of computed elements to use them in small matrix computation ComputedElement.setLocalIndexes(contingencyElements); - ComputedElement.setLocalIndexes(tapPositionChangeElements); - int size = contingencyElements.size() + tapPositionChangeElements.size(); + ComputedElement.setLocalIndexes(actionElements); + int size = contingencyElements.size() + actionElements.size(); DenseMatrix rhs = new DenseMatrix(size, 1); DenseMatrix matrix = new DenseMatrix(size, size); @@ -194,21 +210,36 @@ private void setAlphas(DenseMatrix states, int columnState) { } // loop on actions to fill top-right quadrant of the matrix - for (ComputedTapPositionChangeElement tapPositionChangeElement : tapPositionChangeElements) { - int j = contingencyElements.size() + tapPositionChangeElement.getLocalIndex(); - double value = -(tapPositionChangeStates.get(p1.getPh1Var().getRow(), tapPositionChangeElement.getComputedElementIndex()) - - tapPositionChangeStates.get(p1.getPh2Var().getRow(), tapPositionChangeElement.getComputedElementIndex())); + for (ComputedElement actionElement : actionElements) { + int j = contingencyElements.size() + actionElement.getLocalIndex(); + double value = -(actionsStates.get(p1.getPh1Var().getRow(), actionElement.getComputedElementIndex()) + - actionsStates.get(p1.getPh2Var().getRow(), actionElement.getComputedElementIndex())); matrix.set(i, j, value); } } - for (ComputedTapPositionChangeElement tapPositionChangeElement : tapPositionChangeElements) { - int i = contingencyElements.size() + tapPositionChangeElement.getLocalIndex(); - LfBranch lfBranch = tapPositionChangeElement.getLfBranch(); - ClosedBranchSide1DcFlowEquationTerm p1 = tapPositionChangeElement.getLfBranchEquation(); + for (ComputedElement actionElement : actionElements) { + int i = contingencyElements.size() + actionElement.getLocalIndex(); + LfBranch lfBranch = actionElement.getLfBranch(); + ClosedBranchSide1DcFlowEquationTerm p1 = actionElement.getLfBranchEquation(); + + double newAlpha = 0d; + double oldPower = 0d; + double newPower = 0d; + if (actionElement instanceof ComputedTapPositionChangeElement) { + TapPositionChange tapPositionChange = ((ComputedTapPositionChangeElement) actionElement).getTapPositionChange(); + PiModel newPiModel = tapPositionChange.getNewPiModel(); + newAlpha = newPiModel.getA1(); + oldPower = calculatePower(lfBranch); + newPower = calculatePower(newPiModel); + } else if (actionElement instanceof ComputedSwitchBranchElement) { + if (((ComputedSwitchBranchElement) actionElement).isEnabled()) { + newPower = calculatePower(lfBranch); + } else { + oldPower = calculatePower(lfBranch); + } + } - PiModel newPiModel = tapPositionChangeElement.getTapPositionChange().getNewPiModel(); - double newAlpha = newPiModel.getA1(); rhs.set(i, 0, states.get(p1.getPh1Var().getRow(), columnState) - states.get(p1.getPh2Var().getRow(), columnState) + newAlpha); // loop on contingencies to fill bottom-left quadrant of the matrix @@ -220,12 +251,12 @@ private void setAlphas(DenseMatrix states, int columnState) { } // loop on actions to fill bottom-right quadrant of the matrix - for (ComputedTapPositionChangeElement tapPositionChangeElement2 : tapPositionChangeElements) { - int j = contingencyElements.size() + tapPositionChangeElement2.getLocalIndex(); + for (ComputedElement actionElement2 : actionElements) { + int j = contingencyElements.size() + actionElement2.getLocalIndex(); // if on the diagonal of the matrix, add variation of reactance - double deltaX = (i == j) ? 1d / (calculatePower(lfBranch) - calculatePower(newPiModel)) : 0d; - double value = deltaX - (tapPositionChangeStates.get(p1.getPh1Var().getRow(), tapPositionChangeElement2.getComputedElementIndex()) - - tapPositionChangeStates.get(p1.getPh2Var().getRow(), tapPositionChangeElement2.getComputedElementIndex())); + double deltaX = (i == j) ? 1d / (oldPower - newPower) : 0d; + double value = deltaX - (actionsStates.get(p1.getPh1Var().getRow(), actionElement2.getComputedElementIndex()) + - actionsStates.get(p1.getPh2Var().getRow(), actionElement2.getComputedElementIndex())); matrix.set(i, j, value); } } @@ -233,7 +264,7 @@ private void setAlphas(DenseMatrix states, int columnState) { lu.solve(rhs); // rhs now contains state matrix } contingencyElements.forEach(element -> element.setAlphaForWoodburyComputation(rhs.get(element.getLocalIndex(), 0))); - tapPositionChangeElements.forEach(element -> element.setAlphaForWoodburyComputation(rhs.get(contingencyElements.size() + element.getLocalIndex(), 0))); + actionElements.forEach(element -> element.setAlphaForWoodburyComputation(rhs.get(contingencyElements.size() + element.getLocalIndex(), 0))); } } @@ -268,9 +299,9 @@ public void toPostContingencyAndOperatorStrategyStates(double[] preContingencySt postContingencyAndOperatorStrategyValue += contingencyElement.getAlphaForWoodburyComputation() * contingenciesStates.get(rowIndex, contingencyElement.getComputedElementIndex()); } - for (ComputedTapPositionChangeElement tapPositionChangeElement : tapPositionChangeElements) { - postContingencyAndOperatorStrategyValue += tapPositionChangeElement.getAlphaForWoodburyComputation() - * tapPositionChangeStates.get(rowIndex, tapPositionChangeElement.getComputedElementIndex()); + for (ComputedElement actionElement : actionElements) { + postContingencyAndOperatorStrategyValue += actionElement.getAlphaForWoodburyComputation() + * actionsStates.get(rowIndex, actionElement.getComputedElementIndex()); } preContingencyStates[rowIndex] = postContingencyAndOperatorStrategyValue; } diff --git a/src/main/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysis.java index 4f812249fb..676b99cbd0 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysis.java @@ -10,6 +10,8 @@ import com.google.common.base.Stopwatch; import com.powsybl.action.Action; import com.powsybl.action.PhaseTapChangerTapPositionAction; +import com.powsybl.action.SwitchAction; +import com.powsybl.action.TerminalsConnectionAction; import com.powsybl.commons.report.ReportNode; import com.powsybl.contingency.Contingency; import com.powsybl.iidm.network.Network; @@ -28,9 +30,6 @@ import com.powsybl.openloadflow.network.*; import com.powsybl.openloadflow.network.impl.Networks; import com.powsybl.openloadflow.network.impl.PropagatedContingency; -import com.powsybl.openloadflow.dc.fastdc.ComputedContingencyElement; -import com.powsybl.openloadflow.dc.fastdc.ConnectivityBreakAnalysis; -import com.powsybl.openloadflow.dc.fastdc.WoodburyEngine; import com.powsybl.openloadflow.util.PerUnit; import com.powsybl.openloadflow.util.Reports; import com.powsybl.security.LimitViolationsResult; @@ -98,15 +97,17 @@ private double[] calculatePostContingencyStates(DcLoadFlowContext loadFlowContex private double[] calculatePostContingencyAndOperatorStrategyStates(DcLoadFlowContext loadFlowContext, DenseMatrix contingenciesStates, double[] flowStates, PropagatedContingency contingency, Map contingencyElementByBranch, Set disabledBuses, Set elementsToReconnect, Set partialDisabledBranches, - List operatorStrategyLfActions, Map tapPositionChangeElementByBranch, + List operatorStrategyLfActions, Map actionElementByBranch, DenseMatrix actionsStates, ReportNode reportNode) { List contingencyElements = contingency.getBranchIdsToOpen().keySet().stream() .filter(element -> !elementsToReconnect.contains(element)) .map(contingencyElementByBranch::get) .collect(Collectors.toList()); - List actionElements = operatorStrategyLfActions.stream() - .map(lfAction -> lfAction.getTapPositionChange().getBranch().getId()) - .map(tapPositionChangeElementByBranch::get) + List actionElements = operatorStrategyLfActions.stream() + // TODO : refactor + .map(lfAction -> lfAction.getTapPositionChange() != null ? lfAction.getTapPositionChange().getBranch().getId() + : (lfAction.getDisabledBranch() != null ? lfAction.getDisabledBranch().getId() : lfAction.getEnabledBranch().getId())) + .map(actionElementByBranch::get) .collect(Collectors.toList()); var lfNetwork = loadFlowContext.getNetwork(); @@ -162,7 +163,7 @@ private double[] calculatePostContingencyStatesForAContingencyBreakingConnectivi */ private double[] calculatePostContingencyAndOperatorStrategyStatesForAContingencyBreakingConnectivity(ConnectivityBreakAnalysis.ConnectivityAnalysisResult connectivityAnalysisResult, DcLoadFlowContext loadFlowContext, Map contingencyElementByBranch, double[] flowStates, DenseMatrix contingenciesStates, - List operatorStrategyLfActions, Map tapPositionChangeElementByBranch, DenseMatrix actionsStates, ReportNode reportNode) { + List operatorStrategyLfActions, Map actionElementsByBranch, DenseMatrix actionsStates, ReportNode reportNode) { PropagatedContingency contingency = connectivityAnalysisResult.getPropagatedContingency(); Set disabledBuses = connectivityAnalysisResult.getDisabledBuses(); @@ -178,15 +179,16 @@ private double[] calculatePostContingencyAndOperatorStrategyStatesForAContingenc return calculatePostContingencyAndOperatorStrategyStates(loadFlowContext, contingenciesStates, flowStates, contingency, contingencyElementByBranch, disabledBuses, connectivityAnalysisResult.getElementsToReconnect(), - connectivityAnalysisResult.getPartialDisabledBranches(), operatorStrategyLfActions, tapPositionChangeElementByBranch, actionsStates, reportNode); + connectivityAnalysisResult.getPartialDisabledBranches(), operatorStrategyLfActions, actionElementsByBranch, actionsStates, reportNode); } private void filterActions(List actions) { actions.stream() - .filter(action -> !(action instanceof PhaseTapChangerTapPositionAction)) + .filter(action -> !(action instanceof PhaseTapChangerTapPositionAction + || action instanceof TerminalsConnectionAction || action instanceof SwitchAction)) .findAny() .ifPresent(e -> { - throw new IllegalStateException("For now, only PhaseTapChangerTapPositionAction is allowed in WoodburyDcSecurityAnalysis"); + throw new IllegalStateException("For now, only PhaseTapChangerTapPositionAction, TerminalsConnectionAction and SwitchAction are allowed in WoodburyDcSecurityAnalysis"); }); } @@ -349,19 +351,28 @@ private void addPostContingencyAndOperatorStrategyResults(DcLoadFlowContext cont }); } - private static Map createTapPositionChangeElementsIndexByBranchId(Map lfActionById, EquationSystem equationSystem) { - Map computedTapPositionChangeElements = lfActionById.values().stream() - .filter(lfAction -> lfAction.getTapPositionChange() != null) - .map(lfAction -> new ComputedTapPositionChangeElement(lfAction.getTapPositionChange(), equationSystem)) - .filter(computedTapPositionChangeElement -> computedTapPositionChangeElement.getLfBranchEquation() != null) + private static Map createActionElementsIndexByBranchId(Map lfActionById, EquationSystem equationSystem) { + Map computedElements = lfActionById.values().stream() + .map(lfAction -> { + if (lfAction.getTapPositionChange() != null) { + return new ComputedTapPositionChangeElement(lfAction.getTapPositionChange(), equationSystem); + } else if (lfAction.getEnabledBranch() != null) { + return new ComputedSwitchBranchElement(lfAction.getEnabledBranch(), true, equationSystem); + } else if (lfAction.getDisabledBranch() != null) { + return new ComputedSwitchBranchElement(lfAction.getDisabledBranch(), false, equationSystem); + } else { + throw new IllegalStateException("Only tap position change and branch enabling/disabling are supported"); + } + }) + .filter(computedElement -> computedElement.getLfBranchEquation() != null) .collect(Collectors.toMap( - computedTapPositionChangeElement -> computedTapPositionChangeElement.getLfBranch().getId(), - computedTapPositionChangeElement -> computedTapPositionChangeElement, + computedElement -> computedElement.getLfBranch().getId(), + computedElement -> computedElement, (existing, replacement) -> existing, LinkedHashMap::new )); - ComputedElement.setComputedElementIndexes(computedTapPositionChangeElements.values()); - return computedTapPositionChangeElements; + ComputedElement.setComputedElementIndexes(computedElements.values()); + return computedElements; } @Override @@ -417,8 +428,8 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List tapPositionChangeElementsByBranchId = createTapPositionChangeElementsIndexByBranchId(lfActionById, context.getEquationSystem()); - DenseMatrix actionsStates = ComputedElement.calculateElementsStates(context, tapPositionChangeElementsByBranchId.values()); + Map actionElementsIndexByBranchId = createActionElementsIndexByBranchId(lfActionById, context.getEquationSystem()); + DenseMatrix actionsStates = ComputedElement.calculateElementsStates(context, actionElementsIndexByBranchId.values()); // save base state for later restoration after each contingency/action NetworkState networkState = NetworkState.save(lfNetwork); @@ -434,7 +445,7 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List, double[]> toPostContingencyAndOperatorStrategyStates = operatorStrategyLfActions -> calculatePostContingencyAndOperatorStrategyStates(context, connectivityBreakAnalysisResults.contingenciesStates(), workingContingencyStates, nonBreakingConnectivityContingency, connectivityBreakAnalysisResults.contingencyElementByBranch(), Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), - operatorStrategyLfActions, tapPositionChangeElementsByBranchId, actionsStates, reportNode); + operatorStrategyLfActions, actionElementsIndexByBranchId, actionsStates, reportNode); // runnable to restore pre contingency states, after modifications applied to the lfNetwork Runnable restorePreContingencyStates = () -> { // update workingContingencyStates as it may have been updated by post contingency states calculation @@ -459,7 +470,7 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List, double[]> toPostContingencyAndOperatorStrategyStates = operatorStrategyLfActions -> calculatePostContingencyAndOperatorStrategyStatesForAContingencyBreakingConnectivity(connectivityAnalysisResult, context, connectivityBreakAnalysisResults.contingencyElementByBranch(), workingContingencyStates, connectivityBreakAnalysisResults.contingenciesStates(), - operatorStrategyLfActions, tapPositionChangeElementsByBranchId, actionsStates, reportNode); + operatorStrategyLfActions, actionElementsIndexByBranchId, actionsStates, reportNode); // runnable to restore pre contingency states, after modifications applied to the lfNetwork // no need to update workingContingencyStates as an override of flow states will be computed Runnable restorePreContingencyStates = networkState::restore; From 534b2d3c042ec14628d8d1348fbf4dedd9ed97e3 Mon Sep 17 00:00:00 2001 From: p-arvy Date: Fri, 13 Dec 2024 14:37:46 +0100 Subject: [PATCH 3/4] Refactor calculation of rhs/matrix values in WoodburyEngine Signed-off-by: p-arvy --- .../dc/fastdc/WoodburyEngine.java | 112 +++++++++--------- ...buryDcSecurityAnalysisWithActionsTest.java | 7 +- 2 files changed, 56 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/dc/fastdc/WoodburyEngine.java b/src/main/java/com/powsybl/openloadflow/dc/fastdc/WoodburyEngine.java index de7a0b8a1b..d6cb4c81fa 100644 --- a/src/main/java/com/powsybl/openloadflow/dc/fastdc/WoodburyEngine.java +++ b/src/main/java/com/powsybl/openloadflow/dc/fastdc/WoodburyEngine.java @@ -141,6 +141,50 @@ private double calculatePower(PiModel piModel) { return AbstractClosedBranchDcFlowEquationTerm.computePower(creationParameters.isUseTransformerRatio(), creationParameters.getDcApproximationType(), piModel); } + // TODO : refactor + double getRhsValue(DenseMatrix states, ClosedBranchSide1DcFlowEquationTerm p1, int columnState, ComputedElement computedElement) { + double newAlpha = 0; + if (computedElement instanceof ComputedTapPositionChangeElement) { + TapPositionChange tapPositionChange = ((ComputedTapPositionChangeElement) computedElement).getTapPositionChange(); + PiModel newPiModel = tapPositionChange.getNewPiModel(); + newAlpha = newPiModel.getA1(); + } else if (computedElement instanceof ComputedSwitchBranchElement) { + // FIXME : need to add the new alpha + newAlpha = computedElement.getLfBranch().getPiModel().getA1(); + } + return states.get(p1.getPh1Var().getRow(), columnState) - states.get(p1.getPh2Var().getRow(), columnState) + newAlpha; + } + + // TODO : refactor + double getMatrixValue(LfBranch lfBranch, ClosedBranchSide1DcFlowEquationTerm p1, ComputedElement element, boolean onDiagonal) { + if (element instanceof ComputedContingencyElement) { + double deltaX = onDiagonal ? 1d / calculatePower(lfBranch) : 0d; + return deltaX - (contingenciesStates.get(p1.getPh1Var().getRow(), element.getComputedElementIndex()) + - contingenciesStates.get(p1.getPh2Var().getRow(), element.getComputedElementIndex())); + } else { + double deltaX = 0; + if (onDiagonal) { + double oldPower = 0d; + double newPower = 0d; + if (element instanceof ComputedTapPositionChangeElement) { + TapPositionChange tapPositionChange = ((ComputedTapPositionChangeElement) element).getTapPositionChange(); + PiModel newPiModel = tapPositionChange.getNewPiModel(); + oldPower = calculatePower(lfBranch); + newPower = calculatePower(newPiModel); + } else if (element instanceof ComputedSwitchBranchElement) { + if (((ComputedSwitchBranchElement) element).isEnabled()) { + newPower = calculatePower(lfBranch); + } else { + oldPower = calculatePower(lfBranch); + } + } + deltaX = 1d / (oldPower - newPower); + } + return deltaX - (actionsStates.get(p1.getPh1Var().getRow(), element.getComputedElementIndex()) + - actionsStates.get(p1.getPh2Var().getRow(), element.getComputedElementIndex())); + } + } + /** * Compute the flow transfer factors needed to calculate the post-contingency state values. */ @@ -151,9 +195,8 @@ private void setAlphas(DenseMatrix states, int columnState) { ClosedBranchSide1DcFlowEquationTerm p1 = element.getLfBranchEquation(); // we solve a*alpha = b - double a = 1d / calculatePower(lfBranch) - (contingenciesStates.get(p1.getPh1Var().getRow(), element.getComputedElementIndex()) - - contingenciesStates.get(p1.getPh2Var().getRow(), element.getComputedElementIndex())); - double b = states.get(p1.getPh1Var().getRow(), columnState) - states.get(p1.getPh2Var().getRow(), columnState); + double a = getMatrixValue(lfBranch, p1, element, true); + double b = getRhsValue(states, p1, columnState, element); element.setAlphaForWoodburyComputation(b / a); } else if (contingencyElements.isEmpty() && actionElements.size() == 1) { // TODO : case when there is only one switching action, for now, works only when there is only one action on pst @@ -161,29 +204,8 @@ private void setAlphas(DenseMatrix states, int columnState) { LfBranch lfBranch = element.getLfBranch(); ClosedBranchSide1DcFlowEquationTerm p1 = element.getLfBranchEquation(); - double newAlpha = 0d; - double oldPower = 0d; - double newPower = 0d; - if (element instanceof ComputedTapPositionChangeElement) { - TapPositionChange tapPositionChange = ((ComputedTapPositionChangeElement) element).getTapPositionChange(); - PiModel newPiModel = tapPositionChange.getNewPiModel(); - newAlpha = newPiModel.getA1(); - oldPower = calculatePower(lfBranch); - newPower = calculatePower(newPiModel); - } else if (element instanceof ComputedSwitchBranchElement) { - if (((ComputedSwitchBranchElement) element).isEnabled()) { - newPower = calculatePower(lfBranch); - } else { - oldPower = calculatePower(lfBranch); - } - } - - // we solve a*alpha = b - double deltaX = 1d / (oldPower - newPower); - double a = deltaX - (actionsStates.get(p1.getPh1Var().getRow(), element.getComputedElementIndex()) - - actionsStates.get(p1.getPh2Var().getRow(), element.getComputedElementIndex())); - - double b = states.get(p1.getPh1Var().getRow(), columnState) - states.get(p1.getPh2Var().getRow(), columnState) + newAlpha; + double a = getMatrixValue(lfBranch, p1, element, true); + double b = getRhsValue(states, p1, columnState, element); element.setAlphaForWoodburyComputation(b / a); } else { // set local indexes of computed elements to use them in small matrix computation @@ -197,23 +219,19 @@ private void setAlphas(DenseMatrix states, int columnState) { int i = contingencyElement.getLocalIndex(); LfBranch lfBranch = contingencyElement.getLfBranch(); ClosedBranchSide1DcFlowEquationTerm p1 = contingencyElement.getLfBranchEquation(); - rhs.set(i, 0, states.get(p1.getPh1Var().getRow(), columnState) - states.get(p1.getPh2Var().getRow(), columnState)); + rhs.set(i, 0, getRhsValue(states, p1, columnState, contingencyElement)); // loop on contingencies to fill top-left quadrant of the matrix for (ComputedContingencyElement contingencyElement2 : contingencyElements) { int j = contingencyElement2.getLocalIndex(); - // if on the diagonal of the matrix, add variation of reactance - double deltaX = (i == j) ? 1d / calculatePower(lfBranch) : 0d; - double value = deltaX - (contingenciesStates.get(p1.getPh1Var().getRow(), contingencyElement2.getComputedElementIndex()) - - contingenciesStates.get(p1.getPh2Var().getRow(), contingencyElement2.getComputedElementIndex())); + double value = getMatrixValue(lfBranch, p1, contingencyElement2, i == j); matrix.set(i, j, value); } // loop on actions to fill top-right quadrant of the matrix for (ComputedElement actionElement : actionElements) { int j = contingencyElements.size() + actionElement.getLocalIndex(); - double value = -(actionsStates.get(p1.getPh1Var().getRow(), actionElement.getComputedElementIndex()) - - actionsStates.get(p1.getPh2Var().getRow(), actionElement.getComputedElementIndex())); + double value = getMatrixValue(lfBranch, p1, actionElement, false); matrix.set(i, j, value); } } @@ -222,41 +240,19 @@ private void setAlphas(DenseMatrix states, int columnState) { int i = contingencyElements.size() + actionElement.getLocalIndex(); LfBranch lfBranch = actionElement.getLfBranch(); ClosedBranchSide1DcFlowEquationTerm p1 = actionElement.getLfBranchEquation(); - - double newAlpha = 0d; - double oldPower = 0d; - double newPower = 0d; - if (actionElement instanceof ComputedTapPositionChangeElement) { - TapPositionChange tapPositionChange = ((ComputedTapPositionChangeElement) actionElement).getTapPositionChange(); - PiModel newPiModel = tapPositionChange.getNewPiModel(); - newAlpha = newPiModel.getA1(); - oldPower = calculatePower(lfBranch); - newPower = calculatePower(newPiModel); - } else if (actionElement instanceof ComputedSwitchBranchElement) { - if (((ComputedSwitchBranchElement) actionElement).isEnabled()) { - newPower = calculatePower(lfBranch); - } else { - oldPower = calculatePower(lfBranch); - } - } - - rhs.set(i, 0, states.get(p1.getPh1Var().getRow(), columnState) - states.get(p1.getPh2Var().getRow(), columnState) + newAlpha); + rhs.set(i, 0, getRhsValue(states, p1, columnState, actionElement)); // loop on contingencies to fill bottom-left quadrant of the matrix for (ComputedContingencyElement contingencyElement : contingencyElements) { int j = contingencyElement.getLocalIndex(); - double value = -(contingenciesStates.get(p1.getPh1Var().getRow(), contingencyElement.getComputedElementIndex()) - - contingenciesStates.get(p1.getPh2Var().getRow(), contingencyElement.getComputedElementIndex())); + double value = getMatrixValue(lfBranch, p1, contingencyElement, false); matrix.set(i, j, value); } // loop on actions to fill bottom-right quadrant of the matrix for (ComputedElement actionElement2 : actionElements) { int j = contingencyElements.size() + actionElement2.getLocalIndex(); - // if on the diagonal of the matrix, add variation of reactance - double deltaX = (i == j) ? 1d / (oldPower - newPower) : 0d; - double value = deltaX - (actionsStates.get(p1.getPh1Var().getRow(), actionElement2.getComputedElementIndex()) - - actionsStates.get(p1.getPh2Var().getRow(), actionElement2.getComputedElementIndex())); + double value = getMatrixValue(lfBranch, p1, actionElement2, i == j); matrix.set(i, j, value); } } diff --git a/src/test/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysisWithActionsTest.java b/src/test/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysisWithActionsTest.java index 73b4b0970f..616a4eef14 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysisWithActionsTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysisWithActionsTest.java @@ -448,7 +448,7 @@ void testFastDcSaWithActionNotOnPst() { CompletionException thrown = assertThrows(CompletionException.class, () -> runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, operatorStrategies, actions, ReportNode.NO_OP)); - assertTrue(thrown.getCause().getMessage().contains("For now, only PhaseTapChangerTapPositionAction and TerminalsConnectionAction are allowed in WoodburyDcSecurityAnalysis")); + assertTrue(thrown.getCause().getMessage().contains("For now, only PhaseTapChangerTapPositionAction, TerminalsConnectionAction and SwitchAction are allowed in WoodburyDcSecurityAnalysis")); } @Test @@ -513,6 +513,7 @@ void testFastSaDcTransformerDisconnectionAction() { assertEquals(100.0, getOperatorStrategyResult(result, "strategyOpenPS1").getNetworkResult().getBranchResult("L2").getP1(), LoadFlowAssert.DELTA_POWER); } + // TODO : this test breaks connectivity and should not work ! So, it seems to work as expected @Test void testFastSaDcTransformerDisconnectionActionBreakingConnectivity() { Network network = PhaseControlFactory.createNetworkWith3Buses(); @@ -526,7 +527,6 @@ void testFastSaDcTransformerDisconnectionActionBreakingConnectivity() { SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); LoadFlowParameters parameters = new LoadFlowParameters(); parameters.setDc(true); - parameters.setDistributedSlack(true); securityAnalysisParameters.setLoadFlowParameters(parameters); OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters(); openSecurityAnalysisParameters.setDcFastMode(true); @@ -639,7 +639,4 @@ void testDcSecurityAnalysisWithOperatorStrategy() { assertEquals(network.getLine("L2").getTerminal1().getP(), getOperatorStrategyResult(result, "strategyL3").getNetworkResult().getBranchResult("L2").getP1(), LoadFlowAssert.DELTA_POWER); assertEquals(network.getLine("L1").getTerminal1().getP(), getOperatorStrategyResult(result, "strategyL3").getNetworkResult().getBranchResult("L1").getP1(), LoadFlowAssert.DELTA_POWER); } - - - // FIXME : cases with actions that modify the connectivity (i.e. add network or remove some part are) are not yet handled } From 99ae55f9341f4e8aede7ffe0735808ada81293ae Mon Sep 17 00:00:00 2001 From: p-arvy Date: Fri, 13 Dec 2024 15:25:26 +0100 Subject: [PATCH 4/4] Add case with transformer lost as an action, and non null alpha on current tap Signed-off-by: p-arvy --- .../dc/fastdc/WoodburyEngine.java | 17 ++- .../OpenSecurityAnalysisWithActionsTest.java | 64 +++++++-- ...buryDcSecurityAnalysisWithActionsTest.java | 125 +----------------- 3 files changed, 70 insertions(+), 136 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/dc/fastdc/WoodburyEngine.java b/src/main/java/com/powsybl/openloadflow/dc/fastdc/WoodburyEngine.java index d6cb4c81fa..7be8ea18cb 100644 --- a/src/main/java/com/powsybl/openloadflow/dc/fastdc/WoodburyEngine.java +++ b/src/main/java/com/powsybl/openloadflow/dc/fastdc/WoodburyEngine.java @@ -72,7 +72,7 @@ public static double[] runDcLoadFlowWithModifiedTargetVector(DcLoadFlowContext l * A simplified version of DcLoadFlowEngine that supports on the fly bus and branch disabling, and pst actions. * Note that it does not update the state vector and the network at the end (because we don't need it to just evaluate a few equations). */ - public static double[] runDcLoadFlowWithModifiedTargetVector(DcLoadFlowContext loadFlowContext, DisabledNetwork disabledNetwork, ReportNode reportNode, List pstActions) { + public static double[] runDcLoadFlowWithModifiedTargetVector(DcLoadFlowContext loadFlowContext, DisabledNetwork disabledNetwork, ReportNode reportNode, List lfActions) { Collection remainingBuses; if (disabledNetwork.getBuses().isEmpty()) { remainingBuses = loadFlowContext.getNetwork().getBuses(); @@ -109,9 +109,17 @@ public static double[] runDcLoadFlowWithModifiedTargetVector(DcLoadFlowContext l .forEach(column -> targetVectorArray[column] = 0); } - if (!pstActions.isEmpty()) { + if (!lfActions.isEmpty()) { + // set transformer phase shift to 0 for disconnected phase tap changers + lfActions.stream() + .map(LfAction::getDisabledBranch) + .filter(Objects::nonNull) + .flatMap(lfBranch -> loadFlowContext.getEquationSystem().getEquation(lfBranch.getNum(), DcEquationType.BRANCH_TARGET_ALPHA1).stream()) + .map(Equation::getColumn) + .forEach(column -> targetVectorArray[column] = 0); + // set transformer phase shift to new shifting value - pstActions.stream() + lfActions.stream() .map(LfAction::getTapPositionChange) .filter(Objects::nonNull) .forEach(tapPositionChange -> { @@ -148,8 +156,7 @@ private double calculatePower(PiModel piModel) { TapPositionChange tapPositionChange = ((ComputedTapPositionChangeElement) computedElement).getTapPositionChange(); PiModel newPiModel = tapPositionChange.getNewPiModel(); newAlpha = newPiModel.getA1(); - } else if (computedElement instanceof ComputedSwitchBranchElement) { - // FIXME : need to add the new alpha + } else if (computedElement instanceof ComputedSwitchBranchElement && ((ComputedSwitchBranchElement) computedElement).isEnabled()) { newAlpha = computedElement.getLfBranch().getPiModel().getA1(); } return states.get(p1.getPh1Var().getRow(), columnState) - states.get(p1.getPh2Var().getRow(), columnState) + newAlpha; diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisWithActionsTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisWithActionsTest.java index ba9f4c15ba..61d22bebfe 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisWithActionsTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisWithActionsTest.java @@ -628,8 +628,9 @@ void testCheckActions() { assertEquals("Operator strategy 'strategy6' is associated to contingency 'y' but this contingency is not present in the list", exception.getCause().getMessage()); } - @Test - void testDcSecurityAnalysisWithOperatorStrategy() { + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void testDcSecurityAnalysisWithOperatorStrategy(boolean dcFastMode) { GraphConnectivityFactory connectivityFactory = new NaiveGraphConnectivityFactory<>(LfBus::getNum); securityAnalysisProvider = new OpenSecurityAnalysisProvider(matrixFactory, connectivityFactory); @@ -664,6 +665,9 @@ void testDcSecurityAnalysisWithOperatorStrategy() { setSlackBusId(parameters, "VL2_0"); SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); securityAnalysisParameters.setLoadFlowParameters(parameters); + OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters(); + openSecurityAnalysisParameters.setDcFastMode(dcFastMode); + securityAnalysisParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters); SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, operatorStrategies, actions, ReportNode.NO_OP); @@ -690,8 +694,9 @@ void testDcSecurityAnalysisWithOperatorStrategy() { assertEquals(300.0, getOperatorStrategyResult(result, "strategyL2").getNetworkResult().getBranchResult("L3").getP1(), LoadFlowAssert.DELTA_POWER); } - @Test - void testSaDcLineConnectionAction() { + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void testSaDcLineDisconnectionAction(boolean dcFastMode) { Network network = FourBusNetworkFactory.create(); List contingencies = Stream.of("l14") .map(id -> new Contingency(id, new BranchContingency(id))) @@ -706,6 +711,9 @@ void testSaDcLineConnectionAction() { parameters.setDc(true); SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); securityAnalysisParameters.setLoadFlowParameters(parameters); + OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters(); + openSecurityAnalysisParameters.setDcFastMode(dcFastMode); + securityAnalysisParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters); SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, operatorStrategies, actions, ReportNode.NO_OP); @@ -715,20 +723,34 @@ void testSaDcLineConnectionAction() { BranchResult brl23 = resultStratL1.getNetworkResult().getBranchResult("l23"); BranchResult brl34 = resultStratL1.getNetworkResult().getBranchResult("l34"); - parameters.setDc(false); + assertEquals(2.0, brl12.getP1(), LoadFlowAssert.DELTA_POWER); + assertEquals(3.0, brl23.getP1(), LoadFlowAssert.DELTA_POWER); + assertEquals(-1.0, brl34.getP1(), LoadFlowAssert.DELTA_POWER); + } + + @Test + void testSaAcLineDisconnectionAction() { + Network network = FourBusNetworkFactory.create(); + List contingencies = Stream.of("l14") + .map(id -> new Contingency(id, new BranchContingency(id))) + .toList(); + + List actions = List.of(new TerminalsConnectionAction("openLine", "l13", true)); + List operatorStrategies = List.of(new OperatorStrategy("strategyL1", ContingencyContext.specificContingency("l14"), new TrueCondition(), List.of("openLine"))); + List monitors = createAllBranchesMonitors(network); + + LoadFlowParameters parameters = new LoadFlowParameters(); + parameters.setDistributedSlack(false); SecurityAnalysisParameters securityAnalysisParametersAc = new SecurityAnalysisParameters(); securityAnalysisParametersAc.setLoadFlowParameters(parameters); SecurityAnalysisResult resultAc = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParametersAc, operatorStrategies, actions, ReportNode.NO_OP); + OperatorStrategyResult resultStratL1Ac = getOperatorStrategyResult(resultAc, "strategyL1"); BranchResult brl12Ac = resultStratL1Ac.getNetworkResult().getBranchResult("l12"); BranchResult brl23Ac = resultStratL1Ac.getNetworkResult().getBranchResult("l23"); BranchResult brl34Ac = resultStratL1Ac.getNetworkResult().getBranchResult("l34"); - assertEquals(2.0, brl12.getP1(), LoadFlowAssert.DELTA_POWER); - assertEquals(3.0, brl23.getP1(), LoadFlowAssert.DELTA_POWER); - assertEquals(-1.0, brl34.getP1(), LoadFlowAssert.DELTA_POWER); - assertEquals(2.0, brl12Ac.getP1(), LoadFlowAssert.DELTA_POWER); assertEquals(3.0, brl23Ac.getP1(), LoadFlowAssert.DELTA_POWER); assertEquals(-1.0, brl34Ac.getP1(), LoadFlowAssert.DELTA_POWER); @@ -1558,8 +1580,9 @@ void testVSCLossSetpoint(boolean withFictiveLoad) { assertEquals(-200.0, getOperatorStrategyResult(result, "strategy").getNetworkResult().getBranchResult("l34").getP1(), LoadFlowAssert.DELTA_POWER); } - @Test - void testTerminalsConnectionAction() { + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void testDcTerminalsConnectionAction(boolean dcFastMode) { Network network = FourBusNetworkFactory.create(); network.getLine("l23").getTerminal1().disconnect(); network.getLine("l23").getTerminal2().disconnect(); @@ -1576,6 +1599,9 @@ void testTerminalsConnectionAction() { parameters.setDc(true); SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); securityAnalysisParameters.setLoadFlowParameters(parameters); + OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters(); + openSecurityAnalysisParameters.setDcFastMode(dcFastMode); + securityAnalysisParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters); SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, operatorStrategies, actions, ReportNode.NO_OP); @@ -1584,10 +1610,22 @@ void testTerminalsConnectionAction() { assertEquals(0.333, dcStrategyResult.getNetworkResult().getBranchResult("l12").getP1(), LoadFlowAssert.DELTA_POWER); assertEquals(1.333, dcStrategyResult.getNetworkResult().getBranchResult("l23").getP1(), LoadFlowAssert.DELTA_POWER); assertEquals(-1.0, dcStrategyResult.getNetworkResult().getBranchResult("l34").getP1(), LoadFlowAssert.DELTA_POWER); + } + + @Test + void testAcTerminalsConnectionAction() { + Network network = FourBusNetworkFactory.create(); + network.getLine("l23").getTerminal1().disconnect(); + network.getLine("l23").getTerminal2().disconnect(); + List contingencies = Stream.of("l14") + .map(id -> new Contingency(id, new BranchContingency(id))) + .toList(); + + List actions = List.of(new TerminalsConnectionAction("closeLine", "l23", false)); + List operatorStrategies = List.of(new OperatorStrategy("strategyL1", ContingencyContext.specificContingency("l14"), new TrueCondition(), List.of("closeLine"))); + List monitors = createAllBranchesMonitors(network); - parameters.setDc(false); SecurityAnalysisParameters securityAnalysisParametersAc = new SecurityAnalysisParameters(); - securityAnalysisParametersAc.setLoadFlowParameters(parameters); SecurityAnalysisResult resultAc = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParametersAc, operatorStrategies, actions, ReportNode.NO_OP); OperatorStrategyResult acStrategyResult = getOperatorStrategyResult(resultAc, "strategyL1"); diff --git a/src/test/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysisWithActionsTest.java b/src/test/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysisWithActionsTest.java index 616a4eef14..b369befc97 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysisWithActionsTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/WoodburyDcSecurityAnalysisWithActionsTest.java @@ -7,7 +7,10 @@ */ package com.powsybl.openloadflow.sa; -import com.powsybl.action.*; +import com.powsybl.action.Action; +import com.powsybl.action.GeneratorActionBuilder; +import com.powsybl.action.PhaseTapChangerTapPositionAction; +import com.powsybl.action.TerminalsConnectionAction; import com.powsybl.commons.report.ReportNode; import com.powsybl.contingency.BranchContingency; import com.powsybl.contingency.Contingency; @@ -16,8 +19,6 @@ import com.powsybl.iidm.network.Network; import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.openloadflow.OpenLoadFlowParameters; -import com.powsybl.openloadflow.network.FourBusNetworkFactory; -import com.powsybl.openloadflow.network.NodeBreakerNetworkFactory; import com.powsybl.openloadflow.network.PhaseControlFactory; import com.powsybl.openloadflow.network.SlackBusSelectionMode; import com.powsybl.openloadflow.util.LoadFlowAssert; @@ -35,8 +36,6 @@ import java.util.List; import java.util.concurrent.CompletionException; -import java.util.stream.Collectors; -import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.*; @@ -439,7 +438,7 @@ void testFastSaDcN2ContingencyOneTapPositionChange(boolean dcFastMode) { } @Test - void testFastDcSaWithActionNotOnPst() { + void testFastDcSaWithUnsupportedAction() { Network network = PhaseControlFactory.createWithOneT2wtTwoLines(); List monitors = createAllBranchesMonitors(network); List contingencies = List.of(new Contingency("contingencyLD2", List.of(new LoadContingency("LD2")))); @@ -451,39 +450,6 @@ void testFastDcSaWithActionNotOnPst() { assertTrue(thrown.getCause().getMessage().contains("For now, only PhaseTapChangerTapPositionAction, TerminalsConnectionAction and SwitchAction are allowed in WoodburyDcSecurityAnalysis")); } - @Test - void testFastSaDcLineDisconnectionAction() { - Network network = FourBusNetworkFactory.create(); - List contingencies = Stream.of("l14") - .map(id -> new Contingency(id, new BranchContingency(id))) - .collect(Collectors.toList()); - - List actions = List.of(new TerminalsConnectionAction("openLine", "l13", true)); - List operatorStrategies = List.of(new OperatorStrategy("strategyL1", ContingencyContext.specificContingency("l14"), new TrueCondition(), List.of("openLine"))); - List monitors = createAllBranchesMonitors(network); - - LoadFlowParameters parameters = new LoadFlowParameters(); - parameters.setDistributedSlack(true); - parameters.setDc(true); - SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); - securityAnalysisParameters.setLoadFlowParameters(parameters); - OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters(); - openSecurityAnalysisParameters.setDcFastMode(true); - securityAnalysisParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters); - - SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, - operatorStrategies, actions, ReportNode.NO_OP); - - OperatorStrategyResult resultStratL1 = getOperatorStrategyResult(result, "strategyL1"); - BranchResult brl12 = resultStratL1.getNetworkResult().getBranchResult("l12"); - BranchResult brl23 = resultStratL1.getNetworkResult().getBranchResult("l23"); - BranchResult brl34 = resultStratL1.getNetworkResult().getBranchResult("l34"); - - assertEquals(2.0, brl12.getP1(), LoadFlowAssert.DELTA_POWER); - assertEquals(3.0, brl23.getP1(), LoadFlowAssert.DELTA_POWER); - assertEquals(-1.0, brl34.getP1(), LoadFlowAssert.DELTA_POWER); - } - @Test void testFastSaDcTransformerDisconnectionAction() { Network network = PhaseControlFactory.createWithOneT2wtTwoLines(); @@ -507,7 +473,7 @@ void testFastSaDcTransformerDisconnectionAction() { 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(0); + 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); @@ -537,37 +503,6 @@ void testFastSaDcTransformerDisconnectionActionBreakingConnectivity() { assertEquals(100.0, getOperatorStrategyResult(result, "strategyOpenL23").getNetworkResult().getBranchResult("PS1").getP1(), LoadFlowAssert.DELTA_POWER); } - @Test - void testFastSaDcLineConnectionAction() { - Network network = FourBusNetworkFactory.create(); - network.getLine("l23").getTerminal1().disconnect(); - network.getLine("l23").getTerminal2().disconnect(); - List contingencies = Stream.of("l14") - .map(id -> new Contingency(id, new BranchContingency(id))) - .collect(Collectors.toList()); - - List actions = List.of(new TerminalsConnectionAction("closeLine", "l23", false)); - List operatorStrategies = List.of(new OperatorStrategy("strategyL1", ContingencyContext.specificContingency("l14"), new TrueCondition(), List.of("closeLine"))); - List monitors = createAllBranchesMonitors(network); - - LoadFlowParameters parameters = new LoadFlowParameters(); - parameters.setDistributedSlack(true); - parameters.setDc(true); - SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); - securityAnalysisParameters.setLoadFlowParameters(parameters); - OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters(); - openSecurityAnalysisParameters.setDcFastMode(true); - securityAnalysisParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters); - - SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, - operatorStrategies, actions, ReportNode.NO_OP); - OperatorStrategyResult dcStrategyResult = getOperatorStrategyResult(result, "strategyL1"); - - assertEquals(0.333, dcStrategyResult.getNetworkResult().getBranchResult("l12").getP1(), LoadFlowAssert.DELTA_POWER); - assertEquals(1.333, dcStrategyResult.getNetworkResult().getBranchResult("l23").getP1(), LoadFlowAssert.DELTA_POWER); - assertEquals(-1.0, dcStrategyResult.getNetworkResult().getBranchResult("l34").getP1(), LoadFlowAssert.DELTA_POWER); - } - @Test void testFastSaDcTransformerConnectionAction() { // TODO : problem to update a value that is not present here... Big change expected @@ -584,7 +519,7 @@ void testFastSaDcTransformerConnectionAction() { SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); securityAnalysisParameters.setLoadFlowParameters(parameters); OpenSecurityAnalysisParameters openSecurityAnalysisParameters = new OpenSecurityAnalysisParameters(); - openSecurityAnalysisParameters.setDcFastMode(false); + openSecurityAnalysisParameters.setDcFastMode(true); securityAnalysisParameters.addExtension(OpenSecurityAnalysisParameters.class, openSecurityAnalysisParameters); network.getTwoWindingsTransformer("PS1").getTerminal1().disconnect(); @@ -593,50 +528,4 @@ void testFastSaDcTransformerConnectionAction() { operatorStrategies, actions, ReportNode.NO_OP); assertEquals(50.0, getOperatorStrategyResult(result, "strategyClosePS1").getNetworkResult().getBranchResult("L2").getP1(), LoadFlowAssert.DELTA_POWER); } - - @Test - void testDcSecurityAnalysisWithOperatorStrategy() { - Network network = NodeBreakerNetworkFactory.create3Bars(); - network.getSwitch("C1").setOpen(true); - network.getLineStream().forEach(line -> { - if (line.getCurrentLimits1().isPresent()) { - line.getCurrentLimits1().orElseThrow().setPermanentLimit(310); - } - if (line.getCurrentLimits2().isPresent()) { - line.getCurrentLimits2().orElseThrow().setPermanentLimit(310); - } - }); - - List contingencies = Stream.of("L3") - .map(id -> new Contingency(id, new BranchContingency(id))) - .collect(Collectors.toList()); - - // FIXME : add the cases with connectivity modification due to the actions - List actions = List.of(new SwitchAction("action1", "C1", false)); - List operatorStrategies = List.of(new OperatorStrategy("strategyL3", ContingencyContext.specificContingency("L3"), new TrueCondition(), List.of("action1"))); - List monitors = createAllBranchesMonitors(network); - - LoadFlowParameters parameters = new LoadFlowParameters(); - parameters.setDistributedSlack(false); - parameters.setDc(true); - setSlackBusId(parameters, "VL2_0"); - SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters(); - securityAnalysisParameters.setLoadFlowParameters(parameters); - - // verify pre contingency results - SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters, - operatorStrategies, actions, ReportNode.NO_OP); - assertEquals(400.0, result.getPreContingencyResult().getNetworkResult().getBranchResult("L1").getP1(), LoadFlowAssert.DELTA_POWER); - assertEquals(100.0, result.getPreContingencyResult().getNetworkResult().getBranchResult("L2").getP1(), LoadFlowAssert.DELTA_POWER); - assertEquals(100.0, result.getPreContingencyResult().getNetworkResult().getBranchResult("L3").getP1(), LoadFlowAssert.DELTA_POWER); - - // compare post contingency/action results with load flow - network.getLine("L3").disconnect(); - network.getSwitch("C1").setOpen(false); - loadFlowRunner.run(network, parameters); - - // Compare results on the line L2 - assertEquals(network.getLine("L2").getTerminal1().getP(), getOperatorStrategyResult(result, "strategyL3").getNetworkResult().getBranchResult("L2").getP1(), LoadFlowAssert.DELTA_POWER); - assertEquals(network.getLine("L1").getTerminal1().getP(), getOperatorStrategyResult(result, "strategyL3").getNetworkResult().getBranchResult("L1").getP1(), LoadFlowAssert.DELTA_POWER); - } }