ShuntConverter.java
/**
* Copyright (c) 2022, RTE (http://www.rte-france.com)
* 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.powerfactory.converter;
import java.util.Optional;
import org.apache.commons.math3.complex.Complex;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.VoltageLevel;
import com.powsybl.powerfactory.converter.PowerFactoryImporter.ImportContext;
import com.powsybl.powerfactory.model.DataObject;
import com.powsybl.powerfactory.model.PowerFactoryException;
/**
* @author Luma Zamarre��o {@literal <zamarrenolm at aia.es>}
* @author Jos�� Antonio Marqu��s {@literal <marquesja at aia.es>}
*/
class ShuntConverter extends AbstractConverter {
ShuntConverter(ImportContext importContext, Network network) {
super(importContext, network);
}
void create(DataObject elmShnt) {
NodeRef nodeRef = checkNodes(elmShnt, 1).get(0);
LinearShuntModel linearShuntModel = LinearShuntModel.create(elmShnt);
VoltageLevel vl = getNetwork().getVoltageLevel(nodeRef.voltageLevelId);
vl.newShuntCompensator()
.setId(elmShnt.getLocName())
.setEnsureIdUnicity(true)
.setNode(nodeRef.node)
.setSectionCount(linearShuntModel.sectionCount)
.newLinearModel()
.setGPerSection(linearShuntModel.gPerSection)
.setBPerSection(linearShuntModel.bPerSection)
.setMaximumSectionCount(linearShuntModel.maximumSectionCount)
.add()
.add();
}
private static final class LinearShuntModel {
private final int sectionCount;
private final int maximumSectionCount;
private final double gPerSection;
private final double bPerSection;
private LinearShuntModel(Section section, double gPerSection, double bPerSection) {
this.sectionCount = section.sectionCount;
this.maximumSectionCount = section.maximumSectionCount;
this.gPerSection = gPerSection;
this.bPerSection = bPerSection;
}
private static LinearShuntModel create(DataObject elmShnt) {
int shtype = elmShnt.getIntAttributeValue("shtype");
return switch (shtype) {
case 1 -> rlShunt(elmShnt);
case 2 -> cShunt(elmShnt);
default -> throw new PowerFactoryException("Shunt type not supported: " + shtype);
};
}
private static LinearShuntModel rlShunt(DataObject elmShnt) {
Section section = Section.create(elmShnt);
double rrea = elmShnt.findFloatAttributeValue("rrea").orElse(0f);
double xrea = elmShnt.findFloatAttributeValue("xrea").orElse(0f);
if (rrea != 0.0 || xrea != 0.0) {
Complex yPerSection = new Complex(rrea, xrea).reciprocal();
return new LinearShuntModel(section, yPerSection.getReal(), yPerSection.getImaginary());
}
Optional<Float> ushnm = elmShnt.findFloatAttributeValue("ushnm");
Optional<Float> qcapn = elmShnt.findFloatAttributeValue("qcapn");
if (ushnm.isPresent() && qcapn.isPresent() && ushnm.get() > 0.0) {
double bPerSection = -qcapn.get() / (ushnm.get() * ushnm.get());
return new LinearShuntModel(section, 0.0, bPerSection);
}
throw new PowerFactoryException("Cannot convert RL shunt");
}
private static LinearShuntModel cShunt(DataObject elmShnt) {
Section section = Section.create(elmShnt);
float gparac = elmShnt.getFloatAttributeValue("gparac");
float bcap = elmShnt.getFloatAttributeValue("bcap");
double gPerSection = microSiemensToSiemens(gparac);
double bPerSection = microSiemensToSiemens(bcap);
return new LinearShuntModel(section, gPerSection, bPerSection);
}
private static final class Section {
private final int sectionCount;
private final int maximumSectionCount;
private Section(int sectionCount, int maximumSectionCount) {
this.sectionCount = sectionCount;
this.maximumSectionCount = maximumSectionCount;
}
private static Section create(DataObject elmShnt) {
int ncapa = elmShnt.getIntAttributeValue("ncapa");
int ncapx = elmShnt.getIntAttributeValue("ncapx");
return new Section(ncapa, ncapx);
}
}
}
}