Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement VoltageAngleLimit removal #2742

Merged
merged 3 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strange to call this method from here, once again VoltageAngleLimit is very very close to an Identifiable...


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