diff --git a/data/crac/crac-api/pom.xml b/data/crac/crac-api/pom.xml
index abe878fdff..f0aca66532 100644
--- a/data/crac/crac-api/pom.xml
+++ b/data/crac/crac-api/pom.xml
@@ -48,11 +48,5 @@
com.powsybl
powsybl-contingency-api
-
- org.mockito
- mockito-core
- 5.2.0
- test
-
diff --git a/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/InjectionSetpoint.java b/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/InjectionSetpoint.java
index fa46ad6da3..6a9f92e444 100644
--- a/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/InjectionSetpoint.java
+++ b/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/InjectionSetpoint.java
@@ -31,4 +31,12 @@ public interface InjectionSetpoint extends ElementaryAction {
* Get the unit of the injection setpoint
*/
Unit getUnit();
+
+ @Override
+ default boolean isCompatibleWith(ElementaryAction otherElementaryAction) {
+ if (otherElementaryAction instanceof InjectionSetpoint injectionSetpoint) {
+ return !getNetworkElement().equals(injectionSetpoint.getNetworkElement()) || getSetpoint() == injectionSetpoint.getSetpoint() && getUnit() == injectionSetpoint.getUnit();
+ }
+ return true;
+ }
}
diff --git a/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/NetworkAction.java b/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/NetworkAction.java
index 32ba162ebb..acf8456dd2 100644
--- a/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/NetworkAction.java
+++ b/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/NetworkAction.java
@@ -14,7 +14,7 @@
/**
* Remedial action interface specifying a direct action on the network.
- *
+ *
* The Network Action is completely defined by itself.
* It involves a Set of {@link ElementaryAction}.
* When the apply method is called, an action is triggered on each of these Elementary
@@ -35,6 +35,7 @@ public interface NetworkAction extends RemedialAction {
/**
* Apply the action on a given network.
+ *
* @param network the Network to apply the network action upon
* @return true if the network action was applied, false if not (eg if it was already applied)
*/
@@ -47,6 +48,7 @@ public interface NetworkAction extends RemedialAction {
/**
* States if the network action can be applied without infringing on another network action's scope.
+ *
* @param otherNetworkAction the other network action to check compatibility with
* @return true if both network actions can be applied without any conflictual behaviour
*/
diff --git a/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/PstSetpoint.java b/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/PstSetpoint.java
index fcbdd4c9f6..a158e52128 100644
--- a/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/PstSetpoint.java
+++ b/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/PstSetpoint.java
@@ -25,4 +25,12 @@ public interface PstSetpoint extends ElementaryAction {
* Get the Network Element associated to the elementary action
*/
NetworkElement getNetworkElement();
+
+ @Override
+ default boolean isCompatibleWith(ElementaryAction otherElementaryAction) {
+ if (otherElementaryAction instanceof PstSetpoint pstSetpoint) {
+ return !getNetworkElement().equals(pstSetpoint.getNetworkElement()) || getSetpoint() == pstSetpoint.getSetpoint();
+ }
+ return true;
+ }
}
diff --git a/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/SwitchPair.java b/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/SwitchPair.java
index e0715e7e82..baee9a27ee 100644
--- a/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/SwitchPair.java
+++ b/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/SwitchPair.java
@@ -19,10 +19,19 @@ public interface SwitchPair extends ElementaryAction {
/**
* Get the switch that should be opened by the elementary action
*/
- public NetworkElement getSwitchToOpen();
+ NetworkElement getSwitchToOpen();
/**
* Get the switch that should be closed by the elementary action
*/
- public NetworkElement getSwitchToClose();
+ NetworkElement getSwitchToClose();
+
+ @Override
+ default boolean isCompatibleWith(ElementaryAction otherElementaryAction) {
+ if (otherElementaryAction instanceof SwitchPair switchPair) {
+ return getSwitchToOpen().equals(switchPair.getSwitchToOpen()) && getSwitchToClose().equals(switchPair.getSwitchToClose())
+ || !getSwitchToOpen().equals(switchPair.getSwitchToOpen()) && !getSwitchToOpen().equals(switchPair.getSwitchToClose()) && !getSwitchToClose().equals(switchPair.getSwitchToClose()) && !getSwitchToClose().equals(switchPair.getSwitchToOpen());
+ }
+ return true;
+ }
}
diff --git a/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/TopologicalAction.java b/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/TopologicalAction.java
index b339c729f8..29729170c4 100644
--- a/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/TopologicalAction.java
+++ b/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/networkaction/TopologicalAction.java
@@ -25,4 +25,12 @@ public interface TopologicalAction extends ElementaryAction {
* Get the Network Element associated to the elementary action
*/
NetworkElement getNetworkElement();
+
+ @Override
+ default boolean isCompatibleWith(ElementaryAction otherElementaryAction) {
+ if (otherElementaryAction instanceof TopologicalAction topologicalAction) {
+ return !getNetworkElement().equals(topologicalAction.getNetworkElement()) || getActionType().equals(topologicalAction.getActionType());
+ }
+ return true;
+ }
}
diff --git a/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/ElementaryActionCompatibilityTest.java b/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/ElementaryActionCompatibilityTest.java
new file mode 100644
index 0000000000..ca7defe7ff
--- /dev/null
+++ b/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/ElementaryActionCompatibilityTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2024, RTE (http://www.rte-france.com)
+ * 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/.
+ */
+
+package com.powsybl.openrao.data.cracapi;
+
+import com.powsybl.openrao.commons.Unit;
+import com.powsybl.openrao.data.cracapi.networkaction.ActionType;
+import com.powsybl.openrao.data.cracapi.networkaction.ElementaryAction;
+import com.powsybl.openrao.data.cracapi.networkaction.InjectionSetpoint;
+import com.powsybl.openrao.data.cracapi.networkaction.PstSetpoint;
+import com.powsybl.openrao.data.cracapi.networkaction.SwitchPair;
+import com.powsybl.openrao.data.cracapi.networkaction.TopologicalAction;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * @author Thomas Bouquet {@literal }
+ */
+class ElementaryActionCompatibilityTest {
+ private final NetworkElement switchFr = NetworkActionUtils.createNetworkElement("switch-fr");
+ private final NetworkElement switchBe = NetworkActionUtils.createNetworkElement("switch-be");
+ private final NetworkElement pstFr = NetworkActionUtils.createNetworkElement("pst-fr");
+ private final NetworkElement pstBe = NetworkActionUtils.createNetworkElement("pst-be");
+ private final NetworkElement generatorFr = NetworkActionUtils.createNetworkElement("generator-fr");
+ private final NetworkElement generatorBe = NetworkActionUtils.createNetworkElement("generator-be");
+ private final TopologicalAction openSwitchFr = NetworkActionUtils.createTopologyAction(switchFr, ActionType.OPEN);
+ private final TopologicalAction closeSwitchFr = NetworkActionUtils.createTopologyAction(switchFr, ActionType.CLOSE);
+ private final TopologicalAction openSwitchBe = NetworkActionUtils.createTopologyAction(switchBe, ActionType.OPEN);
+ private final TopologicalAction closeSwitchBe = NetworkActionUtils.createTopologyAction(switchBe, ActionType.CLOSE);
+ private final SwitchPair openSwitchFrCloseSwitchBe = NetworkActionUtils.createSwitchPair(switchFr, switchBe);
+ private final SwitchPair openSwitchBeCloseSwitchFr = NetworkActionUtils.createSwitchPair(switchBe, switchFr);
+ private final PstSetpoint pstFr0 = NetworkActionUtils.createPstSetpoint(pstFr, 0);
+ private final PstSetpoint pstFr5 = NetworkActionUtils.createPstSetpoint(pstFr, 5);
+ private final PstSetpoint pstBe0 = NetworkActionUtils.createPstSetpoint(pstBe, 0);
+ private final PstSetpoint pstBeMinus5 = NetworkActionUtils.createPstSetpoint(pstBe, -5);
+ private final InjectionSetpoint generatorFr0Mw = NetworkActionUtils.createInjectionSetpoint(generatorFr, 0d, Unit.MEGAWATT);
+ private final InjectionSetpoint generatorFr100Mw = NetworkActionUtils.createInjectionSetpoint(generatorFr, 100d, Unit.MEGAWATT);
+ private final InjectionSetpoint generatorFr0A = NetworkActionUtils.createInjectionSetpoint(generatorFr, 0d, Unit.AMPERE);
+ private final InjectionSetpoint generatorFr1000A = NetworkActionUtils.createInjectionSetpoint(generatorFr, 1000d, Unit.AMPERE);
+ private final InjectionSetpoint generatorBe0Mw = NetworkActionUtils.createInjectionSetpoint(generatorBe, 0d, Unit.MEGAWATT);
+ private final InjectionSetpoint generatorBe100Mw = NetworkActionUtils.createInjectionSetpoint(generatorBe, 100d, Unit.MEGAWATT);
+ private final InjectionSetpoint generatorBe0A = NetworkActionUtils.createInjectionSetpoint(generatorBe, 0d, Unit.AMPERE);
+ private final InjectionSetpoint generatorBe1000A = NetworkActionUtils.createInjectionSetpoint(generatorBe, 1000d, Unit.AMPERE);
+ private final List elementaryActions = gatherElementaryActions();
+
+ @Test
+ void testElementaryActionsCompatibility() {
+ assertIncompatibility(openSwitchFr, closeSwitchFr);
+ assertIncompatibility(closeSwitchFr, openSwitchFr);
+ assertIncompatibility(openSwitchBe, closeSwitchBe);
+ assertIncompatibility(closeSwitchBe, openSwitchBe);
+ assertIncompatibility(openSwitchFrCloseSwitchBe, openSwitchBeCloseSwitchFr);
+ assertIncompatibility(openSwitchBeCloseSwitchFr, openSwitchFrCloseSwitchBe);
+ assertIncompatibility(pstFr0, pstFr5);
+ assertIncompatibility(pstFr5, pstFr0);
+ assertIncompatibility(pstBe0, pstBeMinus5);
+ assertIncompatibility(pstBeMinus5, pstBe0);
+ assertIncompatibility(generatorFr0Mw, generatorFr100Mw, generatorFr0A, generatorFr1000A);
+ assertIncompatibility(generatorFr100Mw, generatorFr0Mw, generatorFr0A, generatorFr1000A);
+ assertIncompatibility(generatorFr0A, generatorFr100Mw, generatorFr0Mw, generatorFr1000A);
+ assertIncompatibility(generatorFr1000A, generatorFr0Mw, generatorFr100Mw, generatorFr0A);
+ assertIncompatibility(generatorBe0Mw, generatorBe100Mw, generatorBe0A, generatorBe1000A);
+ assertIncompatibility(generatorBe100Mw, generatorBe0Mw, generatorBe0A, generatorBe1000A);
+ assertIncompatibility(generatorBe0A, generatorBe0Mw, generatorBe100Mw, generatorBe1000A);
+ assertIncompatibility(generatorBe1000A, generatorBe0Mw, generatorBe100Mw, generatorBe0A);
+ }
+
+ private List gatherElementaryActions() {
+ List elementaryActions = new ArrayList<>();
+ elementaryActions.add(openSwitchFr);
+ elementaryActions.add(closeSwitchFr);
+ elementaryActions.add(openSwitchBe);
+ elementaryActions.add(closeSwitchBe);
+ elementaryActions.add(openSwitchFrCloseSwitchBe);
+ elementaryActions.add(openSwitchBeCloseSwitchFr);
+ elementaryActions.add(pstFr0);
+ elementaryActions.add(pstFr5);
+ elementaryActions.add(pstBe0);
+ elementaryActions.add(pstBeMinus5);
+ elementaryActions.add(generatorFr0Mw);
+ elementaryActions.add(generatorFr100Mw);
+ elementaryActions.add(generatorFr0A);
+ elementaryActions.add(generatorFr1000A);
+ elementaryActions.add(generatorBe0Mw);
+ elementaryActions.add(generatorBe100Mw);
+ elementaryActions.add(generatorBe0A);
+ elementaryActions.add(generatorBe1000A);
+ return elementaryActions;
+ }
+
+ private void assertIncompatibility(ElementaryAction elementaryAction, ElementaryAction... incompatibleElementaryActions) {
+ List incompatibleElementaryActionsList = List.of(incompatibleElementaryActions);
+ for (ElementaryAction ea : elementaryActions) {
+ if (incompatibleElementaryActionsList.contains(ea)) {
+ assertFalse(elementaryAction.isCompatibleWith(ea));
+ } else {
+ assertTrue(elementaryAction.isCompatibleWith(ea));
+ }
+ }
+ }
+}
diff --git a/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/NetworkActionTest.java b/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/NetworkActionTest.java
index 5b5d16db59..e52f171f4b 100644
--- a/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/NetworkActionTest.java
+++ b/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/NetworkActionTest.java
@@ -1,33 +1,39 @@
+/*
+ * Copyright (c) 2024, RTE (http://www.rte-france.com)
+ * 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/.
+ */
+
package com.powsybl.openrao.data.cracapi;
+import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.cracapi.networkaction.ActionType;
+import com.powsybl.openrao.data.cracapi.networkaction.ElementaryAction;
import com.powsybl.openrao.data.cracapi.networkaction.InjectionSetpoint;
import com.powsybl.openrao.data.cracapi.networkaction.NetworkAction;
import com.powsybl.openrao.data.cracapi.networkaction.PstSetpoint;
import com.powsybl.openrao.data.cracapi.networkaction.SwitchPair;
import com.powsybl.openrao.data.cracapi.networkaction.TopologicalAction;
import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
+import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
+/**
+ * @author Thomas Bouquet {@literal }
+ */
class NetworkActionTest {
@Test
void compatibility() {
NetworkAction hvdcFrEs200Mw = mockHvdcAction(-200d);
NetworkAction hvdcEsFr200Mw = mockHvdcAction(200d);
- NetworkAction alignedPsts = Mockito.mock(NetworkAction.class);
- PstSetpoint pstSetpoint1 = mockPstSetpoint("pst-fr-1", 4);
- PstSetpoint pstSetpoint2 = mockPstSetpoint("pst-fr-2", 4);
- PstSetpoint pstSetpoint3 = mockPstSetpoint("pst-fr-3", 4);
- Mockito.when(alignedPsts.getElementaryActions()).thenReturn(Set.of(pstSetpoint1, pstSetpoint2, pstSetpoint3));
- NetworkAction switchPairAndPst = Mockito.mock(NetworkAction.class);
- PstSetpoint pstSetpoint4 = mockPstSetpoint("pst-fr-2", -2);
- SwitchPair switchPair = mockSwitchPair();
- Mockito.when(switchPairAndPst.getElementaryActions()).thenReturn(Set.of(pstSetpoint4, switchPair));
+ NetworkAction alignedPsts = mockNetworkAction(mockPstSetpoint("pst-fr-1", 4), mockPstSetpoint("pst-fr-2", 4), mockPstSetpoint("pst-fr-3", 4));
+ NetworkAction switchPairAndPst = mockNetworkAction(mockPstSetpoint("pst-fr-2", -2), mockSwitchPair());
assertTrue(hvdcFrEs200Mw.isCompatibleWith(hvdcFrEs200Mw));
assertFalse(hvdcFrEs200Mw.isCompatibleWith(hvdcEsFr200Mw));
@@ -38,58 +44,30 @@ void compatibility() {
assertTrue(hvdcEsFr200Mw.isCompatibleWith(switchPairAndPst));
assertTrue(alignedPsts.isCompatibleWith(alignedPsts));
assertFalse(alignedPsts.isCompatibleWith(switchPairAndPst));
- assertFalse(switchPairAndPst.isCompatibleWith(switchPairAndPst));
+ assertTrue(switchPairAndPst.isCompatibleWith(switchPairAndPst));
}
private NetworkAction mockHvdcAction(double setpoint) {
- NetworkAction hvdcAction = Mockito.mock(NetworkAction.class);
- TopologicalAction topologicalAction1 = mockTopologicalAction("switch-fr");
- TopologicalAction topologicalAction2 = mockTopologicalAction("switch-es");
- InjectionSetpoint generatorAction11 = mockInjectionSetpoint("generator-fr-1", setpoint / 2d);
- InjectionSetpoint generatorAction12 = mockInjectionSetpoint("generator-fr-2", setpoint / 2d);
- InjectionSetpoint generatorAction21 = mockInjectionSetpoint("generator-es-1", -setpoint / 2d);
- InjectionSetpoint generatorAction22 = mockInjectionSetpoint("generator-es-2", -setpoint / 2d);
- Mockito.when(hvdcAction.getElementaryActions()).thenReturn(Set.of(topologicalAction1, topologicalAction2, generatorAction11, generatorAction12, generatorAction21, generatorAction22));
- Mockito.when(hvdcAction.isCompatibleWith(Mockito.any())).thenCallRealMethod();
- return hvdcAction;
+ return new NetworkActionUtils.NetworkActionImplTest(Set.of(mockTopologicalAction("switch-fr"), mockTopologicalAction("switch-es"), mockInjectionSetpoint("generator-fr-1", setpoint / 2d), mockInjectionSetpoint("generator-fr-2", setpoint / 2d), mockInjectionSetpoint("generator-es-1", -setpoint / 2d), mockInjectionSetpoint("generator-es-2", -setpoint / 2d)));
+ }
+
+ private NetworkAction mockNetworkAction(ElementaryAction... elementaryActions) {
+ return new NetworkActionUtils.NetworkActionImplTest(new HashSet<>(List.of(elementaryActions)));
}
private TopologicalAction mockTopologicalAction(String switchId) {
- TopologicalAction topologicalAction = Mockito.mock(TopologicalAction.class);
- NetworkElement networkElement = mockNetworkElement(switchId);
- Mockito.when(topologicalAction.getNetworkElement()).thenReturn(networkElement);
- Mockito.when(topologicalAction.getActionType()).thenReturn(ActionType.OPEN);
- return topologicalAction;
+ return new NetworkActionUtils.TopologicalActionImplTest(NetworkActionUtils.createNetworkElement(switchId), ActionType.OPEN);
}
private InjectionSetpoint mockInjectionSetpoint(String networkElementId, double setpoint) {
- InjectionSetpoint injectionSetpoint = Mockito.mock(InjectionSetpoint.class);
- NetworkElement networkElement = mockNetworkElement(networkElementId);
- Mockito.when(injectionSetpoint.getSetpoint()).thenReturn(setpoint);
- Mockito.when(injectionSetpoint.getNetworkElement()).thenReturn(networkElement);
- return injectionSetpoint;
+ return new NetworkActionUtils.InjectionSetpointImplTest(NetworkActionUtils.createNetworkElement(networkElementId), setpoint, Unit.MEGAWATT);
}
private PstSetpoint mockPstSetpoint(String pstId, int setpoint) {
- PstSetpoint pstSetpoint = Mockito.mock(PstSetpoint.class);
- NetworkElement networkElement = mockNetworkElement(pstId);
- Mockito.when(pstSetpoint.getSetpoint()).thenReturn(setpoint);
- Mockito.when(pstSetpoint.getNetworkElement()).thenReturn(networkElement);
- return pstSetpoint;
+ return new NetworkActionUtils.PstSetpointImplTest(NetworkActionUtils.createNetworkElement(pstId), setpoint);
}
private SwitchPair mockSwitchPair() {
- SwitchPair switchPair = Mockito.mock(SwitchPair.class);
- NetworkElement switchToOpen = mockNetworkElement("switch-fr");
- NetworkElement switchToClose = mockNetworkElement("switch-es");
- Mockito.when(switchPair.getSwitchToOpen()).thenReturn(switchToOpen);
- Mockito.when(switchPair.getSwitchToClose()).thenReturn(switchToClose);
- return switchPair;
- }
-
- private NetworkElement mockNetworkElement(String networkElementId) {
- NetworkElement networkElement = Mockito.mock(NetworkElement.class);
- Mockito.when(networkElement.getId()).thenReturn(networkElementId);
- return networkElement;
+ return new NetworkActionUtils.SwitchPairImplTest(NetworkActionUtils.createNetworkElement("switch-fr"), NetworkActionUtils.createNetworkElement("switch-es"));
}
}
diff --git a/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/NetworkActionUtils.java b/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/NetworkActionUtils.java
new file mode 100644
index 0000000000..1c60e23bbc
--- /dev/null
+++ b/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/NetworkActionUtils.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2024, RTE (http://www.rte-france.com)
+ * 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/.
+ */
+
+package com.powsybl.openrao.data.cracapi;
+
+import com.powsybl.commons.extensions.Extension;
+import com.powsybl.iidm.network.Country;
+import com.powsybl.iidm.network.Network;
+import com.powsybl.openrao.commons.Unit;
+import com.powsybl.openrao.data.cracapi.cnec.FlowCnec;
+import com.powsybl.openrao.data.cracapi.networkaction.ActionType;
+import com.powsybl.openrao.data.cracapi.networkaction.ElementaryAction;
+import com.powsybl.openrao.data.cracapi.networkaction.InjectionSetpoint;
+import com.powsybl.openrao.data.cracapi.networkaction.NetworkAction;
+import com.powsybl.openrao.data.cracapi.networkaction.PstSetpoint;
+import com.powsybl.openrao.data.cracapi.networkaction.SwitchPair;
+import com.powsybl.openrao.data.cracapi.networkaction.TopologicalAction;
+import com.powsybl.openrao.data.cracapi.usagerule.OnContingencyStateAdderToRemedialAction;
+import com.powsybl.openrao.data.cracapi.usagerule.UsageMethod;
+import com.powsybl.openrao.data.cracapi.usagerule.UsageRule;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Thomas Bouquet {@literal }
+ */
+public final class NetworkActionUtils {
+
+ private NetworkActionUtils() {
+ }
+
+ public static class TopologicalActionImplTest implements TopologicalAction {
+
+ private final NetworkElement networkElement;
+ private final ActionType actionType;
+
+ public TopologicalActionImplTest(NetworkElement networkElement, ActionType actionType) {
+ this.networkElement = networkElement;
+ this.actionType = actionType;
+ }
+
+ @Override
+ public boolean hasImpactOnNetwork(Network network) {
+ return false;
+ }
+
+ @Override
+ public boolean canBeApplied(Network network) {
+ return false;
+ }
+
+ @Override
+ public void apply(Network network) {
+
+ }
+
+ @Override
+ public Set getNetworkElements() {
+ return null;
+ }
+
+ @Override
+ public ActionType getActionType() {
+ return actionType;
+ }
+
+ @Override
+ public NetworkElement getNetworkElement() {
+ return networkElement;
+ }
+ }
+
+ public static class InjectionSetpointImplTest implements InjectionSetpoint {
+
+ private final NetworkElement networkElement;
+ private final double setpoint;
+ private final Unit unit;
+
+ public InjectionSetpointImplTest(NetworkElement networkElement, double setpoint, Unit unit) {
+ this.networkElement = networkElement;
+ this.setpoint = setpoint;
+ this.unit = unit;
+ }
+
+ @Override
+ public boolean hasImpactOnNetwork(Network network) {
+ return false;
+ }
+
+ @Override
+ public boolean canBeApplied(Network network) {
+ return false;
+ }
+
+ @Override
+ public void apply(Network network) {
+
+ }
+
+ @Override
+ public Set getNetworkElements() {
+ return null;
+ }
+
+ @Override
+ public double getSetpoint() {
+ return setpoint;
+ }
+
+ @Override
+ public NetworkElement getNetworkElement() {
+ return networkElement;
+ }
+
+ @Override
+ public Unit getUnit() {
+ return unit;
+ }
+ }
+
+ public static class SwitchPairImplTest implements SwitchPair {
+
+ private final NetworkElement switchToOpen;
+ private final NetworkElement switchToClose;
+
+ public SwitchPairImplTest(NetworkElement switchToOpen, NetworkElement switchToClose) {
+ this.switchToOpen = switchToOpen;
+ this.switchToClose = switchToClose;
+ }
+
+ @Override
+ public boolean hasImpactOnNetwork(Network network) {
+ return false;
+ }
+
+ @Override
+ public boolean canBeApplied(Network network) {
+ return false;
+ }
+
+ @Override
+ public void apply(Network network) {
+
+ }
+
+ @Override
+ public Set getNetworkElements() {
+ return null;
+ }
+
+ @Override
+ public NetworkElement getSwitchToOpen() {
+ return switchToOpen;
+ }
+
+ @Override
+ public NetworkElement getSwitchToClose() {
+ return switchToClose;
+ }
+ }
+
+ public static class PstSetpointImplTest implements PstSetpoint {
+
+ private final NetworkElement networkElement;
+ private final int setpoint;
+
+ public PstSetpointImplTest(NetworkElement networkElement, int setpoint) {
+ this.networkElement = networkElement;
+ this.setpoint = setpoint;
+ }
+
+ @Override
+ public boolean hasImpactOnNetwork(Network network) {
+ return false;
+ }
+
+ @Override
+ public boolean canBeApplied(Network network) {
+ return false;
+ }
+
+ @Override
+ public void apply(Network network) {
+
+ }
+
+ @Override
+ public Set getNetworkElements() {
+ return null;
+ }
+
+ @Override
+ public int getSetpoint() {
+ return setpoint;
+ }
+
+ @Override
+ public NetworkElement getNetworkElement() {
+ return networkElement;
+ }
+ }
+
+ public static class NetworkActionImplTest implements NetworkAction {
+
+ private final Set elementaryActions;
+
+ public NetworkActionImplTest(Set elementaryActions) {
+ this.elementaryActions = new HashSet<>(elementaryActions);
+ }
+
+ @Override
+ public String getId() {
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return null;
+ }
+
+ @Override
+ public String getOperator() {
+ return null;
+ }
+
+ @Override
+ public Set getUsageRules() {
+ return null;
+ }
+
+ @Override
+ public UsageMethod getUsageMethod(State state) {
+ return null;
+ }
+
+ @Override
+ public Optional getSpeed() {
+ return Optional.empty();
+ }
+
+ @Override
+ public Set getFlowCnecsConstrainingUsageRules(Set perimeterCnecs, Network network, State optimizedState) {
+ return null;
+ }
+
+ @Override
+ public Set getFlowCnecsConstrainingForOneUsageRule(UsageRule usageRule, Set perimeterCnecs, Network network) {
+ return null;
+ }
+
+ @Override
+ public Set getNetworkElements() {
+ return null;
+ }
+
+ @Override
+ public OnContingencyStateAdderToRemedialAction newOnStateUsageRule() {
+ return null;
+ }
+
+ @Override
+ public boolean hasImpactOnNetwork(Network network) {
+ return false;
+ }
+
+ @Override
+ public boolean apply(Network network) {
+ return false;
+ }
+
+ @Override
+ public Set getElementaryActions() {
+ return elementaryActions;
+ }
+
+ @Override
+ public > void addExtension(Class super E> aClass, E e) {
+
+ }
+
+ @Override
+ public > E getExtension(Class super E> aClass) {
+ return null;
+ }
+
+ @Override
+ public > E getExtensionByName(String s) {
+ return null;
+ }
+
+ @Override
+ public > boolean removeExtension(Class aClass) {
+ return false;
+ }
+
+ @Override
+ public > Collection getExtensions() {
+ return null;
+ }
+ }
+
+ public static class NetworkElementImplTest implements NetworkElement {
+
+ private final String id;
+
+ public NetworkElementImplTest(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public String getName() {
+ return null;
+ }
+
+ @Override
+ public Set> getLocation(Network network) {
+ return null;
+ }
+
+ @Override
+ public > void addExtension(Class super E> aClass, E e) {
+
+ }
+
+ @Override
+ public > E getExtension(Class super E> aClass) {
+ return null;
+ }
+
+ @Override
+ public > E getExtensionByName(String s) {
+ return null;
+ }
+
+ @Override
+ public > boolean removeExtension(Class aClass) {
+ return false;
+ }
+
+ @Override
+ public > Collection getExtensions() {
+ return null;
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object instanceof NetworkElement networkElement) {
+ return getId().equals(networkElement.getId());
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+ }
+
+ public static NetworkElement createNetworkElement(String networkElementId) {
+ return new NetworkElementImplTest(networkElementId);
+ }
+
+ public static TopologicalAction createTopologyAction(NetworkElement networkElement, ActionType actionType) {
+ return new TopologicalActionImplTest(networkElement, actionType);
+ }
+
+ public static SwitchPair createSwitchPair(NetworkElement switchToOpen, NetworkElement switchToClose) {
+ return new SwitchPairImplTest(switchToOpen, switchToClose);
+ }
+
+ public static PstSetpoint createPstSetpoint(NetworkElement pst, int setpoint) {
+ return new PstSetpointImplTest(pst, setpoint);
+ }
+
+ public static InjectionSetpoint createInjectionSetpoint(NetworkElement networkElement, double setpoint, Unit unit) {
+ return new InjectionSetpointImplTest(networkElement, setpoint, unit);
+ }
+}
diff --git a/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/InjectionSetpointImpl.java b/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/InjectionSetpointImpl.java
index cab6b03326..8815c44827 100644
--- a/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/InjectionSetpointImpl.java
+++ b/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/InjectionSetpointImpl.java
@@ -8,7 +8,6 @@
package com.powsybl.openrao.data.cracimpl;
import com.powsybl.openrao.commons.Unit;
-import com.powsybl.openrao.data.cracapi.networkaction.ElementaryAction;
import com.powsybl.openrao.data.cracapi.networkaction.InjectionSetpoint;
import com.powsybl.openrao.data.cracapi.NetworkElement;
import com.powsybl.iidm.network.*;
@@ -96,14 +95,6 @@ public Set getNetworkElements() {
return Collections.singleton(networkElement);
}
- @Override
- public boolean isCompatibleWith(ElementaryAction otherElementaryAction) {
- if (otherElementaryAction instanceof InjectionSetpoint injectionSetpoint) {
- return !networkElement.equals(injectionSetpoint.getNetworkElement()) || setpoint == injectionSetpoint.getSetpoint();
- }
- return true;
- }
-
@Override
public boolean equals(Object o) {
if (this == o) {
diff --git a/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/PstSetpointImpl.java b/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/PstSetpointImpl.java
index 81989798b8..c6f544e56c 100644
--- a/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/PstSetpointImpl.java
+++ b/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/PstSetpointImpl.java
@@ -9,7 +9,6 @@
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.data.cracapi.NetworkElement;
-import com.powsybl.openrao.data.cracapi.networkaction.ElementaryAction;
import com.powsybl.openrao.data.cracapi.networkaction.PstSetpoint;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.PhaseTapChanger;
@@ -99,14 +98,6 @@ public boolean canBeApplied(Network network) {
return true;
}
- @Override
- public boolean isCompatibleWith(ElementaryAction otherElementaryAction) {
- if (otherElementaryAction instanceof PstSetpoint pstSetpoint) {
- return !networkElement.equals(pstSetpoint.getNetworkElement()) || setpoint == pstSetpoint.getSetpoint();
- }
- return true;
- }
-
@Override
public int hashCode() {
return networkElement.hashCode() + 7 * Double.valueOf(setpoint).hashCode();
diff --git a/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/SwitchPairImpl.java b/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/SwitchPairImpl.java
index 91f996f671..05f36b99b9 100644
--- a/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/SwitchPairImpl.java
+++ b/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/SwitchPairImpl.java
@@ -8,7 +8,6 @@
package com.powsybl.openrao.data.cracimpl;
import com.powsybl.openrao.data.cracapi.NetworkElement;
-import com.powsybl.openrao.data.cracapi.networkaction.ElementaryAction;
import com.powsybl.openrao.data.cracapi.networkaction.SwitchPair;
import com.powsybl.iidm.network.Network;
@@ -58,14 +57,6 @@ public NetworkElement getSwitchToClose() {
return switchToClose;
}
- @Override
- public boolean isCompatibleWith(ElementaryAction otherElementaryAction) {
- if (otherElementaryAction instanceof SwitchPair switchPair) {
- return !switchToOpen.equals(switchPair.getSwitchToOpen()) && !switchToOpen.equals(switchPair.getSwitchToClose()) && !switchToClose.equals(switchPair.getSwitchToClose()) && !switchToClose.equals(switchPair.getSwitchToOpen());
- }
- return true;
- }
-
@Override
public boolean equals(Object o) {
if (this == o) {
diff --git a/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/TopologicalActionImpl.java b/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/TopologicalActionImpl.java
index da3b1b2bb9..781ec550a8 100644
--- a/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/TopologicalActionImpl.java
+++ b/data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/TopologicalActionImpl.java
@@ -9,7 +9,6 @@
import com.powsybl.openrao.data.cracapi.networkaction.ActionType;
import com.powsybl.openrao.data.cracapi.NetworkElement;
-import com.powsybl.openrao.data.cracapi.networkaction.ElementaryAction;
import com.powsybl.openrao.data.cracapi.networkaction.TopologicalAction;
import com.powsybl.iidm.network.Branch;
import com.powsybl.iidm.network.Identifiable;
@@ -105,14 +104,6 @@ public Set getNetworkElements() {
return Collections.singleton(networkElement);
}
- @Override
- public boolean isCompatibleWith(ElementaryAction otherElementaryAction) {
- if (otherElementaryAction instanceof TopologicalAction topologicalAction) {
- return !networkElement.equals(topologicalAction.getNetworkElement()) || actionType.equals(topologicalAction.getActionType());
- }
- return true;
- }
-
@Override
public int hashCode() {
return networkElement.hashCode() + 37 * actionType.hashCode();
diff --git a/data/crac/crac-impl/src/test/java/com/powsybl/openrao/data/cracimpl/NetworkActionImplTest.java b/data/crac/crac-impl/src/test/java/com/powsybl/openrao/data/cracimpl/NetworkActionImplTest.java
index 8a612c4666..c7e5584d9e 100644
--- a/data/crac/crac-impl/src/test/java/com/powsybl/openrao/data/cracimpl/NetworkActionImplTest.java
+++ b/data/crac/crac-impl/src/test/java/com/powsybl/openrao/data/cracimpl/NetworkActionImplTest.java
@@ -137,6 +137,6 @@ void compatibility() {
assertTrue(crac.getNetworkAction("hvdc-es-fr-200-mw").isCompatibleWith(crac.getNetworkAction("switch-pair-and-pst")));
assertTrue(crac.getNetworkAction("aligned-psts").isCompatibleWith(crac.getNetworkAction("aligned-psts")));
assertFalse(crac.getNetworkAction("aligned-psts").isCompatibleWith(crac.getNetworkAction("switch-pair-and-pst")));
- assertFalse(crac.getNetworkAction("switch-pair-and-pst").isCompatibleWith(crac.getNetworkAction("switch-pair-and-pst")));
+ assertTrue(crac.getNetworkAction("switch-pair-and-pst").isCompatibleWith(crac.getNetworkAction("switch-pair-and-pst")));
}
}
diff --git a/data/crac/crac-impl/src/test/java/com/powsybl/openrao/data/cracimpl/SwitchPairImplTest.java b/data/crac/crac-impl/src/test/java/com/powsybl/openrao/data/cracimpl/SwitchPairImplTest.java
index d8104f688b..54a23c751d 100644
--- a/data/crac/crac-impl/src/test/java/com/powsybl/openrao/data/cracimpl/SwitchPairImplTest.java
+++ b/data/crac/crac-impl/src/test/java/com/powsybl/openrao/data/cracimpl/SwitchPairImplTest.java
@@ -119,7 +119,7 @@ void compatibility() {
Crac crac = createCracWithRemedialActions();
SwitchPair switchPair = (SwitchPair) crac.getNetworkAction("open-switch-1-close-switch-2").getElementaryActions().iterator().next();
- assertFalse(switchPair.isCompatibleWith(switchPair));
+ assertTrue(switchPair.isCompatibleWith(switchPair));
assertTrue(switchPair.isCompatibleWith(crac.getNetworkAction("open-switch-2").getElementaryActions().iterator().next()));
assertTrue(switchPair.isCompatibleWith(crac.getNetworkAction("close-switch-1").getElementaryActions().iterator().next()));
assertTrue(switchPair.isCompatibleWith(crac.getNetworkAction("close-switch-2").getElementaryActions().iterator().next()));
@@ -134,7 +134,7 @@ void compatibility() {
assertTrue(switchPair.isCompatibleWith(crac.getNetworkAction("pst-2-tap-3").getElementaryActions().iterator().next()));
assertTrue(switchPair.isCompatibleWith(crac.getNetworkAction("pst-2-tap-8").getElementaryActions().iterator().next()));
- assertFalse(switchPair.isCompatibleWith(crac.getNetworkAction("open-switch-1-close-switch-2").getElementaryActions().iterator().next()));
+ assertTrue(switchPair.isCompatibleWith(crac.getNetworkAction("open-switch-1-close-switch-2").getElementaryActions().iterator().next()));
assertFalse(switchPair.isCompatibleWith(crac.getNetworkAction("open-switch-2-close-switch-1").getElementaryActions().iterator().next()));
assertTrue(switchPair.isCompatibleWith(crac.getNetworkAction("open-switch-3-close-switch-4").getElementaryActions().iterator().next()));
assertFalse(switchPair.isCompatibleWith(crac.getNetworkAction("open-switch-1-close-switch-3").getElementaryActions().iterator().next()));
diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/searchtree/algorithms/ElementaryActionsCompatibilityFilter.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/searchtree/algorithms/ElementaryActionsCompatibilityFilter.java
new file mode 100644
index 0000000000..7869d2e930
--- /dev/null
+++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/searchtree/algorithms/ElementaryActionsCompatibilityFilter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, RTE (http://www.rte-france.com)
+ * 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/.
+ */
+
+package com.powsybl.openrao.searchtreerao.searchtree.algorithms;
+
+import com.powsybl.openrao.searchtreerao.commons.NetworkActionCombination;
+import com.powsybl.openrao.searchtreerao.result.api.OptimizationResult;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author Thomas Bouquet {@literal }
+ */
+public class ElementaryActionsCompatibilityFilter implements NetworkActionCombinationFilter {
+ @Override
+ public Set filter(Set naCombinations, OptimizationResult optimizationResult) {
+ return naCombinations.stream()
+ .filter(naCombination -> naCombination.getNetworkActionSet().stream().allMatch(networkAction -> optimizationResult.getActivatedNetworkActions().stream().allMatch(networkAction::isCompatibleWith)))
+ .collect(Collectors.toSet());
+ }
+}
diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/searchtree/algorithms/SearchTreeBloomer.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/searchtree/algorithms/SearchTreeBloomer.java
index 07d0f4a050..9259a1a8df 100644
--- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/searchtree/algorithms/SearchTreeBloomer.java
+++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/searchtree/algorithms/SearchTreeBloomer.java
@@ -38,7 +38,8 @@ public SearchTreeBloomer(SearchTreeInput input, SearchTreeParameters parameters)
new MaximumNumberOfRemedialActionsFilter(raUsageLimits.getMaxRa()),
new MaximumNumberOfRemedialActionPerTsoFilter(raUsageLimits.getMaxTopoPerTso(), raUsageLimits.getMaxRaPerTso()),
new MaximumNumberOfTsosFilter(raUsageLimits.getMaxTso()),
- new FarFromMostLimitingElementFilter(input.getNetwork(), parameters.getNetworkActionParameters().skipNetworkActionFarFromMostLimitingElements(), parameters.getNetworkActionParameters().getMaxNumberOfBoundariesForSkippingNetworkActions())
+ new FarFromMostLimitingElementFilter(input.getNetwork(), parameters.getNetworkActionParameters().skipNetworkActionFarFromMostLimitingElements(), parameters.getNetworkActionParameters().getMaxNumberOfBoundariesForSkippingNetworkActions()),
+ new ElementaryActionsCompatibilityFilter()
);
this.input = input;
this.parameters = parameters;
diff --git a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/searchtree/algorithms/ElementaryActionsCompatibilityFilterTest.java b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/searchtree/algorithms/ElementaryActionsCompatibilityFilterTest.java
new file mode 100644
index 0000000000..121bc283f6
--- /dev/null
+++ b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/searchtree/algorithms/ElementaryActionsCompatibilityFilterTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2024, RTE (http://www.rte-france.com)
+ * 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/.
+ */
+
+package com.powsybl.openrao.searchtreerao.searchtree.algorithms;
+
+import com.powsybl.openrao.commons.Unit;
+import com.powsybl.openrao.data.cracapi.Crac;
+import com.powsybl.openrao.data.cracapi.InstantKind;
+import com.powsybl.openrao.data.cracapi.networkaction.ActionType;
+import com.powsybl.openrao.data.cracapi.networkaction.NetworkAction;
+import com.powsybl.openrao.data.cracapi.usagerule.UsageMethod;
+import com.powsybl.openrao.data.cracimpl.CracImplFactory;
+import com.powsybl.openrao.searchtreerao.commons.NetworkActionCombination;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * @author Thomas Bouquet {@literal }
+ */
+class ElementaryActionsCompatibilityFilterTest {
+ @Test
+ void removeIncompatibleCombinations() {
+ Crac crac = new CracImplFactory().create("crac", "crac")
+ .newInstant("preventive", InstantKind.PREVENTIVE)
+ .newInstant("outage", InstantKind.OUTAGE)
+ .newInstant("auto", InstantKind.AUTO)
+ .newInstant("curative", InstantKind.CURATIVE);
+
+ NetworkAction appliedRemedialAction1 = crac.newNetworkAction()
+ .withId("applied-remedial-action-1")
+ .withOperator("FR")
+ .newTopologicalAction()
+ .withNetworkElement("switch-1")
+ .withActionType(ActionType.OPEN)
+ .add()
+ .newOnInstantUsageRule()
+ .withInstant("preventive")
+ .withUsageMethod(UsageMethod.AVAILABLE)
+ .add()
+ .add();
+
+ NetworkAction appliedRemedialAction2 = crac.newNetworkAction()
+ .withId("applied-remedial-action-2")
+ .withOperator("FR")
+ .newTopologicalAction()
+ .withNetworkElement("switch-2")
+ .withActionType(ActionType.CLOSE)
+ .add()
+ .newInjectionSetPoint()
+ .withNetworkElement("generator-1")
+ .withSetpoint(100d)
+ .withUnit(Unit.MEGAWATT)
+ .add()
+ .newOnInstantUsageRule()
+ .withInstant("preventive")
+ .withUsageMethod(UsageMethod.AVAILABLE)
+ .add()
+ .add();
+
+ NetworkAction availableRemedialAction1 = crac.newNetworkAction()
+ .withId("available-remedial-action-1")
+ .withOperator("FR")
+ .newTopologicalAction()
+ .withNetworkElement("switch-2")
+ .withActionType(ActionType.OPEN)
+ .add()
+ .newPstSetPoint()
+ .withNetworkElement("pst-1")
+ .withSetpoint(1)
+ .add()
+ .newOnInstantUsageRule()
+ .withInstant("preventive")
+ .withUsageMethod(UsageMethod.AVAILABLE)
+ .add()
+ .add();
+
+ NetworkAction availableRemedialAction2 = crac.newNetworkAction()
+ .withId("available-remedial-action-2")
+ .withOperator("FR")
+ .newInjectionSetPoint()
+ .withNetworkElement("generator-2")
+ .withSetpoint(75d)
+ .withUnit(Unit.MEGAWATT)
+ .add()
+ .newOnInstantUsageRule()
+ .withInstant("preventive")
+ .withUsageMethod(UsageMethod.AVAILABLE)
+ .add()
+ .add();
+
+ NetworkAction availableRemedialAction3 = crac.newNetworkAction()
+ .withId("available-remedial-action-3")
+ .withOperator("FR")
+ .newInjectionSetPoint()
+ .withNetworkElement("generator-1")
+ .withSetpoint(100d)
+ .withUnit(Unit.MEGAWATT)
+ .add()
+ .newTopologicalAction()
+ .withNetworkElement("switch-3")
+ .withActionType(ActionType.CLOSE)
+ .add()
+ .newOnInstantUsageRule()
+ .withInstant("preventive")
+ .withUsageMethod(UsageMethod.AVAILABLE)
+ .add()
+ .add();
+
+ NetworkAction availableRemedialAction4 = crac.newNetworkAction()
+ .withId("available-remedial-action-4")
+ .withOperator("FR")
+ .newSwitchPair()
+ .withSwitchToOpen("switch-2")
+ .withSwitchToClose("switch-1")
+ .add()
+ .newOnInstantUsageRule()
+ .withInstant("preventive")
+ .withUsageMethod(UsageMethod.AVAILABLE)
+ .add()
+ .add();
+
+ NetworkActionCombination networkActionCombination1 = new NetworkActionCombination(Set.of(availableRemedialAction1, availableRemedialAction2));
+ NetworkActionCombination networkActionCombination2 = new NetworkActionCombination(Set.of(availableRemedialAction3));
+ NetworkActionCombination networkActionCombination3 = new NetworkActionCombination(Set.of(availableRemedialAction4));
+ NetworkActionCombination networkActionCombination4 = new NetworkActionCombination(Set.of(availableRemedialAction2, availableRemedialAction3));
+
+ ElementaryActionsCompatibilityFilter naFilter = new ElementaryActionsCompatibilityFilter();
+ Set naCombinations = Set.of(networkActionCombination1, networkActionCombination2, networkActionCombination3, networkActionCombination4);
+
+ Leaf previousLeaf = Mockito.mock(Leaf.class);
+ Mockito.when(previousLeaf.getActivatedNetworkActions()).thenReturn(Set.of(appliedRemedialAction1, appliedRemedialAction2));
+
+ assertEquals(
+ Set.of(networkActionCombination2, networkActionCombination3, networkActionCombination4),
+ naFilter.filter(naCombinations, previousLeaf)
+ );
+ }
+}