MarmotUtilsTest.java
/*
* Copyright (c) 2025, 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.marmot;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openrao.commons.TemporalData;
import com.powsybl.openrao.commons.TemporalDataImpl;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.openrao.data.crac.api.rangeaction.PstRangeAction;
import com.powsybl.openrao.data.crac.api.rangeaction.RangeAction;
import com.powsybl.openrao.data.raoresult.api.RaoResult;
import com.powsybl.openrao.raoapi.RaoInput;
import com.powsybl.openrao.raoapi.parameters.RaoParameters;
import com.powsybl.openrao.raoapi.parameters.extensions.OpenRaoSearchTreeParameters;
import com.powsybl.openrao.searchtreerao.marmot.results.GlobalLinearOptimizationResult;
import com.powsybl.openrao.searchtreerao.result.api.FlowResult;
import com.powsybl.openrao.searchtreerao.result.api.PrePerimeterResult;
import com.powsybl.openrao.searchtreerao.result.api.RangeActionSetpointResult;
import com.powsybl.openrao.searchtreerao.result.api.SensitivityResult;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.io.IOException;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.powsybl.openrao.searchtreerao.marmot.MarmotUtils.getPostOptimizationResults;
import static com.powsybl.openrao.searchtreerao.marmot.MarmotUtils.getPreventivePerimeterCnecs;
import static com.powsybl.openrao.searchtreerao.marmot.MarmotUtils.getTopologicalOptimizationResult;
import static com.powsybl.openrao.searchtreerao.marmot.MarmotUtils.runSensitivityAnalysis;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Thomas Bouquet {@literal <thomas.bouquet at rte-france.com>}
* @author Roxane Chen {@literal <roxane.chen at rte-france.com>}
*/
class MarmotUtilsTest {
private Crac crac1;
private Crac crac2;
private Crac crac3;
private final OffsetDateTime timestamp1 = OffsetDateTime.of(2024, 12, 10, 16, 21, 0, 0, ZoneOffset.UTC);
private final OffsetDateTime timestamp2 = OffsetDateTime.of(2024, 12, 10, 17, 21, 0, 0, ZoneOffset.UTC);
private final OffsetDateTime timestamp3 = OffsetDateTime.of(2024, 12, 10, 18, 21, 0, 0, ZoneOffset.UTC);
RaoParameters parameters;
TemporalData<RaoInput> inputs;
private static final double DOUBLE_TOLERANCE = 1e-4;
private static final double AMPERE_MEGAWATT_TOLERANCE = 1.0;
@BeforeEach
void setUp() throws IOException {
Network network1 = Network.read("12Nodes_2_pst.uct", MarmotUtilsTest.class.getResourceAsStream("/network/12Nodes_2_pst.uct"));
Network network2 = Network.read("12Nodes_2_pst.uct", MarmotUtilsTest.class.getResourceAsStream("/network/12Nodes_2_pst.uct"));
Network network3 = Network.read("12Nodes_2_pst.uct", MarmotUtilsTest.class.getResourceAsStream("/network/12Nodes_2_pst.uct"));
crac1 = Crac.read("small-crac-2pst-1600.json", MarmotUtilsTest.class.getResourceAsStream("/crac/small-crac-2pst-1600.json"), network1);
crac2 = Crac.read("small-crac-2pst-1700.json", MarmotUtilsTest.class.getResourceAsStream("/crac/small-crac-2pst-1700.json"), network2);
crac3 = Crac.read("small-crac-2pst-1800.json", MarmotUtilsTest.class.getResourceAsStream("/crac/small-crac-2pst-1800.json"), network3);
RaoInput raoInput1 = RaoInput.build(network1, crac1).build();
RaoInput raoInput2 = RaoInput.build(network2, crac2).build();
RaoInput raoInput3 = RaoInput.build(network3, crac3).build();
inputs = new TemporalDataImpl<>(Map.of(timestamp1, raoInput1, timestamp2, raoInput2, timestamp3, raoInput3));
parameters = new RaoParameters();
parameters.addExtension(OpenRaoSearchTreeParameters.class, new OpenRaoSearchTreeParameters());
parameters.getExtension(OpenRaoSearchTreeParameters.class).getLoadFlowAndSensitivityParameters().getSensitivityWithLoadFlowParameters().getLoadFlowParameters().setDc(true);
}
@Test
void testGetPreventivePerimeterCnecs() {
FlowCnec preventiveCnecTimestamp1 = crac1.getFlowCnec("cnecDeNlPrev - 1600");
FlowCnec outageCnecTimestamp1 = crac1.getFlowCnec("cnecDeNlOut - 1600");
assertEquals(Set.of(preventiveCnecTimestamp1, outageCnecTimestamp1), getPreventivePerimeterCnecs(crac1));
}
@Test
void testRunInitialSensitivityAnalysis() {
FlowCnec preventiveCnecTimestamp1 = crac1.getFlowCnec("cnecDeNlPrev - 1600");
FlowCnec outageCnecTimestamp1 = crac1.getFlowCnec("cnecDeNlOut - 1600");
FlowCnec preventiveCnecTimestamp2 = crac2.getFlowCnec("cnecDeNlPrev - 1700");
FlowCnec outageCnecTimestamp2 = crac2.getFlowCnec("cnecDeNlOut - 1700");
FlowCnec preventiveCnecTimestamp3 = crac3.getFlowCnec("cnecDeNlPrev - 1800");
FlowCnec outageCnecTimestamp3 = crac3.getFlowCnec("cnecDeNlOut - 1800");
RangeAction<?> pstBeTimestamp1 = crac1.getRangeAction("pstBe - 1600");
RangeAction<?> pstBeTimestamp2 = crac2.getRangeAction("pstBe - 1700");
RangeAction<?> pstBeTimestamp3 = crac3.getRangeAction("pstBe - 1800");
RangeAction<?> pstDeTimestamp3 = crac3.getRangeAction("pstDe - 1800");
// Timestamp 1
PrePerimeterResult prePerimeterResult1 = runSensitivityAnalysis(inputs.getData(timestamp1).get(), parameters);
FlowResult flowResultTimestamp1 = prePerimeterResult1.getFlowResult();
assertFlowValueMw(flowResultTimestamp1, preventiveCnecTimestamp1, -382.0);
assertFlowValueMw(flowResultTimestamp1, outageCnecTimestamp1, -1000.0);
SensitivityResult sensitivityResultTimestamp1 = prePerimeterResult1.getSensitivityResult();
assertSensitivityValue(sensitivityResultTimestamp1, preventiveCnecTimestamp1, pstBeTimestamp1, 25.202534);
assertSensitivityValue(sensitivityResultTimestamp1, outageCnecTimestamp1, pstBeTimestamp1, 0.0);
RangeActionSetpointResult setPointResultTimestamp1 = prePerimeterResult1.getRangeActionSetpointResult();
assertEquals(12, setPointResultTimestamp1.getTap((PstRangeAction) pstBeTimestamp1));
// Timestamp 2
PrePerimeterResult prePerimeterResult2 = runSensitivityAnalysis(inputs.getData(timestamp2).get(), parameters);
FlowResult flowResultTimestamp2 = prePerimeterResult2.getFlowResult();
assertFlowValueMw(flowResultTimestamp2, preventiveCnecTimestamp2, -382.0);
assertFlowValueMw(flowResultTimestamp2, outageCnecTimestamp2, -1000.0);
SensitivityResult sensitivityResultTimestamp2 = prePerimeterResult2.getSensitivityResult();
assertSensitivityValue(sensitivityResultTimestamp2, preventiveCnecTimestamp2, pstBeTimestamp2, 25.202534);
assertSensitivityValue(sensitivityResultTimestamp2, outageCnecTimestamp2, pstBeTimestamp2, 0.0);
RangeActionSetpointResult setPointResultTimestamp2 = prePerimeterResult2.getRangeActionSetpointResult();
assertEquals(12, setPointResultTimestamp2.getTap((PstRangeAction) pstBeTimestamp2));
// Timestamp 3
PrePerimeterResult prePerimeterResult3 = runSensitivityAnalysis(inputs.getData(timestamp3).get(), parameters);
FlowResult flowResultTimestamp3 = prePerimeterResult3.getFlowResult();
assertFlowValueMw(flowResultTimestamp3, preventiveCnecTimestamp3, -382.0);
assertFlowValueMw(flowResultTimestamp3, outageCnecTimestamp3, -1000.0);
SensitivityResult sensitivityResultTimestamp3 = prePerimeterResult3.getSensitivityResult();
assertSensitivityValue(sensitivityResultTimestamp3, preventiveCnecTimestamp3, pstBeTimestamp3, 25.202534);
assertSensitivityValue(sensitivityResultTimestamp3, outageCnecTimestamp3, pstBeTimestamp3, 0.0);
assertSensitivityValue(sensitivityResultTimestamp3, preventiveCnecTimestamp3, pstDeTimestamp3, 25.202534);
assertSensitivityValue(sensitivityResultTimestamp3, outageCnecTimestamp3, pstDeTimestamp3, 0.0);
RangeActionSetpointResult setPointResultTimestamp3 = prePerimeterResult3.getRangeActionSetpointResult();
assertEquals(12, setPointResultTimestamp3.getTap((PstRangeAction) pstBeTimestamp3));
assertEquals(0, setPointResultTimestamp3.getTap((PstRangeAction) pstDeTimestamp3));
}
private static void assertFlowValueMw(FlowResult flowResult, FlowCnec flowCnec, double expectedFlowMw) {
assertEquals(expectedFlowMw, flowResult.getFlow(flowCnec, TwoSides.ONE, Unit.MEGAWATT), AMPERE_MEGAWATT_TOLERANCE);
}
private static void assertSensitivityValue(SensitivityResult sensitivityResult, FlowCnec flowCnec, RangeAction<?> rangeAction, double expectedSensitivityValue) {
assertEquals(expectedSensitivityValue, sensitivityResult.getSensitivityValue(flowCnec, TwoSides.ONE, rangeAction, Unit.MEGAWATT), DOUBLE_TOLERANCE);
}
@Test
void testGetTopologicalOptimizationResult() {
RaoResult raoResult1 = Mockito.mock(RaoResult.class);
RaoResult raoResult2 = Mockito.mock(RaoResult.class);
RaoResult raoResult3 = Mockito.mock(RaoResult.class);
TemporalData<RaoResult> raoResults = new TemporalDataImpl<>(Map.of(timestamp1, raoResult1, timestamp2, raoResult2, timestamp3, raoResult3));
TemporalData<TopologicalOptimizationResult> topologicalOptimizationResults = getTopologicalOptimizationResult(inputs, raoResults);
assertEquals(List.of(timestamp1, timestamp2, timestamp3), topologicalOptimizationResults.getTimestamps());
TopologicalOptimizationResult topologicalOptimizationResult1 = topologicalOptimizationResults.getData(timestamp1).get();
assertEquals(crac1, topologicalOptimizationResult1.raoInput().getCrac());
assertEquals(raoResult1, topologicalOptimizationResult1.topologicalOptimizationResult());
TopologicalOptimizationResult topologicalOptimizationResult2 = topologicalOptimizationResults.getData(timestamp2).get();
assertEquals(crac2, topologicalOptimizationResult2.raoInput().getCrac());
assertEquals(raoResult2, topologicalOptimizationResult2.topologicalOptimizationResult());
TopologicalOptimizationResult topologicalOptimizationResult3 = topologicalOptimizationResults.getData(timestamp3).get();
assertEquals(crac3, topologicalOptimizationResult3.raoInput().getCrac());
assertEquals(raoResult3, topologicalOptimizationResult3.topologicalOptimizationResult());
}
@Test
void testGetPostOptimizationResults() {
RaoResult raoResult1 = Mockito.mock(RaoResult.class);
RaoResult raoResult2 = Mockito.mock(RaoResult.class);
RaoResult raoResult3 = Mockito.mock(RaoResult.class);
TemporalData<RaoResult> raoResults = new TemporalDataImpl<>(Map.of(timestamp1, raoResult1, timestamp2, raoResult2, timestamp3, raoResult3));
PrePerimeterResult initialResult1 = Mockito.mock(PrePerimeterResult.class);
PrePerimeterResult initialResult2 = Mockito.mock(PrePerimeterResult.class);
PrePerimeterResult initialResult3 = Mockito.mock(PrePerimeterResult.class);
TemporalData<PrePerimeterResult> initialResults = new TemporalDataImpl<>(Map.of(timestamp1, initialResult1, timestamp2, initialResult2, timestamp3, initialResult3));
PrePerimeterResult prePerimeterResult1 = Mockito.mock(PrePerimeterResult.class);
PrePerimeterResult prePerimeterResult2 = Mockito.mock(PrePerimeterResult.class);
PrePerimeterResult prePerimeterResult3 = Mockito.mock(PrePerimeterResult.class);
TemporalData<PrePerimeterResult> prePerimeterResults = new TemporalDataImpl<>(Map.of(timestamp1, prePerimeterResult1, timestamp2, prePerimeterResult2, timestamp3, prePerimeterResult3));
GlobalLinearOptimizationResult globalLinearOptimizationResult = Mockito.mock(GlobalLinearOptimizationResult.class);
TemporalData<PostOptimizationResult> postOptimizationResults = getPostOptimizationResults(inputs, initialResults, globalLinearOptimizationResult, raoResults, parameters);
assertEquals(List.of(timestamp1, timestamp2, timestamp3), postOptimizationResults.getTimestamps());
PostOptimizationResult postOptimizationResult1 = postOptimizationResults.getData(timestamp1).get();
assertEquals(crac1, postOptimizationResult1.raoInput().getCrac());
assertEquals(initialResult1, postOptimizationResult1.initialResult());
assertEquals(initialResult1, postOptimizationResult1.prePerimeterFlowResult());
assertEquals(raoResult1, postOptimizationResult1.topologicalOptimizationResult());
PostOptimizationResult postOptimizationResult2 = postOptimizationResults.getData(timestamp2).get();
assertEquals(crac2, postOptimizationResult2.raoInput().getCrac());
assertEquals(initialResult2, postOptimizationResult2.initialResult());
assertEquals(initialResult2, postOptimizationResult2.prePerimeterFlowResult());
assertEquals(raoResult2, postOptimizationResult2.topologicalOptimizationResult());
PostOptimizationResult postOptimizationResult3 = postOptimizationResults.getData(timestamp3).get();
assertEquals(crac3, postOptimizationResult3.raoInput().getCrac());
assertEquals(initialResult3, postOptimizationResult3.initialResult());
assertEquals(initialResult3, postOptimizationResult3.prePerimeterFlowResult());
assertEquals(raoResult3, postOptimizationResult3.topologicalOptimizationResult());
}
}