Skip to content

Commit 003d103

Browse files
bqth29phiedwGodelaine
authored
Final branch 3 (#1509)
* various performance changes * update pom with releases * fix broken test on windows Signed-off-by: Thomas Bouquet <thomas.bouquet@rte-france.com> Co-authored-by: phiedw <philippe.edwards@rte-france.com> Co-authored-by: Godelaine de Montmorillon <godelaine.demontmorillon@rte-france.com>
1 parent c968a60 commit 003d103

16 files changed

Lines changed: 253 additions & 189 deletions

File tree

data/crac/crac-api/src/main/java/com/powsybl/openrao/data/crac/api/rangeaction/RangeAction.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,20 @@ public interface RangeAction<T extends RangeAction<T>> extends RemedialAction<T>
5454
*/
5555
Optional<String> getGroupId();
5656

57+
/**
58+
* Get the variation cost to increase or decrease the setpoint by one unit.
59+
*/
5760
Optional<Double> getVariationCost(VariationDirection variationDirection);
61+
62+
/**
63+
* Get the total cost to spend to increase or decrease the setpoint by a given amount.
64+
*/
65+
default double getTotalCostForVariation(Double variation) {
66+
if (Math.abs(variation) < 1e-6) {
67+
return 0.;
68+
}
69+
double activationCost = getActivationCost().orElse(0.);
70+
double variationCost = getVariationCost(variation > 0 ? VariationDirection.UP : VariationDirection.DOWN).orElse(0.) * Math.abs(variation);
71+
return activationCost + variationCost;
72+
}
5873
}

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@
107107
<maven.jar.version>3.3.0</maven.jar.version>
108108
<maven.jvnet.jaxb.version>4.0.8</maven.jvnet.jaxb.version>
109109
<mockito.core.version>5.12.0</mockito.core.version>
110-
<powsybl.core.version>7.0.0-RC1</powsybl.core.version>
111-
<powsybl.entsoe.version>2.15.0-SNAPSHOT</powsybl.entsoe.version>
112-
<powsybl.openloadflow.version>2.0.0-SNAPSHOT</powsybl.openloadflow.version>
110+
<powsybl.core.version>7.0.0</powsybl.core.version>
111+
<powsybl.entsoe.version>3.0.0</powsybl.entsoe.version>
112+
<powsybl.openloadflow.version>2.0.0</powsybl.openloadflow.version>
113113
<slf4j.version>2.0.13</slf4j.version>
114114
<xmlunit.core.version>2.10.0</xmlunit.core.version>
115115
<com.networknt.version>1.5.3</com.networknt.version>

ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/castor/algorithm/CastorContingencyScenarios.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public class CastorContingencyScenarios {
5151

5252
private static final String CONTINGENCY_SCENARIO = "ContingencyScenario";
5353
private static final int NUMBER_LOGGED_ELEMENTS_DURING_RAO = 2;
54+
private static final double COST_EPSILON = 1e-6;
5455

5556
private final Crac crac;
5657
private final RaoParameters raoParameters;
@@ -167,10 +168,22 @@ private Object runScenario(PrePerimeterResult prePerimeterSensitivityOutput, boo
167168
}
168169
}
169170
TECHNICAL_LOGS.debug("Remaining post-contingency scenarios to optimize: {}", remainingScenarios.decrementAndGet());
170-
networkPool.releaseUsedNetwork(networkClone);
171+
boolean actionWasApplied = contingencyScenarioResults.entrySet().stream()
172+
.filter(stateAndResult -> stateAndResult.getKey().getContingency().orElseThrow().equals(optimizedScenario.getContingency()))
173+
.anyMatch(this::isAnyActionApplied);
174+
networkPool.releaseUsedNetwork(networkClone, actionWasApplied);
171175
return null;
172176
}
173177

