diff --git a/docs/castor/linear-problem/discrete-pst-tap-filler.md b/docs/castor/linear-problem/discrete-pst-tap-filler.md index 3e3af988ba..67b61c2882 100644 --- a/docs/castor/linear-problem/discrete-pst-tap-filler.md +++ b/docs/castor/linear-problem/discrete-pst-tap-filler.md @@ -24,8 +24,8 @@ information [here](/input-data/crac/json.md#range-actions)) | Name | Symbol | Details | Type | Index | Unit | Lower bound | Upper bound | |----------------------------------------------|--------------------|-----------------------------------------------------------------------------------------------------------|---------|---------------------------------------------------|--------------------------|-------------|-------------| -| PstRangeAction tap upward variation | $\Delta t^{+} (r)$ | upward tap variation of PstRangeAction $r$, between two iterations of the optimisation | Integer | One variable for every element of PstRangeActions | No unit (number of taps) | $-\infty$ | $+\infty$ | -| PstRangeAction tap downward variation | $\Delta t^{-} (r)$ | downward tap variation of PstRangeAction $r$, between two iterations of the optimisation | Integer | One variable for every element of PstRangeActions | No unit (number of taps) | $-\infty$ | $+\infty$ | +| PstRangeAction tap upward variation | $\Delta t^{+} (r)$ | upward tap variation of PstRangeAction $r$, between two iterations of the optimisation | Integer | One variable for every element of PstRangeActions | No unit (number of taps) | 0 | $+\infty$ | +| PstRangeAction tap downward variation | $\Delta t^{-} (r)$ | downward tap variation of PstRangeAction $r$, between two iterations of the optimisation | Integer | One variable for every element of PstRangeActions | No unit (number of taps) | 0 | $+\infty$ | | PstRangeAction tap upward variation binary | $\delta ^{+} (r)$ | indicates whether the tap of PstRangeAction $r$ has increased, between two iterations of the optimisation | Binary | One variable for every element of PstRangeActions | No unit | 0 | 1 | | PstRangeAction tap downward variation binary | $\delta ^{-} (r)$ | indicates whether the tap of PstRangeAction $r$ has decreased, between two iterations of the optimisation | Binary | One variable for every element of PstRangeActions | No unit | 0 | 1 | @@ -112,8 +112,14 @@ $$ $$ \begin{equation} -t^-(r) \leq \Delta t^+(r, s) + \Delta t^-(r, s) - (\Delta t^+(r, s') + \Delta t^-(r, s')) \leq t^+(r) +0 \leq \Delta t^+(r, s) - \Delta t^+(r, s') \leq t^+(r) \end{equation} $$ -with $\Delta t(r,s')$ the setpoint of the last range action on the same element as $r$ but a state preceding $s$. \ No newline at end of file +$$ +\begin{equation} +0 \leq \Delta t^-(r, s) - \Delta t^-(r, s') \leq t^-(r) +\end{equation} +$$ + +with $\Delta t(r,s')$ the tap variation of the last range action on the same element as $r$ but in the state preceding $s$. \ No newline at end of file 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 e83758cfbf..eeef275e38 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 @@ -92,15 +92,18 @@ private void buildPstTapVariablesAndConstraints(LinearProblem linearProblem, Pst if (lastAvailableRangeAction != null) { RangeAction preventiveRangeAction = lastAvailableRangeAction.getKey(); Pair pstLimits = getMinAndMaxRelativeTaps(pstRangeAction, linearProblem.infinity()); - double maxRelativeTap = pstLimits.getRight(); - double minRelativeTap = pstLimits.getLeft(); - OpenRaoMPConstraint relativeTapConstraint = linearProblem.addPstRelativeTapConstraint(minRelativeTap, maxRelativeTap, pstRangeAction, state); + double maxRelativeTap = Math.max(0, pstLimits.getRight()); + double minRelativeTap = -Math.min(0, pstLimits.getLeft()); + + OpenRaoMPConstraint relativeTapConstraintUpward = linearProblem.addPstRelativeTapConstraint(0, maxRelativeTap, pstRangeAction, state, LinearProblem.VariationDirectionExtension.UPWARD); OpenRaoMPVariable preventivePstTapUpwardVariationVariable = linearProblem.getPstTapVariationVariable((PstRangeAction) preventiveRangeAction, optimizationPerimeter.getMainOptimizationState(), LinearProblem.VariationDirectionExtension.UPWARD); + relativeTapConstraintUpward.setCoefficient(pstTapUpwardVariationVariable, 1); + relativeTapConstraintUpward.setCoefficient(preventivePstTapUpwardVariationVariable, -1); + + OpenRaoMPConstraint relativeTapConstraintDownard = linearProblem.addPstRelativeTapConstraint(0, minRelativeTap, pstRangeAction, state, LinearProblem.VariationDirectionExtension.DOWNWARD); OpenRaoMPVariable preventivePstTapDownwardVariationVariable = linearProblem.getPstTapVariationVariable((PstRangeAction) preventiveRangeAction, optimizationPerimeter.getMainOptimizationState(), LinearProblem.VariationDirectionExtension.DOWNWARD); - relativeTapConstraint.setCoefficient(pstTapUpwardVariationVariable, 1); - relativeTapConstraint.setCoefficient(pstTapDownwardVariationVariable, 1); - relativeTapConstraint.setCoefficient(preventivePstTapUpwardVariationVariable, -1); - relativeTapConstraint.setCoefficient(preventivePstTapDownwardVariationVariable, -1); + relativeTapConstraintDownard.setCoefficient(pstTapDownwardVariationVariable, 1); + relativeTapConstraintDownard.setCoefficient(preventivePstTapDownwardVariationVariable, -1); } OpenRaoMPVariable setPointVariable = linearProblem.getRangeActionSetpointVariable(pstRangeAction, state); 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 da47a75a47..d19d653c16 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 @@ -160,12 +160,12 @@ public OpenRaoMPConstraint addRangeActionRelativeSetpointConstraint(double lb, d return solver.makeConstraint(lb, ub, rangeActionRelativeSetpointConstraintId(rangeAction, state, raRangeShrinking)); } - public OpenRaoMPConstraint addPstRelativeTapConstraint(double lb, double ub, PstRangeAction pstRangeAction, State state) { - return solver.makeConstraint(lb, ub, pstRangeActionRelativeTapConstraintId(pstRangeAction, state)); + public OpenRaoMPConstraint addPstRelativeTapConstraint(double lb, double ub, PstRangeAction pstRangeAction, State state, VariationDirectionExtension variation) { + return solver.makeConstraint(lb, ub, pstRangeActionRelativeTapConstraintId(pstRangeAction, state, variation)); } - public OpenRaoMPConstraint getPstRelativeTapConstraint(PstRangeAction pstRangeAction, State state) { - return solver.getConstraint(pstRangeActionRelativeTapConstraintId(pstRangeAction, state)); + public OpenRaoMPConstraint getPstRelativeTapConstraint(PstRangeAction pstRangeAction, State state, VariationDirectionExtension variation) { + return solver.getConstraint(pstRangeActionRelativeTapConstraintId(pstRangeAction, state, variation)); } public OpenRaoMPConstraint getRangeActionRelativeSetpointConstraint(RangeAction rangeAction, State state, RaRangeShrinking raRangeShrinking) { diff --git a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/LinearProblemIdGenerator.java b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/LinearProblemIdGenerator.java index bd7ab0dfb1..6bd04f4d67 100644 --- a/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/LinearProblemIdGenerator.java +++ b/ra-optimisation/search-tree-rao/src/main/java/com/powsybl/openrao/searchtreerao/linearoptimisation/algorithms/linearproblem/LinearProblemIdGenerator.java @@ -67,8 +67,8 @@ public static String rangeActionRelativeSetpointConstraintId(RangeAction rang return rangeAction.getId() + SEPARATOR + state.getId() + SEPARATOR + RELATIVE + SEPARATOR + SET_POINT + SEPARATOR + raRangeShrinking.toString() + CONSTRAINT_SUFFIX; } - public static String pstRangeActionRelativeTapConstraintId(PstRangeAction pstRangeAction, State state) { - return pstRangeAction.getId() + SEPARATOR + state.getId() + SEPARATOR + RELATIVE + SEPARATOR + TAP + SEPARATOR + CONSTRAINT_SUFFIX; + public static String pstRangeActionRelativeTapConstraintId(PstRangeAction pstRangeAction, State state, LinearProblem.VariationDirectionExtension upwardOrDownward) { + return pstRangeAction.getId() + SEPARATOR + state.getId() + SEPARATOR + RELATIVE + SEPARATOR + TAP + SEPARATOR + upwardOrDownward.toString().toLowerCase() + SEPARATOR + CONSTRAINT_SUFFIX; } public static String pstTapVariableVariationId(RangeAction rangeAction, State state, LinearProblem.VariationDirectionExtension upwardOrDownward) { 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 1d3f6fe4da..75d435b7a0 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 @@ -55,7 +55,7 @@ void testFillAndUpdateMethods() throws IOException { .withTapToAngleConversionMap(tapToAngle) .newTapRange() .withMinTap(-10) - .withMaxTap(10) + .withMaxTap(7) .withRangeType(RangeType.RELATIVE_TO_PREVIOUS_INSTANT) .add() .add(); @@ -110,7 +110,8 @@ void testFillAndUpdateMethods() throws IOException { OpenRaoMPConstraint upOrDownC = linearProblem.getUpOrDownPstVariationConstraint(pstRangeAction, state); OpenRaoMPConstraint upVariationC = linearProblem.getIsVariationInDirectionConstraint(pstRangeAction, state, LinearProblem.VariationReferenceExtension.PREVIOUS_ITERATION, LinearProblem.VariationDirectionExtension.UPWARD); OpenRaoMPConstraint downVariationC = linearProblem.getIsVariationInDirectionConstraint(pstRangeAction, state, LinearProblem.VariationReferenceExtension.PREVIOUS_ITERATION, LinearProblem.VariationDirectionExtension.DOWNWARD); - OpenRaoMPConstraint craRelativeTapC = linearProblem.getPstRelativeTapConstraint(cra, curativeState); + OpenRaoMPConstraint craRelativeTapUpC = linearProblem.getPstRelativeTapConstraint(cra, curativeState, LinearProblem.VariationDirectionExtension.UPWARD); + OpenRaoMPConstraint craRelativeTapDownC = linearProblem.getPstRelativeTapConstraint(cra, curativeState, LinearProblem.VariationDirectionExtension.DOWNWARD); assertNotNull(setpointV); assertNotNull(variationUpV); @@ -121,7 +122,8 @@ void testFillAndUpdateMethods() throws IOException { assertNotNull(upOrDownC); assertNotNull(upVariationC); assertNotNull(downVariationC); - assertNotNull(craRelativeTapC); + assertNotNull(craRelativeTapUpC); + assertNotNull(craRelativeTapDownC); // check variable bounds assertEquals(0, variationUpV.lb(), 1e-6); @@ -155,12 +157,15 @@ void testFillAndUpdateMethods() throws IOException { assertEquals(1, downVariationC.getCoefficient(variationDownV), 1e-6); assertEquals(-15, downVariationC.getCoefficient(binaryDownV), 1e-6); - assertEquals(-10, craRelativeTapC.lb(), 1e-6); - assertEquals(10, craRelativeTapC.ub(), 1e-6); - assertEquals(1, craRelativeTapC.getCoefficient(craVariationUpV)); - assertEquals(1, craRelativeTapC.getCoefficient(craVariationDownV)); - assertEquals(-1, craRelativeTapC.getCoefficient(variationUpV)); - assertEquals(-1, craRelativeTapC.getCoefficient(variationDownV)); + assertEquals(7, craRelativeTapUpC.ub(), 1e-6); + assertEquals(0, craRelativeTapUpC.lb(), 1e-6); + assertEquals(1, craRelativeTapUpC.getCoefficient(craVariationUpV)); + assertEquals(-1, craRelativeTapUpC.getCoefficient(variationUpV)); + + assertEquals(10, craRelativeTapDownC.ub(), 1e-6); + assertEquals(0, craRelativeTapDownC.lb(), 1e-6); + assertEquals(1, craRelativeTapDownC.getCoefficient(craVariationDownV)); + assertEquals(-1, craRelativeTapDownC.getCoefficient(variationDownV)); // update linear problem, with a new PST tap equal to -4 double alphaBeforeUpdate = tapToAngle.get(-4); diff --git a/tests/src/test/resources/com/powsybl/openrao/tests/features/epic19_specific_rao_parameters/US19_11.feature b/tests/src/test/resources/com/powsybl/openrao/tests/features/epic19_specific_rao_parameters/US19_11.feature index 436aa50864..c95fb6d88e 100644 --- a/tests/src/test/resources/com/powsybl/openrao/tests/features/epic19_specific_rao_parameters/US19_11.feature +++ b/tests/src/test/resources/com/powsybl/openrao/tests/features/epic19_specific_rao_parameters/US19_11.feature @@ -17,12 +17,7 @@ Feature: US 19.11: Handle maximum number of elementary actions per TSO And the tap of PstRangeAction "pst_fr" should be 13 after "co1_fr2_fr3_1" at "curative" And the worst margin is -218.5 A - @fast @rao @second-preventive @flaky - # TODO : fix this test with global 2P is fixed - # for some reason, SCIP and CBC activate 3 range actions at the root leaf of the 2P (2 curative + 1 preventive) - # and XPRESS only 2 (curative). Oddly, both situations seem to produce the same margins. - # We should start by checking the iidm at the end of the optimization of the root leaf, to see if it is necessary to - # activate the preventive (BE) PST in order to achieve these margins, then see what's wrong. + @fast @rao @second-preventive Scenario: US.19.11.9.bis: Same case with global optimization: should have the same results Given network file is "epic19/small-network-2P.uct" Given crac file is "epic19/SL_ep19us11case9.json"