Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optimization tests for OpenReac indicators and bounds #88

Merged
merged 31 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b767132
Divide OpenReacRunnerTest into several TUs
p-arvy Nov 27, 2024
8da89b0
Add TUs for ACOPF indicators
p-arvy Nov 27, 2024
50548d2
Add tests on equipment bounds in optimization of OpenReac
p-arvy Dec 4, 2024
802dd1d
Improve tests on ouput indicators of OpenReac
p-arvy Dec 4, 2024
81908d8
Clean
p-arvy Dec 4, 2024
f6746be
Add resources
p-arvy Dec 4, 2024
28047a0
Merge branch 'refs/heads/main' into refactor-open-reac-tests
p-arvy Dec 4, 2024
84e5da6
Clean
p-arvy Dec 12, 2024
a54206b
Clean code adding new TUs
p-arvy Dec 12, 2024
cd043e8
Clean
p-arvy Dec 12, 2024
1f1c0dd
Merge branch 'refs/heads/main' into refactor-open-reac-tests
p-arvy Dec 12, 2024
3a3b1fd
Merge branch 'refs/heads/main' into refactor-open-reac-tests
p-arvy Dec 13, 2024
d78e93d
Clean
p-arvy Dec 30, 2024
724d6fe
Put computer and time indicators as DEBUG indicators
p-arvy Dec 17, 2024
abfc91b
Clean
p-arvy Dec 19, 2024
2afbe89
Add indicators test for OpenReac
p-arvy Dec 12, 2024
e11a2f6
Add tests for bounds
p-arvy Dec 12, 2024
6f4612b
Add TUs on Q bounds
p-arvy Dec 13, 2024
8aa0e87
Small clean
p-arvy Dec 13, 2024
1044424
Update resources
p-arvy Dec 17, 2024
7070e0e
Clean
p-arvy Dec 19, 2024
f5149f3
Clean after rebase
p-arvy Dec 30, 2024
ead7268
Add indicators test for OpenReac
p-arvy Dec 12, 2024
ef9f4f6
Add tests for bounds
p-arvy Dec 12, 2024
fcd0342
Add TUs on Q bounds
p-arvy Dec 13, 2024
271bcf3
Small clean
p-arvy Dec 13, 2024
c327130
Update resources
p-arvy Dec 17, 2024
f110762
Clean
p-arvy Dec 19, 2024
1be92d9
Clean after rebase
p-arvy Dec 30, 2024
4adf272
Merge
So-Fras Jan 8, 2025
d8b6266
Merge branch 'main' into add-optimization-tests
So-Fras Jan 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.io.InputStream;
import java.nio.file.FileSystem;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ForkJoinPool;
Expand Down Expand Up @@ -82,29 +83,56 @@ protected void testAllModifAndLoadFlow(Network network, String subFolder, OpenRe

/**
* Runs OpenReac and apply the results on the network.
* The application of the voltage plan calculated by optimization is optional.
*/
protected void runAndApplyAllModifications(Network network, String subFolder, OpenReacParameters parameters,
boolean updateNetworkWithVoltages, ReportNode reportNode) throws IOException {
boolean updateNetworkWithVoltages, ReportNode reportNode) throws IOException {
OpenReacResult openReacResult = runOpenReac(network, subFolder, parameters, false, reportNode);
assertEquals(OpenReacStatus.OK, openReacResult.getStatus());
openReacResult.setUpdateNetworkWithVoltages(updateNetworkWithVoltages);
openReacResult.applyAllModifications(network);
}

/**
* Runs OpenReac and returns associated result.
*/
protected OpenReacResult runOpenReac(Network network, String subFolder, boolean onlyIndicators) throws IOException {
return runOpenReac(network, subFolder, new OpenReacParameters(), onlyIndicators);
}

/**
* Runs OpenReac and returns associated result.
*/
protected OpenReacResult runOpenReac(Network network, String subFolder, OpenReacParameters parameters, boolean onlyIndicators) throws IOException {
return runOpenReac(network, subFolder, parameters, onlyIndicators, ReportNode.NO_OP);
}

/**
* Runs OpenReac and returns associated result.
* Note that OpenReac is not really executed by default. If the execution line is not uncommented,
* the results are retrieved and stored in an {@link OpenReacResult} object.
*/
protected OpenReacResult runOpenReac(Network network, String subFolder, OpenReacParameters parameters,
boolean onlyIndicators, ReportNode reportNode) throws IOException {
// set default voltage limits to every voltage levels of the network
setDefaultVoltageLimits(network);
LocalCommandExecutor localCommandExecutor = new TestLocalCommandExecutor(
List.of(subFolder + "/reactiveopf_results_generators.csv",
subFolder + "/reactiveopf_results_indic.txt",
subFolder + "/reactiveopf_results_rtc.csv",
subFolder + "/reactiveopf_results_shunts.csv",
subFolder + "/reactiveopf_results_static_var_compensators.csv",
subFolder + "/reactiveopf_results_vsc_converter_stations.csv",
subFolder + "/reactiveopf_results_voltages.csv"));
List<String> outputFileNames = new ArrayList<>(List.of(subFolder + "/reactiveopf_results_indic.txt"));
if (!onlyIndicators) {
outputFileNames.addAll(List.of(
subFolder + "/reactiveopf_results_rtc.csv",
subFolder + "/reactiveopf_results_shunts.csv",
subFolder + "/reactiveopf_results_static_var_compensators.csv",
subFolder + "/reactiveopf_results_vsc_converter_stations.csv",
subFolder + "/reactiveopf_results_voltages.csv"
));
}
LocalCommandExecutor localCommandExecutor = new TestLocalCommandExecutor(outputFileNames);
// To really run open reac, use the commentede line below. Be sure that open-reac/src/test/resources/com/powsybl/config/test/config.yml contains your ampl path
// try (ComputationManager computationManager = new LocalComputationManager()) {
try (ComputationManager computationManager = new LocalComputationManager(new LocalComputationConfig(tmpDir),
localCommandExecutor, ForkJoinPool.commonPool())) {
OpenReacResult openReacResult = OpenReacRunner.run(network,
network.getVariantManager().getWorkingVariantId(), parameters,
return OpenReacRunner.run(network, network.getVariantManager().getWorkingVariantId(), parameters,
new OpenReacConfig(true), computationManager, reportNode, null);
assertEquals(OpenReacStatus.OK, openReacResult.getStatus());
openReacResult.setUpdateNetworkWithVoltages(updateNetworkWithVoltages);
openReacResult.applyAllModifications(network);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/**
* Copyright (c) 2024, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.openreac.optimization;

import com.powsybl.iidm.network.Network;
import com.powsybl.openreac.network.VoltageControlNetworkFactory;
import com.powsybl.openreac.parameters.input.OpenReacParameters;
import com.powsybl.openreac.parameters.output.OpenReacResult;
import com.powsybl.openreac.parameters.output.OpenReacStatus;
import org.junit.jupiter.api.Test;

import java.io.IOException;

import static org.junit.jupiter.api.Assertions.*;

/**
* Test the generator bounds in OpenReac optimization.
*
* @author Pierre ARVY {@literal <pierre.arvy at artelys.com>}
*/
class OpecReacOptimizationBoundsTest extends AbstractOpenReacRunnerTest {

@Test
void testGeneratorsMaxPBounds() throws IOException {
Network network = VoltageControlNetworkFactory.createWithTwoVoltageControls();
// due to the disconnection, the network is now imbalanced
// and max p of generators is not enough to provide balance
network.getLine("l45").disconnect();
OpenReacResult result = runOpenReac(network, "optimization/bounds/generators-pmax-too-small", true);
assertEquals(OpenReacStatus.NOT_OK, result.getStatus());

// increase max p of generators to allow power balance
network.getGenerator("g2").setMaxP(2.5);
network.getGenerator("g3").setMaxP(2.5);
result = runOpenReac(network, "optimization/bounds/generators-pmax", true);
assertEquals(OpenReacStatus.OK, result.getStatus());
}

@Test
void testGeneratorsMinPBounds() throws IOException {
Network network = VoltageControlNetworkFactory.createWithTwoVoltageControls();
// due to the modifications, the network is now imbalanced
// and min p of generators is not small enough to provide balance
network.getLine("l45").disconnect();
network.getLoad("l4").setP0(3);
network.getGenerator("g2").setMinP(2);
network.getGenerator("g3").setMinP(2);
OpenReacResult result = runOpenReac(network, "optimization/bounds/generators-pmin-too-high", true);
assertEquals(OpenReacStatus.NOT_OK, result.getStatus());

// decrease min p of generators to allow power balance
// but targetP will be fixed in optimization, because it is too close of maxP
network.getGenerator("g2").setMinP(1);
network.getGenerator("g3").setMinP(1);
result = runOpenReac(network, "optimization/bounds/generators-target-p-too-close-pmax", true);
assertEquals(OpenReacStatus.NOT_OK, result.getStatus());

// increase max p of generators to allow modification of targetP in optimization
network.getGenerator("g2").setMaxP(2.5);
network.getGenerator("g3").setMaxP(2.5);
result = runOpenReac(network, "optimization/bounds/generators-pmin", true);
assertEquals(OpenReacStatus.OK, result.getStatus());
}

@Test
void testGeneratorRectangularQBounds() throws IOException {
Network network = VoltageControlNetworkFactory.createWithTwoVoltageControls();
network.getLine("l45").disconnect();
network.getLoad("l4").setP0(4).setQ0(2);

// set reactive limits to both generators
network.getGenerator("g2").newReactiveCapabilityCurve()
.beginPoint()
.setP(0)
.setMinQ(-0.25)
.setMaxQ(0.25)
.endPoint()
.beginPoint()
.setP(2)
.setMinQ(-2)
.setMaxQ(2)
.endPoint()
.add();
network.getGenerator("g3").newReactiveCapabilityCurve()
.beginPoint()
.setP(0)
.setMinQ(-0.25)
.setMaxQ(0.25)
.endPoint()
.beginPoint()
.setP(2)
.setMinQ(-2)
.setMaxQ(2)
.endPoint()
.add();

OpenReacResult result = runOpenReac(network, "optimization/bounds/generator-rectangular-bounds", true);
assertEquals(OpenReacStatus.OK, result.getStatus());
// rectangular bounds in ACOPF implies Q bounds are not large enough to remove reactive slacks in optimization
assertTrue(Integer.parseInt(result.getIndicators().get("nb_reactive_slacks")) > 0);
}

@Test
void testGeneratorQmaxPmaxRatioBounds() throws IOException {
Network network = VoltageControlNetworkFactory.createWithTwoVoltageControls();
network.getLine("l45").disconnect();
network.getLoad("l4").setP0(4).setQ0(2);

OpenReacParameters parameters = new OpenReacParameters();
OpenReacResult result = runOpenReac(network, "optimization/bounds/qmax-pmax-default-ratio", parameters, true);
assertEquals(OpenReacStatus.OK, result.getStatus());
// there are slacks as Q bounds are not large enough
assertTrue(Integer.parseInt(result.getIndicators().get("nb_reactive_slacks")) > 0);

parameters.setDefaultQmaxPmaxRatio(1);
result = runOpenReac(network, "optimization/bounds/same-qmax-pmax", parameters, true);
assertEquals(OpenReacStatus.OK, result.getStatus());
// Q bounds are large enough to remove reactive slacks in optimization
assertEquals(0, Integer.parseInt(result.getIndicators().get("nb_reactive_slacks")));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ void testOutputFileParsing() throws IOException {
assertEquals(7, openReacResult.getGeneratorModifications().size());
assertEquals(3, openReacResult.getVoltageProfile().size());
assertEquals(76, openReacResult.getIndicators().size());

assertTrue(openReacResult.getReactiveSlacks().isEmpty());
}
}
Expand Down
Loading
Loading