diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ConnectDisconnectUtil.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ConnectDisconnectUtil.java index 861c4883022..70dd9e40d52 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ConnectDisconnectUtil.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ConnectDisconnectUtil.java @@ -9,9 +9,7 @@ import com.powsybl.commons.report.ReportNode; import com.powsybl.commons.report.TypedValue; -import com.powsybl.iidm.network.Identifiable; -import com.powsybl.iidm.network.Switch; -import com.powsybl.iidm.network.Terminal; +import com.powsybl.iidm.network.*; import java.util.HashSet; import java.util.List; @@ -114,6 +112,9 @@ static boolean disconnectAllTerminals(Identifiable identifiable, List switchForDisconnection = new HashSet<>(); + // Set of terminals at the other end of paths - used to disconnect their connectable if needed + Set endOfPathTerminals = new HashSet<>(); + // We try to disconnect each terminal for (Terminal terminal : terminals) { // Check if the terminal is already disconnected @@ -131,7 +132,7 @@ static boolean disconnectAllTerminals(Identifiable identifiable, List identifiable, List sw.setOpen(true)); + + // Completely disconnect if needed the elements (other than busbar sections at the end of the paths) + disconnectEndOfPathTerminals(endOfPathTerminals, isSwitchOpenable); return isNowDisconnected; } + + private static void disconnectEndOfPathTerminals(Set endOfPathTerminals, Predicate isSwitchOpenable) { + for (Terminal terminal : endOfPathTerminals) { + if (!terminal.isConnected()) { + // If one side is disconnected, the connectable has to be fully disconnected + switch (terminal.getConnectable().getType()) { + case LINE -> { + Line line = (Line) terminal.getConnectable(); + line.disconnect(isSwitchOpenable); + } + case TWO_WINDINGS_TRANSFORMER -> { + TwoWindingsTransformer twt = (TwoWindingsTransformer) terminal.getConnectable(); + twt.disconnect(isSwitchOpenable); + } + case THREE_WINDINGS_TRANSFORMER -> { + ThreeWindingsTransformer twt = (ThreeWindingsTransformer) terminal.getConnectable(); + twt.disconnect(isSwitchOpenable); + } + case HVDC_CONVERTER_STATION -> + ((HvdcConverterStation) terminal.getConnectable()).getHvdcLine().disconnectConverterStations(isSwitchOpenable); + case DANGLING_LINE -> { + DanglingLine danglingLine = (DanglingLine) terminal.getConnectable(); + if (danglingLine.getTieLine().isPresent()) { + danglingLine.getTieLine().get().disconnectDanglingLines(isSwitchOpenable); + } + } + default -> { + // Nothing to do + } + } + } + } + } } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeBreakerTopologyModel.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeBreakerTopologyModel.java index a6c09915fc1..70901589e18 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeBreakerTopologyModel.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeBreakerTopologyModel.java @@ -1285,6 +1285,11 @@ public boolean disconnect(TerminalExt terminal, Predicate is } boolean getDisconnectingSwitches(Terminal terminal, Predicate isSwitchOpenable, Set switchForDisconnection) { + return getDisconnectingSwitches(terminal, isSwitchOpenable, switchForDisconnection, new HashSet<>()); + } + + boolean getDisconnectingSwitches(Terminal terminal, Predicate isSwitchOpenable, Set switchForDisconnection, + Set endOfPathTerminals) { // Check the topology kind checkTopologyKind(terminal); @@ -1303,6 +1308,9 @@ boolean getDisconnectingSwitches(Terminal terminal, Predicate assertNull(terminal.getBusView().getBus())); line2.getTerminals().forEach(terminal -> assertFalse(terminal.isConnected())); - // TODO: Warning - L2 is half connected! // D_L1 should be open but not D_L2 assertTrue(disconnectorL1.isOpen()); diff --git a/math/src/main/java/com/powsybl/math/graph/UndirectedGraphImpl.java b/math/src/main/java/com/powsybl/math/graph/UndirectedGraphImpl.java index 7fd5d91f17e..dbcde572634 100644 --- a/math/src/main/java/com/powsybl/math/graph/UndirectedGraphImpl.java +++ b/math/src/main/java/com/powsybl/math/graph/UndirectedGraphImpl.java @@ -706,6 +706,26 @@ private void findAllPaths(int v, Predicate pathComplete, Predicate } } + public void identifyEndOfPathVerticesObjects(List paths, Set endOfPathVerticesObjects, + Predicate pathComplete) { + for (TIntArrayList path : paths) { + // We get the last edge of the path + int e = path.get(path.size() - 1); + Edge edge = edges.get(e); + + // The last vertice can be at either side of the edge + V object1 = vertices.get(edge.getV1()).getObject(); + V object2 = vertices.get(edge.getV2()).getObject(); + + // Only one side can validate the predicate + if (Boolean.TRUE.equals(pathComplete.test(object1))) { + endOfPathVerticesObjects.add(object1); + } else { + endOfPathVerticesObjects.add(object2); + } + } + } + @Override public void addListener(UndirectedGraphListener l) { listeners.add(l);