AutoOptimizationPerimeterTest.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.searchtreerao.commons.optimizationperimeters;
import com.powsybl.contingency.ContingencyElementType;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.api.Instant;
import com.powsybl.openrao.data.crac.api.InstantKind;
import com.powsybl.openrao.data.crac.api.State;
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.openrao.data.crac.api.networkaction.ActionType;
import com.powsybl.openrao.data.crac.api.networkaction.NetworkAction;
import com.powsybl.openrao.data.crac.api.usagerule.UsageMethod;
import com.powsybl.openrao.data.crac.impl.CracImplFactory;
import com.powsybl.openrao.raoapi.parameters.RaoParameters;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.util.Map;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* @author Thomas Bouquet {@literal <thomas.bouquet at rte-france.com>}
*/
class AutoOptimizationPerimeterTest {
@Test
void nonAutoState() {
Instant preventiveInstant = Mockito.mock(Instant.class);
Mockito.when(preventiveInstant.isAuto()).thenReturn(false);
State preventiveState = Mockito.mock(State.class);
Mockito.when(preventiveState.getInstant()).thenReturn(preventiveInstant);
Set<FlowCnec> emptyFlowCnecSet = Set.of();
Set<NetworkAction> emptyNetworkActionSet = Set.of();
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> new AutoOptimizationPerimeter(preventiveState, emptyFlowCnecSet, emptyFlowCnecSet, emptyNetworkActionSet));
assertEquals("an AutoOptimizationPerimeter must be based on an auto state", exception.getMessage());
}
@Test
void buildAutoOptimizationPerimeter() {
Crac crac = initCrac();
State automatonState = crac.getState("contingency", crac.getInstant("auto"));
AutoOptimizationPerimeter autoOptimizationPerimeter = AutoOptimizationPerimeter.build(automatonState, crac, null, new RaoParameters(), null);
// Only available topological actions are considered in the perimeter
assertEquals(automatonState, autoOptimizationPerimeter.getMainOptimizationState());
assertEquals(Set.of(automatonState), autoOptimizationPerimeter.getMonitoredStates());
assertEquals(Set.of(crac.getFlowCnec("FlowCNEC - auto")), autoOptimizationPerimeter.getFlowCnecs());
assertEquals(Set.of(crac.getNetworkAction("available-topo")), autoOptimizationPerimeter.getNetworkActions());
assertEquals(Set.of(), autoOptimizationPerimeter.getRangeActions());
}
private Crac initCrac() {
Crac crac = new CracImplFactory().create("crac");
crac.newInstant("preventive", InstantKind.PREVENTIVE)
.newInstant("outage", InstantKind.OUTAGE)
.newInstant("auto", InstantKind.AUTO)
.newInstant("curative", InstantKind.CURATIVE);
crac.newContingency()
.withId("contingency")
.withContingencyElement("contingency-equipment", ContingencyElementType.LINE)
.add();
crac.newFlowCnec()
.withId("FlowCNEC - preventive")
.withOptimized(true)
.withInstant("preventive")
.withNetworkElement("line")
.withNominalVoltage(400)
.newThreshold()
.withSide(TwoSides.ONE)
.withMin(-1000d)
.withMax(1000d)
.withUnit(Unit.AMPERE)
.add()
.add();
crac.newFlowCnec()
.withId("FlowCNEC - outage")
.withOptimized(true)
.withInstant("outage")
.withContingency("contingency")
.withNetworkElement("line")
.withNominalVoltage(400)
.newThreshold()
.withSide(TwoSides.ONE)
.withMin(-2500d)
.withMax(2500d)
.withUnit(Unit.AMPERE)
.add()
.add();
crac.newFlowCnec()
.withId("FlowCNEC - auto")
.withOptimized(true)
.withInstant("auto")
.withContingency("contingency")
.withNetworkElement("line")
.withNominalVoltage(400)
.newThreshold()
.withSide(TwoSides.ONE)
.withMin(-1500d)
.withMax(1500d)
.withUnit(Unit.AMPERE)
.add()
.add();
crac.newFlowCnec()
.withId("FlowCNEC - curative")
.withOptimized(true)
.withInstant("curative")
.withContingency("contingency")
.withNetworkElement("line")
.withNominalVoltage(400)
.newThreshold()
.withSide(TwoSides.ONE)
.withMin(-1000d)
.withMax(1000d)
.withUnit(Unit.AMPERE)
.add()
.add();
crac.newNetworkAction()
.withId("forced-topo")
.withOperator("FR")
.newSwitchAction()
.withNetworkElement("switch-1")
.withActionType(ActionType.OPEN)
.add()
.newOnContingencyStateUsageRule()
.withContingency("contingency")
.withInstant("auto")
.withUsageMethod(UsageMethod.FORCED)
.add()
.add();
crac.newNetworkAction()
.withId("available-topo")
.withOperator("FR")
.newSwitchAction()
.withNetworkElement("switch-2")
.withActionType(ActionType.OPEN)
.add()
.newOnContingencyStateUsageRule()
.withContingency("contingency")
.withInstant("auto")
.withUsageMethod(UsageMethod.AVAILABLE)
.add()
.add();
crac.newPstRangeAction()
.withId("forced-pst")
.withOperator("FR")
.withNetworkElement("pst-1")
.withSpeed(1)
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(0, 0d, 1, 2.34))
.newOnContingencyStateUsageRule()
.withContingency("contingency")
.withInstant("auto")
.withUsageMethod(UsageMethod.FORCED)
.add()
.add();
crac.newPstRangeAction()
.withId("available-pst")
.withOperator("FR")
.withNetworkElement("pst-2")
.withSpeed(2)
.withInitialTap(1)
.withTapToAngleConversionMap(Map.of(0, 0d, 1, 2.34))
.newOnContingencyStateUsageRule()
.withContingency("contingency")
.withInstant("auto")
.withUsageMethod(UsageMethod.AVAILABLE)
.add()
.add();
return crac;
}
}