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

Add concise and detailed logs for shunt compensators activation #70

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
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 @@ -116,6 +118,11 @@ public class OpenReacParameters {

private double twoWindingTransformerRatioVariableScalingFactor = 1e-3;

// 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 @@ -507,6 +514,21 @@ public OpenReacParameters setTwoWindingTransformerRatioVariableScalingFactor(dou
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 @@ -600,22 +622,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
Loading