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

Computing Hvdc line loss in AC emulation #1062

Merged
merged 24 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
67346d7
Added HVDC line loss in AC emulation
SylvestreSakti Jul 10, 2024
7b60f08
Added newline for checkstyle
SylvestreSakti Jul 10, 2024
a15c4e7
Added newline for checkstyle
SylvestreSakti Jul 10, 2024
f6c740b
Modified tests to keep same behaviour with HVDC line resistance in AC…
SylvestreSakti Jul 10, 2024
cf2eb5f
Keeps r in ohms and its getter returns value in per unit
SylvestreSakti Jul 10, 2024
fba1fc4
Modified implementation of line losses with the method getHvdcLineLosses
SylvestreSakti Jul 10, 2024
ba21575
Added FIXME comment to use HvdcUtils.getHvdcLineLosses() from powsybl…
SylvestreSakti Jul 10, 2024
86189c4
Modified one test to check the correct sign of the influence of R in …
SylvestreSakti Jul 10, 2024
a7e9dac
Checkstyle corrections
SylvestreSakti Jul 10, 2024
b6707f5
Added comments to explain test of difference between R=0 and R!=0
SylvestreSakti Jul 10, 2024
65069d7
Use of HvdcUtils.getHvdcLineLosses with new release of powsybl-core
SylvestreSakti Jul 12, 2024
90809f6
Fixed for checkstyle
SylvestreSakti Jul 12, 2024
35bdfbb
Merge branch 'main' into hvdc-line-loss-ac-emulation
annetill Jul 15, 2024
860ee50
Modified to have more common code in AbstractHvdcAcEmulationFlowEquat…
SylvestreSakti Jul 15, 2024
e9cb339
Fixed tests to take cable loss into account
SylvestreSakti Jul 15, 2024
a2fb18c
Changed signs to avoid confusion
SylvestreSakti Jul 15, 2024
74dface
Added assert to check sign of powers
SylvestreSakti Jul 15, 2024
50ecc4d
Rename methods and added comments
SylvestreSakti Jul 15, 2024
8c2af3f
Fixed error in checking sign of losses
SylvestreSakti Jul 15, 2024
423aeeb
Merge branch 'main' into hvdc-line-loss-ac-emulation
annetill Jul 16, 2024
b8dc6dd
Removed unused line
SylvestreSakti Jul 16, 2024
6fc2c5a
Renamed variables
SylvestreSakti Jul 16, 2024
47a137e
Renamed variable for better comprehension
SylvestreSakti Jul 16, 2024
e8fd904
Changed boundedP to rawP in checking controller station
SylvestreSakti Jul 16, 2024
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
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
<slf4jtoys.version>1.6.3</slf4jtoys.version>
<asciitable.version>0.3.2</asciitable.version>

<powsybl-core.version>6.4.0</powsybl-core.version>
<powsybl-core.version>6.4.1</powsybl-core.version>
</properties>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.network.LfHvdc;

import com.powsybl.iidm.network.util.HvdcUtils;

import java.util.List;

