1111import com .powsybl .openloadflow .ac .AcOuterLoopContext ;
1212import com .powsybl .openloadflow .lf .outerloop .OuterLoopResult ;
1313import com .powsybl .openloadflow .lf .outerloop .OuterLoopStatus ;
14- import com .powsybl .openloadflow .network .GeneratorVoltageControl ;
15- import com .powsybl .openloadflow .network .LfBus ;
16- import com .powsybl .openloadflow .network .LfNetwork ;
17- import com .powsybl .openloadflow .network .VoltageControl ;
14+ import com .powsybl .openloadflow .network .*;
1815import com .powsybl .openloadflow .util .PerUnit ;
1916import com .powsybl .openloadflow .util .Reports ;
2017import org .apache .commons .lang3 .mutable .MutableInt ;
@@ -136,6 +133,10 @@ private boolean switchPvPq(List<ControllerBusToPqBus> pvToPqBuses, int remaining
136133 if (!pvToPqBuses .isEmpty ()) {
137134 done = true ;
138135
136+ ReportNode summary = Reports .reportPvToPqBuses (reportNode , pvToPqBuses .size (), modifiedRemainingPvBusCount );
137+
138+ boolean log = LOGGER .isTraceEnabled ();
139+
139140 for (ControllerBusToPqBus pvToPqBus : pvToPqBuses ) {
140141 LfBus controllerBus = pvToPqBus .controllerBus ;
141142
@@ -146,30 +147,23 @@ private boolean switchPvPq(List<ControllerBusToPqBus> pvToPqBuses, int remaining
146147 // increment PV -> PQ switch counter
147148 contextData .incrementPvPqSwitchCount (controllerBus .getId ());
148149
149- if (LOGGER .isTraceEnabled ()) {
150- switch (pvToPqBus .limitType ) {
151- case MAX_Q :
152- LOGGER .trace ("Switch bus '{}' PV -> PQ, q={} > maxQ={}" , controllerBus .getId (), pvToPqBus .q * PerUnit .SB ,
153- pvToPqBus .qLimit * PerUnit .SB );
154- break ;
155- case MIN_Q :
156- LOGGER .trace ("Switch bus '{}' PV -> PQ, q={} < minQ={}" , controllerBus .getId (), pvToPqBus .q * PerUnit .SB ,
157- pvToPqBus .qLimit * PerUnit .SB );
158- break ;
159- case MIN_REALISTIC_V :
160- LOGGER .trace ("Switch bus '{}' PV -> PQ, q set to {} = targetQ - v is below realistic voltage limit ({}pu) when remote voltage target is maintained" ,
161- controllerBus .getId (), pvToPqBus .qLimit * PerUnit .SB , minRealisticVoltage );
162- break ;
163- case MAX_REALISTIC_V :
164- LOGGER .trace ("Switch bus '{}' PV -> PQ, q set to {} = targetQ - v is above realistic voltage limits ({}pu) when remote voltage target is maintained" ,
165- controllerBus .getId (), pvToPqBus .qLimit * PerUnit .SB , maxRealisticVoltage );
166- break ;
167- }
150+ switch (pvToPqBus .limitType ) {
151+ case MAX_Q :
152+ Reports .reportPvToPqMaxQ (summary , controllerBus , pvToPqBus .q , pvToPqBus .qLimit , log , LOGGER );
153+ break ;
154+ case MIN_Q :
155+ Reports .reportPvToPqMinQ (summary , controllerBus , pvToPqBus .q , pvToPqBus .qLimit , log , LOGGER );
156+ break ;
157+ case MIN_REALISTIC_V :
158+ Reports .reportPvToPqMinRealisticV (summary , controllerBus , pvToPqBus .qLimit , minRealisticVoltage , log , LOGGER );
159+ break ;
160+ case MAX_REALISTIC_V :
161+ Reports .reportPvToPqMaxRealisticV (summary , controllerBus , pvToPqBus .qLimit , maxRealisticVoltage , log , LOGGER );
162+ break ;
168163 }
169164 }
170- }
171165
172- Reports . reportPvToPqBuses ( reportNode , pvToPqBuses . size (), modifiedRemainingPvBusCount );
166+ }
173167
174168 LOGGER .info ("{} buses switched PV -> PQ ({} bus remains PV)" , pvToPqBuses .size (), modifiedRemainingPvBusCount );
175169
@@ -184,30 +178,43 @@ public void initialize(AcOuterLoopContext context) {
184178 private static boolean switchPqPv (List <PqToPvBus > pqToPvBuses , ContextData contextData , ReportNode reportNode , int maxPqPvSwitch ) {
185179 int pqPvSwitchCount = 0 ;
186180
181+ boolean log = LOGGER .isTraceEnabled ();
182+
183+ List <ReportNode > pqPvNodes = new ArrayList <>();
184+
187185 for (PqToPvBus pqToPvBus : pqToPvBuses ) {
188186 LfBus controllerBus = pqToPvBus .controllerBus ;
189187
190188 int pvPqSwitchCount = contextData .getPvPqSwitchCount (controllerBus .getId ());
191189 if (pvPqSwitchCount >= maxPqPvSwitch ) {
192- LOGGER .trace ("Bus '{}' blocked PQ as it has reach its max number of PQ -> PV switch ({})" ,
193- controllerBus .getId (), pvPqSwitchCount );
190+ pqPvNodes .add (Reports .reportPvPqSwitchLimit (controllerBus , pvPqSwitchCount , log , LOGGER ));
194191 } else {
195192 controllerBus .setGeneratorVoltageControlEnabled (true );
196193 controllerBus .setGenerationTargetQ (0 );
197194 controllerBus .setQLimitType (null );
198195 pqPvSwitchCount ++;
199196
200- if (LOGGER .isTraceEnabled ()) {
201- if (pqToPvBus .limitType .isMaxLimit ()) {
202- LOGGER .trace ("Switch bus '{}' PQ -> PV, q=maxQ and v={} > targetV={}" , controllerBus .getId (), getBusV (controllerBus ), getBusTargetV (controllerBus ));
203- } else {
204- LOGGER .trace ("Switch bus '{}' PQ -> PV, q=minQ and v={} < targetV={}" , controllerBus .getId (), getBusV (controllerBus ), getBusTargetV (controllerBus ));
205- }
197+ if (pqToPvBus .limitType .isMaxLimit ()) {
198+ pqPvNodes .add (Reports .reportPqToPvBusMaxLimit (controllerBus ,
199+ controllerBus .getGeneratorVoltageControl ().map (VoltageControl ::getControlledBus ).orElseThrow (),
200+ getBusTargetV (controllerBus ),
201+ log ,
202+ LOGGER ));
203+ } else {
204+ pqPvNodes .add (Reports .reportPqToPvBusMinLimit (controllerBus ,
205+ controllerBus .getGeneratorVoltageControl ().map (VoltageControl ::getControlledBus ).orElseThrow (),
206+ getBusTargetV (controllerBus ),
207+ log ,
208+ LOGGER ));
206209 }
207210 }
211+
208212 }
209213
210- Reports .reportPqToPvBuses (reportNode , pqPvSwitchCount , pqToPvBuses .size () - pqPvSwitchCount );
214+ if (!pqPvNodes .isEmpty ()) {
215+ ReportNode summary = Reports .reportPqToPvBuses (reportNode , pqPvSwitchCount , pqToPvBuses .size () - pqPvSwitchCount );
216+ pqPvNodes .forEach (summary ::include );
217+ }
211218
212219 LOGGER .info ("{} buses switched PQ -> PV ({} buses blocked PQ because have reach max number of switch)" ,
213220 pqPvSwitchCount , pqToPvBuses .size () - pqPvSwitchCount );
@@ -269,7 +276,7 @@ private void checkControllerBus(LfBus controllerBus,
269276 }
270277
271278 private double getInitialGenerationTargetQ (LfBus controllerBus ) {
272- return controllerBus .getGenerators ().stream ().mapToDouble (g -> g . getTargetQ () ).sum ();
279+ return controllerBus .getGenerators ().stream ().mapToDouble (LfGenerator :: getTargetQ ).sum ();
273280 }
274281
275282 private boolean isGeneratorRemoteController (LfBus controllerBus ) {
@@ -321,33 +328,38 @@ private void checkPqBus(LfBus controllerCapableBus, List<PqToPvBus> pqToPvBuses,
321328 private boolean switchReactiveControllerBusPq (List <ControllerBusToPqBus > reactiveControllerBusesToPqBuses , ReportNode reportNode ) {
322329 int switchCount = 0 ;
323330
331+ List <ReportNode > switchedNodes = new ArrayList <>();
332+
333+ boolean log = LOGGER .isTraceEnabled ();
334+
324335 for (ControllerBusToPqBus bus : reactiveControllerBusesToPqBuses ) {
325336 LfBus controllerBus = bus .controllerBus ;
326337
327338 controllerBus .setGeneratorReactivePowerControlEnabled (false );
328339 controllerBus .setGenerationTargetQ (bus .qLimit );
329340 switchCount ++;
330341
331- if (LOGGER .isTraceEnabled ()) {
332- switch (bus .limitType ) {
333- case MAX_Q :
334- LOGGER .trace ("Remote reactive power controller bus '{}' -> PQ, q={} > maxQ={}" , controllerBus .getId (), bus .q * PerUnit .SB ,
335- bus .qLimit * PerUnit .SB );
336- break ;
337- case MIN_Q :
338- LOGGER .trace ("Remote reactive power controller bus '{}' -> PQ, q={} < minQ={}" , controllerBus .getId (), bus .q * PerUnit .SB ,
339- bus .qLimit * PerUnit .SB );
340- break ;
341- case MIN_REALISTIC_V , MAX_REALISTIC_V :
342- LOGGER .trace ("Switch bus '{}' PV -> PQ, q set to {} = targetQ - v is outside realistic voltage limits [{}pu,{}pu] when remote voltage is maintained" ,
343- controllerBus .getId (), bus .qLimit * PerUnit .SB , minRealisticVoltage , maxRealisticVoltage );
344-
345- break ;
346- }
342+ switch (bus .limitType ) {
343+ case MAX_Q :
344+ switchedNodes .add (Reports .reportReactiveControllerBusesToPqMaxQ (controllerBus , bus .q , bus .qLimit , log , LOGGER ));
345+ break ;
346+ case MIN_Q :
347+ switchedNodes .add (Reports .reportReactiveControllerBusesToPqMinQ (controllerBus , bus .q , bus .qLimit , log , LOGGER ));
348+ break ;
349+ case MIN_REALISTIC_V , MAX_REALISTIC_V :
350+ // Note: never happens for now. Robust mode applies only to remote voltage control generators
351+ LOGGER .trace ("Switch bus '{}' PV -> PQ, q set to {} = targetQ - v is outside realistic voltage limits [{}pu,{}pu] when remote voltage is maintained" ,
352+ controllerBus .getId (), bus .qLimit * PerUnit .SB , minRealisticVoltage , maxRealisticVoltage );
353+
354+ break ;
347355 }
356+
348357 }
349358
350- Reports .reportReactiveControllerBusesToPqBuses (reportNode , switchCount );
359+ if (!switchedNodes .isEmpty ()) {
360+ ReportNode node = Reports .reportReactiveControllerBusesToPqBuses (reportNode , switchCount );
361+ switchedNodes .forEach (node ::include );
362+ }
351363
352364 LOGGER .info ("{} remote reactive power controller buses switched PQ" , switchCount );
353365
0 commit comments