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: manage contingency on HVDC line #264

Merged
merged 3 commits into from
Apr 8, 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 @@ -190,17 +190,29 @@ void addBattery(Battery battery) {
void addLccConverterStation(LccConverterStation lccCs) {
lccCss.add(lccCs);
HvdcLine line = lccCs.getHvdcLine();
loadTargetP += getLccConverterStationLoadTargetP(lccCs, line);
loadTargetQ += getLccConverterStationLoadTargetQ(lccCs, line);
}

public static double getLccConverterStationLoadTargetP(LccConverterStation lccCs, HvdcLine line) {
// The active power setpoint is always positive.
// If the converter station is at side 1 and is rectifier, p should be positive.
// If the converter station is at side 1 and is inverter, p should be negative.
// If the converter station is at side 2 and is rectifier, p should be positive.
// If the converter station is at side 2 and is inverter, p should be negative.
boolean isConverterStationRectifier = HvdcConverterStations.isRectifier(lccCs);
double pCs = (isConverterStationRectifier ? 1 : -1) * line.getActivePowerSetpoint() *
return (isConverterStationRectifier ? 1 : -1) * line.getActivePowerSetpoint() *
(1 + (isConverterStationRectifier ? 1 : -1) * lccCs.getLossFactor() / 100); // A LCC station has active losses.
double qCs = Math.abs(pCs * Math.tan(Math.acos(lccCs.getPowerFactor()))); // A LCC station always consumes reactive power.
loadTargetP += pCs;
loadTargetQ += qCs;
}

public static double getLccConverterStationLoadTargetQ(LccConverterStation lccCs, HvdcLine line) {
// The active power setpoint is always positive.
// If the converter station is at side 1 and is rectifier, p should be positive.
// If the converter station is at side 1 and is inverter, p should be negative.
// If the converter station is at side 2 and is rectifier, p should be positive.
// If the converter station is at side 2 and is inverter, p should be negative.
double pCs = getLccConverterStationLoadTargetP(lccCs, line);
return Math.abs(pCs * Math.tan(Math.acos(lccCs.getPowerFactor()))); // A LCC station always consumes reactive power.
}

protected void add(LfGenerator generator) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
package com.powsybl.openloadflow.sensi;

import com.powsybl.commons.PowsyblException;
import com.powsybl.contingency.ContingencyElement;
import com.powsybl.contingency.ContingencyElementType;
import com.powsybl.iidm.network.*;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.math.matrix.DenseMatrix;
Expand Down Expand Up @@ -60,7 +58,7 @@ protected static Terminal getEquipmentRegulatingTerminal(Network network, String
if (t2wt != null) {
RatioTapChanger rtc = t2wt.getRatioTapChanger();
if (rtc != null) {
throw new NotImplementedException(String.format("[%s] Bus voltage on two windings transformer is not managed yet", equipmentId));
throw new NotImplementedException(String.format("[%s] Bus target voltage on two windings transformer is not managed yet", equipmentId));
}
return null;
}
Expand All @@ -74,7 +72,7 @@ protected static Terminal getEquipmentRegulatingTerminal(Network network, String
}
}
if (regulatingTerminal != null) {
throw new NotImplementedException(String.format("[%s] Bus voltage on three windings transformer is not managed yet", equipmentId));
throw new NotImplementedException(String.format("[%s] Bus target voltage on three windings transformer is not managed yet", equipmentId));
}
return null;
}
Expand Down Expand Up @@ -583,17 +581,19 @@ protected void warnSkippedFactors(Collection<LfSensitivityFactor> lfFactors) {
}
}

public void checkContingencies(LfNetwork lfNetwork, List<PropagatedContingency> contingencies) {
public void checkContingencies(Network network, LfNetwork lfNetwork, List<PropagatedContingency> contingencies) {
for (PropagatedContingency contingency : contingencies) {
for (ContingencyElement contingencyElement : contingency.getContingency().getElements()) {
if (!contingencyElement.getType().equals(ContingencyElementType.BRANCH)) {
throw new UnsupportedOperationException("Only contingencies on a branch are yet supported");
}
LfBranch lfBranch = lfNetwork.getBranchById(contingencyElement.getId());
for (String branchId : contingency.getBranchIdsToOpen()) {
LfBranch lfBranch = lfNetwork.getBranchById(branchId);
if (lfBranch == null) {
throw new PowsyblException("The contingency on the branch " + contingencyElement.getId() + " not found in the network");
throw new PowsyblException("The contingency on the branch " + branchId + " not found in the network");
}
}
for (String hvdcId : contingency.getHvdcIdsToOpen()) {
HvdcLine hvdcLine = network.getHvdcLine(hvdcId);
if (hvdcLine == null) {
throw new PowsyblException("The DC line '" + hvdcId + "' does not exist in the network");
}

}
Set<String> branchesToRemove = new HashSet<>(); // branches connected to one side, or switches
for (String branchId : contingency.getBranchIdsToOpen()) {
Expand All @@ -607,7 +607,7 @@ public void checkContingencies(LfNetwork lfNetwork, List<PropagatedContingency>
}
}
contingency.getBranchIdsToOpen().removeAll(branchesToRemove);
if (contingency.getBranchIdsToOpen().isEmpty()) {
if (contingency.getBranchIdsToOpen().isEmpty() && contingency.getHvdcIdsToOpen().isEmpty()) {
LOGGER.warn("Contingency {} has no impact", contingency.getContingency().getId());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.powsybl.openloadflow.util.BusState;
import com.powsybl.openloadflow.util.LfContingency;
import com.powsybl.openloadflow.util.PropagatedContingency;
import org.apache.commons.lang3.NotImplementedException;

import java.util.*;
import java.util.function.Supplier;
Expand Down Expand Up @@ -117,6 +118,17 @@ private void calculatePostContingencySensitivityValues(List<LfSensitivityFactor>
LfContingency.reactivateEquations(deactivatedEquations, deactivatedEquationTerms);
}

@Override
public void checkContingencies(Network network, LfNetwork lfNetwork, List<PropagatedContingency> contingencies) {
super.checkContingencies(network, lfNetwork, contingencies);

for (PropagatedContingency contingency : contingencies) {
if (!contingency.getHvdcIdsToOpen().isEmpty()) {
throw new NotImplementedException("Contingencies on a DC line are not yet supported in AC mode.");
}
}
}

/**
* https://people.montefiore.uliege.be/vct/elec0029/lf.pdf / Equation 32 is transposed
*/
Expand All @@ -132,7 +144,7 @@ public void analyse(Network network, List<PropagatedContingency> contingencies,
// create LF network (we only manage main connected component)
List<LfNetwork> lfNetworks = LfNetwork.load(network, new LfNetworkParameters(lfParametersExt.getSlackBusSelector(), false, true, lfParameters.isTwtSplitShuntAdmittance(), false, lfParametersExt.getPlausibleActivePowerLimit(), false));
LfNetwork lfNetwork = lfNetworks.get(0);
checkContingencies(lfNetwork, contingencies);
checkContingencies(network, lfNetwork, contingencies);
checkLoadFlowParameters(lfParameters);
Map<Contingency, Collection<String>> propagatedContingencyMap = contingencies.stream().collect(
Collectors.toMap(PropagatedContingency::getContingency, contingency -> new HashSet<>(contingency.getBranchIdsToOpen()))
Expand Down
Loading