SubnetworkHighlightTest.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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.nad.svg;
import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
import com.powsybl.nad.AbstractTest;
import com.powsybl.nad.build.iidm.VoltageLevelFilter;
import com.powsybl.nad.layout.LayoutParameters;
import com.powsybl.nad.svg.iidm.DefaultLabelProvider;
import com.powsybl.nad.svg.iidm.NominalVoltageStyleProvider;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.time.ZonedDateTime;
class SubnetworkHighlightTest extends AbstractTest {
protected java.nio.file.FileSystem fileSystem;
@BeforeEach
void setup() {
fileSystem = Jimfs.newFileSystem(Configuration.unix());
setLayoutParameters(new LayoutParameters());
setSvgParameters(new SvgParameters()
.setSvgWidthAndHeightAdded(true)
.setFixedWidth(800)
.setHighlightGraph(true));
}
@Override
protected StyleProvider getStyleProvider(Network network) {
return new NominalVoltageStyleProvider(network);
}
@Override
protected LabelProvider getLabelProvider(Network network) {
return new DefaultLabelProvider(network, getSvgParameters()) {
};
}
@Test
void testSubnetworkHighlight() {
Network network = createWithTieLines();
assertSvgEquals("/subnetwork_highlight.svg", network);
}
@Test
void testPartialGraphSubnetworkHighlight() {
Network network = createWithTieLines();
assertSvgEquals("/partial_graph_subnetwork_highlight.svg", network, VoltageLevelFilter.createVoltageLevelDepthFilter(network, "VLHV2", 1));
}
public static Network createWithTieLines() {
Network network = createWithLFResults(NetworkFactory.findDefault());
network.getLine(EurostagTutorialExample1Factory.NHV1_NHV2_1).remove();
network.getLine(EurostagTutorialExample1Factory.NHV1_NHV2_2).remove();
DanglingLine nhv1xnode1 = network.getVoltageLevel(EurostagTutorialExample1Factory.VLHV1)
.newDanglingLine()
.setId(EurostagTutorialExample1Factory.DANGLING_LINE_XNODE1_1)
.setP0(0.0)
.setQ0(0.0)
.setR(1.5)
.setX(20.0)
.setG(1E-6)
.setB(386E-6 / 2)
.setPairingKey(EurostagTutorialExample1Factory.XNODE_1)
.setBus(EurostagTutorialExample1Factory.NHV1)
.add();
DanglingLine xnode1nhv2 = network.getVoltageLevel(EurostagTutorialExample1Factory.VLHV2)
.newDanglingLine()
.setId(EurostagTutorialExample1Factory.DANGLING_LINE_XNODE1_2)
.setP0(0.0)
.setQ0(0.0)
.setR(1.5)
.setX(13.0)
.setG(2E-6)
.setB(386E-6 / 2)
.setBus("NHV2")
.setPairingKey(EurostagTutorialExample1Factory.XNODE_1)
.add();
network.newTieLine()
.setId(EurostagTutorialExample1Factory.NHV1_NHV2_1)
.setDanglingLine1(nhv1xnode1.getId())
.setDanglingLine2(xnode1nhv2.getId())
.add();
network.getVoltageLevel(EurostagTutorialExample1Factory.VLHV1)
.newDanglingLine()
.setId(EurostagTutorialExample1Factory.DANGLING_LINE_XNODE2_1)
.setP0(0.0)
.setQ0(0.0)
.setR(1.5)
.setX(20.0)
.setG(1E-6)
.setB(386E-6 / 2)
.setBus(EurostagTutorialExample1Factory.NHV1)
.setPairingKey("XNODE2")
.add();
network.getVoltageLevel(EurostagTutorialExample1Factory.VLHV2)
.newDanglingLine()
.setId(EurostagTutorialExample1Factory.DANGLING_LINE_XNODE2_2)
.setP0(0.0)
.setQ0(0.0)
.setR(1.5)
.setX(13.0)
.setG(2E-6)
.setB(386E-6 / 2)
.setBus("NHV2")
.setPairingKey("XNODE2")
.add();
network.getTieLine(EurostagTutorialExample1Factory.NHV1_NHV2_1).getDanglingLine1().getTerminal()
.setP(302.4440612792969)
.setQ(98.74027252197266);
network.getTieLine(EurostagTutorialExample1Factory.NHV1_NHV2_1).getDanglingLine2().getTerminal()
.setP(-300.43389892578125)
.setQ(-137.18849182128906);
return network;
}
public static Network createWithLFResults(NetworkFactory factory) {
Network network = createwith3wt(factory);
network.setCaseDate(ZonedDateTime.parse("2013-01-15T18:45:00.000+01:00"));
network.getBusBreakerView().getBus(EurostagTutorialExample1Factory.NGEN)
.setV(24.500000610351563)
.setAngle(2.3259763717651367);
network.getBusBreakerView().getBus(EurostagTutorialExample1Factory.NHV1)
.setV(402.1428451538086)
.setAngle(0.0);
network.getBusBreakerView().getBus("NHV2")
.setV(389.9526763916016)
.setAngle(-3.5063576698303223);
network.getBusBreakerView().getBus("NLOAD")
.setV(147.57861328125)
.setAngle(-9.614486694335938);
network.getBusBreakerView().getBus("BUS_3")
.setV(197.57861328125)
.setAngle(3.0);
network.getBusBreakerView().getBus("BUS_4")
.setV(197.57861328125)
.setAngle(3.0);
network.getBusBreakerView().getBus("BUS_5")
.setV(197.57861328125)
.setAngle(3.0);
network.getGenerator("GEN").getTerminal()
.setP(-605.558349609375)
.setQ(-225.2825164794922);
network.getTwoWindingsTransformer(EurostagTutorialExample1Factory.NGEN_NHV1).getTerminal1()
.setP(605.558349609375)
.setQ(225.2825164794922);
network.getTwoWindingsTransformer(EurostagTutorialExample1Factory.NGEN_NHV1).getTerminal2()
.setP(-604.8909301757812)
.setQ(-197.48046875);
network.getLoad("LOAD").getTerminal()
.setP(600.0)
.setQ(200.0);
network.getTwoWindingsTransformer(EurostagTutorialExample1Factory.NHV2_NLOAD).getTerminal1()
.setP(600.8677978515625)
.setQ(274.3769836425781);
network.getTwoWindingsTransformer(EurostagTutorialExample1Factory.NHV2_NLOAD).getTerminal2()
.setP(-600.0)
.setQ(-200.0);
network.getLine(EurostagTutorialExample1Factory.NHV1_NHV2_1).getTerminal1()
.setP(302.4440612792969)
.setQ(98.74027252197266);
network.getLine(EurostagTutorialExample1Factory.NHV1_NHV2_1).getTerminal2()
.setP(-300.43389892578125)
.setQ(-137.18849182128906);
network.getLine(EurostagTutorialExample1Factory.NHV1_NHV2_2).getTerminal1()
.setP(302.4440612792969)
.setQ(98.74027252197266);
network.getLine(EurostagTutorialExample1Factory.NHV1_NHV2_2).getTerminal2()
.setP(-300.43389892578125)
.setQ(-137.188491821289060);
return network;
}
public static Network createwith3wt(NetworkFactory networkFactory) {
Network network0 = networkFactory.createNetwork("sim1", "test");
Network network1 = network0.createSubnetwork("sub1", "subnetwork1", "test");
Network network2 = network0.createSubnetwork("sub2", "subnetwork2", "test");
Network network3 = network0.createSubnetwork("sub3", "subnetwork3", "test");
Substation p1 = network1.newSubstation()
.setId("P1")
.setCountry(Country.FR)
.setTso("RTE")
.setGeographicalTags("A")
.add();
Substation p2 = network2.newSubstation()
.setId("P2")
.setCountry(Country.FR)
.setTso("RTE")
.setGeographicalTags("B")
.add();
Substation p3 = network3.newSubstation()
.setId("P3")
.setCountry(Country.FR)
.setTso("RTE")
.setGeographicalTags("B")
.add();
VoltageLevel vlgen = p1.newVoltageLevel()
.setId(EurostagTutorialExample1Factory.VLGEN)
.setNominalV(24.0)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
VoltageLevel vlhv1 = p1.newVoltageLevel()
.setId(EurostagTutorialExample1Factory.VLHV1)
.setNominalV(380.0)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
VoltageLevel vlhv2 = p2.newVoltageLevel()
.setId(EurostagTutorialExample1Factory.VLHV2)
.setNominalV(380.0)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
VoltageLevel vlload = p2.newVoltageLevel()
.setId(EurostagTutorialExample1Factory.VLLOAD)
.setNominalV(150.0)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
Bus ngen = vlgen.getBusBreakerView().newBus()
.setId(EurostagTutorialExample1Factory.NGEN)
.add();
Bus nhv1 = vlhv1.getBusBreakerView().newBus()
.setId(EurostagTutorialExample1Factory.NHV1)
.add();
Bus nhv2 = vlhv2.getBusBreakerView().newBus()
.setId("NHV2")
.add();
Bus nload = vlload.getBusBreakerView().newBus()
.setId("NLOAD")
.add();
VoltageLevel vlhv3 = p3.newVoltageLevel()
.setId("VLHV3")
.setNominalV(380.0)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
VoltageLevel vlhv4 = p3.newVoltageLevel()
.setId("VLHV4")
.setNominalV(380.0)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
VoltageLevel vlhv5 = p3.newVoltageLevel()
.setId("VLHV5")
.setNominalV(380.0)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
Bus bus3 = vlhv3.getBusBreakerView().newBus()
.setId("BUS_3")
.add();
bus3.setV(197.57861328125).setAngle(3.0);
Bus bus4 = vlhv4.getBusBreakerView().newBus()
.setId("BUS_4")
.add();
bus4.setV(197.57861328125).setAngle(3.0);
Bus bus5 = vlhv5.getBusBreakerView().newBus()
.setId("BUS_5")
.add();
bus5.setV(197.57861328125).setAngle(3.0);
network0.newLine()
.setId(EurostagTutorialExample1Factory.NHV1_NHV2_1)
.setVoltageLevel1(vlhv1.getId())
.setBus1(nhv1.getId())
.setConnectableBus1(nhv1.getId())
.setVoltageLevel2(vlhv2.getId())
.setBus2(nhv2.getId())
.setConnectableBus2(nhv2.getId())
.setR(3.0)
.setX(33.0)
.setG1(0.0)
.setB1(386E-6 / 2)
.setG2(0.0)
.setB2(386E-6 / 2)
.add();
network0.newLine()
.setId(EurostagTutorialExample1Factory.NHV1_NHV2_2)
.setVoltageLevel1(vlhv1.getId())
.setBus1(nhv1.getId())
.setConnectableBus1(nhv1.getId())
.setVoltageLevel2(vlhv2.getId())
.setBus2(nhv2.getId())
.setConnectableBus2(nhv2.getId())
.setR(3.0)
.setX(33.0)
.setG1(0.0)
.setB1(386E-6 / 2)
.setG2(0.0)
.setB2(386E-6 / 2)
.add();
network0.newLine()
.setId("NHV2_NHV2_3")
.setVoltageLevel1(vlhv2.getId())
.setBus1(nhv2.getId())
.setConnectableBus1(nhv2.getId())
.setVoltageLevel2(vlhv3.getId())
.setBus2(bus3.getId())
.setConnectableBus2(bus3.getId())
.setR(3.0)
.setX(33.0)
.setG1(0.0)
.setB1(386E-6 / 2)
.setG2(0.0)
.setB2(386E-6 / 2)
.add();
int zb380 = 380 * 380 / 100;
p1.newTwoWindingsTransformer()
.setId(EurostagTutorialExample1Factory.NGEN_NHV1)
.setVoltageLevel1(vlgen.getId())
.setBus1(ngen.getId())
.setConnectableBus1(ngen.getId())
.setRatedU1(24.0)
.setVoltageLevel2(vlhv1.getId())
.setBus2(nhv1.getId())
.setConnectableBus2(nhv1.getId())
.setRatedU2(400.0)
.setR(0.24 / 1300 * zb380)
.setX(Math.sqrt(10 * 10 - 0.24 * 0.24) / 1300 * zb380)
.setG(0.0)
.setB(0.0)
.add();
int zb150 = 150 * 150 / 100;
TwoWindingsTransformer nhv2Nload = p2.newTwoWindingsTransformer()
.setId(EurostagTutorialExample1Factory.NHV2_NLOAD)
.setVoltageLevel1(vlhv2.getId())
.setBus1(nhv2.getId())
.setConnectableBus1(nhv2.getId())
.setRatedU1(400.0)
.setVoltageLevel2(vlload.getId())
.setBus2(nload.getId())
.setConnectableBus2(nload.getId())
.setRatedU2(158.0)
.setR(0.21 / 1000 * zb150)
.setX(Math.sqrt(18 * 18 - 0.21 * 0.21) / 1000 * zb150)
.setG(0.0)
.setB(0.0)
.add();
double a = (158.0 / 150.0) / (400.0 / 380.0);
nhv2Nload.newRatioTapChanger()
.beginStep()
.setRho(0.85f * a)
.setR(0.0)
.setX(0.0)
.setG(0.0)
.setB(0.0)
.endStep()
.beginStep()
.setRho(a)
.setR(0.0)
.setX(0.0)
.setG(0.0)
.setB(0.0)
.endStep()
.beginStep()
.setRho(1.15f * a)
.setR(0.0)
.setX(0.0)
.setG(0.0)
.setB(0.0)
.endStep()
.setTapPosition(1)
.setLoadTapChangingCapabilities(true)
.setRegulating(true)
.setRegulationMode(RatioTapChanger.RegulationMode.VOLTAGE)
.setRegulationValue(158.0)
.setTargetDeadband(0)
.setRegulationTerminal(nhv2Nload.getTerminal2())
.add();
vlload.newLoad()
.setId("LOAD")
.setBus(nload.getId())
.setConnectableBus(nload.getId())
.setP0(600.0)
.setQ0(200.0)
.add();
Generator generator = vlgen.newGenerator()
.setId("GEN")
.setBus(ngen.getId())
.setConnectableBus(ngen.getId())
.setMinP(-9999.99)
.setMaxP(9999.99)
.setVoltageRegulatorOn(true)
.setTargetV(24.5)
.setTargetP(607.0)
.setTargetQ(301.0)
.add();
generator.newMinMaxReactiveLimits()
.setMinQ(-9999.99)
.setMaxQ(9999.99)
.add();
p3.newThreeWindingsTransformer()
.setId("3WT")
.setRatedU0(132.0)
.newLeg1()
.setR(17.424)
.setX(1.7424)
.setG(0.00573921028466483)
.setB(0.000573921028466483)
.setRatedU(132.0)
.setVoltageLevel(vlhv5.getId())
.setBus(bus5.getId())
.add()
.newLeg2()
.setR(1.089)
.setX(0.1089)
.setG(0.0)
.setB(0.0)
.setRatedU(33.0)
.setVoltageLevel(vlhv3.getId())
.setBus(bus3.getId())
.add()
.newLeg3()
.setR(0.121)
.setX(0.0121)
.setG(0.0)
.setB(0.0)
.setRatedU(11.0)
.setVoltageLevel(vlhv4.getId())
.setBus(bus4.getId())
.add()
.add();
VscConverterStation cs1 = vlhv3.newVscConverterStation()
.setId("C1")
.setName("Converter1")
.setConnectableBus("BUS_3")
.setBus("BUS_3")
.setLossFactor(1.1f)
.setVoltageSetpoint(405.0)
.setVoltageRegulatorOn(true)
.add();
cs1.getTerminal()
.setP(100.0)
.setQ(50.0);
cs1.newReactiveCapabilityCurve()
.beginPoint()
.setP(5.0)
.setMinQ(0.0)
.setMaxQ(10.0)
.endPoint()
.beginPoint()
.setP(10.0)
.setMinQ(0.0)
.setMaxQ(10.0)
.endPoint()
.add();
VscConverterStation cs2 = vlload.newVscConverterStation()
.setId("C2")
.setName("Converter2")
.setBus(nload.getId())
.setLossFactor(1.1f)
.setReactivePowerSetpoint(123)
.setVoltageRegulatorOn(false)
.setRegulatingTerminal(cs1.getTerminal())
.add();
cs2.newMinMaxReactiveLimits()
.setMinQ(0.0)
.setMaxQ(10.0)
.add();
network0.newHvdcLine()
.setId("L")
.setName("HVDC")
.setConverterStationId1("C1")
.setConverterStationId2("C2")
.setR(1)
.setNominalV(400)
.setConvertersMode(HvdcLine.ConvertersMode.SIDE_1_INVERTER_SIDE_2_RECTIFIER)
.setMaxP(300.0)
.setActivePowerSetpoint(280)
.add();
return network0;
}
}