Skip to content
Open
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 @@ -42,6 +42,7 @@
import static com.powsybl.cgmes.conversion.export.elements.LoadingLimitEq.loadingLimitClassName;
import static com.powsybl.cgmes.model.CgmesNames.DC_TERMINAL1;
import static com.powsybl.cgmes.model.CgmesNames.DC_TERMINAL2;
import static com.powsybl.cgmes.model.CgmesNames.NONCONFORM_LOAD;
import static com.powsybl.cgmes.model.CgmesNamespace.RDF_NAMESPACE;
import static com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part.*;
import static com.powsybl.cgmes.conversion.naming.CgmesObjectReference.ref;
Expand Down Expand Up @@ -93,6 +94,7 @@
writeVoltageLevels(network, cimNamespace, writer, context, exportedBaseVoltagesByNominalV);
writeBusbarSections(network, cimNamespace, writer, context);
writeLoads(network, loadGroups, cimNamespace, writer, context);
writeFictitiousInjections(network, loadGroups, mapNodeKey2NodeId, cimNamespace, writer, context);
String loadAreaId = writeLoadGroups(network, loadGroups.found(), cimNamespace, writer, context);
writeGenerators(network, mapTerminal2Id, regulatingControlsWritten, cimNamespace, writer, context);
writeBatteries(network, cimNamespace, writer, context);
Expand Down Expand Up @@ -281,6 +283,64 @@
return loadAreaId;
}

private static void writeFictitiousInjections(Network network, LoadGroups loadGroups, Map<String, String> mapNodeKey2NodeId,
String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (VoltageLevel vl : network.getVoltageLevels()) {
if (vl.getTopologyKind() == TopologyKind.NODE_BREAKER && !context.isBusBranchExport()) {
writeNodeBreakerFictitiousInjections(vl, loadGroups, mapNodeKey2NodeId, cimNamespace, writer, context);
} else {
writeBusBranchFictitiousInjections(vl, loadGroups, mapNodeKey2NodeId, cimNamespace, writer, context);
}
}
}

private static void writeNodeBreakerFictitiousInjections(VoltageLevel vl, LoadGroups loadGroups, Map<String, String> mapNodeKey2NodeId,
String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
VoltageLevel.NodeBreakerView nb = vl.getNodeBreakerView();
for (int node : nb.getNodes()) {
double p = nb.getFictitiousP0(node);
double q = nb.getFictitiousQ0(node);
if (p != 0.0 || q != 0.0) {
String loadId = context.getNamingStrategy().getCgmesId(refTyped(vl), FICTITIOUS, ref("NCL"), ref(node));
String loadName = vl.getNameOrId() + "_FICT_NCL_" + node;
String terminalId = context.getNamingStrategy().getCgmesId(refTyped(vl), FICTITIOUS, TERMINAL, ref(node));
String cnId = mapNodeKey2NodeId.get(buildNodeKey(vl, node));

writeFictitiousInjection(p, loadId, loadName, terminalId, cnId, vl, loadGroups, cimNamespace, writer, context);
}
}
}

private static void writeBusBranchFictitiousInjections(VoltageLevel vl, LoadGroups loadGroups, Map<String, String> mapNodeKey2NodeId,
String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (Bus b : vl.getBusBreakerView().getBuses()) {
double p = b.getFictitiousP0();
double q = b.getFictitiousQ0();
if (p != 0.0 || q != 0.0) {
String loadId = context.getNamingStrategy().getCgmesId(refTyped(b), FICTITIOUS, ref("NCL"));
String loadName = b.getNameOrId() + "_FICT_NCL";
String terminalId = context.getNamingStrategy().getCgmesId(refTyped(b), FICTITIOUS, TERMINAL);
String cnId = mapNodeKey2NodeId.get(buildNodeKey(b));

writeFictitiousInjection(p, loadId, loadName, terminalId, cnId, vl, loadGroups, cimNamespace, writer, context);
}
}
}

