Skip to content

Commit ee54cab

Browse files
committed
initial implementation
1 parent da71f30 commit ee54cab

File tree

12 files changed

+103
-14
lines changed

12 files changed

+103
-14
lines changed

src/main/java/com/powsybl/openloadflow/AcLoadFlowFromCache.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.slf4j.Logger;
2525
import org.slf4j.LoggerFactory;
2626

27+
import java.util.Collections;
2728
import java.util.List;
2829
import java.util.Objects;
2930
import java.util.stream.Collectors;
@@ -120,7 +121,10 @@ private static AcLoadFlowResult run(AcLoadFlowContext context) {
120121
context.setNetworkUpdated(false);
121122
return result;
122123
}
123-
return new AcLoadFlowResult(context.getNetwork(), 0, 0, AcSolverStatus.CONVERGED, OuterLoopResult.stable(), 0d, 0d);
124+
return new AcLoadFlowResult(context.getNetwork(), 0,
125+
0, AcSolverStatus.CONVERGED, OuterLoopResult.stable(),
126+
0d, 0d,
127+
Collections.EMPTY_MAP);
124128
}
125129

126130
public List<AcLoadFlowResult> run() {

src/main/java/com/powsybl/openloadflow/ac/AcLoadFlowContext.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package com.powsybl.openloadflow.ac;
99

1010
import com.powsybl.openloadflow.ac.equations.asym.AsymmetricalAcEquationSystemCreator;
11+
import com.powsybl.openloadflow.ac.outerloop.AcOuterLoop;
1112
import com.powsybl.openloadflow.equations.JacobianMatrix;
1213
import com.powsybl.openloadflow.lf.AbstractLoadFlowContext;
1314
import com.powsybl.openloadflow.ac.equations.AcEquationSystemCreator;
@@ -18,6 +19,9 @@
1819
import com.powsybl.openloadflow.equations.TargetVector;
1920
import com.powsybl.openloadflow.network.LfNetwork;
2021

22+
import java.util.HashMap;
23+
import java.util.Map;
24+
2125
/**
2226
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
2327
*/
@@ -31,6 +35,8 @@ public class AcLoadFlowContext extends AbstractLoadFlowContext<AcVariableType, A
3135

3236
private boolean networkUpdated = true;
3337

38+
private Map<Class<? extends AcOuterLoop>, Object> outerLoopInitData = new HashMap<>();
39+
3440
public AcLoadFlowContext(LfNetwork network, AcLoadFlowParameters parameters) {
3541
super(network, parameters);
3642
}
@@ -84,6 +90,14 @@ public void setNetworkUpdated(boolean networkUpdated) {
8490
this.networkUpdated = networkUpdated;
8591
}
8692

93+
public Object getOuterLoopInitData(Class<? extends AcOuterLoop> outerLoopClass) {
94+
return outerLoopInitData.get(outerLoopClass);
95+
}
96+
97+
public void setOuterLoopInitData(Map<Class<? extends AcOuterLoop>, Object> outerLoopInitData) {
98+
this.outerLoopInitData = outerLoopInitData;
99+
}
100+
87101
@Override
88102
public void close() {
89103
super.close();

src/main/java/com/powsybl/openloadflow/ac/AcLoadFlowResult.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@
88
package com.powsybl.openloadflow.ac;
99

1010
import com.powsybl.loadflow.LoadFlowResult;
11+
import com.powsybl.openloadflow.ac.outerloop.AcOuterLoop;
1112
import com.powsybl.openloadflow.ac.solver.AcSolverStatus;
1213
import com.powsybl.openloadflow.lf.AbstractLoadFlowResult;
1314
import com.powsybl.openloadflow.lf.outerloop.OuterLoopResult;
1415
import com.powsybl.openloadflow.lf.outerloop.OuterLoopStatus;
1516
import com.powsybl.openloadflow.network.LfNetwork;
1617
import com.powsybl.openloadflow.util.PerUnit;
1718

19+
import java.util.Collections;
20+
import java.util.Map;
1821
import java.util.Objects;
1922

2023
/**
@@ -23,19 +26,24 @@
2326
public class AcLoadFlowResult extends AbstractLoadFlowResult {
2427

2528
public static AcLoadFlowResult createNoCalculationResult(LfNetwork network) {
26-
return new AcLoadFlowResult(network, 0, 0, AcSolverStatus.NO_CALCULATION, OuterLoopResult.stable(), Double.NaN, Double.NaN);
29+
return new AcLoadFlowResult(network, 0, 0, AcSolverStatus.NO_CALCULATION, OuterLoopResult.stable(), Double.NaN, Double.NaN,
30+
Collections.EMPTY_MAP);
2731
}
2832

2933
private final int solverIterations;
3034

3135
private final AcSolverStatus solverStatus;
3236

37+
private final Map<Class<? extends AcOuterLoop>, Object> outerLoopInitData;
38+
3339
public AcLoadFlowResult(LfNetwork network, int outerLoopIterations, int solverIterations,
3440
AcSolverStatus solverStatus, OuterLoopResult outerLoopResult,
35-
double slackBusActivePowerMismatch, double distributedActivePower) {
41+
double slackBusActivePowerMismatch, double distributedActivePower,
42+
Map<Class<? extends AcOuterLoop>, Object> outerLoopInitData) {
3643
super(network, slackBusActivePowerMismatch, outerLoopIterations, outerLoopResult, distributedActivePower);
3744
this.solverIterations = solverIterations;
3845
this.solverStatus = Objects.requireNonNull(solverStatus);
46+
this.outerLoopInitData = outerLoopInitData;
3947
}
4048

4149
public int getSolverIterations() {
@@ -79,6 +87,10 @@ public Status toComponentResultStatus() {
7987
}
8088
}
8189

90+
public Map<Class<? extends AcOuterLoop>, Object> getOuterLoopInitData() {
91+
return outerLoopInitData;
92+
}
93+
8294
@Override
8395
public String toString() {
8496
return "AcLoadFlowResult(outerLoopIterations=" + outerLoopIterations

src/main/java/com/powsybl/openloadflow/ac/AcOuterLoopContext.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,23 @@
1313
import com.powsybl.openloadflow.lf.outerloop.AbstractOuterLoopContext;
1414
import com.powsybl.openloadflow.network.LfNetwork;
1515

16+
import java.util.Optional;
17+
1618
/**
1719
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
1820
*/
1921
public class AcOuterLoopContext extends AbstractOuterLoopContext<AcVariableType, AcEquationType, AcLoadFlowParameters, AcLoadFlowContext> {
2022

2123
private AcSolverResult lastSolverResult;
24+
private Object outerLoopInitData;
2225

23-
AcOuterLoopContext(LfNetwork network) {
26+
AcOuterLoopContext(LfNetwork network, Object dataForRunFromPreviousValues) {
2427
super(network);
28+
this.outerLoopInitData = dataForRunFromPreviousValues;
29+
}
30+
31+
public Optional<Object> getOuterLoopInitData() {
32+
return Optional.ofNullable(outerLoopInitData);
2533
}
2634

2735
public AcSolverResult getLastSolverResult() {

src/main/java/com/powsybl/openloadflow/ac/AcloadFlowEngine.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.slf4j.Logger;
2727
import org.slf4j.LoggerFactory;
2828

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

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

151152
List<AcOuterLoop> outerLoops = context.getParameters().getOuterLoops();
152153
List<Pair<AcOuterLoop, AcOuterLoopContext>> outerLoopsAndContexts = outerLoops.stream()
153-
.map(outerLoop -> Pair.of(outerLoop, new AcOuterLoopContext(context.getNetwork())))
154+
.map(outerLoop -> Pair.of(outerLoop, new AcOuterLoopContext(context.getNetwork(), context.getOuterLoopInitData(outerLoop.getClass()))))
154155
.toList();
155156

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

221-
return buildAcLoadFlowResult(runningContext, outerLoopFinalResult, distributedActivePower);
222+
return buildAcLoadFlowResult(runningContext, outerLoopFinalResult, distributedActivePower, outerLoopsAndContexts);
222223
}
223224

224-
private AcLoadFlowResult buildAcLoadFlowResult(RunningContext runningContext, OuterLoopResult outerLoopFinalResult, double distributedActivePower) {
225+
private AcLoadFlowResult buildAcLoadFlowResult(RunningContext runningContext,
226+
OuterLoopResult outerLoopFinalResult,
227+
double distributedActivePower,
228+
List<Pair<AcOuterLoop, AcOuterLoopContext>> outerLoopsAndContexts) {
229+
230+
Map<Class<? extends AcOuterLoop>, Object> outerLoopInitData = new HashMap<>();
231+
outerLoopsAndContexts.forEach(p -> p.getLeft().getInitData(p.getRight()).ifPresent(d -> outerLoopInitData.put(p.getLeft().getClass(), d)));
232+
225233
AcLoadFlowResult result = new AcLoadFlowResult(context.getNetwork(),
226234
runningContext.outerLoopTotalIterations,
227235
runningContext.nrTotalIterations.getValue(),
228236
runningContext.lastSolverResult.getStatus(),
229237
outerLoopFinalResult,
230238
runningContext.lastSolverResult.getSlackBusActivePowerMismatch(),
231-
distributedActivePower
239+
distributedActivePower,
240+
outerLoopInitData
232241
);
233242

234243
LOGGER.info("AC loadflow complete on network {} (result={})", context.getNetwork(), result);

src/main/java/com/powsybl/openloadflow/ac/outerloop/AcOuterLoop.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,17 @@
1414
import com.powsybl.openloadflow.ac.equations.AcVariableType;
1515
import com.powsybl.openloadflow.lf.outerloop.OuterLoop;
1616

17+
import java.util.Optional;
18+
1719
/**
1820
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
1921
*/
2022
public interface AcOuterLoop extends OuterLoop<AcVariableType, AcEquationType, AcLoadFlowParameters, AcLoadFlowContext, AcOuterLoopContext> {
23+
24+
/**
25+
* Returns data needed to initialize the outerloop for a rerun from previous values.
26+
*/
27+
default Optional<Object> getInitData(AcOuterLoopContext context) {
28+
return Optional.empty();
29+
}
2130
}

src/main/java/com/powsybl/openloadflow/ac/outerloop/ReactiveLimitsOuterLoop.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ private static final class ContextData {
5656

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

59+
public ContextData(Optional<Object> initData) {
60+
initData.ifPresent(d -> {
61+
if (d instanceof Map map) {
62+
pvPqSwitchCount.putAll(map);
63+
}
64+
});
65+
}
66+
5967
void incrementPvPqSwitchCount(String busId) {
6068
pvPqSwitchCount.computeIfAbsent(busId, k -> new MutableInt(0))
6169
.increment();
@@ -163,7 +171,7 @@ private boolean switchPvPq(List<ControllerBusToPqBus> pvToPqBuses, int remaining
163171

164172
@Override
165173
public void initialize(AcOuterLoopContext context) {
166-
context.setData(new ContextData());
174+
context.setData(new ContextData(context.getOuterLoopInitData()));
167175
}
168176

169177
private static boolean switchPqPv(List<PqToPvBus> pqToPvBuses, ContextData contextData, ReportNode reportNode, int maxPqPvSwitch) {
@@ -349,4 +357,9 @@ public OuterLoopResult check(AcOuterLoopContext context, ReportNode reportNode)
349357
}
350358
return new OuterLoopResult(this, status);
351359
}
360+
361+
@Override
362+
public Optional<Object> getInitData(AcOuterLoopContext context) {
363+
return Optional.of(Collections.unmodifiableMap(((ContextData) context.getData()).pvPqSwitchCount));
364+
}
352365
}

src/main/java/com/powsybl/openloadflow/sa/AbstractSecurityAnalysis.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,8 @@ protected static void distributedMismatch(LfNetwork network, double mismatch, Lo
616616

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

619+
protected abstract void updateContext(R result, C context);
620+
619621
protected void afterPreContingencySimulation(P acParameters) {
620622
}
621623

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

650652
// only run post-contingency simulations if pre-contingency simulation is ok
651653
if (preContingencyComputationOk) {
654+
updateContext(preContingencyLoadFlowResult, context);
652655
afterPreContingencySimulation(acParameters);
653656

654657
// update network result

src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,9 @@ protected PostContingencyComputationStatus postContingencyStatusFromLoadFlowResu
112112
protected void beforeActionLoadFlowRun(AcLoadFlowContext context) {
113113
context.getParameters().setVoltageInitializer(new PreviousValueVoltageInitializer(true));
114114
}
115+
116+
@Override
117+
protected void updateContext(AcLoadFlowResult result, AcLoadFlowContext context) {
118+
context.setOuterLoopInitData(result.getOuterLoopInitData());
119+
}
115120
}

src/main/java/com/powsybl/openloadflow/sa/DcSecurityAnalysis.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,9 @@ protected DcLoadFlowEngine createLoadFlowEngine(DcLoadFlowContext context) {
7373
protected PostContingencyComputationStatus postContingencyStatusFromLoadFlowResult(DcLoadFlowResult result) {
7474
return result.isSuccess() ? PostContingencyComputationStatus.CONVERGED : PostContingencyComputationStatus.FAILED;
7575
}
76+
77+
@Override
78+
protected void updateContext(DcLoadFlowResult result, DcLoadFlowContext context) {
79+
// Nothing to do
80+
}
7681
}

0 commit comments

Comments
 (0)