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

Fix extensions dangling terminal references #3221

Merged
merged 24 commits into from
Nov 28, 2024
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 @@ -32,15 +32,11 @@ public void setExtendable(T extendable) {
if (extendable != null && this.extendable != null && this.extendable != extendable) {
throw new PowsyblException("Extension is already associated to the extendable " + this.extendable);
}
if (extendable == null) {
cleanup();
}
this.extendable = extendable;
}

/**
* Method called when the extension is removed from its holder.
* Can be used for e.g. resource cleanup.
*/
protected void cleanup() { }
@Override
public void cleanup() {
// nothing by default
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,11 @@ public interface Extension<T> {
* @throws com.powsybl.commons.PowsyblException if this extension is already held.
*/
void setExtendable(T extendable);

/**
* Method called just before the extension is removed from its holder.
* Can be used for e.g. resource cleanup.
*/
default void cleanup() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.google.auto.service.AutoService;
import com.powsybl.commons.extensions.Extension;
import com.powsybl.commons.extensions.AbstractExtension;
import com.powsybl.commons.extensions.ExtensionJsonSerializer;
import com.powsybl.commons.json.JsonUtil;
import com.powsybl.commons.test.AbstractSerDeTest;
Expand Down Expand Up @@ -249,7 +249,7 @@ void readJsonListContingenciesWithOptionalName() throws IOException {
roundTripTest(contingencyList, ContingencyJsonTest::write, ContingencyJsonTest::readContingencyList, "/contingenciesWithOptionalName.json");
}

static class DummyExtension implements Extension<Contingency> {
static class DummyExtension extends AbstractExtension<Contingency> {

private Contingency contingency;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.powsybl.math.graph.TraversalType;
import com.powsybl.math.graph.TraverseResult;

import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;

Expand Down Expand Up @@ -252,4 +253,11 @@ static Terminal getTerminal(Identifiable<?> identifiable, ThreeSides side) {
}

ThreeSides getSide();

/**
* Retrieves a list of objects that refer to the terminal.
*
* @return a list of referrer objects.
*/
List<Object> getReferrers();
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void remove() {

network.getIndex().remove(this);
for (TerminalExt terminal : terminals) {
terminal.removeAsRegulationPoint();
terminal.getReferrerManager().notifyOfRemoval();
VoltageLevelExt vl = terminal.getVoltageLevel();
vl.getTopologyModel().detach(terminal);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,17 @@ public void allocateVariantArrayElement(int[] indexes, int sourceIndex) {

@Override
public <E extends Extension<I>> boolean removeExtension(Class<E> type) {
return removeExtension(type, true);
}

public <E extends Extension<I>> boolean removeExtension(Class<E> type, boolean cleanup) {
E extension = getExtension(type);
NetworkListenerList listeners = getNetwork().getListeners();
if (extension != null) {
listeners.notifyExtensionBeforeRemoval(extension);
if (cleanup) {
extension.cleanup();
}
removeExtension(type, extension);
listeners.notifyExtensionAfterRemoval(this, extension.getName());
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Copyright (c) 2024, 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.network.impl;

import com.powsybl.commons.extensions.AbstractExtension;
import com.powsybl.iidm.network.Identifiable;
import com.powsybl.iidm.network.Terminal;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public abstract class AbstractIidmExtension<I extends Identifiable<I>> extends AbstractExtension<I> implements Referrer<Terminal> {

protected AbstractIidmExtension(I extendable) {
super(extendable);
}

@Override
public void onReferencedRemoval(Terminal removedTerminal) {
// nothing by default
// this is the place for terminal reference cleanup
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@
package com.powsybl.iidm.network.impl;

import com.powsybl.commons.exceptions.UncheckedClassCastExceptionException;
import com.powsybl.commons.extensions.AbstractExtension;
import com.powsybl.iidm.network.Identifiable;
import com.powsybl.iidm.network.Network;

/**
* @author Florian Dupuy {@literal <florian.dupuy at rte-france.com>}
*/
public abstract class AbstractMultiVariantIdentifiableExtension<T extends Identifiable<T>> extends AbstractExtension<T> implements MultiVariantObject {
public abstract class AbstractMultiVariantIdentifiableExtension<T extends Identifiable<T>> extends AbstractIidmExtension<T> implements MultiVariantObject {

public AbstractMultiVariantIdentifiableExtension(T extendable) {
super(extendable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ protected static void transferExtensions(Network from, Network to, boolean ignor
"an extension of this same class already exists in the destination network.",
clazz.getName(), from.getId(), to.getId());
} else {
from.removeExtension((Class<? extends Extension<Network>>) clazz);
((AbstractIdentifiable<Network>) from).removeExtension((Class<? extends Extension<Network>>) clazz, false);
to.addExtension((Class<? super Extension<Network>>) clazz, (Extension<Network>) e);
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,8 @@ private void throwIncorrectTapPosition(int tapPosition, int highTapPosition) {
+ tapPosition + " [" + lowTapPosition + ", " + highTapPosition
+ "]");
}

public void remove() {
regulatingPoint.remove();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@
package com.powsybl.iidm.network.impl;

import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import com.powsybl.commons.ref.Ref;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.util.SwitchPredicates;
import gnu.trove.list.array.TDoubleArrayList;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

Expand All @@ -33,7 +32,7 @@ abstract class AbstractTerminal implements TerminalExt {

protected VoltageLevelExt voltageLevel;

protected final List<RegulatingPoint> regulated = new ArrayList<>();
protected final ReferrerManager<Terminal> referrerManager = new ReferrerManager<>(this);

// attributes depending on the variant

Expand Down Expand Up @@ -94,12 +93,6 @@ public void setVoltageLevel(VoltageLevelExt voltageLevel) {
}
}

@Override
public void removeAsRegulationPoint() {
regulated.forEach(RegulatingPoint::removeRegulatingTerminal);
regulated.clear();
}

@Override
public double getP() {
if (removed) {
Expand Down Expand Up @@ -250,12 +243,12 @@ public void remove() {
}

@Override
public void setAsRegulatingPoint(RegulatingPoint rp) {
regulated.add(rp);
public ReferrerManager<Terminal> getReferrerManager() {
return referrerManager;
}

@Override
public void removeRegulatingPoint(RegulatingPoint rp) {
regulated.remove(rp);
public List<Object> getReferrers() {
return referrerManager.getReferrers().stream().map(r -> (Object) r).toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,9 @@ public class AreaImpl extends AbstractIdentifiable<Area> implements Area {

private final TDoubleArrayList interchangeTarget;

private final class AreaListener extends DefaultNetworkListener {
@Override
public void beforeRemoval(Identifiable<?> identifiable) {
if (identifiable instanceof DanglingLine danglingLine) {
// if dangling line removed from network, remove its boundary from this extension
AreaImpl.this.removeAreaBoundary(danglingLine.getBoundary());
} else if (identifiable instanceof Connectable<?> connectable) {
// if connectable removed from network, remove its terminals from this extension
connectable.getTerminals().forEach(AreaImpl.this::removeAreaBoundary);
}
// When a VoltageLevel is removed, its areas' voltageLevels attributes are directly updated. This is not managed via this listener.
}
}
private final Referrer<Terminal> terminalReferrer = this::removeAreaBoundary;

/**
* 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;
private final Referrer<Boundary> boundaryReferrer = this::removeAreaBoundary;

AreaImpl(Ref<NetworkImpl> ref, Ref<SubnetworkImpl> subnetworkRef, String id, String name, boolean fictitious, String areaType,
double interchangeTarget) {
Expand All @@ -74,8 +52,6 @@ void moveListener(NetworkImpl fromNetwork, NetworkImpl toNetwork) {
for (int i = 0; i < variantArraySize; i++) {
this.interchangeTarget.add(interchangeTarget);
}
this.areaListener = new AreaListener();
getNetwork().addListener(this.areaListener);
}

@Override
Expand Down Expand Up @@ -229,8 +205,14 @@ public Stream<AreaBoundary> getAreaBoundaryStream() {
protected void addAreaBoundary(AreaBoundaryImpl areaBoundary) {
Optional<Terminal> terminal = areaBoundary.getTerminal();
Optional<Boundary> boundary = areaBoundary.getBoundary();
boundary.ifPresent(b -> checkBoundaryNetwork(b.getDanglingLine().getParentNetwork(), "Boundary of DanglingLine" + b.getDanglingLine().getId()));
terminal.ifPresent(t -> checkBoundaryNetwork(t.getConnectable().getParentNetwork(), "Terminal of connectable " + t.getConnectable().getId()));
boundary.ifPresent(b -> {
checkBoundaryNetwork(b.getDanglingLine().getParentNetwork(), "Boundary of DanglingLine" + b.getDanglingLine().getId());
((DanglingLineBoundaryImplExt) b).getReferrerManager().register(boundaryReferrer);
});
terminal.ifPresent(t -> {
checkBoundaryNetwork(t.getConnectable().getParentNetwork(), "Terminal of connectable " + t.getConnectable().getId());
((TerminalExt) t).getReferrerManager().register(terminalReferrer);
});
areaBoundaries.add(areaBoundary);
}

Expand All @@ -248,8 +230,11 @@ public void remove() {
for (VoltageLevel voltageLevel : new HashSet<>(voltageLevels)) {
voltageLevel.removeArea(this);
}
for (AreaBoundary areaBoundary : areaBoundaries) {
areaBoundary.getTerminal().ifPresent(t -> ((TerminalExt) t).getReferrerManager().unregister(terminalReferrer));
areaBoundary.getBoundary().ifPresent(b -> ((DanglingLineBoundaryImplExt) b).getReferrerManager().unregister(boundaryReferrer));
}
network.getListeners().notifyAfterRemoval(id);
network.removeListener(this.areaListener);
removed = true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (c) 2024, 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.network.impl;

import com.powsybl.iidm.network.Boundary;
import com.powsybl.iidm.network.DanglingLine;
import com.powsybl.iidm.network.util.DanglingLineBoundaryImpl;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public class DanglingLineBoundaryImplExt extends DanglingLineBoundaryImpl {

protected final ReferrerManager<Boundary> referrerManager = new ReferrerManager<>(this);

public DanglingLineBoundaryImplExt(DanglingLine parent) {
super(parent);
}

public ReferrerManager<Boundary> getReferrerManager() {
return referrerManager;
}

void remove() {
referrerManager.notifyOfRemoval();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import com.powsybl.commons.util.trove.TBooleanArrayList;
import com.powsybl.iidm.network.*;
import com.powsybl.commons.ref.Ref;
import com.powsybl.iidm.network.util.DanglingLineBoundaryImpl;
import gnu.trove.list.array.TDoubleArrayList;

import java.util.Collection;
Expand Down Expand Up @@ -259,7 +258,7 @@ void allocateVariantArrayElement(int[] indexes, int sourceIndex) {

private final TDoubleArrayList q0;

private final DanglingLineBoundaryImpl boundary;
private final DanglingLineBoundaryImplExt boundary;

DanglingLineImpl(Ref<NetworkImpl> network, String id, String name, boolean fictitious, double p0, double q0, double r, double x, double g, double b, String pairingKey, GenerationImpl generation) {
super(network, id, name, fictitious);
Expand All @@ -277,7 +276,7 @@ void allocateVariantArrayElement(int[] indexes, int sourceIndex) {
this.b = b;
this.pairingKey = pairingKey;
this.operationalLimitsGroups = new OperationalLimitsGroupsImpl(this, "limits");
this.boundary = new DanglingLineBoundaryImpl(this);
this.boundary = new DanglingLineBoundaryImplExt(this);
this.generation = generation != null ? generation.attach(this) : null;
}

Expand Down Expand Up @@ -309,6 +308,7 @@ public void remove() {
throw new UnsupportedOperationException("Parent tie line " + tieLine.getId() + " should be removed before the child dangling line");
}
super.remove();
boundary.remove();
}

void removeTieLine() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public GeneratorImpl add() {
= new GeneratorImpl(getNetworkRef(),
id, getName(), isFictitious(), energySource,
minP, maxP,
voltageRegulatorOn, regulatingTerminal != null ? regulatingTerminal : terminal,
voltageRegulatorOn, regulatingTerminal,
targetP, targetQ, targetV,
ratedS, isCondenser);
generator.addTerminal(terminal);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class GeneratorImpl extends AbstractConnectable<Generator> implements Generator,
this.reactiveLimits = new ReactiveLimitsHolderImpl(this, new MinMaxReactiveLimitsImpl(-Double.MAX_VALUE, Double.MAX_VALUE));
this.ratedS = ratedS;
int variantArraySize = network.get().getVariantManager().getVariantArraySize();
regulatingPoint = new RegulatingPoint(id, this::getTerminal, variantArraySize, voltageRegulatorOn, voltageRegulatorOn);
regulatingPoint = new RegulatingPoint(id, this::getTerminal, variantArraySize, voltageRegulatorOn, true);
regulatingPoint.setRegulatingTerminal(regulatingTerminal);
this.targetP = new TDoubleArrayList(variantArraySize);
this.targetQ = new TDoubleArrayList(variantArraySize);
Expand Down Expand Up @@ -129,7 +129,6 @@ public GeneratorImpl setVoltageRegulatorOn(boolean voltageRegulatorOn) {
voltageRegulatorOn, targetV.get(variantIndex), targetQ.get(variantIndex),
n.getMinValidationLevel(), n.getReportNodeContext().getReportNode());
boolean oldValue = regulatingPoint.setRegulating(variantIndex, voltageRegulatorOn);
regulatingPoint.setUseVoltageRegulation(voltageRegulatorOn);
String variantId = network.get().getVariantManager().getVariantId(variantIndex);
n.invalidateValidationLevel();
notifyUpdate("voltageRegulatorOn", variantId, oldValue, voltageRegulatorOn);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1015,11 +1015,6 @@ 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 @@ -131,7 +131,7 @@ public PhaseTapChangerImpl setRegulationTerminal(Terminal regulationTerminal) {

@Override
public void remove() {
regulatingPoint.remove();
super.remove();
parent.setPhaseTapChanger(null);
}

Expand Down
Loading