diff --git a/src/main/java/com/powsybl/openloadflow/sensi/AbstractSensitivityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sensi/AbstractSensitivityAnalysis.java index fa4e6d7676..c9a3bed906 100644 --- a/src/main/java/com/powsybl/openloadflow/sensi/AbstractSensitivityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sensi/AbstractSensitivityAnalysis.java @@ -745,25 +745,55 @@ private static Injection getInjection(Network network, String injectionId) { if (injection == null) { injection = network.getVscConverterStation(injectionId); } - - if (injection == null) { - throw new PowsyblException("Injection '" + injectionId + "' not found"); - } - return injection; } protected static String getInjectionBusId(Network network, String injectionId) { + // try with an injection Injection injection = getInjection(network, injectionId); - Bus bus = injection.getTerminal().getBusView().getBus(); - if (bus == null) { + if (injection != null) { + Bus bus = injection.getTerminal().getBusView().getBus(); + if (bus == null) { + return null; + } + if (injection instanceof DanglingLine) { + return LfDanglingLineBus.getId((DanglingLine) injection); + } else { + return bus.getId(); + } + } + + // try with a configured bus + Bus configuredBus = network.getBusBreakerView().getBus(injectionId); + if (configuredBus != null) { + // find a bus from bus view corresponding to this configured bus + List terminals = new ArrayList<>(); + configuredBus.visitConnectedEquipments(new AbstractTerminalTopologyVisitor() { + @Override + public void visitTerminal(Terminal terminal) { + terminals.add(terminal); + } + }); + for (Terminal terminal : terminals) { + Bus bus = terminal.getBusView().getBus(); + if (bus != null) { + return bus.getId(); + } + } return null; } - if (injection instanceof DanglingLine) { - return LfDanglingLineBus.getId((DanglingLine) injection); - } else { + + // try with a busbar section + BusbarSection busbarSection = network.getBusbarSection(injectionId); + if (busbarSection != null) { + Bus bus = busbarSection.getTerminal().getBusView().getBus(); + if (bus == null) { + return null; + } return bus.getId(); } + + throw new PowsyblException("Injection '" + injectionId + "' not found"); } private static void checkBranch(Network network, String branchId) { diff --git a/src/test/java/com/powsybl/openloadflow/sensi/dc/DcSensitivityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sensi/dc/DcSensitivityAnalysisTest.java index 08b225a7b6..7d92ebf7d8 100644 --- a/src/test/java/com/powsybl/openloadflow/sensi/dc/DcSensitivityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sensi/dc/DcSensitivityAnalysisTest.java @@ -25,7 +25,10 @@ import com.powsybl.sensitivity.*; import org.junit.jupiter.api.Test; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.CompletionException; import java.util.stream.Collectors; @@ -884,4 +887,97 @@ void nonImpedantBranchTest() { assertEquals(-0.6666666, result.getBranchFlow1SensitivityValue("glsk", "L2"), LoadFlowAssert.DELTA_POWER); assertEquals(66.6666, result.getBranchFlow1FunctionReferenceValue("L2"), LoadFlowAssert.DELTA_POWER); } + + @Test + void testConfiguredBusFactor() { + Network network = EurostagTutorialExample1Factory.create(); + runAcLf(network); + + SensitivityAnalysisParameters sensiParameters = createParameters(true, "VLLOAD_0"); + + List factors = List.of(createBranchFlowPerInjectionIncrease("NHV1_NHV2_1", "GEN"), + new SensitivityFactor(SensitivityFunctionType.BRANCH_ACTIVE_POWER_1, + "NHV1_NHV2_1", + SensitivityVariableType.INJECTION_ACTIVE_POWER, + "NGEN", + false, + ContingencyContext.all())); + + SensitivityAnalysisResult result = sensiRunner.run(network, factors, Collections.emptyList(), Collections.emptyList(), sensiParameters); + + assertEquals(2, result.getValues().size()); + assertEquals(result.getBranchFlow1SensitivityValue("GEN", "NHV1_NHV2_1"), + result.getBranchFlow1SensitivityValue("NGEN", "NHV1_NHV2_1"), + LoadFlowAssert.DELTA_POWER); + } + + @Test + void testConfiguredBusInvalidFactor() { + Network network = EurostagTutorialExample1Factory.create(); + network.getVoltageLevel("VLGEN").getBusBreakerView().newBus() + .setId("X") + .add(); + runAcLf(network); + + SensitivityAnalysisParameters sensiParameters = createParameters(true, "VLLOAD_0"); + + List factors = List.of(new SensitivityFactor(SensitivityFunctionType.BRANCH_ACTIVE_POWER_1, + "NHV1_NHV2_1", + SensitivityVariableType.INJECTION_ACTIVE_POWER, + "X", + false, + ContingencyContext.all())); + + SensitivityAnalysisResult result = sensiRunner.run(network, factors, Collections.emptyList(), Collections.emptyList(), sensiParameters); + + assertEquals(1, result.getValues().size()); + assertEquals(0, result.getBranchFlow1SensitivityValue("X", "NHV1_NHV2_1"), LoadFlowAssert.DELTA_POWER); + } + + @Test + void testBusbarSectionFactor() { + Network network = NodeBreakerNetworkFactory.create(); + runAcLf(network); + + SensitivityAnalysisParameters sensiParameters = createParameters(true, "VL2_0"); + + List factors = List.of(createBranchFlowPerInjectionIncrease("L1", "G"), + new SensitivityFactor(SensitivityFunctionType.BRANCH_ACTIVE_POWER_1, + "L1", + SensitivityVariableType.INJECTION_ACTIVE_POWER, + "BBS2", + false, + ContingencyContext.all())); + + SensitivityAnalysisResult result = sensiRunner.run(network, factors, Collections.emptyList(), Collections.emptyList(), sensiParameters); + + assertEquals(2, result.getValues().size()); + assertEquals(result.getBranchFlow1SensitivityValue("G", "L1"), + result.getBranchFlow1SensitivityValue("BBS2", "L1"), + LoadFlowAssert.DELTA_POWER); + } + + @Test + void testBusbarSectionInvalidFactor() { + Network network = NodeBreakerNetworkFactory.create(); + network.getVoltageLevel("VL1").getNodeBreakerView().newBusbarSection() + .setId("X") + .setNode(100) + .add(); + runAcLf(network); + + SensitivityAnalysisParameters sensiParameters = createParameters(true, "VL2_0"); + + List factors = List.of(new SensitivityFactor(SensitivityFunctionType.BRANCH_ACTIVE_POWER_1, + "L1", + SensitivityVariableType.INJECTION_ACTIVE_POWER, + "X", + false, + ContingencyContext.all())); + + SensitivityAnalysisResult result = sensiRunner.run(network, factors, Collections.emptyList(), Collections.emptyList(), sensiParameters); + + assertEquals(1, result.getValues().size()); + assertEquals(0, result.getBranchFlow1SensitivityValue("X", "L1"), LoadFlowAssert.DELTA_POWER); + } }