Skip to content

Commit

Permalink
Rework testing of limits in CIM100
Browse files Browse the repository at this point in the history
Signed-off-by: Romain Courtier <[email protected]>
  • Loading branch information
rcourtier committed Jan 29, 2025
1 parent eba05fc commit c9bf10e
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,22 @@ void missingLimitsTest() {
assertNull(limits2.getTemporaryLimit(1200));
}

@Test
void limitsCim100Test() {
// CGMES network:
// An ACLineSegment ACL with CurrentLimit and ApparentPowerLimit (each time patl and tatl) on side 1.
// IIDM network:
// Limits are imported smoothly.
Network network = readCgmesResources(DIR, "limits_cim100.xml");

// Loading limits have been imported smoothly.
Line line = network.getLine("ACL");
assertTrue(line.getCurrentLimits1().isPresent());
assertEquals(100.0, line.getCurrentLimits1().get().getPermanentLimit());
assertEquals(200.0, line.getCurrentLimits1().get().getTemporaryLimit(600).getValue());
assertTrue(line.getApparentPowerLimits1().isPresent());
assertEquals(102.0, line.getApparentPowerLimits1().get().getPermanentLimit());
assertEquals(202.0, line.getApparentPowerLimits1().get().getTemporaryLimit(600).getValue());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import com.powsybl.commons.datasource.ReadOnlyDataSource;
import com.powsybl.commons.datasource.ReadOnlyMemDataSource;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.LoadingLimits.TemporaryLimit;
import com.powsybl.triplestore.api.TripleStoreFactory;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -71,39 +70,6 @@ void microGridConvertBoundary() throws IOException {
t.testConversion(expected, Cgmes3Catalog.microGrid());
}

@Test
void microGridOperationalLimits() {
Network n = networkModel(Cgmes3Catalog.microGrid(), new Conversion.Config());

Line ln = n.getLine("ffbabc27-1ccd-4fdc-b037-e341706c8d29");
assertEquals(1312.0, ln.getCurrentLimits1().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);
assertEquals(1312.0, ln.getCurrentLimits2().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);

assertEquals(1, (int) ln.getCurrentLimits1().map(lim -> lim.getTemporaryLimits().size()).orElse(-1));
TemporaryLimit lntl1 = ln.getCurrentLimits1().flatMap(lim -> lim.getTemporaryLimits().stream().findFirst()).orElseThrow(IllegalStateException::new);
assertEquals(500.0, lntl1.getValue(), 0.0);
assertEquals(10, lntl1.getAcceptableDuration());

assertEquals(1, (int) ln.getCurrentLimits2().map(lim -> lim.getTemporaryLimits().size()).orElse(-1));
TemporaryLimit lntl2 = ln.getCurrentLimits2().flatMap(lim -> lim.getTemporaryLimits().stream().findFirst()).orElseThrow(IllegalStateException::new);
assertEquals(500.0, lntl2.getValue(), 0.0);
assertEquals(10, lntl2.getAcceptableDuration());

TieLine tln = n.getTieLine("dad02278-bd25-476f-8f58-dbe44be72586 + ed0c5d75-4a54-43c8-b782-b20d7431630b");
assertEquals(1371.0, tln.getDanglingLine1().getCurrentLimits().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);
assertEquals(1226.0, tln.getDanglingLine2().getCurrentLimits().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);

assertEquals(1, (int) tln.getDanglingLine1().getCurrentLimits().map(lim -> lim.getTemporaryLimits().size()).orElse(-1));
TemporaryLimit tlntl1 = tln.getDanglingLine1().getCurrentLimits().flatMap(lim -> lim.getTemporaryLimits().stream().findFirst()).orElseThrow(IllegalStateException::new);
assertEquals(500.0, tlntl1.getValue(), 0.0);
assertEquals(10, tlntl1.getAcceptableDuration());

assertEquals(1, (int) tln.getDanglingLine2().getCurrentLimits().map(lim -> lim.getTemporaryLimits().size()).orElse(-1));
TemporaryLimit tlntl2 = ln.getCurrentLimits2().flatMap(lim -> lim.getTemporaryLimits().stream().findFirst()).orElseThrow(IllegalStateException::new);
assertEquals(500.0, tlntl2.getValue(), 0.0);
assertEquals(10, tlntl2.getAcceptableDuration());
}

@Test
void microGridWithAndWithoutTpSv() {
Properties importParams = new Properties();
Expand Down Expand Up @@ -148,27 +114,6 @@ void miniGridConvertBoundary() throws IOException {
t.testConversion(expected, Cgmes3Catalog.miniGrid());
}

@Test
void miniGridOperationalLimits() {
Network n = networkModel(Cgmes3Catalog.miniGrid(), new Conversion.Config());

TwoWindingsTransformer tw2t = n.getTwoWindingsTransformer("813365c3-5be7-4ef0-a0a7-abd1ae6dc174");
assertEquals(753.0659, tw2t.getCurrentLimits1().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);
assertEquals(4123.933, tw2t.getCurrentLimits2().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);

assertEquals(0, (int) tw2t.getCurrentLimits1().map(l -> l.getTemporaryLimits().size()).orElse(-1));
assertEquals(0, (int) tw2t.getCurrentLimits2().map(l -> l.getTemporaryLimits().size()).orElse(-1));

ThreeWindingsTransformer tw3t = n.getThreeWindingsTransformer("411b5401-0a43-404a-acb4-05c3d7d0c95c");
assertEquals(505.1817, tw3t.getLeg1().getCurrentLimits().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);
assertEquals(1683.939, tw3t.getLeg2().getCurrentLimits().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);
assertEquals(962.2509, tw3t.getLeg3().getCurrentLimits().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);

assertEquals(0, (int) tw3t.getLeg1().getCurrentLimits().map(l -> l.getTemporaryLimits().size()).orElse(-1));
assertEquals(0, (int) tw3t.getLeg2().getCurrentLimits().map(l -> l.getTemporaryLimits().size()).orElse(-1));
assertEquals(0, (int) tw3t.getLeg3().getCurrentLimits().map(l -> l.getTemporaryLimits().size()).orElse(-1));
}

@Test
void miniGridRatedS() {
Network n = networkModel(Cgmes3Catalog.miniGrid(), new Conversion.Config());
Expand Down Expand Up @@ -232,25 +177,6 @@ void smallGridConvertBoundary() throws IOException {
t.testConversion(expected, Cgmes3Catalog.smallGrid());
}

@Test
void smallGridOperationalLimits() {
Network n = networkModel(Cgmes3Catalog.smallGrid(), new Conversion.Config());

Line ln = n.getLine("04658820-c766-11e1-8775-005056c00008");
assertEquals(1000.0, ln.getCurrentLimits1().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);
assertEquals(1000.0, ln.getCurrentLimits2().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);

assertEquals(1, (int) ln.getCurrentLimits1().map(l -> l.getTemporaryLimits().size()).orElse(-1));
TemporaryLimit lntl1 = ln.getCurrentLimits1().flatMap(l -> l.getTemporaryLimits().stream().findFirst()).orElseThrow(IllegalStateException::new);
assertEquals(500.0, lntl1.getValue(), 0.0);
assertEquals(900, lntl1.getAcceptableDuration());

assertEquals(1, (int) ln.getCurrentLimits2().map(l -> l.getTemporaryLimits().size()).orElse(-1));
TemporaryLimit lntl2 = ln.getCurrentLimits2().flatMap(l -> l.getTemporaryLimits().stream().findFirst()).orElseThrow(IllegalStateException::new);
assertEquals(500.0, lntl2.getValue(), 0.0);
assertEquals(900, lntl2.getAcceptableDuration());
}

@Test
void smallGridWithAndWithoutTpSv() {
Properties importParams = new Properties();
Expand Down Expand Up @@ -314,25 +240,6 @@ void svedalaConvertBoundary() throws IOException {
t.testConversion(expected, Cgmes3Catalog.svedala());
}

@Test
void svedalaOperationalLimits() {
Network n = networkModel(Cgmes3Catalog.svedala(), new Conversion.Config());

Line ln = n.getLine("c6278b38-b777-4ad9-b395-50c4009afdff");
assertEquals(2970.0, ln.getCurrentLimits1().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);
assertEquals(2970.0, ln.getCurrentLimits2().map(LoadingLimits::getPermanentLimit).orElse(0.0), 0.0);

assertEquals(1, (int) ln.getCurrentLimits1().map(l -> l.getTemporaryLimits().size()).orElse(-1));
TemporaryLimit lntl1 = ln.getCurrentLimits1().flatMap(l -> l.getTemporaryLimits().stream().findFirst()).orElseThrow(IllegalStateException::new);
assertEquals(500.0, lntl1.getValue(), 0.0);
assertEquals(600, lntl1.getAcceptableDuration());

assertEquals(1, (int) ln.getCurrentLimits2().map(l -> l.getTemporaryLimits().size()).orElse(-1));
TemporaryLimit lntl2 = ln.getCurrentLimits2().flatMap(l -> l.getTemporaryLimits().stream().findFirst()).orElseThrow(IllegalStateException::new);
assertEquals(500.0, lntl2.getValue(), 0.0);
assertEquals(600, lntl2.getAcceptableDuration());
}

@Test
void svedalaWithAndWithoutTpSv() {
Properties importParams = new Properties();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<rdf:RDF xmlns:base="urn:uuid:" xmlns:cim="http://iec.ch/TC57/CIM100#" xmlns:md="http://iec.ch/TC57/61970-552/ModelDescription/1#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:eu="http://iec.ch/TC57/CIM100-European#">
<md:FullModel rdf:about="urn:uuid:ModelID">
<md:Model.scenarioTime>2021-03-01T23:00:00Z</md:Model.scenarioTime>
<md:Model.created>2021-03-02T10:22:58Z</md:Model.created>
<md:Model.description>Limits</md:Model.description>
<md:Model.version>001</md:Model.version>
<md:Model.profile>http://iec.ch/TC57/ns/CIM/CoreEquipment-EU/3.0</md:Model.profile>
<md:Model.profile>http://iec.ch/TC57/ns/CIM/Operation-EU/3.0</md:Model.profile>
<md:Model.modelingAuthoritySet>powsybl.org</md:Model.modelingAuthoritySet>
</md:FullModel>
<cim:GeographicalRegion rdf:ID="_GR">
<cim:IdentifiedObject.name>Geographical region</cim:IdentifiedObject.name>
</cim:GeographicalRegion>
<cim:SubGeographicalRegion rdf:ID="_SGR">
<cim:IdentifiedObject.name>Subgeographical region</cim:IdentifiedObject.name>
<cim:SubGeographicalRegion.Region rdf:resource="#_GR"/>
</cim:SubGeographicalRegion>
<cim:Substation rdf:ID="_ST_1">
<cim:IdentifiedObject.name>Substation 1</cim:IdentifiedObject.name>
<cim:Substation.Region rdf:resource="#_SGR"/>
</cim:Substation>
<cim:VoltageLevel rdf:ID="_VL_1">
<cim:IdentifiedObject.name>Voltage level 1</cim:IdentifiedObject.name>
<cim:VoltageLevel.BaseVoltage rdf:resource="#_BV"/>
<cim:VoltageLevel.Substation rdf:resource="#_ST_1"/>
</cim:VoltageLevel>
<cim:ConnectivityNode rdf:ID="_CN_1">
<cim:IdentifiedObject.name>Node 1</cim:IdentifiedObject.name>
<cim:ConnectivityNode.ConnectivityNodeContainer rdf:resource="#_VL_1"/>
</cim:ConnectivityNode>
<cim:Substation rdf:ID="_ST_2">
<cim:IdentifiedObject.name>Substation 2</cim:IdentifiedObject.name>
<cim:Substation.Region rdf:resource="#_SGR"/>
</cim:Substation>
<cim:VoltageLevel rdf:ID="_VL_2">
<cim:IdentifiedObject.name>Voltage level 2</cim:IdentifiedObject.name>
<cim:VoltageLevel.BaseVoltage rdf:resource="#_BV"/>
<cim:VoltageLevel.Substation rdf:resource="#_ST_2"/>
</cim:VoltageLevel>
<cim:ConnectivityNode rdf:ID="_CN_2">
<cim:IdentifiedObject.name>Node 2</cim:IdentifiedObject.name>
<cim:ConnectivityNode.ConnectivityNodeContainer rdf:resource="#_VL_2"/>
</cim:ConnectivityNode>
<cim:ACLineSegment rdf:ID="_ACL">
<cim:IdentifiedObject.name>AC line segment</cim:IdentifiedObject.name>
<cim:ACLineSegment.b0ch>0</cim:ACLineSegment.b0ch>
<cim:ACLineSegment.bch>0</cim:ACLineSegment.bch>
<cim:ACLineSegment.g0ch>0</cim:ACLineSegment.g0ch>
<cim:ACLineSegment.gch>0</cim:ACLineSegment.gch>
<cim:ACLineSegment.r>0.1</cim:ACLineSegment.r>
<cim:ACLineSegment.r0>0.1</cim:ACLineSegment.r0>
<cim:ACLineSegment.x>1</cim:ACLineSegment.x>
<cim:ACLineSegment.x0>0.1</cim:ACLineSegment.x0>
<cim:ConductingEquipment.BaseVoltage rdf:resource="#_BV"/>
<cim:Equipment.EquipmentContainer rdf:resource="#_LN"/>
</cim:ACLineSegment>
<cim:Terminal rdf:ID="_T_ACL_1">
<cim:IdentifiedObject.name>Terminal ACL 1</cim:IdentifiedObject.name>
<cim:ACDCTerminal.sequenceNumber>1</cim:ACDCTerminal.sequenceNumber>
<cim:Terminal.ConductingEquipment rdf:resource="#_ACL"/>
<cim:Terminal.ConnectivityNode rdf:resource="#_CN_1"/>
</cim:Terminal>
<cim:Terminal rdf:ID="_T_ACL_2">
<cim:IdentifiedObject.name>Terminal ACL 2</cim:IdentifiedObject.name>
<cim:ACDCTerminal.sequenceNumber>2</cim:ACDCTerminal.sequenceNumber>
<cim:Terminal.ConductingEquipment rdf:resource="#_ACL"/>
<cim:Terminal.ConnectivityNode rdf:resource="#_CN_2"/>
</cim:Terminal>
<cim:OperationalLimitSet rdf:ID="_OLS_ACL_1">
<cim:IdentifiedObject.name>Limit set</cim:IdentifiedObject.name>
<cim:OperationalLimitSet.Terminal rdf:resource="#_T_ACL_1"/>
</cim:OperationalLimitSet>
<cim:CurrentLimit rdf:ID="_I_PATL_1">
<cim:IdentifiedObject.name>Current limit</cim:IdentifiedObject.name>
<cim:CurrentLimit.normalValue>100</cim:CurrentLimit.normalValue>
<cim:OperationalLimit.OperationalLimitSet rdf:resource="#_OLS_ACL_1"/>
<cim:OperationalLimit.OperationalLimitType rdf:resource="#_PATL"/>
</cim:CurrentLimit>
<cim:CurrentLimit rdf:ID="_I_TATL_1">
<cim:IdentifiedObject.name>Current limit</cim:IdentifiedObject.name>
<cim:CurrentLimit.normalValue>200</cim:CurrentLimit.normalValue>
<cim:OperationalLimit.OperationalLimitSet rdf:resource="#_OLS_ACL_1"/>
<cim:OperationalLimit.OperationalLimitType rdf:resource="#_TATL_600"/>
</cim:CurrentLimit>
<cim:ActivePowerLimit rdf:ID="_P_PATL_1">
<cim:IdentifiedObject.name>Active power limit</cim:IdentifiedObject.name>
<cim:ActivePowerLimit.normalValue>101</cim:ActivePowerLimit.normalValue>
<cim:OperationalLimit.OperationalLimitSet rdf:resource="#_OLS_ACL_1"/>
<cim:OperationalLimit.OperationalLimitType rdf:resource="#_PATL"/>
</cim:ActivePowerLimit>
<cim:ActivePowerLimit rdf:ID="_P_TATL_1">
<cim:IdentifiedObject.name>Active power limit</cim:IdentifiedObject.name>
<cim:ActivePowerLimit.normalValue>201</cim:ActivePowerLimit.normalValue>
<cim:OperationalLimit.OperationalLimitSet rdf:resource="#_OLS_ACL_1"/>
<cim:OperationalLimit.OperationalLimitType rdf:resource="#_TATL_600"/>
</cim:ActivePowerLimit>
<cim:ApparentPowerLimit rdf:ID="_S_PATL_1">
<cim:IdentifiedObject.name>Apparent power limit</cim:IdentifiedObject.name>
<cim:ApparentPowerLimit.normalValue>102</cim:ApparentPowerLimit.normalValue>
<cim:OperationalLimit.OperationalLimitSet rdf:resource="#_OLS_ACL_1"/>
<cim:OperationalLimit.OperationalLimitType rdf:resource="#_PATL"/>
</cim:ApparentPowerLimit>
<cim:ApparentPowerLimit rdf:ID="_S_TATL_1">
<cim:IdentifiedObject.name>Apparent power limit</cim:IdentifiedObject.name>
<cim:ApparentPowerLimit.normalValue>202</cim:ApparentPowerLimit.normalValue>
<cim:OperationalLimit.OperationalLimitSet rdf:resource="#_OLS_ACL_1"/>
<cim:OperationalLimit.OperationalLimitType rdf:resource="#_TATL_600"/>
</cim:ApparentPowerLimit>
<cim:OperationalLimitType rdf:ID="_PATL">
<cim:OperationalLimitType.direction rdf:resource="http://iec.ch/TC57/CIM100#OperationalLimitDirectionKind.absoluteValue" />
<eu:OperationalLimitType.kind rdf:resource="http://iec.ch/TC57/CIM100-European#LimitKind.patl" />
<cim:IdentifiedObject.name>PATL</cim:IdentifiedObject.name>
</cim:OperationalLimitType>
<cim:OperationalLimitType rdf:ID="_TATL_600">
<cim:OperationalLimitType.direction rdf:resource="http://iec.ch/TC57/CIM100#OperationalLimitDirectionKind.absoluteValue" />
<eu:OperationalLimitType.kind rdf:resource="http://iec.ch/TC57/CIM100-European#LimitKind.tatl" />
<cim:IdentifiedObject.name>Tatl 600</cim:IdentifiedObject.name>
<cim:OperationalLimitType.acceptableDuration>600</cim:OperationalLimitType.acceptableDuration>
</cim:OperationalLimitType>
<cim:BaseVoltage rdf:ID="_BV">
<cim:IdentifiedObject.name>100 kV</cim:IdentifiedObject.name>
<cim:BaseVoltage.nominalVoltage>100</cim:BaseVoltage.nominalVoltage>
</cim:BaseVoltage>
</rdf:RDF>
21 changes: 11 additions & 10 deletions cgmes/cgmes-model/src/main/resources/CIM100.sparql
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,11 @@ SELECT *
WHERE {
{ GRAPH ?graph {
?OperationalLimit
cim:OperationalLimit.OperationalLimitType ?OperationalLimitType ;
cim:OperationalLimit.OperationalLimitSet ?OperationalLimitSet ;
a ?OperationalLimitSubclass ;
cim:IdentifiedObject.name ?name ;
a ?OperationalLimitSubclass .
?OperationalLimitType
a cim:OperationalLimitType ;
cim:IdentifiedObject.name ?operationalLimitTypeName .
cim:OperationalLimit.OperationalLimitSet ?OperationalLimitSet ;
cim:OperationalLimit.OperationalLimitType ?OperationalLimitType .
OPTIONAL { ?OperationalLimit eu:IdentifiedObject.shortName ?shortName }
OPTIONAL { ?OperationalLimit cim:CurrentLimit.normalValue ?normalValue }
OPTIONAL { ?OperationalLimit cim:ApparentPowerLimit.normalValue ?normalValue }
OPTIONAL { ?OperationalLimit cim:VoltageLimit.normalValue ?normalValue }
Expand All @@ -131,14 +129,17 @@ WHERE {
?OperationalLimitSet cim:OperationalLimitSet.Equipment ?Equipment .
?Equipment cim:Equipment.EquipmentContainer ?EquipmentContainer
}}
?OperationalLimitType
a cim:OperationalLimitType ;
cim:IdentifiedObject.name ?operationalLimitTypeName .
OPTIONAL { ?OperationalLimitType cim:OperationalLimitType.direction ?direction }
OPTIONAL { ?OperationalLimitType eu:OperationalLimitType.kind ?limitType }
OPTIONAL { ?OperationalLimitType cim:OperationalLimitType.acceptableDuration ?acceptableDuration }
}}
{ GRAPH ?graphSSH {
OPTIONAL {?OperationalLimit cim:CurrentLimit.value ?value }
OPTIONAL {?OperationalLimit cim:ApparentPowerLimit.value ?value }
OPTIONAL {?OperationalLimit cim:VoltageLimit.value ?value }
OPTIONAL { GRAPH ?graphSSH {
{ ?OperationalLimit cim:CurrentLimit.value ?value }
{ ?OperationalLimit cim:ApparentPowerLimit.value ?value }
{ ?OperationalLimit cim:VoltageLimit.value ?value }
}}
}

Expand Down

0 comments on commit c9bf10e

Please sign in to comment.