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

Added support of action to reconnect branch at both side action #943

Merged
merged 6 commits into from
Jan 29, 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
10 changes: 7 additions & 3 deletions src/main/java/com/powsybl/openloadflow/network/LfAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,14 @@ private static Optional<LfAction> create(LfBranch branch, String actionId, boole
private static Optional<LfAction> create(TerminalsConnectionAction action, LfNetwork lfNetwork) {
LfBranch branch = lfNetwork.getBranchById(action.getElementId());
if (branch != null) {
if (action.getSide().isEmpty() && action.isOpen()) {
return Optional.of(new LfAction(action.getId(), branch, null, null, null, null, null));
if (action.getSide().isEmpty()) {
if (action.isOpen()) {
return Optional.of(new LfAction(action.getId(), branch, null, null, null, null, null));
} else {
return Optional.of(new LfAction(action.getId(), null, branch, null, null, null, null));
}
} else {
throw new UnsupportedOperationException("Line connection action: only open line at both sides is supported yet.");
throw new UnsupportedOperationException("Terminals connection action: only open or close branch at both sides is supported yet.");
}
}
return Optional.empty(); // could be in another component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public class LfTopoConfig {

private final Set<String> branchIdsOpenableSide2 = new HashSet<>();

private final Set<String> branchIdsToClose = new HashSet<>();

public LfTopoConfig() {
switchesToOpen = new HashSet<>();
switchesToClose = new HashSet<>();
Expand Down Expand Up @@ -83,4 +85,8 @@ public Set<String> getBranchIdsOpenableSide1() {
public Set<String> getBranchIdsOpenableSide2() {
return branchIdsOpenableSide2;
}

public Set<String> getBranchIdsToClose() {
return branchIdsToClose;
}
}
18 changes: 13 additions & 5 deletions src/main/java/com/powsybl/openloadflow/network/impl/Networks.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,23 @@ private static void retainAndCloseNecessarySwitches(Network network, LfTopoConfi
.forEach(sw -> sw.setRetained(true));

topoConfig.getSwitchesToClose().forEach(sw -> sw.setOpen(false)); // in order to be present in the network.
topoConfig.getBranchIdsToClose().stream().map(network::getBranch).forEach(branch -> {
branch.getTerminal1().connect();
branch.getTerminal2().connect();
}); // in order to be present in the network.
}

private static void restoreInitialTopology(LfNetwork network, Set<Switch> allSwitchesToClose) {
private static void restoreInitialTopology(LfNetwork network, Set<Switch> allSwitchesToClose, Set<String> branchIdsToClose) {
var connectivity = network.getConnectivity();
connectivity.startTemporaryChanges();
allSwitchesToClose.stream().map(Identifiable::getId).forEach(id -> {
LfBranch branch = network.getBranchById(id);
connectivity.removeEdge(branch);
});
branchIdsToClose.stream().forEach(id -> {
LfBranch branch = network.getBranchById(id);
connectivity.removeEdge(branch);
});
Set<LfBus> removedBuses = connectivity.getVerticesRemovedFromMainComponent();
removedBuses.forEach(bus -> bus.setDisabled(true));
Set<LfBranch> removedBranches = new HashSet<>(connectivity.getEdgesRemovedFromMainComponent());
Expand Down Expand Up @@ -182,10 +190,10 @@ public static LfNetworkList load(Network network, LfNetworkParameters networkPar
} else {
modifiedTopoConfig = topoConfig;
}
if (!modifiedTopoConfig.isBreaker()) {
if (!modifiedTopoConfig.isBreaker() && modifiedTopoConfig.getBranchIdsToClose().isEmpty()) {
return new LfNetworkList(load(network, topoConfig, networkParameters, reporter));
} else {
if (!networkParameters.isBreakers()) {
if (!networkParameters.isBreakers() && modifiedTopoConfig.isBreaker()) {
throw new PowsyblException("LF networks have to be built from bus/breaker view");
}

Expand All @@ -201,10 +209,10 @@ public static LfNetworkList load(Network network, LfNetworkParameters networkPar

List<LfNetwork> lfNetworks = load(network, topoConfig, networkParameters, reporter);

if (!modifiedTopoConfig.getSwitchesToClose().isEmpty()) {
if (!(modifiedTopoConfig.getSwitchesToClose().isEmpty() && modifiedTopoConfig.getBranchIdsToClose().isEmpty())) {
for (LfNetwork lfNetwork : lfNetworks) {
// disable all buses and branches not connected to main component (because of switch to close)
restoreInitialTopology(lfNetwork, modifiedTopoConfig.getSwitchesToClose());
restoreInitialTopology(lfNetwork, modifiedTopoConfig.getSwitchesToClose(), modifiedTopoConfig.getBranchIdsToClose());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
import com.powsybl.computation.ComputationManager;
import com.powsybl.contingency.ContingenciesProvider;
import com.powsybl.contingency.Contingency;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.Switch;
import com.powsybl.iidm.network.*;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.loadflow.LoadFlowResult;
import com.powsybl.math.matrix.MatrixFactory;
Expand Down Expand Up @@ -125,6 +124,10 @@ SecurityAnalysisReport runSync(SecurityAnalysisParameters securityAnalysisParame
findAllPtcToOperate(actions, topoConfig);
findAllRtcToOperate(actions, topoConfig);

// try to find branches (lines and two windings transformers).
// tie lines and three windings transformers missing.
findAllBranchesToClose(network, actions, topoConfig);

// load contingencies
List<Contingency> contingencies = contingenciesProvider.getContingencies(network);
// try to find all switches impacted by at least one contingency and for each contingency the branches impacted
Expand Down Expand Up @@ -340,6 +343,21 @@ protected static void findAllRtcToOperate(List<Action> actions, LfTopoConfig top
}
}

protected static void findAllBranchesToClose(Network network, List<Action> actions, LfTopoConfig topoConfig) {
// only branches open at both side or open at one side are visible in the LfNetwork.
for (Action action : actions) {
if (TerminalsConnectionAction.NAME.equals(action.getType())) {
TerminalsConnectionAction terminalsConnectionAction = (TerminalsConnectionAction) action;
if (terminalsConnectionAction.getSide().isEmpty() && !terminalsConnectionAction.isOpen()) {
Branch branch = network.getBranch(terminalsConnectionAction.getElementId());
if (branch != null && !(branch instanceof TieLine)) {
topoConfig.getBranchIdsToClose().add(terminalsConnectionAction.getElementId());
}
}
}
}
}

protected static void distributedMismatch(LfNetwork network, double mismatch, LoadFlowParameters loadFlowParameters,
OpenLoadFlowParameters openLoadFlowParameters) {
if (loadFlowParameters.isDistributedSlack() && Math.abs(mismatch) > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void test() {
assertTrue(LfAction.create(new TerminalsConnectionAction("A line action", "x", true), lfNetwork, network, acParameters.getNetworkParameters().isBreakers()).isEmpty());
assertTrue(LfAction.create(new PhaseTapChangerTapPositionAction("A phase tap change action", "y", false, 3), lfNetwork, network, acParameters.getNetworkParameters().isBreakers()).isEmpty());
var lineAction = new TerminalsConnectionAction("A line action", "L1", ThreeSides.ONE, false);
assertEquals("Line connection action: only open line at both sides is supported yet.", assertThrows(UnsupportedOperationException.class, () -> LfAction.create(lineAction, lfNetwork, network, acParameters.getNetworkParameters().isBreakers())).getMessage());
assertEquals("Terminals connection action: only open or close branch at both sides is supported yet.", assertThrows(UnsupportedOperationException.class, () -> LfAction.create(lineAction, lfNetwork, network, acParameters.getNetworkParameters().isBreakers())).getMessage());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1257,4 +1257,43 @@ void testVSCLossSetpoint() {
assertEquals(-0.0, getPostContingencyResult(result, "contingency").getNetworkResult().getBranchResult("l34").getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(-200.0, getOperatorStrategyResult(result, "strategy").getNetworkResult().getBranchResult("l34").getP1(), LoadFlowAssert.DELTA_POWER);
}

@Test
void testTerminalsConnectionAction() {
Network network = FourBusNetworkFactory.create();
network.getLine("l23").getTerminal1().disconnect();
network.getLine("l23").getTerminal2().disconnect();
List<Contingency> contingencies = Stream.of("l14")
.map(id -> new Contingency(id, new BranchContingency(id)))
.collect(Collectors.toList());

List<Action> actions = List.of(new TerminalsConnectionAction("closeLine", "l23", false));
List<OperatorStrategy> operatorStrategies = List.of(new OperatorStrategy("strategyL1", ContingencyContext.specificContingency("l14"), new TrueCondition(), List.of("closeLine")));
List<StateMonitor> monitors = createAllBranchesMonitors(network);

LoadFlowParameters parameters = new LoadFlowParameters();
parameters.setDistributedSlack(true);
parameters.setDc(true);
SecurityAnalysisParameters securityAnalysisParameters = new SecurityAnalysisParameters();
securityAnalysisParameters.setLoadFlowParameters(parameters);

SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParameters,
operatorStrategies, actions, Reporter.NO_OP);
OperatorStrategyResult dcStrategyResult = getOperatorStrategyResult(result, "strategyL1");

assertEquals(0.333, dcStrategyResult.getNetworkResult().getBranchResult("l12").getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(1.333, dcStrategyResult.getNetworkResult().getBranchResult("l23").getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(-1.0, dcStrategyResult.getNetworkResult().getBranchResult("l34").getP1(), LoadFlowAssert.DELTA_POWER);

parameters.setDc(false);
SecurityAnalysisParameters securityAnalysisParametersAc = new SecurityAnalysisParameters();
securityAnalysisParametersAc.setLoadFlowParameters(parameters);
SecurityAnalysisResult resultAc = runSecurityAnalysis(network, contingencies, monitors, securityAnalysisParametersAc,
operatorStrategies, actions, Reporter.NO_OP);
OperatorStrategyResult acStrategyResult = getOperatorStrategyResult(resultAc, "strategyL1");

assertEquals(0.336, acStrategyResult.getNetworkResult().getBranchResult("l12").getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(1.332, acStrategyResult.getNetworkResult().getBranchResult("l23").getP1(), LoadFlowAssert.DELTA_POWER);
assertEquals(-1.0, acStrategyResult.getNetworkResult().getBranchResult("l34").getP1(), LoadFlowAssert.DELTA_POWER);
}
}