Skip to content

Commit

Permalink
Merge branch 'main' into reactive-slack-on-all-buses
Browse files Browse the repository at this point in the history
# Conflicts:
#	open-reac/src/main/java/com/powsybl/openreac/parameters/input/OpenReacParameters.java
#	open-reac/src/test/resources/openreac-output-shunt/reactiveopf_results_shunts.csv
  • Loading branch information
p-arvy committed Jun 20, 2024
2 parents bbae1e0 + 904cf5c commit 62529b3
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 34 deletions.
12 changes: 8 additions & 4 deletions open-reac/src/main/java/com/powsybl/openreac/OpenReacRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ public static OpenReacResult run(Network network, String variantId, OpenReacPara
AmplModel reactiveOpf = OpenReacModel.buildModel();
OpenReacAmplIOFiles amplIoInterface = new OpenReacAmplIOFiles(parameters, amplExportConfig, network, config.isDebug(), Reports.createOpenReacReporter(reportNode, network.getId(), parameters.getObjective()));
AmplResults run = AmplModelRunner.run(network, variantId, reactiveOpf, manager, amplIoInterface);
return new OpenReacResult(run.isSuccess() && amplIoInterface.checkErrors() ? OpenReacStatus.OK : OpenReacStatus.NOT_OK,
amplIoInterface, run.getIndicators());
OpenReacResult result = new OpenReacResult(run.isSuccess() && amplIoInterface.checkErrors() ? OpenReacStatus.OK : OpenReacStatus.NOT_OK, amplIoInterface, run.getIndicators());
Reports.createShuntModificationsReporter(reportNode, network.getId(), amplIoInterface.getNetworkModifications().getShuntsWithDeltaDiscreteOptimalOverThreshold());
return result;
}

