AbstractAcDcConverterAdder.java
/**
* Copyright (c) 2025, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/)
* 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.iidm.network.impl;
import com.powsybl.iidm.network.*;
import java.util.Objects;
import java.util.Optional;
/**
* @author Damien Jeandemange {@literal <damien.jeandemange at artelys.com>}
*/
abstract class AbstractAcDcConverterAdder<T extends AbstractAcDcConverterAdder<T>> extends AbstractIdentifiableAdder<T> {
protected String dcNode1Id;
protected boolean dcConnected1 = true;
protected String dcNode2Id;
protected boolean dcConnected2 = true;
private Integer node1;
private String bus1;
private String connectableBus1;
protected VoltageLevelExt voltageLevel;
private Integer node2;
private String bus2;
private String connectableBus2;
protected double idleLoss = 0.;
protected double switchingLoss = 0.;
protected double resistiveLoss = 0.;
protected TerminalExt pccTerminal;
protected AcDcConverter.ControlMode controlMode;
protected double targetP = Double.NaN;
protected double targetVdc = Double.NaN;
AbstractAcDcConverterAdder(VoltageLevelExt voltageLevel) {
this.voltageLevel = voltageLevel;
}
protected NetworkImpl getNetwork() {
return voltageLevel.getNetwork();
}
public T setDcNode1(String dcNode1) {
this.dcNode1Id = Objects.requireNonNull(dcNode1);
return self();
}
public T setDcConnected1(boolean dcConnected1) {
this.dcConnected1 = dcConnected1;
return self();
}
public T setDcNode2(String dcNode2) {
this.dcNode2Id = Objects.requireNonNull(dcNode2);
return self();
}
public T setDcConnected2(boolean dcConnected2) {
this.dcConnected2 = dcConnected2;
return self();
}
public T setNode1(int node1) {
this.node1 = node1;
return self();
}
public T setBus1(String bus1) {
this.bus1 = bus1;
return self();
}
public T setConnectableBus1(String connectableBus1) {
this.connectableBus1 = connectableBus1;
return self();
}
protected TerminalExt checkAndGetTerminal1() {
return new TerminalBuilder(voltageLevel.getNetworkRef(), this, ThreeSides.ONE)
.setNode(node1)
.setBus(bus1)
.setConnectableBus(connectableBus1)
.build();
}
public T setNode2(int node2) {
this.node2 = node2;
return self();
}
public T setBus2(String bus2) {
this.bus2 = bus2;
return self();
}
public T setConnectableBus2(String connectableBus2) {
this.connectableBus2 = connectableBus2;
return self();
}
protected Optional<TerminalExt> checkAndGetTerminal2() {
if (hasTwoAcTerminals()) {
return Optional.of(new TerminalBuilder(voltageLevel.getNetworkRef(), this, ThreeSides.TWO)
.setNode(node2)
.setBus(bus2)
.setConnectableBus(connectableBus2)
.build());
}
return Optional.empty();
}
public T setIdleLoss(double idleLoss) {
this.idleLoss = idleLoss;
return self();
}
public T setSwitchingLoss(double switchingLoss) {
this.switchingLoss = switchingLoss;
return self();
}
public T setResistiveLoss(double resistiveLoss) {
this.resistiveLoss = resistiveLoss;
return self();
}
public T setPccTerminal(Terminal pccTerminal) {
this.pccTerminal = (TerminalExt) pccTerminal;
return self();
}
public T setControlMode(AcDcConverter.ControlMode controlMode) {
this.controlMode = controlMode;
return self();
}
public T setTargetP(double targetP) {
this.targetP = targetP;
return self();
}
public T setTargetVdc(double targetVdc) {
this.targetVdc = targetVdc;
return self();
}
protected void preCheck() {
NetworkImpl network = getNetwork();
network.setValidationLevelIfGreaterThan(ValidationUtil.checkAcDcConverterControl(this, controlMode, targetP, targetVdc,
network.getMinValidationLevel(), network.getReportNodeContext().getReportNode()));
ValidationUtil.checkAcDcConverterPccTerminal(this, hasTwoAcTerminals(), pccTerminal, voltageLevel);
}
private boolean hasTwoAcTerminals() {
return bus2 != null || connectableBus2 != null || node2 != null;
}
protected void checkAndAdd(AbstractAcDcConverter<?> dcConverter) {
TerminalExt terminal1 = checkAndGetTerminal1();
DcNode dcNode1 = ValidationUtil.checkAndGetDcNode(getNetwork().getParentNetwork(), this, dcNode1Id, "dcNode1");
DcNode dcNode2 = ValidationUtil.checkAndGetDcNode(getNetwork().getParentNetwork(), this, dcNode2Id, "dcNode2");
ValidationUtil.checkSameParentNetwork(voltageLevel.getParentNetwork(), this, dcNode1, dcNode2);
Optional<TerminalExt> terminal2 = checkAndGetTerminal2();
dcConverter.addTerminal(terminal1);
voltageLevel.getTopologyModel().attach(terminal1, false);
if (pccTerminal == null && terminal2.isEmpty()) {
// default to use terminal1 as pccTerminal, only if converter has only 1 AC Terminal
dcConverter.setPccTerminal(terminal1);
}
terminal2.ifPresent(terminal -> {
dcConverter.addTerminal(terminal);
voltageLevel.getTopologyModel().attach(terminal, false);
});
DcTerminalImpl dcTerminal1 = new DcTerminalImpl(voltageLevel.getNetworkRef(), TwoSides.ONE, dcNode1, dcConnected1);
DcTerminalImpl dcTerminal2 = new DcTerminalImpl(voltageLevel.getNetworkRef(), TwoSides.TWO, dcNode2, dcConnected2);
dcConverter.addDcTerminal(dcTerminal1);
dcConverter.addDcTerminal(dcTerminal2);
getNetwork().getIndex().checkAndAdd(dcConverter);
getNetwork().getListeners().notifyCreation(dcConverter);
}
protected abstract T self();
}