ExplicitAcOuterLoopConfig.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.openloadflow.lf.outerloop.config;
import com.powsybl.commons.PowsyblException;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.LoadFlowParametersOverride;
import com.powsybl.openloadflow.ac.outerloop.*;
import com.powsybl.openloadflow.lf.outerloop.AbstractAreaInterchangeControlOuterLoop;
import com.powsybl.openloadflow.lf.outerloop.AbstractIncrementalPhaseControlOuterLoop;
import com.powsybl.openloadflow.lf.outerloop.OuterLoop;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public class ExplicitAcOuterLoopConfig extends AbstractAcOuterLoopConfig {
public static final List<String> NAMES = List.of(AbstractIncrementalPhaseControlOuterLoop.NAME,
DistributedSlackOuterLoop.NAME,
IncrementalShuntVoltageControlOuterLoop.NAME,
IncrementalTransformerVoltageControlOuterLoop.NAME,
MonitoringVoltageOuterLoop.NAME,
PhaseControlOuterLoop.NAME,
ReactiveLimitsOuterLoop.NAME,
SecondaryVoltageControlOuterLoop.NAME,
ShuntVoltageControlOuterLoop.NAME,
SimpleTransformerVoltageControlOuterLoop.NAME,
TransformerVoltageControlOuterLoop.NAME,
AutomationSystemOuterLoop.NAME,
IncrementalTransformerReactivePowerControlOuterLoop.NAME,
AbstractAreaInterchangeControlOuterLoop.NAME);
private static Optional<AcOuterLoop> createOuterLoop(String name, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt, LoadFlowParametersOverride loadFlowParametersOverride) {
return switch (name) {
case AbstractIncrementalPhaseControlOuterLoop.NAME -> createPhaseControlOuterLoop(parameters,
OpenLoadFlowParameters.PhaseShifterControlMode.INCREMENTAL);
case DistributedSlackOuterLoop.NAME -> createDistributedSlackOuterLoop(parameters, parametersExt, loadFlowParametersOverride);
case IncrementalShuntVoltageControlOuterLoop.NAME -> createShuntVoltageControlOuterLoop(parameters,
OpenLoadFlowParameters.ShuntVoltageControlMode.INCREMENTAL_VOLTAGE_CONTROL);
case IncrementalTransformerVoltageControlOuterLoop.NAME -> createTransformerVoltageControlOuterLoop(parameters,
parametersExt.isTransformerVoltageControlUseInitialTapPosition(),
OpenLoadFlowParameters.TransformerVoltageControlMode.INCREMENTAL_VOLTAGE_CONTROL,
parametersExt.getIncrementalTransformerRatioTapControlOuterLoopMaxTapShift(),
parametersExt.getGeneratorVoltageControlMinNominalVoltage());
case MonitoringVoltageOuterLoop.NAME -> createMonitoringVoltageOuterLoop(parametersExt);
case PhaseControlOuterLoop.NAME -> createPhaseControlOuterLoop(parameters,
OpenLoadFlowParameters.PhaseShifterControlMode.CONTINUOUS_WITH_DISCRETISATION);
case ReactiveLimitsOuterLoop.NAME -> createReactiveLimitsOuterLoop(parameters, parametersExt);
case SecondaryVoltageControlOuterLoop.NAME -> createSecondaryVoltageControlOuterLoop(parametersExt);
case ShuntVoltageControlOuterLoop.NAME -> createShuntVoltageControlOuterLoop(parameters,
OpenLoadFlowParameters.ShuntVoltageControlMode.WITH_GENERATOR_VOLTAGE_CONTROL);
case SimpleTransformerVoltageControlOuterLoop.NAME -> createTransformerVoltageControlOuterLoop(parameters,
parametersExt.isTransformerVoltageControlUseInitialTapPosition(),
OpenLoadFlowParameters.TransformerVoltageControlMode.WITH_GENERATOR_VOLTAGE_CONTROL,
parametersExt.getIncrementalTransformerRatioTapControlOuterLoopMaxTapShift(),
parametersExt.getGeneratorVoltageControlMinNominalVoltage());
case TransformerVoltageControlOuterLoop.NAME -> createTransformerVoltageControlOuterLoop(parameters,
parametersExt.isTransformerVoltageControlUseInitialTapPosition(),
OpenLoadFlowParameters.TransformerVoltageControlMode.AFTER_GENERATOR_VOLTAGE_CONTROL,
parametersExt.getIncrementalTransformerRatioTapControlOuterLoopMaxTapShift(),
parametersExt.getGeneratorVoltageControlMinNominalVoltage());
case AutomationSystemOuterLoop.NAME -> createAutomationSystemOuterLoop(parametersExt);
case IncrementalTransformerReactivePowerControlOuterLoop.NAME -> createTransformerReactivePowerControlOuterLoop(parametersExt);
case AbstractAreaInterchangeControlOuterLoop.NAME -> createAreaInterchangeControlOuterLoop(parameters, parametersExt, loadFlowParametersOverride);
default -> throw new PowsyblException("Unknown outer loop '" + name + "' for AC load flow");
};
}
private static void checkTypeUnicity(List<AcOuterLoop> outerLoops) {
Map<String, Integer> outerLoopTypesCount = outerLoops.stream().collect(Collectors.toMap(OuterLoop::getType, outerLoop -> 1, Integer::sum));
for (var e : outerLoopTypesCount.entrySet()) {
int count = e.getValue();
if (count > 1) {
String type = e.getKey();
throw new PowsyblException("Multiple (" + count + ") outer loops with same type: " + type);
}
}
}
@Override
public List<AcOuterLoop> configure(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
return configure(parameters, parametersExt, LoadFlowParametersOverride.NO_OVERRIDE);
}
@Override
public List<AcOuterLoop> configure(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt, LoadFlowParametersOverride loadFlowParametersOverride) {
List<AcOuterLoop> outerLoops = Objects.requireNonNull(loadFlowParametersOverride.getOuterLoopNames(parametersExt)).stream()
.flatMap(name -> createOuterLoop(name, parameters, parametersExt, loadFlowParametersOverride).stream())
.toList();
checkTypeUnicity(outerLoops);
return filterInconsistentOuterLoops(outerLoops);
}
}