Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing shape #405

Merged
merged 5 commits into from
Jul 21, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
*/
package com.powsybl.sld.layout;

import com.powsybl.sld.model.cells.*;
import com.powsybl.sld.model.cells.Cell;
import com.powsybl.sld.model.cells.ExternCell;
import com.powsybl.sld.model.cells.InternCell;
import com.powsybl.sld.model.cells.ShuntCell;
import com.powsybl.sld.model.coordinate.Side;
import com.powsybl.sld.model.graphs.VoltageLevelGraph;
import com.powsybl.sld.model.nodes.BusNode;
import com.powsybl.sld.model.nodes.Node;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -122,12 +124,12 @@ static List<LegBusSet> createLegBusSets(VoltageLevelGraph graph, Map<BusNode, In
manageShunts(graph, externCells, legBusSets, nodeToNb);
}

externCells.forEach(cell -> pushNewLBS(legBusSets, nodeToNb, cell, Side.UNDEFINED));
externCells.forEach(cell -> pushLBS(legBusSets, new LegBusSet(nodeToNb, cell)));

graph.getInternCellStream()
.filter(cell -> cell.checkIsShape(InternCell.Shape.UNILEG))
.sorted(Comparator.comparing(Cell::getFullId)) // if order is not yet defined & avoid randomness
.forEachOrdered(cell -> pushNewLBS(legBusSets, nodeToNb, cell, Side.UNDEFINED));
.forEachOrdered(cell -> pushLBS(legBusSets, new LegBusSet(nodeToNb, cell, Side.UNDEFINED)));

graph.getInternCellStream()
.filter(cell -> cell.checkIsNotShape(InternCell.Shape.UNILEG, InternCell.Shape.UNHANDLEDPATTERN))
Expand Down Expand Up @@ -166,7 +168,7 @@ private static void manageShunts(VoltageLevelGraph graph, List<ExternCell> exter

sameBusNodesShuntCells.stream().filter(scs -> scs.size() > 2).flatMap(List::stream)
.forEach(sc -> {
pushNewLBS(legBusSets, nodeToNb, sc, Side.UNDEFINED);
pushLBS(legBusSets, new LegBusSet(nodeToNb, sc));
externCells.removeAll(sc.getSideCells());
});
}
Expand All @@ -175,29 +177,20 @@ private static boolean crossContains(List<BusNode> busNodes1, List<BusNode> busN
return busNodes1.containsAll(busNodes2) && busNodes2.containsAll(busNodes1);
}

private static void pushNewLBS(List<LegBusSet> legBusSets, Map<BusNode, Integer> nodeToNb, Cell cell, Side side) {
LegBusSet legBusSet;
if (cell.getType() == Cell.CellType.EXTERN) {
legBusSet = new LegBusSet(nodeToNb, (ExternCell) cell);
} else if (cell.getType() == Cell.CellType.SHUNT) {
legBusSet = new LegBusSet(nodeToNb, (ShuntCell) cell);
} else {
legBusSet = new LegBusSet(nodeToNb, (InternCell) cell, side);
}

public static void pushLBS(List<LegBusSet> legBusSets, LegBusSet legBusSet) {
for (LegBusSet lbs : legBusSets) {
if (lbs.contains(legBusSet)) {
lbs.absorbs(legBusSet);
return;
}
}
List<LegBusSet> absorbedLBS = new ArrayList<>();
legBusSets.forEach(lbs -> {
for (LegBusSet lbs : legBusSets) {
if (legBusSet.contains(lbs)) {
absorbedLBS.add(lbs);
legBusSet.absorbs(lbs);
}
});
}
legBusSets.removeAll(absorbedLBS);
legBusSets.add(legBusSet);
}
Expand All @@ -210,7 +203,7 @@ private static void pushNonUnilegInternCell(List<LegBusSet> legBusSets, Map<BusN
return;
}
}
pushNewLBS(legBusSets, nodeToNb, internCell, Side.LEFT);
pushNewLBS(legBusSets, nodeToNb, internCell, Side.RIGHT);
pushLBS(legBusSets, new LegBusSet(nodeToNb, internCell, Side.LEFT));
pushLBS(legBusSets, new LegBusSet(nodeToNb, internCell, Side.RIGHT));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,20 +128,15 @@ private static void identifyVerticalInternCells(VoltageLevelGraph graph, List<Su
Map<InternCell, Subsection> verticalCells = new LinkedHashMap<>();

graph.getInternCellStream()
.filter(c -> c.checkIsNotShape(InternCell.Shape.UNILEG, InternCell.Shape.UNDEFINED, InternCell.Shape.UNHANDLEDPATTERN))
.filter(c -> c.checkIsNotShape(InternCell.Shape.UNILEG, InternCell.Shape.UNHANDLEDPATTERN))
.forEach(c ->
subsections.stream()
.filter(subsection -> subsection.containsAllBusNodes(c.getBusNodes()))
.findAny().ifPresent(subsection -> verticalCells.putIfAbsent(c, subsection)));

subsections.forEach(ss -> {
List<InternCellSide> icsToRemove = ss.internCellSides.stream()
.filter(ics -> verticalCells.keySet().contains(ics.getCell())).collect(Collectors.toList());
ss.internCellSides.removeAll(icsToRemove);
});
.findFirst().ifPresent(subsection -> verticalCells.putIfAbsent(c, subsection)));

