Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Automatic fix of incompatible target voltages #1115

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.powsybl.openloadflow.dc.equations.DcApproximationType;
import com.powsybl.openloadflow.dc.equations.DcEquationSystemCreationParameters;
import com.powsybl.openloadflow.graph.GraphConnectivityFactory;
import com.powsybl.openloadflow.graph.NaiveGraphConnectivityFactory;
import com.powsybl.openloadflow.lf.AbstractLoadFlowParameters;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.network.util.PreviousValueVoltageInitializer;
Expand Down Expand Up @@ -276,6 +277,8 @@ public enum FictitiousGeneratorVoltageControlCheckMode {

public static final String AREA_INTERCHANGE_P_MAX_MISMATCH_PARAM_NAME = "areaInterchangePMaxMismatch";

public static final String FIX_REMOTE_VOLTAGE_TARGET_PARAM_NAME = "fixRemoteTargetVoltage";

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be documented.
And maybe addiotional parameters given like TARGET_VOLTAGE_PLAUSIBILITY_THRESHOLD

However in my test networks, increasing CONTROLLED_BUS_NEIGHBORS_EXPLORATION_DEPTH had a terrible algotirhmic cost and didn't improve quality (defined as more convergence)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"And maybe addiotional parameters given like TARGET_VOLTAGE_PLAUSIBILITY_THRESHOLD" => yes
for CONTROLLED_BUS_NEIGHBORS_EXPLORATION_DEPTH indeed it should not be configurable, a value of 2 or 3 is probably enough.

public 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 @@ -413,7 +416,8 @@ public static <E extends Enum<E>> List<Object> getEnumPossibleValues(Class<E> en
new Parameter(FICTITIOUS_GENERATOR_VOLTAGE_CONTROL_CHECK_MODE, ParameterType.STRING, "Specifies fictitious generators active power checks exemption for voltage control", OpenLoadFlowParameters.FICTITIOUS_GENERATOR_VOLTAGE_CONTROL_CHECK_MODE_DEFAULT_VALUE.name(), getEnumPossibleValues(FictitiousGeneratorVoltageControlCheckMode.class), ParameterScope.FUNCTIONAL, GENERATOR_VOLTAGE_CONTROL_CATEGORY_KEY),
new Parameter(AREA_INTERCHANGE_CONTROL_PARAM_NAME, ParameterType.BOOLEAN, "Area interchange control", AREA_INTERCHANGE_CONTROL_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, SLACK_DISTRIBUTION_CATEGORY_KEY),
new Parameter(AREA_INTERCHANGE_CONTROL_AREA_TYPE_PARAM_NAME, ParameterType.STRING, "Area type for area interchange control", LfNetworkParameters.AREA_INTERCHANGE_CONTROL_AREA_TYPE_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, SLACK_DISTRIBUTION_CATEGORY_KEY),
new Parameter(AREA_INTERCHANGE_P_MAX_MISMATCH_PARAM_NAME, ParameterType.DOUBLE, "Area interchange max active power mismatch", AREA_INTERCHANGE_P_MAX_MISMATCH_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, SLACK_DISTRIBUTION_CATEGORY_KEY)
new Parameter(AREA_INTERCHANGE_P_MAX_MISMATCH_PARAM_NAME, ParameterType.DOUBLE, "Area interchange max active power mismatch", AREA_INTERCHANGE_P_MAX_MISMATCH_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, SLACK_DISTRIBUTION_CATEGORY_KEY),
new Parameter(FIX_REMOTE_VOLTAGE_TARGET_PARAM_NAME, ParameterType.BOOLEAN, "Automatically fix problematic remote voltage targets", AcLoadFlowParameters.FIX_REMOTE_VOLTAGE_TARGET_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, VOLTAGE_CONTROLS_CATEGORY_KEY)
);

public enum VoltageInitModeOverride {
Expand Down Expand Up @@ -597,6 +601,8 @@ public enum ReactiveRangeCheckMode {

private double areaInterchangePMaxMismatch = AREA_INTERCHANGE_P_MAX_MISMATCH_DEFAULT_VALUE;

private boolean fixRemoteVoltageTarget = AcLoadFlowParameters.FIX_REMOTE_VOLTAGE_TARGET_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 @@ -1322,6 +1328,15 @@ public OpenLoadFlowParameters setAreaInterchangePMaxMismatch(double areaIntercha
return this;
}

public boolean isFixRemoteVoltageTarget() {
return fixRemoteVoltageTarget;
}

public OpenLoadFlowParameters setFixRemoteVoltageTarget(boolean fixRemoteVoltageTarget) {
this.fixRemoteVoltageTarget = fixRemoteVoltageTarget;
return this;
}

public static OpenLoadFlowParameters load() {
return load(PlatformConfig.defaultConfig());
}
Expand Down Expand Up @@ -1400,7 +1415,8 @@ public static OpenLoadFlowParameters load(PlatformConfig platformConfig) {
.setGeneratorVoltageControlMinNominalVoltage(config.getDoubleProperty(GENERATOR_VOLTAGE_CONTROL_MIN_NOMINAL_VOLTAGE_PARAM_NAME, GENERATOR_VOLTAGE_CONTROL_MIN_NOMINAL_VOLTAGE_DEFAULT_VALUE))
.setAreaInterchangeControl(config.getBooleanProperty(AREA_INTERCHANGE_CONTROL_PARAM_NAME, AREA_INTERCHANGE_CONTROL_DEFAULT_VALUE))
.setAreaInterchangeControlAreaType(config.getStringProperty(AREA_INTERCHANGE_CONTROL_AREA_TYPE_PARAM_NAME, LfNetworkParameters.AREA_INTERCHANGE_CONTROL_AREA_TYPE_DEFAULT_VALUE))
.setAreaInterchangePMaxMismatch(config.getDoubleProperty(AREA_INTERCHANGE_P_MAX_MISMATCH_PARAM_NAME, AREA_INTERCHANGE_P_MAX_MISMATCH_DEFAULT_VALUE)));
.setAreaInterchangePMaxMismatch(config.getDoubleProperty(AREA_INTERCHANGE_P_MAX_MISMATCH_PARAM_NAME, AREA_INTERCHANGE_P_MAX_MISMATCH_DEFAULT_VALUE))
.setFixRemoteVoltageTarget(config.getBooleanProperty(FIX_REMOTE_VOLTAGE_TARGET_PARAM_NAME, AcLoadFlowParameters.FIX_REMOTE_VOLTAGE_TARGET_DEFAULT_VALUE)));
return parameters;
}

Expand Down Expand Up @@ -1561,11 +1577,13 @@ public OpenLoadFlowParameters update(Map<String, String> properties) {
.ifPresent(this::setAreaInterchangeControlAreaType);
Optional.ofNullable(properties.get(AREA_INTERCHANGE_P_MAX_MISMATCH_PARAM_NAME))
.ifPresent(prop -> this.setAreaInterchangePMaxMismatch(Double.parseDouble(prop)));
Optional.ofNullable(properties.get(FIX_REMOTE_VOLTAGE_TARGET_PARAM_NAME))
.ifPresent(prop -> this.setFixRemoteVoltageTarget(Boolean.parseBoolean(prop)));
return this;
}

public Map<String, Object> toMap() {
Map<String, Object> map = new LinkedHashMap<>(71);
Map<String, Object> map = new LinkedHashMap<>(72);
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 @@ -1637,6 +1655,7 @@ public Map<String, Object> toMap() {
map.put(AREA_INTERCHANGE_CONTROL_PARAM_NAME, areaInterchangeControl);
map.put(AREA_INTERCHANGE_CONTROL_AREA_TYPE_PARAM_NAME, areaInterchangeControlAreaType);
map.put(AREA_INTERCHANGE_P_MAX_MISMATCH_PARAM_NAME, areaInterchangePMaxMismatch);
map.put(FIX_REMOTE_VOLTAGE_TARGET_PARAM_NAME, fixRemoteVoltageTarget);
return map;
}

Expand Down Expand Up @@ -1751,7 +1770,8 @@ static VoltageInitializer getExtendedVoltageInitializer(LoadFlowParameters param
}

static LfNetworkParameters getNetworkParameters(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
SlackBusSelector slackBusSelector, GraphConnectivityFactory<LfBus, LfBranch> connectivityFactory,
SlackBusSelector slackBusSelector, MatrixFactory matrixFactory,
GraphConnectivityFactory<LfBus, LfBranch> connectivityFactory,
boolean breakers) {
return new LfNetworkParameters()
.setSlackBusSelector(slackBusSelector)
Expand Down Expand Up @@ -1837,7 +1857,7 @@ public static AcLoadFlowParameters createAcParameters(LoadFlowParameters paramet
SlackBusSelector slackBusSelector = SlackBusSelector.fromMode(parametersExt.getSlackBusSelectionMode(), parametersExt.getSlackBusesIds(),
parametersExt.getPlausibleActivePowerLimit(), parametersExt.getMostMeshedSlackBusSelectorMaxNominalVoltagePercentile(), parametersExt.getSlackBusCountryFilter());

var networkParameters = getNetworkParameters(parameters, parametersExt, slackBusSelector, connectivityFactory, breakers);
var networkParameters = getNetworkParameters(parameters, parametersExt, slackBusSelector, matrixFactory, connectivityFactory, breakers);

var equationSystemCreationParameters = new AcEquationSystemCreationParameters(forceA1Var);

Expand Down Expand Up @@ -1877,7 +1897,8 @@ public static AcLoadFlowParameters createAcParameters(LoadFlowParameters paramet
.setVoltageInitializer(voltageInitializer)
.setAsymmetrical(parametersExt.isAsymmetrical())
.setSlackDistributionFailureBehavior(parametersExt.getSlackDistributionFailureBehavior())
.setSolverFactory(solverFactory);
.setSolverFactory(solverFactory)
.setFixRemoteVoltageTarget(parametersExt.isFixRemoteVoltageTarget());
}

public static DcLoadFlowParameters createDcParameters(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
Expand Down Expand Up @@ -1941,6 +1962,14 @@ public static DcLoadFlowParameters createDcParameters(LoadFlowParameters paramet
.setMaxOuterLoopIterations(parametersExt.getMaxOuterLoopIterations());
}

static GraphConnectivityFactory<LfBus, LfBranch> getConnectivityFactory(OpenLoadFlowParameters parametersExt,
GraphConnectivityFactory<LfBus, LfBranch> defaultConnectivityFactory) {
return parametersExt.isNetworkCacheEnabled() && !parametersExt.getActionableSwitchesIds().isEmpty()
|| parametersExt.isSimulateAutomationSystems()
? new NaiveGraphConnectivityFactory<>(LfBus::getNum)
: defaultConnectivityFactory;
}

public static boolean equals(LoadFlowParameters parameters1, LoadFlowParameters parameters2) {
Objects.requireNonNull(parameters1);
Objects.requireNonNull(parameters2);
Expand Down Expand Up @@ -2046,7 +2075,8 @@ public static boolean equals(LoadFlowParameters parameters1, LoadFlowParameters
extension1.getFictitiousGeneratorVoltageControlCheckMode() == extension2.getFictitiousGeneratorVoltageControlCheckMode() &&
extension1.isAreaInterchangeControl() == extension2.isAreaInterchangeControl() &&
Objects.equals(extension1.getAreaInterchangeControlAreaType(), extension2.getAreaInterchangeControlAreaType()) &&
extension1.getAreaInterchangePMaxMismatch() == extension2.getAreaInterchangePMaxMismatch();
extension1.getAreaInterchangePMaxMismatch() == extension2.getAreaInterchangePMaxMismatch() &&
extension1.isFixRemoteVoltageTarget() == extension2.isFixRemoteVoltageTarget();
}

public static LoadFlowParameters clone(LoadFlowParameters parameters) {
Expand Down Expand Up @@ -2142,7 +2172,8 @@ public static LoadFlowParameters clone(LoadFlowParameters parameters) {
.setFictitiousGeneratorVoltageControlCheckMode(extension.getFictitiousGeneratorVoltageControlCheckMode())
.setAreaInterchangeControl(extension.isAreaInterchangeControl())
.setAreaInterchangeControlAreaType(extension.getAreaInterchangeControlAreaType())
.setAreaInterchangePMaxMismatch(extension.getAreaInterchangePMaxMismatch());
.setAreaInterchangePMaxMismatch(extension.getAreaInterchangePMaxMismatch())
.setFixRemoteVoltageTarget(extension.isFixRemoteVoltageTarget());

if (extension2 != null) {
parameters2.addExtension(OpenLoadFlowParameters.class, extension2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import com.powsybl.openloadflow.dc.DcLoadFlowResult;
import com.powsybl.openloadflow.graph.EvenShiloachGraphDecrementalConnectivityFactory;
import com.powsybl.openloadflow.graph.GraphConnectivityFactory;
import com.powsybl.openloadflow.graph.NaiveGraphConnectivityFactory;
import com.powsybl.openloadflow.lf.AbstractLoadFlowResult;
import com.powsybl.openloadflow.lf.outerloop.OuterLoop;
import com.powsybl.openloadflow.network.*;
Expand Down Expand Up @@ -93,13 +92,6 @@ public String getVersion() {
return new PowsyblCoreVersion().getMavenProjectVersion();
}

private GraphConnectivityFactory<LfBus, LfBranch> getConnectivityFactory(OpenLoadFlowParameters parametersExt) {
return parametersExt.isNetworkCacheEnabled() && !parametersExt.getActionableSwitchesIds().isEmpty()
|| parametersExt.isSimulateAutomationSystems()
? new NaiveGraphConnectivityFactory<>(LfBus::getNum)
: connectivityFactory;
}

private void updateAcState(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
AcLoadFlowResult result, AcLoadFlowParameters acParameters, boolean atLeastOneComponentHasToBeUpdated) {
if (parametersExt.isNetworkCacheEnabled()) {
Expand Down Expand Up @@ -134,7 +126,7 @@ private void updateAcState(Network network, LoadFlowParameters parameters, OpenL
}

private LoadFlowResult runAc(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt, ReportNode reportNode) {
GraphConnectivityFactory<LfBus, LfBranch> selectedConnectivityFactory = getConnectivityFactory(parametersExt);
GraphConnectivityFactory<LfBus, LfBranch> selectedConnectivityFactory = OpenLoadFlowParameters.getConnectivityFactory(parametersExt, connectivityFactory);
AcLoadFlowParameters acParameters = OpenLoadFlowParameters.createAcParameters(network, parameters, parametersExt, matrixFactory, selectedConnectivityFactory);
acParameters.setDetailedReport(parametersExt.getReportedFeatures().contains(OpenLoadFlowParameters.ReportedFeatures.NEWTON_RAPHSON_LOAD_FLOW));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* 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.openloadflow;

import com.powsybl.openloadflow.network.LfBus;

import java.util.ArrayList;
import java.util.List;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public class RemoteVoltageTargetCheckResult {

public record IncompatibleTarget(LfBus controlledBus1, LfBus controlledBus2, double targetVoltagePlausibilityIndicator) {
}

public record UnrealisticTarget(LfBus controllerBus, double estimatedDvController) {
}

private final List<IncompatibleTarget> incompatibleTargets = new ArrayList<>();

private final List<UnrealisticTarget> unrealisticTargets = new ArrayList<>();

public List<IncompatibleTarget> getIncompatibleTargets() {
return incompatibleTargets;
}

public List<UnrealisticTarget> getUnrealisticTargets() {
return unrealisticTargets;
}
}
Loading