|
8 | 8 | import static edu.ie3.datamodel.utils.validation.UniquenessValidationUtils.checkAssetUniqueness; |
9 | 9 | import static edu.ie3.datamodel.utils.validation.UniquenessValidationUtils.checkUniqueEntities; |
10 | 10 |
|
11 | | -import edu.ie3.datamodel.exceptions.*; |
| 11 | +import edu.ie3.datamodel.exceptions.DuplicateEntitiesException; |
| 12 | +import edu.ie3.datamodel.exceptions.InvalidEntityException; |
| 13 | +import edu.ie3.datamodel.exceptions.InvalidGridException; |
| 14 | +import edu.ie3.datamodel.exceptions.ValidationException; |
| 15 | +import edu.ie3.datamodel.models.OperationTime; |
12 | 16 | import edu.ie3.datamodel.models.input.AssetInput; |
13 | 17 | import edu.ie3.datamodel.models.input.MeasurementUnitInput; |
14 | 18 | import edu.ie3.datamodel.models.input.NodeInput; |
15 | | -import edu.ie3.datamodel.models.input.connector.*; |
| 19 | +import edu.ie3.datamodel.models.input.connector.ConnectorInput; |
| 20 | +import edu.ie3.datamodel.models.input.connector.LineInput; |
| 21 | +import edu.ie3.datamodel.models.input.connector.Transformer3WInput; |
16 | 22 | import edu.ie3.datamodel.models.input.container.*; |
17 | 23 | import edu.ie3.datamodel.models.input.graphics.GraphicInput; |
18 | 24 | import edu.ie3.datamodel.models.input.system.SystemParticipantInput; |
19 | 25 | import edu.ie3.datamodel.utils.ContainerUtils; |
20 | 26 | import edu.ie3.datamodel.utils.Try; |
21 | | -import edu.ie3.datamodel.utils.Try.*; |
| 27 | +import edu.ie3.datamodel.utils.Try.Failure; |
| 28 | +import edu.ie3.datamodel.utils.Try.Success; |
| 29 | +import java.time.ZonedDateTime; |
22 | 30 | import java.util.*; |
| 31 | +import java.util.function.Predicate; |
| 32 | +import java.util.stream.Collectors; |
23 | 33 | import java.util.stream.Stream; |
| 34 | +import org.jgrapht.Graph; |
| 35 | +import org.jgrapht.alg.connectivity.ConnectivityInspector; |
| 36 | +import org.jgrapht.graph.DefaultEdge; |
| 37 | +import org.jgrapht.graph.SimpleGraph; |
24 | 38 |
|
25 | 39 | public class GridContainerValidationUtils extends ValidationUtils { |
26 | 40 |
|
@@ -155,9 +169,105 @@ private GridContainerValidationUtils() { |
155 | 169 | exceptions.add(MeasurementUnitValidationUtils.check(measurement)); |
156 | 170 | }); |
157 | 171 |
|
| 172 | + exceptions.addAll(checkConnectivity(rawGridElements)); |
| 173 | + |
158 | 174 | return exceptions; |
159 | 175 | } |
160 | 176 |
|
| 177 | + /** |
| 178 | + * Checks the connectivity of the given grid for all defined {@link OperationTime}s. If every |
| 179 | + * {@link AssetInput} is set to {@link OperationTime#notLimited()}, the connectivity is only |
| 180 | + * checked once. |
| 181 | + * |
| 182 | + * @param rawGridElements to check |
| 183 | + * @return a try |
| 184 | + */ |
| 185 | + protected static List<Try<Void, InvalidGridException>> checkConnectivity( |
| 186 | + RawGridElements rawGridElements) { |
| 187 | + Set<ZonedDateTime> times = |
| 188 | + rawGridElements.allEntitiesAsList().stream() |
| 189 | + .map(AssetInput::getOperationTime) |
| 190 | + .filter(OperationTime::isLimited) |
| 191 | + .map(OperationTime::getOperationLimit) |
| 192 | + .filter(Optional::isPresent) |
| 193 | + .map(Optional::get) |
| 194 | + .map(interval -> Set.of(interval.getLower(), interval.getUpper())) |
| 195 | + .flatMap(Collection::stream) |
| 196 | + .collect(Collectors.toSet()); |
| 197 | + |
| 198 | + if (times.isEmpty()) { |
| 199 | + return List.of(checkConnectivity(rawGridElements, Optional.empty())); |
| 200 | + } else { |
| 201 | + return times.stream() |
| 202 | + .sorted() |
| 203 | + .map(time -> checkConnectivity(rawGridElements, Optional.of(time))) |
| 204 | + .toList(); |
| 205 | + } |
| 206 | + } |
| 207 | + |
| 208 | + /** |
| 209 | + * Checks if the given {@link RawGridElements} from a connected grid. |
| 210 | + * |
| 211 | + * @param rawGridElements to check |
| 212 | + * @param time for operation filtering |
| 213 | + * @return a try |
| 214 | + */ |
| 215 | + protected static Try<Void, InvalidGridException> checkConnectivity( |
| 216 | + RawGridElements rawGridElements, Optional<ZonedDateTime> time) { |
| 217 | + |
| 218 | + Predicate<AssetInput> isInOperation = |
| 219 | + assetInput -> time.map(assetInput::inOperationOn).orElse(true); |
| 220 | + |
| 221 | + // build graph |
| 222 | + Graph<UUID, DefaultEdge> graph = new SimpleGraph<>(DefaultEdge.class); |
| 223 | + |
| 224 | + rawGridElements.getNodes().stream() |
| 225 | + .filter(isInOperation) |
| 226 | + .forEach(node -> graph.addVertex(node.getUuid())); |
| 227 | + rawGridElements.getLines().stream() |
| 228 | + .filter(isInOperation) |
| 229 | + .forEach( |
| 230 | + connector -> |
| 231 | + graph.addEdge(connector.getNodeA().getUuid(), connector.getNodeB().getUuid())); |
| 232 | + rawGridElements.getTransformer2Ws().stream() |
| 233 | + .filter(isInOperation) |
| 234 | + .forEach( |
| 235 | + connector -> |
| 236 | + graph.addEdge(connector.getNodeA().getUuid(), connector.getNodeB().getUuid())); |
| 237 | + rawGridElements.getTransformer3Ws().stream() |
| 238 | + .filter(isInOperation) |
| 239 | + .forEach( |
| 240 | + connector -> |
| 241 | + graph.addEdge(connector.getNodeA().getUuid(), connector.getNodeB().getUuid())); |
| 242 | + rawGridElements.getSwitches().stream() |
| 243 | + .filter(isInOperation) |
| 244 | + .forEach( |
| 245 | + connector -> |
| 246 | + graph.addEdge(connector.getNodeA().getUuid(), connector.getNodeB().getUuid())); |
| 247 | + |
| 248 | + ConnectivityInspector<UUID, DefaultEdge> inspector = new ConnectivityInspector<>(graph); |
| 249 | + |
| 250 | + if (inspector.isConnected()) { |
| 251 | + return Success.empty(); |
| 252 | + } else { |
| 253 | + List<Set<UUID>> sets = inspector.connectedSets(); |
| 254 | + |
| 255 | + List<UUID> unconnected = |
| 256 | + sets.stream() |
| 257 | + .max(Comparator.comparing(Set::size)) |
| 258 | + .map(set -> graph.vertexSet().stream().filter(v -> !set.contains(v)).toList()) |
| 259 | + .orElse(List.of()); |
| 260 | + |
| 261 | + String message = "The grid contains unconnected elements"; |
| 262 | + |
| 263 | + if (time.isPresent()) { |
| 264 | + message += " for time " + time.get(); |
| 265 | + } |
| 266 | + |
| 267 | + return Failure.of(new InvalidGridException(message + ": " + unconnected)); |
| 268 | + } |
| 269 | + } |
| 270 | + |
161 | 271 | /** |
162 | 272 | * Checks the validity of each and every system participant. Moreover, it checks, if the systems |
163 | 273 | * are connected to a node that is not in the provided set |
|
0 commit comments