Skip to content

Commit

Permalink
Fixes and behavior changes after review (#2920).
Browse files Browse the repository at this point in the history
Signed-off-by: stojkovicn <nemanja.stojkovic@rte-france.com>
Signed-off-by: nemanja-st <nemanja.stojkovic@redstork-solutions.com>
  • Loading branch information
stojkovicn authored and nemanja-st committed Jul 23, 2024
1 parent 2a47c9c commit be01bfb
Show file tree
Hide file tree
Showing 10 changed files with 502 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ private void addIidmMappingsGenerators(Network network) {
}

private static boolean hasVoltageControlCapability(Generator generator) {
if (Double.isNaN(generator.getTargetV()) || generator.getReactiveLimits() == null) {
if (generator.getReactiveLimits() == null) {
return false;
}

Expand Down Expand Up @@ -432,7 +432,8 @@ private void addIidmMappingsShuntCompensators(Network network) {
continue;
}
String regulatingControlId = shuntCompensator.getProperty(Conversion.CGMES_PREFIX_ALIAS_PROPERTIES + REGULATING_CONTROL);
if (regulatingControlId == null && SteadyStateHypothesisExport.isValidVoltageSetpoint(shuntCompensator.getTargetV())) {
if (regulatingControlId == null && (CgmesExportUtil.isValidVoltageSetpoint(shuntCompensator.getTargetV())
|| !Objects.equals(shuntCompensator, shuntCompensator.getRegulatingTerminal().getConnectable()))) {
regulatingControlId = namingStrategy.getCgmesId(ref(shuntCompensator), Part.REGULATING_CONTROL);
shuntCompensator.setProperty(Conversion.CGMES_PREFIX_ALIAS_PROPERTIES + REGULATING_CONTROL, regulatingControlId);
}
Expand All @@ -442,12 +443,11 @@ private void addIidmMappingsShuntCompensators(Network network) {
private void addIidmMappingsStaticVarCompensators(Network network) {
for (StaticVarCompensator svc : network.getStaticVarCompensators()) {
String regulatingControlId = svc.getProperty(Conversion.CGMES_PREFIX_ALIAS_PROPERTIES + REGULATING_CONTROL);
boolean validVoltageSetpoint = SteadyStateHypothesisExport.isValidVoltageSetpoint(svc.getVoltageSetpoint());
boolean validReactiveSetpoint = SteadyStateHypothesisExport.isValidReactivePowerSetpoint(svc.getReactivePowerSetpoint());
if (regulatingControlId == null && (
svc.getRegulationMode() == StaticVarCompensator.RegulationMode.VOLTAGE ||
svc.getRegulationMode() == StaticVarCompensator.RegulationMode.REACTIVE_POWER ||
validVoltageSetpoint && !validReactiveSetpoint || !validVoltageSetpoint && validReactiveSetpoint)) {
boolean validVoltageSetpoint = CgmesExportUtil.isValidVoltageSetpoint(svc.getVoltageSetpoint());
boolean validReactiveSetpoint = CgmesExportUtil.isValidReactivePowerSetpoint(svc.getReactivePowerSetpoint());
if (regulatingControlId == null && (validReactiveSetpoint
|| validVoltageSetpoint
|| !Objects.equals(svc, svc.getRegulatingTerminal().getConnectable()))) {
regulatingControlId = namingStrategy.getCgmesId(ref(svc), Part.REGULATING_CONTROL);
svc.setProperty(Conversion.CGMES_PREFIX_ALIAS_PROPERTIES + REGULATING_CONTROL, regulatingControlId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.powsybl.cgmes.conversion.export;

import com.powsybl.cgmes.conversion.Conversion;
import com.powsybl.cgmes.conversion.export.elements.RegulatingControlEq;
import com.powsybl.cgmes.conversion.naming.CgmesObjectReference;
import com.powsybl.cgmes.conversion.naming.CgmesObjectReference.Part;
import com.powsybl.cgmes.extensions.CgmesTapChanger;
Expand All @@ -21,6 +22,7 @@
import com.powsybl.commons.report.TypedValue;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.LoadDetail;
import com.powsybl.iidm.network.extensions.RemoteReactivePowerControl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -513,6 +515,68 @@ static String obtainCalculatedSynchronousMachineKind(double minP, double maxP, R
return kind;
}

public static boolean isValidVoltageSetpoint(double v) {
return Double.isFinite(v) && v > 0;
}

public static boolean isValidReactivePowerSetpoint(double q) {
return Double.isFinite(q);
}

public static String getGeneratorRegulatingControlMode(Generator generator, RemoteReactivePowerControl rrpc) {
if (rrpc == null) {
return RegulatingControlEq.REGULATING_CONTROL_VOLTAGE;
}
boolean enabledVoltageControl = generator.isVoltageRegulatorOn();
boolean enabledReactivePowerControl = rrpc.isEnabled();

if (enabledVoltageControl) {
return RegulatingControlEq.REGULATING_CONTROL_VOLTAGE;
} else if (enabledReactivePowerControl) {
return RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER;
} else {
boolean validVoltageSetpoint = isValidVoltageSetpoint(generator.getTargetV());
boolean validReactiveSetpoint = isValidReactivePowerSetpoint(rrpc.getTargetQ());
if (validReactiveSetpoint && !validVoltageSetpoint) {
return RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER;
}
return RegulatingControlEq.REGULATING_CONTROL_VOLTAGE;
}
}

public static String getSvcMode(StaticVarCompensator svc) {
if (svc.getRegulationMode().equals(StaticVarCompensator.RegulationMode.VOLTAGE)) {
return RegulatingControlEq.REGULATING_CONTROL_VOLTAGE;
} else if (svc.getRegulationMode().equals(StaticVarCompensator.RegulationMode.REACTIVE_POWER)) {
return RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER;
} else {
boolean validVoltageSetpoint = isValidVoltageSetpoint(svc.getVoltageSetpoint());
boolean validReactiveSetpoint = isValidReactivePowerSetpoint(svc.getReactivePowerSetpoint());
if (validReactiveSetpoint && !validVoltageSetpoint) {
return RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER;
}
return RegulatingControlEq.REGULATING_CONTROL_VOLTAGE;
}
}

public static String getTcMode(RatioTapChanger rtc) {
if (rtc.getRegulationMode() == null) {
throw new PowsyblException("Regulation mode not defined for RTC.");
}
return switch (rtc.getRegulationMode()) {
case VOLTAGE -> RegulatingControlEq.REGULATING_CONTROL_VOLTAGE;
case REACTIVE_POWER -> RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER;
};
}

public static String getPhaseTapChangerRegulationMode(PhaseTapChanger ptc) {
return switch (ptc.getRegulationMode()) {
case CURRENT_LIMITER -> RegulatingControlEq.REGULATING_CONTROL_CURRENT_FLOW;
case ACTIVE_POWER_CONTROL -> RegulatingControlEq.REGULATING_CONTROL_ACTIVE_POWER;
default -> throw new PowsyblException("Unexpected regulation mode: " + ptc.getRegulationMode());
};
}

public static boolean isMinusOrMaxValue(double value) {
return value == -Double.MAX_VALUE || value == Double.MAX_VALUE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@
public final class EquipmentExport {

private static final String AC_DC_CONVERTER_DC_TERMINAL = "ACDCConverterDCTerminal";
private static final String PHASE_TAP_CHANGER_REGULATION_MODE_ACTIVE_POWER = "activePower";
private static final String PHASE_TAP_CHANGER_REGULATION_MODE_CURRENT_FLOW = "currentFlow";
private static final String RATIO_TAP_CHANGER_REGULATION_MODE_VOLTAGE = "voltage";
private static final String RATIO_TAP_CHANGER_REGULATION_MODE_REACTIVE_POWER = "reactivePower";
private static final String TERMINAL_BOUNDARY = "Terminal_Boundary";
private static final Logger LOG = LoggerFactory.getLogger(EquipmentExport.class);

Expand Down Expand Up @@ -384,15 +380,9 @@ private static void writeGenerators(Network network, Map<Terminal, String> mapTe
Set<String> generatingUnitsWritten = new HashSet<>();
for (Generator generator : network.getGenerators()) {
String cgmesOriginalClass = generator.getProperty(Conversion.PROPERTY_CGMES_ORIGINAL_CLASS, CgmesNames.SYNCHRONOUS_MACHINE);
Terminal regulatingTerminal = generator.getRegulatingTerminal();
String mode = RegulatingControlEq.REGULATING_CONTROL_VOLTAGE;

// Not possible to re-export local reactive power control.
RemoteReactivePowerControl rrpc = generator.getExtension(RemoteReactivePowerControl.class);
if (rrpc != null) {
regulatingTerminal = rrpc.getRegulatingTerminal();
mode = RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER;
}
String mode = CgmesExportUtil.getGeneratorRegulatingControlMode(generator, rrpc);
Terminal regulatingTerminal = mode.equals(RegulatingControlEq.REGULATING_CONTROL_VOLTAGE) ? generator.getRegulatingTerminal() : rrpc.getRegulatingTerminal();
switch (cgmesOriginalClass) {
case CgmesNames.EQUIVALENT_INJECTION:
String reactiveCapabilityCurveId = writeReactiveCapabilityCurve(generator, cimNamespace, writer, context);
Expand Down Expand Up @@ -612,26 +602,14 @@ private static void writeShuntCompensators(Network network, Map<Terminal, String
private static void writeStaticVarCompensators(Network network, Map<Terminal, String> mapTerminal2Id, Set<String> regulatingControlsWritten, String cimNamespace,
XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (StaticVarCompensator svc : network.getStaticVarCompensators()) {
String mode = getSvcMode(svc);
String mode = CgmesExportUtil.getSvcMode(svc);
String regulatingControlId = RegulatingControlEq.writeRegulatingControlEq(svc, exportedTerminalId(mapTerminal2Id, svc.getRegulatingTerminal()), regulatingControlsWritten, mode, cimNamespace, writer, context);
double inductiveRating = svc.getBmin() != 0 ? 1 / svc.getBmin() : 0;
double capacitiveRating = svc.getBmax() != 0 ? 1 / svc.getBmax() : 0;
StaticVarCompensatorEq.write(context.getNamingStrategy().getCgmesId(svc), svc.getNameOrId(), context.getNamingStrategy().getCgmesId(svc.getTerminal().getVoltageLevel()), regulatingControlId, inductiveRating, capacitiveRating, svc.getExtension(VoltagePerReactivePowerControl.class), svc.getRegulationMode(), svc.getVoltageSetpoint(), cimNamespace, writer, context);
}
}

private static String getSvcMode(StaticVarCompensator svc) {
String mode = RegulatingControlEq.REGULATING_CONTROL_VOLTAGE;
StaticVarCompensator.RegulationMode regulationMode = svc.getRegulationMode();
if (regulationMode == StaticVarCompensator.RegulationMode.REACTIVE_POWER
|| regulationMode == StaticVarCompensator.RegulationMode.OFF
&& SteadyStateHypothesisExport.isValidReactivePowerSetpoint(svc.getReactivePowerSetpoint())
&& !SteadyStateHypothesisExport.isValidVoltageSetpoint(svc.getVoltageSetpoint())) {
mode = RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER;
}
return mode;
}

private static void writeLines(Network network, Map<Terminal, String> mapTerminal2Id, String cimNamespace, String euNamespace, String valueAttributeName, String limitTypeAttributeName, String limitKindClassName, boolean writeInfiniteDuration, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (Line line : network.getLines()) {
String baseVoltage = null;
Expand Down Expand Up @@ -863,7 +841,7 @@ private static <C extends Connectable<C>> void writePhaseTapChanger(C eq, PhaseT
Optional<String> regulatingControlId = getTapChangerControlId(eq, tapChangerId);
String cgmesRegulatingControlId = null;
if (regulatingControlId.isPresent() && CgmesExportUtil.regulatingControlIsDefined(ptc)) {
String mode = getPhaseTapChangerRegulationMode(ptc);
String mode = CgmesExportUtil.getPhaseTapChangerRegulationMode(ptc);
String controlName = twtName + "_PTC_RC";
String terminalId = CgmesExportUtil.getTerminalId(ptc.getRegulationTerminal(), context);
cgmesRegulatingControlId = context.getNamingStrategy().getCgmesId(regulatingControlId.get());
Expand Down Expand Up @@ -904,14 +882,6 @@ private static <C extends Connectable<C>> Optional<String> getTapChangerControlI
return Optional.empty();
}

private static String getPhaseTapChangerRegulationMode(PhaseTapChanger ptc) {
return switch (ptc.getRegulationMode()) {
case CURRENT_LIMITER -> PHASE_TAP_CHANGER_REGULATION_MODE_CURRENT_FLOW;
case ACTIVE_POWER_CONTROL -> PHASE_TAP_CHANGER_REGULATION_MODE_ACTIVE_POWER;
default -> throw new PowsyblException("Unexpected regulation mode: " + ptc.getRegulationMode());
};
}

private static int getPhaseTapChangerNeutralStep(PhaseTapChanger ptc) {
int neutralStep = ptc.getLowTapPosition();
double minAlpha = Math.abs(ptc.getStep(neutralStep).getAlpha());
Expand Down Expand Up @@ -947,7 +917,10 @@ private static <C extends Connectable<C>> void writeRatioTapChanger(C eq, RatioT
String terminalId = CgmesExportUtil.getTerminalId(rtc.getRegulationTerminal(), context);
cgmesRegulatingControlId = context.getNamingStrategy().getCgmesId(regulatingControlId.get());
if (!regulatingControlsWritten.contains(cgmesRegulatingControlId)) {
String tccMode = (rtc.getRegulationMode() == RatioTapChanger.RegulationMode.REACTIVE_POWER) ? RATIO_TAP_CHANGER_REGULATION_MODE_REACTIVE_POWER : RATIO_TAP_CHANGER_REGULATION_MODE_VOLTAGE;
String tccMode = CgmesExportUtil.getTcMode(rtc);
if (tccMode.equals(RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER)) {
controlMode = "reactive";
}
TapChangerEq.writeControl(cgmesRegulatingControlId, controlName, tccMode, terminalId, cimNamespace, writer, context);
regulatingControlsWritten.add(cgmesRegulatingControlId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import com.powsybl.cgmes.conversion.CgmesExport;
import com.powsybl.cgmes.conversion.Conversion;
import com.powsybl.cgmes.conversion.export.elements.RegulatingControlEq;
import com.powsybl.cgmes.extensions.CgmesControlArea;
import com.powsybl.cgmes.extensions.CgmesControlAreas;
import com.powsybl.cgmes.extensions.CgmesTapChanger;
Expand Down Expand Up @@ -206,6 +207,7 @@ private static void writeTapChangers(Network network, String cimNamespace, Map<S

for (ThreeWindingsTransformer twt : network.getThreeWindingsTransformers()) {
int i = 1;
CgmesExportUtil.addUpdateCgmesTapChangerExtension(twt, context);
for (ThreeWindingsTransformer.Leg leg : Arrays.asList(twt.getLeg1(), twt.getLeg2(), twt.getLeg3())) {
if (leg.hasPhaseTapChanger()) {
String ptcId = context.getNamingStrategy().getCgmesIdFromAlias(twt, Conversion.CGMES_PREFIX_ALIAS_PROPERTIES + CgmesNames.PHASE_TAP_CHANGER + i);
Expand Down Expand Up @@ -381,7 +383,8 @@ private static void addRegulatingControlView(Generator g, Map<String, List<Regul
String targetValueUnitMultiplier;
boolean enabled;
RemoteReactivePowerControl rrpc = g.getExtension(RemoteReactivePowerControl.class);
if (rrpc != null) {
String generatorMode = CgmesExportUtil.getGeneratorRegulatingControlMode(g, rrpc);
if (generatorMode.equals(RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER)) {
target = rrpc.getTargetQ();
targetValueUnitMultiplier = "M";
enabled = rrpc.isEnabled();
Expand All @@ -397,14 +400,6 @@ private static void addRegulatingControlView(Generator g, Map<String, List<Regul
}
}

public static boolean isValidVoltageSetpoint(double v) {
return Double.isFinite(v) && v > 0;
}

public static boolean isValidReactivePowerSetpoint(double q) {
return Double.isFinite(q);
}

private static void writeStaticVarCompensators(Network network, String cimNamespace, Map<String, List<RegulatingControlView>> regulatingControlViews,
XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (StaticVarCompensator svc : network.getStaticVarCompensators()) {
Expand All @@ -426,12 +421,11 @@ private static void writeStaticVarCompensators(Network network, String cimNamesp
// Regulating control could be reactive power or voltage
double targetValue;
String multiplier;
if (regulationMode == StaticVarCompensator.RegulationMode.VOLTAGE
|| regulationMode == StaticVarCompensator.RegulationMode.OFF && isValidVoltageSetpoint(svc.getVoltageSetpoint()) && !isValidReactivePowerSetpoint(svc.getReactivePowerSetpoint())) {
String svcMode = CgmesExportUtil.getSvcMode(svc);
if (svcMode.equals(RegulatingControlEq.REGULATING_CONTROL_VOLTAGE)) {
targetValue = svc.getVoltageSetpoint();
multiplier = "k";
} else if (regulationMode == StaticVarCompensator.RegulationMode.REACTIVE_POWER
|| regulationMode == StaticVarCompensator.RegulationMode.OFF && isValidReactivePowerSetpoint(svc.getReactivePowerSetpoint()) && !isValidVoltageSetpoint(svc.getVoltageSetpoint())) {
} else if (svcMode.equals(RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER)) {
targetValue = svc.getReactivePowerSetpoint();
multiplier = "M";
} else {
Expand Down Expand Up @@ -468,9 +462,11 @@ private static void addRegulatingControlView(TapChanger<?, ?, ?, ?> tc, CgmesTap
RegulatingControlView rcv = null;
if (tc instanceof RatioTapChanger ratioTapChanger
&& CgmesExportUtil.regulatingControlIsDefined(ratioTapChanger)) {
String unitMultiplier = switch (ratioTapChanger.getRegulationMode()) {
case VOLTAGE -> "k";
case REACTIVE_POWER -> "M";
String controlMode = CgmesExportUtil.getTcMode(ratioTapChanger);
String unitMultiplier = switch (controlMode) {
case RegulatingControlEq.REGULATING_CONTROL_VOLTAGE -> "k";
case RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER -> "M";
default -> "none";
};
rcv = new RegulatingControlView(controlId,
RegulatingControlType.TAP_CHANGER_CONTROL,
Expand All @@ -482,13 +478,13 @@ private static void addRegulatingControlView(TapChanger<?, ?, ?, ?> tc, CgmesTap
} else if (tc instanceof PhaseTapChanger phaseTapChanger
&& CgmesExportUtil.regulatingControlIsDefined(phaseTapChanger)) {
boolean valid;
String unitMultiplier = switch (phaseTapChanger.getRegulationMode()) {
case CURRENT_LIMITER -> {
String unitMultiplier = switch (CgmesExportUtil.getPhaseTapChangerRegulationMode(phaseTapChanger)) {
case RegulatingControlEq.REGULATING_CONTROL_CURRENT_FLOW -> {
// Unit multiplier is none (multiply by 1), regulation value is a current in Amperes
valid = true;
yield "none";
}
case ACTIVE_POWER_CONTROL -> {
case RegulatingControlEq.REGULATING_CONTROL_ACTIVE_POWER -> {
// Unit multiplier is M, regulation value is an active power flow in MW
valid = true;
yield "M";
Expand Down
Loading

0 comments on commit be01bfb

Please sign in to comment.