From d6772a22cff9285e91853a334f6b05b62d05ee56 Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Mon, 25 Mar 2024 17:27:21 +0100 Subject: [PATCH 1/8] Add fictitious bus if none in no-fictitious nodes connected component Signed-off-by: Florian Dupuy --- .../com/powsybl/sld/layout/GraphRefiner.java | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java index dbadf1aac..4dacdb8d0 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java @@ -6,7 +6,6 @@ */ package com.powsybl.sld.layout; -import com.powsybl.commons.PowsyblException; import com.powsybl.sld.model.graphs.NodeFactory; import com.powsybl.sld.model.graphs.VoltageLevelGraph; import com.powsybl.sld.model.nodes.BusNode; @@ -78,20 +77,25 @@ private void handleConnectedComponents(VoltageLevelGraph graph) { .map(setNodes -> setNodes.stream().map(Node::getId).collect(Collectors.toSet())) .forEach(strings -> LOGGER.warn(" - {}", strings)); } - connectedSets.forEach(s -> ensureOneBusInConnectedComponent(graph, s)); + // Add a fictitious bus for all connected components without any bus + connectedSets.stream() + .filter(s -> s.stream().noneMatch(node -> node.getType() == Node.NodeType.BUS)) + .forEach(s -> addFictitiousBusInConnectedComponent(graph, s)); } - private void ensureOneBusInConnectedComponent(VoltageLevelGraph graph, Set nodes) { - if (nodes.stream().anyMatch(node -> node.getType() == Node.NodeType.BUS)) { - return; - } - Node biggestFn = nodes.stream() - .filter(node -> node.getType() == Node.NodeType.INTERNAL) - .min(Comparator.comparingInt(node -> node.getAdjacentEdges().size()) - .reversed() - .thenComparing(Node::getId)) // for stable fictitious node selection, also sort on id - .orElseThrow(() -> new PowsyblException("Empty node set")); - graph.substituteNode(biggestFn, NodeFactory.createFictitiousBusNode(graph, biggestFn.getId() + "FictitiousBus")); + private void addFictitiousBusInConnectedComponent(VoltageLevelGraph graph, Set nodes) { + // Replace the most meshed fictitious node by a fictitious BusNode. + // If no fictitious node, insert a fictitious BusNode at the first node of the set. + nodes.stream().filter(node -> node.getType() == Node.NodeType.INTERNAL) + .min(Comparator.comparingInt(node -> node.getAdjacentEdges().size()).reversed().thenComparing(Node::getId)) // for stable fictitious node selection, also sort on id + .ifPresentOrElse( + mostMeshedFictitiousNode -> graph.substituteNode(mostMeshedFictitiousNode, + NodeFactory.createFictitiousBusNode(graph, mostMeshedFictitiousNode.getId() + "_FictitiousBus")), + () -> { + Node attachedNode = nodes.iterator().next(); + BusNode busNode = NodeFactory.createFictitiousBusNode(graph, attachedNode.getId() + "_FictitiousBus"); + graph.addEdge(busNode, attachedNode); + }); } private Predicate getNodesOnBusPredicate(VoltageLevelGraph graph, List componentsOnBusbars) { From 15580253a9564e17b00ace3a3bdfaef15aa75fc6 Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Tue, 26 Mar 2024 09:32:36 +0100 Subject: [PATCH 2/8] Fixes and adding unit test Signed-off-by: Florian Dupuy --- .../com/powsybl/diagram/test/Networks.java | 91 +++++++ .../com/powsybl/sld/layout/GraphRefiner.java | 9 +- .../powsybl/sld/model/graphs/NodeFactory.java | 4 +- .../sld/iidm/TestCaseFictitiousBus.java | 98 ++----- .../TestCaseFictitiousBusDanglingLoad.svg | 252 ++++++++++++++++++ 5 files changed, 376 insertions(+), 78 deletions(-) create mode 100644 single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBusDanglingLoad.svg diff --git a/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java b/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java index 250e638cb..fc6e1cd32 100644 --- a/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java +++ b/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java @@ -1724,6 +1724,10 @@ public static VoltageLevel createVoltageLevel(Substation s, String id, String na .add(); } + public static void createSwitch(VoltageLevel vl, String id, SwitchKind kind, boolean retained, boolean open, boolean fictitious, int node1, int node2) { + createSwitch(vl, id, id, kind, retained, open, fictitious, node1, node2); + } + public static void createSwitch(VoltageLevel vl, String id, String name, SwitchKind kind, boolean retained, boolean open, boolean fictitious, int node1, int node2) { vl.getNodeBreakerView().newSwitch() .setId(id) @@ -1744,6 +1748,10 @@ public static void createInternalConnection(VoltageLevel vl, int node1, int node .add(); } + public static void createBusBarSection(VoltageLevel vl, String id, int node, int busbarIndex, int sectionIndex) { + createBusBarSection(vl, id, id, node, busbarIndex, sectionIndex); + } + public static void createBusBarSection(VoltageLevel vl, String id, String name, int node, int busbarIndex, int sectionIndex) { BusbarSection bbs = vl.getNodeBreakerView().newBusbarSection() .setId(id) @@ -1756,6 +1764,11 @@ public static void createBusBarSection(VoltageLevel vl, String id, String name, .add(); } + public static void createLoad(VoltageLevel vl, String id, Integer feederOrder, + ConnectablePosition.Direction direction, int node, double p0, double q0) { + createLoad(vl, id, id, id, feederOrder, direction, node, p0, q0); + } + public static void createLoad(VoltageLevel vl, String id, String name, String feederName, Integer feederOrder, ConnectablePosition.Direction direction, int node, double p0, double q0) { Load load = vl.newLoad() @@ -2264,6 +2277,84 @@ public static Network createNetworkWithComplexInternCellDifferentSubsections() { return network; } + /** + *
+     *     vl1  vl2
+     *     |    |
+     * L1  |    |  L2
+     *     |    |
+     *     --*---  Fictitious busbar section
+     *       |
+     *   L3  |
+     *       |
+     *       vl3
+     *
+     * 
+ */ + public static Network createTeePointNetwork() { + Network network = Network.create("testCase1", "test"); + VoltageLevel vl = network.newVoltageLevel() + .setId("vl") + .setNominalV(50) + .setTopologyKind(TopologyKind.NODE_BREAKER) + .add(); + + VoltageLevel vl1 = network.newVoltageLevel() + .setId("vl1") + .setNominalV(10) + .setTopologyKind(TopologyKind.NODE_BREAKER) + .add(); + + VoltageLevel vl2 = network.newVoltageLevel() + .setId("vl2") + .setNominalV(30) + .setTopologyKind(TopologyKind.NODE_BREAKER) + .add(); + + VoltageLevel vl3 = network.newVoltageLevel() + .setId("vl3") + .setNominalV(10) + .setTopologyKind(TopologyKind.NODE_BREAKER) + .add(); + + createInternalConnection(vl, 1, 0); + createInternalConnection(vl, 2, 0); + createInternalConnection(vl, 3, 0); + + createLine(network, "L1", "L1", 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, + 1, 10, vl.getId(), vl1.getId(), + "L1", 0, ConnectablePosition.Direction.TOP, + "L1", 1, ConnectablePosition.Direction.TOP); + + createLine(network, "L2", "L2", 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, + 2, 20, vl.getId(), vl2.getId(), + "L2", 1, ConnectablePosition.Direction.BOTTOM, + "L2", 0, ConnectablePosition.Direction.TOP); + + createLine(network, "L3", "L3", 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, + 3, 30, vl.getId(), vl3.getId(), + "L3", 2, ConnectablePosition.Direction.TOP, + "L3", 0, ConnectablePosition.Direction.TOP); + + return network; + } + + public static Network createDanglingLoadNetwork() { + Network network = Network.create("testDLoad", "testDLoad"); + VoltageLevel vl = network.newVoltageLevel() + .setId("vl") + .setNominalV(50) + .setTopologyKind(TopologyKind.NODE_BREAKER) + .add(); + createLoad(vl, "dLoad", 2, ConnectablePosition.Direction.BOTTOM, 0, 0, 0); + createBusBarSection(vl, "bbs1", 1, 1, 1); + createBusBarSection(vl, "bbs2", 2, 1, 2); + createSwitch(vl, "d", SwitchKind.DISCONNECTOR, true, false, false, 1, 3); + createSwitch(vl, "d12", SwitchKind.DISCONNECTOR, true, false, false, 1, 2); + createLoad(vl, "load", 1, ConnectablePosition.Direction.TOP, 3, 0, 0); + return network; + } + public static void createLine(Bus bus1, Bus bus2) { String id = String.format("%s - %s", bus1.getVoltageLevel().getSubstation().orElseThrow().getId(), diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java index 4dacdb8d0..a1fc53d6c 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java @@ -85,15 +85,16 @@ private void handleConnectedComponents(VoltageLevelGraph graph) { private void addFictitiousBusInConnectedComponent(VoltageLevelGraph graph, Set nodes) { // Replace the most meshed fictitious node by a fictitious BusNode. - // If no fictitious node, insert a fictitious BusNode at the first node of the set. + // If no fictitious node, insert a fictitious BusNode at the first node of the set (sorted in alphabetical order). + int sectionIndex = 1 + graph.getNodeBuses().stream().mapToInt(BusNode::getSectionIndex).max().orElse(0); nodes.stream().filter(node -> node.getType() == Node.NodeType.INTERNAL) .min(Comparator.comparingInt(node -> node.getAdjacentEdges().size()).reversed().thenComparing(Node::getId)) // for stable fictitious node selection, also sort on id .ifPresentOrElse( mostMeshedFictitiousNode -> graph.substituteNode(mostMeshedFictitiousNode, - NodeFactory.createFictitiousBusNode(graph, mostMeshedFictitiousNode.getId() + "_FictitiousBus")), + NodeFactory.createFictitiousBusNode(graph, mostMeshedFictitiousNode.getId() + "_FictitiousBus", 1, sectionIndex)), () -> { - Node attachedNode = nodes.iterator().next(); - BusNode busNode = NodeFactory.createFictitiousBusNode(graph, attachedNode.getId() + "_FictitiousBus"); + Node attachedNode = nodes.stream().min(Comparator.comparing(Node::getId)).orElse(nodes.iterator().next()); + BusNode busNode = NodeFactory.createFictitiousBusNode(graph, attachedNode.getId() + "_FictitiousBus", 1, sectionIndex); graph.addEdge(busNode, attachedNode); }); } diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/model/graphs/NodeFactory.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/model/graphs/NodeFactory.java index 61116ee52..2e14ea1b0 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/model/graphs/NodeFactory.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/model/graphs/NodeFactory.java @@ -56,9 +56,9 @@ public static BusNode createBusNode(VoltageLevelGraph graph, String id, String n return bn; } - public static BusNode createFictitiousBusNode(VoltageLevelGraph graph, String id) { + public static BusNode createFictitiousBusNode(VoltageLevelGraph graph, String id, int busbarIndex, int sectionIndex) { BusNode bn = new BusNode(id, null, true); - bn.setBusBarIndexSectionIndex(1, 1); + bn.setBusBarIndexSectionIndex(busbarIndex, sectionIndex); graph.addNode(bn); return bn; } diff --git a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCaseFictitiousBus.java b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCaseFictitiousBus.java index 48bff6a29..a422392d8 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCaseFictitiousBus.java +++ b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCaseFictitiousBus.java @@ -8,94 +8,31 @@ package com.powsybl.sld.iidm; import com.powsybl.diagram.test.Networks; -import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.TopologyKind; -import com.powsybl.iidm.network.VoltageLevel; -import com.powsybl.iidm.network.extensions.ConnectablePosition; import com.powsybl.sld.builders.NetworkGraphBuilder; import com.powsybl.sld.model.graphs.VoltageLevelGraph; import com.powsybl.sld.svg.styles.iidm.TopologicalStyleProvider; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.io.IOException; + import static org.junit.jupiter.api.Assertions.assertEquals; /** - *
- *     vl1  vl2
- *     |    |
- * L1  |    |  L2
- *     |    |
- *     --*---  Fictitious busbar section
- *       |
- *   L3  |
- *       |
- *       vl3
- *
- * 
- * * @author Thomas Adam {@literal } */ class TestCaseFictitiousBus extends AbstractTestCaseIidm { - private VoltageLevel vl1; - private VoltageLevel vl2; - private VoltageLevel vl3; - - @BeforeEach - public void setUp() { - network = Network.create("testCase1", "test"); - graphBuilder = new NetworkGraphBuilder(network); - substation = null; - vl = network.newVoltageLevel() - .setId("vl") - .setNominalV(50) - .setTopologyKind(TopologyKind.NODE_BREAKER) - .add(); - - vl1 = network.newVoltageLevel() - .setId("vl1") - .setNominalV(10) - .setTopologyKind(TopologyKind.NODE_BREAKER) - .add(); - - vl2 = network.newVoltageLevel() - .setId("vl2") - .setNominalV(30) - .setTopologyKind(TopologyKind.NODE_BREAKER) - .add(); - - vl3 = network.newVoltageLevel() - .setId("vl3") - .setNominalV(10) - .setTopologyKind(TopologyKind.NODE_BREAKER) - .add(); - - Networks.createInternalConnection(vl, 1, 0); - Networks.createInternalConnection(vl, 2, 0); - Networks.createInternalConnection(vl, 3, 0); - - Networks.createLine(network, "L1", "L1", 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, - 1, 10, vl.getId(), vl1.getId(), - "L1", 0, ConnectablePosition.Direction.TOP, - "L1", 1, ConnectablePosition.Direction.TOP); - - Networks.createLine(network, "L2", "L2", 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, - 2, 20, vl.getId(), vl2.getId(), - "L2", 1, ConnectablePosition.Direction.BOTTOM, - "L2", 0, ConnectablePosition.Direction.TOP); - - Networks.createLine(network, "L3", "L3", 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, - 3, 30, vl.getId(), vl3.getId(), - "L3", 2, ConnectablePosition.Direction.TOP, - "L3", 0, ConnectablePosition.Direction.TOP); - + @Override + public void setUp() throws IOException { + // no common setup } @Test void testBasic() { + network = Networks.createTeePointNetwork(); + // build graph - VoltageLevelGraph g = graphBuilder.buildVoltageLevelGraph(vl.getId()); + VoltageLevelGraph g = new NetworkGraphBuilder(network).buildVoltageLevelGraph("vl"); // Run layout voltageLevelGraphLayout(g); @@ -107,8 +44,10 @@ void testBasic() { @Test void testTopological() { + network = Networks.createTeePointNetwork(); + // build graph - VoltageLevelGraph g = graphBuilder.buildVoltageLevelGraph(vl.getId()); + VoltageLevelGraph g = new NetworkGraphBuilder(network).buildVoltageLevelGraph("vl"); // Run layout voltageLevelGraphLayout(g); @@ -117,4 +56,19 @@ void testTopological() { assertEquals(toString("/TestCaseFictitiousBusTopological.svg"), toSVG(g, "/TestCaseFictitiousBusTopological.svg", componentLibrary, layoutParameters, svgParameters, getDefaultDiagramLabelProvider(), new TopologicalStyleProvider(network))); } + + @Test + void testDanglingLoad() { + network = Networks.createDanglingLoadNetwork(); + + // build graph + VoltageLevelGraph g = new NetworkGraphBuilder(network).buildVoltageLevelGraph("vl"); + + // Run layout + voltageLevelGraphLayout(g); + + // write Json and compare to reference + assertEquals(toString("/TestCaseFictitiousBusDanglingLoad.svg"), + toSVG(g, "/TestCaseFictitiousBusDanglingLoad.svg", componentLibrary, layoutParameters, svgParameters, getDefaultDiagramLabelProvider(), new TopologicalStyleProvider(network))); + } } diff --git a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBusDanglingLoad.svg b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBusDanglingLoad.svg new file mode 100644 index 000000000..6e28f7506 --- /dev/null +++ b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBusDanglingLoad.svg @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + L1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + L2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + L3 + + + + From c49cae955f8a3d2db19abdf8aa8e9c707e38e7ae Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Tue, 26 Mar 2024 10:19:32 +0100 Subject: [PATCH 3/8] Add one more load in unit test Signed-off-by: Florian Dupuy --- .../com/powsybl/diagram/test/Networks.java | 14 +- .../com/powsybl/sld/layout/GraphRefiner.java | 8 +- .../com/powsybl/sld/AbstractTestCase.java | 2 - .../TestCaseFictitiousBusDanglingLoad.svg | 144 ++++++++++++------ 4 files changed, 111 insertions(+), 57 deletions(-) diff --git a/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java b/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java index fc6e1cd32..12f0a11c4 100644 --- a/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java +++ b/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java @@ -2346,12 +2346,14 @@ public static Network createDanglingLoadNetwork() { .setNominalV(50) .setTopologyKind(TopologyKind.NODE_BREAKER) .add(); - createLoad(vl, "dLoad", 2, ConnectablePosition.Direction.BOTTOM, 0, 0, 0); - createBusBarSection(vl, "bbs1", 1, 1, 1); - createBusBarSection(vl, "bbs2", 2, 1, 2); - createSwitch(vl, "d", SwitchKind.DISCONNECTOR, true, false, false, 1, 3); - createSwitch(vl, "d12", SwitchKind.DISCONNECTOR, true, false, false, 1, 2); - createLoad(vl, "load", 1, ConnectablePosition.Direction.TOP, 3, 0, 0); + createBusBarSection(vl, "bbs1", 0, 1, 1); + createBusBarSection(vl, "bbs2", 1, 1, 2); + createSwitch(vl, "d", SwitchKind.DISCONNECTOR, true, false, false, 0, 2); + createSwitch(vl, "d12", SwitchKind.DISCONNECTOR, true, false, false, 0, 1); + createSwitch(vl, "ddl2", SwitchKind.DISCONNECTOR, true, false, false, 4, 5); + createLoad(vl, "load", 1, ConnectablePosition.Direction.TOP, 2, 0, 0); + createLoad(vl, "dLoad1", 2, ConnectablePosition.Direction.BOTTOM, 3, 0, 0); + createLoad(vl, "dLoad2", 0, ConnectablePosition.Direction.TOP, 4, 0, 0); return network; } diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java index a1fc53d6c..7e1fa14f4 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java @@ -90,10 +90,12 @@ private void addFictitiousBusInConnectedComponent(VoltageLevelGraph graph, Set node.getType() == Node.NodeType.INTERNAL) .min(Comparator.comparingInt(node -> node.getAdjacentEdges().size()).reversed().thenComparing(Node::getId)) // for stable fictitious node selection, also sort on id .ifPresentOrElse( - mostMeshedFictitiousNode -> graph.substituteNode(mostMeshedFictitiousNode, - NodeFactory.createFictitiousBusNode(graph, mostMeshedFictitiousNode.getId() + "_FictitiousBus", 1, sectionIndex)), + mostMeshedFictitiousNode -> { + BusNode busNode = NodeFactory.createFictitiousBusNode(graph, mostMeshedFictitiousNode.getId() + "_FictitiousBus", 1, sectionIndex); + graph.substituteNode(mostMeshedFictitiousNode, busNode); + }, () -> { - Node attachedNode = nodes.stream().min(Comparator.comparing(Node::getId)).orElse(nodes.iterator().next()); + Node attachedNode = nodes.stream().min(Comparator.comparing(Node::getId)).orElse(nodes.iterator().next()); // for stable node selection BusNode busNode = NodeFactory.createFictitiousBusNode(graph, attachedNode.getId() + "_FictitiousBus", 1, sectionIndex); graph.addEdge(busNode, attachedNode); }); diff --git a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/AbstractTestCase.java b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/AbstractTestCase.java index 7828644e5..92d16260d 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/AbstractTestCase.java +++ b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/AbstractTestCase.java @@ -32,8 +32,6 @@ */ public abstract class AbstractTestCase { - private static final Pattern SVG_FIX_PATTERN = Pattern.compile(">\\s*(<\\!\\[CDATA\\[.*?]]>)\\s* - + - - + + + bbs1 - - - + + + bbs2 + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + - - + + - + - + - - + + + - + - + - - L1 + + + + + load - - - + + + - - + + - - + + - + - + - + - + - + - - L2 + + + + + dLoad1 - - - + + + - - + + - - + + - + - + - - + + + - + - + - - L3 + + + + + dLoad2 From 625da816390476d4cc63360903618b30ebcaf0f5 Mon Sep 17 00:00:00 2001 From: Sophie Frasnedo Date: Tue, 26 Mar 2024 11:02:27 +0100 Subject: [PATCH 4/8] Fix checkstyle Signed-off-by: Sophie Frasnedo --- .../src/test/java/com/powsybl/sld/AbstractTestCase.java | 1 - 1 file changed, 1 deletion(-) diff --git a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/AbstractTestCase.java b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/AbstractTestCase.java index 92d16260d..dfd6994ad 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/AbstractTestCase.java +++ b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/AbstractTestCase.java @@ -25,7 +25,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Objects; -import java.util.regex.Pattern; /** * @author Benoit Jeanson {@literal } From ac256993fe483b5387f2509f65b92e462b148c13 Mon Sep 17 00:00:00 2001 From: Sophie Frasnedo Date: Tue, 26 Mar 2024 11:05:19 +0100 Subject: [PATCH 5/8] Update test references Signed-off-by: Sophie Frasnedo --- .../test/resources/TestCaseFictitiousBus.svg | 26 +++++++++---------- .../TestCaseFictitiousBusTopological.svg | 26 +++++++++---------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBus.svg b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBus.svg index 84c8fc7c2..1396ea15b 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBus.svg +++ b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBus.svg @@ -151,14 +151,14 @@ ]]> - + - + - + @@ -174,10 +174,10 @@ - + - + @@ -188,10 +188,10 @@ - + - + @@ -207,10 +207,10 @@ - + - + @@ -221,10 +221,10 @@ - + - + @@ -240,10 +240,10 @@ - + - + diff --git a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBusTopological.svg b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBusTopological.svg index 6e28f7506..39d32ca6e 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBusTopological.svg +++ b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBusTopological.svg @@ -146,14 +146,14 @@ ]]> - + - + - + @@ -169,10 +169,10 @@ - + - + @@ -183,10 +183,10 @@ - + - + @@ -202,10 +202,10 @@ - + - + @@ -216,10 +216,10 @@ - + - + @@ -235,10 +235,10 @@ - + - + From b562e8ba10f3482f1cd980e956fd35d3176a17aa Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Tue, 26 Mar 2024 12:01:54 +0100 Subject: [PATCH 6/8] Adding generator in unit test Signed-off-by: Florian Dupuy --- .../main/java/com/powsybl/diagram/test/Networks.java | 12 ++++++++++-- .../com/powsybl/sld/iidm/TestCaseFictitiousBus.java | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java b/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java index 12f0a11c4..c95315641 100644 --- a/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java +++ b/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java @@ -1781,6 +1781,13 @@ public static void createLoad(VoltageLevel vl, String id, String name, String fe addFeederPosition(load, feederName, feederOrder, direction); } + public static void createGenerator(VoltageLevel vl, String id, Integer feederOrder, + ConnectablePosition.Direction direction, int node, + double minP, double maxP, boolean voltageRegulator, + double targetP, double targetQ) { + createGenerator(vl, id, id, id, feederOrder, direction, node, minP, maxP, voltageRegulator, targetP, targetQ); + } + public static void createGenerator(VoltageLevel vl, String id, String name, String feederName, Integer feederOrder, ConnectablePosition.Direction direction, int node, double minP, double maxP, boolean voltageRegulator, @@ -2339,7 +2346,7 @@ public static Network createTeePointNetwork() { return network; } - public static Network createDanglingLoadNetwork() { + public static Network createDanglingConnectablesNetwork() { Network network = Network.create("testDLoad", "testDLoad"); VoltageLevel vl = network.newVoltageLevel() .setId("vl") @@ -2353,7 +2360,8 @@ public static Network createDanglingLoadNetwork() { createSwitch(vl, "ddl2", SwitchKind.DISCONNECTOR, true, false, false, 4, 5); createLoad(vl, "load", 1, ConnectablePosition.Direction.TOP, 2, 0, 0); createLoad(vl, "dLoad1", 2, ConnectablePosition.Direction.BOTTOM, 3, 0, 0); - createLoad(vl, "dLoad2", 0, ConnectablePosition.Direction.TOP, 4, 0, 0); + createLoad(vl, "dLoad2", 0, ConnectablePosition.Direction.TOP, 4, 10, 0); + createGenerator(vl, "dGen", null, ConnectablePosition.Direction.TOP, 5, 50, 100, false, 100, 400); return network; } diff --git a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCaseFictitiousBus.java b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCaseFictitiousBus.java index a422392d8..d3e2b1836 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCaseFictitiousBus.java +++ b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCaseFictitiousBus.java @@ -58,8 +58,8 @@ void testTopological() { } @Test - void testDanglingLoad() { - network = Networks.createDanglingLoadNetwork(); + void testDanglingConnectables() { + network = Networks.createDanglingConnectablesNetwork(); // build graph VoltageLevelGraph g = new NetworkGraphBuilder(network).buildVoltageLevelGraph("vl"); From f7a25124df7fd47c1a5f19c95e85a7be0142702c Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Tue, 26 Mar 2024 12:38:52 +0100 Subject: [PATCH 7/8] Fix unit test problematic case Signed-off-by: Florian Dupuy --- .../com/powsybl/sld/layout/GraphRefiner.java | 11 ++-- .../sld/model/graphs/VoltageLevelGraph.java | 9 +++ .../TestCaseFictitiousBusDanglingLoad.svg | 62 +++++++++++++++---- 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java index 7e1fa14f4..d69730c08 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/GraphRefiner.java @@ -85,19 +85,20 @@ private void handleConnectedComponents(VoltageLevelGraph graph) { private void addFictitiousBusInConnectedComponent(VoltageLevelGraph graph, Set nodes) { // Replace the most meshed fictitious node by a fictitious BusNode. - // If no fictitious node, insert a fictitious BusNode at the first node of the set (sorted in alphabetical order). + // If no fictitious node, insert/add a fictitious BusNode at the most meshed node of the set. + Comparator mostMeshedComparator = Comparator.comparingInt(node -> node.getAdjacentEdges().size()).reversed().thenComparing(Node::getId); // for stable fictitious node selection, also sort on id int sectionIndex = 1 + graph.getNodeBuses().stream().mapToInt(BusNode::getSectionIndex).max().orElse(0); nodes.stream().filter(node -> node.getType() == Node.NodeType.INTERNAL) - .min(Comparator.comparingInt(node -> node.getAdjacentEdges().size()).reversed().thenComparing(Node::getId)) // for stable fictitious node selection, also sort on id + .min(mostMeshedComparator) .ifPresentOrElse( mostMeshedFictitiousNode -> { BusNode busNode = NodeFactory.createFictitiousBusNode(graph, mostMeshedFictitiousNode.getId() + "_FictitiousBus", 1, sectionIndex); graph.substituteNode(mostMeshedFictitiousNode, busNode); }, () -> { - Node attachedNode = nodes.stream().min(Comparator.comparing(Node::getId)).orElse(nodes.iterator().next()); // for stable node selection - BusNode busNode = NodeFactory.createFictitiousBusNode(graph, attachedNode.getId() + "_FictitiousBus", 1, sectionIndex); - graph.addEdge(busNode, attachedNode); + Node mostMeshedNode = nodes.stream().min(mostMeshedComparator).orElseThrow(); // always non-empty set + BusNode busNode = NodeFactory.createFictitiousBusNode(graph, mostMeshedNode.getId() + "_FictitiousBus", 1, sectionIndex); + graph.insertNodeNextTo(busNode, mostMeshedNode); }); } diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/model/graphs/VoltageLevelGraph.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/model/graphs/VoltageLevelGraph.java index 4a8919278..485d675eb 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/model/graphs/VoltageLevelGraph.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/model/graphs/VoltageLevelGraph.java @@ -730,6 +730,15 @@ private void substituteInternalMiddle2wtByEquipmentNode(FeederNode feederNode) { } } + public void insertNodeNextTo(Node nodeToInsert, Node adjacentNode) { + List neighbours = adjacentNode.getAdjacentNodes(); + if (neighbours.isEmpty()) { + addEdge(nodeToInsert, adjacentNode); + } else { + insertNode(adjacentNode, nodeToInsert, neighbours.get(0)); + } + } + private record GroundDisconnection(List nodes, FeederNode ground, SwitchNode disconnector, Node forkNode) { } } diff --git a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBusDanglingLoad.svg b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBusDanglingLoad.svg index da3eea046..a9ca6f9de 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBusDanglingLoad.svg +++ b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCaseFictitiousBusDanglingLoad.svg @@ -1,5 +1,5 @@ - +