AbstractAsymmetricalClosedBranchCoupledFlowEquationTerm.java
/**
* Copyright (c) 2023, Jean-Baptiste Heyberger <jbheyberger at gmail.com>
* Copyright (c) 2023, Geoffroy Jamgotchian <geoffroy.jamgotchian at gmail.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.openloadflow.ac.equations.asym;
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openloadflow.ac.equations.AcVariableType;
import com.powsybl.openloadflow.equations.Variable;
import com.powsybl.openloadflow.equations.VariableSet;
import com.powsybl.openloadflow.network.LfBranch;
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.util.ComplexPart;
import com.powsybl.openloadflow.util.Fortescue.SequenceType;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static com.powsybl.openloadflow.network.PiModel.A2;
/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at gmail.com>}
* @author Jean-Baptiste Heyberger {@literal <jbheyberger at gmail.com>}
*/
public abstract class AbstractAsymmetricalClosedBranchCoupledFlowEquationTerm extends AbstractAsymmetricalBranchFlowEquationTerm {
// positive
protected final Variable<AcVariableType> v1Var;
protected final Variable<AcVariableType> v2Var;
protected final Variable<AcVariableType> ph1Var;
protected final Variable<AcVariableType> ph2Var;
// negative
protected final Variable<AcVariableType> v1VarNegative;
protected final Variable<AcVariableType> v2VarNegative;
protected final Variable<AcVariableType> ph1VarNegative;
protected final Variable<AcVariableType> ph2VarNegative;
// zero
protected final Variable<AcVariableType> v1VarZero;
protected final Variable<AcVariableType> v2VarZero;
protected final Variable<AcVariableType> ph1VarZero;
protected final Variable<AcVariableType> ph2VarZero;
protected final List<Variable<AcVariableType>> variables = new ArrayList<>();
protected final ComplexPart complexPart;
protected final TwoSides side;
protected final SequenceType sequenceType;
protected AbstractAsymmetricalClosedBranchCoupledFlowEquationTerm(LfBranch branch, LfBus bus1, LfBus bus2, VariableSet<AcVariableType> variableSet,
ComplexPart complexPart, TwoSides side, SequenceType sequenceType) {
super(branch);
Objects.requireNonNull(bus1);
Objects.requireNonNull(bus2);
Objects.requireNonNull(variableSet);
this.complexPart = Objects.requireNonNull(complexPart);
this.side = Objects.requireNonNull(side);
this.sequenceType = Objects.requireNonNull(sequenceType);
v1Var = variableSet.getVariable(bus1.getNum(), AcVariableType.BUS_V);
v2Var = variableSet.getVariable(bus2.getNum(), AcVariableType.BUS_V);
ph1Var = variableSet.getVariable(bus1.getNum(), AcVariableType.BUS_PHI);
ph2Var = variableSet.getVariable(bus2.getNum(), AcVariableType.BUS_PHI);
v1VarNegative = variableSet.getVariable(bus1.getNum(), AcVariableType.BUS_V_NEGATIVE);
v2VarNegative = variableSet.getVariable(bus2.getNum(), AcVariableType.BUS_V_NEGATIVE);
ph1VarNegative = variableSet.getVariable(bus1.getNum(), AcVariableType.BUS_PHI_NEGATIVE);
ph2VarNegative = variableSet.getVariable(bus2.getNum(), AcVariableType.BUS_PHI_NEGATIVE);
v1VarZero = variableSet.getVariable(bus1.getNum(), AcVariableType.BUS_V_ZERO);
v2VarZero = variableSet.getVariable(bus2.getNum(), AcVariableType.BUS_V_ZERO);
ph1VarZero = variableSet.getVariable(bus1.getNum(), AcVariableType.BUS_PHI_ZERO);
ph2VarZero = variableSet.getVariable(bus2.getNum(), AcVariableType.BUS_PHI_ZERO);
variables.add(v1Var);
variables.add(v2Var);
variables.add(ph1Var);
variables.add(ph2Var);
variables.add(v1VarNegative);
variables.add(v2VarNegative);
variables.add(ph1VarNegative);
variables.add(ph2VarNegative);
variables.add(v1VarZero);
variables.add(v2VarZero);
variables.add(ph1VarZero);
variables.add(ph2VarZero);
}
protected static SequenceType getSequenceType(Variable<AcVariableType> variable) {
return switch (variable.getType()) {
case BUS_V, BUS_PHI -> SequenceType.POSITIVE;
case BUS_V_NEGATIVE, BUS_PHI_NEGATIVE -> SequenceType.NEGATIVE;
case BUS_V_ZERO, BUS_PHI_ZERO -> SequenceType.ZERO;
default -> throw new IllegalStateException("Unknown variable: " + variable);
};
}
protected static boolean isPhase(Variable<AcVariableType> variable) {
return switch (variable.getType()) {
case BUS_PHI, BUS_PHI_NEGATIVE, BUS_PHI_ZERO -> true;
default -> false;
};
}
protected double v(SequenceType g, TwoSides i) {
return switch (g) {
case ZERO -> i == TwoSides.ONE ? sv.get(v1VarZero.getRow()) : sv.get(v2VarZero.getRow());
case POSITIVE -> i == TwoSides.ONE ? sv.get(v1Var.getRow()) : sv.get(v2Var.getRow());
case NEGATIVE -> i == TwoSides.ONE ? sv.get(v1VarNegative.getRow()) : sv.get(v2VarNegative.getRow());
};
}
protected double ph(SequenceType g, TwoSides i) {
return switch (g) {
case ZERO -> i == TwoSides.ONE ? sv.get(ph1VarZero.getRow()) : sv.get(ph2VarZero.getRow());
case POSITIVE -> i == TwoSides.ONE ? sv.get(ph1Var.getRow()) : sv.get(ph2Var.getRow());
case NEGATIVE -> i == TwoSides.ONE ? sv.get(ph1VarNegative.getRow()) : sv.get(ph2VarNegative.getRow());
};
}
protected double r1() {
return 1;
}
protected double a1() {
return 0;
}
protected double r(TwoSides i) {
return i == TwoSides.ONE ? r1() : 1.;
}
protected double a(TwoSides i) {
return i == TwoSides.ONE ? a1() : A2;
}
@Override
public List<Variable<AcVariableType>> getVariables() {
return variables;
}
public TwoSides getSide(Variable<AcVariableType> variable) {
Objects.requireNonNull(variable);
if (variable.equals(v1Var) || variable.equals(v1VarZero) || variable.equals(v1VarNegative)
|| variable.equals(ph1Var) || variable.equals(ph1VarZero) || variable.equals(ph1VarNegative)) {
return TwoSides.ONE;
} else if (variable.equals(v2Var) || variable.equals(v2VarZero) || variable.equals(v2VarNegative)
|| variable.equals(ph2Var) || variable.equals(ph2VarZero) || variable.equals(ph2VarNegative)) {
return TwoSides.TWO;
} else {
throw new IllegalStateException("Unknown variable: " + variable);
}
}
}