From b7063d57c37ad70a404a730e11d75a56353035e5 Mon Sep 17 00:00:00 2001 From: vmouradian Date: Thu, 7 Nov 2024 15:46:38 +0100 Subject: [PATCH 01/10] DC multi slack support Signed-off-by: vmouradian --- .../openloadflow/OpenLoadFlowParameters.java | 2 +- .../openloadflow/dc/DcTargetVector.java | 8 +- .../dc/equations/DcEquationSystemCreator.java | 4 +- .../ac/MultipleSlackBusesTest.java | 91 +++++++++++++++++++ 4 files changed, 101 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java b/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java index e4b3e2d50b..4d1763219d 100644 --- a/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java +++ b/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java @@ -1921,7 +1921,7 @@ public static DcLoadFlowParameters createDcParameters(LoadFlowParameters paramet .setHvdcAcEmulation(parameters.isHvdcAcEmulation()) .setLowImpedanceThreshold(parametersExt.getLowImpedanceThreshold()) .setSvcVoltageMonitoring(false) - .setMaxSlackBusCount(1) + .setMaxSlackBusCount(parametersExt.getMaxSlackBusCount()) .setLinePerUnitMode(parametersExt.getLinePerUnitMode()); var equationSystemCreationParameters = new DcEquationSystemCreationParameters() diff --git a/src/main/java/com/powsybl/openloadflow/dc/DcTargetVector.java b/src/main/java/com/powsybl/openloadflow/dc/DcTargetVector.java index ba1e3a6964..f31fa95945 100644 --- a/src/main/java/com/powsybl/openloadflow/dc/DcTargetVector.java +++ b/src/main/java/com/powsybl/openloadflow/dc/DcTargetVector.java @@ -14,6 +14,7 @@ import com.powsybl.openloadflow.equations.EquationSystem; import com.powsybl.openloadflow.equations.TargetVector; import com.powsybl.openloadflow.network.LfBranch; +import com.powsybl.openloadflow.network.LfBus; import com.powsybl.openloadflow.network.LfNetwork; /** @@ -24,7 +25,12 @@ public class DcTargetVector extends TargetVector public static void init(Equation equation, LfNetwork network, double[] targets) { switch (equation.getType()) { case BUS_TARGET_P: - targets[equation.getColumn()] = network.getBus(equation.getElementNum()).getTargetP(); + LfBus bus = network.getBus(equation.getElementNum()); + targets[equation.getColumn()] = bus.getTargetP(); + // Only used for multi slack (BUS_TARGET_P equation is disabled for first slack bus) + if (bus.isSlack()) { + targets[equation.getColumn()] += DcLoadFlowEngine.getActivePowerMismatch(network.getBuses()) / network.getSlackBuses().size(); + } break; case BUS_TARGET_PHI, diff --git a/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystemCreator.java b/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystemCreator.java index dde572f434..5ef6e96cc4 100644 --- a/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystemCreator.java +++ b/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystemCreator.java @@ -38,7 +38,7 @@ private void createBuses(EquationSystem equation for (LfBus bus : network.getBuses()) { var p = equationSystem.createEquation(bus, DcEquationType.BUS_TARGET_P); bus.setP(p); - if (bus.isSlack()) { + if (bus == network.getSlackBus()) { equationSystem.createEquation(bus, DcEquationType.BUS_TARGET_PHI) .addTerm(equationSystem.getVariable(bus.getNum(), DcVariableType.BUS_PHI).createTerm()); p.setActive(false); @@ -77,7 +77,7 @@ public static void createNonImpedantBranch(EquationSystem slackBusResults = componentResult.getSlackBusResults(); + assertEquals(2, slackBusResults.size()); + assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + assertEquals(-3.5, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + + Line l12A = network.getLine("NHV1_NHV2_1"); + Line l12B = network.getLine("NHV1_NHV2_2"); + TwoWindingsTransformer t2wtGen = network.getTwoWindingsTransformer("NGEN_NHV1"); + TwoWindingsTransformer t2wtLoad = network.getTwoWindingsTransformer("NHV2_NLOAD"); + + assertEquals(301.75, l12A.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); + assertEquals(301.75, l12B.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); + assertEquals(600, t2wtLoad.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); + assertEquals(607, t2wtGen.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); + + parameters.setDistributedSlack(true); + result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + componentResult = result.getComponentResults().get(0); + slackBusResults = componentResult.getSlackBusResults(); + assertEquals(2, slackBusResults.size()); + assertEquals(0, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + assertEquals(0, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + } + + @Test + void dcNonImpedantBranchTest() { + network.getLine("NHV1_NHV2_1") + .setR(0) + .setX(0); + parameters.setDc(true); + LoadFlowResult result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); + List slackBusResults = componentResult.getSlackBusResults(); + assertEquals(2, slackBusResults.size()); + assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + assertEquals(-3.5, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + + Line l12A = network.getLine("NHV1_NHV2_1"); + Line l12B = network.getLine("NHV1_NHV2_2"); + TwoWindingsTransformer t2wtGen = network.getTwoWindingsTransformer("NGEN_NHV1"); + TwoWindingsTransformer t2wtLoad = network.getTwoWindingsTransformer("NHV2_NLOAD"); + + assertEquals(603.5, l12A.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); + assertEquals(0.0, l12B.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); + assertEquals(600, t2wtLoad.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); + assertEquals(607, t2wtGen.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); + + parameters.setDistributedSlack(true); + result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + componentResult = result.getComponentResults().get(0); + slackBusResults = componentResult.getSlackBusResults(); + assertEquals(2, slackBusResults.size()); + assertEquals(0, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + assertEquals(0, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + } + + @Test + void dcMultiSlackWithLoadOnSlackBus() { + parameters.setDc(true); + parametersExt.setSlackBusSelectionMode(SlackBusSelectionMode.NAME); + parametersExt.setSlackBusesIds(List.of("VLHV2", "VLLOAD")); + LoadFlowResult result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); + List slackBusResults = componentResult.getSlackBusResults(); + assertEquals(2, slackBusResults.size()); + TwoWindingsTransformer t2wtLoad = network.getTwoWindingsTransformer("NHV2_NLOAD"); + Load load = network.getLoad("LOAD"); + + assertEquals(-603.5, t2wtLoad.getTerminal2().getP(), LoadFlowAssert.DELTA_POWER); + assertEquals(600.0, load.getTerminal().getP(), LoadFlowAssert.DELTA_POWER); + + assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + assertEquals(-3.5, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + } } From eb66c40bc1e35da4458b334d21302c8bf37b5a28 Mon Sep 17 00:00:00 2001 From: vmouradian Date: Thu, 7 Nov 2024 17:59:34 +0100 Subject: [PATCH 02/10] DC support reference bus different from slack Signed-off-by: vmouradian --- .../com/powsybl/openloadflow/OpenLoadFlowParameters.java | 3 ++- .../dc/equations/DcEquationSystemCreator.java | 4 +++- .../powsybl/openloadflow/ac/MultipleSlackBusesTest.java | 9 +++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java b/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java index 4d1763219d..a385854140 100644 --- a/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java +++ b/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java @@ -1922,7 +1922,8 @@ public static DcLoadFlowParameters createDcParameters(LoadFlowParameters paramet .setLowImpedanceThreshold(parametersExt.getLowImpedanceThreshold()) .setSvcVoltageMonitoring(false) .setMaxSlackBusCount(parametersExt.getMaxSlackBusCount()) - .setLinePerUnitMode(parametersExt.getLinePerUnitMode()); + .setLinePerUnitMode(parametersExt.getLinePerUnitMode()) + .setReferenceBusSelector(ReferenceBusSelector.fromMode(parametersExt.getReferenceBusSelectionMode())); var equationSystemCreationParameters = new DcEquationSystemCreationParameters() .setUpdateFlows(true) diff --git a/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystemCreator.java b/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystemCreator.java index 5ef6e96cc4..90fb5ff99a 100644 --- a/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystemCreator.java +++ b/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystemCreator.java @@ -38,9 +38,11 @@ private void createBuses(EquationSystem equation for (LfBus bus : network.getBuses()) { var p = equationSystem.createEquation(bus, DcEquationType.BUS_TARGET_P); bus.setP(p); - if (bus == network.getSlackBus()) { + if (bus.isReference()) { equationSystem.createEquation(bus, DcEquationType.BUS_TARGET_PHI) .addTerm(equationSystem.getVariable(bus.getNum(), DcVariableType.BUS_PHI).createTerm()); + } + if (bus == network.getSlackBus()) { p.setActive(false); } } diff --git a/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java b/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java index ad180b147b..ecdf517740 100644 --- a/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java +++ b/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java @@ -7,6 +7,7 @@ */ package com.powsybl.openloadflow.ac; +import com.powsybl.iidm.network.Bus; import com.powsybl.iidm.network.Line; import com.powsybl.iidm.network.Load; import com.powsybl.iidm.network.Network; @@ -122,19 +123,23 @@ void dcMultiSlackTest() { LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); List slackBusResults = componentResult.getSlackBusResults(); assertEquals(2, slackBusResults.size()); - assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(-3.5, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + Bus nGen = network.getBusBreakerView().getBus("NGEN"); Line l12A = network.getLine("NHV1_NHV2_1"); Line l12B = network.getLine("NHV1_NHV2_2"); TwoWindingsTransformer t2wtGen = network.getTwoWindingsTransformer("NGEN_NHV1"); TwoWindingsTransformer t2wtLoad = network.getTwoWindingsTransformer("NHV2_NLOAD"); + assertEquals(0, nGen.getAngle(), LoadFlowAssert.DELTA_ANGLE); assertEquals(301.75, l12A.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); assertEquals(301.75, l12B.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); assertEquals(600, t2wtLoad.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); assertEquals(607, t2wtGen.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); + assertEquals(List.of("VLHV1_0", "VLHV2_0"), result.getComponentResults().get(0).getSlackBusResults().stream().map(r -> r.getId()).toList()); + assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + assertEquals(-3.5, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + parameters.setDistributedSlack(true); result = loadFlowRunner.run(network, parameters); assertTrue(result.isFullyConverged()); From 3d58da9a2f2a7073edcd506a236658307a2ac4ab Mon Sep 17 00:00:00 2001 From: vmouradian Date: Tue, 12 Nov 2024 12:13:16 +0100 Subject: [PATCH 03/10] fix unit tests Signed-off-by: vmouradian --- .../ac/AcMultipleSlackBusesTest.java | 110 ++++++++++++++++++ .../DcMultipleSlackBusesTest.java} | 101 +++------------- 2 files changed, 126 insertions(+), 85 deletions(-) create mode 100644 src/test/java/com/powsybl/openloadflow/ac/AcMultipleSlackBusesTest.java rename src/test/java/com/powsybl/openloadflow/{ac/MultipleSlackBusesTest.java => dc/DcMultipleSlackBusesTest.java} (55%) diff --git a/src/test/java/com/powsybl/openloadflow/ac/AcMultipleSlackBusesTest.java b/src/test/java/com/powsybl/openloadflow/ac/AcMultipleSlackBusesTest.java new file mode 100644 index 0000000000..8704822c29 --- /dev/null +++ b/src/test/java/com/powsybl/openloadflow/ac/AcMultipleSlackBusesTest.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2022, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.openloadflow.ac; + +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; +import com.powsybl.loadflow.LoadFlow; +import com.powsybl.loadflow.LoadFlowParameters; +import com.powsybl.loadflow.LoadFlowResult; +import com.powsybl.math.matrix.DenseMatrixFactory; +import com.powsybl.openloadflow.OpenLoadFlowParameters; +import com.powsybl.openloadflow.OpenLoadFlowProvider; +import com.powsybl.openloadflow.ac.solver.NewtonRaphsonStoppingCriteriaType; +import com.powsybl.openloadflow.network.EurostagFactory; +import com.powsybl.openloadflow.util.LoadFlowAssert; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author Geoffroy Jamgotchian {@literal } + */ +class AcMultipleSlackBusesTest { + + private Network network; + + private LoadFlow.Runner loadFlowRunner; + + private LoadFlowParameters parameters; + + private OpenLoadFlowParameters parametersExt; + + @BeforeEach + void setUp() { + network = EurostagFactory.fix(EurostagTutorialExample1Factory.create()); + loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory())); + parameters = new LoadFlowParameters() + .setUseReactiveLimits(false) + .setDistributedSlack(false); + parametersExt = OpenLoadFlowParameters.create(parameters) + .setMaxSlackBusCount(2); + } + + static Stream allStoppingCriteriaTypes() { + return Arrays.stream(NewtonRaphsonStoppingCriteriaType.values()).map(Arguments::of); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("allStoppingCriteriaTypes") + void multiSlackTest(NewtonRaphsonStoppingCriteriaType stoppingCriteria) { + parametersExt.setNewtonRaphsonStoppingCriteriaType(stoppingCriteria); + LoadFlowResult result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); + assertEquals(3, componentResult.getIterationCount()); + List slackBusResults = componentResult.getSlackBusResults(); + assertEquals(2, slackBusResults.size()); + assertEquals(-0.716, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + assertEquals(-0.716, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + + parameters.setDistributedSlack(true); + result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + componentResult = result.getComponentResults().get(0); + slackBusResults = componentResult.getSlackBusResults(); + assertEquals(4, componentResult.getIterationCount()); + assertEquals(2, slackBusResults.size()); + assertEquals(-0.005, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + assertEquals(-0.005, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + } + + @Test + void nonImpedantBranchTest() { + network.getLine("NHV1_NHV2_1") + .setR(0) + .setX(0); + LoadFlowResult result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); + List slackBusResults = componentResult.getSlackBusResults(); + assertEquals(3, componentResult.getIterationCount()); + assertEquals(2, slackBusResults.size()); + assertEquals(-2.755, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + assertEquals(-2.755, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + + parameters.setDistributedSlack(true); + result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + componentResult = result.getComponentResults().get(0); + slackBusResults = componentResult.getSlackBusResults(); + assertEquals(4, componentResult.getIterationCount()); + assertEquals(2, slackBusResults.size()); + assertEquals(-0.005, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + assertEquals(-0.005, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + } +} diff --git a/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java b/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java similarity index 55% rename from src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java rename to src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java index ecdf517740..60351f33da 100644 --- a/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java +++ b/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java @@ -1,11 +1,4 @@ -/** - * Copyright (c) 2022, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * SPDX-License-Identifier: MPL-2.0 - */ -package com.powsybl.openloadflow.ac; +package com.powsybl.openloadflow.dc; import com.powsybl.iidm.network.Bus; import com.powsybl.iidm.network.Line; @@ -19,28 +12,20 @@ import com.powsybl.math.matrix.DenseMatrixFactory; import com.powsybl.openloadflow.OpenLoadFlowParameters; import com.powsybl.openloadflow.OpenLoadFlowProvider; -import com.powsybl.openloadflow.ac.solver.NewtonRaphsonStoppingCriteriaType; import com.powsybl.openloadflow.network.EurostagFactory; import com.powsybl.openloadflow.network.ReferenceBusSelectionMode; import com.powsybl.openloadflow.network.SlackBusSelectionMode; import com.powsybl.openloadflow.util.LoadFlowAssert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import java.util.Arrays; import java.util.List; -import java.util.stream.Stream; +import static com.powsybl.openloadflow.util.LoadFlowAssert.*; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -/** - * @author Geoffroy Jamgotchian {@literal } - */ -class MultipleSlackBusesTest { +class DcMultipleSlackBusesTest { private Network network; @@ -55,68 +40,15 @@ void setUp() { network = EurostagFactory.fix(EurostagTutorialExample1Factory.create()); loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory())); parameters = new LoadFlowParameters() + .setDc(true) .setUseReactiveLimits(false) .setDistributedSlack(false); parametersExt = OpenLoadFlowParameters.create(parameters) .setMaxSlackBusCount(2); } - static Stream allStoppingCriteriaTypes() { - return Arrays.stream(NewtonRaphsonStoppingCriteriaType.values()).map(Arguments::of); - } - - @ParameterizedTest(name = "{0}") - @MethodSource("allStoppingCriteriaTypes") - void multiSlackTest(NewtonRaphsonStoppingCriteriaType stoppingCriteria) { - parametersExt.setNewtonRaphsonStoppingCriteriaType(stoppingCriteria); - LoadFlowResult result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); - assertEquals(3, componentResult.getIterationCount()); - List slackBusResults = componentResult.getSlackBusResults(); - assertEquals(2, slackBusResults.size()); - assertEquals(-0.716, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(-0.716, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - - parameters.setDistributedSlack(true); - result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - componentResult = result.getComponentResults().get(0); - slackBusResults = componentResult.getSlackBusResults(); - assertEquals(4, componentResult.getIterationCount()); - assertEquals(2, slackBusResults.size()); - assertEquals(-0.005, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(-0.005, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - } - - @Test - void nonImpedantBranchTest() { - network.getLine("NHV1_NHV2_1") - .setR(0) - .setX(0); - LoadFlowResult result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); - List slackBusResults = componentResult.getSlackBusResults(); - assertEquals(3, componentResult.getIterationCount()); - assertEquals(2, slackBusResults.size()); - assertEquals(-2.755, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(-2.755, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - - parameters.setDistributedSlack(true); - result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - componentResult = result.getComponentResults().get(0); - slackBusResults = componentResult.getSlackBusResults(); - assertEquals(4, componentResult.getIterationCount()); - assertEquals(2, slackBusResults.size()); - assertEquals(-0.005, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(-0.005, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - } - @Test void dcMultiSlackTest() { - parameters.setDc(true); parametersExt.setReferenceBusSelectionMode(ReferenceBusSelectionMode.GENERATOR_REFERENCE_PRIORITY); LoadFlowResult result = loadFlowRunner.run(network, parameters); assertTrue(result.isFullyConverged()); @@ -130,11 +62,11 @@ void dcMultiSlackTest() { TwoWindingsTransformer t2wtGen = network.getTwoWindingsTransformer("NGEN_NHV1"); TwoWindingsTransformer t2wtLoad = network.getTwoWindingsTransformer("NHV2_NLOAD"); - assertEquals(0, nGen.getAngle(), LoadFlowAssert.DELTA_ANGLE); - assertEquals(301.75, l12A.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); - assertEquals(301.75, l12B.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); - assertEquals(600, t2wtLoad.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); - assertEquals(607, t2wtGen.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); + assertAngleEquals(0.0, nGen); + assertActivePowerEquals(301.75, l12A.getTerminal1()); + assertActivePowerEquals(301.75, l12B.getTerminal1()); + assertActivePowerEquals(600, t2wtLoad.getTerminal1()); + assertActivePowerEquals(607, t2wtGen.getTerminal1()); assertEquals(List.of("VLHV1_0", "VLHV2_0"), result.getComponentResults().get(0).getSlackBusResults().stream().map(r -> r.getId()).toList()); assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); @@ -155,7 +87,6 @@ void dcNonImpedantBranchTest() { network.getLine("NHV1_NHV2_1") .setR(0) .setX(0); - parameters.setDc(true); LoadFlowResult result = loadFlowRunner.run(network, parameters); assertTrue(result.isFullyConverged()); LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); @@ -169,10 +100,10 @@ void dcNonImpedantBranchTest() { TwoWindingsTransformer t2wtGen = network.getTwoWindingsTransformer("NGEN_NHV1"); TwoWindingsTransformer t2wtLoad = network.getTwoWindingsTransformer("NHV2_NLOAD"); - assertEquals(603.5, l12A.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); - assertEquals(0.0, l12B.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); - assertEquals(600, t2wtLoad.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); - assertEquals(607, t2wtGen.getTerminal1().getP(), LoadFlowAssert.DELTA_POWER); + assertActivePowerEquals(603.5, l12A.getTerminal1()); + assertActivePowerEquals(0.0, l12B.getTerminal1()); + assertActivePowerEquals(600, t2wtLoad.getTerminal1()); + assertActivePowerEquals(607, t2wtGen.getTerminal1()); parameters.setDistributedSlack(true); result = loadFlowRunner.run(network, parameters); @@ -186,7 +117,6 @@ void dcNonImpedantBranchTest() { @Test void dcMultiSlackWithLoadOnSlackBus() { - parameters.setDc(true); parametersExt.setSlackBusSelectionMode(SlackBusSelectionMode.NAME); parametersExt.setSlackBusesIds(List.of("VLHV2", "VLLOAD")); LoadFlowResult result = loadFlowRunner.run(network, parameters); @@ -197,10 +127,11 @@ void dcMultiSlackWithLoadOnSlackBus() { TwoWindingsTransformer t2wtLoad = network.getTwoWindingsTransformer("NHV2_NLOAD"); Load load = network.getLoad("LOAD"); - assertEquals(-603.5, t2wtLoad.getTerminal2().getP(), LoadFlowAssert.DELTA_POWER); - assertEquals(600.0, load.getTerminal().getP(), LoadFlowAssert.DELTA_POWER); + assertActivePowerEquals(-603.5, t2wtLoad.getTerminal2()); + assertActivePowerEquals(600.0, load.getTerminal()); assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); assertEquals(-3.5, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); } + } From d139083460fa932836efc415ee42566967713fef Mon Sep 17 00:00:00 2001 From: vmouradian Date: Tue, 12 Nov 2024 16:42:51 +0100 Subject: [PATCH 04/10] copyrigth Signed-off-by: vmouradian --- .../openloadflow/dc/DcMultipleSlackBusesTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java b/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java index 60351f33da..88ee2ac561 100644 --- a/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java +++ b/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java @@ -1,3 +1,11 @@ +/** + * 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; import com.powsybl.iidm.network.Bus; @@ -25,6 +33,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * @author Valentin Mouradian {@literal } + */ class DcMultipleSlackBusesTest { private Network network; From a1e988016f120478cea26d27a93a2855fa0a3cdd Mon Sep 17 00:00:00 2001 From: vmouradian Date: Tue, 12 Nov 2024 16:48:40 +0100 Subject: [PATCH 05/10] comment Signed-off-by: vmouradian --- .../openloadflow/dc/equations/DcEquationSystemCreator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystemCreator.java b/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystemCreator.java index 90fb5ff99a..9c56a8f870 100644 --- a/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystemCreator.java +++ b/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystemCreator.java @@ -42,6 +42,7 @@ private void createBuses(EquationSystem equation equationSystem.createEquation(bus, DcEquationType.BUS_TARGET_PHI) .addTerm(equationSystem.getVariable(bus.getNum(), DcVariableType.BUS_PHI).createTerm()); } + // The P balance equation is only disabled for the first slack bus. In cas of multi-slack, target vector will be updated for the other slack buses if (bus == network.getSlackBus()) { p.setActive(false); } From 40bc0b75f4d590143dd3a9c51a18950aedc8fc17 Mon Sep 17 00:00:00 2001 From: Damien Jeandemange Date: Wed, 13 Nov 2024 10:38:35 +0100 Subject: [PATCH 06/10] clean Signed-off-by: Damien Jeandemange --- .../dc/DcMultipleSlackBusesTest.java | 69 +++++++++---------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java b/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java index 88ee2ac561..dbf52cad46 100644 --- a/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java +++ b/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java @@ -8,11 +8,7 @@ package com.powsybl.openloadflow.dc; -import com.powsybl.iidm.network.Bus; -import com.powsybl.iidm.network.Line; -import com.powsybl.iidm.network.Load; -import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.TwoWindingsTransformer; +import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; import com.powsybl.loadflow.LoadFlow; import com.powsybl.loadflow.LoadFlowParameters; @@ -29,7 +25,8 @@ import java.util.List; -import static com.powsybl.openloadflow.util.LoadFlowAssert.*; +import static com.powsybl.openloadflow.util.LoadFlowAssert.assertActivePowerEquals; +import static com.powsybl.openloadflow.util.LoadFlowAssert.assertAngleEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -45,6 +42,12 @@ class DcMultipleSlackBusesTest { private LoadFlowParameters parameters; private OpenLoadFlowParameters parametersExt; + Bus genBus; + Load load; + private Line line1; + private Line line2; + private TwoWindingsTransformer genT2wt; + private TwoWindingsTransformer loadT2wt; @BeforeEach void setUp() { @@ -52,10 +55,16 @@ void setUp() { loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory())); parameters = new LoadFlowParameters() .setDc(true) - .setUseReactiveLimits(false) .setDistributedSlack(false); parametersExt = OpenLoadFlowParameters.create(parameters) .setMaxSlackBusCount(2); + + genBus = network.getBusBreakerView().getBus("NGEN"); + load = network.getLoad("LOAD"); + line1 = network.getLine("NHV1_NHV2_1"); + line2 = network.getLine("NHV1_NHV2_2"); + genT2wt = network.getTwoWindingsTransformer("NGEN_NHV1"); + loadT2wt = network.getTwoWindingsTransformer("NHV2_NLOAD"); } @Test @@ -66,23 +75,16 @@ void dcMultiSlackTest() { LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); List slackBusResults = componentResult.getSlackBusResults(); assertEquals(2, slackBusResults.size()); - - Bus nGen = network.getBusBreakerView().getBus("NGEN"); - Line l12A = network.getLine("NHV1_NHV2_1"); - Line l12B = network.getLine("NHV1_NHV2_2"); - TwoWindingsTransformer t2wtGen = network.getTwoWindingsTransformer("NGEN_NHV1"); - TwoWindingsTransformer t2wtLoad = network.getTwoWindingsTransformer("NHV2_NLOAD"); - - assertAngleEquals(0.0, nGen); - assertActivePowerEquals(301.75, l12A.getTerminal1()); - assertActivePowerEquals(301.75, l12B.getTerminal1()); - assertActivePowerEquals(600, t2wtLoad.getTerminal1()); - assertActivePowerEquals(607, t2wtGen.getTerminal1()); - - assertEquals(List.of("VLHV1_0", "VLHV2_0"), result.getComponentResults().get(0).getSlackBusResults().stream().map(r -> r.getId()).toList()); + assertEquals(List.of("VLHV1_0", "VLHV2_0"), slackBusResults.stream().map(LoadFlowResult.SlackBusResult::getId).toList()); assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); assertEquals(-3.5, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + assertAngleEquals(0.0, genBus); + assertActivePowerEquals(301.75, line1.getTerminal1()); + assertActivePowerEquals(301.75, line2.getTerminal1()); + assertActivePowerEquals(600, loadT2wt.getTerminal1()); + assertActivePowerEquals(607, genT2wt.getTerminal1()); + parameters.setDistributedSlack(true); result = loadFlowRunner.run(network, parameters); assertTrue(result.isFullyConverged()); @@ -95,26 +97,21 @@ void dcMultiSlackTest() { @Test void dcNonImpedantBranchTest() { - network.getLine("NHV1_NHV2_1") - .setR(0) - .setX(0); + line1.setR(0).setX(0); // "shortcuts" the line2 + LoadFlowResult result = loadFlowRunner.run(network, parameters); assertTrue(result.isFullyConverged()); LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); List slackBusResults = componentResult.getSlackBusResults(); + assertEquals(List.of("VLHV1_0", "VLHV2_0"), slackBusResults.stream().map(LoadFlowResult.SlackBusResult::getId).toList()); assertEquals(2, slackBusResults.size()); assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); assertEquals(-3.5, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - Line l12A = network.getLine("NHV1_NHV2_1"); - Line l12B = network.getLine("NHV1_NHV2_2"); - TwoWindingsTransformer t2wtGen = network.getTwoWindingsTransformer("NGEN_NHV1"); - TwoWindingsTransformer t2wtLoad = network.getTwoWindingsTransformer("NHV2_NLOAD"); - - assertActivePowerEquals(603.5, l12A.getTerminal1()); - assertActivePowerEquals(0.0, l12B.getTerminal1()); - assertActivePowerEquals(600, t2wtLoad.getTerminal1()); - assertActivePowerEquals(607, t2wtGen.getTerminal1()); + assertActivePowerEquals(603.5, line1.getTerminal1()); + assertActivePowerEquals(0.0, line2.getTerminal1()); + assertActivePowerEquals(600, loadT2wt.getTerminal1()); + assertActivePowerEquals(607, genT2wt.getTerminal1()); parameters.setDistributedSlack(true); result = loadFlowRunner.run(network, parameters); @@ -135,14 +132,12 @@ void dcMultiSlackWithLoadOnSlackBus() { LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); List slackBusResults = componentResult.getSlackBusResults(); assertEquals(2, slackBusResults.size()); - TwoWindingsTransformer t2wtLoad = network.getTwoWindingsTransformer("NHV2_NLOAD"); - Load load = network.getLoad("LOAD"); + assertEquals(List.of("VLHV2_0", "VLLOAD_0"), slackBusResults.stream().map(LoadFlowResult.SlackBusResult::getId).toList()); - assertActivePowerEquals(-603.5, t2wtLoad.getTerminal2()); + assertActivePowerEquals(-603.5, loadT2wt.getTerminal2()); assertActivePowerEquals(600.0, load.getTerminal()); assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); assertEquals(-3.5, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); } - } From 1c6936db0b01927264f868ea447e6d290d094985 Mon Sep 17 00:00:00 2001 From: Damien Jeandemange Date: Wed, 13 Nov 2024 10:53:53 +0100 Subject: [PATCH 07/10] add DcValueVoltageInitializer test with reference priority Signed-off-by: Damien Jeandemange --- .../ac/DcValueVoltageInitializerTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/test/java/com/powsybl/openloadflow/ac/DcValueVoltageInitializerTest.java b/src/test/java/com/powsybl/openloadflow/ac/DcValueVoltageInitializerTest.java index f58b0decb7..2628851132 100644 --- a/src/test/java/com/powsybl/openloadflow/ac/DcValueVoltageInitializerTest.java +++ b/src/test/java/com/powsybl/openloadflow/ac/DcValueVoltageInitializerTest.java @@ -8,6 +8,7 @@ package com.powsybl.openloadflow.ac; import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.extensions.ReferencePriority; import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.math.matrix.DenseMatrixFactory; import com.powsybl.math.matrix.MatrixFactory; @@ -66,6 +67,25 @@ void testFourBusNetwork() { assertBusVoltage(lfNetwork, initializer, "b4_vl_0", -0.025); } + @Test + void testFourBusNetworkReferencePriority() { + ReferencePriority.set(network.getGenerator("g4"), 1); + lfNetworkParameters.setReferenceBusSelector(new ReferenceBusGeneratorPrioritySelector()); + LfNetwork lfNetwork = LfNetwork.load(network, new LfNetworkLoaderImpl(), lfNetworkParameters).get(0); + VoltageInitializer initializer = new DcValueVoltageInitializer(lfNetworkParameters, + false, + LoadFlowParameters.BalanceType.PROPORTIONAL_TO_GENERATION_P_MAX, + true, + DcApproximationType.IGNORE_R, + matrixFactory, + 1); + initializer.prepare(lfNetwork); + assertBusVoltage(lfNetwork, initializer, "b1_vl_0", 0.025); + assertBusVoltage(lfNetwork, initializer, "b2_vl_0", 0.0); + assertBusVoltage(lfNetwork, initializer, "b3_vl_0", -0.125); + assertBusVoltage(lfNetwork, initializer, "b4_vl_0", 0.0); + } + @Test void testFourBusNetworkZeroImpedanceBranch() { // Line l12 with zero impedance From 2b39a11fc4db2b3be6756d3d8926993b738fb6a7 Mon Sep 17 00:00:00 2001 From: vmouradian Date: Thu, 14 Nov 2024 15:42:18 +0100 Subject: [PATCH 08/10] parametrized tests for AC and DC multi slack Signed-off-by: vmouradian --- .../ac/AcMultipleSlackBusesTest.java | 110 ---------- .../ac/MultipleSlackBusesTest.java | 194 ++++++++++++++++++ .../dc/DcMultipleSlackBusesTest.java | 143 ------------- 3 files changed, 194 insertions(+), 253 deletions(-) delete mode 100644 src/test/java/com/powsybl/openloadflow/ac/AcMultipleSlackBusesTest.java create mode 100644 src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java delete mode 100644 src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java diff --git a/src/test/java/com/powsybl/openloadflow/ac/AcMultipleSlackBusesTest.java b/src/test/java/com/powsybl/openloadflow/ac/AcMultipleSlackBusesTest.java deleted file mode 100644 index 8704822c29..0000000000 --- a/src/test/java/com/powsybl/openloadflow/ac/AcMultipleSlackBusesTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Copyright (c) 2022, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * SPDX-License-Identifier: MPL-2.0 - */ -package com.powsybl.openloadflow.ac; - -import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; -import com.powsybl.loadflow.LoadFlow; -import com.powsybl.loadflow.LoadFlowParameters; -import com.powsybl.loadflow.LoadFlowResult; -import com.powsybl.math.matrix.DenseMatrixFactory; -import com.powsybl.openloadflow.OpenLoadFlowParameters; -import com.powsybl.openloadflow.OpenLoadFlowProvider; -import com.powsybl.openloadflow.ac.solver.NewtonRaphsonStoppingCriteriaType; -import com.powsybl.openloadflow.network.EurostagFactory; -import com.powsybl.openloadflow.util.LoadFlowAssert; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * @author Geoffroy Jamgotchian {@literal } - */ -class AcMultipleSlackBusesTest { - - private Network network; - - private LoadFlow.Runner loadFlowRunner; - - private LoadFlowParameters parameters; - - private OpenLoadFlowParameters parametersExt; - - @BeforeEach - void setUp() { - network = EurostagFactory.fix(EurostagTutorialExample1Factory.create()); - loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory())); - parameters = new LoadFlowParameters() - .setUseReactiveLimits(false) - .setDistributedSlack(false); - parametersExt = OpenLoadFlowParameters.create(parameters) - .setMaxSlackBusCount(2); - } - - static Stream allStoppingCriteriaTypes() { - return Arrays.stream(NewtonRaphsonStoppingCriteriaType.values()).map(Arguments::of); - } - - @ParameterizedTest(name = "{0}") - @MethodSource("allStoppingCriteriaTypes") - void multiSlackTest(NewtonRaphsonStoppingCriteriaType stoppingCriteria) { - parametersExt.setNewtonRaphsonStoppingCriteriaType(stoppingCriteria); - LoadFlowResult result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); - assertEquals(3, componentResult.getIterationCount()); - List slackBusResults = componentResult.getSlackBusResults(); - assertEquals(2, slackBusResults.size()); - assertEquals(-0.716, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(-0.716, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - - parameters.setDistributedSlack(true); - result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - componentResult = result.getComponentResults().get(0); - slackBusResults = componentResult.getSlackBusResults(); - assertEquals(4, componentResult.getIterationCount()); - assertEquals(2, slackBusResults.size()); - assertEquals(-0.005, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(-0.005, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - } - - @Test - void nonImpedantBranchTest() { - network.getLine("NHV1_NHV2_1") - .setR(0) - .setX(0); - LoadFlowResult result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); - List slackBusResults = componentResult.getSlackBusResults(); - assertEquals(3, componentResult.getIterationCount()); - assertEquals(2, slackBusResults.size()); - assertEquals(-2.755, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(-2.755, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - - parameters.setDistributedSlack(true); - result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - componentResult = result.getComponentResults().get(0); - slackBusResults = componentResult.getSlackBusResults(); - assertEquals(4, componentResult.getIterationCount()); - assertEquals(2, slackBusResults.size()); - assertEquals(-0.005, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(-0.005, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - } -} diff --git a/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java b/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java new file mode 100644 index 0000000000..d93b354537 --- /dev/null +++ b/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java @@ -0,0 +1,194 @@ +/** + * Copyright (c) 2022, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.openloadflow.ac; + +import com.powsybl.iidm.network.Bus; +import com.powsybl.iidm.network.Generator; +import com.powsybl.iidm.network.Line; +import com.powsybl.iidm.network.Load; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.TwoWindingsTransformer; +import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; +import com.powsybl.loadflow.LoadFlow; +import com.powsybl.loadflow.LoadFlowParameters; +import com.powsybl.loadflow.LoadFlowResult; +import com.powsybl.math.matrix.DenseMatrixFactory; +import com.powsybl.openloadflow.OpenLoadFlowParameters; +import com.powsybl.openloadflow.OpenLoadFlowProvider; +import com.powsybl.openloadflow.ac.solver.NewtonRaphsonStoppingCriteriaType; +import com.powsybl.openloadflow.network.EurostagFactory; +import com.powsybl.openloadflow.network.SlackBusSelectionMode; +import com.powsybl.openloadflow.util.LoadFlowAssert; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +import static com.powsybl.openloadflow.util.LoadFlowAssert.assertActivePowerEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author Geoffroy Jamgotchian {@literal } + */ +class MultipleSlackBusesTest { + + private Network network; + + private LoadFlow.Runner loadFlowRunner; + + private LoadFlowParameters parameters; + + private OpenLoadFlowParameters parametersExt; + Bus genBus; + Load load; + Generator generator; + private Line line1; + private Line line2; + private TwoWindingsTransformer loadT2wt; + + @BeforeEach + void setUp() { + network = EurostagFactory.fix(EurostagTutorialExample1Factory.create()); + loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory())); + parameters = new LoadFlowParameters() + .setUseReactiveLimits(false) + .setDistributedSlack(false); + parametersExt = OpenLoadFlowParameters.create(parameters) + .setMaxSlackBusCount(2); + genBus = network.getBusBreakerView().getBus("NGEN"); + load = network.getLoad("LOAD"); + generator = network.getGenerator("GEN"); + line1 = network.getLine("NHV1_NHV2_1"); + line2 = network.getLine("NHV1_NHV2_2"); + loadT2wt = network.getTwoWindingsTransformer("NHV2_NLOAD"); + } + + static Stream allModelAndStoppingCriteriaTypes() { + Stream acStream = Arrays.stream(NewtonRaphsonStoppingCriteriaType.values()).map(a -> Arguments.of(true, a)); + Stream dcStream = Stream.of(Arguments.of(false, NewtonRaphsonStoppingCriteriaType.UNIFORM_CRITERIA)); + return Stream.concat(acStream, dcStream); + } + + static Stream allModelTypes() { + return Stream.of(Arguments.of(true), Arguments.of(false)); + } + + @ParameterizedTest(name = "ac : {0}, NR stopping crit : {1}") + @MethodSource("allModelAndStoppingCriteriaTypes") + void multiSlackTest(boolean ac, NewtonRaphsonStoppingCriteriaType stoppingCriteria) { + parameters.setDc(!ac); + parametersExt.setNewtonRaphsonStoppingCriteriaType(stoppingCriteria); + LoadFlowResult result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); + int expectedIterationCount = ac ? 3 : 0; + assertEquals(expectedIterationCount, componentResult.getIterationCount()); + + List slackBusResults = componentResult.getSlackBusResults(); + double expectedSlackBusMismatch = ac ? -0.7164 : -3.5; + assertSlackBusResults(slackBusResults, expectedSlackBusMismatch, 2); + + if (ac) { + assertActivePowerValues(302.807, 302.807, 600.868); + } else { + assertActivePowerValues(301.75, 301.75, 600); + } + + parameters.setDistributedSlack(true); + result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + componentResult = result.getComponentResults().get(0); + slackBusResults = componentResult.getSlackBusResults(); + + expectedIterationCount = ac ? 4 : 0; + assertEquals(expectedIterationCount, componentResult.getIterationCount()); + expectedSlackBusMismatch = ac ? -0.005 : 0; + assertSlackBusResults(slackBusResults, expectedSlackBusMismatch, 2); + } + + @ParameterizedTest(name = "ac : {0}") + @MethodSource("allModelTypes") + void nonImpedantBranchTest(boolean ac) { + parameters.setDc(!ac); + network.getLine("NHV1_NHV2_1") + .setR(0) + .setX(0); + LoadFlowResult result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); + int expectedIterationCount = ac ? 3 : 0; + assertEquals(expectedIterationCount, componentResult.getIterationCount()); + List slackBusResults = componentResult.getSlackBusResults(); + double expectedSlackBusMismatch = ac ? -2.755 : -3.5; + assertSlackBusResults(slackBusResults, expectedSlackBusMismatch, 2); + + if (ac) { + assertActivePowerValues(603.567, 0.0, 600.812); + } else { + assertActivePowerValues(603.5, 0.0, 600); + } + + parameters.setDistributedSlack(true); + result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + componentResult = result.getComponentResults().get(0); + slackBusResults = componentResult.getSlackBusResults(); + + expectedIterationCount = ac ? 4 : 0; + assertEquals(expectedIterationCount, componentResult.getIterationCount()); + expectedSlackBusMismatch = ac ? -0.005 : 0; + assertSlackBusResults(slackBusResults, expectedSlackBusMismatch, 2); + } + + @ParameterizedTest(name = "ac : {0}") + @MethodSource("allModelTypes") + void dcMultiSlackWithLoadOnSlackBus(boolean ac) { + parameters.setDc(!ac); + parametersExt.setSlackBusSelectionMode(SlackBusSelectionMode.NAME); + parametersExt.setSlackBusesIds(List.of("VLHV2", "VLLOAD")); + LoadFlowResult result = loadFlowRunner.run(network, parameters); + assertTrue(result.isFullyConverged()); + LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); + + int expectedIterationCount = ac ? 3 : 0; + assertEquals(expectedIterationCount, componentResult.getIterationCount()); + + List slackBusResults = componentResult.getSlackBusResults(); + assertEquals(List.of("VLHV2_0", "VLLOAD_0"), slackBusResults.stream().map(LoadFlowResult.SlackBusResult::getId).toList()); + double expectedSlackBusMismatch = ac ? -1.159 : -3.5; + + assertSlackBusResults(slackBusResults, expectedSlackBusMismatch, 2); + + if (ac) { + // Needs to be fixed -> wrong power balance for slack buses with injections + assertActivePowerValues(303.183, 303.183, 301.434); + } else { + assertActivePowerValues(303.5, 303.5, 603.5); + } + } + + void assertActivePowerValues(double line1P1, double line2P1, double loadT2wtP1) { + assertActivePowerEquals(line1P1, line1.getTerminal1()); + assertActivePowerEquals(line2P1, line2.getTerminal1()); + assertActivePowerEquals(loadT2wtP1, loadT2wt.getTerminal1()); + assertActivePowerEquals(600, load.getTerminal()); + assertActivePowerEquals(-607, generator.getTerminal()); + } + + void assertSlackBusResults(List slackBusResults, double expectedMismatch, int slackBusCount) { + assertEquals(slackBusCount, slackBusResults.size()); + for (LoadFlowResult.SlackBusResult slackBusResult : slackBusResults) { + assertEquals(expectedMismatch, slackBusResult.getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); + } + } +} diff --git a/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java b/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java deleted file mode 100644 index dbf52cad46..0000000000 --- a/src/test/java/com/powsybl/openloadflow/dc/DcMultipleSlackBusesTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/** - * 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; - -import com.powsybl.iidm.network.*; -import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; -import com.powsybl.loadflow.LoadFlow; -import com.powsybl.loadflow.LoadFlowParameters; -import com.powsybl.loadflow.LoadFlowResult; -import com.powsybl.math.matrix.DenseMatrixFactory; -import com.powsybl.openloadflow.OpenLoadFlowParameters; -import com.powsybl.openloadflow.OpenLoadFlowProvider; -import com.powsybl.openloadflow.network.EurostagFactory; -import com.powsybl.openloadflow.network.ReferenceBusSelectionMode; -import com.powsybl.openloadflow.network.SlackBusSelectionMode; -import com.powsybl.openloadflow.util.LoadFlowAssert; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.List; - -import static com.powsybl.openloadflow.util.LoadFlowAssert.assertActivePowerEquals; -import static com.powsybl.openloadflow.util.LoadFlowAssert.assertAngleEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * @author Valentin Mouradian {@literal } - */ -class DcMultipleSlackBusesTest { - - private Network network; - - private LoadFlow.Runner loadFlowRunner; - - private LoadFlowParameters parameters; - - private OpenLoadFlowParameters parametersExt; - Bus genBus; - Load load; - private Line line1; - private Line line2; - private TwoWindingsTransformer genT2wt; - private TwoWindingsTransformer loadT2wt; - - @BeforeEach - void setUp() { - network = EurostagFactory.fix(EurostagTutorialExample1Factory.create()); - loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory())); - parameters = new LoadFlowParameters() - .setDc(true) - .setDistributedSlack(false); - parametersExt = OpenLoadFlowParameters.create(parameters) - .setMaxSlackBusCount(2); - - genBus = network.getBusBreakerView().getBus("NGEN"); - load = network.getLoad("LOAD"); - line1 = network.getLine("NHV1_NHV2_1"); - line2 = network.getLine("NHV1_NHV2_2"); - genT2wt = network.getTwoWindingsTransformer("NGEN_NHV1"); - loadT2wt = network.getTwoWindingsTransformer("NHV2_NLOAD"); - } - - @Test - void dcMultiSlackTest() { - parametersExt.setReferenceBusSelectionMode(ReferenceBusSelectionMode.GENERATOR_REFERENCE_PRIORITY); - LoadFlowResult result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); - List slackBusResults = componentResult.getSlackBusResults(); - assertEquals(2, slackBusResults.size()); - assertEquals(List.of("VLHV1_0", "VLHV2_0"), slackBusResults.stream().map(LoadFlowResult.SlackBusResult::getId).toList()); - assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(-3.5, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - - assertAngleEquals(0.0, genBus); - assertActivePowerEquals(301.75, line1.getTerminal1()); - assertActivePowerEquals(301.75, line2.getTerminal1()); - assertActivePowerEquals(600, loadT2wt.getTerminal1()); - assertActivePowerEquals(607, genT2wt.getTerminal1()); - - parameters.setDistributedSlack(true); - result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - componentResult = result.getComponentResults().get(0); - slackBusResults = componentResult.getSlackBusResults(); - assertEquals(2, slackBusResults.size()); - assertEquals(0, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(0, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - } - - @Test - void dcNonImpedantBranchTest() { - line1.setR(0).setX(0); // "shortcuts" the line2 - - LoadFlowResult result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); - List slackBusResults = componentResult.getSlackBusResults(); - assertEquals(List.of("VLHV1_0", "VLHV2_0"), slackBusResults.stream().map(LoadFlowResult.SlackBusResult::getId).toList()); - assertEquals(2, slackBusResults.size()); - assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(-3.5, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - - assertActivePowerEquals(603.5, line1.getTerminal1()); - assertActivePowerEquals(0.0, line2.getTerminal1()); - assertActivePowerEquals(600, loadT2wt.getTerminal1()); - assertActivePowerEquals(607, genT2wt.getTerminal1()); - - parameters.setDistributedSlack(true); - result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - componentResult = result.getComponentResults().get(0); - slackBusResults = componentResult.getSlackBusResults(); - assertEquals(2, slackBusResults.size()); - assertEquals(0, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(0, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - } - - @Test - void dcMultiSlackWithLoadOnSlackBus() { - parametersExt.setSlackBusSelectionMode(SlackBusSelectionMode.NAME); - parametersExt.setSlackBusesIds(List.of("VLHV2", "VLLOAD")); - LoadFlowResult result = loadFlowRunner.run(network, parameters); - assertTrue(result.isFullyConverged()); - LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); - List slackBusResults = componentResult.getSlackBusResults(); - assertEquals(2, slackBusResults.size()); - assertEquals(List.of("VLHV2_0", "VLLOAD_0"), slackBusResults.stream().map(LoadFlowResult.SlackBusResult::getId).toList()); - - assertActivePowerEquals(-603.5, loadT2wt.getTerminal2()); - assertActivePowerEquals(600.0, load.getTerminal()); - - assertEquals(-3.5, slackBusResults.get(0).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - assertEquals(-3.5, slackBusResults.get(1).getActivePowerMismatch(), LoadFlowAssert.DELTA_POWER); - } -} From 2bae3cf71653f46f42fe746fcf2f36646fc82bc9 Mon Sep 17 00:00:00 2001 From: vmouradian Date: Mon, 18 Nov 2024 10:19:23 +0100 Subject: [PATCH 09/10] clean Signed-off-by: vmouradian --- .../com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java b/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java index d93b354537..915a78a051 100644 --- a/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java +++ b/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java @@ -109,7 +109,6 @@ void multiSlackTest(boolean ac, NewtonRaphsonStoppingCriteriaType stoppingCriter assertTrue(result.isFullyConverged()); componentResult = result.getComponentResults().get(0); slackBusResults = componentResult.getSlackBusResults(); - expectedIterationCount = ac ? 4 : 0; assertEquals(expectedIterationCount, componentResult.getIterationCount()); expectedSlackBusMismatch = ac ? -0.005 : 0; @@ -143,7 +142,6 @@ void nonImpedantBranchTest(boolean ac) { assertTrue(result.isFullyConverged()); componentResult = result.getComponentResults().get(0); slackBusResults = componentResult.getSlackBusResults(); - expectedIterationCount = ac ? 4 : 0; assertEquals(expectedIterationCount, componentResult.getIterationCount()); expectedSlackBusMismatch = ac ? -0.005 : 0; @@ -159,14 +157,12 @@ void dcMultiSlackWithLoadOnSlackBus(boolean ac) { LoadFlowResult result = loadFlowRunner.run(network, parameters); assertTrue(result.isFullyConverged()); LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); - int expectedIterationCount = ac ? 3 : 0; assertEquals(expectedIterationCount, componentResult.getIterationCount()); List slackBusResults = componentResult.getSlackBusResults(); assertEquals(List.of("VLHV2_0", "VLLOAD_0"), slackBusResults.stream().map(LoadFlowResult.SlackBusResult::getId).toList()); double expectedSlackBusMismatch = ac ? -1.159 : -3.5; - assertSlackBusResults(slackBusResults, expectedSlackBusMismatch, 2); if (ac) { From a6ab981d78151f706fa8fe222475ec4ad105141d Mon Sep 17 00:00:00 2001 From: vmouradian Date: Mon, 18 Nov 2024 10:28:56 +0100 Subject: [PATCH 10/10] update unit test for ac injection on slack bus Signed-off-by: vmouradian --- .../openloadflow/ac/MultipleSlackBusesTest.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java b/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java index a93301edd1..ee57d97d40 100644 --- a/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java +++ b/src/test/java/com/powsybl/openloadflow/ac/MultipleSlackBusesTest.java @@ -7,6 +7,10 @@ */ package com.powsybl.openloadflow.ac; +import com.powsybl.iidm.network.Bus; +import com.powsybl.iidm.network.Generator; +import com.powsybl.iidm.network.Line; +import com.powsybl.iidm.network.Load; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.TwoWindingsTransformer; import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; @@ -146,7 +150,7 @@ void nonImpedantBranchTest(boolean ac) { @ParameterizedTest(name = "ac : {0}") @MethodSource("allModelTypes") - void dcMultiSlackWithLoadOnSlackBus(boolean ac) { + void loadOnSlackBusTest(boolean ac) { parameters.setDc(!ac); parametersExt.setSlackBusSelectionMode(SlackBusSelectionMode.NAME); parametersExt.setSlackBusesIds(List.of("VLHV2", "VLLOAD")); @@ -158,12 +162,11 @@ void dcMultiSlackWithLoadOnSlackBus(boolean ac) { List slackBusResults = componentResult.getSlackBusResults(); assertEquals(List.of("VLHV2_0", "VLLOAD_0"), slackBusResults.stream().map(LoadFlowResult.SlackBusResult::getId).toList()); - double expectedSlackBusMismatch = ac ? -1.159 : -3.5; + double expectedSlackBusMismatch = ac ? -0.711 : -3.5; assertSlackBusResults(slackBusResults, expectedSlackBusMismatch, 2); if (ac) { - // Needs to be fixed -> wrong power balance for slack buses with injections - assertActivePowerValues(303.183, 303.183, 301.434); + assertActivePowerValues(303.165, 303.165, 601.58); } else { assertActivePowerValues(303.5, 303.5, 603.5); }