Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
work with Olivier PERRIN

commit

investigate tests

Add test

Migrate from CgmesControlArea to Area

Signed-off-by: Hugo SCHINDLER <hugo.schindler@rte-france.com>
  • Loading branch information
OpenSuze committed Feb 12, 2025
1 parent d376571 commit 4dffd5f
Show file tree
Hide file tree
Showing 9 changed files with 432 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Copyright (c) 2025, 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.entsoe.cgmes.balances_adjustment.util;

import com.powsybl.iidm.network.*;

import java.util.Optional;

/**
* @author Hugo Schindler{@literal <hugo.schindler at rte-france.com>}
*/
public final class CgmesAreaUtils {
private CgmesAreaUtils() {
// Utility class
}

static boolean hasAreaBoundaries(Area area) {
return area.getAreaBoundaryStream().map(AreaBoundary::getBoundary).anyMatch(Optional::isPresent);
}

static boolean hasAreaBoundaryTerminals(Area area) {
return area.getAreaBoundaryStream().map(AreaBoundary::getTerminal).anyMatch(Optional::isPresent);
}

static boolean isIdInAreaBoundaryTerminals(String elementId, Area area) {
return area.getAreaBoundaryStream()
.map(AreaBoundary::getTerminal)
.filter(Optional::isPresent)
.map(Optional::get)
.map(Terminal::getConnectable)
.map(Identifiable::getId)
.anyMatch(terminalId -> terminalId.equals(elementId));
}

static boolean isIdInAreaBoundariesDanglingLines(String elementId, Area area) {
return area.getAreaBoundaryStream()
.map(AreaBoundary::getBoundary)
.filter(Optional::isPresent)
.map(Optional::get)
.map(Boundary::getDanglingLine)
.map(Identifiable::getId)
.anyMatch(danglingLineId -> danglingLineId.equals(elementId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@
package com.powsybl.entsoe.cgmes.balances_adjustment.util;

import com.powsybl.balances_adjustment.util.NetworkArea;
import com.powsybl.cgmes.extensions.CgmesControlArea;
import com.powsybl.cgmes.extensions.CgmesDanglingLineBoundaryNode;
import com.powsybl.iidm.network.Bus;
import com.powsybl.iidm.network.Area;
import com.powsybl.iidm.network.DanglingLine;
import com.powsybl.iidm.network.Network;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
Expand All @@ -26,22 +23,16 @@ class CgmesBoundariesArea implements NetworkArea {

private final Set<DanglingLine> danglingLinesCache;

CgmesBoundariesArea(Network network, List<CgmesControlArea> areas) {
CgmesBoundariesArea(Network network, List<Area> areas) {
danglingLinesCache = network.getDanglingLineStream()
.filter(dl -> dl.getExtension(CgmesDanglingLineBoundaryNode.class) == null || !dl.getExtension(CgmesDanglingLineBoundaryNode.class).isHvdc())
.filter(dl -> dl.getTerminal().getBusView().getBus() != null && dl.getTerminal().getBusView().getBus().isInMainSynchronousComponent())
.filter(dl -> areas.isEmpty() || areas.stream().anyMatch(area -> area.getTerminals().stream().anyMatch(t -> t.getConnectable().getId().equals(dl.getId()))
|| area.getBoundaries().stream().anyMatch(b -> b.getDanglingLine().getId().equals(dl.getId()))))
.filter(dl -> areas.isEmpty() || areas.stream().anyMatch(area -> CgmesAreaUtils.isIdInAreaBoundaryTerminals(dl.getId(), area) || CgmesAreaUtils.isIdInAreaBoundariesDanglingLines(dl.getId(), area)))
.collect(Collectors.toSet());
}

@Override
public double getNetPosition() {
return danglingLinesCache.parallelStream().mapToDouble(dl -> dl.getTerminal().isConnected() ? -dl.getBoundary().getP() : 0).sum();
}

@Override
public Collection<Bus> getContainedBusViewBuses() {
return Collections.emptyList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import com.powsybl.balances_adjustment.util.NetworkArea;
import com.powsybl.balances_adjustment.util.NetworkAreaFactory;
import com.powsybl.cgmes.extensions.CgmesControlArea;
import com.powsybl.iidm.network.Area;
import com.powsybl.iidm.network.Network;

import java.util.ArrayList;
Expand All @@ -20,12 +20,12 @@
*/
public class CgmesBoundariesAreaFactory implements NetworkAreaFactory {

private final List<CgmesControlArea> areas = new ArrayList<>();
private final List<Area> areas = new ArrayList<>();

public CgmesBoundariesAreaFactory() {
}

public CgmesBoundariesAreaFactory(List<CgmesControlArea> areas) {
public CgmesBoundariesAreaFactory(List<Area> areas) {
this.areas.addAll(Objects.requireNonNull(areas));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
package com.powsybl.entsoe.cgmes.balances_adjustment.util;

import com.powsybl.balances_adjustment.util.NetworkArea;
import com.powsybl.cgmes.extensions.CgmesControlArea;
import com.powsybl.cgmes.extensions.CgmesDanglingLineBoundaryNode;
import com.powsybl.iidm.network.*;

Expand All @@ -26,7 +25,7 @@ class CgmesVoltageLevelsArea implements NetworkArea {

private final Set<Bus> busesCache;

CgmesVoltageLevelsArea(Network network, CgmesControlArea area, List<String> excludedXnodes, List<String> voltageLevelIds) {
CgmesVoltageLevelsArea(Network network, Area area, List<String> excludedXnodes, List<String> voltageLevelIds) {
this.voltageLevelIds.addAll(voltageLevelIds);

danglingLineBordersCache = createDanglingLinesCache(network, area, excludedXnodes);
Expand All @@ -38,14 +37,15 @@ class CgmesVoltageLevelsArea implements NetworkArea {
.collect(Collectors.toSet());
}

private List<DanglingLine> createDanglingLinesCache(Network network, CgmesControlArea area, List<String> excludedXnodes) {
private List<DanglingLine> createDanglingLinesCache(Network network, Area area, List<String> excludedXnodes) {
return network.getDanglingLineStream()
.filter(this::isAreaBorder)
.filter(dl -> dl.getTerminal().getBusView().getBus() != null && dl.getTerminal().getBusView().getBus().isInMainSynchronousComponent()) // Only consider connected dangling lines in main synchronous component (other synchronous components are not considered)
.filter(dl -> dl.getExtension(CgmesDanglingLineBoundaryNode.class) == null || !dl.getExtension(CgmesDanglingLineBoundaryNode.class).isHvdc()) // Dangling lines connected to DC boundary points are disregarded
.filter(dl -> {
if (area != null && (!area.getTerminals().isEmpty() || !area.getBoundaries().isEmpty())) { // if CgmesControlArea is defined, dangling lines with no associated tie flows are disregarded
return area.getTerminals().stream().anyMatch(t -> t.getConnectable().getId().equals(dl.getId())) || area.getBoundaries().stream().anyMatch(bd -> bd.getDanglingLine().getId().equals(dl.getId()));
if (area != null && (CgmesAreaUtils.hasAreaBoundaryTerminals(area) || CgmesAreaUtils.hasAreaBoundaries(area))) { // if CgmesControlArea is defined, dangling lines with no associated tie flows are disregarded
return CgmesAreaUtils.isIdInAreaBoundaryTerminals(dl.getId(), area) ||
CgmesAreaUtils.isIdInAreaBoundariesDanglingLines(dl.getId(), area);
}
return true;
})
Expand All @@ -58,15 +58,15 @@ private List<DanglingLine> createDanglingLinesCache(Network network, CgmesContro
.toList();
}

private List<? extends Branch<?>> createBranchesCache(Network network, CgmesControlArea area) {
private List<? extends Branch<?>> createBranchesCache(Network network, Area area) {
return network.getLineStream()
.filter(this::isAreaBorder)
.filter(b -> b.getTerminal1().getBusView().getBus() != null && b.getTerminal1().getBusView().getBus().isInMainSynchronousComponent()
&& b.getTerminal2().getBusView().getBus() != null && b.getTerminal2().getBusView().getBus().isInMainSynchronousComponent()) // Only consider branches connected on both sides and in main synchronous component (other synchronous components are not considered)
.filter(b -> !b.hasProperty("isHvdc")) // necessary as extensions of merged lines are not well handled. FIXME: when it is merged on mergingview, this should be deleted.
.filter(b -> {
if (area != null && (!area.getTerminals().isEmpty() || !area.getBoundaries().isEmpty())) { // if CgmesControlArea is defined, branches with no associated tie flows are disregarded
return area.getTerminals().stream().anyMatch(t -> b.getId().contains(t.getConnectable().getId()));
if (area != null && CgmesAreaUtils.hasAreaBoundaryTerminals(area)) { // if CgmesControlArea is defined, branches with no associated tie flows are disregarded
return CgmesAreaUtils.isIdInAreaBoundaryTerminals(b.getId(), area);
}
return true;
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import com.powsybl.balances_adjustment.util.NetworkArea;
import com.powsybl.balances_adjustment.util.NetworkAreaFactory;
import com.powsybl.cgmes.extensions.CgmesControlArea;
import com.powsybl.iidm.network.Area;
import com.powsybl.iidm.network.Network;

import java.util.Arrays;
Expand All @@ -20,23 +20,23 @@
*/
public class CgmesVoltageLevelsAreaFactory implements NetworkAreaFactory {

private final CgmesControlArea area;
private final Area area;
private final List<String> excludedXnodes;
private final List<String> voltageLevelIds;

public CgmesVoltageLevelsAreaFactory(CgmesControlArea area, String... voltageLevelIds) {
public CgmesVoltageLevelsAreaFactory(Area area, String... voltageLevelIds) {
this(area, Arrays.asList(voltageLevelIds));
}

public CgmesVoltageLevelsAreaFactory(CgmesControlArea area, List<String> voltageLevelIds) {
public CgmesVoltageLevelsAreaFactory(Area area, List<String> voltageLevelIds) {
this(area, null, voltageLevelIds);
}

public CgmesVoltageLevelsAreaFactory(List<String> excludedXnodes, List<String> voltageLevelIds) {
this(null, excludedXnodes, voltageLevelIds);
}

public CgmesVoltageLevelsAreaFactory(CgmesControlArea area, List<String> excludedXnodes, List<String> voltageLevelIds) {
public CgmesVoltageLevelsAreaFactory(Area area, List<String> excludedXnodes, List<String> voltageLevelIds) {
this.area = area;
this.excludedXnodes = excludedXnodes;
this.voltageLevelIds = Objects.requireNonNull(voltageLevelIds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@

import com.powsybl.balances_adjustment.util.NetworkArea;
import com.powsybl.balances_adjustment.util.NetworkAreaFactory;
import com.powsybl.cgmes.extensions.CgmesControlAreas;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.test.DanglingLineNetworkFactory;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;
Expand All @@ -38,21 +34,36 @@ void testWithNoArea() {
}

@Test
void testWithArea() {
void testWithAreaFromOldExtension() {
Network network = Network.read("controlArea.xiidm", getClass().getResourceAsStream("/controlArea.xiidm"));
NetworkAreaFactory factory = new CgmesBoundariesAreaFactory(new ArrayList<>(network.getExtension(CgmesControlAreas.class).getCgmesControlAreas()));
NetworkAreaFactory factory = new CgmesBoundariesAreaFactory(network.getAreaStream().toList());
NetworkArea area = factory.create(network);

List<Double> ps = Stream.of(
network.getDanglingLine("_78736387-5f60-4832-b3fe-d50daf81b0a6"),
network.getDanglingLine("_17086487-56ba-4979-b8de-064025a6b4da"),
network.getDanglingLine("_b18cd1aa-7808-49b9-a7cf-605eaf07b006"))
.map(dl -> dl.getBoundary().getP()).collect(Collectors.toList());
double sum = ps.stream().mapToDouble(n -> n).sum();
double sum = Stream.of(
network.getDanglingLine("_78736387-5f60-4832-b3fe-d50daf81b0a6"),
network.getDanglingLine("_17086487-56ba-4979-b8de-064025a6b4da"),
network.getDanglingLine("_b18cd1aa-7808-49b9-a7cf-605eaf07b006"))
.mapToDouble(dl -> dl.getBoundary().getP()).sum();

sum = sum + network.getTieLine("TL_fict").getDanglingLine1().getBoundary().getP();
// FIXME: we miss the line "_b58bf21a-096a-4dae-9a01-3f03b60c24c7_fict_2" because it is not a tie line.
assertEquals(-sum, area.getNetPosition(), DELTA_POWER);
assertTrue(area.getContainedBusViewBuses().isEmpty());
}

@Test
void testWithAreaWithoutAreaExtension() {
Network network = Network.read("controlAreaWithoutExtension.xml", getClass().getResourceAsStream("/controlAreaWithoutExtension.xml"));
NetworkAreaFactory factory = new CgmesBoundariesAreaFactory(network.getAreaStream().toList());
NetworkArea area = factory.create(network);

double sum = Stream.of(
network.getDanglingLine("_78736387-5f60-4832-b3fe-d50daf81b0a6"),
network.getDanglingLine("_17086487-56ba-4979-b8de-064025a6b4da"),
network.getDanglingLine("_b18cd1aa-7808-49b9-a7cf-605eaf07b006"))
.mapToDouble(dl -> dl.getBoundary().getP()).sum();

assertEquals(-sum, area.getNetPosition(), DELTA_POWER);
assertTrue(area.getContainedBusViewBuses().isEmpty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@

import com.powsybl.balances_adjustment.util.NetworkArea;
import com.powsybl.balances_adjustment.util.NetworkAreaFactory;
import com.powsybl.cgmes.extensions.CgmesControlArea;
import com.powsybl.cgmes.extensions.CgmesControlAreas;
import com.powsybl.iidm.network.Area;
import com.powsybl.iidm.network.Line;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.TieLine;
Expand All @@ -25,14 +24,13 @@
*/
class CgmesVoltageLevelsAreaTest {

private final String[] voltageLevelsIds = {"_d0486169-2205-40b2-895e-b672ecb9e5fc", "_4ba71b59-ee2f-450b-9f7d-cc2f1cc5e386", "_8bbd7e74-ae20-4dce-8780-c20f8e18c2e0", "_469df5f7-058f-4451-a998-57a48e8a56fe", "_b10b171b-3bc5-4849-bb1f-61ed9ea1ec7c"};
private final Network network = Network.read("controlArea.xiidm", getClass().getResourceAsStream("/controlArea.xiidm"));

static final double DELTA_POWER = 1e-5;

@Test
void testWithArea() {
CgmesControlArea cgmesArea = network.getExtension(CgmesControlAreas.class).getCgmesControlArea("_BECONTROLAREA");
void testWithAreaFromOldExtension() {
String[] voltageLevelsIds = {"_d0486169-2205-40b2-895e-b672ecb9e5fc", "_4ba71b59-ee2f-450b-9f7d-cc2f1cc5e386", "_8bbd7e74-ae20-4dce-8780-c20f8e18c2e0", "_469df5f7-058f-4451-a998-57a48e8a56fe", "_b10b171b-3bc5-4849-bb1f-61ed9ea1ec7c"};
Network network = Network.read("controlArea.xiidm", getClass().getResourceAsStream("/controlArea.xiidm"));
Area cgmesArea = network.getArea("_BECONTROLAREA");
NetworkAreaFactory factory = new CgmesVoltageLevelsAreaFactory(cgmesArea, voltageLevelsIds);
NetworkArea area = factory.create(network);
assertEquals(5, area.getContainedBusViewBuses().size());
Expand All @@ -51,7 +49,9 @@ void testWithArea() {
}

@Test
void testWithExcludedXnodes() {
void testWithExcludedXnodesFromOldExtension() {
String[] voltageLevelsIds = {"_d0486169-2205-40b2-895e-b672ecb9e5fc", "_4ba71b59-ee2f-450b-9f7d-cc2f1cc5e386", "_8bbd7e74-ae20-4dce-8780-c20f8e18c2e0", "_469df5f7-058f-4451-a998-57a48e8a56fe", "_b10b171b-3bc5-4849-bb1f-61ed9ea1ec7c"};
Network network = Network.read("controlArea.xiidm", getClass().getResourceAsStream("/controlArea.xiidm"));
NetworkAreaFactory factory = new CgmesVoltageLevelsAreaFactory(Arrays.asList("TN_Border_GY11", "XNODE"), Arrays.asList(voltageLevelsIds));
NetworkArea area = factory.create(network);
assertEquals(5, area.getContainedBusViewBuses().size());
Expand All @@ -65,4 +65,41 @@ void testWithExcludedXnodes() {
+ lineFlow;
assertEquals(realNetPosition, area.getNetPosition(), DELTA_POWER);
}

@Test
void testWithAreaWithoutAreaExtension() {
String[] voltageLevelsIds = {"_d0486169-2205-40b2-895e-b672ecb9e5fc", "_4ba71b59-ee2f-450b-9f7d-cc2f1cc5e386", "_8bbd7e74-ae20-4dce-8780-c20f8e18c2e0", "_469df5f7-058f-4451-a998-57a48e8a56fe", "_b10b171b-3bc5-4849-bb1f-61ed9ea1ec7c"};
Network network = Network.read("controlAreaWithoutExtension.xml", getClass().getResourceAsStream("/controlAreaWithoutExtension.xml"));
Area cgmesArea = network.getArea("_BECONTROLAREA");
NetworkAreaFactory factory = new CgmesVoltageLevelsAreaFactory(cgmesArea, voltageLevelsIds);
NetworkArea area = factory.create(network);
assertEquals(5, area.getContainedBusViewBuses().size());

Line line = network.getLine("_b58bf21a-096a-4dae-9a01-3f03b60c24c7_fict_2");
double lineFlow = (line.getTerminal2().getP() - line.getTerminal1().getP()) / 2;
double realNetPosition = -network.getDanglingLine("_78736387-5f60-4832-b3fe-d50daf81b0a6").getBoundary().getP()
- network.getDanglingLine("_17086487-56ba-4979-b8de-064025a6b4da").getBoundary().getP()
- network.getDanglingLine("_b18cd1aa-7808-49b9-a7cf-605eaf07b006").getBoundary().getP()
+ lineFlow;
assertEquals(realNetPosition, area.getNetPosition(), DELTA_POWER);
}

@Test
void testWithExcludedXnodesWithoutAreaExtension() {
String[] voltageLevelsIds = {"_d0486169-2205-40b2-895e-b672ecb9e5fc", "_4ba71b59-ee2f-450b-9f7d-cc2f1cc5e386", "_8bbd7e74-ae20-4dce-8780-c20f8e18c2e0", "_469df5f7-058f-4451-a998-57a48e8a56fe", "_b10b171b-3bc5-4849-bb1f-61ed9ea1ec7c"};
Network network = Network.read("controlAreaWithoutExtension.xml", getClass().getResourceAsStream("/controlAreaWithoutExtension.xml"));
NetworkAreaFactory factory = new CgmesVoltageLevelsAreaFactory(Arrays.asList("TN_Border_GY11", "XNODE"), Arrays.asList(voltageLevelsIds));
NetworkArea area = factory.create(network);
assertEquals(5, area.getContainedBusViewBuses().size());
Line line1 = network.getLine("_b58bf21a-096a-4dae-9a01-3f03b60c24c7_fict");
Line line2 = network.getLine("_b58bf21a-096a-4dae-9a01-3f03b60c24c7_fict_2");
double lineFlow = (line1.getTerminal2().getP() - line1.getTerminal1().getP()) / 2
+ (line2.getTerminal1().getP() - line2.getTerminal2().getP()) / 2;
double realNetPosition = -network.getDanglingLine("_78736387-5f60-4832-b3fe-d50daf81b0a6").getBoundary().getP()
- network.getDanglingLine("_17086487-56ba-4979-b8de-064025a6b4da").getBoundary().getP()
- network.getDanglingLine("_ed0c5d75-4a54-43c8-b782-b20d7431630b").getBoundary().getP()
+ lineFlow;
assertEquals(realNetPosition, area.getNetPosition(), DELTA_POWER);
}

}
Loading

0 comments on commit 4dffd5f

Please sign in to comment.