Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Dynaflow parameter - fix merge loads parameter #366

Merged
merged 7 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 96 additions & 46 deletions dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowParameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -37,9 +38,10 @@ public class DynaFlowParameters extends AbstractExtension<LoadFlowParameters> {
*/
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;
Expand Down Expand Up @@ -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<OutputTypes> 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 <E extends Enum<E>> List<Object> getEnumPossibleValues(Class<E> enumClass) {
return EnumSet.allOf(enumClass).stream().map(Enum::name).collect(Collectors.toList());
}

public static final List<Parameter> 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<String> chosenOutputs = List.of(OutputTypes.TIMELINE.name());
private Double timeStep = null;
private StartingPointMode startingPointMode = null;
private boolean mergeLoads = true;
private EnumSet<OutputTypes> 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;
Expand Down Expand Up @@ -225,12 +241,17 @@ public DynaFlowParameters setTimeOfEvent(Double timeOfEvent) {
return this;
}

public List<String> getChosenOutputs() {
public Set<OutputTypes> getChosenOutputs() {
return chosenOutputs;
}

public DynaFlowParameters setChosenOutputs(List<String> chosenOutputs) {
this.chosenOutputs = chosenOutputs;
public DynaFlowParameters setChosenOutputs(Set<OutputTypes> chosenOutputs) {
this.chosenOutputs = EnumSet.copyOf(chosenOutputs);
return this;
}

public DynaFlowParameters addChosenOutput(OutputTypes chosenOutput) {
this.chosenOutputs.add(chosenOutput);
return this;
}

Expand Down Expand Up @@ -261,7 +282,6 @@ public DynaFlowParameters setSa(Sa securityAnalysis) {
return this;
}

@JsonIgnore
public boolean isMergeLoads() {
return mergeLoads;
}
Expand Down Expand Up @@ -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);
Expand All @@ -352,12 +372,42 @@ public void update(Map<String, String> 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<String, String> createMapFromParameters() {
Map<String, String> 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<String, String> adder) {
if (value != null) {
adder.accept(key, Objects.toString(value));
}
}

public static DynaFlowParameters load(Map<String, String> properties) {
DynaFlowParameters parameters = new DynaFlowParameters();
parameters.update(properties);
Expand Down
21 changes: 4 additions & 17 deletions dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -141,22 +140,10 @@ public Optional<Extension<LoadFlowParameters>> loadSpecificParameters(Map<String

@Override
public Map<String, String> createMapFromSpecificParameters(Extension<LoadFlowParameters> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 <guillaume.pernin at rte-france.com>}
*/
public final class DynaFlowConfigSerializer {
Expand Down Expand Up @@ -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();
}
Expand All @@ -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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import java.io.IOException;

/**
*
* Represents {@link DynaFlowParameters} as a Json extension of {@link LoadFlowParameters}
* @author Guillaume Pernin {@literal <guillaume.pernin at rte-france.com>}
*/
@AutoService(ExtensionJsonSerializer.class)
Expand Down Expand Up @@ -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
Expand Down
Loading
Loading