TestTopologyCalculation.java
/**
* Copyright (c) 2019, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.powsybl.sld.iidm;
import com.powsybl.diagram.test.Networks;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.SwitchKind;
import com.powsybl.iidm.network.TopologyKind;
import com.powsybl.iidm.network.extensions.ConnectablePosition;
import com.powsybl.sld.builders.NetworkGraphBuilder;
import com.powsybl.sld.model.graphs.VoltageLevelGraph;
import com.powsybl.sld.model.nodes.Node;
import com.powsybl.sld.model.nodes.SwitchNode;
import com.powsybl.sld.util.TopologicallyConnectedNodesSet;
import com.powsybl.sld.util.TopologyCalculation;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* <PRE>
* lA lB
* | \ |
* bA1 bA2 bB
* | / / \
* dA d11 --------- b1 -------- d12 dB1 dB2
* | | | | |
* bbs 1.1 -----x----x-------d1-------x-- | -----x---- | -- bbs 1.2
* bbs 2.1 ----------x-d21-x-b2-x-d22-x---x------------x--- bbs 2.2
* </PRE>
*
* @author Benoit Jeanson {@literal <benoit.jeanson at rte-france.com>}
* @author Nicolas Duchene
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
* @author Franck Lecuyer {@literal <franck.lecuyer at rte-france.com>}
*/
class TestTopologyCalculation extends AbstractTestCaseIidm {
@BeforeEach
public void setUp() {
network = Network.create("testCase1", "test");
graphBuilder = new NetworkGraphBuilder(network);
substation = Networks.createSubstation(network, "s", "s", Country.FR);
vl = Networks.createVoltageLevel(substation, "vl", "vl", TopologyKind.NODE_BREAKER, 380);
Networks.createBusBarSection(vl, "bbs1.1", "bbs1.1", 0, 1, 1);
Networks.createBusBarSection(vl, "bbs1.2", "bbs1.2", 1, 1, 2);
Networks.createBusBarSection(vl, "bbs2.1", "bbs2.1", 2, 2, 1);
Networks.createBusBarSection(vl, "bbs2.2", "bbs2.2", 3, 2, 2);
Networks.createLoad(vl, "lA", "lA", "lA", 0, ConnectablePosition.Direction.TOP, 4, 10, 10);
Networks.createSwitch(vl, "bA1", "bA1", SwitchKind.BREAKER, false, false, false, 4, 5);
Networks.createSwitch(vl, "bA2", "bA2", SwitchKind.BREAKER, false, false, false, 4, 5);
Networks.createSwitch(vl, "dA", "dA", SwitchKind.DISCONNECTOR, false, false, false, 0, 5);
Networks.createSwitch(vl, "d11", "d11", SwitchKind.DISCONNECTOR, false, false, false, 0, 6);
Networks.createSwitch(vl, "b1", "b1", SwitchKind.BREAKER, false, false, false, 6, 7);
Networks.createSwitch(vl, "d12", "d12", SwitchKind.DISCONNECTOR, false, false, false, 7, 3);
Networks.createSwitch(vl, "d21", "d21", SwitchKind.DISCONNECTOR, false, false, false, 2, 8);
Networks.createSwitch(vl, "b2", "b2", SwitchKind.BREAKER, false, false, false, 8, 9);
Networks.createSwitch(vl, "d22", "d22", SwitchKind.DISCONNECTOR, false, false, false, 9, 3);
Networks.createSwitch(vl, "d1", "d1", SwitchKind.DISCONNECTOR, false, false, false, 0, 1);
Networks.createLoad(vl, "lB", "lB", "lB", 1, ConnectablePosition.Direction.TOP, 10, 10, 10);
Networks.createSwitch(vl, "bB", "bB", SwitchKind.BREAKER, false, false, false, 10, 11);
Networks.createSwitch(vl, "dB1", "dB1", SwitchKind.DISCONNECTOR, false, false, false, 11, 1);
Networks.createSwitch(vl, "dB2", "dB2", SwitchKind.DISCONNECTOR, false, false, false, 11, 3);
}
public void assertTopo(List<TopologicallyConnectedNodesSet> tcnss,
int expectedNbTcns,
int exploredIndex,
int expectedNbNodes,
int expectedNbBorderSwitches) {
assertEquals(expectedNbTcns, tcnss.size());
TopologicallyConnectedNodesSet tcns = tcnss.get(exploredIndex);
assertEquals(expectedNbNodes, tcns.getNodes().size());
assertEquals(expectedNbBorderSwitches, tcns.getBorderNodes().size());
}
@Test
void test() {
// build graph
VoltageLevelGraph g = graphBuilder.buildVoltageLevelGraph(vl.getId());
TopologyCalculation topologyCalculation = new TopologyCalculation();
List<TopologicallyConnectedNodesSet> tcnss = topologyCalculation.findConnectedNodeSets(g);
assertTopo(tcnss, 1, 0, 25, 0);
((SwitchNode) g.getNode("bA1")).setOpen(true);
tcnss = topologyCalculation.findConnectedNodeSets(g);
assertTopo(tcnss, 1, 0, 25, 0);
((SwitchNode) g.getNode("bA2")).setOpen(true);
tcnss = topologyCalculation.findConnectedNodeSets(g);
assertTopo(tcnss, 2, 0, 24, 2);
assertTopo(tcnss, 2, 1, 3, 2);
((SwitchNode) g.getNode("d1")).setOpen(true);
tcnss = topologyCalculation.findConnectedNodeSets(g);
assertTopo(tcnss, 2, 0, 24, 2);
assertTopo(tcnss, 2, 1, 3, 2);
((SwitchNode) g.getNode("b1")).setOpen(true);
tcnss = topologyCalculation.findConnectedNodeSets(g);
assertTopo(tcnss, 3, 0, 9, 4);
assertTopo(tcnss, 3, 1, 17, 2);
assertTopo(tcnss, 3, 2, 3, 2);
((SwitchNode) g.getNode("dB2")).setOpen(true);
tcnss = topologyCalculation.findConnectedNodeSets(g);
assertTopo(tcnss, 4, 0, 9, 4);
assertTopo(tcnss, 4, 1, 7, 2);
assertTopo(tcnss, 4, 2, 11, 2);
assertTopo(tcnss, 4, 3, 3, 2);
tcnss = topologyCalculation.findConnectedNodeSets(g, this::bordersBreakersOnly);
assertTopo(tcnss, 1, 0, 3, 2);
tcnss = topologyCalculation.findConnectedNodeSets(g, this::feedersSetsOnly);
assertTopo(tcnss, 2, 0, 7, 2);
assertTopo(tcnss, 2, 1, 3, 2);
}
private boolean feedersSetsOnly(TopologicallyConnectedNodesSet topologicallyConnectedNodesSet) {
return topologicallyConnectedNodesSet.getNodes().stream().anyMatch(node -> node.getType() == Node.NodeType.FEEDER);
}
private boolean bordersBreakersOnly(TopologicallyConnectedNodesSet topologicallyConnectedNodesSet) {
return topologicallyConnectedNodesSet.getBorderNodes().stream()
.filter(SwitchNode.class::isInstance)
.map(SwitchNode.class::cast)
.allMatch(switchNode -> switchNode.getKind() == SwitchNode.SwitchKind.BREAKER);
}
}