Skip to content

Commit

Permalink
Move runDcLoadFlow from DC sensitivity analysis to DcLoadFlowEngine (#…
Browse files Browse the repository at this point in the history
…1082)

Signed-off-by: p-arvy <[email protected]>
Co-authored-by: Anne Tilloy <[email protected]>
  • Loading branch information
p-arvy and annetill authored Aug 29, 2024
1 parent e007722 commit b4266bb
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 56 deletions.
57 changes: 53 additions & 4 deletions src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@
*/
package com.powsybl.openloadflow.dc;

import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.math.matrix.MatrixException;
import com.powsybl.openloadflow.dc.equations.DcEquationType;
import com.powsybl.openloadflow.dc.equations.DcVariableType;
import com.powsybl.openloadflow.equations.EquationSystem;
import com.powsybl.openloadflow.equations.JacobianMatrix;
import com.powsybl.openloadflow.equations.TargetVector;
import com.powsybl.openloadflow.equations.Variable;
import com.powsybl.openloadflow.equations.*;
import com.powsybl.openloadflow.lf.LoadFlowEngine;
import com.powsybl.openloadflow.lf.outerloop.OuterLoopStatus;
import com.powsybl.openloadflow.network.DisabledNetwork;
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.network.LfNetwork;
import com.powsybl.openloadflow.network.LfNetworkLoader;
Expand All @@ -29,6 +28,7 @@
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -221,4 +221,53 @@ public static <T> List<DcLoadFlowResult> run(T network, LfNetworkLoader<T> netwo
})
.collect(Collectors.toList());
}

