Skip to content

Commit

Permalink
Security analysis functional logs (#576)
Browse files Browse the repository at this point in the history
Signed-off-by: Geoffroy Jamgotchian <geoffroy.jamgotchian@gmail.com>
  • Loading branch information
geofjamg authored Jul 6, 2022
1 parent 7175f18 commit 51b5c35
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ public AcLoadFlowResult run() {

LOGGER.info("Ac loadflow complete on network {} (result={})", context.getNetwork(), result);

Reports.reportAcLfComplete(context.getNetwork().getReporter(), result.getNewtonRaphsonStatus().name());

return result;
}

Expand Down
12 changes: 8 additions & 4 deletions src/main/java/com/powsybl/openloadflow/network/LfNetwork.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public class LfNetwork extends AbstractPropertyBag implements PropertyBag {

private GraphDecrementalConnectivity<LfBus, LfBranch> connectivity;

private final Reporter reporter;
private Reporter reporter;

public LfNetwork(int numCC, int numSC, SlackBusSelector slackBusSelector,
GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory, Reporter reporter) {
Expand Down Expand Up @@ -107,6 +107,10 @@ public Reporter getReporter() {
return reporter;
}

public void setReporter(Reporter reporter) {
this.reporter = Objects.requireNonNull(reporter);
}

private void invalidateSlack() {
slackBus = null;
}
Expand Down Expand Up @@ -427,7 +431,7 @@ public void writeJson(Writer writer) {
}

private void reportSize(Reporter reporter) {
Reports.reportNetworkSize(reporter, numCC, numSC, busesById.values().size(), branches.size());
Reports.reportNetworkSize(reporter, busesById.values().size(), branches.size());
LOGGER.info("Network {} has {} buses and {} branches",
this, busesById.values().size(), branches.size());
}
Expand All @@ -444,7 +448,7 @@ public void reportBalance(Reporter reporter) {
reactiveLoad += b.getLoadTargetQ() * PerUnit.SB;
}

Reports.reportNetworkBalance(reporter, numCC, numSC, activeGeneration, activeLoad, reactiveGeneration, reactiveLoad);
Reports.reportNetworkBalance(reporter, activeGeneration, activeLoad, reactiveGeneration, reactiveLoad);
LOGGER.info("Network {} balance: active generation={} MW, active load={} MW, reactive generation={} MVar, reactive load={} MVar",
this, activeGeneration, activeLoad, reactiveGeneration, reactiveLoad);
}
Expand All @@ -468,7 +472,7 @@ private void validateBuses(boolean dc, Reporter reporter) {
}
if (!hasAtLeastOneBusVoltageControlled) {
LOGGER.error("Network {} must have at least one bus voltage controlled", this);
Reports.reportNetworkMustHaveAtLeastOneBusVoltageControlled(reporter, numCC, numSC);
Reports.reportNetworkMustHaveAtLeastOneBusVoltageControlled(reporter);
valid = false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package com.powsybl.openloadflow.sa;

import com.powsybl.commons.reporter.Reporter;
import com.powsybl.computation.CompletableFutureTask;
import com.powsybl.computation.ComputationManager;
import com.powsybl.contingency.ContingenciesProvider;
Expand Down Expand Up @@ -40,12 +41,15 @@ public abstract class AbstractSecurityAnalysis {

protected final StateMonitorIndex monitorIndex;

protected final Reporter reporter;

protected AbstractSecurityAnalysis(Network network, MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory,
List<StateMonitor> stateMonitors) {
List<StateMonitor> stateMonitors, Reporter reporter) {
this.network = Objects.requireNonNull(network);
this.matrixFactory = Objects.requireNonNull(matrixFactory);
this.connectivityFactory = Objects.requireNonNull(connectivityFactory);
this.monitorIndex = new StateMonitorIndex(stateMonitors);
this.reporter = Objects.requireNonNull(reporter);
}

public CompletableFuture<SecurityAnalysisReport> run(String workingVariantId, SecurityAnalysisParameters securityAnalysisParameters,
Expand Down
23 changes: 17 additions & 6 deletions src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.powsybl.openloadflow.network.impl.PropagatedContingency;
import com.powsybl.openloadflow.network.util.ActivePowerDistribution;
import com.powsybl.openloadflow.network.util.PreviousValueVoltageInitializer;
import com.powsybl.openloadflow.util.Reports;
import com.powsybl.security.LimitViolationsResult;
import com.powsybl.security.SecurityAnalysisParameters;
import com.powsybl.security.SecurityAnalysisReport;
Expand All @@ -42,8 +43,8 @@
public class AcSecurityAnalysis extends AbstractSecurityAnalysis {

protected AcSecurityAnalysis(Network network, MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory,
List<StateMonitor> stateMonitors) {
super(network, matrixFactory, connectivityFactory, stateMonitors);
List<StateMonitor> stateMonitors, Reporter reporter) {
super(network, matrixFactory, connectivityFactory, stateMonitors, reporter);
}

private static SecurityAnalysisResult createNoResult() {
Expand All @@ -57,6 +58,8 @@ private static SecurityAnalysisResult createNoResult() {
@Override
SecurityAnalysisReport runSync(String workingVariantId, SecurityAnalysisParameters securityAnalysisParameters, ContingenciesProvider contingenciesProvider,
ComputationManager computationManager) {
var saReporter = Reports.createAcSecurityAnalysis(reporter, network.getId());

Stopwatch stopwatch = Stopwatch.createStarted();

LoadFlowParameters lfParameters = securityAnalysisParameters.getLoadFlowParameters();
Expand All @@ -75,10 +78,10 @@ SecurityAnalysisReport runSync(String workingVariantId, SecurityAnalysisParamete
lfParameters.isShuntCompensatorVoltageControlOn(), lfParameters.getBalanceType() == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD,
lfParameters.isHvdcAcEmulation(), securityAnalysisParametersExt.isContingencyPropagation());

AcLoadFlowParameters acParameters = OpenLoadFlowParameters.createAcParameters(network, lfParameters, lfParametersExt, matrixFactory, connectivityFactory, Reporter.NO_OP, true, false);
AcLoadFlowParameters acParameters = OpenLoadFlowParameters.createAcParameters(network, lfParameters, lfParametersExt, matrixFactory, connectivityFactory, saReporter, true, false);

// create networks including all necessary switches
List<LfNetwork> lfNetworks = createNetworks(allSwitchesToOpen, acParameters.getNetworkParameters());
List<LfNetwork> lfNetworks = createNetworks(allSwitchesToOpen, acParameters.getNetworkParameters(), saReporter);

// run simulation on largest network
SecurityAnalysisResult result;
Expand All @@ -100,15 +103,16 @@ SecurityAnalysisReport runSync(String workingVariantId, SecurityAnalysisParamete
return new SecurityAnalysisReport(result);
}

List<LfNetwork> createNetworks(Set<Switch> allSwitchesToOpen, LfNetworkParameters networkParameters) {
List<LfNetwork> createNetworks(Set<Switch> allSwitchesToOpen, LfNetworkParameters networkParameters,
Reporter saReporter) {
List<LfNetwork> lfNetworks;
String tmpVariantId = "olf-tmp-" + UUID.randomUUID();
network.getVariantManager().cloneVariant(network.getVariantManager().getWorkingVariantId(), tmpVariantId);
try {
network.getSwitchStream().filter(sw -> sw.getVoltageLevel().getTopologyKind() == TopologyKind.NODE_BREAKER)
.forEach(sw -> sw.setRetained(false));
allSwitchesToOpen.forEach(sw -> sw.setRetained(true));
lfNetworks = Networks.load(network, networkParameters, Reporter.NO_OP);
lfNetworks = Networks.load(network, networkParameters, saReporter);
} finally {
network.getVariantManager().removeVariant(tmpVariantId);
}
Expand All @@ -131,6 +135,10 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List<Propagated
boolean createResultExtension = openSecurityAnalysisParameters.isCreateResultExtension();

try (AcLoadFlowContext context = new AcLoadFlowContext(network, acParameters)) {
Reporter networkReporter = network.getReporter();
Reporter preContSimReporter = Reports.createPreContingencySimulation(networkReporter);
network.setReporter(preContSimReporter);

// run pre-contingency simulation
AcLoadFlowResult preContingencyLoadFlowResult = new AcloadFlowEngine(context)
.run();
Expand All @@ -157,6 +165,9 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List<Propagated
PropagatedContingency propagatedContingency = contingencyIt.next();
propagatedContingency.toLfContingency(network, true)
.ifPresent(lfContingency -> { // only process contingencies that impact the network
Reporter postContSimReporter = Reports.createPostContingencySimulation(networkReporter, lfContingency.getId());
network.setReporter(postContSimReporter);

lfContingency.apply(loadFlowParameters.getBalanceType());

distributedMismatch(network, lfContingency.getActivePowerLoss(), loadFlowParameters, openLoadFlowParameters);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
public class DcSecurityAnalysis extends AbstractSecurityAnalysis {

protected DcSecurityAnalysis(Network network, MatrixFactory matrixFactory, GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory,
List<StateMonitor> stateMonitors) {
super(network, matrixFactory, connectivityFactory, stateMonitors);
List<StateMonitor> stateMonitors, Reporter reporter) {
super(network, matrixFactory, connectivityFactory, stateMonitors, reporter);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,13 @@ public CompletableFuture<SecurityAnalysisReport> run(Network network, String wor
Objects.requireNonNull(securityAnalysisParameters);
Objects.requireNonNull(contingenciesProvider);
Objects.requireNonNull(stateMonitors);
Objects.requireNonNull(reporter);

AbstractSecurityAnalysis securityAnalysis;
if (securityAnalysisParameters.getLoadFlowParameters().isDc()) {
securityAnalysis = new DcSecurityAnalysis(network, matrixFactory, connectivityFactory, stateMonitors);
securityAnalysis = new DcSecurityAnalysis(network, matrixFactory, connectivityFactory, stateMonitors, reporter);
} else {
securityAnalysis = new AcSecurityAnalysis(network, matrixFactory, connectivityFactory, stateMonitors);
securityAnalysis = new AcSecurityAnalysis(network, matrixFactory, connectivityFactory, stateMonitors, reporter);
}

return securityAnalysis.run(workingVariantId, securityAnalysisParameters, contingenciesProvider, computationManager);
Expand Down
47 changes: 32 additions & 15 deletions src/main/java/com/powsybl/openloadflow/util/Reports.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,40 +21,35 @@ public final class Reports {
private static final String NETWORK_NUM_CC = "networkNumCc";
private static final String NETWORK_NUM_SC = "networkNumSc";
private static final String ITERATION = "iteration";
private static final String NETWORK_ID = "networkId";

private Reports() {
}

public static void reportNetworkSize(Reporter reporter, int networkNumCc, int networkNumSc, int busCount, int branchCount) {
public static void reportNetworkSize(Reporter reporter, int busCount, int branchCount) {
reporter.report(Report.builder()
.withKey("networkSize")
.withDefaultMessage("Network CC${networkNumCc} SC${networkNumSc} has ${busCount} buses and ${branchCount} branches")
.withValue(NETWORK_NUM_CC, networkNumCc)
.withValue(NETWORK_NUM_SC, networkNumSc)
.withDefaultMessage("Network has ${busCount} buses and ${branchCount} branches")
.withValue("busCount", busCount)
.withValue("branchCount", branchCount)
.build());
}

public static void reportNetworkBalance(Reporter reporter, int networkNumCc, int networkNumSc, double activeGeneration, double activeLoad, double reactiveGeneration, double reactiveLoad) {
public static void reportNetworkBalance(Reporter reporter, double activeGeneration, double activeLoad, double reactiveGeneration, double reactiveLoad) {
reporter.report(Report.builder()
.withKey("networkBalance")
.withDefaultMessage("Network CC${networkNumCc} SC${networkNumSc} balance: active generation=${activeGeneration} MW, active load=${activeLoad} MW, reactive generation=${reactiveGeneration} MVar, reactive load=${reactiveLoad} MVar")
.withValue(NETWORK_NUM_CC, networkNumCc)
.withValue(NETWORK_NUM_SC, networkNumSc)
.withDefaultMessage("Network balance: active generation=${activeGeneration} MW, active load=${activeLoad} MW, reactive generation=${reactiveGeneration} MVar, reactive load=${reactiveLoad} MVar")
.withValue("activeGeneration", activeGeneration)
.withValue("activeLoad", activeLoad)
.withValue("reactiveGeneration", reactiveGeneration)
.withValue("reactiveLoad", reactiveLoad)
.build());
}

public static void reportNetworkMustHaveAtLeastOneBusVoltageControlled(Reporter reporter, int networkNumCc, int networkNumSc) {
public static void reportNetworkMustHaveAtLeastOneBusVoltageControlled(Reporter reporter) {
reporter.report(Report.builder()
.withKey("networkMustHaveAtLeastOneBusVoltageControlled")
.withDefaultMessage("Network CC${networkNumCc} SC${networkNumSc} must have at least one bus voltage controlled")
.withValue(NETWORK_NUM_CC, networkNumCc)
.withValue(NETWORK_NUM_SC, networkNumSc)
.withDefaultMessage("Network must have at least one bus voltage controlled")
.build());
}

Expand Down Expand Up @@ -142,9 +137,17 @@ public static void reportGeneratorsDiscardedFromVoltageControlBecauseMaxReactive
.build());
}

public static void reportAcLfComplete(Reporter reporter, String nrStatus) {
reporter.report(Report.builder()
.withKey("acLfComplete")
.withDefaultMessage("AC load flow complete with NR status '${nrStatus}'")
.withValue("nrStatus", nrStatus)
.build());
}

public static Reporter createLoadFlowReporter(Reporter reporter, String networkId) {
return reporter.createSubReporter("loadFlow", "Load flow on network ${networkId}",
"networkId", networkId);
return reporter.createSubReporter("loadFlow", "Load flow on network '${networkId}'",
NETWORK_ID, networkId);
}

public static Reporter createLfNetworkReporter(Reporter reporter, int networkNumCc, int networkNumSc) {
Expand All @@ -163,6 +166,20 @@ public static Reporter createOuterLoopReporter(Reporter reporter, String outerLo

public static Reporter createSensitivityAnalysis(Reporter reporter, String networkId) {
return reporter.createSubReporter("sensitivityAnalysis",
"Sensitivity analysis on network ${networkId}", "networkId", networkId);
"Sensitivity analysis on network '${networkId}'", NETWORK_ID, networkId);
}

public static Reporter createAcSecurityAnalysis(Reporter reporter, String networkId) {
return reporter.createSubReporter("acSecurityAnalysis",
"AC security analysis on network '${networkId}'", NETWORK_ID, networkId);
}

public static Reporter createPreContingencySimulation(Reporter reporter) {
return reporter.createSubReporter("preContingencySimulation", "Pre-contingency simulation");
}

public static Reporter createPostContingencySimulation(Reporter reporter, String contingencyId) {
return reporter.createSubReporter("postContingencySimulation", "Post-contingency simulation '${contingencyId}'",
"contingencyId", contingencyId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ void noGeneratorTest() {
ReporterModel postLoadingReporter = createNetworkReporter.getSubReporters().get(0);
assertEquals("postLoadingProcessing", postLoadingReporter.getTaskKey());
assertEquals(1, postLoadingReporter.getReports().size());
assertEquals("Network CC${networkNumCc} SC${networkNumSc} must have at least one bus voltage controlled",
assertEquals("Network must have at least one bus voltage controlled",
postLoadingReporter.getReports().iterator().next().getDefaultMessage());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import com.powsybl.commons.AbstractConverterTest;
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.reporter.Reporter;
import com.powsybl.contingency.BranchContingency;
import com.powsybl.contingency.Contingency;
import com.powsybl.contingency.GeneratorContingency;
Expand Down Expand Up @@ -65,7 +66,7 @@ void test() throws IOException {
LfNetwork mainNetwork = lfNetworks.get(0);
assertEquals(2, lfNetworks.size());

new AcSecurityAnalysis(network, new DenseMatrixFactory(), connectivityFactory, Collections.emptyList());
new AcSecurityAnalysis(network, new DenseMatrixFactory(), connectivityFactory, Collections.emptyList(), Reporter.NO_OP);

String branchId = "LINE_S3S4";
Contingency contingency = new Contingency(branchId, new BranchContingency(branchId));
Expand Down Expand Up @@ -94,7 +95,7 @@ void testGeneratorNotFound() {
assertEquals(2, lfNetworks.size());

GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory = new EvenShiloachGraphDecrementalConnectivityFactory<>();
new AcSecurityAnalysis(network, new DenseMatrixFactory(), connectivityFactory, Collections.emptyList());
new AcSecurityAnalysis(network, new DenseMatrixFactory(), connectivityFactory, Collections.emptyList(), Reporter.NO_OP);

String generatorId = "GEN";
Contingency contingency = new Contingency(generatorId, new GeneratorContingency(generatorId));
Expand All @@ -110,7 +111,7 @@ void testLoadNotFound() {
assertEquals(2, lfNetworks.size());

GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory = new EvenShiloachGraphDecrementalConnectivityFactory<>();
new AcSecurityAnalysis(network, new DenseMatrixFactory(), connectivityFactory, Collections.emptyList());
new AcSecurityAnalysis(network, new DenseMatrixFactory(), connectivityFactory, Collections.emptyList(), Reporter.NO_OP);

String loadId = "LOAD";
Contingency contingency = new Contingency(loadId, new LoadContingency(loadId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ private void printResult(List<List<LfContingency>> result) {
List<List<LfContingency>> getLoadFlowContingencies(GraphDecrementalConnectivityFactory<LfBus, LfBranch> connectivityFactory) {

var matrixFactory = new DenseMatrixFactory();
AcSecurityAnalysis securityAnalysis = new AcSecurityAnalysis(network, matrixFactory, connectivityFactory, Collections.emptyList());
AcSecurityAnalysis securityAnalysis = new AcSecurityAnalysis(network, matrixFactory, connectivityFactory, Collections.emptyList(), Reporter.NO_OP);

LoadFlowParameters lfParameters = securityAnalysisParameters.getLoadFlowParameters();
OpenLoadFlowParameters lfParametersExt = OpenLoadFlowParameters.get(securityAnalysisParameters.getLoadFlowParameters());
Expand All @@ -157,7 +157,7 @@ List<List<LfContingency>> getLoadFlowContingencies(GraphDecrementalConnectivityF
lfParameters, lfParametersExt, matrixFactory, connectivityFactory, Reporter.NO_OP, true, false);

// create networks including all necessary switches
List<LfNetwork> lfNetworks = securityAnalysis.createNetworks(allSwitchesToOpen, acParameters.getNetworkParameters());
List<LfNetwork> lfNetworks = securityAnalysis.createNetworks(allSwitchesToOpen, acParameters.getNetworkParameters(), Reporter.NO_OP);

// run simulation on each network
start = System.currentTimeMillis();
Expand Down
Loading

0 comments on commit 51b5c35

Please sign in to comment.