OnConstraintUsageRuleHelperTest.java
/*
* 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.crac.io.nc.craccreator.remedialaction;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.crac.io.nc.objects.AssessedElementWithRemedialAction;
import com.powsybl.openrao.data.crac.io.nc.objects.ContingencyWithRemedialAction;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.api.InstantKind;
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openrao.data.crac.io.commons.api.ElementaryCreationContext;
import com.powsybl.openrao.data.crac.io.commons.api.StandardElementaryCreationContext;
import com.powsybl.openrao.data.crac.impl.CracImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Thomas Bouquet {@literal <thomas.bouquet at rte-france.com>}
*/
class OnConstraintUsageRuleHelperTest {
private Crac crac;
private Set<ElementaryCreationContext> cnecCreationContexts;
private Set<AssessedElementWithRemedialAction> assessedElementWithRemedialActions;
private Set<ContingencyWithRemedialAction> contingencyWithRemedialActions;
@BeforeEach
void setUp() {
crac = new CracImpl("crac");
// Set-up instants
crac.newInstant("preventive", InstantKind.PREVENTIVE);
crac.newInstant("outage", InstantKind.OUTAGE);
crac.newInstant("auto", InstantKind.AUTO);
crac.newInstant("curative", InstantKind.CURATIVE);
// Add contingencies
crac.newContingency().withId("contingency-1").add();
crac.newContingency().withId("contingency-2").add();
crac.newContingency().withId("contingency-3").add();
crac.newContingency().withId("contingency-4").add();
crac.newContingency().withId("contingency-5").add();
crac.newContingency().withId("contingency-6").add();
// Add FlowCNECs
crac.newFlowCnec().withId("Line 1 - curative - CO1").withNominalVoltage(400d).withNetworkElement("Line 1").withInstant("curative").withContingency("contingency-1").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 2 - preventive").withNominalVoltage(400d).withNetworkElement("Line 2").withInstant("preventive").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 2 - curative - CO1").withNominalVoltage(400d).withNetworkElement("Line 2").withInstant("curative").withContingency("contingency-1").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 2 - curative - CO2").withNominalVoltage(400d).withNetworkElement("Line 2").withInstant("curative").withContingency("contingency-2").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 2 - curative - CO3").withNominalVoltage(400d).withNetworkElement("Line 2").withInstant("curative").withContingency("contingency-3").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 2 - curative - CO4").withNominalVoltage(400d).withNetworkElement("Line 2").withInstant("curative").withContingency("contingency-4").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 2 - curative - CO5").withNominalVoltage(400d).withNetworkElement("Line 2").withInstant("curative").withContingency("contingency-5").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 2 - curative - CO6").withNominalVoltage(400d).withNetworkElement("Line 2").withInstant("curative").withContingency("contingency-6").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 3 - preventive").withNominalVoltage(400d).withNetworkElement("Line 3").withInstant("preventive").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 3 - curative - CO1").withNominalVoltage(400d).withNetworkElement("Line 3").withInstant("curative").withContingency("contingency-1").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 3 - curative - CO2").withNominalVoltage(400d).withNetworkElement("Line 3").withInstant("curative").withContingency("contingency-2").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 3 - curative - CO3").withNominalVoltage(400d).withNetworkElement("Line 3").withInstant("curative").withContingency("contingency-3").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 3 - curative - CO4").withNominalVoltage(400d).withNetworkElement("Line 3").withInstant("curative").withContingency("contingency-4").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 3 - curative - CO5").withNominalVoltage(400d).withNetworkElement("Line 3").withInstant("curative").withContingency("contingency-5").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 3 - curative - CO6").withNominalVoltage(400d).withNetworkElement("Line 3").withInstant("curative").withContingency("contingency-6").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 4 - curative - CO1").withNominalVoltage(400d).withNetworkElement("Line 4").withInstant("curative").withContingency("contingency-1").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 6 - curative - CO1").withNominalVoltage(400d).withNetworkElement("Line 6").withInstant("curative").withContingency("contingency-1").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
crac.newFlowCnec().withId("Line 8 - curative - CO1").withNominalVoltage(400d).withNetworkElement("Line 8").withInstant("curative").withContingency("contingency-1").newThreshold().withSide(TwoSides.ONE).withMax(1000d).withUnit(Unit.AMPERE).add().add();
// Add CNEC creation contexts
cnecCreationContexts = new HashSet<>();
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-1", null, "Line 1 - curative - CO1", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-2", null, "Line 2 - preventive", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-2", null, "Line 2 - curative - CO1", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-2", null, "Line 2 - curative - CO2", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-2", null, "Line 2 - curative - CO3", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-2", null, "Line 2 - curative - CO4", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-2", null, "Line 2 - curative - CO5", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-2", null, "Line 2 - curative - CO6", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-3", null, "Line 3 - preventive", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-3", null, "Line 3 - curative - CO1", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-3", null, "Line 3 - curative - CO2", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-3", null, "Line 3 - curative - CO3", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-3", null, "Line 3 - curative - CO4", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-3", null, "Line 3 - curative - CO5", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-3", null, "Line 3 - curative - CO6", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-4", null, "Line 4 - curative - CO1", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-6", null, "Line 6 - curative - CO1", false, ""));
cnecCreationContexts.add(StandardElementaryCreationContext.imported("assessed-element-8", null, "Line 8 - curative - CO1", false, ""));
// Add AssessedElementWithRemedialAction property bags
AssessedElementWithRemedialAction assessedElement1WithRemedialAction = new AssessedElementWithRemedialAction("ae1xra", "assessed-element-1", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.included", true);
AssessedElementWithRemedialAction assessedElement2WithRemedialAction = new AssessedElementWithRemedialAction("ae2xra", "assessed-element-2", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.included", true);
AssessedElementWithRemedialAction assessedElement4WithRemedialAction = new AssessedElementWithRemedialAction("ae4xra", "assessed-element-4", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.considered", false);
AssessedElementWithRemedialAction assessedElement5WithRemedialActionIncluded = new AssessedElementWithRemedialAction("ae5xra-included", "assessed-element-5", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.included", true);
AssessedElementWithRemedialAction assessedElement5WithRemedialActionConsidered = new AssessedElementWithRemedialAction("ae5xra-considered", "assessed-element-5", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.considered", true);
AssessedElementWithRemedialAction assessedElement6WithRemedialAction = new AssessedElementWithRemedialAction("ae6xra", "assessed-element-6", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.excluded", true);
AssessedElementWithRemedialAction assessedElement7WithRemedialAction = new AssessedElementWithRemedialAction("ae7xra", "assessed-element-7", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.included", true);
AssessedElementWithRemedialAction assessedElement8WithRemedialActionIncluded = new AssessedElementWithRemedialAction("ae8xra-included", "assessed-element-8", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.included", true);
AssessedElementWithRemedialAction assessedElement8WithRemedialActionConsidered = new AssessedElementWithRemedialAction("ae8xra-considered", "assessed-element-8", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.considered", true);
assessedElementWithRemedialActions = Set.of(assessedElement1WithRemedialAction, assessedElement2WithRemedialAction, assessedElement4WithRemedialAction, assessedElement5WithRemedialActionIncluded, assessedElement5WithRemedialActionConsidered, assessedElement6WithRemedialAction, assessedElement7WithRemedialAction, assessedElement8WithRemedialActionIncluded, assessedElement8WithRemedialActionConsidered);
// Add ContingencyWithRemedialAction property bags
ContingencyWithRemedialAction contingency1WithRemedialAction = new ContingencyWithRemedialAction("co1xra", "contingency-1", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.included", true);
ContingencyWithRemedialAction contingency2WithRemedialAction = new ContingencyWithRemedialAction("co2xra", "contingency-2", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.considered", true);
ContingencyWithRemedialAction contingency3WithRemedialAction = new ContingencyWithRemedialAction("co3xra", "contingency-3", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.included", true);
ContingencyWithRemedialAction contingency4WithRemedialAction = new ContingencyWithRemedialAction("co4xra", "contingency-4", "remedial-action", "http://entsoe.eu/ns/nc#ElementCombinationConstraintKind.considered", true);
contingencyWithRemedialActions = Set.of(contingency1WithRemedialAction, contingency2WithRemedialAction, contingency3WithRemedialAction, contingency4WithRemedialAction);
}
@Test
void getImportedCnecFromAssessedElementId() {
assertEquals(
Set.of(crac.getFlowCnec("Line 2 - preventive"), crac.getFlowCnec("Line 2 - curative - CO1"), crac.getFlowCnec("Line 2 - curative - CO2"), crac.getFlowCnec("Line 2 - curative - CO3"), crac.getFlowCnec("Line 2 - curative - CO4"), crac.getFlowCnec("Line 2 - curative - CO5"), crac.getFlowCnec("Line 2 - curative - CO6")),
OnConstraintUsageRuleHelper.getImportedCnecFromAssessedElementId("assessed-element-2", crac, cnecCreationContexts)
);
}
@Test
void filterCnecsThatHaveGivenContingencies() {
assertEquals(
Set.of(crac.getFlowCnec("Line 2 - curative - CO3"), crac.getFlowCnec("Line 3 - curative - CO3"), crac.getFlowCnec("Line 2 - curative - CO5"), crac.getFlowCnec("Line 3 - curative - CO5")),
OnConstraintUsageRuleHelper.filterCnecsThatHaveGivenContingencies(crac.getCnecs(), Set.of("contingency-3", "contingency-5"))
);
}
@Test
void processCnecsLinkedToRemedialActionWithContingencies() {
Map<String, AssociationStatus> expectedResult = new HashMap<>();
expectedResult.put("Line 1 - curative - CO1", new AssociationStatus(true, ""));
expectedResult.put("Line 2 - curative - CO1", new AssociationStatus(true, ""));
expectedResult.put("Line 2 - curative - CO3", new AssociationStatus(true, ""));
expectedResult.put("assessed-element-4", new AssociationStatus(false, "OnConstraint usage rule for remedial action remedial-action with assessed element assessed-element-4 ignored because the association is disabled."));
expectedResult.put("assessed-element-5", new AssociationStatus(false, "OnConstraint usage rule for remedial action remedial-action with assessed element assessed-element-5 ignored because this assessed element has several conflictual links to the remedial action."));
expectedResult.put("assessed-element-6", new AssociationStatus(false, "OnConstraint usage rule for remedial action remedial-action with assessed element assessed-element-6 ignored because only included combinationConstraintKinds are supported."));
expectedResult.put("assessed-element-7", new AssociationStatus(false, "OnConstraint usage rule for remedial action remedial-action with assessed element assessed-element-7 ignored because no CNEC was imported by Open RAO from this assessed element."));
expectedResult.put("assessed-element-8", new AssociationStatus(false, "OnConstraint usage rule for remedial action remedial-action with assessed element assessed-element-8 ignored because this assessed element has several conflictual links to the remedial action."));
assertEquals(expectedResult, OnConstraintUsageRuleHelper.processCnecsLinkedToRemedialAction(crac, "remedial-action", assessedElementWithRemedialActions, contingencyWithRemedialActions, cnecCreationContexts));
}
@Test
void processCnecsLinkedToRemedialActionWithoutContingencies() {
Map<String, AssociationStatus> expectedResult = new HashMap<>();
expectedResult.put("Line 1 - curative - CO1", new AssociationStatus(true, ""));
expectedResult.put("Line 2 - preventive", new AssociationStatus(true, ""));
expectedResult.put("Line 2 - curative - CO1", new AssociationStatus(true, ""));
expectedResult.put("Line 2 - curative - CO2", new AssociationStatus(true, ""));
expectedResult.put("Line 2 - curative - CO3", new AssociationStatus(true, ""));
expectedResult.put("Line 2 - curative - CO4", new AssociationStatus(true, ""));
expectedResult.put("Line 2 - curative - CO5", new AssociationStatus(true, ""));
expectedResult.put("Line 2 - curative - CO6", new AssociationStatus(true, ""));
expectedResult.put("assessed-element-4", new AssociationStatus(false, "OnConstraint usage rule for remedial action remedial-action with assessed element assessed-element-4 ignored because the association is disabled."));
expectedResult.put("assessed-element-5", new AssociationStatus(false, "OnConstraint usage rule for remedial action remedial-action with assessed element assessed-element-5 ignored because this assessed element has several conflictual links to the remedial action."));
expectedResult.put("assessed-element-6", new AssociationStatus(false, "OnConstraint usage rule for remedial action remedial-action with assessed element assessed-element-6 ignored because only included combinationConstraintKinds are supported."));
expectedResult.put("assessed-element-7", new AssociationStatus(false, "OnConstraint usage rule for remedial action remedial-action with assessed element assessed-element-7 ignored because no CNEC was imported by Open RAO from this assessed element."));
expectedResult.put("assessed-element-8", new AssociationStatus(false, "OnConstraint usage rule for remedial action remedial-action with assessed element assessed-element-8 ignored because this assessed element has several conflictual links to the remedial action."));
assertEquals(expectedResult, OnConstraintUsageRuleHelper.processCnecsLinkedToRemedialAction(crac, "remedial-action", assessedElementWithRemedialActions, Set.of(), cnecCreationContexts));
}
}