From 8bcc3ea80a0e5687abd8453aa54594fbd91727e9 Mon Sep 17 00:00:00 2001 From: EtienneLt <32468651+EtienneLt@users.noreply.github.com> Date: Tue, 14 May 2024 10:53:49 +0200 Subject: [PATCH] Fix java per unit (#744) Signed-off-by: Etienne LESOT (cherry picked from commit aad85d7eb5125ed40bb16185c89f25e506ffeb21) --- .../dataframe/network/NetworkDataframes.java | 20 ++++++------- .../dataframe/network/PerUnitUtil.java | 28 +++++++++++++++++-- tests/test_network.py | 2 +- 3 files changed, 37 insertions(+), 13 deletions(-) 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 697a022382..1dfdd4c24a 100644 --- a/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java +++ b/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java @@ -259,8 +259,8 @@ static NetworkDataframeMapper generators() { .doubles("max_q_at_p", getPerUnitMaxQ(getOppositeP()), false) .doubles("rated_s", (g, context) -> g.getRatedS(), (g, ratedS, context) -> g.setRatedS(ratedS)) .strings("reactive_limits_kind", NetworkDataframes::getReactiveLimitsKind) - .doubles("target_v", (g, context) -> perUnitV(context, g.getTargetV(), g.getRegulatingTerminal()), - (g, v, context) -> g.setTargetV(unPerUnitV(context, v, g.getRegulatingTerminal()))) + .doubles("target_v", (g, context) -> perUnitTargetV(context, g.getTargetV(), g.getRegulatingTerminal(), g.getTerminal()), + (g, v, context) -> g.setTargetV(unPerUnitTargetV(context, v, g.getRegulatingTerminal(), g.getTerminal()))) .doubles("target_q", (g, context) -> perUnitPQ(context, g.getTargetQ()), (g, q, context) -> g.setTargetQ(unPerUnitPQ(context, q))) .booleans("voltage_regulator_on", Generator::isVoltageRegulatorOn, Generator::setVoltageRegulatorOn) .strings("regulated_element_id", generator -> NetworkUtil.getRegulatedElementId(generator::getRegulatingTerminal), @@ -357,8 +357,8 @@ static NetworkDataframeMapper shunts() { .ints("max_section_count", ShuntCompensator::getMaximumSectionCount) .ints("section_count", ShuntCompensator::getSectionCount, ShuntCompensator::setSectionCount) .booleans("voltage_regulation_on", ShuntCompensator::isVoltageRegulatorOn, ShuntCompensator::setVoltageRegulatorOn) - .doubles("target_v", (sc, context) -> perUnitV(context, sc.getTargetV(), sc.getRegulatingTerminal()), - (sc, v, context) -> sc.setTargetV(unPerUnitV(context, v, sc.getRegulatingTerminal()))) + .doubles("target_v", (sc, context) -> perUnitTargetV(context, sc.getTargetV(), sc.getRegulatingTerminal(), sc.getTerminal()), + (sc, v, context) -> sc.setTargetV(unPerUnitTargetV(context, v, sc.getRegulatingTerminal(), sc.getTerminal()))) .doubles("target_deadband", (sc, context) -> perUnitV(context, sc.getTargetDeadband(), sc.getRegulatingTerminal()), (sc, tb, context) -> sc.setTargetDeadband(unPerUnitV(context, tb, sc.getRegulatingTerminal()))) .strings("regulating_bus_id", sc -> getBusId(sc.getRegulatingTerminal())) @@ -633,8 +633,8 @@ static NetworkDataframeMapper vscs() { .doubles("min_q_at_p", getPerUnitMinQ(getOppositeP()), false) .doubles("max_q_at_p", getPerUnitMaxQ(getOppositeP()), false) .strings("reactive_limits_kind", NetworkDataframes::getReactiveLimitsKind) - .doubles("target_v", (vsc, context) -> perUnitV(context, vsc.getVoltageSetpoint(), vsc.getRegulatingTerminal()), - (vsc, targetV, context) -> vsc.setVoltageSetpoint(unPerUnitV(context, targetV, vsc.getRegulatingTerminal()))) + .doubles("target_v", (vsc, context) -> perUnitTargetV(context, vsc.getVoltageSetpoint(), vsc.getRegulatingTerminal(), vsc.getTerminal()), + (vsc, targetV, context) -> vsc.setVoltageSetpoint(unPerUnitTargetV(context, targetV, vsc.getRegulatingTerminal(), vsc.getTerminal()))) .doubles("target_q", (vsc, context) -> perUnitPQ(context, vsc.getReactivePowerSetpoint()), (vsc, targetQ, context) -> vsc.setReactivePowerSetpoint(unPerUnitPQ(context, targetQ))) .booleans("voltage_regulator_on", VscConverterStation::isVoltageRegulatorOn, VscConverterStation::setVoltageRegulatorOn) @@ -659,8 +659,8 @@ private static NetworkDataframeMapper svcs() { .strings("name", svc -> svc.getOptionalName().orElse("")) .doubles("b_min", (svc, context) -> svc.getBmin(), (svc, bMin, context) -> svc.setBmin(bMin)) .doubles("b_max", (svc, context) -> svc.getBmax(), (svc, bMax, context) -> svc.setBmax(bMax)) - .doubles("target_v", (svc, context) -> perUnitV(context, svc.getVoltageSetpoint(), svc.getRegulatingTerminal()), - (svc, targetV, context) -> svc.setVoltageSetpoint(unPerUnitV(context, targetV, svc.getRegulatingTerminal()))) + .doubles("target_v", (svc, context) -> perUnitTargetV(context, svc.getVoltageSetpoint(), svc.getRegulatingTerminal(), svc.getTerminal()), + (svc, targetV, context) -> svc.setVoltageSetpoint(unPerUnitTargetV(context, targetV, svc.getRegulatingTerminal(), svc.getTerminal()))) .doubles("target_q", (svc, context) -> perUnitPQ(context, svc.getReactivePowerSetpoint()), (svc, targetQ, context) -> svc.setReactivePowerSetpoint(unPerUnitPQ(context, targetQ))) .enums("regulation_mode", StaticVarCompensator.RegulationMode.class, @@ -867,8 +867,8 @@ private static NetworkDataframeMapper rtcs() { .ints("step_count", t -> t.getRatioTapChanger().getStepCount()) .booleans("on_load", t -> t.getRatioTapChanger().hasLoadTapChangingCapabilities(), (t, v) -> t.getRatioTapChanger().setLoadTapChangingCapabilities(v)) .booleans("regulating", t -> t.getRatioTapChanger().isRegulating(), (t, v) -> t.getRatioTapChanger().setRegulating(v)) - .doubles("target_v", (t, context) -> perUnitV(context, t.getRatioTapChanger().getTargetV(), t.getRatioTapChanger().getRegulationTerminal()), - (t, v, context) -> t.getRatioTapChanger().setTargetV(unPerUnitV(context, v, t.getRatioTapChanger().getRegulationTerminal()))) + .doubles("target_v", (t, context) -> perUnitTargetV(context, t.getRatioTapChanger().getTargetV(), t.getRatioTapChanger().getRegulationTerminal(), t.getTerminal2()), + (t, v, context) -> t.getRatioTapChanger().setTargetV(unPerUnitTargetV(context, v, t.getRatioTapChanger().getRegulationTerminal(), t.getTerminal2()))) .doubles("target_deadband", (t, context) -> t.getRatioTapChanger().getTargetDeadband(), (t, v, context) -> t.getRatioTapChanger().setTargetDeadband(v)) .strings("regulating_bus_id", t -> getBusId(t.getRatioTapChanger().getRegulationTerminal())) diff --git a/java/src/main/java/com/powsybl/dataframe/network/PerUnitUtil.java b/java/src/main/java/com/powsybl/dataframe/network/PerUnitUtil.java index fad41c94fa..e2679390f8 100644 --- a/java/src/main/java/com/powsybl/dataframe/network/PerUnitUtil.java +++ b/java/src/main/java/com/powsybl/dataframe/network/PerUnitUtil.java @@ -212,9 +212,21 @@ public static double unPerUnitV(DataframeContext dataframeContext, double v, Bus return unPerUnitV(dataframeContext, v, bus.getVoltageLevel().getNominalV()); } + public static double unPerUnitTargetV(DataframeContext dataframeContext, double v, Terminal distantTerminal, Terminal localTerminal) { + if (distantTerminal != null) { + return unPerUnitV(dataframeContext, v, distantTerminal); + } else { + return unPerUnitV(dataframeContext, v, localTerminal); + } + } + public static double unPerUnitV(DataframeContext dataframeContext, double v, Terminal terminal) { if (terminal == null) { - throw new PowsyblException("terminal not found for un per unit V"); + if (dataframeContext.isPerUnit()) { + throw new PowsyblException("terminal not found for un per unit V"); + } else { + return v; + } } return unPerUnitV(dataframeContext, v, terminal.getVoltageLevel().getNominalV()); } @@ -231,9 +243,21 @@ public static double perUnitV(DataframeContext dataframeContext, ThreeWindingsTr return perUnitV(dataframeContext, leg.getRatedU(), leg.getTerminal()); } + public static double perUnitTargetV(DataframeContext dataframeContext, double v, Terminal distantTerminal, Terminal localTerminal) { + if (distantTerminal != null) { + return perUnitV(dataframeContext, v, distantTerminal); + } else { + return perUnitV(dataframeContext, v, localTerminal); + } + } + public static double perUnitV(DataframeContext dataframeContext, double v, Terminal terminal) { if (terminal == null) { - throw new PowsyblException("terminal not found for per unit V"); + if (dataframeContext.isPerUnit()) { + throw new PowsyblException("terminal not found for per unit V"); + } else { + return v; + } } return perUnitV(dataframeContext, v, terminal.getVoltageLevel().getNominalV()); } diff --git a/tests/test_network.py b/tests/test_network.py index 6e9e2b7dfa..508a731488 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -1828,7 +1828,7 @@ def test_ratio_tap_changer_regulated_side(): assert not tap_changer.regulating assert tap_changer.regulated_side == '' - with pytest.raises(pp.PyPowsyblError, match='terminal not found for un per unit V'): + with pytest.raises(pp.PyPowsyblError, match='a regulation terminal has to be set'): n.update_ratio_tap_changers(id='T4-1-0', target_v=100, regulating=True) with pytest.raises(pp.PyPowsyblError, match='must be ONE or TWO'):