Skip to content

Commit

Permalink
Build PreContingencyResult from Dynawo result (#409)
Browse files Browse the repository at this point in the history
Build PreContingencyResult from aggregated results and constraints files for DSA

Signed-off-by: lisrte <[email protected]>
  • Loading branch information
Lisrte authored Dec 12, 2024
1 parent 8cc4bad commit ce17eb5
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 51 deletions.
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 @@ -16,10 +16,7 @@
import com.powsybl.dynawo.commons.timeline.XmlTimeLineParser;
import com.powsybl.iidm.network.Network;
import com.powsybl.loadflow.LoadFlowResult;
import com.powsybl.security.LimitViolation;
import com.powsybl.security.LimitViolationFilter;
import com.powsybl.security.LimitViolationsResult;
import com.powsybl.security.Security;
import com.powsybl.security.*;
import com.powsybl.security.results.NetworkResult;
import com.powsybl.security.results.PostContingencyResult;
import com.powsybl.security.results.PreContingencyResult;
Expand All @@ -31,6 +28,7 @@
import java.util.List;
import java.util.Map;

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 @@ -42,37 +40,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())))
.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)))
.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);
}
}

0 comments on commit ce17eb5

Please sign in to comment.