diff --git a/open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java b/open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java index 3447afa6..41a728bc 100644 --- a/open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java +++ b/open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java @@ -9,6 +9,7 @@ import com.powsybl.ampl.executor.AmplModel; import com.powsybl.ampl.executor.AmplModelRunner; import com.powsybl.ampl.executor.AmplResults; +import com.powsybl.commons.reporter.Reporter; import com.powsybl.computation.ComputationManager; import com.powsybl.computation.local.LocalComputationManager; import com.powsybl.iidm.network.Network; @@ -30,30 +31,40 @@ private OpenReacRunner() { /** * Run OpenReac on the given network. It will NOT modify the network. - * @param variantId the network variant to use. It will set the variant on the network. + * + * @param variantId the network variant to use. It will set the variant on the network. * @param parameters Parameters to customize the OpenReac run. * @return All information about the run and possible modifications to apply. */ public static OpenReacResult run(Network network, String variantId, OpenReacParameters parameters) { - return run(network, variantId, parameters, new OpenReacConfig(false), LocalComputationManager.getDefault()); + return run(network, variantId, parameters, new OpenReacConfig(false), LocalComputationManager.getDefault(), Reporter.NO_OP); } /** * Run OpenReac on the given network. It will NOT modify the network. - * @param variantId the network variant to use. It will set the variant on the network. + * + * @param variantId the network variant to use. It will set the variant on the network. * @param parameters Parameters to customize the OpenReac run. - * @param config allows debugging + * @param config allows debugging * @return All information about the run and possible modifications to apply. */ public static OpenReacResult run(Network network, String variantId, OpenReacParameters parameters, OpenReacConfig config, ComputationManager manager) { - Objects.requireNonNull(network); - Objects.requireNonNull(variantId); - Objects.requireNonNull(parameters); - Objects.requireNonNull(config); - Objects.requireNonNull(manager); - parameters.checkIntegrity(network); + return run(network, variantId, parameters, config, manager, Reporter.NO_OP); + } + + /** + * Run OpenReac on the given network. It will NOT modify the network. + * + * @param variantId the network variant to use. It will set the variant on the network. + * @param parameters Parameters to customize the OpenReac run. + * @param config allows debugging + * @param reporter aggregates functional logging + * @return All information about the run and possible modifications to apply. + */ + public static OpenReacResult run(Network network, String variantId, OpenReacParameters parameters, OpenReacConfig config, ComputationManager manager, Reporter reporter) { + checkParameters(network, variantId, parameters, config, manager, reporter); AmplModel reactiveOpf = OpenReacModel.buildModel(); - OpenReacAmplIOFiles amplIoInterface = new OpenReacAmplIOFiles(parameters, network, config.isDebug()); + OpenReacAmplIOFiles amplIoInterface = new OpenReacAmplIOFiles(parameters, network, config.isDebug(), Reports.createOpenReacReporter(reporter, network.getId(), parameters.getObjective())); AmplResults run = AmplModelRunner.run(network, variantId, reactiveOpf, manager, amplIoInterface); return new OpenReacResult(run.isSuccess() && amplIoInterface.checkErrors() ? OpenReacStatus.OK : OpenReacStatus.NOT_OK, amplIoInterface, run.getIndicators()); @@ -61,22 +72,41 @@ public static OpenReacResult run(Network network, String variantId, OpenReacPara /** * Run OpenReac on the given network. It will NOT modify the network. - * @param variantId the network variant to use. It will set the variant on the network. + * + * @param variantId the network variant to use. It will set the variant on the network. * @param parameters Parameters to customize the OpenReac run. - * @param config allows debugging + * @param config allows debugging * @return All information about the run and possible modifications to apply. */ public static CompletableFuture runAsync(Network network, String variantId, OpenReacParameters parameters, OpenReacConfig config, ComputationManager manager) { + return runAsync(network, variantId, parameters, config, manager, Reporter.NO_OP); + } + + /** + * Run OpenReac on the given network. It will NOT modify the network. + * + * @param variantId the network variant to use. It will set the variant on the network. + * @param parameters Parameters to customize the OpenReac run. + * @param config allows debugging + * @param reporter aggregates functional logging + * @return All information about the run and possible modifications to apply. + */ + public static CompletableFuture runAsync(Network network, String variantId, OpenReacParameters parameters, OpenReacConfig config, ComputationManager manager, Reporter reporter) { + checkParameters(network, variantId, parameters, config, manager, reporter); + AmplModel reactiveOpf = OpenReacModel.buildModel(); + OpenReacAmplIOFiles amplIoInterface = new OpenReacAmplIOFiles(parameters, network, config.isDebug(), Reports.createOpenReacReporter(reporter, network.getId(), parameters.getObjective())); + CompletableFuture runAsync = AmplModelRunner.runAsync(network, variantId, reactiveOpf, manager, amplIoInterface); + return runAsync.thenApply(run -> new OpenReacResult(run.isSuccess() && amplIoInterface.checkErrors() ? OpenReacStatus.OK : OpenReacStatus.NOT_OK, + amplIoInterface, run.getIndicators())); + } + + private static void checkParameters(Network network, String variantId, OpenReacParameters parameters, OpenReacConfig config, ComputationManager manager, Reporter reporter) { Objects.requireNonNull(network); Objects.requireNonNull(variantId); Objects.requireNonNull(parameters); Objects.requireNonNull(config); Objects.requireNonNull(manager); + Objects.requireNonNull(reporter); parameters.checkIntegrity(network); - AmplModel reactiveOpf = OpenReacModel.buildModel(); - OpenReacAmplIOFiles amplIoInterface = new OpenReacAmplIOFiles(parameters, network, config.isDebug()); - CompletableFuture runAsync = AmplModelRunner.runAsync(network, variantId, reactiveOpf, manager, amplIoInterface); - return runAsync.thenApply(run -> new OpenReacResult(run.isSuccess() && amplIoInterface.checkErrors() ? OpenReacStatus.OK : OpenReacStatus.NOT_OK, - amplIoInterface, run.getIndicators())); } } diff --git a/open-reac/src/main/java/com/powsybl/openreac/Reports.java b/open-reac/src/main/java/com/powsybl/openreac/Reports.java new file mode 100644 index 00000000..ab7937b4 --- /dev/null +++ b/open-reac/src/main/java/com/powsybl/openreac/Reports.java @@ -0,0 +1,62 @@ +/** + * 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; + +import com.powsybl.commons.reporter.Report; +import com.powsybl.commons.reporter.Reporter; +import com.powsybl.commons.reporter.TypedValue; +import com.powsybl.openreac.parameters.input.algo.OpenReacOptimisationObjective; + +import java.util.Map; + +/** + * @author Joris Mancini + */ +public final class Reports { + + private Reports() { + // Should not be instantiated + } + + public static Reporter createOpenReacReporter(Reporter reporter, String networkId, OpenReacOptimisationObjective objective) { + return reporter.createSubReporter( + "openReac", + "Open Reac on network '${networkId}' with ${objective} objective", + Map.of( + "networkId", new TypedValue(networkId, TypedValue.UNTYPED), + "objective", new TypedValue(objective.toString(), TypedValue.UNTYPED) + ) + ); + } + + public static void reportConstantQGeneratorsSize(Reporter reporter, int constantQGeneratorsSize) { + reporter.report(Report.builder() + .withKey("constantQGeneratorsSize") + .withDefaultMessage("Reactive power target is considered fixed for ${size} generators") + .withSeverity(TypedValue.INFO_SEVERITY) + .withValue("size", constantQGeneratorsSize) + .build()); + } + + public static void reportVariableTwoWindingsTransformersSize(Reporter reporter, int variableTwoWindingsTransformersSize) { + reporter.report(Report.builder() + .withKey("variableTwoWindingsTransformersSize") + .withDefaultMessage("There are ${size} two-winding transformers with tap position considered as variable") + .withSeverity(TypedValue.INFO_SEVERITY) + .withValue("size", variableTwoWindingsTransformersSize) + .build()); + } + + public static void reportVariableShuntCompensatorsSize(Reporter reporter, int variableShuntCompensatorsSize) { + reporter.report(Report.builder() + .withKey("variableShuntCompensatorsSize") + .withDefaultMessage("There are ${size} shunt compensators with section considered as variable") + .withSeverity(TypedValue.INFO_SEVERITY) + .withValue("size", variableShuntCompensatorsSize) + .build()); + } +} 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 b11f47c5..43c6010d 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 @@ -9,7 +9,9 @@ import com.powsybl.ampl.executor.AmplInputFile; import com.powsybl.ampl.executor.AmplOutputFile; import com.powsybl.ampl.executor.AmplParameters; +import com.powsybl.commons.reporter.Reporter; import com.powsybl.iidm.network.Network; +import com.powsybl.openreac.Reports; import com.powsybl.openreac.parameters.input.*; import com.powsybl.openreac.parameters.input.algo.AlgorithmInput; import com.powsybl.openreac.parameters.output.OpenReacResult; @@ -44,7 +46,7 @@ public class OpenReacAmplIOFiles implements AmplParameters { private final VoltageProfileOutput voltageProfileOutput; private final boolean debug; - public OpenReacAmplIOFiles(OpenReacParameters params, Network network, boolean debug) { + public OpenReacAmplIOFiles(OpenReacParameters params, Network network, boolean debug, Reporter reporter) { //inputs this.constantQGenerators = new ConstantQGenerators(params.getConstantQGenerators()); this.variableShuntCompensators = new VariableShuntCompensators(params.getVariableShuntCompensators()); @@ -59,6 +61,10 @@ public OpenReacAmplIOFiles(OpenReacParameters params, Network network, boolean d this.voltageProfileOutput = new VoltageProfileOutput(); this.debug = debug; + + Reports.reportConstantQGeneratorsSize(reporter, params.getConstantQGenerators().size()); + Reports.reportVariableTwoWindingsTransformersSize(reporter, params.getVariableTwoWindingsTransformers().size()); + Reports.reportVariableShuntCompensatorsSize(reporter, params.getVariableShuntCompensators().size()); } public ReactiveSlackOutput getReactiveSlackOutput() { diff --git a/open-reac/src/test/java/com/powsybl/openreac/OpenReacResultsTest.java b/open-reac/src/test/java/com/powsybl/openreac/OpenReacResultsTest.java index 0ef57e52..ab1b3879 100644 --- a/open-reac/src/test/java/com/powsybl/openreac/OpenReacResultsTest.java +++ b/open-reac/src/test/java/com/powsybl/openreac/OpenReacResultsTest.java @@ -1,5 +1,6 @@ package com.powsybl.openreac; +import com.powsybl.commons.reporter.Reporter; import com.powsybl.ieeecdf.converter.IeeeCdfNetworkFactory; import com.powsybl.iidm.modification.ShuntCompensatorModification; import com.powsybl.iidm.modification.tapchanger.RatioTapPositionModification; @@ -107,7 +108,7 @@ void testWrongVoltageResult() throws IOException { } private OpenReacAmplIOFiles getIOWithMockVoltageProfile(Network network) throws IOException { - OpenReacAmplIOFiles io = new OpenReacAmplIOFiles(new OpenReacParameters(), network, true); + OpenReacAmplIOFiles io = new OpenReacAmplIOFiles(new OpenReacParameters(), network, true, Reporter.NO_OP); try (InputStream input = getClass().getResourceAsStream("/mock_outputs/reactiveopf_results_voltages.csv"); InputStreamReader in = new InputStreamReader(input); BufferedReader reader = new BufferedReader(in)) {