com.powsybl.action.simulator.loadflow.ParallelLoadFlowActionSimulator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of powsybl-action-simulator Show documentation
Show all versions of powsybl-action-simulator Show documentation
A tool to run simulations with preventive or curative actions
/**
* Copyright (c) 2018, 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.action.simulator.loadflow;
import com.google.common.collect.ImmutableList;
import com.powsybl.commons.PowsyblException;
import com.powsybl.computation.*;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.xml.NetworkXml;
import com.powsybl.security.SecurityAnalysisResult;
import com.powsybl.security.SecurityAnalysisResultMerger;
import com.powsybl.security.json.SecurityAnalysisResultDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import static com.powsybl.action.simulator.tools.ActionSimulatorToolConstants.*;
import static com.powsybl.tools.ToolConstants.TASK;
/**
* Runs a load flow action simulator through calls to itools action-simulator command,
* submitted to the computation manager.
*
* @author Yichen Tang
* @author Teofil Calin BANC
*/
public class ParallelLoadFlowActionSimulator {
private static final Logger LOGGER = LoggerFactory.getLogger(ParallelLoadFlowActionSimulator.class);
private static final String ITOOLS_PRG = "itools";
private final ComputationManager computationManager;
private final Network network;
private final LoadFlowActionSimulatorConfig config;
private final boolean applyIfSolved;
private final int taskCount;
private final List> resultHandlers;
private static final String SUB_TASK_ID = "sas"; // sub_action_simulator
public ParallelLoadFlowActionSimulator(Network network, ComputationManager cm, int taskCount) {
this(network, cm, taskCount, LoadFlowActionSimulatorConfig.load(), false, Collections.emptyList());
}
public ParallelLoadFlowActionSimulator(Network network, ComputationManager cm, int taskCount, LoadFlowActionSimulatorConfig config,
boolean applyIfSolved, Consumer... resultHandlers) {
this(network, cm, taskCount, config, applyIfSolved, Arrays.asList(resultHandlers));
}
public ParallelLoadFlowActionSimulator(Network network, ComputationManager cm, int taskCount, LoadFlowActionSimulatorConfig config,
boolean applyIfSolved, List> resultHandlers) {
this.network = Objects.requireNonNull(network);
this.computationManager = Objects.requireNonNull(cm);
this.config = Objects.requireNonNull(config);
this.applyIfSolved = applyIfSolved;
this.taskCount = taskCount;
this.resultHandlers = ImmutableList.copyOf(Objects.requireNonNull(resultHandlers));
}
/**
* Runs a load flow action simulator through calls to itools action-simulator command,
* submitted to the computation manager.
*
* @param script the content of the groovy DSL script representing contingencies and actions.
*
*/
public void run(String script, List contingencyIds) {
LOGGER.debug("Starting parallel action simulator.");
ExecutionEnvironment itoolsEnvironment = new ExecutionEnvironment(Collections.emptyMap(), "subTask_", config.isDebug());
int actualTaskCount = Math.min(taskCount, contingencyIds.size());
CompletableFuture future = computationManager.execute(itoolsEnvironment, new SubTaskHandler(actualTaskCount, script, contingencyIds));
try {
SecurityAnalysisResult result = future.get();
resultHandlers.forEach(h -> h.accept(result));
} catch (Exception e) {
throw new PowsyblException(e);
}
}
/**
* Execution handler for sub-tasks.
* copies network and groovy file to working directory,
* then launches one itools command for each subtask.
* Finally, reads and merge results.
*/
private final class SubTaskHandler extends AbstractExecutionHandler {
private final int actualTaskCount;
private final String script;
private final List contingencyIds;
private SubTaskHandler(int actualTaskCount, String script, List contingencyIds) {
this.actualTaskCount = actualTaskCount;
this.script = script;
this.contingencyIds = contingencyIds;
}
@Override
public List before(Path workingDir) throws IOException {
SimpleCommand subItoolsCmd = buildCommand(workingDir)
.program(ITOOLS_PRG)
.id(SUB_TASK_ID)
.build();
return Collections.singletonList(new CommandExecution(subItoolsCmd, actualTaskCount, 1));
}
/**
* Reads result files and merge them.
*/
@Override
public SecurityAnalysisResult after(Path workingDir, ExecutionReport report) throws IOException {
super.after(workingDir, report);
LOGGER.debug("End of command execution in {}. ", workingDir);
List results = new ArrayList<>();
for (int taskNum = 0; taskNum < actualTaskCount; taskNum++) {
Path taskResultFile = workingDir.resolve(getOutputFileName(taskNum));
results.add(SecurityAnalysisResultDeserializer.read(taskResultFile));
}
return SecurityAnalysisResultMerger.merge(results);
}
private String getOutputFileName(int taskNumber) {
return "task_" + taskNumber + "_result.json";
}
private SimpleCommandBuilder buildCommand(Path workingDir) throws IOException {
SimpleCommandBuilder builder = new SimpleCommandBuilder();
// copy input files to slave workingDir
Path networkDest = workingDir.resolve("network.xiidm");
LOGGER.debug("Copying network to file {}", networkDest);
NetworkXml.write(network, networkDest);
Path dslFileDest = workingDir.resolve("strategy.groovy");
LOGGER.debug("Copying strategy file to {}", dslFileDest);
Files.write(dslFileDest, script.getBytes(StandardCharsets.UTF_8));
builder
.arg("action-simulator")
.option(CASE_FILE, networkDest.toString())
.option(DSL_FILE, dslFileDest.toString())
.option(TASK, i -> new Partition(i + 1, actualTaskCount).toString())
.option(OUTPUT_FILE, this::getOutputFileName)
.option(OUTPUT_FORMAT, "JSON")
.flag(APPLY_IF_SOLVED_VIOLATIONS, applyIfSolved);
if (!contingencyIds.isEmpty()) {
builder.option(CONTINGENCIES, String.join(",", contingencyIds));
}
return builder;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy