diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowParameters.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowParameters.java index 78314fe1f..18562220f 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowParameters.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowParameters.java @@ -6,8 +6,6 @@ */ package com.powsybl.dynaflow; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.core.JsonGenerator; import com.google.common.base.MoreObjects; import com.powsybl.commons.config.ModuleConfig; import com.powsybl.commons.config.PlatformConfig; @@ -24,7 +22,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.util.*; import java.util.function.BiConsumer; import java.util.stream.Collectors; @@ -38,45 +35,6 @@ public class DynaFlowParameters extends AbstractExtension { private static final Logger LOGGER = LoggerFactory.getLogger(DynaFlowParameters.class); - - /** - * Inner class dedicated to Security Analysis (SA) namespace - */ - 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 = DEFAULT_TIME_OF_EVENT; - - public Double getTimeOfEvent() { - return timeOfEvent; - } - - public void setTimeOfEvent(Double timeOfEvent) { - this.timeOfEvent = timeOfEvent; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper("").omitNullValues() - .add(TIME_OF_EVENT, timeOfEvent).toString(); - } - - public static void writeJson(JsonGenerator jsonGenerator, DynaFlowParameters dynaFlowParameters) throws IOException { - if (dynaFlowParameters.getSa().isSerializable()) { - jsonGenerator.writeObjectFieldStart("sa"); - jsonGenerator.writeNumberField("TimeOfEvent", dynaFlowParameters.getTimeOfEvent()); - jsonGenerator.writeEndObject(); - } - } - - @JsonIgnore - public boolean isSerializable() { - return timeOfEvent != null; - } - } - private static final String CHOSEN_OUTPUT_STRING_DELIMITER = ","; private static final String SVC_REGULATION_ON = "svcRegulationOn"; private static final String SHUNT_REGULATION_ON = "shuntRegulationOn"; @@ -122,7 +80,6 @@ private static > List getEnumPossibleValues(Class e 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)), @@ -138,7 +95,6 @@ private static > List getEnumPossibleValues(Class e private double startTime = DEFAULT_START_TIME; private double stopTime = DEFAULT_STOP_TIME; private Double precision = null; - private Sa securityAnalysis = null; private EnumSet chosenOutputs = DEFAULT_CHOSEN_OUTPUTS; private double timeStep = DEFAULT_TIME_STEP; private StartingPointMode startingPointMode = DEFAULT_STARTING_POINT_MODE; @@ -234,19 +190,6 @@ public DynaFlowParameters setPrecision(Double precision) { return this; } - @JsonIgnore - public Double getTimeOfEvent() { - return securityAnalysis == null ? null : securityAnalysis.getTimeOfEvent(); - } - - public DynaFlowParameters setTimeOfEvent(Double timeOfEvent) { - if (this.securityAnalysis == null) { - securityAnalysis = new Sa(); - } - securityAnalysis.setTimeOfEvent(timeOfEvent); - return this; - } - public Set getChosenOutputs() { return chosenOutputs; } @@ -279,15 +222,6 @@ public DynaFlowParameters setStartingPointMode(StartingPointMode startingPointMo return this; } - public Sa getSa() { - return this.securityAnalysis; - } - - public DynaFlowParameters setSa(Sa securityAnalysis) { - this.securityAnalysis = securityAnalysis; - return this; - } - public boolean isMergeLoads() { return mergeLoads; } @@ -315,7 +249,6 @@ public String toString() { .add(START_TIME, startTime) .add(STOP_TIME, stopTime) .add(PRECISION_NAME, precision) - .add(Sa.SECURITY_ANALYSIS, securityAnalysis) .add(CHOSEN_OUTPUTS, chosenOutputs) .add(TIME_STEP, timeStep) .add(STARTING_POINT_MODE, startingPointMode) @@ -326,10 +259,8 @@ public String toString() { public static DynaFlowParameters load(PlatformConfig platformConfig) { Objects.requireNonNull(platformConfig); DynaFlowParameters parameters = new DynaFlowParameters(); - platformConfig.getOptionalModuleConfig(MODULE_SPECIFIC_PARAMETERS) .ifPresent(config -> load(parameters, config)); - return parameters; } @@ -341,6 +272,12 @@ public static DynaFlowParameters load(ModuleConfig config) { return parameters; } + public static DynaFlowParameters load(Map properties) { + DynaFlowParameters parameters = new DynaFlowParameters(); + parameters.update(properties); + return parameters; + } + private static void load(DynaFlowParameters parameters, ModuleConfig config) { config.getOptionalBooleanProperty(SVC_REGULATION_ON).ifPresent(parameters::setSvcRegulationOn); config.getOptionalBooleanProperty(SHUNT_REGULATION_ON).ifPresent(parameters::setShuntRegulationOn); @@ -352,7 +289,6 @@ private static void load(DynaFlowParameters parameters, ModuleConfig config) { config.getOptionalDoubleProperty(START_TIME).ifPresent(parameters::setStartTime); config.getOptionalDoubleProperty(STOP_TIME).ifPresent(parameters::setStopTime); config.getOptionalDoubleProperty(PRECISION_NAME).ifPresent(parameters::setPrecision); - config.getOptionalDoubleProperty(Sa.TIME_OF_EVENT).ifPresent(parameters::setTimeOfEvent); 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); @@ -390,12 +326,6 @@ public void update(Map properties) { Optional.ofNullable(properties.get(START_TIME)).ifPresent(prop -> setStartTime(Double.parseDouble(prop))); Optional.ofNullable(properties.get(STOP_TIME)).ifPresent(prop -> setStopTime(Double.parseDouble(prop))); Optional.ofNullable(properties.get(PRECISION_NAME)).ifPresent(prop -> setPrecision(Double.parseDouble(prop))); - Optional.ofNullable(properties.get(Sa.TIME_OF_EVENT)).ifPresent(prop -> { - if (securityAnalysis == null) { - securityAnalysis = new Sa(); - } - securityAnalysis.setTimeOfEvent(Double.parseDouble(prop)); - }); Optional.ofNullable(properties.get(CHOSEN_OUTPUTS)).ifPresent(prop -> 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))); @@ -417,7 +347,6 @@ public Map createMapFromParameters() { 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())); } @@ -432,10 +361,4 @@ private void addNotNullEntry(String key, Object value, BiConsumer properties) { - DynaFlowParameters parameters = new DynaFlowParameters(); - parameters.update(properties); - return parameters; - } } diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java index b580df72b..2a19da3e1 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java @@ -73,10 +73,10 @@ public static Command getVersionCommand(DynaFlowConfig config) { .build(); } - private static DynaFlowParameters getParametersExt(LoadFlowParameters parameters) { + static DynaFlowParameters getParametersExt(LoadFlowParameters parameters) { DynaFlowParameters parametersExt = parameters.getExtension(DynaFlowParameters.class); if (parametersExt == null) { - parametersExt = new DynaFlowParameters(); + return new DynaFlowParameters(); } return parametersExt; } diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisHandler.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisHandler.java index 314c2ed94..960ba6403 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisHandler.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisHandler.java @@ -106,15 +106,9 @@ private static void writeContingencies(List contingencies, Path wor private static void writeParameters(SecurityAnalysisParameters securityAnalysisParameters, Path workingDir) throws IOException { // TODO(Luma) Take into account also Security Analysis parameters LoadFlowParameters loadFlowParameters = securityAnalysisParameters.getLoadFlowParameters(); - DynaFlowParameters dynaFlowParameters = getParametersExt(loadFlowParameters); - DynaFlowConfigSerializer.serialize(loadFlowParameters, dynaFlowParameters, Path.of("."), workingDir.resolve(CONFIG_FILENAME)); - } - - private static DynaFlowParameters getParametersExt(LoadFlowParameters parameters) { - DynaFlowParameters parametersExt = parameters.getExtension(DynaFlowParameters.class); - if (parametersExt == null) { - parametersExt = new DynaFlowParameters(); - } - return parametersExt; + DynaFlowParameters dynaFlowParameters = DynaFlowProvider.getParametersExt(loadFlowParameters); + DynaFlowSecurityAnalysisParameters dynaFlowSecurityAnalysisParameters = DynaFlowSecurityAnalysisProvider.getParametersExt(securityAnalysisParameters); + DynaFlowConfigSerializer.serialize(loadFlowParameters, dynaFlowParameters, dynaFlowSecurityAnalysisParameters, + Path.of("."), workingDir.resolve(CONFIG_FILENAME)); } } diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisParameters.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisParameters.java new file mode 100644 index 000000000..705076b5e --- /dev/null +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisParameters.java @@ -0,0 +1,84 @@ +/** + * 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.dynaflow; + +import com.google.common.base.MoreObjects; +import com.powsybl.commons.config.ModuleConfig; +import com.powsybl.commons.config.PlatformConfig; +import com.powsybl.commons.extensions.AbstractExtension; +import com.powsybl.security.SecurityAnalysisParameters; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import static com.powsybl.dynaflow.DynaFlowSecurityAnalysisProvider.MODULE_SPECIFIC_PARAMETERS; + +/** + * @author Laurent Issertial {@literal } + */ +public class DynaFlowSecurityAnalysisParameters extends AbstractExtension { + + private static final double DEFAULT_TIME_OF_EVENT = 10d; + private static final String TIME_OF_EVENT = "timeOfEvent"; + public static final List SPECIFIC_PARAMETER_NAMES = List.of(TIME_OF_EVENT); + + private Double timeOfEvent = DEFAULT_TIME_OF_EVENT; + + public Double getTimeOfEvent() { + return timeOfEvent; + } + + public DynaFlowSecurityAnalysisParameters setTimeOfEvent(Double timeOfEvent) { + this.timeOfEvent = timeOfEvent; + return this; + } + + @Override + public String getName() { + return "DynaFlowSecurityAnalysisParameters"; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper("").omitNullValues() + .add(TIME_OF_EVENT, timeOfEvent).toString(); + } + + public static DynaFlowSecurityAnalysisParameters load(PlatformConfig platformConfig) { + Objects.requireNonNull(platformConfig); + DynaFlowSecurityAnalysisParameters parameters = new DynaFlowSecurityAnalysisParameters(); + platformConfig.getOptionalModuleConfig(MODULE_SPECIFIC_PARAMETERS) + .ifPresent(config -> load(parameters, config)); + return parameters; + } + + public static DynaFlowSecurityAnalysisParameters load(ModuleConfig config) { + DynaFlowSecurityAnalysisParameters parameters = new DynaFlowSecurityAnalysisParameters(); + if (config != null) { + load(parameters, config); + } + return parameters; + } + + public static DynaFlowSecurityAnalysisParameters load(Map properties) { + DynaFlowSecurityAnalysisParameters parameters = new DynaFlowSecurityAnalysisParameters(); + parameters.update(properties); + return parameters; + } + + private static void load(DynaFlowSecurityAnalysisParameters parameters, ModuleConfig config) { + config.getOptionalDoubleProperty(TIME_OF_EVENT).ifPresent(parameters::setTimeOfEvent); + } + + public void update(Map properties) { + Objects.requireNonNull(properties); + Optional.ofNullable(properties.get(TIME_OF_EVENT)).ifPresent(prop -> setTimeOfEvent(Double.parseDouble(prop))); + } +} diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisProvider.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisProvider.java index fb02e1bde..6bee63dbf 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisProvider.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisProvider.java @@ -7,24 +7,27 @@ package com.powsybl.dynaflow; import com.google.auto.service.AutoService; +import com.powsybl.commons.config.PlatformConfig; +import com.powsybl.commons.extensions.Extension; +import com.powsybl.commons.extensions.ExtensionJsonSerializer; import com.powsybl.commons.report.ReportNode; import com.powsybl.computation.Command; import com.powsybl.computation.ExecutionEnvironment; import com.powsybl.computation.SimpleCommandBuilder; import com.powsybl.contingency.ContingenciesProvider; import com.powsybl.contingency.Contingency; +import com.powsybl.dynaflow.json.JsonDynaFlowSaParametersSerializer; import com.powsybl.dynawo.commons.DynawoUtil; import com.powsybl.dynawo.commons.PowsyblDynawoVersion; import com.powsybl.iidm.network.Network; +import com.powsybl.security.SecurityAnalysisParameters; import com.powsybl.security.SecurityAnalysisProvider; import com.powsybl.security.SecurityAnalysisReport; import com.powsybl.security.SecurityAnalysisRunParameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; @@ -38,6 +41,7 @@ @AutoService(SecurityAnalysisProvider.class) public class DynaFlowSecurityAnalysisProvider implements SecurityAnalysisProvider { + public static final String MODULE_SPECIFIC_PARAMETERS = "dynaflow-security-analysis-default-parameters"; private static final Logger LOG = LoggerFactory.getLogger(DynaFlowSecurityAnalysisProvider.class); private static final String WORKING_DIR_PREFIX = "dynaflow_sa_"; private final Supplier configSupplier; @@ -50,6 +54,17 @@ public DynaFlowSecurityAnalysisProvider(Supplier configSupplier) this.configSupplier = Objects.requireNonNull(configSupplier); } + public static Command getCommand(DynaFlowConfig config) { + List args = Arrays.asList("--network", IIDM_FILENAME, + "--config", CONFIG_FILENAME, + "--contingencies", CONTINGENCIES_FILENAME); + return new SimpleCommandBuilder() + .id("dynaflow_sa") + .program(config.getProgram()) + .args(args) + .build(); + } + @Override public CompletableFuture run(Network network, String workingVariantId, @@ -83,19 +98,46 @@ public String getName() { return DYNAFLOW_NAME; } + public Optional getLoadFlowProviderName() { + return Optional.of(DYNAFLOW_NAME); + } + @Override public String getVersion() { return new PowsyblDynawoVersion().getMavenProjectVersion(); } - public static Command getCommand(DynaFlowConfig config) { - List args = Arrays.asList("--network", IIDM_FILENAME, - "--config", CONFIG_FILENAME, - "--contingencies", CONTINGENCIES_FILENAME); - return new SimpleCommandBuilder() - .id("dynaflow_sa") - .program(config.getProgram()) - .args(args) - .build(); + @Override + public Optional> loadSpecificParameters(PlatformConfig platformConfig) { + // if not specified, dynaflow sa parameters must be default here + return Optional.of(DynaFlowSecurityAnalysisParameters.load(platformConfig)); + } + + @Override + public Optional> loadSpecificParameters(Map properties) { + return Optional.of(DynaFlowSecurityAnalysisParameters.load(properties)); + } + + @Override + public void updateSpecificParameters(Extension extension, Map properties) { + getParametersExt(extension.getExtendable()).update(properties); + } + + @Override + public List getSpecificParametersNames() { + return DynaFlowSecurityAnalysisParameters.SPECIFIC_PARAMETER_NAMES; + } + + @Override + public Optional getSpecificParametersSerializer() { + return Optional.of(new JsonDynaFlowSaParametersSerializer()); + } + + static DynaFlowSecurityAnalysisParameters getParametersExt(SecurityAnalysisParameters parameters) { + DynaFlowSecurityAnalysisParameters parametersExt = parameters.getExtension(DynaFlowSecurityAnalysisParameters.class); + if (parametersExt == null) { + return new DynaFlowSecurityAnalysisParameters(); + } + return parametersExt; } } 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 5bb8aa295..70f152563 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/json/DynaFlowConfigSerializer.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/json/DynaFlowConfigSerializer.java @@ -10,6 +10,7 @@ import com.powsybl.commons.json.JsonUtil; import com.powsybl.dynaflow.DynaFlowConstants; import com.powsybl.dynaflow.DynaFlowParameters; +import com.powsybl.dynaflow.DynaFlowSecurityAnalysisParameters; import com.powsybl.loadflow.LoadFlowParameters; import java.io.BufferedWriter; @@ -30,50 +31,32 @@ public final class DynaFlowConfigSerializer { private DynaFlowConfigSerializer() { } + public static void serialize(LoadFlowParameters lfParameters, DynaFlowParameters dynaFlowParameters, + DynaFlowSecurityAnalysisParameters saParameters, Path workingDir, Path file) throws IOException { + try (BufferedWriter writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) { + JsonUtil.writeJson(writer, jsonGenerator -> serialize(lfParameters, dynaFlowParameters, saParameters, workingDir, jsonGenerator)); + } + } + public static void serialize(LoadFlowParameters lfParameters, DynaFlowParameters dynaFlowParameters, Path workingDir, Path file) throws IOException { try (BufferedWriter writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) { - JsonUtil.writeJson(writer, jsonGenerator -> serialize(lfParameters, dynaFlowParameters, workingDir, jsonGenerator)); + JsonUtil.writeJson(writer, jsonGenerator -> serialize(lfParameters, dynaFlowParameters, null, workingDir, jsonGenerator)); } } public static void serialize(LoadFlowParameters lfParameters, DynaFlowParameters dynaFlowParameters, Path workingDir, Writer writer) { - JsonUtil.writeJson(writer, jsonGenerator -> serialize(lfParameters, dynaFlowParameters, workingDir, jsonGenerator)); + JsonUtil.writeJson(writer, jsonGenerator -> serialize(lfParameters, dynaFlowParameters, null, workingDir, jsonGenerator)); } - private static void serialize(LoadFlowParameters lfParameters, DynaFlowParameters dynaFlowParameters, Path workingDir, JsonGenerator jsonGenerator) { + private static void serialize(LoadFlowParameters lfParameters, DynaFlowParameters dynaFlowParameters, + DynaFlowSecurityAnalysisParameters saParameters, Path workingDir, JsonGenerator jsonGenerator) { try { jsonGenerator.writeStartObject(); jsonGenerator.writeObjectFieldStart("dfl-config"); - writeNonNullField(jsonGenerator, "SVCRegulationOn", dynaFlowParameters.getSvcRegulationOn()); - writeNonNullField(jsonGenerator, "ShuntRegulationOn", dynaFlowParameters.getShuntRegulationOn()); - writeNonNullField(jsonGenerator, "AutomaticSlackBusOn", dynaFlowParameters.getAutomaticSlackBusOn()); - writeNonNullField(jsonGenerator, "DsoVoltageLevel", dynaFlowParameters.getDsoVoltageLevel()); - jsonGenerator.writeBooleanField("InfiniteReactiveLimits", !lfParameters.isUseReactiveLimits()); - - if (dynaFlowParameters.getActivePowerCompensation() != null) { - jsonGenerator.writeStringField("ActivePowerCompensation", dynaFlowParameters.getActivePowerCompensation().name()); - } - writeNonNullField(jsonGenerator, "SettingPath", dynaFlowParameters.getSettingPath()); - writeNonNullField(jsonGenerator, "AssemblingPath", dynaFlowParameters.getAssemblingPath()); - writeNonNullField(jsonGenerator, "StartTime", dynaFlowParameters.getStartTime()); - writeNonNullField(jsonGenerator, "StopTime", dynaFlowParameters.getStopTime()); - writeNonNullField(jsonGenerator, "Precision", dynaFlowParameters.getPrecision()); - - if (dynaFlowParameters.getSa() != null) { - DynaFlowParameters.Sa.writeJson(jsonGenerator, dynaFlowParameters); - } - if (dynaFlowParameters.getChosenOutputs() != null) { - jsonGenerator.writeFieldName("ChosenOutputs"); - jsonGenerator.writeStartArray(); - for (DynaFlowConstants.OutputTypes outputType : dynaFlowParameters.getChosenOutputs()) { - jsonGenerator.writeString(outputType.name()); - } - jsonGenerator.writeEndArray(); - } - - writeNonNullField(jsonGenerator, "TimeStep", dynaFlowParameters.getTimeStep()); - if (dynaFlowParameters.getStartingPointMode() != null) { - jsonGenerator.writeStringField("StartingPointMode", dynaFlowParameters.getStartingPointMode().getName()); + serialize(lfParameters, jsonGenerator); + serialize(dynaFlowParameters, jsonGenerator); + if (saParameters != null) { + serialize(saParameters, jsonGenerator); } jsonGenerator.writeStringField("OutputDir", workingDir.toString()); jsonGenerator.writeEndObject(); @@ -83,6 +66,46 @@ private static void serialize(LoadFlowParameters lfParameters, DynaFlowParameter } } + private static void serialize(DynaFlowParameters dynaFlowParameters, JsonGenerator jsonGenerator) throws IOException { + writeNonNullField(jsonGenerator, "SVCRegulationOn", dynaFlowParameters.getSvcRegulationOn()); + writeNonNullField(jsonGenerator, "ShuntRegulationOn", dynaFlowParameters.getShuntRegulationOn()); + writeNonNullField(jsonGenerator, "AutomaticSlackBusOn", dynaFlowParameters.getAutomaticSlackBusOn()); + writeNonNullField(jsonGenerator, "DsoVoltageLevel", dynaFlowParameters.getDsoVoltageLevel()); + + if (dynaFlowParameters.getActivePowerCompensation() != null) { + jsonGenerator.writeStringField("ActivePowerCompensation", dynaFlowParameters.getActivePowerCompensation().name()); + } + writeNonNullField(jsonGenerator, "SettingPath", dynaFlowParameters.getSettingPath()); + writeNonNullField(jsonGenerator, "AssemblingPath", dynaFlowParameters.getAssemblingPath()); + writeNonNullField(jsonGenerator, "StartTime", dynaFlowParameters.getStartTime()); + writeNonNullField(jsonGenerator, "StopTime", dynaFlowParameters.getStopTime()); + writeNonNullField(jsonGenerator, "Precision", dynaFlowParameters.getPrecision()); + + if (dynaFlowParameters.getChosenOutputs() != null) { + jsonGenerator.writeFieldName("ChosenOutputs"); + jsonGenerator.writeStartArray(); + for (DynaFlowConstants.OutputTypes outputType : dynaFlowParameters.getChosenOutputs()) { + jsonGenerator.writeString(outputType.name()); + } + jsonGenerator.writeEndArray(); + } + + writeNonNullField(jsonGenerator, "TimeStep", dynaFlowParameters.getTimeStep()); + if (dynaFlowParameters.getStartingPointMode() != null) { + jsonGenerator.writeStringField("StartingPointMode", dynaFlowParameters.getStartingPointMode().getName()); + } + } + + private static void serialize(LoadFlowParameters lfParameters, JsonGenerator jsonGenerator) throws IOException { + jsonGenerator.writeBooleanField("InfiniteReactiveLimits", !lfParameters.isUseReactiveLimits()); + } + + private static void serialize(DynaFlowSecurityAnalysisParameters saParameters, JsonGenerator jsonGenerator) throws IOException { + jsonGenerator.writeObjectFieldStart("sa"); + jsonGenerator.writeNumberField("TimeOfEvent", saParameters.getTimeOfEvent()); + jsonGenerator.writeEndObject(); + } + private static void writeNonNullField(JsonGenerator jsonGenerator, String fieldName, Boolean value) throws IOException { if (value != null) { jsonGenerator.writeBooleanField(fieldName, value); diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/json/JsonDynaFlowSaParametersSerializer.java b/dynaflow/src/main/java/com/powsybl/dynaflow/json/JsonDynaFlowSaParametersSerializer.java new file mode 100644 index 000000000..ba7c562e6 --- /dev/null +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/json/JsonDynaFlowSaParametersSerializer.java @@ -0,0 +1,85 @@ +/** + * 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.dynaflow.json; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.google.auto.service.AutoService; +import com.powsybl.commons.extensions.ExtensionJsonSerializer; +import com.powsybl.commons.json.JsonUtil; +import com.powsybl.dynaflow.DynaFlowSecurityAnalysisParameters; +import com.powsybl.security.SecurityAnalysisParameters; + +import java.io.IOException; + +/** + * Represents {@link DynaFlowSecurityAnalysisParameters} as a Json extension of {@link SecurityAnalysisParameters} + * @author Laurent Issertial {@literal } + */ +@AutoService(ExtensionJsonSerializer.class) +public class JsonDynaFlowSaParametersSerializer implements + ExtensionJsonSerializer { + + @Override + public String getCategoryName() { + return "security-analysis-parameters"; + } + + @Override + public Class getExtensionClass() { + return DynaFlowSecurityAnalysisParameters.class; + } + + @Override + public String getExtensionName() { + return "DynaFlowSecurityAnalysisParameters"; + } + + /** + * Specifies serialization for our extension: ignore name et extendable + */ + private interface SerializationSpec { + + @JsonIgnore + String getName(); + + @JsonIgnore + SecurityAnalysisParameters getExtendable(); + } + + private static ObjectMapper createMapper() { + return JsonUtil.createObjectMapper() + .addMixIn(DynaFlowSecurityAnalysisParameters.class, SerializationSpec.class) + .setSerializationInclusion(JsonInclude.Include.NON_ABSENT); + } + + @Override + public void serialize(DynaFlowSecurityAnalysisParameters jsonDynaFlowParameters, JsonGenerator jsonGenerator, + SerializerProvider provider) throws IOException { + createMapper().writeValue(jsonGenerator, jsonDynaFlowParameters); + } + + @Override + public DynaFlowSecurityAnalysisParameters deserialize(JsonParser parser, DeserializationContext context) throws IOException { + return createMapper().readValue(parser, DynaFlowSecurityAnalysisParameters.class); + } + + @Override + public DynaFlowSecurityAnalysisParameters deserializeAndUpdate(JsonParser parser, DeserializationContext context, + DynaFlowSecurityAnalysisParameters toUpdateParameters) throws IOException { + ObjectMapper objectMapper = createMapper(); + ObjectReader objectReader = objectMapper.readerForUpdating(toUpdateParameters); + return objectReader.readValue(parser, DynaFlowSecurityAnalysisParameters.class); + } +} diff --git a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowParametersTest.java b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowParametersTest.java index e690e54f6..2c0c1b24e 100644 --- a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowParametersTest.java +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowParametersTest.java @@ -87,7 +87,7 @@ void checkParameters() { moduleConfig.setStringProperty("startingPointMode", startingPointMode.getName()); moduleConfig.setStringProperty("mergeLoads", Boolean.toString(mergeLoads)); - DynaFlowParameters parameters = DynaFlowParameters.load(platformConfig); + DynaFlowParameters parameters = DynaFlowParameters.load(moduleConfig); assertEquals(svcRegulationOn, parameters.getSvcRegulationOn()); assertEquals(shuntRegulationOn, parameters.getShuntRegulationOn()); @@ -99,7 +99,6 @@ void checkParameters() { assertEquals(startTime, parameters.getStartTime(), 0.1d); assertEquals(stopTime, parameters.getStopTime(), 0.1d); assertEquals(precision, parameters.getPrecision(), 0.1d); - assertEquals(timeOfEvent, parameters.getTimeOfEvent(), 0.1d); assertThat(parameters.getChosenOutputs()).map(OutputTypes::name).containsExactlyInAnyOrderElementsOf(chosenOutputs); assertEquals(timeStep, parameters.getTimeStep(), 0.1d); assertEquals(startingPointMode, parameters.getStartingPointMode()); @@ -125,7 +124,6 @@ void checkDefaultParameters() { assertEquals(0d, parametersExt.getStartTime()); assertEquals(100d, parametersExt.getStopTime()); assertNull(parametersExt.getPrecision()); - assertNull(parametersExt.getSa()); assertThat(parametersExt.getChosenOutputs()).containsExactly(OutputTypes.TIMELINE); assertEquals(10d, parametersExt.getTimeStep()); assertEquals(StartingPointMode.WARM, parametersExt.getStartingPointMode()); @@ -181,8 +179,6 @@ void checkAllParametersAssignedToString() { ", startTime=" + startTime + ", stopTime=" + stopTime + ", precision=" + precision + - ", sa=" + - "{timeOfEvent=" + timeOfEvent + "}" + ", chosenOutputs=" + chosenOutputs + ", timeStep=" + timeStep + ", startingPointMode=" + startingPointMode + @@ -228,7 +224,6 @@ void parametersSerialization() throws IOException { .setStartTime(0.) .setStopTime(100.) .setPrecision(0.) - .setTimeOfEvent(10.) .setChosenOutputs(Set.of(OutputTypes.STEADYSTATE)) .setTimeStep(2.6) .setStartingPointMode(StartingPointMode.WARM) @@ -294,7 +289,6 @@ void loadMapDynaflowParameters() { assertEquals(startTime, dynaFlowParameters.getStartTime(), 0.1d); assertEquals(stopTime, dynaFlowParameters.getStopTime(), 0.1d); assertEquals(precision, dynaFlowParameters.getPrecision(), 0.1d); - assertEquals(timeOfEvent, dynaFlowParameters.getTimeOfEvent(), 0.1d); assertThat(dynaFlowParameters.getChosenOutputs()).containsExactlyInAnyOrderElementsOf(chosenOutputs); assertEquals(timeStep, dynaFlowParameters.getTimeStep(), 0.1d); assertEquals(startingPointMode, dynaFlowParameters.getStartingPointMode()); diff --git a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisParametersTest.java b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisParametersTest.java new file mode 100644 index 000000000..0a84761db --- /dev/null +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisParametersTest.java @@ -0,0 +1,103 @@ +/** + * 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.dynaflow; + +import com.google.common.jimfs.Configuration; +import com.google.common.jimfs.Jimfs; +import com.powsybl.commons.config.InMemoryPlatformConfig; +import com.powsybl.commons.config.MapModuleConfig; +import com.powsybl.commons.test.AbstractSerDeTest; +import com.powsybl.dynaflow.json.DynaFlowConfigSerializer; +import com.powsybl.loadflow.LoadFlowParameters; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; + +import static com.powsybl.commons.test.ComparisonUtils.assertTxtEquals; +import static com.powsybl.dynaflow.DynaFlowSecurityAnalysisProvider.MODULE_SPECIFIC_PARAMETERS; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * @author Laurent Issertial {@literal } + */ +public class DynaFlowSecurityAnalysisParametersTest extends AbstractSerDeTest { + + private InMemoryPlatformConfig platformConfig; + + @BeforeEach + @Override + public void setUp() { + fileSystem = Jimfs.newFileSystem(Configuration.unix()); + platformConfig = new InMemoryPlatformConfig(fileSystem); + } + + @AfterEach + @Override + public void tearDown() throws IOException { + fileSystem.close(); + } + + @Test + void checkParameters() { + double timeOfEvent = 24.; + MapModuleConfig moduleConfig = platformConfig.createModuleConfig(MODULE_SPECIFIC_PARAMETERS); + moduleConfig.setStringProperty("timeOfEvent", Double.toString(timeOfEvent)); + DynaFlowSecurityAnalysisParameters saParam = DynaFlowSecurityAnalysisParameters.load(moduleConfig); + assertEquals(timeOfEvent, saParam.getTimeOfEvent()); + } + + @Test + void checkAllParametersAssignedToString() { + DynaFlowSecurityAnalysisParameters saParam = new DynaFlowSecurityAnalysisParameters(); + saParam.update(Map.of("timeOfEvent", Double.toString(23d))); + assertEquals("{timeOfEvent=23.0}", saParam.toString()); + } + + @Test + void defaultParametersSerialization() throws IOException { + Path workingDir = fileSystem.getPath("dynaflow_sa/workingDir"); + Path parameterFile = fileSystem.getPath(DynaFlowConstants.CONFIG_FILENAME); + DynaFlowConfigSerializer.serialize(LoadFlowParameters.load(platformConfig), + new DynaFlowParameters(), + new DynaFlowSecurityAnalysisParameters(), + workingDir, + parameterFile); + + try (InputStream actual = Files.newInputStream(parameterFile); + InputStream expected = getClass().getResourceAsStream("/params_default_sa.json")) { + assertNotNull(expected); + assertTxtEquals(expected, actual); + } + } + + @Test + void parametersSerialization() throws IOException { + DynaFlowSecurityAnalysisParameters saParam = new DynaFlowSecurityAnalysisParameters() + .setTimeOfEvent(20d); + Path workingDir = fileSystem.getPath("dynaflow_sa/workingDir"); + Path parameterFile = fileSystem.getPath(DynaFlowConstants.CONFIG_FILENAME); + DynaFlowConfigSerializer.serialize(LoadFlowParameters.load(platformConfig), + new DynaFlowParameters(), + saParam, + workingDir, + parameterFile); + + try (InputStream actual = Files.newInputStream(parameterFile); + InputStream expected = getClass().getResourceAsStream("/params_sa.json")) { + assertNotNull(expected); + assertTxtEquals(expected, actual); + } + } +} 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 44e474bd7..f19612f59 100644 --- a/dynaflow/src/test/java/com/powsybl/dynaflow/json/JsonDynaFlowParametersSerializerTest.java +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/json/JsonDynaFlowParametersSerializerTest.java @@ -35,7 +35,6 @@ void testDeserialize() { double expectedStartTime = 0.; double expectedStopTime = 100.; double expectedPrecision = 0.; - double expectedTimeOfEvent = 10.; Set expectedChosenOutputs = Set.of(DynaFlowConstants.OutputTypes.STEADYSTATE, DynaFlowConstants.OutputTypes.TIMELINE); double expectedTimeStep = 2.6; @@ -54,7 +53,6 @@ void testDeserialize() { assertEquals(expectedStartTime, dynaFlowParameters.getStartTime(), 0.1d); assertEquals(expectedStopTime, dynaFlowParameters.getStopTime(), 0.1d); assertEquals(expectedPrecision, dynaFlowParameters.getPrecision(), 0.1d); - assertEquals(expectedTimeOfEvent, dynaFlowParameters.getTimeOfEvent(), 0.1d); assertThat(dynaFlowParameters.getChosenOutputs()).containsExactlyInAnyOrderElementsOf(expectedChosenOutputs); assertEquals(expectedTimeStep, dynaFlowParameters.getTimeStep(), 0.1d); assertEquals(DynaFlowConstants.StartingPointMode.WARM, dynaFlowParameters.getStartingPointMode()); @@ -83,7 +81,6 @@ void roundTripParameters() throws IOException { .setStartTime(0.) .setStopTime(100.) .setPrecision(0.) - .setTimeOfEvent(10.) .setChosenOutputs(Set.of(DynaFlowConstants.OutputTypes.STEADYSTATE)) .setTimeStep(2.6) .setStartingPointMode(DynaFlowConstants.StartingPointMode.WARM) diff --git a/dynaflow/src/test/java/com/powsybl/dynaflow/json/JsonDynaFlowSaParametersSerializerTest.java b/dynaflow/src/test/java/com/powsybl/dynaflow/json/JsonDynaFlowSaParametersSerializerTest.java new file mode 100644 index 000000000..33e42d063 --- /dev/null +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/json/JsonDynaFlowSaParametersSerializerTest.java @@ -0,0 +1,43 @@ +/** + * 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.dynaflow.json; + +import com.powsybl.commons.config.InMemoryPlatformConfig; +import com.powsybl.commons.test.AbstractSerDeTest; +import com.powsybl.dynaflow.DynaFlowSecurityAnalysisParameters; +import com.powsybl.security.SecurityAnalysisParameters; +import com.powsybl.security.json.JsonSecurityAnalysisParameters; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +/** + * @author Laurent Issertial {@literal } + */ +class JsonDynaFlowSaParametersSerializerTest extends AbstractSerDeTest { + + @Test + void roundTripParameters() throws IOException { + InMemoryPlatformConfig platformConfig = new InMemoryPlatformConfig(fileSystem); + SecurityAnalysisParameters parameters = SecurityAnalysisParameters.load(platformConfig); + DynaFlowSecurityAnalysisParameters params = new DynaFlowSecurityAnalysisParameters() + .setTimeOfEvent(23.); + parameters.addExtension(DynaFlowSecurityAnalysisParameters.class, params); + + roundTripTest(parameters, JsonSecurityAnalysisParameters::write, + JsonSecurityAnalysisParameters::read, "/dynaflow_sa_parameters_set_serialization.json"); + } + + @Test + void serializeWithDefaultDynaflowSaParameters() throws IOException { + InMemoryPlatformConfig platformConfig = new InMemoryPlatformConfig(fileSystem); + SecurityAnalysisParameters parameters = SecurityAnalysisParameters.load(platformConfig); + roundTripTest(parameters, JsonSecurityAnalysisParameters::write, + JsonSecurityAnalysisParameters::read, "/dynaflow_sa_default_serialization.json"); + } +} diff --git a/dynaflow/src/test/resources/config.json b/dynaflow/src/test/resources/config.json index 87af4e32b..52144df4e 100644 --- a/dynaflow/src/test/resources/config.json +++ b/dynaflow/src/test/resources/config.json @@ -17,9 +17,6 @@ "startTime" : 0.0, "stopTime" : 100.0, "precision" : 0.0, - "sa" : { - "timeOfEvent" : 10.0 - }, "chosenOutputs" : [ "STEADYSTATE", "TIMELINE" ], "timeStep" : 2.6, "startingPointMode" : "warm", diff --git a/dynaflow/src/test/resources/dynaflow_parameters_set_serialization.json b/dynaflow/src/test/resources/dynaflow_parameters_set_serialization.json index 31c68066e..64e78fb59 100644 --- a/dynaflow/src/test/resources/dynaflow_parameters_set_serialization.json +++ b/dynaflow/src/test/resources/dynaflow_parameters_set_serialization.json @@ -31,10 +31,7 @@ "chosenOutputs" : [ "STEADYSTATE" ], "timeStep" : 2.6, "startingPointMode" : "warm", - "mergeLoads" : false, - "sa" : { - "timeOfEvent" : 10.0 - } + "mergeLoads" : false } } } \ No newline at end of file diff --git a/dynaflow/src/test/resources/dynaflow_sa_default_serialization.json b/dynaflow/src/test/resources/dynaflow_sa_default_serialization.json new file mode 100644 index 000000000..24ab08798 --- /dev/null +++ b/dynaflow/src/test/resources/dynaflow_sa_default_serialization.json @@ -0,0 +1,50 @@ +{ + "version" : "1.2", + "increased-violations-parameters" : { + "flow-proportional-threshold" : 0.1, + "low-voltage-proportional-threshold" : 0.0, + "low-voltage-absolute-threshold" : 0.0, + "high-voltage-proportional-threshold" : 0.0, + "high-voltage-absolute-threshold" : 0.0 + }, + "intermediate-results-in-operator-strategy" : false, + "load-flow-parameters" : { + "version" : "1.9", + "voltageInitMode" : "UNIFORM_VALUES", + "transformerVoltageControlOn" : false, + "phaseShifterRegulationOn" : false, + "useReactiveLimits" : true, + "twtSplitShuntAdmittance" : false, + "shuntCompensatorVoltageControlOn" : false, + "readSlackBus" : true, + "writeSlackBus" : true, + "dc" : false, + "distributedSlack" : true, + "balanceType" : "PROPORTIONAL_TO_GENERATION_P_MAX", + "dcUseTransformerRatio" : true, + "countriesToBalance" : [ ], + "connectedComponentMode" : "MAIN", + "hvdcAcEmulation" : true, + "dcPowerFactor" : 1.0, + "extensions" : { + "DynaFlowParameters" : { + "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 + } + } + }, + "extensions" : { + "DynaFlowSecurityAnalysisParameters" : { + "timeOfEvent" : 10.0 + } + } +} \ No newline at end of file diff --git a/dynaflow/src/test/resources/dynaflow_sa_parameters_set_serialization.json b/dynaflow/src/test/resources/dynaflow_sa_parameters_set_serialization.json new file mode 100644 index 000000000..ae11d9988 --- /dev/null +++ b/dynaflow/src/test/resources/dynaflow_sa_parameters_set_serialization.json @@ -0,0 +1,50 @@ +{ + "version" : "1.2", + "increased-violations-parameters" : { + "flow-proportional-threshold" : 0.1, + "low-voltage-proportional-threshold" : 0.0, + "low-voltage-absolute-threshold" : 0.0, + "high-voltage-proportional-threshold" : 0.0, + "high-voltage-absolute-threshold" : 0.0 + }, + "intermediate-results-in-operator-strategy" : false, + "load-flow-parameters" : { + "version" : "1.9", + "voltageInitMode" : "UNIFORM_VALUES", + "transformerVoltageControlOn" : false, + "phaseShifterRegulationOn" : false, + "useReactiveLimits" : true, + "twtSplitShuntAdmittance" : false, + "shuntCompensatorVoltageControlOn" : false, + "readSlackBus" : true, + "writeSlackBus" : true, + "dc" : false, + "distributedSlack" : true, + "balanceType" : "PROPORTIONAL_TO_GENERATION_P_MAX", + "dcUseTransformerRatio" : true, + "countriesToBalance" : [ ], + "connectedComponentMode" : "MAIN", + "hvdcAcEmulation" : true, + "dcPowerFactor" : 1.0, + "extensions" : { + "DynaFlowParameters" : { + "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 + } + } + }, + "extensions" : { + "DynaFlowSecurityAnalysisParameters" : { + "timeOfEvent" : 23.0 + } + } +} \ No newline at end of file diff --git a/dynaflow/src/test/resources/params.json b/dynaflow/src/test/resources/params.json index 9c5d96ec0..4e33e987e 100644 --- a/dynaflow/src/test/resources/params.json +++ b/dynaflow/src/test/resources/params.json @@ -1,19 +1,16 @@ { "dfl-config" : { + "InfiniteReactiveLimits" : true, "SVCRegulationOn" : true, "ShuntRegulationOn" : false, "AutomaticSlackBusOn" : true, "DsoVoltageLevel" : 32.4, - "InfiniteReactiveLimits" : true, "ActivePowerCompensation" : "P", "SettingPath" : "path/to/settingFile", "AssemblingPath" : "path/to/assemblingFile", "StartTime" : 0.0, "StopTime" : 100.0, "Precision" : 0.0, - "sa" : { - "TimeOfEvent" : 10.0 - }, "ChosenOutputs" : [ "STEADYSTATE" ], "TimeStep" : 2.6, "StartingPointMode" : "warm", diff --git a/dynaflow/src/test/resources/params_default.json b/dynaflow/src/test/resources/params_default.json index 13db75192..0c3f5b52c 100644 --- a/dynaflow/src/test/resources/params_default.json +++ b/dynaflow/src/test/resources/params_default.json @@ -1,10 +1,10 @@ { "dfl-config" : { + "InfiniteReactiveLimits" : true, "SVCRegulationOn" : true, "ShuntRegulationOn" : true, "AutomaticSlackBusOn" : true, "DsoVoltageLevel" : 45.0, - "InfiniteReactiveLimits" : true, "ActivePowerCompensation" : "PMAX", "StartTime" : 0.0, "StopTime" : 100.0, diff --git a/dynaflow/src/test/resources/params_default_sa.json b/dynaflow/src/test/resources/params_default_sa.json new file mode 100644 index 000000000..f430415c1 --- /dev/null +++ b/dynaflow/src/test/resources/params_default_sa.json @@ -0,0 +1,19 @@ +{ + "dfl-config" : { + "InfiniteReactiveLimits" : false, + "SVCRegulationOn" : true, + "ShuntRegulationOn" : true, + "AutomaticSlackBusOn" : true, + "DsoVoltageLevel" : 45.0, + "ActivePowerCompensation" : "PMAX", + "StartTime" : 0.0, + "StopTime" : 100.0, + "ChosenOutputs" : [ "TIMELINE" ], + "TimeStep" : 10.0, + "StartingPointMode" : "warm", + "sa" : { + "TimeOfEvent" : 10.0 + }, + "OutputDir" : "dynaflow_sa/workingDir" + } +} \ No newline at end of file diff --git a/dynaflow/src/test/resources/params_sa.json b/dynaflow/src/test/resources/params_sa.json new file mode 100644 index 000000000..81ac97091 --- /dev/null +++ b/dynaflow/src/test/resources/params_sa.json @@ -0,0 +1,19 @@ +{ + "dfl-config" : { + "InfiniteReactiveLimits" : false, + "SVCRegulationOn" : true, + "ShuntRegulationOn" : true, + "AutomaticSlackBusOn" : true, + "DsoVoltageLevel" : 45.0, + "ActivePowerCompensation" : "PMAX", + "StartTime" : 0.0, + "StopTime" : 100.0, + "ChosenOutputs" : [ "TIMELINE" ], + "TimeStep" : 10.0, + "StartingPointMode" : "warm", + "sa" : { + "TimeOfEvent" : 20.0 + }, + "OutputDir" : "dynaflow_sa/workingDir" + } +} \ No newline at end of file diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java index 70f8cc6eb..b1f66c88d 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java @@ -12,10 +12,7 @@ import com.powsybl.commons.report.ReportNode; import com.powsybl.commons.test.TestUtil; import com.powsybl.contingency.Contingency; -import com.powsybl.dynaflow.DynaFlowConfig; -import com.powsybl.dynaflow.DynaFlowParameters; -import com.powsybl.dynaflow.DynaFlowProvider; -import com.powsybl.dynaflow.DynaFlowSecurityAnalysisProvider; +import com.powsybl.dynaflow.*; import com.powsybl.ieeecdf.converter.IeeeCdfNetworkFactory; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.VariantManagerConstants; @@ -58,12 +55,14 @@ class DynaFlowTest extends AbstractDynawoTest { @BeforeEach void setUp() throws Exception { super.setUp(); - DynaFlowConfig config = new DynaFlowConfig(Path.of("/dynaflow-launcher"), false); + DynaFlowConfig config = new DynaFlowConfig(Path.of("/dynaflow-launcher"), true); loadFlowProvider = new DynaFlowProvider(() -> config); loadFlowParameters = new LoadFlowParameters(); securityAnalysisProvider = new DynaFlowSecurityAnalysisProvider(() -> config); securityAnalysisParameters = new SecurityAnalysisParameters(); loadFlowParameters.addExtension(DynaFlowParameters.class, new DynaFlowParameters()); + securityAnalysisParameters.addExtension(DynaFlowSecurityAnalysisParameters.class, + new DynaFlowSecurityAnalysisParameters().setTimeOfEvent(15.)); } @Test diff --git a/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/sa_bb_results.json b/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/sa_bb_results.json index f5dff8c5f..88089409b 100644 --- a/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/sa_bb_results.json +++ b/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/sa_bb_results.json @@ -215,14 +215,6 @@ "limit" : 13.386000000000001, "limitReduction" : 1.0, "value" : 13.377658087264606 - }, { - "subjectId" : "_BUS____9_VL", - "subjectName" : "BUS 9_VL", - "limitType" : "LOW_VOLTAGE", - "limitName" : "UInfUmin", - "limit" : 13.386000000000001, - "limitReduction" : 1.0, - "value" : 13.384395964628164 } ], "actionsTaken" : [ ] }, diff --git a/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/sa_nb_results.json b/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/sa_nb_results.json index 9ae2c0898..0341336e6 100644 --- a/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/sa_nb_results.json +++ b/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/sa_nb_results.json @@ -29,7 +29,7 @@ "limitName" : "UInfUmin", "limit" : 220.0, "limitReduction" : 1.0, - "value" : 217.0313224616953 + "value" : 217.0314175890167 }, { "subjectId" : "S1VL2_BBS1", "subjectName" : "S1VL2_BBS1", @@ -37,7 +37,7 @@ "limitName" : "UInfUmin", "limit" : 390.0, "limitReduction" : 1.0, - "value" : 386.2578552204816 + "value" : 386.25793073656337 }, { "subjectId" : "S1VL2_BBS2", "subjectName" : "S1VL2_BBS2", @@ -45,21 +45,21 @@ "limitName" : "UInfUmin", "limit" : 390.0, "limitReduction" : 1.0, - "value" : 386.2578552204816 + "value" : 386.25793073656337 }, { "subjectId" : "S1VL1", "limitType" : "LOW_VOLTAGE", "limitName" : "UInfUmin", "limit" : 220.0, "limitReduction" : 1.0, - "value" : 217.0313224616953 + "value" : 217.0314175890167 }, { "subjectId" : "S1VL2", "limitType" : "LOW_VOLTAGE", "limitName" : "UInfUmin", "limit" : 390.0, "limitReduction" : 1.0, - "value" : 386.2578552204816 + "value" : 386.25793073656337 } ], "actionsTaken" : [ ] }, @@ -117,7 +117,7 @@ "limitName" : "UInfUmin", "limit" : 220.0, "limitReduction" : 1.0, - "value" : 217.86284536089713 + "value" : 217.86293797312413 }, { "subjectId" : "S1VL2_BBS1", "subjectName" : "S1VL2_BBS1", @@ -125,7 +125,7 @@ "limitName" : "UInfUmin", "limit" : 390.0, "limitReduction" : 1.0, - "value" : 387.735597348476 + "value" : 387.73566855444443 }, { "subjectId" : "S1VL2_BBS2", "subjectName" : "S1VL2_BBS2", @@ -133,21 +133,21 @@ "limitName" : "UInfUmin", "limit" : 390.0, "limitReduction" : 1.0, - "value" : 387.735597348476 + "value" : 387.73566855444443 }, { "subjectId" : "S1VL1", "limitType" : "LOW_VOLTAGE", "limitName" : "UInfUmin", "limit" : 220.0, "limitReduction" : 1.0, - "value" : 217.86284536089713 + "value" : 217.86293797312413 }, { "subjectId" : "S1VL2", "limitType" : "LOW_VOLTAGE", "limitName" : "UInfUmin", "limit" : 390.0, "limitReduction" : 1.0, - "value" : 387.735597348476 + "value" : 387.73566855444443 } ], "actionsTaken" : [ ] }, diff --git a/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/timeline_report_as.txt b/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/timeline_report_as.txt index 2019d5ca4..d876dbee7 100644 --- a/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/timeline_report_as.txt +++ b/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/timeline_report_as.txt @@ -1,44 +1,44 @@ + Root message + Dynaflow security analysis on network 'ieee14bus' + Contingency '_BUS___10-BUS___11-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS___10-BUS___11-1_AC' + [t=20.0] LINE : opening both sides on equipment '_BUS___10-BUS___11-1_AC' + Contingency '_BUS___12-BUS___13-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS___12-BUS___13-1_AC' + [t=20.0] LINE : opening both sides on equipment '_BUS___12-BUS___13-1_AC' + Contingency '_BUS___13-BUS___14-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS___13-BUS___14-1_AC' + [t=20.0] LINE : opening both sides on equipment '_BUS___13-BUS___14-1_AC' + Contingency '_BUS____1-BUS____2-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____1-BUS____2-1_AC' - [t=10.0] Generator : maximum reactive power limit reached on equipment '_GEN____2_SM' - [t=20.0] Generator : maximum reactive power limit reached on equipment '_GEN____3_SM' - [t=20.0] Generator : maximum reactive power limit reached on equipment '_GEN____6_SM' - [t=25.0] Generator : maximum reactive power limit reached on equipment '_GEN____8_SM' + [t=20.0] LINE : opening both sides on equipment '_BUS____1-BUS____2-1_AC' + [t=20.0] Generator : maximum reactive power limit reached on equipment '_GEN____2_SM' + [t=30.0] Generator : maximum reactive power limit reached on equipment '_GEN____3_SM' + [t=30.0] Generator : maximum reactive power limit reached on equipment '_GEN____6_SM' + [t=35.0] Generator : maximum reactive power limit reached on equipment '_GEN____8_SM' + Contingency '_BUS____1-BUS____5-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____1-BUS____5-1_AC' - [t=10.0] Generator : maximum reactive power limit reached on equipment '_GEN____2_SM' + [t=20.0] LINE : opening both sides on equipment '_BUS____1-BUS____5-1_AC' + [t=20.0] Generator : maximum reactive power limit reached on equipment '_GEN____2_SM' + Contingency '_BUS____2-BUS____3-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____2-BUS____3-1_AC' - [t=10.0] Generator : maximum reactive power limit reached on equipment '_GEN____3_SM' + [t=20.0] LINE : opening both sides on equipment '_BUS____2-BUS____3-1_AC' + [t=20.0] Generator : maximum reactive power limit reached on equipment '_GEN____3_SM' + Contingency '_BUS____2-BUS____4-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____2-BUS____4-1_AC' + [t=20.0] LINE : opening both sides on equipment '_BUS____2-BUS____4-1_AC' + Contingency '_BUS____2-BUS____5-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____2-BUS____5-1_AC' + [t=20.0] LINE : opening both sides on equipment '_BUS____2-BUS____5-1_AC' + Contingency '_BUS____3-BUS____4-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____3-BUS____4-1_AC' + [t=20.0] LINE : opening both sides on equipment '_BUS____3-BUS____4-1_AC' + Contingency '_BUS____4-BUS____5-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____4-BUS____5-1_AC' - [t=10.0] Generator : maximum reactive power limit reached on equipment '_GEN____2_SM' + [t=20.0] LINE : opening both sides on equipment '_BUS____4-BUS____5-1_AC' + [t=20.0] Generator : maximum reactive power limit reached on equipment '_GEN____2_SM' + Contingency '_BUS____6-BUS___11-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____6-BUS___11-1_AC' + [t=20.0] LINE : opening both sides on equipment '_BUS____6-BUS___11-1_AC' + Contingency '_BUS____6-BUS___12-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____6-BUS___12-1_AC' + [t=20.0] LINE : opening both sides on equipment '_BUS____6-BUS___12-1_AC' + Contingency '_BUS____6-BUS___13-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____6-BUS___13-1_AC' + [t=20.0] LINE : opening both sides on equipment '_BUS____6-BUS___13-1_AC' + Contingency '_BUS____7-BUS____8-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____7-BUS____8-1_AC' - [t=10.0] GENERATOR : disconnecting on equipment '_GEN____8_SM' + [t=20.0] LINE : opening both sides on equipment '_BUS____7-BUS____8-1_AC' + [t=20.0] GENERATOR : disconnecting on equipment '_GEN____8_SM' + Contingency '_BUS____7-BUS____9-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____7-BUS____9-1_AC' + [t=20.0] LINE : opening both sides on equipment '_BUS____7-BUS____9-1_AC' + Contingency '_BUS____9-BUS___10-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____9-BUS___10-1_AC' + [t=20.0] LINE : opening both sides on equipment '_BUS____9-BUS___10-1_AC' + Contingency '_BUS____9-BUS___14-1_AC' - [t=10.0] LINE : opening both sides on equipment '_BUS____9-BUS___14-1_AC' + [t=20.0] LINE : opening both sides on equipment '_BUS____9-BUS___14-1_AC'