Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
25ff548
Modify FlowsLimitsHolder API to manage multiple active OperationalLim…
NathanDissoubray Jan 22, 2026
b71f560
Update Impls that are easy to update
NathanDissoubray Jan 22, 2026
0fa38a1
Modify OperationalLimitsGroup(s)Impl
NathanDissoubray Jan 22, 2026
497d475
Add a addSelected method and to keep same expected results with setSe…
NathanDissoubray Jan 23, 2026
673f9c4
Modify checkLimitViolation to get multiple Overload instead of a sing…
NathanDissoubray Jan 26, 2026
b36f24a
Implement methods for security needed to handle multiple limits, apar…
NathanDissoubray Jan 26, 2026
940fd40
Rename getAllSelectedOperationalLimitsGroup -> ...Groups
NathanDissoubray Jan 27, 2026
0df8345
Add methods to get Active,Apparent,Current limits from an id
NathanDissoubray Jan 27, 2026
6270e7f
Rename getSelectedOrThrow to getOperationalLimitsGroupOrThrow in OpLi…
NathanDissoubray Jan 27, 2026
cc5aa65
Remove TODO
NathanDissoubray Jan 27, 2026
5c3db00
Add back constructor of OperationalLimitsGroupImpl with a string and …
NathanDissoubray Jan 27, 2026
81c500b
Remove unneeded blank line
NathanDissoubray Jan 27, 2026
f6092a4
Replace usage of string collection by a predicate in OperationalLimit…
NathanDissoubray Jan 28, 2026
8bf6b68
Add missing . in error message
NathanDissoubray Jan 28, 2026
261f236
Simplify calls to functions getting a given side for the limits
NathanDissoubray Jan 28, 2026
1bf8ee0
Remove notification of deselection on setSelected if the group is alr…
NathanDissoubray Jan 28, 2026
b6459c9
LimitsComputer adaptations
olperr1 Jan 28, 2026
f11157f
Modify getLoadingLimits and getAllSelectedLoadingLimits to a simpler …
NathanDissoubray Jan 29, 2026
6be65dc
Replace collect(Collectors.toList()) by toList()
NathanDissoubray Jan 29, 2026
c4e921b
Clean function name and predicate useage in OperationalLimitsGroupsIm…
NathanDissoubray Jan 29, 2026
6d1859a
Checkstyle
NathanDissoubray Jan 29, 2026
ed032a9
Overload have the id of the limits group they are related to
NathanDissoubray Jan 29, 2026
6fabc50
Add method to return all the ids of the side of a branch from the bra…
NathanDissoubray Jan 29, 2026
c25731f
Add javadoc
NathanDissoubray Jan 29, 2026
1b3884f
Change some private functions in LimitViolationUtils to public, make …
NathanDissoubray Jan 30, 2026
82a2468
Rewrite checkLimitViolation to handle multiple groups
NathanDissoubray Jan 30, 2026
96a14bf
Fix logic error with naming of group in overload construction
NathanDissoubray Jan 30, 2026
5f2837d
Fix forgotten filtering of overloading on permanent limits
NathanDissoubray Jan 30, 2026
1e35b7c
Add ability to deselect multiple groups at once
NathanDissoubray Jan 30, 2026
30d4ba7
Add functions to add and deselect groups directly from a branch
NathanDissoubray Jan 30, 2026
a60ce89
Modify the DefaultLimitViolationDetector to use methods in LimitViola…
NathanDissoubray Feb 3, 2026
d02cb0f
Modify LimitViolationDetector to use LimitViolationDetection
NathanDissoubray Feb 3, 2026
36a9434
Modify LimitViolationDetector on temporary to also use LimitViolation…
NathanDissoubray Feb 3, 2026
293bb09
Add operationalGroupId and the value of the permanent limit in the pe…
NathanDissoubray Feb 3, 2026
4a72244
Add a test to check multiple activated limits group
NathanDissoubray Feb 4, 2026
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
124 changes: 123 additions & 1 deletion iidm/iidm-api/src/main/java/com/powsybl/iidm/network/Branch.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import java.util.Collection;
import java.util.Optional;
import java.util.function.Function;

import static com.powsybl.iidm.network.util.LoadingLimitsUtil.initializeFromLoadingLimits;

