com.powsybl.python.sensitivity.SensitivityAnalysisContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pypowsybl Show documentation
Show all versions of pypowsybl Show documentation
A C interface to powsybl, for pypowsybl implementation
The newest version!
/**
* Copyright (c) 2021, 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.python.sensitivity;
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.contingency.Contingency;
import com.powsybl.contingency.ContingencyContext;
import com.powsybl.contingency.ContingencyContextType;
import com.powsybl.iidm.network.*;
import com.powsybl.python.commons.CommonObjects;
import com.powsybl.python.contingency.ContingencyContainerImpl;
import com.powsybl.sensitivity.*;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Geoffroy Jamgotchian {@literal }
*/
class SensitivityAnalysisContext extends ContingencyContainerImpl {
private List variableSets = Collections.emptyList();
public static class MatrixInfo {
private final ContingencyContextType contingencyContextType;
private final SensitivityFunctionType functionType;
private final SensitivityVariableType variableType;
private final List columnIds;
private final List rowIds;
private final List contingencyIds;
private int offsetData;
private int offsetColumn;
MatrixInfo(ContingencyContextType context, SensitivityFunctionType functionType, SensitivityVariableType variableType,
List columnIds, List rowIds, List contingencyIds) {
this.contingencyContextType = context;
this.functionType = functionType;
this.variableType = variableType;
this.columnIds = columnIds;
this.rowIds = rowIds;
this.contingencyIds = contingencyIds;
}
ContingencyContextType getContingencyContextType() {
return contingencyContextType;
}
SensitivityFunctionType getFunctionType() {
return functionType;
}
public SensitivityVariableType getVariableType() {
return variableType;
}
void setOffsetData(int offset) {
this.offsetData = offset;
}
void setOffsetColumn(int offset) {
this.offsetColumn = offset;
}
int getOffsetData() {
return offsetData;
}
int getOffsetColumn() {
return offsetColumn;
}
List getRowIds() {
return rowIds;
}
List getColumnIds() {
return columnIds;
}
List getContingencyIds() {
return contingencyIds;
}
int getRowCount() {
return rowIds.size();
}
int getColumnCount() {
return columnIds.size();
}
}
private final Map factorsMatrix = new HashMap<>();
void addFactorMatrix(String matrixId, List branchesIds, List variablesIds,
List contingencies, ContingencyContextType contingencyContextType,
SensitivityFunctionType sensitivityFunctionType, SensitivityVariableType sensitivityVariableType) {
if (factorsMatrix.containsKey(matrixId)) {
throw new PowsyblException("Matrix '" + matrixId + "' already exists.");
}
MatrixInfo info = new MatrixInfo(contingencyContextType, sensitivityFunctionType, sensitivityVariableType, branchesIds, variablesIds, contingencies);
factorsMatrix.put(matrixId, info);
}
public void setVariableSets(List variableSets) {
this.variableSets = Objects.requireNonNull(variableSets);
}
List prepareMatrices() {
List matrices = new ArrayList<>();
int offsetData = 0;
int offsetColumns = 0;
for (MatrixInfo matrix : factorsMatrix.values()) {
matrix.setOffsetData(offsetData);
matrix.setOffsetColumn(offsetColumns);
matrices.add(matrix);
offsetData += matrix.getColumnCount() * matrix.getRowCount();
offsetColumns += matrix.getColumnCount();
}
return matrices;
}
int getTotalNumberOfMatrixFactors(List matrices) {
int count = 0;
for (MatrixInfo matrix : matrices) {
count += matrix.getColumnCount() * matrix.getRowCount();
}
return count;
}
int getTotalNumberOfMatrixFactorsColumns(List matrices) {
int count = 0;
for (MatrixInfo matrix : matrices) {
count += matrix.getColumnCount();
}
return count;
}
private SensitivityVariableType getVariableType(Network network, String variableId) {
Identifiable> identifiable = network.getIdentifiable(variableId);
if (identifiable instanceof Injection>) {
return SensitivityVariableType.INJECTION_ACTIVE_POWER;
} else if (identifiable instanceof TwoWindingsTransformer) {
return SensitivityVariableType.TRANSFORMER_PHASE;
} else if (identifiable instanceof HvdcLine) {
return SensitivityVariableType.HVDC_LINE_ACTIVE_POWER;
} else {
return null;
}
}
SensitivityAnalysisResultContext run(Network network, SensitivityAnalysisParameters sensitivityAnalysisParameters, String provider, ReportNode reportNode) {
List contingencies = createContingencies(network);
List matrices = prepareMatrices();
Map variableSetsById = variableSets.stream().collect(Collectors.toMap(SensitivityVariableSet::getId, e -> e));
SensitivityFactorReader factorReader = handler -> {
for (MatrixInfo matrix : matrices) {
List columns = matrix.getColumnIds();
List rows = matrix.getRowIds();
List contingencyContexts = new ArrayList<>();
if (matrix.getContingencyContextType() == ContingencyContextType.ALL) {
contingencyContexts.add(ContingencyContext.all());
} else if (matrix.getContingencyContextType() == ContingencyContextType.NONE) {
contingencyContexts.add(ContingencyContext.none());
} else {
for (String c : matrix.getContingencyIds()) {
contingencyContexts.add(ContingencyContext.specificContingency(c));
}
}
switch (matrix.getFunctionType()) {
case BRANCH_ACTIVE_POWER_1, BRANCH_ACTIVE_POWER_2, BRANCH_ACTIVE_POWER_3,
BRANCH_REACTIVE_POWER_1, BRANCH_REACTIVE_POWER_2, BRANCH_REACTIVE_POWER_3,
BRANCH_CURRENT_1, BRANCH_CURRENT_2, BRANCH_CURRENT_3 -> {
for (String variableId : rows) {
for (String branchId : columns) {
SensitivityVariableType variableType = matrix.getVariableType();
boolean variableSet = false;
if (variableType == null) {
variableType = getVariableType(network, variableId);
if (variableType == null) {
if (variableSetsById.containsKey(variableId)) {
variableSet = true;
variableType = SensitivityVariableType.INJECTION_ACTIVE_POWER;
} else {
throw new PowsyblException("Variable '" + variableId + "' not found");
}
}
}
for (ContingencyContext cCtx : contingencyContexts) {
handler.onFactor(matrix.getFunctionType(), branchId, variableType, variableId, variableSet, cCtx);
}
}
}
}
case BUS_VOLTAGE -> {
for (String targetVoltageId : rows) {
for (String busVoltageId : columns) {
handler.onFactor(SensitivityFunctionType.BUS_VOLTAGE, busVoltageId,
SensitivityVariableType.BUS_TARGET_VOLTAGE, targetVoltageId, false, ContingencyContext.all());
}
}
}
}
}
};
int baseCaseValueSize = getTotalNumberOfMatrixFactors(matrices);
double[] baseCaseValues = new double[baseCaseValueSize];
double[][] valuesByContingencyIndex = new double[contingencies.size()][baseCaseValueSize];
int totalColumnsCount = getTotalNumberOfMatrixFactorsColumns(matrices);
double[] baseCaseReferences = new double[totalColumnsCount];
double[][] referencesByContingencyIndex = new double[contingencies.size()][totalColumnsCount];
NavigableMap factorIndexMatrixMap = new TreeMap<>();
for (MatrixInfo m : matrices) {
factorIndexMatrixMap.put(m.getOffsetData(), m);
}
SensitivityResultWriter valueWriter = new SensitivityResultWriter() {
@Override
public void writeSensitivityValue(int factorContext, int contingencyIndex, double value, double functionReference) {
MatrixInfo m = factorIndexMatrixMap.floorEntry(factorContext).getValue();
int columnIdx = m.getOffsetColumn() + (factorContext - m.getOffsetData()) % m.getColumnCount();
if (contingencyIndex != -1) {
valuesByContingencyIndex[contingencyIndex][factorContext] = value;
referencesByContingencyIndex[contingencyIndex][columnIdx] = functionReference;
} else {
baseCaseValues[factorContext] = value;
baseCaseReferences[columnIdx] = functionReference;
}
}
@Override
public void writeContingencyStatus(int i, SensitivityAnalysisResult.Status status) {
// nothing to do
}
};
SensitivityAnalysis.find(provider)
.run(network,
network.getVariantManager().getWorkingVariantId(),
factorReader,
valueWriter,
contingencies,
variableSets,
sensitivityAnalysisParameters,
CommonObjects.getComputationManager(),
(reportNode == null) ? ReportNode.NO_OP : reportNode);
Map valuesByContingencyId = new HashMap<>(contingencies.size());
Map referencesByContingencyId = new HashMap<>(contingencies.size());
for (int contingencyIndex = 0; contingencyIndex < contingencies.size(); contingencyIndex++) {
Contingency contingency = contingencies.get(contingencyIndex);
valuesByContingencyId.put(contingency.getId(), valuesByContingencyIndex[contingencyIndex]);
referencesByContingencyId.put(contingency.getId(), referencesByContingencyIndex[contingencyIndex]);
}
return new SensitivityAnalysisResultContext(factorsMatrix,
baseCaseValues,
valuesByContingencyId,
baseCaseReferences,
referencesByContingencyId);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy