From 4c2ed0816b6549f0397595105529249530d3441f Mon Sep 17 00:00:00 2001 From: vmouradian Date: Tue, 3 Dec 2024 13:27:39 +0100 Subject: [PATCH 01/18] introduce contingency parameters extension Signed-off-by: vmouradian --- .../sa/ContingencyParameters.java | 47 +++++++++++++++++++ .../sa/OpenSecurityAnalysisTest.java | 13 +++++ 2 files changed, 60 insertions(+) create mode 100644 src/main/java/com/powsybl/openloadflow/sa/ContingencyParameters.java diff --git a/src/main/java/com/powsybl/openloadflow/sa/ContingencyParameters.java b/src/main/java/com/powsybl/openloadflow/sa/ContingencyParameters.java new file mode 100644 index 0000000000..df5e685d2b --- /dev/null +++ b/src/main/java/com/powsybl/openloadflow/sa/ContingencyParameters.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/) + * 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.openloadflow.sa; + +import com.powsybl.commons.extensions.AbstractExtension; +import com.powsybl.contingency.Contingency; +import com.powsybl.loadflow.LoadFlowParameters; + +/** + * @author Valentin Mouradian {@literal } + */ +public class ContingencyParameters extends AbstractExtension { + + private boolean distributedSlack; + + private boolean areaInterchangeControl; + + private LoadFlowParameters.BalanceType balanceType; + + public ContingencyParameters(boolean distributedSlack, boolean areaInterchangeControl, LoadFlowParameters.BalanceType balanceType) { + this.distributedSlack = distributedSlack; + this.areaInterchangeControl = areaInterchangeControl; + this.balanceType = balanceType; + } + + @Override + public String getName() { + return "ContingencyParameters"; + } + + public boolean isDistributedSlack() { + return distributedSlack; + } + + public boolean isAreaInterchangeControl() { + return areaInterchangeControl; + } + + public LoadFlowParameters.BalanceType getBalanceType() { + return balanceType; + } +} diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java index 07a08ee6b8..112cd6b5cb 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java @@ -4034,4 +4034,17 @@ void testNoCc0Sc0() { assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, saResultAll.getPreContingencyResult().getStatus()); assertEquals(6, saResultAll.getPreContingencyResult().getNetworkResult().getBusResults().size()); // 6 buses in total } + + @Test + void testContingencyParametersExtension() { + Contingency contingency = new Contingency("L2", new BranchContingency("L2")); + contingency.addExtension(ContingencyParameters.class, new ContingencyParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); + + ContingencyParameters contingencyParameters = contingency.getExtension(ContingencyParameters.class); + + assertEquals(contingencyParameters, contingency.getExtensionByName("ContingencyParameters")); + assertFalse(contingencyParameters.isDistributedSlack()); + assertTrue(contingencyParameters.isAreaInterchangeControl()); + assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, contingencyParameters.getBalanceType()); + } } From 07efd53419ce8a76e7e005b0a7f5babe40235cb1 Mon Sep 17 00:00:00 2001 From: vmouradian Date: Tue, 3 Dec 2024 14:36:32 +0100 Subject: [PATCH 02/18] some doc Signed-off-by: vmouradian --- docs/security/parameters.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/security/parameters.md b/docs/security/parameters.md index cd2476aac8..0657418548 100644 --- a/docs/security/parameters.md +++ b/docs/security/parameters.md @@ -75,3 +75,14 @@ open-security-analysis-default-parameters: ``` At the moment, overriding the parameters by a JSON file is not supported by Open Load Flow. + +## Contingency Parameters + +Some load flow related parameters can be configured per contingency. This can be done by adding to the `Contingency` object an extension of the `ContingencyParameters` class. +Those parameters correspond to parameters present in [`LoadFlowParameters`](inv:powsyblcore:*:*#simulation/loadflow/configuration) and [`OpenLoadFlowParameters`](../loadflow/parameters.md#specific-parameters) : + +- `distributedSlack` (see [distributedSlack](inv:powsyblcore:*:*#simulation/loadflow/configuration)) +- `areaInterchangeControl` (see [areaInterchangeControl](../loadflow/parameters.md#specific-parameters)) +- `balanceType` (see [balanceType](inv:powsyblcore:*:*#simulation/loadflow/configuration)) + +If the extension is added to a contingency, the values of these parameters will override their equivalent of the SA input parameters for post contingency and post remedial actions states calculations. From 74215d2661e5a443d03a1a8c73a468945c7c4d4b Mon Sep 17 00:00:00 2001 From: vmouradian Date: Thu, 5 Dec 2024 18:30:13 +0100 Subject: [PATCH 03/18] add serde (no tests yet) Signed-off-by: vmouradian --- .../ContingencyParametersJsonSerializer.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java diff --git a/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java b/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java new file mode 100644 index 0000000000..350cbe6b11 --- /dev/null +++ b/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java @@ -0,0 +1,58 @@ +package com.powsybl.openloadflow.sa; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.powsybl.commons.extensions.ExtensionJsonSerializer; +import com.powsybl.commons.json.JsonUtil; +import com.powsybl.contingency.Contingency; + +import java.io.IOException; + +public class ContingencyParametersJsonSerializer implements ExtensionJsonSerializer { + + @Override + public String getExtensionName() { + return "contigency-parameters"; + } + + @Override + public String getCategoryName() { + return "contingency"; + } + + @Override + public Class getExtensionClass() { + return ContingencyParameters.class; + } + + /** + * Specifies serialization for our extension: ignore name et extendable + */ + private interface SerializationSpec { + + @JsonIgnore + String getName(); + + @JsonIgnore + Contingency getExtendable(); + } + + private static ObjectMapper createMapper() { + return JsonUtil.createObjectMapper() + .addMixIn(ContingencyParameters.class, SerializationSpec.class); + } + + @Override + public void serialize(ContingencyParameters extension, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + createMapper().writeValue(jsonGenerator, extension); + } + + @Override + public ContingencyParameters deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { + return createMapper().readValue(jsonParser, ContingencyParameters.class); + } +} From f622794d0e1b8f47c4a4110787ee8c22ae4cd97a Mon Sep 17 00:00:00 2001 From: vmouradian Date: Fri, 6 Dec 2024 13:47:35 +0100 Subject: [PATCH 04/18] fix serde Signed-off-by: vmouradian --- .../java/com/powsybl/openloadflow/sa/ContingencyParameters.java | 2 +- .../openloadflow/sa/ContingencyParametersJsonSerializer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/sa/ContingencyParameters.java b/src/main/java/com/powsybl/openloadflow/sa/ContingencyParameters.java index df5e685d2b..740ea6c200 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/ContingencyParameters.java +++ b/src/main/java/com/powsybl/openloadflow/sa/ContingencyParameters.java @@ -30,7 +30,7 @@ public ContingencyParameters(boolean distributedSlack, boolean areaInterchangeCo @Override public String getName() { - return "ContingencyParameters"; + return "contingency-parameters"; } public boolean isDistributedSlack() { diff --git a/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java b/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java index 350cbe6b11..6ba0d7f9da 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java +++ b/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java @@ -16,7 +16,7 @@ public class ContingencyParametersJsonSerializer implements ExtensionJsonSeriali @Override public String getExtensionName() { - return "contigency-parameters"; + return "contingency-parameters"; } @Override From 75bc31be601bcd4a2cd7d788c5ae9352e5f45468 Mon Sep 17 00:00:00 2001 From: vmouradian Date: Fri, 6 Dec 2024 13:47:43 +0100 Subject: [PATCH 05/18] add serde tests Signed-off-by: vmouradian --- .../sa/OpenSecurityAnalysisProviderTest.java | 24 +++++++ .../sa/OpenSecurityAnalysisTest.java | 13 ---- .../openloadflow/util/JsonSerializer.java | 65 +++++++++++++++++++ src/test/resources/contingencies.json | 14 ++++ 4 files changed, 103 insertions(+), 13 deletions(-) create mode 100644 src/test/java/com/powsybl/openloadflow/util/JsonSerializer.java create mode 100644 src/test/resources/contingencies.json diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisProviderTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisProviderTest.java index f8d4c879d3..08e030763c 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisProviderTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisProviderTest.java @@ -10,6 +10,10 @@ import com.powsybl.commons.config.InMemoryPlatformConfig; import com.powsybl.commons.config.MapModuleConfig; import com.powsybl.commons.test.AbstractSerDeTest; +import com.powsybl.contingency.BranchContingency; +import com.powsybl.contingency.Contingency; +import com.powsybl.loadflow.LoadFlowParameters; +import com.powsybl.openloadflow.util.JsonSerializer; import com.powsybl.openloadflow.util.PowsyblOpenLoadFlowVersion; import com.powsybl.openloadflow.util.ProviderConstants; import com.powsybl.security.SecurityAnalysisParameters; @@ -105,4 +109,24 @@ void jsonTest() throws IOException { parameters.addExtension(OpenSecurityAnalysisParameters.class, parametersExt); roundTripTest(parameters, JsonSecurityAnalysisParameters::write, JsonSecurityAnalysisParameters::read, "/sa-params.json"); } + + @Test + void testContingencyParametersExtension() { + Contingency contingency = new Contingency("L2", new BranchContingency("L2")); + contingency.addExtension(ContingencyParameters.class, new ContingencyParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); + + ContingencyParameters contingencyParameters = contingency.getExtension(ContingencyParameters.class); + + assertEquals(contingencyParameters, contingency.getExtensionByName("contingency-parameters")); + assertFalse(contingencyParameters.isDistributedSlack()); + assertTrue(contingencyParameters.isAreaInterchangeControl()); + assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, contingencyParameters.getBalanceType()); + } + + @Test + void testContingencyParametersExtensionJson() throws IOException { + Contingency contingency = new Contingency("L2", new BranchContingency("L2")); + contingency.addExtension(ContingencyParameters.class, new ContingencyParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); + roundTripTest(contingency, JsonSerializer::write, JsonSerializer::readContingency, "/contingencies.json"); + } } diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java index 112cd6b5cb..07a08ee6b8 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java @@ -4034,17 +4034,4 @@ void testNoCc0Sc0() { assertEquals(LoadFlowResult.ComponentResult.Status.CONVERGED, saResultAll.getPreContingencyResult().getStatus()); assertEquals(6, saResultAll.getPreContingencyResult().getNetworkResult().getBusResults().size()); // 6 buses in total } - - @Test - void testContingencyParametersExtension() { - Contingency contingency = new Contingency("L2", new BranchContingency("L2")); - contingency.addExtension(ContingencyParameters.class, new ContingencyParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); - - ContingencyParameters contingencyParameters = contingency.getExtension(ContingencyParameters.class); - - assertEquals(contingencyParameters, contingency.getExtensionByName("ContingencyParameters")); - assertFalse(contingencyParameters.isDistributedSlack()); - assertTrue(contingencyParameters.isAreaInterchangeControl()); - assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, contingencyParameters.getBalanceType()); - } } diff --git a/src/test/java/com/powsybl/openloadflow/util/JsonSerializer.java b/src/test/java/com/powsybl/openloadflow/util/JsonSerializer.java new file mode 100644 index 0000000000..6e506f6c90 --- /dev/null +++ b/src/test/java/com/powsybl/openloadflow/util/JsonSerializer.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/) + * 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.openloadflow.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.powsybl.commons.json.JsonUtil; +import com.powsybl.contingency.Contingency; +import com.powsybl.contingency.json.ContingencyJsonModule; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; + +/** + * @author Valentin Mouradian {@literal } + */ +public final class JsonSerializer { + + private JsonSerializer() { + } + + private static T read(Path jsonFile, Class clazz) { + Objects.requireNonNull(jsonFile); + + try (InputStream is = Files.newInputStream(jsonFile)) { + ObjectMapper objectMapper = JsonUtil.createObjectMapper(); + ContingencyJsonModule module = new ContingencyJsonModule(); + objectMapper.registerModule(module); + + return (T) objectMapper.readValue(is, clazz); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public static Contingency readContingency(Path jsonFile) { + return read(jsonFile, Contingency.class); + } + + public static void write(T object, Path jsonFile) { + Objects.requireNonNull(object); + Objects.requireNonNull(jsonFile); + + try (OutputStream os = Files.newOutputStream(jsonFile)) { + ObjectMapper mapper = JsonUtil.createObjectMapper(); + ContingencyJsonModule module = new ContingencyJsonModule(); + mapper.registerModule(module); + + ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); + writer.writeValue(os, object); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } +} diff --git a/src/test/resources/contingencies.json b/src/test/resources/contingencies.json new file mode 100644 index 0000000000..771a4c21e6 --- /dev/null +++ b/src/test/resources/contingencies.json @@ -0,0 +1,14 @@ +{ + "id" : "L2", + "elements" : [ { + "id" : "L2", + "type" : "BRANCH" + } ], + "extensions" : { + "contingency-parameters" : { + "distributedSlack" : false, + "areaInterchangeControl" : true, + "balanceType" : "PROPORTIONAL_TO_LOAD" + } + } +} \ No newline at end of file From 0f441d7234e89fbb6f39aa34938c561e55e799ea Mon Sep 17 00:00:00 2001 From: vmouradian Date: Fri, 6 Dec 2024 14:18:06 +0100 Subject: [PATCH 06/18] add auto service Signed-off-by: vmouradian --- .../openloadflow/sa/ContingencyParametersJsonSerializer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java b/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java index 6ba0d7f9da..b2e25ccf85 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java +++ b/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java @@ -6,12 +6,14 @@ import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; +import com.google.auto.service.AutoService; import com.powsybl.commons.extensions.ExtensionJsonSerializer; import com.powsybl.commons.json.JsonUtil; import com.powsybl.contingency.Contingency; import java.io.IOException; +@AutoService(ExtensionJsonSerializer.class) public class ContingencyParametersJsonSerializer implements ExtensionJsonSerializer { @Override From 5ea6cb77935590163aa58bfd07e83c7a989e9a86 Mon Sep 17 00:00:00 2001 From: vmouradian Date: Fri, 6 Dec 2024 14:40:30 +0100 Subject: [PATCH 07/18] fix coverage Signed-off-by: vmouradian --- .../openloadflow/sa/OpenSecurityAnalysisProviderTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisProviderTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisProviderTest.java index 08e030763c..41bd249eaa 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisProviderTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisProviderTest.java @@ -127,6 +127,7 @@ void testContingencyParametersExtension() { void testContingencyParametersExtensionJson() throws IOException { Contingency contingency = new Contingency("L2", new BranchContingency("L2")); contingency.addExtension(ContingencyParameters.class, new ContingencyParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); + assertEquals(ContingencyParameters.class, new ContingencyParametersJsonSerializer().getExtensionClass()); roundTripTest(contingency, JsonSerializer::write, JsonSerializer::readContingency, "/contingencies.json"); } } From 7b3307d6c3479e31daa7d80c611afc73091080d7 Mon Sep 17 00:00:00 2001 From: vmouradian Date: Tue, 17 Dec 2024 12:12:24 +0100 Subject: [PATCH 08/18] refactor Signed-off-by: vmouradian --- .../ContingencyLoadFlowParameters.java} | 6 +- ...encyLoadFlowParametersJsonSerializer.java} | 16 ++-- .../sa/OpenSecurityAnalysisProviderTest.java | 25 ------ .../OpenSecurityAnalysisExtensionsTest.java | 88 +++++++++++++++++++ .../openloadflow/util/JsonSerializer.java | 65 -------------- 5 files changed, 99 insertions(+), 101 deletions(-) rename src/main/java/com/powsybl/openloadflow/sa/{ContingencyParameters.java => extensions/ContingencyLoadFlowParameters.java} (81%) rename src/main/java/com/powsybl/openloadflow/sa/{ContingencyParametersJsonSerializer.java => extensions/ContingencyLoadFlowParametersJsonSerializer.java} (61%) create mode 100644 src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java delete mode 100644 src/test/java/com/powsybl/openloadflow/util/JsonSerializer.java diff --git a/src/main/java/com/powsybl/openloadflow/sa/ContingencyParameters.java b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java similarity index 81% rename from src/main/java/com/powsybl/openloadflow/sa/ContingencyParameters.java rename to src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java index 740ea6c200..c9a17b3a43 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/ContingencyParameters.java +++ b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * SPDX-License-Identifier: MPL-2.0 */ -package com.powsybl.openloadflow.sa; +package com.powsybl.openloadflow.sa.extensions; import com.powsybl.commons.extensions.AbstractExtension; import com.powsybl.contingency.Contingency; @@ -14,7 +14,7 @@ /** * @author Valentin Mouradian {@literal } */ -public class ContingencyParameters extends AbstractExtension { +public class ContingencyLoadFlowParameters extends AbstractExtension { private boolean distributedSlack; @@ -22,7 +22,7 @@ public class ContingencyParameters extends AbstractExtension { private LoadFlowParameters.BalanceType balanceType; - public ContingencyParameters(boolean distributedSlack, boolean areaInterchangeControl, LoadFlowParameters.BalanceType balanceType) { + public ContingencyLoadFlowParameters(boolean distributedSlack, boolean areaInterchangeControl, LoadFlowParameters.BalanceType balanceType) { this.distributedSlack = distributedSlack; this.areaInterchangeControl = areaInterchangeControl; this.balanceType = balanceType; diff --git a/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java similarity index 61% rename from src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java rename to src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java index b2e25ccf85..de15cb0306 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/ContingencyParametersJsonSerializer.java +++ b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java @@ -1,4 +1,4 @@ -package com.powsybl.openloadflow.sa; +package com.powsybl.openloadflow.sa.extensions; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonGenerator; @@ -14,7 +14,7 @@ import java.io.IOException; @AutoService(ExtensionJsonSerializer.class) -public class ContingencyParametersJsonSerializer implements ExtensionJsonSerializer { +public class ContingencyLoadFlowParametersJsonSerializer implements ExtensionJsonSerializer { @Override public String getExtensionName() { @@ -27,8 +27,8 @@ public String getCategoryName() { } @Override - public Class getExtensionClass() { - return ContingencyParameters.class; + public Class getExtensionClass() { + return ContingencyLoadFlowParameters.class; } /** @@ -45,16 +45,16 @@ private interface SerializationSpec { private static ObjectMapper createMapper() { return JsonUtil.createObjectMapper() - .addMixIn(ContingencyParameters.class, SerializationSpec.class); + .addMixIn(ContingencyLoadFlowParameters.class, SerializationSpec.class); } @Override - public void serialize(ContingencyParameters extension, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + public void serialize(ContingencyLoadFlowParameters extension, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { createMapper().writeValue(jsonGenerator, extension); } @Override - public ContingencyParameters deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { - return createMapper().readValue(jsonParser, ContingencyParameters.class); + public ContingencyLoadFlowParameters deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { + return createMapper().readValue(jsonParser, ContingencyLoadFlowParameters.class); } } diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisProviderTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisProviderTest.java index 41bd249eaa..f8d4c879d3 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisProviderTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisProviderTest.java @@ -10,10 +10,6 @@ import com.powsybl.commons.config.InMemoryPlatformConfig; import com.powsybl.commons.config.MapModuleConfig; import com.powsybl.commons.test.AbstractSerDeTest; -import com.powsybl.contingency.BranchContingency; -import com.powsybl.contingency.Contingency; -import com.powsybl.loadflow.LoadFlowParameters; -import com.powsybl.openloadflow.util.JsonSerializer; import com.powsybl.openloadflow.util.PowsyblOpenLoadFlowVersion; import com.powsybl.openloadflow.util.ProviderConstants; import com.powsybl.security.SecurityAnalysisParameters; @@ -109,25 +105,4 @@ void jsonTest() throws IOException { parameters.addExtension(OpenSecurityAnalysisParameters.class, parametersExt); roundTripTest(parameters, JsonSecurityAnalysisParameters::write, JsonSecurityAnalysisParameters::read, "/sa-params.json"); } - - @Test - void testContingencyParametersExtension() { - Contingency contingency = new Contingency("L2", new BranchContingency("L2")); - contingency.addExtension(ContingencyParameters.class, new ContingencyParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); - - ContingencyParameters contingencyParameters = contingency.getExtension(ContingencyParameters.class); - - assertEquals(contingencyParameters, contingency.getExtensionByName("contingency-parameters")); - assertFalse(contingencyParameters.isDistributedSlack()); - assertTrue(contingencyParameters.isAreaInterchangeControl()); - assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, contingencyParameters.getBalanceType()); - } - - @Test - void testContingencyParametersExtensionJson() throws IOException { - Contingency contingency = new Contingency("L2", new BranchContingency("L2")); - contingency.addExtension(ContingencyParameters.class, new ContingencyParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); - assertEquals(ContingencyParameters.class, new ContingencyParametersJsonSerializer().getExtensionClass()); - roundTripTest(contingency, JsonSerializer::write, JsonSerializer::readContingency, "/contingencies.json"); - } } diff --git a/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java b/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java new file mode 100644 index 0000000000..6ad377788b --- /dev/null +++ b/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/) + * 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.openloadflow.sa.extensions; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.powsybl.commons.json.JsonUtil; +import com.powsybl.commons.test.AbstractSerDeTest; +import com.powsybl.contingency.BranchContingency; +import com.powsybl.contingency.Contingency; +import com.powsybl.contingency.json.ContingencyJsonModule; +import com.powsybl.loadflow.LoadFlowParameters; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author Valentin Mouradian {@literal } + */ +class OpenSecurityAnalysisExtensionsTest extends AbstractSerDeTest { + + @Test + void testContingencyParametersExtension() { + Contingency contingency = new Contingency("L2", new BranchContingency("L2")); + contingency.addExtension(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); + + ContingencyLoadFlowParameters contingencyLoadFlowParameters = contingency.getExtension(ContingencyLoadFlowParameters.class); + + assertEquals(contingencyLoadFlowParameters, contingency.getExtensionByName("contingency-parameters")); + assertFalse(contingencyLoadFlowParameters.isDistributedSlack()); + assertTrue(contingencyLoadFlowParameters.isAreaInterchangeControl()); + assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, contingencyLoadFlowParameters.getBalanceType()); + } + + @Test + void testContingencyParametersExtensionJson() throws IOException { + Contingency contingency = new Contingency("L2", new BranchContingency("L2")); + contingency.addExtension(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); + assertEquals(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParametersJsonSerializer().getExtensionClass()); + roundTripTest(contingency, OpenSecurityAnalysisExtensionsTest::writeContingency, OpenSecurityAnalysisExtensionsTest::readContingency, "/contingencies.json"); + } + + public static Contingency readContingency(Path jsonFile) { + Objects.requireNonNull(jsonFile); + + try (InputStream is = Files.newInputStream(jsonFile)) { + ObjectMapper objectMapper = JsonUtil.createObjectMapper(); + ContingencyJsonModule module = new ContingencyJsonModule(); + objectMapper.registerModule(module); + + return objectMapper.readValue(is, Contingency.class); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public static void writeContingency(Contingency contingency, Path jsonFile) { + Objects.requireNonNull(contingency); + Objects.requireNonNull(jsonFile); + + try (OutputStream os = Files.newOutputStream(jsonFile)) { + ObjectMapper mapper = JsonUtil.createObjectMapper(); + ContingencyJsonModule module = new ContingencyJsonModule(); + mapper.registerModule(module); + + ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); + writer.writeValue(os, contingency); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + +} diff --git a/src/test/java/com/powsybl/openloadflow/util/JsonSerializer.java b/src/test/java/com/powsybl/openloadflow/util/JsonSerializer.java deleted file mode 100644 index 6e506f6c90..0000000000 --- a/src/test/java/com/powsybl/openloadflow/util/JsonSerializer.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/) - * 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.openloadflow.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; -import com.powsybl.commons.json.JsonUtil; -import com.powsybl.contingency.Contingency; -import com.powsybl.contingency.json.ContingencyJsonModule; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Objects; - -/** - * @author Valentin Mouradian {@literal } - */ -public final class JsonSerializer { - - private JsonSerializer() { - } - - private static T read(Path jsonFile, Class clazz) { - Objects.requireNonNull(jsonFile); - - try (InputStream is = Files.newInputStream(jsonFile)) { - ObjectMapper objectMapper = JsonUtil.createObjectMapper(); - ContingencyJsonModule module = new ContingencyJsonModule(); - objectMapper.registerModule(module); - - return (T) objectMapper.readValue(is, clazz); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - public static Contingency readContingency(Path jsonFile) { - return read(jsonFile, Contingency.class); - } - - public static void write(T object, Path jsonFile) { - Objects.requireNonNull(object); - Objects.requireNonNull(jsonFile); - - try (OutputStream os = Files.newOutputStream(jsonFile)) { - ObjectMapper mapper = JsonUtil.createObjectMapper(); - ContingencyJsonModule module = new ContingencyJsonModule(); - mapper.registerModule(module); - - ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); - writer.writeValue(os, object); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } -} From 2f8968deddeac57a6f6186a7bd8a84047426ce5d Mon Sep 17 00:00:00 2001 From: vmouradian Date: Wed, 18 Dec 2024 17:26:48 +0100 Subject: [PATCH 09/18] rename Signed-off-by: vmouradian --- docs/security/parameters.md | 2 +- .../ContingencyLoadFlowParametersJsonSerializer.java | 2 +- .../sa/extensions/OpenSecurityAnalysisExtensionsTest.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/security/parameters.md b/docs/security/parameters.md index 0657418548..d83bb133e2 100644 --- a/docs/security/parameters.md +++ b/docs/security/parameters.md @@ -78,7 +78,7 @@ At the moment, overriding the parameters by a JSON file is not supported by Open ## Contingency Parameters -Some load flow related parameters can be configured per contingency. This can be done by adding to the `Contingency` object an extension of the `ContingencyParameters` class. +Some load flow related parameters can be configured per contingency. This can be done by adding to the `Contingency` object an extension of the `ContingencyLoadFlowParameters` class. Those parameters correspond to parameters present in [`LoadFlowParameters`](inv:powsyblcore:*:*#simulation/loadflow/configuration) and [`OpenLoadFlowParameters`](../loadflow/parameters.md#specific-parameters) : - `distributedSlack` (see [distributedSlack](inv:powsyblcore:*:*#simulation/loadflow/configuration)) diff --git a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java index de15cb0306..80d8cc16af 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java +++ b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java @@ -32,7 +32,7 @@ public Class getExtensionClass() { } /** - * Specifies serialization for our extension: ignore name et extendable + * Specifies serialization for our extension: ignore name and extendable */ private interface SerializationSpec { diff --git a/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java b/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java index 6ad377788b..02257a0cbd 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java @@ -35,7 +35,7 @@ class OpenSecurityAnalysisExtensionsTest extends AbstractSerDeTest { @Test - void testContingencyParametersExtension() { + void testContingencyLoadFlowParametersExtension() { Contingency contingency = new Contingency("L2", new BranchContingency("L2")); contingency.addExtension(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); @@ -48,7 +48,7 @@ void testContingencyParametersExtension() { } @Test - void testContingencyParametersExtensionJson() throws IOException { + void testContingencyLoadFlowParametersExtensionJson() throws IOException { Contingency contingency = new Contingency("L2", new BranchContingency("L2")); contingency.addExtension(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); assertEquals(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParametersJsonSerializer().getExtensionClass()); From cc7563bc76649cbbfb7752e4758c49eb7c64256b Mon Sep 17 00:00:00 2001 From: vmouradian Date: Mon, 23 Dec 2024 15:55:51 +0100 Subject: [PATCH 10/18] change name parameter + add copyrigth/author Signed-off-by: vmouradian --- .../sa/extensions/ContingencyLoadFlowParameters.java | 2 +- .../ContingencyLoadFlowParametersJsonSerializer.java | 12 +++++++++++- .../OpenSecurityAnalysisExtensionsTest.java | 2 +- src/test/resources/contingencies.json | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java index c9a17b3a43..4e16d472c2 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java +++ b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java @@ -30,7 +30,7 @@ public ContingencyLoadFlowParameters(boolean distributedSlack, boolean areaInter @Override public String getName() { - return "contingency-parameters"; + return "contingency-load-flow-parameters"; } public boolean isDistributedSlack() { diff --git a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java index 80d8cc16af..85f4b3e3d3 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java +++ b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java @@ -1,3 +1,10 @@ +/** + * Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/) + * 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.openloadflow.sa.extensions; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -13,12 +20,15 @@ import java.io.IOException; +/** + * @author Valentin Mouradian {@literal } + */ @AutoService(ExtensionJsonSerializer.class) public class ContingencyLoadFlowParametersJsonSerializer implements ExtensionJsonSerializer { @Override public String getExtensionName() { - return "contingency-parameters"; + return "contingency-load-flow-parameters"; } @Override diff --git a/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java b/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java index 02257a0cbd..48239dad50 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java @@ -41,7 +41,7 @@ void testContingencyLoadFlowParametersExtension() { ContingencyLoadFlowParameters contingencyLoadFlowParameters = contingency.getExtension(ContingencyLoadFlowParameters.class); - assertEquals(contingencyLoadFlowParameters, contingency.getExtensionByName("contingency-parameters")); + assertEquals(contingencyLoadFlowParameters, contingency.getExtensionByName("contingency-load-flow-parameters")); assertFalse(contingencyLoadFlowParameters.isDistributedSlack()); assertTrue(contingencyLoadFlowParameters.isAreaInterchangeControl()); assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, contingencyLoadFlowParameters.getBalanceType()); diff --git a/src/test/resources/contingencies.json b/src/test/resources/contingencies.json index 771a4c21e6..4b1a9ea4d8 100644 --- a/src/test/resources/contingencies.json +++ b/src/test/resources/contingencies.json @@ -5,7 +5,7 @@ "type" : "BRANCH" } ], "extensions" : { - "contingency-parameters" : { + "contingency-load-flow-parameters" : { "distributedSlack" : false, "areaInterchangeControl" : true, "balanceType" : "PROPORTIONAL_TO_LOAD" From 8e3b390336db5c75fac87651a47dc6fd85cd49b2 Mon Sep 17 00:00:00 2001 From: vmouradian Date: Fri, 3 Jan 2025 15:23:25 +0100 Subject: [PATCH 11/18] refactor to have optional values Signed-off-by: vmouradian --- .../ContingencyLoadFlowParameters.java | 40 ++++++++---- ...gencyLoadFlowParametersJsonSerializer.java | 62 ++++++++++++------- .../OpenSecurityAnalysisExtensionsTest.java | 23 ++++--- 3 files changed, 82 insertions(+), 43 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java index 4e16d472c2..01206a24a1 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java +++ b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java @@ -11,21 +11,20 @@ import com.powsybl.contingency.Contingency; import com.powsybl.loadflow.LoadFlowParameters; +import java.util.Optional; + /** * @author Valentin Mouradian {@literal } */ public class ContingencyLoadFlowParameters extends AbstractExtension { - private boolean distributedSlack; + private Boolean distributedSlack = null; - private boolean areaInterchangeControl; + private Boolean areaInterchangeControl = null; - private LoadFlowParameters.BalanceType balanceType; + private LoadFlowParameters.BalanceType balanceType = null; - public ContingencyLoadFlowParameters(boolean distributedSlack, boolean areaInterchangeControl, LoadFlowParameters.BalanceType balanceType) { - this.distributedSlack = distributedSlack; - this.areaInterchangeControl = areaInterchangeControl; - this.balanceType = balanceType; + public ContingencyLoadFlowParameters() { } @Override @@ -33,15 +32,30 @@ public String getName() { return "contingency-load-flow-parameters"; } - public boolean isDistributedSlack() { - return distributedSlack; + public Optional isDistributedSlack() { + return Optional.ofNullable(distributedSlack); } - public boolean isAreaInterchangeControl() { - return areaInterchangeControl; + public Optional isAreaInterchangeControl() { + return Optional.ofNullable(areaInterchangeControl); } - public LoadFlowParameters.BalanceType getBalanceType() { - return balanceType; + public Optional getBalanceType() { + return Optional.ofNullable(balanceType); + } + + public ContingencyLoadFlowParameters setDistributedSlack(Boolean distributedSlack) { + this.distributedSlack = distributedSlack; + return this; + } + + public ContingencyLoadFlowParameters setAreaInterchangeControl(Boolean areaInterchangeControl) { + this.areaInterchangeControl = areaInterchangeControl; + return this; + } + + public ContingencyLoadFlowParameters setBalanceType(LoadFlowParameters.BalanceType balanceType) { + this.balanceType = balanceType; + return this; } } diff --git a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java index 85f4b3e3d3..6eb5567712 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java +++ b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParametersJsonSerializer.java @@ -7,18 +7,19 @@ */ package com.powsybl.openloadflow.sa.extensions; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import com.google.auto.service.AutoService; +import com.powsybl.commons.PowsyblException; import com.powsybl.commons.extensions.ExtensionJsonSerializer; -import com.powsybl.commons.json.JsonUtil; import com.powsybl.contingency.Contingency; +import com.powsybl.loadflow.LoadFlowParameters; import java.io.IOException; +import java.util.Optional; /** * @author Valentin Mouradian {@literal } @@ -33,7 +34,7 @@ public String getExtensionName() { @Override public String getCategoryName() { - return "contingency"; + return "security-analysis"; } @Override @@ -41,30 +42,45 @@ public Class getExtensionClass() { return ContingencyLoadFlowParameters.class; } - /** - * Specifies serialization for our extension: ignore name and extendable - */ - private interface SerializationSpec { - - @JsonIgnore - String getName(); - - @JsonIgnore - Contingency getExtendable(); - } - - private static ObjectMapper createMapper() { - return JsonUtil.createObjectMapper() - .addMixIn(ContingencyLoadFlowParameters.class, SerializationSpec.class); - } - @Override public void serialize(ContingencyLoadFlowParameters extension, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { - createMapper().writeValue(jsonGenerator, extension); + Optional distributedSlack = extension.isDistributedSlack(); + Optional areaInterchangeControl = extension.isAreaInterchangeControl(); + Optional balanceType = extension.getBalanceType(); + + jsonGenerator.writeStartObject(); + if (distributedSlack.isPresent()) { + jsonGenerator.writeBooleanField("distributedSlack", distributedSlack.get()); + } + if (areaInterchangeControl.isPresent()) { + jsonGenerator.writeBooleanField("areaInterchangeControl", areaInterchangeControl.get()); + } + if (balanceType.isPresent()) { + jsonGenerator.writeStringField("balanceType", balanceType.get().name()); + } + jsonGenerator.writeEndObject(); } @Override public ContingencyLoadFlowParameters deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { - return createMapper().readValue(jsonParser, ContingencyLoadFlowParameters.class); + ContingencyLoadFlowParameters contingencyLoadFlowParameters = new ContingencyLoadFlowParameters(); + while (jsonParser.nextToken() != JsonToken.END_OBJECT) { + if (jsonParser.currentName().equals("distributedSlack")) { + jsonParser.nextToken(); + boolean distributedSlack = jsonParser.readValueAs(Boolean.class); + contingencyLoadFlowParameters.setDistributedSlack(distributedSlack); + } else if (jsonParser.currentName().equals("areaInterchangeControl")) { + jsonParser.nextToken(); + boolean areaInterchangeControl = jsonParser.readValueAs(Boolean.class); + contingencyLoadFlowParameters.setAreaInterchangeControl(areaInterchangeControl); + } else if (jsonParser.currentName().equals("balanceType")) { + jsonParser.nextToken(); + LoadFlowParameters.BalanceType balanceType = LoadFlowParameters.BalanceType.valueOf(jsonParser.readValueAs(String.class)); + contingencyLoadFlowParameters.setBalanceType(balanceType); + } else { + throw new PowsyblException("Unexpected field: " + jsonParser.currentName()); + } + } + return contingencyLoadFlowParameters; } } diff --git a/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java b/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java index 48239dad50..a5b9abecaa 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java @@ -37,20 +37,29 @@ class OpenSecurityAnalysisExtensionsTest extends AbstractSerDeTest { @Test void testContingencyLoadFlowParametersExtension() { Contingency contingency = new Contingency("L2", new BranchContingency("L2")); - contingency.addExtension(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); + ContingencyLoadFlowParameters contingencyLoadFlowParameters = new ContingencyLoadFlowParameters() + .setAreaInterchangeControl(true) + .setBalanceType(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD); + contingency.addExtension(ContingencyLoadFlowParameters.class, contingencyLoadFlowParameters); - ContingencyLoadFlowParameters contingencyLoadFlowParameters = contingency.getExtension(ContingencyLoadFlowParameters.class); + ContingencyLoadFlowParameters extension = contingency.getExtension(ContingencyLoadFlowParameters.class); + assertEquals(extension, contingency.getExtensionByName("contingency-load-flow-parameters")); - assertEquals(contingencyLoadFlowParameters, contingency.getExtensionByName("contingency-load-flow-parameters")); - assertFalse(contingencyLoadFlowParameters.isDistributedSlack()); - assertTrue(contingencyLoadFlowParameters.isAreaInterchangeControl()); - assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, contingencyLoadFlowParameters.getBalanceType()); + assertFalse(extension.isDistributedSlack().isPresent()); + assertTrue(extension.isAreaInterchangeControl().isPresent()); + assertTrue(extension.getBalanceType().isPresent()); + + assertTrue(extension.isAreaInterchangeControl().get()); + assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, extension.getBalanceType().get()); } @Test void testContingencyLoadFlowParametersExtensionJson() throws IOException { Contingency contingency = new Contingency("L2", new BranchContingency("L2")); - contingency.addExtension(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD)); + ContingencyLoadFlowParameters contingencyLoadFlowParameters = new ContingencyLoadFlowParameters().setDistributedSlack(false) + .setAreaInterchangeControl(true) + .setBalanceType(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD); + contingency.addExtension(ContingencyLoadFlowParameters.class, contingencyLoadFlowParameters); assertEquals(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParametersJsonSerializer().getExtensionClass()); roundTripTest(contingency, OpenSecurityAnalysisExtensionsTest::writeContingency, OpenSecurityAnalysisExtensionsTest::readContingency, "/contingencies.json"); } From 67e8423bd2c9daef97135a5c2d08d28c8151a244 Mon Sep 17 00:00:00 2001 From: vmouradian Date: Mon, 6 Jan 2025 14:43:19 +0100 Subject: [PATCH 12/18] clean Signed-off-by: vmouradian --- .../ContingencyLoadFlowParameters.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java index 01206a24a1..a83a9bd403 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java +++ b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java @@ -11,6 +11,7 @@ import com.powsybl.contingency.Contingency; import com.powsybl.loadflow.LoadFlowParameters; +import java.util.Objects; import java.util.Optional; /** @@ -18,14 +19,11 @@ */ public class ContingencyLoadFlowParameters extends AbstractExtension { - private Boolean distributedSlack = null; + private Boolean distributedSlack; - private Boolean areaInterchangeControl = null; + private Boolean areaInterchangeControl; - private LoadFlowParameters.BalanceType balanceType = null; - - public ContingencyLoadFlowParameters() { - } + private LoadFlowParameters.BalanceType balanceType; @Override public String getName() { @@ -44,18 +42,18 @@ public Optional getBalanceType() { return Optional.ofNullable(balanceType); } - public ContingencyLoadFlowParameters setDistributedSlack(Boolean distributedSlack) { + public ContingencyLoadFlowParameters setDistributedSlack(boolean distributedSlack) { this.distributedSlack = distributedSlack; return this; } - public ContingencyLoadFlowParameters setAreaInterchangeControl(Boolean areaInterchangeControl) { + public ContingencyLoadFlowParameters setAreaInterchangeControl(boolean areaInterchangeControl) { this.areaInterchangeControl = areaInterchangeControl; return this; } public ContingencyLoadFlowParameters setBalanceType(LoadFlowParameters.BalanceType balanceType) { - this.balanceType = balanceType; + this.balanceType = Objects.requireNonNull(balanceType); return this; } } From 92c6ffc34a223483ac3359d4265b8e60e612798a Mon Sep 17 00:00:00 2001 From: vmouradian Date: Thu, 16 Jan 2025 10:52:36 +0100 Subject: [PATCH 13/18] wip add new getters Signed-off-by: vmouradian --- .../extensions/ContingencyLoadFlowParameters.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java index a83a9bd403..f4b3e512ab 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java +++ b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java @@ -10,6 +10,7 @@ import com.powsybl.commons.extensions.AbstractExtension; import com.powsybl.contingency.Contingency; import com.powsybl.loadflow.LoadFlowParameters; +import com.powsybl.openloadflow.OpenLoadFlowParameters; import java.util.Objects; import java.util.Optional; @@ -34,14 +35,26 @@ public Optional isDistributedSlack() { return Optional.ofNullable(distributedSlack); } + public boolean isDistributedSlack(LoadFlowParameters loadFlowParameters) { + return distributedSlack != null ? distributedSlack : loadFlowParameters.isDistributedSlack(); + } + public Optional isAreaInterchangeControl() { return Optional.ofNullable(areaInterchangeControl); } + public boolean isAreaInterchangeControl(OpenLoadFlowParameters loadFlowParametersExt) { + return areaInterchangeControl != null ? areaInterchangeControl : loadFlowParametersExt.isAreaInterchangeControl(); + } + public Optional getBalanceType() { return Optional.ofNullable(balanceType); } + public LoadFlowParameters.BalanceType getBalanceType(LoadFlowParameters loadFlowParameters) { + return balanceType != null ? balanceType : loadFlowParameters.getBalanceType(); + } + public ContingencyLoadFlowParameters setDistributedSlack(boolean distributedSlack) { this.distributedSlack = distributedSlack; return this; From aefec28d0a9546dc94431fdbc089bfec32dae92d Mon Sep 17 00:00:00 2001 From: vmouradian Date: Thu, 16 Jan 2025 11:39:49 +0100 Subject: [PATCH 14/18] unit test for getters with default values Signed-off-by: vmouradian --- .../OpenSecurityAnalysisExtensionsTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java b/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java index a5b9abecaa..a2c16439ab 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java @@ -15,6 +15,7 @@ import com.powsybl.contingency.Contingency; import com.powsybl.contingency.json.ContingencyJsonModule; import com.powsybl.loadflow.LoadFlowParameters; +import com.powsybl.openloadflow.OpenLoadFlowParameters; import org.junit.jupiter.api.Test; import java.io.IOException; @@ -45,12 +46,25 @@ void testContingencyLoadFlowParametersExtension() { ContingencyLoadFlowParameters extension = contingency.getExtension(ContingencyLoadFlowParameters.class); assertEquals(extension, contingency.getExtensionByName("contingency-load-flow-parameters")); + // test base getters assertFalse(extension.isDistributedSlack().isPresent()); assertTrue(extension.isAreaInterchangeControl().isPresent()); assertTrue(extension.getBalanceType().isPresent()); assertTrue(extension.isAreaInterchangeControl().get()); assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, extension.getBalanceType().get()); + + // test getters with default values + LoadFlowParameters loadFlowParameters = new LoadFlowParameters() + .setDistributedSlack(true) + .setBalanceType(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_GENERATION_REMAINING_MARGIN); + + OpenLoadFlowParameters openLoadFlowParameters = OpenLoadFlowParameters.create(loadFlowParameters) + .setAreaInterchangeControl(false); + + assertTrue(extension.isDistributedSlack(loadFlowParameters)); + assertTrue(extension.isAreaInterchangeControl(openLoadFlowParameters)); + assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, extension.getBalanceType(loadFlowParameters)); } @Test From 02e455f888285c4c05379a3a187e92ddb6f0b06f Mon Sep 17 00:00:00 2001 From: Damien Jeandemange Date: Thu, 16 Jan 2025 16:15:22 +0100 Subject: [PATCH 15/18] fix Signed-off-by: Damien Jeandemange --- .../sa/extensions/ContingencyLoadFlowParameters.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java index f4b3e512ab..2a2d4c4169 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java +++ b/src/main/java/com/powsybl/openloadflow/sa/extensions/ContingencyLoadFlowParameters.java @@ -12,7 +12,6 @@ import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.openloadflow.OpenLoadFlowParameters; -import java.util.Objects; import java.util.Optional; /** @@ -55,18 +54,18 @@ public LoadFlowParameters.BalanceType getBalanceType(LoadFlowParameters loadFlow return balanceType != null ? balanceType : loadFlowParameters.getBalanceType(); } - public ContingencyLoadFlowParameters setDistributedSlack(boolean distributedSlack) { + public ContingencyLoadFlowParameters setDistributedSlack(Boolean distributedSlack) { this.distributedSlack = distributedSlack; return this; } - public ContingencyLoadFlowParameters setAreaInterchangeControl(boolean areaInterchangeControl) { + public ContingencyLoadFlowParameters setAreaInterchangeControl(Boolean areaInterchangeControl) { this.areaInterchangeControl = areaInterchangeControl; return this; } public ContingencyLoadFlowParameters setBalanceType(LoadFlowParameters.BalanceType balanceType) { - this.balanceType = Objects.requireNonNull(balanceType); + this.balanceType = balanceType; return this; } } From 676f335d9635aa25d9b43fd32e17e14e211a8fc7 Mon Sep 17 00:00:00 2001 From: Damien Jeandemange Date: Thu, 16 Jan 2025 16:15:30 +0100 Subject: [PATCH 16/18] doc Signed-off-by: Damien Jeandemange --- docs/security/parameters.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/security/parameters.md b/docs/security/parameters.md index d83bb133e2..7639c695c3 100644 --- a/docs/security/parameters.md +++ b/docs/security/parameters.md @@ -76,13 +76,20 @@ open-security-analysis-default-parameters: At the moment, overriding the parameters by a JSON file is not supported by Open Load Flow. -## Contingency Parameters +## Contingency Load Flow Parameters -Some load flow related parameters can be configured per contingency. This can be done by adding to the `Contingency` object an extension of the `ContingencyLoadFlowParameters` class. -Those parameters correspond to parameters present in [`LoadFlowParameters`](inv:powsyblcore:*:*#simulation/loadflow/configuration) and [`OpenLoadFlowParameters`](../loadflow/parameters.md#specific-parameters) : +A specific set of load flow parameters can be configured for each contingency individually. -- `distributedSlack` (see [distributedSlack](inv:powsyblcore:*:*#simulation/loadflow/configuration)) -- `areaInterchangeControl` (see [areaInterchangeControl](../loadflow/parameters.md#specific-parameters)) -- `balanceType` (see [balanceType](inv:powsyblcore:*:*#simulation/loadflow/configuration)) +These parameters correspond directly to the parameters in the [`LoadFlowParameters`](inv:powsyblcore:*:*#simulation/loadflow/configuration) from powsybl-core API and +the [`OpenLoadFlowParameters`](../loadflow/parameters.md#specific-parameters) specific parameters: +- `distributedSlack`: Refer to [`distributedSlack` in powsybl-core](inv:powsyblcore:*:*#simulation/loadflow/configuration) +- `areaInterchangeControl`: Refer to [`areaInterchangeControl` in powsybl-open-loadflow](../loadflow/parameters.md#specific-parameters) +- `balanceType`: Refer to [`balanceType` in powsybl-core](inv:powsyblcore:*:*#simulation/loadflow/configuration) -If the extension is added to a contingency, the values of these parameters will override their equivalent of the SA input parameters for post contingency and post remedial actions states calculations. +To customize these parameters for a contingency, add to the `Contingency` object a `ContingencyLoadFlowParameters` extension where you may configure the parameters. +The behavior is as follows: +- When the extension is added: The specified parameters override the corresponding SA input parameters. +- When the extension is absent: The load flow parameters provided in the SA input parameters are applied. + +Note that if the operator strategies are defined for the contingency, the overridden load flow parameters will apply to +the operator strategies actions simulation too. From cc1fc9f68d287c78b69e77c94bdfbbf57f5448bd Mon Sep 17 00:00:00 2001 From: vmouradian Date: Thu, 16 Jan 2025 16:59:44 +0100 Subject: [PATCH 17/18] add test Signed-off-by: vmouradian --- .../OpenSecurityAnalysisExtensionsTest.java | 72 ++++++++++++------- src/test/resources/contingencies.json | 34 ++++++--- 2 files changed, 71 insertions(+), 35 deletions(-) diff --git a/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java b/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java index a2c16439ab..8667d349c0 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/extensions/OpenSecurityAnalysisExtensionsTest.java @@ -13,9 +13,11 @@ import com.powsybl.commons.test.AbstractSerDeTest; import com.powsybl.contingency.BranchContingency; import com.powsybl.contingency.Contingency; +import com.powsybl.contingency.contingency.list.DefaultContingencyList; import com.powsybl.contingency.json.ContingencyJsonModule; import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.openloadflow.OpenLoadFlowParameters; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.io.IOException; @@ -35,26 +37,33 @@ */ class OpenSecurityAnalysisExtensionsTest extends AbstractSerDeTest { - @Test - void testContingencyLoadFlowParametersExtension() { - Contingency contingency = new Contingency("L2", new BranchContingency("L2")); - ContingencyLoadFlowParameters contingencyLoadFlowParameters = new ContingencyLoadFlowParameters() + Contingency contingency; + ContingencyLoadFlowParameters contingencyLoadFlowParameters; + + @BeforeEach + void setUpContingency() { + contingency = new Contingency("L2", new BranchContingency("L2")); + contingencyLoadFlowParameters = new ContingencyLoadFlowParameters() .setAreaInterchangeControl(true) .setBalanceType(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD); contingency.addExtension(ContingencyLoadFlowParameters.class, contingencyLoadFlowParameters); + } - ContingencyLoadFlowParameters extension = contingency.getExtension(ContingencyLoadFlowParameters.class); - assertEquals(extension, contingency.getExtensionByName("contingency-load-flow-parameters")); + @Test + void testContingencyLoadFlowParametersExtension() { + assertEquals(contingencyLoadFlowParameters, contingency.getExtensionByName("contingency-load-flow-parameters")); // test base getters - assertFalse(extension.isDistributedSlack().isPresent()); - assertTrue(extension.isAreaInterchangeControl().isPresent()); - assertTrue(extension.getBalanceType().isPresent()); + assertFalse(contingencyLoadFlowParameters.isDistributedSlack().isPresent()); + assertTrue(contingencyLoadFlowParameters.isAreaInterchangeControl().isPresent()); + assertTrue(contingencyLoadFlowParameters.getBalanceType().isPresent()); - assertTrue(extension.isAreaInterchangeControl().get()); - assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, extension.getBalanceType().get()); + assertTrue(contingencyLoadFlowParameters.isAreaInterchangeControl().get()); + assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, contingencyLoadFlowParameters.getBalanceType().get()); + } - // test getters with default values + @Test + void testContingencyLoadFlowParametersExtensionDefaults() { LoadFlowParameters loadFlowParameters = new LoadFlowParameters() .setDistributedSlack(true) .setBalanceType(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_GENERATION_REMAINING_MARGIN); @@ -62,23 +71,36 @@ void testContingencyLoadFlowParametersExtension() { OpenLoadFlowParameters openLoadFlowParameters = OpenLoadFlowParameters.create(loadFlowParameters) .setAreaInterchangeControl(false); - assertTrue(extension.isDistributedSlack(loadFlowParameters)); - assertTrue(extension.isAreaInterchangeControl(openLoadFlowParameters)); - assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, extension.getBalanceType(loadFlowParameters)); + assertTrue(contingencyLoadFlowParameters.isDistributedSlack(loadFlowParameters)); + assertTrue(contingencyLoadFlowParameters.isAreaInterchangeControl(openLoadFlowParameters)); + assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, contingencyLoadFlowParameters.getBalanceType(loadFlowParameters)); + + //switch between overriden and default values + + contingencyLoadFlowParameters.setDistributedSlack(true); + contingencyLoadFlowParameters.setAreaInterchangeControl(null); + contingencyLoadFlowParameters.setBalanceType(null); + + assertFalse(contingencyLoadFlowParameters.isAreaInterchangeControl(openLoadFlowParameters)); + assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_GENERATION_REMAINING_MARGIN, contingencyLoadFlowParameters.getBalanceType(loadFlowParameters)); } @Test void testContingencyLoadFlowParametersExtensionJson() throws IOException { - Contingency contingency = new Contingency("L2", new BranchContingency("L2")); - ContingencyLoadFlowParameters contingencyLoadFlowParameters = new ContingencyLoadFlowParameters().setDistributedSlack(false) - .setAreaInterchangeControl(true) - .setBalanceType(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD); + contingencyLoadFlowParameters.setDistributedSlack(false); contingency.addExtension(ContingencyLoadFlowParameters.class, contingencyLoadFlowParameters); assertEquals(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParametersJsonSerializer().getExtensionClass()); - roundTripTest(contingency, OpenSecurityAnalysisExtensionsTest::writeContingency, OpenSecurityAnalysisExtensionsTest::readContingency, "/contingencies.json"); + + ContingencyLoadFlowParameters contingencyLoadFlowParameters2 = new ContingencyLoadFlowParameters(); + Contingency contingency2 = new Contingency("L5", new BranchContingency("L5")); + contingency2.addExtension(ContingencyLoadFlowParameters.class, contingencyLoadFlowParameters2); + + DefaultContingencyList contingencyList = new DefaultContingencyList(contingency, contingency2); + + roundTripTest(contingencyList, OpenSecurityAnalysisExtensionsTest::writeContingency, OpenSecurityAnalysisExtensionsTest::readContingencyList, "/contingencies.json"); } - public static Contingency readContingency(Path jsonFile) { + public static DefaultContingencyList readContingencyList(Path jsonFile) { Objects.requireNonNull(jsonFile); try (InputStream is = Files.newInputStream(jsonFile)) { @@ -86,14 +108,14 @@ public static Contingency readContingency(Path jsonFile) { ContingencyJsonModule module = new ContingencyJsonModule(); objectMapper.registerModule(module); - return objectMapper.readValue(is, Contingency.class); + return objectMapper.readValue(is, DefaultContingencyList.class); } catch (IOException e) { throw new UncheckedIOException(e); } } - public static void writeContingency(Contingency contingency, Path jsonFile) { - Objects.requireNonNull(contingency); + public static void writeContingency(DefaultContingencyList contingencyList, Path jsonFile) { + Objects.requireNonNull(contingencyList); Objects.requireNonNull(jsonFile); try (OutputStream os = Files.newOutputStream(jsonFile)) { @@ -102,7 +124,7 @@ public static void writeContingency(Contingency contingency, Path jsonFile) { mapper.registerModule(module); ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); - writer.writeValue(os, contingency); + writer.writeValue(os, contingencyList); } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/src/test/resources/contingencies.json b/src/test/resources/contingencies.json index 4b1a9ea4d8..b3d264ae06 100644 --- a/src/test/resources/contingencies.json +++ b/src/test/resources/contingencies.json @@ -1,14 +1,28 @@ { - "id" : "L2", - "elements" : [ { + "type" : "default", + "version" : "1.0", + "name" : "", + "contingencies" : [ { "id" : "L2", - "type" : "BRANCH" - } ], - "extensions" : { - "contingency-load-flow-parameters" : { - "distributedSlack" : false, - "areaInterchangeControl" : true, - "balanceType" : "PROPORTIONAL_TO_LOAD" + "elements" : [ { + "id" : "L2", + "type" : "BRANCH" + } ], + "extensions" : { + "contingency-load-flow-parameters" : { + "distributedSlack" : false, + "areaInterchangeControl" : true, + "balanceType" : "PROPORTIONAL_TO_LOAD" + } } - } + }, { + "id" : "L5", + "elements" : [ { + "id" : "L5", + "type" : "BRANCH" + } ], + "extensions" : { + "contingency-load-flow-parameters" : { } + } + } ] } \ No newline at end of file From cc8ad5a19d83abfafd79c7f431bcea1848f1c3fd Mon Sep 17 00:00:00 2001 From: vmouradian Date: Thu, 16 Jan 2025 17:13:55 +0100 Subject: [PATCH 18/18] doc Signed-off-by: vmouradian --- docs/security/parameters.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/security/parameters.md b/docs/security/parameters.md index 7639c695c3..54a9c8c904 100644 --- a/docs/security/parameters.md +++ b/docs/security/parameters.md @@ -87,9 +87,13 @@ the [`OpenLoadFlowParameters`](../loadflow/parameters.md#specific-parameters) sp - `balanceType`: Refer to [`balanceType` in powsybl-core](inv:powsyblcore:*:*#simulation/loadflow/configuration) To customize these parameters for a contingency, add to the `Contingency` object a `ContingencyLoadFlowParameters` extension where you may configure the parameters. -The behavior is as follows: + +The behaviour is not implemented yet. +It will be as follows: - When the extension is added: The specified parameters override the corresponding SA input parameters. - When the extension is absent: The load flow parameters provided in the SA input parameters are applied. Note that if the operator strategies are defined for the contingency, the overridden load flow parameters will apply to the operator strategies actions simulation too. + +This extension does not override any parameter in case of a sensitivity analysis.