From 2fe1265473052e01a2d144f08ebe29cc6d6c7648 Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Thu, 23 May 2024 16:36:37 +0200 Subject: [PATCH 1/2] Factorize TapChangerAdderImpl Signed-off-by: Florian Dupuy --- .../impl/AbstractTapChangerAdderImpl.java | 129 ++++++++++++++++++ .../impl/PhaseTapChangerAdderImpl.java | 119 +++------------- .../impl/RatioTapChangerAdderImpl.java | 124 +++-------------- 3 files changed, 167 insertions(+), 205 deletions(-) create mode 100644 iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractTapChangerAdderImpl.java diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractTapChangerAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractTapChangerAdderImpl.java new file mode 100644 index 00000000000..de468fdff70 --- /dev/null +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/AbstractTapChangerAdderImpl.java @@ -0,0 +1,129 @@ +/** + * 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.powsybl.commons.report.TypedValue; +import com.powsybl.iidm.network.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author Florian Dupuy {@literal } + */ +abstract class AbstractTapChangerAdderImpl< + A extends AbstractTapChangerAdderImpl, + H extends TapChangerParent, + T extends TapChanger, + S extends TapChangerStepImpl> { + + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTapChangerAdderImpl.class); + + protected final H parent; + private int lowTapPosition = 0; + private Integer tapPosition; + protected final List steps; + private double regulationValue = Double.NaN; + private boolean regulating = false; + private double targetDeadband = Double.NaN; + private TerminalExt regulationTerminal; + + protected AbstractTapChangerAdderImpl(H parent) { + this.parent = parent; + this.steps = new ArrayList<>(); + } + + public A setLowTapPosition(int lowTapPosition) { + this.lowTapPosition = lowTapPosition; + return self(); + } + + public A setTapPosition(int tapPosition) { + this.tapPosition = tapPosition; + return self(); + } + + public A setRegulationValue(double regulationValue) { + this.regulationValue = regulationValue; + return self(); + } + + public A setRegulating(boolean regulating) { + this.regulating = regulating; + return self(); + } + + public A setTargetDeadband(double targetDeadband) { + this.targetDeadband = targetDeadband; + return self(); + } + + public A setRegulationTerminal(Terminal regulationTerminal) { + this.regulationTerminal = (TerminalExt) regulationTerminal; + return self(); + } + + NetworkImpl getNetwork() { + return parent.getNetwork(); + } + + public T add() { + NetworkImpl network = getNetwork(); + if (tapPosition == null) { + ValidationUtil.throwExceptionOrLogError(parent, "tap position is not set", network.getMinValidationLevel()); + network.setValidationLevelIfGreaterThan(ValidationLevel.EQUIPMENT); + } + if (steps.isEmpty()) { + throw new ValidationException(parent, getValidableType() + " should have at least one step"); + } + if (tapPosition != null) { + int highTapPosition = lowTapPosition + steps.size() - 1; + if (tapPosition < lowTapPosition || tapPosition > highTapPosition) { + ValidationUtil.throwExceptionOrLogError(parent, "incorrect tap position " + + tapPosition + " [" + lowTapPosition + ", " + + highTapPosition + "]", network.getMinValidationLevel()); + network.setValidationLevelIfGreaterThan(ValidationLevel.EQUIPMENT); + } + } + + network.setValidationLevelIfGreaterThan(checkTapChangerRegulation(parent, regulationValue, regulating, regulationTerminal)); + network.setValidationLevelIfGreaterThan(ValidationUtil.checkTargetDeadband(parent, getValidableType(), regulating, + targetDeadband, network.getMinValidationLevel())); + + T tapChanger = createTapChanger(parent, lowTapPosition, steps, regulationTerminal, tapPosition, regulating, regulationValue, targetDeadband); + + Set> otherTapChangers = new HashSet<>(parent.getAllTapChangers()); + otherTapChangers.remove(tapChanger); + network.setValidationLevelIfGreaterThan(ValidationUtil.checkOnlyOneTapChangerRegulatingEnabled(parent, otherTapChangers, regulating, + network.getMinValidationLevel().compareTo(ValidationLevel.STEADY_STATE_HYPOTHESIS) >= 0)); + + if (parent.hasPhaseTapChanger() && parent.hasRatioTapChanger()) { + LOGGER.warn("{} has both Ratio and Phase Tap Changer", parent); + network.getReportNodeContext().getReportNode().newReportNode() + .withMessageTemplate("validationWarning", "${parent} has both Ratio and Phase Tap Changer.") + .withUntypedValue("parent", parent.getMessageHeader()) + .withSeverity(TypedValue.WARN_SEVERITY) + .add(); + } + + return tapChanger; + } + + protected abstract T createTapChanger(H parent, int lowTapPosition, List steps, TerminalExt regulationTerminal, Integer tapPosition, boolean regulating, double regulationValue, double targetDeadband); + + protected abstract A self(); + + protected abstract ValidationLevel checkTapChangerRegulation(H parent, double regulationValue, boolean regulating, TerminalExt regulationTerminal); + + protected abstract String getValidableType(); + +} diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/PhaseTapChangerAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/PhaseTapChangerAdderImpl.java index 4ff8060405c..a17a45b1d53 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/PhaseTapChangerAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/PhaseTapChangerAdderImpl.java @@ -7,42 +7,21 @@ */ package com.powsybl.iidm.network.impl; -import com.powsybl.commons.report.TypedValue; -import com.powsybl.iidm.network.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.powsybl.iidm.network.PhaseTapChanger; +import com.powsybl.iidm.network.PhaseTapChangerAdder; +import com.powsybl.iidm.network.ValidationLevel; +import com.powsybl.iidm.network.ValidationUtil; -import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; /** * * @author Geoffroy Jamgotchian {@literal } */ -class PhaseTapChangerAdderImpl implements PhaseTapChangerAdder { - - private static final Logger LOGGER = LoggerFactory.getLogger(PhaseTapChangerAdderImpl.class); - - private final PhaseTapChangerParent parent; - - private int lowTapPosition = 0; - - private Integer tapPosition; - - private final List steps = new ArrayList<>(); +class PhaseTapChangerAdderImpl extends AbstractTapChangerAdderImpl implements PhaseTapChangerAdder { private PhaseTapChanger.RegulationMode regulationMode = PhaseTapChanger.RegulationMode.FIXED_TAP; - private double regulationValue = Double.NaN; - - private boolean regulating = false; - - private double targetDeadband = Double.NaN; - - private TerminalExt regulationTerminal; - class StepAdderImpl implements PhaseTapChangerAdder.StepAdder { private double alpha = Double.NaN; @@ -104,23 +83,7 @@ public PhaseTapChangerAdder endStep() { } PhaseTapChangerAdderImpl(PhaseTapChangerParent parent) { - this.parent = parent; - } - - NetworkImpl getNetwork() { - return parent.getNetwork(); - } - - @Override - public PhaseTapChangerAdder setLowTapPosition(int lowTapPosition) { - this.lowTapPosition = lowTapPosition; - return this; - } - - @Override - public PhaseTapChangerAdder setTapPosition(int tapPosition) { - this.tapPosition = tapPosition; - return this; + super(parent); } @Override @@ -130,76 +93,30 @@ public PhaseTapChangerAdder setRegulationMode(PhaseTapChanger.RegulationMode reg } @Override - public PhaseTapChangerAdder setRegulationValue(double regulationValue) { - this.regulationValue = regulationValue; - return this; + public PhaseTapChangerAdder.StepAdder beginStep() { + return new StepAdderImpl(); } @Override - public PhaseTapChangerAdder setRegulating(boolean regulating) { - this.regulating = regulating; - return this; + protected PhaseTapChanger createTapChanger(PhaseTapChangerParent parent, int lowTapPosition, List steps, TerminalExt regulationTerminal, Integer tapPosition, boolean regulating, double regulationValue, double targetDeadband) { + PhaseTapChangerImpl tapChanger = new PhaseTapChangerImpl(parent, lowTapPosition, steps, regulationTerminal, tapPosition, regulating, regulationMode, regulationValue, targetDeadband); + parent.setPhaseTapChanger(tapChanger); + return tapChanger; } @Override - public PhaseTapChangerAdder setTargetDeadband(double targetDeadband) { - this.targetDeadband = targetDeadband; + protected PhaseTapChangerAdderImpl self() { return this; } @Override - public PhaseTapChangerAdder setRegulationTerminal(Terminal regulationTerminal) { - this.regulationTerminal = (TerminalExt) regulationTerminal; - return this; + protected ValidationLevel checkTapChangerRegulation(PhaseTapChangerParent parent, double regulationValue, boolean regulating, TerminalExt regulationTerminal) { + return ValidationUtil.checkPhaseTapChangerRegulation(parent, regulationMode, regulationValue, regulating, + regulationTerminal, getNetwork(), getNetwork().getMinValidationLevel().compareTo(ValidationLevel.STEADY_STATE_HYPOTHESIS) >= 0); } @Override - public PhaseTapChangerAdder.StepAdder beginStep() { - return new StepAdderImpl(); + protected String getValidableType() { + return "phase tap changer"; } - - @Override - public PhaseTapChanger add() { - NetworkImpl network = getNetwork(); - if (tapPosition == null) { - ValidationUtil.throwExceptionOrLogError(parent, "tap position is not set", network.getMinValidationLevel()); - network.setValidationLevelIfGreaterThan(ValidationLevel.EQUIPMENT); - } - if (steps.isEmpty()) { - throw new ValidationException(parent, "a phase tap changer shall have at least one step"); - } - if (tapPosition != null) { - int highTapPosition = lowTapPosition + steps.size() - 1; - if (tapPosition < lowTapPosition || tapPosition > highTapPosition) { - ValidationUtil.throwExceptionOrLogError(parent, "incorrect tap position " - + tapPosition + " [" + lowTapPosition + ", " - + highTapPosition + "]", network.getMinValidationLevel()); - network.setValidationLevelIfGreaterThan(ValidationLevel.EQUIPMENT); - } - } - network.setValidationLevelIfGreaterThan(ValidationUtil.checkPhaseTapChangerRegulation(parent, regulationMode, regulationValue, regulating, - regulationTerminal, network, network.getMinValidationLevel().compareTo(ValidationLevel.STEADY_STATE_HYPOTHESIS) >= 0)); - network.setValidationLevelIfGreaterThan(ValidationUtil.checkTargetDeadband(parent, "phase tap changer", regulating, - targetDeadband, network.getMinValidationLevel())); - PhaseTapChangerImpl tapChanger - = new PhaseTapChangerImpl(parent, lowTapPosition, steps, regulationTerminal, tapPosition, regulating, regulationMode, regulationValue, targetDeadband); - - Set> tapChangers = new HashSet<>(parent.getAllTapChangers()); - tapChangers.remove(parent.getPhaseTapChanger()); - network.setValidationLevelIfGreaterThan(ValidationUtil.checkOnlyOneTapChangerRegulatingEnabled(parent, tapChangers, - regulating, network.getMinValidationLevel().compareTo(ValidationLevel.STEADY_STATE_HYPOTHESIS) >= 0)); - - if (parent.hasRatioTapChanger()) { - LOGGER.warn("{} has both Ratio and Phase Tap Changer", parent); - network.getReportNodeContext().getReportNode().newReportNode() - .withMessageTemplate("validationWarning", "${parent} has both Ratio and Phase Tap Changer.") - .withUntypedValue("parent", parent.getMessageHeader()) - .withSeverity(TypedValue.WARN_SEVERITY) - .add(); - } - - parent.setPhaseTapChanger(tapChanger); - return tapChanger; - } - } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/RatioTapChangerAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/RatioTapChangerAdderImpl.java index 5bfc721822d..7759d20c5e6 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/RatioTapChangerAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/RatioTapChangerAdderImpl.java @@ -7,44 +7,23 @@ */ package com.powsybl.iidm.network.impl; -import com.powsybl.commons.report.TypedValue; -import com.powsybl.iidm.network.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.powsybl.iidm.network.RatioTapChanger; +import com.powsybl.iidm.network.RatioTapChangerAdder; +import com.powsybl.iidm.network.ValidationLevel; +import com.powsybl.iidm.network.ValidationUtil; -import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; /** * * @author Geoffroy Jamgotchian {@literal } */ -class RatioTapChangerAdderImpl implements RatioTapChangerAdder { - - private static final Logger LOGGER = LoggerFactory.getLogger(RatioTapChangerAdderImpl.class); - - private final RatioTapChangerParent parent; - - private int lowTapPosition = 0; - - private Integer tapPosition; - - private final List steps = new ArrayList<>(); +class RatioTapChangerAdderImpl extends AbstractTapChangerAdderImpl implements RatioTapChangerAdder { private boolean loadTapChangingCapabilities = false; - private boolean regulating = false; - private RatioTapChanger.RegulationMode regulationMode = null; - private double regulationValue = Double.NaN; - - private double targetDeadband = Double.NaN; - - private TerminalExt regulationTerminal; - class StepAdderImpl implements RatioTapChangerAdder.StepAdder { private double rho = Double.NaN; @@ -98,23 +77,7 @@ public RatioTapChangerAdder endStep() { } RatioTapChangerAdderImpl(RatioTapChangerParent parent) { - this.parent = parent; - } - - NetworkImpl getNetwork() { - return parent.getNetwork(); - } - - @Override - public RatioTapChangerAdder setLowTapPosition(int lowTapPosition) { - this.lowTapPosition = lowTapPosition; - return this; - } - - @Override - public RatioTapChangerAdder setTapPosition(int tapPosition) { - this.tapPosition = tapPosition; - return this; + super(parent); } @Override @@ -123,19 +86,12 @@ public RatioTapChangerAdder setLoadTapChangingCapabilities(boolean loadTapChangi return this; } - @Override - public RatioTapChangerAdder setRegulating(boolean regulating) { - this.regulating = regulating; - return this; - } - @Override public RatioTapChangerAdder setTargetV(double targetV) { if (!Double.isNaN(targetV)) { this.regulationMode = RatioTapChanger.RegulationMode.VOLTAGE; } - this.regulationValue = targetV; - return this; + return setRegulationValue(targetV); } @Override @@ -145,71 +101,31 @@ public RatioTapChangerAdder setRegulationMode(RatioTapChanger.RegulationMode reg } @Override - public RatioTapChangerAdder setRegulationValue(double regulationValue) { - this.regulationValue = regulationValue; - return this; + public RatioTapChangerAdder.StepAdder beginStep() { + return new StepAdderImpl(); } @Override - public RatioTapChangerAdder setTargetDeadband(double targetDeadband) { - this.targetDeadband = targetDeadband; - return this; + protected RatioTapChanger createTapChanger(RatioTapChangerParent parent, int lowTapPosition, List steps, TerminalExt regulationTerminal, Integer tapPosition, boolean regulating, double regulationValue, double targetDeadband) { + RatioTapChangerImpl tapChanger = new RatioTapChangerImpl(parent, lowTapPosition, steps, regulationTerminal, loadTapChangingCapabilities, + tapPosition, regulating, regulationMode, regulationValue, targetDeadband); + parent.setRatioTapChanger(tapChanger); + return tapChanger; } @Override - public RatioTapChangerAdder setRegulationTerminal(Terminal regulationTerminal) { - this.regulationTerminal = (TerminalExt) regulationTerminal; + protected RatioTapChangerAdderImpl self() { return this; } @Override - public RatioTapChangerAdder.StepAdder beginStep() { - return new StepAdderImpl(); + protected ValidationLevel checkTapChangerRegulation(RatioTapChangerParent parent, double regulationValue, boolean regulating, TerminalExt regulationTerminal) { + return ValidationUtil.checkRatioTapChangerRegulation(parent, regulating, loadTapChangingCapabilities, regulationTerminal, + regulationMode, regulationValue, getNetwork(), getNetwork().getMinValidationLevel()); } @Override - public RatioTapChanger add() { - NetworkImpl network = getNetwork(); - if (tapPosition == null) { - ValidationUtil.throwExceptionOrLogError(parent, "tap position is not set", network.getMinValidationLevel()); - network.setValidationLevelIfGreaterThan(ValidationLevel.EQUIPMENT); - } - if (steps.isEmpty()) { - throw new ValidationException(parent, "ratio tap changer should have at least one step"); - } - if (tapPosition != null) { - int highTapPosition = lowTapPosition + steps.size() - 1; - if (tapPosition < lowTapPosition || tapPosition > highTapPosition) { - ValidationUtil.throwExceptionOrLogError(parent, "incorrect tap position " - + tapPosition + " [" + lowTapPosition + ", " - + highTapPosition + "]", network.getMinValidationLevel()); - network.setValidationLevelIfGreaterThan(ValidationLevel.EQUIPMENT); - } - } - network.setValidationLevelIfGreaterThan(ValidationUtil.checkRatioTapChangerRegulation(parent, regulating, loadTapChangingCapabilities, regulationTerminal, - regulationMode, regulationValue, network, network.getMinValidationLevel())); - network.setValidationLevelIfGreaterThan(ValidationUtil.checkTargetDeadband(parent, "ratio tap changer", regulating, targetDeadband, - network.getMinValidationLevel())); - RatioTapChangerImpl tapChanger - = new RatioTapChangerImpl(parent, lowTapPosition, steps, regulationTerminal, loadTapChangingCapabilities, - tapPosition, regulating, regulationMode, regulationValue, targetDeadband); - - Set> tapChangers = new HashSet<>(parent.getAllTapChangers()); - tapChangers.remove(parent.getRatioTapChanger()); - network.setValidationLevelIfGreaterThan(ValidationUtil.checkOnlyOneTapChangerRegulatingEnabled(parent, tapChangers, regulating, - network.getMinValidationLevel().compareTo(ValidationLevel.STEADY_STATE_HYPOTHESIS) >= 0)); - - if (parent.hasPhaseTapChanger()) { - LOGGER.warn("{} has both Ratio and Phase Tap Changer", parent); - network.getReportNodeContext().getReportNode().newReportNode() - .withMessageTemplate("validationWarning", "${parent} has both Ratio and Phase Tap Changer.") - .withUntypedValue("parent", parent.getMessageHeader()) - .withSeverity(TypedValue.WARN_SEVERITY) - .add(); - } - - parent.setRatioTapChanger(tapChanger); - return tapChanger; + protected String getValidableType() { + return "ratio tap changer"; } - } From f34c1a7b4972980f8176ff09bf655640eedf743d Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Thu, 23 May 2024 16:37:22 +0200 Subject: [PATCH 2/2] Fix unit test: "shall" is now "should" Signed-off-by: Florian Dupuy --- .../powsybl/iidm/network/tck/AbstractTapChangerTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/AbstractTapChangerTest.java b/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/AbstractTapChangerTest.java index 13721d67a10..24954126d3b 100644 --- a/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/AbstractTapChangerTest.java +++ b/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/AbstractTapChangerTest.java @@ -376,15 +376,15 @@ private void createPhaseTapChangerWith2Steps(int tapPosition, int lowTap, boolea @Test public void invalidPhaseTapChangerWithoutSteps() { - ValidationException e = assertThrows(ValidationException.class, () -> twt.newPhaseTapChanger() + PhaseTapChangerAdder phaseTapChangerAdder = twt.newPhaseTapChanger() .setTapPosition(1) .setLowTapPosition(0) .setRegulating(true) .setRegulationMode(PhaseTapChanger.RegulationMode.ACTIVE_POWER_CONTROL) .setRegulationValue(10.0) - .setRegulationTerminal(terminal) - .add()); - assertTrue(e.getMessage().contains("phase tap changer shall have at least one step")); + .setRegulationTerminal(terminal); + ValidationException e = assertThrows(ValidationException.class, phaseTapChangerAdder::add); + assertEquals("2 windings transformer 'twt': phase tap changer should have at least one step", e.getMessage()); } @Test