|
| 1 | +// SPDX-FileCopyrightText: 2021 Alliander N.V. |
| 2 | +// |
| 3 | +// SPDX-License-Identifier: Apache-2.0 |
| 4 | +package org.lfenergy.compas.scl.auto.alignment.builder; |
| 5 | + |
| 6 | +import com.powsybl.sld.model.*; |
| 7 | +import org.lfenergy.compas.scl.auto.alignment.model.*; |
| 8 | + |
| 9 | +import java.util.HashMap; |
| 10 | +import java.util.Map; |
| 11 | +import java.util.Optional; |
| 12 | +import java.util.concurrent.atomic.AtomicInteger; |
| 13 | + |
| 14 | +public class VoltageLevelGraphBuilder extends AbstractGraphBuilder<VoltageLevelGraph> { |
| 15 | + private final GenericVoltageLevel voltageLevel; |
| 16 | + private final GenericSubstation substation; |
| 17 | + |
| 18 | + public VoltageLevelGraphBuilder(GenericVoltageLevel voltageLevel) { |
| 19 | + this(voltageLevel, null, new HashMap<>(), true); |
| 20 | + } |
| 21 | + |
| 22 | + public VoltageLevelGraphBuilder(GenericVoltageLevel voltageLevel, |
| 23 | + GenericSubstation substation, |
| 24 | + Map<String, Node> path2Node) { |
| 25 | + this(voltageLevel, substation, path2Node, false); |
| 26 | + } |
| 27 | + |
| 28 | + private VoltageLevelGraphBuilder(GenericVoltageLevel voltageLevel, |
| 29 | + GenericSubstation substation, |
| 30 | + Map<String, Node> path2Node, |
| 31 | + boolean forVoltageLevelDiagram) { |
| 32 | + super(path2Node); |
| 33 | + this.voltageLevel = voltageLevel; |
| 34 | + this.substation = substation; |
| 35 | + |
| 36 | + var voltageLevelInfos = new VoltageLevelInfos(voltageLevel.getFullName(), |
| 37 | + voltageLevel.getFullName(), |
| 38 | + voltageLevel.getVoltage()); |
| 39 | + setGraph(VoltageLevelGraph.create(voltageLevelInfos, forVoltageLevelDiagram)); |
| 40 | + |
| 41 | + createVoltageLevel(); |
| 42 | + } |
| 43 | + |
| 44 | + private void createVoltageLevel() { |
| 45 | + // First process the Busbars. |
| 46 | + var busbarIndex = new AtomicInteger(1); |
| 47 | + voltageLevel.getBays().stream() |
| 48 | + .filter(GenericBay::isBusbar) |
| 49 | + .forEach(busbar -> processBusbarNode(busbar, busbarIndex)); |
| 50 | + |
| 51 | + // Next process the other bays. |
| 52 | + voltageLevel.getBays().stream() |
| 53 | + .filter(bay -> !bay.isBusbar()) |
| 54 | + .forEach(this::processBayNode); |
| 55 | + } |
| 56 | + |
| 57 | + private void processBusbarNode(GenericBay busbar, |
| 58 | + AtomicInteger busbarIndex) { |
| 59 | + busbar.getConnectivityNodes() |
| 60 | + .forEach(connectivityNode -> |
| 61 | + addNode(connectivityNode.getPathName(), |
| 62 | + createBusbarNode(busbar.getFullName(), busbarIndex.getAndIncrement(), 1))); |
| 63 | + } |
| 64 | + |
| 65 | + public BusNode createBusbarNode(String id, int busbarIndex, int sectionIndex) { |
| 66 | + BusNode busNode = BusNode.create(getGraph(), id, id); |
| 67 | + getGraph().addNode(busNode); |
| 68 | + busNode.setBusBarIndexSectionIndex(busbarIndex, sectionIndex); |
| 69 | + return busNode; |
| 70 | + } |
| 71 | + |
| 72 | + private void processBayNode(GenericBay bay) { |
| 73 | + bay.getConnectivityNodes().forEach(this::createConnectivityNode); |
| 74 | + bay.getConductingEquipments().forEach(this::processConductingEquipment); |
| 75 | + } |
| 76 | + |
| 77 | + private void createConnectivityNode(GenericConnectivityNode connectivityNode) { |
| 78 | + getPowerTransformer(connectivityNode.getPathName()) |
| 79 | + .ifPresentOrElse(powerTransformer -> { |
| 80 | + if (powerTransformer.isFeeder2WT()) { |
| 81 | + addNode(connectivityNode.getPathName(), |
| 82 | + createFeeder2WTLegNode(connectivityNode.getPathName(), |
| 83 | + powerTransformer.getSide(connectivityNode.getPathName()), 0, null)); |
| 84 | + } else if (powerTransformer.isFeeder3WT()) { |
| 85 | + addNode(connectivityNode.getPathName(), |
| 86 | + createFeeder3WTLegNode(connectivityNode.getPathName(), |
| 87 | + powerTransformer.getSide(connectivityNode.getPathName()), 0, null)); |
| 88 | + } |
| 89 | + }, () -> |
| 90 | + addNode(connectivityNode.getPathName(), |
| 91 | + createFictitiousNode(connectivityNode.getPathName())) |
| 92 | + ); |
| 93 | + } |
| 94 | + |
| 95 | + private Optional<GenericPowerTransformer> getPowerTransformer(String pathName) { |
| 96 | + if (substation != null) { |
| 97 | + return substation.getPowerTransformerByConnectivityNode(pathName); |
| 98 | + } |
| 99 | + return Optional.empty(); |
| 100 | + } |
| 101 | + |
| 102 | + private void processConductingEquipment(GenericConductingEquipment conductingEquipment) { |
| 103 | + var terminals = conductingEquipment.getTerminals(); |
| 104 | + var fullName = conductingEquipment.getFullName(); |
| 105 | + var node = createSwitchNode(fullName); |
| 106 | + |
| 107 | + Node node1 = terminalToNode(terminals.get(0)); |
| 108 | + Node node2 = null; |
| 109 | + var termNb = terminals.size(); |
| 110 | + if (termNb == 1) { |
| 111 | + node2 = createLoad(fullName + "/Grounded"); |
| 112 | + } else if (termNb == 2) { |
| 113 | + node2 = terminalToNode(terminals.get(1)); |
| 114 | + } |
| 115 | + connectNode(node, node1); |
| 116 | + connectNode(node, node2); |
| 117 | + } |
| 118 | + |
| 119 | + private Node terminalToNode(GenericTerminal terminal) { |
| 120 | + var pathName = terminal.getConnectivityNode(); |
| 121 | + if (pathName != null) { |
| 122 | + return getNodeByPath(pathName); |
| 123 | + } |
| 124 | + return createLoad(terminal.getCNodeName()); |
| 125 | + } |
| 126 | + |
| 127 | + private SwitchNode createSwitchNode(String id) { |
| 128 | + SwitchNode sw = new SwitchNode(id, id, SwitchNode.SwitchKind.BREAKER.name(), false, |
| 129 | + getGraph(), SwitchNode.SwitchKind.BREAKER, false); |
| 130 | + getGraph().addNode(sw); |
| 131 | + return sw; |
| 132 | + } |
| 133 | + |
| 134 | + private void connectNode(Node node1, Node node2) { |
| 135 | + getGraph().addEdge(node1, node2); |
| 136 | + } |
| 137 | + |
| 138 | + private FictitiousNode createFictitiousNode(String id) { |
| 139 | + InternalNode fictitiousNode = new InternalNode(id, getGraph()); |
| 140 | + getGraph().addNode(fictitiousNode); |
| 141 | + return fictitiousNode; |
| 142 | + } |
| 143 | + |
| 144 | + private FeederNode createLoad(String id) { |
| 145 | + FeederInjectionNode fn = FeederInjectionNode.createLoad(getGraph(), id, id); |
| 146 | + commonFeederSetting(fn, id, 0, null); |
| 147 | + return fn; |
| 148 | + } |
| 149 | + |
| 150 | + public Feeder2WTLegNode createFeeder2WTLegNode(String id, FeederWithSideNode.Side side, int order, |
| 151 | + BusCell.Direction direction) { |
| 152 | + Feeder2WTLegNode f2WTe = Feeder2WTLegNode.create(getGraph(), id + "_" + side, id, id, side); |
| 153 | + commonFeederSetting(f2WTe, id, order, direction); |
| 154 | + return f2WTe; |
| 155 | + } |
| 156 | + |
| 157 | + public Feeder3WTLegNode createFeeder3WTLegNode(String id, FeederWithSideNode.Side side, int order, |
| 158 | + BusCell.Direction direction) { |
| 159 | + Feeder3WTLegNode f3WTe = Feeder3WTLegNode.createForSubstationDiagram(getGraph(), id + "_" + side, id, id, side); |
| 160 | + commonFeederSetting(f3WTe, id + side.getIntValue(), order, direction); |
| 161 | + return f3WTe; |
| 162 | + } |
| 163 | + |
| 164 | + private void commonFeederSetting(FeederNode node, String id, int order, BusCell.Direction direction) { |
| 165 | + node.setLabel(id); |
| 166 | + getGraph().addNode(node); |
| 167 | + |
| 168 | + if (direction != null) { |
| 169 | + node.setOrder(order); |
| 170 | + node.setDirection(direction); |
| 171 | + } |
| 172 | + } |
| 173 | +} |
0 commit comments