Skip to content

Commit

Permalink
CGMES export - Add a parameter to export generators in local regulati…
Browse files Browse the repository at this point in the history
…on mode (#3198)

* Gives an option to export generators in local regulation mode in the CGMES export
* Remove duplicated code by setting the proper value for the terminal used for regulation in the CGMES Equipment export
* Update the CGMES export documentation
* Avoid potential rounding variations of targetV if local nominalV and remote nominalV are identical

Signed-off-by: Romain Courtier <romain.courtier@rte-france.com>
  • Loading branch information
rcourtier authored Nov 26, 2024
1 parent a82905c commit bf12fdd
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ private void addParametersToContext(CgmesExportContext context, Properties param
.setExportTransformersWithHighestVoltageAtEnd1(Parameter.readBoolean(getFormat(), params, EXPORT_TRANSFORMERS_WITH_HIGHEST_VOLTAGE_AT_END1_PARAMETER, defaultValueConfig))
.setExportLoadFlowStatus(Parameter.readBoolean(getFormat(), params, EXPORT_LOAD_FLOW_STATUS_PARAMETER, defaultValueConfig))
.setExportAllLimitsGroup(Parameter.readBoolean(getFormat(), params, EXPORT_ALL_LIMITS_GROUP_PARAMETER, defaultValueConfig))
.setExportGeneratorsInLocalRegulationMode(Parameter.readBoolean(getFormat(), params, EXPORT_GENERATORS_IN_LOCAL_REGULATION_MODE_PARAMETER, defaultValueConfig))
.setMaxPMismatchConverged(Parameter.readDouble(getFormat(), params, MAX_P_MISMATCH_CONVERGED_PARAMETER, defaultValueConfig))
.setMaxQMismatchConverged(Parameter.readDouble(getFormat(), params, MAX_Q_MISMATCH_CONVERGED_PARAMETER, defaultValueConfig))
.setExportSvInjectionsForSlacks(Parameter.readBoolean(getFormat(), params, EXPORT_SV_INJECTIONS_FOR_SLACKS_PARAMETER, defaultValueConfig))
Expand Down Expand Up @@ -544,6 +545,7 @@ public String getFormat() {
public static final String EXPORT_TRANSFORMERS_WITH_HIGHEST_VOLTAGE_AT_END1 = "iidm.export.cgmes.export-transformers-with-highest-voltage-at-end1";
public static final String EXPORT_LOAD_FLOW_STATUS = "iidm.export.cgmes.export-load-flow-status";
public static final String EXPORT_ALL_LIMITS_GROUP = "iidm.export.cgmes.export-all-limits-group";
public static final String EXPORT_GENERATORS_IN_LOCAL_REGULATION_MODE = "iidm.export.cgmes.export-generators-in-local-regulation-mode";
public static final String MAX_P_MISMATCH_CONVERGED = "iidm.export.cgmes.max-p-mismatch-converged";
public static final String MAX_Q_MISMATCH_CONVERGED = "iidm.export.cgmes.max-q-mismatch-converged";
public static final String EXPORT_SV_INJECTIONS_FOR_SLACKS = "iidm.export.cgmes.export-sv-injections-for-slacks";
Expand Down Expand Up @@ -637,7 +639,12 @@ public String getFormat() {
EXPORT_ALL_LIMITS_GROUP,
ParameterType.BOOLEAN,
"True to export all OperationalLimitsGroup, False to export only the selected group",
CgmesExportContext.EXPORT_LOAD_FLOW_STATUS_DEFAULT_VALUE);
CgmesExportContext.EXPORT_ALL_LIMITS_GROUP_DEFAULT_VALUE);
private static final Parameter EXPORT_GENERATORS_IN_LOCAL_REGULATION_MODE_PARAMETER = new Parameter(
EXPORT_GENERATORS_IN_LOCAL_REGULATION_MODE,
ParameterType.BOOLEAN,
"True to export voltage regulating generators in local regulation mode, False to keep their regulation mode unchanged.",
CgmesExportContext.EXPORT_GENERATORS_IN_LOCAL_REGULATION_MODE_DEFAULT_VALUE);
private static final Parameter MAX_P_MISMATCH_CONVERGED_PARAMETER = new Parameter(
MAX_P_MISMATCH_CONVERGED,
ParameterType.DOUBLE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public class CgmesExportContext {
public static final boolean ENCODE_IDS_DEFAULT_VALUE = true;
public static final boolean EXPORT_LOAD_FLOW_STATUS_DEFAULT_VALUE = true;
public static final boolean EXPORT_ALL_LIMITS_GROUP_DEFAULT_VALUE = true;
public static final boolean EXPORT_GENERATORS_IN_LOCAL_REGULATION_MODE_DEFAULT_VALUE = false;
// From QoCDC 3.3.1 rules IGMConvergence, KirchhoffsFirstLaw, ... that refer to SV_INJECTION_LIMIT=0.1
public static final double MAX_P_MISMATCH_CONVERGED_DEFAULT_VALUE = 0.1;
public static final double MAX_Q_MISMATCH_CONVERGED_DEFAULT_VALUE = 0.1;
Expand All @@ -88,6 +89,7 @@ public class CgmesExportContext {
private boolean exportTransformersWithHighestVoltageAtEnd1 = EXPORT_TRANSFORMERS_WITH_HIGHEST_VOLTAGE_AT_END1_DEFAULT_VALUE;
private boolean exportLoadFlowStatus = EXPORT_LOAD_FLOW_STATUS_DEFAULT_VALUE;
private boolean exportAllLimitsGroup = EXPORT_ALL_LIMITS_GROUP_DEFAULT_VALUE;
private boolean exportGeneratorsInLocalRegulationMode = EXPORT_GENERATORS_IN_LOCAL_REGULATION_MODE_DEFAULT_VALUE;
private double maxPMismatchConverged = MAX_P_MISMATCH_CONVERGED_DEFAULT_VALUE;
private double maxQMismatchConverged = MAX_Q_MISMATCH_CONVERGED_DEFAULT_VALUE;
private boolean isExportSvInjectionsForSlacks = EXPORT_SV_INJECTIONS_FOR_SLACKS_DEFAULT_VALUE;
Expand Down Expand Up @@ -619,6 +621,15 @@ public CgmesExportContext setExportAllLimitsGroup(boolean exportAllLimitsGroup)
return this;
}

public boolean isExportGeneratorsInLocalRegulationMode() {
return exportGeneratorsInLocalRegulationMode;
}

public CgmesExportContext setExportGeneratorsInLocalRegulationMode(boolean exportGeneratorsInLocalRegulationMode) {
this.exportGeneratorsInLocalRegulationMode = exportGeneratorsInLocalRegulationMode;
return this;
}

public double getMaxPMismatchConverged() {
return maxPMismatchConverged;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,15 @@ private static void writeGenerators(Network network, Map<Terminal, String> mapTe
String cgmesOriginalClass = generator.getProperty(Conversion.PROPERTY_CGMES_ORIGINAL_CLASS, CgmesNames.SYNCHRONOUS_MACHINE);
RemoteReactivePowerControl rrpc = generator.getExtension(RemoteReactivePowerControl.class);
String mode = CgmesExportUtil.getGeneratorRegulatingControlMode(generator, rrpc);
Terminal regulatingTerminal = mode.equals(RegulatingControlEq.REGULATING_CONTROL_VOLTAGE) ? generator.getRegulatingTerminal() : rrpc.getRegulatingTerminal();
Terminal regulatingTerminal;
if (mode.equals(RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER)) {
regulatingTerminal = rrpc.getRegulatingTerminal();
} else if (context.isExportGeneratorsInLocalRegulationMode()) {
regulatingTerminal = generator.getTerminal();
} else {
regulatingTerminal = generator.getRegulatingTerminal();
}
String regulatingControlId;
switch (cgmesOriginalClass) {
case CgmesNames.EQUIVALENT_INJECTION:
String reactiveCapabilityCurveId = writeReactiveCapabilityCurve(generator, cimNamespace, writer, context);
Expand All @@ -393,7 +401,7 @@ private static void writeGenerators(Network network, Map<Terminal, String> mapTe
cimNamespace, writer, context);
break;
case CgmesNames.EXTERNAL_NETWORK_INJECTION:
String regulatingControlId = RegulatingControlEq.writeRegulatingControlEq(generator, exportedTerminalId(mapTerminal2Id, regulatingTerminal), regulatingControlsWritten, mode, cimNamespace, writer, context);
regulatingControlId = RegulatingControlEq.writeRegulatingControlEq(generator, exportedTerminalId(mapTerminal2Id, regulatingTerminal), regulatingControlsWritten, mode, cimNamespace, writer, context);
ExternalNetworkInjectionEq.write(context.getNamingStrategy().getCgmesId(generator), generator.getNameOrId(),
context.getNamingStrategy().getCgmesId(generator.getTerminal().getVoltageLevel()),
obtainGeneratorGovernorScd(generator), generator.getMaxP(), obtainMaxQ(generator), generator.getMinP(), obtainMinQ(generator),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,14 @@ private static void addRegulatingControlView(Generator g, Map<String, List<Regul
enabled = rrpc.isEnabled();
} else {
target = g.getTargetV();
if (context.isExportGeneratorsInLocalRegulationMode()) {
double remoteNominalV = g.getRegulatingTerminal().getVoltageLevel().getNominalV();
double localNominalV = g.getTerminal().getVoltageLevel().getNominalV();
if (localNominalV != remoteNominalV) {
// This check prevents potential rounding variations of target when both voltages are equals
target = localNominalV * target / remoteNominalV;
}
}
targetValueUnitMultiplier = "k";
enabled = g.isVoltageRegulatorOn();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,14 @@ void generatorRegulatingControlEQTest() throws IOException {
eq = getEQ(network, baseName, tmpDir, exportParams);
testRcEqRcWithAttribute(eq, "_GEN_RC", "_NHV2_NLOAD_PT_T_1", "voltage");

// Generator with remote voltage regulation exported in local regulation mode
Properties exportInLocalRegulationModeParams = new Properties();
exportInLocalRegulationModeParams.put(CgmesExport.PROFILES, "EQ");
exportInLocalRegulationModeParams.put(CgmesExport.EXPORT_GENERATORS_IN_LOCAL_REGULATION_MODE, true);
network = EurostagTutorialExample1Factory.createWithRemoteVoltageGenerator();
eq = getEQ(network, baseName, tmpDir, exportInLocalRegulationModeParams);
testRcEqRcWithAttribute(eq, "_GEN_RC", "_GEN_SM_T_1", "voltage");

// Generator with local reactive
network = EurostagTutorialExample1Factory.createWithLocalReactiveGenerator();
eq = getEQ(network, baseName, tmpDir, exportParams);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -681,10 +681,18 @@ void generatorRegulatingControlSSHTest() throws IOException {
// Generator remote voltage
network = EurostagTutorialExample1Factory.createWithRemoteVoltageGenerator();
ssh = getSSH(network, baseName, tmpDir, exportParams);
testRcEqRcWithAttribute(ssh, "_GEN_RC", "false", "true", "0", "24.5", "k");
testRcEqRcWithAttribute(ssh, "_GEN_RC", "false", "true", "0", "399", "k");
network.getGenerator("GEN").setVoltageRegulatorOn(false);
ssh = getSSH(network, baseName, tmpDir, exportParams);
testRcEqRcWithAttribute(ssh, "_GEN_RC", "false", "false", "0", "24.5", "k");
testRcEqRcWithAttribute(ssh, "_GEN_RC", "false", "false", "0", "399", "k");

// Generator with remote voltage regulation exported in local regulation mode
Properties exportInLocalRegulationModeParams = new Properties();
exportInLocalRegulationModeParams.put(CgmesExport.PROFILES, "SSH");
exportInLocalRegulationModeParams.put(CgmesExport.EXPORT_GENERATORS_IN_LOCAL_REGULATION_MODE, true);
network = EurostagTutorialExample1Factory.createWithRemoteVoltageGenerator();
ssh = getSSH(network, baseName, tmpDir, exportInLocalRegulationModeParams);
testRcEqRcWithAttribute(ssh, "_GEN_RC", "false", "true", "0", "25.2", "k");

// Generator with local reactive
network = EurostagTutorialExample1Factory.createWithLocalReactiveGenerator();
Expand Down Expand Up @@ -719,16 +727,16 @@ void generatorRegulatingControlSSHTest() throws IOException {
// Generator with remote reactive and voltage
network = EurostagTutorialExample1Factory.createWithRemoteReactiveAndVoltageGenerators();
ssh = getSSH(network, baseName, tmpDir, exportParams);
testRcEqRcWithAttribute(ssh, "_GEN_RC", "false", "true", "0", "24.5", "k");
testRcEqRcWithAttribute(ssh, "_GEN_RC", "false", "true", "0", "399", "k");
network.getGenerator("GEN").setVoltageRegulatorOn(false);
ssh = getSSH(network, baseName, tmpDir, exportParams);
testRcEqRcWithAttribute(ssh, "_GEN_RC", "false", "true", "0", "200", "M");
network.getGenerator("GEN").getExtension(RemoteReactivePowerControl.class).setEnabled(false);
ssh = getSSH(network, baseName, tmpDir, exportParams);
testRcEqRcWithAttribute(ssh, "_GEN_RC", "false", "false", "0", "24.5", "k");
testRcEqRcWithAttribute(ssh, "_GEN_RC", "false", "false", "0", "399", "k");
network.getGenerator("GEN").setVoltageRegulatorOn(true);
ssh = getSSH(network, baseName, tmpDir, exportParams);
testRcEqRcWithAttribute(ssh, "_GEN_RC", "false", "true", "0", "24.5", "k");
testRcEqRcWithAttribute(ssh, "_GEN_RC", "false", "true", "0", "399", "k");

// Generator without control
network = EurostagTutorialExample1Factory.createWithoutControl();
Expand Down
5 changes: 5 additions & 0 deletions docs/grid_exchange_formats/cgmes/export.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,11 @@ This property is set to `true` by default.
Optional property that defines whether all OperationalLimitsGroup should be exported, or only the selected (active) ones.
This property is set to `true` by default, which means all groups are exported (not only the active ones).

**iidm.export.cgmes.export-generators-in-local-regulation-mode**
Optional property that allows to export voltage regulating generators in local regulation mode. This doesn't concern reactive power regulating generators.
If set to true, the generator's regulating terminal is set to the generator's own terminal and the target voltage is rescaled accordingly.
This property is set to `false` by default.

**iidm.export.cgmes.max-p-mismatch-converged**
Optional property that defines the threshold below which a bus is considered to be balanced for the load flow status of the `TopologicalIsland` in active power. If the sum of all the active power of the terminals connected to the bus is greater than this threshold, then the load flow is considered to be divergent. Its default value is `0.1`, and it should be used only if the `iidm.export.cgmes.export-load-flow-status` property is set to `true`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,8 @@ private static Network addReactiveGenerator(Network network, Terminal terminal)

private static Network addRemoteVoltageGenerator(Network network) {
network.getGenerator("GEN")
.setRegulatingTerminal(network.getTwoWindingsTransformer(NHV2_NLOAD).getTerminal1());
.setRegulatingTerminal(network.getTwoWindingsTransformer(NHV2_NLOAD).getTerminal1())
.setTargetV(399);
return network;
}

Expand Down

0 comments on commit bf12fdd

Please sign in to comment.