AbstractSensitivityAnalysisTest.java
/**
* Copyright (c) 2020, 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.openloadflow.sensi;
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.commons.test.AbstractSerDeTest;
import com.powsybl.computation.local.LocalComputationManager;
import com.powsybl.contingency.BranchContingency;
import com.powsybl.contingency.Contingency;
import com.powsybl.contingency.ContingencyContext;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
import com.powsybl.loadflow.LoadFlow;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.loadflow.LoadFlowResult;
import com.powsybl.math.matrix.DenseMatrix;
import com.powsybl.math.matrix.DenseMatrixFactory;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowProvider;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.util.LoadFlowAssert;
import com.powsybl.sensitivity.*;
import java.util.*;
import java.util.concurrent.CompletionException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public abstract class AbstractSensitivityAnalysisTest extends AbstractSerDeTest {
protected static final double SENSI_CHANGE = 10e-4;
protected final DenseMatrixFactory matrixFactory = new DenseMatrixFactory();
protected final OpenSensitivityAnalysisProvider sensiProvider = new OpenSensitivityAnalysisProvider(matrixFactory);
protected final SensitivityAnalysis.Runner sensiRunner = new SensitivityAnalysis.Runner(sensiProvider);
protected final OpenLoadFlowProvider loadFlowProvider = new OpenLoadFlowProvider(matrixFactory);
protected final LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(loadFlowProvider);
protected static SensitivityAnalysisParameters createParameters(boolean dc, String slackBusId, boolean distributedSlack) {
return createParameters(dc, List.of(slackBusId), distributedSlack);
}
protected static SensitivityAnalysisParameters createParameters(boolean dc, List<String> slackBusesIds, boolean distributedSlack) {
SensitivityAnalysisParameters sensiParameters = new SensitivityAnalysisParameters();
LoadFlowParameters lfParameters = sensiParameters.getLoadFlowParameters();
lfParameters.setDc(dc)
.setDistributedSlack(distributedSlack);
OpenLoadFlowParameters.create(lfParameters)
.setSlackBusSelectionMode(SlackBusSelectionMode.NAME)
.setSlackBusesIds(slackBusesIds);
return sensiParameters;
}
protected static SensitivityAnalysisParameters createParameters(boolean dc, String slackBusId) {
return createParameters(dc, slackBusId, false);
}
protected static SensitivityAnalysisParameters createParameters(boolean dc) {
SensitivityAnalysisParameters sensiParameters = new SensitivityAnalysisParameters();
LoadFlowParameters lfParameters = sensiParameters.getLoadFlowParameters();
lfParameters.setDc(dc)
.setDistributedSlack(true);
OpenLoadFlowParameters.create(lfParameters)
.setSlackBusSelectionMode(SlackBusSelectionMode.MOST_MESHED);
return sensiParameters;
}
protected static <T extends Injection<T>> List<SensitivityFactor> createFactorMatrix(List<T> injections, List<Branch> branches, String contingencyId, TwoSides side) {
Objects.requireNonNull(injections);
Objects.requireNonNull(branches);
return injections.stream().flatMap(injection -> branches.stream().map(branch -> createBranchFlowPerInjectionIncrease(branch.getId(), injection.getId(), contingencyId, side))).collect(Collectors.toList());
}
protected static <T extends Injection<T>> List<SensitivityFactor> createFactorMatrix(List<T> injections, List<Branch> branches, TwoSides side) {
return createFactorMatrix(injections, branches, null, side);
}
protected static <T extends Injection<T>> List<SensitivityFactor> createFactorMatrix(List<T> injections, List<Branch> branches) {
return createFactorMatrix(injections, branches, null, TwoSides.ONE);
}
protected static <T extends Injection<T>> List<SensitivityFactor> createFactorMatrix(List<T> injections, List<Branch> branches, String contingencyId) {
return createFactorMatrix(injections, branches, contingencyId, TwoSides.ONE);
}
protected static SensitivityFactor createBranchFlowPerInjectionIncrease(String functionId, String variableId, String contingencyId) {
return createBranchFlowPerInjectionIncrease(functionId, variableId, contingencyId, TwoSides.ONE);
}
protected static SensitivityFactor createBranchFlowPerInjectionIncrease(String functionId, String variableId, String contingencyId, TwoSides side) {
SensitivityFunctionType ftype = side.equals(TwoSides.ONE) ? SensitivityFunctionType.BRANCH_ACTIVE_POWER_1 : SensitivityFunctionType.BRANCH_ACTIVE_POWER_2;
return new SensitivityFactor(ftype, functionId, SensitivityVariableType.INJECTION_ACTIVE_POWER, variableId, false, Objects.isNull(contingencyId) ? ContingencyContext.all() : ContingencyContext.specificContingency(contingencyId));
}
protected static SensitivityFactor createBranchFlowPerInjectionIncrease(String functionId, String variableId, TwoSides side) {
return createBranchFlowPerInjectionIncrease(functionId, variableId, null, side);
}
protected static SensitivityFactor createBranchFlowPerInjectionIncrease(String functionId, String variableId) {
return createBranchFlowPerInjectionIncrease(functionId, variableId, null, TwoSides.ONE);
}
protected static SensitivityFactor createBranchFlowPerLinearGlsk(String functionId, String variableId, String contingencyId, TwoSides side) {
return createBranchFlowPerLinearGlsk(functionId, variableId, Objects.isNull(contingencyId) ? ContingencyContext.all() : ContingencyContext.specificContingency(contingencyId), side);
}
protected static SensitivityFactor createBranchReactivePowerPerTargetV(String functionId, String variableId, String contingencyId, TwoSides side) {
SensitivityFunctionType ftype = side.equals(TwoSides.ONE) ? SensitivityFunctionType.BRANCH_REACTIVE_POWER_1 : SensitivityFunctionType.BRANCH_REACTIVE_POWER_2;
return new SensitivityFactor(ftype, functionId, SensitivityVariableType.BUS_TARGET_VOLTAGE, variableId, false, Objects.isNull(contingencyId) ? ContingencyContext.all() : ContingencyContext.specificContingency(contingencyId));
}
protected static SensitivityFactor createBranchReactivePowerPerTargetV(String functionId, String variableId, TwoSides side) {
return createBranchReactivePowerPerTargetV(functionId, variableId, null, side);
}
protected static SensitivityFactor createBranchReactivePowerPerTargetV(String functionId, String variableId) {
return createBranchReactivePowerPerTargetV(functionId, variableId, TwoSides.ONE);
}
protected static SensitivityFactor createBranchFlowPerLinearGlsk(String functionId, String variableId, ContingencyContext contingencyContext) {
return createBranchFlowPerLinearGlsk(functionId, variableId, contingencyContext, TwoSides.ONE);
}
protected static SensitivityFactor createBranchFlowPerLinearGlsk(String functionId, String variableId, String contingencyId) {
return createBranchFlowPerLinearGlsk(functionId, variableId, contingencyId, TwoSides.ONE);
}
protected static SensitivityFactor createBranchFlowPerLinearGlsk(String functionId, String variableId, ContingencyContext contingencyContext, TwoSides side) {
SensitivityFunctionType ftype = side.equals(TwoSides.ONE) ? SensitivityFunctionType.BRANCH_ACTIVE_POWER_1 : SensitivityFunctionType.BRANCH_ACTIVE_POWER_2;
return new SensitivityFactor(ftype, functionId, SensitivityVariableType.INJECTION_ACTIVE_POWER, variableId, true, contingencyContext);
}
protected static SensitivityFactor createBranchFlowPerLinearGlsk(String functionId, String variableId, TwoSides side) {
return createBranchFlowPerLinearGlsk(functionId, variableId, (String) null, side);
}
protected static SensitivityFactor createBranchFlowPerLinearGlsk(String functionId, String variableId) {
return createBranchFlowPerLinearGlsk(functionId, variableId, (String) null, TwoSides.ONE);
}
protected static SensitivityFactor createBranchFlowPerPSTAngle(String functionId, String variableId, String contingencyId) {
return createBranchFlowPerPSTAngle(functionId, variableId, contingencyId, TwoSides.ONE);
}
protected static SensitivityFactor createBranchFlowPerPSTAngle(String functionId, String variableId, String contingencyId, TwoSides side) {
SensitivityFunctionType ftype = side.equals(TwoSides.ONE) ? SensitivityFunctionType.BRANCH_ACTIVE_POWER_1 : SensitivityFunctionType.BRANCH_ACTIVE_POWER_2;
return new SensitivityFactor(ftype, functionId, SensitivityVariableType.TRANSFORMER_PHASE, variableId, false, Objects.isNull(contingencyId) ? ContingencyContext.all() : ContingencyContext.specificContingency(contingencyId));
}
protected static SensitivityFactor createBranchFlowPerPSTAngle(String functionId, String variableId, TwoSides side) {
return createBranchFlowPerPSTAngle(functionId, variableId, null, side);
}
protected static SensitivityFactor createBranchFlowPerTransformerLegPSTAngle(String functionId, String variableId, ThreeSides side) {
SensitivityVariableType fVariable = side.equals(ThreeSides.ONE) ? SensitivityVariableType.TRANSFORMER_PHASE_1
: side.equals(ThreeSides.TWO) ? SensitivityVariableType.TRANSFORMER_PHASE_2
: SensitivityVariableType.TRANSFORMER_PHASE_3;
return new SensitivityFactor(SensitivityFunctionType.BRANCH_ACTIVE_POWER_1, functionId, fVariable, variableId, false, ContingencyContext.all());
}
protected static SensitivityFactor createTransformerLegFlowPerInjectionIncrease(String functionId, String variableId, ThreeSides side) {
SensitivityFunctionType ftype = side.equals(ThreeSides.ONE) ? SensitivityFunctionType.BRANCH_ACTIVE_POWER_1
: side.equals(ThreeSides.TWO) ? SensitivityFunctionType.BRANCH_ACTIVE_POWER_2
: SensitivityFunctionType.BRANCH_ACTIVE_POWER_3;
return new SensitivityFactor(ftype, functionId, SensitivityVariableType.INJECTION_ACTIVE_POWER, variableId, false, ContingencyContext.all());
}
protected static SensitivityFactor createBranchFlowPerPSTAngle(String functionId, String variableId) {
return createBranchFlowPerPSTAngle(functionId, variableId, null, TwoSides.ONE);
}
protected static SensitivityFactor createBranchIntensityPerInjectionIncrease(String functionId, String variableId, TwoSides side) {
SensitivityFunctionType ftype = side.equals(TwoSides.ONE) ? SensitivityFunctionType.BRANCH_CURRENT_1 : SensitivityFunctionType.BRANCH_CURRENT_2;
return new SensitivityFactor(ftype, functionId, SensitivityVariableType.INJECTION_ACTIVE_POWER, variableId, false, ContingencyContext.all());
}
protected static SensitivityFactor createTransformerLegIntensityPerInjectionIncrease(String functionId, String variableId, ThreeSides side) {
SensitivityFunctionType ftype = side.equals(ThreeSides.ONE) ? SensitivityFunctionType.BRANCH_CURRENT_1
: side.equals(ThreeSides.TWO) ? SensitivityFunctionType.BRANCH_CURRENT_2
: SensitivityFunctionType.BRANCH_CURRENT_3;
return new SensitivityFactor(ftype, functionId, SensitivityVariableType.INJECTION_ACTIVE_POWER, variableId, false, ContingencyContext.all());
}
protected static SensitivityFactor createBranchIntensityPerInjectionIncrease(String functionId, String variableId) {
return createBranchIntensityPerInjectionIncrease(functionId, variableId, TwoSides.ONE);
}
protected static SensitivityFactor createBranchIntensityPerPSTAngle(String functionId, String variableId, TwoSides side) {
SensitivityFunctionType ftype = side.equals(TwoSides.ONE) ? SensitivityFunctionType.BRANCH_CURRENT_1 : SensitivityFunctionType.BRANCH_CURRENT_2;
return new SensitivityFactor(ftype, functionId, SensitivityVariableType.TRANSFORMER_PHASE, variableId, false, ContingencyContext.all());
}
protected static SensitivityFactor createBranchIntensityPerPSTAngle(String functionId, String variableId) {
return createBranchIntensityPerPSTAngle(functionId, variableId, TwoSides.ONE);
}
protected static SensitivityFactor createBusVoltagePerTargetQ(String functionId, String variableId, String contingencyId) {
return new SensitivityFactor(SensitivityFunctionType.BUS_VOLTAGE, functionId, SensitivityVariableType.INJECTION_REACTIVE_POWER, variableId, false, Objects.isNull(contingencyId) ? ContingencyContext.all() : ContingencyContext.specificContingency(contingencyId));
}
protected static SensitivityFactor createTargetQPerTargetV(String functionId, String variableId, String contingencyId) {
return new SensitivityFactor(SensitivityFunctionType.BUS_REACTIVE_POWER, functionId, SensitivityVariableType.BUS_TARGET_VOLTAGE, variableId, false, Objects.isNull(contingencyId) ? ContingencyContext.all() : ContingencyContext.specificContingency(contingencyId));
}
protected static SensitivityFactor createBusVoltagePerTargetV(String functionId, String variableId, String contingencyId) {
return new SensitivityFactor(SensitivityFunctionType.BUS_VOLTAGE, functionId, SensitivityVariableType.BUS_TARGET_VOLTAGE, variableId, false, Objects.isNull(contingencyId) ? ContingencyContext.all() : ContingencyContext.specificContingency(contingencyId));
}
protected static SensitivityFactor createBusVoltagePerTargetV(String functionId, String variableId) {
return createBusVoltagePerTargetV(functionId, variableId, null);
}
protected static SensitivityFactor createHvdcInjection(String functionId, String variableId, TwoSides side) {
SensitivityFunctionType ftype = side.equals(TwoSides.ONE) ? SensitivityFunctionType.BRANCH_ACTIVE_POWER_1 : SensitivityFunctionType.BRANCH_ACTIVE_POWER_2;
return new SensitivityFactor(ftype, functionId, SensitivityVariableType.HVDC_LINE_ACTIVE_POWER, variableId, false, ContingencyContext.all());
}
public static class SensitivityMatrix {
private static final double STEP_SIZE = 0.01;
private static final String TMP_VARIANT_ID = "sensi";
private final SensitivityFunctionType functionType;
private final List<? extends Identifiable<?>> functions;
private final SensitivityVariableType variableType;
private final List<? extends Identifiable<?>> variables;
public SensitivityMatrix(SensitivityFunctionType functionType, Stream<? extends Identifiable<?>> functions,
SensitivityVariableType variableType, Stream<? extends Identifiable<?>> variables) {
this.functionType = Objects.requireNonNull(functionType);
this.functions = Objects.requireNonNull(functions).sorted(Comparator.comparing(Identifiable::getId)).toList();
this.variableType = Objects.requireNonNull(variableType);
this.variables = Objects.requireNonNull(variables).sorted(Comparator.comparing(Identifiable::getId)).toList();
}
public List<SensitivityFactor> toFactors() {
List<SensitivityFactor> factors = new ArrayList<>();
for (var variable : variables) {
for (var function : functions) {
factors.add(new SensitivityFactor(functionType, function.getId(), variableType, variable.getId(),
false, ContingencyContext.all()));
}
}
return factors;
}
public DenseMatrix toResultMatrix(SensitivityAnalysisResult result) {
DenseMatrix matrix = new DenseMatrix(variables.size(), functions.size());
for (int i = 0; i < variables.size(); i++) {
var variable = variables.get(i);
for (int j = 0; j < functions.size(); j++) {
var function = functions.get(j);
matrix.set(i, j, result.getSensitivityValue(variable.getId(), function.getId(), functionType, variableType));
}
}
return matrix;
}
DenseMatrix calculateSensiWithLoadFlow(Network network, LoadFlow.Runner loadFlowRunner) {
DenseMatrix matrix = new DenseMatrix(variables.size(), functions.size());
for (int i = 0; i < variables.size(); i++) {
var variable = variables.get(i);
network.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, TMP_VARIANT_ID);
LoadFlowResult result = loadFlowRunner.run(network);
assertTrue(result.isFullyConverged());
calculateFunction(network, matrix, i, false);
switch (variableType) {
case INJECTION_REACTIVE_POWER -> {
var g = network.getGenerator(variable.getId());
if (g != null) {
g.setTargetQ(g.getTargetQ() + STEP_SIZE);
} else {
var l = network.getLoad(variable.getId());
if (l != null) {
l.setQ0(l.getQ0() - STEP_SIZE);
}
}
}
case BUS_TARGET_VOLTAGE -> {
var g = network.getGenerator(variable.getId());
g.setTargetV(g.getTargetV() + STEP_SIZE);
}
default -> throw new UnsupportedOperationException();
}
result = loadFlowRunner.run(network);
assertTrue(result.isFullyConverged());
calculateFunction(network, matrix, i, true);
network.getVariantManager().removeVariant(TMP_VARIANT_ID);
}
return matrix;
}
private void calculateFunction(Network network, DenseMatrix matrix, int i, boolean diff) {
for (int j = 0; j < functions.size(); j++) {
var function = functions.get(j);
double value = switch (functionType) {
case BUS_VOLTAGE -> {
Bus b = network.getBusBreakerView().getBus(function.getId());
yield b.getV();
}
case BRANCH_CURRENT_1 -> {
Line l = network.getLine(function.getId());
yield l.getTerminal1().getI();
}
case BUS_REACTIVE_POWER -> {
Bus b = network.getBusBreakerView().getBus(function.getId());
yield b.getQ();
}
default -> throw new UnsupportedOperationException();
};
if (diff) {
double oldValue = matrix.get(i, j);
matrix.set(i, j, (value - oldValue) / STEP_SIZE);
} else {
matrix.set(i, j, value);
}
}
}
}
protected static void assertMatricesEquals(DenseMatrix m1, DenseMatrix m2, double epsilon) {
assertEquals(m1.getRowCount(), m2.getRowCount());
assertEquals(m1.getColumnCount(), m2.getColumnCount());
for (int i = 0; i < m1.getRowCount(); i++) {
for (int j = 0; j < m1.getColumnCount(); j++) {
assertEquals(m1.get(i, j), m2.get(i, j), epsilon);
}
}
}
protected void runAcLf(Network network) {
runAcLf(network, ReportNode.NO_OP);
}
protected void runAcLf(Network network, ReportNode reportNode) {
LoadFlowParameters parameters = new LoadFlowParameters().setWriteSlackBus(false);
LoadFlowResult result = new OpenLoadFlowProvider(matrixFactory)
.run(network, LocalComputationManager.getDefault(), VariantManagerConstants.INITIAL_VARIANT_ID, parameters, reportNode)
.join();
if (!result.isFullyConverged()) {
throw new PowsyblException("AC LF diverged");
}
}
protected void runDcLf(Network network) {
runDcLf(network, ReportNode.NO_OP);
}
protected void runDcLf(Network network, ReportNode reportNode) {
LoadFlowParameters parameters = new LoadFlowParameters().setWriteSlackBus(false).setDc(true);
LoadFlowResult result = new OpenLoadFlowProvider(matrixFactory)
.run(network, LocalComputationManager.getDefault(), VariantManagerConstants.INITIAL_VARIANT_ID, parameters, reportNode)
.join();
if (!result.isFullyConverged()) {
throw new PowsyblException("DC LF failed");
}
}
protected void runLf(Network network, LoadFlowParameters loadFlowParameters) {
runLf(network, loadFlowParameters, ReportNode.NO_OP);
}
protected void runLf(Network network, LoadFlowParameters loadFlowParameters, ReportNode reportNode) {
LoadFlowResult result = new OpenLoadFlowProvider(matrixFactory)
.run(network, LocalComputationManager.getDefault(), VariantManagerConstants.INITIAL_VARIANT_ID, loadFlowParameters, reportNode)
.join();
if (!result.isFullyConverged()) {
throw new PowsyblException("LF failed");
}
}
protected void testInjectionNotFound(boolean dc) {
Network network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
runAcLf(network);
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "VLLOAD_0");
List<SensitivityFactor> factors = Collections.singletonList(createBranchFlowPerInjectionIncrease("NHV1_NHV2_1", "a"));
List<Contingency> contingencies = Collections.emptyList();
List<SensitivityVariableSet> variableSets = Collections.emptyList();
CompletionException e = assertThrows(CompletionException.class, () -> sensiRunner.run(network, factors, contingencies, variableSets, sensiParameters));
assertTrue(e.getCause() instanceof PowsyblException);
assertEquals("Injection 'a' not found", e.getCause().getMessage());
}
protected void testInjectionNotFoundAdditionalFactor(boolean dc) {
Network network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "VLLOAD_0");
List<SensitivityFactor> factors = Collections.singletonList(createBranchFlowPerInjectionIncrease("NHV1_NHV2_1", "a"));
List<Contingency> contingencies = Collections.emptyList();
List<SensitivityVariableSet> variableSets = Collections.emptyList();
CompletionException e = assertThrows(CompletionException.class, () -> sensiRunner.run(network, factors, contingencies, variableSets, sensiParameters));
assertTrue(e.getCause() instanceof PowsyblException);
assertEquals("Injection 'a' not found", e.getCause().getMessage());
}
protected void testInjectionNotFoundAdditionalFactorContingency(boolean dc) {
Network network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "VLLOAD_0");
List<SensitivityFactor> factors = List.of(createBranchFlowPerInjectionIncrease("NHV1_NHV2_1", "a"));
List<Contingency> contingencies = List.of(new Contingency("a", new BranchContingency("NHV1_NHV2_2")));
List<SensitivityVariableSet> variableSets = Collections.emptyList();
CompletionException e = assertThrows(CompletionException.class, () -> sensiRunner.run(network, factors, contingencies, variableSets, sensiParameters));
assertTrue(e.getCause() instanceof PowsyblException);
assertEquals("Injection 'a' not found", e.getCause().getMessage());
}
protected void testGlskInjectionNotFound(boolean dc) {
Network network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
runAcLf(network);
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "VLLOAD_0");
List<SensitivityFactor> factors = Collections.singletonList(createBranchFlowPerLinearGlsk("NHV1_NHV2_1", "glsk"));
List<Contingency> contingencies = Collections.emptyList();
List<SensitivityVariableSet> variableSets = Collections.singletonList(new SensitivityVariableSet("glsk", List.of(new WeightedSensitivityVariable("a", 10f))));
CompletionException e = assertThrows(CompletionException.class, () -> sensiRunner.run(network, factors, contingencies, variableSets, sensiParameters));
assertTrue(e.getCause() instanceof PowsyblException);
assertEquals("Injection 'a' not found", e.getCause().getMessage());
}
protected void testHvdcInjectionNotFound(boolean dc) {
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "b1_vl_0", true);
Network network = HvdcNetworkFactory.createTwoCcLinkedByAHvdcWithGenerators();
List<SensitivityFactor> factors = List.of(createHvdcInjection("l12", "nop", TwoSides.ONE));
List<Contingency> contingencies = Collections.emptyList();
List<SensitivityVariableSet> variableSets = Collections.emptyList();
CompletionException e = assertThrows(CompletionException.class, () -> sensiRunner.run(network, factors, contingencies, variableSets, sensiParameters));
assertTrue(e.getCause() instanceof PowsyblException);
assertEquals("HVDC line 'nop' cannot be found in the network.", e.getCause().getMessage());
}
protected void testBranchNotFound(boolean dc) {
Network network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
runAcLf(network);
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "VLLOAD_0");
List<SensitivityFactor> factors = List.of(createBranchFlowPerInjectionIncrease("b", "GEN"));
List<Contingency> contingencies = Collections.emptyList();
List<SensitivityVariableSet> variableSets = Collections.emptyList();
CompletionException e = assertThrows(CompletionException.class, () -> sensiRunner.run(network, factors, contingencies, variableSets, sensiParameters));
assertTrue(e.getCause() instanceof PowsyblException);
assertEquals("Branch, tie line, dangling line or leg of 'b' not found", e.getCause().getMessage());
}
protected void testEmptyFactors(boolean dc) {
Network network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
runAcLf(network);
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "VLLOAD_0");
List<SensitivityFactor> factors = Collections.emptyList();
SensitivityAnalysisResult result = sensiRunner.run(network, factors, Collections.emptyList(), Collections.emptyList(), sensiParameters);
assertTrue(result.getValues().isEmpty());
}
protected void testBranchFunctionOutsideMainComponent(boolean dc) {
Network network = HvdcNetworkFactory.createLccWithBiggerComponents();
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "vl1_0");
List<SensitivityFactor> factors = List.of(createBranchFlowPerInjectionIncrease("l56", "g1"));
SensitivityAnalysisResult result = sensiRunner.run(network, factors, Collections.emptyList(), Collections.emptyList(), sensiParameters);
assertEquals(1, result.getValues().size());
assertEquals(0d, result.getValues().iterator().next().getValue());
}
protected void testInjectionOutsideMainComponent(boolean dc) {
Network network = HvdcNetworkFactory.createLccWithBiggerComponents();
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "vl1_0");
List<SensitivityFactor> factors = List.of(createBranchFlowPerInjectionIncrease("l12", "g3"));
SensitivityAnalysisResult result = sensiRunner.run(network, factors, Collections.emptyList(), Collections.emptyList(), sensiParameters);
assertEquals(1, result.getValues().size());
assertEquals(0f, result.getBranchFlow1SensitivityValue("g3", "l12", SensitivityVariableType.INJECTION_ACTIVE_POWER), LoadFlowAssert.DELTA_POWER);
}
protected void testPhaseShifterOutsideMainComponent(boolean dc) {
Network network = HvdcNetworkFactory.createLccWithBiggerComponents();
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "vl1_0");
List<SensitivityFactor> factors = List.of(createBranchFlowPerPSTAngle("l12", "l45"));
SensitivityAnalysisResult result = sensiRunner.run(network, factors, Collections.emptyList(), Collections.emptyList(), sensiParameters);
assertEquals(1, result.getValues().size());
assertEquals(0d, result.getBranchFlow1SensitivityValue("l45", "l12", SensitivityVariableType.TRANSFORMER_PHASE), LoadFlowAssert.DELTA_POWER);
if (dc) {
assertEquals(100.00, result.getBranchFlow1FunctionReferenceValue("l12"), LoadFlowAssert.DELTA_POWER);
} else {
assertEquals(100.08, result.getBranchFlow1FunctionReferenceValue("l12"), LoadFlowAssert.DELTA_POWER);
}
}
protected void testGlskOutsideMainComponent(boolean dc) {
Network network = HvdcNetworkFactory.createLccWithBiggerComponents();
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "vl1_0");
List<SensitivityFactor> factors = List.of(createBranchFlowPerLinearGlsk("l12", "glsk"));
List<SensitivityVariableSet> variableSets = Collections.singletonList(new SensitivityVariableSet("glsk", List.of(new WeightedSensitivityVariable("g6", 1f),
new WeightedSensitivityVariable("g3", 2f))));
SensitivityAnalysisResult result = sensiRunner.run(network, factors, Collections.emptyList(), variableSets, sensiParameters);
assertEquals(1, result.getValues().size());
assertEquals(0, result.getBranchFlow1SensitivityValue("glsk", "l12", SensitivityVariableType.INJECTION_ACTIVE_POWER), LoadFlowAssert.DELTA_POWER);
if (dc) {
assertEquals(100.000, result.getBranchFlow1FunctionReferenceValue("l12"), LoadFlowAssert.DELTA_POWER);
} else {
assertEquals(100.080, result.getBranchFlow1FunctionReferenceValue("l12"), LoadFlowAssert.DELTA_POWER);
}
}
protected void testGlskAndLineOutsideMainComponent(boolean dc) {
Network network = HvdcNetworkFactory.createLccWithBiggerComponents();
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "vl1_0");
List<SensitivityFactor> factors = List.of(createBranchFlowPerLinearGlsk("l56", "glsk"));
List<SensitivityVariableSet> variableSets = List.of(new SensitivityVariableSet("glsk", List.of(new WeightedSensitivityVariable("g6", 1f),
new WeightedSensitivityVariable("g3", 2f))));
SensitivityAnalysisResult result = sensiRunner.run(network, factors, Collections.emptyList(), variableSets, sensiParameters);
assertEquals(1, result.getValues().size());
assertEquals(Double.NaN, result.getBranchFlow1SensitivityValue("glsk", "l56", SensitivityVariableType.INJECTION_ACTIVE_POWER), LoadFlowAssert.DELTA_POWER);
assertEquals(Double.NaN, result.getBranchFlow1FunctionReferenceValue("l56"), LoadFlowAssert.DELTA_POWER);
}
protected void testGlskPartiallyOutsideMainComponent(boolean dc) {
Network network = HvdcNetworkFactory.createLccWithBiggerComponents();
SensitivityAnalysisParameters sensiParameters = createParameters(dc, "vl1_0");
List<SensitivityFactor> factors = List.of(createBranchFlowPerLinearGlsk("l12", "glsk"));
List<SensitivityVariableSet> variableSets = List.of(new SensitivityVariableSet("glsk", List.of(new WeightedSensitivityVariable("ld2", 1f),
new WeightedSensitivityVariable("g3", 2f))));
SensitivityAnalysisResult result = sensiRunner.run(network, factors, Collections.emptyList(), variableSets, sensiParameters);
assertEquals(1, result.getValues().size());
List<SensitivityFactor> factorsInjection = List.of(createBranchFlowPerInjectionIncrease("l12", "ld2"));
SensitivityAnalysisResult resultInjection = sensiRunner.run(network, factorsInjection, Collections.emptyList(), Collections.emptyList(), sensiParameters);
assertEquals(resultInjection.getValues().iterator().next().getValue(), result.getValues().iterator().next().getValue(), LoadFlowAssert.DELTA_POWER);
}
}