AbstractTapChangerTest.java
/**
* Copyright (c) 2017, 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.iidm.network.*;
import com.powsybl.iidm.network.test.NoEquipmentNetworkFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
public abstract class AbstractTapChangerTest {
private Network network;
private Substation substation;
private TwoWindingsTransformer twt;
private Terminal terminal;
@BeforeEach
public void setUp() {
network = NoEquipmentNetworkFactory.create();
substation = network.getSubstation("sub");
twt = substation.newTwoWindingsTransformer()
.setId("twt")
.setName("twt_name")
.setR(1.0)
.setX(2.0)
.setG(3.0)
.setB(4.0)
.setRatedU1(5.0)
.setRatedU2(6.0)
.setVoltageLevel1("vl1")
.setVoltageLevel2("vl2")
.setConnectableBus1("busA")
.setConnectableBus2("busB")
.add();
terminal = twt.getTerminal(TwoSides.ONE);
}
@Test
public void baseTestsPhaseTapChanger() {
// adder
PhaseTapChanger phaseTapChanger = twt.newPhaseTapChanger()
.setTapPosition(1)
.setLowTapPosition(0)
.setRegulating(true)
.setTargetDeadband(1.0)
.setRegulationMode(PhaseTapChanger.RegulationMode.ACTIVE_POWER_CONTROL)
.setRegulationValue(10.0)
.setRegulationTerminal(terminal)
.beginStep()
.setR(1.0)
.setX(2.0)
.setG(3.0)
.setB(4.0)
.setAlpha(0.0)
.setRho(1.0)
.endStep()
.beginStep()
.setR(1.0)
.setX(2.0)
.setG(3.0)
.setB(4.0)
.setAlpha(5.0)
.setRho(6.0)
.endStep()
.add();
assertEquals(2, phaseTapChanger.getStepCount());
assertEquals(2, phaseTapChanger.getAllSteps().size());
assertEquals(0, phaseTapChanger.getLowTapPosition());
assertEquals(1, phaseTapChanger.getHighTapPosition());
assertTrue(phaseTapChanger.isRegulating());
assertEquals(1.0, phaseTapChanger.getTargetDeadband(), 0.0);
assertEquals(PhaseTapChanger.RegulationMode.ACTIVE_POWER_CONTROL, phaseTapChanger.getRegulationMode());
assertEquals(terminal, phaseTapChanger.getRegulationTerminal());
assertEquals(10.0, phaseTapChanger.getRegulationValue(), 0.0);
// setter getter
assertEquals(0, phaseTapChanger.getNeutralPosition().orElseThrow(IllegalStateException::new));
PhaseTapChangerStep neutralStep = phaseTapChanger.getNeutralStep().orElseThrow(IllegalStateException::new);
assertEquals(1.0, neutralStep.getR(), 0.0);
assertEquals(2.0, neutralStep.getX(), 0.0);
assertEquals(3.0, neutralStep.getG(), 0.0);
assertEquals(4.0, neutralStep.getB(), 0.0);
assertEquals(0.0, neutralStep.getAlpha(), 0.0);
assertEquals(1.0, neutralStep.getRho(), 0.0);
phaseTapChanger.setTapPosition(0);
assertEquals(0, phaseTapChanger.getTapPosition());
assertEquals(phaseTapChanger.getCurrentStep().getR(), phaseTapChanger.getStep(0).getR(), 0.0);
assertEquals(phaseTapChanger.getCurrentStep().getX(), phaseTapChanger.getStep(0).getX(), 0.0);
assertEquals(phaseTapChanger.getCurrentStep().getG(), phaseTapChanger.getStep(0).getG(), 0.0);
assertEquals(phaseTapChanger.getCurrentStep().getB(), phaseTapChanger.getStep(0).getB(), 0.0);
assertEquals(phaseTapChanger.getCurrentStep().getAlpha(), phaseTapChanger.getStep(0).getAlpha(), 0.0);
assertEquals(phaseTapChanger.getCurrentStep().getRho(), phaseTapChanger.getStep(0).getRho(), 0.0);
phaseTapChanger.setRegulationValue(5.0);
assertEquals(5.0, phaseTapChanger.getRegulationValue(), 0.0);
phaseTapChanger.setTargetDeadband(0.5);
assertEquals(0.5, phaseTapChanger.getTargetDeadband(), 0.0);
phaseTapChanger.setRegulating(false);
assertFalse(phaseTapChanger.isRegulating());
phaseTapChanger.setRegulationMode(PhaseTapChanger.RegulationMode.FIXED_TAP);
assertEquals(PhaseTapChanger.RegulationMode.FIXED_TAP, phaseTapChanger.getRegulationMode());
Terminal terminal2 = twt.getTerminal2();
phaseTapChanger.setRegulationTerminal(terminal2);
assertSame(terminal2, phaseTapChanger.getRegulationTerminal());
Terminal loadTerminal = twt.getTerminal1().getVoltageLevel().newLoad().setId("L").setP0(1.0).setQ0(1.0).setBus("busA").add().getTerminal();
phaseTapChanger.setRegulationTerminal(loadTerminal).setRegulationMode(PhaseTapChanger.RegulationMode.CURRENT_LIMITER).setRegulating(true);
assertSame(loadTerminal, phaseTapChanger.getRegulationTerminal());
network.getLoad("L").remove();
assertNull(phaseTapChanger.getRegulationTerminal());
assertFalse(phaseTapChanger.isRegulating());
phaseTapChanger.setRegulationTerminal(terminal).setRegulationMode(PhaseTapChanger.RegulationMode.FIXED_TAP);
int lowTapPosition = 2;
phaseTapChanger.setLowTapPosition(lowTapPosition);
assertEquals(lowTapPosition, phaseTapChanger.getLowTapPosition());
assertEquals(2, phaseTapChanger.getNeutralPosition().orElseThrow(IllegalStateException::new));
try {
phaseTapChanger.setTapPosition(5);
fail();
} catch (ValidationException ignored) {
// ignore
}
try {
phaseTapChanger.getStep(5);
fail();
} catch (ValidationException ignored) {
// ignore
}
try {
phaseTapChanger.setTargetDeadband(-1);
fail();
} catch (ValidationException ignored) {
// ignore
}
try {
phaseTapChanger.setTargetDeadband(Double.NaN);
phaseTapChanger.setRegulating(true);
fail();
} catch (ValidationException ignored) {
// ignore
}
// Changes listener
NetworkListener mockedListener = mock(DefaultNetworkListener.class);
// Add observer changes to current network
network.addListener(mockedListener);
// Changes will raise notifications
PhaseTapChangerStep currentStep = phaseTapChanger.getCurrentStep();
currentStep.setR(2.0);
currentStep.setX(3.0);
currentStep.setG(4.0);
currentStep.setB(5.0);
currentStep.setAlpha(6.0);
currentStep.setRho(7.0);
verify(mockedListener, times(6)).onUpdate(any(Identifiable.class), anyString(), nullable(String.class), any(), any());
// Remove observer
network.removeListener(mockedListener);
// Cancel modification
currentStep.setR(1.0);
currentStep.setX(2.0);
currentStep.setG(3.0);
currentStep.setB(4.0);
currentStep.setAlpha(5.0);
currentStep.setRho(6.0);
// Check no notification
verifyNoMoreInteractions(mockedListener);
// remove
phaseTapChanger.remove();
assertNull(twt.getPhaseTapChanger());
}
@Test
public void testDefaultPhaseTapChangerStep() {
PhaseTapChanger phaseTapChanger = twt.newPhaseTapChanger()
.setTapPosition(0)
.setLowTapPosition(0)
.setRegulating(true)
.setTargetDeadband(1.0)
.setRegulationMode(PhaseTapChanger.RegulationMode.ACTIVE_POWER_CONTROL)
.setRegulationValue(10.0)
.setRegulationTerminal(terminal)
.beginStep()
.setAlpha(0.0)
.endStep()
.add();
PhaseTapChangerStep step = phaseTapChanger.getStep(0);
assertEquals(0.0, step.getR(), 0.0);
assertEquals(0.0, step.getX(), 0.0);
assertEquals(0.0, step.getG(), 0.0);
assertEquals(0.0, step.getB(), 0.0);
assertEquals(1.0, step.getRho(), 0.0);
}
@Test
public void testPhaseTapChangerStepsReplacer() {
PhaseTapChanger phaseTapChanger = twt.newPhaseTapChanger()
.setTapPosition(1)
.setLowTapPosition(0)
.setRegulating(true)
.setTargetDeadband(1.0)
.setRegulationMode(PhaseTapChanger.RegulationMode.ACTIVE_POWER_CONTROL)
.setRegulationValue(10.0)
.setRegulationTerminal(terminal)
.beginStep()
.setR(1.0)
.setX(2.0)
.setG(3.0)
.setB(4.0)
.setAlpha(0.0)
.setRho(1.0)
.endStep()
.beginStep()
.setR(1.0)
.setX(2.0)
.setG(3.0)
.setB(4.0)
.setAlpha(5.0)
.setRho(6.0)
.endStep()
.add();
assertEquals(2, phaseTapChanger.getStepCount());
assertEquals(2, phaseTapChanger.getAllSteps().size());
assertEquals(0, phaseTapChanger.getLowTapPosition());
assertEquals(1, phaseTapChanger.getHighTapPosition());
assertEquals(0, phaseTapChanger.getNeutralPosition().orElseThrow());
//check neutral step attributes
PhaseTapChangerStep neutralStep = phaseTapChanger.getNeutralStep().orElseThrow();
assertEquals(0, neutralStep.getAlpha(), 0.0);
assertEquals(1, neutralStep.getRho(), 0.0);
assertEquals(1, neutralStep.getR(), 0.0);
assertEquals(2, neutralStep.getX(), 0.0);
assertEquals(3, neutralStep.getG(), 0.0);
assertEquals(4, neutralStep.getB(), 0.0);
//replace steps
phaseTapChanger.stepsReplacer()
.beginStep()
.setR(1.0)
.setX(2.0)
.setG(3.0)
.setB(4.0)
.setAlpha(5.0)
.setRho(6.0)
.endStep()
.beginStep()
.setR(5.0)
.setX(6.0)
.setG(7.0)
.setB(8.0)
.setAlpha(6.0)
.setRho(7.0)
.endStep()
.beginStep()
.setR(9.0)
.setX(10.0)
.setG(11.0)
.setB(12.0)
.setAlpha(0.0)
.setRho(1.0)
.endStep()
.replaceSteps();
assertEquals(3, phaseTapChanger.getStepCount());
assertEquals(3, phaseTapChanger.getAllSteps().size());
assertEquals(0, phaseTapChanger.getLowTapPosition());
assertEquals(2, phaseTapChanger.getHighTapPosition());
assertEquals(2, phaseTapChanger.getNeutralPosition().orElseThrow());
//check neutral step attributes
neutralStep = phaseTapChanger.getNeutralStep().orElseThrow();
assertEquals(0, neutralStep.getAlpha(), 0.0);
assertEquals(1, neutralStep.getRho(), 0.0);
assertEquals(9, neutralStep.getR(), 0.0);
assertEquals(10, neutralStep.getX(), 0.0);
assertEquals(11, neutralStep.getG(), 0.0);
assertEquals(12, neutralStep.getB(), 0.0);
}
@Test
public void invalidTapPositionPhase() {
ValidationException e = assertThrows(ValidationException.class, () -> createPhaseTapChangerWith2Steps(3, 0, false,
PhaseTapChanger.RegulationMode.FIXED_TAP, 1.0, 1.0, terminal));
assertTrue(e.getMessage().contains("incorrect tap position"));
}
@Test
public void invalidNullModePhase() {
ValidationException e = assertThrows(ValidationException.class, () -> createPhaseTapChangerWith2Steps(1, 0, true,
null, 1.0, 1.0, terminal));
assertTrue(e.getMessage().contains("phase regulation mode is not set"));
}
@Test
public void invalidRegulatingValuePhase() {
ValidationException e = assertThrows(ValidationException.class, () -> createPhaseTapChangerWith2Steps(1, 0, true,
PhaseTapChanger.RegulationMode.ACTIVE_POWER_CONTROL, Double.NaN, 1.0, terminal));
assertTrue(e.getMessage().contains("phase regulation is on and threshold/setpoint value is not set"));
}
@Test
public void invalidNullRegulatingTerminalPhase() {
ValidationException e = assertThrows(ValidationException.class, () -> createPhaseTapChangerWith2Steps(1, 0, true,
PhaseTapChanger.RegulationMode.ACTIVE_POWER_CONTROL, 1.0, 1.0, null));
assertTrue(e.getMessage().contains("phase regulation is on and regulated terminal is not set"));
}
@Test
public void invalidModePhase() {
ValidationException e = assertThrows(ValidationException.class, () -> createPhaseTapChangerWith2Steps(1, 0, true,
PhaseTapChanger.RegulationMode.FIXED_TAP, 1.0, 1.0, terminal));
assertTrue(e.getMessage().contains("phase regulation cannot be on if mode is FIXED"));
}
@Test
public void invalidTargetDeadbandPtc() {
ValidationException e = assertThrows(ValidationException.class, () -> createPhaseTapChangerWith2Steps(1, 0, false,
PhaseTapChanger.RegulationMode.FIXED_TAP, 1.0, -1.0, terminal));
assertTrue(e.getMessage().contains("2 windings transformer 'twt': Unexpected value for target deadband of phase tap changer: -1.0"));
}
@Test
public void testTapChangerSetterGetterInMultiVariants() {
VariantManager variantManager = network.getVariantManager();
createPhaseTapChangerWith2Steps(1, 0, false,
PhaseTapChanger.RegulationMode.ACTIVE_POWER_CONTROL, 1.0, 1.0, terminal);
createRatioTapChangerWith3Steps(0, 1, true, true, 10.0, 1.0, terminal);
createThreeWindingTransformer();
ThreeWindingsTransformer threeWindingsTransformer = network.getThreeWindingsTransformer("twt2");
ThreeWindingsTransformer.Leg leg2 = threeWindingsTransformer.getLeg2();
ThreeWindingsTransformer.Leg leg3 = threeWindingsTransformer.getLeg3();
PhaseTapChanger phaseTapChanger = twt.getPhaseTapChanger();
RatioTapChanger ratioTapChanger = twt.getRatioTapChanger();
RatioTapChanger ratioTapChangerInLeg2 = leg2.getRatioTapChanger();
RatioTapChanger ratioTapChangerInLeg3 = leg3.getRatioTapChanger();
List<String> variantsToAdd = Arrays.asList("s1", "s2", "s3", "s4");
variantManager.cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, variantsToAdd);
variantManager.setWorkingVariant("s4");
// check values cloned by extend
assertKnownState(phaseTapChanger, ratioTapChanger, ratioTapChangerInLeg2, ratioTapChangerInLeg3);
// change values in s4
phaseTapChanger.setTapPosition(0);
phaseTapChanger.setRegulating(false);
phaseTapChanger.setRegulationValue(9.9);
ratioTapChanger.setTapPosition(0);
ratioTapChanger.setRegulating(false);
ratioTapChanger.setRegulationMode(RatioTapChanger.RegulationMode.VOLTAGE);
ratioTapChanger.setRegulationValue(3.5);
ratioTapChangerInLeg2.setTapPosition(2);
ratioTapChangerInLeg2.setRegulating(false);
ratioTapChangerInLeg2.setRegulationMode(RatioTapChanger.RegulationMode.REACTIVE_POWER);
ratioTapChangerInLeg2.setRegulationValue(31.5);
ratioTapChangerInLeg3.setTapPosition(4);
ratioTapChangerInLeg3.setRegulating(false);
ratioTapChangerInLeg3.setRegulationMode(RatioTapChanger.RegulationMode.VOLTAGE);
ratioTapChangerInLeg3.setRegulationValue(13.5);
// remove s2
variantManager.removeVariant("s2");
variantManager.cloneVariant("s4", "s2b");
variantManager.setWorkingVariant("s2b");
// check values cloned by allocate
assertEquals(0, phaseTapChanger.getTapPosition());
assertFalse(phaseTapChanger.isRegulating());
assertEquals(9.9, phaseTapChanger.getRegulationValue(), 0.0);
assertEquals(0, ratioTapChanger.getTapPosition());
assertFalse(ratioTapChanger.isRegulating());
assertEquals(RatioTapChanger.RegulationMode.VOLTAGE, ratioTapChanger.getRegulationMode());
assertEquals(3.5, ratioTapChanger.getRegulationValue(), 0.0);
assertEquals(2, ratioTapChangerInLeg2.getTapPosition());
assertFalse(ratioTapChangerInLeg2.isRegulating());
assertEquals(RatioTapChanger.RegulationMode.REACTIVE_POWER, ratioTapChangerInLeg2.getRegulationMode());
assertEquals(31.5, ratioTapChangerInLeg2.getRegulationValue(), 0.0);
assertEquals(4, ratioTapChangerInLeg3.getTapPosition());
assertFalse(ratioTapChangerInLeg3.isRegulating());
assertEquals(RatioTapChanger.RegulationMode.VOLTAGE, ratioTapChangerInLeg3.getRegulationMode());
assertEquals(13.5, ratioTapChangerInLeg3.getRegulationValue(), 0.0);
// recheck initial variant value
variantManager.setWorkingVariant(VariantManagerConstants.INITIAL_VARIANT_ID);
assertKnownState(phaseTapChanger, ratioTapChanger, ratioTapChangerInLeg2, ratioTapChangerInLeg3);
// remove working variant s4
variantManager.setWorkingVariant("s4");
variantManager.removeVariant("s4");
getTapPositionThrowsException(phaseTapChanger);
getTapPositionThrowsException(ratioTapChanger);
getTapPositionThrowsException(ratioTapChangerInLeg2);
getTapPositionThrowsException(ratioTapChangerInLeg3);
// check we delete a single variant's values
variantManager.setWorkingVariant("s3");
assertEquals(1, phaseTapChanger.getTapPosition());
}
private void assertKnownState(PhaseTapChanger phaseTapChanger, RatioTapChanger ratioTapChanger,
RatioTapChanger ratioTapChangerInLeg2, RatioTapChanger ratioTapChangerInLeg3) {
assertEquals(1, phaseTapChanger.getTapPosition());
assertFalse(phaseTapChanger.isRegulating());
assertEquals(1.0, phaseTapChanger.getRegulationValue(), 0.0);
assertEquals(1, ratioTapChanger.getTapPosition());
assertTrue(ratioTapChanger.isRegulating());
assertEquals(10.0, ratioTapChanger.getRegulationValue(), 0.0);
assertEquals(1, ratioTapChangerInLeg2.getTapPosition());
assertTrue(ratioTapChangerInLeg2.isRegulating());
assertEquals(10.0, ratioTapChangerInLeg2.getRegulationValue(), 0.0);
assertEquals(3, ratioTapChangerInLeg3.getTapPosition());
assertFalse(ratioTapChangerInLeg3.isRegulating());
assertEquals(11.0, ratioTapChangerInLeg3.getRegulationValue(), 0.0);
}
private void getTapPositionThrowsException(TapChanger<?, ?, ?, ?> tapChanger) {
try {
tapChanger.getTapPosition();
fail();
} catch (Exception ignored) {
// ignore
}
}
private void createPhaseTapChangerWith2Steps(int tapPosition, int lowTap, boolean isRegulating,
PhaseTapChanger.RegulationMode mode, double value, double deadband,
Terminal terminal) {
twt.newPhaseTapChanger()
.setTapPosition(tapPosition)
.setLowTapPosition(lowTap)
.setRegulating(isRegulating)
.setRegulationMode(mode)
.setRegulationValue(value)
.setTargetDeadband(deadband)
.setRegulationTerminal(terminal)
.beginStep()
.setR(1.0)
.setX(2.0)
.setG(3.0)
.setB(4.0)
.setAlpha(5.0)
.setRho(6.0)
.endStep()
.beginStep()
.setR(1.0)
.setX(2.0)
.setG(3.0)
.setB(4.0)
.setAlpha(5.0)
.setRho(6.0)
.endStep()
.add();
}
@Test
public void invalidPhaseTapChangerWithoutSteps() {
PhaseTapChangerAdder phaseTapChangerAdder = twt.newPhaseTapChanger()
.setTapPosition(1)
.setLowTapPosition(0)
.setRegulating(true)
.setRegulationMode(PhaseTapChanger.RegulationMode.ACTIVE_POWER_CONTROL)
.setRegulationValue(10.0)
.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
public void baseTestsRatioTapChanger() {
// adder
RatioTapChanger ratioTapChanger = twt.newRatioTapChanger()
.setLowTapPosition(0)
.setTapPosition(1)
.setLoadTapChangingCapabilities(false)
.setRegulating(true)
.setTargetDeadband(1.0)
.setRegulationMode(RatioTapChanger.RegulationMode.VOLTAGE)
.setRegulationValue(220.0)
.setRegulationTerminal(twt.getTerminal1())
.beginStep()
.setR(39.78473)
.setX(39.784725)
.setG(0.0)
.setB(0.0)
.setRho(0.9)
.endStep()
.beginStep()
.setR(39.78474)
.setX(39.784726)
.setG(0.0)
.setB(0.0)
.setRho(1.0)
.endStep()
.beginStep()
.setR(39.78475)
.setX(39.784727)
.setG(0.0)
.setB(0.0)
.setRho(1.1)
.endStep()
.add();
assertEquals(1, ratioTapChanger.getTapPosition());
assertEquals(3, ratioTapChanger.getAllSteps().size());
assertFalse(ratioTapChanger.hasLoadTapChangingCapabilities());
assertTrue(ratioTapChanger.isRegulating());
assertEquals(1.0, ratioTapChanger.getTargetDeadband(), 0.0);
assertEquals(RatioTapChanger.RegulationMode.VOLTAGE, ratioTapChanger.getRegulationMode());
assertEquals(220.0, ratioTapChanger.getRegulationValue(), 0.0);
assertSame(twt.getTerminal1(), ratioTapChanger.getRegulationTerminal());
assertEquals(3, ratioTapChanger.getStepCount());
// setter getter
assertEquals(1, ratioTapChanger.getNeutralPosition().orElseThrow(IllegalStateException::new));
RatioTapChangerStep neutralStep = ratioTapChanger.getNeutralStep().orElseThrow(IllegalStateException::new);
assertEquals(39.78474, neutralStep.getR(), 0.0);
assertEquals(39.784726, neutralStep.getX(), 0.0);
assertEquals(0.0, neutralStep.getG(), 0.0);
assertEquals(0.0, neutralStep.getB(), 0.0);
assertEquals(1.0, neutralStep.getRho(), 0.0);
ratioTapChanger.setTapPosition(2);
assertEquals(2, ratioTapChanger.getTapPosition());
ratioTapChanger.setRegulationValue(110.0);
assertEquals(110.0, ratioTapChanger.getRegulationValue(), 0.0);
ratioTapChanger.setRegulationMode(RatioTapChanger.RegulationMode.REACTIVE_POWER);
assertEquals(RatioTapChanger.RegulationMode.REACTIVE_POWER, ratioTapChanger.getRegulationMode());
ratioTapChanger.setRegulationValue(-50.0);
assertEquals(-50.0, ratioTapChanger.getRegulationValue(), 0.0);
ratioTapChanger.setRegulating(false);
assertFalse(ratioTapChanger.isRegulating());
ratioTapChanger.setTargetDeadband(0.5);
assertEquals(0.5, ratioTapChanger.getTargetDeadband(), 0.0);
ratioTapChanger.setRegulationTerminal(twt.getTerminal2());
assertSame(twt.getTerminal2(), ratioTapChanger.getRegulationTerminal());
ratioTapChanger.setLoadTapChangingCapabilities(true);
assertTrue(ratioTapChanger.hasLoadTapChangingCapabilities());
try {
ratioTapChanger.setTargetDeadband(-1);
fail();
} catch (ValidationException ignored) {
// ignore
}
try {
ratioTapChanger.setTargetDeadband(Double.NaN);
ratioTapChanger.setRegulating(true);
fail();
} catch (ValidationException ignored) {
// ignore
}
// ratio tap changer step setter/getter
RatioTapChangerStep step = ratioTapChanger.getStep(0);
double stepR = 10.0;
double stepX = 20.0;
double stepG = 30.0;
double stepB = 40.0;
double stepRho = 50.0;
step.setR(stepR);
assertEquals(stepR, step.getR(), 0.0);
step.setX(stepX);
assertEquals(stepX, step.getX(), 0.0);
step.setG(stepG);
assertEquals(stepG, step.getG(), 0.0);
step.setB(stepB);
assertEquals(stepB, step.getB(), 0.0);
step.setRho(stepRho);
assertEquals(stepRho, step.getRho(), 0.0);
// remove
ratioTapChanger.remove();
assertNull(twt.getRatioTapChanger());
}
@Test
public void testDefaultRatioTapChangerStep() {
RatioTapChanger ratioTapChanger = twt.newRatioTapChanger()
.setLowTapPosition(0)
.setTapPosition(0)
.setLoadTapChangingCapabilities(false)
.setRegulating(true)
.setTargetDeadband(1.0)
.setRegulationMode(RatioTapChanger.RegulationMode.VOLTAGE)
.setRegulationValue(220.0)
.setRegulationTerminal(twt.getTerminal1())
.beginStep()
.setRho(0.9)
.endStep()
.add();
RatioTapChangerStep step = ratioTapChanger.getStep(0);
assertEquals(0.0, step.getR(), 0.0);
assertEquals(0.0, step.getX(), 0.0);
assertEquals(0.0, step.getG(), 0.0);
assertEquals(0.0, step.getB(), 0.0);
}
@Test
public void testRatioTapChangerStepsReplacer() {
RatioTapChanger ratioTapChanger = twt.newRatioTapChanger()
.setTapPosition(1)
.setLowTapPosition(0)
.setRegulating(true)
.setTargetDeadband(1.0)
.setRegulationMode(RatioTapChanger.RegulationMode.REACTIVE_POWER)
.setRegulationValue(10.0)
.setRegulationTerminal(terminal)
.beginStep()
.setR(1.0)
.setX(2.0)
.setG(3.0)
.setB(4.0)
.setRho(1.0)
.endStep()
.beginStep()
.setR(1.0)
.setX(2.0)
.setG(3.0)
.setB(4.0)
.setRho(6.0)
.endStep()
.add();
assertEquals(2, ratioTapChanger.getStepCount());
assertEquals(2, ratioTapChanger.getAllSteps().size());
assertEquals(0, ratioTapChanger.getLowTapPosition());
assertEquals(1, ratioTapChanger.getHighTapPosition());
assertEquals(0, ratioTapChanger.getNeutralPosition().orElseThrow());
//check neutral step attributes
RatioTapChangerStep neutralStep = ratioTapChanger.getNeutralStep().orElseThrow();
assertEquals(1, neutralStep.getRho());
assertEquals(1, neutralStep.getR());
assertEquals(2, neutralStep.getX());
assertEquals(3, neutralStep.getG());
assertEquals(4, neutralStep.getB());
//replace steps
ratioTapChanger.stepsReplacer()
.beginStep()
.setR(1.0)
.setX(2.0)
.setG(3.0)
.setB(4.0)
.setRho(6.0)
.endStep()
.beginStep()
.setR(5.0)
.setX(6.0)
.setG(7.0)
.setB(8.0)
.setRho(7.0)
.endStep()
.beginStep()
.setR(9.0)
.setX(10.0)
.setG(11.0)
.setB(12.0)
.setRho(1.0)
.endStep()
.replaceSteps();
assertEquals(3, ratioTapChanger.getStepCount());
assertEquals(3, ratioTapChanger.getAllSteps().size());
assertEquals(0, ratioTapChanger.getLowTapPosition());
assertEquals(2, ratioTapChanger.getHighTapPosition());
assertEquals(2, ratioTapChanger.getNeutralPosition().orElseThrow());
//check neutral step attributes
neutralStep = ratioTapChanger.getNeutralStep().orElseThrow();
assertEquals(1, neutralStep.getRho());
assertEquals(9, neutralStep.getR());
assertEquals(10, neutralStep.getX());
assertEquals(11, neutralStep.getG());
assertEquals(12, neutralStep.getB());
}
@Test
public void invalidRatioTapChangerWithoutSteps() {
ValidationException e = assertThrows(ValidationException.class, () -> twt.newRatioTapChanger()
.setLowTapPosition(0)
.setTapPosition(1)
.setLoadTapChangingCapabilities(false)
.setRegulating(true)
.setRegulationMode(RatioTapChanger.RegulationMode.VOLTAGE)
.setRegulationValue(220.0)
.setRegulationTerminal(twt.getTerminal1())
.add());
assertTrue(e.getMessage().contains("ratio tap changer should have at least one step"));
}
@Test
public void invalidTapPosition() {
ValidationException e = assertThrows(ValidationException.class, () -> createRatioTapChangerWith3Steps(0, 4, true, false, 10.0, 1.0, terminal));
assertTrue(e.getMessage().contains("incorrect tap position"));
}
@Test
public void undefinedRegulationValue() {
ValidationException e = assertThrows(ValidationException.class, () -> createRatioTapChangerWith3Steps(0, 1, true, true, Double.NaN, 1.0, terminal));
assertTrue(e.getMessage().contains("a regulation value has to be set for a regulating ratio tap changer"));
ValidationException e2 = assertThrows(ValidationException.class, () -> createRatioTapChangerWith3Steps(0, 1, true, true, RatioTapChanger.RegulationMode.REACTIVE_POWER, Double.NaN, 1.0, terminal));
assertTrue(e2.getMessage().contains("a regulation value has to be set for a regulating ratio tap changer"));
}
@Test
public void undefinedRegulationValueOnlyWarning() {
createRatioTapChangerWith3Steps(0, 1, false, true, Double.NaN, 1.0, terminal);
RatioTapChanger rtc = twt.getRatioTapChanger();
assertNotNull(rtc);
assertFalse(rtc.hasLoadTapChangingCapabilities());
assertTrue(rtc.isRegulating());
assertEquals(RatioTapChanger.RegulationMode.VOLTAGE, rtc.getRegulationMode());
assertTrue(Double.isNaN(rtc.getRegulationValue()));
createRatioTapChangerWith3Steps(0, 1, false, true, RatioTapChanger.RegulationMode.REACTIVE_POWER, Double.NaN, 1.0, terminal);
rtc = twt.getRatioTapChanger();
assertNotNull(rtc);
assertFalse(rtc.hasLoadTapChangingCapabilities());
assertTrue(rtc.isRegulating());
assertEquals(RatioTapChanger.RegulationMode.REACTIVE_POWER, rtc.getRegulationMode());
assertTrue(Double.isNaN(rtc.getRegulationValue()));
}
@Test
public void invalidNullModeRatio() {
ValidationException e = assertThrows(ValidationException.class, () -> createRatioTapChangerWith3Steps(0, 1, true, true, null, 10.0, 1.0, terminal));
assertTrue(e.getMessage().contains("regulation mode of regulating ratio tap changer must be given"));
}
@Test
public void negativeTargetV() {
ValidationException e = assertThrows(ValidationException.class, () -> createRatioTapChangerWith3Steps(0, 1, true, true, -10.0, 1.0, terminal));
assertTrue(e.getMessage().contains("bad target voltage"));
}
@Test
public void targetVGettingInReactivePowerMode() {
createRatioTapChangerWith3Steps(0, 1, false, true, RatioTapChanger.RegulationMode.REACTIVE_POWER, -50, 1.0, terminal);
RatioTapChanger rtc = twt.getRatioTapChanger();
// getTargetV NaN because RTC is in reactive power control mode
assertTrue(Double.isNaN(rtc.getTargetV()));
}
@Test
public void targetVSetting() {
createRatioTapChangerWith3Steps(0, 1, false, true, RatioTapChanger.RegulationMode.REACTIVE_POWER, -50, 1.0, terminal);
RatioTapChanger rtc = twt.getRatioTapChanger();
assertDoesNotThrow(() -> rtc.setTargetV(130));
// setTargetV switched RTC to voltage control mode
assertEquals(RatioTapChanger.RegulationMode.VOLTAGE, rtc.getRegulationMode());
assertEquals(130, rtc.getTargetV(), 0.0);
}
@Test
public void invalidTargetDeadbandRtc() {
ValidationException e = assertThrows(ValidationException.class, () -> createRatioTapChangerWith3Steps(0, 1, true, true, 10.0, -1.0, terminal));
assertTrue(e.getMessage().contains("2 windings transformer 'twt': Unexpected value for target deadband of ratio tap changer: -1.0"));
}
@Test
public void nullRegulatingTerminal() {
ValidationException e = assertThrows(ValidationException.class, () -> createRatioTapChangerWith3Steps(0, 1, true, true, 10.0, 1.0, null));
assertTrue(e.getMessage().contains("a regulation terminal has to be set for a regulating ratio tap changer"));
}
@Test
public void nullRegulatingTerminalOnlyWarning() {
createRatioTapChangerWith3Steps(0, 1, false, true, 10.0, 1.0, null);
RatioTapChanger rtc = twt.getRatioTapChanger();
assertNotNull(rtc);
assertFalse(rtc.hasLoadTapChangingCapabilities());
assertTrue(rtc.isRegulating());
assertNull(rtc.getRegulationTerminal());
}
private void createRatioTapChangerWith3Steps(int low, int tap, boolean load, boolean regulating,
double targetV, double deadband, Terminal terminal) {
createRatioTapChangerWith3Steps(low, tap, load, regulating, RatioTapChanger.RegulationMode.VOLTAGE, targetV, deadband, terminal);
}
private void createRatioTapChangerWith3Steps(int low, int tap, boolean load, boolean regulating,
RatioTapChanger.RegulationMode regulationMode,
double regulationValue, double deadband, Terminal terminal) {
twt.newRatioTapChanger()
.setLowTapPosition(low)
.setTapPosition(tap)
.setLoadTapChangingCapabilities(load)
.setRegulating(regulating)
.setRegulationMode(regulationMode)
.setRegulationValue(regulationValue)
.setTargetDeadband(deadband)
.setRegulationTerminal(terminal)
.beginStep()
.setR(39.78473)
.setX(39.784725)
.setG(0.0)
.setB(0.0)
.setRho(1.0)
.endStep()
.beginStep()
.setR(39.78474)
.setX(39.784726)
.setG(0.0)
.setB(0.0)
.setRho(1.0)
.endStep()
.beginStep()
.setR(39.78475)
.setX(39.784727)
.setG(0.0)
.setB(0.0)
.setRho(1.0)
.endStep()
.add();
}
private void createThreeWindingTransformer() {
substation.newThreeWindingsTransformer()
.setId("twt2")
.setName("twtName")
.newLeg1()
.setR(1.3)
.setX(1.4)
.setG(1.6)
.setB(1.7)
.setRatedU(1.1)
.setVoltageLevel("vl1")
.setConnectableBus("busA")
.setBus("busA")
.add()
.newLeg2()
.setR(2.03)
.setX(2.04)
.setG(0.0)
.setB(0.0)
.setRatedU(2.05)
.setVoltageLevel("vl2")
.setConnectableBus("busB")
.add()
.newLeg3()
.setR(3.3)
.setX(3.4)
.setG(0.0)
.setB(0.0)
.setRatedU(3.5)
.setVoltageLevel("vl2")
.setConnectableBus("busB")
.add()
.add();
ThreeWindingsTransformer threeWindingsTransformer = network.getThreeWindingsTransformer("twt2");
ThreeWindingsTransformer.Leg leg2 = threeWindingsTransformer.getLeg2();
ThreeWindingsTransformer.Leg leg3 = threeWindingsTransformer.getLeg3();
leg2.newRatioTapChanger()
.setRegulationMode(RatioTapChanger.RegulationMode.VOLTAGE)
.setRegulationValue(10.0)
.setTargetDeadband(0)
.setLoadTapChangingCapabilities(false)
.setLowTapPosition(0)
.setTapPosition(1)
.setRegulating(true)
.setRegulationTerminal(threeWindingsTransformer.getTerminal(ThreeSides.TWO))
.beginStep()
.setR(39.78473)
.setX(39.784725)
.setG(0.0)
.setB(0.0)
.setRho(1.0)
.endStep()
.beginStep()
.setR(39.78474)
.setX(39.784726)
.setG(0.0)
.setB(0.0)
.setRho(1.0)
.endStep()
.beginStep()
.setR(39.78475)
.setX(39.784727)
.setG(0.0)
.setB(0.0)
.setRho(1.0)
.endStep()
.add();
leg3.newRatioTapChanger()
.setRegulationMode(RatioTapChanger.RegulationMode.VOLTAGE)
.setRegulationValue(11.0)
.setLoadTapChangingCapabilities(false)
.setLowTapPosition(2)
.setTapPosition(3)
.setRegulating(false)
.setRegulationTerminal(threeWindingsTransformer.getTerminal(ThreeSides.TWO))
.beginStep()
.setR(39.78473)
.setX(39.784725)
.setG(0.0)
.setB(0.0)
.setRho(1.0)
.endStep()
.beginStep()
.setR(39.78474)
.setX(39.784726)
.setG(0.0)
.setB(0.0)
.setRho(1.0)
.endStep()
.beginStep()
.setR(39.78475)
.setX(39.784727)
.setG(0.0)
.setB(0.0)
.setRho(1.0)
.endStep()
.add();
}
}