Skip to content

Commit

Permalink
Fix transformer voltage control outer loop AFTER GENERATOR (#1038)
Browse files Browse the repository at this point in the history
Signed-off-by: Anne Tilloy <anne.tilloy@rte-france.com>
Co-authored-by: VIDAL Didier (Externe) <didier.vidal_externe@rte-france.com>
Co-authored-by: Geoffroy Jamgotchian <geoffroy.jamgotchian@rte-france.com>
  • Loading branch information
3 people committed May 31, 2024
1 parent 1cbd341 commit adf0a80
Show file tree
Hide file tree
Showing 11 changed files with 234 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ protected static Optional<AcOuterLoop> createMonitoringVoltageOuterLoop(OpenLoad
}

protected static Optional<AcOuterLoop> createTransformerVoltageControlOuterLoop(LoadFlowParameters parameters, OpenLoadFlowParameters.TransformerVoltageControlMode controlMode,
int incrementalTransformerVoltageControlOuterLoopMaxTapShift) {
int incrementalTransformerVoltageControlOuterLoopMaxTapShift, double generatorVoltageControlMinNominalVoltage) {
if (parameters.isTransformerVoltageControlOn()) {
AcOuterLoop outerLoop = switch (controlMode) {
case WITH_GENERATOR_VOLTAGE_CONTROL -> new SimpleTransformerVoltageControlOuterLoop();
case AFTER_GENERATOR_VOLTAGE_CONTROL -> new TransformerVoltageControlOuterLoop();
case AFTER_GENERATOR_VOLTAGE_CONTROL -> new TransformerVoltageControlOuterLoop(generatorVoltageControlMinNominalVoltage);
case INCREMENTAL_VOLTAGE_CONTROL -> new IncrementalTransformerVoltageControlOuterLoop(incrementalTransformerVoltageControlOuterLoopMaxTapShift);
};
return Optional.of(outerLoop);
Expand All @@ -71,7 +71,8 @@ protected static Optional<AcOuterLoop> createTransformerVoltageControlOuterLoop(
protected static Optional<AcOuterLoop> createTransformerVoltageControlOuterLoop(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
return createTransformerVoltageControlOuterLoop(parameters,
parametersExt.getTransformerVoltageControlMode(),
parametersExt.getIncrementalTransformerRatioTapControlOuterLoopMaxTapShift());
parametersExt.getIncrementalTransformerRatioTapControlOuterLoopMaxTapShift(),
parametersExt.getGeneratorVoltageControlMinNominalVoltage());
}

protected static Optional<AcOuterLoop> createTransformerReactivePowerControlOuterLoop(OpenLoadFlowParameters parametersExt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ private static Optional<AcOuterLoop> createOuterLoop(String name, LoadFlowParame
OpenLoadFlowParameters.ShuntVoltageControlMode.INCREMENTAL_VOLTAGE_CONTROL);
case IncrementalTransformerVoltageControlOuterLoop.NAME -> createTransformerVoltageControlOuterLoop(parameters,
OpenLoadFlowParameters.TransformerVoltageControlMode.INCREMENTAL_VOLTAGE_CONTROL,
parametersExt.getIncrementalTransformerRatioTapControlOuterLoopMaxTapShift());
parametersExt.getIncrementalTransformerRatioTapControlOuterLoopMaxTapShift(),
parametersExt.getGeneratorVoltageControlMinNominalVoltage());
case MonitoringVoltageOuterLoop.NAME -> createMonitoringVoltageOuterLoop(parametersExt);
case PhaseControlOuterLoop.NAME -> createPhaseControlOuterLoop(parameters,
OpenLoadFlowParameters.PhaseShifterControlMode.CONTINUOUS_WITH_DISCRETISATION);
Expand All @@ -56,10 +57,12 @@ private static Optional<AcOuterLoop> createOuterLoop(String name, LoadFlowParame
OpenLoadFlowParameters.ShuntVoltageControlMode.WITH_GENERATOR_VOLTAGE_CONTROL);
case SimpleTransformerVoltageControlOuterLoop.NAME -> createTransformerVoltageControlOuterLoop(parameters,
OpenLoadFlowParameters.TransformerVoltageControlMode.WITH_GENERATOR_VOLTAGE_CONTROL,
parametersExt.getIncrementalTransformerRatioTapControlOuterLoopMaxTapShift());
parametersExt.getIncrementalTransformerRatioTapControlOuterLoopMaxTapShift(),
parametersExt.getGeneratorVoltageControlMinNominalVoltage());
case TransformerVoltageControlOuterLoop.NAME -> createTransformerVoltageControlOuterLoop(parameters,
OpenLoadFlowParameters.TransformerVoltageControlMode.AFTER_GENERATOR_VOLTAGE_CONTROL,
parametersExt.getIncrementalTransformerRatioTapControlOuterLoopMaxTapShift());
parametersExt.getIncrementalTransformerRatioTapControlOuterLoopMaxTapShift(),
parametersExt.getGeneratorVoltageControlMinNominalVoltage());
case AutomationSystemOuterLoop.NAME -> createAutomationSystemOuterLoop(parametersExt);
case IncrementalTransformerReactivePowerControlOuterLoop.NAME -> createTransformerReactivePowerControlOuterLoop(parametersExt);
default -> throw new PowsyblException("Unknown outer loop '" + name + "'");
Expand Down
37 changes: 32 additions & 5 deletions src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ public enum SlackDistributionFailureBehavior {

public static final boolean WRITE_REFERENCE_TERMINALS_DEFAULT_VALUE = true;

protected static final double GENERATOR_VOLTAGE_CONTROL_MIN_NOMINAL_VOLTAGE_DEFAULT_VALUE = -1d;

public static final String SLACK_BUS_SELECTION_MODE_PARAM_NAME = "slackBusSelectionMode";

public static final String SLACK_BUSES_IDS_PARAM_NAME = "slackBusesIds";
Expand Down Expand Up @@ -248,6 +250,8 @@ public enum SlackDistributionFailureBehavior {

public static final String VOLTAGE_TARGET_PRIORITIES_PARAM_NAME = "voltageTargetPriorities";

public static final String GENERATOR_VOLTAGE_CONTROL_MIN_NOMINAL_VOLTAGE_PARAM_NAME = "generatorVoltageControlMinNominalVoltage";

private static <E extends Enum<E>> List<Object> getEnumPossibleValues(Class<E> enumClass) {
return EnumSet.allOf(enumClass).stream().map(Enum::name).collect(Collectors.toList());
}
Expand Down Expand Up @@ -317,7 +321,8 @@ private static <E extends Enum<E>> List<Object> getEnumPossibleValues(Class<E> e
new Parameter(NEWTON_KRYLOV_LINE_SEARCH_PARAM_NAME, ParameterType.BOOLEAN, "Newton Krylov line search activation", NewtonKrylovParameters.LINE_SEARCH_DEFAULT_VALUE),
new Parameter(REFERENCE_BUS_SELECTION_MODE_PARAM_NAME, ParameterType.STRING, "Reference bus selection mode", ReferenceBusSelector.DEFAULT_MODE.name(), getEnumPossibleValues(ReferenceBusSelectionMode.class)),
new Parameter(WRITE_REFERENCE_TERMINALS_PARAM_NAME, ParameterType.BOOLEAN, "Write Reference Terminals", WRITE_REFERENCE_TERMINALS_DEFAULT_VALUE),
new Parameter(VOLTAGE_TARGET_PRIORITIES_PARAM_NAME, ParameterType.STRING_LIST, "Voltage target priorities for voltage controls", LfNetworkParameters.VOLTAGE_CONTROL_PRIORITIES_DEFAULT_VALUE, getEnumPossibleValues(VoltageControl.Type.class))
new Parameter(VOLTAGE_TARGET_PRIORITIES_PARAM_NAME, ParameterType.STRING_LIST, "Voltage target priorities for voltage controls", LfNetworkParameters.VOLTAGE_CONTROL_PRIORITIES_DEFAULT_VALUE, getEnumPossibleValues(VoltageControl.Type.class)),
new Parameter(GENERATOR_VOLTAGE_CONTROL_MIN_NOMINAL_VOLTAGE_PARAM_NAME, ParameterType.DOUBLE, "Nominal voltage under which generator voltage controls are disabled during transformer voltage control outer loop of mode AFTER_GENERATOR_VOLTAGE_CONTROL, < 0 means automatic detection", OpenLoadFlowParameters.GENERATOR_VOLTAGE_CONTROL_MIN_NOMINAL_VOLTAGE_DEFAULT_VALUE)
);

public enum VoltageInitModeOverride {
Expand Down Expand Up @@ -489,6 +494,8 @@ public enum ReactiveRangeCheckMode {

private List<String> voltageTargetPriorities = LfNetworkParameters.VOLTAGE_CONTROL_PRIORITIES_DEFAULT_VALUE;

private double generatorVoltageControlMinNominalVoltage = GENERATOR_VOLTAGE_CONTROL_MIN_NOMINAL_VOLTAGE_DEFAULT_VALUE;

public static double checkParameterValue(double parameterValue, boolean condition, String parameterName) {
if (!condition) {
throw new IllegalArgumentException("Invalid value for parameter " + parameterName + ": " + parameterValue);
Expand Down Expand Up @@ -1153,6 +1160,20 @@ public OpenLoadFlowParameters setVoltageTargetPriorities(List<String> voltageTar
return this;
}

/**
* Only if transformer voltage control is active and with mode `AFTER_GENERATOR_VOLTAGE_CONTROL`. Set the nominal
* voltage under which the generator voltage control are disabled during outer loop. This parameter overrides the
* automatic nominal voltage computation if >= 0.
*/
public OpenLoadFlowParameters setGeneratorVoltageControlMinNominalVoltage(double generatorVoltageControlMinNominalVoltage) {
this.generatorVoltageControlMinNominalVoltage = generatorVoltageControlMinNominalVoltage;
return this;
}

public double getGeneratorVoltageControlMinNominalVoltage() {
return generatorVoltageControlMinNominalVoltage;
}

public static OpenLoadFlowParameters load() {
return load(PlatformConfig.defaultConfig());
}
Expand Down Expand Up @@ -1226,7 +1247,8 @@ public static OpenLoadFlowParameters load(PlatformConfig platformConfig) {
.setNewtonKrylovLineSearch(config.getBooleanProperty(NEWTON_KRYLOV_LINE_SEARCH_PARAM_NAME, NewtonKrylovParameters.LINE_SEARCH_DEFAULT_VALUE))
.setReferenceBusSelectionMode(config.getEnumProperty(REFERENCE_BUS_SELECTION_MODE_PARAM_NAME, ReferenceBusSelectionMode.class, ReferenceBusSelector.DEFAULT_MODE))
.setWriteReferenceTerminals(config.getBooleanProperty(WRITE_REFERENCE_TERMINALS_PARAM_NAME, WRITE_REFERENCE_TERMINALS_DEFAULT_VALUE))
.setVoltageTargetPriorities(config.getStringListProperty(VOLTAGE_TARGET_PRIORITIES_PARAM_NAME, LfNetworkParameters.VOLTAGE_CONTROL_PRIORITIES_DEFAULT_VALUE)));
.setVoltageTargetPriorities(config.getStringListProperty(VOLTAGE_TARGET_PRIORITIES_PARAM_NAME, LfNetworkParameters.VOLTAGE_CONTROL_PRIORITIES_DEFAULT_VALUE))
.setGeneratorVoltageControlMinNominalVoltage(config.getDoubleProperty(GENERATOR_VOLTAGE_CONTROL_MIN_NOMINAL_VOLTAGE_PARAM_NAME, GENERATOR_VOLTAGE_CONTROL_MIN_NOMINAL_VOLTAGE_DEFAULT_VALUE)));
return parameters;
}

Expand Down Expand Up @@ -1375,11 +1397,13 @@ public OpenLoadFlowParameters update(Map<String, String> properties) {
.ifPresent(prop -> this.setWriteReferenceTerminals(Boolean.parseBoolean(prop)));
Optional.ofNullable(properties.get(VOLTAGE_TARGET_PRIORITIES_PARAM_NAME))
.ifPresent(prop -> this.setVoltageTargetPriorities(parseStringListProp(prop)));
Optional.ofNullable(properties.get(GENERATOR_VOLTAGE_CONTROL_MIN_NOMINAL_VOLTAGE_PARAM_NAME))
.ifPresent(prop -> this.setGeneratorVoltageControlMinNominalVoltage(Double.parseDouble(prop)));
return this;
}

public Map<String, Object> toMap() {
Map<String, Object> map = new LinkedHashMap<>(65);
Map<String, Object> map = new LinkedHashMap<>(66);
map.put(SLACK_BUS_SELECTION_MODE_PARAM_NAME, slackBusSelectionMode);
map.put(SLACK_BUSES_IDS_PARAM_NAME, slackBusesIds);
map.put(SLACK_DISTRIBUTION_FAILURE_BEHAVIOR_PARAM_NAME, slackDistributionFailureBehavior);
Expand Down Expand Up @@ -1445,6 +1469,7 @@ public Map<String, Object> toMap() {
map.put(REFERENCE_BUS_SELECTION_MODE_PARAM_NAME, referenceBusSelectionMode);
map.put(WRITE_REFERENCE_TERMINALS_PARAM_NAME, writeReferenceTerminals);
map.put(VOLTAGE_TARGET_PRIORITIES_PARAM_NAME, voltageTargetPriorities);
map.put(GENERATOR_VOLTAGE_CONTROL_MIN_NOMINAL_VOLTAGE_PARAM_NAME, generatorVoltageControlMinNominalVoltage);
return map;
}

Expand Down Expand Up @@ -1819,7 +1844,8 @@ public static boolean equals(LoadFlowParameters parameters1, LoadFlowParameters
extension1.getMaxRatioMismatch() == extension2.getMaxRatioMismatch() &&
extension1.getMaxSusceptanceMismatch() == extension2.getMaxSusceptanceMismatch() &&
extension1.getNewtonRaphsonStoppingCriteriaType() == extension2.getNewtonRaphsonStoppingCriteriaType() &&
Objects.equals(extension1.getVoltageTargetPriorities(), extension2.getVoltageTargetPriorities());
Objects.equals(extension1.getVoltageTargetPriorities(), extension2.getVoltageTargetPriorities()) &&
extension1.getGeneratorVoltageControlMinNominalVoltage() == extension2.getGeneratorVoltageControlMinNominalVoltage();
}

public static LoadFlowParameters clone(LoadFlowParameters parameters) {
Expand Down Expand Up @@ -1909,7 +1935,8 @@ public static LoadFlowParameters clone(LoadFlowParameters parameters) {
.setMaxSusceptanceMismatch(extension.getMaxSusceptanceMismatch())
.setNewtonRaphsonStoppingCriteriaType(extension.getNewtonRaphsonStoppingCriteriaType())
.setReferenceBusSelectionMode(extension.getReferenceBusSelectionMode())
.setVoltageTargetPriorities(extension.getVoltageTargetPriorities());
.setVoltageTargetPriorities(extension.getVoltageTargetPriorities())
.setGeneratorVoltageControlMinNominalVoltage(extension.getGeneratorVoltageControlMinNominalVoltage());

if (extension2 != null) {
parameters2.addExtension(OpenLoadFlowParameters.class, extension2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.powsybl.openloadflow.lf.outerloop.OuterLoopStatus;
import com.powsybl.openloadflow.network.LfBranch;
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.network.TransformerVoltageControl;
import com.powsybl.openloadflow.network.VoltageControl;
import org.apache.commons.lang3.mutable.MutableObject;

Expand All @@ -26,6 +27,8 @@ public class TransformerVoltageControlOuterLoop extends AbstractTransformerVolta

public static final String NAME = "TransformerVoltageControl";

private final double maxControlledNominalVoltageOverride;

private static final class ContextData {

private double maxControlledNominalVoltage = Double.MIN_VALUE;
Expand All @@ -45,6 +48,37 @@ private List<LfBus> getBusesWithVoltageControlDisabled() {
}
}

public TransformerVoltageControlOuterLoop(double maxControlledNominalVoltageOverride) {
this.maxControlledNominalVoltageOverride = maxControlledNominalVoltageOverride;
}

private static boolean isTransformerVoltageControlsValidForMaxControlledNominalVoltageCalculation(TransformerVoltageControl transformerVoltageControl) {
// are removed from this automatic algorithm the transformer voltage control that are between two nominal
// voltages equivalents.
if (transformerVoltageControl != null) {
for (LfBranch branch : transformerVoltageControl.getControllerElements()) {
if (!branch.isConnectedAtBothSides()
|| branch.getBus1().getNominalV() == branch.getBus2().getNominalV()) {
return false;
}
}
return true;
}
return false;
}

private static double calculateMaxControlledNominalVoltage(AcOuterLoopContext context) {
double maxControlledNominalVoltage = Double.MIN_VALUE;
for (LfBus bus : context.getNetwork().getBuses()) {
if (!bus.isDisabled()
&& bus.isTransformerVoltageControlled()
&& isTransformerVoltageControlsValidForMaxControlledNominalVoltageCalculation(bus.getTransformerVoltageControl().orElse(null))) {
maxControlledNominalVoltage = Math.max(maxControlledNominalVoltage, bus.getNominalV());
}
}
return maxControlledNominalVoltage;
}

@Override
public void initialize(AcOuterLoopContext context) {
context.setData(new ContextData());
Expand All @@ -53,15 +87,9 @@ public void initialize(AcOuterLoopContext context) {
controllerBranch.setVoltageControlEnabled(false);
}

// All transformer voltage control are disabled for the first equation system resolution.
double[] maxControlledNominalVoltage = new double[1];
maxControlledNominalVoltage[0] = Double.MIN_VALUE;
for (LfBus bus : context.getNetwork().getBuses()) {
if (!bus.isDisabled() && bus.isTransformerVoltageControlled()) {
maxControlledNominalVoltage[0] = Math.max(maxControlledNominalVoltage[0], bus.getNominalV());
}
}
((ContextData) context.getData()).setMaxControlledNominalVoltage(maxControlledNominalVoltage[0]);
// all transformer voltage control are disabled for the first equation system resolution.
double maxControlledNominalVoltage = maxControlledNominalVoltageOverride < 0 ? calculateMaxControlledNominalVoltage(context) : maxControlledNominalVoltageOverride;
((ContextData) context.getData()).setMaxControlledNominalVoltage(maxControlledNominalVoltage);
}

@Override
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/com/powsybl/openloadflow/network/LfNetwork.java
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,8 @@ public Validity getValidity() {

/**
* Disable transformer voltage control when there is no generator controlling voltage on the connected component
* that belong to the not controlled side of the transformer.
* that belong to the not controlled side of the transformer. Note that branches in contingency are not taken into
* account.
*/
public void fixTransformerVoltageControls() {
List<LfBranch> controllerBranches = new ArrayList<>(1);
Expand Down Expand Up @@ -790,7 +791,8 @@ public void fixTransformerVoltageControls() {
continue;
}
boolean noPvBusesInComponent = componentNoPVBusesMap.computeIfAbsent(getConnectivity().getComponentNumber(notControlledSide),
k -> getConnectivity().getConnectedComponent(notControlledSide).stream().noneMatch(LfBus::isGeneratorVoltageControlled));
k -> getConnectivity().getConnectedComponent(notControlledSide).stream()
.noneMatch(bus -> bus.isGeneratorVoltageControlled() && bus.isGeneratorVoltageControlEnabled()));
if (noPvBusesInComponent) {
branch.setVoltageControlEnabled(false);
LOGGER.trace("Transformer {} voltage control has been disabled because no PV buses on not controlled side connected component",
Expand Down
Loading

0 comments on commit adf0a80

Please sign in to comment.