/**
Expand Down Expand Up @@ -107,8 +108,11 @@ public static CompletableFuture<OpenReacResult> runAsync(Network network, String
AmplModel reactiveOpf = OpenReacModel.buildModel();
OpenReacAmplIOFiles amplIoInterface = new OpenReacAmplIOFiles(parameters, amplExportConfig, network, config.isDebug(), Reports.createOpenReacReporter(reportNode, network.getId(), parameters.getObjective()));
CompletableFuture<AmplResults> runAsync = AmplModelRunner.runAsync(network, variantId, reactiveOpf, manager, amplIoInterface);
return runAsync.thenApply(run -> new OpenReacResult(run.isSuccess() && amplIoInterface.checkErrors() ? OpenReacStatus.OK : OpenReacStatus.NOT_OK,
amplIoInterface, run.getIndicators()));
return runAsync.thenApply(run -> {
OpenReacResult result = new OpenReacResult(run.isSuccess() && amplIoInterface.checkErrors() ? OpenReacStatus.OK : OpenReacStatus.NOT_OK, amplIoInterface, run.getIndicators());
Reports.createShuntModificationsReporter(reportNode, network.getId(), amplIoInterface.getNetworkModifications().getShuntsWithDeltaDiscreteOptimalOverThreshold());
return result;
});
}

private static void checkParameters(Network network, String variantId, OpenReacParameters parameters, OpenReacConfig config, ComputationManager manager, ReportNode reportNode) {
Expand Down
36 changes: 34 additions & 2 deletions open-reac/src/main/java/com/powsybl/openreac/Reports.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,29 @@
import com.powsybl.commons.report.ReportNode;
import com.powsybl.commons.report.TypedValue;
import com.powsybl.openreac.parameters.input.algo.OpenReacOptimisationObjective;
import com.powsybl.openreac.parameters.output.network.ShuntCompensatorNetworkOutput;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.List;
import java.util.Locale;

/**
* @author Joris Mancini {@literal <joris.mancini_externe at rte-france.com>}
*/
public final class Reports {

private static final String NETWORK_ID = "networkId";
private static final DecimalFormat REACTIVE_VALUE_FORMAT = new DecimalFormat("0.0", DecimalFormatSymbols.getInstance(Locale.ROOT));

private Reports() {
// Should not be instantiated
}

public static ReportNode createOpenReacReporter(ReportNode reportNode, String networkId, OpenReacOptimisationObjective objective) {
return reportNode.newReportNode()
.withMessageTemplate("openReac", "Open Reac on network '${networkId}' with ${objective} objective")
.withUntypedValue("networkId", networkId)
.withUntypedValue(NETWORK_ID, networkId)
.withUntypedValue("objective", objective.toString())
.add();
}
Expand Down Expand Up @@ -54,8 +63,31 @@ public static void reportVariableShuntCompensatorsSize(ReportNode reportNode, in
public static ReportNode createParameterIntegrityReporter(ReportNode reportNode, String networkId) {
return reportNode.newReportNode()
.withMessageTemplate("openReacParameterIntegrity", "Open reac parameter integrity on network '${networkId}'")
.withUntypedValue("networkId", networkId)
.withUntypedValue(NETWORK_ID, networkId)
.add();
}

public static void createShuntModificationsReporter(ReportNode reportNode, String networkId, List<ShuntCompensatorNetworkOutput.ShuntWithDeltaDiscreteOptimalOverThreshold> shuntsWithDeltaDiscreteOptimalOverThresholds) {
if (!shuntsWithDeltaDiscreteOptimalOverThresholds.isEmpty()) {
ReportNode reportShunts = reportNode.newReportNode()
.withMessageTemplate("shuntCompensatorDeltaOverThreshold", "Shunt compensator reactive delta over threshold")
.withUntypedValue(NETWORK_ID, networkId)
.add();
reportShunts.newReportNode()
.withMessageTemplate("shuntCompensatorDeltaOverThresholdCount", "For ${shuntsCount} shunt compensators, there is a significant difference between the updated discretized reactive power value and the theoretical optimal reactive power value.")
.withUntypedValue("shuntsCount", shuntsWithDeltaDiscreteOptimalOverThresholds.size())
.withSeverity(TypedValue.INFO_SEVERITY)
.add();

shuntsWithDeltaDiscreteOptimalOverThresholds.forEach(shunt ->
reportShunts.newReportNode()
.withMessageTemplate("shuntCompensatorDeltaDiscretizedOptimizedOverThreshold", "After discretization, shunt compensator ${shuntCompensatorId} with ${maxSectionCount} available section(s) has been set to ${discretizedValue} MVar (optimal value : ${optimalValue} MVar)")
.withUntypedValue("shuntCompensatorId", shunt.id())
.withUntypedValue("maxSectionCount", shunt.maximumSectionCount())
.withUntypedValue("discretizedValue", REACTIVE_VALUE_FORMAT.format(shunt.discretizedReactiveValue()))
.withUntypedValue("optimalValue", REACTIVE_VALUE_FORMAT.format(shunt.optimalReactiveValue()))
.withSeverity(TypedValue.TRACE_SEVERITY)
.add());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public OpenReacAmplIOFiles(OpenReacParameters params, AmplExportConfig amplExpor

//outputs
this.reactiveSlackOutput = new ReactiveSlackOutput();
this.networkModifications = new NetworkModifications(network);
this.networkModifications = new NetworkModifications(network, params.getShuntCompensatorActivationAlertThreshold());
this.voltageProfileOutput = new VoltageProfileOutput();

this.debug = debug;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public class OpenReacParameters {

private final List<String> configuredReactiveSlackBuses = new ArrayList<>();

private static final String NOT_FOUND_IN_NETWORK = " not found in the network.";

// Algo parameters

private OpenReacOptimisationObjective objective = OpenReacOptimisationObjective.MIN_GENERATION;
Expand Down Expand Up @@ -120,6 +122,11 @@ public class OpenReacParameters {

private double shuntVariableScalingFactor = 1e-1;

// Shunt compensator alert threshold
// (to help reporting the shunt compensators with a delta between optimized and discretized reactive value over this threshold in MVar)

private double shuntCompensatorActivationAlertThreshold;

/**
* Override some voltage level limits in the network. This will NOT modify the network object.
* <p>
Expand Down Expand Up @@ -526,6 +533,21 @@ public OpenReacParameters setShuntVariableScalingFactor(double shuntVariableScal
return this;
}

/**
* @return the shunt compensator activation alert threshold
*/
public double getShuntCompensatorActivationAlertThreshold() {
return shuntCompensatorActivationAlertThreshold;
}

public OpenReacParameters setShuntCompensatorActivationAlertThreshold(double shuntCompensatorActivationAlertThreshold) {
if (shuntCompensatorActivationAlertThreshold < 0 || Double.isNaN(shuntCompensatorActivationAlertThreshold)) {
throw new IllegalArgumentException("The shunt compensator activation alert threshold must be >= 0 and defined to be consistent.");
}
this.shuntCompensatorActivationAlertThreshold = shuntCompensatorActivationAlertThreshold;
return this;
}

public List<OpenReacAlgoParam> getAllAlgorithmParams() {
ArrayList<OpenReacAlgoParam> allAlgoParams = new ArrayList<>();
allAlgoParams.add(objective.toParam());
Expand Down Expand Up @@ -620,22 +642,22 @@ public void checkIntegrity(Network network, ReportNode reportNode) throws Invali

for (String shuntId : getVariableShuntCompensators()) {
if (network.getShuntCompensator(shuntId) == null) {
throw new InvalidParametersException("Shunt " + shuntId + " not found in the network.");
throw new InvalidParametersException("Shunt " + shuntId + NOT_FOUND_IN_NETWORK);
}
}
for (String genId : getConstantQGenerators()) {
if (network.getGenerator(genId) == null) {
throw new InvalidParametersException("Generator " + genId + " not found in the network.");
throw new InvalidParametersException("Generator " + genId + NOT_FOUND_IN_NETWORK);
}
}
for (String transformerId : getVariableTwoWindingsTransformers()) {
if (network.getTwoWindingsTransformer(transformerId) == null) {
throw new InvalidParametersException("Two windings transformer " + transformerId + " not found in the network.");
throw new InvalidParametersException("Two windings transformer " + transformerId + NOT_FOUND_IN_NETWORK);
}
}
for (String busId : getConfiguredReactiveSlackBuses()) {
if (network.getBusView().getBus(busId) == null) {
throw new InvalidParametersException("Bus " + busId + " not found in the network.");
throw new InvalidParametersException("Bus " + busId + NOT_FOUND_IN_NETWORK);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public class NetworkModifications {
private final SvcNetworkOutput svcOutput;
private final TapPositionNetworkOutput tapPositionOutput;

public NetworkModifications(Network network) {
public NetworkModifications(Network network, double shuntCompensatorActivationAlertThreshold) {
generatorNetworkOutput = new GeneratorNetworkOutput(network);
shuntsOutput = new ShuntCompensatorNetworkOutput(network);
shuntsOutput = new ShuntCompensatorNetworkOutput(network, shuntCompensatorActivationAlertThreshold);
vscOutput = new VscNetworkOutput(network);
svcOutput = new SvcNetworkOutput(network);
tapPositionOutput = new TapPositionNetworkOutput(network);
Expand All @@ -48,6 +48,10 @@ public List<ShuntCompensatorModification> getShuntModifications() {
return shuntsOutput.getModifications();
}

public List<ShuntCompensatorNetworkOutput.ShuntWithDeltaDiscreteOptimalOverThreshold> getShuntsWithDeltaDiscreteOptimalOverThreshold() {
return shuntsOutput.getShuntsWithDeltaDiscreteOptimalOverThresholds();
}

public List<VscConverterStationModification> getVscModifications() {
return vscOutput.getModifications();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.ShuntCompensator;

import java.util.ArrayList;
import java.util.List;

/**
* @author Nicolas Pierre {@literal <nicolas.pierre at artelys.com>}
*/
Expand All @@ -21,9 +24,14 @@ public class ShuntCompensatorNetworkOutput extends AbstractNetworkOutput<ShuntCo
private static final int ID_COLUMN_INDEX = 1;
private static final int B_COLUMN_INDEX = 3;
private static final int BUS_COLUMN_INDEX = 2;
private final List<ShuntWithDeltaDiscreteOptimalOverThreshold> shuntWithDeltaDiscreteOptimalOverThresholds = new ArrayList<>();
private final double shuntCompensatorActivationAlertThreshold;

public record ShuntWithDeltaDiscreteOptimalOverThreshold(String id, int maximumSectionCount, double discretizedReactiveValue, double optimalReactiveValue) { }

public ShuntCompensatorNetworkOutput(Network network) {
public ShuntCompensatorNetworkOutput(Network network, double shuntCompensatorActivationAlertThreshold) {
super(network);
this.shuntCompensatorActivationAlertThreshold = shuntCompensatorActivationAlertThreshold;
}

@Override
Expand Down Expand Up @@ -64,6 +72,15 @@ private int findSectionCount(ShuntCompensator sc, double b) {
sectionCount = i;
}
}
double optimalReactiveValue = Math.abs(b * Math.pow(sc.getTerminal().getVoltageLevel().getNominalV(), 2));
double discretizedReactiveValue = Math.abs(sc.getB(sectionCount) * Math.pow(sc.getTerminal().getVoltageLevel().getNominalV(), 2));
if (Math.abs(discretizedReactiveValue - optimalReactiveValue) > shuntCompensatorActivationAlertThreshold) {
shuntWithDeltaDiscreteOptimalOverThresholds.add(new ShuntWithDeltaDiscreteOptimalOverThreshold(sc.getId(), sc.getMaximumSectionCount(), discretizedReactiveValue, optimalReactiveValue));
}
return sectionCount;
}

public List<ShuntWithDeltaDiscreteOptimalOverThreshold> getShuntsWithDeltaDiscreteOptimalOverThresholds() {
return shuntWithDeltaDiscreteOptimalOverThresholds;
}
}
Loading

0 comments on commit 62529b3

Please sign in to comment.