|
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