AmplUtil.java
/**
* Copyright (c) 2016, All partners of the iTesla project (http://www.itesla-project.eu/consortium)
* Copyright (c) 2017, 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.ampl.converter;
import com.powsybl.commons.util.StringToIntMapper;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.HvdcConverterStation.HvdcType;
import java.util.Objects;
/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public final class AmplUtil {
private AmplUtil() {
}
public static Iterable<Bus> getBuses(Network n) {
return n.getBusView().getBuses();
}
public static String getBusId(Bus bus) {
return bus == null ? null : bus.getId();
}
public static Bus getBus(Terminal t) {
return t.getBusView().getBus();
}
public static int getBusNum(StringToIntMapper<AmplSubset> mapper, Terminal t) {
Bus bus = getBus(t);
return bus == null ? -1 : mapper.getInt(AmplSubset.BUS, bus.getId());
}
public static Bus getConnectableBus(Terminal t) {
return t.getBusView().getConnectableBus();
}
public static int getConnectableBusNum(StringToIntMapper<AmplSubset> mapper, Terminal t) {
Bus bus = getConnectableBus(t);
return bus == null ? -1 : mapper.getInt(AmplSubset.BUS, bus.getId());
}
private static void createLimitsIds(StringToIntMapper<AmplSubset> mapper, CurrentLimits limits, String branchId, String sideId) {
for (LoadingLimits.TemporaryLimit tl : limits.getTemporaryLimits()) {
String limitId = branchId + "_" + sideId + "_" + tl.getAcceptableDuration();
mapper.newInt(AmplSubset.TEMPORARY_CURRENT_LIMIT, limitId);
}
}
public static StringToIntMapper<AmplSubset> createMapper(Network network) {
StringToIntMapper<AmplSubset> mapper = new StringToIntMapper<>(AmplSubset.class);
fillMapper(mapper, network);
return mapper;
}
public static String getXnodeBusId(TieLine tieLine) {
return tieLine.getPairingKey();
}
public static String getXnodeVoltageLevelId(TieLine tieLine) {
return tieLine.getPairingKey();
}
public static String getThreeWindingsTransformerMiddleBusId(ThreeWindingsTransformer twt) {
return twt.getId(); // same id as the transformer
}
public static String getThreeWindingsTransformerMiddleVoltageLevelId(ThreeWindingsTransformer twt) {
return twt.getId(); // same id as the transformer
}
public static String getDanglingLineMiddleBusId(DanglingLine dl) {
return dl.getId(); // same id as the dangling line
}
public static String getDanglingLineMiddleVoltageLevelId(DanglingLine dl) {
return dl.getId(); // same id as the dangling line
}
public static void fillMapper(StringToIntMapper<AmplSubset> mapper, Network network) {
// Network
mapper.newInt(AmplSubset.NETWORK, network.getId());
// Voltage levels
network.getVoltageLevelStream().forEach(vl -> mapper.newInt(AmplSubset.VOLTAGE_LEVEL, vl.getId()));
// Buses
getBuses(network).forEach(b -> mapper.newInt(AmplSubset.BUS, b.getId()));
// Lines
fillLines(mapper, network);
// Tie lines
fillTieLines(mapper, network);
// Two windings transformers
fillTwoWindingsTransformers(mapper, network);
// Three windings transformers
fillThreeWindingsTransformers(mapper, network);
// Dangling lines
fillDanglingLines(mapper, network);
// loads
network.getLoadStream().forEach(l -> mapper.newInt(AmplSubset.LOAD, l.getId()));
// shunts
network.getShuntCompensatorStream().forEach(sc -> mapper.newInt(AmplSubset.SHUNT, sc.getId()));
// generators
network.getGeneratorStream().forEach(g -> mapper.newInt(AmplSubset.GENERATOR, g.getId()));
// batteries
network.getBatteryStream().forEach(g -> mapper.newInt(AmplSubset.BATTERY, g.getId()));
// static var compensators
network.getStaticVarCompensatorStream().forEach(svc -> mapper.newInt(AmplSubset.STATIC_VAR_COMPENSATOR, svc.getId()));
// HVDC lines
network.getHvdcLineStream().forEach(hvdc -> mapper.newInt(AmplSubset.HVDC_LINE, hvdc.getId()));
// HvdcConverterStations
network.getHvdcConverterStations().forEach(conv ->
mapper.newInt(conv.getHvdcType().equals(HvdcType.VSC) ? AmplSubset.VSC_CONVERTER_STATION : AmplSubset.LCC_CONVERTER_STATION, conv.getId()));
}
private static void fillLines(StringToIntMapper<AmplSubset> mapper, Network network) {
for (Line l : network.getLines()) {
mapper.newInt(AmplSubset.BRANCH, l.getId());
// limits
l.getCurrentLimits1().ifPresent(currentLimits -> createLimitsIds(mapper, currentLimits, l.getId(), "_1_"));
l.getCurrentLimits2().ifPresent(currentLimits -> createLimitsIds(mapper, currentLimits, l.getId(), "_2_"));
}
}
public static void fillTieLines(StringToIntMapper<AmplSubset> mapper, Network network) {
for (TieLine tl : network.getTieLines()) {
mapper.newInt(AmplSubset.BRANCH, tl.getId());
mapper.newInt(AmplSubset.VOLTAGE_LEVEL, AmplUtil.getXnodeVoltageLevelId(tl));
mapper.newInt(AmplSubset.BUS, AmplUtil.getXnodeBusId(tl));
DanglingLine dl1 = tl.getDanglingLine1();
DanglingLine dl2 = tl.getDanglingLine2();
mapper.newInt(AmplSubset.BRANCH, dl1.getId());
mapper.newInt(AmplSubset.BRANCH, dl2.getId());
// limits
dl1.getCurrentLimits().ifPresent(currentLimits -> createLimitsIds(mapper, currentLimits, tl.getId(), "_1_"));
dl2.getCurrentLimits().ifPresent(currentLimits -> createLimitsIds(mapper, currentLimits, tl.getId(), "_2_"));
}
}
private static void fillTwoWindingsTransformers(StringToIntMapper<AmplSubset> mapper, Network network) {
for (TwoWindingsTransformer twt : network.getTwoWindingsTransformers()) {
mapper.newInt(AmplSubset.BRANCH, twt.getId());
if (twt.hasRatioTapChanger()) {
mapper.newInt(AmplSubset.TAP_CHANGER_TABLE, twt.getId() + "_ratio_table");
mapper.newInt(AmplSubset.RATIO_TAP_CHANGER, twt.getId());
}
if (twt.hasPhaseTapChanger()) {
mapper.newInt(AmplSubset.TAP_CHANGER_TABLE, twt.getId() + "_phase_table");
mapper.newInt(AmplSubset.PHASE_TAP_CHANGER, twt.getId());
}
// limits
twt.getCurrentLimits1().ifPresent(currentLimits -> createLimitsIds(mapper, currentLimits, twt.getId(), "_1_"));
twt.getCurrentLimits2().ifPresent(currentLimits -> createLimitsIds(mapper, currentLimits, twt.getId(), "_2_"));
}
}
private static void fillThreeWindingsTransformers(StringToIntMapper<AmplSubset> mapper, Network network) {
for (ThreeWindingsTransformer twt : network.getThreeWindingsTransformers()) {
mapper.newInt(AmplSubset.VOLTAGE_LEVEL, twt.getId());
mapper.newInt(AmplSubset.BUS, twt.getId());
mapper.newInt(AmplSubset.THREE_WINDINGS_TRANSFO, twt.getId());
mapper.newInt(AmplSubset.BRANCH, twt.getId() + AmplConstants.LEG1_SUFFIX);
mapper.newInt(AmplSubset.BRANCH, twt.getId() + AmplConstants.LEG2_SUFFIX);
mapper.newInt(AmplSubset.BRANCH, twt.getId() + AmplConstants.LEG3_SUFFIX);
if (twt.getLeg1().hasRatioTapChanger()) {
mapper.newInt(AmplSubset.TAP_CHANGER_TABLE, twt.getId() + "_leg1_ratio_table");
mapper.newInt(AmplSubset.RATIO_TAP_CHANGER, twt.getId() + AmplConstants.LEG1_SUFFIX);
}
if (twt.getLeg2().hasRatioTapChanger()) {
mapper.newInt(AmplSubset.TAP_CHANGER_TABLE, twt.getId() + "_leg2_ratio_table");
mapper.newInt(AmplSubset.RATIO_TAP_CHANGER, twt.getId() + AmplConstants.LEG2_SUFFIX);
}
if (twt.getLeg3().hasRatioTapChanger()) {
mapper.newInt(AmplSubset.TAP_CHANGER_TABLE, twt.getId() + "_leg3_ratio_table");
mapper.newInt(AmplSubset.RATIO_TAP_CHANGER, twt.getId() + AmplConstants.LEG3_SUFFIX);
}
if (twt.getLeg1().hasPhaseTapChanger()) {
mapper.newInt(AmplSubset.TAP_CHANGER_TABLE, twt.getId() + "_leg1_phase_table");
mapper.newInt(AmplSubset.PHASE_TAP_CHANGER, twt.getId() + AmplConstants.LEG1_SUFFIX);
}
if (twt.getLeg2().hasPhaseTapChanger()) {
mapper.newInt(AmplSubset.TAP_CHANGER_TABLE, twt.getId() + "_leg2_phase_table");
mapper.newInt(AmplSubset.PHASE_TAP_CHANGER, twt.getId() + AmplConstants.LEG2_SUFFIX);
}
if (twt.getLeg3().hasPhaseTapChanger()) {
mapper.newInt(AmplSubset.TAP_CHANGER_TABLE, twt.getId() + "_leg3_phase_table");
mapper.newInt(AmplSubset.PHASE_TAP_CHANGER, twt.getId() + AmplConstants.LEG3_SUFFIX);
}
// limits
twt.getLeg1().getCurrentLimits().ifPresent(l -> createLimitsIds(mapper, l, twt.getId() + AmplConstants.LEG1_SUFFIX, ""));
twt.getLeg2().getCurrentLimits().ifPresent(l -> createLimitsIds(mapper, l, twt.getId() + AmplConstants.LEG2_SUFFIX, ""));
twt.getLeg3().getCurrentLimits().ifPresent(l -> createLimitsIds(mapper, l, twt.getId() + AmplConstants.LEG3_SUFFIX, ""));
}
}
private static void fillDanglingLines(StringToIntMapper<AmplSubset> mapper, Network network) {
for (DanglingLine dl : network.getDanglingLines(DanglingLineFilter.UNPAIRED)) {
mapper.newInt(AmplSubset.VOLTAGE_LEVEL, dl.getId());
mapper.newInt(AmplSubset.BUS, dl.getId());
mapper.newInt(AmplSubset.BRANCH, dl.getId());
mapper.newInt(AmplSubset.LOAD, dl.getId());
// limits
dl.getCurrentLimits().ifPresent(l -> createLimitsIds(mapper, l, dl.getId(), ""));
}
}
public static void resetNetworkMapping(StringToIntMapper<AmplSubset> mapper) {
mapper.reset(AmplSubset.NETWORK);
mapper.reset(AmplSubset.BUS);
mapper.reset(AmplSubset.VOLTAGE_LEVEL);
mapper.reset(AmplSubset.BRANCH);
mapper.reset(AmplSubset.RATIO_TAP_CHANGER);
mapper.reset(AmplSubset.PHASE_TAP_CHANGER);
mapper.reset(AmplSubset.TAP_CHANGER_TABLE);
mapper.reset(AmplSubset.LOAD);
mapper.reset(AmplSubset.SHUNT);
mapper.reset(AmplSubset.GENERATOR);
mapper.reset(AmplSubset.BATTERY);
mapper.reset(AmplSubset.TEMPORARY_CURRENT_LIMIT);
mapper.reset(AmplSubset.THREE_WINDINGS_TRANSFO);
mapper.reset(AmplSubset.STATIC_VAR_COMPENSATOR);
mapper.reset(AmplSubset.HVDC_LINE);
}
public static String getLegSuffix(ThreeSides leg) {
Objects.requireNonNull(leg);
return switch (leg) {
case ONE -> AmplConstants.LEG1_SUFFIX;
case TWO -> AmplConstants.LEG2_SUFFIX;
case THREE -> AmplConstants.LEG3_SUFFIX;
};
}
}