Skip to content

Commit 5da4279

Browse files
adds MODIFY_OR_ADD to limit modification (#95)
Signed-off-by: Mathieu DEHARBE <[email protected]>
1 parent d7afbc7 commit 5da4279

File tree

3 files changed

+184
-97
lines changed

3 files changed

+184
-97
lines changed

src/main/java/org/gridsuite/modification/dto/TemporaryLimitModificationType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
public enum TemporaryLimitModificationType {
1313
ADD,
1414
MODIFY,
15+
MODIFY_OR_ADD,
1516
DELETE,
1617
REPLACE
1718
}

src/main/java/org/gridsuite/modification/modifications/AbstractBranchModification.java

Lines changed: 166 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.powsybl.commons.report.TypedValue;
1212
import com.powsybl.iidm.network.*;
1313
import com.powsybl.iidm.network.extensions.*;
14+
import jakarta.validation.constraints.NotNull;
1415
import org.gridsuite.modification.NetworkModificationException;
1516
import org.gridsuite.modification.dto.*;
1617
import org.gridsuite.modification.utils.ModificationUtils;
@@ -380,20 +381,24 @@ public boolean isThisLimitDeleted(List<CurrentTemporaryLimitModificationInfos> t
380381
.anyMatch(temporaryLimit -> temporaryLimit.getAcceptableDuration() == acceptableDuration && temporaryLimit.getModificationType() == TemporaryLimitModificationType.DELETE);
381382
}
382383

383-
protected void modifyTemporaryLimits(OperationalLimitsGroupModificationInfos operationalLimitsGroupModificationInfos,
384+
/**
385+
* This function removes all the temporary limits of the 'currentLimits' concerned and recreates them (except in case of deletion)
386+
*/
387+
protected void modifyTemporaryLimits(@NotNull OperationalLimitsGroupModificationInfos operationalLimitsGroupModificationInfos,
384388
CurrentLimitsAdder limitsAdder,
385389
CurrentLimits currentLimits,
386390
List<ReportNode> limitsReports) {
387391
CurrentLimitsModificationInfos currentLimitsInfos = operationalLimitsGroupModificationInfos.getCurrentLimits();
388392

389-
// we create a mutable list of temporary limits to be able to remove the limits that are modified in current modification
390-
List<LoadingLimits.TemporaryLimit> branchTemporaryLimits = new ArrayList<>();
391-
boolean areLimitsReplaced = operationalLimitsGroupModificationInfos != null && TemporaryLimitModificationType.REPLACE.equals(operationalLimitsGroupModificationInfos.getTemporaryLimitsModificationType());
393+
// we create a mutable list of temporary limits to be able to remove the limits that are modified in this current modification
394+
// those left at the end of the network modification are those that have not been modified (or deleted)
395+
List<LoadingLimits.TemporaryLimit> unmodifiedTemporaryLimits = new ArrayList<>();
396+
boolean areLimitsReplaced = TemporaryLimitModificationType.REPLACE.equals(operationalLimitsGroupModificationInfos.getTemporaryLimitsModificationType());
392397
if (currentLimits != null && !areLimitsReplaced) {
393-
branchTemporaryLimits.addAll(currentLimits.getTemporaryLimits());
398+
unmodifiedTemporaryLimits.addAll(currentLimits.getTemporaryLimits());
394399
}
395400
List<ReportNode> temporaryLimitsReports = new ArrayList<>();
396-
if (operationalLimitsGroupModificationInfos != null && TemporaryLimitModificationType.REPLACE.equals(operationalLimitsGroupModificationInfos.getTemporaryLimitsModificationType())) {
401+
if (areLimitsReplaced) {
397402
temporaryLimitsReports.add(ReportNode.newRootReportNode()
398403
.withAllResourceBundlesFromClasspath()
399404
.withMessageTemplate("network.modification.temporaryLimitsReplaced")
@@ -403,98 +408,24 @@ protected void modifyTemporaryLimits(OperationalLimitsGroupModificationInfos ope
403408

404409
if (currentLimitsInfos != null && currentLimitsInfos.getTemporaryLimits() != null) {
405410
for (CurrentTemporaryLimitModificationInfos limit : currentLimitsInfos.getTemporaryLimits()) {
406-
int limitAcceptableDuration = limit.getAcceptableDuration() == null ? Integer.MAX_VALUE : limit.getAcceptableDuration();
407-
double limitValue = limit.getValue() == null ? Double.MAX_VALUE : limit.getValue();
408-
String limitDurationToReport = limitAcceptableDuration == Integer.MAX_VALUE ? " " : String.valueOf(limitAcceptableDuration);
409-
String limitValueToReport = limitValue == Double.MAX_VALUE ? "no value" : String.valueOf(limitValue);
410-
LoadingLimits.TemporaryLimit limitToModify = null;
411-
if (currentLimits != null) {
412-
limitToModify = currentLimits.getTemporaryLimit(limitAcceptableDuration);
413-
if (limitToModify != null && !limitToModify.getName().equals(limit.getName())) {
414-
boolean isThisLimitDeleted = isThisLimitDeleted(currentLimitsInfos.getTemporaryLimits(), limitAcceptableDuration);
415-
if (isThisLimitDeleted) {
416-
limitToModify = null;
417-
} else if (TemporaryLimitModificationType.ADD.equals(limit.getModificationType())) {
418-
throw new PowsyblException("2 temporary limits have the same duration " + limitAcceptableDuration);
419-
}
420-
}
421-
422-
//Additional check for limit sets tabular modifications
423-
if (operationalLimitsGroupModificationInfos != null && TemporaryLimitModificationType.ADD.equals(operationalLimitsGroupModificationInfos.getTemporaryLimitsModificationType())) {
424-
currentLimits.getTemporaryLimits().stream().filter(temporaryLimit -> temporaryLimit.getName().equals(limit.getName())).findFirst().ifPresent(temporaryLimit -> {
425-
throw new PowsyblException("2 temporary limits have the same name " + limit.getName());
426-
});
427-
}
428-
// we remove the limit to modify from the list of temporary limits so we can get the list of temporary limits coming from previous modifications
429-
branchTemporaryLimits.removeIf(temporaryLimit -> temporaryLimit.getAcceptableDuration() == limitAcceptableDuration);
430-
}
431-
if (limitToModify == null && limit.getModificationType() == TemporaryLimitModificationType.ADD || limit.getModificationType() == TemporaryLimitModificationType.REPLACE) {
432-
temporaryLimitsReports.add(ReportNode.newRootReportNode()
433-
.withAllResourceBundlesFromClasspath()
434-
.withMessageTemplate("network.modification.temporaryLimitAdded.name")
435-
.withUntypedValue(NAME, limit.getName())
436-
.withUntypedValue(DURATION, limitDurationToReport)
437-
.withUntypedValue(VALUE, limitValueToReport)
438-
.withSeverity(TypedValue.INFO_SEVERITY)
439-
.build());
440-
441-
} else if (limitToModify != null) {
442-
if (limit.getModificationType() == TemporaryLimitModificationType.DELETE) {
443-
temporaryLimitsReports.add(ReportNode.newRootReportNode()
444-
.withAllResourceBundlesFromClasspath()
445-
.withMessageTemplate("network.modification.temporaryLimitDeleted.name")
446-
.withUntypedValue(NAME, limit.getName())
447-
.withUntypedValue(DURATION, limitDurationToReport)
448-
.withSeverity(TypedValue.INFO_SEVERITY)
449-
.build());
450-
continue;
451-
} else if (Double.compare(limitToModify.getValue(), limitValue) != 0 && limit.getModificationType() != null) {
452-
temporaryLimitsReports.add(ReportNode.newRootReportNode()
453-
.withAllResourceBundlesFromClasspath()
454-
.withMessageTemplate("network.modification.temporaryLimitModified.name")
455-
.withUntypedValue(NAME, limit.getName())
456-
.withUntypedValue(DURATION, limitDurationToReport)
457-
.withUntypedValue(VALUE, limitValueToReport)
458-
.withUntypedValue("oldValue",
459-
limitToModify.getValue() == Double.MAX_VALUE ? "no value"
460-
: String.valueOf(limitToModify.getValue()))
461-
.withSeverity(TypedValue.INFO_SEVERITY)
462-
.build());
463-
} else {
464-
limitValue = limitToModify.getValue();
465-
}
466-
} else if (limit.getModificationType() == TemporaryLimitModificationType.MODIFY) {
467-
temporaryLimitsReports.add(ReportNode.newRootReportNode()
468-
.withAllResourceBundlesFromClasspath()
469-
.withMessageTemplate("network.modification.temporaryLimitsNoMatch")
470-
.withUntypedValue(LIMIT_ACCEPTABLE_DURATION, limitAcceptableDuration)
471-
.withSeverity(TypedValue.WARN_SEVERITY)
472-
.build());
473-
continue;
474-
} else {
475-
continue;
476-
}
477-
limitsAdder
478-
.beginTemporaryLimit()
479-
.setName(limit.getName())
480-
.setValue(limitValue)
481-
.setAcceptableDuration(limitAcceptableDuration)
482-
.endTemporaryLimit();
411+
applyTemporaryLimitModification(
412+
operationalLimitsGroupModificationInfos,
413+
limitsAdder,
414+
currentLimits,
415+
limit,
416+
unmodifiedTemporaryLimits,
417+
temporaryLimitsReports
418+
);
483419
}
484420
}
485-
// we add the temporary limits comming from previous modifications
486-
if (!branchTemporaryLimits.isEmpty()) {
487-
for (LoadingLimits.TemporaryLimit limit : branchTemporaryLimits) {
488-
limitsAdder
489-
.beginTemporaryLimit()
490-
.setName(limit.getName())
491-
.setValue(limit.getValue())
492-
.setAcceptableDuration(limit.getAcceptableDuration())
493-
.endTemporaryLimit();
421+
// we add (back) the temporary limits that have not been modified
422+
if (!unmodifiedTemporaryLimits.isEmpty()) {
423+
for (LoadingLimits.TemporaryLimit limit : unmodifiedTemporaryLimits) {
424+
addTemporaryLimit(limitsAdder, limit.getName(), limit.getValue(), limit.getAcceptableDuration());
494425
}
495426
}
496427
if (!temporaryLimitsReports.isEmpty()) {
497-
temporaryLimitsReports.add(0, ReportNode.newRootReportNode()
428+
temporaryLimitsReports.addFirst(ReportNode.newRootReportNode()
498429
.withAllResourceBundlesFromClasspath()
499430
.withMessageTemplate("network.modification.temporaryLimitsModification")
500431
.withSeverity(TypedValue.INFO_SEVERITY)
@@ -503,6 +434,148 @@ protected void modifyTemporaryLimits(OperationalLimitsGroupModificationInfos ope
503434
}
504435
}
505436

437+
private static boolean mayCreateALimit(TemporaryLimitModificationType modificationType) {
438+
return modificationType == TemporaryLimitModificationType.ADD
439+
|| modificationType == TemporaryLimitModificationType.REPLACE
440+
|| modificationType == TemporaryLimitModificationType.MODIFY_OR_ADD;
441+
}
442+
443+
/**
444+
* modify a specific limit
445+
* @param operationalLimitsGroupModificationInfos part of the network modification containing the operational limits groups data
446+
* @param limitsAdder adder which receives all the "validated" limits to be added at the end
447+
* @param networkCurrentLimits limits of the branch which is currently modified by the network modification
448+
* @param limit modification to be applied to the limit
449+
* @param unmodifiedTemporaryLimits list of all the unmodified limits that will be added at the end of the network modification
450+
* @param temporaryLimitsReports log report
451+
*/
452+
private void applyTemporaryLimitModification(
453+
OperationalLimitsGroupModificationInfos operationalLimitsGroupModificationInfos,
454+
CurrentLimitsAdder limitsAdder,
455+
CurrentLimits networkCurrentLimits,
456+
CurrentTemporaryLimitModificationInfos limit,
457+
List<LoadingLimits.TemporaryLimit> unmodifiedTemporaryLimits,
458+
List<ReportNode> temporaryLimitsReports) {
459+
CurrentLimitsModificationInfos currentLimitsInfos = operationalLimitsGroupModificationInfos.getCurrentLimits();
460+
int limitAcceptableDuration = limit.getAcceptableDuration() == null ? Integer.MAX_VALUE : limit.getAcceptableDuration();
461+
double limitValue = limit.getValue() == null ? Double.MAX_VALUE : limit.getValue();
462+
String limitDurationToReport = limitAcceptableDuration == Integer.MAX_VALUE ? " " : String.valueOf(limitAcceptableDuration);
463+
String limitValueToReport = limitValue == Double.MAX_VALUE ? "no value" : String.valueOf(limitValue);
464+
LoadingLimits.TemporaryLimit limitToModify = null;
465+
if (networkCurrentLimits != null) {
466+
limitToModify = getTemporaryLimitToModify(networkCurrentLimits, limit, currentLimitsInfos, operationalLimitsGroupModificationInfos.getTemporaryLimitsModificationType());
467+
// this limit is modified by the network modification so we remove it from the list of unmodified temporary limits
468+
unmodifiedTemporaryLimits.removeIf(temporaryLimit -> temporaryLimit.getAcceptableDuration() == limitAcceptableDuration);
469+
}
470+
if (limitToModify == null && mayCreateALimit(limit.getModificationType())) {
471+
createTemporaryLimit(limitsAdder, limit, temporaryLimitsReports, limitDurationToReport, limitValueToReport, limitValue, limitAcceptableDuration);
472+
} else if (limitToModify != null) {
473+
// the limit already exists
474+
if (limit.getModificationType() == TemporaryLimitModificationType.DELETE) {
475+
// the limit has been removed previously
476+
temporaryLimitsReports.add(ReportNode.newRootReportNode()
477+
.withAllResourceBundlesFromClasspath()
478+
.withMessageTemplate("network.modification.temporaryLimitDeleted.name")
479+
.withUntypedValue(NAME, limit.getName())
480+
.withUntypedValue(DURATION, limitDurationToReport)
481+
.withSeverity(TypedValue.INFO_SEVERITY)
482+
.build());
483+
} else {
484+
modifyTemporaryLimit(limitsAdder, limit, temporaryLimitsReports, limitToModify, limitValue, limitDurationToReport, limitValueToReport, limitAcceptableDuration);
485+
}
486+
} else if (limit.getModificationType() == TemporaryLimitModificationType.MODIFY || limit.getModificationType() == TemporaryLimitModificationType.MODIFY_OR_ADD) {
487+
// invalid modification
488+
temporaryLimitsReports.add(ReportNode.newRootReportNode()
489+
.withAllResourceBundlesFromClasspath()
490+
.withMessageTemplate("network.modification.temporaryLimitsNoMatch")
491+
.withUntypedValue(LIMIT_ACCEPTABLE_DURATION, limitAcceptableDuration)
492+
.withSeverity(TypedValue.WARN_SEVERITY)
493+
.build());
494+
}
495+
}
496+
497+
private static void modifyTemporaryLimit(
498+
CurrentLimitsAdder limitsAdder,
499+
CurrentTemporaryLimitModificationInfos limitModificationInfos,
500+
List<ReportNode> temporaryLimitsReports,
501+
LoadingLimits.TemporaryLimit limitToModify,
502+
double limitValue,
503+
String limitDurationToReport,
504+
String limitValueToReport,
505+
int limitAcceptableDuration) {
506+
if (Double.compare(limitToModify.getValue(), limitValue) != 0 && limitModificationInfos.getModificationType() != null) {
507+
temporaryLimitsReports.add(ReportNode.newRootReportNode()
508+
.withAllResourceBundlesFromClasspath()
509+
.withMessageTemplate("network.modification.temporaryLimitModified.name")
510+
.withUntypedValue(NAME, limitModificationInfos.getName())
511+
.withUntypedValue(DURATION, limitDurationToReport)
512+
.withUntypedValue(VALUE, limitValueToReport)
513+
.withUntypedValue("oldValue",
514+
limitToModify.getValue() == Double.MAX_VALUE ? "no value"
515+
: String.valueOf(limitToModify.getValue()))
516+
.withSeverity(TypedValue.INFO_SEVERITY)
517+
.build());
518+
addTemporaryLimit(limitsAdder, limitModificationInfos.getName(), limitValue, limitAcceptableDuration);
519+
} else {
520+
// no real modification
521+
addTemporaryLimit(limitsAdder, limitModificationInfos.getName(), limitToModify.getValue(), limitAcceptableDuration);
522+
}
523+
}
524+
525+
private static void createTemporaryLimit(
526+
CurrentLimitsAdder limitsAdder,
527+
CurrentTemporaryLimitModificationInfos limit,
528+
List<ReportNode> temporaryLimitsReports,
529+
String limitDurationToReport,
530+
String limitValueToReport,
531+
double limitValue,
532+
int limitAcceptableDuration) {
533+
temporaryLimitsReports.add(ReportNode.newRootReportNode()
534+
.withAllResourceBundlesFromClasspath()
535+
.withMessageTemplate("network.modification.temporaryLimitAdded.name")
536+
.withUntypedValue(NAME, limit.getName())
537+
.withUntypedValue(DURATION, limitDurationToReport)
538+
.withUntypedValue(VALUE, limitValueToReport)
539+
.withSeverity(TypedValue.INFO_SEVERITY)
540+
.build());
541+
addTemporaryLimit(limitsAdder, limit.getName(), limitValue, limitAcceptableDuration);
542+
}
543+
544+
private static void addTemporaryLimit(CurrentLimitsAdder limitsAdder, String limit, double limitValue, int limitAcceptableDuration) {
545+
limitsAdder
546+
.beginTemporaryLimit()
547+
.setName(limit)
548+
.setValue(limitValue)
549+
.setAcceptableDuration(limitAcceptableDuration)
550+
.endTemporaryLimit();
551+
}
552+
553+
private LoadingLimits.TemporaryLimit getTemporaryLimitToModify(
554+
CurrentLimits networkCurrentLimits,
555+
CurrentTemporaryLimitModificationInfos limit,
556+
CurrentLimitsModificationInfos currentLimitsInfos,
557+
TemporaryLimitModificationType temporaryLimitsModificationType) {
558+
int limitAcceptableDuration = limit.getAcceptableDuration() == null ? Integer.MAX_VALUE : limit.getAcceptableDuration();
559+
LoadingLimits.TemporaryLimit limitToModify;
560+
limitToModify = networkCurrentLimits.getTemporaryLimit(limitAcceptableDuration);
561+
if (limitToModify != null && !limitToModify.getName().equals(limit.getName())) {
562+
boolean isThisLimitDeleted = isThisLimitDeleted(currentLimitsInfos.getTemporaryLimits(), limitAcceptableDuration);
563+
if (isThisLimitDeleted) {
564+
limitToModify = null;
565+
} else if (TemporaryLimitModificationType.ADD.equals(limit.getModificationType())) {
566+
throw new PowsyblException("2 temporary limits have the same duration " + limitAcceptableDuration);
567+
}
568+
}
569+
570+
//Additional check for limit sets tabular modifications
571+
if (TemporaryLimitModificationType.ADD.equals(temporaryLimitsModificationType)) {
572+
networkCurrentLimits.getTemporaryLimits().stream().filter(temporaryLimit -> temporaryLimit.getName().equals(limit.getName())).findFirst().ifPresent(temporaryLimit -> {
573+
throw new PowsyblException("2 temporary limits have the same name " + limit.getName());
574+
});
575+
}
576+
return limitToModify;
577+
}
578+
506579
protected boolean characteristicsModified(BranchModificationInfos branchModificationInfos) {
507580
return branchModificationInfos.getX() != null
508581
&& branchModificationInfos.getX().getValue() != null

0 commit comments

Comments
 (0)