Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getI() method to DanglingLine's boundary #3168

Merged
merged 18 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public interface Boundary {
*/
double getQ();

/**
* Get the current in A at the fictitious boundary terminal.
*/
double getI();

/**
* Get the danglingLine the boundary is associated to.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ public double getQ() {
}
}

@Override
public double getI() {
if (useHypothesis(parent)) {
return Math.hypot(getP(), getQ()) / (Math.sqrt(3.) * getV() / 1000);
}
Terminal t = parent.getTerminal();
Bus b = t.getBusView().getBus();
if (zeroImpedance(parent)) {
return t.getI();
} else {
return new SV(t.getP(), t.getQ(), getV(b), getAngle(b), TwoSides.ONE).otherSideI(parent, false);
}
}

@Override
public DanglingLine getDanglingLine() {
return parent;
Expand Down
12 changes: 12 additions & 0 deletions iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/SV.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ public double getA() {
return a;
}

public double getI() {
return Math.hypot(p, q) / (Math.sqrt(3.) * u / 1000);
}

public TwoSides getSide() {
return side;
}
Expand Down Expand Up @@ -162,6 +166,14 @@ public double otherSideA(DanglingLine dl, boolean splitShuntAdmittance) {
return otherSide(dl, splitShuntAdmittance).getA();
}

public double otherSideI(DanglingLine dl) {
return otherSide(dl).getI();
}

public double otherSideI(DanglingLine dl, boolean splitShuntAdmittance) {
return otherSide(dl, splitShuntAdmittance).getI();
}

private static double getRho(TwoWindingsTransformer twt) {
double rho = twt.getRatedU2() / twt.getRatedU1();
if (twt.getRatioTapChanger() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,45 +59,53 @@ void testDanglingLine() {
double q1 = -77.444122;
double v1 = 118.13329315185547;
double a1 = 0.19568365812301636;
double i1 = 726.224579;

double p2 = 15.098317;
double q2 = 64.333028;
double v2 = 138.0;
double a2 = 0.0;
double i2 = 276.462893;

SV svA1 = new SV(p1, q1, v1, a1, TwoSides.ONE);
SV svA2 = svA1.otherSide(dl);
assertEquals(p2, svA2.getP(), tol);
assertEquals(q2, svA2.getQ(), tol);
assertEquals(v2, svA2.getU(), tol);
assertEquals(a2, svA2.getA(), tol);
assertEquals(i2, svA2.getI(), tol);

SV svB2 = new SV(p2, q2, v2, a2, TwoSides.TWO);
SV svB1 = svB2.otherSide(dl);
assertEquals(p1, svB1.getP(), tol);
assertEquals(q1, svB1.getQ(), tol);
assertEquals(v1, svB1.getU(), tol);
assertEquals(a1, svB1.getA(), tol);
assertEquals(i1, svB1.getI(), tol);

assertEquals(p2, svA1.otherSideP(dl), tol);
assertEquals(q2, svA1.otherSideQ(dl), tol);
assertEquals(v2, svA1.otherSideU(dl), tol);
assertEquals(a2, svA1.otherSideA(dl), tol);
assertEquals(i2, svA1.otherSideI(dl), tol);

assertEquals(p1, svB2.otherSideP(dl), tol);
assertEquals(q1, svB2.otherSideQ(dl), tol);
assertEquals(v1, svB2.otherSideU(dl), tol);
assertEquals(a1, svB2.otherSideA(dl), tol);
assertEquals(i1, svB2.otherSideI(dl), tol);

assertEquals(p2, svA1.otherSideP(dl, false), tol);
assertEquals(q2, svA1.otherSideQ(dl, false), tol);
assertEquals(v2, svA1.otherSideU(dl, false), tol);
assertEquals(a2, svA1.otherSideA(dl, false), tol);
assertEquals(i2, svA1.otherSideI(dl, false), tol);

assertEquals(p1, svB2.otherSideP(dl, false), tol);
assertEquals(q1, svB2.otherSideQ(dl, false), tol);
assertEquals(v1, svB2.otherSideU(dl, false), tol);
assertEquals(a1, svB2.otherSideA(dl, false), tol);
assertEquals(i1, svB2.otherSideI(dl, false), tol);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,14 @@ void tieLineTest0() {
assertTrue(compare(caseSv0.nodeBoundary.a, tieLine.getDanglingLine1().getBoundary().getAngle(), isvHalf1.getA()));
assertTrue(compare(getP(caseSv0.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getP(), isvHalf1.getP()));
assertTrue(compare(getQ(caseSv0.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getQ(), isvHalf1.getQ()));
assertTrue(compare(getI(caseSv0.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getI(), isvHalf1.getI()));

SV isvHalf2 = initialHalf2SvBoundary(caseSv0, initialModelCase(TwoSides.TWO, TwoSides.ONE), TwoSides.ONE);
assertTrue(compare(caseSv0.nodeBoundary.v, tieLine.getDanglingLine2().getBoundary().getV(), isvHalf2.getU()));
assertTrue(compare(caseSv0.nodeBoundary.a, tieLine.getDanglingLine2().getBoundary().getAngle(), isvHalf2.getA()));
assertTrue(compare(getP(caseSv0.line2, TwoSides.ONE), tieLine.getDanglingLine2().getBoundary().getP(), isvHalf2.getP()));
assertTrue(compare(getQ(caseSv0.line2, TwoSides.ONE), tieLine.getDanglingLine2().getBoundary().getQ(), isvHalf2.getQ()));
assertTrue(compare(getI(caseSv0.line2, TwoSides.ONE), tieLine.getDanglingLine2().getBoundary().getI(), isvHalf2.getI()));
}

@Test
Expand Down Expand Up @@ -92,12 +94,14 @@ void tieLineTest1() {
assertTrue(compare(caseSv1.nodeBoundary.a, tieLine.getDanglingLine1().getBoundary().getAngle(), isvHalf1.getA()));
assertTrue(compare(getP(caseSv1.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getP(), isvHalf1.getP()));
assertTrue(compare(getQ(caseSv1.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getQ(), isvHalf1.getQ()));
assertTrue(compare(getI(caseSv1.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getI(), isvHalf1.getI()));

SV isvHalf2 = initialHalf2SvBoundary(caseSv1, initialModelCase(TwoSides.TWO, TwoSides.TWO), TwoSides.TWO);
assertTrue(compare(caseSv1.nodeBoundary.v, tieLine.getDanglingLine2().getBoundary().getV(), isvHalf2.getU()));
assertTrue(compare(caseSv1.nodeBoundary.a, tieLine.getDanglingLine2().getBoundary().getAngle(), isvHalf2.getA()));
assertTrue(compare(getP(caseSv1.line2, TwoSides.TWO), tieLine.getDanglingLine2().getBoundary().getP(), isvHalf2.getP()));
assertTrue(compare(getQ(caseSv1.line2, TwoSides.TWO), tieLine.getDanglingLine2().getBoundary().getQ(), isvHalf2.getQ()));
assertTrue(compare(getI(caseSv1.line2, TwoSides.TWO), tieLine.getDanglingLine2().getBoundary().getI(), isvHalf2.getI()));
}

@Test
Expand Down Expand Up @@ -127,12 +131,14 @@ void tieLineTest2() {
assertTrue(compare(caseSv2.nodeBoundary.a, tieLine.getDanglingLine1().getBoundary().getAngle(), isvHalf1.getA()));
assertTrue(compare(getP(caseSv2.line1, TwoSides.ONE), tieLine.getDanglingLine1().getBoundary().getP(), isvHalf1.getP()));
assertTrue(compare(getQ(caseSv2.line1, TwoSides.ONE), tieLine.getDanglingLine1().getBoundary().getQ(), isvHalf1.getQ()));
assertTrue(compare(getI(caseSv2.line1, TwoSides.ONE), tieLine.getDanglingLine1().getBoundary().getI(), isvHalf1.getI()));

SV isvHalf2 = initialHalf2SvBoundary(caseSv2, initialModelCase(TwoSides.ONE, TwoSides.ONE), TwoSides.ONE);
assertTrue(compare(caseSv2.nodeBoundary.v, tieLine.getDanglingLine2().getBoundary().getV(), isvHalf2.getU()));
assertTrue(compare(caseSv2.nodeBoundary.a, tieLine.getDanglingLine2().getBoundary().getAngle(), isvHalf2.getA()));
assertTrue(compare(getP(caseSv2.line2, TwoSides.ONE), tieLine.getDanglingLine2().getBoundary().getP(), isvHalf2.getP()));
assertTrue(compare(getQ(caseSv2.line2, TwoSides.ONE), tieLine.getDanglingLine2().getBoundary().getQ(), isvHalf2.getQ()));
assertTrue(compare(getI(caseSv2.line2, TwoSides.ONE), tieLine.getDanglingLine2().getBoundary().getI(), isvHalf2.getI()));
}

@Test
Expand Down Expand Up @@ -162,12 +168,14 @@ void tieLineTest3() {
assertTrue(compare(caseSv3.nodeBoundary.a, tieLine.getDanglingLine1().getBoundary().getAngle(), isvHalf1.getA()));
assertTrue(compare(getP(caseSv3.line1, TwoSides.ONE), tieLine.getDanglingLine1().getBoundary().getP(), isvHalf1.getP()));
assertTrue(compare(getQ(caseSv3.line1, TwoSides.ONE), tieLine.getDanglingLine1().getBoundary().getQ(), isvHalf1.getQ()));
assertTrue(compare(getI(caseSv3.line1, TwoSides.ONE), tieLine.getDanglingLine1().getBoundary().getI(), isvHalf1.getI()));

SV isvHalf2 = initialHalf2SvBoundary(caseSv3, initialModelCase(TwoSides.ONE, TwoSides.TWO), TwoSides.TWO);
assertTrue(compare(caseSv3.nodeBoundary.v, tieLine.getDanglingLine2().getBoundary().getV(), isvHalf2.getU()));
assertTrue(compare(caseSv3.nodeBoundary.a, tieLine.getDanglingLine2().getBoundary().getAngle(), isvHalf2.getA()));
assertTrue(compare(getP(caseSv3.line2, TwoSides.TWO), tieLine.getDanglingLine2().getBoundary().getP(), isvHalf2.getP()));
assertTrue(compare(getQ(caseSv3.line2, TwoSides.TWO), tieLine.getDanglingLine2().getBoundary().getQ(), isvHalf2.getQ()));
assertTrue(compare(getI(caseSv3.line2, TwoSides.TWO), tieLine.getDanglingLine2().getBoundary().getI(), isvHalf2.getI()));
}

@Test
Expand Down Expand Up @@ -197,12 +205,51 @@ void tieLineWithDifferentNominalVoltageAtEndsTest() {
assertTrue(compare(caseSv.nodeBoundary.a, tieLine.getDanglingLine1().getBoundary().getAngle(), isvHalf1.getA()));
assertTrue(compare(getP(caseSv.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getP(), isvHalf1.getP()));
assertTrue(compare(getQ(caseSv.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getQ(), isvHalf1.getQ()));
assertTrue(compare(getI(caseSv.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getI(), isvHalf1.getI()));

SV isvHalf2 = initialHalf2SvBoundary(caseSv, initialModelDifferentVlCase(TwoSides.TWO, TwoSides.ONE), TwoSides.ONE);
assertTrue(compare(caseSv.nodeBoundary.v, tieLine.getDanglingLine2().getBoundary().getV(), isvHalf2.getU()));
assertTrue(compare(caseSv.nodeBoundary.a, tieLine.getDanglingLine2().getBoundary().getAngle(), isvHalf2.getA()));
assertTrue(compare(getP(caseSv.line2, TwoSides.ONE), tieLine.getDanglingLine2().getBoundary().getP(), isvHalf2.getP()));
assertTrue(compare(getQ(caseSv.line2, TwoSides.ONE), tieLine.getDanglingLine2().getBoundary().getQ(), isvHalf2.getQ()));
assertTrue(compare(getI(caseSv.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getI(), isvHalf1.getI()));
}

@Test
void tieLineWithNaNVoltagesTest() {

// Line1 from node1 to boundaryNode, Line2 from boundaryNode to node2
CaseSv caseSv = createCaseNaNVoltages();
Network n = createNetworkWithTieLineWithDifferentNominalVoltageAtEnds(NetworkFactory.findDefault(), TwoSides.TWO, TwoSides.ONE, caseSv);
TieLine tieLine = n.getTieLine("TWO + ONE");

SV sv2 = new SV(tieLine.getDanglingLine1().getTerminal().getP(), tieLine.getDanglingLine1().getTerminal().getQ(),
tieLine.getDanglingLine1().getTerminal().getBusView().getBus().getV(),
tieLine.getDanglingLine1().getTerminal().getBusView().getBus().getAngle(),
TwoSides.ONE).otherSide(tieLine);
SV isv2 = initialSv2(caseSv, initialModelDifferentVlCase(TwoSides.TWO, TwoSides.ONE), TwoSides.TWO, TwoSides.ONE);
assertTrue(compare(sv2, caseSv.node2, caseSv.line2, TwoSides.ONE, isv2));

SV sv1 = new SV(tieLine.getDanglingLine2().getTerminal().getP(), tieLine.getDanglingLine2().getTerminal().getQ(),
tieLine.getDanglingLine2().getTerminal().getBusView().getBus().getV(),
tieLine.getDanglingLine2().getTerminal().getBusView().getBus().getAngle(),
TwoSides.TWO).otherSide(tieLine);
SV isv1 = initialSv1(caseSv, initialModelDifferentVlCase(TwoSides.TWO, TwoSides.ONE), TwoSides.TWO, TwoSides.ONE);
assertTrue(compare(sv1, caseSv.node1, caseSv.line1, TwoSides.TWO, isv1));

SV isvHalf1 = initialHalf1SvBoundary(caseSv, initialModelDifferentVlCase(TwoSides.TWO, TwoSides.ONE), TwoSides.TWO);
assertTrue(compare(caseSv.nodeBoundary.v, tieLine.getDanglingLine1().getBoundary().getV(), isvHalf1.getU()));
assertTrue(compare(caseSv.nodeBoundary.a, tieLine.getDanglingLine1().getBoundary().getAngle(), isvHalf1.getA()));
assertTrue(compare(getP(caseSv.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getP(), isvHalf1.getP()));
assertTrue(compare(getQ(caseSv.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getQ(), isvHalf1.getQ()));
assertTrue(compare(getI(caseSv.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getI(), isvHalf1.getI()));

SV isvHalf2 = initialHalf2SvBoundary(caseSv, initialModelDifferentVlCase(TwoSides.TWO, TwoSides.ONE), TwoSides.ONE);
assertTrue(compare(caseSv.nodeBoundary.v, tieLine.getDanglingLine2().getBoundary().getV(), isvHalf2.getU()));
assertTrue(compare(caseSv.nodeBoundary.a, tieLine.getDanglingLine2().getBoundary().getAngle(), isvHalf2.getA()));
assertTrue(compare(getP(caseSv.line2, TwoSides.ONE), tieLine.getDanglingLine2().getBoundary().getP(), isvHalf2.getP()));
assertTrue(compare(getQ(caseSv.line2, TwoSides.ONE), tieLine.getDanglingLine2().getBoundary().getQ(), isvHalf2.getQ()));
assertTrue(compare(getI(caseSv.line1, TwoSides.TWO), tieLine.getDanglingLine1().getBoundary().getI(), isvHalf1.getI()));
}

@Test
Expand Down Expand Up @@ -553,6 +600,14 @@ private static double getQ(LineSv line, TwoSides boundarySide) {
}
}

private static double getI(LineSv line, TwoSides boundarySide) {
if (boundarySide == TwoSides.ONE) {
return line.getI1();
} else {
return line.getI2();
}
}

// We define an error by value to adjust the case. The error is calculated by difference between
// the calculated value with both models, the initial model of the case and the current model of the danglingLine
// Errors are due to the danglingLine model (it does not allow shunt admittance at both ends)
Expand Down Expand Up @@ -595,8 +650,8 @@ private static CaseSv createCase0() {
NodeSv nodeBoundary = new NodeSv(1.05913402, Math.toDegrees(-0.01700730));
NodeSv node2 = new NodeSv(1.04546576, Math.toDegrees(-0.04168907));

LineSv line1 = new LineSv(0.32101578, -0.16210107, -0.26328124, 0.00991455);
LineSv line2 = new LineSv(0.26328124, -0.00991455, -0.21700000, -0.12700000);
LineSv line1 = new LineSv(0.32101578, -0.16210107, -0.26328124, 0.00991455, node1.v, nodeBoundary.v);
LineSv line2 = new LineSv(0.26328124, -0.00991455, -0.21700000, -0.12700000, nodeBoundary.v, node2.v);
return new CaseSv(node1, node2, nodeBoundary, line1, line2);
}

Expand All @@ -606,8 +661,8 @@ private static CaseSv createCase1() {
NodeSv nodeBoundary = new NodeSv(1.05916756, Math.toDegrees(-0.01702560));
NodeSv node2 = new NodeSv(1.04216358, Math.toDegrees(-0.03946400));

LineSv line1 = new LineSv(0.32116645, -0.16274609, -0.26342655, 0.01056498);
LineSv line2 = new LineSv(-0.21700000, -0.12700000, 0.26342655, -0.01056498);
LineSv line1 = new LineSv(0.32116645, -0.16274609, -0.26342655, 0.01056498, node1.v, nodeBoundary.v);
LineSv line2 = new LineSv(-0.21700000, -0.12700000, 0.26342655, -0.01056498, node2.v, nodeBoundary.v);
return new CaseSv(node1, node2, nodeBoundary, line1, line2);
}

Expand All @@ -617,8 +672,8 @@ private static CaseSv createCase2() {
NodeSv nodeBoundary = new NodeSv(1.05998661, Math.toDegrees(-0.01660626));
NodeSv node2 = new NodeSv(1.04634503, Math.toDegrees(-0.04125738));

LineSv line1 = new LineSv(-0.26335112, 0.01016197, 0.32106283, -0.16270573);
LineSv line2 = new LineSv(0.26335112, -0.01016197, -0.21700000, -0.12700000);
LineSv line1 = new LineSv(-0.26335112, 0.01016197, 0.32106283, -0.16270573, nodeBoundary.v, node1.v);
LineSv line2 = new LineSv(0.26335112, -0.01016197, -0.21700000, -0.12700000, nodeBoundary.v, node2.v);
return new CaseSv(node1, node2, nodeBoundary, line1, line2);
}

Expand All @@ -628,21 +683,33 @@ private static CaseSv createCase3() {
NodeSv nodeBoundary = new NodeSv(1.06002014, Math.toDegrees(-0.01662448));
NodeSv node2 = new NodeSv(1.04304009, Math.toDegrees(-0.03903205));

LineSv line1 = new LineSv(-0.26349561, 0.01081185, 0.32121215, -0.16335034);
LineSv line2 = new LineSv(-0.21700000, -0.12700000, 0.26349561, -0.01081185);
LineSv line1 = new LineSv(-0.26349561, 0.01081185, 0.32121215, -0.16335034, nodeBoundary.v, node1.v);
LineSv line2 = new LineSv(-0.21700000, -0.12700000, 0.26349561, -0.01081185, node2.v, nodeBoundary.v);
return new CaseSv(node1, node2, nodeBoundary, line1, line2);
}

// Line1 from nodeBoundary to node1, Line2 from node2 to nodeBoundary
// Line1 from node1 to nodeBoundary, Line2 from nodeBoundary to node2
// Different nominal voltage at node1 and node2
private static CaseSv createCaseDifferentNominalVoltageAtEnds() {
NodeSv node1 = new NodeSv(145.2861673277147, Math.toDegrees(-0.01745197));
NodeSv nodeBoundary = new NodeSv(145.42378472578227, Math.toDegrees(-0.02324020));
NodeSv node2 = new NodeSv(231.30269602522478, Math.toDegrees(-0.02818192));

LineSv line1 = new LineSv(11.729938, -8.196614, -11.713527, 1.301712);
LineSv line2 = new LineSv(11.713527, -1.301712, -11.700000, -6.700000);
LineSv line1 = new LineSv(11.729938, -8.196614, -11.713527, 1.301712, node1.v, nodeBoundary.v);
LineSv line2 = new LineSv(11.713527, -1.301712, -11.700000, -6.700000, nodeBoundary.v, node2.v);
return new CaseSv(node1, node2, nodeBoundary, line1, line2);
}

// Line1 from node1 to nodeBoundary, Line2 from nodeBoundary to node2
// Different nominal voltage at node1 and node2
// NaN values for voltages - simulates DC LF
private static CaseSv createCaseNaNVoltages() {
NodeSv node1 = new NodeSv(Double.NaN, Math.toDegrees(-0.01745197));
NodeSv nodeBoundary = new NodeSv(Double.NaN, Math.toDegrees(-0.02324020));
NodeSv node2 = new NodeSv(Double.NaN, Math.toDegrees(-0.02818192));

LineSv line1 = new LineSv(11.729938, -8.196614, -11.713527, 1.301712, node1.v, nodeBoundary.v);
LineSv line2 = new LineSv(11.713527, -1.301712, -11.700000, -6.700000, nodeBoundary.v, node2.v);
return new CaseSv(node1, node2, nodeBoundary, line1, line2);
}

Expand Down Expand Up @@ -677,12 +744,24 @@ private static final class LineSv {
private final double q1;
private final double p2;
private final double q2;
private final double v1;
private final double v2;

private LineSv(double p1, double q1, double p2, double q2) {
private LineSv(double p1, double q1, double p2, double q2, double v1, double v2) {
this.p1 = p1;
this.q1 = q1;
this.p2 = p2;
this.q2 = q2;
this.v1 = v1;
this.v2 = v2;
}

private double getI1() {
return Math.hypot(p1, q1) / (Math.sqrt(3.) * v1 / 1000);
}

private double getI2() {
return Math.hypot(p2, q2) / (Math.sqrt(3.) * v2 / 1000);
}
}

Expand Down
Loading