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

Build PreContingencyResult from Dynawo result #409

Open
wants to merge 1 commit into
base: bus_disconnection
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -26,18 +26,17 @@
import com.powsybl.security.LimitViolationFilter;
import com.powsybl.security.SecurityAnalysisParameters;
import com.powsybl.security.SecurityAnalysisReport;
import com.powsybl.security.SecurityAnalysisResult;
import com.powsybl.security.interceptors.SecurityAnalysisInterceptor;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;

import static com.powsybl.dynaflow.DynaFlowConstants.CONFIG_FILENAME;
import static com.powsybl.dynaflow.SecurityAnalysisConstants.CONTINGENCIES_FILENAME;
import static com.powsybl.dynaflow.results.ContingencyResultsUtils.createSecurityAnalysisResult;
import static com.powsybl.dynawo.commons.DynawoConstants.NETWORK_FILENAME;
import static com.powsybl.dynawo.commons.DynawoConstants.TIMELINE_FOLDER;
import static com.powsybl.dynawo.commons.DynawoUtil.getCommandExecutions;
Expand Down Expand Up @@ -85,12 +84,7 @@ public SecurityAnalysisReport after(Path workingDir, ExecutionReport report) thr
super.after(workingDir, report);
network.getVariantManager().setWorkingVariant(workingVariantId);
ContingencyResultsUtils.reportContingenciesTimelines(contingencies, workingDir.resolve(TIMELINE_FOLDER), reportNode);
return new SecurityAnalysisReport(
new SecurityAnalysisResult(
ContingencyResultsUtils.getPreContingencyResult(network, violationFilter),
ContingencyResultsUtils.getPostContingencyResults(network, violationFilter, workingDir, contingencies),
Collections.emptyList())
);
return new SecurityAnalysisReport(createSecurityAnalysisResult(network, violationFilter, workingDir, contingencies));
}