private static void writeFictitiousInjection(double p, String loadId, String loadName, String terminalId, String cnId,

Check warning on line 330 in cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/EquipmentExport.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Method has 10 parameters, which is greater than 7 authorized.

See more on https://sonarcloud.io/project/issues?id=com.powsybl%3Apowsybl-core&issues=AZpPinY4Eby0I46az_Eg&open=AZpPinY4Eby0I46az_Eg&pullRequest=3637
VoltageLevel vl, LoadGroups loadGroups, String cimNamespace,
XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
String equipmentContainerId = context.getNamingStrategy().getCgmesId(vl);
if (p <= 0) {
writeEnergySource(loadId, loadName, equipmentContainerId, cimNamespace, writer, context);
} else {
String loadGroup = loadGroups.groupFor(NONCONFORM_LOAD, context);
EnergyConsumerEq.write(NONCONFORM_LOAD, loadId, loadName, loadGroup, equipmentContainerId, null, cimNamespace, writer, context);
}

TerminalEq.write(terminalId, loadId, cnId, 1, cimNamespace, writer, context);
}

private static void writeLoads(Network network, LoadGroups loadGroups, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (Load load : network.getLoads()) {
if (context.isExportedEquipment(load)) {
Expand All @@ -290,7 +350,7 @@
case CgmesNames.ASYNCHRONOUS_MACHINE ->
writeAsynchronousMachine(loadId, load.getNameOrId(), cimNamespace, writer, context);
case CgmesNames.ENERGY_SOURCE -> writeEnergySource(loadId, load.getNameOrId(), context.getNamingStrategy().getCgmesId(load.getTerminal().getVoltageLevel()), cimNamespace, writer, context);
case CgmesNames.ENERGY_CONSUMER, CgmesNames.CONFORM_LOAD, CgmesNames.NONCONFORM_LOAD, CgmesNames.STATION_SUPPLY -> {
case CgmesNames.ENERGY_CONSUMER, CgmesNames.CONFORM_LOAD, NONCONFORM_LOAD, CgmesNames.STATION_SUPPLY -> {
String loadGroup = loadGroups.groupFor(className, context);
String loadResponseCharacteristicId = writeLoadResponseCharacteristic(load, cimNamespace, writer, context);
EnergyConsumerEq.write(className, loadId, load.getNameOrId(), loadGroup, context.getNamingStrategy().getCgmesId(load.getTerminal().getVoltageLevel()), loadResponseCharacteristicId, cimNamespace, writer, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import static com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part.TOPOLOGICAL_ISLAND;
import static com.powsybl.cgmes.conversion.naming.CgmesObjectReference.ref;
import static com.powsybl.cgmes.conversion.naming.CgmesObjectReference.refTyped;

/**
* @author Miora Ralambotiana {@literal <miora.ralambotiana at rte-france.com>}
Expand Down Expand Up @@ -271,9 +272,11 @@ boolean isInAccordanceWithKirchhoffsFirstLaw(Bus bus) {
}

boolean isInAccordance;
if (BusTools.hasAnyFinite(busViewBus, Terminal::getP) && BusTools.hasAnyFinite(busViewBus, Terminal::getQ)) {
double sumP = BusTools.sum(busViewBus, Terminal::getP);
double sumQ = BusTools.sum(busViewBus, Terminal::getQ);
if (bus.getFictitiousP0() != 0.0
|| bus.getFictitiousQ0() != 0.0
|| BusTools.hasAnyFinite(busViewBus, Terminal::getP) && BusTools.hasAnyFinite(busViewBus, Terminal::getQ)) {
double sumP = BusTools.sum(busViewBus, Terminal::getP) + bus.getFictitiousP0();
double sumQ = BusTools.sum(busViewBus, Terminal::getQ) + bus.getFictitiousQ0();
isInAccordance = Math.abs(sumP) <= maxPMismatchConverged && Math.abs(sumQ) <= maxQMismatchConverged;
if (!isInAccordance && LOG.isInfoEnabled()) {
LOG.info("Bus {} is not in accordance with Kirchhoff's first law. Mismatch = {}", bus, String.format("(%.4f, %.4f)", sumP, sumQ));
Expand Down Expand Up @@ -390,6 +393,9 @@ private static void writePowerFlows(Network network, String cimNamespace, XMLStr
}
}

// Write SvPowerFlow for synthetic fictitious injections exported as NonConformLoad
writeFictitiousInjectionsPowerFlows(network, cimNamespace, writer, context);

Map<String, Double> equivalentInjectionTerminalP = new HashMap<>();
Map<String, Double> equivalentInjectionTerminalQ = new HashMap<>();
network.getDanglingLines(DanglingLineFilter.ALL).forEach(dl -> {
Expand Down Expand Up @@ -418,6 +424,39 @@ private static void writePowerFlows(Network network, String cimNamespace, XMLStr
}
}

private static void writeFictitiousInjectionsPowerFlows(Network network, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) {
for (VoltageLevel vl : network.getVoltageLevels()) {
if (vl.getTopologyKind() == TopologyKind.NODE_BREAKER && !context.isBusBranchExport()) {
writeNodeBreakerFictitiousInjections(vl, cimNamespace, writer, context);
} else {
writeBusBranchFictitiousInjections(vl, cimNamespace, writer, context);
}
}
}

private static void writeNodeBreakerFictitiousInjections(VoltageLevel vl, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) {
VoltageLevel.NodeBreakerView nb = vl.getNodeBreakerView();
for (int node : nb.getNodes()) {
double p = nb.getFictitiousP0(node);
double q = nb.getFictitiousQ0(node);
if (p != 0.0 || q != 0.0) {
String terminalId = context.getNamingStrategy().getCgmesId(refTyped(vl), com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part.FICTITIOUS, com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part.TERMINAL, ref(node));
writePowerFlow(terminalId, p, q, cimNamespace, writer, context);
}
}
}

private static void writeBusBranchFictitiousInjections(VoltageLevel vl, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) {
for (Bus b : vl.getBusBreakerView().getBuses()) {
double p = b.getFictitiousP0();
double q = b.getFictitiousQ0();
if (p != 0.0 || q != 0.0) {
String terminalId = context.getNamingStrategy().getCgmesId(refTyped(b), com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part.FICTITIOUS, com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part.TERMINAL);
writePowerFlow(terminalId, p, q, cimNamespace, writer, context);
}
}
}

private static void writePowerFlowForSwitchesInVoltageLevel(VoltageLevel vl, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) {
SlackTerminal st = vl.getExtension(SlackTerminal.class);
Terminal slackTerminal = st != null ? st.getTerminal() : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public static void write(Network network, XMLStreamWriter writer, CgmesExportCon
}

writeLoads(network, cimNamespace, writer, context);
writeFictitiousInjections(network, cimNamespace, writer, context);
writeEquivalentInjections(network, cimNamespace, writer, context);
writeTapChangers(network, cimNamespace, regulatingControlViews, writer, context);
writeGenerators(network, cimNamespace, regulatingControlViews, writer, context);
Expand Down Expand Up @@ -171,6 +172,53 @@ private static void writeTerminals(Network network, String cimNamespace, XMLStre
}
}

private static void writeFictitiousInjections(Network network, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (VoltageLevel vl : network.getVoltageLevels()) {
if (vl.getTopologyKind() == TopologyKind.NODE_BREAKER && !context.isBusBranchExport()) {
writeNodeBreakerFictitiousInjections(vl, cimNamespace, writer, context);
} else {
writeBusBranchFictitiousInjections(vl, cimNamespace, writer, context);
}
}
}

private static void writeNodeBreakerFictitiousInjections(VoltageLevel vl, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
VoltageLevel.NodeBreakerView nb = vl.getNodeBreakerView();
for (int node : nb.getNodes()) {
double p = nb.getFictitiousP0(node);
double q = nb.getFictitiousQ0(node);
if (p != 0.0 || q != 0.0) {
String loadId = context.getNamingStrategy().getCgmesId(refTyped(vl), com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part.FICTITIOUS, ref("NCL"), ref(node));
String terminalId = context.getNamingStrategy().getCgmesId(refTyped(vl), com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part.FICTITIOUS, com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part.TERMINAL, ref(node));
writeFictitiousInjection(loadId, terminalId, p, q, cimNamespace, writer, context);
}
}
}

private static void writeBusBranchFictitiousInjections(VoltageLevel vl, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (Bus b : vl.getBusBreakerView().getBuses()) {
double p = b.getFictitiousP0();
double q = b.getFictitiousQ0();
if (p != 0.0 || q != 0.0) {
String loadId = context.getNamingStrategy().getCgmesId(refTyped(b), com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part.FICTITIOUS, ref("NCL"));
String terminalId = context.getNamingStrategy().getCgmesId(refTyped(b), com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part.FICTITIOUS, com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part.TERMINAL);
writeFictitiousInjection(loadId, terminalId, p, q, cimNamespace, writer, context);
}
}
}

private static void writeFictitiousInjection(String loadId, String terminalId, double p, double q,
String cimNamespace, XMLStreamWriter writer,
CgmesExportContext context) throws XMLStreamException {
if (p <= 0) {
writeEnergySource(loadId, p, q, cimNamespace, writer, context);
} else {
writeSshEnergyConsumer(loadId, CgmesNames.NONCONFORM_LOAD, p, q, cimNamespace, writer, context);
}
// Terminal connected state (always connected in SSH for fictitious terminals)
writeTerminal(terminalId, true, cimNamespace, writer, context);
}

private static void writeEquivalentInjections(Network network, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
// One equivalent injection for every dangling line
List<String> exported = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,53 @@ private static void writeTerminals(Network network, String cimNamespace, XMLStre
writeBoundaryTerminals(network, cimNamespace, writer, context);
writeSwitchesTerminals(network, cimNamespace, writer, context);
writeDcTerminals(network, cimNamespace, writer, context);
// Fictitious injections as NonConformLoad in Bus/Breaker topology: link terminals to TopologicalNode (bus)
writeFictitiousInjectionTerminals(network, cimNamespace, writer, context);
// Only if it is an updated export
if (!context.isExportEquipment()) {
writeBusbarSectionTerminalsFromBusBranchCgmesModel(network, cimNamespace, writer, context);
}
}

private static void writeFictitiousInjectionTerminals(Network network, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (VoltageLevel vl : network.getVoltageLevels()) {
if (vl.getTopologyKind() == TopologyKind.NODE_BREAKER && !context.isBusBranchExport()) {
writeNodeBreakerFictitiousTerminals(vl, cimNamespace, writer, context);
} else {
writeBusBranchFictitiousTerminals(vl, cimNamespace, writer, context);
}
}
}

private static void writeNodeBreakerFictitiousTerminals(VoltageLevel vl, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
VoltageLevel.NodeBreakerView nodeBreakerView = vl.getNodeBreakerView();

for (int node : nodeBreakerView.getNodes()) {
double p = nodeBreakerView.getFictitiousP0(node);
double q = nodeBreakerView.getFictitiousQ0(node);

if (p != 0.0 || q != 0.0) {
String terminalId = context.getNamingStrategy().getCgmesId(refTyped(vl), FICTITIOUS, TERMINAL, ref(node));
Bus bus = getBusForBusBreakerViewBus(vl, node);
String topologicalNodeId = context.getNamingStrategy().getCgmesId(bus);
writeTerminal(terminalId, topologicalNodeId, cimNamespace, writer, context);
}
}
}

private static void writeBusBranchFictitiousTerminals(VoltageLevel vl, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (Bus bus : vl.getBusBreakerView().getBuses()) {
double p = bus.getFictitiousP0();
double q = bus.getFictitiousQ0();

if (p != 0.0 || q != 0.0) {
String terminalId = context.getNamingStrategy().getCgmesId(refTyped(bus), FICTITIOUS, TERMINAL);
String topologicalNodeId = context.getNamingStrategy().getCgmesId(bus);
writeTerminal(terminalId, topologicalNodeId, cimNamespace, writer, context);
}
}
}

private static void writeBusbarSectionTerminalsFromBusBranchCgmesModel(Network network, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (Bus b : network.getBusBreakerView().getBuses()) {
String topologicalNodeId = context.getNamingStrategy().getCgmesId(b);
Expand Down
Loading
Loading