From db98dbf4c61ab3a4fa1630fd012b35ed4005dbff Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Wed, 6 Dec 2023 13:21:23 +0100 Subject: [PATCH] add regulating element for generator, vsc and svc creation Signed-off-by: Etienne LESOT --- .../dataframe/network/NetworkDataframes.java | 9 ----- .../adders/GeneratorDataframeAdder.java | 11 +++--- .../network/adders/SvcDataframeAdder.java | 10 +++--- .../adders/TwoWindingsTransformerSeries.java | 7 ++++ .../dataframe/network/adders/Util.java | 35 +++++++++++++++++++ .../adders/VscStationDataframeAdder.java | 6 +++- tests/test_network.py | 9 +++-- tests/test_network_elements_creation.py | 2 +- tests/test_per_unit.py | 19 +++++----- 9 files changed, 73 insertions(+), 35 deletions(-) create mode 100644 java/src/main/java/com/powsybl/dataframe/network/adders/Util.java diff --git a/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java b/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java index fb741ee5d1..5a13d46316 100644 --- a/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java +++ b/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java @@ -286,10 +286,6 @@ private static String getRegulatedElementId(Injection injection) { } else { throw new UnsupportedOperationException(String.format("%s is neither a generator, a vsc station or a var static compensator", injection.getId())); } - if (terminal.getVoltageLevel().getTopologyKind() == TopologyKind.BUS_BREAKER) { - //Not supported for the moment - return null; - } return terminal.getConnectable() != null ? terminal.getConnectable().getId() : null; } @@ -297,11 +293,6 @@ private static void setRegulatedElement(Injection injection, String elementId Network network = injection.getNetwork(); Identifiable identifiable = network.getIdentifiable(elementId); if (identifiable instanceof Injection) { - Terminal terminal = ((Injection) identifiable).getTerminal(); - if (terminal.getVoltageLevel().getTopologyKind() == TopologyKind.BUS_BREAKER) { - throw new UnsupportedOperationException("Cannot set regulated element to " + elementId + - ": not currently supported for bus breaker topologies."); - } if (injection instanceof Generator) { ((Generator) injection).setRegulatingTerminal(((Injection) identifiable).getTerminal()); } else if (injection instanceof VscConverterStation) { diff --git a/java/src/main/java/com/powsybl/dataframe/network/adders/GeneratorDataframeAdder.java b/java/src/main/java/com/powsybl/dataframe/network/adders/GeneratorDataframeAdder.java index 9d2666db11..3c476b78a7 100644 --- a/java/src/main/java/com/powsybl/dataframe/network/adders/GeneratorDataframeAdder.java +++ b/java/src/main/java/com/powsybl/dataframe/network/adders/GeneratorDataframeAdder.java @@ -12,9 +12,7 @@ import com.powsybl.dataframe.update.IntSeries; import com.powsybl.dataframe.update.StringSeries; import com.powsybl.dataframe.update.UpdatingDataframe; -import com.powsybl.iidm.network.EnergySource; -import com.powsybl.iidm.network.GeneratorAdder; -import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.*; import java.util.Collections; import java.util.List; @@ -43,7 +41,8 @@ public class GeneratorDataframeAdder extends AbstractSimpleAdder { SeriesMetadata.doubles("target_q"), SeriesMetadata.doubles("rated_s"), SeriesMetadata.doubles("target_v"), - SeriesMetadata.booleans("voltage_regulator_on") + SeriesMetadata.booleans("voltage_regulator_on"), + SeriesMetadata.strings("regulating_element_id") ); @Override @@ -63,6 +62,7 @@ private static class GeneratorSeries extends InjectionSeries { private final IntSeries voltageRegulatorOn; private final StringSeries energySource; private final StringSeries busOrBusbarSections; + private final StringSeries regulatingElements; GeneratorSeries(UpdatingDataframe dataframe) { super(dataframe); @@ -76,11 +76,13 @@ private static class GeneratorSeries extends InjectionSeries { this.voltageRegulatorOn = dataframe.getInts("voltage_regulator_on"); this.energySource = dataframe.getStrings("energy_source"); this.busOrBusbarSections = dataframe.getStrings("bus_or_busbar_section_id"); + this.regulatingElements = dataframe.getStrings("regulating_element_id"); } GeneratorAdder createAdder(Network network, int row) { GeneratorAdder adder = getVoltageLevelOrThrowWithBusOrBusbarSectionId(network, row, voltageLevels, busOrBusbarSections) .newGenerator(); + setInjectionAttributes(adder, row); applyIfPresent(maxP, row, adder::setMaxP); applyIfPresent(minP, row, adder::setMinP); @@ -90,6 +92,7 @@ GeneratorAdder createAdder(Network network, int row) { applyIfPresent(ratedS, row, adder::setRatedS); applyBooleanIfPresent(voltageRegulatorOn, row, adder::setVoltageRegulatorOn); applyIfPresent(energySource, row, EnergySource.class, adder::setEnergySource); + applyIfPresent(regulatingElements, row, elementId -> Util.setRegulatingTerminal(adder::setRegulatingTerminal, network, elementId)); return adder; } } diff --git a/java/src/main/java/com/powsybl/dataframe/network/adders/SvcDataframeAdder.java b/java/src/main/java/com/powsybl/dataframe/network/adders/SvcDataframeAdder.java index df7659f984..d44c24e8a8 100644 --- a/java/src/main/java/com/powsybl/dataframe/network/adders/SvcDataframeAdder.java +++ b/java/src/main/java/com/powsybl/dataframe/network/adders/SvcDataframeAdder.java @@ -11,9 +11,7 @@ import com.powsybl.dataframe.update.DoubleSeries; import com.powsybl.dataframe.update.StringSeries; import com.powsybl.dataframe.update.UpdatingDataframe; -import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.StaticVarCompensator; -import com.powsybl.iidm.network.StaticVarCompensatorAdder; +import com.powsybl.iidm.network.*; import java.util.Collections; import java.util.List; @@ -39,7 +37,8 @@ public class SvcDataframeAdder extends AbstractSimpleAdder { SeriesMetadata.doubles("b_min"), SeriesMetadata.strings("regulation_mode"), SeriesMetadata.doubles("target_v"), - SeriesMetadata.doubles("target_q") + SeriesMetadata.doubles("target_q"), + SeriesMetadata.strings("regulating_element_id") ); @Override @@ -56,6 +55,7 @@ private static class StaticVarCompensatorSeries extends InjectionSeries { private final DoubleSeries targetV; private final DoubleSeries targetQ; private final StringSeries busOrBusbarSections; + private final StringSeries regulatingElements; StaticVarCompensatorSeries(UpdatingDataframe dataframe) { super(dataframe); @@ -66,6 +66,7 @@ private static class StaticVarCompensatorSeries extends InjectionSeries { this.targetV = dataframe.getDoubles("target_v"); this.regulationModes = dataframe.getStrings("regulation_mode"); this.busOrBusbarSections = dataframe.getStrings("bus_or_busbar_section_id"); + this.regulatingElements = dataframe.getStrings("regulating_element_id"); } StaticVarCompensatorAdder createAdder(Network network, int row) { @@ -77,6 +78,7 @@ StaticVarCompensatorAdder createAdder(Network network, int row) { applyIfPresent(targetQ, row, adder::setReactivePowerSetpoint); applyIfPresent(targetV, row, adder::setVoltageSetpoint); applyIfPresent(regulationModes, row, StaticVarCompensator.RegulationMode.class, adder::setRegulationMode); + applyIfPresent(regulatingElements, row, elementId -> Util.setRegulatingTerminal(adder::setRegulatingTerminal, network, elementId)); return adder; } } diff --git a/java/src/main/java/com/powsybl/dataframe/network/adders/TwoWindingsTransformerSeries.java b/java/src/main/java/com/powsybl/dataframe/network/adders/TwoWindingsTransformerSeries.java index 47bab1e0aa..926dbea67c 100644 --- a/java/src/main/java/com/powsybl/dataframe/network/adders/TwoWindingsTransformerSeries.java +++ b/java/src/main/java/com/powsybl/dataframe/network/adders/TwoWindingsTransformerSeries.java @@ -1,3 +1,10 @@ +/** + * 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.dataframe.network.adders; import com.powsybl.commons.PowsyblException; diff --git a/java/src/main/java/com/powsybl/dataframe/network/adders/Util.java b/java/src/main/java/com/powsybl/dataframe/network/adders/Util.java new file mode 100644 index 0000000000..8cec43e743 --- /dev/null +++ b/java/src/main/java/com/powsybl/dataframe/network/adders/Util.java @@ -0,0 +1,35 @@ +/** + * 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.dataframe.network.adders; + +import com.powsybl.iidm.network.Identifiable; +import com.powsybl.iidm.network.Injection; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.Terminal; + +import java.util.function.Consumer; + +/** + * @author Etienne Lesot + */ +public final class Util { + + private Util() { + + } + + public static void setRegulatingTerminal(Consumer adder, Network network, String elementId) { + Identifiable injection = network.getIdentifiable(elementId); + if (injection instanceof Injection) { + adder.accept(((Injection) injection).getTerminal()); + } else { + throw new UnsupportedOperationException("Cannot set regulated element to " + elementId + + ": the regulated element may only be a busbar section or an injection."); + } + } +} diff --git a/java/src/main/java/com/powsybl/dataframe/network/adders/VscStationDataframeAdder.java b/java/src/main/java/com/powsybl/dataframe/network/adders/VscStationDataframeAdder.java index 5d5683510a..b663ed9478 100644 --- a/java/src/main/java/com/powsybl/dataframe/network/adders/VscStationDataframeAdder.java +++ b/java/src/main/java/com/powsybl/dataframe/network/adders/VscStationDataframeAdder.java @@ -39,7 +39,8 @@ public class VscStationDataframeAdder extends AbstractSimpleAdder { SeriesMetadata.doubles("target_v"), SeriesMetadata.doubles("target_q"), SeriesMetadata.doubles("loss_factor"), - SeriesMetadata.booleans("voltage_regulator_on") + SeriesMetadata.booleans("voltage_regulator_on"), + SeriesMetadata.strings("regulating_element_id") ); @Override @@ -55,6 +56,7 @@ private static class VscStationSeries extends InjectionSeries { private final DoubleSeries targetQ; private final IntSeries voltageRegulatorOn; private final StringSeries busOrBusbarSections; + private final StringSeries regulatingElements; VscStationSeries(UpdatingDataframe dataframe) { super(dataframe); @@ -64,6 +66,7 @@ private static class VscStationSeries extends InjectionSeries { this.targetQ = dataframe.getDoubles("target_q"); this.voltageRegulatorOn = dataframe.getInts("voltage_regulator_on"); this.busOrBusbarSections = dataframe.getStrings("bus_or_busbar_section_id"); + this.regulatingElements = dataframe.getStrings("regulating_element_id"); } VscConverterStationAdder createAdder(Network network, int row) { @@ -74,6 +77,7 @@ VscConverterStationAdder createAdder(Network network, int row) { applyIfPresent(targetV, row, adder::setVoltageSetpoint); applyIfPresent(targetQ, row, adder::setReactivePowerSetpoint); applyBooleanIfPresent(voltageRegulatorOn, row, adder::setVoltageRegulatorOn); + applyIfPresent(regulatingElements, row, elementId -> Util.setRegulatingTerminal(adder::setRegulatingTerminal, network, elementId)); return adder; } } diff --git a/tests/test_network.py b/tests/test_network.py index 3ad8be9c5c..4c5576a8ad 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -586,13 +586,12 @@ def test_regulated_terminal_node_breaker(): def test_regulated_terminal_bus_breaker(): n = pp.network.create_eurostag_tutorial_example1_network() generators = n.get_generators() - assert '' == generators['regulated_element_id']['GEN'] - + assert 'GEN' == generators['regulated_element_id']['GEN'] with pytest.raises(pp.PyPowsyblError): n.update_generators(id='GEN', regulated_element_id='NHV1') - with pytest.raises(pp.PyPowsyblError): - n.update_generators(id='GEN', regulated_element_id='LOAD') - + n.update_generators(id='GEN', regulated_element_id='LOAD') + generators = n.get_generators() + assert 'LOAD' == generators['regulated_element_id']['GEN'] def test_update_unknown_data(): n = pp.network.create_eurostag_tutorial_example1_network() diff --git a/tests/test_network_elements_creation.py b/tests/test_network_elements_creation.py index 9f941328ea..cdb5361c05 100644 --- a/tests/test_network_elements_creation.py +++ b/tests/test_network_elements_creation.py @@ -549,7 +549,7 @@ def test_create_network_and_run_loadflow(): generators = pd.DataFrame.from_records(index='id', data=[ {'voltage_level_id': 'VL1', 'id': 'GEN', 'bus_id': 'B1', 'target_p': 100, 'min_p': 0, 'max_p': 200, - 'target_v': 400, 'voltage_regulator_on': True} + 'target_v': 400, 'voltage_regulator_on': True, 'regulating_element_id': 'LOAD'} ]) n.create_generators(generators) diff --git a/tests/test_per_unit.py b/tests/test_per_unit.py index 66c3dfdc40..f5ec55cb94 100644 --- a/tests/test_per_unit.py +++ b/tests/test_per_unit.py @@ -47,12 +47,10 @@ def test_generator_per_unit(): 'target_v', 'target_q', 'voltage_regulator_on', 'regulated_element_id', 'p', 'q', 'i', 'voltage_level_id', 'bus_id', 'connected'], - data=[['GEN', '', 'OTHER', 6.07, -100, 49.99, -100, 100, None, 'MIN_MAX', 1.02, 3.01, True, '', -3.03, -1.12641, - 3.16461, - 'VLGEN', 'VLGEN_0', True], - ['GEN2', '', 'OTHER', 6.07, -100, 49.99, -1.79769e+306, 1.79769e+306, None, 'MIN_MAX', 1.02, 3.01, True, '', - -3.03, - -1.13, 3.16, 'VLGEN', 'VLGEN_0', True]]) + data=[['GEN', '', 'OTHER', 6.07, -100, 49.99, -100, 100, None, 'MIN_MAX', 1.02, 3.01, True, 'GEN', -3.03, + -1.12641, 3.16461, 'VLGEN', 'VLGEN_0', True], + ['GEN2', '', 'OTHER', 6.07, -100, 49.99, -1.79769e+306, 1.79769e+306, None, 'MIN_MAX', 1.02, 3.01, True, + 'GEN2', -3.03, -1.13, 3.16, 'VLGEN', 'VLGEN_0', True]]) pd.testing.assert_frame_equal(expected, n.get_generators(), check_dtype=False, atol=1e-2) generators2 = pd.DataFrame(data=[[6.080, 3.02, 1.1, False, False]], columns=['target_p', 'target_q', 'target_v', 'voltage_regulator_on', 'connected'], @@ -64,11 +62,10 @@ def test_generator_per_unit(): 'target_v', 'target_q', 'voltage_regulator_on', 'regulated_element_id', 'p', 'q', 'i', 'voltage_level_id', 'bus_id', 'connected'], - data=[['GEN', '', 'OTHER', 6.07, -100, 49.99, -100, 100, None, 'MIN_MAX', 1.1, 3.02, False, '', -3.03, -1.12641, NaN, - 'VLGEN', '', False], - ['GEN2', '', 'OTHER', 6.07, -100, 49.99, -1.79769e+306, 1.79769e+306, None, 'MIN_MAX', 1.02, 3.01, True, '', - -3.03, - -1.13, 3.16, 'VLGEN', 'VLGEN_0', True]]) + data=[['GEN', '', 'OTHER', 6.07, -100, 49.99, -100, 100, None, 'MIN_MAX', 1.1, 3.02, False, 'GEN', -3.03, + -1.12641, NaN, 'VLGEN', '', False], + ['GEN2', '', 'OTHER', 6.07, -100, 49.99, -1.79769e+306, 1.79769e+306, None, 'MIN_MAX', 1.02, 3.01, True, + 'GEN2', -3.03, -1.13, 3.16, 'VLGEN', 'VLGEN_0', True]]) pd.testing.assert_frame_equal(expected, n.get_generators(), check_dtype=False, atol=1e-2)