From 5e2415339d4446aa08b48d4f2f60ae71d837621f Mon Sep 17 00:00:00 2001 From: Franck LECUYER Date: Fri, 26 Apr 2024 11:14:12 +0200 Subject: [PATCH 1/3] Add synthetic and detailed logs for missing voltage levels limits. Add synthetic and detailed logs for inconsistent voltage levels limits (limit < 0 and low limit > high limit) Signed-off-by: Franck LECUYER --- .../com/powsybl/openreac/OpenReacRunner.java | 4 +- .../java/com/powsybl/openreac/Reports.java | 8 ++ .../parameters/input/OpenReacParameters.java | 129 +++++++++++++++--- .../openreac/OpenReacParametersTest.java | 30 +++- .../VoltageLevelLimitsOverrideInputTest.java | 1 + 5 files changed, 150 insertions(+), 22 deletions(-) diff --git a/open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java b/open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java index 80e6690d..860b92c0 100644 --- a/open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java +++ b/open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java @@ -71,7 +71,7 @@ public static OpenReacResult run(Network network, String variantId, OpenReacPara * @return All information about the run and possible modifications to apply. */ public static OpenReacResult run(Network network, String variantId, OpenReacParameters parameters, OpenReacConfig config, ComputationManager manager, ReportNode reportNode, AmplExportConfig amplExportConfig) { - checkParameters(network, variantId, parameters, config, manager, reportNode); + checkParameters(network, variantId, parameters, config, manager, Reports.createParametersIntegrityReporter(reportNode, network.getId())); AmplModel reactiveOpf = OpenReacModel.buildModel(); OpenReacAmplIOFiles amplIoInterface = new OpenReacAmplIOFiles(parameters, amplExportConfig, network, config.isDebug(), Reports.createOpenReacReporter(reportNode, network.getId(), parameters.getObjective())); AmplResults run = AmplModelRunner.run(network, variantId, reactiveOpf, manager, amplIoInterface); @@ -118,6 +118,6 @@ private static void checkParameters(Network network, String variantId, OpenReacP Objects.requireNonNull(config); Objects.requireNonNull(manager); Objects.requireNonNull(reportNode); - parameters.checkIntegrity(network); + parameters.checkIntegrity(network, reportNode); } } diff --git a/open-reac/src/main/java/com/powsybl/openreac/Reports.java b/open-reac/src/main/java/com/powsybl/openreac/Reports.java index 070d36da..7e3494f4 100644 --- a/open-reac/src/main/java/com/powsybl/openreac/Reports.java +++ b/open-reac/src/main/java/com/powsybl/openreac/Reports.java @@ -50,4 +50,12 @@ public static void reportVariableShuntCompensatorsSize(ReportNode reportNode, in .withUntypedValue("size", variableShuntCompensatorsSize) .add(); } + + public static ReportNode createParametersIntegrityReporter(ReportNode reportNode, String networkId) { + return reportNode.newReportNode() + .withMessageTemplate("openReacParametersIntegrity", "Open reac parameters integrity on network '${networkId}'") + .withUntypedValue("networkId", networkId) + .add(); + } + } diff --git a/open-reac/src/main/java/com/powsybl/openreac/parameters/input/OpenReacParameters.java b/open-reac/src/main/java/com/powsybl/openreac/parameters/input/OpenReacParameters.java index 6ee5a51b..2ba86ddc 100644 --- a/open-reac/src/main/java/com/powsybl/openreac/parameters/input/OpenReacParameters.java +++ b/open-reac/src/main/java/com/powsybl/openreac/parameters/input/OpenReacParameters.java @@ -6,15 +6,17 @@ */ package com.powsybl.openreac.parameters.input; +import com.powsybl.commons.report.ReportNode; +import com.powsybl.commons.report.TypedValue; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.VoltageLevel; import com.powsybl.openreac.exceptions.InvalidParametersException; import com.powsybl.openreac.parameters.input.algo.*; +import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; -import java.util.stream.Collectors; /** * This class stores all inputs parameters specific to the OpenReac optimizer. @@ -536,10 +538,14 @@ public List getAllAlgorithmParams() { /** * Do some checks on the parameters given, such as provided IDs must correspond to the given network element * - * @param network Network on which ID are going to be infered + * @param network Network on which ID are going to be infered + * @param reportNode aggregates functional logging * @throws InvalidParametersException if the parameters contain some incoherences. */ - public void checkIntegrity(Network network) throws InvalidParametersException { + public void checkIntegrity(Network network, ReportNode reportNode) throws InvalidParametersException { + Map> voltageLevelsWithMissingLimits = new TreeMap<>(); + Map> voltageLevelsWithInconsistentLimits = new TreeMap<>(); + for (String shuntId : getVariableShuntCompensators()) { if (network.getShuntCompensator(shuntId) == null) { throw new InvalidParametersException("Shunt " + shuntId + " not found in the network."); @@ -562,16 +568,53 @@ public void checkIntegrity(Network network) throws InvalidParametersException { } // Check integrity of voltage overrides - boolean integrityVoltageLimitOverrides = checkVoltageLimitOverrides(network); - if (!integrityVoltageLimitOverrides) { - throw new InvalidParametersException("At least one voltage limit override is inconsistent."); - } + boolean integrityVoltageLimitOverrides = checkVoltageLimitOverrides(network, voltageLevelsWithInconsistentLimits); // Check integrity of low/high voltage limits, taking into account voltage limit overrides - boolean integrityVoltageLevelLimits = checkLowVoltageLevelLimits(network); - integrityVoltageLevelLimits &= checkHighVoltageLevelLimits(network); - if (!integrityVoltageLevelLimits) { - throw new InvalidParametersException("At least one voltage level has an undefined or incorrect voltage limit."); + boolean integrityVoltageLevelLimits = checkLowVoltageLevelLimits(network, voltageLevelsWithMissingLimits); + integrityVoltageLevelLimits &= checkHighVoltageLevelLimits(network, voltageLevelsWithMissingLimits); + + if (!integrityVoltageLevelLimits || !integrityVoltageLimitOverrides) { + if (!voltageLevelsWithMissingLimits.isEmpty()) { + reportNode.newReportNode() + .withMessageTemplate("nbVoltageLevelsWithMissingLimits", "${size} voltage level(s) have undefined low and/or high voltage limits") + .withSeverity(TypedValue.INFO_SEVERITY) + .withUntypedValue("size", voltageLevelsWithMissingLimits.size()) + .add(); + voltageLevelsWithMissingLimits.forEach((key, value) -> { + String messageSuffix = "has undefined low and high voltage limits"; + if (value.getLeft() == 0) { + messageSuffix = "has undefined high voltage limit"; + } else if (value.getRight() == 0) { + messageSuffix = "has undefined low voltage limit"; + } + reportNode.newReportNode() + .withMessageTemplate("voltageLevelWithMissingLimits", "${vlId} " + messageSuffix) + .withSeverity(TypedValue.TRACE_SEVERITY) + .withUntypedValue("vlId", key) + .add(); + }); + } + if (!voltageLevelsWithInconsistentLimits.isEmpty()) { + reportNode.newReportNode() + .withMessageTemplate("nbVoltageLevelsWithInconsistentLimits", "${size} voltage level(s) have inconsistent low and/or high voltage limits") + .withSeverity(TypedValue.INFO_SEVERITY) + .withUntypedValue("size", voltageLevelsWithInconsistentLimits.size()) + .add(); + voltageLevelsWithInconsistentLimits.forEach((key, value) -> reportNode.newReportNode() + .withMessageTemplate("voltageLevelWithInconsistentLimits", "${vlId} has one or two inconsistent voltage limits (low voltage limit = ${low}, high voltage limit = ${high})") + .withSeverity(TypedValue.TRACE_SEVERITY) + .withUntypedValue("vlId", key) + .withUntypedValue("low", value.getLeft()) + .withUntypedValue("high", value.getRight()) + .add()); + } + + if (!integrityVoltageLevelLimits) { + throw new InvalidParametersException("At least one voltage level has an undefined or incorrect voltage limit."); + } else { + throw new InvalidParametersException("At least one voltage limit override is inconsistent."); + } } boolean integrityAlgorithmParameters = checkAlgorithmParametersIntegrity(); @@ -580,6 +623,16 @@ public void checkIntegrity(Network network) throws InvalidParametersException { } } + /** + * Do some checks on the parameters given, such as provided IDs must correspond to the given network element + * + * @param network Network on which ID are going to be infered + * @throws InvalidParametersException if the parameters contain some incoherences. + */ + public void checkIntegrity(Network network) throws InvalidParametersException { + checkIntegrity(network, ReportNode.NO_OP); + } + /** * @return true if the algorithm parameters are consistent, false otherwise. */ @@ -628,7 +681,7 @@ public boolean checkAlgorithmParametersIntegrity() { * @return true if the low voltage level limits are correct taking into account low voltage limit overrides, * false otherwise. */ - boolean checkLowVoltageLevelLimits(Network network) { + boolean checkLowVoltageLevelLimits(Network network, Map> voltageLevelsWithMissingLimits) { boolean integrityVoltageLevelLimits = true; for (VoltageLevel vl : network.getVoltageLevels()) { @@ -637,9 +690,11 @@ boolean checkLowVoltageLevelLimits(Network network) { if (Double.isNaN(lowLimit)) { List overrides = getSpecificVoltageLimits(vl.getId(), VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT); if (overrides.size() != 1) { + voltageLevelsWithMissingLimits.merge(vl.getId(), Pair.of(1, 0), (old, value) -> Pair.of(old.getLeft() + 1, old.getRight())); LOGGER.warn("Voltage level {} has no low voltage limit defined. Please add one or use a voltage limit override.", vl.getId()); integrityVoltageLevelLimits = false; } else if (overrides.get(0).isRelative()) { // we have one and just one + voltageLevelsWithMissingLimits.merge(vl.getId(), Pair.of(1, 0), (old, value) -> Pair.of(old.getLeft() + 1, old.getRight())); LOGGER.warn("Relative voltage override impossible on undefined low voltage limit for voltage level {}.", vl.getId()); integrityVoltageLevelLimits = false; } @@ -655,7 +710,7 @@ boolean checkLowVoltageLevelLimits(Network network) { * @return true if the high voltage level limits are correct taking into account high voltage limit overrides, * false otherwise. */ - boolean checkHighVoltageLevelLimits(Network network) { + boolean checkHighVoltageLevelLimits(Network network, Map> voltageLevelsWithMissingLimits) { boolean integrityVoltageLevelLimits = true; for (VoltageLevel vl : network.getVoltageLevels()) { @@ -664,9 +719,11 @@ boolean checkHighVoltageLevelLimits(Network network) { if (Double.isNaN(highLimit)) { List overrides = getSpecificVoltageLimits(vl.getId(), VoltageLimitOverride.VoltageLimitType.HIGH_VOLTAGE_LIMIT); if (overrides.size() != 1) { + voltageLevelsWithMissingLimits.merge(vl.getId(), Pair.of(0, 1), (old, value) -> Pair.of(old.getLeft(), old.getRight() + 1)); LOGGER.warn("Voltage level {} has no high voltage limit defined. Please add one or use a voltage limit override.", vl.getId()); integrityVoltageLevelLimits = false; } else if (overrides.get(0).isRelative()) { + voltageLevelsWithMissingLimits.merge(vl.getId(), Pair.of(0, 1), (old, value) -> Pair.of(old.getLeft(), old.getRight() + 1)); LOGGER.warn("Relative voltage override impossible on undefined high voltage limit for voltage level {}.", vl.getId()); integrityVoltageLevelLimits = false; } @@ -681,8 +738,11 @@ boolean checkHighVoltageLevelLimits(Network network) { * @param network the network on which are applied voltage limit overrides. * @return true if the integrity of voltage limit overrides is verified, false otherwise. */ - boolean checkVoltageLimitOverrides(Network network) { + boolean checkVoltageLimitOverrides(Network network, + Map> voltageLevelsWithInconsistentLimits) { // Check integrity of voltage overrides + Map> voltageLevelsLimitsAfterOverride = new HashMap<>(); + boolean integrityVoltageLimitOverrides = true; for (VoltageLimitOverride voltageLimitOverride : getSpecificVoltageLimits()) { String voltageLevelId = voltageLimitOverride.getVoltageLevelId(); @@ -697,25 +757,56 @@ boolean checkVoltageLimitOverrides(Network network) { if (voltageLimitOverride.isRelative()) { double value = voltageLimitOverride.getVoltageLimitType() == VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT ? - voltageLevel.getLowVoltageLimit() : voltageLevel.getHighVoltageLimit(); + voltageLevel.getLowVoltageLimit() : voltageLevel.getHighVoltageLimit(); if (Double.isNaN(value)) { LOGGER.warn("Voltage level {} has undefined {}, relative voltage limit override is impossible.", - voltageLevelId, voltageLimitOverride.getVoltageLimitType()); + voltageLevelId, voltageLimitOverride.getVoltageLimitType()); integrityVoltageLimitOverrides = false; + continue; } // verify voltage limit override does not lead to negative limit value - if (value + voltageLimitOverride.getLimit() < 0) { + double valueAfter = value + voltageLimitOverride.getLimit(); + if (voltageLimitOverride.getVoltageLimitType() == VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT) { + voltageLevelsLimitsAfterOverride.merge(voltageLevelId, Pair.of(valueAfter, voltageLevel.getHighVoltageLimit()), (old, newValue) -> Pair.of(valueAfter, old.getRight())); + if (valueAfter < 0) { + voltageLevelsWithInconsistentLimits.merge(voltageLevelId, Pair.of(valueAfter, voltageLevel.getHighVoltageLimit()), (old, newValue) -> Pair.of(valueAfter, old.getRight())); + } + } else { + voltageLevelsLimitsAfterOverride.merge(voltageLevelId, Pair.of(voltageLevel.getLowVoltageLimit(), valueAfter), (old, newValue) -> Pair.of(old.getLeft(), valueAfter)); + if (valueAfter < 0) { + voltageLevelsWithInconsistentLimits.merge(voltageLevelId, Pair.of(voltageLevel.getLowVoltageLimit(), valueAfter), (old, newValue) -> Pair.of(old.getLeft(), valueAfter)); + } + } + if (valueAfter < 0) { LOGGER.warn("Voltage level {} relative override leads to a negative {}.", - voltageLevelId, voltageLimitOverride.getVoltageLimitType()); + voltageLevelId, voltageLimitOverride.getVoltageLimitType()); integrityVoltageLimitOverrides = false; } + } else { + if (voltageLimitOverride.getVoltageLimitType() == VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT) { + voltageLevelsLimitsAfterOverride.merge(voltageLevelId, Pair.of(voltageLimitOverride.getLimit(), voltageLevel.getHighVoltageLimit()), (old, newValue) -> Pair.of(voltageLimitOverride.getLimit(), old.getRight())); + } else { + voltageLevelsLimitsAfterOverride.merge(voltageLevelId, Pair.of(voltageLevel.getLowVoltageLimit(), voltageLimitOverride.getLimit()), (old, newValue) -> Pair.of(old.getLeft(), voltageLimitOverride.getLimit())); + } } } + + // check low limit is lower than high limit after overrides + if (integrityVoltageLimitOverrides) { + for (Map.Entry> entry : voltageLevelsLimitsAfterOverride.entrySet()) { + String vlId = entry.getKey(); + if (entry.getValue().getLeft() > entry.getValue().getRight()) { + voltageLevelsWithInconsistentLimits.merge(vlId, Pair.of(entry.getValue().getLeft(), entry.getValue().getRight()), (old, newValue) -> Pair.of(entry.getValue().getLeft(), entry.getValue().getRight())); + integrityVoltageLimitOverrides = false; + } + } + } + return integrityVoltageLimitOverrides; } private List getSpecificVoltageLimits(String voltageLevelId, VoltageLimitOverride.VoltageLimitType type) { return specificVoltageLimits.stream() - .filter(limit -> limit.getVoltageLevelId().equals(voltageLevelId) && limit.getVoltageLimitType() == type).collect(Collectors.toList()); + .filter(limit -> limit.getVoltageLevelId().equals(voltageLevelId) && limit.getVoltageLimitType() == type).toList(); } } diff --git a/open-reac/src/test/java/com/powsybl/openreac/OpenReacParametersTest.java b/open-reac/src/test/java/com/powsybl/openreac/OpenReacParametersTest.java index 509e9b56..4b4f3665 100644 --- a/open-reac/src/test/java/com/powsybl/openreac/OpenReacParametersTest.java +++ b/open-reac/src/test/java/com/powsybl/openreac/OpenReacParametersTest.java @@ -10,6 +10,7 @@ import com.powsybl.iidm.network.*; import com.powsybl.openreac.exceptions.InvalidParametersException; import com.powsybl.openreac.parameters.input.OpenReacParameters; +import com.powsybl.openreac.parameters.input.VoltageLimitOverride; import com.powsybl.openreac.parameters.input.algo.OpenReacAlgoParam; import com.powsybl.openreac.parameters.input.algo.OpenReacAmplLogLevel; import com.powsybl.openreac.parameters.input.algo.OpenReacOptimisationObjective; @@ -26,7 +27,7 @@ * @author Nicolas PIERRE {@literal } * @author Pierre ARVY {@literal } */ -public class OpenReacParametersTest { +class OpenReacParametersTest { @Test void testObjectiveIntegrity() { @@ -412,6 +413,33 @@ void testListsOfParametersIntegrity() { testBusesWithReactiveSlacksParametersIntegrity(network, wrongId); } + @Test + void testMissingVoltageLevelsLimitsIntegrity() { + Network network = IeeeCdfNetworkFactory.create57(); + OpenReacParameters parameters = new OpenReacParameters(); + InvalidParametersException e = assertThrows(InvalidParametersException.class, () -> parameters.checkIntegrity(network)); + assertEquals("At least one voltage level has an undefined or incorrect voltage limit.", e.getMessage()); + } + + @Test + void testInconsistentVoltageLevelsLimitsIntegrity() { + Network network = IeeeCdfNetworkFactory.create57(); + setDefaultVoltageLimits(network); // set default voltage limits to every voltage levels of the network + VoltageLevel vl = network.getVoltageLevels().iterator().next(); + OpenReacParameters parameters = new OpenReacParameters(); + + // if low relative voltage override leads to low limit < 0, throws exception + parameters.addSpecificVoltageLimits(List.of(new VoltageLimitOverride(vl.getId(), VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT, true, -2.))); + InvalidParametersException e = assertThrows(InvalidParametersException.class, () -> parameters.checkIntegrity(network)); + assertEquals("At least one voltage limit override is inconsistent.", e.getMessage()); + + // if high relative voltage override leads to high limit lower than low limit, throws exception + parameters.getSpecificVoltageLimits().clear(); + parameters.addSpecificVoltageLimits(List.of(new VoltageLimitOverride(vl.getId(), VoltageLimitOverride.VoltageLimitType.HIGH_VOLTAGE_LIMIT, true, -0.5))); + InvalidParametersException e1 = assertThrows(InvalidParametersException.class, () -> parameters.checkIntegrity(network)); + assertEquals("At least one voltage limit override is inconsistent.", e1.getMessage()); + } + void testTwoWindingsTransformersParametersIntegrity(Network network, String wrongId) { OpenReacParameters parameters = new OpenReacParameters(); parameters.addVariableTwoWindingsTransformers(network.getTwoWindingsTransformerStream().map(TwoWindingsTransformer::getId).collect(Collectors.toList())); diff --git a/open-reac/src/test/java/com/powsybl/openreac/parameters/input/VoltageLevelLimitsOverrideInputTest.java b/open-reac/src/test/java/com/powsybl/openreac/parameters/input/VoltageLevelLimitsOverrideInputTest.java index aa085101..0d55b3d7 100644 --- a/open-reac/src/test/java/com/powsybl/openreac/parameters/input/VoltageLevelLimitsOverrideInputTest.java +++ b/open-reac/src/test/java/com/powsybl/openreac/parameters/input/VoltageLevelLimitsOverrideInputTest.java @@ -157,6 +157,7 @@ void testVoltageOverrideWithNegativeVoltageLimit() { params2.getSpecificVoltageLimits().clear(); voltageLimitsOverride2.clear(); + vl.setLowVoltageLimit(0.); voltageLimitsOverride2.add(new VoltageLimitOverride(vl.getId(), VoltageLimitOverride.VoltageLimitType.HIGH_VOLTAGE_LIMIT, true, -480)); params2.addSpecificVoltageLimits(voltageLimitsOverride2); assertDoesNotThrow(() -> params2.checkIntegrity(network)); // zero value From 3017ac5142e3660e06693cb6222dd059362b4bb3 Mon Sep 17 00:00:00 2001 From: Franck LECUYER Date: Mon, 13 May 2024 16:47:16 +0200 Subject: [PATCH 2/3] Modifications after code review. Signed-off-by: Franck LECUYER --- .../src/main/java/com/powsybl/openreac/OpenReacRunner.java | 4 ++-- open-reac/src/main/java/com/powsybl/openreac/Reports.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java b/open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java index 860b92c0..6ea11480 100644 --- a/open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java +++ b/open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java @@ -71,7 +71,7 @@ public static OpenReacResult run(Network network, String variantId, OpenReacPara * @return All information about the run and possible modifications to apply. */ public static OpenReacResult run(Network network, String variantId, OpenReacParameters parameters, OpenReacConfig config, ComputationManager manager, ReportNode reportNode, AmplExportConfig amplExportConfig) { - checkParameters(network, variantId, parameters, config, manager, Reports.createParametersIntegrityReporter(reportNode, network.getId())); + checkParameters(network, variantId, parameters, config, manager, reportNode); AmplModel reactiveOpf = OpenReacModel.buildModel(); OpenReacAmplIOFiles amplIoInterface = new OpenReacAmplIOFiles(parameters, amplExportConfig, network, config.isDebug(), Reports.createOpenReacReporter(reportNode, network.getId(), parameters.getObjective())); AmplResults run = AmplModelRunner.run(network, variantId, reactiveOpf, manager, amplIoInterface); @@ -118,6 +118,6 @@ private static void checkParameters(Network network, String variantId, OpenReacP Objects.requireNonNull(config); Objects.requireNonNull(manager); Objects.requireNonNull(reportNode); - parameters.checkIntegrity(network, reportNode); + parameters.checkIntegrity(network, Reports.createParameterIntegrityReporter(reportNode, network.getId())); } } diff --git a/open-reac/src/main/java/com/powsybl/openreac/Reports.java b/open-reac/src/main/java/com/powsybl/openreac/Reports.java index 7e3494f4..bb27751e 100644 --- a/open-reac/src/main/java/com/powsybl/openreac/Reports.java +++ b/open-reac/src/main/java/com/powsybl/openreac/Reports.java @@ -51,9 +51,9 @@ public static void reportVariableShuntCompensatorsSize(ReportNode reportNode, in .add(); } - public static ReportNode createParametersIntegrityReporter(ReportNode reportNode, String networkId) { + public static ReportNode createParameterIntegrityReporter(ReportNode reportNode, String networkId) { return reportNode.newReportNode() - .withMessageTemplate("openReacParametersIntegrity", "Open reac parameters integrity on network '${networkId}'") + .withMessageTemplate("openReacParameterIntegrity", "Open reac parameter integrity on network '${networkId}'") .withUntypedValue("networkId", networkId) .add(); } From a600459ba297d1d41b96a1bc37461bf946d7503a Mon Sep 17 00:00:00 2001 From: Franck LECUYER Date: Mon, 13 May 2024 17:40:23 +0200 Subject: [PATCH 3/3] Fix Sonar issues Signed-off-by: Franck LECUYER --- .../parameters/input/OpenReacParameters.java | 149 ++++++++++-------- 1 file changed, 85 insertions(+), 64 deletions(-) diff --git a/open-reac/src/main/java/com/powsybl/openreac/parameters/input/OpenReacParameters.java b/open-reac/src/main/java/com/powsybl/openreac/parameters/input/OpenReacParameters.java index 2ba86ddc..4d945ff4 100644 --- a/open-reac/src/main/java/com/powsybl/openreac/parameters/input/OpenReacParameters.java +++ b/open-reac/src/main/java/com/powsybl/openreac/parameters/input/OpenReacParameters.java @@ -535,40 +535,10 @@ public List getAllAlgorithmParams() { return allAlgoParams; } - /** - * Do some checks on the parameters given, such as provided IDs must correspond to the given network element - * - * @param network Network on which ID are going to be infered - * @param reportNode aggregates functional logging - * @throws InvalidParametersException if the parameters contain some incoherences. - */ - public void checkIntegrity(Network network, ReportNode reportNode) throws InvalidParametersException { + private void checkLowAndHighVoltageLimitIntegrity(Network network, boolean integrityVoltageLimitOverrides, + Map> voltageLevelsWithInconsistentLimits, + ReportNode reportNode) { Map> voltageLevelsWithMissingLimits = new TreeMap<>(); - Map> voltageLevelsWithInconsistentLimits = new TreeMap<>(); - - for (String shuntId : getVariableShuntCompensators()) { - if (network.getShuntCompensator(shuntId) == null) { - throw new InvalidParametersException("Shunt " + shuntId + " not found in the network."); - } - } - for (String genId : getConstantQGenerators()) { - if (network.getGenerator(genId) == null) { - throw new InvalidParametersException("Generator " + genId + " not found in the network."); - } - } - for (String transformerId : getVariableTwoWindingsTransformers()) { - if (network.getTwoWindingsTransformer(transformerId) == null) { - throw new InvalidParametersException("Two windings transformer " + transformerId + " not found in the network."); - } - } - for (String busId : getConfiguredReactiveSlackBuses()) { - if (network.getBusView().getBus(busId) == null) { - throw new InvalidParametersException("Bus " + busId + " not found in the network."); - } - } - - // Check integrity of voltage overrides - boolean integrityVoltageLimitOverrides = checkVoltageLimitOverrides(network, voltageLevelsWithInconsistentLimits); // Check integrity of low/high voltage limits, taking into account voltage limit overrides boolean integrityVoltageLevelLimits = checkLowVoltageLevelLimits(network, voltageLevelsWithMissingLimits); @@ -616,6 +586,44 @@ public void checkIntegrity(Network network, ReportNode reportNode) throws Invali throw new InvalidParametersException("At least one voltage limit override is inconsistent."); } } + } + + /** + * Do some checks on the parameters given, such as provided IDs must correspond to the given network element + * + * @param network Network on which ID are going to be infered + * @param reportNode aggregates functional logging + * @throws InvalidParametersException if the parameters contain some incoherences. + */ + public void checkIntegrity(Network network, ReportNode reportNode) throws InvalidParametersException { + Map> voltageLevelsWithInconsistentLimits = new TreeMap<>(); + + for (String shuntId : getVariableShuntCompensators()) { + if (network.getShuntCompensator(shuntId) == null) { + throw new InvalidParametersException("Shunt " + shuntId + " not found in the network."); + } + } + for (String genId : getConstantQGenerators()) { + if (network.getGenerator(genId) == null) { + throw new InvalidParametersException("Generator " + genId + " not found in the network."); + } + } + for (String transformerId : getVariableTwoWindingsTransformers()) { + if (network.getTwoWindingsTransformer(transformerId) == null) { + throw new InvalidParametersException("Two windings transformer " + transformerId + " not found in the network."); + } + } + for (String busId : getConfiguredReactiveSlackBuses()) { + if (network.getBusView().getBus(busId) == null) { + throw new InvalidParametersException("Bus " + busId + " not found in the network."); + } + } + + // Check integrity of voltage overrides + boolean integrityVoltageLimitOverrides = checkVoltageLimitOverrides(network, voltageLevelsWithInconsistentLimits); + + // Check integrity of low/high voltage limits, taking into account voltage limit overrides + checkLowAndHighVoltageLimitIntegrity(network, integrityVoltageLimitOverrides, voltageLevelsWithInconsistentLimits, reportNode); boolean integrityAlgorithmParameters = checkAlgorithmParametersIntegrity(); if (!integrityAlgorithmParameters) { @@ -734,6 +742,48 @@ boolean checkHighVoltageLevelLimits(Network network, Map> voltageLevelsLimitsAfterOverride, + Map> voltageLevelsWithInconsistentLimits) { + boolean integrityVoltageLimitOverrides = true; + double value = voltageLimitOverride.getVoltageLimitType() == VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT ? + voltageLevel.getLowVoltageLimit() : voltageLevel.getHighVoltageLimit(); + if (Double.isNaN(value)) { + LOGGER.warn("Voltage level {} has undefined {}, relative voltage limit override is impossible.", + voltageLevel.getId(), voltageLimitOverride.getVoltageLimitType()); + integrityVoltageLimitOverrides = false; + } else { + // verify voltage limit override does not lead to negative limit value + double valueAfter = value + voltageLimitOverride.getLimit(); + if (voltageLimitOverride.getVoltageLimitType() == VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT) { + voltageLevelsLimitsAfterOverride.merge(voltageLevel.getId(), Pair.of(valueAfter, voltageLevel.getHighVoltageLimit()), (old, newValue) -> Pair.of(valueAfter, old.getRight())); + if (valueAfter < 0) { + voltageLevelsWithInconsistentLimits.merge(voltageLevel.getId(), Pair.of(valueAfter, voltageLevel.getHighVoltageLimit()), (old, newValue) -> Pair.of(valueAfter, old.getRight())); + } + } else { + voltageLevelsLimitsAfterOverride.merge(voltageLevel.getId(), Pair.of(voltageLevel.getLowVoltageLimit(), valueAfter), (old, newValue) -> Pair.of(old.getLeft(), valueAfter)); + if (valueAfter < 0) { + voltageLevelsWithInconsistentLimits.merge(voltageLevel.getId(), Pair.of(voltageLevel.getLowVoltageLimit(), valueAfter), (old, newValue) -> Pair.of(old.getLeft(), valueAfter)); + } + } + if (valueAfter < 0) { + LOGGER.warn("Voltage level {} relative override leads to a negative {}.", + voltageLevel.getId(), voltageLimitOverride.getVoltageLimitType()); + integrityVoltageLimitOverrides = false; + } + } + return integrityVoltageLimitOverrides; + } + + private void checkAbsoluteVoltageLimitOverrides(VoltageLimitOverride voltageLimitOverride, VoltageLevel voltageLevel, + Map> voltageLevelsLimitsAfterOverride) { + if (voltageLimitOverride.getVoltageLimitType() == VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT) { + voltageLevelsLimitsAfterOverride.merge(voltageLevel.getId(), Pair.of(voltageLimitOverride.getLimit(), voltageLevel.getHighVoltageLimit()), (old, newValue) -> Pair.of(voltageLimitOverride.getLimit(), old.getRight())); + } else { + voltageLevelsLimitsAfterOverride.merge(voltageLevel.getId(), Pair.of(voltageLevel.getLowVoltageLimit(), voltageLimitOverride.getLimit()), (old, newValue) -> Pair.of(old.getLeft(), voltageLimitOverride.getLimit())); + } + } + /** * @param network the network on which are applied voltage limit overrides. * @return true if the integrity of voltage limit overrides is verified, false otherwise. @@ -756,38 +806,9 @@ boolean checkVoltageLimitOverrides(Network network, } if (voltageLimitOverride.isRelative()) { - double value = voltageLimitOverride.getVoltageLimitType() == VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT ? - voltageLevel.getLowVoltageLimit() : voltageLevel.getHighVoltageLimit(); - if (Double.isNaN(value)) { - LOGGER.warn("Voltage level {} has undefined {}, relative voltage limit override is impossible.", - voltageLevelId, voltageLimitOverride.getVoltageLimitType()); - integrityVoltageLimitOverrides = false; - continue; - } - // verify voltage limit override does not lead to negative limit value - double valueAfter = value + voltageLimitOverride.getLimit(); - if (voltageLimitOverride.getVoltageLimitType() == VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT) { - voltageLevelsLimitsAfterOverride.merge(voltageLevelId, Pair.of(valueAfter, voltageLevel.getHighVoltageLimit()), (old, newValue) -> Pair.of(valueAfter, old.getRight())); - if (valueAfter < 0) { - voltageLevelsWithInconsistentLimits.merge(voltageLevelId, Pair.of(valueAfter, voltageLevel.getHighVoltageLimit()), (old, newValue) -> Pair.of(valueAfter, old.getRight())); - } - } else { - voltageLevelsLimitsAfterOverride.merge(voltageLevelId, Pair.of(voltageLevel.getLowVoltageLimit(), valueAfter), (old, newValue) -> Pair.of(old.getLeft(), valueAfter)); - if (valueAfter < 0) { - voltageLevelsWithInconsistentLimits.merge(voltageLevelId, Pair.of(voltageLevel.getLowVoltageLimit(), valueAfter), (old, newValue) -> Pair.of(old.getLeft(), valueAfter)); - } - } - if (valueAfter < 0) { - LOGGER.warn("Voltage level {} relative override leads to a negative {}.", - voltageLevelId, voltageLimitOverride.getVoltageLimitType()); - integrityVoltageLimitOverrides = false; - } + integrityVoltageLimitOverrides &= checkRelativeVoltageLimitOverrides(voltageLimitOverride, voltageLevel, voltageLevelsLimitsAfterOverride, voltageLevelsWithInconsistentLimits); } else { - if (voltageLimitOverride.getVoltageLimitType() == VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT) { - voltageLevelsLimitsAfterOverride.merge(voltageLevelId, Pair.of(voltageLimitOverride.getLimit(), voltageLevel.getHighVoltageLimit()), (old, newValue) -> Pair.of(voltageLimitOverride.getLimit(), old.getRight())); - } else { - voltageLevelsLimitsAfterOverride.merge(voltageLevelId, Pair.of(voltageLevel.getLowVoltageLimit(), voltageLimitOverride.getLimit()), (old, newValue) -> Pair.of(old.getLeft(), voltageLimitOverride.getLimit())); - } + checkAbsoluteVoltageLimitOverrides(voltageLimitOverride, voltageLevel, voltageLevelsLimitsAfterOverride); } }