/**
* A simplified version of DcLoadFlowEngine that supports on the fly bus and branch disabling and that do not
* update the state vector and the network at the end (because we don't need it to just evaluate a few equations).
*/
public static double[] run(DcLoadFlowContext loadFlowContext, DisabledNetwork disabledNetwork, ReportNode reportNode) {
Collection<LfBus> remainingBuses;
if (disabledNetwork.getBuses().isEmpty()) {
remainingBuses = loadFlowContext.getNetwork().getBuses();
} else {
remainingBuses = new LinkedHashSet<>(loadFlowContext.getNetwork().getBuses());
remainingBuses.removeAll(disabledNetwork.getBuses());
}

DcLoadFlowParameters parameters = loadFlowContext.getParameters();
if (parameters.isDistributedSlack()) {
distributeSlack(remainingBuses, parameters.getBalanceType(), parameters.getNetworkParameters().isUseActiveLimits());
}

// we need to copy the target array because:
// - in case of disabled buses or branches some elements could be overwritten to zero
// - JacobianMatrix.solveTransposed take as an input the second member and reuse the array
// to fill with the solution
// so we need to copy to later the target as it is and reusable for next run
var targetVectorArray = loadFlowContext.getTargetVector().getArray().clone();

if (!disabledNetwork.getBuses().isEmpty()) {
// set buses injections and transformers to 0
disabledNetwork.getBuses().stream()
.flatMap(lfBus -> loadFlowContext.getEquationSystem().getEquation(lfBus.getNum(), DcEquationType.BUS_TARGET_P).stream())
.map(Equation::getColumn)
.forEach(column -> targetVectorArray[column] = 0);
}

if (!disabledNetwork.getBranches().isEmpty()) {
// set transformer phase shift to 0
disabledNetwork.getBranches().stream()
.flatMap(lfBranch -> loadFlowContext.getEquationSystem().getEquation(lfBranch.getNum(), DcEquationType.BRANCH_TARGET_ALPHA1).stream())
.map(Equation::getColumn)
.forEach(column -> targetVectorArray[column] = 0);
}

boolean succeeded = solve(targetVectorArray, loadFlowContext.getJacobianMatrix(), reportNode);
if (!succeeded) {
throw new PowsyblException("DC solver failed");
}

return targetVectorArray; // now contains dx
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import com.powsybl.openloadflow.dc.equations.DcEquationSystemCreationParameters;
import com.powsybl.openloadflow.dc.equations.DcEquationType;
import com.powsybl.openloadflow.dc.equations.DcVariableType;
import com.powsybl.openloadflow.equations.Equation;
import com.powsybl.openloadflow.graph.GraphConnectivityFactory;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.network.impl.LfNetworkList;
Expand All @@ -40,6 +39,7 @@
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.powsybl.openloadflow.dc.DcLoadFlowEngine.run;
import static com.powsybl.openloadflow.network.util.ParticipatingElement.normalizeParticipationFactors;

/**
Expand Down Expand Up @@ -85,7 +85,7 @@ private DenseMatrix calculateFlowStates(DcLoadFlowContext loadFlowContext, List<
.collect(Collectors.toSet()), BusState::save);
}

double[] dx = runDcLoadFlow(loadFlowContext, disabledNetwork, reportNode);
double[] dx = run(loadFlowContext, disabledNetwork, reportNode);

if (parameters.isDistributedSlack()) {
ElementState.restore(busStates);
Expand All @@ -94,56 +94,6 @@ private DenseMatrix calculateFlowStates(DcLoadFlowContext loadFlowContext, List<
return new DenseMatrix(dx.length, 1, dx);
}

/**
* A simplified version of DcLoadFlowEngine that supports on the fly bus and branch disabling and that do not
* update the state vector and the network at the end (because we don't need it to just evaluate a few equations)
*/
public double[] runDcLoadFlow(DcLoadFlowContext loadFlowContext, DisabledNetwork disabledNetwork,
ReportNode reportNode) {
Collection<LfBus> remainingBuses;
if (disabledNetwork.getBuses().isEmpty()) {
remainingBuses = loadFlowContext.getNetwork().getBuses();
} else {
remainingBuses = new LinkedHashSet<>(loadFlowContext.getNetwork().getBuses());
remainingBuses.removeAll(disabledNetwork.getBuses());
}

DcLoadFlowParameters parameters = loadFlowContext.getParameters();
if (parameters.isDistributedSlack()) {
DcLoadFlowEngine.distributeSlack(remainingBuses, parameters.getBalanceType(), parameters.getNetworkParameters().isUseActiveLimits());
}

// we need to copy the target array because:
// - in case of disabled buses or branches some elements could be overwritten to zero
// - JacobianMatrix.solveTransposed take as an input the second member and reuse the array
// to fill with the solution
// so we need to copy to later the target as it is and reusable for next run
var targetVectorArray = loadFlowContext.getTargetVector().getArray().clone();

if (!disabledNetwork.getBuses().isEmpty()) {
// set buses injections and transformers to 0
disabledNetwork.getBuses().stream()
.flatMap(lfBus -> loadFlowContext.getEquationSystem().getEquation(lfBus.getNum(), DcEquationType.BUS_TARGET_P).stream())
.map(Equation::getColumn)
.forEach(column -> targetVectorArray[column] = 0);
}

if (!disabledNetwork.getBranches().isEmpty()) {
// set transformer phase shift to 0
disabledNetwork.getBranches().stream()
.flatMap(lfBranch -> loadFlowContext.getEquationSystem().getEquation(lfBranch.getNum(), DcEquationType.BRANCH_TARGET_ALPHA1).stream())
.map(Equation::getColumn)
.forEach(column -> targetVectorArray[column] = 0);
}

boolean succeeded = DcLoadFlowEngine.solve(targetVectorArray, loadFlowContext.getJacobianMatrix(), reportNode);
if (!succeeded) {
throw new PowsyblException("DC solver failed");
}

return targetVectorArray; // now contains dx
}

/**
* Calculate flow and sensitivity values from pre-contingency states or post-contingency states.
* Write the flow and sensitivity values for a LfSensitivityFactor in the SensitivityResultWriter.
Expand Down

0 comments on commit b4266bb

Please sign in to comment.