Skip to content

Commit b1cbb14

Browse files
authored
Add RA usage limit on the number of applicable elementary actions per TSO (#1009)
* Create max-elementary-actions usage limit Signed-off-by: Thomas Bouquet <[email protected]> * Limit RA with elementary actions on topo only Signed-off-by: Thomas Bouquet <[email protected]> * Remove PSTs to apply topo - max elem. actions Signed-off-by: Thomas Bouquet <[email protected]> * Add CastorFullOptimization test Signed-off-by: Thomas Bouquet <[email protected]> * Update version of CRAC in test Signed-off-by: Thomas Bouquet <[email protected]> * Move test to cucumber Signed-off-by: Thomas Bouquet <[email protected]> * Test with PSTs Signed-off-by: Thomas Bouquet <[email protected]> * Update doc Signed-off-by: Thomas Bouquet <[email protected]> * Broken links in doc Signed-off-by: Thomas Bouquet <[email protected]> * Operational constrain + cucumber tests Signed-off-by: Thomas Bouquet <[email protected]> * Create separate US for cucumber tests Signed-off-by: Thomas Bouquet <[email protected]> * Create separate filter for constraint in bloomer Signed-off-by: Thomas Bouquet <[email protected]> * Fix tests Signed-off-by: Thomas Bouquet <[email protected]> * Add cumulative effect of max EA usage limit Signed-off-by: Thomas Bouquet <[email protected]> * Cucumber test: same PST used in preventive and curative Signed-off-by: Thomas Bouquet <[email protected]> * Cucumber test: multi-curative with mixed PSTs and topos Signed-off-by: Thomas Bouquet <[email protected]> * Refactor decrease max EA / TSO Signed-off-by: Thomas Bouquet <[email protected]> * Cucumber test: multiple TSOs with EA limit Signed-off-by: Thomas Bouquet <[email protected]> * Test Filler Signed-off-by: Thomas Bouquet <[email protected]> * Merge main Signed-off-by: Thomas Bouquet <[email protected]> * Move discrete PSTs check in RaoUtil Signed-off-by: Thomas Bouquet <[email protected]> * some fixes after review Signed-off-by: Thomas Bouquet <[email protected]> * Move Instant.compareTo to API for bug fix Signed-off-by: Thomas Bouquet <[email protected]> * resolve conflicts with main Signed-off-by: Thomas Bouquet <[email protected]> * Merge main Signed-off-by: Thomas Bouquet <[email protected]> * Merge main Signed-off-by: Thomas Bouquet <[email protected]> * Fix use of inifinity in LP Signed-off-by: Thomas Bouquet <[email protected]> --------- Signed-off-by: Thomas Bouquet <[email protected]>
1 parent dc31f03 commit b1cbb14

File tree

47 files changed

+2393
-123
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2393
-123
lines changed

data/crac-creation/crac-creation-util/src/main/java/com/powsybl/openrao/data/craccreation/util/RaUsageLimitsAdder.java

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public static void addRaUsageLimits(Crac crac, CracCreationParameters parameters
2727
.withMaxRaPerTso(raUsageLimits.getMaxRaPerTso())
2828
.withMaxPstPerTso(raUsageLimits.getMaxPstPerTso())
2929
.withMaxTopoPerTso(raUsageLimits.getMaxTopoPerTso())
30+
.withMaxElementaryActionPerTso(raUsageLimits.getMaxElementaryActionsPerTso())
3031
.add());
3132
}
3233
}

data/crac-io/crac-io-json/src/main/java/com/powsybl/openrao/data/craciojson/JsonSerializationConstants.java

