Skip to content

Commit

Permalink
More robust UCTE naming strategy (#3206)
Browse files Browse the repository at this point in the history
* add xiidm to ucte element's id conversion
* optimisation of checking elements
* create CounterNamingStrategy
* change nodeCounter incrementation loop
* change dangling lines code generation
* change nodeID generation
* changer danglingline getBusBreakerView()
* change OrderCode list
* update danglingline xnodeCode generation

Signed-off-by: Leclerc Clement <[email protected]>
  • Loading branch information
clementleclercRTE authored Dec 16, 2024
1 parent fe577f8 commit 9001b57
Show file tree
Hide file tree
Showing 19 changed files with 675 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* Copyright (c) 2024, 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.ucte.converter;

import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import com.powsybl.ucte.converter.util.UcteConverterConstants;
import com.powsybl.ucte.network.UcteElementId;
import com.powsybl.ucte.network.UcteNodeCode;

import java.util.HashMap;
import java.util.Map;

/**
* @author Clément LECLERC {@literal <[email protected]>}
*/
public abstract class AbstractNamingStrategy implements NamingStrategy {

protected final Map<String, UcteNodeCode> ucteNodeIds = new HashMap<>();
protected final Map<String, UcteElementId> ucteElementIds = new HashMap<>();

@Override
public void initializeNetwork(Network network) {
//Empty implementation by default
}

@Override
public UcteNodeCode getUcteNodeCode(String id) {
return ucteNodeIds.computeIfAbsent(id, k -> UcteNodeCode.parseUcteNodeCode(k)
.orElseThrow(() -> new UcteException(UcteConverterConstants.NO_UCTE_CODE_ERROR + k)));
}

@Override
public UcteNodeCode getUcteNodeCode(Bus bus) {
if (bus == null) {
throw new PowsyblException("the bus is null");
}
return getUcteNodeCode(bus.getId());
}

@Override
public UcteNodeCode getUcteNodeCode(DanglingLine danglingLine) {
if (danglingLine.getPairingKey() == null) {
return getUcteNodeCode(danglingLine.getId());
}
return getUcteNodeCode(danglingLine.getPairingKey());
}

@Override
public UcteElementId getUcteElementId(String id) {
return ucteElementIds.computeIfAbsent(id, k -> UcteElementId.parseUcteElementId(k)
.orElseThrow(() -> new UcteException(UcteConverterConstants.NO_UCTE_CODE_ERROR + k)));
}

@Override
public UcteElementId getUcteElementId(Switch sw) {
if (sw == null) {
throw new PowsyblException("the switch is null");
}
return getUcteElementId(sw.getId());
}

@Override
public UcteElementId getUcteElementId(Branch branch) {
if (branch == null) {
throw new PowsyblException("the branch is null");
}
return getUcteElementId(branch.getId());
}

@Override
public UcteElementId getUcteElementId(DanglingLine danglingLine) {
if (danglingLine == null) {
throw new PowsyblException("the danglingLine is null");
}
return getUcteElementId(danglingLine.getId());
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/**
* Copyright (c) 2024, 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.ucte.converter;

import com.google.auto.service.AutoService;
import com.powsybl.iidm.network.*;
import com.powsybl.ucte.network.UcteCountryCode;
import com.powsybl.ucte.network.UcteElementId;
import com.powsybl.ucte.network.UcteNodeCode;
import com.powsybl.ucte.network.UcteVoltageLevelCode;
import com.powsybl.ucte.network.util.UcteNetworkUtil;

import java.util.*;

/**
* @author Clément LECLERC {@literal <[email protected]>}
*/
@AutoService(NamingStrategy.class)
public class CounterNamingStrategy extends AbstractNamingStrategy {

private int voltageLevelCounter;

@Override
public String getName() {
return "Counter";
}

@Override
public void initializeNetwork(Network network) {
voltageLevelCounter = 0;
network.getVoltageLevelStream()
.forEach(this::processVoltageLevel);

network.getBranchStream().forEach(this::generateUcteElementId);
network.getDanglingLineStream().forEach(this::generateUcteElementId);
}

private void processVoltageLevel(VoltageLevel voltageLevel) {
Iterator<Bus> buslist = voltageLevel.getBusBreakerView().getBuses().iterator();
for (int i = 0; buslist.hasNext(); i++) {
Bus bus = buslist.next();
char orderCode = UcteNetworkUtil.getOrderCode(i);
generateUcteNodeId(bus.getId(), voltageLevel, orderCode);
}

voltageLevel.getBusBreakerView().getSwitches()
.forEach(this::generateUcteElementId);
voltageLevelCounter++;
}

private UcteNodeCode generateUcteNodeId(String busId, VoltageLevel voltageLevel, char orderCode) {
if (UcteNodeCode.isUcteNodeId(busId)) {
return changeOrderCode(busId, orderCode);
}
return createNewUcteNodeId(busId, voltageLevel, orderCode);
}

private UcteNodeCode changeOrderCode(String busId, char orderCode) {
UcteNodeCode newNodeCode = UcteNodeCode.parseUcteNodeCode(busId).orElseThrow();
newNodeCode.setBusbar(orderCode);
ucteNodeIds.put(busId, newNodeCode);
return newNodeCode;
}

private UcteNodeCode createNewUcteNodeId(String busId, VoltageLevel voltageLevel, char orderCode) {
String newNodeId = String.format("%05d", voltageLevelCounter);
char countryCode = UcteCountryCode.fromVoltagelevel(voltageLevel).getUcteCode();
char voltageLevelCode = UcteVoltageLevelCode.voltageLevelCodeFromVoltage(voltageLevel.getNominalV());

UcteNodeCode ucteNodeCode = new UcteNodeCode(
UcteCountryCode.fromUcteCode(countryCode),
newNodeId,
UcteVoltageLevelCode.voltageLevelCodeFromChar(voltageLevelCode),
orderCode);

ucteNodeIds.put(busId, ucteNodeCode);
return ucteNodeCode;
}

private UcteElementId generateUcteElementId(String id, UcteNodeCode node1, UcteNodeCode node2) {
if (ucteElementIds.containsKey(id)) {
return ucteElementIds.get(id);
}

UcteElementId uniqueElementId = UcteNetworkUtil.ORDER_CODES.stream()
.map(orderCode -> new UcteElementId(node1, node2, orderCode))
.filter(elementId -> !ucteElementIds.containsValue(elementId))
.findFirst()
.orElseThrow(() -> new UcteException("Unable to generate unique element ID"));

ucteElementIds.put(id, uniqueElementId);
return uniqueElementId;
}

private UcteElementId generateUcteElementId(Branch<?> branch) {
if (ucteElementIds.containsKey(branch.getId())) {
return ucteElementIds.get(branch.getId());
}
UcteNodeCode node1 = ucteNodeIds.get(branch.getTerminal1().getBusBreakerView().getBus().getId());
UcteNodeCode node2 = ucteNodeIds.get(branch.getTerminal2().getBusBreakerView().getBus().getId());

return generateUcteElementId(branch.getId(), node1, node2);
}

private UcteElementId generateUcteElementId(DanglingLine danglingLine) {
if (ucteElementIds.containsKey(danglingLine.getId())) {
return ucteElementIds.get(danglingLine.getId());
}

UcteNodeCode code1;
UcteNodeCode code2;

code1 = getUcteNodeCode(danglingLine.getTerminal().getBusBreakerView().getBus());

if (danglingLine.getPairingKey() != null && UcteNodeCode.isUcteNodeId(danglingLine.getPairingKey())) {
code2 = UcteNodeCode.parseUcteNodeCode(danglingLine.getPairingKey()).orElseThrow();
ucteNodeIds.put(danglingLine.getPairingKey(), code2);
} else {
code2 = generateUcteNodeId(danglingLine.getId(), danglingLine.getTerminal().getVoltageLevel(), UcteNetworkUtil.getOrderCode(0));
}
return generateUcteElementId(danglingLine.getId(), code1, code2);
}

private UcteElementId generateUcteElementId(Switch sw) {
if (ucteElementIds.containsKey(sw.getId())) {
return ucteElementIds.get(sw.getId());
}

VoltageLevel.BusBreakerView view = sw.getVoltageLevel().getBusBreakerView();
Bus bus1 = view.getBus1(sw.getId());
Bus bus2 = view.getBus2(sw.getId());

UcteNodeCode u1 = getUcteNodeCode(bus1.getId());
UcteNodeCode u2 = getUcteNodeCode(bus2.getId());

return generateUcteElementId(sw.getId(), u1, u2);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,63 +9,18 @@
package com.powsybl.ucte.converter;

import com.google.auto.service.AutoService;
import com.powsybl.iidm.network.*;
import com.powsybl.ucte.network.UcteElementId;
import com.powsybl.ucte.network.UcteNodeCode;

import java.util.HashMap;
import java.util.Map;

/**
* A {@link NamingStrategy} implementation that ensures the conformity of IDs with the UCTE-DEF format
*
* @author Mathieu Bague {@literal <[email protected]>}
*/
@AutoService(NamingStrategy.class)
public class DefaultNamingStrategy implements NamingStrategy {

private final Map<String, UcteNodeCode> ucteNodeIds = new HashMap<>();

private final Map<String, UcteElementId> ucteElementIds = new HashMap<>();
public class DefaultNamingStrategy extends AbstractNamingStrategy {

@Override
public String getName() {
return "Default";
}

@Override
public UcteNodeCode getUcteNodeCode(String id) {
return ucteNodeIds.computeIfAbsent(id, k -> UcteNodeCode.parseUcteNodeCode(k).orElseThrow(() -> new UcteException("Invalid UCTE node identifier: " + k)));
}

@Override
public UcteNodeCode getUcteNodeCode(Bus bus) {
return getUcteNodeCode(bus.getId());
}

@Override
public UcteNodeCode getUcteNodeCode(DanglingLine danglingLine) {
return getUcteNodeCode(danglingLine.getPairingKey());
}

@Override
public UcteElementId getUcteElementId(String id) {
return ucteElementIds.computeIfAbsent(id, k -> UcteElementId.parseUcteElementId(k).orElseThrow(() -> new UcteException("Invalid UCTE node identifier: " + k)));
}

@Override
public UcteElementId getUcteElementId(Switch sw) {
return getUcteElementId(sw.getId());
}

@Override
public UcteElementId getUcteElementId(Branch branch) {
return getUcteElementId(branch.getId());
}

@Override
public UcteElementId getUcteElementId(DanglingLine danglingLine) {
return getUcteElementId(danglingLine.getId());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
*/
public interface NamingStrategy {

void initializeNetwork(Network network);

String getName();

UcteNodeCode getUcteNodeCode(String id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import java.util.*;
import java.util.function.Supplier;

import static com.powsybl.ucte.converter.util.UcteConstants.*;
import static com.powsybl.ucte.converter.util.UcteConverterConstants.*;
import static com.powsybl.ucte.converter.util.UcteConverterHelper.*;

/**
Expand Down Expand Up @@ -87,6 +87,7 @@ public void export(Network network, Properties parameters, DataSource dataSource

String namingStrategyName = Parameter.readString(getFormat(), parameters, NAMING_STRATEGY_PARAMETER, defaultValueConfig);
NamingStrategy namingStrategy = findNamingStrategy(namingStrategyName, NAMING_STRATEGY_SUPPLIERS.get());
namingStrategy.initializeNetwork(network);
boolean combinePhaseAngleRegulation = Parameter.readBoolean(getFormat(), parameters, COMBINE_PHASE_ANGLE_REGULATION_PARAMETER, defaultValueConfig);

UcteNetwork ucteNetwork = createUcteNetwork(network, namingStrategy, combinePhaseAngleRegulation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.powsybl.ucte.converter.util.UcteConstants.*;
import static com.powsybl.ucte.converter.util.UcteConverterConstants.*;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
/**
* @author Sebastien Murgey {@literal <sebastien.murgey at rte-france.com>}
*/
public final class UcteConstants {
public final class UcteConverterConstants {

private UcteConstants() {
private UcteConverterConstants() {
throw new IllegalStateException("Should not be constructed");
}

Expand All @@ -26,4 +26,5 @@ private UcteConstants() {
public static final String ORDER_CODE = "orderCode";
public static final String POWER_PLANT_TYPE_PROPERTY_KEY = "powerPlantType";
public static final int DEFAULT_POWER_LIMIT = 9999;
public static final String NO_UCTE_CODE_ERROR = "No UCTE code found for id: ";
}
Loading

0 comments on commit 9001b57

Please sign in to comment.