From 5fecbd00fd95a960e32a145ec8e724fe7e0db97c Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Mon, 9 Oct 2023 17:23:29 +0200 Subject: [PATCH 1/2] Reporter filled with timeline information in loadflow Signed-off-by: Florian Dupuy --- .../powsybl/dynaflow/DynaFlowConstants.java | 8 +++---- .../powsybl/dynaflow/DynaFlowProvider.java | 23 ++++++++++++++++--- .../dynaflow/DynaFlowSecurityAnalysis.java | 7 +++--- .../java/com/powsybl/dynaflow/Reports.java | 6 +++++ 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowConstants.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowConstants.java index 616bd42a3..2be350ffb 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowConstants.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowConstants.java @@ -15,14 +15,14 @@ public final class DynaFlowConstants { public static final String DYNAFLOW_NAME = "DynaFlow"; - public static final String CONFIG_FILENAME = "config.json"; - public static final String IIDM_FILENAME = "network.xiidm"; - public static final String OUTPUT_IIDM_FILENAME = "outputIIDM.xml"; - public static final String OUTPUT_RESULTS_FILENAME = "results.json"; + static final String DYNAFLOW_OUTPUTS_FOLDER = "outputs"; + static final String DYNAWO_TIMELINE_FOLDER = "timeLine"; + static final String DYNAFLOW_TIMELINE_FILE = "timeline.xml"; + public enum OutputTypes { STEADYSTATE, diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java index 0ef4b9d1b..8bbcf9bee 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java @@ -13,6 +13,7 @@ import com.powsybl.commons.extensions.Extension; import com.powsybl.commons.extensions.ExtensionJsonSerializer; import com.powsybl.commons.parameters.Parameter; +import com.powsybl.commons.reporter.Reporter; import com.powsybl.computation.*; import com.powsybl.dynaflow.json.DynaFlowConfigSerializer; import com.powsybl.dynaflow.json.JsonDynaFlowParametersSerializer; @@ -20,6 +21,8 @@ import com.powsybl.dynawo.commons.NetworkResultsUpdater; import com.powsybl.dynawo.commons.PowsyblDynawoVersion; import com.powsybl.dynawo.commons.loadmerge.LoadsMerger; +import com.powsybl.dynawo.commons.timeline.TimelineEntry; +import com.powsybl.dynawo.commons.timeline.XmlTimeLineParser; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.xml.NetworkXml; import com.powsybl.loadflow.LoadFlowParameters; @@ -103,7 +106,8 @@ public String getVersion() { } @Override - public CompletableFuture run(Network network, ComputationManager computationManager, String workingStateId, LoadFlowParameters loadFlowParameters) { + public CompletableFuture run(Network network, ComputationManager computationManager, String workingStateId, + LoadFlowParameters loadFlowParameters, Reporter reporter) { Objects.requireNonNull(network); Objects.requireNonNull(computationManager); Objects.requireNonNull(workingStateId); @@ -113,7 +117,7 @@ public CompletableFuture run(Network network, ComputationManager ExecutionEnvironment env = new ExecutionEnvironment(config.createEnv(), WORKING_DIR_PREFIX, config.isDebug()); Command versionCmd = getVersionCommand(config); DynawoUtil.requireDynawoMinVersion(env, computationManager, versionCmd, true); - return computationManager.execute(env, new DynaFlowHandler(network, workingStateId, dynaFlowParameters, loadFlowParameters, config)); + return computationManager.execute(env, new DynaFlowHandler(network, workingStateId, dynaFlowParameters, loadFlowParameters, config, reporter)); } @Override @@ -149,14 +153,16 @@ private static class DynaFlowHandler extends AbstractExecutionHandler tl = new XmlTimeLineParser().parse(timelineFile); + tl.forEach(e -> Reports.reportTimelineEvent(dfReporter, e)); + } } } diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysis.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysis.java index ceb62d46e..b16863e9c 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysis.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysis.java @@ -50,7 +50,6 @@ public class DynaFlowSecurityAnalysis { private static final String DYNAFLOW_LAUNCHER_PROGRAM_NAME = "dynaflow-launcher.sh"; private static final String CONTINGENCIES_FILENAME = "contingencies.json"; private static final String DYNAWO_CONSTRAINTS_FOLDER = "constraints"; - private static final String DYNAWO_TIMELINE_FOLDER = "timeLine"; private final Supplier configSupplier; @@ -172,7 +171,7 @@ public SecurityAnalysisReport after(Path workingDir, ExecutionReport report) thr .toList(); // Report the timeline events from the timeline files written by dynawo - Path timelineDir = workingDir.resolve(DYNAWO_TIMELINE_FOLDER); + Path timelineDir = workingDir.resolve(DynaFlowConstants.DYNAWO_TIMELINE_FOLDER); contingencies.forEach(c -> { Reporter contingencyReporter = Reports.createDynaFlowTimelineReporter(reporter, c.getId()); getTimeline(timelineDir, c).forEach(e -> Reports.reportTimelineEvent(contingencyReporter, e)); @@ -204,8 +203,8 @@ private static PostContingencyResult getPostContingencyResult(Network network, L } } - private List getTimeline(Path constraintsDir, Contingency c) { - Path timelineFile = constraintsDir.resolve("timeline_" + c.getId() + ".xml"); + private List getTimeline(Path timelineDir, Contingency c) { + Path timelineFile = timelineDir.resolve("timeline_" + c.getId() + ".xml"); return new XmlTimeLineParser().parse(timelineFile); } } diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/Reports.java b/dynaflow/src/main/java/com/powsybl/dynaflow/Reports.java index 6fd9fdb18..0371d6edd 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/Reports.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/Reports.java @@ -22,6 +22,12 @@ public final class Reports { private Reports() { } + public static Reporter createDynaFlowReporter(Reporter reporter, String networkId) { + return reporter.createSubReporter("dynaflow", + "Dynaflow loadflow on network '${networkId}'", + "networkId", networkId); + } + public static Reporter createDynaFlowSecurityAnalysisReporter(Reporter reporter, String networkId) { return reporter.createSubReporter("dynaflowSa", "Dynaflow security analysis on network '${networkId}'", From 80bc43b6b0ca65fb6dce5260a6856b89529cff96 Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Mon, 9 Oct 2023 18:15:56 +0200 Subject: [PATCH 2/2] Add integration test Signed-off-by: Florian Dupuy --- .../com/powsybl/dynawo/it/DynaFlowTest.java | 20 +++++++++++++++++-- .../resources/loadflow_timeline_report.txt | 5 +++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 dynawo-integration-tests/src/test/resources/loadflow_timeline_report.txt diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java index 00b3a8ffe..30e376334 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java @@ -73,15 +73,31 @@ void setUp() throws Exception { } @Test - void testLf() { + void testLf() throws IOException { Network network = IeeeCdfNetworkFactory.create14Solved(); - LoadFlowResult result = loadFlowProvider.run(network, computationManager, VariantManagerConstants.INITIAL_VARIANT_ID, loadFlowParameters) + network.getLine("L6-13-1").newCurrentLimits1() + .beginTemporaryLimit().setName("1").setAcceptableDuration(60).setValue(100).endTemporaryLimit() + .beginTemporaryLimit().setName("2").setAcceptableDuration(120).setValue(110).endTemporaryLimit() + .setPermanentLimit(200) + .add(); + + ReporterModel reporter = new ReporterModel("root", "testLf root reporter"); + LoadFlowResult result = loadFlowProvider.run(network, computationManager, VariantManagerConstants.INITIAL_VARIANT_ID, loadFlowParameters, reporter) .join(); + assertTrue(result.isOk()); assertEquals(1, result.getComponentResults().size()); LoadFlowResult.ComponentResult componentResult = result.getComponentResults().get(0); assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, componentResult.getStatus()); assertEquals("B4", componentResult.getSlackBusId()); + + StringWriter sw = new StringWriter(); + reporter.export(sw); + System.out.println(sw); + InputStream refStream = Objects.requireNonNull(getClass().getResourceAsStream("/loadflow_timeline_report.txt")); + String refLogExport = TestUtil.normalizeLineSeparator(new String(ByteStreams.toByteArray(refStream), StandardCharsets.UTF_8)); + String logExport = TestUtil.normalizeLineSeparator(sw.toString()); + assertEquals(refLogExport, logExport); } @Test diff --git a/dynawo-integration-tests/src/test/resources/loadflow_timeline_report.txt b/dynawo-integration-tests/src/test/resources/loadflow_timeline_report.txt new file mode 100644 index 000000000..6e91453e0 --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/loadflow_timeline_report.txt @@ -0,0 +1,5 @@ ++ testLf root reporter + + Dynaflow loadflow on network 'ieee14cdf-solved' + [t=90.0] Overload 60 : opening line on equipment 'L6-13-1' + [t=90.0] LINE : opening both sides on equipment 'L6-13-1' + [t=90.0] Overload 60 : opening line on equipment 'L6-13-1'