Skip to content

Commit

Permalink
Fix high memory usage with DC Sensitivity Analysis and DC Woodbury Se…
Browse files Browse the repository at this point in the history
…curity Analysis (#1109)

Signed-off-by: PRABAKARAN Sylvestre <sylvestre.prabakaran@rte-france.com>
(cherry picked from commit 807808a)
  • Loading branch information
SylvestreSakti authored and olperr1 committed Nov 4, 2024
1 parent db7e6ea commit 469c491
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List<Propag
cleanContingencies(lfNetwork, propagatedContingencies);

double[] preContingencyStates = DcLoadFlowEngine.run(context, new DisabledNetwork(), reportNode);
double[] baseContingencyStates = preContingencyStates.clone();

// set pre contingency angle states as state vector of equation system
context.getEquationSystem().getStateVector().set(preContingencyStates);
Expand Down Expand Up @@ -238,7 +239,7 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List<Propag

logPostContingencyStart(lfNetwork, lfContingency);
Stopwatch stopwatch = Stopwatch.createStarted();

System.arraycopy(baseContingencyStates, 0, preContingencyStates, 0, baseContingencyStates.length);
double[] postContingencyStates = calculatePostContingencyStatesForAContingency(context, connectivityBreakAnalysisResults.contingenciesStates(), preContingencyStates, propagatedContingency,
connectivityBreakAnalysisResults.contingencyElementByBranch(), Collections.emptySet(), Collections.emptySet(), reportNode, Collections.emptySet());
// compute post contingency result with post contingency states
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.powsybl.iidm.network.Network;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.math.matrix.DenseMatrix;
import com.powsybl.math.matrix.DenseMatrixFactory;
import com.powsybl.math.matrix.MatrixFactory;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.dc.DcLoadFlowContext;
Expand Down Expand Up @@ -231,7 +232,6 @@ private void calculateSensitivityValuesForAContingency(DcLoadFlowContext loadFlo
DenseMatrix postContingencyFlowStates = engine.run(newFlowStates);
DenseMatrix postContingencyFactorStates = engine.run(newFactorStates);
calculateSensitivityValues(factors, postContingencyFactorStates, postContingencyFlowStates, contingency, resultWriter, disabledNetwork);

// write contingency status
if (contingency.hasNoImpact()) {
resultWriter.writeContingencyStatus(contingency.getIndex(), SensitivityAnalysisResult.Status.NO_IMPACT);
Expand Down Expand Up @@ -438,13 +438,14 @@ public void analyse(Network network, List<PropagatedContingency> contingencies,
: Collections.emptyList();

// run DC load on pre-contingency network
DenseMatrix flowStates = calculateFlowStates(loadFlowContext, participatingElements, new DisabledNetwork(), reportNode);

DenseMatrix baseFlowStates = calculateFlowStates(loadFlowContext, participatingElements, new DisabledNetwork(), reportNode);
DenseMatrix flowStates = (DenseMatrix) baseFlowStates.copy(new DenseMatrixFactory());
// compute the pre-contingency factor states
DenseMatrix factorsStates = calculateFactorStates(loadFlowContext, factorGroups, participatingElements);
DenseMatrix baseFactorStates = calculateFactorStates(loadFlowContext, factorGroups, participatingElements);
DenseMatrix factorStates = (DenseMatrix) baseFactorStates.copy(new DenseMatrixFactory());

// calculate sensitivity values for pre-contingency network
calculateSensitivityValues(validFactorHolder.getFactorsForBaseNetwork(), factorsStates, flowStates, null, resultWriter, new DisabledNetwork());
calculateSensitivityValues(validFactorHolder.getFactorsForBaseNetwork(), factorStates, flowStates, null, resultWriter, new DisabledNetwork());

// filter contingencies without factors
List<PropagatedContingency> contingenciesWithFactors = new ArrayList<>();
Expand All @@ -464,23 +465,45 @@ public void analyse(Network network, List<PropagatedContingency> contingencies,

// process contingencies with no connectivity break
for (PropagatedContingency contingency : connectivityBreakAnalysisResults.nonBreakingConnectivityContingencies()) {
matrixShallowCopy(baseFlowStates, flowStates);
matrixShallowCopy(baseFactorStates, factorStates);

calculateSensitivityValuesForAContingency(loadFlowContext, lfParametersExt, validFactorHolder, factorGroups,
factorsStates, connectivityBreakAnalysisResults.contingenciesStates(), flowStates, contingency,
factorStates, connectivityBreakAnalysisResults.contingenciesStates(), flowStates, contingency,
connectivityBreakAnalysisResults.contingencyElementByBranch(), Collections.emptySet(), participatingElements, Collections.emptySet(), resultWriter, reportNode, Collections.emptySet(), false);
}

LOGGER.info("Processing contingencies with connectivity break");

// process contingencies with connectivity break
for (ConnectivityBreakAnalysis.ConnectivityAnalysisResult connectivityAnalysisResult : connectivityBreakAnalysisResults.connectivityAnalysisResults()) {
matrixShallowCopy(baseFlowStates, flowStates);
matrixShallowCopy(baseFactorStates, factorStates);

processContingenciesBreakingConnectivity(connectivityAnalysisResult, loadFlowContext, lfParameters, lfParametersExt,
validFactorHolder, factorGroups, participatingElements, connectivityBreakAnalysisResults.contingencyElementByBranch(),
flowStates, factorsStates, connectivityBreakAnalysisResults.contingenciesStates(), resultWriter, reportNode);
flowStates, factorStates, connectivityBreakAnalysisResults.contingenciesStates(), resultWriter, reportNode);
}
}

stopwatch.stop();
LOGGER.info("DC sensitivity analysis done in {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));
}
}

/**
* Copy all the values that are in an originalMatrix and paste it in the copyMatrix (without allocating new memory spaces)
* The dimensions of both matrices must be the same
*/
// TODO : implement this method for DenseMatrix in powsybl-core ?
private static void matrixShallowCopy(DenseMatrix originalMatrix, DenseMatrix copyMatrix) {
if (originalMatrix.getRowCount() == copyMatrix.getRowCount() && originalMatrix.getColumnCount() == copyMatrix.getColumnCount()) {
for (int columnIndex = 0; columnIndex < originalMatrix.getColumnCount(); columnIndex++) {
for (int rowIndex = 0; rowIndex < originalMatrix.getRowCount(); rowIndex++) {
copyMatrix.set(rowIndex, columnIndex, originalMatrix.get(rowIndex, columnIndex));
}
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ private void setAlphas(DenseMatrix states, int columnState) {

/**
* Calculate post-contingency states values using pre-contingency states values and some flow transfer factors (alphas).
* @return a matrix of post-contingency voltage angle states.
* @return a matrix of post-contingency voltage angle states (which is the same modified pre-contingency states java object).
*/
public DenseMatrix run(DenseMatrix preContingencyStates) {
Objects.requireNonNull(preContingencyStates);
// fill the post contingency matrices
DenseMatrix postContingencyStates = new DenseMatrix(preContingencyStates.getRowCount(), preContingencyStates.getColumnCount());
DenseMatrix postContingencyStates = preContingencyStates;
for (int columnIndex = 0; columnIndex < preContingencyStates.getColumnCount(); columnIndex++) {
setAlphas(preContingencyStates, columnIndex);
for (int rowIndex = 0; rowIndex < preContingencyStates.getRowCount(); rowIndex++) {
Expand All @@ -106,11 +106,11 @@ public DenseMatrix run(DenseMatrix preContingencyStates) {

/**
* Calculate post-contingency states values using pre-contingency states values and some flow transfer factors (alphas).
* @return an array of post-contingency voltage angle states.
* @return an array of post-contingency voltage angle states (which is the same modified pre-contingency java object).
*/
public double[] run(double[] preContingencyStates) {
Objects.requireNonNull(preContingencyStates);
double[] postContingencyStates = new double[preContingencyStates.length];
double[] postContingencyStates = preContingencyStates;
setAlphas(new DenseMatrix(preContingencyStates.length, 1, preContingencyStates), 0);
for (int rowIndex = 0; rowIndex < preContingencyStates.length; rowIndex++) {
double postContingencyValue = preContingencyStates[rowIndex];
Expand Down

0 comments on commit 469c491

Please sign in to comment.