2424import com .powsybl .iidm .network .Network ;
2525import com .powsybl .iidm .network .extensions .GeneratorStartup ;
2626import com .powsybl .network .store .iidm .impl .NetworkImpl ;
27+ import lombok .Builder ;
28+ import lombok .Getter ;
2729import org .gridsuite .modification .server .NetworkModificationException ;
2830import org .gridsuite .modification .server .dto .FilterEquipments ;
2931import org .gridsuite .modification .server .dto .GenerationDispatchInfos ;
4244import java .util .Objects ;
4345import java .util .TreeSet ;
4446import java .util .UUID ;
47+ import java .util .concurrent .atomic .AtomicReference ;
4548import java .util .function .Function ;
4649import java .util .stream .Collectors ;
4750import java .util .stream .Stream ;
@@ -92,7 +95,7 @@ private static double computeTotalDemand(Component component, double lossCoeffic
9295 return totalLoad * (1. + lossCoefficient / 100. );
9396 }
9497
95- private double computeTotalAmountFixedSupply (Network network , Component component , List <String > generatorsWithFixedSupply , Reporter reporter ) {
98+ private static double computeTotalAmountFixedSupply (Network network , Component component , List <String > generatorsWithFixedSupply , Reporter reporter ) {
9699 double totalAmountFixedSupply = 0. ;
97100
98101 totalAmountFixedSupply += generatorsWithFixedSupply .stream ().map (network ::getGenerator )
@@ -116,7 +119,7 @@ private static Component getSynchronousComponentFrom(HvdcConverterStation<?> sta
116119 return station .getTerminal ().getBusView ().getBus ().getSynchronousComponent ();
117120 }
118121
119- private double computeHvdcBalance (Component component ) {
122+ private static double computeHvdcBalance (Component component ) {
120123 AtomicDouble balance = new AtomicDouble (0. );
121124
122125 component .getBusStream ().forEach (bus -> {
@@ -151,7 +154,7 @@ private double computeHvdcBalance(Component component) {
151154 return balance .get ();
152155 }
153156
154- private List <Generator > computeAdjustableGenerators (Component component , List <String > generatorsWithFixedSupply , Reporter reporter ) {
157+ private static List <Generator > computeAdjustableGenerators (Component component , List <String > generatorsWithFixedSupply , Reporter reporter ) {
155158 List <Generator > res ;
156159
157160 // get all generators in the component
@@ -205,6 +208,13 @@ public void onUpdate(Identifiable identifiable, String attribute, String variant
205208 }
206209 }
207210
211+ @ Builder
212+ @ Getter
213+ private static class GeneratorsFrequencyReserve {
214+ private final List <String > generators ;
215+ private final double frequencyReserve ;
216+ }
217+
208218 @ Override
209219 public void check (Network network ) throws NetworkModificationException {
210220 double lossCoefficient = generationDispatchInfos .getLossCoefficient ();
@@ -217,8 +227,8 @@ public void check(Network network) throws NetworkModificationException {
217227 }
218228 }
219229
220- private List <String > exportFilters (List <GeneratorsFilterInfos > generatorsFilters ,
221- Network network , Reporter subReporter , ApplicationContext context ) {
230+ private static List <String > exportFilters (List <GeneratorsFilterInfos > generatorsFilters ,
231+ Network network , Reporter subReporter , ApplicationContext context ) {
222232 if (CollectionUtils .isEmpty (generatorsFilters )) {
223233 return List .of ();
224234 }
@@ -263,7 +273,27 @@ private List<String> collectGeneratorsWithFixedSupply(Network network, Reporter
263273 return exportFilters (generationDispatchInfos .getGeneratorsWithFixedSupply (), network , subReporter , context );
264274 }
265275
266- private double reduceGeneratorMaxPValue (Generator generator , List <String > generatorsWithoutOutage ) {
276+ private List <GeneratorsFrequencyReserve > collectGeneratorsWithFrequencyReserve (Network network , Reporter subReporter , ApplicationContext context ) {
277+ return generationDispatchInfos .getGeneratorsFrequencyReserve ().stream ().map (g -> {
278+ List <String > generators = exportFilters (g .getGeneratorsFilters (), network , subReporter , context );
279+ return GeneratorsFrequencyReserve .builder ().generators (generators ).frequencyReserve (g .getFrequencyReserve ()).build ();
280+ }).collect (Collectors .toList ());
281+ }
282+
283+ private static double computeGenFrequencyReserve (Generator generator ,
284+ List <GeneratorsFrequencyReserve > generatorsFrequencyReserve ) {
285+ AtomicReference <Double > freqReserve = new AtomicReference <>(0. );
286+ generatorsFrequencyReserve .forEach (g -> {
287+ if (g .getGenerators ().contains (generator .getId ())) {
288+ freqReserve .set (g .getFrequencyReserve ());
289+ }
290+ });
291+ return freqReserve .get ();
292+ }
293+
294+ private double reduceGeneratorMaxPValue (Generator generator ,
295+ List <String > generatorsWithoutOutage ,
296+ List <GeneratorsFrequencyReserve > generatorsFrequencyReserve ) {
267297 double res = generator .getMaxP ();
268298 if (!generatorsWithoutOutage .contains (generator .getId ())) {
269299 GeneratorStartup startupExtension = generator .getExtension (GeneratorStartup .class );
@@ -275,7 +305,8 @@ private double reduceGeneratorMaxPValue(Generator generator, List<String> genera
275305 res *= 1. - generationDispatchInfos .getDefaultOutageRate () / 100. ;
276306 }
277307 }
278- return res ;
308+ double genFrequencyReserve = computeGenFrequencyReserve (generator , generatorsFrequencyReserve );
309+ return res * (1. - genFrequencyReserve / 100. );
279310 }
280311
281312 @ Override
@@ -291,6 +322,9 @@ public void apply(Network network, Reporter subReporter, ApplicationContext cont
291322 // get generators with fixed supply
292323 List <String > generatorsWithFixedSupply = collectGeneratorsWithFixedSupply (network , subReporter , context );
293324
325+ // get generators with frequency reserve
326+ List <GeneratorsFrequencyReserve > generatorsWithFrequencyReserve = collectGeneratorsWithFrequencyReserve (network , subReporter , context );
327+
294328 for (Component component : synchronousComponents ) {
295329 int componentNum = component .getNum ();
296330
@@ -331,7 +365,7 @@ public void apply(Network network, Reporter subReporter, ApplicationContext cont
331365 // stacking of adjustable generators to ensure the totalAmountSupplyToBeDispatched
332366 List <Scalable > generatorsScalable = adjustableGenerators .stream ().map (generator -> {
333367 double minValue = generator .getMinP ();
334- double maxValue = reduceGeneratorMaxPValue (generator , generatorsWithoutOutage );
368+ double maxValue = reduceGeneratorMaxPValue (generator , generatorsWithoutOutage , generatorsWithFrequencyReserve );
335369 return (Scalable ) Scalable .onGenerator (generator .getId (), minValue , maxValue );
336370 }).collect (Collectors .toList ());
337371
0 commit comments