AreaConverter.java
/**
* Copyright (c) 2025, University of West Bohemia (https://www.zcu.cz)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.psse.converter;
import com.powsybl.iidm.network.Area;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.Terminal;
import com.powsybl.iidm.network.VoltageLevel;
import com.powsybl.iidm.network.util.ContainersMapping;
import com.powsybl.psse.model.pf.PsseArea;
import com.powsybl.psse.model.pf.PsseBus;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
/**
* @author Petr Janecek {@literal <pjanecek at ntis.zcu.cz>}
*/
public class AreaConverter extends AbstractConverter {
AreaConverter(PsseArea psseArea, List<PsseBus> buses, ContainersMapping containersMapping, Network network) {
super(containersMapping, network);
this.psseArea = psseArea;
this.buses = buses;
}
Area create() {
String areaId = AREA_ID_PREFIX + psseArea.getI();
var area = getNetwork().newArea()
.setId(areaId)
.setAreaType(CONTROL_AREA_TYPE)
.setInterchangeTarget(psseArea.getPdes())
.setName(psseArea.getArname())
.add();
addVoltageLevelsToArea(area);
addAreaBoundaries(area);
return area;
}
private void addVoltageLevelsToArea(Area area) {
for (var bus : buses) {
if (bus.getArea() == psseArea.getI()) {
String voltageLevelId = getContainersMapping().getVoltageLevelId(bus.getI());
VoltageLevel voltageLevel = getNetwork().getVoltageLevel(voltageLevelId);
area.addVoltageLevel(voltageLevel);
}
}
}
private void addAreaBoundaries(Area area) {
Set<VoltageLevel> areaVoltageLevels = extractVoltageLevels(area);
addLineBoundaryTerminals(area, areaVoltageLevels);
addHvdcLinesBoundaryTerminals(area, areaVoltageLevels);
addTransformerTwoWindingsBoundaryTerminals(area, areaVoltageLevels);
addTransformerTreeWindingsBoundaryTerminals(area, areaVoltageLevels);
}
private void addLineBoundaryTerminals(Area area, Set<VoltageLevel> areaVoltageLevels) {
getNetwork().getLines().forEach(line ->
processTerminals(line.getTerminals(), area, areaVoltageLevels, IS_AC));
}
private void addHvdcLinesBoundaryTerminals(Area area, Set<VoltageLevel> areaVoltageLevels) {
getNetwork().getHvdcLines().forEach(line -> processTerminals(
List.of(line.getConverterStation1().getTerminal(), line.getConverterStation2().getTerminal()),
area, areaVoltageLevels, IS_DC));
}
private void addTransformerTwoWindingsBoundaryTerminals(Area area, Set<VoltageLevel> areaVoltageLevels) {
getNetwork().getTwoWindingsTransformers().forEach(trf ->
processTerminals(trf.getTerminals(), area, areaVoltageLevels, IS_AC));
}
private void addTransformerTreeWindingsBoundaryTerminals(Area area, Set<VoltageLevel> areaVoltageLevels) {
getNetwork().getThreeWindingsTransformers().forEach(trf ->
processTerminals(trf.getTerminals(), area, areaVoltageLevels, IS_AC)
);
}
private void processTerminals(List<? extends Terminal> terminals, Area area, Set<VoltageLevel> areaVoltageLevels,
boolean isAC) {
var boundaryTerminals = boundaryTerminal(terminals, areaVoltageLevels);
for (var terminal : boundaryTerminals) {
addAreaBoundary(area, terminal, isAC);
}
}
private Terminal[] boundaryTerminal(List<? extends Terminal> terminals, Set<VoltageLevel> areaVoltageLevels) {
var terminalsInArea = new ArrayList<Terminal>();
for (var terminal : terminals) {
if (areaVoltageLevels.contains(terminal.getVoltageLevel())) {
terminalsInArea.add(terminal);
}
}
return terminals.size() > terminalsInArea.size() ? terminalsInArea.toArray(new Terminal[0]) : new Terminal[0];
}
private Set<VoltageLevel> extractVoltageLevels(Area area) {
return StreamSupport.stream(area.getVoltageLevels().spliterator(), false)
.collect(Collectors.toSet());
}
private void addAreaBoundary(Area area, Terminal terminal, boolean isAC) {
area.newAreaBoundary()
.setTerminal(terminal)
.setAc(isAC)
.add();
}
private static final String AREA_ID_PREFIX = "A";
private static final boolean IS_AC = true;
private static final boolean IS_DC = false;
private static final String CONTROL_AREA_TYPE = "ControlArea";
private final PsseArea psseArea;
private final List<PsseBus> buses;
}