From dcb23387a30bbb1dfabb2df0b343e850292c4196 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Thu, 7 Nov 2024 10:17:32 +0100 Subject: [PATCH] Refactor voltage level topology implementation (#3196) * Refactor voltage level topology implementation Signed-off-by: Geoffroy Jamgotchian --- .../network/impl/AbstractConnectable.java | 6 +- .../iidm/network/impl/AbstractTerminal.java | 4 +- .../network/impl/AbstractTopologyModel.java | 150 ++++++++++++++++ .../iidm/network/impl/BatteryAdderImpl.java | 2 +- .../iidm/network/impl/BusAdderImpl.java | 6 +- ...evel.java => BusBreakerTopologyModel.java} | 90 +++++----- .../iidm/network/impl/BusTerminal.java | 24 +-- .../network/impl/BusbarSectionAdderImpl.java | 2 +- .../iidm/network/impl/CalculatedBusImpl.java | 4 +- .../network/impl/ConnectDisconnectUtil.java | 16 +- .../network/impl/DanglingLineAdderImpl.java | 2 +- .../iidm/network/impl/GeneratorAdderImpl.java | 2 +- .../iidm/network/impl/GroundAdderImpl.java | 2 +- .../impl/LccConverterStationAdderImpl.java | 2 +- .../iidm/network/impl/LineAdderImpl.java | 8 +- .../iidm/network/impl/LoadAdderImpl.java | 2 +- .../iidm/network/impl/NetworkImpl.java | 9 +- ...vel.java => NodeBreakerTopologyModel.java} | 121 ++++++------- .../iidm/network/impl/NodeTerminal.java | 20 ++- .../impl/ShuntCompensatorAdderImpl.java | 2 +- .../impl/StaticVarCompensatorAdderImpl.java | 2 +- .../powsybl/iidm/network/impl/SwitchImpl.java | 6 +- .../ThreeWindingsTransformerAdderImpl.java | 12 +- .../iidm/network/impl/TopologyModel.java | 28 +++ .../impl/TwoWindingsTransformerAdderImpl.java | 8 +- .../network/impl/VoltageLevelAdderImpl.java | 7 +- .../iidm/network/impl/VoltageLevelExt.java | 29 +-- ...oltageLevel.java => VoltageLevelImpl.java} | 169 +++++++++++------- .../impl/VscConverterStationAdderImpl.java | 2 +- .../network/impl/NodeBreakerConnectTest.java | 8 +- ...el.java => TestAbstractTopologyModel.java} | 8 +- 31 files changed, 467 insertions(+), 286 deletions(-) create mode 100644 iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractTopologyModel.java rename iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/{BusBreakerVoltageLevel.java => BusBreakerTopologyModel.java} (91%) rename iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/{NodeBreakerVoltageLevel.java => NodeBreakerTopologyModel.java} (91%) create mode 100644 iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/TopologyModel.java rename iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/{AbstractVoltageLevel.java => VoltageLevelImpl.java} (81%) rename iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/{TestAbstractVoltageLevel.java => TestAbstractTopologyModel.java} (80%) diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractConnectable.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractConnectable.java index 7025a5084bf..756f6be24a2 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractConnectable.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractConnectable.java @@ -72,7 +72,7 @@ public void remove() { for (TerminalExt terminal : terminals) { terminal.removeAsRegulationPoint(); VoltageLevelExt vl = terminal.getVoltageLevel(); - vl.detach(terminal); + vl.getTopologyModel().detach(terminal); } network.getListeners().notifyAfterRemoval(id); @@ -181,10 +181,10 @@ protected void move(TerminalExt oldTerminal, TopologyPoint oldTopologyPoint, Str private void attachTerminal(TerminalExt oldTerminal, TopologyPoint oldTopologyPoint, VoltageLevelExt voltageLevel, TerminalExt terminalExt) { // first, attach new terminal to connectable and to voltage level of destination, to ensure that the new terminal is valid terminalExt.setConnectable(this); - voltageLevel.attach(terminalExt, false); + voltageLevel.getTopologyModel().attach(terminalExt, false); // then we can detach the old terminal, as we now know that the new terminal is valid - oldTerminal.getVoltageLevel().detach(oldTerminal); + oldTerminal.getVoltageLevel().getTopologyModel().detach(oldTerminal); // replace the old terminal by the new terminal in the connectable int iSide = terminals.indexOf(oldTerminal); diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractTerminal.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractTerminal.java index 58e89278588..0f7d2f336e1 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractTerminal.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractTerminal.java @@ -182,7 +182,7 @@ public boolean connect(Predicate isTypeSwitchToOperate) { String variantId = getVariantManagerHolder().getVariantManager().getVariantId(variantIndex); boolean connectedBefore = isConnected(); connectable.notifyUpdate("beginConnect", variantId, connectedBefore, null); - boolean connected = voltageLevel.connect(this, isTypeSwitchToOperate); + boolean connected = voltageLevel.getTopologyModel().connect(this, isTypeSwitchToOperate); boolean connectedAfter = isConnected(); connectable.notifyUpdate("endConnect", variantId, null, connectedAfter); return connected; @@ -209,7 +209,7 @@ public boolean disconnect(Predicate isSwitchOpenable) { String variantId = getVariantManagerHolder().getVariantManager().getVariantId(variantIndex); boolean disconnectedBefore = !isConnected(); connectable.notifyUpdate("beginDisconnect", variantId, disconnectedBefore, null); - boolean disconnected = voltageLevel.disconnect(this, isSwitchOpenable); + boolean disconnected = voltageLevel.getTopologyModel().disconnect(this, isSwitchOpenable); boolean disconnectedAfter = !isConnected(); connectable.notifyUpdate("endDisconnect", variantId, null, disconnectedAfter); return disconnected; diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractTopologyModel.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractTopologyModel.java new file mode 100644 index 00000000000..91079102ccd --- /dev/null +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractTopologyModel.java @@ -0,0 +1,150 @@ +/** + * 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.google.common.collect.FluentIterable; +import com.google.common.primitives.Ints; +import com.powsybl.commons.config.PlatformConfig; +import com.powsybl.iidm.network.*; +import com.powsybl.iidm.network.util.ShortIdDictionary; + +import java.io.IOException; +import java.io.PrintStream; +import java.io.Writer; +import java.nio.file.Path; +import java.util.List; +import java.util.Objects; +import java.util.Random; +import java.util.stream.Stream; + +/** + * @author Geoffroy Jamgotchian {@literal } + */ +abstract class AbstractTopologyModel implements TopologyModel { + + public static final int DEFAULT_NODE_INDEX_LIMIT = 1000; + + public static final int NODE_INDEX_LIMIT = loadNodeIndexLimit(PlatformConfig.defaultConfig()); + + protected final VoltageLevelExt voltageLevel; + + protected AbstractTopologyModel(VoltageLevelExt voltageLevel) { + this.voltageLevel = Objects.requireNonNull(voltageLevel); + } + + protected static int loadNodeIndexLimit(PlatformConfig platformConfig) { + return platformConfig + .getOptionalModuleConfig("iidm") + .map(moduleConfig -> moduleConfig.getIntProperty("node-index-limit", DEFAULT_NODE_INDEX_LIMIT)) + .orElse(DEFAULT_NODE_INDEX_LIMIT); + } + + protected NetworkImpl getNetwork() { + return voltageLevel.getNetwork(); + } + + protected static void addNextTerminals(TerminalExt otherTerminal, List nextTerminals) { + Objects.requireNonNull(otherTerminal); + Objects.requireNonNull(nextTerminals); + Connectable otherConnectable = otherTerminal.getConnectable(); + if (otherConnectable instanceof Branch branch) { + if (branch.getTerminal1() == otherTerminal) { + nextTerminals.add((TerminalExt) branch.getTerminal2()); + } else if (branch.getTerminal2() == otherTerminal) { + nextTerminals.add((TerminalExt) branch.getTerminal1()); + } else { + throw new IllegalStateException(); + } + } else if (otherConnectable instanceof ThreeWindingsTransformer ttc) { + if (ttc.getLeg1().getTerminal() == otherTerminal) { + nextTerminals.add((TerminalExt) ttc.getLeg2().getTerminal()); + nextTerminals.add((TerminalExt) ttc.getLeg3().getTerminal()); + } else if (ttc.getLeg2().getTerminal() == otherTerminal) { + nextTerminals.add((TerminalExt) ttc.getLeg1().getTerminal()); + nextTerminals.add((TerminalExt) ttc.getLeg3().getTerminal()); + } else if (ttc.getLeg3().getTerminal() == otherTerminal) { + nextTerminals.add((TerminalExt) ttc.getLeg1().getTerminal()); + nextTerminals.add((TerminalExt) ttc.getLeg2().getTerminal()); + } else { + throw new IllegalStateException(); + } + } + } + + public void invalidateCache() { + invalidateCache(false); + } + + public abstract Iterable getTerminals(); + + public abstract Stream getTerminalStream(); + + public Iterable getConnectables(Class clazz) { + Iterable terminals = getTerminals(); + return FluentIterable.from(terminals) + .transform(Terminal::getConnectable) + .filter(clazz) + .toSet(); + } + + public Stream getConnectableStream(Class clazz) { + return getTerminalStream() + .map(Terminal::getConnectable) + .filter(clazz::isInstance) + .map(clazz::cast) + .distinct(); + } + + public int getConnectableCount(Class clazz) { + return Ints.checkedCast(getConnectableStream(clazz).count()); + } + + public Iterable getConnectables() { + return FluentIterable.from(getTerminals()) + .transform(Terminal::getConnectable) + .toSet(); + } + + public Stream getConnectableStream() { + return getTerminalStream() + .map(Terminal::getConnectable) + .distinct(); + } + + public abstract VoltageLevelExt.NodeBreakerViewExt getNodeBreakerView(); + + public abstract VoltageLevelExt.BusBreakerViewExt getBusBreakerView(); + + public abstract VoltageLevelExt.BusViewExt getBusView(); + + public abstract Iterable getSwitches(); + + public abstract int getSwitchCount(); + + public abstract TopologyKind getTopologyKind(); + + public abstract void extendVariantArraySize(int initVariantArraySize, int number, int sourceIndex); + + public abstract void reduceVariantArraySize(int number); + + public abstract void deleteVariantArrayElement(int index); + + public abstract void allocateVariantArrayElement(int[] indexes, int sourceIndex); + + protected abstract void removeTopology(); + + public abstract void printTopology(); + + public abstract void printTopology(PrintStream out, ShortIdDictionary dict); + + public abstract void exportTopology(Path file) throws IOException; + + public abstract void exportTopology(Writer writer); + + public abstract void exportTopology(Writer writer, Random random); +} diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BatteryAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BatteryAdderImpl.java index dbe328bfa95..d865fce6cbe 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BatteryAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BatteryAdderImpl.java @@ -92,7 +92,7 @@ public BatteryImpl add() { BatteryImpl battery = new BatteryImpl(getNetworkRef(), id, getName(), isFictitious(), targetP, targetQ, minP, maxP); battery.addTerminal(terminal); - voltageLevel.attach(terminal, false); + voltageLevel.getTopologyModel().attach(terminal, false); network.getIndex().checkAndAdd(battery); network.getListeners().notifyCreation(battery); return battery; diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusAdderImpl.java index dd663b3173f..fa139ab2165 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusAdderImpl.java @@ -15,9 +15,9 @@ */ class BusAdderImpl extends AbstractIdentifiableAdder implements BusAdder { - private final BusBreakerVoltageLevel voltageLevel; + private final VoltageLevelExt voltageLevel; - BusAdderImpl(BusBreakerVoltageLevel voltageLevel) { + BusAdderImpl(VoltageLevelExt voltageLevel) { this.voltageLevel = voltageLevel; } @@ -35,7 +35,7 @@ protected String getTypeDescription() { public ConfiguredBus add() { String id = checkAndGetUniqueId(); ConfiguredBusImpl bus = new ConfiguredBusImpl(id, getName(), isFictitious(), voltageLevel); - voltageLevel.addBus(bus); + ((BusBreakerTopologyModel) voltageLevel.getTopologyModel()).addBus(bus); getNetwork().getListeners().notifyCreation(bus); return bus; } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusBreakerVoltageLevel.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusBreakerTopologyModel.java similarity index 91% rename from iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusBreakerVoltageLevel.java rename to iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusBreakerTopologyModel.java index cc565709153..8c62770a282 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusBreakerVoltageLevel.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusBreakerTopologyModel.java @@ -13,7 +13,6 @@ import com.powsybl.commons.PowsyblException; import com.powsybl.commons.util.Colors; import com.powsybl.iidm.network.*; -import com.powsybl.commons.ref.Ref; import com.powsybl.iidm.network.util.Identifiables; import com.powsybl.iidm.network.util.Networks; import com.powsybl.iidm.network.util.ShortIdDictionary; @@ -44,11 +43,11 @@ /** * @author Geoffroy Jamgotchian {@literal } */ -class BusBreakerVoltageLevel extends AbstractVoltageLevel { +class BusBreakerTopologyModel extends AbstractTopologyModel { private static final boolean DRAW_SWITCH_ID = true; - private final class SwitchAdderImpl extends AbstractIdentifiableAdder implements BusBreakerView.SwitchAdder { + private final class SwitchAdderImpl extends AbstractIdentifiableAdder implements VoltageLevel.BusBreakerView.SwitchAdder { private String busId1; @@ -61,7 +60,7 @@ private SwitchAdderImpl() { @Override protected NetworkImpl getNetwork() { - return BusBreakerVoltageLevel.this.getNetwork(); + return BusBreakerTopologyModel.this.getNetwork(); } @Override @@ -70,19 +69,19 @@ protected String getTypeDescription() { } @Override - public BusBreakerView.SwitchAdder setBus1(String bus1) { + public VoltageLevel.BusBreakerView.SwitchAdder setBus1(String bus1) { this.busId1 = bus1; return this; } @Override - public BusBreakerView.SwitchAdder setBus2(String bus2) { + public VoltageLevel.BusBreakerView.SwitchAdder setBus2(String bus2) { this.busId2 = bus2; return this; } @Override - public BusBreakerView.SwitchAdder setOpen(boolean open) { + public VoltageLevel.BusBreakerView.SwitchAdder setOpen(boolean open) { this.open = open; return this; } @@ -100,7 +99,7 @@ public Switch add() { throw new ValidationException(this, "same bus at both ends"); } - SwitchImpl aSwitch = new SwitchImpl(BusBreakerVoltageLevel.this, id, getName(), isFictitious(), SwitchKind.BREAKER, open, true); + SwitchImpl aSwitch = new SwitchImpl(voltageLevel, id, getName(), isFictitious(), SwitchKind.BREAKER, open, true); addSwitch(aSwitch, busId1, busId2); getNetwork().getListeners().notifyCreation(aSwitch); return aSwitch; @@ -122,7 +121,7 @@ private Integer getVertex(String busId, boolean throwException) { if (throwException && v == null) { throw new PowsyblException("Bus " + busId + " not found in voltage level " - + BusBreakerVoltageLevel.this.id); + + voltageLevel.getId()); } return v; } @@ -145,7 +144,7 @@ private Integer getEdge(String switchId, boolean throwException) { if (throwException && e == null) { throw new PowsyblException("Switch " + switchId + " not found in voltage level" - + BusBreakerVoltageLevel.this.id); + + voltageLevel.getId()); } return e; } @@ -215,9 +214,9 @@ protected boolean isBusValid(Set busSet) { private MergedBus createMergedBus(int busNum, Set busSet) { String suffix = "_" + busNum; - String mergedBusId = Identifiables.getUniqueId(BusBreakerVoltageLevel.this.id + suffix, getNetwork().getIndex()::contains); - String mergedBusName = BusBreakerVoltageLevel.this.name != null ? BusBreakerVoltageLevel.this.name + suffix : null; - return new MergedBus(mergedBusId, mergedBusName, BusBreakerVoltageLevel.this.fictitious, busSet); + String mergedBusId = Identifiables.getUniqueId(voltageLevel.getId() + suffix, getNetwork().getIndex()::contains); + String mergedBusName = voltageLevel.getOptionalName().map(name -> name + suffix).orElse(null); + return new MergedBus(mergedBusId, mergedBusName, voltageLevel.isFictitious(), busSet); } private void updateCache() { @@ -278,7 +277,7 @@ private MergedBus getMergedBus(String mergedBusId, boolean throwException) { if (throwException && bus == null) { throw new PowsyblException("Bus " + mergedBusId + " not found in voltage level " - + BusBreakerVoltageLevel.this.id); + + voltageLevel.getId()); } return bus; } @@ -309,11 +308,10 @@ public VariantImpl copy() { protected final VariantArray variants; - BusBreakerVoltageLevel(String id, String name, boolean fictitious, SubstationImpl substation, Ref ref, - Ref subnetworkRef, double nominalV, double lowVoltageLimit, double highVoltageLimit) { - super(id, name, fictitious, substation, ref, subnetworkRef, nominalV, lowVoltageLimit, highVoltageLimit); + BusBreakerTopologyModel(VoltageLevelExt voltageLevel) { + super(voltageLevel); // the ref object of the variant array is the same as the current object - variants = new VariantArray<>(ref, VariantImpl::new); + variants = new VariantArray<>(voltageLevel.getNetworkRef(), VariantImpl::new); // invalidate topology and connected components graph.addListener(new UndirectedGraphListener<>() { @Override @@ -388,14 +386,14 @@ static PowsyblException createNotSupportedBusBreakerTopologyException() { return new PowsyblException("Not supported in a bus breaker topology"); } - private final NodeBreakerViewExt nodeBreakerView = new NodeBreakerViewExt() { + private final VoltageLevelExt.NodeBreakerViewExt nodeBreakerView = new VoltageLevelExt.NodeBreakerViewExt() { @Override public double getFictitiousP0(int node) { throw createNotSupportedBusBreakerTopologyException(); } @Override - public NodeBreakerView setFictitiousP0(int node, double p0) { + public VoltageLevel.NodeBreakerView setFictitiousP0(int node, double p0) { throw createNotSupportedBusBreakerTopologyException(); } @@ -405,7 +403,7 @@ public double getFictitiousQ0(int node) { } @Override - public NodeBreakerView setFictitiousQ0(int node, double q0) { + public VoltageLevel.NodeBreakerView setFictitiousQ0(int node, double q0) { throw createNotSupportedBusBreakerTopologyException(); } @@ -576,11 +574,11 @@ public void traverse(int[] node, TopologyTraverser traverser) { }; @Override - public NodeBreakerViewExt getNodeBreakerView() { + public VoltageLevelExt.NodeBreakerViewExt getNodeBreakerView() { return nodeBreakerView; } - private final BusBreakerViewExt busBreakerView = new BusBreakerViewExt() { + private final VoltageLevelExt.BusBreakerViewExt busBreakerView = new VoltageLevelExt.BusBreakerViewExt() { @Override public Iterable getBuses() { @@ -599,22 +597,22 @@ public int getBusCount() { @Override public ConfiguredBus getBus(String id) { - return BusBreakerVoltageLevel.this.getBus(id, false); + return BusBreakerTopologyModel.this.getBus(id, false); } @Override public BusAdder newBus() { - return new BusAdderImpl(BusBreakerVoltageLevel.this); + return new BusAdderImpl(voltageLevel); } @Override public void removeBus(String busId) { - BusBreakerVoltageLevel.this.removeBus(busId); + BusBreakerTopologyModel.this.removeBus(busId); } @Override public void removeAllBuses() { - BusBreakerVoltageLevel.this.removeAllBuses(); + BusBreakerTopologyModel.this.removeAllBuses(); } @Override @@ -634,12 +632,12 @@ public int getSwitchCount() { @Override public void removeSwitch(String switchId) { - BusBreakerVoltageLevel.this.removeSwitch(switchId); + BusBreakerTopologyModel.this.removeSwitch(switchId); } @Override public void removeAllSwitches() { - BusBreakerVoltageLevel.this.removeAllSwitches(); + BusBreakerTopologyModel.this.removeAllSwitches(); } @Override @@ -671,11 +669,11 @@ public Stream getBusStreamFromBusViewBusId(String mergedBusId) { @Override public SwitchImpl getSwitch(String switchId) { - return BusBreakerVoltageLevel.this.getSwitch(switchId, false); + return BusBreakerTopologyModel.this.getSwitch(switchId, false); } @Override - public BusBreakerView.SwitchAdder newSwitch() { + public VoltageLevel.BusBreakerView.SwitchAdder newSwitch() { return new SwitchAdderImpl(); } @@ -690,11 +688,11 @@ public void traverse(Bus bus, TopologyTraverser traverser) { }; @Override - public BusBreakerViewExt getBusBreakerView() { + public VoltageLevelExt.BusBreakerViewExt getBusBreakerView() { return busBreakerView; } - private final BusViewExt busView = new BusViewExt() { + private final VoltageLevelExt.BusViewExt busView = new VoltageLevelExt.BusViewExt() { @Override public Iterable getBuses() { @@ -719,7 +717,7 @@ public Bus getMergedBus(String configuredBusId) { }; @Override - public BusViewExt getBusView() { + public VoltageLevelExt.BusViewExt getBusView() { return busView; } @@ -748,7 +746,7 @@ void addBus(ConfiguredBus bus) { private void removeBus(String busId) { ConfiguredBus bus = getBus(busId, true); if (bus.getTerminalCount() > 0) { - throw new ValidationException(this, "Cannot remove bus " + throw new ValidationException(voltageLevel, "Cannot remove bus " + bus.getId() + " because of connectable equipments"); } // TODO improve check efficency @@ -777,11 +775,11 @@ private void removeBus(String busId) { private void removeAllBuses() { if (graph.getEdgeCount() > 0) { - throw new ValidationException(this, "Cannot remove all buses because there is still some switches"); + throw new ValidationException(voltageLevel, "Cannot remove all buses because there is still some switches"); } for (ConfiguredBus bus : graph.getVerticesObj()) { if (bus.getTerminalCount() > 0) { - throw new ValidationException(this, "Cannot remove bus " + throw new ValidationException(voltageLevel, "Cannot remove bus " + bus.getId() + " because of connected equipments"); } } @@ -811,7 +809,7 @@ private void removeSwitch(String switchId) { Integer e = switches.get(switchId); if (e == null) { throw new PowsyblException("Switch '" + switchId - + "' not found in voltage level '" + id + "'"); + + "' not found in voltage level '" + voltageLevel.getId() + "'"); } NetworkImpl network = getNetwork(); SwitchImpl aSwitch = graph.getEdgeObject(e); @@ -845,7 +843,7 @@ private void removeAllSwitches() { private void checkTerminal(TerminalExt terminal) { if (!(terminal instanceof BusTerminal)) { throw new ValidationException(terminal.getConnectable(), - "voltage level " + BusBreakerVoltageLevel.this.id + " has a bus/breaker topology" + "voltage level " + voltageLevel.getId() + " has a bus/breaker topology" + ", a bus connection should be specified instead of a node connection"); } @@ -863,7 +861,7 @@ public void attach(final TerminalExt terminal, boolean test) { return; } // create the link terminal -> voltage level - terminal.setVoltageLevel(this); + terminal.setVoltageLevel(voltageLevel); // create the link bus -> terminal String connectableBusId = ((BusTerminal) terminal).getConnectableBusId(); @@ -899,8 +897,7 @@ public void detach(final TerminalExt terminal) { terminal.setVoltageLevel(null); } - @Override - public boolean connect(TerminalExt terminal) { + boolean connect(TerminalExt terminal) { if (!(terminal instanceof BusTerminal)) { throw new IllegalStateException("Given TerminalExt not supported: " + terminal.getClass().getName()); } @@ -923,8 +920,7 @@ public boolean connect(TerminalExt terminal, Predicate isTyp return connect(terminal); } - @Override - public boolean disconnect(TerminalExt terminal) { + boolean disconnect(TerminalExt terminal) { if (!(terminal instanceof BusTerminal)) { throw new IllegalStateException("Given TerminalExt not supported: " + terminal.getClass().getName()); } @@ -1021,25 +1017,21 @@ private static TraverseResult getTraverserResult(Set visitedTerminals, @Override public void extendVariantArraySize(int initVariantArraySize, int number, int sourceIndex) { - super.extendVariantArraySize(initVariantArraySize, number, sourceIndex); variants.push(number, () -> variants.copy(sourceIndex)); } @Override public void reduceVariantArraySize(int number) { - super.reduceVariantArraySize(number); variants.pop(number); } @Override public void deleteVariantArrayElement(int index) { - super.deleteVariantArrayElement(index); variants.delete(index); } @Override public void allocateVariantArrayElement(int[] indexes, final int sourceIndex) { - super.allocateVariantArrayElement(indexes, sourceIndex); variants.allocate(indexes, () -> variants.copy(sourceIndex)); } @@ -1057,7 +1049,7 @@ public void printTopology() { @Override public void printTopology(PrintStream out, ShortIdDictionary dict) { out.println("-------------------------------------------------------------"); - out.println("Topology of " + BusBreakerVoltageLevel.this.id); + out.println("Topology of " + voltageLevel.getId()); Function vertexToString = bus -> { StringBuilder builder = new StringBuilder(); diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusTerminal.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusTerminal.java index 80e92cf69f8..6444b9d43ce 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusTerminal.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusTerminal.java @@ -26,10 +26,14 @@ */ class BusTerminal extends AbstractTerminal { + private BusBreakerTopologyModel getTopologyModel() { + return (BusBreakerTopologyModel) voltageLevel.getTopologyModel(); + } + private final NodeBreakerView nodeBreakerView = new NodeBreakerView() { @Override public int getNode() { - throw BusBreakerVoltageLevel.createNotSupportedBusBreakerTopologyException(); + throw BusBreakerTopologyModel.createNotSupportedBusBreakerTopologyException(); } @Override @@ -56,7 +60,7 @@ public ConfiguredBus getConnectableBus() { if (removed) { throw new PowsyblException(CANNOT_ACCESS_BUS_REMOVED_EQUIPMENT + connectable.id); } - return ((BusBreakerVoltageLevel) voltageLevel).getBus(getConnectableBusId(), true); + return getTopologyModel().getBus(getConnectableBusId(), true); } @Override @@ -65,15 +69,15 @@ public void setConnectableBus(String busId) { throw new PowsyblException(UNMODIFIABLE_REMOVED_EQUIPMENT + connectable.id); } Objects.requireNonNull(busId); - BusBreakerVoltageLevel vl = (BusBreakerVoltageLevel) voltageLevel; + BusBreakerTopologyModel topologyModel = getTopologyModel(); // Assert that the new bus exists - vl.getBus(busId, true); + topologyModel.getBus(busId, true); - vl.detach(BusTerminal.this); + topologyModel.detach(BusTerminal.this); int variantIndex = getVariantManagerHolder().getVariantIndex(); String oldValue = BusTerminal.this.connectableBusId.set(variantIndex, busId); - vl.attach(BusTerminal.this, false); + topologyModel.attach(BusTerminal.this, false); String variantId = getVariantManagerHolder().getVariantManager().getVariantId(variantIndex); getConnectable().notifyUpdate("connectableBusId", variantId, oldValue, busId); } @@ -108,8 +112,8 @@ public MergedBus getConnectableBus() { if (removed) { throw new PowsyblException(CANNOT_ACCESS_BUS_REMOVED_EQUIPMENT + connectable.id); } - ConfiguredBus bus = ((BusBreakerVoltageLevel) voltageLevel).getBus(getConnectableBusId(), true); - return ((BusBreakerVoltageLevel) voltageLevel).calculatedBusTopology.getMergedBus(bus); + ConfiguredBus bus = getTopologyModel().getBus(getConnectableBusId(), true); + return getTopologyModel().calculatedBusTopology.getMergedBus(bus); } }; @@ -172,7 +176,7 @@ public boolean traverse(TopologyTraverser traverser, Set visitedTermin if (removed) { throw new PowsyblException(String.format("Associated equipment %s is removed", connectable.id)); } - return ((BusBreakerVoltageLevel) voltageLevel).traverse(this, traverser, visitedTerminals, traversalType); + return getTopologyModel().traverse(this, traverser, visitedTerminals, traversalType); } @Override @@ -185,7 +189,7 @@ public void traverse(TopologyTraverser traverser, TraversalType traversalType) { if (removed) { throw new PowsyblException(String.format("Associated equipment %s is removed", connectable.id)); } - ((BusBreakerVoltageLevel) voltageLevel).traverse(this, traverser, traversalType); + getTopologyModel().traverse(this, traverser, traversalType); } @Override diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusbarSectionAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusbarSectionAdderImpl.java index 1bd5708ecc7..0e513c7198b 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusbarSectionAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/BusbarSectionAdderImpl.java @@ -50,7 +50,7 @@ public BusbarSection add() { TerminalExt terminal = new NodeTerminal(voltageLevel.getNetworkRef(), null, node); BusbarSectionImpl section = new BusbarSectionImpl(voltageLevel.getNetworkRef(), id, getName(), isFictitious()); section.addTerminal(terminal); - voltageLevel.attach(terminal, false); + voltageLevel.getTopologyModel().attach(terminal, false); getNetwork().getIndex().checkAndAdd(section); getNetwork().getListeners().notifyCreation(section); return section; diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/CalculatedBusImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/CalculatedBusImpl.java index bf1cd008d4c..60907282a5b 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/CalculatedBusImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/CalculatedBusImpl.java @@ -29,7 +29,7 @@ class CalculatedBusImpl extends AbstractBus implements CalculatedBus { private NodeTerminal terminalRef; - CalculatedBusImpl(String id, String name, boolean fictitious, NodeBreakerVoltageLevel voltageLevel, TIntArrayList nodes, List terminals, Function getBusFromTerminal) { + CalculatedBusImpl(String id, String name, boolean fictitious, VoltageLevelExt voltageLevel, TIntArrayList nodes, List terminals, Function getBusFromTerminal) { super(id, name, fictitious, voltageLevel); this.terminals = Objects.requireNonNull(terminals); this.getBusFromTerminal = Objects.requireNonNull(getBusFromTerminal); @@ -47,7 +47,7 @@ class CalculatedBusImpl extends AbstractBus implements CalculatedBus { * @param terminals The terminals belong to this bus * @return The first terminal of the {@code terminals} list, or a terminal which belongs to an equivalent "electrical" bus. */ - private static NodeTerminal findTerminal(NodeBreakerVoltageLevel voltageLevel, TIntArrayList nodes, List terminals) { + private static NodeTerminal findTerminal(VoltageLevelExt voltageLevel, TIntArrayList nodes, List terminals) { if (!terminals.isEmpty()) { return terminals.get(0); } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ConnectDisconnectUtil.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ConnectDisconnectUtil.java index e178a176e2e..861c4883022 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ConnectDisconnectUtil.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ConnectDisconnectUtil.java @@ -19,6 +19,7 @@ import java.util.function.Predicate; import static com.powsybl.iidm.network.TopologyKind.BUS_BREAKER; +import static com.powsybl.iidm.network.TopologyKind.NODE_BREAKER; /** * @author Nicolas Rol {@literal } @@ -63,8 +64,9 @@ static boolean connectAllTerminals(Identifiable identifiable, List identifiable, List getVoltageLevels() { - return Iterables.concat(index.getAll(BusBreakerVoltageLevel.class), - index.getAll(NodeBreakerVoltageLevel.class)); + return Collections.unmodifiableCollection(index.getAll(VoltageLevelImpl.class)); } @Override public Stream getVoltageLevelStream() { - return Stream.concat(index.getAll(BusBreakerVoltageLevel.class).stream(), - index.getAll(NodeBreakerVoltageLevel.class).stream()); + return index.getAll(VoltageLevelImpl.class).stream().map(Function.identity()); } @Override public int getVoltageLevelCount() { - return index.getAll(BusBreakerVoltageLevel.class).size() - + index.getAll(NodeBreakerVoltageLevel.class).size(); + return index.getAll(VoltageLevelImpl.class).size(); } @Override diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeBreakerVoltageLevel.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeBreakerTopologyModel.java similarity index 91% rename from iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeBreakerVoltageLevel.java rename to iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeBreakerTopologyModel.java index f8483387a6d..83ac29d03f4 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeBreakerVoltageLevel.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeBreakerTopologyModel.java @@ -14,8 +14,8 @@ import com.powsybl.commons.PowsyblException; import com.powsybl.commons.util.Colors; import com.powsybl.iidm.network.*; +import com.powsybl.iidm.network.VoltageLevel.NodeBreakerView.InternalConnectionAdder; import com.powsybl.iidm.network.VoltageLevel.NodeBreakerView.SwitchAdder; -import com.powsybl.commons.ref.Ref; import com.powsybl.iidm.network.util.Identifiables; import com.powsybl.iidm.network.util.ShortIdDictionary; import com.powsybl.iidm.network.util.SwitchPredicates; @@ -50,9 +50,9 @@ /** * @author Geoffroy Jamgotchian {@literal } */ -class NodeBreakerVoltageLevel extends AbstractVoltageLevel { +class NodeBreakerTopologyModel extends AbstractTopologyModel { - private static final Logger LOGGER = LoggerFactory.getLogger(NodeBreakerVoltageLevel.class); + private static final Logger LOGGER = LoggerFactory.getLogger(NodeBreakerTopologyModel.class); private static final String WRONG_TERMINAL_TYPE_EXCEPTION_MESSAGE = "Given TerminalExt not supported: "; @@ -85,7 +85,7 @@ public VariantImpl copy() { private final VariantArray variants; - private final class SwitchAdderImpl extends AbstractIdentifiableAdder implements NodeBreakerView.SwitchAdder { + private final class SwitchAdderImpl extends AbstractIdentifiableAdder implements SwitchAdder { private Integer node1; @@ -107,7 +107,7 @@ private SwitchAdderImpl(SwitchKind kind) { @Override protected NetworkImpl getNetwork() { - return NodeBreakerVoltageLevel.this.getNetwork(); + return NodeBreakerTopologyModel.this.getNetwork(); } @Override @@ -116,19 +116,19 @@ protected String getTypeDescription() { } @Override - public NodeBreakerView.SwitchAdder setNode1(int node1) { + public SwitchAdder setNode1(int node1) { this.node1 = node1; return this; } @Override - public NodeBreakerView.SwitchAdder setNode2(int node2) { + public SwitchAdder setNode2(int node2) { this.node2 = node2; return this; } @Override - public NodeBreakerView.SwitchAdder setKind(SwitchKind kind) { + public SwitchAdder setKind(SwitchKind kind) { if (kind == null) { throw new NullPointerException("kind is null"); } @@ -142,13 +142,13 @@ public SwitchAdder setKind(String kind) { } @Override - public NodeBreakerView.SwitchAdder setOpen(boolean open) { + public SwitchAdder setOpen(boolean open) { this.open = open; return this; } @Override - public NodeBreakerView.SwitchAdder setRetained(boolean retained) { + public SwitchAdder setRetained(boolean retained) { this.retained = retained; return this; } @@ -168,7 +168,7 @@ public Switch add() { if (kind == null) { throw new ValidationException(this, "kind is not set"); } - SwitchImpl aSwitch = new SwitchImpl(NodeBreakerVoltageLevel.this, id, getName(), isFictitious(), kind, open, retained); + SwitchImpl aSwitch = new SwitchImpl(voltageLevel, id, getName(), isFictitious(), kind, open, retained); graph.addVertexIfNotPresent(node1); graph.addVertexIfNotPresent(node2); graph.addEdge(node1, node2, aSwitch); @@ -177,7 +177,7 @@ public Switch add() { } - private final class InternalConnectionAdderImpl implements NodeBreakerView.InternalConnectionAdder { + private final class InternalConnectionAdderImpl implements InternalConnectionAdder { private Integer node1; @@ -187,13 +187,13 @@ private InternalConnectionAdderImpl() { } @Override - public NodeBreakerView.InternalConnectionAdder setNode1(int node1) { + public InternalConnectionAdder setNode1(int node1) { this.node1 = node1; return this; } @Override - public NodeBreakerView.InternalConnectionAdder setNode2(int node2) { + public InternalConnectionAdder setNode2(int node2) { this.node2 = node2; return this; } @@ -201,10 +201,10 @@ public NodeBreakerView.InternalConnectionAdder setNode2(int node2) { @Override public void add() { if (node1 == null) { - throw new ValidationException(NodeBreakerVoltageLevel.this, "first connection node is not set"); + throw new ValidationException(voltageLevel, "first connection node is not set"); } if (node2 == null) { - throw new ValidationException(NodeBreakerVoltageLevel.this, "second connection node is not set"); + throw new ValidationException(voltageLevel, "second connection node is not set"); } graph.addVertexIfNotPresent(node1); graph.addVertexIfNotPresent(node2); @@ -274,7 +274,7 @@ private void traverse(int n, boolean[] encountered, Predicate termin }, encountered); // check that the component is a bus - String busId = Identifiables.getUniqueId(NAMING_STRATEGY.getId(NodeBreakerVoltageLevel.this, nodes), getNetwork().getIndex()::contains); + String busId = Identifiables.getUniqueId(NAMING_STRATEGY.getId(voltageLevel, nodes), getNetwork().getIndex()::contains); CopyOnWriteArrayList terminals = new CopyOnWriteArrayList<>(); for (int i = 0; i < nodes.size(); i++) { int n2 = nodes.getQuick(i); @@ -291,9 +291,9 @@ private void traverse(int n, boolean[] encountered, Predicate termin private void addBus(TIntArrayList nodes, Map id2bus, CalculatedBus[] node2bus, String busId, CopyOnWriteArrayList terminals) { - String busName = NAMING_STRATEGY.getName(NodeBreakerVoltageLevel.this, nodes); + String busName = NAMING_STRATEGY.getName(voltageLevel, nodes); Function getBusFromTerminal = getBusChecker() == CALCULATED_BUS_CHECKER ? t -> t.getBusView().getBus() : t -> t.getBusBreakerView().getBus(); - CalculatedBusImpl bus = new CalculatedBusImpl(busId, busName, NodeBreakerVoltageLevel.this.fictitious, NodeBreakerVoltageLevel.this, nodes, terminals, getBusFromTerminal); + CalculatedBusImpl bus = new CalculatedBusImpl(busId, busName, voltageLevel.isFictitious(), voltageLevel, nodes, terminals, getBusFromTerminal); id2bus.put(busId, bus); for (int i = 0; i < nodes.size(); i++) { node2bus[nodes.getQuick(i)] = bus; @@ -304,7 +304,7 @@ protected void updateCache(final Predicate terminate) { if (busCache != null) { return; } - LOGGER.trace("Update bus topology of voltage level {}", NodeBreakerVoltageLevel.this.id); + LOGGER.trace("Update bus topology of voltage level {}", voltageLevel.getId()); Map id2bus = new LinkedHashMap<>(); CalculatedBus[] node2bus = new CalculatedBus[graph.getVertexCapacity()]; boolean[] encountered = new boolean[graph.getVertexCapacity()]; @@ -497,28 +497,27 @@ public boolean isValid(UndirectedGraph graph, private interface BusNamingStrategy { - String getId(NodeBreakerVoltageLevel voltageLevel, TIntArrayList nodes); + String getId(VoltageLevel voltageLevel, TIntArrayList nodes); - String getName(NodeBreakerVoltageLevel voltageLevel, TIntArrayList nodes); + String getName(VoltageLevel voltageLevel, TIntArrayList nodes); } private static final class LowestNodeNumberBusNamingStrategy implements BusNamingStrategy { @Override - public String getId(NodeBreakerVoltageLevel voltageLevel, TIntArrayList nodes) { + public String getId(VoltageLevel voltageLevel, TIntArrayList nodes) { return voltageLevel.getId() + "_" + nodes.min(); } @Override - public String getName(NodeBreakerVoltageLevel voltageLevel, TIntArrayList nodes) { - return voltageLevel.name != null ? voltageLevel.name + "_" + nodes.min() : null; + public String getName(VoltageLevel voltageLevel, TIntArrayList nodes) { + return voltageLevel.getOptionalName().map(name -> name + "_" + nodes.min()).orElse(null); } } - NodeBreakerVoltageLevel(String id, String name, boolean fictitious, SubstationImpl substation, Ref ref, - Ref subnetworkRef, double nominalV, double lowVoltageLimit, double highVoltageLimit) { - super(id, name, fictitious, substation, ref, subnetworkRef, nominalV, lowVoltageLimit, highVoltageLimit); - variants = new VariantArray<>(ref, VariantImpl::new); + NodeBreakerTopologyModel(VoltageLevelExt voltageLevel) { + super(voltageLevel); + variants = new VariantArray<>(voltageLevel.getNetworkRef(), VariantImpl::new); graph.addListener(new DefaultUndirectedGraphListener<>() { private static final String INTERNAL_CONNECTION = "internalConnection"; @@ -531,7 +530,7 @@ public void edgeAdded(int e, SwitchImpl aSwitch) { switches.put(aSwitch.getId(), e); network.getListeners().notifyCreation(aSwitch); } else { - network.getListeners().notifyElementAdded(NodeBreakerVoltageLevel.this, INTERNAL_CONNECTION, null); + network.getListeners().notifyElementAdded(voltageLevel, INTERNAL_CONNECTION, null); } invalidateCache(); } @@ -553,7 +552,7 @@ public void edgeRemoved(int e, SwitchImpl aSwitch) { switches.remove(switchId); network.getListeners().notifyAfterRemoval(switchId); } else { - network.getListeners().notifyElementRemoved(NodeBreakerVoltageLevel.this, INTERNAL_CONNECTION, null); + network.getListeners().notifyElementRemoved(voltageLevel, INTERNAL_CONNECTION, null); } } @@ -570,7 +569,7 @@ public void allEdgesRemoved(Collection aSwitches) { if (ss != null) { network.getIndex().remove(ss); } else { - network.getListeners().notifyElementRemoved(NodeBreakerVoltageLevel.this, INTERNAL_CONNECTION, null); + network.getListeners().notifyElementRemoved(voltageLevel, INTERNAL_CONNECTION, null); } }); switches.clear(); @@ -627,7 +626,7 @@ CalculatedBusTopology getCalculatedBusTopology() { return variants.get().calculatedBusTopology; } - private final NodeBreakerViewExt nodeBreakerView = new NodeBreakerViewExt() { + private final VoltageLevelExt.NodeBreakerViewExt nodeBreakerView = new VoltageLevelExt.NodeBreakerViewExt() { private final TIntObjectMap fictitiousP0ByNode = TCollections.synchronizedMap(new TIntObjectHashMap<>()); private final TIntObjectMap fictitiousQ0ByNode = TCollections.synchronizedMap(new TIntObjectHashMap<>()); @@ -642,9 +641,9 @@ public double getFictitiousP0(int node) { } @Override - public NodeBreakerView setFictitiousP0(int node, double p0) { + public VoltageLevel.NodeBreakerView setFictitiousP0(int node, double p0) { if (Double.isNaN(p0)) { - throw new ValidationException(NodeBreakerVoltageLevel.this, "undefined value cannot be set as fictitious p0"); + throw new ValidationException(voltageLevel, "undefined value cannot be set as fictitious p0"); } TDoubleArrayList p0ByVariant = fictitiousP0ByNode.get(node); if (p0ByVariant == null) { @@ -660,7 +659,7 @@ public NodeBreakerView setFictitiousP0(int node, double p0) { int variantIndex = getNetwork().getVariantIndex(); double oldValue = p0ByVariant.set(getNetwork().getVariantIndex(), p0); String variantId = getNetwork().getVariantManager().getVariantId(variantIndex); - getNetwork().getListeners().notifyUpdate(NodeBreakerVoltageLevel.this, "fictitiousP0", variantId, oldValue, p0); + getNetwork().getListeners().notifyUpdate(voltageLevel, "fictitiousP0", variantId, oldValue, p0); TIntSet toRemove = clearFictitiousInjections(fictitiousP0ByNode); synchronized (fictitiousP0ByNode) { toRemove.forEach(n -> { @@ -681,9 +680,9 @@ public double getFictitiousQ0(int node) { } @Override - public NodeBreakerView setFictitiousQ0(int node, double q0) { + public VoltageLevel.NodeBreakerView setFictitiousQ0(int node, double q0) { if (Double.isNaN(q0)) { - throw new ValidationException(NodeBreakerVoltageLevel.this, "undefined value cannot be set as fictitious q0"); + throw new ValidationException(voltageLevel, "undefined value cannot be set as fictitious q0"); } TDoubleArrayList q0ByVariant = fictitiousQ0ByNode.get(node); if (q0ByVariant == null) { @@ -699,7 +698,7 @@ public NodeBreakerView setFictitiousQ0(int node, double q0) { int variantIndex = getNetwork().getVariantIndex(); double oldValue = q0ByVariant.set(getNetwork().getVariantIndex(), q0); String variantId = getNetwork().getVariantManager().getVariantId(variantIndex); - getNetwork().getListeners().notifyUpdate(NodeBreakerVoltageLevel.this, "fictitiousQ0", variantId, oldValue, q0); + getNetwork().getListeners().notifyUpdate(voltageLevel, "fictitiousQ0", variantId, oldValue, q0); TIntSet toRemove = clearFictitiousInjections(fictitiousQ0ByNode); synchronized (fictitiousQ0ByNode) { toRemove.forEach(n -> { @@ -877,7 +876,7 @@ public void removeSwitch(String switchId) { Integer e = switches.get(switchId); if (e == null) { throw new PowsyblException("Switch '" + switchId - + "' not found in voltage level '" + id + "'"); + + "' not found in voltage level '" + voltageLevel.getId() + "'"); } graph.removeEdge(e); graph.removeIsolatedVertices(); @@ -885,7 +884,7 @@ public void removeSwitch(String switchId) { @Override public BusbarSectionAdder newBusbarSection() { - return new BusbarSectionAdderImpl(NodeBreakerVoltageLevel.this); + return new BusbarSectionAdderImpl(voltageLevel); } @Override @@ -906,7 +905,7 @@ public int getBusbarSectionCount() { @Override public BusbarSection getBusbarSection(String id) { BusbarSection bbs = getNetwork().getIndex().get(id, BusbarSection.class); - if (bbs != null && bbs.getTerminal().getVoltageLevel() != NodeBreakerVoltageLevel.this) { + if (bbs != null && bbs.getTerminal().getVoltageLevel() != voltageLevel) { return null; } return bbs; @@ -942,11 +941,11 @@ private static TIntSet clearFictitiousInjections(TIntObjectMap } @Override - public NodeBreakerViewExt getNodeBreakerView() { + public VoltageLevelExt.NodeBreakerViewExt getNodeBreakerView() { return nodeBreakerView; } - private final BusViewExt busView = new BusViewExt() { + private final VoltageLevelExt.BusViewExt busView = new VoltageLevelExt.BusViewExt() { @Override public Iterable getBuses() { @@ -972,11 +971,11 @@ public Bus getMergedBus(String busBarId) { }; @Override - public BusViewExt getBusView() { + public VoltageLevelExt.BusViewExt getBusView() { return busView; } - private final BusBreakerViewExt busBreakerView = new BusBreakerViewExt() { + private final VoltageLevelExt.BusBreakerViewExt busBreakerView = new VoltageLevelExt.BusBreakerViewExt() { @Override public Iterable getBuses() { @@ -1074,7 +1073,7 @@ public Switch getSwitch(String switchId) { } @Override - public BusBreakerView.SwitchAdder newSwitch() { + public SwitchAdder newSwitch() { throw createNotSupportedNodeBreakerTopologyException(); } @@ -1085,7 +1084,7 @@ public void traverse(Bus bus, TopologyTraverser traverser) { }; @Override - public BusBreakerViewExt getBusBreakerView() { + public VoltageLevelExt.BusBreakerViewExt getBusBreakerView() { return busBreakerView; } @@ -1107,7 +1106,7 @@ public TopologyKind getTopologyKind() { private void checkTerminal(TerminalExt terminal) { if (!(terminal instanceof NodeTerminal)) { throw new ValidationException(terminal.getConnectable(), - "voltage level " + NodeBreakerVoltageLevel.this.id + " has a node/breaker topology" + "voltage level " + voltageLevel.getId() + " has a node/breaker topology" + ", a node connection should be specified instead of a bus connection"); } int node = ((NodeTerminal) terminal).getNode(); @@ -1116,7 +1115,7 @@ private void checkTerminal(TerminalExt terminal) { throw new ValidationException(terminal.getConnectable(), "an equipment (" + graph.getVertexObject(node).getConnectable().getId() + ") is already connected to node " + node + " of voltage level " - + NodeBreakerVoltageLevel.this.id); + + voltageLevel.getId()); } } @@ -1129,12 +1128,12 @@ public void attach(TerminalExt terminal, boolean test) { int node = ((NodeTerminal) terminal).getNode(); // create the link terminal <-> voltage level - terminal.setVoltageLevel(NodeBreakerVoltageLevel.this); + terminal.setVoltageLevel(voltageLevel); // create the link terminal <-> graph vertex graph.setVertexObject(node, (NodeTerminal) terminal); - getNetwork().getVariantManager().forEachVariant(this::invalidateCache); + getNetwork().getVariantManager().forEachVariant(NodeBreakerTopologyModel.this::invalidateCache); } @Override @@ -1147,7 +1146,7 @@ public void detach(TerminalExt terminal) { graph.setVertexObject(node, null); - getNetwork().getVariantManager().forEachVariant(this::invalidateCache); + getNetwork().getVariantManager().forEachVariant(NodeBreakerTopologyModel.this::invalidateCache); // remove the link terminal -> voltage level terminal.setVoltageLevel(null); @@ -1181,8 +1180,7 @@ private void checkTopologyKind(Terminal terminal) { * @param terminal Terminal to connect * @return true if the terminal has been connected, false if it hasn't or if it was already connected */ - @Override - public boolean connect(TerminalExt terminal) { + boolean connect(TerminalExt terminal) { // Only keep the closed non-fictional breakers in the nominal case return connect(terminal, SwitchPredicates.IS_NONFICTIONAL_BREAKER); } @@ -1224,7 +1222,7 @@ boolean getConnectingSwitches(Terminal terminal, Predicate i // find all paths starting from the current terminal to a busbar section that does not contain an open switch // that is not of the type of switch the user wants to operate // Paths are already sorted by the number of open switches and by the size of the paths - List paths = graph.findAllPaths(node, NodeBreakerVoltageLevel::isBusbarSection, sw -> checkNonClosableSwitch(sw, isSwitchOperable), + List paths = graph.findAllPaths(node, NodeBreakerTopologyModel::isBusbarSection, sw -> checkNonClosableSwitch(sw, isSwitchOperable), Comparator.comparing((TIntArrayList o) -> o.grep(idx -> SwitchPredicates.IS_OPEN.test(graph.getEdgeObject(idx))).size()) .thenComparing(TIntArrayList::size)); if (!paths.isEmpty()) { @@ -1245,8 +1243,7 @@ boolean getConnectingSwitches(Terminal terminal, Predicate i return false; } - @Override - public boolean disconnect(TerminalExt terminal) { + boolean disconnect(TerminalExt terminal) { // Only keep the closed non-fictional breakers in the nominal case return disconnect(terminal, SwitchPredicates.IS_CLOSED_BREAKER); } @@ -1280,7 +1277,7 @@ boolean getDisconnectingSwitches(Terminal terminal, Predicate paths = graph.findAllPaths(node, NodeBreakerVoltageLevel::isBusbarSection, SwitchPredicates.IS_OPEN); + List paths = graph.findAllPaths(node, NodeBreakerTopologyModel::isBusbarSection, SwitchPredicates.IS_OPEN); if (paths.isEmpty()) { return false; } @@ -1385,25 +1382,21 @@ private static TraverseResult getTraverseResult(Set visitedTerminals, @Override public void extendVariantArraySize(int initVariantArraySize, int number, int sourceIndex) { - super.extendVariantArraySize(initVariantArraySize, number, sourceIndex); variants.push(number, VariantImpl::new); } @Override public void reduceVariantArraySize(int number) { - super.reduceVariantArraySize(number); variants.pop(number); } @Override public void deleteVariantArrayElement(int index) { - super.deleteVariantArrayElement(index); variants.delete(index); } @Override public void allocateVariantArrayElement(int[] indexes, final int sourceIndex) { - super.allocateVariantArrayElement(indexes, sourceIndex); variants.allocate(indexes, VariantImpl::new); } @@ -1424,7 +1417,7 @@ public void printTopology() { @Override public void printTopology(PrintStream out, ShortIdDictionary dict) { out.println("-------------------------------------------------------------"); - out.println("Topology of " + NodeBreakerVoltageLevel.this.id); + out.println("Topology of " + voltageLevel.getId()); graph.print(out, terminal -> terminal != null ? terminal.getConnectable().toString() : null, null); } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeTerminal.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeTerminal.java index 31fe6f1d27b..e1acd93912c 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeTerminal.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NodeTerminal.java @@ -57,6 +57,10 @@ public void moveConnectable(int node, String voltageLevelId) { } }; + private NodeBreakerTopologyModel getTopologyModel() { + return (NodeBreakerTopologyModel) voltageLevel.getTopologyModel(); + } + private final BusBreakerViewExt busBreakerView = new BusBreakerViewExt() { @Override @@ -64,7 +68,7 @@ public BusExt getBus() { if (removed) { throw new PowsyblException(CANNOT_ACCESS_BUS_REMOVED_EQUIPMENT + connectable.id); } - return ((NodeBreakerVoltageLevel) voltageLevel).getCalculatedBusBreakerTopology().getBus(node); + return getTopologyModel().getCalculatedBusBreakerTopology().getBus(node); } @Override @@ -72,12 +76,12 @@ public BusExt getConnectableBus() { if (removed) { throw new PowsyblException(CANNOT_ACCESS_BUS_REMOVED_EQUIPMENT + connectable.id); } - return ((NodeBreakerVoltageLevel) voltageLevel).getCalculatedBusBreakerTopology().getConnectableBus(node); + return getTopologyModel().getCalculatedBusBreakerTopology().getConnectableBus(node); } @Override public void setConnectableBus(String busId) { - throw NodeBreakerVoltageLevel.createNotSupportedNodeBreakerTopologyException(); + throw NodeBreakerTopologyModel.createNotSupportedNodeBreakerTopologyException(); } @Override @@ -102,7 +106,7 @@ public BusExt getBus() { if (removed) { throw new PowsyblException(CANNOT_ACCESS_BUS_REMOVED_EQUIPMENT + connectable.id); } - return ((NodeBreakerVoltageLevel) voltageLevel).getCalculatedBusTopology().getBus(node); + return getTopologyModel().getCalculatedBusTopology().getBus(node); } @Override @@ -110,7 +114,7 @@ public BusExt getConnectableBus() { if (removed) { throw new PowsyblException(CANNOT_ACCESS_BUS_REMOVED_EQUIPMENT + connectable.id); } - return ((NodeBreakerVoltageLevel) voltageLevel).getCalculatedBusTopology().getConnectableBus(node); + return getTopologyModel().getCalculatedBusTopology().getConnectableBus(node); } }; @@ -231,7 +235,7 @@ public boolean isConnected() { if (removed) { throw new PowsyblException("Cannot access connectivity status of removed equipment " + connectable.id); } - return ((NodeBreakerVoltageLevel) voltageLevel).isConnected(this); + return getTopologyModel().isConnected(this); } @Override @@ -239,7 +243,7 @@ public boolean traverse(TopologyTraverser traverser, Set visitedTermin if (removed) { throw new PowsyblException(String.format("Associated equipment %s is removed", connectable.id)); } - return ((NodeBreakerVoltageLevel) voltageLevel).traverse(this, traverser, visitedTerminals, traversalType); + return getTopologyModel().traverse(this, traverser, visitedTerminals, traversalType); } @Override @@ -252,7 +256,7 @@ public void traverse(TopologyTraverser traverser, TraversalType traversalType) { if (removed) { throw new PowsyblException(String.format("Associated equipment %s is removed", connectable.id)); } - ((NodeBreakerVoltageLevel) voltageLevel).traverse(this, traverser, traversalType); + getTopologyModel().traverse(this, traverser, traversalType); } @Override diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ShuntCompensatorAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ShuntCompensatorAdderImpl.java index 5802e57907d..a83a21c13c4 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ShuntCompensatorAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ShuntCompensatorAdderImpl.java @@ -225,7 +225,7 @@ id, getName(), isFictitious(), modelBuilder.build(), sectionCount, voltageRegulatorOn, targetV, targetDeadband); shunt.addTerminal(terminal); - voltageLevel.attach(terminal, false); + voltageLevel.getTopologyModel().attach(terminal, false); network.getIndex().checkAndAdd(shunt); network.getListeners().notifyCreation(shunt); return shunt; diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/StaticVarCompensatorAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/StaticVarCompensatorAdderImpl.java index 1952e3e1c8b..af6a95bbb75 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/StaticVarCompensatorAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/StaticVarCompensatorAdderImpl.java @@ -91,7 +91,7 @@ public StaticVarCompensatorImpl add() { regulationMode, regulatingTerminal != null ? regulatingTerminal : terminal, getNetworkRef()); svc.addTerminal(terminal); - voltageLevel.attach(terminal, false); + voltageLevel.getTopologyModel().attach(terminal, false); network.getIndex().checkAndAdd(svc); network.getListeners().notifyCreation(svc); return svc; diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/SwitchImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/SwitchImpl.java index f66a27304dc..144f9fde0c3 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/SwitchImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/SwitchImpl.java @@ -70,7 +70,7 @@ public void setOpen(boolean open) { boolean oldValue = this.open.get(index); if (oldValue != open) { this.open.set(index, open); - voltageLevel.invalidateCache(isRetained()); + voltageLevel.getTopologyModel().invalidateCache(isRetained()); String variantId = network.getVariantManager().getVariantId(index); network.getListeners().notifyUpdate(this, "open", variantId, oldValue, open); } @@ -91,7 +91,7 @@ public void setRetained(boolean retained) { boolean oldValue = this.retained.get(index); if (oldValue != retained) { this.retained.set(index, retained); - voltageLevel.invalidateCache(); + voltageLevel.getTopologyModel().invalidateCache(); String variantId = network.getVariantManager().getVariantId(index); network.getListeners().notifyUpdate(this, "retained", variantId, oldValue, retained); } @@ -102,7 +102,7 @@ public void setFictitious(boolean fictitious) { boolean oldValue = this.fictitious; if (oldValue != fictitious) { this.fictitious = fictitious; - voltageLevel.invalidateCache(); + voltageLevel.getTopologyModel().invalidateCache(); NetworkImpl network = getNetwork(); network.getListeners().notifyUpdate(this, "fictitious", oldValue, fictitious); } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ThreeWindingsTransformerAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ThreeWindingsTransformerAdderImpl.java index c426ceaa21a..aa556962e45 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ThreeWindingsTransformerAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/ThreeWindingsTransformerAdderImpl.java @@ -291,14 +291,14 @@ public ThreeWindingsTransformerImpl add() { // check that the 3 windings transformer is attachable on the 3 sides (only // verify) - voltageLevel1.attach(terminal1, true); - voltageLevel2.attach(terminal2, true); - voltageLevel3.attach(terminal3, true); + voltageLevel1.getTopologyModel().attach(terminal1, true); + voltageLevel2.getTopologyModel().attach(terminal2, true); + voltageLevel3.getTopologyModel().attach(terminal3, true); // do attach - voltageLevel1.attach(terminal1, false); - voltageLevel2.attach(terminal2, false); - voltageLevel3.attach(terminal3, false); + voltageLevel1.getTopologyModel().attach(terminal1, false); + voltageLevel2.getTopologyModel().attach(terminal2, false); + voltageLevel3.getTopologyModel().attach(terminal3, false); getNetwork().getIndex().checkAndAdd(transformer); getNetwork().getListeners().notifyCreation(transformer); diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/TopologyModel.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/TopologyModel.java new file mode 100644 index 00000000000..6914887600e --- /dev/null +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/TopologyModel.java @@ -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 java.util.function.Predicate; + +/** + * @author Geoffroy Jamgotchian {@literal } + */ +interface TopologyModel { + + void invalidateCache(boolean exceptBusBreakerView); + + void invalidateCache(); + + void attach(TerminalExt terminal, boolean test); + + void detach(TerminalExt terminal); + + boolean connect(TerminalExt terminal, Predicate isTypeSwitchToOperate); + + boolean disconnect(TerminalExt terminal, Predicate isSwitchOpenable); +} diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/TwoWindingsTransformerAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/TwoWindingsTransformerAdderImpl.java index e9835ac7c06..bf553f4889c 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/TwoWindingsTransformerAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/TwoWindingsTransformerAdderImpl.java @@ -124,11 +124,11 @@ public TwoWindingsTransformer add() { transformer.addTerminal(terminal2); // check that the two windings transformer is attachable on both side - voltageLevel1.attach(terminal1, true); - voltageLevel2.attach(terminal2, true); + voltageLevel1.getTopologyModel().attach(terminal1, true); + voltageLevel2.getTopologyModel().attach(terminal2, true); - voltageLevel1.attach(terminal1, false); - voltageLevel2.attach(terminal2, false); + voltageLevel1.getTopologyModel().attach(terminal1, false); + voltageLevel2.getTopologyModel().attach(terminal2, false); getNetwork().getIndex().checkAndAdd(transformer); getNetwork().getListeners().notifyCreation(transformer); return transformer; diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VoltageLevelAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VoltageLevelAdderImpl.java index 3d8130a7b63..bff9f8ddab7 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VoltageLevelAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VoltageLevelAdderImpl.java @@ -94,12 +94,7 @@ public VoltageLevel add() { ValidationUtil.checkVoltageLimits(this, lowVoltageLimit, highVoltageLimit); ValidationUtil.checkTopologyKind(this, topologyKind); - VoltageLevelExt voltageLevel = switch (topologyKind) { - case NODE_BREAKER -> - new NodeBreakerVoltageLevel(id, getName(), isFictitious(), substation, networkRef, subnetworkRef, nominalV, lowVoltageLimit, highVoltageLimit); - case BUS_BREAKER -> - new BusBreakerVoltageLevel(id, getName(), isFictitious(), substation, networkRef, subnetworkRef, nominalV, lowVoltageLimit, highVoltageLimit); - }; + VoltageLevelExt voltageLevel = new VoltageLevelImpl(id, getName(), isFictitious(), substation, networkRef, subnetworkRef, nominalV, lowVoltageLimit, highVoltageLimit, topologyKind); getNetwork().getIndex().checkAndAdd(voltageLevel); Optional.ofNullable(substation).ifPresent(s -> s.addVoltageLevel(voltageLevel)); getNetwork().getListeners().notifyCreation(voltageLevel); diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VoltageLevelExt.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VoltageLevelExt.java index 7a465e87fb3..7c9d1636688 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VoltageLevelExt.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VoltageLevelExt.java @@ -7,16 +7,15 @@ */ package com.powsybl.iidm.network.impl; +import com.powsybl.iidm.network.Validable; import com.powsybl.iidm.network.VoltageLevel; import com.powsybl.commons.ref.Ref; -import java.util.function.Predicate; - /** * * @author Geoffroy Jamgotchian {@literal } */ -interface VoltageLevelExt extends VoltageLevel, MultiVariantObject { +interface VoltageLevelExt extends VoltageLevel, MultiVariantObject, Validable { interface NodeBreakerViewExt extends NodeBreakerView { @@ -45,29 +44,7 @@ interface BusViewExt extends BusView { @Override NetworkExt getParentNetwork(); - /** - * Attach an equipment to the topology. - */ - void attach(TerminalExt terminal, boolean test); - - /** - * Detach an equipment from the topology. - */ - void detach(TerminalExt terminal); - - boolean connect(TerminalExt terminal); - - boolean connect(TerminalExt terminal, Predicate isTypeSwitchToOperate); - - boolean disconnect(TerminalExt terminal); - - boolean disconnect(TerminalExt terminal, Predicate isSwitchOpenable); - - default void invalidateCache() { - invalidateCache(false); - } - - void invalidateCache(boolean exceptBusBreakerView); + TopologyModel getTopologyModel(); String getSubnetworkId(); diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractVoltageLevel.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VoltageLevelImpl.java similarity index 81% rename from iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractVoltageLevel.java rename to iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VoltageLevelImpl.java index d438ab56d18..7fc379bc153 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractVoltageLevel.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VoltageLevelImpl.java @@ -7,14 +7,17 @@ */ package com.powsybl.iidm.network.impl; -import com.google.common.collect.FluentIterable; import com.google.common.collect.Lists; import com.google.common.primitives.Ints; import com.powsybl.commons.PowsyblException; -import com.powsybl.commons.config.PlatformConfig; import com.powsybl.iidm.network.*; import com.powsybl.commons.ref.Ref; +import com.powsybl.iidm.network.util.ShortIdDictionary; +import java.io.IOException; +import java.io.PrintStream; +import java.io.Writer; +import java.nio.file.Path; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -23,14 +26,10 @@ * * @author Geoffroy Jamgotchian {@literal } */ -abstract class AbstractVoltageLevel extends AbstractIdentifiable implements VoltageLevelExt { - - private static final int DEFAULT_NODE_INDEX_LIMIT = 1000; - - public static final int NODE_INDEX_LIMIT = loadNodeIndexLimit(PlatformConfig.defaultConfig()); +class VoltageLevelImpl extends AbstractIdentifiable implements VoltageLevelExt { private final Ref networkRef; - private Ref subnetworkRef; + private final Ref subnetworkRef; private final SubstationImpl substation; @@ -40,13 +39,16 @@ abstract class AbstractVoltageLevel extends AbstractIdentifiable i private double highVoltageLimit; + private final AbstractTopologyModel topologyModel; + /** Areas associated to this VoltageLevel, with at most one area for each area type */ private final Set areas = new LinkedHashSet<>(); private boolean removed = false; - AbstractVoltageLevel(String id, String name, boolean fictitious, SubstationImpl substation, Ref networkRef, - Ref subnetworkRef, double nominalV, double lowVoltageLimit, double highVoltageLimit) { + VoltageLevelImpl(String id, String name, boolean fictitious, SubstationImpl substation, Ref networkRef, + Ref subnetworkRef, double nominalV, double lowVoltageLimit, double highVoltageLimit, + TopologyKind topologyKind) { super(id, name, fictitious); this.substation = substation; this.networkRef = networkRef; @@ -54,13 +56,15 @@ abstract class AbstractVoltageLevel extends AbstractIdentifiable i this.nominalV = nominalV; this.lowVoltageLimit = lowVoltageLimit; this.highVoltageLimit = highVoltageLimit; + this.topologyModel = switch (Objects.requireNonNull(topologyKind)) { + case NODE_BREAKER -> new NodeBreakerTopologyModel(this); + case BUS_BREAKER -> new BusBreakerTopologyModel(this); + }; } - protected static int loadNodeIndexLimit(PlatformConfig platformConfig) { - return platformConfig - .getOptionalModuleConfig("iidm") - .map(moduleConfig -> moduleConfig.getIntProperty("node-index-limit", DEFAULT_NODE_INDEX_LIMIT)) - .orElse(DEFAULT_NODE_INDEX_LIMIT); + @Override + public AbstractTopologyModel getTopologyModel() { + return topologyModel; } @Override @@ -157,6 +161,21 @@ public Substation getNullableSubstation() { return substation; } + @Override + public NodeBreakerViewExt getNodeBreakerView() { + return topologyModel.getNodeBreakerView(); + } + + @Override + public BusBreakerViewExt getBusBreakerView() { + return topologyModel.getBusBreakerView(); + } + + @Override + public BusViewExt getBusView() { + return topologyModel.getBusView(); + } + @Override public NetworkImpl getNetwork() { if (removed) { @@ -247,39 +266,27 @@ public T getConnectable(String id, Class aClass) { @Override public Iterable getConnectables(Class clazz) { - Iterable terminals = getTerminals(); - return FluentIterable.from(terminals) - .transform(Terminal::getConnectable) - .filter(clazz) - .toSet(); + return topologyModel.getConnectables(clazz); } @Override public Stream getConnectableStream(Class clazz) { - return getTerminalStream() - .map(Terminal::getConnectable) - .filter(clazz::isInstance) - .map(clazz::cast) - .distinct(); + return topologyModel.getConnectableStream(clazz); } @Override public int getConnectableCount(Class clazz) { - return Ints.checkedCast(getConnectableStream(clazz).count()); + return topologyModel.getConnectableCount(clazz); } @Override public Iterable getConnectables() { - return FluentIterable.from(getTerminals()) - .transform(Terminal::getConnectable) - .toSet(); + return topologyModel.getConnectables(); } @Override public Stream getConnectableStream() { - return getTerminalStream() - .map(Terminal::getConnectable) - .distinct(); + return topologyModel.getConnectableStream(); } @Override @@ -342,6 +349,16 @@ public Stream getLoadStream() { return getConnectableStream(Load.class); } + @Override + public Iterable getSwitches() { + return topologyModel.getSwitches(); + } + + @Override + public int getSwitchCount() { + return topologyModel.getSwitchCount(); + } + @Override public int getLoadCount() { return getConnectableCount(Load.class); @@ -517,41 +534,39 @@ protected String getTypeDescription() { return "Voltage level"; } - protected abstract Iterable getTerminals(); + @Override + public void visitEquipments(TopologyVisitor visitor) { + AbstractBus.visitEquipments(topologyModel.getTerminals(), visitor); + } - protected abstract Stream getTerminalStream(); + @Override + public TopologyKind getTopologyKind() { + return topologyModel.getTopologyKind(); + } @Override - public void visitEquipments(TopologyVisitor visitor) { - AbstractBus.visitEquipments(getTerminals(), visitor); - } - - protected static void addNextTerminals(TerminalExt otherTerminal, List nextTerminals) { - Objects.requireNonNull(otherTerminal); - Objects.requireNonNull(nextTerminals); - Connectable otherConnectable = otherTerminal.getConnectable(); - if (otherConnectable instanceof Branch branch) { - if (branch.getTerminal1() == otherTerminal) { - nextTerminals.add((TerminalExt) branch.getTerminal2()); - } else if (branch.getTerminal2() == otherTerminal) { - nextTerminals.add((TerminalExt) branch.getTerminal1()); - } else { - throw new IllegalStateException(); - } - } else if (otherConnectable instanceof ThreeWindingsTransformer ttc) { - if (ttc.getLeg1().getTerminal() == otherTerminal) { - nextTerminals.add((TerminalExt) ttc.getLeg2().getTerminal()); - nextTerminals.add((TerminalExt) ttc.getLeg3().getTerminal()); - } else if (ttc.getLeg2().getTerminal() == otherTerminal) { - nextTerminals.add((TerminalExt) ttc.getLeg1().getTerminal()); - nextTerminals.add((TerminalExt) ttc.getLeg3().getTerminal()); - } else if (ttc.getLeg3().getTerminal() == otherTerminal) { - nextTerminals.add((TerminalExt) ttc.getLeg1().getTerminal()); - nextTerminals.add((TerminalExt) ttc.getLeg2().getTerminal()); - } else { - throw new IllegalStateException(); - } - } + public void printTopology() { + topologyModel.printTopology(); + } + + @Override + public void printTopology(PrintStream out, ShortIdDictionary dict) { + topologyModel.printTopology(out, dict); + } + + @Override + public void exportTopology(Path file) throws IOException { + topologyModel.exportTopology(file); + } + + @Override + public void exportTopology(Writer writer, Random random) { + topologyModel.exportTopology(writer, random); + } + + @Override + public void exportTopology(Writer writer) { + topologyModel.exportTopology(writer); } @Override @@ -568,7 +583,7 @@ public void remove() { } // Remove the topology - removeTopology(); + topologyModel.removeTopology(); // Remove this voltage level from the areas getAreas().forEach(area -> area.removeVoltageLevel(this)); @@ -580,5 +595,27 @@ public void remove() { removed = true; } - protected abstract void removeTopology(); + @Override + public void extendVariantArraySize(int initVariantArraySize, int number, int sourceIndex) { + super.extendVariantArraySize(initVariantArraySize, number, sourceIndex); + topologyModel.extendVariantArraySize(initVariantArraySize, number, sourceIndex); + } + + @Override + public void reduceVariantArraySize(int number) { + super.reduceVariantArraySize(number); + topologyModel.reduceVariantArraySize(number); + } + + @Override + public void deleteVariantArrayElement(int index) { + super.deleteVariantArrayElement(index); + topologyModel.deleteVariantArrayElement(index); + } + + @Override + public void allocateVariantArrayElement(int[] indexes, int sourceIndex) { + super.allocateVariantArrayElement(indexes, sourceIndex); + topologyModel.allocateVariantArrayElement(indexes, sourceIndex); + } } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VscConverterStationAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VscConverterStationAdderImpl.java index ced37052959..3c361ab1cdf 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VscConverterStationAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/VscConverterStationAdderImpl.java @@ -73,7 +73,7 @@ public VscConverterStationImpl add() { = new VscConverterStationImpl(id, name, isFictitious(), getLossFactor(), getNetworkRef(), voltageRegulatorOn, reactivePowerSetpoint, voltageSetpoint, regulatingTerminal == null ? terminal : regulatingTerminal); converterStation.addTerminal(terminal); - getVoltageLevel().attach(terminal, false); + getVoltageLevel().getTopologyModel().attach(terminal, false); network.getIndex().checkAndAdd(converterStation); network.getListeners().notifyCreation(converterStation); return converterStation; diff --git a/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/NodeBreakerConnectTest.java b/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/NodeBreakerConnectTest.java index ad1ec8a5db1..6be33d030ac 100644 --- a/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/NodeBreakerConnectTest.java +++ b/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/NodeBreakerConnectTest.java @@ -158,8 +158,8 @@ void testNodeBreakerConnectViaVoltageLevelConnectedLoad() { assertTrue(network.getSwitch("B2").isOpen()); if (l.getTerminal() instanceof TerminalExt terminal) { - NodeBreakerVoltageLevel voltageLevel = (NodeBreakerVoltageLevel) network.getVoltageLevel("VL"); - voltageLevel.connect(terminal); + NodeBreakerTopologyModel topologyModel = (NodeBreakerTopologyModel) ((VoltageLevelImpl) network.getVoltageLevel("VL")).getTopologyModel(); + topologyModel.connect(terminal); } assertTrue(network.getSwitch("B2").isOpen()); assertTrue(l.getTerminal().isConnected()); @@ -183,8 +183,8 @@ void testNodeBreakerDisconnectionDiamond() { Load l = network.getLoad("L"); assertTrue(l.getTerminal().isConnected()); if (l.getTerminal() instanceof TerminalExt terminal) { - NodeBreakerVoltageLevel voltageLevel = (NodeBreakerVoltageLevel) network.getVoltageLevel("VL"); - voltageLevel.disconnect(terminal); + NodeBreakerTopologyModel topologyModel = (NodeBreakerTopologyModel) ((VoltageLevelImpl) network.getVoltageLevel("VL")).getTopologyModel(); + topologyModel.disconnect(terminal); } assertFalse(l.getTerminal().isConnected()); } diff --git a/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/TestAbstractVoltageLevel.java b/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/TestAbstractTopologyModel.java similarity index 80% rename from iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/TestAbstractVoltageLevel.java rename to iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/TestAbstractTopologyModel.java index 224cb563ff4..fd35ac2a281 100644 --- a/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/TestAbstractVoltageLevel.java +++ b/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/TestAbstractTopologyModel.java @@ -22,12 +22,12 @@ /** * @author Lucas Leblow {@literal } */ -class TestAbstractVoltageLevel { +class TestAbstractTopologyModel { @Test void testLoadNodeIndexLimit() throws IOException { - assertEquals(1000, AbstractVoltageLevel.NODE_INDEX_LIMIT); - assertEquals(1000, AbstractVoltageLevel.loadNodeIndexLimit(PlatformConfig.defaultConfig())); + assertEquals(1000, AbstractTopologyModel.NODE_INDEX_LIMIT); + assertEquals(1000, AbstractTopologyModel.loadNodeIndexLimit(PlatformConfig.defaultConfig())); try (FileSystem fileSystem = Jimfs.newFileSystem(Configuration.unix())) { @@ -35,7 +35,7 @@ void testLoadNodeIndexLimit() throws IOException { MapModuleConfig moduleConfig = platformConfig.createModuleConfig("iidm"); moduleConfig.setStringProperty("node-index-limit", "5"); - assertEquals(5, AbstractVoltageLevel.loadNodeIndexLimit(platformConfig)); + assertEquals(5, AbstractTopologyModel.loadNodeIndexLimit(platformConfig)); } } }