VoltageRegulationUtils.java
/**
* Copyright (c) 2023, 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.iidm.modification.util;
import com.powsybl.iidm.network.*;
import java.util.ArrayList;
import java.util.List;
import java.util.OptionalDouble;
import java.util.stream.Stream;
public final class VoltageRegulationUtils {
private VoltageRegulationUtils() {
}
/**
* Get the stream of all generators of the network controlling voltage at controlled bus.
*/
public static Stream<Generator> getRegulatingGenerators(Network network, Bus controlledBus) {
if (controlledBus != null) {
return network.getGeneratorStream().filter(Generator::isVoltageRegulatorOn)
.filter(g -> g.getRegulatingTerminal().getBusView().getBus() != null)
.filter(g -> controlledBus.equals(g.getRegulatingTerminal().getBusView().getBus()));
} else {
return Stream.empty();
}
}
/**
* Get the stream of all shunt compensators of the network controlling voltage at controlled bus.
*/
public static Stream<ShuntCompensator> getRegulatingShuntCompensators(Network network, Bus controlledBus) {
if (controlledBus != null) {
return network.getShuntCompensatorStream().filter(ShuntCompensator::isVoltageRegulatorOn)
.filter(sh -> sh.getRegulatingTerminal().getBusView().getBus() != null)
.filter(sh -> controlledBus.equals(sh.getRegulatingTerminal().getBusView().getBus()));
} else {
return Stream.empty();
}
}
/**
* A method to find an acceptable target voltage for a regulating element to be connected. Only generators and shunt
* compensators are yet supported. As a first version, we don't consider heterogeneous voltage controls.
*
* @param controlledBus the controlled bus of the regulating terminal of the regulating element
* @param regulatingElementId the id of the regulating element
* @return the targetV, or {@link OptionalDouble#empty()} if no acceptable targetV has been found
*/
public static OptionalDouble getTargetVForRegulatingElement(Network network, Bus controlledBus, String regulatingElementId,
IdentifiableType identifiableType) {
List<Double> targets = switch (identifiableType) {
case GENERATOR -> getRegulatingGenerators(network, controlledBus)
.filter(g -> !g.getId().equals(regulatingElementId))
.map(Generator::getTargetV).distinct().toList();
case SHUNT_COMPENSATOR -> getRegulatingShuntCompensators(network, controlledBus)
.filter(g -> !g.getId().equals(regulatingElementId))
.map(ShuntCompensator::getTargetV).distinct().toList();
default -> new ArrayList<>();
};
if (targets.isEmpty() || targets.size() > 1) {
// it means that the network cannot give valuable information about targetV, this field has to be given in
// the network modification.
return OptionalDouble.empty();
} else { // targets.size() == 1
return OptionalDouble.of(targets.get(0));
}
}
}