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

Refactor discrete voltage control #413

Merged
merged 44 commits into from
Jan 12, 2022
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6b9cd7e
Element disabling notification
geofjamg Nov 8, 2021
eff37b8
Fix
geofjamg Nov 8, 2021
f5142d5
Refactoring
geofjamg Nov 8, 2021
064d1a7
Renaming
geofjamg Nov 8, 2021
793eeb5
Merge branch 'main' into disable_notif
geofjamg Nov 8, 2021
c5144cb
Merge
geofjamg Nov 8, 2021
8c84b28
Refactor bus/branch state
geofjamg Nov 8, 2021
a3a6929
Fix branche state
geofjamg Nov 8, 2021
a4d1293
Cleanup
geofjamg Nov 9, 2021
3dab170
Refactoring
geofjamg Nov 9, 2021
3210211
Refactoring
geofjamg Nov 9, 2021
4676db6
Refactoring
geofjamg Nov 10, 2021
613fce0
Refactoring
geofjamg Nov 10, 2021
d3ab1c7
Fix
geofjamg Nov 10, 2021
4ac5cfe
Cleanup
geofjamg Nov 10, 2021
ab055d4
Merge branch 'main' into disable_notif
geofjamg Nov 10, 2021
14dae46
Refactor discrete voltage control
geofjamg Jan 5, 2022
20658be
Refactor shunt voltage control
geofjamg Jan 5, 2022
75f6543
Cleanup
geofjamg Jan 5, 2022
049da92
Add some tests.
annetill Jan 6, 2022
84843c6
Merge branch 'main' into refactor_discrete_voltage_control
geofjamg Jan 6, 2022
360b542
Merge
geofjamg Jan 6, 2022
0ae127f
Merge branch 'main' into disable_notif
geofjamg Jan 6, 2022
a79d21f
Try to fix SA
geofjamg Jan 6, 2022
1e865bd
Merge branch 'disable_notif' into refactor_discrete_voltage_control
geofjamg Jan 6, 2022
0c7a454
Fix SA
geofjamg Jan 6, 2022
440d49a
Add assertions.
annetill Jan 7, 2022
fd65610
Fix tests.
annetill Jan 7, 2022
d64c1fa
Merge branch 'main' into refactor_discrete_voltage_control
geofjamg Jan 10, 2022
25cff4d
Fix merge
geofjamg Jan 10, 2022
ed0a2c3
Fix security analysis with voltage controls.
annetill Jan 10, 2022
fbbc424
Fix after review.
annetill Jan 10, 2022
2959c7e
Fix
geofjamg Jan 10, 2022
a503da8
Fix
geofjamg Jan 10, 2022
4e63cd0
Fix KLU issue
geofjamg Jan 10, 2022
82d38d9
Merge branch 'main' into refactor_discrete_voltage_control
annetill Jan 11, 2022
cbd20b0
Fix update in case of local voltage control.
annetill Jan 11, 2022
e01d7fc
Try to improve unit tests.
annetill Jan 11, 2022
1ca5b62
Fix tests.
annetill Jan 11, 2022
8d21add
Cleanup
geofjamg Jan 11, 2022
34784a3
Cleanup
geofjamg Jan 11, 2022
3bce6f6
Cleanup
geofjamg Jan 11, 2022
9912269
Remove TODO.
annetill Jan 12, 2022
750180d
Fix AS.
annetill Jan 12, 2022
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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ private void updateVoltageControl(VoltageControl voltageControl) {
// we only support one controlling static var compensator without any other controlling generators
// we don't support controller bus that wants to control back voltage with slope.
if (!firstControllerBus.isVoltageControlEnabled()) {
equationSystem.createEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V_WITH_SLOPE).setActive(false);
equationSystem.getEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V_WITH_SLOPE)
.orElseThrow().setActive(false);
}
} else {
if (voltageControl.isVoltageControlLocal()) {
Expand All @@ -47,7 +48,8 @@ private void updateVoltageControl(VoltageControl voltageControl) {

private void updateVoltageControl(LfBus controllerBus, boolean newVoltageControllerEnabled) {
// active/de-activate bus target reactive power equation to switch bus PV or PQ
equationSystem.createEquation(controllerBus.getNum(), AcEquationType.BUS_TARGET_Q)
equationSystem.getEquation(controllerBus.getNum(), AcEquationType.BUS_TARGET_Q)
.orElseThrow()
.setActive(!newVoltageControllerEnabled);

updateVoltageControl(controllerBus.getVoltageControl().orElseThrow());
Expand All @@ -62,11 +64,13 @@ private void updateDiscretePhaseControl(DiscretePhaseControl phaseControl, Discr
boolean on = newMode != DiscretePhaseControl.Mode.OFF;

// activate/de-activate phase control equation
equationSystem.createEquation(phaseControl.getControlled().getNum(), AcEquationType.BRANCH_TARGET_P)
equationSystem.getEquation(phaseControl.getControlled().getNum(), AcEquationType.BRANCH_TARGET_P)
.orElseThrow()
.setActive(on);

// de-activate/activate constant A1 equation
equationSystem.createEquation(phaseControl.getController().getNum(), AcEquationType.BRANCH_TARGET_ALPHA1)
equationSystem.getEquation(phaseControl.getController().getNum(), AcEquationType.BRANCH_TARGET_ALPHA1)
.orElseThrow()
.setActive(!on);
}

Expand All @@ -75,81 +79,26 @@ public void onDiscretePhaseControlModeChange(DiscretePhaseControl phaseControl,
updateDiscretePhaseControl(phaseControl, newMode);
}

private void updateTransformerVoltageControl(TransformerVoltageControl voltageControl, DiscreteVoltageControl.Mode newMode) {
LfBus controlledBus = voltageControl.getControlled();
if (newMode == DiscreteVoltageControl.Mode.OFF) {

// de-activate transformer voltage control equation
equationSystem.createEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V)
.setActive(false);

for (LfBranch controllerBranch : voltageControl.getControllers()) {
// activate constant R1 equation
equationSystem.createEquation(controllerBranch.getNum(), AcEquationType.BRANCH_TARGET_RHO1)
.setActive(true);

// clean transformer distribution equations
equationSystem.removeEquation(controllerBranch.getNum(), AcEquationType.DISTR_RHO);
}
} else { // newMode == DiscreteVoltageControl.Mode.VOLTAGE

// activate transformer voltage control equation
equationSystem.createEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V)
.setActive(true);

// add transformer distribution equations
AcEquationSystem.createR1DistributionEquations(voltageControl.getControllers(), equationSystem);

for (LfBranch controllerBranch : voltageControl.getControllers()) {
// de-activate constant R1 equation
equationSystem.createEquation(controllerBranch.getNum(), AcEquationType.BRANCH_TARGET_RHO1)
.setActive(false);
}
}
}

private void updateShuntVoltageControl(ShuntVoltageControl voltageControl, DiscreteVoltageControl.Mode newMode) {
LfBus controlledBus = voltageControl.getControlled();
if (newMode == DiscreteVoltageControl.Mode.OFF) {

// de-activate transformer or shunt voltage control equation
equationSystem.createEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V)
.setActive(false);

for (LfBus controllerBus : voltageControl.getControllers()) {
controllerBus.getControllerShunt().ifPresent(shunt -> {
// activate constant B equation
equationSystem.createEquation(shunt.getNum(), AcEquationType.SHUNT_TARGET_B)
.setActive(true);

// clean shunt distribution equations
equationSystem.removeEquation(shunt.getNum(), AcEquationType.DISTR_B);
});
}
} else { // newMode == DiscreteVoltageControl.Mode.VOLTAGE

// de-activate transformer or shunt voltage control equation
equationSystem.createEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V)
.setActive(false);

// add shunt distribution equations
AcEquationSystem.createBDistributionEquations(voltageControl.getControllers(), equationSystem);

for (LfBus controllerBus : voltageControl.getControllers()) {
controllerBus.getControllerShunt().ifPresent(shunt ->
// de-activate constant B equation
equationSystem.createEquation(shunt.getNum(), AcEquationType.BRANCH_TARGET_RHO1)
.setActive(false));
}
}
}

