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 reports in LfNetworkLoaderImpl #1020

Merged
merged 9 commits into from
May 16, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ private static void checkUniqueTargetVControlledBus(double controllerTargetV, Lf
LOGGER.error("Bus '{}' control voltage of bus '{}' which is already controlled by buses '{}' with a different target voltage: {} (kept) and {} (ignored)",
controllerBus.getId(), controlledBus.getId(), busesId, controllerTargetV * controlledBus.getNominalV(),
voltageControlTargetV * controlledBus.getNominalV());
Reports.reportBusAlreadyControlledWithDifferentTargetV(controllerBus.getNetwork().getReportNode(), controllerBus.getId(), controlledBus.getId(), busesId, controllerTargetV * controlledBus.getNominalV(),
voltageControlTargetV * controlledBus.getNominalV());
}
}

Expand All @@ -211,6 +213,7 @@ private static void checkUniqueTargetVControllerBus(LfGenerator lfGenerator, dou
String generatorIds = controllerBus.getGenerators().stream().map(LfGenerator::getId).collect(Collectors.joining(", "));
LOGGER.error("Generators [{}] are connected to the same bus '{}' with different target voltages: {} (kept) and {} (rejected)",
generatorIds, controllerBus.getId(), previousTargetV * controlledBus.getNominalV(), targetV * controlledBus.getNominalV());
Reports.reportNotUniqueTargetVControllerBus(controllerBus.getNetwork().getReportNode(), generatorIds, controllerBus.getId(), previousTargetV * controlledBus.getNominalV(), targetV * controlledBus.getNominalV());
}
}

