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

Contingency refactoring #493

Merged
merged 45 commits into from
Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
8f5b8d5
Refactor contingency application.
annetill Apr 5, 2022
31bdb33
Remove dependancy to IIDM network.
annetill Apr 5, 2022
2865304
Simplify.
annetill Apr 5, 2022
576d416
Add tests.
annetill Apr 5, 2022
b54a5f8
Remove useless code.
annetill Apr 5, 2022
289fb6b
Hvdc Ac emulation not supported yet.
annetill Apr 5, 2022
4cdc0aa
Add a unit test and clean code.
annetill Apr 5, 2022
6a0ced1
Start support of other contingencies for AC sensitivity analysis.
annetill Apr 5, 2022
94f0b06
Load and generator contingency support for AC sensitivity analysis.
annetill Apr 5, 2022
250d6bf
Merge.
annetill Apr 7, 2022
898779a
Small fixes after merge.
annetill Apr 7, 2022
4cd030d
Try to fix GLSK.
annetill Apr 8, 2022
62cdf98
Fix bug.
annetill Apr 8, 2022
7611b6b
Merge.
annetill Apr 8, 2022
4fe7423
Merge.
annetill Apr 10, 2022
494aeed
Save work.
annetill Apr 11, 2022
932e746
Fix checkstyle.
annetill Apr 11, 2022
596b85f
Refactoring.
annetill Apr 11, 2022
f6f86ab
Merge.
annetill Apr 13, 2022
2c0300b
Clarify.
annetill Apr 13, 2022
894c441
Merge branch 'main' into hvdc-contingency-refactoring
annetill Apr 14, 2022
b60a6ca
Fix bug.
annetill Apr 14, 2022
f232df7
Merge.
annetill Apr 21, 2022
bf3880b
Merge branch 'main' into hvdc-contingency-refactoring
annetill May 9, 2022
4fa8542
Merge.
annetill May 13, 2022
1dd1bc6
Merge branch 'main' into hvdc-contingency-refactoring
annetill May 16, 2022
dde2c31
Merge branch 'main' into hvdc-contingency-refactoring
annetill May 17, 2022
128f7c0
Merge branch 'main' into hvdc-contingency-refactoring
annetill May 18, 2022
8822df9
Support of a contingency with an HVDC in AC emulation.
annetill May 19, 2022
b8fac53
Add test for AC sensitivity analysis.
annetill May 19, 2022
8f02c7d
Add a unit test.
annetill May 25, 2022
6cfe4b1
Add unit test and clean.
annetill May 25, 2022
8a34d3c
Fix and factorize the case where a disabled line is the function of a…
Hadrien-Godard May 25, 2022
b9e84c5
New test
Hadrien-Godard May 25, 2022
770757d
Fix isElementConnectedToComponent removing disabled lines from compon…
Hadrien-Godard May 27, 2022
2272d5c
Revert "Fix isElementConnectedToComponent removing disabled lines fro…
annetill May 30, 2022
f1c4a3b
Revert "New test"
annetill May 30, 2022
522b3ed
Merge.
annetill May 30, 2022
d27724f
Refactoring.
annetill May 30, 2022
1758b1d
Merge branch 'main' into hvdc-contingency-refactoring
annetill Jun 1, 2022
37a9594
Squashed commit of the following:
geofjamg Jun 1, 2022
6f8c934
Clean
geofjamg Jun 1, 2022
e557675
Merge branch 'main' into hvdc-contingency-refactoring
geofjamg Jun 2, 2022
7f4f07b
Apply review comments.
annetill Jun 2, 2022
2b0ca27
Merge branch 'hvdc-contingency-refactoring' of https://github.com/pow…
annetill Jun 2, 2022
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
43 changes: 33 additions & 10 deletions src/main/java/com/powsybl/openloadflow/network/LfContingency.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Writer;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.*;

