1111import com .powsybl .commons .report .ReportNode ;
1212import com .powsybl .commons .test .PowsyblTestReportResourceBundle ;
1313import com .powsybl .commons .test .TestUtil ;
14+ import com .powsybl .contingency .ContingenciesProvider ;
15+ import com .powsybl .contingency .Contingency ;
16+ import com .powsybl .contingency .ContingencyContext ;
1417import com .powsybl .iidm .network .Network ;
1518import com .powsybl .loadflow .LoadFlowParameters ;
1619import com .powsybl .loadflow .LoadFlowResult ;
2023import com .powsybl .openloadflow .VoltageTargetCheck ;
2124import com .powsybl .openloadflow .VoltageTargetChecker ;
2225import com .powsybl .openloadflow .network .VoltageControlNetworkFactory ;
26+ import com .powsybl .openloadflow .sa .OpenSecurityAnalysisProvider ;
27+ import com .powsybl .openloadflow .sensi .OpenSensitivityAnalysisProvider ;
2328import com .powsybl .openloadflow .util .LoadFlowAssert ;
2429import com .powsybl .openloadflow .util .report .PowsyblOpenLoadFlowReportResourceBundle ;
30+ import com .powsybl .security .SecurityAnalysisParameters ;
31+ import com .powsybl .security .SecurityAnalysisRunParameters ;
32+ import com .powsybl .sensitivity .*;
33+ import org .junit .jupiter .api .BeforeEach ;
2534import org .junit .jupiter .api .Test ;
2635import static org .junit .jupiter .api .Assertions .*;
2736
3140
3241class VoltageCheckerTest {
3342
34- @ Test
35- void testIncompatibleReport () {
36- Network network = VoltageControlNetworkFactory .createWithGeneratorRemoteControlAndSmallSeparatingImpedance ();
43+ private Network network ;
44+
45+ @ BeforeEach
46+ void setUp () {
47+ network = VoltageControlNetworkFactory .createWithGeneratorRemoteControlAndSmallSeparatingImpedance ();
3748
3849 network .getGenerator ("g1" ).setTargetV (400 );
3950 network .getGenerator ("g2" ).setTargetV (403 );
4051 network .getGenerator ("g3" ).setTargetV (407 );
52+ }
53+
54+ @ Test
55+ void testIncompatibleReport () {
4156 VoltageTargetCheck .Result result = VoltageTargetChecker .findElementsToDiscardFromVoltageControl (network , new LoadFlowParameters ());
4257 List <VoltageTargetCheck .IncompatibleTargetResolution > incompatibleTargetResolutions = result .incompatibleTargetResolutions ();
4358 VoltageTargetCheck .IncompatibleTargetResolution incompatibleTargetResolution1 = incompatibleTargetResolutions .get (0 );
@@ -65,11 +80,6 @@ void testIncompatibleReport() {
6580
6681 @ Test
6782 void testAutomaticFix () {
68- Network network = VoltageControlNetworkFactory .createWithGeneratorRemoteControlAndSmallSeparatingImpedance ();
69- network .getGenerator ("g1" ).setTargetV (400 );
70- network .getGenerator ("g2" ).setTargetV (403 );
71- network .getGenerator ("g3" ).setTargetV (407 );
72-
7383 OpenLoadFlowProvider runner = new OpenLoadFlowProvider ();
7484 LoadFlowRunParameters runParameters = new LoadFlowRunParameters ();
7585 LoadFlowParameters params = new LoadFlowParameters ();
@@ -90,11 +100,6 @@ void testAutomaticFix() {
90100
91101 @ Test
92102 void testAutomaticFixReports () throws IOException {
93- Network network = VoltageControlNetworkFactory .createWithGeneratorRemoteControlAndSmallSeparatingImpedance ();
94- network .getGenerator ("g1" ).setTargetV (400 );
95- network .getGenerator ("g2" ).setTargetV (403 );
96- network .getGenerator ("g3" ).setTargetV (407 );
97-
98103 // Add a PV node on the load
99104 network .getVoltageLevel ("vl5" ).newGenerator ()
100105 .setId ("g5" )
@@ -136,4 +141,107 @@ void testAutomaticFixReports() throws IOException {
136141 assertTrue (reportString .contains (" Controlled buses 'vl4_0' and '***' have incompatible voltage targets (plausibility indicator: ***): disabling controller elements [vl1_0]" ));
137142 assertTrue (reportString .contains (" Controlled buses 'vl4_2' and '***' have incompatible voltage targets (plausibility indicator: ***): disabling controller elements [vl3_0]" ));
138143 }
144+
145+ @ Test
146+ void testAutomaticFixSecurityAnalysis () throws IOException {
147+ // Checking that voltage target check is disabled during contingency cases
148+ OpenSecurityAnalysisProvider saRunner = new OpenSecurityAnalysisProvider ();
149+ ReportNode testReport = ReportNode .newRootReportNode ()
150+ .withResourceBundles (PowsyblOpenLoadFlowReportResourceBundle .BASE_NAME , PowsyblTestReportResourceBundle .TEST_BASE_NAME )
151+ .withMessageTemplate ("test" )
152+ .build ();
153+ LoadFlowParameters params = new LoadFlowParameters ();
154+ OpenLoadFlowParameters .create (params ).setFixVoltageTargets (true );
155+
156+ SecurityAnalysisRunParameters runParameters = new SecurityAnalysisRunParameters ()
157+ .setSecurityAnalysisParameters (new SecurityAnalysisParameters ().setLoadFlowParameters (params ))
158+ .setReportNode (testReport );
159+ List <Contingency > contingencies = List .of (Contingency .line ("l1" ), Contingency .line ("l2" ));
160+ ContingenciesProvider provider = n -> contingencies ;
161+ saRunner .run (network , network .getVariantManager ().getWorkingVariantId (), provider , runParameters ).join ();
162+ // For high values, indicator values is hardware sensitive (based on small differences between large numbers)
163+ // So we remove them from the tests
164+ String reportString = TestUtil .normalizeLineSeparator (LoadFlowAssert .reportToString (testReport ).replaceAll ("indicator:.*\\ )" , "indicator: ***)" ));
165+ // Also replacing all vl ids by *** to avoid order difference between hardwares
166+ reportString = reportString .replaceAll ("vl\\ d_\\ d" , "***" );
167+ assertEquals ("""
168+ + test
169+ + AC security analysis on network 'generator-remote-control-test'
170+ + Network CC0 SC0
171+ + Network info
172+ Network has 7 buses and 6 branches
173+ Network balance: active generation=300 MW, active load=299.6 MW, reactive generation=0 MVar, reactive load=200 MVar
174+ Angle reference bus: ***
175+ Slack bus: ***
176+ + Pre-contingency simulation
177+ + Checking voltage targets
178+ Controlled buses '***' and '***' have incompatible voltage targets (plausibility indicator: ***): disabling controller elements [***]
179+ Controlled buses '***' and '***' have incompatible voltage targets (plausibility indicator: ***): disabling controller elements [***]
180+ Outer loop DistributedSlack
181+ Outer loop ReactiveLimits
182+ AC load flow completed successfully (solverStatus=CONVERGED, outerloopStatus=STABLE)
183+ + Post-contingency simulation 'l1'
184+ Contingency caused the loss of 100 MW injection: 100 MW distributed, 0 MW remaining.
185+ Outer loop DistributedSlack
186+ Outer loop ReactiveLimits
187+ AC load flow completed successfully (solverStatus=CONVERGED, outerloopStatus=STABLE)
188+ + Post-contingency simulation 'l2'
189+ Contingency caused the loss of 100 MW injection: 100 MW distributed, 0 MW remaining.
190+ Outer loop DistributedSlack
191+ Outer loop ReactiveLimits
192+ AC load flow completed successfully (solverStatus=CONVERGED, outerloopStatus=STABLE)
193+ """ , reportString );
194+ }
195+
196+ @ Test
197+ void testAutomaticFixSensitivityAnalysis () throws IOException {
198+ // Checking that voltage target check is disabled during contingency cases in sensitivity analysis
199+ OpenSensitivityAnalysisProvider sensiProvider = new OpenSensitivityAnalysisProvider ();
200+ SensitivityAnalysis .Runner sensiRunner = new SensitivityAnalysis .Runner (sensiProvider );
201+ ReportNode testReport = ReportNode .newRootReportNode ()
202+ .withResourceBundles (PowsyblOpenLoadFlowReportResourceBundle .BASE_NAME , PowsyblTestReportResourceBundle .TEST_BASE_NAME )
203+ .withMessageTemplate ("test" )
204+ .build ();
205+ LoadFlowParameters params = new LoadFlowParameters ();
206+ OpenLoadFlowParameters .create (params ).setFixVoltageTargets (true );
207+ List <Contingency > contingencies = List .of (Contingency .line ("l1" ), Contingency .line ("l2" ));
208+ SensitivityAnalysisRunParameters runParameters = new SensitivityAnalysisRunParameters ()
209+ .setParameters (new SensitivityAnalysisParameters ().setLoadFlowParameters (params ))
210+ .setContingencies (contingencies )
211+ .setReportNode (testReport );
212+ SensitivityFactor factor = new SensitivityFactor (SensitivityFunctionType .BRANCH_ACTIVE_POWER_1 , "l1" , SensitivityVariableType .INJECTION_ACTIVE_POWER , "g1" , false , ContingencyContext .all ());
213+ sensiRunner .run (network , List .of (factor ), runParameters );
214+ // For high values, indicator values is hardware sensitive (based on small differences between large numbers)
215+ // So we remove them from the tests
216+ String reportString = TestUtil .normalizeLineSeparator (LoadFlowAssert .reportToString (testReport ).replaceAll ("indicator:.*\\ )" , "indicator: ***)" ));
217+ // Also strongest incompatibility with vl4_0 can be vl4_2 or vl5_0 depending on incompatibility factor numerical errors
218+ // Also replacing all vl ids by *** to avoid order difference between hardwares
219+ reportString = reportString .replaceAll ("vl\\ d_\\ d" , "***" );
220+
221+ // Even the display order (sorted in plausibility indicator) is different between architectures ! SO lets check expected sentences alone
222+ assertEquals ("""
223+ + test
224+ + Sensitivity analysis on network 'generator-remote-control-test'
225+ + Network CC0 SC0
226+ + Network info
227+ Network has 7 buses and 6 branches
228+ Network balance: active generation=300 MW, active load=299.6 MW, reactive generation=0 MVar, reactive load=200 MVar
229+ Angle reference bus: ***
230+ Slack bus: ***
231+ + Checking voltage targets
232+ Controlled buses '***' and '***' have incompatible voltage targets (plausibility indicator: ***): disabling controller elements [***]
233+ Controlled buses '***' and '***' have incompatible voltage targets (plausibility indicator: ***): disabling controller elements [***]
234+ Outer loop DistributedSlack
235+ Outer loop ReactiveLimits
236+ AC load flow completed successfully (solverStatus=CONVERGED, outerloopStatus=STABLE)
237+ + Post-contingency simulation 'l1'
238+ Outer loop DistributedSlack
239+ Outer loop ReactiveLimits
240+ AC load flow completed successfully (solverStatus=CONVERGED, outerloopStatus=STABLE)
241+ + Post-contingency simulation 'l2'
242+ Outer loop DistributedSlack
243+ Outer loop ReactiveLimits
244+ AC load flow completed successfully (solverStatus=CONVERGED, outerloopStatus=STABLE)
245+ """ , reportString );
246+ }
139247}
0 commit comments