Skip to content

Commit

Permalink
Merge branch 'main' into hvdc_pmax_sparse_matrix
Browse files Browse the repository at this point in the history
  • Loading branch information
jeandemanged authored Nov 13, 2024
2 parents 7ec9a78 + 6650b47 commit 70b1c48
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ protected DcLoadFlowParameters createParameters(LoadFlowParameters lfParameters,
* In case of connectivity break, a pre-computation has been done in {@link #calculatePostContingencyStatesForAContingencyBreakingConnectivity}
* to reset active power flow of hvdc lines on which one bus is lost.
* If connectivity, a generator, a load or a phase tap changer is lost due to the contingency, the pre contingency flowStates are overridden.
* @return the post contingency states for the contingency
*/
private double[] calculatePostContingencyStatesForAContingency(DcLoadFlowContext loadFlowContext, DenseMatrix contingenciesStates, double[] flowStates,
PropagatedContingency contingency, Map<String, ComputedContingencyElement> contingencyElementByBranch,
Expand All @@ -92,7 +93,6 @@ private double[] calculatePostContingencyStatesForAContingency(DcLoadFlowContext
DisabledNetwork disabledNetwork = new DisabledNetwork(disabledBuses, disabledBranches);

WoodburyEngine engine = new WoodburyEngine(loadFlowContext.getParameters().getEquationSystemCreationParameters(), contingencyElements, contingenciesStates);
double[] postContingencyStates;
double[] newFlowStates = flowStates;
if (contingency.getGeneratorIdsToLose().isEmpty() && contingency.getLoadIdsToLose().isEmpty()) {

Expand All @@ -108,7 +108,7 @@ private double[] calculatePostContingencyStatesForAContingency(DcLoadFlowContext
if (!disabledBuses.isEmpty() || !lostPhaseControllers.isEmpty()) {
newFlowStates = DcLoadFlowEngine.run(loadFlowContext, disabledNetwork, reportNode);
}
postContingencyStates = engine.run(newFlowStates);
engine.toPostContingencyStates(newFlowStates);
} else {
// if we have a contingency including the loss of a DC line or a generator or a load
// save base state for later restoration after each contingency
Expand All @@ -117,11 +117,11 @@ private double[] calculatePostContingencyStatesForAContingency(DcLoadFlowContext
contingency.toLfContingency(lfNetwork, false)
.ifPresent(lfContingency -> lfContingency.apply(lfParameters.getBalanceType()));
newFlowStates = DcLoadFlowEngine.run(loadFlowContext, disabledNetwork, reportNode);
postContingencyStates = engine.run(newFlowStates);
engine.toPostContingencyStates(newFlowStates);
networkState.restore();
}

return postContingencyStates;
return newFlowStates;
}

/**
Expand Down Expand Up @@ -201,8 +201,11 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List<Propag
// this is a difference with dc security analysis
cleanContingencies(lfNetwork, propagatedContingencies);

// compute the pre-contingency states
double[] preContingencyStates = DcLoadFlowEngine.run(context, new DisabledNetwork(), reportNode);
double[] baseContingencyStates = preContingencyStates.clone();
// create workingContingencyStates that will be a working copy of pre-contingency states
double[] workingContingencyStates = new double[preContingencyStates.length];
System.arraycopy(preContingencyStates, 0, workingContingencyStates, 0, preContingencyStates.length);

// set pre contingency angle states as state vector of equation system
context.getEquationSystem().getStateVector().set(preContingencyStates);
Expand Down Expand Up @@ -239,8 +242,8 @@ 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,
System.arraycopy(preContingencyStates, 0, workingContingencyStates, 0, preContingencyStates.length);
double[] postContingencyStates = calculatePostContingencyStatesForAContingency(context, connectivityBreakAnalysisResults.contingenciesStates(), workingContingencyStates, propagatedContingency,
connectivityBreakAnalysisResults.contingencyElementByBranch(), Collections.emptySet(), Collections.emptySet(), reportNode, Collections.emptySet());
// compute post contingency result with post contingency states
PostContingencyResult postContingencyResult = computePostContingencyResult(context, propagatedContingency.getContingency(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +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.MatrixException;
import com.powsybl.math.matrix.MatrixFactory;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.dc.DcLoadFlowContext;
Expand Down Expand Up @@ -189,6 +189,7 @@ private void calculateSensitivityValues(List<LfSensitivityFactor<DcVariableType,
* if the factorsStates should be overridden or not in this method.
* If connectivity, a generator, a load or a phase tap changer is lost due to the contingency,
* the flowStates are overridden.
* The matrices factorStates and flowStates are modified by this method.
*/
private void calculateSensitivityValuesForAContingency(DcLoadFlowContext loadFlowContext, OpenLoadFlowParameters lfParametersExt, SensitivityFactorHolder<DcVariableType, DcEquationType> validFactorHolder,
SensitivityFactorGroupList<DcVariableType, DcEquationType> factorGroups, DenseMatrix factorStates, DenseMatrix contingenciesStates, DenseMatrix flowStates,
Expand Down Expand Up @@ -229,9 +230,9 @@ private void calculateSensitivityValuesForAContingency(DcLoadFlowContext loadFlo
newFlowStates = calculateFlowStates(loadFlowContext, participatingElements, disabledNetwork, reportNode);
}

DenseMatrix postContingencyFlowStates = engine.run(newFlowStates);
DenseMatrix postContingencyFactorStates = engine.run(newFactorStates);
calculateSensitivityValues(factors, postContingencyFactorStates, postContingencyFlowStates, contingency, resultWriter, disabledNetwork);
engine.toPostContingencyStates(newFlowStates);
engine.toPostContingencyStates(newFactorStates);
calculateSensitivityValues(factors, newFactorStates, newFlowStates, contingency, resultWriter, disabledNetwork);
// write contingency status
if (contingency.hasNoImpact()) {
resultWriter.writeContingencyStatus(contingency.getIndex(), SensitivityAnalysisResult.Status.NO_IMPACT);
Expand Down Expand Up @@ -280,9 +281,9 @@ private void calculateSensitivityValuesForAContingency(DcLoadFlowContext loadFlo

DenseMatrix newFlowStates = calculateFlowStates(loadFlowContext, newParticipatingElements, disabledNetwork, reportNode);

DenseMatrix postContingencyFlowStates = engine.run(newFlowStates);
DenseMatrix postContingencyFactorStates = engine.run(newFactorStates);
calculateSensitivityValues(factors, postContingencyFactorStates, postContingencyFlowStates, contingency, resultWriter, disabledNetwork);
engine.toPostContingencyStates(newFlowStates);
engine.toPostContingencyStates(newFactorStates);
calculateSensitivityValues(factors, newFactorStates, newFlowStates, contingency, resultWriter, disabledNetwork);

networkState.restore();
}
Expand Down Expand Up @@ -439,13 +440,16 @@ public void analyse(Network network, List<PropagatedContingency> contingencies,

// run DC load on pre-contingency network
DenseMatrix baseFlowStates = calculateFlowStates(loadFlowContext, participatingElements, new DisabledNetwork(), reportNode);
DenseMatrix flowStates = (DenseMatrix) baseFlowStates.copy(new DenseMatrixFactory());
// create workingFlowStates matrix that will be a working copy of baseFlowStates
DenseMatrix workingFlowStates = new DenseMatrix(baseFlowStates.getRowCount(), baseFlowStates.getColumnCount());

// compute the pre-contingency factor states
DenseMatrix baseFactorStates = calculateFactorStates(loadFlowContext, factorGroups, participatingElements);
DenseMatrix factorStates = (DenseMatrix) baseFactorStates.copy(new DenseMatrixFactory());
// create workingFactorStates matrix that will be a working copy of baseFactorStates
DenseMatrix workingFactorStates = new DenseMatrix(baseFactorStates.getRowCount(), baseFactorStates.getColumnCount());

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

// filter contingencies without factors
List<PropagatedContingency> contingenciesWithFactors = new ArrayList<>();
Expand All @@ -465,24 +469,24 @@ 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);
matrixCopyValues(baseFlowStates, workingFlowStates);
matrixCopyValues(baseFactorStates, workingFactorStates);

calculateSensitivityValuesForAContingency(loadFlowContext, lfParametersExt, validFactorHolder, factorGroups,
factorStates, connectivityBreakAnalysisResults.contingenciesStates(), flowStates, contingency,
workingFactorStates, connectivityBreakAnalysisResults.contingenciesStates(), workingFlowStates, 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);
matrixCopyValues(baseFlowStates, workingFlowStates);
matrixCopyValues(baseFactorStates, workingFactorStates);

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

Expand All @@ -496,13 +500,15 @@ public void analyse(Network network, List<PropagatedContingency> contingencies,
* 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) {
private static void matrixCopyValues(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));
}
}
} else {
throw new MatrixException("Incompatible matrices dimensions when copying values. Received (" + originalMatrix.getRowCount() + ", " + originalMatrix.getColumnCount() + ") and (" + copyMatrix.getRowCount() + ", " + copyMatrix.getColumnCount() + ")");
}
}

Expand Down
20 changes: 7 additions & 13 deletions src/main/java/com/powsybl/openloadflow/sensi/WoodburyEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,11 @@ 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 (which is the same modified pre-contingency states java object).
* Calculate post-contingency states values by modifying pre-contingency states values using some flow transfer factors (alphas).
*/
public DenseMatrix run(DenseMatrix preContingencyStates) {
public void toPostContingencyStates(DenseMatrix preContingencyStates) {
Objects.requireNonNull(preContingencyStates);
// fill the post contingency matrices
DenseMatrix postContingencyStates = preContingencyStates;

for (int columnIndex = 0; columnIndex < preContingencyStates.getColumnCount(); columnIndex++) {
setAlphas(preContingencyStates, columnIndex);
for (int rowIndex = 0; rowIndex < preContingencyStates.getRowCount(); rowIndex++) {
Expand All @@ -98,29 +96,25 @@ public DenseMatrix run(DenseMatrix preContingencyStates) {
postContingencyValue += contingencyElement.getAlphaForPostContingencyState()
* contingenciesStates.get(rowIndex, contingencyElement.getContingencyIndex());
}
postContingencyStates.set(rowIndex, columnIndex, postContingencyValue);
preContingencyStates.set(rowIndex, columnIndex, postContingencyValue);
}
}
return postContingencyStates;
}

/**
* 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 (which is the same modified pre-contingency java object).
* Calculate post-contingency states values by modifying pre-contingency states values using some flow transfer factors (alphas).
*/
public double[] run(double[] preContingencyStates) {
public void toPostContingencyStates(double[] preContingencyStates) {
Objects.requireNonNull(preContingencyStates);
double[] postContingencyStates = preContingencyStates;
setAlphas(new DenseMatrix(preContingencyStates.length, 1, preContingencyStates), 0);
for (int rowIndex = 0; rowIndex < preContingencyStates.length; rowIndex++) {
double postContingencyValue = preContingencyStates[rowIndex];
for (ComputedContingencyElement contingencyElement : contingencyElements) {
postContingencyValue += contingencyElement.getAlphaForPostContingencyState()
* contingenciesStates.get(rowIndex, contingencyElement.getContingencyIndex());
}
postContingencyStates[rowIndex] = postContingencyValue;
preContingencyStates[rowIndex] = postContingencyValue;
}
return postContingencyStates;
}
}

0 comments on commit 70b1c48

Please sign in to comment.