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

Check physical parameters in RaoResult's isSecure #905

Merged
merged 34 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
ec14273
Check parameters
bqth29 Feb 27, 2024
485986e
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Feb 27, 2024
2994c82
Check physical parameters in isSecure
bqth29 Feb 28, 2024
240db5e
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Mar 22, 2024
5423aa5
Test Instant.min
bqth29 Mar 22, 2024
18ab9f2
Exhaustive tests with all 2 types of CNECs
bqth29 Mar 22, 2024
a5eee12
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Mar 22, 2024
c528edf
Remove comments
bqth29 Mar 22, 2024
8336a69
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Mar 22, 2024
4109876
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Mar 25, 2024
a83a13b
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Apr 4, 2024
af2c3f3
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Apr 4, 2024
8cdd91b
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Apr 4, 2024
efed6ad
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Apr 10, 2024
784885c
Merge branch 'main' into check_physical_parameters_in_is_secure
pet-mit Apr 11, 2024
867460c
Merge branch 'main' into check_physical_parameters_in_is_secure
pet-mit Apr 11, 2024
032152e
Change test 12.15.6
pet-mit Apr 12, 2024
9b1540a
Rollb
bqth29 Apr 12, 2024
4b238f6
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Apr 17, 2024
d966b9a
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Apr 22, 2024
7f1c8da
Merge branch 'main' into change_swe_cne_test
bqth29 Apr 22, 2024
49599f1
Merge branch 'change_swe_cne_test' into check_physical_parameters_in_…
bqth29 Apr 22, 2024
243d906
Merge branch 'main' into check_physical_parameters_in_is_secure
pet-mit May 6, 2024
78e746e
Merge branch 'check_physical_parameters_in_is_secure' of https://gith…
bqth29 May 27, 2024
0a0cb2b
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 May 27, 2024
27e892d
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Jun 17, 2024
88a0a2c
Fix test 12.15.6 + remove dupliacted code (now default RaoResul method)
bqth29 Jun 17, 2024
f12c823
Merge branch 'main' into check_physical_parameters_in_is_secure
bqth29 Jun 17, 2024
1e23795
Merge branch 'main' into check_physical_parameters_in_is_secure
pet-mit Jun 20, 2024
30c682d
Update data/result-exporter/swe-cne-exporter/src/main/java/com/powsyb…
bqth29 Jun 21, 2024
cdc1968
Fix tests and remove duplicated code
bqth29 Jun 21, 2024
d6f4a56
Promote default methods to Instant interface
bqth29 Jun 21, 2024
93b0b35
Update data/result-exporter/swe-cne-exporter/src/main/java/com/powsyb…
bqth29 Jun 24, 2024
d3607c8
Fix after comments
bqth29 Jun 24, 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 @@ -36,4 +36,16 @@ public interface Instant extends Identifiable<Instant>, Comparable<Instant> {
boolean isAuto();

boolean isCurative();

@Override
default int compareTo(Instant otherInstant) {
return Integer.compare(getOrder(), otherInstant.getOrder());
}

static Instant min(Instant instant1, Instant instant2) {
if (instant1 == null || instant2 == null) {
return null;
}
return instant1.comesBefore(instant2) ? instant1 : instant2;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,4 @@ public int hashCode() {
Instant getInstantBefore() {
return previous;
}

@Override
public int compareTo(Instant otherInstant) {
return Integer.compare(getOrder(), otherInstant.getOrder());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,14 @@ void testInstantBeforeAfter() {

assertFalse(preventiveInstant.comesAfter(preventiveInstant));
}

@Test
void testMin() {
InstantImpl instant1 = new InstantImpl("instant1", InstantKind.PREVENTIVE, null);
InstantImpl instant2 = new InstantImpl("instant2", InstantKind.CURATIVE, instant1);
assertEquals(instant1, Instant.min(instant1, instant2));
assertNull(Instant.min(instant1, null));
assertNull(Instant.min(null, instant2));
assertNull(Instant.min(null, null));
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -189,17 +189,6 @@ private static String getIdFromNullableInstant(Instant optimizedInstant) {
return optimizedInstant == null ? INITIAL_INSTANT_ID : optimizedInstant.getId();
}

@Override
public boolean isActivatedDuringState(State state, RemedialAction<?> remedialAction) {
if (remedialAction instanceof NetworkAction networkAction) {
return isActivatedDuringState(state, networkAction);
} else if (remedialAction instanceof RangeAction<?> rangeAction) {
return isActivatedDuringState(state, rangeAction);
} else {
throw new OpenRaoException("Unrecognized remedial action type");
}
}

public NetworkActionResult getAndCreateIfAbsentNetworkActionResult(NetworkAction networkAction) {
networkActionResults.putIfAbsent(networkAction, new NetworkActionResult());
return networkActionResults.get(networkAction);
Expand Down Expand Up @@ -344,7 +333,12 @@ private boolean instantHasNoNegativeMargin(Instant optimizedInstant, PhysicalPar
for (PhysicalParameter physicalParameter : Set.of(u)) {
switch (physicalParameter) {
case ANGLE -> {
if (angleCnecResults.keySet().stream()
if (crac.getAngleCnecs().stream()
.mapToDouble(cnec -> getMargin(Instant.min(optimizedInstant, cnec.getState().getInstant()), cnec, Unit.DEGREE))
.anyMatch(Double::isNaN)) {
throw new OpenRaoException("RaoResult does not contain angle values for all AngleCNECs, security status for physical parameter ANGLE is unknown");
}
if (crac.getAngleCnecs().stream()
.mapToDouble(cnec -> getMargin(optimizedInstant, cnec, Unit.DEGREE))
.filter(margin -> !Double.isNaN(margin))
.anyMatch(margin -> margin < 0)) {
Expand All @@ -357,7 +351,12 @@ private boolean instantHasNoNegativeMargin(Instant optimizedInstant, PhysicalPar
}
}
case VOLTAGE -> {
if (voltageCnecResults.keySet().stream()
if (crac.getVoltageCnecs().stream()
.mapToDouble(cnec -> getMargin(Instant.min(optimizedInstant, cnec.getState().getInstant()), cnec, Unit.KILOVOLT))
.anyMatch(Double::isNaN)) {
throw new OpenRaoException("RaoResult does not contain voltage values for all VoltageCNECs, security status for physical parameter VOLTAGE is unknown");
}
if (crac.getVoltageCnecs().stream()
.mapToDouble(cnec -> getMargin(optimizedInstant, cnec, Unit.KILOVOLT))
.filter(margin -> !Double.isNaN(margin))
.anyMatch(margin -> margin < 0)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.PhysicalParameter;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.cracapi.Crac;
import com.powsybl.openrao.data.cracapi.Instant;
import com.powsybl.openrao.data.cracapi.State;
Expand Down Expand Up @@ -37,6 +38,7 @@
class RaoResultImplTest {
private static final double DOUBLE_TOLERANCE = 1e-6;
private static final String PREVENTIVE_INSTANT_ID = "preventive";
private static final String OUTAGE_INSTANT_ID = "outage";
private static final String AUTO_INSTANT_ID = "auto";
private static final String CURATIVE_INSTANT_ID = "curative";

Expand All @@ -46,12 +48,14 @@ class RaoResultImplTest {
private PstRangeAction pst;
private NetworkAction na;
private Instant preventiveInstant;
private Instant outageInstant;
private Instant autoInstant;
private Instant curativeInstant;

private void setUp() {
crac = CommonCracCreation.createWithPreventiveAndCurativePstRange();
preventiveInstant = crac.getInstant(PREVENTIVE_INSTANT_ID);
outageInstant = crac.getInstant(OUTAGE_INSTANT_ID);
autoInstant = crac.getInstant(AUTO_INSTANT_ID);
curativeInstant = crac.getInstant(CURATIVE_INSTANT_ID);
cnec = crac.getFlowCnec("cnec1basecase");
Expand Down Expand Up @@ -332,4 +336,161 @@ void testIsSecureDependsOnOptimizationState() {
assertTrue(raoResult.isSecure(curativeInstant, PhysicalParameter.FLOW, PhysicalParameter.ANGLE, PhysicalParameter.VOLTAGE));
assertTrue(raoResult.isSecure());
}

@Test
void comprehensiveRaoResultWithAllThreeTypesOfCnecs() {
setUp();
addOutageFlowCnec();
addAngleCnecs();
addVoltageCnecs();

AngleCnecResult angleResult1 = raoResult.getAndCreateIfAbsentAngleCnecResult(crac.getAngleCnec("angleCnecPreventive"));
ElementaryAngleCnecResult elementaryAngleCnecResult1 = angleResult1.getAndCreateIfAbsentResultForOptimizationState(preventiveInstant);
elementaryAngleCnecResult1.setAngle(50., DEGREE);
elementaryAngleCnecResult1.setMargin(10., DEGREE);

AngleCnecResult angleResult2 = raoResult.getAndCreateIfAbsentAngleCnecResult(crac.getAngleCnec("angleCnecStateOutageContingency1"));
ElementaryAngleCnecResult elementaryAngleCnecResult2 = angleResult2.getAndCreateIfAbsentResultForOptimizationState(preventiveInstant);
elementaryAngleCnecResult2.setAngle(90., DEGREE);
elementaryAngleCnecResult2.setMargin(30., DEGREE);

AngleCnecResult angleResult3 = raoResult.getAndCreateIfAbsentAngleCnecResult(crac.getAngleCnec("angleCnecStateCurativeContingency1"));
ElementaryAngleCnecResult elementaryAngleCnecResult3 = angleResult3.getAndCreateIfAbsentResultForOptimizationState(preventiveInstant);
elementaryAngleCnecResult3.setAngle(35., DEGREE);
elementaryAngleCnecResult3.setMargin(-.5, DEGREE);

VoltageCnecResult voltageResult1 = raoResult.getAndCreateIfAbsentVoltageCnecResult(crac.getVoltageCnec("voltageCnecPreventive"));
ElementaryVoltageCnecResult elementaryVoltageCnecResult1 = voltageResult1.getAndCreateIfAbsentResultForOptimizationState(preventiveInstant);
elementaryVoltageCnecResult1.setVoltage(400., KILOVOLT);
elementaryVoltageCnecResult1.setMargin(40., KILOVOLT);

VoltageCnecResult voltageResult2 = raoResult.getAndCreateIfAbsentVoltageCnecResult(crac.getVoltageCnec("voltageCnecStateOutageContingency1"));
ElementaryVoltageCnecResult elementaryVoltageCnecResult2 = voltageResult2.getAndCreateIfAbsentResultForOptimizationState(preventiveInstant);
elementaryVoltageCnecResult2.setVoltage(415., KILOVOLT);
elementaryVoltageCnecResult2.setMargin(5., KILOVOLT);

VoltageCnecResult voltageResult3 = raoResult.getAndCreateIfAbsentVoltageCnecResult(crac.getVoltageCnec("voltageCnecStateCurativeContingency1"));
ElementaryVoltageCnecResult elementaryVoltageCnecResult3 = voltageResult3.getAndCreateIfAbsentResultForOptimizationState(preventiveInstant);
elementaryVoltageCnecResult3.setVoltage(400., KILOVOLT);
elementaryVoltageCnecResult3.setMargin(40., KILOVOLT);

assertFalse(raoResult.isSecure(preventiveInstant, PhysicalParameter.FLOW, PhysicalParameter.ANGLE, PhysicalParameter.VOLTAGE));
assertTrue(raoResult.isSecure(preventiveInstant, PhysicalParameter.FLOW, PhysicalParameter.VOLTAGE));

assertEquals("RaoResult does not contain angle values for all AngleCNECs, security status for physical parameter ANGLE is unknown", assertThrows(OpenRaoException.class, () -> raoResult.isSecure(outageInstant, PhysicalParameter.FLOW, PhysicalParameter.ANGLE)).getMessage());
assertEquals("RaoResult does not contain angle values for all AngleCNECs, security status for physical parameter ANGLE is unknown", assertThrows(OpenRaoException.class, () -> raoResult.isSecure(curativeInstant, PhysicalParameter.FLOW, PhysicalParameter.ANGLE)).getMessage());
assertEquals("RaoResult does not contain voltage values for all VoltageCNECs, security status for physical parameter VOLTAGE is unknown", assertThrows(OpenRaoException.class, () -> raoResult.isSecure(outageInstant, PhysicalParameter.FLOW, PhysicalParameter.VOLTAGE)).getMessage());
assertEquals("RaoResult does not contain voltage values for all VoltageCNECs, security status for physical parameter VOLTAGE is unknown", assertThrows(OpenRaoException.class, () -> raoResult.isSecure(curativeInstant, PhysicalParameter.FLOW, PhysicalParameter.VOLTAGE)).getMessage());
}

private void addVoltageCnecs() {
crac.newVoltageCnec()
.withId("voltageCnecPreventive")
.withNetworkElement("BBE2AA1 ")
.withInstant(PREVENTIVE_INSTANT_ID)
.withMonitored(true)
.withOperator("operator1")
.newThreshold()
.withUnit(KILOVOLT)
.withMax(440.)
.add()
.add();

crac.newVoltageCnec()
.withId("voltageCnecStateOutageContingency1")
.withNetworkElement("BBE2AA1 ")
.withInstant(OUTAGE_INSTANT_ID)
.withContingency("Contingency FR1 FR3")
.withMonitored(true)
.withOperator("operator1")
.newThreshold()
.withUnit(KILOVOLT)
.withMax(420.)
.add()
.add();

crac.newVoltageCnec()
.withId("voltageCnecStateCurativeContingency1")
.withNetworkElement("BBE2AA1 ")
.withInstant(CURATIVE_INSTANT_ID)
.withContingency("Contingency FR1 FR3")
.withMonitored(true)
.withOperator("operator1")
.newThreshold()
.withUnit(KILOVOLT)
.withMax(440.)
.add()
.add();
}

private void addAngleCnecs() {
crac.newAngleCnec()
.withId("angleCnecPreventive")
.withExportingNetworkElement("BBE2AA1 ")
.withImportingNetworkElement("FFR3AA1 ")
.withInstant(PREVENTIVE_INSTANT_ID)
.withOperator("operator1")
.withMonitored(true)
.newThreshold()
.withUnit(DEGREE)
.withMin(-60.)
.withMax(60.)
.add()
.add();

crac.newAngleCnec()
.withId("angleCnecStateOutageContingency1")
.withExportingNetworkElement("BBE2AA1 ")
.withImportingNetworkElement("FFR3AA1 ")
.withInstant(OUTAGE_INSTANT_ID)
.withContingency("Contingency FR1 FR3")
.withMonitored(true)
.withOperator("operator1")
.newThreshold()
.withUnit(DEGREE)
.withMin(-120.)
.withMax(120.)
.add()
.add();

crac.newAngleCnec()
.withId("angleCnecStateCurativeContingency1")
.withExportingNetworkElement("BBE2AA1 ")
.withImportingNetworkElement("FFR3AA1 ")
.withInstant(CURATIVE_INSTANT_ID)
.withContingency("Contingency FR1 FR3")
.withMonitored(true)
.withOperator("operator1")
.newThreshold()
.withUnit(DEGREE)
.withMin(-30.)
.withMax(30.)
.add()
.add();
}

private void addOutageFlowCnec() {
crac.newFlowCnec()
.withId("cnec1stateOutageContingency1")
.withNetworkElement("BBE2AA1 FFR3AA1 1")
.withInstant(OUTAGE_INSTANT_ID)
.withContingency("Contingency FR1 FR3")
.withOptimized(true)
.withOperator("operator1")
.withNominalVoltage(380.)
.withIMax(5000.)
.newThreshold()
.withUnit(Unit.MEGAWATT)
.withSide(Side.LEFT)
.withMin(-2000.)
.withMax(2000.)
.add()
.newThreshold()
.withUnit(Unit.MEGAWATT)
.withSide(Side.RIGHT)
.withMin(-2000.)
.withMax(2000.)
.add()
.add();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,16 @@ private void addReason(Point point) {
Reason reason = new Reason();
RaoResult raoResult = sweCneHelper.getRaoResult();
boolean isDivergent = sweCneHelper.isAnyContingencyInFailure() || raoResult.getComputationStatus() == ComputationStatus.FAILURE;
boolean isUnsecure = !raoResult.isSecure(PhysicalParameter.FLOW, PhysicalParameter.ANGLE);
boolean isUnsecure;
try {
isUnsecure = !raoResult.isSecure(PhysicalParameter.FLOW, PhysicalParameter.ANGLE);
} catch (OpenRaoException e) {
if ("RaoResult does not contain angle values for all AngleCNECs, security status for physical parameter ANGLE is unknown".equals(e.getMessage())) {
isUnsecure = false; // simply ignore AngleCNECs
} else {
throw e; // unexpected error
}
}
bqth29 marked this conversation as resolved.
Show resolved Hide resolved
if (isDivergent) {
reason.setCode(DIVERGENCE_CODE);
reason.setText(DIVERGENCE_TEXT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
import com.powsybl.openrao.data.raoresultapi.RaoResult;
import com.powsybl.openrao.data.raoresultapi.RaoResultClone;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -54,7 +57,7 @@ public double getAngle(Instant optimizationInstant, AngleCnec angleCnec, Unit un
if (!unit.equals(Unit.DEGREE)) {
throw new OpenRaoException("Unexpected unit for angle monitoring result : " + unit);
}
if (!optimizationInstant.isCurative()) {
if (optimizationInstant == null || !optimizationInstant.isCurative()) {
throw new OpenRaoException("Unexpected optimization instant for angle monitoring result (only curative instant is supported currently) : " + optimizationInstant);
}
return angleMonitoringResult.getAngle(angleCnec, unit);
Expand Down Expand Up @@ -87,17 +90,19 @@ public boolean isActivatedDuringState(State state, NetworkAction networkAction)

@Override
public boolean isSecure(Instant instant, PhysicalParameter... u) {
if (Set.of(u).contains(PhysicalParameter.ANGLE)) {
return raoResult.isSecure(instant, u) && angleMonitoringResult.isSecure();
List<PhysicalParameter> physicalParameters = new ArrayList<>(Stream.of(u).sorted().toList());
if (physicalParameters.remove(PhysicalParameter.ANGLE)) {
return raoResult.isSecure(instant, physicalParameters.toArray(new PhysicalParameter[0])) && angleMonitoringResult.isSecure();
} else {
return raoResult.isSecure(instant, u);
}
}

@Override
public boolean isSecure(PhysicalParameter... u) {
if (Set.of(u).contains(PhysicalParameter.ANGLE)) {
return raoResult.isSecure(u) && angleMonitoringResult.isSecure();
List<PhysicalParameter> physicalParameters = new ArrayList<>(Stream.of(u).sorted().toList());
if (physicalParameters.remove(PhysicalParameter.ANGLE)) {
return raoResult.isSecure(physicalParameters.toArray(new PhysicalParameter[0])) && angleMonitoringResult.isSecure();
} else {
return raoResult.isSecure(u);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ void testIsSecureWhenRaoResultAndAngleMonitoringIsSecure() {
RaoResult raoResultWithVoltageMonitoring = new RaoResultWithAngleMonitoring(raoResult, angleMonitoringResult);
Mockito.when(raoResult.isSecure()).thenReturn(true);
Mockito.when(angleMonitoringResult.isSecure()).thenReturn(true);
Mockito.when(raoResult.isSecure(PhysicalParameter.FLOW, PhysicalParameter.ANGLE)).thenReturn(true);
Mockito.when(raoResult.isSecure(Mockito.any(Instant.class), Mockito.eq(PhysicalParameter.FLOW), Mockito.eq(PhysicalParameter.ANGLE))).thenReturn(true);
Mockito.when(raoResult.isSecure(PhysicalParameter.FLOW)).thenReturn(true);
Mockito.when(raoResult.isSecure(Mockito.any(Instant.class), Mockito.eq(PhysicalParameter.FLOW))).thenReturn(true);

assertTrue(raoResultWithVoltageMonitoring.isSecure());
assertTrue(raoResultWithVoltageMonitoring.isSecure(PhysicalParameter.FLOW, PhysicalParameter.ANGLE));
Expand All @@ -102,9 +102,9 @@ void testIsSecureWhenRaoResultAndAngleMonitoringUnsecureIfAngleNotChecked() {
RaoResult raoResultWithVoltageMonitoring = new RaoResultWithAngleMonitoring(raoResult, angleMonitoringResult);
Mockito.when(raoResult.isSecure()).thenReturn(true);
Mockito.when(angleMonitoringResult.isSecure()).thenReturn(false);
Mockito.when(raoResult.isSecure(PhysicalParameter.FLOW, PhysicalParameter.ANGLE)).thenReturn(true);
Mockito.when(raoResult.isSecure(PhysicalParameter.FLOW)).thenReturn(true);
Mockito.when(raoResult.isSecure(PhysicalParameter.FLOW, PhysicalParameter.VOLTAGE)).thenReturn(true);
Mockito.when(raoResult.isSecure(Mockito.any(Instant.class), Mockito.eq(PhysicalParameter.FLOW), Mockito.eq(PhysicalParameter.ANGLE))).thenReturn(true);
Mockito.when(raoResult.isSecure(Mockito.any(Instant.class), Mockito.eq(PhysicalParameter.FLOW))).thenReturn(true);
Mockito.when(raoResult.isSecure(Mockito.any(Instant.class), Mockito.eq(PhysicalParameter.FLOW), Mockito.eq(PhysicalParameter.VOLTAGE))).thenReturn(true);

assertFalse(raoResultWithVoltageMonitoring.isSecure());
Expand Down
Loading
Loading