+1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ private JsonSerializationConstants() {
152152
public static final String MAX_TOPO_PER_TSO = "max-topo-per-tso";
153153
public static final String MAX_PST_PER_TSO = "max-pst-per-tso";
154154
public static final String MAX_RA_PER_TSO = "max-ra-per-tso";
155+
public static final String MAX_ELEMENTARY_ACTIONS_PER_TSO = "max-elementary-actions-per-tso";
155156

156157
// units
157158
public static final String AMPERE_UNIT = "ampere";

data/crac-io/crac-io-json/src/main/java/com/powsybl/openrao/data/craciojson/deserializers/RaUsageLimitsDeserializer.java

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Map;
2020

2121
import static com.powsybl.openrao.data.craciojson.JsonSerializationConstants.INSTANT;
22+
import static com.powsybl.openrao.data.craciojson.JsonSerializationConstants.MAX_ELEMENTARY_ACTIONS_PER_TSO;
2223
import static com.powsybl.openrao.data.craciojson.JsonSerializationConstants.MAX_RA;
2324
import static com.powsybl.openrao.data.craciojson.JsonSerializationConstants.MAX_TSO;
2425
import static com.powsybl.openrao.data.craciojson.JsonSerializationConstants.MAX_TOPO_PER_TSO;
@@ -44,6 +45,7 @@ public static void deserialize(JsonParser jsonParser, Crac crac) throws IOExcept
4445
.withMaxRaPerTso(raUsageLimits.getMaxRaPerTso())
4546
.withMaxPstPerTso(raUsageLimits.getMaxPstPerTso())
4647
.withMaxTopoPerTso(raUsageLimits.getMaxTopoPerTso())
48+
.withMaxElementaryActionPerTso(raUsageLimits.getMaxElementaryActionsPerTso())
4749
.add();
4850
}
4951
}
@@ -91,6 +93,10 @@ public static Pair<String, RaUsageLimits> deserializeRaUsageLimits(JsonParser js
9193
jsonParser.nextToken();
9294
raUsageLimits.setMaxRaPerTso(readStringToPositiveIntMap(jsonParser));
9395
}
96+
case MAX_ELEMENTARY_ACTIONS_PER_TSO -> {
97+
jsonParser.nextToken();
98+
raUsageLimits.setMaxElementaryActionsPerTso(readStringToPositiveIntMap(jsonParser));
99+
}
94100
default ->
95101
throw new OpenRaoException(String.format("Cannot deserialize ra-usage-limits-per-instant parameters: unexpected field in %s (%s)", RA_USAGE_LIMITS_PER_INSTANT, jsonParser.getCurrentName()));
96102
}

data/crac-io/crac-io-json/src/main/java/com/powsybl/openrao/data/craciojson/serializers/CracSerializer.java

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ private void serializeRaUsageLimits(Crac crac, JsonGenerator gen) throws IOExcep
7575
gen.writeObjectField(MAX_TOPO_PER_TSO, new TreeMap<>(raUsageLimits.getMaxTopoPerTso()));
7676
gen.writeObjectField(MAX_PST_PER_TSO, new TreeMap<>(raUsageLimits.getMaxPstPerTso()));
7777
gen.writeObjectField(MAX_RA_PER_TSO, new TreeMap<>(raUsageLimits.getMaxRaPerTso()));
78+
gen.writeObjectField(MAX_ELEMENTARY_ACTIONS_PER_TSO, new TreeMap<>(raUsageLimits.getMaxElementaryActionsPerTso()));
7879
gen.writeEndObject();
7980
}
8081
gen.writeEndArray();

data/crac-io/crac-io-json/src/test/java/com/powsybl/openrao/data/craciojson/CracImportExportTest.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import org.mockito.Mockito;
3131

