Skip to content

Commit e11dac4

Browse files
authored
add shunt compensator modification (#263)
Signed-off-by: Seddik Yengui <[email protected]>
1 parent 843f4af commit e11dac4

File tree

10 files changed

+520
-0
lines changed

10 files changed

+520
-0
lines changed

src/main/java/org/gridsuite/modification/server/ModificationType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public enum ModificationType {
2525
SUBSTATION_CREATION,
2626
SUBSTATION_MODIFICATION,
2727
SHUNT_COMPENSATOR_CREATION,
28+
SHUNT_COMPENSATOR_MODIFICATION,
2829
VOLTAGE_LEVEL_CREATION,
2930
VOLTAGE_LEVEL_MODIFICATION,
3031
LINE_SPLIT_WITH_VOLTAGE_LEVEL,

src/main/java/org/gridsuite/modification/server/NetworkModificationException.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public enum Type {
4545
BUS_NOT_FOUND(HttpStatus.NOT_FOUND),
4646
CREATE_GENERATOR_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
4747
CREATE_SHUNT_COMPENSATOR_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
48+
MODIFY_SHUNT_COMPENSATOR_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
4849
DELETE_EQUIPMENT_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
4950
EQUIPMENT_NOT_FOUND(HttpStatus.NOT_FOUND),
5051
ATTRIBUTE_NOT_EDITABLE(HttpStatus.BAD_REQUEST),
@@ -63,6 +64,7 @@ public enum Type {
6364
BUSBAR_SECTION_NOT_DEFINED(HttpStatus.BAD_REQUEST),
6465
GENERATOR_ALREADY_EXISTS(HttpStatus.BAD_REQUEST),
6566
SHUNT_COMPENSATOR_ALREADY_EXISTS(HttpStatus.BAD_REQUEST),
67+
SHUNT_COMPENSATOR_NOT_FOUND(HttpStatus.NOT_FOUND),
6668
LINE_ALREADY_EXISTS(HttpStatus.BAD_REQUEST),
6769
TWO_WINDINGS_TRANSFORMER_ALREADY_EXISTS(HttpStatus.BAD_REQUEST),
6870
CONNECTION_POSITION_ERROR(HttpStatus.BAD_REQUEST),

src/main/java/org/gridsuite/modification/server/dto/ModificationInfos.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
@JsonSubTypes.Type(value = VoltageLevelCreationInfos.class, name = "VOLTAGE_LEVEL_CREATION"),
4545
@JsonSubTypes.Type(value = VoltageLevelModificationInfos.class, name = "VOLTAGE_LEVEL_MODIFICATION"),
4646
@JsonSubTypes.Type(value = ShuntCompensatorCreationInfos.class, name = "SHUNT_COMPENSATOR_CREATION"),
47+
@JsonSubTypes.Type(value = ShuntCompensatorModificationInfos.class, name = "SHUNT_COMPENSATOR_MODIFICATION"),
4748
@JsonSubTypes.Type(value = TwoWindingsTransformerCreationInfos.class, name = "TWO_WINDINGS_TRANSFORMER_CREATION"),
4849
@JsonSubTypes.Type(value = TwoWindingsTransformerModificationInfos.class, name = "TWO_WINDINGS_TRANSFORMER_MODIFICATION"),
4950
@JsonSubTypes.Type(value = EquipmentDeletionInfos.class, name = "EQUIPMENT_DELETION"),
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Copyright (c) 2023, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
8+
package org.gridsuite.modification.server.dto;
9+
10+
import com.fasterxml.jackson.annotation.JsonProperty;
11+
import com.powsybl.commons.reporter.Reporter;
12+
import com.powsybl.commons.reporter.ReporterModel;
13+
import io.swagger.v3.oas.annotations.media.Schema;
14+
import lombok.Getter;
15+
import lombok.NoArgsConstructor;
16+
import lombok.Setter;
17+
import lombok.ToString;
18+
import lombok.experimental.SuperBuilder;
19+
import org.gridsuite.modification.server.ModificationType;
20+
import org.gridsuite.modification.server.NetworkModificationException;
21+
import org.gridsuite.modification.server.entities.equipment.modification.ShuntCompensatorModificationEntity;
22+
import org.gridsuite.modification.server.modifications.AbstractModification;
23+
import org.gridsuite.modification.server.modifications.ShuntCompensatorModification;
24+
25+
/**
26+
* @author Seddik Yengui <Seddik.yengui at rte-france.com>
27+
*/
28+
29+
@SuperBuilder
30+
@NoArgsConstructor
31+
@Getter
32+
@Setter
33+
@ToString(callSuper = true)
34+
@Schema(description = "Shunt compensator modification")
35+
public class ShuntCompensatorModificationInfos extends BasicEquipmentModificationInfos {
36+
37+
@Schema(description = "voltage level id")
38+
private String voltageLevelId;
39+
40+
@Schema(description = "Susceptance per section")
41+
private AttributeModification<Double> susceptancePerSection;
42+
43+
@JsonProperty("qAtNominalV")
44+
@Schema(description = "Q at Nominal Voltage")
45+
private AttributeModification<Double> qAtNominalV;
46+
47+
@Schema(description = "Shunt Compensator Type")
48+
private AttributeModification<ShuntCompensatorType> shuntCompensatorType;
49+
50+
@Override
51+
public ShuntCompensatorModificationEntity toEntity() {
52+
return new ShuntCompensatorModificationEntity(this);
53+
}
54+
55+
@Override
56+
public AbstractModification toModification() {
57+
return new ShuntCompensatorModification(this);
58+
}
59+
60+
@Override
61+
public NetworkModificationException.Type getErrorType() {
62+
return NetworkModificationException.Type.MODIFY_SHUNT_COMPENSATOR_ERROR;
63+
}
64+
65+
@Override
66+
public Reporter createSubReporter(ReporterModel reporter) {
67+
return reporter.createSubReporter(ModificationType.SHUNT_COMPENSATOR_MODIFICATION.name(), "Modification of shunt compensator " + getEquipmentId());
68+
}
69+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/**
2+
* Copyright (c) 2023, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
8+
package org.gridsuite.modification.server.entities.equipment.modification;
9+
10+
import lombok.Getter;
11+
import lombok.NoArgsConstructor;
12+
import lombok.NonNull;
13+
import org.gridsuite.modification.server.dto.ModificationInfos;
14+
import org.gridsuite.modification.server.dto.ShuntCompensatorModificationInfos;
15+
import org.gridsuite.modification.server.dto.ShuntCompensatorType;
16+
import org.gridsuite.modification.server.entities.equipment.modification.attribute.DoubleModificationEmbedded;
17+
import org.gridsuite.modification.server.entities.equipment.modification.attribute.EnumModificationEmbedded;
18+
19+
import javax.persistence.AttributeOverride;
20+
import javax.persistence.AttributeOverrides;
21+
import javax.persistence.Column;
22+
import javax.persistence.Embedded;
23+
import javax.persistence.Entity;
24+
import javax.persistence.Table;
25+
26+
import static org.gridsuite.modification.server.dto.AttributeModification.toAttributeModification;
27+
28+
/**
29+
* @author Seddik Yengui <Seddik.yengui at rte-france.com>
30+
*/
31+
32+
@NoArgsConstructor
33+
@Getter
34+
@Entity
35+
@Table(name = "shuntCompensatorModification")
36+
public class ShuntCompensatorModificationEntity extends BasicEquipmentModificationEntity {
37+
@Column(name = "voltageLevelId")
38+
private String voltageLevelId;
39+
40+
@Embedded
41+
@AttributeOverrides(value = {
42+
@AttributeOverride(name = "value", column = @Column(name = "susceptancePerSection")),
43+
@AttributeOverride(name = "opType", column = @Column(name = "susceptancePerSectionOp"))
44+
})
45+
private DoubleModificationEmbedded susceptancePerSection;
46+
47+
@Embedded
48+
@AttributeOverrides(value = {
49+
@AttributeOverride(name = "value", column = @Column(name = "qAtNominalV")),
50+
@AttributeOverride(name = "opType", column = @Column(name = "qAtNominalVOp"))
51+
})
52+
private DoubleModificationEmbedded qAtNominalV;
53+
54+
@Embedded
55+
@AttributeOverrides(value = {
56+
@AttributeOverride(name = "value", column = @Column(name = "shuntCompensatorType")),
57+
@AttributeOverride(name = "opType", column = @Column(name = "shuntCompensatorTypeOp"))
58+
})
59+
private EnumModificationEmbedded<ShuntCompensatorType> shuntCompensatorType;
60+
61+
public ShuntCompensatorModificationEntity(ShuntCompensatorModificationInfos shuntCompensatorModificationInfos) {
62+
super(shuntCompensatorModificationInfos);
63+
assignAttributes(shuntCompensatorModificationInfos);
64+
}
65+
66+
@Override
67+
public void update(@NonNull ModificationInfos modificationInfos) {
68+
super.update(modificationInfos);
69+
assignAttributes((ShuntCompensatorModificationInfos) modificationInfos);
70+
}
71+
72+
private void assignAttributes(ShuntCompensatorModificationInfos shuntCompensatorModificationInfos) {
73+
this.voltageLevelId = shuntCompensatorModificationInfos.getVoltageLevelId();
74+
this.qAtNominalV = new DoubleModificationEmbedded(shuntCompensatorModificationInfos.getQAtNominalV());
75+
this.shuntCompensatorType = new EnumModificationEmbedded<>(shuntCompensatorModificationInfos.getShuntCompensatorType());
76+
this.susceptancePerSection = new DoubleModificationEmbedded(shuntCompensatorModificationInfos.getSusceptancePerSection());
77+
}
78+
79+
@Override
80+
public ShuntCompensatorModificationInfos toModificationInfos() {
81+
return toShuntCompensatorModificationInfosBuilder().build();
82+
}
83+
84+
private ShuntCompensatorModificationInfos.ShuntCompensatorModificationInfosBuilder<?, ?> toShuntCompensatorModificationInfosBuilder() {
85+
return ShuntCompensatorModificationInfos
86+
.builder()
87+
.uuid(getId())
88+
.date(getDate())
89+
.voltageLevelId(getVoltageLevelId())
90+
.equipmentId(getEquipmentId())
91+
.equipmentName(toAttributeModification(getEquipmentNameValue(), getEquipmentNameOp()))
92+
.shuntCompensatorType(toAttributeModification(getShuntCompensatorType()))
93+
.qAtNominalV(toAttributeModification(getQAtNominalV()))
94+
.susceptancePerSection(toAttributeModification(getSusceptancePerSection()));
95+
}
96+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* Copyright (c) 2023, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
8+
package org.gridsuite.modification.server.modifications;
9+
10+
import com.powsybl.commons.reporter.Report;
11+
import com.powsybl.commons.reporter.Reporter;
12+
import com.powsybl.commons.reporter.TypedValue;
13+
import com.powsybl.iidm.network.Network;
14+
import com.powsybl.iidm.network.ShuntCompensator;
15+
import com.powsybl.iidm.network.ShuntCompensatorLinearModel;
16+
import com.powsybl.iidm.network.ShuntCompensatorModelType;
17+
import com.powsybl.iidm.network.VoltageLevel;
18+
import org.gridsuite.modification.server.NetworkModificationException;
19+
import org.gridsuite.modification.server.dto.ShuntCompensatorModificationInfos;
20+
import org.gridsuite.modification.server.dto.ShuntCompensatorType;
21+
22+
import java.util.ArrayList;
23+
import java.util.List;
24+
25+
import static org.gridsuite.modification.server.NetworkModificationException.Type.SHUNT_COMPENSATOR_NOT_FOUND;
26+
import static org.gridsuite.modification.server.NetworkModificationException.Type.VOLTAGE_LEVEL_NOT_FOUND;
27+
28+
/**
29+
* @author Seddik Yengui <Seddik.yengui at rte-france.com>
30+
*/
31+
32+
public class ShuntCompensatorModification extends AbstractModification {
33+
private final ShuntCompensatorModificationInfos modificationInfos;
34+
35+
public ShuntCompensatorModification(ShuntCompensatorModificationInfos shuntCompensatorModificationInfos) {
36+
this.modificationInfos = shuntCompensatorModificationInfos;
37+
}
38+
39+
@Override
40+
public void apply(Network network, Reporter subReporter) {
41+
ShuntCompensator shuntCompensator = network.getShuntCompensator(modificationInfos.getEquipmentId());
42+
if (shuntCompensator == null) {
43+
throw new NetworkModificationException(SHUNT_COMPENSATOR_NOT_FOUND,
44+
String.format("Shunt compensator %s does not exist in network", modificationInfos.getEquipmentId()));
45+
}
46+
VoltageLevel voltageLevel = network.getVoltageLevel(modificationInfos.getVoltageLevelId());
47+
48+
if (voltageLevel == null) {
49+
throw new NetworkModificationException(VOLTAGE_LEVEL_NOT_FOUND,
50+
String.format("Voltage level %s does not exist in network", modificationInfos.getVoltageLevelId()));
51+
}
52+
53+
subReporter.report(Report.builder()
54+
.withKey("shuntCompensatorModification")
55+
.withDefaultMessage("Shunt Compensator with id=${id} modified :")
56+
.withValue("id", modificationInfos.getEquipmentId())
57+
.withSeverity(TypedValue.INFO_SEVERITY)
58+
.build());
59+
60+
ModificationUtils.getInstance().applyElementaryModifications(shuntCompensator::setName, () -> shuntCompensator.getOptionalName().orElse("No value"), modificationInfos.getEquipmentName(), subReporter, "Name");
61+
62+
if (shuntCompensator.getModelType() == ShuntCompensatorModelType.LINEAR) {
63+
applyModificationOnLinearModel(subReporter, shuntCompensator, voltageLevel);
64+
}
65+
66+
}
67+
68+
private void applyModificationOnLinearModel(Reporter subReporter, ShuntCompensator shuntCompensator, VoltageLevel voltageLevel) {
69+
List<Report> reports = new ArrayList<>();
70+
ShuntCompensatorLinearModel model = shuntCompensator.getModel(ShuntCompensatorLinearModel.class);
71+
var shuntCompensatorType = model.getBPerSection() > 0 ? ShuntCompensatorType.CAPACITOR : ShuntCompensatorType.REACTOR;
72+
73+
if (modificationInfos.getShuntCompensatorType() != null) {
74+
reports.add(ModificationUtils.getInstance().buildModificationReport(shuntCompensatorType, modificationInfos.getShuntCompensatorType().getValue(), "Type"));
75+
shuntCompensatorType = modificationInfos.getShuntCompensatorType().getValue();
76+
if (modificationInfos.getQAtNominalV() == null) {
77+
// we retrieve the absolute value of susceptance per section, then we determine the sign using the type
78+
double bPerSectionAbsoluteValue = Math.abs(model.getBPerSection());
79+
double newBPerSection = shuntCompensatorType == ShuntCompensatorType.CAPACITOR ? bPerSectionAbsoluteValue : -bPerSectionAbsoluteValue;
80+
model.setBPerSection(newBPerSection);
81+
}
82+
}
83+
84+
if (modificationInfos.getQAtNominalV() != null) {
85+
double olQAtNominalV = Math.abs(Math.pow(voltageLevel.getNominalV(), 2) * model.getBPerSection());
86+
double susceptancePerSection = modificationInfos.getQAtNominalV().getValue() / Math.pow(voltageLevel.getNominalV(), 2);
87+
88+
model.setBPerSection(shuntCompensatorType == ShuntCompensatorType.CAPACITOR ? susceptancePerSection : -susceptancePerSection);
89+
reports.add(ModificationUtils.getInstance().buildModificationReport(olQAtNominalV, modificationInfos.getQAtNominalV().getValue(), "Q at nominal voltage"));
90+
}
91+
reports.forEach(subReporter::report);
92+
ModificationUtils.getInstance().applyElementaryModifications(model::setBPerSection, model::getBPerSection, modificationInfos.getSusceptancePerSection(), subReporter, "Susceptance per section");
93+
}
94+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
2+
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-4.1.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
3+
<changeSet author="yenguised (generated)" id="1687174097961-5">
4+
<createTable tableName="shunt_compensator_modification">
5+
<column name="equipment_id" type="VARCHAR(255)"/>
6+
<column name="equipment_name_op" type="VARCHAR(255)"/>
7+
<column name="equipment_name_value" type="VARCHAR(255)"/>
8+
<column name="q_at_nominalvop" type="VARCHAR(255)"/>
9+
<column name="q_at_nominalv" type="FLOAT8"/>
10+
<column name="shunt_compensator_type_op" type="VARCHAR(255)"/>
11+
<column name="shunt_compensator_type" type="VARCHAR(255)"/>
12+
<column name="susceptance_per_section_op" type="VARCHAR(255)"/>
13+
<column name="susceptance_per_section" type="FLOAT8"/>
14+
<column name="voltage_level_id" type="VARCHAR(255)"/>
15+
<column name="id" type="UUID">
16+
<constraints nullable="false" primaryKey="true" primaryKeyName="shunt_compensator_modificationPK"/>
17+
</column>
18+
</createTable>
19+
</changeSet>
20+
<changeSet author="yenguised (generated)" id="1687174097961-6">
21+
<addForeignKeyConstraint baseColumnNames="id" baseTableName="shunt_compensator_modification" constraintName="FK4yslt3fbu775g44gyo65kok0k" deferrable="false" initiallyDeferred="false" referencedColumnNames="id" referencedTableName="modification" validate="true"/>
22+
</changeSet>
23+
</databaseChangeLog>

src/main/resources/db/changelog/db.changelog-master.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ databaseChangeLog:
147147
- include:
148148
file: changesets/changelog_20230529T102224Z.xml
149149
relativeToChangelogFile: true
150+
- include:
151+
file: changesets/changelog_20230619T112802Z.xml
152+
relativeToChangelogFile: true
150153
- include:
151154
file: changesets/changelog_20230620T132951Z.xml
152155
relativeToChangelogFile: true

0 commit comments

Comments
 (0)