diff --git a/open-reac/src/main/java/com/powsybl/openreac/parameters/OpenReacAmplIOFiles.java b/open-reac/src/main/java/com/powsybl/openreac/parameters/OpenReacAmplIOFiles.java index ee3aace5..b11f47c5 100644 --- a/open-reac/src/main/java/com/powsybl/openreac/parameters/OpenReacAmplIOFiles.java +++ b/open-reac/src/main/java/com/powsybl/openreac/parameters/OpenReacAmplIOFiles.java @@ -14,6 +14,7 @@ import com.powsybl.openreac.parameters.input.algo.AlgorithmInput; import com.powsybl.openreac.parameters.output.OpenReacResult; import com.powsybl.openreac.parameters.output.ReactiveSlackOutput; +import com.powsybl.openreac.parameters.output.VoltageProfileOutput; import com.powsybl.openreac.parameters.output.network.NetworkModifications; import java.util.ArrayList; @@ -40,6 +41,7 @@ public class OpenReacAmplIOFiles implements AmplParameters { private final VoltageLevelLimitsOverrideInput voltageLimitsOverride; private final ConfiguredBusesWithReactiveSlack configuredReactiveSlackBuses; private final NetworkModifications networkModifications; + private final VoltageProfileOutput voltageProfileOutput; private final boolean debug; public OpenReacAmplIOFiles(OpenReacParameters params, Network network, boolean debug) { @@ -54,6 +56,7 @@ public OpenReacAmplIOFiles(OpenReacParameters params, Network network, boolean d //outputs this.reactiveSlackOutput = new ReactiveSlackOutput(); this.networkModifications = new NetworkModifications(network); + this.voltageProfileOutput = new VoltageProfileOutput(); this.debug = debug; } @@ -66,6 +69,10 @@ public NetworkModifications getNetworkModifications() { return networkModifications; } + public VoltageProfileOutput getVoltageProfileOutput() { + return voltageProfileOutput; + } + @Override public Collection getInputParameters() { return List.of(constantQGenerators, variableShuntCompensators, variableTwoWindingsTransformers, @@ -76,9 +83,10 @@ public Collection getInputParameters() { public Collection getOutputParameters(boolean isConvergenceOk) { if (isConvergenceOk) { List networkModificationsOutputFiles = networkModifications.getOutputFiles(); - List list = new ArrayList<>(networkModificationsOutputFiles.size() + 1); + List list = new ArrayList<>(networkModificationsOutputFiles.size() + 2); list.addAll(networkModificationsOutputFiles); list.add(reactiveSlackOutput); + list.add(voltageProfileOutput); return list; } return List.of(); diff --git a/open-reac/src/main/java/com/powsybl/openreac/parameters/output/OpenReacResult.java b/open-reac/src/main/java/com/powsybl/openreac/parameters/output/OpenReacResult.java index a7ea265a..361df858 100644 --- a/open-reac/src/main/java/com/powsybl/openreac/parameters/output/OpenReacResult.java +++ b/open-reac/src/main/java/com/powsybl/openreac/parameters/output/OpenReacResult.java @@ -7,15 +7,16 @@ package com.powsybl.openreac.parameters.output; import com.powsybl.iidm.modification.*; +import com.powsybl.iidm.modification.tapchanger.AbstractTapPositionModification; import com.powsybl.iidm.modification.tapchanger.RatioTapPositionModification; -import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.*; import com.powsybl.openreac.parameters.OpenReacAmplIOFiles; import com.powsybl.openreac.parameters.output.ReactiveSlackOutput.ReactiveSlack; +import org.jgrapht.alg.util.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; /** * OpenReac user interface to get results information. @@ -24,6 +25,7 @@ */ public class OpenReacResult { + private static final Logger LOGGER = LoggerFactory.getLogger(OpenReacResult.class); private final OpenReacStatus status; private final List reactiveSlacks; private final Map indicators; @@ -32,6 +34,8 @@ public class OpenReacResult { private final List vscModifications; private final List svcModifications; private final List tapPositionModifications; + private final HashMap> voltageProfile; + private boolean updateNetworkWithVoltages = true; /** * @param status the final status of the OpenReac run. @@ -48,6 +52,7 @@ public OpenReacResult(OpenReacStatus status, OpenReacAmplIOFiles amplIOFiles, Ma this.vscModifications = List.copyOf(amplIOFiles.getNetworkModifications().getVscModifications()); this.svcModifications = List.copyOf(amplIOFiles.getNetworkModifications().getSvcModifications()); this.tapPositionModifications = List.copyOf(amplIOFiles.getNetworkModifications().getTapPositionModifications()); + this.voltageProfile = new HashMap<>(amplIOFiles.getVoltageProfileOutput().getVoltageProfile()); } public OpenReacStatus getStatus() { @@ -82,7 +87,19 @@ public List getVscModifications() { return vscModifications; } - public List getAllModifs() { + public Map> getVoltageProfile() { + return voltageProfile; + } + + public boolean isUpdateNetworkWithVoltages() { + return updateNetworkWithVoltages; + } + + public void setUpdateNetworkWithVoltages(boolean updateNetworkWithVoltages) { + this.updateNetworkWithVoltages = updateNetworkWithVoltages; + } + + public List getAllNetworkModifications() { List modifs = new ArrayList<>(getGeneratorModifications().size() + getShuntsModifications().size() + getSvcModifications().size() + @@ -97,8 +114,71 @@ public List getAllModifs() { } public void applyAllModifications(Network network) { - for (NetworkModification modif : getAllModifs()) { + for (NetworkModification modif : getAllNetworkModifications()) { modif.apply(network); } + + // update target of ratio tap changers specified as variable by user + getTapPositionModifications().stream() + .map(AbstractTapPositionModification::getTransformerId) + .map(network::getTwoWindingsTransformer) + .forEach(transformer -> { + RatioTapChanger ratioTapChanger = transformer.getRatioTapChanger(); + if (ratioTapChanger != null) { + Optional bus = getRegulatingBus(ratioTapChanger.getRegulationTerminal(), transformer.getId()); + bus.ifPresent(b -> { + Pair busUpdate = voltageProfile.get(b.getId()); + if (busUpdate != null) { + ratioTapChanger.setTargetV(busUpdate.getFirst() * b.getVoltageLevel().getNominalV()); + } else { + throw new IllegalStateException("Voltage profile not found for bus " + b.getId()); + } + }); + } + }); + + // update target of shunts specified as variable by user + getShuntsModifications().stream() + .map(ShuntCompensatorModification::getShuntCompensatorId) + .map(network::getShuntCompensator) + .forEach(shunt -> { + Optional bus = getRegulatingBus(shunt.getRegulatingTerminal(), shunt.getId()); + bus.ifPresent(b -> { + Pair busUpdate = voltageProfile.get(b.getId()); + if (busUpdate != null) { + shunt.setTargetV(busUpdate.getFirst() * b.getVoltageLevel().getNominalV()); + } else { + throw new IllegalStateException("Voltage profile not found for bus " + b.getId()); + } + }); + }); + + // update voltages of the buses + if (isUpdateNetworkWithVoltages()) { + for (var busUpdate : voltageProfile.entrySet()) { + Optional.ofNullable(network.getBusView().getBus(busUpdate.getKey())).ifPresentOrElse( + bus -> { + double v = busUpdate.getValue().getFirst(); + double angle = busUpdate.getValue().getSecond(); + bus.setV(v * bus.getVoltageLevel().getNominalV()); + bus.setAngle(Math.toDegrees(angle)); + }, () -> { + throw new IllegalStateException("Bus " + busUpdate.getKey() + " not found in network " + network.getId()); + }); + } + } + } + + Optional getRegulatingBus(Terminal terminal, String elementId) { + if (terminal == null) { + LOGGER.warn("Regulating terminal of element {} is null.", elementId); + return Optional.empty(); + } + Bus bus = terminal.getBusView().getBus(); + if (bus == null) { + LOGGER.warn("Bus of regulating terminal of element {} is null.", elementId); + return Optional.empty(); + } + return Optional.ofNullable(bus); } } diff --git a/open-reac/src/main/java/com/powsybl/openreac/parameters/output/VoltageProfileOutput.java b/open-reac/src/main/java/com/powsybl/openreac/parameters/output/VoltageProfileOutput.java new file mode 100644 index 00000000..8ace718d --- /dev/null +++ b/open-reac/src/main/java/com/powsybl/openreac/parameters/output/VoltageProfileOutput.java @@ -0,0 +1,57 @@ +/** + * 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/. + */ +package com.powsybl.openreac.parameters.output; + +import com.powsybl.ampl.converter.AmplSubset; +import com.powsybl.commons.util.StringToIntMapper; +import com.powsybl.openreac.parameters.AmplIOUtils; +import org.jgrapht.alg.util.Pair; + +import java.util.*; + +/** + * @author Pierre Arvy + */ +public class VoltageProfileOutput extends AbstractNoThrowOutput { + + private static final String ELEMENT = "voltages"; + public static final int EXPECTED_COLS = 5; + private static final int ID_COLUMN_INDEX = 4; + private static final int V_COLUMN_INDEX = 2; + private static final int ANGLE_COLUMN_INDEX = 3; + + private final Map> voltageProfile = new HashMap<>(); + + public Map> getVoltageProfile() { + return voltageProfile; + } + + @Override + public String getElement() { + return ELEMENT; + } + + @Override + public int getExpectedColumns() { + return EXPECTED_COLS; + } + + @Override + protected void readLine(String[] tokens, StringToIntMapper stringToIntMapper) { + String id = AmplIOUtils.removeQuotes(tokens[ID_COLUMN_INDEX]); + double v = readDouble(tokens[V_COLUMN_INDEX]); + double angle = readDouble(tokens[ANGLE_COLUMN_INDEX]); + voltageProfile.put(id, Pair.of(v, angle)); + } + + @Override + public boolean throwOnMissingFile() { + triggerErrorState(); + return false; + } + +} diff --git a/open-reac/src/main/resources/openreac/reactiveopfoutput.run b/open-reac/src/main/resources/openreac/reactiveopfoutput.run index cd87a102..184edefb 100644 --- a/open-reac/src/main/resources/openreac/reactiveopfoutput.run +++ b/open-reac/src/main/resources/openreac/reactiveopfoutput.run @@ -190,6 +190,24 @@ close (fileOut); +############################################################################### +# +# Writing results for buses states +# +############################################################################### +if final_status == "OK" then { + + let fileOut := "reactiveopf_results_voltages.csv"; + printf "#variant;bus;V(pu);theta(rad);id;\n" > (fileOut); + printf {n in BUSCC} "%i;%i;%.3f;%.3f;%s;\n", + 1, n, V[n], teta[n], '"' & bus_id[1,n] & '"' + > (fileOut); + close (fileOut); + +} + + + ############################################################################### # # Writing results for LCC converters diff --git a/open-reac/src/test/java/com/powsybl/openreac/OpenReacResultsTest.java b/open-reac/src/test/java/com/powsybl/openreac/OpenReacResultsTest.java new file mode 100644 index 00000000..0ef57e52 --- /dev/null +++ b/open-reac/src/test/java/com/powsybl/openreac/OpenReacResultsTest.java @@ -0,0 +1,118 @@ +package com.powsybl.openreac; + +import com.powsybl.ieeecdf.converter.IeeeCdfNetworkFactory; +import com.powsybl.iidm.modification.ShuntCompensatorModification; +import com.powsybl.iidm.modification.tapchanger.RatioTapPositionModification; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.RatioTapChanger; +import com.powsybl.iidm.network.ShuntCompensator; +import com.powsybl.openreac.network.ShuntNetworkFactory; +import com.powsybl.openreac.network.VoltageControlNetworkFactory; +import com.powsybl.openreac.parameters.OpenReacAmplIOFiles; +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.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class OpenReacResultsTest { + + @Test + void testTransformerTargetVUpdateWithoutVoltageResult() throws IOException { + Network network = VoltageControlNetworkFactory.createNetworkWithT2wt(); + String t2wtId = "T2wT"; + RatioTapChanger rtc = network.getTwoWindingsTransformer(t2wtId).getRatioTapChanger() + .setTargetDeadband(0) + .setRegulating(true); + + // add transformer as variable for target V update + OpenReacAmplIOFiles io = getIOWithMockVoltageProfile(network); + io.getNetworkModifications().getTapPositionModifications().add(new RatioTapPositionModification(t2wtId, 0)); + + OpenReacResult results = new OpenReacResult(OpenReacStatus.OK, io, new HashMap<>()); + IllegalStateException e = assertThrows(IllegalStateException.class, () -> results.applyAllModifications(network)); + assertEquals("Voltage profile not found for bus " + rtc.getRegulationTerminal().getBusView().getBus().getId(), e.getMessage()); + } + + @Test + void testTransformerTargetVUpdateWithoutRegulationBus() throws IOException { + Network network = VoltageControlNetworkFactory.createNetworkWithT2wt(); + String t2wtId = "T2wT"; + RatioTapChanger rtc = network.getTwoWindingsTransformer(t2wtId).getRatioTapChanger() + .setTargetDeadband(0) + .setRegulating(true); + rtc.getRegulationTerminal().disconnect(); + + // add transformer as variable for target V update + OpenReacAmplIOFiles io = getIOWithMockVoltageProfile(network); + io.getNetworkModifications().getTapPositionModifications().add(new RatioTapPositionModification(t2wtId, 0)); + + // apply results without warm start (to avoid exception) + OpenReacResult results = new OpenReacResult(OpenReacStatus.OK, io, new HashMap<>()); + results.setUpdateNetworkWithVoltages(false); + results.applyAllModifications(network); + + // target V is not updated + assertEquals(33, rtc.getTargetV()); + } + + @Test + void testShuntTargetVUpdateWithoutVoltageResult() throws IOException { + Network network = ShuntNetworkFactory.create(); + ShuntCompensator shunt = network.getShuntCompensator("SHUNT"); + String regulatedBusId = shunt.getRegulatingTerminal().getBusView().getBus().getId(); + + OpenReacAmplIOFiles io = getIOWithMockVoltageProfile(network); + io.getNetworkModifications().getShuntModifications().add(new ShuntCompensatorModification("SHUNT", true, 0)); + + OpenReacResult results = new OpenReacResult(OpenReacStatus.OK, io, new HashMap<>()); + IllegalStateException e = assertThrows(IllegalStateException.class, () -> results.applyAllModifications(network)); + assertEquals("Voltage profile not found for bus " + regulatedBusId, e.getMessage()); + } + + @Test + void testShuntUpdateWithoutRegulationBus() throws IOException { + Network network = ShuntNetworkFactory.create(); + ShuntCompensator shunt = network.getShuntCompensator("SHUNT"); + shunt.getRegulatingTerminal().disconnect(); + + OpenReacAmplIOFiles io = getIOWithMockVoltageProfile(network); + io.getNetworkModifications().getShuntModifications().add(new ShuntCompensatorModification("SHUNT", null, 0)); + + // apply results without warm start + OpenReacResult results = new OpenReacResult(OpenReacStatus.OK, io, new HashMap<>()); + results.setUpdateNetworkWithVoltages(false); + results.applyAllModifications(network); + + // target V not updated + assertEquals(393, shunt.getTargetV()); + } + + @Test + void testWrongVoltageResult() throws IOException { + Network network = IeeeCdfNetworkFactory.create14(); + OpenReacAmplIOFiles io = getIOWithMockVoltageProfile(network); + String idBusNotFound = io.getVoltageProfileOutput().getVoltageProfile().keySet().iterator().next(); + OpenReacResult results = new OpenReacResult(OpenReacStatus.OK, io, new HashMap<>()); + IllegalStateException e = assertThrows(IllegalStateException.class, () -> results.applyAllModifications(network)); + assertEquals("Bus " + idBusNotFound + " not found in network " + network.getId(), e.getMessage()); + } + + private OpenReacAmplIOFiles getIOWithMockVoltageProfile(Network network) throws IOException { + OpenReacAmplIOFiles io = new OpenReacAmplIOFiles(new OpenReacParameters(), network, true); + try (InputStream input = getClass().getResourceAsStream("/mock_outputs/reactiveopf_results_voltages.csv"); + InputStreamReader in = new InputStreamReader(input); + BufferedReader reader = new BufferedReader(in)) { + io.getVoltageProfileOutput().read(reader, null); + } + return io; + } +} diff --git a/open-reac/src/test/java/com/powsybl/openreac/OpenReacRunnerTest.java b/open-reac/src/test/java/com/powsybl/openreac/OpenReacRunnerTest.java index cc081d71..91edd507 100644 --- a/open-reac/src/test/java/com/powsybl/openreac/OpenReacRunnerTest.java +++ b/open-reac/src/test/java/com/powsybl/openreac/OpenReacRunnerTest.java @@ -41,8 +41,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; /** * @author Geoffroy Jamgotchian @@ -200,7 +199,8 @@ public void testOutputFileParsing() throws IOException { "mock_outputs/reactiveopf_results_rtc.csv", "mock_outputs/reactiveopf_results_shunts.csv", "mock_outputs/reactiveopf_results_static_var_compensators.csv", - "mock_outputs/reactiveopf_results_vsc_converter_stations.csv")); + "mock_outputs/reactiveopf_results_vsc_converter_stations.csv", + "mock_outputs/reactiveopf_results_voltages.csv")); try (ComputationManager computationManager = new LocalComputationManager(new LocalComputationConfig(tmpDir), localCommandExecutor, ForkJoinPool.commonPool())) { OpenReacResult openReacResult = OpenReacRunner.run(network, @@ -213,6 +213,7 @@ public void testOutputFileParsing() throws IOException { assertEquals(1, openReacResult.getSvcModifications().size()); assertEquals(1, openReacResult.getVscModifications().size()); assertEquals(7, openReacResult.getGeneratorModifications().size()); + assertEquals(3, openReacResult.getVoltageProfile().size()); assertEquals(82, openReacResult.getIndicators().size()); assertTrue(openReacResult.getReactiveSlacks().isEmpty()); } @@ -230,7 +231,8 @@ void testRunAsync() throws IOException { 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_vsc_converter_stations.csv", + subFolder + "/reactiveopf_results_voltages.csv")); // To really run open reac, use the commented 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), @@ -244,23 +246,7 @@ void testRunAsync() throws IOException { } private void testAllModifAndLoadFlow(Network network, String subFolder, OpenReacParameters parameters) throws IOException { - 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")); - // 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, new OpenReacConfig(true), - computationManager); - assertEquals(OpenReacStatus.OK, openReacResult.getStatus()); - openReacResult.applyAllModifications(network); - } + runAndApplyAllModifications(network, subFolder, parameters, true); LoadFlowResult loadFlowResult = LoadFlow.run(network); assertTrue(loadFlowResult.isOk()); } @@ -295,23 +281,37 @@ public void testSvc() throws IOException { } @Test - public void testShuntReconnection() throws IOException { + void testShunt() throws IOException { Network network = create(); setDefaultVoltageLimits(network); // set default voltage limits to every voltage levels of the network + ShuntCompensator shunt = network.getShuntCompensator("SHUNT"); + assertFalse(shunt.getTerminal().isConnected()); + assertEquals(393, shunt.getTargetV()); + OpenReacParameters parameters = new OpenReacParameters(); - parameters.addVariableShuntCompensators(List.of("SHUNT")); + parameters.addVariableShuntCompensators(List.of(shunt.getId())); testAllModifAndLoadFlow(network, "openreac-output-shunt", parameters); + assertTrue(shunt.getTerminal().isConnected()); // shunt has been reconnected + assertEquals(420.8, shunt.getTargetV()); // targetV has been updated } @Test public void testTransformer() throws IOException { Network network = VoltageControlNetworkFactory.createNetworkWithT2wt(); setDefaultVoltageLimits(network); // set default voltage limits to every voltage levels of the network - network.getTwoWindingsTransformer("T2wT").getRatioTapChanger().setTapPosition(2); + RatioTapChanger rtc = network.getTwoWindingsTransformer("T2wT").getRatioTapChanger() + .setTapPosition(2) + .setTargetDeadband(0) + .setRegulating(true); + assertEquals(2, rtc.getTapPosition()); + assertEquals(33.0, rtc.getTargetV()); + OpenReacParameters parameters = new OpenReacParameters(); parameters.addConstantQGenerators(List.of("GEN_1")); parameters.addVariableTwoWindingsTransformers(List.of("T2wT")); testAllModifAndLoadFlow(network, "openreac-output-transfo", parameters); + assertEquals(0, rtc.getTapPosition()); + assertEquals(22.935, rtc.getTargetV()); } @Test @@ -322,6 +322,52 @@ public void testRealNetwork() throws IOException { testAllModifAndLoadFlow(network, "openreac-output-real-network", parameters); } + @Test + void testWarmStart() throws IOException { + Network network = VoltageControlNetworkFactory.createNetworkWithT2wt(); + setDefaultVoltageLimits(network); + String subFolder = "openreac-output-warm-start"; + OpenReacParameters parameters = new OpenReacParameters(); + + runAndApplyAllModifications(network, subFolder, parameters, false); // without warm start, no update + assertEquals(Double.NaN, network.getBusBreakerView().getBus("BUS_1").getV()); + assertEquals(Double.NaN, network.getBusBreakerView().getBus("BUS_1").getAngle()); + assertEquals(Double.NaN, network.getBusBreakerView().getBus("BUS_2").getV()); + assertEquals(Double.NaN, network.getBusBreakerView().getBus("BUS_2").getAngle()); + assertEquals(Double.NaN, network.getBusBreakerView().getBus("BUS_3").getV()); + assertEquals(Double.NaN, network.getBusBreakerView().getBus("BUS_3").getAngle()); + + runAndApplyAllModifications(network, subFolder, parameters, true); + assertEquals(119.592, network.getBusBreakerView().getBus("BUS_1").getV()); + assertEquals(0.802, network.getBusBreakerView().getBus("BUS_1").getAngle(), 0.001); + assertEquals(118.8, network.getBusBreakerView().getBus("BUS_2").getV()); + assertEquals(0, network.getBusBreakerView().getBus("BUS_2").getAngle()); + assertEquals(22.935, network.getBusBreakerView().getBus("BUS_3").getV()); + assertEquals(-4.698, network.getBusBreakerView().getBus("BUS_3").getAngle(), 0.001); + } + + private void runAndApplyAllModifications(Network network, String subFolder, OpenReacParameters parameters, boolean updateNetworkWithVoltages) throws IOException { + 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")); + // 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, + new OpenReacConfig(true), computationManager); + assertEquals(OpenReacStatus.OK, openReacResult.getStatus()); + openReacResult.setUpdateNetworkWithVoltages(updateNetworkWithVoltages); + openReacResult.applyAllModifications(network); + } + } + public static Network create() { Network network = Network.create("svc", "test"); Substation s1 = network.newSubstation() diff --git a/open-reac/src/test/java/com/powsybl/openreac/parameters/output/VoltageProfileOutputTest.java b/open-reac/src/test/java/com/powsybl/openreac/parameters/output/VoltageProfileOutputTest.java new file mode 100644 index 00000000..45f31e26 --- /dev/null +++ b/open-reac/src/test/java/com/powsybl/openreac/parameters/output/VoltageProfileOutputTest.java @@ -0,0 +1,46 @@ +package com.powsybl.openreac.parameters.output; + +import org.jgrapht.alg.util.Pair; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import static org.junit.jupiter.api.Assertions.*; + +class VoltageProfileOutputTest { + + @Test + void readTest() throws IOException { + VoltageProfileOutput output = new VoltageProfileOutput(); + try (InputStream input = getClass().getResourceAsStream("/mock_outputs/reactiveopf_results_voltages.csv"); + InputStreamReader in = new InputStreamReader(input); + BufferedReader reader = new BufferedReader(in)) { + + output.read(reader, null); + assertEquals(3, output.getVoltageProfile().size()); + Pair busVoltage1 = output.getVoltageProfile().get("bus1"); + Pair busVoltage2 = output.getVoltageProfile().get("bus2"); + Pair busVoltage3 = output.getVoltageProfile().get("bus3"); + Assertions.assertAll( + () -> assertEquals(0.8, busVoltage1.getFirst()), + () -> assertEquals(1.1, busVoltage1.getSecond()), + () -> assertEquals(1.2, busVoltage2.getFirst()), + () -> assertEquals(Double.NaN, busVoltage2.getSecond()), + () -> assertEquals(Double.NaN, busVoltage3.getFirst()), + () -> assertEquals(0.11, busVoltage3.getSecond()) + ); + } + } + + @Test + void testErrorState() { + VoltageProfileOutput output = new VoltageProfileOutput(); + boolean throwOnMissingFile = output.throwOnMissingFile(); + assertFalse(throwOnMissingFile); + assertTrue(output.isErrorState()); + } +} diff --git a/open-reac/src/test/resources/mock_outputs/reactiveopf_results_voltages.csv b/open-reac/src/test/resources/mock_outputs/reactiveopf_results_voltages.csv new file mode 100644 index 00000000..c2325da4 --- /dev/null +++ b/open-reac/src/test/resources/mock_outputs/reactiveopf_results_voltages.csv @@ -0,0 +1,4 @@ +#variant;bus;V(pu);theta(rad);id; +1;1;0.8;1.1;'bus1'; +1;2;1.2;-99999;'bus2'; +1;1;-99999;0.11;'bus3'; diff --git a/open-reac/src/test/resources/openreac-output-ieee14/reactiveopf_results_indic.txt b/open-reac/src/test/resources/openreac-output-ieee14/reactiveopf_results_indic.txt index 46d921f9..cfcba5f7 100644 --- a/open-reac/src/test/resources/openreac-output-ieee14/reactiveopf_results_indic.txt +++ b/open-reac/src/test/resources/openreac-output-ieee14/reactiveopf_results_indic.txt @@ -1,18 +1,18 @@ final_status OK dcopf_status OK -ctime_start 'Fri Nov 24 11:59:34 2023' +ctime_start 'Wed Jan 10 14:48:12 2024' last_solve_result_num 0 nb_iter_last 6 nb_iter_total 6 -_ampl_elapsed_time 0.125000 -_total_solve_time 0.031250 +_ampl_elapsed_time 0.047000 +_total_solve_time 0.046875 total_time 0 operatingSystem windows OS 'Windows_NT' COMPUTERNAME 'ARTELYS-PC253' -directory 'C:\Users\parvy\AppData\Local\Temp\ampl_12583331805904096086' +directory 'C:\Users\parvy\AppData\Local\Temp\ampl_18317757654451996032' log_level_ampl INFO log_level_knitro 2 diff --git a/open-reac/src/test/resources/openreac-output-ieee14/reactiveopf_results_voltages.csv b/open-reac/src/test/resources/openreac-output-ieee14/reactiveopf_results_voltages.csv new file mode 100644 index 00000000..58d56b24 --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-ieee14/reactiveopf_results_voltages.csv @@ -0,0 +1,15 @@ +#variant;bus;V(pu);theta(rad);id; +1;1;1.083;0.168;"VL1_0"; +1;2;1.045;0.089;"VL2_0"; +1;3;0.971;-0.042;"VL3_0"; +1;4;0.991;0.000;"VL4_0"; +1;5;0.995;0.027;"VL5_0"; +1;6;0.973;-0.084;"VL6_0"; +1;7;1.050;-0.057;"VL7_0"; +1;8;1.500;-0.057;"VL8_0"; +1;9;0.918;-0.085;"VL9_0"; +1;10;0.919;-0.091;"VL10_0"; +1;11;0.942;-0.090;"VL11_0"; +1;12;0.954;-0.102;"VL12_0"; +1;13;0.945;-0.102;"VL13_0"; +1;14;0.909;-0.115;"VL14_0"; diff --git a/open-reac/src/test/resources/openreac-output-real-network/reactiveopf_results_indic.txt b/open-reac/src/test/resources/openreac-output-real-network/reactiveopf_results_indic.txt index 420331e6..b617eff6 100644 --- a/open-reac/src/test/resources/openreac-output-real-network/reactiveopf_results_indic.txt +++ b/open-reac/src/test/resources/openreac-output-real-network/reactiveopf_results_indic.txt @@ -1,18 +1,18 @@ final_status OK dcopf_status OK -ctime_start 'Fri Nov 24 12:03:02 2023' +ctime_start 'Wed Jan 10 14:49:19 2024' last_solve_result_num 0 nb_iter_last 7 nb_iter_total 7 -_ampl_elapsed_time 0.110000 +_ampl_elapsed_time 0.095000 _total_solve_time 0.031250 total_time 0 operatingSystem windows OS 'Windows_NT' COMPUTERNAME 'ARTELYS-PC253' -directory 'C:\Users\parvy\AppData\Local\Temp\ampl_3114721600970297698' +directory 'C:\Users\parvy\AppData\Local\Temp\ampl_7845811466926249191' log_level_ampl INFO log_level_knitro 2 diff --git a/open-reac/src/test/resources/openreac-output-real-network/reactiveopf_results_voltages.csv b/open-reac/src/test/resources/openreac-output-real-network/reactiveopf_results_voltages.csv new file mode 100644 index 00000000..52ca94d3 --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-real-network/reactiveopf_results_voltages.csv @@ -0,0 +1,58 @@ +#variant;bus;V(pu);theta(rad);id; +1;1;1.393;0.040;"VL1_0"; +1;2;1.382;0.040;"VL2_0"; +1;3;1.390;0.032;"VL3_0"; +1;4;1.392;0.023;"VL4_0"; +1;5;1.442;-0.016;"VL4_1"; +1;6;1.391;0.018;"VL5_0"; +1;7;1.393;0.020;"VL6_0"; +1;8;1.395;0.034;"VL7_0"; +1;9;1.442;0.014;"VL7_1"; +1;10;1.403;0.067;"VL8_0"; +1;11;1.379;0.013;"VL9_0"; +1;12;1.460;0.002;"VL9_1"; +1;13;1.374;-0.008;"VL10_0"; +1;14;1.475;-0.017;"VL10_1"; +1;15;1.372;0.001;"VL11_0"; +1;16;1.432;-0.032;"VL11_1"; +1;17;1.431;-0.009;"VL11_2"; +1;18;1.376;0.001;"VL12_0"; +1;19;1.368;0.000;"VL13_0"; +1;20;1.480;-0.029;"VL13_1"; +1;21;1.364;-0.001;"VL14_0"; +1;22;1.500;-0.016;"VL14_1"; +1;23;1.380;0.012;"VL15_0"; +1;24;1.456;-0.001;"VL15_1"; +1;25;1.379;-0.001;"VL16_0"; +1;26;1.381;0.011;"VL17_0"; +1;27;1.413;-0.029;"VL19_0"; +1;28;1.404;-0.031;"VL20_0"; +1;29;1.461;-0.030;"VL20_1"; +1;30;1.460;-0.029;"VL22_0"; +1;31;1.460;-0.030;"VL23_0"; +1;32;1.467;-0.031;"VL24_0"; +1;33;1.482;-0.070;"VL24_1"; +1;34;1.406;-0.027;"VL24_2"; +1;35;1.422;-0.006;"VL27_0"; +1;36;1.432;0.006;"VL28_0"; +1;37;1.467;-0.074;"VL30_0"; +1;38;1.445;-0.078;"VL31_0"; +1;39;1.447;-0.071;"VL32_0"; +1;40;1.424;-0.039;"VL32_1"; +1;41;1.445;-0.071;"VL33_0"; +1;42;1.427;-0.037;"VL35_0"; +1;43;1.433;-0.034;"VL36_0"; +1;44;1.439;-0.033;"VL37_0"; +1;45;1.461;-0.028;"VL38_0"; +1;46;1.438;-0.033;"VL39_0"; +1;47;1.427;-0.059;"VL39_1"; +1;48;1.429;-0.034;"VL40_0"; +1;49;1.427;-0.054;"VL40_1"; +1;50;1.419;-0.047;"VL42_0"; +1;51;1.457;-0.022;"VL44_0"; +1;52;1.478;-0.028;"VL47_0"; +1;53;1.473;-0.028;"VL48_0"; +1;54;1.465;-0.030;"VL50_0"; +1;55;1.428;-0.005;"VL52_0"; +1;56;1.425;-0.013;"VL53_0"; +1;57;1.440;-0.007;"VL54_0"; diff --git a/open-reac/src/test/resources/openreac-output-shunt/reactiveopf_results_indic.txt b/open-reac/src/test/resources/openreac-output-shunt/reactiveopf_results_indic.txt index a205a5f3..bd50fa75 100644 --- a/open-reac/src/test/resources/openreac-output-shunt/reactiveopf_results_indic.txt +++ b/open-reac/src/test/resources/openreac-output-shunt/reactiveopf_results_indic.txt @@ -1,18 +1,18 @@ final_status OK dcopf_status OK -ctime_start 'Fri Nov 24 12:01:56 2023' +ctime_start 'Wed Jan 10 12:29:15 2024' last_solve_result_num 0 nb_iter_last 29 nb_iter_total 29 -_ampl_elapsed_time 0.077000 -_total_solve_time 0.031250 +_ampl_elapsed_time 0.062000 +_total_solve_time 0.000000 total_time 0 operatingSystem windows OS 'Windows_NT' COMPUTERNAME 'ARTELYS-PC253' -directory 'C:\Users\parvy\AppData\Local\Temp\ampl_12369045109419234150' +directory 'C:\Users\parvy\AppData\Local\Temp\ampl_16952986494138910718' log_level_ampl INFO log_level_knitro 2 diff --git a/open-reac/src/test/resources/openreac-output-shunt/reactiveopf_results_voltages.csv b/open-reac/src/test/resources/openreac-output-shunt/reactiveopf_results_voltages.csv new file mode 100644 index 00000000..d6f739bd --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-shunt/reactiveopf_results_voltages.csv @@ -0,0 +1,4 @@ +#variant;bus;V(pu);theta(rad);id; +1;1;1.050;0.002;"vl1_0"; +1;2;1.049;0.000;"vl2_0"; +1;3;1.052;-0.001;"vl3_0"; diff --git a/open-reac/src/test/resources/openreac-output-svc/reactiveopf_results_indic.txt b/open-reac/src/test/resources/openreac-output-svc/reactiveopf_results_indic.txt index a9224ea0..76c4722a 100644 --- a/open-reac/src/test/resources/openreac-output-svc/reactiveopf_results_indic.txt +++ b/open-reac/src/test/resources/openreac-output-svc/reactiveopf_results_indic.txt @@ -1,18 +1,18 @@ final_status OK dcopf_status OK -ctime_start 'Fri Nov 24 12:01:27 2023' +ctime_start 'Wed Jan 10 12:32:41 2024' last_solve_result_num 0 nb_iter_last 6 nb_iter_total 6 -_ampl_elapsed_time 0.094000 +_ampl_elapsed_time 0.093000 _total_solve_time 0.031250 total_time 0 operatingSystem windows OS 'Windows_NT' COMPUTERNAME 'ARTELYS-PC253' -directory 'C:\Users\parvy\AppData\Local\Temp\ampl_11598000998118468803' +directory 'C:\Users\parvy\AppData\Local\Temp\ampl_60840544416039339' log_level_ampl INFO log_level_knitro 2 diff --git a/open-reac/src/test/resources/openreac-output-svc/reactiveopf_results_voltages.csv b/open-reac/src/test/resources/openreac-output-svc/reactiveopf_results_voltages.csv new file mode 100644 index 00000000..e9648927 --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-svc/reactiveopf_results_voltages.csv @@ -0,0 +1,3 @@ +#variant;bus;V(pu);theta(rad);id; +1;1;1.050;0.002;"vl1_0"; +1;2;1.049;0.000;"vl2_0"; diff --git a/open-reac/src/test/resources/openreac-output-transfo/reactiveopf_results_indic.txt b/open-reac/src/test/resources/openreac-output-transfo/reactiveopf_results_indic.txt index b898ef32..6c3fb12f 100644 --- a/open-reac/src/test/resources/openreac-output-transfo/reactiveopf_results_indic.txt +++ b/open-reac/src/test/resources/openreac-output-transfo/reactiveopf_results_indic.txt @@ -1,18 +1,18 @@ final_status OK dcopf_status OK -ctime_start 'Fri Nov 24 12:02:34 2023' +ctime_start 'Wed Jan 10 12:32:01 2024' last_solve_result_num 0 nb_iter_last 4 nb_iter_total 4 -_ampl_elapsed_time 0.095000 +_ampl_elapsed_time 0.125000 _total_solve_time 0.031250 total_time 0 operatingSystem windows OS 'Windows_NT' COMPUTERNAME 'ARTELYS-PC253' -directory 'C:\Users\parvy\AppData\Local\Temp\ampl_7140935963031466466' +directory 'C:\Users\parvy\AppData\Local\Temp\ampl_4525712114905560758' log_level_ampl INFO log_level_knitro 2 diff --git a/open-reac/src/test/resources/openreac-output-transfo/reactiveopf_results_voltages.csv b/open-reac/src/test/resources/openreac-output-transfo/reactiveopf_results_voltages.csv new file mode 100644 index 00000000..38af3a57 --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-transfo/reactiveopf_results_voltages.csv @@ -0,0 +1,4 @@ +#variant;bus;V(pu);theta(rad);id; +1;1;0.906;0.014;"VL_1_0"; +1;2;0.900;0.000;"VL_2_0"; +1;3;0.695;-0.082;"VL_3_0"; diff --git a/open-reac/src/test/resources/openreac-output-vsc/reactiveopf_results_indic.txt b/open-reac/src/test/resources/openreac-output-vsc/reactiveopf_results_indic.txt index 07bad8c4..79889398 100644 --- a/open-reac/src/test/resources/openreac-output-vsc/reactiveopf_results_indic.txt +++ b/open-reac/src/test/resources/openreac-output-vsc/reactiveopf_results_indic.txt @@ -1,7 +1,7 @@ final_status OK dcopf_status OK -ctime_start 'Fri Nov 24 12:01:03 2023' +ctime_start 'Wed Jan 10 12:33:19 2024' last_solve_result_num 0 nb_iter_last 6 nb_iter_total 6 @@ -12,7 +12,7 @@ total_time 0 operatingSystem windows OS 'Windows_NT' COMPUTERNAME 'ARTELYS-PC253' -directory 'C:\Users\parvy\AppData\Local\Temp\ampl_2514974589581916563' +directory 'C:\Users\parvy\AppData\Local\Temp\ampl_1855145751103852938' log_level_ampl INFO log_level_knitro 2 diff --git a/open-reac/src/test/resources/openreac-output-vsc/reactiveopf_results_voltages.csv b/open-reac/src/test/resources/openreac-output-vsc/reactiveopf_results_voltages.csv new file mode 100644 index 00000000..7859766f --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-vsc/reactiveopf_results_voltages.csv @@ -0,0 +1,7 @@ +#variant;bus;V(pu);theta(rad);id; +1;1;0.568;-0.707;"b1_vl_0"; +1;2;0.500;-0.927;"b2_vl_0"; +1;3;0.651;-0.810;"b3_vl_0"; +1;4;0.651;0.117;"b4_vl_0"; +1;5;0.500;0.000;"b5_vl_0"; +1;6;0.568;0.220;"b6_vl_0"; diff --git a/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_generators.csv b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_generators.csv new file mode 100644 index 00000000..d111e44e --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_generators.csv @@ -0,0 +1,2 @@ +#variant;num;bus;vRegul;V(pu);targetP(MW);targetQ(Mvar);P(MW);Q(MW); +1;1;1;'true';0.906;25.0;7.9;-21.2;-7.9; diff --git a/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_indic.txt b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_indic.txt new file mode 100644 index 00000000..22759e32 --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_indic.txt @@ -0,0 +1,88 @@ +final_status OK +dcopf_status OK + +ctime_start 'Thu Jan 11 15:12:16 2024' +last_solve_result_num 0 +nb_iter_last 5 +nb_iter_total 5 +_ampl_elapsed_time 0.047000 +_total_solve_time 0.031250 +total_time 0 + +operatingSystem windows +OS 'Windows_NT' +COMPUTERNAME 'ARTELYS-PC253' +directory 'C:\Users\parvy\AppData\Local\Temp\ampl_1724309836662612364' + +log_level_ampl INFO +log_level_knitro 2 +objective_choice 0 +ratio_voltage_target 0.500000 +coeff_alpha 1.000000 +Pnull 0.010000 +Znull 0.000100 +epsilon_nominal_voltage 1.000000 +min_plausible_low_voltage_limit 0.500000 +max_plausible_high_voltage_limit 1.500000 +ignore_voltage_bounds 0.000000 +buses_with_reactive_slacks NO_GENERATION +PQmax 9000.000000 +defaultPmax 1000.000000 +defaultPmin 0.000000 +defaultQmaxPmaxRatio 0.300000 +defaultQmin -300.000000 +defaultQmax 300.000000 +minimalQPrange 1.000000 + +nb_substations 3 +nb_bus_in_data_file 3 +nb_bus_in_ACDC_CC 3 +nb_bus_in_AC_CC 3 +nb_bus_in_ACDC_but_out_AC_CC 0 +nb_bus_with_voltage_value 0 +nb_bus_with_reactive_slacks 2 +nb_bus_without_reactive_slacks 1 +nb_branch_in_data_file 2 +nb_branch_in_AC_CC 2 +nb_branch_with_nonsmall_impedance 2 +nb_branch_with_zero_or_small_impedance 0 +nb_unit_in_data_file 1 +nb_unit_in_AC_CC 1 +nb_unit_up_and_running 1 +nb_unit_with_variable_reactive_power 1 +nb_unit_with_fixed_reactive_power 0 +nb_load_in_data_file 2 +nb_load_in_AC_CC 2 +nb_shunt_in_data_file 0 +nb_shunt_connectable_or_in_AC_CC 0 +nb_shunt_with_fixed_value 0 +nb_shunt_with_variable_value 0 +nb_transformers_with_variable_ratio 0 +nb_transformers_with_fixed_ratio 1 +nb_svc_in_data_file 0 +nb_svc_in_AC_CC 0 +nb_svc_up_and_operating 0 +nb_vsc_converter_in_data_file 0 +nb_vsc_converter_up_and_running 0 +nb_lcc_converter_in_data_file 0 +nb_lcc_converter_up_and_running 0 +nb_batteries 0 +sum_batteries_pmax 0.0 +sum_batteries_pmin 0.0 + +max_teta_dc 0.01 +max_teta_ac 0.01 +teta_max 3.01 +min_teta_dc -0.05 +min_teta_ac -0.08 +teta_min -3.05 +max_delta_teta_dc 0.045914 +max_delta_teta_ac 0.081650 +min_delta_teta_dc 0.009298 +min_delta_teta_ac 0.014293 + +nb_reactive_slacks 0 +nb_slacks_condensator 0 +sum_slacks_condensator 0.0 +nb_slacks_self 0 +sum_slacks_self 0.0 diff --git a/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_rtc.csv b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_rtc.csv new file mode 100644 index 00000000..9a62a138 --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_rtc.csv @@ -0,0 +1 @@ +#variant;num;tap; diff --git a/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_shunts.csv b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_shunts.csv new file mode 100644 index 00000000..8d515fde --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_shunts.csv @@ -0,0 +1 @@ +#variant;num;bus;b(pu);Q(Mvar);section; diff --git a/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_static_var_compensators.csv b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_static_var_compensators.csv new file mode 100644 index 00000000..6792ddb9 --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_static_var_compensators.csv @@ -0,0 +1 @@ +#variant;num;bus;vRegul;V(pu);Q(Mvar); diff --git a/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_voltages.csv b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_voltages.csv new file mode 100644 index 00000000..38af3a57 --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_voltages.csv @@ -0,0 +1,4 @@ +#variant;bus;V(pu);theta(rad);id; +1;1;0.906;0.014;"VL_1_0"; +1;2;0.900;0.000;"VL_2_0"; +1;3;0.695;-0.082;"VL_3_0"; diff --git a/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_vsc_converter_stations.csv b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_vsc_converter_stations.csv new file mode 100644 index 00000000..aa24858c --- /dev/null +++ b/open-reac/src/test/resources/openreac-output-warm-start/reactiveopf_results_vsc_converter_stations.csv @@ -0,0 +1 @@ +#variant;num;bus;vRegul;targetV(pu);targetQ(Mvar);P(MW);Q(Mvar);