From 04969cc1e2a7a76c772bdff88d99ff9f8de73d45 Mon Sep 17 00:00:00 2001 From: Lisrte Date: Wed, 3 Jul 2024 13:36:41 +0200 Subject: [PATCH] Refactor Dynaflow parameter - fix merge loads parameter (#366) * Fix merge loads parameter serialization * Fix createMapFromSpecificParameters * Add unit test coverage * Replace chosenOutputs List with EnumSet * Add default values to DynaFlowParameters Signed-off-by: lisrte --- .../powsybl/dynaflow/DynaFlowParameters.java | 142 ++++++++++++------ .../powsybl/dynaflow/DynaFlowProvider.java | 21 +-- .../json/DynaFlowConfigSerializer.java | 14 +- .../JsonDynaFlowParametersSerializer.java | 4 +- .../dynaflow/DynaFlowParametersTest.java | 47 +++--- .../dynaflow/DynaFlowProviderTest.java | 25 ++- .../JsonDynaFlowParametersSerializerTest.java | 15 +- .../dynaflow_default_serialization.json | 12 +- ...dynaflow_parameters_set_serialization.json | 1 + .../src/test/resources/params_default.json | 9 ++ 10 files changed, 185 insertions(+), 105 deletions(-) diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowParameters.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowParameters.java index 3d71517a5..fd5cf7eec 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowParameters.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowParameters.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.util.*; +import java.util.function.BiConsumer; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -37,9 +38,10 @@ public class DynaFlowParameters extends AbstractExtension { */ public static class Sa { private static final String SECURITY_ANALYSIS = "sa"; //Security analysis + private static final double DEFAULT_TIME_OF_EVENT = 10d; protected static final String TIME_OF_EVENT = "timeOfEvent"; - private Double timeOfEvent = null; + private Double timeOfEvent = DEFAULT_TIME_OF_EVENT; public Double getTimeOfEvent() { return timeOfEvent; @@ -70,57 +72,71 @@ public boolean isSerializable() { } private static final String CHOSEN_OUTPUT_STRING_DELIMITER = ","; - protected static final String SVC_REGULATION_ON = "svcRegulationOn"; - protected static final String SHUNT_REGULATION_ON = "shuntRegulationOn"; - protected static final String AUTOMATIC_SLACK_BUS_ON = "automaticSlackBusOn"; - protected static final String DSO_VOLTAGE_LEVEL = "dsoVoltageLevel"; - protected static final String ACTIVE_POWER_COMPENSATION = "activePowerCompensation"; - protected static final String SETTING_PATH = "settingPath"; - protected static final String ASSEMBLING_PATH = "assemblingPath"; - protected static final String START_TIME = "startTime"; - protected static final String STOP_TIME = "stopTime"; - protected static final String PRECISION_NAME = "precision"; - protected static final String CHOSEN_OUTPUTS = "chosenOutputs"; - protected static final String TIME_STEP = "timeStep"; - protected static final String STARTING_POINT_MODE = "startingPointMode"; - protected static final String MERGE_LOADS = "mergeLoads"; + private static final String SVC_REGULATION_ON = "svcRegulationOn"; + private static final String SHUNT_REGULATION_ON = "shuntRegulationOn"; + private static final String AUTOMATIC_SLACK_BUS_ON = "automaticSlackBusOn"; + private static final String DSO_VOLTAGE_LEVEL = "dsoVoltageLevel"; + private static final String ACTIVE_POWER_COMPENSATION = "activePowerCompensation"; + private static final String SETTING_PATH = "settingPath"; + private static final String ASSEMBLING_PATH = "assemblingPath"; + private static final String START_TIME = "startTime"; + private static final String STOP_TIME = "stopTime"; + private static final String PRECISION_NAME = "precision"; + private static final String CHOSEN_OUTPUTS = "chosenOutputs"; + private static final String TIME_STEP = "timeStep"; + private static final String STARTING_POINT_MODE = "startingPointMode"; + private static final String MERGE_LOADS = "mergeLoads"; + + // Default values + private static final boolean DEFAULT_SVC_REGULATION_ON = true; + private static final boolean DEFAULT_SHUNT_REGULATION_ON = true; + private static final boolean DEFAULT_AUTOMATIC_SLACK_BUS_ON = true; + private static final double DEFAULT_DSO_VOLTAGE_LEVEL = 45d; + private static final ActivePowerCompensation DEFAULT_ACTIVE_POWER_COMPENSATION = ActivePowerCompensation.PMAX; + private static final double DEFAULT_START_TIME = 0d; + private static final double DEFAULT_STOP_TIME = 100d; + private static final double DEFAULT_PRECISION = Double.NaN; + private static final EnumSet DEFAULT_CHOSEN_OUTPUTS = EnumSet.of(OutputTypes.TIMELINE); + private static final double DEFAULT_TIME_STEP = 10d; + private static final StartingPointMode DEFAULT_STARTING_POINT_MODE = StartingPointMode.WARM; + private static final boolean DEFAULT_MERGE_LOADS = true; private static > List getEnumPossibleValues(Class enumClass) { return EnumSet.allOf(enumClass).stream().map(Enum::name).collect(Collectors.toList()); } public static final List SPECIFIC_PARAMETERS = List.of( - new Parameter(SVC_REGULATION_ON, ParameterType.BOOLEAN, "Static Var Compensator regulation on", Boolean.TRUE), - new Parameter(SHUNT_REGULATION_ON, ParameterType.BOOLEAN, "Shunt compensator regulation on", Boolean.TRUE), - new Parameter(AUTOMATIC_SLACK_BUS_ON, ParameterType.BOOLEAN, "Automatic slack bus selection on", Boolean.TRUE), - new Parameter(DSO_VOLTAGE_LEVEL, ParameterType.DOUBLE, "DSO voltage level threshold", 45d), - new Parameter(ACTIVE_POWER_COMPENSATION, ParameterType.STRING, "Active power compensation mode", ActivePowerCompensation.PMAX.name(), getEnumPossibleValues(ActivePowerCompensation.class)), + new Parameter(SVC_REGULATION_ON, ParameterType.BOOLEAN, "Static Var Compensator regulation on", DEFAULT_SVC_REGULATION_ON), + new Parameter(SHUNT_REGULATION_ON, ParameterType.BOOLEAN, "Shunt compensator regulation on", DEFAULT_SHUNT_REGULATION_ON), + new Parameter(AUTOMATIC_SLACK_BUS_ON, ParameterType.BOOLEAN, "Automatic slack bus selection on", DEFAULT_AUTOMATIC_SLACK_BUS_ON), + new Parameter(DSO_VOLTAGE_LEVEL, ParameterType.DOUBLE, "DSO voltage level threshold", DEFAULT_DSO_VOLTAGE_LEVEL), + new Parameter(ACTIVE_POWER_COMPENSATION, ParameterType.STRING, "Active power compensation mode", DEFAULT_ACTIVE_POWER_COMPENSATION.name(), getEnumPossibleValues(ActivePowerCompensation.class)), new Parameter(SETTING_PATH, ParameterType.STRING, "Setting file path", null, null, ParameterScope.TECHNICAL), new Parameter(ASSEMBLING_PATH, ParameterType.STRING, "Assembling file path", null, null, ParameterScope.TECHNICAL), - new Parameter(START_TIME, ParameterType.DOUBLE, "Start time", 0d), - new Parameter(STOP_TIME, ParameterType.DOUBLE, "Stop time", 100d), - new Parameter(PRECISION_NAME, ParameterType.DOUBLE, "Precision", Double.NaN), - new Parameter(Sa.TIME_OF_EVENT, ParameterType.DOUBLE, "Time of event", 10d), - new Parameter(CHOSEN_OUTPUTS, ParameterType.STRING_LIST, "Chosen outputs", List.of(OutputTypes.TIMELINE.name()), getEnumPossibleValues(OutputTypes.class), ParameterScope.TECHNICAL), - new Parameter(TIME_STEP, ParameterType.DOUBLE, "Time step", 10d), - new Parameter(STARTING_POINT_MODE, ParameterType.STRING, "Starting point mode", StartingPointMode.WARM.name(), getEnumPossibleValues(StartingPointMode.class)), - new Parameter(MERGE_LOADS, ParameterType.BOOLEAN, "Merge loads connected to same bus", Boolean.TRUE)); - - private Boolean svcRegulationOn = null; - private Boolean shuntRegulationOn = null; - private Boolean automaticSlackBusOn = null; - private Double dsoVoltageLevel = null; - private ActivePowerCompensation activePowerCompensation = null; + new Parameter(START_TIME, ParameterType.DOUBLE, "Start time", DEFAULT_START_TIME), + new Parameter(STOP_TIME, ParameterType.DOUBLE, "Stop time", DEFAULT_STOP_TIME), + new Parameter(PRECISION_NAME, ParameterType.DOUBLE, "Precision", DEFAULT_PRECISION), + new Parameter(Sa.TIME_OF_EVENT, ParameterType.DOUBLE, "Time of event", Sa.DEFAULT_TIME_OF_EVENT), + new Parameter(CHOSEN_OUTPUTS, ParameterType.STRING_LIST, "Chosen outputs", DEFAULT_CHOSEN_OUTPUTS.stream().map(OutputTypes::name).toList(), getEnumPossibleValues(OutputTypes.class), ParameterScope.TECHNICAL), + new Parameter(TIME_STEP, ParameterType.DOUBLE, "Time step", DEFAULT_TIME_STEP), + new Parameter(STARTING_POINT_MODE, ParameterType.STRING, "Starting point mode", DEFAULT_STARTING_POINT_MODE.name(), getEnumPossibleValues(StartingPointMode.class)), + new Parameter(MERGE_LOADS, ParameterType.BOOLEAN, "Merge loads connected to same bus", DEFAULT_MERGE_LOADS)); + + private boolean svcRegulationOn = DEFAULT_SVC_REGULATION_ON; + private boolean shuntRegulationOn = DEFAULT_SHUNT_REGULATION_ON; + private boolean automaticSlackBusOn = DEFAULT_AUTOMATIC_SLACK_BUS_ON; + private double dsoVoltageLevel = DEFAULT_DSO_VOLTAGE_LEVEL; + private ActivePowerCompensation activePowerCompensation = DEFAULT_ACTIVE_POWER_COMPENSATION; private String settingPath = null; private String assemblingPath = null; - private Double startTime = null; - private Double stopTime = null; + private double startTime = DEFAULT_START_TIME; + private double stopTime = DEFAULT_STOP_TIME; private Double precision = null; private Sa securityAnalysis = null; - private List chosenOutputs = List.of(OutputTypes.TIMELINE.name()); - private Double timeStep = null; - private StartingPointMode startingPointMode = null; - private boolean mergeLoads = true; + private EnumSet chosenOutputs = DEFAULT_CHOSEN_OUTPUTS; + private double timeStep = DEFAULT_TIME_STEP; + private StartingPointMode startingPointMode = DEFAULT_STARTING_POINT_MODE; + private boolean mergeLoads = DEFAULT_MERGE_LOADS; public Boolean getSvcRegulationOn() { return svcRegulationOn; @@ -225,12 +241,17 @@ public DynaFlowParameters setTimeOfEvent(Double timeOfEvent) { return this; } - public List getChosenOutputs() { + public Set getChosenOutputs() { return chosenOutputs; } - public DynaFlowParameters setChosenOutputs(List chosenOutputs) { - this.chosenOutputs = chosenOutputs; + public DynaFlowParameters setChosenOutputs(Set chosenOutputs) { + this.chosenOutputs = EnumSet.copyOf(chosenOutputs); + return this; + } + + public DynaFlowParameters addChosenOutput(OutputTypes chosenOutput) { + this.chosenOutputs.add(chosenOutput); return this; } @@ -261,7 +282,6 @@ public DynaFlowParameters setSa(Sa securityAnalysis) { return this; } - @JsonIgnore public boolean isMergeLoads() { return mergeLoads; } @@ -327,7 +347,7 @@ private static void load(DynaFlowParameters parameters, ModuleConfig config) { config.getOptionalDoubleProperty(STOP_TIME).ifPresent(parameters::setStopTime); config.getOptionalDoubleProperty(PRECISION_NAME).ifPresent(parameters::setPrecision); config.getOptionalDoubleProperty(Sa.TIME_OF_EVENT).ifPresent(parameters::setTimeOfEvent); - config.getOptionalStringListProperty(CHOSEN_OUTPUTS).ifPresent(parameters::setChosenOutputs); + config.getOptionalEnumSetProperty(CHOSEN_OUTPUTS, OutputTypes.class).ifPresent(parameters::setChosenOutputs); config.getOptionalDoubleProperty(TIME_STEP).ifPresent(parameters::setTimeStep); config.getOptionalStringProperty(STARTING_POINT_MODE).map(StartingPointMode::fromString).ifPresent(parameters::setStartingPointMode); config.getOptionalBooleanProperty(MERGE_LOADS).ifPresent(parameters::setMergeLoads); @@ -352,12 +372,42 @@ public void update(Map properties) { securityAnalysis.setTimeOfEvent(Double.parseDouble(prop)); }); Optional.ofNullable(properties.get(CHOSEN_OUTPUTS)).ifPresent(prop -> - setChosenOutputs(Stream.of(prop.split(CHOSEN_OUTPUT_STRING_DELIMITER)).map(String::trim).collect(Collectors.toList()))); + setChosenOutputs(Stream.of(prop.split(CHOSEN_OUTPUT_STRING_DELIMITER)).map(o -> OutputTypes.valueOf(o.trim())).collect(Collectors.toSet()))); Optional.ofNullable(properties.get(TIME_STEP)).ifPresent(prop -> setTimeStep(Double.parseDouble(prop))); Optional.ofNullable(properties.get(STARTING_POINT_MODE)).ifPresent(prop -> setStartingPointMode(StartingPointMode.fromString(prop))); Optional.ofNullable(properties.get(MERGE_LOADS)).ifPresent(prop -> setMergeLoads(Boolean.parseBoolean(prop))); } + public Map createMapFromParameters() { + Map parameters = new HashMap<>(); + addNotNullEntry(SVC_REGULATION_ON, svcRegulationOn, parameters::put); + addNotNullEntry(SHUNT_REGULATION_ON, shuntRegulationOn, parameters::put); + addNotNullEntry(AUTOMATIC_SLACK_BUS_ON, automaticSlackBusOn, parameters::put); + addNotNullEntry(DSO_VOLTAGE_LEVEL, dsoVoltageLevel, parameters::put); + if (activePowerCompensation != null) { + parameters.put(ACTIVE_POWER_COMPENSATION, activePowerCompensation.name()); + } + addNotNullEntry(SETTING_PATH, settingPath, parameters::put); + addNotNullEntry(ASSEMBLING_PATH, assemblingPath, parameters::put); + addNotNullEntry(START_TIME, startTime, parameters::put); + addNotNullEntry(STOP_TIME, stopTime, parameters::put); + addNotNullEntry(PRECISION_NAME, precision, parameters::put); + addNotNullEntry(Sa.TIME_OF_EVENT, getTimeOfEvent(), parameters::put); + if (!chosenOutputs.isEmpty()) { + parameters.put(CHOSEN_OUTPUTS, String.join(CHOSEN_OUTPUT_STRING_DELIMITER, chosenOutputs.stream().map(OutputTypes::name).toList())); + } + addNotNullEntry(TIME_STEP, timeStep, parameters::put); + addNotNullEntry(STARTING_POINT_MODE, startingPointMode, parameters::put); + addNotNullEntry(MERGE_LOADS, mergeLoads, parameters::put); + return parameters; + } + + private void addNotNullEntry(String key, Object value, BiConsumer adder) { + if (value != null) { + adder.accept(key, Objects.toString(value)); + } + } + public static DynaFlowParameters load(Map properties) { DynaFlowParameters parameters = new DynaFlowParameters(); parameters.update(properties); diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java index ba61308c5..e7581daac 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java @@ -39,7 +39,6 @@ import java.util.concurrent.CompletableFuture; import static com.powsybl.dynaflow.DynaFlowConstants.*; -import static com.powsybl.dynaflow.DynaFlowParameters.*; import static com.powsybl.dynawo.commons.DynawoConstants.DYNAWO_TIMELINE_FOLDER; /** @@ -141,22 +140,10 @@ public Optional> loadSpecificParameters(Map createMapFromSpecificParameters(Extension extension) { - return Map.ofEntries( - Map.entry(SVC_REGULATION_ON, Boolean.toString(((DynaFlowParameters) extension).getSvcRegulationOn())), - Map.entry(SHUNT_REGULATION_ON, Boolean.toString(((DynaFlowParameters) extension).getShuntRegulationOn())), - Map.entry(AUTOMATIC_SLACK_BUS_ON, Boolean.toString(((DynaFlowParameters) extension).getAutomaticSlackBusOn())), - Map.entry(DSO_VOLTAGE_LEVEL, Double.toString(((DynaFlowParameters) extension).getDsoVoltageLevel())), - Map.entry(ACTIVE_POWER_COMPENSATION, ((DynaFlowParameters) extension).getActivePowerCompensation().name()), - Map.entry(SETTING_PATH, ((DynaFlowParameters) extension).getSettingPath()), - Map.entry(ASSEMBLING_PATH, ((DynaFlowParameters) extension).getAssemblingPath()), - Map.entry(START_TIME, Double.toString(((DynaFlowParameters) extension).getStartTime())), - Map.entry(STOP_TIME, Double.toString(((DynaFlowParameters) extension).getStopTime())), - Map.entry(PRECISION_NAME, Double.toString(((DynaFlowParameters) extension).getPrecision())), - Map.entry(Sa.TIME_OF_EVENT, Double.toString(((DynaFlowParameters) extension).getSa().getTimeOfEvent())), - Map.entry(CHOSEN_OUTPUTS, String.join(", ", ((DynaFlowParameters) extension).getChosenOutputs())), - Map.entry(TIME_STEP, Double.toString(((DynaFlowParameters) extension).getTimeStep())), - Map.entry(STARTING_POINT_MODE, ((DynaFlowParameters) extension).getStartingPointMode().name()), - Map.entry(MERGE_LOADS, Boolean.toString(((DynaFlowParameters) extension).isMergeLoads()))); + if (extension instanceof DynaFlowParameters dfp) { + return dfp.createMapFromParameters(); + } + return Collections.emptyMap(); } @Override diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/json/DynaFlowConfigSerializer.java b/dynaflow/src/main/java/com/powsybl/dynaflow/json/DynaFlowConfigSerializer.java index 79a85f2af..5bb8aa295 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/json/DynaFlowConfigSerializer.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/json/DynaFlowConfigSerializer.java @@ -8,6 +8,7 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.powsybl.commons.json.JsonUtil; +import com.powsybl.dynaflow.DynaFlowConstants; import com.powsybl.dynaflow.DynaFlowParameters; import com.powsybl.loadflow.LoadFlowParameters; @@ -20,7 +21,8 @@ import java.nio.file.Path; /** - * + * Serializes parameters from {@link DynaFlowParameters} used by Dynawo. + * Some parameters are directly used by powsybl-dynawo and thus not serialized. * @author Guillaume Pernin {@literal } */ public final class DynaFlowConfigSerializer { @@ -55,18 +57,16 @@ private static void serialize(LoadFlowParameters lfParameters, DynaFlowParameter writeNonNullField(jsonGenerator, "AssemblingPath", dynaFlowParameters.getAssemblingPath()); writeNonNullField(jsonGenerator, "StartTime", dynaFlowParameters.getStartTime()); writeNonNullField(jsonGenerator, "StopTime", dynaFlowParameters.getStopTime()); + writeNonNullField(jsonGenerator, "Precision", dynaFlowParameters.getPrecision()); - if (dynaFlowParameters.getPrecision() != null && !Double.isNaN(dynaFlowParameters.getPrecision())) { - jsonGenerator.writeNumberField("Precision", dynaFlowParameters.getPrecision()); - } if (dynaFlowParameters.getSa() != null) { DynaFlowParameters.Sa.writeJson(jsonGenerator, dynaFlowParameters); } if (dynaFlowParameters.getChosenOutputs() != null) { jsonGenerator.writeFieldName("ChosenOutputs"); jsonGenerator.writeStartArray(); - for (String outputType : dynaFlowParameters.getChosenOutputs()) { - jsonGenerator.writeString(outputType); + for (DynaFlowConstants.OutputTypes outputType : dynaFlowParameters.getChosenOutputs()) { + jsonGenerator.writeString(outputType.name()); } jsonGenerator.writeEndArray(); } @@ -90,7 +90,7 @@ private static void writeNonNullField(JsonGenerator jsonGenerator, String fieldN } private static void writeNonNullField(JsonGenerator jsonGenerator, String fieldName, Double value) throws IOException { - if (value != null) { + if (value != null && !Double.isNaN(value)) { jsonGenerator.writeNumberField(fieldName, value); } } diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/json/JsonDynaFlowParametersSerializer.java b/dynaflow/src/main/java/com/powsybl/dynaflow/json/JsonDynaFlowParametersSerializer.java index acc0361d2..2020cb6c9 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/json/JsonDynaFlowParametersSerializer.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/json/JsonDynaFlowParametersSerializer.java @@ -23,7 +23,7 @@ import java.io.IOException; /** - * + * Represents {@link DynaFlowParameters} as a Json extension of {@link LoadFlowParameters} * @author Guillaume Pernin {@literal } */ @AutoService(ExtensionJsonSerializer.class) @@ -59,7 +59,7 @@ private interface SerializationSpec { private static ObjectMapper createMapper() { return JsonUtil.createObjectMapper() .addMixIn(DynaFlowParameters.class, SerializationSpec.class) - .setSerializationInclusion(JsonInclude.Include.NON_NULL); + .setSerializationInclusion(JsonInclude.Include.NON_ABSENT); } @Override diff --git a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowParametersTest.java b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowParametersTest.java index 9d646b02e..ad4aca131 100644 --- a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowParametersTest.java +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowParametersTest.java @@ -28,6 +28,7 @@ import static com.powsybl.commons.test.ComparisonUtils.assertTxtEquals; import static com.powsybl.dynaflow.DynaFlowProvider.MODULE_SPECIFIC_PARAMETERS; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; /** @@ -61,14 +62,11 @@ void checkParameters() { double startTime = 0.; double stopTime = 100.; double precision = 15.45; - double timeOfEvent = 10.; - List chosenOutputs = Arrays.asList(OutputTypes.STEADYSTATE.name(), OutputTypes.TIMELINE.name()); + double timeOfEvent = 14.; + List chosenOutputs = List.of(OutputTypes.STEADYSTATE.name(), OutputTypes.TIMELINE.name()); double timeStep = 0; StartingPointMode startingPointMode = StartingPointMode.FLAT; - boolean mergeLoads = false; - - DynaFlowParameters.Sa securityAnalysis = new DynaFlowParameters.Sa(); - securityAnalysis.setTimeOfEvent(2.); + boolean mergeLoads = true; MapModuleConfig moduleConfig = platformConfig.createModuleConfig(MODULE_SPECIFIC_PARAMETERS); moduleConfig.setStringProperty("svcRegulationOn", Boolean.toString(svcRegulationOn)); @@ -100,7 +98,7 @@ void checkParameters() { assertEquals(stopTime, parameters.getStopTime(), 0.1d); assertEquals(precision, parameters.getPrecision(), 0.1d); assertEquals(timeOfEvent, parameters.getTimeOfEvent(), 0.1d); - assertArrayEquals(chosenOutputs.toArray(), parameters.getChosenOutputs().toArray()); + assertThat(parameters.getChosenOutputs()).map(OutputTypes::name).containsExactlyInAnyOrderElementsOf(chosenOutputs); assertEquals(timeStep, parameters.getTimeStep(), 0.1d); assertEquals(startingPointMode, parameters.getStartingPointMode()); assertEquals(mergeLoads, parameters.isMergeLoads()); @@ -112,22 +110,23 @@ void checkDefaultParameters() { DynaFlowParameters parametersExt = parameters.getExtension(DynaFlowParameters.class); assertNotNull(parametersExt); - assertEquals("{chosenOutputs=[TIMELINE], mergeLoads=true}", parametersExt.toString()); + assertEquals("{svcRegulationOn=true, shuntRegulationOn=true, automaticSlackBusOn=true, dsoVoltageLevel=45.0, activePowerCompensation=PMAX, startTime=0.0, stopTime=100.0, chosenOutputs=[TIMELINE], timeStep=10.0, startingPointMode=WARM, mergeLoads=true}", + parametersExt.toString()); - assertNull(parametersExt.getSvcRegulationOn()); - assertNull(parametersExt.getShuntRegulationOn()); - assertNull(parametersExt.getAutomaticSlackBusOn()); - assertNull(parametersExt.getDsoVoltageLevel()); - assertNull(parametersExt.getActivePowerCompensation()); + assertTrue(parametersExt.getSvcRegulationOn()); + assertTrue(parametersExt.getShuntRegulationOn()); + assertTrue(parametersExt.getAutomaticSlackBusOn()); + assertEquals(45d, parametersExt.getDsoVoltageLevel()); + assertEquals(ActivePowerCompensation.PMAX, parametersExt.getActivePowerCompensation()); assertNull(parametersExt.getSettingPath()); assertNull(parametersExt.getAssemblingPath()); - assertNull(parametersExt.getStartTime()); - assertNull(parametersExt.getStopTime()); + assertEquals(0d, parametersExt.getStartTime()); + assertEquals(100d, parametersExt.getStopTime()); assertNull(parametersExt.getPrecision()); assertNull(parametersExt.getSa()); - assertEquals(List.of(OutputTypes.TIMELINE.name()), parametersExt.getChosenOutputs()); - assertNull(parametersExt.getTimeStep()); - assertNull(parametersExt.getStartingPointMode()); + assertThat(parametersExt.getChosenOutputs()).containsExactly(OutputTypes.TIMELINE); + assertEquals(10d, parametersExt.getTimeStep()); + assertEquals(StartingPointMode.WARM, parametersExt.getStartingPointMode()); assertTrue(parametersExt.isMergeLoads()); } @@ -205,6 +204,7 @@ void defaultParametersSerialization() throws IOException { try (InputStream actual = Files.newInputStream(parameterFile); InputStream expected = getClass().getResourceAsStream("/params_default.json")) { + assertNotNull(expected); assertTxtEquals(expected, actual); } } @@ -227,10 +227,10 @@ void parametersSerialization() throws IOException { .setStopTime(100.) .setPrecision(0.) .setTimeOfEvent(10.) - .setChosenOutputs(Collections.singletonList(OutputTypes.STEADYSTATE.name())) + .setChosenOutputs(Set.of(OutputTypes.STEADYSTATE)) .setTimeStep(2.6) .setStartingPointMode(StartingPointMode.WARM) - .setMergeLoads(false); + .setMergeLoads(true); lfParameters.addExtension(DynaFlowParameters.class, dynaFlowParameters); Path workingDir = fileSystem.getPath("dynaflow/workingDir"); @@ -239,6 +239,7 @@ void parametersSerialization() throws IOException { try (InputStream actual = Files.newInputStream(parameterFile); InputStream expected = getClass().getResourceAsStream("/params.json")) { + assertNotNull(expected); assertTxtEquals(expected, actual); } } @@ -257,7 +258,7 @@ void loadMapDynaflowParameters() { double stopTime = 100.; double precision = 15.45; double timeOfEvent = 10.; - List chosenOutputs = Arrays.asList(OutputTypes.STEADYSTATE.name(), OutputTypes.TIMELINE.name()); + Set chosenOutputs = Set.of(OutputTypes.STEADYSTATE, OutputTypes.TIMELINE); double timeStep = 0; StartingPointMode startingPointMode = StartingPointMode.WARM; boolean mergeLoads = false; @@ -274,7 +275,7 @@ void loadMapDynaflowParameters() { properties.put("stopTime", Double.toString(stopTime)); properties.put("precision", Double.toString(precision)); properties.put("timeOfEvent", Double.toString(timeOfEvent)); - properties.put("chosenOutputs", OutputTypes.STEADYSTATE.name() + ", " + OutputTypes.TIMELINE.name()); + properties.put("chosenOutputs", "STEADYSTATE, TIMELINE"); properties.put("timeStep", Double.toString(timeStep)); properties.put("startingPointMode", startingPointMode.getName()); properties.put("mergeLoads", Boolean.toString(mergeLoads)); @@ -292,7 +293,7 @@ void loadMapDynaflowParameters() { assertEquals(stopTime, dynaFlowParameters.getStopTime(), 0.1d); assertEquals(precision, dynaFlowParameters.getPrecision(), 0.1d); assertEquals(timeOfEvent, dynaFlowParameters.getTimeOfEvent(), 0.1d); - assertArrayEquals(chosenOutputs.toArray(), dynaFlowParameters.getChosenOutputs().toArray()); + assertThat(dynaFlowParameters.getChosenOutputs()).containsExactlyInAnyOrderElementsOf(chosenOutputs); assertEquals(timeStep, dynaFlowParameters.getTimeStep(), 0.1d); assertEquals(startingPointMode, dynaFlowParameters.getStartingPointMode()); assertEquals(mergeLoads, dynaFlowParameters.isMergeLoads()); diff --git a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowProviderTest.java b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowProviderTest.java index 9bac95638..5df23c61b 100644 --- a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowProviderTest.java +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowProviderTest.java @@ -27,7 +27,6 @@ import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; @@ -37,6 +36,7 @@ import static com.powsybl.dynaflow.DynaFlowConstants.*; import static com.powsybl.loadflow.LoadFlowResult.Status.FAILED; import static com.powsybl.loadflow.LoadFlowResult.Status.FULLY_CONVERGED; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; /** @@ -210,10 +210,31 @@ void testUpdateSpecificParameters() { assertTrue(dynaParams.getShuntRegulationOn()); assertFalse(dynaParams.getAutomaticSlackBusOn()); assertEquals(2, dynaParams.getDsoVoltageLevel(), 0.1d); - assertArrayEquals(Arrays.asList(OutputTypes.STEADYSTATE.name(), OutputTypes.CONSTRAINTS.name()).toArray(), dynaParams.getChosenOutputs().toArray()); + assertThat(dynaParams.getChosenOutputs()).containsExactlyInAnyOrder(OutputTypes.STEADYSTATE, OutputTypes.CONSTRAINTS); assertEquals(0, dynaParams.getTimeStep(), 0.1d); } + @Test + void testGetSpecificParameters() { + Map expectedProperties = Map.ofEntries( + Map.entry("svcRegulationOn", "true"), + Map.entry("dsoVoltageLevel", "45.0"), + Map.entry("shuntRegulationOn", "true"), + Map.entry("automaticSlackBusOn", "true"), + Map.entry("timeStep", "10.0"), + Map.entry("startingPointMode", "WARM"), + Map.entry("startTime", "0.0"), + Map.entry("stopTime", "100.0"), + Map.entry("activePowerCompensation", "PMAX"), + Map.entry("chosenOutputs", "TIMELINE"), + Map.entry("mergeLoads", "true")); + + LoadFlowParameters params = LoadFlowParameters.load(); + DynaFlowParameters dynaParams = params.getExtension(DynaFlowParameters.class); + Map properties = provider.createMapFromSpecificParameters(dynaParams); + assertThat(properties).containsExactlyInAnyOrderEntriesOf(expectedProperties); + } + private void compare(Network expected, Network actual) throws IOException { Path pexpected = tmpDir.resolve("expected.xiidm"); assertNotNull(pexpected); diff --git a/dynaflow/src/test/java/com/powsybl/dynaflow/json/JsonDynaFlowParametersSerializerTest.java b/dynaflow/src/test/java/com/powsybl/dynaflow/json/JsonDynaFlowParametersSerializerTest.java index f81e5cadc..44e474bd7 100644 --- a/dynaflow/src/test/java/com/powsybl/dynaflow/json/JsonDynaFlowParametersSerializerTest.java +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/json/JsonDynaFlowParametersSerializerTest.java @@ -15,10 +15,9 @@ import org.junit.jupiter.api.Test; import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.*; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; /** @@ -37,7 +36,7 @@ void testDeserialize() { double expectedStopTime = 100.; double expectedPrecision = 0.; double expectedTimeOfEvent = 10.; - List expectedChosenOutputs = Arrays.asList(DynaFlowConstants.OutputTypes.STEADYSTATE.name(), DynaFlowConstants.OutputTypes.TIMELINE.name()); + Set expectedChosenOutputs = Set.of(DynaFlowConstants.OutputTypes.STEADYSTATE, DynaFlowConstants.OutputTypes.TIMELINE); double expectedTimeStep = 2.6; LoadFlowParameters lfParameters = LoadFlowParameters.load(); @@ -56,9 +55,10 @@ void testDeserialize() { assertEquals(expectedStopTime, dynaFlowParameters.getStopTime(), 0.1d); assertEquals(expectedPrecision, dynaFlowParameters.getPrecision(), 0.1d); assertEquals(expectedTimeOfEvent, dynaFlowParameters.getTimeOfEvent(), 0.1d); - assertArrayEquals(expectedChosenOutputs.toArray(), dynaFlowParameters.getChosenOutputs().toArray()); + assertThat(dynaFlowParameters.getChosenOutputs()).containsExactlyInAnyOrderElementsOf(expectedChosenOutputs); assertEquals(expectedTimeStep, dynaFlowParameters.getTimeStep(), 0.1d); assertEquals(DynaFlowConstants.StartingPointMode.WARM, dynaFlowParameters.getStartingPointMode()); + assertFalse(dynaFlowParameters.isMergeLoads()); assertTrue(lfParameters.isTransformerVoltageControlOn()); assertFalse(lfParameters.isPhaseShifterRegulationOn()); @@ -84,9 +84,10 @@ void roundTripParameters() throws IOException { .setStopTime(100.) .setPrecision(0.) .setTimeOfEvent(10.) - .setChosenOutputs(Collections.singletonList(DynaFlowConstants.OutputTypes.STEADYSTATE.name())) + .setChosenOutputs(Set.of(DynaFlowConstants.OutputTypes.STEADYSTATE)) .setTimeStep(2.6) - .setStartingPointMode(DynaFlowConstants.StartingPointMode.WARM); + .setStartingPointMode(DynaFlowConstants.StartingPointMode.WARM) + .setMergeLoads(false); parameters.addExtension(DynaFlowParameters.class, params); diff --git a/dynaflow/src/test/resources/dynaflow_default_serialization.json b/dynaflow/src/test/resources/dynaflow_default_serialization.json index d1f587fe7..2cf51df50 100644 --- a/dynaflow/src/test/resources/dynaflow_default_serialization.json +++ b/dynaflow/src/test/resources/dynaflow_default_serialization.json @@ -18,7 +18,17 @@ "dcPowerFactor" : 1.0, "extensions" : { "DynaFlowParameters" : { - "chosenOutputs" : [ "TIMELINE" ] + "svcRegulationOn" : true, + "shuntRegulationOn" : true, + "automaticSlackBusOn" : true, + "dsoVoltageLevel" : 45.0, + "activePowerCompensation" : "PMAX", + "startTime" : 0.0, + "stopTime" : 100.0, + "chosenOutputs" : [ "TIMELINE" ], + "timeStep" : 10.0, + "startingPointMode" : "warm", + "mergeLoads" : true } } } \ No newline at end of file diff --git a/dynaflow/src/test/resources/dynaflow_parameters_set_serialization.json b/dynaflow/src/test/resources/dynaflow_parameters_set_serialization.json index 605143a3c..31c68066e 100644 --- a/dynaflow/src/test/resources/dynaflow_parameters_set_serialization.json +++ b/dynaflow/src/test/resources/dynaflow_parameters_set_serialization.json @@ -31,6 +31,7 @@ "chosenOutputs" : [ "STEADYSTATE" ], "timeStep" : 2.6, "startingPointMode" : "warm", + "mergeLoads" : false, "sa" : { "timeOfEvent" : 10.0 } diff --git a/dynaflow/src/test/resources/params_default.json b/dynaflow/src/test/resources/params_default.json index 8aba0278e..13db75192 100644 --- a/dynaflow/src/test/resources/params_default.json +++ b/dynaflow/src/test/resources/params_default.json @@ -1,7 +1,16 @@ { "dfl-config" : { + "SVCRegulationOn" : true, + "ShuntRegulationOn" : true, + "AutomaticSlackBusOn" : true, + "DsoVoltageLevel" : 45.0, "InfiniteReactiveLimits" : true, + "ActivePowerCompensation" : "PMAX", + "StartTime" : 0.0, + "StopTime" : 100.0, "ChosenOutputs" : [ "TIMELINE" ], + "TimeStep" : 10.0, + "StartingPointMode" : "warm", "OutputDir" : "dynaflow/workingDir" } } \ No newline at end of file