178+
private boolean isAnyActionApplied(Map.Entry<State, PostPerimeterResult> stateAndResult) {
179+
State state = stateAndResult.getKey();
180+
PostPerimeterResult postPerimeterResult = stateAndResult.getValue();
181+
boolean anyRangeActionApplied = !postPerimeterResult.getOptimizationResult().getActivatedRangeActions(state).isEmpty();
182+
boolean anyNetworkActionApplied = !postPerimeterResult.getOptimizationResult().getActivatedNetworkActions().isEmpty();
183+
return anyRangeActionApplied || anyNetworkActionApplied;
184+
185+
}
186+
174187
private PostPerimeterResult generateSkippedPostPerimeterResult(State state, double sensitivityFailureOvercost) {
175188
OptimizationResult skippedOptimizationResult = new SkippedOptimizationResultImpl(state, new HashSet<>(), new HashSet<>(), ComputationStatus.FAILURE, sensitivityFailureOvercost);
176189
PrePerimeterResult prePerimeterResult = new PrePerimeterSensitivityResultImpl(skippedOptimizationResult, skippedOptimizationResult, null, skippedOptimizationResult);
@@ -271,17 +284,17 @@ private OptimizationResult optimizeCurativePerimeter(Perimeter curativePerimeter
271284
}
272285

273286
static boolean isStopCriterionChecked(ObjectiveFunctionResult result, TreeParameters treeParameters) {
274-
if (result.getVirtualCost() > 1e-6) {
287+
if (result.getVirtualCost() > COST_EPSILON) {
275288
return false;
276289
}
277-
if (result.getFunctionalCost() < -Double.MAX_VALUE / 2 && result.getVirtualCost() < 1e-6) {
290+
if (result.getFunctionalCost() < -Double.MAX_VALUE / 2 && result.getVirtualCost() < COST_EPSILON) {
278291
return true;
279292
}
280293

281294
if (treeParameters.stopCriterion().equals(TreeParameters.StopCriterion.MIN_OBJECTIVE)) {
282295
return false;
283296
} else if (treeParameters.stopCriterion().equals(TreeParameters.StopCriterion.AT_TARGET_OBJECTIVE_VALUE)) {
284-
return result.getCost() < treeParameters.targetObjectiveValue();
297+
return result.getCost() < treeParameters.targetObjectiveValue() + COST_EPSILON;
285298
} else {
286299
throw new OpenRaoException("Unexpected stop criterion: " + treeParameters.stopCriterion());
287300
}

ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/castor/algorithm/CastorFullOptimization.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public CompletableFuture<RaoResult> run() {
8383
}
8484
StateTree stateTree = new StateTree(crac);
8585

86-
currentStep = "initial sensitivity analysis ----";
86+
currentStep = "initial sensitivity analysis";
8787
// ----- INITIAL SENSI -----
8888
// compute initial sensitivity on all CNECs
8989
// (this is necessary to have initial flows for MNEC and loopflow constraints on CNECs, in preventive and curative perimeters)

ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/RaoLogger.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,9 @@ public static void logRangeActions(OpenRaoLogger logger,
133133
boolean globalPstOptimization = optimizationContext instanceof GlobalOptimizationPerimeter;
134134

135135
List<String> rangeActionSetpoints = optimizationContext.getRangeActionOptimizationStates().stream().flatMap(state ->
136-
leaf.getActivatedRangeActions(state).stream().map(rangeAction -> {
137-
double rangeActionValue = rangeAction instanceof PstRangeAction pstRangeAction ? leaf.getOptimizedTap(pstRangeAction, state) :
138-
leaf.getOptimizedSetpoint(rangeAction, state);
139-
return globalPstOptimization ? format("%s@%s: %.0f", rangeAction.getName(), state.getId(), rangeActionValue) :
140-
format("%s: %.0f", rangeAction.getName(), rangeActionValue);
141-
})).toList();
136+
leaf.getActivatedRangeActions(state).stream().map(rangeAction ->
137+
getIndividualStringForRangeActionAndState(leaf, state, rangeAction, globalPstOptimization)
138+
)).toList();
142139

143140
boolean isRangeActionSetPointEmpty = rangeActionSetpoints.isEmpty();
144141
if (isRangeActionSetPointEmpty) {
@@ -148,6 +145,16 @@ public static void logRangeActions(OpenRaoLogger logger,
148145
}
149146
}
150147

148+
private static String getIndividualStringForRangeActionAndState(Leaf leaf, State state, RangeAction<?> rangeAction, boolean globalPstOptimization) {
149+
double valueVariation = rangeAction instanceof PstRangeAction pstRangeAction ? leaf.getTapVariation(pstRangeAction, state) :
150+
leaf.getSetPointVariation(rangeAction, state);
151+
double postOptimValue = rangeAction instanceof PstRangeAction pstRangeAction ? leaf.getOptimizedTap(pstRangeAction, state) :
152+
leaf.getOptimizedSetpoint(rangeAction, state);
153+
double cost = rangeAction.getTotalCostForVariation(valueVariation);
154+
return globalPstOptimization ? format("%s@%s: %.0f (var: %.0f)", rangeAction.getName(), state.getId(), postOptimValue, valueVariation) :
155+
format("%s: %.0f (var: %.0f, cost %.0f)", rangeAction.getName(), postOptimValue, valueVariation, cost);
156+
}
157+
151158
public static void logMostLimitingElementsResults(OpenRaoLogger logger, OptimizationResult optimizationResult, ObjectiveFunctionParameters.ObjectiveFunctionType objectiveFunction, Unit unit, int numberOfLoggedElements) {
152159
logMostLimitingElementsResults(logger, optimizationResult, optimizationResult, null, objectiveFunction, unit, numberOfLoggedElements);
153160
}

ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/costevaluatorresult/SumMaxPerTimestampCostEvaluatorResult.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public double getCost(Set<String> contingenciesToExclude, Set<String> cnecsToExc
5353
Map<OffsetDateTime, Set<State>> statesToEvaluatePerTimestamp = new HashMap<>();
5454
Set<State> statesToEvaluateWithoutTimestamp = new HashSet<>();
5555

56-
costPerState.keySet().stream().forEach(state -> {
56+
costPerState.keySet().forEach(state -> {
5757
if (statesContingencyMustBeKept(state, contingenciesToExclude)) {
5858
Optional<OffsetDateTime> timestamp = state.getTimestamp();
5959
if (timestamp.isPresent()) {
@@ -64,8 +64,8 @@ public double getCost(Set<String> contingenciesToExclude, Set<String> cnecsToExc
6464
}
6565
});
6666

67-
return statesToEvaluatePerTimestamp.values().stream().mapToDouble(states -> states.stream().mapToDouble(state -> costPerState.get(state)).max().orElse(0)).sum()
68-
+ statesToEvaluateWithoutTimestamp.stream().mapToDouble(state -> costPerState.get(state)).max().orElse(0);
67+
return statesToEvaluatePerTimestamp.values().stream().mapToDouble(states -> states.stream().mapToDouble(costPerState::get).max().orElse(0)).sum()
68+
+ statesToEvaluateWithoutTimestamp.stream().mapToDouble(costPerState::get).max().orElse(0);
6969

7070
}
7171

ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/objectivefunctionevaluator/RemedialActionCostEvaluator.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import com.powsybl.openrao.data.crac.api.networkaction.NetworkAction;
1212
import com.powsybl.openrao.data.crac.api.rangeaction.PstRangeAction;
1313
import com.powsybl.openrao.data.crac.api.rangeaction.RangeAction;
14-
import com.powsybl.openrao.data.crac.api.rangeaction.VariationDirection;
1514
import com.powsybl.openrao.searchtreerao.commons.costevaluatorresult.AbsoluteCostEvaluatorResult;
1615
import com.powsybl.openrao.searchtreerao.commons.costevaluatorresult.CostEvaluatorResult;
1716
import com.powsybl.openrao.searchtreerao.result.api.FlowResult;
@@ -61,11 +60,9 @@ private double getTotalRangeActionsCost(RemedialActionActivationResult remedialA
6160
private double computeRangeActionCost(RangeAction<?> rangeAction, State state, RemedialActionActivationResult remedialActionActivationResult) {
6261
double variation = rangeAction instanceof PstRangeAction pstRangeAction ? (double) remedialActionActivationResult.getTapVariation(pstRangeAction, state) : remedialActionActivationResult.getSetPointVariation(rangeAction, state);
6362
double after = rangeAction instanceof PstRangeAction pstRangeAction ? (double) remedialActionActivationResult.getOptimizedTap(pstRangeAction, state) : remedialActionActivationResult.getOptimizedSetpoint(rangeAction, state);
64-
if (variation == 0.0) {
63+
if (Math.abs(variation) < 1e-6) {
6564
return 0.0;
6665
}
67-
double activationCost = rangeAction.getActivationCost().orElse(0.0);
68-
VariationDirection variationDirection = variation > 0 ? VariationDirection.UP : VariationDirection.DOWN;
6966
if (!(rangeAction instanceof PstRangeAction)) {
7067
TECHNICAL_LOGS.debug("{} variation of {} MW at state {} ({} -> {})", rangeAction.getId(),
7168
BigDecimal.valueOf(variation).setScale(2, RoundingMode.HALF_UP),
@@ -79,6 +76,6 @@ private double computeRangeActionCost(RangeAction<?> rangeAction, State state, R
7976
BigDecimal.valueOf(after - variation).setScale(2, RoundingMode.HALF_UP),
8077
BigDecimal.valueOf(after).setScale(2, RoundingMode.HALF_UP));
8178
}
82-
return activationCost + Math.abs(variation) * rangeAction.getVariationCost(variationDirection).orElse(0.0);
79+
return rangeAction.getTotalCostForVariation(variation);
8380
}
8481
}

ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/fastrao/FastRao.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,13 @@ public static RaoResult launchFastRaoOptimization(RaoInput raoInput, RaoParamete
109109
PrePerimeterSensitivityAnalysis prePerimeterSensitivityAnalysis = new PrePerimeterSensitivityAnalysis(
110110
crac,
111111
crac.getFlowCnecs(),
112-
crac.getRangeActions(),
112+
crac.getRangeActions().isEmpty() ? new HashSet<>() : Set.of(crac.getRangeActions().stream().findFirst().orElseThrow()),
113113
parameters,
114114
toolProvider);
115115

116116
// Run initial sensi (for initial values, and to know which cnecs to put in the first rao)
117117
PrePerimeterResult initialResult = prePerimeterSensitivityAnalysis.runInitialSensitivityAnalysis(raoInput.getNetwork());
118+
RangeActionSetpointResult initialRangeActionSetpointResult = RangeActionSetpointResultImpl.buildWithSetpointsFromNetwork(raoInput.getNetwork(), crac.getRangeActions());
118119

119120
if (crac.getFlowCnecs().isEmpty()) {
120121
return new UnoptimizedRaoResultImpl(initialResult);
@@ -149,7 +150,7 @@ public static RaoResult launchFastRaoOptimization(RaoInput raoInput, RaoParamete
149150
consideredCnecs.add(getWorstPreventiveCnec(stepResult, crac));
150151
cleanVariants(raoInput.getNetwork(), initialNetworkVariants, raoInput.getNetworkVariantId());
151152

152-
raoResult = runFilteredRao(raoInput, parameters, targetEndInstant, consideredCnecs, toolProvider, initialResult, networkPool, counter);
153+
raoResult = runFilteredRao(raoInput, parameters, targetEndInstant, consideredCnecs, toolProvider, initialResult, initialRangeActionSetpointResult, networkPool, counter);
153154
stepResult = raoResult.getAppropriateResult(lastInstant);
154155

155156
RaoLogger.logObjectiveFunctionResult(String.format("[FAST RAO] Iteration %d: sensitivity analysis: ", counter),
@@ -229,7 +230,7 @@ private static Set<FlowCnec> getCostlyVirtualCnecs(ObjectiveFunctionResult ofRes
229230
return flowCnecs;
230231
}
231232

232-
private static FastRaoResultImpl runFilteredRao(RaoInput raoInput, RaoParameters parameters, Instant targetEndInstant, Set<FlowCnec> flowCnecsToKeep, ToolProvider toolProvider, PrePerimeterResult initialResult, AbstractNetworkPool networkPool, int counter) throws ExecutionException, InterruptedException {
233+
private static FastRaoResultImpl runFilteredRao(RaoInput raoInput, RaoParameters parameters, Instant targetEndInstant, Set<FlowCnec> flowCnecsToKeep, ToolProvider toolProvider, PrePerimeterResult initialResult, RangeActionSetpointResult initialRangeActionSetpointResult, AbstractNetworkPool networkPool, int counter) throws ExecutionException, InterruptedException {
233234
Crac crac = raoInput.getCrac();
234235

235236
// Filter CRAC to only keep flowCnecsToKeep
@@ -279,6 +280,7 @@ private static FastRaoResultImpl runFilteredRao(RaoInput raoInput, RaoParameters
279280
crac,
280281
raoResult,
281282
initialResult,
283+
initialRangeActionSetpointResult,
282284
CompletableFuture.completedFuture(initialResult),
283285
stateTree,
284286
parameters,
@@ -292,6 +294,7 @@ private static FastRaoResultImpl runFilteredRao(RaoInput raoInput, RaoParameters
292294
crac,
293295
raoResult,
294296
initialResult,
297+
initialRangeActionSetpointResult,
295298
postPraSensi.thenApply(PostPerimeterResult::getPrePerimeterResultForAllFollowingStates),
296299
stateTree,
297300
parameters,
@@ -305,6 +308,7 @@ private static FastRaoResultImpl runFilteredRao(RaoInput raoInput, RaoParameters
305308
crac,
306309
raoResult,
307310
initialResult,
311+
initialRangeActionSetpointResult,
308312
postAraSensi.thenApply(PostPerimeterResult::getPrePerimeterResultForAllFollowingStates),
309313
stateTree,
310314
parameters,
@@ -341,18 +345,19 @@ private static CompletableFuture<PostPerimeterResult> runPostPerimeterAnalysis(
341345
Crac crac,
342346
RaoResult raoResult,
343347
PrePerimeterResult initialResult,
348+
RangeActionSetpointResult initialRangeActionSetpointResult,
344349
CompletableFuture<PrePerimeterResult> previousSensiFuture,
345350
StateTree stateTree,
346351
RaoParameters parameters,
347352
ToolProvider toolProvider,
348353
InstantKind instantKind) {
349354

355+
// Collect all activated remedial actions (for costly evaluation)
356+
RemedialActionActivationResult remedialActionActivationResult = createRemedialActionsActivationResults(instantKind, raoResult, crac, initialRangeActionSetpointResult);
357+
350358
// Apply Preventive Remedial Actions
351359
applyOptimalPreventiveRemedialActions(networkCopy, crac.getPreventiveState(), raoResult);
352360

353-
// Collect all activated remedial actions (for costly evaluation)
354-
RemedialActionActivationResult remedialActionActivationResult = createRemedialActionsActivationResults(instantKind, raoResult, crac, initialResult);
355-
356361
AppliedRemedialActions appliedRemedialActions;
357362
if (instantKind.equals(InstantKind.PREVENTIVE)) {
358363
// for preventive no need the preventive RAs were already applied on the network
@@ -363,7 +368,12 @@ private static CompletableFuture<PostPerimeterResult> runPostPerimeterAnalysis(
363368
}
364369

365370
// Build sensitivity analysis
366-
PostPerimeterSensitivityAnalysis perimeterSensiAnalysis = new PostPerimeterSensitivityAnalysis(crac, crac.getStates(), parameters, toolProvider);
371+
PostPerimeterSensitivityAnalysis perimeterSensiAnalysis = new PostPerimeterSensitivityAnalysis(
372+
crac,
373+
crac.getFlowCnecs(),
374+
crac.getRangeActions().isEmpty() ? new HashSet<>() : Set.of(crac.getRangeActions().stream().findFirst().orElseThrow()),
375+
parameters,
376+
toolProvider);
367377

368378
// Run asynchronously
369379
return perimeterSensiAnalysis.runAsyncBasedOnInitialPreviousAndActivatedRa(
@@ -376,10 +386,10 @@ private static CompletableFuture<PostPerimeterResult> runPostPerimeterAnalysis(
376386
);
377387
}
378388

379-
private static RemedialActionActivationResult createRemedialActionsActivationResults(InstantKind instantKind, RaoResult raoResult, Crac crac, PrePerimeterResult initialResult) {
389+
private static RemedialActionActivationResult createRemedialActionsActivationResults(InstantKind instantKind, RaoResult raoResult, Crac crac, RangeActionSetpointResult initialRangeActionSetpointResult) {
380390
// Get all the remedial action activated during all instant <= instandKind
381391
Map<State, Set<NetworkAction>> networkActionsActivated = new HashMap<>();
382-
RangeActionActivationResultImpl rangeActionActivationResult = new RangeActionActivationResultImpl(initialResult.getRangeActionSetpointResult());
392+
RangeActionActivationResultImpl rangeActionActivationResult = new RangeActionActivationResultImpl(initialRangeActionSetpointResult);
383393
if (raoResult instanceof OneStateOnlyRaoResultImpl) {
384394
State preventiveState = crac.getPreventiveState();
385395
networkActionsActivated.put(preventiveState, raoResult.getActivatedNetworkActionsDuringState(preventiveState));

0 commit comments

Comments
 (0)