Skip to content

Save and restore only active power changes in Fast DC Security Analysis #1205

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

Merged
merged 21 commits into from
Apr 11, 2025
Merged
Show file tree
Hide file tree
Changes from 17 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 updateAcParameters a boolean to indicate if voltage/reactive dependent parameters should be updated or not.
Copy link
Collaborator

@vidaldid-rte vidaldid-rte Apr 10, 2025

Choose a reason for hiding this comment

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

The name updateAcParameters is confusing. Parameters usually refers to parameters that alter the simulator behaviour.
Why not updateAcQuantities ?

(the comment applies to all similar uses of the term parameter in this file (in comments for example)

Copy link
Member

Choose a reason for hiding this comment

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

I agree

Copy link
Member Author

Choose a reason for hiding this comment

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

Applied. Thanks for the suggestion.

*/
public void processLostPowerChanges(LoadFlowParameters.BalanceType balanceType, boolean updateAcParameters) {
processLostLoads(balanceType, updateAcParameters);
processLostGenerators(updateAcParameters);
processHvdcsWithoutPower();
}

private void processLostLoads(LoadFlowParameters.BalanceType balanceType, boolean updateAcParameters) {
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 (updateAcParameters) {
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 updateAcParameters) {
Set<LfBus> generatorBuses = new HashSet<>();
for (LfGenerator generator : lostGenerators) {
// DC and AC parameters
generator.setTargetP(0);
generator.setInitialTargetP(0);
LfBus bus = generator.getBus();
generatorBuses.add(bus);
generator.setParticipating(false);
generator.setDisabled(true);

if (!updateAcParameters) {
continue;
}

// Only AC parameters
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 (!updateAcParameters) {
return;
}

// Only AC parameters
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