Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix byFilter deletion network impacts reduction #590

Merged
merged 8 commits into from
Feb 7, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.gridsuite.modification.NetworkModificationException.Type.MODIFICATION_ERROR;

Expand Down Expand Up @@ -267,30 +268,44 @@ private void flushEquipmentInfos() {
equipmentInfosService.addAllEquipmentInfos(modifiedEquipments);
}

private List<AbstractBaseImpact> reduceNetworkImpacts() {
private List<AbstractBaseImpact> reduceDeletionImpacts() {
List<AbstractBaseImpact> reducedDeletionImpacts = new ArrayList<>();
List<SimpleElementImpact> deletionImpacts = getDeletionSimpleImpacts();
Set<String> deletionImpactedSubstationsIds = getImpactedSubstationIds(deletionImpacts);
// All network is impacted ? then return only one substation collection impact
if (deletionImpactedSubstationsIds.size() >= collectionThreshold) {
return getFullNetworkImpact();
}

// Do not reduce deletion impacts to collection impacts
// keep simple impacts
reducedDeletionImpacts.addAll(deletionImpacts);
return reducedDeletionImpacts;
}

private List<AbstractBaseImpact> reduceCreationModificationImpacts() {
List<AbstractBaseImpact> reducedImpacts = new ArrayList<>();
Set<String> impactedSubstationsIds = new HashSet<>();

// Impacts type collection
// Group simple impacts over same element type into collection impact
// And compute impactedSubstationsIds on the way
for (IdentifiableType elementType : IdentifiableType.values()) {
List<SimpleElementImpact> impacts = getSimpleImpacts(elementType);
if (impacts.size() >= collectionThreshold) {
reducedImpacts.add(CollectionElementImpact.builder()
.elementType(elementType)
.build());
} else {
impactedSubstationsIds.addAll(impacts.stream().flatMap(i -> i.getSubstationIds().stream()).toList());
impactedSubstationsIds.addAll(getImpactedSubstationIds(impacts));
}
}

// All network is impacted ?
// All network is impacted ? then return only one substation collection impact
if (impactedSubstationsIds.size() >= collectionThreshold) {
return List.of(CollectionElementImpact.builder()
.elementType(IdentifiableType.SUBSTATION)
.build());
return getFullNetworkImpact();
}

// Impacts type simple for substation only
// Create Simple Impacts for substation type only
reducedImpacts.addAll(
impactedSubstationsIds.stream().map(id ->
SimpleElementImpact.builder()
Expand All @@ -301,11 +316,48 @@ private List<AbstractBaseImpact> reduceNetworkImpacts() {
.build()
).toList()
);
return reducedImpacts;
}

// Impacts type simple for deletion only
reducedImpacts.addAll(simpleImpacts.stream().filter(SimpleElementImpact::isDeletion).distinct().toList());
private List<AbstractBaseImpact> reduceNetworkImpacts() {

return reducedImpacts;
List<AbstractBaseImpact> reducedDeletionImpacts = reduceDeletionImpacts();
if (isAllNetworkImpacted(reducedDeletionImpacts)) {
return reducedDeletionImpacts;
}

List<AbstractBaseImpact> reducedModificationImpacts = reduceCreationModificationImpacts();
if (isAllNetworkImpacted(reducedModificationImpacts)) {
return reducedModificationImpacts;
}

// fuse both reduced impacts
return Stream.concat(reducedModificationImpacts.stream(), reducedDeletionImpacts.stream()).toList();
}

private List<AbstractBaseImpact> getFullNetworkImpact() {
return List.of(CollectionElementImpact.builder()
.elementType(IdentifiableType.SUBSTATION)
.build());
}

private boolean isAllNetworkImpacted(List<AbstractBaseImpact> impacts) {
return impacts.contains(CollectionElementImpact.builder()
.elementType(IdentifiableType.SUBSTATION)
.build());
}

private Set<String> getImpactedSubstationIds(List<SimpleElementImpact> impacts) {
Set<String> impactedSubstationsIds = new HashSet<>();
impactedSubstationsIds.addAll(impacts.stream().flatMap(i -> i.getSubstationIds().stream()).toList());
return impactedSubstationsIds;
}

private List<SimpleElementImpact> getDeletionSimpleImpacts() {
return simpleImpacts.stream()
.filter(SimpleElementImpact::isDeletion)
.distinct()
.toList();
}

private List<SimpleElementImpact> getSimpleImpacts(IdentifiableType elementType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
abstract class AbstractByFilterDeletionTest extends AbstractNetworkModificationTest {
protected static final UUID FILTER_ID_1 = UUID.randomUUID();
protected static final UUID FILTER_ID_2 = UUID.randomUUID();
protected static final UUID FILTER_ID_3 = UUID.randomUUID();

protected static final String EQUIPMENT_WRONG_ID_1 = "wrongId1";

protected abstract IdentifiableType getIdentifiableType();
Expand Down Expand Up @@ -149,10 +151,15 @@ protected ModificationInfos buildModification() {
.name("filter2")
.build();

var filter3 = FilterInfos.builder()
.id(FILTER_ID_3)
.name("filter3")
.build();

return ByFilterDeletionInfos.builder()
.stashed(false)
.equipmentType(getIdentifiableType())
.filters(List.of(filter1, filter2))
.filters(List.of(filter1, filter2, filter3))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter;
import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes;
import org.gridsuite.filter.utils.EquipmentType;
import org.gridsuite.modification.server.impacts.AbstractBaseImpact;
import org.gridsuite.modification.server.service.FilterService;
import org.gridsuite.modification.server.utils.NetworkCreation;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -22,6 +23,8 @@
import java.util.List;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;
import static org.gridsuite.modification.server.impacts.TestImpactUtils.createCollectionElementImpact;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

Expand All @@ -31,6 +34,9 @@ class EquipmentByFilterDeletionTest extends AbstractByFilterDeletionTest {
private static final String LOAD_ID_2 = "load2";
private static final String LOAD_ID_3 = "load3";
private static final String LOAD_ID_4 = "load4";
private static final String LOAD_ID_7 = "load7";
private static final String LOAD_ID_11 = "load11";
private static final String LOAD_ID_12 = "load12";

@BeforeEach
void specificSetUp() {
Expand All @@ -49,6 +55,9 @@ protected void assertAfterNetworkModificationCreation() {
assertNull(getNetwork().getLoad(LOAD_ID_2));
assertNull(getNetwork().getLoad(LOAD_ID_3));
assertNull(getNetwork().getLoad(LOAD_ID_4));
assertNull(getNetwork().getLoad(LOAD_ID_7));
assertNull(getNetwork().getLoad(LOAD_ID_11));
assertNull(getNetwork().getLoad(LOAD_ID_12));
}

@Override
Expand All @@ -57,6 +66,9 @@ protected void assertAfterNetworkModificationDeletion() {
assertNotNull(getNetwork().getLoad(LOAD_ID_2));
assertNotNull(getNetwork().getLoad(LOAD_ID_3));
assertNotNull(getNetwork().getLoad(LOAD_ID_4));
assertNotNull(getNetwork().getLoad(LOAD_ID_7));
assertNotNull(getNetwork().getLoad(LOAD_ID_11));
assertNotNull(getNetwork().getLoad(LOAD_ID_12));
}

@Override
Expand Down Expand Up @@ -84,6 +96,16 @@ protected List<AbstractFilter> getTestFilters() {
.filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(LOAD_ID_3, null),
new IdentifierListFilterEquipmentAttributes(LOAD_ID_4, null)))
.build();
return List.of(filter1, filter2);
IdentifierListFilter filter3 = IdentifierListFilter.builder().id(FILTER_ID_3).modificationDate(new Date()).equipmentType(EquipmentType.LOAD)
.filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(LOAD_ID_7, null),
new IdentifierListFilterEquipmentAttributes(LOAD_ID_11, null),
new IdentifierListFilterEquipmentAttributes(LOAD_ID_12, null)))
.build();
return List.of(filter1, filter2, filter3);
}

@Override
protected void assertResultImpacts(List<AbstractBaseImpact> impacts) {
assertThat(impacts).containsExactly(createCollectionElementImpact(IdentifiableType.SUBSTATION));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,18 @@ public static Network createLoadNetwork(UUID uuid, NetworkFactory networkFactory
createSwitch(v32, "v32d1", "v32d1", SwitchKind.DISCONNECTOR, true, false, false, 0, 2);
createSwitch(v32, "v32d2", "v32d2", SwitchKind.DISCONNECTOR, true, false, false, 1, 3);

Substation s4 = createSubstation(network, "s4", "s4", Country.FR);
VoltageLevel v41 = createVoltageLevel(s4, "v41", "v41", TopologyKind.NODE_BREAKER, 450.0);
createBusBarSection(v41, "7.1", "7.1", 0);
createLoad(v41, "load11", "load11", 1, 42.1, 1.0, "cn0", 3, ConnectablePosition.Direction.TOP);
createSwitch(v41, "v41d1", "v41d1", SwitchKind.DISCONNECTOR, true, false, false, 0, 1);

Substation s5 = createSubstation(network, "s5", "s5", Country.FR);
VoltageLevel v51 = createVoltageLevel(s5, "v51", "v51", TopologyKind.NODE_BREAKER, 450.0);
createBusBarSection(v51, "8.1", "8.1", 0);
createLoad(v51, "load12", "load12", 1, 42.1, 1.0, "cn0", 3, ConnectablePosition.Direction.TOP);
createSwitch(v51, "v51d1", "v51d1", SwitchKind.DISCONNECTOR, true, false, false, 0, 1);

network.getVariantManager().setWorkingVariant(VariantManagerConstants.INITIAL_VARIANT_ID);
network.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, VARIANT_ID);

Expand Down