diff --git a/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java b/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java index e6c342147d..3cc2979c0a 100644 --- a/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java +++ b/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java @@ -134,6 +134,8 @@ public enum FictitiousGeneratorVoltageControlCheckMode { public static final String SLACK_DISTRIBUTION_FAILURE_BEHAVIOR_PARAM_NAME = "slackDistributionFailureBehavior"; + public static final String UNREALISTIC_VOLTAGE_CHECK_BEHAVIOR_PARAM_NAME = "unrealisticVoltageCheckBehavior"; + public static final String VOLTAGE_REMOTE_CONTROL_PARAM_NAME = "voltageRemoteControl"; public static final String GENERATOR_REACTIVE_POWER_REMOTE_CONTROL_PARAM_NAME = "generatorReactivePowerRemoteControl"; @@ -336,6 +338,7 @@ public static > List getEnumPossibleValues(Class en new Parameter(LOW_IMPEDANCE_BRANCH_MODE_PARAM_NAME, ParameterType.STRING, "Low impedance branch mode", LOW_IMPEDANCE_BRANCH_MODE_DEFAULT_VALUE.name(), getEnumPossibleValues(LowImpedanceBranchMode.class), ParameterScope.FUNCTIONAL, MODEL_CATEGORY_KEY), new Parameter(VOLTAGE_REMOTE_CONTROL_PARAM_NAME, ParameterType.BOOLEAN, "Generator voltage remote control", VOLTAGE_REMOTE_CONTROL_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, GENERATOR_VOLTAGE_CONTROL_CATEGORY_KEY), new Parameter(SLACK_DISTRIBUTION_FAILURE_BEHAVIOR_PARAM_NAME, ParameterType.STRING, "Behavior in case of slack distribution failure", SLACK_DISTRIBUTION_FAILURE_BEHAVIOR_DEFAULT_VALUE.name(), getEnumPossibleValues(SlackDistributionFailureBehavior.class), ParameterScope.FUNCTIONAL, SLACK_DISTRIBUTION_CATEGORY_KEY), + new Parameter(UNREALISTIC_VOLTAGE_CHECK_BEHAVIOR_PARAM_NAME, ParameterType.STRING, "Behavior in case of unrealistic voltage", NewtonRaphsonParameters.DEFAULT_UNREALISTIC_VOLTAGE_CHECK_BEHAVIOR.name(), getEnumPossibleValues(NewtonRaphsonParameters.UnrealisticVoltageCheckBehavior.class)), new Parameter(LOAD_POWER_FACTOR_CONSTANT_PARAM_NAME, ParameterType.BOOLEAN, "Load power factor is constant", LOAD_POWER_FACTOR_CONSTANT_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, SLACK_DISTRIBUTION_CATEGORY_KEY), new Parameter(PLAUSIBLE_ACTIVE_POWER_LIMIT_PARAM_NAME, ParameterType.DOUBLE, "Plausible active power limit", LfNetworkParameters.PLAUSIBLE_ACTIVE_POWER_LIMIT_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, SLACK_DISTRIBUTION_CATEGORY_KEY), new Parameter(SLACK_BUS_P_MAX_MISMATCH_PARAM_NAME, ParameterType.DOUBLE, "Slack bus max active power mismatch", SLACK_BUS_P_MAX_MISMATCH_DEFAULT_VALUE, ParameterScope.FUNCTIONAL, SLACK_DISTRIBUTION_CATEGORY_KEY), @@ -435,6 +438,8 @@ public enum ReportedFeatures { private SlackDistributionFailureBehavior slackDistributionFailureBehavior = SLACK_DISTRIBUTION_FAILURE_BEHAVIOR_DEFAULT_VALUE; + private NewtonRaphsonParameters.UnrealisticVoltageCheckBehavior unrealisticVoltageCheckBehavior = NewtonRaphsonParameters.DEFAULT_UNREALISTIC_VOLTAGE_CHECK_BEHAVIOR; + private boolean voltageRemoteControl = VOLTAGE_REMOTE_CONTROL_DEFAULT_VALUE; private LowImpedanceBranchMode lowImpedanceBranchMode = LOW_IMPEDANCE_BRANCH_MODE_DEFAULT_VALUE; @@ -627,6 +632,15 @@ public OpenLoadFlowParameters setSlackDistributionFailureBehavior(SlackDistribut return this; } + public NewtonRaphsonParameters.UnrealisticVoltageCheckBehavior getUnrealisticVoltageCheckBehavior() { + return unrealisticVoltageCheckBehavior; + } + + public OpenLoadFlowParameters setUnrealisticVoltageCheckBehavior(NewtonRaphsonParameters.UnrealisticVoltageCheckBehavior unrealisticVoltageCheckBehavior) { + this.unrealisticVoltageCheckBehavior = Objects.requireNonNull(unrealisticVoltageCheckBehavior); + return this; + } + public boolean isVoltageRemoteControl() { return voltageRemoteControl; } @@ -1285,6 +1299,7 @@ public static OpenLoadFlowParameters load(PlatformConfig platformConfig) { .setLowImpedanceBranchMode(config.getEnumProperty(LOW_IMPEDANCE_BRANCH_MODE_PARAM_NAME, LowImpedanceBranchMode.class, LOW_IMPEDANCE_BRANCH_MODE_DEFAULT_VALUE)) .setVoltageRemoteControl(config.getBooleanProperty(VOLTAGE_REMOTE_CONTROL_PARAM_NAME, VOLTAGE_REMOTE_CONTROL_DEFAULT_VALUE)) .setSlackDistributionFailureBehavior(config.getEnumProperty(SLACK_DISTRIBUTION_FAILURE_BEHAVIOR_PARAM_NAME, SlackDistributionFailureBehavior.class, SLACK_DISTRIBUTION_FAILURE_BEHAVIOR_DEFAULT_VALUE)) + .setUnrealisticVoltageCheckBehavior(config.getEnumProperty(UNREALISTIC_VOLTAGE_CHECK_BEHAVIOR_PARAM_NAME, NewtonRaphsonParameters.UnrealisticVoltageCheckBehavior.class, NewtonRaphsonParameters.DEFAULT_UNREALISTIC_VOLTAGE_CHECK_BEHAVIOR)) .setLoadPowerFactorConstant(config.getBooleanProperty(LOAD_POWER_FACTOR_CONSTANT_PARAM_NAME, LOAD_POWER_FACTOR_CONSTANT_DEFAULT_VALUE)) .setPlausibleActivePowerLimit(config.getDoubleProperty(PLAUSIBLE_ACTIVE_POWER_LIMIT_PARAM_NAME, LfNetworkParameters.PLAUSIBLE_ACTIVE_POWER_LIMIT_DEFAULT_VALUE)) .setNewtonRaphsonStoppingCriteriaType(config.getEnumProperty(NEWTONRAPHSON_STOPPING_CRITERIA_TYPE_PARAM_NAME, NewtonRaphsonStoppingCriteriaType.class, NEWTONRAPHSON_STOPPING_CRITERIA_TYPE_DEFAULT_VALUE)) @@ -1373,6 +1388,8 @@ public OpenLoadFlowParameters update(Map properties) { .ifPresent(prop -> this.setVoltageRemoteControl(Boolean.parseBoolean(prop))); Optional.ofNullable(properties.get(SLACK_DISTRIBUTION_FAILURE_BEHAVIOR_PARAM_NAME)) .ifPresent(prop -> this.setSlackDistributionFailureBehavior(SlackDistributionFailureBehavior.valueOf(prop))); + Optional.ofNullable(properties.get(UNREALISTIC_VOLTAGE_CHECK_BEHAVIOR_PARAM_NAME)) + .ifPresent(prop -> this.setUnrealisticVoltageCheckBehavior(NewtonRaphsonParameters.UnrealisticVoltageCheckBehavior.valueOf(prop))); Optional.ofNullable(properties.get(LOAD_POWER_FACTOR_CONSTANT_PARAM_NAME)) .ifPresent(prop -> this.setLoadPowerFactorConstant(Boolean.parseBoolean(prop))); Optional.ofNullable(properties.get(PLAUSIBLE_ACTIVE_POWER_LIMIT_PARAM_NAME)) @@ -1510,6 +1527,7 @@ public Map toMap() { 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); + map.put(UNREALISTIC_VOLTAGE_CHECK_BEHAVIOR_PARAM_NAME, unrealisticVoltageCheckBehavior); map.put(VOLTAGE_REMOTE_CONTROL_PARAM_NAME, voltageRemoteControl); map.put(LOW_IMPEDANCE_BRANCH_MODE_PARAM_NAME, lowImpedanceBranchMode); map.put(LOAD_POWER_FACTOR_CONSTANT_PARAM_NAME, loadPowerFactorConstant); @@ -1782,6 +1800,7 @@ public static AcLoadFlowParameters createAcParameters(LoadFlowParameters paramet var newtonRaphsonParameters = new NewtonRaphsonParameters() .setStoppingCriteria(createNewtonRaphsonStoppingCriteria(parametersExt)) .setMaxIterations(parametersExt.getMaxNewtonRaphsonIterations()) + .setUnrealisticVoltageCheckBehavior(parametersExt.getUnrealisticVoltageCheckBehavior()) .setMinRealisticVoltage(parametersExt.getMinRealisticVoltage()) .setMaxRealisticVoltage(parametersExt.getMaxRealisticVoltage()) .setStateVectorScalingMode(parametersExt.getStateVectorScalingMode()) @@ -1915,6 +1934,7 @@ public static boolean equals(LoadFlowParameters parameters1, LoadFlowParameters return extension1.getSlackBusSelectionMode() == extension2.getSlackBusSelectionMode() && extension1.getSlackBusesIds().equals(extension2.getSlackBusesIds()) && extension1.getSlackDistributionFailureBehavior() == extension2.getSlackDistributionFailureBehavior() && + extension1.getUnrealisticVoltageCheckBehavior() == extension2.getUnrealisticVoltageCheckBehavior() && extension1.isVoltageRemoteControl() == extension2.isVoltageRemoteControl() && extension1.getLowImpedanceBranchMode() == extension2.getLowImpedanceBranchMode() && extension1.isLoadPowerFactorConstant() == extension2.isLoadPowerFactorConstant() && @@ -2008,6 +2028,7 @@ public static LoadFlowParameters clone(LoadFlowParameters parameters) { .setSlackBusSelectionMode(extension.getSlackBusSelectionMode()) .setSlackBusesIds(new ArrayList<>(extension.getSlackBusesIds())) .setSlackDistributionFailureBehavior(extension.getSlackDistributionFailureBehavior()) + .setUnrealisticVoltageCheckBehavior(extension.getUnrealisticVoltageCheckBehavior()) .setVoltageRemoteControl(extension.isVoltageRemoteControl()) .setLowImpedanceBranchMode(extension.getLowImpedanceBranchMode()) .setLoadPowerFactorConstant(extension.isLoadPowerFactorConstant()) diff --git a/src/main/java/com/powsybl/openloadflow/ac/AcloadFlowEngine.java b/src/main/java/com/powsybl/openloadflow/ac/AcloadFlowEngine.java index 6331fb5f26..1d860596fa 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/AcloadFlowEngine.java +++ b/src/main/java/com/powsybl/openloadflow/ac/AcloadFlowEngine.java @@ -27,10 +27,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; /** * @author Geoffroy Jamgotchian {@literal } @@ -108,7 +105,7 @@ private void runOuterLoop(AcOuterLoop outerLoop, AcOuterLoopContext outerLoopCon outerLoopIteration.increment(); } } while (outerLoopResult.status() == OuterLoopStatus.UNSTABLE - && runningContext.lastSolverResult.getStatus() == AcSolverStatus.CONVERGED + && lastResultStatusAcceptable(runningContext, context.getParameters().getNewtonRaphsonParameters()) && runningContext.outerLoopTotalIterations < context.getParameters().getMaxOuterLoopIterations()); if (outerLoopResult.status() != OuterLoopStatus.STABLE) { @@ -116,6 +113,20 @@ private void runOuterLoop(AcOuterLoop outerLoop, AcOuterLoopContext outerLoopCon } } + private static boolean lastResultStatusAcceptable(RunningContext runningContext, NewtonRaphsonParameters nrParameters) { + switch (runningContext.lastSolverResult.getStatus()) { + case CONVERGED -> { + return true; + } + case UNREALISTIC_STATE -> { + return nrParameters.getUnrealisticVoltageCheckBehavior() == NewtonRaphsonParameters.UnrealisticVoltageCheckBehavior.FAIL_AT_UNREALISTIC_STATE_IN_FINAL_ITERATION_ONLY; + } + default -> { + return false; + } + } + } + @Override public AcLoadFlowResult run() { LOGGER.info("Start AC loadflow on network {}", context.getNetwork()); @@ -159,7 +170,7 @@ public AcLoadFlowResult run() { runningContext.nrTotalIterations.add(runningContext.lastSolverResult.getIterations()); // continue with outer loops only if solver succeed - if (runningContext.lastSolverResult.getStatus() == AcSolverStatus.CONVERGED) { + if (lastResultStatusAcceptable(runningContext, context.getParameters().getNewtonRaphsonParameters())) { // re-run all outer loops until solver failed or no more solver iterations are needed int oldNrTotalIterations; @@ -174,14 +185,14 @@ public AcLoadFlowResult run() { // - last solver run succeed, // - last OuterLoopStatus is not FAILED // - we have not reached max number of outer loop iteration - if (runningContext.lastSolverResult.getStatus() != AcSolverStatus.CONVERGED + if (!lastResultStatusAcceptable(runningContext, context.getParameters().getNewtonRaphsonParameters()) || runningContext.lastOuterLoopResult.status() == OuterLoopStatus.FAILED || runningContext.outerLoopTotalIterations >= context.getParameters().getMaxOuterLoopIterations()) { break; } } } while (runningContext.nrTotalIterations.getValue() > oldNrTotalIterations - && runningContext.lastSolverResult.getStatus() == AcSolverStatus.CONVERGED + && lastResultStatusAcceptable(runningContext, context.getParameters().getNewtonRaphsonParameters()) && runningContext.lastOuterLoopResult.status() != OuterLoopStatus.FAILED && runningContext.outerLoopTotalIterations < context.getParameters().getMaxOuterLoopIterations()); } diff --git a/src/main/java/com/powsybl/openloadflow/ac/UnrealisticVoltageCheck.java b/src/main/java/com/powsybl/openloadflow/ac/UnrealisticVoltageCheck.java new file mode 100644 index 0000000000..094eaf78b0 --- /dev/null +++ b/src/main/java/com/powsybl/openloadflow/ac/UnrealisticVoltageCheck.java @@ -0,0 +1,54 @@ +/** + * 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.ac; + +import com.powsybl.commons.report.ReportNode; +import com.powsybl.openloadflow.ac.equations.AcEquationType; +import com.powsybl.openloadflow.ac.equations.AcVariableType; +import com.powsybl.openloadflow.ac.solver.NewtonRaphsonParameters; +import com.powsybl.openloadflow.equations.*; +import com.powsybl.openloadflow.network.LfNetwork; +import com.powsybl.openloadflow.util.Reports; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * @author Sebastien Murgey {@literal } + */ +public final class UnrealisticVoltageCheck { + private static final Logger LOGGER = LoggerFactory.getLogger(UnrealisticVoltageCheck.class); + + private UnrealisticVoltageCheck() { + } + + public static boolean isStateUnrealistic(LfNetwork network, EquationSystem equationSystem, NewtonRaphsonParameters parameters, ReportNode reportNode) { + Map busesOutOfNormalVoltageRange = new LinkedHashMap<>(); + for (Variable v : equationSystem.getIndex().getSortedVariablesToFind()) { + if (v.getType() == AcVariableType.BUS_V && !network.getBus(v.getElementNum()).isFictitious()) { + double value = equationSystem.getStateVector().get(v.getRow()); + if (value < parameters.getMinRealisticVoltage() || value > parameters.getMaxRealisticVoltage()) { + busesOutOfNormalVoltageRange.put(network.getBus(v.getElementNum()).getId(), value); + } + } + } + if (!busesOutOfNormalVoltageRange.isEmpty()) { + if (LOGGER.isTraceEnabled()) { + for (var e : busesOutOfNormalVoltageRange.entrySet()) { + LOGGER.trace("Bus '{}' has an unrealistic voltage magnitude: {} pu", e.getKey(), e.getValue()); + } + } + LOGGER.error("{} buses have a voltage magnitude out of range [{}, {}]: {}", + busesOutOfNormalVoltageRange.size(), parameters.getMinRealisticVoltage(), parameters.getMaxRealisticVoltage(), busesOutOfNormalVoltageRange); + + Reports.reportNewtonRaphsonBusesOutOfRealisticVoltageRange(reportNode, busesOutOfNormalVoltageRange, parameters.getMinRealisticVoltage(), parameters.getMaxRealisticVoltage()); + } + return !busesOutOfNormalVoltageRange.isEmpty(); + } +} diff --git a/src/main/java/com/powsybl/openloadflow/ac/solver/NewtonRaphson.java b/src/main/java/com/powsybl/openloadflow/ac/solver/NewtonRaphson.java index a644d44a37..c860f5068d 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/solver/NewtonRaphson.java +++ b/src/main/java/com/powsybl/openloadflow/ac/solver/NewtonRaphson.java @@ -9,6 +9,7 @@ import com.powsybl.commons.report.ReportNode; import com.powsybl.math.matrix.MatrixException; +import com.powsybl.openloadflow.ac.UnrealisticVoltageCheck; import com.powsybl.openloadflow.ac.equations.AcEquationType; import com.powsybl.openloadflow.ac.equations.AcVariableType; import com.powsybl.openloadflow.equations.*; @@ -172,30 +173,6 @@ private AcSolverStatus runIteration(StateVectorScaling svScaling, MutableInt ite } } - private boolean isStateUnrealistic(ReportNode reportNode) { - Map busesOutOfNormalVoltageRange = new LinkedHashMap<>(); - for (Variable v : equationSystem.getIndex().getSortedVariablesToFind()) { - if (v.getType() == AcVariableType.BUS_V && !network.getBus(v.getElementNum()).isFictitious()) { - double value = equationSystem.getStateVector().get(v.getRow()); - if (value < parameters.getMinRealisticVoltage() || value > parameters.getMaxRealisticVoltage()) { - busesOutOfNormalVoltageRange.put(network.getBus(v.getElementNum()).getId(), value); - } - } - } - if (!busesOutOfNormalVoltageRange.isEmpty()) { - if (LOGGER.isTraceEnabled()) { - for (var e : busesOutOfNormalVoltageRange.entrySet()) { - LOGGER.trace("Bus '{}' has an unrealistic voltage magnitude: {} pu", e.getKey(), e.getValue()); - } - } - LOGGER.error("{} buses have a voltage magnitude out of range [{}, {}]: {}", - busesOutOfNormalVoltageRange.size(), parameters.getMinRealisticVoltage(), parameters.getMaxRealisticVoltage(), busesOutOfNormalVoltageRange); - - Reports.reportNewtonRaphsonBusesOutOfRealisticVoltageRange(reportNode, busesOutOfNormalVoltageRange, parameters.getMinRealisticVoltage(), parameters.getMaxRealisticVoltage()); - } - return !busesOutOfNormalVoltageRange.isEmpty(); - } - @Override public AcSolverResult run(VoltageInitializer voltageInitializer, ReportNode reportNode) { // initialize state vector @@ -236,7 +213,8 @@ public AcSolverResult run(VoltageInitializer voltageInitializer, ReportNode repo } // update network state variable - if (status == AcSolverStatus.CONVERGED && isStateUnrealistic(reportNode)) { + if (status == AcSolverStatus.CONVERGED && + UnrealisticVoltageCheck.isStateUnrealistic(network, equationSystem, parameters, reportNode)) { status = AcSolverStatus.UNREALISTIC_STATE; } diff --git a/src/main/java/com/powsybl/openloadflow/ac/solver/NewtonRaphsonParameters.java b/src/main/java/com/powsybl/openloadflow/ac/solver/NewtonRaphsonParameters.java index 4dfd598e8d..b80364054f 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/solver/NewtonRaphsonParameters.java +++ b/src/main/java/com/powsybl/openloadflow/ac/solver/NewtonRaphsonParameters.java @@ -14,6 +14,13 @@ */ public class NewtonRaphsonParameters extends AbstractNewtonParameters { + public enum UnrealisticVoltageCheckBehavior { + FAIL_AT_UNREALISTIC_STATE_IN_ANY_ITERATION, + FAIL_AT_UNREALISTIC_STATE_IN_FINAL_ITERATION_ONLY + } + + public static final UnrealisticVoltageCheckBehavior DEFAULT_UNREALISTIC_VOLTAGE_CHECK_BEHAVIOR = UnrealisticVoltageCheckBehavior.FAIL_AT_UNREALISTIC_STATE_IN_ANY_ITERATION; + public static final int DEFAULT_MAX_ITERATIONS = 15; public static final double DEFAULT_MIN_REALISTIC_VOLTAGE = 0.5; public static final double DEFAULT_MAX_REALISTIC_VOLTAGE = 2; @@ -24,6 +31,8 @@ public NewtonRaphsonParameters() { super(DEFAULT_MAX_ITERATIONS); } + private UnrealisticVoltageCheckBehavior unrealisticVoltageCheckBehavior; + private double minRealisticVoltage = DEFAULT_MIN_REALISTIC_VOLTAGE; private double maxRealisticVoltage = DEFAULT_MAX_REALISTIC_VOLTAGE; @@ -42,6 +51,15 @@ public NewtonRaphsonParameters() { private boolean alwaysUpdateNetwork = ALWAYS_UPDATE_NETWORK_DEFAULT_VALUE; + public UnrealisticVoltageCheckBehavior getUnrealisticVoltageCheckBehavior() { + return unrealisticVoltageCheckBehavior; + } + + public NewtonRaphsonParameters setUnrealisticVoltageCheckBehavior(UnrealisticVoltageCheckBehavior unrealisticVoltageCheckBehavior) { + this.unrealisticVoltageCheckBehavior = unrealisticVoltageCheckBehavior; + return this; + } + public double getMinRealisticVoltage() { return minRealisticVoltage; } @@ -128,6 +146,7 @@ public NewtonRaphsonParameters setMaxVoltageChangeStateVectorScalingMaxDphi(doub public String toString() { return "NewtonRaphsonParameters(" + "maxIterations=" + maxIterations + + ", unrealisticVoltageCheckBehavior=" + unrealisticVoltageCheckBehavior + ", minRealisticVoltage=" + minRealisticVoltage + ", maxRealisticVoltage=" + maxRealisticVoltage + ", stoppingCriteria=" + stoppingCriteria.getClass().getSimpleName() + diff --git a/src/test/java/com/powsybl/openloadflow/OpenLoadFlowParametersTest.java b/src/test/java/com/powsybl/openloadflow/OpenLoadFlowParametersTest.java index c79f42720d..97849de31c 100644 --- a/src/test/java/com/powsybl/openloadflow/OpenLoadFlowParametersTest.java +++ b/src/test/java/com/powsybl/openloadflow/OpenLoadFlowParametersTest.java @@ -384,7 +384,7 @@ void testCloneParameters() { @Test void testToString() { OpenLoadFlowParameters parameters = new OpenLoadFlowParameters(); - assertEquals("OpenLoadFlowParameters(slackBusSelectionMode=MOST_MESHED, slackBusesIds=[], slackDistributionFailureBehavior=LEAVE_ON_SLACK_BUS, voltageRemoteControl=true, lowImpedanceBranchMode=REPLACE_BY_ZERO_IMPEDANCE_LINE, loadPowerFactorConstant=false, plausibleActivePowerLimit=5000.0, newtonRaphsonStoppingCriteriaType=UNIFORM_CRITERIA, slackBusPMaxMismatch=1.0, maxActivePowerMismatch=0.01, maxReactivePowerMismatch=0.01, maxVoltageMismatch=1.0E-4, maxAngleMismatch=1.0E-5, maxRatioMismatch=1.0E-5, maxSusceptanceMismatch=1.0E-4, voltagePerReactivePowerControl=false, generatorReactivePowerRemoteControl=false, transformerReactivePowerControl=false, maxNewtonRaphsonIterations=15, maxOuterLoopIterations=20, newtonRaphsonConvEpsPerEq=1.0E-4, voltageInitModeOverride=NONE, transformerVoltageControlMode=WITH_GENERATOR_VOLTAGE_CONTROL, shuntVoltageControlMode=WITH_GENERATOR_VOLTAGE_CONTROL, minPlausibleTargetVoltage=0.8, maxPlausibleTargetVoltage=1.2, minRealisticVoltage=0.5, maxRealisticVoltage=2.0, reactiveRangeCheckMode=MAX, lowImpedanceThreshold=1.0E-8, networkCacheEnabled=false, svcVoltageMonitoring=true, stateVectorScalingMode=NONE, maxSlackBusCount=1, debugDir=null, incrementalTransformerRatioTapControlOuterLoopMaxTapShift=3, secondaryVoltageControl=false, reactiveLimitsMaxPqPvSwitch=3, phaseShifterControlMode=CONTINUOUS_WITH_DISCRETISATION, alwaysUpdateNetwork=false, mostMeshedSlackBusSelectorMaxNominalVoltagePercentile=95.0, reportedFeatures=[], slackBusCountryFilter=[], actionableSwitchesIds=[], actionableTransformersIds=[], asymmetrical=false, minNominalVoltageTargetVoltageCheck=20.0, reactivePowerDispatchMode=Q_EQUAL_PROPORTION, outerLoopNames=null, useActiveLimits=true, disableVoltageControlOfGeneratorsOutsideActivePowerLimits=false, lineSearchStateVectorScalingMaxIteration=10, lineSearchStateVectorScalingStepFold=1.3333333333333333, maxVoltageChangeStateVectorScalingMaxDv=0.1, maxVoltageChangeStateVectorScalingMaxDphi=0.17453292519943295, linePerUnitMode=IMPEDANCE, useLoadModel=false, dcApproximationType=IGNORE_R, simulateAutomationSystems=false, acSolverType=NEWTON_RAPHSON, maxNewtonKrylovIterations=100, newtonKrylovLineSearch=false, referenceBusSelectionMode=FIRST_SLACK, writeReferenceTerminals=true, voltageTargetPriorities=[GENERATOR, TRANSFORMER, SHUNT], transformerVoltageControlUseInitialTapPosition=false, generatorVoltageControlMinNominalVoltage=-1.0, fictitiousGeneratorVoltageControlCheckMode=FORCED)", + assertEquals("OpenLoadFlowParameters(slackBusSelectionMode=MOST_MESHED, slackBusesIds=[], slackDistributionFailureBehavior=LEAVE_ON_SLACK_BUS, unrealisticVoltageCheckBehavior=FAIL_AT_UNREALISTIC_STATE_IN_ANY_ITERATION, voltageRemoteControl=true, lowImpedanceBranchMode=REPLACE_BY_ZERO_IMPEDANCE_LINE, loadPowerFactorConstant=false, plausibleActivePowerLimit=5000.0, newtonRaphsonStoppingCriteriaType=UNIFORM_CRITERIA, slackBusPMaxMismatch=1.0, maxActivePowerMismatch=0.01, maxReactivePowerMismatch=0.01, maxVoltageMismatch=1.0E-4, maxAngleMismatch=1.0E-5, maxRatioMismatch=1.0E-5, maxSusceptanceMismatch=1.0E-4, voltagePerReactivePowerControl=false, generatorReactivePowerRemoteControl=false, transformerReactivePowerControl=false, maxNewtonRaphsonIterations=15, maxOuterLoopIterations=20, newtonRaphsonConvEpsPerEq=1.0E-4, voltageInitModeOverride=NONE, transformerVoltageControlMode=WITH_GENERATOR_VOLTAGE_CONTROL, shuntVoltageControlMode=WITH_GENERATOR_VOLTAGE_CONTROL, minPlausibleTargetVoltage=0.8, maxPlausibleTargetVoltage=1.2, minRealisticVoltage=0.5, maxRealisticVoltage=2.0, reactiveRangeCheckMode=MAX, lowImpedanceThreshold=1.0E-8, networkCacheEnabled=false, svcVoltageMonitoring=true, stateVectorScalingMode=NONE, maxSlackBusCount=1, debugDir=null, incrementalTransformerRatioTapControlOuterLoopMaxTapShift=3, secondaryVoltageControl=false, reactiveLimitsMaxPqPvSwitch=3, phaseShifterControlMode=CONTINUOUS_WITH_DISCRETISATION, alwaysUpdateNetwork=false, mostMeshedSlackBusSelectorMaxNominalVoltagePercentile=95.0, reportedFeatures=[], slackBusCountryFilter=[], actionableSwitchesIds=[], actionableTransformersIds=[], asymmetrical=false, minNominalVoltageTargetVoltageCheck=20.0, reactivePowerDispatchMode=Q_EQUAL_PROPORTION, outerLoopNames=null, useActiveLimits=true, disableVoltageControlOfGeneratorsOutsideActivePowerLimits=false, lineSearchStateVectorScalingMaxIteration=10, lineSearchStateVectorScalingStepFold=1.3333333333333333, maxVoltageChangeStateVectorScalingMaxDv=0.1, maxVoltageChangeStateVectorScalingMaxDphi=0.17453292519943295, linePerUnitMode=IMPEDANCE, useLoadModel=false, dcApproximationType=IGNORE_R, simulateAutomationSystems=false, acSolverType=NEWTON_RAPHSON, maxNewtonKrylovIterations=100, newtonKrylovLineSearch=false, referenceBusSelectionMode=FIRST_SLACK, writeReferenceTerminals=true, voltageTargetPriorities=[GENERATOR, TRANSFORMER, SHUNT], transformerVoltageControlUseInitialTapPosition=false, generatorVoltageControlMinNominalVoltage=-1.0, fictitiousGeneratorVoltageControlCheckMode=FORCED)", parameters.toString()); } diff --git a/src/test/java/com/powsybl/openloadflow/OpenLoadFlowProviderTest.java b/src/test/java/com/powsybl/openloadflow/OpenLoadFlowProviderTest.java index b5eb3cc21d..84fa70df37 100644 --- a/src/test/java/com/powsybl/openloadflow/OpenLoadFlowProviderTest.java +++ b/src/test/java/com/powsybl/openloadflow/OpenLoadFlowProviderTest.java @@ -59,7 +59,7 @@ void testDcParameters() { void testAcParameters() { Network network = Mockito.mock(Network.class); AcLoadFlowParameters acParameters = OpenLoadFlowParameters.createAcParameters(network, new LoadFlowParameters().setReadSlackBus(true), new OpenLoadFlowParameters(), new DenseMatrixFactory(), new EvenShiloachGraphDecrementalConnectivityFactory<>(), false, false); - assertEquals("AcLoadFlowParameters(networkParameters=LfNetworkParameters(slackBusSelector=NetworkSlackBusSelector, connectivityFactory=EvenShiloachGraphDecrementalConnectivityFactory, generatorVoltageRemoteControl=true, minImpedance=false, twtSplitShuntAdmittance=false, breakers=false, plausibleActivePowerLimit=5000.0, computeMainConnectedComponentOnly=true, countriesToBalance=[], distributedOnConformLoad=false, phaseControl=false, transformerVoltageControl=false, voltagePerReactivePowerControl=false, generatorReactivePowerRemoteControl=false, transformerReactivePowerControl=false, loadFlowModel=AC, reactiveLimits=true, hvdcAcEmulation=true, minPlausibleTargetVoltage=0.8, maxPlausibleTargetVoltage=1.2, loaderPostProcessorSelection=[], reactiveRangeCheckMode=MAX, lowImpedanceThreshold=1.0E-8, svcVoltageMonitoring=true, maxSlackBusCount=1, debugDir=null, secondaryVoltageControl=false, cacheEnabled=false, asymmetrical=false, minNominalVoltageTargetVoltageCheck=20.0, linePerUnitMode=IMPEDANCE, useLoadModel=false, simulateAutomationSystems=false, referenceBusSelector=ReferenceBusFirstSlackSelector, voltageTargetPriorities=[GENERATOR, TRANSFORMER, SHUNT], fictitiousGeneratorVoltageControlCheckMode=FORCED), equationSystemCreationParameters=AcEquationSystemCreationParameters(forceA1Var=false), newtonRaphsonParameters=NewtonRaphsonParameters(maxIterations=15, minRealisticVoltage=0.5, maxRealisticVoltage=2.0, stoppingCriteria=DefaultNewtonRaphsonStoppingCriteria, stateVectorScalingMode=NONE, alwaysUpdateNetwork=false, lineSearchStateVectorScalingMaxIteration=10, lineSearchStateVectorScalingStepFold=1.3333333333333333, maxVoltageChangeStateVectorScalingMaxDv=0.1, maxVoltageChangeStateVectorScalingMaxDphi=0.17453292519943295), newtonKrylovParameters=NewtonKrylovParameters(maxIterations=100, lineSearch=false), outerLoops=[DistributedSlackOuterLoop, MonitoringVoltageOuterLoop, ReactiveLimitsOuterLoop], maxOuterLoopIterations=20, matrixFactory=DenseMatrixFactory, voltageInitializer=UniformValueVoltageInitializer, asymmetrical=false, slackDistributionFailureBehavior=LEAVE_ON_SLACK_BUS, solverFactory=NewtonRaphsonFactory, detailedReport=false)", + assertEquals("AcLoadFlowParameters(networkParameters=LfNetworkParameters(slackBusSelector=NetworkSlackBusSelector, connectivityFactory=EvenShiloachGraphDecrementalConnectivityFactory, generatorVoltageRemoteControl=true, minImpedance=false, twtSplitShuntAdmittance=false, breakers=false, plausibleActivePowerLimit=5000.0, computeMainConnectedComponentOnly=true, countriesToBalance=[], distributedOnConformLoad=false, phaseControl=false, transformerVoltageControl=false, voltagePerReactivePowerControl=false, generatorReactivePowerRemoteControl=false, transformerReactivePowerControl=false, loadFlowModel=AC, reactiveLimits=true, hvdcAcEmulation=true, minPlausibleTargetVoltage=0.8, maxPlausibleTargetVoltage=1.2, loaderPostProcessorSelection=[], reactiveRangeCheckMode=MAX, lowImpedanceThreshold=1.0E-8, svcVoltageMonitoring=true, maxSlackBusCount=1, debugDir=null, secondaryVoltageControl=false, cacheEnabled=false, asymmetrical=false, minNominalVoltageTargetVoltageCheck=20.0, linePerUnitMode=IMPEDANCE, useLoadModel=false, simulateAutomationSystems=false, referenceBusSelector=ReferenceBusFirstSlackSelector, voltageTargetPriorities=[GENERATOR, TRANSFORMER, SHUNT], fictitiousGeneratorVoltageControlCheckMode=FORCED), equationSystemCreationParameters=AcEquationSystemCreationParameters(forceA1Var=false), newtonRaphsonParameters=NewtonRaphsonParameters(maxIterations=15, unrealisticVoltageCheckBehavior=FAIL_AT_UNREALISTIC_STATE_IN_ANY_ITERATION, minRealisticVoltage=0.5, maxRealisticVoltage=2.0, stoppingCriteria=DefaultNewtonRaphsonStoppingCriteria, stateVectorScalingMode=NONE, alwaysUpdateNetwork=false, lineSearchStateVectorScalingMaxIteration=10, lineSearchStateVectorScalingStepFold=1.3333333333333333, maxVoltageChangeStateVectorScalingMaxDv=0.1, maxVoltageChangeStateVectorScalingMaxDphi=0.17453292519943295), newtonKrylovParameters=NewtonKrylovParameters(maxIterations=100, lineSearch=false), outerLoops=[DistributedSlackOuterLoop, MonitoringVoltageOuterLoop, ReactiveLimitsOuterLoop], maxOuterLoopIterations=20, matrixFactory=DenseMatrixFactory, voltageInitializer=UniformValueVoltageInitializer, asymmetrical=false, slackDistributionFailureBehavior=LEAVE_ON_SLACK_BUS, solverFactory=NewtonRaphsonFactory, detailedReport=false)", acParameters.toString()); } @@ -87,7 +87,7 @@ void testGetExtendedVoltageInitializer() { @Test void specificParametersTest() { OpenLoadFlowProvider provider = new OpenLoadFlowProvider(); - assertEquals(68, provider.getSpecificParameters().size()); + assertEquals(69, provider.getSpecificParameters().size()); LoadFlowParameters parameters = new LoadFlowParameters(); provider.loadSpecificParameters(Collections.emptyMap()) @@ -110,7 +110,7 @@ void testCreateMapFromSpecificParameters() { OpenLoadFlowParameters parametersExt = new OpenLoadFlowParameters(); OpenLoadFlowProvider provider = new OpenLoadFlowProvider(); Map map = provider.createMapFromSpecificParameters(parametersExt); - assertEquals(68, map.size()); + assertEquals(69, map.size()); assertEquals(provider.getSpecificParameters().size(), map.size()); } diff --git a/src/test/resources/debug-parameters.json b/src/test/resources/debug-parameters.json index 3dbd07f73c..54c8ce42bb 100644 --- a/src/test/resources/debug-parameters.json +++ b/src/test/resources/debug-parameters.json @@ -23,6 +23,7 @@ "slackBusSelectionMode" : "NAME", "slackBusesIds" : [ "b1_vl_0" ], "slackDistributionFailureBehavior" : "LEAVE_ON_SLACK_BUS", + "unrealisticVoltageCheckBehavior" : "FAIL_AT_UNREALISTIC_STATE_IN_ANY_ITERATION", "voltageRemoteControl" : true, "lowImpedanceBranchMode" : "REPLACE_BY_ZERO_IMPEDANCE_LINE", "loadPowerFactorConstant" : false,