Expand Down Expand Up @@ -290,6 +293,8 @@ private static boolean checkUniqueControlledSide(GeneratorReactivePowerControl g
if (!side.equals(generatorReactivePowerControl.getControlledSide())) {
LOGGER.error("Controlled branch '{}' is controlled at both sides. Controlled side {} (kept) {} (rejected).",
generatorReactivePowerControl.getControlledBranch().getId(), generatorReactivePowerControl.getControlledSide(), side);
Reports.reportBranchControlledAtBothSides(generatorReactivePowerControl.getControlledBranch().getNetwork().getReportNode(),
generatorReactivePowerControl.getControlledBranch().getId(), generatorReactivePowerControl.getControlledSide().name(), side.name());
return false;
}
return true;
Expand Down Expand Up @@ -713,6 +718,7 @@ private static void createShuntVoltageControl(LfNetwork lfNetwork, ShuntCompensa
// number of variables. We have only one B variable for more than one bus target V equations.
if (!controllerShunt.getVoltageControl().orElseThrow().getControlledBus().getId().equals(controlledBus.getId())) {
LOGGER.error("Controller shunt {} is already in a shunt voltage control. The second controlled bus {} is ignored", controllerShunt.getId(), controlledBus.getId());
Reports.reportControllerShuntAlreadyInVoltageControl(controllerBus.getNetwork().getReportNode(), controllerShunt.getId(), controlledBus.getId());
}
return;
}
Expand Down
42 changes: 42 additions & 0 deletions src/main/java/com/powsybl/openloadflow/util/Reports.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,48 @@ public static void reportNetworkBalance(ReportNode reportNode, double activeGene
.add();
}

public static void reportNotUniqueTargetVControllerBus(ReportNode reportNode, String generatorIds, String controllerBusId, Double keptTargetV, Double rejectedTargetV) {
reportNode.newReportNode()
.withMessageTemplate("notUniqueTargetVControllerBus", "Generators [${generatorIds}] are connected to the same bus ${controllerBusId} with different target voltages: ${keptTargetV} kV (kept) and ${rejectedTargetV} kV (rejected)")
.withTypedValue("generatorIds", generatorIds, "Generator ids")
.withTypedValue("controllerBusId", controllerBusId, "Controller bus id")
.withTypedValue("keptTargetV", keptTargetV, "Kept target V")
.withTypedValue("rejectedTargetV", rejectedTargetV, "Rejected target V")
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
}

public static void reportControllerShuntAlreadyInVoltageControl(ReportNode reportNode, String controllerShuntId, String controlledBusId) {
reportNode.newReportNode()
.withMessageTemplate("controllerShuntAlreadyInVoltageControl", "Controller shunt ${controllerShuntId} is already in a shunt voltage control. The second controlled bus ${controlledBusId} is ignored")
.withTypedValue("controllerShuntId", controllerShuntId, "Controller shunt id")
.withTypedValue("controlledBusId", controlledBusId, "Controlled bus id")
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
}

public static void reportBusAlreadyControlledWithDifferentTargetV(ReportNode reportNode, String controllerBusId, String controlledBusId, String busesId, Double keptTargetV, Double ignoredTargetV) {
reportNode.newReportNode()
.withMessageTemplate("busAlreadyControlledWithDifferentTargetV", "Bus ${controllerBusId} controls voltage of bus ${controlledBusId} which is already controlled by buses [${busesId}] with a different target voltage: ${keptTargetV} kV (kept) and ${ignoredTargetV} kV (ignored)")
.withTypedValue("controllerBusId", controllerBusId, "Controller bus id")
.withTypedValue("controlledBusId", controlledBusId, "Controlled bus id")
.withTypedValue("busesId", busesId, "Buses id")
.withTypedValue("keptTargetV", keptTargetV, "Kept target V")
.withTypedValue("ignoredTargetV", ignoredTargetV, "Ignored target V")
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
}

public static void reportBranchControlledAtBothSides(ReportNode reportNode, String controlledBranchId, String keptSide, String rejectedSide) {
reportNode.newReportNode()
.withMessageTemplate("branchControlledAtBothSides", "Controlled branch ${controlledBranchId} is controlled at both sides. Controlled side ${keptSide} (kept) side ${rejectedSide} (rejected).")
.withTypedValue("controlledBranchId", controlledBranchId, "Controlled branch id")
.withTypedValue("keptSide", keptSide, "Kept side")
.withTypedValue("rejectedSide", rejectedSide, "Rejected side")
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
}

public static void reportNetworkMustHaveAtLeastOneBusGeneratorVoltageControlEnabled(ReportNode reportNode) {
reportNode.newReportNode()
.withMessageTemplate("networkMustHaveAtLeastOneBusGeneratorVoltageControlEnabled", "Network must have at least one bus with generator voltage control enabled")
Expand Down
13 changes: 11 additions & 2 deletions src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
*/
package com.powsybl.openloadflow.ac;

import com.powsybl.commons.report.ReportNode;
import com.powsybl.computation.local.LocalComputationManager;
import com.powsybl.iidm.network.*;
import com.powsybl.loadflow.LoadFlow;
import com.powsybl.loadflow.LoadFlowParameters;
Expand All @@ -15,9 +17,12 @@
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.OpenLoadFlowProvider;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.util.LoadFlowAssert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;

import static com.powsybl.openloadflow.util.LoadFlowAssert.*;
import static org.junit.jupiter.api.Assertions.*;

Expand Down Expand Up @@ -324,7 +329,7 @@ void testNoShuntVoltageControl3() {
}

@Test
void testUnsupportedSharedVoltageControl() {
void testUnsupportedSharedVoltageControl() throws IOException {
// in that test case, we test two shunts connected to the same bus, both are in voltage regulation
// but with a different regulating terminal.
ShuntCompensator shunt2 = network.getVoltageLevel("vl3").newShuntCompensator()
Expand All @@ -349,11 +354,15 @@ void testUnsupportedSharedVoltageControl() {
.add();

parameters.setShuntCompensatorVoltageControlOn(true);
LoadFlowResult result = loadFlowRunner.run(network, parameters);
ReportNode reportNode = ReportNode.newRootReportNode()
.withMessageTemplate("testReport", "Test Report")
.build();
LoadFlowResult result = loadFlowRunner.run(network, network.getVariantManager().getWorkingVariantId(), LocalComputationManager.getDefault(), parameters, reportNode);
assertTrue(result.isFullyConverged());
assertVoltageEquals(391.640, bus3);
assertEquals(1, shunt.getSectionCount());
assertEquals(2, shunt2.getSectionCount());
LoadFlowAssert.assertReportEquals("/controllerShuntAlreadyInVoltageControlReport.txt", reportNode);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
*/
package com.powsybl.openloadflow.ac;

import com.powsybl.commons.report.ReportNode;
import com.powsybl.computation.local.LocalComputationManager;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.CoordinatedReactiveControlAdder;
import com.powsybl.iidm.network.extensions.RemoteReactivePowerControl;
Expand All @@ -21,9 +23,12 @@
import com.powsybl.openloadflow.ac.solver.NewtonRaphsonStoppingCriteriaType;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.network.impl.LfNetworkLoaderImpl;
import com.powsybl.openloadflow.util.LoadFlowAssert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;

import static com.powsybl.openloadflow.util.LoadFlowAssert.*;
import static org.junit.jupiter.api.Assertions.*;

Expand Down Expand Up @@ -453,7 +458,7 @@ void testDiscardedGeneratorRemoteReactivePowerControls() {
}

@Test
void testSharedGeneratorRemoteReactivePowerControl() {
void testSharedGeneratorRemoteReactivePowerControl() throws IOException {
// we create a basic 4-buses network
Network network = FourBusNetworkFactory.createBaseNetwork();
Bus b1 = network.getBusBreakerView().getBus("b1");
Expand Down Expand Up @@ -498,11 +503,15 @@ void testSharedGeneratorRemoteReactivePowerControl() {
.withEnabled(true).add();

parametersExt.setGeneratorReactivePowerRemoteControl(true);
LoadFlowResult result2 = loadFlowRunner.run(network, parameters);
ReportNode reportNode = ReportNode.newRootReportNode()
.withMessageTemplate("testReport", "Test Report")
.build();
LoadFlowResult result2 = loadFlowRunner.run(network, VariantManagerConstants.INITIAL_VARIANT_ID, LocalComputationManager.getDefault(), parameters, reportNode);
assertTrue(result2.isFullyConverged());
assertReactivePowerEquals(1, l34.getTerminal(TwoSides.TWO));
assertEquals(0.0, Math.abs(b1.getConnectedTerminalStream().mapToDouble(Terminal::getQ).sum()), DELTA_POWER);
assertEquals(0.0, Math.abs(b4.getConnectedTerminalStream().mapToDouble(Terminal::getQ).sum()), DELTA_POWER);
LoadFlowAssert.assertReportEquals("/sharedGeneratorRemoteReactivePowerControlReport.txt", reportNode);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
*/
package com.powsybl.openloadflow.ac;

import com.powsybl.commons.report.ReportNode;
import com.powsybl.iidm.network.*;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.network.impl.Networks;
import com.powsybl.openloadflow.util.LoadFlowAssert;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

Expand All @@ -23,7 +26,7 @@
class GeneratorTargetVoltageInconsistencyTest {

@Test
void localTest() {
void localTest() throws IOException {
Network network = Network.create("generatorLocalInconsistentTargetVoltage", "code");
Substation s = network.newSubstation()
.setId("s")
Expand Down Expand Up @@ -85,7 +88,12 @@ void localTest() {
.setX(1)
.add();

List<LfNetwork> lfNetworks = Networks.load(network, new FirstSlackBusSelector());
LfNetworkParameters lfNetworkParameters = new LfNetworkParameters()
.setSlackBusSelector(new FirstSlackBusSelector());
ReportNode reportNode = ReportNode.newRootReportNode()
.withMessageTemplate("testReport", "Test Report")
.build();
List<LfNetwork> lfNetworks = Networks.load(network, lfNetworkParameters, reportNode);
assertEquals(1, lfNetworks.size());

LfNetwork lfNetwork = lfNetworks.get(0);
Expand All @@ -95,6 +103,7 @@ void localTest() {
Optional<GeneratorVoltageControl> vc = controlledBus.getGeneratorVoltageControl();
assertTrue(vc.isPresent());
assertEquals(23, vc.get().getTargetValue() * controlledBus.getNominalV());
LoadFlowAssert.assertReportEquals("/notUniqueTargetVControllerBusReport.txt", reportNode);
}

@Test
Expand Down Expand Up @@ -195,7 +204,7 @@ void remoteTest() {
}

@Test
void remoteAndLocalTest() {
void remoteAndLocalTest() throws IOException {
Network network = Network.create("generatorRemoteAndLocalInconsistentTargetVoltage", "code");
Substation s = network.newSubstation()
.setId("s")
Expand Down Expand Up @@ -283,12 +292,15 @@ void remoteAndLocalTest() {

assertEquals(412, network.getGenerator("g1").getTargetV());
assertEquals(413, g2.getTargetV());

List<LfNetwork> networkList = Networks.load(network, parameters);
ReportNode reportNode = ReportNode.newRootReportNode()
.withMessageTemplate("testReport", "Test Report")
.build();
List<LfNetwork> networkList = Networks.load(network, parameters, reportNode);
LfNetwork mainNetwork = networkList.get(0);
Optional<GeneratorVoltageControl> sharedVoltageControl = mainNetwork.getBusById("vl2_0").getGeneratorVoltageControl();
assertTrue(sharedVoltageControl.isPresent());

assertEquals(413 / g2.getTerminal().getVoltageLevel().getNominalV(), sharedVoltageControl.get().getTargetValue());
LoadFlowAssert.assertReportEquals("/busAlreadyControlledWithDifferentTargetVReport.txt", reportNode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
+ Test Report
+ Network CC0 SC0
Bus vl1_0 controls voltage of bus vl2_0 which is already controlled by buses [vl2_0, vl1_0] with a different target voltage: 412.0 kV (kept) and 413.0 kV (ignored)
+ Network info
Network has 3 buses and 2 branches
Network balance: active generation=200.0 MW, active load=99.9 MW, reactive generation=0.0 MVar, reactive load=80.0 MVar
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
+ Test Report
+ Load flow on network 'svc'
+ Network CC0 SC0
Controller shunt vl3_0_controller_shunt_compensators is already in a shunt voltage control. The second controlled bus vl2_0 is ignored
+ Network info
Network has 3 buses and 2 branches
Network balance: active generation=101.36639999999998 MW, active load=101.0 MW, reactive generation=0.0 MVar, reactive load=150.0 MVar
Outer loop DistributedSlack
Outer loop VoltageMonitoring
Outer loop ReactiveLimits
Outer loop ShuntVoltageControl
Outer loop DistributedSlack
Outer loop VoltageMonitoring
Outer loop ReactiveLimits
Outer loop ShuntVoltageControl
AC load flow completed successfully (solverStatus=CONVERGED, outerloopStatus=STABLE)
6 changes: 6 additions & 0 deletions src/test/resources/notUniqueTargetVControllerBusReport.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
+ Test Report
+ Network CC0 SC0
Generators [g1, g2] are connected to the same bus vl1_0 with different target voltages: 23.0 kV (kept) and 22.0 kV (rejected)
+ Network info
Network has 2 buses and 1 branches
Network balance: active generation=200.0 MW, active load=99.9 MW, reactive generation=0.0 MVar, reactive load=80.0 MVar
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
+ Test Report
+ Load flow on network 'test'
+ Network CC0 SC0
Controlled branch l34 is controlled at both sides. Controlled side TWO (kept) side ONE (rejected).
+ Network info
Network has 4 buses and 5 branches
Network balance: active generation=3.0 MW, active load=5.0 MW, reactive generation=0.0 MVar, reactive load=0.0 MVar
Outer loop VoltageMonitoring
AC load flow completed successfully (solverStatus=CONVERGED, outerloopStatus=STABLE)