Skip to content

Commit a984abb

Browse files
committed
looks good
1 parent 6a5cec7 commit a984abb

File tree

4 files changed

+124
-132
lines changed

4 files changed

+124
-132
lines changed

network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/AbstractTopology.java

+36-56
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77
package com.powsybl.network.store.iidm.impl;
88

9-
import com.google.common.util.concurrent.AtomicDouble;
109
import com.powsybl.commons.config.PlatformConfig;
1110
import com.powsybl.iidm.network.*;
1211
import com.powsybl.network.store.model.*;
@@ -17,7 +16,6 @@
1716
import org.jgrapht.graph.DirectedPseudograph;
1817

1918
import java.util.*;
20-
import java.util.concurrent.atomic.AtomicReference;
2119
import java.util.stream.Collectors;
2220

2321
/**
@@ -362,63 +360,50 @@ private void setCalculatedBuses(Resource<VoltageLevelAttributes> voltageLevelRes
362360
}
363361
}
364362

365-
private void getVAndAngleFromConfiguredBus(NetworkObjectIndex index,
366-
Resource<VoltageLevelAttributes> voltageLevelResource,
367-
ConnectedSetResult<T> connectedSet,
368-
AtomicDouble v,
369-
AtomicDouble angle) {
370-
// Search with early return for a first configured bus with a connected terminal matching a vertex in the connectedSet of this bus
371-
for (Bus bus: index.getConfiguredBuses(voltageLevelResource.getId())) {
372-
ConfiguredBusImpl configuredBus = (ConfiguredBusImpl) bus;
373-
for (Terminal t: configuredBus.getAllTerminals()) {
374-
if (t.isConnected()) {
375-
for (Vertex vertex: connectedSet.getConnectedVertices()) {
376-
if (vertex.getId().equals(t.getConnectable().getId())) {
377-
v.set(configuredBus.getResource().getAttributes().getV());
378-
angle.set(configuredBus.getResource().getAttributes().getAngle());
379-
return;
380-
}
363+
private CalculatedBusAttributes findFirstMatchingNodeBreakerCalculatedBusAttributes(Resource<VoltageLevelAttributes> voltageLevelResource,
364+
ConnectedSetResult<T> connectedSet, boolean isBusView) {
365+
// TODO Some day we may decide to start preserving values in nodebreaker topology after invalidating the views,
366+
// so we could remove this check for isCalculatedBusesValid. Here it controls preserving
367+
// the value accross the other view, we have it to be consistent with preserving values
368+
// from the same view (currently not preserved)
369+
if (voltageLevelResource.getAttributes().isCalculatedBusesValid()) {
370+
List<CalculatedBusAttributes> calculatedBusAttributes = isBusView ? voltageLevelResource.getAttributes().getCalculatedBusesForBusBreakerView() : voltageLevelResource.getAttributes().getCalculatedBusesForBusView();
371+
if (!CollectionUtils.isEmpty(calculatedBusAttributes)) {
372+
Map<Integer, Integer> nodesToCalculatedBuses = isBusView ? voltageLevelResource.getAttributes().getNodeToCalculatedBusForBusBreakerView() : voltageLevelResource.getAttributes().getNodeToCalculatedBusForBusView();
373+
if (!MapUtils.isEmpty(nodesToCalculatedBuses)) {
374+
Integer node = (Integer) connectedSet.getConnectedNodesOrBuses().iterator().next(); // non deterministic
375+
Integer busNum = nodesToCalculatedBuses.get(node);
376+
if (busNum != null) {
377+
return calculatedBusAttributes.get(busNum);
381378
}
382379
}
383380
}
384381
}
382+
return null;
385383
}
386384

387-
private void getVAndAngleFromOtherView(NetworkObjectIndex index,
385+
private CalculatedBusAttributes createCalculatedBusAttributesWithVAndAngle(NetworkObjectIndex index,
388386
Resource<VoltageLevelAttributes> voltageLevelResource,
389387
ConnectedSetResult<T> connectedSet,
390-
AtomicDouble v,
391-
AtomicDouble angle,
392388
boolean isBusView) {
389+
double v = Double.NaN;
390+
double angle = Double.NaN;
393391
if (voltageLevelResource.getAttributes().getTopologyKind() == TopologyKind.NODE_BREAKER) {
394-
if (!voltageLevelResource.getAttributes().isCalculatedBusesValid()) {
395-
// TODO Some day we may decide to start preserving values in nodebreaker topology after invalidating the views,
396-
// so we could remove this check for isCalculatedBusesValid. Here it controls preserving
397-
// the value accross the other view, we have it to be consistent with preserving values
398-
// from the same view (currently not preserved)
399-
return;
400-
}
401-
List<CalculatedBusAttributes> calculatedBusAttributes = isBusView ? voltageLevelResource.getAttributes().getCalculatedBusesForBusBreakerView() : voltageLevelResource.getAttributes().getCalculatedBusesForBusView();
402-
if (!CollectionUtils.isEmpty(calculatedBusAttributes)) {
403-
Map<Integer, Integer> nodesToCalculatedBuses = isBusView ? voltageLevelResource.getAttributes().getNodeToCalculatedBusForBusBreakerView() : voltageLevelResource.getAttributes().getNodeToCalculatedBusForBusView();
404-
if (!MapUtils.isEmpty(nodesToCalculatedBuses)) {
405-
Integer node = (Integer) connectedSet.getConnectedNodesOrBuses().iterator().next();
406-
Integer busNum = nodesToCalculatedBuses.get(node);
407-
if (busNum != null) {
408-
CalculatedBusAttributes busAttributes = calculatedBusAttributes.get(busNum);
409-
if (busAttributes != null) {
410-
v.set(busAttributes.getV());
411-
angle.set(busAttributes.getAngle());
412-
}
413-
}
414-
}
392+
CalculatedBusAttributes busAttributes = findFirstMatchingNodeBreakerCalculatedBusAttributes(voltageLevelResource, connectedSet, isBusView);
393+
if (busAttributes != null) {
394+
v = busAttributes.getV();
395+
angle = busAttributes.getAngle();
415396
}
416-
} else {
397+
} else { // BUS_BREAKER
417398
// currently for busbreakertopology the values are always preserved
418399
// when using only the busbreakerview. So mimic the behavior and always preserve them
419400
// when using the busview: get V and Angle values from configured buses
420-
getVAndAngleFromConfiguredBus(index, voltageLevelResource, connectedSet, v, angle);
401+
String configuredBusId = ((ConnectedSetResult<String>) connectedSet).getConnectedNodesOrBuses().iterator().next(); // nondeterministic
402+
Bus b = index.getConfiguredBus(configuredBusId).orElseThrow();
403+
v = b.getV();
404+
angle = b.getAngle();
421405
}
406+
return new CalculatedBusAttributes(connectedSet.getConnectedVertices(), null, null, v, angle);
422407
}
423408

424409
private CalculationResult<T> getCalculatedBusAttributesList(NetworkObjectIndex index, Resource<VoltageLevelAttributes> voltageLevelResource, boolean isBusView) {
@@ -432,18 +417,13 @@ private CalculationResult<T> getCalculatedBusAttributesList(NetworkObjectIndex i
432417
List<ConnectedSetResult<T>> connectedSetList = findConnectedSetList(index, voltageLevelResource, isBusView);
433418
calculatedBusAttributesList = connectedSetList
434419
.stream()
435-
.map(connectedSet -> {
436-
AtomicDouble v = new AtomicDouble(Double.NaN);
437-
AtomicDouble angle = new AtomicDouble(Double.NaN);
438-
//TODO in this case in nodebreaker topology we currently don't preserve any values from
439-
//the same view if it was already computed but is invalidated.
440-
//we could do it some day (we need to define good heuristics to
441-
//match previous values to new buses).
442-
//NOTE: We chose to have the same behavior when getting the values from the other view
443-
// get V and Angle values from other view if available
444-
getVAndAngleFromOtherView(index, voltageLevelResource, connectedSet, v, angle, isBusView);
445-
return new CalculatedBusAttributes(connectedSet.getConnectedVertices(), null, null, v.get(), angle.get());
446-
})
420+
//TODO in this case in nodebreaker topology we currently don't preserve any values from
421+
//the same view if it was already computed but is invalidated.
422+
//we could do it some day (we need to define good heuristics to
423+
//match previous values to new buses).
424+
//NOTE: We chose to have the same behavior when getting the values from the other view
425+
// get V and Angle values from other view if available
426+
.map(connectedSet -> createCalculatedBusAttributesWithVAndAngle(index, voltageLevelResource, connectedSet, isBusView))
447427
.collect(Collectors.toList());
448428
setCalculatedBuses(voltageLevelResource, isBusView, calculatedBusAttributesList);
449429

network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/CalculatedBus.java

+28-54
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
import org.apache.commons.collections4.MapUtils;
2020

2121
import java.util.*;
22+
import java.util.Map.Entry;
2223
import java.util.function.Function;
2324
import java.util.function.ObjDoubleConsumer;
2425
import java.util.function.Predicate;
25-
import java.util.function.ToDoubleFunction;
2626
import java.util.stream.Collectors;
2727
import java.util.stream.Stream;
2828

@@ -52,9 +52,6 @@ public final class CalculatedBus implements BaseBus {
5252

5353
private final Function<Terminal, Bus> getBusFromTerminal;
5454

55-
private static final String VOLTAGE = "v";
56-
private static final String ANGLE = "angle";
57-
5855
CalculatedBus(NetworkObjectIndex index, String voltageLevelId, String id, String name, Resource<VoltageLevelAttributes> voltageLevelResource,
5956
int calculatedBusNum, boolean isBusView) {
6057
this.index = Objects.requireNonNull(index);
@@ -142,24 +139,16 @@ private void setVInCalculatedBus(CalculatedBusAttributes calculatedBusAttributes
142139
calculatedBusAttributes.setV(value);
143140
}
144141

145-
private void setVInConfiguredBus(ConfiguredBusAttributes configuredBusAttributes, double value) {
146-
configuredBusAttributes.setV(value);
147-
}
148-
149-
private double getVInBus(Bus bus) {
150-
return bus.getV();
142+
private void setVInConfiguredBus(ConfiguredBusImpl configuredBus, double value) {
143+
configuredBus.setConfiguredBusV(value);
151144
}
152145

153146
private void setAngleInCalculatedBus(CalculatedBusAttributes calculatedBusAttributes, double value) {
154147
calculatedBusAttributes.setAngle(value);
155148
}
156149

157-
private void setAngleInConfiguredBus(ConfiguredBusAttributes configuredBusAttributes, double value) {
158-
configuredBusAttributes.setAngle(value);
159-
}
160-
161-
private double getAngleInBus(Bus bus) {
162-
return bus.getAngle();
150+
private void setAngleInConfiguredBus(ConfiguredBusImpl configuredBus, double value) {
151+
configuredBus.setConfiguredBusAngle(value);
163152
}
164153

165154
@Override
@@ -169,7 +158,8 @@ public Bus setV(double v) {
169158

170159
if (getVoltageLevel().getTopologyKind() == TopologyKind.BUS_BREAKER) {
171160
// update V in configured buses
172-
updateConfiguredBuses(v, VOLTAGE, this::getVInBus, this::setVInConfiguredBus);
161+
// this triggers network notifications for 'v' for each configured bus
162+
updateConfiguredBuses(v, this::setVInConfiguredBus);
173163
} else {
174164
// update V for buses in the other view (busView/busBreakerView)
175165
updateBusesAttributes(v, this::setVInCalculatedBus);
@@ -189,7 +179,8 @@ public Bus setAngle(double angle) {
189179

190180
if (getVoltageLevel().getTopologyKind() == TopologyKind.BUS_BREAKER) {
191181
// update angle in configuredBus
192-
updateConfiguredBuses(angle, ANGLE, this::getAngleInBus, this::setAngleInConfiguredBus);
182+
// this triggers network notifications for 'angle' for each configured bus
183+
updateConfiguredBuses(angle, this::setAngleInConfiguredBus);
193184
} else {
194185
// update angle for buses in the other view (busView/busBreakerView)
195186
updateBusesAttributes(angle, this::setAngleInCalculatedBus);
@@ -520,20 +511,19 @@ public int getCalculatedBusNum() {
520511
}
521512

522513
private void updateBusesAttributes(double value, ObjDoubleConsumer<CalculatedBusAttributes> setValue) {
514+
// busnum of this bus -> nodes in this bus -> busnums in the other view -> buses of the other view
523515
VoltageLevelAttributes vlAttributes = ((VoltageLevelImpl) getVoltageLevel()).getResource().getAttributes();
524516
Map<Integer, Integer> nodesToCalculatedBuses = isBusView
525517
? vlAttributes.getNodeToCalculatedBusForBusView()
526518
: vlAttributes.getNodeToCalculatedBusForBusBreakerView();
527-
if (!MapUtils.isEmpty(nodesToCalculatedBuses)) {
528-
nodesToCalculatedBuses.entrySet().stream()
529-
.filter(entry -> getCalculatedBusNum() == entry.getValue())
530-
.map(Map.Entry::getKey)
531-
.forEach(node -> {
532-
Map<Integer, Integer> nodesToCalculatedBusesInOtherView = isBusView
533-
? vlAttributes.getNodeToCalculatedBusForBusBreakerView()
534-
: vlAttributes.getNodeToCalculatedBusForBusView();
535-
if (!MapUtils.isEmpty(nodesToCalculatedBusesInOtherView) &&
536-
nodesToCalculatedBusesInOtherView.containsKey(node)) {
519+
Map<Integer, Integer> nodesToCalculatedBusesInOtherView = isBusView
520+
? vlAttributes.getNodeToCalculatedBusForBusBreakerView()
521+
: vlAttributes.getNodeToCalculatedBusForBusView();
522+
if (!MapUtils.isEmpty(nodesToCalculatedBuses) && !MapUtils.isEmpty(nodesToCalculatedBusesInOtherView)) {
523+
for (Entry<Integer, Integer> entry : nodesToCalculatedBuses.entrySet()) {
524+
if (getCalculatedBusNum() == entry.getValue()) {
525+
int node = entry.getKey();
526+
if (nodesToCalculatedBusesInOtherView.containsKey(node)) {
537527
int busNumInOtherView = nodesToCalculatedBusesInOtherView.get(node);
538528
List<CalculatedBusAttributes> calculatedBusAttributes = isBusView
539529
? vlAttributes.getCalculatedBusesForBusBreakerView()
@@ -543,35 +533,19 @@ private void updateBusesAttributes(double value, ObjDoubleConsumer<CalculatedBus
543533
index.updateVoltageLevelResource(voltageLevelResource, AttributeFilter.SV);
544534
}
545535
}
546-
});
536+
}
537+
}
547538
}
548539
}
549540

550541
private void updateConfiguredBuses(double newValue,
551-
String attributeName,
552-
ToDoubleFunction<Bus> getValue,
553-
ObjDoubleConsumer<ConfiguredBusAttributes> setValue) {
554-
List<Bus> buses = ((VoltageLevelImpl) getVoltageLevel()).getResource().getAttributes()
555-
.getBusToCalculatedBusForBusView().entrySet().stream()
556-
.filter(entry -> getCalculatedBusNum() == entry.getValue())
557-
.map(Map.Entry::getKey)
558-
.map(getVoltageLevel().getBusBreakerView()::getBus)
559-
.toList();
560-
561-
Map<Bus, Map.Entry<Double, Double>> oldNewValues = buses.stream()
562-
.collect(Collectors.toMap(
563-
bus -> bus,
564-
bus -> new AbstractMap.SimpleEntry<>(getValue.applyAsDouble(bus), newValue)
565-
));
566-
567-
buses.forEach(bus -> {
568-
setValue.accept(((ConfiguredBusImpl) bus).getResource().getAttributes(), newValue);
569-
index.updateConfiguredBusResource(((ConfiguredBusImpl) bus).getResource(), null);
570-
});
571-
572-
String variantId = index.getNetwork().getVariantManager().getWorkingVariantId();
573-
oldNewValues.forEach((bus, oldNewValue) ->
574-
index.notifyUpdate(bus, attributeName, variantId, oldNewValue.getKey(), oldNewValue.getValue())
575-
);
542+
ObjDoubleConsumer<ConfiguredBusImpl> setValue) {
543+
VoltageLevelAttributes vlAttributes = ((VoltageLevelImpl) getVoltageLevel()).getResource().getAttributes();
544+
for (Entry<String, Integer> entry : vlAttributes.getBusToCalculatedBusForBusView().entrySet()) {
545+
if (getCalculatedBusNum() == entry.getValue()) {
546+
Bus bus = getVoltageLevel().getBusBreakerView().getBus(entry.getKey());
547+
setValue.accept((ConfiguredBusImpl) bus, newValue);
548+
}
549+
}
576550
}
577551
}

0 commit comments

Comments
 (0)