From 2b6a07f10249bd7cc04d1cf6c3e6b43b9f667aab Mon Sep 17 00:00:00 2001 From: Lisrte Date: Tue, 1 Oct 2024 11:18:06 +0200 Subject: [PATCH] Dynawo final state values (#381) * Add FSV input * Rename curve to outputVariable * Parse Fsv CSV file * Add Fsv handling in integration test Signed-off-by: lisrte --- README.md | 16 ++-- .../dynawo/commons/AbstractCsvParser.java | 28 +++--- .../commons/dynawologs/CsvLogParser.java | 2 +- .../commons/timeline/CsvTimeLineParser.java | 2 +- docs/dynamic_simulation/index.md | 2 +- ...{curves-dsl.md => output-variables-dsl.md} | 15 +++- .../dsl/DynawoCurveGroovyExtension.groovy | 41 --------- ...DynawoOutputVariableGroovyExtension.groovy | 42 +++++++++ .../dynawo/dsl/CurvesSupplierTest.java | 83 ------------------ .../dsl/OutputVariablesSupplierTest.java | 85 +++++++++++++++++++ .../dynawo/dsl/ieee/AbstractIeeeTest.java | 18 ++-- .../dsl/ieee/DynawoLocalCommandExecutor.java | 4 +- .../{curves.groovy => outputVariables.groovy} | 2 +- .../dynawo/it/DynawoSimulationTest.java | 38 +++++---- .../{curves.groovy => outputVariables.groovy} | 4 +- .../dynawo/DynawoSimulationContext.java | 29 ++++--- .../dynawo/DynawoSimulationHandler.java | 84 ++++++++++++------ .../dynawo/DynawoSimulationProvider.java | 6 +- .../dynawo/builders/BuilderReports.java | 4 +- .../dynawo/outputvariables/CsvFsvParser.java | 60 +++++++++++++ .../DynawoOutputVariable.java} | 20 +++-- .../DynawoOutputVariablesBuilder.java} | 43 ++++++---- .../dynawo/outputvariables/FsvEntry.java | 14 +++ .../curves/CurvesJsonDeserializer.java | 69 --------------- .../OutputVariablesJsonDeserializer.java | 73 ++++++++++++++++ .../com/powsybl/dynawo/xml/CurvesXml.java | 41 --------- .../dynawo/xml/DynawoSimulationConstants.java | 8 +- .../java/com/powsybl/dynawo/xml/JobsXml.java | 16 +++- .../dynawo/xml/OutputVariablesXml.java | 53 ++++++++++++ .../powsybl/dynawo/DynawoProviderTest.java | 20 ++--- ...t.java => OutputVariablesBuilderTest.java} | 45 +++++----- .../dynawo/models/buses/StandardBusTest.java | 6 +- .../dynawo/models/lines/StandardLineTest.java | 6 +- .../outputvariables/CsvFsvParserTest.java | 42 +++++++++ .../DynawoCurvesJsonDeserializerTest.java | 44 ---------- ...woOutputVariablesJsonDeserializerTest.java | 46 ++++++++++ .../xml/AbstractDynamicModelXmlTest.java | 8 +- ...stractParametrizedDynamicModelXmlTest.java | 6 +- .../dynawo/xml/DynamicModelsXmlTest.java | 10 +-- .../powsybl/dynawo/xml/DynawoTestUtil.java | 25 ++++-- .../com/powsybl/dynawo/xml/EventXmlTest.java | 4 +- .../com/powsybl/dynawo/xml/JobsXmlTest.java | 6 +- ...lTest.java => OutputVariablesXmlTest.java} | 11 +-- .../powsybl/dynawo/xml/ParametersXmlTest.java | 2 +- dynawo-simulation/src/test/resources/fsv.csv | 4 + .../src/test/resources/fsvInput.xml | 7 ++ .../src/test/resources/fsvInput.xsd | 36 ++++++++ .../src/test/resources/fsvWrongEntry.csv | 3 + dynawo-simulation/src/test/resources/jobs.xml | 1 + dynawo-simulation/src/test/resources/jobs.xsd | 16 ++++ .../src/test/resources/jobsWithDump.xml | 1 + .../test/resources/jobsWithSpecificLogs.xml | 1 + .../{curves.json => outputVariables.json} | 10 +++ 53 files changed, 777 insertions(+), 485 deletions(-) rename docs/dynamic_simulation/{curves-dsl.md => output-variables-dsl.md} (67%) delete mode 100644 dynawo-dsl/src/main/groovy/com/powsybl/dynawo/dsl/DynawoCurveGroovyExtension.groovy create mode 100644 dynawo-dsl/src/main/groovy/com/powsybl/dynawo/dsl/DynawoOutputVariableGroovyExtension.groovy delete mode 100644 dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/CurvesSupplierTest.java create mode 100644 dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/OutputVariablesSupplierTest.java rename dynawo-dsl/src/test/resources/{curves.groovy => outputVariables.groovy} (98%) rename dynawo-integration-tests/src/test/resources/ieee14/disconnectline/{curves.groovy => outputVariables.groovy} (95%) create mode 100644 dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/CsvFsvParser.java rename dynawo-simulation/src/main/java/com/powsybl/dynawo/{curves/DynawoCurve.java => outputvariables/DynawoOutputVariable.java} (54%) rename dynawo-simulation/src/main/java/com/powsybl/dynawo/{curves/DynawoCurvesBuilder.java => outputvariables/DynawoOutputVariablesBuilder.java} (61%) create mode 100644 dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/FsvEntry.java delete mode 100644 dynawo-simulation/src/main/java/com/powsybl/dynawo/suppliers/curves/CurvesJsonDeserializer.java create mode 100644 dynawo-simulation/src/main/java/com/powsybl/dynawo/suppliers/outputvariables/OutputVariablesJsonDeserializer.java delete mode 100644 dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/CurvesXml.java create mode 100644 dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/OutputVariablesXml.java rename dynawo-simulation/src/test/java/com/powsybl/dynawo/builders/{CurvesBuilderTest.java => OutputVariablesBuilderTest.java} (62%) create mode 100644 dynawo-simulation/src/test/java/com/powsybl/dynawo/outputvariables/CsvFsvParserTest.java delete mode 100644 dynawo-simulation/src/test/java/com/powsybl/dynawo/suppliers/DynawoCurvesJsonDeserializerTest.java create mode 100644 dynawo-simulation/src/test/java/com/powsybl/dynawo/suppliers/DynawoOutputVariablesJsonDeserializerTest.java rename dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/{CurvesXmlTest.java => OutputVariablesXmlTest.java} (72%) create mode 100644 dynawo-simulation/src/test/resources/fsv.csv create mode 100644 dynawo-simulation/src/test/resources/fsvInput.xml create mode 100644 dynawo-simulation/src/test/resources/fsvInput.xsd create mode 100644 dynawo-simulation/src/test/resources/fsvWrongEntry.csv rename dynawo-simulation/src/test/resources/suppliers/{curves.json => outputVariables.json} (70%) diff --git a/README.md b/README.md index a5962d814..24ece6a9d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ To run a dynamic simulation, you need: - a case file - a `DynamicModelsSupplier` to associate dynamic models to the equipment of the network - an `EventModelsSuppler` to configure events simulated during the simulation (optional) -- a `CurvesSupplier` to follow the evolution of dynamic variables during the simulation (optional) +- an `OutputVariablesSupplier` to follow the evolution of dynamic variables during the simulation (optional) - a set of parameters to configure the simulation (optional) Thanks to `powsybl-dynawo-dsl`, the inputs can be easily configured using Groovy scripts. @@ -38,25 +38,25 @@ The simulation parameters can be configured either in the `config.yml` file or u Network network = Network.read("/path/to/the/casefile.xiidm"); // Load the dynamic models mapping -GroovyDynamicModelsSupplier dynamicModelsSupplier = new GroovyDynamicModelsSupplier( +DynamicModelsSupplier dynamicModelsSupplier = new GroovyDynamicModelsSupplier( Paths.get("/path/to/dynamicModelsMapping.groovy"), GroovyExtension.find(DynamicModelGroovyExtension.class, DynawoSimulationProvider.NAME)); // Load the events -GroovyEventModelsSupplier eventModelsSupplier = new GroovyEventModelsSupplier( +EventModelsSupplier eventModelsSupplier = new GroovyEventModelsSupplier( Paths.get("/path/to/event.groovy"), GroovyExtension.find(EventModelGroovyExtension.class, DynawoSimulationProvider.NAME)); -// Configure the curves -GroovyCurvesSupplier curvesSupplier = new GroovyCurvesSupplier( - Paths.get("/path/to/curves.groovy"), - GroovyExtension.find(CurveGroovyExtension.class, DynawoSimulationProvider.NAME)); +// Configure the output variables +OutputVariablesSupplier outputVariablesSupplier = new GroovyOutputVariablesSupplier( + Paths.get("/path/to/outputVariables.groovy"), + GroovyExtension.find(OutputVariableGroovyExtension.class, DynawoSimulationProvider.NAME)); // Load the parameters DynamicSimulationParameters parameters = DynamicSimulationParameters.load(); // Run the simulation and display the results -DynamicSimulationResult result = DynamicSimulation.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, parameters); +DynamicSimulationResult result = DynamicSimulation.run(network, dynamicModelsSupplier, eventModelsSupplier, outputVariablesSupplier, parameters); System.out.println(result.getStatus()); System.out.println("Timeline:"); result.getTimeLine().forEach(tl -> System.out.printf("[%.8f] %s (on %s)%n", tl.time(), tl.message(), tl.modelName())); diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/AbstractCsvParser.java b/commons/src/main/java/com/powsybl/dynawo/commons/AbstractCsvParser.java index 2ccfed9eb..00c41f79f 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/AbstractCsvParser.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/AbstractCsvParser.java @@ -28,36 +28,30 @@ public abstract class AbstractCsvParser { protected static final char DEFAULT_SEPARATOR = '|'; - private final char separator; + private final CsvParser csvParser; - protected AbstractCsvParser(char separator) { - this.separator = separator; + protected AbstractCsvParser(char separator, boolean skipHeader) { + CsvParserSettings settings = new CsvParserSettings(); + settings.getFormat().setDelimiter(separator); + settings.getFormat().setQuoteEscape('"'); + settings.getFormat().setLineSeparator(System.lineSeparator()); + settings.setMaxColumns(getNbColumns()); + settings.setHeaderExtractionEnabled(skipHeader); + csvParser = new CsvParser(settings); } public List parse(Path file) { if (!Files.exists(file)) { return Collections.emptyList(); } - try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) { - return parse(reader); + Objects.requireNonNull(reader); + return read(csvParser.iterate(reader).iterator()); } catch (IOException e) { throw new UncheckedIOException(e); } } - private List parse(BufferedReader reader) { - Objects.requireNonNull(reader); - CsvParserSettings settings = new CsvParserSettings(); - settings.getFormat().setDelimiter(separator); - settings.getFormat().setQuoteEscape('"'); - settings.getFormat().setLineSeparator(System.lineSeparator()); - settings.setMaxColumns(getNbColumns()); - CsvParser csvParser = new CsvParser(settings); - ResultIterator iterator = csvParser.iterate(reader).iterator(); - return read(iterator); - } - protected List read(ResultIterator iterator) { List logs = new ArrayList<>(); int iLine = 0; diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParser.java b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParser.java index 43a429139..c8db4ce91 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParser.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParser.java @@ -23,7 +23,7 @@ public CsvLogParser() { } public CsvLogParser(char separator) { - super(separator); + super(separator, false); } @Override diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParser.java b/commons/src/main/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParser.java index 70b3e4a52..c1c9dbe55 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParser.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParser.java @@ -23,7 +23,7 @@ public CsvTimeLineParser() { } public CsvTimeLineParser(char separator) { - super(separator); + super(separator, false); } @Override diff --git a/docs/dynamic_simulation/index.md b/docs/dynamic_simulation/index.md index e6d743836..8bdd104b7 100644 --- a/docs/dynamic_simulation/index.md +++ b/docs/dynamic_simulation/index.md @@ -5,7 +5,7 @@ configuration.md dynamic-models-dsl.md event-models-dsl.md -curves-dsl.md +output-variables-dsl.md ``` PowSyBl provides an implementation of the [DynamicSimulation API from powsybl-core](inv:powsyblcore:*:*#simulation/dynamic/index) with [Dynaωo](https://dynawo.github.io), a tool for long-term stability simulation. diff --git a/docs/dynamic_simulation/curves-dsl.md b/docs/dynamic_simulation/output-variables-dsl.md similarity index 67% rename from docs/dynamic_simulation/curves-dsl.md rename to docs/dynamic_simulation/output-variables-dsl.md index 216d70b5c..acd0bf178 100644 --- a/docs/dynamic_simulation/curves-dsl.md +++ b/docs/dynamic_simulation/output-variables-dsl.md @@ -1,10 +1,19 @@ -# Curves DSL -The curves domain specific language allow a user to configure the curves Dynawo will export at the end of the simulation. This DSL defines the `curve` keywords. +# Output Variables DSL +The output variables domain specific language allow a user to configure the curves or final state values Dynawo will export at the end of the simulation. +This DSL defines the `curve` and `fsv`keywords. The `curve` keyword combined with the `variable` field create a single curve for a dynamic model. One identifies a dynamic model by its ID, the same as the one used in the [Dynamic Models DSL](dynamic-models-dsl). The variable to plot is identified by its name. ```groovy curve { - dynamicModelId load.id + dynamicModelId "dynamicId" + variable "load_PPu" +} +``` + +If the only information needed is the variable final value, the `curve` keyword can be replaced by `fsv` keyword: +```groovy +fsv { + dynamicModelId "dynamicId" variable "load_PPu" } ``` diff --git a/dynawo-dsl/src/main/groovy/com/powsybl/dynawo/dsl/DynawoCurveGroovyExtension.groovy b/dynawo-dsl/src/main/groovy/com/powsybl/dynawo/dsl/DynawoCurveGroovyExtension.groovy deleted file mode 100644 index 9c8283df2..000000000 --- a/dynawo-dsl/src/main/groovy/com/powsybl/dynawo/dsl/DynawoCurveGroovyExtension.groovy +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2020, 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/. - */ -package com.powsybl.dynawo.dsl - -import com.google.auto.service.AutoService -import com.powsybl.commons.report.ReportNode -import com.powsybl.dynamicsimulation.Curve -import com.powsybl.dynamicsimulation.groovy.CurveGroovyExtension -import com.powsybl.dynawo.DynawoSimulationProvider -import com.powsybl.dynawo.curves.DynawoCurvesBuilder - -import java.util.function.Consumer -/** - * An implementation of {@link CurveGroovyExtension} that adds the
curve
keyword to the DSL - * - * @author Mathieu Bague {@literal } - */ -@AutoService(CurveGroovyExtension.class) -class DynawoCurveGroovyExtension implements CurveGroovyExtension { - - @Override - String getName() { - DynawoSimulationProvider.NAME - } - - @Override - void load(Binding binding, Consumer consumer, ReportNode reportNode) { - Closure closure = { Closure closure -> - def cloned = closure.clone() - DynawoCurvesBuilder curvesBuilder = new DynawoCurvesBuilder(reportNode) - cloned.delegate = curvesBuilder - cloned() - curvesBuilder.add(consumer) - } - binding.curve = closure - } -} diff --git a/dynawo-dsl/src/main/groovy/com/powsybl/dynawo/dsl/DynawoOutputVariableGroovyExtension.groovy b/dynawo-dsl/src/main/groovy/com/powsybl/dynawo/dsl/DynawoOutputVariableGroovyExtension.groovy new file mode 100644 index 000000000..e7b769313 --- /dev/null +++ b/dynawo-dsl/src/main/groovy/com/powsybl/dynawo/dsl/DynawoOutputVariableGroovyExtension.groovy @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2020, 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/. + */ +package com.powsybl.dynawo.dsl + +import com.google.auto.service.AutoService +import com.powsybl.commons.report.ReportNode +import com.powsybl.dynamicsimulation.OutputVariable +import com.powsybl.dynamicsimulation.groovy.OutputVariableGroovyExtension +import com.powsybl.dynawo.DynawoSimulationProvider +import com.powsybl.dynawo.outputvariables.DynawoOutputVariablesBuilder + +import java.util.function.Consumer +/** + * An implementation of {@link OutputVariableGroovyExtension} that adds the
curve
and
fsv
keywords to the DSL + * + * @author Mathieu Bague {@literal } + */ +@AutoService(OutputVariableGroovyExtension.class) +class DynawoOutputVariableGroovyExtension implements OutputVariableGroovyExtension { + + @Override + String getName() { + DynawoSimulationProvider.NAME + } + + @Override + void load(Binding binding, Consumer consumer, ReportNode reportNode) { + Closure closure = { Closure closure, OutputVariable.OutputType type -> + def cloned = closure.clone() + DynawoOutputVariablesBuilder variablesBuilder = new DynawoOutputVariablesBuilder(reportNode).outputType(type) + cloned.delegate = variablesBuilder + cloned() + variablesBuilder.add(consumer) + } + binding.curve = c -> closure(c, OutputVariable.OutputType.CURVE) + binding.fsv = c -> closure(c, OutputVariable.OutputType.FINAL_STATE) + } +} diff --git a/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/CurvesSupplierTest.java b/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/CurvesSupplierTest.java deleted file mode 100644 index 86731722d..000000000 --- a/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/CurvesSupplierTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Copyright (c) 2020, 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/. - */ -package com.powsybl.dynawo.dsl; - -import com.google.common.jimfs.Configuration; -import com.google.common.jimfs.Jimfs; -import com.powsybl.dynamicsimulation.Curve; -import com.powsybl.dynamicsimulation.CurvesSupplier; -import com.powsybl.dynamicsimulation.groovy.CurveGroovyExtension; -import com.powsybl.dynamicsimulation.groovy.GroovyCurvesSupplier; -import com.powsybl.dynamicsimulation.groovy.GroovyExtension; -import com.powsybl.dynawo.curves.DynawoCurve; -import com.powsybl.dynawo.DynawoSimulationProvider; -import com.powsybl.iidm.network.Generator; -import com.powsybl.iidm.network.Load; -import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.nio.file.FileSystem; -import java.nio.file.Files; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * @author Marcos de Miguel {@literal } - */ -class CurvesSupplierTest extends AbstractModelSupplierTest { - - private FileSystem fileSystem; - private Network network; - - @BeforeEach - void setup() throws IOException { - fileSystem = Jimfs.newFileSystem(Configuration.unix()); - network = EurostagTutorialExample1Factory.create(); - - Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/curves.groovy")), fileSystem.getPath("/curves.groovy")); - } - - @AfterEach - void tearDown() throws IOException { - fileSystem.close(); - } - - @Test - void test() { - List extensions = validateGroovyExtension(); - CurvesSupplier supplier = new GroovyCurvesSupplier(fileSystem.getPath("/curves.groovy"), extensions); - List curves = supplier.get(network); - assertEquals(11, curves.size()); - curves.forEach(this::validateCurve); - } - - private List validateGroovyExtension() { - List extensions = GroovyExtension.find(CurveGroovyExtension.class, DynawoSimulationProvider.NAME); - assertEquals(1, extensions.size()); - assertInstanceOf(DynawoCurveGroovyExtension.class, extensions.get(0)); - return extensions; - } - - private void validateCurve(Curve curve) { - assertEquals(DynawoCurve.class, curve.getClass()); - DynawoCurve curveImpl = (DynawoCurve) curve; - if (curveImpl.getModelId().equals("NETWORK")) { - assertTrue(Arrays.asList("NGEN_Upu_value", "NHV1_Upu_value", "NHV2_Upu_value", "NLOAD_Upu_value").contains(curveImpl.getVariable())); - } else if (network.getIdentifiable(curveImpl.getModelId()) instanceof Generator) { - assertTrue(Arrays.asList("generator_omegaPu", "generator_PGen", "generator_UStatorPU", "voltageRegulator_UcEfdP", "voltageRegulator_EfdPu").contains(curveImpl.getVariable())); - } else if (network.getIdentifiable(curveImpl.getModelId()) instanceof Load) { - assertTrue(Arrays.asList("load_PPu", "load_QPu").contains(curveImpl.getVariable())); - } - } -} diff --git a/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/OutputVariablesSupplierTest.java b/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/OutputVariablesSupplierTest.java new file mode 100644 index 000000000..f599cdd9f --- /dev/null +++ b/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/OutputVariablesSupplierTest.java @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2020, 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/. + */ +package com.powsybl.dynawo.dsl; + +import com.google.common.jimfs.Configuration; +import com.google.common.jimfs.Jimfs; +import com.powsybl.dynamicsimulation.OutputVariable; +import com.powsybl.dynamicsimulation.OutputVariablesSupplier; +import com.powsybl.dynamicsimulation.groovy.GroovyExtension; +import com.powsybl.dynamicsimulation.groovy.GroovyOutputVariablesSupplier; +import com.powsybl.dynamicsimulation.groovy.OutputVariableGroovyExtension; +import com.powsybl.dynawo.outputvariables.DynawoOutputVariable; +import com.powsybl.dynawo.DynawoSimulationProvider; +import com.powsybl.iidm.network.Generator; +import com.powsybl.iidm.network.Load; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.file.FileSystem; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Marcos de Miguel {@literal } + */ +class OutputVariablesSupplierTest extends AbstractModelSupplierTest { + + private FileSystem fileSystem; + private Network network; + + @BeforeEach + void setup() throws IOException { + fileSystem = Jimfs.newFileSystem(Configuration.unix()); + network = EurostagTutorialExample1Factory.create(); + + Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/outputVariables.groovy")), fileSystem.getPath("/outputVariables.groovy")); + } + + @AfterEach + void tearDown() throws IOException { + fileSystem.close(); + } + + @Test + void test() { + List extensions = validateGroovyExtension(); + OutputVariablesSupplier supplier = new GroovyOutputVariablesSupplier(fileSystem.getPath("/outputVariables.groovy"), extensions); + List outputVariables = supplier.get(network); + assertEquals(11, outputVariables.size()); + outputVariables.forEach(this::validateOutputVariable); + } + + private List validateGroovyExtension() { + List extensions = GroovyExtension.find(OutputVariableGroovyExtension.class, DynawoSimulationProvider.NAME); + assertEquals(1, extensions.size()); + assertInstanceOf(DynawoOutputVariableGroovyExtension.class, extensions.get(0)); + return extensions; + } + + private void validateOutputVariable(OutputVariable outputVariable) { + assertEquals(DynawoOutputVariable.class, outputVariable.getClass()); + if (outputVariable.getModelId().equals("NETWORK")) { + assertEquals(OutputVariable.OutputType.CURVE, outputVariable.getOutputType()); + assertTrue(Arrays.asList("NGEN_Upu_value", "NHV1_Upu_value", "NHV2_Upu_value", "NLOAD_Upu_value").contains(outputVariable.getVariableName())); + } else if (network.getIdentifiable(outputVariable.getModelId()) instanceof Generator) { + assertEquals(OutputVariable.OutputType.FINAL_STATE, outputVariable.getOutputType()); + assertTrue(Arrays.asList("generator_omegaPu", "generator_PGen", "generator_UStatorPU", "voltageRegulator_UcEfdP", "voltageRegulator_EfdPu").contains(outputVariable.getVariableName())); + } else if (network.getIdentifiable(outputVariable.getModelId()) instanceof Load) { + assertEquals(OutputVariable.OutputType.CURVE, outputVariable.getOutputType()); + assertTrue(Arrays.asList("load_PPu", "load_QPu").contains(outputVariable.getVariableName())); + } + } +} diff --git a/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/ieee/AbstractIeeeTest.java b/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/ieee/AbstractIeeeTest.java index 75826799a..d6c7160f4 100644 --- a/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/ieee/AbstractIeeeTest.java +++ b/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/ieee/AbstractIeeeTest.java @@ -44,7 +44,7 @@ public abstract class AbstractIeeeTest { private DynamicModelsSupplier dynamicModelsSupplier; private EventModelsSupplier eventModelsSupplier; - private CurvesSupplier curvesSupplier; + private OutputVariablesSupplier outputVariablesSupplier; @AfterEach void tearDown() throws IOException { @@ -54,7 +54,7 @@ void tearDown() throws IOException { public abstract String getWorkingDirName(); protected void setup(String parametersFile, String networkParametersFile, String networkParametersId, String solverParametersFile, String solverParametersId, String networkFile, - String dynamicModelsFile, String eventModelsFile, String curvesFile, int startTime, int stopTime) throws IOException { + String dynamicModelsFile, String eventModelsFile, String outputVariablesFile, int startTime, int stopTime) throws IOException { // The parameter files are copied into the PlatformConfig filesystem, // that filesystem is the one that DynawoSimulationContext and ParametersXml will use to read the parameters @@ -83,13 +83,13 @@ protected void setup(String parametersFile, String networkParametersFile, String eventModelsSupplier = EventModelsSupplier.empty(); } - // Curves - if (curvesFile != null) { - Files.copy(Objects.requireNonNull(getClass().getResourceAsStream(curvesFile)), workingDir.resolve("curves.groovy")); - List curveGroovyExtensions = GroovyExtension.find(CurveGroovyExtension.class, DynawoSimulationProvider.NAME); - curvesSupplier = new GroovyCurvesSupplier(workingDir.resolve("curves.groovy"), curveGroovyExtensions); + // Output Variables + if (outputVariablesFile != null) { + Files.copy(Objects.requireNonNull(getClass().getResourceAsStream(outputVariablesFile)), workingDir.resolve("outputVariables.groovy")); + List variableGroovyExtensions = GroovyExtension.find(OutputVariableGroovyExtension.class, DynawoSimulationProvider.NAME); + outputVariablesSupplier = new GroovyOutputVariablesSupplier(workingDir.resolve("outputVariables.groovy"), variableGroovyExtensions); } else { - curvesSupplier = CurvesSupplier.empty(); + outputVariablesSupplier = OutputVariablesSupplier.empty(); } parameters = new DynamicSimulationParameters() @@ -116,7 +116,7 @@ public DynamicSimulationResult runSimulation(LocalCommandExecutor commandExecuto DynamicSimulation.Runner dynawoSimulation = DynamicSimulation.find(); assertEquals(DynawoSimulationProvider.NAME, dynawoSimulation.getName()); return dynawoSimulation.run(network, dynamicModelsSupplier, eventModelsSupplier, - curvesSupplier, network.getVariantManager().getWorkingVariantId(), + outputVariablesSupplier, network.getVariantManager().getWorkingVariantId(), computationManager, parameters, NO_OP); } diff --git a/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/ieee/DynawoLocalCommandExecutor.java b/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/ieee/DynawoLocalCommandExecutor.java index 940fc4bd7..5a16a0a25 100644 --- a/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/ieee/DynawoLocalCommandExecutor.java +++ b/dynawo-dsl/src/test/java/com/powsybl/dynawo/dsl/ieee/DynawoLocalCommandExecutor.java @@ -61,8 +61,8 @@ protected void validateInputs(Path workingDir) throws IOException { } protected void copyOutputs(Path workingDir) throws IOException { - Path output = Files.createDirectories(workingDir.resolve("outputs/curves").toAbsolutePath()); - Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/" + baseDirName + "/dynawo-outputs/curves.csv")), output.resolve("curves.csv")); + Path output = Files.createDirectories(workingDir.resolve("outputs/outputVariables").toAbsolutePath()); + Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/" + baseDirName + "/dynawo-outputs/outputVariables.csv")), output.resolve("curves.csv")); } @Override diff --git a/dynawo-dsl/src/test/resources/curves.groovy b/dynawo-dsl/src/test/resources/outputVariables.groovy similarity index 98% rename from dynawo-dsl/src/test/resources/curves.groovy rename to dynawo-dsl/src/test/resources/outputVariables.groovy index 49c11a42d..bf4f0ed70 100644 --- a/dynawo-dsl/src/test/resources/curves.groovy +++ b/dynawo-dsl/src/test/resources/outputVariables.groovy @@ -17,7 +17,7 @@ for (Bus bus : network.busBreakerView.buses) { } for (Generator gen : network.generators) { - curve { + fsv { dynamicModelId gen.id variables "generator_omegaPu", "generator_PGen", "generator_UStatorPU", "voltageRegulator_UcEfdP", "voltageRegulator_EfdPu" } diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynawoSimulationTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynawoSimulationTest.java index d35d33f1b..b34219fd1 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynawoSimulationTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynawoSimulationTest.java @@ -72,9 +72,9 @@ void testIeee14() { getResourceAsStream("/ieee14/disconnectline/eventModels.groovy"), GroovyExtension.find(EventModelGroovyExtension.class, DynawoSimulationProvider.NAME)); - GroovyCurvesSupplier curvesSupplier = new GroovyCurvesSupplier( - getResourceAsStream("/ieee14/disconnectline/curves.groovy"), - GroovyExtension.find(CurveGroovyExtension.class, DynawoSimulationProvider.NAME)); + GroovyOutputVariablesSupplier outputVariablesSupplier = new GroovyOutputVariablesSupplier( + getResourceAsStream("/ieee14/disconnectline/outputVariables.groovy"), + GroovyExtension.find(OutputVariableGroovyExtension.class, DynawoSimulationProvider.NAME)); List modelsParameters = ParametersXml.load(getResourceAsStream("/ieee14/disconnectline/models.par")); ParametersSet networkParameters = ParametersXml.load(getResourceAsStream("/ieee14/disconnectline/network.par"), "8"); @@ -85,16 +85,18 @@ void testIeee14() { .setSolverType(DynawoSimulationParameters.SolverType.IDA) .setTimelineExportMode(DynawoSimulationParameters.ExportMode.XML); - DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, + DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, outputVariablesSupplier, VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); assertEquals(DynamicSimulationResult.Status.SUCCESS, result.getStatus()); assertTrue(result.getStatusText().isEmpty()); - assertEquals(41, result.getCurves().size()); + assertEquals(27, result.getCurves().size()); DoubleTimeSeries ts1 = result.getCurve("_GEN____1_SM_generator_UStatorPu"); assertEquals("_GEN____1_SM_generator_UStatorPu", ts1.getMetadata().getName()); assertEquals(587, ts1.toArray().length); + assertEquals(14, result.getFinalStateValues().size()); + assertEquals(1.046227, result.getFinalStateValues().get("NETWORK__BUS___10_TN_Upu_value")); List timeLine = result.getTimeLine(); assertEquals(23, timeLine.size()); checkFirstTimeLineEvent(timeLine.get(0), 0, "_GEN____8_SM", "PMIN : activation"); @@ -112,9 +114,9 @@ void testIeee14WithDump() throws IOException { getResourceAsStream("/ieee14/disconnectline/eventModels.groovy"), GroovyExtension.find(EventModelGroovyExtension.class, DynawoSimulationProvider.NAME)); - GroovyCurvesSupplier curvesSupplier = new GroovyCurvesSupplier( - getResourceAsStream("/ieee14/disconnectline/curves.groovy"), - GroovyExtension.find(CurveGroovyExtension.class, DynawoSimulationProvider.NAME)); + GroovyOutputVariablesSupplier outputVariablesSupplier = new GroovyOutputVariablesSupplier( + getResourceAsStream("/ieee14/disconnectline/outputVariables.groovy"), + GroovyExtension.find(OutputVariableGroovyExtension.class, DynawoSimulationProvider.NAME)); Path dumpDir = Files.createDirectory(localDir.resolve("dumpFiles")); @@ -130,7 +132,7 @@ void testIeee14WithDump() throws IOException { .setSolverType(DynawoSimulationParameters.SolverType.IDA) .setDumpFileParameters(dumpFileParameters); - DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, + DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, outputVariablesSupplier, VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); assertEquals(DynamicSimulationResult.Status.SUCCESS, result.getStatus()); @@ -145,7 +147,7 @@ void testIeee14WithDump() throws IOException { } dynawoSimulationParameters.setDumpFileParameters(DumpFileParameters.createImportDumpFileParameters(dumpDir, dumpFile)); - result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, + result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, outputVariablesSupplier, VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); @@ -169,7 +171,7 @@ void testSvarc() { .setSolverType(DynawoSimulationParameters.SolverType.IDA) .setPrecision(10e-8); - DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, EventModelsSupplier.empty(), CurvesSupplier.empty(), + DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, EventModelsSupplier.empty(), OutputVariablesSupplier.empty(), VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); @@ -199,7 +201,7 @@ void testHvdc() { .setSolverType(DynawoSimulationParameters.SolverType.IDA) .setSpecificLogs(EnumSet.allOf(DynawoSimulationParameters.SpecificLog.class)); - DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, EventModelsSupplier.empty(), CurvesSupplier.empty(), + DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, EventModelsSupplier.empty(), OutputVariablesSupplier.empty(), VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, reportNode) .join(); @@ -223,9 +225,9 @@ void testSmib() { getResourceAsStream("/smib/eventModels.groovy"), GroovyExtension.find(EventModelGroovyExtension.class, DynawoSimulationProvider.NAME)); - GroovyCurvesSupplier curvesSupplier = new GroovyCurvesSupplier( + GroovyOutputVariablesSupplier outputVariablesSupplier = new GroovyOutputVariablesSupplier( getResourceAsStream("/smib/curves.groovy"), - GroovyExtension.find(CurveGroovyExtension.class, DynawoSimulationProvider.NAME)); + GroovyExtension.find(OutputVariableGroovyExtension.class, DynawoSimulationProvider.NAME)); List modelsParameters = ParametersXml.load(getResourceAsStream("/smib/SMIB.par")); ParametersSet networkParameters = ParametersXml.load(getResourceAsStream("/smib/network.par"), "8"); @@ -236,7 +238,7 @@ void testSmib() { .setSolverType(DynawoSimulationParameters.SolverType.IDA) .setWriteFinalState(false); - DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, + DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, outputVariablesSupplier, VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); @@ -265,7 +267,7 @@ void testSimulationError() { .setSolverParameters(ParametersXml.load(getResourceAsStream("/error/solvers.par"), "3")) .setSolverType(DynawoSimulationParameters.SolverType.SIM); - DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, CurvesSupplier.empty(), + DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, OutputVariablesSupplier.empty(), VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); @@ -291,7 +293,7 @@ void testIeee14DynawoSuppliers() { .setSolverType(DynawoSimulationParameters.SolverType.IDA) .setTimelineExportMode(DynawoSimulationParameters.ExportMode.XML); - DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, CurvesSupplier.empty(), + DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, OutputVariablesSupplier.empty(), VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); @@ -327,7 +329,7 @@ void testIEEE14SignalN() { .setSolverType(DynawoSimulationParameters.SolverType.SIM) .setTimelineExportMode(DynawoSimulationParameters.ExportMode.XML); - DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, CurvesSupplier.empty(), + DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, OutputVariablesSupplier.empty(), VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); diff --git a/dynawo-integration-tests/src/test/resources/ieee14/disconnectline/curves.groovy b/dynawo-integration-tests/src/test/resources/ieee14/disconnectline/outputVariables.groovy similarity index 95% rename from dynawo-integration-tests/src/test/resources/ieee14/disconnectline/curves.groovy rename to dynawo-integration-tests/src/test/resources/ieee14/disconnectline/outputVariables.groovy index e7acd795b..cd3a671b7 100644 --- a/dynawo-integration-tests/src/test/resources/ieee14/disconnectline/curves.groovy +++ b/dynawo-integration-tests/src/test/resources/ieee14/disconnectline/outputVariables.groovy @@ -5,12 +5,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +package ieee14.disconnectline + import com.powsybl.iidm.network.Bus import com.powsybl.iidm.network.Generator import com.powsybl.iidm.network.Load for (Bus bus : network.busBreakerView.buses) { - curve { + fsv { staticId bus.id variable "Upu_value" } diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/DynawoSimulationContext.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/DynawoSimulationContext.java index fa2ac14b9..116e34051 100644 --- a/dynawo-simulation/src/main/java/com/powsybl/dynawo/DynawoSimulationContext.java +++ b/dynawo-simulation/src/main/java/com/powsybl/dynawo/DynawoSimulationContext.java @@ -8,9 +8,8 @@ import com.powsybl.commons.PowsyblException; import com.powsybl.commons.report.ReportNode; -import com.powsybl.dynamicsimulation.Curve; import com.powsybl.dynamicsimulation.DynamicSimulationParameters; -import com.powsybl.dynawo.curves.DynawoCurve; +import com.powsybl.dynamicsimulation.OutputVariable; import com.powsybl.dynawo.models.AbstractPureDynamicBlackBoxModel; import com.powsybl.dynawo.models.BlackBoxModel; import com.powsybl.dynawo.models.EquipmentBlackBoxModel; @@ -52,7 +51,7 @@ public class DynawoSimulationContext { private final List dynamicModels; private final List eventModels; private final Map staticIdBlackBoxModelMap; - private final List curves; + private final Map> outputVariables; private final Map macroStaticReferences = new LinkedHashMap<>(); private final List macroConnectList = new ArrayList<>(); private final Map macroConnectorsMap = new LinkedHashMap<>(); @@ -62,12 +61,12 @@ public class DynawoSimulationContext { protected final MacroConnectionsAdder macroConnectionsAdder; public DynawoSimulationContext(Network network, String workingVariantId, List dynamicModels, List eventModels, - List curves, DynamicSimulationParameters parameters, DynawoSimulationParameters dynawoSimulationParameters) { - this(network, workingVariantId, dynamicModels, eventModels, curves, parameters, dynawoSimulationParameters, ReportNode.NO_OP); + List outputVariables, DynamicSimulationParameters parameters, DynawoSimulationParameters dynawoSimulationParameters) { + this(network, workingVariantId, dynamicModels, eventModels, outputVariables, parameters, dynawoSimulationParameters, ReportNode.NO_OP); } public DynawoSimulationContext(Network network, String workingVariantId, List dynamicModels, List eventModels, - List curves, DynamicSimulationParameters parameters, DynawoSimulationParameters dynawoSimulationParameters, ReportNode reportNode) { + List outputVariables, DynamicSimulationParameters parameters, DynawoSimulationParameters dynawoSimulationParameters, ReportNode reportNode) { ReportNode contextReportNode = DynawoSimulationReports.createDynawoSimulationContextReportNode(reportNode); this.network = Objects.requireNonNull(network); @@ -95,10 +94,8 @@ public DynawoSimulationContext(Network network, String workingVariantId, List e.setEquipmentHasDynamicModel(this)); - this.curves = Objects.requireNonNull(curves).stream() - .filter(DynawoCurve.class::isInstance) - .map(DynawoCurve.class::cast) - .toList(); + this.outputVariables = Objects.requireNonNull(outputVariables).stream() + .collect(Collectors.groupingBy(OutputVariable::getOutputType)); this.frequencySynchronizer = setupFrequencySynchronizer(); this.macroConnectionsAdder = new MacroConnectionsAdder(this::getDynamicModel, this::getPureDynamicModel, @@ -271,12 +268,16 @@ public List getBlackBoxEventModels() { return eventModels; } - public List getCurves() { - return curves; + public List getOutputVariables(OutputVariable.OutputType type) { + return outputVariables.get(type); + } + + public boolean withCurveVariables() { + return outputVariables.containsKey(OutputVariable.OutputType.CURVE); } - public boolean withCurves() { - return !curves.isEmpty(); + public boolean withFsvVariables() { + return outputVariables.containsKey(OutputVariable.OutputType.FINAL_STATE); } public List getDynamicModelsParameters() { diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/DynawoSimulationHandler.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/DynawoSimulationHandler.java index d0391ed6a..094dd7f15 100644 --- a/dynawo-simulation/src/main/java/com/powsybl/dynawo/DynawoSimulationHandler.java +++ b/dynawo-simulation/src/main/java/com/powsybl/dynawo/DynawoSimulationHandler.java @@ -15,7 +15,8 @@ import com.powsybl.dynamicsimulation.DynamicSimulationResult; import com.powsybl.dynamicsimulation.DynamicSimulationResultImpl; import com.powsybl.dynamicsimulation.TimelineEvent; -import com.powsybl.dynawo.xml.CurvesXml; +import com.powsybl.dynawo.outputvariables.CsvFsvParser; +import com.powsybl.dynawo.xml.OutputVariablesXml; import com.powsybl.dynawo.xml.DydXml; import com.powsybl.dynawo.xml.JobsXml; import com.powsybl.dynawo.xml.ParametersXml; @@ -71,6 +72,7 @@ public final class DynawoSimulationHandler extends AbstractExecutionHandler timeline = new ArrayList<>(); private final Map curves = new HashMap<>(); + private final Map fsv = new HashMap<>(); private DynamicSimulationResult.Status status = DynamicSimulationResult.Status.SUCCESS; private String statusText = ""; @@ -85,14 +87,10 @@ public DynawoSimulationHandler(DynawoSimulationContext context, Command command, @Override public List before(Path workingDir) throws IOException { - Path outputNetworkFile = workingDir.resolve(OUTPUTS_FOLDER).resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_IIDM_FILENAME); - if (Files.exists(outputNetworkFile)) { - Files.delete(outputNetworkFile); - } - Path curvesPath = workingDir.resolve(CURVES_OUTPUT_PATH).toAbsolutePath().resolve(CURVES_FILENAME); - if (Files.exists(curvesPath)) { - Files.delete(curvesPath); - } + Path basePath = workingDir.resolve(OUTPUTS_FOLDER); + deleteExistingFile(basePath, FINAL_STATE_FOLDER, OUTPUT_IIDM_FILENAME); + deleteExistingFile(basePath, CURVES_OUTPUT_PATH, CURVES_FILENAME); + deleteExistingFile(basePath, FSV_OUTPUT_PATH, FSV_OUTPUT_FILENAME); writeInputFiles(workingDir); return getCommandExecutions(command); } @@ -102,25 +100,12 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th Path outputsFolder = workingDir.resolve(OUTPUTS_FOLDER); context.getNetwork().getVariantManager().setWorkingVariant(context.getWorkingVariantId()); - DynawoSimulationParameters parameters = context.getDynawoSimulationParameters(); - DumpFileParameters dumpFileParameters = parameters.getDumpFileParameters(); - - setDynawoLog(outputsFolder, parameters.getSpecificLogs()); - // Error file + setDynawoLog(outputsFolder, context.getDynawoSimulationParameters().getSpecificLogs()); Path errorFile = workingDir.resolve(ERROR_FILENAME); if (Files.exists(errorFile)) { Matcher errorMatcher = Pattern.compile(DYNAWO_ERROR_PATTERN + "(.*)").matcher(Files.readString(errorFile)); if (!errorMatcher.find()) { - if (parameters.isWriteFinalState()) { - updateNetwork(outputsFolder); - } - if (dumpFileParameters.exportDumpFile()) { - setDumpFile(outputsFolder, dumpFileParameters.dumpFileFolder(), workingDir.getFileName()); - } - setTimeline(outputsFolder); - if (context.withCurves()) { - setCurves(workingDir); - } + setSuccessOutputs(workingDir, outputsFolder); } else { status = DynamicSimulationResult.Status.FAILURE; statusText = errorMatcher.group().substring(DYNAWO_ERROR_PATTERN.length()); @@ -131,7 +116,25 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th statusText = "Dynawo error log file not found"; } - return new DynamicSimulationResultImpl(status, statusText, curves, timeline); + return new DynamicSimulationResultImpl(status, statusText, curves, fsv, timeline); + } + + private void setSuccessOutputs(Path workingDir, Path outputsFolder) throws IOException { + DynawoSimulationParameters parameters = context.getDynawoSimulationParameters(); + if (parameters.isWriteFinalState()) { + updateNetwork(outputsFolder); + } + DumpFileParameters dumpFileParameters = parameters.getDumpFileParameters(); + if (dumpFileParameters.exportDumpFile()) { + setDumpFile(outputsFolder, dumpFileParameters.dumpFileFolder(), workingDir.getFileName()); + } + setTimeline(outputsFolder); + if (context.withCurveVariables()) { + setCurves(outputsFolder); + } + if (context.withFsvVariables()) { + setFinalStateValues(outputsFolder); + } } private void setDynawoLog(Path outputsFolder, Set specificLogs) throws IOException { @@ -190,7 +193,7 @@ private void setTimeline(Path outputsFolder) { } private void setCurves(Path workingDir) { - Path curvesPath = workingDir.resolve(CURVES_OUTPUT_PATH).toAbsolutePath().resolve(CURVES_FILENAME); + Path curvesPath = workingDir.resolve(CURVES_OUTPUT_PATH).resolve(CURVES_FILENAME); if (Files.exists(curvesPath)) { TimeSeries.parseCsv(curvesPath, new TimeSeriesCsvConfig(TimeSeriesConstants.DEFAULT_SEPARATOR, false, TimeSeries.TimeFormat.FRACTIONS_OF_SECOND)) .values().forEach(l -> l.forEach(curve -> curves.put(curve.getMetadata().getName(), (DoubleTimeSeries) curve))); @@ -201,13 +204,27 @@ private void setCurves(Path workingDir) { } } + private void setFinalStateValues(Path workingDir) { + Path fsvPath = workingDir.resolve(FSV_OUTPUT_PATH).resolve(FSV_OUTPUT_FILENAME); + if (Files.exists(fsvPath)) { + new CsvFsvParser(';').parse(fsvPath).forEach(e -> fsv.put(e.model() + "_" + e.variable(), e.value())); + } else { + LOGGER.warn("Final state values folder not found"); + status = DynamicSimulationResult.Status.FAILURE; + statusText = "Dynawo final state values folder not found"; + } + } + private void writeInputFiles(Path workingDir) throws IOException { DynawoUtil.writeIidm(dynawoInput, workingDir.resolve(NETWORK_FILENAME)); JobsXml.write(workingDir, context); DydXml.write(workingDir, context); ParametersXml.write(workingDir, context); - if (context.withCurves()) { - CurvesXml.write(workingDir, context); + if (context.withCurveVariables()) { + OutputVariablesXml.writeCurve(workingDir, context); + } + if (context.withFsvVariables()) { + OutputVariablesXml.writeFsv(workingDir, context); } DumpFileParameters dumpFileParameters = context.getDynawoSimulationParameters().getDumpFileParameters(); if (dumpFileParameters.useDumpFile()) { @@ -217,4 +234,15 @@ private void writeInputFiles(Path workingDir) throws IOException { } } } + + private static void deleteExistingFile(Path basePath, String... elements) throws IOException { + Path finalPath = basePath; + for (String element : elements) { + finalPath = finalPath.resolve(element); + if (!Files.exists(finalPath)) { + return; + } + } + Files.delete(finalPath); + } } diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/DynawoSimulationProvider.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/DynawoSimulationProvider.java index 4068d6a4d..343fbddbc 100644 --- a/dynawo-simulation/src/main/java/com/powsybl/dynawo/DynawoSimulationProvider.java +++ b/dynawo-simulation/src/main/java/com/powsybl/dynawo/DynawoSimulationProvider.java @@ -76,11 +76,11 @@ public static Command getVersionCommand(DynawoSimulationConfig dynawoSimulationC } @Override - public CompletableFuture run(Network network, DynamicModelsSupplier dynamicModelsSupplier, EventModelsSupplier eventModelsSupplier, CurvesSupplier curvesSupplier, String workingVariantId, + public CompletableFuture run(Network network, DynamicModelsSupplier dynamicModelsSupplier, EventModelsSupplier eventModelsSupplier, OutputVariablesSupplier outputVariablesSupplier, String workingVariantId, ComputationManager computationManager, DynamicSimulationParameters parameters, ReportNode reportNode) { Objects.requireNonNull(dynamicModelsSupplier); Objects.requireNonNull(eventModelsSupplier); - Objects.requireNonNull(curvesSupplier); + Objects.requireNonNull(outputVariablesSupplier); Objects.requireNonNull(workingVariantId); Objects.requireNonNull(parameters); Objects.requireNonNull(reportNode); @@ -92,7 +92,7 @@ public CompletableFuture run(Network network, DynamicMo DynawoSimulationContext context = new DynawoSimulationContext(network, workingVariantId, BlackBoxSupplierUtils.getBlackBoxModelList(dynamicModelsSupplier, network, dsReportNode), BlackBoxSupplierUtils.getBlackBoxModelList(eventModelsSupplier, network, dsReportNode), - curvesSupplier.get(network), + outputVariablesSupplier.get(network), parameters, DynawoSimulationParameters.load(parameters), reportNode); diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/builders/BuilderReports.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/builders/BuilderReports.java index e3a408961..da8d322d2 100644 --- a/dynawo-simulation/src/main/java/com/powsybl/dynawo/builders/BuilderReports.java +++ b/dynawo-simulation/src/main/java/com/powsybl/dynawo/builders/BuilderReports.java @@ -55,9 +55,9 @@ public static void reportModelInstantiationFailure(ReportNode reportNode, String .add(); } - public static void reportCurveInstantiationFailure(ReportNode reportNode, String id) { + public static void reportOutputVariableInstantiationFailure(ReportNode reportNode, String id) { reportNode.newReportNode() - .withMessageTemplate("curveInstantiationError", "Curve ${id} cannot be instantiated") + .withMessageTemplate("outputVariableInstantiationError", "Output variable ${id} cannot be instantiated") .withUntypedValue("id", id) .withSeverity(TypedValue.WARN_SEVERITY) .add(); diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/CsvFsvParser.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/CsvFsvParser.java new file mode 100644 index 000000000..30ec5d088 --- /dev/null +++ b/dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/CsvFsvParser.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2023, 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.dynawo.outputvariables; + +import com.powsybl.dynawo.commons.AbstractCsvParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Optional; + +/** + * @author Laurent Issertial {@literal } + */ +public final class CsvFsvParser extends AbstractCsvParser { + + private static final Logger LOGGER = LoggerFactory.getLogger(CsvFsvParser.class); + + private static final int NB_COLUMNS = 4; + + public CsvFsvParser() { + this(DEFAULT_SEPARATOR); + } + + public CsvFsvParser(char separator) { + super(separator, true); + } + + @Override + protected Optional createEntry(String[] tokens) { + String model = tokens[0]; + String variable = tokens[1]; + String value = tokens[2]; + if (model == null || variable == null || value == null) { + LOGGER.warn("Inconsistent FSV entry (model: '{}', variable: '{}', value: '{}')", model, variable, value); + } else { + try { + double valueD = Double.parseDouble(value); + return Optional.of(new FsvEntry(model, variable, valueD)); + } catch (NumberFormatException e) { + LOGGER.warn("Inconsistent value entry '{}'", value); + } + } + return Optional.empty(); + } + + @Override + protected boolean hasCorrectNbColumns(int tokensSize) { + return tokensSize == NB_COLUMNS; + } + + @Override + protected int getNbColumns() { + return NB_COLUMNS; + } +} diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/curves/DynawoCurve.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/DynawoOutputVariable.java similarity index 54% rename from dynawo-simulation/src/main/java/com/powsybl/dynawo/curves/DynawoCurve.java rename to dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/DynawoOutputVariable.java index de9670b7b..27f841f83 100644 --- a/dynawo-simulation/src/main/java/com/powsybl/dynawo/curves/DynawoCurve.java +++ b/dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/DynawoOutputVariable.java @@ -4,30 +4,40 @@ * 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/. */ -package com.powsybl.dynawo.curves; +package com.powsybl.dynawo.outputvariables; -import com.powsybl.dynamicsimulation.Curve; +import com.powsybl.dynamicsimulation.OutputVariable; import java.util.Objects; /** + * @author Laurent Issertial {@literal } * @author Mathieu Bague {@literal } */ -public class DynawoCurve implements Curve { +public class DynawoOutputVariable implements OutputVariable { private final String dynamicModelId; private final String variable; + private final OutputType outputType; - DynawoCurve(String dynamicModelId, String variable) { + DynawoOutputVariable(String dynamicModelId, String variable, OutputType outputType) { this.dynamicModelId = Objects.requireNonNull(dynamicModelId); this.variable = Objects.requireNonNull(variable); + this.outputType = Objects.requireNonNull(outputType); } + @Override public String getModelId() { return dynamicModelId; } - public String getVariable() { + @Override + public String getVariableName() { return variable; } + + @Override + public OutputType getOutputType() { + return outputType; + } } diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/curves/DynawoCurvesBuilder.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/DynawoOutputVariablesBuilder.java similarity index 61% rename from dynawo-simulation/src/main/java/com/powsybl/dynawo/curves/DynawoCurvesBuilder.java rename to dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/DynawoOutputVariablesBuilder.java index a519420f4..260c0f846 100644 --- a/dynawo-simulation/src/main/java/com/powsybl/dynawo/curves/DynawoCurvesBuilder.java +++ b/dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/DynawoOutputVariablesBuilder.java @@ -5,22 +5,22 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * SPDX-License-Identifier: MPL-2.0 */ -package com.powsybl.dynawo.curves; +package com.powsybl.dynawo.outputvariables; import com.powsybl.commons.report.ReportNode; -import com.powsybl.dynamicsimulation.Curve; +import com.powsybl.dynamicsimulation.OutputVariable; import com.powsybl.dynawo.builders.BuilderReports; import java.util.*; import java.util.function.Consumer; /** - * A curve for
Dynawo
can be defined using {@code staticId} and {@code variable} or {@code dynamicModelId} and {@code variable}. + * An output variable for
Dynawo
can be defined using {@code staticId} and {@code variable} or {@code dynamicModelId} and {@code variable}. * Definition with {@code staticId} and {@code variable} are used when no explicit dynamic component exists. *
Dynawo
expects {@code dynamicModelId} = “NETWORK” for these variables. * @author Laurent Issertial {@literal } */ -public class DynawoCurvesBuilder { +public class DynawoOutputVariablesBuilder { private static final String DEFAULT_DYNAMIC_MODEL_ID = "NETWORK"; @@ -29,40 +29,46 @@ public class DynawoCurvesBuilder { private String dynamicModelId; private String staticId; private List variables; + private OutputVariable.OutputType type = OutputVariable.OutputType.CURVE; - public DynawoCurvesBuilder(ReportNode reportNode) { + public DynawoOutputVariablesBuilder(ReportNode reportNode) { this.reportNode = reportNode; } - public DynawoCurvesBuilder() { + public DynawoOutputVariablesBuilder() { this(ReportNode.NO_OP); } - public DynawoCurvesBuilder dynamicModelId(String dynamicModelId) { + public DynawoOutputVariablesBuilder dynamicModelId(String dynamicModelId) { this.dynamicModelId = dynamicModelId; return this; } - public DynawoCurvesBuilder staticId(String staticId) { + public DynawoOutputVariablesBuilder staticId(String staticId) { this.staticId = staticId; return this; } - public DynawoCurvesBuilder variables(String... variables) { + public DynawoOutputVariablesBuilder variables(String... variables) { this.variables = List.of(variables); return this; } - public DynawoCurvesBuilder variables(List variables) { + public DynawoOutputVariablesBuilder variables(List variables) { this.variables = variables; return this; } - public DynawoCurvesBuilder variable(String variable) { + public DynawoOutputVariablesBuilder variable(String variable) { this.variables = List.of(variable); return this; } + public DynawoOutputVariablesBuilder outputType(OutputVariable.OutputType type) { + this.type = type; + return this; + } + private String getId() { return dynamicModelId != null ? dynamicModelId : staticId; } @@ -83,22 +89,23 @@ private void checkData() { private boolean isInstantiable() { checkData(); if (!isInstantiable) { - BuilderReports.reportCurveInstantiationFailure(reportNode, getId()); + BuilderReports.reportOutputVariableInstantiationFailure(reportNode, getId()); } return isInstantiable; } - public void add(Consumer curveConsumer) { + public void add(Consumer outputVariableConsumer) { if (isInstantiable()) { boolean hasDynamicModelId = dynamicModelId != null; String id = hasDynamicModelId ? dynamicModelId : DEFAULT_DYNAMIC_MODEL_ID; - variables.forEach(v -> curveConsumer.accept(new DynawoCurve(id, hasDynamicModelId ? v : staticId + "_" + v))); + variables.forEach(v -> + outputVariableConsumer.accept(new DynawoOutputVariable(id, hasDynamicModelId ? v : staticId + "_" + v, type))); } } - public List build() { - List curves = new ArrayList<>(); - add(curves::add); - return curves; + public List build() { + List outputVariables = new ArrayList<>(); + add(outputVariables::add); + return outputVariables; } } diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/FsvEntry.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/FsvEntry.java new file mode 100644 index 000000000..a509bd195 --- /dev/null +++ b/dynawo-simulation/src/main/java/com/powsybl/dynawo/outputvariables/FsvEntry.java @@ -0,0 +1,14 @@ +/** + * 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.dynawo.outputvariables; + +/** + * @author Laurent Issertial {@literal } + */ +public record FsvEntry(String model, String variable, double value) { +} diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/suppliers/curves/CurvesJsonDeserializer.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/suppliers/curves/CurvesJsonDeserializer.java deleted file mode 100644 index 5f131b9d1..000000000 --- a/dynawo-simulation/src/main/java/com/powsybl/dynawo/suppliers/curves/CurvesJsonDeserializer.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * 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.dynawo.suppliers.curves; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import com.powsybl.commons.json.JsonUtil; -import com.powsybl.dynamicsimulation.Curve; -import com.powsybl.dynawo.curves.DynawoCurvesBuilder; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.function.Supplier; - -/** - * @author Laurent Issertial {@literal } - */ -public class CurvesJsonDeserializer extends StdDeserializer> { - - private final transient Supplier builderConstructor; - - public CurvesJsonDeserializer(Supplier builderConstructor) { - super(List.class); - this.builderConstructor = builderConstructor; - } - - public CurvesJsonDeserializer() { - this(DynawoCurvesBuilder::new); - } - - @Override - public List deserialize(JsonParser parser, DeserializationContext context) { - List modelConfigList = new ArrayList<>(); - JsonUtil.parseObject(parser, name -> { - if (name.equals("curves")) { - JsonUtil.parseObjectArray(parser, modelConfigList::add, this::parseCurvesBuilder); - return true; - } - return false; - }); - return modelConfigList.stream() - .flatMap(b -> b.build().stream()) - .filter(Objects::nonNull) - .toList(); - } - - private DynawoCurvesBuilder parseCurvesBuilder(JsonParser parser) { - DynawoCurvesBuilder curvesBuilder = builderConstructor.get(); - JsonUtil.parseObject(parser, name -> { - boolean handled = true; - switch (name) { - case "dynamicModelId" -> curvesBuilder.dynamicModelId(parser.nextTextValue()); - case "staticId" -> curvesBuilder.staticId(parser.nextTextValue()); - case "variable" -> curvesBuilder.variable(parser.nextTextValue()); - case "variables" -> curvesBuilder.variables(JsonUtil.parseStringArray(parser)); - default -> handled = false; - } - return handled; - }); - return curvesBuilder; - } -} diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/suppliers/outputvariables/OutputVariablesJsonDeserializer.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/suppliers/outputvariables/OutputVariablesJsonDeserializer.java new file mode 100644 index 000000000..55c16e04d --- /dev/null +++ b/dynawo-simulation/src/main/java/com/powsybl/dynawo/suppliers/outputvariables/OutputVariablesJsonDeserializer.java @@ -0,0 +1,73 @@ +/** + * 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.dynawo.suppliers.outputvariables; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.powsybl.commons.json.JsonUtil; +import com.powsybl.dynamicsimulation.OutputVariable; +import com.powsybl.dynawo.outputvariables.DynawoOutputVariablesBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.Supplier; + +/** + * @author Laurent Issertial {@literal } + */ +public class OutputVariablesJsonDeserializer extends StdDeserializer> { + + private final transient Supplier builderConstructor; + + public OutputVariablesJsonDeserializer(Supplier builderConstructor) { + super(List.class); + this.builderConstructor = builderConstructor; + } + + public OutputVariablesJsonDeserializer() { + this(DynawoOutputVariablesBuilder::new); + } + + @Override + public List deserialize(JsonParser parser, DeserializationContext context) { + List modelConfigList = new ArrayList<>(); + JsonUtil.parseObject(parser, name -> { + if (name.equals("curves")) { + JsonUtil.parseObjectArray(parser, modelConfigList::add, p -> parseOutputVariablesBuilder(p, OutputVariable.OutputType.CURVE)); + return true; + } else if (name.equals("fsv")) { + JsonUtil.parseObjectArray(parser, modelConfigList::add, p -> parseOutputVariablesBuilder(p, OutputVariable.OutputType.FINAL_STATE)); + return true; + } + return false; + }); + return modelConfigList.stream() + .flatMap(b -> b.build().stream()) + .filter(Objects::nonNull) + .toList(); + } + + private DynawoOutputVariablesBuilder parseOutputVariablesBuilder(JsonParser parser, OutputVariable.OutputType outputType) { + DynawoOutputVariablesBuilder variablesBuilder = builderConstructor.get(); + variablesBuilder.outputType(outputType); + JsonUtil.parseObject(parser, name -> { + boolean handled = true; + switch (name) { + case "dynamicModelId" -> variablesBuilder.dynamicModelId(parser.nextTextValue()); + case "staticId" -> variablesBuilder.staticId(parser.nextTextValue()); + case "variable" -> variablesBuilder.variable(parser.nextTextValue()); + case "variables" -> variablesBuilder.variables(JsonUtil.parseStringArray(parser)); + default -> handled = false; + } + return handled; + }); + return variablesBuilder; + } +} diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/CurvesXml.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/CurvesXml.java deleted file mode 100644 index bb45bee41..000000000 --- a/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/CurvesXml.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2020, 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/. - */ -package com.powsybl.dynawo.xml; - -import com.powsybl.dynawo.DynawoSimulationContext; -import com.powsybl.dynawo.curves.DynawoCurve; - -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; -import java.io.IOException; -import java.nio.file.Path; - -import static com.powsybl.dynawo.xml.DynawoSimulationConstants.CRV_FILENAME; -import static com.powsybl.dynawo.xml.DynawoSimulationXmlConstants.DYN_URI; - -/** - * @author Marcos de Miguel {@literal } - */ -public final class CurvesXml extends AbstractXmlDynawoSimulationWriter { - - private CurvesXml() { - super(CRV_FILENAME, "curvesInput"); - } - - public static void write(Path workingDir, DynawoSimulationContext context) throws IOException { - new CurvesXml().createXmlFileFromContext(workingDir, context); - } - - @Override - public void write(XMLStreamWriter writer, DynawoSimulationContext context) throws XMLStreamException { - for (DynawoCurve dynCurve : context.getCurves()) { - writer.writeEmptyElement(DYN_URI, "curve"); - writer.writeAttribute("model", dynCurve.getModelId()); - writer.writeAttribute("variable", dynCurve.getVariable()); - } - } -} diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/DynawoSimulationConstants.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/DynawoSimulationConstants.java index e9f5c1e38..8fe746bd8 100644 --- a/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/DynawoSimulationConstants.java +++ b/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/DynawoSimulationConstants.java @@ -19,10 +19,16 @@ public final class DynawoSimulationConstants { public static final String CRV_FILENAME = "powsybl_dynawo.crv"; - public static final String CURVES_OUTPUT_PATH = "outputs/curves"; + public static final String FSV_FILENAME = "powsybl_dynawo.fsv"; + + public static final String CURVES_OUTPUT_PATH = "curves"; public static final String CURVES_FILENAME = "curves.csv"; + public static final String FSV_OUTPUT_PATH = "finalStateValues"; + + public static final String FSV_OUTPUT_FILENAME = "finalStateValues.csv"; + public static final String MULTIPLE_JOBS_FILENAME = "multiple_jobs.xml"; public static final String AGGREGATED_RESULTS = "aggregatedResults.xml"; diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/JobsXml.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/JobsXml.java index fc1e185de..e0e436383 100644 --- a/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/JobsXml.java +++ b/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/JobsXml.java @@ -24,6 +24,8 @@ */ public final class JobsXml extends AbstractXmlDynawoSimulationWriter { + private static final String EXPORT_MODE = "exportMode"; + private JobsXml() { super(JOBS_FILENAME, "jobs"); } @@ -96,16 +98,22 @@ private static void writeOutput(XMLStreamWriter writer, DynawoSimulationContext writer.writeAttribute("global", Boolean.toString(false)); writer.writeEmptyElement(DYN_URI, "timeline"); - writer.writeAttribute("exportMode", parameters.getTimelineExportMode().toString()); + writer.writeAttribute(EXPORT_MODE, parameters.getTimelineExportMode().toString()); writer.writeEmptyElement(DYN_URI, "finalState"); writer.writeAttribute("exportIIDMFile", Boolean.toString(parameters.isWriteFinalState())); writer.writeAttribute("exportDumpFile", Boolean.toString(parameters.getDumpFileParameters().exportDumpFile())); - if (context.withCurves()) { + if (context.withCurveVariables()) { writer.writeEmptyElement(DYN_URI, "curves"); - writer.writeAttribute("inputFile", DynawoSimulationConstants.CRV_FILENAME); - writer.writeAttribute("exportMode", DynawoSimulationParameters.ExportMode.CSV.toString()); + writer.writeAttribute("inputFile", CRV_FILENAME); + writer.writeAttribute(EXPORT_MODE, DynawoSimulationParameters.ExportMode.CSV.toString()); + } + + if (context.withFsvVariables()) { + writer.writeEmptyElement(DYN_URI, "finalStateValues"); + writer.writeAttribute("inputFile", FSV_FILENAME); + writer.writeAttribute(EXPORT_MODE, DynawoSimulationParameters.ExportMode.CSV.toString()); } writer.writeStartElement(DYN_URI, "logs"); diff --git a/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/OutputVariablesXml.java b/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/OutputVariablesXml.java new file mode 100644 index 000000000..569ebe6f1 --- /dev/null +++ b/dynawo-simulation/src/main/java/com/powsybl/dynawo/xml/OutputVariablesXml.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2020, 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/. + */ +package com.powsybl.dynawo.xml; + +import com.powsybl.dynamicsimulation.OutputVariable; +import com.powsybl.dynawo.DynawoSimulationContext; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; +import java.io.IOException; +import java.nio.file.Path; + +import static com.powsybl.dynawo.xml.DynawoSimulationConstants.CRV_FILENAME; +import static com.powsybl.dynawo.xml.DynawoSimulationConstants.FSV_FILENAME; +import static com.powsybl.dynawo.xml.DynawoSimulationXmlConstants.DYN_URI; + +/** + * @author Marcos de Miguel {@literal } + */ +public final class OutputVariablesXml extends AbstractXmlDynawoSimulationWriter { + + private final OutputVariable.OutputType outputType; + private final String xmlElementName; + + private OutputVariablesXml(String xmlFileName, String xmlRootName, String xmlElementName, OutputVariable.OutputType outputType) { + super(xmlFileName, xmlRootName); + this.xmlElementName = xmlElementName; + this.outputType = outputType; + } + + public static void writeCurve(Path workingDir, DynawoSimulationContext context) throws IOException { + new OutputVariablesXml(CRV_FILENAME, "curvesInput", "curve", OutputVariable.OutputType.CURVE) + .createXmlFileFromContext(workingDir, context); + } + + public static void writeFsv(Path workingDir, DynawoSimulationContext context) throws IOException { + new OutputVariablesXml(FSV_FILENAME, "finalStateValuesInput", "finalStateValue", OutputVariable.OutputType.FINAL_STATE) + .createXmlFileFromContext(workingDir, context); + } + + @Override + public void write(XMLStreamWriter writer, DynawoSimulationContext context) throws XMLStreamException { + for (OutputVariable variable : context.getOutputVariables(outputType)) { + writer.writeEmptyElement(DYN_URI, xmlElementName); + writer.writeAttribute("model", variable.getModelId()); + writer.writeAttribute("variable", variable.getVariableName()); + } + } +} diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/DynawoProviderTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/DynawoProviderTest.java index e9e57124d..cb584114c 100644 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/DynawoProviderTest.java +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/DynawoProviderTest.java @@ -14,7 +14,7 @@ import com.powsybl.computation.local.LocalComputationConfig; import com.powsybl.computation.local.LocalComputationManager; import com.powsybl.dynamicsimulation.*; -import com.powsybl.dynawo.curves.DynawoCurvesBuilder; +import com.powsybl.dynawo.outputvariables.DynawoOutputVariablesBuilder; import com.powsybl.dynawo.commons.DynawoConstants; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.Substation; @@ -53,10 +53,10 @@ public void setUp() throws IOException { config = DynawoSimulationConfig.load(); } - public static class CurvesSupplierMock implements CurvesSupplier { + public static class OutputVariablesSupplierMock implements OutputVariablesSupplier { @Override - public List get(Network network, ReportNode reportNode) { - return new DynawoCurvesBuilder().dynamicModelId("bus").variable("uPu").build(); + public List get(Network network, ReportNode reportNode) { + return new DynawoOutputVariablesBuilder().dynamicModelId("bus").variable("uPu").build(); } } @@ -91,7 +91,7 @@ void testWithMergeLoads() throws Exception { DynamicSimulation.Runner dynawoSimulation = DynamicSimulation.find(); assertEquals(DynawoSimulationProvider.NAME, dynawoSimulation.getName()); DynamicSimulationResult result = dynawoSimulation.run(network, (n, r) -> Collections.emptyList(), EventModelsSupplier.empty(), - CurvesSupplier.empty(), network.getVariantManager().getWorkingVariantId(), + OutputVariablesSupplier.empty(), network.getVariantManager().getWorkingVariantId(), computationManager, DynamicSimulationParameters.load(), NO_OP); assertNotNull(result); } @@ -109,7 +109,7 @@ void testWithoutMergeLoads() throws Exception { assertEquals(DynawoSimulationProvider.NAME, dynawoSimulation.getName()); DynamicSimulationResult result = dynawoSimulation.run(network, (n, r) -> Collections.emptyList(), EventModelsSupplier.empty(), - CurvesSupplier.empty(), network.getVariantManager().getWorkingVariantId(), + OutputVariablesSupplier.empty(), network.getVariantManager().getWorkingVariantId(), computationManager, dynamicSimulationParameters, NO_OP); assertNotNull(result); } @@ -133,7 +133,7 @@ void testWithDump() throws Exception { assertEquals(DynawoSimulationProvider.NAME, dynawoSimulation.getName()); DynamicSimulationResult result = dynawoSimulation.run(network, (n, r) -> Collections.emptyList(), EventModelsSupplier.empty(), - CurvesSupplier.empty(), network.getVariantManager().getWorkingVariantId(), + OutputVariablesSupplier.empty(), network.getVariantManager().getWorkingVariantId(), computationManager, dynamicSimulationParameters, NO_OP); assertNotNull(result); } @@ -146,7 +146,7 @@ void testFail() throws Exception { DynamicSimulation.Runner dynawoSimulation = DynamicSimulation.find(); assertEquals(DynawoSimulationProvider.NAME, dynawoSimulation.getName()); DynamicSimulationResult result = dynawoSimulation.run(network, (n, r) -> Collections.emptyList(), EventModelsSupplier.empty(), - CurvesSupplier.empty(), network.getVariantManager().getWorkingVariantId(), + OutputVariablesSupplier.empty(), network.getVariantManager().getWorkingVariantId(), computationManager, DynamicSimulationParameters.load(), NO_OP); assertNotNull(result); assertEquals(FAILURE, result.getStatus()); @@ -160,7 +160,7 @@ void testWithoutCurves() throws Exception { DynamicSimulation.Runner dynawoSimulation = DynamicSimulation.find(); assertEquals(DynawoSimulationProvider.NAME, dynawoSimulation.getName()); DynamicSimulationResult result = dynawoSimulation.run(network, (n, r) -> Collections.emptyList(), EventModelsSupplier.empty(), - new CurvesSupplierMock(), network.getVariantManager().getWorkingVariantId(), + new OutputVariablesSupplierMock(), network.getVariantManager().getWorkingVariantId(), computationManager, DynamicSimulationParameters.load(), NO_OP); assertNotNull(result); assertEquals(FAILURE, result.getStatus()); @@ -195,7 +195,7 @@ void testCallingBadVersionDynawo() throws Exception { assertEquals(DynawoSimulationProvider.NAME, dynawoSimulation.getName()); DynamicModelsSupplier dms = (n, r) -> Collections.emptyList(); EventModelsSupplier ems = EventModelsSupplier.empty(); - CurvesSupplier cs = CurvesSupplier.empty(); + OutputVariablesSupplier cs = OutputVariablesSupplier.empty(); String wvId = network.getVariantManager().getWorkingVariantId(); DynamicSimulationParameters dsp = DynamicSimulationParameters.load(); PowsyblException e = assertThrows(PowsyblException.class, () -> dynawoSimulation.run(network, dms, ems, cs, wvId, computationManager, dsp, NO_OP)); diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/builders/CurvesBuilderTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/builders/OutputVariablesBuilderTest.java similarity index 62% rename from dynawo-simulation/src/test/java/com/powsybl/dynawo/builders/CurvesBuilderTest.java rename to dynawo-simulation/src/test/java/com/powsybl/dynawo/builders/OutputVariablesBuilderTest.java index 0d4eddf57..8818cf263 100644 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/builders/CurvesBuilderTest.java +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/builders/OutputVariablesBuilderTest.java @@ -2,9 +2,8 @@ import com.powsybl.commons.report.ReportNode; import com.powsybl.commons.test.TestUtil; -import com.powsybl.dynamicsimulation.Curve; -import com.powsybl.dynawo.curves.DynawoCurve; -import com.powsybl.dynawo.curves.DynawoCurvesBuilder; +import com.powsybl.dynamicsimulation.OutputVariable; +import com.powsybl.dynawo.outputvariables.DynawoOutputVariablesBuilder; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -19,7 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -class CurvesBuilderTest { +class OutputVariablesBuilderTest { private ReportNode reporter; @@ -30,31 +29,31 @@ void setup() { @Test void buildFromDynamicId() { - List curveList = new DynawoCurvesBuilder() + List outputVariables = new DynawoOutputVariablesBuilder() .dynamicModelId("BBM_GEN") .variable("generator_omegaPu") .build(); - assertEquals(1, curveList.size()); - DynawoCurve curve = (DynawoCurve) curveList.get(0); - assertEquals("BBM_GEN", curve.getModelId()); - assertEquals("generator_omegaPu", curve.getVariable()); + assertEquals(1, outputVariables.size()); + OutputVariable variable = outputVariables.get(0); + assertEquals("BBM_GEN", variable.getModelId()); + assertEquals("generator_omegaPu", variable.getVariableName()); } @Test void buildFromStaticId() { - List curveList = new DynawoCurvesBuilder() + List outputVariables = new DynawoOutputVariablesBuilder() .staticId("GEN") .variables("generator_omegaPu", "generator_PGen") .build(); - assertEquals(2, curveList.size()); - DynawoCurve curve = (DynawoCurve) curveList.get(0); - assertEquals("NETWORK", curve.getModelId()); - assertEquals("GEN_generator_omegaPu", curve.getVariable()); + assertEquals(2, outputVariables.size()); + OutputVariable variable = outputVariables.get(0); + assertEquals("NETWORK", variable.getModelId()); + assertEquals("GEN_generator_omegaPu", variable.getVariableName()); } @ParameterizedTest(name = "{1}") @MethodSource("provideBuilderError") - void testScriptError(Function builderFunction, boolean isInstantiable, String report) throws IOException { + void testScriptError(Function builderFunction, boolean isInstantiable, String report) throws IOException { boolean hasInstance = !builderFunction.apply(reporter).build().isEmpty(); assertEquals(isInstantiable, hasInstance); checkReportNode(report); @@ -62,8 +61,8 @@ void testScriptError(Function builderFunction, private static Stream provideBuilderError() { return Stream.of( - Arguments.of((Function) r -> - new DynawoCurvesBuilder(r) + Arguments.of((Function) r -> + new DynawoOutputVariablesBuilder(r) .staticId("GEN") .dynamicModelId("BBM_GEN") .variable("uPu"), @@ -72,24 +71,24 @@ private static Stream provideBuilderError() { + Builder tests Both 'dynamicModelId' and 'staticId' are defined, 'dynamicModelId' will be used """), - Arguments.of((Function) r -> - new DynawoCurvesBuilder(r) + Arguments.of((Function) r -> + new DynawoOutputVariablesBuilder(r) .staticId("GEN"), false, """ + Builder tests 'variables' field is not set - Curve GEN cannot be instantiated + Output variable GEN cannot be instantiated """), - Arguments.of((Function) r -> - new DynawoCurvesBuilder(r) + Arguments.of((Function) r -> + new DynawoOutputVariablesBuilder(r) .staticId("GEN") .variables(), false, """ + Builder tests 'variables' list is empty - Curve GEN cannot be instantiated + Output variable GEN cannot be instantiated """) ); } diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/models/buses/StandardBusTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/models/buses/StandardBusTest.java index 7f3f1ac11..0a71e1446 100644 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/models/buses/StandardBusTest.java +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/models/buses/StandardBusTest.java @@ -9,8 +9,8 @@ package com.powsybl.dynawo.models.buses; import com.powsybl.commons.PowsyblException; -import com.powsybl.dynamicsimulation.Curve; import com.powsybl.dynamicsimulation.DynamicSimulationParameters; +import com.powsybl.dynamicsimulation.OutputVariable; import com.powsybl.dynawo.DynawoSimulationContext; import com.powsybl.dynawo.DynawoSimulationParameters; import com.powsybl.dynawo.models.BlackBoxModel; @@ -45,8 +45,8 @@ void connectionToModelWithoutDynamicModelException() { DynawoSimulationParameters dynawoParameters = DynawoSimulationParameters.load(); String workingVariantId = network.getVariantManager().getWorkingVariantId(); List events = Collections.emptyList(); - List curves = Collections.emptyList(); - PowsyblException e = assertThrows(PowsyblException.class, () -> new DynawoSimulationContext(network, workingVariantId, dynamicModels, events, curves, parameters, dynawoParameters)); + List outputVariables = Collections.emptyList(); + PowsyblException e = assertThrows(PowsyblException.class, () -> new DynawoSimulationContext(network, workingVariantId, dynamicModels, events, outputVariables, parameters, dynawoParameters)); assertEquals("The equipment NHV1_NHV2_1 linked to the StandardBus NHV1 does not possess a dynamic model", e.getMessage()); } } diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/models/lines/StandardLineTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/models/lines/StandardLineTest.java index 81e9b2c64..9a150dd0e 100644 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/models/lines/StandardLineTest.java +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/models/lines/StandardLineTest.java @@ -7,8 +7,8 @@ */ package com.powsybl.dynawo.models.lines; -import com.powsybl.dynamicsimulation.Curve; import com.powsybl.dynamicsimulation.DynamicSimulationParameters; +import com.powsybl.dynamicsimulation.OutputVariable; import com.powsybl.dynawo.DynawoSimulationContext; import com.powsybl.dynawo.DynawoSimulationParameters; import com.powsybl.dynawo.models.BlackBoxModel; @@ -52,9 +52,9 @@ void connectionToDynamicOverloadManagementSystemException() { DynawoSimulationParameters dynawoParameters = DynawoSimulationParameters.load(); String workingVariantId = network.getVariantManager().getWorkingVariantId(); List events = Collections.emptyList(); - List curves = Collections.emptyList(); + List outputVariables = Collections.emptyList(); UnsupportedOperationException e = assertThrows(UnsupportedOperationException.class, - () -> new DynawoSimulationContext(network, workingVariantId, dynamicModels, events, curves, parameters, dynawoParameters)); + () -> new DynawoSimulationContext(network, workingVariantId, dynamicModels, events, outputVariables, parameters, dynawoParameters)); assertEquals("i variable not implemented in StandardLine dynawo's model", e.getMessage()); } } diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/outputvariables/CsvFsvParserTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/outputvariables/CsvFsvParserTest.java new file mode 100644 index 000000000..c0961a43d --- /dev/null +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/outputvariables/CsvFsvParserTest.java @@ -0,0 +1,42 @@ +/** + * 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.dynawo.outputvariables; + +import org.junit.jupiter.api.Test; + +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.List; +import java.util.Objects; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Laurent Issertial {@literal } + */ +class CsvFsvParserTest { + + @Test + void testFsvParsing() throws URISyntaxException { + + Path path = Path.of(Objects.requireNonNull(getClass().getResource("/fsv.csv")).toURI()); + List timeline = new CsvFsvParser(';').parse(path); + assertThat(timeline).containsExactly( + new FsvEntry("NETWORK", "_BUS____1_TN_Upu_value", 1.060012), + new FsvEntry("GEN____1_SM", "generator_omegaPu", 1.0), + new FsvEntry("_LOAD___2_EC", "load_PPu", 0.216995)); + } + + @Test + void testInconsistentEntry() throws URISyntaxException { + CsvFsvParser parser = new CsvFsvParser(';'); + Path path = Path.of(Objects.requireNonNull(getClass().getResource("/fsvWrongEntry.csv")).toURI()); + List timeline = parser.parse(path); + assertThat(timeline).isEmpty(); + } +} diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/suppliers/DynawoCurvesJsonDeserializerTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/suppliers/DynawoCurvesJsonDeserializerTest.java deleted file mode 100644 index e9523a8db..000000000 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/suppliers/DynawoCurvesJsonDeserializerTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * 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.dynawo.suppliers; - -import com.powsybl.dynamicsimulation.Curve; -import com.powsybl.dynawo.curves.DynawoCurvesBuilder; -import com.powsybl.dynawo.suppliers.curves.CurvesJsonDeserializer; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Laurent Issertial {@literal } - */ -class DynawoCurvesJsonDeserializerTest { - - @Test - void testCurvesSupplier() throws IOException { - try (InputStream is = getClass().getResourceAsStream("/suppliers/curves.json")) { - List curves = new SupplierJsonDeserializer<>(new CurvesJsonDeserializer()).deserialize(is); - assertThat(curves).usingRecursiveFieldByFieldElementComparatorOnFields() - .containsExactlyInAnyOrderElementsOf(getExpectedCurves()); - } - } - - private static List getExpectedCurves() { - List curves = new ArrayList<>(); - new DynawoCurvesBuilder().dynamicModelId("BBM_GEN").variables("voltageRegulator_EfdPu").add(curves::add); - new DynawoCurvesBuilder().staticId("BUS").variables("Upu_value").add(curves::add); - new DynawoCurvesBuilder().dynamicModelId("BBM_GEN2").variables("generator_omegaPu", "generator_PGen", "generator_UStatorPU").add(curves::add); - new DynawoCurvesBuilder().staticId("LOAD").variables("load_PPu", "load_QPu").add(curves::add); - return curves; - } -} diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/suppliers/DynawoOutputVariablesJsonDeserializerTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/suppliers/DynawoOutputVariablesJsonDeserializerTest.java new file mode 100644 index 000000000..c1dd51ce7 --- /dev/null +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/suppliers/DynawoOutputVariablesJsonDeserializerTest.java @@ -0,0 +1,46 @@ +/** + * 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.dynawo.suppliers; + +import com.powsybl.dynamicsimulation.OutputVariable; +import com.powsybl.dynawo.outputvariables.DynawoOutputVariablesBuilder; +import com.powsybl.dynawo.suppliers.outputvariables.OutputVariablesJsonDeserializer; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Laurent Issertial {@literal } + */ +class DynawoOutputVariablesJsonDeserializerTest { + + @Test + void testOutputVariablesSupplier() throws IOException { + try (InputStream is = getClass().getResourceAsStream("/suppliers/outputVariables.json")) { + List outputVariables = new SupplierJsonDeserializer<>(new OutputVariablesJsonDeserializer()).deserialize(is); + assertThat(outputVariables).usingRecursiveFieldByFieldElementComparatorOnFields() + .containsExactlyInAnyOrderElementsOf(getExpectedOutputVariables()); + } + } + + private static List getExpectedOutputVariables() { + List variables = new ArrayList<>(); + new DynawoOutputVariablesBuilder().dynamicModelId("BBM_GEN").variables("voltageRegulator_EfdPu").add(variables::add); + new DynawoOutputVariablesBuilder().staticId("BUS").variables("Upu_value").add(variables::add); + new DynawoOutputVariablesBuilder().dynamicModelId("BBM_GEN2").variables("generator_omegaPu", "generator_PGen", "generator_UStatorPU").add(variables::add); + new DynawoOutputVariablesBuilder().staticId("LOAD").variables("load_PPu", "load_QPu").outputType(OutputVariable.OutputType.CURVE).add(variables::add); + new DynawoOutputVariablesBuilder().dynamicModelId("BBM_GEN").variables("generator_PGen").outputType(OutputVariable.OutputType.FINAL_STATE).add(variables::add); + new DynawoOutputVariablesBuilder().staticId("LOAD").variables("load_QPu").outputType(OutputVariable.OutputType.FINAL_STATE).add(variables::add); + return variables; + } +} diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/AbstractDynamicModelXmlTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/AbstractDynamicModelXmlTest.java index 4f86ea48d..e3b034e32 100644 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/AbstractDynamicModelXmlTest.java +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/AbstractDynamicModelXmlTest.java @@ -10,8 +10,8 @@ import com.powsybl.commons.report.ReportNode; import com.powsybl.commons.test.AbstractSerDeTest; import com.powsybl.commons.test.TestUtil; -import com.powsybl.dynamicsimulation.Curve; import com.powsybl.dynamicsimulation.DynamicSimulationParameters; +import com.powsybl.dynamicsimulation.OutputVariable; import com.powsybl.dynawo.DynawoSimulationContext; import com.powsybl.dynawo.DynawoSimulationParameters; import com.powsybl.dynawo.models.BlackBoxModel; @@ -46,7 +46,7 @@ public abstract class AbstractDynamicModelXmlTest extends AbstractSerDeTest { protected Network network; protected List dynamicModels = new ArrayList<>(); protected List eventModels = new ArrayList<>(); - protected List curves = new ArrayList<>(); + protected List outputVariables = new ArrayList<>(); protected DynawoSimulationContext context; protected ReportNode reportNode = ReportNode.newRootReportNode().withMessageTemplate("testDyd", "Test DYD").build(); @@ -61,7 +61,7 @@ void setup() { void clear() { dynamicModels.clear(); eventModels.clear(); - curves.clear(); + outputVariables.clear(); } public void validate(String schemaDefinition, String expectedResourceName, Path xmlFile) throws SAXException, IOException { @@ -79,7 +79,7 @@ public void validate(String schemaDefinition, String expectedResourceName, Path void setupDynawoContext() { DynamicSimulationParameters parameters = DynamicSimulationParameters.load(); DynawoSimulationParameters dynawoParameters = DynawoSimulationParameters.load(); - context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, curves, parameters, dynawoParameters, reportNode); + context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, outputVariables, parameters, dynawoParameters, reportNode); } protected abstract void setupNetwork(); diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/AbstractParametrizedDynamicModelXmlTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/AbstractParametrizedDynamicModelXmlTest.java index 746b98fdd..c3b4a7caa 100644 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/AbstractParametrizedDynamicModelXmlTest.java +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/AbstractParametrizedDynamicModelXmlTest.java @@ -10,8 +10,8 @@ import com.powsybl.commons.report.ReportNode; import com.powsybl.commons.test.AbstractSerDeTest; import com.powsybl.commons.test.TestUtil; -import com.powsybl.dynamicsimulation.Curve; import com.powsybl.dynamicsimulation.DynamicSimulationParameters; +import com.powsybl.dynamicsimulation.OutputVariable; import com.powsybl.dynawo.DynawoSimulationContext; import com.powsybl.dynawo.DynawoSimulationParameters; import com.powsybl.dynawo.models.BlackBoxModel; @@ -44,7 +44,7 @@ public abstract class AbstractParametrizedDynamicModelXmlTest extends AbstractSe protected Network network; protected List dynamicModels = new ArrayList<>(); protected List eventModels = new ArrayList<>(); - protected List curves = new ArrayList<>(); + protected List outputVariables = new ArrayList<>(); protected DynawoSimulationContext context; protected ReportNode reportNode = ReportNode.newRootReportNode().withMessageTemplate("testDyd", "Test DYD").build(); @@ -63,7 +63,7 @@ public void validate(String schemaDefinition, String expectedResourceName, Path protected void setupDynawoContext() { DynamicSimulationParameters parameters = DynamicSimulationParameters.load(); DynawoSimulationParameters dynawoParameters = DynawoSimulationParameters.load(); - context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, curves, parameters, dynawoParameters, reportNode); + context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, outputVariables, parameters, dynawoParameters, reportNode); } protected void checkReport(String report) throws IOException { diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/DynamicModelsXmlTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/DynamicModelsXmlTest.java index d6e38cb33..e1dc4c8ba 100644 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/DynamicModelsXmlTest.java +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/DynamicModelsXmlTest.java @@ -35,7 +35,7 @@ class DynamicModelsXmlTest extends DynawoTestUtil { void writeDynamicModel() throws SAXException, IOException { DynamicSimulationParameters parameters = DynamicSimulationParameters.load(); DynawoSimulationParameters dynawoParameters = DynawoSimulationParameters.load(); - DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, new ArrayList<>(), curves, parameters, dynawoParameters); + DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, new ArrayList<>(), outputVariables, parameters, dynawoParameters); DydXml.write(tmpDir, context); validate("dyd.xsd", "dyd.xml", tmpDir.resolve(DynawoSimulationConstants.DYD_FILENAME)); @@ -52,7 +52,7 @@ void writeDynamicModelWithLoadsAndOnlyOneFictitiousGenerator() throws SAXExcepti .parameterSetId("GF") .build()); - DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, new ArrayList<>(), curves, parameters, dynawoParameters); + DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, new ArrayList<>(), outputVariables, parameters, dynawoParameters); DydXml.write(tmpDir, context); validate("dyd.xsd", "dyd_fictitious.xml", tmpDir.resolve(DynawoSimulationConstants.DYD_FILENAME)); @@ -74,7 +74,7 @@ void duplicateStaticId() { dynamicModels.add(load1); dynamicModels.add(load2); String workingVariantId = network.getVariantManager().getWorkingVariantId(); - DynawoSimulationContext context = new DynawoSimulationContext(network, workingVariantId, dynamicModels, eventModels, curves, DynamicSimulationParameters.load(), DynawoSimulationParameters.load()); + DynawoSimulationContext context = new DynawoSimulationContext(network, workingVariantId, dynamicModels, eventModels, outputVariables, DynamicSimulationParameters.load(), DynawoSimulationParameters.load()); Assertions.assertThat(context.getBlackBoxDynamicModels()).containsExactly(load1); } @@ -94,13 +94,13 @@ void duplicateDynamicId() { dynamicModels.add(load1); dynamicModels.add(load2); String workingVariantId = network.getVariantManager().getWorkingVariantId(); - DynawoSimulationContext context = new DynawoSimulationContext(network, workingVariantId, dynamicModels, eventModels, curves, DynamicSimulationParameters.load(), DynawoSimulationParameters.load()); + DynawoSimulationContext context = new DynawoSimulationContext(network, workingVariantId, dynamicModels, eventModels, outputVariables, DynamicSimulationParameters.load(), DynawoSimulationParameters.load()); Assertions.assertThat(context.getBlackBoxDynamicModels()).containsExactly(load1); } @Test void testIncorrectModelException() { - DynawoSimulationContext dc = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, curves, DynamicSimulationParameters.load(), DynawoSimulationParameters.load()); + DynawoSimulationContext dc = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, outputVariables, DynamicSimulationParameters.load(), DynawoSimulationParameters.load()); Identifiable gen = network.getIdentifiable("GEN5"); Exception e = assertThrows(PowsyblException.class, () -> dc.getDynamicModel(gen, LineModel.class, true)); assertEquals("The model identified by the static id GEN5 does not match the expected model (LineModel)", e.getMessage()); diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/DynawoTestUtil.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/DynawoTestUtil.java index 399d56244..30e53581c 100644 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/DynawoTestUtil.java +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/DynawoTestUtil.java @@ -7,8 +7,8 @@ package com.powsybl.dynawo.xml; import com.powsybl.commons.test.AbstractSerDeTest; -import com.powsybl.dynamicsimulation.Curve; -import com.powsybl.dynawo.curves.DynawoCurvesBuilder; +import com.powsybl.dynamicsimulation.OutputVariable; +import com.powsybl.dynawo.outputvariables.DynawoOutputVariablesBuilder; import com.powsybl.dynawo.models.BlackBoxModel; import com.powsybl.dynawo.models.automationsystems.overloadmanagments.DynamicOverloadManagementSystemBuilder; import com.powsybl.dynawo.models.events.EventDisconnectionBuilder; @@ -47,25 +47,34 @@ public class DynawoTestUtil extends AbstractSerDeTest { protected Network network; protected List dynamicModels; protected List eventModels; - protected List curves; + protected List outputVariables; @BeforeEach void setup() { network = createEurostagTutorialExample1WithMoreLoads(); - curves = new ArrayList<>(); - network.getBusBreakerView().getBusStream().forEach(b -> new DynawoCurvesBuilder() + outputVariables = new ArrayList<>(); + + network.getLoadStream().forEach(b -> new DynawoOutputVariablesBuilder() + .staticId(b.getId()) + .variables("load_PPu", "load_QPu") + .outputType(OutputVariable.OutputType.FINAL_STATE) + .add(outputVariables::add)); + + network.getBusBreakerView().getBusStream().forEach(b -> new DynawoOutputVariablesBuilder() .staticId(b.getId()) .variables("Upu_value") - .add(curves::add)); + .outputType(OutputVariable.OutputType.CURVE) + .add(outputVariables::add)); // A curve is made up of the id of the dynamic model and the variable to plot. // The static id of the generator is used as the id of the dynamic model (dynamicModelId). - network.getGeneratorStream().forEach(g -> new DynawoCurvesBuilder() + network.getGeneratorStream().forEach(g -> new DynawoOutputVariablesBuilder() .dynamicModelId(g.getId()) .variables("generator_omegaPu", "generator_PGen", "generator_UStatorPu", "voltageRegulator_UcEfdP", "voltageRegulator_EfdPu") - .add(curves::add)); + .outputType(OutputVariable.OutputType.CURVE) + .add(outputVariables::add)); // Dynamic Models dynamicModels = new ArrayList<>(); diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/EventXmlTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/EventXmlTest.java index d70fbd112..e2c58f790 100644 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/EventXmlTest.java +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/EventXmlTest.java @@ -35,7 +35,7 @@ void writeDynamicModel() throws SAXException, IOException { DynamicSimulationParameters parameters = DynamicSimulationParameters.load(); DynawoSimulationParameters dynawoParameters = DynawoSimulationParameters.load(); DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), - dynamicModels, eventModels, curves, parameters, dynawoParameters); + dynamicModels, eventModels, outputVariables, parameters, dynawoParameters); DydXml.write(tmpDir, context); validate("dyd.xsd", "events.xml", tmpDir.resolve(DynawoSimulationConstants.DYD_FILENAME)); @@ -66,7 +66,7 @@ void duplicateEventId() { eventModels.add(event1Duplicate); eventModels.add(event2Duplicate); String workingVariantId = network.getVariantManager().getWorkingVariantId(); - DynawoSimulationContext context = new DynawoSimulationContext(network, workingVariantId, dynamicModels, eventModels, curves, DynamicSimulationParameters.load(), DynawoSimulationParameters.load()); + DynawoSimulationContext context = new DynawoSimulationContext(network, workingVariantId, dynamicModels, eventModels, outputVariables, DynamicSimulationParameters.load(), DynawoSimulationParameters.load()); Assertions.assertThat(context.getBlackBoxEventModels()).containsExactly(event1, event2); } } diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/JobsXmlTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/JobsXmlTest.java index 607c0d5f6..5270cbb82 100644 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/JobsXmlTest.java +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/JobsXmlTest.java @@ -26,7 +26,7 @@ class JobsXmlTest extends DynawoTestUtil { void writeJob() throws SAXException, IOException { DynamicSimulationParameters parameters = DynamicSimulationParameters.load(); DynawoSimulationParameters dynawoParameters = DynawoSimulationParameters.load(); - DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, curves, parameters, dynawoParameters); + DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, outputVariables, parameters, dynawoParameters); JobsXml.write(tmpDir, context); validate("jobs.xsd", "jobs.xml", tmpDir.resolve(DynawoSimulationConstants.JOBS_FILENAME)); @@ -37,7 +37,7 @@ void writeJobWithDumpFile() throws SAXException, IOException { DynamicSimulationParameters parameters = DynamicSimulationParameters.load(); DynawoSimulationParameters dynawoParameters = DynawoSimulationParameters.load() .setDumpFileParameters(DumpFileParameters.createImportExportDumpFileParameters(Path.of("/dumpFiles"), "dump.dmp")); - DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, curves, parameters, dynawoParameters); + DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, outputVariables, parameters, dynawoParameters); JobsXml.write(tmpDir, context); validate("jobs.xsd", "jobsWithDump.xml", tmpDir.resolve(DynawoSimulationConstants.JOBS_FILENAME)); @@ -48,7 +48,7 @@ void writeJobWithSpecificLogs() throws SAXException, IOException { DynamicSimulationParameters parameters = DynamicSimulationParameters.load(); DynawoSimulationParameters dynawoParameters = DynawoSimulationParameters.load() .setSpecificLogs(EnumSet.allOf(DynawoSimulationParameters.SpecificLog.class)); - DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, curves, parameters, dynawoParameters); + DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, outputVariables, parameters, dynawoParameters); JobsXml.write(tmpDir, context); validate("jobs.xsd", "jobsWithSpecificLogs.xml", tmpDir.resolve(DynawoSimulationConstants.JOBS_FILENAME)); diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/CurvesXmlTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/OutputVariablesXmlTest.java similarity index 72% rename from dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/CurvesXmlTest.java rename to dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/OutputVariablesXmlTest.java index 71a55854a..7cc50512e 100644 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/CurvesXmlTest.java +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/OutputVariablesXmlTest.java @@ -17,16 +17,17 @@ /** * @author Marcos de Miguel {@literal } */ -class CurvesXmlTest extends DynawoTestUtil { +class OutputVariablesXmlTest extends DynawoTestUtil { @Test - void writeCurve() throws SAXException, IOException { + void writeOutputVariables() throws SAXException, IOException { DynamicSimulationParameters parameters = DynamicSimulationParameters.load(); DynawoSimulationParameters dynawoParameters = DynawoSimulationParameters.load(); - DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, curves, parameters, dynawoParameters); + DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, outputVariables, parameters, dynawoParameters); - CurvesXml.write(tmpDir, context); + OutputVariablesXml.writeCurve(tmpDir, context); validate("curvesInput.xsd", "curvesInput.xml", tmpDir.resolve(DynawoSimulationConstants.CRV_FILENAME)); + OutputVariablesXml.writeFsv(tmpDir, context); + validate("fsvInput.xsd", "fsvInput.xml", tmpDir.resolve(DynawoSimulationConstants.FSV_FILENAME)); } - } diff --git a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/ParametersXmlTest.java b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/ParametersXmlTest.java index 2eccf1ea8..e3ef16741 100644 --- a/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/ParametersXmlTest.java +++ b/dynawo-simulation/src/test/java/com/powsybl/dynawo/xml/ParametersXmlTest.java @@ -24,7 +24,7 @@ class ParametersXmlTest extends DynawoTestUtil { void writeOmegaRef() throws SAXException, IOException { DynamicSimulationParameters parameters = DynamicSimulationParameters.load(); DynawoSimulationParameters dynawoParameters = DynawoSimulationParameters.load(PlatformConfig.defaultConfig(), fileSystem); - DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, curves, parameters, dynawoParameters); + DynawoSimulationContext context = new DynawoSimulationContext(network, network.getVariantManager().getWorkingVariantId(), dynamicModels, eventModels, outputVariables, parameters, dynawoParameters); DydXml.write(tmpDir, context); ParametersXml.write(tmpDir, context); diff --git a/dynawo-simulation/src/test/resources/fsv.csv b/dynawo-simulation/src/test/resources/fsv.csv new file mode 100644 index 000000000..f721f1ccd --- /dev/null +++ b/dynawo-simulation/src/test/resources/fsv.csv @@ -0,0 +1,4 @@ +model;variable;value; +NETWORK;_BUS____1_TN_Upu_value;1.060012; +GEN____1_SM;generator_omegaPu;1.000000; +_LOAD___2_EC;load_PPu;0.216995; \ No newline at end of file diff --git a/dynawo-simulation/src/test/resources/fsvInput.xml b/dynawo-simulation/src/test/resources/fsvInput.xml new file mode 100644 index 000000000..0687bd985 --- /dev/null +++ b/dynawo-simulation/src/test/resources/fsvInput.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dynawo-simulation/src/test/resources/fsvInput.xsd b/dynawo-simulation/src/test/resources/fsvInput.xsd new file mode 100644 index 000000000..f63902eac --- /dev/null +++ b/dynawo-simulation/src/test/resources/fsvInput.xsd @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dynawo-simulation/src/test/resources/fsvWrongEntry.csv b/dynawo-simulation/src/test/resources/fsvWrongEntry.csv new file mode 100644 index 000000000..9d0fb28de --- /dev/null +++ b/dynawo-simulation/src/test/resources/fsvWrongEntry.csv @@ -0,0 +1,3 @@ +model;variable;value; +NETWORK;_BUS____1_TN_Upu_value;XX; +;_BUS____1_TN_Upu_value;10.5; \ No newline at end of file diff --git a/dynawo-simulation/src/test/resources/jobs.xml b/dynawo-simulation/src/test/resources/jobs.xml index fff3b5d5c..7cf59d4f5 100644 --- a/dynawo-simulation/src/test/resources/jobs.xml +++ b/dynawo-simulation/src/test/resources/jobs.xml @@ -14,6 +14,7 @@ + diff --git a/dynawo-simulation/src/test/resources/jobs.xsd b/dynawo-simulation/src/test/resources/jobs.xsd index a8b2dcded..9e4bb580d 100644 --- a/dynawo-simulation/src/test/resources/jobs.xsd +++ b/dynawo-simulation/src/test/resources/jobs.xsd @@ -7,6 +7,7 @@ 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 + This file is part of Dynawo, an hybrid C++/Modelica open source time domain simulation tool for power systems. --> @@ -34,6 +35,7 @@ + @@ -169,6 +171,7 @@ + @@ -180,6 +183,14 @@ + + + + + + + + @@ -204,4 +215,9 @@ + + + + + diff --git a/dynawo-simulation/src/test/resources/jobsWithDump.xml b/dynawo-simulation/src/test/resources/jobsWithDump.xml index 969a0554e..381ec04ff 100644 --- a/dynawo-simulation/src/test/resources/jobsWithDump.xml +++ b/dynawo-simulation/src/test/resources/jobsWithDump.xml @@ -15,6 +15,7 @@ + diff --git a/dynawo-simulation/src/test/resources/jobsWithSpecificLogs.xml b/dynawo-simulation/src/test/resources/jobsWithSpecificLogs.xml index 62f9584f8..b022f3e8c 100644 --- a/dynawo-simulation/src/test/resources/jobsWithSpecificLogs.xml +++ b/dynawo-simulation/src/test/resources/jobsWithSpecificLogs.xml @@ -14,6 +14,7 @@ + diff --git a/dynawo-simulation/src/test/resources/suppliers/curves.json b/dynawo-simulation/src/test/resources/suppliers/outputVariables.json similarity index 70% rename from dynawo-simulation/src/test/resources/suppliers/curves.json rename to dynawo-simulation/src/test/resources/suppliers/outputVariables.json index 3b89f124c..9daabb7bc 100644 --- a/dynawo-simulation/src/test/resources/suppliers/curves.json +++ b/dynawo-simulation/src/test/resources/suppliers/outputVariables.json @@ -16,5 +16,15 @@ "staticId": "LOAD", "variables": ["load_PPu", "load_QPu"] } + ], + "fsv":[ + { + "dynamicModelId": "BBM_GEN", + "variable": "generator_PGen" + }, + { + "staticId": "LOAD", + "variable": "load_QPu" + } ] } \ No newline at end of file