Skip to content

Commit

Permalink
Fix area listeners when merging and detaching Networks (#3081)
Browse files Browse the repository at this point in the history
Signed-off-by: Damien Jeandemange <damien.jeandemange@artelys.com>
  • Loading branch information
jeandemanged authored Jun 24, 2024
1 parent 6e18e4f commit 45eeaef
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,19 @@ public void beforeRemoval(Identifiable<?> identifiable) {
}
}

/**
* Must be called whenever the Area is moved to a different root Network when merging and detaching.
* @param fromNetwork previous root network
* @param toNetwork new root network
*/
void moveListener(NetworkImpl fromNetwork, NetworkImpl toNetwork) {
fromNetwork.removeListener(this.areaListener);
toNetwork.addListener(this.areaListener);
}

private final NetworkListener areaListener;

public AreaImpl(Ref<NetworkImpl> ref, Ref<SubnetworkImpl> subnetworkRef, String id, String name, boolean fictitious, String areaType,
AreaImpl(Ref<NetworkImpl> ref, Ref<SubnetworkImpl> subnetworkRef, String id, String name, boolean fictitious, String areaType,
double acInterchangeTarget) {
super(id, name, fictitious);
this.networkRef = Objects.requireNonNull(ref);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,11 @@ private void merge(Network other) {

checkMergeability(otherNetwork);

otherNetwork.getAreaStream().forEach(a -> {
AreaImpl area = (AreaImpl) a;
area.moveListener(otherNetwork, this);
});

// try to find dangling lines couples
List<DanglingLinePair> lines = new ArrayList<>();
Map<String, List<DanglingLine>> dl1byPairingKey = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ public Network detach() {
transferExtensions(this, detachedNetwork);
transferProperties(this, detachedNetwork);

// Memorize the network identifiables/voltageAngleLimits before moving references (to use them latter)
// Memorize the network identifiables/voltageAngleLimits before moving references (to use them later)
Collection<Identifiable<?>> identifiables = getIdentifiables();
Iterable<VoltageAngleLimit> vals = getVoltageAngleLimits();

Expand All @@ -831,6 +831,11 @@ public Network detach() {
detachedNetwork.getVoltageAngleLimitsIndex().put(val.getId(), val);
}

detachedNetwork.getAreaStream().forEach(a -> {
AreaImpl area = (AreaImpl) a;
area.moveListener(previousRootNetwork, detachedNetwork);
});

// We don't control that regulating terminals and phase/ratio regulation terminals are in the same subnetwork
// as their network elements (generators, PSTs, ...). It is unlikely that those terminals and their elements
// are in different subnetworks but nothing prevents it. For now, we ignore this case, but it may be necessary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
import com.powsybl.iidm.network.test.FourSubstationsNodeBreakerFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
Expand Down Expand Up @@ -424,6 +425,41 @@ public void removeEquipmentRemovesAreaBoundary() {
assertEquals(2, controlAreaB.getAreaBoundaryStream().count());
}

@Test
public void removeEquipmentRemovesAreaBoundaryMergeAndDetach() {
// do a merge
Network fourBus = FourSubstationsNodeBreakerFactory.create();
Network merged = Network.merge(network, fourBus);
network = merged.getSubnetwork("sim1");
controlAreaA = network.getArea("ControlArea_A");
controlAreaB = network.getArea("ControlArea_B");
dlXnode1A = network.getDanglingLine("NHV1_XNODE1");
tieLine1 = network.getTieLine("NHV1_NHV2_1");
assertEquals(2, controlAreaA.getAreaBoundaryStream().count());
assertEquals(2, controlAreaB.getAreaBoundaryStream().count());

// Verify the cleanup listener is now effective on the merged network
tieLine1.remove();
dlXnode1A.remove();

assertEquals(1, controlAreaA.getAreaBoundaryStream().count());
assertEquals(2, controlAreaB.getAreaBoundaryStream().count());

// now detach
network = network.detach();
controlAreaA = network.getArea("ControlArea_A");
controlAreaB = network.getArea("ControlArea_B");
dlXnode2A = network.getDanglingLine("NVH1_XNODE2");
tieLine2 = network.getTieLine("NHV1_NHV2_2");

// Verify the cleanup listener is now effective on the detached network
tieLine2.remove();
dlXnode2A.remove();

assertEquals(0, controlAreaA.getAreaBoundaryStream().count());
assertEquals(2, controlAreaB.getAreaBoundaryStream().count());
}

@Test
public void throwBoundaryOtherNetwork() {
Network subnetwork = network.createSubnetwork("subnetwork_id", "Subnetwork", "json");
Expand Down

0 comments on commit 45eeaef

Please sign in to comment.