BusTerminal.java
/**
* Copyright (c) 2016, All partners of the iTesla project (http://www.itesla-project.eu/consortium)
* 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.PowsyblException;
import com.powsybl.commons.util.trove.TBooleanArrayList;
import com.powsybl.iidm.network.Terminal;
import com.powsybl.iidm.network.ThreeSides;
import com.powsybl.iidm.network.TopologyPoint;
import com.powsybl.commons.ref.Ref;
import com.powsybl.math.graph.TraversalType;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Set;
/**
* A terminal connected to a bus/breaker topology.
*
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
class BusTerminal extends AbstractTerminal {
private BusBreakerTopologyModel getTopologyModel() {
return (BusBreakerTopologyModel) voltageLevel.getTopologyModel();
}
private final NodeBreakerView nodeBreakerView = new NodeBreakerView() {
@Override
public int getNode() {
throw BusBreakerTopologyModel.createNotSupportedBusBreakerTopologyException();
}
@Override
public void moveConnectable(int node, String voltageLevelId) {
if (removed) {
throw new PowsyblException(UNMODIFIABLE_REMOVED_EQUIPMENT + connectable.id);
}
getConnectable().move(BusTerminal.this, node, voltageLevelId);
}
};
private final BusBreakerViewExt busBreakerView = new BusBreakerViewExt() {
@Override
public BusExt getBus() {
if (removed) {
throw new PowsyblException(CANNOT_ACCESS_BUS_REMOVED_EQUIPMENT + connectable.id);
}
return isConnected() ? getConnectableBus() : null;
}
@Override
public ConfiguredBus getConnectableBus() {
if (removed) {
throw new PowsyblException(CANNOT_ACCESS_BUS_REMOVED_EQUIPMENT + connectable.id);
}
return getTopologyModel().getBus(getConnectableBusId(), true);
}
@Override
public void setConnectableBus(String busId) {
if (removed) {
throw new PowsyblException(UNMODIFIABLE_REMOVED_EQUIPMENT + connectable.id);
}
Objects.requireNonNull(busId);
BusBreakerTopologyModel topologyModel = getTopologyModel();
// Assert that the new bus exists
topologyModel.getBus(busId, true);
topologyModel.detach(BusTerminal.this);
int variantIndex = getVariantManagerHolder().getVariantIndex();
String oldValue = BusTerminal.this.connectableBusId.set(variantIndex, busId);
topologyModel.attach(BusTerminal.this, false);
String variantId = getVariantManagerHolder().getVariantManager().getVariantId(variantIndex);
getConnectable().notifyUpdate("connectableBusId", variantId, oldValue, busId);
}
@Override
public void moveConnectable(String busId, boolean connected) {
if (removed) {
throw new PowsyblException(UNMODIFIABLE_REMOVED_EQUIPMENT + connectable.id);
}
getConnectable().move(BusTerminal.this, busId, connected);
}
};
@Override
public TopologyPoint getTopologyPoint() {
return new BusTopologyPointImpl(getVoltageLevel().getId(), getConnectableBusId(), isConnected());
}
private final BusViewExt busView = new BusViewExt() {
@Override
public BusExt getBus() {
if (removed) {
throw new PowsyblException(CANNOT_ACCESS_BUS_REMOVED_EQUIPMENT + connectable.id);
}
return isConnected() ? this.getConnectableBus() : null;
}
@Override
public MergedBus getConnectableBus() {
if (removed) {
throw new PowsyblException(CANNOT_ACCESS_BUS_REMOVED_EQUIPMENT + connectable.id);
}
ConfiguredBus bus = getTopologyModel().getBus(getConnectableBusId(), true);
return getTopologyModel().calculatedBusTopology.getMergedBus(bus);
}
};
// attributes depending on the variant
private final TBooleanArrayList connected;
private final ArrayList<String> connectableBusId;
BusTerminal(Ref<? extends VariantManagerHolder> network, ThreeSides side, String connectableBusId, boolean connected) {
super(network, side);
Objects.requireNonNull(connectableBusId);
int variantArraySize = network.get().getVariantManager().getVariantArraySize();
this.connected = new TBooleanArrayList(variantArraySize);
this.connectableBusId = new ArrayList<>(variantArraySize);
for (int i = 0; i < variantArraySize; i++) {
this.connected.add(connected);
this.connectableBusId.add(connectableBusId);
}
}
void unsetConnectableBusId() {
if (removed) {
throw new PowsyblException(UNMODIFIABLE_REMOVED_EQUIPMENT + connectable.id);
}
int variantIndex = getVariantManagerHolder().getVariantIndex();
this.connectableBusId.set(variantIndex, null);
}
String getConnectableBusId() {
if (removed) {
throw new PowsyblException(CANNOT_ACCESS_BUS_REMOVED_EQUIPMENT + connectable.id);
}
return this.connectableBusId.get(getVariantManagerHolder().getVariantIndex());
}
void setConnected(boolean connected) {
if (removed) {
throw new PowsyblException(UNMODIFIABLE_REMOVED_EQUIPMENT + connectable.id);
}
int variantIndex = getVariantManagerHolder().getVariantIndex();
boolean oldValue = this.connected.set(variantIndex, connected);
String variantId = getVariantManagerHolder().getVariantManager().getVariantId(variantIndex);
getConnectable().notifyUpdate("connected" + getAttributeSideSuffix(), variantId, oldValue, connected);
}
@Override
public boolean isConnected() {
if (removed) {
throw new PowsyblException("Cannot access connectivity status of removed equipment " + connectable.id);
}
return this.connected.get(getVariantManagerHolder().getVariantIndex());
}
@Override
public boolean traverse(TopologyTraverser traverser, Set<Terminal> visitedTerminals, TraversalType traversalType) {
if (removed) {
throw new PowsyblException(String.format("Associated equipment %s is removed", connectable.id));
}
return getTopologyModel().traverse(this, traverser, visitedTerminals, traversalType);
}
@Override
public void traverse(TopologyTraverser traverser) {
traverse(traverser, TraversalType.DEPTH_FIRST);
}
@Override
public void traverse(TopologyTraverser traverser, TraversalType traversalType) {
if (removed) {
throw new PowsyblException(String.format("Associated equipment %s is removed", connectable.id));
}
getTopologyModel().traverse(this, traverser, traversalType);
}
@Override
protected double getV() {
if (removed) {
throw new PowsyblException("Cannot access v of removed equipment " + connectable.id);
}
return busBreakerView.getBus() != null ? busBreakerView.getBus().getV() : Double.NaN;
}
@Override
public NodeBreakerView getNodeBreakerView() {
return nodeBreakerView;
}
@Override
public BusBreakerViewExt getBusBreakerView() {
return busBreakerView;
}
@Override
public BusViewExt getBusView() {
return busView;
}
@Override
public String toString() {
return getClass().getSimpleName() + "[" + getConnectableBusId() + "]";
}
@Override
public void extendVariantArraySize(int initVariantArraySize, int number, int sourceIndex) {
super.extendVariantArraySize(initVariantArraySize, number, sourceIndex);
connected.ensureCapacity(connected.size() + number);
connectableBusId.ensureCapacity(connectableBusId.size() + number);
for (int i = 0; i < number; i++) {
connected.add(connected.get(sourceIndex));
connectableBusId.add(connectableBusId.get(sourceIndex));
}
}
@Override
public void reduceVariantArraySize(int number) {
super.reduceVariantArraySize(number);
for (int i = 0; i < number; i++) {
connected.removeAt(connected.size() - 1);
connectableBusId.remove(connectableBusId.size() - 1);
}
}
@Override
public void deleteVariantArrayElement(int index) {
super.deleteVariantArrayElement(index);
connectableBusId.set(index, null);
}
@Override
public void allocateVariantArrayElement(int[] indexes, int sourceIndex) {
super.allocateVariantArrayElement(indexes, sourceIndex);
for (int index : indexes) {
connected.set(index, connected.get(sourceIndex));
connectableBusId.set(index, connectableBusId.get(sourceIndex));
}
}
}