diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/AbstractEquipmentTopologyVisitor.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/AbstractEquipmentTopologyVisitor.java index f8c6770c64d..071dd089249 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/AbstractEquipmentTopologyVisitor.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/AbstractEquipmentTopologyVisitor.java @@ -63,4 +63,9 @@ public void visitStaticVarCompensator(StaticVarCompensator staticVarCompensator) public void visitHvdcConverterStation(HvdcConverterStation converterStation) { visitEquipment(converterStation); } + + @Override + public void visitGround(Ground ground) { + visitEquipment(ground); + } } diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/AbstractTerminalTopologyVisitor.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/AbstractTerminalTopologyVisitor.java index 91f19da209c..16d6950a3cb 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/AbstractTerminalTopologyVisitor.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/AbstractTerminalTopologyVisitor.java @@ -76,4 +76,9 @@ public void visitStaticVarCompensator(StaticVarCompensator staticVarCompensator) public void visitHvdcConverterStation(HvdcConverterStation converterStation) { visitInjection(converterStation); } + + @Override + public void visitGround(Ground ground) { + visitInjection(ground); + } } diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/DefaultTopologyVisitor.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/DefaultTopologyVisitor.java index ae6a97243dd..adb1d10fb6d 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/DefaultTopologyVisitor.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/DefaultTopologyVisitor.java @@ -66,4 +66,9 @@ public void visitStaticVarCompensator(StaticVarCompensator staticVarCompensator) public void visitHvdcConverterStation(HvdcConverterStation converterStation) { // empty default implementation } + + @Override + public void visitGround(Ground ground) { + // empty default implementation + } } diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Ground.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Ground.java new file mode 100644 index 00000000000..adfd11e720c --- /dev/null +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Ground.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023, 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; + +/** + * @author Nicolas Rol {@literal } + */ +public interface Ground extends Injection { + + @Override + default IdentifiableType getType() { + return IdentifiableType.GROUND; + } +} diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/GroundAdder.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/GroundAdder.java new file mode 100644 index 00000000000..490affa4f19 --- /dev/null +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/GroundAdder.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023, 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; + +/** + * @author Nicolas Rol {@literal } + */ +public interface GroundAdder extends InjectionAdder { + @Override + Ground add(); +} diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/IdentifiableType.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/IdentifiableType.java index 7f5dcc6168e..7e7fc9a7307 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/IdentifiableType.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/IdentifiableType.java @@ -29,5 +29,6 @@ public enum IdentifiableType { DANGLING_LINE, STATIC_VAR_COMPENSATOR, HVDC_CONVERTER_STATION, - OVERLOAD_MANAGEMENT_SYSTEM + OVERLOAD_MANAGEMENT_SYSTEM, + GROUND } diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Network.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Network.java index 65de0bab69f..bf1d1a25055 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Network.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Network.java @@ -1161,11 +1161,32 @@ default HvdcLine getHvdcLine(HvdcConverterStation converterStation) { */ HvdcLineAdder newHvdcLine(); + /** + * Get all grounds. + */ + Iterable getGrounds(); /** - * Get an equipment by its ID or alias + * Get all grounds. + */ + Stream getGroundStream(); + + /** + * Get the ground count. + */ + int getGroundCount(); + + /** + * Get a ground. * - * @param id the id or an alias of the equipment + * @param id the id or an alias of the ground + */ + Ground getGround(String id); + + /** + * * Get an identifiable by its ID or alias + * + * @param id the id or an alias of the identifiable */ Identifiable getIdentifiable(String id); @@ -1416,6 +1437,8 @@ default Stream> getIdentifiableStream(IdentifiableType identifia return getHvdcConverterStationStream().map(Function.identity()); case STATIC_VAR_COMPENSATOR: return getStaticVarCompensatorStream().map(Function.identity()); + case GROUND: + return getGroundStream().map(Function.identity()); default: throw new PowsyblException("can get a stream of " + identifiableType + " from a network."); } diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/TopologyVisitor.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/TopologyVisitor.java index 7fd37048b92..38ad3104dfe 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/TopologyVisitor.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/TopologyVisitor.java @@ -36,4 +36,6 @@ default void visitBattery(Battery battery) { default void visitHvdcConverterStation(HvdcConverterStation converterStation) { } + + void visitGround(Ground connectable); } diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/VoltageLevel.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/VoltageLevel.java index 4e45848e7f7..eecd4f4036b 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/VoltageLevel.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/VoltageLevel.java @@ -14,7 +14,10 @@ import java.io.PrintStream; import java.io.Writer; import java.nio.file.Path; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.Random; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -827,7 +830,7 @@ default Stream getBusStreamFromBusViewBusId(String mergedBusId) { Switch getSwitch(String switchId); /** - * Get a builer to create a new switch. + * Get a builder to create a new switch. * * @throws com.powsybl.commons.PowsyblException if the topology kind is NODE_BREAKER */ @@ -1249,6 +1252,26 @@ default Stream getDanglingLineStream() { */ int getThreeWindingsTransformerCount(); + /** + * Get a builder to create a new ground. + */ + GroundAdder newGround(); + + /** + * Get grounds. + */ + Iterable getGrounds(); + + /** + * Get grounds. + */ + Stream getGroundStream(); + + /** + * Get ground count. + */ + int getGroundCount(); + /** * Remove this voltage level from the network. */ diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractBus.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractBus.java index aa420b2d9d7..71d0fc7da3e 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractBus.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractBus.java @@ -82,6 +82,7 @@ public double getP() { case TWO_WINDINGS_TRANSFORMER: case THREE_WINDINGS_TRANSFORMER: case DANGLING_LINE: + case GROUND: // skip break; case GENERATOR: @@ -113,6 +114,7 @@ public double getQ() { case TWO_WINDINGS_TRANSFORMER: case THREE_WINDINGS_TRANSFORMER: case DANGLING_LINE: + case GROUND: // skip break; case GENERATOR: @@ -338,6 +340,10 @@ static void visitEquipments(Iterable terminals, Topology visitor.visitHvdcConverterStation((HvdcConverterStation) connectable); break; + case GROUND: + visitor.visitGround((GroundImpl) connectable); + break; + default: throw new IllegalStateException(); } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractHvdcConverterStationAdder.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractHvdcConverterStationAdder.java index 4a6cff3927a..a18c1e57f01 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractHvdcConverterStationAdder.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractHvdcConverterStationAdder.java @@ -13,19 +13,12 @@ */ public abstract class AbstractHvdcConverterStationAdder> extends AbstractInjectionAdder { - private final VoltageLevelExt voltageLevel; - private float lossFactor = Float.NaN; AbstractHvdcConverterStationAdder(VoltageLevelExt voltageLevel) { this.voltageLevel = voltageLevel; } - @Override - protected NetworkImpl getNetwork() { - return voltageLevel.getNetwork(); - } - protected VoltageLevelExt getVoltageLevel() { return voltageLevel; } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractInjectionAdder.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractInjectionAdder.java index 5fdc06e079d..aa47c2bc9f7 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractInjectionAdder.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractInjectionAdder.java @@ -20,6 +20,8 @@ abstract class AbstractInjectionAdder> exten private String connectableBus; + protected VoltageLevelExt voltageLevel; + public T setNode(int node) { this.node = node; return (T) this; @@ -35,10 +37,17 @@ public T setConnectableBus(String connectableBus) { return (T) this; } - protected abstract Ref getVariantManagerHolder(); + @Override + protected NetworkImpl getNetwork() { + return voltageLevel.getNetwork(); + } + + protected Ref getNetworkRef() { + return voltageLevel.getNetworkRef(); + } protected TerminalExt checkAndGetTerminal() { - return new TerminalBuilder(getVariantManagerHolder(), this) + return new TerminalBuilder(getNetworkRef(), this) .setNode(node) .setBus(bus) .setConnectableBus(connectableBus) 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/AbstractVoltageLevel.java index 238982545a6..8dfe5e052dc 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/AbstractVoltageLevel.java @@ -424,6 +424,26 @@ public Stream getThreeWindingsTransformerStream() { return getConnectableStream(ThreeWindingsTransformer.class); } + @Override + public GroundAdder newGround() { + return new GroundAdderImpl(this); + } + + @Override + public Iterable getGrounds() { + return getConnectables(Ground.class); + } + + @Override + public Stream getGroundStream() { + return getConnectableStream(Ground.class); + } + + @Override + public int getGroundCount() { + return getConnectableCount(Ground.class); + } + @Override protected String getTypeDescription() { return "Voltage level"; 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 305b8a5d9fc..db71fa7b259 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 @@ -8,7 +8,6 @@ import com.powsybl.iidm.network.BatteryAdder; import com.powsybl.iidm.network.ValidationUtil; -import com.powsybl.iidm.network.impl.util.Ref; import java.util.Objects; @@ -19,8 +18,6 @@ */ public class BatteryAdderImpl extends AbstractInjectionAdder implements BatteryAdder { - private final VoltageLevelExt voltageLevel; - private double targetP = Double.NaN; private double targetQ = Double.NaN; @@ -33,14 +30,6 @@ public BatteryAdderImpl(VoltageLevelExt voltageLevel) { this.voltageLevel = Objects.requireNonNull(voltageLevel); } - /** - * {@inheritDoc} - */ - @Override - protected NetworkImpl getNetwork() { - return voltageLevel.getNetwork(); - } - /** * {@inheritDoc} */ @@ -85,15 +74,6 @@ public BatteryAdderImpl setMaxP(double maxP) { return this; } - @Override - protected Ref getVariantManagerHolder() { - return getNetworkRef(); - } - - private Ref getNetworkRef() { - return voltageLevel.getNetworkRef(); - } - /** * {@inheritDoc} */ 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/BusBreakerVoltageLevel.java index 25b69a36947..b025a984af2 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/BusBreakerVoltageLevel.java @@ -213,6 +213,8 @@ protected boolean isBusValid(Set busSet) { case STATIC_VAR_COMPENSATOR: feederCount++; break; + case GROUND: + break; case BUSBAR_SECTION: // must not happend in a bus/breaker topology default: diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/DanglingLineAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/DanglingLineAdderImpl.java index 47db5f62801..dd36fcd980a 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/DanglingLineAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/DanglingLineAdderImpl.java @@ -8,7 +8,6 @@ import com.powsybl.iidm.network.DanglingLineAdder; import com.powsybl.iidm.network.ValidationUtil; -import com.powsybl.iidm.network.impl.util.Ref; /** * @@ -18,8 +17,6 @@ */ class DanglingLineAdderImpl extends AbstractInjectionAdder implements DanglingLineAdder { - private final VoltageLevelExt voltageLevel; - private double p0 = Double.NaN; private double q0 = Double.NaN; @@ -40,11 +37,6 @@ class DanglingLineAdderImpl extends AbstractInjectionAdder getVariantManagerHolder() { - return getNetworkRef(); - } - - private Ref getNetworkRef() { - return voltageLevel.getNetworkRef(); - } - @Override public GenerationAdder newGeneration() { return new GenerationAdderImpl(this); diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/GeneratorAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/GeneratorAdderImpl.java index e347b98734a..5913e770cfd 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/GeneratorAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/GeneratorAdderImpl.java @@ -7,7 +7,6 @@ package com.powsybl.iidm.network.impl; import com.powsybl.iidm.network.*; -import com.powsybl.iidm.network.impl.util.Ref; /** * @@ -15,8 +14,6 @@ */ class GeneratorAdderImpl extends AbstractInjectionAdder implements GeneratorAdder { - private final VoltageLevelExt voltageLevel; - private EnergySource energySource = EnergySource.OTHER; private double minP = Double.NaN; @@ -39,11 +36,6 @@ class GeneratorAdderImpl extends AbstractInjectionAdder impl this.voltageLevel = voltageLevel; } - @Override - protected NetworkImpl getNetwork() { - return voltageLevel.getNetwork(); - } - @Override protected String getTypeDescription() { return "Generator"; @@ -103,15 +95,6 @@ public GeneratorAdder setRatedS(double ratedS) { return this; } - @Override - protected Ref getVariantManagerHolder() { - return getNetworkRef(); - } - - private Ref getNetworkRef() { - return voltageLevel.getNetworkRef(); - } - @Override public GeneratorImpl add() { NetworkImpl network = getNetwork(); diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/GroundAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/GroundAdderImpl.java new file mode 100644 index 00000000000..ad5756892f3 --- /dev/null +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/GroundAdderImpl.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023, 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.GroundAdder; + +/** + * @author Nicolas Rol {@literal } + */ +class GroundAdderImpl extends AbstractInjectionAdder implements GroundAdder { + + GroundAdderImpl(VoltageLevelExt voltageLevel) { + this.voltageLevel = voltageLevel; + } + + @Override + protected String getTypeDescription() { + return "Ground"; + } + + @Override + public GroundImpl add() { + NetworkImpl network = getNetwork(); + String id = checkAndGetUniqueId(); + TerminalExt terminal = checkAndGetTerminal(); + GroundImpl ground = new GroundImpl(getNetworkRef(), id, id); + ground.addTerminal(terminal); + voltageLevel.attach(terminal, false); + network.getIndex().checkAndAdd(ground); + network.getListeners().notifyCreation(ground); + return ground; + } +} diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/GroundImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/GroundImpl.java new file mode 100644 index 00000000000..d73bafee4ad --- /dev/null +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/GroundImpl.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023, 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.PowsyblException; +import com.powsybl.iidm.network.Ground; +import com.powsybl.iidm.network.impl.util.Ref; + +/** + * @author Nicolas Rol {@literal } + */ +class GroundImpl extends AbstractConnectable implements Ground { + + GroundImpl(Ref networkRef, + String id, String name) { + super(networkRef, id, name, false); + } + + @Override + public TerminalExt getTerminal() { + return terminals.get(0); + } + + @Override + public void setFictitious(boolean fictitious) { + if (fictitious) { + throw new PowsyblException("The ground cannot be fictitious."); + } else { + this.fictitious = false; + } + } + + @Override + protected String getTypeDescription() { + return "Ground"; + } +} diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/LccConverterStationAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/LccConverterStationAdderImpl.java index 544980fee77..fc8433908fc 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/LccConverterStationAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/LccConverterStationAdderImpl.java @@ -9,7 +9,6 @@ import com.powsybl.iidm.network.LccConverterStation; import com.powsybl.iidm.network.LccConverterStationAdder; import com.powsybl.iidm.network.ValidationUtil; -import com.powsybl.iidm.network.impl.util.Ref; /** * @author Geoffroy Jamgotchian {@literal } @@ -34,15 +33,6 @@ public LccConverterStationAdder setPowerFactor(float powerFactor) { return this; } - @Override - protected Ref getVariantManagerHolder() { - return getNetworkRef(); - } - - private Ref getNetworkRef() { - return getVoltageLevel().getNetworkRef(); - } - @Override public LccConverterStation add() { String id = checkAndGetUniqueId(); diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/LoadAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/LoadAdderImpl.java index 0bbd64ad3f7..68ace062f85 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/LoadAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/LoadAdderImpl.java @@ -7,7 +7,6 @@ package com.powsybl.iidm.network.impl; import com.powsybl.iidm.network.*; -import com.powsybl.iidm.network.impl.util.Ref; /** * @@ -15,8 +14,6 @@ */ class LoadAdderImpl extends AbstractInjectionAdder implements LoadAdder { - private final VoltageLevelExt voltageLevel; - private LoadType loadType = LoadType.UNDEFINED; private AbstractLoadModelImpl model; @@ -29,11 +26,6 @@ class LoadAdderImpl extends AbstractInjectionAdder implements Loa this.voltageLevel = voltageLevel; } - @Override - protected NetworkImpl getNetwork() { - return voltageLevel.getNetwork(); - } - @Override protected String getTypeDescription() { return "Load"; @@ -71,15 +63,6 @@ public ExponentialLoadModelAdder newExponentialModel() { return new ExponentialLoadModelAdderImpl(this); } - @Override - protected Ref getVariantManagerHolder() { - return getNetworkRef(); - } - - private Ref getNetworkRef() { - return voltageLevel.getNetworkRef(); - } - @Override public LoadImpl add() { NetworkImpl network = getNetwork(); diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NetworkImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NetworkImpl.java index ce8f68df56c..b714fd39920 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NetworkImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/NetworkImpl.java @@ -719,6 +719,26 @@ public HvdcLineAdder newHvdcLine() { return newHvdcLine(null); } + @Override + public Ground getGround(String id) { + return index.get(id, GroundImpl.class); + } + + @Override + public Iterable getGrounds() { + return Collections.unmodifiableCollection(index.getAll(GroundImpl.class)); + } + + @Override + public Stream getGroundStream() { + return index.getAll(GroundImpl.class).stream().map(Function.identity()); + } + + @Override + public int getGroundCount() { + return index.getAll(GroundImpl.class).size(); + } + HvdcLineAdder newHvdcLine(String subnetwork) { return new HvdcLineAdderImpl(this, subnetwork); } 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/NodeBreakerVoltageLevel.java index 5467093d09c..a2496cda227 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/NodeBreakerVoltageLevel.java @@ -464,29 +464,16 @@ public boolean isValid(UndirectedGraph graph, if (terminal != null) { AbstractConnectable connectable = terminal.getConnectable(); switch (connectable.getType()) { - case LINE: - case TWO_WINDINGS_TRANSFORMER: - case THREE_WINDINGS_TRANSFORMER: - case HVDC_CONVERTER_STATION: - case DANGLING_LINE: + case LINE, TWO_WINDINGS_TRANSFORMER, THREE_WINDINGS_TRANSFORMER, HVDC_CONVERTER_STATION, DANGLING_LINE -> { branchCount++; feederCount++; - break; - - case LOAD: - case GENERATOR: - case BATTERY: - case SHUNT_COMPENSATOR: - case STATIC_VAR_COMPENSATOR: - feederCount++; - break; - - case BUSBAR_SECTION: - busbarSectionCount++; - break; - - default: - throw new IllegalStateException(); + } + case LOAD, GENERATOR, BATTERY, SHUNT_COMPENSATOR, STATIC_VAR_COMPENSATOR -> feederCount++; + case BUSBAR_SECTION -> busbarSectionCount++; + case GROUND -> { + // Do nothing + } + default -> throw new IllegalStateException(); } } } 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 fba74598488..aff8bf9ae16 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 @@ -7,7 +7,6 @@ package com.powsybl.iidm.network.impl; import com.powsybl.iidm.network.*; -import com.powsybl.iidm.network.impl.util.Ref; import java.util.ArrayList; import java.util.List; @@ -19,8 +18,6 @@ */ class ShuntCompensatorAdderImpl extends AbstractInjectionAdder implements ShuntCompensatorAdder { - private final VoltageLevelExt voltageLevel; - private ShuntCompensatorModelBuilder modelBuilder; private Integer sectionCount; @@ -37,11 +34,6 @@ class ShuntCompensatorAdderImpl extends AbstractInjectionAdder getVariantManagerHolder() { - return getNetworkRef(); - } - - private Ref getNetworkRef() { - return voltageLevel.getNetworkRef(); - } - @Override public ShuntCompensatorImpl add() { NetworkImpl network = getNetwork(); 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 889022e7556..49986a9c987 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 @@ -6,8 +6,10 @@ */ package com.powsybl.iidm.network.impl; -import com.powsybl.iidm.network.*; -import com.powsybl.iidm.network.impl.util.Ref; +import com.powsybl.iidm.network.StaticVarCompensator; +import com.powsybl.iidm.network.StaticVarCompensatorAdder; +import com.powsybl.iidm.network.Terminal; +import com.powsybl.iidm.network.ValidationUtil; import java.util.Objects; @@ -16,8 +18,6 @@ */ class StaticVarCompensatorAdderImpl extends AbstractInjectionAdder implements StaticVarCompensatorAdder { - private final VoltageLevelExt vl; - private double bMin = Double.NaN; private double bMax = Double.NaN; @@ -31,12 +31,7 @@ class StaticVarCompensatorAdderImpl extends AbstractInjectionAdder getVariantManagerHolder() { - return getNetworkRef(); - } - - private Ref getNetworkRef() { - return vl.getNetworkRef(); - } - @Override public StaticVarCompensatorImpl add() { NetworkImpl network = getNetwork(); @@ -103,7 +89,7 @@ public StaticVarCompensatorImpl add() { regulationMode, regulatingTerminal != null ? regulatingTerminal : terminal, getNetworkRef()); svc.addTerminal(terminal); - vl.attach(terminal, false); + voltageLevel.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/SubnetworkImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/SubnetworkImpl.java index c0673bb2994..577b9bb7ac0 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/SubnetworkImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/SubnetworkImpl.java @@ -12,10 +12,10 @@ import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.impl.util.RefChain; import com.powsybl.iidm.network.impl.util.RefObj; -import java.time.ZonedDateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.time.ZonedDateTime; import java.util.*; import java.util.function.Function; import java.util.function.Predicate; @@ -619,6 +619,27 @@ public HvdcLineAdder newHvdcLine() { return getNetwork().newHvdcLine(id); } + @Override + public Ground getGround(String id) { + Ground s = getNetwork().getGround(id); + return contains(s) ? s : null; + } + + @Override + public Iterable getGrounds() { + return getGroundStream().toList(); + } + + @Override + public Stream getGroundStream() { + return getNetwork().getGroundStream().filter(this::contains); + } + + @Override + public int getGroundCount() { + return (int) getGroundStream().count(); + } + @Override public Identifiable getIdentifiable(String id) { Identifiable i = getNetwork().getIdentifiable(id); 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 9d0d264be5d..45a0e07c799 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 @@ -8,9 +8,8 @@ import com.powsybl.iidm.network.Terminal; import com.powsybl.iidm.network.ValidationLevel; -import com.powsybl.iidm.network.VscConverterStationAdder; import com.powsybl.iidm.network.ValidationUtil; -import com.powsybl.iidm.network.impl.util.Ref; +import com.powsybl.iidm.network.VscConverterStationAdder; /** * @author Geoffroy Jamgotchian {@literal } @@ -59,15 +58,6 @@ public VscConverterStationAdder setRegulatingTerminal(Terminal regulatingTermina return this; } - @Override - protected Ref getVariantManagerHolder() { - return getNetworkRef(); - } - - private Ref getNetworkRef() { - return getVoltageLevel().getNetworkRef(); - } - @Override public VscConverterStationImpl add() { NetworkImpl network = getNetwork(); diff --git a/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/tck/GroundTest.java b/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/tck/GroundTest.java new file mode 100644 index 00000000000..5fa4d54372b --- /dev/null +++ b/iidm/iidm-impl/src/test/java/com/powsybl/iidm/network/impl/tck/GroundTest.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023, 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.tck; + +import com.powsybl.iidm.network.tck.AbstractGroundTest; + +/** + * @author Nicolas Rol {@literal } + */ +class GroundTest extends AbstractGroundTest { +} diff --git a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/GroundSerDe.java b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/GroundSerDe.java new file mode 100644 index 00000000000..7eb26230d54 --- /dev/null +++ b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/GroundSerDe.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023, 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.serde; + +import com.powsybl.iidm.network.Ground; +import com.powsybl.iidm.network.GroundAdder; +import com.powsybl.iidm.network.VoltageLevel; + +import static com.powsybl.iidm.serde.ConnectableSerDeUtil.readNodeOrBus; +import static com.powsybl.iidm.serde.ConnectableSerDeUtil.writeNodeOrBus; + +/** + * @author Nicolas Rol {@literal } + */ +public class GroundSerDe extends AbstractSimpleIdentifiableSerDe { + + static final GroundSerDe INSTANCE = new GroundSerDe(); + + static final String ROOT_ELEMENT_NAME = "ground"; + static final String ARRAY_ELEMENT_NAME = "grounds"; + + @Override + protected String getRootElementName() { + return ROOT_ELEMENT_NAME; + } + + @Override + protected void writeRootElementAttributes(Ground ground, VoltageLevel vl, NetworkSerializerContext context) { + writeNodeOrBus(null, ground.getTerminal(), context); + } + + @Override + protected GroundAdder createAdder(VoltageLevel voltageLevel) { + return voltageLevel.newGround(); + } + + @Override + protected Ground readRootElementAttributes(GroundAdder adder, VoltageLevel parent, NetworkDeserializerContext context) { + readNodeOrBus(adder, context); + return adder.add(); + } + + @Override + protected void readSubElements(Ground ground, NetworkDeserializerContext context) { + context.getReader().readChildNodes(elementName -> readSubElement(elementName, ground, context)); + } +} diff --git a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/NetworkSerDe.java b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/NetworkSerDe.java index 5debecd41b4..9b6004138c4 100644 --- a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/NetworkSerDe.java +++ b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/NetworkSerDe.java @@ -565,7 +565,8 @@ private static BiMap createArrayNameSingleNameBiMap(boolean with Map.entry(VoltageAngleLimitSerDe.ARRAY_ELEMENT_NAME, VoltageAngleLimitSerDe.ROOT_ELEMENT_NAME), Map.entry(VoltageLevelSerDe.ARRAY_ELEMENT_NAME, VoltageLevelSerDe.ROOT_ELEMENT_NAME), Map.entry(VoltageLevelSerDe.INJ_ARRAY_ELEMENT_NAME, VoltageLevelSerDe.INJ_ROOT_ELEMENT_NAME), - Map.entry(VscConverterStationSerDe.ARRAY_ELEMENT_NAME, VscConverterStationSerDe.ROOT_ELEMENT_NAME)); + Map.entry(VscConverterStationSerDe.ARRAY_ELEMENT_NAME, VscConverterStationSerDe.ROOT_ELEMENT_NAME), + Map.entry(GroundSerDe.ARRAY_ELEMENT_NAME, GroundSerDe.ROOT_ELEMENT_NAME)); Map extensionsMap = new HashMap<>(); if (withExtensions) { diff --git a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/VoltageLevelSerDe.java b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/VoltageLevelSerDe.java index 78339cdcf54..bb09f0b23ff 100644 --- a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/VoltageLevelSerDe.java +++ b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/VoltageLevelSerDe.java @@ -82,6 +82,7 @@ protected void writeSubElements(VoltageLevel vl, Container> c) { if (c instanceof Network network) { @@ -318,6 +330,7 @@ protected void readSubElements(VoltageLevel vl, NetworkDeserializerContext conte case StaticVarCompensatorSerDe.ROOT_ELEMENT_NAME -> StaticVarCompensatorSerDe.INSTANCE.read(vl, context); case VscConverterStationSerDe.ROOT_ELEMENT_NAME -> VscConverterStationSerDe.INSTANCE.read(vl, context); case LccConverterStationSerDe.ROOT_ELEMENT_NAME -> LccConverterStationSerDe.INSTANCE.read(vl, context); + case GroundSerDe.ROOT_ELEMENT_NAME -> GroundSerDe.INSTANCE.read(vl, context); default -> readSubElement(elementName, vl, context); } }); diff --git a/iidm/iidm-serde/src/main/resources/xsd/iidm_V1_12.xsd b/iidm/iidm-serde/src/main/resources/xsd/iidm_V1_12.xsd index 91a8ad187f1..f1d62b6d4ff 100644 --- a/iidm/iidm-serde/src/main/resources/xsd/iidm_V1_12.xsd +++ b/iidm/iidm-serde/src/main/resources/xsd/iidm_V1_12.xsd @@ -109,6 +109,7 @@ + @@ -650,4 +651,10 @@ + + + + + + diff --git a/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/GroundSerDeTest.java b/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/GroundSerDeTest.java new file mode 100644 index 00000000000..c78eaeacb60 --- /dev/null +++ b/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/GroundSerDeTest.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023, 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.serde; + +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.test.TwoVoltageLevelNetworkFactory; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static com.powsybl.iidm.serde.IidmSerDeConstants.CURRENT_IIDM_VERSION; + +/** + * @author Nicolas Rol {@literal } + */ +class GroundSerDeTest extends AbstractIidmSerDeTest { + + @Test + void test() throws IOException { + // Initialise the network + Network network = TwoVoltageLevelNetworkFactory.createWithGrounds(); + + // Test for current version + allFormatsRoundTripTest(network, "ground.xml", CURRENT_IIDM_VERSION); + + // backward compatibility + allFormatsRoundTripFromVersionedXmlFromMinToCurrentVersionTest("ground.xml", IidmVersion.V_1_11); + } +} diff --git a/iidm/iidm-serde/src/test/resources/V1_11/ground.xml b/iidm/iidm-serde/src/test/resources/V1_11/ground.xml new file mode 100644 index 00000000000..0fffadbe000 --- /dev/null +++ b/iidm/iidm-serde/src/test/resources/V1_11/ground.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-serde/src/test/resources/V1_12/ground.xml b/iidm/iidm-serde/src/test/resources/V1_12/ground.xml new file mode 100644 index 00000000000..b8e62d6934b --- /dev/null +++ b/iidm/iidm-serde/src/test/resources/V1_12/ground.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/AbstractGroundTest.java b/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/AbstractGroundTest.java new file mode 100644 index 00000000000..f7027b9bd2c --- /dev/null +++ b/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/AbstractGroundTest.java @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2023, 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.tck; + +import com.powsybl.commons.PowsyblException; +import com.powsybl.iidm.network.*; +import com.powsybl.iidm.network.extensions.BusbarSectionPositionAdder; +import com.powsybl.iidm.network.test.TwoVoltageLevelNetworkFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Nicolas Rol {@literal } + */ +public abstract class AbstractGroundTest { + private Network network; + + @BeforeEach + public void initNetwork() { + // Network initialisation + network = TwoVoltageLevelNetworkFactory.create(); + } + + @Test + void test() { + // Get the voltage levels + VoltageLevel vl1 = network.getVoltageLevel("VL1"); + VoltageLevel vl2 = network.getVoltageLevel("VL2"); + + // Create disconnector and ground element in node-breaker view + vl1.getNodeBreakerView().newDisconnector() + .setId("D_1_6") + .setKind(SwitchKind.DISCONNECTOR) + .setOpen(false) + .setNode1(1) + .setNode2(6) + .add(); + Ground groundNB = createGroundNodeBreaker(vl1, "GroundNB", 6, true); + + // Create ground in bus-breaker view + Ground groundBB = createGroundBusBreaker(vl2, "GroundBB", "BUS2", true); + + // List of grounds + List groundList = List.of(groundNB, groundBB); + List groundListVl1 = Collections.singletonList(groundNB); + + // Test getters + assertEquals(IdentifiableType.GROUND, groundNB.getType()); + assertEquals(IdentifiableType.GROUND, groundBB.getType()); + assertEquals(vl1, groundNB.getTerminal().getVoltageLevel()); + assertEquals(vl2, groundBB.getTerminal().getVoltageLevel()); + assertEquals("GroundNB", groundNB.getId()); + assertEquals("GroundBB", groundBB.getId()); + assertEquals(network, groundNB.getNetwork()); + assertEquals(network, groundBB.getNetwork()); + assertEquals(network, groundNB.getParentNetwork()); + assertEquals(network, groundBB.getParentNetwork()); + assertEquals(2, network.getIdentifiableStream(IdentifiableType.GROUND).count()); + network.getIdentifiableStream(IdentifiableType.GROUND).forEach(ground -> assertTrue(groundList.contains((Ground) ground))); + assertEquals(groundNB, network.getGround("GroundNB")); + assertEquals(2, ((Collection) network.getGrounds()).size()); + network.getGrounds().forEach(ground -> assertTrue(groundList.contains(ground))); + network.getGroundStream().forEach(ground -> assertTrue(groundList.contains(ground))); + assertEquals(2, network.getGroundCount()); + assertNull(network.getGround("GroundNB2")); + assertEquals(1, ((Collection) vl1.getGrounds()).size()); + vl1.getGrounds().forEach(ground -> assertTrue(groundListVl1.contains(ground))); + vl1.getGroundStream().forEach(ground -> assertTrue(groundListVl1.contains(ground))); + assertEquals(1, vl1.getGroundCount()); + } + + @Test + void testOnSubnetwork() { + // Subnetwork creation + Network subnetwork1 = createSubnetwork(network, "Sub1", "Sub1", "format1"); + Network subnetwork2 = createSubnetwork(network, "Sub2", "Sub2", "format2"); + + // Get the voltage levels + VoltageLevel vl1Sub1 = subnetwork1.getVoltageLevel("Sub1_VL1"); + VoltageLevel vl2Sub1 = subnetwork1.getVoltageLevel("Sub1_VL2"); + + // Create disconnector and ground element in node-breaker view + vl1Sub1.getNodeBreakerView().newDisconnector() + .setId("D_1_6") + .setKind(SwitchKind.DISCONNECTOR) + .setOpen(false) + .setNode1(1) + .setNode2(6) + .add(); + vl1Sub1.getNodeBreakerView().newDisconnector() + .setId("D_2_7") + .setKind(SwitchKind.DISCONNECTOR) + .setOpen(false) + .setNode1(2) + .setNode2(7) + .add(); + Ground groundNBSub16 = createGroundNodeBreaker(vl1Sub1, "GroundNBSub1_6", 6, true); + Ground groundNBSub17 = createGroundNodeBreaker(vl1Sub1, "GroundNBSub1_7", 7, true); + + // Create ground in bus-breaker view + Ground groundBBSub12 = createGroundBusBreaker(vl2Sub1, "GroundBBSub1_2", "Sub1_BUS2", true); + + // List of grounds + List groundList = List.of(groundNBSub16, groundNBSub17, groundBBSub12); + + // Assertions + assertEquals(groundNBSub16, subnetwork1.getGround("GroundNBSub1_6")); + assertEquals(3, ((List) subnetwork1.getGrounds()).size()); + subnetwork1.getGrounds().forEach(ground -> assertTrue(groundList.contains(ground))); + assertEquals(3, subnetwork1.getGroundStream().count()); + subnetwork1.getGroundStream().forEach(ground -> assertTrue(groundList.contains(ground))); + assertEquals(3, subnetwork1.getGroundCount()); + assertNull(subnetwork2.getGround("GroundNB")); + } + + @Test + void testCreateSameId() { + // Get the voltage level + VoltageLevel vl1 = network.getVoltageLevel("VL1"); + VoltageLevel vl2 = network.getVoltageLevel("VL2"); + + // Create first grounds + vl1.getNodeBreakerView().newDisconnector() + .setId("D_1_6") + .setKind(SwitchKind.DISCONNECTOR) + .setOpen(false) + .setNode1(1) + .setNode2(6) + .add(); + createGroundNodeBreaker(vl1, "Ground", 6, false); + createGroundBusBreaker(vl2, "Ground1", "BUS1", false); + + // Create a second with the same ID + PowsyblException exception = assertThrows(PowsyblException.class, () -> createGroundNodeBreaker(vl1, "Ground", 7, false)); + assertTrue(Pattern.compile("The network test already contains an object '(\\w+)' with the id 'Ground'").matcher(exception.getMessage()).find()); + exception = assertThrows(PowsyblException.class, () -> createGroundBusBreaker(vl2, "Ground1", "BUS1", false)); + assertTrue(Pattern.compile("The network test already contains an object '(\\w+)' with the id 'Ground1'").matcher(exception.getMessage()).find()); + // Nota : the class name is undefined here since it will depend on the implementation of the Ground interface + } + + @Test + void testFictitiousGround() { + // Get the voltage level + VoltageLevel vl1 = network.getVoltageLevel("VL1"); + + // Create first grounds + vl1.getNodeBreakerView().newDisconnector() + .setId("D_1_6") + .setKind(SwitchKind.DISCONNECTOR) + .setOpen(false) + .setNode1(1) + .setNode2(6) + .add(); + Ground ground = createGroundNodeBreaker(vl1, "Ground", 7, false); + + // Ground cannot be fictitious + ground.setFictitious(false); + assertFalse(ground.isFictitious()); + + // Create a second with the same ID + PowsyblException exception = assertThrows(PowsyblException.class, () -> ground.setFictitious(true)); + assertTrue(Pattern.compile("The ground cannot be fictitious.").matcher(exception.getMessage()).find()); + } + + @Test + void testCreationError() { + // Get the voltage level + VoltageLevel vl1 = network.getVoltageLevel("VL1"); + VoltageLevel vl2 = network.getVoltageLevel("VL2"); + + // Create first grounds + vl1.getNodeBreakerView().newDisconnector() + .setId("D_1_6") + .setKind(SwitchKind.DISCONNECTOR) + .setOpen(false) + .setNode1(1) + .setNode2(6) + .add(); + // Create a ground in NB + GroundAdder groundAdderNB = vl1.newGround() + .setId("Ground") + .setEnsureIdUnicity(true); + ValidationException exception = assertThrows(ValidationException.class, groundAdderNB::add); + assertEquals("Ground 'Ground': connectable bus is not set", exception.getMessage()); + groundAdderNB = vl1.newGround() + .setNode(6) + .setEnsureIdUnicity(true); + PowsyblException powsyblException = assertThrows(PowsyblException.class, groundAdderNB::add); + assertEquals("Ground id is not set", powsyblException.getMessage()); + + // Create a ground in BB + GroundAdder groundAdderBB = vl2.newGround() + .setId("Ground") + .setEnsureIdUnicity(true); + exception = assertThrows(ValidationException.class, groundAdderBB::add); + assertEquals("Ground 'Ground': connectable bus is not set", exception.getMessage()); + groundAdderBB = vl2.newGround() + .setBus("BUS1") + .setEnsureIdUnicity(true); + powsyblException = assertThrows(PowsyblException.class, groundAdderBB::add); + assertEquals("Ground id is not set", powsyblException.getMessage()); + } + + private Ground createGroundNodeBreaker(VoltageLevel voltageLevel, String id, int node, boolean ensureIdUnicity) { + return voltageLevel.newGround() + .setId(id) + .setNode(node) + .setEnsureIdUnicity(ensureIdUnicity) + .add(); + } + + private Ground createGroundBusBreaker(VoltageLevel voltageLevel, String id, String bus, boolean ensureIdUnicity) { + return voltageLevel.newGround() + .setId(id) + .setBus(bus) + .setEnsureIdUnicity(ensureIdUnicity) + .add(); + } + + private Network createSubnetwork(Network network, String subnetworkId, String name, String sourceFormat) { + // Subnetwork creation + Network subnetwork = network.createSubnetwork(subnetworkId, name, sourceFormat); + + // Substation + Substation substation = subnetwork.newSubstation() + .setId(subnetworkId + "_S") + .setCountry(Country.FR) + .add(); + + // Voltage levels + VoltageLevel vl1 = substation.newVoltageLevel() + .setId(subnetworkId + "_VL1") + .setNominalV(400.0) + .setTopologyKind(TopologyKind.NODE_BREAKER) + .add(); + VoltageLevel vl2 = substation.newVoltageLevel() + .setId(subnetworkId + "_VL2") + .setNominalV(220.0) + .setTopologyKind(TopologyKind.BUS_BREAKER) + .add(); + + // Buses and Busbar sections + BusbarSection bbs1 = vl1.getNodeBreakerView().newBusbarSection() + .setId(subnetworkId + "_BBS1") + .setNode(0) + .add(); + bbs1.newExtension(BusbarSectionPositionAdder.class) + .withBusbarIndex(1) + .withSectionIndex(1) + .add(); + BusbarSection bbs2 = vl1.getNodeBreakerView().newBusbarSection() + .setId(subnetworkId + "_BBS2") + .setNode(1) + .add(); + bbs2.newExtension(BusbarSectionPositionAdder.class) + .withBusbarIndex(2) + .withSectionIndex(1) + .add(); + vl2.getBusBreakerView().newBus() + .setId(subnetworkId + "_BUS1") + .add(); + vl2.getBusBreakerView().newBus() + .setId(subnetworkId + "_BUS2") + .add(); + + return subnetwork; + } +} diff --git a/iidm/iidm-test/src/main/java/com/powsybl/iidm/network/test/TwoVoltageLevelNetworkFactory.java b/iidm/iidm-test/src/main/java/com/powsybl/iidm/network/test/TwoVoltageLevelNetworkFactory.java new file mode 100644 index 00000000000..50188cab3a2 --- /dev/null +++ b/iidm/iidm-test/src/main/java/com/powsybl/iidm/network/test/TwoVoltageLevelNetworkFactory.java @@ -0,0 +1,191 @@ +/* + * 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.test; + +import com.powsybl.iidm.network.*; +import com.powsybl.iidm.network.extensions.BusbarSectionPositionAdder; + +import java.time.ZonedDateTime; + +/** + * @author Nicolas Rol {@literal } + */ +public final class TwoVoltageLevelNetworkFactory { + + private TwoVoltageLevelNetworkFactory() { + } + + public static Network create() { + return create(NetworkFactory.findDefault()); + } + + public static Network create(NetworkFactory networkFactory) { + // Network initialisation + Network network = networkFactory.createNetwork("test", "test"); + network.setCaseDate(ZonedDateTime.parse("2023-12-18T14:49:00.000+01:00")); + + // Substation + Substation substation = network.newSubstation() + .setId("S") + .setCountry(Country.FR) + .add(); + + // Voltage levels + VoltageLevel vl1 = substation.newVoltageLevel() + .setId("VL1") + .setNominalV(400.0) + .setTopologyKind(TopologyKind.NODE_BREAKER) + .add(); + VoltageLevel vl2 = substation.newVoltageLevel() + .setId("VL2") + .setNominalV(220.0) + .setTopologyKind(TopologyKind.BUS_BREAKER) + .add(); + + // Buses and Busbar sections + BusbarSection bbs1 = vl1.getNodeBreakerView().newBusbarSection() + .setId("BBS1") + .setNode(0) + .add(); + bbs1.newExtension(BusbarSectionPositionAdder.class) + .withBusbarIndex(1) + .withSectionIndex(1) + .add(); + BusbarSection bbs2 = vl1.getNodeBreakerView().newBusbarSection() + .setId("BBS2") + .setNode(1) + .add(); + bbs2.newExtension(BusbarSectionPositionAdder.class) + .withBusbarIndex(2) + .withSectionIndex(1) + .add(); + vl2.getBusBreakerView().newBus() + .setId("BUS1") + .add(); + vl2.getBusBreakerView().newBus() + .setId("BUS2") + .add(); + + // Loads and generators + vl1.newLoad() + .setId("L") + .setNode(2) + .setP0(1) + .setQ0(1) + .add(); + vl2.newGenerator() + .setId("CB") + .setEnergySource(EnergySource.HYDRO) + .setMinP(0.0) + .setMaxP(70.0) + .setVoltageRegulatorOn(false) + .setTargetP(0.0) + .setTargetV(0.0) + .setTargetQ(0.0) + .setBus("BUS1") + .add(); + substation.newTwoWindingsTransformer() + .setId("TWT") + .setR(2.0) + .setX(14.745) + .setG(0.0) + .setB(3.2E-5) + .setRatedU1(225.0) + .setRatedU2(225.0) + .setNode1(3) + .setVoltageLevel1("VL1") + .setBus2("BUS1") + .setVoltageLevel2("VL2") + .add(); + + // Disconnectors + vl1.getNodeBreakerView().newDisconnector() + .setId("D_0_3") + .setKind(SwitchKind.DISCONNECTOR) + .setOpen(false) + .setNode1(0) + .setNode2(4) + .add(); + vl1.getNodeBreakerView().newDisconnector() + .setId("D_1_3") + .setKind(SwitchKind.DISCONNECTOR) + .setOpen(false) + .setNode1(1) + .setNode2(4) + .add(); + vl1.getNodeBreakerView().newDisconnector() + .setId("D_0_5") + .setKind(SwitchKind.DISCONNECTOR) + .setOpen(false) + .setNode1(0) + .setNode2(5) + .add(); + vl1.getNodeBreakerView().newDisconnector() + .setId("D_1_5") + .setKind(SwitchKind.DISCONNECTOR) + .setOpen(false) + .setNode1(1) + .setNode2(5) + .add(); + vl1.getNodeBreakerView().newBreaker() + .setId("BR_LOAD") + .setNode1(2) + .setNode2(4) + .setOpen(false) + .add(); + vl1.getNodeBreakerView().newBreaker() + .setId("BR_VL1") + .setNode1(3) + .setNode2(5) + .setOpen(true) + .add(); + vl2.getBusBreakerView().newSwitch() + .setId("BR_VL2") + .setBus1("BUS1") + .setBus2("BUS2") + .setOpen(false) + .add(); + + return network; + } + + public static Network createWithGrounds() { + return createWithGrounds(NetworkFactory.findDefault()); + } + + public static Network createWithGrounds(NetworkFactory networkFactory) { + Network network = create(networkFactory); + + // Get the voltage level + VoltageLevel vl1 = network.getVoltageLevel("VL1"); + VoltageLevel vl2 = network.getVoltageLevel("VL2"); + + // Create disconnector and ground element in node-breaker view + vl1.getNodeBreakerView().newDisconnector() + .setId("D_1_6") + .setKind(SwitchKind.DISCONNECTOR) + .setOpen(false) + .setNode1(1) + .setNode2(6) + .add(); + vl1.newGround() + .setId("GroundNB") + .setNode(6) + .setEnsureIdUnicity(true) + .add(); + + // Create ground in bus-breaker view + vl2.newGround() + .setId("GroundBB") + .setBus("BUS2") + .setEnsureIdUnicity(true) + .add(); + + return network; + } +} diff --git a/loadflow/loadflow-results-completion/src/main/java/com/powsybl/loadflow/resultscompletion/z0flows/Z0FlowFromBusBalance.java b/loadflow/loadflow-results-completion/src/main/java/com/powsybl/loadflow/resultscompletion/z0flows/Z0FlowFromBusBalance.java index 7721e4c0d4c..62d5d808b40 100644 --- a/loadflow/loadflow-results-completion/src/main/java/com/powsybl/loadflow/resultscompletion/z0flows/Z0FlowFromBusBalance.java +++ b/loadflow/loadflow-results-completion/src/main/java/com/powsybl/loadflow/resultscompletion/z0flows/Z0FlowFromBusBalance.java @@ -6,13 +6,11 @@ */ package com.powsybl.loadflow.resultscompletion.z0flows; -import java.util.Objects; - import com.powsybl.iidm.network.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.powsybl.iidm.network.TwoSides; +import java.util.Objects; /** * @author Luma ZamarreƱo {@literal } @@ -142,6 +140,11 @@ public void visitStaticVarCompensator(StaticVarCompensator staticVarCompensator) addFlowQ(staticVarCompensator.getTerminal()); } + @Override + public void visitGround(Ground ground) { + addFlow(ground.getTerminal()); + } + private final Bus bus; private final Line line;