From d2b9c627103d552d887e63eda638e434ebc6b840 Mon Sep 17 00:00:00 2001 From: Lisrte Date: Wed, 11 Oct 2023 11:02:42 +0200 Subject: [PATCH] Skip models with duplicate dynamic id for dynamic and event model lists (#293) * Skip models with duplicate dynamic id for dynamic and event model lists * Use predicate for duplicate ID double check Signed-off-by: lisrte --- .../powsybl/dynawaltz/DynaWaltzContext.java | 54 +++++++++---------- .../dynawaltz/xml/DynamicModelsXmlTest.java | 25 ++++++--- .../powsybl/dynawaltz/xml/EventXmlTest.java | 15 +++--- 3 files changed, 53 insertions(+), 41 deletions(-) diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java index 09614f1a7..0e8a41f1a 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java @@ -28,6 +28,7 @@ import java.util.*; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -60,8 +61,12 @@ public DynaWaltzContext(Network network, String workingVariantId, List curves, DynamicSimulationParameters parameters, DynaWaltzParameters dynaWaltzParameters) { this.network = Objects.requireNonNull(network); this.workingVariantId = Objects.requireNonNull(workingVariantId); - this.dynamicModels = checkDuplicateStaticId(Objects.requireNonNull(dynamicModels)); - this.eventModels = checkEventModelIdUniqueness(Objects.requireNonNull(eventModels)); + this.dynamicModels = Objects.requireNonNull(dynamicModels).stream() + .filter(distinctByDynamicId().and(distinctByStaticId())) + .toList(); + this.eventModels = Objects.requireNonNull(eventModels).stream() + .filter(distinctByDynamicId()) + .toList(); this.staticIdBlackBoxModelMap = getInputBlackBoxDynamicModelStream() .filter(EquipmentBlackBoxModel.class::isInstance) .map(EquipmentBlackBoxModel.class::cast) @@ -166,31 +171,26 @@ public T getPureDynamicModel(String dynamicId, Class connec } } - private static List checkDuplicateStaticId(List dynamicModels) { - Set staticIds = new HashSet<>(); - return dynamicModels.stream() - .filter(bbm -> { - if (bbm instanceof EquipmentBlackBoxModel eBbm && !staticIds.add(eBbm.getStaticId())) { - LOGGER.warn("Duplicate static id found: {} -> dynamic model {} {} will be skipped", eBbm.getStaticId(), eBbm.getLib(), eBbm.getDynamicModelId()); - return false; - } - return true; - }) - .collect(Collectors.toList()); - } - - private static List checkEventModelIdUniqueness(List eventModels) { - Set dynamicIds = new HashSet<>(); - Set duplicates = new HashSet<>(); - for (BlackBoxModel bbm : eventModels) { - if (!dynamicIds.add(bbm.getDynamicModelId())) { - duplicates.add(bbm.getDynamicModelId()); + protected static Predicate distinctByStaticId() { + Set seen = new HashSet<>(); + return bbm -> { + if (bbm instanceof EquipmentBlackBoxModel eBbm && !seen.add(eBbm.getStaticId())) { + LOGGER.warn("Duplicate static id found: {} -> dynamic model {} {} will be skipped", eBbm.getStaticId(), eBbm.getLib(), eBbm.getDynamicModelId()); + return false; } - } - if (!duplicates.isEmpty()) { - throw new PowsyblException("Duplicate dynamicId: " + duplicates); - } - return eventModels; + return true; + }; + } + + protected static Predicate distinctByDynamicId() { + Set seen = new HashSet<>(); + return bbm -> { + if (!seen.add(bbm.getDynamicModelId())) { + LOGGER.warn("Duplicate dynamic id found: {} -> model {} will be skipped", bbm.getDynamicModelId(), bbm.getName()); + return false; + } + return true; + }; } public void addMacroConnect(String macroConnectorId, List attributesFrom, List attributesTo) { @@ -262,7 +262,7 @@ public Stream getBlackBoxEventModelStream() { } public List getBlackBoxEventModels() { - return Collections.unmodifiableList(eventModels); + return eventModels; } public List getCurves() { diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynamicModelsXmlTest.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynamicModelsXmlTest.java index 04f751dc7..ebcb229a5 100644 --- a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynamicModelsXmlTest.java +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynamicModelsXmlTest.java @@ -13,8 +13,10 @@ import com.powsybl.dynawaltz.models.InjectionModel; import com.powsybl.dynawaltz.models.generators.GeneratorFictitious; import com.powsybl.dynawaltz.models.lines.LineModel; +import com.powsybl.dynawaltz.models.loads.BaseLoad; import com.powsybl.dynawaltz.models.transformers.TapChangerModel; import com.powsybl.iidm.network.Identifiable; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.xml.sax.SAXException; @@ -61,14 +63,25 @@ void writeDynamicModelWithLoadsAndOnlyOneFictitiousGenerator() throws SAXExcepti @Test void duplicateStaticId() { dynamicModels.clear(); - network.getGeneratorStream().forEach(gen -> { - if (gen.getId().equals("GEN5") || gen.getId().equals("GEN6")) { - dynamicModels.add(new GeneratorFictitious("BBM_" + gen.getId(), network.getGenerator("GEN5"), "GF")); - } - }); + BaseLoad load1 = new BaseLoad("BBM_LOAD", network.getLoad("LOAD"), "lab", "LoadAlphaBeta"); + BaseLoad load2 = new BaseLoad("BBM_LOAD2", network.getLoad("LOAD"), "lab", "LoadAlphaBeta"); + dynamicModels.add(load1); + dynamicModels.add(load2); + String workingVariantId = network.getVariantManager().getWorkingVariantId(); + DynaWaltzContext context = new DynaWaltzContext(network, workingVariantId, dynamicModels, eventModels, curves, DynamicSimulationParameters.load(), DynaWaltzParameters.load()); + Assertions.assertThat(context.getBlackBoxDynamicModels()).containsExactly(load1); + } + + @Test + void duplicateDynamicId() { + dynamicModels.clear(); + BaseLoad load1 = new BaseLoad("BBM_LOAD", network.getLoad("LOAD"), "lab", "LoadAlphaBeta"); + BaseLoad load2 = new BaseLoad("BBM_LOAD", network.getLoad("LOAD2"), "lab", "LoadAlphaBeta"); + dynamicModels.add(load1); + dynamicModels.add(load2); String workingVariantId = network.getVariantManager().getWorkingVariantId(); DynaWaltzContext context = new DynaWaltzContext(network, workingVariantId, dynamicModels, eventModels, curves, DynamicSimulationParameters.load(), DynaWaltzParameters.load()); - assertEquals(1, context.getBlackBoxDynamicModels().size()); + Assertions.assertThat(context.getBlackBoxDynamicModels()).containsExactly(load1); } @Test diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/EventXmlTest.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/EventXmlTest.java index 4d19caa83..8b19021d5 100644 --- a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/EventXmlTest.java +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/EventXmlTest.java @@ -6,22 +6,19 @@ */ package com.powsybl.dynawaltz.xml; -import com.powsybl.commons.PowsyblException; import com.powsybl.dynamicsimulation.DynamicSimulationParameters; import com.powsybl.dynawaltz.DynaWaltzContext; import com.powsybl.dynawaltz.DynaWaltzParameters; import com.powsybl.dynawaltz.models.events.EventInjectionDisconnection; import com.powsybl.dynawaltz.models.events.EventQuadripoleDisconnection; import com.powsybl.dynawaltz.models.generators.SynchronousGenerator; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.xml.sax.SAXException; import javax.xml.stream.XMLStreamException; import java.io.IOException; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - /** * @author Marcos de Miguel */ @@ -43,12 +40,14 @@ void writeDynamicModel() throws SAXException, IOException, XMLStreamException { @Test void duplicateEventId() { eventModels.clear(); - eventModels.add(new EventQuadripoleDisconnection(network.getLine("NHV1_NHV2_1"), 5)); + EventQuadripoleDisconnection event1 = new EventQuadripoleDisconnection(network.getLine("NHV1_NHV2_1"), 5); + EventInjectionDisconnection event2 = new EventInjectionDisconnection(network.getGenerator("GEN2"), 1, true); + eventModels.add(event1); eventModels.add(new EventQuadripoleDisconnection(network.getLine("NHV1_NHV2_1"), 5, true, false)); - eventModels.add(new EventInjectionDisconnection(network.getGenerator("GEN2"), 1, true)); + eventModels.add(event2); eventModels.add(new EventInjectionDisconnection(network.getGenerator("GEN2"), 1, false)); String workingVariantId = network.getVariantManager().getWorkingVariantId(); - Exception e = assertThrows(PowsyblException.class, () -> new DynaWaltzContext(network, workingVariantId, dynamicModels, eventModels, curves, null, null)); - assertEquals("Duplicate dynamicId: [Disconnect_NHV1_NHV2_1, Disconnect_GEN2]", e.getMessage()); + DynaWaltzContext context = new DynaWaltzContext(network, workingVariantId, dynamicModels, eventModels, curves, DynamicSimulationParameters.load(), DynaWaltzParameters.load()); + Assertions.assertThat(context.getBlackBoxEventModels()).containsExactly(event1, event2); } }