AsymmetricalClosedBranchCoupledPowerEquationTerm.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_i-a_j)) * y*_ij_gh * V_gi * 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}
*
* Expanded formula :
* T(i,j,g,h) = rho_i * rho_j * V_gi * V_hj * yx_ij_gh * cos(a_i - a_j + th_gi - th_hj)
* - rho_i * rho_j * V_gi * V_hj * yy_ij_gh * sin(a_i - a_j + th_gi - th_hj)
* -j( rho_i * rho_j * V_gi * V_hj * yx_ij_gh * sin(a_i - a_j + th_gi - th_hj)
* + rho_i * rho_j * V_gi * V_hj * yy_ij_gh * cos(a_i - a_j + th_gi - 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 Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at gmail.com>}
* @author Jean-Baptiste Heyberger {@literal <jbheyberger at gmail.com>}
*/
public class AsymmetricalClosedBranchCoupledPowerEquationTerm extends AbstractAsymmetricalClosedBranchCoupledFlowEquationTerm {
public AsymmetricalClosedBranchCoupledPowerEquationTerm(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 dpdv(TwoSides i, TwoSides j, SequenceType g, SequenceType h,
TwoSides derivationSide, SequenceType derivationSequence) {
double tmpVal = y.getX(i, j, g, h) * FastMath.cos(a(i) - a(j) + ph(g, i) - ph(h, j)) + y.getY(i, j, g, h) * FastMath.sin(a(i) - a(j) + ph(g, i) - ph(h, j));
if (i == derivationSide && g == derivationSequence && j == derivationSide && h == derivationSequence) {
return 2 * r(i) * r(j) * v(g, i) * tmpVal;
} else if (i == derivationSide && g == derivationSequence) {
return r(i) * r(j) * v(h, j) * tmpVal;
} else if (j == derivationSide && h == derivationSequence) {
return r(i) * r(j) * v(g, i) * tmpVal;
}
return 0;
}
public double dpdph(TwoSides i, TwoSides j, SequenceType g, SequenceType h,
TwoSides derivationSide, SequenceType derivationSequence) {
if (i == derivationSide && g == derivationSequence && j == derivationSide && h == derivationSequence) {
return 0;
} else if (i == derivationSide && g == derivationSequence) {
return r(i) * r(j) * v(g, i) * v(h, j) * (y.getX(i, j, g, h) * -FastMath.sin(a(i) - a(j) + ph(g, i) - ph(h, j)) + y.getY(i, j, g, h) * FastMath.cos(a(i) - a(j) + ph(g, i) - ph(h, j)));
} else if (j == derivationSide && h == derivationSequence) {
return r(i) * r(j) * v(g, i) * v(h, j) * (y.getX(i, j, g, h) * -FastMath.sin(a(i) - a(j) + ph(g, i) - ph(h, j)) - y.getY(i, j, g, h) * FastMath.cos(a(i) - a(j) + ph(g, i) - ph(h, j)));
}
return 0;
}
public double dqdv(TwoSides i, TwoSides j, SequenceType g, SequenceType h,
TwoSides derivationSide, SequenceType derivationSequence) {
double tmpVal = y.getX(i, j, g, h) * FastMath.sin(a(i) - a(j) + ph(g, i) - ph(h, j)) - y.getY(i, j, g, h) * FastMath.cos(a(i) - a(j) + ph(g, i) - ph(h, j));
if (i == derivationSide && g == derivationSequence && j == derivationSide && h == derivationSequence) {
return 2 * r(i) * r(j) * v(g, i) * tmpVal;
} else if (i == derivationSide && g == derivationSequence) {
return r(i) * r(j) * v(h, j) * tmpVal;
} else if (j == derivationSide && h == derivationSequence) {
return r(i) * r(j) * v(g, i) * tmpVal;
}
return 0;
}
public double dqdph(TwoSides i, TwoSides j, SequenceType g, SequenceType h,
TwoSides derivationSide, SequenceType derivationSequence) {
if (i == derivationSide && g == derivationSequence && j == derivationSide && h == derivationSequence) {
return 0;
} else if (i == derivationSide && g == derivationSequence) {
return r(i) * r(j) * v(g, i) * v(h, j) * (y.getX(i, j, g, h) * FastMath.cos(a(i) - a(j) + ph(g, i) - ph(h, j)) + y.getY(i, j, g, h) * FastMath.sin(a(i) - a(j) + ph(g, i) - ph(h, j)));
} else if (j == derivationSide && h == derivationSequence) {
return r(i) * r(j) * v(g, i) * v(h, j) * (y.getX(i, j, g, h) * -FastMath.cos(a(i) - a(j) + ph(g, i) - ph(h, j)) + y.getY(i, j, g, h) * FastMath.sin(a(i) - a(j) + ph(g, i) - ph(h, j)));
}
return 0;
}
public double p(TwoSides i, TwoSides j, SequenceType g, SequenceType h) {
return r(i) * r(j) * v(g, i) * v(h, j) * (y.getX(i, j, g, h) * FastMath.cos(a(i) - a(j) + ph(g, i) - ph(h, j))
+ y.getY(i, j, g, h) * FastMath.sin(a(i) - a(j) + ph(g, i) - ph(h, j)));
}
public double q(TwoSides i, TwoSides j, SequenceType g, SequenceType h) {
return r(i) * r(j) * v(g, i) * v(h, j) * (y.getX(i, j, g, h) * FastMath.sin(a(i) - a(j) + ph(g, i) - ph(h, j))
- y.getY(i, j, g, h) * FastMath.cos(a(i) - a(j) + ph(g, i) - ph(h, j)));
}
public double dp(TwoSides i, TwoSides j, SequenceType g, SequenceType h,
TwoSides derivationSide, SequenceType derivationSequence, boolean phase) {
if (phase) {
return dpdph(i, j, g, h, derivationSide, derivationSequence);
} else {
return dpdv(i, j, g, h, derivationSide, derivationSequence);
}
}
public double dq(TwoSides i, TwoSides j, SequenceType g, SequenceType h,
TwoSides derivationSide, SequenceType derivationSequence, boolean phase) {
if (phase) {
return dqdph(i, j, g, h, derivationSide, derivationSequence);
} else {
return dqdv(i, j, g, h, derivationSide, derivationSequence);
}
}
public double s() {
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) { // P
return p(i, i, sequenceType, SequenceType.ZERO)
+ p(i, i, sequenceType, SequenceType.POSITIVE)
+ p(i, i, sequenceType, SequenceType.NEGATIVE)
+ p(i, j, sequenceType, SequenceType.ZERO)
+ p(i, j, sequenceType, SequenceType.POSITIVE)
+ p(i, j, sequenceType, SequenceType.NEGATIVE);
} else { // Q
return q(i, i, sequenceType, SequenceType.ZERO)
+ q(i, i, sequenceType, SequenceType.POSITIVE)
+ q(i, i, sequenceType, SequenceType.NEGATIVE)
+ q(i, j, sequenceType, SequenceType.ZERO)
+ q(i, j, sequenceType, SequenceType.POSITIVE)
+ q(i, j, sequenceType, SequenceType.NEGATIVE);
}
}
public double ds(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) {
// dP
return dp(i, i, sequenceType, SequenceType.ZERO, derivationSide, derivationSequence, phase)
+ dp(i, i, sequenceType, SequenceType.POSITIVE, derivationSide, derivationSequence, phase)
+ dp(i, i, sequenceType, SequenceType.NEGATIVE, derivationSide, derivationSequence, phase)
+ dp(i, j, sequenceType, SequenceType.ZERO, derivationSide, derivationSequence, phase)
+ dp(i, j, sequenceType, SequenceType.POSITIVE, derivationSide, derivationSequence, phase)
+ dp(i, j, sequenceType, SequenceType.NEGATIVE, derivationSide, derivationSequence, phase);
} else {
// dQ
return dq(i, i, sequenceType, SequenceType.ZERO, derivationSide, derivationSequence, phase)
+ dq(i, i, sequenceType, SequenceType.POSITIVE, derivationSide, derivationSequence, phase)
+ dq(i, i, sequenceType, SequenceType.NEGATIVE, derivationSide, derivationSequence, phase)
+ dq(i, j, sequenceType, SequenceType.ZERO, derivationSide, derivationSequence, phase)
+ dq(i, j, sequenceType, SequenceType.POSITIVE, derivationSide, derivationSequence, phase)
+ dq(i, j, sequenceType, SequenceType.NEGATIVE, derivationSide, derivationSequence, phase);
}
}
@Override
public double eval() {
return s();
}
@Override
public double der(Variable<AcVariableType> variable) {
Objects.requireNonNull(variable);
return ds(variable);
}
@Override
public String getName() {
return "ac_pq_coupled_closed";
}
}