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

Sensitivity analysis: support of dangling line contingency #300

Merged
merged 7 commits into from
May 6, 2021
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 @@ -503,7 +503,9 @@ private void processConverterStation(LfNetwork lfNetwork, HvdcConverterStation<?
}
}

private Map<LfBus, BusState> applyDcLineContingency(Network network, LfNetwork lfNetwork, PropagatedContingency contingency) {
private Map<LfBus, BusState> applyHvdcLineContingency(Network network, LfNetwork lfNetwork, PropagatedContingency contingency) {
// it applies on the network the loss of the HVDC lines contained in the contingency.
// Buses state are stored too.
Collection<Pair<LfBus, LccConverterStation>> lccs = new HashSet<>();
Collection<Pair<LfBus, LfVscConverterStationImpl>> vscs = new HashSet<>();
for (String hvdcId : contingency.getHvdcIdsToOpen()) {
Expand Down Expand Up @@ -558,7 +560,7 @@ public void calculateContingencySensitivityValues(PropagatedContingency continge
calculateSensitivityValues(factors, factorStates, contingenciesStates, flowStates, contingencyElements,
contingency.getContingency().getId(), contingency.getIndex(), valueWriter);
} else { // if we have a contingency including the loss of a DC line
Map<LfBus, BusState> busStates = applyDcLineContingency(network, lfNetwork, contingency);
Map<LfBus, BusState> busStates = applyHvdcLineContingency(network, lfNetwork, contingency);
boolean shouldChangeRhs = lfParameters.isDistributedSlack()
&& (lfParameters.getBalanceType() == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD || lfParameters.getBalanceType() == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD);
DenseMatrix statesWithoutDcLine = factorStates;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,51 +7,66 @@
package com.powsybl.openloadflow.util;

import com.powsybl.commons.PowsyblException;
import com.powsybl.computation.ComputationManager;
import com.powsybl.contingency.tasks.AbstractTrippingTask;
import com.powsybl.iidm.network.*;

import java.util.*;

/**
* @author Florian Dupuy <florian.dupuy at rte-france.com>
*/
public class BranchTripping extends AbstractTrippingTask {
public class ContingencyTripping {

private final String branchId;
private final String voltageLevelId;
private final List<? extends Terminal> terminals;

public BranchTripping(String branchId) {
this(branchId, null);
public ContingencyTripping(List<? extends Terminal> terminals) {
this.terminals = terminals;
}

public BranchTripping(String branchId, String voltageLevelId) {
this.branchId = Objects.requireNonNull(branchId);
this.voltageLevelId = voltageLevelId;
public ContingencyTripping(Terminal terminal) {
this(Collections.singletonList(terminal));
}

@Override
public void traverse(Network network, ComputationManager computationManager, Set<Switch> switchesToOpen, Set<Terminal> terminalsToDisconnect) {
public static ContingencyTripping createBranchTripping(Network network, String branchId) {
return createBranchTripping(network, branchId, null);
}

public static ContingencyTripping createBranchTripping(Network network, String branchId, String voltageLevelId) {
Objects.requireNonNull(network);
Objects.requireNonNull(branchId);

Branch<?> branch = network.getBranch(branchId);
if (branch == null) {
throw new PowsyblException("Branch '" + branchId + "' not found");
throw new PowsyblException("Branch '" + branchId + "' not found in the network");
}

Set<Terminal> traversedTerminals = new HashSet<>();
if (voltageLevelId != null) {
if (voltageLevelId.equals(branch.getTerminal1().getVoltageLevel().getId())) {
traverseFromTerminal(branch.getTerminal1(), switchesToOpen, traversedTerminals);
return new ContingencyTripping(branch.getTerminal1());
} else if (voltageLevelId.equals(branch.getTerminal2().getVoltageLevel().getId())) {
traverseFromTerminal(branch.getTerminal2(), switchesToOpen, traversedTerminals);
return new ContingencyTripping(branch.getTerminal2());
} else {
throw new PowsyblException("VoltageLevel '" + voltageLevelId + "' not connected to branch '" + branchId + "'");
}
} else {
traverseFromTerminal(branch.getTerminal1(), switchesToOpen, traversedTerminals);
traverseFromTerminal(branch.getTerminal2(), switchesToOpen, traversedTerminals);
return new ContingencyTripping(branch.getTerminals());
}
}

public static ContingencyTripping createDanglingLineTripping(Network network, String dlId) {
Objects.requireNonNull(network);
Objects.requireNonNull(dlId);

DanglingLine danglingLine = network.getDanglingLine(dlId);
if (danglingLine == null) {
throw new PowsyblException("Dangling line '" + dlId + "' not found in the network");
}

return new ContingencyTripping(danglingLine.getTerminal());
}

public void traverse(Set<Switch> switchesToOpen, Set<Terminal> terminalsToDisconnect) {
Set<Terminal> traversedTerminals = new HashSet<>();
terminals.forEach(t -> traverseFromTerminal(t, switchesToOpen, traversedTerminals));
terminalsToDisconnect.addAll(traversedTerminals);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,22 @@ public static List<PropagatedContingency> create(Network network, List<Contingen
case LINE:
case TWO_WINDINGS_TRANSFORMER:
// branch check is done inside branch tripping
new BranchTripping(element.getId(), null)
.traverse(network, null, switchesToOpen, terminalsToDisconnect);
ContingencyTripping.createBranchTripping(network, element.getId())
.traverse(switchesToOpen, terminalsToDisconnect);
propagatedContingency.getBranchIdsToOpen().add(element.getId());
break;
case HVDC_LINE:
HvdcLine hvdcLine = network.getHvdcLine(element.getId());
if (hvdcLine == null) {
throw new PowsyblException("HVDC line '" + element.getId() + "' not found");
throw new PowsyblException("HVDC line '" + element.getId() + "' not found in the network");
}
propagatedContingency.getHvdcIdsToOpen().add(element.getId());
break;
case DANGLING_LINE:
ContingencyTripping.createDanglingLineTripping(network, element.getId())
.traverse(switchesToOpen, terminalsToDisconnect);
propagatedContingency.getBranchIdsToOpen().add(element.getId());
break;
default:
//TODO: support all kinds of contingencies
throw new UnsupportedOperationException("TODO");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.powsybl.math.matrix.DenseMatrixFactory;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowProvider;
import com.powsybl.openloadflow.network.DanglingLineFactory;
import com.powsybl.openloadflow.network.SlackBusSelectionMode;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -37,76 +38,13 @@ class AcLoadFlowDanglingLineTest {

private OpenLoadFlowParameters parametersExt;

private Network createNetwork() {
Network network = Network.create("dl", "test");
Substation s1 = network.newSubstation()
.setId("S1")
.add();
Substation s2 = network.newSubstation()
.setId("S2")
.add();
VoltageLevel vl1 = s1.newVoltageLevel()
.setId("vl1")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
bus1 = vl1.getBusBreakerView().newBus()
.setId("b1")
.add();
g1 = vl1.newGenerator()
.setId("g1")
.setConnectableBus("b1")
.setBus("b1")
.setTargetP(101.3664)
.setTargetV(390)
.setMinP(0)
.setMaxP(150)
.setVoltageRegulatorOn(true)
.add();
VoltageLevel vl2 = s2.newVoltageLevel()
.setId("vl2")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
bus2 = vl2.getBusBreakerView().newBus()
.setId("b2")
.add();
dl1 = vl2.newDanglingLine()
.setId("dl1")
.setConnectableBus("b2")
.setBus("b2")
.setR(0.7)
.setX(1)
.setG(Math.pow(10, -6))
.setB(3 * Math.pow(10, -6))
.setP0(101)
.setQ0(150)
.newGeneration()
.setTargetP(0)
.setTargetQ(0)
.setTargetV(390)
.setVoltageRegulationOn(false)
.add()
.add();
network.newLine()
.setId("l1")
.setVoltageLevel1("vl1")
.setBus1("b1")
.setVoltageLevel2("vl2")
.setBus2("b2")
.setR(1)
.setX(3)
.setG1(0)
.setG2(0)
.setB1(0)
.setB2(0)
.add();
return network;
}

@BeforeEach
void setUp() {
network = createNetwork();
network = DanglingLineFactory.create();
bus1 = network.getBusBreakerView().getBus("b1");
bus2 = network.getBusBreakerView().getBus("b2");
dl1 = network.getDanglingLine("dl1");
g1 = network.getGenerator("g1");
loadFlowRunner = new LoadFlow.Runner(new OpenLoadFlowProvider(new DenseMatrixFactory()));
parameters = new LoadFlowParameters().setNoGeneratorReactiveLimits(true)
.setDistributedSlack(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/**
* Copyright (c) 2021, RTE (http://www.rte-france.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/.
*/
package com.powsybl.openloadflow.network;

import com.powsybl.iidm.network.*;

/**
* @author Anne Tilloy <anne.tilloy at artelys.com>
*/
public class DanglingLineFactory extends AbstractLoadFlowNetworkFactory {

public static Network create() {
Network network = Network.create("dl", "test");
Substation s1 = network.newSubstation()
.setId("S1")
.add();
Substation s2 = network.newSubstation()
.setId("S2")
.add();
VoltageLevel vl1 = s1.newVoltageLevel()
.setId("vl1")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
vl1.getBusBreakerView().newBus()
.setId("b1")
.add();
vl1.newGenerator()
.setId("g1")
.setConnectableBus("b1")
.setBus("b1")
.setTargetP(101.3664)
.setTargetV(390)
.setMinP(0)
.setMaxP(150)
.setVoltageRegulatorOn(true)
.add();
VoltageLevel vl2 = s2.newVoltageLevel()
.setId("vl2")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
vl2.getBusBreakerView().newBus()
.setId("b2")
.add();
vl2.newDanglingLine()
.setId("dl1")
.setConnectableBus("b2")
.setBus("b2")
.setR(0.7)
.setX(1)
.setG(Math.pow(10, -6))
.setB(3 * Math.pow(10, -6))
.setP0(101)
.setQ0(150)
.newGeneration()
.setTargetP(0)
.setTargetQ(0)
.setTargetV(390)
.setVoltageRegulationOn(false)
.add()
.add();
network.newLine()
.setId("l1")
.setVoltageLevel1("vl1")
.setBus1("b1")
.setVoltageLevel2("vl2")
.setBus2("b2")
.setR(1)
.setX(3)
.setG1(0)
.setG2(0)
.setB1(0)
.setB2(0)
.add();
return network;
}

public static Network createWithLoad() {

Network network = create();

Substation s3 = network.newSubstation()
.setId("S3")
.add();
VoltageLevel vl3 = s3.newVoltageLevel()
.setId("vl3")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
vl3.getBusBreakerView().newBus()
.setId("b3")
.add();
vl3.newLoad()
.setId("load3")
.setBus("b3")
.setP0(10.0)
.setQ0(5.0)
.add();

network.newLine()
.setId("l13")
.setVoltageLevel1("vl1")
.setBus1("b1")
.setVoltageLevel2("vl3")
.setBus2("b3")
.setR(10)
.setX(3)
.setG1(0)
.setG2(0)
.setB1(0)
.setB2(0)
.add();
network.newLine()
.setId("l32")
.setVoltageLevel1("vl3")
.setBus1("b3")
.setVoltageLevel2("vl2")
.setBus2("b2")
.setR(10)
.setX(10)
.setG1(0)
.setG2(0)
.setB1(0)
.setB2(0)
.add();

network.getDanglingLine("dl1").setP0(91);

return network;
}

}
Loading