Skip to content

Commit

Permalink
Remove voltage level and its equipments (#2464)
Browse files Browse the repository at this point in the history
Signed-off-by: Etienne Homer <[email protected]>
  • Loading branch information
etiennehomer authored Feb 13, 2023
1 parent 216a4ab commit 6086eb0
Show file tree
Hide file tree
Showing 6 changed files with 301 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,15 @@ static void notFoundVoltageLevelReport(Reporter reporter, String voltageLevelId)
.build());
}

static void removedVoltageLevelReport(Reporter reporter, String voltageLevelId) {
reporter.report(Report.builder()
.withKey("removeVoltageLevel")
.withDefaultMessage("Voltage level ${voltageLevelId}, its equipments and the branches it is connected to have been removed")
.withValue(CONNECTABLE_ID, voltageLevelId)
.withSeverity(TypedValue.ERROR_SEVERITY)
.build());
}

static void noTeePointAndOrTappedVoltageLevelReport(Reporter reporter, String line1Id, String line2Id, String line3Id) {
reporter.report(Report.builder()
.withKey("noTeePointAndOrTappedVoltageLevel")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Copyright (c) 2023, 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.iidm.modification.topology;

import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.reporter.Reporter;
import com.powsybl.iidm.modification.AbstractNetworkModification;
import com.powsybl.iidm.network.*;
import com.powsybl.computation.ComputationManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

import static com.powsybl.iidm.modification.topology.ModificationReports.notFoundVoltageLevelReport;
import static com.powsybl.iidm.modification.topology.ModificationReports.removedVoltageLevelReport;

/**
* @author Etienne Homer <etienne.homer at rte-france.com>
*/
public class RemoveVoltageLevel extends AbstractNetworkModification {
private static final Logger LOGGER = LoggerFactory.getLogger(RemoveVoltageLevel.class);

private final String voltageLevelId;

public RemoveVoltageLevel(String voltageLevelId) {
this.voltageLevelId = Objects.requireNonNull(voltageLevelId);
}

@Override
public void apply(Network network, boolean throwException, ComputationManager computationManager, Reporter reporter) {
VoltageLevel voltageLevel = network.getVoltageLevel(voltageLevelId);
if (voltageLevel == null) {
LOGGER.error("Voltage level {} not found", voltageLevelId);
notFoundVoltageLevelReport(reporter, voltageLevelId);
if (throwException) {
throw new PowsyblException("Voltage level not found: " + voltageLevelId);
}
return;
}

voltageLevel.getConnectables(HvdcConverterStation.class).forEach(hcs -> {
if (hcs.getHvdcLine() != null) {
hcs.getHvdcLine().remove();
}
hcs.remove();
});

voltageLevel.getConnectables().forEach(Connectable::remove);

voltageLevel.remove();
removedVoltageLevelReport(reporter, voltageLevelId);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Copyright (c) 2023, 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.iidm.modification.topology;

/**
* @author Etienne Homer <etienne.homer at rte-france.com>
*/
public class RemoveVoltageLevelBuilder {
private String voltageLevelId = null;

public RemoveVoltageLevel build() {
return new RemoveVoltageLevel(voltageLevelId);
}

/**
* @param voltageLevelId the non-null ID of the voltage level
*/
public RemoveVoltageLevelBuilder withVoltageLevelId(String voltageLevelId) {
this.voltageLevelId = voltageLevelId;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* Copyright (c) 2023, 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.iidm.modification.topology;

import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.reporter.Reporter;
import com.powsybl.commons.test.AbstractConverterTest;
import com.powsybl.iidm.modification.NetworkModification;
import com.powsybl.iidm.network.DefaultNetworkListener;
import com.powsybl.iidm.network.Identifiable;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.test.FourSubstationsNodeBreakerFactory;
import com.powsybl.iidm.xml.NetworkXml;
import org.junit.After;
import org.junit.Test;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import static com.powsybl.iidm.modification.topology.TopologyTestUtils.*;
import static org.junit.Assert.*;

/**
* @author Etienne Homer <etienne.homer at rte-france.com>
*/
public class RemoveVoltageLevelTest extends AbstractConverterTest {

private final Set<String> removedObjects = new HashSet<>();
private final Set<String> beforeRemovalObjects = new HashSet<>();

@After
public void tearDown() {
removedObjects.clear();
}

private void addListener(Network network) {
network.addListener(new DefaultNetworkListener() {
@Override
public void beforeRemoval(Identifiable id) {
beforeRemovalObjects.add(id.getId());
}

@Override
public void afterRemoval(String id) {
removedObjects.add(id);
}
});
}

@Test
public void testRemoveVoltageLevel() {
Network network = FourSubstationsNodeBreakerFactory.create();
addListener(network);

new RemoveVoltageLevelBuilder().withVoltageLevelId("S1VL1").build().apply(network);
assertEquals(Set.of("TWT", "S1VL1_BBS", "S1VL1_BBS_TWT_DISCONNECTOR", "S1VL1", "S1VL1_LD1_BREAKER", "LD1", "S1VL1_TWT_BREAKER", "S1VL1_BBS_LD1_DISCONNECTOR"), beforeRemovalObjects);
assertEquals(Set.of("TWT", "S1VL1_BBS", "S1VL1_BBS_TWT_DISCONNECTOR", "S1VL1", "S1VL1_LD1_BREAKER", "LD1", "S1VL1_TWT_BREAKER", "S1VL1_BBS_LD1_DISCONNECTOR"), removedObjects);
assertNull(network.getVoltageLevel("S1VL1"));
assertNull(network.getTwoWindingsTransformer("TWT"));

new RemoveVoltageLevelBuilder().withVoltageLevelId("S1VL2").build().apply(network);
assertNull(network.getVoltageLevel("S1VL1"));
assertNull(network.getVscConverterStation("LCC1"));
assertNull(network.getHvdcLine("HVDC2"));

new RemoveVoltageLevelBuilder().withVoltageLevelId("S2VL1").build().apply(network);
assertNull(network.getVoltageLevel("S2VL1"));
assertNull(network.getLine("LINE_S2S3"));
assertNull(network.getHvdcLine("HVDC1"));
assertNull(network.getVscConverterStation("VSC2"));

RemoveVoltageLevel removeUnknown = new RemoveVoltageLevel("UNKNOWN");
removeUnknown.apply(network, false, Reporter.NO_OP);
PowsyblException e = assertThrows(PowsyblException.class, () -> removeUnknown.apply(network, true, Reporter.NO_OP));
assertEquals("Voltage level not found: UNKNOWN", e.getMessage());
}

@Test
public void testRemoveVLRoundTripNB() throws IOException {
Network network = createNbNetwork();
NetworkModification modification = new RemoveVoltageLevelBuilder().withVoltageLevelId("C").build();
modification.apply(network);
roundTripXmlTest(network, NetworkXml::writeAndValidate, NetworkXml::validateAndRead,
"/eurostag-remove-voltage-level-nb.xml");
}

@Test
public void testRemoveVLRoundTriBB() throws IOException {
Network network = createBbNetwork();
NetworkModification modification = new RemoveVoltageLevelBuilder().withVoltageLevelId("VLGEN").build();
modification.apply(network);
roundTripXmlTest(network, NetworkXml::writeAndValidate, NetworkXml::validateAndRead,
"/eurostag-remove-voltage-level-bb.xml");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_9" id="sim1" caseDate="2021-08-27T14:44:56.567+02:00" forecastDistance="0" sourceFormat="test" minimumValidationLevel="STEADY_STATE_HYPOTHESIS">
<iidm:voltageLevel id="NHV1_NHV2_1_VL#0" nominalV="380.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="bus"/>
</iidm:busBreakerTopology>
</iidm:voltageLevel>
<iidm:substation id="P1" country="FR" tso="RTE" geographicalTags="A">
<iidm:voltageLevel id="VLHV1" nominalV="380.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NHV1"/>
</iidm:busBreakerTopology>
</iidm:voltageLevel>
</iidm:substation>
<iidm:substation id="P2" country="FR" tso="RTE" geographicalTags="B">
<iidm:voltageLevel id="VLHV2" nominalV="380.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NHV2"/>
</iidm:busBreakerTopology>
</iidm:voltageLevel>
<iidm:voltageLevel id="VLLOAD" nominalV="150.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NLOAD"/>
</iidm:busBreakerTopology>
<iidm:load id="LOAD" loadType="UNDEFINED" p0="600.0" q0="200.0" bus="NLOAD" connectableBus="NLOAD"/>
</iidm:voltageLevel>
<iidm:twoWindingsTransformer id="NHV2_NLOAD" r="0.04724999999999999" x="4.049724365620455" g="0.0" b="0.0" ratedU1="400.0" ratedU2="158.0" bus1="NHV2" connectableBus1="NHV2" voltageLevelId1="VLHV2" bus2="NLOAD" connectableBus2="NLOAD" voltageLevelId2="VLLOAD">
<iidm:ratioTapChanger lowTapPosition="0" tapPosition="1" targetDeadband="0.0" loadTapChangingCapabilities="true" regulating="true" targetV="158.0">
<iidm:terminalRef id="NHV2_NLOAD" side="TWO"/>
<iidm:step r="0.0" x="0.0" g="0.0" b="0.0" rho="0.8505666905244191"/>
<iidm:step r="0.0" x="0.0" g="0.0" b="0.0" rho="1.0006666666666666"/>
<iidm:step r="0.0" x="0.0" g="0.0" b="0.0" rho="1.150766642808914"/>
</iidm:ratioTapChanger>
</iidm:twoWindingsTransformer>
</iidm:substation>
<iidm:line id="NHV1_NHV2_1" r="3.0" x="33.0" g1="0.0" b1="1.93E-4" g2="0.0" b2="1.93E-4" bus1="NHV1" connectableBus1="NHV1" voltageLevelId1="VLHV1" bus2="NHV2" connectableBus2="NHV2" voltageLevelId2="VLHV2"/>
<iidm:line id="NHV1_NHV2_2" r="3.0" x="33.0" g1="0.0" b1="1.93E-4" g2="0.0" b2="1.93E-4" bus1="NHV1" connectableBus1="NHV1" voltageLevelId1="VLHV1" bus2="NHV2" connectableBus2="NHV2" voltageLevelId2="VLHV2"/>
</iidm:network>
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_9" id="fictitious" caseDate="2021-08-27T14:44:56.567+02:00" forecastDistance="0" sourceFormat="test" minimumValidationLevel="STEADY_STATE_HYPOTHESIS">
<iidm:voltageLevel id="VLTEST" nominalV="380.0" topologyKind="NODE_BREAKER">
<iidm:nodeBreakerTopology/>
</iidm:voltageLevel>
<iidm:substation id="A" country="FR">
<iidm:voltageLevel id="N" nominalV="225.0" lowVoltageLimit="220.0" highVoltageLimit="245.00002" topologyKind="NODE_BREAKER">
<iidm:nodeBreakerTopology>
<iidm:busbarSection id="O" name="E" node="0"/>
<iidm:busbarSection id="P" name="Q" node="1"/>
<iidm:switch id="R" name="S" kind="DISCONNECTOR" retained="false" open="true" node1="0" node2="19"/>
<iidm:switch id="T" name="U" kind="DISCONNECTOR" retained="false" open="true" node1="0" node2="17"/>
<iidm:switch id="V" name="W" kind="DISCONNECTOR" retained="false" open="true" node1="0" node2="21"/>
<iidm:switch id="X" name="Y" kind="DISCONNECTOR" retained="false" open="true" node1="0" node2="11"/>
<iidm:switch id="Z" name="AA" kind="DISCONNECTOR" retained="false" open="true" node1="0" node2="13"/>
<iidm:switch id="AB" name="AC" kind="DISCONNECTOR" retained="false" open="false" node1="0" node2="15"/>
<iidm:switch id="AD" name="AE" kind="DISCONNECTOR" retained="false" open="true" node1="0" node2="8"/>
<iidm:switch id="AF" name="AG" fictitious="true" kind="DISCONNECTOR" retained="false" open="true" node1="0" node2="2"/>
<iidm:switch id="AH" name="AI" kind="DISCONNECTOR" retained="false" open="false" node1="7" node2="0"/>
<iidm:switch id="AJ" name="AK" kind="DISCONNECTOR" retained="false" open="false" node1="1" node2="6"/>
<iidm:switch id="AL" name="AM" kind="DISCONNECTOR" retained="false" open="false" node1="1" node2="19"/>
<iidm:switch id="AN" name="AO" kind="DISCONNECTOR" retained="false" open="false" node1="1" node2="17"/>
<iidm:switch id="AP" name="AQ" kind="DISCONNECTOR" retained="false" open="false" node1="1" node2="21"/>
<iidm:switch id="AR" name="AS" kind="DISCONNECTOR" retained="false" open="true" node1="1" node2="11"/>
<iidm:switch id="AT" name="AU" kind="DISCONNECTOR" retained="false" open="true" node1="1" node2="13"/>
<iidm:switch id="AV" name="AW" kind="DISCONNECTOR" retained="false" open="true" node1="1" node2="15"/>
<iidm:switch id="AX" name="AY" kind="DISCONNECTOR" retained="false" open="false" node1="1" node2="8"/>
<iidm:switch id="AZ" name="BA" fictitious="true" kind="DISCONNECTOR" retained="false" open="true" node1="1" node2="2"/>
<iidm:switch id="BB" name="BC" fictitious="true" kind="BREAKER" retained="true" open="true" node1="2" node2="3"/>
<iidm:switch id="BD" name="BE" kind="BREAKER" retained="true" open="false" node1="3" node2="4"/>
<iidm:switch id="BF" name="BG" kind="DISCONNECTOR" retained="false" open="false" node1="3" node2="5"/>
<iidm:switch id="BH" name="BI" kind="DISCONNECTOR" retained="false" open="true" node1="9" node2="3"/>
<iidm:switch id="BJ" name="BK" kind="BREAKER" retained="true" open="false" node1="6" node2="7"/>
<iidm:switch id="BL" name="BM" kind="BREAKER" retained="true" open="false" node1="8" node2="9"/>
<iidm:switch id="BN" name="BO" kind="DISCONNECTOR" retained="false" open="false" node1="9" node2="10"/>
<iidm:switch id="BP" name="BQ" kind="BREAKER" retained="true" open="true" node1="11" node2="12"/>
<iidm:switch id="BR" name="BS" kind="BREAKER" retained="true" open="true" node1="13" node2="14"/>
<iidm:switch id="BT" name="BU" kind="BREAKER" retained="true" open="false" node1="15" node2="16"/>
<iidm:switch id="BV" name="BW" kind="BREAKER" retained="true" open="false" node1="17" node2="18"/>
<iidm:switch id="BX" name="BY" kind="BREAKER" retained="true" open="false" node1="19" node2="20"/>
<iidm:switch id="BZ" name="CA" kind="BREAKER" retained="true" open="false" node1="21" node2="22"/>
<iidm:bus v="236.44736" angle="15.250391" nodes="0,1,6,7,8,9,10,15,16,17,18,19,20,21,22"/>
</iidm:nodeBreakerTopology>
<iidm:generator id="CB" energySource="HYDRO" minP="0.0" maxP="70.0" voltageRegulatorOn="false" targetP="0.0" targetV="0.0" targetQ="0.0" node="12">
<iidm:reactiveCapabilityCurve>
<iidm:point p="0.0" minQ="-59.3" maxQ="60.0"/>
<iidm:point p="70.0" minQ="-54.55" maxQ="46.25"/>
</iidm:reactiveCapabilityCurve>
</iidm:generator>
<iidm:generator id="CC" energySource="HYDRO" minP="0.0" maxP="80.0" voltageRegulatorOn="false" targetP="0.0" targetV="0.0" targetQ="0.0" node="14">
<iidm:reactiveCapabilityCurve>
<iidm:point p="0.0" minQ="-56.8" maxQ="57.4"/>
<iidm:point p="80.0" minQ="-53.514" maxQ="36.4"/>
</iidm:reactiveCapabilityCurve>
</iidm:generator>
<iidm:generator id="CD" energySource="HYDRO" minP="0.0" maxP="35.0" voltageRegulatorOn="true" targetP="21.789589" targetV="236.44736" targetQ="-20.701546" node="16" p="-21.789589" q="20.693394">
<iidm:reactiveCapabilityCurve>
<iidm:point p="0.0" minQ="-20.6" maxQ="18.1"/>
<iidm:point p="35.0" minQ="-21.725" maxQ="6.3500004"/>
</iidm:reactiveCapabilityCurve>
</iidm:generator>
<iidm:load id="CE" loadType="UNDEFINED" p0="-72.18689" q0="50.168945" node="4" p="-72.18689" q="50.168945"/>
<iidm:load id="CF" loadType="UNDEFINED" p0="8.455854" q0="-23.695925" node="18" p="8.455854" q="-23.695925"/>
<iidm:load id="CG" loadType="UNDEFINED" p0="90.39911" q0="-51.96869" node="20" p="90.39911" q="-51.96869"/>
<iidm:load id="CH" loadType="UNDEFINED" p0="-5.102249" q0="4.9081216" node="22" p="-5.102249" q="4.9081216"/>
</iidm:voltageLevel>
</iidm:substation>
</iidm:network>

0 comments on commit 6086eb0

Please sign in to comment.