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

Network action compatibility filter #912

Merged
merged 25 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
af13c6b
Network actions compatibility
bqth29 Feb 6, 2024
b6d536f
Move compatibility checker to RAO utils
bqth29 Mar 5, 2024
e468fd2
Merge branch 'main' into coreCSA/remedial_action_compatibility
bqth29 Mar 5, 2024
ccc0e5f
Merge branch 'main' into coreCSA/remedial_action_compatibility
bqth29 Mar 6, 2024
bef7b8f
Refactor by adding methods in respective APIs
bqth29 Mar 6, 2024
38e691f
Remove RA if equal to an already applied RA
bqth29 Mar 6, 2024
ca8e675
Remove checker and add method in bloomer directly
bqth29 Mar 6, 2024
67ca1d7
Declare function in interface
bqth29 Mar 6, 2024
bc23dd9
Simplify filter in bloomer
bqth29 Mar 6, 2024
9ab96c3
Merge branch 'main' into coreCSA/remedial_action_compatibility
pet-mit Mar 7, 2024
72f2dc0
Merge branch 'main' into coreCSA/remedial_action_compatibility
bqth29 Mar 25, 2024
db4b1fb
Merge branch 'main' into coreCSA/remedial_action_compatibility
bqth29 Mar 25, 2024
386a4a2
Change compatibility rule for switch pairs
bqth29 Mar 25, 2024
577f339
Merge branch 'main' into coreCSA/remedial_action_compatibility
bqth29 Apr 4, 2024
1439f7e
Merge branch 'main' into coreCSA/remedial_action_compatibility
bqth29 Apr 4, 2024
72c5a9f
Merge branch 'main' into coreCSA/remedial_action_compatibility
bqth29 Apr 4, 2024
15ece16
Merge branch 'main' into coreCSA/remedial_action_compatibility
bqth29 Apr 10, 2024
e443317
Merge branch 'main' into coreCSA/remedial_action_compatibility
bqth29 Apr 17, 2024
3b2a568
Merge branch 'main' into coreCSA/remedial_action_compatibility
bqth29 Apr 22, 2024
a82dcaf
Merge branch 'main' into coreCSA/remedial_action_compatibility
bqth29 Apr 24, 2024
55b777c
Duplicate isCompatibleWith tests in NetworkActionTest
bqth29 Apr 24, 2024
0d9bf83
Merge branch 'main' into coreCSA/remedial_action_compatibility
pet-mit May 6, 2024
584bf31
Merge branch 'coreCSA/remedial_action_compatibility' of https://githu…
bqth29 Jun 17, 2024
7a0cb1e
Merge branch 'main' into coreCSA/remedial_action_compatibility
bqth29 Jun 17, 2024
01a35b0
Update filter on EA + better tests coverage
bqth29 Jun 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,11 @@ public interface ElementaryAction {
* Get the Network Elements associated to the elementary action
*/
Set<NetworkElement> getNetworkElements();

/**
* States if the elementary action can be applied without infringing on elementary network action's scope.
* @param otherElementaryAction the other elementary action to check compatibility with
* @return true if both elementary actions can be applied without any conflictual behaviour
*/
boolean isCompatibleWith(ElementaryAction otherElementaryAction);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

/**
* Remedial action interface specifying a direct action on the network.
*
* <p>
* 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
Expand All @@ -35,6 +35,7 @@ public interface NetworkAction extends RemedialAction<NetworkAction> {

/**
* 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)
*/
Expand All @@ -44,4 +45,21 @@ public interface NetworkAction extends RemedialAction<NetworkAction> {
* Get the set of the elementary actions constituting then network action
*/
Set<ElementaryAction> getElementaryActions();

/**
* 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
*/
default boolean isCompatibleWith(NetworkAction otherNetworkAction) {
for (ElementaryAction elementaryAction1 : getElementaryActions()) {
for (ElementaryAction elementaryAction2 : otherNetworkAction.getElementaryActions()) {
if (!elementaryAction1.isCompatibleWith(elementaryAction2)) {
return false;
}
}
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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 <thomas.bouquet at rte-france.com>}
*/
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<ElementaryAction> 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<ElementaryAction> gatherElementaryActions() {
List<ElementaryAction> 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<ElementaryAction> incompatibleElementaryActionsList = List.of(incompatibleElementaryActions);
for (ElementaryAction ea : elementaryActions) {
if (incompatibleElementaryActionsList.contains(ea)) {
assertFalse(elementaryAction.isCompatibleWith(ea));
} else {
assertTrue(elementaryAction.isCompatibleWith(ea));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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 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 <thomas.bouquet at rte-france.com>}
*/
class NetworkActionTest {
@Test
void compatibility() {
NetworkAction hvdcFrEs200Mw = mockHvdcAction(-200d);
NetworkAction hvdcEsFr200Mw = mockHvdcAction(200d);
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));
assertTrue(hvdcFrEs200Mw.isCompatibleWith(alignedPsts));
assertTrue(hvdcFrEs200Mw.isCompatibleWith(switchPairAndPst));
assertTrue(hvdcEsFr200Mw.isCompatibleWith(hvdcEsFr200Mw));
assertTrue(hvdcEsFr200Mw.isCompatibleWith(alignedPsts));
assertTrue(hvdcEsFr200Mw.isCompatibleWith(switchPairAndPst));
assertTrue(alignedPsts.isCompatibleWith(alignedPsts));
assertFalse(alignedPsts.isCompatibleWith(switchPairAndPst));
assertTrue(switchPairAndPst.isCompatibleWith(switchPairAndPst));
}

private NetworkAction mockHvdcAction(double setpoint) {
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) {
return new NetworkActionUtils.TopologicalActionImplTest(NetworkActionUtils.createNetworkElement(switchId), ActionType.OPEN);
}

private InjectionSetpoint mockInjectionSetpoint(String networkElementId, double setpoint) {
return new NetworkActionUtils.InjectionSetpointImplTest(NetworkActionUtils.createNetworkElement(networkElementId), setpoint, Unit.MEGAWATT);
}

private PstSetpoint mockPstSetpoint(String pstId, int setpoint) {
return new NetworkActionUtils.PstSetpointImplTest(NetworkActionUtils.createNetworkElement(pstId), setpoint);
}

private SwitchPair mockSwitchPair() {
return new NetworkActionUtils.SwitchPairImplTest(NetworkActionUtils.createNetworkElement("switch-fr"), NetworkActionUtils.createNetworkElement("switch-es"));
}
}
Loading
Loading