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

CGMES export: improve default ratedS value #2598

Merged
merged 7 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,28 @@ private CgmesExportUtil() {
private static final Pattern ENTSOE_BD_EXCEPTIONS_PATTERN1 = Pattern.compile("(?i)[a-f\\d]{8}-[a-f\\d]{4}-[a-f\\d]{4}-[a-f\\d]{4}-[a-f\\d]{7}");
private static final Pattern ENTSOE_BD_EXCEPTIONS_PATTERN2 = Pattern.compile("(?i)[a-f\\d]{8}[a-f\\d]{4}[a-f\\d]{4}[a-f\\d]{4}[a-f\\d]{12}");

private static double fixValue(double value) {
return Double.isNaN(value) ? 0.0 : value; // disconnected equipment in general, a bit dangerous.
private static double fixValue(double value, double defaultValue) {
return Double.isNaN(value) ? defaultValue : value;
}

public static String format(double value) {
return format(value, 0.0); // disconnected equipment in general, a bit dangerous.
}

public static String format(double value, double defaultValue) {
// Always use scientific format for extreme values
if (value == Double.MAX_VALUE || value == -Double.MAX_VALUE) {
return scientificFormat(value);
return scientificFormat(value, defaultValue);
}
return DOUBLE_FORMAT.format(fixValue(value));
return DOUBLE_FORMAT.format(fixValue(value, defaultValue));
}

public static String scientificFormat(double value) {
return SCIENTIFIC_FORMAT.format(fixValue(value));
return scientificFormat(value, 0.0); // disconnected equipment in general, a bit dangerous.
}

private static String scientificFormat(double value, double defaultValue) {
return SCIENTIFIC_FORMAT.format(fixValue(value, defaultValue));
}

public static String format(int value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,10 @@ private static <I extends ReactiveLimitsHolder & Injection<I>> void writeSynchro
default:
throw new PowsyblException("Unexpected type of ReactiveLimits on the generator " + i.getNameOrId());
}
double defaultRatedS = computeDefaultRatedS(i, minP, maxP);
SynchronousMachineEq.write(context.getNamingStrategy().getCgmesId(i), i.getNameOrId(),
context.getNamingStrategy().getCgmesId(i.getTerminal().getVoltageLevel()),
generatingUnit, regulatingControlId, reactiveLimitsId, minQ, maxQ, ratedS, kind, cimNamespace, writer, context);
generatingUnit, regulatingControlId, reactiveLimitsId, minQ, maxQ, ratedS, defaultRatedS, kind, cimNamespace, writer, context);
if (!generatingUnitsWritten.contains(generatingUnit)) {
// We have not preserved the names of generating units
// We name generating units based on the first machine found
Expand All @@ -373,6 +374,28 @@ private static <I extends ReactiveLimitsHolder & Injection<I>> void writeSynchro
}
}

private static <I extends ReactiveLimitsHolder & Injection<I>> double computeDefaultRatedS(I i, double minP, double maxP) {
List<Double> values = new ArrayList<>();
values.add(Math.abs(minP));
values.add(Math.abs(maxP));
ReactiveLimits limits = i.getReactiveLimits();
if (limits.getKind() == ReactiveLimitsKind.MIN_MAX) {
values.add(Math.abs(i.getReactiveLimits(MinMaxReactiveLimits.class).getMinQ()));
values.add(Math.abs(i.getReactiveLimits(MinMaxReactiveLimits.class).getMaxQ()));
} else { // reactive capability curve
ReactiveCapabilityCurve curve = i.getReactiveLimits(ReactiveCapabilityCurve.class);
for (ReactiveCapabilityCurve.Point p : curve.getPoints()) {
values.add(Math.abs(p.getP()));
values.add(Math.abs(p.getMinQ()));
values.add(Math.abs(p.getMaxQ()));
values.add(Math.sqrt(p.getP() * p.getP() + p.getMinQ() * p.getMinQ()));
values.add(Math.sqrt(p.getP() * p.getP() + p.getMaxQ() * p.getMaxQ()));
}
}
values.sort(Double::compareTo);
return values.get(values.size() - 1);
}

private static void writeShuntCompensators(Network network, Map<Terminal, String> mapTerminal2Id, Set<String> regulatingControlsWritten, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (ShuntCompensator s : network.getShuntCompensators()) {
double bPerSection = 0.0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public final class PowerTransformerEq {
private static final String EQ_POWERTRANSFORMEREND_RATEDS = "PowerTransformerEnd.ratedS";
private static final String EQ_POWERTRANSFORMEREND_RATEDU = "PowerTransformerEnd.ratedU";

private static final double EQ_POWERTRANSFORMEREND_RATEDS_DEFAULT_VALUE = 100.0;

public static void write(String id, String transformerName, String equipmentContainer, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
CgmesExportUtil.writeStartIdName("PowerTransformer", id, transformerName, cimNamespace, writer, context);
if (equipmentContainer != null) {
Expand Down Expand Up @@ -57,7 +59,7 @@ public static void writeEnd(String id, String transformerEndName, String transfo
writer.writeCharacters(CgmesExportUtil.format(b));
writer.writeEndElement();
writer.writeStartElement(cimNamespace, EQ_POWERTRANSFORMEREND_RATEDS);
writer.writeCharacters(CgmesExportUtil.format(Double.isNaN(ratedS) ? 100 : ratedS)); //RatedS by default to 100, needed for SUV
writer.writeCharacters(CgmesExportUtil.format(ratedS, EQ_POWERTRANSFORMEREND_RATEDS_DEFAULT_VALUE));
writer.writeEndElement();
writer.writeStartElement(cimNamespace, EQ_POWERTRANSFORMEREND_RATEDU);
writer.writeCharacters(CgmesExportUtil.format(ratedU));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
public final class SynchronousMachineEq {

public static void write(String id, String generatorName, String equipmentContainer, String generatingUnit, String regulatingControlId, String reactiveCapabilityCurveId,
double minQ, double maxQ, double ratedS, String kind, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
double minQ, double maxQ, double ratedS, double defaultRatedS, String kind, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
CgmesExportUtil.writeStartIdName("SynchronousMachine", id, generatorName, cimNamespace, writer, context);
CgmesExportUtil.writeReference("Equipment.EquipmentContainer", equipmentContainer, cimNamespace, writer, context);
CgmesExportUtil.writeReference("RotatingMachine.GeneratingUnit", generatingUnit, cimNamespace, writer, context);
Expand All @@ -38,7 +38,7 @@ public static void write(String id, String generatorName, String equipmentContai
writer.writeCharacters(CgmesExportUtil.format(maxQ));
writer.writeEndElement();
writer.writeStartElement(cimNamespace, "RotatingMachine.ratedS");
writer.writeCharacters(CgmesExportUtil.format(Double.isNaN(ratedS) ? 100 : ratedS)); //RatedS by default to 100, needed for SUV
writer.writeCharacters(CgmesExportUtil.format(ratedS, defaultRatedS));
writer.writeEndElement();
writer.writeEmptyElement(cimNamespace, "SynchronousMachine.type");
writer.writeAttribute(RDF_NAMESPACE, CgmesNames.RESOURCE, String.format("%s%s.%s", cimNamespace, "SynchronousMachineKind", kind)); // all generators are considered generators
Expand Down