-
Notifications
You must be signed in to change notification settings - Fork 8
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
DcValueVoltageInitializer fails in presence of resistive only branches #683
Changes from 4 commits
2ec2182
495024f
984ebcc
10756b4
5487f4d
49a8e4c
305712f
4085499
d8ed92d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,8 @@ | |
import com.powsybl.openloadflow.util.PerUnit; | ||
import com.powsybl.openloadflow.util.Reports; | ||
import org.jgrapht.Graph; | ||
import org.jgrapht.alg.interfaces.SpanningTreeAlgorithm; | ||
import org.jgrapht.alg.spanning.KruskalMinimumSpanningTree; | ||
import org.jgrapht.graph.Pseudograph; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
@@ -75,6 +77,14 @@ public class LfNetwork extends AbstractPropertyBag implements PropertyBag { | |
|
||
private GraphConnectivity<LfBus, LfBranch> connectivity; | ||
|
||
private Graph<LfBus, LfBranch> dcZeroImpedanceSubGraph; | ||
|
||
private Graph<LfBus, LfBranch> acZeroImpedanceSubGraph; | ||
|
||
private SpanningTreeAlgorithm.SpanningTree<LfBranch> dcZeroImpedanceSpanningTree; | ||
|
||
private SpanningTreeAlgorithm.SpanningTree<LfBranch> acZeroImpedanceSpanningTree; | ||
|
||
private Reporter reporter; | ||
|
||
public LfNetwork(int numCC, int numSC, SlackBusSelector slackBusSelector, | ||
|
@@ -120,13 +130,21 @@ public void updateSlack() { | |
} | ||
} | ||
|
||
private void invalidateZeroImpedanceSubGraphs() { | ||
dcZeroImpedanceSubGraph = null; | ||
acZeroImpedanceSubGraph = null; | ||
dcZeroImpedanceSpanningTree = null; | ||
acZeroImpedanceSpanningTree = null; | ||
} | ||
|
||
public void addBranch(LfBranch branch) { | ||
Objects.requireNonNull(branch); | ||
branch.setNum(branches.size()); | ||
branches.add(branch); | ||
branchesById.put(branch.getId(), branch); | ||
invalidateSlack(); | ||
connectivity = null; | ||
invalidateZeroImpedanceSubGraphs(); | ||
|
||
// create bus -> branches link | ||
if (branch.getBus1() != null) { | ||
|
@@ -447,10 +465,10 @@ public void reportBalance(Reporter reporter) { | |
this, activeGeneration, activeLoad, reactiveGeneration, reactiveLoad); | ||
} | ||
|
||
public void fix(boolean minImpedance, boolean dc, double lowImpedanceThreshold) { | ||
public void fix(boolean minImpedance, double lowImpedanceThreshold) { | ||
if (minImpedance) { | ||
for (LfBranch branch : branches) { | ||
branch.setMinZ(dc, lowImpedanceThreshold); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should not do this here at a post loading fix. z cut could be done in a cleaner way at branch creation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It has been designed like that because min z what dependent of the AC or DC context. Now, as we store both, we can do that at branch creation. Do you want me to do this? |
||
branch.setMinZ(lowImpedanceThreshold); | ||
} | ||
} | ||
} | ||
|
@@ -496,7 +514,7 @@ public static <T> List<LfNetwork> load(T network, LfNetworkLoader<T> networkLoad | |
List<LfNetwork> lfNetworks = networkLoader.load(network, parameters, reporter); | ||
for (LfNetwork lfNetwork : lfNetworks) { | ||
Reporter reporterNetwork = Reports.createPostLoadingProcessingReporter(lfNetwork.getReporter()); | ||
lfNetwork.fix(parameters.isMinImpedance(), parameters.isDc(), parameters.getLowImpedanceThreshold()); | ||
lfNetwork.fix(parameters.isMinImpedance(), parameters.getLowImpedanceThreshold()); | ||
lfNetwork.validate(parameters.isDc(), reporterNetwork); | ||
if (lfNetwork.isValid()) { | ||
lfNetwork.reportSize(reporterNetwork); | ||
|
@@ -508,25 +526,60 @@ public static <T> List<LfNetwork> load(T network, LfNetworkLoader<T> networkLoad | |
return lfNetworks; | ||
} | ||
|
||
private static SpanningTreeAlgorithm.SpanningTree<LfBranch> createZeroImpedanceSpanningTree(Graph<LfBus, LfBranch> zeroImpedanceSubGraph, boolean dc) { | ||
if (!zeroImpedanceSubGraph.vertexSet().isEmpty()) { | ||
SpanningTreeAlgorithm.SpanningTree<LfBranch> spanningTree = new KruskalMinimumSpanningTree<>(zeroImpedanceSubGraph).getSpanningTree(); | ||
for (LfBranch branch : spanningTree.getEdges()) { | ||
branch.setSpanningTreeEdge(dc, true); | ||
} | ||
return spanningTree; | ||
} | ||
return null; | ||
} | ||
|
||
public void updateZeroImpedanceCache(boolean dc) { | ||
if (dc) { | ||
if (dcZeroImpedanceSubGraph == null) { | ||
dcZeroImpedanceSubGraph = createZeroImpedanceSubGraph(true); | ||
dcZeroImpedanceSpanningTree = createZeroImpedanceSpanningTree(dcZeroImpedanceSubGraph, true); | ||
} | ||
} else { | ||
if (acZeroImpedanceSubGraph == null) { | ||
acZeroImpedanceSubGraph = createZeroImpedanceSubGraph(false); | ||
acZeroImpedanceSpanningTree = createZeroImpedanceSpanningTree(acZeroImpedanceSubGraph, false); | ||
} | ||
} | ||
} | ||
|
||
public Graph<LfBus, LfBranch> getZeroImpedanceSubGraph(boolean dc) { | ||
updateZeroImpedanceCache(dc); | ||
return dc ? dcZeroImpedanceSubGraph : acZeroImpedanceSubGraph; | ||
} | ||
|
||
public SpanningTreeAlgorithm.SpanningTree<LfBranch> getZeroImpedanceSpanningTree(boolean dc) { | ||
updateZeroImpedanceCache(dc); | ||
return dc ? dcZeroImpedanceSpanningTree : acZeroImpedanceSpanningTree; | ||
} | ||
|
||
/** | ||
* Create the subgraph of zero-impedance LfBranches and their corresponding LfBuses | ||
* The graph is intentionally not cached as a parameter so far, to avoid the complexity of invalidating it if changes occur | ||
* Create the subgraph of zero-impedance LfBranches and their corresponding LfBuses. | ||
* | ||
* @return the zero-impedance subgraph | ||
*/ | ||
public Graph<LfBus, LfBranch> createZeroImpedanceSubGraph() { | ||
return createSubGraph(branch -> branch.isZeroImpedance() | ||
private Graph<LfBus, LfBranch> createZeroImpedanceSubGraph(boolean dc) { | ||
return createSubGraph(branch -> branch.isZeroImpedance(dc) | ||
&& branch.getBus1() != null && branch.getBus2() != null); | ||
} | ||
|
||
public Graph<LfBus, LfBranch> createSubGraph(Predicate<LfBranch> branchFilter) { | ||
private Graph<LfBus, LfBranch> createSubGraph(Predicate<LfBranch> branchFilter) { | ||
Objects.requireNonNull(branchFilter); | ||
|
||
List<LfBranch> zeroImpedanceBranches = getBranches().stream() | ||
List<LfBranch> filteredBranches = getBranches().stream() | ||
.filter(branchFilter) | ||
.collect(Collectors.toList()); | ||
|
||
Graph<LfBus, LfBranch> subGraph = new Pseudograph<>(LfBranch.class); | ||
for (LfBranch branch : zeroImpedanceBranches) { | ||
for (LfBranch branch : filteredBranches) { | ||
subGraph.addVertex(branch.getBus1()); | ||
subGraph.addVertex(branch.getBus2()); | ||
subGraph.addEdge(branch.getBus1(), branch.getBus2(), branch); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe zeroImpedanceSubGraph and zeroImpedanceSpanningTree could be grouped in another object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it could be a good idea.