verticalCells.forEach((cell, sub) -> {
cell.setShape(InternCell.Shape.VERTICAL);
sub.internCellSides.removeIf(ics -> ics.getCell() == cell);
sub.internCellSides.add(new InternCellSide(cell, Side.UNDEFINED));
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,21 @@ public void organizeBlocks() {
assignLeg(serialRootBlock, candidateLegs.get(1));
body = serialRootBlock.extractBody(new ArrayList<>(legs.values()));
body.setOrientation(Orientation.RIGHT);

// if one bus on each side, the intern cell is either flat or vertical
// if more than one bus on one side, the intern cell is
// - either crossover (two sections): detected later in Subsection::identifyCrossOverAndCheckOrientation
// - or vertical (one section): detected later in Subsection::identifyVerticalInternCells
if (candidateLegs.stream().map(LegBlock::getBusNodes).allMatch(bn -> bn.size() == 1)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first sight, an UNILEG could be tagged as MAYBEFLAT if it is connected to a single bus (this case is actually very weird), maybe you should perform the test on UNILEG first

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, indeed, good catch! But as this is unrelated to current issue and as it implies deeper changes, I'll create an issue about that.

shape = Shape.MAYBEFLAT;
}
} else {
if (candidateLegs.size() != 1) {
if (candidateLegs.size() == 1) {
shape = Shape.UNILEG;
LegBlock leg = candidateLegs.get(0);
legs.put(Side.UNDEFINED, leg);
leg.setOrientation(Orientation.UP);
} else {
if (exceptionIfPatternNotHandled) {
throw new PowsyblException("InternCell pattern not recognized");
} else {
Expand All @@ -95,14 +108,6 @@ public void organizeBlocks() {
}
}
}
if (candidateLegs.size() == 1) {
shape = Shape.UNILEG;
LegBlock leg = candidateLegs.get(0);
legs.put(Side.UNDEFINED, leg);
leg.setOrientation(Orientation.UP);
} else if (candidateLegs.size() == 2 && getBusNodes().size() == 2) {
shape = Shape.MAYBEFLAT;
}
}

public void setFlat() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,34 @@ public void test() {
// write Json and compare to reference
assertEquals(toString("/TestCase3Coupling.json"), toJson(g, "/TestCase3Coupling.json"));
}

@Test
public void test3Bars() {
createSwitch(vl, "d3", "d3", SwitchKind.DISCONNECTOR, false, false, false, 2, 4);
createBusBarSection(vl, "bbs3", "bbs3", 4, 3, 1);

// build graph
VoltageLevelGraph g = graphBuilder.buildVoltageLevelGraph(vl.getId());

// Run layout
voltageLevelGraphLayout(g);

// write Json and compare to reference
assertEquals(toString("/TestCase3Coupling3Bars.json"), toJson(g, "/TestCase3Coupling3Bars.json"));
}

@Test
public void test3Bars2Sections() {
createSwitch(vl, "d3", "d3", SwitchKind.DISCONNECTOR, false, false, false, 2, 4);
createBusBarSection(vl, "bbs3", "bbs3", 4, 1, 2);

// build graph
VoltageLevelGraph g = graphBuilder.buildVoltageLevelGraph(vl.getId());

// Run layout
voltageLevelGraphLayout(g);

// write Json and compare to reference
assertEquals(toString("/TestCase3Coupling3Bars2Sections.json"), toJson(g, "/TestCase3Coupling3Bars2Sections.json"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
*/
package com.powsybl.sld.iidm;

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.sld.builders.NetworkGraphBuilder;
import com.powsybl.sld.model.graphs.VoltageLevelGraph;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -26,12 +30,19 @@
*
* @author Florian Dupuy <florian.dupuy at rte-france.com>
*/
public class TestCase3TripleCoupling extends TestCase3Coupling {
public class TestCase3TripleCoupling extends AbstractTestCaseIidm {

@Before
public void setUp() {
// we add two other coupling to TestCase3Coupling setUp
super.setUp();
network = Network.create("testCase2", "test");
graphBuilder = new NetworkGraphBuilder(network);
substation = createSubstation(network, "s", "s", Country.FR);
vl = createVoltageLevel(substation, "vl", "vl", TopologyKind.NODE_BREAKER, 380, 10);
createBusBarSection(vl, "bbs1", "bbs1", 0, 1, 1);
createSwitch(vl, "d1", "d1", SwitchKind.DISCONNECTOR, false, false, false, 0, 1);
createSwitch(vl, "b", "b", SwitchKind.BREAKER, false, false, false, 1, 2);
createSwitch(vl, "d2", "d2", SwitchKind.DISCONNECTOR, false, false, false, 2, 3);
createBusBarSection(vl, "bbs2", "bbs2", 3, 2, 1);

// second coupling
createSwitch(vl, "d3", "d3", SwitchKind.DISCONNECTOR, false, false, false, 0, 4);
Expand Down
Loading