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

Consider sides when applying limitReductions with IdentifiableCriterion #3050

Merged
merged 5 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AtLeast name is a bit unexpected now that there is this sides consideration.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
import java.util.Objects;

/**
* <p>Criterion checking that at least one side of a network element belongs to a country defined in a list.</p>
* <p>Criterion checking that one of side of the network element belongs to a country defined in a list.</p>
* <p>When <code>filter</code> is called with a non-null <code>side</code>, only the country on this particular side
* is checked. Else, the validation is performed on whichever side.</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"on whichever side" does not reflect what's written in the code.

Suggested change
* <p>Criterion checking that one of side of the network element belongs to a country defined in a list.</p>
* <p>When <code>filter</code> is called with a non-null <code>side</code>, only the country on this particular side
* is checked. Else, the validation is performed on whichever side.</p>
* <p>Criterion checking that one of the sides of the network element belongs to a country defined in a list.</p>
* <p>When {@link #filter(NetworkElement, ThreeSides)}} is called with a non-null <code>side</code>, only the country on this particular side
* is checked.</p>

* @author Olivier Perrin {@literal <olivier.perrin@rte-france.com>}
*/
public class AtLeastOneCountryCriterion implements Criterion {
Expand All @@ -40,7 +42,12 @@ public boolean filter(Identifiable<?> identifiable, IdentifiableType type) {

@Override
public boolean filter(NetworkElement networkElement) {
return filterWithCountries(getCountriesToCheck(networkElement));
return filter(networkElement, null);
}

@Override
public boolean filter(NetworkElement networkElement, ThreeSides side) {
return filterWithCountries(getCountriesToCheck(networkElement, side));
}

public List<Country> getCountries() {
Expand All @@ -55,8 +62,10 @@ private List<Country> getCountriesToCheck(Identifiable<?> identifiable, Identifi
}
}

private List<Country> getCountriesToCheck(NetworkElement networkElement) {
return Arrays.asList(networkElement.getCountry1().orElse(null), networkElement.getCountry2().orElse(null));
private List<Country> getCountriesToCheck(NetworkElement networkElement, ThreeSides side) {
return side != null ?
Collections.singletonList(networkElement.getCountry(side).orElse(null)) :
Arrays.asList(networkElement.getCountry1().orElse(null), networkElement.getCountry2().orElse(null));
flo-dup marked this conversation as resolved.
Show resolved Hide resolved
}

private boolean filterWithCountries(List<Country> countriesToCheck) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@
import com.powsybl.iidm.criteria.translation.NetworkElement;
import com.powsybl.iidm.network.Identifiable;
import com.powsybl.iidm.network.IdentifiableType;
import com.powsybl.iidm.network.ThreeSides;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
* <p>Criterion checking that one of the nominal voltages of the network element, <b>on whichever side</b>,
* <p>Criterion checking that one of the nominal voltages of the network element
* is inside a {@link VoltageInterval}.</p>
* <p>When <code>filter</code> is called with a non-null <code>side</code>, the voltage level on this particular side
* should be inside the {@link VoltageInterval}. Else, the validation is performed on whichever side.</p>
* @author Olivier Perrin {@literal <olivier.perrin@rte-france.com>}
*/
public class AtLeastOneNominalVoltageCriterion implements Criterion {
Expand All @@ -43,7 +46,12 @@ public boolean filter(Identifiable<?> identifiable, IdentifiableType type) {

@Override
public boolean filter(NetworkElement networkElement) {
return filterNominalVoltages(getNominalVoltagesToCheck(networkElement));
return filter(networkElement, null);
}

@Override
public boolean filter(NetworkElement networkElement, ThreeSides side) {
return filterNominalVoltages(getNominalVoltagesToCheck(networkElement, side));
}

private List<Double> getNominalVoltagesToCheck(Identifiable<?> identifiable, IdentifiableType type) {
Expand All @@ -56,10 +64,12 @@ private List<Double> getNominalVoltagesToCheck(Identifiable<?> identifiable, Ide
};
}

private List<Double> getNominalVoltagesToCheck(NetworkElement networkElement) {
return Arrays.asList(networkElement.getNominalVoltage1().orElse(null),
networkElement.getNominalVoltage2().orElse(null),
networkElement.getNominalVoltage3().orElse(null));
private List<Double> getNominalVoltagesToCheck(NetworkElement networkElement, ThreeSides side) {
return side != null ?
Collections.singletonList(networkElement.getNominalVoltage(side).orElse(null)) :
Arrays.asList(networkElement.getNominalVoltage1().orElse(null),
networkElement.getNominalVoltage2().orElse(null),
networkElement.getNominalVoltage3().orElse(null));
}

private boolean filterNominalVoltages(List<Double> nominalVoltagesToCheck) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.powsybl.iidm.network.Identifiable;
import com.powsybl.iidm.network.IdentifiableType;
import com.powsybl.iidm.criteria.translation.NetworkElement;
import com.powsybl.iidm.network.ThreeSides;

/**
* the purpose of these class is to filter contingencies in a criterion contingency list
Expand Down Expand Up @@ -45,4 +46,8 @@ default boolean filter(Identifiable<?> identifiable, IdentifiableType type) {
default boolean filter(NetworkElement networkElement) {
return false;
}

default boolean filter(NetworkElement networkElement, ThreeSides side) {
return filter(networkElement);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.powsybl.iidm.criteria;

import com.powsybl.iidm.criteria.translation.NetworkElement;
import com.powsybl.iidm.network.ThreeSides;

/**
* <p>Visitor used to detect if a given {@link NetworkElement} validates criteria.</p>
Expand All @@ -16,22 +17,28 @@
public class NetworkElementVisitor {

private final NetworkElement networkElement;
private final ThreeSides side;

public NetworkElementVisitor(NetworkElement networkElement) {
this(networkElement, null);
}

public NetworkElementVisitor(NetworkElement networkElement, ThreeSides side) {
this.networkElement = networkElement;
this.side = side;
}

public boolean visit(AbstractNetworkElementEquipmentCriterion c) {
return networkElement.isValidFor(c.getNetworkElementCriterionType())
&& doRespectCriterion(networkElement, c.getCountryCriterion())
&& doRespectCriterion(networkElement, c.getNominalVoltageCriterion());
&& doRespectCriterion(c.getCountryCriterion())
&& doRespectCriterion(c.getNominalVoltageCriterion());
}

public boolean visit(NetworkElementIdListCriterion c) {
return c.getNetworkElementIds().contains(networkElement.getId());
}

private boolean doRespectCriterion(NetworkElement networkElement, Criterion criterion) {
return criterion == null || criterion.filter(networkElement);
private boolean doRespectCriterion(Criterion criterion) {
return criterion == null || criterion.filter(networkElement, side);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,35 @@ public String getId() {

@Override
public Optional<Country> getCountry1() {
return getCountry(TwoSides.ONE);
return getCountry(ThreeSides.ONE);
}

@Override
public Optional<Country> getCountry2() {
return getCountry(TwoSides.TWO);
return getCountry(ThreeSides.TWO);
}

@Override
public Optional<Country> getCountry3() {
return getCountry(ThreeSides.THREE);
}

@Override
public Optional<Country> getCountry() {
return getCountry1();
}

private Optional<Country> getCountry(TwoSides side) {
@Override
public Optional<Country> getCountry(ThreeSides side) {
return switch (identifiable.getType()) {
case LINE, TIE_LINE -> getCountryFromTerminal(((Branch<?>) identifiable).getTerminal(side));
case HVDC_LINE -> getCountryFromTerminal(((HvdcLine) identifiable).getConverterStation(side).getTerminal());
case LINE, TIE_LINE -> side != ThreeSides.THREE ?
getCountryFromTerminal(((Branch<?>) identifiable).getTerminal(side.toTwoSides())) : Optional.empty();
case HVDC_LINE -> side != ThreeSides.THREE ?
getCountryFromTerminal(((HvdcLine) identifiable).getConverterStation(side.toTwoSides()).getTerminal()) : Optional.empty();
case DANGLING_LINE, GENERATOR, LOAD, BATTERY, SHUNT_COMPENSATOR, STATIC_VAR_COMPENSATOR, BUSBAR_SECTION, HVDC_CONVERTER_STATION ->
side != TwoSides.ONE ? Optional.empty() : getCountryFromTerminal(((Injection<?>) identifiable).getTerminal());
case TWO_WINDINGS_TRANSFORMER -> side != TwoSides.ONE ? Optional.empty() :
((TwoWindingsTransformer) identifiable).getSubstation().map(Substation::getNullableCountry);
case THREE_WINDINGS_TRANSFORMER -> side != TwoSides.ONE ? Optional.empty() :
((ThreeWindingsTransformer) identifiable).getSubstation().map(Substation::getNullableCountry);
side != ThreeSides.ONE ? Optional.empty() : getCountryFromTerminal(((Injection<?>) identifiable).getTerminal());
case TWO_WINDINGS_TRANSFORMER -> ((TwoWindingsTransformer) identifiable).getSubstation().map(Substation::getNullableCountry);
case THREE_WINDINGS_TRANSFORMER -> ((ThreeWindingsTransformer) identifiable).getSubstation().map(Substation::getNullableCountry);
default -> Optional.empty();
};
}
Expand Down Expand Up @@ -99,7 +105,8 @@ public Optional<Double> getNominalVoltage() {
return getNominalVoltage1();
}

private Optional<Double> getNominalVoltage(ThreeSides side) {
@Override
public Optional<Double> getNominalVoltage(ThreeSides side) {
return switch (identifiable.getType()) {
case DANGLING_LINE, GENERATOR, LOAD, BATTERY, SHUNT_COMPENSATOR, STATIC_VAR_COMPENSATOR, BUSBAR_SECTION, HVDC_CONVERTER_STATION ->
side != ThreeSides.ONE ? Optional.empty() :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import com.powsybl.iidm.criteria.NetworkElementCriterion;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.ThreeSides;

import java.util.Optional;

Expand All @@ -25,14 +26,32 @@ public interface NetworkElement {

Optional<Country> getCountry2();

Optional<Country> getCountry3();

Optional<Country> getCountry();

default Optional<Country> getCountry(ThreeSides side) {
return switch (side) {
case ONE -> getCountry1();
case TWO -> getCountry2();
case THREE -> getCountry3();
};
}

Optional<Double> getNominalVoltage1();

Optional<Double> getNominalVoltage2();

Optional<Double> getNominalVoltage3();

default Optional<Double> getNominalVoltage(ThreeSides side) {
return switch (side) {
case ONE -> getNominalVoltage1();
case TWO -> getNominalVoltage2();
case THREE -> getNominalVoltage3();
};
}

Optional<Double> getNominalVoltage();

boolean isValidFor(NetworkElementCriterion.NetworkElementCriterionType networkElementCriterionType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@
*/
package com.powsybl.iidm.criteria;

import com.powsybl.iidm.criteria.translation.DefaultNetworkElementAdapter;
import com.powsybl.iidm.criteria.translation.NetworkElement;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.DanglingLine;
import com.powsybl.iidm.network.ThreeSides;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.util.List;
import java.util.Optional;

import static com.powsybl.iidm.criteria.translation.DefaultNetworkElementAdapterTest.mockDanglingLine;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.mockito.Mockito.when;

/**
* @author Olivier Perrin {@literal <olivier.perrin at rte-france.com>}
Expand Down Expand Up @@ -46,10 +47,10 @@ void typeTest() {
@Test
void emptyCriterionTest() {
DanglingLineCriterion criterion = new DanglingLineCriterion(null, null);
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine1)));
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine2)));
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine3)));
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine4)));
assertCriterionTrue(criterion, danglingLine1);
assertCriterionTrue(criterion, danglingLine2);
assertCriterionTrue(criterion, danglingLine3);
assertCriterionTrue(criterion, danglingLine4);

NetworkElement anotherTypeElement = Mockito.mock(NetworkElement.class);
assertFalse(criterion.accept(new NetworkElementVisitor(anotherTypeElement)));
Expand All @@ -59,51 +60,51 @@ void emptyCriterionTest() {
void nominalVoltageTest() {
DanglingLineCriterion criterion = new DanglingLineCriterion(null, new SingleNominalVoltageCriterion(
VoltageInterval.between(40., 100., true, true)));
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine1)));
assertFalse(criterion.accept(new NetworkElementVisitor(danglingLine2)));
assertFalse(criterion.accept(new NetworkElementVisitor(danglingLine3)));
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine4)));
assertCriterionTrue(criterion, danglingLine1);
assertCriterionFalse(criterion, danglingLine2);
assertCriterionFalse(criterion, danglingLine3);
assertCriterionTrue(criterion, danglingLine4);
}

@Test
void countryTest() {
DanglingLineCriterion criterion = new DanglingLineCriterion(new SingleCountryCriterion(List.of(Country.BE)), null);
assertFalse(criterion.accept(new NetworkElementVisitor(danglingLine1)));
assertFalse(criterion.accept(new NetworkElementVisitor(danglingLine2)));
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine3)));
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine4)));
assertCriterionFalse(criterion, danglingLine1);
assertCriterionFalse(criterion, danglingLine2);
assertCriterionTrue(criterion, danglingLine3);
assertCriterionTrue(criterion, danglingLine4);

criterion = new DanglingLineCriterion(new SingleCountryCriterion(List.of(Country.FR, Country.BE)), null);
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine1)));
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine2)));
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine3)));
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine4)));
assertCriterionTrue(criterion, danglingLine1);
assertCriterionTrue(criterion, danglingLine2);
assertCriterionTrue(criterion, danglingLine3);
assertCriterionTrue(criterion, danglingLine4);
}

@Test
void mixedCriteriaTest() {
DanglingLineCriterion criterion = new DanglingLineCriterion(new SingleCountryCriterion(List.of(Country.FR)),
new SingleNominalVoltageCriterion(
VoltageInterval.between(350., 450., true, true)));
assertFalse(criterion.accept(new NetworkElementVisitor(danglingLine1)));
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine2)));
assertFalse(criterion.accept(new NetworkElementVisitor(danglingLine3)));
assertFalse(criterion.accept(new NetworkElementVisitor(danglingLine4)));
assertCriterionFalse(criterion, danglingLine1);
assertCriterionTrue(criterion, danglingLine2);
assertCriterionFalse(criterion, danglingLine3);
assertCriterionFalse(criterion, danglingLine4);
}

private void assertCriterionTrue(DanglingLineCriterion criterion, NetworkElement danglingLine) {
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine)));
assertTrue(criterion.accept(new NetworkElementVisitor(danglingLine, ThreeSides.ONE)));
}

private void assertCriterionFalse(DanglingLineCriterion criterion, NetworkElement danglingLine) {
assertFalse(criterion.accept(new NetworkElementVisitor(danglingLine)));
assertFalse(criterion.accept(new NetworkElementVisitor(danglingLine, ThreeSides.ONE)));
}

protected static NetworkElement createDanglingLine(String id, Country country, double nominalVoltage) {
NetworkElement n = Mockito.mock(NetworkElement.class);
when(n.getId()).thenReturn(id);
when(n.getCountry()).thenReturn(Optional.of(country));
when(n.getCountry1()).thenReturn(Optional.of(country));
when(n.getCountry2()).thenReturn(Optional.empty());
when(n.getNominalVoltage()).thenReturn(Optional.of(nominalVoltage));
when(n.getNominalVoltage1()).thenReturn(Optional.of(nominalVoltage));
when(n.getNominalVoltage2()).thenReturn(Optional.empty());
when(n.getNominalVoltage3()).thenReturn(Optional.empty());
when(n.isValidFor(NetworkElementCriterion.NetworkElementCriterionType.DANGLING_LINE)).thenReturn(true);
when(n.isValidFor(NetworkElementCriterion.NetworkElementCriterionType.IDENTIFIABLE)).thenReturn(true);
return n;
DanglingLine danglingLine = mockDanglingLine(id, country, nominalVoltage);
return new DefaultNetworkElementAdapter(danglingLine);
}
}

Expand Down
Loading