sensitivityResult = new AtomicReference<>();
+ boolean actionWasTaken = actionWasTaken(
+ optimizationResult.getActivatedNetworkActions(),
+ optimizationResult.getActivatedRangeActionsPerState());
+ if (actionWasTaken) {
+ SensitivityComputer sensitivityComputer = buildSensitivityComputer(
+ initialFlowResult,
+ appliedCurativeRemedialActions);
+
+ int oldThreadCount = setNewThreadCountAndGetOldValue();
+ sensitivityComputer.compute(network);
+ resetThreadCount(oldThreadCount);
+ flowResult.set(sensitivityComputer.getBranchResult(network));
+ sensitivityResult.set(sensitivityComputer.getSensitivityResult());
+ } else {
+ flowResult.set(previousResultsFuture);
+ sensitivityResult.set(previousResultsFuture);
+ }
+
+ ObjectiveFunction objectiveFunction = ObjectiveFunction.build(
+ flowCnecs,
+ toolProvider.getLoopFlowCnecs(flowCnecs),
+ initialFlowResult,
+ previousResultsFuture,
+ operatorsNotSharingCras,
+ raoParameters,
+ optimizationResult.getActivatedRangeActionsPerState().keySet()
+ );
+
+ ObjectiveFunctionResult objectiveFunctionResult = objectiveFunction.evaluate(
+ flowResult.get(),
+ new RemedialActionActivationResultImpl(optimizationResult, optimizationResult)
+ );
- ObjectiveFunction objectiveFunction = ObjectiveFunction.build(
- flowCnecs,
- toolProvider.getLoopFlowCnecs(flowCnecs),
- initialFlowResult,
- previousResultsFuture,
- operatorsNotSharingCras,
- raoParameters,
- optimizationResult.getActivatedRangeActionsPerState().keySet()
- );
-
- ObjectiveFunctionResult objectiveFunctionResult = objectiveFunction.evaluate(
- flowResult.get(),
- new RemedialActionActivationResultImpl(optimizationResult, optimizationResult)
- );
-
- return new PostPerimeterResult(optimizationResult, new PrePerimeterSensitivityResultImpl(
- flowResult.get(),
- sensitivityResult.get(),
- RangeActionSetpointResultImpl.buildWithSetpointsFromNetwork(network, rangeActions),
- objectiveFunctionResult
- ));
+ return new PostPerimeterResult(optimizationResult,
+ new PrePerimeterSensitivityResultImpl(
+ flowResult.get(),
+ sensitivityResult.get(),
+ RangeActionSetpointResultImpl.buildWithSetpointsFromNetwork(network,
+ rangeActions),
+ objectiveFunctionResult
+ ));
+ });
}
/**
*
* Asynchronously runs a post-perimeter computation
- *
- * If a remedial action was taken, it performs a sensitivity analysis.
- * Otherwise, it waits and retrieves the pre-perimeter results from the {@code previousResultsFuture}.
- * After computations, the objective function is evaluated and a {@link PostPerimeterResult} is constructed and returned.
+ *
+ * If a remedial action was taken, it performs a sensitivity analysis. Otherwise, it waits and
+ * retrieves the pre-perimeter results from the {@code previousResultsFuture}. After
+ * computations, the objective function is evaluated and a {@link PostPerimeterResult} is
+ * constructed and returned.
*
*
- * @param network the network instance on which computations are performed
+ * @param network the network instance on which computations are
+ * performed
* @param initialFlowResult the initial flow result
- * @param previousResultsFuture a future providing the results of the previous perimeter
+ * @param previousResultsFuture a future providing the results of the previous
+ * perimeter
* @param operatorsNotSharingCras the set of operators not sharing CRAs
- * @param remedialActionActivationResult the set of remedial actions that were activated in the previous perimeter
+ * @param remedialActionActivationResult the set of remedial actions that were activated in the
+ * previous perimeter
* @param appliedCurativeRemedialActions the applied curative remedial actions for 2P
* @return a {@code Future}
*/
- public CompletableFuture runAsyncBasedOnInitialPreviousAndActivatedRa(Network network,
- FlowResult initialFlowResult,
- CompletableFuture previousResultsFuture,
- Set operatorsNotSharingCras,
- RemedialActionActivationResult remedialActionActivationResult,
- AppliedRemedialActions appliedCurativeRemedialActions) {
+ public CompletableFuture runAsyncBasedOnInitialPreviousAndActivatedRa(
+ Network network,
+ FlowResult initialFlowResult,
+ CompletableFuture previousResultsFuture,
+ Set operatorsNotSharingCras,
+ RemedialActionActivationResult remedialActionActivationResult,
+ AppliedRemedialActions appliedCurativeRemedialActions) {
return CompletableFuture.supplyAsync(() -> {
AtomicReference flowResult = new AtomicReference<>();
AtomicReference sensitivityResult = new AtomicReference<>();
- boolean actionWasTaken = actionWasTaken(remedialActionActivationResult.getActivatedNetworkActions(), remedialActionActivationResult.getActivatedRangeActionsPerState());
+ boolean actionWasTaken = actionWasTaken(
+ remedialActionActivationResult.getActivatedNetworkActions(),
+ remedialActionActivationResult.getActivatedRangeActionsPerState());
if (actionWasTaken) {
- SensitivityComputer sensitivityComputer = buildSensitivityComputer(initialFlowResult, appliedCurativeRemedialActions);
+ SensitivityComputer sensitivityComputer = buildSensitivityComputer(
+ initialFlowResult, appliedCurativeRemedialActions);
int oldThreadCount = setNewThreadCountAndGetOldValue();
sensitivityComputer.compute(network);
@@ -179,18 +206,23 @@ public CompletableFuture runAsyncBasedOnInitialPreviousAndA
flowResult.get(),
remedialActionActivationResult
);
- OptimizationResult optimizationResult = new OptimizationResultImpl(objectiveFunctionResult, flowResult.get(), sensitivityResult.get(), remedialActionActivationResult, remedialActionActivationResult);
-
- return new PostPerimeterResult(optimizationResult, new PrePerimeterSensitivityResultImpl(
- flowResult.get(),
- sensitivityResult.get(),
- RangeActionSetpointResultImpl.buildWithSetpointsFromNetwork(network, rangeActions),
- objectiveFunctionResult
- ));
+ OptimizationResult optimizationResult = new OptimizationResultImpl(
+ objectiveFunctionResult, flowResult.get(), sensitivityResult.get(),
+ remedialActionActivationResult, remedialActionActivationResult);
+
+ return new PostPerimeterResult(optimizationResult,
+ new PrePerimeterSensitivityResultImpl(
+ flowResult.get(),
+ sensitivityResult.get(),
+ RangeActionSetpointResultImpl.buildWithSetpointsFromNetwork(network,
+ rangeActions),
+ objectiveFunctionResult
+ ));
});
}
- private boolean actionWasTaken(Set activatedNetworkActions, Map>> activatedRangeActionsPerState) {
+ private boolean actionWasTaken(Set activatedNetworkActions,
+ Map>> activatedRangeActionsPerState) {
if (!activatedNetworkActions.isEmpty()) {
return true;
}
diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/castor/algorithm/PrePerimeterSensitivityAnalysis.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/castor/algorithm/PrePerimeterSensitivityAnalysis.java
index 6daa29c207..19bcb47597 100644
--- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/castor/algorithm/PrePerimeterSensitivityAnalysis.java
+++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/castor/algorithm/PrePerimeterSensitivityAnalysis.java
@@ -7,27 +7,31 @@
package com.powsybl.openrao.searchtreerao.castor.algorithm;
+import com.powsybl.iidm.network.Network;
+import com.powsybl.openrao.commons.opentelemetry.OpenTelemetryReporter;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.api.State;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.openrao.data.crac.api.rangeaction.RangeAction;
import com.powsybl.openrao.raoapi.parameters.RaoParameters;
-import com.powsybl.openrao.searchtreerao.result.api.*;
-import com.powsybl.openrao.searchtreerao.result.impl.PrePerimeterSensitivityResultImpl;
import com.powsybl.openrao.searchtreerao.commons.SensitivityComputer;
import com.powsybl.openrao.searchtreerao.commons.ToolProvider;
import com.powsybl.openrao.searchtreerao.commons.objectivefunction.ObjectiveFunction;
+import com.powsybl.openrao.searchtreerao.result.api.FlowResult;
+import com.powsybl.openrao.searchtreerao.result.api.ObjectiveFunctionResult;
+import com.powsybl.openrao.searchtreerao.result.api.PrePerimeterResult;
+import com.powsybl.openrao.searchtreerao.result.api.RangeActionSetpointResult;
+import com.powsybl.openrao.searchtreerao.result.api.SensitivityResult;
+import com.powsybl.openrao.searchtreerao.result.impl.PrePerimeterSensitivityResultImpl;
import com.powsybl.openrao.searchtreerao.result.impl.RangeActionSetpointResultImpl;
import com.powsybl.openrao.searchtreerao.result.impl.RemedialActionActivationResultImpl;
import com.powsybl.openrao.sensitivityanalysis.AppliedRemedialActions;
-import com.powsybl.iidm.network.Network;
-
import java.util.Set;
/**
- * This class aims at performing the sensitivity analysis before the optimization of a perimeter. At these specific
- * instants we actually want to compute all the results on the network. They will be useful either for the optimization
- * or to fill results in the final output.
+ * This class aims at performing the sensitivity analysis before the optimization of a perimeter. At
+ * these specific instants we actually want to compute all the results on the network. They will be
+ * useful either for the optimization or to fill results in the final output.
*
* @author Baptiste Seguinot {@literal }
*/
@@ -38,41 +42,57 @@ public class PrePerimeterSensitivityAnalysis extends AbstractMultiPerimeterSensi
private ObjectiveFunction objectiveFunction;
public PrePerimeterSensitivityAnalysis(Crac crac,
- Set flowCnecs,
- Set> rangeActions,
- RaoParameters raoParameters,
- ToolProvider toolProvider,
- boolean multiThreadedSensitivities) {
- super(crac, flowCnecs, rangeActions, raoParameters, toolProvider, multiThreadedSensitivities);
+ Set flowCnecs,
+ Set> rangeActions,
+ RaoParameters raoParameters,
+ ToolProvider toolProvider,
+ boolean multiThreadedSensitivities) {
+ super(crac, flowCnecs, rangeActions, raoParameters, toolProvider,
+ multiThreadedSensitivities);
}
public PrePerimeterResult runInitialSensitivityAnalysis(Network network) {
- return runInitialSensitivityAnalysis(network, Set.of());
+ return OpenTelemetryReporter.withSpan("rao.runInitialSensitivityAnalysis", cx -> {
+ return runInitialSensitivityAnalysis(network, Set.of());
+ });
}
- public PrePerimeterResult runInitialSensitivityAnalysis(Network network, Set optimizedStates) {
- SensitivityComputer.SensitivityComputerBuilder sensitivityComputerBuilder = buildSensiBuilder()
- .withOutageInstant(crac.getOutageInstant());
- if (raoParameters.getLoopFlowParameters().isPresent()) {
- sensitivityComputerBuilder.withCommercialFlowsResults(toolProvider.getLoopFlowComputation(), toolProvider.getLoopFlowCnecs(flowCnecs));
- }
- if (raoParameters.getObjectiveFunctionParameters().getType().relativePositiveMargins()) {
- sensitivityComputerBuilder.withPtdfsResults(toolProvider.getAbsolutePtdfSumsComputation(), flowCnecs);
- }
-
- sensitivityComputer = sensitivityComputerBuilder.build();
- objectiveFunction = ObjectiveFunction.buildForInitialSensitivityComputation(flowCnecs, raoParameters, optimizedStates);
-
- return runAndGetResult(network, objectiveFunction);
+ public PrePerimeterResult runInitialSensitivityAnalysis(Network network,
+ Set optimizedStates) {
+ return OpenTelemetryReporter.withSpan("rao.runSensitivityAnalysisBasedOnInitialResults",
+ cx -> {
+ SensitivityComputer.SensitivityComputerBuilder sensitivityComputerBuilder = buildSensiBuilder()
+ .withOutageInstant(crac.getOutageInstant());
+ if (raoParameters.getLoopFlowParameters().isPresent()) {
+ sensitivityComputerBuilder.withCommercialFlowsResults(
+ toolProvider.getLoopFlowComputation(),
+ toolProvider.getLoopFlowCnecs(flowCnecs));
+ }
+ if (raoParameters.getObjectiveFunctionParameters().getType()
+ .relativePositiveMargins()) {
+ sensitivityComputerBuilder.withPtdfsResults(
+ toolProvider.getAbsolutePtdfSumsComputation(), flowCnecs);
+ }
+
+ sensitivityComputer = sensitivityComputerBuilder.build();
+ objectiveFunction = ObjectiveFunction.buildForInitialSensitivityComputation(
+ flowCnecs,
+ raoParameters, optimizedStates);
+
+ return runAndGetResult(network, objectiveFunction);
+ });
}
public PrePerimeterResult runBasedOnInitialResults(Network network,
- FlowResult initialFlowResult,
- Set operatorsNotSharingCras,
- AppliedRemedialActions appliedCurativeRemedialActions) {
+ FlowResult initialFlowResult,
+ Set operatorsNotSharingCras,
+ AppliedRemedialActions appliedCurativeRemedialActions) {
- sensitivityComputer = buildSensitivityComputer(initialFlowResult, appliedCurativeRemedialActions);
- objectiveFunction = ObjectiveFunction.build(flowCnecs, toolProvider.getLoopFlowCnecs(flowCnecs), initialFlowResult, initialFlowResult, operatorsNotSharingCras, raoParameters, Set.of(crac.getPreventiveState()));
+ sensitivityComputer = buildSensitivityComputer(initialFlowResult,
+ appliedCurativeRemedialActions);
+ objectiveFunction = ObjectiveFunction.build(flowCnecs,
+ toolProvider.getLoopFlowCnecs(flowCnecs), initialFlowResult, initialFlowResult,
+ operatorsNotSharingCras, raoParameters, Set.of(crac.getPreventiveState()));
return runAndGetResult(network, objectiveFunction);
}
@@ -83,24 +103,27 @@ public ObjectiveFunction getObjectiveFunction() {
private SensitivityComputer.SensitivityComputerBuilder buildSensiBuilder() {
return SensitivityComputer.create()
- .withToolProvider(toolProvider)
- .withCnecs(flowCnecs)
- .withRangeActions(rangeActions);
+ .withToolProvider(toolProvider)
+ .withCnecs(flowCnecs)
+ .withRangeActions(rangeActions);
}
- private PrePerimeterResult runAndGetResult(Network network, ObjectiveFunction objectiveFunction) {
+ private PrePerimeterResult runAndGetResult(Network network,
+ ObjectiveFunction objectiveFunction) {
int oldThreadCount = setNewThreadCountAndGetOldValue();
sensitivityComputer.compute(network);
resetThreadCount(oldThreadCount);
FlowResult flowResult = sensitivityComputer.getBranchResult(network);
SensitivityResult sensitivityResult = sensitivityComputer.getSensitivityResult();
- RangeActionSetpointResult rangeActionSetpointResult = RangeActionSetpointResultImpl.buildWithSetpointsFromNetwork(network, rangeActions);
- ObjectiveFunctionResult objectiveFunctionResult = objectiveFunction.evaluate(flowResult, RemedialActionActivationResultImpl.empty(rangeActionSetpointResult));
+ RangeActionSetpointResult rangeActionSetpointResult = RangeActionSetpointResultImpl.buildWithSetpointsFromNetwork(
+ network, rangeActions);
+ ObjectiveFunctionResult objectiveFunctionResult = objectiveFunction.evaluate(flowResult,
+ RemedialActionActivationResultImpl.empty(rangeActionSetpointResult));
return new PrePerimeterSensitivityResultImpl(
- flowResult,
- sensitivityResult,
- rangeActionSetpointResult,
- objectiveFunctionResult
+ flowResult,
+ sensitivityResult,
+ rangeActionSetpointResult,
+ objectiveFunctionResult
);
}
}
diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/castor/algorithm/pstregulation/CastorPstRegulation.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/castor/algorithm/pstregulation/CastorPstRegulation.java
index caf17327d9..7be5fb7e09 100644
--- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/castor/algorithm/pstregulation/CastorPstRegulation.java
+++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/castor/algorithm/pstregulation/CastorPstRegulation.java
@@ -7,12 +7,18 @@
package com.powsybl.openrao.searchtreerao.castor.algorithm.pstregulation;
+import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.BUSINESS_LOGS;
+import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.BUSINESS_WARNS;
+import static com.powsybl.openrao.raoapi.parameters.extensions.MultithreadingParameters.getAvailableCPUs;
+import static com.powsybl.openrao.searchtreerao.commons.RaoUtil.getFlowUnit;
+
import com.powsybl.contingency.Contingency;
import com.powsybl.iidm.network.Network;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.Unit;
+import com.powsybl.openrao.commons.opentelemetry.OpenTelemetryReporter;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.api.Identifiable;
import com.powsybl.openrao.data.crac.api.Instant;
@@ -26,7 +32,6 @@
import com.powsybl.openrao.searchtreerao.result.impl.PostPerimeterResult;
import com.powsybl.openrao.searchtreerao.result.impl.SkippedOptimizationResultImpl;
import com.powsybl.openrao.util.AbstractNetworkPool;
-
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
@@ -40,34 +45,42 @@
import java.util.function.Function;
import java.util.stream.Collectors;
-import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.BUSINESS_LOGS;
-import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.BUSINESS_WARNS;
-import static com.powsybl.openrao.raoapi.parameters.extensions.MultithreadingParameters.getAvailableCPUs;
-import static com.powsybl.openrao.searchtreerao.commons.RaoUtil.getFlowUnit;
-
/**
* @author Thomas Bouquet {@literal }
*/
public final class CastorPstRegulation {
+
private CastorPstRegulation() {
}
- public static Set regulatePsts(Map pstsToRegulate, Map postContingencyResults, Network network, Crac crac, RaoParameters raoParameters, RaoResult raoResult) {
+ public static Set regulatePsts(Map pstsToRegulate,
+ Map postContingencyResults, Network network, Crac crac,
+ RaoParameters raoParameters, RaoResult raoResult) {
// filter out non-curative PSTs
// currently, only PSTs with a usage rule for a given state are regulated
- Set rangeActionsToRegulate = getPstRangeActionsForRegulation(pstsToRegulate.keySet(), crac);
+ Set rangeActionsToRegulate = getPstRangeActionsForRegulation(
+ pstsToRegulate.keySet(), crac);
if (rangeActionsToRegulate.isEmpty()) {
return Set.of();
}
- Set statesToRegulate = getStatesToRegulate(crac, postContingencyResults, getFlowUnit(raoParameters), rangeActionsToRegulate, SearchTreeRaoPstRegulationParameters.getPstsToRegulate(raoParameters), network);
+ Set statesToRegulate = getStatesToRegulate(crac, postContingencyResults,
+ getFlowUnit(raoParameters), rangeActionsToRegulate,
+ SearchTreeRaoPstRegulationParameters.getPstsToRegulate(raoParameters), network);
if (statesToRegulate.isEmpty()) {
return Set.of();
}
- Set contingencies = statesToRegulate.stream().map(PstRegulationInput::curativeState).map(State::getContingency).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toSet());
- BUSINESS_LOGS.info("{} contingency scenario(s) to regulate: {}", contingencies.size(), String.join(", ", contingencies.stream().map(contingency -> contingency.getName().orElse(contingency.getId())).sorted().toList()));
- BUSINESS_LOGS.info("{} PST(s) to regulate: {}", rangeActionsToRegulate.size(), String.join(", ", rangeActionsToRegulate.stream().map(PstRangeAction::getName).sorted().toList()));
+ Set contingencies = statesToRegulate.stream()
+ .map(PstRegulationInput::curativeState).map(State::getContingency)
+ .filter(Optional::isPresent).map(Optional::get).collect(Collectors.toSet());
+ BUSINESS_LOGS.info("{} contingency scenario(s) to regulate: {}", contingencies.size(),
+ String.join(", ", contingencies.stream()
+ .map(contingency -> contingency.getName().orElse(contingency.getId())).sorted()
+ .toList()));
+ BUSINESS_LOGS.info("{} PST(s) to regulate: {}", rangeActionsToRegulate.size(),
+ String.join(", ",
+ rangeActionsToRegulate.stream().map(PstRangeAction::getName).sorted().toList()));
// update loadflow parameters
LoadFlowParameters loadFlowParameters = getLoadFlowParameters(raoParameters);
@@ -78,27 +91,36 @@ public static Set regulatePsts(Map pstsToRe
applyOptimalRemedialActionsForState(network, raoResult, crac.getPreventiveState());
// regulate PSTs for each curative scenario in parallel
- try (AbstractNetworkPool networkPool = AbstractNetworkPool.create(network, network.getVariantManager().getWorkingVariantId(), getNumberOfThreads(crac, raoParameters), true)) {
- List> tasks = statesToRegulate.stream().map(pstRegulationInput ->
- networkPool.submit(() -> regulatePstsForContingencyScenario(pstRegulationInput, crac, rangeActionsToRegulate, raoResult, loadFlowParameters, networkPool))
- ).toList();
- Set pstRegulationResults = new HashSet<>();
- for (ForkJoinTask task : tasks) {
- try {
- pstRegulationResults.add(task.get());
- } catch (ExecutionException e) {
- throw new OpenRaoException(e);
+ return OpenTelemetryReporter.withSpan("rao.regulatePstsParallel", cx -> {
+ try (AbstractNetworkPool networkPool = AbstractNetworkPool.create(network,
+ network.getVariantManager().getWorkingVariantId(),
+ getNumberOfThreads(crac, raoParameters), true)) {
+ List> tasks = statesToRegulate.stream()
+ .map(pstRegulationInput ->
+ networkPool.submit(
+ () -> regulatePstsForContingencyScenario(pstRegulationInput, crac,
+ rangeActionsToRegulate, raoResult, loadFlowParameters, networkPool))
+ ).toList();
+ Set pstRegulationResults = new HashSet<>();
+ for (ForkJoinTask task : tasks) {
+ try {
+ pstRegulationResults.add(task.get());
+ } catch (ExecutionException e) {
+ throw new OpenRaoException(e);
+ }
}
+ networkPool.shutdownAndAwaitTermination(1000, TimeUnit.SECONDS);
+ return pstRegulationResults;
+ } catch (Exception e) {
+ Thread.currentThread().interrupt();
+ BUSINESS_WARNS.warn(
+ "An error occurred during PST regulation, pre-regulation RAO result will be kept.");
+ return Set.of();
+ } finally {
+ loadFlowParameters.setPhaseShifterRegulationOn(
+ initialPhaseShifterRegulationOnValue);
}
- networkPool.shutdownAndAwaitTermination(1000, TimeUnit.SECONDS);
- return pstRegulationResults;
- } catch (Exception e) {
- Thread.currentThread().interrupt();
- BUSINESS_WARNS.warn("An error occurred during PST regulation, pre-regulation RAO result will be kept.");
- return Set.of();
- } finally {
- loadFlowParameters.setPhaseShifterRegulationOn(initialPhaseShifterRegulationOnValue);
- }
+ });
}
/**
@@ -109,37 +131,55 @@ public static Set regulatePsts(Map pstsToRe
*
* For all such states, the associated PST regulation input is included in a set that is returned.
*/
- private static Set getStatesToRegulate(Crac crac, Map postContingencyResults, Unit unit, Set rangeActionsToRegulate, Map linesInSeriesWithPst, Network network) {
+ private static Set getStatesToRegulate(Crac crac,
+ Map postContingencyResults, Unit unit,
+ Set rangeActionsToRegulate, Map linesInSeriesWithPst,
+ Network network) {
Instant lastInstant = crac.getLastInstant();
return lastInstant.isCurative() ?
crac.getStates(lastInstant).stream()
.filter(postContingencyResults::containsKey)
- .filter(curativeState -> !(postContingencyResults.get(curativeState).optimizationResult() instanceof SkippedOptimizationResultImpl))
- .map(curativeState -> getPstRegulationInput(curativeState, crac, postContingencyResults.get(curativeState), unit, rangeActionsToRegulate, linesInSeriesWithPst, network))
+ .filter(curativeState -> !(postContingencyResults.get(curativeState)
+ .optimizationResult() instanceof SkippedOptimizationResultImpl))
+ .map(curativeState -> getPstRegulationInput(curativeState, crac,
+ postContingencyResults.get(curativeState), unit, rangeActionsToRegulate,
+ linesInSeriesWithPst, network))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toSet())
: Set.of();
}
- private static Optional getPstRegulationInput(State curativeState, Crac crac, PostPerimeterResult postPerimeterResult, Unit unit, Set rangeActionsToRegulate, Map linesInSeriesWithPst, Network network) {
- Optional limitingElement = getMostLimitingElementProtectedByPst(curativeState, crac, postPerimeterResult, unit, new HashSet<>(linesInSeriesWithPst.values()));
+ private static Optional getPstRegulationInput(State curativeState,
+ Crac crac, PostPerimeterResult postPerimeterResult, Unit unit,
+ Set rangeActionsToRegulate, Map linesInSeriesWithPst,
+ Network network) {
+ Optional limitingElement = getMostLimitingElementProtectedByPst(curativeState,
+ crac, postPerimeterResult, unit, new HashSet<>(linesInSeriesWithPst.values()));
if (limitingElement.isPresent()) {
Set elementaryPstRegulationInputs = rangeActionsToRegulate.stream()
- .filter(pstRangeAction -> linesInSeriesWithPst.containsKey(pstRangeAction.getNetworkElement().getId()))
- .map(pstRangeAction -> ElementaryPstRegulationInput.of(pstRangeAction, linesInSeriesWithPst.get(pstRangeAction.getNetworkElement().getId()), curativeState, crac, network))
+ .filter(pstRangeAction -> linesInSeriesWithPst.containsKey(
+ pstRangeAction.getNetworkElement().getId()))
+ .map(pstRangeAction -> ElementaryPstRegulationInput.of(pstRangeAction,
+ linesInSeriesWithPst.get(pstRangeAction.getNetworkElement().getId()),
+ curativeState, crac, network))
.collect(Collectors.toSet());
- return Optional.of(new PstRegulationInput(curativeState, limitingElement.get(), elementaryPstRegulationInputs));
+ return Optional.of(new PstRegulationInput(curativeState, limitingElement.get(),
+ elementaryPstRegulationInputs));
}
return Optional.empty();
}
/**
- * If the most limiting element of a curative state is overloaded and is in series with a PST, it is returned.
- * If not, an empty optional value is returned instead.
+ * If the most limiting element of a curative state is overloaded and is in series with a PST,
+ * it is returned. If not, an empty optional value is returned instead.
*/
- private static Optional getMostLimitingElementProtectedByPst(State curativeState, Crac crac, PostPerimeterResult postPerimeterResult, Unit unit, Set linesInSeriesWithPst) {
- Map marginPerCnec = crac.getFlowCnecs(curativeState).stream().collect(Collectors.toMap(Function.identity(), flowCnec -> postPerimeterResult.optimizationResult().getMargin(flowCnec, unit)));
+ private static Optional getMostLimitingElementProtectedByPst(State curativeState,
+ Crac crac, PostPerimeterResult postPerimeterResult, Unit unit,
+ Set linesInSeriesWithPst) {
+ Map marginPerCnec = crac.getFlowCnecs(curativeState).stream().collect(
+ Collectors.toMap(Function.identity(),
+ flowCnec -> postPerimeterResult.optimizationResult().getMargin(flowCnec, unit)));
List> sortedNegativeMargins = marginPerCnec.entrySet().stream()
.filter(entry -> entry.getValue() < 0)
.sorted(Map.Entry.comparingByValue()).toList();
@@ -148,49 +188,67 @@ private static Optional getMostLimitingElementProtectedByPst(State cur
}
double minMargin = sortedNegativeMargins.get(0).getValue();
Set limitingElements = new HashSet<>();
- sortedNegativeMargins.stream().filter(entry -> entry.getValue() == minMargin).forEach(entry -> limitingElements.add(entry.getKey()));
+ sortedNegativeMargins.stream().filter(entry -> entry.getValue() == minMargin)
+ .forEach(entry -> limitingElements.add(entry.getKey()));
return limitingElements.stream()
.filter(flowCnec -> linesInSeriesWithPst.contains(flowCnec.getNetworkElement().getId()))
.min(Comparator.comparing(Identifiable::getId));
}
private static LoadFlowParameters getLoadFlowParameters(RaoParameters raoParameters) {
- return raoParameters.hasExtension(OpenRaoSearchTreeParameters.class) ? raoParameters.getExtension(OpenRaoSearchTreeParameters.class).getLoadFlowAndSensitivityParameters().getSensitivityWithLoadFlowParameters().getLoadFlowParameters() : new LoadFlowParameters();
+ return raoParameters.hasExtension(OpenRaoSearchTreeParameters.class)
+ ? raoParameters.getExtension(OpenRaoSearchTreeParameters.class)
+ .getLoadFlowAndSensitivityParameters().getSensitivityWithLoadFlowParameters()
+ .getLoadFlowParameters() : new LoadFlowParameters();
}
- private static void updateLoadFlowParametersForPstRegulation(LoadFlowParameters loadFlowParameters) {
+ private static void updateLoadFlowParametersForPstRegulation(
+ LoadFlowParameters loadFlowParameters) {
loadFlowParameters.setPhaseShifterRegulationOn(true);
if (loadFlowParameters.getExtension(OpenLoadFlowParameters.class) == null) {
- loadFlowParameters.addExtension(OpenLoadFlowParameters.class, new OpenLoadFlowParameters());
+ loadFlowParameters.addExtension(OpenLoadFlowParameters.class,
+ new OpenLoadFlowParameters());
}
- loadFlowParameters.getExtension(OpenLoadFlowParameters.class).setMaxOuterLoopIterations(1000);
+ loadFlowParameters.getExtension(OpenLoadFlowParameters.class)
+ .setMaxOuterLoopIterations(1000);
}
- private static void applyOptimalRemedialActionsForState(Network networkClone, RaoResult raoResult, State state) {
+ private static void applyOptimalRemedialActionsForState(Network networkClone,
+ RaoResult raoResult, State state) {
// network actions need to be applied BEFORE range actions because to apply HVDC range actions we need to apply AC emulation deactivation network actions beforehand
- raoResult.getActivatedNetworkActionsDuringState(state).forEach(networkAction -> networkAction.apply(networkClone));
- raoResult.getActivatedRangeActionsDuringState(state).forEach(rangeAction -> rangeAction.apply(networkClone, raoResult.getOptimizedSetPointOnState(state, rangeAction)));
+ raoResult.getActivatedNetworkActionsDuringState(state)
+ .forEach(networkAction -> networkAction.apply(networkClone));
+ raoResult.getActivatedRangeActionsDuringState(state).forEach(
+ rangeAction -> rangeAction.apply(networkClone,
+ raoResult.getOptimizedSetPointOnState(state, rangeAction)));
}
- private static Set getPstRangeActionsForRegulation(Set pstsToRegulate, Crac crac) {
+ private static Set getPstRangeActionsForRegulation(Set pstsToRegulate,
+ Crac crac) {
Map rangeActionPerPst = getRangeActionPerPst(pstsToRegulate, crac);
Set rangeActionsToRegulate = new HashSet<>();
for (String pstId : pstsToRegulate) {
if (rangeActionPerPst.containsKey(pstId)) {
rangeActionsToRegulate.add(rangeActionPerPst.get(pstId));
} else {
- BUSINESS_LOGS.info("PST {} cannot be regulated as no curative PST range action was defined for it.", pstId);
+ BUSINESS_LOGS.info(
+ "PST {} cannot be regulated as no curative PST range action was defined for it.",
+ pstId);
}
}
return rangeActionsToRegulate;
}
- private static Map getRangeActionPerPst(Set pstsToRegulate, Crac crac) {
+ private static Map getRangeActionPerPst(Set pstsToRegulate,
+ Crac crac) {
// filter out crac's last instant range actions, as results reporting would be less relevant
return crac.getPstRangeActions().stream()
- .filter(pstRangeAction -> pstRangeAction.getUsageRules().stream().anyMatch(usageRule -> usageRule.getInstant() == crac.getLastInstant()))
- .filter(pstRangeAction -> pstsToRegulate.contains(pstRangeAction.getNetworkElement().getId()))
- .collect(Collectors.toMap(pstRangeAction -> pstRangeAction.getNetworkElement().getId(), Function.identity()));
+ .filter(pstRangeAction -> pstRangeAction.getUsageRules().stream()
+ .anyMatch(usageRule -> usageRule.getInstant() == crac.getLastInstant()))
+ .filter(pstRangeAction -> pstsToRegulate.contains(
+ pstRangeAction.getNetworkElement().getId()))
+ .collect(Collectors.toMap(pstRangeAction -> pstRangeAction.getNetworkElement().getId(),
+ Function.identity()));
}
private static int getNumberOfThreads(Crac crac, RaoParameters raoParameters) {
@@ -198,20 +256,29 @@ private static int getNumberOfThreads(Crac crac, RaoParameters raoParameters) {
}
/**
- * Performs PST regulation for a curative state. The taps are changed during the loadflow iterations.
+ * Performs PST regulation for a curative state. The taps are changed during the loadflow
+ * iterations.
*/
- private static PstRegulationResult regulatePstsForContingencyScenario(PstRegulationInput pstRegulationInput, Crac crac, Set rangeActionsToRegulate, RaoResult raoResult, LoadFlowParameters loadFlowParameters, AbstractNetworkPool networkPool) throws InterruptedException {
+ private static PstRegulationResult regulatePstsForContingencyScenario(
+ PstRegulationInput pstRegulationInput, Crac crac,
+ Set rangeActionsToRegulate, RaoResult raoResult,
+ LoadFlowParameters loadFlowParameters, AbstractNetworkPool networkPool)
+ throws InterruptedException {
Network networkClone = networkPool.getAvailableNetwork();
Contingency contingency = pstRegulationInput.curativeState().getContingency().orElseThrow();
simulateContingencyAndApplyCurativeActions(contingency, networkClone, crac, raoResult);
- Map initialTapPerPst = getInitialTapPerPst(rangeActionsToRegulate, networkClone);
- Map regulatedTapPerPst = PstRegulator.regulatePsts(pstRegulationInput.elementaryPstRegulationInputs(), networkClone, loadFlowParameters);
- logPstRegulationResultsForContingencyScenario(contingency, initialTapPerPst, regulatedTapPerPst, pstRegulationInput.limitingElement());
+ Map initialTapPerPst = getInitialTapPerPst(rangeActionsToRegulate,
+ networkClone);
+ Map regulatedTapPerPst = PstRegulator.regulatePsts(
+ pstRegulationInput.elementaryPstRegulationInputs(), networkClone, loadFlowParameters);
+ logPstRegulationResultsForContingencyScenario(contingency, initialTapPerPst,
+ regulatedTapPerPst, pstRegulationInput.limitingElement());
networkPool.releaseUsedNetwork(networkClone);
return new PstRegulationResult(contingency, regulatedTapPerPst);
}
- private static void simulateContingencyAndApplyCurativeActions(Contingency contingency, Network networkClone, Crac crac, RaoResult raoResult) {
+ private static void simulateContingencyAndApplyCurativeActions(Contingency contingency,
+ Network networkClone, Crac crac, RaoResult raoResult) {
// simulate contingency
contingency.toModification().apply(networkClone);
@@ -221,28 +288,37 @@ private static void simulateContingencyAndApplyCurativeActions(Contingency conti
.forEach(state -> applyOptimalRemedialActionsForState(networkClone, raoResult, state));
}
- private static Map getInitialTapPerPst(Set rangeActionsToRegulate, Network networkClone) {
- return rangeActionsToRegulate.stream().collect(Collectors.toMap(Function.identity(), pstRangeAction -> networkClone.getTwoWindingsTransformer(pstRangeAction.getNetworkElement().getId()).getPhaseTapChanger().getTapPosition()));
+ private static Map getInitialTapPerPst(
+ Set rangeActionsToRegulate, Network networkClone) {
+ return rangeActionsToRegulate.stream().collect(Collectors.toMap(Function.identity(),
+ pstRangeAction -> networkClone.getTwoWindingsTransformer(
+ pstRangeAction.getNetworkElement().getId()).getPhaseTapChanger().getTapPosition()));
}
private static void logPstRegulationResultsForContingencyScenario(Contingency contingency,
- Map initialTapPerPst,
- Map regulatedTapPerPst,
- FlowCnec mostLimitingElement) {
- List sortedPstRangeActions = initialTapPerPst.keySet().stream().sorted(Comparator.comparing(PstRangeAction::getId)).toList();
+ Map initialTapPerPst,
+ Map regulatedTapPerPst,
+ FlowCnec mostLimitingElement) {
+ List sortedPstRangeActions = initialTapPerPst.keySet().stream()
+ .sorted(Comparator.comparing(PstRangeAction::getId)).toList();
List shiftDetails = new ArrayList<>();
sortedPstRangeActions.forEach(
pstRangeAction -> {
int initialTap = initialTapPerPst.get(pstRangeAction);
int regulatedTap = regulatedTapPerPst.get(pstRangeAction);
if (initialTap != regulatedTap) {
- shiftDetails.add("%s (%s -> %s)".formatted(pstRangeAction.getName(), initialTap, regulatedTap));
+ shiftDetails.add("%s (%s -> %s)".formatted(pstRangeAction.getName(), initialTap,
+ regulatedTap));
}
}
);
- String allShiftedPstsDetails = shiftDetails.isEmpty() ? "no PST shifted" : String.join(", ", shiftDetails);
+ String allShiftedPstsDetails =
+ shiftDetails.isEmpty() ? "no PST shifted" : String.join(", ", shiftDetails);
if (!shiftDetails.isEmpty()) {
- BUSINESS_LOGS.info("FlowCNEC '{}' of contingency scenario '{}' is overloaded and is the most limiting element, PST regulation has been triggered: {}", mostLimitingElement.getId(), contingency.getName().orElse(contingency.getId()), allShiftedPstsDetails);
+ BUSINESS_LOGS.info(
+ "FlowCNEC '{}' of contingency scenario '{}' is overloaded and is the most limiting element, PST regulation has been triggered: {}",
+ mostLimitingElement.getId(), contingency.getName().orElse(contingency.getId()),
+ allShiftedPstsDetails);
}
}
}
diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/RaoUtil.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/RaoUtil.java
index 6b350af3be..9d918628b4 100644
--- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/RaoUtil.java
+++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/RaoUtil.java
@@ -7,12 +7,20 @@
package com.powsybl.openrao.searchtreerao.commons;
+import static com.powsybl.openrao.raoapi.parameters.extensions.LoadFlowAndSensitivityParameters.getLoadFlowProvider;
+import static com.powsybl.openrao.raoapi.parameters.extensions.LoadFlowAndSensitivityParameters.getSensitivityWithLoadFlowParameters;
+import static com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoRangeActionsOptimizationParameters.getPstModel;
+import static com.powsybl.openrao.searchtreerao.commons.HvdcUtils.addNetworkActionAssociatedWithHvdcRangeAction;
+import static com.powsybl.openrao.searchtreerao.commons.HvdcUtils.updateHvdcRangeActionInitialSetpoint;
+import static java.lang.String.format;
+
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.iidm.network.extensions.HvdcAngleDroopActivePowerControl;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider;
+import com.powsybl.openrao.commons.opentelemetry.OpenTelemetryReporter;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.api.RemedialAction;
import com.powsybl.openrao.data.crac.api.State;
@@ -32,31 +40,30 @@
import com.powsybl.openrao.searchtreerao.commons.optimizationperimeters.OptimizationPerimeter;
import com.powsybl.openrao.searchtreerao.result.api.FlowResult;
import com.powsybl.openrao.searchtreerao.result.api.OptimizationResult;
-import org.apache.commons.lang3.tuple.Pair;
-
-import java.util.*;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
-
-import static com.powsybl.openrao.raoapi.parameters.extensions.LoadFlowAndSensitivityParameters.getLoadFlowProvider;
-import static com.powsybl.openrao.raoapi.parameters.extensions.LoadFlowAndSensitivityParameters.getSensitivityWithLoadFlowParameters;
-import static com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoRangeActionsOptimizationParameters.getPstModel;
-import static com.powsybl.openrao.searchtreerao.commons.HvdcUtils.addNetworkActionAssociatedWithHvdcRangeAction;
-import static com.powsybl.openrao.searchtreerao.commons.HvdcUtils.updateHvdcRangeActionInitialSetpoint;
-import static java.lang.String.format;
+import org.apache.commons.lang3.tuple.Pair;
/**
* @author Joris Mancini {@literal }
*/
public final class RaoUtil {
+
private RaoUtil() {
}
public static void initData(RaoInput raoInput, RaoParameters raoParameters) {
- checkParameters(raoParameters, raoInput);
- checkCnecsThresholdsUnit(raoParameters, raoInput);
- initNetwork(raoInput.getNetwork(), raoInput.getNetworkVariantId());
- updateHvdcRangeActionInitialSetpoint(raoInput.getCrac(), raoInput.getNetwork(), raoParameters);
- addNetworkActionAssociatedWithHvdcRangeAction(raoInput.getCrac(), raoInput.getNetwork());
+ OpenTelemetryReporter.withSpan("rao.initData", cx -> {
+ checkParameters(raoParameters, raoInput);
+ checkCnecsThresholdsUnit(raoParameters, raoInput);
+ initNetwork(raoInput.getNetwork(), raoInput.getNetworkVariantId());
+ updateHvdcRangeActionInitialSetpoint(raoInput.getCrac(), raoInput.getNetwork(),
+ raoParameters);
+ addNetworkActionAssociatedWithHvdcRangeAction(raoInput.getCrac(),
+ raoInput.getNetwork());
+ });
}
public static void initNetwork(Network network, String networkVariantId) {
@@ -69,21 +76,25 @@ public static void checkParameters(RaoParameters raoParameters, RaoInput raoInpu
checkHvdcAcEmulationParameters(raoParameters, raoInput);
if (!PstModel.APPROXIMATED_INTEGERS.equals(getPstModel(raoParameters))
- && raoInput.getCrac().getRaUsageLimitsPerInstant().values().stream().anyMatch(raUsageLimits -> !raUsageLimits.getMaxElementaryActionsPerTso().isEmpty())) {
+ && raoInput.getCrac().getRaUsageLimitsPerInstant().values().stream()
+ .anyMatch(raUsageLimits -> !raUsageLimits.getMaxElementaryActionsPerTso().isEmpty())) {
String msg = "The PSTs must be approximated as integers to use the limitations of elementary actions as a constraint in the RAO.";
OpenRaoLoggerProvider.BUSINESS_LOGS.error(msg);
throw new OpenRaoException(msg);
}
}
- public static void checkHvdcAcEmulationParameters(RaoParameters raoParameters, RaoInput raoInput) {
+ public static void checkHvdcAcEmulationParameters(RaoParameters raoParameters,
+ RaoInput raoInput) {
boolean isAnyHvdcInAcEmulation = raoInput.getNetwork().getHvdcLineStream()
.anyMatch(hvdcLine -> {
- HvdcAngleDroopActivePowerControl extension = hvdcLine.getExtension(HvdcAngleDroopActivePowerControl.class);
+ HvdcAngleDroopActivePowerControl extension = hvdcLine.getExtension(
+ HvdcAngleDroopActivePowerControl.class);
return extension != null && extension.isEnabled();
});
- if (!getSensitivityWithLoadFlowParameters(raoParameters).getLoadFlowParameters().isHvdcAcEmulation() && isAnyHvdcInAcEmulation) {
+ if (!getSensitivityWithLoadFlowParameters(raoParameters).getLoadFlowParameters()
+ .isHvdcAcEmulation() && isAnyHvdcInAcEmulation) {
String msg = "hvdcAcEmulation is not enabled but some HVDC lines are in AC emulation mode which will not be coherent.";
OpenRaoLoggerProvider.BUSINESS_LOGS.error(msg);
throw new OpenRaoException(msg);
@@ -94,11 +105,17 @@ private static void checkLoopFlowParameters(RaoParameters raoParameters, RaoInpu
if ((raoParameters.getLoopFlowParameters().isPresent()
|| raoParameters.getObjectiveFunctionParameters().getType().relativePositiveMargins())
&& (Objects.isNull(raoInput.getReferenceProgram()))) {
- OpenRaoLoggerProvider.BUSINESS_WARNS.warn("No ReferenceProgram provided. A ReferenceProgram will be generated using information in the network file.");
- raoInput.setReferenceProgram(ReferenceProgramBuilder.buildReferenceProgram(raoInput.getNetwork(), getLoadFlowProvider(raoParameters), getSensitivityWithLoadFlowParameters(raoParameters).getLoadFlowParameters()));
+ OpenRaoLoggerProvider.BUSINESS_WARNS.warn(
+ "No ReferenceProgram provided. A ReferenceProgram will be generated using information in the network file.");
+ raoInput.setReferenceProgram(
+ ReferenceProgramBuilder.buildReferenceProgram(raoInput.getNetwork(),
+ getLoadFlowProvider(raoParameters),
+ getSensitivityWithLoadFlowParameters(raoParameters).getLoadFlowParameters()));
}
- if (raoParameters.getLoopFlowParameters().isPresent() && (Objects.isNull(raoInput.getReferenceProgram()) || Objects.isNull(raoInput.getGlskProvider()))) {
+ if (raoParameters.getLoopFlowParameters().isPresent() && (
+ Objects.isNull(raoInput.getReferenceProgram()) || Objects.isNull(
+ raoInput.getGlskProvider()))) {
String msg = format(
"Loopflow computation cannot be performed on CRAC %s because it lacks a ReferenceProgram or a GlskProvider",
raoInput.getCrac().getId());
@@ -107,21 +124,31 @@ private static void checkLoopFlowParameters(RaoParameters raoParameters, RaoInpu
}
}
- private static void checkObjectiveFunctionParameters(RaoParameters raoParameters, RaoInput raoInput) {
+ private static void checkObjectiveFunctionParameters(RaoParameters raoParameters,
+ RaoInput raoInput) {
if (raoParameters.getObjectiveFunctionParameters().getType().relativePositiveMargins()) {
if (raoInput.getGlskProvider() == null) {
- throw new OpenRaoException(format("Objective function %s requires glsks", raoParameters.getObjectiveFunctionParameters().getType()));
+ throw new OpenRaoException(format("Objective function %s requires glsks",
+ raoParameters.getObjectiveFunctionParameters().getType()));
}
- if (raoParameters.getRelativeMarginsParameters().map(relativeMarginsParameters -> relativeMarginsParameters.getPtdfBoundaries().isEmpty()).orElse(true)) {
- throw new OpenRaoException(format("Objective function %s requires a config with a non empty boundary set", raoParameters.getObjectiveFunctionParameters().getType()));
+ if (raoParameters.getRelativeMarginsParameters().map(
+ relativeMarginsParameters -> relativeMarginsParameters.getPtdfBoundaries()
+ .isEmpty()).orElse(true)) {
+ throw new OpenRaoException(
+ format("Objective function %s requires a config with a non empty boundary set",
+ raoParameters.getObjectiveFunctionParameters().getType()));
}
}
if (raoParameters.getObjectiveFunctionParameters().getType().costOptimization() &&
(!raoParameters.hasExtension(OpenRaoSearchTreeParameters.class) ||
- raoParameters.hasExtension(OpenRaoSearchTreeParameters.class) && raoParameters.getExtension(OpenRaoSearchTreeParameters.class).getMinMarginsParameters().isEmpty())) {
- throw new OpenRaoException(format("Objective function type %s requires a config with costly min margin parameters", raoParameters.getObjectiveFunctionParameters().getType()));
+ raoParameters.hasExtension(OpenRaoSearchTreeParameters.class)
+ && raoParameters.getExtension(OpenRaoSearchTreeParameters.class)
+ .getMinMarginsParameters().isEmpty())) {
+ throw new OpenRaoException(format(
+ "Objective function type %s requires a config with costly min margin parameters",
+ raoParameters.getObjectiveFunctionParameters().getType()));
}
}
@@ -129,15 +156,19 @@ public static void checkCnecsThresholdsUnit(RaoParameters raoParameters, RaoInpu
Crac crac = raoInput.getCrac();
if (!getSensitivityWithLoadFlowParameters(raoParameters).getLoadFlowParameters().isDc()) {
crac.getFlowCnecs().forEach(flowCnec -> {
- if (flowCnec.getThresholds().stream().anyMatch(branchThreshold -> branchThreshold.getUnit().equals(Unit.MEGAWATT))) {
- String msg = format("A threshold for the flowCnec %s is defined in MW but the loadflow computation is in AC. It will be imprecisely converted by the RAO which could create uncoherent results due to side effects", flowCnec.getId());
+ if (flowCnec.getThresholds().stream()
+ .anyMatch(branchThreshold -> branchThreshold.getUnit().equals(Unit.MEGAWATT))) {
+ String msg = format(
+ "A threshold for the flowCnec %s is defined in MW but the loadflow computation is in AC. It will be imprecisely converted by the RAO which could create uncoherent results due to side effects",
+ flowCnec.getId());
OpenRaoLoggerProvider.BUSINESS_WARNS.warn(msg);
}
});
}
}
- public static double getFlowUnitMultiplier(FlowCnec cnec, TwoSides voltageSide, Unit unitFrom, Unit unitTo) {
+ public static double getFlowUnitMultiplier(FlowCnec cnec, TwoSides voltageSide, Unit unitFrom,
+ Unit unitTo) {
if (unitFrom == unitTo) {
return 1;
}
@@ -152,39 +183,55 @@ public static double getFlowUnitMultiplier(FlowCnec cnec, TwoSides voltageSide,
}
/**
- * Returns true if any flowCnec has a negative margin.
- * We need to know the unit of the objective function, because a negative margin in A can be positive in MW
- * given different approximations, and vice versa
+ * Returns true if any flowCnec has a negative margin. We need to know the unit of the objective
+ * function, because a negative margin in A can be positive in MW given different
+ * approximations, and vice versa
*/
- public static boolean isAnyMarginNegative(FlowResult flowResult, Set flowCnecs, Unit marginUnit) {
- return flowCnecs.stream().anyMatch(flowCnec -> flowResult.getMargin(flowCnec, marginUnit) <= 0);
+ public static boolean isAnyMarginNegative(FlowResult flowResult, Set flowCnecs,
+ Unit marginUnit) {
+ return flowCnecs.stream()
+ .anyMatch(flowCnec -> flowResult.getMargin(flowCnec, marginUnit) <= 0);
}
/**
- * Evaluates if a remedial action is available.
- * 1) The remedial action has no usage rule: it will not be available.
- * 2) It gathers all the remedial action usage rules and filters out the OnFlowConstraint(InCountry) with no negative margins on their associated cnecs.
- * If there are remaining usage rules, the remedial action is available.
+ * Evaluates if a remedial action is available. 1) The remedial action has no usage rule: it
+ * will not be available. 2) It gathers all the remedial action usage rules and filters out the
+ * OnFlowConstraint(InCountry) with no negative margins on their associated cnecs. If there are
+ * remaining usage rules, the remedial action is available.
*/
- public static boolean canRemedialActionBeUsed(RemedialAction> remedialAction, State state, FlowResult flowResult, Set flowCnecs, Network network, RaoParameters raoParameters) {
- return remedialAction.getUsageRules().stream().anyMatch(ur -> isUsageRuleActivated(ur, remedialAction, state, flowResult, flowCnecs, network, getFlowUnit(raoParameters)));
+ public static boolean canRemedialActionBeUsed(RemedialAction> remedialAction, State state,
+ FlowResult flowResult, Set flowCnecs, Network network,
+ RaoParameters raoParameters) {
+ return remedialAction.getUsageRules().stream().anyMatch(
+ ur -> isUsageRuleActivated(ur, remedialAction, state, flowResult, flowCnecs, network,
+ getFlowUnit(raoParameters)));
}
- private static boolean isUsageRuleActivated(UsageRule usageRule, RemedialAction> remedialAction, State state, FlowResult flowResult, Set flowCnecs, Network network, Unit unit) {
+ private static boolean isUsageRuleActivated(UsageRule usageRule,
+ RemedialAction> remedialAction, State state, FlowResult flowResult,
+ Set flowCnecs, Network network, Unit unit) {
if (usageRule instanceof OnInstant onInstant) {
return onInstant.getInstant().equals(state.getInstant());
} else if (usageRule instanceof OnContingencyState onContingencyState) {
return onContingencyState.getState().equals(state);
} else if (usageRule instanceof OnFlowConstraintInCountry onFlowConstraintInCountry) {
- if (onFlowConstraintInCountry.getContingency().isPresent() && !onFlowConstraintInCountry.getContingency().equals(state.getContingency())) {
+ if (onFlowConstraintInCountry.getContingency().isPresent()
+ && !onFlowConstraintInCountry.getContingency().equals(state.getContingency())) {
return false;
}
- return isAnyMarginNegative(flowResult, remedialAction.getFlowCnecsConstrainingForOneUsageRule(onFlowConstraintInCountry, flowCnecs, network), unit) && onFlowConstraintInCountry.getInstant().equals(state.getInstant());
- } else if (usageRule instanceof OnConstraint> onConstraint && onConstraint.getCnec() instanceof FlowCnec flowCnec) {
- if (!onConstraint.getInstant().isPreventive() && !flowCnec.getState().getContingency().equals(state.getContingency())) {
+ return isAnyMarginNegative(flowResult,
+ remedialAction.getFlowCnecsConstrainingForOneUsageRule(onFlowConstraintInCountry,
+ flowCnecs, network), unit) && onFlowConstraintInCountry.getInstant()
+ .equals(state.getInstant());
+ } else if (usageRule instanceof OnConstraint> onConstraint
+ && onConstraint.getCnec() instanceof FlowCnec flowCnec) {
+ if (!onConstraint.getInstant().isPreventive() && !flowCnec.getState().getContingency()
+ .equals(state.getContingency())) {
return false;
}
- return isAnyMarginNegative(flowResult, remedialAction.getFlowCnecsConstrainingForOneUsageRule(onConstraint, flowCnecs, network), unit) && onConstraint.getInstant().equals(state.getInstant());
+ return isAnyMarginNegative(flowResult,
+ remedialAction.getFlowCnecsConstrainingForOneUsageRule(onConstraint, flowCnecs,
+ network), unit) && onConstraint.getInstant().equals(state.getInstant());
} else {
return false;
}
@@ -194,7 +241,8 @@ private static boolean isUsageRuleActivated(UsageRule usageRule, RemedialAction<
* Returns the range action from optimizationContext that is available on the latest state
* strictly before the given state, and that acts on the same network element as rangeAction.
*/
- public static Pair, State> getLastAvailableRangeActionOnSameNetworkElement(OptimizationPerimeter optimizationContext, RangeAction> rangeAction, State state) {
+ public static Pair, State> getLastAvailableRangeActionOnSameNetworkElement(
+ OptimizationPerimeter optimizationContext, RangeAction> rangeAction, State state) {
if (state.isPreventive() || state.equals(optimizationContext.getMainOptimizationState())) {
// no previous instant
@@ -205,8 +253,10 @@ public static Pair, State> getLastAvailableRangeActionOnSameNetwo
State previousUsageState = optimizationContext.getMainOptimizationState();
if (previousUsageState.getInstant().comesBefore(state.getInstant())) {
- Optional> correspondingRa = optimizationContext.getRangeActionsPerState().get(previousUsageState).stream()
- .filter(ra -> ra.getId().equals(rangeAction.getId()) || ra.getNetworkElements().equals(rangeAction.getNetworkElements()))
+ Optional> correspondingRa = optimizationContext.getRangeActionsPerState()
+ .get(previousUsageState).stream()
+ .filter(ra -> ra.getId().equals(rangeAction.getId()) || ra.getNetworkElements()
+ .equals(rangeAction.getNetworkElements()))
.findAny();
if (correspondingRa.isPresent()) {
@@ -215,7 +265,8 @@ public static Pair, State> getLastAvailableRangeActionOnSameNetwo
}
return null;
} else {
- throw new OpenRaoException("Linear optimization does not handle range actions which are neither PREVENTIVE nor CURATIVE.");
+ throw new OpenRaoException(
+ "Linear optimization does not handle range actions which are neither PREVENTIVE nor CURATIVE.");
}
}
@@ -223,14 +274,19 @@ public static double getLargestCnecThreshold(Set flowCnecs, Unit unit)
return flowCnecs.stream().filter(Cnec::isOptimized)
.map(flowCnec ->
flowCnec.getMonitoredSides().stream().map(side ->
- Math.max(Math.abs(flowCnec.getUpperBound(side, unit).orElse(0.)), Math.abs(flowCnec.getLowerBound(side, unit).orElse(0.)))).max(Double::compare).orElse(0.))
+ Math.max(Math.abs(flowCnec.getUpperBound(side, unit).orElse(0.)),
+ Math.abs(flowCnec.getLowerBound(side, unit).orElse(0.))))
+ .max(Double::compare).orElse(0.))
.max(Double::compare)
.orElse(0.);
}
- public static void applyRemedialActions(Network network, OptimizationResult optResult, State state) {
- optResult.getActivatedNetworkActions().forEach(networkAction -> networkAction.apply(network));
- optResult.getActivatedRangeActions(state).forEach(rangeAction -> rangeAction.apply(network, optResult.getOptimizedSetpoint(rangeAction, state)));
+ public static void applyRemedialActions(Network network, OptimizationResult optResult,
+ State state) {
+ optResult.getActivatedNetworkActions()
+ .forEach(networkAction -> networkAction.apply(network));
+ optResult.getActivatedRangeActions(state).forEach(rangeAction -> rangeAction.apply(network,
+ optResult.getOptimizedSetpoint(rangeAction, state)));
}
public static Set getDuplicateCnecs(Set flowcnecs) {
@@ -242,7 +298,9 @@ public static Set getDuplicateCnecs(Set flowcnecs) {
// TODO: find a better place for this function
public static Unit getFlowUnit(RaoParameters raoParameters) {
- return getSensitivityWithLoadFlowParameters(raoParameters).getLoadFlowParameters().isDc() ? Unit.MEGAWATT : Unit.AMPERE;
+ return getSensitivityWithLoadFlowParameters(raoParameters).getLoadFlowParameters().isDc()
+ ? Unit.MEGAWATT : Unit.AMPERE;
}
}
+
diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/ToolProvider.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/ToolProvider.java
index fede621851..4402178f1a 100644
--- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/ToolProvider.java
+++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/ToolProvider.java
@@ -7,8 +7,19 @@
package com.powsybl.openrao.searchtreerao.commons;
-import com.powsybl.openrao.commons.*;
+import static com.powsybl.openrao.raoapi.parameters.extensions.LoadFlowAndSensitivityParameters.getSensitivityProvider;
+import static com.powsybl.openrao.raoapi.parameters.extensions.LoadFlowAndSensitivityParameters.getSensitivityWithLoadFlowParameters;
+import static com.powsybl.openrao.searchtreerao.commons.RaoUtil.getFlowUnit;
+
+import com.powsybl.glsk.commons.ZonalData;
+import com.powsybl.glsk.commons.ZonalDataImpl;
+import com.powsybl.iidm.network.Country;
+import com.powsybl.iidm.network.Network;
+import com.powsybl.openrao.commons.EICode;
+import com.powsybl.openrao.commons.OpenRaoException;
+import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider;
+import com.powsybl.openrao.commons.opentelemetry.OpenTelemetryReporter;
import com.powsybl.openrao.data.crac.api.Instant;
import com.powsybl.openrao.data.crac.api.cnec.Cnec;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
@@ -18,28 +29,25 @@
import com.powsybl.openrao.loopflowcomputation.LoopFlowComputation;
import com.powsybl.openrao.loopflowcomputation.LoopFlowComputationImpl;
import com.powsybl.openrao.raoapi.RaoInput;
-import com.powsybl.openrao.raoapi.parameters.RaoParameters;
import com.powsybl.openrao.raoapi.parameters.LoopFlowParameters;
+import com.powsybl.openrao.raoapi.parameters.RaoParameters;
import com.powsybl.openrao.raoapi.parameters.RelativeMarginsParameters;
import com.powsybl.openrao.sensitivityanalysis.AppliedRemedialActions;
import com.powsybl.openrao.sensitivityanalysis.SystematicSensitivityInterface;
-import com.powsybl.glsk.commons.ZonalData;
-import com.powsybl.glsk.commons.ZonalDataImpl;
-import com.powsybl.iidm.network.Country;
-import com.powsybl.iidm.network.Network;
import com.powsybl.sensitivity.SensitivityVariableSet;
-
-import java.util.*;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
-import static com.powsybl.openrao.raoapi.parameters.extensions.LoadFlowAndSensitivityParameters.getSensitivityProvider;
-import static com.powsybl.openrao.raoapi.parameters.extensions.LoadFlowAndSensitivityParameters.getSensitivityWithLoadFlowParameters;
-import static com.powsybl.openrao.searchtreerao.commons.RaoUtil.getFlowUnit;
-
/**
* @author Joris Mancini {@literal }
*/
public final class ToolProvider {
+
private Network network;
private RaoParameters raoParameters;
private ReferenceProgram referenceProgram;
@@ -65,9 +73,11 @@ private boolean hasLoopFlowExtension(FlowCnec cnec) {
public Set getLoopFlowCnecs(Set allCnecs) {
Optional loopFlowParametersOptional = raoParameters.getLoopFlowParameters();
- if (loopFlowParametersOptional.isPresent() && !loopFlowParametersOptional.get().getCountries().isEmpty()) {
+ if (loopFlowParametersOptional.isPresent() && !loopFlowParametersOptional.get()
+ .getCountries().isEmpty()) {
return allCnecs.stream()
- .filter(cnec -> hasLoopFlowExtension(cnec) && cnecIsInCountryList(cnec, network, loopFlowParametersOptional.get().getCountries()))
+ .filter(cnec -> hasLoopFlowExtension(cnec) && cnecIsInCountryList(cnec, network,
+ loopFlowParametersOptional.get().getCountries()))
.collect(Collectors.toSet());
} else {
return allCnecs.stream()
@@ -76,23 +86,25 @@ public Set getLoopFlowCnecs(Set allCnecs) {
}
}
- static boolean cnecIsInCountryList(Cnec> cnec, Network network, Set loopflowCountries) {
+ static boolean cnecIsInCountryList(Cnec> cnec, Network network,
+ Set loopflowCountries) {
return cnec.getLocation(network).stream().anyMatch(loopflowCountries::contains);
}
public SystematicSensitivityInterface getSystematicSensitivityInterface(Set cnecs,
- Set> rangeActions,
- boolean computePtdfs,
- boolean computeLoopFlows, Instant outageInstant) {
- return getSystematicSensitivityInterface(cnecs, rangeActions, computePtdfs, computeLoopFlows, null, outageInstant);
+ Set> rangeActions,
+ boolean computePtdfs,
+ boolean computeLoopFlows, Instant outageInstant) {
+ return getSystematicSensitivityInterface(cnecs, rangeActions, computePtdfs,
+ computeLoopFlows, null, outageInstant);
}
public SystematicSensitivityInterface getSystematicSensitivityInterface(Set cnecs,
- Set> rangeActions,
- boolean computePtdfs,
- boolean computeLoopFlows,
- AppliedRemedialActions appliedRemedialActions,
- Instant outageInstant) {
+ Set> rangeActions,
+ boolean computePtdfs,
+ boolean computeLoopFlows,
+ AppliedRemedialActions appliedRemedialActions,
+ Instant outageInstant) {
Unit flowUnit = getFlowUnit(raoParameters);
@@ -100,7 +112,8 @@ public SystematicSensitivityInterface getSystematicSensitivityInterface(Set loopflowCnecs = getLoopFlowCnecs(cnecs);
- builder.withPtdfSensitivities(getGlskForEic(getEicForLoopFlows()), loopflowCnecs, computationUnits);
+ builder.withPtdfSensitivities(getGlskForEic(getEicForLoopFlows()), loopflowCnecs,
+ computationUnits);
} else if (computePtdfs) {
- builder.withPtdfSensitivities(getGlskForEic(getEicForObjectiveFunction()), cnecs, computationUnits);
+ builder.withPtdfSensitivities(getGlskForEic(getEicForObjectiveFunction()), cnecs,
+ computationUnits);
}
return builder.build();
@@ -149,7 +164,8 @@ ZonalData getGlskForEic(Set listEicCode) {
for (String eiCode : listEicCode) {
SensitivityVariableSet linearGlsk = glskProvider.getData(eiCode);
if (Objects.isNull(linearGlsk)) {
- OpenRaoLoggerProvider.TECHNICAL_LOGS.warn("No GLSK found for CountryEICode {}", eiCode);
+ OpenRaoLoggerProvider.TECHNICAL_LOGS.warn("No GLSK found for CountryEICode {}",
+ eiCode);
} else {
glskBoundaries.put(eiCode, linearGlsk);
}
@@ -163,6 +179,7 @@ public static ToolProviderBuilder create() {
}
public static final class ToolProviderBuilder {
+
private Network network;
private RaoParameters raoParameters;
private ReferenceProgram referenceProgram;
@@ -180,14 +197,18 @@ public ToolProviderBuilder withRaoParameters(RaoParameters raoParameters) {
return this;
}
- public ToolProviderBuilder withLoopFlowComputation(ReferenceProgram referenceProgram, ZonalData glskProvider, LoopFlowComputation loopFlowComputation) {
+ public ToolProviderBuilder withLoopFlowComputation(ReferenceProgram referenceProgram,
+ ZonalData glskProvider,
+ LoopFlowComputation loopFlowComputation) {
this.referenceProgram = referenceProgram;
this.glskProvider = glskProvider;
this.loopFlowComputation = loopFlowComputation;
return this;
}
- public ToolProviderBuilder withAbsolutePtdfSumsComputation(ZonalData glskProvider, AbsolutePtdfSumsComputation absolutePtdfSumsComputation) {
+ public ToolProviderBuilder withAbsolutePtdfSumsComputation(
+ ZonalData glskProvider,
+ AbsolutePtdfSumsComputation absolutePtdfSumsComputation) {
this.glskProvider = glskProvider;
this.absolutePtdfSumsComputation = absolutePtdfSumsComputation;
return this;
@@ -207,35 +228,40 @@ public ToolProvider build() {
}
}
- public static ToolProvider buildFromRaoInputAndParameters(RaoInput raoInput, RaoParameters raoParameters) {
-
- ToolProvider.ToolProviderBuilder toolProviderBuilder = ToolProvider.create()
- .withNetwork(raoInput.getNetwork())
- .withRaoParameters(raoParameters);
- if (raoInput.getReferenceProgram() != null) {
- toolProviderBuilder.withLoopFlowComputation(
- raoInput.getReferenceProgram(),
- raoInput.getGlskProvider(),
- new LoopFlowComputationImpl(
- raoInput.getGlskProvider(),
+ public static ToolProvider buildFromRaoInputAndParameters(RaoInput raoInput,
+ RaoParameters raoParameters) {
+ return OpenTelemetryReporter.withSpan("rao.buildToolProvider", cx -> {
+ ToolProvider.ToolProviderBuilder toolProviderBuilder = ToolProvider.create()
+ .withNetwork(raoInput.getNetwork())
+ .withRaoParameters(raoParameters);
+ if (raoInput.getReferenceProgram() != null) {
+ toolProviderBuilder.withLoopFlowComputation(
raoInput.getReferenceProgram(),
- getFlowUnit(raoParameters)
- )
- );
- }
- if (raoParameters.getObjectiveFunctionParameters().getType().relativePositiveMargins()) {
- Optional optionalRelativeMarginsParameters = raoParameters.getRelativeMarginsParameters();
- if (optionalRelativeMarginsParameters.isEmpty()) {
- throw new OpenRaoException("No relative margins parameters were defined with objective function " + raoParameters.getObjectiveFunctionParameters().getType());
+ raoInput.getGlskProvider(),
+ new LoopFlowComputationImpl(
+ raoInput.getGlskProvider(),
+ raoInput.getReferenceProgram(),
+ getFlowUnit(raoParameters)
+ )
+ );
}
- toolProviderBuilder.withAbsolutePtdfSumsComputation(
- raoInput.getGlskProvider(),
- new AbsolutePtdfSumsComputation(
+ if (raoParameters.getObjectiveFunctionParameters().getType()
+ .relativePositiveMargins()) {
+ Optional optionalRelativeMarginsParameters = raoParameters.getRelativeMarginsParameters();
+ if (optionalRelativeMarginsParameters.isEmpty()) {
+ throw new OpenRaoException(
+ "No relative margins parameters were defined with objective function "
+ + raoParameters.getObjectiveFunctionParameters().getType());
+ }
+ toolProviderBuilder.withAbsolutePtdfSumsComputation(
raoInput.getGlskProvider(),
- optionalRelativeMarginsParameters.get().getPtdfBoundaries()
- )
- );
- }
- return toolProviderBuilder.build();
+ new AbsolutePtdfSumsComputation(
+ raoInput.getGlskProvider(),
+ optionalRelativeMarginsParameters.get().getPtdfBoundaries()
+ )
+ );
+ }
+ return toolProviderBuilder.build();
+ });
}
}
diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/parameters/TreeParameters.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/parameters/TreeParameters.java
index 2dfa0aa967..a3afa58ce9 100644
--- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/parameters/TreeParameters.java
+++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/commons/parameters/TreeParameters.java
@@ -7,24 +7,28 @@
package com.powsybl.openrao.searchtreerao.commons.parameters;
-import com.powsybl.openrao.raoapi.parameters.ObjectiveFunctionParameters;
-import com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoRangeActionsOptimizationParameters;
-import com.powsybl.openrao.raoapi.parameters.RaoParameters;
-
-import static com.powsybl.openrao.raoapi.parameters.extensions.MultithreadingParameters.*;
+import static com.powsybl.openrao.raoapi.parameters.extensions.MultithreadingParameters.getAvailableCPUs;
import static com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoObjectiveFunctionParameters.getCurativeMinObjImprovement;
import static com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoRangeActionsOptimizationParameters.getRaRangeShrinking;
-import static com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoTopoOptimizationParameters.*;
+import static com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoTopoOptimizationParameters.getMaxCurativeSearchTreeDepth;
+import static com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoTopoOptimizationParameters.getMaxPreventiveSearchTreeDepth;
+
+import com.powsybl.openrao.commons.opentelemetry.OpenTelemetryReporter;
+import com.powsybl.openrao.raoapi.parameters.ObjectiveFunctionParameters;
+import com.powsybl.openrao.raoapi.parameters.RaoParameters;
+import com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoRangeActionsOptimizationParameters;
/**
- * This class contains internal Open RAO parameters used in the SearchTree algorithm.
- * These parameters are dynamically generated by the SearchTreeRaoProvider depending on the context and on
- * the user's RAO parameters, and then used in SearchTree algorithm.
- * They should not be visible to the user.
+ * This class contains internal Open RAO parameters used in the SearchTree algorithm. These
+ * parameters are dynamically generated by the SearchTreeRaoProvider depending on the context and on
+ * the user's RAO parameters, and then used in SearchTree algorithm. They should not be visible to
+ * the user.
*
* @author Peter Mitri {@literal }
*/
-public record TreeParameters(StopCriterion stopCriterion, double targetObjectiveValue, int maximumSearchDepth, int leavesInParallel, boolean raRangeShrinking) {
+public record TreeParameters(StopCriterion stopCriterion, double targetObjectiveValue,
+ int maximumSearchDepth, int leavesInParallel,
+ boolean raRangeShrinking) {
public enum StopCriterion {
MIN_OBJECTIVE,
@@ -32,10 +36,15 @@ public enum StopCriterion {
}
public static TreeParameters buildForPreventivePerimeter(RaoParameters parameters) {
- SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking raRangeShrinking = getRaRangeShrinking(parameters);
- boolean shouldShrinkRaRange = raRangeShrinking.equals(SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking.ENABLED_IN_FIRST_PRAO_AND_CRAO) ||
- raRangeShrinking.equals(SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking.ENABLED);
- if (parameters.getObjectiveFunctionParameters().getType() == ObjectiveFunctionParameters.ObjectiveFunctionType.SECURE_FLOW) {
+ SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking raRangeShrinking = getRaRangeShrinking(
+ parameters);
+ boolean shouldShrinkRaRange = raRangeShrinking.equals(
+ SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking.ENABLED_IN_FIRST_PRAO_AND_CRAO)
+ ||
+ raRangeShrinking.equals(
+ SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking.ENABLED);
+ if (parameters.getObjectiveFunctionParameters().getType()
+ == ObjectiveFunctionParameters.ObjectiveFunctionType.SECURE_FLOW) {
return new TreeParameters(StopCriterion.AT_TARGET_OBJECTIVE_VALUE,
0.0, // secure
getMaxPreventiveSearchTreeDepth(parameters),
@@ -50,30 +59,41 @@ public static TreeParameters buildForPreventivePerimeter(RaoParameters parameter
}
}
- public static TreeParameters buildForCurativePerimeter(RaoParameters parameters, Double preventiveOptimizedCost) {
- StopCriterion stopCriterion = StopCriterion.AT_TARGET_OBJECTIVE_VALUE;
- double targetObjectiveValue;
- if (parameters.getObjectiveFunctionParameters().getType() == ObjectiveFunctionParameters.ObjectiveFunctionType.SECURE_FLOW) {
- targetObjectiveValue = 0.0;
- } else {
- targetObjectiveValue = preventiveOptimizedCost - getCurativeMinObjImprovement(parameters);
- if (parameters.getObjectiveFunctionParameters().getEnforceCurativeSecurity()) {
- targetObjectiveValue = Math.min(targetObjectiveValue, 0);
+ public static TreeParameters buildForCurativePerimeter(RaoParameters parameters,
+ Double preventiveOptimizedCost) {
+ return OpenTelemetryReporter.withSpan("rao.buildCurativePerimeter", cx -> {
+ StopCriterion stopCriterion = StopCriterion.AT_TARGET_OBJECTIVE_VALUE;
+ double targetObjectiveValue;
+ if (parameters.getObjectiveFunctionParameters().getType()
+ == ObjectiveFunctionParameters.ObjectiveFunctionType.SECURE_FLOW) {
+ targetObjectiveValue = 0.0;
+ } else {
+ targetObjectiveValue =
+ preventiveOptimizedCost - getCurativeMinObjImprovement(parameters);
+ if (parameters.getObjectiveFunctionParameters().getEnforceCurativeSecurity()) {
+ targetObjectiveValue = Math.min(targetObjectiveValue, 0);
+ }
}
- }
- SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking raRangeShrinking = getRaRangeShrinking(parameters);
- boolean shouldShrinkRaRange = raRangeShrinking.equals(SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking.ENABLED_IN_FIRST_PRAO_AND_CRAO) ||
- raRangeShrinking.equals(SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking.ENABLED);
- return new TreeParameters(stopCriterion,
- targetObjectiveValue,
- getMaxCurativeSearchTreeDepth(parameters),
- 1,
- shouldShrinkRaRange);
+ SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking raRangeShrinking = getRaRangeShrinking(
+ parameters);
+ boolean shouldShrinkRaRange = raRangeShrinking.equals(
+ SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking.ENABLED_IN_FIRST_PRAO_AND_CRAO)
+ ||
+ raRangeShrinking.equals(
+ SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking.ENABLED);
+ return new TreeParameters(stopCriterion,
+ targetObjectiveValue,
+ getMaxCurativeSearchTreeDepth(parameters),
+ 1,
+ shouldShrinkRaRange);
+ });
}
public static TreeParameters buildForSecondPreventivePerimeter(RaoParameters parameters) {
- boolean raRangeShrinking = getRaRangeShrinking(parameters).equals(SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking.ENABLED);
- if (parameters.getObjectiveFunctionParameters().getType().equals(ObjectiveFunctionParameters.ObjectiveFunctionType.SECURE_FLOW)) {
+ boolean raRangeShrinking = getRaRangeShrinking(parameters).equals(
+ SearchTreeRaoRangeActionsOptimizationParameters.RaRangeShrinking.ENABLED);
+ if (parameters.getObjectiveFunctionParameters().getType()
+ .equals(ObjectiveFunctionParameters.ObjectiveFunctionType.SECURE_FLOW)) {
return new TreeParameters(StopCriterion.AT_TARGET_OBJECTIVE_VALUE,
0.0, // secure
getMaxPreventiveSearchTreeDepth(parameters),
diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/IteratingLinearOptimizer.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/IteratingLinearOptimizer.java
index e275acd712..e18ecaf4a8 100644
--- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/IteratingLinearOptimizer.java
+++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/IteratingLinearOptimizer.java
@@ -7,6 +7,13 @@
package com.powsybl.openrao.searchtreerao.linearoptimisation.algorithms;
+import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.BUSINESS_LOGS;
+import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.BUSINESS_WARNS;
+import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.TECHNICAL_LOGS;
+import static com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoRangeActionsOptimizationParameters.getPstModel;
+
+import com.powsybl.iidm.network.Network;
+import com.powsybl.openrao.commons.opentelemetry.OpenTelemetryReporter;
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;
@@ -17,19 +24,20 @@
import com.powsybl.openrao.searchtreerao.linearoptimisation.algorithms.linearproblem.LinearProblem;
import com.powsybl.openrao.searchtreerao.linearoptimisation.inputs.IteratingLinearOptimizerInput;
import com.powsybl.openrao.searchtreerao.linearoptimisation.parameters.IteratingLinearOptimizerParameters;
-import com.powsybl.openrao.searchtreerao.result.api.*;
+import com.powsybl.openrao.searchtreerao.result.api.FlowResult;
+import com.powsybl.openrao.searchtreerao.result.api.LinearOptimizationResult;
+import com.powsybl.openrao.searchtreerao.result.api.LinearProblemStatus;
+import com.powsybl.openrao.searchtreerao.result.api.NetworkActionsResult;
+import com.powsybl.openrao.searchtreerao.result.api.ObjectiveFunctionResult;
+import com.powsybl.openrao.searchtreerao.result.api.RangeActionActivationResult;
+import com.powsybl.openrao.searchtreerao.result.api.SensitivityResult;
import com.powsybl.openrao.searchtreerao.result.impl.IteratingLinearOptimizationResultImpl;
import com.powsybl.openrao.searchtreerao.result.impl.LinearProblemResult;
import com.powsybl.openrao.searchtreerao.result.impl.RangeActionActivationResultImpl;
import com.powsybl.openrao.searchtreerao.result.impl.RemedialActionActivationResultImpl;
import com.powsybl.openrao.sensitivityanalysis.AppliedRemedialActions;
-import com.powsybl.iidm.network.Network;
-import org.apache.commons.lang3.tuple.Pair;
-
import java.util.Locale;
-
-import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.*;
-import static com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoRangeActionsOptimizationParameters.getPstModel;
+import org.apache.commons.lang3.tuple.Pair;
/**
* @author Joris Mancini {@literal }
@@ -40,68 +48,83 @@ private IteratingLinearOptimizer() {
}
- public static LinearOptimizationResult optimize(IteratingLinearOptimizerInput input, IteratingLinearOptimizerParameters parameters) {
+ 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());
IteratingLinearOptimizationResultImpl previousResult = bestResult;
SensitivityComputer sensitivityComputer = null;
LinearProblem linearProblem = LinearProblem.create()
- .buildFromInputsAndParameters(input, parameters);
+ .buildFromInputsAndParameters(input, parameters);
- linearProblem.fill(input.preOptimizationFlowResult(), input.preOptimizationSensitivityResult());
+ linearProblem.fill(input.preOptimizationFlowResult(),
+ input.preOptimizationSensitivityResult());
for (int iteration = 1; iteration <= parameters.getMaxNumberOfIterations(); iteration++) {
LinearProblemStatus solveStatus = solveLinearProblem(linearProblem, iteration);
bestResult.setNbOfIteration(iteration);
if (solveStatus == LinearProblemStatus.FEASIBLE) {
- TECHNICAL_LOGS.warn("The solver was interrupted. A feasible solution has been produced.");
+ TECHNICAL_LOGS.warn(
+ "The solver was interrupted. A feasible solution has been produced.");
} else if (solveStatus != LinearProblemStatus.OPTIMAL) {
BUSINESS_LOGS.error("Linear optimization failed at iteration {}", iteration);
if (iteration == 1) {
bestResult.setStatus(solveStatus);
- BUSINESS_LOGS.info("Linear problem failed with the following status : {}, initial situation is kept.", solveStatus);
+ BUSINESS_LOGS.info(
+ "Linear problem failed with the following status : {}, initial situation is kept.",
+ solveStatus);
return bestResult;
}
bestResult.setStatus(LinearProblemStatus.FEASIBLE);
return bestResult;
}
- RangeActionActivationResult linearProblemResult = new LinearProblemResult(linearProblem, input.prePerimeterSetpoints(), input.optimizationPerimeter());
- RangeActionActivationResult currentRangeActionActivationResult = roundResult(linearProblemResult, bestResult, input, parameters);
- currentRangeActionActivationResult = resolveIfApproximatedPstTaps(bestResult, linearProblem, iteration, currentRangeActionActivationResult, input, parameters);
+ RangeActionActivationResult linearProblemResult = new LinearProblemResult(linearProblem,
+ input.prePerimeterSetpoints(), input.optimizationPerimeter());
+ RangeActionActivationResult currentRangeActionActivationResult = roundResult(
+ linearProblemResult, bestResult, input, parameters);
+ currentRangeActionActivationResult = resolveIfApproximatedPstTaps(bestResult,
+ linearProblem, iteration, currentRangeActionActivationResult, input, parameters);
- if (!hasAnyRangeActionChanged(currentRangeActionActivationResult, previousResult, input.optimizationPerimeter())) {
+ if (!hasAnyRangeActionChanged(currentRangeActionActivationResult, previousResult,
+ input.optimizationPerimeter())) {
// If the solution has not changed, no need to run a new sensitivity computation and iteration can stop
- TECHNICAL_LOGS.info("Iteration {}: same results as previous iterations, optimal solution found", iteration);
+ TECHNICAL_LOGS.info(
+ "Iteration {}: same results as previous iterations, optimal solution found",
+ iteration);
return bestResult;
}
- sensitivityComputer = runSensitivityAnalysis(sensitivityComputer, iteration, currentRangeActionActivationResult, input, parameters);
- if (sensitivityComputer.getSensitivityResult().getSensitivityStatus() == ComputationStatus.FAILURE) {
+ sensitivityComputer = runSensitivityAnalysis(sensitivityComputer, iteration,
+ currentRangeActionActivationResult, input, parameters);
+ if (sensitivityComputer.getSensitivityResult().getSensitivityStatus()
+ == ComputationStatus.FAILURE) {
bestResult.setStatus(LinearProblemStatus.SENSITIVITY_COMPUTATION_FAILED);
return bestResult;
}
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()
);
previousResult = currentResult;
- Pair mipShouldStop = updateBestResultAndCheckStopCondition(parameters.getRaRangeShrinking(), linearProblem, input, iteration, currentResult, bestResult);
+ Pair mipShouldStop = updateBestResultAndCheckStopCondition(
+ parameters.getRaRangeShrinking(), linearProblem, input, iteration, currentResult,
+ bestResult);
if (Boolean.TRUE.equals(mipShouldStop.getRight())) {
return bestResult;
} else {
@@ -112,25 +135,36 @@ public static LinearOptimizationResult optimize(IteratingLinearOptimizerInput in
return bestResult;
}
- private static SensitivityComputer runSensitivityAnalysis(SensitivityComputer sensitivityComputer, int iteration, RangeActionActivationResult currentRangeActionActivationResult, IteratingLinearOptimizerInput input, IteratingLinearOptimizerParameters parameters) {
+ private static SensitivityComputer runSensitivityAnalysis(
+ SensitivityComputer sensitivityComputer, int iteration,
+ RangeActionActivationResult currentRangeActionActivationResult,
+ IteratingLinearOptimizerInput input, IteratingLinearOptimizerParameters parameters) {
SensitivityComputer tmpSensitivityComputer = sensitivityComputer;
if (input.optimizationPerimeter() instanceof GlobalOptimizationPerimeter) {
- AppliedRemedialActions appliedRemedialActionsInSecondaryStates = applyRangeActions(currentRangeActionActivationResult, input);
- tmpSensitivityComputer = createSensitivityComputer(appliedRemedialActionsInSecondaryStates, input, parameters);
+ AppliedRemedialActions appliedRemedialActionsInSecondaryStates = applyRangeActions(
+ currentRangeActionActivationResult, input);
+ tmpSensitivityComputer = createSensitivityComputer(
+ appliedRemedialActionsInSecondaryStates, input, parameters);
} else {
applyRangeActions(currentRangeActionActivationResult, input);
- if (tmpSensitivityComputer == null) { // first iteration, do not need to be updated afterwards
- tmpSensitivityComputer = createSensitivityComputer(input.preOptimizationAppliedRemedialActions(), input, parameters);
+ if (tmpSensitivityComputer
+ == null) { // first iteration, do not need to be updated afterwards
+ tmpSensitivityComputer = createSensitivityComputer(
+ input.preOptimizationAppliedRemedialActions(), input, parameters);
}
}
runSensitivityAnalysis(tmpSensitivityComputer, input.network(), iteration);
return tmpSensitivityComputer;
}
- private static RangeActionActivationResult resolveIfApproximatedPstTaps(IteratingLinearOptimizationResultImpl bestResult, LinearProblem linearProblem, int iteration, RangeActionActivationResult currentRangeActionActivationResult, IteratingLinearOptimizerInput input, IteratingLinearOptimizerParameters parameters) {
+ private static RangeActionActivationResult resolveIfApproximatedPstTaps(
+ IteratingLinearOptimizationResultImpl bestResult, LinearProblem linearProblem,
+ int iteration, RangeActionActivationResult currentRangeActionActivationResult,
+ IteratingLinearOptimizerInput input, IteratingLinearOptimizerParameters parameters) {
LinearProblemStatus solveStatus;
RangeActionActivationResult rangeActionActivationResult = currentRangeActionActivationResult;
- if (getPstModel(parameters.getRangeActionParametersExtension()).equals(PstModel.APPROXIMATED_INTEGERS)) {
+ if (getPstModel(parameters.getRangeActionParametersExtension()).equals(
+ PstModel.APPROXIMATED_INTEGERS)) {
// if the PST approximation is APPROXIMATED_INTEGERS, we re-solve the optimization problem
// but first, we update it, with an adjustment of the PSTs angleToTap conversion factors, to
@@ -140,65 +174,93 @@ private static RangeActionActivationResult resolveIfApproximatedPstTaps(Iteratin
linearProblem.updateBetweenMipIteration(rangeActionActivationResult);
solveStatus = solveLinearProblem(linearProblem, iteration);
- if (solveStatus == LinearProblemStatus.OPTIMAL || solveStatus == LinearProblemStatus.FEASIBLE) {
- RangeActionActivationResult updatedLinearProblemResult = new LinearProblemResult(linearProblem, input.prePerimeterSetpoints(), input.optimizationPerimeter());
- rangeActionActivationResult = roundResult(updatedLinearProblemResult, bestResult, input, parameters);
+ if (solveStatus == LinearProblemStatus.OPTIMAL
+ || solveStatus == LinearProblemStatus.FEASIBLE) {
+ RangeActionActivationResult updatedLinearProblemResult = new LinearProblemResult(
+ linearProblem, input.prePerimeterSetpoints(), input.optimizationPerimeter());
+ rangeActionActivationResult = roundResult(updatedLinearProblemResult, bestResult,
+ input, parameters);
}
}
return rangeActionActivationResult;
}
- private static LinearProblemStatus solveLinearProblem(LinearProblem linearProblem, int iteration) {
- TECHNICAL_LOGS.debug("Iteration {}: linear optimization [start]", iteration);
- LinearProblemStatus status = linearProblem.solve();
- TECHNICAL_LOGS.debug("Iteration {}: linear optimization [end]", iteration);
- return status;
+ private static LinearProblemStatus solveLinearProblem(LinearProblem linearProblem,
+ int iteration) {
+ return OpenTelemetryReporter.withSpan("rao.iteratingLinearSolver.solveLinearProblem",
+ cx -> {
+ TECHNICAL_LOGS.debug("Iteration {}: linear optimization [start]", iteration);
+ LinearProblemStatus status = linearProblem.solve();
+ TECHNICAL_LOGS.debug("Iteration {}: linear optimization [end]", iteration);
+ return status;
+ });
}
- private static boolean hasAnyRangeActionChanged(RangeActionActivationResult newRangeActionActivationResult, RangeActionActivationResult oldRangeActionActivationResult, OptimizationPerimeter optimizationContext) {
+ 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) {
+ public static AppliedRemedialActions applyRangeActions(
+ RangeActionActivationResult rangeActionActivationResult,
+ IteratingLinearOptimizerInput input) {
OptimizationPerimeter optimizationContext = input.optimizationPerimeter();
// apply RangeAction from first optimization state
- optimizationContext.getRangeActionsPerState().get(optimizationContext.getMainOptimizationState())
- .forEach(ra -> ra.apply(input.network(), rangeActionActivationResult.getOptimizedSetpoint(ra, optimizationContext.getMainOptimizationState())));
+ optimizationContext.getRangeActionsPerState()
+ .get(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();
+ 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;
}
}
- private static SensitivityComputer createSensitivityComputer(AppliedRemedialActions appliedRemedialActions, IteratingLinearOptimizerInput input, IteratingLinearOptimizerParameters parameters) {
+ 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());
-
- if (parameters.isRaoWithLoopFlowLimitation() && parameters.getLoopFlowParametersExtension().getPtdfApproximation().shouldUpdatePtdfWithPstChange()) {
- builder.withCommercialFlowsResults(input.toolProvider().getLoopFlowComputation(), input.optimizationPerimeter().getLoopFlowCnecs());
+ .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());
} else if (parameters.isRaoWithLoopFlowLimitation()) {
builder.withCommercialFlowsResults(input.preOptimizationFlowResult());
}
if (parameters.getObjectiveFunction().relativePositiveMargins()) {
- if (parameters.getMaxMinRelativeMarginParameters().getPtdfApproximation().shouldUpdatePtdfWithPstChange()) {
- builder.withPtdfsResults(input.toolProvider().getAbsolutePtdfSumsComputation(), input.optimizationPerimeter().getFlowCnecs());
+ if (parameters.getMaxMinRelativeMarginParameters().getPtdfApproximation()
+ .shouldUpdatePtdfWithPstChange()) {
+ builder.withPtdfsResults(input.toolProvider().getAbsolutePtdfSumsComputation(),
+ input.optimizationPerimeter().getFlowCnecs());
} else {
builder.withPtdfsResults(input.preOptimizationFlowResult());
}
@@ -207,45 +269,66 @@ private static SensitivityComputer createSensitivityComputer(AppliedRemedialActi
return builder.build();
}
- private static void runSensitivityAnalysis(SensitivityComputer sensitivityComputer, Network network, int iteration) {
+ private static void runSensitivityAnalysis(SensitivityComputer sensitivityComputer,
+ Network network, int iteration) {
sensitivityComputer.compute(network);
- if (sensitivityComputer.getSensitivityResult().getSensitivityStatus() == ComputationStatus.FAILURE) {
- BUSINESS_WARNS.warn("Systematic sensitivity computation failed at iteration {}", iteration);
+ if (sensitivityComputer.getSensitivityResult().getSensitivityStatus()
+ == ComputationStatus.FAILURE) {
+ BUSINESS_WARNS.warn("Systematic sensitivity computation failed at iteration {}",
+ iteration);
}
}
private static IteratingLinearOptimizationResultImpl createResult(FlowResult flowResult,
- SensitivityResult sensitivityResult,
- RangeActionActivationResult rangeActionActivation,
- NetworkActionsResult networkActionsResult,
- int nbOfIterations,
- ObjectiveFunction objectiveFunction) {
- return new IteratingLinearOptimizationResultImpl(LinearProblemStatus.OPTIMAL, nbOfIterations, rangeActionActivation, flowResult,
- objectiveFunction.evaluate(flowResult, new RemedialActionActivationResultImpl(rangeActionActivation, networkActionsResult)), sensitivityResult);
+ SensitivityResult sensitivityResult,
+ RangeActionActivationResult rangeActionActivation,
+ NetworkActionsResult networkActionsResult,
+ int nbOfIterations,
+ ObjectiveFunction objectiveFunction) {
+ return new IteratingLinearOptimizationResultImpl(LinearProblemStatus.OPTIMAL,
+ nbOfIterations, rangeActionActivation, flowResult,
+ objectiveFunction.evaluate(flowResult,
+ new RemedialActionActivationResultImpl(rangeActionActivation,
+ networkActionsResult)), sensitivityResult);
}
- private static Pair updateBestResultAndCheckStopCondition(boolean raRangeShrinking, LinearProblem linearProblem, IteratingLinearOptimizerInput input, int iteration, IteratingLinearOptimizationResultImpl currentResult, IteratingLinearOptimizationResultImpl bestResult) {
+ private static Pair updateBestResultAndCheckStopCondition(
+ boolean raRangeShrinking, LinearProblem linearProblem, IteratingLinearOptimizerInput input,
+ int iteration, IteratingLinearOptimizationResultImpl currentResult,
+ IteratingLinearOptimizationResultImpl bestResult) {
if (currentResult.getCost() < bestResult.getCost()) {
logBetterResult(iteration, currentResult);
- linearProblem.updateBetweenSensiIteration(currentResult.getBranchResult(), currentResult.getSensitivityResult(), currentResult.getRangeActionActivationResult());
+ linearProblem.updateBetweenSensiIteration(currentResult.getBranchResult(),
+ currentResult.getSensitivityResult(),
+ currentResult.getRangeActionActivationResult());
return Pair.of(currentResult, false);
}
logWorseResult(iteration, bestResult, currentResult);
applyRangeActions(bestResult, input);
if (raRangeShrinking) {
- linearProblem.updateBetweenSensiIteration(currentResult.getBranchResult(), currentResult.getSensitivityResult(), currentResult.getRangeActionActivationResult());
+ linearProblem.updateBetweenSensiIteration(currentResult.getBranchResult(),
+ currentResult.getSensitivityResult(),
+ currentResult.getRangeActionActivationResult());
}
return Pair.of(bestResult, !raRangeShrinking);
}
- private static RangeActionActivationResult roundResult(RangeActionActivationResult linearProblemResult, IteratingLinearOptimizationResultImpl previousResult, IteratingLinearOptimizerInput input, IteratingLinearOptimizerParameters parameters) {
- RangeActionActivationResultImpl roundedResult = roundPsts(linearProblemResult, previousResult, input, parameters);
+ private static RangeActionActivationResult roundResult(
+ RangeActionActivationResult linearProblemResult,
+ IteratingLinearOptimizationResultImpl previousResult, IteratingLinearOptimizerInput input,
+ IteratingLinearOptimizerParameters parameters) {
+ RangeActionActivationResultImpl roundedResult = roundPsts(linearProblemResult,
+ previousResult, input, parameters);
roundOtherRas(linearProblemResult, input.optimizationPerimeter(), roundedResult);
return roundedResult;
}
- private static RangeActionActivationResultImpl roundPsts(RangeActionActivationResult linearProblemResult, IteratingLinearOptimizationResultImpl previousResult, IteratingLinearOptimizerInput input, IteratingLinearOptimizerParameters parameters) {
- if (getPstModel(parameters.getRangeActionParametersExtension()).equals(PstModel.CONTINUOUS)) {
+ private static RangeActionActivationResultImpl roundPsts(
+ RangeActionActivationResult linearProblemResult,
+ IteratingLinearOptimizationResultImpl previousResult, IteratingLinearOptimizerInput input,
+ IteratingLinearOptimizerParameters parameters) {
+ if (getPstModel(parameters.getRangeActionParametersExtension()).equals(
+ PstModel.CONTINUOUS)) {
return BestTapFinder.round(
linearProblemResult,
input.network(),
@@ -255,23 +338,28 @@ private static RangeActionActivationResultImpl roundPsts(RangeActionActivationRe
parameters.getFlowUnit()
);
}
- RangeActionActivationResultImpl roundedResult = new RangeActionActivationResultImpl(input.prePerimeterSetpoints());
- input.optimizationPerimeter().getRangeActionOptimizationStates().forEach(state -> linearProblemResult.getActivatedRangeActions(state)
- .stream().filter(PstRangeAction.class::isInstance).map(PstRangeAction.class::cast)
- .forEach(pst -> roundedResult.putResult(pst, state, pst.convertTapToAngle(linearProblemResult.getOptimizedTap(pst, state))))
- );
+ RangeActionActivationResultImpl roundedResult = new RangeActionActivationResultImpl(
+ input.prePerimeterSetpoints());
+ input.optimizationPerimeter().getRangeActionOptimizationStates()
+ .forEach(state -> linearProblemResult.getActivatedRangeActions(state)
+ .stream().filter(PstRangeAction.class::isInstance).map(PstRangeAction.class::cast)
+ .forEach(pst -> roundedResult.putResult(pst, state,
+ pst.convertTapToAngle(linearProblemResult.getOptimizedTap(pst, state)))));
return roundedResult;
}
static void roundOtherRas(RangeActionActivationResult linearProblemResult,
- 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)))));
+ 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) {
+ private static void logBetterResult(int iteration,
+ ObjectiveFunctionResult currentObjectiveFunctionResult) {
TECHNICAL_LOGS.info(
"Iteration {}: better solution found with a cost of {} (functional: {})",
iteration,
@@ -286,7 +374,8 @@ private static void logBetterResult(int iteration, ObjectiveFunctionResult curre
});
}
- private static void logWorseResult(int iteration, ObjectiveFunctionResult bestResult, ObjectiveFunctionResult currentResult) {
+ 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,
diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/OpenRaoMPSolver.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/OpenRaoMPSolver.java
index 8e56cc3e5a..f01d323964 100644
--- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/OpenRaoMPSolver.java
+++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/OpenRaoMPSolver.java
@@ -12,9 +12,9 @@
import com.google.ortools.linearsolver.MPSolverParameters;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider;
+import com.powsybl.openrao.commons.opentelemetry.OpenTelemetryReporter;
import com.powsybl.openrao.raoapi.parameters.extensions.SearchTreeRaoRangeActionsOptimizationParameters;
import com.powsybl.openrao.searchtreerao.result.api.LinearProblemStatus;
-
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
@@ -26,11 +26,13 @@
* @author Peter Mitri {@literal }
*/
public class OpenRaoMPSolver {
+
static {
try {
Loader.loadNativeLibraries();
} catch (Exception e) {
- OpenRaoLoggerProvider.TECHNICAL_LOGS.error("Native library jniortools could not be loaded. You can ignore this message if it is not needed.");
+ OpenRaoLoggerProvider.TECHNICAL_LOGS.error(
+ "Native library jniortools could not be loaded. You can ignore this message if it is not needed.");
}
}
@@ -52,7 +54,8 @@ public class OpenRaoMPSolver {
OpenRaoMPObjective objective;
private boolean objectiveMinimization = true;
- public OpenRaoMPSolver(String optProblemName, SearchTreeRaoRangeActionsOptimizationParameters.Solver solver) {
+ public OpenRaoMPSolver(String optProblemName,
+ SearchTreeRaoRangeActionsOptimizationParameters.Solver solver) {
this.solver = solver;
this.optProblemName = optProblemName;
solveConfiguration = new MPSolverParameters();
@@ -76,13 +79,15 @@ public SearchTreeRaoRangeActionsOptimizationParameters.Solver getSolver() {
return solver;
}
- private MPSolver.OptimizationProblemType getOrToolsProblemType(SearchTreeRaoRangeActionsOptimizationParameters.Solver solver) {
+ private MPSolver.OptimizationProblemType getOrToolsProblemType(
+ SearchTreeRaoRangeActionsOptimizationParameters.Solver solver) {
Objects.requireNonNull(solver);
return switch (solver) {
case CBC -> MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING;
case SCIP -> MPSolver.OptimizationProblemType.SCIP_MIXED_INTEGER_PROGRAMMING;
case XPRESS -> MPSolver.OptimizationProblemType.XPRESS_MIXED_INTEGER_PROGRAMMING;
- default -> throw new OpenRaoException(String.format("unknown solver %s in RAO parameters", solver));
+ default -> throw new OpenRaoException(
+ String.format("unknown solver %s in RAO parameters", solver));
};
}
@@ -99,7 +104,8 @@ public OpenRaoMPConstraint getConstraint(String name) {
if (hasConstraint(name)) {
return constraints.get(name);
} else {
- throw new OpenRaoException(String.format("Constraint %s has not been created yet", name));
+ throw new OpenRaoException(
+ String.format("Constraint %s has not been created yet", name));
}
}
@@ -137,7 +143,8 @@ private OpenRaoMPVariable makeVar(double lb, double ub, boolean integer, String
}
double roundedLb = roundDouble(lb);
double roundedUb = roundDouble(ub);
- OpenRaoMPVariable variable = new OpenRaoMPVariable(mpSolver.makeVar(roundedLb, roundedUb, integer, name));
+ OpenRaoMPVariable variable = new OpenRaoMPVariable(
+ mpSolver.makeVar(roundedLb, roundedUb, integer, name));
variables.put(name, variable);
return variable;
}
@@ -148,7 +155,8 @@ public OpenRaoMPConstraint makeConstraint(double lb, double ub, String name) {
} else {
double roundedLb = roundDouble(lb);
double roundedUb = roundDouble(ub);
- OpenRaoMPConstraint constraint = new OpenRaoMPConstraint(mpSolver.makeConstraint(roundedLb, roundedUb, name));
+ OpenRaoMPConstraint constraint = new OpenRaoMPConstraint(
+ mpSolver.makeConstraint(roundedLb, roundedUb, name));
constraints.put(name, constraint);
return constraint;
}
@@ -168,14 +176,17 @@ public boolean setSolverSpecificParametersAsString(String solverSpecificParamete
}
public void setRelativeMipGap(double relativeMipGap) {
- solveConfiguration.setDoubleParam(MPSolverParameters.DoubleParam.RELATIVE_MIP_GAP, relativeMipGap);
+ solveConfiguration.setDoubleParam(MPSolverParameters.DoubleParam.RELATIVE_MIP_GAP,
+ relativeMipGap);
}
public LinearProblemStatus solve() {
- if (OpenRaoLoggerProvider.TECHNICAL_LOGS.isTraceEnabled()) {
- mpSolver.enableOutput();
- }
- return convertResultStatus(mpSolver.solve(solveConfiguration));
+ return OpenTelemetryReporter.withSpan("rao.mpsolver.solve", cx -> {
+ if (OpenRaoLoggerProvider.TECHNICAL_LOGS.isTraceEnabled()) {
+ mpSolver.enableOutput();
+ }
+ return convertResultStatus(mpSolver.solve(solveConfiguration));
+ });
}
static LinearProblemStatus convertResultStatus(MPSolver.ResultStatus status) {
@@ -237,7 +248,8 @@ static double roundDouble(double value) {
return 0.;
}
double t = value * (1L << NUMBER_OF_BITS_TO_ROUND_OFF);
- if (t != Double.POSITIVE_INFINITY && value != Double.NEGATIVE_INFINITY && !Double.isNaN(t)) {
+ if (t != Double.POSITIVE_INFINITY && value != Double.NEGATIVE_INFINITY && !Double.isNaN(
+ t)) {
return value - t + t;
}
return value;
diff --git a/sensitivity-analysis/src/main/java/com/powsybl/openrao/sensitivityanalysis/SystematicSensitivityInterface.java b/sensitivity-analysis/src/main/java/com/powsybl/openrao/sensitivityanalysis/SystematicSensitivityInterface.java
index e2c54aa81d..0bc732d6b5 100644
--- a/sensitivity-analysis/src/main/java/com/powsybl/openrao/sensitivityanalysis/SystematicSensitivityInterface.java
+++ b/sensitivity-analysis/src/main/java/com/powsybl/openrao/sensitivityanalysis/SystematicSensitivityInterface.java
@@ -7,21 +7,22 @@
package com.powsybl.openrao.sensitivityanalysis;
+import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.BUSINESS_WARNS;
+import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.TECHNICAL_LOGS;
+
+import com.powsybl.glsk.commons.ZonalData;
+import com.powsybl.iidm.network.Network;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.Unit;
-import com.powsybl.glsk.commons.ZonalData;
+import com.powsybl.openrao.commons.opentelemetry.OpenTelemetryReporter;
import com.powsybl.openrao.data.crac.api.Instant;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.openrao.data.crac.api.rangeaction.RangeAction;
-import com.powsybl.iidm.network.Network;
import com.powsybl.sensitivity.SensitivityAnalysisParameters;
import com.powsybl.sensitivity.SensitivityVariableSet;
-
import java.util.Objects;
import java.util.Set;
-import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.*;
-
/**
* An interface with the engine that computes sensitivities and flows needed in the RAO.
*
@@ -30,6 +31,7 @@
* @author Baptiste Seguinot {@literal }
*/
public final class SystematicSensitivityInterface {
+
/**
* Name of sensitivity analysis provider
*/
@@ -55,6 +57,7 @@ public final class SystematicSensitivityInterface {
* Builder
*/
public static final class SystematicSensitivityInterfaceBuilder {
+
private String sensitivityProvider;
private SensitivityAnalysisParameters defaultParameters;
private final MultipleSensitivityProvider multipleSensitivityProvider = new MultipleSensitivityProvider();
@@ -66,17 +69,20 @@ private SystematicSensitivityInterfaceBuilder() {
}
- public SystematicSensitivityInterfaceBuilder withSensitivityProviderName(String sensitivityProvider) {
+ public SystematicSensitivityInterfaceBuilder withSensitivityProviderName(
+ String sensitivityProvider) {
this.sensitivityProvider = sensitivityProvider;
return this;
}
- public SystematicSensitivityInterfaceBuilder withParameters(SensitivityAnalysisParameters defaultParameters) {
+ public SystematicSensitivityInterfaceBuilder withParameters(
+ SensitivityAnalysisParameters defaultParameters) {
this.defaultParameters = defaultParameters;
return this;
}
- public SystematicSensitivityInterfaceBuilder withSensitivityProvider(CnecSensitivityProvider cnecSensitivityProvider) {
+ public SystematicSensitivityInterfaceBuilder withSensitivityProvider(
+ CnecSensitivityProvider cnecSensitivityProvider) {
if (Objects.isNull(cnecSensitivityProvider)) {
throw new OpenRaoException("Null sensitivity provider.");
}
@@ -85,26 +91,32 @@ public SystematicSensitivityInterfaceBuilder withSensitivityProvider(CnecSensiti
return this;
}
- public SystematicSensitivityInterfaceBuilder withPtdfSensitivities(ZonalData glsk, Set cnecs, Set units) {
+ public SystematicSensitivityInterfaceBuilder withPtdfSensitivities(
+ ZonalData glsk, Set cnecs, Set units) {
return this.withSensitivityProvider(new PtdfSensitivityProvider(glsk, cnecs, units));
}
- public SystematicSensitivityInterfaceBuilder withRangeActionSensitivities(Set> rangeActions, Set cnecs, Set units) {
- return this.withSensitivityProvider(new RangeActionSensitivityProvider(rangeActions, cnecs, units));
+ public SystematicSensitivityInterfaceBuilder withRangeActionSensitivities(
+ Set> rangeActions, Set cnecs, Set units) {
+ return this.withSensitivityProvider(
+ new RangeActionSensitivityProvider(rangeActions, cnecs, units));
}
- public SystematicSensitivityInterfaceBuilder withLoadflow(Set cnecs, Set units) {
+ public SystematicSensitivityInterfaceBuilder withLoadflow(Set cnecs,
+ Set units) {
return this.withSensitivityProvider(new LoadflowProvider(cnecs, units));
}
- public SystematicSensitivityInterfaceBuilder withAppliedRemedialActions(AppliedRemedialActions appliedRemedialActions) {
+ public SystematicSensitivityInterfaceBuilder withAppliedRemedialActions(
+ AppliedRemedialActions appliedRemedialActions) {
this.appliedRemedialActions = appliedRemedialActions;
return this;
}
public SystematicSensitivityInterfaceBuilder withOutageInstant(Instant outageInstant) {
if (!outageInstant.isOutage()) {
- throw new OpenRaoException("Instant provided in the systematic sensitivity builder has to be an outage");
+ throw new OpenRaoException(
+ "Instant provided in the systematic sensitivity builder has to be an outage");
}
this.outageInstant = outageInstant;
return this;
@@ -112,7 +124,8 @@ public SystematicSensitivityInterfaceBuilder withOutageInstant(Instant outageIns
public SystematicSensitivityInterface build() {
if (Objects.isNull(sensitivityProvider)) {
- throw new OpenRaoException("Please provide a sensitivity provider implementation name when building a SystematicSensitivityInterface");
+ throw new OpenRaoException(
+ "Please provide a sensitivity provider implementation name when building a SystematicSensitivityInterface");
}
if (!providerInitialised) {
throw new OpenRaoException("Sensitivity provider has not been initialized");
@@ -121,7 +134,8 @@ public SystematicSensitivityInterface build() {
defaultParameters = new SensitivityAnalysisParameters();
}
if (Objects.isNull(outageInstant)) {
- throw new OpenRaoException("Outage instant has not been defined in the systematic sensitivity interface");
+ throw new OpenRaoException(
+ "Outage instant has not been defined in the systematic sensitivity interface");
}
SystematicSensitivityInterface systematicSensitivityInterface = new SystematicSensitivityInterface();
systematicSensitivityInterface.sensitivityProvider = sensitivityProvider;
@@ -146,11 +160,13 @@ public static SystematicSensitivityInterfaceBuilder builder() {
* SystematicSensitivityResult to the given network variant.
*/
public SystematicSensitivityResult run(Network network) {
- SystematicSensitivityResult result = runWithConfig(network);
- if (!result.isSuccess()) {
- BUSINESS_WARNS.warn("Sensitivity analysis failed.");
- }
- return result;
+ return OpenTelemetryReporter.withSpan("rao.systematicSA.run", cx -> {
+ SystematicSensitivityResult result = runWithConfig(network);
+ if (!result.isSuccess()) {
+ BUSINESS_WARNS.warn("Sensitivity analysis failed.");
+ }
+ return result;
+ });
}
/**
@@ -163,7 +179,8 @@ private SystematicSensitivityResult runWithConfig(Network network) {
return new SystematicSensitivityResult();
}
SystematicSensitivityResult tempSystematicSensitivityAnalysisResult = SystematicSensitivityAdapter
- .runSensitivity(network, cnecSensitivityProvider, appliedRemedialActions, parameters, sensitivityProvider, outageInstant);
+ .runSensitivity(network, cnecSensitivityProvider, appliedRemedialActions, parameters,
+ sensitivityProvider, outageInstant);
if (!tempSystematicSensitivityAnalysisResult.isSuccess()) {
TECHNICAL_LOGS.error("Sensitivity analysis failed: no output data available.");
diff --git a/util/src/main/java/com/powsybl/openrao/util/MultipleNetworkPool.java b/util/src/main/java/com/powsybl/openrao/util/MultipleNetworkPool.java
index 24b5490194..70598ab890 100644
--- a/util/src/main/java/com/powsybl/openrao/util/MultipleNetworkPool.java
+++ b/util/src/main/java/com/powsybl/openrao/util/MultipleNetworkPool.java
@@ -7,11 +7,13 @@
package com.powsybl.openrao.util;
+import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.TECHNICAL_LOGS;
+
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.VariantManagerConstants;
import com.powsybl.iidm.serde.NetworkSerDe;
import com.powsybl.openrao.commons.OpenRaoException;
-
+import com.powsybl.openrao.commons.opentelemetry.OpenTelemetryReporter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -19,8 +21,6 @@
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.atomic.AtomicInteger;
-import static com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider.TECHNICAL_LOGS;
-
/**
* @author Sebastien Murgey {@literal }
*/
@@ -28,7 +28,8 @@ public class MultipleNetworkPool extends AbstractNetworkPool {
private int networkNumberOfClones = 0;
- protected MultipleNetworkPool(Network network, String targetVariant, int parallelism, boolean initClones) {
+ protected MultipleNetworkPool(Network network, String targetVariant, int parallelism,
+ boolean initClones) {
super(network, targetVariant, parallelism);
if (initClones) {
initClones(parallelism);
@@ -41,7 +42,8 @@ protected void cleanVariants(Network networkClone) {
.filter(variantId -> !variantId.equals(VariantManagerConstants.INITIAL_VARIANT_ID))
.filter(variantId -> !variantId.equals(stateSaveVariant))
.toList();
- variantsToBeRemoved.forEach(variantId -> networkClone.getVariantManager().removeVariant(variantId));
+ variantsToBeRemoved.forEach(
+ variantId -> networkClone.getVariantManager().removeVariant(variantId));
}
@Override
@@ -52,41 +54,47 @@ public int getNetworkNumberOfClones() {
@Override
public void initClones(int desiredNumberOfClones) {
- int requiredClones = Math.min(getParallelism(), desiredNumberOfClones);
- int clonesToAdd = requiredClones - networkNumberOfClones;
+ OpenTelemetryReporter.withSpan("rao.multipleNetworkPool.initClones", cx -> {
+ int requiredClones = Math.min(getParallelism(), desiredNumberOfClones);
+ int clonesToAdd = requiredClones - networkNumberOfClones;
- if (clonesToAdd == 0) {
- return;
- }
+ if (clonesToAdd == 0) {
+ return;
+ }
- TECHNICAL_LOGS.debug("Filling network pool with {} new cop{} of network {} on variant {}", clonesToAdd, clonesToAdd == 1 ? "y" : "ies", network.getId(), targetVariant);
+ TECHNICAL_LOGS.debug(
+ "Filling network pool with {} new cop{} of network {} on variant {}",
+ clonesToAdd, clonesToAdd == 1 ? "y" : "ies", network.getId(), targetVariant);
- String initialVariant = network.getVariantManager().getWorkingVariantId();
- network.getVariantManager().setWorkingVariant(targetVariant);
+ String initialVariant = network.getVariantManager().getWorkingVariantId();
+ network.getVariantManager().setWorkingVariant(targetVariant);
- AtomicInteger remainingClones = new AtomicInteger(requiredClones);
- List> tasks = new ArrayList<>();
- try {
- for (int i = networkNumberOfClones; i < requiredClones; i++) {
- int finalI = i;
- tasks.add(this.submit(() -> createNetworkCopy(finalI, remainingClones)));
- }
- for (ForkJoinTask task : tasks) {
- try {
- boolean isSuccess = networksQueue.offer(task.get());
- if (!isSuccess) {
- throw new OpenRaoException(String.format("Cannot offer copy n°'%d' in pool. Should not happen", networkNumberOfClones + 1));
- } else {
- networkNumberOfClones++;
+ AtomicInteger remainingClones = new AtomicInteger(requiredClones);
+ List> tasks = new ArrayList<>();
+ try {
+ for (int i = networkNumberOfClones; i < requiredClones; i++) {
+ int finalI = i;
+ tasks.add(this.submit(() -> createNetworkCopy(finalI, remainingClones)));
+ }
+ for (ForkJoinTask task : tasks) {
+ try {
+ boolean isSuccess = networksQueue.offer(task.get());
+ if (!isSuccess) {
+ throw new OpenRaoException(
+ String.format("Cannot offer copy n°'%d' in pool. Should not happen",
+ networkNumberOfClones + 1));
+ } else {
+ networkNumberOfClones++;
+ }
+ } catch (ExecutionException e) {
+ throw new OpenRaoException(e);
}
- } catch (ExecutionException e) {
- throw new OpenRaoException(e);
}
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
}
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- network.getVariantManager().setWorkingVariant(initialVariant);
+ network.getVariantManager().setWorkingVariant(initialVariant);
+ });
}
private Network createNetworkCopy(int finalI, AtomicInteger remainingClones) {
@@ -94,8 +102,10 @@ private Network createNetworkCopy(int finalI, AtomicInteger remainingClones) {
Network copy = NetworkSerDe.copy(network);
// The initial network working variant is VariantManagerConstants.INITIAL_VARIANT_ID
// in cloned network, so we need to copy it again.
- copy.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, Arrays.asList(stateSaveVariant, workingVariant), true);
+ copy.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID,
+ Arrays.asList(stateSaveVariant, workingVariant), true);
remainingClones.decrementAndGet();
return copy;
}
}
+
diff --git a/util/src/test/java/com/powsybl/openrao/util/NetworkPoolTest.java b/util/src/test/java/com/powsybl/openrao/util/NetworkPoolTest.java
index dfb182da89..888498e585 100644
--- a/util/src/test/java/com/powsybl/openrao/util/NetworkPoolTest.java
+++ b/util/src/test/java/com/powsybl/openrao/util/NetworkPoolTest.java
@@ -7,26 +7,31 @@
package com.powsybl.openrao.util;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import com.powsybl.iidm.network.Network;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.slf4j.LoggerFactory;
-import org.slf4j.MDC;
-
+import com.powsybl.openrao.commons.opentelemetry.OpenTelemetryReporter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-
-import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
/**
* @author Sebastien Murgey {@literal }
*/
class NetworkPoolTest {
+
private Network network;
private String initialVariant;
private String otherVariant = "otherVariant";
@@ -40,20 +45,24 @@ public void setUp() {
@Test
void testCreate() {
- assertTrue(AbstractNetworkPool.create(network, otherVariant, 10, true) instanceof MultipleNetworkPool);
- assertTrue(AbstractNetworkPool.create(network, otherVariant, 1, true) instanceof SingleNetworkPool);
+ assertTrue(AbstractNetworkPool.create(network, otherVariant, 10,
+ true) instanceof MultipleNetworkPool);
+ assertTrue(AbstractNetworkPool.create(network, otherVariant, 1,
+ true) instanceof SingleNetworkPool);
}
@Test
void networkPoolUsageTest() {
- try (AbstractNetworkPool pool = AbstractNetworkPool.create(network, otherVariant, 10, false)) {
+ try (AbstractNetworkPool pool = AbstractNetworkPool.create(network, otherVariant, 10,
+ false)) {
pool.initClones(4);
Network networkCopy = pool.getAvailableNetwork();
assertNotNull(networkCopy);
assertNotEquals(network, networkCopy);
- assertTrue(networkCopy.getVariantManager().getWorkingVariantId().startsWith("OpenRaoNetworkPool working variant"));
+ assertTrue(networkCopy.getVariantManager().getWorkingVariantId()
+ .startsWith("OpenRaoNetworkPool working variant"));
pool.initClones(1);
assertNotEquals(network, pool.getAvailableNetwork());
@@ -73,7 +82,8 @@ void singleNetworkPoolUsageTest() throws InterruptedException {
assertNotNull(networkCopy);
assertEquals(network, networkCopy);
assertEquals(4, network.getVariantManager().getVariantIds().size());
- assertTrue(networkCopy.getVariantManager().getWorkingVariantId().startsWith("OpenRaoNetworkPool working variant"));
+ assertTrue(networkCopy.getVariantManager().getWorkingVariantId()
+ .startsWith("OpenRaoNetworkPool working variant"));
pool.releaseUsedNetwork(networkCopy);
@@ -88,19 +98,22 @@ void checkMDCIsCopied() throws InterruptedException {
listAppender.start();
logger.addAppender(listAppender);
- MDC.put("extrafield", "value from caller");
- AbstractNetworkPool pool = AbstractNetworkPool.create(network, otherVariant, 20, true);
- for (int i = 0; i < 20; i++) {
- pool.submit(() -> {
- LoggerFactory.getLogger("LOGGER").info("Hello from forked thread");
- });
- }
- pool.shutdownAndAwaitTermination(1, TimeUnit.SECONDS);
+ OpenTelemetryReporter.withSpan("checkMDCIsCopied", cx -> {
+ MDC.put("extrafield", "value from caller");
+ AbstractNetworkPool pool = AbstractNetworkPool.create(network, otherVariant, 20, true);
+ for (int i = 0; i < 20; i++) {
+ pool.submit(() -> {
+ LoggerFactory.getLogger("LOGGER").info("Hello from forked thread");
+ });
+ }
+ pool.shutdownAndAwaitTermination(1, TimeUnit.SECONDS);
+ });
List logsList = listAppender.list;
for (int i = 0; i < 20; i++) {
assertTrue(logsList.get(i).getMDCPropertyMap().containsKey("extrafield"));
- assertEquals("value from caller", logsList.get(i).getMDCPropertyMap().get("extrafield"));
+ assertEquals("value from caller",
+ logsList.get(i).getMDCPropertyMap().get("extrafield"));
}
}