ExampleGenerator.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.iidm.network.TwoSides;
import com.powsybl.glsk.commons.ZonalData;
import com.powsybl.glsk.commons.ZonalDataImpl;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.api.InstantKind;
import com.powsybl.openrao.data.crac.impl.CracImplFactory;
import com.powsybl.openrao.data.refprog.referenceprogram.ReferenceExchangeData;
import com.powsybl.openrao.data.refprog.referenceprogram.ReferenceProgram;
import com.powsybl.openrao.commons.EICode;
import com.powsybl.openrao.sensitivityanalysis.SystematicSensitivityResult;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.VoltageLevel;
import com.powsybl.sensitivity.SensitivityVariableSet;
import com.powsybl.sensitivity.WeightedSensitivityVariable;
import org.mockito.Mockito;
import java.util.*;
import static com.powsybl.openrao.commons.Unit.MEGAWATT;
/**
* Test case is a network with 5 nodes and 1 xnode (in 4 countries).
*
* FR (+100 MW) BE 1 (+125 MW)
* + ------------ +---------------------------+ XBE (-25 MW)
* | |
* | + BE 2 (-100 MW)
* | |
* + ------------ +
* DE (0 MW) NL (-100 MW)
*
* All lines have same impedance and are monitored.
* Each Country GLSK is a simple one node GLSK, except for Belgium where GLSKs are equally distributed
* on the 2 nodes + the xnode
* Compensation is considered as equally shared on each country, and there are no losses.
*
* @author Sebastien Murgey {@literal <sebastien.murgey at rte-france.com>}
* @author Baptiste Seguinot {@literal <baptiste.seguinot at rte-france.com>}
*/
final class ExampleGenerator {
private static final String PREVENTIVE_INSTANT_ID = "preventive";
private static final String OUTAGE_INSTANT_ID = "outage";
private ExampleGenerator() {
throw new AssertionError("Utility class should not be instantiated");
}
static Network network() {
Network network = Network.create("Test", "code");
Substation substationFr = network.newSubstation()
.setId("Substation FR")
.setName("Substation FR")
.setCountry(Country.FR)
.add();
VoltageLevel voltageLevelFr = substationFr.newVoltageLevel()
.setId("Voltage level FR")
.setName("Voltage level FR")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.setLowVoltageLimit(300)
.setHighVoltageLimit(500)
.add();
voltageLevelFr.getBusBreakerView()
.newBus()
.setId("Bus FR")
.setName("Bus FR")
.add();
voltageLevelFr.newGenerator()
.setId("Generator FR")
.setName("Generator FR")
.setBus("Bus FR")
.setEnergySource(EnergySource.OTHER)
.setMinP(1000)
.setMaxP(2000)
.setRatedS(100)
.setTargetP(1600)
.setTargetV(400)
.setVoltageRegulatorOn(true)
.add();
voltageLevelFr.newLoad()
.setId("Load FR")
.setName("Load FR")
.setBus("Bus FR")
.setLoadType(LoadType.UNDEFINED)
.setP0(1500)
.setQ0(0)
.add();
Substation substationBe = network.newSubstation()
.setId("Substation BE")
.setName("Substation BE")
.setCountry(Country.BE)
.add();
VoltageLevel voltageLevelBe = substationBe.newVoltageLevel()
.setId("Voltage level BE")
.setName("Voltage level BE")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.setLowVoltageLimit(300)
.setHighVoltageLimit(500)
.add();
voltageLevelBe.getBusBreakerView()
.newBus()
.setId("Bus BE 1")
.setName("Bus BE 1")
.add();
voltageLevelBe.newGenerator()
.setId("Generator BE 1")
.setName("Generator BE 1")
.setBus("Bus BE 1")
.setEnergySource(EnergySource.OTHER)
.setMinP(1000)
.setMaxP(2000)
.setRatedS(100)
.setTargetP(1625)
.setTargetV(400)
.setVoltageRegulatorOn(true)
.add();
voltageLevelBe.newLoad()
.setId("Load BE 1")
.setName("Load BE 1")
.setBus("Bus BE 1")
.setLoadType(LoadType.UNDEFINED)
.setP0(1500)
.setQ0(0)
.add();
voltageLevelBe.getBusBreakerView()
.newBus()
.setId("Bus BE 2")
.setName("Bus BE 2")
.add();
voltageLevelBe.newGenerator()
.setId("Generator BE 2")
.setName("Generator BE 2")
.setBus("Bus BE 2")
.setEnergySource(EnergySource.OTHER)
.setMinP(1000)
.setMaxP(2000)
.setRatedS(100)
.setTargetP(1500)
.setTargetV(400)
.setVoltageRegulatorOn(true)
.add();
voltageLevelBe.newLoad()
.setId("Load BE 2")
.setName("Load BE 2")
.setBus("Bus BE 2")
.setLoadType(LoadType.UNDEFINED)
.setP0(1600)
.setQ0(0)
.add();
Substation substationDe = network.newSubstation()
.setId("Substation DE")
.setName("Substation DE")
.setCountry(Country.DE)
.add();
VoltageLevel voltageLevelDe = substationDe.newVoltageLevel()
.setId("Voltage level DE")
.setName("Voltage level DE")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.setLowVoltageLimit(300)
.setHighVoltageLimit(500)
.add();
voltageLevelDe.getBusBreakerView()
.newBus()
.setId("Bus DE")
.setName("Bus DE")
.add();
voltageLevelDe.newGenerator()
.setId("Generator DE")
.setName("Generator DE")
.setBus("Bus DE")
.setEnergySource(EnergySource.OTHER)
.setMinP(1000)
.setMaxP(2000)
.setRatedS(100)
.setTargetP(1500)
.setTargetV(400)
.setVoltageRegulatorOn(true)
.add();
voltageLevelDe.newLoad()
.setId("Load DE")
.setName("Load DE")
.setBus("Bus DE")
.setLoadType(LoadType.UNDEFINED)
.setP0(1500)
.setQ0(0)
.add();
Substation substationNl = network.newSubstation()
.setId("Substation NL")
.setName("Substation NL")
.setCountry(Country.NL)
.add();
VoltageLevel voltageLevelNl = substationNl.newVoltageLevel()
.setId("Voltage level NL")
.setName("Voltage level NL")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.setLowVoltageLimit(300)
.setHighVoltageLimit(500)
.add();
voltageLevelNl.getBusBreakerView()
.newBus()
.setId("Bus NL")
.setName("Bus NL")
.add();
voltageLevelNl.newGenerator()
.setId("Generator NL")
.setName("Generator NL")
.setBus("Bus NL")
.setEnergySource(EnergySource.OTHER)
.setMinP(1000)
.setMaxP(2000)
.setRatedS(100)
.setTargetP(1500)
.setTargetV(400)
.setVoltageRegulatorOn(true)
.add();
voltageLevelNl.newLoad()
.setId("Load NL")
.setName("Load NL")
.setBus("Bus NL")
.setLoadType(LoadType.UNDEFINED)
.setP0(1600)
.setQ0(0)
.add();
network.newLine()
.setId("FR-BE1")
.setName("FR-BE1")
.setVoltageLevel1("Voltage level FR")
.setVoltageLevel2("Voltage level BE")
.setBus1("Bus FR")
.setBus2("Bus BE 1")
.setR(0)
.setX(5)
.setB1(0)
.setB2(0)
.setG1(0)
.setG2(0)
.add();
network.newLine()
.setId("FR-DE")
.setName("FR-DE")
.setVoltageLevel1("Voltage level FR")
.setVoltageLevel2("Voltage level DE")
.setBus1("Bus FR")
.setBus2("Bus DE")
.setR(0)
.setX(5)
.setB1(0)
.setB2(0)
.setG1(0)
.setG2(0)
.add();
network.newLine()
.setId("BE2-NL")
.setName("BE2-NL")
.setVoltageLevel1("Voltage level BE")
.setVoltageLevel2("Voltage level NL")
.setBus1("Bus BE 2")
.setBus2("Bus NL")
.setR(0)
.setX(5)
.setB1(0)
.setB2(0)
.setG1(0)
.setG2(0)
.add();
network.newLine()
.setId("DE-NL")
.setName("DE-NL")
.setVoltageLevel1("Voltage level DE")
.setVoltageLevel2("Voltage level NL")
.setBus1("Bus DE")
.setBus2("Bus NL")
.setR(0)
.setX(5)
.setB1(0)
.setB2(0)
.setG1(0)
.setG2(0)
.add();
network.newLine()
.setId("BE1-BE2")
.setName("BE1-BE2")
.setVoltageLevel1("Voltage level BE")
.setVoltageLevel2("Voltage level BE")
.setBus1("Bus BE 1")
.setBus2("Bus BE 2")
.setR(0)
.setX(5)
.setB1(0)
.setB2(0)
.setG1(0)
.setG2(0)
.add();
voltageLevelBe.newDanglingLine()
.setId("BE1-XBE")
.setBus("Bus BE 1")
.setPairingKey("XBE")
.setP0(25)
.setQ0(0)
.setR(0)
.setX(5)
.setB(0)
.setG(0)
.add();
return network;
}
static Crac crac() {
Crac crac = new CracImplFactory().create("test-crac")
.newInstant(PREVENTIVE_INSTANT_ID, InstantKind.PREVENTIVE)
.newInstant(OUTAGE_INSTANT_ID, InstantKind.OUTAGE);
crac.newFlowCnec()
.withId("FR-BE1")
.withInstant(PREVENTIVE_INSTANT_ID)
.withNetworkElement("FR-BE1")
.newThreshold()
.withMin(-200.)
.withMax(200.)
.withUnit(MEGAWATT)
.withSide(TwoSides.ONE)
.add()
.add();
crac.newFlowCnec()
.withId("FR-DE")
.withInstant(PREVENTIVE_INSTANT_ID)
.withNetworkElement("FR-DE")
.newThreshold()
.withMin(-200.)
.withMax(200.)
.withUnit(MEGAWATT)
.withSide(TwoSides.TWO)
.add()
.add();
crac.newFlowCnec()
.withId("BE2-NL")
.withInstant(PREVENTIVE_INSTANT_ID)
.withNetworkElement("BE2-NL")
.newThreshold()
.withMin(-200.)
.withMax(200.)
.withUnit(MEGAWATT)
.withSide(TwoSides.ONE)
.add()
.add();
crac.newFlowCnec()
.withId("DE-NL")
.withInstant(PREVENTIVE_INSTANT_ID)
.withNetworkElement("DE-NL")
.newThreshold()
.withMin(-200.)
.withMax(200.)
.withUnit(MEGAWATT)
.withSide(TwoSides.TWO)
.add()
.add();
crac.newFlowCnec()
.withId("BE1-BE2")
.withInstant(PREVENTIVE_INSTANT_ID)
.withNetworkElement("BE1-BE2")
.newThreshold()
.withMin(-200.)
.withMax(200.)
.withUnit(MEGAWATT)
.withSide(TwoSides.ONE)
.add()
.add();
return crac;
}
static ZonalData<SensitivityVariableSet> glskProvider() {
List<WeightedSensitivityVariable> glskBe = new ArrayList<>();
glskBe.add(new WeightedSensitivityVariable("Generator BE 1", 1.0f / 3.0f));
glskBe.add(new WeightedSensitivityVariable("Generator BE 2", 1.0f / 3.0f));
glskBe.add(new WeightedSensitivityVariable("BE1-XBE", 1.0f / 3.0f));
Map<String, SensitivityVariableSet> glsks = new HashMap<>();
glsks.put("10YFR-RTE------C", new SensitivityVariableSet("10YFR-RTE------C", List.of(new WeightedSensitivityVariable("Generator FR", 1.))));
glsks.put("10YBE----------2", new SensitivityVariableSet("10YBE----------2", glskBe));
glsks.put("10YCB-GERMANY--8", new SensitivityVariableSet("10YCB-GERMANY--8", List.of(new WeightedSensitivityVariable("Generator DE", 1.))));
glsks.put("10YNL----------L", new SensitivityVariableSet("10YNL----------L", List.of(new WeightedSensitivityVariable("Generator NL", 1.))));
return new ZonalDataImpl<>(glsks);
}
static ReferenceProgram referenceProgram() {
EICode areaFrance = new EICode(Country.FR);
EICode areaBelgium = new EICode(Country.BE);
EICode areaNetherlands = new EICode(Country.NL);
EICode areaGermany = new EICode(Country.DE);
List<ReferenceExchangeData> exchangeDataList = Arrays.asList(
new ReferenceExchangeData(areaFrance, areaBelgium, 50),
new ReferenceExchangeData(areaFrance, areaGermany, 50),
new ReferenceExchangeData(areaBelgium, areaNetherlands, 50),
new ReferenceExchangeData(areaGermany, areaNetherlands, 50));
return new ReferenceProgram(exchangeDataList);
}
static SystematicSensitivityResult systematicSensitivityResult(Crac crac, ZonalData<SensitivityVariableSet> glsk) {
SystematicSensitivityResult sensisResults = Mockito.mock(SystematicSensitivityResult.class);
// flow results
Mockito.when(sensisResults.getReferenceFlow(crac.getFlowCnec("FR-BE1"), TwoSides.ONE)).thenReturn(30.);
Mockito.when(sensisResults.getReferenceFlow(crac.getFlowCnec("BE1-BE2"), TwoSides.ONE)).thenReturn(280.);
Mockito.when(sensisResults.getReferenceFlow(crac.getFlowCnec("FR-DE"), TwoSides.TWO)).thenReturn(170.);
Mockito.when(sensisResults.getReferenceFlow(crac.getFlowCnec("BE2-NL"), TwoSides.ONE)).thenReturn(30.);
Mockito.when(sensisResults.getReferenceFlow(crac.getFlowCnec("DE-NL"), TwoSides.TWO)).thenReturn(170.);
// sensi results
SensitivityVariableSet glskFr = glsk.getData("10YFR-RTE------C");
SensitivityVariableSet glskBe = glsk.getData("10YBE----------2");
SensitivityVariableSet glskDe = glsk.getData("10YCB-GERMANY--8");
SensitivityVariableSet glskNl = glsk.getData("10YNL----------L");
Mockito.when(sensisResults.getSensitivityOnFlow(glskFr, crac.getFlowCnec("FR-BE1"), TwoSides.ONE)).thenReturn(0.);
Mockito.when(sensisResults.getSensitivityOnFlow(glskBe, crac.getFlowCnec("FR-BE1"), TwoSides.ONE)).thenReturn(-1.5);
Mockito.when(sensisResults.getSensitivityOnFlow(glskDe, crac.getFlowCnec("FR-BE1"), TwoSides.ONE)).thenReturn(-0.4);
Mockito.when(sensisResults.getSensitivityOnFlow(glskNl, crac.getFlowCnec("FR-BE1"), TwoSides.ONE)).thenReturn(-0.8);
Mockito.when(sensisResults.getSensitivityOnFlow(glskFr, crac.getFlowCnec("BE1-BE2"), TwoSides.ONE)).thenReturn(0.);
Mockito.when(sensisResults.getSensitivityOnFlow(glskBe, crac.getFlowCnec("BE1-BE2"), TwoSides.ONE)).thenReturn(0.);
Mockito.when(sensisResults.getSensitivityOnFlow(glskDe, crac.getFlowCnec("BE1-BE2"), TwoSides.ONE)).thenReturn(-0.4);
Mockito.when(sensisResults.getSensitivityOnFlow(glskNl, crac.getFlowCnec("BE1-BE2"), TwoSides.ONE)).thenReturn(-0.8);
Mockito.when(sensisResults.getSensitivityOnFlow(glskFr, crac.getFlowCnec("FR-DE"), TwoSides.TWO)).thenReturn(0.);
Mockito.when(sensisResults.getSensitivityOnFlow(glskBe, crac.getFlowCnec("FR-DE"), TwoSides.TWO)).thenReturn(-0.5);
Mockito.when(sensisResults.getSensitivityOnFlow(glskDe, crac.getFlowCnec("FR-DE"), TwoSides.TWO)).thenReturn(-1.6);
Mockito.when(sensisResults.getSensitivityOnFlow(glskNl, crac.getFlowCnec("FR-DE"), TwoSides.TWO)).thenReturn(-1.2);
Mockito.when(sensisResults.getSensitivityOnFlow(glskFr, crac.getFlowCnec("BE2-NL"), TwoSides.ONE)).thenReturn(0.);
Mockito.when(sensisResults.getSensitivityOnFlow(glskBe, crac.getFlowCnec("BE2-NL"), TwoSides.ONE)).thenReturn(0.5);
Mockito.when(sensisResults.getSensitivityOnFlow(glskDe, crac.getFlowCnec("BE2-NL"), TwoSides.ONE)).thenReturn(-0.4);
Mockito.when(sensisResults.getSensitivityOnFlow(glskNl, crac.getFlowCnec("BE2-NL"), TwoSides.ONE)).thenReturn(-0.8);
Mockito.when(sensisResults.getSensitivityOnFlow(glskFr, crac.getFlowCnec("DE-NL"), TwoSides.TWO)).thenReturn(0.);
Mockito.when(sensisResults.getSensitivityOnFlow(glskBe, crac.getFlowCnec("DE-NL"), TwoSides.TWO)).thenReturn(-0.5);
Mockito.when(sensisResults.getSensitivityOnFlow(glskDe, crac.getFlowCnec("DE-NL"), TwoSides.TWO)).thenReturn(0.4);
Mockito.when(sensisResults.getSensitivityOnFlow(glskNl, crac.getFlowCnec("DE-NL"), TwoSides.TWO)).thenReturn(-1.2);
return sensisResults;
}
}