StackScalableTest.java
/**
* 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.iidm.modification.scalable;
import com.powsybl.commons.report.PowsyblCoreReportResourceBundle;
import com.powsybl.commons.test.PowsyblCoreTestReportResourceBundle;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.iidm.network.Generator;
import com.powsybl.iidm.network.Injection;
import com.powsybl.iidm.network.Network;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import static com.powsybl.iidm.modification.scalable.ScalableTestNetwork.createNetworkwithDanglingLineAndBattery;
import static com.powsybl.iidm.modification.scalable.ScalingParameters.Priority.ONESHOT;
import static com.powsybl.iidm.modification.scalable.ScalingParameters.Priority.RESPECT_OF_VOLUME_ASKED;
import static com.powsybl.iidm.modification.scalable.ScalingParameters.ScalingType.DELTA_P;
import static com.powsybl.iidm.modification.scalable.ScalingParameters.ScalingType.TARGET_P;
import static com.powsybl.iidm.modification.util.ModificationReports.scalingReport;
import static org.junit.jupiter.api.Assertions.assertEquals;
class StackScalableTest {
private Network network;
private Scalable g1;
private Scalable g2;
private Scalable g3;
private Scalable l1;
private Scalable l2;
private Scalable l3;
private Scalable s;
private Scalable unknownGenerator;
private Scalable unknownLoad;
private Scalable unknownDanglingLine;
private Scalable dl1;
@BeforeEach
void setUp() {
network = createNetworkwithDanglingLineAndBattery();
g1 = Scalable.onGenerator("g1"); //initial targetP : 80MW
g2 = Scalable.onGenerator("g2"); //initial targetP : 50MW
g3 = Scalable.onGenerator("g3", -10, 80); //initial targetP : 30MW
s = Scalable.onGenerator("s"); //initial targetP : 0MW
unknownGenerator = Scalable.onGenerator("unknown");
l1 = Scalable.onLoad("l1"); //initial P0 : 100MW
l2 = Scalable.onLoad("l2", 20, 80); //initial P0 : 80MW
l3 = Scalable.onLoad("l3", -50, 100); //initial P0 : 50MW
unknownLoad = Scalable.onLoad("unknown");
unknownDanglingLine = Scalable.onDanglingLine("unknown");
dl1 = Scalable.onDanglingLine("dl1", 20, 80); //initial P0 : 50MW
}
private void reset() {
Scalable.stack(g1, g2, g3).reset(network);
Scalable.stack(l1, l2, s, unknownGenerator, unknownLoad, unknownDanglingLine, dl1).reset(network);
l3.reset(network);
}
@Test
void testScaleOnGeneratorsStackingUp() {
ReportNode reportNode = ReportNode.newRootReportNode()
.withResourceBundles(PowsyblCoreTestReportResourceBundle.TEST_BASE_NAME, PowsyblCoreReportResourceBundle.BASE_NAME)
.withMessageTemplate("scaling")
.build();
List<Generator> generatorList = Arrays.asList(network.getGenerator("g1"), network.getGenerator("g2"), network.getGenerator("g3"));
ScalingParameters scalingParameters = new ScalingParameters(Scalable.ScalingConvention.GENERATOR,
true, true, ONESHOT, true, DELTA_P);
// Proportional to Target P
StackScalable stackScalable = Scalable.stack(generatorList);
double variationDone = stackScalable.scale(network, 100.0, scalingParameters);
scalingReport(reportNode,
"generators",
"STACKING",
scalingParameters.getScalingType(),
100.0, variationDone);
assertEquals(100.0, variationDone, 1e-5);
assertEquals(150.0, network.getGenerator("g1").getTargetP(), 1e-5);
assertEquals(80.0, network.getGenerator("g2").getTargetP(), 1e-5);
assertEquals(30.0, network.getGenerator("g3").getTargetP(), 1e-5);
reset();
}
@Test
void testScaleOnGeneratorsStackingTargetPMoreThanCurrent() {
ReportNode reportNode = ReportNode.newRootReportNode()
.withResourceBundles(PowsyblCoreTestReportResourceBundle.TEST_BASE_NAME, PowsyblCoreReportResourceBundle.BASE_NAME)
.withMessageTemplate("scaling")
.build();
List<Generator> generatorList = Arrays.asList(network.getGenerator("g1"), network.getGenerator("g2"), network.getGenerator("g3"));
ScalingParameters scalingParameters = new ScalingParameters(Scalable.ScalingConvention.GENERATOR,
true, true, ONESHOT, true, TARGET_P);
// Proportional to Target P
StackScalable stackScalable = Scalable.stack(generatorList);
double variationDone = stackScalable.scale(network, 300.0, scalingParameters);
scalingReport(reportNode,
"generators",
"STACKING",
scalingParameters.getScalingType(),
300.0, variationDone);
assertEquals(140.0, variationDone, 1e-5);
assertEquals(150.0, network.getGenerator("g1").getTargetP(), 1e-5);
assertEquals(100.0, network.getGenerator("g2").getTargetP(), 1e-5);
assertEquals(50.0, network.getGenerator("g3").getTargetP(), 1e-5);
reset();
}
@Test
void testScaleOnGeneratorsStackingTargetPLessThanCurrent() {
ReportNode reportNode = ReportNode.newRootReportNode()
.withResourceBundles(PowsyblCoreTestReportResourceBundle.TEST_BASE_NAME, PowsyblCoreReportResourceBundle.BASE_NAME)
.withMessageTemplate("scaling")
.build();
List<Generator> generatorList = Arrays.asList(network.getGenerator("g1"), network.getGenerator("g2"), network.getGenerator("g3"));
ScalingParameters scalingParameters = new ScalingParameters(Scalable.ScalingConvention.GENERATOR,
true, true, ONESHOT, true, TARGET_P);
// Proportional to Target P
StackScalable stackScalable = Scalable.stack(generatorList);
double variationDone = stackScalable.scale(network, 100.0, scalingParameters);
scalingReport(reportNode,
"generators",
"STACKING",
scalingParameters.getScalingType(),
100.0, variationDone);
assertEquals(-60.0, variationDone, 1e-5);
assertEquals(20.0, network.getGenerator("g1").getTargetP(), 1e-5);
assertEquals(50.0, network.getGenerator("g2").getTargetP(), 1e-5);
assertEquals(30.0, network.getGenerator("g3").getTargetP(), 1e-5);
reset();
}
@Test
void testMaxValueBoundsScalingUp() {
ReportNode reportNode = ReportNode.newRootReportNode()
.withResourceBundles(PowsyblCoreTestReportResourceBundle.TEST_BASE_NAME, PowsyblCoreReportResourceBundle.BASE_NAME)
.withMessageTemplate("scaling")
.build();
List<Generator> generatorList = Arrays.asList(network.getGenerator("g1"), network.getGenerator("g2"), network.getGenerator("g3"));
ScalingParameters scalingParameters = new ScalingParameters(Scalable.ScalingConvention.GENERATOR,
true, true, ONESHOT, true, DELTA_P);
double initialValue = generatorList.stream().mapToDouble(Generator::getTargetP).sum();
double maxValue = initialValue + 75.0;
// Proportional to Target P
StackScalable stackScalable = Scalable.stack(generatorList, -Double.MAX_VALUE, maxValue);
double variationDone = stackScalable.scale(network, 100.0, scalingParameters);
scalingReport(reportNode,
"generators",
"STACKING",
scalingParameters.getScalingType(),
100.0, variationDone);
assertEquals(75.0, variationDone, 1e-5);
assertEquals(150.0, network.getGenerator("g1").getTargetP(), 1e-5);
assertEquals(55.0, network.getGenerator("g2").getTargetP(), 1e-5);
assertEquals(30.0, network.getGenerator("g3").getTargetP(), 1e-5);
reset();
}
@Test
void testMinValueBoundsScalingDown() {
ReportNode reportNode = ReportNode.newRootReportNode()
.withResourceBundles(PowsyblCoreTestReportResourceBundle.TEST_BASE_NAME, PowsyblCoreReportResourceBundle.BASE_NAME)
.withMessageTemplate("scaling")
.build();
List<Generator> generatorList = Arrays.asList(network.getGenerator("g1"), network.getGenerator("g2"), network.getGenerator("g3"));
ScalingParameters scalingParameters = new ScalingParameters(Scalable.ScalingConvention.GENERATOR,
true, true, ONESHOT, true, DELTA_P);
double initialValue = generatorList.stream().mapToDouble(Generator::getTargetP).sum();
double minValue = initialValue - 75.0;
// Proportional to Target P
StackScalable stackScalable = Scalable.stack(generatorList, minValue, Double.MAX_VALUE);
double variationDone = stackScalable.scale(network, -100.0, scalingParameters);
scalingReport(reportNode,
"generators",
"STACKING",
scalingParameters.getScalingType(),
-100.0, variationDone);
assertEquals(-75.0, variationDone, 1e-5);
assertEquals(5.0, network.getGenerator("g1").getTargetP(), 1e-5);
assertEquals(50.0, network.getGenerator("g2").getTargetP(), 1e-5);
assertEquals(30.0, network.getGenerator("g3").getTargetP(), 1e-5);
reset();
}
@Test
void testDisableInjections() {
ReportNode reportNode = ReportNode.newRootReportNode()
.withResourceBundles(PowsyblCoreTestReportResourceBundle.TEST_BASE_NAME, PowsyblCoreReportResourceBundle.BASE_NAME)
.withMessageTemplate("scaling")
.build();
List<Injection<?>> injectionsList = Arrays.asList(
network.getGenerator("g1"), network.getGenerator("g2"),
network.getDanglingLine("dl1"),
network.getLoad("l1"), network.getLoad("l2"));
StackScalable stackScalable;
double variationDone;
// Stack scalable with scalables on l1, g1 and dl1 disabled, should saturate g2, and use part of l2
ScalingParameters scalingParameters = new ScalingParameters(Scalable.ScalingConvention.GENERATOR,
true, true, RESPECT_OF_VOLUME_ASKED, false, DELTA_P);
scalingParameters.setIgnoredInjectionIds(Set.of("l1", "g1", "dl1"));
stackScalable = Scalable.stack(injectionsList);
double volumeAsked = 100.;
variationDone = stackScalable.scale(network, volumeAsked, scalingParameters);
scalingReport(reportNode,
"generators, loads and dangling lines",
"STACKING",
scalingParameters.getScalingType(),
volumeAsked, variationDone);
assertEquals(volumeAsked, variationDone, 1e-5);
assertEquals(80.0, network.getGenerator("g1").getTargetP(), 1e-5); //skipped, initial P
assertEquals(100., network.getGenerator("g2").getTargetP(), 1e-5); //saturated, Pmax
assertEquals(50.0, network.getDanglingLine("dl1").getP0(), 1e-5); //skipped, initial P
assertEquals(100.0, network.getLoad("l1").getP0(), 1e-5); //skipped, initial P
assertEquals(80. - 50., network.getLoad("l2").getP0(), 1e-5); //remaining P on this scalable
reset();
}
}