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 aClass, E e) { + + } + + @Override + public > E getExtension(Class 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 aClass, E e) { + + } + + @Override + public > E getExtension(Class 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) + ); + } +}