|
6 | 6 | */ |
7 | 7 | package org.gridsuite.modification.modifications; |
8 | 8 |
|
9 | | -import com.powsybl.iidm.network.IdentifiableType; |
10 | | -import com.powsybl.iidm.network.Switch; |
11 | | -import com.powsybl.iidm.network.Terminal; |
| 9 | +import com.powsybl.iidm.network.*; |
| 10 | +import com.powsybl.math.graph.TraversalType; |
12 | 11 | import com.powsybl.math.graph.TraverseResult; |
13 | 12 |
|
| 13 | +import java.util.*; |
| 14 | + |
14 | 15 | /** |
15 | | - * @author Slimane Amar <slimane.amar at rte-france.com> |
| 16 | + * @author Ghazwa Rehili <ghazwa.rehili at rte-france.com> |
16 | 17 | */ |
17 | 18 | // FIXME : to remove when this class is available in network-store |
18 | | -public class BusbarSectionFinderTraverser implements Terminal.TopologyTraverser { |
| 19 | +public final class BusbarSectionFinderTraverser { |
| 20 | + |
| 21 | + private BusbarSectionFinderTraverser() { |
| 22 | + throw new UnsupportedOperationException(); |
| 23 | + } |
19 | 24 |
|
20 | | - private final boolean onlyConnectedBbs; |
| 25 | + public record SwitchInfo(String id, boolean isOpen) { } |
21 | 26 |
|
22 | | - private String firstTraversedBbsId; |
| 27 | + public record BusbarSectionResult(String busbarSectionId, int depth, SwitchInfo lastSwitch, boolean allClosedSwitch) { } |
23 | 28 |
|
24 | | - public BusbarSectionFinderTraverser(boolean onlyConnectedBbs) { |
25 | | - this.onlyConnectedBbs = onlyConnectedBbs; |
| 29 | + public static String findBusbarSectionId(Terminal terminal) { |
| 30 | + BusbarSectionResult result = getBusbarSectionResult(terminal); |
| 31 | + return result != null ? result.busbarSectionId() : terminal.getVoltageLevel().getNodeBreakerView().getBusbarSections().iterator().next().getId(); |
26 | 32 | } |
27 | 33 |
|
28 | | - @Override |
29 | | - public TraverseResult traverse(Terminal terminal, boolean connected) { |
30 | | - if (terminal.getConnectable().getType() == IdentifiableType.BUSBAR_SECTION) { |
31 | | - firstTraversedBbsId = terminal.getConnectable().getId(); |
32 | | - return TraverseResult.TERMINATE_TRAVERSER; |
| 34 | + public static BusbarSectionResult getBusbarSectionResult(Terminal terminal) { |
| 35 | + int startNode = terminal.getNodeBreakerView().getNode(); |
| 36 | + List<BusbarSectionResult> allResults = searchAllBusbars(terminal.getVoltageLevel(), startNode); |
| 37 | + if (allResults.isEmpty()) { |
| 38 | + return null; |
33 | 39 | } |
34 | | - return TraverseResult.CONTINUE; |
| 40 | + return selectBestBusbar(allResults); |
35 | 41 | } |
36 | 42 |
|
37 | | - @Override |
38 | | - public TraverseResult traverse(Switch aSwitch) { |
39 | | - if (onlyConnectedBbs && aSwitch.isOpen()) { |
40 | | - return TraverseResult.TERMINATE_PATH; |
| 43 | + private static BusbarSectionResult selectBestBusbar(List<BusbarSectionResult> results) { |
| 44 | + List<BusbarSectionResult> withAllClosedSwitch = results.stream().filter(r -> r.allClosedSwitch).toList(); |
| 45 | + if (!withAllClosedSwitch.isEmpty()) { |
| 46 | + return withAllClosedSwitch.stream().min(Comparator.comparingInt(BusbarSectionResult::depth) |
| 47 | + .thenComparing(BusbarSectionResult::busbarSectionId)).orElse(null); |
41 | 48 | } |
42 | | - return TraverseResult.CONTINUE; |
| 49 | + List<BusbarSectionResult> withClosedSwitch = results.stream().filter(r -> r.lastSwitch() != null && !r.lastSwitch().isOpen()).toList(); |
| 50 | + if (!withClosedSwitch.isEmpty()) { |
| 51 | + return withClosedSwitch.stream().min(Comparator.comparingInt(BusbarSectionResult::depth) |
| 52 | + .thenComparing(BusbarSectionResult::busbarSectionId)).orElse(null); |
| 53 | + } |
| 54 | + List<BusbarSectionResult> withOpenSwitch = results.stream().filter(r -> r.lastSwitch() != null && r.lastSwitch().isOpen()).toList(); |
| 55 | + if (!withOpenSwitch.isEmpty()) { |
| 56 | + return withOpenSwitch.stream().min(Comparator.comparingInt(BusbarSectionResult::depth) |
| 57 | + .thenComparing(BusbarSectionResult::busbarSectionId)).orElse(null); |
| 58 | + } |
| 59 | + return results.getFirst(); |
43 | 60 | } |
44 | 61 |
|
45 | | - public String getFirstTraversedBbsId() { |
46 | | - return firstTraversedBbsId; |
| 62 | + private static List<BusbarSectionResult> searchAllBusbars(VoltageLevel voltageLevel, int startNode) { |
| 63 | + List<BusbarSectionResult> results = new ArrayList<>(); |
| 64 | + record NodeState(int depth, boolean allClosed) { } |
| 65 | + Map<Integer, NodeState> visitedNodes = new HashMap<>(); |
| 66 | + visitedNodes.put(startNode, new NodeState(0, true)); |
| 67 | + voltageLevel.getNodeBreakerView().getTerminal(startNode).traverse(new Terminal.TopologyTraverser() { |
| 68 | + SwitchInfo lastSwitch = null; |
| 69 | + @Override |
| 70 | + public TraverseResult traverse(Terminal terminal, boolean connected) { |
| 71 | + if (terminal.getVoltageLevel() != voltageLevel) { |
| 72 | + return TraverseResult.TERMINATE_PATH; |
| 73 | + } |
| 74 | + NodeState currentNodeState = visitedNodes.get(terminal.getNodeBreakerView().getNode()); |
| 75 | + if (terminal.getConnectable() instanceof BusbarSection busbarSection) { |
| 76 | + if (currentNodeState != null) { |
| 77 | + results.add(new BusbarSectionResult(busbarSection.getId(), currentNodeState.depth, lastSwitch, currentNodeState.allClosed)); |
| 78 | + } |
| 79 | + return TraverseResult.TERMINATE_PATH; |
| 80 | + } |
| 81 | + return TraverseResult.CONTINUE; |
| 82 | + } |
| 83 | + |
| 84 | + @Override |
| 85 | + public TraverseResult traverse(Switch aSwitch) { |
| 86 | + int node1 = voltageLevel.getNodeBreakerView().getNode1(aSwitch.getId()); |
| 87 | + int node2 = voltageLevel.getNodeBreakerView().getNode2(aSwitch.getId()); |
| 88 | + int sourceNode = visitedNodes.containsKey(node1) ? node1 : node2; |
| 89 | + int targetNode = visitedNodes.containsKey(node1) ? node2 : node1; |
| 90 | + NodeState sourceState = visitedNodes.get(sourceNode); |
| 91 | + NodeState newState = new NodeState(sourceState.depth + 1, sourceState.allClosed && !aSwitch.isOpen()); |
| 92 | + visitedNodes.put(targetNode, newState); |
| 93 | + lastSwitch = new SwitchInfo(aSwitch.getId(), aSwitch.isOpen()); |
| 94 | + return TraverseResult.CONTINUE; |
| 95 | + } |
| 96 | + }, TraversalType.BREADTH_FIRST); |
| 97 | + return results; |
47 | 98 | } |
48 | 99 | } |
49 | 100 |
|
0 commit comments