Skip to content

Commit

Permalink
Implement VoltageAngleLimit removal (#2742)
Browse files Browse the repository at this point in the history
* Implement VoltageAngleLimit removal
* Use FourSubstationsNodeBreakerFactory in removal test
* Fix code smells

---------

Signed-off-by: Olivier Perrin <olivier.perrin@rte-france.com>
  • Loading branch information
olperr1 authored Oct 6, 2023
1 parent 60ed033 commit b3162cc
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,11 @@ public int getConnectableCount() {

@Override
public VoltageAngleLimitAdder newVoltageAngleLimit() {
return new VoltageAngleLimitAdderImpl(ref);
return newVoltageAngleLimit(null);
}

VoltageAngleLimitAdder newVoltageAngleLimit(String subnetwork) {
return new VoltageAngleLimitAdderImpl(this, subnetwork);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public Line getLine(String id) {

@Override
public VoltageAngleLimitAdder newVoltageAngleLimit() {
return new VoltageAngleLimitAdderImpl(rootNetworkRef, id);
return getNetwork().newVoltageAngleLimit(id);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,18 @@
*/
class VoltageAngleLimitAdderImpl implements VoltageAngleLimitAdder, Validable {

private final Ref<NetworkImpl> networkRef;
private final String subnetworkId;
private final NetworkImpl network;
private final String subnetwork;
private String id;
private Terminal from;
private Terminal to;
private double lowLimit = Double.NaN;

private double highLimit = Double.NaN;

VoltageAngleLimitAdderImpl(Ref<NetworkImpl> networkRef) {
this(networkRef, null);
}

VoltageAngleLimitAdderImpl(Ref<NetworkImpl> networkRef, String subnetworkId) {
this.networkRef = networkRef;
this.subnetworkId = subnetworkId;
VoltageAngleLimitAdderImpl(NetworkImpl network, String subnetwork) {
this.network = network;
this.subnetwork = subnetwork;
}

@Override
Expand Down Expand Up @@ -71,19 +67,23 @@ public VoltageAngleLimit add() {
if (id == null) {
throw new IllegalStateException("Voltage angle limit id is mandatory.");
}
if (subnetworkId != null && checkTerminalsInSubnetwork(subnetworkId)) {
if (subnetwork != null && checkTerminalsInSubnetwork(subnetwork)) {
throw new ValidationException(this, "The involved voltage levels are not in the subnetwork '" +
subnetworkId + "'. Create this VoltageAngleLimit from the parent network '" + networkRef.get().getId() + "'");
subnetwork + "'. Create this VoltageAngleLimit from the parent network '" + network.getId() + "'");
}
if (networkRef.get().getVoltageAngleLimitsIndex().containsKey(id)) {
throw new PowsyblException("The network " + networkRef.get().getId()
if (network.getVoltageAngleLimitsIndex().containsKey(id)) {
throw new PowsyblException("The network " + network.getId()
+ " already contains a voltage angle limit with the id '" + id + "'");
}
if (!Double.isNaN(lowLimit) && !Double.isNaN(highLimit) && lowLimit >= highLimit) {
throw new IllegalStateException("Voltage angle low limit must be lower than the high limit.");
}

VoltageAngleLimit voltageAngleLimit = new VoltageAngleLimitImpl(id, from, to, lowLimit, highLimit);
VoltageLevelExt voltageLevel1 = (VoltageLevelExt) from.getVoltageLevel();
VoltageLevelExt voltageLevel2 = (VoltageLevelExt) to.getVoltageLevel();
Ref<NetworkImpl> networkRef = AbstractIdentifiableAdder.computeNetworkRef(network, voltageLevel1, voltageLevel2);

VoltageAngleLimit voltageAngleLimit = new VoltageAngleLimitImpl(id, from, to, lowLimit, highLimit, networkRef);
networkRef.get().getVoltageAngleLimitsIndex().put(id, voltageAngleLimit);
return voltageAngleLimit;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.OptionalDouble;

import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.impl.util.Ref;

/**
*
Expand All @@ -19,18 +20,22 @@
*/
class VoltageAngleLimitImpl implements VoltageAngleLimit {

private final Ref<NetworkImpl> networkRef;

private final String id;
private final Terminal fromTerminal;
private final Terminal toTerminal;
private final double lowLimit;
private final double highLimit;

VoltageAngleLimitImpl(String id, Terminal fromTerminal, Terminal toTerminal, double lowLimit, double highLimit) {
VoltageAngleLimitImpl(String id, Terminal fromTerminal, Terminal toTerminal,
double lowLimit, double highLimit, Ref<NetworkImpl> networkRef) {
this.id = id;
this.fromTerminal = fromTerminal;
this.toTerminal = toTerminal;
this.lowLimit = lowLimit;
this.highLimit = highLimit;
this.networkRef = networkRef;
}

@Override
Expand All @@ -57,4 +62,9 @@ public OptionalDouble getLowLimit() {
public OptionalDouble getHighLimit() {
return Double.isNaN(highLimit) ? OptionalDouble.empty() : OptionalDouble.of(highLimit);
}

@Override
public void remove() {
this.networkRef.get().getVoltageAngleLimitsIndex().remove(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.test.FourSubstationsNodeBreakerFactory;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

/**
*
* @author Luma Zamarreño <zamarrenolm at aia.es>
Expand Down Expand Up @@ -110,4 +108,22 @@ void uniqueIdTest() {
assertEquals("The network " + network.getId()
+ " already contains a voltage angle limit with the id 'Limit'", e.getMessage());
}

@Test
void removeTest() {
String id = "VOLTAGE_ANGLE_LIMIT_LINE_S2S3";

Network network = FourSubstationsNodeBreakerFactory.create();
Line lineS2S3 = network.getLine("LINE_S2S3");
network.newVoltageAngleLimit().setId(id)
.from(lineS2S3.getTerminal1())
.to(lineS2S3.getTerminal2())
.setHighLimit(10.0)
.add();

assertNotNull(network.getVoltageAngleLimit(id));
network.getVoltageAngleLimit(id).remove();
assertNull(network.getVoltageAngleLimit(id));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.List;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.*;
Expand Down Expand Up @@ -324,6 +325,94 @@ public void onCreation(Identifiable identifiable) {
assertFalse(listenerCalled.booleanValue());
}

@Test
public void testAngleVoltageLimitCreation() {
addSubstation(network, "s0");
addSubstation(subnetwork1, "s1");
addSubstation(subnetwork2, "s2");

addVoltageLevel(network.getSubstation("s0").newVoltageLevel(), "vl0_0");
addVoltageLevel(network.getSubstation("s0").newVoltageLevel(), "vl0_1");
addVoltageLevel(network.getSubstation("s1").newVoltageLevel(), "vl1_0");
addVoltageLevel(network.getSubstation("s1").newVoltageLevel(), "vl1_1");
addVoltageLevel(network.getSubstation("s2").newVoltageLevel(), "vl2_0");
addVoltageLevel(network.getSubstation("s2").newVoltageLevel(), "vl2_1");

Line l0 = addLine(network, "l0", "vl0_0", "vl0_1");
Line l1 = addLine(network, "l1", "vl1_0", "vl1_1");
Line l2 = addLine(network, "l2", "vl2_0", "vl2_1");

// On root network, terminals both in root network
VoltageAngleLimit vla0 = addVoltageAngleLimit(network, "vla0", l0.getTerminal1(), l0.getTerminal2());

// On root network, terminals both in subnetwork1
VoltageAngleLimit vla1 = addVoltageAngleLimit(network, "vla1", l1.getTerminal1(), l1.getTerminal2());

// On subnetwork2, terminals both in subnetwork2
VoltageAngleLimit vla2 = addVoltageAngleLimit(subnetwork2, "vla2", l2.getTerminal1(), l2.getTerminal2());

// On root network, terminals in different subnetworks
VoltageAngleLimit vla3 = addVoltageAngleLimit(network, "vla3", l1.getTerminal1(), l2.getTerminal1());

// On root network, terminals in root network and subnetwork2
VoltageAngleLimit vla4 = addVoltageAngleLimit(network, "vla4", l0.getTerminal1(), l2.getTerminal1());

// Try to detach all. Some elements prevent it.
assertFalse(subnetwork1.isDetachable());
assertFalse(subnetwork2.isDetachable());
// Remove problematic elements
vla3.remove();
vla4.remove();

// Detach all
assertTrue(subnetwork1.isDetachable());
assertTrue(subnetwork2.isDetachable());
Network n1 = subnetwork1.detach();
Network n2 = subnetwork2.detach();
// - Check VoltageAngleLimits
assertEquals(1, List.of(network.getVoltageAngleLimits()).size());
assertEquals(1, List.of(n1.getVoltageAngleLimits()).size());
assertEquals(1, List.of(n2.getVoltageAngleLimits()).size());
assertEquals(vla0, network.getVoltageAngleLimit("vla0"));
assertNull(network.getVoltageAngleLimit("vla1"));
assertNull(network.getVoltageAngleLimit("vla2"));
assertEquals(vla1, n1.getVoltageAngleLimit("vla1"));
assertEquals(vla2, n2.getVoltageAngleLimit("vla2"));
}

@Test
public void failCreateVoltageAngleLimitFromSubnetworkBetweenRootAndSubnetwork() {
addSubstation(network, "s0");
addSubstation(subnetwork1, "s1");
addVoltageLevel(network.getSubstation("s0").newVoltageLevel(), "vl0_0");
addVoltageLevel(network.getSubstation("s0").newVoltageLevel(), "vl0_1");
addVoltageLevel(network.getSubstation("s1").newVoltageLevel(), "vl1_0");
addVoltageLevel(network.getSubstation("s1").newVoltageLevel(), "vl1_1");
Line l0 = addLine(network, "l0", "vl0_0", "vl0_1");
Line l1 = addLine(network, "l1", "vl1_0", "vl1_1");

// On subnetwork1, voltage levels in root network and subnetwork2 => should fail
Terminal from = l0.getTerminal1();
Terminal to = l1.getTerminal1();
Exception e = assertThrows(ValidationException.class, () -> addVoltageAngleLimit(subnetwork1, "vla", from, to));
assertTrue(e.getMessage().contains("Create this VoltageAngleLimit from the parent network"));
}

@Test
public void failCreateVoltageAngleLimitFromASubnetworkInAnother() {
addSubstation(subnetwork1, "s2");

addVoltageLevel(network.getSubstation("s2").newVoltageLevel(), "vl2_0");
addVoltageLevel(subnetwork2.newVoltageLevel(), "vl2_1");
Line l2 = addLine(network, "l2", "vl2_0", "vl2_1");

// On subnetwork1, voltage levels both in subnetwork2 => should fail
Terminal from = l2.getTerminal1();
Terminal to = l2.getTerminal2();
PowsyblException e = assertThrows(ValidationException.class, () -> addVoltageAngleLimit(subnetwork1, "vla", from, to));
assertTrue(e.getMessage().contains("Create this VoltageAngleLimit from the parent network"));
}

void assertValidationLevels(ValidationLevel expected) {
// The validation level must be the same between the root network and its subnetworks
assertEquals(expected, network.getValidationLevel());
Expand Down Expand Up @@ -418,6 +507,12 @@ private ThreeWindingsTransformer addThreeWindingsTransformer(Substation substati
.add();
}

private VoltageAngleLimit addVoltageAngleLimit(Network network, String id, Terminal from, Terminal to) {
return network.newVoltageAngleLimit()
.setId(id).from(from).to(to)
.add();
}

private String getBusId(String vlId3) {
return "bus_" + vlId3;
}
Expand Down

0 comments on commit b3162cc

Please sign in to comment.