/**
Expand All @@ -30,6 +32,8 @@ public abstract class AbstractHvdcAcEmulationFlowEquationTerm extends AbstractEl

protected final double p0;

protected final double r;

protected final double lossFactor1;

protected final double lossFactor2;
Expand All @@ -45,6 +49,7 @@ protected AbstractHvdcAcEmulationFlowEquationTerm(LfHvdc hvdc, LfBus bus1, LfBus
variables = List.of(ph1Var, ph2Var);
k = hvdc.getDroop() * 180 / Math.PI;
p0 = hvdc.getP0();
r = hvdc.getR();
lossFactor1 = hvdc.getConverterStation1().getLossFactor() / 100;
lossFactor2 = hvdc.getConverterStation2().getLossFactor() / 100;
pMaxFromCS1toCS2 = hvdc.getPMaxFromCS1toCS2();
Expand Down Expand Up @@ -78,6 +83,10 @@ protected double getVscLossMultiplier() {
return (1 - lossFactor1) * (1 - lossFactor2);
}

protected static double getHvdcLineLosses(double rectifierPDc, double r) {
return HvdcUtils.getHvdcLineLosses(rectifierPDc, 1, r);
}

@Override
public List<Variable<AcVariableType>> getVariables() {
return variables;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ public HvdcAcEmulationSide1ActiveFlowEquationTerm(LfHvdc hvdc, LfBus bus1, LfBus
}

private double p1(double ph1, double ph2) {
double rawP = rawP(p0, k, ph1, ph2);
double boundedP = boundedP(rawP);
return (isController(rawP) ? 1 : getVscLossMultiplier()) * boundedP;
double rawP = boundedP(rawP(p0, k, ph1, ph2));
if (isController(rawP)) {
return rawP;
} else {
double rectifierPDc = (1 - lossFactor1) * rawP;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you try to put more commun code in the abstract?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some modifications have been done, especially by creating a method getAbsActivePowerWithLosses() that computes the absolute value of the active power taking into account loss of converters (in the correct order depending on the direction of the transit) and the line loss.

return (1 - lossFactor2) * (rectifierPDc - getHvdcLineLosses(rectifierPDc, r));
}
}

private static boolean isController(double rawP) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ public HvdcAcEmulationSide2ActiveFlowEquationTerm(LfHvdc hvdc, LfBus bus1, LfBus
}

private double p2(double ph1, double ph2) {
double rawP = rawP(p0, k, ph1, ph2);
double boundedP = boundedP(rawP);
return -(isController(rawP) ? 1 : getVscLossMultiplier()) * boundedP;
double rawP = boundedP(rawP(p0, k, ph1, ph2));
if (isController(rawP)) {
return -rawP;
} else {
double rectifierPDc = -(1 - lossFactor2) * rawP;
return (1 - lossFactor1) * (rectifierPDc + getHvdcLineLosses(rectifierPDc, r));
}
}

private boolean isController(double rawP) {
Expand All @@ -40,7 +44,7 @@ private boolean isInOperatingRange(double rawP) {
private double dp2dph1(double ph1, double ph2) {
double rawP = rawP(p0, k, ph1, ph2);
if (isInOperatingRange(rawP)) {
return -(isController(rawP) ? 1 : getVscLossMultiplier()) * k;
return -(isController(rawP) ? 1 : getVscLossMultiplier()) * k; // derivative of cable loss is neglected
} else {
return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/powsybl/openloadflow/network/LfHvdc.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public interface LfHvdc extends LfElement {

double getDroop();

double getR();

double getP0();

boolean isAcEmulation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public class LfHvdcImpl extends AbstractElement implements LfHvdc {

private double p0 = Double.NaN;

private double r = Double.NaN;

private double nominalV = Double.NaN;

private LfVscConverterStation converterStation1;

private LfVscConverterStation converterStation2;
Expand All @@ -52,6 +56,8 @@ public LfHvdcImpl(String id, LfBus bus1, LfBus bus2, LfNetwork network, HvdcLine
this.id = Objects.requireNonNull(id);
this.bus1 = bus1;
this.bus2 = bus2;
this.nominalV = hvdcLine.getNominalV();
this.r = hvdcLine.getR();
HvdcAngleDroopActivePowerControl droopControl = hvdcLine.getExtension(HvdcAngleDroopActivePowerControl.class);
this.acEmulation = acEmulation && droopControl != null && droopControl.isEnabled();
if (this.acEmulation) {
Expand Down Expand Up @@ -128,6 +134,11 @@ public double getDroop() {
return droop / PerUnit.SB;
}

@Override
public double getR() {
return r / PerUnit.zb(nominalV);
}

@Override
public double getP0() {
return p0 / PerUnit.SB;
Expand Down
1 change: 1 addition & 0 deletions src/test/java/com/powsybl/openloadflow/EquationsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ void hvdcTest() {
Mockito.doReturn(false).when(hvdc).isDisabled();
Mockito.doReturn(DROOP).when(hvdc).getDroop();
Mockito.doReturn(P_0).when(hvdc).getP0();
Mockito.doReturn(0d).when(hvdc).getR();
Mockito.doReturn(Double.MAX_VALUE).when(hvdc).getPMaxFromCS1toCS2();
Mockito.doReturn(Double.MAX_VALUE).when(hvdc).getPMaxFromCS2toCS1();
LfVscConverterStationImpl station1 = Mockito.mock(LfVscConverterStationImpl.class, new RuntimeExceptionAnswer());
Expand Down
33 changes: 33 additions & 0 deletions src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowVscTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,20 @@ void testHvdcPowerAcEmulation() {
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowResult result = loadFlowRunner.run(network, new LoadFlowParameters());
assertTrue(result.isFullyConverged());
// AC Emulation takes into account cable loss
assertActivePowerEquals(198.158, network.getHvdcConverterStation("cs2").getTerminal());
assertActivePowerEquals(-193.799, network.getHvdcConverterStation("cs3").getTerminal());
assertActivePowerEquals(-304.359, network.getGenerator("g1").getTerminal());
assertActivePowerEquals(300.0, network.getLoad("l4").getTerminal());
}

@Test
void testHvdcPowerAcEmulationWithoutR() {
Network network = HvdcNetworkFactory.createHvdcLinkedByTwoLinesAndSwitch();
network.getHvdcLine("hvdc23").setR(0d); //Removing resistance to ignore cable loss
LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
LoadFlowResult result = loadFlowRunner.run(network, new LoadFlowParameters());
assertTrue(result.isFullyConverged());
assertActivePowerEquals(198.158, network.getHvdcConverterStation("cs2").getTerminal());
assertActivePowerEquals(-193.822, network.getHvdcConverterStation("cs3").getTerminal());
assertActivePowerEquals(-304.335, network.getGenerator("g1").getTerminal());
Expand All @@ -293,7 +307,16 @@ void testHvdcDirectionChangeAcEmulation() {
assertTrue(pcs2 < 0, "Power delivered by cs2");
assertTrue(Math.abs(pcs1) > Math.abs(pcs2), "Loss at HVDC output");

// Test if removing line resistance increases the power transit
network.getHvdcLine("hvdc12").setR(0d);
result = loadFlowRunner.run(network, new LoadFlowParameters());
assertTrue(result.isFullyConverged());
double pcs1r0 = network.getVscConverterStation("cs1").getTerminal().getP();
double pcs2r0 = network.getVscConverterStation("cs2").getTerminal().getP();
assertTrue(pcs1r0 - pcs2r0 < pcs1 - pcs2); // Check that loss with R=0 is lower than loss with R!=0

// Reverse power flow direction
network.getHvdcLine("hvdc12").setR(0.1d);
network.getGenerator("g2").setTargetP(5);
network.getGenerator("g1").setTargetP(0);
result = loadFlowRunner.run(network, new LoadFlowParameters());
Expand All @@ -312,6 +335,14 @@ void testHvdcDirectionChangeAcEmulation() {
assertTrue(pcs2 > 0, "Power enters at cs2");
assertTrue(pcs1 < 0, "Power delivered by cs1");
assertTrue(Math.abs(pcs2) > Math.abs(pcs1), "Loss at HVDC output");

// Test if removing line resistance increases the power transit in symetric network
network.getHvdcLine("hvdc12").setR(0d);
result = loadFlowRunner.run(network, new LoadFlowParameters());
assertTrue(result.isFullyConverged());
pcs1r0 = network.getVscConverterStation("cs1").getTerminal().getP();
pcs2r0 = network.getVscConverterStation("cs2").getTerminal().getP();
assertTrue(pcs2r0 - pcs1r0 < pcs2 - pcs1); // Check that loss with R=0 is lower than loss with R!=0
}

@Test
Expand Down Expand Up @@ -450,6 +481,7 @@ void testAcEmuWithOperationalLimits() {
Network network = HvdcNetworkFactory.createHvdcLinkedByTwoLinesAndSwitch(HvdcConverterStation.HvdcType.VSC);
// without limit p=195
network.getHvdcLine("hvdc23")
.setR(0d) //Removing resistance to ignore cable loss
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a general comment, if unit tests changed because we improve/fix something, we prefer to fix them than to retry to code the old behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, then the values of the tests have been updated with the new behavior (that have been verified). A new test had been added for the case without R to have an independant test ignoring line loss.

.newExtension(HvdcOperatorActivePowerRangeAdder.class)
.withOprFromCS2toCS1(180)
.withOprFromCS1toCS2(170)
Expand Down Expand Up @@ -482,6 +514,7 @@ void testAcEmuAndPMax() {
Network network = HvdcNetworkFactory.createHvdcLinkedByTwoLinesAndSwitch(HvdcConverterStation.HvdcType.VSC);
// without limit p=195
network.getHvdcLine("hvdc23")
.setR(0d) //Removing resistance to ignore cable loss
.setMaxP(170);

LoadFlow.Runner loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1284,6 +1284,7 @@ void testVSCLossAcEmulation() {
// but other converter station keeps its voltage control capability.
// remedial action re-enables the ac emulation of the hvdc line.
Network network = HvdcNetworkFactory.createHvdcLinkedByTwoLinesAndSwitch(HvdcConverterStation.HvdcType.VSC);
network.getHvdcLine("hvdc23").setR(0d); //Removing resistance to ignore cable loss
List<Contingency> contingencies = List.of(new Contingency("contingency", new LineContingency("l12")));
List<Action> actions = List.of(new SwitchAction("action", "s2", false));
List<OperatorStrategy> operatorStrategies = List.of(new OperatorStrategy("strategy",
Expand Down Expand Up @@ -1330,6 +1331,7 @@ void testHvdcDisconnectedThenConnectedByStrategy() {
List<StateMonitor> monitors = createNetworkMonitors(network);

// with AC emulation first
network.getHvdcLine("hvdc23").setR(0d); //Removing resistance to ignore cable loss in AC emulation
SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, new SecurityAnalysisParameters(),
operatorStrategies, actions, ReportNode.NO_OP);

Expand All @@ -1349,6 +1351,7 @@ void testHvdcDisconnectedThenConnectedByStrategy() {
// without AC emulation
SecurityAnalysisParameters parameters = new SecurityAnalysisParameters();
parameters.getLoadFlowParameters().setHvdcAcEmulation(false);
network.getHvdcLine("hvdc23").setR(0.1d); //Putting back resistance of the cable to keep same old behaviour
SecurityAnalysisResult result2 = runSecurityAnalysis(network, contingencies, monitors, parameters,
operatorStrategies, actions, ReportNode.NO_OP);

Expand Down