Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix case9241pegase.mat import #3254

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,20 @@
import com.powsybl.commons.parameters.Parameter;
import com.powsybl.commons.parameters.ParameterDefaultValueConfig;
import com.powsybl.commons.parameters.ParameterType;
import com.powsybl.iidm.network.Importer;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.SlackTerminal;
import com.powsybl.iidm.network.util.ContainersMapping;
import com.powsybl.matpower.model.*;

import org.apache.commons.math3.complex.Complex;
import org.jgrapht.alg.util.Pair;
import java.time.ZonedDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -341,81 +339,20 @@ private static void createApparentPowerLimits(MBranch mBranch, ApparentPowerLimi
private static void createBranches(MatpowerModel model, ContainersMapping containerMapping, Network network, Context context) {
for (MBranch mBranch : model.getBranches()) {

String bus1Id = getId(BUS_PREFIX, mBranch.getFrom());
String bus2Id = getId(BUS_PREFIX, mBranch.getTo());
String connectableBus1 = getId(BUS_PREFIX, mBranch.getFrom());
String connectableBus2 = getId(BUS_PREFIX, mBranch.getTo());
String voltageLevel1Id = containerMapping.getVoltageLevelId(mBranch.getFrom());
String voltageLevel2Id = containerMapping.getVoltageLevelId(mBranch.getTo());
VoltageLevel voltageLevel1 = network.getVoltageLevel(voltageLevel1Id);
VoltageLevel voltageLevel2 = network.getVoltageLevel(voltageLevel2Id);
double zb = voltageLevel2.getNominalV() * voltageLevel2.getNominalV() / context.getBaseMva();
boolean isInService = isInService(mBranch);
String connectedBus1 = isInService ? bus1Id : null;
String connectedBus2 = isInService ? bus2Id : null;

Branch<?> branch;
if (isTransformer(model, mBranch)) {
TwoWindingsTransformer newTwt = voltageLevel2.getSubstation()
.orElseThrow(() -> new PowsyblException("Substation null! Transformer must be within a substation"))
.newTwoWindingsTransformer()
.setId(getId(TRANSFORMER_PREFIX, mBranch.getFrom(), mBranch.getTo()))
.setEnsureIdUnicity(true)
.setBus1(connectedBus1)
.setConnectableBus1(bus1Id)
.setVoltageLevel1(voltageLevel1Id)
.setBus2(connectedBus2)
.setConnectableBus2(bus2Id)
.setVoltageLevel2(voltageLevel2Id)
.setRatedU1(voltageLevel1.getNominalV() * mBranch.getRatio())
.setRatedU2(voltageLevel2.getNominalV())
.setR(mBranch.getR() * zb)
.setX(mBranch.getX() * zb)
.setG(0)
.setB(mBranch.getB() / zb)
.add();
if (mBranch.getPhaseShiftAngle() != 0) {
newTwt.newPhaseTapChanger()
.setTapPosition(0)
.beginStep()
.setRho(1)
.setAlpha(-mBranch.getPhaseShiftAngle())
.setR(0)
.setX(0)
.setG(0)
.setB(0)
.endStep()
.add();
}
branch = newTwt;
LOGGER.trace("Created TwoWindingsTransformer {} {} {}", newTwt.getId(), bus1Id, bus2Id);
branch = createTransformer(mBranch, voltageLevel1, connectableBus1, voltageLevel2, connectableBus2, isInService, zb);
} else {
double nominalV1 = voltageLevel1.getNominalV();
double nominalV2 = voltageLevel2.getNominalV();
double sBase = context.getBaseMva();
double r = impedanceToEngineeringUnitsForLine(mBranch.getR(), nominalV1, nominalV2, sBase);
double x = impedanceToEngineeringUnitsForLine(mBranch.getX(), nominalV1, nominalV2, sBase);
Complex ytr = impedanceToAdmittance(r, x);
double g1 = admittanceEndToEngineeringUnitsForLine(ytr.getReal(), 0.0, nominalV1, nominalV2, sBase);
double b1 = admittanceEndToEngineeringUnitsForLine(ytr.getImaginary(), mBranch.getB() * 0.5, nominalV1, nominalV2, sBase);
double g2 = admittanceEndToEngineeringUnitsForLine(ytr.getReal(), 0.0, nominalV2, nominalV1, sBase);
double b2 = admittanceEndToEngineeringUnitsForLine(ytr.getImaginary(), mBranch.getB() * 0.5, nominalV2, nominalV1, sBase);

branch = network.newLine()
.setId(getId(LINE_PREFIX, mBranch.getFrom(), mBranch.getTo()))
.setEnsureIdUnicity(true)
.setBus1(connectedBus1)
.setConnectableBus1(bus1Id)
.setVoltageLevel1(voltageLevel1Id)
.setBus2(connectedBus2)
.setConnectableBus2(bus2Id)
.setVoltageLevel2(voltageLevel2Id)
.setR(r)
.setX(x)
.setG1(g1)
.setB1(b1)
.setG2(g2)
.setB2(b2)
.add();
LOGGER.trace("Created line {} {} {}", branch.getId(), bus1Id, bus2Id);
branch = createLine(network, context, mBranch, voltageLevel1, connectableBus1, voltageLevel2, connectableBus2, isInService);
}
if (mBranch.getRateA() != 0) {
// we create the apparent power limit arbitrary on both sides
Expand All @@ -428,6 +365,90 @@ private static void createBranches(MatpowerModel model, ContainersMapping contai
}
}

private static Branch<?> createLine(Network network, Context context, MBranch mBranch,
VoltageLevel voltageLevel1, String connectableBus1,
VoltageLevel voltageLevel2, String connectableBus2,
boolean isInService) {
Branch<?> branch;
String bus1 = isInService ? connectableBus1 : null;
String bus2 = isInService ? connectableBus2 : null;
double nominalV1 = voltageLevel1.getNominalV();
double nominalV2 = voltageLevel2.getNominalV();
double sBase = context.getBaseMva();
double r = impedanceToEngineeringUnitsForLine(mBranch.getR(), nominalV1, nominalV2, sBase);
double x = impedanceToEngineeringUnitsForLine(mBranch.getX(), nominalV1, nominalV2, sBase);
Complex ytr = impedanceToAdmittance(r, x);
double g1 = admittanceEndToEngineeringUnitsForLine(ytr.getReal(), 0.0, nominalV1, nominalV2, sBase);
double b1 = admittanceEndToEngineeringUnitsForLine(ytr.getImaginary(), mBranch.getB() * 0.5, nominalV1, nominalV2, sBase);
double g2 = admittanceEndToEngineeringUnitsForLine(ytr.getReal(), 0.0, nominalV2, nominalV1, sBase);
double b2 = admittanceEndToEngineeringUnitsForLine(ytr.getImaginary(), mBranch.getB() * 0.5, nominalV2, nominalV1, sBase);

branch = network.newLine()
.setId(getId(LINE_PREFIX, mBranch.getFrom(), mBranch.getTo()))
.setEnsureIdUnicity(true)
.setBus1(bus1)
.setConnectableBus1(connectableBus1)
.setVoltageLevel1(voltageLevel1.getId())
.setBus2(bus2)
.setConnectableBus2(connectableBus2)
.setVoltageLevel2(voltageLevel2.getId())
.setR(r)
.setX(x)
.setG1(g1)
.setB1(b1)
.setG2(g2)
.setB2(b2)
.add();
LOGGER.trace("Created line {} {} {}", branch.getId(), bus1, bus2);
return branch;
}

private static Branch<?> createTransformer(MBranch mBranch,
VoltageLevel voltageLevel1, String connectableBus1,
VoltageLevel voltageLevel2, String connectableBus2,
boolean isInService, double zb) {
Branch<?> branch;
String bus1 = isInService ? connectableBus1 : null;
String bus2 = isInService ? connectableBus2 : null;
// we might have a matpower branch with a phase shift and a 0 ratio (0 in matpower just means undefined)
// we need to create an IIDM transformer but we just in that case fix the ratio to 1
double ratio = mBranch.getRatio() == 0 ? 1 : mBranch.getRatio();
TwoWindingsTransformer newTwt = voltageLevel2.getSubstation()
.orElseThrow(() -> new PowsyblException("Substation null! Transformer must be within a substation"))
.newTwoWindingsTransformer()
.setId(getId(TRANSFORMER_PREFIX, mBranch.getFrom(), mBranch.getTo()))
.setEnsureIdUnicity(true)
.setBus1(bus1)
.setConnectableBus1(connectableBus1)
.setVoltageLevel1(voltageLevel1.getId())
.setBus2(bus2)
.setConnectableBus2(connectableBus2)
.setVoltageLevel2(voltageLevel2.getId())
.setRatedU1(voltageLevel1.getNominalV() * ratio)
.setRatedU2(voltageLevel2.getNominalV())
.setR(mBranch.getR() * zb)
.setX(mBranch.getX() * zb)
.setG(0)
.setB(mBranch.getB() / zb)
.add();
if (mBranch.getPhaseShiftAngle() != 0) {
newTwt.newPhaseTapChanger()
.setTapPosition(0)
.beginStep()
.setRho(1)
.setAlpha(-mBranch.getPhaseShiftAngle())
.setR(0)
.setX(0)
.setG(0)
.setB(0)
.endStep()
.add();
}
branch = newTwt;
LOGGER.trace("Created TwoWindingsTransformer {} {} {}", newTwt.getId(), bus1, bus2);
return branch;
}

// avoid NaN when r and x, both are 0.0
private static Complex impedanceToAdmittance(double r, double x) {
return r == 0.0 && x == 0.0 ? new Complex(0.0, 0.0) : new Complex(r, x).reciprocal();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ void testCase14WithPhaseShifter() throws IOException {
testCase(MatpowerModelFactory.create14WithPhaseShifter());
}

@Test
void testCase14WithPhaseShifterZeroRatioIssue() throws IOException {
testCase(MatpowerModelFactory.readModelJsonFromResources("ieee14-phase-shifter-zero-ratio-issue.json"));
}

@Test
void testCase14WithPhaseShifterSolved() throws IOException {
testCaseSolved(MatpowerModelFactory.create14WithPhaseShifter());
Expand Down
Loading
Loading