Skip to content

Force area boundary branches to min impedance #1218

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

Merged
merged 9 commits into from
Apr 18, 2025
7 changes: 7 additions & 0 deletions docs/loadflow/loadflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,10 @@ Indeed, in this case the slack injection can be seen as an interchange to 'the v
- Connected to only buses that have an area:
- All connected branches are boundaries of those areas: Not attributed to anyone, the mismatch will already be present in the interchange mismatch
- Some connected branches are not declared as boundaries of the areas: Amount of mismatch to distribute is split equally among the areas (added to their "total mismatch")

### Zero impedance boundary branches
The following applies when the [`lowImpedanceBranchMode`](parameters.md) is set to `REPLACE_BY_ZERO_IMPEDANCE_LINE`.
Currently, computations involving zero-impedance branches used as boundary branches are not supported.
However, it is still possible to submit network models that include zero-impedance boundary branches.
If a terminal of a zero-impedance branch is designated as a boundary, Open LoadFlow will internally assign the branch
an impedance value equal to the [`lowImpedanceThreshold`](parameters.md) parameter.
5 changes: 5 additions & 0 deletions src/main/java/com/powsybl/openloadflow/network/LfNetwork.java
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,11 @@ public void fix(boolean minImpedance, double lowImpedanceThreshold) {
|| b.isTransformerReactivePowerController() || b.isTransformerReactivePowerControlled()
|| b.getGeneratorReactivePowerControl().isPresent())
.forEach(branch -> branch.setMinZ(lowImpedanceThreshold));
// zero impedance boundary branch is not supported
areas.stream()
.flatMap(a -> a.getBoundaries().stream())
.map(LfArea.Boundary::getBranch)
.forEach(branch -> branch.setMinZ(lowImpedanceThreshold));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowProvider;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.network.impl.Networks;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
Expand Down Expand Up @@ -66,6 +67,40 @@ void twoAreasWithUnpairedDanglingLine() {
runLfTwoAreas(network, interchangeTarget1, interchangeTarget2, -10, 0);
}

@Test
void zeroImpedanceBoundaryBranchesNetworkConversion() {
Network network = MultiAreaNetworkFactory.createTwoAreasWithDanglingLine();
network.getLine("l23_A1").setX(0); // boundary
network.getDanglingLine("dl1").setX(0); // boundary
network.getLine("l12").setX(0); // not boundary

LfNetwork lfNetwork = Networks.load(network, new LfNetworkParameters().setAreaInterchangeControl(false)).get(0);
assertTrue(lfNetwork.getBranchById("dl1").isZeroImpedance(LoadFlowModel.AC));
assertTrue(lfNetwork.getBranchById("l23_A1").isZeroImpedance(LoadFlowModel.AC));
assertTrue(lfNetwork.getBranchById("l12").isZeroImpedance(LoadFlowModel.AC));

lfNetwork = Networks.load(network, new LfNetworkParameters().setAreaInterchangeControl(true)).get(0);
assertFalse(lfNetwork.getBranchById("dl1").isZeroImpedance(LoadFlowModel.AC));
assertEquals(LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE, lfNetwork.getBranchById("dl1").getPiModel().getX());
assertFalse(lfNetwork.getBranchById("l23_A1").isZeroImpedance(LoadFlowModel.AC));
assertEquals(LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE, lfNetwork.getBranchById("l23_A1").getPiModel().getX());
assertTrue(lfNetwork.getBranchById("l12").isZeroImpedance(LoadFlowModel.AC));

}

@Test
void twoAreasWithZeroImpedanceBoundaryBranches() {
Network network = MultiAreaNetworkFactory.createTwoAreasWithDanglingLine();
double interchangeTarget1 = -40;
double interchangeTarget2 = 20;
network.getLine("l23_A1").setX(0);
network.getDanglingLine("dl1").setX(0);
parametersExt.setLowImpedanceBranchMode(OpenLoadFlowParameters.LowImpedanceBranchMode.REPLACE_BY_ZERO_IMPEDANCE_LINE);
runLfTwoAreas(network, interchangeTarget1, interchangeTarget2, -10, 2);
parameters.setDc(true);
runLfTwoAreas(network, interchangeTarget1, interchangeTarget2, -10, 0);
}

@Test
void twoAreasWithTieLineTest() {
Network network = MultiAreaNetworkFactory.createTwoAreasWithTieLine();
Expand Down