Skip to content

Commit 46688e5

Browse files
author
Pauline Jean-Marie
committed
POC security analysis with limits override (missing a run for each conditional action)
1 parent 0db5290 commit 46688e5

File tree

3 files changed

+49
-22
lines changed

3 files changed

+49
-22
lines changed

src/main/java/com/powsybl/openloadflow/sa/AbstractSecurityAnalysis.java

+23-15
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.powsybl.computation.ComputationManager;
1616
import com.powsybl.contingency.ContingenciesProvider;
1717
import com.powsybl.contingency.Contingency;
18+
import com.powsybl.contingency.ContingencyContext;
1819
import com.powsybl.iidm.network.Branch;
1920
import com.powsybl.iidm.network.Network;
2021
import com.powsybl.iidm.network.Switch;
@@ -43,6 +44,7 @@
4344
import com.powsybl.security.monitor.StateMonitorIndex;
4445
import com.powsybl.security.results.*;
4546
import com.powsybl.security.strategy.ConditionalActions;
47+
import com.powsybl.security.strategy.OperationalLimitOverride;
4648
import com.powsybl.security.strategy.OperatorStrategy;
4749
import org.slf4j.Logger;
4850
import org.slf4j.LoggerFactory;
@@ -90,13 +92,14 @@ protected static SecurityAnalysisResult createNoResult() {
9092

9193
public CompletableFuture<SecurityAnalysisReport> run(String workingVariantId, SecurityAnalysisParameters securityAnalysisParameters,
9294
ContingenciesProvider contingenciesProvider, ComputationManager computationManager,
93-
List<OperatorStrategy> operatorStrategies, List<Action> actions, List<LimitReduction> limitReductions) {
95+
List<OperatorStrategy> operatorStrategies, List<Action> actions, List<LimitReduction> limitReductions,
96+
List<OperationalLimitOverride> limitsToOverride) {
9497
Objects.requireNonNull(workingVariantId);
9598
Objects.requireNonNull(securityAnalysisParameters);
9699
Objects.requireNonNull(contingenciesProvider);
97100
return CompletableFutureTask.runAsync(() -> {
98101
network.getVariantManager().setWorkingVariant(workingVariantId);
99-
return runSync(securityAnalysisParameters, contingenciesProvider, operatorStrategies, actions, limitReductions);
102+
return runSync(securityAnalysisParameters, contingenciesProvider, operatorStrategies, actions, limitReductions, limitsToOverride);
100103
}, computationManager.getExecutor());
101104
}
102105

@@ -107,7 +110,7 @@ public CompletableFuture<SecurityAnalysisReport> run(String workingVariantId, Se
107110
protected abstract P createParameters(LoadFlowParameters lfParameters, OpenLoadFlowParameters lfParametersExt, boolean breakers);
108111

109112
SecurityAnalysisReport runSync(SecurityAnalysisParameters securityAnalysisParameters, ContingenciesProvider contingenciesProvider,
110-
List<OperatorStrategy> operatorStrategies, List<Action> actions, List<LimitReduction> limitReductions) {
113+
List<OperatorStrategy> operatorStrategies, List<Action> actions, List<LimitReduction> limitReductions, List<OperationalLimitOverride> limitsToOverride) {
111114
var saReportNode = createSaRootReportNode();
112115

113116
Stopwatch stopwatch = Stopwatch.createStarted();
@@ -150,7 +153,7 @@ SecurityAnalysisReport runSync(SecurityAnalysisParameters securityAnalysisParame
150153
try (LfNetworkList lfNetworks = Networks.load(network, parameters.getNetworkParameters(), topoConfig, saReportNode)) {
151154
// run simulation on largest network
152155
SecurityAnalysisResult result = lfNetworks.getLargest().filter(n -> n.getValidity() == LfNetwork.Validity.VALID)
153-
.map(largestNetwork -> runSimulations(largestNetwork, propagatedContingencies, parameters, securityAnalysisParameters, operatorStrategies, actions, limitReductions))
156+
.map(largestNetwork -> runSimulations(largestNetwork, propagatedContingencies, parameters, securityAnalysisParameters, operatorStrategies, actions, limitReductions, limitsToOverride))
154157
.orElse(createNoResult());
155158

156159
stopwatch.stop();
@@ -396,7 +399,7 @@ protected void afterPreContingencySimulation(P acParameters) {
396399

397400
protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List<PropagatedContingency> propagatedContingencies, P acParameters,
398401
SecurityAnalysisParameters securityAnalysisParameters, List<OperatorStrategy> operatorStrategies,
399-
List<Action> actions, List<LimitReduction> limitReductions) {
402+
List<Action> actions, List<LimitReduction> limitReductions, List<OperationalLimitOverride> limitsToOverride) {
400403
Map<String, Action> actionsById = indexActionsById(actions);
401404
Set<Action> neededActions = new HashSet<>(actionsById.size());
402405
Map<String, List<OperatorStrategy>> operatorStrategiesByContingencyId = indexOperatorStrategiesByContingencyId(propagatedContingencies, operatorStrategies, actionsById, neededActions);
@@ -417,7 +420,8 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List<Propag
417420
.run();
418421

419422
boolean preContingencyComputationOk = preContingencyLoadFlowResult.isSuccess();
420-
var preContingencyLimitViolationManager = new LimitViolationManager(limitReductions);
423+
var limitsToOverridePreContingency = limitsToOverride.stream().filter(l -> l.getContingencyContext() == ContingencyContext.none()).toList();
424+
var preContingencyLimitViolationManager = new LimitViolationManager(limitReductions, limitsToOverridePreContingency);
421425
List<PostContingencyResult> postContingencyResults = new ArrayList<>();
422426
var preContingencyNetworkResult = new PreContingencyNetworkResult(lfNetwork, monitorIndex, createResultExtension);
423427
List<OperatorStrategyResult> operatorStrategyResults = new ArrayList<>();
@@ -451,7 +455,8 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List<Propag
451455
var postContingencyResult = runPostContingencySimulation(lfNetwork, context, propagatedContingency.getContingency(),
452456
lfContingency, preContingencyLimitViolationManager,
453457
securityAnalysisParameters.getIncreasedViolationsParameters(),
454-
preContingencyNetworkResult, createResultExtension, limitReductions);
458+
preContingencyNetworkResult, createResultExtension, limitReductions,
459+
limitsToOverride);
455460
postContingencyResults.add(postContingencyResult);
456461

457462
List<OperatorStrategy> operatorStrategiesForThisContingency = operatorStrategiesByContingencyId.get(lfContingency.getId());
@@ -468,7 +473,7 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List<Propag
468473
operatorStrategy, preContingencyLimitViolationManager,
469474
securityAnalysisParameters.getIncreasedViolationsParameters(), lfActionById,
470475
createResultExtension, lfContingency, postContingencyResult.getLimitViolationsResult(),
471-
acParameters.getNetworkParameters(), limitReductions)
476+
acParameters.getNetworkParameters(), limitReductions, limitsToOverride)
472477
.ifPresent(operatorStrategyResults::add);
473478
} else {
474479
// multiple operator strategies, save post contingency state for later restoration after action
@@ -480,7 +485,7 @@ protected SecurityAnalysisResult runSimulations(LfNetwork lfNetwork, List<Propag
480485
operatorStrategy, preContingencyLimitViolationManager,
481486
securityAnalysisParameters.getIncreasedViolationsParameters(), lfActionById,
482487
createResultExtension, lfContingency, postContingencyResult.getLimitViolationsResult(),
483-
acParameters.getNetworkParameters(), limitReductions)
488+
acParameters.getNetworkParameters(), limitReductions, limitsToOverride)
484489
.ifPresent(result -> {
485490
operatorStrategyResults.add(result);
486491
postContingencyNetworkState.restore();
@@ -512,13 +517,13 @@ private Optional<OperatorStrategyResult> runActionSimulation(LfNetwork network,
512517
SecurityAnalysisParameters.IncreasedViolationsParameters violationsParameters,
513518
Map<String, LfAction> lfActionById, boolean createResultExtension, LfContingency contingency,
514519
LimitViolationsResult postContingencyLimitViolations, LfNetworkParameters networkParameters,
515-
List<LimitReduction> limitReductions) {
520+
List<LimitReduction> limitReductions, List<OperationalLimitOverride> limitsToOverride) {
516521
OperatorStrategyResult operatorStrategyResult = null;
517522

518523
List<String> actionIds = checkCondition(operatorStrategy, postContingencyLimitViolations);
519524
if (!actionIds.isEmpty()) {
520525
operatorStrategyResult = runActionSimulation(network, context, operatorStrategy, actionIds, preContingencyLimitViolationManager,
521-
violationsParameters, lfActionById, createResultExtension, contingency, networkParameters, limitReductions);
526+
violationsParameters, lfActionById, createResultExtension, contingency, networkParameters, limitReductions, limitsToOverride);
522527
}
523528

524529
return Optional.ofNullable(operatorStrategyResult);
@@ -528,7 +533,7 @@ protected PostContingencyResult runPostContingencySimulation(LfNetwork network,
528533
LimitViolationManager preContingencyLimitViolationManager,
529534
SecurityAnalysisParameters.IncreasedViolationsParameters violationsParameters,
530535
PreContingencyNetworkResult preContingencyNetworkResult, boolean createResultExtension,
531-
List<LimitReduction> limitReductions) {
536+
List<LimitReduction> limitReductions, List<OperationalLimitOverride> limitsToOverride) {
532537
LOGGER.info("Start post contingency '{}' simulation on network {}", lfContingency.getId(), network);
533538
LOGGER.debug("Contingency '{}' impact on network {}: remove {} buses, remove {} branches, remove {} generators, shift {} shunts, shift {} loads",
534539
lfContingency.getId(), network, lfContingency.getDisabledNetwork().getBuses(), lfContingency.getDisabledNetwork().getBranchesStatus(),
@@ -538,7 +543,8 @@ protected PostContingencyResult runPostContingencySimulation(LfNetwork network,
538543

539544
// restart LF on post contingency equation system
540545
PostContingencyComputationStatus status = runActionLoadFlow(context); // FIXME: change name.
541-
var postContingencyLimitViolationManager = new LimitViolationManager(preContingencyLimitViolationManager, limitReductions, violationsParameters);
546+
var limitsToOverridePostContingency = limitsToOverride.stream().filter(l -> Objects.equals(l.getContingencyContext(), ContingencyContext.specificContingency(contingency.getId())) && l.getConditionalActionsId().isEmpty()).toList();
547+
var postContingencyLimitViolationManager = new LimitViolationManager(preContingencyLimitViolationManager, limitReductions, limitsToOverridePostContingency, violationsParameters);
542548
var postContingencyNetworkResult = new PostContingencyNetworkResult(network, monitorIndex, createResultExtension, preContingencyNetworkResult, contingency);
543549

544550
if (status.equals(PostContingencyComputationStatus.CONVERGED)) {
@@ -571,7 +577,8 @@ protected OperatorStrategyResult runActionSimulation(LfNetwork network, C contex
571577
LimitViolationManager preContingencyLimitViolationManager,
572578
SecurityAnalysisParameters.IncreasedViolationsParameters violationsParameters,
573579
Map<String, LfAction> lfActionById, boolean createResultExtension, LfContingency contingency,
574-
LfNetworkParameters networkParameters, List<LimitReduction> limitReductions) {
580+
LfNetworkParameters networkParameters, List<LimitReduction> limitReductions,
581+
List<OperationalLimitOverride> limitsToOverride) {
575582
LOGGER.info("Start operator strategy {} after contingency '{}' simulation on network {}", operatorStrategy.getId(),
576583
operatorStrategy.getContingencyContext().getContingencyId(), network);
577584

@@ -589,7 +596,8 @@ protected OperatorStrategyResult runActionSimulation(LfNetwork network, C contex
589596

590597
// restart LF on post contingency and post actions equation system
591598
PostContingencyComputationStatus status = runActionLoadFlow(context);
592-
var postActionsViolationManager = new LimitViolationManager(preContingencyLimitViolationManager, limitReductions, violationsParameters);
599+
var limitsToOverridePostActions = limitsToOverride.stream().filter(l -> Objects.equals(l.getContingencyContext(), ContingencyContext.specificContingency(contingency.getId())) && l.getConditionalActionsId().isPresent()).toList();
600+
var postActionsViolationManager = new LimitViolationManager(preContingencyLimitViolationManager, limitReductions, limitsToOverridePostActions, violationsParameters);
593601
var postActionsNetworkResult = new PreContingencyNetworkResult(network, monitorIndex, createResultExtension);
594602

595603
if (status.equals(PostContingencyComputationStatus.CONVERGED)) {

src/main/java/com/powsybl/openloadflow/sa/LimitViolationManager.java

+24-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.powsybl.iidm.network.LimitType;
1111
import com.powsybl.iidm.network.ThreeSides;
1212
import com.powsybl.iidm.network.TwoSides;
13+
import com.powsybl.iidm.network.util.LimitViolationUtils;
1314
import com.powsybl.openloadflow.network.LfBranch;
1415
import com.powsybl.openloadflow.network.LfBus;
1516
import com.powsybl.openloadflow.network.LfNetwork;
@@ -19,6 +20,7 @@
1920
import com.powsybl.security.LimitViolationType;
2021
import com.powsybl.security.SecurityAnalysisParameters;
2122
import com.powsybl.security.limitreduction.LimitReduction;
23+
import com.powsybl.security.strategy.OperationalLimitOverride;
2224
import org.apache.commons.lang3.function.TriFunction;
2325
import org.apache.commons.lang3.tuple.Pair;
2426

@@ -42,17 +44,25 @@ public class LimitViolationManager {
4244

4345
private final Map<Object, LimitViolation> violations = new LinkedHashMap<>();
4446

47+
private final List<OperationalLimitOverride> limitsToOverride;
48+
//private final Map<String, List<OperationalLimitOverride>> limitsToOverridePerElementId = new LinkedHashMap<>();
49+
4550
public LimitViolationManager(LimitViolationManager reference, List<LimitReduction> limitReductions,
51+
List<OperationalLimitOverride> limitsToOverride,
4652
SecurityAnalysisParameters.IncreasedViolationsParameters parameters) {
4753
this.reference = reference;
4854
if (reference != null) {
4955
this.parameters = Objects.requireNonNull(parameters);
5056
}
5157
this.limitReductionManager = LimitReductionManager.create(limitReductions);
58+
this.limitsToOverride = limitsToOverride;
59+
/*for (OperationalLimitOverride limitToOverride: limitsToOverride) {
60+
this.limitsToOverridePerElementId.computeIfAbsent(limitToOverride.getNetworkElementId(), k -> new ArrayList<>()).add(limitToOverride);
61+
}*/
5262
}
5363

54-
public LimitViolationManager(List<LimitReduction> limitReductions) {
55-
this(null, limitReductions, null);
64+
public LimitViolationManager(List<LimitReduction> limitReductions, List<OperationalLimitOverride> limitsToOverride) {
65+
this(null, limitReductions, limitsToOverride, null);
5666
}
5767

5868
public List<LimitViolation> getLimitViolations() {
@@ -111,7 +121,7 @@ private void detectBranchSideViolations(LfBranch branch, LfBus bus,
111121
Function<LfBranch, Evaluable> pGetter,
112122
ToDoubleFunction<LfBranch> sGetter,
113123
TwoSides side) {
114-
List<LfBranch.LfLimit> limits = limitsGetter.apply(branch, LimitType.CURRENT, limitReductionManager);
124+
List<LfBranch.LfLimit> limits = getLimits(branch, side, LimitType.CURRENT, limitReductionManager, limitsGetter);
115125
if (!limits.isEmpty()) {
116126
double i = iGetter.apply(branch).eval();
117127
limits.stream()
@@ -121,7 +131,7 @@ private void detectBranchSideViolations(LfBranch branch, LfBus bus,
121131
.ifPresent(this::addBranchLimitViolation);
122132
}
123133

124-
limits = limitsGetter.apply(branch, LimitType.ACTIVE_POWER, limitReductionManager);
134+
limits = getLimits(branch, side, LimitType.ACTIVE_POWER, limitReductionManager, limitsGetter);
125135
if (!limits.isEmpty()) {
126136
double p = pGetter.apply(branch).eval();
127137
limits.stream()
@@ -131,7 +141,7 @@ private void detectBranchSideViolations(LfBranch branch, LfBus bus,
131141
.ifPresent(this::addBranchLimitViolation);
132142
}
133143

134-
limits = limitsGetter.apply(branch, LimitType.APPARENT_POWER, limitReductionManager);
144+
limits = getLimits(branch, side, LimitType.APPARENT_POWER, limitReductionManager, limitsGetter);
135145
if (!limits.isEmpty()) {
136146
//Apparent power is not relevant for fictitious branches and may be NaN
137147
double s = sGetter.applyAsDouble(branch);
@@ -145,6 +155,15 @@ private void detectBranchSideViolations(LfBranch branch, LfBus bus,
145155
}
146156
}
147157

158+
private List<LfBranch.LfLimit> getLimits(LfBranch branch, TwoSides branchSide, LimitType type, LimitReductionManager limitReductionManager, TriFunction<LfBranch, LimitType, LimitReductionManager, List<LfBranch.LfLimit>> limitsGetter) {
159+
for (OperationalLimitOverride limitToOverride : this.limitsToOverride) {
160+
if (Objects.equals(limitToOverride.getNetworkElementId(), branch.getId()) && limitToOverride.getSide().map(side -> side.toTwoSides() == branchSide).orElse(true) && limitToOverride.getType() == type) {
161+
return List.of(new LfBranch.LfLimit(LimitViolationUtils.PERMANENT_LIMIT_NAME, Integer.MAX_VALUE, limitToOverride.getMaxValue(), 1)); // TODO compute reduction
162+
}
163+
}
164+
return limitsGetter.apply(branch, type, limitReductionManager);
165+
}
166+
148167
/**
149168
* Detect violation limits on one branch and add them to the given list
150169
* @param branch branch of interest
@@ -155,7 +174,6 @@ private void detectBranchViolations(LfBranch branch) {
155174
if (branch.getBus1() != null) {
156175
detectBranchSideViolations(branch, branch.getBus1(), LfBranch::getLimits1, LfBranch::getI1, LfBranch::getP1, LfBranch::computeApparentPower1, TwoSides.ONE);
157176
}
158-
159177
if (branch.getBus2() != null) {
160178
detectBranchSideViolations(branch, branch.getBus2(), LfBranch::getLimits2, LfBranch::getI2, LfBranch::getP2, LfBranch::computeApparentPower2, TwoSides.TWO);
161179
}

0 commit comments

Comments
 (0)