AbstractLoadTest.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.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.test.FictitiousSwitchFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
public abstract class AbstractLoadTest {
private static final String TO_REMOVE = "toRemove";
Network network;
VoltageLevel voltageLevel;
@BeforeEach
public void initNetwork() {
network = FictitiousSwitchFactory.create();
voltageLevel = network.getVoltageLevel("C");
}
@Test
public void testSetterGetter() {
Load load = network.getLoad("CE");
load.setP0(-1.0);
assertEquals(-1.0, load.getP0(), 0.0);
load.setQ0(-2.0);
assertEquals(-2.0, load.getQ0(), 0.0);
load.setP0(1.0);
assertEquals(1.0, load.getP0(), 0.0);
load.setQ0(0.0);
assertEquals(0.0, load.getQ0(), 0.0);
load.setLoadType(LoadType.AUXILIARY);
assertEquals(LoadType.AUXILIARY, load.getLoadType());
}
@Test
public void invalidP0() {
ValidationException e = assertThrows(ValidationException.class, () -> createLoad("invalid", Double.NaN, 1.0));
assertTrue(e.getMessage().contains("p0 is invalid"));
}
@Test
public void invalidQ0() {
ValidationException e = assertThrows(ValidationException.class, () -> createLoad("invalid", 20.0, Double.NaN));
assertTrue(e.getMessage().contains("q0 is invalid"));
}
@Test
public void testChangesNotification() {
// Changes listener
NetworkListener mockedListener = Mockito.mock(DefaultNetworkListener.class);
// Add observer changes to current network
network.addListener(mockedListener);
// Tested instance
Load load = network.getLoad("CE");
// Get initial values
double p0OldValue = load.getP0();
double q0OldValue = load.getQ0();
// Change values P0 & Q0
load.setP0(-1.0);
load.setQ0(-2.0);
// Check update notification
Mockito.verify(mockedListener, Mockito.times(1))
.onUpdate(load, "p0", VariantManagerConstants.INITIAL_VARIANT_ID, p0OldValue, -1.0);
Mockito.verify(mockedListener, Mockito.times(1))
.onUpdate(load, "q0", VariantManagerConstants.INITIAL_VARIANT_ID, q0OldValue, -2.0);
// At this point
// no more changes is taking into account
// Simulate exception for onUpdate calls
Mockito.doThrow(new PowsyblException()).when(mockedListener)
.onUpdate(load, "p0", VariantManagerConstants.INITIAL_VARIANT_ID, p0OldValue, -1.0);
// Case when same values P0 & Q0 are set
load.setP0(-1.0);
load.setQ0(-2.0);
// Case when no listener is registered
network.removeListener(mockedListener);
load.setP0(1.0);
load.setQ0(0.0);
// Check no notification
Mockito.verifyNoMoreInteractions(mockedListener);
}
@Test
public void duplicateEquipment() {
voltageLevel.newLoad()
.setId("duplicate")
.setP0(2.0)
.setQ0(1.0)
.setNode(1)
.add();
PowsyblException e = assertThrows(PowsyblException.class, () -> createLoad("duplicate", 2.0, 1.0));
assertTrue(e.getMessage().contains("with the id 'duplicate'"));
}
@Test
public void duplicateId() {
// "C" id of voltageLevel
PowsyblException e = assertThrows(PowsyblException.class, () -> createLoad("C", 2.0, 1.0));
assertTrue(e.getMessage().contains("with the id 'C'"));
}
@Test
public void testAdder() {
Load load = voltageLevel.newLoad()
.setId("testAdder")
.setP0(2.0)
.setQ0(1.0)
.setLoadType(LoadType.AUXILIARY)
.setNode(1)
.add();
assertEquals(2.0, load.getP0(), 0.0);
assertEquals(1.0, load.getQ0(), 0.0);
assertEquals("testAdder", load.getId());
assertEquals(LoadType.AUXILIARY, load.getLoadType());
}
@Test
public void testRemove() {
createLoad(TO_REMOVE, 2.0, 1.0);
Load load = network.getLoad(TO_REMOVE);
int loadCount = network.getLoadCount();
assertNotNull(load);
load.remove();
assertNotNull(load);
assertNull(network.getLoad(TO_REMOVE));
assertEquals(loadCount - 1L, network.getLoadCount());
}
@Test
public void testSetterGetterInMultiVariants() {
// Changes listener
NetworkListener mockedListener = Mockito.mock(DefaultNetworkListener.class);
// Set observer changes
network.addListener(mockedListener);
// Init variant manager
VariantManager variantManager = network.getVariantManager();
createLoad("testMultiVariant", 0.6d, 0.7d);
Load load = network.getLoad("testMultiVariant");
List<String> variantsToAdd = Arrays.asList("s1", "s2", "s3", "s4");
variantManager.cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, variantsToAdd);
variantManager.setWorkingVariant("s4");
// check values cloned by extend
assertEquals(0.6d, load.getP0(), 0.0);
assertEquals(0.7d, load.getQ0(), 0.0);
// change values in s4
load.setP0(3.0);
load.setQ0(2.0);
// Check P0 & Q0 update notification
Mockito.verify(mockedListener, Mockito.times(1)).onUpdate(load, "p0", "s4", 0.6d, 3.0);
Mockito.verify(mockedListener, Mockito.times(1)).onUpdate(load, "q0", "s4", 0.7d, 2.0);
// remove s2
variantManager.removeVariant("s2");
variantManager.cloneVariant("s4", "s2b");
variantManager.setWorkingVariant("s2b");
// check values cloned by allocate
assertEquals(3.0, load.getP0(), 0.0);
assertEquals(2.0, load.getQ0(), 0.0);
// recheck initial variant value
variantManager.setWorkingVariant(VariantManagerConstants.INITIAL_VARIANT_ID);
assertEquals(0.6, load.getP0(), 0.0);
assertEquals(0.7, load.getQ0(), 0.0);
// remove working variant s4
variantManager.setWorkingVariant("s4");
variantManager.removeVariant("s4");
try {
load.getQ0();
fail();
} catch (Exception ignored) {
// ignore
}
// Remove observer changes
network.removeListener(mockedListener);
}
@Test
public void move() {
Load loadNbv = network.getLoad("CF");
// Moving to existing node (with no equipment)
loadNbv.getTerminal().getNodeBreakerView().moveConnectable(3, voltageLevel.getId());
assertEquals(3, loadNbv.getTerminal().getNodeBreakerView().getNode());
// Moving to existing node (with equipment)
Terminal.NodeBreakerView nbv0 = loadNbv.getTerminal().getNodeBreakerView();
try {
nbv0.moveConnectable(4, "C");
fail();
} catch (ValidationException e) {
assertEquals("Load 'CF': an equipment (CJ) is already connected to node 4 of voltage level C", e.getMessage());
}
// Moving to non existing node: node created
loadNbv.getTerminal().getNodeBreakerView().moveConnectable(6, voltageLevel.getId());
assertEquals(6, loadNbv.getTerminal().getNodeBreakerView().getNode());
// Moving to non-connected bus in bus breaker view
VoltageLevel vlBbv = network.newVoltageLevel()
.setId("vlBbv")
.setNominalV(45)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
Bus bbvBus0 = vlBbv.getBusBreakerView().newBus()
.setId("bbvBus0")
.add();
loadNbv.getTerminal().getBusBreakerView().moveConnectable(bbvBus0.getId(), false);
assertNull(loadNbv.getTerminal().getBusBreakerView().getBus());
assertEquals(bbvBus0, loadNbv.getTerminal().getBusBreakerView().getConnectableBus());
// Moving to connected bus in bus breaker view
Bus bbvBus1 = vlBbv.getBusBreakerView().newBus()
.setId("bbvBus1")
.add();
loadNbv.getTerminal().getBusBreakerView().moveConnectable(bbvBus1.getId(), true);
assertEquals(bbvBus1, loadNbv.getTerminal().getBusBreakerView().getBus());
assertEquals(bbvBus1, loadNbv.getTerminal().getBusBreakerView().getConnectableBus());
// Moving to unknown bus in bus breaker view
Terminal.BusBreakerView bbv0 = loadNbv.getTerminal().getBusBreakerView();
try {
bbv0.moveConnectable("unknownBus", true);
fail();
} catch (PowsyblException e) {
assertEquals("Bus 'unknownBus' not found", e.getMessage());
}
// Moving load in bus breaker view to connected bus in bus breaker view
Load loadBbv = vlBbv.newLoad()
.setId("loadBbv")
.setP0(2.0)
.setQ0(1.0)
.setBus(bbvBus1.getId())
.add();
loadBbv.getTerminal().getBusBreakerView().moveConnectable(bbvBus1.getId(), true);
assertEquals(bbvBus1, loadBbv.getTerminal().getBusBreakerView().getBus());
assertEquals(bbvBus1, loadBbv.getTerminal().getBusBreakerView().getConnectableBus());
// Moving to (now existing & available) node
loadBbv.getTerminal().getNodeBreakerView().moveConnectable(6, voltageLevel.getId());
assertEquals(6, loadBbv.getTerminal().getNodeBreakerView().getNode());
// Moving to unknown voltage level
Terminal.NodeBreakerView nbv = loadBbv.getTerminal().getNodeBreakerView();
try {
nbv.moveConnectable(6, "unknownVl");
fail();
} catch (PowsyblException e) {
assertEquals("Voltage level 'unknownVl' not found", e.getMessage());
}
}
private void createLoad(String id, double p0, double q0) {
voltageLevel.newLoad()
.setId(id)
.setP0(p0)
.setQ0(q0)
.setNode(1)
.add();
}
@Test
public void removePropertyTest() {
Load load = network.getLoad("CE");
assertNotNull(load);
assertFalse(load.hasProperty("a"));
assertNull(load.getProperty("a"));
load.setProperty("a", "b");
assertTrue(load.hasProperty("a"));
assertNotNull(load.getProperty("a"));
assertEquals("b", load.getProperty("a"));
load.removeProperty("a");
assertFalse(load.hasProperty("a"));
assertNull(load.getProperty("a"));
}
@Test
public void setNameTest() {
NetworkListener mockedListener = Mockito.mock(DefaultNetworkListener.class);
network.addListener(mockedListener);
Load load = network.getLoad("CE");
assertNotNull(load);
assertTrue(load.getOptionalName().isEmpty());
load.setName("FOO");
assertEquals("FOO", load.getOptionalName().orElseThrow());
Mockito.verify(mockedListener, Mockito.times(1)).onUpdate(load, "name", null, null, "FOO");
}
@Test
public void testZipLoadModel() {
Load load = voltageLevel.newLoad()
.setId("newZipLoad")
.setP0(2.0)
.setQ0(1.0)
.setNode(1)
.newZipModel()
.setC0p(0.3)
.setC1p(0.5)
.setC2p(0.2)
.setC0q(0.1)
.setC1q(0.2)
.setC2q(0.7)
.add()
.add();
assertEquals(2.0, load.getP0(), 0.0);
assertEquals(1.0, load.getQ0(), 0.0);
ZipLoadModel loadModel = (ZipLoadModel) load.getModel().orElseThrow();
assertEquals(0.3, loadModel.getC0p(), 0);
assertEquals(0.5, loadModel.getC1p(), 0);
assertEquals(0.2, loadModel.getC2p(), 0);
assertEquals(0.1, loadModel.getC0q(), 0);
assertEquals(0.2, loadModel.getC1q(), 0);
assertEquals(0.7, loadModel.getC2q(), 0);
loadModel.setC0p(0.31);
loadModel.setC1p(0.51);
loadModel.setC2p(0.21);
loadModel.setC0q(0.11);
loadModel.setC1q(0.21);
loadModel.setC2q(0.71);
assertEquals(0.31, loadModel.getC0p(), 0);
assertEquals(0.51, loadModel.getC1p(), 0);
assertEquals(0.21, loadModel.getC2p(), 0);
assertEquals(0.11, loadModel.getC0q(), 0);
assertEquals(0.21, loadModel.getC1q(), 0);
assertEquals(0.71, loadModel.getC2q(), 0);
ValidationException e = assertThrows(ValidationException.class, () -> loadModel.setC0p(Double.NaN));
assertEquals("Load 'newZipLoad': Invalid zip load model coefficient: NaN", e.getMessage());
loadModel.setC0p(-0.3);
assertEquals(-0.3, loadModel.getC0p(), 0);
}
@Test
public void testExponentialLoadModel() {
Load load = voltageLevel.newLoad()
.setId("newZipLoad")
.setP0(2.0)
.setQ0(1.0)
.setNode(1)
.newExponentialModel()
.setNp(0.6)
.setNq(0.5)
.add()
.add();
assertEquals(2.0, load.getP0(), 0.0);
assertEquals(1.0, load.getQ0(), 0.0);
ExponentialLoadModel loadModel = (ExponentialLoadModel) load.getModel().orElseThrow();
assertEquals(0.6, loadModel.getNp(), 0);
assertEquals(0.5, loadModel.getNq(), 0);
loadModel.setNp(0.61);
loadModel.setNq(0.51);
assertEquals(0.61, loadModel.getNp(), 0);
assertEquals(0.51, loadModel.getNq(), 0);
ValidationException e = assertThrows(ValidationException.class, () -> loadModel.setNp(-2));
assertEquals("Load 'newZipLoad': Invalid load model exponential value: -2.0", e.getMessage());
}
}