Skip to content

Commit

Permalink
Fix PerEquationTypeStoppingCriteria (#951)
Browse files Browse the repository at this point in the history
Signed-off-by: Damien Jeandemange <[email protected]>
  • Loading branch information
jeandemanged authored Jan 15, 2024
1 parent dd38a35 commit dd6acf1
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 48 deletions.
26 changes: 12 additions & 14 deletions src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ private static <E extends Enum<E>> List<Object> getEnumPossibleValues(Class<E> e
new Parameter(REACTIVE_POWER_REMOTE_CONTROL_PARAM_NAME, ParameterType.BOOLEAN, "SVC remote reactive power control", REACTIVE_POWER_REMOTE_CONTROL_DEFAULT_VALUE),
new Parameter(MAX_NEWTON_RAPHSON_ITERATIONS_PARAM_NAME, ParameterType.INTEGER, "Max iterations per Newton-Raphson", NewtonRaphsonParameters.DEFAULT_MAX_ITERATIONS),
new Parameter(MAX_OUTER_LOOP_ITERATIONS_PARAM_NAME, ParameterType.INTEGER, "Max outer loop iterations", AbstractLoadFlowParameters.DEFAULT_MAX_OUTER_LOOP_ITERATIONS),
new Parameter(NEWTON_RAPHSON_CONV_EPS_PER_EQ_PARAM_NAME, ParameterType.DOUBLE, "Newton-Raphson convergence epsilon per equation", DefaultNewtonRaphsonStoppingCriteria.DEFAULT_CONV_EPS_PER_EQ),
new Parameter(NEWTON_RAPHSON_CONV_EPS_PER_EQ_PARAM_NAME, ParameterType.DOUBLE, "Newton-Raphson convergence epsilon per equation", NewtonRaphsonStoppingCriteria.DEFAULT_CONV_EPS_PER_EQ),
new Parameter(VOLTAGE_INIT_MODE_OVERRIDE_PARAM_NAME, ParameterType.STRING, "Voltage init mode override", VOLTAGE_INIT_MODE_OVERRIDE_DEFAULT_VALUE.name(), getEnumPossibleValues(VoltageInitModeOverride.class)),
new Parameter(TRANSFORMER_VOLTAGE_CONTROL_MODE_PARAM_NAME, ParameterType.STRING, "Transformer voltage control mode", TRANSFORMER_VOLTAGE_CONTROL_MODE_DEFAULT_VALUE.name(), getEnumPossibleValues(TransformerVoltageControlMode.class)),
new Parameter(SHUNT_VOLTAGE_CONTROL_MODE_PARAM_NAME, ParameterType.STRING, "Shunt voltage control mode", SHUNT_VOLTAGE_CONTROL_MODE_DEFAULT_VALUE.name(), getEnumPossibleValues(ShuntVoltageControlMode.class)),
Expand Down Expand Up @@ -361,7 +361,7 @@ public enum LowImpedanceBranchMode {

private int maxOuterLoopIterations = AbstractLoadFlowParameters.DEFAULT_MAX_OUTER_LOOP_ITERATIONS;

private double newtonRaphsonConvEpsPerEq = DefaultNewtonRaphsonStoppingCriteria.DEFAULT_CONV_EPS_PER_EQ;
private double newtonRaphsonConvEpsPerEq = NewtonRaphsonStoppingCriteria.DEFAULT_CONV_EPS_PER_EQ;

private VoltageInitModeOverride voltageInitModeOverride = VOLTAGE_INIT_MODE_OVERRIDE_DEFAULT_VALUE;

Expand Down Expand Up @@ -1081,7 +1081,7 @@ public static OpenLoadFlowParameters load(PlatformConfig platformConfig) {
.setReactivePowerRemoteControl(config.getBooleanProperty(REACTIVE_POWER_REMOTE_CONTROL_PARAM_NAME, REACTIVE_POWER_REMOTE_CONTROL_DEFAULT_VALUE))
.setMaxNewtonRaphsonIterations(config.getIntProperty(MAX_NEWTON_RAPHSON_ITERATIONS_PARAM_NAME, NewtonRaphsonParameters.DEFAULT_MAX_ITERATIONS))
.setMaxOuterLoopIterations(config.getIntProperty(MAX_OUTER_LOOP_ITERATIONS_PARAM_NAME, AbstractLoadFlowParameters.DEFAULT_MAX_OUTER_LOOP_ITERATIONS))
.setNewtonRaphsonConvEpsPerEq(config.getDoubleProperty(NEWTON_RAPHSON_CONV_EPS_PER_EQ_PARAM_NAME, DefaultNewtonRaphsonStoppingCriteria.DEFAULT_CONV_EPS_PER_EQ))
.setNewtonRaphsonConvEpsPerEq(config.getDoubleProperty(NEWTON_RAPHSON_CONV_EPS_PER_EQ_PARAM_NAME, NewtonRaphsonStoppingCriteria.DEFAULT_CONV_EPS_PER_EQ))
.setVoltageInitModeOverride(config.getEnumProperty(VOLTAGE_INIT_MODE_OVERRIDE_PARAM_NAME, VoltageInitModeOverride.class, VOLTAGE_INIT_MODE_OVERRIDE_DEFAULT_VALUE))
.setTransformerVoltageControlMode(config.getEnumProperty(TRANSFORMER_VOLTAGE_CONTROL_MODE_PARAM_NAME, TransformerVoltageControlMode.class, TRANSFORMER_VOLTAGE_CONTROL_MODE_DEFAULT_VALUE))
.setShuntVoltageControlMode(config.getEnumProperty(SHUNT_VOLTAGE_CONTROL_MODE_PARAM_NAME, ShuntVoltageControlMode.class, SHUNT_VOLTAGE_CONTROL_MODE_DEFAULT_VALUE))
Expand Down Expand Up @@ -1458,17 +1458,15 @@ public static AcLoadFlowParameters createAcParameters(Network network, LoadFlowP
}

private static NewtonRaphsonStoppingCriteria createNewtonRaphsonStoppingCriteria(OpenLoadFlowParameters parametersExt) {
switch (parametersExt.getNewtonRaphsonStoppingCriteriaType()) {
case UNIFORM_CRITERIA:
return new DefaultNewtonRaphsonStoppingCriteria(parametersExt.getNewtonRaphsonConvEpsPerEq());
case PER_EQUATION_TYPE_CRITERIA:
return new PerEquationTypeStoppingCriteria(parametersExt.getMaxActivePowerMismatch(),
parametersExt.getMaxReactivePowerMismatch(), parametersExt.getMaxVoltageMismatch(),
parametersExt.getMaxAngleMismatch(), parametersExt.getMaxRatioMismatch(),
parametersExt.getMaxSusceptanceMismatch());
default:
throw new PowsyblException("Unknown Newton Raphson stopping criteria type: " + parametersExt.getNewtonRaphsonStoppingCriteriaType());
}
return switch (parametersExt.getNewtonRaphsonStoppingCriteriaType()) {
case UNIFORM_CRITERIA ->
new DefaultNewtonRaphsonStoppingCriteria(parametersExt.getNewtonRaphsonConvEpsPerEq());
case PER_EQUATION_TYPE_CRITERIA ->
new PerEquationTypeStoppingCriteria(parametersExt.getNewtonRaphsonConvEpsPerEq(), parametersExt.getMaxActivePowerMismatch(),
parametersExt.getMaxReactivePowerMismatch(), parametersExt.getMaxVoltageMismatch(),
parametersExt.getMaxAngleMismatch(), parametersExt.getMaxRatioMismatch(),
parametersExt.getMaxSusceptanceMismatch());
};
}

static List<AcOuterLoop> createOuterLoops(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,10 @@
*/
public class DefaultNewtonRaphsonStoppingCriteria implements NewtonRaphsonStoppingCriteria {

/**
* Convergence epsilon per equation: 10^-4 in p.u => 10^-2 in Kv, Mw or MVar
*/
public static final double DEFAULT_CONV_EPS_PER_EQ = Math.pow(10, -4);

private final double convEpsPerEq;

public DefaultNewtonRaphsonStoppingCriteria() {
this(DEFAULT_CONV_EPS_PER_EQ);
this(NewtonRaphsonStoppingCriteria.DEFAULT_CONV_EPS_PER_EQ);
}

public DefaultNewtonRaphsonStoppingCriteria(double convEpsPerEq) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
*/
public interface NewtonRaphsonStoppingCriteria {

/**
* Convergence epsilon per equation: 10^-4 in p.u => 10^-2 in Kv, Mw or MVar
*/
double DEFAULT_CONV_EPS_PER_EQ = Math.pow(10, -4);

class TestResult {

private final boolean stop;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/
package com.powsybl.openloadflow.ac.solver;

import com.powsybl.commons.PowsyblException;
import com.powsybl.openloadflow.ac.equations.AcEquationType;
import com.powsybl.openloadflow.ac.equations.AcVariableType;
import com.powsybl.openloadflow.equations.EquationSystem;
Expand All @@ -19,6 +18,8 @@
*/
public class PerEquationTypeStoppingCriteria implements NewtonRaphsonStoppingCriteria {

private final double convEpsPerEq;

private final double maxDefaultAngleMismatch;

private final double maxDefaultRatioMismatch;
Expand All @@ -31,10 +32,11 @@ public class PerEquationTypeStoppingCriteria implements NewtonRaphsonStoppingCri

private final double maxVoltageMismatch;

public PerEquationTypeStoppingCriteria(double maxActivePowerMismatch,
public PerEquationTypeStoppingCriteria(double convEpsPerEq, double maxActivePowerMismatch,
double maxReactivePowerMismatch, double maxVoltageMismatch,
double maxDefaultAngleMismatch, double maxDefaultRatioMismatch,
double maxDefaultSusceptanceMismatch) {
this.convEpsPerEq = convEpsPerEq;
this.maxActivePowerMismatch = maxActivePowerMismatch;
this.maxReactivePowerMismatch = maxReactivePowerMismatch;
this.maxVoltageMismatch = maxVoltageMismatch;
Expand All @@ -52,48 +54,41 @@ private boolean computeStop(double[] fx, EquationSystem<AcVariableType, AcEquati
var type = eq.getType();
var idx = eq.getColumn();
switch (type) {
case BRANCH_TARGET_P,
BUS_TARGET_P,
DUMMY_TARGET_P:
case BRANCH_TARGET_P, BUS_TARGET_P, DUMMY_TARGET_P, BUS_DISTR_SLACK_P -> {
if (Math.abs(fx[idx]) * PerUnit.SB >= maxActivePowerMismatch) {
return false;
}
break;
case BRANCH_TARGET_Q,
BUS_TARGET_Q,
DISTR_Q,
DUMMY_TARGET_Q:
}
case BRANCH_TARGET_Q, BUS_TARGET_Q, DISTR_Q, DUMMY_TARGET_Q -> {
if (Math.abs(fx[idx]) * PerUnit.SB >= maxReactivePowerMismatch) {
return false;
}
break;
case BUS_TARGET_V,
ZERO_V:
}
case BUS_TARGET_V, ZERO_V -> {
if (Math.abs(fx[idx]) >= maxVoltageMismatch) {
return false;
}
break;
case BRANCH_TARGET_RHO1,
DISTR_RHO:
}
case BRANCH_TARGET_RHO1, DISTR_RHO -> {
if (Math.abs(fx[idx]) >= maxDefaultRatioMismatch) {
return false;
}
break;
case DISTR_SHUNT_B,
SHUNT_TARGET_B:
}
case DISTR_SHUNT_B, SHUNT_TARGET_B -> {
if (Math.abs(fx[idx]) >= maxDefaultSusceptanceMismatch) {
return false;
}
break;
case BUS_TARGET_PHI,
ZERO_PHI,
BRANCH_TARGET_ALPHA1:
}
case BUS_TARGET_PHI, ZERO_PHI, BRANCH_TARGET_ALPHA1 -> {
if (Math.abs(fx[idx]) >= maxDefaultAngleMismatch) {
return false;
}
break;
default:
throw new PowsyblException("Unknown equation term");
}
default -> {
if (Math.abs(fx[idx]) >= convEpsPerEq) {
return false;
}
}
}
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@
import com.powsybl.math.matrix.DenseMatrixFactory;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowProvider;
import com.powsybl.openloadflow.ac.solver.NewtonRaphsonStoppingCriteriaType;
import com.powsybl.openloadflow.network.EurostagFactory;
import com.powsybl.openloadflow.util.LoadFlowAssert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand Down Expand Up @@ -48,8 +54,14 @@ void setUp() {
.setMaxSlackBusCount(2);
}

@Test
void multiSlackTest() {
static Stream<Arguments> allStoppingCriteriaTypes() {
return Arrays.stream(NewtonRaphsonStoppingCriteriaType.values()).map(Arguments::of);
}

@ParameterizedTest(name = "{0}")
@MethodSource("allStoppingCriteriaTypes")
void multiSlackTest(NewtonRaphsonStoppingCriteriaType stoppingCriteria) {
parametersExt.setNewtonRaphsonStoppingCriteriaType(stoppingCriteria);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
package com.powsybl.openloadflow.ac.solver;

import com.powsybl.iidm.network.Bus;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.Terminal;
import com.powsybl.loadflow.LoadFlow;
Expand All @@ -15,10 +16,13 @@
import com.powsybl.math.matrix.DenseMatrixFactory;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowProvider;
import com.powsybl.openloadflow.ac.AsymmetricalLoadFlowTest;
import com.powsybl.openloadflow.network.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static com.powsybl.openloadflow.util.LoadFlowAssert.assertAngleEquals;
import static com.powsybl.openloadflow.util.LoadFlowAssert.assertVoltageEquals;
import static org.junit.jupiter.api.Assertions.*;

/**
Expand Down Expand Up @@ -190,4 +194,28 @@ void testReactivePowerConvergedPerEquationCriteria2() {
assertEquals(0.0, b1Q, 1E-2);
assertEquals(0.0, b2Q, 1E-2);
}

@Test
void fourNodesAsymTestPerEqStoppingCriteria() {
network = AsymmetricalLoadFlowTest.fourNodescreate();
parameters
.setUseReactiveLimits(false)
.setDistributedSlack(false);
OpenLoadFlowParameters.create(parameters)
.setSlackBusSelectionMode(SlackBusSelectionMode.FIRST)
.setAsymmetrical(true)
.setNewtonRaphsonStoppingCriteriaType(NewtonRaphsonStoppingCriteriaType.PER_EQUATION_TYPE_CRITERIA);

LoadFlowResult result = loadFlowRunner.run(network, parameters);
assertTrue(result.isFullyConverged());
Bus bus1 = network.getBusBreakerView().getBus("B1");
Bus bus2 = network.getBusBreakerView().getBus("B2");
Bus bus3 = network.getBusBreakerView().getBus("B3");
Bus bus4 = network.getBusBreakerView().getBus("B4");
assertVoltageEquals(100., bus1);
assertAngleEquals(0, bus1);
assertVoltageEquals(99.7971047825933, bus2); // balanced = 99.79736062173895
assertVoltageEquals(99.45937102112217, bus3); // balanced = 99.54462759204546
assertVoltageEquals(99.2070528211056, bus4); // balanced = 99.29252809145005
}
}

0 comments on commit dd6acf1

Please sign in to comment.