Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix decremental connectivity #517

Merged
merged 7 commits into from
Apr 20, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ static VoltageInitializer getExtendedVoltageInitializer(LoadFlowParameters param
}

static LfNetworkParameters getNetworkParameters(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
SlackBusSelector slackBusSelector, GraphDecrementalConnectivityFactory<LfBus> connectivityFactory,
SlackBusSelector slackBusSelector, GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory,
boolean breakers) {
return new LfNetworkParameters(slackBusSelector,
connectivityFactory,
Expand All @@ -510,13 +510,13 @@ static LfNetworkParameters getNetworkParameters(LoadFlowParameters parameters, O
}

public static AcLoadFlowParameters createAcParameters(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus> connectivityFactory,
MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory,
Reporter reporter) {
return createAcParameters(network, parameters, parametersExt, matrixFactory, connectivityFactory, reporter, false, false);
}

public static AcLoadFlowParameters createAcParameters(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus> connectivityFactory,
MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory,
Reporter reporter, boolean breakers, boolean forceA1Var) {
AcLoadFlowParameters acParameters = createAcParameters(parameters, parametersExt, matrixFactory, connectivityFactory, reporter, breakers, forceA1Var);
if (parameters.isReadSlackBus()) {
Expand All @@ -526,7 +526,7 @@ public static AcLoadFlowParameters createAcParameters(Network network, LoadFlowP
}

public static AcLoadFlowParameters createAcParameters(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus> connectivityFactory,
MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory,
Reporter reporter, boolean breakers, boolean forceA1Var) {
SlackBusSelector slackBusSelector = SlackBusSelector.fromMode(parametersExt.getSlackBusSelectionMode(), parametersExt.getSlackBusesIds());

Expand All @@ -552,7 +552,7 @@ public static AcLoadFlowParameters createAcParameters(LoadFlowParameters paramet
}

public static DcLoadFlowParameters createDcParameters(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus> connectivityFactory,
MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory,
boolean forcePhaseControlOffAndAddAngle1Var) {
var dcParameters = createDcParameters(parameters, parametersExt, matrixFactory, connectivityFactory, forcePhaseControlOffAndAddAngle1Var);
if (parameters.isReadSlackBus()) {
Expand All @@ -562,7 +562,7 @@ public static DcLoadFlowParameters createDcParameters(Network network, LoadFlowP
}

public static DcLoadFlowParameters createDcParameters(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus> connectivityFactory,
MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory,
boolean forcePhaseControlOffAndAddAngle1Var) {
SlackBusSelector slackBusSelector = SlackBusSelector.fromMode(parametersExt.getSlackBusSelectionMode(), parametersExt.getSlackBusesIds());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class OpenLoadFlowProvider implements LoadFlowProvider {

private final MatrixFactory matrixFactory;

private final GraphDecrementalConnectivityFactory<LfBus> connectivityFactory;
private final GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory;

private boolean forcePhaseControlOffAndAddAngle1Var = false; // just for unit testing

Expand All @@ -72,7 +72,7 @@ public OpenLoadFlowProvider(MatrixFactory matrixFactory) {
this(matrixFactory, new EvenShiloachGraphDecrementalConnectivityFactory<>());
}

public OpenLoadFlowProvider(MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus> connectivityFactory) {
public OpenLoadFlowProvider(MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory) {
this.matrixFactory = Objects.requireNonNull(matrixFactory);
this.connectivityFactory = Objects.requireNonNull(connectivityFactory);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@ public void initialize(LfNetwork network) {
var connectivity = network.getConnectivity();

// apply contingency (in case we are inside a security analysis)
for (LfBranch disabledBranch : disabledBranches) {
connectivity.cut(disabledBranch.getBus1(), disabledBranch.getBus2());
}
disabledBranches.stream()
.filter(b -> b.getBus1() != null && b.getBus2() != null)
.forEach(connectivity::cut);
int smallComponentsCountBeforePhaseShifterLoss = connectivity.getSmallComponents().size();

// then the phase shifter controlled branch
connectivity.cut(controlledBranch.getBus1(), controlledBranch.getBus2());
if (controlledBranch.getBus1() != null && controlledBranch.getBus2() != null) {
connectivity.cut(controlledBranch);
}

if (connectivity.getSmallComponents().size() != smallComponentsCountBeforePhaseShifterLoss) {
// phase shifter controlled branch necessary for connectivity, we switch off control
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
package com.powsybl.openloadflow.graph;

import com.powsybl.commons.PowsyblException;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.jgrapht.Graph;
import org.jgrapht.Graphs;
import org.jgrapht.alg.connectivity.ConnectivityInspector;
Expand All @@ -26,19 +26,19 @@
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
* @author Florian Dupuy <florian.dupuy at rte-france.com>
*/
public class EvenShiloachGraphDecrementalConnectivity<V> implements GraphDecrementalConnectivity<V> {
public class EvenShiloachGraphDecrementalConnectivity<V, E> implements GraphDecrementalConnectivity<V, E> {

private static final Logger LOGGER = LoggerFactory.getLogger(EvenShiloachGraphDecrementalConnectivity.class);

private final Graph<V, Object> graph = new Pseudograph<>(Object.class);
private final Graph<V, E> graph = new Pseudograph<>(null, null, false);

private final Map<V, Integer> vertexToConnectedComponent;

private final List<Set<V>> newConnectedComponents;
private final Map<V, LevelNeighbours> levelNeighboursMap;

private final List<Pair<V, V>> cutEdges;
private final List<Pair<V, V>> unprocessedCutEdges;
private final List<Triple<V, E, V>> cutEdges;
private final List<E> edgesToCut;
private final Set<V> vertices;

private final LinkedList<Map<V, LevelNeighbours>> allSavedChangedLevels;
Expand All @@ -48,7 +48,7 @@ public class EvenShiloachGraphDecrementalConnectivity<V> implements GraphDecreme

public EvenShiloachGraphDecrementalConnectivity() {
this.cutEdges = new ArrayList<>();
this.unprocessedCutEdges = new ArrayList<>();
this.edgesToCut = new ArrayList<>();
this.newConnectedComponents = new ArrayList<>();
this.vertexToConnectedComponent = new HashMap<>();
this.levelNeighboursMap = new HashMap<>();
Expand All @@ -66,36 +66,37 @@ public void addVertex(V vertex) {
}

@Override
public void addEdge(V vertex1, V vertex2) {
if (vertex1 == null || vertex2 == null) {
return;
}
public void addEdge(V vertex1, V vertex2, E edge) {
Objects.requireNonNull(vertex1);
Objects.requireNonNull(vertex2);
if (vertex1 != vertex2) {
graph.addEdge(vertex1, vertex2, new Object());
graph.addEdge(vertex1, vertex2, edge);
} else {
LOGGER.warn("Loop on vertex {}: problem in input graph", vertex1);
}
invalidateInit();
}

private void invalidateInit() {
edgesToCut.forEach(graph::removeEdge);
init = false;
cutEdges.clear();
unprocessedCutEdges.clear();
edgesToCut.clear();
newConnectedComponents.clear();
invalidateVertexMapCache();
}

@Override
public void cut(V vertex1, V vertex2) {
if (vertex1 == null || vertex2 == null) {
return;
public void cut(E edge) {
if (!graph.containsEdge(edge)) {
throw new PowsyblException("No such edge in graph: " + edge);
}
invalidateVertexMapCache(); // connectivity unchanged if one vertex null
if (edgesToCut.contains(edge)) {
throw new PowsyblException("Edge already cut: " + edge);
}
invalidateVertexMapCache();

Pair<V, V> edgeCut = Pair.of(vertex1, vertex2);
cutEdges.add(edgeCut);
unprocessedCutEdges.add(edgeCut);
edgesToCut.add(edge);
}

private void invalidateVertexMapCache() {
Expand Down Expand Up @@ -124,8 +125,8 @@ public void reset() {
allSavedChangedLevels.descendingIterator().forEachRemaining(levelNeighboursMap::putAll);
allSavedChangedLevels.clear();

for (Pair<V, V> cutEdge : cutEdges) {
graph.addEdge(cutEdge.getLeft(), cutEdge.getRight(), new Object());
for (Triple<V, E, V> cutEdge : cutEdges) {
graph.addEdge(cutEdge.getLeft(), cutEdge.getRight(), cutEdge.getMiddle());
}
cutEdges.clear();
}
Expand Down Expand Up @@ -170,15 +171,16 @@ public Set<V> getNonConnectedVertices(V vertex) {
}

private void lazyComputeConnectivity() {
if (init && unprocessedCutEdges.isEmpty()) {
if (init && edgesToCut.isEmpty()) {
return;
}

init();
for (Pair<V, V> cutEdge : unprocessedCutEdges) {
V vertex1 = cutEdge.getLeft();
V vertex2 = cutEdge.getRight();
graph.removeEdge(vertex1, vertex2);
for (E edgeToCut : edgesToCut) {
V vertex1 = graph.getEdgeSource(edgeToCut);
V vertex2 = graph.getEdgeTarget(edgeToCut);
cutEdges.add(Triple.of(vertex1, edgeToCut, vertex2));
graph.removeEdge(edgeToCut);

GraphProcess processA = new GraphProcessA(vertex1, vertex2);
GraphProcessB processB = new GraphProcessB(vertex1, vertex2);
Expand All @@ -195,7 +197,7 @@ private void lazyComputeConnectivity() {
allSavedChangedLevels.add(processB.savedChangedLevels);
}
}
unprocessedCutEdges.clear();
edgesToCut.clear();

sortComponents();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
/**
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
*/
public class EvenShiloachGraphDecrementalConnectivityFactory<V> implements GraphDecrementalConnectivityFactory<V> {
public class EvenShiloachGraphDecrementalConnectivityFactory<V, E> implements GraphDecrementalConnectivityFactory<V, E> {

@Override
public GraphDecrementalConnectivity<V> create() {
public GraphDecrementalConnectivity<V, E> create() {
return new EvenShiloachGraphDecrementalConnectivity<>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,16 @@
/**
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
*/
public interface GraphDecrementalConnectivity<V> {
public interface GraphDecrementalConnectivity<V, E> {

void addVertex(V vertex);

void addEdge(V vertex1, V vertex2);
void addEdge(V vertex1, V vertex2, E edge);

/**
* Cut one edge between given vertices
* @param vertex1 first vertex, from or towards which the edge has been constructed
* @param vertex2 second vertex, towards or from which the edge has been constructed
* Cut given edge
*/
void cut(V vertex1, V vertex2);
void cut(E edge);

/**
* Reset all the cut done previously in the graph
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
*/
public interface GraphDecrementalConnectivityFactory<V> {
public interface GraphDecrementalConnectivityFactory<V, E> {

GraphDecrementalConnectivity<V> create();
GraphDecrementalConnectivity<V, E> create();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package com.powsybl.openloadflow.graph;

import com.powsybl.commons.PowsyblException;
import org.apache.commons.lang3.tuple.Triple;
import org.jgrapht.Graph;
import org.jgrapht.alg.interfaces.SpanningTreeAlgorithm;
Expand All @@ -18,7 +19,7 @@
/**
* @author Florian Dupuy <florian.dupuy at rte-france.com>
*/
public class MinimumSpanningTreeGraphDecrementalConnectivity<V> implements GraphDecrementalConnectivity<V> {
public class MinimumSpanningTreeGraphDecrementalConnectivity<V, E> implements GraphDecrementalConnectivity<V, E> {

private SpanningTrees mstOrigin;
private SpanningTrees mst;
Expand All @@ -40,32 +41,30 @@ public void addVertex(V vertex) {
}

@Override
public void addEdge(V vertex1, V vertex2) {
if (vertex1 == null || vertex2 == null) {
return;
}
graph.addEdge(vertex1, vertex2, new Object());
public void addEdge(V vertex1, V vertex2, E edge) {
Objects.requireNonNull(vertex1);
Objects.requireNonNull(vertex2);
graph.addEdge(vertex1, vertex2, edge);
}

@Override
public void cut(V vertex1, V vertex2) {
if (vertex1 == null || vertex2 == null) {
return;
public void cut(E edge) {
if (!graph.containsEdge(edge)) {
throw new PowsyblException("No such edge in graph: " + edge);
}

if (this.mstOrigin == null) {
this.mstOrigin = new KruskalMinimumSpanningTrees().getSpanningTree();
resetMst();
}
Objects.requireNonNull(vertex1);
Objects.requireNonNull(vertex2);
Object e = graph.removeEdge(vertex1, vertex2);

if (mst != null && mst.getEdges().contains(e)) {
if (mst != null && mst.getEdges().contains(edge)) {
invalidateMst();
}

cutEdges.add(Triple.of(vertex1, vertex2, e));
V vertex1 = graph.getEdgeSource(edge);
V vertex2 = graph.getEdgeTarget(edge);
graph.removeEdge(edge);
cutEdges.add(Triple.of(vertex1, vertex2, edge));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
/**
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
*/
public class MinimumSpanningTreeGraphDecrementalConnectivityFactory<V> implements GraphDecrementalConnectivityFactory<V> {
public class MinimumSpanningTreeGraphDecrementalConnectivityFactory<V, E> implements GraphDecrementalConnectivityFactory<V, E> {

@Override
public GraphDecrementalConnectivity<V> create() {
public GraphDecrementalConnectivity<V, E> create() {
return new MinimumSpanningTreeGraphDecrementalConnectivity<>();
}
}
Loading