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 22 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
32 changes: 16 additions & 16 deletions open-reac/src/main/resources/openreac/reactiveopfoutput.run
Original file line number Diff line number Diff line change
Expand Up @@ -229,26 +229,26 @@ let fileOut := "reactiveopf_results_indic.txt";
printf "%s %s\n","final_status",final_status > (fileOut);
printf "%s %s\n","dcopf_status",dcopf_status > (fileOut);

printf "\n" > (fileOut);
printf "%s %Q\n","ctime_start",ctime_start > (fileOut);
printf "%s %i\n","last_solve_result_num",solve_result_num > (fileOut);
printf "%s %i\n","nb_iter_last",nb_iter_last > (fileOut);
printf "%s %i\n","nb_iter_total",nb_iter_total > (fileOut);
printf "%s %f\n","_ampl_elapsed_time",_ampl_elapsed_time > (fileOut);
printf "%s %f\n","_total_solve_time",_total_solve_time > (fileOut);
printf "%s %i\n","total_time",_total_solve_time+_ampl_elapsed_time > (fileOut);

printf "\n" > (fileOut);
printf "%s %s\n","operatingSystem",operatingSystem > (fileOut);
printf{LOG_DEBUG} "\n" > (fileOut);
printf{LOG_DEBUG} "%s %Q\n","ctime_start",ctime_start > (fileOut);
printf{LOG_DEBUG} "%s %i\n","last_solve_result_num",solve_result_num > (fileOut);
printf{LOG_DEBUG} "%s %i\n","nb_iter_last",nb_iter_last > (fileOut);
printf{LOG_DEBUG} "%s %i\n","nb_iter_total",nb_iter_total > (fileOut);
printf{LOG_DEBUG} "%s %f\n","_ampl_elapsed_time",_ampl_elapsed_time > (fileOut);
printf{LOG_DEBUG} "%s %f\n","_total_solve_time",_total_solve_time > (fileOut);
printf{LOG_DEBUG} "%s %i\n","total_time",_total_solve_time+_ampl_elapsed_time > (fileOut);

printf{LOG_DEBUG} "\n" > (fileOut);
printf{LOG_DEBUG} "%s %s\n","operatingSystem",operatingSystem > (fileOut);
if length($OS) > 0 then {
printf "%s %Q\n","OS",$OS > (fileOut); # Windows
printf "%s %Q\n","COMPUTERNAME",$COMPUTERNAME > (fileOut);
printf{LOG_DEBUG} "%s %Q\n","OS",$OS > (fileOut); # Windows
printf{LOG_DEBUG} "%s %Q\n","COMPUTERNAME",$COMPUTERNAME > (fileOut);
}
if length($SHELL) > 0 then {
printf "%s %Q\n","SHELL",$SHELL > (fileOut); # Linux
printf "%s %Q\n","HOSTNAME",$HOSTNAME > (fileOut);
printf{LOG_DEBUG} "%s %Q\n","SHELL",$SHELL > (fileOut); # Linux
printf{LOG_DEBUG} "%s %Q\n","HOSTNAME",$HOSTNAME > (fileOut);
}
printf "%s %Q\n","directory",_cd > (fileOut);
printf{LOG_DEBUG} "%s %Q\n","directory",_cd > (fileOut);

