com.powsybl.cgmes.conversion.elements.hvdc.IslandEndHvdc Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of powsybl-cgmes-conversion Show documentation
Show all versions of powsybl-cgmes-conversion Show documentation
Conversion between CGMES and IIDM Network definitions
/**
* Copyright (c) 2020, 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.cgmes.conversion.elements.hvdc;
import com.powsybl.cgmes.conversion.elements.hvdc.Adjacency.AdjacentType;
import com.powsybl.cgmes.conversion.elements.hvdc.NodeEquipment.EquipmentReference;
import com.powsybl.commons.PowsyblException;
import java.util.*;
import java.util.stream.Collectors;
/**
*
* @author Luma Zamarreño {@literal }
* @author José Antonio Marqués {@literal }
*/
class IslandEndHvdc {
// TN: n transformers (n >= 0), C1: one acDcConverter, LS1: one dcLineSegment
// TN: n transformers (n >= 0), C2: two acDcConverters, LS1: one dcLineSegment
// TN: n transformers (n >= 0), CN: n acDcConverters, LSN: 2 * CN (Two dcLineSegments by acDcConverter)
// TN: n transformers (n >= 0), C1: one acDcConverter, LS2: two dcLineSegments
// TN: n transformers (n >= 0), CN: n acDcConverters (usually 2), LSN: n dcLineSegments (usually 2)
enum HvdcEndType {
HVDC_TN_C1_LS1, HVDC_TN_C2_LS1, HVDC_TN_CN_LS2N, HVDC_TN_CN_LSN
}
private final List hvdc;
IslandEndHvdc() {
hvdc = new ArrayList<>();
}
void add(Adjacency adjacency, NodeEquipment nodeEquipment, List islandNodesEnd) {
if (islandNodesEnd.isEmpty()) {
return;
}
Set visitedNodes = new HashSet<>();
Set usedAcDcConverters = new HashSet<>();
// islandNodesEnd can contain more than one hvdc configuration
// Select the node with transformers where are more acDcConverters connected to
Optional nodeEndWithTransformers = nodeConnectedToTransformersWithMoreAcDcConvertersConnectedTo(nodeEquipment, islandNodesEnd, visitedNodes);
while (nodeEndWithTransformers.isPresent()) {
Set acDcConverters = add(adjacency, nodeEquipment, visitedNodes, nodeEndWithTransformers.get(), islandNodesEnd);
usedAcDcConverters.addAll(acDcConverters);
nodeEndWithTransformers = nodeConnectedToTransformersWithMoreAcDcConvertersConnectedTo(nodeEquipment, islandNodesEnd, visitedNodes);
}
// IslandsEnds without transformers
// Select the node where are more acDcConverters connected to, avoiding used acDcConverters
Optional nodeEnd = nodeWithMoreAcDcConvertersConnectedTo(nodeEquipment, islandNodesEnd, visitedNodes, usedAcDcConverters);
while (nodeEnd.isPresent()) {
Set acDcConverters = add(adjacency, nodeEquipment, visitedNodes, nodeEnd.get(), islandNodesEnd);
usedAcDcConverters.addAll(acDcConverters);
nodeEnd = nodeWithMoreAcDcConvertersConnectedTo(nodeEquipment, islandNodesEnd, visitedNodes, usedAcDcConverters);
}
}
private static Optional nodeConnectedToTransformersWithMoreAcDcConvertersConnectedTo(NodeEquipment nodeEquipment,
List islandNodesEnd, Set visitedNodes) {
return notVisitedNodesSortedByAcDcConvertersConnectedTo(nodeEquipment, islandNodesEnd, visitedNodes).stream()
.filter(nodeEquipment::containsAnyTransformer).findFirst();
}
private static Optional nodeWithMoreAcDcConvertersConnectedTo(NodeEquipment nodeEquipment,
List islandNodesEnd, Set visitedNodes, Set usedAcDcConverters) {
return notVisitedNodesSortedByNotUsedAcDcConvertersConnectedTo(nodeEquipment, islandNodesEnd, visitedNodes, usedAcDcConverters).stream().findFirst();
}
// Not visited nodes connected to acDcConverters sorted by number of acDcConverters connected to
// First node = node with more acDcConverters connected to
private static List notVisitedNodesSortedByAcDcConvertersConnectedTo(NodeEquipment nodeEquipment,
List islandNodesEnd, Set visitedNodes) {
return islandNodesEnd.stream().filter(nodeEnd -> !visitedNodes.contains(nodeEnd) && nodeEquipment.containsAnyAcDcConverter(nodeEnd))
.sorted(Comparator.comparingInt(nodeEquipment::acDcConvertersConnectedTo).reversed().thenComparing(nodeEnd -> nodeEnd))
.collect(Collectors.toList());
}
private static List notVisitedNodesSortedByNotUsedAcDcConvertersConnectedTo(NodeEquipment nodeEquipment, List islandNodesEnd, Set visitedNodes, Set usedAcDcConverters) {
return islandNodesEnd.stream().filter(nodeEnd -> !visitedNodes.contains(nodeEnd) && nodeEquipment.containsAnyNotUsedAcDcConverter(nodeEnd, usedAcDcConverters))
.sorted(Comparator.comparingInt(nodeEquipment::acDcConvertersConnectedTo).reversed().thenComparing(nodeEnd -> nodeEnd))
.collect(Collectors.toList());
}
private Set add(Adjacency adjacency, NodeEquipment nodeEquipment, Set visitedNodes, String nodeEnd,
List islandNodesEnd) {
List hvdcNodes = computeHvdcNodes(adjacency, nodeEquipment, nodeEnd, islandNodesEnd);
Set transformers = computeEquipment(nodeEquipment, hvdcNodes,
NodeEquipment.EquipmentType.TRANSFORMER);
Set acDcConverters = computeEquipment(nodeEquipment, hvdcNodes,
NodeEquipment.EquipmentType.AC_DC_CONVERTER);
Set dcLineSegment = computeEquipment(nodeEquipment, hvdcNodes,
NodeEquipment.EquipmentType.DC_LINE_SEGMENT);
visitedNodes.addAll(hvdcNodes);
HvdcEnd hvdcEnd = new HvdcEnd(hvdcNodes, transformers, acDcConverters, dcLineSegment);
hvdc.add(hvdcEnd);
return acDcConverters;
}
private static List computeHvdcNodes(Adjacency adjacency, NodeEquipment nodeEquipment,
String nodeEnd, List islandNodesEnd) {
List listNodes = new ArrayList<>();
listNodes.add(nodeEnd);
int k = 0;
while (k < listNodes.size()) {
String node = listNodes.get(k);
if (adjacency.get().containsKey(node)) {
adjacency.get().get(node).forEach(adjacent -> {
if (isAdjacentOk(nodeEquipment, listNodes, islandNodesEnd,
adjacent.type, adjacent.node)) {
listNodes.add(adjacent.node);
}
});
}
k++;
}
return listNodes;
}
private static boolean isAdjacentOk(NodeEquipment nodeEquipment, List visitedNodes,
List islandNodesEnd, AdjacentType adType, String adNode) {
if (Adjacency.isDcLineSegment(adType)) {
return false;
}
if (!islandNodesEnd.contains(adNode)) {
return false;
}
if (visitedNodes.contains(adNode)) {
return false;
}
return !nodeEquipment.multiAcDcConverter(adNode);
}
private static Set computeEquipment(NodeEquipment nodeEquipment, List hvdcNode,
NodeEquipment.EquipmentType type) {
Set listEq = new HashSet<>();
hvdcNode.forEach(n -> addEquipment(nodeEquipment, n, type, listEq));
return listEq;
}
private static void addEquipment(NodeEquipment nodeEquipment, String node,
NodeEquipment.EquipmentType type, Set listEq) {
List listEqNode = nodeEquipment.getNodeEquipment().get(node);
if (listEqNode == null) {
return;
}
listEqNode.stream()
.filter(eq -> eq.type == type)
.forEachOrdered(eq -> listEq.add(eq.equipmentId));
}
List getHvdc() {
return hvdc;
}
static class HvdcEnd {
final List nodesEnd;
final Set transformersEnd;
final Set acDcConvertersEnd;
final Set dcLineSegmentsEnd;
HvdcEnd(List nodesEnd, Set transformersEnd, Set acDcConvertersEnd, Set dcLineSegmentsEnd) {
Objects.requireNonNull(nodesEnd);
Objects.requireNonNull(transformersEnd);
Objects.requireNonNull(acDcConvertersEnd);
Objects.requireNonNull(dcLineSegmentsEnd);
this.nodesEnd = nodesEnd;
this.transformersEnd = transformersEnd;
this.acDcConvertersEnd = acDcConvertersEnd;
this.dcLineSegmentsEnd = dcLineSegmentsEnd;
}
HvdcEndType computeType() {
int t = this.transformersEnd.size();
int c = this.acDcConvertersEnd.size();
int ls = this.dcLineSegmentsEnd.size();
if (t >= 0 && c == 1 && ls == 1) {
return HvdcEndType.HVDC_TN_C1_LS1;
} else if (t >= 0 && c >= 1 && ls == 2 * c) {
return HvdcEndType.HVDC_TN_CN_LS2N;
} else if (t >= 0 && c == 2 && ls == 1) {
return HvdcEndType.HVDC_TN_C2_LS1;
} else if (t >= 0 && c == ls && c > 1) {
return HvdcEndType.HVDC_TN_CN_LSN;
}
throw new PowsyblException(String.format("Unexpected HVDC configuration: Transformers %d Converters %d DcLineSegments %d", t, c, ls));
}
boolean isMatchingTo(HvdcEnd otherHvdcEnd) {
if (this.acDcConvertersEnd.size() != otherHvdcEnd.acDcConvertersEnd.size()) {
return false;
}
if (this.dcLineSegmentsEnd.size() != otherHvdcEnd.dcLineSegmentsEnd.size()) {
return false;
}
return this.dcLineSegmentsEnd.stream()
.allMatch(otherHvdcEnd.dcLineSegmentsEnd::contains);
}
boolean isAssociatedWith(HvdcEnd otherHvdcEnd) {
return this.dcLineSegmentsEnd.stream().anyMatch(otherHvdcEnd.dcLineSegmentsEnd::contains);
}
static HvdcEnd joinAll(List listHvdcEnd) {
HvdcEnd finalHvdcEnd = new HvdcEnd(new ArrayList<>(), new HashSet<>(), new HashSet<>(), new HashSet<>());
listHvdcEnd.stream().forEach(hvdcEnd -> {
finalHvdcEnd.nodesEnd.addAll(hvdcEnd.nodesEnd);
finalHvdcEnd.transformersEnd.addAll(hvdcEnd.transformersEnd);
finalHvdcEnd.acDcConvertersEnd.addAll(hvdcEnd.acDcConvertersEnd);
finalHvdcEnd.dcLineSegmentsEnd.addAll(hvdcEnd.dcLineSegmentsEnd);
});
return finalHvdcEnd;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy