From f1b842357228109f5eb2e226a069ae5b81d61074 Mon Sep 17 00:00:00 2001 From: thiriondan Date: Mon, 22 Jul 2024 15:53:52 +0200 Subject: [PATCH] Set default imax values when importing curative cnec --- .../criticalbranch/CriticalBranchReader.java | 43 ++++++++++++++++--- .../creator/cse/CseCracCreatorTest.java | 16 +++++-- .../epic90_robust_crac/US90_2.feature | 2 +- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/data/crac-creation/crac-creator-cse/src/main/java/com/powsybl/openrao/data/craccreation/creator/cse/criticalbranch/CriticalBranchReader.java b/data/crac-creation/crac-creator-cse/src/main/java/com/powsybl/openrao/data/craccreation/creator/cse/criticalbranch/CriticalBranchReader.java index ddaaabffc2..d72dd1b0ac 100644 --- a/data/crac-creation/crac-creator-cse/src/main/java/com/powsybl/openrao/data/craccreation/creator/cse/criticalbranch/CriticalBranchReader.java +++ b/data/crac-creation/crac-creator-cse/src/main/java/com/powsybl/openrao/data/craccreation/creator/cse/criticalbranch/CriticalBranchReader.java @@ -104,10 +104,10 @@ public CriticalBranchReader(List tBranches, @Nullable TOutage tOutage, this.criticalBranchImportStatus = ImportStatus.INCOMPLETE_DATA; this.invalidBranchReason = String.format("CNEC is defined on outage %s which is not defined", outage); } else { - this.isImported = true; this.isDirectionInverted = branchHelper.isInvertedInNetwork(); this.selected = !isMonitored && isSelected(tBranch); if (tOutage == null) { + this.isImported = true; // preventive this.isBaseCase = true; this.contingencyId = null; @@ -117,8 +117,14 @@ public CriticalBranchReader(List tBranches, @Nullable TOutage tOutage, // curative this.isBaseCase = false; this.contingencyId = outage; - this.criticalBranchImportStatus = ImportStatus.IMPORTED; - importCurativeCnecs(tBranch, branchHelper, outage, crac, isMonitored); + if(importCurativeCnecs(tBranch, branchHelper, outage, crac, isMonitored)) { + this.criticalBranchImportStatus = ImportStatus.IMPORTED; + this.isImported = true; + } else { + this.criticalBranchImportStatus = ImportStatus.INCOMPLETE_DATA; + this.invalidBranchReason = "Incomplete Imax data to create at least one preventive CNEC for the branch."; + this.isImported = false; + } } } } @@ -134,12 +140,37 @@ private void importPreventiveCnec(TBranch tBranch, UcteFlowElementHelper branchH importCnec(crac, tBranch, branchHelper, isMonitored ? tBranch.getIlimitMNE() : tBranch.getImax(), null, crac.getPreventiveInstant().getId(), isMonitored); } - private void importCurativeCnecs(TBranch tBranch, UcteFlowElementHelper branchHelper, String outage, Crac crac, boolean isMonitored) { + /** + * Returns true if at least one CNEC has been correctly imported. + * @param tBranch + * @param branchHelper + * @param outage + * @param crac + * @param isMonitored + * @return + */ + private boolean importCurativeCnecs(TBranch tBranch, UcteFlowElementHelper branchHelper, String outage, Crac crac, boolean isMonitored) { HashMap cnecCaracs = new HashMap<>(); cnecCaracs.put(crac.getOutageInstant(), isMonitored ? tBranch.getIlimitMNEAfterOutage() : tBranch.getImaxAfterOutage()); - cnecCaracs.put(crac.getInstant(InstantKind.AUTO), isMonitored ? tBranch.getIlimitMNEAfterSPS() : tBranch.getImaxAfterSPS()); - cnecCaracs.put(crac.getInstant(InstantKind.CURATIVE), isMonitored ? tBranch.getIlimitMNEAfterCRA() : tBranch.getImaxAfterCRA()); + cnecCaracs.put(crac.getInstant(InstantKind.AUTO), isMonitored ? tBranch.getIlimitMNEAfterSPS() : findTargetImaxAfterSPS(tBranch)); + cnecCaracs.put(crac.getInstant(InstantKind.CURATIVE), isMonitored ? tBranch.getIlimitMNEAfterCRA() : findTargetImaxAfterCRA(tBranch.getImaxAfterCRA())); cnecCaracs.forEach((instant, iMax) -> importCnec(crac, tBranch, branchHelper, iMax, outage, instant.getId(), isMonitored)); + return cnecCaracs.values().stream().anyMatch(Objects::nonNull); + } + + private TImax findTargetImaxAfterCRA(final TImax imaxAfterCRA) { + return imaxAfterCRA != null ? imaxAfterCRA : createDefaultImaxAfterCRA(); + } + + private TImax createDefaultImaxAfterCRA() { + final TImax tempImax = new TImax(); + tempImax.setUnit("Pct"); + tempImax.setV((short) 100); + return tempImax; + } + + private TImax findTargetImaxAfterSPS(final TBranch tBranch) { + return tBranch.getImaxAfterSPS() != null ? tBranch.getImaxAfterSPS() : tBranch.getImaxAfterOutage(); } private void importCnec(Crac crac, TBranch tBranch, UcteFlowElementHelper branchHelper, @Nullable TImax tImax, String outage, String instantId, boolean isMonitored) { diff --git a/data/crac-creation/crac-creator-cse/src/test/java/com/powsybl/openrao/data/craccreation/creator/cse/CseCracCreatorTest.java b/data/crac-creation/crac-creator-cse/src/test/java/com/powsybl/openrao/data/craccreation/creator/cse/CseCracCreatorTest.java index ddeab39dac..bc79834d0f 100644 --- a/data/crac-creation/crac-creator-cse/src/test/java/com/powsybl/openrao/data/craccreation/creator/cse/CseCracCreatorTest.java +++ b/data/crac-creation/crac-creator-cse/src/test/java/com/powsybl/openrao/data/craccreation/creator/cse/CseCracCreatorTest.java @@ -48,6 +48,7 @@ class CseCracCreatorTest { private static final String PREVENTIVE_INSTANT_ID = "preventive"; private static final String OUTAGE_INSTANT_ID = "outage"; private static final String CURATIVE_INSTANT_ID = "curative"; + private static final String AUTO_INSTANT_ID = "auto"; private final OffsetDateTime offsetDateTime = null; private CracCreationParameters parameters = new CracCreationParameters(); @@ -226,9 +227,10 @@ void createCurativeCnecs() throws IOException { assertTrue(cnec2context.isImported()); assertFalse(cnec2context.isDirectionInvertedInNetwork()); assertEquals("outage_1", cnec2context.getContingencyId().get()); - assertEquals(2, cnec2context.getCreatedCnecsIds().size()); + assertEquals(3, cnec2context.getCreatedCnecsIds().size()); assertEquals("French line 1 - FFR1AA1 ->FFR2AA1 - outage_1 - outage", cnec2context.getCreatedCnecsIds().get(OUTAGE_INSTANT_ID)); assertEquals("French line 1 - FFR1AA1 ->FFR2AA1 - outage_1 - curative", cnec2context.getCreatedCnecsIds().get(CURATIVE_INSTANT_ID)); + assertEquals("French line 1 - FFR1AA1 ->FFR2AA1 - outage_1 - auto", cnec2context.getCreatedCnecsIds().get(AUTO_INSTANT_ID)); } @Test @@ -323,22 +325,28 @@ void testRaOnConstraint() throws IOException { FlowCnec outageCnec = importedCrac.getFlowCnec("French line 1 - FFR1AA1 ->FFR2AA1 - outage_1 - outage"); FlowCnec curativeCnec = importedCrac.getFlowCnec("French line 1 - FFR1AA1 ->FFR2AA1 - outage_1 - curative"); + FlowCnec autoCnec = importedCrac.getFlowCnec("French line 1 - FFR1AA1 ->FFR2AA1 - outage_1 - auto"); // PRA RemedialAction ra = importedCrac.getRangeAction("PST_pra_3_BBE2AA1 BBE3AA1 1"); - assertEquals(2, ra.getUsageRules().size()); + assertEquals(3, ra.getUsageRules().size()); List usageRuleList = ra.getUsageRules().stream().toList(); UsageRule usageRule1 = usageRuleList.get(0); UsageRule usageRule2 = usageRuleList.get(1); + UsageRule usageRule3 = usageRuleList.get(2); assertTrue(usageRule1 instanceof OnConstraint); assertTrue(usageRule2 instanceof OnConstraint); + assertTrue(usageRule3 instanceof OnConstraint); assertEquals(preventiveInstant, usageRule1.getInstant()); assertEquals(preventiveInstant, usageRule2.getInstant()); - assertTrue(((OnConstraint) usageRule1).getCnec().equals(outageCnec) || ((OnConstraint) usageRule2).getCnec().equals(outageCnec)); - assertTrue(((OnConstraint) usageRule1).getCnec().equals(curativeCnec) || ((OnConstraint) usageRule2).getCnec().equals(curativeCnec)); + assertEquals(preventiveInstant, usageRule3.getInstant()); + assertTrue(((OnConstraint) usageRule1).getCnec().equals(outageCnec) || ((OnConstraint) usageRule2).getCnec().equals(outageCnec) || ((OnConstraint) usageRule3).getCnec().equals(outageCnec)); + assertTrue(((OnConstraint) usageRule1).getCnec().equals(curativeCnec) || ((OnConstraint) usageRule2).getCnec().equals(curativeCnec) || ((OnConstraint) usageRule3).getCnec().equals(curativeCnec)); + assertTrue(((OnConstraint) usageRule1).getCnec().equals(autoCnec) || ((OnConstraint) usageRule2).getCnec().equals(autoCnec) || ((OnConstraint) usageRule3).getCnec().equals(autoCnec)); System.out.println(usageRule1.getUsageMethod(preventiveState)); System.out.println(usageRule2.getUsageMethod(preventiveState)); + System.out.println(usageRule3.getUsageMethod(preventiveState)); assertEquals(UsageMethod.AVAILABLE, usageRule1.getUsageMethod(preventiveState)); assertEquals(UsageMethod.AVAILABLE, usageRule2.getUsageMethod(preventiveState)); assertEquals(UsageMethod.UNDEFINED, usageRule1.getUsageMethod(outageState)); diff --git a/tests/src/test/resources/com/powsybl/openrao/tests/features/epic90_robust_crac/US90_2.feature b/tests/src/test/resources/com/powsybl/openrao/tests/features/epic90_robust_crac/US90_2.feature index 72bee05fec..5c13579889 100644 --- a/tests/src/test/resources/com/powsybl/openrao/tests/features/epic90_robust_crac/US90_2.feature +++ b/tests/src/test/resources/com/powsybl/openrao/tests/features/epic90_robust_crac/US90_2.feature @@ -20,7 +20,7 @@ Feature: US 90.2: asterisks* as wildcards in UCTE CRACs importers Given network file is "crac90/TestCase_severalVoltageLevels_Xnodes_8characters.uct" Given crac file is "crac90/cseCrac_ep90us2case2.xml" When I import crac - Then it should have 8 cnecs + Then it should have 11 cnecs And the native CNEC "basecase_branch_3 - DDE1AA1* - DDE2AA1* - basecase" should not be imported And the native CNEC "basecase_branch_4 - XFRDE111 - FFR2AA12 - basecase" should not be imported And the native remedial action "cra_2" should not be imported because of "INCONSISTENCY_IN_DATA"