From b0c2d983f7996133eb5ef96c9fab623fcf4c6bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Marqu=C3=A9s?= Date: Thu, 21 Mar 2024 15:05:23 +0100 Subject: [PATCH 01/22] copy of the imported PSSE model to make the updates and export (deep copy) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- .../powsybl/psse/converter/BusConverter.java | 18 +++---- .../FixedShuntCompensatorConverter.java | 14 ++--- .../psse/converter/GeneratorConverter.java | 16 +++--- .../powsybl/psse/converter/LineConverter.java | 12 ++--- .../powsybl/psse/converter/LoadConverter.java | 16 +++--- .../powsybl/psse/converter/PsseExporter.java | 41 +++++---------- .../SwitchedShuntCompensatorConverter.java | 16 +++--- .../psse/converter/TransformerConverter.java | 52 +++++++++---------- .../psse/converter/PsseExporterTest.java | 46 ++++++++++++++++ .../com/powsybl/psse/model/pf/PsseBus.java | 18 +++++++ .../powsybl/psse/model/pf/PsseFixedShunt.java | 10 ++++ .../powsybl/psse/model/pf/PsseGenerator.java | 28 ++++++++++ .../com/powsybl/psse/model/pf/PsseLoad.java | 24 +++++++++ .../model/pf/PsseNonTransformerBranch.java | 21 ++++++++ .../psse/model/pf/PssePowerFlowModel.java | 33 ++++++++++++ .../com/powsybl/psse/model/pf/PsseRates.java | 20 +++++++ .../psse/model/pf/PsseSwitchedShunt.java | 42 +++++++++++++++ .../psse/model/pf/PsseTransformer.java | 43 +++++++++++++++ .../psse/model/pf/PsseTransformerWinding.java | 20 +++++++ 19 files changed, 377 insertions(+), 113 deletions(-) diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java index 7a1c4e65664..4308ce28a8b 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java @@ -6,7 +6,6 @@ */ package com.powsybl.psse.converter; -import java.util.Collections; import java.util.Objects; import com.powsybl.iidm.network.Bus; @@ -38,20 +37,17 @@ void create(VoltageLevel voltageLevel) { } // At the moment we do not consider new buses - static void updateBuses(Network network, PssePowerFlowModel psseModel, PssePowerFlowModel updatePsseModel) { + static void updateBuses(Network network, PssePowerFlowModel psseModel) { psseModel.getBuses().forEach(psseBus -> { - updatePsseModel.addBuses(Collections.singletonList(psseBus)); - PsseBus updatePsseBus = updatePsseModel.getBuses().get(updatePsseModel.getBuses().size() - 1); - - String busId = AbstractConverter.getBusId(updatePsseBus.getI()); + String busId = AbstractConverter.getBusId(psseBus.getI()); Bus bus = network.getBusBreakerView().getBus(busId); if (bus == null) { - updatePsseBus.setVm(0.0); - updatePsseBus.setVa(0.0); - updatePsseBus.setIde(4); + psseBus.setVm(0.0); + psseBus.setVa(0.0); + psseBus.setIde(4); } else { - updatePsseBus.setVm(bus.getV() / bus.getVoltageLevel().getNominalV()); - updatePsseBus.setVa(bus.getAngle()); + psseBus.setVm(bus.getV() / bus.getVoltageLevel().getNominalV()); + psseBus.setVa(bus.getAngle()); } }); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java index e6f196a2c2a..6bb3acba4f4 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java @@ -6,7 +6,6 @@ */ package com.powsybl.psse.converter; -import java.util.Collections; import java.util.Objects; import com.powsybl.iidm.network.*; @@ -61,18 +60,15 @@ private static String getShuntId(String busId, String fixedShuntId) { } // At the moment we do not consider new fixedShunts - static void updateFixedShunts(Network network, PssePowerFlowModel psseModel, PssePowerFlowModel updatePsseModel) { + static void updateFixedShunts(Network network, PssePowerFlowModel psseModel) { psseModel.getFixedShunts().forEach(psseFixedShunt -> { - updatePsseModel.addFixedShunts(Collections.singletonList(psseFixedShunt)); - PsseFixedShunt updatePsseFixedShunt = updatePsseModel.getFixedShunts().get(updatePsseModel.getFixedShunts().size() - 1); - - String fixedShuntId = getShuntId(getBusId(updatePsseFixedShunt.getI()), updatePsseFixedShunt.getId()); + String fixedShuntId = getShuntId(getBusId(psseFixedShunt.getI()), psseFixedShunt.getId()); ShuntCompensator fixedShunt = network.getShuntCompensator(fixedShuntId); if (fixedShunt == null) { - updatePsseFixedShunt.setStatus(0); + psseFixedShunt.setStatus(0); } else { - updatePsseFixedShunt.setStatus(getStatus(fixedShunt)); - updatePsseFixedShunt.setBl(getQ(fixedShunt)); + psseFixedShunt.setStatus(getStatus(fixedShunt)); + psseFixedShunt.setBl(getQ(fixedShunt)); } }); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java index fdcecb460a6..fd50b489c52 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java @@ -6,7 +6,6 @@ */ package com.powsybl.psse.converter; -import java.util.Collections; import java.util.Objects; import org.slf4j.Logger; @@ -120,19 +119,16 @@ private static String getGeneratorId(String busId, String generatorId) { } // At the moment we do not consider new generators - static void updateGenerators(Network network, PssePowerFlowModel psseModel, PssePowerFlowModel updatePsseModel) { + static void updateGenerators(Network network, PssePowerFlowModel psseModel) { psseModel.getGenerators().forEach(psseGen -> { - updatePsseModel.addGenerators(Collections.singletonList(psseGen)); - PsseGenerator updatePsseGen = updatePsseModel.getGenerators().get(updatePsseModel.getGenerators().size() - 1); - - String genId = getGeneratorId(getBusId(updatePsseGen.getI()), updatePsseGen.getId()); + String genId = getGeneratorId(getBusId(psseGen.getI()), psseGen.getId()); Generator gen = network.getGenerator(genId); if (gen == null) { - updatePsseGen.setStat(0); + psseGen.setStat(0); } else { - updatePsseGen.setStat(getStatus(gen)); - updatePsseGen.setPg(getP(gen)); - updatePsseGen.setQg(getQ(gen)); + psseGen.setStat(getStatus(gen)); + psseGen.setPg(getP(gen)); + psseGen.setQg(getQ(gen)); } }); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java index 7cd13263e96..b9a38cc12fa 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java @@ -23,7 +23,6 @@ import static com.powsybl.psse.model.PsseVersion.Major.V35; -import java.util.Collections; import java.util.Objects; /** @@ -118,17 +117,14 @@ private static String getLineId(PsseNonTransformerBranch psseLine) { } // At the moment we do not consider new lines and antenna lines are exported as open - static void updateLines(Network network, PssePowerFlowModel psseModel, PssePowerFlowModel updatePsseModel) { + static void updateLines(Network network, PssePowerFlowModel psseModel) { psseModel.getNonTransformerBranches().forEach(psseLine -> { - updatePsseModel.addNonTransformerBranches(Collections.singletonList(psseLine)); - PsseNonTransformerBranch updatePsseLine = updatePsseModel.getNonTransformerBranches().get(updatePsseModel.getNonTransformerBranches().size() - 1); - - String lineId = getLineId(updatePsseLine); + String lineId = getLineId(psseLine); Line line = network.getLine(lineId); if (line == null) { - updatePsseLine.setSt(0); + psseLine.setSt(0); } else { - updatePsseLine.setSt(getStatus(line)); + psseLine.setSt(getStatus(line)); } }); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java index f4ebf754670..1e8b476232e 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java @@ -6,7 +6,6 @@ */ package com.powsybl.psse.converter; -import java.util.Collections; import java.util.Objects; import com.powsybl.iidm.network.Load; @@ -92,19 +91,16 @@ private static String getLoadId(String busId, String loadId) { } // At the moment we do not consider new loads - static void updateLoads(Network network, PssePowerFlowModel psseModel, PssePowerFlowModel updatePsseModel) { + static void updateLoads(Network network, PssePowerFlowModel psseModel) { psseModel.getLoads().forEach(psseLoad -> { - updatePsseModel.addLoads(Collections.singletonList(psseLoad)); - PsseLoad updatePsseLoad = updatePsseModel.getLoads().get(updatePsseModel.getLoads().size() - 1); - - String loadId = getLoadId(getBusId(updatePsseLoad.getI()), updatePsseLoad.getId()); + String loadId = getLoadId(getBusId(psseLoad.getI()), psseLoad.getId()); Load load = network.getLoad(loadId); if (load == null) { - updatePsseLoad.setStatus(0); + psseLoad.setStatus(0); } else { - updatePsseLoad.setStatus(getStatus(load)); - updatePsseLoad.setPl(getP(load)); - updatePsseLoad.setQl(getQ(load)); + psseLoad.setStatus(getStatus(load)); + psseLoad.setPl(getP(load)); + psseLoad.setQl(getQ(load)); } }); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java index c33a1f6c5aa..4cead8d50ff 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java @@ -108,36 +108,23 @@ public void export(Network network, Properties parameters, DataSource dataSource } } + // New equipment is not supported + // Antennas (Branches connected only at one end) are exported as out of service (both sides open) private static PssePowerFlowModel createUpdatePsseModel(Network network, PssePowerFlowModel psseModel) { - PssePowerFlowModel updatePsseModel = new PssePowerFlowModel(psseModel.getCaseIdentification()); - - copyPermanentBlocks(psseModel, updatePsseModel); - updateModifiedBlocks(network, psseModel, updatePsseModel); - return updatePsseModel; + // Only the updated blocks are copied, non-updated blocks are referenced + PssePowerFlowModel referencedAndCopiedPsseModel = psseModel.referenceAndCopyPssePowerFlowModel(); + updateModifiedBlocks(network, referencedAndCopiedPsseModel); + return referencedAndCopiedPsseModel; } - private static void copyPermanentBlocks(PssePowerFlowModel psseModel, PssePowerFlowModel updatePsseModel) { - updatePsseModel.addAreas(psseModel.getAreas()); - updatePsseModel.addTwoTerminalDcTransmissionLines(psseModel.getTwoTerminalDcTransmissionLines()); - updatePsseModel.addVoltageSourceConverterDcTransmissionLines(psseModel.getVoltageSourceConverterDcTransmissionLines()); - updatePsseModel.addTransformerImpedanceCorrections(psseModel.getTransformerImpedanceCorrections()); - updatePsseModel.addMultiTerminalDcTransmissionLines(psseModel.getMultiTerminalDcTransmissionLines()); - updatePsseModel.addLineGrouping(psseModel.getLineGrouping()); - updatePsseModel.addZones(psseModel.getZones()); - updatePsseModel.addInterareaTransfer(psseModel.getInterareaTransfer()); - updatePsseModel.addOwners(psseModel.getOwners()); - updatePsseModel.addFacts(psseModel.getFacts()); - updatePsseModel.addGneDevice(psseModel.getGneDevice()); - updatePsseModel.addInductionMachines(psseModel.getInductionMachines()); - } + private static void updateModifiedBlocks(Network network, PssePowerFlowModel referencedAndCopiedPsseModel) { - private static void updateModifiedBlocks(Network network, PssePowerFlowModel psseModel, PssePowerFlowModel updatePsseModel) { - BusConverter.updateBuses(network, psseModel, updatePsseModel); - LoadConverter.updateLoads(network, psseModel, updatePsseModel); - FixedShuntCompensatorConverter.updateFixedShunts(network, psseModel, updatePsseModel); - GeneratorConverter.updateGenerators(network, psseModel, updatePsseModel); - LineConverter.updateLines(network, psseModel, updatePsseModel); - TransformerConverter.updateTransformers(network, psseModel, updatePsseModel); - SwitchedShuntCompensatorConverter.updateSwitchedShunts(network, psseModel, updatePsseModel); + BusConverter.updateBuses(network, referencedAndCopiedPsseModel); + LoadConverter.updateLoads(network, referencedAndCopiedPsseModel); + FixedShuntCompensatorConverter.updateFixedShunts(network, referencedAndCopiedPsseModel); + GeneratorConverter.updateGenerators(network, referencedAndCopiedPsseModel); + LineConverter.updateLines(network, referencedAndCopiedPsseModel); + TransformerConverter.updateTransformers(network, referencedAndCopiedPsseModel); + SwitchedShuntCompensatorConverter.updateSwitchedShunts(network, referencedAndCopiedPsseModel); } } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java index 70feee192f3..b9b823d7aba 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java @@ -7,7 +7,6 @@ package com.powsybl.psse.converter; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Objects; @@ -267,19 +266,16 @@ private static String getShuntId(String busId, String id) { } // At the moment we do not consider new switchedShunts - static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel, PssePowerFlowModel updatePsseModel) { - PsseVersion version = PsseVersion.fromRevision(updatePsseModel.getCaseIdentification().getRev()); + static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel) { + PsseVersion version = PsseVersion.fromRevision(psseModel.getCaseIdentification().getRev()); psseModel.getSwitchedShunts().forEach(psseSwitchedShunt -> { - updatePsseModel.addSwitchedShunts(Collections.singletonList(psseSwitchedShunt)); - PsseSwitchedShunt updatePsseSwitchedShunt = updatePsseModel.getSwitchedShunts().get(updatePsseModel.getSwitchedShunts().size() - 1); - - String switchedShuntId = getShuntId(getBusId(updatePsseSwitchedShunt.getI()), defineShuntId(updatePsseSwitchedShunt, version)); + String switchedShuntId = getShuntId(getBusId(psseSwitchedShunt.getI()), defineShuntId(psseSwitchedShunt, version)); ShuntCompensator switchedShunt = network.getShuntCompensator(switchedShuntId); if (switchedShunt == null) { - updatePsseSwitchedShunt.setStat(0); + psseSwitchedShunt.setStat(0); } else { - updatePsseSwitchedShunt.setStat(getStatus(switchedShunt)); - updatePsseSwitchedShunt.setBinit(getQ(switchedShunt)); + psseSwitchedShunt.setStat(getStatus(switchedShunt)); + psseSwitchedShunt.setBinit(getQ(switchedShunt)); } }); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java index 43db9ef1d17..cf444338052 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java @@ -7,7 +7,6 @@ package com.powsybl.psse.converter; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -839,31 +838,28 @@ private static String getTransformerId(int i, int j, int k, String ckt) { } // At the moment we do not consider new transformers and antenna twoWindingsTransformers are exported as open - static void updateTransformers(Network network, PssePowerFlowModel psseModel, PssePowerFlowModel updatePsseModel) { + static void updateTransformers(Network network, PssePowerFlowModel psseModel) { psseModel.getTransformers().forEach(psseTransformer -> { - updatePsseModel.addTransformers(Collections.singletonList(psseTransformer)); - PsseTransformer updatePsseTransformer = updatePsseModel.getTransformers().get(updatePsseModel.getTransformers().size() - 1); - - if (isTwoWindingsTransformer(updatePsseTransformer)) { - updateTwoWindingsTransformer(network, updatePsseTransformer); + if (isTwoWindingsTransformer(psseTransformer)) { + updateTwoWindingsTransformer(network, psseTransformer); } else { - updateThreeWindingsTransformer(network, updatePsseTransformer); + updateThreeWindingsTransformer(network, psseTransformer); } }); } - private static void updateTwoWindingsTransformer(Network network, PsseTransformer updatePsseTransformer) { - String transformerId = getTransformerId(updatePsseTransformer.getI(), updatePsseTransformer.getJ(), updatePsseTransformer.getCkt()); + private static void updateTwoWindingsTransformer(Network network, PsseTransformer psseTransformer) { + String transformerId = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); TwoWindingsTransformer tw2t = network.getTwoWindingsTransformer(transformerId); if (tw2t == null) { - updatePsseTransformer.setStat(0); + psseTransformer.setStat(0); } else { double baskv1 = tw2t.getTerminal1().getVoltageLevel().getNominalV(); - double nomV1 = getNomV(updatePsseTransformer.getWinding1(), tw2t.getTerminal1().getVoltageLevel()); - updatePsseTransformer.getWinding1().setWindv(defineWindV(getRatio(tw2t.getRatioTapChanger(), tw2t.getPhaseTapChanger()), baskv1, nomV1, updatePsseTransformer.getCw())); - updatePsseTransformer.getWinding1().setAng(getAngle(tw2t.getPhaseTapChanger())); + double nomV1 = getNomV(psseTransformer.getWinding1(), tw2t.getTerminal1().getVoltageLevel()); + psseTransformer.getWinding1().setWindv(defineWindV(getRatio(tw2t.getRatioTapChanger(), tw2t.getPhaseTapChanger()), baskv1, nomV1, psseTransformer.getCw())); + psseTransformer.getWinding1().setAng(getAngle(tw2t.getPhaseTapChanger())); - updatePsseTransformer.setStat(getStatus(tw2t)); + psseTransformer.setStat(getStatus(tw2t)); } } @@ -875,28 +871,28 @@ private static int getStatus(TwoWindingsTransformer tw2t) { } } - private static void updateThreeWindingsTransformer(Network network, PsseTransformer updatePsseTransformer) { - String transformerId = getTransformerId(updatePsseTransformer.getI(), updatePsseTransformer.getJ(), updatePsseTransformer.getK(), updatePsseTransformer.getCkt()); + private static void updateThreeWindingsTransformer(Network network, PsseTransformer psseTransformer) { + String transformerId = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt()); ThreeWindingsTransformer tw3t = network.getThreeWindingsTransformer(transformerId); if (tw3t == null) { - updatePsseTransformer.setStat(0); + psseTransformer.setStat(0); } else { double baskv1 = tw3t.getLeg1().getTerminal().getVoltageLevel().getNominalV(); - double nomV1 = getNomV(updatePsseTransformer.getWinding1(), tw3t.getLeg1().getTerminal().getVoltageLevel()); - updatePsseTransformer.getWinding1().setWindv(defineWindV(getRatio(tw3t.getLeg1().getRatioTapChanger(), tw3t.getLeg1().getPhaseTapChanger()), baskv1, nomV1, updatePsseTransformer.getCw())); - updatePsseTransformer.getWinding1().setAng(getAngle(tw3t.getLeg1().getPhaseTapChanger())); + double nomV1 = getNomV(psseTransformer.getWinding1(), tw3t.getLeg1().getTerminal().getVoltageLevel()); + psseTransformer.getWinding1().setWindv(defineWindV(getRatio(tw3t.getLeg1().getRatioTapChanger(), tw3t.getLeg1().getPhaseTapChanger()), baskv1, nomV1, psseTransformer.getCw())); + psseTransformer.getWinding1().setAng(getAngle(tw3t.getLeg1().getPhaseTapChanger())); double baskv2 = tw3t.getLeg2().getTerminal().getVoltageLevel().getNominalV(); - double nomV2 = getNomV(updatePsseTransformer.getWinding2(), tw3t.getLeg2().getTerminal().getVoltageLevel()); - updatePsseTransformer.getWinding2().setWindv(defineWindV(getRatio(tw3t.getLeg2().getRatioTapChanger(), tw3t.getLeg2().getPhaseTapChanger()), baskv2, nomV2, updatePsseTransformer.getCw())); - updatePsseTransformer.getWinding2().setAng(getAngle(tw3t.getLeg2().getPhaseTapChanger())); + double nomV2 = getNomV(psseTransformer.getWinding2(), tw3t.getLeg2().getTerminal().getVoltageLevel()); + psseTransformer.getWinding2().setWindv(defineWindV(getRatio(tw3t.getLeg2().getRatioTapChanger(), tw3t.getLeg2().getPhaseTapChanger()), baskv2, nomV2, psseTransformer.getCw())); + psseTransformer.getWinding2().setAng(getAngle(tw3t.getLeg2().getPhaseTapChanger())); double baskv3 = tw3t.getLeg3().getTerminal().getVoltageLevel().getNominalV(); - double nomV3 = getNomV(updatePsseTransformer.getWinding3(), tw3t.getLeg3().getTerminal().getVoltageLevel()); - updatePsseTransformer.getWinding3().setWindv(defineWindV(getRatio(tw3t.getLeg3().getRatioTapChanger(), tw3t.getLeg3().getPhaseTapChanger()), baskv3, nomV3, updatePsseTransformer.getCw())); - updatePsseTransformer.getWinding3().setAng(getAngle(tw3t.getLeg3().getPhaseTapChanger())); + double nomV3 = getNomV(psseTransformer.getWinding3(), tw3t.getLeg3().getTerminal().getVoltageLevel()); + psseTransformer.getWinding3().setWindv(defineWindV(getRatio(tw3t.getLeg3().getRatioTapChanger(), tw3t.getLeg3().getPhaseTapChanger()), baskv3, nomV3, psseTransformer.getCw())); + psseTransformer.getWinding3().setAng(getAngle(tw3t.getLeg3().getPhaseTapChanger())); - updatePsseTransformer.setStat(getStatus(tw3t)); + psseTransformer.setStat(getStatus(tw3t)); } } diff --git a/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseExporterTest.java b/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseExporterTest.java index ab098fd3178..b7e8561eed5 100644 --- a/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseExporterTest.java +++ b/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseExporterTest.java @@ -6,13 +6,21 @@ */ package com.powsybl.psse.converter; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ser.FilterProvider; +import com.fasterxml.jackson.databind.ser.PropertyWriter; +import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; +import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; import com.google.common.collect.ImmutableList; +import com.google.common.io.ByteStreams; import com.powsybl.commons.test.AbstractSerDeTest; import com.powsybl.commons.datasource.DataSource; import com.powsybl.commons.datasource.FileDataSource; import com.powsybl.commons.datasource.ReadOnlyDataSource; import com.powsybl.commons.datasource.ResourceDataSource; import com.powsybl.commons.datasource.ResourceSet; +import com.powsybl.commons.test.TestUtil; import com.powsybl.iidm.network.Generator; import com.powsybl.iidm.network.Line; import com.powsybl.iidm.network.Load; @@ -20,10 +28,20 @@ import com.powsybl.iidm.network.ShuntCompensator; import com.powsybl.iidm.network.TwoWindingsTransformer; import com.powsybl.iidm.network.impl.NetworkFactoryImpl; + +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; import java.time.ZonedDateTime; + +import com.powsybl.psse.converter.extensions.PsseModelExtension; +import com.powsybl.psse.model.PsseVersion; +import com.powsybl.psse.model.PsseVersioned; +import com.powsybl.psse.model.Revision; +import com.powsybl.psse.model.pf.PssePowerFlowModel; import org.junit.jupiter.api.Test; import static com.powsybl.commons.test.ComparisonUtils.compareTxt; +import static com.powsybl.psse.model.PsseVersion.fromRevision; import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.IOException; @@ -79,6 +97,11 @@ void importExportTest24() throws IOException { Network network = importTest("IEEE_24_bus", "IEEE_24_bus.raw", false); changeIEEE24BusNetwork(network); exportTest(network, "IEEE_24_bus_updated_exported", "IEEE_24_bus_updated_exported.raw"); + + // check that the psseModel associated with the network has not been changed + PssePowerFlowModel psseModel = network.getExtension(PsseModelExtension.class).getPsseModel(); + String jsonRef = loadJsonReference("IEEE_24_bus.json"); + assertEquals(jsonRef, toJsonString(psseModel)); } private static void changeIEEE24BusNetwork(Network network) { @@ -113,6 +136,29 @@ private static void changeIEEE24BusNetwork(Network network) { tw2t.getTerminal2().disconnect(); } + private static String toJsonString(PssePowerFlowModel rawData) throws JsonProcessingException { + PsseVersion version = fromRevision(rawData.getCaseIdentification().getRev()); + SimpleBeanPropertyFilter filter = new SimpleBeanPropertyFilter() { + @Override + protected boolean include(PropertyWriter writer) { + Revision rev = writer.getAnnotation(Revision.class); + return rev == null || PsseVersioned.isValidVersion(version, rev); + } + }; + FilterProvider filters = new SimpleFilterProvider().addFilter("PsseVersionFilter", filter); + String json = new ObjectMapper().writerWithDefaultPrettyPrinter().with(filters).writeValueAsString(rawData); + return TestUtil.normalizeLineSeparator(json); + } + + private String loadJsonReference(String fileName) { + try { + InputStream is = getClass().getResourceAsStream("/" + fileName); + return TestUtil.normalizeLineSeparator(new String(ByteStreams.toByteArray(is), StandardCharsets.UTF_8)); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + @Test void importExportTest30() throws IOException { Network network = importTest("IEEE_30_bus", "IEEE_30_bus.raw", false); diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseBus.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseBus.java index fd28d087c87..5f179ec76c1 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseBus.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseBus.java @@ -170,4 +170,22 @@ public void setEvlo(double evlo) { checkVersion("evlo"); this.evlo = evlo; } + + public PsseBus copy() { + PsseBus copy = new PsseBus(); + copy.i = this.i; + copy.name = this.name; + copy.baskv = this.baskv; + copy.ide = this.ide; + copy.area = this.area; + copy.zone = this.zone; + copy.owner = this.owner; + copy.vm = this.vm; + copy.va = this.va; + copy.nvhi = this.nvhi; + copy.nvlo = this.nvlo; + copy.evhi = this.evhi; + copy.evlo = this.evlo; + return copy; + } } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseFixedShunt.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseFixedShunt.java index d04a12bbd66..2eaee1c676f 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseFixedShunt.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseFixedShunt.java @@ -68,4 +68,14 @@ public double getBl() { public void setBl(double bl) { this.bl = bl; } + + public PsseFixedShunt copy() { + PsseFixedShunt copy = new PsseFixedShunt(); + copy.i = this.i; + copy.id = this.id; + copy.status = this.status; + copy.gl = this.gl; + copy.bl = this.bl; + return copy; + } } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseGenerator.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseGenerator.java index 0d08e622804..f6bb501d0bc 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseGenerator.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseGenerator.java @@ -274,4 +274,32 @@ public void setBaslod(int baslod) { public PsseOwnership getOwnership() { return ownership; } + + public PsseGenerator copy() { + PsseGenerator copy = new PsseGenerator(); + copy.i = this.i; + copy.id = this.id; + copy.pg = this.pg; + copy.qg = this.qg; + copy.qt = this.qt; + copy.qb = this.qb; + copy.vs = this.vs; + copy.ireg = this.ireg; + copy.mbase = this.mbase; + copy.zr = this.zr; + copy.zx = this.zx; + copy.rt = this.rt; + copy.xt = this.xt; + copy.gtap = this.gtap; + copy.stat = this.stat; + copy.rmpct = this.rmpct; + copy.pt = this.pt; + copy.pb = this.pb; + copy.ownership = this.ownership; + copy.wmod = this.wmod; + copy.wpf = this.wpf; + copy.nreg = this.nreg; + copy.baslod = this.baslod; + return copy; + } } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseLoad.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseLoad.java index d217e0f3f2c..b930f041ed0 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseLoad.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseLoad.java @@ -228,4 +228,28 @@ public void setLoadtype(String loadtype) { checkVersion("loadtype"); this.loadtype = loadtype; } + + public PsseLoad copy() { + PsseLoad copy = new PsseLoad(); + copy.i = this.i; + copy.id = this.id; + copy.status = this.status; + copy.area = this.area; + copy.zone = this.zone; + copy.owner = this.owner; + copy.pl = this.pl; + copy.ql = this.ql; + copy.ip = this.ip; + copy.iq = this.iq; + copy.yp = this.yp; + copy.yq = this.yq; + copy.owner = this.owner; + copy.scale = this.scale; + copy.intrpt = this.intrpt; + copy.dgenp = this.dgenp; + copy.dgenq = this.dgenq; + copy.dgenm = this.dgenm; + copy.loadtype = this.loadtype; + return copy; + } } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseNonTransformerBranch.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseNonTransformerBranch.java index 6093948e251..29e829c527e 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseNonTransformerBranch.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseNonTransformerBranch.java @@ -196,4 +196,25 @@ public PsseOwnership getOwnership() { public PsseRates getRates() { return rates; } + + public PsseNonTransformerBranch copy() { + PsseNonTransformerBranch copy = new PsseNonTransformerBranch(); + copy.i = this.i; + copy.j = this.j; + copy.ckt = this.ckt; + copy.r = this.r; + copy.x = this.x; + copy.b = this.b; + copy.rates = this.rates.copy(); + copy.gi = this.gi; + copy.bi = this.bi; + copy.gj = this.gj; + copy.bj = this.bj; + copy.st = this.st; + copy.met = this.met; + copy.len = this.len; + copy.ownership = this.ownership; + copy.name = this.name; + return copy; + } } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PssePowerFlowModel.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PssePowerFlowModel.java index 78b96314afc..e13be21e68e 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PssePowerFlowModel.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PssePowerFlowModel.java @@ -219,6 +219,39 @@ public List getInductionMachines() { return Collections.unmodifiableList(inductionMachines); } + public PssePowerFlowModel referenceAndCopyPssePowerFlowModel() { + PssePowerFlowModel newPsseModel = new PssePowerFlowModel(this.getCaseIdentification()); + referencePermanentBlocks(this, newPsseModel); + copyModifiedBlocks(this, newPsseModel); + return newPsseModel; + } + + private static void referencePermanentBlocks(PssePowerFlowModel psseModel, PssePowerFlowModel newPsseModel) { + newPsseModel.addAreas(psseModel.getAreas()); + newPsseModel.addTwoTerminalDcTransmissionLines(psseModel.getTwoTerminalDcTransmissionLines()); + newPsseModel.addVoltageSourceConverterDcTransmissionLines(psseModel.getVoltageSourceConverterDcTransmissionLines()); + newPsseModel.addTransformerImpedanceCorrections(psseModel.getTransformerImpedanceCorrections()); + newPsseModel.addMultiTerminalDcTransmissionLines(psseModel.getMultiTerminalDcTransmissionLines()); + newPsseModel.addLineGrouping(psseModel.getLineGrouping()); + newPsseModel.addZones(psseModel.getZones()); + newPsseModel.addInterareaTransfer(psseModel.getInterareaTransfer()); + newPsseModel.addOwners(psseModel.getOwners()); + newPsseModel.addFacts(psseModel.getFacts()); + newPsseModel.addGneDevice(psseModel.getGneDevice()); + newPsseModel.addInductionMachines(psseModel.getInductionMachines()); + } + + private static void copyModifiedBlocks(PssePowerFlowModel psseModel, PssePowerFlowModel newPsseModel) { + psseModel.getBuses().forEach(psseBus -> newPsseModel.buses.add(psseBus.copy())); + psseModel.getLoads().forEach(psseLoad -> newPsseModel.loads.add(psseLoad.copy())); + + psseModel.getFixedShunts().forEach(psseFixedShunt -> newPsseModel.fixedShunts.add(psseFixedShunt.copy())); + psseModel.getGenerators().forEach(psseGenerator -> newPsseModel.generators.add(psseGenerator.copy())); + psseModel.getNonTransformerBranches().forEach(nonTransformerBranch -> newPsseModel.nonTransformerBranches.add(nonTransformerBranch.copy())); + psseModel.getTransformers().forEach(psseTransformer -> newPsseModel.transformers.add(psseTransformer.copy())); + psseModel.getSwitchedShunts().forEach(psseSwitchedShunt -> newPsseModel.switchedShunts.add(psseSwitchedShunt.copy())); + } + private List modelled(List elements) { for (PsseVersioned v : elements) { v.setModel(this); diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseRates.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseRates.java index e6afcb8c932..2ca7b45b9b1 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseRates.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseRates.java @@ -238,4 +238,24 @@ public void setRate12(double rate12) { checkVersion("rate12"); this.rate12 = rate12; } + + public PsseRates copy() { + PsseRates copy = new PsseRates(); + copy.ratea = this.ratea; + copy.rateb = this.rateb; + copy.ratec = this.ratec; + copy.rate1 = this.rate1; + copy.rate2 = this.rate2; + copy.rate3 = this.rate3; + copy.rate4 = this.rate4; + copy.rate5 = this.rate5; + copy.rate6 = this.rate6; + copy.rate7 = this.rate7; + copy.rate8 = this.rate8; + copy.rate9 = this.rate9; + copy.rate10 = this.rate10; + copy.rate11 = this.rate11; + copy.rate12 = this.rate12; + return copy; + } } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSwitchedShunt.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSwitchedShunt.java index a46b2203d02..5046d27e065 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSwitchedShunt.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSwitchedShunt.java @@ -468,4 +468,46 @@ public int getS8() { public void setS8(int s8) { this.s8 = s8; } + + public PsseSwitchedShunt copy() { + PsseSwitchedShunt copy = new PsseSwitchedShunt(); + copy.i = this.i; + copy.modsw = this.modsw; + copy.adjm = this.adjm; + copy.stat = this.stat; + copy.vswhi = this.vswhi; + copy.vswlo = this.vswlo; + copy.swrem = this.swrem; + copy.rmpct = this.rmpct; + copy.rmidnt = this.rmidnt; + copy.binit = this.binit; + copy.n1 = this.n1; + copy.b1 = this.b1; + copy.n2 = this.n2; + copy.b2 = this.b2; + copy.n3 = this.n3; + copy.b3 = this.b3; + copy.n4 = this.n4; + copy.b4 = this.b4; + copy.n5 = this.n5; + copy.b5 = this.b5; + copy.n6 = this.n6; + copy.b6 = this.b6; + copy.n7 = this.n7; + copy.b7 = this.b7; + copy.n8 = this.n8; + copy.b8 = this.b8; + copy.id = this.id; + copy.swreg = this.swreg; + copy.nreg = this.nreg; + copy.s1 = this.s1; + copy.s2 = this.s2; + copy.s3 = this.s3; + copy.s4 = this.s4; + copy.s5 = this.s5; + copy.s6 = this.s6; + copy.s7 = this.s7; + copy.s8 = this.s8; + return copy; + } } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformer.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformer.java index d4abae2e6e1..da76f937139 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformer.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformer.java @@ -364,6 +364,33 @@ public void setImpedances(TransformerImpedances impedances) { this.impedances = impedances; } + public PsseTransformer copy() { + PsseTransformer copy = new PsseTransformer(); + copy.i = this.i; + copy.j = this.j; + copy.k = this.k; + copy.ckt = this.ckt; + copy.cw = this.cw; + copy.cz = this.cz; + copy.cm = this.cm; + copy.mag1 = this.mag1; + copy.mag2 = this.mag2; + copy.nmetr = this.nmetr; + copy.name = this.name; + copy.stat = this.stat; + copy.ownership = this.ownership; + copy.vecgrp = this.vecgrp; + copy.zcod = this.zcod; + copy.impedances = this.impedances.copy(); + copy.winding1 = this.winding1.copy(); + copy.winding1Rates = this.winding1Rates.copy(); + copy.winding2 = this.winding2.copy(); + copy.winding2Rates = this.winding2Rates.copy(); + copy.winding3 = this.winding3.copy(); + copy.winding3Rates = this.winding3Rates.copy(); + return copy; + } + public static class TransformerImpedances { @Parsed(field = {"r12", "r1_2"}) private double r12 = 0; @@ -405,5 +432,21 @@ public static class TransformerImpedances { @NullString(nulls = {"null"}) @Parsed private double anstar = 0; + + public TransformerImpedances copy() { + TransformerImpedances copy = new TransformerImpedances(); + copy.r12 = this.r12; + copy.x12 = this.x12; + copy.sbase12 = this.sbase12; + copy.r23 = this.r23; + copy.x23 = this.x23; + copy.sbase23 = this.sbase23; + copy.r31 = this.r31; + copy.x31 = this.x31; + copy.sbase31 = this.sbase31; + copy.vmstar = this.vmstar; + copy.anstar = this.anstar; + return copy; + } } } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformerWinding.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformerWinding.java index 7bf58b8afad..b646f75fc53 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformerWinding.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformerWinding.java @@ -145,4 +145,24 @@ public double getCx() { public double getCnxa() { return cnxa; } + + public PsseTransformerWinding copy() { + PsseTransformerWinding copy = new PsseTransformerWinding(); + copy.windv = this.windv; + copy.nomv = this.nomv; + copy.ang = this.ang; + copy.cod = this.cod; + copy.cont = this.cont; + copy.node = this.node; + copy.rma = this.rma; + copy.rmi = this.rmi; + copy.vma = this.vma; + copy.vmi = this.vmi; + copy.ntp = this.ntp; + copy.tab = this.tab; + copy.cr = this.cr; + copy.cx = this.cx; + copy.cnxa = this.cnxa; + return copy; + } } From 362d13fc16d0fb9acb2b519459d0243d468fc0e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Marqu=C3=A9s?= Date: Thu, 11 Apr 2024 10:07:47 +0200 Subject: [PATCH 02/22] Import and update substation data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- .../src/main/resources/IEEE_14_bus.json | 3 +- .../IEEE_14_bus_nodeBreaker_rev35.raw | 131 ++ .../src/main/resources/IEEE_24_bus.json | 3 +- .../model/io/RecordGroupIOLegacyText.java | 8 + .../psse/model/pf/PssePowerFlowModel.java | 11 + .../powsybl/psse/model/pf/PsseSubstation.java | 803 +++++++ .../psse/model/pf/io/PowerFlowRawData35.java | 5 +- .../psse/model/pf/io/PowerFlowRawxData35.java | 4 + .../model/pf/io/PowerFlowRecordGroup.java | 10 +- .../psse/model/pf/io/SubstationData.java | 329 +++ .../powsybl/psse/model/PsseRawDataTest.java | 50 + .../resources/IEEE_14_bus_Q_record_rev35.json | 3 +- .../test/resources/IEEE_14_bus_completed.json | 3 +- .../IEEE_14_bus_completed_rev35.json | 3 +- .../IEEE_14_bus_nodeBreaker_rev35.json | 1971 +++++++++++++++++ .../IEEE_14_bus_nodeBreaker_rev35.rawx | 193 ++ ...IEEE_14_bus_nodeBreaker_rev35_exported.raw | 131 ++ ...EEE_14_bus_nodeBreaker_rev35_exported.rawx | 156 ++ .../src/test/resources/IEEE_14_bus_rev35.json | 3 +- .../resources/IEEE_14_isolated_buses.json | 3 +- .../src/test/resources/IEEE_24_bus_rev35.json | 3 +- 21 files changed, 3814 insertions(+), 12 deletions(-) create mode 100644 psse/psse-model-test/src/main/resources/IEEE_14_bus_nodeBreaker_rev35.raw create mode 100644 psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java create mode 100644 psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java create mode 100644 psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.json create mode 100644 psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.rawx create mode 100644 psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw create mode 100644 psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.rawx diff --git a/psse/psse-model-test/src/main/resources/IEEE_14_bus.json b/psse/psse-model-test/src/main/resources/IEEE_14_bus.json index 25b1e4b1d90..1724dc8df07 100644 --- a/psse/psse-model-test/src/main/resources/IEEE_14_bus.json +++ b/psse/psse-model-test/src/main/resources/IEEE_14_bus.json @@ -1348,5 +1348,6 @@ "facts" : [ ], "switchedShunts" : [ ], "gneDevice" : [ ], - "inductionMachines" : [ ] + "inductionMachines" : [ ], + "substations" : [ ] } \ No newline at end of file diff --git a/psse/psse-model-test/src/main/resources/IEEE_14_bus_nodeBreaker_rev35.raw b/psse/psse-model-test/src/main/resources/IEEE_14_bus_nodeBreaker_rev35.raw new file mode 100644 index 00000000000..b05e6eab619 --- /dev/null +++ b/psse/psse-model-test/src/main/resources/IEEE_14_bus_nodeBreaker_rev35.raw @@ -0,0 +1,131 @@ + 0, 100.0, 35, 0, 0, 60.00 / October 01, 2013 18:37:53 + 08/19/93 UW ARCHIVE 100.0 1962 W IEEE 14 Bus Test Case + +0 / END OF SYSTEM-WIDE DATA, BEGIN BUS DATA + 1,'Bus 1 ', 138.0000,3, 1, 1, 1,1.06000, 0.0000 + 2,'Bus 2 ', 138.0000,2, 1, 1, 1,1.04500, -4.9826 + 3,'Bus 3 ', 138.0000,2, 1, 1, 1,1.01000, -12.7250 + 4,'Bus 4 ', 138.0000,1, 1, 1, 1,1.01767, -10.3128 + 5,'Bus 5 ', 138.0000,1, 1, 1, 1,1.01951, -8.7738 + 6,'Bus 6 ', 138.0000,2, 1, 1, 1,1.07000, -14.2209 + 7,'Bus 7 ', 138.0000,1, 1, 1, 1,1.06152, -13.3596 + 8,'Bus 8 ', 138.0000,2, 1, 1, 1,1.09000, -13.3596 + 9,'Bus 9 ', 138.0000,1, 1, 1, 1,1.05593, -14.9385 + 10,'Bus 10 ', 138.0000,1, 1, 1, 1,1.05099, -15.0972 + 11,'Bus 11 ', 138.0000,1, 1, 1, 1,1.05691, -14.7906 + 12,'Bus 12 ', 138.0000,1, 1, 1, 1,1.05519, -15.0755 + 13,'Bus 13 ', 138.0000,1, 1, 1, 1,1.05038, -15.1562 + 14,'Bus 14 ', 138.0000,1, 1, 1, 1,1.03553, -16.0336 +0 / END OF BUS DATA, BEGIN LOAD DATA + 2,'1 ',1, 1, 1, 21.700, 12.700, 0.000, 0.000, 0.000, -0.000, 1,1 + 3,'1 ',1, 1, 1, 94.200, 19.000, 0.000, 0.000, 0.000, -0.000, 1,1 + 4,'1 ',1, 1, 1, 47.800, -3.900, 0.000, 0.000, 0.000, -0.000, 1,1 + 5,'1 ',1, 1, 1, 7.600, 1.600, 0.000, 0.000, 0.000, -0.000, 1,1 + 6,'1 ',1, 1, 1, 11.200, 7.500, 0.000, 0.000, 0.000, -0.000, 1,1 + 9,'1 ',1, 1, 1, 29.500, 16.600, 0.000, 0.000, 0.000, -0.000, 1,1 + 10,'1 ',1, 1, 1, 9.000, 5.800, 0.000, 0.000, 0.000, -0.000, 1,1 + 11,'1 ',1, 1, 1, 3.500, 1.800, 0.000, 0.000, 0.000, -0.000, 1,1 + 12,'1 ',1, 1, 1, 6.100, 1.600, 0.000, 0.000, 0.000, -0.000, 1,1 + 13,'1 ',1, 1, 1, 13.500, 5.800, 0.000, 0.000, 0.000, -0.000, 1,1 + 14,'1 ',1, 1, 1, 14.900, 5.000, 0.000, 0.000, 0.000, -0.000, 1,1 +0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA + 9,' 1', 1, 0.000, 19.000 +0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA + 1,'1 ', 232.392, -16.549, 0.000, 0.000,1.06000, 0, 0, 615.000, 0.00000, 1.00000, 0.00000, 0.00000,1.00000,1, 100.0, 10000.000,-10000.000, 0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000,0, 1.0000 + 2,'1 ', 40.000, 43.556, 50.000, -40.000,1.04500, 0, 0, 60.000, 0.00000, 1.00000, 0.00000, 0.00000,1.00000,1, 100.0, 10000.000,-10000.000, 0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000,0, 1.0000 + 3,'1 ', 0.000, 25.075, 40.000, 0.000,1.01000, 0, 0, 60.000, 0.00000, 1.00000, 0.00000, 0.00000,1.00000,1, 100.0, 10000.000,-10000.000, 0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000,0, 1.0000 + 6,'1 ', 0.000, 12.730, 24.000, -6.000,1.07000, 0, 0, 25.000, 0.00000, 1.00000, 0.00000, 0.00000,1.00000,1, 100.0, 10000.000,-10000.000, 0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000,0, 1.0000 + 8,'1 ', 0.000, 17.623, 24.000, -6.000,1.09000, 0, 0, 25.000, 0.00000, 1.00000, 0.00000, 0.00000,1.00000,1, 100.0, 10000.000,-10000.000, 0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000,0, 1.0000 +0 / END OF GENERATOR DATA, BEGIN BRANCH DATA + 1, 2,'1 ', 0.01938, 0.05917,0.05280, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 1, 5,'1 ', 0.05403, 0.22304,0.04920, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 2, 3,'1 ', 0.04699, 0.19797,0.04380, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 2, 4,'1 ', 0.05811, 0.17632,0.03400, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 2, 5,'1 ', 0.05695, 0.17388,0.03460, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 3, 4,'1 ', 0.06701, 0.17103,0.01280, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 4, 5,'1 ', 0.01335, 0.04211,0.00000, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 6, 11,'1 ', 0.09498, 0.19890,0.00000, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 6, 12,'1 ', 0.12291, 0.25581,0.00000, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 6, 13,'1 ', 0.06615, 0.13027,0.00000, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 7, 8,'1 ', 0.00000, 0.17615,0.00000, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 7, 9,'1 ', 0.00000, 0.11001,0.00000, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 9, 10,'1 ', 0.03181, 0.08450,0.00000, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 9, 14,'1 ', 0.12711, 0.27038,0.00000, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 10, 11,'1 ', 0.08205, 0.19207,0.00000, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 12, 13,'1 ', 0.22092, 0.19988,0.00000, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 13, 14,'1 ', 0.17093, 0.34802,0.00000, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 +0 / END OF BRANCH DATA, BEGIN SYSTEM SWITCHING DEVICE DATA +0 / END OF SYSTEM SWITCHING DEVICE DATA, BEGIN TRANSFORMER DATA + 4, 7, 0,'1 ',1,1,1, 0.00000, 0.00000,2,' ',1, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 0.00000, 0.20912, 100.00 +0.97800, 0.000, 0.000, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,0, 0, 0, 1.50000, 0.51000, 1.50000, 0.51000,159, 0, 0.00000, 0.00000 +1.00000, 0.000 + 4, 9, 0,'1 ',1,1,1, 0.00000, 0.00000,2,' ',1, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 0.00000, 0.55618, 100.00 +0.96900, 0.000, 0.000, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,0, 0, 0, 1.50000, 0.51000, 1.50000, 0.51000,159, 0, 0.00000, 0.00000 +1.00000, 0.000 + 5, 6, 0,'1 ',1,1,1, 0.00000, 0.00000,2,' ',1, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 0.00000, 0.25202, 100.00 +0.93200, 0.000, 0.000, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,0, 0, 0, 1.50000, 0.51000, 1.50000, 0.51000,159, 0, 0.00000, 0.00000 +1.00000, 0.000 +0 / END OF TRANSFORMER DATA, BEGIN AREA DATA + 1, 2, 0.000, 999.990,'IEEE14 ' +0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA +0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA +0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA +0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA +0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA +0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA +0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA +0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA + 1,'1' +0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA +0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA +0 /END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA +0 /END OF GNE DEVICE DATA, BEGIN INDUCTION MACHINE DATA +0 /END OF INDUCTION MACHINE DATA, BEGIN SUBSTATION DATA + 1, 'STATION 1', 0.0, 0.0, 0.1 + / BEGIN SUBSTATION NODE DATA + 1, 'NB1', 1, 1, 1.0, 0.0 + 2, 'NB2', 1, 1, 1.0, 0.0 + 3, 'NL2', 1, 1, 1.0, 0.0 + 4, 'NL5', 1, 1, 1.0, 0.0 + 5, 'NG1', 1, 1, 1.0, 0.0 + 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA + 1, 2, '1 ', 'Sw-BusBars', 2, 1, 1, 0, 0, 0, 0 + 1, 3, '1 ', 'Sw-BranchToBus2', 2, 1, 1, 0, 0, 0, 0 + 2, 4, '1 ', 'Sw-BranchToBus5', 2, 1, 1, 0, 0, 0, 0 + 2, 5, '1 ', 'Sw-Gen1', 2, 1, 1, 0, 0, 0, 0 + 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION TERMINAL DATA + 1, 5, 'M', '1 ' + 1, 3, 'B', 2, '1 ' + 1, 4, 'B', 5, '1 ' + 0 / END OF SUBSTATION TERMINAL DATA + 2, 'STATION 5', 0.0, 0.0, 0.1 + / BEGIN SUBSTATION NODE DATA + 1, 'NB1', 2, 1, 1.0, 0.0 + 2, 'NB2', 2, 1, 1.0, 0.0 + 3, 'NL3', 2, 1, 1.0, 0.0 + 4, 'NL4', 2, 1, 1.0, 0.0 + 5, 'NL5', 2, 1, 1.0, 0.0 + 6, 'NL1', 2, 1, 1.0, 0.0 + 7, 'NG1', 2, 1, 1.0, 0.0 + 8, 'NLd1', 2, 1, 1.0, 0.0 + 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA + 1, 2, '1 ', 'Sw-BusBars', 2, 1, 1, 0, 0, 0, 0 + 1, 6, '1 ', 'Sw-BranchToBus1', 2, 1, 1, 0, 0, 0, 0 + 1, 7, '1 ', 'Sw-Gen1', 2, 1, 1, 0, 0, 0, 0 + 1, 8, '1 ', 'Sw-Load1', 2, 1, 1, 0, 0, 0, 0 + 2, 3, '1 ', 'Sw-BranchToBus3', 2, 1, 1, 0, 0, 0, 0 + 2, 4, '1 ', 'Sw-BranchToBus4', 2, 1, 1, 0, 0, 0, 0 + 2, 5, '1 ', 'Sw-BranchToBus5', 2, 1, 1, 0, 0, 0, 0 + 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION TERMINAL DATA + 2, 7, 'M', '1 ' + 2, 8, 'L', '1 ' + 2, 6, 'B', 1, '1 ' + 2, 3, 'B', 3, '1 ' + 2, 4, 'B', 4, '1 ' + 2, 5, 'B', 5, '1 ' + 0 / END OF SUBSTATION TERMINAL DATA +0 /END OF SUBSTATION DATA +Q diff --git a/psse/psse-model-test/src/main/resources/IEEE_24_bus.json b/psse/psse-model-test/src/main/resources/IEEE_24_bus.json index a57e4700cf9..3054262fe1a 100644 --- a/psse/psse-model-test/src/main/resources/IEEE_24_bus.json +++ b/psse/psse-model-test/src/main/resources/IEEE_24_bus.json @@ -2526,5 +2526,6 @@ "b8" : 0.0 } ], "gneDevice" : [ ], - "inductionMachines" : [ ] + "inductionMachines" : [ ], + "substations" : [ ] } \ No newline at end of file diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/io/RecordGroupIOLegacyText.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/io/RecordGroupIOLegacyText.java index 524dea028e5..fd70af4d8ff 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/io/RecordGroupIOLegacyText.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/io/RecordGroupIOLegacyText.java @@ -95,6 +95,14 @@ public static void writeEnd(String legacyTextName, OutputStream outputStream) { write(String.format("0 / END OF %s DATA", legacyTextName), outputStream); } + public static void writeComment(String comment, OutputStream outputStream) { + write(String.format(" / %s%n", comment), outputStream); + } + + public static void writeEndComment(String comment, OutputStream outputStream) { + write(String.format("0 / %s%n", comment), outputStream); + } + public static void writeQ(OutputStream outputStream) { write(String.format("%nQ%n"), outputStream); } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PssePowerFlowModel.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PssePowerFlowModel.java index e1398adf866..ceb17920567 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PssePowerFlowModel.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PssePowerFlowModel.java @@ -60,6 +60,8 @@ public class PssePowerFlowModel { private final List inductionMachines = new ArrayList<>(); + private final List substations = new ArrayList<>(); + public PssePowerFlowModel(PsseCaseIdentification caseIdentification) { this.caseIdentification = Objects.requireNonNull(caseIdentification); } @@ -220,6 +222,14 @@ public List getInductionMachines() { return Collections.unmodifiableList(inductionMachines); } + public void addSubstations(List substations) { + this.substations.addAll(substations); + } + + public List getSubstations() { + return Collections.unmodifiableList(substations); + } + public PssePowerFlowModel referenceAndCopyPssePowerFlowModel() { PssePowerFlowModel newPsseModel = new PssePowerFlowModel(this.getCaseIdentification()); referencePermanentBlocks(this, newPsseModel); @@ -243,6 +253,7 @@ private static void referencePermanentBlocks(PssePowerFlowModel psseModel, PsseP } private static void copyModifiedBlocks(PssePowerFlowModel psseModel, PssePowerFlowModel newPsseModel) { + psseModel.getSubstations().forEach(psseSubstation -> newPsseModel.substations.add(psseSubstation.copy())); psseModel.getBuses().forEach(psseBus -> newPsseModel.buses.add(psseBus.copy())); psseModel.getLoads().forEach(psseLoad -> newPsseModel.loads.add(psseLoad.copy())); diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java new file mode 100644 index 00000000000..c5992dac222 --- /dev/null +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java @@ -0,0 +1,803 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.psse.model.pf; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.univocity.parsers.annotations.Nested; +import com.univocity.parsers.annotations.NullString; +import com.univocity.parsers.annotations.Parsed; + +/** + * + * @author Luma Zamarreño {@literal } + * @author José Antonio Marqués {@literal } + */ + +@JsonIgnoreProperties({"record"}) +@JsonPropertyOrder({"is", "name", "lati", "long", "srg"}) + +public class PsseSubstation { + + public PsseSubstation(PsseSubstationRecord record, + List nodes, List switchingDevices, + List equipmentTerminals) { + this.record = record; + this.nodes = nodes; + this.switchingDevices = switchingDevices; + this.equipmentTerminals = equipmentTerminals; + } + + private final PsseSubstationRecord record; + private final List nodes; + private final List switchingDevices; + private final List equipmentTerminals; + + public int getIs() { + return record.is; + } + + public String getName() { + return record.name; + } + + public double getLati() { + return record.lati; + } + + public double getLong() { + return record.longi; + } + + public double getSrg() { + return record.srg; + } + + public PsseSubstationRecord getRecord() { + return record; + } + + public List getNodes() { + return nodes; + } + + public List getSwitchingDevices() { + return switchingDevices; + } + + public List getEquipmentTerminals() { + return equipmentTerminals; + } + + public PsseSubstation copy() { + PsseSubstationRecord copyRecord = this.record.copy(); + + List copyNodes = new ArrayList<>(); + this.nodes.forEach(node -> copyNodes.add(node.copy())); + + List copySwitchingDevices = new ArrayList<>(); + this.switchingDevices.forEach(switchingDevice -> copySwitchingDevices.add(switchingDevice.copy())); + + List copyEquipmentTerminals = new ArrayList<>(); + this.equipmentTerminals.forEach(equipmentTerminal -> copyEquipmentTerminals.add(equipmentTerminal.copy())); + + return new PsseSubstation(copyRecord, copyNodes, copySwitchingDevices, copyEquipmentTerminals); + } + + public static class PsseSubstationRecord { + @Parsed(field = {"is", "isub"}) + private int is; + @Parsed(defaultNullRead = " ") + private String name; + + @Parsed + private double lati = 0.0; + + @Parsed(field = {"long"}) + private double longi = 0.0; + + @Parsed + private double srg = 0.0; + + public int getIs() { + return is; + } + + public void setIs(int is) { + this.is = is; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getLati() { + return lati; + } + + public void setLati(double lati) { + this.lati = lati; + } + + public double getLong() { + return longi; + } + + public void setLong(double longi) { + this.longi = longi; + } + + public double getSrg() { + return srg; + } + + public void setSrg(double srg) { + this.srg = srg; + } + + public PsseSubstationRecord copy() { + PsseSubstationRecord copy = new PsseSubstationRecord(); + copy.is = this.is; + copy.name = this.name; + copy.lati = this.lati; + copy.longi = this.longi; + copy.srg = this.srg; + return copy; + } + } + + public static class PsseSubstationNode { + + @Parsed(field = {"ni", "inode"}) + private int ni; + + @Parsed(defaultNullRead = " ") + private String name; + + @Parsed(field = {"i", "ibus"}) + private int i; + + @Parsed(field = {"stat", "status"}) + private int status = 1; + + @Parsed + private double vm = 1.0; + + @Parsed + private double va = 0.0; + + public int getNi() { + return ni; + } + + public void setNi(int ni) { + this.ni = ni; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public double getVm() { + return vm; + } + + public void setVm(double vm) { + this.vm = vm; + } + + public double getVa() { + return va; + } + + public void setVa(double va) { + this.va = va; + } + + public PsseSubstationNode copy() { + PsseSubstationNode copy = new PsseSubstationNode(); + copy.ni = this.ni; + copy.name = this.name; + copy.i = this.i; + copy.status = this.status; + copy.vm = this.vm; + copy.va = this.va; + return copy; + } + } + + public static class PsseSubstationSwitchingDevice { + + @Parsed(field = {"ni", "inode"}) + private int ni; + + @Parsed(field = {"nj", "jnode"}) + private int nj = 0; + + @Parsed(field = {"ckt", "swdid"}, defaultNullRead = "1 ") + private String ckt; + + @Parsed(defaultNullRead = " ") + private String name; + + @Parsed + private int type = 1; + + @Parsed(field = {"status", "stat"}) + private int status = 1; + + @Parsed + private int nstat = 1; + + @Parsed(field = {"x", "xpu"}) + private double x = 0.0001; + + @Parsed + private double rate1 = 0.0; + + @Parsed + private double rate2 = 0.0; + + @Parsed + private double rate3 = 0.0; + + public int getNi() { + return ni; + } + + public void setNi(int ni) { + this.ni = ni; + } + + public int getNj() { + return nj; + } + + public void setNj(int nj) { + this.nj = nj; + } + + public String getCkt() { + return ckt; + } + + public void setCkt(String ckt) { + this.ckt = ckt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public int getNstat() { + return nstat; + } + + public void setNstat(int nstat) { + this.nstat = nstat; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getRate1() { + return rate1; + } + + public void setRate1(double rate1) { + this.rate1 = rate1; + } + + public double getRate2() { + return rate2; + } + + public void setRate2(double rate2) { + this.rate2 = rate2; + } + + public double getRate3() { + return rate3; + } + + public void setRate3(double rate3) { + this.rate3 = rate3; + } + + public PsseSubstationSwitchingDevice copy() { + PsseSubstationSwitchingDevice copy = new PsseSubstationSwitchingDevice(); + copy.ni = this.ni; + copy.nj = this.nj; + copy.ckt = this.ckt; + copy.name = this.name; + copy.type = this.type; + copy.status = this.status; + copy.nstat = this.nstat; + copy.x = this.x; + copy.rate1 = this.rate1; + copy.rate2 = this.rate2; + copy.rate3 = this.rate3; + return copy; + } + } + + public static class PsseSubstationEquipmentTerminal { + + @Parsed(field = {"i", "ibus"}) + private int i; + + @Parsed(field = {"ni", "inode"}) + private int ni; + + @Parsed + private String type; + + @Parsed(field = {"id", "eqid"}, defaultNullRead = "1 ") + private String id; + + @NullString(nulls = {"null"}) + @Parsed(field = {"j", "jbus"}) + private int j = 0; + + @NullString(nulls = {"null"}) + @Parsed(field = {"k", "kbus"}) + private int k = 0; + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getNi() { + return ni; + } + + public void setNi(int ni) { + this.ni = ni; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public PsseSubstationEquipmentTerminal copy() { + PsseSubstationEquipmentTerminal copy = new PsseSubstationEquipmentTerminal(); + copy.i = this.i; + copy.ni = this.ni; + copy.type = this.type; + copy.id = this.id; + copy.j = this.j; + copy.k = this.k; + return copy; + } + + public PsseSubstationEquipmentTerminalOneBus convertToEquipmentTerminalOneBus() { + PsseSubstationEquipmentTerminalOneBus oneBus = new PsseSubstationEquipmentTerminalOneBus(); + oneBus.i = i; + oneBus.ni = ni; + oneBus.type = type; + oneBus.id = id; + return oneBus; + } + + public PsseSubstationEquipmentTerminalTwoBuses convertToEquipmentTerminalTwoBuses() { + PsseSubstationEquipmentTerminalTwoBuses twoBuses = new PsseSubstationEquipmentTerminalTwoBuses(); + twoBuses.i = i; + twoBuses.ni = ni; + twoBuses.type = type; + twoBuses.id = id; + twoBuses.j = j; + return twoBuses; + } + + public PsseSubstationEquipmentTerminalThreeBuses convertToEquipmentTerminalThreeBuses() { + PsseSubstationEquipmentTerminalThreeBuses threeBuses = new PsseSubstationEquipmentTerminalThreeBuses(); + threeBuses.i = i; + threeBuses.ni = ni; + threeBuses.type = type; + threeBuses.id = id; + threeBuses.j = j; + threeBuses.k = k; + return threeBuses; + } + } + + public static class PsseSubstationEquipmentTerminalCommonStart { + + @Parsed + private int i; + + @Parsed + private int ni; + + @Parsed + private String type; + + public String getType() { + return type; + } + } + + public static class PsseSubstationEquipmentTerminalOneBus { + + @Parsed + private int i; + + @Parsed + private int ni; + + @Parsed + private String type; + + @Parsed(defaultNullRead = "1 ") + private String id; + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getNi() { + return ni; + } + + public void setNi(int ni) { + this.ni = ni; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public PsseSubstationEquipmentTerminal convertToEquipmentTerminal() { + PsseSubstationEquipmentTerminal equipmentTerminal = new PsseSubstationEquipmentTerminal(); + equipmentTerminal.i = i; + equipmentTerminal.ni = ni; + equipmentTerminal.type = type; + equipmentTerminal.id = id; + equipmentTerminal.j = 0; + equipmentTerminal.k = 0; + return equipmentTerminal; + } + } + + public static class PsseSubstationEquipmentTerminalTwoBuses { + + @Parsed + private int i; + + @Parsed + private int ni; + + @Parsed + private String type; + + @Parsed + private int j = 0; + + @Parsed(defaultNullRead = "1 ") + private String id; + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getNi() { + return ni; + } + + public void setNi(int ni) { + this.ni = ni; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public PsseSubstationEquipmentTerminal convertToEquipmentTerminal() { + PsseSubstationEquipmentTerminal equipmentTerminal = new PsseSubstationEquipmentTerminal(); + equipmentTerminal.i = i; + equipmentTerminal.ni = ni; + equipmentTerminal.type = type; + equipmentTerminal.id = id; + equipmentTerminal.j = j; + equipmentTerminal.k = 0; + return equipmentTerminal; + } + } + + public static class PsseSubstationEquipmentTerminalThreeBuses { + + @Parsed + private int i; + + @Parsed + private int ni; + + @Parsed + private String type; + + @Parsed + private int j = 0; + + @Parsed + private int k = 0; + + @Parsed(defaultNullRead = "1 ") + private String id; + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getNi() { + return ni; + } + + public void setNi(int ni) { + this.ni = ni; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public PsseSubstationEquipmentTerminal convertToEquipmentTerminal() { + PsseSubstationEquipmentTerminal equipmentTerminal = new PsseSubstationEquipmentTerminal(); + equipmentTerminal.i = i; + equipmentTerminal.ni = ni; + equipmentTerminal.type = type; + equipmentTerminal.id = id; + equipmentTerminal.j = j; + equipmentTerminal.k = k; + return equipmentTerminal; + } + } + + public static class PsseSubstationNodex { + + public PsseSubstationNodex() { + } + + public PsseSubstationNodex(int isub, PsseSubstationNode node) { + this.isub = isub; + this.node = node; + } + + @Parsed + private int isub; + @Nested + private PsseSubstationNode node; + + public int getIsub() { + return isub; + } + + public PsseSubstationNode getNode() { + return node; + } + } + + public static class PsseSubstationSwitchingDevicex { + + public PsseSubstationSwitchingDevicex() { + + } + + public PsseSubstationSwitchingDevicex(int isub, PsseSubstationSwitchingDevice switchingDevice) { + this.isub = isub; + this.switchingDevice = switchingDevice; + } + + @Parsed + private int isub; + @Nested + private PsseSubstationSwitchingDevice switchingDevice; + + public int getIsub() { + return isub; + } + + public PsseSubstationSwitchingDevice getSwitchingDevice() { + return switchingDevice; + } + } + + public static class PsseSubstationEquipmentTerminalx { + + public PsseSubstationEquipmentTerminalx() { + + } + + public PsseSubstationEquipmentTerminalx(int isub, PsseSubstationEquipmentTerminal equipmentTerminal) { + this.isub = isub; + this.equipmentTerminal = equipmentTerminal; + } + + @Parsed + private int isub; + @Nested + private PsseSubstationEquipmentTerminal equipmentTerminal; + + public int getIsub() { + return isub; + } + + public PsseSubstationEquipmentTerminal getEquipmentTerminal() { + return equipmentTerminal; + } + } + + public static boolean isOneBus(String type) { + return type.equals("L") || type.equals("F") || type.equals("M") + || type.equals("S") || type.equals("I") || type.equals("D") + || type.equals("V") || type.equals("N") || type.equals("A"); + } + + public static boolean isTwoBuses(String type) { + return type.equals("B") || type.equals("2"); + } + + public static boolean isThreeBuses(String type) { + return type.equals("3"); + } +} diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRawData35.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRawData35.java index 764d282756f..9a54a934446 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRawData35.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRawData35.java @@ -67,7 +67,8 @@ public PssePowerFlowModel read(ReadOnlyDataSource dataSource, String ext, Contex model.addSwitchedShunts(new SwitchedShuntData().read(reader, context)); model.addGneDevice(new GneDeviceData().read(reader, context)); model.addInductionMachines(new InductionMachineData().read(reader, context)); - reader.skip(SUBSTATION); + + model.addSubstations(new SubstationData().read(reader, context)); return model; } @@ -125,7 +126,7 @@ private void write(PssePowerFlowModel model, Context context, BufferedOutputStre new GneDeviceData().write(model.getGneDevice(), context, outputStream); new InductionMachineData().write(model.getInductionMachines(), context, outputStream); - writeEmpty(SUBSTATION, outputStream); + new SubstationData().write(model.getSubstations(), context, outputStream); writeQ(outputStream); } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRawxData35.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRawxData35.java index 24b35c358ed..a7f72389290 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRawxData35.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRawxData35.java @@ -72,6 +72,8 @@ private PssePowerFlowModel read(InputStream stream, Context context) throws IOEx model.addGneDevice(new GneDeviceData().read(null, context)); model.addInductionMachines(new InductionMachineData().read(null, context)); + model.addSubstations(new SubstationData().read(null, context)); + return model; } @@ -119,6 +121,8 @@ private void write(PssePowerFlowModel model, Context context, BufferedOutputStre new GneDeviceData().write(model.getGneDevice(), context, null); new InductionMachineData().write(model.getInductionMachines(), context, null); + new SubstationData().write(model.getSubstations(), context, null); + generator.writeEndObject(); // network generator.writeEndObject(); // root generator.flush(); diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRecordGroup.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRecordGroup.java index 6abd36abd8a..935ef89253b 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRecordGroup.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRecordGroup.java @@ -44,8 +44,14 @@ public enum PowerFlowRecordGroup implements RecordGroupIdentification { SWITCHED_SHUNT("swshunt", "SWITCHED SHUNT"), GNE_DEVICE("gne", "GNE DEVICE"), INDUCTION_MACHINE("indmach", "INDUCTION MACHINE"), - SUBSTATION("sub"); - + SUBSTATION("sub", "SUBSTATION"), + INTERNAL_SUBSTATION_NODE("subnode"), + INTERNAL_SUBSTATION_SWITCHING_DEVICE("subswd"), + INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL("subterm"), + INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_COMMON_START("subterm"), + INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_ONE_BUS("subterm"), + INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_TWO_BUSES("subterm"), + INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_THREE_BUSES("subterm"); private final String rawxNodeName; private final String rawName; diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java new file mode 100644 index 00000000000..eb9c0796456 --- /dev/null +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java @@ -0,0 +1,329 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.psse.model.pf.io; + +import com.powsybl.psse.model.PsseException; +import com.powsybl.psse.model.io.*; +import com.powsybl.psse.model.pf.PsseSubstation; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static com.powsybl.psse.model.pf.PsseSubstation.*; +import static com.powsybl.psse.model.pf.io.PowerFlowRecordGroup.*; + +/** + * + * @author Luma Zamarreño {@literal } + * @author José Antonio Marqués {@literal } + */ +class SubstationData extends AbstractRecordGroup { + + SubstationData() { + super(SUBSTATION); + withIO(FileFormat.LEGACY_TEXT, new IOLegacyText(this)); + withIO(FileFormat.JSON, new IOJson(this)); + } + + @Override + protected Class psseTypeClass() { + return PsseSubstation.class; + } + + private static class IOLegacyText extends RecordGroupIOLegacyText { + + IOLegacyText(AbstractRecordGroup recordGroup) { + super(recordGroup); + } + + @Override + public List read(LegacyTextReader reader, Context context) throws IOException { + + SubstationRecordData recordData = new SubstationRecordData(); + List substationList = new ArrayList<>(); + + if (!reader.isQRecordFound()) { + String line = reader.readRecordLine(); + while (!reader.endOfBlock(line)) { + PsseSubstationRecord record = recordData.readFromStrings(Collections.singletonList(line), context).get(0); + + List nodeList = new SubstationNodeData().read(reader, context); + List switchingDeviceList = new SubstationSwitchingDeviceData().read(reader, context); + List equipmentTerminalList = readEquipmentTerminalData(reader, context); + + PsseSubstation substation = new PsseSubstation(record, nodeList, switchingDeviceList, equipmentTerminalList); + substationList.add(substation); + + line = reader.readRecordLine(); + } + } + + return substationList; + } + + private List readEquipmentTerminalData(LegacyTextReader reader, Context context) throws IOException { + SubstationEquipmentTerminalDataCommonStart commonStartData = new SubstationEquipmentTerminalDataCommonStart(); + List equipmentTerminalOneBusRecords = new ArrayList<>(); + List equipmentTerminalTwoBusesRecords = new ArrayList<>(); + List equipmentTerminalThreeBusesRecords = new ArrayList<>(); + + String line = reader.readRecordLine(); + while (!reader.endOfBlock(line)) { + PsseSubstationEquipmentTerminalCommonStart commonStart = commonStartData.readFromStrings(Collections.singletonList(line), context).get(0); + if (isOneBus(commonStart.getType())) { + equipmentTerminalOneBusRecords.add(line); + } else if (isTwoBuses(commonStart.getType())) { + equipmentTerminalTwoBusesRecords.add(line); + } else if (isThreeBuses(commonStart.getType())) { + equipmentTerminalThreeBusesRecords.add(line); + } else { + throw new PsseException("Unexpected equipment terminal type: " + commonStart.getType()); + } + line = reader.readRecordLine(); + } + + List equipmentTerminalOneBusList = new SubstationEquipmentTerminalDataOneBus().readFromStrings(equipmentTerminalOneBusRecords, context); + List equipmentTerminalTwoBusesList = new SubstationEquipmentTerminalDataTwoBuses().readFromStrings(equipmentTerminalTwoBusesRecords, context); + List equipmentTerminalThreeBusesList = new SubstationEquipmentTerminalDataThreeBuses().readFromStrings(equipmentTerminalThreeBusesRecords, context); + + List equipmentTerminalList = equipmentTerminalOneBusList.stream().map(PsseSubstationEquipmentTerminalOneBus::convertToEquipmentTerminal).collect(Collectors.toList()); + equipmentTerminalList.addAll(equipmentTerminalTwoBusesList.stream().map(PsseSubstationEquipmentTerminalTwoBuses::convertToEquipmentTerminal).toList()); + equipmentTerminalList.addAll(equipmentTerminalThreeBusesList.stream().map(PsseSubstationEquipmentTerminalThreeBuses::convertToEquipmentTerminal).toList()); + + return equipmentTerminalList; + } + + @Override + public void write(List substationList, Context context, OutputStream outputStream) { + + writeBegin(outputStream); + + substationList.forEach(substation -> { + + SubstationRecordData recordData = new SubstationRecordData(); + write(recordData.buildRecords(Collections.singletonList(substation.getRecord()), context.getFieldNames(SUBSTATION), recordData.quotedFields(), context), outputStream); + + writeComment(" BEGIN SUBSTATION NODE DATA", outputStream); + + SubstationNodeData nodeData = new SubstationNodeData(); + write(nodeData.buildRecords(substation.getNodes(), context.getFieldNames(INTERNAL_SUBSTATION_NODE), nodeData.quotedFields(), context), outputStream); + writeEndComment(" END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA", outputStream); + + SubstationSwitchingDeviceData switchingDeviceData = new SubstationSwitchingDeviceData(); + write(switchingDeviceData.buildRecords(substation.getSwitchingDevices(), context.getFieldNames(INTERNAL_SUBSTATION_SWITCHING_DEVICE), nodeData.quotedFields(), context), outputStream); + writeEndComment(" END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA", outputStream); + + write(writeEquipmentTerminalData(substation.getEquipmentTerminals(), context), outputStream); + writeEndComment(" END OF SUBSTATION EQUIPMENT TERMINAL DATA", outputStream); + }); + + writeEnd(outputStream); + } + + private List writeEquipmentTerminalData(List equipmentTerminalList, Context context) { + + List eqOneBus = equipmentTerminalList.stream().filter(eq -> isOneBus(eq.getType())).map(PsseSubstationEquipmentTerminal::convertToEquipmentTerminalOneBus).collect(Collectors.toList()); + List eqTwoBuses = equipmentTerminalList.stream().filter(eq -> isTwoBuses(eq.getType())).map(PsseSubstationEquipmentTerminal::convertToEquipmentTerminalTwoBuses).collect(Collectors.toList()); + List eqThreeBuses = equipmentTerminalList.stream().filter(eq -> isThreeBuses(eq.getType())).map(PsseSubstationEquipmentTerminal::convertToEquipmentTerminalThreeBuses).collect(Collectors.toList()); + + SubstationEquipmentTerminalDataOneBus oneBusData = new SubstationEquipmentTerminalDataOneBus(); + List strings = oneBusData.buildRecords(eqOneBus, context.getFieldNames(INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_ONE_BUS), oneBusData.quotedFields(), context); + + SubstationEquipmentTerminalDataTwoBuses twoBusesData = new SubstationEquipmentTerminalDataTwoBuses(); + strings.addAll(twoBusesData.buildRecords(eqTwoBuses, context.getFieldNames(INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_TWO_BUSES), twoBusesData.quotedFields(), context)); + + SubstationEquipmentTerminalDataThreeBuses threeBusesData = new SubstationEquipmentTerminalDataThreeBuses(); + strings.addAll(threeBusesData.buildRecords(eqThreeBuses, context.getFieldNames(INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_THREE_BUSES), threeBusesData.quotedFields(), context)); + + return strings; + } + + private static class SubstationNodeData extends AbstractRecordGroup { + SubstationNodeData() { + super(INTERNAL_SUBSTATION_NODE, "ni", "name", "i", "status", "vm", "va"); + withQuotedFields(QUOTED_FIELDS); + } + + @Override + public Class psseTypeClass() { + return PsseSubstationNode.class; + } + } + + private static class SubstationSwitchingDeviceData extends AbstractRecordGroup { + SubstationSwitchingDeviceData() { + super(INTERNAL_SUBSTATION_SWITCHING_DEVICE, "ni", "nj", "ckt", "name", "type", "status", "nstat", "x", "rate1", "rate2", "rate3"); + withQuotedFields(QUOTED_FIELDS); + } + + @Override + public Class psseTypeClass() { + return PsseSubstationSwitchingDevice.class; + } + } + + private static class SubstationEquipmentTerminalDataCommonStart extends AbstractRecordGroup { + SubstationEquipmentTerminalDataCommonStart() { + super(INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_COMMON_START, "i", "ni", "type"); + withQuotedFields(QUOTED_FIELDS); + } + + @Override + public Class psseTypeClass() { + return PsseSubstationEquipmentTerminalCommonStart.class; + } + } + + private static class SubstationEquipmentTerminalDataOneBus extends AbstractRecordGroup { + SubstationEquipmentTerminalDataOneBus() { + super(INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_ONE_BUS, "i", "ni", "type", "id"); + withQuotedFields(QUOTED_FIELDS); + } + + @Override + public Class psseTypeClass() { + return PsseSubstationEquipmentTerminalOneBus.class; + } + } + + private static class SubstationEquipmentTerminalDataTwoBuses extends AbstractRecordGroup { + SubstationEquipmentTerminalDataTwoBuses() { + super(INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_TWO_BUSES, "i", "ni", "type", "j", "id"); + withQuotedFields(QUOTED_FIELDS); + } + + @Override + public Class psseTypeClass() { + return PsseSubstationEquipmentTerminalTwoBuses.class; + } + } + + private static class SubstationEquipmentTerminalDataThreeBuses extends AbstractRecordGroup { + SubstationEquipmentTerminalDataThreeBuses() { + super(INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_THREE_BUSES, "i", "ni", "type", "j", "k", "id"); + withQuotedFields(QUOTED_FIELDS); + } + + @Override + public Class psseTypeClass() { + return PsseSubstationEquipmentTerminalThreeBuses.class; + } + } + } + + private static class IOJson extends RecordGroupIOJson { + IOJson(AbstractRecordGroup recordGroup) { + super(recordGroup); + } + + @Override + public List read(LegacyTextReader reader, Context context) throws IOException { + if (reader != null) { + throw new PsseException("Unexpected reader. Should be null"); + } + List recordList = new SubstationRecordData().read(null, context); + List nodexList = new SubstationNodexData().read(null, context); + List switchingDevicexList = new SubstationSwitchingDevicexData().read(null, context); + List equipmentTerminalxList = new SubstationEquipmentTerminalxData().read(null, context); + return convertToSubstationList(recordList, nodexList, switchingDevicexList, equipmentTerminalxList); + } + + @Override + public void write(List substationList, Context context, OutputStream outputStream) { + if (outputStream != null) { + throw new PsseException("Unexpected outputStream. Should be null"); + } + List recordList = substationList.stream().map(PsseSubstation::getRecord).collect(Collectors.toList()); + new SubstationRecordData().write(recordList, context, null); + + List nodexList = new ArrayList<>(); + substationList.forEach(substation -> substation.getNodes().forEach(node -> nodexList.add( + new PsseSubstationNodex(substation.getRecord().getIs(), node)))); + new SubstationNodexData().write(nodexList, context, null); + + List switchingDevicexList = new ArrayList<>(); + substationList.forEach(substation -> substation.getSwitchingDevices().forEach(switchingDevice -> switchingDevicexList.add( + new PsseSubstationSwitchingDevicex(substation.getRecord().getIs(), switchingDevice)))); + new SubstationSwitchingDevicexData().write(switchingDevicexList, context, null); + + List equipmentTerminalxList = new ArrayList<>(); + substationList.forEach(substation -> substation.getEquipmentTerminals().forEach(equipmentTerminal -> equipmentTerminalxList.add( + new PsseSubstationEquipmentTerminalx(substation.getRecord().getIs(), equipmentTerminal)))); + new SubstationEquipmentTerminalxData().write(equipmentTerminalxList, context, null); + } + + private static List convertToSubstationList(List recordList, + List nodexList, List switchingDevicexList, + List equipmentTerminalxList) { + + List substationList = new ArrayList<>(); + for (PsseSubstationRecord record : recordList) { + List nodeList = nodexList.stream().filter(n -> n.getIsub() == record.getIs()).map(PsseSubstationNodex::getNode).collect(Collectors.toList()); + List switchingDeviceList = switchingDevicexList.stream().filter(sd -> sd.getIsub() == record.getIs()).map(PsseSubstationSwitchingDevicex::getSwitchingDevice).collect(Collectors.toList()); + List equipmentTerminalList = equipmentTerminalxList.stream().filter(eq -> eq.getIsub() == record.getIs()).map(PsseSubstationEquipmentTerminalx::getEquipmentTerminal).collect(Collectors.toList()); + + substationList.add(new PsseSubstation(record, nodeList, switchingDeviceList, equipmentTerminalList)); + } + return substationList; + } + + private static class SubstationNodexData extends AbstractRecordGroup { + SubstationNodexData() { + super(INTERNAL_SUBSTATION_NODE); + withQuotedFields(QUOTED_FIELDS); + } + + @Override + public Class psseTypeClass() { + return PsseSubstationNodex.class; + } + } + + private static class SubstationSwitchingDevicexData extends AbstractRecordGroup { + SubstationSwitchingDevicexData() { + super(INTERNAL_SUBSTATION_SWITCHING_DEVICE); + withQuotedFields(QUOTED_FIELDS); + } + + @Override + public Class psseTypeClass() { + return PsseSubstationSwitchingDevicex.class; + } + } + + private static class SubstationEquipmentTerminalxData extends AbstractRecordGroup { + SubstationEquipmentTerminalxData() { + super(INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL); + withQuotedFields(QUOTED_FIELDS); + } + + @Override + public Class psseTypeClass() { + return PsseSubstationEquipmentTerminalx.class; + } + } + } + + private static class SubstationRecordData extends AbstractRecordGroup { + SubstationRecordData() { + super(SUBSTATION, "is", "name", "lati", "long", "srg"); + withQuotedFields(QUOTED_FIELDS); + } + + @Override + public Class psseTypeClass() { + return PsseSubstationRecord.class; + } + } + + private static final String[] QUOTED_FIELDS = {"name", "type", "id", "ckt", "eqid"}; +} diff --git a/psse/psse-model/src/test/java/com/powsybl/psse/model/PsseRawDataTest.java b/psse/psse-model/src/test/java/com/powsybl/psse/model/PsseRawDataTest.java index f74693548ba..39840c4b02a 100644 --- a/psse/psse-model/src/test/java/com/powsybl/psse/model/PsseRawDataTest.java +++ b/psse/psse-model/src/test/java/com/powsybl/psse/model/PsseRawDataTest.java @@ -100,6 +100,14 @@ private ReadOnlyDataSource ieee14CompletedRawx35() { return new ResourceDataSource("IEEE_14_bus_completed_rev35", new ResourceSet("/", "IEEE_14_bus_completed_rev35.rawx")); } + private ReadOnlyDataSource ieee14NodeBreakerRaw35() { + return new ResourceDataSource("IEEE_14_bus_nodeBreaker_rev35", new ResourceSet("/", "IEEE_14_bus_nodeBreaker_rev35.raw")); + } + + private ReadOnlyDataSource ieee14NodeBreakerRawx35() { + return new ResourceDataSource("IEEE_14_bus_nodeBreaker_rev35", new ResourceSet("/", "IEEE_14_bus_nodeBreaker_rev35.rawx")); + } + private ReadOnlyDataSource ieee14InvalidRaw() { return new ResourceDataSource("IEEE_14_bus_invalid", new ResourceSet("/", "IEEE_14_bus_invalid.raw")); } @@ -695,6 +703,22 @@ void ieee14BusCompletedRev35RawxTest() throws IOException { assertEquals(expectedJson, toJson(rawData)); } + @Test + void ieee14BusNodeBreakerRev35Test() throws IOException { + String expectedJson = loadReference("/IEEE_14_bus_nodeBreaker_rev35.json"); + PssePowerFlowModel rawData = new PowerFlowRawData35().read(ieee14NodeBreakerRaw35(), "raw", new Context()); + assertNotNull(rawData); + assertEquals(expectedJson, toJson(rawData)); + } + + @Test + void ieee14BusNodeBreakerRev35RawxTest() throws IOException { + String expectedJson = loadReference("/IEEE_14_bus_nodeBreaker_rev35.json"); + PssePowerFlowModel rawData = new PowerFlowRawxData35().read(ieee14NodeBreakerRawx35(), "rawx", new Context()); + assertNotNull(rawData); + assertEquals(expectedJson, toJson(rawData)); + } + @Test void ieee14BusNonInductionMachineDataTest() throws IOException { String expectedJson = loadReference("/IEEE_14_bus.json"); @@ -758,6 +782,32 @@ void ieee14BusCompletedRev35RawxWriteTest() throws IOException { } } + @Test + void ieee14BusNodeBreakerRev35WriteTest() throws IOException { + Context context = new Context(); + PowerFlowRawData35 rawData35 = new PowerFlowRawData35(); + PssePowerFlowModel rawData = rawData35.read(ieee14NodeBreakerRaw35(), "raw", context); + assertNotNull(rawData); + + rawData35.write(rawData, context, new FileDataSource(fileSystem.getPath("/work/"), "IEEE_14_bus_nodeBreaker_rev35_exported")); + try (InputStream is = Files.newInputStream(fileSystem.getPath("/work/", "IEEE_14_bus_nodeBreaker_rev35_exported.raw"))) { + compareTxt(getClass().getResourceAsStream("/" + "IEEE_14_bus_nodeBreaker_rev35_exported.raw"), is); + } + } + + @Test + void ieee14BusNodeBreakerRev35RawxWriteTest() throws IOException { + Context context = new Context(); + PowerFlowRawxData35 rawxData35 = new PowerFlowRawxData35(); + PssePowerFlowModel rawData = rawxData35.read(ieee14NodeBreakerRawx35(), "rawx", context); + assertNotNull(rawData); + + rawxData35.write(rawData, context, new FileDataSource(fileSystem.getPath("/work/"), "IEEE_14_bus_nodeBreaker_rev35_exported")); + try (InputStream is = Files.newInputStream(fileSystem.getPath("/work/", "IEEE_14_bus_nodeBreaker_rev35_exported.rawx"))) { + compareTxt(getClass().getResourceAsStream("/" + "IEEE_14_bus_nodeBreaker_rev35_exported.rawx"), is); + } + } + @Test void invalidIeee14BusTest() throws IOException { Context context = new Context(); diff --git a/psse/psse-model/src/test/resources/IEEE_14_bus_Q_record_rev35.json b/psse/psse-model/src/test/resources/IEEE_14_bus_Q_record_rev35.json index 4d918533689..ba28f3d54ac 100644 --- a/psse/psse-model/src/test/resources/IEEE_14_bus_Q_record_rev35.json +++ b/psse/psse-model/src/test/resources/IEEE_14_bus_Q_record_rev35.json @@ -1665,5 +1665,6 @@ "facts" : [ ], "switchedShunts" : [ ], "gneDevice" : [ ], - "inductionMachines" : [ ] + "inductionMachines" : [ ], + "substations" : [ ] } \ No newline at end of file diff --git a/psse/psse-model/src/test/resources/IEEE_14_bus_completed.json b/psse/psse-model/src/test/resources/IEEE_14_bus_completed.json index 533387594b7..ae1f9824f40 100644 --- a/psse/psse-model/src/test/resources/IEEE_14_bus_completed.json +++ b/psse/psse-model/src/test/resources/IEEE_14_bus_completed.json @@ -1920,5 +1920,6 @@ "ia1" : 0.0, "ia2" : 0.0, "xamult" : 1.0 - } ] + } ], + "substations" : [ ] } \ No newline at end of file diff --git a/psse/psse-model/src/test/resources/IEEE_14_bus_completed_rev35.json b/psse/psse-model/src/test/resources/IEEE_14_bus_completed_rev35.json index d4fb7b755fc..303f6b2282a 100644 --- a/psse/psse-model/src/test/resources/IEEE_14_bus_completed_rev35.json +++ b/psse/psse-model/src/test/resources/IEEE_14_bus_completed_rev35.json @@ -2254,5 +2254,6 @@ "ia1" : 0.0, "ia2" : 0.0, "xamult" : 1.0 - } ] + } ], + "substations" : [ ] } \ No newline at end of file diff --git a/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.json b/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.json new file mode 100644 index 00000000000..f4f5a121ae5 --- /dev/null +++ b/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.json @@ -0,0 +1,1971 @@ +{ + "caseIdentification" : { + "ic" : 0, + "sbase" : 100.0, + "rev" : 35, + "xfrrat" : 0.0, + "nxfrat" : 0.0, + "basfrq" : 60.0, + "title1" : " 08/19/93 UW ARCHIVE 100.0 1962 W IEEE 14 Bus Test Case", + "title2" : "" + }, + "buses" : [ { + "i" : 1, + "name" : "Bus 1 ", + "baskv" : 138.0, + "ide" : 3, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.06, + "va" : 0.0, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 2, + "name" : "Bus 2 ", + "baskv" : 138.0, + "ide" : 2, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.045, + "va" : -4.9826, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 3, + "name" : "Bus 3 ", + "baskv" : 138.0, + "ide" : 2, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.01, + "va" : -12.725, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 4, + "name" : "Bus 4 ", + "baskv" : 138.0, + "ide" : 1, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.01767, + "va" : -10.3128, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 5, + "name" : "Bus 5 ", + "baskv" : 138.0, + "ide" : 1, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.01951, + "va" : -8.7738, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 6, + "name" : "Bus 6 ", + "baskv" : 138.0, + "ide" : 2, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.07, + "va" : -14.2209, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 7, + "name" : "Bus 7 ", + "baskv" : 138.0, + "ide" : 1, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.06152, + "va" : -13.3596, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 8, + "name" : "Bus 8 ", + "baskv" : 138.0, + "ide" : 2, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.09, + "va" : -13.3596, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 9, + "name" : "Bus 9 ", + "baskv" : 138.0, + "ide" : 1, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.05593, + "va" : -14.9385, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 10, + "name" : "Bus 10 ", + "baskv" : 138.0, + "ide" : 1, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.05099, + "va" : -15.0972, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 11, + "name" : "Bus 11 ", + "baskv" : 138.0, + "ide" : 1, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.05691, + "va" : -14.7906, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 12, + "name" : "Bus 12 ", + "baskv" : 138.0, + "ide" : 1, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.05519, + "va" : -15.0755, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 13, + "name" : "Bus 13 ", + "baskv" : 138.0, + "ide" : 1, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.05038, + "va" : -15.1562, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + }, { + "i" : 14, + "name" : "Bus 14 ", + "baskv" : 138.0, + "ide" : 1, + "area" : 1, + "zone" : 1, + "owner" : 1, + "vm" : 1.03553, + "va" : -16.0336, + "nvhi" : 1.1, + "nvlo" : 0.9, + "evhi" : 1.1, + "evlo" : 0.9 + } ], + "loads" : [ { + "i" : 2, + "id" : "1 ", + "status" : 1, + "area" : 1, + "zone" : 1, + "pl" : 21.7, + "ql" : 12.7, + "ip" : 0.0, + "iq" : 0.0, + "yp" : 0.0, + "yq" : -0.0, + "owner" : 1, + "scale" : 1, + "intrpt" : 0, + "dgenp" : 0.0, + "dgenq" : 0.0, + "dgenm" : 0.0, + "loadtype" : " " + }, { + "i" : 3, + "id" : "1 ", + "status" : 1, + "area" : 1, + "zone" : 1, + "pl" : 94.2, + "ql" : 19.0, + "ip" : 0.0, + "iq" : 0.0, + "yp" : 0.0, + "yq" : -0.0, + "owner" : 1, + "scale" : 1, + "intrpt" : 0, + "dgenp" : 0.0, + "dgenq" : 0.0, + "dgenm" : 0.0, + "loadtype" : " " + }, { + "i" : 4, + "id" : "1 ", + "status" : 1, + "area" : 1, + "zone" : 1, + "pl" : 47.8, + "ql" : -3.9, + "ip" : 0.0, + "iq" : 0.0, + "yp" : 0.0, + "yq" : -0.0, + "owner" : 1, + "scale" : 1, + "intrpt" : 0, + "dgenp" : 0.0, + "dgenq" : 0.0, + "dgenm" : 0.0, + "loadtype" : " " + }, { + "i" : 5, + "id" : "1 ", + "status" : 1, + "area" : 1, + "zone" : 1, + "pl" : 7.6, + "ql" : 1.6, + "ip" : 0.0, + "iq" : 0.0, + "yp" : 0.0, + "yq" : -0.0, + "owner" : 1, + "scale" : 1, + "intrpt" : 0, + "dgenp" : 0.0, + "dgenq" : 0.0, + "dgenm" : 0.0, + "loadtype" : " " + }, { + "i" : 6, + "id" : "1 ", + "status" : 1, + "area" : 1, + "zone" : 1, + "pl" : 11.2, + "ql" : 7.5, + "ip" : 0.0, + "iq" : 0.0, + "yp" : 0.0, + "yq" : -0.0, + "owner" : 1, + "scale" : 1, + "intrpt" : 0, + "dgenp" : 0.0, + "dgenq" : 0.0, + "dgenm" : 0.0, + "loadtype" : " " + }, { + "i" : 9, + "id" : "1 ", + "status" : 1, + "area" : 1, + "zone" : 1, + "pl" : 29.5, + "ql" : 16.6, + "ip" : 0.0, + "iq" : 0.0, + "yp" : 0.0, + "yq" : -0.0, + "owner" : 1, + "scale" : 1, + "intrpt" : 0, + "dgenp" : 0.0, + "dgenq" : 0.0, + "dgenm" : 0.0, + "loadtype" : " " + }, { + "i" : 10, + "id" : "1 ", + "status" : 1, + "area" : 1, + "zone" : 1, + "pl" : 9.0, + "ql" : 5.8, + "ip" : 0.0, + "iq" : 0.0, + "yp" : 0.0, + "yq" : -0.0, + "owner" : 1, + "scale" : 1, + "intrpt" : 0, + "dgenp" : 0.0, + "dgenq" : 0.0, + "dgenm" : 0.0, + "loadtype" : " " + }, { + "i" : 11, + "id" : "1 ", + "status" : 1, + "area" : 1, + "zone" : 1, + "pl" : 3.5, + "ql" : 1.8, + "ip" : 0.0, + "iq" : 0.0, + "yp" : 0.0, + "yq" : -0.0, + "owner" : 1, + "scale" : 1, + "intrpt" : 0, + "dgenp" : 0.0, + "dgenq" : 0.0, + "dgenm" : 0.0, + "loadtype" : " " + }, { + "i" : 12, + "id" : "1 ", + "status" : 1, + "area" : 1, + "zone" : 1, + "pl" : 6.1, + "ql" : 1.6, + "ip" : 0.0, + "iq" : 0.0, + "yp" : 0.0, + "yq" : -0.0, + "owner" : 1, + "scale" : 1, + "intrpt" : 0, + "dgenp" : 0.0, + "dgenq" : 0.0, + "dgenm" : 0.0, + "loadtype" : " " + }, { + "i" : 13, + "id" : "1 ", + "status" : 1, + "area" : 1, + "zone" : 1, + "pl" : 13.5, + "ql" : 5.8, + "ip" : 0.0, + "iq" : 0.0, + "yp" : 0.0, + "yq" : -0.0, + "owner" : 1, + "scale" : 1, + "intrpt" : 0, + "dgenp" : 0.0, + "dgenq" : 0.0, + "dgenm" : 0.0, + "loadtype" : " " + }, { + "i" : 14, + "id" : "1 ", + "status" : 1, + "area" : 1, + "zone" : 1, + "pl" : 14.9, + "ql" : 5.0, + "ip" : 0.0, + "iq" : 0.0, + "yp" : 0.0, + "yq" : -0.0, + "owner" : 1, + "scale" : 1, + "intrpt" : 0, + "dgenp" : 0.0, + "dgenq" : 0.0, + "dgenm" : 0.0, + "loadtype" : " " + } ], + "fixedShunts" : [ { + "i" : 9, + "id" : " 1", + "status" : 1, + "gl" : 0.0, + "bl" : 19.0 + } ], + "generators" : [ { + "i" : 1, + "id" : "1 ", + "pg" : 232.392, + "qg" : -16.549, + "qt" : 0.0, + "qb" : 0.0, + "vs" : 1.06, + "ireg" : 0, + "mbase" : 615.0, + "zr" : 0.0, + "zx" : 1.0, + "rt" : 0.0, + "xt" : 0.0, + "gtap" : 1.0, + "stat" : 1, + "rmpct" : 100.0, + "pt" : 10000.0, + "pb" : -10000.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "wmod" : 0, + "wpf" : 1.0, + "nreg" : 0, + "baslod" : 0 + }, { + "i" : 2, + "id" : "1 ", + "pg" : 40.0, + "qg" : 43.556, + "qt" : 50.0, + "qb" : -40.0, + "vs" : 1.045, + "ireg" : 0, + "mbase" : 60.0, + "zr" : 0.0, + "zx" : 1.0, + "rt" : 0.0, + "xt" : 0.0, + "gtap" : 1.0, + "stat" : 1, + "rmpct" : 100.0, + "pt" : 10000.0, + "pb" : -10000.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "wmod" : 0, + "wpf" : 1.0, + "nreg" : 0, + "baslod" : 0 + }, { + "i" : 3, + "id" : "1 ", + "pg" : 0.0, + "qg" : 25.075, + "qt" : 40.0, + "qb" : 0.0, + "vs" : 1.01, + "ireg" : 0, + "mbase" : 60.0, + "zr" : 0.0, + "zx" : 1.0, + "rt" : 0.0, + "xt" : 0.0, + "gtap" : 1.0, + "stat" : 1, + "rmpct" : 100.0, + "pt" : 10000.0, + "pb" : -10000.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "wmod" : 0, + "wpf" : 1.0, + "nreg" : 0, + "baslod" : 0 + }, { + "i" : 6, + "id" : "1 ", + "pg" : 0.0, + "qg" : 12.73, + "qt" : 24.0, + "qb" : -6.0, + "vs" : 1.07, + "ireg" : 0, + "mbase" : 25.0, + "zr" : 0.0, + "zx" : 1.0, + "rt" : 0.0, + "xt" : 0.0, + "gtap" : 1.0, + "stat" : 1, + "rmpct" : 100.0, + "pt" : 10000.0, + "pb" : -10000.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "wmod" : 0, + "wpf" : 1.0, + "nreg" : 0, + "baslod" : 0 + }, { + "i" : 8, + "id" : "1 ", + "pg" : 0.0, + "qg" : 17.623, + "qt" : 24.0, + "qb" : -6.0, + "vs" : 1.09, + "ireg" : 0, + "mbase" : 25.0, + "zr" : 0.0, + "zx" : 1.0, + "rt" : 0.0, + "xt" : 0.0, + "gtap" : 1.0, + "stat" : 1, + "rmpct" : 100.0, + "pt" : 10000.0, + "pb" : -10000.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "wmod" : 0, + "wpf" : 1.0, + "nreg" : 0, + "baslod" : 0 + } ], + "nonTransformerBranches" : [ { + "i" : 1, + "j" : 2, + "ckt" : "1 ", + "r" : 0.01938, + "x" : 0.05917, + "b" : 0.0528, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 1, + "j" : 5, + "ckt" : "1 ", + "r" : 0.05403, + "x" : 0.22304, + "b" : 0.0492, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 2, + "j" : 3, + "ckt" : "1 ", + "r" : 0.04699, + "x" : 0.19797, + "b" : 0.0438, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 2, + "j" : 4, + "ckt" : "1 ", + "r" : 0.05811, + "x" : 0.17632, + "b" : 0.034, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 2, + "j" : 5, + "ckt" : "1 ", + "r" : 0.05695, + "x" : 0.17388, + "b" : 0.0346, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 3, + "j" : 4, + "ckt" : "1 ", + "r" : 0.06701, + "x" : 0.17103, + "b" : 0.0128, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 4, + "j" : 5, + "ckt" : "1 ", + "r" : 0.01335, + "x" : 0.04211, + "b" : 0.0, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 6, + "j" : 11, + "ckt" : "1 ", + "r" : 0.09498, + "x" : 0.1989, + "b" : 0.0, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 6, + "j" : 12, + "ckt" : "1 ", + "r" : 0.12291, + "x" : 0.25581, + "b" : 0.0, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 6, + "j" : 13, + "ckt" : "1 ", + "r" : 0.06615, + "x" : 0.13027, + "b" : 0.0, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 7, + "j" : 8, + "ckt" : "1 ", + "r" : 0.0, + "x" : 0.17615, + "b" : 0.0, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 7, + "j" : 9, + "ckt" : "1 ", + "r" : 0.0, + "x" : 0.11001, + "b" : 0.0, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 9, + "j" : 10, + "ckt" : "1 ", + "r" : 0.03181, + "x" : 0.0845, + "b" : 0.0, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 9, + "j" : 14, + "ckt" : "1 ", + "r" : 0.12711, + "x" : 0.27038, + "b" : 0.0, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 10, + "j" : 11, + "ckt" : "1 ", + "r" : 0.08205, + "x" : 0.19207, + "b" : 0.0, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 12, + "j" : 13, + "ckt" : "1 ", + "r" : 0.22092, + "x" : 0.19988, + "b" : 0.0, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + }, { + "i" : 13, + "j" : 14, + "ckt" : "1 ", + "r" : 0.17093, + "x" : 0.34802, + "b" : 0.0, + "rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "gi" : 0.0, + "bi" : 0.0, + "gj" : 0.0, + "bj" : 0.0, + "st" : 1, + "met" : 1, + "len" : 0.0, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "name" : " " + } ], + "transformers" : [ { + "anstar" : 0.0, + "ckt" : "1 ", + "cm" : 1, + "cw" : 1, + "cz" : 1, + "i" : 4, + "j" : 7, + "k" : 0, + "mag1" : 0.0, + "mag2" : 0.0, + "name" : " ", + "nmetr" : 2, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "r12" : 0.0, + "r23" : 0.0, + "r31" : 0.0, + "sbase12" : 100.0, + "sbase23" : "NaN", + "sbase31" : "NaN", + "stat" : 1, + "vecgrp" : " ", + "vmstar" : 1.0, + "winding1" : { + "windv" : 0.978, + "nomv" : 0.0, + "ang" : 0.0, + "cod" : 0, + "cont" : 0, + "node" : 0, + "rma" : 1.5, + "rmi" : 0.51, + "vma" : 1.5, + "vmi" : 0.51, + "ntp" : 159, + "tab" : 0, + "cr" : 0.0, + "cx" : 0.0, + "cnxa" : 0.0 + }, + "winding1Rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "winding2" : { + "windv" : 1.0, + "nomv" : 0.0, + "ang" : 0.0, + "cod" : 0, + "cont" : 0, + "node" : 0, + "rma" : "NaN", + "rmi" : "NaN", + "vma" : "NaN", + "vmi" : "NaN", + "ntp" : 33, + "tab" : 0, + "cr" : 0.0, + "cx" : 0.0, + "cnxa" : 0.0 + }, + "winding2Rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "winding3" : { + "windv" : "NaN", + "nomv" : 0.0, + "ang" : 0.0, + "cod" : 0, + "cont" : 0, + "node" : 0, + "rma" : "NaN", + "rmi" : "NaN", + "vma" : "NaN", + "vmi" : "NaN", + "ntp" : 33, + "tab" : 0, + "cr" : 0.0, + "cx" : 0.0, + "cnxa" : 0.0 + }, + "winding3Rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "x12" : 0.20912, + "x23" : "NaN", + "x31" : "NaN", + "zcod" : 0 + }, { + "anstar" : 0.0, + "ckt" : "1 ", + "cm" : 1, + "cw" : 1, + "cz" : 1, + "i" : 4, + "j" : 9, + "k" : 0, + "mag1" : 0.0, + "mag2" : 0.0, + "name" : " ", + "nmetr" : 2, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "r12" : 0.0, + "r23" : 0.0, + "r31" : 0.0, + "sbase12" : 100.0, + "sbase23" : "NaN", + "sbase31" : "NaN", + "stat" : 1, + "vecgrp" : " ", + "vmstar" : 1.0, + "winding1" : { + "windv" : 0.969, + "nomv" : 0.0, + "ang" : 0.0, + "cod" : 0, + "cont" : 0, + "node" : 0, + "rma" : 1.5, + "rmi" : 0.51, + "vma" : 1.5, + "vmi" : 0.51, + "ntp" : 159, + "tab" : 0, + "cr" : 0.0, + "cx" : 0.0, + "cnxa" : 0.0 + }, + "winding1Rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "winding2" : { + "windv" : 1.0, + "nomv" : 0.0, + "ang" : 0.0, + "cod" : 0, + "cont" : 0, + "node" : 0, + "rma" : "NaN", + "rmi" : "NaN", + "vma" : "NaN", + "vmi" : "NaN", + "ntp" : 33, + "tab" : 0, + "cr" : 0.0, + "cx" : 0.0, + "cnxa" : 0.0 + }, + "winding2Rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "winding3" : { + "windv" : "NaN", + "nomv" : 0.0, + "ang" : 0.0, + "cod" : 0, + "cont" : 0, + "node" : 0, + "rma" : "NaN", + "rmi" : "NaN", + "vma" : "NaN", + "vmi" : "NaN", + "ntp" : 33, + "tab" : 0, + "cr" : 0.0, + "cx" : 0.0, + "cnxa" : 0.0 + }, + "winding3Rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "x12" : 0.55618, + "x23" : "NaN", + "x31" : "NaN", + "zcod" : 0 + }, { + "anstar" : 0.0, + "ckt" : "1 ", + "cm" : 1, + "cw" : 1, + "cz" : 1, + "i" : 5, + "j" : 6, + "k" : 0, + "mag1" : 0.0, + "mag2" : 0.0, + "name" : " ", + "nmetr" : 2, + "ownership" : { + "o1" : 1, + "f1" : 1.0, + "o2" : 0, + "f2" : 1.0, + "o3" : 0, + "f3" : 1.0, + "o4" : 0, + "f4" : 1.0 + }, + "r12" : 0.0, + "r23" : 0.0, + "r31" : 0.0, + "sbase12" : 100.0, + "sbase23" : "NaN", + "sbase31" : "NaN", + "stat" : 1, + "vecgrp" : " ", + "vmstar" : 1.0, + "winding1" : { + "windv" : 0.932, + "nomv" : 0.0, + "ang" : 0.0, + "cod" : 0, + "cont" : 0, + "node" : 0, + "rma" : 1.5, + "rmi" : 0.51, + "vma" : 1.5, + "vmi" : 0.51, + "ntp" : 159, + "tab" : 0, + "cr" : 0.0, + "cx" : 0.0, + "cnxa" : 0.0 + }, + "winding1Rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "winding2" : { + "windv" : 1.0, + "nomv" : 0.0, + "ang" : 0.0, + "cod" : 0, + "cont" : 0, + "node" : 0, + "rma" : "NaN", + "rmi" : "NaN", + "vma" : "NaN", + "vmi" : "NaN", + "ntp" : 33, + "tab" : 0, + "cr" : 0.0, + "cx" : 0.0, + "cnxa" : 0.0 + }, + "winding2Rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "winding3" : { + "windv" : "NaN", + "nomv" : 0.0, + "ang" : 0.0, + "cod" : 0, + "cont" : 0, + "node" : 0, + "rma" : "NaN", + "rmi" : "NaN", + "vma" : "NaN", + "vmi" : "NaN", + "ntp" : 33, + "tab" : 0, + "cr" : 0.0, + "cx" : 0.0, + "cnxa" : 0.0 + }, + "winding3Rates" : { + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0, + "rate4" : 0.0, + "rate5" : 0.0, + "rate6" : 0.0, + "rate7" : 0.0, + "rate8" : 0.0, + "rate9" : 0.0, + "rate10" : 0.0, + "rate11" : 0.0, + "rate12" : 0.0 + }, + "x12" : 0.25202, + "x23" : "NaN", + "x31" : "NaN", + "zcod" : 0 + } ], + "areas" : [ { + "i" : 1, + "isw" : 2, + "pdes" : 0.0, + "ptol" : 999.99, + "arname" : "IEEE14 " + } ], + "twoTerminalDcTransmissionLines" : [ ], + "voltageSourceConverterDcTransmissionLines" : [ ], + "transformerImpedanceCorrections" : [ ], + "multiTerminalDcTransmissionLines" : [ ], + "lineGrouping" : [ ], + "zones" : [ ], + "interareaTransfer" : [ ], + "owners" : [ { + "i" : 1, + "owname" : "1" + } ], + "facts" : [ ], + "switchedShunts" : [ ], + "gneDevice" : [ ], + "inductionMachines" : [ ], + "substations" : [ { + "is" : 1, + "name" : "STATION 1", + "lati" : 0.0, + "long" : 0.0, + "srg" : 0.1, + "nodes" : [ { + "ni" : 1, + "name" : "NB1", + "i" : 1, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + }, { + "ni" : 2, + "name" : "NB2", + "i" : 1, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + }, { + "ni" : 3, + "name" : "NL2", + "i" : 1, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + }, { + "ni" : 4, + "name" : "NL5", + "i" : 1, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + }, { + "ni" : 5, + "name" : "NG1", + "i" : 1, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + } ], + "switchingDevices" : [ { + "ni" : 1, + "nj" : 2, + "ckt" : "1 ", + "name" : "Sw-BusBars", + "type" : 2, + "status" : 1, + "nstat" : 1, + "x" : 0.0, + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0 + }, { + "ni" : 1, + "nj" : 3, + "ckt" : "1 ", + "name" : "Sw-BranchToBus2", + "type" : 2, + "status" : 1, + "nstat" : 1, + "x" : 0.0, + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0 + }, { + "ni" : 2, + "nj" : 4, + "ckt" : "1 ", + "name" : "Sw-BranchToBus5", + "type" : 2, + "status" : 1, + "nstat" : 1, + "x" : 0.0, + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0 + }, { + "ni" : 2, + "nj" : 5, + "ckt" : "1 ", + "name" : "Sw-Gen1", + "type" : 2, + "status" : 1, + "nstat" : 1, + "x" : 0.0, + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0 + } ], + "equipmentTerminals" : [ { + "i" : 1, + "ni" : 5, + "type" : "M", + "id" : "1 ", + "j" : 0, + "k" : 0 + }, { + "i" : 1, + "ni" : 3, + "type" : "B", + "id" : "1 ", + "j" : 2, + "k" : 0 + }, { + "i" : 1, + "ni" : 4, + "type" : "B", + "id" : "1 ", + "j" : 5, + "k" : 0 + } ] + }, { + "is" : 2, + "name" : "STATION 5", + "lati" : 0.0, + "long" : 0.0, + "srg" : 0.1, + "nodes" : [ { + "ni" : 1, + "name" : "NB1", + "i" : 2, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + }, { + "ni" : 2, + "name" : "NB2", + "i" : 2, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + }, { + "ni" : 3, + "name" : "NL3", + "i" : 2, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + }, { + "ni" : 4, + "name" : "NL4", + "i" : 2, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + }, { + "ni" : 5, + "name" : "NL5", + "i" : 2, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + }, { + "ni" : 6, + "name" : "NL1", + "i" : 2, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + }, { + "ni" : 7, + "name" : "NG1", + "i" : 2, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + }, { + "ni" : 8, + "name" : "NLd1", + "i" : 2, + "status" : 1, + "vm" : 1.0, + "va" : 0.0 + } ], + "switchingDevices" : [ { + "ni" : 1, + "nj" : 2, + "ckt" : "1 ", + "name" : "Sw-BusBars", + "type" : 2, + "status" : 1, + "nstat" : 1, + "x" : 0.0, + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0 + }, { + "ni" : 1, + "nj" : 6, + "ckt" : "1 ", + "name" : "Sw-BranchToBus1", + "type" : 2, + "status" : 1, + "nstat" : 1, + "x" : 0.0, + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0 + }, { + "ni" : 1, + "nj" : 7, + "ckt" : "1 ", + "name" : "Sw-Gen1", + "type" : 2, + "status" : 1, + "nstat" : 1, + "x" : 0.0, + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0 + }, { + "ni" : 1, + "nj" : 8, + "ckt" : "1 ", + "name" : "Sw-Load1", + "type" : 2, + "status" : 1, + "nstat" : 1, + "x" : 0.0, + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0 + }, { + "ni" : 2, + "nj" : 3, + "ckt" : "1 ", + "name" : "Sw-BranchToBus3", + "type" : 2, + "status" : 1, + "nstat" : 1, + "x" : 0.0, + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0 + }, { + "ni" : 2, + "nj" : 4, + "ckt" : "1 ", + "name" : "Sw-BranchToBus4", + "type" : 2, + "status" : 1, + "nstat" : 1, + "x" : 0.0, + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0 + }, { + "ni" : 2, + "nj" : 5, + "ckt" : "1 ", + "name" : "Sw-BranchToBus5", + "type" : 2, + "status" : 1, + "nstat" : 1, + "x" : 0.0, + "rate1" : 0.0, + "rate2" : 0.0, + "rate3" : 0.0 + } ], + "equipmentTerminals" : [ { + "i" : 2, + "ni" : 7, + "type" : "M", + "id" : "1 ", + "j" : 0, + "k" : 0 + }, { + "i" : 2, + "ni" : 8, + "type" : "L", + "id" : "1 ", + "j" : 0, + "k" : 0 + }, { + "i" : 2, + "ni" : 6, + "type" : "B", + "id" : "1 ", + "j" : 1, + "k" : 0 + }, { + "i" : 2, + "ni" : 3, + "type" : "B", + "id" : "1 ", + "j" : 3, + "k" : 0 + }, { + "i" : 2, + "ni" : 4, + "type" : "B", + "id" : "1 ", + "j" : 4, + "k" : 0 + }, { + "i" : 2, + "ni" : 5, + "type" : "B", + "id" : "1 ", + "j" : 5, + "k" : 0 + } ] + } ] +} \ No newline at end of file diff --git a/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.rawx b/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.rawx new file mode 100644 index 00000000000..ef3155f2880 --- /dev/null +++ b/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.rawx @@ -0,0 +1,193 @@ +{ + "network":{ + "caseid":{ + "fields":["ic", "sbase", "rev", "xfrrat", "nxfrat", "basfrq", "title1", "title2"], + "data":[0, 100.00, 35, 0, 0, 60.00, + " 08/19/93 UW ARCHIVE 100.0 1962 W IEEE 14 Bus Test Case", ""] + }, + "bus":{ + "fields":["ibus", "name", "baskv", "ide", "area", "zone", "owner", "vm", "va"], + "data":[ + [1, "Bus 1 ", 138.0000, 3, 1, 1, 1, 1.06000, 0.0000], + [2, "Bus 2 ", 138.0000, 2, 1, 1, 1, 1.04500, -4.9826], + [3, "Bus 3 ", 138.0000, 2, 1, 1, 1, 1.01000, -12.7250], + [4, "Bus 4 ", 138.0000, 1, 1, 1, 1, 1.01767, -10.3128], + [5, "Bus 5 ", 138.0000, 1, 1, 1, 1, 1.01951, -8.7738], + [6, "Bus 6 ", 138.0000, 2, 1, 1, 1, 1.07000, -14.2209], + [7, "Bus 7 ", 138.0000, 1, 1, 1, 1, 1.06152, -13.3596], + [8, "Bus 8 ", 138.0000, 2, 1, 1, 1, 1.09000, -13.3596], + [9, "Bus 9 ", 138.0000, 1, 1, 1, 1, 1.05593, -14.9385], + [10, "Bus 10 ", 138.0000, 1, 1, 1, 1, 1.05099, -15.0972], + [11, "Bus 11 ", 138.0000, 1, 1, 1, 1, 1.05691, -14.7906], + [12, "Bus 12 ", 138.0000, 1, 1, 1, 1, 1.05519, -15.0755], + [13, "Bus 13 ", 138.0000, 1, 1, 1, 1, 1.05038, -15.1562], + [14, "Bus 14 ", 138.0000, 1, 1, 1, 1, 1.03553, -16.0336] + ] + }, + "load":{ + "fields":["ibus", "loadid", "stat", "area", "zone", "pl", "ql", "ip", "iq", "yp", "yq", "owner", "scale"], + "data":[ + [2, "1 ", 1, 1, 1, 21.700, 12.700, 0.000, 0.000, 0.000, -0.000, 1, 1], + [3, "1 ", 1, 1, 1, 94.200, 19.000, 0.000, 0.000, 0.000, -0.000, 1, 1], + [4, "1 ", 1, 1, 1, 47.800, -3.900, 0.000, 0.000, 0.000, -0.000, 1, 1], + [5, "1 ", 1, 1, 1, 7.600, 1.600, 0.000, 0.000, 0.000, -0.000, 1, 1], + [6, "1 ", 1, 1, 1, 11.200, 7.500, 0.000, 0.000, 0.000, -0.000, 1, 1], + [9, "1 ", 1, 1, 1, 29.500, 16.600, 0.000, 0.000, 0.000, -0.000, 1, 1], + [10, "1 ", 1, 1, 1, 9.000, 5.800, 0.000, 0.000, 0.000, -0.000, 1, 1], + [11, "1 ", 1, 1, 1, 3.500, 1.800, 0.000, 0.000, 0.000, -0.000, 1, 1], + [12, "1 ", 1, 1, 1, 6.100, 1.600, 0.000, 0.000, 0.000, -0.000, 1, 1], + [13, "1 ", 1, 1, 1, 13.500, 5.800, 0.000, 0.000, 0.000, -0.000, 1, 1], + [14, "1 ", 1, 1, 1, 14.900, 5.000, 0.000, 0.000, 0.000, -0.000, 1, 1] + ] + }, + "fixshunt":{ + "fields":["ibus", "shntid", "stat", "gl", "bl"], + "data":[ + [9, " 1", 1, 0.000, 19.000] + ] + }, + "generator":{ + "fields":["ibus", "machid", "pg", "qg", "qt", "qb", "vs", "ireg", "mbase", "zr", "zx", "rt", "xt", "gtap", "stat", + "rmpct", "pt", "pb", "o1", "f1", "o2", "f2", "o3", "f3", "o4", "f4", "wmod", "wpf"], + "data":[ + [1, "1 ", 232.392, -16.549, 0.000, 0.000, 1.06000, 0, 615.000, 0.00000, 1.00000, 0.00000, 0.00000, 1.00000, 1, + 100.0, 10000.000, -10000.000, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [2, "1 ", 40.000, 43.556, 50.000, -40.000, 1.04500, 0, 60.000, 0.00000, 1.00000, 0.00000, 0.00000, 1.00000, 1, + 100.0, 10000.000, -10000.000, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [3, "1 ", 0.000, 25.075, 40.000, 0.000, 1.01000, 0, 60.000, 0.00000, 1.00000, 0.00000, 0.00000, 1.00000, 1, + 100.0, 10000.000, -10000.000, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000,0, 1.0000], + [6, "1 ", 0.000, 12.730, 24.000, -6.000, 1.07000, 0, 25.000, 0.00000, 1.00000, 0.00000, 0.00000, 1.00000, 1, + 100.0, 10000.000, -10000.000, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000,0, 1.0000], + [8, "1 ", 0.000, 17.623, 24.000, -6.000, 1.09000, 0, 25.000, 0.00000, 1.00000, 0.00000, 0.00000, 1.00000, 1, + 100.0, 10000.000, -10000.000, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000] + ] + }, + "acline":{ + "fields":["ibus", "jbus", "ckt", "rpu", "xpu", "bpu", "rate1", "rate2", "rate3", "gi", "bi", "gj", "bj", "stat", + "met", "len", "o1", "f1", "o2", "f2", "o3", "f3", "o4", "f4"], + "data":[ + [1, 2, "1 ", 0.01938, 0.05917, 0.05280, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [1, 5, "1 ", 0.05403, 0.22304, 0.04920, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [2, 3, "1 ", 0.04699, 0.19797, 0.04380, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [2, 4, "1 ", 0.05811, 0.17632, 0.03400, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [2, 5, "1 ", 0.05695, 0.17388, 0.03460, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [3, 4, "1 ", 0.06701, 0.17103, 0.01280, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [4, 5, "1 ", 0.01335, 0.04211, 0.00000, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [6, 11, "1 ", 0.09498, 0.19890, 0.00000, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [6, 12, "1 ", 0.12291, 0.25581, 0.00000, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [6, 13, "1 ", 0.06615, 0.13027, 0.00000, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [7, 8, "1 ", 0.00000, 0.17615, 0.00000, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [7, 9, "1 ", 0.00000, 0.11001, 0.00000, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [9, 10, "1 ", 0.03181, 0.08450, 0.00000, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [9, 14, "1 ", 0.12711, 0.27038, 0.00000, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [10, 11, "1 ", 0.08205, 0.19207, 0.00000, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [12, 13, "1 ", 0.22092, 0.19988, 0.00000, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000], + [13, 14, "1 ", 0.17093, 0.34802, 0.00000, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000, 1, + 1, 0.0, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000] + ] + }, + "transformer":{ + "fields":["ibus", "jbus", "kbus", "ckt", "cw", "cz", "cm", "mag1", "mag2", "nmet", "name", "stat", "o1", "f1", "o2", "f2", "o3", "f3", "o4", "f4", + "r1_2", "x1_2", "sbase1_2", + "windv1", "nomv1", "ang1", "wdg1rate1", "wdg1rate2", "wdg1rate3", "cod1", "cont1", "rma1", "rmi1", "vma1", "vmi1", "ntp1", "tab1", "cr1", "cx1", + "windv2", "nomv2"], + "data":[ + [4, 7, 0, "1 ", 1, 1, 1, 0.00000, 0.00000, 2, " ", 1, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000, + 0.00000, 0.20912, 100.00, + 0.97800, 0.000, 0.000, 0.00, 0.00, 0.00, 0, 0, 1.50000, 0.51000, 1.50000, 0.51000, 159, 0, 0.00000, 0.00000, + 1.00000, 0.000], + [4, 9, 0, "1 ", 1, 1, 1, 0.00000, 0.00000, 2, " ", 1, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000, + 0.00000, 0.55618, 100.00, + 0.96900, 0.000, 0.000, 0.00, 0.00, 0.00, 0, 0, 1.50000, 0.51000, 1.50000, 0.51000, 159, 0, 0.00000, 0.00000, + 1.00000, 0.000], + [5, 6, 0, "1 ", 1, 1, 1, 0.00000, 0.00000, 2, " ", 1, 1, 1.0000, 0, 1.0000, 0, 1.0000, 0, 1.0000, + 0.00000, 0.25202, 100.00, + 0.93200, 0.000, 0.000, 0.00, 0.00, 0.00, 0, 0, 1.50000, 0.51000, 1.50000, 0.51000, 159, 0, 0.00000, 0.00000, + 1.00000, 0.000] + ] + }, + "area":{ + "fields":["iarea", "isw", "pdes", "ptol", "arname"], + "data":[ + [1, 2, 0.000, 999.990, "IEEE14 "] + ] + }, + "owner":{ + "fields":["iowner", "owname"], + "data":[ + [1, "1"] + ] + }, + "sub":{ + "fields":["isub", "name", "lati", "long", "srg"], + "data":[ + [1, "STATION 1", 0.0, 0.0, 0.1], + [2, "STATION 5", 0.0, 0.0, 0.1] + ] + }, + "subnode":{ + "fields":["isub", "inode", "name", "ibus", "stat", "vm", "va"], + "data":[ + [1, 1, "NB1", 1, 1, 1.0, 0.0], + [1, 2, "NB2", 1, 1, 1.0, 0.0], + [1, 3, "NL2", 1, 1, 1.0, 0.0], + [1, 4, "NL5", 1, 1, 1.0, 0.0], + [1, 5, "NG1", 1, 1, 1.0, 0.0], + [2, 1, "NB1", 2, 1, 1.0, 0.0], + [2, 2, "NB2", 2, 1, 1.0, 0.0], + [2, 3, "NL3", 2, 1, 1.0, 0.0], + [2, 4, "NL4", 2, 1, 1.0, 0.0], + [2, 5, "NL5", 2, 1, 1.0, 0.0], + [2, 6, "NL1", 2, 1, 1.0, 0.0], + [2, 7, "NG1", 2, 1, 1.0, 0.0], + [2, 8, "NLd1", 2, 1, 1.0, 0.0] + ] + }, + "subswd":{ + "fields":["isub", "inode", "jnode", "swdid", "name", "type", "stat", "nstat", "xpu", "rate1", "rate2", "rate3"], + "data":[ + [1, 1, 2, "1 ", "Sw-BusBars", 2, 1, 1, 0, 0, 0, 0], + [1, 1, 3, "1 ", "Sw-BranchToBus2", 2, 1, 1, 0, 0, 0, 0], + [1, 2, 4, "1 ", "Sw-BranchToBus5", 2, 1, 1, 0, 0, 0, 0], + [1, 2, 5, "1 ", "Sw-Gen1", 2, 1, 1, 0, 0, 0, 0], + [2, 1, 2, "1 ", "Sw-BusBars", 2, 1, 1, 0, 0, 0, 0], + [2, 1, 6, "1 ", "Sw-BranchToBus1", 2, 1, 1, 0, 0, 0, 0], + [2, 1, 7, "1 ", "Sw-Gen1", 2, 1, 1, 0, 0, 0, 0], + [2, 1, 8, "1 ", "Sw-Load1", 2, 1, 1, 0, 0, 0, 0], + [2, 2, 3, "1 ", "Sw-BranchToBus3", 2, 1, 1, 0, 0, 0, 0], + [2, 2, 4, "1 ", "Sw-BranchToBus4", 2, 1, 1, 0, 0, 0, 0], + [2, 2, 5, "1 ", "Sw-BranchToBus5", 2, 1, 1, 0, 0, 0, 0] + ] + }, + "subterm":{ + "fields":["isub", "inode", "type", "eqid", "ibus", "jbus", "kbus"], + "data":[ + [1, 5, "M", "1 ", 1, null, null], + [1, 3, "B", "1 ", 1, 2, null], + [1, 4, "B", "1 ", 1, 5, null], + [2, 7, "M", "1 ", 2, null, null], + [2, 8, "L", "1 ", 2, null, null], + [2, 6, "B", "1 ", 2, 1, null], + [2, 3, "B", "1 ", 2, 3, null], + [2, 4, "B", "1 ", 2, 4, null], + [2, 5, "B", "1 ", 2, 5, null] + ] + } + } +} \ No newline at end of file diff --git a/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw b/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw new file mode 100644 index 00000000000..a9775c5957c --- /dev/null +++ b/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw @@ -0,0 +1,131 @@ +0,100.0,35,0.0,0.0,60.0 + 08/19/93 UW ARCHIVE 100.0 1962 W IEEE 14 Bus Test Case + +0 / END OF SYSTEM-WIDE DATA, BEGIN BUS DATA +1,'Bus 1 ',138.0,3,1,1,1,1.06,0.0 +2,'Bus 2 ',138.0,2,1,1,1,1.045,-4.9826 +3,'Bus 3 ',138.0,2,1,1,1,1.01,-12.725 +4,'Bus 4 ',138.0,1,1,1,1,1.01767,-10.3128 +5,'Bus 5 ',138.0,1,1,1,1,1.01951,-8.7738 +6,'Bus 6 ',138.0,2,1,1,1,1.07,-14.2209 +7,'Bus 7 ',138.0,1,1,1,1,1.06152,-13.3596 +8,'Bus 8 ',138.0,2,1,1,1,1.09,-13.3596 +9,'Bus 9 ',138.0,1,1,1,1,1.05593,-14.9385 +10,'Bus 10 ',138.0,1,1,1,1,1.05099,-15.0972 +11,'Bus 11 ',138.0,1,1,1,1,1.05691,-14.7906 +12,'Bus 12 ',138.0,1,1,1,1,1.05519,-15.0755 +13,'Bus 13 ',138.0,1,1,1,1,1.05038,-15.1562 +14,'Bus 14 ',138.0,1,1,1,1,1.03553,-16.0336 +0 / END OF BUS DATA, BEGIN LOAD DATA +2,'1 ',1,1,1,21.7,12.7,0.0,0.0,0.0,-0.0,1,1 +3,'1 ',1,1,1,94.2,19.0,0.0,0.0,0.0,-0.0,1,1 +4,'1 ',1,1,1,47.8,-3.9,0.0,0.0,0.0,-0.0,1,1 +5,'1 ',1,1,1,7.6,1.6,0.0,0.0,0.0,-0.0,1,1 +6,'1 ',1,1,1,11.2,7.5,0.0,0.0,0.0,-0.0,1,1 +9,'1 ',1,1,1,29.5,16.6,0.0,0.0,0.0,-0.0,1,1 +10,'1 ',1,1,1,9.0,5.8,0.0,0.0,0.0,-0.0,1,1 +11,'1 ',1,1,1,3.5,1.8,0.0,0.0,0.0,-0.0,1,1 +12,'1 ',1,1,1,6.1,1.6,0.0,0.0,0.0,-0.0,1,1 +13,'1 ',1,1,1,13.5,5.8,0.0,0.0,0.0,-0.0,1,1 +14,'1 ',1,1,1,14.9,5.0,0.0,0.0,0.0,-0.0,1,1 +0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA +9,' 1',1,0.0,19.0 +0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA +1,'1 ',232.392,-16.549,0.0,0.0,1.06,0,0,615.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +2,'1 ',40.0,43.556,50.0,-40.0,1.045,0,0,60.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +3,'1 ',0.0,25.075,40.0,0.0,1.01,0,0,60.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +6,'1 ',0.0,12.73,24.0,-6.0,1.07,0,0,25.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +8,'1 ',0.0,17.623,24.0,-6.0,1.09,0,0,25.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +0 / END OF GENERATOR DATA, BEGIN BRANCH DATA +1,2,'1 ',0.01938,0.05917,0.0528,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +1,5,'1 ',0.05403,0.22304,0.0492,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +2,3,'1 ',0.04699,0.19797,0.0438,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +2,4,'1 ',0.05811,0.17632,0.034,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +2,5,'1 ',0.05695,0.17388,0.0346,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +3,4,'1 ',0.06701,0.17103,0.0128,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +4,5,'1 ',0.01335,0.04211,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +6,11,'1 ',0.09498,0.1989,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +6,12,'1 ',0.12291,0.25581,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +6,13,'1 ',0.06615,0.13027,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +7,8,'1 ',0.0,0.17615,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +7,9,'1 ',0.0,0.11001,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +9,10,'1 ',0.03181,0.0845,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +9,14,'1 ',0.12711,0.27038,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +10,11,'1 ',0.08205,0.19207,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +12,13,'1 ',0.22092,0.19988,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +13,14,'1 ',0.17093,0.34802,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +0 / END OF BRANCH DATA, BEGIN SYSTEM SWITCHING DEVICE DATA +0 / END OF SYSTEM SWITCHING DEVICE DATA, BEGIN TRANSFORMER DATA +4,7,0,'1 ',1,1,1,0.0,0.0,2,' ',1,1,1.0,0,1.0,0,1.0,0,1.0 +0.0,0.20912,100.0 +0.978,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,159,0,0.0,0.0 +1.0,0.0 +4,9,0,'1 ',1,1,1,0.0,0.0,2,' ',1,1,1.0,0,1.0,0,1.0,0,1.0 +0.0,0.55618,100.0 +0.969,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,159,0,0.0,0.0 +1.0,0.0 +5,6,0,'1 ',1,1,1,0.0,0.0,2,' ',1,1,1.0,0,1.0,0,1.0,0,1.0 +0.0,0.25202,100.0 +0.932,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,159,0,0.0,0.0 +1.0,0.0 +0 / END OF TRANSFORMER DATA, BEGIN AREA DATA +1,2,0.0,999.99,'IEEE14 ' +0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA +0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA +0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA +0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA +0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA +0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA +0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA +0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA +1,'1' +0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA +0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA +0 / END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA +0 / END OF GNE DEVICE DATA, BEGIN INDUCTION MACHINE DATA +0 / END OF INDUCTION MACHINE DATA, BEGIN SUBSTATION DATA +1,'STATION 1',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',1,1,1.0,0.0 +2,'NB2',1,1,1.0,0.0 +3,'NL2',1,1,1.0,0.0 +4,'NL5',1,1,1.0,0.0 +5,'NG1',1,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-BranchToBus2','2',1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-BranchToBus5','2',1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-Gen1','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +1,5,'M','1 ' +1,3,'B',2,'1 ' +1,4,'B',5,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +2,'STATION 5',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',2,1,1.0,0.0 +2,'NB2',2,1,1.0,0.0 +3,'NL3',2,1,1.0,0.0 +4,'NL4',2,1,1.0,0.0 +5,'NL5',2,1,1.0,0.0 +6,'NL1',2,1,1.0,0.0 +7,'NG1',2,1,1.0,0.0 +8,'NLd1',2,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 +1,6,'1 ','Sw-BranchToBus1','2',1,1,0.0,0.0,0.0,0.0 +1,7,'1 ','Sw-Gen1','2',1,1,0.0,0.0,0.0,0.0 +1,8,'1 ','Sw-Load1','2',1,1,0.0,0.0,0.0,0.0 +2,3,'1 ','Sw-BranchToBus3','2',1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-BranchToBus4','2',1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-BranchToBus5','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +2,7,'M','1 ' +2,8,'L','1 ' +2,6,'B',1,'1 ' +2,3,'B',3,'1 ' +2,4,'B',4,'1 ' +2,5,'B',5,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +0 / END OF SUBSTATION DATA +Q diff --git a/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.rawx b/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.rawx new file mode 100644 index 00000000000..1e99ebc3e3a --- /dev/null +++ b/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.rawx @@ -0,0 +1,156 @@ +{ + "network" : { + "caseid" : { + "fields" : [ "ic", "sbase", "rev", "xfrrat", "nxfrat", "basfrq", "title1", "title2" ], + "data" : [ 0,100.0,35,0.0,0.0,60.0," 08/19/93 UW ARCHIVE 100.0 1962 W IEEE 14 Bus Test Case","" ] + }, + "bus" : { + "fields" : [ "ibus", "name", "baskv", "ide", "area", "zone", "owner", "vm", "va" ], + "data" : [ + [ 1,"Bus 1 ",138.0,3,1,1,1,1.06,0.0 ], + [ 2,"Bus 2 ",138.0,2,1,1,1,1.045,-4.9826 ], + [ 3,"Bus 3 ",138.0,2,1,1,1,1.01,-12.725 ], + [ 4,"Bus 4 ",138.0,1,1,1,1,1.01767,-10.3128 ], + [ 5,"Bus 5 ",138.0,1,1,1,1,1.01951,-8.7738 ], + [ 6,"Bus 6 ",138.0,2,1,1,1,1.07,-14.2209 ], + [ 7,"Bus 7 ",138.0,1,1,1,1,1.06152,-13.3596 ], + [ 8,"Bus 8 ",138.0,2,1,1,1,1.09,-13.3596 ], + [ 9,"Bus 9 ",138.0,1,1,1,1,1.05593,-14.9385 ], + [ 10,"Bus 10 ",138.0,1,1,1,1,1.05099,-15.0972 ], + [ 11,"Bus 11 ",138.0,1,1,1,1,1.05691,-14.7906 ], + [ 12,"Bus 12 ",138.0,1,1,1,1,1.05519,-15.0755 ], + [ 13,"Bus 13 ",138.0,1,1,1,1,1.05038,-15.1562 ], + [ 14,"Bus 14 ",138.0,1,1,1,1,1.03553,-16.0336 ] + ] + }, + "load" : { + "fields" : [ "ibus", "loadid", "stat", "area", "zone", "pl", "ql", "ip", "iq", "yp", "yq", "owner", "scale" ], + "data" : [ + [ 2,"1 ",1,1,1,21.7,12.7,0.0,0.0,0.0,-0.0,1,1 ], + [ 3,"1 ",1,1,1,94.2,19.0,0.0,0.0,0.0,-0.0,1,1 ], + [ 4,"1 ",1,1,1,47.8,-3.9,0.0,0.0,0.0,-0.0,1,1 ], + [ 5,"1 ",1,1,1,7.6,1.6,0.0,0.0,0.0,-0.0,1,1 ], + [ 6,"1 ",1,1,1,11.2,7.5,0.0,0.0,0.0,-0.0,1,1 ], + [ 9,"1 ",1,1,1,29.5,16.6,0.0,0.0,0.0,-0.0,1,1 ], + [ 10,"1 ",1,1,1,9.0,5.8,0.0,0.0,0.0,-0.0,1,1 ], + [ 11,"1 ",1,1,1,3.5,1.8,0.0,0.0,0.0,-0.0,1,1 ], + [ 12,"1 ",1,1,1,6.1,1.6,0.0,0.0,0.0,-0.0,1,1 ], + [ 13,"1 ",1,1,1,13.5,5.8,0.0,0.0,0.0,-0.0,1,1 ], + [ 14,"1 ",1,1,1,14.9,5.0,0.0,0.0,0.0,-0.0,1,1 ] + ] + }, + "fixshunt" : { + "fields" : [ "ibus", "shntid", "stat", "gl", "bl" ], + "data" : [ + [ 9," 1",1,0.0,19.0 ] + ] + }, + "generator" : { + "fields" : [ "ibus", "machid", "pg", "qg", "qt", "qb", "vs", "ireg", "mbase", "zr", "zx", "rt", "xt", "gtap", "stat", "rmpct", "pt", "pb", "o1", "f1", "o2", "f2", "o3", "f3", "o4", "f4", "wmod", "wpf" ], + "data" : [ + [ 1,"1 ",232.392,-16.549,0.0,0.0,1.06,0,615.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 ], + [ 2,"1 ",40.0,43.556,50.0,-40.0,1.045,0,60.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 ], + [ 3,"1 ",0.0,25.075,40.0,0.0,1.01,0,60.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 ], + [ 6,"1 ",0.0,12.73,24.0,-6.0,1.07,0,25.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 ], + [ 8,"1 ",0.0,17.623,24.0,-6.0,1.09,0,25.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 ] + ] + }, + "acline" : { + "fields" : [ "ibus", "jbus", "ckt", "rpu", "xpu", "bpu", "rate1", "rate2", "rate3", "gi", "bi", "gj", "bj", "stat", "met", "len", "o1", "f1", "o2", "f2", "o3", "f3", "o4", "f4" ], + "data" : [ + [ 1,2,"1 ",0.01938,0.05917,0.0528,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 1,5,"1 ",0.05403,0.22304,0.0492,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 2,3,"1 ",0.04699,0.19797,0.0438,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 2,4,"1 ",0.05811,0.17632,0.034,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 2,5,"1 ",0.05695,0.17388,0.0346,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 3,4,"1 ",0.06701,0.17103,0.0128,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 4,5,"1 ",0.01335,0.04211,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 6,11,"1 ",0.09498,0.1989,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 6,12,"1 ",0.12291,0.25581,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 6,13,"1 ",0.06615,0.13027,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 7,8,"1 ",0.0,0.17615,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 7,9,"1 ",0.0,0.11001,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 9,10,"1 ",0.03181,0.0845,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 9,14,"1 ",0.12711,0.27038,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 10,11,"1 ",0.08205,0.19207,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 12,13,"1 ",0.22092,0.19988,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ], + [ 13,14,"1 ",0.17093,0.34802,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 ] + ] + }, + "transformer" : { + "fields" : [ "ibus", "jbus", "kbus", "ckt", "cw", "cz", "cm", "mag1", "mag2", "nmet", "name", "stat", "o1", "f1", "o2", "f2", "o3", "f3", "o4", "f4", "r1_2", "x1_2", "sbase1_2", "windv1", "nomv1", "ang1", "wdg1rate1", "wdg1rate2", "wdg1rate3", "cod1", "cont1", "rma1", "rmi1", "vma1", "vmi1", "ntp1", "tab1", "cr1", "cx1", "windv2", "nomv2" ], + "data" : [ + [ 4,7,0,"1 ",1,1,1,0.0,0.0,2," ",1,1,1.0,0,1.0,0,1.0,0,1.0,0.0,0.20912,100.0,0.978,0.0,0.0,0.0,0.0,0.0,0,0,1.5,0.51,1.5,0.51,159,0,0.0,0.0,1.0,0.0 ], + [ 4,9,0,"1 ",1,1,1,0.0,0.0,2," ",1,1,1.0,0,1.0,0,1.0,0,1.0,0.0,0.55618,100.0,0.969,0.0,0.0,0.0,0.0,0.0,0,0,1.5,0.51,1.5,0.51,159,0,0.0,0.0,1.0,0.0 ], + [ 5,6,0,"1 ",1,1,1,0.0,0.0,2," ",1,1,1.0,0,1.0,0,1.0,0,1.0,0.0,0.25202,100.0,0.932,0.0,0.0,0.0,0.0,0.0,0,0,1.5,0.51,1.5,0.51,159,0,0.0,0.0,1.0,0.0 ] + ] + }, + "area" : { + "fields" : [ "iarea", "isw", "pdes", "ptol", "arname" ], + "data" : [ + [ 1,2,0.0,999.99,"IEEE14 " ] + ] + }, + "owner" : { + "fields" : [ "iowner", "owname" ], + "data" : [ + [ 1,"1" ] + ] + }, + "sub" : { + "fields" : [ "isub", "name", "lati", "long", "srg" ], + "data" : [ + [ 1,"STATION 1",0.0,0.0,0.1 ], + [ 2,"STATION 5",0.0,0.0,0.1 ] + ] + }, + "subnode" : { + "fields" : [ "isub", "inode", "name", "ibus", "stat", "vm", "va" ], + "data" : [ + [ 1,1,"NB1",1,1,1.0,0.0 ], + [ 1,2,"NB2",1,1,1.0,0.0 ], + [ 1,3,"NL2",1,1,1.0,0.0 ], + [ 1,4,"NL5",1,1,1.0,0.0 ], + [ 1,5,"NG1",1,1,1.0,0.0 ], + [ 2,1,"NB1",2,1,1.0,0.0 ], + [ 2,2,"NB2",2,1,1.0,0.0 ], + [ 2,3,"NL3",2,1,1.0,0.0 ], + [ 2,4,"NL4",2,1,1.0,0.0 ], + [ 2,5,"NL5",2,1,1.0,0.0 ], + [ 2,6,"NL1",2,1,1.0,0.0 ], + [ 2,7,"NG1",2,1,1.0,0.0 ], + [ 2,8,"NLd1",2,1,1.0,0.0 ] + ] + }, + "subswd" : { + "fields" : [ "isub", "inode", "jnode", "swdid", "name", "type", "stat", "nstat", "xpu", "rate1", "rate2", "rate3" ], + "data" : [ + [ 1,1,2,1 ,"Sw-BusBars","2",1,1,0.0,0.0,0.0,0.0 ], + [ 1,1,3,1 ,"Sw-BranchToBus2","2",1,1,0.0,0.0,0.0,0.0 ], + [ 1,2,4,1 ,"Sw-BranchToBus5","2",1,1,0.0,0.0,0.0,0.0 ], + [ 1,2,5,1 ,"Sw-Gen1","2",1,1,0.0,0.0,0.0,0.0 ], + [ 2,1,2,1 ,"Sw-BusBars","2",1,1,0.0,0.0,0.0,0.0 ], + [ 2,1,6,1 ,"Sw-BranchToBus1","2",1,1,0.0,0.0,0.0,0.0 ], + [ 2,1,7,1 ,"Sw-Gen1","2",1,1,0.0,0.0,0.0,0.0 ], + [ 2,1,8,1 ,"Sw-Load1","2",1,1,0.0,0.0,0.0,0.0 ], + [ 2,2,3,1 ,"Sw-BranchToBus3","2",1,1,0.0,0.0,0.0,0.0 ], + [ 2,2,4,1 ,"Sw-BranchToBus4","2",1,1,0.0,0.0,0.0,0.0 ], + [ 2,2,5,1 ,"Sw-BranchToBus5","2",1,1,0.0,0.0,0.0,0.0 ] + ] + }, + "subterm" : { + "fields" : [ "isub", "inode", "type", "eqid", "ibus", "jbus", "kbus" ], + "data" : [ + [ 1,5,"M","1 ",1,0,0 ], + [ 1,3,"B","1 ",1,2,0 ], + [ 1,4,"B","1 ",1,5,0 ], + [ 2,7,"M","1 ",2,0,0 ], + [ 2,8,"L","1 ",2,0,0 ], + [ 2,6,"B","1 ",2,1,0 ], + [ 2,3,"B","1 ",2,3,0 ], + [ 2,4,"B","1 ",2,4,0 ], + [ 2,5,"B","1 ",2,5,0 ] + ] + } + } +} \ No newline at end of file diff --git a/psse/psse-model/src/test/resources/IEEE_14_bus_rev35.json b/psse/psse-model/src/test/resources/IEEE_14_bus_rev35.json index 4d918533689..ba28f3d54ac 100644 --- a/psse/psse-model/src/test/resources/IEEE_14_bus_rev35.json +++ b/psse/psse-model/src/test/resources/IEEE_14_bus_rev35.json @@ -1665,5 +1665,6 @@ "facts" : [ ], "switchedShunts" : [ ], "gneDevice" : [ ], - "inductionMachines" : [ ] + "inductionMachines" : [ ], + "substations" : [ ] } \ No newline at end of file diff --git a/psse/psse-model/src/test/resources/IEEE_14_isolated_buses.json b/psse/psse-model/src/test/resources/IEEE_14_isolated_buses.json index 6b4cd164594..467b0ed2327 100644 --- a/psse/psse-model/src/test/resources/IEEE_14_isolated_buses.json +++ b/psse/psse-model/src/test/resources/IEEE_14_isolated_buses.json @@ -1532,5 +1532,6 @@ "b8" : 0.0 } ], "gneDevice" : [ ], - "inductionMachines" : [ ] + "inductionMachines" : [ ], + "substations" : [ ] } \ No newline at end of file diff --git a/psse/psse-model/src/test/resources/IEEE_24_bus_rev35.json b/psse/psse-model/src/test/resources/IEEE_24_bus_rev35.json index 11b82df7568..93b0fb1454d 100644 --- a/psse/psse-model/src/test/resources/IEEE_24_bus_rev35.json +++ b/psse/psse-model/src/test/resources/IEEE_24_bus_rev35.json @@ -3138,5 +3138,6 @@ "s8" : 1 } ], "gneDevice" : [ ], - "inductionMachines" : [ ] + "inductionMachines" : [ ], + "substations" : [ ] } \ No newline at end of file From 5e9384724ea317552cbc985c10cfd75c425ead14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Marqu=C3=A9s?= Date: Thu, 11 Apr 2024 15:18:44 +0200 Subject: [PATCH 03/22] Remove duplicated code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- .../powsybl/psse/model/pf/PsseSubstation.java | 237 ------------------ .../model/pf/io/PowerFlowRecordGroup.java | 13 +- .../psse/model/pf/io/SubstationData.java | 34 ++- 3 files changed, 24 insertions(+), 260 deletions(-) diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java index c5992dac222..2d181de3def 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java @@ -458,36 +458,6 @@ public PsseSubstationEquipmentTerminal copy() { copy.k = this.k; return copy; } - - public PsseSubstationEquipmentTerminalOneBus convertToEquipmentTerminalOneBus() { - PsseSubstationEquipmentTerminalOneBus oneBus = new PsseSubstationEquipmentTerminalOneBus(); - oneBus.i = i; - oneBus.ni = ni; - oneBus.type = type; - oneBus.id = id; - return oneBus; - } - - public PsseSubstationEquipmentTerminalTwoBuses convertToEquipmentTerminalTwoBuses() { - PsseSubstationEquipmentTerminalTwoBuses twoBuses = new PsseSubstationEquipmentTerminalTwoBuses(); - twoBuses.i = i; - twoBuses.ni = ni; - twoBuses.type = type; - twoBuses.id = id; - twoBuses.j = j; - return twoBuses; - } - - public PsseSubstationEquipmentTerminalThreeBuses convertToEquipmentTerminalThreeBuses() { - PsseSubstationEquipmentTerminalThreeBuses threeBuses = new PsseSubstationEquipmentTerminalThreeBuses(); - threeBuses.i = i; - threeBuses.ni = ni; - threeBuses.type = type; - threeBuses.id = id; - threeBuses.j = j; - threeBuses.k = k; - return threeBuses; - } } public static class PsseSubstationEquipmentTerminalCommonStart { @@ -506,213 +476,6 @@ public String getType() { } } - public static class PsseSubstationEquipmentTerminalOneBus { - - @Parsed - private int i; - - @Parsed - private int ni; - - @Parsed - private String type; - - @Parsed(defaultNullRead = "1 ") - private String id; - - public int getI() { - return i; - } - - public void setI(int i) { - this.i = i; - } - - public int getNi() { - return ni; - } - - public void setNi(int ni) { - this.ni = ni; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public PsseSubstationEquipmentTerminal convertToEquipmentTerminal() { - PsseSubstationEquipmentTerminal equipmentTerminal = new PsseSubstationEquipmentTerminal(); - equipmentTerminal.i = i; - equipmentTerminal.ni = ni; - equipmentTerminal.type = type; - equipmentTerminal.id = id; - equipmentTerminal.j = 0; - equipmentTerminal.k = 0; - return equipmentTerminal; - } - } - - public static class PsseSubstationEquipmentTerminalTwoBuses { - - @Parsed - private int i; - - @Parsed - private int ni; - - @Parsed - private String type; - - @Parsed - private int j = 0; - - @Parsed(defaultNullRead = "1 ") - private String id; - - public int getI() { - return i; - } - - public void setI(int i) { - this.i = i; - } - - public int getNi() { - return ni; - } - - public void setNi(int ni) { - this.ni = ni; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public int getJ() { - return j; - } - - public void setJ(int j) { - this.j = j; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public PsseSubstationEquipmentTerminal convertToEquipmentTerminal() { - PsseSubstationEquipmentTerminal equipmentTerminal = new PsseSubstationEquipmentTerminal(); - equipmentTerminal.i = i; - equipmentTerminal.ni = ni; - equipmentTerminal.type = type; - equipmentTerminal.id = id; - equipmentTerminal.j = j; - equipmentTerminal.k = 0; - return equipmentTerminal; - } - } - - public static class PsseSubstationEquipmentTerminalThreeBuses { - - @Parsed - private int i; - - @Parsed - private int ni; - - @Parsed - private String type; - - @Parsed - private int j = 0; - - @Parsed - private int k = 0; - - @Parsed(defaultNullRead = "1 ") - private String id; - - public int getI() { - return i; - } - - public void setI(int i) { - this.i = i; - } - - public int getNi() { - return ni; - } - - public void setNi(int ni) { - this.ni = ni; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public int getJ() { - return j; - } - - public void setJ(int j) { - this.j = j; - } - - public int getK() { - return k; - } - - public void setK(int k) { - this.k = k; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public PsseSubstationEquipmentTerminal convertToEquipmentTerminal() { - PsseSubstationEquipmentTerminal equipmentTerminal = new PsseSubstationEquipmentTerminal(); - equipmentTerminal.i = i; - equipmentTerminal.ni = ni; - equipmentTerminal.type = type; - equipmentTerminal.id = id; - equipmentTerminal.j = j; - equipmentTerminal.k = k; - return equipmentTerminal; - } - } - public static class PsseSubstationNodex { public PsseSubstationNodex() { diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRecordGroup.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRecordGroup.java index 935ef89253b..1f31eeaf95e 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRecordGroup.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRecordGroup.java @@ -48,13 +48,18 @@ public enum PowerFlowRecordGroup implements RecordGroupIdentification { INTERNAL_SUBSTATION_NODE("subnode"), INTERNAL_SUBSTATION_SWITCHING_DEVICE("subswd"), INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL("subterm"), - INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_COMMON_START("subterm"), - INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_ONE_BUS("subterm"), - INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_TWO_BUSES("subterm"), - INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_THREE_BUSES("subterm"); + INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_COMMON_START(), + INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_ONE_BUS(), + INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_TWO_BUSES(), + INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_THREE_BUSES(); private final String rawxNodeName; private final String rawName; + PowerFlowRecordGroup() { + this.rawxNodeName = name(); + this.rawName = name(); + } + PowerFlowRecordGroup(String rawxNodeName) { this.rawxNodeName = rawxNodeName; this.rawName = name(); diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java index eb9c0796456..cc349b4f4c9 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java @@ -91,13 +91,9 @@ private List readEquipmentTerminalData(LegacyTe line = reader.readRecordLine(); } - List equipmentTerminalOneBusList = new SubstationEquipmentTerminalDataOneBus().readFromStrings(equipmentTerminalOneBusRecords, context); - List equipmentTerminalTwoBusesList = new SubstationEquipmentTerminalDataTwoBuses().readFromStrings(equipmentTerminalTwoBusesRecords, context); - List equipmentTerminalThreeBusesList = new SubstationEquipmentTerminalDataThreeBuses().readFromStrings(equipmentTerminalThreeBusesRecords, context); - - List equipmentTerminalList = equipmentTerminalOneBusList.stream().map(PsseSubstationEquipmentTerminalOneBus::convertToEquipmentTerminal).collect(Collectors.toList()); - equipmentTerminalList.addAll(equipmentTerminalTwoBusesList.stream().map(PsseSubstationEquipmentTerminalTwoBuses::convertToEquipmentTerminal).toList()); - equipmentTerminalList.addAll(equipmentTerminalThreeBusesList.stream().map(PsseSubstationEquipmentTerminalThreeBuses::convertToEquipmentTerminal).toList()); + List equipmentTerminalList = new SubstationEquipmentTerminalDataOneBus().readFromStrings(equipmentTerminalOneBusRecords, context); + equipmentTerminalList.addAll(new SubstationEquipmentTerminalDataTwoBuses().readFromStrings(equipmentTerminalTwoBusesRecords, context)); + equipmentTerminalList.addAll(new SubstationEquipmentTerminalDataThreeBuses().readFromStrings(equipmentTerminalThreeBusesRecords, context)); return equipmentTerminalList; } @@ -131,9 +127,9 @@ public void write(List substationList, Context context, OutputSt private List writeEquipmentTerminalData(List equipmentTerminalList, Context context) { - List eqOneBus = equipmentTerminalList.stream().filter(eq -> isOneBus(eq.getType())).map(PsseSubstationEquipmentTerminal::convertToEquipmentTerminalOneBus).collect(Collectors.toList()); - List eqTwoBuses = equipmentTerminalList.stream().filter(eq -> isTwoBuses(eq.getType())).map(PsseSubstationEquipmentTerminal::convertToEquipmentTerminalTwoBuses).collect(Collectors.toList()); - List eqThreeBuses = equipmentTerminalList.stream().filter(eq -> isThreeBuses(eq.getType())).map(PsseSubstationEquipmentTerminal::convertToEquipmentTerminalThreeBuses).collect(Collectors.toList()); + List eqOneBus = equipmentTerminalList.stream().filter(eq -> isOneBus(eq.getType())).collect(Collectors.toList()); + List eqTwoBuses = equipmentTerminalList.stream().filter(eq -> isTwoBuses(eq.getType())).collect(Collectors.toList()); + List eqThreeBuses = equipmentTerminalList.stream().filter(eq -> isThreeBuses(eq.getType())).collect(Collectors.toList()); SubstationEquipmentTerminalDataOneBus oneBusData = new SubstationEquipmentTerminalDataOneBus(); List strings = oneBusData.buildRecords(eqOneBus, context.getFieldNames(INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_ONE_BUS), oneBusData.quotedFields(), context); @@ -183,39 +179,39 @@ public Class psseTypeClass() { } } - private static class SubstationEquipmentTerminalDataOneBus extends AbstractRecordGroup { + private static class SubstationEquipmentTerminalDataOneBus extends AbstractRecordGroup { SubstationEquipmentTerminalDataOneBus() { super(INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_ONE_BUS, "i", "ni", "type", "id"); withQuotedFields(QUOTED_FIELDS); } @Override - public Class psseTypeClass() { - return PsseSubstationEquipmentTerminalOneBus.class; + public Class psseTypeClass() { + return PsseSubstationEquipmentTerminal.class; } } - private static class SubstationEquipmentTerminalDataTwoBuses extends AbstractRecordGroup { + private static class SubstationEquipmentTerminalDataTwoBuses extends AbstractRecordGroup { SubstationEquipmentTerminalDataTwoBuses() { super(INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_TWO_BUSES, "i", "ni", "type", "j", "id"); withQuotedFields(QUOTED_FIELDS); } @Override - public Class psseTypeClass() { - return PsseSubstationEquipmentTerminalTwoBuses.class; + public Class psseTypeClass() { + return PsseSubstationEquipmentTerminal.class; } } - private static class SubstationEquipmentTerminalDataThreeBuses extends AbstractRecordGroup { + private static class SubstationEquipmentTerminalDataThreeBuses extends AbstractRecordGroup { SubstationEquipmentTerminalDataThreeBuses() { super(INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_THREE_BUSES, "i", "ni", "type", "j", "k", "id"); withQuotedFields(QUOTED_FIELDS); } @Override - public Class psseTypeClass() { - return PsseSubstationEquipmentTerminalThreeBuses.class; + public Class psseTypeClass() { + return PsseSubstationEquipmentTerminal.class; } } } From cab4aa15aad300da70136c6350047bdb87f28ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Marqu=C3=A9s?= Date: Thu, 11 Apr 2024 15:40:00 +0200 Subject: [PATCH 04/22] Fix code smells MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- .../powsybl/psse/model/pf/PsseSubstation.java | 18 +++++++++--------- .../psse/model/pf/io/PowerFlowRecordGroup.java | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java index 2d181de3def..06cc80eaf8a 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java @@ -30,39 +30,39 @@ public class PsseSubstation { public PsseSubstation(PsseSubstationRecord record, List nodes, List switchingDevices, List equipmentTerminals) { - this.record = record; + this.srecord = record; this.nodes = nodes; this.switchingDevices = switchingDevices; this.equipmentTerminals = equipmentTerminals; } - private final PsseSubstationRecord record; + private final PsseSubstationRecord srecord; private final List nodes; private final List switchingDevices; private final List equipmentTerminals; public int getIs() { - return record.is; + return srecord.is; } public String getName() { - return record.name; + return srecord.name; } public double getLati() { - return record.lati; + return srecord.lati; } public double getLong() { - return record.longi; + return srecord.longi; } public double getSrg() { - return record.srg; + return srecord.srg; } public PsseSubstationRecord getRecord() { - return record; + return srecord; } public List getNodes() { @@ -78,7 +78,7 @@ public List getEquipmentTerminals() { } public PsseSubstation copy() { - PsseSubstationRecord copyRecord = this.record.copy(); + PsseSubstationRecord copyRecord = this.srecord.copy(); List copyNodes = new ArrayList<>(); this.nodes.forEach(node -> copyNodes.add(node.copy())); diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRecordGroup.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRecordGroup.java index 1f31eeaf95e..058b9aee342 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRecordGroup.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/PowerFlowRecordGroup.java @@ -48,6 +48,7 @@ public enum PowerFlowRecordGroup implements RecordGroupIdentification { INTERNAL_SUBSTATION_NODE("subnode"), INTERNAL_SUBSTATION_SWITCHING_DEVICE("subswd"), INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL("subterm"), + // only needed in raw format, not used in rawx format INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_COMMON_START(), INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_ONE_BUS(), INTERNAL_SUBSTATION_EQUIPMENT_TERMINAL_TWO_BUSES(), From 67ff326dff210c2cc2e5cb361e9cd8b60dbeaa6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Marqu=C3=A9s?= Date: Thu, 11 Apr 2024 15:59:55 +0200 Subject: [PATCH 05/22] Fix code smells MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- .../com/powsybl/psse/model/pf/PsseSubstation.java | 4 ++-- .../powsybl/psse/model/pf/io/SubstationData.java | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java index 06cc80eaf8a..8d9a172ac20 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseSubstation.java @@ -27,10 +27,10 @@ public class PsseSubstation { - public PsseSubstation(PsseSubstationRecord record, + public PsseSubstation(PsseSubstationRecord srecord, List nodes, List switchingDevices, List equipmentTerminals) { - this.srecord = record; + this.srecord = srecord; this.nodes = nodes; this.switchingDevices = switchingDevices; this.equipmentTerminals = equipmentTerminals; diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java index cc349b4f4c9..2c0d8a8f232 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java @@ -54,13 +54,13 @@ public List read(LegacyTextReader reader, Context context) throw if (!reader.isQRecordFound()) { String line = reader.readRecordLine(); while (!reader.endOfBlock(line)) { - PsseSubstationRecord record = recordData.readFromStrings(Collections.singletonList(line), context).get(0); + PsseSubstationRecord srecord = recordData.readFromStrings(Collections.singletonList(line), context).get(0); List nodeList = new SubstationNodeData().read(reader, context); List switchingDeviceList = new SubstationSwitchingDeviceData().read(reader, context); List equipmentTerminalList = readEquipmentTerminalData(reader, context); - PsseSubstation substation = new PsseSubstation(record, nodeList, switchingDeviceList, equipmentTerminalList); + PsseSubstation substation = new PsseSubstation(srecord, nodeList, switchingDeviceList, equipmentTerminalList); substationList.add(substation); line = reader.readRecordLine(); @@ -262,12 +262,12 @@ private static List convertToSubstationList(List equipmentTerminalxList) { List substationList = new ArrayList<>(); - for (PsseSubstationRecord record : recordList) { - List nodeList = nodexList.stream().filter(n -> n.getIsub() == record.getIs()).map(PsseSubstationNodex::getNode).collect(Collectors.toList()); - List switchingDeviceList = switchingDevicexList.stream().filter(sd -> sd.getIsub() == record.getIs()).map(PsseSubstationSwitchingDevicex::getSwitchingDevice).collect(Collectors.toList()); - List equipmentTerminalList = equipmentTerminalxList.stream().filter(eq -> eq.getIsub() == record.getIs()).map(PsseSubstationEquipmentTerminalx::getEquipmentTerminal).collect(Collectors.toList()); + for (PsseSubstationRecord srecord : recordList) { + List nodeList = nodexList.stream().filter(n -> n.getIsub() == srecord.getIs()).map(PsseSubstationNodex::getNode).collect(Collectors.toList()); + List switchingDeviceList = switchingDevicexList.stream().filter(sd -> sd.getIsub() == srecord.getIs()).map(PsseSubstationSwitchingDevicex::getSwitchingDevice).collect(Collectors.toList()); + List equipmentTerminalList = equipmentTerminalxList.stream().filter(eq -> eq.getIsub() == srecord.getIs()).map(PsseSubstationEquipmentTerminalx::getEquipmentTerminal).collect(Collectors.toList()); - substationList.add(new PsseSubstation(record, nodeList, switchingDeviceList, equipmentTerminalList)); + substationList.add(new PsseSubstation(srecord, nodeList, switchingDeviceList, equipmentTerminalList)); } return substationList; } From b39afefc526d2094508abe67017a3db4c224098f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Marqu=C3=A9s?= Date: Wed, 17 Apr 2024 10:34:54 +0200 Subject: [PATCH 06/22] nodeBreaker convert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- .../iidm/network/util/ContainersMapping.java | 4 + .../psse/converter/AbstractConverter.java | 90 ++++ .../powsybl/psse/converter/BusConverter.java | 110 ++++- .../FixedShuntCompensatorConverter.java | 25 +- .../psse/converter/GeneratorConverter.java | 52 ++- .../powsybl/psse/converter/LineConverter.java | 36 +- .../powsybl/psse/converter/LoadConverter.java | 31 +- .../psse/converter/NodeBreakerExport.java | 122 +++++ .../psse/converter/NodeBreakerImport.java | 92 ++++ .../psse/converter/NodeBreakerValidation.java | 228 ++++++++++ .../powsybl/psse/converter/PsseExporter.java | 27 +- .../powsybl/psse/converter/PsseImporter.java | 70 +-- .../psse/converter/SlackConverter.java | 17 +- .../SwitchedShuntCompensatorConverter.java | 52 ++- .../psse/converter/TransformerConverter.java | 231 ++++++---- .../converter/TwoTerminalDcConverter.java | 32 +- .../psse/converter/VoltageLevelConverter.java | 299 ++++++++++++- .../psse/converter/PsseExporterTest.java | 25 +- .../psse/converter/PsseImporterTest.java | 16 +- .../src/test/resources/ExampleVersion32.xiidm | 17 +- .../src/test/resources/IEEE_118_bus.xiidm | 417 ++++++++---------- .../src/test/resources/IEEE_14_bus.xiidm | 43 +- .../IEEE_14_bus_nodeBreaker_rev35.xiidm | 156 +++++++ ...IEEE_14_bus_nodeBreaker_rev35_exported.raw | 131 ++++++ ...s_nodeBreaker_rev35_split_bus_exported.raw | 133 ++++++ .../IEEE_14_buses_duplicate_ids.xiidm | 52 +-- .../IEEE_14_buses_duplicate_ids_rev35.xiidm | 51 +-- .../resources/IEEE_14_buses_zip_load.xiidm | 43 +- .../resources/IEEE_14_isolated_buses.xiidm | 49 +- .../src/test/resources/IEEE_24_bus.xiidm | 86 ++-- .../src/test/resources/IEEE_30_bus.xiidm | 85 ++-- .../src/test/resources/IEEE_57_bus.xiidm | 167 ++++--- .../RawCaseWithSpecialCharacters.xiidm | 13 +- .../src/test/resources/SwitchedShunt.xiidm | 15 +- .../SwitchedShuntWithZeroVswlo.xiidm | 15 +- .../resources/ThreeMIB_T3W_modified.xiidm | 13 +- .../test/resources/ThreeMIB_T3W_phase.xiidm | 13 +- .../resources/TransformersWithZeroNomV.xiidm | 13 +- ...allelTwoTerminalDcBetweenSameAcBuses.xiidm | 24 +- .../src/test/resources/remoteControl.xiidm | 26 +- .../src/test/resources/twoTerminalDc.xiidm | 24 +- .../twoTerminalDc_with_negative_setvl.xiidm | 24 +- 42 files changed, 2288 insertions(+), 881 deletions(-) create mode 100644 psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerExport.java create mode 100644 psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerImport.java create mode 100644 psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java create mode 100644 psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm create mode 100644 psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw create mode 100644 psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/ContainersMapping.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/ContainersMapping.java index 2050ebed91d..fad62515695 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/ContainersMapping.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/ContainersMapping.java @@ -30,6 +30,10 @@ public class ContainersMapping { private final Map voltageLevelIdToSubstationId = new HashMap<>(); + public Set getBusesSet(String voltageLevelId) { + return voltageLevelIdToBusNums.containsKey(voltageLevelId) ? voltageLevelIdToBusNums.get(voltageLevelId) : new HashSet<>(); + } + public String getVoltageLevelId(int num) { String voltageLevelId = busNumToVoltageLevelId.get(num); if (voltageLevelId == null) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java index 64ec71aafc6..b4cef520b0f 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java @@ -7,8 +7,15 @@ */ package com.powsybl.psse.converter; +import java.util.Comparator; +import java.util.List; import java.util.Objects; +import java.util.Set; +import com.powsybl.iidm.network.Terminal; +import com.powsybl.iidm.network.VoltageLevel; +import com.powsybl.iidm.network.util.Networks; +import com.powsybl.psse.model.PsseException; import org.apache.commons.math3.complex.Complex; import com.powsybl.iidm.network.Network; @@ -20,6 +27,31 @@ */ public abstract class AbstractConverter { + enum PsseEquipmentType { + PSSE_LOAD("L"), + PSSE_FIXED_SHUNT("F"), + PSSE_GENERATOR("M"), + PSSE_BRANCH("B"), + PSSE_TWO_WINDING("2"), + PSSE_THREE_WINDING("3"), + PSSE_SWITCHED_SHUNT("s"), + PSSE_INDUCTION_MACHINE("I"), + PSSE_TWO_TERMINAL_DC_LINE("D"), + PSSE_VSC_DC_LINE("V"), + PSSE_MULTI_TERMINAL_LINE("N"), + PSSE_FACTS_DEVICE("A"); + + private final String textCode; + + PsseEquipmentType(String textCode) { + this.textCode = textCode; + } + + private String getTextCode() { + return textCode; + } + } + AbstractConverter(ContainersMapping containersMapping, Network network) { this.containersMapping = Objects.requireNonNull(containersMapping); this.network = Objects.requireNonNull(network); @@ -33,10 +65,68 @@ Network getNetwork() { return network; } + static String getVoltageLevelId(Set busNums) { + return "VL" + busNums.stream().min(Comparator.naturalOrder()).orElseThrow(() -> new PsseException("Unexpected empty busNums")); + } + static String getBusId(int busNum) { return "B" + busNum; } + static String getNodeBreakerEquipmentIdBus(String equipmentId, int bus) { + return equipmentId + "." + bus; + } + + // EquipmentId must be independent of the bus order + static String getNodeBreakerEquipmentId(String type, int busI, int busJ, int busK, String id) { + List sortedBuses = List.of(busI, busJ, busK).stream().sorted().toList(); + int bus1 = sortedBuses.get(0); + int bus2 = sortedBuses.get(1); + int bus3 = sortedBuses.get(2); + + // after sorting, zeros will be at the beginning + if (bus1 == 0 && bus2 == 0) { + return type + "." + bus3 + "." + id; + } else if (bus1 == 0) { + return type + "." + bus2 + "." + bus3 + "." + id; + } else { + return type + "." + bus1 + "." + bus2 + "." + "." + bus3 + id; + } + } + + static String getNodeBreakerEquipmentId(PsseEquipmentType equipmentType, int busI, String id) { + return equipmentType.getTextCode() + "." + busI + "." + id; + } + + static String getNodeBreakerEquipmentId(PsseEquipmentType equipmentType, int busI, int busJ, String id) { + List sortedBuses = List.of(busI, busJ).stream().sorted().toList(); + int bus1 = sortedBuses.get(0); + int bus2 = sortedBuses.get(1); + return equipmentType.getTextCode() + "." + bus1 + "." + bus2 + "." + id; + } + + static String getNodeBreakerEquipmentId(PsseEquipmentType equipmentType, int busI, int busJ, int busK, String id) { + List sortedBuses = List.of(busI, busJ, busK).stream().sorted().toList(); + int bus1 = sortedBuses.get(0); + int bus2 = sortedBuses.get(1); + int bus3 = sortedBuses.get(2); + return equipmentType.getTextCode() + "." + bus1 + "." + bus2 + "." + bus3 + "." + id; + } + + static int obtainBus(NodeBreakerExport nodeBreakerExport, String equipmentId, int bus) { + return nodeBreakerExport.getEquipmentIdBusBus(getNodeBreakerEquipmentIdBus(equipmentId, bus)).orElseGet(() -> bus); + } + + static Terminal obtainTerminalNode(Network network, String voltageLevelId, int node) { + VoltageLevel voltageLevel = network.getVoltageLevel(voltageLevelId); + return voltageLevel != null ? obtainTerminalNode(voltageLevel, node) : null; + } + + static Terminal obtainTerminalNode(VoltageLevel voltageLevel, int node) { + return voltageLevel.getNodeBreakerView().getOptionalTerminal(node) + .orElseGet(() -> Networks.getEquivalentTerminal(voltageLevel, node)); + } + static Complex impedanceToEngineeringUnits(Complex impedance, double vnom, double sbase) { return impedance.multiply(vnom * vnom / sbase); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java index aff238867ca..f5e6e62b78c 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java @@ -7,14 +7,16 @@ */ package com.powsybl.psse.converter; -import java.util.Objects; +import java.util.*; import com.powsybl.iidm.network.Bus; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.VoltageLevel; import com.powsybl.iidm.network.util.ContainersMapping; +import com.powsybl.psse.model.PsseException; import com.powsybl.psse.model.pf.PsseBus; import com.powsybl.psse.model.pf.PssePowerFlowModel; +import org.apache.commons.lang3.StringUtils; /** * @author Luma Zamarreño {@literal } @@ -22,36 +24,108 @@ */ class BusConverter extends AbstractConverter { - BusConverter(PsseBus psseBus, ContainersMapping containerMapping, Network network) { + private static final int MAX_BUS_LENGTH = 12; + + BusConverter(PsseBus psseBus, ContainersMapping containerMapping, Network network, NodeBreakerImport nodeBreakerImport) { super(containerMapping, network); this.psseBus = Objects.requireNonNull(psseBus); + this.nodeBreakerImport = Objects.requireNonNull(nodeBreakerImport); } void create(VoltageLevel voltageLevel) { + // The bus is only created in busBranch voltage levels, when bus is a connectivity bus. + if (nodeBreakerImport.isTopologicalBus(psseBus.getI())) { + return; + } + String busId = getBusId(psseBus.getI()); Bus bus = voltageLevel.getBusBreakerView().newBus() - .setId(busId) - .setName(psseBus.getName()) - .add(); + .setId(busId) + .setName(psseBus.getName()) + .add(); bus.setV(psseBus.getVm() * voltageLevel.getNominalV()) - .setAngle(psseBus.getVa()); + .setAngle(psseBus.getVa()); } - // At the moment we do not consider new buses - static void updateBuses(Network network, PssePowerFlowModel psseModel) { + // At the moment we only consider new buses created by opening switches in nodeBreaker substations + static void updateBuses(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { + Map busNumToPsseBus = new HashMap<>(); + psseModel.getBuses().forEach(psseBus -> { - String busId = AbstractConverter.getBusId(psseBus.getI()); - Bus bus = network.getBusBreakerView().getBus(busId); - if (bus == null) { - psseBus.setVm(0.0); - psseBus.setVa(0.0); - psseBus.setIde(4); - } else { - psseBus.setVm(bus.getV() / bus.getVoltageLevel().getNominalV()); - psseBus.setVa(bus.getAngle()); - } + + String busId = nodeBreakerExport.getBusBreakerBusId(psseBus.getI()).orElseGet(() -> AbstractConverter.getBusId(psseBus.getI())); + int type = nodeBreakerExport.getBusType(psseBus.getI()).orElseGet(psseBus::getIde); + + updatePsseBus(network, busId, psseBus, type); + + busNumToPsseBus.put(psseBus.getI(), psseBus); }); + + // create new psse buses + List addedBuses = new ArrayList<>(); + nodeBreakerExport.getNewBusesSet().stream().sorted().forEach(newBus -> { + int copyBus = nodeBreakerExport.getNewBusCopyBus(newBus).orElseThrow(); + String busBreakerId = nodeBreakerExport.getNewBusBusBreakerId(newBus).orElseThrow(); + int type = nodeBreakerExport.getNewBusType(newBus).orElseThrow(); + + PsseBus psseBus = createNewBus(copyBus, newBus, busNumToPsseBus); + updatePsseBus(network, busBreakerId, psseBus, type); + + addedBuses.add(psseBus); + }); + + psseModel.addBuses(addedBuses); + } + + private static PsseBus createNewBus(int copyBus, int newBus, Map busNumToPsseBus) { + PsseBus psseBusToBeCopied = obtainPsseBus(copyBus, busNumToPsseBus); + PsseBus psseBus = psseBusToBeCopied.copy(); + psseBus.setI(newBus); + psseBus.setName(obtainNewBusName(psseBus.getName().trim(), "-" + newBus)); + return psseBus; + } + + // new bus name is obtained by adding "-" + newBus, but MAX_BUS_LENGTH must be ensured + private static String obtainNewBusName(String baseName, String tag) { + int newLength = baseName.length() + tag.length(); + if (newLength < MAX_BUS_LENGTH) { + return StringUtils.rightPad(baseName + tag, MAX_BUS_LENGTH, " "); + } else if (newLength == MAX_BUS_LENGTH) { + return baseName + tag; + } else { + return baseName.substring(0, MAX_BUS_LENGTH - tag.length()) + tag; + } + } + + private static PsseBus obtainPsseBus(int bus, Map busNumToPsseBus) { + if (busNumToPsseBus.containsKey(bus)) { + return busNumToPsseBus.get(bus); + } else { + throw new PsseException("Unexpected null PsseBus for " + bus); + } + } + + private static void updatePsseBus(Network network, String busId, PsseBus psseBus, int type) { + Bus bus = network.getBusBreakerView().getBus(busId); + if (bus == null) { + psseBus.setVm(0.0); + psseBus.setVa(0.0); + psseBus.setIde(4); + } else { + psseBus.setVm(getVm(bus)); + psseBus.setVa(getVa(bus)); + psseBus.setIde(type); + } + } + + private static double getVm(Bus bus) { + return Double.isFinite(bus.getV()) && bus.getV() > 0.0 ? bus.getV() / bus.getVoltageLevel().getNominalV() : 1.0; + } + + private static double getVa(Bus bus) { + return Double.isFinite(bus.getAngle()) ? bus.getAngle() : 0.0; } private final PsseBus psseBus; + private final NodeBreakerImport nodeBreakerImport; } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java index 45e6e035bf6..a9d9f9b3561 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java @@ -8,6 +8,7 @@ package com.powsybl.psse.converter; import java.util.Objects; +import java.util.OptionalInt; import com.powsybl.iidm.network.*; import org.slf4j.Logger; @@ -17,15 +18,18 @@ import com.powsybl.psse.model.pf.PsseFixedShunt; import com.powsybl.psse.model.pf.PssePowerFlowModel; +import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_FIXED_SHUNT; + /** * @author Luma Zamarreño {@literal } * @author José Antonio Marqués {@literal } */ class FixedShuntCompensatorConverter extends AbstractConverter { - FixedShuntCompensatorConverter(PsseFixedShunt psseFixedShunt, ContainersMapping containerMapping, Network network) { + FixedShuntCompensatorConverter(PsseFixedShunt psseFixedShunt, ContainersMapping containerMapping, Network network, NodeBreakerImport nodeBreakerImport) { super(containerMapping, network); this.psseFixedShunt = Objects.requireNonNull(psseFixedShunt); + this.nodeBreakerImport = Objects.requireNonNull(nodeBreakerImport); } void create() { @@ -39,7 +43,6 @@ void create() { .getVoltageLevel(getContainersMapping().getVoltageLevelId(psseFixedShunt.getI())); ShuntCompensatorAdder adder = voltageLevel.newShuntCompensator() .setId(getShuntId(busId)) - .setConnectableBus(busId) .setVoltageRegulatorOn(false) .setSectionCount(1); adder.newLinearModel() @@ -48,7 +51,15 @@ void create() { .setMaximumSectionCount(1) .add(); - adder.setBus(psseFixedShunt.getStatus() == 1 ? busId : null); + String equipmentId = getNodeBreakerEquipmentId(PSSE_FIXED_SHUNT, psseFixedShunt.getI(), psseFixedShunt.getId()); + OptionalInt node = nodeBreakerImport.getNode(getNodeBreakerEquipmentIdBus(equipmentId, psseFixedShunt.getI())); + if (node.isPresent()) { + adder.setNode(node.getAsInt()); + } else { + adder.setConnectableBus(busId); + adder.setBus(psseFixedShunt.getStatus() == 1 ? busId : null); + } + adder.add(); } @@ -61,21 +72,24 @@ private static String getShuntId(String busId, String fixedShuntId) { } // At the moment we do not consider new fixedShunts - static void updateFixedShunts(Network network, PssePowerFlowModel psseModel) { + static void updateFixedShunts(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { psseModel.getFixedShunts().forEach(psseFixedShunt -> { String fixedShuntId = getShuntId(getBusId(psseFixedShunt.getI()), psseFixedShunt.getId()); ShuntCompensator fixedShunt = network.getShuntCompensator(fixedShuntId); + int bus = obtainBus(nodeBreakerExport, getNodeBreakerEquipmentId(PSSE_FIXED_SHUNT, psseFixedShunt.getI(), psseFixedShunt.getId()), psseFixedShunt.getI()); + if (fixedShunt == null) { psseFixedShunt.setStatus(0); } else { psseFixedShunt.setStatus(getStatus(fixedShunt)); psseFixedShunt.setBl(getQ(fixedShunt)); } + psseFixedShunt.setI(bus); }); } private static int getStatus(ShuntCompensator fixedShunt) { - if (fixedShunt.getTerminal().isConnected()) { + if (fixedShunt.getTerminal().isConnected() && fixedShunt.getTerminal().getBusBreakerView().getBus() != null) { return 1; } else { return 0; @@ -88,6 +102,7 @@ private static double getQ(ShuntCompensator fixedShunt) { } private final PsseFixedShunt psseFixedShunt; + private final NodeBreakerImport nodeBreakerImport; private static final Logger LOGGER = LoggerFactory.getLogger(FixedShuntCompensatorConverter.class); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java index 266a824fff6..e18ab9278f1 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java @@ -8,6 +8,8 @@ package com.powsybl.psse.converter; import java.util.Objects; +import java.util.Optional; +import java.util.OptionalInt; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,19 +21,23 @@ import com.powsybl.iidm.network.Terminal; import com.powsybl.iidm.network.VoltageLevel; import com.powsybl.iidm.network.util.ContainersMapping; +import com.powsybl.psse.converter.NodeBreakerImport.NodeBreakerControlNode; import com.powsybl.psse.model.pf.PsseBus; import com.powsybl.psse.model.pf.PsseGenerator; import com.powsybl.psse.model.pf.PssePowerFlowModel; +import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_GENERATOR; + /** * @author Luma Zamarreño {@literal } * @author José Antonio Marqués {@literal } */ class GeneratorConverter extends AbstractConverter { - GeneratorConverter(PsseGenerator psseGenerator, ContainersMapping containerMapping, Network network) { + GeneratorConverter(PsseGenerator psseGenerator, ContainersMapping containerMapping, Network network, NodeBreakerImport nodeBreakerImport) { super(containerMapping, network); this.psseGenerator = Objects.requireNonNull(psseGenerator); + this.nodeBreakerImport = Objects.requireNonNull(nodeBreakerImport); } void create() { @@ -39,14 +45,21 @@ void create() { VoltageLevel voltageLevel = getNetwork().getVoltageLevel(getContainersMapping().getVoltageLevelId(psseGenerator.getI())); GeneratorAdder adder = voltageLevel.newGenerator() .setId(getGeneratorId(busId, psseGenerator)) - .setConnectableBus(busId) .setTargetP(psseGenerator.getPg()) .setMaxP(psseGenerator.getPt()) .setMinP(psseGenerator.getPb()) .setTargetQ(psseGenerator.getQg()) .setVoltageRegulatorOn(false); - adder.setBus(psseGenerator.getStat() == 1 ? busId : null); + String equipmentId = getNodeBreakerEquipmentId(PSSE_GENERATOR, psseGenerator.getI(), psseGenerator.getId()); + OptionalInt node = nodeBreakerImport.getNode(getNodeBreakerEquipmentIdBus(equipmentId, psseGenerator.getI())); + if (node.isPresent()) { + adder.setNode(node.getAsInt()); + } else { + adder.setConnectableBus(busId); + adder.setBus(psseGenerator.getStat() == 1 ? busId : null); + } + Generator generator = adder.add(); generator.newMinMaxReactiveLimits() @@ -68,7 +81,7 @@ void addControl(PsseBus psseBus) { return; } - Terminal regulatingTerminal = defineRegulatingTerminal(psseGenerator, getNetwork()); + Terminal regulatingTerminal = defineRegulatingTerminal(psseGenerator, getNetwork(), generator, nodeBreakerImport); // Discard control if the generator is controlling an isolated bus if (regulatingTerminal == null) { return; @@ -90,22 +103,25 @@ private static boolean defineVoltageRegulatorOn(PsseBus psseBus) { return psseBus.getIde() == 2 || psseBus.getIde() == 3; } - // Nreg (version 35) is not yet considered - private static Terminal defineRegulatingTerminal(PsseGenerator psseGenerator, Network network) { - String defaultRegulatingBusId = getBusId(psseGenerator.getI()); + private static Terminal defineRegulatingTerminal(PsseGenerator psseGenerator, Network network, Generator generator, NodeBreakerImport nodeBreakerImport) { Terminal regulatingTerminal = null; if (psseGenerator.getIreg() == 0) { - Bus bus = network.getBusBreakerView().getBus(defaultRegulatingBusId); - regulatingTerminal = bus.getConnectedTerminalStream().findFirst().orElse(null); + regulatingTerminal = generator.getTerminal(); } else { - String regulatingBusId = getBusId(psseGenerator.getIreg()); - Bus bus = network.getBusBreakerView().getBus(regulatingBusId); - if (bus != null) { - regulatingTerminal = bus.getConnectedTerminalStream().findFirst().orElse(null); + String equipmentId = getNodeBreakerEquipmentId(PSSE_GENERATOR, psseGenerator.getI(), psseGenerator.getId()); + Optional controlNode = nodeBreakerImport.getControlNode(getNodeBreakerEquipmentIdBus(equipmentId, psseGenerator.getIreg())); + if (controlNode.isPresent()) { + regulatingTerminal = obtainTerminalNode(network, controlNode.get().getVoltageLevelId(), controlNode.get().getNode()); + } else { + String regulatingBusId = getBusId(psseGenerator.getIreg()); + Bus bus = network.getBusBreakerView().getBus(regulatingBusId); + if (bus != null) { + regulatingTerminal = bus.getConnectedTerminalStream().findFirst().orElse(null); + } } } if (regulatingTerminal == null) { - String generatorId = getGeneratorId(defaultRegulatingBusId, psseGenerator); + String generatorId = getGeneratorId(getBusId(psseGenerator.getI()), psseGenerator.getId()); LOGGER.warn("Generator {}. Regulating terminal is not assigned as the bus is isolated", generatorId); } return regulatingTerminal; @@ -120,10 +136,12 @@ private static String getGeneratorId(String busId, String generatorId) { } // At the moment we do not consider new generators - static void updateGenerators(Network network, PssePowerFlowModel psseModel) { + static void updateGenerators(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { psseModel.getGenerators().forEach(psseGen -> { String genId = getGeneratorId(getBusId(psseGen.getI()), psseGen.getId()); Generator gen = network.getGenerator(genId); + int bus = obtainBus(nodeBreakerExport, getNodeBreakerEquipmentId(PSSE_GENERATOR, psseGen.getI(), psseGen.getId()), psseGen.getI()); + if (gen == null) { psseGen.setStat(0); } else { @@ -131,11 +149,12 @@ static void updateGenerators(Network network, PssePowerFlowModel psseModel) { psseGen.setPg(getP(gen)); psseGen.setQg(getQ(gen)); } + psseGen.setI(bus); }); } private static int getStatus(Generator gen) { - if (gen.getTerminal().isConnected()) { + if (gen.getTerminal().isConnected() && gen.getTerminal().getBusBreakerView().getBus() != null) { return 1; } else { return 0; @@ -159,6 +178,7 @@ private static double getQ(Generator gen) { } private final PsseGenerator psseGenerator; + private final NodeBreakerImport nodeBreakerImport; private static final Logger LOGGER = LoggerFactory.getLogger(GeneratorConverter.class); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java index 542b219ae03..b12faf05c17 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java @@ -22,9 +22,11 @@ import com.powsybl.psse.model.pf.PsseNonTransformerBranch; import com.powsybl.psse.model.pf.PssePowerFlowModel; +import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_BRANCH; import static com.powsybl.psse.model.PsseVersion.Major.V35; import java.util.Objects; +import java.util.OptionalInt; /** * @author Luma Zamarreño {@literal } @@ -32,11 +34,12 @@ */ class LineConverter extends AbstractConverter { - LineConverter(PsseNonTransformerBranch psseLine, ContainersMapping containerMapping, PerUnitContext perUnitContext, Network network, PsseVersion version) { + LineConverter(PsseNonTransformerBranch psseLine, ContainersMapping containerMapping, PerUnitContext perUnitContext, Network network, PsseVersion version, NodeBreakerImport nodeBreakerImport) { super(containerMapping, network); this.psseLine = Objects.requireNonNull(psseLine); this.perUnitContext = Objects.requireNonNull(perUnitContext); this.version = Objects.requireNonNull(version); + this.nodeBreakerImport = nodeBreakerImport; } void create() { @@ -62,9 +65,7 @@ void create() { LineAdder adder = getNetwork().newLine() .setId(id) .setEnsureIdUnicity(true) - .setConnectableBus1(bus1Id) .setVoltageLevel1(voltageLevel1Id) - .setConnectableBus2(bus2Id) .setVoltageLevel2(voltageLevel2Id) .setR(rEu) .setX(xEu) @@ -73,8 +74,21 @@ void create() { .setG2(g2Eu) .setB2(b2Eu); - adder.setBus1(psseLine.getSt() == 1 ? bus1Id : null); - adder.setBus2(psseLine.getSt() == 1 ? bus2Id : null); + String equipmentId = getNodeBreakerEquipmentId(PSSE_BRANCH, psseLine.getI(), psseLine.getJ(), psseLine.getCkt()); + OptionalInt node1 = nodeBreakerImport.getNode(getNodeBreakerEquipmentIdBus(equipmentId, psseLine.getI())); + if (node1.isPresent()) { + adder.setNode1(node1.getAsInt()); + } else { + adder.setConnectableBus1(bus1Id); + adder.setBus1(psseLine.getSt() == 1 ? bus1Id : null); + } + OptionalInt node2 = nodeBreakerImport.getNode(getNodeBreakerEquipmentIdBus(equipmentId, psseLine.getJ())); + if (node2.isPresent()) { + adder.setNode2(node2.getAsInt()); + } else { + adder.setConnectableBus2(bus2Id); + adder.setBus2(psseLine.getSt() == 1 ? bus2Id : null); + } Line line = adder.add(); defineOperationalLimits(line, voltageLevel1.getNominalV(), voltageLevel2.getNominalV()); @@ -118,20 +132,27 @@ private static String getLineId(PsseNonTransformerBranch psseLine) { } // At the moment we do not consider new lines and antenna lines are exported as open - static void updateLines(Network network, PssePowerFlowModel psseModel) { + static void updateLines(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { psseModel.getNonTransformerBranches().forEach(psseLine -> { String lineId = getLineId(psseLine); Line line = network.getLine(lineId); + String equipmentId = getNodeBreakerEquipmentId(PSSE_BRANCH, psseLine.getI(), psseLine.getJ(), psseLine.getCkt()); + int busI = obtainBus(nodeBreakerExport, equipmentId, psseLine.getI()); + int busJ = obtainBus(nodeBreakerExport, equipmentId, psseLine.getJ()); + if (line == null) { psseLine.setSt(0); } else { psseLine.setSt(getStatus(line)); } + psseLine.setI(busI); + psseLine.setJ(busJ); }); } private static int getStatus(Line line) { - if (line.getTerminal1().isConnected() && line.getTerminal2().isConnected()) { + if (line.getTerminal1().isConnected() && line.getTerminal1().getBusBreakerView().getBus() != null + && line.getTerminal2().isConnected() && line.getTerminal2().getBusBreakerView().getBus() != null) { return 1; } else { return 0; @@ -141,6 +162,7 @@ private static int getStatus(Line line) { private final PsseNonTransformerBranch psseLine; private final PerUnitContext perUnitContext; private final PsseVersion version; + private final NodeBreakerImport nodeBreakerImport; private static final Logger LOGGER = LoggerFactory.getLogger(LineConverter.class); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java index d4bcc25ab5e..0edb6ec34b9 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java @@ -8,24 +8,25 @@ package com.powsybl.psse.converter; import java.util.Objects; +import java.util.OptionalInt; -import com.powsybl.iidm.network.Load; -import com.powsybl.iidm.network.LoadAdder; -import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.VoltageLevel; +import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.util.ContainersMapping; import com.powsybl.psse.model.pf.PsseLoad; import com.powsybl.psse.model.pf.PssePowerFlowModel; +import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_LOAD; + /** * @author Luma Zamarreño {@literal } * @author José Antonio Marqués {@literal } */ class LoadConverter extends AbstractConverter { - LoadConverter(PsseLoad psseLoad, ContainersMapping containerMapping, Network network) { + LoadConverter(PsseLoad psseLoad, ContainersMapping containerMapping, Network network, NodeBreakerImport nodeBreakerImport) { super(containerMapping, network); this.psseLoad = Objects.requireNonNull(psseLoad); + this.nodeBreakerImport = Objects.requireNonNull(nodeBreakerImport); } void create() { @@ -39,7 +40,7 @@ void create() { LoadAdder adder = voltageLevel.newLoad() .setId(getLoadId(busId)) - .setConnectableBus(busId) + .setP0(p0) .setQ0(q0); @@ -79,7 +80,15 @@ void create() { .add(); } - adder.setBus(psseLoad.getStatus() == 1 ? busId : null); + String equipmentId = getNodeBreakerEquipmentId(PSSE_LOAD, psseLoad.getI(), psseLoad.getId()); + OptionalInt node = nodeBreakerImport.getNode(getNodeBreakerEquipmentIdBus(equipmentId, psseLoad.getI())); + if (node.isPresent()) { + adder.setNode(node.getAsInt()); + } else { + adder.setConnectableBus(busId); + adder.setBus(psseLoad.getStatus() == 1 ? busId : null); + } + adder.add(); } @@ -92,10 +101,12 @@ private static String getLoadId(String busId, String loadId) { } // At the moment we do not consider new loads - static void updateLoads(Network network, PssePowerFlowModel psseModel) { + static void updateLoads(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { psseModel.getLoads().forEach(psseLoad -> { String loadId = getLoadId(getBusId(psseLoad.getI()), psseLoad.getId()); Load load = network.getLoad(loadId); + int bus = obtainBus(nodeBreakerExport, getNodeBreakerEquipmentId(PSSE_LOAD, psseLoad.getI(), psseLoad.getId()), psseLoad.getI()); + if (load == null) { psseLoad.setStatus(0); } else { @@ -103,11 +114,12 @@ static void updateLoads(Network network, PssePowerFlowModel psseModel) { psseLoad.setPl(getP(load)); psseLoad.setQl(getQ(load)); } + psseLoad.setI(bus); }); } private static int getStatus(Load load) { - if (load.getTerminal().isConnected()) { + if (load.getTerminal().isConnected() && load.getTerminal().getBusBreakerView().getBus() != null) { return 1; } else { return 0; @@ -131,4 +143,5 @@ private static double getQ(Load load) { } private final PsseLoad psseLoad; + private final NodeBreakerImport nodeBreakerImport; } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerExport.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerExport.java new file mode 100644 index 00000000000..15920c52cd4 --- /dev/null +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerExport.java @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.psse.converter; + +import org.jgrapht.alg.util.Pair; + +import java.util.*; + +/** + * @author Luma Zamarreño {@literal } + * @author José Antonio Marqués {@literal } + */ +final class NodeBreakerExport { + private int maxPsseBus; + private final Map newBuses; + private final Map> buses; + private final Set isolatedBuses; + private final Map> nodeBus; + private final Map equipmentIdBusBus; + + NodeBreakerExport(int maxPsseBus) { + this.maxPsseBus = maxPsseBus; + this.newBuses = new HashMap<>(); + this.buses = new HashMap<>(); + this.isolatedBuses = new HashSet<>(); + this.nodeBus = new HashMap<>(); + this.equipmentIdBusBus = new HashMap<>(); + } + + int getNewPsseBus() { + return ++maxPsseBus; + } + + void addNewBus(int newBus, int copyBus, String busBreakerBusId, int type) { + newBuses.put(newBus, new NodeBreakerNewBus(copyBus, busBreakerBusId, type)); + } + + Set getNewBusesSet() { + return newBuses.keySet(); + } + + OptionalInt getNewBusCopyBus(int newBus) { + return newBuses.containsKey(newBus) ? OptionalInt.of(newBuses.get(newBus).busCopy) : OptionalInt.empty(); + } + + Optional getNewBusBusBreakerId(int newBus) { + return newBuses.containsKey(newBus) ? Optional.of(newBuses.get(newBus).busBreakerId) : Optional.empty(); + } + + OptionalInt getNewBusType(int newBus) { + return newBuses.containsKey(newBus) ? OptionalInt.of(newBuses.get(newBus).type) : OptionalInt.empty(); + } + + void addBusMapping(int bus, String busBreakerBusId, int type) { + this.buses.put(bus, Pair.of(busBreakerBusId, type)); + } + + Optional getBusBreakerBusId(int bus) { + return this.buses.containsKey(bus) ? Optional.of(this.buses.get(bus).getFirst()) : Optional.empty(); + } + + OptionalInt getBusType(int bus) { + return this.buses.containsKey(bus) ? OptionalInt.of(this.buses.get(bus).getSecond()) : OptionalInt.empty(); + } + + void addIsolatedBus(int bus) { + this.isolatedBuses.add(bus); + } + + boolean isFreeBus(int bus) { + return !(this.buses.containsKey(bus) || this.isolatedBuses.contains(bus)); + } + + void addNodesBusMapping(String voltageLevelId, List nodes, int bus, boolean inService) { + nodes.forEach(node -> addNodeBusMapping(voltageLevelId, node, bus, inService)); + } + + void addNodeBusMapping(String voltageLevelId, int node, int bus, boolean inService) { + this.nodeBus.put(getNodeId(voltageLevelId, node), Pair.of(bus, inService)); + } + + OptionalInt getNodeBus(String voltageLevelId, int node) { + return this.nodeBus.containsKey(getNodeId(voltageLevelId, node)) ? OptionalInt.of(this.nodeBus.get(getNodeId(voltageLevelId, node)).getFirst()) : OptionalInt.empty(); + } + + Optional isNodeInService(String voltageLevelId, int node) { + return this.nodeBus.containsKey(getNodeId(voltageLevelId, node)) ? Optional.of(this.nodeBus.get(getNodeId(voltageLevelId, node)).getSecond()) : Optional.empty(); + } + + boolean isFreeNode(String voltageLevelId, int node) { + return !this.nodeBus.containsKey(getNodeId(voltageLevelId, node)); + } + + private static String getNodeId(String voltageLevelId, int node) { + return voltageLevelId + "-" + node; + } + + void addEquipmentIdBus(String equipmentIdBusBus, int bus) { + this.equipmentIdBusBus.put(equipmentIdBusBus, bus); + } + + OptionalInt getEquipmentIdBusBus(String equipmentIdBusBus) { + return this.equipmentIdBusBus.containsKey(equipmentIdBusBus) ? OptionalInt.of(this.equipmentIdBusBus.get(equipmentIdBusBus)) : OptionalInt.empty(); + } + + private static final class NodeBreakerNewBus { + private final int busCopy; + private final String busBreakerId; + private final int type; + + private NodeBreakerNewBus(int busCopy, String busBreakerId, int type) { + this.busCopy = busCopy; + this.busBreakerId = busBreakerId; + this.type = type; + } + } +} diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerImport.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerImport.java new file mode 100644 index 00000000000..86ad628268d --- /dev/null +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerImport.java @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.psse.converter; + +import java.util.*; + +/** + * @author Luma Zamarreño {@literal } + * @author José Antonio Marqués {@literal } + */ +final class NodeBreakerImport { + + private final Set topologicalBuses; + private final Map equipmentIdBusNode; + private final Map equipmentIdBusControlNode; + + private final Map slackBusControlNode; + + NodeBreakerImport() { + this.topologicalBuses = new HashSet<>(); // buses not used for defining the connectivity + this.equipmentIdBusNode = new HashMap<>(); + this.equipmentIdBusControlNode = new HashMap<>(); + this.slackBusControlNode = new HashMap<>(); + } + + void addTopologicalBuses(Set buses) { + topologicalBuses.addAll(buses); + } + + boolean isTopologicalBus(int bus) { + return topologicalBuses.contains(bus); + } + + void addEquipment(String equipmentIdBus, int node) { + equipmentIdBusNode.put(equipmentIdBus, node); + } + + OptionalInt getNode(String equipmentIdBus) { + if (equipmentIdBusNode.containsKey(equipmentIdBus)) { + return OptionalInt.of(equipmentIdBusNode.get(equipmentIdBus)); + } else { + return OptionalInt.empty(); + } + } + + void addControl(String equipmentIdBus, String voltageLevelId, int node) { + equipmentIdBusControlNode.put(equipmentIdBus, new NodeBreakerControlNode(voltageLevelId, node)); + } + + Optional getControlNode(String equipmentIdBus) { + if (equipmentIdBusControlNode.containsKey(equipmentIdBus)) { + return Optional.of(equipmentIdBusControlNode.get(equipmentIdBus)); + } else { + return Optional.empty(); + } + } + + void addSlackControl(int bus, String voltageLevelId, int node) { + slackBusControlNode.put(bus, new NodeBreakerControlNode(voltageLevelId, node)); + } + + Optional getSlackControlNode(int bus) { + if (slackBusControlNode.containsKey(bus)) { + return Optional.of(slackBusControlNode.get(bus)); + } else { + return Optional.empty(); + } + } + + static final class NodeBreakerControlNode { + private final String voltageLevelId; + private final int node; + + private NodeBreakerControlNode(String voltageLevelId, int node) { + this.voltageLevelId = voltageLevelId; + this.node = node; + } + + String getVoltageLevelId() { + return voltageLevelId; + } + + int getNode() { + return node; + } + } +} diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java new file mode 100644 index 00000000000..aa2c07715b9 --- /dev/null +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java @@ -0,0 +1,228 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.psse.converter; + +import com.powsybl.psse.model.pf.*; +import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationNode; +import com.powsybl.psse.model.PsseVersion; +import org.jgrapht.Graph; +import org.jgrapht.alg.connectivity.ConnectivityInspector; +import org.jgrapht.alg.util.Pair; +import org.jgrapht.graph.Pseudograph; + +import java.util.*; +import java.util.stream.Collectors; + +import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.*; +import static com.powsybl.psse.converter.AbstractConverter.getNodeBreakerEquipmentId; +import static com.powsybl.psse.model.PsseVersion.Major.V35; + +/** + * @author Luma Zamarreño {@literal } + * @author José Antonio Marqués {@literal } + */ +final class NodeBreakerValidation { + private final boolean ignoreNodeBreakerTopology; + private final Map> busSubstations; + private final Map> busEquipmentTerminals; + private final Map> busControls; + + NodeBreakerValidation(boolean ignoreNodeBreakerTopology) { + this.ignoreNodeBreakerTopology = ignoreNodeBreakerTopology; + this.busSubstations = new HashMap<>(); + this.busEquipmentTerminals = new HashMap<>(); + this.busControls = new HashMap<>(); + } + + Optional getSubstationIfOnlyOneExists(int bus) { + if (busSubstations.containsKey(bus) && busSubstations.get(bus).size() == 1) { + return Optional.of(busSubstations.get(bus).iterator().next()); + } else { + return Optional.empty(); + } + } + + List getControls(int bus) { + return busControls.containsKey(bus) ? busControls.get(bus) : new ArrayList<>(); + } + + void fill(PssePowerFlowModel pssePowerFlowModel, PsseVersion version) { + if (version.major() != V35) { + return; + } + + pssePowerFlowModel.getSubstations().forEach(psseSubstation -> { + Set buses = psseSubstation.getNodes().stream().map(PsseSubstationNode::getI).collect(Collectors.toSet()); + buses.forEach(bus -> busSubstations.computeIfAbsent(bus, k -> new ArrayList<>()).add(psseSubstation)); + }); + + pssePowerFlowModel.getLoads().forEach(psseLoad -> { + String id = getNodeBreakerEquipmentId(PSSE_LOAD, psseLoad.getI(), psseLoad.getId()); + busEquipmentTerminals.computeIfAbsent(psseLoad.getI(), k -> new ArrayList<>()).add(id); + }); + pssePowerFlowModel.getFixedShunts().forEach(psseFixedShunt -> { + String id = getNodeBreakerEquipmentId(PSSE_FIXED_SHUNT, psseFixedShunt.getI(), psseFixedShunt.getId()); + busEquipmentTerminals.computeIfAbsent(psseFixedShunt.getI(), k -> new ArrayList<>()).add(id); + }); + pssePowerFlowModel.getGenerators().forEach(psseGenerator -> { + String id = getNodeBreakerEquipmentId(PSSE_GENERATOR, psseGenerator.getI(), psseGenerator.getId()); + busEquipmentTerminals.computeIfAbsent(psseGenerator.getI(), k -> new ArrayList<>()).add(id); + if (psseGenerator.getIreg() != 0) { + busControls.computeIfAbsent(psseGenerator.getIreg(), k -> new ArrayList<>()).add(new NodeBreakerControl(id, psseGenerator.getNreg())); + } + }); + pssePowerFlowModel.getNonTransformerBranches().forEach(psseNonTransformerBranch -> { + String id = getNodeBreakerEquipmentId(PSSE_BRANCH, psseNonTransformerBranch.getI(), psseNonTransformerBranch.getJ(), psseNonTransformerBranch.getCkt()); + busEquipmentTerminals.computeIfAbsent(psseNonTransformerBranch.getI(), k -> new ArrayList<>()).add(id); + busEquipmentTerminals.computeIfAbsent(psseNonTransformerBranch.getJ(), k -> new ArrayList<>()).add(id); + }); + pssePowerFlowModel.getTransformers().forEach(psseTransformer -> { + if (psseTransformer.getK() == 0) { + twoWindingsTransformerNetworkValidation(psseTransformer); + } else { + threeWindingsTransformerNetworkValidation(psseTransformer); + } + }); + pssePowerFlowModel.getTwoTerminalDcTransmissionLines().forEach(psseTwoTerminalDcTransmissionLine -> { + String idRectifier = getNodeBreakerEquipmentId(PSSE_TWO_TERMINAL_DC_LINE, psseTwoTerminalDcTransmissionLine.getRectifier().getIp(), psseTwoTerminalDcTransmissionLine.getName()); + String idInverter = getNodeBreakerEquipmentId(PSSE_TWO_TERMINAL_DC_LINE, psseTwoTerminalDcTransmissionLine.getInverter().getIp(), psseTwoTerminalDcTransmissionLine.getName()); + busEquipmentTerminals.computeIfAbsent(psseTwoTerminalDcTransmissionLine.getRectifier().getIp(), k -> new ArrayList<>()).add(idRectifier); + busEquipmentTerminals.computeIfAbsent(psseTwoTerminalDcTransmissionLine.getInverter().getIp(), k -> new ArrayList<>()).add(idInverter); + }); + pssePowerFlowModel.getSwitchedShunts().forEach(psseSwitchedShunt -> { + String id = getNodeBreakerEquipmentId(PSSE_SWITCHED_SHUNT, psseSwitchedShunt.getI(), psseSwitchedShunt.getId()); + busEquipmentTerminals.computeIfAbsent(psseSwitchedShunt.getI(), k -> new ArrayList<>()).add(id); + if (psseSwitchedShunt.getSwreg() != 0) { + busControls.computeIfAbsent(psseSwitchedShunt.getSwreg(), k -> new ArrayList<>()).add(new NodeBreakerControl(id, psseSwitchedShunt.getNreg())); + } + }); + } + + private void twoWindingsTransformerNetworkValidation(PsseTransformer psseTransformer) { + String id = getNodeBreakerEquipmentId(PSSE_TWO_WINDING, psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); + busEquipmentTerminals.computeIfAbsent(psseTransformer.getI(), k -> new ArrayList<>()).add(id); + busEquipmentTerminals.computeIfAbsent(psseTransformer.getJ(), k -> new ArrayList<>()).add(id); + + addWindingControl(psseTransformer.getWinding1(), id); + } + + private void threeWindingsTransformerNetworkValidation(PsseTransformer psseTransformer) { + String id = getNodeBreakerEquipmentId(PSSE_THREE_WINDING, psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt()); + busEquipmentTerminals.computeIfAbsent(psseTransformer.getI(), k -> new ArrayList<>()).add(id); + busEquipmentTerminals.computeIfAbsent(psseTransformer.getJ(), k -> new ArrayList<>()).add(id); + busEquipmentTerminals.computeIfAbsent(psseTransformer.getK(), k -> new ArrayList<>()).add(id); + + addWindingControl(psseTransformer.getWinding1(), id); + addWindingControl(psseTransformer.getWinding2(), id); + addWindingControl(psseTransformer.getWinding3(), id); + } + + private void addWindingControl(PsseTransformerWinding psseTransformerWinding, String id) { + int iReg = Math.abs(psseTransformerWinding.getCont()); + if (iReg != 0) { + busControls.computeIfAbsent(iReg, k -> new ArrayList<>()).add(new NodeBreakerControl(id, psseTransformerWinding.getNode())); + } + } + + boolean isNodeBreakerSubstationCoherent(Set expectedBuses) { + if (ignoreNodeBreakerTopology) { + return false; + } + if (expectedBuses.isEmpty()) { + return false; + } + Set expectedSubstations = expectedBuses.stream() + .map(this::getSubstationIfOnlyOneExists) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toSet()); + if (expectedSubstations.size() != 1) { + return false; + } + PsseSubstation expectedSubstation = expectedSubstations.iterator().next(); + if (!areControlsCoherent(expectedSubstation, expectedBuses)) { + return false; + } + Set expectedEquipmentTerminals = expectedBuses.stream() + .flatMap(bus -> getEquipmentTerminals(bus).stream()) + .collect(Collectors.toSet()); + List> nodeComponents = obtainNodeComponents(expectedSubstation); + + Set actualBuses = new HashSet<>(); + Set actualEquipmentTerminals = new HashSet<>(); + for (Set nodeComponentSet : nodeComponents) { + Set busComponentSet = expectedSubstation.getNodes().stream() + .filter(n -> nodeComponentSet.contains(n.getNi())) + .map(PsseSubstationNode::getI).collect(Collectors.toSet()); + Set equipmentTerminalComponent = expectedSubstation.getEquipmentTerminals().stream() + .filter(eqt -> nodeComponentSet.contains(eqt.getNi())) + .map(eqt -> getNodeBreakerEquipmentId(eqt.getType(), eqt.getI(), eqt.getJ(), eqt.getK(), eqt.getId())).collect(Collectors.toSet()); + + actualBuses.addAll(busComponentSet); + actualEquipmentTerminals.addAll(equipmentTerminalComponent); + } + if (expectedBuses.size() != actualBuses.size()) { + return false; + } + if (expectedEquipmentTerminals.size() != actualEquipmentTerminals.size()) { + return false; + } + return expectedBuses.containsAll(actualBuses) && expectedEquipmentTerminals.containsAll(actualEquipmentTerminals); + } + + // All the nodes associated with controls must be inside the substation data + private boolean areControlsCoherent(PsseSubstation psseSubstation, Set buses) { + Set nodesSet = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).collect(Collectors.toSet()); + for (int bus : buses) { + List controls = getControls(bus); + if (controls.stream().map(NodeBreakerControl::getNode).anyMatch(node -> !nodesSet.contains(node))) { + return false; + } + } + return true; + } + + private static List> obtainNodeComponents(PsseSubstation psseSubstation) { + Set nodesSet = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).collect(Collectors.toSet()); + + Graph> sGraph = new Pseudograph<>(null, null, false); + nodesSet.forEach(sGraph::addVertex); + psseSubstation.getSwitchingDevices().forEach(switchingDevice -> { + if (switchingDevice.getStatus() == 1) { // Only closed switches + sGraph.addEdge(switchingDevice.getNi(), switchingDevice.getNj(), Pair.of(switchingDevice.getNi(), switchingDevice.getNj())); + } + }); + return new ConnectivityInspector<>(sGraph).connectedSets(); + } + + private List getEquipmentTerminals(int bus) { + return busEquipmentTerminals.containsKey(bus) ? busEquipmentTerminals.get(bus) : new ArrayList<>(); + } + + private static boolean isOutOfService(PsseSubstation expectedSubstation, int node) { + return expectedSubstation.getNodes().stream().anyMatch(n -> n.getNi() == node && n.getStatus() != 1); + } + + static final class NodeBreakerControl { + private final String equipmentId; + private final int node; + + private NodeBreakerControl(String equipmentId, int node) { + this.equipmentId = equipmentId; + this.node = node; + } + + String getEquipmentId() { + return equipmentId; + } + + int getNode() { + return node; + } + } +} diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java index bd6dd208af7..d3a20004573 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java @@ -111,21 +111,26 @@ public void export(Network network, Properties parameters, DataSource dataSource // New equipment is not supported // Antennas (Branches connected only at one end) are exported as out of service (both sides open) + // New buses are created in voltageLevels with nodeBreaker topology when buses are split private static PssePowerFlowModel createUpdatePsseModel(Network network, PssePowerFlowModel psseModel) { // Only the updated blocks are copied, non-updated blocks are referenced - PssePowerFlowModel referencedAndCopiedPsseModel = psseModel.referenceAndCopyPssePowerFlowModel(); - updateModifiedBlocks(network, referencedAndCopiedPsseModel); - return referencedAndCopiedPsseModel; + PssePowerFlowModel updatedPsseModel = psseModel.referenceAndCopyPssePowerFlowModel(); + updateModifiedBlocks(network, updatedPsseModel); + return updatedPsseModel; } - private static void updateModifiedBlocks(Network network, PssePowerFlowModel referencedAndCopiedPsseModel) { + private static void updateModifiedBlocks(Network network, PssePowerFlowModel updatedPsseModel) { + NodeBreakerExport nodeBreakerExport = VoltageLevelConverter.mapSubstations(network, updatedPsseModel); - BusConverter.updateBuses(network, referencedAndCopiedPsseModel); - LoadConverter.updateLoads(network, referencedAndCopiedPsseModel); - FixedShuntCompensatorConverter.updateFixedShunts(network, referencedAndCopiedPsseModel); - GeneratorConverter.updateGenerators(network, referencedAndCopiedPsseModel); - LineConverter.updateLines(network, referencedAndCopiedPsseModel); - TransformerConverter.updateTransformers(network, referencedAndCopiedPsseModel); - SwitchedShuntCompensatorConverter.updateSwitchedShunts(network, referencedAndCopiedPsseModel); + // Only after mapping all substations, the substation data can be updated + VoltageLevelConverter.updateSubstations(network, updatedPsseModel, nodeBreakerExport); + + BusConverter.updateBuses(network, updatedPsseModel, nodeBreakerExport); + LoadConverter.updateLoads(network, updatedPsseModel, nodeBreakerExport); + FixedShuntCompensatorConverter.updateFixedShunts(network, updatedPsseModel, nodeBreakerExport); + GeneratorConverter.updateGenerators(network, updatedPsseModel, nodeBreakerExport); + LineConverter.updateLines(network, updatedPsseModel, nodeBreakerExport); + TransformerConverter.updateTransformers(network, updatedPsseModel, nodeBreakerExport); + SwitchedShuntCompensatorConverter.updateSwitchedShunts(network, updatedPsseModel, nodeBreakerExport); } } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java index ef1fecaeec0..0eb653e1659 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java @@ -55,6 +55,10 @@ public class PsseImporter implements Importer { ParameterType.BOOLEAN, "Ignore base voltage specified in the file", Boolean.FALSE); + private static final Parameter IGNORE_NODE_BREAKER_TOPOLOGY_PARAMETER = new Parameter("psse.import.ignore-node-breaker-topology", + ParameterType.BOOLEAN, + "Ignore the node breaker topolgy specified in the substation data of the file", + Boolean.FALSE); @Override public String getFormat() { @@ -63,7 +67,9 @@ public String getFormat() { @Override public List getParameters() { - return Collections.singletonList(IGNORE_BASE_VOLTAGE_PARAMETER); + return List.of( + IGNORE_BASE_VOLTAGE_PARAMETER, + IGNORE_NODE_BREAKER_TOPOLOGY_PARAMETER); } @Override @@ -164,60 +170,66 @@ private Network convert(PssePowerFlowModel psseModel, Network network, Propertie boolean ignoreBaseVoltage = Parameter.readBoolean(FORMAT, parameters, IGNORE_BASE_VOLTAGE_PARAMETER, ParameterDefaultValueConfig.INSTANCE); + boolean ignoreNodeBreakerTopology = Parameter.readBoolean(FORMAT, parameters, IGNORE_NODE_BREAKER_TOPOLOGY_PARAMETER, + ParameterDefaultValueConfig.INSTANCE); PerUnitContext perUnitContext = new PerUnitContext(psseModel.getCaseIdentification().getSbase(), ignoreBaseVoltage); // The map gives access to PsseBus object with the int bus Number Map busNumToPsseBus = psseModel.getBuses().stream().collect(Collectors.toMap(PsseBus::getI, Function.identity())); + // Necessary data for validating nodeBreaker topology + NodeBreakerValidation nodeBreakerValidation = new NodeBreakerValidation(ignoreNodeBreakerTopology); + nodeBreakerValidation.fill(psseModel, version); + // build container to fit IIDM requirements ContainersMapping containersMapping = defineContainersMapping(psseModel, busNumToPsseBus, perUnitContext); // create buses - createBuses(psseModel, containersMapping, perUnitContext, network); + NodeBreakerImport nodeBreakerImport = createBuses(psseModel, containersMapping, perUnitContext, network, nodeBreakerValidation); // Create loads for (PsseLoad psseLoad : psseModel.getLoads()) { - new LoadConverter(psseLoad, containersMapping, network).create(); + new LoadConverter(psseLoad, containersMapping, network, nodeBreakerImport).create(); } // Create fixed shunts for (PsseFixedShunt psseShunt : psseModel.getFixedShunts()) { - new FixedShuntCompensatorConverter(psseShunt, containersMapping, network).create(); + new FixedShuntCompensatorConverter(psseShunt, containersMapping, network, nodeBreakerImport).create(); } // Create switched shunts for (PsseSwitchedShunt psseSwShunt : psseModel.getSwitchedShunts()) { - new SwitchedShuntCompensatorConverter(psseSwShunt, containersMapping, network, version).create(); + new SwitchedShuntCompensatorConverter(psseSwShunt, containersMapping, network, version, nodeBreakerImport).create(); } for (PsseGenerator psseGen : psseModel.getGenerators()) { - new GeneratorConverter(psseGen, containersMapping, network).create(); + new GeneratorConverter(psseGen, containersMapping, network, nodeBreakerImport).create(); } for (PsseNonTransformerBranch psseLine : psseModel.getNonTransformerBranches()) { - new LineConverter(psseLine, containersMapping, perUnitContext, network, version).create(); + new LineConverter(psseLine, containersMapping, perUnitContext, network, version, nodeBreakerImport).create(); } for (PsseTransformer psseTfo : psseModel.getTransformers()) { - new TransformerConverter(psseTfo, containersMapping, perUnitContext, network, busNumToPsseBus, psseModel.getCaseIdentification().getSbase(), version).create(); + new TransformerConverter(psseTfo, containersMapping, perUnitContext, network, busNumToPsseBus, psseModel.getCaseIdentification().getSbase(), version, nodeBreakerImport).create(); } for (PsseTwoTerminalDcTransmissionLine psseTwoTerminaDc : psseModel.getTwoTerminalDcTransmissionLines()) { - new TwoTerminalDcConverter(psseTwoTerminaDc, containersMapping, network).create(); + new TwoTerminalDcConverter(psseTwoTerminaDc, containersMapping, network, nodeBreakerImport).create(); } // Attach a slack bus - new SlackConverter(psseModel.getBuses(), containersMapping, network).create(); + new SlackConverter(psseModel.getBuses(), containersMapping, network, nodeBreakerImport).create(); // Add controls for (PsseSwitchedShunt psseSwShunt : psseModel.getSwitchedShunts()) { - new SwitchedShuntCompensatorConverter(psseSwShunt, containersMapping, network, version).addControl(); + new SwitchedShuntCompensatorConverter(psseSwShunt, containersMapping, network, version, nodeBreakerImport).addControl(); } for (PsseGenerator psseGen : psseModel.getGenerators()) { - new GeneratorConverter(psseGen, containersMapping, network).addControl(busNumToPsseBus.get(psseGen.getI())); + new GeneratorConverter(psseGen, containersMapping, network, nodeBreakerImport).addControl(busNumToPsseBus.get(psseGen.getI())); } for (PsseTransformer psseTransformer : psseModel.getTransformers()) { - new TransformerConverter(psseTransformer, containersMapping, perUnitContext, network, busNumToPsseBus, psseModel.getCaseIdentification().getSbase(), version).addControl(); + new TransformerConverter(psseTransformer, containersMapping, perUnitContext, network, busNumToPsseBus, psseModel.getCaseIdentification().getSbase(), version, nodeBreakerImport).addControl(); } return network; @@ -237,14 +249,14 @@ private ContainersMapping defineContainersMapping(PssePowerFlowModel psseModel, }); return ContainersMapping.create(psseModel.getBuses(), edges, - PsseBus::getI, - Edge::getBus1, - Edge::getBus2, - Edge::isZeroImpedance, - Edge::isTransformer, - busNumber -> getNominalVFromBusNumber(busNumToPsseBus, busNumber, perUnitContext), - busNums -> "VL" + busNums.stream().sorted().findFirst().orElseThrow(() -> new PsseException("Unexpected empty busNums")), - substationNums -> "S" + substationNums.stream().sorted().findFirst().orElseThrow(() -> new PsseException("Unexpected empty substationNums"))); + PsseBus::getI, + Edge::getBus1, + Edge::getBus2, + Edge::isZeroImpedance, + Edge::isTransformer, + busNumber -> getNominalVFromBusNumber(busNumToPsseBus, busNumber, perUnitContext), + AbstractConverter::getVoltageLevelId, + substationNums -> "S" + substationNums.stream().sorted().findFirst().orElseThrow(() -> new PsseException("Unexpected empty substationNums"))); } private double getNominalVFromBusNumber(Map busNumToPsseBus, int busNumber, PerUnitContext perUnitContext) { @@ -254,14 +266,20 @@ private double getNominalVFromBusNumber(Map busNumToPsseBus, i return VoltageLevelConverter.getNominalV(busNumToPsseBus.get(busNumber), perUnitContext.isIgnoreBaseVoltage()); } - private static void createBuses(PssePowerFlowModel psseModel, ContainersMapping containersMapping, - PerUnitContext perUnitContext, Network network) { + private static NodeBreakerImport createBuses(PssePowerFlowModel psseModel, ContainersMapping containersMapping, + PerUnitContext perUnitContext, Network network, + NodeBreakerValidation nodeBreakerValidation) { + + NodeBreakerImport nodeBreakerImport = new NodeBreakerImport(); + for (PsseBus psseBus : psseModel.getBuses()) { Substation substation = new SubstationConverter(psseBus, containersMapping, network).create(); - VoltageLevel voltageLevel = new VoltageLevelConverter(psseBus, containersMapping, perUnitContext, network).create(substation); - new BusConverter(psseBus, containersMapping, network).create(voltageLevel); + VoltageLevel voltageLevel = new VoltageLevelConverter(psseBus, containersMapping, perUnitContext, network, nodeBreakerValidation, nodeBreakerImport).create(substation); + new BusConverter(psseBus, containersMapping, network, nodeBreakerImport).create(voltageLevel); } + + return nodeBreakerImport; } private static final class Edge { @@ -294,7 +312,7 @@ private boolean isZeroImpedance() { } } - static class PerUnitContext { + static final class PerUnitContext { private final double sb; private final boolean ignoreBaseVoltage; diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SlackConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SlackConverter.java index 8ebc8db3edb..5296fc05e42 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SlackConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SlackConverter.java @@ -9,6 +9,7 @@ import com.powsybl.iidm.network.Bus; import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.Terminal; import com.powsybl.iidm.network.extensions.SlackTerminal; import com.powsybl.iidm.network.util.ContainersMapping; import com.powsybl.iidm.network.util.TerminalFinder; @@ -16,6 +17,7 @@ import java.util.List; import java.util.Objects; +import java.util.Optional; /** * @author Luma Zamarreño {@literal } @@ -23,16 +25,24 @@ */ class SlackConverter extends AbstractConverter { - SlackConverter(List psseBusList, ContainersMapping containerMapping, Network network) { + SlackConverter(List psseBusList, ContainersMapping containerMapping, Network network, NodeBreakerImport nodeBreakerImport) { super(containerMapping, network); this.psseBusList = Objects.requireNonNull(psseBusList); + this.nodeBreakerImport = Objects.requireNonNull(nodeBreakerImport); } void create() { for (PsseBus psseBus : psseBusList) { if (psseBus.getIde() == 3) { - String busId = AbstractConverter.getBusId(psseBus.getI()); - Bus bus = getNetwork().getBusBreakerView().getBus(busId); + Bus bus; + Optional slackControlNode = nodeBreakerImport.getSlackControlNode(psseBus.getI()); + if (slackControlNode.isPresent()) { + Terminal terminal = obtainTerminalNode(getNetwork(), slackControlNode.get().getVoltageLevelId(), slackControlNode.get().getNode()); + bus = terminal != null ? terminal.getBusBreakerView().getBus() : null; + } else { + String busId = AbstractConverter.getBusId(psseBus.getI()); + bus = getNetwork().getBusBreakerView().getBus(busId); + } if (slackBusIsValidForIidm(bus)) { SlackTerminal.attach(bus); } @@ -45,4 +55,5 @@ private static boolean slackBusIsValidForIidm(Bus bus) { } private final List psseBusList; + private final NodeBreakerImport nodeBreakerImport; } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java index 068c6776900..5ac1af3452c 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java @@ -7,10 +7,7 @@ */ package com.powsybl.psse.converter; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; import com.powsybl.iidm.network.*; @@ -21,6 +18,7 @@ import com.powsybl.psse.model.PsseVersion; import com.powsybl.psse.model.pf.PssePowerFlowModel; import com.powsybl.psse.model.pf.PsseSwitchedShunt; +import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_SWITCHED_SHUNT; import static com.powsybl.psse.model.PsseVersion.Major.V35; /** @@ -29,10 +27,11 @@ */ class SwitchedShuntCompensatorConverter extends AbstractConverter { - SwitchedShuntCompensatorConverter(PsseSwitchedShunt psseSwitchedShunt, ContainersMapping containerMapping, Network network, PsseVersion version) { + SwitchedShuntCompensatorConverter(PsseSwitchedShunt psseSwitchedShunt, ContainersMapping containerMapping, Network network, PsseVersion version, NodeBreakerImport nodeBreakerImport) { super(containerMapping, network); this.psseSwitchedShunt = Objects.requireNonNull(psseSwitchedShunt); this.version = Objects.requireNonNull(version); + this.nodeBreakerImport = Objects.requireNonNull(nodeBreakerImport); } void create() { @@ -47,8 +46,17 @@ void create() { ShuntCompensatorAdder adder = voltageLevel.newShuntCompensator() .setId(getShuntId(busId, id)) - .setConnectableBus(busId) .setSectionCount(defineSectionCount(psseSwitchedShunt.getBinit(), shuntBlocks)); + + String equipmentId = getNodeBreakerEquipmentId(PSSE_SWITCHED_SHUNT, psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version)); + OptionalInt node = nodeBreakerImport.getNode(getNodeBreakerEquipmentIdBus(equipmentId, psseSwitchedShunt.getI())); + if (node.isPresent()) { + adder.setNode(node.getAsInt()); + } else { + adder.setConnectableBus(busId); + adder.setBus(psseSwitchedShunt.getStat() == 1 ? busId : null); + } + ShuntCompensatorNonLinearModelAdder modelAdder = adder.newNonLinearModel(); shuntBlocks.forEach(shuntBlock -> { for (int i = 0; i < shuntBlock.getN(); i++) { @@ -59,8 +67,6 @@ void create() { } }); modelAdder.add(); - - adder.setBus(psseSwitchedShunt.getStat() == 1 ? busId : null); adder.add(); } @@ -74,7 +80,7 @@ void addControl() { return; } - Terminal regulatingTerminal = defineRegulatingTerminal(psseSwitchedShunt, getNetwork(), version); + Terminal regulatingTerminal = defineRegulatingTerminal(psseSwitchedShunt, getNetwork(), shunt, version, nodeBreakerImport); // Discard control if the switchedShunt is controlling an isolated bus if (regulatingTerminal == null) { return; @@ -105,17 +111,21 @@ private static boolean isControllingVoltage(PsseSwitchedShunt psseSwitchedShunt) } // Nreg (version 35) is not yet considered - private static Terminal defineRegulatingTerminal(PsseSwitchedShunt psseSwitchedShunt, Network network, PsseVersion version) { - String defaultRegulatingBusId = getBusId(psseSwitchedShunt.getI()); + private static Terminal defineRegulatingTerminal(PsseSwitchedShunt psseSwitchedShunt, Network network, ShuntCompensator shunt, PsseVersion version, NodeBreakerImport nodeBreakerImport) { Terminal regulatingTerminal = null; if (switchedShuntRegulatingBus(psseSwitchedShunt, version) == 0) { - Bus bus = network.getBusBreakerView().getBus(defaultRegulatingBusId); - regulatingTerminal = bus.getConnectedTerminalStream().findFirst().orElse(null); + regulatingTerminal = shunt.getTerminal(); } else { - String regulatingBusId = getBusId(switchedShuntRegulatingBus(psseSwitchedShunt, version)); - Bus bus = network.getBusBreakerView().getBus(regulatingBusId); - if (bus != null) { - regulatingTerminal = bus.getConnectedTerminalStream().findFirst().orElse(null); + String equipmentId = getNodeBreakerEquipmentId(PSSE_SWITCHED_SHUNT, psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version)); + Optional controlNode = nodeBreakerImport.getControlNode(getNodeBreakerEquipmentIdBus(equipmentId, switchedShuntRegulatingBus(psseSwitchedShunt, version))); + if (controlNode.isPresent()) { + regulatingTerminal = obtainTerminalNode(network, controlNode.get().getVoltageLevelId(), controlNode.get().getNode()); + } else { + String regulatingBusId = getBusId(switchedShuntRegulatingBus(psseSwitchedShunt, version)); + Bus bus = network.getBusBreakerView().getBus(regulatingBusId); + if (bus != null) { + regulatingTerminal = bus.getConnectedTerminalStream().findFirst().orElse(null); + } } } if (regulatingTerminal == null) { @@ -267,22 +277,24 @@ private static String getShuntId(String busId, String id) { } // At the moment we do not consider new switchedShunts - static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel) { + static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { PsseVersion version = PsseVersion.fromRevision(psseModel.getCaseIdentification().getRev()); psseModel.getSwitchedShunts().forEach(psseSwitchedShunt -> { String switchedShuntId = getShuntId(getBusId(psseSwitchedShunt.getI()), defineShuntId(psseSwitchedShunt, version)); ShuntCompensator switchedShunt = network.getShuntCompensator(switchedShuntId); + int bus = obtainBus(nodeBreakerExport, getNodeBreakerEquipmentId(PSSE_SWITCHED_SHUNT, psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version)), psseSwitchedShunt.getI()); if (switchedShunt == null) { psseSwitchedShunt.setStat(0); } else { psseSwitchedShunt.setStat(getStatus(switchedShunt)); psseSwitchedShunt.setBinit(getQ(switchedShunt)); } + psseSwitchedShunt.setI(bus); }); } private static int getStatus(ShuntCompensator switchedShunt) { - if (switchedShunt.getTerminal().isConnected()) { + if (switchedShunt.getTerminal().isConnected() && switchedShunt.getTerminal().getBusBreakerView().getBus() != null) { return 1; } else { return 0; @@ -296,6 +308,6 @@ private static double getQ(ShuntCompensator switchedShunt) { private final PsseSwitchedShunt psseSwitchedShunt; private final PsseVersion version; - + private final NodeBreakerImport nodeBreakerImport; private static final Logger LOGGER = LoggerFactory.getLogger(SwitchedShuntCompensatorConverter.class); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java index fea2c97589c..8541450f258 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java @@ -7,10 +7,7 @@ */ package com.powsybl.psse.converter; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import com.powsybl.commons.PowsyblException; import com.powsybl.iidm.network.*; @@ -27,6 +24,8 @@ import com.powsybl.psse.model.pf.PssePowerFlowModel; import com.powsybl.psse.model.pf.PsseTransformer; import com.powsybl.psse.model.pf.PsseTransformerWinding; +import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_TWO_WINDING; +import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_THREE_WINDING; import static com.powsybl.psse.model.PsseVersion.Major.V35; /** @@ -38,14 +37,15 @@ class TransformerConverter extends AbstractConverter { private static final double TOLERANCE = 0.00001; TransformerConverter(PsseTransformer psseTransformer, ContainersMapping containersMapping, - PerUnitContext perUnitContext, Network network, Map busNumToPsseBus, double sbase, - PsseVersion version) { + PerUnitContext perUnitContext, Network network, Map busNumToPsseBus, double sbase, + PsseVersion version, NodeBreakerImport nodeBreakerImport) { super(containersMapping, network); this.psseTransformer = Objects.requireNonNull(psseTransformer); this.busNumToPsseBus = Objects.requireNonNull(busNumToPsseBus); this.sbase = sbase; this.perUnitContext = Objects.requireNonNull(perUnitContext); this.version = Objects.requireNonNull(version); + this.nodeBreakerImport = Objects.requireNonNull(nodeBreakerImport); } void create() { @@ -84,7 +84,7 @@ private void createTwoWindingsTransformer() { // Handling magnetizing admittance Gm and Bm Complex ysh = defineShuntAdmittance(id, psseTransformer.getMag1(), psseTransformer.getMag2(), sbase, sbase12, baskv1, nomV1, psseTransformer.getCm()); - // To engineering units + // To engineering units z = impedanceToEngineeringUnits(z, voltageLevel2.getNominalV(), perUnitContext.getSb()); ysh = admittanceToEngineeringUnits(ysh, voltageLevel2.getNominalV(), perUnitContext.getSb()); @@ -100,23 +100,35 @@ private void createTwoWindingsTransformer() { TapChanger tapChangerAdjustedYsh = tapChangerAdjustmentAfterMovingShuntAdmittanceBetweenRatioAndTransmissionImpedance(tapChangerAdjustedRatio); TwoWindingsTransformerAdder adder = voltageLevel2.getSubstation() - .orElseThrow(() -> new PowsyblException("Substation null! Transformer must be within a substation")) - .newTwoWindingsTransformer() - .setId(id) - .setEnsureIdUnicity(true) - .setConnectableBus1(bus1Id) - .setVoltageLevel1(voltageLevel1Id) - .setConnectableBus2(bus2Id) - .setVoltageLevel2(voltageLevel2Id) - .setRatedU1(voltageLevel1.getNominalV()) - .setRatedU2(voltageLevel2.getNominalV()) - .setR(z.getReal()) - .setX(z.getImaginary()) - .setG(ysh.getReal()) - .setB(ysh.getImaginary()); - - adder.setBus1(psseTransformer.getStat() == 1 ? bus1Id : null); - adder.setBus2(psseTransformer.getStat() == 1 ? bus2Id : null); + .orElseThrow(() -> new PowsyblException("Substation null! Transformer must be within a substation")) + .newTwoWindingsTransformer() + .setId(id) + .setEnsureIdUnicity(true) + .setVoltageLevel1(voltageLevel1Id) + .setVoltageLevel2(voltageLevel2Id) + .setRatedU1(voltageLevel1.getNominalV()) + .setRatedU2(voltageLevel2.getNominalV()) + .setR(z.getReal()) + .setX(z.getImaginary()) + .setG(ysh.getReal()) + .setB(ysh.getImaginary()); + + String equipmentId = getNodeBreakerEquipmentId(PSSE_TWO_WINDING, psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); + OptionalInt node1 = nodeBreakerImport.getNode(getNodeBreakerEquipmentIdBus(equipmentId, psseTransformer.getI())); + if (node1.isPresent()) { + adder.setNode1(node1.getAsInt()); + } else { + adder.setConnectableBus1(bus1Id); + adder.setBus1(psseTransformer.getStat() == 1 ? bus1Id : null); + } + OptionalInt node2 = nodeBreakerImport.getNode(getNodeBreakerEquipmentIdBus(equipmentId, psseTransformer.getJ())); + if (node2.isPresent()) { + adder.setNode2(node2.getAsInt()); + } else { + adder.setConnectableBus2(bus2Id); + adder.setBus2(psseTransformer.getStat() == 1 ? bus2Id : null); + } + TwoWindingsTransformer twt = adder.add(); tapChangerToIidm(tapChangerAdjustedYsh, twt); @@ -183,42 +195,43 @@ private void createThreeWindingsTransformer() { TapChanger tapChanger1AdjustedYsh = tapChangerAdjustmentAfterMovingShuntAdmittanceBetweenRatioAndTransmissionImpedance(tapChanger1); ThreeWindingsTransformerAdder adder = voltageLevel1.getSubstation() - .orElseThrow(() -> new PowsyblException("Substation null! Transformer must be within a substation")) - .newThreeWindingsTransformer() - .setRatedU0(v0) - .setEnsureIdUnicity(true) - .setId(id) - .newLeg1() - .setR(z1.getReal()) - .setX(z1.getImaginary()) - .setG(ysh.getReal()) - .setB(ysh.getImaginary()) - .setRatedU(voltageLevel1.getNominalV()) - .setConnectableBus(bus1Id) - .setVoltageLevel(voltageLevel1Id) - .setBus(leg1IsConnected() ? bus1Id : null) - .add() - .newLeg2() - .setR(z2.getReal()) - .setX(z2.getImaginary()) - .setG(0) - .setB(0) - .setRatedU(voltageLevel2.getNominalV()) - .setConnectableBus(bus2Id) - .setVoltageLevel(voltageLevel2Id) - .setBus(leg2IsConnected() ? bus2Id : null) - .add() - .newLeg3() - .setR(z3.getReal()) - .setX(z3.getImaginary()) - .setG(0) - .setB(0) - .setRatedU(voltageLevel3.getNominalV()) - .setConnectableBus(bus3Id) - .setVoltageLevel(voltageLevel3Id) - .setBus(leg3IsConnected() ? bus3Id : null) - .add(); - + .orElseThrow(() -> new PowsyblException("Substation null! Transformer must be within a substation")) + .newThreeWindingsTransformer() + .setRatedU0(v0) + .setEnsureIdUnicity(true) + .setId(id); + ThreeWindingsTransformerAdder.LegAdder legAdder1 = adder + .newLeg1() + .setR(z1.getReal()) + .setX(z1.getImaginary()) + .setG(ysh.getReal()) + .setB(ysh.getImaginary()) + .setRatedU(voltageLevel1.getNominalV()) + .setVoltageLevel(voltageLevel1Id); + ThreeWindingsTransformerAdder.LegAdder legAdder2 = adder + .newLeg2() + .setR(z2.getReal()) + .setX(z2.getImaginary()) + .setG(0) + .setB(0) + .setRatedU(voltageLevel2.getNominalV()) + .setVoltageLevel(voltageLevel2Id); + ThreeWindingsTransformerAdder.LegAdder legAdder3 = adder + .newLeg3() + .setR(z3.getReal()) + .setX(z3.getImaginary()) + .setG(0) + .setB(0) + .setRatedU(voltageLevel3.getNominalV()) + .setVoltageLevel(voltageLevel3Id); + + String equipmentId = getNodeBreakerEquipmentId(PSSE_THREE_WINDING, psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt()); + legConnectivity(legAdder1, equipmentId, psseTransformer.getI(), bus1Id, leg1IsConnected()); + legAdder1.add(); + legConnectivity(legAdder2, equipmentId, psseTransformer.getJ(), bus2Id, leg2IsConnected()); + legAdder2.add(); + legConnectivity(legAdder3, equipmentId, psseTransformer.getK(), bus3Id, leg3IsConnected()); + legAdder3.add(); ThreeWindingsTransformer twt = adder.add(); twt.setProperty("v", Double.toString(psseTransformer.getVmstar() * v0)); @@ -228,6 +241,16 @@ private void createThreeWindingsTransformer() { defineOperationalLimits(twt, voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), voltageLevel3.getNominalV()); } + private void legConnectivity(ThreeWindingsTransformerAdder.LegAdder legAdder, String equipmentId, int bus, String busId, boolean isLegConnected) { + OptionalInt node1 = nodeBreakerImport.getNode(getNodeBreakerEquipmentIdBus(equipmentId, bus)); + if (node1.isPresent()) { + legAdder.setNode(node1.getAsInt()); + } else { + legAdder.setConnectableBus(busId); + legAdder.setBus(isLegConnected ? busId : null); + } + } + private static double getNomV(PsseTransformerWinding winding, VoltageLevel voltageLevel) { double nomV = winding.getNomv(); if (nomV == 0.0) { @@ -703,48 +726,50 @@ private static boolean isTwoWindingsTransformer(PsseTransformer psseTransformer) private void addControlTwoWindingsTransformer() { String id = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); + String equipmentId = ""; TwoWindingsTransformer twt = getNetwork().getTwoWindingsTransformer(id); if (twt == null) { return; } boolean regulatingForcedToOff = false; if (twt.hasRatioTapChanger()) { - boolean regulating = defineVoltageControl(getNetwork(), twt.getId(), psseTransformer.getWinding1(), twt.getRatioTapChanger(), regulatingForcedToOff); + boolean regulating = defineVoltageControl(getNetwork(), twt.getId(), equipmentId, psseTransformer.getWinding1(), twt.getRatioTapChanger(), regulatingForcedToOff, nodeBreakerImport); regulatingForcedToOff = forceRegulatingToOff(regulatingForcedToOff, regulating); } if (twt.hasPhaseTapChanger()) { - defineActivePowerControl(getNetwork(), twt.getId(), psseTransformer.getWinding1(), twt.getPhaseTapChanger(), regulatingForcedToOff); + defineActivePowerControl(getNetwork(), twt.getId(), equipmentId, psseTransformer.getWinding1(), twt.getPhaseTapChanger(), regulatingForcedToOff, nodeBreakerImport); } } private void addControlThreeWindingsTransformer() { String id = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt()); + String equipmentId = ""; ThreeWindingsTransformer twt = getNetwork().getThreeWindingsTransformer(id); if (twt == null) { return; } boolean regulatingForcedToOff = false; - regulatingForcedToOff = addControlThreeWindingsTransformerLeg(getNetwork(), twt.getId(), twt.getLeg1(), psseTransformer.getWinding1(), regulatingForcedToOff); - regulatingForcedToOff = addControlThreeWindingsTransformerLeg(getNetwork(), twt.getId(), twt.getLeg2(), psseTransformer.getWinding2(), regulatingForcedToOff); - addControlThreeWindingsTransformerLeg(getNetwork(), twt.getId(), twt.getLeg3(), psseTransformer.getWinding3(), regulatingForcedToOff); + regulatingForcedToOff = addControlThreeWindingsTransformerLeg(getNetwork(), twt.getId(), equipmentId, twt.getLeg1(), psseTransformer.getWinding1(), regulatingForcedToOff, nodeBreakerImport); + regulatingForcedToOff = addControlThreeWindingsTransformerLeg(getNetwork(), twt.getId(), equipmentId, twt.getLeg2(), psseTransformer.getWinding2(), regulatingForcedToOff, nodeBreakerImport); + addControlThreeWindingsTransformerLeg(getNetwork(), twt.getId(), equipmentId, twt.getLeg3(), psseTransformer.getWinding3(), regulatingForcedToOff, nodeBreakerImport); } - private static boolean addControlThreeWindingsTransformerLeg(Network network, String id, Leg leg, - PsseTransformerWinding winding, boolean regulatingForcedToOffInput) { + private static boolean addControlThreeWindingsTransformerLeg(Network network, String id, String equipmentId, Leg leg, + PsseTransformerWinding winding, boolean regulatingForcedToOffInput, NodeBreakerImport nodeBreakerImport) { boolean regulatingForcedToOff = regulatingForcedToOffInput; if (leg.hasRatioTapChanger()) { - boolean regulating = defineVoltageControl(network, id, winding, leg.getRatioTapChanger(), regulatingForcedToOff); + boolean regulating = defineVoltageControl(network, id, equipmentId, winding, leg.getRatioTapChanger(), regulatingForcedToOff, nodeBreakerImport); regulatingForcedToOff = forceRegulatingToOff(regulatingForcedToOff, regulating); } if (leg.hasPhaseTapChanger()) { - boolean regulating = defineActivePowerControl(network, id, winding, leg.getPhaseTapChanger(), regulatingForcedToOff); + boolean regulating = defineActivePowerControl(network, id, equipmentId, winding, leg.getPhaseTapChanger(), regulatingForcedToOff, nodeBreakerImport); regulatingForcedToOff = forceRegulatingToOff(regulatingForcedToOff, regulating); } return regulatingForcedToOff; } - private static boolean defineVoltageControl(Network network, String id, PsseTransformerWinding winding, RatioTapChanger rtc, - boolean regulatingForcedToOff) { + private static boolean defineVoltageControl(Network network, String id, String equipmentId, PsseTransformerWinding winding, RatioTapChanger rtc, + boolean regulatingForcedToOff, NodeBreakerImport nodeBreakerImport) { if (Math.abs(winding.getCod()) == 2) { LOGGER.warn("Transformer {}. Reactive power control not supported", id); return false; @@ -753,7 +778,7 @@ private static boolean defineVoltageControl(Network network, String id, PsseTran return false; } - Terminal regulatingTerminal = defineRegulatingTerminal(network, id, winding); + Terminal regulatingTerminal = defineRegulatingTerminal(network, id, equipmentId, winding, nodeBreakerImport); // Discard control if the transformer is controlling an isolated bus if (regulatingTerminal == null) { return false; @@ -780,12 +805,12 @@ private static boolean defineVoltageControl(Network network, String id, PsseTran return regulating; } - private static boolean defineActivePowerControl(Network network, String id, PsseTransformerWinding winding, PhaseTapChanger ptc, boolean regulatingForcedToOff) { + private static boolean defineActivePowerControl(Network network, String id, String equipmentId, PsseTransformerWinding winding, PhaseTapChanger ptc, boolean regulatingForcedToOff, NodeBreakerImport nodeBreakerImport) { if (Math.abs(winding.getCod()) != 3) { return false; } - Terminal regulatingTerminal = defineRegulatingTerminal(network, id, winding); + Terminal regulatingTerminal = defineRegulatingTerminal(network, id, equipmentId, winding, nodeBreakerImport); // Discard control if the transformer is controlling an isolated bus if (regulatingTerminal == null) { return false; @@ -816,13 +841,19 @@ private static boolean forceRegulatingToOff(boolean regulatingForcedToOff, boole return regulatingForcedToOff || regulating; } - private static Terminal defineRegulatingTerminal(Network network, String id, PsseTransformerWinding winding) { + private static Terminal defineRegulatingTerminal(Network network, String id, String equipmentId, PsseTransformerWinding winding, NodeBreakerImport nodeBreakerImport) { Terminal regulatingTerminal = null; - String regulatingBusId = getBusId(Math.abs(winding.getCont())); - Bus bus = network.getBusBreakerView().getBus(regulatingBusId); - if (bus != null) { - regulatingTerminal = bus.getConnectedTerminalStream().findFirst().orElse(null); + int busI = Math.abs(winding.getCont()); + Optional controlNode = nodeBreakerImport.getControlNode(getNodeBreakerEquipmentIdBus(equipmentId, busI)); + if (controlNode.isPresent()) { + regulatingTerminal = obtainTerminalNode(network, controlNode.get().getVoltageLevelId(), controlNode.get().getNode()); + } else { + String regulatingBusId = getBusId(busI); + Bus bus = network.getBusBreakerView().getBus(regulatingBusId); + if (bus != null) { + regulatingTerminal = bus.getConnectedTerminalStream().findFirst().orElse(null); + } } if (regulatingTerminal == null) { LOGGER.warn("Transformer {}. Regulating terminal is not assigned as the bus is isolated", id); @@ -839,17 +870,17 @@ private static String getTransformerId(int i, int j, int k, String ckt) { } // At the moment we do not consider new transformers and antenna twoWindingsTransformers are exported as open - static void updateTransformers(Network network, PssePowerFlowModel psseModel) { + static void updateTransformers(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { psseModel.getTransformers().forEach(psseTransformer -> { if (isTwoWindingsTransformer(psseTransformer)) { - updateTwoWindingsTransformer(network, psseTransformer); + updateTwoWindingsTransformer(network, psseTransformer, nodeBreakerExport); } else { - updateThreeWindingsTransformer(network, psseTransformer); + updateThreeWindingsTransformer(network, psseTransformer, nodeBreakerExport); } }); } - private static void updateTwoWindingsTransformer(Network network, PsseTransformer psseTransformer) { + private static void updateTwoWindingsTransformer(Network network, PsseTransformer psseTransformer, NodeBreakerExport nodeBreakerExport) { String transformerId = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); TwoWindingsTransformer tw2t = network.getTwoWindingsTransformer(transformerId); if (tw2t == null) { @@ -860,19 +891,26 @@ private static void updateTwoWindingsTransformer(Network network, PsseTransforme psseTransformer.getWinding1().setWindv(defineWindV(getRatio(tw2t.getRatioTapChanger(), tw2t.getPhaseTapChanger()), baskv1, nomV1, psseTransformer.getCw())); psseTransformer.getWinding1().setAng(getAngle(tw2t.getPhaseTapChanger())); + String equipmentId = getNodeBreakerEquipmentId(PSSE_TWO_WINDING, psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); + int busI = obtainBus(nodeBreakerExport, equipmentId, psseTransformer.getI()); + int busJ = obtainBus(nodeBreakerExport, equipmentId, psseTransformer.getJ()); + psseTransformer.setI(busI); + psseTransformer.setJ(busJ); + psseTransformer.setStat(getStatus(tw2t)); } } private static int getStatus(TwoWindingsTransformer tw2t) { - if (tw2t.getTerminal1().isConnected() && tw2t.getTerminal2().isConnected()) { + if (tw2t.getTerminal1().isConnected() && tw2t.getTerminal1().getBusBreakerView().getBus() != null + && tw2t.getTerminal2().isConnected() && tw2t.getTerminal2().getBusBreakerView().getBus() != null) { return 1; } else { return 0; } } - private static void updateThreeWindingsTransformer(Network network, PsseTransformer psseTransformer) { + private static void updateThreeWindingsTransformer(Network network, PsseTransformer psseTransformer, NodeBreakerExport nodeBreakerExport) { String transformerId = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt()); ThreeWindingsTransformer tw3t = network.getThreeWindingsTransformer(transformerId); if (tw3t == null) { @@ -893,19 +931,31 @@ private static void updateThreeWindingsTransformer(Network network, PsseTransfor psseTransformer.getWinding3().setWindv(defineWindV(getRatio(tw3t.getLeg3().getRatioTapChanger(), tw3t.getLeg3().getPhaseTapChanger()), baskv3, nomV3, psseTransformer.getCw())); psseTransformer.getWinding3().setAng(getAngle(tw3t.getLeg3().getPhaseTapChanger())); + String equipmentId = getNodeBreakerEquipmentId(PSSE_THREE_WINDING, psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt()); + int busI = obtainBus(nodeBreakerExport, equipmentId, psseTransformer.getI()); + int busJ = obtainBus(nodeBreakerExport, equipmentId, psseTransformer.getJ()); + int busK = obtainBus(nodeBreakerExport, equipmentId, psseTransformer.getK()); + psseTransformer.setI(busI); + psseTransformer.setJ(busJ); + psseTransformer.setK(busK); + psseTransformer.setStat(getStatus(tw3t)); } } private static int getStatus(ThreeWindingsTransformer tw3t) { - if (tw3t.getLeg1().getTerminal().isConnected() && tw3t.getLeg2().getTerminal().isConnected() - && tw3t.getLeg3().getTerminal().isConnected()) { + if (tw3t.getLeg1().getTerminal().isConnected() && tw3t.getLeg1().getTerminal().getBusBreakerView().getBus() != null + && tw3t.getLeg2().getTerminal().isConnected() && tw3t.getLeg2().getTerminal().getBusBreakerView().getBus() != null + && tw3t.getLeg3().getTerminal().isConnected() && tw3t.getLeg3().getTerminal().getBusBreakerView().getBus() != null) { return 1; - } else if (tw3t.getLeg1().getTerminal().isConnected() && tw3t.getLeg2().getTerminal().isConnected()) { + } else if (tw3t.getLeg1().getTerminal().isConnected() && tw3t.getLeg1().getTerminal().getBusBreakerView().getBus() != null + && tw3t.getLeg2().getTerminal().isConnected() && tw3t.getLeg2().getTerminal().getBusBreakerView().getBus() != null) { return 3; - } else if (tw3t.getLeg1().getTerminal().isConnected() && tw3t.getLeg3().getTerminal().isConnected()) { + } else if (tw3t.getLeg1().getTerminal().isConnected() && tw3t.getLeg1().getTerminal().getBusBreakerView().getBus() != null + && tw3t.getLeg3().getTerminal().isConnected() && tw3t.getLeg3().getTerminal().getBusBreakerView().getBus() != null) { return 2; - } else if (tw3t.getLeg2().getTerminal().isConnected() && tw3t.getLeg3().getTerminal().isConnected()) { + } else if (tw3t.getLeg2().getTerminal().isConnected() && tw3t.getLeg2().getTerminal().getBusBreakerView().getBus() != null + && tw3t.getLeg3().getTerminal().isConnected() && tw3t.getLeg3().getTerminal().getBusBreakerView().getBus() != null) { return 4; } else { return 0; @@ -940,6 +990,7 @@ private static double getAngle(PhaseTapChanger ptc) { private final double sbase; private final PerUnitContext perUnitContext; private final PsseVersion version; + private final NodeBreakerImport nodeBreakerImport; private static final Logger LOGGER = LoggerFactory.getLogger(TransformerConverter.class); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java index 8899704e6ec..ae882d31a99 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java @@ -13,8 +13,10 @@ import com.powsybl.iidm.network.util.Identifiables; import com.powsybl.psse.model.pf.PsseTwoTerminalDcConverter; import com.powsybl.psse.model.pf.PsseTwoTerminalDcTransmissionLine; +import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_TWO_TERMINAL_DC_LINE; import java.util.Objects; +import java.util.OptionalInt; /** * @author Luma Zamarreño {@literal } @@ -24,9 +26,10 @@ class TwoTerminalDcConverter extends AbstractConverter { private static final double DEFAULT_MAXP_FACTOR = 1.2; - TwoTerminalDcConverter(PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc, ContainersMapping containerMapping, Network network) { + TwoTerminalDcConverter(PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc, ContainersMapping containerMapping, Network network, NodeBreakerImport nodeBreakerImport) { super(containerMapping, network); this.psseTwoTerminalDc = Objects.requireNonNull(psseTwoTerminalDc); + this.nodeBreakerImport = nodeBreakerImport; } void create() { @@ -37,10 +40,17 @@ void create() { LccConverterStationAdder adderR = voltageLevelR.newLccConverterStation() .setId(getLccConverterId(psseTwoTerminalDc, psseTwoTerminalDc.getRectifier())) .setName(psseTwoTerminalDc.getName()) - .setConnectableBus(busIdR) .setLossFactor((float) lossFactor) - .setPowerFactor((float) getLccConverterPowerFactor(psseTwoTerminalDc.getRectifier())) - .setBus(psseTwoTerminalDc.getMdc() == 0 ? null : busIdR); + .setPowerFactor((float) getLccConverterPowerFactor(psseTwoTerminalDc.getRectifier())); + + String equipmentIdR = getNodeBreakerEquipmentId(PSSE_TWO_TERMINAL_DC_LINE, psseTwoTerminalDc.getRectifier().getIp(), psseTwoTerminalDc.getName()); + OptionalInt nodeR = nodeBreakerImport.getNode(getNodeBreakerEquipmentIdBus(equipmentIdR, psseTwoTerminalDc.getRectifier().getIp())); + if (nodeR.isPresent()) { + adderR.setNode(nodeR.getAsInt()); + } else { + adderR.setConnectableBus(busIdR); + adderR.setBus(psseTwoTerminalDc.getMdc() == 0 ? null : busIdR); + } LccConverterStation cR = adderR.add(); String busIdI = getBusId(psseTwoTerminalDc.getInverter().getIp()); @@ -48,10 +58,17 @@ void create() { LccConverterStationAdder adderI = voltageLevelI.newLccConverterStation() .setId(getLccConverterId(psseTwoTerminalDc, psseTwoTerminalDc.getInverter())) .setName(psseTwoTerminalDc.getName()) - .setConnectableBus(busIdI) .setLossFactor((float) lossFactor) - .setPowerFactor((float) getLccConverterPowerFactor(psseTwoTerminalDc.getInverter())) - .setBus(psseTwoTerminalDc.getMdc() == 0 ? null : busIdI); + .setPowerFactor((float) getLccConverterPowerFactor(psseTwoTerminalDc.getInverter())); + + String equipmentIdI = getNodeBreakerEquipmentId(PSSE_TWO_TERMINAL_DC_LINE, psseTwoTerminalDc.getInverter().getIp(), psseTwoTerminalDc.getName()); + OptionalInt nodeI = nodeBreakerImport.getNode(getNodeBreakerEquipmentIdBus(equipmentIdI, psseTwoTerminalDc.getInverter().getIp())); + if (nodeI.isPresent()) { + adderI.setNode(nodeI.getAsInt()); + } else { + adderI.setConnectableBus(busIdI); + adderI.setBus(psseTwoTerminalDc.getMdc() == 0 ? null : busIdI); + } LccConverterStation cI = adderI.add(); HvdcLineAdder adder = getNetwork().newHvdcLine() @@ -100,4 +117,5 @@ private String getTwoTerminalDcId(PsseTwoTerminalDcTransmissionLine psseTwoTermi } private final PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc; + private final NodeBreakerImport nodeBreakerImport; } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java index c0dbb392d1a..396893f9e23 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java @@ -7,15 +7,21 @@ */ package com.powsybl.psse.converter; -import java.util.Objects; +import java.util.*; +import java.util.stream.Collectors; -import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.Substation; -import com.powsybl.iidm.network.TopologyKind; -import com.powsybl.iidm.network.VoltageLevel; +import com.powsybl.iidm.network.*; +import com.powsybl.iidm.network.extensions.SlackTerminal; import com.powsybl.iidm.network.util.ContainersMapping; import com.powsybl.psse.converter.PsseImporter.PerUnitContext; +import com.powsybl.psse.converter.NodeBreakerValidation.NodeBreakerControl; +import com.powsybl.psse.model.PsseException; import com.powsybl.psse.model.pf.PsseBus; +import com.powsybl.psse.model.pf.PssePowerFlowModel; +import com.powsybl.psse.model.pf.PsseSubstation; +import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationNode; +import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationSwitchingDevice; +import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationEquipmentTerminal; /** * @author Luma Zamarreño {@literal } @@ -23,23 +29,37 @@ */ class VoltageLevelConverter extends AbstractConverter { - VoltageLevelConverter(PsseBus psseBus, ContainersMapping containerMapping, PerUnitContext perUnitContext, Network network) { + VoltageLevelConverter(PsseBus psseBus, ContainersMapping containerMapping, PerUnitContext perUnitContext, Network network, NodeBreakerValidation nodeBreakerValidation, NodeBreakerImport nodeBreakerImport) { super(containerMapping, network); this.psseBus = Objects.requireNonNull(psseBus); this.perUnitContext = Objects.requireNonNull(perUnitContext); + this.nodeBreakerValidation = Objects.requireNonNull(nodeBreakerValidation); + this.nodeBreakerImport = Objects.requireNonNull(nodeBreakerImport); } VoltageLevel create(Substation substation) { String voltageLevelId = getContainersMapping().getVoltageLevelId(psseBus.getI()); - double nominalV = getNominalV(psseBus, perUnitContext.isIgnoreBaseVoltage()); VoltageLevel voltageLevel = getNetwork().getVoltageLevel(voltageLevelId); if (voltageLevel == null) { + double nominalV = getNominalV(psseBus, perUnitContext.isIgnoreBaseVoltage()); + boolean isNodeBreakerValid = nodeBreakerValidation.isNodeBreakerSubstationCoherent(getContainersMapping().getBusesSet(voltageLevelId)); + + TopologyKind topologyKind = isNodeBreakerValid ? TopologyKind.NODE_BREAKER : TopologyKind.BUS_BREAKER; voltageLevel = substation.newVoltageLevel() .setId(voltageLevelId) .setNominalV(nominalV) - .setTopologyKind(TopologyKind.BUS_BREAKER) + .setTopologyKind(topologyKind) .add(); + + if (isNodeBreakerValid) { + addNodeBreakerEquipment(voltageLevelId, voltageLevel, nodeBreakerValidation, nodeBreakerImport); + } + } + + // Add slack control data + if (voltageLevel.getTopologyKind().equals(TopologyKind.NODE_BREAKER) && psseBus.getIde() == 3) { + nodeBreakerImport.addSlackControl(psseBus.getI(), voltageLevelId, obtainSlackNode(nodeBreakerValidation, psseBus.getI())); } return voltageLevel; } @@ -48,6 +68,269 @@ static double getNominalV(PsseBus psseBus, boolean isIgnoreBaseVoltage) { return isIgnoreBaseVoltage || psseBus.getBaskv() == 0 ? 1 : psseBus.getBaskv(); } + private void addNodeBreakerEquipment(String voltageLevelId, VoltageLevel voltageLevel, NodeBreakerValidation nodeBreakerValidation, NodeBreakerImport nodeBreakerImport) { + Set buses = getContainersMapping().getBusesSet(voltageLevelId); + PsseSubstation substation = buses.stream().map(nodeBreakerValidation::getSubstationIfOnlyOneExists) + .filter(Optional::isPresent) + .map(Optional::get) + .findFirst().orElseThrow(); + + nodeBreakerImport.addTopologicalBuses(buses); + + for (PsseSubstationSwitchingDevice switchingDevice : substation.getSwitchingDevices()) { + voltageLevel.getNodeBreakerView().newSwitch() + .setId(getSwitchId(voltageLevelId, switchingDevice)) + .setName(switchingDevice.getName()) + .setNode1(switchingDevice.getNi()) + .setNode2(switchingDevice.getNj()) + .setKind(obtainSwitchingKind(switchingDevice.getType())) + .setOpen(switchingDevice.getStatus() != 1) + .add(); + } + + // Define where equipment must be connected + int lastNode = substation.getNodes().stream().map(PsseSubstationNode::getNi).max(Comparator.naturalOrder()).orElseThrow(); + Set nodesWithEquipment = new HashSet<>(); + for (PsseSubstationEquipmentTerminal equipmentTerminal : substation.getEquipmentTerminals()) { + String equipmentId = getNodeBreakerEquipmentId(equipmentTerminal.getType(), equipmentTerminal.getI(), equipmentTerminal.getJ(), equipmentTerminal.getK(), equipmentTerminal.getId()); + int bus = obtainBus(equipmentTerminal, buses); + String equipmentIdBus = getNodeBreakerEquipmentIdBus(equipmentId, bus); + // IIDM only allows one piece of equipment by node + if (nodesWithEquipment.contains(equipmentTerminal.getNi())) { + lastNode++; + voltageLevel.getNodeBreakerView().newInternalConnection().setNode1(equipmentTerminal.getNi()).setNode2(lastNode).add(); + nodeBreakerImport.addEquipment(equipmentIdBus, lastNode); + } else { + nodeBreakerImport.addEquipment(equipmentIdBus, equipmentTerminal.getNi()); + nodesWithEquipment.add(equipmentTerminal.getNi()); + } + } + + // Define where controls must be connected. Psse nodes and iidm nodes are identical. + buses.forEach(bus -> { + List controls = nodeBreakerValidation.getControls(bus); + controls.forEach(control -> nodeBreakerImport.addControl(getNodeBreakerEquipmentIdBus(control.getEquipmentId(), bus), voltageLevelId, control.getNode())); + }); + } + + private static SwitchKind obtainSwitchingKind(int type) { + return type == 2 ? SwitchKind.BREAKER : SwitchKind.DISCONNECTOR; + } + + private static int obtainBus(PsseSubstationEquipmentTerminal equipmentTerminal, Set buses) { + return buses.stream().filter(bus -> bus == equipmentTerminal.getI() || bus == equipmentTerminal.getJ() || bus == equipmentTerminal.getK()).min(Comparator.naturalOrder()).orElseThrow(); + } + + private static String getSwitchId(String voltageLevelId, PsseSubstationSwitchingDevice switchingDevice) { + return voltageLevelId + "-Sw-" + switchingDevice.getNi() + "-" + switchingDevice.getNj() + "-" + switchingDevice.getCkt(); + } + + private static int obtainSlackNode(NodeBreakerValidation nodeBreakerValidation, int bus) { + PsseSubstation psseSubstation = nodeBreakerValidation.getSubstationIfOnlyOneExists(bus).orElseThrow(); + return psseSubstation.getNodes().stream().filter(n -> n.getI() == bus).map(PsseSubstationNode::getNi).findFirst().orElseThrow(); + } + + static NodeBreakerExport mapSubstations(Network network, PssePowerFlowModel psseModel) { + int maxPsseBus = psseModel.getBuses().stream().map(PsseBus::getI).max(Comparator.naturalOrder()).orElseThrow(); + NodeBreakerExport nodeBreakerExport = new NodeBreakerExport(maxPsseBus); + + psseModel.getSubstations().forEach(psseSubstation -> mapSubstation(network, psseSubstation, nodeBreakerExport)); + + return nodeBreakerExport; + } + + private static void mapSubstation(Network network, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { + VoltageLevel voltageLevel = obtainVoltageLevel(network, psseSubstation); + if (voltageLevel != null && isNodeBreaker(voltageLevel)) { + mapBusBreakerBusesToPsseBuses(voltageLevel, psseSubstation, nodeBreakerExport); + mapIsolatedPsseNodesToPsseBuses(voltageLevel, psseSubstation, nodeBreakerExport); + mapEquipmentIdBustoBus(voltageLevel, psseSubstation, nodeBreakerExport); + } + } + + private static VoltageLevel obtainVoltageLevel(Network network, PsseSubstation psseSubstation) { + Set busesSet = psseSubstation.getNodes().stream().map(PsseSubstationNode::getI).collect(Collectors.toSet()); + String voltageLevelId = getVoltageLevelId(busesSet); + return network.getVoltageLevel(voltageLevelId); + } + + private static boolean isNodeBreaker(VoltageLevel voltageLevel) { + Objects.requireNonNull(voltageLevel); + return voltageLevel.getTopologyKind().equals(TopologyKind.NODE_BREAKER); + } + + private static void mapBusBreakerBusesToPsseBuses(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { + Set psseNodesSet = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).collect(Collectors.toSet()); + Map> busBreakerBusIdNodeList = obtainBusBreakerBusIdNodeList(voltageLevel); + + // First, buses with more psse nodes + Comparator comp = Comparator.comparingInt((String key) -> onlyPsseNodes(busBreakerBusIdNodeList.get(key), psseNodesSet).size()) + .reversed() + .thenComparing(Comparator.naturalOrder()); + + busBreakerBusIdNodeList.keySet().stream().sorted(comp).forEach(key -> { + + Optional bus = mapPsseBus(psseSubstation, nodeBreakerExport); + int busType = obtainBusBreakerBusType(voltageLevel, key); + if (bus.isPresent()) { + nodeBreakerExport.addBusMapping(bus.get(), key, busType); + nodeBreakerExport.addNodesBusMapping(voltageLevel.getId(), onlyPsseNodes(busBreakerBusIdNodeList.get(key), psseNodesSet), bus.get(), true); + } else { + int newBus = nodeBreakerExport.getNewPsseBus(); + nodeBreakerExport.addNewBus(newBus, selectCopyBus(psseSubstation), key, busType); + nodeBreakerExport.addNodesBusMapping(voltageLevel.getId(), onlyPsseNodes(busBreakerBusIdNodeList.get(key), psseNodesSet), newBus, true); + } + }); + } + + // discard nodes associated with internal connections + private static List onlyPsseNodes(List iidmNodes, Set psseNodesSet) { + return iidmNodes.stream().filter(psseNodesSet::contains).toList(); + } + + private static Map> obtainBusBreakerBusIdNodeList(VoltageLevel voltageLevel) { + Map> busBreakerBusIdNodeList = new HashMap<>(); + + for (int node : voltageLevel.getNodeBreakerView().getNodes()) { + Terminal terminal = obtainTerminalNode(voltageLevel, node); + if (terminal != null) { + Bus bus = terminal.getBusBreakerView().getBus(); + if (bus != null) { + busBreakerBusIdNodeList.computeIfAbsent(bus.getId(), k -> new ArrayList<>()).add(node); + } + } + } + return busBreakerBusIdNodeList; + } + + // Map to the free psse bus with more matching nodes + private static Optional mapPsseBus(PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { + + Comparator comp = Comparator.comparingInt((Integer b) -> nodesAssociatedWithBus(psseSubstation, b).size()) + .reversed() + .thenComparing(Comparator.naturalOrder()); + + return psseSubstation.getNodes().stream() + .map(PsseSubstationNode::getI).filter(nodeBreakerExport::isFreeBus) + .collect(Collectors.toSet()) + .stream().min(comp); + } + + private static int selectCopyBus(PsseSubstation psseSubstation) { + return psseSubstation.getNodes().stream().map(PsseSubstationNode::getI).min(Comparator.naturalOrder()).orElseThrow(); + } + + private static List nodesAssociatedWithBus(PsseSubstation psseSubstation, int bus) { + return psseSubstation.getNodes().stream().filter(n -> n.getI() == bus).map(PsseSubstationNode::getNi).toList(); + } + + private static int obtainBusBreakerBusType(VoltageLevel voltageLevel, String busBreakerBusId) { + Bus bus = voltageLevel.getBusBreakerView().getBus(busBreakerBusId); + if (bus == null) { // unexpected + return 4; + } + SlackTerminal slackTerminal = voltageLevel.getExtension(SlackTerminal.class); + if (slackTerminal != null && bus.equals(slackTerminal.getTerminal().getBusBreakerView().getBus())) { + return 3; + } + return bus.getGeneratorStream().anyMatch(VoltageLevelConverter::withLocalRegulatingControl) ? 2 : 1; + } + + private static boolean withLocalRegulatingControl(Generator generator) { + return generator.isVoltageRegulatorOn() + && generator.getTerminal().getBusBreakerView().getBus().equals(generator.getRegulatingTerminal().getBusBreakerView().getBus()); + } + + private static void mapIsolatedPsseNodesToPsseBuses(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { + mapIsolatedPsseNodesToTheAssociatedFreeBus(voltageLevel, psseSubstation, nodeBreakerExport); + mapIsolatedPsseNodesToFreeBus(voltageLevel, psseSubstation, nodeBreakerExport); + mapIsolatedPsseNodesToNewBus(voltageLevel, psseSubstation, nodeBreakerExport); + } + + private static void mapIsolatedPsseNodesToTheAssociatedFreeBus(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { + List isolatedNodes = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).filter(node -> nodeBreakerExport.isFreeNode(voltageLevel.getId(), node)).toList(); + isolatedNodes.forEach(node -> { + Optional bus = psseSubstation.getNodes().stream() + .filter(n -> n.getNi() == node && nodeBreakerExport.isFreeBus(n.getI())) + .map(PsseSubstationNode::getI).min(Comparator.naturalOrder()); + if (bus.isPresent()) { + nodeBreakerExport.addNodeBusMapping(voltageLevel.getId(), node, bus.get(), false); + nodeBreakerExport.addIsolatedBus(bus.get()); + } + }); + } + + private static void mapIsolatedPsseNodesToFreeBus(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { + List isolatedNodes = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).filter(node -> nodeBreakerExport.isFreeNode(voltageLevel.getId(), node)).toList(); + isolatedNodes.forEach(node -> { + Optional bus = psseSubstation.getNodes().stream() + .map(PsseSubstationNode::getI) + .filter(nodeBreakerExport::isFreeBus) + .min(Comparator.naturalOrder()); + if (bus.isPresent()) { + nodeBreakerExport.addNodeBusMapping(voltageLevel.getId(), node, bus.get(), false); + nodeBreakerExport.addIsolatedBus(bus.get()); + } + }); + } + + private static void mapIsolatedPsseNodesToNewBus(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { + List isolatedNodes = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).filter(node -> nodeBreakerExport.isFreeNode(voltageLevel.getId(), node)).toList(); + isolatedNodes.forEach(node -> { + int bus = nodeBreakerExport.getNewPsseBus(); + nodeBreakerExport.addNodeBusMapping(voltageLevel.getId(), node, bus, false); + nodeBreakerExport.addIsolatedBus(bus); + }); + } + + private static void mapEquipmentIdBustoBus(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { + psseSubstation.getEquipmentTerminals().forEach(equipmentTerminal -> { + String equipmentId = getNodeBreakerEquipmentId(equipmentTerminal.getType(), equipmentTerminal.getI(), equipmentTerminal.getJ(), equipmentTerminal.getK(), equipmentTerminal.getId()); + nodeBreakerExport.getNodeBus(voltageLevel.getId(), equipmentTerminal.getNi()).ifPresent(bus -> { + if (bus != equipmentTerminal.getI()) { + nodeBreakerExport.addEquipmentIdBus(getNodeBreakerEquipmentIdBus(equipmentId, equipmentTerminal.getI()), bus); + } + }); + }); + } + + static void updateSubstations(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { + psseModel.getSubstations().forEach(psseSubstation -> { + VoltageLevel voltageLevel = obtainVoltageLevel(network, psseSubstation); + if (voltageLevel != null && isNodeBreaker(voltageLevel)) { + updateSubstation(voltageLevel, psseSubstation, nodeBreakerExport); + } + }); + } + + private static void updateSubstation(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { + + psseSubstation.getNodes().forEach(psseSubstationNode -> { + int bus = nodeBreakerExport.getNodeBus(voltageLevel.getId(), psseSubstationNode.getNi()).orElseThrow(); + boolean inService = nodeBreakerExport.isNodeInService(voltageLevel.getId(), psseSubstationNode.getNi()).orElseThrow(); + psseSubstationNode.setI(bus); + psseSubstationNode.setStatus(inService ? 1 : 0); + }); + + psseSubstation.getSwitchingDevices().forEach(switchingDevice -> { + String switchId = getSwitchId(voltageLevel.getId(), switchingDevice); + Switch sw = voltageLevel.getNodeBreakerView().getSwitch(switchId); + if (sw == null) { + throw new PsseException("Unexpected null breaker: " + switchId); + } + switchingDevice.setStatus(sw.isOpen() ? 0 : 1); + }); + + psseSubstation.getEquipmentTerminals().forEach(equipmentTerminal -> { + String equipmentId = getNodeBreakerEquipmentId(equipmentTerminal.getType(), equipmentTerminal.getI(), equipmentTerminal.getJ(), equipmentTerminal.getK(), equipmentTerminal.getId()); + nodeBreakerExport.getEquipmentIdBusBus(getNodeBreakerEquipmentIdBus(equipmentId, equipmentTerminal.getI())).ifPresent(equipmentTerminal::setI); + nodeBreakerExport.getEquipmentIdBusBus(getNodeBreakerEquipmentIdBus(equipmentId, equipmentTerminal.getJ())).ifPresent(equipmentTerminal::setJ); + nodeBreakerExport.getEquipmentIdBusBus(getNodeBreakerEquipmentIdBus(equipmentId, equipmentTerminal.getK())).ifPresent(equipmentTerminal::setK); + }); + } + private final PsseBus psseBus; private final PerUnitContext perUnitContext; + private final NodeBreakerValidation nodeBreakerValidation; + private final NodeBreakerImport nodeBreakerImport; } diff --git a/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseExporterTest.java b/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseExporterTest.java index 6bd07439e7a..af3b5afad4d 100644 --- a/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseExporterTest.java +++ b/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseExporterTest.java @@ -22,12 +22,7 @@ import com.powsybl.commons.datasource.ResourceDataSource; import com.powsybl.commons.datasource.ResourceSet; import com.powsybl.commons.test.TestUtil; -import com.powsybl.iidm.network.Generator; -import com.powsybl.iidm.network.Line; -import com.powsybl.iidm.network.Load; -import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.ShuntCompensator; -import com.powsybl.iidm.network.TwoWindingsTransformer; +import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.impl.NetworkFactoryImpl; import java.io.UncheckedIOException; @@ -250,6 +245,24 @@ void importExportRawxCaseWithSpecialCharacters() throws IOException { exportTest(network, "RawxCaseWithSpecialCharacters_exported", "RawxCaseWithSpecialCharacters_exported.rawx"); } + @Test + void importExportTestRaw14NodeBreaker() throws IOException { + Network network = importTest("IEEE_14_bus_nodeBreaker_rev35", "IEEE_14_bus_nodeBreaker_rev35.raw", false); + exportTest(network, "IEEE_14_bus_nodeBreaker_rev35_exported", "IEEE_14_bus_nodeBreaker_rev35_exported.raw"); + } + + @Test + void importExportTestRaw14NodeBreakerSplitBus() throws IOException { + Network network = importTest("IEEE_14_bus_nodeBreaker_rev35", "IEEE_14_bus_nodeBreaker_rev35.raw", false); + + VoltageLevel vl1 = network.getVoltageLevel("VL1"); + vl1.getNodeBreakerView().getSwitch("VL1-Sw-1-2-1 ").setOpen(true); + VoltageLevel vl2 = network.getVoltageLevel("VL2"); + vl2.getNodeBreakerView().getSwitch("VL2-Sw-1-2-1 ").setOpen(true); + + exportTest(network, "IEEE_14_bus_nodeBreaker_rev35_split_bus_exported", "IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw"); + } + @Test void exportDataTest() throws IOException { PsseExporter psseExporter = new PsseExporter(); diff --git a/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseImporterTest.java b/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseImporterTest.java index 8f567b0c3bc..18039c1872c 100644 --- a/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseImporterTest.java +++ b/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseImporterTest.java @@ -7,13 +7,9 @@ */ package com.powsybl.psse.converter; -import com.powsybl.commons.datasource.ReadOnlyDataSource; -import com.powsybl.commons.datasource.ResourceDataSource; -import com.powsybl.commons.datasource.ResourceSet; +import com.powsybl.commons.datasource.*; import com.powsybl.commons.test.AbstractSerDeTest; -import com.powsybl.iidm.network.Importer; -import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.NetworkFactory; +import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.impl.NetworkFactoryImpl; import com.powsybl.iidm.serde.NetworkSerDe; import com.powsybl.psse.model.PsseException; @@ -44,8 +40,9 @@ void baseTest() { Importer importer = new PsseImporter(); assertEquals("PSS/E", importer.getFormat()); assertEquals("PSS/E Format to IIDM converter", importer.getComment()); - assertEquals(1, importer.getParameters().size()); + assertEquals(2, importer.getParameters().size()); assertEquals("psse.import.ignore-base-voltage", importer.getParameters().get(0).getName()); + assertEquals("psse.import.ignore-node-breaker-topology", importer.getParameters().get(1).getName()); } private void testNetwork(Network network) throws IOException { @@ -292,4 +289,9 @@ void dataSourceExistsTest() { void importTest14ZipLoad() throws IOException { importTest("IEEE_14_buses_zip_load", "IEEE_14_buses_zip_load.raw", false); } + + @Test + void importTest14NodeBreaker() throws IOException { + importTest("IEEE_14_bus_nodeBreaker_rev35", "IEEE_14_bus_nodeBreaker_rev35.raw", false); + } } diff --git a/psse/psse-converter/src/test/resources/ExampleVersion32.xiidm b/psse/psse-converter/src/test/resources/ExampleVersion32.xiidm index 0dfa30a42e3..eb929bba50b 100644 --- a/psse/psse-converter/src/test/resources/ExampleVersion32.xiidm +++ b/psse/psse-converter/src/test/resources/ExampleVersion32.xiidm @@ -25,10 +25,9 @@ - - + @@ -54,12 +53,12 @@ - + - + @@ -77,16 +76,16 @@ - + - - - - + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_118_bus.xiidm b/psse/psse-converter/src/test/resources/IEEE_118_bus.xiidm index c18ea69dcd6..b953b309b75 100644 --- a/psse/psse-converter/src/test/resources/IEEE_118_bus.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_118_bus.xiidm @@ -6,7 +6,6 @@ - @@ -34,7 +33,6 @@ - @@ -47,7 +45,6 @@ - @@ -55,7 +52,7 @@ - + @@ -67,7 +64,6 @@ - @@ -112,7 +108,6 @@ - @@ -140,7 +135,6 @@ - @@ -162,7 +156,7 @@ - + @@ -174,7 +168,6 @@ - @@ -186,7 +179,6 @@ - @@ -230,7 +222,6 @@ - @@ -249,7 +240,7 @@ - + @@ -261,7 +252,6 @@ - @@ -289,7 +279,6 @@ - @@ -301,7 +290,6 @@ - @@ -321,7 +309,6 @@ - @@ -344,7 +331,6 @@ - @@ -360,7 +346,7 @@ - + @@ -380,7 +366,6 @@ - @@ -400,7 +385,6 @@ - @@ -442,7 +426,6 @@ - @@ -476,7 +459,6 @@ - @@ -520,7 +502,6 @@ - @@ -532,7 +513,6 @@ - @@ -544,7 +524,6 @@ - @@ -573,12 +552,11 @@ - - + @@ -602,7 +580,7 @@ - + @@ -614,7 +592,6 @@ - @@ -630,12 +607,11 @@ - - + @@ -659,7 +635,7 @@ - + @@ -671,7 +647,6 @@ - @@ -690,7 +665,6 @@ - @@ -702,7 +676,6 @@ - @@ -714,7 +687,6 @@ - @@ -737,7 +709,6 @@ - @@ -749,7 +720,6 @@ - @@ -781,12 +751,11 @@ - - + @@ -828,7 +797,6 @@ - @@ -876,7 +844,6 @@ - @@ -888,7 +855,6 @@ - @@ -900,7 +866,6 @@ - @@ -960,7 +925,6 @@ - @@ -972,7 +936,6 @@ - @@ -1000,7 +963,6 @@ - @@ -1012,7 +974,6 @@ - @@ -1024,7 +985,6 @@ - @@ -1047,7 +1007,6 @@ - @@ -1078,7 +1037,6 @@ - @@ -1103,7 +1061,6 @@ - @@ -1115,7 +1072,6 @@ - @@ -1143,7 +1099,6 @@ - @@ -1165,183 +1120,183 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_bus.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_bus.xiidm index ce91cadaba9..f4618338ef8 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_bus.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_bus.xiidm @@ -16,7 +16,6 @@ - @@ -28,7 +27,6 @@ - @@ -47,12 +45,12 @@ - + - + @@ -65,13 +63,12 @@ - - + @@ -127,23 +124,23 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm new file mode 100644 index 00000000000..7f5194128c5 --- /dev/null +++ b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw new file mode 100644 index 00000000000..7df443e5c9a --- /dev/null +++ b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw @@ -0,0 +1,131 @@ +0,100.0,35,0.0,0.0,60.0 + 08/19/93 UW ARCHIVE 100.0 1962 W IEEE 14 Bus Test Case + +0 / END OF SYSTEM-WIDE DATA, BEGIN BUS DATA +1,'Bus 1 ',138.0,3,1,1,1,1.0,0.0 +2,'Bus 2 ',138.0,2,1,1,1,1.0,0.0 +3,'Bus 3 ',138.0,2,1,1,1,1.01,-12.725 +4,'Bus 4 ',138.0,1,1,1,1,1.01767,-10.3128 +5,'Bus 5 ',138.0,1,1,1,1,1.01951,-8.7738 +6,'Bus 6 ',138.0,2,1,1,1,1.07,-14.2209 +7,'Bus 7 ',138.0,1,1,1,1,1.06152,-13.3596 +8,'Bus 8 ',138.0,2,1,1,1,1.09,-13.3596 +9,'Bus 9 ',138.0,1,1,1,1,1.05593,-14.9385 +10,'Bus 10 ',138.0,1,1,1,1,1.05099,-15.0972 +11,'Bus 11 ',138.0,1,1,1,1,1.05691,-14.7906 +12,'Bus 12 ',138.0,1,1,1,1,1.05519,-15.0755 +13,'Bus 13 ',138.0,1,1,1,1,1.05038,-15.1562 +14,'Bus 14 ',138.0,1,1,1,1,1.03553,-16.0336 +0 / END OF BUS DATA, BEGIN LOAD DATA +2,'1 ',1,1,1,21.7,12.7,0.0,0.0,0.0,-0.0,1,1 +3,'1 ',1,1,1,94.2,19.0,0.0,0.0,0.0,-0.0,1,1 +4,'1 ',1,1,1,47.8,-3.9,0.0,0.0,0.0,-0.0,1,1 +5,'1 ',1,1,1,7.6,1.6,0.0,0.0,0.0,-0.0,1,1 +6,'1 ',1,1,1,11.2,7.5,0.0,0.0,0.0,-0.0,1,1 +9,'1 ',1,1,1,29.5,16.6,0.0,0.0,0.0,-0.0,1,1 +10,'1 ',1,1,1,9.0,5.8,0.0,0.0,0.0,-0.0,1,1 +11,'1 ',1,1,1,3.5,1.8,0.0,0.0,0.0,-0.0,1,1 +12,'1 ',1,1,1,6.1,1.6,0.0,0.0,0.0,-0.0,1,1 +13,'1 ',1,1,1,13.5,5.8,0.0,0.0,0.0,-0.0,1,1 +14,'1 ',1,1,1,14.9,5.0,0.0,0.0,0.0,-0.0,1,1 +0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA +9,' 1',1,0.0,19.0 +0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA +1,'1 ',232.392,-16.549,0.0,0.0,1.06,0,0,615.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +2,'1 ',40.0,43.556,50.0,-40.0,1.045,0,0,60.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +3,'1 ',0.0,25.075,40.0,0.0,1.01,0,0,60.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +6,'1 ',0.0,12.73,24.0,-6.0,1.07,0,0,25.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +8,'1 ',0.0,17.623,24.0,-6.0,1.09,0,0,25.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +0 / END OF GENERATOR DATA, BEGIN BRANCH DATA +1,2,'1 ',0.01938,0.05917,0.0528,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +1,5,'1 ',0.05403,0.22304,0.0492,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +2,3,'1 ',0.04699,0.19797,0.0438,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +2,4,'1 ',0.05811,0.17632,0.034,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +2,5,'1 ',0.05695,0.17388,0.0346,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +3,4,'1 ',0.06701,0.17103,0.0128,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +4,5,'1 ',0.01335,0.04211,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +6,11,'1 ',0.09498,0.1989,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +6,12,'1 ',0.12291,0.25581,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +6,13,'1 ',0.06615,0.13027,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +7,8,'1 ',0.0,0.17615,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +7,9,'1 ',0.0,0.11001,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +9,10,'1 ',0.03181,0.0845,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +9,14,'1 ',0.12711,0.27038,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +10,11,'1 ',0.08205,0.19207,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +12,13,'1 ',0.22092,0.19988,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +13,14,'1 ',0.17093,0.34802,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +0 / END OF BRANCH DATA, BEGIN SYSTEM SWITCHING DEVICE DATA +0 / END OF SYSTEM SWITCHING DEVICE DATA, BEGIN TRANSFORMER DATA +4,7,0,'1 ',1,1,1,0.0,0.0,2,' ',1,1,1.0,0,1.0,0,1.0,0,1.0 +0.0,0.20912,100.0 +0.978,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,159,0,0.0,0.0 +1.0,0.0 +4,9,0,'1 ',1,1,1,0.0,0.0,2,' ',1,1,1.0,0,1.0,0,1.0,0,1.0 +0.0,0.55618,100.0 +0.969,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,159,0,0.0,0.0 +1.0,0.0 +5,6,0,'1 ',1,1,1,0.0,0.0,2,' ',1,1,1.0,0,1.0,0,1.0,0,1.0 +0.0,0.25202,100.0 +0.932,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,159,0,0.0,0.0 +1.0,0.0 +0 / END OF TRANSFORMER DATA, BEGIN AREA DATA +1,2,0.0,999.99,'IEEE14 ' +0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA +0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA +0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA +0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA +0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA +0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA +0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA +0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA +1,'1' +0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA +0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA +0 / END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA +0 / END OF GNE DEVICE DATA, BEGIN INDUCTION MACHINE DATA +0 / END OF INDUCTION MACHINE DATA, BEGIN SUBSTATION DATA +1,'STATION 1',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',1,1,1.0,0.0 +2,'NB2',1,1,1.0,0.0 +3,'NL2',1,1,1.0,0.0 +4,'NL5',1,1,1.0,0.0 +5,'NG1',1,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-BranchToBus2','2',1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-BranchToBus5','2',1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-Gen1','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +1,5,'M','1 ' +1,3,'B',2,'1 ' +1,4,'B',5,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +2,'STATION 5',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',2,1,1.0,0.0 +2,'NB2',2,1,1.0,0.0 +3,'NL3',2,1,1.0,0.0 +4,'NL4',2,1,1.0,0.0 +5,'NL5',2,1,1.0,0.0 +6,'NL1',2,1,1.0,0.0 +7,'NG1',2,1,1.0,0.0 +8,'NLd1',2,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 +1,6,'1 ','Sw-BranchToBus1','2',1,1,0.0,0.0,0.0,0.0 +1,7,'1 ','Sw-Gen1','2',1,1,0.0,0.0,0.0,0.0 +1,8,'1 ','Sw-Load1','2',1,1,0.0,0.0,0.0,0.0 +2,3,'1 ','Sw-BranchToBus3','2',1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-BranchToBus4','2',1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-BranchToBus5','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +2,7,'M','1 ' +2,8,'L','1 ' +2,6,'B',1,'1 ' +2,3,'B',3,'1 ' +2,4,'B',4,'1 ' +2,5,'B',5,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +0 / END OF SUBSTATION DATA +Q diff --git a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw new file mode 100644 index 00000000000..d0aa7e2f7cf --- /dev/null +++ b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw @@ -0,0 +1,133 @@ +0,100.0,35,0.0,0.0,60.0 + 08/19/93 UW ARCHIVE 100.0 1962 W IEEE 14 Bus Test Case + +0 / END OF SYSTEM-WIDE DATA, BEGIN BUS DATA +1,'Bus 1 ',138.0,3,1,1,1,1.0,0.0 +2,'Bus 2 ',138.0,2,1,1,1,1.0,0.0 +3,'Bus 3 ',138.0,2,1,1,1,1.01,-12.725 +4,'Bus 4 ',138.0,1,1,1,1,1.01767,-10.3128 +5,'Bus 5 ',138.0,1,1,1,1,1.01951,-8.7738 +6,'Bus 6 ',138.0,2,1,1,1,1.07,-14.2209 +7,'Bus 7 ',138.0,1,1,1,1,1.06152,-13.3596 +8,'Bus 8 ',138.0,2,1,1,1,1.09,-13.3596 +9,'Bus 9 ',138.0,1,1,1,1,1.05593,-14.9385 +10,'Bus 10 ',138.0,1,1,1,1,1.05099,-15.0972 +11,'Bus 11 ',138.0,1,1,1,1,1.05691,-14.7906 +12,'Bus 12 ',138.0,1,1,1,1,1.05519,-15.0755 +13,'Bus 13 ',138.0,1,1,1,1,1.05038,-15.1562 +14,'Bus 14 ',138.0,1,1,1,1,1.03553,-16.0336 +15,'Bus 1-15 ',138.0,1,1,1,1,1.0,0.0 +16,'Bus 2-16 ',138.0,1,1,1,1,1.0,0.0 +0 / END OF BUS DATA, BEGIN LOAD DATA +2,'1 ',1,1,1,21.7,12.7,0.0,0.0,0.0,-0.0,1,1 +3,'1 ',1,1,1,94.2,19.0,0.0,0.0,0.0,-0.0,1,1 +4,'1 ',1,1,1,47.8,-3.9,0.0,0.0,0.0,-0.0,1,1 +5,'1 ',1,1,1,7.6,1.6,0.0,0.0,0.0,-0.0,1,1 +6,'1 ',1,1,1,11.2,7.5,0.0,0.0,0.0,-0.0,1,1 +9,'1 ',1,1,1,29.5,16.6,0.0,0.0,0.0,-0.0,1,1 +10,'1 ',1,1,1,9.0,5.8,0.0,0.0,0.0,-0.0,1,1 +11,'1 ',1,1,1,3.5,1.8,0.0,0.0,0.0,-0.0,1,1 +12,'1 ',1,1,1,6.1,1.6,0.0,0.0,0.0,-0.0,1,1 +13,'1 ',1,1,1,13.5,5.8,0.0,0.0,0.0,-0.0,1,1 +14,'1 ',1,1,1,14.9,5.0,0.0,0.0,0.0,-0.0,1,1 +0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA +9,' 1',1,0.0,19.0 +0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA +1,'1 ',232.392,-16.549,0.0,0.0,1.06,0,0,615.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +2,'1 ',40.0,43.556,50.0,-40.0,1.045,0,0,60.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +3,'1 ',0.0,25.075,40.0,0.0,1.01,0,0,60.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +6,'1 ',0.0,12.73,24.0,-6.0,1.07,0,0,25.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +8,'1 ',0.0,17.623,24.0,-6.0,1.09,0,0,25.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +0 / END OF GENERATOR DATA, BEGIN BRANCH DATA +15,2,'1 ',0.01938,0.05917,0.0528,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +1,5,'1 ',0.05403,0.22304,0.0492,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +16,3,'1 ',0.04699,0.19797,0.0438,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +16,4,'1 ',0.05811,0.17632,0.034,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +16,5,'1 ',0.05695,0.17388,0.0346,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +3,4,'1 ',0.06701,0.17103,0.0128,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +4,5,'1 ',0.01335,0.04211,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +6,11,'1 ',0.09498,0.1989,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +6,12,'1 ',0.12291,0.25581,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +6,13,'1 ',0.06615,0.13027,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +7,8,'1 ',0.0,0.17615,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +7,9,'1 ',0.0,0.11001,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +9,10,'1 ',0.03181,0.0845,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +9,14,'1 ',0.12711,0.27038,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +10,11,'1 ',0.08205,0.19207,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +12,13,'1 ',0.22092,0.19988,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +13,14,'1 ',0.17093,0.34802,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +0 / END OF BRANCH DATA, BEGIN SYSTEM SWITCHING DEVICE DATA +0 / END OF SYSTEM SWITCHING DEVICE DATA, BEGIN TRANSFORMER DATA +4,7,0,'1 ',1,1,1,0.0,0.0,2,' ',1,1,1.0,0,1.0,0,1.0,0,1.0 +0.0,0.20912,100.0 +0.978,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,159,0,0.0,0.0 +1.0,0.0 +4,9,0,'1 ',1,1,1,0.0,0.0,2,' ',1,1,1.0,0,1.0,0,1.0,0,1.0 +0.0,0.55618,100.0 +0.969,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,159,0,0.0,0.0 +1.0,0.0 +5,6,0,'1 ',1,1,1,0.0,0.0,2,' ',1,1,1.0,0,1.0,0,1.0,0,1.0 +0.0,0.25202,100.0 +0.932,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,159,0,0.0,0.0 +1.0,0.0 +0 / END OF TRANSFORMER DATA, BEGIN AREA DATA +1,2,0.0,999.99,'IEEE14 ' +0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA +0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA +0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA +0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA +0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA +0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA +0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA +0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA +1,'1' +0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA +0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA +0 / END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA +0 / END OF GNE DEVICE DATA, BEGIN INDUCTION MACHINE DATA +0 / END OF INDUCTION MACHINE DATA, BEGIN SUBSTATION DATA +1,'STATION 1',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',15,1,1.0,0.0 +2,'NB2',1,1,1.0,0.0 +3,'NL2',15,1,1.0,0.0 +4,'NL5',1,1,1.0,0.0 +5,'NG1',1,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-BranchToBus2','2',1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-BranchToBus5','2',1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-Gen1','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +1,5,'M','1 ' +15,3,'B',2,'1 ' +1,4,'B',5,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +2,'STATION 5',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',2,1,1.0,0.0 +2,'NB2',16,1,1.0,0.0 +3,'NL3',16,1,1.0,0.0 +4,'NL4',16,1,1.0,0.0 +5,'NL5',16,1,1.0,0.0 +6,'NL1',2,1,1.0,0.0 +7,'NG1',2,1,1.0,0.0 +8,'NLd1',2,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 +1,6,'1 ','Sw-BranchToBus1','2',1,1,0.0,0.0,0.0,0.0 +1,7,'1 ','Sw-Gen1','2',1,1,0.0,0.0,0.0,0.0 +1,8,'1 ','Sw-Load1','2',1,1,0.0,0.0,0.0,0.0 +2,3,'1 ','Sw-BranchToBus3','2',1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-BranchToBus4','2',1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-BranchToBus5','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +2,7,'M','1 ' +2,8,'L','1 ' +2,6,'B',15,'1 ' +16,3,'B',3,'1 ' +16,4,'B',4,'1 ' +16,5,'B',5,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +0 / END OF SUBSTATION DATA +Q diff --git a/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids.xiidm index badc5a94bbe..3eed48f2bcc 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids.xiidm @@ -9,7 +9,6 @@ - @@ -20,7 +19,6 @@ - @@ -33,7 +31,6 @@ - @@ -55,22 +52,22 @@ - + - + - + - + @@ -83,13 +80,12 @@ - - + @@ -145,25 +141,25 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm index 4f5e634be4d..1f07af48974 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm @@ -6,11 +6,9 @@ - - @@ -33,7 +31,6 @@ - @@ -46,7 +43,6 @@ - @@ -68,17 +64,17 @@ - + - + - + @@ -91,13 +87,12 @@ - - + @@ -157,25 +152,25 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_buses_zip_load.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_buses_zip_load.xiidm index e732810547b..24ecc834fae 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_buses_zip_load.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_buses_zip_load.xiidm @@ -16,7 +16,6 @@ - @@ -30,7 +29,6 @@ - @@ -49,12 +47,12 @@ - + - + @@ -67,13 +65,12 @@ - - + @@ -129,23 +126,23 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_isolated_buses.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_isolated_buses.xiidm index 1368b38a8e1..d8e04a291f6 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_isolated_buses.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_isolated_buses.xiidm @@ -16,7 +16,6 @@ - @@ -28,7 +27,6 @@ - @@ -47,12 +45,12 @@ - + - + @@ -65,13 +63,12 @@ - - + @@ -137,17 +134,17 @@ - + - + - + @@ -169,23 +166,23 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_24_bus.xiidm b/psse/psse-converter/src/test/resources/IEEE_24_bus.xiidm index eb403c5e8a9..5b01e2da3b6 100644 --- a/psse/psse-converter/src/test/resources/IEEE_24_bus.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_24_bus.xiidm @@ -6,7 +6,6 @@ - @@ -23,7 +22,6 @@ - @@ -41,14 +39,14 @@ - + - + @@ -75,7 +73,7 @@ - + @@ -83,7 +81,7 @@ - + @@ -91,7 +89,7 @@ - + @@ -99,7 +97,7 @@ - + @@ -107,7 +105,7 @@ - + @@ -136,7 +134,6 @@ - @@ -156,7 +153,6 @@ - @@ -168,7 +164,6 @@ - @@ -180,7 +175,6 @@ - @@ -192,7 +186,6 @@ - @@ -211,7 +204,6 @@ - @@ -263,7 +255,7 @@ - + @@ -271,7 +263,7 @@ - + @@ -279,7 +271,7 @@ - + @@ -287,7 +279,7 @@ - + @@ -295,7 +287,7 @@ - + @@ -303,7 +295,7 @@ - + @@ -311,7 +303,7 @@ - + @@ -319,7 +311,7 @@ - + @@ -327,7 +319,7 @@ - + @@ -335,7 +327,7 @@ - + @@ -343,7 +335,7 @@ - + @@ -351,7 +343,7 @@ - + @@ -359,7 +351,7 @@ - + @@ -367,7 +359,7 @@ - + @@ -375,7 +367,7 @@ - + @@ -383,7 +375,7 @@ - + @@ -391,7 +383,7 @@ - + @@ -399,7 +391,7 @@ - + @@ -407,7 +399,7 @@ - + @@ -415,7 +407,7 @@ - + @@ -423,7 +415,7 @@ - + @@ -431,7 +423,7 @@ - + @@ -439,7 +431,7 @@ - + @@ -447,7 +439,7 @@ - + @@ -455,7 +447,7 @@ - + @@ -463,7 +455,7 @@ - + @@ -471,7 +463,7 @@ - + @@ -479,7 +471,7 @@ - + @@ -487,7 +479,7 @@ - + @@ -495,7 +487,7 @@ - + @@ -503,7 +495,7 @@ - + @@ -511,7 +503,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/IEEE_30_bus.xiidm b/psse/psse-converter/src/test/resources/IEEE_30_bus.xiidm index 0e381a3e72a..31a96945618 100644 --- a/psse/psse-converter/src/test/resources/IEEE_30_bus.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_30_bus.xiidm @@ -16,7 +16,6 @@ - @@ -43,7 +42,7 @@ - + @@ -61,7 +60,6 @@ - @@ -87,7 +85,7 @@ - + @@ -98,7 +96,7 @@ - + @@ -124,7 +122,6 @@ - @@ -266,7 +263,7 @@ - + @@ -288,7 +285,7 @@ - + @@ -296,7 +293,7 @@ - + @@ -304,7 +301,7 @@ - + @@ -312,7 +309,7 @@ - + @@ -320,7 +317,7 @@ - + @@ -328,7 +325,7 @@ - + @@ -336,7 +333,7 @@ - + @@ -344,7 +341,7 @@ - + @@ -352,7 +349,7 @@ - + @@ -360,7 +357,7 @@ - + @@ -368,10 +365,10 @@ - - - - + + + + @@ -379,8 +376,8 @@ - - + + @@ -388,9 +385,9 @@ - - - + + + @@ -398,8 +395,8 @@ - - + + @@ -407,7 +404,7 @@ - + @@ -415,7 +412,7 @@ - + @@ -423,7 +420,7 @@ - + @@ -431,8 +428,8 @@ - - + + @@ -440,7 +437,7 @@ - + @@ -448,7 +445,7 @@ - + @@ -456,15 +453,15 @@ - - - - - - - - - + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_57_bus.xiidm b/psse/psse-converter/src/test/resources/IEEE_57_bus.xiidm index dddbc59a624..6c7126e390f 100644 --- a/psse/psse-converter/src/test/resources/IEEE_57_bus.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_57_bus.xiidm @@ -6,7 +6,6 @@ - @@ -18,7 +17,6 @@ - @@ -30,7 +28,6 @@ - @@ -47,12 +44,12 @@ - + - + @@ -72,7 +69,6 @@ - @@ -86,7 +82,7 @@ - + @@ -98,7 +94,6 @@ - @@ -111,13 +106,12 @@ - - + @@ -132,7 +126,7 @@ - + @@ -148,12 +142,12 @@ - + - + @@ -165,7 +159,6 @@ - @@ -180,7 +173,7 @@ - + @@ -194,7 +187,7 @@ - + @@ -208,7 +201,7 @@ - + @@ -246,7 +239,7 @@ - + @@ -274,7 +267,7 @@ - + @@ -331,7 +324,7 @@ - + @@ -383,7 +376,7 @@ - + @@ -397,7 +390,7 @@ - + @@ -469,71 +462,71 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/RawCaseWithSpecialCharacters.xiidm b/psse/psse-converter/src/test/resources/RawCaseWithSpecialCharacters.xiidm index e2ce31a7364..e3c9be1b25e 100644 --- a/psse/psse-converter/src/test/resources/RawCaseWithSpecialCharacters.xiidm +++ b/psse/psse-converter/src/test/resources/RawCaseWithSpecialCharacters.xiidm @@ -25,7 +25,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -69,8 +69,8 @@ - - + + @@ -110,13 +110,12 @@ - - + @@ -124,7 +123,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/SwitchedShunt.xiidm b/psse/psse-converter/src/test/resources/SwitchedShunt.xiidm index 11259c3c17e..8fd41650068 100644 --- a/psse/psse-converter/src/test/resources/SwitchedShunt.xiidm +++ b/psse/psse-converter/src/test/resources/SwitchedShunt.xiidm @@ -10,7 +10,6 @@ - @@ -35,7 +34,7 @@ - + @@ -43,7 +42,7 @@ - + @@ -69,7 +68,6 @@ - @@ -89,8 +87,8 @@ - - + + @@ -130,13 +128,12 @@ - - + @@ -144,7 +141,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/SwitchedShuntWithZeroVswlo.xiidm b/psse/psse-converter/src/test/resources/SwitchedShuntWithZeroVswlo.xiidm index e1f7e8edf55..9927981266f 100644 --- a/psse/psse-converter/src/test/resources/SwitchedShuntWithZeroVswlo.xiidm +++ b/psse/psse-converter/src/test/resources/SwitchedShuntWithZeroVswlo.xiidm @@ -10,7 +10,6 @@ - @@ -35,7 +34,7 @@ - + @@ -43,7 +42,7 @@ - + @@ -69,7 +68,6 @@ - @@ -89,8 +87,8 @@ - - + + @@ -130,13 +128,12 @@ - - + @@ -144,7 +141,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/ThreeMIB_T3W_modified.xiidm b/psse/psse-converter/src/test/resources/ThreeMIB_T3W_modified.xiidm index f11d9b3f068..547b1f57d36 100644 --- a/psse/psse-converter/src/test/resources/ThreeMIB_T3W_modified.xiidm +++ b/psse/psse-converter/src/test/resources/ThreeMIB_T3W_modified.xiidm @@ -25,7 +25,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -69,8 +69,8 @@ - - + + @@ -110,13 +110,12 @@ - - + @@ -124,7 +123,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/ThreeMIB_T3W_phase.xiidm b/psse/psse-converter/src/test/resources/ThreeMIB_T3W_phase.xiidm index 8a3959ed27f..2205d88b88d 100644 --- a/psse/psse-converter/src/test/resources/ThreeMIB_T3W_phase.xiidm +++ b/psse/psse-converter/src/test/resources/ThreeMIB_T3W_phase.xiidm @@ -25,7 +25,7 @@ - + @@ -33,10 +33,10 @@ - + - + @@ -95,7 +95,7 @@ - + @@ -110,13 +110,12 @@ - - + @@ -124,7 +123,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/TransformersWithZeroNomV.xiidm b/psse/psse-converter/src/test/resources/TransformersWithZeroNomV.xiidm index daa07f2a1aa..c841b80954c 100644 --- a/psse/psse-converter/src/test/resources/TransformersWithZeroNomV.xiidm +++ b/psse/psse-converter/src/test/resources/TransformersWithZeroNomV.xiidm @@ -25,7 +25,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -69,8 +69,8 @@ - - + + @@ -110,13 +110,12 @@ - - + @@ -124,7 +123,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/parallelTwoTerminalDcBetweenSameAcBuses.xiidm b/psse/psse-converter/src/test/resources/parallelTwoTerminalDcBetweenSameAcBuses.xiidm index 6bb2efbb6da..f8914ec3692 100644 --- a/psse/psse-converter/src/test/resources/parallelTwoTerminalDcBetweenSameAcBuses.xiidm +++ b/psse/psse-converter/src/test/resources/parallelTwoTerminalDcBetweenSameAcBuses.xiidm @@ -16,7 +16,6 @@ - @@ -28,7 +27,6 @@ - @@ -53,10 +51,9 @@ - - + @@ -80,12 +77,11 @@ - - + @@ -117,7 +113,7 @@ - + @@ -125,7 +121,7 @@ - + @@ -133,7 +129,7 @@ - + @@ -141,7 +137,7 @@ - + @@ -149,7 +145,7 @@ - + @@ -157,7 +153,7 @@ - + @@ -165,7 +161,7 @@ - + @@ -173,7 +169,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/remoteControl.xiidm b/psse/psse-converter/src/test/resources/remoteControl.xiidm index 0b5bc450103..83422034493 100644 --- a/psse/psse-converter/src/test/resources/remoteControl.xiidm +++ b/psse/psse-converter/src/test/resources/remoteControl.xiidm @@ -16,7 +16,6 @@ - @@ -28,7 +27,6 @@ - @@ -64,7 +62,7 @@ - + @@ -75,8 +73,8 @@ - - + + @@ -97,7 +95,7 @@ - + @@ -126,7 +124,7 @@ - + @@ -138,7 +136,7 @@ - + @@ -146,7 +144,7 @@ - + @@ -154,7 +152,7 @@ - + @@ -162,7 +160,7 @@ - + @@ -170,7 +168,7 @@ - + @@ -178,7 +176,7 @@ - + @@ -186,7 +184,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/twoTerminalDc.xiidm b/psse/psse-converter/src/test/resources/twoTerminalDc.xiidm index d4196ef0b18..c7e830e6729 100644 --- a/psse/psse-converter/src/test/resources/twoTerminalDc.xiidm +++ b/psse/psse-converter/src/test/resources/twoTerminalDc.xiidm @@ -16,7 +16,6 @@ - @@ -28,7 +27,6 @@ - @@ -52,10 +50,9 @@ - - + @@ -79,12 +76,11 @@ - - + @@ -115,7 +111,7 @@ - + @@ -123,7 +119,7 @@ - + @@ -131,7 +127,7 @@ - + @@ -139,7 +135,7 @@ - + @@ -147,7 +143,7 @@ - + @@ -155,7 +151,7 @@ - + @@ -163,7 +159,7 @@ - + @@ -171,7 +167,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/twoTerminalDc_with_negative_setvl.xiidm b/psse/psse-converter/src/test/resources/twoTerminalDc_with_negative_setvl.xiidm index 86c647c769d..60b2f5585a6 100644 --- a/psse/psse-converter/src/test/resources/twoTerminalDc_with_negative_setvl.xiidm +++ b/psse/psse-converter/src/test/resources/twoTerminalDc_with_negative_setvl.xiidm @@ -16,7 +16,6 @@ - @@ -28,7 +27,6 @@ - @@ -52,10 +50,9 @@ - - + @@ -79,12 +76,11 @@ - - + @@ -115,7 +111,7 @@ - + @@ -123,7 +119,7 @@ - + @@ -131,7 +127,7 @@ - + @@ -139,7 +135,7 @@ - + @@ -147,7 +143,7 @@ - + @@ -155,7 +151,7 @@ - + @@ -163,7 +159,7 @@ - + @@ -171,7 +167,7 @@ - + From b74848e281c5b646fb5d8a11b089e2c014a5a3f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Marqu=C3=A9s?= Date: Wed, 17 Apr 2024 11:54:20 +0200 Subject: [PATCH 07/22] Fix code smells MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- .../powsybl/psse/converter/LineConverter.java | 12 ++-- .../psse/converter/NodeBreakerValidation.java | 4 -- .../powsybl/psse/converter/PsseImporter.java | 56 +++---------------- .../psse/converter/TransformerConverter.java | 12 ++-- .../psse/converter/VoltageLevelConverter.java | 2 +- 5 files changed, 20 insertions(+), 66 deletions(-) diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java index b12faf05c17..445604989f0 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java @@ -54,13 +54,13 @@ void create() { VoltageLevel voltageLevel2 = getNetwork().getVoltageLevel(voltageLevel2Id); // Support lines with different nominal voltage at ends - double rEu = impedanceToEngineeringUnitsForLinesWithDifferentNominalVoltageAtEnds(psseLine.getR(), voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), perUnitContext.getSb()); - double xEu = impedanceToEngineeringUnitsForLinesWithDifferentNominalVoltageAtEnds(psseLine.getX(), voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), perUnitContext.getSb()); + double rEu = impedanceToEngineeringUnitsForLinesWithDifferentNominalVoltageAtEnds(psseLine.getR(), voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), perUnitContext.sb()); + double xEu = impedanceToEngineeringUnitsForLinesWithDifferentNominalVoltageAtEnds(psseLine.getX(), voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), perUnitContext.sb()); Complex yEu = new Complex(rEu, xEu).reciprocal(); - double g1Eu = admittanceEnd1ToEngineeringUnitsForLinesWithDifferentNominalVoltageAtEnds(yEu.getReal(), psseLine.getGi(), voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), perUnitContext.getSb()); - double b1Eu = admittanceEnd1ToEngineeringUnitsForLinesWithDifferentNominalVoltageAtEnds(yEu.getImaginary(), psseLine.getB() * 0.5 + psseLine.getBi(), voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), perUnitContext.getSb()); - double g2Eu = admittanceEnd2ToEngineeringUnitsForLinesWithDifferentNominalVoltageAtEnds(yEu.getReal(), psseLine.getGj(), voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), perUnitContext.getSb()); - double b2Eu = admittanceEnd2ToEngineeringUnitsForLinesWithDifferentNominalVoltageAtEnds(yEu.getImaginary(), psseLine.getB() * 0.5 + psseLine.getBj(), voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), perUnitContext.getSb()); + double g1Eu = admittanceEnd1ToEngineeringUnitsForLinesWithDifferentNominalVoltageAtEnds(yEu.getReal(), psseLine.getGi(), voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), perUnitContext.sb()); + double b1Eu = admittanceEnd1ToEngineeringUnitsForLinesWithDifferentNominalVoltageAtEnds(yEu.getImaginary(), psseLine.getB() * 0.5 + psseLine.getBi(), voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), perUnitContext.sb()); + double g2Eu = admittanceEnd2ToEngineeringUnitsForLinesWithDifferentNominalVoltageAtEnds(yEu.getReal(), psseLine.getGj(), voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), perUnitContext.sb()); + double b2Eu = admittanceEnd2ToEngineeringUnitsForLinesWithDifferentNominalVoltageAtEnds(yEu.getImaginary(), psseLine.getB() * 0.5 + psseLine.getBj(), voltageLevel1.getNominalV(), voltageLevel2.getNominalV(), perUnitContext.sb()); LineAdder adder = getNetwork().newLine() .setId(id) diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java index aa2c07715b9..f79d37f3ff7 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java @@ -204,10 +204,6 @@ private List getEquipmentTerminals(int bus) { return busEquipmentTerminals.containsKey(bus) ? busEquipmentTerminals.get(bus) : new ArrayList<>(); } - private static boolean isOutOfService(PsseSubstation expectedSubstation, int node) { - return expectedSubstation.getNodes().stream().anyMatch(n -> n.getNi() == node && n.getStatus() != 1); - } - static final class NodeBreakerControl { private final String equipmentId; private final int node; diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java index 0eb653e1659..431ca7df0a8 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java @@ -250,10 +250,10 @@ private ContainersMapping defineContainersMapping(PssePowerFlowModel psseModel, return ContainersMapping.create(psseModel.getBuses(), edges, PsseBus::getI, - Edge::getBus1, - Edge::getBus2, - Edge::isZeroImpedance, - Edge::isTransformer, + Edge::bus1, + Edge::bus2, + Edge::zeroImpedance, + Edge::transformer, busNumber -> getNominalVFromBusNumber(busNumToPsseBus, busNumber, perUnitContext), AbstractConverter::getVoltageLevelId, substationNums -> "S" + substationNums.stream().sorted().findFirst().orElseThrow(() -> new PsseException("Unexpected empty substationNums"))); @@ -263,7 +263,7 @@ private double getNominalVFromBusNumber(Map busNumToPsseBus, i if (!busNumToPsseBus.containsKey(busNumber)) { // never should happen throw new PsseException("busId without PsseBus" + busNumber); } - return VoltageLevelConverter.getNominalV(busNumToPsseBus.get(busNumber), perUnitContext.isIgnoreBaseVoltage()); + return VoltageLevelConverter.getNominalV(busNumToPsseBus.get(busNumber), perUnitContext.ignoreBaseVoltage()); } private static NodeBreakerImport createBuses(PssePowerFlowModel psseModel, ContainersMapping containersMapping, @@ -282,51 +282,9 @@ private static NodeBreakerImport createBuses(PssePowerFlowModel psseModel, Conta return nodeBreakerImport; } - private static final class Edge { - private final int bus1; - private final int bus2; - private final boolean transformer; - private final boolean zeroImpedance; - - private Edge(int bus1, int bus2, boolean transformer, boolean zeroImpedance) { - this.bus1 = bus1; - this.bus2 = bus2; - this.transformer = transformer; - this.zeroImpedance = zeroImpedance; - } - - private int getBus1() { - return bus1; - } - - private int getBus2() { - return bus2; - } - - private boolean isTransformer() { - return transformer; - } - - private boolean isZeroImpedance() { - return zeroImpedance; - } + private record Edge(int bus1, int bus2, boolean transformer, boolean zeroImpedance) { } - static final class PerUnitContext { - private final double sb; - private final boolean ignoreBaseVoltage; - - PerUnitContext(double sb, boolean ignoreBaseVoltage) { - this.sb = sb; - this.ignoreBaseVoltage = ignoreBaseVoltage; - } - - double getSb() { - return sb; - } - - boolean isIgnoreBaseVoltage() { - return ignoreBaseVoltage; - } + record PerUnitContext(double sb, boolean ignoreBaseVoltage) { } } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java index 8541450f258..e8153735b58 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java @@ -85,8 +85,8 @@ private void createTwoWindingsTransformer() { Complex ysh = defineShuntAdmittance(id, psseTransformer.getMag1(), psseTransformer.getMag2(), sbase, sbase12, baskv1, nomV1, psseTransformer.getCm()); // To engineering units - z = impedanceToEngineeringUnits(z, voltageLevel2.getNominalV(), perUnitContext.getSb()); - ysh = admittanceToEngineeringUnits(ysh, voltageLevel2.getNominalV(), perUnitContext.getSb()); + z = impedanceToEngineeringUnits(z, voltageLevel2.getNominalV(), perUnitContext.sb()); + ysh = admittanceToEngineeringUnits(ysh, voltageLevel2.getNominalV(), perUnitContext.sb()); // move w2 to side 1 z = impedanceAdjustmentAfterMovingRatio(z, w2); @@ -186,10 +186,10 @@ private void createThreeWindingsTransformer() { double v0 = 1.0; // To engineering units - z1 = impedanceToEngineeringUnits(z1, v0, perUnitContext.getSb()); - z2 = impedanceToEngineeringUnits(z2, v0, perUnitContext.getSb()); - z3 = impedanceToEngineeringUnits(z3, v0, perUnitContext.getSb()); - ysh = admittanceToEngineeringUnits(ysh, v0, perUnitContext.getSb()); + z1 = impedanceToEngineeringUnits(z1, v0, perUnitContext.sb()); + z2 = impedanceToEngineeringUnits(z2, v0, perUnitContext.sb()); + z3 = impedanceToEngineeringUnits(z3, v0, perUnitContext.sb()); + ysh = admittanceToEngineeringUnits(ysh, v0, perUnitContext.sb()); // move ysh between w1 and z TapChanger tapChanger1AdjustedYsh = tapChangerAdjustmentAfterMovingShuntAdmittanceBetweenRatioAndTransmissionImpedance(tapChanger1); diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java index 396893f9e23..bfde8ed9757 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java @@ -42,7 +42,7 @@ VoltageLevel create(Substation substation) { VoltageLevel voltageLevel = getNetwork().getVoltageLevel(voltageLevelId); if (voltageLevel == null) { - double nominalV = getNominalV(psseBus, perUnitContext.isIgnoreBaseVoltage()); + double nominalV = getNominalV(psseBus, perUnitContext.ignoreBaseVoltage()); boolean isNodeBreakerValid = nodeBreakerValidation.isNodeBreakerSubstationCoherent(getContainersMapping().getBusesSet(voltageLevelId)); TopologyKind topologyKind = isNodeBreakerValid ? TopologyKind.NODE_BREAKER : TopologyKind.BUS_BREAKER; From e896564f4d164e019a0a4f939fbd1f1e46e0ca1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Marqu=C3=A9s?= Date: Mon, 22 Apr 2024 08:38:28 +0200 Subject: [PATCH 08/22] Add tests. Last changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- .../psse/converter/AbstractConverter.java | 20 +- .../powsybl/psse/converter/BusConverter.java | 31 +- .../psse/converter/GeneratorConverter.java | 9 + .../psse/converter/NodeBreakerExport.java | 39 +- .../powsybl/psse/converter/PsseExporter.java | 1 + .../psse/converter/SlackConverter.java | 25 +- .../SwitchedShuntCompensatorConverter.java | 10 + .../psse/converter/TransformerConverter.java | 34 +- .../converter/TwoTerminalDcConverter.java | 38 +- .../psse/converter/VoltageLevelConverter.java | 36 +- .../psse/converter/PsseExporterTest.java | 32 + .../psse/converter/PsseImporterTest.java | 5 + .../IEEE_14_bus_nodeBreaker_rev35.xiidm | 4 + ...s_nodeBreaker_rev35_split_bus_exported.raw | 2 +- .../IEEE_14_buses_duplicate_ids_rev35.xiidm | 4 +- .../five_bus_nodeBreaker_rev35.xiidm | 110 ++ .../five_bus_nodeBreaker_rev35_exported.raw | 139 ++ ...nodeBreaker_rev35_split_buses_exported.raw | 148 ++ ...allelTwoTerminalDcBetweenSameAcBuses.xiidm | 4 +- .../src/test/resources/twoTerminalDc.xiidm | 2 +- .../twoTerminalDc_with_negative_setvl.xiidm | 2 +- .../IEEE_14_bus_completed_exported.raw | 8 +- .../resources/five_bus_nodeBreaker_rev35.raw | 139 ++ .../psse/model/io/AbstractRecordGroup.java | 4 + .../psse/model/pf/PsseTransformerWinding.java | 4 + .../io/TwoTerminalDcTransmissionLineData.java | 2 +- .../powsybl/psse/model/PsseRawDataTest.java | 12 + .../IEEE_14_bus_completed_rev35_exported.raw | 8 +- .../resources/five_bus_nodeBreaker_rev35.json | 1195 +++++++++++++++++ 29 files changed, 2000 insertions(+), 67 deletions(-) create mode 100644 psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm create mode 100644 psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_exported.raw create mode 100644 psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw create mode 100644 psse/psse-model-test/src/main/resources/five_bus_nodeBreaker_rev35.raw create mode 100644 psse/psse-model/src/test/resources/five_bus_nodeBreaker_rev35.json diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java index b4cef520b0f..56c2c8562a0 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java @@ -13,6 +13,7 @@ import java.util.Set; import com.powsybl.iidm.network.Terminal; +import com.powsybl.iidm.network.TopologyKind; import com.powsybl.iidm.network.VoltageLevel; import com.powsybl.iidm.network.util.Networks; import com.powsybl.psse.model.PsseException; @@ -34,7 +35,7 @@ enum PsseEquipmentType { PSSE_BRANCH("B"), PSSE_TWO_WINDING("2"), PSSE_THREE_WINDING("3"), - PSSE_SWITCHED_SHUNT("s"), + PSSE_SWITCHED_SHUNT("S"), PSSE_INDUCTION_MACHINE("I"), PSSE_TWO_TERMINAL_DC_LINE("D"), PSSE_VSC_DC_LINE("V"), @@ -47,7 +48,7 @@ enum PsseEquipmentType { this.textCode = textCode; } - private String getTextCode() { + String getTextCode() { return textCode; } } @@ -90,7 +91,7 @@ static String getNodeBreakerEquipmentId(String type, int busI, int busJ, int bus } else if (bus1 == 0) { return type + "." + bus2 + "." + bus3 + "." + id; } else { - return type + "." + bus1 + "." + bus2 + "." + "." + bus3 + id; + return type + "." + bus1 + "." + bus2 + "." + bus3 + "." + id; } } @@ -117,6 +118,19 @@ static int obtainBus(NodeBreakerExport nodeBreakerExport, String equipmentId, in return nodeBreakerExport.getEquipmentIdBusBus(getNodeBreakerEquipmentIdBus(equipmentId, bus)).orElseGet(() -> bus); } + // the psse control node always is identical to the iidm node (not affected by internal connections) + static int obtainRegulatingBus(NodeBreakerExport nodeBreakerExport, Terminal regulatingTerminal, int bus) { + if (regulatingTerminal == null) { + return bus; + } + if (regulatingTerminal.getVoltageLevel().getTopologyKind().equals(TopologyKind.BUS_BREAKER)) { + return bus; + } + String voltageLevelId = regulatingTerminal.getVoltageLevel().getId(); + int node = regulatingTerminal.getNodeBreakerView().getNode(); + return nodeBreakerExport.getNodeBus(voltageLevelId, node).orElseGet(() -> bus); + } + static Terminal obtainTerminalNode(Network network, String voltageLevelId, int node) { VoltageLevel voltageLevel = network.getVoltageLevel(voltageLevelId); return voltageLevel != null ? obtainTerminalNode(voltageLevel, node) : null; diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java index f5e6e62b78c..c6df3401d14 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java @@ -63,18 +63,25 @@ static void updateBuses(Network network, PssePowerFlowModel psseModel, NodeBreak // create new psse buses List addedBuses = new ArrayList<>(); - nodeBreakerExport.getNewBusesSet().stream().sorted().forEach(newBus -> { - int copyBus = nodeBreakerExport.getNewBusCopyBus(newBus).orElseThrow(); - String busBreakerId = nodeBreakerExport.getNewBusBusBreakerId(newBus).orElseThrow(); - int type = nodeBreakerExport.getNewBusType(newBus).orElseThrow(); + nodeBreakerExport.getNewMappedBusesSet().stream().sorted().forEach(newBus -> { + int copyBus = nodeBreakerExport.getNewMappedBusCopyBus(newBus).orElseThrow(); + String busBreakerId = nodeBreakerExport.getNewMappedBusBusBreakerId(newBus).orElse(null); + int type = nodeBreakerExport.getNewMappedBusType(newBus).orElseThrow(); PsseBus psseBus = createNewBus(copyBus, newBus, busNumToPsseBus); updatePsseBus(network, busBreakerId, psseBus, type); + addedBuses.add(psseBus); + }); + + nodeBreakerExport.getNewNotMappedBusesSet().stream().sorted().forEach(newBus -> { + int copyBus = nodeBreakerExport.getNewNotMappedBusCopyBus(newBus).orElseThrow(); + PsseBus psseBus = createNewBus(copyBus, newBus, busNumToPsseBus); + updateIsolatedPsseBus(psseBus); addedBuses.add(psseBus); }); - psseModel.addBuses(addedBuses); + psseModel.addBuses(addedBuses.stream().sorted(Comparator.comparingInt(psseBus -> psseBus.getI())).toList()); } private static PsseBus createNewBus(int copyBus, int newBus, Map busNumToPsseBus) { @@ -105,12 +112,10 @@ private static PsseBus obtainPsseBus(int bus, Map busNumToPsse } } - private static void updatePsseBus(Network network, String busId, PsseBus psseBus, int type) { - Bus bus = network.getBusBreakerView().getBus(busId); + private static void updatePsseBus(Network network, String busBreakerId, PsseBus psseBus, int type) { + Bus bus = network.getBusBreakerView().getBus(busBreakerId); if (bus == null) { - psseBus.setVm(0.0); - psseBus.setVa(0.0); - psseBus.setIde(4); + updateIsolatedPsseBus(psseBus); } else { psseBus.setVm(getVm(bus)); psseBus.setVa(getVa(bus)); @@ -118,6 +123,12 @@ private static void updatePsseBus(Network network, String busId, PsseBus psseBus } } + private static void updateIsolatedPsseBus(PsseBus psseBus) { + psseBus.setVm(0.0); + psseBus.setVa(0.0); + psseBus.setIde(4); + } + private static double getVm(Bus bus) { return Double.isFinite(bus.getV()) && bus.getV() > 0.0 ? bus.getV() / bus.getVoltageLevel().getNominalV() : 1.0; } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java index e18ab9278f1..ff3406b496f 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java @@ -141,6 +141,7 @@ static void updateGenerators(Network network, PssePowerFlowModel psseModel, Node String genId = getGeneratorId(getBusId(psseGen.getI()), psseGen.getId()); Generator gen = network.getGenerator(genId); int bus = obtainBus(nodeBreakerExport, getNodeBreakerEquipmentId(PSSE_GENERATOR, psseGen.getI(), psseGen.getId()), psseGen.getI()); + int regulatingBus = obtainRegulatingBus(nodeBreakerExport, gen.getRegulatingTerminal(), psseGen.getIreg()); if (gen == null) { psseGen.setStat(0); @@ -150,9 +151,17 @@ static void updateGenerators(Network network, PssePowerFlowModel psseModel, Node psseGen.setQg(getQ(gen)); } psseGen.setI(bus); + if (regulatingBusMustBeChanged(bus, regulatingBus, psseGen.getIreg())) { + psseGen.setIreg(regulatingBus); + } }); } + // zero can be used for local regulation + private static boolean regulatingBusMustBeChanged(int bus, int newRegulatingBus, int regulatingBus) { + return !(bus == newRegulatingBus && regulatingBus == 0); + } + private static int getStatus(Generator gen) { if (gen.getTerminal().isConnected() && gen.getTerminal().getBusBreakerView().getBus() != null) { return 1; diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerExport.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerExport.java index 15920c52cd4..40a1d4dc9bd 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerExport.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerExport.java @@ -17,7 +17,8 @@ */ final class NodeBreakerExport { private int maxPsseBus; - private final Map newBuses; + private final Map newMappedBuses; // New buses mapped to iidm buses + private final Map newNotMappedBuses; // New buses not mapped to iidm buses private final Map> buses; private final Set isolatedBuses; private final Map> nodeBus; @@ -25,7 +26,8 @@ final class NodeBreakerExport { NodeBreakerExport(int maxPsseBus) { this.maxPsseBus = maxPsseBus; - this.newBuses = new HashMap<>(); + this.newMappedBuses = new HashMap<>(); + this.newNotMappedBuses = new HashMap<>(); this.buses = new HashMap<>(); this.isolatedBuses = new HashSet<>(); this.nodeBus = new HashMap<>(); @@ -36,24 +38,37 @@ int getNewPsseBus() { return ++maxPsseBus; } - void addNewBus(int newBus, int copyBus, String busBreakerBusId, int type) { - newBuses.put(newBus, new NodeBreakerNewBus(copyBus, busBreakerBusId, type)); + void addNewMappedBus(int newBus, int copyBus, String busBreakerBusId, int type) { + newMappedBuses.put(newBus, new NodeBreakerNewBus(copyBus, busBreakerBusId, type)); } - Set getNewBusesSet() { - return newBuses.keySet(); + void addNewNotMappedBus(int newBus, int copyBus) { + newNotMappedBuses.put(newBus, copyBus); } - OptionalInt getNewBusCopyBus(int newBus) { - return newBuses.containsKey(newBus) ? OptionalInt.of(newBuses.get(newBus).busCopy) : OptionalInt.empty(); + Set getNewMappedBusesSet() { + return newMappedBuses.keySet(); } - Optional getNewBusBusBreakerId(int newBus) { - return newBuses.containsKey(newBus) ? Optional.of(newBuses.get(newBus).busBreakerId) : Optional.empty(); + OptionalInt getNewMappedBusCopyBus(int newBus) { + return newMappedBuses.containsKey(newBus) ? OptionalInt.of(newMappedBuses.get(newBus).busCopy) : OptionalInt.empty(); } - OptionalInt getNewBusType(int newBus) { - return newBuses.containsKey(newBus) ? OptionalInt.of(newBuses.get(newBus).type) : OptionalInt.empty(); + Optional getNewMappedBusBusBreakerId(int newBus) { + // New Isolated buses do not have busBreakerId. Null is considered + return newMappedBuses.containsKey(newBus) ? Optional.ofNullable(newMappedBuses.get(newBus).busBreakerId) : Optional.empty(); + } + + OptionalInt getNewMappedBusType(int newBus) { + return newMappedBuses.containsKey(newBus) ? OptionalInt.of(newMappedBuses.get(newBus).type) : OptionalInt.empty(); + } + + Set getNewNotMappedBusesSet() { + return newNotMappedBuses.keySet(); + } + + OptionalInt getNewNotMappedBusCopyBus(int newBus) { + return newNotMappedBuses.containsKey(newBus) ? OptionalInt.of(newNotMappedBuses.get(newBus)) : OptionalInt.empty(); } void addBusMapping(int bus, String busBreakerBusId, int type) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java index d3a20004573..7d2672d5ae9 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java @@ -131,6 +131,7 @@ private static void updateModifiedBlocks(Network network, PssePowerFlowModel upd GeneratorConverter.updateGenerators(network, updatedPsseModel, nodeBreakerExport); LineConverter.updateLines(network, updatedPsseModel, nodeBreakerExport); TransformerConverter.updateTransformers(network, updatedPsseModel, nodeBreakerExport); + TwoTerminalDcConverter.updateTwoTerminalDcTransmissionLines(network, updatedPsseModel, nodeBreakerExport); SwitchedShuntCompensatorConverter.updateSwitchedShunts(network, updatedPsseModel, nodeBreakerExport); } } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SlackConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SlackConverter.java index 5296fc05e42..1629b373bf8 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SlackConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SlackConverter.java @@ -10,6 +10,7 @@ import com.powsybl.iidm.network.Bus; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.Terminal; +import com.powsybl.iidm.network.VoltageLevel; import com.powsybl.iidm.network.extensions.SlackTerminal; import com.powsybl.iidm.network.util.ContainersMapping; import com.powsybl.iidm.network.util.TerminalFinder; @@ -32,22 +33,24 @@ class SlackConverter extends AbstractConverter { } void create() { - for (PsseBus psseBus : psseBusList) { - if (psseBus.getIde() == 3) { - Bus bus; - Optional slackControlNode = nodeBreakerImport.getSlackControlNode(psseBus.getI()); - if (slackControlNode.isPresent()) { - Terminal terminal = obtainTerminalNode(getNetwork(), slackControlNode.get().getVoltageLevelId(), slackControlNode.get().getNode()); - bus = terminal != null ? terminal.getBusBreakerView().getBus() : null; - } else { - String busId = AbstractConverter.getBusId(psseBus.getI()); - bus = getNetwork().getBusBreakerView().getBus(busId); + psseBusList.stream().filter(psseBus -> psseBus.getIde() == 3).forEach(psseBus -> { + + Optional slackControlNode = nodeBreakerImport.getSlackControlNode(psseBus.getI()); + if (slackControlNode.isPresent()) { + Terminal terminal = obtainTerminalNode(getNetwork(), slackControlNode.get().getVoltageLevelId(), slackControlNode.get().getNode()); + VoltageLevel voltageLevel = getNetwork().getVoltageLevel(slackControlNode.get().getVoltageLevelId()); + + if (voltageLevel != null && terminal != null) { + SlackTerminal.reset(voltageLevel, terminal); } + } else { + String busId = AbstractConverter.getBusId(psseBus.getI()); + Bus bus = getNetwork().getBusBreakerView().getBus(busId); if (slackBusIsValidForIidm(bus)) { SlackTerminal.attach(bus); } } - } + }); } private static boolean slackBusIsValidForIidm(Bus bus) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java index 5ac1af3452c..3cfec460589 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java @@ -143,6 +143,14 @@ private static int switchedShuntRegulatingBus(PsseSwitchedShunt switchedShunt, P } } + private static void setSwitchedShuntRegulatingBus(PsseSwitchedShunt switchedShunt, PsseVersion psseVersion, int regulatingBus) { + if (psseVersion.major() == V35) { + switchedShunt.setSwreg(regulatingBus); + } else { + switchedShunt.setSwrem(regulatingBus); + } + } + private static int defineSectionCount(double binit, List shuntBlocks) { double maxDistance = Double.MAX_VALUE; int sectionCount = 0; @@ -283,6 +291,7 @@ static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel, String switchedShuntId = getShuntId(getBusId(psseSwitchedShunt.getI()), defineShuntId(psseSwitchedShunt, version)); ShuntCompensator switchedShunt = network.getShuntCompensator(switchedShuntId); int bus = obtainBus(nodeBreakerExport, getNodeBreakerEquipmentId(PSSE_SWITCHED_SHUNT, psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version)), psseSwitchedShunt.getI()); + int regulatingBus = obtainRegulatingBus(nodeBreakerExport, switchedShunt.getRegulatingTerminal(), switchedShuntRegulatingBus(psseSwitchedShunt, version)); if (switchedShunt == null) { psseSwitchedShunt.setStat(0); } else { @@ -290,6 +299,7 @@ static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel, psseSwitchedShunt.setBinit(getQ(switchedShunt)); } psseSwitchedShunt.setI(bus); + setSwitchedShuntRegulatingBus(psseSwitchedShunt, version, regulatingBus); }); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java index e8153735b58..1836ab21d84 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java @@ -16,6 +16,7 @@ import org.slf4j.LoggerFactory; import com.powsybl.iidm.network.ThreeWindingsTransformer.Leg; +import com.powsybl.iidm.network.RatioTapChanger; import com.powsybl.iidm.network.util.ContainersMapping; import com.powsybl.psse.converter.PsseImporter.PerUnitContext; import com.powsybl.psse.model.PsseException; @@ -24,8 +25,8 @@ import com.powsybl.psse.model.pf.PssePowerFlowModel; import com.powsybl.psse.model.pf.PsseTransformer; import com.powsybl.psse.model.pf.PsseTransformerWinding; -import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_TWO_WINDING; -import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_THREE_WINDING; + +import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.*; import static com.powsybl.psse.model.PsseVersion.Major.V35; /** @@ -726,7 +727,7 @@ private static boolean isTwoWindingsTransformer(PsseTransformer psseTransformer) private void addControlTwoWindingsTransformer() { String id = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); - String equipmentId = ""; + String equipmentId = getNodeBreakerEquipmentId(PSSE_TWO_WINDING, psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); TwoWindingsTransformer twt = getNetwork().getTwoWindingsTransformer(id); if (twt == null) { return; @@ -743,7 +744,7 @@ private void addControlTwoWindingsTransformer() { private void addControlThreeWindingsTransformer() { String id = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt()); - String equipmentId = ""; + String equipmentId = getNodeBreakerEquipmentId(PSSE_THREE_WINDING, psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt()); ThreeWindingsTransformer twt = getNetwork().getThreeWindingsTransformer(id); if (twt == null) { return; @@ -896,11 +897,21 @@ private static void updateTwoWindingsTransformer(Network network, PsseTransforme int busJ = obtainBus(nodeBreakerExport, equipmentId, psseTransformer.getJ()); psseTransformer.setI(busI); psseTransformer.setJ(busJ); + int regulatingBus = obtainRegulatingBus(nodeBreakerExport, obtainRegulatingTerminal(tw2t), psseTransformer.getWinding1().getCont()); + psseTransformer.getWinding1().setCont(regulatingBus); psseTransformer.setStat(getStatus(tw2t)); } } + private static Terminal obtainRegulatingTerminal(TwoWindingsTransformer tw2t) { + Terminal regulatingTerminal = tw2t.getOptionalRatioTapChanger().map(RatioTapChanger::getRegulationTerminal).orElse(null); + if (regulatingTerminal != null) { + return regulatingTerminal; + } + return tw2t.getOptionalPhaseTapChanger().map(PhaseTapChanger::getRegulationTerminal).orElse(null); + } + private static int getStatus(TwoWindingsTransformer tw2t) { if (tw2t.getTerminal1().isConnected() && tw2t.getTerminal1().getBusBreakerView().getBus() != null && tw2t.getTerminal2().isConnected() && tw2t.getTerminal2().getBusBreakerView().getBus() != null) { @@ -939,10 +950,25 @@ private static void updateThreeWindingsTransformer(Network network, PsseTransfor psseTransformer.setJ(busJ); psseTransformer.setK(busK); + int regulatingBus1 = obtainRegulatingBus(nodeBreakerExport, obtainRegulatingTerminal(tw3t.getLeg1()), psseTransformer.getWinding1().getCont()); + int regulatingBus2 = obtainRegulatingBus(nodeBreakerExport, obtainRegulatingTerminal(tw3t.getLeg2()), psseTransformer.getWinding2().getCont()); + int regulatingBus3 = obtainRegulatingBus(nodeBreakerExport, obtainRegulatingTerminal(tw3t.getLeg3()), psseTransformer.getWinding3().getCont()); + psseTransformer.getWinding1().setCont(regulatingBus1); + psseTransformer.getWinding2().setCont(regulatingBus2); + psseTransformer.getWinding3().setCont(regulatingBus3); + psseTransformer.setStat(getStatus(tw3t)); } } + private static Terminal obtainRegulatingTerminal(Leg leg) { + Terminal regulatingTerminal = leg.getOptionalRatioTapChanger().map(RatioTapChanger::getRegulationTerminal).orElse(null); + if (regulatingTerminal != null) { + return regulatingTerminal; + } + return leg.getOptionalPhaseTapChanger().map(PhaseTapChanger::getRegulationTerminal).orElse(null); + } + private static int getStatus(ThreeWindingsTransformer tw3t) { if (tw3t.getLeg1().getTerminal().isConnected() && tw3t.getLeg1().getTerminal().getBusBreakerView().getBus() != null && tw3t.getLeg2().getTerminal().isConnected() && tw3t.getLeg2().getTerminal().getBusBreakerView().getBus() != null diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java index ae882d31a99..6c992eaa962 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java @@ -11,8 +11,10 @@ import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.util.ContainersMapping; import com.powsybl.iidm.network.util.Identifiables; +import com.powsybl.psse.model.pf.PssePowerFlowModel; import com.powsybl.psse.model.pf.PsseTwoTerminalDcConverter; import com.powsybl.psse.model.pf.PsseTwoTerminalDcTransmissionLine; + import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_TWO_TERMINAL_DC_LINE; import java.util.Objects; @@ -72,7 +74,7 @@ void create() { LccConverterStation cI = adderI.add(); HvdcLineAdder adder = getNetwork().newHvdcLine() - .setId(getTwoTerminalDcId(psseTwoTerminalDc)) + .setId(getTwoTerminalDcId(getNetwork(), psseTwoTerminalDc)) .setName(psseTwoTerminalDc.getName()) .setR(psseTwoTerminalDc.getRdc()) .setNominalV(psseTwoTerminalDc.getVschd()) @@ -111,9 +113,37 @@ private String getLccConverterId(PsseTwoTerminalDcTransmissionLine psseTwoTermin id -> getNetwork().getLccConverterStation(id) != null); } - private String getTwoTerminalDcId(PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc) { - return Identifiables.getUniqueId("TwoTerminalDc-" + psseTwoTerminalDc.getRectifier().getIp() + "-" + psseTwoTerminalDc.getInverter().getIp(), - id -> getNetwork().getHvdcLine(id) != null); + private static String getTwoTerminalDcId(Network network, PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc) { + return "TwoTerminalDc-" + psseTwoTerminalDc.getRectifier().getIp() + "-" + psseTwoTerminalDc.getInverter().getIp() + "-" + psseTwoTerminalDc.getName(); + } + + static void updateTwoTerminalDcTransmissionLines(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { + psseModel.getTwoTerminalDcTransmissionLines().forEach(psseTwoTerminalDc -> { + String hvdcId = getTwoTerminalDcId(network, psseTwoTerminalDc); + HvdcLine hvdcLine = network.getHvdcLine(hvdcId); + + String equipmentIdRectifier = getNodeBreakerEquipmentId(PSSE_TWO_TERMINAL_DC_LINE, psseTwoTerminalDc.getRectifier().getIp(), psseTwoTerminalDc.getName()); + int busRectifier = obtainBus(nodeBreakerExport, equipmentIdRectifier, psseTwoTerminalDc.getRectifier().getIp()); + String equipmentIdInverter = getNodeBreakerEquipmentId(PSSE_TWO_TERMINAL_DC_LINE, psseTwoTerminalDc.getInverter().getIp(), psseTwoTerminalDc.getName()); + int busInverter = obtainBus(nodeBreakerExport, equipmentIdInverter, psseTwoTerminalDc.getInverter().getIp()); + + if (hvdcLine == null) { + psseTwoTerminalDc.setMdc(0); + } else { + psseTwoTerminalDc.setMdc(obtainControlMode(hvdcLine, psseTwoTerminalDc.getMdc())); + } + psseTwoTerminalDc.getRectifier().setIp(busRectifier); + psseTwoTerminalDc.getInverter().setIp(busInverter); + }); + } + + private static int obtainControlMode(HvdcLine hvdcLine, int mdc) { + if (hvdcLine.getConverterStation1().getTerminal().isConnected() && hvdcLine.getConverterStation1().getTerminal().getBusBreakerView().getBus() != null + && hvdcLine.getConverterStation2().getTerminal().isConnected() && hvdcLine.getConverterStation2().getTerminal().getBusBreakerView().getBus() != null) { + return mdc != 0 ? mdc : 1; + } else { + return 0; + } } private final PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc; diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java index bfde8ed9757..fe7d821b715 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java @@ -22,6 +22,7 @@ import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationNode; import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationSwitchingDevice; import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationEquipmentTerminal; +import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_GENERATOR; /** * @author Luma Zamarreño {@literal } @@ -53,7 +54,7 @@ VoltageLevel create(Substation substation) { .add(); if (isNodeBreakerValid) { - addNodeBreakerEquipment(voltageLevelId, voltageLevel, nodeBreakerValidation, nodeBreakerImport); + addNodeBreakerConnectivity(voltageLevelId, voltageLevel, nodeBreakerValidation, nodeBreakerImport); } } @@ -68,7 +69,7 @@ static double getNominalV(PsseBus psseBus, boolean isIgnoreBaseVoltage) { return isIgnoreBaseVoltage || psseBus.getBaskv() == 0 ? 1 : psseBus.getBaskv(); } - private void addNodeBreakerEquipment(String voltageLevelId, VoltageLevel voltageLevel, NodeBreakerValidation nodeBreakerValidation, NodeBreakerImport nodeBreakerImport) { + private void addNodeBreakerConnectivity(String voltageLevelId, VoltageLevel voltageLevel, NodeBreakerValidation nodeBreakerValidation, NodeBreakerImport nodeBreakerImport) { Set buses = getContainersMapping().getBusesSet(voltageLevelId); PsseSubstation substation = buses.stream().map(nodeBreakerValidation::getSubstationIfOnlyOneExists) .filter(Optional::isPresent) @@ -106,6 +107,16 @@ private void addNodeBreakerEquipment(String voltageLevelId, VoltageLevel voltage } } + // Nodes without equipment are defined as busbar sections to improve the regulating terminal selection + substation.getNodes().stream() + .map(PsseSubstationNode::getNi) + .filter(node -> !nodesWithEquipment.contains(node)) + .collect(Collectors.toSet()).forEach(node -> voltageLevel.getNodeBreakerView() + .newBusbarSection() + .setId(busbarSectionId(voltageLevel.getId(), node)) + .setNode(node) + .add()); + // Define where controls must be connected. Psse nodes and iidm nodes are identical. buses.forEach(bus -> { List controls = nodeBreakerValidation.getControls(bus); @@ -125,9 +136,19 @@ private static String getSwitchId(String voltageLevelId, PsseSubstationSwitching return voltageLevelId + "-Sw-" + switchingDevice.getNi() + "-" + switchingDevice.getNj() + "-" + switchingDevice.getCkt(); } + private static String busbarSectionId(String voltageLevelId, int node) { + return String.format("%s-Busbar-%d", voltageLevelId, node); + } + private static int obtainSlackNode(NodeBreakerValidation nodeBreakerValidation, int bus) { PsseSubstation psseSubstation = nodeBreakerValidation.getSubstationIfOnlyOneExists(bus).orElseThrow(); - return psseSubstation.getNodes().stream().filter(n -> n.getI() == bus).map(PsseSubstationNode::getNi).findFirst().orElseThrow(); + return psseSubstation.getNodes().stream().filter(n -> n.getI() == bus) + .map(PsseSubstationNode::getNi).min(Comparator.comparingInt((Integer node) -> connectedGenerators(psseSubstation, node)) + .reversed().thenComparing(Comparator.naturalOrder())).orElseThrow(); + } + + private static int connectedGenerators(PsseSubstation psseSubstation, int node) { + return (int) psseSubstation.getEquipmentTerminals().stream().filter(eqt -> eqt.getNi() == node && eqt.getType().equals(PSSE_GENERATOR.getTextCode())).count(); } static NodeBreakerExport mapSubstations(Network network, PssePowerFlowModel psseModel) { @@ -177,7 +198,7 @@ private static void mapBusBreakerBusesToPsseBuses(VoltageLevel voltageLevel, Pss nodeBreakerExport.addNodesBusMapping(voltageLevel.getId(), onlyPsseNodes(busBreakerBusIdNodeList.get(key), psseNodesSet), bus.get(), true); } else { int newBus = nodeBreakerExport.getNewPsseBus(); - nodeBreakerExport.addNewBus(newBus, selectCopyBus(psseSubstation), key, busType); + nodeBreakerExport.addNewMappedBus(newBus, selectCopyBus(psseSubstation), key, busType); nodeBreakerExport.addNodesBusMapping(voltageLevel.getId(), onlyPsseNodes(busBreakerBusIdNodeList.get(key), psseNodesSet), newBus, true); } }); @@ -277,9 +298,10 @@ private static void mapIsolatedPsseNodesToFreeBus(VoltageLevel voltageLevel, Pss private static void mapIsolatedPsseNodesToNewBus(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { List isolatedNodes = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).filter(node -> nodeBreakerExport.isFreeNode(voltageLevel.getId(), node)).toList(); isolatedNodes.forEach(node -> { - int bus = nodeBreakerExport.getNewPsseBus(); - nodeBreakerExport.addNodeBusMapping(voltageLevel.getId(), node, bus, false); - nodeBreakerExport.addIsolatedBus(bus); + int newBus = nodeBreakerExport.getNewPsseBus(); + nodeBreakerExport.addNewNotMappedBus(newBus, selectCopyBus(psseSubstation)); + nodeBreakerExport.addNodeBusMapping(voltageLevel.getId(), node, newBus, false); + nodeBreakerExport.addIsolatedBus(newBus); }); } diff --git a/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseExporterTest.java b/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseExporterTest.java index af3b5afad4d..15ca4274318 100644 --- a/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseExporterTest.java +++ b/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseExporterTest.java @@ -263,6 +263,38 @@ void importExportTestRaw14NodeBreakerSplitBus() throws IOException { exportTest(network, "IEEE_14_bus_nodeBreaker_rev35_split_bus_exported", "IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw"); } + @Test + void importExportTestRawFiveBusNodeBreaker() throws IOException { + Network network = importTest("five_bus_nodeBreaker_rev35", "five_bus_nodeBreaker_rev35.raw", false); + exportTest(network, "five_bus_nodeBreaker_rev35_exported", "five_bus_nodeBreaker_rev35_exported.raw"); + } + + @Test + void importExportTestRawFiveBusNodeBreakerSplitBus() throws IOException { + Network network = importTest("five_bus_nodeBreaker_rev35", "five_bus_nodeBreaker_rev35.raw", false); + + VoltageLevel vl1 = network.getVoltageLevel("VL1"); + vl1.getNodeBreakerView().getSwitch("VL1-Sw-1-2-1 ").setOpen(true); + + VoltageLevel vl2 = network.getVoltageLevel("VL2"); + vl2.getNodeBreakerView().getSwitch("VL2-Sw-1-2-1 ").setOpen(true); + vl2.getNodeBreakerView().getSwitch("VL2-Sw-1-4-1 ").setOpen(true); + + VoltageLevel vl3 = network.getVoltageLevel("VL3"); + vl3.getNodeBreakerView().getSwitch("VL3-Sw-1-2-1 ").setOpen(true); + vl3.getNodeBreakerView().getSwitch("VL3-Sw-2-5-1 ").setOpen(true); + + VoltageLevel vl4 = network.getVoltageLevel("VL4"); + vl4.getNodeBreakerView().getSwitch("VL4-Sw-1-2-1 ").setOpen(true); + vl4.getNodeBreakerView().getSwitch("VL4-Sw-2-4-1 ").setOpen(true); + + VoltageLevel vl5 = network.getVoltageLevel("VL5"); + vl5.getNodeBreakerView().getSwitch("VL5-Sw-1-2-1 ").setOpen(true); + vl5.getNodeBreakerView().getSwitch("VL5-Sw-1-4-1 ").setOpen(true); + + exportTest(network, "five_bus_nodeBreaker_rev35_split_buses_exported", "five_bus_nodeBreaker_rev35_split_buses_exported.raw"); + } + @Test void exportDataTest() throws IOException { PsseExporter psseExporter = new PsseExporter(); diff --git a/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseImporterTest.java b/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseImporterTest.java index 18039c1872c..2ff17ed58d0 100644 --- a/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseImporterTest.java +++ b/psse/psse-converter/src/test/java/com/powsybl/psse/converter/PsseImporterTest.java @@ -294,4 +294,9 @@ void importTest14ZipLoad() throws IOException { void importTest14NodeBreaker() throws IOException { importTest("IEEE_14_bus_nodeBreaker_rev35", "IEEE_14_bus_nodeBreaker_rev35.raw", false); } + + @Test + void importFiveBusNodeBreaker() throws IOException { + importTest("five_bus_nodeBreaker_rev35", "five_bus_nodeBreaker_rev35.raw", false); + } } diff --git a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm index 7f5194128c5..1baa3a1b5b5 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm @@ -3,6 +3,8 @@ + + @@ -16,6 +18,8 @@ + + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw index d0aa7e2f7cf..fce69f8951e 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw +++ b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw @@ -39,7 +39,7 @@ 6,'1 ',0.0,12.73,24.0,-6.0,1.07,0,0,25.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 8,'1 ',0.0,17.623,24.0,-6.0,1.09,0,0,25.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 0 / END OF GENERATOR DATA, BEGIN BRANCH DATA -15,2,'1 ',0.01938,0.05917,0.0528,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +15,2,'1 ',0.01938,0.05917,0.0528,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 1,5,'1 ',0.05403,0.22304,0.0492,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 16,3,'1 ',0.04699,0.19797,0.0438,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 16,4,'1 ',0.05811,0.17632,0.034,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 diff --git a/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm index 1f07af48974..41606c585d8 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm @@ -171,8 +171,8 @@ - - + + diff --git a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm new file mode 100644 index 00000000000..cdff2b2aa6c --- /dev/null +++ b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_exported.raw b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_exported.raw new file mode 100644 index 00000000000..23b8fd90165 --- /dev/null +++ b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_exported.raw @@ -0,0 +1,139 @@ +0,100.0,35,0.0,0.0,60.0 + 17/04/24 UW ARCHIVE 100.0 1962 W Five Bus nodeBreaker Test Case + +0 / END OF SYSTEM-WIDE DATA, BEGIN BUS DATA +1,'Bus 1 ',138.0,3,1,1,1,1.0,0.0 +2,'Bus 2 ',138.0,1,1,1,1,1.0,0.0 +3,'Bus 3 ',45.0,1,1,1,1,1.0,0.0 +4,'Bus 4 ',21.0,1,1,1,1,1.0,0.0 +5,'Bus 5 ',138.0,1,1,1,1,1.0,0.0 +0 / END OF BUS DATA, BEGIN LOAD DATA +2,'1 ',1,1,1,21.7,12.7,0.0,0.0,0.0,-0.0,1,1 +3,'1 ',1,1,1,94.2,19.0,0.0,0.0,0.0,-0.0,1,1 +4,'1 ',1,1,1,47.8,-3.9,0.0,0.0,0.0,-0.0,1,1 +5,'1 ',1,1,1,7.6,1.6,0.0,0.0,0.0,-0.0,1,1 +0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA +2,'1 ',1,0.0,19.0 +0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA +1,'1 ',232.392,-16.549,0.0,0.0,1.06,1,2,615.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +0 / END OF GENERATOR DATA, BEGIN BRANCH DATA +1,2,'1 ',0.01938,0.05917,0.0528,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +0 / END OF BRANCH DATA, BEGIN SYSTEM SWITCHING DEVICE DATA +0 / END OF SYSTEM SWITCHING DEVICE DATA, BEGIN TRANSFORMER DATA +1,3,0,'1 ',1,1,1,0.0,0.0,2,'2WT ',1,1,1.0,0,1.0,0,1.0,0,1.0 +0.0,0.20912,100.0 +0.978,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,3,2,1.5,0.51,1.5,0.51,3,0,0.0,0.0 +1.0,0.0 +1,3,4,'1 ',1,1,1,0.0,0.0,2,'3WT ',1,1,1.0,0,1.0,0,1.0,0,1.0 +334279.0,0.13432,440.0,262298.0,0.20807,280.0,1515.0,0.10652,160.0,1.0,0.0 +0.978,138.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,3,0,0.0,0.0 +0.988,45.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,3,0,0.0,0.0 +0.9980000000000001,21.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,4,2,1.5,0.51,1.5,0.51,3,0,0.0,0.0 +0 / END OF TRANSFORMER DATA, BEGIN AREA DATA +0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA +'EATL P1 ',1,7.365,0.0,500.0,0.0,7.365,0.1,'R',0.0,50,1.0 +1,1,17.3,12.7,0.48,21.32,500.0,0.832,1.1,1.2,0.975,0.0125,0,0,0,0,'1 ',0.0 +5,1,20.5,18.0,0.48,21.32,240.0,1.7325,1.1419,1.2064,0.8968,0.0129,0,0,0,0,'1 ',0.0 +0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA +0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA +0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA +0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA +0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA +0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA +0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA +0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA +0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA +5,'1 ',0,0,1,1.0,0.99,5,2,100.0,' ',100.0,1,1,100.0 +0 / END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA +0 / END OF GNE DEVICE DATA, BEGIN INDUCTION MACHINE DATA +0 / END OF INDUCTION MACHINE DATA, BEGIN SUBSTATION DATA +1,'STATION 1',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',1,1,1.0,0.0 +2,'NB2',1,1,1.0,0.0 +3,'NLINE',1,1,1.0,0.0 +4,'NT2W',1,1,1.0,0.0 +5,'NT3W',1,1,1.0,0.0 +6,'NDCLINE',1,1,1.0,0.0 +7,'NGEN',1,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 +2,3,'1 ','Sw-LineToBus2','2',1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-T2wToBus3','2',1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-T3wToBus3Bus4','2',1,1,0.0,0.0,0.0,0.0 +1,6,'1 ','Sw-LineDcToBus5','2',1,1,0.0,0.0,0.0,0.0 +1,7,'1 ','Sw-Gen','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +1,7,'M','1 ' +1,6,'D','EATL P1 ' +1,3,'B',2,'1 ' +1,4,'2',3,'1 ' +1,5,'3',3,4,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +2,'STATION 2',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',2,1,1.0,0.0 +2,'NB2',2,1,1.0,0.0 +3,'NLINE',2,1,1.0,0.0 +4,'NLOAD',2,1,1.0,0.0 +5,'NFSHUNT',2,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-LineToBus1','2',1,1,0.0,0.0,0.0,0.0 +1,4,'1 ','Sw-Load','2',1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-FixedShunt','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +2,4,'L','1 ' +2,5,'F','1 ' +2,3,'B',1,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +3,'STATION 3',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',3,1,1.0,0.0 +2,'NB2',3,1,1.0,0.0 +3,'NT2W',3,1,1.0,0.0 +4,'NT3W',3,1,1.0,0.0 +5,'NLOAD',3,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-T2w','2',1,1,0.0,0.0,0.0,0.0 +1,4,'1 ','Sw-T3w','2',1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-Load','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +3,5,'L','1 ' +3,3,'2',1,'1 ' +3,4,'3',1,4,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +4,'STATION 4',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',4,1,1.0,0.0 +2,'NB2',4,1,1.0,0.0 +3,'NT3W',4,1,1.0,0.0 +4,'NLOAD',4,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-T3w','2',1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-Load','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +4,4,'L','1 ' +4,3,'3',1,3,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +5,'STATION 5',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',5,1,1.0,0.0 +2,'NB2',5,1,1.0,0.0 +3,'NDCLINE',5,1,1.0,0.0 +4,'NLOAD',5,1,1.0,0.0 +5,'NSSHUNT',5,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-DcLine','2',1,1,0.0,0.0,0.0,0.0 +1,4,'1 ','Sw-Load','2',1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-SwitchedShunt','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +5,4,'L','1 ' +5,5,'S','1 ' +5,3,'D','EATL P1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +0 / END OF SUBSTATION DATA +Q diff --git a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw new file mode 100644 index 00000000000..08cd13044de --- /dev/null +++ b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw @@ -0,0 +1,148 @@ +0,100.0,35,0.0,0.0,60.0 + 17/04/24 UW ARCHIVE 100.0 1962 W Five Bus nodeBreaker Test Case + +0 / END OF SYSTEM-WIDE DATA, BEGIN BUS DATA +1,'Bus 1 ',138.0,1,1,1,1,1.0,0.0 +2,'Bus 2 ',138.0,1,1,1,1,1.0,0.0 +3,'Bus 3 ',45.0,1,1,1,1,1.0,0.0 +4,'Bus 4 ',21.0,1,1,1,1,1.0,0.0 +5,'Bus 5 ',138.0,1,1,1,1,1.0,0.0 +6,'Bus 1-6 ',138.0,3,1,1,1,1.0,0.0 +7,'Bus 2-7 ',138.0,1,1,1,1,1.0,0.0 +8,'Bus 2-8 ',138.0,1,1,1,1,1.0,0.0 +9,'Bus 3-9 ',45.0,1,1,1,1,1.0,0.0 +10,'Bus 3-10 ',45.0,1,1,1,1,1.0,0.0 +11,'Bus 4-11 ',21.0,1,1,1,1,1.0,0.0 +12,'Bus 4-12 ',21.0,1,1,1,1,1.0,0.0 +13,'Bus 5-13 ',138.0,1,1,1,1,1.0,0.0 +14,'Bus 5-14 ',138.0,1,1,1,1,1.0,0.0 +0 / END OF BUS DATA, BEGIN LOAD DATA +8,'1 ',0,1,1,21.7,12.7,0.0,0.0,0.0,-0.0,1,1 +10,'1 ',0,1,1,94.2,19.0,0.0,0.0,0.0,-0.0,1,1 +12,'1 ',0,1,1,47.8,-3.9,0.0,0.0,0.0,-0.0,1,1 +14,'1 ',0,1,1,7.6,1.6,0.0,0.0,0.0,-0.0,1,1 +0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA +7,'1 ',1,0.0,19.0 +0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA +6,'1 ',232.392,-16.549,0.0,0.0,1.06,1,2,615.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +0 / END OF GENERATOR DATA, BEGIN BRANCH DATA +1,2,'1 ',0.01938,0.05917,0.0528,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +0 / END OF BRANCH DATA, BEGIN SYSTEM SWITCHING DEVICE DATA +0 / END OF SYSTEM SWITCHING DEVICE DATA, BEGIN TRANSFORMER DATA +1,3,0,'1 ',1,1,1,0.0,0.0,2,'2WT ',1,1,1.0,0,1.0,0,1.0,0,1.0 +0.0,0.20912,100.0 +0.978,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,9,2,1.5,0.51,1.5,0.51,3,0,0.0,0.0 +1.0,0.0 +1,3,4,'1 ',1,1,1,0.0,0.0,2,'3WT ',1,1,1.0,0,1.0,0,1.0,0,1.0 +334279.0,0.13432,440.0,262298.0,0.20807,280.0,1515.0,0.10652,160.0,1.0,0.0 +0.978,138.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,3,0,0.0,0.0 +0.988,45.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,3,0,0.0,0.0 +0.9980000000000001,21.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,11,2,1.5,0.51,1.5,0.51,3,0,0.0,0.0 +0 / END OF TRANSFORMER DATA, BEGIN AREA DATA +0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA +'EATL P1 ',1,7.365,0.0,500.0,0.0,7.365,0.1,'R',0.0,50,1.0 +6,1,17.3,12.7,0.48,21.32,500.0,0.832,1.1,1.2,0.975,0.0125,0,0,0,0,'1 ',0.0 +5,1,20.5,18.0,0.48,21.32,240.0,1.7325,1.1419,1.2064,0.8968,0.0129,0,0,0,0,'1 ',0.0 +0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA +0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA +0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA +0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA +0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA +0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA +0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA +0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA +0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA +13,'1 ',0,0,1,1.0,0.99,13,2,100.0,' ',100.0,1,1,100.0 +0 / END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA +0 / END OF GNE DEVICE DATA, BEGIN INDUCTION MACHINE DATA +0 / END OF INDUCTION MACHINE DATA, BEGIN SUBSTATION DATA +1,'STATION 1',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',6,1,1.0,0.0 +2,'NB2',1,1,1.0,0.0 +3,'NLINE',1,1,1.0,0.0 +4,'NT2W',1,1,1.0,0.0 +5,'NT3W',1,1,1.0,0.0 +6,'NDCLINE',6,1,1.0,0.0 +7,'NGEN',6,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 +2,3,'1 ','Sw-LineToBus2','2',1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-T2wToBus3','2',1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-T3wToBus3Bus4','2',1,1,0.0,0.0,0.0,0.0 +1,6,'1 ','Sw-LineDcToBus5','2',1,1,0.0,0.0,0.0,0.0 +1,7,'1 ','Sw-Gen','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +6,7,'M','1 ' +6,6,'D','EATL P1 ' +1,3,'B',2,'1 ' +1,4,'2',3,'1 ' +1,5,'3',3,4,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +2,'STATION 2',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',2,1,1.0,0.0 +2,'NB2',7,1,1.0,0.0 +3,'NLINE',2,1,1.0,0.0 +4,'NLOAD',8,1,1.0,0.0 +5,'NFSHUNT',7,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-LineToBus1','2',1,1,0.0,0.0,0.0,0.0 +1,4,'1 ','Sw-Load','2',0,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-FixedShunt','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +8,4,'L','1 ' +7,5,'F','1 ' +2,3,'B',1,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +3,'STATION 3',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',3,1,1.0,0.0 +2,'NB2',9,1,1.0,0.0 +3,'NT2W',3,1,1.0,0.0 +4,'NT3W',3,1,1.0,0.0 +5,'NLOAD',10,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-T2w','2',1,1,0.0,0.0,0.0,0.0 +1,4,'1 ','Sw-T3w','2',1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-Load','2',0,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +10,5,'L','1 ' +3,3,'2',1,'1 ' +3,4,'3',1,4,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +4,'STATION 4',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',4,1,1.0,0.0 +2,'NB2',11,1,1.0,0.0 +3,'NT3W',4,1,1.0,0.0 +4,'NLOAD',12,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-T3w','2',1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-Load','2',0,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +12,4,'L','1 ' +4,3,'3',1,3,'1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +5,'STATION 5',0.0,0.0,0.1 + / BEGIN SUBSTATION NODE DATA +1,'NB1',5,1,1.0,0.0 +2,'NB2',13,1,1.0,0.0 +3,'NDCLINE',5,1,1.0,0.0 +4,'NLOAD',14,1,1.0,0.0 +5,'NSSHUNT',13,1,1.0,0.0 +0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA +1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-DcLine','2',1,1,0.0,0.0,0.0,0.0 +1,4,'1 ','Sw-Load','2',0,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-SwitchedShunt','2',1,1,0.0,0.0,0.0,0.0 +0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA +14,4,'L','1 ' +13,5,'S','1 ' +5,3,'D','EATL P1 ' +0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA +0 / END OF SUBSTATION DATA +Q diff --git a/psse/psse-converter/src/test/resources/parallelTwoTerminalDcBetweenSameAcBuses.xiidm b/psse/psse-converter/src/test/resources/parallelTwoTerminalDcBetweenSameAcBuses.xiidm index f8914ec3692..f3f7555c4ea 100644 --- a/psse/psse-converter/src/test/resources/parallelTwoTerminalDcBetweenSameAcBuses.xiidm +++ b/psse/psse-converter/src/test/resources/parallelTwoTerminalDcBetweenSameAcBuses.xiidm @@ -177,8 +177,8 @@ - - + + diff --git a/psse/psse-converter/src/test/resources/twoTerminalDc.xiidm b/psse/psse-converter/src/test/resources/twoTerminalDc.xiidm index c7e830e6729..42afdd0d9c1 100644 --- a/psse/psse-converter/src/test/resources/twoTerminalDc.xiidm +++ b/psse/psse-converter/src/test/resources/twoTerminalDc.xiidm @@ -175,7 +175,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/twoTerminalDc_with_negative_setvl.xiidm b/psse/psse-converter/src/test/resources/twoTerminalDc_with_negative_setvl.xiidm index 60b2f5585a6..9bab61d29b4 100644 --- a/psse/psse-converter/src/test/resources/twoTerminalDc_with_negative_setvl.xiidm +++ b/psse/psse-converter/src/test/resources/twoTerminalDc_with_negative_setvl.xiidm @@ -175,7 +175,7 @@ - + diff --git a/psse/psse-model-test/src/main/resources/IEEE_14_bus_completed_exported.raw b/psse/psse-model-test/src/main/resources/IEEE_14_bus_completed_exported.raw index 9c78c69acf3..432d4fcf4fb 100644 --- a/psse/psse-model-test/src/main/resources/IEEE_14_bus_completed_exported.raw +++ b/psse/psse-model-test/src/main/resources/IEEE_14_bus_completed_exported.raw @@ -70,11 +70,11 @@ 1,2,0.0,999.99,'IEEE14 ' 0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA 'EATL P1 ',0,7.365,0.0,500.0,0.0,7.365,0.1,'R',0.0,50,1.0 -10,1,17.3,12.7,0.48,21.32,500.0,0.832,1.1,1.2,0.975,0.0125,0,0,0,1 ,0.0 -12,1,20.5,18.0,0.48,21.32,240.0,1.7325,1.1419,1.2064,0.8968,0.0129,0,0,0,1 ,0.0 +10,1,17.3,12.7,0.48,21.32,500.0,0.832,1.1,1.2,0.975,0.0125,0,0,0,'1 ',0.0 +12,1,20.5,18.0,0.48,21.32,240.0,1.7325,1.1419,1.2064,0.8968,0.0129,0,0,0,'1 ',0.0 'WATL P1 ',1,5.125,280.0,500.0,0.0,5.125,0.1,'R',0.0,20,1.0 -12,1,17.3,12.7,0.44,21.32,500.0,0.832,1.125,1.2,0.975,0.0125,0,0,0,1 ,0.0 -14,1,20.5,17.9,0.44,21.32,240.0,1.7325,1.1032,1.2064,0.8968,0.0129,0,0,0,1 ,0.0 +12,1,17.3,12.7,0.44,21.32,500.0,0.832,1.125,1.2,0.975,0.0125,0,0,0,'1 ',0.0 +14,1,20.5,17.9,0.44,21.32,240.0,1.7325,1.1032,1.2064,0.8968,0.0129,0,0,0,'1 ',0.0 0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA 'VDCLINE1',1,0.71,1,0.3204,2,0.3883,3,0.1942,4,0.0971 7,2,2,-209.0,0.95,100.0,0.1,50.0,400.0,1200.0,0.1,100.0,-110.0,7,100.0 diff --git a/psse/psse-model-test/src/main/resources/five_bus_nodeBreaker_rev35.raw b/psse/psse-model-test/src/main/resources/five_bus_nodeBreaker_rev35.raw new file mode 100644 index 00000000000..97b8fc8bba6 --- /dev/null +++ b/psse/psse-model-test/src/main/resources/five_bus_nodeBreaker_rev35.raw @@ -0,0 +1,139 @@ + 0, 100.0, 35, 0, 0, 60.00 / October 01, 2013 18:37:53 + 17/04/24 UW ARCHIVE 100.0 1962 W Five Bus nodeBreaker Test Case + +0 / END OF SYSTEM-WIDE DATA, BEGIN BUS DATA + 1,'Bus 1 ', 138.0000,3, 1, 1, 1,1.06000, 0.0000 + 2,'Bus 2 ', 138.0000,1, 1, 1, 1,1.00000, 0.0000 + 3,'Bus 3 ', 45.0000,1, 1, 1, 1,1.00000, 0.0000 + 4,'Bus 4 ', 21.0000,1, 1, 1, 1,1.00000, 0.0000 + 5,'Bus 5 ', 138.0000,1, 1, 1, 1,1.00000, 0.0000 +0 / END OF BUS DATA, BEGIN LOAD DATA + 2,'1 ',1, 1, 1, 21.700, 12.700, 0.000, 0.000, 0.000, -0.000, 1,1 + 3,'1 ',1, 1, 1, 94.200, 19.000, 0.000, 0.000, 0.000, -0.000, 1,1 + 4,'1 ',1, 1, 1, 47.800, -3.900, 0.000, 0.000, 0.000, -0.000, 1,1 + 5,'1 ',1, 1, 1, 7.600, 1.600, 0.000, 0.000, 0.000, -0.000, 1,1 +0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA + 2,'1 ', 1, 0.000, 19.000 +0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA + 1,'1 ', 232.392, -16.549, 0.000, 0.000,1.06000, 1, 2, 615.000, 0.00000, 1.00000, 0.00000, 0.00000,1.00000,1, 100.0, 10000.000,-10000.000, 0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000,0, 1.0000 +0 / END OF GENERATOR DATA, BEGIN BRANCH DATA + 1, 2,'1 ', 0.01938, 0.05917,0.05280, '', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 +0 / END OF BRANCH DATA, BEGIN SYSTEM SWITCHING DEVICE DATA +0 / END OF SYSTEM SWITCHING DEVICE DATA, BEGIN TRANSFORMER DATA + 1, 3, 0,'1 ',1,1,1, 0.00000, 0.00000,2,'2WT ',1, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 0.00000, 0.20912, 100.00 + 0.97800, 0.000, 0.000, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,1, 3, 2, 1.50000, 0.51000, 1.50000, 0.51000,3, 0, 0.00000, 0.00000 + 1.00000, 0.000 + 1, 3, 4,'1 ',1,1,1, 0.00000, 0.00000,2,'3WT ',1, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000 + 3.34279E+5, 1.34320E-1, 440.00, 2.62298E+5, 2.08070E-1, 280.00, 1.51500E+3, 1.06520E-1, 160.00,1.00000, 0.0000 + 0.97800, 138.000, 0.000, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,0, 0, 0, 1.50000, 0.51000, 1.50000, 0.51000,3, 0, 0.00000, 0.00000 + 0.98800, 45.000, 0.000, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,0, 0, 0, 1.50000, 0.51000, 1.50000, 0.51000,3, 0, 0.00000, 0.00000 + 0.99800, 21.000, 0.000, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,1, 4, 2, 1.50000, 0.51000, 1.50000, 0.51000,3, 0, 0.00000, 0.00000 +0 / END OF TRANSFORMER DATA, BEGIN AREA DATA +0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA +'EATL P1 ',0, 7.3650, 0.00, 500.00, 0.00, 7.3650, 0.10000,'R', 0.00, 50, 1.00000 + 1, 1,17.30,12.70, 0.4800,21.3200, 500.0,0.83200,1.10000,1.20000,0.97500,0.01250, 0, 0, 0, 0,'1 ', 0.0000 + 5, 1,20.50,18.00, 0.4800,21.3200, 240.0,1.73250,1.14190,1.20640,0.89680,0.01290, 0, 0, 0, 0,'1 ', 0.0000 +0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA +0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA +0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA +0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA +0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA +0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA +0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA +0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA +0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA + 5,'1 ',0,0,1,1.00000,0.99000, 5,2,100.0,' ', 100.00, 1, 1, 100.00 +0 /END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA +0 /END OF GNE DEVICE DATA, BEGIN INDUCTION MACHINE DATA +0 /END OF INDUCTION MACHINE DATA, BEGIN SUBSTATION DATA + 1, 'STATION 1', 0.0, 0.0, 0.1 + / BEGIN SUBSTATION NODE DATA + 1, 'NB1', 1, 1, 1.0, 0.0 + 2, 'NB2', 1, 1, 1.0, 0.0 + 3, 'NLINE', 1, 1, 1.0, 0.0 + 4, 'NT2W', 1, 1, 1.0, 0.0 + 5, 'NT3W', 1, 1, 1.0, 0.0 + 6, 'NDCLINE', 1, 1, 1.0, 0.0 + 7, 'NGEN', 1, 1, 1.0, 0.0 + 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA + 1, 2, '1 ', 'Sw-BusBars', 2, 1, 1, 0, 0, 0, 0 + 2, 3, '1 ', 'Sw-LineToBus2', 2, 1, 1, 0, 0, 0, 0 + 2, 4, '1 ', 'Sw-T2wToBus3', 2, 1, 1, 0, 0, 0, 0 + 2, 5, '1 ', 'Sw-T3wToBus3Bus4', 2, 1, 1, 0, 0, 0, 0 + 1, 6, '1 ', 'Sw-LineDcToBus5', 2, 1, 1, 0, 0, 0, 0 + 1, 7, '1 ', 'Sw-Gen', 2, 1, 1, 0, 0, 0, 0 + 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION TERMINAL DATA + 1, 7, 'M', '1 ' + 1, 3, 'B', 2, '1 ' + 1, 4, '2', 3, '1 ' + 1, 5, '3', 3, 4, '1 ' + 1, 6, 'D', 'EATL P1 ' + 0 / END OF SUBSTATION TERMINAL DATA + 2, 'STATION 2', 0.0, 0.0, 0.1 + / BEGIN SUBSTATION NODE DATA + 1, 'NB1', 2, 1, 1.0, 0.0 + 2, 'NB2', 2, 1, 1.0, 0.0 + 3, 'NLINE', 2, 1, 1.0, 0.0 + 4, 'NLOAD', 2, 1, 1.0, 0.0 + 5, 'NFSHUNT', 2, 1, 1.0, 0.0 + 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA + 1, 2, '1 ', 'Sw-BusBars', 2, 1, 1, 0, 0, 0, 0 + 1, 3, '1 ', 'Sw-LineToBus1', 2, 1, 1, 0, 0, 0, 0 + 1, 4, '1 ', 'Sw-Load', 2, 1, 1, 0, 0, 0, 0 + 2, 5, '1 ', 'Sw-FixedShunt', 2, 1, 1, 0, 0, 0, 0 + 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION TERMINAL DATA + 2, 4, 'L', '1 ' + 2, 5, 'F', '1 ' + 2, 3, 'B', 1, '1 ' + 0 / END OF SUBSTATION TERMINAL DATA + 3, 'STATION 3', 0.0, 0.0, 0.1 + / BEGIN SUBSTATION NODE DATA + 1, 'NB1', 3, 1, 1.0, 0.0 + 2, 'NB2', 3, 1, 1.0, 0.0 + 3, 'NT2W', 3, 1, 1.0, 0.0 + 4, 'NT3W', 3, 1, 1.0, 0.0 + 5, 'NLOAD', 3, 1, 1.0, 0.0 + 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA + 1, 2, '1 ', 'Sw-BusBars', 2, 1, 1, 0, 0, 0, 0 + 1, 3, '1 ', 'Sw-T2w', 2, 1, 1, 0, 0, 0, 0 + 1, 4, '1 ', 'Sw-T3w', 2, 1, 1, 0, 0, 0, 0 + 2, 5, '1 ', 'Sw-Load', 2, 1, 1, 0, 0, 0, 0 + 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION TERMINAL DATA + 3, 5, 'L', '1 ' + 3, 3, '2', 1, '1 ' + 3, 4, '3', 1, 4, '1 ' + 0 / END OF SUBSTATION TERMINAL DATA + 4, 'STATION 4', 0.0, 0.0, 0.1 + / BEGIN SUBSTATION NODE DATA + 1, 'NB1', 4, 1, 1.0, 0.0 + 2, 'NB2', 4, 1, 1.0, 0.0 + 3, 'NT3W', 4, 1, 1.0, 0.0 + 4, 'NLOAD', 4, 1, 1.0, 0.0 + 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA + 1, 2, '1 ', 'Sw-BusBars', 2, 1, 1, 0, 0, 0, 0 + 1, 3, '1 ', 'Sw-T3w', 2, 1, 1, 0, 0, 0, 0 + 2, 4, '1 ', 'Sw-Load', 2, 1, 1, 0, 0, 0, 0 + 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION TERMINAL DATA + 4, 4, 'L', '1 ' + 4, 3, '3', 1, 3, '1 ' + 0 / END OF SUBSTATION TERMINAL DATA + 5, 'STATION 5', 0.0, 0.0, 0.1 + / BEGIN SUBSTATION NODE DATA + 1, 'NB1', 5, 1, 1.0, 0.0 + 2, 'NB2', 5, 1, 1.0, 0.0 + 3, 'NDCLINE', 5, 1, 1.0, 0.0 + 4, 'NLOAD', 5, 1, 1.0, 0.0 + 5, 'NSSHUNT', 5, 1, 1.0, 0.0 + 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA + 1, 2, '1 ', 'Sw-BusBars', 2, 1, 1, 0, 0, 0, 0 + 1, 3, '1 ', 'Sw-DcLine', 2, 1, 1, 0, 0, 0, 0 + 1, 4, '1 ', 'Sw-Load', 2, 1, 1, 0, 0, 0, 0 + 2, 5, '1 ', 'Sw-SwitchedShunt', 2, 1, 1, 0, 0, 0, 0 + 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION TERMINAL DATA + 5, 4, 'L', '1 ' + 5, 5, 'S', '1 ' + 5, 3, 'D', 'EATL P1 ' + 0 / END OF SUBSTATION TERMINAL DATA +0 /END OF SUBSTATION DATA +Q diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/io/AbstractRecordGroup.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/io/AbstractRecordGroup.java index f860f2b498a..d7040d38cfe 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/io/AbstractRecordGroup.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/io/AbstractRecordGroup.java @@ -145,6 +145,10 @@ public void writeHead(T psseObject, Context context, OutputStream outputStream) } public List readFromStrings(List records, Context context) { + // fieldNames should not be updated when recordsList is empty + if (records.isEmpty()) { + return new ArrayList<>(); + } String[] allFieldNames = fieldNames(context.getVersion()); List psseObjects = parseRecords(records, allFieldNames, context); String[] actualFieldNames = ArrayUtils.subarray(allFieldNames, 0, context.getCurrentRecordGroupMaxNumFields()); diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformerWinding.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformerWinding.java index b5d92a38862..3f67985d121 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformerWinding.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformerWinding.java @@ -102,6 +102,10 @@ public int getCod() { return cod; } + public void setCont(int cont) { + this.cont = cont; + } + public int getCont() { return cont; } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/TwoTerminalDcTransmissionLineData.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/TwoTerminalDcTransmissionLineData.java index ef52d97c4c8..661b651f7a8 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/TwoTerminalDcTransmissionLineData.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/TwoTerminalDcTransmissionLineData.java @@ -37,7 +37,7 @@ class TwoTerminalDcTransmissionLineData extends AbstractRecordGroup Date: Mon, 22 Apr 2024 09:00:32 +0200 Subject: [PATCH 09/22] Fix code smells MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- .../java/com/powsybl/psse/converter/BusConverter.java | 2 +- .../powsybl/psse/converter/TwoTerminalDcConverter.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java index c6df3401d14..c79d03eec75 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java @@ -81,7 +81,7 @@ static void updateBuses(Network network, PssePowerFlowModel psseModel, NodeBreak addedBuses.add(psseBus); }); - psseModel.addBuses(addedBuses.stream().sorted(Comparator.comparingInt(psseBus -> psseBus.getI())).toList()); + psseModel.addBuses(addedBuses.stream().sorted(Comparator.comparingInt(PsseBus::getI)).toList()); } private static PsseBus createNewBus(int copyBus, int newBus, Map busNumToPsseBus) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java index 6c992eaa962..7099768b804 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java @@ -74,7 +74,7 @@ void create() { LccConverterStation cI = adderI.add(); HvdcLineAdder adder = getNetwork().newHvdcLine() - .setId(getTwoTerminalDcId(getNetwork(), psseTwoTerminalDc)) + .setId(getTwoTerminalDcId(psseTwoTerminalDc)) .setName(psseTwoTerminalDc.getName()) .setR(psseTwoTerminalDc.getRdc()) .setNominalV(psseTwoTerminalDc.getVschd()) @@ -103,7 +103,7 @@ private static double getTwoTerminalDcMaxP(PsseTwoTerminalDcTransmissionLine pss return getTwoTerminalDcActivePowerSetpoint(psseTwoTerminalDc) * DEFAULT_MAXP_FACTOR; } - // power factor calculated under assumption that that the maximum overlap angle is 60 degree (see Kimbark's book) + // power factor calculated under assumption that the maximum overlap angle is 60 degree (see Kimbark's book) private static double getLccConverterPowerFactor(PsseTwoTerminalDcConverter converter) { return 0.5 * (Math.cos(Math.toRadians(converter.getAnmx())) + Math.cos(Math.toRadians(60.0))); } @@ -113,13 +113,13 @@ private String getLccConverterId(PsseTwoTerminalDcTransmissionLine psseTwoTermin id -> getNetwork().getLccConverterStation(id) != null); } - private static String getTwoTerminalDcId(Network network, PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc) { + private static String getTwoTerminalDcId(PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc) { return "TwoTerminalDc-" + psseTwoTerminalDc.getRectifier().getIp() + "-" + psseTwoTerminalDc.getInverter().getIp() + "-" + psseTwoTerminalDc.getName(); } static void updateTwoTerminalDcTransmissionLines(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { psseModel.getTwoTerminalDcTransmissionLines().forEach(psseTwoTerminalDc -> { - String hvdcId = getTwoTerminalDcId(network, psseTwoTerminalDc); + String hvdcId = getTwoTerminalDcId(psseTwoTerminalDc); HvdcLine hvdcLine = network.getHvdcLine(hvdcId); String equipmentIdRectifier = getNodeBreakerEquipmentId(PSSE_TWO_TERMINAL_DC_LINE, psseTwoTerminalDc.getRectifier().getIp(), psseTwoTerminalDc.getName()); From 364a2f7a03e271e21a5da22e956a2c5318bbe60e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Marqu=C3=A9s?= Date: Tue, 11 Jun 2024 13:01:32 +0200 Subject: [PATCH 10/22] switching device type must be an integer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- ...IEEE_14_bus_nodeBreaker_rev35_exported.raw | 22 +++++----- ...s_nodeBreaker_rev35_split_bus_exported.raw | 22 +++++----- .../five_bus_nodeBreaker_rev35_exported.raw | 42 +++++++++---------- ...nodeBreaker_rev35_split_buses_exported.raw | 42 +++++++++---------- .../psse/model/pf/io/SubstationData.java | 7 ++-- ...IEEE_14_bus_nodeBreaker_rev35_exported.raw | 22 +++++----- ...EEE_14_bus_nodeBreaker_rev35_exported.rawx | 22 +++++----- 7 files changed, 90 insertions(+), 89 deletions(-) diff --git a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw index 7df443e5c9a..d0523789417 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw +++ b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw @@ -92,10 +92,10 @@ 4,'NL5',1,1,1.0,0.0 5,'NG1',1,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 -1,3,'1 ','Sw-BranchToBus2','2',1,1,0.0,0.0,0.0,0.0 -2,4,'1 ','Sw-BranchToBus5','2',1,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-Gen1','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,1,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-BranchToBus2',2,1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-BranchToBus5',2,1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-Gen1',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 1,5,'M','1 ' 1,3,'B',2,'1 ' @@ -112,13 +112,13 @@ 7,'NG1',2,1,1.0,0.0 8,'NLd1',2,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 -1,6,'1 ','Sw-BranchToBus1','2',1,1,0.0,0.0,0.0,0.0 -1,7,'1 ','Sw-Gen1','2',1,1,0.0,0.0,0.0,0.0 -1,8,'1 ','Sw-Load1','2',1,1,0.0,0.0,0.0,0.0 -2,3,'1 ','Sw-BranchToBus3','2',1,1,0.0,0.0,0.0,0.0 -2,4,'1 ','Sw-BranchToBus4','2',1,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-BranchToBus5','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,1,1,0.0,0.0,0.0,0.0 +1,6,'1 ','Sw-BranchToBus1',2,1,1,0.0,0.0,0.0,0.0 +1,7,'1 ','Sw-Gen1',2,1,1,0.0,0.0,0.0,0.0 +1,8,'1 ','Sw-Load1',2,1,1,0.0,0.0,0.0,0.0 +2,3,'1 ','Sw-BranchToBus3',2,1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-BranchToBus4',2,1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-BranchToBus5',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 2,7,'M','1 ' 2,8,'L','1 ' diff --git a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw index fce69f8951e..bcbfdcfe666 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw +++ b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw @@ -94,10 +94,10 @@ 4,'NL5',1,1,1.0,0.0 5,'NG1',1,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 -1,3,'1 ','Sw-BranchToBus2','2',1,1,0.0,0.0,0.0,0.0 -2,4,'1 ','Sw-BranchToBus5','2',1,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-Gen1','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-BranchToBus2',2,1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-BranchToBus5',2,1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-Gen1',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 1,5,'M','1 ' 15,3,'B',2,'1 ' @@ -114,13 +114,13 @@ 7,'NG1',2,1,1.0,0.0 8,'NLd1',2,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 -1,6,'1 ','Sw-BranchToBus1','2',1,1,0.0,0.0,0.0,0.0 -1,7,'1 ','Sw-Gen1','2',1,1,0.0,0.0,0.0,0.0 -1,8,'1 ','Sw-Load1','2',1,1,0.0,0.0,0.0,0.0 -2,3,'1 ','Sw-BranchToBus3','2',1,1,0.0,0.0,0.0,0.0 -2,4,'1 ','Sw-BranchToBus4','2',1,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-BranchToBus5','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 +1,6,'1 ','Sw-BranchToBus1',2,1,1,0.0,0.0,0.0,0.0 +1,7,'1 ','Sw-Gen1',2,1,1,0.0,0.0,0.0,0.0 +1,8,'1 ','Sw-Load1',2,1,1,0.0,0.0,0.0,0.0 +2,3,'1 ','Sw-BranchToBus3',2,1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-BranchToBus4',2,1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-BranchToBus5',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 2,7,'M','1 ' 2,8,'L','1 ' diff --git a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_exported.raw b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_exported.raw index 23b8fd90165..4a6aeed6319 100644 --- a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_exported.raw +++ b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_exported.raw @@ -57,12 +57,12 @@ 6,'NDCLINE',1,1,1.0,0.0 7,'NGEN',1,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 -2,3,'1 ','Sw-LineToBus2','2',1,1,0.0,0.0,0.0,0.0 -2,4,'1 ','Sw-T2wToBus3','2',1,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-T3wToBus3Bus4','2',1,1,0.0,0.0,0.0,0.0 -1,6,'1 ','Sw-LineDcToBus5','2',1,1,0.0,0.0,0.0,0.0 -1,7,'1 ','Sw-Gen','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,1,1,0.0,0.0,0.0,0.0 +2,3,'1 ','Sw-LineToBus2',2,1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-T2wToBus3',2,1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-T3wToBus3Bus4',2,1,1,0.0,0.0,0.0,0.0 +1,6,'1 ','Sw-LineDcToBus5',2,1,1,0.0,0.0,0.0,0.0 +1,7,'1 ','Sw-Gen',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 1,7,'M','1 ' 1,6,'D','EATL P1 ' @@ -78,10 +78,10 @@ 4,'NLOAD',2,1,1.0,0.0 5,'NFSHUNT',2,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 -1,3,'1 ','Sw-LineToBus1','2',1,1,0.0,0.0,0.0,0.0 -1,4,'1 ','Sw-Load','2',1,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-FixedShunt','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,1,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-LineToBus1',2,1,1,0.0,0.0,0.0,0.0 +1,4,'1 ','Sw-Load',2,1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-FixedShunt',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 2,4,'L','1 ' 2,5,'F','1 ' @@ -95,10 +95,10 @@ 4,'NT3W',3,1,1.0,0.0 5,'NLOAD',3,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 -1,3,'1 ','Sw-T2w','2',1,1,0.0,0.0,0.0,0.0 -1,4,'1 ','Sw-T3w','2',1,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-Load','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,1,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-T2w',2,1,1,0.0,0.0,0.0,0.0 +1,4,'1 ','Sw-T3w',2,1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-Load',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 3,5,'L','1 ' 3,3,'2',1,'1 ' @@ -111,9 +111,9 @@ 3,'NT3W',4,1,1.0,0.0 4,'NLOAD',4,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 -1,3,'1 ','Sw-T3w','2',1,1,0.0,0.0,0.0,0.0 -2,4,'1 ','Sw-Load','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,1,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-T3w',2,1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-Load',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 4,4,'L','1 ' 4,3,'3',1,3,'1 ' @@ -126,10 +126,10 @@ 4,'NLOAD',5,1,1.0,0.0 5,'NSSHUNT',5,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 -1,3,'1 ','Sw-DcLine','2',1,1,0.0,0.0,0.0,0.0 -1,4,'1 ','Sw-Load','2',1,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-SwitchedShunt','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,1,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-DcLine',2,1,1,0.0,0.0,0.0,0.0 +1,4,'1 ','Sw-Load',2,1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-SwitchedShunt',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 5,4,'L','1 ' 5,5,'S','1 ' diff --git a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw index 08cd13044de..afa7fa497f7 100644 --- a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw +++ b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw @@ -66,12 +66,12 @@ 6,'NDCLINE',6,1,1.0,0.0 7,'NGEN',6,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 -2,3,'1 ','Sw-LineToBus2','2',1,1,0.0,0.0,0.0,0.0 -2,4,'1 ','Sw-T2wToBus3','2',1,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-T3wToBus3Bus4','2',1,1,0.0,0.0,0.0,0.0 -1,6,'1 ','Sw-LineDcToBus5','2',1,1,0.0,0.0,0.0,0.0 -1,7,'1 ','Sw-Gen','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 +2,3,'1 ','Sw-LineToBus2',2,1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-T2wToBus3',2,1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-T3wToBus3Bus4',2,1,1,0.0,0.0,0.0,0.0 +1,6,'1 ','Sw-LineDcToBus5',2,1,1,0.0,0.0,0.0,0.0 +1,7,'1 ','Sw-Gen',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 6,7,'M','1 ' 6,6,'D','EATL P1 ' @@ -87,10 +87,10 @@ 4,'NLOAD',8,1,1.0,0.0 5,'NFSHUNT',7,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 -1,3,'1 ','Sw-LineToBus1','2',1,1,0.0,0.0,0.0,0.0 -1,4,'1 ','Sw-Load','2',0,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-FixedShunt','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-LineToBus1',2,1,1,0.0,0.0,0.0,0.0 +1,4,'1 ','Sw-Load',2,0,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-FixedShunt',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 8,4,'L','1 ' 7,5,'F','1 ' @@ -104,10 +104,10 @@ 4,'NT3W',3,1,1.0,0.0 5,'NLOAD',10,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 -1,3,'1 ','Sw-T2w','2',1,1,0.0,0.0,0.0,0.0 -1,4,'1 ','Sw-T3w','2',1,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-Load','2',0,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-T2w',2,1,1,0.0,0.0,0.0,0.0 +1,4,'1 ','Sw-T3w',2,1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-Load',2,0,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 10,5,'L','1 ' 3,3,'2',1,'1 ' @@ -120,9 +120,9 @@ 3,'NT3W',4,1,1.0,0.0 4,'NLOAD',12,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 -1,3,'1 ','Sw-T3w','2',1,1,0.0,0.0,0.0,0.0 -2,4,'1 ','Sw-Load','2',0,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-T3w',2,1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-Load',2,0,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 12,4,'L','1 ' 4,3,'3',1,3,'1 ' @@ -135,10 +135,10 @@ 4,'NLOAD',14,1,1.0,0.0 5,'NSSHUNT',13,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',0,1,0.0,0.0,0.0,0.0 -1,3,'1 ','Sw-DcLine','2',1,1,0.0,0.0,0.0,0.0 -1,4,'1 ','Sw-Load','2',0,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-SwitchedShunt','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-DcLine',2,1,1,0.0,0.0,0.0,0.0 +1,4,'1 ','Sw-Load',2,0,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-SwitchedShunt',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 14,4,'L','1 ' 13,5,'S','1 ' diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java index 2c0d8a8f232..314044ac7b8 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java @@ -115,7 +115,7 @@ public void write(List substationList, Context context, OutputSt writeEndComment(" END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA", outputStream); SubstationSwitchingDeviceData switchingDeviceData = new SubstationSwitchingDeviceData(); - write(switchingDeviceData.buildRecords(substation.getSwitchingDevices(), context.getFieldNames(INTERNAL_SUBSTATION_SWITCHING_DEVICE), nodeData.quotedFields(), context), outputStream); + write(switchingDeviceData.buildRecords(substation.getSwitchingDevices(), context.getFieldNames(INTERNAL_SUBSTATION_SWITCHING_DEVICE), switchingDeviceData.quotedFields(), context), outputStream); writeEndComment(" END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA", outputStream); write(writeEquipmentTerminalData(substation.getEquipmentTerminals(), context), outputStream); @@ -158,7 +158,7 @@ public Class psseTypeClass() { private static class SubstationSwitchingDeviceData extends AbstractRecordGroup { SubstationSwitchingDeviceData() { super(INTERNAL_SUBSTATION_SWITCHING_DEVICE, "ni", "nj", "ckt", "name", "type", "status", "nstat", "x", "rate1", "rate2", "rate3"); - withQuotedFields(QUOTED_FIELDS); + withQuotedFields(QUOTED_FIELDS_SWITCHING_DEVICES); } @Override @@ -287,7 +287,7 @@ public Class psseTypeClass() { private static class SubstationSwitchingDevicexData extends AbstractRecordGroup { SubstationSwitchingDevicexData() { super(INTERNAL_SUBSTATION_SWITCHING_DEVICE); - withQuotedFields(QUOTED_FIELDS); + withQuotedFields(QUOTED_FIELDS_SWITCHING_DEVICES); } @Override @@ -322,4 +322,5 @@ public Class psseTypeClass() { } private static final String[] QUOTED_FIELDS = {"name", "type", "id", "ckt", "eqid"}; + private static final String[] QUOTED_FIELDS_SWITCHING_DEVICES = {"name", "ckt"}; } diff --git a/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw b/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw index a9775c5957c..e09d9ad305a 100644 --- a/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw +++ b/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.raw @@ -92,10 +92,10 @@ 4,'NL5',1,1,1.0,0.0 5,'NG1',1,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 -1,3,'1 ','Sw-BranchToBus2','2',1,1,0.0,0.0,0.0,0.0 -2,4,'1 ','Sw-BranchToBus5','2',1,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-Gen1','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,1,1,0.0,0.0,0.0,0.0 +1,3,'1 ','Sw-BranchToBus2',2,1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-BranchToBus5',2,1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-Gen1',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 1,5,'M','1 ' 1,3,'B',2,'1 ' @@ -112,13 +112,13 @@ 7,'NG1',2,1,1.0,0.0 8,'NLd1',2,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA -1,2,'1 ','Sw-BusBars','2',1,1,0.0,0.0,0.0,0.0 -1,6,'1 ','Sw-BranchToBus1','2',1,1,0.0,0.0,0.0,0.0 -1,7,'1 ','Sw-Gen1','2',1,1,0.0,0.0,0.0,0.0 -1,8,'1 ','Sw-Load1','2',1,1,0.0,0.0,0.0,0.0 -2,3,'1 ','Sw-BranchToBus3','2',1,1,0.0,0.0,0.0,0.0 -2,4,'1 ','Sw-BranchToBus4','2',1,1,0.0,0.0,0.0,0.0 -2,5,'1 ','Sw-BranchToBus5','2',1,1,0.0,0.0,0.0,0.0 +1,2,'1 ','Sw-BusBars',2,1,1,0.0,0.0,0.0,0.0 +1,6,'1 ','Sw-BranchToBus1',2,1,1,0.0,0.0,0.0,0.0 +1,7,'1 ','Sw-Gen1',2,1,1,0.0,0.0,0.0,0.0 +1,8,'1 ','Sw-Load1',2,1,1,0.0,0.0,0.0,0.0 +2,3,'1 ','Sw-BranchToBus3',2,1,1,0.0,0.0,0.0,0.0 +2,4,'1 ','Sw-BranchToBus4',2,1,1,0.0,0.0,0.0,0.0 +2,5,'1 ','Sw-BranchToBus5',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 2,7,'M','1 ' 2,8,'L','1 ' diff --git a/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.rawx b/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.rawx index 1e99ebc3e3a..2ce9bec6784 100644 --- a/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.rawx +++ b/psse/psse-model/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_exported.rawx @@ -125,17 +125,17 @@ "subswd" : { "fields" : [ "isub", "inode", "jnode", "swdid", "name", "type", "stat", "nstat", "xpu", "rate1", "rate2", "rate3" ], "data" : [ - [ 1,1,2,1 ,"Sw-BusBars","2",1,1,0.0,0.0,0.0,0.0 ], - [ 1,1,3,1 ,"Sw-BranchToBus2","2",1,1,0.0,0.0,0.0,0.0 ], - [ 1,2,4,1 ,"Sw-BranchToBus5","2",1,1,0.0,0.0,0.0,0.0 ], - [ 1,2,5,1 ,"Sw-Gen1","2",1,1,0.0,0.0,0.0,0.0 ], - [ 2,1,2,1 ,"Sw-BusBars","2",1,1,0.0,0.0,0.0,0.0 ], - [ 2,1,6,1 ,"Sw-BranchToBus1","2",1,1,0.0,0.0,0.0,0.0 ], - [ 2,1,7,1 ,"Sw-Gen1","2",1,1,0.0,0.0,0.0,0.0 ], - [ 2,1,8,1 ,"Sw-Load1","2",1,1,0.0,0.0,0.0,0.0 ], - [ 2,2,3,1 ,"Sw-BranchToBus3","2",1,1,0.0,0.0,0.0,0.0 ], - [ 2,2,4,1 ,"Sw-BranchToBus4","2",1,1,0.0,0.0,0.0,0.0 ], - [ 2,2,5,1 ,"Sw-BranchToBus5","2",1,1,0.0,0.0,0.0,0.0 ] + [ 1,1,2,1 ,"Sw-BusBars",2,1,1,0.0,0.0,0.0,0.0 ], + [ 1,1,3,1 ,"Sw-BranchToBus2",2,1,1,0.0,0.0,0.0,0.0 ], + [ 1,2,4,1 ,"Sw-BranchToBus5",2,1,1,0.0,0.0,0.0,0.0 ], + [ 1,2,5,1 ,"Sw-Gen1",2,1,1,0.0,0.0,0.0,0.0 ], + [ 2,1,2,1 ,"Sw-BusBars",2,1,1,0.0,0.0,0.0,0.0 ], + [ 2,1,6,1 ,"Sw-BranchToBus1",2,1,1,0.0,0.0,0.0,0.0 ], + [ 2,1,7,1 ,"Sw-Gen1",2,1,1,0.0,0.0,0.0,0.0 ], + [ 2,1,8,1 ,"Sw-Load1",2,1,1,0.0,0.0,0.0,0.0 ], + [ 2,2,3,1 ,"Sw-BranchToBus3",2,1,1,0.0,0.0,0.0,0.0 ], + [ 2,2,4,1 ,"Sw-BranchToBus4",2,1,1,0.0,0.0,0.0,0.0 ], + [ 2,2,5,1 ,"Sw-BranchToBus5",2,1,1,0.0,0.0,0.0,0.0 ] ] }, "subterm" : { From e6900f609808fc16959e54171f4397ce5aef7fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Marqu=C3=A9s?= Date: Mon, 17 Jun 2024 13:03:20 +0200 Subject: [PATCH 11/22] Adjust to full export MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- .../psse/converter/AbstractConverter.java | 252 ++++++++++++-- .../powsybl/psse/converter/BusConverter.java | 121 ++++--- .../powsybl/psse/converter/ContextExport.java | 299 ++++++++++++++++ .../FixedShuntCompensatorConverter.java | 18 +- .../psse/converter/GeneratorConverter.java | 27 +- .../powsybl/psse/converter/LineConverter.java | 19 +- .../powsybl/psse/converter/LoadConverter.java | 39 +-- .../psse/converter/NodeBreakerExport.java | 137 -------- .../powsybl/psse/converter/PsseExporter.java | 22 +- .../psse/converter/SlackConverter.java | 2 +- .../SwitchedShuntCompensatorConverter.java | 35 +- .../psse/converter/TransformerConverter.java | 46 +-- .../converter/TwoTerminalDcConverter.java | 53 ++- .../psse/converter/VoltageLevelConverter.java | 329 +++++++++++------- .../IEEE_14_buses_duplicate_ids_rev35.xiidm | 12 +- .../IEEE_24_bus_updated_exported.raw | 20 +- .../RawCaseWithSpecialCharacters_exported.raw | 2 +- .../test/resources/SwitchedShunt_exported.raw | 2 +- .../ThreeMIB_T3W_modified_exported.raw | 2 +- .../resources/ThreeMIB_T3W_phase_exported.raw | 2 +- .../TwoWindingsTransformerPhase_exported.raw | 2 +- .../five_bus_nodeBreaker_rev35.xiidm | 6 +- ...nodeBreaker_rev35_split_buses_exported.raw | 24 +- ...allelTwoTerminalDcBetweenSameAcBuses.xiidm | 12 +- .../remoteControl_updated_exported.raw | 2 +- .../src/test/resources/twoTerminalDc.xiidm | 6 +- .../twoTerminalDc_with_negative_setvl.xiidm | 6 +- .../psse/model/pf/PssePowerFlowModel.java | 5 + 28 files changed, 946 insertions(+), 556 deletions(-) create mode 100644 psse/psse-converter/src/main/java/com/powsybl/psse/converter/ContextExport.java delete mode 100644 psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerExport.java diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java index 56c2c8562a0..3da14adff69 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java @@ -7,19 +7,18 @@ */ package com.powsybl.psse.converter; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -import com.powsybl.iidm.network.Terminal; -import com.powsybl.iidm.network.TopologyKind; -import com.powsybl.iidm.network.VoltageLevel; +import java.util.*; +import java.util.stream.Stream; + +import com.powsybl.iidm.network.*; +import com.powsybl.iidm.network.util.Identifiables; import com.powsybl.iidm.network.util.Networks; import com.powsybl.psse.model.PsseException; +import com.powsybl.psse.model.pf.PsseSubstation; +import com.powsybl.psse.model.pf.PsseTwoTerminalDcConverter; +import com.powsybl.psse.model.pf.PsseTwoTerminalDcTransmissionLine; import org.apache.commons.math3.complex.Complex; -import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.util.ContainersMapping; /** @@ -74,13 +73,184 @@ static String getBusId(int busNum) { return "B" + busNum; } + static OptionalInt extractBusNumber(String configuredBusId) { + if (configuredBusId.length() <= 1) { + return OptionalInt.empty(); + } + String busNumber = configuredBusId.substring(1); + return busNumber.matches("[1-9]\\d*") ? OptionalInt.of(Integer.parseInt(busNumber)) : OptionalInt.empty(); + } + + static String getFixedShuntId(int busI, String fixedShuntId) { + return getBusId(busI) + "-SH" + fixedShuntId; + } + + static String getGeneratorId(int busI, String generatorId) { + return getBusId(busI) + "-G" + generatorId; + } + + static String getLineId(int busI, int busJ, String ckt) { + return "L-" + busI + "-" + busJ + "-" + ckt; + } + + static String getLoadId(int busI, String loadId) { + return getBusId(busI) + "-L" + loadId; + } + + static String getSwitchedShuntId(int busI, String id) { + return getBusId(busI) + "-SwSH" + id; + } + + static String getTransformerId(int busI, int busJ, String ckt) { + return "T-" + busI + "-" + busJ + "-" + ckt; + } + + static String getTransformerId(int busI, int busJ, int busK, String ckt) { + return "T-" + busI + "-" + busJ + "-" + busK + "-" + ckt; + } + + // we can not use rectifierIp and inverterIp as it is managed with only one end in substationData + // In Psse each two-terminal dc line must have a unique name (up to 12 characters) + static String getTwoTerminalDcId(String name) { + return "TwoTerminalDc-" + name; + } + + public static String extractTwoTerminalDcName(String twoTerminalDcId) { + String name = twoTerminalDcId.replace("TwoTerminalDc-", ""); + return name.substring(0, Math.min(12, name.length())); + } + + static String getLccConverterId(Network network, PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc, PsseTwoTerminalDcConverter converter) { + return Identifiables.getUniqueId("LccConverter-" + converter.getIp() + "-" + psseTwoTerminalDc.getName(), id -> network.getLccConverterStation(id) != null); + } + + static String getSwitchId(String voltageLevelId, PsseSubstation.PsseSubstationSwitchingDevice switchingDevice) { + return voltageLevelId + "-Sw-" + switchingDevice.getNi() + "-" + switchingDevice.getNj() + "-" + switchingDevice.getCkt(); + } + + static String busbarSectionId(String voltageLevelId, int node) { + return String.format("%s-Busbar-%d", voltageLevelId, node); + } + + public static Optional extractCkt(String identifiableId, IdentifiableType identifiableType) { + return switch (identifiableType) { + case SWITCH, LINE, TWO_WINDINGS_TRANSFORMER, THREE_WINDINGS_TRANSFORMER -> extractCkt(identifiableId, "-"); + case LOAD -> extractCkt(identifiableId, "-L"); + case GENERATOR -> extractCkt(identifiableId, "-G"); + case SHUNT_COMPENSATOR -> { + Optional ckt = extractCkt(identifiableId, "-SH"); + yield ckt.isPresent() ? ckt : extractCkt(identifiableId, "-SwSH"); + } + case HVDC_LINE -> Optional.of(extractTwoTerminalDcName(identifiableId)); + default -> throw new PsseException("unexpected identifiableType: " + identifiableType.name()); + }; + } + + private static Optional extractCkt(String identifiableId, String subString) { + int index = identifiableId.lastIndexOf(subString); + if (index != -1) { + return Optional.of(identifiableId.substring(index + subString.length())); + } else { + return Optional.empty(); + } + } + static String getNodeBreakerEquipmentIdBus(String equipmentId, int bus) { return equipmentId + "." + bus; } + static String getPsseEquipmentType(Identifiable identifiable) { + return switch (identifiable.getType()) { + case LOAD -> PsseEquipmentType.PSSE_LOAD.getTextCode(); + case GENERATOR -> PsseEquipmentType.PSSE_GENERATOR.getTextCode(); + case LINE -> PsseEquipmentType.PSSE_BRANCH.getTextCode(); + case TWO_WINDINGS_TRANSFORMER -> PsseEquipmentType.PSSE_TWO_WINDING.getTextCode(); + case THREE_WINDINGS_TRANSFORMER -> PsseEquipmentType.PSSE_THREE_WINDING.getTextCode(); + case SHUNT_COMPENSATOR -> { + ShuntCompensator shunt = (ShuntCompensator) identifiable; + yield isFixedShunt(shunt) ? PsseEquipmentType.PSSE_FIXED_SHUNT.getTextCode() : PsseEquipmentType.PSSE_SWITCHED_SHUNT.getTextCode(); + } + case HVDC_LINE -> PsseEquipmentType.PSSE_TWO_TERMINAL_DC_LINE.getTextCode(); + default -> throw new PsseException("unexpected identifiableType: " + identifiable.getType().name()); + }; + } + + private static boolean isFixedShunt(ShuntCompensator shunt) { + if (shunt.getId().contains("-SH")) { + return true; + } else if (shunt.getId().contains("-SwSH")) { + return false; + } else { + return shunt.getMaximumSectionCount() == 1 + && !shunt.isVoltageRegulatorOn() + && Double.isNaN(shunt.getTargetV()); + } + } + + static List getEquipmentListToBeExported(VoltageLevel voltageLevel) { + List equipmentListToBeExported = new ArrayList<>(); + for (Connectable connectable : voltageLevel.getConnectables()) { + if (isEquipmentToBeExported(connectable.getType())) { + if (connectable.getType().equals(IdentifiableType.HVDC_CONVERTER_STATION)) { + HvdcConverterStation converterStation = (HvdcConverterStation) connectable; + equipmentListToBeExported.add(converterStation.getHvdcLine().getId()); + } else { + equipmentListToBeExported.add(connectable.getId()); + } + } + } + return equipmentListToBeExported.stream().sorted().toList(); + } + + static List getEquipmentNodes(VoltageLevel voltageLevel, String equipmentId) { + return getEquipmentTerminals(voltageLevel, equipmentId).stream().map(terminal -> terminal.getNodeBreakerView().getNode()).toList(); + } + + static List getEquipmentTerminals(VoltageLevel voltageLevel, String equipmentId) { + List terminals = new ArrayList<>(); + Connectable connectable = voltageLevel.getNetwork().getConnectable(equipmentId); + if (connectable != null) { + connectable.getTerminals().forEach(terminal -> addVoltageLevelTerminal(voltageLevel, terminal, terminals)); + } else { + Identifiable identifiable = voltageLevel.getNetwork().getIdentifiable(equipmentId); + if (identifiable != null && identifiable.getType().equals(IdentifiableType.HVDC_LINE)) { + HvdcLine hvdcLine = (HvdcLine) identifiable; + addVoltageLevelTerminal(voltageLevel, hvdcLine.getConverterStation1().getTerminal(), terminals); + addVoltageLevelTerminal(voltageLevel, hvdcLine.getConverterStation2().getTerminal(), terminals); + } else { + throw new PsseException("Unexpected identifiable: " + equipmentId); + } + } + return terminals; + } + + static ThreeSides getTerminalSide(Terminal terminal) { + if (terminal.getConnectable().getType().equals(IdentifiableType.HVDC_CONVERTER_STATION)) { + HvdcConverterStation converterStation = (HvdcConverterStation) terminal.getConnectable(); + return converterStation.equals(converterStation.getHvdcLine().getConverterStation1()) ? ThreeSides.ONE : ThreeSides.TWO; + } else { + return terminal.getSide(); + } + } + + private static void addVoltageLevelTerminal(VoltageLevel voltageLevel, Terminal terminal, List terminals) { + if (terminal != null && terminal.getVoltageLevel().equals(voltageLevel)) { + terminals.add(terminal); + } + } + + private static boolean isEquipmentToBeExported(IdentifiableType type) { + return switch (type) { + case LOAD, GENERATOR, SHUNT_COMPENSATOR, LINE, TWO_WINDINGS_TRANSFORMER, THREE_WINDINGS_TRANSFORMER, HVDC_CONVERTER_STATION -> + true; + case BUSBAR_SECTION, HVDC_LINE, SWITCH -> false; + default -> throw new PsseException("Unexpected equipment type: " + type.name()); + }; + } + // EquipmentId must be independent of the bus order static String getNodeBreakerEquipmentId(String type, int busI, int busJ, int busK, String id) { - List sortedBuses = List.of(busI, busJ, busK).stream().sorted().toList(); + List sortedBuses = Stream.of(busI, busJ, busK).sorted().toList(); int bus1 = sortedBuses.get(0); int bus2 = sortedBuses.get(1); int bus3 = sortedBuses.get(2); @@ -100,45 +270,59 @@ static String getNodeBreakerEquipmentId(PsseEquipmentType equipmentType, int bus } static String getNodeBreakerEquipmentId(PsseEquipmentType equipmentType, int busI, int busJ, String id) { - List sortedBuses = List.of(busI, busJ).stream().sorted().toList(); + List sortedBuses = Stream.of(busI, busJ).sorted().toList(); int bus1 = sortedBuses.get(0); int bus2 = sortedBuses.get(1); return equipmentType.getTextCode() + "." + bus1 + "." + bus2 + "." + id; } static String getNodeBreakerEquipmentId(PsseEquipmentType equipmentType, int busI, int busJ, int busK, String id) { - List sortedBuses = List.of(busI, busJ, busK).stream().sorted().toList(); + List sortedBuses = Stream.of(busI, busJ, busK).sorted().toList(); int bus1 = sortedBuses.get(0); int bus2 = sortedBuses.get(1); int bus3 = sortedBuses.get(2); return equipmentType.getTextCode() + "." + bus1 + "." + bus2 + "." + bus3 + "." + id; } - static int obtainBus(NodeBreakerExport nodeBreakerExport, String equipmentId, int bus) { - return nodeBreakerExport.getEquipmentIdBusBus(getNodeBreakerEquipmentIdBus(equipmentId, bus)).orElseGet(() -> bus); + static Terminal findTerminalNode(Network network, String voltageLevelId, int node) { + VoltageLevel voltageLevel = network.getVoltageLevel(voltageLevelId); + return voltageLevel != null ? findTerminalNode(voltageLevel, node) : null; } - // the psse control node always is identical to the iidm node (not affected by internal connections) - static int obtainRegulatingBus(NodeBreakerExport nodeBreakerExport, Terminal regulatingTerminal, int bus) { - if (regulatingTerminal == null) { - return bus; - } - if (regulatingTerminal.getVoltageLevel().getTopologyKind().equals(TopologyKind.BUS_BREAKER)) { - return bus; + static Terminal findTerminalNode(VoltageLevel voltageLevel, int node) { + return voltageLevel.getNodeBreakerView().getOptionalTerminal(node) + .orElseGet(() -> Networks.getEquivalentTerminal(voltageLevel, node)); + } + + static Bus getTerminalBus(Terminal terminal) { + return terminal.getBusView().getBus() != null ? terminal.getBusView().getBus() : terminal.getBusView().getConnectableBus(); + } + + static int getTerminalBusI(Terminal terminal, ContextExport contextExport) { + if (terminal.getVoltageLevel().getTopologyKind().equals(TopologyKind.NODE_BREAKER)) { + int node = terminal.getNodeBreakerView().getNode(); + return contextExport.getNodeBreakerExport().getNodeBusI(terminal.getVoltageLevel(), node).orElseThrow(); + } else { + Bus bus = getTerminalBus(terminal); + return contextExport.getBusBreakerExport().getBusBusI(bus.getId()).orElseThrow(); } - String voltageLevelId = regulatingTerminal.getVoltageLevel().getId(); - int node = regulatingTerminal.getNodeBreakerView().getNode(); - return nodeBreakerExport.getNodeBus(voltageLevelId, node).orElseGet(() -> bus); } - static Terminal obtainTerminalNode(Network network, String voltageLevelId, int node) { - VoltageLevel voltageLevel = network.getVoltageLevel(voltageLevelId); - return voltageLevel != null ? obtainTerminalNode(voltageLevel, node) : null; + static int getRegulatingTerminalBusI(Terminal regulatingTerminal, int busI, int previousRegulatingBusI, ContextExport contextExport) { + int regulatingBusI = getRegulatingTerminalBusI(regulatingTerminal, contextExport); + return busI == regulatingBusI && previousRegulatingBusI == 0 ? previousRegulatingBusI : regulatingBusI; } - static Terminal obtainTerminalNode(VoltageLevel voltageLevel, int node) { - return voltageLevel.getNodeBreakerView().getOptionalTerminal(node) - .orElseGet(() -> Networks.getEquivalentTerminal(voltageLevel, node)); + static int getRegulatingTerminalBusI(Terminal regulatingTerminal, ContextExport contextExport) { + if (regulatingTerminal == null) { + return 0; + } else { + return getTerminalBusI(regulatingTerminal, contextExport); + } + } + + static int getStatus(Terminal terminal) { + return terminal.isConnected() && terminal.getBusView().getBus() != null ? 1 : 0; } static Complex impedanceToEngineeringUnits(Complex impedance, double vnom, double sbase) { @@ -177,6 +361,14 @@ static double shuntAdmittanceToPower(double shuntAdmittance, double vnom) { return shuntAdmittance * vnom * vnom; } + static double getVm(Bus bus) { + return bus != null && Double.isFinite(bus.getV()) && bus.getV() > 0.0 ? bus.getV() / bus.getVoltageLevel().getNominalV() : 1.0; + } + + static double getVa(Bus bus) { + return bus != null && Double.isFinite(bus.getAngle()) ? bus.getAngle() : 0.0; + } + private final ContainersMapping containersMapping; private final Network network; } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java index c79d03eec75..59d37605f62 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java @@ -47,53 +47,80 @@ void create(VoltageLevel voltageLevel) { .setAngle(psseBus.getVa()); } - // At the moment we only consider new buses created by opening switches in nodeBreaker substations - static void updateBuses(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { + static void updateAndCreateBuses(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { Map busNumToPsseBus = new HashMap<>(); + psseModel.getBuses().forEach(psseBus -> busNumToPsseBus.put(psseBus.getI(), psseBus)); - psseModel.getBuses().forEach(psseBus -> { - - String busId = nodeBreakerExport.getBusBreakerBusId(psseBus.getI()).orElseGet(() -> AbstractConverter.getBusId(psseBus.getI())); - int type = nodeBreakerExport.getBusType(psseBus.getI()).orElseGet(psseBus::getIde); - - updatePsseBus(network, busId, psseBus, type); - - busNumToPsseBus.put(psseBus.getI(), psseBus); + contextExport.getBusBreakerExport().getBuses().forEach(busViewBusId -> { + int busI = contextExport.getBusBreakerExport().getBusBusI(busViewBusId).orElseThrow(); + int type = contextExport.getBusBreakerExport().getBusType(busViewBusId).orElseThrow(); + updateAndCreateBus(network, busViewBusId, busI, type, null, psseModel, busNumToPsseBus); }); - // create new psse buses - List addedBuses = new ArrayList<>(); - nodeBreakerExport.getNewMappedBusesSet().stream().sorted().forEach(newBus -> { - int copyBus = nodeBreakerExport.getNewMappedBusCopyBus(newBus).orElseThrow(); - String busBreakerId = nodeBreakerExport.getNewMappedBusBusBreakerId(newBus).orElse(null); - int type = nodeBreakerExport.getNewMappedBusType(newBus).orElseThrow(); + contextExport.getNodeBreakerExport().getBuses().forEach(busViewBusId -> { + int busI = contextExport.getNodeBreakerExport().getBusBusI(busViewBusId).orElseThrow(); + Integer busCopy = contextExport.getNodeBreakerExport().getBusBusCopy(busViewBusId).orElse(null); + int type = contextExport.getNodeBreakerExport().getBusType(busViewBusId).orElseThrow(); + updateAndCreateBus(network, busViewBusId, busI, type, busCopy, psseModel, busNumToPsseBus); + }); - PsseBus psseBus = createNewBus(copyBus, newBus, busNumToPsseBus); - updatePsseBus(network, busBreakerId, psseBus, type); - addedBuses.add(psseBus); + contextExport.getNodeBreakerExport().getIsolatedBusesI().forEach(busI -> { + VoltageLevel voltageLevel = contextExport.getNodeBreakerExport().getIsolatedBusIVoltageLevel(busI).orElseThrow(); + Integer busCopy = contextExport.getNodeBreakerExport().getIsolatedBusIBusCopy(busI).orElse(null); + createIsolatedBus(voltageLevel, busI, busCopy, psseModel, busNumToPsseBus); }); - nodeBreakerExport.getNewNotMappedBusesSet().stream().sorted().forEach(newBus -> { - int copyBus = nodeBreakerExport.getNewNotMappedBusCopyBus(newBus).orElseThrow(); + psseModel.replaceAllBuses(psseModel.getBuses().stream().sorted(Comparator.comparingInt(PsseBus::getI)).toList()); + } + + private static void updateAndCreateBus(Network network, String busViewBusId, int busI, int type, Integer busCopy, PssePowerFlowModel psseModel, Map busNumToPsseBus) { + if (busNumToPsseBus.containsKey(busI)) { + PsseBus psseBus = busNumToPsseBus.get(busI); + updatePsseBus(network, busViewBusId, type, psseBus); + } else if (busCopy != null) { + PsseBus psseBus = createNewBusFromCopy(busCopy, busI, busNumToPsseBus); + updatePsseBus(network, busViewBusId, type, psseBus); + psseModel.addBuses(Collections.singletonList(psseBus)); + } else { + Bus bus = Objects.requireNonNull(network.getBusView().getBus(busViewBusId)); + psseModel.addBuses(Collections.singletonList(createNewBus(bus, busI, type))); + } + } - PsseBus psseBus = createNewBus(copyBus, newBus, busNumToPsseBus); + private static void createIsolatedBus(VoltageLevel voltageLevel, int busI, Integer busCopy, PssePowerFlowModel psseModel, Map busNumToPsseBus) { + if (busNumToPsseBus.containsKey(busI)) { + PsseBus psseBus = busNumToPsseBus.get(busI); updateIsolatedPsseBus(psseBus); - addedBuses.add(psseBus); - }); + } else if (busCopy != null) { + PsseBus psseBus = createNewBusFromCopy(busCopy, busI, busNumToPsseBus); + updateIsolatedPsseBus(psseBus); + psseModel.addBuses(Collections.singletonList(psseBus)); + } else { + psseModel.addBuses(Collections.singletonList(createNewIsolatedBus(voltageLevel, busI))); + } + } - psseModel.addBuses(addedBuses.stream().sorted(Comparator.comparingInt(PsseBus::getI)).toList()); + private static void updatePsseBus(Network network, String busViewBusId, int type, PsseBus psseBus) { + Bus bus = network.getBusView().getBus(busViewBusId); + if (bus == null) { + updateIsolatedPsseBus(psseBus); + } else { + psseBus.setVm(getVm(bus)); + psseBus.setVa(getVa(bus)); + psseBus.setIde(type); + } } - private static PsseBus createNewBus(int copyBus, int newBus, Map busNumToPsseBus) { - PsseBus psseBusToBeCopied = obtainPsseBus(copyBus, busNumToPsseBus); + private static PsseBus createNewBusFromCopy(int copyBus, int newBus, Map busNumToPsseBus) { + PsseBus psseBusToBeCopied = findPsseBus(copyBus, busNumToPsseBus); PsseBus psseBus = psseBusToBeCopied.copy(); psseBus.setI(newBus); - psseBus.setName(obtainNewBusName(psseBus.getName().trim(), "-" + newBus)); + psseBus.setName(findNewBusName(psseBus.getName().trim(), "-" + newBus)); return psseBus; } // new bus name is obtained by adding "-" + newBus, but MAX_BUS_LENGTH must be ensured - private static String obtainNewBusName(String baseName, String tag) { + private static String findNewBusName(String baseName, String tag) { int newLength = baseName.length() + tag.length(); if (newLength < MAX_BUS_LENGTH) { return StringUtils.rightPad(baseName + tag, MAX_BUS_LENGTH, " "); @@ -104,7 +131,7 @@ private static String obtainNewBusName(String baseName, String tag) { } } - private static PsseBus obtainPsseBus(int bus, Map busNumToPsseBus) { + private static PsseBus findPsseBus(int bus, Map busNumToPsseBus) { if (busNumToPsseBus.containsKey(bus)) { return busNumToPsseBus.get(bus); } else { @@ -112,29 +139,33 @@ private static PsseBus obtainPsseBus(int bus, Map busNumToPsse } } - private static void updatePsseBus(Network network, String busBreakerId, PsseBus psseBus, int type) { - Bus bus = network.getBusBreakerView().getBus(busBreakerId); - if (bus == null) { - updateIsolatedPsseBus(psseBus); - } else { - psseBus.setVm(getVm(bus)); - psseBus.setVa(getVa(bus)); - psseBus.setIde(type); - } - } - private static void updateIsolatedPsseBus(PsseBus psseBus) { psseBus.setVm(0.0); psseBus.setVa(0.0); psseBus.setIde(4); } - private static double getVm(Bus bus) { - return Double.isFinite(bus.getV()) && bus.getV() > 0.0 ? bus.getV() / bus.getVoltageLevel().getNominalV() : 1.0; + private static PsseBus createNewBus(Bus bus, int busI, int type) { + PsseBus psseBus = new PsseBus(); + psseBus.setI(busI); + psseBus.setName(bus.getNameOrId()); + psseBus.setBaskv(bus.getVoltageLevel().getNominalV()); + psseBus.setIde(type); + psseBus.setVm(getVm(bus)); + psseBus.setVa(getVa(bus)); + + return psseBus; } - private static double getVa(Bus bus) { - return Double.isFinite(bus.getAngle()) ? bus.getAngle() : 0.0; + private static PsseBus createNewIsolatedBus(VoltageLevel voltageLevel, int busI) { + PsseBus psseBus = new PsseBus(); + psseBus.setI(busI); + psseBus.setName(voltageLevel.getId() + "-" + busI); + psseBus.setBaskv(voltageLevel.getNominalV()); + + updateIsolatedPsseBus(psseBus); + + return psseBus; } private final PsseBus psseBus; diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/ContextExport.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/ContextExport.java new file mode 100644 index 00000000000..9dd70ebeeb6 --- /dev/null +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/ContextExport.java @@ -0,0 +1,299 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.psse.converter; + +import com.powsybl.iidm.network.Identifiable; +import com.powsybl.iidm.network.IdentifiableType; +import com.powsybl.iidm.network.VoltageLevel; +import com.powsybl.psse.model.PsseException; +import com.powsybl.psse.model.pf.PsseSubstation; + +import java.util.*; +import java.util.stream.Stream; + +/** + * @author Luma Zamarreño {@literal } + * @author José Antonio Marqués {@literal } + */ +final class ContextExport { + private int maxPsseBus; + private final BusBreakerExport busBreakerExport; + private final NodeBreakerExport nodeBreakerExport; + private final Map> equipmentTerminalData; + private final Map equipmentCkt; + private final Map> equipmentAllCkt; + + ContextExport(int maxPsseBus) { + this.maxPsseBus = maxPsseBus; + this.busBreakerExport = new BusBreakerExport(); + this.nodeBreakerExport = new NodeBreakerExport(); + this.equipmentTerminalData = new HashMap<>(); + this.equipmentCkt = new HashMap<>(); + this.equipmentAllCkt = new HashMap<>(); + } + + int getNewPsseBusI() { + return ++maxPsseBus; + } + + BusBreakerExport getBusBreakerExport() { + return this.busBreakerExport; + } + + NodeBreakerExport getNodeBreakerExport() { + return this.nodeBreakerExport; + } + + boolean isFreePsseBusI(int busI) { + return busBreakerExport.isFreePsseBusId(busI) && nodeBreakerExport.isFreePsseBusId(busI); + } + + void addEquipmentEnd(String equipmentId, VoltageLevel voltageLevel, int node, int busI, int end) { + equipmentTerminalData.computeIfAbsent(equipmentId, k -> new ArrayList<>()).add(new EqR(voltageLevel, node, busI, end)); + } + + void addEquipmentEnd(String equipmentId, VoltageLevel voltageLevel, int busI, int end) { + equipmentTerminalData.computeIfAbsent(equipmentId, k -> new ArrayList<>()).add(new EqR(voltageLevel, null, busI, end)); + } + + List getEquipmentBusesList(String equipmentId, VoltageLevel voltageLevel, int node) { + List busesList = new ArrayList<>(); + if (equipmentTerminalData.containsKey(equipmentId)) { + int bus = equipmentTerminalData.get(equipmentId).stream().filter(eqR -> eqR.voltageLevel.equals(voltageLevel) && eqR.node == node).map(eqR -> eqR.busI).findFirst().orElseThrow(); + busesList.add(bus); + addToBusList(busesList, bus, equipmentTerminalData.get(equipmentId).stream().filter(eqR -> eqR.end == 1).map(eqR -> eqR.busI).findFirst().orElse(0)); + addToBusList(busesList, bus, equipmentTerminalData.get(equipmentId).stream().filter(eqR -> eqR.end == 2).map(eqR -> eqR.busI).findFirst().orElse(0)); + addToBusList(busesList, bus, equipmentTerminalData.get(equipmentId).stream().filter(eqR -> eqR.end == 3).map(eqR -> eqR.busI).findFirst().orElse(0)); + } + return busesList; + } + + private static void addToBusList(List busList, int bus, int busEnd) { + if (bus != busEnd) { + busList.add(busEnd); + } + } + + String getEquipmentCkt(String equipmentId, IdentifiableType type, int busI, int busJ, int busK) { + if (equipmentCkt.containsKey(equipmentId)) { + return equipmentCkt.get(equipmentId); + } + String equipmentBusesId = getEquipmentBusesId(equipmentId, type.name(), busI, busJ, busK); + Optional optCkt = AbstractConverter.extractCkt(equipmentId, type); + if (optCkt.isPresent() && cktIsFree(equipmentBusesId, optCkt.get())) { + addCkt(equipmentId, equipmentBusesId, optCkt.get()); + return optCkt.get(); + } + String ckt = getNewCkt(equipmentBusesId); + addCkt(equipmentId, equipmentBusesId, ckt); + return ckt; + } + + private boolean cktIsFree(String equipmentBusesId, String ckt) { + if (equipmentAllCkt.containsKey(equipmentBusesId)) { + return !equipmentAllCkt.get(equipmentBusesId).contains(ckt); + } else { + return true; + } + } + + private void addCkt(String equipmentId, String equipmentBusesId, String ckt) { + equipmentAllCkt.computeIfAbsent(equipmentBusesId, k -> new ArrayList<>()).add(ckt); + equipmentCkt.put(equipmentId, ckt); + } + + private String getNewCkt(String equipmentBusesId) { + for (int i = 1; i <= 99; i++) { + String ckt = String.format("%02d", i); + if (cktIsFree(equipmentBusesId, ckt)) { + return ckt; + } + } + throw new PsseException("unable to obtain a ckt for " + equipmentBusesId); + } + + private static String getEquipmentBusesId(String equipmentId, String type, int busI, int busJ, int busK) { + List sortedBuses = Stream.of(busI, busJ, busK).filter(bus -> bus != 0).sorted().toList(); + if (sortedBuses.size() == 1) { + return type + "-" + sortedBuses.get(0); + } else if (sortedBuses.size() == 2) { + return type + "-" + sortedBuses.get(0) + "-" + sortedBuses.get(1); + } else if (sortedBuses.size() == 3) { + return type + "-" + sortedBuses.get(0) + "-" + sortedBuses.get(1) + "-" + sortedBuses.get(2); + } else { + throw new PsseException("All the buses are zero. EquipmentId: " + equipmentId); + } + } + + static class BusBreakerExport { + private final Map buses; + private final Set usedPsseBusI; + + BusBreakerExport() { + this.buses = new HashMap<>(); + this.usedPsseBusI = new HashSet<>(); + } + + void addBus(String busViewId, int busI, int type) { + buses.put(busViewId, new BusR(busI, type)); + usedPsseBusI.add(busI); + } + + List getBuses() { + return buses.keySet().stream().sorted().toList(); + } + + OptionalInt getBusBusI(String busViewId) { + return buses.containsKey(busViewId) ? OptionalInt.of(buses.get(busViewId).busI) : OptionalInt.empty(); + } + + OptionalInt getBusType(String busViewId) { + return buses.containsKey(busViewId) ? OptionalInt.of(buses.get(busViewId).type) : OptionalInt.empty(); + } + + private boolean isFreePsseBusId(int busI) { + return !usedPsseBusI.contains(busI); + } + + private record BusR(int busI, int type) { + } + } + + static class NodeBreakerExport { + private final Map voltageLevels; + private final Map nodes; + private final Map buses; + private final Map isolatedBusesI; + private final Set usedPsseBusI; + private final Map selectedNodes; + + NodeBreakerExport() { + this.voltageLevels = new HashMap<>(); + this.nodes = new HashMap<>(); + this.buses = new HashMap<>(); + this.isolatedBusesI = new HashMap<>(); + this.usedPsseBusI = new HashSet<>(); + this.selectedNodes = new HashMap<>(); + } + + void addVoltageLevels(List voltageLevels) { + voltageLevels.forEach(voltageLevel -> this.voltageLevels.put(voltageLevel, null)); + } + + void addVoltageLevel(VoltageLevel voltageLevel, PsseSubstation psseSubstation) { + voltageLevels.put(voltageLevel, psseSubstation); + } + + List getVoltageLevels() { + return voltageLevels.keySet().stream().sorted(Comparator.comparing(Identifiable::getId)).toList(); + } + + Optional getPsseSubstationMappedToVoltageLevel(VoltageLevel voltageLevel) { + return Optional.ofNullable(voltageLevels.get(voltageLevel)); + } + + void addNodes(String busViewBusId, VoltageLevel voltageLevel, List nodes, int busI, Integer busCopy, int type) { + nodes.forEach(node -> this.nodes.put(getNodeId(voltageLevel, node), new NodeR(voltageLevel, node, busI, isInService(type), busViewBusId))); + buses.put(busViewBusId, new BusR(busI, busCopy, type)); + usedPsseBusI.add(busI); + } + + void addIsolatedNode(VoltageLevel voltageLevel, int node, int busI, Integer busCopy) { + nodes.put(getNodeId(voltageLevel, node), new NodeR(voltageLevel, node, busI, false, null)); + isolatedBusesI.put(busI, new BusIR(voltageLevel, busCopy)); + usedPsseBusI.add(busI); + } + + void addNodes(String busViewBusId, VoltageLevel voltageLevel, List nodes, int busI, int type) { + nodes.forEach(node -> this.nodes.put(getNodeId(voltageLevel, node), new NodeR(voltageLevel, node, busI, isInService(type), busViewBusId))); + buses.put(busViewBusId, new BusR(busI, null, type)); + usedPsseBusI.add(busI); + } + + void addIsolatedNode(VoltageLevel voltageLevel, int node, int busI) { + nodes.put(getNodeId(voltageLevel, node), new NodeR(voltageLevel, node, busI, false, null)); + isolatedBusesI.put(busI, new BusIR(voltageLevel, null)); + usedPsseBusI.add(busI); + } + + List getBuses() { + return buses.keySet().stream().sorted().toList(); + } + + OptionalInt getBusBusI(String busViewId) { + return buses.containsKey(busViewId) ? OptionalInt.of(buses.get(busViewId).busI) : OptionalInt.empty(); + } + + Optional getBusBusCopy(String busViewId) { + return buses.containsKey(busViewId) ? Optional.ofNullable(buses.get(busViewId).busCopy) : Optional.empty(); + } + + OptionalInt getBusType(String busViewId) { + return buses.containsKey(busViewId) ? OptionalInt.of(buses.get(busViewId).type) : OptionalInt.empty(); + } + + OptionalInt getNodeBusI(VoltageLevel voltageLevel, int node) { + return nodes.containsKey(getNodeId(voltageLevel, node)) ? OptionalInt.of(nodes.get(getNodeId(voltageLevel, node)).busI) : OptionalInt.empty(); + } + + Optional isNodeInService(VoltageLevel voltageLevel, int node) { + return nodes.containsKey(getNodeId(voltageLevel, node)) ? Optional.of(nodes.get(getNodeId(voltageLevel, node)).isInService) : Optional.empty(); + } + + List getIsolatedBusesI() { + return isolatedBusesI.keySet().stream().sorted().toList(); + } + + Optional getIsolatedBusIVoltageLevel(int busI) { + return isolatedBusesI.containsKey(busI) ? Optional.of(isolatedBusesI.get(busI).voltageLevel) : Optional.empty(); + } + + Optional getIsolatedBusIBusCopy(int busI) { + return isolatedBusesI.containsKey(busI) ? Optional.ofNullable(isolatedBusesI.get(busI).busCopy) : Optional.empty(); + } + + void addSelectedNode(VoltageLevel voltageLevel, Set nodes, int selectedNode) { + nodes.forEach(node -> selectedNodes.put(getNodeId(voltageLevel, node), new SelectedNodeR(voltageLevel, selectedNode))); + } + + List getSelectedNodes(VoltageLevel voltageLevel) { + return new HashSet<>(selectedNodes.values()).stream().filter(value -> value.voltageLevel.equals(voltageLevel)).map(value -> value.node).sorted().toList(); + } + + OptionalInt getSelectedNode(VoltageLevel voltageLevel, int node) { + return selectedNodes.containsKey(getNodeId(voltageLevel, node)) ? OptionalInt.of(selectedNodes.get(getNodeId(voltageLevel, node)).node) : OptionalInt.empty(); + } + + private static boolean isInService(int type) { + return type != 4; + } + + private static String getNodeId(VoltageLevel voltageLevel, int node) { + return voltageLevel.getId() + "-" + node; + } + + private boolean isFreePsseBusId(int busI) { + return !usedPsseBusI.contains(busI); + } + + private record SelectedNodeR(VoltageLevel voltageLevel, int node) { + } + + private record NodeR(VoltageLevel voltageLevel, int node, int busI, boolean isInService, String busViewBusId) { + } + + private record BusR(int busI, Integer busCopy, int type) { + } + + private record BusIR(VoltageLevel voltageLevel, Integer busCopy) { + } + } + + private record EqR(VoltageLevel voltageLevel, Integer node, int busI, int end) { + } +} diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java index a9d9f9b3561..60e078c3251 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java @@ -38,11 +38,10 @@ void create() { return; } - String busId = getBusId(psseFixedShunt.getI()); VoltageLevel voltageLevel = getNetwork() .getVoltageLevel(getContainersMapping().getVoltageLevelId(psseFixedShunt.getI())); ShuntCompensatorAdder adder = voltageLevel.newShuntCompensator() - .setId(getShuntId(busId)) + .setId(getFixedShuntId(psseFixedShunt.getI(), psseFixedShunt.getId())) .setVoltageRegulatorOn(false) .setSectionCount(1); adder.newLinearModel() @@ -56,6 +55,7 @@ void create() { if (node.isPresent()) { adder.setNode(node.getAsInt()); } else { + String busId = getBusId(psseFixedShunt.getI()); adder.setConnectableBus(busId); adder.setBus(psseFixedShunt.getStatus() == 1 ? busId : null); } @@ -63,20 +63,12 @@ void create() { adder.add(); } - private String getShuntId(String busId) { - return getShuntId(busId, psseFixedShunt.getId()); - } - - private static String getShuntId(String busId, String fixedShuntId) { - return busId + "-SH" + fixedShuntId; - } - // At the moment we do not consider new fixedShunts - static void updateFixedShunts(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { + static void updateFixedShunts(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { psseModel.getFixedShunts().forEach(psseFixedShunt -> { - String fixedShuntId = getShuntId(getBusId(psseFixedShunt.getI()), psseFixedShunt.getId()); + String fixedShuntId = getFixedShuntId(psseFixedShunt.getI(), psseFixedShunt.getId()); ShuntCompensator fixedShunt = network.getShuntCompensator(fixedShuntId); - int bus = obtainBus(nodeBreakerExport, getNodeBreakerEquipmentId(PSSE_FIXED_SHUNT, psseFixedShunt.getI(), psseFixedShunt.getId()), psseFixedShunt.getI()); + int bus = getTerminalBusI(fixedShunt.getTerminal(), contextExport); if (fixedShunt == null) { psseFixedShunt.setStatus(0); diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java index ff3406b496f..395af5e4e51 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java @@ -41,10 +41,9 @@ class GeneratorConverter extends AbstractConverter { } void create() { - String busId = getBusId(psseGenerator.getI()); VoltageLevel voltageLevel = getNetwork().getVoltageLevel(getContainersMapping().getVoltageLevelId(psseGenerator.getI())); GeneratorAdder adder = voltageLevel.newGenerator() - .setId(getGeneratorId(busId, psseGenerator)) + .setId(getGeneratorId(psseGenerator.getI(), psseGenerator.getId())) .setTargetP(psseGenerator.getPg()) .setMaxP(psseGenerator.getPt()) .setMinP(psseGenerator.getPb()) @@ -56,6 +55,7 @@ void create() { if (node.isPresent()) { adder.setNode(node.getAsInt()); } else { + String busId = getBusId(psseGenerator.getI()); adder.setConnectableBus(busId); adder.setBus(psseGenerator.getStat() == 1 ? busId : null); } @@ -73,8 +73,7 @@ void create() { } void addControl(PsseBus psseBus) { - String busId = getBusId(psseGenerator.getI()); - Generator generator = getNetwork().getGenerator(getGeneratorId(busId, psseGenerator)); + Generator generator = getNetwork().getGenerator(getGeneratorId(psseGenerator.getI(), psseGenerator.getId())); // Add control only if generator has been created if (generator == null) { @@ -111,7 +110,7 @@ private static Terminal defineRegulatingTerminal(PsseGenerator psseGenerator, Ne String equipmentId = getNodeBreakerEquipmentId(PSSE_GENERATOR, psseGenerator.getI(), psseGenerator.getId()); Optional controlNode = nodeBreakerImport.getControlNode(getNodeBreakerEquipmentIdBus(equipmentId, psseGenerator.getIreg())); if (controlNode.isPresent()) { - regulatingTerminal = obtainTerminalNode(network, controlNode.get().getVoltageLevelId(), controlNode.get().getNode()); + regulatingTerminal = findTerminalNode(network, controlNode.get().getVoltageLevelId(), controlNode.get().getNode()); } else { String regulatingBusId = getBusId(psseGenerator.getIreg()); Bus bus = network.getBusBreakerView().getBus(regulatingBusId); @@ -121,27 +120,19 @@ private static Terminal defineRegulatingTerminal(PsseGenerator psseGenerator, Ne } } if (regulatingTerminal == null) { - String generatorId = getGeneratorId(getBusId(psseGenerator.getI()), psseGenerator.getId()); + String generatorId = getGeneratorId(psseGenerator.getI(), psseGenerator.getId()); LOGGER.warn("Generator {}. Regulating terminal is not assigned as the bus is isolated", generatorId); } return regulatingTerminal; } - private static String getGeneratorId(String busId, PsseGenerator psseGenerator) { - return getGeneratorId(busId, psseGenerator.getId()); - } - - private static String getGeneratorId(String busId, String generatorId) { - return busId + "-G" + generatorId; - } - // At the moment we do not consider new generators - static void updateGenerators(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { + static void updateGenerators(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { psseModel.getGenerators().forEach(psseGen -> { - String genId = getGeneratorId(getBusId(psseGen.getI()), psseGen.getId()); + String genId = getGeneratorId(psseGen.getI(), psseGen.getId()); Generator gen = network.getGenerator(genId); - int bus = obtainBus(nodeBreakerExport, getNodeBreakerEquipmentId(PSSE_GENERATOR, psseGen.getI(), psseGen.getId()), psseGen.getI()); - int regulatingBus = obtainRegulatingBus(nodeBreakerExport, gen.getRegulatingTerminal(), psseGen.getIreg()); + int bus = getTerminalBusI(gen.getTerminal(), contextExport); + int regulatingBus = getRegulatingTerminalBusI(gen.getRegulatingTerminal(), bus, psseGen.getIreg(), contextExport); if (gen == null) { psseGen.setStat(0); diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java index 445604989f0..e266fa7f377 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java @@ -43,7 +43,7 @@ class LineConverter extends AbstractConverter { } void create() { - String id = getLineId(); + String id = getLineId(psseLine.getI(), psseLine.getJ(), psseLine.getCkt()); String bus1Id = getBusId(psseLine.getI()); String bus2Id = getBusId(psseLine.getJ()); @@ -123,22 +123,13 @@ private void defineOperationalLimits(Line line, double vnom1, double vnom2) { } } - private String getLineId() { - return getLineId(psseLine); - } - - private static String getLineId(PsseNonTransformerBranch psseLine) { - return "L-" + psseLine.getI() + "-" + psseLine.getJ() + "-" + psseLine.getCkt(); - } - // At the moment we do not consider new lines and antenna lines are exported as open - static void updateLines(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { + static void updateLines(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { psseModel.getNonTransformerBranches().forEach(psseLine -> { - String lineId = getLineId(psseLine); + String lineId = getLineId(psseLine.getI(), psseLine.getJ(), psseLine.getCkt()); Line line = network.getLine(lineId); - String equipmentId = getNodeBreakerEquipmentId(PSSE_BRANCH, psseLine.getI(), psseLine.getJ(), psseLine.getCkt()); - int busI = obtainBus(nodeBreakerExport, equipmentId, psseLine.getI()); - int busJ = obtainBus(nodeBreakerExport, equipmentId, psseLine.getJ()); + int busI = getTerminalBusI(line.getTerminal1(), contextExport); + int busJ = getTerminalBusI(line.getTerminal2(), contextExport); if (line == null) { psseLine.setSt(0); diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java index 0edb6ec34b9..e35d80022a9 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java @@ -7,8 +7,7 @@ */ package com.powsybl.psse.converter; -import java.util.Objects; -import java.util.OptionalInt; +import java.util.*; import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.util.ContainersMapping; @@ -31,7 +30,6 @@ class LoadConverter extends AbstractConverter { void create() { - String busId = getBusId(psseLoad.getI()); VoltageLevel voltageLevel = getNetwork() .getVoltageLevel(getContainersMapping().getVoltageLevelId(psseLoad.getI())); @@ -39,7 +37,7 @@ void create() { double q0 = psseLoad.getQl() + psseLoad.getIq() + psseLoad.getYq(); LoadAdder adder = voltageLevel.newLoad() - .setId(getLoadId(busId)) + .setId(getLoadId(psseLoad.getI(), psseLoad.getId())) .setP0(p0) .setQ0(q0); @@ -85,6 +83,7 @@ void create() { if (node.isPresent()) { adder.setNode(node.getAsInt()); } else { + String busId = getBusId(psseLoad.getI()); adder.setConnectableBus(busId); adder.setBus(psseLoad.getStatus() == 1 ? busId : null); } @@ -92,38 +91,24 @@ void create() { adder.add(); } - private String getLoadId(String busId) { - return getLoadId(busId, psseLoad.getId()); - } - - private static String getLoadId(String busId, String loadId) { - return busId + "-L" + loadId; - } - - // At the moment we do not consider new loads - static void updateLoads(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { + static void updateLoads(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { psseModel.getLoads().forEach(psseLoad -> { - String loadId = getLoadId(getBusId(psseLoad.getI()), psseLoad.getId()); + String loadId = getLoadId(psseLoad.getI(), psseLoad.getId()); Load load = network.getLoad(loadId); - int bus = obtainBus(nodeBreakerExport, getNodeBreakerEquipmentId(PSSE_LOAD, psseLoad.getI(), psseLoad.getId()), psseLoad.getI()); - if (load == null) { psseLoad.setStatus(0); } else { - psseLoad.setStatus(getStatus(load)); - psseLoad.setPl(getP(load)); - psseLoad.setQl(getQ(load)); + updateLoad(load, psseLoad, contextExport); } - psseLoad.setI(bus); }); } - private static int getStatus(Load load) { - if (load.getTerminal().isConnected() && load.getTerminal().getBusBreakerView().getBus() != null) { - return 1; - } else { - return 0; - } + private static void updateLoad(Load load, PsseLoad psseLoad, ContextExport contextExport) { + int bus = getTerminalBusI(load.getTerminal(), contextExport); + psseLoad.setStatus(getStatus(load.getTerminal())); + psseLoad.setPl(getP(load)); + psseLoad.setQl(getQ(load)); + psseLoad.setI(bus); } private static double getP(Load load) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerExport.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerExport.java deleted file mode 100644 index 40a1d4dc9bd..00000000000 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerExport.java +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Copyright (c) 2024, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * SPDX-License-Identifier: MPL-2.0 - */ -package com.powsybl.psse.converter; - -import org.jgrapht.alg.util.Pair; - -import java.util.*; - -/** - * @author Luma Zamarreño {@literal } - * @author José Antonio Marqués {@literal } - */ -final class NodeBreakerExport { - private int maxPsseBus; - private final Map newMappedBuses; // New buses mapped to iidm buses - private final Map newNotMappedBuses; // New buses not mapped to iidm buses - private final Map> buses; - private final Set isolatedBuses; - private final Map> nodeBus; - private final Map equipmentIdBusBus; - - NodeBreakerExport(int maxPsseBus) { - this.maxPsseBus = maxPsseBus; - this.newMappedBuses = new HashMap<>(); - this.newNotMappedBuses = new HashMap<>(); - this.buses = new HashMap<>(); - this.isolatedBuses = new HashSet<>(); - this.nodeBus = new HashMap<>(); - this.equipmentIdBusBus = new HashMap<>(); - } - - int getNewPsseBus() { - return ++maxPsseBus; - } - - void addNewMappedBus(int newBus, int copyBus, String busBreakerBusId, int type) { - newMappedBuses.put(newBus, new NodeBreakerNewBus(copyBus, busBreakerBusId, type)); - } - - void addNewNotMappedBus(int newBus, int copyBus) { - newNotMappedBuses.put(newBus, copyBus); - } - - Set getNewMappedBusesSet() { - return newMappedBuses.keySet(); - } - - OptionalInt getNewMappedBusCopyBus(int newBus) { - return newMappedBuses.containsKey(newBus) ? OptionalInt.of(newMappedBuses.get(newBus).busCopy) : OptionalInt.empty(); - } - - Optional getNewMappedBusBusBreakerId(int newBus) { - // New Isolated buses do not have busBreakerId. Null is considered - return newMappedBuses.containsKey(newBus) ? Optional.ofNullable(newMappedBuses.get(newBus).busBreakerId) : Optional.empty(); - } - - OptionalInt getNewMappedBusType(int newBus) { - return newMappedBuses.containsKey(newBus) ? OptionalInt.of(newMappedBuses.get(newBus).type) : OptionalInt.empty(); - } - - Set getNewNotMappedBusesSet() { - return newNotMappedBuses.keySet(); - } - - OptionalInt getNewNotMappedBusCopyBus(int newBus) { - return newNotMappedBuses.containsKey(newBus) ? OptionalInt.of(newNotMappedBuses.get(newBus)) : OptionalInt.empty(); - } - - void addBusMapping(int bus, String busBreakerBusId, int type) { - this.buses.put(bus, Pair.of(busBreakerBusId, type)); - } - - Optional getBusBreakerBusId(int bus) { - return this.buses.containsKey(bus) ? Optional.of(this.buses.get(bus).getFirst()) : Optional.empty(); - } - - OptionalInt getBusType(int bus) { - return this.buses.containsKey(bus) ? OptionalInt.of(this.buses.get(bus).getSecond()) : OptionalInt.empty(); - } - - void addIsolatedBus(int bus) { - this.isolatedBuses.add(bus); - } - - boolean isFreeBus(int bus) { - return !(this.buses.containsKey(bus) || this.isolatedBuses.contains(bus)); - } - - void addNodesBusMapping(String voltageLevelId, List nodes, int bus, boolean inService) { - nodes.forEach(node -> addNodeBusMapping(voltageLevelId, node, bus, inService)); - } - - void addNodeBusMapping(String voltageLevelId, int node, int bus, boolean inService) { - this.nodeBus.put(getNodeId(voltageLevelId, node), Pair.of(bus, inService)); - } - - OptionalInt getNodeBus(String voltageLevelId, int node) { - return this.nodeBus.containsKey(getNodeId(voltageLevelId, node)) ? OptionalInt.of(this.nodeBus.get(getNodeId(voltageLevelId, node)).getFirst()) : OptionalInt.empty(); - } - - Optional isNodeInService(String voltageLevelId, int node) { - return this.nodeBus.containsKey(getNodeId(voltageLevelId, node)) ? Optional.of(this.nodeBus.get(getNodeId(voltageLevelId, node)).getSecond()) : Optional.empty(); - } - - boolean isFreeNode(String voltageLevelId, int node) { - return !this.nodeBus.containsKey(getNodeId(voltageLevelId, node)); - } - - private static String getNodeId(String voltageLevelId, int node) { - return voltageLevelId + "-" + node; - } - - void addEquipmentIdBus(String equipmentIdBusBus, int bus) { - this.equipmentIdBusBus.put(equipmentIdBusBus, bus); - } - - OptionalInt getEquipmentIdBusBus(String equipmentIdBusBus) { - return this.equipmentIdBusBus.containsKey(equipmentIdBusBus) ? OptionalInt.of(this.equipmentIdBusBus.get(equipmentIdBusBus)) : OptionalInt.empty(); - } - - private static final class NodeBreakerNewBus { - private final int busCopy; - private final String busBreakerId; - private final int type; - - private NodeBreakerNewBus(int busCopy, String busBreakerId, int type) { - this.busCopy = busCopy; - this.busBreakerId = busBreakerId; - this.type = type; - } - } -} diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java index 19f306f2f42..bb04708c95d 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java @@ -120,18 +120,18 @@ private static PssePowerFlowModel createUpdatePsseModel(Network network, PssePow } private static void updateModifiedBlocks(Network network, PssePowerFlowModel updatedPsseModel) { - NodeBreakerExport nodeBreakerExport = VoltageLevelConverter.mapSubstations(network, updatedPsseModel); + ContextExport contextExport = VoltageLevelConverter.createContextExport(network, updatedPsseModel); // Only after mapping all substations, the substation data can be updated - VoltageLevelConverter.updateSubstations(network, updatedPsseModel, nodeBreakerExport); - - BusConverter.updateBuses(network, updatedPsseModel, nodeBreakerExport); - LoadConverter.updateLoads(network, updatedPsseModel, nodeBreakerExport); - FixedShuntCompensatorConverter.updateFixedShunts(network, updatedPsseModel, nodeBreakerExport); - GeneratorConverter.updateGenerators(network, updatedPsseModel, nodeBreakerExport); - LineConverter.updateLines(network, updatedPsseModel, nodeBreakerExport); - TransformerConverter.updateTransformers(network, updatedPsseModel, nodeBreakerExport); - TwoTerminalDcConverter.updateTwoTerminalDcTransmissionLines(network, updatedPsseModel, nodeBreakerExport); - SwitchedShuntCompensatorConverter.updateSwitchedShunts(network, updatedPsseModel, nodeBreakerExport); + VoltageLevelConverter.updateSubstations(contextExport); + + BusConverter.updateAndCreateBuses(network, updatedPsseModel, contextExport); + LoadConverter.updateLoads(network, updatedPsseModel, contextExport); + FixedShuntCompensatorConverter.updateFixedShunts(network, updatedPsseModel, contextExport); + GeneratorConverter.updateGenerators(network, updatedPsseModel, contextExport); + LineConverter.updateLines(network, updatedPsseModel, contextExport); + TransformerConverter.updateTransformers(network, updatedPsseModel, contextExport); + TwoTerminalDcConverter.updateTwoTerminalDcTransmissionLines(network, updatedPsseModel, contextExport); + SwitchedShuntCompensatorConverter.updateSwitchedShunts(network, updatedPsseModel, contextExport); } } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SlackConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SlackConverter.java index 1629b373bf8..88af6ff9989 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SlackConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SlackConverter.java @@ -37,7 +37,7 @@ void create() { Optional slackControlNode = nodeBreakerImport.getSlackControlNode(psseBus.getI()); if (slackControlNode.isPresent()) { - Terminal terminal = obtainTerminalNode(getNetwork(), slackControlNode.get().getVoltageLevelId(), slackControlNode.get().getNode()); + Terminal terminal = findTerminalNode(getNetwork(), slackControlNode.get().getVoltageLevelId(), slackControlNode.get().getNode()); VoltageLevel voltageLevel = getNetwork().getVoltageLevel(slackControlNode.get().getVoltageLevelId()); if (voltageLevel != null && terminal != null) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java index 3cfec460589..832a6de23e5 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java @@ -40,12 +40,11 @@ void create() { return; } - String busId = getBusId(psseSwitchedShunt.getI()); String id = defineShuntId(psseSwitchedShunt, version); VoltageLevel voltageLevel = getNetwork().getVoltageLevel(getContainersMapping().getVoltageLevelId(psseSwitchedShunt.getI())); ShuntCompensatorAdder adder = voltageLevel.newShuntCompensator() - .setId(getShuntId(busId, id)) + .setId(getSwitchedShuntId(psseSwitchedShunt.getI(), id)) .setSectionCount(defineSectionCount(psseSwitchedShunt.getBinit(), shuntBlocks)); String equipmentId = getNodeBreakerEquipmentId(PSSE_SWITCHED_SHUNT, psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version)); @@ -53,6 +52,7 @@ void create() { if (node.isPresent()) { adder.setNode(node.getAsInt()); } else { + String busId = getBusId(psseSwitchedShunt.getI()); adder.setConnectableBus(busId); adder.setBus(psseSwitchedShunt.getStat() == 1 ? busId : null); } @@ -71,9 +71,8 @@ void create() { } void addControl() { - String busId = getBusId(psseSwitchedShunt.getI()); String id = defineShuntId(psseSwitchedShunt, version); - ShuntCompensator shunt = getNetwork().getShuntCompensator(getShuntId(busId, id)); + ShuntCompensator shunt = getNetwork().getShuntCompensator(getSwitchedShuntId(psseSwitchedShunt.getI(), id)); // Add control only if shunt has been created if (shunt == null) { @@ -119,7 +118,7 @@ private static Terminal defineRegulatingTerminal(PsseSwitchedShunt psseSwitchedS String equipmentId = getNodeBreakerEquipmentId(PSSE_SWITCHED_SHUNT, psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version)); Optional controlNode = nodeBreakerImport.getControlNode(getNodeBreakerEquipmentIdBus(equipmentId, switchedShuntRegulatingBus(psseSwitchedShunt, version))); if (controlNode.isPresent()) { - regulatingTerminal = obtainTerminalNode(network, controlNode.get().getVoltageLevelId(), controlNode.get().getNode()); + regulatingTerminal = findTerminalNode(network, controlNode.get().getVoltageLevelId(), controlNode.get().getNode()); } else { String regulatingBusId = getBusId(switchedShuntRegulatingBus(psseSwitchedShunt, version)); Bus bus = network.getBusBreakerView().getBus(regulatingBusId); @@ -180,15 +179,15 @@ private static List defineShuntBlocks(PsseSwitchedShunt psseSwitched psseCapacitorBlocks.sort(Comparator.comparing(ShuntBlock::getB)); LOGGER.warn("Switched combination not exactly supported ({})", - getShuntId(getBusId(psseSwitchedShunt.getI()), defineShuntId(psseSwitchedShunt, version))); + getSwitchedShuntId(psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version))); } double bAdd = 0.0; List shuntBlocks = new ArrayList<>(); if (!psseReactorBlocks.isEmpty()) { - for (int i = 0; i < psseReactorBlocks.size(); i++) { - for (int j = 0; j < psseReactorBlocks.get(i).getN(); j++) { - bAdd = bAdd + psseReactorBlocks.get(i).getB(); + for (ShuntBlock psseReactorBlock : psseReactorBlocks) { + for (int j = 0; j < psseReactorBlock.getN(); j++) { + bAdd = bAdd + psseReactorBlock.getB(); shuntBlocks.add(new ShuntBlock(1, 1, bAdd)); } } @@ -199,9 +198,9 @@ private static List defineShuntBlocks(PsseSwitchedShunt psseSwitched } if (!psseCapacitorBlocks.isEmpty()) { - for (int i = 0; i < psseCapacitorBlocks.size(); i++) { - for (int j = 0; j < psseCapacitorBlocks.get(i).getN(); j++) { - bAdd = bAdd + psseCapacitorBlocks.get(i).getB(); + for (ShuntBlock psseCapacitorBlock : psseCapacitorBlocks) { + for (int j = 0; j < psseCapacitorBlock.getN(); j++) { + bAdd = bAdd + psseCapacitorBlock.getB(); shuntBlocks.add(new ShuntBlock(1, 1, bAdd)); } } @@ -280,18 +279,14 @@ private static String defineShuntId(PsseSwitchedShunt psseSwitchedShunt, PsseVer } } - private static String getShuntId(String busId, String id) { - return busId + "-SwSH" + id; - } - // At the moment we do not consider new switchedShunts - static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { + static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { PsseVersion version = PsseVersion.fromRevision(psseModel.getCaseIdentification().getRev()); psseModel.getSwitchedShunts().forEach(psseSwitchedShunt -> { - String switchedShuntId = getShuntId(getBusId(psseSwitchedShunt.getI()), defineShuntId(psseSwitchedShunt, version)); + String switchedShuntId = getSwitchedShuntId(psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version)); ShuntCompensator switchedShunt = network.getShuntCompensator(switchedShuntId); - int bus = obtainBus(nodeBreakerExport, getNodeBreakerEquipmentId(PSSE_SWITCHED_SHUNT, psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version)), psseSwitchedShunt.getI()); - int regulatingBus = obtainRegulatingBus(nodeBreakerExport, switchedShunt.getRegulatingTerminal(), switchedShuntRegulatingBus(psseSwitchedShunt, version)); + int bus = getTerminalBusI(switchedShunt.getTerminal(), contextExport); + int regulatingBus = getRegulatingTerminalBusI(switchedShunt.getRegulatingTerminal(), bus, switchedShuntRegulatingBus(psseSwitchedShunt, version), contextExport); if (switchedShunt == null) { psseSwitchedShunt.setStat(0); } else { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java index 1836ab21d84..5b9bbee274e 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java @@ -96,7 +96,7 @@ private void createTwoWindingsTransformer() { // move ysh between w1 and z // Ysh_eu = Ysh_pu * sbase / (vn1 *vn1) Convert Ysh per unit to engineering units // Ysh_eu_moved = Ysh_eu * (ratedU1 / ratedU2) * (ratedU1 / ratedU2) Apply the structural ratio when moving - // Ysh_eu_moved = Ysh_eu * sbase / (vn2 * vn2) as ratedU1 = vn1 and ratedU2 ) vn2 + // Ysh_eu_moved = Ysh_eu * sbase / (vn2 * vn2) as ratedU1 = vn1 and ratedU2 = vn2 // As vn2 is used to convert to eu, only the ratio remains to be applied TapChanger tapChangerAdjustedYsh = tapChangerAdjustmentAfterMovingShuntAdmittanceBetweenRatioAndTransmissionImpedance(tapChangerAdjustedRatio); @@ -848,7 +848,7 @@ private static Terminal defineRegulatingTerminal(Network network, String id, Str int busI = Math.abs(winding.getCont()); Optional controlNode = nodeBreakerImport.getControlNode(getNodeBreakerEquipmentIdBus(equipmentId, busI)); if (controlNode.isPresent()) { - regulatingTerminal = obtainTerminalNode(network, controlNode.get().getVoltageLevelId(), controlNode.get().getNode()); + regulatingTerminal = findTerminalNode(network, controlNode.get().getVoltageLevelId(), controlNode.get().getNode()); } else { String regulatingBusId = getBusId(busI); Bus bus = network.getBusBreakerView().getBus(regulatingBusId); @@ -862,26 +862,18 @@ private static Terminal defineRegulatingTerminal(Network network, String id, Str return regulatingTerminal; } - private static String getTransformerId(int i, int j, String ckt) { - return "T-" + i + "-" + j + "-" + ckt; - } - - private static String getTransformerId(int i, int j, int k, String ckt) { - return "T-" + i + "-" + j + "-" + k + "-" + ckt; - } - // At the moment we do not consider new transformers and antenna twoWindingsTransformers are exported as open - static void updateTransformers(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { + static void updateTransformers(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { psseModel.getTransformers().forEach(psseTransformer -> { if (isTwoWindingsTransformer(psseTransformer)) { - updateTwoWindingsTransformer(network, psseTransformer, nodeBreakerExport); + updateTwoWindingsTransformer(network, psseTransformer, contextExport); } else { - updateThreeWindingsTransformer(network, psseTransformer, nodeBreakerExport); + updateThreeWindingsTransformer(network, psseTransformer, contextExport); } }); } - private static void updateTwoWindingsTransformer(Network network, PsseTransformer psseTransformer, NodeBreakerExport nodeBreakerExport) { + private static void updateTwoWindingsTransformer(Network network, PsseTransformer psseTransformer, ContextExport contextExport) { String transformerId = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); TwoWindingsTransformer tw2t = network.getTwoWindingsTransformer(transformerId); if (tw2t == null) { @@ -892,19 +884,18 @@ private static void updateTwoWindingsTransformer(Network network, PsseTransforme psseTransformer.getWinding1().setWindv(defineWindV(getRatio(tw2t.getRatioTapChanger(), tw2t.getPhaseTapChanger()), baskv1, nomV1, psseTransformer.getCw())); psseTransformer.getWinding1().setAng(getAngle(tw2t.getPhaseTapChanger())); - String equipmentId = getNodeBreakerEquipmentId(PSSE_TWO_WINDING, psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); - int busI = obtainBus(nodeBreakerExport, equipmentId, psseTransformer.getI()); - int busJ = obtainBus(nodeBreakerExport, equipmentId, psseTransformer.getJ()); + int busI = getTerminalBusI(tw2t.getTerminal1(), contextExport); + int busJ = getTerminalBusI(tw2t.getTerminal2(), contextExport); psseTransformer.setI(busI); psseTransformer.setJ(busJ); - int regulatingBus = obtainRegulatingBus(nodeBreakerExport, obtainRegulatingTerminal(tw2t), psseTransformer.getWinding1().getCont()); + int regulatingBus = getRegulatingTerminalBusI(findRegulatingTerminal(tw2t), contextExport); psseTransformer.getWinding1().setCont(regulatingBus); psseTransformer.setStat(getStatus(tw2t)); } } - private static Terminal obtainRegulatingTerminal(TwoWindingsTransformer tw2t) { + private static Terminal findRegulatingTerminal(TwoWindingsTransformer tw2t) { Terminal regulatingTerminal = tw2t.getOptionalRatioTapChanger().map(RatioTapChanger::getRegulationTerminal).orElse(null); if (regulatingTerminal != null) { return regulatingTerminal; @@ -921,7 +912,7 @@ private static int getStatus(TwoWindingsTransformer tw2t) { } } - private static void updateThreeWindingsTransformer(Network network, PsseTransformer psseTransformer, NodeBreakerExport nodeBreakerExport) { + private static void updateThreeWindingsTransformer(Network network, PsseTransformer psseTransformer, ContextExport contextExport) { String transformerId = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt()); ThreeWindingsTransformer tw3t = network.getThreeWindingsTransformer(transformerId); if (tw3t == null) { @@ -942,17 +933,16 @@ private static void updateThreeWindingsTransformer(Network network, PsseTransfor psseTransformer.getWinding3().setWindv(defineWindV(getRatio(tw3t.getLeg3().getRatioTapChanger(), tw3t.getLeg3().getPhaseTapChanger()), baskv3, nomV3, psseTransformer.getCw())); psseTransformer.getWinding3().setAng(getAngle(tw3t.getLeg3().getPhaseTapChanger())); - String equipmentId = getNodeBreakerEquipmentId(PSSE_THREE_WINDING, psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt()); - int busI = obtainBus(nodeBreakerExport, equipmentId, psseTransformer.getI()); - int busJ = obtainBus(nodeBreakerExport, equipmentId, psseTransformer.getJ()); - int busK = obtainBus(nodeBreakerExport, equipmentId, psseTransformer.getK()); + int busI = getTerminalBusI(tw3t.getLeg1().getTerminal(), contextExport); + int busJ = getTerminalBusI(tw3t.getLeg2().getTerminal(), contextExport); + int busK = getTerminalBusI(tw3t.getLeg3().getTerminal(), contextExport); psseTransformer.setI(busI); psseTransformer.setJ(busJ); psseTransformer.setK(busK); - int regulatingBus1 = obtainRegulatingBus(nodeBreakerExport, obtainRegulatingTerminal(tw3t.getLeg1()), psseTransformer.getWinding1().getCont()); - int regulatingBus2 = obtainRegulatingBus(nodeBreakerExport, obtainRegulatingTerminal(tw3t.getLeg2()), psseTransformer.getWinding2().getCont()); - int regulatingBus3 = obtainRegulatingBus(nodeBreakerExport, obtainRegulatingTerminal(tw3t.getLeg3()), psseTransformer.getWinding3().getCont()); + int regulatingBus1 = getRegulatingTerminalBusI(findRegulatingTerminal(tw3t.getLeg1()), contextExport); + int regulatingBus2 = getRegulatingTerminalBusI(findRegulatingTerminal(tw3t.getLeg2()), contextExport); + int regulatingBus3 = getRegulatingTerminalBusI(findRegulatingTerminal(tw3t.getLeg3()), contextExport); psseTransformer.getWinding1().setCont(regulatingBus1); psseTransformer.getWinding2().setCont(regulatingBus2); psseTransformer.getWinding3().setCont(regulatingBus3); @@ -961,7 +951,7 @@ private static void updateThreeWindingsTransformer(Network network, PsseTransfor } } - private static Terminal obtainRegulatingTerminal(Leg leg) { + private static Terminal findRegulatingTerminal(Leg leg) { Terminal regulatingTerminal = leg.getOptionalRatioTapChanger().map(RatioTapChanger::getRegulationTerminal).orElse(null); if (regulatingTerminal != null) { return regulatingTerminal; diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java index 7099768b804..0d36bc6a67e 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java @@ -10,7 +10,6 @@ import com.powsybl.iidm.network.HvdcLine.ConvertersMode; import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.util.ContainersMapping; -import com.powsybl.iidm.network.util.Identifiables; import com.powsybl.psse.model.pf.PssePowerFlowModel; import com.powsybl.psse.model.pf.PsseTwoTerminalDcConverter; import com.powsybl.psse.model.pf.PsseTwoTerminalDcTransmissionLine; @@ -40,7 +39,7 @@ void create() { String busIdR = getBusId(psseTwoTerminalDc.getRectifier().getIp()); VoltageLevel voltageLevelR = getNetwork().getVoltageLevel(getContainersMapping().getVoltageLevelId(psseTwoTerminalDc.getRectifier().getIp())); LccConverterStationAdder adderR = voltageLevelR.newLccConverterStation() - .setId(getLccConverterId(psseTwoTerminalDc, psseTwoTerminalDc.getRectifier())) + .setId(getLccConverterId(getNetwork(), psseTwoTerminalDc, psseTwoTerminalDc.getRectifier())) .setName(psseTwoTerminalDc.getName()) .setLossFactor((float) lossFactor) .setPowerFactor((float) getLccConverterPowerFactor(psseTwoTerminalDc.getRectifier())); @@ -58,7 +57,7 @@ void create() { String busIdI = getBusId(psseTwoTerminalDc.getInverter().getIp()); VoltageLevel voltageLevelI = getNetwork().getVoltageLevel(getContainersMapping().getVoltageLevelId(psseTwoTerminalDc.getInverter().getIp())); LccConverterStationAdder adderI = voltageLevelI.newLccConverterStation() - .setId(getLccConverterId(psseTwoTerminalDc, psseTwoTerminalDc.getInverter())) + .setId(getLccConverterId(getNetwork(), psseTwoTerminalDc, psseTwoTerminalDc.getInverter())) .setName(psseTwoTerminalDc.getName()) .setLossFactor((float) lossFactor) .setPowerFactor((float) getLccConverterPowerFactor(psseTwoTerminalDc.getInverter())); @@ -74,7 +73,7 @@ void create() { LccConverterStation cI = adderI.add(); HvdcLineAdder adder = getNetwork().newHvdcLine() - .setId(getTwoTerminalDcId(psseTwoTerminalDc)) + .setId(getTwoTerminalDcId(psseTwoTerminalDc.getName())) .setName(psseTwoTerminalDc.getName()) .setR(psseTwoTerminalDc.getRdc()) .setNominalV(psseTwoTerminalDc.getVschd()) @@ -87,16 +86,15 @@ void create() { } private static double getTwoTerminalDcActivePowerSetpoint(PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc) { - switch (psseTwoTerminalDc.getMdc()) { - case 1: + return switch (psseTwoTerminalDc.getMdc()) { + case 1 -> // The desired real power demand - return Math.abs(psseTwoTerminalDc.getSetvl()); - case 2: + Math.abs(psseTwoTerminalDc.getSetvl()); + case 2 -> // It is the current in amps (should divide by 1000 to convert to MW) - return psseTwoTerminalDc.getSetvl() * psseTwoTerminalDc.getVschd() / 1000.0; - default: - return 0.0; - } + psseTwoTerminalDc.getSetvl() * psseTwoTerminalDc.getVschd() / 1000.0; + default -> 0.0; + }; } private static double getTwoTerminalDcMaxP(PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc) { @@ -108,36 +106,33 @@ private static double getLccConverterPowerFactor(PsseTwoTerminalDcConverter conv return 0.5 * (Math.cos(Math.toRadians(converter.getAnmx())) + Math.cos(Math.toRadians(60.0))); } - private String getLccConverterId(PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc, PsseTwoTerminalDcConverter converter) { - return Identifiables.getUniqueId("LccConverter-" + psseTwoTerminalDc.getRectifier().getIp() + "-" + psseTwoTerminalDc.getInverter().getIp() + "-" + converter.getIp(), - id -> getNetwork().getLccConverterStation(id) != null); - } - - private static String getTwoTerminalDcId(PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc) { - return "TwoTerminalDc-" + psseTwoTerminalDc.getRectifier().getIp() + "-" + psseTwoTerminalDc.getInverter().getIp() + "-" + psseTwoTerminalDc.getName(); - } - - static void updateTwoTerminalDcTransmissionLines(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { + static void updateTwoTerminalDcTransmissionLines(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { psseModel.getTwoTerminalDcTransmissionLines().forEach(psseTwoTerminalDc -> { - String hvdcId = getTwoTerminalDcId(psseTwoTerminalDc); + String hvdcId = getTwoTerminalDcId(psseTwoTerminalDc.getName()); HvdcLine hvdcLine = network.getHvdcLine(hvdcId); - String equipmentIdRectifier = getNodeBreakerEquipmentId(PSSE_TWO_TERMINAL_DC_LINE, psseTwoTerminalDc.getRectifier().getIp(), psseTwoTerminalDc.getName()); - int busRectifier = obtainBus(nodeBreakerExport, equipmentIdRectifier, psseTwoTerminalDc.getRectifier().getIp()); - String equipmentIdInverter = getNodeBreakerEquipmentId(PSSE_TWO_TERMINAL_DC_LINE, psseTwoTerminalDc.getInverter().getIp(), psseTwoTerminalDc.getName()); - int busInverter = obtainBus(nodeBreakerExport, equipmentIdInverter, psseTwoTerminalDc.getInverter().getIp()); + int busRectifier = getTerminalBusI(rectifierTerminal(hvdcLine), contextExport); + int busInverter = getTerminalBusI(inverterTerminal(hvdcLine), contextExport); if (hvdcLine == null) { psseTwoTerminalDc.setMdc(0); } else { - psseTwoTerminalDc.setMdc(obtainControlMode(hvdcLine, psseTwoTerminalDc.getMdc())); + psseTwoTerminalDc.setMdc(findControlMode(hvdcLine, psseTwoTerminalDc.getMdc())); } psseTwoTerminalDc.getRectifier().setIp(busRectifier); psseTwoTerminalDc.getInverter().setIp(busInverter); }); } - private static int obtainControlMode(HvdcLine hvdcLine, int mdc) { + private static Terminal rectifierTerminal(HvdcLine hvdcLine) { + return hvdcLine.getConvertersMode().equals(ConvertersMode.SIDE_1_RECTIFIER_SIDE_2_INVERTER) ? hvdcLine.getConverterStation1().getTerminal() : hvdcLine.getConverterStation2().getTerminal(); + } + + private static Terminal inverterTerminal(HvdcLine hvdcLine) { + return hvdcLine.getConvertersMode().equals(ConvertersMode.SIDE_1_RECTIFIER_SIDE_2_INVERTER) ? hvdcLine.getConverterStation2().getTerminal() : hvdcLine.getConverterStation1().getTerminal(); + } + + private static int findControlMode(HvdcLine hvdcLine, int mdc) { if (hvdcLine.getConverterStation1().getTerminal().isConnected() && hvdcLine.getConverterStation1().getTerminal().getBusBreakerView().getBus() != null && hvdcLine.getConverterStation2().getTerminal().isConnected() && hvdcLine.getConverterStation2().getTerminal().getBusBreakerView().getBus() != null) { return mdc != 0 ? mdc : 1; diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java index fe7d821b715..26440ad47bc 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java @@ -22,6 +22,11 @@ import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationNode; import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationSwitchingDevice; import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationEquipmentTerminal; +import org.jgrapht.Graph; +import org.jgrapht.alg.connectivity.ConnectivityInspector; +import org.jgrapht.alg.util.Pair; +import org.jgrapht.graph.Pseudograph; + import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_GENERATOR; /** @@ -60,7 +65,7 @@ VoltageLevel create(Substation substation) { // Add slack control data if (voltageLevel.getTopologyKind().equals(TopologyKind.NODE_BREAKER) && psseBus.getIde() == 3) { - nodeBreakerImport.addSlackControl(psseBus.getI(), voltageLevelId, obtainSlackNode(nodeBreakerValidation, psseBus.getI())); + nodeBreakerImport.addSlackControl(psseBus.getI(), voltageLevelId, findSlackNode(nodeBreakerValidation, psseBus.getI())); } return voltageLevel; } @@ -84,7 +89,7 @@ private void addNodeBreakerConnectivity(String voltageLevelId, VoltageLevel volt .setName(switchingDevice.getName()) .setNode1(switchingDevice.getNi()) .setNode2(switchingDevice.getNj()) - .setKind(obtainSwitchingKind(switchingDevice.getType())) + .setKind(findSwitchingKind(switchingDevice.getType())) .setOpen(switchingDevice.getStatus() != 1) .add(); } @@ -94,7 +99,7 @@ private void addNodeBreakerConnectivity(String voltageLevelId, VoltageLevel volt Set nodesWithEquipment = new HashSet<>(); for (PsseSubstationEquipmentTerminal equipmentTerminal : substation.getEquipmentTerminals()) { String equipmentId = getNodeBreakerEquipmentId(equipmentTerminal.getType(), equipmentTerminal.getI(), equipmentTerminal.getJ(), equipmentTerminal.getK(), equipmentTerminal.getId()); - int bus = obtainBus(equipmentTerminal, buses); + int bus = findBus(equipmentTerminal, buses); String equipmentIdBus = getNodeBreakerEquipmentIdBus(equipmentId, bus); // IIDM only allows one piece of equipment by node if (nodesWithEquipment.contains(equipmentTerminal.getNi())) { @@ -124,23 +129,15 @@ private void addNodeBreakerConnectivity(String voltageLevelId, VoltageLevel volt }); } - private static SwitchKind obtainSwitchingKind(int type) { + private static SwitchKind findSwitchingKind(int type) { return type == 2 ? SwitchKind.BREAKER : SwitchKind.DISCONNECTOR; } - private static int obtainBus(PsseSubstationEquipmentTerminal equipmentTerminal, Set buses) { + private static int findBus(PsseSubstationEquipmentTerminal equipmentTerminal, Set buses) { return buses.stream().filter(bus -> bus == equipmentTerminal.getI() || bus == equipmentTerminal.getJ() || bus == equipmentTerminal.getK()).min(Comparator.naturalOrder()).orElseThrow(); } - private static String getSwitchId(String voltageLevelId, PsseSubstationSwitchingDevice switchingDevice) { - return voltageLevelId + "-Sw-" + switchingDevice.getNi() + "-" + switchingDevice.getNj() + "-" + switchingDevice.getCkt(); - } - - private static String busbarSectionId(String voltageLevelId, int node) { - return String.format("%s-Busbar-%d", voltageLevelId, node); - } - - private static int obtainSlackNode(NodeBreakerValidation nodeBreakerValidation, int bus) { + private static int findSlackNode(NodeBreakerValidation nodeBreakerValidation, int bus) { PsseSubstation psseSubstation = nodeBreakerValidation.getSubstationIfOnlyOneExists(bus).orElseThrow(); return psseSubstation.getNodes().stream().filter(n -> n.getI() == bus) .map(PsseSubstationNode::getNi).min(Comparator.comparingInt((Integer node) -> connectedGenerators(psseSubstation, node)) @@ -151,107 +148,166 @@ private static int connectedGenerators(PsseSubstation psseSubstation, int node) return (int) psseSubstation.getEquipmentTerminals().stream().filter(eqt -> eqt.getNi() == node && eqt.getType().equals(PSSE_GENERATOR.getTextCode())).count(); } - static NodeBreakerExport mapSubstations(Network network, PssePowerFlowModel psseModel) { - int maxPsseBus = psseModel.getBuses().stream().map(PsseBus::getI).max(Comparator.naturalOrder()).orElseThrow(); - NodeBreakerExport nodeBreakerExport = new NodeBreakerExport(maxPsseBus); + static ContextExport createContextExport(Network network, PssePowerFlowModel psseModel) { + int maxPsseBus = psseModel.getBuses().stream().map(PsseBus::getI).max(Comparator.naturalOrder()).orElse(0); + ContextExport contextExport = new ContextExport(maxPsseBus); - psseModel.getSubstations().forEach(psseSubstation -> mapSubstation(network, psseSubstation, nodeBreakerExport)); + // First busBreaker voltageLevels + List busBreakerVoltageLevels = network.getVoltageLevelStream().filter(vl -> vl.getTopologyKind().equals(TopologyKind.BUS_BREAKER)).toList(); + busBreakerVoltageLevels.forEach(voltageLevel -> createBusBreakerExport(voltageLevel, contextExport)); - return nodeBreakerExport; - } - - private static void mapSubstation(Network network, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { - VoltageLevel voltageLevel = obtainVoltageLevel(network, psseSubstation); - if (voltageLevel != null && isNodeBreaker(voltageLevel)) { - mapBusBreakerBusesToPsseBuses(voltageLevel, psseSubstation, nodeBreakerExport); - mapIsolatedPsseNodesToPsseBuses(voltageLevel, psseSubstation, nodeBreakerExport); - mapEquipmentIdBustoBus(voltageLevel, psseSubstation, nodeBreakerExport); - } - } + // Always after busBreaker voltageLevels + findNodeBreakerVoltageLevelsAndMapPsseSubstation(network, psseModel, contextExport); + contextExport.getNodeBreakerExport().getVoltageLevels().forEach(voltageLevel -> { + Optional psseSubstation = contextExport.getNodeBreakerExport().getPsseSubstationMappedToVoltageLevel(voltageLevel); + if (psseSubstation.isPresent()) { + createNodeBreakerExport(voltageLevel, psseSubstation.get(), contextExport); + } else { + createNodeBreakerExport(voltageLevel, contextExport); + } + }); - private static VoltageLevel obtainVoltageLevel(Network network, PsseSubstation psseSubstation) { - Set busesSet = psseSubstation.getNodes().stream().map(PsseSubstationNode::getI).collect(Collectors.toSet()); - String voltageLevelId = getVoltageLevelId(busesSet); - return network.getVoltageLevel(voltageLevelId); + return contextExport; } - private static boolean isNodeBreaker(VoltageLevel voltageLevel) { - Objects.requireNonNull(voltageLevel); - return voltageLevel.getTopologyKind().equals(TopologyKind.NODE_BREAKER); + private static void findNodeBreakerVoltageLevelsAndMapPsseSubstation(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { + psseModel.getSubstations().forEach(psseSubstation -> { + VoltageLevel voltageLevel = findVoltageLevel(network, psseSubstation); + if (voltageLevel != null && voltageLevel.getTopologyKind().equals(TopologyKind.NODE_BREAKER)) { + contextExport.getNodeBreakerExport().addVoltageLevel(voltageLevel, psseSubstation); + } + }); + List voltageLevelList = contextExport.getNodeBreakerExport().getVoltageLevels(); + List nodeBreakerVoltageLevelsNotMapped = network.getVoltageLevelStream().filter(voltageLevel -> voltageLevel.getTopologyKind().equals(TopologyKind.NODE_BREAKER) && !voltageLevelList.contains(voltageLevel)).toList(); + contextExport.getNodeBreakerExport().addVoltageLevels(nodeBreakerVoltageLevelsNotMapped); } - private static void mapBusBreakerBusesToPsseBuses(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { - Set psseNodesSet = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).collect(Collectors.toSet()); - Map> busBreakerBusIdNodeList = obtainBusBreakerBusIdNodeList(voltageLevel); + private static void createNodeBreakerExport(VoltageLevel voltageLevel, PsseSubstation psseSubstation, ContextExport contextExport) { + List nodesAfterExcludingInternalConnections = findNodesAfterExcludingInternalConnections(voltageLevel, contextExport); + Map> busViewBusIdNodeList = findBusViewBusIdNodeList(voltageLevel, nodesAfterExcludingInternalConnections); - // First, buses with more psse nodes - Comparator comp = Comparator.comparingInt((String key) -> onlyPsseNodes(busBreakerBusIdNodeList.get(key), psseNodesSet).size()) + // First, buses with more nodes + Comparator comp = Comparator.comparingInt((String key) -> busViewBusIdNodeList.get(key).size()) .reversed() .thenComparing(Comparator.naturalOrder()); - busBreakerBusIdNodeList.keySet().stream().sorted(comp).forEach(key -> { + busViewBusIdNodeList.keySet().stream().sorted(comp).forEach(busViewBusId -> { + Optional bus = mapPsseBus(psseSubstation, busViewBusIdNodeList.get(busViewBusId), contextExport); + int busType = findBusViewBusType(voltageLevel, busViewBusId); + if (bus.isPresent()) { + contextExport.getNodeBreakerExport().addNodes(busViewBusId, voltageLevel, busViewBusIdNodeList.get(busViewBusId), bus.get(), busType); + } else { + int newBus = contextExport.getNewPsseBusI(); + contextExport.getNodeBreakerExport().addNodes(busViewBusId, voltageLevel, busViewBusIdNodeList.get(busViewBusId), newBus, selectCopyBus(psseSubstation), busType); + } + }); - Optional bus = mapPsseBus(psseSubstation, nodeBreakerExport); - int busType = obtainBusBreakerBusType(voltageLevel, key); + List isolatedNodes = findIsolatedNodes(nodesAfterExcludingInternalConnections, busViewBusIdNodeList); + isolatedNodes.forEach(node -> { + Optional bus = mapPsseBus(psseSubstation, Collections.singletonList(node), contextExport); if (bus.isPresent()) { - nodeBreakerExport.addBusMapping(bus.get(), key, busType); - nodeBreakerExport.addNodesBusMapping(voltageLevel.getId(), onlyPsseNodes(busBreakerBusIdNodeList.get(key), psseNodesSet), bus.get(), true); + contextExport.getNodeBreakerExport().addIsolatedNode(voltageLevel, node, bus.get()); } else { - int newBus = nodeBreakerExport.getNewPsseBus(); - nodeBreakerExport.addNewMappedBus(newBus, selectCopyBus(psseSubstation), key, busType); - nodeBreakerExport.addNodesBusMapping(voltageLevel.getId(), onlyPsseNodes(busBreakerBusIdNodeList.get(key), psseNodesSet), newBus, true); + int newBus = contextExport.getNewPsseBusI(); + contextExport.getNodeBreakerExport().addIsolatedNode(voltageLevel, node, newBus, selectCopyBus(psseSubstation)); } }); + + getEquipmentListToBeExported(voltageLevel).forEach(equipmentId -> + getEquipmentTerminals(voltageLevel, equipmentId).forEach(terminal -> { + int node = contextExport.getNodeBreakerExport().getSelectedNode(voltageLevel, terminal.getNodeBreakerView().getNode()).orElseThrow(); + int busI = contextExport.getNodeBreakerExport().getNodeBusI(voltageLevel, node).orElseThrow(); + int end = getSideEnd(getTerminalSide(terminal)); + contextExport.addEquipmentEnd(equipmentId, voltageLevel, node, busI, end); + })); } - // discard nodes associated with internal connections - private static List onlyPsseNodes(List iidmNodes, Set psseNodesSet) { - return iidmNodes.stream().filter(psseNodesSet::contains).toList(); + private static void createNodeBreakerExport(VoltageLevel voltageLevel, ContextExport contextExport) { + createNodeBreakerExport(voltageLevel, null, contextExport); } - private static Map> obtainBusBreakerBusIdNodeList(VoltageLevel voltageLevel) { - Map> busBreakerBusIdNodeList = new HashMap<>(); + private static void createBusBreakerExport(VoltageLevel voltageLevel, ContextExport contextExport) { + Map> busViewBusBusBreakerViewBuses = new HashMap<>(); + voltageLevel.getBusBreakerView().getBuses().forEach(busBreakerViewBus -> busViewBusBusBreakerViewBuses.computeIfAbsent(voltageLevel.getBusView().getMergedBus(busBreakerViewBus.getId()).getId(), k -> new ArrayList<>()).add(busBreakerViewBus.getId())); + + voltageLevel.getBusView().getBuses().forEach(bus -> { + int busType = findBusViewBusType(voltageLevel, bus.getId()); + String busBreakerViewId = findBusBreakerViewBusId(bus.getId(), busViewBusBusBreakerViewBuses); + OptionalInt busI = extractBusNumber(busBreakerViewId); + if (busI.isEmpty()) { + contextExport.getBusBreakerExport().addBus(bus.getId(), contextExport.getNewPsseBusI(), busType); + } else { + contextExport.getBusBreakerExport().addBus(bus.getId(), busI.getAsInt(), busType); + } + }); + + getEquipmentListToBeExported(voltageLevel).forEach(equipmentId -> + getEquipmentTerminals(voltageLevel, equipmentId).forEach(terminal -> { + Bus bus = getTerminalBus(terminal); + int busI = contextExport.getBusBreakerExport().getBusBusI(bus.getId()).orElseThrow(); + int end = getSideEnd(terminal.getSide()); + contextExport.addEquipmentEnd(equipmentId, voltageLevel, busI, end); + })); + } + + private static List findNodesAfterExcludingInternalConnections(VoltageLevel voltageLevel, ContextExport contextExport) { + Graph> inGraph = new Pseudograph<>(null, null, false); for (int node : voltageLevel.getNodeBreakerView().getNodes()) { - Terminal terminal = obtainTerminalNode(voltageLevel, node); + inGraph.addVertex(node); + } + voltageLevel.getNodeBreakerView().getInternalConnections().forEach(internalConnection -> inGraph.addEdge(internalConnection.getNode1(), internalConnection.getNode2(), Pair.of(internalConnection.getNode1(), internalConnection.getNode2()))); + + List> componentsSetList = new ConnectivityInspector<>(inGraph).connectedSets(); + + componentsSetList.forEach(componetSet -> contextExport.getNodeBreakerExport().addSelectedNode(voltageLevel, componetSet, componetSet.stream().min(Comparator.naturalOrder()).orElseThrow())); + return contextExport.getNodeBreakerExport().getSelectedNodes(voltageLevel); + } + + private static Map> findBusViewBusIdNodeList(VoltageLevel voltageLevel, List nodesAfterExcludingInternalConnections) { + Map> busViewBusIdNodeList = new HashMap<>(); + + nodesAfterExcludingInternalConnections.forEach(node -> { + Terminal terminal = findTerminalNode(voltageLevel, node); if (terminal != null) { - Bus bus = terminal.getBusBreakerView().getBus(); + Bus bus = terminal.getBusView().getBus(); if (bus != null) { - busBreakerBusIdNodeList.computeIfAbsent(bus.getId(), k -> new ArrayList<>()).add(node); + busViewBusIdNodeList.computeIfAbsent(bus.getId(), k -> new ArrayList<>()).add(node); } } - } - return busBreakerBusIdNodeList; + }); + return busViewBusIdNodeList; } - // Map to the free psse bus with more matching nodes - private static Optional mapPsseBus(PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { + private static List findIsolatedNodes(List nodesAfterExcludingInternalConnections, Map> busViewBusIdNodeList) { + List psseBusesIAssociatedWithBus = busViewBusIdNodeList.values().stream().flatMap(List::stream).toList(); + return nodesAfterExcludingInternalConnections.stream().filter(node -> !psseBusesIAssociatedWithBus.contains(node)).toList(); + } - Comparator comp = Comparator.comparingInt((Integer b) -> nodesAssociatedWithBus(psseSubstation, b).size()) + private static Optional mapPsseBus(PsseSubstation psseSubstation, List nodes, ContextExport contextExport) { + if (psseSubstation == null) { + return Optional.empty(); + } + + Comparator comp = Comparator.comparingInt((Integer busI) -> nodesAssociatedWithBus(psseSubstation, nodes, busI).size()) .reversed() .thenComparing(Comparator.naturalOrder()); return psseSubstation.getNodes().stream() - .map(PsseSubstationNode::getI).filter(nodeBreakerExport::isFreeBus) + .map(PsseSubstationNode::getI).filter(contextExport::isFreePsseBusI) .collect(Collectors.toSet()) .stream().min(comp); } - private static int selectCopyBus(PsseSubstation psseSubstation) { - return psseSubstation.getNodes().stream().map(PsseSubstationNode::getI).min(Comparator.naturalOrder()).orElseThrow(); - } - - private static List nodesAssociatedWithBus(PsseSubstation psseSubstation, int bus) { - return psseSubstation.getNodes().stream().filter(n -> n.getI() == bus).map(PsseSubstationNode::getNi).toList(); - } - - private static int obtainBusBreakerBusType(VoltageLevel voltageLevel, String busBreakerBusId) { - Bus bus = voltageLevel.getBusBreakerView().getBus(busBreakerBusId); + private static int findBusViewBusType(VoltageLevel voltageLevel, String busViewBusId) { + Bus bus = voltageLevel.getBusView().getBus(busViewBusId); if (bus == null) { // unexpected return 4; } SlackTerminal slackTerminal = voltageLevel.getExtension(SlackTerminal.class); - if (slackTerminal != null && bus.equals(slackTerminal.getTerminal().getBusBreakerView().getBus())) { + if (slackTerminal != null + && slackTerminal.getTerminal().getBusView().getBus() != null + && bus.getId().equals(slackTerminal.getTerminal().getBusView().getBus().getId())) { return 3; } return bus.getGeneratorStream().anyMatch(VoltageLevelConverter::withLocalRegulatingControl) ? 2 : 1; @@ -259,77 +315,51 @@ private static int obtainBusBreakerBusType(VoltageLevel voltageLevel, String bus private static boolean withLocalRegulatingControl(Generator generator) { return generator.isVoltageRegulatorOn() - && generator.getTerminal().getBusBreakerView().getBus().equals(generator.getRegulatingTerminal().getBusBreakerView().getBus()); + && generator.getTerminal().getBusView().getBus().equals(generator.getRegulatingTerminal().getBusView().getBus()); } - private static void mapIsolatedPsseNodesToPsseBuses(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { - mapIsolatedPsseNodesToTheAssociatedFreeBus(voltageLevel, psseSubstation, nodeBreakerExport); - mapIsolatedPsseNodesToFreeBus(voltageLevel, psseSubstation, nodeBreakerExport); - mapIsolatedPsseNodesToNewBus(voltageLevel, psseSubstation, nodeBreakerExport); + private static Integer selectCopyBus(PsseSubstation psseSubstation) { + return psseSubstation != null ? psseSubstation.getNodes().stream().map(PsseSubstationNode::getI).min(Comparator.naturalOrder()).orElseThrow() : null; } - private static void mapIsolatedPsseNodesToTheAssociatedFreeBus(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { - List isolatedNodes = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).filter(node -> nodeBreakerExport.isFreeNode(voltageLevel.getId(), node)).toList(); - isolatedNodes.forEach(node -> { - Optional bus = psseSubstation.getNodes().stream() - .filter(n -> n.getNi() == node && nodeBreakerExport.isFreeBus(n.getI())) - .map(PsseSubstationNode::getI).min(Comparator.naturalOrder()); - if (bus.isPresent()) { - nodeBreakerExport.addNodeBusMapping(voltageLevel.getId(), node, bus.get(), false); - nodeBreakerExport.addIsolatedBus(bus.get()); - } - }); + private static List nodesAssociatedWithBus(PsseSubstation psseSubstation, List nodes, int busI) { + return psseSubstation.getNodes().stream().filter(n -> n.getI() == busI && nodes.contains(n.getNi())).map(PsseSubstationNode::getNi).toList(); } - private static void mapIsolatedPsseNodesToFreeBus(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { - List isolatedNodes = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).filter(node -> nodeBreakerExport.isFreeNode(voltageLevel.getId(), node)).toList(); - isolatedNodes.forEach(node -> { - Optional bus = psseSubstation.getNodes().stream() - .map(PsseSubstationNode::getI) - .filter(nodeBreakerExport::isFreeBus) - .min(Comparator.naturalOrder()); - if (bus.isPresent()) { - nodeBreakerExport.addNodeBusMapping(voltageLevel.getId(), node, bus.get(), false); - nodeBreakerExport.addIsolatedBus(bus.get()); + private static String findBusBreakerViewBusId(String busViewBusId, Map> busViewBusBusBreakerViewBuses) { + if (busViewBusBusBreakerViewBuses.containsKey(busViewBusId)) { + List busBreakerViewBuses = busViewBusBusBreakerViewBuses.get(busViewBusId); + if (busBreakerViewBuses.isEmpty()) { + throw new PsseException("BusView without busBreakerView: " + busViewBusId); + } else { + return busBreakerViewBuses.stream().sorted().toList().get(0); } - }); + } else { + throw new PsseException("BusView bus does not found: " + busViewBusId); + } } - private static void mapIsolatedPsseNodesToNewBus(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { - List isolatedNodes = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).filter(node -> nodeBreakerExport.isFreeNode(voltageLevel.getId(), node)).toList(); - isolatedNodes.forEach(node -> { - int newBus = nodeBreakerExport.getNewPsseBus(); - nodeBreakerExport.addNewNotMappedBus(newBus, selectCopyBus(psseSubstation)); - nodeBreakerExport.addNodeBusMapping(voltageLevel.getId(), node, newBus, false); - nodeBreakerExport.addIsolatedBus(newBus); - }); + private static int getSideEnd(ThreeSides side) { + return side == null ? 1 : side.getNum(); } - private static void mapEquipmentIdBustoBus(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { - psseSubstation.getEquipmentTerminals().forEach(equipmentTerminal -> { - String equipmentId = getNodeBreakerEquipmentId(equipmentTerminal.getType(), equipmentTerminal.getI(), equipmentTerminal.getJ(), equipmentTerminal.getK(), equipmentTerminal.getId()); - nodeBreakerExport.getNodeBus(voltageLevel.getId(), equipmentTerminal.getNi()).ifPresent(bus -> { - if (bus != equipmentTerminal.getI()) { - nodeBreakerExport.addEquipmentIdBus(getNodeBreakerEquipmentIdBus(equipmentId, equipmentTerminal.getI()), bus); - } - }); - }); + private static VoltageLevel findVoltageLevel(Network network, PsseSubstation psseSubstation) { + Set busesSet = psseSubstation.getNodes().stream().map(PsseSubstationNode::getI).collect(Collectors.toSet()); + String voltageLevelId = getVoltageLevelId(busesSet); + return network.getVoltageLevel(voltageLevelId); } - static void updateSubstations(Network network, PssePowerFlowModel psseModel, NodeBreakerExport nodeBreakerExport) { - psseModel.getSubstations().forEach(psseSubstation -> { - VoltageLevel voltageLevel = obtainVoltageLevel(network, psseSubstation); - if (voltageLevel != null && isNodeBreaker(voltageLevel)) { - updateSubstation(voltageLevel, psseSubstation, nodeBreakerExport); - } + static void updateSubstations(ContextExport contextExport) { + contextExport.getNodeBreakerExport().getVoltageLevels().forEach(voltageLevel -> { + Optional optionalPsseSubstation = contextExport.getNodeBreakerExport().getPsseSubstationMappedToVoltageLevel(voltageLevel); + optionalPsseSubstation.ifPresent(psseSubstation -> updateSubstation(voltageLevel, psseSubstation, contextExport)); }); } - private static void updateSubstation(VoltageLevel voltageLevel, PsseSubstation psseSubstation, NodeBreakerExport nodeBreakerExport) { - + private static void updateSubstation(VoltageLevel voltageLevel, PsseSubstation psseSubstation, ContextExport contextExport) { psseSubstation.getNodes().forEach(psseSubstationNode -> { - int bus = nodeBreakerExport.getNodeBus(voltageLevel.getId(), psseSubstationNode.getNi()).orElseThrow(); - boolean inService = nodeBreakerExport.isNodeInService(voltageLevel.getId(), psseSubstationNode.getNi()).orElseThrow(); + int bus = contextExport.getNodeBreakerExport().getNodeBusI(voltageLevel, psseSubstationNode.getNi()).orElseThrow(); + boolean inService = contextExport.getNodeBreakerExport().isNodeInService(voltageLevel, psseSubstationNode.getNi()).orElseThrow(); psseSubstationNode.setI(bus); psseSubstationNode.setStatus(inService ? 1 : 0); }); @@ -343,12 +373,43 @@ private static void updateSubstation(VoltageLevel voltageLevel, PsseSubstation p switchingDevice.setStatus(sw.isOpen() ? 0 : 1); }); - psseSubstation.getEquipmentTerminals().forEach(equipmentTerminal -> { - String equipmentId = getNodeBreakerEquipmentId(equipmentTerminal.getType(), equipmentTerminal.getI(), equipmentTerminal.getJ(), equipmentTerminal.getK(), equipmentTerminal.getId()); - nodeBreakerExport.getEquipmentIdBusBus(getNodeBreakerEquipmentIdBus(equipmentId, equipmentTerminal.getI())).ifPresent(equipmentTerminal::setI); - nodeBreakerExport.getEquipmentIdBusBus(getNodeBreakerEquipmentIdBus(equipmentId, equipmentTerminal.getJ())).ifPresent(equipmentTerminal::setJ); - nodeBreakerExport.getEquipmentIdBusBus(getNodeBreakerEquipmentIdBus(equipmentId, equipmentTerminal.getK())).ifPresent(equipmentTerminal::setK); - }); + // Always are created to avoid changing the id of lines, twoWindingsTransformers and threeWindingsTransformers + // the id must be created with the sorted buses if we want to obtain the equipment with the equipmentTerminal data + psseSubstation.getEquipmentTerminals().clear(); + psseSubstation.getEquipmentTerminals().addAll(createPsseSubstationEquipmentTerminals(voltageLevel, contextExport)); + } + + private static List createPsseSubstationEquipmentTerminals(VoltageLevel voltageLevel, ContextExport contextExport) { + List equipmentTerminals = new ArrayList<>(); + + getEquipmentListToBeExported(voltageLevel).forEach(equipmentId -> getEquipmentNodes(voltageLevel, equipmentId).forEach(node -> { + int selectedNode = contextExport.getNodeBreakerExport().getSelectedNode(voltageLevel, node).orElseThrow(); + List busesList = contextExport.getEquipmentBusesList(equipmentId, voltageLevel, selectedNode); + if (busesList.size() == 3) { + Identifiable identifiable = getIdentifiable(voltageLevel, equipmentId); + PsseSubstation.PsseSubstationEquipmentTerminal equipmentTerminal = new PsseSubstationEquipmentTerminal(); + equipmentTerminal.setNi(selectedNode); + equipmentTerminal.setType(getPsseEquipmentType(identifiable)); + equipmentTerminal.setId(contextExport.getEquipmentCkt(equipmentId, identifiable.getType(), busesList.get(0), busesList.get(1), busesList.get(2))); + equipmentTerminal.setI(busesList.get(0)); + equipmentTerminal.setJ(busesList.get(1)); + equipmentTerminal.setK(busesList.get(2)); + + equipmentTerminals.add(equipmentTerminal); + } else { + throw new PsseException("Unexpected size of the busesList. Must be 3 and it is " + busesList.size()); + } + })); + return equipmentTerminals; + } + + private static Identifiable getIdentifiable(VoltageLevel voltageLevel, String identifiableId) { + Identifiable identifiable = voltageLevel.getNetwork().getIdentifiable(identifiableId); + if (identifiable != null) { + return identifiable; + } else { + throw new PsseException("Unexpected identifiableId: " + identifiableId); + } } private final PsseBus psseBus; diff --git a/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm index 41606c585d8..16285dad508 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm @@ -114,7 +114,7 @@ - + @@ -131,8 +131,8 @@ - - + + @@ -149,7 +149,7 @@ - + @@ -171,8 +171,8 @@ - - + + diff --git a/psse/psse-converter/src/test/resources/IEEE_24_bus_updated_exported.raw b/psse/psse-converter/src/test/resources/IEEE_24_bus_updated_exported.raw index 156618012c4..0f1a1a9731b 100644 --- a/psse/psse-converter/src/test/resources/IEEE_24_bus_updated_exported.raw +++ b/psse/psse-converter/src/test/resources/IEEE_24_bus_updated_exported.raw @@ -1,29 +1,29 @@ 0,100.0,33,0.0,0.0,60.0 -1,'1 ',138.0,3,1,1,1,1.01,0.0,1.1,0.9,1.1,0.9 -2,'2 ',138.0,2,1,1,1,1.0078083,0.010302,1.1,0.9,1.1,0.9 +1,'1 ',138.0,1,1,1,1,1.01,0.0,1.1,0.9,1.1,0.9 +2,'2 ',138.0,1,1,1,1,1.0078083,0.010302,1.1,0.9,1.1,0.9 3,'3 ',138.0,1,1,1,1,0.8725895,10.854671999999999,1.1,0.9,1.1,0.9 4,'4 ',138.0,1,1,1,1,0.8960821000000001,-0.420867,1.1,0.9,1.1,0.9 5,'5 ',138.0,1,1,1,1,0.9361993000000001,-0.225937,1.1,0.9,1.1,0.9 6,'6 ',138.0,1,1,1,1,0.9174536999999999,0.394102,1.1,0.9,1.1,0.9 -7,'7 ',138.0,2,1,1,1,0.8046468000000001,-0.586911,1.1,0.9,1.1,0.9 +7,'7 ',138.0,1,1,1,1,0.8046468000000001,-0.586911,1.1,0.9,1.1,0.9 8,'8 ',230.0,1,1,1,1,0.8138681,-0.877892,1.1,0.9,1.1,0.9 9,'9 ',138.0,1,1,1,1,0.8436328000000001,5.032729,1.1,0.9,1.1,0.9 10,'10 ',138.0,1,1,1,1,0.8909816,3.754978,1.1,0.9,1.1,0.9 11,'11 ',230.0,1,1,1,1,0.8448145,12.753775,1.1,0.9,1.1,0.9 12,'12 ',230.0,1,1,1,1,0.8485616,11.888811,1.1,0.9,1.1,0.9 -13,'13 ',230.0,2,1,1,1,0.8456831,15.589552,1.1,0.9,1.1,0.9 -14,'14 ',230.0,2,1,1,1,0.8451174999999999,18.92841,1.1,0.9,1.1,0.9 -15,'15 ',230.0,2,1,1,1,0.8942742,33.521496,1.1,0.9,1.1,0.9 -16,'16 ',230.0,2,1,1,1,0.8710441999999999,27.333125,1.1,0.9,1.1,0.9 +13,'13 ',230.0,1,1,1,1,0.8456831,15.589552,1.1,0.9,1.1,0.9 +14,'14 ',230.0,1,1,1,1,0.8451174999999999,18.92841,1.1,0.9,1.1,0.9 +15,'15 ',230.0,1,1,1,1,0.8942742,33.521496,1.1,0.9,1.1,0.9 +16,'16 ',230.0,1,1,1,1,0.8710441999999999,27.333125,1.1,0.9,1.1,0.9 17,'17 ',230.0,1,1,1,1,0.9049095,32.357875,1.1,0.9,1.1,0.9 -18,'18 ',230.0,2,1,1,1,0.9102625,34.214053,1.1,0.9,1.1,0.9 +18,'18 ',230.0,1,1,1,1,0.9102625,34.214053,1.1,0.9,1.1,0.9 19,'19 ',230.0,1,1,1,1,0.8606714999999999,24.021133000000003,1.1,0.9,1.1,0.9 20,'20 ',230.0,1,1,1,1,0.8581869,22.534312,1.1,0.9,1.1,0.9 -21,'21 ',230.0,2,1,1,1,0.9205443,35.989936,1.1,0.9,1.1,0.9 +21,'21 ',230.0,1,1,1,1,0.9205443,35.989936,1.1,0.9,1.1,0.9 22,'22 ',230.0,2,1,1,1,1.01,37.853184,1.1,0.9,1.1,0.9 -23,'23 ',230.0,2,1,1,1,0.8585606,22.279994000000002,1.1,0.9,1.1,0.9 +23,'23 ',230.0,1,1,1,1,0.8585606,22.279994000000002,1.1,0.9,1.1,0.9 24,'24 ',230.0,1,1,1,1,0.8637621000000001,25.043152000000003,1.1,0.9,1.1,0.9 0 / END OF BUS DATA, BEGIN LOAD DATA 2,'1 ',0,1,1,97.0,20.0,0.0,0.0,0.0,0.0,1,1 diff --git a/psse/psse-converter/src/test/resources/RawCaseWithSpecialCharacters_exported.raw b/psse/psse-converter/src/test/resources/RawCaseWithSpecialCharacters_exported.raw index 0c57f438990..55921ea55e0 100644 --- a/psse/psse-converter/src/test/resources/RawCaseWithSpecialCharacters_exported.raw +++ b/psse/psse-converter/src/test/resources/RawCaseWithSpecialCharacters_exported.raw @@ -7,7 +7,7 @@ 4,'Bus4)=? ',500.0,1,1,1,1,1.01691,-11.4772,1.1,0.9,1.1,0.9 5,'Bus5¿¡{ ',500.0,1,1,1,1,0.97278,-42.3008,1.1,0.9,1.1,0.9 6,'Bus6}[] ',500.0,3,1,1,1,1.0,-57.1678,1.1,0.9,1.1,0.9 -7,'Bus7<>: ',16.0,2,1,1,1,1.0,0.0,1.1,0.9,1.1,0.9 +7,'Bus7<>: ',16.0,1,1,1,1,1.0,0.0,1.1,0.9,1.1,0.9 0 / END OF BUS DATA, BEGIN LOAD DATA 4,'1 ',1,1,1,1400.0,100.0,0.0,0.0,0.0,0.0,1,1 5,'1 ',1,1,1,2000.0,100.0,0.0,0.0,0.0,0.0,1,1 diff --git a/psse/psse-converter/src/test/resources/SwitchedShunt_exported.raw b/psse/psse-converter/src/test/resources/SwitchedShunt_exported.raw index d139374f09f..fe290e32f62 100644 --- a/psse/psse-converter/src/test/resources/SwitchedShunt_exported.raw +++ b/psse/psse-converter/src/test/resources/SwitchedShunt_exported.raw @@ -7,7 +7,7 @@ 4,'4 ',500.0,1,1,1,1,1.01691,-11.4772,1.1,0.9,1.1,0.9 5,'5 ',500.0,1,1,1,1,0.97278,-42.3008,1.1,0.9,1.1,0.9 6,'6 ',500.0,3,1,1,1,1.0,-57.1678,1.1,0.9,1.1,0.9 -7,'7 ',16.0,2,1,1,1,1.0,0.0,1.1,0.9,1.1,0.9 +7,'7 ',16.0,1,1,1,1,1.0,0.0,1.1,0.9,1.1,0.9 0 / END OF BUS DATA, BEGIN LOAD DATA 4,'1 ',1,1,1,1400.0,100.0,0.0,0.0,0.0,0.0,1,1 5,'1 ',1,1,1,2000.0,100.0,0.0,0.0,0.0,0.0,1,1 diff --git a/psse/psse-converter/src/test/resources/ThreeMIB_T3W_modified_exported.raw b/psse/psse-converter/src/test/resources/ThreeMIB_T3W_modified_exported.raw index 25db92d8b27..19c53ea6435 100644 --- a/psse/psse-converter/src/test/resources/ThreeMIB_T3W_modified_exported.raw +++ b/psse/psse-converter/src/test/resources/ThreeMIB_T3W_modified_exported.raw @@ -7,7 +7,7 @@ 4,'4 ',500.0,1,1,1,1,1.01691,-11.4772,1.1,0.9,1.1,0.9 5,'5 ',500.0,1,1,1,1,0.97278,-42.3008,1.1,0.9,1.1,0.9 6,'6 ',500.0,3,1,1,1,1.0,-57.1678,1.1,0.9,1.1,0.9 -7,'7 ',16.0,2,1,1,1,1.0,0.0,1.1,0.9,1.1,0.9 +7,'7 ',16.0,1,1,1,1,1.0,0.0,1.1,0.9,1.1,0.9 0 / END OF BUS DATA, BEGIN LOAD DATA 4,'1 ',1,1,1,1400.0,100.0,0.0,0.0,0.0,0.0,1,1 5,'1 ',1,1,1,2000.0,100.0,0.0,0.0,0.0,0.0,1,1 diff --git a/psse/psse-converter/src/test/resources/ThreeMIB_T3W_phase_exported.raw b/psse/psse-converter/src/test/resources/ThreeMIB_T3W_phase_exported.raw index f3f1f385d2d..20aaa6e8e0c 100644 --- a/psse/psse-converter/src/test/resources/ThreeMIB_T3W_phase_exported.raw +++ b/psse/psse-converter/src/test/resources/ThreeMIB_T3W_phase_exported.raw @@ -7,7 +7,7 @@ 4,'4 ',500.0,1,1,1,1,1.01691,-11.4772,1.1,0.9,1.1,0.9 5,'5 ',500.0,1,1,1,1,0.97278,-42.3008,1.1,0.9,1.1,0.9 6,'6 ',500.0,3,1,1,1,1.0,-57.1678,1.1,0.9,1.1,0.9 -7,'7 ',16.0,2,1,1,1,1.0,0.0,1.1,0.9,1.1,0.9 +7,'7 ',16.0,1,1,1,1,1.0,0.0,1.1,0.9,1.1,0.9 0 / END OF BUS DATA, BEGIN LOAD DATA 4,'1 ',1,1,1,1400.0,100.0,0.0,0.0,0.0,0.0,1,1 5,'1 ',1,1,1,2000.0,100.0,0.0,0.0,0.0,0.0,1,1 diff --git a/psse/psse-converter/src/test/resources/TwoWindingsTransformerPhase_exported.raw b/psse/psse-converter/src/test/resources/TwoWindingsTransformerPhase_exported.raw index 2b2e10f0a72..12a84f0a748 100644 --- a/psse/psse-converter/src/test/resources/TwoWindingsTransformerPhase_exported.raw +++ b/psse/psse-converter/src/test/resources/TwoWindingsTransformerPhase_exported.raw @@ -2,7 +2,7 @@ 08/19/93 UW ARCHIVE 100.0 1962 W IEEE 14 Bus Test Case 1,'Bus 1 ',138.0,3,1,1,1,1.06,0.0 -2,'Bus 2 ',138.0,2,1,1,1,1.0579,-4.27 +2,'Bus 2 ',138.0,1,1,1,1,1.0579,-4.27 0 / END OF BUS DATA, BEGIN LOAD DATA 2,'1 ',1,1,1,21.7,12.7,0.0,0.0,0.0,-0.0,1,1 0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA diff --git a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm index cdff2b2aa6c..c8f3207052d 100644 --- a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm +++ b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm @@ -16,7 +16,7 @@ - + @@ -99,11 +99,11 @@ - + - + diff --git a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw index afa7fa497f7..120329c0f3b 100644 --- a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw +++ b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw @@ -9,13 +9,13 @@ 5,'Bus 5 ',138.0,1,1,1,1,1.0,0.0 6,'Bus 1-6 ',138.0,3,1,1,1,1.0,0.0 7,'Bus 2-7 ',138.0,1,1,1,1,1.0,0.0 -8,'Bus 2-8 ',138.0,1,1,1,1,1.0,0.0 -9,'Bus 3-9 ',45.0,1,1,1,1,1.0,0.0 -10,'Bus 3-10 ',45.0,1,1,1,1,1.0,0.0 -11,'Bus 4-11 ',21.0,1,1,1,1,1.0,0.0 -12,'Bus 4-12 ',21.0,1,1,1,1,1.0,0.0 +8,'Bus 2-8 ',138.0,4,1,1,1,0.0,0.0 +9,'Bus 3-9 ',45.0,4,1,1,1,0.0,0.0 +10,'Bus 3-10 ',45.0,4,1,1,1,0.0,0.0 +11,'Bus 4-11 ',21.0,4,1,1,1,0.0,0.0 +12,'Bus 4-12 ',21.0,4,1,1,1,0.0,0.0 13,'Bus 5-13 ',138.0,1,1,1,1,1.0,0.0 -14,'Bus 5-14 ',138.0,1,1,1,1,1.0,0.0 +14,'Bus 5-14 ',138.0,4,1,1,1,0.0,0.0 0 / END OF BUS DATA, BEGIN LOAD DATA 8,'1 ',0,1,1,21.7,12.7,0.0,0.0,0.0,-0.0,1,1 10,'1 ',0,1,1,94.2,19.0,0.0,0.0,0.0,-0.0,1,1 @@ -84,7 +84,7 @@ 1,'NB1',2,1,1.0,0.0 2,'NB2',7,1,1.0,0.0 3,'NLINE',2,1,1.0,0.0 -4,'NLOAD',8,1,1.0,0.0 +4,'NLOAD',8,0,1.0,0.0 5,'NFSHUNT',7,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA 1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 @@ -99,10 +99,10 @@ 3,'STATION 3',0.0,0.0,0.1 / BEGIN SUBSTATION NODE DATA 1,'NB1',3,1,1.0,0.0 -2,'NB2',9,1,1.0,0.0 +2,'NB2',9,0,1.0,0.0 3,'NT2W',3,1,1.0,0.0 4,'NT3W',3,1,1.0,0.0 -5,'NLOAD',10,1,1.0,0.0 +5,'NLOAD',10,0,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA 1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 1,3,'1 ','Sw-T2w',2,1,1,0.0,0.0,0.0,0.0 @@ -116,9 +116,9 @@ 4,'STATION 4',0.0,0.0,0.1 / BEGIN SUBSTATION NODE DATA 1,'NB1',4,1,1.0,0.0 -2,'NB2',11,1,1.0,0.0 +2,'NB2',11,0,1.0,0.0 3,'NT3W',4,1,1.0,0.0 -4,'NLOAD',12,1,1.0,0.0 +4,'NLOAD',12,0,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA 1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 1,3,'1 ','Sw-T3w',2,1,1,0.0,0.0,0.0,0.0 @@ -132,7 +132,7 @@ 1,'NB1',5,1,1.0,0.0 2,'NB2',13,1,1.0,0.0 3,'NDCLINE',5,1,1.0,0.0 -4,'NLOAD',14,1,1.0,0.0 +4,'NLOAD',14,0,1.0,0.0 5,'NSSHUNT',13,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA 1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 diff --git a/psse/psse-converter/src/test/resources/parallelTwoTerminalDcBetweenSameAcBuses.xiidm b/psse/psse-converter/src/test/resources/parallelTwoTerminalDcBetweenSameAcBuses.xiidm index f3f7555c4ea..626e8960cdc 100644 --- a/psse/psse-converter/src/test/resources/parallelTwoTerminalDcBetweenSameAcBuses.xiidm +++ b/psse/psse-converter/src/test/resources/parallelTwoTerminalDcBetweenSameAcBuses.xiidm @@ -38,8 +38,8 @@ - - + + @@ -98,8 +98,8 @@ - - + + @@ -177,8 +177,8 @@ - - + + diff --git a/psse/psse-converter/src/test/resources/remoteControl_updated_exported.raw b/psse/psse-converter/src/test/resources/remoteControl_updated_exported.raw index 31d11858b55..2727888a544 100644 --- a/psse/psse-converter/src/test/resources/remoteControl_updated_exported.raw +++ b/psse/psse-converter/src/test/resources/remoteControl_updated_exported.raw @@ -6,7 +6,7 @@ IEEE 14 Bus Test Case 3 'Bus 3' 230.0 2 1 1 1 1.01 -10.89084078 1.1 0.9 1.1 0.9 4 'Bus 4' 230.0 1 1 1 1 1.05105699 -8.57388999 1.1 0.9 1.1 0.9 5 'Bus 5' 230.0 1 1 1 1 1.01 -6.28249254 1.1 0.9 1.1 0.9 -6 'Bus 6' 110.0 2 1 1 1 0.76525721 -8.23300073 1.1 0.9 1.1 0.9 +6 'Bus 6' 110.0 1 1 1 1 0.76525721 -8.23300073 1.1 0.9 1.1 0.9 7 'Bus 7' 110.0 1 1 1 1 1.35886657 -8.57388999 1.1 0.9 1.1 0.9 8 'Bus 8' 110.0 1 1 1 1 1.11028739 -15.7635741 1.1 0.9 1.1 0.9 9 'Bus 9' 20.0 1 1 1 1 1.19041863 -20.324152 1.1 0.9 1.1 0.9 diff --git a/psse/psse-converter/src/test/resources/twoTerminalDc.xiidm b/psse/psse-converter/src/test/resources/twoTerminalDc.xiidm index 42afdd0d9c1..0fc3a63a398 100644 --- a/psse/psse-converter/src/test/resources/twoTerminalDc.xiidm +++ b/psse/psse-converter/src/test/resources/twoTerminalDc.xiidm @@ -38,7 +38,7 @@ - + @@ -97,7 +97,7 @@ - + @@ -175,7 +175,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/twoTerminalDc_with_negative_setvl.xiidm b/psse/psse-converter/src/test/resources/twoTerminalDc_with_negative_setvl.xiidm index 9bab61d29b4..3bd7dfc812a 100644 --- a/psse/psse-converter/src/test/resources/twoTerminalDc_with_negative_setvl.xiidm +++ b/psse/psse-converter/src/test/resources/twoTerminalDc_with_negative_setvl.xiidm @@ -38,7 +38,7 @@ - + @@ -97,7 +97,7 @@ - + @@ -175,7 +175,7 @@ - + diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PssePowerFlowModel.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PssePowerFlowModel.java index ceb17920567..6b6c1c5d66d 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PssePowerFlowModel.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PssePowerFlowModel.java @@ -74,6 +74,11 @@ public void addBuses(List buses) { this.buses.addAll(modelled(buses)); } + public void replaceAllBuses(List buses) { + this.buses.clear(); + this.buses.addAll(modelled(buses)); + } + public List getBuses() { return Collections.unmodifiableList(buses); } From 24711a139110488fc2270aca02d9dc4dfa9f847f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Marqu=C3=A9s?= Date: Mon, 17 Jun 2024 13:45:05 +0200 Subject: [PATCH 12/22] Fix code smells MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- .../powsybl/psse/converter/AbstractConverter.java | 15 +++++++++------ .../SwitchedShuntCompensatorConverter.java | 6 ++++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java index 3da14adff69..6822e8e89bc 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java @@ -27,6 +27,9 @@ */ public abstract class AbstractConverter { + private static final String FIXED_SHUNT_TAG = "-SH"; + private static final String SWITCHED_SHUNT_TAG = "-SwSH"; + enum PsseEquipmentType { PSSE_LOAD("L"), PSSE_FIXED_SHUNT("F"), @@ -82,7 +85,7 @@ static OptionalInt extractBusNumber(String configuredBusId) { } static String getFixedShuntId(int busI, String fixedShuntId) { - return getBusId(busI) + "-SH" + fixedShuntId; + return getBusId(busI) + FIXED_SHUNT_TAG + fixedShuntId; } static String getGeneratorId(int busI, String generatorId) { @@ -98,7 +101,7 @@ static String getLoadId(int busI, String loadId) { } static String getSwitchedShuntId(int busI, String id) { - return getBusId(busI) + "-SwSH" + id; + return getBusId(busI) + SWITCHED_SHUNT_TAG + id; } static String getTransformerId(int busI, int busJ, String ckt) { @@ -138,8 +141,8 @@ public static Optional extractCkt(String identifiableId, IdentifiableTyp case LOAD -> extractCkt(identifiableId, "-L"); case GENERATOR -> extractCkt(identifiableId, "-G"); case SHUNT_COMPENSATOR -> { - Optional ckt = extractCkt(identifiableId, "-SH"); - yield ckt.isPresent() ? ckt : extractCkt(identifiableId, "-SwSH"); + Optional ckt = extractCkt(identifiableId, FIXED_SHUNT_TAG); + yield ckt.isPresent() ? ckt : extractCkt(identifiableId, SWITCHED_SHUNT_TAG); } case HVDC_LINE -> Optional.of(extractTwoTerminalDcName(identifiableId)); default -> throw new PsseException("unexpected identifiableType: " + identifiableType.name()); @@ -176,9 +179,9 @@ static String getPsseEquipmentType(Identifiable identifiable) { } private static boolean isFixedShunt(ShuntCompensator shunt) { - if (shunt.getId().contains("-SH")) { + if (shunt.getId().contains(FIXED_SHUNT_TAG)) { return true; - } else if (shunt.getId().contains("-SwSH")) { + } else if (shunt.getId().contains(SWITCHED_SHUNT_TAG)) { return false; } else { return shunt.getMaximumSectionCount() == 1 diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java index 832a6de23e5..b6d79d6c25a 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java @@ -178,8 +178,10 @@ private static List defineShuntBlocks(PsseSwitchedShunt psseSwitched psseReactorBlocks.sort(Comparator.comparing(ShuntBlock::getB).reversed()); psseCapacitorBlocks.sort(Comparator.comparing(ShuntBlock::getB)); - LOGGER.warn("Switched combination not exactly supported ({})", - getSwitchedShuntId(psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version))); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn("Switched combination not exactly supported ({})", + getSwitchedShuntId(psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version))); + } } double bAdd = 0.0; From ff611be815eba7582212eb77b7f0ce910b17fd14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Marqu=C3=A9s?= Date: Mon, 17 Jun 2024 14:14:49 +0200 Subject: [PATCH 13/22] Reduce method complexity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Antonio Marqués --- .../SwitchedShuntCompensatorConverter.java | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java index b6d79d6c25a..5c07c7f8c45 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java @@ -186,27 +186,13 @@ private static List defineShuntBlocks(PsseSwitchedShunt psseSwitched double bAdd = 0.0; List shuntBlocks = new ArrayList<>(); - if (!psseReactorBlocks.isEmpty()) { - for (ShuntBlock psseReactorBlock : psseReactorBlocks) { - for (int j = 0; j < psseReactorBlock.getN(); j++) { - bAdd = bAdd + psseReactorBlock.getB(); - shuntBlocks.add(new ShuntBlock(1, 1, bAdd)); - } - } - } + bAdd = addShuntBlocks(psseReactorBlocks, bAdd, shuntBlocks); if (psseSwitchedShunt.getAdjm() == 1) { bAdd = 0.0; } - if (!psseCapacitorBlocks.isEmpty()) { - for (ShuntBlock psseCapacitorBlock : psseCapacitorBlocks) { - for (int j = 0; j < psseCapacitorBlock.getN(); j++) { - bAdd = bAdd + psseCapacitorBlock.getB(); - shuntBlocks.add(new ShuntBlock(1, 1, bAdd)); - } - } - } + addShuntBlocks(psseCapacitorBlocks, bAdd, shuntBlocks); // Add the zero block, shunt disconnected shuntBlocks.add(new ShuntBlock(1, 1, 0.0)); @@ -216,6 +202,19 @@ private static List defineShuntBlocks(PsseSwitchedShunt psseSwitched return shuntBlocks; } + private static double addShuntBlocks(List psseShuntBlocks, double bAddInitial, List shuntBlocks) { + double bAdd = bAddInitial; + if (!psseShuntBlocks.isEmpty()) { + for (ShuntBlock psseCapacitorBlock : psseShuntBlocks) { + for (int j = 0; j < psseCapacitorBlock.getN(); j++) { + bAdd = bAdd + psseCapacitorBlock.getB(); + shuntBlocks.add(new ShuntBlock(1, 1, bAdd)); + } + } + } + return bAdd; + } + // defined blocks can be reactors (< 0) or / and capacitors ( > 0) private static List collectShuntBlocks(PsseSwitchedShunt psseSwitchedShunt, PsseVersion version) { List shuntBlocks = new ArrayList<>(); From 916148bb80a6a5641e526057c224698985cc3242 Mon Sep 17 00:00:00 2001 From: marquesja1 Date: Fri, 12 Jul 2024 09:28:09 +0200 Subject: [PATCH 14/22] Remove setCont Signed-off-by: marquesja1 --- .../com/powsybl/psse/model/pf/PsseTransformerWinding.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformerWinding.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformerWinding.java index 2cd22fb3b8d..f4ba479fd04 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformerWinding.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/PsseTransformerWinding.java @@ -94,10 +94,6 @@ public int getCod() { return cod; } - public void setCont(int cont) { - this.cont = cont; - } - public int getCont() { return cont; } From 93b063b7683ea469eea513e1cd41af451e6782e0 Mon Sep 17 00:00:00 2001 From: marquesja1 Date: Fri, 12 Jul 2024 09:46:24 +0200 Subject: [PATCH 15/22] Fix unitary results Signed-off-by: marquesja1 --- .../src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm | 2 +- .../src/test/resources/five_bus_nodeBreaker_rev35.xiidm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm index 1baa3a1b5b5..a8aac76d202 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm @@ -1,5 +1,5 @@ - + diff --git a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm index c8f3207052d..aa8628bc9b3 100644 --- a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm +++ b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm @@ -1,5 +1,5 @@ - + From c560041d4bbf18e88bb5318d61dd4421c9c6dde3 Mon Sep 17 00:00:00 2001 From: marquesja1 Date: Tue, 6 Aug 2024 13:56:43 +0200 Subject: [PATCH 16/22] Fix typo Signed-off-by: marquesja1 --- .../java/com/powsybl/psse/model/io/AbstractRecordGroup.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/io/AbstractRecordGroup.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/io/AbstractRecordGroup.java index d7040d38cfe..eb52b66b016 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/io/AbstractRecordGroup.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/io/AbstractRecordGroup.java @@ -74,7 +74,7 @@ public RecordGroupIdentification getIdentification() { /** * Some record groups have a fine level of detail on which field names should be saved in the context depending on each record - * This function will be override for Transformer data: + * This function will be overridden for Transformer data: * We want to save different field names for transformers with 2 / 3 windings * * @param object the object to be evaluated for a specific record group identification From f740d86940d6ae45ff91ea4b91bbe58c5fc37338 Mon Sep 17 00:00:00 2001 From: marquesja1 Date: Tue, 6 Aug 2024 14:21:46 +0200 Subject: [PATCH 17/22] Adjustments after testing a private real case Signed-off-by: marquesja1 --- .../psse/converter/GeneratorConverter.java | 2 +- .../powsybl/psse/model/io/LegacyTextReader.java | 16 ++++++++++++++++ .../psse/model/pf/io/CaseIdentificationData.java | 2 +- .../io/MultiTerminalDcTransmissionLineData.java | 4 ++-- .../powsybl/psse/model/pf/io/SubstationData.java | 8 ++++---- .../psse/model/pf/io/TransformerData.java | 4 ++-- .../pf/io/TwoTerminalDcTransmissionLineData.java | 4 ++-- ...ageSourceConverterDcTransmissionLineData.java | 4 ++-- 8 files changed, 30 insertions(+), 14 deletions(-) diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java index 395af5e4e51..916db0d7002 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java @@ -119,7 +119,7 @@ private static Terminal defineRegulatingTerminal(PsseGenerator psseGenerator, Ne } } } - if (regulatingTerminal == null) { + if (regulatingTerminal == null && psseGenerator.getI() != psseGenerator.getIreg()) { String generatorId = getGeneratorId(psseGenerator.getI(), psseGenerator.getId()); LOGGER.warn("Generator {}. Regulating terminal is not assigned as the bus is isolated", generatorId); } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/io/LegacyTextReader.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/io/LegacyTextReader.java index 7b6561bc915..8e85526258e 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/io/LegacyTextReader.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/io/LegacyTextReader.java @@ -90,6 +90,14 @@ public String readLine() throws IOException { return reader.readLine(); } + public String readUntilFindingARecordLineNotEmpty() throws IOException { + String line = readRecordLine(); + while (emptyLine(line)) { + line = readRecordLine(); + } + return line; + } + // Read a line that contains a record // Removes comments and normalizes spaces in unquoted areas public String readRecordLine() throws IOException { @@ -97,6 +105,9 @@ public String readRecordLine() throws IOException { if (line == null) { throw new PsseException("PSSE. Unexpected end of file"); } + if (isRecordLineDefiningTheAttributeFields(line)) { + return ""; // an empty line must be returned + } StringBuilder newLine = new StringBuilder(); Matcher m = FileFormat.LEGACY_TEXT_QUOTED_OR_WHITESPACE.matcher(removeComment(line)); while (m.find()) { @@ -112,6 +123,11 @@ public String readRecordLine() throws IOException { return newLine.toString().trim(); } + // all the lines beginning with "@!" are record lines defining the attribute fields + private static boolean isRecordLineDefiningTheAttributeFields(String line) { + return line.length() >= 2 && line.substring(0, 2).equals("@!"); + } + private static String removeComment(String line) { // Only outside quotes return line.replaceAll("('[^']*')|(^/[^/]*)|(/[^/]*)", "$1$2"); diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/CaseIdentificationData.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/CaseIdentificationData.java index fc881ae2513..f77c021ec13 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/CaseIdentificationData.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/CaseIdentificationData.java @@ -47,7 +47,7 @@ protected CaseIdentificationLegacyText(AbstractRecordGroup read(LegacyTextReader reader, C List linkRecords = new ArrayList<>(); if (!reader.isQRecordFound()) { - String line = reader.readRecordLine(); + String line = reader.readUntilFindingARecordLineNotEmpty(); while (!reader.endOfBlock(line)) { PsseMultiTerminalDcMain main = mainData.readFromStrings(Collections.singletonList(line), context).get(0); addNextNrecords(reader, converterRecords, main.getNconv()); addNextNrecords(reader, busRecords, main.getNdcbs()); addNextNrecords(reader, linkRecords, main.getNdcln()); - line = reader.readRecordLine(); + line = reader.readUntilFindingARecordLineNotEmpty(); PsseMultiTerminalDcTransmissionLine multiTerminal = new PsseMultiTerminalDcTransmissionLine(main); multiTerminalList.add(multiTerminal); diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java index 314044ac7b8..7af624705bc 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/SubstationData.java @@ -52,7 +52,7 @@ public List read(LegacyTextReader reader, Context context) throw List substationList = new ArrayList<>(); if (!reader.isQRecordFound()) { - String line = reader.readRecordLine(); + String line = reader.readUntilFindingARecordLineNotEmpty(); while (!reader.endOfBlock(line)) { PsseSubstationRecord srecord = recordData.readFromStrings(Collections.singletonList(line), context).get(0); @@ -63,7 +63,7 @@ public List read(LegacyTextReader reader, Context context) throw PsseSubstation substation = new PsseSubstation(srecord, nodeList, switchingDeviceList, equipmentTerminalList); substationList.add(substation); - line = reader.readRecordLine(); + line = reader.readUntilFindingARecordLineNotEmpty(); } } @@ -76,7 +76,7 @@ private List readEquipmentTerminalData(LegacyTe List equipmentTerminalTwoBusesRecords = new ArrayList<>(); List equipmentTerminalThreeBusesRecords = new ArrayList<>(); - String line = reader.readRecordLine(); + String line = reader.readUntilFindingARecordLineNotEmpty(); while (!reader.endOfBlock(line)) { PsseSubstationEquipmentTerminalCommonStart commonStart = commonStartData.readFromStrings(Collections.singletonList(line), context).get(0); if (isOneBus(commonStart.getType())) { @@ -88,7 +88,7 @@ private List readEquipmentTerminalData(LegacyTe } else { throw new PsseException("Unexpected equipment terminal type: " + commonStart.getType()); } - line = reader.readRecordLine(); + line = reader.readUntilFindingARecordLineNotEmpty(); } List equipmentTerminalList = new SubstationEquipmentTerminalDataOneBus().readFromStrings(equipmentTerminalOneBusRecords, context); diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/TransformerData.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/TransformerData.java index 58c02fbfcb1..782f3e95b19 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/TransformerData.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/TransformerData.java @@ -64,7 +64,7 @@ public List read(LegacyTextReader reader, Context context) thro List impedanceRecords = new ArrayList<>(); List windingRecords = new ArrayList<>(); if (!reader.isQRecordFound()) { - String line = reader.readRecordLine(); + String line = reader.readUntilFindingARecordLineNotEmpty(); while (!reader.endOfBlock(line)) { mainRecords.add(line); impedanceRecords.add(reader.readRecordLine()); @@ -73,7 +73,7 @@ public List read(LegacyTextReader reader, Context context) thro if (is3Winding(line)) { windingRecords.add(reader.readRecordLine()); } - line = reader.readRecordLine(); + line = reader.readUntilFindingARecordLineNotEmpty(); } } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/TwoTerminalDcTransmissionLineData.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/TwoTerminalDcTransmissionLineData.java index 661b651f7a8..3b526b62e0e 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/TwoTerminalDcTransmissionLineData.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/TwoTerminalDcTransmissionLineData.java @@ -56,12 +56,12 @@ public List read(LegacyTextReader reader, Con List mainRecords = new ArrayList<>(); List converterRecords = new ArrayList<>(); if (!reader.isQRecordFound()) { - String line = reader.readRecordLine(); + String line = reader.readUntilFindingARecordLineNotEmpty(); while (!reader.endOfBlock(line)) { mainRecords.add(line); converterRecords.add(reader.readRecordLine()); converterRecords.add(reader.readRecordLine()); - line = reader.readRecordLine(); + line = reader.readUntilFindingARecordLineNotEmpty(); } } diff --git a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/VoltageSourceConverterDcTransmissionLineData.java b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/VoltageSourceConverterDcTransmissionLineData.java index 821088b81d9..5e7b4876a44 100644 --- a/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/VoltageSourceConverterDcTransmissionLineData.java +++ b/psse/psse-model/src/main/java/com/powsybl/psse/model/pf/io/VoltageSourceConverterDcTransmissionLineData.java @@ -52,12 +52,12 @@ public List read(LegacyTextReader List mainRecords = new ArrayList<>(); List converterRecords = new ArrayList<>(); if (!reader.isQRecordFound()) { - String line = reader.readRecordLine(); + String line = reader.readUntilFindingARecordLineNotEmpty(); while (!reader.endOfBlock(line)) { mainRecords.add(line); converterRecords.add(reader.readRecordLine()); converterRecords.add(reader.readRecordLine()); - line = reader.readRecordLine(); + line = reader.readUntilFindingARecordLineNotEmpty(); } } From f2e6b48b1b9fb714f68446e40382e1b598f44974 Mon Sep 17 00:00:00 2001 From: marquesja1 Date: Fri, 9 Aug 2024 11:44:51 +0200 Subject: [PATCH 18/22] Adjustments after testing with a private real case Signed-off-by: marquesja1 --- .../iidm/network/util/ContainersMapping.java | 28 +- .../psse/converter/AbstractConverter.java | 170 ++------ .../powsybl/psse/converter/BusConverter.java | 124 +----- .../powsybl/psse/converter/ContextExport.java | 272 ++----------- .../FixedShuntCompensatorConverter.java | 4 +- .../psse/converter/GeneratorConverter.java | 15 +- .../powsybl/psse/converter/LineConverter.java | 6 +- .../powsybl/psse/converter/LoadConverter.java | 8 +- .../psse/converter/NodeBreakerValidation.java | 117 +++--- .../powsybl/psse/converter/PsseExporter.java | 21 +- .../powsybl/psse/converter/PsseImporter.java | 9 +- .../SwitchedShuntCompensatorConverter.java | 14 +- .../psse/converter/TransformerConverter.java | 47 +-- .../converter/TwoTerminalDcConverter.java | 15 +- .../psse/converter/VoltageLevelConverter.java | 365 +++++++----------- .../src/test/resources/IEEE_118_bus.xiidm | 138 +++---- .../src/test/resources/IEEE_14_bus.xiidm | 34 +- .../IEEE_14_bus_nodeBreaker_rev35.xiidm | 42 +- ...s_nodeBreaker_rev35_split_bus_exported.raw | 32 +- .../IEEE_14_buses_duplicate_ids.xiidm | 38 +- .../IEEE_14_buses_duplicate_ids_rev35.xiidm | 36 +- .../resources/IEEE_14_buses_zip_load.xiidm | 34 +- .../resources/IEEE_14_isolated_buses.xiidm | 34 +- .../src/test/resources/IEEE_24_bus.xiidm | 34 +- .../src/test/resources/IEEE_57_bus.xiidm | 144 +++---- .../src/test/resources/IsolatedSlackBus.xiidm | 4 +- .../RawCaseWithSpecialCharacters.xiidm | 6 +- .../src/test/resources/SwitchedShunt.xiidm | 6 +- .../SwitchedShuntWithZeroVswlo.xiidm | 6 +- .../resources/ThreeMIB_T3W_modified.xiidm | 6 +- .../test/resources/ThreeMIB_T3W_phase.xiidm | 6 +- .../resources/TransformersWithZeroNomV.xiidm | 6 +- .../TwoWindingsTransformerPhase.xiidm | 6 +- .../five_bus_nodeBreaker_rev35.xiidm | 20 +- ...nodeBreaker_rev35_split_buses_exported.raw | 73 ++-- .../src/test/resources/remoteControl.xiidm | 8 +- 36 files changed, 678 insertions(+), 1250 deletions(-) diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/ContainersMapping.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/ContainersMapping.java index fad62515695..004f1d9358a 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/ContainersMapping.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/ContainersMapping.java @@ -64,11 +64,21 @@ public static ContainersMapping create(List buses, List branches, T throw new PowsyblException("Deprecated. Not used anymore"); } + public static ContainersMapping create(List buses, List branches, + ToIntFunction busToNum, ToIntFunction branchToNum1, ToIntFunction branchToNum2, + Predicate branchToIsZeroImpedance, Predicate branchToIsTransformer, + ToDoubleFunction busToNominalVoltage, Function, String> busesToVoltageLevelId, + Function, String> busesToSubstationId) { + + return create(buses, branches, busToNum, branchToNum1, branchToNum2, branchToIsZeroImpedance, branchToIsTransformer, busToNominalVoltage, + null, busesToVoltageLevelId, busesToSubstationId); + } + public static ContainersMapping create(List buses, List branches, ToIntFunction busToNum, ToIntFunction branchToNum1, ToIntFunction branchToNum2, Predicate branchToIsZeroImpedance, Predicate branchToIsTransformer, - ToDoubleFunction busToNominalVoltage, Function, String> busesToVoltageLevelId, - Function, String> busesToSubstationId) { + ToDoubleFunction busToNominalVoltage, ToIntFunction busToSubstationNumber, + Function, String> busesToVoltageLevelId, Function, String> busesToSubstationId) { Objects.requireNonNull(buses); Objects.requireNonNull(branches); @@ -100,7 +110,7 @@ public static ContainersMapping create(List buses, List branches, for (Set busNums : new ConnectivityInspector<>(sGraph).connectedSets()) { createAndMapSubstationAndVoltageLevelsInside(branchToNum1, branchToNum2, branchToIsZeroImpedance, - busToNominalVoltage, busesToVoltageLevelId, busesToSubstationId, busNums, sGraph, containersMapping); + busToNominalVoltage, busToSubstationNumber, busesToVoltageLevelId, busesToSubstationId, busNums, sGraph, containersMapping); } return containersMapping; @@ -108,7 +118,8 @@ public static ContainersMapping create(List buses, List branches, private static void createAndMapSubstationAndVoltageLevelsInside(ToIntFunction branchToNum1, ToIntFunction branchToNum2, Predicate branchToIsZeroImpedance, - ToDoubleFunction busToNominalVoltage, Function, String> busesToVoltageLevelId, + ToDoubleFunction busToNominalVoltage, ToIntFunction busToSubstationNumber, + Function, String> busesToVoltageLevelId, Function, String> busesToSubstationId, Set substationBusNums, Graph sGraph, ContainersMapping containersMapping) { @@ -135,18 +146,21 @@ private static void createAndMapSubstationAndVoltageLevelsInside(ToIntFuncti Map> vls = new HashMap<>(); new ConnectivityInspector<>(vlGraph).connectedSets() - .forEach(voltageLevelIds -> vls.merge(getNominalVoltage(voltageLevelIds, busToNominalVoltage), voltageLevelIds, ContainersMapping::unionSet)); + .forEach(voltageLevelIds -> vls.merge(getNominalVoltage(voltageLevelIds, busToNominalVoltage, busToSubstationNumber), voltageLevelIds, ContainersMapping::unionSet)); vls.values().forEach(voltageLevelIds -> mapSubstationAndVoltageLevel(busesToVoltageLevelId, substationId, voltageLevelIds, containersMapping)); } } - private static String getNominalVoltage(Set voltageLevelIds, ToDoubleFunction busToVoltageLevelNominal) { + // We only consider in the same voltageLevel buses with the same nominal voltage and with the same substationData (only defined in PSSE) + private static String getNominalVoltage(Set voltageLevelIds, ToDoubleFunction busToVoltageLevelNominal, ToIntFunction busToSubstationNumber) { Objects.requireNonNull(busToVoltageLevelNominal); if (voltageLevelIds.isEmpty()) { // should never happen throw new PowsyblException("Unexpected empty connected set"); } - return String.valueOf(busToVoltageLevelNominal.applyAsDouble(voltageLevelIds.iterator().next())); + int bus = voltageLevelIds.iterator().next(); + return busToSubstationNumber == null ? String.valueOf(busToVoltageLevelNominal.applyAsDouble(bus)) : + String.valueOf(busToVoltageLevelNominal.applyAsDouble(voltageLevelIds.iterator().next())) + "-" + busToSubstationNumber.applyAsInt(bus); } private static Set unionSet(Set set1, Set set2) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java index 6822e8e89bc..bf51193a194 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java @@ -69,7 +69,28 @@ Network getNetwork() { } static String getVoltageLevelId(Set busNums) { - return "VL" + busNums.stream().min(Comparator.naturalOrder()).orElseThrow(() -> new PsseException("Unexpected empty busNums")); + if (busNums.isEmpty()) { + throw new PsseException("Unexpected empty busNums"); + } + List sortedBusNums = busNums.stream().sorted().toList(); + String voltageLevelId = "VL" + sortedBusNums.get(0); + for (int i = 1; i < sortedBusNums.size(); i++) { + voltageLevelId = voltageLevelId.concat(String.format("-%d", sortedBusNums.get(i))); + } + return voltageLevelId; + } + + static List extractBusesFromVoltageLevelId(String voltageLevelId) { + List buses = new ArrayList<>(); + if (voltageLevelId.length() <= 2 || !voltageLevelId.startsWith("VL")) { + return buses; + } + List busesText = Arrays.stream(voltageLevelId.substring(2).split("-")).toList(); + if (!busesText.stream().allMatch(busText -> busText.matches("[1-9]\\d*"))) { + return buses; + } + busesText.forEach(busText -> buses.add(Integer.parseInt(busText))); + return buses; } static String getBusId(int busNum) { @@ -77,7 +98,7 @@ static String getBusId(int busNum) { } static OptionalInt extractBusNumber(String configuredBusId) { - if (configuredBusId.length() <= 1) { + if (configuredBusId.length() <= 1 || !configuredBusId.startsWith("B")) { return OptionalInt.empty(); } String busNumber = configuredBusId.substring(1); @@ -118,11 +139,6 @@ static String getTwoTerminalDcId(String name) { return "TwoTerminalDc-" + name; } - public static String extractTwoTerminalDcName(String twoTerminalDcId) { - String name = twoTerminalDcId.replace("TwoTerminalDc-", ""); - return name.substring(0, Math.min(12, name.length())); - } - static String getLccConverterId(Network network, PsseTwoTerminalDcTransmissionLine psseTwoTerminalDc, PsseTwoTerminalDcConverter converter) { return Identifiables.getUniqueId("LccConverter-" + converter.getIp() + "-" + psseTwoTerminalDc.getName(), id -> network.getLccConverterStation(id) != null); } @@ -135,122 +151,10 @@ static String busbarSectionId(String voltageLevelId, int node) { return String.format("%s-Busbar-%d", voltageLevelId, node); } - public static Optional extractCkt(String identifiableId, IdentifiableType identifiableType) { - return switch (identifiableType) { - case SWITCH, LINE, TWO_WINDINGS_TRANSFORMER, THREE_WINDINGS_TRANSFORMER -> extractCkt(identifiableId, "-"); - case LOAD -> extractCkt(identifiableId, "-L"); - case GENERATOR -> extractCkt(identifiableId, "-G"); - case SHUNT_COMPENSATOR -> { - Optional ckt = extractCkt(identifiableId, FIXED_SHUNT_TAG); - yield ckt.isPresent() ? ckt : extractCkt(identifiableId, SWITCHED_SHUNT_TAG); - } - case HVDC_LINE -> Optional.of(extractTwoTerminalDcName(identifiableId)); - default -> throw new PsseException("unexpected identifiableType: " + identifiableType.name()); - }; - } - - private static Optional extractCkt(String identifiableId, String subString) { - int index = identifiableId.lastIndexOf(subString); - if (index != -1) { - return Optional.of(identifiableId.substring(index + subString.length())); - } else { - return Optional.empty(); - } - } - static String getNodeBreakerEquipmentIdBus(String equipmentId, int bus) { return equipmentId + "." + bus; } - static String getPsseEquipmentType(Identifiable identifiable) { - return switch (identifiable.getType()) { - case LOAD -> PsseEquipmentType.PSSE_LOAD.getTextCode(); - case GENERATOR -> PsseEquipmentType.PSSE_GENERATOR.getTextCode(); - case LINE -> PsseEquipmentType.PSSE_BRANCH.getTextCode(); - case TWO_WINDINGS_TRANSFORMER -> PsseEquipmentType.PSSE_TWO_WINDING.getTextCode(); - case THREE_WINDINGS_TRANSFORMER -> PsseEquipmentType.PSSE_THREE_WINDING.getTextCode(); - case SHUNT_COMPENSATOR -> { - ShuntCompensator shunt = (ShuntCompensator) identifiable; - yield isFixedShunt(shunt) ? PsseEquipmentType.PSSE_FIXED_SHUNT.getTextCode() : PsseEquipmentType.PSSE_SWITCHED_SHUNT.getTextCode(); - } - case HVDC_LINE -> PsseEquipmentType.PSSE_TWO_TERMINAL_DC_LINE.getTextCode(); - default -> throw new PsseException("unexpected identifiableType: " + identifiable.getType().name()); - }; - } - - private static boolean isFixedShunt(ShuntCompensator shunt) { - if (shunt.getId().contains(FIXED_SHUNT_TAG)) { - return true; - } else if (shunt.getId().contains(SWITCHED_SHUNT_TAG)) { - return false; - } else { - return shunt.getMaximumSectionCount() == 1 - && !shunt.isVoltageRegulatorOn() - && Double.isNaN(shunt.getTargetV()); - } - } - - static List getEquipmentListToBeExported(VoltageLevel voltageLevel) { - List equipmentListToBeExported = new ArrayList<>(); - for (Connectable connectable : voltageLevel.getConnectables()) { - if (isEquipmentToBeExported(connectable.getType())) { - if (connectable.getType().equals(IdentifiableType.HVDC_CONVERTER_STATION)) { - HvdcConverterStation converterStation = (HvdcConverterStation) connectable; - equipmentListToBeExported.add(converterStation.getHvdcLine().getId()); - } else { - equipmentListToBeExported.add(connectable.getId()); - } - } - } - return equipmentListToBeExported.stream().sorted().toList(); - } - - static List getEquipmentNodes(VoltageLevel voltageLevel, String equipmentId) { - return getEquipmentTerminals(voltageLevel, equipmentId).stream().map(terminal -> terminal.getNodeBreakerView().getNode()).toList(); - } - - static List getEquipmentTerminals(VoltageLevel voltageLevel, String equipmentId) { - List terminals = new ArrayList<>(); - Connectable connectable = voltageLevel.getNetwork().getConnectable(equipmentId); - if (connectable != null) { - connectable.getTerminals().forEach(terminal -> addVoltageLevelTerminal(voltageLevel, terminal, terminals)); - } else { - Identifiable identifiable = voltageLevel.getNetwork().getIdentifiable(equipmentId); - if (identifiable != null && identifiable.getType().equals(IdentifiableType.HVDC_LINE)) { - HvdcLine hvdcLine = (HvdcLine) identifiable; - addVoltageLevelTerminal(voltageLevel, hvdcLine.getConverterStation1().getTerminal(), terminals); - addVoltageLevelTerminal(voltageLevel, hvdcLine.getConverterStation2().getTerminal(), terminals); - } else { - throw new PsseException("Unexpected identifiable: " + equipmentId); - } - } - return terminals; - } - - static ThreeSides getTerminalSide(Terminal terminal) { - if (terminal.getConnectable().getType().equals(IdentifiableType.HVDC_CONVERTER_STATION)) { - HvdcConverterStation converterStation = (HvdcConverterStation) terminal.getConnectable(); - return converterStation.equals(converterStation.getHvdcLine().getConverterStation1()) ? ThreeSides.ONE : ThreeSides.TWO; - } else { - return terminal.getSide(); - } - } - - private static void addVoltageLevelTerminal(VoltageLevel voltageLevel, Terminal terminal, List terminals) { - if (terminal != null && terminal.getVoltageLevel().equals(voltageLevel)) { - terminals.add(terminal); - } - } - - private static boolean isEquipmentToBeExported(IdentifiableType type) { - return switch (type) { - case LOAD, GENERATOR, SHUNT_COMPENSATOR, LINE, TWO_WINDINGS_TRANSFORMER, THREE_WINDINGS_TRANSFORMER, HVDC_CONVERTER_STATION -> - true; - case BUSBAR_SECTION, HVDC_LINE, SWITCH -> false; - default -> throw new PsseException("Unexpected equipment type: " + type.name()); - }; - } - // EquipmentId must be independent of the bus order static String getNodeBreakerEquipmentId(String type, int busI, int busJ, int busK, String id) { List sortedBuses = Stream.of(busI, busJ, busK).sorted().toList(); @@ -297,31 +201,13 @@ static Terminal findTerminalNode(VoltageLevel voltageLevel, int node) { .orElseGet(() -> Networks.getEquivalentTerminal(voltageLevel, node)); } - static Bus getTerminalBus(Terminal terminal) { - return terminal.getBusView().getBus() != null ? terminal.getBusView().getBus() : terminal.getBusView().getConnectableBus(); - } - - static int getTerminalBusI(Terminal terminal, ContextExport contextExport) { - if (terminal.getVoltageLevel().getTopologyKind().equals(TopologyKind.NODE_BREAKER)) { - int node = terminal.getNodeBreakerView().getNode(); - return contextExport.getNodeBreakerExport().getNodeBusI(terminal.getVoltageLevel(), node).orElseThrow(); - } else { - Bus bus = getTerminalBus(terminal); - return contextExport.getBusBreakerExport().getBusBusI(bus.getId()).orElseThrow(); - } + static Bus findBusViewNode(VoltageLevel voltageLevel, int node) { + Terminal terminal = findTerminalNode(voltageLevel, node); + return terminal != null ? getTerminalBusView(terminal) : null; } - static int getRegulatingTerminalBusI(Terminal regulatingTerminal, int busI, int previousRegulatingBusI, ContextExport contextExport) { - int regulatingBusI = getRegulatingTerminalBusI(regulatingTerminal, contextExport); - return busI == regulatingBusI && previousRegulatingBusI == 0 ? previousRegulatingBusI : regulatingBusI; - } - - static int getRegulatingTerminalBusI(Terminal regulatingTerminal, ContextExport contextExport) { - if (regulatingTerminal == null) { - return 0; - } else { - return getTerminalBusI(regulatingTerminal, contextExport); - } + static Bus getTerminalBusView(Terminal terminal) { + return terminal.getBusView().getBus() != null ? terminal.getBusView().getBus() : terminal.getBusView().getConnectableBus(); } static int getStatus(Terminal terminal) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java index 59d37605f62..ecf7804b451 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java @@ -13,10 +13,8 @@ import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.VoltageLevel; import com.powsybl.iidm.network.util.ContainersMapping; -import com.powsybl.psse.model.PsseException; import com.powsybl.psse.model.pf.PsseBus; import com.powsybl.psse.model.pf.PssePowerFlowModel; -import org.apache.commons.lang3.StringUtils; /** * @author Luma Zamarreño {@literal } @@ -24,8 +22,6 @@ */ class BusConverter extends AbstractConverter { - private static final int MAX_BUS_LENGTH = 12; - BusConverter(PsseBus psseBus, ContainersMapping containerMapping, Network network, NodeBreakerImport nodeBreakerImport) { super(containerMapping, network); this.psseBus = Objects.requireNonNull(psseBus); @@ -47,57 +43,16 @@ void create(VoltageLevel voltageLevel) { .setAngle(psseBus.getVa()); } - static void updateAndCreateBuses(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { - Map busNumToPsseBus = new HashMap<>(); - psseModel.getBuses().forEach(psseBus -> busNumToPsseBus.put(psseBus.getI(), psseBus)); - - contextExport.getBusBreakerExport().getBuses().forEach(busViewBusId -> { - int busI = contextExport.getBusBreakerExport().getBusBusI(busViewBusId).orElseThrow(); - int type = contextExport.getBusBreakerExport().getBusType(busViewBusId).orElseThrow(); - updateAndCreateBus(network, busViewBusId, busI, type, null, psseModel, busNumToPsseBus); + static void updateBuses(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { + psseModel.getBuses().forEach(psseBus -> { + Optional busViewBusId = contextExport.getBusViewBusId(psseBus.getI()); + OptionalInt type = contextExport.getType(psseBus.getI()); + if (busViewBusId.isPresent() && type.isPresent()) { + updatePsseBus(network, busViewBusId.get(), type.getAsInt(), psseBus); + } else { + updateIsolatedPsseBus(psseBus); + } }); - - contextExport.getNodeBreakerExport().getBuses().forEach(busViewBusId -> { - int busI = contextExport.getNodeBreakerExport().getBusBusI(busViewBusId).orElseThrow(); - Integer busCopy = contextExport.getNodeBreakerExport().getBusBusCopy(busViewBusId).orElse(null); - int type = contextExport.getNodeBreakerExport().getBusType(busViewBusId).orElseThrow(); - updateAndCreateBus(network, busViewBusId, busI, type, busCopy, psseModel, busNumToPsseBus); - }); - - contextExport.getNodeBreakerExport().getIsolatedBusesI().forEach(busI -> { - VoltageLevel voltageLevel = contextExport.getNodeBreakerExport().getIsolatedBusIVoltageLevel(busI).orElseThrow(); - Integer busCopy = contextExport.getNodeBreakerExport().getIsolatedBusIBusCopy(busI).orElse(null); - createIsolatedBus(voltageLevel, busI, busCopy, psseModel, busNumToPsseBus); - }); - - psseModel.replaceAllBuses(psseModel.getBuses().stream().sorted(Comparator.comparingInt(PsseBus::getI)).toList()); - } - - private static void updateAndCreateBus(Network network, String busViewBusId, int busI, int type, Integer busCopy, PssePowerFlowModel psseModel, Map busNumToPsseBus) { - if (busNumToPsseBus.containsKey(busI)) { - PsseBus psseBus = busNumToPsseBus.get(busI); - updatePsseBus(network, busViewBusId, type, psseBus); - } else if (busCopy != null) { - PsseBus psseBus = createNewBusFromCopy(busCopy, busI, busNumToPsseBus); - updatePsseBus(network, busViewBusId, type, psseBus); - psseModel.addBuses(Collections.singletonList(psseBus)); - } else { - Bus bus = Objects.requireNonNull(network.getBusView().getBus(busViewBusId)); - psseModel.addBuses(Collections.singletonList(createNewBus(bus, busI, type))); - } - } - - private static void createIsolatedBus(VoltageLevel voltageLevel, int busI, Integer busCopy, PssePowerFlowModel psseModel, Map busNumToPsseBus) { - if (busNumToPsseBus.containsKey(busI)) { - PsseBus psseBus = busNumToPsseBus.get(busI); - updateIsolatedPsseBus(psseBus); - } else if (busCopy != null) { - PsseBus psseBus = createNewBusFromCopy(busCopy, busI, busNumToPsseBus); - updateIsolatedPsseBus(psseBus); - psseModel.addBuses(Collections.singletonList(psseBus)); - } else { - psseModel.addBuses(Collections.singletonList(createNewIsolatedBus(voltageLevel, busI))); - } } private static void updatePsseBus(Network network, String busViewBusId, int type, PsseBus psseBus) { @@ -105,37 +60,13 @@ private static void updatePsseBus(Network network, String busViewBusId, int type if (bus == null) { updateIsolatedPsseBus(psseBus); } else { - psseBus.setVm(getVm(bus)); - psseBus.setVa(getVa(bus)); - psseBus.setIde(type); - } - } - - private static PsseBus createNewBusFromCopy(int copyBus, int newBus, Map busNumToPsseBus) { - PsseBus psseBusToBeCopied = findPsseBus(copyBus, busNumToPsseBus); - PsseBus psseBus = psseBusToBeCopied.copy(); - psseBus.setI(newBus); - psseBus.setName(findNewBusName(psseBus.getName().trim(), "-" + newBus)); - return psseBus; - } - - // new bus name is obtained by adding "-" + newBus, but MAX_BUS_LENGTH must be ensured - private static String findNewBusName(String baseName, String tag) { - int newLength = baseName.length() + tag.length(); - if (newLength < MAX_BUS_LENGTH) { - return StringUtils.rightPad(baseName + tag, MAX_BUS_LENGTH, " "); - } else if (newLength == MAX_BUS_LENGTH) { - return baseName + tag; - } else { - return baseName.substring(0, MAX_BUS_LENGTH - tag.length()) + tag; - } - } - - private static PsseBus findPsseBus(int bus, Map busNumToPsseBus) { - if (busNumToPsseBus.containsKey(bus)) { - return busNumToPsseBus.get(bus); - } else { - throw new PsseException("Unexpected null PsseBus for " + bus); + if (type == 4) { + updateIsolatedPsseBus(psseBus); + } else { + psseBus.setVm(getVm(bus)); + psseBus.setVa(getVa(bus)); + psseBus.setIde(type); + } } } @@ -145,29 +76,6 @@ private static void updateIsolatedPsseBus(PsseBus psseBus) { psseBus.setIde(4); } - private static PsseBus createNewBus(Bus bus, int busI, int type) { - PsseBus psseBus = new PsseBus(); - psseBus.setI(busI); - psseBus.setName(bus.getNameOrId()); - psseBus.setBaskv(bus.getVoltageLevel().getNominalV()); - psseBus.setIde(type); - psseBus.setVm(getVm(bus)); - psseBus.setVa(getVa(bus)); - - return psseBus; - } - - private static PsseBus createNewIsolatedBus(VoltageLevel voltageLevel, int busI) { - PsseBus psseBus = new PsseBus(); - psseBus.setI(busI); - psseBus.setName(voltageLevel.getId() + "-" + busI); - psseBus.setBaskv(voltageLevel.getNominalV()); - - updateIsolatedPsseBus(psseBus); - - return psseBus; - } - private final PsseBus psseBus; private final NodeBreakerImport nodeBreakerImport; } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/ContextExport.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/ContextExport.java index 9dd70ebeeb6..a06ed372a4f 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/ContextExport.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/ContextExport.java @@ -7,293 +7,81 @@ */ package com.powsybl.psse.converter; -import com.powsybl.iidm.network.Identifiable; -import com.powsybl.iidm.network.IdentifiableType; import com.powsybl.iidm.network.VoltageLevel; -import com.powsybl.psse.model.PsseException; +import com.powsybl.psse.model.pf.PsseBus; import com.powsybl.psse.model.pf.PsseSubstation; import java.util.*; -import java.util.stream.Stream; /** * @author Luma Zamarreño {@literal } * @author José Antonio Marqués {@literal } */ final class ContextExport { - private int maxPsseBus; - private final BusBreakerExport busBreakerExport; + private final Map ibusToPsseBus; + private final Map buses; private final NodeBreakerExport nodeBreakerExport; - private final Map> equipmentTerminalData; - private final Map equipmentCkt; - private final Map> equipmentAllCkt; - ContextExport(int maxPsseBus) { - this.maxPsseBus = maxPsseBus; - this.busBreakerExport = new BusBreakerExport(); + ContextExport() { + this.ibusToPsseBus = new HashMap<>(); + this.buses = new HashMap<>(); this.nodeBreakerExport = new NodeBreakerExport(); - this.equipmentTerminalData = new HashMap<>(); - this.equipmentCkt = new HashMap<>(); - this.equipmentAllCkt = new HashMap<>(); } - int getNewPsseBusI() { - return ++maxPsseBus; + void addIbus(int busI, PsseBus psseBus) { + ibusToPsseBus.put(busI, psseBus); } - BusBreakerExport getBusBreakerExport() { - return this.busBreakerExport; + Optional getPsseBus(int busI) { + return ibusToPsseBus.containsKey(busI) ? Optional.of(ibusToPsseBus.get(busI)) : Optional.empty(); } - NodeBreakerExport getNodeBreakerExport() { - return this.nodeBreakerExport; - } - - boolean isFreePsseBusI(int busI) { - return busBreakerExport.isFreePsseBusId(busI) && nodeBreakerExport.isFreePsseBusId(busI); - } - - void addEquipmentEnd(String equipmentId, VoltageLevel voltageLevel, int node, int busI, int end) { - equipmentTerminalData.computeIfAbsent(equipmentId, k -> new ArrayList<>()).add(new EqR(voltageLevel, node, busI, end)); - } - - void addEquipmentEnd(String equipmentId, VoltageLevel voltageLevel, int busI, int end) { - equipmentTerminalData.computeIfAbsent(equipmentId, k -> new ArrayList<>()).add(new EqR(voltageLevel, null, busI, end)); - } - - List getEquipmentBusesList(String equipmentId, VoltageLevel voltageLevel, int node) { - List busesList = new ArrayList<>(); - if (equipmentTerminalData.containsKey(equipmentId)) { - int bus = equipmentTerminalData.get(equipmentId).stream().filter(eqR -> eqR.voltageLevel.equals(voltageLevel) && eqR.node == node).map(eqR -> eqR.busI).findFirst().orElseThrow(); - busesList.add(bus); - addToBusList(busesList, bus, equipmentTerminalData.get(equipmentId).stream().filter(eqR -> eqR.end == 1).map(eqR -> eqR.busI).findFirst().orElse(0)); - addToBusList(busesList, bus, equipmentTerminalData.get(equipmentId).stream().filter(eqR -> eqR.end == 2).map(eqR -> eqR.busI).findFirst().orElse(0)); - addToBusList(busesList, bus, equipmentTerminalData.get(equipmentId).stream().filter(eqR -> eqR.end == 3).map(eqR -> eqR.busI).findFirst().orElse(0)); - } - return busesList; + void addBus(int busI, String busViewId, int type) { + buses.put(busI, new BusR(busViewId, type)); } - private static void addToBusList(List busList, int bus, int busEnd) { - if (bus != busEnd) { - busList.add(busEnd); - } - } - - String getEquipmentCkt(String equipmentId, IdentifiableType type, int busI, int busJ, int busK) { - if (equipmentCkt.containsKey(equipmentId)) { - return equipmentCkt.get(equipmentId); - } - String equipmentBusesId = getEquipmentBusesId(equipmentId, type.name(), busI, busJ, busK); - Optional optCkt = AbstractConverter.extractCkt(equipmentId, type); - if (optCkt.isPresent() && cktIsFree(equipmentBusesId, optCkt.get())) { - addCkt(equipmentId, equipmentBusesId, optCkt.get()); - return optCkt.get(); - } - String ckt = getNewCkt(equipmentBusesId); - addCkt(equipmentId, equipmentBusesId, ckt); - return ckt; + Optional getBusViewBusId(int bus) { + return buses.containsKey(bus) ? Optional.of(buses.get(bus).busViewId()) : Optional.empty(); } - private boolean cktIsFree(String equipmentBusesId, String ckt) { - if (equipmentAllCkt.containsKey(equipmentBusesId)) { - return !equipmentAllCkt.get(equipmentBusesId).contains(ckt); - } else { - return true; - } - } - - private void addCkt(String equipmentId, String equipmentBusesId, String ckt) { - equipmentAllCkt.computeIfAbsent(equipmentBusesId, k -> new ArrayList<>()).add(ckt); - equipmentCkt.put(equipmentId, ckt); - } - - private String getNewCkt(String equipmentBusesId) { - for (int i = 1; i <= 99; i++) { - String ckt = String.format("%02d", i); - if (cktIsFree(equipmentBusesId, ckt)) { - return ckt; - } - } - throw new PsseException("unable to obtain a ckt for " + equipmentBusesId); + OptionalInt getType(int bus) { + return buses.containsKey(bus) ? OptionalInt.of(buses.get(bus).type()) : OptionalInt.empty(); } - private static String getEquipmentBusesId(String equipmentId, String type, int busI, int busJ, int busK) { - List sortedBuses = Stream.of(busI, busJ, busK).filter(bus -> bus != 0).sorted().toList(); - if (sortedBuses.size() == 1) { - return type + "-" + sortedBuses.get(0); - } else if (sortedBuses.size() == 2) { - return type + "-" + sortedBuses.get(0) + "-" + sortedBuses.get(1); - } else if (sortedBuses.size() == 3) { - return type + "-" + sortedBuses.get(0) + "-" + sortedBuses.get(1) + "-" + sortedBuses.get(2); - } else { - throw new PsseException("All the buses are zero. EquipmentId: " + equipmentId); - } - } - - static class BusBreakerExport { - private final Map buses; - private final Set usedPsseBusI; - - BusBreakerExport() { - this.buses = new HashMap<>(); - this.usedPsseBusI = new HashSet<>(); - } - - void addBus(String busViewId, int busI, int type) { - buses.put(busViewId, new BusR(busI, type)); - usedPsseBusI.add(busI); - } - - List getBuses() { - return buses.keySet().stream().sorted().toList(); - } - - OptionalInt getBusBusI(String busViewId) { - return buses.containsKey(busViewId) ? OptionalInt.of(buses.get(busViewId).busI) : OptionalInt.empty(); - } - - OptionalInt getBusType(String busViewId) { - return buses.containsKey(busViewId) ? OptionalInt.of(buses.get(busViewId).type) : OptionalInt.empty(); - } - - private boolean isFreePsseBusId(int busI) { - return !usedPsseBusI.contains(busI); - } - - private record BusR(int busI, int type) { - } + NodeBreakerExport getNodeBreakerExport() { + return this.nodeBreakerExport; } static class NodeBreakerExport { - private final Map voltageLevels; - private final Map nodes; - private final Map buses; - private final Map isolatedBusesI; - private final Set usedPsseBusI; - private final Map selectedNodes; + private final Map voltageLevelPsseSubstation; + private final Map nodes; NodeBreakerExport() { - this.voltageLevels = new HashMap<>(); + this.voltageLevelPsseSubstation = new HashMap<>(); this.nodes = new HashMap<>(); - this.buses = new HashMap<>(); - this.isolatedBusesI = new HashMap<>(); - this.usedPsseBusI = new HashSet<>(); - this.selectedNodes = new HashMap<>(); - } - - void addVoltageLevels(List voltageLevels) { - voltageLevels.forEach(voltageLevel -> this.voltageLevels.put(voltageLevel, null)); } - void addVoltageLevel(VoltageLevel voltageLevel, PsseSubstation psseSubstation) { - voltageLevels.put(voltageLevel, psseSubstation); + void addVoltageLevelPsseSubstation(VoltageLevel voltageLevel, PsseSubstation psseSubstation) { + voltageLevelPsseSubstation.put(voltageLevel, psseSubstation); } - List getVoltageLevels() { - return voltageLevels.keySet().stream().sorted(Comparator.comparing(Identifiable::getId)).toList(); + Optional getVoltageLevelPsseSubstation(VoltageLevel voltageLevel) { + return Optional.ofNullable(voltageLevelPsseSubstation.get(voltageLevel)); } - Optional getPsseSubstationMappedToVoltageLevel(VoltageLevel voltageLevel) { - return Optional.ofNullable(voltageLevels.get(voltageLevel)); + void addNode(VoltageLevel voltageLevel, int node, String busViewBusId) { + nodes.put(getNodeId(voltageLevel, node), busViewBusId); } - void addNodes(String busViewBusId, VoltageLevel voltageLevel, List nodes, int busI, Integer busCopy, int type) { - nodes.forEach(node -> this.nodes.put(getNodeId(voltageLevel, node), new NodeR(voltageLevel, node, busI, isInService(type), busViewBusId))); - buses.put(busViewBusId, new BusR(busI, busCopy, type)); - usedPsseBusI.add(busI); - } - - void addIsolatedNode(VoltageLevel voltageLevel, int node, int busI, Integer busCopy) { - nodes.put(getNodeId(voltageLevel, node), new NodeR(voltageLevel, node, busI, false, null)); - isolatedBusesI.put(busI, new BusIR(voltageLevel, busCopy)); - usedPsseBusI.add(busI); - } - - void addNodes(String busViewBusId, VoltageLevel voltageLevel, List nodes, int busI, int type) { - nodes.forEach(node -> this.nodes.put(getNodeId(voltageLevel, node), new NodeR(voltageLevel, node, busI, isInService(type), busViewBusId))); - buses.put(busViewBusId, new BusR(busI, null, type)); - usedPsseBusI.add(busI); - } - - void addIsolatedNode(VoltageLevel voltageLevel, int node, int busI) { - nodes.put(getNodeId(voltageLevel, node), new NodeR(voltageLevel, node, busI, false, null)); - isolatedBusesI.put(busI, new BusIR(voltageLevel, null)); - usedPsseBusI.add(busI); - } - - List getBuses() { - return buses.keySet().stream().sorted().toList(); - } - - OptionalInt getBusBusI(String busViewId) { - return buses.containsKey(busViewId) ? OptionalInt.of(buses.get(busViewId).busI) : OptionalInt.empty(); - } - - Optional getBusBusCopy(String busViewId) { - return buses.containsKey(busViewId) ? Optional.ofNullable(buses.get(busViewId).busCopy) : Optional.empty(); - } - - OptionalInt getBusType(String busViewId) { - return buses.containsKey(busViewId) ? OptionalInt.of(buses.get(busViewId).type) : OptionalInt.empty(); - } - - OptionalInt getNodeBusI(VoltageLevel voltageLevel, int node) { - return nodes.containsKey(getNodeId(voltageLevel, node)) ? OptionalInt.of(nodes.get(getNodeId(voltageLevel, node)).busI) : OptionalInt.empty(); - } - - Optional isNodeInService(VoltageLevel voltageLevel, int node) { - return nodes.containsKey(getNodeId(voltageLevel, node)) ? Optional.of(nodes.get(getNodeId(voltageLevel, node)).isInService) : Optional.empty(); - } - - List getIsolatedBusesI() { - return isolatedBusesI.keySet().stream().sorted().toList(); - } - - Optional getIsolatedBusIVoltageLevel(int busI) { - return isolatedBusesI.containsKey(busI) ? Optional.of(isolatedBusesI.get(busI).voltageLevel) : Optional.empty(); - } - - Optional getIsolatedBusIBusCopy(int busI) { - return isolatedBusesI.containsKey(busI) ? Optional.ofNullable(isolatedBusesI.get(busI).busCopy) : Optional.empty(); - } - - void addSelectedNode(VoltageLevel voltageLevel, Set nodes, int selectedNode) { - nodes.forEach(node -> selectedNodes.put(getNodeId(voltageLevel, node), new SelectedNodeR(voltageLevel, selectedNode))); - } - - List getSelectedNodes(VoltageLevel voltageLevel) { - return new HashSet<>(selectedNodes.values()).stream().filter(value -> value.voltageLevel.equals(voltageLevel)).map(value -> value.node).sorted().toList(); - } - - OptionalInt getSelectedNode(VoltageLevel voltageLevel, int node) { - return selectedNodes.containsKey(getNodeId(voltageLevel, node)) ? OptionalInt.of(selectedNodes.get(getNodeId(voltageLevel, node)).node) : OptionalInt.empty(); - } - - private static boolean isInService(int type) { - return type != 4; + Optional getNodeViewBusId(VoltageLevel voltageLevel, int node) { + return nodes.containsKey(getNodeId(voltageLevel, node)) ? Optional.of(nodes.get(getNodeId(voltageLevel, node))) : Optional.empty(); } private static String getNodeId(VoltageLevel voltageLevel, int node) { return voltageLevel.getId() + "-" + node; } - - private boolean isFreePsseBusId(int busI) { - return !usedPsseBusI.contains(busI); - } - - private record SelectedNodeR(VoltageLevel voltageLevel, int node) { - } - - private record NodeR(VoltageLevel voltageLevel, int node, int busI, boolean isInService, String busViewBusId) { - } - - private record BusR(int busI, Integer busCopy, int type) { - } - - private record BusIR(VoltageLevel voltageLevel, Integer busCopy) { - } } - private record EqR(VoltageLevel voltageLevel, Integer node, int busI, int end) { + private record BusR(String busViewId, int type) { } } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java index 60e078c3251..d6b290a774c 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java @@ -64,11 +64,10 @@ void create() { } // At the moment we do not consider new fixedShunts - static void updateFixedShunts(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { + static void updateFixedShunts(Network network, PssePowerFlowModel psseModel) { psseModel.getFixedShunts().forEach(psseFixedShunt -> { String fixedShuntId = getFixedShuntId(psseFixedShunt.getI(), psseFixedShunt.getId()); ShuntCompensator fixedShunt = network.getShuntCompensator(fixedShuntId); - int bus = getTerminalBusI(fixedShunt.getTerminal(), contextExport); if (fixedShunt == null) { psseFixedShunt.setStatus(0); @@ -76,7 +75,6 @@ static void updateFixedShunts(Network network, PssePowerFlowModel psseModel, Con psseFixedShunt.setStatus(getStatus(fixedShunt)); psseFixedShunt.setBl(getQ(fixedShunt)); } - psseFixedShunt.setI(bus); }); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java index 916db0d7002..d274b87ee51 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java @@ -88,7 +88,9 @@ void addControl(PsseBus psseBus) { boolean psseVoltageRegulatorOn = defineVoltageRegulatorOn(psseBus); double vnom = regulatingTerminal.getVoltageLevel().getNominalV(); double targetV = psseGenerator.getVs() * vnom; + boolean voltageRegulatorOn = false; + // we consider < but psse accepts bus type 2 with Qmin == Qmax if (targetV > 0.0 && psseGenerator.getQb() < psseGenerator.getQt()) { voltageRegulatorOn = psseVoltageRegulatorOn; } @@ -127,12 +129,10 @@ private static Terminal defineRegulatingTerminal(PsseGenerator psseGenerator, Ne } // At the moment we do not consider new generators - static void updateGenerators(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { + static void updateGenerators(Network network, PssePowerFlowModel psseModel) { psseModel.getGenerators().forEach(psseGen -> { String genId = getGeneratorId(psseGen.getI(), psseGen.getId()); Generator gen = network.getGenerator(genId); - int bus = getTerminalBusI(gen.getTerminal(), contextExport); - int regulatingBus = getRegulatingTerminalBusI(gen.getRegulatingTerminal(), bus, psseGen.getIreg(), contextExport); if (gen == null) { psseGen.setStat(0); @@ -141,18 +141,9 @@ static void updateGenerators(Network network, PssePowerFlowModel psseModel, Cont psseGen.setPg(getP(gen)); psseGen.setQg(getQ(gen)); } - psseGen.setI(bus); - if (regulatingBusMustBeChanged(bus, regulatingBus, psseGen.getIreg())) { - psseGen.setIreg(regulatingBus); - } }); } - // zero can be used for local regulation - private static boolean regulatingBusMustBeChanged(int bus, int newRegulatingBus, int regulatingBus) { - return !(bus == newRegulatingBus && regulatingBus == 0); - } - private static int getStatus(Generator gen) { if (gen.getTerminal().isConnected() && gen.getTerminal().getBusBreakerView().getBus() != null) { return 1; diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java index e266fa7f377..14c85640f12 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java @@ -124,20 +124,16 @@ private void defineOperationalLimits(Line line, double vnom1, double vnom2) { } // At the moment we do not consider new lines and antenna lines are exported as open - static void updateLines(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { + static void updateLines(Network network, PssePowerFlowModel psseModel) { psseModel.getNonTransformerBranches().forEach(psseLine -> { String lineId = getLineId(psseLine.getI(), psseLine.getJ(), psseLine.getCkt()); Line line = network.getLine(lineId); - int busI = getTerminalBusI(line.getTerminal1(), contextExport); - int busJ = getTerminalBusI(line.getTerminal2(), contextExport); if (line == null) { psseLine.setSt(0); } else { psseLine.setSt(getStatus(line)); } - psseLine.setI(busI); - psseLine.setJ(busJ); }); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java index e35d80022a9..95e4a0df205 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LoadConverter.java @@ -91,24 +91,22 @@ void create() { adder.add(); } - static void updateLoads(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { + static void updateLoads(Network network, PssePowerFlowModel psseModel) { psseModel.getLoads().forEach(psseLoad -> { String loadId = getLoadId(psseLoad.getI(), psseLoad.getId()); Load load = network.getLoad(loadId); if (load == null) { psseLoad.setStatus(0); } else { - updateLoad(load, psseLoad, contextExport); + updateLoad(load, psseLoad); } }); } - private static void updateLoad(Load load, PsseLoad psseLoad, ContextExport contextExport) { - int bus = getTerminalBusI(load.getTerminal(), contextExport); + private static void updateLoad(Load load, PsseLoad psseLoad) { psseLoad.setStatus(getStatus(load.getTerminal())); psseLoad.setPl(getP(load)); psseLoad.setQl(getQ(load)); - psseLoad.setI(bus); } private static double getP(Load load) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java index f79d37f3ff7..43c35f70cbd 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java @@ -39,6 +39,16 @@ final class NodeBreakerValidation { this.busControls = new HashMap<>(); } + Optional getSubstationIfOnlyOneExists(Set buses) { + Set psseSubstations = buses.stream() + .map(this::getSubstationIfOnlyOneExists) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toSet()); + return psseSubstations.size() == 1 ? Optional.of(psseSubstations.iterator().next()) : Optional.empty(); + } + + // nodeBreaker topology of a bus can only be defined in one substationData Optional getSubstationIfOnlyOneExists(int bus) { if (busSubstations.containsKey(bus) && busSubstations.get(bus).size() == 1) { return Optional.of(busSubstations.get(bus).iterator().next()); @@ -129,75 +139,74 @@ private void addWindingControl(PsseTransformerWinding psseTransformerWinding, St } } - boolean isNodeBreakerSubstationCoherent(Set expectedBuses) { + // All the buses must be defined inside the same psseSubstation + // if two buses of the same voltageLevel are defined in different psseSubstations then the node numbers could be incoherent (can be overlapped) + boolean isNodeBreakerSubstationDataCoherent(Set expectedBuses) { if (ignoreNodeBreakerTopology) { return false; } if (expectedBuses.isEmpty()) { return false; } - Set expectedSubstations = expectedBuses.stream() - .map(this::getSubstationIfOnlyOneExists) - .filter(Optional::isPresent) - .map(Optional::get) - .collect(Collectors.toSet()); - if (expectedSubstations.size() != 1) { - return false; - } - PsseSubstation expectedSubstation = expectedSubstations.iterator().next(); - if (!areControlsCoherent(expectedSubstation, expectedBuses)) { - return false; - } - Set expectedEquipmentTerminals = expectedBuses.stream() - .flatMap(bus -> getEquipmentTerminals(bus).stream()) - .collect(Collectors.toSet()); - List> nodeComponents = obtainNodeComponents(expectedSubstation); - - Set actualBuses = new HashSet<>(); - Set actualEquipmentTerminals = new HashSet<>(); - for (Set nodeComponentSet : nodeComponents) { - Set busComponentSet = expectedSubstation.getNodes().stream() - .filter(n -> nodeComponentSet.contains(n.getNi())) - .map(PsseSubstationNode::getI).collect(Collectors.toSet()); - Set equipmentTerminalComponent = expectedSubstation.getEquipmentTerminals().stream() - .filter(eqt -> nodeComponentSet.contains(eqt.getNi())) - .map(eqt -> getNodeBreakerEquipmentId(eqt.getType(), eqt.getI(), eqt.getJ(), eqt.getK(), eqt.getId())).collect(Collectors.toSet()); - - actualBuses.addAll(busComponentSet); - actualEquipmentTerminals.addAll(equipmentTerminalComponent); - } - if (expectedBuses.size() != actualBuses.size()) { + Optional expectedPsseSubstation = getSubstationIfOnlyOneExists(expectedBuses); + return expectedPsseSubstation.filter(substation -> expectedBuses.stream().allMatch(bus -> isNodeBreakerSubstationDataCoherent(substation, bus))).isPresent(); + } + + private boolean isNodeBreakerSubstationDataCoherent(PsseSubstation psseSubstation, int bus) { + Set nodesSetByDefinition = psseSubstation.getNodes().stream().filter(psseNode -> psseNode.getI() == bus).map(PsseSubstationNode::getNi).collect(Collectors.toSet()); + Set nodesSetBySwitching = obtainNodeComponentBySwitching(psseSubstation, bus); + if (!isValidNodesSet(psseSubstation, bus, nodesSetByDefinition, nodesSetBySwitching)) { return false; } - if (expectedEquipmentTerminals.size() != actualEquipmentTerminals.size()) { + if (!areControlsCoherent(bus, nodesSetBySwitching)) { return false; } - return expectedBuses.containsAll(actualBuses) && expectedEquipmentTerminals.containsAll(actualEquipmentTerminals); - } - - // All the nodes associated with controls must be inside the substation data - private boolean areControlsCoherent(PsseSubstation psseSubstation, Set buses) { - Set nodesSet = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).collect(Collectors.toSet()); - for (int bus : buses) { - List controls = getControls(bus); - if (controls.stream().map(NodeBreakerControl::getNode).anyMatch(node -> !nodesSet.contains(node))) { - return false; - } - } - return true; + List equipmentTerminalsByPsseBlocks = getEquipmentTerminals(bus); + Set equipmentTerminalByEquipmentTerminalData = psseSubstation.getEquipmentTerminals().stream() + .filter(eqt -> eqt.getI() == bus) + .map(eqt -> getNodeBreakerEquipmentId(eqt.getType(), eqt.getI(), eqt.getJ(), eqt.getK(), eqt.getId())).collect(Collectors.toSet()); + Set equipmentTerminalByNodeSet = psseSubstation.getEquipmentTerminals().stream() + .filter(eqt -> nodesSetBySwitching.contains(eqt.getNi())) + .map(eqt -> getNodeBreakerEquipmentId(eqt.getType(), eqt.getI(), eqt.getJ(), eqt.getK(), eqt.getId())).collect(Collectors.toSet()); + + return equipmentTerminalsByPsseBlocks.size() == equipmentTerminalByEquipmentTerminalData.size() + && equipmentTerminalsByPsseBlocks.size() == equipmentTerminalByNodeSet.size() + && equipmentTerminalByEquipmentTerminalData.containsAll(equipmentTerminalsByPsseBlocks) + && equipmentTerminalByEquipmentTerminalData.containsAll(equipmentTerminalByNodeSet); } - private static List> obtainNodeComponents(PsseSubstation psseSubstation) { - Set nodesSet = psseSubstation.getNodes().stream().map(PsseSubstationNode::getNi).collect(Collectors.toSet()); + // base on real cases and substation configurations created automatically by psse + // isolated nodes are discarded + // nodes are in the same component if they are connected by switches without considering their status (open / close) + private static Set obtainNodeComponentBySwitching(PsseSubstation psseSubstation, int bus) { + Set nodesSet = psseSubstation.getNodes().stream().filter(psseNode -> psseNode.getStatus() == 1).map(PsseSubstationNode::getNi).collect(Collectors.toSet()); Graph> sGraph = new Pseudograph<>(null, null, false); nodesSet.forEach(sGraph::addVertex); - psseSubstation.getSwitchingDevices().forEach(switchingDevice -> { - if (switchingDevice.getStatus() == 1) { // Only closed switches - sGraph.addEdge(switchingDevice.getNi(), switchingDevice.getNj(), Pair.of(switchingDevice.getNi(), switchingDevice.getNj())); - } - }); - return new ConnectivityInspector<>(sGraph).connectedSets(); + psseSubstation.getSwitchingDevices().forEach(switchingDevice -> sGraph.addEdge(switchingDevice.getNi(), switchingDevice.getNj(), Pair.of(switchingDevice.getNi(), switchingDevice.getNj()))); + + List> nodeComponents = new ConnectivityInspector<>(sGraph).connectedSets().stream().filter(nodeComponent -> nodeComponentAssociatedWithBus(psseSubstation, nodeComponent, bus)).toList(); + return nodeComponents.size() == 1 ? nodeComponents.get(0) : new HashSet<>(); + } + + private static boolean nodeComponentAssociatedWithBus(PsseSubstation psseSubstation, Set nodeComponent, int bus) { + return psseSubstation.getNodes().stream().anyMatch(psseNode -> psseNode.getI() == bus && nodeComponent.contains(psseNode.getNi())); + } + + private static boolean isValidNodesSet(PsseSubstation psseSubstation, int bus, Set nodesSetByDefinition, Set nodesSetBySwitching) { + if (nodesSetBySwitching.isEmpty()) { + return false; + } + // nodesSetByDefinition must be equal to isolatedNodesSet + nodesSetBySwitching + Set isolatedNodesSet = psseSubstation.getNodes().stream().filter(psseNode -> psseNode.getStatus() == 0 && psseNode.getI() == bus).map(PsseSubstationNode::getNi).collect(Collectors.toSet()); + isolatedNodesSet.addAll(nodesSetBySwitching); + return isolatedNodesSet.size() == nodesSetByDefinition.size() && nodesSetByDefinition.containsAll(isolatedNodesSet); + } + + // All the nodes associated with controls must be inside the nodesSetBySwitching + private boolean areControlsCoherent(int bus, Set nodesSetBySwitching) { + List controls = getControls(bus); + return controls.stream().map(NodeBreakerControl::getNode).allMatch(nodesSetBySwitching::contains); } private List getEquipmentTerminals(int bus) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java index bb04708c95d..263791b6320 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java @@ -122,16 +122,15 @@ private static PssePowerFlowModel createUpdatePsseModel(Network network, PssePow private static void updateModifiedBlocks(Network network, PssePowerFlowModel updatedPsseModel) { ContextExport contextExport = VoltageLevelConverter.createContextExport(network, updatedPsseModel); - // Only after mapping all substations, the substation data can be updated - VoltageLevelConverter.updateSubstations(contextExport); - - BusConverter.updateAndCreateBuses(network, updatedPsseModel, contextExport); - LoadConverter.updateLoads(network, updatedPsseModel, contextExport); - FixedShuntCompensatorConverter.updateFixedShunts(network, updatedPsseModel, contextExport); - GeneratorConverter.updateGenerators(network, updatedPsseModel, contextExport); - LineConverter.updateLines(network, updatedPsseModel, contextExport); - TransformerConverter.updateTransformers(network, updatedPsseModel, contextExport); - TwoTerminalDcConverter.updateTwoTerminalDcTransmissionLines(network, updatedPsseModel, contextExport); - SwitchedShuntCompensatorConverter.updateSwitchedShunts(network, updatedPsseModel, contextExport); + VoltageLevelConverter.updateSubstations(network, contextExport); + + BusConverter.updateBuses(network, updatedPsseModel, contextExport); + LoadConverter.updateLoads(network, updatedPsseModel); + FixedShuntCompensatorConverter.updateFixedShunts(network, updatedPsseModel); + GeneratorConverter.updateGenerators(network, updatedPsseModel); + LineConverter.updateLines(network, updatedPsseModel); + TransformerConverter.updateTransformers(network, updatedPsseModel); + TwoTerminalDcConverter.updateTwoTerminalDcTransmissionLines(network, updatedPsseModel); + SwitchedShuntCompensatorConverter.updateSwitchedShunts(network, updatedPsseModel); } } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java index 9b2bbdc932f..cf9d8025b49 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java @@ -182,7 +182,7 @@ private Network convert(PssePowerFlowModel psseModel, Network network, Propertie nodeBreakerValidation.fill(psseModel, version); // build container to fit IIDM requirements - ContainersMapping containersMapping = defineContainersMapping(psseModel, busNumToPsseBus, perUnitContext); + ContainersMapping containersMapping = defineContainersMapping(psseModel, busNumToPsseBus, perUnitContext, nodeBreakerValidation); // create buses NodeBreakerImport nodeBreakerImport = createBuses(psseModel, containersMapping, perUnitContext, network, nodeBreakerValidation); @@ -235,7 +235,7 @@ private Network convert(PssePowerFlowModel psseModel, Network network, Propertie return network; } - private ContainersMapping defineContainersMapping(PssePowerFlowModel psseModel, Map busNumToPsseBus, PerUnitContext perUnitContext) { + private ContainersMapping defineContainersMapping(PssePowerFlowModel psseModel, Map busNumToPsseBus, PerUnitContext perUnitContext, NodeBreakerValidation nodeBreakerValidation) { List edges = new ArrayList<>(); // only zeroImpedance Lines are necessary and they are not allowed, so nothing to do @@ -255,6 +255,7 @@ private ContainersMapping defineContainersMapping(PssePowerFlowModel psseModel, Edge::zeroImpedance, Edge::transformer, busNumber -> getNominalVFromBusNumber(busNumToPsseBus, busNumber, perUnitContext), + busNumber -> getPsseSubstationId(nodeBreakerValidation, busNumber), AbstractConverter::getVoltageLevelId, substationNums -> "S" + substationNums.stream().sorted().findFirst().orElseThrow(() -> new PsseException("Unexpected empty substationNums"))); } @@ -266,6 +267,10 @@ private double getNominalVFromBusNumber(Map busNumToPsseBus, i return VoltageLevelConverter.getNominalV(busNumToPsseBus.get(busNumber), perUnitContext.ignoreBaseVoltage()); } + private int getPsseSubstationId(NodeBreakerValidation nodeBreakerValidation, int busNumber) { + return nodeBreakerValidation.getSubstationIfOnlyOneExists(busNumber).map(psseSubstation -> psseSubstation.getRecord().getIs()).orElse(0); + } + private static NodeBreakerImport createBuses(PssePowerFlowModel psseModel, ContainersMapping containersMapping, PerUnitContext perUnitContext, Network network, NodeBreakerValidation nodeBreakerValidation) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java index 5c07c7f8c45..1c6df2b94e2 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java @@ -142,14 +142,6 @@ private static int switchedShuntRegulatingBus(PsseSwitchedShunt switchedShunt, P } } - private static void setSwitchedShuntRegulatingBus(PsseSwitchedShunt switchedShunt, PsseVersion psseVersion, int regulatingBus) { - if (psseVersion.major() == V35) { - switchedShunt.setSwreg(regulatingBus); - } else { - switchedShunt.setSwrem(regulatingBus); - } - } - private static int defineSectionCount(double binit, List shuntBlocks) { double maxDistance = Double.MAX_VALUE; int sectionCount = 0; @@ -281,21 +273,17 @@ private static String defineShuntId(PsseSwitchedShunt psseSwitchedShunt, PsseVer } // At the moment we do not consider new switchedShunts - static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { + static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel) { PsseVersion version = PsseVersion.fromRevision(psseModel.getCaseIdentification().getRev()); psseModel.getSwitchedShunts().forEach(psseSwitchedShunt -> { String switchedShuntId = getSwitchedShuntId(psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version)); ShuntCompensator switchedShunt = network.getShuntCompensator(switchedShuntId); - int bus = getTerminalBusI(switchedShunt.getTerminal(), contextExport); - int regulatingBus = getRegulatingTerminalBusI(switchedShunt.getRegulatingTerminal(), bus, switchedShuntRegulatingBus(psseSwitchedShunt, version), contextExport); if (switchedShunt == null) { psseSwitchedShunt.setStat(0); } else { psseSwitchedShunt.setStat(getStatus(switchedShunt)); psseSwitchedShunt.setBinit(getQ(switchedShunt)); } - psseSwitchedShunt.setI(bus); - setSwitchedShuntRegulatingBus(psseSwitchedShunt, version, regulatingBus); }); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java index 5b9bbee274e..455782aaa08 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java @@ -863,17 +863,17 @@ private static Terminal defineRegulatingTerminal(Network network, String id, Str } // At the moment we do not consider new transformers and antenna twoWindingsTransformers are exported as open - static void updateTransformers(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { + static void updateTransformers(Network network, PssePowerFlowModel psseModel) { psseModel.getTransformers().forEach(psseTransformer -> { if (isTwoWindingsTransformer(psseTransformer)) { - updateTwoWindingsTransformer(network, psseTransformer, contextExport); + updateTwoWindingsTransformer(network, psseTransformer); } else { - updateThreeWindingsTransformer(network, psseTransformer, contextExport); + updateThreeWindingsTransformer(network, psseTransformer); } }); } - private static void updateTwoWindingsTransformer(Network network, PsseTransformer psseTransformer, ContextExport contextExport) { + private static void updateTwoWindingsTransformer(Network network, PsseTransformer psseTransformer) { String transformerId = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); TwoWindingsTransformer tw2t = network.getTwoWindingsTransformer(transformerId); if (tw2t == null) { @@ -884,25 +884,10 @@ private static void updateTwoWindingsTransformer(Network network, PsseTransforme psseTransformer.getWinding1().setWindv(defineWindV(getRatio(tw2t.getRatioTapChanger(), tw2t.getPhaseTapChanger()), baskv1, nomV1, psseTransformer.getCw())); psseTransformer.getWinding1().setAng(getAngle(tw2t.getPhaseTapChanger())); - int busI = getTerminalBusI(tw2t.getTerminal1(), contextExport); - int busJ = getTerminalBusI(tw2t.getTerminal2(), contextExport); - psseTransformer.setI(busI); - psseTransformer.setJ(busJ); - int regulatingBus = getRegulatingTerminalBusI(findRegulatingTerminal(tw2t), contextExport); - psseTransformer.getWinding1().setCont(regulatingBus); - psseTransformer.setStat(getStatus(tw2t)); } } - private static Terminal findRegulatingTerminal(TwoWindingsTransformer tw2t) { - Terminal regulatingTerminal = tw2t.getOptionalRatioTapChanger().map(RatioTapChanger::getRegulationTerminal).orElse(null); - if (regulatingTerminal != null) { - return regulatingTerminal; - } - return tw2t.getOptionalPhaseTapChanger().map(PhaseTapChanger::getRegulationTerminal).orElse(null); - } - private static int getStatus(TwoWindingsTransformer tw2t) { if (tw2t.getTerminal1().isConnected() && tw2t.getTerminal1().getBusBreakerView().getBus() != null && tw2t.getTerminal2().isConnected() && tw2t.getTerminal2().getBusBreakerView().getBus() != null) { @@ -912,7 +897,7 @@ private static int getStatus(TwoWindingsTransformer tw2t) { } } - private static void updateThreeWindingsTransformer(Network network, PsseTransformer psseTransformer, ContextExport contextExport) { + private static void updateThreeWindingsTransformer(Network network, PsseTransformer psseTransformer) { String transformerId = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt()); ThreeWindingsTransformer tw3t = network.getThreeWindingsTransformer(transformerId); if (tw3t == null) { @@ -933,32 +918,10 @@ private static void updateThreeWindingsTransformer(Network network, PsseTransfor psseTransformer.getWinding3().setWindv(defineWindV(getRatio(tw3t.getLeg3().getRatioTapChanger(), tw3t.getLeg3().getPhaseTapChanger()), baskv3, nomV3, psseTransformer.getCw())); psseTransformer.getWinding3().setAng(getAngle(tw3t.getLeg3().getPhaseTapChanger())); - int busI = getTerminalBusI(tw3t.getLeg1().getTerminal(), contextExport); - int busJ = getTerminalBusI(tw3t.getLeg2().getTerminal(), contextExport); - int busK = getTerminalBusI(tw3t.getLeg3().getTerminal(), contextExport); - psseTransformer.setI(busI); - psseTransformer.setJ(busJ); - psseTransformer.setK(busK); - - int regulatingBus1 = getRegulatingTerminalBusI(findRegulatingTerminal(tw3t.getLeg1()), contextExport); - int regulatingBus2 = getRegulatingTerminalBusI(findRegulatingTerminal(tw3t.getLeg2()), contextExport); - int regulatingBus3 = getRegulatingTerminalBusI(findRegulatingTerminal(tw3t.getLeg3()), contextExport); - psseTransformer.getWinding1().setCont(regulatingBus1); - psseTransformer.getWinding2().setCont(regulatingBus2); - psseTransformer.getWinding3().setCont(regulatingBus3); - psseTransformer.setStat(getStatus(tw3t)); } } - private static Terminal findRegulatingTerminal(Leg leg) { - Terminal regulatingTerminal = leg.getOptionalRatioTapChanger().map(RatioTapChanger::getRegulationTerminal).orElse(null); - if (regulatingTerminal != null) { - return regulatingTerminal; - } - return leg.getOptionalPhaseTapChanger().map(PhaseTapChanger::getRegulationTerminal).orElse(null); - } - private static int getStatus(ThreeWindingsTransformer tw3t) { if (tw3t.getLeg1().getTerminal().isConnected() && tw3t.getLeg1().getTerminal().getBusBreakerView().getBus() != null && tw3t.getLeg2().getTerminal().isConnected() && tw3t.getLeg2().getTerminal().getBusBreakerView().getBus() != null diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java index 0d36bc6a67e..cf2f9ab7fe7 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java @@ -106,32 +106,19 @@ private static double getLccConverterPowerFactor(PsseTwoTerminalDcConverter conv return 0.5 * (Math.cos(Math.toRadians(converter.getAnmx())) + Math.cos(Math.toRadians(60.0))); } - static void updateTwoTerminalDcTransmissionLines(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { + static void updateTwoTerminalDcTransmissionLines(Network network, PssePowerFlowModel psseModel) { psseModel.getTwoTerminalDcTransmissionLines().forEach(psseTwoTerminalDc -> { String hvdcId = getTwoTerminalDcId(psseTwoTerminalDc.getName()); HvdcLine hvdcLine = network.getHvdcLine(hvdcId); - int busRectifier = getTerminalBusI(rectifierTerminal(hvdcLine), contextExport); - int busInverter = getTerminalBusI(inverterTerminal(hvdcLine), contextExport); - if (hvdcLine == null) { psseTwoTerminalDc.setMdc(0); } else { psseTwoTerminalDc.setMdc(findControlMode(hvdcLine, psseTwoTerminalDc.getMdc())); } - psseTwoTerminalDc.getRectifier().setIp(busRectifier); - psseTwoTerminalDc.getInverter().setIp(busInverter); }); } - private static Terminal rectifierTerminal(HvdcLine hvdcLine) { - return hvdcLine.getConvertersMode().equals(ConvertersMode.SIDE_1_RECTIFIER_SIDE_2_INVERTER) ? hvdcLine.getConverterStation1().getTerminal() : hvdcLine.getConverterStation2().getTerminal(); - } - - private static Terminal inverterTerminal(HvdcLine hvdcLine) { - return hvdcLine.getConvertersMode().equals(ConvertersMode.SIDE_1_RECTIFIER_SIDE_2_INVERTER) ? hvdcLine.getConverterStation2().getTerminal() : hvdcLine.getConverterStation1().getTerminal(); - } - private static int findControlMode(HvdcLine hvdcLine, int mdc) { if (hvdcLine.getConverterStation1().getTerminal().isConnected() && hvdcLine.getConverterStation1().getTerminal().getBusBreakerView().getBus() != null && hvdcLine.getConverterStation2().getTerminal().isConnected() && hvdcLine.getConverterStation2().getTerminal().getBusBreakerView().getBus() != null) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java index 26440ad47bc..5a1a6d52252 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java @@ -22,10 +22,6 @@ import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationNode; import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationSwitchingDevice; import com.powsybl.psse.model.pf.PsseSubstation.PsseSubstationEquipmentTerminal; -import org.jgrapht.Graph; -import org.jgrapht.alg.connectivity.ConnectivityInspector; -import org.jgrapht.alg.util.Pair; -import org.jgrapht.graph.Pseudograph; import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_GENERATOR; @@ -49,7 +45,7 @@ VoltageLevel create(Substation substation) { if (voltageLevel == null) { double nominalV = getNominalV(psseBus, perUnitContext.ignoreBaseVoltage()); - boolean isNodeBreakerValid = nodeBreakerValidation.isNodeBreakerSubstationCoherent(getContainersMapping().getBusesSet(voltageLevelId)); + boolean isNodeBreakerValid = nodeBreakerValidation.isNodeBreakerSubstationDataCoherent(getContainersMapping().getBusesSet(voltageLevelId)); TopologyKind topologyKind = isNodeBreakerValid ? TopologyKind.NODE_BREAKER : TopologyKind.BUS_BREAKER; voltageLevel = substation.newVoltageLevel() @@ -76,14 +72,23 @@ static double getNominalV(PsseBus psseBus, boolean isIgnoreBaseVoltage) { private void addNodeBreakerConnectivity(String voltageLevelId, VoltageLevel voltageLevel, NodeBreakerValidation nodeBreakerValidation, NodeBreakerImport nodeBreakerImport) { Set buses = getContainersMapping().getBusesSet(voltageLevelId); - PsseSubstation substation = buses.stream().map(nodeBreakerValidation::getSubstationIfOnlyOneExists) - .filter(Optional::isPresent) - .map(Optional::get) - .findFirst().orElseThrow(); - nodeBreakerImport.addTopologicalBuses(buses); + Optional psseSubstation = nodeBreakerValidation.getSubstationIfOnlyOneExists(buses); + if (psseSubstation.isPresent()) { + int lastNode = psseSubstation.get().getNodes().stream().map(PsseSubstationNode::getNi).max(Comparator.naturalOrder()).orElseThrow(); + for (int bus : buses) { + lastNode = addNodeBreakerConnectivity(voltageLevelId, voltageLevel, psseSubstation.get(), bus, lastNode, nodeBreakerValidation, nodeBreakerImport); + } + } + } + + private static int addNodeBreakerConnectivity(String voltageLevelId, VoltageLevel voltageLevel, PsseSubstation psseSubstation, int bus, int lastNodeInternalConnections, NodeBreakerValidation nodeBreakerValidation, NodeBreakerImport nodeBreakerImport) { + Set nodesSet = psseSubstation.getNodes().stream().filter(psseNode -> psseNode.getStatus() == 1 && psseNode.getI() == bus).map(PsseSubstationNode::getNi).collect(Collectors.toSet()); + + List switchingDeviceList = psseSubstation.getSwitchingDevices().stream() + .filter(sd -> nodesSet.contains(sd.getNi()) && nodesSet.contains(sd.getNj())).toList(); - for (PsseSubstationSwitchingDevice switchingDevice : substation.getSwitchingDevices()) { + for (PsseSubstationSwitchingDevice switchingDevice : switchingDeviceList) { voltageLevel.getNodeBreakerView().newSwitch() .setId(getSwitchId(voltageLevelId, switchingDevice)) .setName(switchingDevice.getName()) @@ -95,11 +100,13 @@ private void addNodeBreakerConnectivity(String voltageLevelId, VoltageLevel volt } // Define where equipment must be connected - int lastNode = substation.getNodes().stream().map(PsseSubstationNode::getNi).max(Comparator.naturalOrder()).orElseThrow(); Set nodesWithEquipment = new HashSet<>(); - for (PsseSubstationEquipmentTerminal equipmentTerminal : substation.getEquipmentTerminals()) { + + List equipmentTerminalList = psseSubstation.getEquipmentTerminals().stream().filter(eqt -> nodesSet.contains(eqt.getNi())).toList(); + + int lastNode = lastNodeInternalConnections; + for (PsseSubstationEquipmentTerminal equipmentTerminal : equipmentTerminalList) { String equipmentId = getNodeBreakerEquipmentId(equipmentTerminal.getType(), equipmentTerminal.getI(), equipmentTerminal.getJ(), equipmentTerminal.getK(), equipmentTerminal.getId()); - int bus = findBus(equipmentTerminal, buses); String equipmentIdBus = getNodeBreakerEquipmentIdBus(equipmentId, bus); // IIDM only allows one piece of equipment by node if (nodesWithEquipment.contains(equipmentTerminal.getNi())) { @@ -112,31 +119,38 @@ private void addNodeBreakerConnectivity(String voltageLevelId, VoltageLevel volt } } - // Nodes without equipment are defined as busbar sections to improve the regulating terminal selection - substation.getNodes().stream() - .map(PsseSubstationNode::getNi) - .filter(node -> !nodesWithEquipment.contains(node)) - .collect(Collectors.toSet()).forEach(node -> voltageLevel.getNodeBreakerView() + // Nodes not isolated and without equipment are defined as busbar sections to improve the regulating terminal selection + psseSubstation.getNodes().stream() + .filter(psseNode -> nodesSet.contains(psseNode.getNi()) && !nodesWithEquipment.contains(psseNode.getNi())) + .forEach(psseNode -> voltageLevel.getNodeBreakerView() .newBusbarSection() - .setId(busbarSectionId(voltageLevel.getId(), node)) - .setNode(node) + .setId(busbarSectionId(voltageLevel.getId(), psseNode.getNi())) + .setName(psseNode.getName()) + .setNode(psseNode.getNi()) .add()); // Define where controls must be connected. Psse nodes and iidm nodes are identical. - buses.forEach(bus -> { - List controls = nodeBreakerValidation.getControls(bus); - controls.forEach(control -> nodeBreakerImport.addControl(getNodeBreakerEquipmentIdBus(control.getEquipmentId(), bus), voltageLevelId, control.getNode())); - }); + List controls = nodeBreakerValidation.getControls(bus); + controls.forEach(control -> nodeBreakerImport.addControl(getNodeBreakerEquipmentIdBus(control.getEquipmentId(), bus), voltageLevelId, control.getNode())); + + // update voltages + psseSubstation.getNodes().stream() + .filter(psseNode -> nodesSet.contains(psseNode.getNi())) + .forEach(psseNode -> { + Bus busView = findBusViewNode(voltageLevel, psseNode.getNi()); + if (busView != null) { + busView.setV(psseNode.getVm() * voltageLevel.getNominalV()); + busView.setAngle(psseNode.getVa()); + } + }); + + return lastNode; } private static SwitchKind findSwitchingKind(int type) { return type == 2 ? SwitchKind.BREAKER : SwitchKind.DISCONNECTOR; } - private static int findBus(PsseSubstationEquipmentTerminal equipmentTerminal, Set buses) { - return buses.stream().filter(bus -> bus == equipmentTerminal.getI() || bus == equipmentTerminal.getJ() || bus == equipmentTerminal.getK()).min(Comparator.naturalOrder()).orElseThrow(); - } - private static int findSlackNode(NodeBreakerValidation nodeBreakerValidation, int bus) { PsseSubstation psseSubstation = nodeBreakerValidation.getSubstationIfOnlyOneExists(bus).orElseThrow(); return psseSubstation.getNodes().stream().filter(n -> n.getI() == bus) @@ -149,159 +163,81 @@ private static int connectedGenerators(PsseSubstation psseSubstation, int node) } static ContextExport createContextExport(Network network, PssePowerFlowModel psseModel) { - int maxPsseBus = psseModel.getBuses().stream().map(PsseBus::getI).max(Comparator.naturalOrder()).orElse(0); - ContextExport contextExport = new ContextExport(maxPsseBus); - - // First busBreaker voltageLevels - List busBreakerVoltageLevels = network.getVoltageLevelStream().filter(vl -> vl.getTopologyKind().equals(TopologyKind.BUS_BREAKER)).toList(); - busBreakerVoltageLevels.forEach(voltageLevel -> createBusBreakerExport(voltageLevel, contextExport)); - - // Always after busBreaker voltageLevels - findNodeBreakerVoltageLevelsAndMapPsseSubstation(network, psseModel, contextExport); - contextExport.getNodeBreakerExport().getVoltageLevels().forEach(voltageLevel -> { - Optional psseSubstation = contextExport.getNodeBreakerExport().getPsseSubstationMappedToVoltageLevel(voltageLevel); - if (psseSubstation.isPresent()) { - createNodeBreakerExport(voltageLevel, psseSubstation.get(), contextExport); + ContextExport contextExport = new ContextExport(); + mapVoltageLevelsAndPsseSubstation(network, psseModel, contextExport); + mapBusIAndPsseBus(psseModel, contextExport); + + network.getVoltageLevels().forEach(voltageLevel -> { + if (voltageLevel.getTopologyKind().equals(TopologyKind.BUS_BREAKER)) { + createBusBranchContextExport(voltageLevel, contextExport); } else { - createNodeBreakerExport(voltageLevel, contextExport); + createNodeBreakerContextExport(voltageLevel, contextExport); } }); - return contextExport; } - private static void findNodeBreakerVoltageLevelsAndMapPsseSubstation(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { + private static void mapVoltageLevelsAndPsseSubstation(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { + Map busPsseSubstation = new HashMap<>(); psseModel.getSubstations().forEach(psseSubstation -> { - VoltageLevel voltageLevel = findVoltageLevel(network, psseSubstation); - if (voltageLevel != null && voltageLevel.getTopologyKind().equals(TopologyKind.NODE_BREAKER)) { - contextExport.getNodeBreakerExport().addVoltageLevel(voltageLevel, psseSubstation); - } + Set buses = psseSubstation.getNodes().stream().map(PsseSubstationNode::getI).collect(Collectors.toSet()); + buses.forEach(bus -> busPsseSubstation.put(bus, psseSubstation)); }); - List voltageLevelList = contextExport.getNodeBreakerExport().getVoltageLevels(); - List nodeBreakerVoltageLevelsNotMapped = network.getVoltageLevelStream().filter(voltageLevel -> voltageLevel.getTopologyKind().equals(TopologyKind.NODE_BREAKER) && !voltageLevelList.contains(voltageLevel)).toList(); - contextExport.getNodeBreakerExport().addVoltageLevels(nodeBreakerVoltageLevelsNotMapped); - } - - private static void createNodeBreakerExport(VoltageLevel voltageLevel, PsseSubstation psseSubstation, ContextExport contextExport) { - List nodesAfterExcludingInternalConnections = findNodesAfterExcludingInternalConnections(voltageLevel, contextExport); - Map> busViewBusIdNodeList = findBusViewBusIdNodeList(voltageLevel, nodesAfterExcludingInternalConnections); - // First, buses with more nodes - Comparator comp = Comparator.comparingInt((String key) -> busViewBusIdNodeList.get(key).size()) - .reversed() - .thenComparing(Comparator.naturalOrder()); - - busViewBusIdNodeList.keySet().stream().sorted(comp).forEach(busViewBusId -> { - Optional bus = mapPsseBus(psseSubstation, busViewBusIdNodeList.get(busViewBusId), contextExport); - int busType = findBusViewBusType(voltageLevel, busViewBusId); - if (bus.isPresent()) { - contextExport.getNodeBreakerExport().addNodes(busViewBusId, voltageLevel, busViewBusIdNodeList.get(busViewBusId), bus.get(), busType); - } else { - int newBus = contextExport.getNewPsseBusI(); - contextExport.getNodeBreakerExport().addNodes(busViewBusId, voltageLevel, busViewBusIdNodeList.get(busViewBusId), newBus, selectCopyBus(psseSubstation), busType); - } - }); + network.getVoltageLevels().forEach(voltageLevel -> getVoltageLevelPsseSubstation(voltageLevel, busPsseSubstation) + .ifPresent(psseSubstation -> contextExport.getNodeBreakerExport().addVoltageLevelPsseSubstation(voltageLevel, psseSubstation))); + } - List isolatedNodes = findIsolatedNodes(nodesAfterExcludingInternalConnections, busViewBusIdNodeList); - isolatedNodes.forEach(node -> { - Optional bus = mapPsseBus(psseSubstation, Collections.singletonList(node), contextExport); - if (bus.isPresent()) { - contextExport.getNodeBreakerExport().addIsolatedNode(voltageLevel, node, bus.get()); - } else { - int newBus = contextExport.getNewPsseBusI(); - contextExport.getNodeBreakerExport().addIsolatedNode(voltageLevel, node, newBus, selectCopyBus(psseSubstation)); + private static Optional getVoltageLevelPsseSubstation(VoltageLevel voltageLevel, Map busPsseSubstation) { + List buses = extractBusesFromVoltageLevelId(voltageLevel.getId()); + Set psseSubstationSet = new HashSet<>(); + buses.forEach(bus -> { + if (busPsseSubstation.containsKey(bus)) { + psseSubstationSet.add(busPsseSubstation.get(bus)); } }); - - getEquipmentListToBeExported(voltageLevel).forEach(equipmentId -> - getEquipmentTerminals(voltageLevel, equipmentId).forEach(terminal -> { - int node = contextExport.getNodeBreakerExport().getSelectedNode(voltageLevel, terminal.getNodeBreakerView().getNode()).orElseThrow(); - int busI = contextExport.getNodeBreakerExport().getNodeBusI(voltageLevel, node).orElseThrow(); - int end = getSideEnd(getTerminalSide(terminal)); - contextExport.addEquipmentEnd(equipmentId, voltageLevel, node, busI, end); - })); + if (psseSubstationSet.size() >= 2) { + throw new PsseException("Only one PsseSubstation by voltageLevel. VoltageLevelId: " + voltageLevel.getId()); + } + return psseSubstationSet.isEmpty() ? Optional.empty() : Optional.of(psseSubstationSet.iterator().next()); } - private static void createNodeBreakerExport(VoltageLevel voltageLevel, ContextExport contextExport) { - createNodeBreakerExport(voltageLevel, null, contextExport); + private static void mapBusIAndPsseBus(PssePowerFlowModel psseModel, ContextExport contextExport) { + psseModel.getBuses().forEach(psseBus -> contextExport.addIbus(psseBus.getI(), psseBus)); } - private static void createBusBreakerExport(VoltageLevel voltageLevel, ContextExport contextExport) { + private static void createBusBranchContextExport(VoltageLevel voltageLevel, ContextExport contextExport) { Map> busViewBusBusBreakerViewBuses = new HashMap<>(); - voltageLevel.getBusBreakerView().getBuses().forEach(busBreakerViewBus -> busViewBusBusBreakerViewBuses.computeIfAbsent(voltageLevel.getBusView().getMergedBus(busBreakerViewBus.getId()).getId(), k -> new ArrayList<>()).add(busBreakerViewBus.getId())); - voltageLevel.getBusView().getBuses().forEach(bus -> { - int busType = findBusViewBusType(voltageLevel, bus.getId()); - String busBreakerViewId = findBusBreakerViewBusId(bus.getId(), busViewBusBusBreakerViewBuses); - OptionalInt busI = extractBusNumber(busBreakerViewId); - if (busI.isEmpty()) { - contextExport.getBusBreakerExport().addBus(bus.getId(), contextExport.getNewPsseBusI(), busType); - } else { - contextExport.getBusBreakerExport().addBus(bus.getId(), busI.getAsInt(), busType); + // psse isolated buses do not have busView + voltageLevel.getBusBreakerView().getBuses().forEach(busBreakerViewBus -> { + Bus mergedBus = voltageLevel.getBusView().getMergedBus(busBreakerViewBus.getId()); + if (mergedBus != null) { + busViewBusBusBreakerViewBuses.computeIfAbsent(mergedBus.getId(), k -> new ArrayList<>()).add(busBreakerViewBus.getId()); } }); - getEquipmentListToBeExported(voltageLevel).forEach(equipmentId -> - getEquipmentTerminals(voltageLevel, equipmentId).forEach(terminal -> { - Bus bus = getTerminalBus(terminal); - int busI = contextExport.getBusBreakerExport().getBusBusI(bus.getId()).orElseThrow(); - int end = getSideEnd(terminal.getSide()); - contextExport.addEquipmentEnd(equipmentId, voltageLevel, busI, end); - })); - } - - private static List findNodesAfterExcludingInternalConnections(VoltageLevel voltageLevel, ContextExport contextExport) { - Graph> inGraph = new Pseudograph<>(null, null, false); - - for (int node : voltageLevel.getNodeBreakerView().getNodes()) { - inGraph.addVertex(node); - } - voltageLevel.getNodeBreakerView().getInternalConnections().forEach(internalConnection -> inGraph.addEdge(internalConnection.getNode1(), internalConnection.getNode2(), Pair.of(internalConnection.getNode1(), internalConnection.getNode2()))); - - List> componentsSetList = new ConnectivityInspector<>(inGraph).connectedSets(); - - componentsSetList.forEach(componetSet -> contextExport.getNodeBreakerExport().addSelectedNode(voltageLevel, componetSet, componetSet.stream().min(Comparator.naturalOrder()).orElseThrow())); - return contextExport.getNodeBreakerExport().getSelectedNodes(voltageLevel); - } - - private static Map> findBusViewBusIdNodeList(VoltageLevel voltageLevel, List nodesAfterExcludingInternalConnections) { - Map> busViewBusIdNodeList = new HashMap<>(); - - nodesAfterExcludingInternalConnections.forEach(node -> { - Terminal terminal = findTerminalNode(voltageLevel, node); - if (terminal != null) { - Bus bus = terminal.getBusView().getBus(); - if (bus != null) { - busViewBusIdNodeList.computeIfAbsent(bus.getId(), k -> new ArrayList<>()).add(node); - } - } + voltageLevel.getBusView().getBuses().forEach(bus -> { + String busBreakerViewId = findBusBreakerViewBusId(bus.getId(), busViewBusBusBreakerViewBuses); + extractBusNumber(busBreakerViewId).ifPresent(busI -> contextExport.addBus(busI, bus.getId(), findBusViewBusType(voltageLevel, bus))); }); - return busViewBusIdNodeList; - } - - private static List findIsolatedNodes(List nodesAfterExcludingInternalConnections, Map> busViewBusIdNodeList) { - List psseBusesIAssociatedWithBus = busViewBusIdNodeList.values().stream().flatMap(List::stream).toList(); - return nodesAfterExcludingInternalConnections.stream().filter(node -> !psseBusesIAssociatedWithBus.contains(node)).toList(); } - private static Optional mapPsseBus(PsseSubstation psseSubstation, List nodes, ContextExport contextExport) { - if (psseSubstation == null) { - return Optional.empty(); + private static String findBusBreakerViewBusId(String busViewBusId, Map> busViewBusBusBreakerViewBuses) { + if (busViewBusBusBreakerViewBuses.containsKey(busViewBusId)) { + List busBreakerViewBuses = busViewBusBusBreakerViewBuses.get(busViewBusId); + if (busBreakerViewBuses.isEmpty()) { + throw new PsseException("BusView without busBreakerView: " + busViewBusId); + } else { + return busBreakerViewBuses.stream().sorted().toList().get(0); + } + } else { + throw new PsseException("BusView bus does not found: " + busViewBusId); } - - Comparator comp = Comparator.comparingInt((Integer busI) -> nodesAssociatedWithBus(psseSubstation, nodes, busI).size()) - .reversed() - .thenComparing(Comparator.naturalOrder()); - - return psseSubstation.getNodes().stream() - .map(PsseSubstationNode::getI).filter(contextExport::isFreePsseBusI) - .collect(Collectors.toSet()) - .stream().min(comp); } - private static int findBusViewBusType(VoltageLevel voltageLevel, String busViewBusId) { - Bus bus = voltageLevel.getBusView().getBus(busViewBusId); - if (bus == null) { // unexpected + private static int findBusViewBusType(VoltageLevel voltageLevel, Bus bus) { + if (!bus.isInMainConnectedComponent()) { return 4; } SlackTerminal slackTerminal = voltageLevel.getExtension(SlackTerminal.class); @@ -318,53 +254,64 @@ private static boolean withLocalRegulatingControl(Generator generator) { && generator.getTerminal().getBusView().getBus().equals(generator.getRegulatingTerminal().getBusView().getBus()); } - private static Integer selectCopyBus(PsseSubstation psseSubstation) { - return psseSubstation != null ? psseSubstation.getNodes().stream().map(PsseSubstationNode::getI).min(Comparator.naturalOrder()).orElseThrow() : null; - } - - private static List nodesAssociatedWithBus(PsseSubstation psseSubstation, List nodes, int busI) { - return psseSubstation.getNodes().stream().filter(n -> n.getI() == busI && nodes.contains(n.getNi())).map(PsseSubstationNode::getNi).toList(); - } - - private static String findBusBreakerViewBusId(String busViewBusId, Map> busViewBusBusBreakerViewBuses) { - if (busViewBusBusBreakerViewBuses.containsKey(busViewBusId)) { - List busBreakerViewBuses = busViewBusBusBreakerViewBuses.get(busViewBusId); - if (busBreakerViewBuses.isEmpty()) { - throw new PsseException("BusView without busBreakerView: " + busViewBusId); - } else { - return busBreakerViewBuses.stream().sorted().toList().get(0); + // All the nodes are always associated with the same busI, so the busViewId will be ok only when we do not have bus-sections + private static void createNodeBreakerContextExport(VoltageLevel voltageLevel, ContextExport contextExport) { + Map> busIBusViews = new HashMap<>(); + PsseSubstation psseSubstation = contextExport.getNodeBreakerExport().getVoltageLevelPsseSubstation(voltageLevel).orElseThrow(); + for (int node : voltageLevel.getNodeBreakerView().getNodes()) { + Bus bus = findBusViewNode(voltageLevel, node); + if (bus != null) { + contextExport.getNodeBreakerExport().addNode(voltageLevel, node, bus.getId()); + findBusI(psseSubstation, node).ifPresent(busI -> busIBusViews.computeIfAbsent(busI, k -> new ArrayList<>()).add(bus)); } - } else { - throw new PsseException("BusView bus does not found: " + busViewBusId); } + // we try to assign a busView inside mainConnectedComponent with the strong psse bus type and, we preserve the original bus type + busIBusViews.forEach((busI, busList) -> { + Bus selectedBus = busList.stream().min(Comparator.comparingInt(busView -> findType(voltageLevel, busView))).orElseThrow(); + int type = contextExport.getPsseBus(busI).map(PsseBus::getIde).orElseGet(() -> findBusViewBusType(voltageLevel, selectedBus)); + contextExport.addBus(busI, selectedBus.getId(), type); + }); } - private static int getSideEnd(ThreeSides side) { - return side == null ? 1 : side.getNum(); + private static int findType(VoltageLevel voltageLevel, Bus busView) { + int type = findBusViewBusType(voltageLevel, busView); + return switch (type) { + case 3 -> 0; + case 2 -> 1; + case 1 -> 2; + case 4 -> 3; + default -> throw new PsseException("Unexpected psse bus type: " + type); + }; } - private static VoltageLevel findVoltageLevel(Network network, PsseSubstation psseSubstation) { - Set busesSet = psseSubstation.getNodes().stream().map(PsseSubstationNode::getI).collect(Collectors.toSet()); - String voltageLevelId = getVoltageLevelId(busesSet); - return network.getVoltageLevel(voltageLevelId); + private static Optional findBusI(PsseSubstation psseSubstation, int node) { + return psseSubstation.getNodes().stream().filter(psseNode -> psseNode.getNi() == node).map(PsseSubstationNode::getI).findFirst(); } - static void updateSubstations(ContextExport contextExport) { - contextExport.getNodeBreakerExport().getVoltageLevels().forEach(voltageLevel -> { - Optional optionalPsseSubstation = contextExport.getNodeBreakerExport().getPsseSubstationMappedToVoltageLevel(voltageLevel); - optionalPsseSubstation.ifPresent(psseSubstation -> updateSubstation(voltageLevel, psseSubstation, contextExport)); + static void updateSubstations(Network network, ContextExport contextExport) { + network.getVoltageLevels().forEach(voltageLevel -> { + if (voltageLevel.getTopologyKind().equals(TopologyKind.NODE_BREAKER)) { + Set buses = new HashSet<>(extractBusesFromVoltageLevelId(voltageLevel.getId())); + contextExport.getNodeBreakerExport().getVoltageLevelPsseSubstation(voltageLevel).ifPresent(psseSubstation -> updateSubstation(voltageLevel, psseSubstation, buses, contextExport)); + } }); } - private static void updateSubstation(VoltageLevel voltageLevel, PsseSubstation psseSubstation, ContextExport contextExport) { - psseSubstation.getNodes().forEach(psseSubstationNode -> { - int bus = contextExport.getNodeBreakerExport().getNodeBusI(voltageLevel, psseSubstationNode.getNi()).orElseThrow(); - boolean inService = contextExport.getNodeBreakerExport().isNodeInService(voltageLevel, psseSubstationNode.getNi()).orElseThrow(); - psseSubstationNode.setI(bus); - psseSubstationNode.setStatus(inService ? 1 : 0); - }); + private static void updateSubstation(VoltageLevel voltageLevel, PsseSubstation psseSubstation, Set busesSet, ContextExport contextExport) { + Set psseNodeSet = psseSubstation.getNodes().stream().filter(psseNode -> busesSet.contains(psseNode.getI())).collect(Collectors.toSet()); + psseNodeSet.forEach(psseSubstationNode -> contextExport.getNodeBreakerExport().getNodeViewBusId(voltageLevel, psseSubstationNode.getNi()).ifPresent(busViewBusId -> { + Bus bus = voltageLevel.getBusView().getBus(busViewBusId); + if (bus != null) { + psseSubstationNode.setVm(getVm(bus)); + psseSubstationNode.setVa(getVa(bus)); + } + })); + + Set nodesSet = psseNodeSet.stream().map(PsseSubstationNode::getNi).collect(Collectors.toSet()); + Set switchingDeviceSet = psseSubstation.getSwitchingDevices().stream() + .filter(sd -> nodesSet.contains(sd.getNi()) && nodesSet.contains(sd.getNj())).collect(Collectors.toSet()); - psseSubstation.getSwitchingDevices().forEach(switchingDevice -> { + switchingDeviceSet.forEach(switchingDevice -> { String switchId = getSwitchId(voltageLevel.getId(), switchingDevice); Switch sw = voltageLevel.getNodeBreakerView().getSwitch(switchId); if (sw == null) { @@ -372,44 +319,6 @@ private static void updateSubstation(VoltageLevel voltageLevel, PsseSubstation p } switchingDevice.setStatus(sw.isOpen() ? 0 : 1); }); - - // Always are created to avoid changing the id of lines, twoWindingsTransformers and threeWindingsTransformers - // the id must be created with the sorted buses if we want to obtain the equipment with the equipmentTerminal data - psseSubstation.getEquipmentTerminals().clear(); - psseSubstation.getEquipmentTerminals().addAll(createPsseSubstationEquipmentTerminals(voltageLevel, contextExport)); - } - - private static List createPsseSubstationEquipmentTerminals(VoltageLevel voltageLevel, ContextExport contextExport) { - List equipmentTerminals = new ArrayList<>(); - - getEquipmentListToBeExported(voltageLevel).forEach(equipmentId -> getEquipmentNodes(voltageLevel, equipmentId).forEach(node -> { - int selectedNode = contextExport.getNodeBreakerExport().getSelectedNode(voltageLevel, node).orElseThrow(); - List busesList = contextExport.getEquipmentBusesList(equipmentId, voltageLevel, selectedNode); - if (busesList.size() == 3) { - Identifiable identifiable = getIdentifiable(voltageLevel, equipmentId); - PsseSubstation.PsseSubstationEquipmentTerminal equipmentTerminal = new PsseSubstationEquipmentTerminal(); - equipmentTerminal.setNi(selectedNode); - equipmentTerminal.setType(getPsseEquipmentType(identifiable)); - equipmentTerminal.setId(contextExport.getEquipmentCkt(equipmentId, identifiable.getType(), busesList.get(0), busesList.get(1), busesList.get(2))); - equipmentTerminal.setI(busesList.get(0)); - equipmentTerminal.setJ(busesList.get(1)); - equipmentTerminal.setK(busesList.get(2)); - - equipmentTerminals.add(equipmentTerminal); - } else { - throw new PsseException("Unexpected size of the busesList. Must be 3 and it is " + busesList.size()); - } - })); - return equipmentTerminals; - } - - private static Identifiable getIdentifiable(VoltageLevel voltageLevel, String identifiableId) { - Identifiable identifiable = voltageLevel.getNetwork().getIdentifiable(identifiableId); - if (identifiable != null) { - return identifiable; - } else { - throw new PsseException("Unexpected identifiableId: " + identifiableId); - } } private final PsseBus psseBus; diff --git a/psse/psse-converter/src/test/resources/IEEE_118_bus.xiidm b/psse/psse-converter/src/test/resources/IEEE_118_bus.xiidm index 401f066be5a..bcfa04efdef 100644 --- a/psse/psse-converter/src/test/resources/IEEE_118_bus.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_118_bus.xiidm @@ -39,7 +39,7 @@ - + @@ -52,7 +52,7 @@ - + @@ -149,14 +149,14 @@ - + - + @@ -228,7 +228,7 @@ - + @@ -240,7 +240,7 @@ - + @@ -337,7 +337,7 @@ - + @@ -346,7 +346,7 @@ - + @@ -546,7 +546,7 @@ - + @@ -556,7 +556,7 @@ - + @@ -571,7 +571,7 @@ - + @@ -580,7 +580,7 @@ - + @@ -598,7 +598,7 @@ - + @@ -611,7 +611,7 @@ - + @@ -626,7 +626,7 @@ - + @@ -635,7 +635,7 @@ - + @@ -745,7 +745,7 @@ - + @@ -755,7 +755,7 @@ - + @@ -1123,16 +1123,16 @@ - + - + - - + + - - + + @@ -1141,13 +1141,13 @@ - + - - - - + + + + @@ -1155,30 +1155,30 @@ - + - - + + - + - + - + - - - - + + + + @@ -1192,15 +1192,15 @@ - + - - - + + + @@ -1208,29 +1208,29 @@ - + - + - - - - - + + + + + - - + + - - - - - - - - - + + + + + + + + + @@ -1242,15 +1242,15 @@ - - + + - - - - - + + + + + @@ -1297,7 +1297,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_bus.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_bus.xiidm index 36ba633dbc5..e2c8c56c8c3 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_bus.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_bus.xiidm @@ -33,7 +33,7 @@ - + @@ -45,19 +45,19 @@ - + - + - + @@ -68,7 +68,7 @@ - + @@ -125,19 +125,19 @@ - + - - - - - - - - - - - + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm index a8aac76d202..6d746618588 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35.xiidm @@ -3,8 +3,8 @@ - - + + @@ -18,8 +18,8 @@ - - + + @@ -46,7 +46,7 @@ - + @@ -58,19 +58,19 @@ - + - + - + @@ -81,7 +81,7 @@ - + @@ -138,19 +138,19 @@ - + - - - - - - - - - - - + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw index bcbfdcfe666..9be75617c4a 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw +++ b/psse/psse-converter/src/test/resources/IEEE_14_bus_nodeBreaker_rev35_split_bus_exported.raw @@ -16,8 +16,6 @@ 12,'Bus 12 ',138.0,1,1,1,1,1.05519,-15.0755 13,'Bus 13 ',138.0,1,1,1,1,1.05038,-15.1562 14,'Bus 14 ',138.0,1,1,1,1,1.03553,-16.0336 -15,'Bus 1-15 ',138.0,1,1,1,1,1.0,0.0 -16,'Bus 2-16 ',138.0,1,1,1,1,1.0,0.0 0 / END OF BUS DATA, BEGIN LOAD DATA 2,'1 ',1,1,1,21.7,12.7,0.0,0.0,0.0,-0.0,1,1 3,'1 ',1,1,1,94.2,19.0,0.0,0.0,0.0,-0.0,1,1 @@ -39,11 +37,11 @@ 6,'1 ',0.0,12.73,24.0,-6.0,1.07,0,0,25.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 8,'1 ',0.0,17.623,24.0,-6.0,1.09,0,0,25.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 0 / END OF GENERATOR DATA, BEGIN BRANCH DATA -15,2,'1 ',0.01938,0.05917,0.0528,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +1,2,'1 ',0.01938,0.05917,0.0528,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 1,5,'1 ',0.05403,0.22304,0.0492,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 -16,3,'1 ',0.04699,0.19797,0.0438,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 -16,4,'1 ',0.05811,0.17632,0.034,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 -16,5,'1 ',0.05695,0.17388,0.0346,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +2,3,'1 ',0.04699,0.19797,0.0438,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +2,4,'1 ',0.05811,0.17632,0.034,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 +2,5,'1 ',0.05695,0.17388,0.0346,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 3,4,'1 ',0.06701,0.17103,0.0128,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 4,5,'1 ',0.01335,0.04211,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 6,11,'1 ',0.09498,0.1989,0.0,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 @@ -88,9 +86,9 @@ 0 / END OF INDUCTION MACHINE DATA, BEGIN SUBSTATION DATA 1,'STATION 1',0.0,0.0,0.1 / BEGIN SUBSTATION NODE DATA -1,'NB1',15,1,1.0,0.0 +1,'NB1',1,1,1.0,0.0 2,'NB2',1,1,1.0,0.0 -3,'NL2',15,1,1.0,0.0 +3,'NL2',1,1,1.0,0.0 4,'NL5',1,1,1.0,0.0 5,'NG1',1,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA @@ -100,16 +98,16 @@ 2,5,'1 ','Sw-Gen1',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 1,5,'M','1 ' -15,3,'B',2,'1 ' +1,3,'B',2,'1 ' 1,4,'B',5,'1 ' 0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA 2,'STATION 5',0.0,0.0,0.1 / BEGIN SUBSTATION NODE DATA 1,'NB1',2,1,1.0,0.0 -2,'NB2',16,1,1.0,0.0 -3,'NL3',16,1,1.0,0.0 -4,'NL4',16,1,1.0,0.0 -5,'NL5',16,1,1.0,0.0 +2,'NB2',2,1,1.0,0.0 +3,'NL3',2,1,1.0,0.0 +4,'NL4',2,1,1.0,0.0 +5,'NL5',2,1,1.0,0.0 6,'NL1',2,1,1.0,0.0 7,'NG1',2,1,1.0,0.0 8,'NLd1',2,1,1.0,0.0 @@ -124,10 +122,10 @@ 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA 2,7,'M','1 ' 2,8,'L','1 ' -2,6,'B',15,'1 ' -16,3,'B',3,'1 ' -16,4,'B',4,'1 ' -16,5,'B',5,'1 ' +2,6,'B',1,'1 ' +2,3,'B',3,'1 ' +2,4,'B',4,'1 ' +2,5,'B',5,'1 ' 0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA 0 / END OF SUBSTATION DATA Q diff --git a/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids.xiidm index 90522a1c496..c37689ae42e 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids.xiidm @@ -37,7 +37,7 @@ - + @@ -52,29 +52,29 @@ - + - + - + - + - + @@ -85,7 +85,7 @@ - + @@ -142,19 +142,19 @@ - + - - - - - - - - - - - + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm index 48eda6689cf..fb849869d40 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_buses_duplicate_ids_rev35.xiidm @@ -49,7 +49,7 @@ - + @@ -64,24 +64,24 @@ - + - + - + - + @@ -92,7 +92,7 @@ - + @@ -155,19 +155,19 @@ - + - - - - - - - - - - - + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_buses_zip_load.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_buses_zip_load.xiidm index a2b268eb221..76957ebca8c 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_buses_zip_load.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_buses_zip_load.xiidm @@ -35,7 +35,7 @@ - + @@ -47,19 +47,19 @@ - + - + - + @@ -70,7 +70,7 @@ - + @@ -127,19 +127,19 @@ - + - - - - - - - - - - - + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_14_isolated_buses.xiidm b/psse/psse-converter/src/test/resources/IEEE_14_isolated_buses.xiidm index 04587539072..30be1e60b85 100644 --- a/psse/psse-converter/src/test/resources/IEEE_14_isolated_buses.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_14_isolated_buses.xiidm @@ -33,7 +33,7 @@ - + @@ -45,19 +45,19 @@ - + - + - + @@ -68,7 +68,7 @@ - + @@ -167,19 +167,19 @@ - + - - - - - - - - - - - + + + + + + + + + + + diff --git a/psse/psse-converter/src/test/resources/IEEE_24_bus.xiidm b/psse/psse-converter/src/test/resources/IEEE_24_bus.xiidm index 17f16ece4c0..1c9176f8871 100644 --- a/psse/psse-converter/src/test/resources/IEEE_24_bus.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_24_bus.xiidm @@ -57,7 +57,7 @@ - + @@ -67,13 +67,13 @@ - + - + @@ -81,7 +81,7 @@ - + @@ -89,7 +89,7 @@ - + @@ -97,7 +97,7 @@ - + @@ -105,7 +105,7 @@ - + @@ -271,7 +271,7 @@ - + @@ -295,7 +295,7 @@ - + @@ -303,7 +303,7 @@ - + @@ -311,7 +311,7 @@ - + @@ -327,7 +327,7 @@ - + @@ -335,7 +335,7 @@ - + @@ -343,7 +343,7 @@ - + @@ -351,7 +351,7 @@ - + @@ -359,7 +359,7 @@ - + @@ -367,7 +367,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/IEEE_57_bus.xiidm b/psse/psse-converter/src/test/resources/IEEE_57_bus.xiidm index c1a620eca44..7707a29b4a8 100644 --- a/psse/psse-converter/src/test/resources/IEEE_57_bus.xiidm +++ b/psse/psse-converter/src/test/resources/IEEE_57_bus.xiidm @@ -34,7 +34,7 @@ - + @@ -44,12 +44,12 @@ - + - + @@ -75,14 +75,14 @@ - + - + @@ -100,7 +100,7 @@ - + @@ -111,14 +111,14 @@ - + - + @@ -126,14 +126,14 @@ - + - + @@ -142,12 +142,12 @@ - + - + @@ -165,7 +165,7 @@ - + @@ -173,35 +173,35 @@ - + - + - + - + - + @@ -232,14 +232,14 @@ - + - + @@ -261,13 +261,13 @@ - + - + @@ -317,14 +317,14 @@ - + - + @@ -369,28 +369,28 @@ - + - + - + - + @@ -463,70 +463,70 @@ - + - - - - + + + + - + - - - - - - - - - + + + + + + + + + - - - - - - + + + + + + - - - + + + - + - - + + - - - + + + - + - + - - - - - - - + + + + + + + - - - + + + - - + + diff --git a/psse/psse-converter/src/test/resources/IsolatedSlackBus.xiidm b/psse/psse-converter/src/test/resources/IsolatedSlackBus.xiidm index a01f8feb95b..24b5cbf4c89 100644 --- a/psse/psse-converter/src/test/resources/IsolatedSlackBus.xiidm +++ b/psse/psse-converter/src/test/resources/IsolatedSlackBus.xiidm @@ -1,7 +1,7 @@ - + @@ -11,7 +11,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/RawCaseWithSpecialCharacters.xiidm b/psse/psse-converter/src/test/resources/RawCaseWithSpecialCharacters.xiidm index 51c6428eff1..f7fea839fd9 100644 --- a/psse/psse-converter/src/test/resources/RawCaseWithSpecialCharacters.xiidm +++ b/psse/psse-converter/src/test/resources/RawCaseWithSpecialCharacters.xiidm @@ -1,7 +1,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/SwitchedShunt.xiidm b/psse/psse-converter/src/test/resources/SwitchedShunt.xiidm index d5b7c9792a1..a1706380e13 100644 --- a/psse/psse-converter/src/test/resources/SwitchedShunt.xiidm +++ b/psse/psse-converter/src/test/resources/SwitchedShunt.xiidm @@ -1,7 +1,7 @@ - + @@ -34,7 +34,7 @@ - + @@ -42,7 +42,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/SwitchedShuntWithZeroVswlo.xiidm b/psse/psse-converter/src/test/resources/SwitchedShuntWithZeroVswlo.xiidm index 9b8f3258737..19b1e3147c6 100644 --- a/psse/psse-converter/src/test/resources/SwitchedShuntWithZeroVswlo.xiidm +++ b/psse/psse-converter/src/test/resources/SwitchedShuntWithZeroVswlo.xiidm @@ -1,7 +1,7 @@ - + @@ -34,7 +34,7 @@ - + @@ -42,7 +42,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/ThreeMIB_T3W_modified.xiidm b/psse/psse-converter/src/test/resources/ThreeMIB_T3W_modified.xiidm index ad96500f746..440ebcc328a 100644 --- a/psse/psse-converter/src/test/resources/ThreeMIB_T3W_modified.xiidm +++ b/psse/psse-converter/src/test/resources/ThreeMIB_T3W_modified.xiidm @@ -1,7 +1,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/ThreeMIB_T3W_phase.xiidm b/psse/psse-converter/src/test/resources/ThreeMIB_T3W_phase.xiidm index 9ee433b1202..74e718e6af3 100644 --- a/psse/psse-converter/src/test/resources/ThreeMIB_T3W_phase.xiidm +++ b/psse/psse-converter/src/test/resources/ThreeMIB_T3W_phase.xiidm @@ -1,7 +1,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/TransformersWithZeroNomV.xiidm b/psse/psse-converter/src/test/resources/TransformersWithZeroNomV.xiidm index d475e1c0745..693d7290aa6 100644 --- a/psse/psse-converter/src/test/resources/TransformersWithZeroNomV.xiidm +++ b/psse/psse-converter/src/test/resources/TransformersWithZeroNomV.xiidm @@ -1,7 +1,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/psse/psse-converter/src/test/resources/TwoWindingsTransformerPhase.xiidm b/psse/psse-converter/src/test/resources/TwoWindingsTransformerPhase.xiidm index 0be0f5d600a..8868aa2bdde 100644 --- a/psse/psse-converter/src/test/resources/TwoWindingsTransformerPhase.xiidm +++ b/psse/psse-converter/src/test/resources/TwoWindingsTransformerPhase.xiidm @@ -1,7 +1,7 @@ - + @@ -11,13 +11,13 @@ - + - + diff --git a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm index aa8628bc9b3..c86e508fdbb 100644 --- a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm +++ b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35.xiidm @@ -3,8 +3,8 @@ - - + + @@ -20,8 +20,8 @@ - - + + @@ -31,8 +31,8 @@ - - + + @@ -69,8 +69,8 @@ - - + + @@ -85,8 +85,8 @@ - - + + diff --git a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw index 120329c0f3b..190ed38a94e 100644 --- a/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw +++ b/psse/psse-converter/src/test/resources/five_bus_nodeBreaker_rev35_split_buses_exported.raw @@ -2,46 +2,37 @@ 17/04/24 UW ARCHIVE 100.0 1962 W Five Bus nodeBreaker Test Case 0 / END OF SYSTEM-WIDE DATA, BEGIN BUS DATA -1,'Bus 1 ',138.0,1,1,1,1,1.0,0.0 +1,'Bus 1 ',138.0,3,1,1,1,1.0,0.0 2,'Bus 2 ',138.0,1,1,1,1,1.0,0.0 3,'Bus 3 ',45.0,1,1,1,1,1.0,0.0 4,'Bus 4 ',21.0,1,1,1,1,1.0,0.0 5,'Bus 5 ',138.0,1,1,1,1,1.0,0.0 -6,'Bus 1-6 ',138.0,3,1,1,1,1.0,0.0 -7,'Bus 2-7 ',138.0,1,1,1,1,1.0,0.0 -8,'Bus 2-8 ',138.0,4,1,1,1,0.0,0.0 -9,'Bus 3-9 ',45.0,4,1,1,1,0.0,0.0 -10,'Bus 3-10 ',45.0,4,1,1,1,0.0,0.0 -11,'Bus 4-11 ',21.0,4,1,1,1,0.0,0.0 -12,'Bus 4-12 ',21.0,4,1,1,1,0.0,0.0 -13,'Bus 5-13 ',138.0,1,1,1,1,1.0,0.0 -14,'Bus 5-14 ',138.0,4,1,1,1,0.0,0.0 0 / END OF BUS DATA, BEGIN LOAD DATA -8,'1 ',0,1,1,21.7,12.7,0.0,0.0,0.0,-0.0,1,1 -10,'1 ',0,1,1,94.2,19.0,0.0,0.0,0.0,-0.0,1,1 -12,'1 ',0,1,1,47.8,-3.9,0.0,0.0,0.0,-0.0,1,1 -14,'1 ',0,1,1,7.6,1.6,0.0,0.0,0.0,-0.0,1,1 +2,'1 ',0,1,1,21.7,12.7,0.0,0.0,0.0,-0.0,1,1 +3,'1 ',0,1,1,94.2,19.0,0.0,0.0,0.0,-0.0,1,1 +4,'1 ',0,1,1,47.8,-3.9,0.0,0.0,0.0,-0.0,1,1 +5,'1 ',0,1,1,7.6,1.6,0.0,0.0,0.0,-0.0,1,1 0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA -7,'1 ',1,0.0,19.0 +2,'1 ',1,0.0,19.0 0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA -6,'1 ',232.392,-16.549,0.0,0.0,1.06,1,2,615.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 +1,'1 ',232.392,-16.549,0.0,0.0,1.06,1,2,615.0,0.0,1.0,0.0,0.0,1.0,1,100.0,10000.0,-10000.0,0,1,1.0,0,1.0,0,1.0,0,1.0,0,1.0 0 / END OF GENERATOR DATA, BEGIN BRANCH DATA 1,2,'1 ',0.01938,0.05917,0.0528,' ',0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,1,0.0,1,1.0,0,1.0,0,1.0,0,1.0 0 / END OF BRANCH DATA, BEGIN SYSTEM SWITCHING DEVICE DATA 0 / END OF SYSTEM SWITCHING DEVICE DATA, BEGIN TRANSFORMER DATA 1,3,0,'1 ',1,1,1,0.0,0.0,2,'2WT ',1,1,1.0,0,1.0,0,1.0,0,1.0 0.0,0.20912,100.0 -0.978,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,9,2,1.5,0.51,1.5,0.51,3,0,0.0,0.0 +0.978,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,3,2,1.5,0.51,1.5,0.51,3,0,0.0,0.0 1.0,0.0 1,3,4,'1 ',1,1,1,0.0,0.0,2,'3WT ',1,1,1.0,0,1.0,0,1.0,0,1.0 334279.0,0.13432,440.0,262298.0,0.20807,280.0,1515.0,0.10652,160.0,1.0,0.0 0.978,138.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,3,0,0.0,0.0 0.988,45.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,1.5,0.51,1.5,0.51,3,0,0.0,0.0 -0.9980000000000001,21.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,11,2,1.5,0.51,1.5,0.51,3,0,0.0,0.0 +0.9980000000000001,21.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,4,2,1.5,0.51,1.5,0.51,3,0,0.0,0.0 0 / END OF TRANSFORMER DATA, BEGIN AREA DATA 0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA 'EATL P1 ',1,7.365,0.0,500.0,0.0,7.365,0.1,'R',0.0,50,1.0 -6,1,17.3,12.7,0.48,21.32,500.0,0.832,1.1,1.2,0.975,0.0125,0,0,0,0,'1 ',0.0 +1,1,17.3,12.7,0.48,21.32,500.0,0.832,1.1,1.2,0.975,0.0125,0,0,0,0,'1 ',0.0 5,1,20.5,18.0,0.48,21.32,240.0,1.7325,1.1419,1.2064,0.8968,0.0129,0,0,0,0,'1 ',0.0 0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA 0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA @@ -52,19 +43,19 @@ 0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA 0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA 0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA -13,'1 ',0,0,1,1.0,0.99,13,2,100.0,' ',100.0,1,1,100.0 +5,'1 ',0,0,1,1.0,0.99,5,2,100.0,' ',100.0,1,1,100.0 0 / END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA 0 / END OF GNE DEVICE DATA, BEGIN INDUCTION MACHINE DATA 0 / END OF INDUCTION MACHINE DATA, BEGIN SUBSTATION DATA 1,'STATION 1',0.0,0.0,0.1 / BEGIN SUBSTATION NODE DATA -1,'NB1',6,1,1.0,0.0 +1,'NB1',1,1,1.0,0.0 2,'NB2',1,1,1.0,0.0 3,'NLINE',1,1,1.0,0.0 4,'NT2W',1,1,1.0,0.0 5,'NT3W',1,1,1.0,0.0 -6,'NDCLINE',6,1,1.0,0.0 -7,'NGEN',6,1,1.0,0.0 +6,'NDCLINE',1,1,1.0,0.0 +7,'NGEN',1,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA 1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 2,3,'1 ','Sw-LineToBus2',2,1,1,0.0,0.0,0.0,0.0 @@ -73,8 +64,8 @@ 1,6,'1 ','Sw-LineDcToBus5',2,1,1,0.0,0.0,0.0,0.0 1,7,'1 ','Sw-Gen',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA -6,7,'M','1 ' -6,6,'D','EATL P1 ' +1,7,'M','1 ' +1,6,'D','EATL P1 ' 1,3,'B',2,'1 ' 1,4,'2',3,'1 ' 1,5,'3',3,4,'1 ' @@ -82,66 +73,66 @@ 2,'STATION 2',0.0,0.0,0.1 / BEGIN SUBSTATION NODE DATA 1,'NB1',2,1,1.0,0.0 -2,'NB2',7,1,1.0,0.0 +2,'NB2',2,1,1.0,0.0 3,'NLINE',2,1,1.0,0.0 -4,'NLOAD',8,0,1.0,0.0 -5,'NFSHUNT',7,1,1.0,0.0 +4,'NLOAD',2,1,1.0,0.0 +5,'NFSHUNT',2,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA 1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 1,3,'1 ','Sw-LineToBus1',2,1,1,0.0,0.0,0.0,0.0 1,4,'1 ','Sw-Load',2,0,1,0.0,0.0,0.0,0.0 2,5,'1 ','Sw-FixedShunt',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA -8,4,'L','1 ' -7,5,'F','1 ' +2,4,'L','1 ' +2,5,'F','1 ' 2,3,'B',1,'1 ' 0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA 3,'STATION 3',0.0,0.0,0.1 / BEGIN SUBSTATION NODE DATA 1,'NB1',3,1,1.0,0.0 -2,'NB2',9,0,1.0,0.0 +2,'NB2',3,1,1.0,0.0 3,'NT2W',3,1,1.0,0.0 4,'NT3W',3,1,1.0,0.0 -5,'NLOAD',10,0,1.0,0.0 +5,'NLOAD',3,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA 1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 1,3,'1 ','Sw-T2w',2,1,1,0.0,0.0,0.0,0.0 1,4,'1 ','Sw-T3w',2,1,1,0.0,0.0,0.0,0.0 2,5,'1 ','Sw-Load',2,0,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA -10,5,'L','1 ' +3,5,'L','1 ' 3,3,'2',1,'1 ' 3,4,'3',1,4,'1 ' 0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA 4,'STATION 4',0.0,0.0,0.1 / BEGIN SUBSTATION NODE DATA 1,'NB1',4,1,1.0,0.0 -2,'NB2',11,0,1.0,0.0 +2,'NB2',4,1,1.0,0.0 3,'NT3W',4,1,1.0,0.0 -4,'NLOAD',12,0,1.0,0.0 +4,'NLOAD',4,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA 1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 1,3,'1 ','Sw-T3w',2,1,1,0.0,0.0,0.0,0.0 2,4,'1 ','Sw-Load',2,0,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA -12,4,'L','1 ' +4,4,'L','1 ' 4,3,'3',1,3,'1 ' 0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA 5,'STATION 5',0.0,0.0,0.1 / BEGIN SUBSTATION NODE DATA 1,'NB1',5,1,1.0,0.0 -2,'NB2',13,1,1.0,0.0 +2,'NB2',5,1,1.0,0.0 3,'NDCLINE',5,1,1.0,0.0 -4,'NLOAD',14,0,1.0,0.0 -5,'NSSHUNT',13,1,1.0,0.0 +4,'NLOAD',5,1,1.0,0.0 +5,'NSSHUNT',5,1,1.0,0.0 0 / END OF SUBSTATION NODE DATA, BEGIN SUBSTATION SWITCHING DEVICE DATA 1,2,'1 ','Sw-BusBars',2,0,1,0.0,0.0,0.0,0.0 1,3,'1 ','Sw-DcLine',2,1,1,0.0,0.0,0.0,0.0 1,4,'1 ','Sw-Load',2,0,1,0.0,0.0,0.0,0.0 2,5,'1 ','Sw-SwitchedShunt',2,1,1,0.0,0.0,0.0,0.0 0 / END OF SUBSTATION SWITCHING DEVICE DATA, BEGIN SUBSTATION EQUIPMENT TERMINAL DATA -14,4,'L','1 ' -13,5,'S','1 ' +5,4,'L','1 ' +5,5,'S','1 ' 5,3,'D','EATL P1 ' 0 / END OF SUBSTATION EQUIPMENT TERMINAL DATA 0 / END OF SUBSTATION DATA diff --git a/psse/psse-converter/src/test/resources/remoteControl.xiidm b/psse/psse-converter/src/test/resources/remoteControl.xiidm index 46e83a148b0..727ac2e9a7f 100644 --- a/psse/psse-converter/src/test/resources/remoteControl.xiidm +++ b/psse/psse-converter/src/test/resources/remoteControl.xiidm @@ -39,7 +39,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -73,7 +73,7 @@ - + @@ -95,7 +95,7 @@ - + From e180561b257708dff179bc20528ddb6da7e48235 Mon Sep 17 00:00:00 2001 From: marquesja1 Date: Tue, 10 Sep 2024 15:14:58 +0200 Subject: [PATCH 19/22] Some improvements Signed-off-by: marquesja1 --- .../psse/converter/AbstractConverter.java | 35 ++++++ .../powsybl/psse/converter/BusConverter.java | 23 ++-- .../powsybl/psse/converter/ContextExport.java | 81 ++++++------- .../FixedShuntCompensatorConverter.java | 17 ++- .../psse/converter/GeneratorConverter.java | 1 - .../powsybl/psse/converter/LineConverter.java | 1 - .../psse/converter/NodeBreakerValidation.java | 2 +- .../powsybl/psse/converter/PsseExporter.java | 2 +- .../SwitchedShuntCompensatorConverter.java | 11 +- .../psse/converter/TransformerConverter.java | 111 +++++++++--------- .../converter/TwoTerminalDcConverter.java | 3 +- .../psse/converter/VoltageLevelConverter.java | 72 +++++------- 12 files changed, 181 insertions(+), 178 deletions(-) diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java index bf51193a194..3e400fe2e0f 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/AbstractConverter.java @@ -11,6 +11,7 @@ import java.util.stream.Stream; import com.powsybl.iidm.network.*; +import com.powsybl.iidm.network.extensions.SlackTerminal; import com.powsybl.iidm.network.util.Identifiables; import com.powsybl.iidm.network.util.Networks; import com.powsybl.psse.model.PsseException; @@ -151,6 +152,14 @@ static String busbarSectionId(String voltageLevelId, int node) { return String.format("%s-Busbar-%d", voltageLevelId, node); } + static String getNodeId(VoltageLevel voltageLevel, int node) { + return voltageLevel.getId() + "-" + node; + } + + static int getStatus(ShuntCompensator shuntCompensator) { + return shuntCompensator.getTerminal().isConnected() && shuntCompensator.getTerminal().getBusBreakerView().getBus() != null ? 1 : 0; + } + static String getNodeBreakerEquipmentIdBus(String equipmentId, int bus) { return equipmentId + "." + bus; } @@ -214,6 +223,28 @@ static int getStatus(Terminal terminal) { return terminal.isConnected() && terminal.getBusView().getBus() != null ? 1 : 0; } + static int findBusViewBusType(VoltageLevel voltageLevel, Bus bus) { + if (!bus.isInMainConnectedComponent()) { + return 4; + } + SlackTerminal slackTerminal = voltageLevel.getExtension(SlackTerminal.class); + if (slackTerminal != null + && slackTerminal.getTerminal().getBusView().getBus() != null + && bus.getId().equals(slackTerminal.getTerminal().getBusView().getBus().getId())) { + return 3; + } + return bus.getGeneratorStream().anyMatch(AbstractConverter::withLocalRegulatingControl) ? 2 : 1; + } + + private static boolean withLocalRegulatingControl(Generator generator) { + return generator.isVoltageRegulatorOn() + && generator.getTerminal().getBusView().getBus().equals(generator.getRegulatingTerminal().getBusView().getBus()); + } + + static boolean exportVoltageLevelAsNodeBreaker(VoltageLevel voltageLevel) { + return voltageLevel.getTopologyKind().equals(TopologyKind.NODE_BREAKER); + } + static Complex impedanceToEngineeringUnits(Complex impedance, double vnom, double sbase) { return impedance.multiply(vnom * vnom / sbase); } @@ -258,6 +289,10 @@ static double getVa(Bus bus) { return bus != null && Double.isFinite(bus.getAngle()) ? bus.getAngle() : 0.0; } + static double currentInAmpsToMw(double current, double nominalV) { + return current * nominalV / 1000.0; + } + private final ContainersMapping containersMapping; private final Network network; } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java index ecf7804b451..1a5ea74aae2 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/BusConverter.java @@ -43,28 +43,31 @@ void create(VoltageLevel voltageLevel) { .setAngle(psseBus.getVa()); } - static void updateBuses(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { + static void updateBuses(PssePowerFlowModel psseModel, ContextExport contextExport) { psseModel.getBuses().forEach(psseBus -> { - Optional busViewBusId = contextExport.getBusViewBusId(psseBus.getI()); - OptionalInt type = contextExport.getType(psseBus.getI()); - if (busViewBusId.isPresent() && type.isPresent()) { - updatePsseBus(network, busViewBusId.get(), type.getAsInt(), psseBus); + Optional busViewBus = contextExport.getLinkExport().getBusView(psseBus.getI()); + if (busViewBus.isPresent()) { + updatePsseBus(busViewBus.get(), findBusType(busViewBus.get().getVoltageLevel(), busViewBus.get(), psseBus), psseBus); } else { updateIsolatedPsseBus(psseBus); } }); } - private static void updatePsseBus(Network network, String busViewBusId, int type, PsseBus psseBus) { - Bus bus = network.getBusView().getBus(busViewBusId); - if (bus == null) { + // type is preserved in the update of nodeBreaker topologies. Type is calculated internally by psse based on the status of switches + private static int findBusType(VoltageLevel voltageLevel, Bus busView, PsseBus psseBus) { + return exportVoltageLevelAsNodeBreaker(voltageLevel) ? psseBus.getIde() : findBusViewBusType(voltageLevel, busView); + } + + private static void updatePsseBus(Bus busView, int type, PsseBus psseBus) { + if (busView == null) { updateIsolatedPsseBus(psseBus); } else { if (type == 4) { updateIsolatedPsseBus(psseBus); } else { - psseBus.setVm(getVm(bus)); - psseBus.setVa(getVa(bus)); + psseBus.setVm(getVm(busView)); + psseBus.setVa(getVa(busView)); psseBus.setIde(type); } } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/ContextExport.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/ContextExport.java index a06ed372a4f..123a10ac1d2 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/ContextExport.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/ContextExport.java @@ -7,8 +7,8 @@ */ package com.powsybl.psse.converter; +import com.powsybl.iidm.network.Bus; import com.powsybl.iidm.network.VoltageLevel; -import com.powsybl.psse.model.pf.PsseBus; import com.powsybl.psse.model.pf.PsseSubstation; import java.util.*; @@ -18,70 +18,67 @@ * @author José Antonio Marqués {@literal } */ final class ContextExport { - private final Map ibusToPsseBus; - private final Map buses; - private final NodeBreakerExport nodeBreakerExport; + private final LinkExport linkExport; + private final UpdateExport updateExport; ContextExport() { - this.ibusToPsseBus = new HashMap<>(); - this.buses = new HashMap<>(); - this.nodeBreakerExport = new NodeBreakerExport(); + this.linkExport = new LinkExport(); + this.updateExport = new UpdateExport(); } - void addIbus(int busI, PsseBus psseBus) { - ibusToPsseBus.put(busI, psseBus); + LinkExport getLinkExport() { + return this.linkExport; } - Optional getPsseBus(int busI) { - return ibusToPsseBus.containsKey(busI) ? Optional.of(ibusToPsseBus.get(busI)) : Optional.empty(); + UpdateExport getUpdateExport() { + return this.updateExport; } - void addBus(int busI, String busViewId, int type) { - buses.put(busI, new BusR(busViewId, type)); - } + static class LinkExport { + private final Map busIToBusView; + private final Map voltageLevelNodeIdToBusI; - Optional getBusViewBusId(int bus) { - return buses.containsKey(bus) ? Optional.of(buses.get(bus).busViewId()) : Optional.empty(); - } + LinkExport() { + this.busIToBusView = new HashMap<>(); + this.voltageLevelNodeIdToBusI = new HashMap<>(); + } - OptionalInt getType(int bus) { - return buses.containsKey(bus) ? OptionalInt.of(buses.get(bus).type()) : OptionalInt.empty(); - } + void addBusViewBusILink(Bus busView, int busI) { + this.busIToBusView.put(busI, busView); + } + + Optional getBusView(int busI) { + return this.busIToBusView.containsKey(busI) ? Optional.of(this.busIToBusView.get(busI)) : Optional.empty(); + } + + void addNodeBusILink(VoltageLevel voltageLevel, int node, int busI) { + this.voltageLevelNodeIdToBusI.put(AbstractConverter.getNodeId(voltageLevel, node), busI); + } + + OptionalInt getBusI(VoltageLevel voltageLevel, int node) { + String voltageLevelNodeId = AbstractConverter.getNodeId(voltageLevel, node); + return this.voltageLevelNodeIdToBusI.containsKey(voltageLevelNodeId) ? OptionalInt.of(this.voltageLevelNodeIdToBusI.get(voltageLevelNodeId)) : OptionalInt.empty(); + } - NodeBreakerExport getNodeBreakerExport() { - return this.nodeBreakerExport; + Optional getBusView(VoltageLevel voltageLevel, int node) { + OptionalInt busI = getBusI(voltageLevel, node); + return busI.isPresent() ? getBusView(busI.getAsInt()) : Optional.empty(); + } } - static class NodeBreakerExport { + static class UpdateExport { private final Map voltageLevelPsseSubstation; - private final Map nodes; - NodeBreakerExport() { + UpdateExport() { this.voltageLevelPsseSubstation = new HashMap<>(); - this.nodes = new HashMap<>(); } void addVoltageLevelPsseSubstation(VoltageLevel voltageLevel, PsseSubstation psseSubstation) { voltageLevelPsseSubstation.put(voltageLevel, psseSubstation); } - Optional getVoltageLevelPsseSubstation(VoltageLevel voltageLevel) { + Optional getPsseSubstation(VoltageLevel voltageLevel) { return Optional.ofNullable(voltageLevelPsseSubstation.get(voltageLevel)); } - - void addNode(VoltageLevel voltageLevel, int node, String busViewBusId) { - nodes.put(getNodeId(voltageLevel, node), busViewBusId); - } - - Optional getNodeViewBusId(VoltageLevel voltageLevel, int node) { - return nodes.containsKey(getNodeId(voltageLevel, node)) ? Optional.of(nodes.get(getNodeId(voltageLevel, node))) : Optional.empty(); - } - - private static String getNodeId(VoltageLevel voltageLevel, int node) { - return voltageLevel.getId() + "-" + node; - } - } - - private record BusR(String busViewId, int type) { } } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java index d6b290a774c..24875a63232 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/FixedShuntCompensatorConverter.java @@ -63,7 +63,6 @@ void create() { adder.add(); } - // At the moment we do not consider new fixedShunts static void updateFixedShunts(Network network, PssePowerFlowModel psseModel) { psseModel.getFixedShunts().forEach(psseFixedShunt -> { String fixedShuntId = getFixedShuntId(psseFixedShunt.getI(), psseFixedShunt.getId()); @@ -73,22 +72,20 @@ static void updateFixedShunts(Network network, PssePowerFlowModel psseModel) { psseFixedShunt.setStatus(0); } else { psseFixedShunt.setStatus(getStatus(fixedShunt)); + psseFixedShunt.setGl(getP(fixedShunt)); psseFixedShunt.setBl(getQ(fixedShunt)); } }); } - private static int getStatus(ShuntCompensator fixedShunt) { - if (fixedShunt.getTerminal().isConnected() && fixedShunt.getTerminal().getBusBreakerView().getBus() != null) { - return 1; - } else { - return 0; - } + private static double getP(ShuntCompensator shuntCompensator) { + return shuntAdmittanceToPower(shuntCompensator.getG(shuntCompensator.getSectionCount()), + shuntCompensator.getTerminal().getVoltageLevel().getNominalV()); } - private static double getQ(ShuntCompensator fixedShunt) { - return shuntAdmittanceToPower(fixedShunt.getB(fixedShunt.getSectionCount()), - fixedShunt.getTerminal().getVoltageLevel().getNominalV()); + private static double getQ(ShuntCompensator shuntCompensator) { + return shuntAdmittanceToPower(shuntCompensator.getB(shuntCompensator.getSectionCount()), + shuntCompensator.getTerminal().getVoltageLevel().getNominalV()); } private final PsseFixedShunt psseFixedShunt; diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java index d274b87ee51..903796e23e2 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java @@ -128,7 +128,6 @@ private static Terminal defineRegulatingTerminal(PsseGenerator psseGenerator, Ne return regulatingTerminal; } - // At the moment we do not consider new generators static void updateGenerators(Network network, PssePowerFlowModel psseModel) { psseModel.getGenerators().forEach(psseGen -> { String genId = getGeneratorId(psseGen.getI(), psseGen.getId()); diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java index 14c85640f12..bd6b8e75b06 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java @@ -123,7 +123,6 @@ private void defineOperationalLimits(Line line, double vnom1, double vnom2) { } } - // At the moment we do not consider new lines and antenna lines are exported as open static void updateLines(Network network, PssePowerFlowModel psseModel) { psseModel.getNonTransformerBranches().forEach(psseLine -> { String lineId = getLineId(psseLine.getI(), psseLine.getJ(), psseLine.getCkt()); diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java index 43c35f70cbd..02787c00120 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/NodeBreakerValidation.java @@ -175,7 +175,7 @@ private boolean isNodeBreakerSubstationDataCoherent(PsseSubstation psseSubstatio && equipmentTerminalByEquipmentTerminalData.containsAll(equipmentTerminalByNodeSet); } - // base on real cases and substation configurations created automatically by psse + // based on real cases and substation configurations created automatically by psse // isolated nodes are discarded // nodes are in the same component if they are connected by switches without considering their status (open / close) private static Set obtainNodeComponentBySwitching(PsseSubstation psseSubstation, int bus) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java index 263791b6320..9e05d8c5281 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseExporter.java @@ -124,7 +124,7 @@ private static void updateModifiedBlocks(Network network, PssePowerFlowModel upd VoltageLevelConverter.updateSubstations(network, contextExport); - BusConverter.updateBuses(network, updatedPsseModel, contextExport); + BusConverter.updateBuses(updatedPsseModel, contextExport); LoadConverter.updateLoads(network, updatedPsseModel); FixedShuntCompensatorConverter.updateFixedShunts(network, updatedPsseModel); GeneratorConverter.updateGenerators(network, updatedPsseModel); diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java index 1c6df2b94e2..aa780b7dcc4 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/SwitchedShuntCompensatorConverter.java @@ -272,7 +272,6 @@ private static String defineShuntId(PsseSwitchedShunt psseSwitchedShunt, PsseVer } } - // At the moment we do not consider new switchedShunts static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel) { PsseVersion version = PsseVersion.fromRevision(psseModel.getCaseIdentification().getRev()); psseModel.getSwitchedShunts().forEach(psseSwitchedShunt -> { @@ -287,17 +286,9 @@ static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel) }); } - private static int getStatus(ShuntCompensator switchedShunt) { - if (switchedShunt.getTerminal().isConnected() && switchedShunt.getTerminal().getBusBreakerView().getBus() != null) { - return 1; - } else { - return 0; - } - } - private static double getQ(ShuntCompensator switchedShunt) { return shuntAdmittanceToPower(switchedShunt.getB(switchedShunt.getSectionCount()), - switchedShunt.getTerminal().getVoltageLevel().getNominalV()); + switchedShunt.getTerminal().getVoltageLevel().getNominalV()); } private final PsseSwitchedShunt psseSwitchedShunt; diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java index 455782aaa08..f8c879e02da 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java @@ -875,66 +875,62 @@ static void updateTransformers(Network network, PssePowerFlowModel psseModel) { private static void updateTwoWindingsTransformer(Network network, PsseTransformer psseTransformer) { String transformerId = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); - TwoWindingsTransformer tw2t = network.getTwoWindingsTransformer(transformerId); - if (tw2t == null) { + TwoWindingsTransformer t2w = network.getTwoWindingsTransformer(transformerId); + if (t2w == null) { psseTransformer.setStat(0); } else { - double baskv1 = tw2t.getTerminal1().getVoltageLevel().getNominalV(); - double nomV1 = getNomV(psseTransformer.getWinding1(), tw2t.getTerminal1().getVoltageLevel()); - psseTransformer.getWinding1().setWindv(defineWindV(getRatio(tw2t.getRatioTapChanger(), tw2t.getPhaseTapChanger()), baskv1, nomV1, psseTransformer.getCw())); - psseTransformer.getWinding1().setAng(getAngle(tw2t.getPhaseTapChanger())); + double baskv1 = t2w.getTerminal1().getVoltageLevel().getNominalV(); + double nomV1 = getNomV(psseTransformer.getWinding1(), t2w.getTerminal1().getVoltageLevel()); + psseTransformer.getWinding1().setWindv(defineWindV(getRatio(t2w.getRatioTapChanger(), t2w.getPhaseTapChanger()), baskv1, nomV1, psseTransformer.getCw())); + psseTransformer.getWinding1().setAng(getAngle(t2w.getPhaseTapChanger())); - psseTransformer.setStat(getStatus(tw2t)); + psseTransformer.setStat(getStatus(t2w)); } } - private static int getStatus(TwoWindingsTransformer tw2t) { - if (tw2t.getTerminal1().isConnected() && tw2t.getTerminal1().getBusBreakerView().getBus() != null - && tw2t.getTerminal2().isConnected() && tw2t.getTerminal2().getBusBreakerView().getBus() != null) { - return 1; - } else { - return 0; - } + private static int getStatus(TwoWindingsTransformer t2w) { + return t2w.getTerminal1().isConnected() && t2w.getTerminal1().getBusBreakerView().getBus() != null + && t2w.getTerminal2().isConnected() && t2w.getTerminal2().getBusBreakerView().getBus() != null ? 1 : 0; } private static void updateThreeWindingsTransformer(Network network, PsseTransformer psseTransformer) { String transformerId = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt()); - ThreeWindingsTransformer tw3t = network.getThreeWindingsTransformer(transformerId); - if (tw3t == null) { + ThreeWindingsTransformer t3w = network.getThreeWindingsTransformer(transformerId); + if (t3w == null) { psseTransformer.setStat(0); } else { - double baskv1 = tw3t.getLeg1().getTerminal().getVoltageLevel().getNominalV(); - double nomV1 = getNomV(psseTransformer.getWinding1(), tw3t.getLeg1().getTerminal().getVoltageLevel()); - psseTransformer.getWinding1().setWindv(defineWindV(getRatio(tw3t.getLeg1().getRatioTapChanger(), tw3t.getLeg1().getPhaseTapChanger()), baskv1, nomV1, psseTransformer.getCw())); - psseTransformer.getWinding1().setAng(getAngle(tw3t.getLeg1().getPhaseTapChanger())); + double baskv1 = t3w.getLeg1().getTerminal().getVoltageLevel().getNominalV(); + double nomV1 = getNomV(psseTransformer.getWinding1(), t3w.getLeg1().getTerminal().getVoltageLevel()); + psseTransformer.getWinding1().setWindv(defineWindV(getRatio(t3w.getLeg1().getRatioTapChanger(), t3w.getLeg1().getPhaseTapChanger()), baskv1, nomV1, psseTransformer.getCw())); + psseTransformer.getWinding1().setAng(getAngle(t3w.getLeg1().getPhaseTapChanger())); - double baskv2 = tw3t.getLeg2().getTerminal().getVoltageLevel().getNominalV(); - double nomV2 = getNomV(psseTransformer.getWinding2(), tw3t.getLeg2().getTerminal().getVoltageLevel()); - psseTransformer.getWinding2().setWindv(defineWindV(getRatio(tw3t.getLeg2().getRatioTapChanger(), tw3t.getLeg2().getPhaseTapChanger()), baskv2, nomV2, psseTransformer.getCw())); - psseTransformer.getWinding2().setAng(getAngle(tw3t.getLeg2().getPhaseTapChanger())); + double baskv2 = t3w.getLeg2().getTerminal().getVoltageLevel().getNominalV(); + double nomV2 = getNomV(psseTransformer.getWinding2(), t3w.getLeg2().getTerminal().getVoltageLevel()); + psseTransformer.getWinding2().setWindv(defineWindV(getRatio(t3w.getLeg2().getRatioTapChanger(), t3w.getLeg2().getPhaseTapChanger()), baskv2, nomV2, psseTransformer.getCw())); + psseTransformer.getWinding2().setAng(getAngle(t3w.getLeg2().getPhaseTapChanger())); - double baskv3 = tw3t.getLeg3().getTerminal().getVoltageLevel().getNominalV(); - double nomV3 = getNomV(psseTransformer.getWinding3(), tw3t.getLeg3().getTerminal().getVoltageLevel()); - psseTransformer.getWinding3().setWindv(defineWindV(getRatio(tw3t.getLeg3().getRatioTapChanger(), tw3t.getLeg3().getPhaseTapChanger()), baskv3, nomV3, psseTransformer.getCw())); - psseTransformer.getWinding3().setAng(getAngle(tw3t.getLeg3().getPhaseTapChanger())); + double baskv3 = t3w.getLeg3().getTerminal().getVoltageLevel().getNominalV(); + double nomV3 = getNomV(psseTransformer.getWinding3(), t3w.getLeg3().getTerminal().getVoltageLevel()); + psseTransformer.getWinding3().setWindv(defineWindV(getRatio(t3w.getLeg3().getRatioTapChanger(), t3w.getLeg3().getPhaseTapChanger()), baskv3, nomV3, psseTransformer.getCw())); + psseTransformer.getWinding3().setAng(getAngle(t3w.getLeg3().getPhaseTapChanger())); - psseTransformer.setStat(getStatus(tw3t)); + psseTransformer.setStat(getStatus(t3w)); } } - private static int getStatus(ThreeWindingsTransformer tw3t) { - if (tw3t.getLeg1().getTerminal().isConnected() && tw3t.getLeg1().getTerminal().getBusBreakerView().getBus() != null - && tw3t.getLeg2().getTerminal().isConnected() && tw3t.getLeg2().getTerminal().getBusBreakerView().getBus() != null - && tw3t.getLeg3().getTerminal().isConnected() && tw3t.getLeg3().getTerminal().getBusBreakerView().getBus() != null) { + private static int getStatus(ThreeWindingsTransformer t3w) { + if (t3w.getLeg1().getTerminal().isConnected() && t3w.getLeg1().getTerminal().getBusBreakerView().getBus() != null + && t3w.getLeg2().getTerminal().isConnected() && t3w.getLeg2().getTerminal().getBusBreakerView().getBus() != null + && t3w.getLeg3().getTerminal().isConnected() && t3w.getLeg3().getTerminal().getBusBreakerView().getBus() != null) { return 1; - } else if (tw3t.getLeg1().getTerminal().isConnected() && tw3t.getLeg1().getTerminal().getBusBreakerView().getBus() != null - && tw3t.getLeg2().getTerminal().isConnected() && tw3t.getLeg2().getTerminal().getBusBreakerView().getBus() != null) { + } else if (t3w.getLeg1().getTerminal().isConnected() && t3w.getLeg1().getTerminal().getBusBreakerView().getBus() != null + && t3w.getLeg2().getTerminal().isConnected() && t3w.getLeg2().getTerminal().getBusBreakerView().getBus() != null) { return 3; - } else if (tw3t.getLeg1().getTerminal().isConnected() && tw3t.getLeg1().getTerminal().getBusBreakerView().getBus() != null - && tw3t.getLeg3().getTerminal().isConnected() && tw3t.getLeg3().getTerminal().getBusBreakerView().getBus() != null) { + } else if (t3w.getLeg1().getTerminal().isConnected() && t3w.getLeg1().getTerminal().getBusBreakerView().getBus() != null + && t3w.getLeg3().getTerminal().isConnected() && t3w.getLeg3().getTerminal().getBusBreakerView().getBus() != null) { return 2; - } else if (tw3t.getLeg2().getTerminal().isConnected() && tw3t.getLeg2().getTerminal().getBusBreakerView().getBus() != null - && tw3t.getLeg3().getTerminal().isConnected() && tw3t.getLeg3().getTerminal().getBusBreakerView().getBus() != null) { + } else if (t3w.getLeg2().getTerminal().isConnected() && t3w.getLeg2().getTerminal().getBusBreakerView().getBus() != null + && t3w.getLeg3().getTerminal().isConnected() && t3w.getLeg3().getTerminal().getBusBreakerView().getBus() != null) { return 4; } else { return 0; @@ -942,26 +938,31 @@ private static int getStatus(ThreeWindingsTransformer tw3t) { } private static double getRatio(RatioTapChanger rtc, PhaseTapChanger ptc) { - double rho = 1.0; - if (rtc != null) { - rho = rho * rtc.getCurrentStep().getRho(); - } - if (ptc != null) { - rho = rho * ptc.getCurrentStep().getRho(); + if (rtc != null && ptc != null) { + return getRatio(rtc) * getRatio(ptc); + } else if (rtc != null) { + return getRatio(rtc); + } else if (ptc != null) { + return getRatio(ptc); + } else { + return 1.0; } - return 1.0 / rho; + } + + private static double getRatio(RatioTapChanger rtc) { + return rtc != null ? 1.0 / rtc.getCurrentStep().getRho() : 1.0; + } + + private static double getRatio(PhaseTapChanger ptc) { + return ptc != null ? 1.0 / ptc.getCurrentStep().getRho() : 1.0; } private static double getAngle(PhaseTapChanger ptc) { - double alpha = 0.0; - if (ptc != null) { - alpha = ptc.getCurrentStep().getAlpha(); - } - // To avoid - 0.0 - if (alpha != 0.0) { - return -alpha; - } - return alpha; + return ptc != null ? convertToAngle(ptc.getCurrentStep().getAlpha()) : 0.0; + } + + private static double convertToAngle(double alpha) { + return alpha != 0.0 ? -alpha : alpha; // To avoid - 0.0 } private final PsseTransformer psseTransformer; diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java index cf2f9ab7fe7..95f0eeb34a6 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TwoTerminalDcConverter.java @@ -91,8 +91,7 @@ private static double getTwoTerminalDcActivePowerSetpoint(PsseTwoTerminalDcTrans // The desired real power demand Math.abs(psseTwoTerminalDc.getSetvl()); case 2 -> - // It is the current in amps (should divide by 1000 to convert to MW) - psseTwoTerminalDc.getSetvl() * psseTwoTerminalDc.getVschd() / 1000.0; + currentInAmpsToMw(psseTwoTerminalDc.getSetvl(), psseTwoTerminalDc.getVschd()); default -> 0.0; }; } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java index 5a1a6d52252..e9257466848 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/VoltageLevelConverter.java @@ -11,7 +11,6 @@ import java.util.stream.Collectors; import com.powsybl.iidm.network.*; -import com.powsybl.iidm.network.extensions.SlackTerminal; import com.powsybl.iidm.network.util.ContainersMapping; import com.powsybl.psse.converter.PsseImporter.PerUnitContext; import com.powsybl.psse.converter.NodeBreakerValidation.NodeBreakerControl; @@ -165,18 +164,26 @@ private static int connectedGenerators(PsseSubstation psseSubstation, int node) static ContextExport createContextExport(Network network, PssePowerFlowModel psseModel) { ContextExport contextExport = new ContextExport(); mapVoltageLevelsAndPsseSubstation(network, psseModel, contextExport); - mapBusIAndPsseBus(psseModel, contextExport); - - network.getVoltageLevels().forEach(voltageLevel -> { - if (voltageLevel.getTopologyKind().equals(TopologyKind.BUS_BREAKER)) { - createBusBranchContextExport(voltageLevel, contextExport); - } else { + getSortedVoltageLevels(network).forEach(voltageLevel -> { + if (exportVoltageLevelAsNodeBreaker(voltageLevel)) { createNodeBreakerContextExport(voltageLevel, contextExport); + } else { + createBusBranchContextExport(voltageLevel, contextExport); } }); return contextExport; } + private static List getSortedVoltageLevels(Network network) { + return network.getVoltageLevelStream().sorted(Comparator.comparingInt(VoltageLevelConverter::minBus) + .thenComparing(Identifiable::getId)).toList(); + } + + private static int minBus(VoltageLevel voltageLevel) { + List buses = extractBusesFromVoltageLevelId(voltageLevel.getId()); + return buses.isEmpty() ? Integer.MAX_VALUE : buses.get(0); + } + private static void mapVoltageLevelsAndPsseSubstation(Network network, PssePowerFlowModel psseModel, ContextExport contextExport) { Map busPsseSubstation = new HashMap<>(); psseModel.getSubstations().forEach(psseSubstation -> { @@ -185,7 +192,7 @@ private static void mapVoltageLevelsAndPsseSubstation(Network network, PssePower }); network.getVoltageLevels().forEach(voltageLevel -> getVoltageLevelPsseSubstation(voltageLevel, busPsseSubstation) - .ifPresent(psseSubstation -> contextExport.getNodeBreakerExport().addVoltageLevelPsseSubstation(voltageLevel, psseSubstation))); + .ifPresent(psseSubstation -> contextExport.getUpdateExport().addVoltageLevelPsseSubstation(voltageLevel, psseSubstation))); } private static Optional getVoltageLevelPsseSubstation(VoltageLevel voltageLevel, Map busPsseSubstation) { @@ -202,10 +209,6 @@ private static Optional getVoltageLevelPsseSubstation(VoltageLev return psseSubstationSet.isEmpty() ? Optional.empty() : Optional.of(psseSubstationSet.iterator().next()); } - private static void mapBusIAndPsseBus(PssePowerFlowModel psseModel, ContextExport contextExport) { - psseModel.getBuses().forEach(psseBus -> contextExport.addIbus(psseBus.getI(), psseBus)); - } - private static void createBusBranchContextExport(VoltageLevel voltageLevel, ContextExport contextExport) { Map> busViewBusBusBreakerViewBuses = new HashMap<>(); @@ -219,7 +222,7 @@ private static void createBusBranchContextExport(VoltageLevel voltageLevel, Cont voltageLevel.getBusView().getBuses().forEach(bus -> { String busBreakerViewId = findBusBreakerViewBusId(bus.getId(), busViewBusBusBreakerViewBuses); - extractBusNumber(busBreakerViewId).ifPresent(busI -> contextExport.addBus(busI, bus.getId(), findBusViewBusType(voltageLevel, bus))); + extractBusNumber(busBreakerViewId).ifPresent(busI -> contextExport.getLinkExport().addBusViewBusILink(bus, busI)); }); } @@ -236,44 +239,26 @@ private static String findBusBreakerViewBusId(String busViewBusId, Map> busIBusViews = new HashMap<>(); - PsseSubstation psseSubstation = contextExport.getNodeBreakerExport().getVoltageLevelPsseSubstation(voltageLevel).orElseThrow(); + PsseSubstation psseSubstation = contextExport.getUpdateExport().getPsseSubstation(voltageLevel).orElseThrow(); for (int node : voltageLevel.getNodeBreakerView().getNodes()) { Bus bus = findBusViewNode(voltageLevel, node); if (bus != null) { - contextExport.getNodeBreakerExport().addNode(voltageLevel, node, bus.getId()); - findBusI(psseSubstation, node).ifPresent(busI -> busIBusViews.computeIfAbsent(busI, k -> new ArrayList<>()).add(bus)); + int busI = findBusI(psseSubstation, node).orElseThrow(); + contextExport.getLinkExport().addNodeBusILink(voltageLevel, node, busI); + busIBusViews.computeIfAbsent(busI, k -> new ArrayList<>()).add(bus); } } // we try to assign a busView inside mainConnectedComponent with the strong psse bus type and, we preserve the original bus type busIBusViews.forEach((busI, busList) -> { - Bus selectedBus = busList.stream().min(Comparator.comparingInt(busView -> findType(voltageLevel, busView))).orElseThrow(); - int type = contextExport.getPsseBus(busI).map(PsseBus::getIde).orElseGet(() -> findBusViewBusType(voltageLevel, selectedBus)); - contextExport.addBus(busI, selectedBus.getId(), type); + Bus selectedBus = busList.stream().min(Comparator.comparingInt(busView -> findPriorityType(voltageLevel, busView))).orElseThrow(); + contextExport.getLinkExport().addBusViewBusILink(selectedBus, busI); }); } - private static int findType(VoltageLevel voltageLevel, Bus busView) { + private static int findPriorityType(VoltageLevel voltageLevel, Bus busView) { int type = findBusViewBusType(voltageLevel, busView); return switch (type) { case 3 -> 0; @@ -292,19 +277,16 @@ static void updateSubstations(Network network, ContextExport contextExport) { network.getVoltageLevels().forEach(voltageLevel -> { if (voltageLevel.getTopologyKind().equals(TopologyKind.NODE_BREAKER)) { Set buses = new HashSet<>(extractBusesFromVoltageLevelId(voltageLevel.getId())); - contextExport.getNodeBreakerExport().getVoltageLevelPsseSubstation(voltageLevel).ifPresent(psseSubstation -> updateSubstation(voltageLevel, psseSubstation, buses, contextExport)); + contextExport.getUpdateExport().getPsseSubstation(voltageLevel).ifPresent(psseSubstation -> updateSubstation(voltageLevel, psseSubstation, buses, contextExport)); } }); } private static void updateSubstation(VoltageLevel voltageLevel, PsseSubstation psseSubstation, Set busesSet, ContextExport contextExport) { Set psseNodeSet = psseSubstation.getNodes().stream().filter(psseNode -> busesSet.contains(psseNode.getI())).collect(Collectors.toSet()); - psseNodeSet.forEach(psseSubstationNode -> contextExport.getNodeBreakerExport().getNodeViewBusId(voltageLevel, psseSubstationNode.getNi()).ifPresent(busViewBusId -> { - Bus bus = voltageLevel.getBusView().getBus(busViewBusId); - if (bus != null) { - psseSubstationNode.setVm(getVm(bus)); - psseSubstationNode.setVa(getVa(bus)); - } + psseNodeSet.forEach(psseSubstationNode -> contextExport.getLinkExport().getBusView(voltageLevel, psseSubstationNode.getNi()).ifPresent(busView -> { + psseSubstationNode.setVm(getVm(busView)); + psseSubstationNode.setVa(getVa(busView)); })); Set nodesSet = psseNodeSet.stream().map(PsseSubstationNode::getNi).collect(Collectors.toSet()); From a8d56960ad1f4622962a9426df3a9f3265fcc6db Mon Sep 17 00:00:00 2001 From: marquesja1 Date: Thu, 12 Sep 2024 16:37:51 +0200 Subject: [PATCH 20/22] Typo Signed-off-by: marquesja1 --- .../src/main/java/com/powsybl/psse/converter/PsseImporter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java index cf9d8025b49..36eff502a71 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java @@ -57,7 +57,7 @@ public class PsseImporter implements Importer { Boolean.FALSE); private static final Parameter IGNORE_NODE_BREAKER_TOPOLOGY_PARAMETER = new Parameter("psse.import.ignore-node-breaker-topology", ParameterType.BOOLEAN, - "Ignore the node breaker topolgy specified in the substation data of the file", + "Ignore the node breaker topology specified in the substation data of the file", Boolean.FALSE); @Override From 2b555d008d87ead97f369bc47fa8aa185d945630 Mon Sep 17 00:00:00 2001 From: marquesja1 Date: Fri, 20 Dec 2024 09:07:58 +0100 Subject: [PATCH 21/22] Fix last update Signed-off-by: marquesja1 --- .../java/com/powsybl/psse/converter/GeneratorConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java index 3ebe4b35d4f..903796e23e2 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/GeneratorConverter.java @@ -122,7 +122,7 @@ private static Terminal defineRegulatingTerminal(PsseGenerator psseGenerator, Ne } } if (regulatingTerminal == null && psseGenerator.getI() != psseGenerator.getIreg()) { - String generatorId = getGeneratorId(defaultRegulatingBusId, psseGenerator); + String generatorId = getGeneratorId(psseGenerator.getI(), psseGenerator.getId()); LOGGER.warn("Generator {}. Regulating terminal is not assigned as the bus is isolated", generatorId); } return regulatingTerminal; From 3b130b3615dfd79054f486f9fa8aa8a540685530 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Mon, 30 Dec 2024 12:58:41 +0100 Subject: [PATCH 22/22] Minor clean Signed-off-by: Geoffroy Jamgotchian --- .../java/com/powsybl/iidm/network/util/ContainersMapping.java | 2 +- .../main/java/com/powsybl/psse/converter/LineConverter.java | 4 ++-- .../java/com/powsybl/psse/converter/TransformerConverter.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/ContainersMapping.java b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/ContainersMapping.java index 004f1d9358a..3f08d7a8b76 100644 --- a/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/ContainersMapping.java +++ b/iidm/iidm-api/src/main/java/com/powsybl/iidm/network/util/ContainersMapping.java @@ -31,7 +31,7 @@ public class ContainersMapping { private final Map voltageLevelIdToSubstationId = new HashMap<>(); public Set getBusesSet(String voltageLevelId) { - return voltageLevelIdToBusNums.containsKey(voltageLevelId) ? voltageLevelIdToBusNums.get(voltageLevelId) : new HashSet<>(); + return voltageLevelIdToBusNums.computeIfAbsent(voltageLevelId, k -> new HashSet<>()); } public String getVoltageLevelId(int num) { diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java index bd6b8e75b06..81f5d1455b8 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/LineConverter.java @@ -45,8 +45,6 @@ class LineConverter extends AbstractConverter { void create() { String id = getLineId(psseLine.getI(), psseLine.getJ(), psseLine.getCkt()); - String bus1Id = getBusId(psseLine.getI()); - String bus2Id = getBusId(psseLine.getJ()); String voltageLevel1Id = getContainersMapping().getVoltageLevelId(psseLine.getI()); String voltageLevel2Id = getContainersMapping().getVoltageLevelId(psseLine.getJ()); @@ -79,6 +77,7 @@ void create() { if (node1.isPresent()) { adder.setNode1(node1.getAsInt()); } else { + String bus1Id = getBusId(psseLine.getI()); adder.setConnectableBus1(bus1Id); adder.setBus1(psseLine.getSt() == 1 ? bus1Id : null); } @@ -86,6 +85,7 @@ void create() { if (node2.isPresent()) { adder.setNode2(node2.getAsInt()); } else { + String bus2Id = getBusId(psseLine.getJ()); adder.setConnectableBus2(bus2Id); adder.setBus2(psseLine.getSt() == 1 ? bus2Id : null); } diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java index f8c879e02da..d316f3c579f 100644 --- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java +++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/TransformerConverter.java @@ -61,12 +61,10 @@ private void createTwoWindingsTransformer() { String id = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt()); - String bus1Id = getBusId(psseTransformer.getI()); String voltageLevel1Id = getContainersMapping().getVoltageLevelId(psseTransformer.getI()); VoltageLevel voltageLevel1 = getNetwork().getVoltageLevel(voltageLevel1Id); double baskv1 = busNumToPsseBus.get(psseTransformer.getI()).getBaskv(); - String bus2Id = getBusId(psseTransformer.getJ()); String voltageLevel2Id = getContainersMapping().getVoltageLevelId(psseTransformer.getJ()); VoltageLevel voltageLevel2 = getNetwork().getVoltageLevel(voltageLevel2Id); double baskv2 = busNumToPsseBus.get(psseTransformer.getJ()).getBaskv(); @@ -119,6 +117,7 @@ private void createTwoWindingsTransformer() { if (node1.isPresent()) { adder.setNode1(node1.getAsInt()); } else { + String bus1Id = getBusId(psseTransformer.getI()); adder.setConnectableBus1(bus1Id); adder.setBus1(psseTransformer.getStat() == 1 ? bus1Id : null); } @@ -126,6 +125,7 @@ private void createTwoWindingsTransformer() { if (node2.isPresent()) { adder.setNode2(node2.getAsInt()); } else { + String bus2Id = getBusId(psseTransformer.getJ()); adder.setConnectableBus2(bus2Id); adder.setBus2(psseTransformer.getStat() == 1 ? bus2Id : null); }