private static void writeContingencies(List<Contingency> contingencies, Path workingDir) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public final class SecurityAnalysisConstants {

public static final String CONTINGENCIES_FILENAME = "contingencies.json";

public static final String BASE_SCENARIO_NAME = "Base";

private SecurityAnalysisConstants() {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.Map;
import java.util.stream.Collectors;

import static com.powsybl.dynaflow.SecurityAnalysisConstants.BASE_SCENARIO_NAME;
import static com.powsybl.dynaflow.SecurityAnalysisConstants.CONSTRAINTS_FOLDER;
import static com.powsybl.dynawo.commons.DynawoConstants.AGGREGATED_RESULTS;

Expand All @@ -40,37 +41,59 @@ public final class ContingencyResultsUtils {
private ContingencyResultsUtils() {
}

public static SecurityAnalysisResult createSecurityAnalysisResult(Network network, LimitViolationFilter violationFilter,
Path workingDir, List<Contingency> contingencies) {
Map<String, Status> aggregatedResults = getAggregatedResults(workingDir);
Path constraintsDir = workingDir.resolve(CONSTRAINTS_FOLDER);
return new SecurityAnalysisResult(
ContingencyResultsUtils.getPreContingencyResult(network, violationFilter, constraintsDir, aggregatedResults),
ContingencyResultsUtils.getPostContingencyResults(network, violationFilter, constraintsDir, aggregatedResults, contingencies),
Collections.emptyList());
}

/**
* Build the pre-contingency results from the input network
* Build the pre-contingency results from the constraints file written by dynawo or directly form the network if the results are not found
*/
public static PreContingencyResult getPreContingencyResult(Network network, LimitViolationFilter violationFilter) {
List<LimitViolation> limitViolations = Security.checkLimits(network);
List<LimitViolation> filteredViolations = violationFilter.apply(limitViolations, network);
private static PreContingencyResult getPreContingencyResult(Network network, LimitViolationFilter violationFilter,
Path constraintsDir, Map<String, Status> scenarioResults) {
NetworkResult networkResult = new NetworkResult(Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
return new PreContingencyResult(LoadFlowResult.ComponentResult.Status.CONVERGED, new LimitViolationsResult(filteredViolations), networkResult);
if (scenarioResults.containsKey(BASE_SCENARIO_NAME)) {
return new PreContingencyResult(ResultsUtil.convertToPreStatus(scenarioResults.get(BASE_SCENARIO_NAME)),
getLimitViolationsResult(network, violationFilter, constraintsDir, BASE_SCENARIO_NAME),
networkResult);
} else {
//Dynaflow SA case (see issue #174)
List<LimitViolation> limitViolations = Security.checkLimits(network);
List<LimitViolation> filteredViolations = violationFilter.apply(limitViolations, network);
return new PreContingencyResult(LoadFlowResult.ComponentResult.Status.CONVERGED, new LimitViolationsResult(filteredViolations), networkResult);
}
}

/**
* Build the post-contingency results from the constraints files written by dynawo
*/
public static List<PostContingencyResult> getPostContingencyResults(Network network, LimitViolationFilter violationFilter,
Path workingDir, List<Contingency> contingencies) {
Path constraintsDir = workingDir.resolve(CONSTRAINTS_FOLDER);
private static List<PostContingencyResult> getPostContingencyResults(Network network, LimitViolationFilter violationFilter,
Path constraintsDir, Map<String, Status> scenarioResults,
List<Contingency> contingencies) {
return contingencies.stream()
.map(c -> new PostContingencyResult(c,
ResultsUtil.convertToPostStatus(scenarioResults.getOrDefault(c.getId(), Status.EXECUTION_PROBLEM)),
getLimitViolationsResult(network, violationFilter, constraintsDir, c.getId())))
.collect(Collectors.toList());
}

private static Map<String, Status> getAggregatedResults(Path workingDir) {
Path results = workingDir.resolve(AGGREGATED_RESULTS);
Map<String, Status> scenarioResults = new HashMap<>();
if (Files.exists(results)) {
new XmlScenarioResultParser().parse(results, s -> scenarioResults.put(s.id(), s.status()));
}
return contingencies.stream()
.map(c -> new PostContingencyResult(c,
ResultsUtil.convertStatus(scenarioResults.getOrDefault(c.getId(), Status.EXECUTION_PROBLEM)),
getLimitViolationsResult(network, violationFilter, constraintsDir, c)))
.collect(Collectors.toList());
return scenarioResults;
}

private static LimitViolationsResult getLimitViolationsResult(Network network, LimitViolationFilter violationFilter,
Path constraintsDir, Contingency contingency) {
Path constraintsFile = constraintsDir.resolve("constraints_" + contingency.getId() + ".xml");
Path constraintsDir, String contingencyName) {
Path constraintsFile = constraintsDir.resolve("constraints_" + contingencyName + ".xml");
if (Files.exists(constraintsFile)) {
List<LimitViolation> limitViolationsRead = ConstraintsReader.read(network, constraintsFile);
List<LimitViolation> limitViolationsFiltered = violationFilter.apply(limitViolationsRead, network);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
package com.powsybl.dynaflow.results;

import com.powsybl.loadflow.LoadFlowResult;
import com.powsybl.security.PostContingencyComputationStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -16,7 +17,6 @@

import static com.powsybl.dynaflow.results.Status.CONVERGENCE;
import static com.powsybl.dynaflow.results.Status.CRITERIA_NON_RESPECTED;
import static com.powsybl.security.PostContingencyComputationStatus.*;

/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
Expand All @@ -28,11 +28,18 @@ private ResultsUtil() {

private static final Logger LOGGER = LoggerFactory.getLogger(ResultsUtil.class);

public static PostContingencyComputationStatus convertStatus(Status status) {
public static PostContingencyComputationStatus convertToPostStatus(Status status) {
return switch (status) {
case CONVERGENCE -> CONVERGED;
case DIVERGENCE -> SOLVER_FAILED;
case EXECUTION_PROBLEM, CRITERIA_NON_RESPECTED -> FAILED;
case CONVERGENCE -> PostContingencyComputationStatus.CONVERGED;
case DIVERGENCE -> PostContingencyComputationStatus.SOLVER_FAILED;
case EXECUTION_PROBLEM, CRITERIA_NON_RESPECTED -> PostContingencyComputationStatus.FAILED;
};
}

public static LoadFlowResult.ComponentResult.Status convertToPreStatus(Status status) {
return switch (status) {
case CONVERGENCE -> LoadFlowResult.ComponentResult.Status.CONVERGED;
case DIVERGENCE, EXECUTION_PROBLEM, CRITERIA_NON_RESPECTED -> LoadFlowResult.ComponentResult.Status.FAILED;
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.regex.Pattern;

/**
* @author Marcos de Miguel {@literal <demiguelm at aia.es>}
Expand All @@ -53,6 +54,7 @@ public final class ConstraintsReader {

private static final Supplier<XMLInputFactory> XML_INPUT_FACTORY_SUPPLIER = Suppliers.memoize(XMLInputFactory::newInstance);
public static final String DYN_CALCULATED_BUS_PREFIX = "calculatedBus_";
public static final Pattern DYN_CALCULATED_BUS_PATTERN = Pattern.compile("calculatedBus_" + ".*_\\d*");

public static List<LimitViolation> read(Network network, Path xmlFile) {
try (InputStream is = Files.newInputStream(xmlFile)) {
Expand Down Expand Up @@ -130,7 +132,7 @@ private static Optional<LimitViolation> getLimitViolation(Network network, Strin
}

private static Optional<Identifiable<?>> getLimitViolationIdentifiable(Network network, String name) {
if (name.matches(DYN_CALCULATED_BUS_PREFIX + ".*_\\d*")) {
if (DYN_CALCULATED_BUS_PATTERN.matcher(name).matches()) {
// FIXME: the voltage level information should be directly referenced
// The naming corresponds to buses which are calculated in dynawo: https://github.com/dynawo/dynawo/blob/8f1e20e43db7ec4d2e4982deac8307dfa8d0dbec/dynawo/sources/Modeler/DataInterface/PowSyblIIDM/DYNVoltageLevelInterfaceIIDM.cpp#L290
String vlId = name.substring(DYN_CALCULATED_BUS_PREFIX.length(), name.lastIndexOf("_"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
"subjectId" : "_BUS____1-BUS____2-1_AC",
"subjectName" : "BUS 1-BUS 2-1",
"limitType" : "CURRENT",
"limitName" : "permanent",
"limitName" : "PATL",
"limit" : 836.74,
"limitReduction" : 1.0,
"value" : 1248.0773003764798,
"value" : 1248.100487597837,
"side" : "ONE"
} ],
"actionsTaken" : [ ]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"version" : "1.7",
"preContingencyResult" : {
"status" : "CONVERGED",
"status" : "FAILED",
"limitViolationsResult" : {
"limitViolations" : [ {
"subjectId" : "_BUS____1-BUS____2-1_AC",
"subjectName" : "BUS 1-BUS 2-1",
"limitType" : "CURRENT",
"limitName" : "permanent",
"limitName" : "PATL",
"limit" : 836.74,
"limitReduction" : 1.0,
"value" : 1248.0773003764798,
"value" : 1248.100487597837,
"side" : "ONE"
} ],
"actionsTaken" : [ ]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"version" : "1.7",
"preContingencyResult" : {
"status" : "CONVERGED",
"status" : "FAILED",
"limitViolationsResult" : {
"limitViolations" : [ {
"subjectId" : "_BUS____1-BUS____2-1_AC",
"subjectName" : "BUS 1-BUS 2-1",
"limitType" : "CURRENT",
"limitName" : "permanent",
"limitName" : "PATL",
"limit" : 836.74,
"limitReduction" : 1.0,
"value" : 1248.0773003764798,
"value" : 1248.100487597837,
"side" : "ONE"
} ],
"actionsTaken" : [ ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,16 @@
import com.powsybl.iidm.serde.NetworkSerDe;
import com.powsybl.security.LimitViolationFilter;
import com.powsybl.security.SecurityAnalysisReport;
import com.powsybl.security.SecurityAnalysisResult;
import com.powsybl.security.interceptors.SecurityAnalysisInterceptor;

import javax.xml.stream.XMLStreamException;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;

import static com.powsybl.dynaflow.results.ContingencyResultsUtils.createSecurityAnalysisResult;
import static com.powsybl.dynawo.DynawoFilesUtils.deleteExistingFile;
import static com.powsybl.dynawo.commons.DynawoConstants.*;
import static com.powsybl.dynawo.commons.DynawoUtil.getCommandExecutions;
Expand Down Expand Up @@ -79,13 +78,7 @@ public SecurityAnalysisReport after(Path workingDir, ExecutionReport report) thr
NetworkResultsUpdater.update(context.getNetwork(), NetworkSerDe.read(outputNetworkFile), context.getDynawoSimulationParameters().isMergeLoads());
}
ContingencyResultsUtils.reportContingenciesTimelines(context.getContingencies(), workingDir.resolve(TIMELINE_FOLDER), reportNode);

return new SecurityAnalysisReport(
new SecurityAnalysisResult(
ContingencyResultsUtils.getPreContingencyResult(network, violationFilter),
ContingencyResultsUtils.getPostContingencyResults(network, violationFilter, workingDir, context.getContingencies()),
Collections.emptyList())
);
return new SecurityAnalysisReport(createSecurityAnalysisResult(network, violationFilter, workingDir, context.getContingencies()));
}

private void writeInputFiles(Path workingDir) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.nio.file.Path;
import java.util.Objects;

import static com.powsybl.dynaflow.SecurityAnalysisConstants.BASE_SCENARIO_NAME;
import static com.powsybl.dynawo.DynawoSimulationConstants.JOBS_FILENAME;
import static com.powsybl.dynawo.DynawoSimulationConstants.MULTIPLE_JOBS_FILENAME;

Expand Down Expand Up @@ -52,6 +53,6 @@ private static void writeScenario(XMLStreamWriter writer, String id) throws XMLS

private static void writeBaseScenario(XMLStreamWriter writer) throws XMLStreamException {
writer.writeEmptyElement("scenario");
writer.writeAttribute("id", "Base");
writer.writeAttribute("id", BASE_SCENARIO_NAME);
}
}
Loading