Skip to content

Commit ab1fc2c

Browse files
committed
Changed SubgridContainer to represent galvanically seperated grids
1 parent 05ec099 commit ab1fc2c

File tree

5 files changed

+11
-319
lines changed

5 files changed

+11
-319
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
### Changed
1515
- Updated dependabot workflow and added CODEOWNERS [#1328](https://github.com/ie3-institute/PowerSystemDataModel/issues/1328)
1616
- Extend azimuth angle range to [-180°, 180°] for PV inputs [#1330](https://github.com/ie3-institute/PowerSystemDataModel/issues/1330)
17+
- Changed `SubgridContainer` to represent galvanically seperated grids [#1226](https://github.com/ie3-institute/PowerSystemDataModel/issues/1226)
1718

1819
## [7.0.0] - 2025-05-08
1920

docs/readthedocs/models/input/grid/gridcontainer.md

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,6 @@ Why predominant?
2020
As of convention, the `SubGridContainers` hold also reference to the transformers leading to higher sub grids
2121
and their higher voltage coupling point.
2222

23-
![Sub grid boundary definition for transformers with upstream switchgear](../../../_static/figures/transformerWithSwitchGear.png)
24-
25-
Let's shed a more detailed light on the boundaries of a sub grid as of our definition.
26-
This especially is important, if the switchgear of the transformer is modeled in detail.
27-
We defined, that all nodes in upstream direction of the transformer, that are connected by switches *only* (therefore
28-
are within the switchgear) are counted towards the inferior sub grid structure (here "2"), although they belong to a
29-
different voltage level.
30-
This decision is taken, because we assume, that the interest to operate on the given switchgear will most likely be
31-
placed in the inferior grid structure.
32-
33-
The "real" coupling node A is not comprised in the sub grids node collection, but obviously has reference through the
34-
switch between nodes A and B.
35-
3623
A synoptic overview of both classes' attributes is given here:
3724

3825
## Attributes, Units and Remarks

src/main/java/edu/ie3/datamodel/utils/ContainerUtils.java

Lines changed: 5 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -426,41 +426,11 @@ public static GraphicElements filterForSubnet(GraphicElements input, int subnet)
426426
*/
427427
public static VoltageLevel determinePredominantVoltLvl(RawGridElements rawGrid, int subnet)
428428
throws InvalidGridException {
429-
/* Exclude all nodes, that are at the high voltage side of the transformer */
430-
Set<NodeInput> gridNodes = new HashSet<>(rawGrid.getNodes());
431-
gridNodes.removeAll(
432-
/* Remove all nodes, that are upstream of transformers, this comprises all those, that are connected by
433-
* switches */
434-
rawGrid.getTransformer2Ws().stream()
435-
.flatMap(
436-
transformer ->
437-
ContainerUtils.traverseAlongSwitchChain(transformer.getNodeA(), rawGrid)
438-
.stream())
439-
.collect(Collectors.toSet()));
440-
gridNodes.removeAll(
441-
rawGrid.getTransformer3Ws().stream()
442-
.flatMap(
443-
transformer -> {
444-
if (transformer.getNodeA().getSubnet() == subnet)
445-
return Stream.of(transformer.getNodeB(), transformer.getNodeC());
446-
else if (transformer.getNodeB().getSubnet() == subnet)
447-
return Stream.concat(
448-
ContainerUtils.traverseAlongSwitchChain(transformer.getNodeA(), rawGrid)
449-
.stream(),
450-
Stream.of(transformer.getNodeC(), transformer.getNodeInternal()));
451-
else
452-
return Stream.concat(
453-
ContainerUtils.traverseAlongSwitchChain(transformer.getNodeA(), rawGrid)
454-
.stream(),
455-
Stream.of(transformer.getNodeB(), transformer.getNodeInternal()));
456-
})
457-
.collect(Collectors.toSet()));
458-
459429
/* Build a mapping, which voltage level appears how often */
460430
Map<VoltageLevel, Long> voltageLevelCount =
461-
gridNodes.stream()
462-
.map(NodeInput::getVoltLvl)
463-
.collect(Collectors.groupingBy(voltLvl -> voltLvl, Collectors.counting()));
431+
rawGrid.getNodes().stream()
432+
.filter(n -> n.getSubnet() == subnet)
433+
.collect(Collectors.groupingBy(NodeInput::getVoltLvl, Collectors.counting()));
464434

465435
/* At this point only one voltage level should be apparent */
466436
int amountOfVoltLvl = voltageLevelCount.size();
@@ -677,14 +647,8 @@ private static TransformerSubGridContainers getSubGridContainers(
677647
RawGridElements rawGridElements,
678648
Map<Integer, SubGridContainer> subGrids)
679649
throws TopologyException {
680-
/* Get the sub grid container at port A - travel upstream as long as nodes are connected
681-
* _only_ by switches */
682-
NodeInput topNode = traverseAlongSwitchChain(transformer.getNodeA(), rawGridElements).getLast();
683-
if (Objects.isNull(topNode))
684-
throw new TopologyException(
685-
"Cannot find most upstream node of transformer '" + transformer + "'");
686-
687-
SubGridContainer containerA = subGrids.get(topNode.getSubnet());
650+
/* Get the sub grid container at port A */
651+
SubGridContainer containerA = subGrids.get(transformer.getNodeA().getSubnet());
688652

689653
/* Get the sub grid container at port B */
690654
SubGridContainer containerB = subGrids.get(transformer.getNodeB().getSubnet());
@@ -696,81 +660,6 @@ private static TransformerSubGridContainers getSubGridContainers(
696660
} else return new TransformerSubGridContainers(containerA, containerB);
697661
}
698662

699-
/**
700-
* Traversing along a chain of switches and return the traveled nodes. The end thereby is defined
701-
* by a node, that either is a dead end or is connected to any other type of connector (e.g.
702-
* lines, transformers) and therefore leads to other parts of a "real" grid. If the starting node
703-
* is not part of any switch, the starting node is returned.
704-
*
705-
* @param startNode Node that is meant to be the start of the switch chain
706-
* @param rawGridElements Elements of the pure grid structure.
707-
* @return The end node of the switch chain
708-
*/
709-
public static LinkedList<NodeInput> traverseAlongSwitchChain(
710-
NodeInput startNode, RawGridElements rawGridElements) {
711-
Set<NodeInput> possibleJunctions =
712-
Stream.concat(
713-
Stream.concat(
714-
rawGridElements.getLines().parallelStream(),
715-
rawGridElements.getTransformer2Ws().parallelStream()),
716-
rawGridElements.getTransformer3Ws().parallelStream())
717-
.flatMap(connector -> connector.allNodes().parallelStream())
718-
.collect(Collectors.toSet());
719-
return traverseAlongSwitchChain(startNode, rawGridElements.getSwitches(), possibleJunctions);
720-
}
721-
722-
/**
723-
* Traversing along a chain of switches and return the traveled nodes. The end thereby is defined
724-
* by a node, that either is a dead end or part of the provided node set. If the starting node is
725-
* not part of any switch, the starting node is returned.
726-
*
727-
* @param startNode Node that is meant to be the start of the switch chain
728-
* @param switches Set of available switches
729-
* @param possibleJunctions Set of nodes that denote possible junctions to "real" grid
730-
* @return The end node of the switch chain
731-
*/
732-
private static LinkedList<NodeInput> traverseAlongSwitchChain(
733-
NodeInput startNode, Set<SwitchInput> switches, Set<NodeInput> possibleJunctions) {
734-
LinkedList<NodeInput> traveledNodes = new LinkedList<>();
735-
traveledNodes.addFirst(startNode);
736-
737-
/* Get the switch, that is connected to the starting node and determine the next node */
738-
List<SwitchInput> nextSwitches =
739-
switches.stream().filter(switcher -> switcher.allNodes().contains(startNode)).toList();
740-
switch (nextSwitches.size()) {
741-
case 0:
742-
/* No further switch found -> Return the starting node */
743-
break;
744-
case 1:
745-
/* One next switch has been found -> Travel in this direction */
746-
SwitchInput nextSwitch = nextSwitches.get(0);
747-
Optional<NodeInput> candidateNodes =
748-
nextSwitch.allNodes().stream().filter(node -> node != startNode).findFirst();
749-
NodeInput nextNode =
750-
candidateNodes.orElseThrow(
751-
() ->
752-
new IllegalArgumentException(
753-
"There is no further node available at switch " + nextSwitch));
754-
if (possibleJunctions.contains(nextNode)) {
755-
/* This is a junction, leading to another Connector than a switch */
756-
traveledNodes.addLast(nextNode);
757-
} else {
758-
/* Add the traveled nodes to the nodes to be excluded, to avoid endless loops in cyclic switch topologies */
759-
HashSet<NodeInput> newNodesToExclude = new HashSet<>(possibleJunctions);
760-
newNodesToExclude.add(nextNode);
761-
HashSet<SwitchInput> newSwitches = new HashSet<>(switches);
762-
newSwitches.remove(nextSwitch);
763-
traveledNodes.addAll(traverseAlongSwitchChain(nextNode, newSwitches, newNodesToExclude));
764-
}
765-
break;
766-
default:
767-
throw new IllegalArgumentException(
768-
"Cannot traverse along switch chain, as there is a junction included at node "
769-
+ startNode);
770-
}
771-
return traveledNodes;
772-
}
773-
774663
/**
775664
* Combines a given collection of sub grid containers to a joint model. If the single models do
776665
* not fit together, exceptions are thrown.

src/main/java/edu/ie3/datamodel/utils/validation/GridContainerValidationUtils.java

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,13 @@
2020
import edu.ie3.datamodel.models.input.container.*;
2121
import edu.ie3.datamodel.models.input.graphics.GraphicInput;
2222
import edu.ie3.datamodel.models.input.system.SystemParticipantInput;
23-
import edu.ie3.datamodel.utils.ContainerUtils;
2423
import edu.ie3.datamodel.utils.Try;
2524
import edu.ie3.datamodel.utils.Try.Failure;
2625
import edu.ie3.datamodel.utils.Try.Success;
2726
import java.time.ZonedDateTime;
2827
import java.util.*;
2928
import java.util.function.Predicate;
3029
import java.util.stream.Collectors;
31-
import java.util.stream.Stream;
3230
import org.jgrapht.Graph;
3331
import org.jgrapht.alg.connectivity.ConnectivityInspector;
3432
import org.jgrapht.graph.DefaultEdge;
@@ -135,26 +133,12 @@ private GridContainerValidationUtils() {
135133
exceptions.addAll(ConnectorValidationUtils.check(transformer));
136134
});
137135

138-
/* Checking switches
139-
* Because of the fact, that a transformer with switch gear in "upstream" direction has its corresponding node in
140-
* upper grid connected to a switch, instead of to the transformer directly: Collect all nodes at the end of the
141-
* upstream switch chain and add them to the set of allowed nodes */
142-
HashSet<NodeInput> validSwitchNodes = new HashSet<>(nodes);
143-
validSwitchNodes.addAll(
144-
Stream.of(rawGridElements.getTransformer2Ws(), rawGridElements.getTransformer2Ws())
145-
.flatMap(Set::stream)
146-
.parallel()
147-
.map(
148-
transformer ->
149-
ContainerUtils.traverseAlongSwitchChain(transformer.getNodeA(), rawGridElements)
150-
.getLast())
151-
.toList());
152-
136+
/* Checking switches */
153137
rawGridElements
154138
.getSwitches()
155139
.forEach(
156140
switcher -> {
157-
exceptions.add(checkNodeAvailability(switcher, validSwitchNodes));
141+
exceptions.add(checkNodeAvailability(switcher, nodes));
158142
exceptions.addAll(ConnectorValidationUtils.check(switcher));
159143
});
160144

0 commit comments

Comments
 (0)