RangeActionActivationResultImplTest.java
/*
* Copyright (c) 2021, 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.result.impl;
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.rangeaction.HvdcRangeAction;
import com.powsybl.openrao.data.crac.api.rangeaction.InjectionRangeAction;
import com.powsybl.openrao.data.crac.api.rangeaction.PstRangeAction;
import com.powsybl.openrao.data.crac.api.usagerule.UsageMethod;
import com.powsybl.openrao.data.crac.impl.utils.CommonCracCreation;
import com.powsybl.openrao.searchtreerao.result.api.RangeActionSetpointResult;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Map;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Joris Mancini {@literal <joris.mancini at rte-france.com>}
*/
class RangeActionActivationResultImplTest {
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 CURATIVE_INSTANT_ID = "curative";
private PstRangeAction pstRangeAction1;
private PstRangeAction pstRangeAction2; // 1 on 2 are on the same PST
private PstRangeAction pstRangeAction3;
private State pState;
private State oState1;
private State cState1;
private State cState2;
private RangeActionSetpointResult rangeActionSetpointResult;
@BeforeEach
public void setUp() {
Crac crac = CommonCracCreation.create();
Instant outageInstant = crac.getInstant(OUTAGE_INSTANT_ID);
Instant curativeInstant = crac.getInstant(CURATIVE_INSTANT_ID);
crac.newFlowCnec()
.withId("cnecOnOutageState1")
.withNetworkElement("BBE2AA1 FFR3AA1 1")
.withInstant(OUTAGE_INSTANT_ID)
.withContingency("Contingency FR1 FR3")
.newThreshold().withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).withMin(-1500.).withMax(1500.).add()
.add();
pState = crac.getPreventiveState();
oState1 = crac.getState("Contingency FR1 FR3", outageInstant);
cState1 = crac.getState("Contingency FR1 FR3", curativeInstant);
cState2 = crac.getState("Contingency FR1 FR2", curativeInstant);
pstRangeAction1 = crac.newPstRangeAction()
.withId("pst1")
.withNetworkElement("BBE2AA1 BBE3AA1 1")
.newOnInstantUsageRule().withInstant(PREVENTIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.newOnInstantUsageRule().withInstant(CURATIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(-3, -3.1, -2, -2.1, -1, -1.1, 0, 0., 1, 1.1, 2, 2.1, 3, 3.1))
.add();
pstRangeAction2 = crac.newPstRangeAction()
.withId("pst2")
.withNetworkElement("BBE2AA1 BBE3AA1 1")
.newOnInstantUsageRule().withInstant(PREVENTIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.newOnInstantUsageRule().withInstant(CURATIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(-3, -3.1, -2, -2.1, -1, -1.1, 0, 0., 1, 1.1, 2, 2.1, 3, 3.1))
.add();
pstRangeAction3 = crac.newPstRangeAction()
.withId("pst3")
.withNetworkElement("anotherPst")
.newOnInstantUsageRule().withInstant(PREVENTIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.newOnInstantUsageRule().withInstant(CURATIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(-3, -3.1, -2, -2.1, -1, -1.1, 0, 0., 1, 1.1, 2, 2.1, 3, 3.1))
.add();
rangeActionSetpointResult = new RangeActionSetpointResultImpl(Map.of(
pstRangeAction1, 0.,
pstRangeAction2, 0.,
pstRangeAction3, -2.1));
}
@Test
void test1() {
// pstRangeAction1 is activated in preventive, pstRangeAction3 is activated in curative
RangeActionActivationResultImpl raar = new RangeActionActivationResultImpl(rangeActionSetpointResult);
raar.putResult(pstRangeAction1, pState, 1.1);
raar.putResult(pstRangeAction3, pState, -2.1); // should not be taken into account as activation with same setpoint as reference
raar.putResult(pstRangeAction3, cState2, -1.1);
// pstRangeAction1
assertEquals(1.1, raar.getOptimizedSetpoint(pstRangeAction1, pState), DOUBLE_TOLERANCE);
assertEquals(1.1, raar.getOptimizedSetpoint(pstRangeAction1, oState1), DOUBLE_TOLERANCE);
assertEquals(1.1, raar.getOptimizedSetpoint(pstRangeAction1, cState1), DOUBLE_TOLERANCE);
assertEquals(1.1, raar.getOptimizedSetpoint(pstRangeAction1, cState2), DOUBLE_TOLERANCE);
assertEquals(1, raar.getOptimizedTap(pstRangeAction1, pState), DOUBLE_TOLERANCE);
assertEquals(1, raar.getOptimizedTap(pstRangeAction1, oState1), DOUBLE_TOLERANCE);
assertEquals(1, raar.getOptimizedTap(pstRangeAction1, cState1), DOUBLE_TOLERANCE);
assertEquals(1, raar.getOptimizedTap(pstRangeAction1, cState2), DOUBLE_TOLERANCE);
// pstRangeAction2 (same as RA 1, as same PST)
assertEquals(1.1, raar.getOptimizedSetpoint(pstRangeAction2, pState), DOUBLE_TOLERANCE);
assertEquals(1.1, raar.getOptimizedSetpoint(pstRangeAction2, oState1), DOUBLE_TOLERANCE);
assertEquals(1.1, raar.getOptimizedSetpoint(pstRangeAction2, cState1), DOUBLE_TOLERANCE);
assertEquals(1.1, raar.getOptimizedSetpoint(pstRangeAction2, cState2), DOUBLE_TOLERANCE);
assertEquals(1, raar.getOptimizedTap(pstRangeAction2, pState), DOUBLE_TOLERANCE);
assertEquals(1, raar.getOptimizedTap(pstRangeAction2, oState1), DOUBLE_TOLERANCE);
assertEquals(1, raar.getOptimizedTap(pstRangeAction2, cState1), DOUBLE_TOLERANCE);
assertEquals(1, raar.getOptimizedTap(pstRangeAction2, cState2), DOUBLE_TOLERANCE);
// pstRangeAction3, activated in cState2
assertEquals(-2.1, raar.getOptimizedSetpoint(pstRangeAction3, pState), DOUBLE_TOLERANCE);
assertEquals(-2.1, raar.getOptimizedSetpoint(pstRangeAction3, oState1), DOUBLE_TOLERANCE);
assertEquals(-2.1, raar.getOptimizedSetpoint(pstRangeAction3, cState1), DOUBLE_TOLERANCE);
assertEquals(-1.1, raar.getOptimizedSetpoint(pstRangeAction3, cState2), DOUBLE_TOLERANCE);
assertEquals(-2, raar.getOptimizedTap(pstRangeAction3, pState), DOUBLE_TOLERANCE);
assertEquals(-2, raar.getOptimizedTap(pstRangeAction3, oState1), DOUBLE_TOLERANCE);
assertEquals(-2, raar.getOptimizedTap(pstRangeAction3, cState1), DOUBLE_TOLERANCE);
assertEquals(-1, raar.getOptimizedTap(pstRangeAction3, cState2), DOUBLE_TOLERANCE);
// activations
// both pstRangeAction1 and pstRangeAction2 have tap which change in the preventive state
// but only the pstRangeAction1 is explicitly activated
// it is a classic example of a PRA and a CRA on a same PST
assertEquals(Set.of(pstRangeAction1), raar.getActivatedRangeActions(pState));
assertEquals(Set.of(), raar.getActivatedRangeActions(oState1));
assertEquals(Set.of(), raar.getActivatedRangeActions(cState1));
assertEquals(Set.of(pstRangeAction3), raar.getActivatedRangeActions(cState2));
// tap and setpoint per State
assertEquals(Map.of(pstRangeAction1, 1.1, pstRangeAction2, 1.1, pstRangeAction3, -2.1), raar.getOptimizedSetpointsOnState(pState));
assertEquals(Map.of(pstRangeAction1, 1.1, pstRangeAction2, 1.1, pstRangeAction3, -1.1), raar.getOptimizedSetpointsOnState(cState2));
assertEquals(Map.of(pstRangeAction1, 1, pstRangeAction2, 1, pstRangeAction3, -2), raar.getOptimizedTapsOnState(pState));
assertEquals(Map.of(pstRangeAction1, 1, pstRangeAction2, 1, pstRangeAction3, -1), raar.getOptimizedTapsOnState(cState2));
}
@Test
void test2() {
// pstRangeAction1 is activated in preventive,
// pstRangeAction2, on same PST, is activated in curative
// pstRangeAction3 is activated in preventive and in both curative states
RangeActionActivationResultImpl raar = new RangeActionActivationResultImpl(rangeActionSetpointResult);
raar.putResult(pstRangeAction1, pState, 3.1);
raar.putResult(pstRangeAction1, cState2, 3.1); //should not be taken into account as activation with same setpoint as previous instant
raar.putResult(pstRangeAction2, cState1, 2.1);
raar.putResult(pstRangeAction2, cState2, 3.1); //should not be taken into account as activation with same setpoint as previous instant
raar.putResult(pstRangeAction3, pState, 0.0);
raar.putResult(pstRangeAction3, cState1, -3.1);
raar.putResult(pstRangeAction3, cState2, -2.1); //come back to initial tap, but diff compared to preventive
// pstRangeAction1
assertEquals(3.1, raar.getOptimizedSetpoint(pstRangeAction1, pState), DOUBLE_TOLERANCE);
assertEquals(3.1, raar.getOptimizedSetpoint(pstRangeAction1, oState1), DOUBLE_TOLERANCE);
assertEquals(2.1, raar.getOptimizedSetpoint(pstRangeAction1, cState1), DOUBLE_TOLERANCE);
assertEquals(3.1, raar.getOptimizedSetpoint(pstRangeAction1, cState2), DOUBLE_TOLERANCE);
assertEquals(3, raar.getOptimizedTap(pstRangeAction1, pState), DOUBLE_TOLERANCE);
assertEquals(3, raar.getOptimizedTap(pstRangeAction1, oState1), DOUBLE_TOLERANCE);
assertEquals(2, raar.getOptimizedTap(pstRangeAction1, cState1), DOUBLE_TOLERANCE);
assertEquals(3, raar.getOptimizedTap(pstRangeAction1, cState2), DOUBLE_TOLERANCE);
// pstRangeAction2 (same as RA 1, as same PST)
assertEquals(3.1, raar.getOptimizedSetpoint(pstRangeAction2, pState), DOUBLE_TOLERANCE);
assertEquals(3.1, raar.getOptimizedSetpoint(pstRangeAction2, oState1), DOUBLE_TOLERANCE);
assertEquals(2.1, raar.getOptimizedSetpoint(pstRangeAction2, cState1), DOUBLE_TOLERANCE);
assertEquals(3.1, raar.getOptimizedSetpoint(pstRangeAction2, cState2), DOUBLE_TOLERANCE);
assertEquals(3, raar.getOptimizedTap(pstRangeAction2, pState), DOUBLE_TOLERANCE);
assertEquals(3, raar.getOptimizedTap(pstRangeAction2, oState1), DOUBLE_TOLERANCE);
assertEquals(2, raar.getOptimizedTap(pstRangeAction2, cState1), DOUBLE_TOLERANCE);
assertEquals(3, raar.getOptimizedTap(pstRangeAction2, cState2), DOUBLE_TOLERANCE);
// pstRangeAction3, activated in cState2
assertEquals(0.0, raar.getOptimizedSetpoint(pstRangeAction3, pState), DOUBLE_TOLERANCE);
assertEquals(0.0, raar.getOptimizedSetpoint(pstRangeAction3, oState1), DOUBLE_TOLERANCE);
assertEquals(-3.1, raar.getOptimizedSetpoint(pstRangeAction3, cState1), DOUBLE_TOLERANCE);
assertEquals(-2.1, raar.getOptimizedSetpoint(pstRangeAction3, cState2), DOUBLE_TOLERANCE);
assertEquals(0, raar.getOptimizedTap(pstRangeAction3, pState), DOUBLE_TOLERANCE);
assertEquals(0, raar.getOptimizedTap(pstRangeAction3, oState1), DOUBLE_TOLERANCE);
assertEquals(-3, raar.getOptimizedTap(pstRangeAction3, cState1), DOUBLE_TOLERANCE);
assertEquals(-2, raar.getOptimizedTap(pstRangeAction3, cState2), DOUBLE_TOLERANCE);
// activations
assertEquals(Set.of(pstRangeAction1, pstRangeAction3), raar.getActivatedRangeActions(pState));
assertEquals(Set.of(), raar.getActivatedRangeActions(oState1));
assertEquals(Set.of(pstRangeAction2, pstRangeAction3), raar.getActivatedRangeActions(cState1));
assertEquals(Set.of(pstRangeAction3), raar.getActivatedRangeActions(cState2));
// tap and setpoint per State
assertEquals(Map.of(pstRangeAction1, 3.1, pstRangeAction2, 3.1, pstRangeAction3, 0.0), raar.getOptimizedSetpointsOnState(pState));
assertEquals(Map.of(pstRangeAction1, 2.1, pstRangeAction2, 2.1, pstRangeAction3, -3.1), raar.getOptimizedSetpointsOnState(cState1));
assertEquals(Map.of(pstRangeAction1, 3, pstRangeAction2, 3, pstRangeAction3, 0), raar.getOptimizedTapsOnState(pState));
assertEquals(Map.of(pstRangeAction1, 2, pstRangeAction2, 2, pstRangeAction3, -3), raar.getOptimizedTapsOnState(cState1));
}
@Test
void testRangeActionsVariation() {
Crac crac = CommonCracCreation.create();
State state = crac.getState(crac.getContingency("Contingency FR1 FR3"), crac.getInstant(InstantKind.CURATIVE));
PstRangeAction pstRangeAction = crac.newPstRangeAction()
.withId("pst-range-action")
.withNetworkElement("pst")
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(-1, -6.22, 0, 0d, 1, 6.22))
.add();
InjectionRangeAction injectionRangeAction1 = crac.newInjectionRangeAction()
.withId("injection-range-action-1")
.withInitialSetpoint(50d)
.withNetworkElementAndKey(1d, "generator")
.newRange()
.withMin(0d)
.withMax(100d)
.add()
.add();
InjectionRangeAction injectionRangeAction2 = crac.newInjectionRangeAction()
.withId("injection-range-action-2")
.withInitialSetpoint(25d)
.withNetworkElementAndKey(1d, "load")
.newRange()
.withMin(10d)
.withMax(75d)
.add()
.add();
HvdcRangeAction hvdcRangeAction = crac.newHvdcRangeAction()
.withId("hvdc-range-action")
.withInitialSetpoint(0d)
.withNetworkElement("hvdc")
.newRange()
.withMin(-1000d)
.withMax(1000d)
.add()
.add();
RangeActionSetpointResult setPointResult = new RangeActionSetpointResultImpl(Map.of(
pstRangeAction, 0d,
injectionRangeAction1, 60d,
injectionRangeAction2, 25d,
hvdcRangeAction, 300d));
RangeActionActivationResultImpl rangeActionActivationResult = new RangeActionActivationResultImpl(setPointResult);
rangeActionActivationResult.putResult(pstRangeAction, state, -6.22);
rangeActionActivationResult.putResult(injectionRangeAction1, state, 75d);
rangeActionActivationResult.putResult(injectionRangeAction2, state, 25d);
rangeActionActivationResult.putResult(hvdcRangeAction, state, 800d);
assertEquals(-1, rangeActionActivationResult.getTapVariation(pstRangeAction, state));
assertEquals(-6.22, rangeActionActivationResult.getSetPointVariation(pstRangeAction, state));
assertEquals(15d, rangeActionActivationResult.getSetPointVariation(injectionRangeAction1, state));
assertEquals(0d, rangeActionActivationResult.getSetPointVariation(injectionRangeAction2, state));
assertEquals(500d, rangeActionActivationResult.getSetPointVariation(hvdcRangeAction, state));
}
}