AsymmetricalClosedBranchCoupledCurrentEquationTerm.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 net.jafama.FastMath;
import java.util.Objects;
/**
* We define T(i,j,g,h) = rho_i * rho_j * exp(j(a_j-a_i)) * y*_ij_gh * V_hj
* where i,j are line's ends i,j included in {1,2}
* where g,h are fortescue sequences g,h included in {z, p, n} = {0,1,2} (z = zero = 0, p = positive = 1, n = negative = 2)
*
* Expanded formula :
* T(i,j,g,h) = rho_i * rho_j * V_hj * yx_ij_gh * cos(a_j - a_i + th_hj)
* - rho_i * rho_j * V_hj * yy_ij_gh * sin(a_j - a_i + th_hj)
* +j( rho_i * rho_j * V_hj * yx_ij_gh * sin(a_j - a_i + th_hj)
* + rho_i * rho_j * V_hj * yy_ij_gh * cos(a_j - a_i + th_hj) )
*
* By construction we have :
* [ y_11_zz y_11_zp y_11_zn y_12_zz y_12_zp y_12_zn ]
* [ y_11_pz y_11_pp y_11_pn y_12_pz y_12_pp y_12_pn ]
* [Yzpn] = [ y_11_nz y_11_np y_11_nn y_12_nz y_12_np y_12_nn ]
* [ y_21_zz y_21_zp y_21_zn y_22_zz y_22_zp y_22_zn ]
* [ y_21_pz y_21_pp y_21_pn y_22_pz y_22_pp y_22_pn ]
* [ y_21_nz y_21_np y_21_nn y_22_nz y_22_np y_22_nn ]
*
* @author Jean-Baptiste Heyberger {@literal <jbheyberger at gmail.com>}
*/
public class AsymmetricalClosedBranchCoupledCurrentEquationTerm extends AbstractAsymmetricalClosedBranchCoupledFlowEquationTerm {
public AsymmetricalClosedBranchCoupledCurrentEquationTerm(LfBranch branch, LfBus bus1, LfBus bus2, VariableSet<AcVariableType> variableSet,
ComplexPart complexPart, TwoSides side, SequenceType sequenceType) {
super(branch, bus1, bus2, variableSet, complexPart, side, sequenceType);
}
public double ix(TwoSides i, TwoSides j, SequenceType g, SequenceType h) {
return r(i) * r(j) * v(h, j) * (y.getX(i, j, g, h) * FastMath.cos(a(j) - a(i) + ph(h, j))
- y.getY(i, j, g, h) * FastMath.sin(a(j) - a(i) + ph(h, j)));
}
public double iy(TwoSides i, TwoSides j, SequenceType g, SequenceType h) {
return r(i) * r(j) * v(h, j) * (y.getX(i, j, g, h) * FastMath.sin(a(j) - a(i) + ph(h, j))
+ y.getY(i, j, g, h) * FastMath.cos(a(j) - a(i) + ph(h, j)));
}
public double dixdv(TwoSides i, TwoSides j, SequenceType g, SequenceType h,
TwoSides derivationSide, SequenceType derivationSequence) {
if (j == derivationSide && h == derivationSequence) {
return r(i) * r(j) * (y.getX(i, j, g, h) * FastMath.cos(a(j) - a(i) + ph(h, j)) - y.getY(i, j, g, h) * FastMath.sin(a(j) - a(i) + ph(h, j)));
}
return 0;
}
public double dixdph(TwoSides i, TwoSides j, SequenceType g, SequenceType h,
TwoSides derivationSide, SequenceType derivationSequence) {
if (j == derivationSide && h == derivationSequence) {
return r(i) * r(j) * v(h, j) * (-y.getX(i, j, g, h) * FastMath.sin(a(j) - a(i) + ph(h, j)) - y.getY(i, j, g, h) * FastMath.cos(a(j) - a(i) + ph(h, j)));
}
return 0;
}
public double dix(TwoSides i, TwoSides j, SequenceType g, SequenceType h,
TwoSides derivationSide, SequenceType derivationSequence, boolean phase) {
if (phase) {
return dixdph(i, j, g, h, derivationSide, derivationSequence);
} else {
return dixdv(i, j, g, h, derivationSide, derivationSequence);
}
}
public double diydv(TwoSides i, TwoSides j, SequenceType g, SequenceType h,
TwoSides derivationSide, SequenceType derivationSequence) {
if (j == derivationSide && h == derivationSequence) {
return r(i) * r(j) * (y.getX(i, j, g, h) * FastMath.sin(a(j) - a(i) + ph(h, j)) + y.getY(i, j, g, h) * FastMath.cos(a(j) - a(i) + ph(h, j)));
}
return 0;
}
public double diydph(TwoSides i, TwoSides j, SequenceType g, SequenceType h,
TwoSides derivationSide, SequenceType derivationSequence) {
if (j == derivationSide && h == derivationSequence) {
return r(i) * r(j) * v(h, j) * (y.getX(i, j, g, h) * FastMath.cos(a(j) - a(i) + ph(h, j)) - y.getY(i, j, g, h) * FastMath.sin(a(j) - a(i) + ph(h, j)));
}
return 0;
}
public double diy(TwoSides i, TwoSides j, SequenceType g, SequenceType h, TwoSides derivationSide, SequenceType derivationSequence, boolean phase) {
if (phase) {
return diydph(i, j, g, h, derivationSide, derivationSequence);
} else {
return diydv(i, j, g, h, derivationSide, derivationSequence);
}
}
public double di(Variable<AcVariableType> variable) {
TwoSides i;
TwoSides j;
if (side == TwoSides.ONE) {
i = TwoSides.ONE;
j = TwoSides.TWO;
} else {
i = TwoSides.TWO;
j = TwoSides.ONE;
}
TwoSides derivationSide = getSide(variable);
SequenceType derivationSequence = getSequenceType(variable);
boolean phase = isPhase(variable);
// iDerivative is the side of "variable" that is used for derivation
if (complexPart == ComplexPart.REAL) {
// dIx
return dix(i, i, sequenceType, SequenceType.ZERO, derivationSide, derivationSequence, phase)
+ dix(i, i, sequenceType, SequenceType.POSITIVE, derivationSide, derivationSequence, phase)
+ dix(i, i, sequenceType, SequenceType.NEGATIVE, derivationSide, derivationSequence, phase)
+ dix(i, j, sequenceType, SequenceType.ZERO, derivationSide, derivationSequence, phase)
+ dix(i, j, sequenceType, SequenceType.POSITIVE, derivationSide, derivationSequence, phase)
+ dix(i, j, sequenceType, SequenceType.NEGATIVE, derivationSide, derivationSequence, phase);
} else {
// dIy
return diy(i, i, sequenceType, SequenceType.ZERO, derivationSide, derivationSequence, phase)
+ diy(i, i, sequenceType, SequenceType.POSITIVE, derivationSide, derivationSequence, phase)
+ diy(i, i, sequenceType, SequenceType.NEGATIVE, derivationSide, derivationSequence, phase)
+ diy(i, j, sequenceType, SequenceType.ZERO, derivationSide, derivationSequence, phase)
+ diy(i, j, sequenceType, SequenceType.POSITIVE, derivationSide, derivationSequence, phase)
+ diy(i, j, sequenceType, SequenceType.NEGATIVE, derivationSide, derivationSequence, phase);
}
}
public double i() {
TwoSides i;
TwoSides j;
if (side == TwoSides.ONE) {
i = TwoSides.ONE;
j = TwoSides.TWO;
} else {
i = TwoSides.TWO;
j = TwoSides.ONE;
}
if (complexPart == ComplexPart.REAL) { // Ix
return ix(i, i, sequenceType, SequenceType.ZERO)
+ ix(i, i, sequenceType, SequenceType.POSITIVE)
+ ix(i, i, sequenceType, SequenceType.NEGATIVE)
+ ix(i, j, sequenceType, SequenceType.ZERO)
+ ix(i, j, sequenceType, SequenceType.POSITIVE)
+ ix(i, j, sequenceType, SequenceType.NEGATIVE);
} else { // Iy
return iy(i, i, sequenceType, SequenceType.ZERO)
+ iy(i, i, sequenceType, SequenceType.POSITIVE)
+ iy(i, i, sequenceType, SequenceType.NEGATIVE)
+ iy(i, j, sequenceType, SequenceType.ZERO)
+ iy(i, j, sequenceType, SequenceType.POSITIVE)
+ iy(i, j, sequenceType, SequenceType.NEGATIVE);
}
}
@Override
public double eval() {
return i();
}
@Override
public double der(Variable<AcVariableType> variable) {
Objects.requireNonNull(variable);
return di(variable);
}
@Override
public String getName() {
return "ac_ixiy_coupled_closed";
}
}