Expand Down Expand Up @@ -141,6 +142,20 @@ public interface Branch<I extends Branch<I>> extends Identifiable<I> {
*/
Optional<OperationalLimitsGroup> getSelectedOperationalLimitsGroup1();

/**
* Get all the selected {@link OperationalLimitsGroup} on the given <code>side</code>.
* @param side the side to get the group limits on
* @return all the selected {@link OperationalLimitsGroup} on the <code>side</code>, might be empty if none is selected.
*/
Collection<OperationalLimitsGroup> getAllSelectedOperationalLimitsGroups(TwoSides side);

/**
* Get the id of all the selected {@link OperationalLimitsGroup} on the given <code>side</code>
* @param side the side to get the id of the group limits on
* @return all the selected {@link OperationalLimitsGroup} on the <code>side</code>, might be empty if none is selected.
*/
Collection<String> getAllSelectedOperationalLimitsGroupIds(TwoSides side);

/**
* <p>Create a new {@link OperationalLimitsGroup} on side 1 with the given ID.</p>
* <p>If a group of the given ID already exists, it is replaced silently.</p>
Expand All @@ -149,14 +164,25 @@ public interface Branch<I extends Branch<I>> extends Identifiable<I> {
OperationalLimitsGroup newOperationalLimitsGroup1(String id);

/**
* <p>Set the {@link OperationalLimitsGroup} corresponding to the given ID as as the selected one on side 1.</p>
* <p>Set the {@link OperationalLimitsGroup} corresponding to the given ID as the selected one on side 1.</p>
* <p>Throw a {@link com.powsybl.commons.PowsyblException} if the ID doesn't correspond to any existing group.</p>
* <p>Throw an {@link NullPointerException} if the ID is <code>null</code>.
* To reset the selected group, use {@link #cancelSelectedOperationalLimitsGroup1}.</p>
* @param id an ID of {@link OperationalLimitsGroup}
*/
void setSelectedOperationalLimitsGroup1(String id);

/**
* <p>Set the {@link OperationalLimitsGroup} corresponding to the given IDs as selected on side 1. If other groups were also selected, they are still selected</p>
* <p>Throw a {@link com.powsybl.commons.PowsyblException} if the ID doesn't correspond to any existing group.</p>
* <p>Throw an {@link NullPointerException} if any ID is <code>null</code>.</p>
* To deselect a selected group, use {@link #deselectOperationalLimitsGroups1(String...)}.
* To deselect all the selected groups, use {@link #cancelSelectedOperationalLimitsGroup1()}
* To have a single group selected and deselect all other groups, use {@link #setSelectedOperationalLimitsGroup1(String)}
* @param ids the IDs of one or more {@link OperationalLimitsGroup}
*/
void addSelectedOperationalLimitsGroups1(String... ids);

/**
* <p>Remove the {@link OperationalLimitsGroup} corresponding to the given ID on side 1.</p>
* <p>Throw an {@link NullPointerException} if the ID is <code>null</code>.
Expand All @@ -170,6 +196,16 @@ public interface Branch<I extends Branch<I>> extends Identifiable<I> {
*/
void cancelSelectedOperationalLimitsGroup1();

/**
* <p>Deselect the {@link OperationalLimitsGroup} corresponding to all the <code>ids</code> on side 1.</p>
* <p>If the {@link OperationalLimitsGroup} exists but is not selected, this method will do nothing</p>
* <p>Throw a {@link com.powsybl.commons.PowsyblException} if the ID doesn't correspond to any existing group</p>
* <p>Throw a {@link NullPointerException} if the ID is <code>null</code>.</p>
* To deselect all {@link OperationalLimitsGroup}, use {@link #cancelSelectedOperationalLimitsGroup1()}
* @param ids the ID of the groups to remove from the selected
*/
void deselectOperationalLimitsGroups1(String... ids);

/**
* Get the {@link CurrentLimits} of the selected {@link OperationalLimitsGroup} on side 1.
* @return {@link CurrentLimits} of the selected {@link OperationalLimitsGroup} on side 1 if any, <code>null</code> otherwise.
Expand Down Expand Up @@ -218,6 +254,20 @@ default ApparentPowerLimits getNullableApparentPowerLimits1() {
return getApparentPowerLimits1().orElse(null);
}

/**
* Helper function to return all the limits of this branch's <code>side</code>, of a given type using the provided function to get it from each {@link OperationalLimitsGroup}
* @param operationalLimitToLoadingLimitFunction the function that will return an optional {@link LoadingLimits} from an {@link OperationalLimitsGroup}
* @return a collection of loadingLimits, all the same type
* @param <T> the type of loadingLimit
*/
private <T extends LoadingLimits> Collection<T> getAllSelectedLoadingLimits(Function<OperationalLimitsGroup, Optional<T>> operationalLimitToLoadingLimitFunction, TwoSides side) {
return getAllSelectedOperationalLimitsGroups(side)
.stream()
.map(operationalLimitToLoadingLimitFunction)
.flatMap(Optional::stream)
.toList();
}

/**
* <p>Create an adder to add a new {@link CurrentLimits} in the selected {@link OperationalLimitsGroup} on side 1.</p>
* <p>If there's no selected group, the adder will also create a new group with the default name and set it as selected.
Expand Down Expand Up @@ -374,6 +424,17 @@ default ApparentPowerLimitsAdder newApparentPowerLimits1(ApparentPowerLimits app
*/
void setSelectedOperationalLimitsGroup2(String id);

/**
* <p>Set the {@link OperationalLimitsGroup} corresponding to the given IDs as selected on side 2. If other groups were also selected, they are still selected</p>
* <p>Throw a {@link com.powsybl.commons.PowsyblException} if the ID doesn't correspond to any existing group.</p>
* <p>Throw an {@link NullPointerException} if any ID is <code>null</code>.</p>
* To deselect a selected group, use {@link #deselectOperationalLimitsGroups2(String...)}.
* To deselect all the selected groups, use {@link #cancelSelectedOperationalLimitsGroup2()}
* To have a single group selected and deselect all other groups, use {@link #setSelectedOperationalLimitsGroup2(String)}
* @param ids the IDs of one or more {@link OperationalLimitsGroup}
*/
void addSelectedOperationalLimitsGroups2(String... ids);

/**
* <p>Remove the {@link OperationalLimitsGroup} corresponding to the given ID on side 2.</p>
* <p>Throw an {@link NullPointerException} if the ID is <code>null</code>.
Expand All @@ -387,6 +448,16 @@ default ApparentPowerLimitsAdder newApparentPowerLimits1(ApparentPowerLimits app
*/
void cancelSelectedOperationalLimitsGroup2();

/**
* <p>Deselect the {@link OperationalLimitsGroup} corresponding to all the <code>ids</code> on side 2.</p>
* <p>If the {@link OperationalLimitsGroup} exists but is not selected, this method will do nothing</p>
* <p>Throw a {@link com.powsybl.commons.PowsyblException} if the ID doesn't correspond to any existing group</p>
* <p>Throw a {@link NullPointerException} if the ID is <code>null</code>.</p>
* To deselect all {@link OperationalLimitsGroup}, use {@link #cancelSelectedOperationalLimitsGroup2()}
* @param ids the ID of the groups to remove from the selected
*/
void deselectOperationalLimitsGroups2(String... ids);

/**
* Get the {@link CurrentLimits} of the selected {@link OperationalLimitsGroup} on side 2.
* @return {@link CurrentLimits} of the selected {@link OperationalLimitsGroup} on side 2 if any, <code>null</code> otherwise.
Expand Down Expand Up @@ -521,20 +592,53 @@ default Optional<CurrentLimits> getCurrentLimits(TwoSides side) {
};
}

/**
* Get all the limits of type {@link LimitType#CURRENT} on the <code>side</code> of this branch,
* for the {@link OperationalLimitsGroup} that are selected
* @param side the side on which to get the limits
* @return a collection of all the current limits of this branch on the given <code>side</code>,
* one for each {@link OperationalLimitsGroup} that is selected
*/
default Collection<CurrentLimits> getAllSelectedCurrentLimits(TwoSides side) {
return getAllSelectedLoadingLimits(OperationalLimitsGroup::getCurrentLimits, side);
}

default Optional<ActivePowerLimits> getActivePowerLimits(TwoSides side) {
return switch (side) {
case ONE -> getActivePowerLimits1();
case TWO -> getActivePowerLimits2();
};
}

/**
* Get all the limits of type {@link LimitType#ACTIVE_POWER} on the <code>side</code> of this branch,
* for the {@link OperationalLimitsGroup} that are selected
* @param side the side on which to get the limits
* @return a collection of all the active power limits of this branch on the given <code>side</code>,
* one for each {@link OperationalLimitsGroup} that is selected
*/
default Collection<ActivePowerLimits> getAllSelectedActivePowerLimits(TwoSides side) {
return getAllSelectedLoadingLimits(OperationalLimitsGroup::getActivePowerLimits, side);
}

default Optional<ApparentPowerLimits> getApparentPowerLimits(TwoSides side) {
return switch (side) {
case ONE -> getApparentPowerLimits1();
case TWO -> getApparentPowerLimits2();
};
}

/**
* Get all the limits of type {@link LimitType#APPARENT_POWER} on the <code>side</code> of this branch,
* for the {@link OperationalLimitsGroup} that are selected
* @param side the side on which to get the limits
* @return a collection of all the apparent power limits of this branch on the given <code>side</code>,
* one for each {@link OperationalLimitsGroup} that is selected
*/
default Collection<ApparentPowerLimits> getAllSelectedApparentPowerLimits(TwoSides side) {
return getAllSelectedLoadingLimits(OperationalLimitsGroup::getApparentPowerLimits, side);
}

default Optional<? extends LoadingLimits> getLimits(LimitType type, TwoSides side) {
return switch (type) {
case CURRENT -> getCurrentLimits(side);
Expand All @@ -545,6 +649,24 @@ default Optional<? extends LoadingLimits> getLimits(LimitType type, TwoSides sid
};
}

/**
* Get all the limits of the given <code>type</code>, on the <code>side</code> of this branch,
* for the {@link OperationalLimitsGroup} that are selected
* @param type the type of the limit, refer to {@link LimitType}
* @param side the side on which to get the limits
* @return a collection of all the <code>type</code> limits of this branch on the <code>side</code>,
* one for each {@link OperationalLimitsGroup} that is selected. Might be empty if none is selected.
*/
default Collection<? extends LoadingLimits> getAllSelectedLimits(LimitType type, TwoSides side) {
return switch (type) {
case CURRENT -> getAllSelectedCurrentLimits(side);
case ACTIVE_POWER -> getAllSelectedActivePowerLimits(side);
case APPARENT_POWER -> getAllSelectedApparentPowerLimits(side);
default ->
throw new UnsupportedOperationException(String.format("Getting %s limits is not supported.", type.name()));
};
}

default CurrentLimits getNullableCurrentLimits(TwoSides side) {
return switch (side) {
case ONE -> getNullableCurrentLimits1();
Expand Down
Loading