Skip to content

Add optimized states to optimization result API #1290

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

Open
wants to merge 4 commits 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 @@ -207,7 +207,7 @@ private OptimizationResult optimizeCurativePerimeter(Perimeter curativePerimeter
boolean stopCriterionReached = isStopCriterionChecked(objectiveFunctionResult, curativeTreeParameters);
if (stopCriterionReached) {
NetworkActionsResult networkActionsResult = new NetworkActionsResultImpl(Collections.emptySet());
return new OptimizationResultImpl(objectiveFunctionResult, prePerimeterSensitivityOutput, prePerimeterSensitivityOutput, networkActionsResult, rangeActionsResult);
return new OptimizationResultImpl(objectiveFunctionResult, prePerimeterSensitivityOutput, prePerimeterSensitivityOutput, networkActionsResult, rangeActionsResult, Set.of(curativeState));
}

OptimizationPerimeter optPerimeter = CurativeOptimizationPerimeter.buildForStates(curativeState, curativePerimeter.getAllStates(), crac, network, raoParameters, prePerimeterSensitivityOutput);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

package com.powsybl.openrao.searchtreerao.linearoptimisation.algorithms;

import com.powsybl.openrao.data.crac.api.State;
import com.powsybl.openrao.data.crac.api.rangeaction.PstRangeAction;
import com.powsybl.openrao.data.raoresult.api.ComputationStatus;
import com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoRangeActionsOptimizationParameters.PstModel;
Expand All @@ -27,6 +28,7 @@
import org.apache.commons.lang3.tuple.Pair;

import java.util.Locale;
import java.util.Set;

import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.*;
import static com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoRangeActionsOptimizationParameters.getPstModel;
Expand All @@ -43,19 +45,20 @@ private IteratingLinearOptimizer() {
public static LinearOptimizationResult optimize(IteratingLinearOptimizerInput input, IteratingLinearOptimizerParameters parameters) {

IteratingLinearOptimizationResultImpl bestResult = createResult(
input.preOptimizationFlowResult(),
input.preOptimizationSensitivityResult(),
input.raActivationFromParentLeaf(),
input.appliedNetworkActionsInPrimaryState(),
0,
input.objectiveFunction());
input.preOptimizationFlowResult(),
input.preOptimizationSensitivityResult(),
input.raActivationFromParentLeaf(),
input.appliedNetworkActionsInPrimaryState(),
0,
input.objectiveFunction(),
input.optimizationPerimeter().getRangeActionOptimizationStates());

IteratingLinearOptimizationResultImpl previousResult = bestResult;

SensitivityComputer sensitivityComputer = null;

LinearProblem linearProblem = LinearProblem.create()
.buildFromInputsAndParameters(input, parameters);
.buildFromInputsAndParameters(input, parameters);

linearProblem.fill(input.preOptimizationFlowResult(), input.preOptimizationSensitivityResult());

Expand Down Expand Up @@ -92,12 +95,13 @@ public static LinearOptimizationResult optimize(IteratingLinearOptimizerInput in
}

IteratingLinearOptimizationResultImpl currentResult = createResult(
sensitivityComputer.getBranchResult(input.network()),
sensitivityComputer.getSensitivityResult(),
currentRangeActionActivationResult,
input.appliedNetworkActionsInPrimaryState(),
iteration,
input.objectiveFunction()
sensitivityComputer.getBranchResult(input.network()),
sensitivityComputer.getSensitivityResult(),
currentRangeActionActivationResult,
input.appliedNetworkActionsInPrimaryState(),
iteration,
input.objectiveFunction(),
input.optimizationPerimeter().getRangeActionOptimizationStates()
);
previousResult = currentResult;

Expand Down Expand Up @@ -157,8 +161,8 @@ private static LinearProblemStatus solveLinearProblem(LinearProblem linearProble

private static boolean hasAnyRangeActionChanged(RangeActionActivationResult newRangeActionActivationResult, RangeActionActivationResult oldRangeActionActivationResult, OptimizationPerimeter optimizationContext) {
return optimizationContext.getRangeActionsPerState().entrySet().stream()
.anyMatch(e -> e.getValue().stream()
.anyMatch(ra -> Math.abs(newRangeActionActivationResult.getOptimizedSetpoint(ra, e.getKey()) - oldRangeActionActivationResult.getOptimizedSetpoint(ra, e.getKey())) >= 1e-6));
.anyMatch(e -> e.getValue().stream()
.anyMatch(ra -> Math.abs(newRangeActionActivationResult.getOptimizedSetpoint(ra, e.getKey()) - oldRangeActionActivationResult.getOptimizedSetpoint(ra, e.getKey())) >= 1e-6));
}

public static AppliedRemedialActions applyRangeActions(RangeActionActivationResult rangeActionActivationResult, IteratingLinearOptimizerInput input) {
Expand All @@ -167,15 +171,15 @@ public static AppliedRemedialActions applyRangeActions(RangeActionActivationResu

// apply RangeAction from first optimization state
optimizationContext.getRangeActionsPerState().get(optimizationContext.getMainOptimizationState())
.forEach(ra -> ra.apply(input.network(), rangeActionActivationResult.getOptimizedSetpoint(ra, optimizationContext.getMainOptimizationState())));
.forEach(ra -> ra.apply(input.network(), rangeActionActivationResult.getOptimizedSetpoint(ra, optimizationContext.getMainOptimizationState())));

// add RangeAction activated in the following states
if (optimizationContext instanceof GlobalOptimizationPerimeter) {
AppliedRemedialActions appliedRemedialActions = input.preOptimizationAppliedRemedialActions().copyNetworkActionsAndAutomaticRangeActions();

optimizationContext.getRangeActionsPerState().entrySet().stream()
.filter(e -> !e.getKey().equals(optimizationContext.getMainOptimizationState())) // remove preventive state
.forEach(e -> e.getValue().forEach(ra -> appliedRemedialActions.addAppliedRangeAction(e.getKey(), ra, rangeActionActivationResult.getOptimizedSetpoint(ra, e.getKey()))));
.filter(e -> !e.getKey().equals(optimizationContext.getMainOptimizationState())) // remove preventive state
.forEach(e -> e.getValue().forEach(ra -> appliedRemedialActions.addAppliedRangeAction(e.getKey(), ra, rangeActionActivationResult.getOptimizedSetpoint(ra, e.getKey()))));
return appliedRemedialActions;
} else {
return null;
Expand All @@ -185,11 +189,11 @@ public static AppliedRemedialActions applyRangeActions(RangeActionActivationResu
private static SensitivityComputer createSensitivityComputer(AppliedRemedialActions appliedRemedialActions, IteratingLinearOptimizerInput input, IteratingLinearOptimizerParameters parameters) {

SensitivityComputer.SensitivityComputerBuilder builder = SensitivityComputer.create()
.withCnecs(input.optimizationPerimeter().getFlowCnecs())
.withRangeActions(input.optimizationPerimeter().getRangeActions())
.withAppliedRemedialActions(appliedRemedialActions)
.withToolProvider(input.toolProvider())
.withOutageInstant(input.outageInstant());
.withCnecs(input.optimizationPerimeter().getFlowCnecs())
.withRangeActions(input.optimizationPerimeter().getRangeActions())
.withAppliedRemedialActions(appliedRemedialActions)
.withToolProvider(input.toolProvider())
.withOutageInstant(input.outageInstant());

if (parameters.isRaoWithLoopFlowLimitation() && parameters.getLoopFlowParametersExtension().getPtdfApproximation().shouldUpdatePtdfWithPstChange()) {
builder.withCommercialFlowsResults(input.toolProvider().getLoopFlowComputation(), input.optimizationPerimeter().getLoopFlowCnecs());
Expand All @@ -215,13 +219,14 @@ private static void runSensitivityAnalysis(SensitivityComputer sensitivityComput
}

private static IteratingLinearOptimizationResultImpl createResult(FlowResult flowResult,
SensitivityResult sensitivityResult,
RangeActionActivationResult rangeActionActivation,
NetworkActionsResult networkActionsResult,
int nbOfIterations,
ObjectiveFunction objectiveFunction) {
SensitivityResult sensitivityResult,
RangeActionActivationResult rangeActionActivation,
NetworkActionsResult networkActionsResult,
int nbOfIterations,
ObjectiveFunction objectiveFunction,
Set<State> optimizedStates) {
return new IteratingLinearOptimizationResultImpl(LinearProblemStatus.OPTIMAL, nbOfIterations, rangeActionActivation, flowResult,
objectiveFunction.evaluate(flowResult, new RemedialActionActivationResultImpl(rangeActionActivation, networkActionsResult)), sensitivityResult);
objectiveFunction.evaluate(flowResult, new RemedialActionActivationResultImpl(rangeActionActivation, networkActionsResult)), sensitivityResult, optimizedStates);
}

private static Pair<IteratingLinearOptimizationResultImpl, Boolean> updateBestResultAndCheckStopCondition(boolean raRangeShrinking, LinearProblem linearProblem, IteratingLinearOptimizerInput input, int iteration, IteratingLinearOptimizationResultImpl currentResult, IteratingLinearOptimizationResultImpl bestResult) {
Expand Down Expand Up @@ -264,29 +269,29 @@ private static RangeActionActivationResultImpl roundPsts(RangeActionActivationRe
}

static void roundOtherRas(RangeActionActivationResult linearProblemResult,
OptimizationPerimeter optimizationContext,
RangeActionActivationResultImpl roundedResult) {
OptimizationPerimeter optimizationContext,
RangeActionActivationResultImpl roundedResult) {
optimizationContext.getRangeActionsPerState().keySet().forEach(state -> linearProblemResult.getActivatedRangeActions(state).stream()
.filter(ra -> !(ra instanceof PstRangeAction))
.forEach(ra -> roundedResult.putResult(ra, state, Math.round(linearProblemResult.getOptimizedSetpoint(ra, state)))));
}

private static void logBetterResult(int iteration, ObjectiveFunctionResult currentObjectiveFunctionResult) {
TECHNICAL_LOGS.info(
"Iteration {}: better solution found with a cost of {} (functional: {})",
iteration,
formatDouble(currentObjectiveFunctionResult.getCost()),
formatDouble(currentObjectiveFunctionResult.getFunctionalCost()));
"Iteration {}: better solution found with a cost of {} (functional: {})",
iteration,
formatDouble(currentObjectiveFunctionResult.getCost()),
formatDouble(currentObjectiveFunctionResult.getFunctionalCost()));
}

private static void logWorseResult(int iteration, ObjectiveFunctionResult bestResult, ObjectiveFunctionResult currentResult) {
TECHNICAL_LOGS.info(
"Iteration {}: linear optimization found a worse result than best iteration, with a cost increasing from {} to {} (functional: from {} to {})",
iteration,
formatDouble(bestResult.getCost()),
formatDouble(currentResult.getCost()),
formatDouble(bestResult.getFunctionalCost()),
formatDouble(currentResult.getFunctionalCost()));
"Iteration {}: linear optimization found a worse result than best iteration, with a cost increasing from {} to {} (functional: from {} to {})",
iteration,
formatDouble(bestResult.getCost()),
formatDouble(currentResult.getCost()),
formatDouble(bestResult.getFunctionalCost()),
formatDouble(currentResult.getFunctionalCost()));
}

private static String formatDouble(double value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand All @@ -58,12 +59,14 @@ private InterTemporalIteratingLinearOptimizer() {

public static LinearOptimizationResult optimize(InterTemporalIteratingLinearOptimizerInput input, IteratingLinearOptimizerParameters parameters) {
// 1. Initialize best result using input data
Set<State> optimizedStates = new HashSet<>(input.iteratingLinearOptimizerInputs().map(individualInput -> individualInput.optimizationPerimeter().getMainOptimizationState()).getDataPerTimestamp().values());
GlobalLinearOptimizationResult bestResult = createInitialResult(
input.iteratingLinearOptimizerInputs().map(IteratingLinearOptimizerInput::prePerimeterFlowResult),
input.iteratingLinearOptimizerInputs().map(IteratingLinearOptimizerInput::preOptimizationSensitivityResult),
input.iteratingLinearOptimizerInputs().map(IteratingLinearOptimizerInput::prePerimeterSetpoints).map(RangeActionActivationResultImpl::new),
input.iteratingLinearOptimizerInputs().map(IteratingLinearOptimizerInput::appliedNetworkActionsInPrimaryState),
input.objectiveFunction()
input.objectiveFunction(),
optimizedStates
);
GlobalLinearOptimizationResult previousResult = bestResult;

Expand Down Expand Up @@ -138,7 +141,8 @@ public static LinearOptimizationResult optimize(InterTemporalIteratingLinearOpti
input.iteratingLinearOptimizerInputs().map(IteratingLinearOptimizerInput::network),
rangeActionActivationPerTimestamp,
input.iteratingLinearOptimizerInputs().map(IteratingLinearOptimizerInput::appliedNetworkActionsInPrimaryState),
input.objectiveFunction()
input.objectiveFunction(),
optimizedStates
);
previousResult = newResult;

Expand Down Expand Up @@ -275,17 +279,17 @@ private static void runSensitivityAnalysis(SensitivityComputer sensitivityComput
}

// Result management
private static GlobalLinearOptimizationResult createInitialResult(TemporalData<FlowResult> flowResults, TemporalData<SensitivityResult> sensitivityResults, TemporalData<RangeActionActivationResult> rangeActionActivations, TemporalData<NetworkActionsResult> preventiveTopologicalActions, ObjectiveFunction objectiveFunction) {
return new GlobalLinearOptimizationResult(flowResults, sensitivityResults, rangeActionActivations, preventiveTopologicalActions, objectiveFunction, LinearProblemStatus.OPTIMAL);
private static GlobalLinearOptimizationResult createInitialResult(TemporalData<FlowResult> flowResults, TemporalData<SensitivityResult> sensitivityResults, TemporalData<RangeActionActivationResult> rangeActionActivations, TemporalData<NetworkActionsResult> preventiveTopologicalActions, ObjectiveFunction objectiveFunction, Set<State> optimizedStates) {
return new GlobalLinearOptimizationResult(flowResults, sensitivityResults, rangeActionActivations, preventiveTopologicalActions, objectiveFunction, LinearProblemStatus.OPTIMAL, optimizedStates);
}

private static GlobalLinearOptimizationResult createResultFromData(TemporalData<SensitivityComputer> sensitivityComputers, TemporalData<Network> networks, TemporalData<RangeActionActivationResult> rangeActionActivation, TemporalData<NetworkActionsResult> preventiveTopologicalActions, ObjectiveFunction objectiveFunction) {
private static GlobalLinearOptimizationResult createResultFromData(TemporalData<SensitivityComputer> sensitivityComputers, TemporalData<Network> networks, TemporalData<RangeActionActivationResult> rangeActionActivation, TemporalData<NetworkActionsResult> preventiveTopologicalActions, ObjectiveFunction objectiveFunction, Set<State> optimizedStates) {
Map<OffsetDateTime, FlowResult> flowResults = new HashMap<>();
for (OffsetDateTime timestamp : sensitivityComputers.getTimestamps()) {
FlowResult flowResult = sensitivityComputers.getData(timestamp).orElseThrow().getBranchResult(networks.getData(timestamp).orElseThrow());
flowResults.put(timestamp, flowResult);
}
return new GlobalLinearOptimizationResult(new TemporalDataImpl<>(flowResults), sensitivityComputers.map(SensitivityComputer::getSensitivityResult), rangeActionActivation, preventiveTopologicalActions, objectiveFunction, LinearProblemStatus.OPTIMAL);
return new GlobalLinearOptimizationResult(new TemporalDataImpl<>(flowResults), sensitivityComputers.map(SensitivityComputer::getSensitivityResult), rangeActionActivation, preventiveTopologicalActions, objectiveFunction, LinearProblemStatus.OPTIMAL, optimizedStates);
}

// Set-point rounding
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import com.powsybl.openrao.searchtreerao.result.impl.OneStateOnlyRaoResultImpl;
import com.powsybl.openrao.searchtreerao.result.impl.OptimizationResultImpl;

import java.util.Set;

import static com.powsybl.openrao.searchtreerao.marmot.MarmotUtils.getPreventivePerimeterCnecs;

/** This class concatenates all data around one individual timestamp from running Marmot:
Expand All @@ -33,7 +35,7 @@ public record PostOptimizationResult(RaoInput raoInput, PrePerimeterResult initi
public RaoResult merge() {
Crac crac = raoInput.getCrac();
State preventiveState = crac.getPreventiveState();
OptimizationResult mergedOptimizationResult = new OptimizationResultImpl(linearOptimizationResult, linearOptimizationResult, linearOptimizationResult, new NetworkActionsResultImpl(topologicalOptimizationResult.getActivatedNetworkActionsDuringState(preventiveState)), linearOptimizationResult);
OptimizationResult mergedOptimizationResult = new OptimizationResultImpl(linearOptimizationResult, linearOptimizationResult, linearOptimizationResult, new NetworkActionsResultImpl(topologicalOptimizationResult.getActivatedNetworkActionsDuringState(preventiveState)), linearOptimizationResult, Set.of(preventiveState));
return new OneStateOnlyRaoResultImpl(preventiveState, initialResult, mergedOptimizationResult, getPreventivePerimeterCnecs(crac));
}
}
Loading
Loading