3232
import java.time.OffsetDateTime;
33-
import java.util.HashMap;
3433
import java.util.List;
3534
import java.util.Map;
3635
import java.util.stream.Collectors;
@@ -108,9 +107,10 @@ private void checkContent(Crac crac) {
108107
RaUsageLimits expectedUsageLimits = crac.getRaUsageLimits(curativeInstant);
109108
assertEquals(4, expectedUsageLimits.getMaxRa());
110109
assertEquals(2, expectedUsageLimits.getMaxTso());
111-
assertEquals(new HashMap<>(Map.of("FR", 12)), expectedUsageLimits.getMaxRaPerTso());
112-
assertEquals(new HashMap<>(Map.of("FR", 7)), expectedUsageLimits.getMaxPstPerTso());
113-
assertEquals(new HashMap<>(Map.of("FR", 5, "BE", 6)), expectedUsageLimits.getMaxTopoPerTso());
110+
assertEquals(Map.of("FR", 12), expectedUsageLimits.getMaxRaPerTso());
111+
assertEquals(Map.of("FR", 7), expectedUsageLimits.getMaxPstPerTso());
112+
assertEquals(Map.of("FR", 5, "BE", 6), expectedUsageLimits.getMaxTopoPerTso());
113+
assertEquals(Map.of("FR", 21), expectedUsageLimits.getMaxElementaryActionsPerTso());
114114
// check instant with no limits
115115
assertEquals(new RaUsageLimits(), crac.getRaUsageLimits(preventiveInstant));
116116

data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/RaUsageLimits.java

+10
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ public class RaUsageLimits {
2222
private static final Map<String, Integer> DEFAULT_MAX_TOPO_PER_TSO = new HashMap<>();
2323
private static final Map<String, Integer> DEFAULT_MAX_PST_PER_TSO = new HashMap<>();
2424
private static final Map<String, Integer> DEFAULT_MAX_RA_PER_TSO = new HashMap<>();
25+
private static final Map<String, Integer> DEFAULT_MAX_ELEMENTARY_ACTIONS_PER_TSO = new HashMap<>();
2526
private int maxRa = DEFAULT_MAX_RA;
2627
private int maxTso = DEFAULT_MAX_TSO;
2728
private final Set<String> maxTsoExclusion = new HashSet<>();
2829
private Map<String, Integer> maxTopoPerTso = DEFAULT_MAX_TOPO_PER_TSO;
2930
private Map<String, Integer> maxPstPerTso = DEFAULT_MAX_PST_PER_TSO;
3031
private Map<String, Integer> maxRaPerTso = DEFAULT_MAX_RA_PER_TSO;
32+
private Map<String, Integer> maxElementaryActionsPerTso = DEFAULT_MAX_ELEMENTARY_ACTIONS_PER_TSO;
3133

3234
public void setMaxRa(int maxRa) {
3335
if (maxRa < 0) {
@@ -77,6 +79,10 @@ public void setMaxRaPerTso(Map<String, Integer> maxRaPerTso) {
7779
}
7880
}
7981

82+
public void setMaxElementaryActionsPerTso(Map<String, Integer> maxElementaryActionsPerTso) {
83+
this.maxElementaryActionsPerTso = Objects.isNull(maxElementaryActionsPerTso) ? new HashMap<>() : replaceNegativeValues(maxElementaryActionsPerTso);
84+
}
85+
8086
public int getMaxRa() {
8187
return maxRa;
8288
}
@@ -97,6 +103,10 @@ public Map<String, Integer> getMaxRaPerTso() {
97103
return maxRaPerTso;
98104
}
99105

106+
public Map<String, Integer> getMaxElementaryActionsPerTso() {
107+
return maxElementaryActionsPerTso;
108+
}
109+
100110
public Set<String> getMaxTsoExclusion() {
101111
return maxTsoExclusion;
102112
}

data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/RaUsageLimitsAdder.java

+2
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@ public interface RaUsageLimitsAdder {
2424

2525
RaUsageLimitsAdder withMaxRaPerTso(Map<String, Integer> maxRaPerTso);
2626

27+
RaUsageLimitsAdder withMaxElementaryActionPerTso(Map<String, Integer> maxRaPerTso);
28+
2729
RaUsageLimits add();
2830
}

data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/RaUsageLimitsTest.java

+8
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ void testNominalBehavior() {
3535
assertTrue(raUsageLimits.getMaxRaPerTso().isEmpty());
3636
assertTrue(raUsageLimits.getMaxPstPerTso().isEmpty());
3737
assertTrue(raUsageLimits.getMaxTopoPerTso().isEmpty());
38+
assertTrue(raUsageLimits.getMaxElementaryActionsPerTso().isEmpty());
3839
// set regular values
3940
raUsageLimits.setMaxRa(4);
4041
assertEquals(4, raUsageLimits.getMaxRa());
@@ -49,6 +50,9 @@ void testNominalBehavior() {
4950
Map<String, Integer> raMap = Map.of("FR", 7, "DE", 10);
5051
raUsageLimits.setMaxRaPerTso(raMap);
5152
assertEquals(raMap, raUsageLimits.getMaxRaPerTso());
53+
Map<String, Integer> elementaryActionsMap = Map.of("FR", 3, "DE", 2);
54+
raUsageLimits.setMaxElementaryActionsPerTso(elementaryActionsMap);
55+
assertEquals(elementaryActionsMap, raUsageLimits.getMaxElementaryActionsPerTso());
5256
}
5357

5458
@Test
@@ -63,13 +67,15 @@ void testEquality() {
6367
raUsageLimits1.setMaxRaPerTso(Map.of("FR", 4));
6468
raUsageLimits1.setMaxTopoPerTso(Map.of("FR", 2));
6569
raUsageLimits1.setMaxPstPerTso(Map.of("FR", 3));
70+
raUsageLimits1.setMaxElementaryActionsPerTso(Map.of("FR", 3));
6671
assertNotEquals(raUsageLimits1, raUsageLimits2);
6772
// applies the same modification to the second object
6873
raUsageLimits2.setMaxRa(3);
6974
raUsageLimits2.setMaxTso(5);
7075
raUsageLimits2.setMaxRaPerTso(Map.of("FR", 4));
7176
raUsageLimits2.setMaxTopoPerTso(Map.of("FR", 2));
7277
raUsageLimits2.setMaxPstPerTso(Map.of("FR", 3));
78+
raUsageLimits2.setMaxElementaryActionsPerTso(Map.of("FR", 3));
7379
assertEquals(raUsageLimits1, raUsageLimits2);
7480
}
7581

@@ -109,6 +115,8 @@ void testIllegalValues() {
109115
assertTrue(raUsageLimits.getMaxTopoPerTso().isEmpty());
110116
raUsageLimits.setMaxRaPerTso(null);
111117
assertTrue(raUsageLimits.getMaxRaPerTso().isEmpty());
118+
raUsageLimits.setMaxElementaryActionsPerTso(null);
119+
assertTrue(raUsageLimits.getMaxElementaryActionsPerTso().isEmpty());
112120
// check logs
113121
assertEquals(3, logsList.size());
114122
assertEquals("The value -3 provided for max number of TSOs is smaller than 0. It will be set to 0 instead.", logsList.get(0).getFormattedMessage());

data/crac/crac-impl/src/main/java/com/powsybl/openrao/data/cracimpl/RaUsageLimitsAdderImpl.java

+6
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ public RaUsageLimitsAdder withMaxRaPerTso(Map<String, Integer> maxRaPerTso) {
6060
return this;
6161
}
6262

63+
@Override
64+
public RaUsageLimitsAdder withMaxElementaryActionPerTso(Map<String, Integer> maxElementaryActionPerTso) {
65+
raUsageLimits.setMaxElementaryActionsPerTso(maxElementaryActionPerTso);
66+
return this;
67+
}
68+
6369
@Override
6470
public RaUsageLimits add() {
6571
owner.addRaUsageLimits(instant, raUsageLimits);

data/crac/crac-impl/src/test/java/com/powsybl/openrao/data/cracimpl/RaUsageLimitsAdderImplTest.java

+2
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,13 @@ void testAdd() {
6666
raUsageLimits.setMaxRaPerTso(new HashMap<>(Map.of("FR", 41)));
6767
raUsageLimits.setMaxPstPerTso(new HashMap<>(Map.of("BE", 7)));
6868
raUsageLimits.setMaxTopoPerTso(new HashMap<>(Map.of("DE", 5)));
69+
raUsageLimits.setMaxElementaryActionsPerTso(new HashMap<>(Map.of("FR", 3)));
6970
crac.newRaUsageLimits("curative")
7071
.withMaxTso(raUsageLimits.getMaxTso())
7172
.withMaxRaPerTso(raUsageLimits.getMaxRaPerTso())
7273
.withMaxPstPerTso(raUsageLimits.getMaxPstPerTso())
7374
.withMaxTopoPerTso(raUsageLimits.getMaxTopoPerTso())
75+
.withMaxElementaryActionPerTso(raUsageLimits.getMaxElementaryActionsPerTso())
7476
.add();
7577
assertEquals(raUsageLimits, crac.getRaUsageLimits(curativeInstant));
7678
}

data/crac/crac-impl/src/test/java/com/powsybl/openrao/data/cracimpl/utils/CommonCracCreation.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public final class CommonCracCreation {
3636
private static final String AUTO_INSTANT_ID = "auto";
3737
private static final String CURATIVE_INSTANT_ID = "curative";
3838

39-
private static class IidmPstHelper {
39+
public static class IidmPstHelper {
4040

4141
private final String pstId;
4242
private int initialTapPosition;

data/crac/crac-impl/src/test/java/com/powsybl/openrao/data/cracimpl/utils/ExhaustiveCracCreation.java

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public static Crac create(CracFactory cracFactory) {
6969
.withMaxPstPerTso(new HashMap<>(Map.of("FR", 7)))
7070
.withMaxTopoPerTso(new HashMap<>(Map.of("FR", 5, "BE", 6)))
7171
.withMaxRaPerTso(new HashMap<>(Map.of("FR", 12)))
72+
.withMaxElementaryActionPerTso(new HashMap<>(Map.of("FR", 21)))
7273
.add();
7374

7475
String contingency1Id = "contingency1Id";

0 commit comments

Comments
 (0)