Skip to content

Commit

Permalink
Flow decomposition observers refactoring (#171)
Browse files Browse the repository at this point in the history
Flow decomposition observers refactoring

Signed-off-by: Caio Luke <[email protected]>
  • Loading branch information
caioluke authored Oct 18, 2024
1 parent dd496bc commit 8b00ffe
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 137 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ Observers are notified of the following events:
* when the nodal injection matrix is computed (for base case or contingency)
* when the PTDF matrix is computed (for base case or contingency)
* when the PSDF matrix is computed (for base case or contingency)
* when the AC nodal injections matrix is computed (for base case or contingency)
* when the DC nodal injections matrix is computed (for base case or contingency)
* when the AC loadflow is computed (for base case or contingency)
* when the DC loadflow is computed (for base case or contingency)
* when the computation is done

After AC and DC loadflows the observer has access to the network at that stage, as well as the loadflow result.
In this manner, it is possible to retrieve any information of the network after loadflow calculations.

Note that these observers are meant to be used for testing purposes only.
Using observers impacts calculation performance and therefore are not suitable in production environment.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,8 @@ private FlowComputerUtils() {
// empty constructor
}

public static Map<String, Double> calculateAcTerminalReferenceFlows(Collection<Branch> xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult, TwoSides side) {
if (loadFlowServiceAcResult.fallbackHasBeenActivated()) {
return xnecList.stream().collect(Collectors.toMap(Identifiable::getId, branch -> Double.NaN));
}
return getTerminalReferenceFlow(xnecList, side);
public static Map<String, Double> calculateAcTerminalReferenceFlows(Collection<Branch> xnecList, boolean fallbackHasBeenActivated, TwoSides side) {
return fallbackHasBeenActivated ? getFallbackActivatedTerminalResults(xnecList) : getTerminalReferenceFlow(xnecList, side);
}

public static Map<String, Double> getTerminalReferenceFlow(Collection<Branch> xnecList, TwoSides side) {
Expand All @@ -42,11 +39,8 @@ public static Map<String, Double> getTerminalReferenceFlow(Collection<Branch> xn
));
}

public static Map<String, Double> calculateAcTerminalCurrents(Collection<Branch> xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult, TwoSides side) {
if (loadFlowServiceAcResult.fallbackHasBeenActivated()) {
return xnecList.stream().collect(Collectors.toMap(Identifiable::getId, branch -> Double.NaN));
}
return getTerminalCurrent(xnecList, side);
public static Map<String, Double> calculateAcTerminalCurrents(Collection<Branch> xnecList, boolean fallbackHasBeenActivated, TwoSides side) {
return fallbackHasBeenActivated ? getFallbackActivatedTerminalResults(xnecList) : getTerminalCurrent(xnecList, side);
}

public static Map<String, Double> getTerminalCurrent(Collection<Branch> xnecList, TwoSides side) {
Expand All @@ -56,4 +50,8 @@ public static Map<String, Double> getTerminalCurrent(Collection<Branch> xnecList
branch -> branch.getTerminal(side).getI()
));
}

private static Map<String, Double> getFallbackActivatedTerminalResults(Collection<Branch> xnecList) {
return xnecList.stream().collect(Collectors.toMap(Identifiable::getId, branch -> Double.NaN));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
/**
* @author Sebastien Murgey {@literal <sebastien.murgey at rte-france.com>}
* @author Hugo Schindler {@literal <hugo.schindler at rte-france.com>}
* @author Caio Luke {@literal <caio.luke at artelys.com>}
*/
public class FlowDecompositionComputer {

Expand Down Expand Up @@ -148,15 +149,14 @@ private void decomposeFlowForState(Network network,
Map<Country, Map<String, Double>> glsks,
LoadFlowRunningService.Result loadFlowServiceAcResult) {
// AC load flow
saveAcReferenceFlows(flowDecompositionResultsBuilder, network, xnecList, loadFlowServiceAcResult);
saveAcCurrents(flowDecompositionResultsBuilder, network, xnecList, loadFlowServiceAcResult);
saveAcLoadFlowResults(flowDecompositionResultsBuilder, network, xnecList, loadFlowServiceAcResult);

// Losses compensation
compensateLosses(network);

// DC load flow
runDcLoadFlow(network);
saveDcReferenceFlow(flowDecompositionResultsBuilder, network, xnecList);
LoadFlowRunningService.Result loadFlowServiceDcResult = runDcLoadFlow(network);
saveDcLoadFlowResults(flowDecompositionResultsBuilder, network, xnecList, loadFlowServiceDcResult);

// Nodal injections
NetworkMatrixIndexes networkMatrixIndexes = new NetworkMatrixIndexes(network, new ArrayList<>(xnecList));
Expand Down Expand Up @@ -187,21 +187,24 @@ private LoadFlowRunningService.Result runAcLoadFlow(Network network) {
return loadFlowRunningService.runAcLoadflow(network, loadFlowParameters, parameters.isDcFallbackEnabledAfterAcDivergence());
}

private void saveAcReferenceFlows(FlowDecompositionResults.PerStateBuilder flowDecompositionResultBuilder, Network network, Set<Branch> xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) {
Map<String, Double> acTerminal1ReferenceFlows = FlowComputerUtils.calculateAcTerminalReferenceFlows(xnecList, loadFlowServiceAcResult, TwoSides.ONE);
Map<String, Double> acTerminal2ReferenceFlows = FlowComputerUtils.calculateAcTerminalReferenceFlows(xnecList, loadFlowServiceAcResult, TwoSides.TWO);
flowDecompositionResultBuilder.saveAcTerminal1ReferenceFlow(acTerminal1ReferenceFlows);
flowDecompositionResultBuilder.saveAcTerminal2ReferenceFlow(acTerminal2ReferenceFlows);
observers.computedAcFlows(network, loadFlowServiceAcResult);
observers.computedAcNodalInjections(network, loadFlowServiceAcResult.fallbackHasBeenActivated());
private void saveAcLoadFlowResults(FlowDecompositionResults.PerStateBuilder flowDecompositionResultsBuilder, Network network, Set<Branch> xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) {
saveAcReferenceFlows(flowDecompositionResultsBuilder, xnecList, loadFlowServiceAcResult.fallbackHasBeenActivated());
saveAcCurrents(flowDecompositionResultsBuilder, xnecList, loadFlowServiceAcResult.fallbackHasBeenActivated());
observers.computedAcLoadFlowResults(network, loadFlowServiceAcResult);
}

private void saveAcCurrents(FlowDecompositionResults.PerStateBuilder flowDecompositionResultBuilder, Network network, Set<Branch> xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) {
Map<String, Double> acTerminal1Currents = FlowComputerUtils.calculateAcTerminalCurrents(xnecList, loadFlowServiceAcResult, TwoSides.ONE);
Map<String, Double> acTerminal2Currents = FlowComputerUtils.calculateAcTerminalCurrents(xnecList, loadFlowServiceAcResult, TwoSides.TWO);
private void saveAcReferenceFlows(FlowDecompositionResults.PerStateBuilder flowDecompositionResultsBuilder, Set<Branch> xnecList, boolean fallbackHasBeenActivated) {
Map<String, Double> acTerminal1ReferenceFlows = FlowComputerUtils.calculateAcTerminalReferenceFlows(xnecList, fallbackHasBeenActivated, TwoSides.ONE);
Map<String, Double> acTerminal2ReferenceFlows = FlowComputerUtils.calculateAcTerminalReferenceFlows(xnecList, fallbackHasBeenActivated, TwoSides.TWO);
flowDecompositionResultsBuilder.saveAcTerminal1ReferenceFlow(acTerminal1ReferenceFlows);
flowDecompositionResultsBuilder.saveAcTerminal2ReferenceFlow(acTerminal2ReferenceFlows);
}

private void saveAcCurrents(FlowDecompositionResults.PerStateBuilder flowDecompositionResultBuilder, Set<Branch> xnecList, boolean fallbackHasBeenActivated) {
Map<String, Double> acTerminal1Currents = FlowComputerUtils.calculateAcTerminalCurrents(xnecList, fallbackHasBeenActivated, TwoSides.ONE);
Map<String, Double> acTerminal2Currents = FlowComputerUtils.calculateAcTerminalCurrents(xnecList, fallbackHasBeenActivated, TwoSides.TWO);
flowDecompositionResultBuilder.saveAcCurrentTerminal1(acTerminal1Currents);
flowDecompositionResultBuilder.saveAcCurrentTerminal2(acTerminal2Currents);
observers.computedAcCurrents(network, loadFlowServiceAcResult);
}

private Map<Country, Double> getZonesNetPosition(Network network) {
Expand Down Expand Up @@ -239,10 +242,9 @@ private SparseMatrixWithIndexesTriplet getNodalInjectionsMatrix(Network network,
return nodalInjectionsMatrix;
}

private void saveDcReferenceFlow(FlowDecompositionResults.PerStateBuilder flowDecompositionResultBuilder, Network network, Set<Branch> xnecList) {
private void saveDcLoadFlowResults(FlowDecompositionResults.PerStateBuilder flowDecompositionResultBuilder, Network network, Set<Branch> xnecList, LoadFlowRunningService.Result loadFlowServiceDcResult) {
flowDecompositionResultBuilder.saveDcReferenceFlow(FlowComputerUtils.getTerminalReferenceFlow(xnecList, TwoSides.ONE));
observers.computedDcFlows(network);
observers.computedDcNodalInjections(network);
observers.computedDcLoadFlowResults(network, loadFlowServiceDcResult);
}

private SensitivityAnalyser getSensitivityAnalyser(Network network, NetworkMatrixIndexes networkMatrixIndexes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
package com.powsybl.flow_decomposition;

import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Network;
import com.powsybl.loadflow.LoadFlowResult;

import java.util.Map;

/**
* @author Guillaume Verger {@literal <guillaume.verger at artelys.com>}
* @author Caio Luke {@literal <caio.luke at artelys.com>}
*/
public interface FlowDecompositionObserver {

Expand Down Expand Up @@ -74,52 +77,19 @@ public interface FlowDecompositionObserver {
void computedPsdfMatrix(Map<String, Map<String, Double>> psdfMatrix);

/**
* Called when the AC nodal injections matrix is computed (for base case or contingency)
* Called after an AC loadflow has been computed
*
* @param positions the positions after AC loadflow
* @param network the network after AC loadflow
* @param loadFlowResult loadflow result after AC loadflow
* @param fallbackHasBeenActivated true if AC loadflow didn't converge
*/
void computedAcNodalInjections(Map<String, Double> positions, boolean fallbackHasBeenActivated);
void computedAcLoadFlowResults(Network network, LoadFlowResult loadFlowResult, boolean fallbackHasBeenActivated);

/**
* Called when the DC nodal injections matrix is computed (for base case or contingency)
* Called after a DC loadflow has been computed
*
* @param positions the positions after DC loadflow
* @param network the network after DC loadflow
* @param loadFlowResult loadflow result after DC loadflow
*/
void computedDcNodalInjections(Map<String, Double> positions);

/**
* Called when the AC loadflow is computed (for base case or contingency)
*
* @param flows the terminal 1 flow for all branches
*/
void computedAcFlowsTerminal1(Map<String, Double> flows);

/**
* Called when the AC loadflow is computed (for base case or contingency)
*
* @param flows the terminal 2 flow for all branches
*/
void computedAcFlowsTerminal2(Map<String, Double> flows);

/**
* Called when the DC loadflow is computed (for base case or contingency)
*
* @param flows the flows for all branches
*/
void computedDcFlows(Map<String, Double> flows);

/**
* Called when the AC loadflow is computed (for base case or contingency)
*
* @param currents the terminal 1 current for all branches
*/
void computedAcCurrentsTerminal1(Map<String, Double> currents);

/**
* Called when the AC loadflow is computed (for base case or contingency)
*
* @param currents the terminal 1 current for all branches
*/
void computedAcCurrentsTerminal2(Map<String, Double> currents);
void computedDcLoadFlowResults(Network network, LoadFlowResult loadFlowResult);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@
*/
package com.powsybl.flow_decomposition;

import com.powsybl.flow_decomposition.LoadFlowRunningService.Result;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.TwoSides;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* @author Guillaume Verger {@literal <guillaume.verger at artelys.com>}
* @author Caio Luke {@literal <caio.luke at artelys.com>}
*/
public class FlowDecompositionObserverList {

Expand Down Expand Up @@ -83,59 +82,15 @@ public void computedPsdfMatrix(SparseMatrixWithIndexesTriplet matrix) {
sendMatrix(FlowDecompositionObserver::computedPsdfMatrix, matrix);
}

public void computedAcFlows(Network network, Result loadFlowServiceAcResult) {
if (observers.isEmpty()) {
return;
}

for (FlowDecompositionObserver o : observers) {
o.computedAcFlowsTerminal1(FlowComputerUtils.calculateAcTerminalReferenceFlows(network.getBranchStream().toList(), loadFlowServiceAcResult, TwoSides.ONE));
o.computedAcFlowsTerminal2(FlowComputerUtils.calculateAcTerminalReferenceFlows(network.getBranchStream().toList(), loadFlowServiceAcResult, TwoSides.TWO));
}
}

public void computedDcFlows(Network network) {
if (observers.isEmpty()) {
return;
}

for (FlowDecompositionObserver o : observers) {
o.computedDcFlows(FlowComputerUtils.getTerminalReferenceFlow(network.getBranchStream().toList(), TwoSides.ONE));
}
}

public void computedAcCurrents(Network network, Result loadFlowServiceAcResult) {
if (observers.isEmpty()) {
return;
}

public void computedAcLoadFlowResults(Network network, LoadFlowRunningService.Result loadFlowServiceAcResult) {
for (FlowDecompositionObserver o : observers) {
o.computedAcCurrentsTerminal1(FlowComputerUtils.calculateAcTerminalCurrents(network.getBranchStream().toList(), loadFlowServiceAcResult, TwoSides.ONE));
o.computedAcCurrentsTerminal2(FlowComputerUtils.calculateAcTerminalCurrents(network.getBranchStream().toList(), loadFlowServiceAcResult, TwoSides.TWO));
o.computedAcLoadFlowResults(network, loadFlowServiceAcResult.getLoadFlowResult(), loadFlowServiceAcResult.fallbackHasBeenActivated());
}
}

public void computedAcNodalInjections(Network network, boolean fallbackHasBeenActivated) {
if (observers.isEmpty()) {
return;
}

Map<String, Double> results = new ReferenceNodalInjectionComputer().run(NetworkUtil.getNodeList(network));

for (FlowDecompositionObserver o : observers) {
o.computedAcNodalInjections(results, fallbackHasBeenActivated);
}
}

public void computedDcNodalInjections(Network network) {
if (observers.isEmpty()) {
return;
}

Map<String, Double> results = new ReferenceNodalInjectionComputer().run(NetworkUtil.getNodeList(network));

public void computedDcLoadFlowResults(Network network, LoadFlowRunningService.Result loadFlowServiceDcResult) {
for (FlowDecompositionObserver o : observers) {
o.computedDcNodalInjections(results);
o.computedDcLoadFlowResults(network, loadFlowServiceDcResult.getLoadFlowResult());
}
}

Expand Down
Loading

0 comments on commit 8b00ffe

Please sign in to comment.