Skip to content

Commit

Permalink
Network action compatibility filter (#912)
Browse files Browse the repository at this point in the history
* Network actions compatibility filter

Signed-off-by: Thomas Bouquet <thomas.bouquet@rte-france.com>
  • Loading branch information
bqth29 authored Jun 17, 2024
1 parent cebab11 commit d7d3772
Show file tree
Hide file tree
Showing 18 changed files with 1,278 additions and 4 deletions.
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

0 comments on commit d7d3772

Please sign in to comment.