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

CgmesIidmMapping now strictly contains topological mapping and is optional for CGMES import and export #2037

Merged
merged 7 commits into from
Mar 29, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void export(Network network, Properties params, DataSource ds) {
String filenameTp = baseName + "_TP.xml";
String filenameSsh = baseName + "_SSH.xml";
String filenameSv = baseName + "_SV.xml";
CgmesExportContext context = new CgmesExportContext(network)
CgmesExportContext context = new CgmesExportContext(network, ConversionParameters.readBooleanParameter(getFormat(), params, WITH_TOPOLOGICAL_MAPPING_PARAMETER, defaultValueConfig))
.setExportBoundaryPowerFlows(ConversionParameters.readBooleanParameter(getFormat(), params, EXPORT_BOUNDARY_POWER_FLOWS_PARAMETER, defaultValueConfig))
.setExportFlowsForSwitches(ConversionParameters.readBooleanParameter(getFormat(), params, EXPORT_POWER_FLOWS_FOR_SWITCHES_PARAMETER, defaultValueConfig));
String cimVersionParam = ConversionParameters.readStringParameter(getFormat(), params, CIM_VERSION_PARAMETER, defaultValueConfig);
Expand Down Expand Up @@ -126,6 +126,7 @@ public String getFormat() {
public static final String EXPORT_BOUNDARY_POWER_FLOWS = "iidm.export.cgmes.export-boundary-power-flows";
public static final String EXPORT_POWER_FLOWS_FOR_SWITCHES = "iidm.export.cgmes.export-power-flows-for-switches";
public static final String PROFILES = "iidm.export.cgmes.profiles";
public static final String WITH_TOPOLOGICAL_MAPPING = "iidm.export.cgmes.with-topological-mapping";

private static final Parameter BASE_NAME_PARAMETER = new Parameter(
BASE_NAME,
Expand All @@ -152,11 +153,17 @@ public String getFormat() {
ParameterType.STRING_LIST,
"Profiles to export",
List.of("EQ", "TP", "SSH", "SV"));
private static final Parameter WITH_TOPOLOGICAL_MAPPING_PARAMETER = new Parameter(
WITH_TOPOLOGICAL_MAPPING,
ParameterType.BOOLEAN,
"Take topological mapping (CGMES-IIDM) of CgmesIidmMapping extension into account or create one for CGMES export",
Boolean.FALSE);

private static final List<Parameter> STATIC_PARAMETERS = List.of(
BASE_NAME_PARAMETER,
CIM_VERSION_PARAMETER,
EXPORT_BOUNDARY_POWER_FLOWS_PARAMETER,
EXPORT_POWER_FLOWS_FOR_SWITCHES_PARAMETER,
PROFILES_PARAMETER);
PROFILES_PARAMETER,
WITH_TOPOLOGICAL_MAPPING_PARAMETER);
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,11 @@ public Network convert() {
if (context.config().createCgmesExportMapping) {
CgmesIidmMappingAdder mappingAdder = network.newExtension(CgmesIidmMappingAdder.class);
cgmes.topologicalNodes().forEach(tn -> mappingAdder.addTopologicalNode(tn.getId("TopologicalNode"), tn.getId("name"), isBoundaryTopologicalNode(tn.getLocal("graphTP"))));
cgmes.baseVoltages().forEach(bv -> mappingAdder.addBaseVoltage(bv.getId("BaseVoltage"), bv.asDouble("nominalVoltage"), isBoundaryBaseVoltage(bv.getLocal("graph"))));
mappingAdder.add();
}
BaseVoltageMappingAdder bvAdder = network.newExtension(BaseVoltageMappingAdder.class);
cgmes.baseVoltages().forEach(bv -> bvAdder.addBaseVoltage(bv.getId("BaseVoltage"), bv.asDouble("nominalVoltage"), isBoundaryBaseVoltage(bv.getLocal("graph"))));
bvAdder.add();

Function<PropertyBag, AbstractObjectConversion> convf;

Expand Down Expand Up @@ -243,21 +245,20 @@ public Network convert() {
network.newExtension(CgmesConversionContextExtensionAdder.class).withContext(context).add();
}

CgmesIidmMapping mapping = network.getExtension(CgmesIidmMapping.class);
if (mapping != null) {
mapping.addTopologyListener();
if (config.createCgmesExportMapping) {
network.getExtension(CgmesIidmMapping.class).addTopologyListener();
}
return network;
}

private CgmesIidmMapping.Source isBoundaryTopologicalNode(String graph) {
private Source isBoundaryTopologicalNode(String graph) {
//There are unit tests where the boundary file contains the sequence "TPBD" and others "TP_BD"
return graph.contains("TP") && graph.contains("BD") ? CgmesIidmMapping.Source.BOUNDARY : CgmesIidmMapping.Source.IGM;
return graph.contains("TP") && graph.contains("BD") ? Source.BOUNDARY : Source.IGM;
}

private CgmesIidmMapping.Source isBoundaryBaseVoltage(String graph) {
private Source isBoundaryBaseVoltage(String graph) {
//There are unit tests where the boundary file contains the sequence "EQBD" and others "EQ_BD"
return graph.contains("EQ") && graph.contains("BD") ? CgmesIidmMapping.Source.BOUNDARY : CgmesIidmMapping.Source.IGM;
return graph.contains("EQ") && graph.contains("BD") ? Source.BOUNDARY : Source.IGM;
}

private static void completeVoltagesAndAngles(Network network) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class CgmesExportContext {
private final Map<String, Set<CgmesIidmMapping.CgmesTopologicalNode>> topologicalNodeByBusViewBusMapping = new HashMap<>();
private final Set<CgmesIidmMapping.CgmesTopologicalNode> unmappedTopologicalNodes = new HashSet<>();

private final Map<Double, CgmesIidmMapping.BaseVoltageSource> baseVoltageByNominalVoltageMapping = new HashMap<>();
private final Map<Double, BaseVoltageMapping.BaseVoltageSource> baseVoltageByNominalVoltageMapping = new HashMap<>();

public static final class ModelDescription {

Expand Down Expand Up @@ -113,7 +113,18 @@ public String getProfile() {
}
}

interface TopologicalConsumer {
void accept(String iidmId, String cgmesId, String cgmesName, Source source);
}

public CgmesExportContext() {
}

public CgmesExportContext(Network network) {
this(network, false);
}

public CgmesExportContext(Network network, boolean withTopologicalMapping) {
CimCharacteristics cimCharacteristics = network.getExtension(CimCharacteristics.class);
if (cimCharacteristics != null) {
cimVersion = cimCharacteristics.getCimVersion();
Expand All @@ -136,20 +147,33 @@ public CgmesExportContext(Network network) {
sshModelDescription.addDependencies(sshMetadata.getDependencies());
sshModelDescription.setModelingAuthoritySet(sshMetadata.getModelingAuthoritySet());
}
addIidmMappings(network);
addIidmMappings(network, withTopologicalMapping);
}

public void addIidmMappings(Network network) {
addIidmMappings(network, false);
}

public void addIidmMappings(Network network, boolean withTopologicalMapping) {
// For a merging view we plan to call CgmesExportContext() and then addIidmMappings(network) for every network
addIidmMappingsSubstations(network);
CgmesIidmMapping mapping = network.getExtension(CgmesIidmMapping.class);
if (mapping == null) {
network.newExtension(CgmesIidmMappingAdder.class).add();
mapping = network.getExtension(CgmesIidmMapping.class);
mapping.addTopologyListener();
if (withTopologicalMapping) {
CgmesIidmMapping mapping = network.getExtension(CgmesIidmMapping.class);
if (mapping == null) {
network.newExtension(CgmesIidmMappingAdder.class).add();
mapping = network.getExtension(CgmesIidmMapping.class);
mapping.addTopologyListener();
}
addIidmMappingsTopologicalNodes(mapping, network);
} else {
addIidmMappingsTopologicalNodes(network);
}
BaseVoltageMapping bvMapping = network.getExtension(BaseVoltageMapping.class);
if (bvMapping == null) {
network.newExtension(BaseVoltageMappingAdder.class).add();
bvMapping = network.getExtension(BaseVoltageMapping.class);
}
addIidmMappingsTopologicalNodes(mapping, network);
addIidmMappingsBaseVoltages(mapping, network);
addIidmMappingsBaseVoltages(bvMapping, network);
addIidmMappingsTerminals(network);
addIidmMappingsGenerators(network);
addIidmMappingsShuntCompensators(network);
Expand Down Expand Up @@ -199,15 +223,29 @@ private static void updateTopologicalNodesMapping(CgmesIidmMapping mapping, Netw
// We have to rely on the busView to obtain the calculated bus for every configured bus (getMergedBus)s
for (VoltageLevel vl : network.getVoltageLevels()) {
if (vl.getTopologyKind() == TopologyKind.BUS_BREAKER) {
updateBusBreakerTopologicalNodesMapping(mapping, vl);
computeBusBreakerTopologicalNodeMapping(vl, mapping::putTopologicalNode);
} else {
updateNodeBreakerTopologicalNodesMapping(mapping, vl);
computeNodeBreakerTopologicalNodesMapping(vl, mapping::putTopologicalNode);
}
}
}
}

private static void updateBusBreakerTopologicalNodesMapping(CgmesIidmMapping mapping, VoltageLevel vl) {
private void addIidmMappingsTopologicalNodes(Network network) {
for (VoltageLevel vl : network.getVoltageLevels()) {
if (vl.getTopologyKind() == TopologyKind.BUS_BREAKER) {
computeBusBreakerTopologicalNodeMapping(vl, (iidmId, cgmesId, cgmesName, source) -> topologicalNodeByBusViewBusMapping
.computeIfAbsent(iidmId, key -> new HashSet<>())
.add(new CgmesIidmMapping.CgmesTopologicalNode(cgmesId, cgmesName, source)));
} else {
computeNodeBreakerTopologicalNodesMapping(vl, (iidmId, cgmesId, cgmesName, source) -> topologicalNodeByBusViewBusMapping
.computeIfAbsent(iidmId, key -> new HashSet<>())
.add(new CgmesIidmMapping.CgmesTopologicalNode(cgmesId, cgmesName, source)));
}
}
}

private static void computeBusBreakerTopologicalNodeMapping(VoltageLevel vl, TopologicalConsumer addTnMapping) {
for (Bus configuredBus : vl.getBusBreakerView().getBuses()) {
Bus busViewBus;
String topologicalNode;
Expand All @@ -218,12 +256,12 @@ private static void updateBusBreakerTopologicalNodesMapping(CgmesIidmMapping map
busViewBus = vl.getBusView().getMergedBus(configuredBus.getId());
if (busViewBus != null && topologicalNode != null) {
String topologicalNodeName = configuredBus.getNameOrId();
mapping.putTopologicalNode(busViewBus.getId(), configuredBus.getId(), topologicalNodeName, CgmesIidmMapping.Source.IGM);
addTnMapping.accept(busViewBus.getId(), configuredBus.getId(), topologicalNodeName, Source.IGM);
}
}
}

private static void updateNodeBreakerTopologicalNodesMapping(CgmesIidmMapping mapping, VoltageLevel vl) {
private static void computeNodeBreakerTopologicalNodesMapping(VoltageLevel vl, TopologicalConsumer addTnMapping) {
for (int node : vl.getNodeBreakerView().getNodes()) {
Bus busViewBus;
String topologicalNode;
Expand All @@ -237,22 +275,22 @@ private static void updateNodeBreakerTopologicalNodesMapping(CgmesIidmMapping ma
busViewBus = terminal.getBusView().getBus();
if (topologicalNode != null && busViewBus != null) {
String topologicalNodeName = bus.getNameOrId();
mapping.putTopologicalNode(busViewBus.getId(), bus.getId(), topologicalNodeName, CgmesIidmMapping.Source.IGM);
addTnMapping.accept(busViewBus.getId(), bus.getId(), topologicalNodeName, Source.IGM);
}
}
}
}
}

private void addIidmMappingsBaseVoltages(CgmesIidmMapping mapping, Network network) {
private void addIidmMappingsBaseVoltages(BaseVoltageMapping mapping, Network network) {
if (mapping.isBaseVoltageEmpty()) {
for (VoltageLevel vl : network.getVoltageLevels()) {
double nominalV = vl.getNominalV();
String baseVoltageId = CgmesExportUtil.getUniqueId();
mapping.addBaseVoltage(nominalV, baseVoltageId, CgmesIidmMapping.Source.IGM);
mapping.addBaseVoltage(nominalV, baseVoltageId, Source.IGM);
}
}
Map<Double, CgmesIidmMapping.BaseVoltageSource> bvByNominalVoltage = mapping.baseVoltagesByNominalVoltageMap();
Map<Double, BaseVoltageMapping.BaseVoltageSource> bvByNominalVoltage = mapping.baseVoltagesByNominalVoltageMap();
baseVoltageByNominalVoltageMapping.putAll(bvByNominalVoltage);
}

Expand Down Expand Up @@ -468,9 +506,6 @@ private void addIidmMappingsControlArea(Network network) {
}
}

public CgmesExportContext() {
}

public int getCimVersion() {
return cimVersion;
}
Expand Down Expand Up @@ -548,7 +583,7 @@ public CgmesIidmMapping.CgmesTopologicalNode getUnmappedTopologicalNode(String t
return unmappedTopologicalNodes.stream().filter(cgmesTopologicalNode -> cgmesTopologicalNode.getCgmesId().equals(topologicalNodeId)).findAny().orElse(null);
}

public CgmesIidmMapping.BaseVoltageSource getBaseVoltageByNominalVoltage(double nominalV) {
public BaseVoltageMapping.BaseVoltageSource getBaseVoltageByNominalVoltage(double nominalV) {
return baseVoltageByNominalVoltageMapping.get(nominalV);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
import com.google.common.collect.HashBiMap;
import com.powsybl.cgmes.conversion.Conversion;
import com.powsybl.cgmes.conversion.export.elements.*;
import com.powsybl.cgmes.extensions.CgmesControlArea;
import com.powsybl.cgmes.extensions.CgmesControlAreas;
import com.powsybl.cgmes.extensions.CgmesIidmMapping;
import com.powsybl.cgmes.extensions.*;
import com.powsybl.cgmes.model.CgmesNames;
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.exceptions.UncheckedXmlStreamException;
Expand Down Expand Up @@ -219,18 +217,18 @@ private static void writeVoltageLevels(Network network, String cimNamespace, XML
Set<Double> exportedBaseVoltagesByNominalV = new HashSet<>();
for (VoltageLevel voltageLevel : network.getVoltageLevels()) {
double nominalV = voltageLevel.getNominalV();
CgmesIidmMapping.BaseVoltageSource baseVoltage = context.getBaseVoltageByNominalVoltage(nominalV);
if (!exportedBaseVoltagesByNominalV.contains(nominalV) && baseVoltage.getSource().equals(CgmesIidmMapping.Source.IGM)) {
BaseVoltageEq.write(baseVoltage.getCgmesId(), nominalV, cimNamespace, writer);
BaseVoltageMapping.BaseVoltageSource baseVoltage = context.getBaseVoltageByNominalVoltage(nominalV);
if (!exportedBaseVoltagesByNominalV.contains(nominalV) && baseVoltage.getSource().equals(Source.IGM)) {
BaseVoltageEq.write(baseVoltage.getId(), nominalV, cimNamespace, writer);
exportedBaseVoltagesByNominalV.add(nominalV);
}
VoltageLevelEq.write(voltageLevel.getId(), voltageLevel.getNameOrId(), voltageLevel.getLowVoltageLimit(), voltageLevel.getHighVoltageLimit(), voltageLevel.getNullableSubstation().getId(), baseVoltage.getCgmesId(), cimNamespace, writer);
VoltageLevelEq.write(voltageLevel.getId(), voltageLevel.getNameOrId(), voltageLevel.getLowVoltageLimit(), voltageLevel.getHighVoltageLimit(), voltageLevel.getNullableSubstation().getId(), baseVoltage.getId(), cimNamespace, writer);
}
}

private static void writeBusbarSections(Network network, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (BusbarSection bus : network.getBusbarSections()) {
BusbarSectionEq.write(bus.getId(), bus.getNameOrId(), bus.getTerminal().getVoltageLevel().getId(), context.getBaseVoltageByNominalVoltage(bus.getTerminal().getVoltageLevel().getNominalV()).getCgmesId(), cimNamespace, writer);
BusbarSectionEq.write(bus.getId(), bus.getNameOrId(), bus.getTerminal().getVoltageLevel().getId(), context.getBaseVoltageByNominalVoltage(bus.getTerminal().getVoltageLevel().getNominalV()).getId(), cimNamespace, writer);
}
}

Expand Down Expand Up @@ -481,12 +479,12 @@ private static String writeDanglingLineSubstation(DanglingLine danglingLine, Str

private static String writeDanglingLineBaseVoltage(DanglingLine danglingLine, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
double nominalV = danglingLine.getTerminal().getVoltageLevel().getNominalV();
CgmesIidmMapping.BaseVoltageSource baseVoltage = context.getBaseVoltageByNominalVoltage(nominalV);
if (baseVoltage.getSource().equals(CgmesIidmMapping.Source.IGM)) {
BaseVoltageEq.write(baseVoltage.getCgmesId(), nominalV, cimNamespace, writer);
BaseVoltageMapping.BaseVoltageSource baseVoltage = context.getBaseVoltageByNominalVoltage(nominalV);
if (baseVoltage.getSource().equals(Source.IGM)) {
BaseVoltageEq.write(baseVoltage.getId(), nominalV, cimNamespace, writer);
}

return baseVoltage.getCgmesId();
return baseVoltage.getId();
}

private static String writeDanglingLineVoltageLevel(DanglingLine danglingLine, String substationId, String baseVoltageId, String cimNamespace, XMLStreamWriter writer) throws XMLStreamException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import com.powsybl.cgmes.conversion.Conversion;
import com.powsybl.cgmes.extensions.CgmesIidmMapping;
import com.powsybl.cgmes.extensions.Source;
import com.powsybl.cgmes.model.CgmesNames;
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.exceptions.UncheckedXmlStreamException;
Expand Down Expand Up @@ -183,8 +184,8 @@ private static void writeTopologicalNodes(Network network, String cimNamespace,
private static void writeBusTopologicalNodes(Network network, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (Bus b : network.getBusView().getBuses()) {
for (CgmesIidmMapping.CgmesTopologicalNode topologicalNode : context.getTopologicalNodesByBusViewBus(b.getId())) {
if (topologicalNode.getSource().equals(CgmesIidmMapping.Source.IGM)) {
String baseVoltage = context.getBaseVoltageByNominalVoltage(b.getVoltageLevel().getNominalV()).getCgmesId();
if (topologicalNode.getSource().equals(Source.IGM)) {
String baseVoltage = context.getBaseVoltageByNominalVoltage(b.getVoltageLevel().getNominalV()).getId();
writeTopologicalNode(topologicalNode.getCgmesId(), topologicalNode.getName(), b.getVoltageLevel().getId(), baseVoltage, cimNamespace, writer);
}
}
Expand All @@ -196,8 +197,8 @@ private static void writeDanglingLineTopologicalNodes(Network network, String ci
Optional<String> topologicalNodeId = dl.getAliasFromType(Conversion.CGMES_PREFIX_ALIAS_PROPERTIES + CgmesNames.TOPOLOGICAL_NODE);
if (topologicalNodeId.isPresent()) {
CgmesIidmMapping.CgmesTopologicalNode cgmesTopologicalNode = context.getUnmappedTopologicalNode(topologicalNodeId.get());
if (cgmesTopologicalNode != null && cgmesTopologicalNode.getSource().equals(CgmesIidmMapping.Source.IGM)) {
String baseVoltage = context.getBaseVoltageByNominalVoltage(dl.getBoundary().getVoltageLevel().getNominalV()).getCgmesId();
if (cgmesTopologicalNode != null && cgmesTopologicalNode.getSource().equals(Source.IGM)) {
String baseVoltage = context.getBaseVoltageByNominalVoltage(dl.getBoundary().getVoltageLevel().getNominalV()).getId();
writeTopologicalNode(cgmesTopologicalNode.getCgmesId(), dl.getNameOrId(), dl.getBoundary().getVoltageLevel().getId(), baseVoltage, cimNamespace, writer);
}
}
Expand Down
Loading