Skip to content

Commit

Permalink
Merge branch 'main' into bump_core_610
Browse files Browse the repository at this point in the history
  • Loading branch information
So-Fras authored Dec 11, 2023
2 parents c5a8420 + fe9215f commit 93ffc71
Show file tree
Hide file tree
Showing 5 changed files with 1,924 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import com.powsybl.nad.utils.iidm.IidmUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.function.Predicate;
Expand All @@ -19,8 +21,12 @@
*/
public class VoltageLevelFilter implements Predicate<VoltageLevel> {

protected static final Logger LOGGER = LoggerFactory.getLogger(VoltageLevelFilter.class);

public static final Predicate<VoltageLevel> NO_FILTER = voltageLevel -> true;

private static final String UNKNOWN_VOLTAGE_LEVEL = "Unknown voltage level id '";

private final Set<VoltageLevel> voltageLevels;

public VoltageLevelFilter(Set<VoltageLevel> voltageLevels) {
Expand All @@ -40,43 +46,55 @@ public boolean test(VoltageLevel voltageLevel) {
return voltageLevels.contains(voltageLevel);
}

public static VoltageLevelFilter createVoltageLevelsFilter(Network network, List<String> voltageLevelIds) {
return createVoltageLevelsDepthFilter(network, voltageLevelIds, 0);
}

public static VoltageLevelFilter createVoltageLevelDepthFilter(Network network, String voltageLevelId, int depth) {
Objects.requireNonNull(network);
Objects.requireNonNull(voltageLevelId);
return createVoltageLevelsDepthFilter(network, List.of(voltageLevelId), depth);
}

Set<VoltageLevel> voltageLevels = new HashSet<>();
VoltageLevel vl = network.getVoltageLevel(voltageLevelId);
if (vl == null) {
throw new PowsyblException("Unknown voltage level id '" + voltageLevelId + "'");
}
public static VoltageLevelFilter createVoltageLevelsDepthFilter(Network network, List<String> voltageLevelIds, int depth) {
return createVoltageLevelFilterWithPredicate(network, voltageLevelIds, depth, NO_FILTER);
}

Set<VoltageLevel> startingSet = new HashSet<>();
startingSet.add(vl);
traverseVoltageLevels(startingSet, depth, voltageLevels);
return new VoltageLevelFilter(voltageLevels);
public static VoltageLevelFilter createNominalVoltageLowerBoundFilter(Network network, List<String> voltageLevelIds, double nominalVoltageLowerBound, int depth) {
return createNominalVoltageFilter(network, voltageLevelIds, nominalVoltageLowerBound, Double.MAX_VALUE, depth);
}

public static VoltageLevelFilter createVoltageLevelsDepthFilter(Network network, List<String> voltageLevelIds, int depth) {
public static VoltageLevelFilter createNominalVoltageUpperBoundFilter(Network network, List<String> voltageLevelIds, double nominalVoltageUpperBound, int depth) {
return createNominalVoltageFilter(network, voltageLevelIds, 0, nominalVoltageUpperBound, depth);
}

public static VoltageLevelFilter createNominalVoltageFilter(Network network, List<String> voltageLevelIds,
double nominalVoltageLowerBound, double nominalVoltageUpperBound,
int depth) {
checkVoltageBoundValues(nominalVoltageLowerBound, nominalVoltageUpperBound);
Predicate<VoltageLevel> voltageLevelPredicate = voltageLevel -> voltageLevel.getNominalV() >= nominalVoltageLowerBound && voltageLevel.getNominalV() <= nominalVoltageUpperBound;

return createVoltageLevelFilterWithPredicate(network, voltageLevelIds, depth, voltageLevelPredicate);
}

public static VoltageLevelFilter createVoltageLevelFilterWithPredicate(Network network, List<String> voltageLevelIds, int depth, Predicate<VoltageLevel> voltageLevelPredicate) {
Objects.requireNonNull(network);
Objects.requireNonNull(voltageLevelIds);
Set<VoltageLevel> startingSet = new HashSet<>();

for (String voltageLevelId : voltageLevelIds) {
VoltageLevel vl = network.getVoltageLevel(voltageLevelId);
if (vl == null) {
throw new PowsyblException("Unknown voltage level id '" + voltageLevelId + "'");
throw new PowsyblException(UNKNOWN_VOLTAGE_LEVEL + voltageLevelId + "'");
}
if (!voltageLevelPredicate.test(vl)) {
LOGGER.warn("vl '{}' does not comply with the predicate", voltageLevelId);
}
startingSet.add(vl);
}

Set<VoltageLevel> voltageLevels = new HashSet<>();
traverseVoltageLevels(startingSet, depth, voltageLevels);
VoltageLevelFilter.traverseVoltageLevels(startingSet, depth, voltageLevels, voltageLevelPredicate);
return new VoltageLevelFilter(voltageLevels);
}

public static VoltageLevelFilter createVoltageLevelsFilter(Network network, List<String> voltageLevelIds) {
return createVoltageLevelsDepthFilter(network, voltageLevelIds, 0);
}

public static Collection<VoltageLevel> getNextDepthVoltageLevels(Network network, List<VoltageLevel> voltageLevels) {
List<String> voltageLevelIds = voltageLevels.stream().map(VoltageLevel::getId).collect(Collectors.toList());
VoltageLevelFilter voltageLevelFilter = createVoltageLevelsDepthFilter(network, voltageLevelIds, 1);
Expand All @@ -85,27 +103,38 @@ public static Collection<VoltageLevel> getNextDepthVoltageLevels(Network network
return voltageLevelSet;
}

private static void traverseVoltageLevels(Set<VoltageLevel> voltageLevelsDepth, int depth, Set<VoltageLevel> visitedVoltageLevels) {
private static void traverseVoltageLevels(Set<VoltageLevel> voltageLevelsDepth, int depth, Set<VoltageLevel> visitedVoltageLevels, Predicate<VoltageLevel> predicate) {
if (depth < 0) {
return;
}
Set<VoltageLevel> nextDepthVoltageLevels = new HashSet<>();
for (VoltageLevel vl : voltageLevelsDepth) {
if (!visitedVoltageLevels.contains(vl)) {
visitedVoltageLevels.add(vl);
vl.visitEquipments(new VlVisitor(nextDepthVoltageLevels, visitedVoltageLevels));
vl.visitEquipments(new VlVisitor(nextDepthVoltageLevels, visitedVoltageLevels, predicate));
}
}
traverseVoltageLevels(nextDepthVoltageLevels, depth - 1, visitedVoltageLevels);
traverseVoltageLevels(nextDepthVoltageLevels, depth - 1, visitedVoltageLevels, predicate);
}

private static void checkVoltageBoundValues(double nominalVoltageLowerBound, double nominalVoltageUpperBound) {
if (nominalVoltageLowerBound < 0 || nominalVoltageUpperBound < 0) {
throw new PowsyblException("Voltage bounds must be positive");
}
if (nominalVoltageLowerBound > nominalVoltageUpperBound) {
throw new PowsyblException("Low bound must be less than or equal to high bound");
}
}

private static class VlVisitor extends DefaultTopologyVisitor {
private final Set<VoltageLevel> nextDepthVoltageLevels;
private final Set<VoltageLevel> visitedVoltageLevels;
private final Predicate<VoltageLevel> voltageLevelPredicate;

public VlVisitor(Set<VoltageLevel> nextDepthVoltageLevels, Set<VoltageLevel> visitedVoltageLevels) {
public VlVisitor(Set<VoltageLevel> nextDepthVoltageLevels, Set<VoltageLevel> visitedVoltageLevels, Predicate<VoltageLevel> voltageLevelPredicate) {
this.nextDepthVoltageLevels = nextDepthVoltageLevels;
this.visitedVoltageLevels = visitedVoltageLevels;
this.voltageLevelPredicate = voltageLevelPredicate;
}

@Override
Expand Down Expand Up @@ -143,7 +172,7 @@ private void visitBranch(Branch<?> branch, TwoSides side) {

private void visitTerminal(Terminal terminal) {
VoltageLevel voltageLevel = terminal.getVoltageLevel();
if (!visitedVoltageLevels.contains(voltageLevel)) {
if (!visitedVoltageLevels.contains(voltageLevel) && voltageLevelPredicate.test(voltageLevel)) {
nextDepthVoltageLevels.add(voltageLevel);
}
}
Expand All @@ -155,5 +184,4 @@ public void visitDanglingLine(DanglingLine danglingLine) {
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@
*/
package com.powsybl.nad;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import com.powsybl.commons.PowsyblException;
import com.powsybl.diagram.test.Networks;
import com.powsybl.ieeecdf.converter.IeeeCdfNetworkFactory;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.test.*;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
import com.powsybl.nad.build.iidm.VoltageLevelFilter;
import com.powsybl.nad.layout.LayoutParameters;
import com.powsybl.nad.svg.LabelProvider;
Expand All @@ -21,12 +26,14 @@
import com.powsybl.nad.svg.iidm.NominalVoltageStyleProvider;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;

import java.nio.file.FileSystem;
import java.nio.file.Path;
import java.util.*;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static com.powsybl.nad.build.iidm.VoltageLevelFilter.NO_FILTER;
import static org.junit.jupiter.api.Assertions.*;

/**
* @author Thomas Adam {@literal <tadam at silicom.fr>}
Expand Down Expand Up @@ -62,7 +69,7 @@ void testDrawSvg() {
NadParameters nadParameters = new NadParameters()
.setSvgParameters(getSvgParameters())
.setStyleProviderFactory(this::getStyleProvider);
NetworkAreaDiagram.draw(network, svgFile, nadParameters, VoltageLevelFilter.NO_FILTER);
NetworkAreaDiagram.draw(network, svgFile, nadParameters, NO_FILTER);
assertEquals(toString("/dangling_line_connected.svg"), getContentFile(svgFile));
}

Expand All @@ -75,4 +82,69 @@ void testGetVisibleVoltageLevels() {
ids = NetworkAreaDiagram.getDisplayedVoltageLevels(network, List.of("VLHV1"), 2);
assertEquals("VLGEN, VLHV1, VLHV2, VLLOAD", String.join(", ", ids));
}

@Test
void testVoltageFilteredDiagramTwoBounds() {
Network network = IeeeCdfNetworkFactory.create14();
Path svgFileVoltageFilter = fileSystem.getPath("nad-test-voltage-filter.svg");
NetworkAreaDiagram.draw(network, svgFileVoltageFilter, new NadParameters(), VoltageLevelFilter.createNominalVoltageFilter(network, List.of("VL4"), 120, 180, 2));
assertEquals(toString("/IEEE_14_bus_voltage_filter1.svg"), getContentFile(svgFileVoltageFilter));
}

@Test
void testVoltageFilteredDiagramLowBound() {
Network network = IeeeCdfNetworkFactory.create14();
Path svgFileVoltageFilter = fileSystem.getPath("nad-test-voltage-filter.svg");
NetworkAreaDiagram.draw(network, svgFileVoltageFilter, new NadParameters(), VoltageLevelFilter.createNominalVoltageLowerBoundFilter(network, List.of("VL4"), 120, 2));
assertEquals(toString("/IEEE_14_bus_voltage_filter1.svg"), getContentFile(svgFileVoltageFilter));
}

@Test
void testVoltageFilteredDiagramHighBound() {
Network network = IeeeCdfNetworkFactory.create14();
Path svgFileVoltageFilter = fileSystem.getPath("nad-test-voltage-filter.svg");
NetworkAreaDiagram.draw(network, svgFileVoltageFilter, new NadParameters(), VoltageLevelFilter.createNominalVoltageUpperBoundFilter(network, List.of("VL4"), 180, 2));
assertEquals(toString("/IEEE_14_bus_voltage_filter2.svg"), getContentFile(svgFileVoltageFilter));
}

@Test
void testVoltageFilteredDiagramOutOfBound() {
ListAppender<ILoggingEvent> logWatcher = new ListAppender<>();
logWatcher.start();
((Logger) LoggerFactory.getLogger(VoltageLevelFilter.class)).addAppender(logWatcher);
Network network = IeeeCdfNetworkFactory.create14();
Path svgFileVoltageFilter = fileSystem.getPath("nad-test-voltage-filter.svg");
List<String> voltageLevelList = List.of("VL4");
VoltageLevelFilter voltageLevelFilter = VoltageLevelFilter.createNominalVoltageUpperBoundFilter(network, voltageLevelList, 130, 2);
NetworkAreaDiagram.draw(network, svgFileVoltageFilter, new NadParameters(), voltageLevelFilter);

List<ILoggingEvent> logsList = logWatcher.list;
assertEquals(1, logsList.size());
assertEquals("vl 'VL4' does not comply with the predicate", logsList.get(0).getFormattedMessage());
assertEquals(toString("/IEEE_14_bus_voltage_filter3.svg"), getContentFile(svgFileVoltageFilter));
}

@Test
void testVoltageFilteredDiagramNegativeBound() {
Network network = IeeeCdfNetworkFactory.create14();
List<String> voltageLevelList = List.of("VL4");
PowsyblException e = assertThrows(PowsyblException.class, () -> VoltageLevelFilter.createNominalVoltageFilter(network, voltageLevelList, -100, 180, 2));
assertTrue(e.getMessage().contains("Voltage bounds must be positive"));
}

@Test
void testVoltageFilteredDiagramInconsistentBounds() {
Network network = IeeeCdfNetworkFactory.create14();
List<String> voltageLevelList = List.of("VL4");
PowsyblException e = assertThrows(PowsyblException.class, () -> VoltageLevelFilter.createNominalVoltageFilter(network, voltageLevelList, 180, 90, 2));
assertTrue(e.getMessage().contains("Low bound must be less than or equal to high bound"));
}

@Test
void testVoltageFilteredDiagramUnexistingVoltageLevel() {
Network network = IeeeCdfNetworkFactory.create14();
List<String> voltageLevelList = List.of("VL456");
PowsyblException e = assertThrows(PowsyblException.class, () -> VoltageLevelFilter.createNominalVoltageUpperBoundFilter(network, voltageLevelList, 90, 2));
assertTrue(e.getMessage().contains("Unknown voltage level id 'VL456'"));
}
}
Loading

0 comments on commit 93ffc71

Please sign in to comment.