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

[WIP] Remember PV-PQ switch count in SA and sensi #1164

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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 @@ -24,6 +24,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -120,7 +121,10 @@ private static AcLoadFlowResult run(AcLoadFlowContext context) {
context.setNetworkUpdated(false);
return result;
}
return new AcLoadFlowResult(context.getNetwork(), 0, 0, AcSolverStatus.CONVERGED, OuterLoopResult.stable(), 0d, 0d);
return new AcLoadFlowResult(context.getNetwork(), 0,
0, AcSolverStatus.CONVERGED, OuterLoopResult.stable(),
0d, 0d,
Collections.EMPTY_MAP);
}

public List<AcLoadFlowResult> run() {
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/powsybl/openloadflow/ac/AcLoadFlowContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.powsybl.openloadflow.ac;

import com.powsybl.openloadflow.ac.equations.asym.AsymmetricalAcEquationSystemCreator;
import com.powsybl.openloadflow.ac.outerloop.AcOuterLoop;
import com.powsybl.openloadflow.equations.JacobianMatrix;
import com.powsybl.openloadflow.lf.AbstractLoadFlowContext;
import com.powsybl.openloadflow.ac.equations.AcEquationSystemCreator;
Expand All @@ -18,6 +19,9 @@
import com.powsybl.openloadflow.equations.TargetVector;
import com.powsybl.openloadflow.network.LfNetwork;

import java.util.HashMap;
import java.util.Map;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
Expand All @@ -31,6 +35,8 @@ public class AcLoadFlowContext extends AbstractLoadFlowContext<AcVariableType, A

private boolean networkUpdated = true;

private Map<Class<? extends AcOuterLoop>, Object> outerLoopInitData = new HashMap<>();

public AcLoadFlowContext(LfNetwork network, AcLoadFlowParameters parameters) {
super(network, parameters);
}
Expand Down Expand Up @@ -84,6 +90,14 @@ public void setNetworkUpdated(boolean networkUpdated) {
this.networkUpdated = networkUpdated;
}

public Object getOuterLoopInitData(Class<? extends AcOuterLoop> outerLoopClass) {
return outerLoopInitData.get(outerLoopClass);
}

public void setOuterLoopInitData(Map<Class<? extends AcOuterLoop>, Object> outerLoopInitData) {
this.outerLoopInitData = outerLoopInitData;
}

@Override
public void close() {
super.close();
Expand Down
16 changes: 14 additions & 2 deletions src/main/java/com/powsybl/openloadflow/ac/AcLoadFlowResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@
package com.powsybl.openloadflow.ac;

import com.powsybl.loadflow.LoadFlowResult;
import com.powsybl.openloadflow.ac.outerloop.AcOuterLoop;
import com.powsybl.openloadflow.ac.solver.AcSolverStatus;
import com.powsybl.openloadflow.lf.AbstractLoadFlowResult;
import com.powsybl.openloadflow.lf.outerloop.OuterLoopResult;
import com.powsybl.openloadflow.lf.outerloop.OuterLoopStatus;
import com.powsybl.openloadflow.network.LfNetwork;
import com.powsybl.openloadflow.util.PerUnit;

import java.util.Collections;
import java.util.Map;
import java.util.Objects;

/**
Expand All @@ -23,19 +26,24 @@
public class AcLoadFlowResult extends AbstractLoadFlowResult {

public static AcLoadFlowResult createNoCalculationResult(LfNetwork network) {
return new AcLoadFlowResult(network, 0, 0, AcSolverStatus.NO_CALCULATION, OuterLoopResult.stable(), Double.NaN, Double.NaN);
return new AcLoadFlowResult(network, 0, 0, AcSolverStatus.NO_CALCULATION, OuterLoopResult.stable(), Double.NaN, Double.NaN,
Collections.EMPTY_MAP);
}

private final int solverIterations;

private final AcSolverStatus solverStatus;

private final Map<Class<? extends AcOuterLoop>, Object> outerLoopInitData;

public AcLoadFlowResult(LfNetwork network, int outerLoopIterations, int solverIterations,
AcSolverStatus solverStatus, OuterLoopResult outerLoopResult,
double slackBusActivePowerMismatch, double distributedActivePower) {
double slackBusActivePowerMismatch, double distributedActivePower,
Map<Class<? extends AcOuterLoop>, Object> outerLoopInitData) {
super(network, slackBusActivePowerMismatch, outerLoopIterations, outerLoopResult, distributedActivePower);
this.solverIterations = solverIterations;
this.solverStatus = Objects.requireNonNull(solverStatus);
this.outerLoopInitData = outerLoopInitData;
}

public int getSolverIterations() {
Expand Down Expand Up @@ -79,6 +87,10 @@ public Status toComponentResultStatus() {
}
}

public Map<Class<? extends AcOuterLoop>, Object> getOuterLoopInitData() {
return outerLoopInitData;
}

@Override
public String toString() {
return "AcLoadFlowResult(outerLoopIterations=" + outerLoopIterations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,23 @@
import com.powsybl.openloadflow.lf.outerloop.AbstractOuterLoopContext;
import com.powsybl.openloadflow.network.LfNetwork;

import java.util.Optional;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public class AcOuterLoopContext extends AbstractOuterLoopContext<AcVariableType, AcEquationType, AcLoadFlowParameters, AcLoadFlowContext> {

private AcSolverResult lastSolverResult;
private Object outerLoopInitData;

AcOuterLoopContext(LfNetwork network) {
AcOuterLoopContext(LfNetwork network, Object dataForRunFromPreviousValues) {
super(network);
this.outerLoopInitData = dataForRunFromPreviousValues;
}

public Optional<Object> getOuterLoopInitData() {
return Optional.ofNullable(outerLoopInitData);
}

public AcSolverResult getLastSolverResult() {
Expand Down
19 changes: 14 additions & 5 deletions src/main/java/com/powsybl/openloadflow/ac/AcloadFlowEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -138,7 +139,7 @@ public AcLoadFlowResult run() {
LOGGER.info("Network must have at least one bus with generator voltage control enabled");
Reports.reportNetworkMustHaveAtLeastOneBusGeneratorVoltageControlEnabled(reportNode);
runningContext.lastSolverResult = new AcSolverResult(AcSolverStatus.SOLVER_FAILED, 0, Double.NaN);
return buildAcLoadFlowResult(runningContext, OuterLoopResult.stable(), distributedActivePower);
return buildAcLoadFlowResult(runningContext, OuterLoopResult.stable(), distributedActivePower, Collections.EMPTY_LIST);
}

AcSolver solver = solverFactory.create(context.getNetwork(),
Expand All @@ -150,7 +151,7 @@ public AcLoadFlowResult run() {

List<AcOuterLoop> outerLoops = context.getParameters().getOuterLoops();
List<Pair<AcOuterLoop, AcOuterLoopContext>> outerLoopsAndContexts = outerLoops.stream()
.map(outerLoop -> Pair.of(outerLoop, new AcOuterLoopContext(context.getNetwork())))
.map(outerLoop -> Pair.of(outerLoop, new AcOuterLoopContext(context.getNetwork(), context.getOuterLoopInitData(outerLoop.getClass()))))
.toList();

// outer loops initialization
Expand Down Expand Up @@ -218,17 +219,25 @@ public AcLoadFlowResult run() {
new OuterLoopResult(runningContext.lastOuterLoopResult.outerLoopName(), OuterLoopStatus.UNSTABLE, runningContext.lastOuterLoopResult.statusText());
}

return buildAcLoadFlowResult(runningContext, outerLoopFinalResult, distributedActivePower);
return buildAcLoadFlowResult(runningContext, outerLoopFinalResult, distributedActivePower, outerLoopsAndContexts);
}

private AcLoadFlowResult buildAcLoadFlowResult(RunningContext runningContext, OuterLoopResult outerLoopFinalResult, double distributedActivePower) {
private AcLoadFlowResult buildAcLoadFlowResult(RunningContext runningContext,
OuterLoopResult outerLoopFinalResult,
double distributedActivePower,
List<Pair<AcOuterLoop, AcOuterLoopContext>> outerLoopsAndContexts) {

Map<Class<? extends AcOuterLoop>, Object> outerLoopInitData = new HashMap<>();
outerLoopsAndContexts.forEach(p -> p.getLeft().getInitData(p.getRight()).ifPresent(d -> outerLoopInitData.put(p.getLeft().getClass(), d)));

AcLoadFlowResult result = new AcLoadFlowResult(context.getNetwork(),
runningContext.outerLoopTotalIterations,
runningContext.nrTotalIterations.getValue(),
runningContext.lastSolverResult.getStatus(),
outerLoopFinalResult,
runningContext.lastSolverResult.getSlackBusActivePowerMismatch(),
distributedActivePower
distributedActivePower,
outerLoopInitData
);

LOGGER.info("AC loadflow complete on network {} (result={})", context.getNetwork(), result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,17 @@
import com.powsybl.openloadflow.ac.equations.AcVariableType;
import com.powsybl.openloadflow.lf.outerloop.OuterLoop;

import java.util.Optional;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public interface AcOuterLoop extends OuterLoop<AcVariableType, AcEquationType, AcLoadFlowParameters, AcLoadFlowContext, AcOuterLoopContext> {

/**
* Returns data needed to initialize the outerloop for a rerun from previous values.
*/
default Optional<Object> getInitData(AcOuterLoopContext context) {
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ private static final class ContextData {

private final Map<String, MutableInt> pvPqSwitchCount = new HashMap<>();

public ContextData(Optional<Object> initData) {
initData.ifPresent(d -> {
if (d instanceof Map map) {
pvPqSwitchCount.putAll(map);
}
});
}

void incrementPvPqSwitchCount(String busId) {
pvPqSwitchCount.computeIfAbsent(busId, k -> new MutableInt(0))
.increment();
Expand Down Expand Up @@ -163,7 +171,7 @@ private boolean switchPvPq(List<ControllerBusToPqBus> pvToPqBuses, int remaining

@Override
public void initialize(AcOuterLoopContext context) {
context.setData(new ContextData());
context.setData(new ContextData(context.getOuterLoopInitData()));
}

private static boolean switchPqPv(List<PqToPvBus> pqToPvBuses, ContextData contextData, ReportNode reportNode, int maxPqPvSwitch) {
Expand Down Expand Up @@ -349,4 +357,9 @@ public OuterLoopResult check(AcOuterLoopContext context, ReportNode reportNode)
}
return new OuterLoopResult(this, status);
}

@Override
public Optional<Object> getInitData(AcOuterLoopContext context) {
return Optional.of(Collections.unmodifiableMap(((ContextData) context.getData()).pvPqSwitchCount));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,8 @@ protected static void distributedMismatch(LfNetwork network, double mismatch, Lo

protected abstract LoadFlowEngine<V, E, P, R> createLoadFlowEngine(C context);

protected abstract void updateContext(R result, C context);

protected void afterPreContingencySimulation(P acParameters) {
}

Expand Down Expand Up @@ -649,6 +651,7 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List<Propag

// only run post-contingency simulations if pre-contingency simulation is ok
if (preContingencyComputationOk) {
updateContext(preContingencyLoadFlowResult, context);
afterPreContingencySimulation(acParameters);

// update network result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,9 @@ protected PostContingencyComputationStatus postContingencyStatusFromLoadFlowResu
protected void beforeActionLoadFlowRun(AcLoadFlowContext context) {
context.getParameters().setVoltageInitializer(new PreviousValueVoltageInitializer(true));
}

@Override
protected void updateContext(AcLoadFlowResult result, AcLoadFlowContext context) {
context.setOuterLoopInitData(result.getOuterLoopInitData());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,9 @@ protected DcLoadFlowEngine createLoadFlowEngine(DcLoadFlowContext context) {
protected PostContingencyComputationStatus postContingencyStatusFromLoadFlowResult(DcLoadFlowResult result) {
return result.isSuccess() ? PostContingencyComputationStatus.CONVERGED : PostContingencyComputationStatus.FAILED;
}

@Override
protected void updateContext(DcLoadFlowResult result, DcLoadFlowContext context) {
// Nothing to do
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private void calculatePostContingencySensitivityValues(List<LfSensitivityFactor<
activePowerDistribution.run(lfNetwork, lfContingency.getActivePowerLoss());
}

if (!runLoadFlow(context, false)) {
if (!runLoadFlow(context, false, false)) {
// write contingency status
resultWriter.writeContingencyStatus(contingencyIndex, SensitivityAnalysisResult.Status.FAILURE);
return;
Expand Down Expand Up @@ -145,10 +145,15 @@ private void calculatePostContingencySensitivityValues(List<LfSensitivityFactor<
calculateSensitivityValues(lfFactors, factorGroups, factorsStates, contingencyIndex, resultWriter);
}

private static boolean runLoadFlow(AcLoadFlowContext context, boolean throwsExceptionIfNoConvergence) {
private static boolean runLoadFlow(AcLoadFlowContext context,
boolean throwsExceptionIfNoConvergence,
boolean updateContext) {
AcLoadFlowResult result = new AcloadFlowEngine(context)
.run();
if (result.isSuccess() || result.getSolverStatus() == AcSolverStatus.NO_CALCULATION) {
if (updateContext) {
context.setOuterLoopInitData(result.getOuterLoopInitData());
}
return true;
} else {
if (throwsExceptionIfNoConvergence) {
Expand Down Expand Up @@ -249,7 +254,7 @@ public void analyse(Network network, List<PropagatedContingency> contingencies,

try (AcLoadFlowContext context = new AcLoadFlowContext(lfNetwork, acParameters)) {

runLoadFlow(context, true);
runLoadFlow(context, true, true);

// index factors by variable group to compute a minimal number of states
SensitivityFactorGroupList<AcVariableType, AcEquationType> factorGroups = createFactorGroups(validLfFactors.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1818,7 +1818,9 @@ void testStatusConversion() {

private AcLoadFlowResult buildTestAcLoadFlowResult(AcSolverStatus solverStatus, OuterLoopStatus outerLoopStatus) {
LfNetwork lfNetwork = Mockito.mock(LfNetwork.class);
return new AcLoadFlowResult(lfNetwork, 0, 0, solverStatus, new OuterLoopResult("", outerLoopStatus), 0d, 0d);
return new AcLoadFlowResult(lfNetwork, 0, 0,
solverStatus, new OuterLoopResult("", outerLoopStatus),
0d, 0d, Collections.EMPTY_MAP);
}

@Test
Expand Down
Loading