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

[WIP] Fix SA reports in MT, an support operator strategies in MT #1168

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Next Next commit
Fix SA reports in MT, an support operator strategies in MT
Signed-off-by: Didier Vidal <didier.vidal_externe@rte-france.com>
  • Loading branch information
vidaldid-rte committed Jan 9, 2025
commit 352dd988b806b3a1b2df075a899406f46f5b8637
Original file line number Diff line number Diff line change
@@ -42,6 +42,8 @@
import com.powsybl.security.results.*;
import com.powsybl.security.strategy.ConditionalActions;
import com.powsybl.security.strategy.OperatorStrategy;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@@ -155,7 +157,8 @@ SecurityAnalysisReport runSync(SecurityAnalysisParameters securityAnalysisParame

// create networks including all necessary switches
try (LfNetworkList lfNetworks = Networks.load(network, parameters.getNetworkParameters(), topoConfig, saReportNode)) {
finalResult = runSimulationsOnAllComponents(lfNetworks, propagatedContingencies, parameters, securityAnalysisParameters, operatorStrategies, actions, limitReductions, lfParameters);
finalResult = runSimulationsOnAllComponents(lfNetworks, propagatedContingencies, parameters, securityAnalysisParameters, operatorStrategies, actions, limitReductions, lfParameters,
lfNetworks.getList().stream().collect(Collectors.toMap(n -> new ImmutablePair<>(n.getNumCC(), n.getNumSC()), n -> n.getReportNode())));
}

} else {
@@ -171,6 +174,7 @@ SecurityAnalysisReport runSync(SecurityAnalysisParameters securityAnalysisParame
try {
Lock networkLock = new ReentrantLock();
List<CompletableFuture<Void>> futures = new ArrayList<>();
Map<Pair<Integer, Integer>, ReportNode> ccNetworkReportNodes = new HashMap<>();
for (int i = 0; i < contingenciesPartitions.size(); i++) {
final int partitionNum = i;
var contingenciesPartition = contingenciesPartitions.get(i);
@@ -192,22 +196,32 @@ SecurityAnalysisReport runSync(SecurityAnalysisParameters securityAnalysisParame
P parameters;
networkLock.lock();
try {
boolean first = ccNetworkReportNodes.isEmpty();
network.getVariantManager().setWorkingVariant(workingVariantId);

propagatedContingencies = PropagatedContingency.createList(network, contingenciesPartition, partitionTopoConfig, creationParameters);

parameters = createParameters(lfParameters, lfParametersExt, partitionTopoConfig.isBreaker());

// create networks including all necessary switches
lfNetworks = Networks.load(network, parameters.getNetworkParameters(), partitionTopoConfig, saReportNode);
// LfNetworks creation reports are only made for the first partition
lfNetworks = Networks.load(network, parameters.getNetworkParameters(), partitionTopoConfig, first ? saReportNode : ReportNode.NO_OP);
lfNetworksList.add(0, lfNetworks); // FIXME to workaround variant removal bug, to fix in core

if (first) {
// List CC reports to attach post contingency result
for (LfNetwork n : lfNetworks.getList()) {
ccNetworkReportNodes.put(new ImmutablePair<>(n.getNumCC(), n.getNumSC()), n.getReportNode());
}
}
} finally {
networkLock.unlock();
}

// run simulation on largest network
partitionResults.set(partitionNum, runSimulationsOnAllComponents(
lfNetworks, propagatedContingencies, parameters, securityAnalysisParameters, operatorStrategies, actions, limitReductions, lfParameters));
lfNetworks, propagatedContingencies, parameters, securityAnalysisParameters, operatorStrategies, actions, limitReductions, lfParameters,
ccNetworkReportNodes));

return null;
}, executor));
@@ -250,7 +264,8 @@ SecurityAnalysisReport runSync(SecurityAnalysisParameters securityAnalysisParame

SecurityAnalysisResult runSimulationsOnAllComponents(LfNetworkList networks, List<PropagatedContingency> propagatedContingencies, P parameters,
SecurityAnalysisParameters securityAnalysisParameters, List<OperatorStrategy> operatorStrategies,
List<Action> actions, List<LimitReduction> limitReductions, LoadFlowParameters lfParameters) {
List<Action> actions, List<LimitReduction> limitReductions, LoadFlowParameters lfParameters,
Map<Pair<Integer, Integer>, ReportNode> postCtgReportNodeMap) {

List<LfNetwork> networkToSimulate = new ArrayList<>(getNetworksToSimulate(networks, lfParameters.getConnectedComponentMode()));

@@ -260,7 +275,7 @@ SecurityAnalysisResult runSimulationsOnAllComponents(LfNetworkList networks, Lis

// run simulation on first lfNetwork to initialize results structures
LfNetwork firstNetwork = networkToSimulate.remove(0);
SecurityAnalysisResult result = runSimulations(firstNetwork, propagatedContingencies, parameters, securityAnalysisParameters, operatorStrategies, actions, limitReductions);
SecurityAnalysisResult result = runSimulations(firstNetwork, propagatedContingencies, parameters, securityAnalysisParameters, operatorStrategies, actions, limitReductions, postCtgReportNodeMap);

List<PostContingencyResult> postContingencyResults = result.getPostContingencyResults();
List<OperatorStrategyResult> operatorStrategyResults = result.getOperatorStrategyResults();
@@ -276,7 +291,8 @@ SecurityAnalysisResult runSimulationsOnAllComponents(LfNetworkList networks, Lis
preContingencyViolations = new ArrayList<>(preContingencyViolations);

for (LfNetwork n : networkToSimulate) {
SecurityAnalysisResult resultOtherComponent = runSimulations(n, propagatedContingencies, parameters, securityAnalysisParameters, operatorStrategies, actions, limitReductions);
SecurityAnalysisResult resultOtherComponent = runSimulations(n, propagatedContingencies, parameters, securityAnalysisParameters,
operatorStrategies, actions, limitReductions, postCtgReportNodeMap);

// Merge into first result
// PreContingency results first
@@ -477,7 +493,8 @@ protected static Map<String, Action> indexActionsById(List<Action> actions) {
protected static Map<String, List<OperatorStrategy>> indexOperatorStrategiesByContingencyId(List<PropagatedContingency> propagatedContingencies,
List<OperatorStrategy> operatorStrategies,
Map<String, Action> actionsById,
Set<Action> neededActions) {
Set<Action> neededActions,
boolean tolerateMissingContingencies) {
Set<String> contingencyIds = propagatedContingencies.stream().map(propagatedContingency -> propagatedContingency.getContingency().getId()).collect(Collectors.toSet());
Map<String, List<OperatorStrategy>> operatorStrategiesByContingencyId = new HashMap<>();
for (OperatorStrategy operatorStrategy : operatorStrategies) {
@@ -496,8 +513,10 @@ protected static Map<String, List<OperatorStrategy>> indexOperatorStrategiesByCo
operatorStrategiesByContingencyId.computeIfAbsent(operatorStrategy.getContingencyContext().getContingencyId(), key -> new ArrayList<>())
.add(operatorStrategy);
} else {
throw new PowsyblException("Operator strategy '" + operatorStrategy.getId() + "' is associated to contingency '"
+ operatorStrategy.getContingencyContext().getContingencyId() + "' but this contingency is not present in the list");
if (!tolerateMissingContingencies) {
throw new PowsyblException("Operator strategy '" + operatorStrategy.getId() + "' is associated to contingency '"
+ operatorStrategy.getContingencyContext().getContingencyId() + "' but this contingency is not present in the list");
}
}
}
return operatorStrategiesByContingencyId;
@@ -621,10 +640,15 @@ protected void afterPreContingencySimulation(P acParameters) {

protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List<PropagatedContingency> propagatedContingencies, P acParameters,
SecurityAnalysisParameters securityAnalysisParameters, List<OperatorStrategy> operatorStrategies,
List<Action> actions, List<LimitReduction> limitReductions) {
List<Action> actions, List<LimitReduction> limitReductions, Map<Pair<Integer, Integer>, ReportNode> postContReportMap) {
Map<String, Action> actionsById = indexActionsById(actions);
Set<Action> neededActions = new HashSet<>(actionsById.size());
Map<String, List<OperatorStrategy>> operatorStrategiesByContingencyId = indexOperatorStrategiesByContingencyId(propagatedContingencies, operatorStrategies, actionsById, neededActions);
boolean tolerateMissingContingencies = false;
OpenSecurityAnalysisParameters securityAnalysisParametersExt = securityAnalysisParameters.getExtension(OpenSecurityAnalysisParameters.class);
tolerateMissingContingencies = securityAnalysisParametersExt != null && securityAnalysisParametersExt.getThreadCount() > 1;

Map<String, List<OperatorStrategy>> operatorStrategiesByContingencyId =
indexOperatorStrategiesByContingencyId(propagatedContingencies, operatorStrategies, actionsById, neededActions, tolerateMissingContingencies);
Map<String, LfAction> lfActionById = createLfActions(lfNetwork, neededActions, network, acParameters.getNetworkParameters()); // only convert needed actions

LoadFlowParameters loadFlowParameters = securityAnalysisParameters.getLoadFlowParameters();
@@ -633,9 +657,16 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List<Propag
boolean createResultExtension = openSecurityAnalysisParameters.isCreateResultExtension();

try (C context = createLoadFlowContext(lfNetwork, acParameters)) {
ReportNode networkReportNode = lfNetwork.getReportNode();
ReportNode preContSimReportNode = Reports.createPreContingencySimulation(networkReportNode);
lfNetwork.setReportNode(preContSimReportNode);
final ReportNode preContReportNode;
final ReportNode ccReportNode = postContReportMap.get(new ImmutablePair<>(lfNetwork.getNumCC(), lfNetwork.getNumSC()));
synchronized (ccReportNode) {
// In an MT run, the report is a NO_OP if not the first thread to run on this CC, to avoid duplicate
// functional reports of lf network loading and precontingency run
preContReportNode = (ccReportNode.getChildren().size() == 1) ? ccReportNode : ReportNode.NO_OP;
ReportNode preContSimReportNode = Reports.createPreContingencySimulation(preContReportNode);
lfNetwork.setReportNode(preContSimReportNode);
}


// run pre-contingency simulation
R preContingencyLoadFlowResult = createLoadFlowEngine(context)
@@ -666,7 +697,8 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List<Propag
PropagatedContingency propagatedContingency = contingencyIt.next();
propagatedContingency.toLfContingency(lfNetwork)
.ifPresent(lfContingency -> { // only process contingencies that impact the network
ReportNode postContSimReportNode = Reports.createPostContingencySimulation(networkReportNode, lfContingency.getId());
ReportNode postContSimReportNode =
Reports.createPostContingencySimulation(ccReportNode, lfContingency.getId());
lfNetwork.setReportNode(postContSimReportNode);

lfContingency.apply(loadFlowParameters.getBalanceType());
Loading
Loading