Skip to content
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 @@ -147,23 +147,50 @@ public void apply(LoadFlowParameters.BalanceType balanceType) {
shunt.setG(shunt.getG() - e.getValue().getG());
shunt.setB(shunt.getB() - e.getValue().getB());
}
processLostPowerChanges(balanceType, true);
}

/**
* Process the power shifts due to the loss of loads, generators, and HVDCs.
* @param balanceType the property defining how to manage active distribution.
* @param updateAcQuantities a boolean to indicate if voltage/reactive dependent quantities should be updated or not.
*/
public void processLostPowerChanges(LoadFlowParameters.BalanceType balanceType, boolean updateAcQuantities) {
processLostLoads(balanceType, updateAcQuantities);
processLostGenerators(updateAcQuantities);
processHvdcsWithoutPower();
}

private void processLostLoads(LoadFlowParameters.BalanceType balanceType, boolean updateAcQuantities) {
for (var e : lostLoads.entrySet()) {
LfLoad load = e.getKey();
LfLostLoad lostLoad = e.getValue();
PowerShift shift = lostLoad.getPowerShift();
load.setTargetP(load.getTargetP() - getUpdatedLoadP0(load, balanceType, shift.getActive(), shift.getVariableActive(), lostLoad.getNotParticipatingLoadP0()));
load.setTargetQ(load.getTargetQ() - shift.getReactive());
if (updateAcQuantities) {
load.setTargetQ(load.getTargetQ() - shift.getReactive());
}
load.setAbsVariableTargetP(load.getAbsVariableTargetP() - Math.abs(shift.getVariableActive()));
lostLoad.getOriginalIds().forEach(loadId -> load.setOriginalLoadDisabled(loadId, true));
}
}

private void processLostGenerators(boolean updateAcQuantities) {
Set<LfBus> generatorBuses = new HashSet<>();
for (LfGenerator generator : lostGenerators) {
// DC and AC quantities
generator.setTargetP(0);
generator.setInitialTargetP(0);
LfBus bus = generator.getBus();
generatorBuses.add(bus);
generator.setParticipating(false);
generator.setDisabled(true);

if (!updateAcQuantities) {
continue;
}

// Only AC quantities
if (generator.getGeneratorControlType() != LfGenerator.GeneratorControlType.OFF) {
generator.setGeneratorControlType(LfGenerator.GeneratorControlType.OFF);
bus.getGeneratorVoltageControl().ifPresent(GeneratorVoltageControl::updateReactiveKeys);
Expand All @@ -179,6 +206,12 @@ public void apply(LoadFlowParameters.BalanceType balanceType) {
});
}
}

if (!updateAcQuantities) {
return;
}

// Only AC quantities
for (LfBus bus : generatorBuses) {
if (bus.getGenerators().stream().noneMatch(gen -> gen.getGeneratorControlType() == LfGenerator.GeneratorControlType.VOLTAGE)) {
bus.setGeneratorVoltageControlEnabled(false);
Expand All @@ -187,6 +220,9 @@ public void apply(LoadFlowParameters.BalanceType balanceType) {
bus.setGeneratorReactivePowerControlEnabled(false);
}
}
}

private void processHvdcsWithoutPower() {
for (LfHvdc hvdc : hvdcsWithoutPower) {
hvdc.getConverterStation1().setTargetP(0.0);
hvdc.getConverterStation2().setTargetP(0.0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,16 @@ private double[] calculatePostContingencyAndOperatorStrategyStates(DcLoadFlowCon
engine.toPostContingencyAndOperatorStrategyStates(newFlowStates);
} else {
// if we have a contingency including the loss of a DC line or a generator or a load
// save base state for later restoration after each contingency
// save dc buses' base state for later restoration after processing lost power changes
DcLoadFlowParameters lfParameters = loadFlowContext.getParameters();
NetworkState networkState = NetworkState.save(lfNetwork);
List<BusDcState> busStates = ElementState.save(lfNetwork.getBuses(), BusDcState::save);
connectivityAnalysisResult.toLfContingency()
.ifPresent(lfContingency -> lfContingency.apply(lfParameters.getBalanceType()));
// only process the power shifts due to the loss of loads, generators, and HVDCs
// the loss of buses and phase shifts are taken into account in the override of the flow states
.ifPresent(lfContingency -> lfContingency.processLostPowerChanges(lfParameters.getBalanceType(), false));
newFlowStates = WoodburyEngine.runDcLoadFlowWithModifiedTargetVector(loadFlowContext, disabledNetwork, reportNode, operatorStrategyLfActions);
engine.toPostContingencyAndOperatorStrategyStates(newFlowStates);
networkState.restore();
ElementState.restore(busStates);
}

return newFlowStates;
Expand Down