@Override
public void onDiscreteVoltageControlModeChange(DiscreteVoltageControl voltageControl, DiscreteVoltageControl.Mode newMode) {
if (voltageControl instanceof TransformerVoltageControl) {
updateTransformerVoltageControl((TransformerVoltageControl) voltageControl, newMode);
AcEquationSystem.updateTransformerVoltageControlEquations((TransformerVoltageControl) voltageControl, equationSystem);
} else if (voltageControl instanceof ShuntVoltageControl) {
updateShuntVoltageControl((ShuntVoltageControl) voltageControl, newMode);
AcEquationSystem.updateShuntVoltageControlEquations((ShuntVoltageControl) voltageControl, equationSystem);
}
}

@Override
public void onDisableChange(LfElement element, boolean disabled) {
if (element.getType() == ElementType.BUS) {
LfBus bus = (LfBus) element;
bus.getVoltageControl().ifPresent(this::updateVoltageControl);
bus.getTransformerVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateTransformerVoltageControlEquations(voltageControl, equationSystem));
bus.getShuntVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateShuntVoltageControlEquations(voltageControl, equationSystem));
} else if (element.getType() == ElementType.BRANCH) {
LfBranch branch = (LfBranch) element;
branch.getTransformerVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateTransformerVoltageControlEquations(voltageControl, equationSystem));
// TODO phase control.
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public enum AcEquationType implements Quantity {
ZERO_V("zero_v", ElementType.BRANCH), // zero impedance branch, voltage magnitude equality
ZERO_PHI("zero_\u03C6", ElementType.BRANCH), // zero impedance branch, voltage angle equality
DISTR_RHO("distr_\u03C1", ElementType.BRANCH), // remote transformer voltage control ratio distribution
DISTR_B("distr_b", ElementType.SHUNT_COMPENSATOR); // remote transformer voltage control ratio distribution
DISTR_SHUNT_B("distr_b", ElementType.SHUNT_COMPENSATOR); // shunt remote voltage control susceptance distribution

private final String symbol;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,6 @@ private static double getReactivePowerDistributionTarget(LfNetwork network, int
return target;
}

private static double getRho1DistributionTarget(LfNetwork network, int num, DistributionData data) {
LfBranch controllerBranch = network.getBranch(num);
LfBranch firstControllerBranch = network.getBranch(data.getFirstControllerElementNum());
// as a first and very simple ratio distribution strategy, we keep the gap between the 2 ratios constant
return controllerBranch.getPiModel().getR1() - firstControllerBranch.getPiModel().getR1();
}

private static double getBDistributionTarget(LfNetwork network, int num, DistributionData data) {
LfShunt controllerShunt = network.getShunt(num);
LfShunt firstControllerShunt = network.getShunt(data.getFirstControllerElementNum());
// as a first and very simple B distribution strategy, we keep the gap between the 2 B constant
return controllerShunt.getB() - firstControllerShunt.getB();
}

private static double createBusWithSlopeTarget(LfBus bus) {
// take first generator with slope: network loading ensures that there's only one generator with slope
double slope = bus.getGeneratorsControllingVoltageWithSlope().get(0).getSlope();
Expand Down Expand Up @@ -220,11 +206,8 @@ public static void initTarget(Equation<AcVariableType, AcEquationType> equation,
break;

case DISTR_RHO:
targets[equation.getColumn()] = getRho1DistributionTarget(network, equation.getElementNum(), equation.getData());
break;

case DISTR_B:
targets[equation.getColumn()] = getBDistributionTarget(network, equation.getElementNum(), equation.getData());
case DISTR_SHUNT_B:
targets[equation.getColumn()] = 0;
break;

default:
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/com/powsybl/openloadflow/equations/EquationUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import com.powsybl.openloadflow.network.ElementType;
import com.powsybl.openloadflow.network.LfBranch;
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.network.LfShunt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

Expand Down Expand Up @@ -64,6 +66,27 @@ public static <V extends Enum<V> & Quantity, E extends Enum<E> & Quantity> void
deactivatedEquationTerms.add(equationTerm);
}
}

List<LfShunt> shunts = new ArrayList<>(2);
bus.getShunt().ifPresent(shunts::add);
bus.getControllerShunt().ifPresent(shunts::add);
for (LfShunt shunt : shunts) {
// deactivate all equations related to a shunt
for (Equation<V, E> equation : equationSystem.getEquations(ElementType.SHUNT_COMPENSATOR, shunt.getNum())) {
if (equation.isActive()) {
equation.setActive(false);
deactivatedEquations.add(equation);
}
}

// deactivate all equation terms related to a shunt
for (EquationTerm<V, E> equationTerm : equationSystem.getEquationTerms(ElementType.SHUNT_COMPENSATOR, shunt.getNum())) {
if (equationTerm.isActive()) {
equationTerm.setActive(false);
deactivatedEquationTerms.add(equationTerm);
}
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/**
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
*/
public abstract class AbstractElement {
public abstract class AbstractElement implements LfElement {

protected final LfNetwork network;

Expand All @@ -38,7 +38,12 @@ public boolean isDisabled() {
}

public void setDisabled(boolean disabled) {
this.disabled = disabled;
if (disabled != this.disabled) {
this.disabled = disabled;
for (LfNetworkListener listener : network.getListeners()) {
listener.onDisableChange(this, disabled);
}
}
}

public LfNetwork getNetwork() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,9 @@ public void onGenerationReactivePowerTargetChange(LfBus bus, double oldGeneratio
public void onDiscretePhaseControlTapPositionChange(PiModel piModel, int oldPosition, int newPosition) {
// empty
}

@Override
public void onDisableChange(LfElement element, boolean disabled) {
// empty
}
}
36 changes: 36 additions & 0 deletions src/main/java/com/powsybl/openloadflow/network/BusModeState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) 2021, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.powsybl.openloadflow.network;

/**
* @author Anne Tilloy <anne.tilloy at rte-france.com>
*/
public class BusModeState extends ElementState<LfBus> {

private final DiscreteVoltageControl.Mode transformerVoltageControlMode;
private final DiscreteVoltageControl.Mode shuntVoltageControlMode;

public BusModeState(LfBus bus) {
super(bus);
transformerVoltageControlMode = bus.getTransformerVoltageControl().map(TransformerVoltageControl::getMode).orElse(null);
shuntVoltageControlMode = bus.getShuntVoltageControl().map(ShuntVoltageControl::getMode).orElse(null);
}

@Override
public void restore() {
if (transformerVoltageControlMode != null) {
element.getTransformerVoltageControl().ifPresent(control -> control.setMode(transformerVoltageControlMode));
}
if (shuntVoltageControlMode != null) {
element.getShuntVoltageControl().ifPresent(control -> control.setMode(shuntVoltageControlMode));
}
}

public static BusModeState save(LfBus bus) {
return new BusModeState(bus);
}
}
10 changes: 0 additions & 10 deletions src/main/java/com/powsybl/openloadflow/network/BusState.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ public class BusState extends BusDcState {
private final double loadTargetQ;
private final double generationTargetQ;
private final boolean voltageControlEnabled;
private final DiscreteVoltageControl.Mode transformerVoltageControlMode;
private final DiscreteVoltageControl.Mode shuntVoltageControlMode;
private final boolean disabled;

public BusState(LfBus bus) {
Expand All @@ -27,8 +25,6 @@ public BusState(LfBus bus) {
this.loadTargetQ = bus.getLoadTargetQ();
this.generationTargetQ = bus.getGenerationTargetQ();
this.voltageControlEnabled = bus.isVoltageControlEnabled();
transformerVoltageControlMode = bus.getTransformerVoltageControl().map(TransformerVoltageControl::getMode).orElse(null);
shuntVoltageControlMode = bus.getShuntVoltageControl().map(ShuntVoltageControl::getMode).orElse(null);
this.disabled = bus.isDisabled();
}

Expand All @@ -41,12 +37,6 @@ public void restore() {
element.setGenerationTargetQ(generationTargetQ);
element.setVoltageControlEnabled(voltageControlEnabled);
element.setVoltageControlSwitchOffCount(0);
if (transformerVoltageControlMode != null) {
element.getTransformerVoltageControl().ifPresent(control -> control.setMode(transformerVoltageControlMode));
}
if (shuntVoltageControlMode != null) {
element.getShuntVoltageControl().ifPresent(control -> control.setMode(shuntVoltageControlMode));
}
element.setDisabled(disabled);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ public interface LfNetworkListener {
void onGenerationReactivePowerTargetChange(LfBus bus, double oldGenerationTargetQ, double newGenerationTargetQ);

void onDiscretePhaseControlTapPositionChange(PiModel piModel, int oldPosition, int newPosition);

void onDisableChange(LfElement element, boolean disabled);
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void updateReactiveKeys() {
// no reactive dispatch on PQ buses, so we set the key to 0
for (int i = 0; i < controllerBuses.size(); i++) {
LfBus controllerBus = controllerBuses.get(i);
if (!controllerBus.isVoltageControlEnabled()) {
if (controllerBus.isDisabled() || !controllerBus.isVoltageControlEnabled()) {
reactiveKeys[i] = 0d;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ private void roundBToClosestSection(double b, Controller controller) {
smallestDistance = distance;
}
}
LOGGER.info("Round B shift of shunt '{}': {} -> {}", controller.getId(), b, controller.getB());
LOGGER.trace("Round B shift of shunt '{}': {} -> {}", controller.getId(), b, controller.getB());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List<Propagated
List<BranchResult> preContingencyBranchResults = new ArrayList<>();
List<BusResults> preContingencyBusResults = new ArrayList<>();
List<ThreeWindingsTransformerResult> preContingencyThreeWindingsTransformerResults = new ArrayList<>();
List<BranchState> branchStates = ElementState.save(network.getBranches(), BranchState::save);
List<BusModeState> busModeStates = ElementState.save(network.getBuses(), BusModeState::save);

// run pre-contingency simulation
try (AcloadFlowEngine engine = new AcloadFlowEngine(network, acParameters)) {
Expand All @@ -133,7 +135,6 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List<Propagated

// save base state for later restoration after each contingency
List<BusState> busStates = ElementState.save(network.getBuses(), BusState::save);
List<BranchState> branchStates = ElementState.save(network.getBranches(), BranchState::save);
for (LfBus bus : network.getBuses()) {
bus.setVoltageControlSwitchOffCount(0);
}
Expand All @@ -145,12 +146,12 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List<Propagated
PropagatedContingency propagatedContingency = contingencyIt.next();
LfContingency.create(propagatedContingency, network, connectivity, true)
.ifPresent(lfContingency -> { // only process contingencies that impact the network
for (LfBus bus : lfContingency.getBuses()) {
bus.setDisabled(true);
}
for (LfBranch branch : lfContingency.getBranches()) {
branch.setDisabled(true);
}
for (LfBus bus : lfContingency.getBuses()) {
bus.setDisabled(true);
}

distributedMismatch(network, lfContingency.getActivePowerLoss(), loadFlowParameters, openLoadFlowParameters);

Expand All @@ -162,6 +163,7 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List<Propagated

// restore base state
ElementState.restore(busStates);
ElementState.restore(busModeStates);
ElementState.restore(branchStates);
}
});
Expand Down
Loading