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