2121import com .powsybl .openrao .searchtreerao .linearoptimisation .algorithms .linearproblem .LinearProblem ;
2222import com .powsybl .openrao .searchtreerao .linearoptimisation .algorithms .linearproblem .OpenRaoMPConstraint ;
2323import com .powsybl .openrao .searchtreerao .linearoptimisation .algorithms .linearproblem .OpenRaoMPVariable ;
24+ import com .powsybl .openrao .searchtreerao .marmot .MarmotUtils ;
2425import com .powsybl .openrao .searchtreerao .result .api .FlowResult ;
2526import com .powsybl .openrao .searchtreerao .result .api .RangeActionActivationResult ;
2627import com .powsybl .openrao .searchtreerao .result .api .SensitivityResult ;
4041 * @author Godelaine de Montmorillon {@literal <godelaine.demontmorillon at rte-france.com>}
4142 */
4243public class GeneratorConstraintsFiller implements ProblemFiller {
43- private final TemporalData <Network > networks ;
44+ private final Map < String , TemporalData <GeneratorData >> generatorData ;
4445 private final TemporalData <State > preventiveStates ;
4546 private final TemporalData <Set <InjectionRangeAction >> injectionRangeActionsPerTimestamp ;
4647 private final Set <GeneratorConstraints > generatorConstraints ;
@@ -59,7 +60,7 @@ public GeneratorConstraintsFiller(TemporalData<Network> networks,
5960 TemporalData <State > preventiveStates ,
6061 TemporalData <Set <InjectionRangeAction >> injectionRangeActionsPerTimestamp ,
6162 Set <GeneratorConstraints > generatorConstraints ) {
62- this .networks = networks ;
63+ this .generatorData = processGeneratorData ( networks ) ;
6364 this .preventiveStates = preventiveStates ;
6465 this .injectionRangeActionsPerTimestamp = injectionRangeActionsPerTimestamp ;
6566 this .generatorConstraints = generatorConstraints ;
@@ -84,7 +85,7 @@ private static double computeTimestampDuration(List<OffsetDateTime> timestamps)
8485
8586 @ Override
8687 public void fill (LinearProblem linearProblem , FlowResult flowResult , SensitivityResult sensitivityResult , RangeActionActivationResult rangeActionActivationResult ) {
87- int numberOfTimestamps = networks .getTimestamps ().size ();
88+ int numberOfTimestamps = preventiveStates .getTimestamps ().size ();
8889 for (GeneratorConstraints individualGeneratorConstraints : generatorConstraints ) {
8990 String generatorId = individualGeneratorConstraints .getGeneratorId ();
9091 Optional <Double > leadTime = individualGeneratorConstraints .getLeadTime ();
@@ -153,18 +154,18 @@ public void fill(LinearProblem linearProblem, FlowResult flowResult, Sensitivity
153154 // Specific first timestamp constraints
154155 OffsetDateTime firstTimestamp = timestamps .getFirst ();
155156 if (!individualGeneratorConstraints .isShutDownAllowed ()) {
156- addShutDownProhibitedOnFirstTimestampConstraint (linearProblem , generatorId , firstTimestamp , networks . getData ( firstTimestamp ). orElseThrow () );
157+ addShutDownProhibitedOnFirstTimestampConstraint (linearProblem , generatorId , firstTimestamp );
157158 }
158159 if (!individualGeneratorConstraints .isStartUpAllowed ()) {
159- addStartUpProhibitedOnFirstTimestampConstraint (linearProblem , generatorId , firstTimestamp , networks . getData ( firstTimestamp ). orElseThrow () );
160+ addStartUpProhibitedOnFirstTimestampConstraint (linearProblem , generatorId , firstTimestamp );
160161 }
161162 }
162163 }
163164 }
164165
165166 // ---- Variables
166167 private void addPowerVariable (LinearProblem linearProblem , String generatorId , OffsetDateTime timestamp ) {
167- double pMax = getMaxP (generatorId , networks . getData ( timestamp ). orElseThrow () );
168+ double pMax = getMaxPower (generatorId , timestamp );
168169 linearProblem .addGeneratorPowerVariable (generatorId , pMax , timestamp );
169170 }
170171
@@ -242,8 +243,8 @@ private static void addStateToTransitionConstraints(LinearProblem linearProblem,
242243 * P <= P_max ON + OFF_POWER_THRESHOLD OFF
243244 */
244245 private void addOnOffPowerConstraints (LinearProblem linearProblem , String generatorId , OffsetDateTime timestamp ) {
245- double pMin = getMinP (generatorId , networks . getData ( timestamp ). orElseThrow () );
246- double pMax = getMaxP (generatorId , networks . getData ( timestamp ). orElseThrow () );
246+ double pMin = getMinPower (generatorId , timestamp );
247+ double pMax = getMaxPower (generatorId , timestamp );
247248 OpenRaoMPVariable generatorPowerVariable = linearProblem .getGeneratorPowerVariable (generatorId , timestamp );
248249 OpenRaoMPVariable generatorOnVariable = linearProblem .getGeneratorStateVariable (generatorId , timestamp , LinearProblem .GeneratorState .ON );
249250 OpenRaoMPVariable generatorOffVariable = linearProblem .getGeneratorStateVariable (generatorId , timestamp , LinearProblem .GeneratorState .OFF );
@@ -291,7 +292,7 @@ private void addPowerVariationConstraints(LinearProblem linearProblem,
291292 OffsetDateTime nextTimestamp ) {
292293 double upwardPowerGradient = generatorConstraints .getUpwardPowerGradient ().orElse (DEFAULT_POWER_GRADIENT );
293294 double downwardPowerGradient = generatorConstraints .getDownwardPowerGradient ().orElse (-DEFAULT_POWER_GRADIENT );
294- double pMin = getMinP (generatorConstraints .getGeneratorId (), networks . getData ( timestamp ). orElseThrow () );
295+ double pMin = getMinPower (generatorConstraints .getGeneratorId (), timestamp );
295296
296297 OpenRaoMPConstraint powerTransitionConstraintInf = linearProblem .addGeneratorPowerTransitionConstraint (
297298 generatorConstraints .getGeneratorId (), 0 , linearProblem .infinity (), timestamp , LinearProblem .AbsExtension .POSITIVE
@@ -320,7 +321,7 @@ private void addPowerVariationConstraints(LinearProblem linearProblem,
320321 powerTransitionConstraintSup .setCoefficient (offOffTransitionVariable , -OFF_POWER_THRESHOLD );
321322
322323 // OFF -> ON
323- double nextPMin = getMinP (generatorConstraints .getGeneratorId (), networks . getData ( nextTimestamp ). orElseThrow () );
324+ double nextPMin = getMinPower (generatorConstraints .getGeneratorId (), nextTimestamp );
324325 OpenRaoMPVariable offOnTransitionVariable = linearProblem .getGeneratorStateTransitionVariable (
325326 generatorConstraints .getGeneratorId (), timestamp , LinearProblem .GeneratorState .OFF , LinearProblem .GeneratorState .ON
326327 );
@@ -365,8 +366,8 @@ private void addShutDownProhibitedConstraint(LinearProblem linearProblem, String
365366 * ON(t) = 1 on first timestamp when P(t) >= Pmin
366367 * <br/>
367368 */
368- private void addShutDownProhibitedOnFirstTimestampConstraint (LinearProblem linearProblem , String generatorId , OffsetDateTime timestamp , Network network ) {
369- if (getP (generatorId , network ) >= getMinP (generatorId , network )) {
369+ private void addShutDownProhibitedOnFirstTimestampConstraint (LinearProblem linearProblem , String generatorId , OffsetDateTime timestamp ) {
370+ if (getInitialPower (generatorId , timestamp ) >= getMinPower (generatorId , timestamp )) {
370371 OpenRaoMPConstraint shutDownOnFirstTimestampProhibitedConstraint = linearProblem .addGeneratorShutDownOnFirstTimestampProhibitedConstraint (generatorId , timestamp );
371372 shutDownOnFirstTimestampProhibitedConstraint .setCoefficient (linearProblem .getGeneratorStateVariable (generatorId , timestamp , LinearProblem .GeneratorState .ON ), 1.0 );
372373 }
@@ -389,8 +390,8 @@ private void addStartUpProhibitedConstraint(LinearProblem linearProblem, String
389390 * OFF(t) = 1 on first timestamp when P(t) < Pmin
390391 * <br/>
391392 */
392- private void addStartUpProhibitedOnFirstTimestampConstraint (LinearProblem linearProblem , String generatorId , OffsetDateTime timestamp , Network network ) {
393- if (getP (generatorId , network ) < getMinP (generatorId , network )) {
393+ private void addStartUpProhibitedOnFirstTimestampConstraint (LinearProblem linearProblem , String generatorId , OffsetDateTime timestamp ) {
394+ if (getInitialPower (generatorId , timestamp ) < getMinPower (generatorId , timestamp )) {
394395 OpenRaoMPConstraint startUpOnFirstTimestampProhibitedConstraint = linearProblem .addGeneratorStartUpOnFirstTimestampProhibitedConstraint (generatorId , timestamp );
395396 startUpOnFirstTimestampProhibitedConstraint .setCoefficient (linearProblem .getGeneratorStateVariable (generatorId , timestamp , LinearProblem .GeneratorState .OFF ), 1.0 );
396397 }
@@ -444,18 +445,6 @@ private static double getDistributionKey(String generatorId, InjectionRangeActio
444445 return injectionRangeAction .getInjectionDistributionKeys ().get (networkElement );
445446 }
446447
447- private static double getMinP (String generatorId , Network network ) {
448- return Math .max (ON_THRESHOLD , getGenerator (generatorId , network ).getMinP ());
449- }
450-
451- private static double getMaxP (String generatorId , Network network ) {
452- return getGenerator (generatorId , network ).getMaxP ();
453- }
454-
455- private static double getP (String generatorId , Network network ) {
456- return getGenerator (generatorId , network ).getTargetP ();
457- }
458-
459448 // TODO: import generator data in the GeneratorConstraint directly
460449 private static Generator getGenerator (String generatorId , Network network ) {
461450 Generator generator = network .getGenerator (generatorId );
@@ -477,4 +466,41 @@ private Optional<Double> addLeadAndLag(Optional<Double> lead, Optional<Double> l
477466 public void updateBetweenMipIteration (LinearProblem linearProblem , RangeActionActivationResult rangeActionActivationResult ) {
478467 // nothing to do
479468 }
469+
470+ // pre-processed generator data
471+
472+ private double getMinPower (String generatorId , OffsetDateTime timestamp ) {
473+ return Math .max (ON_THRESHOLD , getGeneratorData (generatorId , timestamp ).minPower ());
474+ }
475+
476+ private double getMaxPower (String generatorId , OffsetDateTime timestamp ) {
477+ return getGeneratorData (generatorId , timestamp ).maxPower ();
478+ }
479+
480+ private double getInitialPower (String generatorId , OffsetDateTime timestamp ) {
481+ return getGeneratorData (generatorId , timestamp ).initialPower ();
482+ }
483+
484+ private GeneratorData getGeneratorData (String generatorId , OffsetDateTime timestamp ) {
485+ return generatorData .getOrDefault (generatorId , new TemporalDataImpl <>()).getData (timestamp ).orElse (GeneratorData .defaultData (generatorId ));
486+ }
487+
488+ private static Map <String , TemporalData <GeneratorData >> processGeneratorData (TemporalData <Network > networks ) {
489+ Map <String , TemporalData <GeneratorData >> generatorData = new HashMap <>();
490+ for (OffsetDateTime timestamp : networks .getTimestamps ()) {
491+ Network network = networks .getData (timestamp ).orElseThrow ();
492+ for (Generator generator : network .getGenerators ()) {
493+ generatorData .computeIfAbsent (generator .getId (), k -> new TemporalDataImpl <>())
494+ .put (timestamp , new GeneratorData (generator .getId (), generator .getMinP (), generator .getMaxP (), generator .getTargetP ()));
495+ }
496+ MarmotUtils .releaseNetwork (network );
497+ }
498+ return generatorData ;
499+ }
500+
501+ private record GeneratorData (String generatorId , double minPower , double maxPower , double initialPower ) {
502+ public static GeneratorData defaultData (String generatorId ) {
503+ return new GeneratorData (generatorId , 0.0 , Double .MAX_VALUE , 0.0 );
504+ }
505+ }
480506}
0 commit comments