diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java index 019ed49f1..d3302c725 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java @@ -36,6 +36,7 @@ public class DynaWaltzContext { private final DynaWaltzParametersDatabase parametersDatabase; private final List dynamicModels; private final List eventModels; + private final Map staticIdBlackBoxModelMap; private final List curves; private final Map macroStaticReferences = new LinkedHashMap<>(); private final Map connectorsMap = new LinkedHashMap<>(); @@ -58,7 +59,10 @@ public DynaWaltzContext(Network network, String workingVariantId, List blackBoxModel.getStaticId().isPresent()) + .collect(Collectors.toMap(bbm -> bbm.getStaticId().get(), Function.identity(), this::mergeDuplicateStaticId, LinkedHashMap::new)); this.curves = Objects.requireNonNull(curves); this.parameters = Objects.requireNonNull(parameters); this.dynaWaltzParameters = Objects.requireNonNull(dynaWaltzParameters); @@ -117,14 +121,26 @@ public Collection getMacroStaticReferences() { return macroStaticReferences.values(); } - public Map getStaticIdBlackBoxModelMap() { - return getInputBlackBoxDynamicModelStream() - .filter(blackBoxModel -> blackBoxModel.getStaticId().isPresent()) - .collect(Collectors.toMap(bbm -> bbm.getStaticId().get(), Function.identity(), this::mergeDuplicateStaticId, LinkedHashMap::new)); + public BlackBoxModel getStaticIdBlackBoxModel(String staticId) { + return staticIdBlackBoxModelMap.get(staticId); } private BlackBoxModel mergeDuplicateStaticId(BlackBoxModel bbm1, BlackBoxModel bbm2) { - throw new AssertionError("Duplicate staticId " + bbm1.getStaticId()); + throw new PowsyblException("Duplicate staticId: " + bbm1.getStaticId().orElseThrow()); + } + + 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()); + } + } + if (!duplicates.isEmpty()) { + throw new PowsyblException("Duplicate dynamicId: " + duplicates); + } + return eventModels; } public Collection getMacroConnectors() { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/OmegaRef.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/OmegaRef.java index 7f8022f1b..56965f080 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/OmegaRef.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/OmegaRef.java @@ -112,7 +112,7 @@ private BusModel getBusAssociatedTo(GeneratorSynchronousModel generatorModel, Dy throw new PowsyblException("Generator " + generatorModel.getLib() + " not found in DynaWaltz context. Id : " + generatorModel.getDynamicModelId()); } String connectedStaticId = generator.getTerminal().getBusBreakerView().getConnectableBus().getId(); - BusModel busModel = (BusModel) context.getStaticIdBlackBoxModelMap().get(connectedStaticId); + BusModel busModel = (BusModel) context.getStaticIdBlackBoxModel(connectedStaticId); if (busModel == null) { busModel = context.getNetworkModel().getDefaultBusModel(connectedStaticId); } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automatons/CurrentLimitAutomaton.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automatons/CurrentLimitAutomaton.java index d64c02abe..76e490ac0 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automatons/CurrentLimitAutomaton.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automatons/CurrentLimitAutomaton.java @@ -45,7 +45,7 @@ public List getModelsConnectedTo(DynaWaltzContext context) { if (line == null) { throw new PowsyblException("Unknown line static id: " + lineStaticId); } - BlackBoxModel connectedBbm = context.getStaticIdBlackBoxModelMap().get(line.getId()); + BlackBoxModel connectedBbm = context.getStaticIdBlackBoxModel(line.getId()); if (connectedBbm == null) { return List.of(context.getNetworkModel().getDefaultLineModel(lineStaticId, side)); } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/buses/StandardBus.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/buses/StandardBus.java index f38695df9..c39f78a0d 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/buses/StandardBus.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/buses/StandardBus.java @@ -83,7 +83,7 @@ public List getModelsConnectedTo(DynaWaltzContext dynaWaltzContext) { List connectedBbm = new ArrayList<>(); for (Generator g : dynaWaltzContext.getNetwork().getGenerators()) { if (g.getTerminal().getBusBreakerView().getConnectableBus().equals(bus)) { - connectedBbm.add(dynaWaltzContext.getStaticIdBlackBoxModelMap().get(g.getId())); + connectedBbm.add(dynaWaltzContext.getStaticIdBlackBoxModel(g.getId())); } } return connectedBbm; diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventQuadripoleDisconnection.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventQuadripoleDisconnection.java index 6ac5316c6..f2fe96b2e 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventQuadripoleDisconnection.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventQuadripoleDisconnection.java @@ -51,7 +51,7 @@ public List getVarConnectionsWith(Model connected) { @Override public List getModelsConnectedTo(DynaWaltzContext context) { - BlackBoxModel connectedBbm = context.getStaticIdBlackBoxModelMap().get(getEquipmentStaticId()); + BlackBoxModel connectedBbm = context.getStaticIdBlackBoxModel(getEquipmentStaticId()); if (connectedBbm == null) { return List.of(context.getNetworkModel().getDefaultLineModel(getEquipmentStaticId(), Branch.Side.ONE)); } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventSetPointBoolean.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventSetPointBoolean.java index a7cae41f7..8429f94b9 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventSetPointBoolean.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventSetPointBoolean.java @@ -47,7 +47,7 @@ public List getVarConnectionsWith(Model connected) { @Override public List getModelsConnectedTo(DynaWaltzContext context) { - BlackBoxModel connectedBbm = context.getStaticIdBlackBoxModelMap().get(getEquipmentStaticId()); + BlackBoxModel connectedBbm = context.getStaticIdBlackBoxModel(getEquipmentStaticId()); if (connectedBbm == null) { throw new PowsyblException("Cannot find generator '" + getEquipmentStaticId() + "' among the dynamic models provided"); } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/AbstractGeneratorModel.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/AbstractGeneratorModel.java index c4863a123..945a51db6 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/AbstractGeneratorModel.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/AbstractGeneratorModel.java @@ -57,7 +57,7 @@ public List getModelsConnectedTo(DynaWaltzContext context) { throw new PowsyblException("Generator static id unknown: " + staticId); } String connectedStaticId = generator.getTerminal().getBusBreakerView().getConnectableBus().getId(); - BlackBoxModel connectedBbm = context.getStaticIdBlackBoxModelMap().get(connectedStaticId); + BlackBoxModel connectedBbm = context.getStaticIdBlackBoxModel(connectedStaticId); if (connectedBbm == null) { return List.of(context.getNetworkModel().getDefaultBusModel(connectedStaticId)); } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/lines/StandardLine.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/lines/StandardLine.java index 3486acd22..7e2e05e48 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/lines/StandardLine.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/lines/StandardLine.java @@ -57,7 +57,7 @@ public List getModelsConnectedTo(DynaWaltzContext dynaWaltzContext) { List connectedBbm = new ArrayList<>(); for (Bus b : dynaWaltzContext.getNetwork().getBusBreakerView().getBuses()) { if (b.getLineStream().anyMatch(l -> l.equals(line))) { - connectedBbm.add(dynaWaltzContext.getStaticIdBlackBoxModelMap().get(b.getId())); + connectedBbm.add(dynaWaltzContext.getStaticIdBlackBoxModel(b.getId())); } } return connectedBbm; diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/AbstractLoad.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/AbstractLoad.java index 7b16f5f0a..d1fbfff74 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/AbstractLoad.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/AbstractLoad.java @@ -33,7 +33,7 @@ public List getModelsConnectedTo(DynaWaltzContext context) { throw new PowsyblException("Load static id unknown: " + staticId); } String connectedStaticId = load.getTerminal().getBusBreakerView().getConnectableBus().getId(); - BlackBoxModel connectedBbm = context.getStaticIdBlackBoxModelMap().get(connectedStaticId); + BlackBoxModel connectedBbm = context.getStaticIdBlackBoxModel(connectedStaticId); if (connectedBbm == null) { return List.of(context.getNetworkModel().getDefaultBusModel(connectedStaticId)); } diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynaWaltzTestUtil.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynaWaltzTestUtil.java index 1b848713b..20febc011 100644 --- a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynaWaltzTestUtil.java +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynaWaltzTestUtil.java @@ -14,16 +14,14 @@ import com.powsybl.dynawaltz.models.buses.StandardBus; import com.powsybl.dynawaltz.models.events.EventQuadripoleDisconnection; import com.powsybl.dynawaltz.models.events.EventSetPointBoolean; -import com.powsybl.dynawaltz.models.generators.*; +import com.powsybl.dynawaltz.models.generators.GeneratorFictitious; +import com.powsybl.dynawaltz.models.generators.GeneratorSynchronous; import com.powsybl.dynawaltz.models.lines.StandardLine; import com.powsybl.dynawaltz.models.loads.LoadAlphaBeta; import com.powsybl.dynawaltz.models.loads.LoadOneTransformer; import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; -import junit.framework.AssertionFailedError; import org.junit.Before; -import org.junit.Rule; -import org.junit.rules.ExpectedException; import org.xml.sax.SAXException; import javax.xml.XMLConstants; @@ -45,9 +43,6 @@ */ public class DynaWaltzTestUtil extends AbstractConverterTest { - @Rule - public ExpectedException exception = ExpectedException.none(); - protected Network network; protected List dynamicModels; protected List eventModels; @@ -105,9 +100,7 @@ public void setup() { // Events eventModels = new ArrayList<>(); - network.getLineStream().forEach(l -> { - eventModels.add(new EventQuadripoleDisconnection("EM_" + l.getId(), l.getId(), 5, false, true)); - }); + network.getLineStream().forEach(l -> eventModels.add(new EventQuadripoleDisconnection("EM_" + l.getId(), l.getId(), 5, false, true))); network.getGeneratorStream().forEach(g -> { if (g.getId().equals("GEN2")) { eventModels.add(new EventSetPointBoolean("EM_" + g.getId(), g.getId(), 1, true)); @@ -115,9 +108,7 @@ public void setup() { }); // Automatons - network.getLineStream().forEach(l -> { - dynamicModels.add(new CurrentLimitAutomaton("BBM_" + l.getId(), l.getId(), "CLA", Branch.Side.ONE)); - }); + network.getLineStream().forEach(l -> dynamicModels.add(new CurrentLimitAutomaton("BBM_" + l.getId(), l.getId(), "CLA", Branch.Side.ONE))); } public void validate(String schemaDefinition, String expectedResourceName, Path xmlFile) throws SAXException, IOException { @@ -214,17 +205,4 @@ private static Network createEurostagTutorialExample1WithMoreLoads() { .add(); return network; } - - public static T assertThrows(Class expectedType, Runnable runnable) { - try { - runnable.run(); - } catch (Throwable actualException) { - if (expectedType.isInstance(actualException)) { - return (T) actualException; - } else { - throw new AssertionFailedError(String.format("Expected %s to be thrown, but %s was thrown", expectedType.getCanonicalName(), actualException.getClass().getCanonicalName())); - } - } - throw new AssertionFailedError(String.format("Expected %s to be thrown, but nothing was thrown.", expectedType.getCanonicalName())); - } } 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 1b267b487..0dbae84b5 100644 --- a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynamicModelsXmlTest.java +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynamicModelsXmlTest.java @@ -6,6 +6,7 @@ */ 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; @@ -17,6 +18,9 @@ import java.io.IOException; import java.util.ArrayList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + /** * @author Marcos de Miguel */ @@ -49,4 +53,17 @@ public void writeDynamicModelWithLoadsAndOnlyOneFictitiousGenerator() throws SAX validate("dyd.xsd", "dyd_fictitious.xml", tmpDir.resolve(DynaWaltzConstants.DYD_FILENAME)); } + @Test + public void duplicateStaticId() { + dynamicModels.clear(); + network.getGeneratorStream().forEach(gen -> { + if (gen.getId().equals("GEN5") || gen.getId().equals("GEN6")) { + dynamicModels.add(new GeneratorFictitious("BBM_" + gen.getId(), "duplicateID", "GF")); + } + }); + String workingVariantId = network.getVariantManager().getWorkingVariantId(); + Exception e = assertThrows(PowsyblException.class, () -> new DynaWaltzContext(network, workingVariantId, dynamicModels, eventModels, curves, null, null)); + assertEquals("Duplicate staticId: duplicateID", e.getMessage()); + } + } 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 b48e57298..26b1e1fac 100644 --- a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/EventXmlTest.java +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/EventXmlTest.java @@ -6,17 +6,21 @@ */ 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.BlackBoxModel; +import com.powsybl.dynawaltz.models.events.EventQuadripoleDisconnection; +import com.powsybl.dynawaltz.models.events.EventSetPointBoolean; import com.powsybl.dynawaltz.models.generators.GeneratorSynchronous; import org.junit.Test; import org.xml.sax.SAXException; import javax.xml.stream.XMLStreamException; import java.io.IOException; -import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; /** * @author Marcos de Miguel @@ -25,9 +29,8 @@ public class EventXmlTest extends DynaWaltzTestUtil { @Test public void writeDynamicModel() throws SAXException, IOException, XMLStreamException { - List dynamicModels = List.of( - new GeneratorSynchronous("BBM_GEN2", "GEN2", "GSFWPR", "GeneratorSynchronousFourWindingsProportionalRegulations") - ); + dynamicModels.clear(); + dynamicModels.add(new GeneratorSynchronous("BBM_GEN2", "GEN2", "GSFWPR", "GeneratorSynchronousFourWindingsProportionalRegulations")); DynamicSimulationParameters parameters = DynamicSimulationParameters.load(); DynaWaltzParameters dynawoParameters = DynaWaltzParameters.load(); DynaWaltzContext context = new DynaWaltzContext(network, network.getVariantManager().getWorkingVariantId(), @@ -37,4 +40,18 @@ public void writeDynamicModel() throws SAXException, IOException, XMLStreamExcep validate("dyd.xsd", "events.xml", tmpDir.resolve(DynaWaltzConstants.DYD_FILENAME)); } + @Test + public void duplicateEventId() { + eventModels.clear(); + network.getLineStream().forEach(l -> eventModels.add(new EventQuadripoleDisconnection("duplicateID", l.getId(), 5, false, true))); + network.getGeneratorStream().forEach(g -> { + if (g.getId().equals("GEN2") || g.getId().equals("GEN4")) { + eventModels.add(new EventSetPointBoolean("duplicateID2", g.getId(), 1, true)); + } + }); + String workingVariantId = network.getVariantManager().getWorkingVariantId(); + Exception e = assertThrows(PowsyblException.class, () -> new DynaWaltzContext(network, workingVariantId, dynamicModels, eventModels, curves, null, null)); + assertEquals("Duplicate dynamicId: [duplicateID, duplicateID2]", e.getMessage()); + } + }