From 1664247b85fba001bab62ec116b99161fd6d4fef Mon Sep 17 00:00:00 2001 From: Peter Mitri Date: Tue, 1 Oct 2024 17:40:17 +0200 Subject: [PATCH 1/2] [MIP] Remove ProblemFiller::updateBetweenSensiIteration() method (#1106) * Remove ProblemFiller::updateBetweenSensiIteration() method Signed-off-by: Peter Mitri --- .../ContinuousRangeActionGroupFiller.java | 7 +- .../algorithms/fillers/CoreProblemFiller.java | 79 ++++++------------- .../fillers/DiscretePstGroupFiller.java | 24 ++---- .../fillers/DiscretePstTapFiller.java | 26 +++--- .../algorithms/fillers/MaxLoopFlowFiller.java | 41 ++-------- .../fillers/MaxMinMarginFiller.java | 7 +- .../fillers/MaxMinRelativeMarginFiller.java | 26 +++--- .../algorithms/fillers/MnecFiller.java | 7 +- .../algorithms/fillers/ProblemFiller.java | 4 +- .../fillers/RaUsageLimitsFiller.java | 7 +- .../fillers/UnoptimizedCnecFiller.java | 7 +- .../linearproblem/LinearProblem.java | 11 ++- .../linearproblem/LinearProblemBuilder.java | 19 +++-- .../fillers/AbstractFillerTest.java | 13 +++ .../ContinuousRangeActionGroupFillerTest.java | 4 +- .../fillers/CoreProblemFillerTest.java | 37 ++++++++- .../fillers/DiscretePstGroupFillerTest.java | 14 ++-- .../fillers/DiscretePstTapFillerTest.java | 5 +- .../fillers/MaxLoopFlowFillerTest.java | 4 +- .../fillers/MaxMinMarginFillerTest.java | 5 +- .../MaxMinRelativeMarginFillerTest.java | 10 +-- .../algorithms/fillers/MnecFillerTest.java | 2 - .../fillers/RaUsageLimitsFillerTest.java | 11 +-- ...mizedCnecFillerMarginDecreaseRuleTest.java | 4 +- 24 files changed, 156 insertions(+), 218 deletions(-) diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/ContinuousRangeActionGroupFiller.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/ContinuousRangeActionGroupFiller.java index 058dba16ce..afcb7c6e68 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/ContinuousRangeActionGroupFiller.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/ContinuousRangeActionGroupFiller.java @@ -32,15 +32,10 @@ public ContinuousRangeActionGroupFiller(Map>> rangeAct } @Override - public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult) { + public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { buildRangeActionGroupConstraint(linearProblem); } - @Override - public void updateBetweenSensiIteration(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { - // nothing to do - } - @Override public void updateBetweenMipIteration(LinearProblem linearProblem, RangeActionActivationResult rangeActionActivationResult) { // nothing to do diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/CoreProblemFiller.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/CoreProblemFiller.java index 11f9388e46..9781309c97 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/CoreProblemFiller.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/CoreProblemFiller.java @@ -43,7 +43,6 @@ public class CoreProblemFiller implements ProblemFiller { private final OptimizationPerimeter optimizationContext; private final Set flowCnecs; private final RangeActionSetpointResult prePerimeterRangeActionSetpoints; - private final RangeActionActivationResult raActivationFromParentLeaf; private final RangeActionsOptimizationParameters rangeActionParameters; private final Unit unit; private int iteration = 0; @@ -54,7 +53,6 @@ public class CoreProblemFiller implements ProblemFiller { public CoreProblemFiller(OptimizationPerimeter optimizationContext, RangeActionSetpointResult prePerimeterRangeActionSetpoints, - RangeActionActivationResult raActivationFromParentLeaf, RangeActionsOptimizationParameters rangeActionParameters, Unit unit, boolean raRangeShrinking, @@ -63,7 +61,6 @@ public CoreProblemFiller(OptimizationPerimeter optimizationContext, this.flowCnecs = new TreeSet<>(Comparator.comparing(Identifiable::getId)); this.flowCnecs.addAll(optimizationContext.getFlowCnecs()); this.prePerimeterRangeActionSetpoints = prePerimeterRangeActionSetpoints; - this.raActivationFromParentLeaf = raActivationFromParentLeaf; this.rangeActionParameters = rangeActionParameters; this.unit = unit; this.raRangeShrinking = raRangeShrinking; @@ -71,7 +68,7 @@ public CoreProblemFiller(OptimizationPerimeter optimizationContext, } @Override - public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult) { + public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { Set validFlowCnecs = FillersUtil.getFlowCnecsComputationStatusOk(flowCnecs, sensitivityResult); // add variables @@ -79,24 +76,15 @@ public void fill(LinearProblem linearProblem, FlowResult flowResult, Sensitivity buildRangeActionVariables(linearProblem); // add constraints - buildFlowConstraints(linearProblem, validFlowCnecs, flowResult, sensitivityResult); + buildFlowConstraints(linearProblem, validFlowCnecs, flowResult, sensitivityResult, rangeActionActivationResult); buildRangeActionConstraints(linearProblem); + checkAndActivateRangeShrinking(linearProblem, rangeActionActivationResult); // complete objective fillObjectiveWithRangeActionPenaltyCost(linearProblem); } - @Override - public void updateBetweenSensiIteration(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { - // update reference flow and sensitivities of flow constraints - Set validFlowCnecs = FillersUtil.getFlowCnecsComputationStatusOk(flowCnecs, sensitivityResult); - updateFlowConstraints(linearProblem, validFlowCnecs, flowResult, sensitivityResult, rangeActionActivationResult); - if (raRangeShrinking) { - updateRangeActionConstraints(linearProblem, rangeActionActivationResult); - } - } - @Override public void updateBetweenMipIteration(LinearProblem linearProblem, RangeActionActivationResult rangeActionActivationResult) { // nothing to do @@ -120,11 +108,10 @@ private void buildFlowVariables(LinearProblem linearProblem, Set valid *
  • in MEGAWATT for HVDC range actions
  • *
  • in MEGAWATT for Injection range actions
  • * - * + *

    * Build one absolute variation variable AV[r] for each RangeAction r * This variable describes the absolute difference between the range action setpoint * and its initial value. It is given in the same unit as S[r]. - * */ private void buildRangeActionVariables(LinearProblem linearProblem) { optimizationContext.getRangeActionsPerState().forEach((state, rangeActions) -> @@ -141,7 +128,7 @@ private void buildRangeActionVariables(LinearProblem linearProblem) { * on this Cnec. * F[c] = f_ref[c] + sum{r in RangeAction} sensitivity[c,r] * (S[r] - currentSetPoint[r]) */ - private void buildFlowConstraints(LinearProblem linearProblem, Set validFlowCnecs, FlowResult flowResult, SensitivityResult sensitivityResult) { + private void buildFlowConstraints(LinearProblem linearProblem, Set validFlowCnecs, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { validFlowCnecs.forEach(cnec -> cnec.getMonitoredSides().forEach(side -> { // create constraint double referenceFlow = flowResult.getFlow(cnec, side, unit) * RaoUtil.getFlowUnitMultiplier(cnec, side, unit, Unit.MEGAWATT); @@ -151,24 +138,6 @@ private void buildFlowConstraints(LinearProblem linearProblem, Set val flowConstraint.setCoefficient(flowVariable, 1); // add sensitivity coefficients - addImpactOfRangeActionOnCnec(linearProblem, sensitivityResult, cnec, side, raActivationFromParentLeaf); - })); - } - - /** - * Update the flow constraints, with the new reference flows and new sensitivities - * F[c] = f_ref[c] + sum{r in RangeAction} sensitivity[c,r] * (S[r] - currentSetPoint[r]) - */ - private void updateFlowConstraints(LinearProblem linearProblem, Set validFlowCnecs, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { - validFlowCnecs.forEach(cnec -> cnec.getMonitoredSides().forEach(side -> { - double referenceFlow = flowResult.getFlow(cnec, side, unit) * RaoUtil.getFlowUnitMultiplier(cnec, side, unit, Unit.MEGAWATT); - OpenRaoMPConstraint flowConstraint = linearProblem.getFlowConstraint(cnec, side); - - //reset bounds - flowConstraint.setUb(referenceFlow); - flowConstraint.setLb(referenceFlow); - - //reset sensitivity coefficients addImpactOfRangeActionOnCnec(linearProblem, sensitivityResult, cnec, side, rangeActionActivationResult); })); } @@ -196,23 +165,20 @@ private void addImpactOfRangeActionOnCnec(LinearProblem linearProblem, Sensitivi } private void addImpactOfRangeActionOnCnec(LinearProblem linearProblem, SensitivityResult sensitivityResult, RangeAction rangeAction, State state, FlowCnec cnec, TwoSides side, OpenRaoMPConstraint flowConstraint, RangeActionActivationResult rangeActionActivationResult) { - OpenRaoMPVariable setPointVariable = linearProblem.getRangeActionSetpointVariable(rangeAction, state); - double sensitivity = sensitivityResult.getSensitivityValue(cnec, side, rangeAction, Unit.MEGAWATT); - if (isRangeActionSensitivityAboveThreshold(rangeAction, Math.abs(sensitivity))) { - double currentSetPoint = rangeActionActivationResult.getOptimizedSetpoint(rangeAction, state); + if (!isRangeActionSensitivityAboveThreshold(rangeAction, Math.abs(sensitivity))) { + // don't consider this RA's impact on this CNEC + return; + } - // care : might not be robust as getCurrentValue get the current setPoint from a network variant - // we need to be sure that this variant has been properly set - flowConstraint.setLb(flowConstraint.lb() - sensitivity * currentSetPoint); - flowConstraint.setUb(flowConstraint.ub() - sensitivity * currentSetPoint); + OpenRaoMPVariable setPointVariable = linearProblem.getRangeActionSetpointVariable(rangeAction, state); + double currentSetPoint = rangeActionActivationResult.getOptimizedSetpoint(rangeAction, state); - flowConstraint.setCoefficient(setPointVariable, -sensitivity); - } else { - // We need to do this in case of an update - flowConstraint.setCoefficient(setPointVariable, 0); - } + flowConstraint.setLb(flowConstraint.lb() - sensitivity * currentSetPoint); + flowConstraint.setUb(flowConstraint.ub() - sensitivity * currentSetPoint); + + flowConstraint.setCoefficient(setPointVariable, -sensitivity); } private boolean isRangeActionSensitivityAboveThreshold(RangeAction rangeAction, double sensitivity) { @@ -234,13 +200,18 @@ private void buildRangeActionConstraints(LinearProblem linearProblem) { entry.getValue().forEach(rangeAction -> buildConstraintsForRangeActionAndState(linearProblem, rangeAction, entry.getKey()))); } - private void updateRangeActionConstraints(LinearProblem linearProblem, RangeActionActivationResult rangeActionActivationResult) { + private void checkAndActivateRangeShrinking(LinearProblem linearProblem, RangeActionActivationResult rangeActionActivationResult) { + if (!raRangeShrinking) { + return; + } + if (iteration > 0) { + // don't shrink the range for the first iteration + optimizationContext.getRangeActionsPerState().forEach((state, rangeActionSet) -> rangeActionSet.forEach(rangeAction -> updateConstraintsForRangeAction(linearProblem, rangeAction, state, rangeActionActivationResult, iteration))); + } iteration++; - optimizationContext.getRangeActionsPerState().forEach((state, rangeActionSet) -> rangeActionSet.forEach(rangeAction -> updateConstraintsForRangeAction(linearProblem, rangeAction, state, rangeActionActivationResult, iteration) - )); } - private void updateConstraintsForRangeAction(LinearProblem linearProblem, RangeAction rangeAction, State state, RangeActionActivationResult rangeActionActivationResult, int iteration) { + private static void updateConstraintsForRangeAction(LinearProblem linearProblem, RangeAction rangeAction, State state, RangeActionActivationResult rangeActionActivationResult, int iteration) { double previousSetPointValue = rangeActionActivationResult.getOptimizedSetpoint(rangeAction, state); List minAndMaxAbsoluteAndRelativeSetpoints = getMinAndMaxAbsoluteAndRelativeSetpoints(rangeAction, linearProblem.infinity()); double minAbsoluteSetpoint = minAndMaxAbsoluteAndRelativeSetpoints.get(0); @@ -341,7 +312,7 @@ private void buildConstraintsForRangeActionAndState(LinearProblem linearProblem, } } - private List getMinAndMaxAbsoluteAndRelativeSetpoints(RangeAction rangeAction, double infinity) { + private static List getMinAndMaxAbsoluteAndRelativeSetpoints(RangeAction rangeAction, double infinity) { // if relative to previous instant range double minAbsoluteSetpoint = -infinity; diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstGroupFiller.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstGroupFiller.java index ba3abf046f..19be50307c 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstGroupFiller.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstGroupFiller.java @@ -15,7 +15,6 @@ import com.powsybl.openrao.searchtreerao.result.api.FlowResult; import com.powsybl.openrao.searchtreerao.result.api.RangeActionActivationResult; import com.powsybl.openrao.searchtreerao.result.api.SensitivityResult; -import com.powsybl.iidm.network.Network; import java.util.Map; import java.util.Optional; @@ -28,25 +27,16 @@ public class DiscretePstGroupFiller implements ProblemFiller { private final State optimizedState; private final Map> pstRangeActions; - private final Network network; - public DiscretePstGroupFiller(Network network, State optimizedState, Map> pstRangeActions) { + public DiscretePstGroupFiller(State optimizedState, Map> pstRangeActions) { this.pstRangeActions = pstRangeActions; - this.network = network; this.optimizedState = optimizedState; } @Override - public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult) { + public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { pstRangeActions.forEach((state, rangeActionSet) -> rangeActionSet.forEach(rangeAction -> - buildRangeActionGroupConstraint(linearProblem, rangeAction, state) - )); - } - - @Override - public void updateBetweenSensiIteration(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { - pstRangeActions.forEach((state, rangeActionSet) -> rangeActionSet.forEach(rangeAction -> - updateRangeActionGroupConstraint(linearProblem, rangeAction, state, rangeActionActivationResult) + buildRangeActionGroupConstraint(linearProblem, rangeAction, state, rangeActionActivationResult) )); } @@ -57,7 +47,7 @@ public void updateBetweenMipIteration(LinearProblem linearProblem, RangeActionAc )); } - private void buildRangeActionGroupConstraint(LinearProblem linearProblem, PstRangeAction pstRangeAction, State state) { + private void buildRangeActionGroupConstraint(LinearProblem linearProblem, PstRangeAction pstRangeAction, State state, RangeActionActivationResult rangeActionActivationResult) { Optional optGroupId = pstRangeAction.getGroupId(); if (optGroupId.isPresent()) { String groupId = optGroupId.get(); @@ -67,12 +57,12 @@ private void buildRangeActionGroupConstraint(LinearProblem linearProblem, PstRan } catch (OpenRaoException ignored) { linearProblem.addPstGroupTapVariable(-linearProblem.infinity(), linearProblem.infinity(), groupId, state); } - addRangeActionGroupConstraint(linearProblem, pstRangeAction, groupId, state); + addRangeActionGroupConstraint(linearProblem, pstRangeAction, groupId, state, rangeActionActivationResult); } } - private void addRangeActionGroupConstraint(LinearProblem linearProblem, PstRangeAction pstRangeAction, String groupId, State state) { - double currentTap = pstRangeAction.getCurrentTapPosition(network); + private void addRangeActionGroupConstraint(LinearProblem linearProblem, PstRangeAction pstRangeAction, String groupId, State state, RangeActionActivationResult rangeActionActivationResult) { + double currentTap = rangeActionActivationResult.getOptimizedTap(pstRangeAction, optimizedState); OpenRaoMPConstraint groupSetPointConstraint = linearProblem.addPstGroupTapConstraint(currentTap, currentTap, pstRangeAction, state); groupSetPointConstraint.setCoefficient(linearProblem.getPstTapVariationVariable(pstRangeAction, state, LinearProblem.VariationDirectionExtension.UPWARD), -1); groupSetPointConstraint.setCoefficient(linearProblem.getPstTapVariationVariable(pstRangeAction, state, LinearProblem.VariationDirectionExtension.DOWNWARD), 1); diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstTapFiller.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstTapFiller.java index 430c6c0832..8a56771d1d 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstTapFiller.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstTapFiller.java @@ -21,7 +21,6 @@ import com.powsybl.openrao.searchtreerao.result.api.RangeActionActivationResult; import com.powsybl.openrao.searchtreerao.result.api.RangeActionSetpointResult; import com.powsybl.openrao.searchtreerao.result.api.SensitivityResult; -import com.powsybl.iidm.network.Network; import org.apache.commons.lang3.tuple.Pair; import java.util.*; @@ -31,31 +30,28 @@ */ public class DiscretePstTapFiller implements ProblemFiller { - private final Network network; private final OptimizationPerimeter optimizationPerimeter; private final Map> rangeActions; private final RangeActionSetpointResult prePerimeterRangeActionSetpoints; + private int iteration = 0; - public DiscretePstTapFiller(Network network, - OptimizationPerimeter optimizationPerimeter, + public DiscretePstTapFiller(OptimizationPerimeter optimizationPerimeter, Map> rangeActions, RangeActionSetpointResult prePerimeterRangeActionSetpoints) { - this.network = network; this.optimizationPerimeter = optimizationPerimeter; this.rangeActions = rangeActions; this.prePerimeterRangeActionSetpoints = prePerimeterRangeActionSetpoints; } @Override - public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult) { + public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { + iteration++; rangeActions.entrySet().stream() .sorted(Comparator.comparingInt(e -> e.getKey().getInstant().getOrder())).forEach(entry -> entry.getValue().forEach(rangeAction -> - buildPstTapVariablesAndConstraints(linearProblem, rangeAction, entry.getKey()))); - } - - @Override - public void updateBetweenSensiIteration(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { - update(linearProblem, rangeActionActivationResult); + buildPstTapVariablesAndConstraints(linearProblem, rangeAction, entry.getKey(), rangeActionActivationResult))); + if (iteration > 1) { + update(linearProblem, rangeActionActivationResult); + } } @Override @@ -72,11 +68,11 @@ private void update(LinearProblem linearProblem, RangeActionActivationResult ran updateRelativeRangeConstraints(linearProblem, rangeAction, entry.getKey(), rangeActionActivationResult))); } - private void buildPstTapVariablesAndConstraints(LinearProblem linearProblem, PstRangeAction pstRangeAction, State state) { + private void buildPstTapVariablesAndConstraints(LinearProblem linearProblem, PstRangeAction pstRangeAction, State state, RangeActionActivationResult rangeActionActivationResult) { // compute a few values on PST taps and angle - double currentAngle = pstRangeAction.getCurrentSetpoint(network); - int currentTap = pstRangeAction.getCurrentTapPosition(network); + double currentAngle = rangeActionActivationResult.getOptimizedSetpoint(pstRangeAction, state); + int currentTap = rangeActionActivationResult.getOptimizedTap(pstRangeAction, state); Pair, State> lastAvailableRangeAction = RaoUtil.getLastAvailableRangeActionOnSameNetworkElement(optimizationPerimeter, pstRangeAction, state); Pair admissibleTaps = getMinAndMaxAdmissibleTaps(pstRangeAction, lastAvailableRangeAction); diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxLoopFlowFiller.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxLoopFlowFiller.java index 66aa013402..9b130faa75 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxLoopFlowFiller.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxLoopFlowFiller.java @@ -34,6 +34,7 @@ public class MaxLoopFlowFiller implements ProblemFiller { private final double loopFlowAcceptableAugmentation; private final double loopFlowViolationCost; private final double loopFlowConstraintAdjustmentCoefficient; + private FlowResult preOptimFlowResult; // = flow result used in the first "fill" iteration public MaxLoopFlowFiller(Set loopFlowCnecs, FlowResult initialFlowResult, LoopFlowParametersExtension loopFlowParameters) { this.loopFlowCnecs = new TreeSet<>(Comparator.comparing(Identifiable::getId)); @@ -50,13 +51,12 @@ private Set getValidLoopFlowCnecs(SensitivityResult sensitivityResult) } @Override - public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult) { - buildLoopFlowConstraintsAndUpdateObjectiveFunction(linearProblem, getValidLoopFlowCnecs(sensitivityResult), flowResult); - } - - @Override - public void updateBetweenSensiIteration(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { - updateLoopFlowConstraints(linearProblem, getValidLoopFlowCnecs(sensitivityResult), flowResult); + public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { + if (preOptimFlowResult == null) { + preOptimFlowResult = flowResult; + } + FlowResult flowResultToUse = loopFlowPtdfApproximationLevel.shouldUpdatePtdfWithPstChange() ? flowResult : preOptimFlowResult; + buildLoopFlowConstraintsAndUpdateObjectiveFunction(linearProblem, getValidLoopFlowCnecs(sensitivityResult), flowResultToUse); } @Override @@ -87,7 +87,6 @@ public void updateBetweenMipIteration(LinearProblem linearProblem, RangeActionAc * and a "virtual cost" is added to objective function as "loopflowViolationVariable * Loopflow violation cost" */ private void buildLoopFlowConstraintsAndUpdateObjectiveFunction(LinearProblem linearProblem, Set validLoopFlowCnecs, FlowResult flowResult) { - for (FlowCnec cnec : validLoopFlowCnecs) { for (TwoSides side : cnec.getMonitoredSides()) { @@ -138,32 +137,6 @@ private void buildLoopFlowConstraintsAndUpdateObjectiveFunction(LinearProblem li } } - /** - * Update LoopFlow constraints' bounds when commercial flows have changed - */ - private void updateLoopFlowConstraints(LinearProblem linearProblem, Set validLoopFlowCnecs, FlowResult flowResult) { - - if (!loopFlowPtdfApproximationLevel.shouldUpdatePtdfWithPstChange()) { - return; - } - - for (FlowCnec loopFlowCnec : validLoopFlowCnecs) { - for (TwoSides side : loopFlowCnec.getMonitoredSides()) { - double loopFlowUpperBound = getLoopFlowUpperBound(loopFlowCnec, side); - if (loopFlowUpperBound == Double.POSITIVE_INFINITY) { - continue; - } - double commercialFlow = flowResult.getCommercialFlow(loopFlowCnec, side, Unit.MEGAWATT); - - OpenRaoMPConstraint positiveLoopflowViolationConstraint = linearProblem.getMaxLoopFlowConstraint(loopFlowCnec, side, LinearProblem.BoundExtension.LOWER_BOUND); - positiveLoopflowViolationConstraint.setLb(-loopFlowUpperBound + commercialFlow); - - OpenRaoMPConstraint negativeLoopflowViolationConstraint = linearProblem.getMaxLoopFlowConstraint(loopFlowCnec, side, LinearProblem.BoundExtension.UPPER_BOUND); - negativeLoopflowViolationConstraint.setUb(loopFlowUpperBound + commercialFlow); - } - } - } - private double getLoopFlowUpperBound(FlowCnec loopFlowCnec, TwoSides side) { double loopFlowThreshold = loopFlowCnec.getExtension(LoopFlowThreshold.class).getThresholdWithReliabilityMargin(Unit.MEGAWATT); double initialLoopFlow = initialFlowResult.getLoopFlow(loopFlowCnec, side, Unit.MEGAWATT); diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinMarginFiller.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinMarginFiller.java index 346c9f5104..2a40c9a87d 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinMarginFiller.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinMarginFiller.java @@ -41,7 +41,7 @@ public MaxMinMarginFiller(Set optimizedCnecs, } @Override - public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult) { + public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { Set validFlowCnecs = FillersUtil.getFlowCnecsComputationStatusOk(optimizedCnecs, sensitivityResult); // build variables @@ -54,11 +54,6 @@ public void fill(LinearProblem linearProblem, FlowResult flowResult, Sensitivity fillObjectiveWithMinMargin(linearProblem); } - @Override - public void updateBetweenSensiIteration(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { - // Objective does not change, nothing to do - } - @Override public void updateBetweenMipIteration(LinearProblem linearProblem, RangeActionActivationResult rangeActionActivationResult) { // Objective does not change, nothing to do diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinRelativeMarginFiller.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinRelativeMarginFiller.java index 04c444af6f..bf5ad73f9a 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinRelativeMarginFiller.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinRelativeMarginFiller.java @@ -29,7 +29,7 @@ * @author Peter Mitri {@literal } */ public class MaxMinRelativeMarginFiller extends MaxMinMarginFiller { - private final FlowResult initialFlowResult; + private final FlowResult preOptimFlowResult; private final PtdfApproximation ptdfApproximationLevel; private final Unit unit; private final double ptdfSumLowerBound; @@ -38,11 +38,11 @@ public class MaxMinRelativeMarginFiller extends MaxMinMarginFiller { private final double maxNegativeRelativeRam; public MaxMinRelativeMarginFiller(Set optimizedCnecs, - FlowResult initialFlowResult, + FlowResult preOptimFlowResult, Unit unit, RelativeMarginsParametersExtension maxMinRelativeMarginParameters) { super(optimizedCnecs, unit); - this.initialFlowResult = initialFlowResult; + this.preOptimFlowResult = preOptimFlowResult; this.ptdfApproximationLevel = maxMinRelativeMarginParameters.getPtdfApproximation(); this.unit = unit; this.ptdfSumLowerBound = maxMinRelativeMarginParameters.getPtdfSumLowerBound(); @@ -52,25 +52,17 @@ public MaxMinRelativeMarginFiller(Set optimizedCnecs, } @Override - public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult) { - super.fill(linearProblem, flowResult, sensitivityResult); + public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { + super.fill(linearProblem, flowResult, sensitivityResult, rangeActionActivationResult); buildMinimumRelativeMarginSignBinaryVariable(linearProblem); updateMinimumNegativeMarginDefinition(linearProblem); Set validFlowCnecs = FillersUtil.getFlowCnecsComputationStatusOk(optimizedCnecs, sensitivityResult); buildMinimumRelativeMarginVariable(linearProblem, validFlowCnecs); - buildMinimumRelativeMarginConstraints(linearProblem, validFlowCnecs); + FlowResult flowResultToUse = ptdfApproximationLevel.shouldUpdatePtdfWithPstChange() ? flowResult : preOptimFlowResult; + buildMinimumRelativeMarginConstraints(linearProblem, validFlowCnecs, flowResultToUse); fillObjectiveWithMinRelMargin(linearProblem); } - @Override - public void updateBetweenSensiIteration(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { - if (ptdfApproximationLevel.shouldUpdatePtdfWithPstChange()) { - FillersUtil.getFlowCnecsComputationStatusOk(optimizedCnecs, sensitivityResult).forEach(cnec -> cnec.getMonitoredSides().forEach(side -> - setOrUpdateRelativeMarginCoefficients(linearProblem, flowResult, cnec, side) - )); - } - } - private void updateMinimumNegativeMarginDefinition(LinearProblem linearProblem) { OpenRaoMPVariable minimumMarginVariable = linearProblem.getMinimumMarginVariable(); OpenRaoMPVariable minRelMarginSignBinaryVariable = linearProblem.getMinimumRelativeMarginSignBinaryVariable(); @@ -109,7 +101,7 @@ private void buildMinimumRelativeMarginSignBinaryVariable(LinearProblem linearPr /** * Define the minimum relative margin (like absolute margin but by dividing by sum of PTDFs) */ - private void buildMinimumRelativeMarginConstraints(LinearProblem linearProblem, Set validFlowCnecs) { + private void buildMinimumRelativeMarginConstraints(LinearProblem linearProblem, Set validFlowCnecs, FlowResult flowResult) { OpenRaoMPVariable minRelMarginVariable = linearProblem.getMinimumRelativeMarginVariable(); OpenRaoMPVariable minRelMarginSignBinaryVariable = linearProblem.getMinimumRelativeMarginSignBinaryVariable(); @@ -121,7 +113,7 @@ private void buildMinimumRelativeMarginConstraints(LinearProblem linearProblem, minimumRelativeMarginSetToZero.setCoefficient(minRelMarginVariable, 1); validFlowCnecs.forEach(cnec -> cnec.getMonitoredSides().forEach(side -> - setOrUpdateRelativeMarginCoefficients(linearProblem, initialFlowResult, cnec, side) + setOrUpdateRelativeMarginCoefficients(linearProblem, flowResult, cnec, side) )); } diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MnecFiller.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MnecFiller.java index 11589d19c0..7b54cb331b 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MnecFiller.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MnecFiller.java @@ -47,18 +47,13 @@ public MnecFiller(FlowResult initialFlowResult, Set monitoredCnecs, Un } @Override - public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult) { + public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { Set validMonitoredCnecs = FillersUtil.getFlowCnecsComputationStatusOk(monitoredCnecs, sensitivityResult); buildMarginViolationVariable(linearProblem, validMonitoredCnecs); buildMnecMarginConstraints(linearProblem, validMonitoredCnecs); fillObjectiveWithMnecPenaltyCost(linearProblem, validMonitoredCnecs); } - @Override - public void updateBetweenSensiIteration(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { - // nothing to do - } - @Override public void updateBetweenMipIteration(LinearProblem linearProblem, RangeActionActivationResult rangeActionActivationResult) { // nothing to do diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/ProblemFiller.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/ProblemFiller.java index 3b7af7a764..92a5ce9750 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/ProblemFiller.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/ProblemFiller.java @@ -17,9 +17,7 @@ */ public interface ProblemFiller { - void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult); - - void updateBetweenSensiIteration(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult); + void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult); void updateBetweenMipIteration(LinearProblem linearProblem, RangeActionActivationResult rangeActionActivationResult); } diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/RaUsageLimitsFiller.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/RaUsageLimitsFiller.java index 1f4b5fbda4..20fb5139bc 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/RaUsageLimitsFiller.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/RaUsageLimitsFiller.java @@ -58,7 +58,7 @@ public RaUsageLimitsFiller(Map>> rangeActions, } @Override - public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult) { + public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { rangeActions.forEach((state, rangeActionSet) -> { if (!rangeActionLimitationParameters.areRangeActionLimitedForState(state)) { return; @@ -82,11 +82,6 @@ public void fill(LinearProblem linearProblem, FlowResult flowResult, Sensitivity }); } - @Override - public void updateBetweenSensiIteration(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { - // nothing to do, we are only comparing optimal and pre-perimeter setpoints - } - @Override public void updateBetweenMipIteration(LinearProblem linearProblem, RangeActionActivationResult rangeActionActivationResult) { rangeActions.forEach((state, rangeActionSet) -> { diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/UnoptimizedCnecFiller.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/UnoptimizedCnecFiller.java index c091c7a1cc..6851281a42 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/UnoptimizedCnecFiller.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/UnoptimizedCnecFiller.java @@ -50,7 +50,7 @@ public UnoptimizedCnecFiller(Set flowCnecs, } @Override - public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult) { + public void fill(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { // Get list of valid flow CNECs Set validFlowCnecs = getValidFlowCnecs(sensitivityResult); @@ -65,11 +65,6 @@ public void fill(LinearProblem linearProblem, FlowResult flowResult, Sensitivity updateMinimumMarginConstraints(linearProblem, validFlowCnecs); } - @Override - public void updateBetweenSensiIteration(LinearProblem linearProblem, FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { - // nothing to do - } - @Override public void updateBetweenMipIteration(LinearProblem linearProblem, RangeActionActivationResult rangeActionActivationResult) { // nothing to do diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/LinearProblem.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/LinearProblem.java index 944435b549..67c731a3ff 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/LinearProblem.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/LinearProblem.java @@ -33,6 +33,7 @@ public final class LinearProblem { private final OpenRaoMPSolver solver; private final List fillerList; + private final RangeActionActivationResult raActivationFromParentLeaf; private final double relativeMipGap; private final String solverSpecificParameters; @@ -81,9 +82,10 @@ public static LinearProblemBuilder create() { return new LinearProblemBuilder(); } - LinearProblem(List fillerList, RangeActionsOptimizationParameters.Solver solver, double relativeMipGap, String solverSpecificParameters) { + LinearProblem(List fillerList, RangeActionActivationResult raActivationFromParentLeaf, RangeActionsOptimizationParameters.Solver solver, double relativeMipGap, String solverSpecificParameters) { this.solver = new OpenRaoMPSolver(OPT_PROBLEM_NAME, solver); this.fillerList = fillerList; + this.raActivationFromParentLeaf = raActivationFromParentLeaf; this.relativeMipGap = relativeMipGap; this.solverSpecificParameters = solverSpecificParameters; this.solver.setMinimization(); @@ -94,16 +96,13 @@ public List getFillers() { } public void fill(FlowResult flowResult, SensitivityResult sensitivityResult) { - fillerList.forEach(problemFiller -> problemFiller.fill(this, flowResult, sensitivityResult)); + fillerList.forEach(problemFiller -> problemFiller.fill(this, flowResult, sensitivityResult, raActivationFromParentLeaf)); } public void updateBetweenSensiIteration(FlowResult flowResult, SensitivityResult sensitivityResult, RangeActionActivationResult rangeActionActivationResult) { // TODO: only reset if failed states have changed? Then we need access to all CRAC states in order to query the sensitivity result this.solver.resetModel(); - fill(flowResult, sensitivityResult); - // TODO: remove "update" when "rangeActionActivationResult" can be used by "fill" - // (used in discrete PST fillers & for RA range shrinking in CoreProblemFiller) - fillerList.forEach(problemFiller -> problemFiller.updateBetweenSensiIteration(this, flowResult, sensitivityResult, rangeActionActivationResult)); + fillerList.forEach(problemFiller -> problemFiller.fill(this, flowResult, sensitivityResult, rangeActionActivationResult)); } public void updateBetweenMipIteration(RangeActionActivationResult rangeActionActivationResult) { diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/LinearProblemBuilder.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/LinearProblemBuilder.java index fee61c4411..9baf225217 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/LinearProblemBuilder.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/LinearProblemBuilder.java @@ -14,6 +14,7 @@ import com.powsybl.openrao.searchtreerao.linearoptimisation.algorithms.fillers.*; import com.powsybl.openrao.searchtreerao.linearoptimisation.inputs.IteratingLinearOptimizerInput; import com.powsybl.openrao.searchtreerao.linearoptimisation.parameters.IteratingLinearOptimizerParameters; +import com.powsybl.openrao.searchtreerao.result.api.RangeActionActivationResult; import java.util.*; import java.util.stream.Collectors; @@ -26,6 +27,7 @@ public class LinearProblemBuilder { private RangeActionsOptimizationParameters.Solver solver; private double relativeMipGap = RangeActionsOptimizationParameters.LinearOptimizationSolver.DEFAULT_RELATIVE_MIP_GAP; private String solverSpecificParameters = RangeActionsOptimizationParameters.LinearOptimizationSolver.DEFAULT_SOLVER_SPECIFIC_PARAMETERS; + private RangeActionActivationResult initialRangeActionActivationResult; private IteratingLinearOptimizerInput inputs; private IteratingLinearOptimizerParameters parameters; @@ -38,7 +40,8 @@ public LinearProblem buildFromInputsAndParameters(IteratingLinearOptimizerInput this.withSolver(parameters.getSolverParameters().getSolver()) .withRelativeMipGap(parameters.getSolverParameters().getRelativeMipGap()) .withSolverSpecificParameters(parameters.getSolverParameters().getSolverSpecificParameters()) - .withProblemFiller(buildCoreProblemFiller()); + .withProblemFiller(buildCoreProblemFiller()) + .withInitialRangeActionActivationResult(inputs.getRaActivationFromParentLeaf()); // max.min margin, or max.min relative margin if (parameters.getObjectiveFunction().relativePositiveMargins()) { @@ -82,11 +85,11 @@ public LinearProblem buildFromInputsAndParameters(IteratingLinearOptimizerInput this.withProblemFiller(buildRaUsageLimitsFiller()); } - return new LinearProblem(problemFillers, solver, relativeMipGap, solverSpecificParameters); + return new LinearProblem(problemFillers, initialRangeActionActivationResult, solver, relativeMipGap, solverSpecificParameters); } public LinearProblem build() { - return new LinearProblem(problemFillers, solver, relativeMipGap, solverSpecificParameters); + return new LinearProblem(problemFillers, initialRangeActionActivationResult, solver, relativeMipGap, solverSpecificParameters); } public LinearProblemBuilder withProblemFiller(ProblemFiller problemFiller) { @@ -109,12 +112,16 @@ public LinearProblemBuilder withSolverSpecificParameters(String solverSpecificPa return this; } + public LinearProblemBuilder withInitialRangeActionActivationResult(RangeActionActivationResult rangeActionActivationResult) { + this.initialRangeActionActivationResult = rangeActionActivationResult; + return this; + } + private ProblemFiller buildCoreProblemFiller() { return new CoreProblemFiller( inputs.getOptimizationPerimeter(), inputs.getPrePerimeterSetpoints(), - inputs.getRaActivationFromParentLeaf(), - parameters.getRangeActionParameters(), + parameters.getRangeActionParameters(), parameters.getObjectiveFunctionUnit(), parameters.getRaRangeShrinking(), parameters.getRangeActionParameters().getPstModel() @@ -164,7 +171,6 @@ private ProblemFiller buildUnoptimizedCnecFiller() { private ProblemFiller buildIntegerPstTapFiller(Map> pstRangeActions) { return new DiscretePstTapFiller( - inputs.getNetwork(), inputs.getOptimizationPerimeter(), pstRangeActions, inputs.getPrePerimeterSetpoints() @@ -173,7 +179,6 @@ private ProblemFiller buildIntegerPstTapFiller(Map> p private ProblemFiller buildDiscretePstGroupFiller(Map> pstRangeActions) { return new DiscretePstGroupFiller( - inputs.getNetwork(), inputs.getOptimizationPerimeter().getMainOptimizationState(), pstRangeActions ); diff --git a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/AbstractFillerTest.java b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/AbstractFillerTest.java index 8d381ade97..bc14d23135 100644 --- a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/AbstractFillerTest.java +++ b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/AbstractFillerTest.java @@ -13,14 +13,19 @@ import com.powsybl.iidm.network.TwoSides; import com.powsybl.openrao.data.cracapi.range.RangeType; import com.powsybl.openrao.data.cracapi.rangeaction.PstRangeAction; +import com.powsybl.openrao.data.cracapi.rangeaction.RangeAction; import com.powsybl.openrao.data.cracimpl.utils.NetworkImportsUtil; import com.powsybl.openrao.data.raoresultapi.ComputationStatus; import com.powsybl.openrao.searchtreerao.result.api.FlowResult; +import com.powsybl.openrao.searchtreerao.result.api.RangeActionActivationResult; import com.powsybl.openrao.searchtreerao.result.api.SensitivityResult; +import com.powsybl.openrao.searchtreerao.result.impl.RangeActionActivationResultImpl; +import com.powsybl.openrao.searchtreerao.result.impl.RangeActionSetpointResultImpl; import org.mockito.Mockito; import java.io.IOException; import java.util.Map; +import java.util.Set; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @@ -121,4 +126,12 @@ protected void addPstGroupInCrac() { protected void useNetworkWithTwoPsts() { network = NetworkImportsUtil.import12NodesWith2PstsNetwork(); } + + protected RangeActionActivationResult getInitialRangeActionActivationResult() { + return getInitialRangeActionActivationResult(crac.getRangeActions()); + } + + protected RangeActionActivationResult getInitialRangeActionActivationResult(Set> rangeActionSet) { + return new RangeActionActivationResultImpl(RangeActionSetpointResultImpl.buildWithSetpointsFromNetwork(network, crac.getRangeActions())); + } } diff --git a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/ContinuousRangeActionGroupFillerTest.java b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/ContinuousRangeActionGroupFillerTest.java index eb505312f3..5b34860366 100644 --- a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/ContinuousRangeActionGroupFillerTest.java +++ b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/ContinuousRangeActionGroupFillerTest.java @@ -18,7 +18,6 @@ import com.powsybl.openrao.searchtreerao.linearoptimisation.algorithms.linearproblem.LinearProblem; import com.powsybl.openrao.searchtreerao.linearoptimisation.algorithms.linearproblem.LinearProblemBuilder; import com.powsybl.openrao.searchtreerao.result.api.RangeActionSetpointResult; -import com.powsybl.openrao.searchtreerao.result.impl.RangeActionActivationResultImpl; import com.powsybl.openrao.searchtreerao.result.impl.RangeActionSetpointResultImpl; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -62,8 +61,7 @@ void testFillAndUpdateMethods() throws IOException { CoreProblemFiller coreProblemFiller = new CoreProblemFiller( optimizationPerimeter, initialRangeActionSetpointResult, - new RangeActionActivationResultImpl(initialRangeActionSetpointResult), - rangeActionParameters, + rangeActionParameters, Unit.MEGAWATT, false, RangeActionsOptimizationParameters.PstModel.CONTINUOUS); diff --git a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/CoreProblemFillerTest.java b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/CoreProblemFillerTest.java index 4200174836..9c723cadab 100644 --- a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/CoreProblemFillerTest.java +++ b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/CoreProblemFillerTest.java @@ -66,6 +66,7 @@ private void buildLinearProblem() { linearProblem = new LinearProblemBuilder() .withProblemFiller(coreProblemFiller) .withSolver(RangeActionsOptimizationParameters.Solver.SCIP) + .withInitialRangeActionActivationResult(getInitialRangeActionActivationResult()) .build(); linearProblem.fill(flowResult, sensitivityResult); } @@ -96,7 +97,6 @@ private void initialize(Set cnecs, double pstSensitivityThreshold, dou coreProblemFiller = new CoreProblemFiller( optimizationPerimeter, initialRangeActionSetpointResult, - new RangeActionActivationResultImpl(initialRangeActionSetpointResult), rangeActionParameters, Unit.MEGAWATT, raRangeShrinking, pstModel); buildLinearProblem(); @@ -449,6 +449,41 @@ void updateTestOnPreventive() { assertEquals(3, linearProblem.numConstraints()); } + @Test + void updateTestOnPreventiveWithRaRangeShrinking() { + initialize(Set.of(cnec1), 1e-6, 1e-6, 1e-6, crac.getPreventiveState(), true, RangeActionsOptimizationParameters.PstModel.CONTINUOUS); + State state = cnec1.getState(); + + Exception e = assertThrows(OpenRaoException.class, () -> linearProblem.getRangeActionRelativeSetpointConstraint(pstRangeAction, state, LinearProblem.RaRangeShrinking.TRUE)); + assertEquals("Constraint PRA_PST_BE_preventive_relative_setpoint_iterative-shrinkconstraint has not been created yet", e.getMessage()); + + // 1st update + updateLinearProblem(); + + assertEquals(3, linearProblem.numVariables()); + assertEquals(4, linearProblem.numConstraints()); + + OpenRaoMPVariable setPointVariable = linearProblem.getRangeActionSetpointVariable(pstRangeAction, state); + OpenRaoMPConstraint shrinkingConstraint = linearProblem.getRangeActionRelativeSetpointConstraint(pstRangeAction, state, LinearProblem.RaRangeShrinking.TRUE); + assertNotNull(shrinkingConstraint); + assertEquals(1, shrinkingConstraint.getCoefficient(setPointVariable)); + assertEquals(-10.5161, shrinkingConstraint.lb(), DOUBLE_TOLERANCE); + assertEquals(5.0626, shrinkingConstraint.ub(), DOUBLE_TOLERANCE); + + // 2nd update + updateLinearProblem(); + + assertEquals(3, linearProblem.numVariables()); + assertEquals(4, linearProblem.numConstraints()); + + setPointVariable = linearProblem.getRangeActionSetpointVariable(pstRangeAction, state); + shrinkingConstraint = linearProblem.getRangeActionRelativeSetpointConstraint(pstRangeAction, state, LinearProblem.RaRangeShrinking.TRUE); + assertNotNull(shrinkingConstraint); + assertEquals(1, shrinkingConstraint.getCoefficient(setPointVariable)); + assertEquals(-7.9222, shrinkingConstraint.lb(), DOUBLE_TOLERANCE); + assertEquals(2.4687, shrinkingConstraint.ub(), DOUBLE_TOLERANCE); + } + @Test void updateTestOnCurativeWithRaRangeShrinking() { initialize(Set.of(cnec2), 1e-6, 1e-6, 1e-6, cnec2.getState(), true, RangeActionsOptimizationParameters.PstModel.CONTINUOUS); diff --git a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstGroupFillerTest.java b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstGroupFillerTest.java index 3bb9edb3e9..2733f8935e 100644 --- a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstGroupFillerTest.java +++ b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstGroupFillerTest.java @@ -63,21 +63,18 @@ void testFillAndUpdateMethods() throws IOException { CoreProblemFiller coreProblemFiller = new CoreProblemFiller( optimizationPerimeter, initialRangeActionSetpointResult, - new RangeActionActivationResultImpl(initialRangeActionSetpointResult), - rangeActionParameters, + rangeActionParameters, Unit.MEGAWATT, false, RangeActionsOptimizationParameters.PstModel.APPROXIMATED_INTEGERS); Map> pstRangeActions = new HashMap<>(); pstRangeActions.put(state, Set.of(pstRa1, pstRa2)); DiscretePstTapFiller discretePstTapFiller = new DiscretePstTapFiller( - network, optimizationPerimeter, pstRangeActions, initialRangeActionSetpointResult); DiscretePstGroupFiller discretePstGroupFiller = new DiscretePstGroupFiller( - network, state, pstRangeActions); @@ -86,6 +83,7 @@ void testFillAndUpdateMethods() throws IOException { .withProblemFiller(discretePstTapFiller) .withProblemFiller(discretePstGroupFiller) .withSolver(RangeActionsOptimizationParameters.Solver.SCIP) + .withInitialRangeActionActivationResult(getInitialRangeActionActivationResult()) .build(); // fill problem @@ -121,8 +119,12 @@ void testFillAndUpdateMethods() throws IOException { // update with a tap of -10 double newAlpha = tapToAngle.get(-10); RangeActionActivationResult updatedRangeActionActivationResult = new RangeActionActivationResultImpl(new RangeActionSetpointResultImpl(Map.of(pstRa1, newAlpha, pstRa2, newAlpha))); - discretePstTapFiller.updateBetweenSensiIteration(linearProblem, flowResult, sensitivityResult, updatedRangeActionActivationResult); - discretePstGroupFiller.updateBetweenSensiIteration(linearProblem, flowResult, sensitivityResult, updatedRangeActionActivationResult); + linearProblem.updateBetweenSensiIteration(flowResult, sensitivityResult, updatedRangeActionActivationResult); + linearProblem.updateBetweenSensiIteration(flowResult, sensitivityResult, updatedRangeActionActivationResult); + + // Re-fetch the constraints because the MIP has been rebuilt + groupTap1C = linearProblem.getPstGroupTapConstraint(pstRa1, state); + groupTap2C = linearProblem.getPstGroupTapConstraint(pstRa2, state); // check constraints assertEquals(-10, groupTap1C.lb(), 1e-6); diff --git a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstTapFillerTest.java b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstTapFillerTest.java index 408c527908..a04d59981f 100644 --- a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstTapFillerTest.java +++ b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/DiscretePstTapFillerTest.java @@ -84,7 +84,6 @@ void setUpAndFill() throws IOException { CoreProblemFiller coreProblemFiller = new CoreProblemFiller( optimizationPerimeter, initialRangeActionSetpointResult, - new RangeActionActivationResultImpl(initialRangeActionSetpointResult), rangeActionParameters, Unit.MEGAWATT, false, RangeActionsOptimizationParameters.PstModel.APPROXIMATED_INTEGERS); @@ -93,7 +92,6 @@ void setUpAndFill() throws IOException { pstRangeActions.put(preventiveState, Set.of(pstRangeAction)); pstRangeActions.put(curativeState, Set.of(cra)); discretePstTapFiller = new DiscretePstTapFiller( - network, optimizationPerimeter, pstRangeActions, initialRangeActionSetpointResult); @@ -102,6 +100,7 @@ void setUpAndFill() throws IOException { .withProblemFiller(coreProblemFiller) .withProblemFiller(discretePstTapFiller) .withSolver(RangeActionsOptimizationParameters.Solver.SCIP) + .withInitialRangeActionActivationResult(getInitialRangeActionActivationResult()) .build(); // fill linear problem @@ -202,7 +201,7 @@ void testFillAndUpdateMethods() { // pra optimal tap = -4, cra optimal tap = -6 rangeActionActivationResultBeforeUpdate.putResult(pra, preventiveState, tapToAngle.get(-4)); rangeActionActivationResultBeforeUpdate.putResult(cra, curativeState, tapToAngle.get(-6)); - discretePstTapFiller.updateBetweenSensiIteration(linearProblem, flowResult, sensitivityResult, rangeActionActivationResultBeforeUpdate); + linearProblem.updateBetweenSensiIteration(flowResult, sensitivityResult, rangeActionActivationResultBeforeUpdate); checkContent(pra, preventiveState, -4, -15, 15, false); checkContent(cra, curativeState, -6, -16, 16, false); diff --git a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxLoopFlowFillerTest.java b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxLoopFlowFillerTest.java index 6ce6dae894..ad08691588 100644 --- a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxLoopFlowFillerTest.java +++ b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxLoopFlowFillerTest.java @@ -77,8 +77,7 @@ public void setUp() throws IOException { coreProblemFiller = new CoreProblemFiller( optimizationPerimeter, initialRangeActionSetpointResult, - new RangeActionActivationResultImpl(initialRangeActionSetpointResult), - rangeActionParameters, + rangeActionParameters, Unit.MEGAWATT, false, RangeActionsOptimizationParameters.PstModel.CONTINUOUS ); @@ -104,6 +103,7 @@ private void buildLinearProblem() { .withProblemFiller(coreProblemFiller) .withProblemFiller(maxLoopFlowFiller) .withSolver(RangeActionsOptimizationParameters.Solver.SCIP) + .withInitialRangeActionActivationResult(getInitialRangeActionActivationResult()) .build(); linearProblem.fill(flowResult, sensitivityResult); } diff --git a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinMarginFillerTest.java b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinMarginFillerTest.java index fb92fc6e16..c4fb72342b 100644 --- a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinMarginFillerTest.java +++ b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinMarginFillerTest.java @@ -19,7 +19,6 @@ import com.powsybl.openrao.searchtreerao.linearoptimisation.algorithms.linearproblem.LinearProblem; import com.powsybl.openrao.searchtreerao.linearoptimisation.algorithms.linearproblem.LinearProblemBuilder; import com.powsybl.openrao.searchtreerao.result.api.RangeActionSetpointResult; -import com.powsybl.openrao.searchtreerao.result.impl.RangeActionActivationResultImpl; import com.powsybl.openrao.searchtreerao.result.impl.RangeActionSetpointResultImpl; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -65,8 +64,7 @@ public void setUp() throws IOException { coreProblemFiller = new CoreProblemFiller( optimizationPerimeter, initialRangeActionSetpointResult, - new RangeActionActivationResultImpl(initialRangeActionSetpointResult), - rangeActionParameters, + rangeActionParameters, Unit.MEGAWATT, false, RangeActionsOptimizationParameters.PstModel.CONTINUOUS); } @@ -80,6 +78,7 @@ private void buildLinearProblem() { .withProblemFiller(coreProblemFiller) .withProblemFiller(maxMinMarginFiller) .withSolver(RangeActionsOptimizationParameters.Solver.SCIP) + .withInitialRangeActionActivationResult(getInitialRangeActionActivationResult()) .build(); linearProblem.fill(flowResult, sensitivityResult); } diff --git a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinRelativeMarginFillerTest.java b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinRelativeMarginFillerTest.java index e1fca5b5e1..3efa8428a6 100644 --- a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinRelativeMarginFillerTest.java +++ b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MaxMinRelativeMarginFillerTest.java @@ -80,7 +80,6 @@ public void setUp() throws IOException { coreProblemFiller = new CoreProblemFiller( optimizationPerimeter, initialRangeActionSetpointResult, - new RangeActionActivationResultImpl(initialRangeActionSetpointResult), rangeActionParameters, MEGAWATT, false, RangeActionsOptimizationParameters.PstModel.CONTINUOUS); @@ -90,10 +89,10 @@ private void createMaxMinRelativeMarginFiller(Unit unit, double cnecInitialAbsol FlowResult initialFlowResult = Mockito.mock(FlowResult.class); when(initialFlowResult.getPtdfZonalSum(cnec1, TwoSides.ONE)).thenReturn(cnecInitialAbsolutePtdfSum); maxMinRelativeMarginFiller = new MaxMinRelativeMarginFiller( - Set.of(cnec1), - initialFlowResult, - unit, - parameters + Set.of(cnec1), + initialFlowResult, + unit, + parameters ); } @@ -102,6 +101,7 @@ private void buildLinearProblem() { .withProblemFiller(coreProblemFiller) .withProblemFiller(maxMinRelativeMarginFiller) .withSolver(RangeActionsOptimizationParameters.Solver.SCIP) + .withInitialRangeActionActivationResult(getInitialRangeActionActivationResult()) .build(); linearProblem.fill(flowResult, sensitivityResult); } diff --git a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MnecFillerTest.java b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MnecFillerTest.java index 41c3eca5ab..65b723189d 100644 --- a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MnecFillerTest.java +++ b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/MnecFillerTest.java @@ -23,7 +23,6 @@ import com.powsybl.openrao.searchtreerao.linearoptimisation.algorithms.linearproblem.*; import com.powsybl.openrao.searchtreerao.result.api.FlowResult; import com.powsybl.openrao.searchtreerao.result.api.RangeActionSetpointResult; -import com.powsybl.openrao.searchtreerao.result.impl.RangeActionActivationResultImpl; import com.powsybl.openrao.searchtreerao.result.impl.RangeActionSetpointResultImpl; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -108,7 +107,6 @@ public void setUp() throws IOException { coreProblemFiller = new CoreProblemFiller( optimizationPerimeter, initialRangeActionSetpointResult, - new RangeActionActivationResultImpl(initialRangeActionSetpointResult), rangeActionParameters, Unit.MEGAWATT, false, RangeActionsOptimizationParameters.PstModel.CONTINUOUS); diff --git a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/RaUsageLimitsFillerTest.java b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/RaUsageLimitsFillerTest.java index 048c124f1b..755f5d8f95 100644 --- a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/RaUsageLimitsFillerTest.java +++ b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/RaUsageLimitsFillerTest.java @@ -27,10 +27,7 @@ import org.mockito.Mockito; import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @@ -113,8 +110,7 @@ public void setup() throws IOException { coreProblemFiller = new CoreProblemFiller( optimizationPerimeter, prePerimeterRangeActionSetpointResult, - prePerimeterRangeActionActivationResult, - rangeActionParameters, + rangeActionParameters, Unit.MEGAWATT, false, RangeActionsOptimizationParameters.PstModel.CONTINUOUS); } @@ -552,13 +548,14 @@ void testMaxElementaryActionsPerTsoConstraint() { when(optimizationPerimeter.getMainOptimizationState()).thenReturn(state); when(optimizationPerimeter.getRangeActionsPerState()).thenReturn(rangeActionsPerState); - DiscretePstTapFiller discretePstTapFiller = new DiscretePstTapFiller(network, optimizationPerimeter, pstRangeActionsPerState, prePerimeterRangeActionSetpointResult); + DiscretePstTapFiller discretePstTapFiller = new DiscretePstTapFiller(optimizationPerimeter, pstRangeActionsPerState, prePerimeterRangeActionSetpointResult); linearProblem = new LinearProblemBuilder() .withProblemFiller(coreProblemFiller) .withProblemFiller(discretePstTapFiller) .withProblemFiller(raUsageLimitsFiller) .withSolver(RangeActionsOptimizationParameters.Solver.SCIP) + .withInitialRangeActionActivationResult(prePerimeterRangeActionActivationResult) .build(); linearProblem.fill(flowResult, sensitivityResult); diff --git a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/UnoptimizedCnecFillerMarginDecreaseRuleTest.java b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/UnoptimizedCnecFillerMarginDecreaseRuleTest.java index fb5c7460a5..e13a1dc988 100644 --- a/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/UnoptimizedCnecFillerMarginDecreaseRuleTest.java +++ b/ra-optimisation/search-tree-rao/src/test/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/fillers/UnoptimizedCnecFillerMarginDecreaseRuleTest.java @@ -25,7 +25,6 @@ import com.powsybl.openrao.searchtreerao.linearoptimisation.algorithms.linearproblem.LinearProblemBuilder; import com.powsybl.openrao.searchtreerao.result.api.FlowResult; import com.powsybl.openrao.searchtreerao.result.api.RangeActionSetpointResult; -import com.powsybl.openrao.searchtreerao.result.impl.RangeActionActivationResultImpl; import com.powsybl.openrao.searchtreerao.result.impl.RangeActionSetpointResultImpl; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -86,8 +85,7 @@ public void setUp() throws IOException { coreProblemFiller = new CoreProblemFiller( optimizationPerimeter, initialRangeActionSetpointResult, - new RangeActionActivationResultImpl(initialRangeActionSetpointResult), - rangeActionParameters, + rangeActionParameters, MEGAWATT, false, RangeActionsOptimizationParameters.PstModel.CONTINUOUS); } From 1925c36a98f2efac3ddb1edfa2f561372f39f8fa Mon Sep 17 00:00:00 2001 From: Thomas Bouquet <63302082+bqth29@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:13:46 +0200 Subject: [PATCH 2/2] Mutualize RaUsageLimits serializers/deserializers and support `max-elementary-actions-per-tso` (#1150) * Mutualize RaUsageLimitsDeserializers Signed-off-by: Thomas Bouquet * Mutualize RaUsageLimitsSerializers and add max-elementary-actions-per-tso Signed-off-by: Thomas Bouquet --------- Signed-off-by: Thomas Bouquet --- .../RaUsageLimitsDeserializer.java | 69 +------------------ .../json/serializers/CracSerializer.java | 13 +--- .../JsonCracCreationParametersConstants.java | 30 +++++--- .../CracCreationParametersJsonTest.java | 1 + ...rac-creator-parameters-with-ra-limits.json | 3 + 5 files changed, 28 insertions(+), 88 deletions(-) diff --git a/data/crac-io/crac-io-json/src/main/java/com/powsybl/openrao/data/cracio/json/deserializers/RaUsageLimitsDeserializer.java b/data/crac-io/crac-io-json/src/main/java/com/powsybl/openrao/data/cracio/json/deserializers/RaUsageLimitsDeserializer.java index 0a8372318d..fcbbd2cc44 100644 --- a/data/crac-io/crac-io-json/src/main/java/com/powsybl/openrao/data/cracio/json/deserializers/RaUsageLimitsDeserializer.java +++ b/data/crac-io/crac-io-json/src/main/java/com/powsybl/openrao/data/cracio/json/deserializers/RaUsageLimitsDeserializer.java @@ -9,23 +9,12 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; -import com.powsybl.openrao.commons.OpenRaoException; import com.powsybl.openrao.data.cracapi.Crac; import com.powsybl.openrao.data.cracapi.RaUsageLimits; +import com.powsybl.openrao.data.cracapi.parameters.JsonCracCreationParametersConstants; import org.apache.commons.lang3.tuple.Pair; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import static com.powsybl.openrao.data.cracio.json.JsonSerializationConstants.INSTANT; -import static com.powsybl.openrao.data.cracio.json.JsonSerializationConstants.MAX_ELEMENTARY_ACTIONS_PER_TSO; -import static com.powsybl.openrao.data.cracio.json.JsonSerializationConstants.MAX_RA; -import static com.powsybl.openrao.data.cracio.json.JsonSerializationConstants.MAX_TSO; -import static com.powsybl.openrao.data.cracio.json.JsonSerializationConstants.MAX_TOPO_PER_TSO; -import static com.powsybl.openrao.data.cracio.json.JsonSerializationConstants.MAX_PST_PER_TSO; -import static com.powsybl.openrao.data.cracio.json.JsonSerializationConstants.MAX_RA_PER_TSO; -import static com.powsybl.openrao.data.cracio.json.JsonSerializationConstants.RA_USAGE_LIMITS_PER_INSTANT; /** * @author Martin Belthle {@literal } @@ -37,7 +26,7 @@ private RaUsageLimitsDeserializer() { public static void deserialize(JsonParser jsonParser, Crac crac) throws IOException { while (jsonParser.nextToken() != JsonToken.END_ARRAY) { - Pair raUsageLimitsPair = deserializeRaUsageLimits(jsonParser); + Pair raUsageLimitsPair = JsonCracCreationParametersConstants.deserializeRaUsageLimits(jsonParser); RaUsageLimits raUsageLimits = raUsageLimitsPair.getRight(); crac.newRaUsageLimits(raUsageLimitsPair.getLeft()) .withMaxRa(raUsageLimits.getMaxRa()) @@ -49,58 +38,4 @@ public static void deserialize(JsonParser jsonParser, Crac crac) throws IOExcept .add(); } } - - private static Map readStringToPositiveIntMap(JsonParser jsonParser) throws IOException { - HashMap map = jsonParser.readValueAs(HashMap.class); - // Check types - map.forEach((Object o, Object o2) -> { - if (!(o instanceof String) || !(o2 instanceof Integer)) { - throw new OpenRaoException("Unexpected key or value type in a Map parameter!"); - } - if ((int) o2 < 0) { - throw new OpenRaoException("Unexpected negative integer!"); - } - }); - return map; - } - - public static Pair deserializeRaUsageLimits(JsonParser jsonParser) throws IOException { - RaUsageLimits raUsageLimits = new RaUsageLimits(); - String instant = null; - while (!jsonParser.nextToken().isStructEnd()) { - switch (jsonParser.getCurrentName()) { - case INSTANT -> { - jsonParser.nextToken(); - instant = jsonParser.getValueAsString(); - } - case MAX_RA -> { - jsonParser.nextToken(); - raUsageLimits.setMaxRa(jsonParser.getIntValue()); - } - case MAX_TSO -> { - jsonParser.nextToken(); - raUsageLimits.setMaxTso(jsonParser.getIntValue()); - } - case MAX_TOPO_PER_TSO -> { - jsonParser.nextToken(); - raUsageLimits.setMaxTopoPerTso(readStringToPositiveIntMap(jsonParser)); - } - case MAX_PST_PER_TSO -> { - jsonParser.nextToken(); - raUsageLimits.setMaxPstPerTso(readStringToPositiveIntMap(jsonParser)); - } - case MAX_RA_PER_TSO -> { - jsonParser.nextToken(); - raUsageLimits.setMaxRaPerTso(readStringToPositiveIntMap(jsonParser)); - } - case MAX_ELEMENTARY_ACTIONS_PER_TSO -> { - jsonParser.nextToken(); - raUsageLimits.setMaxElementaryActionsPerTso(readStringToPositiveIntMap(jsonParser)); - } - default -> - throw new OpenRaoException(String.format("Cannot deserialize ra-usage-limits-per-instant parameters: unexpected field in %s (%s)", RA_USAGE_LIMITS_PER_INSTANT, jsonParser.getCurrentName())); - } - } - return Pair.of(instant, raUsageLimits); - } } diff --git a/data/crac-io/crac-io-json/src/main/java/com/powsybl/openrao/data/cracio/json/serializers/CracSerializer.java b/data/crac-io/crac-io-json/src/main/java/com/powsybl/openrao/data/cracio/json/serializers/CracSerializer.java index 481be5170b..c9790fc011 100644 --- a/data/crac-io/crac-io-json/src/main/java/com/powsybl/openrao/data/cracio/json/serializers/CracSerializer.java +++ b/data/crac-io/crac-io-json/src/main/java/com/powsybl/openrao/data/cracio/json/serializers/CracSerializer.java @@ -15,6 +15,7 @@ import com.powsybl.openrao.data.cracapi.cnec.FlowCnec; import com.powsybl.openrao.data.cracapi.cnec.VoltageCnec; import com.powsybl.openrao.data.cracapi.networkaction.NetworkAction; +import com.powsybl.openrao.data.cracapi.parameters.JsonCracCreationParametersConstants; import com.powsybl.openrao.data.cracapi.rangeaction.CounterTradeRangeAction; import com.powsybl.openrao.data.cracapi.rangeaction.HvdcRangeAction; import com.powsybl.openrao.data.cracapi.rangeaction.InjectionRangeAction; @@ -29,7 +30,6 @@ import java.util.stream.Collectors; import static com.powsybl.openrao.data.cracio.json.JsonSerializationConstants.*; -import static com.powsybl.openrao.data.cracio.json.JsonSerializationConstants.INSTANT; /** * @author Alexandre Montigny {@literal } @@ -67,16 +67,7 @@ public void serialize(Crac crac, JsonGenerator gen, SerializerProvider serialize private void serializeRaUsageLimits(Crac crac, JsonGenerator gen) throws IOException { gen.writeArrayFieldStart(RA_USAGE_LIMITS_PER_INSTANT); for (Map.Entry entry : crac.getRaUsageLimitsPerInstant().entrySet()) { - RaUsageLimits raUsageLimits = entry.getValue(); - gen.writeStartObject(); - gen.writeStringField(INSTANT, entry.getKey().getId()); - gen.writeNumberField(MAX_RA, raUsageLimits.getMaxRa()); - gen.writeNumberField(MAX_TSO, raUsageLimits.getMaxTso()); - gen.writeObjectField(MAX_TOPO_PER_TSO, new TreeMap<>(raUsageLimits.getMaxTopoPerTso())); - gen.writeObjectField(MAX_PST_PER_TSO, new TreeMap<>(raUsageLimits.getMaxPstPerTso())); - gen.writeObjectField(MAX_RA_PER_TSO, new TreeMap<>(raUsageLimits.getMaxRaPerTso())); - gen.writeObjectField(MAX_ELEMENTARY_ACTIONS_PER_TSO, new TreeMap<>(raUsageLimits.getMaxElementaryActionsPerTso())); - gen.writeEndObject(); + JsonCracCreationParametersConstants.serializeRaUsageLimitForOneInstant(gen, Map.entry(entry.getKey().getId(), entry.getValue())); } gen.writeEndArray(); } diff --git a/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/parameters/JsonCracCreationParametersConstants.java b/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/parameters/JsonCracCreationParametersConstants.java index ace9db6f64..eb30ba549e 100644 --- a/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/parameters/JsonCracCreationParametersConstants.java +++ b/data/crac/crac-api/src/main/java/com/powsybl/openrao/data/cracapi/parameters/JsonCracCreationParametersConstants.java @@ -38,6 +38,7 @@ public final class JsonCracCreationParametersConstants { public static final String MAX_TOPO_PER_TSO = "max-topo-per-tso"; public static final String MAX_PST_PER_TSO = "max-pst-per-tso"; public static final String MAX_RA_PER_TSO = "max-ra-per-tso"; + public static final String MAX_ELEMENTARY_ACTIONS_PER_TSO = "max-elementary-actions-per-tso"; private JsonCracCreationParametersConstants() { // should not be instantiated @@ -67,19 +68,24 @@ static void serializeRaUsageLimits(CracCreationParameters parameters, JsonGenera jsonGenerator.writeFieldName(RA_USAGE_LIMITS_PER_INSTANT); jsonGenerator.writeStartArray(); for (Map.Entry entry : parameters.getRaUsageLimitsPerInstant().entrySet()) { - RaUsageLimits raUsageLimits = entry.getValue(); - jsonGenerator.writeStartObject(); - jsonGenerator.writeStringField(INSTANT, entry.getKey()); - jsonGenerator.writeNumberField(MAX_RA, raUsageLimits.getMaxRa()); - jsonGenerator.writeNumberField(MAX_TSO, raUsageLimits.getMaxTso()); - jsonGenerator.writeObjectField(MAX_TOPO_PER_TSO, new TreeMap<>(raUsageLimits.getMaxTopoPerTso())); - jsonGenerator.writeObjectField(MAX_PST_PER_TSO, new TreeMap<>(raUsageLimits.getMaxPstPerTso())); - jsonGenerator.writeObjectField(MAX_RA_PER_TSO, new TreeMap<>(raUsageLimits.getMaxRaPerTso())); - jsonGenerator.writeEndObject(); + serializeRaUsageLimitForOneInstant(jsonGenerator, entry); } jsonGenerator.writeEndArray(); } + public static void serializeRaUsageLimitForOneInstant(JsonGenerator jsonGenerator, Map.Entry entry) throws IOException { + RaUsageLimits raUsageLimits = entry.getValue(); + jsonGenerator.writeStartObject(); + jsonGenerator.writeStringField(INSTANT, entry.getKey()); + jsonGenerator.writeNumberField(MAX_RA, raUsageLimits.getMaxRa()); + jsonGenerator.writeNumberField(MAX_TSO, raUsageLimits.getMaxTso()); + jsonGenerator.writeObjectField(MAX_TOPO_PER_TSO, new TreeMap<>(raUsageLimits.getMaxTopoPerTso())); + jsonGenerator.writeObjectField(MAX_PST_PER_TSO, new TreeMap<>(raUsageLimits.getMaxPstPerTso())); + jsonGenerator.writeObjectField(MAX_RA_PER_TSO, new TreeMap<>(raUsageLimits.getMaxRaPerTso())); + jsonGenerator.writeObjectField(MAX_ELEMENTARY_ACTIONS_PER_TSO, new TreeMap<>(raUsageLimits.getMaxElementaryActionsPerTso())); + jsonGenerator.writeEndObject(); + } + static void deserializeRaUsageLimitsAndUpdateParameters(JsonParser jsonParser, CracCreationParameters parameters) throws IOException { while (jsonParser.nextToken() != JsonToken.END_ARRAY) { Pair pairOfInstantAndItsRaUsageLimits = deserializeRaUsageLimits(jsonParser); @@ -101,7 +107,7 @@ private static Map readStringToPositiveIntMap(JsonParser jsonPa return map; } - private static Pair deserializeRaUsageLimits(JsonParser jsonParser) throws IOException { + public static Pair deserializeRaUsageLimits(JsonParser jsonParser) throws IOException { RaUsageLimits raUsageLimits = new RaUsageLimits(); String instant = null; while (!jsonParser.nextToken().isStructEnd()) { @@ -130,6 +136,10 @@ private static Pair deserializeRaUsageLimits(JsonParser j jsonParser.nextToken(); raUsageLimits.setMaxRaPerTso(readStringToPositiveIntMap(jsonParser)); break; + case MAX_ELEMENTARY_ACTIONS_PER_TSO: + jsonParser.nextToken(); + raUsageLimits.setMaxElementaryActionsPerTso(readStringToPositiveIntMap(jsonParser)); + break; default: throw new OpenRaoException(String.format("Cannot deserialize ra-usage-limits-per-instant parameters: unexpected field in %s (%s)", RA_USAGE_LIMITS_PER_INSTANT, jsonParser.getCurrentName())); } diff --git a/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/parameters/CracCreationParametersJsonTest.java b/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/parameters/CracCreationParametersJsonTest.java index 0b91eb20f2..826826dbe1 100644 --- a/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/parameters/CracCreationParametersJsonTest.java +++ b/data/crac/crac-api/src/test/java/com/powsybl/openrao/data/cracapi/parameters/CracCreationParametersJsonTest.java @@ -60,6 +60,7 @@ void importFromFileWithRaLimits() { expectedLimitsPreventive.setMaxRaPerTso(Map.of("FR", 4)); expectedLimitsPreventive.setMaxTopoPerTso(Map.of("FR", 2)); expectedLimitsPreventive.setMaxPstPerTso(Map.of("FR", 3)); + expectedLimitsPreventive.setMaxElementaryActionsPerTso(Map.of("FR", 10)); RaUsageLimits expectedLimitsCurative = new RaUsageLimits(); expectedLimitsCurative.setMaxRa(7); expectedLimitsCurative.setMaxTso(2); diff --git a/data/crac/crac-api/src/test/resources/parameters/crac-creator-parameters-with-ra-limits.json b/data/crac/crac-api/src/test/resources/parameters/crac-creator-parameters-with-ra-limits.json index cdfb5e942a..e81cea3aab 100644 --- a/data/crac/crac-api/src/test/resources/parameters/crac-creator-parameters-with-ra-limits.json +++ b/data/crac/crac-api/src/test/resources/parameters/crac-creator-parameters-with-ra-limits.json @@ -25,6 +25,9 @@ }, "max-ra-per-tso" : { "FR" : 7 + }, + "max-elementary-actions-per-tso" : { + "FR" : 10 } } ] } \ No newline at end of file