Skip to content

Commit

Permalink
Skip models with duplicate dynamic id for dynamic and event model lis…
Browse files Browse the repository at this point in the history
…ts (#293)

* Skip models with duplicate dynamic id for dynamic and event model lists
* Use predicate for duplicate ID double check

Signed-off-by: lisrte <laurent.issertial@rte-france.com>
  • Loading branch information
Lisrte authored Oct 11, 2023
1 parent 5f03058 commit d2b9c62
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 41 deletions.
54 changes: 27 additions & 27 deletions dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -60,8 +61,12 @@ public DynaWaltzContext(Network network, String workingVariantId, List<BlackBoxM
List<Curve> 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)
Expand Down Expand Up @@ -166,31 +171,26 @@ public <T extends Model> T getPureDynamicModel(String dynamicId, Class<T> connec
}
}

private static List<BlackBoxModel> checkDuplicateStaticId(List<BlackBoxModel> dynamicModels) {
Set<String> 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<BlackBoxModel> checkEventModelIdUniqueness(List<BlackBoxModel> eventModels) {
Set<String> dynamicIds = new HashSet<>();
Set<String> duplicates = new HashSet<>();
for (BlackBoxModel bbm : eventModels) {
if (!dynamicIds.add(bbm.getDynamicModelId())) {
duplicates.add(bbm.getDynamicModelId());
protected static Predicate<BlackBoxModel> distinctByStaticId() {
Set<String> 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<BlackBoxModel> distinctByDynamicId() {
Set<String> 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<MacroConnectAttribute> attributesFrom, List<MacroConnectAttribute> attributesTo) {
Expand Down Expand Up @@ -262,7 +262,7 @@ public Stream<BlackBoxModel> getBlackBoxEventModelStream() {
}

public List<BlackBoxModel> getBlackBoxEventModels() {
return Collections.unmodifiableList(eventModels);
return eventModels;
}

public List<Curve> getCurves() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <demiguelm at aia.es>
*/
Expand All @@ -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);
}
}

0 comments on commit d2b9c62

Please sign in to comment.