|
10 | 10 | import com.powsybl.iidm.network.*; |
11 | 11 | import com.powsybl.iidm.network.extensions.*; |
12 | 12 | import com.powsybl.math.graph.TraversalType; |
| 13 | +import lombok.NonNull; |
13 | 14 | import org.gridsuite.network.map.dto.common.*; |
14 | 15 | import org.gridsuite.network.map.dto.definition.extension.*; |
15 | 16 | import org.gridsuite.network.map.dto.definition.threewindingstransformer.ThreeWindingsTransformerTabInfos; |
| 17 | +import org.springframework.lang.Nullable; |
16 | 18 | import org.springframework.util.CollectionUtils; |
17 | 19 |
|
18 | | -import java.util.ArrayList; |
19 | 20 | import java.util.Collection; |
20 | 21 | import java.util.HashMap; |
21 | 22 | import java.util.List; |
|
24 | 25 | import java.util.function.Consumer; |
25 | 26 | import java.util.function.Function; |
26 | 27 | import java.util.stream.Collectors; |
| 28 | +import java.util.stream.Stream; |
27 | 29 |
|
28 | 30 | import static org.gridsuite.network.map.dto.common.CurrentLimitsData.Applicability.*; |
29 | 31 |
|
@@ -93,85 +95,55 @@ public static void buildCurrentLimits(Collection<OperationalLimitsGroup> current |
93 | 95 | } |
94 | 96 | } |
95 | 97 |
|
96 | | - private static CurrentLimitsData copyCurrentLimitsData(CurrentLimitsData currentLimitsData, CurrentLimitsData.Applicability applicability) { |
97 | | - return CurrentLimitsData.builder() |
98 | | - .id(currentLimitsData.getId()) |
99 | | - .applicability(applicability) |
100 | | - .temporaryLimits(currentLimitsData.getTemporaryLimits()) |
101 | | - .permanentLimit(currentLimitsData.getPermanentLimit()).build(); |
102 | | - } |
103 | | - |
104 | 98 | /** |
| 99 | + * Combine 2 sides in one list. |
105 | 100 | * @return id of the selected operation limits group 1 and 2 if they have been renamed |
106 | 101 | */ |
107 | | - public static void mergeCurrentLimits(Collection<OperationalLimitsGroup> operationalLimitsGroups1, |
108 | | - Collection<OperationalLimitsGroup> operationalLimitsGroups2, |
109 | | - Consumer<List<CurrentLimitsData>> build) { |
110 | | - List<CurrentLimitsData> mergedLimitsData = new ArrayList<>(); |
111 | | - |
| 102 | + @Nullable |
| 103 | + public static List<CurrentLimitsData> mergeCurrentLimits(@NonNull final Collection<OperationalLimitsGroup> operationalLimitsGroups1, |
| 104 | + @NonNull final Collection<OperationalLimitsGroup> operationalLimitsGroups2) { |
112 | 105 | // Build temporary limit from side 1 and 2 |
113 | | - List<CurrentLimitsData> currentLimitsData1 = operationalLimitsGroups1.stream() |
114 | | - .map(ElementUtils::operationalLimitsGroupToMapDataCurrentLimits).toList(); |
115 | | - ArrayList<CurrentLimitsData> currentLimitsData2 = new ArrayList<>(operationalLimitsGroups2.stream() |
116 | | - .map(ElementUtils::operationalLimitsGroupToMapDataCurrentLimits).toList()); |
117 | | - |
118 | | - // combine 2 sides in one list |
| 106 | + final List<CurrentLimitsData> currentLimitsData1 = operationalLimitsGroups1.stream() |
| 107 | + .map(operationalLimitsGroup -> operationalLimitsGroupToMapDataCurrentLimits(operationalLimitsGroup).setApplicability(SIDE1)) |
| 108 | + .toList(); |
| 109 | + final List<CurrentLimitsData> currentLimitsData2 = operationalLimitsGroups2.stream() |
| 110 | + .map(operationalLimitsGroup -> operationalLimitsGroupToMapDataCurrentLimits(operationalLimitsGroup).setApplicability(SIDE2)) |
| 111 | + .toList(); |
119 | 112 |
|
120 | 113 | // simple case : one of the arrays are empty |
121 | 114 | if (currentLimitsData2.isEmpty() && !currentLimitsData1.isEmpty()) { |
122 | | - for (CurrentLimitsData currentLimitsData : currentLimitsData1) { |
123 | | - mergedLimitsData.add(copyCurrentLimitsData(currentLimitsData, SIDE1)); |
124 | | - } |
125 | | - build.accept(mergedLimitsData); |
126 | | - return; |
| 115 | + return currentLimitsData1; |
127 | 116 | } |
128 | 117 | if (currentLimitsData1.isEmpty() && !currentLimitsData2.isEmpty()) { |
129 | | - for (CurrentLimitsData currentLimitsData : currentLimitsData2) { |
130 | | - mergedLimitsData.add(copyCurrentLimitsData(currentLimitsData, SIDE2)); |
131 | | - } |
132 | | - build.accept(mergedLimitsData); |
133 | | - return; |
| 118 | + return currentLimitsData2; |
134 | 119 | } |
135 | 120 |
|
136 | 121 | // more complex case |
137 | | - for (CurrentLimitsData limitsData : currentLimitsData1) { |
138 | | - Optional<CurrentLimitsData> l2 = currentLimitsData2.stream().filter(l -> l.getId().equals(limitsData.getId())).findFirst(); |
139 | | - |
140 | | - if (l2.isPresent()) { |
141 | | - CurrentLimitsData limitsData2 = l2.get(); |
142 | | - // Only side one has limits |
143 | | - if (limitsData.hasLimits() && !limitsData2.hasLimits()) { |
144 | | - mergedLimitsData.add(copyCurrentLimitsData(limitsData, SIDE1)); |
145 | | - // only side two has limits |
146 | | - } else if (limitsData2.hasLimits() && !limitsData.hasLimits()) { |
147 | | - mergedLimitsData.add(copyCurrentLimitsData(limitsData2, SIDE2)); |
148 | | - } else { |
149 | | - // both sides have limits and limits are equals |
150 | | - if (limitsData.limitsEquals(limitsData2)) { |
151 | | - mergedLimitsData.add(copyCurrentLimitsData(limitsData, EQUIPMENT)); |
152 | | - // both side have limits and they are different : create 2 different limit sets |
153 | | - } else { |
154 | | - // Side 1 |
155 | | - mergedLimitsData.add(copyCurrentLimitsData(limitsData, SIDE1)); |
156 | | - // Side 2 |
157 | | - mergedLimitsData.add(copyCurrentLimitsData(limitsData2, SIDE2)); |
| 122 | + return Stream.concat(currentLimitsData1.stream(), currentLimitsData2.stream()) |
| 123 | + .collect(Collectors.groupingByConcurrent(CurrentLimitsData::getId)) |
| 124 | + .values() |
| 125 | + .parallelStream() |
| 126 | + .<CurrentLimitsData>mapMulti((currentLimitsData, acc) -> { |
| 127 | + if (currentLimitsData.isEmpty() || currentLimitsData.size() > 2) { |
| 128 | + throw new UnsupportedOperationException("IDs are assumed unique in each lists"); |
| 129 | + } else if (currentLimitsData.size() == 2) { |
| 130 | + final CurrentLimitsData limitsData = currentLimitsData.get(0); |
| 131 | + final CurrentLimitsData limitsData2 = currentLimitsData.get(1); |
| 132 | + if (limitsData.hasLimits() && !limitsData2.hasLimits()) { // Only side one has limits |
| 133 | + acc.accept(limitsData); |
| 134 | + return; |
| 135 | + } else if (limitsData2.hasLimits() && !limitsData.hasLimits()) { // only side two has limits |
| 136 | + acc.accept(limitsData2); |
| 137 | + return; |
| 138 | + } else if (limitsData.limitsEquals(limitsData2)) { // both sides have limits and limits are equals |
| 139 | + acc.accept(limitsData.setApplicability(EQUIPMENT)); |
| 140 | + return; |
158 | 141 | } |
| 142 | + // both side have limits and are different: create 2 different limit sets |
159 | 143 | } |
160 | | - // remove processed limits from side 2 |
161 | | - currentLimitsData2.remove(l2.get()); |
162 | | - } else { |
163 | | - mergedLimitsData.add(copyCurrentLimitsData(limitsData, SIDE1)); |
164 | | - } |
165 | | - } |
166 | | - |
167 | | - // add remaining limits from side 2 |
168 | | - for (CurrentLimitsData limitsData : currentLimitsData2) { |
169 | | - mergedLimitsData.add(copyCurrentLimitsData(limitsData, SIDE2)); |
170 | | - } |
171 | | - |
172 | | - if (!mergedLimitsData.isEmpty()) { |
173 | | - build.accept(mergedLimitsData); |
174 | | - } |
| 144 | + currentLimitsData.forEach(acc); |
| 145 | + }) |
| 146 | + .toList(); |
175 | 147 | } |
176 | 148 |
|
177 | 149 | public static Optional<StandbyAutomatonInfos> toStandbyAutomaton(StaticVarCompensator staticVarCompensator) { |
|
0 commit comments