Skip to content

Commit c043004

Browse files
authored
Enhance busbar sections retrieval – rework BusbarSectionFinderTraverser (#294)
Signed-off-by: Rehili Ghazwa <[email protected]>
1 parent 8a696e4 commit c043004

File tree

7 files changed

+330
-29
lines changed

7 files changed

+330
-29
lines changed

src/main/java/org/gridsuite/network/map/dto/definition/extension/BusbarSectionFinderTraverser.java

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,97 @@
66
*/
77
package org.gridsuite.network.map.dto.definition.extension;
88

9-
import com.powsybl.iidm.network.IdentifiableType;
9+
import com.powsybl.iidm.network.BusbarSection;
1010
import com.powsybl.iidm.network.Switch;
1111
import com.powsybl.iidm.network.Terminal;
12+
import com.powsybl.iidm.network.VoltageLevel;
13+
import com.powsybl.math.graph.TraversalType;
1214
import com.powsybl.math.graph.TraverseResult;
1315

16+
import java.util.*;
17+
1418
/**
15-
* @author Slimane Amar <slimane.amar at rte-france.com>
19+
* @author Ghazwa Rehili <ghazwa.rehili at rte-france.com>
1620
*/
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+
}
1827

19-
private final boolean onlyConnectedBbs;
28+
public record SwitchInfo(String id, boolean isOpen) { }
2029

21-
private String firstTraversedBbsId;
30+
public record BusbarSectionResult(String busbarSectionId, int depth, SwitchInfo lastSwitch, boolean allClosedSwitch) { }
2231

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();
2535
}
2636

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;
3242
}
33-
return TraverseResult.CONTINUE;
43+
return selectBestBusbar(allResults);
3444
}
3545

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);
4051
}
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();
4263
}
4364

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;
46101
}
47102
}

src/main/java/org/gridsuite/network/map/dto/utils/ElementUtils.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import com.powsybl.iidm.network.*;
1010
import com.powsybl.iidm.network.extensions.ConnectablePosition;
11-
import com.powsybl.math.graph.TraversalType;
1211
import org.gridsuite.network.map.dto.common.ReactiveCapabilityCurveMapData;
1312
import org.gridsuite.network.map.dto.common.TapChangerData;
1413
import org.gridsuite.network.map.dto.common.TapChangerStepData;
@@ -92,9 +91,8 @@ public static String getBusOrBusbarSection(Terminal terminal) {
9291
return terminal.getBusBreakerView().getConnectableBus().getId();
9392
}
9493
} else {
95-
final BusbarSectionFinderTraverser connectedBusbarSectionFinder = new BusbarSectionFinderTraverser(terminal.isConnected());
96-
terminal.traverse(connectedBusbarSectionFinder, TraversalType.BREADTH_FIRST);
97-
return connectedBusbarSectionFinder.getFirstTraversedBbsId();
94+
// NODE_BREAKER: explore all paths and choose the busbar with the closed disconnector
95+
return BusbarSectionFinderTraverser.findBusbarSectionId(terminal);
9896
}
9997
}
10098

src/test/java/org/gridsuite/network/map/NetworkMapControllerTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
*/
5555
@AutoConfigureMockMvc
5656
@SpringBootTest
57-
class NetworkMapControllerTest {
57+
public class NetworkMapControllerTest {
5858

5959
private static final UUID NETWORK_UUID = UUID.fromString("7928181c-7977-4592-ba19-88027e4254e4");
6060
private static final UUID NETWORK_2_UUID = UUID.fromString("9828181c-7977-4592-ba19-8976e4254e");
@@ -1268,7 +1268,7 @@ static void tearDown() {
12681268
Mockito.validateMockitoUsage();
12691269
}
12701270

1271-
private static void createSwitch(VoltageLevel vl, String id, SwitchKind kind, boolean open, int node1, int node2) {
1271+
public static void createSwitch(VoltageLevel vl, String id, SwitchKind kind, boolean open, int node1, int node2) {
12721272
vl.getNodeBreakerView().newSwitch()
12731273
.setId(id)
12741274
.setName(id)

0 commit comments

Comments
 (0)