Skip to content

Commit

Permalink
Merge branch 'accelerate_state_tree_init' of https://github.com/powsy…
Browse files Browse the repository at this point in the history
…bl/open-rao into accelerate_state_tree_init
  • Loading branch information
phiedw committed Apr 24, 2024
2 parents 7bfa69e + 5b8c4f0 commit 33dc0a6
Show file tree
Hide file tree
Showing 6 changed files with 358 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.powsybl.iidm.network.Network;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
Expand Down Expand Up @@ -57,8 +58,12 @@ private static void duplicateCnecsWithNoUsefulRaOnOutageInstant(Crac crac, Netwo
return;
}
// Find CNECs with no useful RA and duplicate them on outage instant
Set<RemedialAction<?>> remedialActions = new HashSet<>();
remedialActions.addAll(crac.getPotentiallyAvailableRangeActions(state));
remedialActions.addAll(crac.getPotentiallyAvailableNetworkActions(state));

crac.getFlowCnecs(state).stream()
.filter(cnec -> crac.getRemedialActions().stream().noneMatch(ra -> isRaUsefulForCnec(ra, cnec, network)))
.filter(cnec -> shouldDuplicateAutoCnecInOutageState(remedialActions, cnec, network))
.forEach(cnec -> {
duplicateCnecOnOutageInstant(crac, cnec);
report.add(String.format("CNEC \"%s\" has no associated automaton. It will be cloned on the OUTAGE instant in order to be secured during preventive RAO.", cnec.getId()));
Expand Down Expand Up @@ -112,36 +117,45 @@ private static void copyThresholds(FlowCnec cnec, FlowCnecAdder adder) {
);
}

private static boolean isRaUsefulForCnec(RemedialAction<?> ra, FlowCnec cnec, Network network) {
if (ra.getUsageMethod(cnec.getState()).equals(UsageMethod.FORCED) || ra.getUsageMethod(cnec.getState()).equals(UsageMethod.AVAILABLE)) {
return ra.getUsageRules().stream()
.filter(usageRule -> usageRule instanceof OnInstant || usageRule instanceof OnContingencyState)
.anyMatch(usageRule -> usageRule.getInstant().equals(cnec.getState().getInstant()))
||
ra.getUsageRules().stream()
.filter(OnFlowConstraint.class::isInstance)
.map(OnFlowConstraint.class::cast)
.anyMatch(ofc -> isOfcUsefulForCnec(ofc, cnec))
||
ra.getUsageRules().stream()
.filter(OnFlowConstraintInCountry.class::isInstance)
.map(OnFlowConstraintInCountry.class::cast)
.anyMatch(ofc -> isOfccUsefulForCnec(ofc, cnec, network));
}
return false;
}

/**
* Returns true if a given OnFlowConstraint usage rule is applicable for a given FlowCnec
* Indicates whether an auto FlowCNEC should be duplicated in the outage state or not.
* A FlowCNEC must be duplicated if no auto remedial action can act on it, leaving only the preventive remedial
* actions to possibly reduce the flow which means that the CNEC should be added to the preventive perimeter.
* <p/>
* This CNEC must however be kept in the auto instant because an overload on this line may be the triggering
* condition of auto remedial actions that can affect other FlowCNECs of the same state.
* <p/>
* If no auto remedial action affects the CNEC and the CNEC does not trigger any auto remedial action, there is no
* need to duplicate it because this means that no auto remedial action is available for this auto state at all.
* In this case, the StateTree algorithm will automatically include all the CNECs from the state to the preventive perimeter.
* @param remedialActions The set of remedial actions that may affect the CNEC
* @param flowCnec The FlowCNEC to possibly duplicate
* @param network The network
* @return Boolean value that indicates whether the CNEC should be duplicate in the outage state or not
*/
private static boolean isOfcUsefulForCnec(OnFlowConstraint ofc, FlowCnec cnec) {
return ofc.getFlowCnec().equals(cnec);
}

/**
* Returns true if a given OnFlowConstraintInCountry usage rule is applicable for a given FlowCnec
*/
private static boolean isOfccUsefulForCnec(OnFlowConstraintInCountry ofcc, FlowCnec cnec, Network network) {
return cnec.getLocation(network).contains(Optional.of(ofcc.getCountry()));
private static boolean shouldDuplicateAutoCnecInOutageState(Set<RemedialAction<?>> remedialActions, FlowCnec flowCnec, Network network) {
boolean raForOtherCnecs = false;
for (RemedialAction<?> remedialAction : remedialActions) {
for (UsageRule usageRule : remedialAction.getUsageRules()) {
if (usageRule instanceof OnInstant onInstant && onInstant.getInstant().equals(flowCnec.getState().getInstant())) {
return false;
} else if (usageRule instanceof OnContingencyState onContingencyState && onContingencyState.getState().equals(flowCnec.getState())) {
return false;
} else if (usageRule instanceof OnFlowConstraint onFlowConstraint && onFlowConstraint.getFlowCnec().getState().equals(flowCnec.getState())) {
if (onFlowConstraint.getFlowCnec().equals(flowCnec)) {
return false;
} else {
raForOtherCnecs = true;
}
} else if (usageRule instanceof OnFlowConstraintInCountry onFlowConstraintInCountry && onFlowConstraintInCountry.getInstant().equals(flowCnec.getState().getInstant())) {
if (flowCnec.getLocation(network).contains(Optional.of(onFlowConstraintInCountry.getCountry()))) {
return false;
} else {
raForOtherCnecs = true;
}
}
}
}
return raForOtherCnecs;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,33 @@ void testDuplicateAutoCnecs5() {
CracValidator.validateCrac(crac, network);
assertEquals(3, crac.getFlowCnecs().size());
}

@Test
void testDuplicateCnecsWithOnFlowConstraints() {
crac.newNetworkAction()
.withId("network-action-1")
.newTopologicalAction().withNetworkElement("FFR2AA1 FFR3AA1 1").withActionType(ActionType.OPEN).add()
.newOnFlowConstraintUsageRule().withFlowCnec("auto-cnec-1").withInstant(AUTO_INSTANT_ID).withUsageMethod(UsageMethod.FORCED).add()
.add();

CracValidator.validateCrac(crac, network);
assertEquals(4, crac.getFlowCnecs().size());
assertNull(crac.getFlowCnec("auto-cnec-1 - OUTAGE DUPLICATE"));
assertNotNull(crac.getFlowCnec("auto-cnec-2 - OUTAGE DUPLICATE"));
}

@Test
void testDuplicateCnecsWithOnFlowConstraintInCountries() {
crac.newNetworkAction()
.withId("network-action-1")
.newTopologicalAction().withNetworkElement("FFR2AA1 FFR3AA1 1").withActionType(ActionType.OPEN).add()
.newOnFlowConstraintInCountryUsageRule().withCountry(Country.BE).withInstant(AUTO_INSTANT_ID).withUsageMethod(UsageMethod.FORCED).add()
.add();

CracValidator.validateCrac(crac, network);
assertEquals(4, crac.getFlowCnecs().size());
assertNull(crac.getFlowCnec("auto-cnec-1 - OUTAGE DUPLICATE"));
assertNotNull(crac.getFlowCnec("auto-cnec-2 - OUTAGE DUPLICATE"));
assertNull(crac.getFlowCnec("auto-cnec-3 - OUTAGE DUPLICATE"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,13 @@ public CompletableFuture<OptimizationResult> run() {
if (rootLeaf.getStatus().equals(Leaf.Status.ERROR)) {
topLevelLogger.info("Could not evaluate leaf: {}", rootLeaf);
logOptimizationSummary(rootLeaf);
rootLeaf.finalizeOptimization();
return CompletableFuture.completedFuture(rootLeaf);
} else if (stopCriterionReached(rootLeaf)) {
topLevelLogger.info("Stop criterion reached on {}", rootLeaf);
RaoLogger.logMostLimitingElementsResults(topLevelLogger, rootLeaf, parameters.getObjectiveFunction(), NUMBER_LOGGED_ELEMENTS_END_TREE);
logOptimizationSummary(rootLeaf);
rootLeaf.finalizeOptimization();
return CompletableFuture.completedFuture(rootLeaf);
}

Expand All @@ -134,7 +136,8 @@ public CompletableFuture<OptimizationResult> run() {
logVirtualCostInformation(rootLeaf, "");

if (stopCriterionReached(rootLeaf)) {
logOptimizationSummary(optimalLeaf);
logOptimizationSummary(rootLeaf);
rootLeaf.finalizeOptimization();
return CompletableFuture.completedFuture(rootLeaf);
}

Expand All @@ -147,6 +150,7 @@ public CompletableFuture<OptimizationResult> run() {
RaoLogger.logMostLimitingElementsResults(TECHNICAL_LOGS, optimalLeaf, parameters.getObjectiveFunction(), NUMBER_LOGGED_ELEMENTS_END_TREE);

logOptimizationSummary(optimalLeaf);
optimalLeaf.finalizeOptimization();
return CompletableFuture.completedFuture(optimalLeaf);
}

Expand Down Expand Up @@ -370,7 +374,6 @@ private void optimizeLeaf(Leaf leaf) {
} else {
TECHNICAL_LOGS.info("No range actions to optimize");
}
leaf.finalizeOptimization();
}

private SensitivityComputer getSensitivityComputerForEvaluation(boolean isRootLeaf) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,13 @@ Feature: US 12.15: export different reason per perimeter in SWE CNE

@fast @cne-export @mock
Scenario: US 12.15.6: CNE export with angles, no angle results
# Copy of 12.15.4 with extra angle CNEC but no angle values in RAO result
# Should not fail. Should instead skip angle CNECs, thus expected CNE is the same as 12.5.4
# Copy of 12.15.4 with extra angle CNEC but no angle values in RAO result and a secure RAO
# Should not fail. Should instead skip angle CNECs, thus expected CNE is the same as 12.5.4 (but secure)
Given network file is "epic12/nordic32.xiidm"
Given crac file is "epic12/CIM_12_15_5.xml"
Given crac creation parameters file is "epic12/CimCracCreationParameters_MonitorLeftSide.json"
Given configuration file is "epic12/raoParametersSweIDCC_minObjectiveDisabled2P.json"
Given RaoResult file is "epic12/RaoResult_12_15_4.json"
Given RaoResult file is "epic12/RaoResult_12_15_6.json"
When I import data at "2021-04-02 05:00"
And I export SWE CNE
Then the exported CNE file is the same as "epic12/ExpectedCNE_12_15_4.xml"
Then the exported CNE file is the same as "epic12/ExpectedCNE_12_15_6.xml"
141 changes: 141 additions & 0 deletions tests/src/test/resources/files/cne/epic12/ExpectedCNE_12_15_6.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<CriticalNetworkElement_MarketDocument xsi:schemaLocation="iec62325-451-n-cne_v2_3.xsd" xmlns="urn:iec62325.351:tc57wg16:451-n:cnedocument:2:3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<mRID>documentId</mRID>
<revisionNumber>3</revisionNumber>
<type>B06</type>
<process.processType>A48</process.processType>
<sender_MarketParticipant.mRID codingScheme="A01">senderId</sender_MarketParticipant.mRID>
<sender_MarketParticipant.marketRole.type>A44</sender_MarketParticipant.marketRole.type>
<receiver_MarketParticipant.mRID codingScheme="A01">receiverId</receiver_MarketParticipant.mRID>
<receiver_MarketParticipant.marketRole.type>A36</receiver_MarketParticipant.marketRole.type>
<createdDateTime>2023-01-30T15:58:09Z</createdDateTime>
<time_Period.timeInterval>
<start>2019-04-01T13:09Z</start>
<end>2019-04-01T14:09Z</end>
</time_Period.timeInterval>
<TimeSeries>
<mRID>CNE_RAO_CASTOR-TimeSeries-1</mRID>
<businessType>B54</businessType>
<curveType>A01</curveType>
<Period>
<timeInterval>
<start>2021-04-02T03:00Z</start>
<end>2021-04-02T04:00Z</end>
</timeInterval>
<resolution>PT60M</resolution>
<Point>
<position>1</position>
<Constraint_Series>
<mRID>1ddcfad-29bb-4ef1-828f-ed7065fd8928</mRID>
<businessType>B56</businessType>
</Constraint_Series>
<Constraint_Series>
<mRID>db4a7e0-dde6-4cc3-9ca5-4816d6f26491</mRID>
<businessType>B56</businessType>
<Contingency_Series>
<mRID>CO_N1012_N1014</mRID>
<name>CO_N1012_N1014</name>
</Contingency_Series>
</Constraint_Series>
<Constraint_Series>
<mRID>b893392-32ed-4569-8bcf-f022fb4c5933</mRID>
<businessType>B56</businessType>
<Contingency_Series>
<mRID>CO_N1012_N4012</mRID>
<name>CO_N1012_N4012</name>
</Contingency_Series>
</Constraint_Series>
<Constraint_Series>
<mRID>ab18126-3240-4a1d-808a-2884cd09875f</mRID>
<businessType>B57</businessType>
<Monitored_Series>
<mRID>CNE_N1011_N1013</mRID>
<name>CNE_N1011_N1013</name>
<RegisteredResource>
<mRID codingScheme="A02">N1011___-N1013___-1_AC</mRID>
<name>N1011_N1013</name>
<in_AggregateNode.mRID codingScheme="A02">N1011____VL</in_AggregateNode.mRID>
<out_AggregateNode.mRID codingScheme="A02">N1013____VL</out_AggregateNode.mRID>
<Measurements>
<measurementType>A01</measurementType>
<unitSymbol>AMP</unitSymbol>
<positiveFlowIn>A02</positiveFlowIn>
<analogValues.value>1076</analogValues.value>
</Measurements>
<Measurements>
<measurementType>A02</measurementType>
<unitSymbol>AMP</unitSymbol>
<positiveFlowIn>A02</positiveFlowIn>
<analogValues.value>1000</analogValues.value>
</Measurements>
</RegisteredResource>
</Monitored_Series>
</Constraint_Series>
<Constraint_Series>
<mRID>e1fc140-be92-4ed1-bf9a-befe09ab1553</mRID>
<businessType>B57</businessType>
<Contingency_Series>
<mRID>CO_N1012_N1014</mRID>
<name>CO_N1012_N1014</name>
</Contingency_Series>
<Monitored_Series>
<mRID>CNE_N1013_N1014</mRID>
<name>CNE_N1013_N1014</name>
<RegisteredResource>
<mRID codingScheme="A02">N1013___-N1014___-1_AC</mRID>
<name>N1013_N1014</name>
<in_AggregateNode.mRID codingScheme="A02">N1013____VL</in_AggregateNode.mRID>
<out_AggregateNode.mRID codingScheme="A02">N1014____VL</out_AggregateNode.mRID>
<Measurements>
<measurementType>A01</measurementType>
<unitSymbol>AMP</unitSymbol>
<positiveFlowIn>A02</positiveFlowIn>
<analogValues.value>700</analogValues.value>
</Measurements>
<Measurements>
<measurementType>A13</measurementType>
<unitSymbol>AMP</unitSymbol>
<positiveFlowIn>A02</positiveFlowIn>
<analogValues.value>500</analogValues.value>
</Measurements>
</RegisteredResource>
</Monitored_Series>
</Constraint_Series>
<Constraint_Series>
<mRID>5ac608b-32a2-46da-b497-5eb07774e9cd</mRID>
<businessType>B57</businessType>
<Contingency_Series>
<mRID>CO_N1012_N4012</mRID>
<name>CO_N1012_N4012</name>
</Contingency_Series>
<Monitored_Series>
<mRID>CNE_N1013_N1014</mRID>
<name>CNE_N1013_N1014</name>
<RegisteredResource>
<mRID codingScheme="A02">N1013___-N1014___-1_AC</mRID>
<name>N1013_N1014</name>
<in_AggregateNode.mRID codingScheme="A02">N1013____VL</in_AggregateNode.mRID>
<out_AggregateNode.mRID codingScheme="A02">N1014____VL</out_AggregateNode.mRID>
<Measurements>
<measurementType>A01</measurementType>
<unitSymbol>AMP</unitSymbol>
<positiveFlowIn>A02</positiveFlowIn>
<analogValues.value>1919</analogValues.value>
</Measurements>
<Measurements>
<measurementType>A13</measurementType>
<unitSymbol>AMP</unitSymbol>
<positiveFlowIn>A02</positiveFlowIn>
<analogValues.value>500</analogValues.value>
</Measurements>
</RegisteredResource>
</Monitored_Series>
</Constraint_Series>
<Reason>
<code>Z13</code>
<text>Network is secure</text>
</Reason>
</Point>
</Period>
</TimeSeries>
</CriticalNetworkElement_MarketDocument>
Loading

0 comments on commit 33dc0a6

Please sign in to comment.