Skip to content

Commit 6b5a7f1

Browse files
committed
enhance TU with mixed topo kind
1 parent 6bcd0d2 commit 6b5a7f1

File tree

1 file changed

+101
-71
lines changed

1 file changed

+101
-71
lines changed

src/test/java/org/gridsuite/network/map/mapper/BusbarSectionFinderTraverserTest.java

Lines changed: 101 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -322,133 +322,154 @@ void setUp() {
322322
network.getVariantManager().setWorkingVariant(VariantManagerConstants.INITIAL_VARIANT_ID);
323323
}
324324

325+
/* ============================================
326+
* FORK topology tests
327+
* ============================================
328+
*/
329+
325330
@Test
326-
void testLine7FindsBus2ViaFork() {
331+
void testForkTopologyFindsBus2() {
332+
// LINE7 and LINE8 share the same fork point (node 8)
333+
// Both must find BUS2 because SECT_BUS2 is closed
327334
Line line7 = network.getLine("LINE7_FORK");
328-
Terminal terminal = line7.getTerminal2(); // VLGEN7 side
329-
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
330-
assertNotNull(result);
335+
Line line8 = network.getLine("LINE8_FORK");
336+
BusbarSectionFinderTraverser.BusbarSectionResult result7 = BusbarSectionFinderTraverser.findBestBusbar(line7.getTerminal2());
337+
BusbarSectionFinderTraverser.BusbarSectionResult result8 = BusbarSectionFinderTraverser.findBestBusbar(line8.getTerminal1());
338+
// Both lines must find the same busbar
339+
assertNotNull(result7);
340+
assertEquals("BUS2_NGEN7", result7.busbarSectionId());
341+
assertNotNull(result8);
342+
assertEquals("BUS2_NGEN7", result8.busbarSectionId());
343+
// Check depth and last switch
344+
assertEquals(4, result7.depth());
345+
assertEquals(4, result8.depth());
346+
assertEquals("SECT_BUS2", result7.lastSwitch().id());
347+
assertFalse(result7.lastSwitch().isOpen());
348+
}
349+
350+
@Test
351+
void testForkPreferencesClosedOverOpen() {
352+
Line line7 = network.getLine("LINE7_FORK");
353+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(line7.getTerminal2());
354+
// Must prefer BUS2 with closed switch rather than BUS1 with open switch
331355
assertEquals("BUS2_NGEN7", result.busbarSectionId());
332-
assertEquals(4, result.depth());
333-
assertNotNull(result.lastSwitch());
334-
assertEquals("SECT_BUS2", result.lastSwitch().id());
335356
assertFalse(result.lastSwitch().isOpen());
336357
}
337358

338359
@Test
339-
void testLine8FindsBus2ViaFork() {
340-
Line line8 = network.getLine("LINE8_FORK");
341-
Terminal terminal = line8.getTerminal1(); // VLGEN7 side
342-
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
360+
void testForkFallbackToBus1WhenBus2Open() {
361+
VoltageLevel vlgen7 = network.getVoltageLevel("VLGEN7");
362+
// Open SECT_BUS2 to disconnect BUS2
363+
vlgen7.getNodeBreakerView().getSwitch("SECT_BUS2").setOpen(true);
364+
Line line7 = network.getLine("LINE7_FORK");
365+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(line7.getTerminal2());
366+
// Must find BUS1 (with open switch)
343367
assertNotNull(result);
344-
assertEquals("BUS2_NGEN7", result.busbarSectionId());
345-
assertEquals(4, result.depth());
346-
assertNotNull(result.lastSwitch());
347-
assertEquals("SECT_BUS2", result.lastSwitch().id());
348-
assertFalse(result.lastSwitch().isOpen());
368+
assertEquals("BUS1_NGEN7", result.busbarSectionId());
369+
assertEquals("SECT_BUS1", result.lastSwitch().id());
370+
assertTrue(result.lastSwitch().isOpen());
349371
}
350372

373+
/* ============================================
374+
* BYPASS topology tests
375+
* ============================================
376+
*/
377+
351378
@Test
352-
void testLine9FindsBus4DirectPath() {
379+
void testBypassTopologyActivePath() {
353380
Line line9 = network.getLine("LINE9_INDEPENDENT");
354-
Terminal terminal = line9.getTerminal1(); // VLGEN7 side
355-
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
381+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(line9.getTerminal1());
382+
// Must find BUS4 via the bypass path
356383
assertNotNull(result);
357384
assertEquals("BUS4_NGEN7", result.busbarSectionId());
358-
assertEquals(5, result.depth());
385+
// Expected depth for bypass path
386+
assertTrue(result.depth() >= 4);
387+
// Last switch must be closed (not the open breaker)
359388
assertNotNull(result.lastSwitch());
360-
assertEquals("SECT_BUS4", result.lastSwitch().id());
361389
assertFalse(result.lastSwitch().isOpen());
362390
}
363391

364392
@Test
365-
void testBus1AccessibleThroughOpenSwitch() {
366-
Line line7 = network.getLine("LINE7_FORK");
367-
Terminal terminal = line7.getTerminal2();
368-
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
369-
// Should prefer BUS2 (closed) over BUS1 (open)
370-
assertNotNull(result);
371-
assertEquals("BUS2_NGEN7", result.busbarSectionId());
372-
}
373-
374-
@Test
375-
void testFindsBus1WhenBus2SwitchOpen() {
393+
void testBypassSwitchesToMainPathWhenBreakerCloses() {
376394
VoltageLevel vlgen7 = network.getVoltageLevel("VLGEN7");
377-
Switch sectBus2 = vlgen7.getNodeBreakerView().getSwitch("SECT_BUS2");
378-
sectBus2.setOpen(true); // Open the switch to BUS2
379-
Line line7 = network.getLine("LINE7_FORK");
380-
Terminal terminal = line7.getTerminal2();
381-
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
395+
// Close BRKR10 and open bypass DISC7
396+
vlgen7.getNodeBreakerView().getSwitch("BRKR10").setOpen(false);
397+
vlgen7.getNodeBreakerView().getSwitch("DISC7").setOpen(true);
398+
Line line9 = network.getLine("LINE9_INDEPENDENT");
399+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(line9.getTerminal1());
400+
// Must still find BUS4
382401
assertNotNull(result);
383-
assertEquals("BUS1_NGEN7", result.busbarSectionId());
384-
assertEquals(4, result.depth());
385-
assertNotNull(result.lastSwitch());
386-
assertTrue(result.lastSwitch().isOpen());
402+
assertEquals("BUS4_NGEN7", result.busbarSectionId());
403+
// Path must now use the closed breaker
404+
assertFalse(result.lastSwitch().isOpen());
387405
}
388406

389407
@Test
390-
void testBus3AccessibleWhenBus4Open() {
408+
void testBypassFallbackToBus3() {
391409
VoltageLevel vlgen7 = network.getVoltageLevel("VLGEN7");
392-
Switch sectBus4 = vlgen7.getNodeBreakerView().getSwitch("SECT_BUS4");
393-
sectBus4.setOpen(true); // Open BUS4 connection
410+
// Completely isolate BUS4
411+
vlgen7.getNodeBreakerView().getSwitch("SECT_BUS4").setOpen(true);
394412
Line line9 = network.getLine("LINE9_INDEPENDENT");
395-
Terminal terminal = line9.getTerminal1();
396-
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
413+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(line9.getTerminal1());
414+
// Should still find BUS4 because bypass is still connected to it
397415
assertNotNull(result);
398416
assertEquals("BUS4_NGEN7", result.busbarSectionId());
399417
}
400418

419+
/* ============================================
420+
* Selection priority tests
421+
* ============================================
422+
*/
423+
401424
@Test
402-
void testFindBusbarSectionIdConvenienceMethod() {
425+
void testPrioritizesShortestClosedPath() {
403426
Line line7 = network.getLine("LINE7_FORK");
404-
Terminal terminal = line7.getTerminal2();
405-
String busbarId = BusbarSectionFinderTraverser.findBusbarSectionId(terminal);
406-
assertNotNull(busbarId);
407-
assertEquals("BUS2_NGEN7", busbarId);
427+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(line7.getTerminal2());
428+
// BUS2 is the closest with closed switch
429+
assertNotNull(result);
430+
assertEquals("BUS2_NGEN7", result.busbarSectionId());
431+
assertEquals(4, result.depth());
432+
assertEquals(3, result.switchesBeforeLast());
408433
}
409434

410435
@Test
411-
void testReturnsNullWhenNoBusbarAccessible() {
436+
void testSelectionPriorityOrder() {
412437
VoltageLevel vlgen7 = network.getVoltageLevel("VLGEN7");
413-
// Open all switches connecting busbars
438+
// Open all coupling disconnectors
414439
vlgen7.getNodeBreakerView().getSwitch("SECT_BUS1").setOpen(true);
415440
vlgen7.getNodeBreakerView().getSwitch("SECT_BUS2").setOpen(true);
416441
vlgen7.getNodeBreakerView().getSwitch("SECT_BUS3").setOpen(true);
417442
vlgen7.getNodeBreakerView().getSwitch("SECT_BUS4").setOpen(true);
418-
vlgen7.getNodeBreakerView().getSwitch("FORK_SW1").setOpen(true);
419-
vlgen7.getNodeBreakerView().getSwitch("FORK_SW2").setOpen(true);
443+
// But keep fork connections
420444
Line line7 = network.getLine("LINE7_FORK");
421-
Terminal terminal = line7.getTerminal2();
422-
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
445+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(line7.getTerminal2());
446+
// Must find a busbar with open switch priority 2
423447
assertNotNull(result);
424-
assertEquals("BUS1_NGEN7", result.busbarSectionId());
425-
assertEquals(4, result.depth());
426-
assertEquals(3, result.switchesBeforeLast());
427448
assertNotNull(result.lastSwitch());
428-
assertEquals("SECT_BUS1", result.lastSwitch().id());
429-
assertEquals(SwitchKind.DISCONNECTOR, result.lastSwitch().kind());
430449
assertTrue(result.lastSwitch().isOpen());
431-
assertEquals(0, result.lastSwitch().node1());
432-
assertEquals(6, result.lastSwitch().node2());
433450
}
434451

435452
@Test
436-
void testPrefersShortestClosedPath() {
453+
void testReturnsResultEvenWithNoClosedPaths() {
454+
VoltageLevel vlgen7 = network.getVoltageLevel("VLGEN7");
455+
// Open all coupling switches but keep fork switches
456+
vlgen7.getNodeBreakerView().getSwitch("SECT_BUS1").setOpen(true);
457+
vlgen7.getNodeBreakerView().getSwitch("SECT_BUS2").setOpen(true);
437458
Line line7 = network.getLine("LINE7_FORK");
438-
Terminal terminal = line7.getTerminal2();
439-
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
440-
// BUS2 should be preferred (3 switches) over potential longer paths
459+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(line7.getTerminal2());
460+
// Must return a result (busbar accessible via open switch)
441461
assertNotNull(result);
442-
assertEquals("BUS2_NGEN7", result.busbarSectionId());
443-
assertEquals(4, result.depth());
462+
assertTrue(result.depth() > 0);
444463
}
445464

446465
@Test
447-
void testForkTopologySharesBusbar() {
466+
void testForkLinesShareSameBusbar() {
448467
Line line7 = network.getLine("LINE7_FORK");
449468
Line line8 = network.getLine("LINE8_FORK");
450469
String busbar7 = BusbarSectionFinderTraverser.findBusbarSectionId(line7.getTerminal2());
451470
String busbar8 = BusbarSectionFinderTraverser.findBusbarSectionId(line8.getTerminal1());
471+
// Both fork lines must find the same busbar
472+
assertNotNull(busbar7);
452473
assertEquals(busbar7, busbar8);
453474
assertEquals("BUS2_NGEN7", busbar7);
454475
}
@@ -472,4 +493,13 @@ void testHandlesMixedSwitchTypes() {
472493
// Path contains both breakers and disconnectors
473494
assertTrue(result.depth() > 0);
474495
}
496+
497+
@Test
498+
void testSwitchesBeforeLastCountAccuracy() {
499+
Line line7 = network.getLine("LINE7_FORK");
500+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(line7.getTerminal2());
501+
assertNotNull(result);
502+
// With depth=4, we must have 3 switches before the last one
503+
assertEquals(result.depth() - 1, result.switchesBeforeLast());
504+
}
475505
}

0 commit comments

Comments
 (0)