/**
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
Expand All @@ -38,6 +35,8 @@ public class LfContingency {

private final Set<LfGenerator> generators;
annetill marked this conversation as resolved.
Show resolved Hide resolved

private final Set<LfGenerator> participatingGeneratorsToBeRemoved = new HashSet<>();
annetill marked this conversation as resolved.
Show resolved Hide resolved

private double activePowerLoss = 0;

public LfContingency(String id, int index, Set<LfBus> disabledBuses, Set<LfBranch> disabledBranches, Map<LfShunt, Double> shuntsShift,
Expand Down Expand Up @@ -92,7 +91,7 @@ public double getActivePowerLoss() {
return activePowerLoss;
}

public void apply(LoadFlowParameters parameters) {
public void apply(LoadFlowParameters.BalanceType balanceType) {
for (LfBranch branch : disabledBranches) {
branch.setDisabled(true);
}
Expand All @@ -106,7 +105,7 @@ public void apply(LoadFlowParameters parameters) {
for (var e : busesLoadShift.entrySet()) {
LfBus bus = e.getKey();
PowerShift shift = e.getValue();
bus.setLoadTargetP(bus.getLoadTargetP() - getUpdatedLoadP0(bus, parameters.getBalanceType(), shift.getActive(), shift.getVariableActive()));
bus.setLoadTargetP(bus.getLoadTargetP() - getUpdatedLoadP0(bus, balanceType, shift.getActive(), shift.getVariableActive()));
bus.setLoadTargetQ(bus.getLoadTargetQ() - shift.getReactive());
bus.getLoads().setAbsVariableLoadTargetP(bus.getLoads().getAbsVariableLoadTargetP() - Math.abs(shift.getVariableActive()) * PerUnit.SB);
}
Expand All @@ -118,6 +117,7 @@ public void apply(LoadFlowParameters parameters) {
generator.setParticipating(false);
if (generator.getGeneratorControlType() != LfGenerator.GeneratorControlType.OFF) {
generator.setGeneratorControlType(LfGenerator.GeneratorControlType.OFF);
participatingGeneratorsToBeRemoved.add(generator);
annetill marked this conversation as resolved.
Show resolved Hide resolved
} else {
bus.setGenerationTargetQ(bus.getGenerationTargetQ() - generator.getTargetQ());
}
Expand All @@ -131,14 +131,37 @@ public void apply(LoadFlowParameters parameters) {

public static double getUpdatedLoadP0(LfBus bus, LoadFlowParameters.BalanceType balanceType, double initialP0, double initialVariableActivePower) {
double factor = 0.0;
if (balanceType == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD) {
factor = Math.abs(initialP0) / (bus.getLoads().getAbsVariableLoadTargetP() / PerUnit.SB);
} else if (balanceType == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD) {
factor = initialVariableActivePower / (bus.getLoads().getAbsVariableLoadTargetP() / PerUnit.SB);
if (bus.getLoads().getLoadCount() > 0) {
if (balanceType == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD) {
factor = Math.abs(initialP0) / (bus.getLoads().getAbsVariableLoadTargetP() / PerUnit.SB);
} else if (balanceType == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD) {
factor = initialVariableActivePower / (bus.getLoads().getAbsVariableLoadTargetP() / PerUnit.SB);
}
}
return initialP0 + (bus.getLoadTargetP() - bus.getInitialLoadTargetP()) * factor;
}

public Set<LfGenerator> getParticipatingGeneratorsToBeRemoved() {
return participatingGeneratorsToBeRemoved;
}

public Set<LfBus> getLoadAndGeneratorBuses() {
Set<LfBus> affectedBuses = new HashSet<>();
for (var e : busesLoadShift.entrySet()) {
LfBus bus = e.getKey();
if (bus != null) {
affectedBuses.add(bus);
}
}
for (LfGenerator generator : generators) {
LfBus bus = generator.getBus();
if (bus != null) {
affectedBuses.add(bus);
}
}
return affectedBuses;
}

public void writeJson(Writer writer) {
Objects.requireNonNull(writer);
try (JsonGenerator jsonGenerator = new JsonFactory()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.powsybl.contingency.Contingency;
import com.powsybl.contingency.ContingencyElement;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.HvdcAngleDroopActivePowerControl;
import com.powsybl.iidm.network.extensions.LoadDetail;
import com.powsybl.openloadflow.graph.GraphDecrementalConnectivity;
import com.powsybl.openloadflow.network.*;
Expand Down Expand Up @@ -104,11 +105,11 @@ private static PowerShift getLoadPowerShift(Load load, boolean slackDistribution
}

public static List<PropagatedContingency> createListForSensitivityAnalysis(Network network, List<Contingency> contingencies,
boolean slackDistributionOnConformLoad) {
boolean slackDistributionOnConformLoad, boolean hvdcAcEmulation) {
List<PropagatedContingency> propagatedContingencies = new ArrayList<>();
for (int index = 0; index < contingencies.size(); index++) {
Contingency contingency = contingencies.get(index);
PropagatedContingency propagatedContingency = PropagatedContingency.create(network, contingency, index, false, false, slackDistributionOnConformLoad);
PropagatedContingency propagatedContingency = PropagatedContingency.create(network, contingency, index, false, false, slackDistributionOnConformLoad, hvdcAcEmulation);
Optional<Switch> coupler = propagatedContingency.switchesToOpen.stream().filter(PropagatedContingency::isCoupler).findFirst();
if (coupler.isEmpty()) {
propagatedContingencies.add(propagatedContingency);
Expand All @@ -123,24 +124,26 @@ public static List<PropagatedContingency> createListForSensitivityAnalysis(Netwo

public static List<PropagatedContingency> createListForSecurityAnalysis(Network network, List<Contingency> contingencies,
Set<Switch> allSwitchesToOpen, boolean shuntCompensatorVoltageControlOn,
boolean slackDistributionOnConformLoad) {
boolean slackDistributionOnConformLoad, boolean hvdcAcEmulation) {
List<PropagatedContingency> propagatedContingencies = new ArrayList<>();
for (int index = 0; index < contingencies.size(); index++) {
Contingency contingency = contingencies.get(index);
PropagatedContingency propagatedContingency =
PropagatedContingency.create(network, contingency, index, shuntCompensatorVoltageControlOn, true, slackDistributionOnConformLoad);
PropagatedContingency.create(network, contingency, index, shuntCompensatorVoltageControlOn, true, slackDistributionOnConformLoad, hvdcAcEmulation);
propagatedContingencies.add(propagatedContingency);
allSwitchesToOpen.addAll(propagatedContingency.switchesToOpen);
}
return propagatedContingencies;
}

private static PropagatedContingency create(Network network, Contingency contingency, int index, boolean shuntCompensatorVoltageControlOn,
boolean withBreakers, boolean slackDistributionOnConformLoad) {
boolean withBreakers, boolean slackDistributionOnConformLoad, boolean hvdcAcEmulation) {
Set<Switch> switchesToOpen = new HashSet<>();
Set<Terminal> terminalsToDisconnect = new HashSet<>();
Set<String> branchIdsToOpen = new HashSet<>();
Set<String> hvdcIdsToOpen = new HashSet<>();
Set<VscConverterStation> vscsToLose = new HashSet<>();
Set<LccConverterStation> lccsToLose = new HashSet<>();
Set<Load> loadsToLose = new HashSet<>();
Set<Generator> generatorsToLose = new HashSet<>();
Set<ShuntCompensator> shuntsToLose = new HashSet<>();
Expand All @@ -160,7 +163,26 @@ private static PropagatedContingency create(Network network, Contingency conting
if (hvdcLine == null) {
throw new PowsyblException("HVDC line '" + element.getId() + "' not found in the network");
}
hvdcIdsToOpen.add(element.getId());
HvdcAngleDroopActivePowerControl control = hvdcLine.getExtension(HvdcAngleDroopActivePowerControl.class);
if (control != null && control.isEnabled() && hvdcAcEmulation) {
// Not depending on AC or DC computation.
throw new PowsyblException("Contingency on HVDC line '" + element.getId() + "' with AC emulation control: not supported yet.");
annetill marked this conversation as resolved.
Show resolved Hide resolved
}
hvdcIdsToOpen.add(element.getId()); // FIXME: try to use it only for HVDC in AC emulation.
if (hvdcLine.getConverterStation1() instanceof VscConverterStation) {
VscConverterStation vsc1 = (VscConverterStation) hvdcLine.getConverterStation1();
vscsToLose.add(vsc1);
} else {
LccConverterStation lcc1 = (LccConverterStation) hvdcLine.getConverterStation1();
lccsToLose.add(lcc1);
}
if (hvdcLine.getConverterStation2() instanceof VscConverterStation) {
VscConverterStation vsc2 = (VscConverterStation) hvdcLine.getConverterStation2();
vscsToLose.add(vsc2);
} else {
LccConverterStation lcc2 = (LccConverterStation) hvdcLine.getConverterStation2();
lccsToLose.add(lcc2);
}
break;
case DANGLING_LINE:
// dangling line check is done inside tripping
Expand Down Expand Up @@ -218,6 +240,14 @@ private static PropagatedContingency create(Network network, Contingency conting
shuntsToLose.add((ShuntCompensator) connectable);
break;

case HVDC_CONVERTER_STATION:
if (connectable instanceof VscConverterStation) {
vscsToLose.add((VscConverterStation) connectable);
} else {
lccsToLose.add((LccConverterStation) connectable);
}
break;

case BUSBAR_SECTION:
// we don't care
break;
Expand All @@ -235,6 +265,9 @@ private static PropagatedContingency create(Network network, Contingency conting
for (Generator generator : generatorsToLose) {
generatorIdsToLose.add(generator.getId());
}
for (VscConverterStation vsc : vscsToLose) {
generatorIdsToLose.add(vsc.getId());
}
for (Load load : loadsToLose) {
Bus bus = withBreakers ? load.getTerminal().getBusBreakerView().getBus()
: load.getTerminal().getBusView().getBus();
Expand All @@ -243,6 +276,16 @@ private static PropagatedContingency create(Network network, Contingency conting
.add(getLoadPowerShift(load, slackDistributionOnConformLoad));
}
}
for (LccConverterStation lcc : lccsToLose) {
Bus bus = withBreakers ? lcc.getTerminal().getBusBreakerView().getBus()
: lcc.getTerminal().getBusView().getBus();
if (bus != null) {
// No variable active part for a LCC.
loadIdsToShift.computeIfAbsent(bus.getId(), k -> new PowerShift())
.add(new PowerShift(HvdcConverterStations.getConverterStationTargetP(lcc) / PerUnit.SB, 0,
HvdcConverterStations.getLccConverterStationLoadTargetQ(lcc) / PerUnit.SB));
}
}
for (ShuntCompensator shunt : shuntsToLose) {
double nominalV = shunt.getTerminal().getVoltageLevel().getNominalV();
shuntIdsToShift.put(shunt.getId(), shunt.getB() * nominalV * nominalV / PerUnit.SB);
Expand Down Expand Up @@ -291,10 +334,6 @@ public Optional<LfContingency> toLfContingency(LfNetwork network, boolean useSma
// reset connectivity to discard triggered branches
connectivity.reset();

if (!hvdcIdsToOpen.isEmpty()) {
throw new UnsupportedOperationException("HVDC line contingency not supported");
}

Map<LfShunt, Double> shunts = new HashMap<>(1);
for (var e : shuntIdsToShift.entrySet()) {
LfShunt shunt = network.getShuntById(e.getKey());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ SecurityAnalysisReport runSync(String workingVariantId, SecurityAnalysisParamete
// try to find all switches impacted by at least one contingency and for each contingency the branches impacted
Set<Switch> allSwitchesToOpen = new HashSet<>();
List<PropagatedContingency> propagatedContingencies = PropagatedContingency.createListForSecurityAnalysis(network, contingencies, allSwitchesToOpen,
lfParameters.isShuntCompensatorVoltageControlOn(), lfParameters.getBalanceType() == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD);
lfParameters.isShuntCompensatorVoltageControlOn(), lfParameters.getBalanceType() == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD,
lfParameters.isHvdcAcEmulation());

AcLoadFlowParameters acParameters = OpenLoadFlowParameters.createAcParameters(network, lfParameters, lfParametersExt, matrixFactory, connectivityFactory, Reporter.NO_OP, true, false);

Expand Down Expand Up @@ -146,7 +147,7 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List<Propagated
PropagatedContingency propagatedContingency = contingencyIt.next();
propagatedContingency.toLfContingency(network, true)
.ifPresent(lfContingency -> { // only process contingencies that impact the network
lfContingency.apply(loadFlowParameters);
lfContingency.apply(loadFlowParameters.getBalanceType());

distributedMismatch(network, lfContingency.getActivePowerLoss(), loadFlowParameters, openLoadFlowParameters);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@
import com.powsybl.openloadflow.equations.Quantity;
import com.powsybl.openloadflow.graph.GraphDecrementalConnectivity;
import com.powsybl.openloadflow.graph.GraphDecrementalConnectivityFactory;
import com.powsybl.openloadflow.network.LfBranch;
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.network.LfElement;
import com.powsybl.openloadflow.network.LfNetwork;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.network.impl.HvdcConverterStations;
import com.powsybl.openloadflow.network.impl.LfDanglingLineBus;
import com.powsybl.openloadflow.network.impl.PropagatedContingency;
Expand Down Expand Up @@ -553,8 +550,8 @@ public void fillRhs(Matrix rhs, Map<LfBus, Double> participationByBus) {

boolean updateConnectivityWeights(Set<LfBus> nonConnectedBuses) {
mainComponentWeights = variableElements.entrySet().stream()
.filter(entry -> !nonConnectedBuses.contains((LfBus) entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
.filter(entry -> !nonConnectedBuses.contains((LfBus) entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return mainComponentWeights.size() != variableElements.size();
}
}
Expand Down Expand Up @@ -709,7 +706,7 @@ public void checkContingencies(LfNetwork lfNetwork, List<PropagatedContingency>
}
}
contingency.getBranchIdsToOpen().removeAll(branchesToRemove);
if (contingency.getBranchIdsToOpen().isEmpty() && contingency.getHvdcIdsToOpen().isEmpty() && contingency.getGeneratorIdsToLose().isEmpty() && contingency.getLoadIdsToShift().isEmpty()) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe keep that if we handle well HVDC in AC emulation.

if (contingency.getBranchIdsToOpen().isEmpty() && contingency.getGeneratorIdsToLose().isEmpty() && contingency.getLoadIdsToShift().isEmpty()) {
LOGGER.warn("Contingency {} has no impact", contingency.getContingency().getId());
}
}
Expand Down
Loading