printf "\n" > (fileOut);
printf "%s %s\n","log_level_ampl",log_level_ampl > (fileOut);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void testTransformerTargetVUpdateWithoutRegulationBus() throws IOException {

@Test
void testShuntTargetVUpdateWithoutVoltageResult() throws IOException {
Network network = ShuntNetworkFactory.create();
Network network = ShuntNetworkFactory.createWithNonLinearModel();
ShuntCompensator shunt = network.getShuntCompensator("SHUNT");
String regulatedBusId = shunt.getRegulatingTerminal().getBusView().getBus().getId();

Expand All @@ -91,7 +91,7 @@ void testShuntTargetVUpdateWithoutVoltageResult() throws IOException {

@Test
void testShuntUpdateWithoutRegulationBus() throws IOException {
Network network = ShuntNetworkFactory.create();
Network network = ShuntNetworkFactory.createWithNonLinearModel();
ShuntCompensator shunt = network.getShuntCompensator("SHUNT");
shunt.getRegulatingTerminal().disconnect();

Expand Down
520 changes: 0 additions & 520 deletions open-reac/src/test/java/com/powsybl/openreac/OpenReacRunnerTest.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,88 @@ public final class ShuntNetworkFactory {
private ShuntNetworkFactory() {
}

public static Network create() {
public static Network createWithLinearModel() {
Network network = Network.create("svc", "test");
Substation s1 = network.newSubstation()
.setId("S1")
.add();
Substation s2 = network.newSubstation()
.setId("S2")
.add();
VoltageLevel vl1 = s1.newVoltageLevel()
.setId("vl1")
.setNominalV(400)
.setHighVoltageLimit(420)
.setLowVoltageLimit(380)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
vl1.getBusBreakerView().newBus()
.setId("b1")
.add();
vl1.newGenerator()
.setId("g1")
.setConnectableBus("b1")
.setBus("b1")
.setTargetP(101.3664)
.setTargetV(390)
.setMinP(0)
.setMaxP(150)
.setVoltageRegulatorOn(true)
.add();
VoltageLevel vl2 = s2.newVoltageLevel()
.setId("vl2")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
vl2.getBusBreakerView().newBus()
.setId("b2")
.add();
vl2.newLoad()
.setId("ld1")
.setConnectableBus("b2")
.setBus("b2")
.setP0(101)
.setQ0(150)
.add();
VoltageLevel vl3 = s2.newVoltageLevel()
.setId("vl3")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
vl3.getBusBreakerView().newBus()
.setId("b3")
.add();
vl3.newShuntCompensator()
.setId("SHUNT")
// .setBus("b3")
.setConnectableBus("b3")
.setSectionCount(0)
.setVoltageRegulatorOn(true)
.setTargetV(393)
.setTargetDeadband(5.0)
.newLinearModel()
.setMaximumSectionCount(25)
.setBPerSection(1e-3)
.add()
.add();
network.newLine()
.setId("l1")
.setBus1("b1")
.setBus2("b2")
.setR(1)
.setX(3)
.add();
network.newLine()
.setId("l2")
.setBus1("b3")
.setBus2("b2")
.setR(1)
.setX(3)
.add();
return network;
}

public static Network createWithNonLinearModel() {
Network network = Network.create("svc", "test");
Substation s1 = network.newSubstation()
.setId("S1")
Expand Down Expand Up @@ -105,7 +186,7 @@ public static Network create() {
}

public static Network createWithTwoShuntCompensators() {
Network network = create();
Network network = createWithNonLinearModel();
VoltageLevel vl3 = network.getVoltageLevel("vl3");
vl3.newShuntCompensator()
.setId("SHUNT2")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/**
* Copyright (c) 2023, 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/.
*/
package com.powsybl.openreac.optimization;

import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.commons.test.ComparisonUtils;
import com.powsybl.computation.ComputationManager;
import com.powsybl.computation.local.LocalCommandExecutor;
import com.powsybl.computation.local.LocalComputationConfig;
import com.powsybl.computation.local.LocalComputationManager;
import com.powsybl.iidm.network.*;
import com.powsybl.loadflow.LoadFlow;
import com.powsybl.loadflow.LoadFlowResult;
import com.powsybl.openreac.OpenReacConfig;
import com.powsybl.openreac.OpenReacRunner;
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.AfterEach;
import org.junit.jupiter.api.BeforeEach;

import java.io.IOException;
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;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.nio.file.Files.*;
import static org.junit.jupiter.api.Assertions.*;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
* @author Nicolas PIERRE {@literal <nicolas.pierre at artelys.com>}
*/
abstract class AbstractOpenReacRunnerTest {
protected FileSystem fileSystem;
protected Path tmpDir;

@BeforeEach
public void setUp() throws IOException {
fileSystem = Jimfs.newFileSystem(Configuration.unix());
tmpDir = createDirectory(fileSystem.getPath("tmp"));
}

@AfterEach
void tearDown() throws IOException {
fileSystem.close();
}

protected void assertEqualsToRef(Path p, String refFileName) throws IOException {
try (InputStream actual = newInputStream(p)) {
ComparisonUtils.assertTxtEquals(Objects.requireNonNull(getClass().getResourceAsStream(refFileName)), actual);
}
}

protected Path getAmplExecPath() throws IOException {
Path execFolder;
try (Stream<Path> walk = walk(tmpDir)) {
execFolder = walk.limit(2).collect(Collectors.toList()).get(1);
}
return execFolder;
}

/**
* Runs OpenReac, apply the results and verify that a load flow converges on these results.
*/
protected void testAllModifAndLoadFlow(Network network, String subFolder, OpenReacParameters parameters, ReportNode reportNode) throws IOException {
runAndApplyAllModifications(network, subFolder, parameters, true, reportNode);
LoadFlowResult loadFlowResult = LoadFlow.run(network);
assertTrue(loadFlowResult.isFullyConverged());
}

/**
* 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 {
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);
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())) {
return OpenReacRunner.run(network, network.getVariantManager().getWorkingVariantId(), parameters,
new OpenReacConfig(true), computationManager, reportNode, null);
}
}

/**
* Add voltage limits to voltage levels with undefined limits.
* OpenReac needs voltage limits to run optimization.
*/
protected void setDefaultVoltageLimits(Network network) {
for (VoltageLevel vl : network.getVoltageLevels()) {
if (vl.getLowVoltageLimit() <= 0 || Double.isNaN(vl.getLowVoltageLimit())) {
vl.setLowVoltageLimit(0.5 * vl.getNominalV());
}
if (Double.isNaN(vl.getHighVoltageLimit())) {
vl.setHighVoltageLimit(1.5 * vl.getNominalV());
}
}
}
}
Loading
Loading