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

Support outerLoopNames parameter in DC Load Flow #1159

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
18 changes: 17 additions & 1 deletion docs/loadflow/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,23 @@ This parameter allows to disable the voltage control of generators which `target
This parameter allows to configure both the list of outer loops that can be executed and their explicit execution order.
Each outer loop name specified in the list must be unique and match the `NAME` attribute of the respective outer loop.

By default, this parameter is set to `null`, and the activated outer loops are executed in a default order (defined in DefaultAcOuterLoopConfig).
By default, this parameter is set to `null`, and the activated outer loops are executed in a default order
(as defined in `DefaultAcOuterLoopConfig` for AC Load Flow and `DefaultDcOuterLoopConfig` for DC Load Flow).
vidaldid-rte marked this conversation as resolved.
Show resolved Hide resolved

The supported outer loop names for AC load flow and their default order are:
1. `DistributedSlack` / `AreaInterchangeControl`
2. `SecondaryVoltageControl`
3. `VoltageMonitoring`
4. `ReactiveLimits`
5. `PhaseControl` / `IncrementalPhaseControl`
6. `SimpleTransformerVoltageControl` / `TransformerVoltageControl` / `IncrementalTransformerVoltageControl`
7. `IncrementalTransformerReactivePowerControl`
8. `ShuntVoltageControl` / `IncrementalShuntVoltageControl`
9. `AutomationSystem`

And for DC load flow:
1. `IncrementalPhaseControl`
2. `AreaInterchangeControl`

**linePerUnitMode**
This parameter defines how lines ending in different nominal voltages at both sides are perunit-ed.
Expand Down
32 changes: 14 additions & 18 deletions src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,20 @@
import com.powsybl.openloadflow.ac.solver.*;
import com.powsybl.openloadflow.ac.outerloop.AcOuterLoop;
import com.powsybl.openloadflow.ac.outerloop.ReactiveLimitsOuterLoop;
import com.powsybl.openloadflow.dc.DcAreaInterchangeControlOuterLoop;
import com.powsybl.openloadflow.dc.DcIncrementalPhaseControlOuterLoop;
import com.powsybl.openloadflow.dc.DcLoadFlowParameters;
import com.powsybl.openloadflow.dc.DcOuterLoop;
import com.powsybl.openloadflow.dc.DcValueVoltageInitializer;
import com.powsybl.openloadflow.dc.equations.DcApproximationType;
import com.powsybl.openloadflow.dc.equations.DcEquationSystemCreationParameters;
import com.powsybl.openloadflow.graph.GraphConnectivityFactory;
import com.powsybl.openloadflow.lf.AbstractLoadFlowParameters;
import com.powsybl.openloadflow.lf.outerloop.config.AcOuterLoopConfig;
import com.powsybl.openloadflow.lf.outerloop.config.DcOuterLoopConfig;
import com.powsybl.openloadflow.lf.outerloop.config.DefaultAcOuterLoopConfig;
import com.powsybl.openloadflow.lf.outerloop.config.DefaultDcOuterLoopConfig;
import com.powsybl.openloadflow.lf.outerloop.config.ExplicitAcOuterLoopConfig;
import com.powsybl.openloadflow.lf.outerloop.config.ExplicitDcOuterLoopConfig;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.network.util.ActivePowerDistribution;
import com.powsybl.openloadflow.network.util.PreviousValueVoltageInitializer;
import com.powsybl.openloadflow.network.util.UniformValueVoltageInitializer;
import com.powsybl.openloadflow.network.util.VoltageInitializer;
Expand Down Expand Up @@ -399,7 +402,7 @@ public static List<Object> getAcSolverTypePossibleValues() {
new Parameter(ASYMMETRICAL_PARAM_NAME, ParameterType.BOOLEAN, "Asymmetrical calculation", LfNetworkParameters.ASYMMETRICAL_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, MODEL_CATEGORY_KEY),
new Parameter(MIN_NOMINAL_VOLTAGE_TARGET_VOLTAGE_CHECK_PARAM_NAME, ParameterType.DOUBLE, "Min nominal voltage for target voltage check", LfNetworkParameters.MIN_NOMINAL_VOLTAGE_TARGET_VOLTAGE_CHECK_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, VOLTAGE_CONTROLS_CATEGORY_KEY),
new Parameter(REACTIVE_POWER_DISPATCH_MODE_PARAM_NAME, ParameterType.STRING, "Generators reactive power from bus dispatch mode", REACTIVE_POWER_DISPATCH_MODE_DEFAULT_VALUE.name(), getEnumPossibleValues(ReactivePowerDispatchMode.class), ParameterScope.FUNCTIONAL, GENERATOR_VOLTAGE_CONTROL_CATEGORY_KEY),
new Parameter(OUTER_LOOP_NAMES_PARAM_NAME, ParameterType.STRING_LIST, "Ordered explicit list of outer loop names, supported outer loops are " + String.join(", ", ExplicitAcOuterLoopConfig.NAMES), OUTER_LOOP_NAMES_DEFAULT_VALUE, ParameterScope.TECHNICAL, OUTER_LOOPS_CATEGORY_KEY),
new Parameter(OUTER_LOOP_NAMES_PARAM_NAME, ParameterType.STRING_LIST, "Ordered explicit list of outer loop names, supported outer loops are for AC : [" + String.join(", ", ExplicitAcOuterLoopConfig.NAMES) + "], and for DC : [" + String.join(", ", ExplicitDcOuterLoopConfig.NAMES) + "]", OUTER_LOOP_NAMES_DEFAULT_VALUE, ParameterScope.TECHNICAL, OUTER_LOOPS_CATEGORY_KEY),
new Parameter(USE_ACTIVE_LIMITS_PARAM_NAME, ParameterType.BOOLEAN, "Use active power limits in slack distribution", LfNetworkParameters.USE_ACTIVE_LIMITS_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, SLACK_DISTRIBUTION_CATEGORY_KEY),
new Parameter(DISABLE_VOLTAGE_CONTROL_OF_GENERATORS_OUTSIDE_ACTIVE_POWER_LIMITS_PARAM_NAME, ParameterType.BOOLEAN, "Disable voltage control of generators outside active power limits", LfNetworkParameters.DISABLE_VOLTAGE_CONTROL_OF_GENERATORS_OUTSIDE_ACTIVE_POWER_LIMITS_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, GENERATOR_VOLTAGE_CONTROL_CATEGORY_KEY),
new Parameter(LINE_SEARCH_STATE_VECTOR_SCALING_MAX_ITERATION_PARAM_NAME, ParameterType.INTEGER, "Max iteration for the line search state vector scaling", LineSearchStateVectorScaling.DEFAULT_MAX_ITERATION, ParameterScope.FUNCTIONAL, NEWTON_RAPHSON_CATEGORY_KEY),
Expand Down Expand Up @@ -1827,6 +1830,13 @@ static List<AcOuterLoop> createAcOuterLoops(LoadFlowParameters parameters, OpenL
return outerLoopConfig.configure(parameters, parametersExt);
}

static List<DcOuterLoop> createDcOuterLoops(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
DcOuterLoopConfig outerLoopConfig = DcOuterLoopConfig.findOuterLoopConfig()
.orElseGet(() -> parametersExt.getOuterLoopNames() != null ? new ExplicitDcOuterLoopConfig()
: new DefaultDcOuterLoopConfig());
return outerLoopConfig.configure(parameters, parametersExt);
}

public static AcLoadFlowParameters createAcParameters(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
MatrixFactory matrixFactory, GraphConnectivityFactory<LfBus, LfBranch> connectivityFactory,
boolean breakers, boolean forceA1Var) {
Expand Down Expand Up @@ -1855,20 +1865,6 @@ public static AcLoadFlowParameters createAcParameters(LoadFlowParameters paramet
.setSolverFactory(solverFactory, parameters);
}

static List<DcOuterLoop> createDcOuterLoops(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
List<DcOuterLoop> outerLoops = new ArrayList<>();
if (parameters.isPhaseShifterRegulationOn()) {
DcIncrementalPhaseControlOuterLoop phaseShifterControlOuterLoop = new DcIncrementalPhaseControlOuterLoop();
outerLoops.add(phaseShifterControlOuterLoop);
}
if (parametersExt.isAreaInterchangeControl()) {
ActivePowerDistribution activePowerDistribution = ActivePowerDistribution.create(parameters.getBalanceType(), false, parametersExt.isUseActiveLimits());
DcAreaInterchangeControlOuterLoop areaInterchangeControlOuterLoop = new DcAreaInterchangeControlOuterLoop(activePowerDistribution, parametersExt.getSlackBusPMaxMismatch(), parametersExt.getAreaInterchangePMaxMismatch());
outerLoops.add(areaInterchangeControlOuterLoop);
}
return outerLoops;
}

public static DcLoadFlowParameters createDcParameters(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
MatrixFactory matrixFactory, GraphConnectivityFactory<LfBus, LfBranch> connectivityFactory,
boolean forcePhaseControlOffAndAddAngle1Var) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ public class AcAreaInterchangeControlOuterLoop

private static final Logger LOGGER = LoggerFactory.getLogger(AcAreaInterchangeControlOuterLoop.class);

public static final String NAME = "AreaInterchangeControl";

public AcAreaInterchangeControlOuterLoop(ActivePowerDistribution activePowerDistribution, double slackBusPMaxMismatch, double areaInterchangePMaxMismatch) {
super(activePowerDistribution, new DistributedSlackOuterLoop(activePowerDistribution, slackBusPMaxMismatch), slackBusPMaxMismatch, areaInterchangePMaxMismatch, LOGGER);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ public class AcIncrementalPhaseControlOuterLoop
extends AbstractIncrementalPhaseControlOuterLoop<AcVariableType, AcEquationType, AcLoadFlowParameters, AcLoadFlowContext, AcOuterLoopContext>
implements AcOuterLoop {

public static final String NAME = "IncrementalPhaseControl";

public AcIncrementalPhaseControlOuterLoop() {
super(LoggerFactory.getLogger(AcIncrementalPhaseControlOuterLoop.class));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public DcAreaInterchangeControlOuterLoop(ActivePowerDistribution activePowerDist

@Override
public String getName() {
return "AreaInterchangeControl";
Copy link
Contributor

Choose a reason for hiding this comment

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

This method getName() can be moved to the parent abstract class AbstractAreaInterchangeControlOuterLoop

return NAME;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public DcIncrementalPhaseControlOuterLoop() {

@Override
public String getName() {
return "DC Incremental phase control";
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here with the class AbstractIncrementalPhaseControlOuterLoop

return NAME;
}

public static class DcSensitivityContext extends AbstractSensitivityContext<DcVariableType, DcEquationType> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public abstract class AbstractAreaInterchangeControlOuterLoop<
O extends AbstractOuterLoopContext<V, E, P, C>>
extends AbstractActivePowerDistributionOuterLoop<V, E, P, C, O> {

public static final String NAME = "AreaInterchangeControl";

private final Logger logger;

protected static final String FAILED_TO_DISTRIBUTE_INTERCHANGE_ACTIVE_POWER_MISMATCH = "Failed to distribute interchange active power mismatch";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public abstract class AbstractIncrementalPhaseControlOuterLoop<V extends Enum<V>
public static final double MIN_TARGET_DEADBAND = 1 / PerUnit.SB; // 1 MW
public static final double SENSI_EPS = 1e-6;
public static final double PHASE_SHIFT_CROSS_IMPACT_MARGIN = 0.75;

public static final String NAME = "IncrementalPhaseControl";
protected final Logger logger;

protected AbstractIncrementalPhaseControlOuterLoop(Logger logger) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.openloadflow;
package com.powsybl.openloadflow.lf.outerloop.config;

import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.ac.outerloop.*;
import com.powsybl.openloadflow.network.util.ActivePowerDistribution;
import com.powsybl.openloadflow.util.PerUnit;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/)
* 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.loadflow.LoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.dc.DcAreaInterchangeControlOuterLoop;
import com.powsybl.openloadflow.dc.DcIncrementalPhaseControlOuterLoop;
import com.powsybl.openloadflow.dc.DcOuterLoop;
import com.powsybl.openloadflow.network.util.ActivePowerDistribution;

import java.util.Optional;

/**
* @author Valentin Mouradian {@literal <valentin.mouradian at artelys.com>}
*/
abstract class AbstractDcOuterLoopConfig implements DcOuterLoopConfig {

protected AbstractDcOuterLoopConfig() {
}

protected static Optional<DcOuterLoop> createAreaInterchangeControlOuterLoop(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
if (parametersExt.isAreaInterchangeControl()) {
ActivePowerDistribution activePowerDistribution = ActivePowerDistribution.create(parameters.getBalanceType(), parametersExt.isLoadPowerFactorConstant(), parametersExt.isUseActiveLimits());
return Optional.of(new DcAreaInterchangeControlOuterLoop(activePowerDistribution, parametersExt.getSlackBusPMaxMismatch(), parametersExt.getAreaInterchangePMaxMismatch()));
}
return Optional.empty();
}

protected static Optional<DcOuterLoop> createIncrementalPhaseControlOuterLoop(LoadFlowParameters parameters) {
if (parameters.isPhaseShifterRegulationOn()) {
return Optional.of(new DcIncrementalPhaseControlOuterLoop());
}
return Optional.empty();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Copyright (c) 2021, RTE (http://www.rte-france.com)
* Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/)
* 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.openloadflow.ac.outerloop.AcOuterLoop;

import java.util.Optional;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
* @author Valentin Mouradian {@literal <valentin.mouradian at artelys.com>}
*/
public interface AcOuterLoopConfig extends OuterLoopConfig<AcOuterLoop> {

static Optional<AcOuterLoopConfig> findOuterLoopConfig() {
return OuterLoopConfig.findOuterLoopConfig(AcOuterLoopConfig.class);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/)
* 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.openloadflow.dc.DcOuterLoop;

import java.util.Optional;

/**
* @author Valentin Mouradian {@literal <valentin.mouradian at artelys.com>}
*/
public interface DcOuterLoopConfig extends OuterLoopConfig<DcOuterLoop> {

static Optional<DcOuterLoopConfig> findOuterLoopConfig() {
return OuterLoopConfig.findOuterLoopConfig(DcOuterLoopConfig.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.openloadflow;
package com.powsybl.openloadflow.lf.outerloop.config;

import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.ac.outerloop.*;

import java.util.ArrayList;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/)
* 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.loadflow.LoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.dc.DcOuterLoop;

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

/**
* @author Valentin Mouradian {@literal <valentin.mouradian at artelys.com>}
*/
public class DefaultDcOuterLoopConfig extends AbstractDcOuterLoopConfig {

@Override
public List<DcOuterLoop> configure(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
List<DcOuterLoop> outerLoops = new ArrayList<>(2);
// incremental phase control
createIncrementalPhaseControlOuterLoop(parameters).ifPresent(outerLoops::add);
// area interchange control
createAreaInterchangeControlOuterLoop(parameters, parametersExt).ifPresent(outerLoops::add);
return outerLoops;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.openloadflow;
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.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;
Expand All @@ -23,7 +26,7 @@
*/
public class ExplicitAcOuterLoopConfig extends AbstractAcOuterLoopConfig {

public static final List<String> NAMES = List.of(AcIncrementalPhaseControlOuterLoop.NAME,
public static final List<String> NAMES = List.of(AbstractIncrementalPhaseControlOuterLoop.NAME,
DistributedSlackOuterLoop.NAME,
IncrementalShuntVoltageControlOuterLoop.NAME,
IncrementalTransformerVoltageControlOuterLoop.NAME,
Expand All @@ -36,11 +39,11 @@ public class ExplicitAcOuterLoopConfig extends AbstractAcOuterLoopConfig {
TransformerVoltageControlOuterLoop.NAME,
AutomationSystemOuterLoop.NAME,
IncrementalTransformerReactivePowerControlOuterLoop.NAME,
AcAreaInterchangeControlOuterLoop.NAME);
AbstractAreaInterchangeControlOuterLoop.NAME);

private static Optional<AcOuterLoop> createOuterLoop(String name, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
return switch (name) {
case AcIncrementalPhaseControlOuterLoop.NAME -> createPhaseControlOuterLoop(parameters,
case AbstractIncrementalPhaseControlOuterLoop.NAME -> createPhaseControlOuterLoop(parameters,
OpenLoadFlowParameters.PhaseShifterControlMode.INCREMENTAL);
case DistributedSlackOuterLoop.NAME -> createDistributedSlackOuterLoop(parameters, parametersExt);
case IncrementalShuntVoltageControlOuterLoop.NAME -> createShuntVoltageControlOuterLoop(parameters,
Expand Down Expand Up @@ -69,8 +72,8 @@ private static Optional<AcOuterLoop> createOuterLoop(String name, LoadFlowParame
parametersExt.getGeneratorVoltageControlMinNominalVoltage());
case AutomationSystemOuterLoop.NAME -> createAutomationSystemOuterLoop(parametersExt);
case IncrementalTransformerReactivePowerControlOuterLoop.NAME -> createTransformerReactivePowerControlOuterLoop(parametersExt);
case AcAreaInterchangeControlOuterLoop.NAME -> createAreaInterchangeControlOuterLoop(parameters, parametersExt);
default -> throw new PowsyblException("Unknown outer loop '" + name + "'");
case AbstractAreaInterchangeControlOuterLoop.NAME -> createAreaInterchangeControlOuterLoop(parameters, parametersExt);
default -> throw new PowsyblException("Unknown outer loop '" + name + "' for AC load flow");
};
}

Expand Down
Loading
Loading