LoopFlowComputationImplTest.java
/*
* Copyright (c) 2020, 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.loopflowcomputation;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.glsk.commons.ZonalData;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.loopflowextension.LoopFlowThresholdImpl;
import com.powsybl.openrao.data.refprog.referenceprogram.ReferenceProgram;
import com.powsybl.openrao.sensitivityanalysis.SystematicSensitivityResult;
import com.powsybl.iidm.network.*;
import com.powsybl.sensitivity.SensitivityAnalysisParameters;
import com.powsybl.sensitivity.SensitivityVariableSet;
import com.powsybl.sensitivity.WeightedSensitivityVariable;
import org.junit.jupiter.api.BeforeEach;
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.*;
import static org.mockito.ArgumentMatchers.any;
/**
* @author Pengbo Wang {@literal <pengbo.wang at rte-international.com>}
* @author Baptiste Seguinot {@literal <baptiste.seguinot at rte-france.com>}
*/
class LoopFlowComputationImplTest {
private static final double DOUBLE_TOLERANCE = 0.1;
private Crac crac;
@BeforeEach
public void setUp() {
crac = ExampleGenerator.crac();
LoopFlowThresholdImpl loopFlowExtensionMock = Mockito.mock(LoopFlowThresholdImpl.class);
crac.getFlowCnec("FR-BE1").addExtension(LoopFlowThresholdImpl.class, loopFlowExtensionMock);
crac.getFlowCnec("BE1-BE2").addExtension(LoopFlowThresholdImpl.class, loopFlowExtensionMock);
crac.getFlowCnec("BE2-NL").addExtension(LoopFlowThresholdImpl.class, loopFlowExtensionMock);
crac.getFlowCnec("FR-DE").addExtension(LoopFlowThresholdImpl.class, loopFlowExtensionMock);
crac.getFlowCnec("DE-NL").addExtension(LoopFlowThresholdImpl.class, loopFlowExtensionMock);
}
private Terminal mockInjection(boolean inMainComponent) {
Bus bus = Mockito.mock(Bus.class);
Mockito.doReturn(inMainComponent).when(bus).isInMainConnectedComponent();
Terminal.BusView busView = Mockito.mock(Terminal.BusView.class);
Mockito.doReturn(bus).when(busView).getBus();
Terminal terminal = Mockito.mock(Terminal.class);
Mockito.doReturn(busView).when(terminal).getBusView();
return terminal;
}
@Test
void calculateLoopFlowTest() {
ZonalData<SensitivityVariableSet> glsk = ExampleGenerator.glskProvider();
ReferenceProgram referenceProgram = ExampleGenerator.referenceProgram();
SystematicSensitivityResult ptdfsAndFlows = ExampleGenerator.systematicSensitivityResult(crac, glsk);
Network network = Mockito.mock(Network.class);
Generator gen = Mockito.mock(Generator.class);
Load load = Mockito.mock(Load.class);
Mockito.when(network.getGenerator(any())).thenReturn(gen);
Mockito.when(network.getLoad(any())).thenReturn(load);
Mockito.doReturn(mockInjection(true)).when(gen).getTerminal();
Mockito.doReturn(mockInjection(true)).when(load).getTerminal();
LoopFlowComputation loopFlowComputation = new LoopFlowComputationImpl(glsk, referenceProgram);
LoopFlowResult loopFlowResult = loopFlowComputation.buildLoopFlowsFromReferenceFlowAndPtdf(ptdfsAndFlows, crac.getFlowCnecs(), network);
assertEquals(-50., loopFlowResult.getLoopFlow(crac.getFlowCnec("FR-BE1"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(200., loopFlowResult.getLoopFlow(crac.getFlowCnec("BE1-BE2"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(-50., loopFlowResult.getLoopFlow(crac.getFlowCnec("BE2-NL"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(50., loopFlowResult.getLoopFlow(crac.getFlowCnec("FR-DE"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(50., loopFlowResult.getLoopFlow(crac.getFlowCnec("DE-NL"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(80, loopFlowResult.getCommercialFlow(crac.getFlowCnec("FR-BE1"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(80., loopFlowResult.getCommercialFlow(crac.getFlowCnec("BE1-BE2"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(80, loopFlowResult.getCommercialFlow(crac.getFlowCnec("BE2-NL"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(120., loopFlowResult.getCommercialFlow(crac.getFlowCnec("FR-DE"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(120., loopFlowResult.getCommercialFlow(crac.getFlowCnec("DE-NL"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(30., loopFlowResult.getReferenceFlow(crac.getFlowCnec("FR-BE1"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(280., loopFlowResult.getReferenceFlow(crac.getFlowCnec("BE1-BE2"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(30., loopFlowResult.getReferenceFlow(crac.getFlowCnec("BE2-NL"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(170., loopFlowResult.getReferenceFlow(crac.getFlowCnec("FR-DE"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(170., loopFlowResult.getReferenceFlow(crac.getFlowCnec("DE-NL"), TwoSides.TWO), DOUBLE_TOLERANCE);
}
@Test
void testIsInMainComponent() {
SensitivityVariableSet linearGlsk = Mockito.mock(SensitivityVariableSet.class);
Network network = Mockito.mock(Network.class);
Mockito.doReturn(Map.of("gen1", new WeightedSensitivityVariable("gen1", 5f))).when(linearGlsk).getVariablesById();
Mockito.doReturn(null).when(network).getGenerator("gen1");
Mockito.doReturn(null).when(network).getLoad("gen1");
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> LoopFlowComputationImpl.isInMainComponent(linearGlsk, network));
assertEquals("gen1 is neither a generator nor a load nor a dangling line in the network. It is not a valid GLSK.", exception.getMessage());
Mockito.doReturn(Map.of(
"gen1", new WeightedSensitivityVariable("gen1", 5f),
"load1", new WeightedSensitivityVariable("load1", 6f),
"dl1", new WeightedSensitivityVariable("dl1", 6f)))
.when(linearGlsk).getVariablesById();
Generator gen1 = Mockito.mock(Generator.class);
Load load1 = Mockito.mock(Load.class);
DanglingLine dl1 = Mockito.mock(DanglingLine.class);
Mockito.doReturn(gen1).when(network).getGenerator("gen1");
Mockito.doReturn(load1).when(network).getLoad("load1");
Mockito.doReturn(dl1).when(network).getDanglingLine("dl1");
Mockito.doReturn(mockInjection(false)).when(gen1).getTerminal();
Mockito.doReturn(mockInjection(false)).when(load1).getTerminal();
Mockito.doReturn(mockInjection(false)).when(dl1).getTerminal();
assertFalse(LoopFlowComputationImpl.isInMainComponent(linearGlsk, network));
Mockito.doReturn(mockInjection(true)).when(gen1).getTerminal();
Mockito.doReturn(mockInjection(false)).when(load1).getTerminal();
Mockito.doReturn(mockInjection(false)).when(dl1).getTerminal();
assertTrue(LoopFlowComputationImpl.isInMainComponent(linearGlsk, network));
Mockito.doReturn(mockInjection(false)).when(gen1).getTerminal();
Mockito.doReturn(mockInjection(true)).when(load1).getTerminal();
Mockito.doReturn(mockInjection(false)).when(dl1).getTerminal();
assertTrue(LoopFlowComputationImpl.isInMainComponent(linearGlsk, network));
Mockito.doReturn(mockInjection(false)).when(gen1).getTerminal();
Mockito.doReturn(mockInjection(false)).when(load1).getTerminal();
Mockito.doReturn(mockInjection(true)).when(dl1).getTerminal();
assertTrue(LoopFlowComputationImpl.isInMainComponent(linearGlsk, network));
Mockito.doReturn(mockInjection(false)).when(gen1).getTerminal();
Mockito.doReturn(mockInjection(true)).when(load1).getTerminal();
Mockito.doReturn(mockInjection(true)).when(dl1).getTerminal();
assertTrue(LoopFlowComputationImpl.isInMainComponent(linearGlsk, network));
Mockito.doReturn(null).when(network).getGenerator("gen1");
Mockito.doReturn(null).when(network).getLoad("gen1");
Mockito.doReturn(null).when(network).getDanglingLine("gen1");
Mockito.doReturn(null).when(network).getGenerator("load1");
Mockito.doReturn(null).when(network).getLoad("load1");
Mockito.doReturn(null).when(network).getDanglingLine("load1");
Mockito.doReturn(null).when(network).getGenerator("dl1");
Mockito.doReturn(null).when(network).getLoad("dl1");
Mockito.doReturn(dl1).when(network).getDanglingLine("dl1");
exception = assertThrows(OpenRaoException.class, () -> LoopFlowComputationImpl.isInMainComponent(linearGlsk, network));
String message = exception.getMessage();
assertTrue(message.contains(" is neither a generator nor a load nor a dangling line in the network. It is not a valid GLSK."));
assertTrue(message.contains("gen1") || message.contains("load1"));
}
@Test
void testIsInMainComponentNullBus() {
SensitivityVariableSet linearGlsk = Mockito.mock(SensitivityVariableSet.class);
Network network = Mockito.mock(Network.class);
Terminal.BusView busView = Mockito.mock(Terminal.BusView.class);
Mockito.doReturn(null).when(busView).getBus();
Terminal terminal = Mockito.mock(Terminal.class);
Mockito.doReturn(busView).when(terminal).getBusView();
Mockito.doReturn(Set.of(
new WeightedSensitivityVariable("gen1", 5f),
new WeightedSensitivityVariable("load1", 6f)))
.when(linearGlsk).getVariables();
Generator gen1 = Mockito.mock(Generator.class);
Load load1 = Mockito.mock(Load.class);
Mockito.doReturn(gen1).when(network).getGenerator("gen1");
Mockito.doReturn(load1).when(network).getLoad("load1");
Mockito.doReturn(terminal).when(gen1).getTerminal();
Mockito.doReturn(mockInjection(false)).when(load1).getTerminal();
assertFalse(LoopFlowComputationImpl.isInMainComponent(linearGlsk, network));
Mockito.doReturn(mockInjection(false)).when(gen1).getTerminal();
Mockito.doReturn(terminal).when(load1).getTerminal();
assertFalse(LoopFlowComputationImpl.isInMainComponent(linearGlsk, network));
}
@Test
void testComputeLoopFlowsWithIsolatedGlsk() {
ZonalData<SensitivityVariableSet> glsk = ExampleGenerator.glskProvider();
ReferenceProgram referenceProgram = ExampleGenerator.referenceProgram();
SystematicSensitivityResult ptdfsAndFlows = ExampleGenerator.systematicSensitivityResult(crac, glsk);
Network network = Mockito.mock(Network.class);
Generator genDe = Mockito.mock(Generator.class);
Generator genNl = Mockito.mock(Generator.class);
Generator genBe = Mockito.mock(Generator.class);
Load loadFr = Mockito.mock(Load.class);
Load loadBe = Mockito.mock(Load.class);
DanglingLine danglingLine = Mockito.mock(DanglingLine.class);
Mockito.when(network.getGenerator("Generator DE")).thenReturn(genDe);
Mockito.when(network.getGenerator("Generator NL")).thenReturn(genNl);
Mockito.when(network.getGenerator("Generator FR")).thenReturn(null);
Mockito.when(network.getGenerator("Generator BE 1")).thenReturn(null);
Mockito.when(network.getGenerator("Generator BE 2")).thenReturn(genBe);
Mockito.when(network.getLoad("Generator DE")).thenReturn(null);
Mockito.when(network.getLoad("Generator NL")).thenReturn(null);
Mockito.when(network.getLoad("Generator FR")).thenReturn(loadFr);
Mockito.when(network.getLoad("Generator BE 1")).thenReturn(loadBe);
Mockito.when(network.getLoad("Generator BE 2")).thenReturn(null);
Mockito.when(network.getDanglingLine("BE1-XBE")).thenReturn(danglingLine);
Mockito.doReturn(mockInjection(true)).when(genDe).getTerminal();
Mockito.doReturn(mockInjection(false)).when(genNl).getTerminal();
Mockito.doReturn(mockInjection(false)).when(genBe).getTerminal();
Mockito.doReturn(mockInjection(true)).when(loadFr).getTerminal();
Mockito.doReturn(mockInjection(false)).when(loadBe).getTerminal();
Mockito.doReturn(mockInjection(false)).when(danglingLine).getTerminal();
LoopFlowComputation loopFlowComputation = new LoopFlowComputationImpl(glsk, referenceProgram);
LoopFlowResult loopFlowResult = loopFlowComputation.buildLoopFlowsFromReferenceFlowAndPtdf(ptdfsAndFlows, crac.getFlowCnecs(), network);
assertEquals(30., loopFlowResult.getLoopFlow(crac.getFlowCnec("FR-BE1"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(280., loopFlowResult.getLoopFlow(crac.getFlowCnec("BE1-BE2"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(30., loopFlowResult.getLoopFlow(crac.getFlowCnec("BE2-NL"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(170., loopFlowResult.getLoopFlow(crac.getFlowCnec("FR-DE"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(170., loopFlowResult.getLoopFlow(crac.getFlowCnec("DE-NL"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(0, loopFlowResult.getCommercialFlow(crac.getFlowCnec("FR-BE1"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(0., loopFlowResult.getCommercialFlow(crac.getFlowCnec("BE1-BE2"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(0., loopFlowResult.getCommercialFlow(crac.getFlowCnec("BE2-NL"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(0., loopFlowResult.getCommercialFlow(crac.getFlowCnec("FR-DE"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(0., loopFlowResult.getCommercialFlow(crac.getFlowCnec("DE-NL"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(30., loopFlowResult.getReferenceFlow(crac.getFlowCnec("FR-BE1"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(280., loopFlowResult.getReferenceFlow(crac.getFlowCnec("BE1-BE2"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(30., loopFlowResult.getReferenceFlow(crac.getFlowCnec("BE2-NL"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(170., loopFlowResult.getReferenceFlow(crac.getFlowCnec("FR-DE"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(170., loopFlowResult.getReferenceFlow(crac.getFlowCnec("DE-NL"), TwoSides.TWO), DOUBLE_TOLERANCE);
}
@Test
void testCalculateLoopFlows() {
ZonalData<SensitivityVariableSet> glsk = ExampleGenerator.glskProvider();
ReferenceProgram referenceProgram = ExampleGenerator.referenceProgram();
Network network = ExampleGenerator.network();
SensitivityAnalysisParameters sensitivityAnalysisParameters = new SensitivityAnalysisParameters();
sensitivityAnalysisParameters.getLoadFlowParameters().setDc(true);
LoopFlowResult loopFlowResult = new LoopFlowComputationImpl(glsk, referenceProgram).calculateLoopFlows(network, "OpenLoadFlow", sensitivityAnalysisParameters, crac.getFlowCnecs(), crac.getOutageInstant());
assertEquals(-20., loopFlowResult.getLoopFlow(crac.getFlowCnec("FR-BE1"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(80., loopFlowResult.getLoopFlow(crac.getFlowCnec("BE1-BE2"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(-20., loopFlowResult.getLoopFlow(crac.getFlowCnec("BE2-NL"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(20., loopFlowResult.getLoopFlow(crac.getFlowCnec("FR-DE"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(20., loopFlowResult.getLoopFlow(crac.getFlowCnec("DE-NL"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(40., loopFlowResult.getCommercialFlow(crac.getFlowCnec("FR-BE1"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(40., loopFlowResult.getCommercialFlow(crac.getFlowCnec("BE1-BE2"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(40., loopFlowResult.getCommercialFlow(crac.getFlowCnec("BE2-NL"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(60., loopFlowResult.getCommercialFlow(crac.getFlowCnec("FR-DE"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(60., loopFlowResult.getCommercialFlow(crac.getFlowCnec("DE-NL"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(20., loopFlowResult.getReferenceFlow(crac.getFlowCnec("FR-BE1"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(120., loopFlowResult.getReferenceFlow(crac.getFlowCnec("BE1-BE2"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(20., loopFlowResult.getReferenceFlow(crac.getFlowCnec("BE2-NL"), TwoSides.ONE), DOUBLE_TOLERANCE);
assertEquals(80., loopFlowResult.getReferenceFlow(crac.getFlowCnec("FR-DE"), TwoSides.TWO), DOUBLE_TOLERANCE);
assertEquals(80., loopFlowResult.getReferenceFlow(crac.getFlowCnec("DE-NL"), TwoSides.TWO), DOUBLE_TOLERANCE);
}
}