Skip to content

Commit

Permalink
refactor dc outerloops creation + add active boolean to outerloops
Browse files Browse the repository at this point in the history
Signed-off-by: vmouradian <[email protected]>
  • Loading branch information
vmouradian committed Dec 6, 2024
1 parent 0c3d84f commit 5b602bd
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,14 @@ protected static Optional<AcOuterLoop> createAutomationSystemOuterLoop(OpenLoadF

static List<AcOuterLoop> filterInconsistentOuterLoops(List<AcOuterLoop> outerLoops) {
if (outerLoops.stream().anyMatch(AcAreaInterchangeControlOuterLoop.class::isInstance)) {
return outerLoops.stream().filter(o -> {
if (o instanceof DistributedSlackOuterLoop) {
LOGGER.warn("Distributed slack and area interchange control are both enabled. " +
"Distributed slack outer loop will be disabled, slack will be distributed by the area interchange control.");
return false;
}
return true;
}).toList();
outerLoops.stream()
.filter(DistributedSlackOuterLoop.class::isInstance)
.map(DistributedSlackOuterLoop.class::cast)
.forEach(distributedSlackOuterLoop -> {
LOGGER.warn("Distributed slack and area interchange control are both enabled. " +
"Distributed slack outer loop will be disabled, slack will be distributed by the area interchange control.");
distributedSlackOuterLoop.setActive(false);
});
}
return outerLoops;
}
Expand Down
23 changes: 21 additions & 2 deletions src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@
import com.powsybl.openloadflow.ac.solver.*;
import com.powsybl.openloadflow.ac.outerloop.AcOuterLoop;
import com.powsybl.openloadflow.ac.outerloop.ReactiveLimitsOuterLoop;
import com.powsybl.openloadflow.dc.DcAreaInterchangeControlOuterLoop;
import com.powsybl.openloadflow.dc.DcIncrementalPhaseControlOuterLoop;
import com.powsybl.openloadflow.dc.DcLoadFlowParameters;
import com.powsybl.openloadflow.dc.DcOuterLoop;
import com.powsybl.openloadflow.dc.DcValueVoltageInitializer;
import com.powsybl.openloadflow.dc.equations.DcApproximationType;
import com.powsybl.openloadflow.dc.equations.DcEquationSystemCreationParameters;
import com.powsybl.openloadflow.graph.GraphConnectivityFactory;
import com.powsybl.openloadflow.lf.AbstractLoadFlowParameters;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.network.util.ActivePowerDistribution;
import com.powsybl.openloadflow.network.util.PreviousValueVoltageInitializer;
import com.powsybl.openloadflow.network.util.UniformValueVoltageInitializer;
import com.powsybl.openloadflow.network.util.VoltageInitializer;
Expand Down Expand Up @@ -1816,7 +1820,7 @@ public static AcLoadFlowParameters createAcParameters(Network network, LoadFlowP
return acParameters;
}

static List<AcOuterLoop> createOuterLoops(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
static List<AcOuterLoop> createAcOuterLoops(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
AcOuterLoopConfig outerLoopConfig = AcOuterLoopConfig.findOuterLoopConfig()
.orElseGet(() -> parametersExt.getOuterLoopNames() != null ? new ExplicitAcOuterLoopConfig()
: new DefaultAcOuterLoopConfig());
Expand All @@ -1835,7 +1839,7 @@ public static AcLoadFlowParameters createAcParameters(LoadFlowParameters paramet

VoltageInitializer voltageInitializer = getExtendedVoltageInitializer(parameters, parametersExt, networkParameters, matrixFactory);

List<AcOuterLoop> outerLoops = createOuterLoops(parameters, parametersExt);
List<AcOuterLoop> outerLoops = createAcOuterLoops(parameters, parametersExt);

AcSolverFactory solverFactory = AcSolverFactory.find(parametersExt.getAcSolverType());

Expand All @@ -1851,6 +1855,20 @@ public static AcLoadFlowParameters createAcParameters(LoadFlowParameters paramet
.setSolverFactory(solverFactory, parameters);
}

static List<DcOuterLoop> createDcOuterLoops(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
List<DcOuterLoop> outerLoops = new ArrayList<>();
if (parameters.isPhaseShifterRegulationOn()) {
DcIncrementalPhaseControlOuterLoop phaseShifterControlOuterLoop = new DcIncrementalPhaseControlOuterLoop();
outerLoops.add(phaseShifterControlOuterLoop);
}
if (parametersExt.isAreaInterchangeControl()) {
ActivePowerDistribution activePowerDistribution = ActivePowerDistribution.create(parameters.getBalanceType(), false, parametersExt.isUseActiveLimits());
DcAreaInterchangeControlOuterLoop areaInterchangeControlOuterLoop = new DcAreaInterchangeControlOuterLoop(activePowerDistribution, parametersExt.getSlackBusPMaxMismatch(), parametersExt.getAreaInterchangePMaxMismatch());
outerLoops.add(areaInterchangeControlOuterLoop);
}
return outerLoops;
}

public static DcLoadFlowParameters createDcParameters(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
MatrixFactory matrixFactory, GraphConnectivityFactory<LfBus, LfBranch> connectivityFactory,
boolean forcePhaseControlOffAndAddAngle1Var) {
Expand Down Expand Up @@ -1914,6 +1932,7 @@ public static DcLoadFlowParameters createDcParameters(LoadFlowParameters paramet
.setAreaInterchangeControl(parametersExt.isAreaInterchangeControl())
.setBalanceType(parameters.getBalanceType())
.setSetVToNan(true)
.setOuterLoops(createDcOuterLoops(parameters, parametersExt))
.setMaxOuterLoopIterations(parametersExt.getMaxOuterLoopIterations())
.setSlackBusPMaxMismatch(parametersExt.getSlackBusPMaxMismatch())
.setAreaInterchangePMaxMismatch(parametersExt.getAreaInterchangePMaxMismatch());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ public AcLoadFlowResult run() {

List<AcOuterLoop> outerLoops = context.getParameters().getOuterLoops();
List<Pair<AcOuterLoop, AcOuterLoopContext>> outerLoopsAndContexts = outerLoops.stream()
.filter(AcOuterLoop::isActive)
.map(outerLoop -> Pair.of(outerLoop, new AcOuterLoopContext(context.getNetwork())))
.toList();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
/**
* @author Valentin Mouradian {@literal <valentin.mouradian at artelys.com>}
*/
public class DcAreaInterchangeControlControlOuterLoop extends AbstractAreaInterchangeControlOuterLoop<DcVariableType, DcEquationType, DcLoadFlowParameters, DcLoadFlowContext, DcOuterLoopContext> implements DcOuterLoop {
public class DcAreaInterchangeControlOuterLoop extends AbstractAreaInterchangeControlOuterLoop<DcVariableType, DcEquationType, DcLoadFlowParameters, DcLoadFlowContext, DcOuterLoopContext> implements DcOuterLoop {

private static final Logger LOGGER = LoggerFactory.getLogger(DcAreaInterchangeControlControlOuterLoop.class);
private static final Logger LOGGER = LoggerFactory.getLogger(DcAreaInterchangeControlOuterLoop.class);

protected DcAreaInterchangeControlControlOuterLoop(ActivePowerDistribution activePowerDistribution, double slackBusPMaxMismatch, double areaInterchangePMaxMismatch) {
public DcAreaInterchangeControlOuterLoop(ActivePowerDistribution activePowerDistribution, double slackBusPMaxMismatch, double areaInterchangePMaxMismatch) {
super(activePowerDistribution, null, slackBusPMaxMismatch, areaInterchangePMaxMismatch, LOGGER);
}

Expand Down
51 changes: 34 additions & 17 deletions src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.powsybl.openloadflow.dc.equations.DcVariableType;
import com.powsybl.openloadflow.equations.*;
import com.powsybl.openloadflow.lf.LoadFlowEngine;
import com.powsybl.openloadflow.lf.outerloop.OuterLoop;
import com.powsybl.openloadflow.lf.outerloop.OuterLoopResult;
import com.powsybl.openloadflow.lf.outerloop.OuterLoopStatus;
import com.powsybl.openloadflow.network.LfBus;
Expand All @@ -28,10 +29,10 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
Expand Down Expand Up @@ -181,30 +182,29 @@ public DcLoadFlowResult run() {
DcLoadFlowParameters parameters = context.getParameters();
TargetVector<DcVariableType, DcEquationType> targetVector = context.getTargetVector();
RunningContext runningContext = new RunningContext();
List<DcOuterLoop> outerLoops = parameters.getOuterLoops();

// outer loop initialization
List<Pair<DcOuterLoop, DcOuterLoopContext>> outerLoopsAndContexts = new ArrayList<>();
boolean distributedSlack = parameters.isDistributedSlack() || areaInterchangeControlFallback();

if (parameters.getNetworkParameters().isPhaseControl()) {
DcIncrementalPhaseControlOuterLoop phaseShifterControlOuterLoop = new DcIncrementalPhaseControlOuterLoop();
DcOuterLoopContext phaseShifterControlOuterLoopContext = new DcOuterLoopContext(network);
outerLoopsAndContexts.add(Pair.of(phaseShifterControlOuterLoop, phaseShifterControlOuterLoopContext));
phaseShifterControlOuterLoop.initialize(phaseShifterControlOuterLoopContext);
}
List<DcOuterLoop> activeOuterLoops = outerLoops.stream()
.filter(DcOuterLoop::isActive)
.toList();
List<Pair<DcOuterLoop, DcOuterLoopContext>> outerLoopsAndContexts = activeOuterLoops.stream()
.map(outerLoop -> Pair.of(outerLoop, new DcOuterLoopContext(context.getNetwork())))
.toList();

if (parameters.isAreaInterchangeControl() && network.hasArea()) {
ActivePowerDistribution activePowerDistribution = ActivePowerDistribution.create(parameters.getBalanceType(), false, parameters.getNetworkParameters().isUseActiveLimits());
DcAreaInterchangeControlControlOuterLoop areaInterchangeControlOuterLoop = new DcAreaInterchangeControlControlOuterLoop(activePowerDistribution, parameters.getSlackBusPMaxMismatch(), parameters.getAreaInterchangePMaxMismatch());
DcOuterLoopContext areaInterchangeControlOuterLoopContext = new DcOuterLoopContext(network);
outerLoopsAndContexts.add(Pair.of(areaInterchangeControlOuterLoop, areaInterchangeControlOuterLoopContext));
areaInterchangeControlOuterLoop.initialize(areaInterchangeControlOuterLoopContext);
// outer loops initialization
for (var outerLoopAndContext : outerLoopsAndContexts) {
var outerLoop = outerLoopAndContext.getLeft();
var outerLoopContext = outerLoopAndContext.getRight();
outerLoop.initialize(outerLoopContext);
}

initStateVector(network, equationSystem, new UniformValueVoltageInitializer());

double initialSlackBusActivePowerMismatch = getActivePowerMismatch(network.getBuses());
double distributedActivePower = 0.0;
if (parameters.isDistributedSlack() || parameters.isAreaInterchangeControl()) {
if (distributedSlack) {
// FIXME handle distribution failure
distributedActivePower = distributeSlack(network, network.getBuses(), parameters.getBalanceType(), parameters.getNetworkParameters().isUseActiveLimits());
}
Expand Down Expand Up @@ -248,7 +248,7 @@ public DcLoadFlowResult run() {
for (var outerLoopAndContext : Lists.reverse(outerLoopsAndContexts)) {
var outerLoop = outerLoopAndContext.getLeft();
var outerLoopContext = outerLoopAndContext.getRight();
if (outerLoop instanceof DcAreaInterchangeControlControlOuterLoop activePowerDistributionOuterLoop) {
if (outerLoop instanceof DcAreaInterchangeControlOuterLoop activePowerDistributionOuterLoop) {
distributedActivePower += activePowerDistributionOuterLoop.getDistributedActivePower(outerLoopContext);
}
outerLoop.cleanup(outerLoopContext);
Expand Down Expand Up @@ -297,4 +297,21 @@ public static <T> List<DcLoadFlowResult> run(T network, LfNetworkLoader<T> netwo
.toList();
}

/**
* If Area Interchange Control is activated but the network has no area, we fall back to distributed slack
*/
boolean areaInterchangeControlFallback() {
List<DcOuterLoop> outerLoops = context.getParameters().getOuterLoops();
Optional<DcAreaInterchangeControlOuterLoop> aicOuterLoop = outerLoops.stream()
.filter(DcAreaInterchangeControlOuterLoop.class::isInstance)
.filter(OuterLoop::isActive)
.map(DcAreaInterchangeControlOuterLoop.class::cast)
.findFirst();
if (aicOuterLoop.isPresent() && !context.getNetwork().hasArea()) {
aicOuterLoop.get().setActive(false);
return true;
}
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import com.powsybl.openloadflow.dc.equations.DcEquationSystemCreationParameters;
import com.powsybl.openloadflow.lf.AbstractLoadFlowParameters;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
Expand All @@ -28,6 +30,7 @@ public class DcLoadFlowParameters extends AbstractLoadFlowParameters<DcLoadFlowP
private LoadFlowParameters.BalanceType balanceType = LoadFlowParameters.DEFAULT_BALANCE_TYPE;

private boolean setVToNan = false;
protected List<DcOuterLoop> outerLoops = Collections.emptyList();

private int maxOuterLoopIterations = DEFAULT_MAX_OUTER_LOOP_ITERATIONS;

Expand Down Expand Up @@ -89,6 +92,15 @@ public DcLoadFlowParameters setSetVToNan(boolean setVToNan) {
return this;
}

public List<DcOuterLoop> getOuterLoops() {
return outerLoops;
}

public DcLoadFlowParameters setOuterLoops(List<DcOuterLoop> outerLoops) {
this.outerLoops = Objects.requireNonNull(outerLoops);
return this;
}

public double getSlackBusPMaxMismatch() {
return slackBusPMaxMismatch;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ public abstract class AbstractActivePowerDistributionOuterLoop<V extends Enum<V>
O extends OuterLoopContext<V, E, P, C>>
implements ActivePowerDistributionOuterLoop<V, E, P, C, O> {

boolean active = true;

@Override
public boolean isActive() {
return active;
}

public void setActive(boolean active) {
this.active = active;
}

@Override
public double getDistributedActivePower(O context) {
var contextData = context.getData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public abstract class AbstractAreaInterchangeControlOuterLoop<
C extends LoadFlowContext<V, E, P>,
O extends AbstractOuterLoopContext<V, E, P, C>>
extends AbstractActivePowerDistributionOuterLoop<V, E, P, C, O>
implements OuterLoop<V, E, P, C, O>, ActivePowerDistributionOuterLoop<V, E, P, C, O> {
implements ActivePowerDistributionOuterLoop<V, E, P, C, O> {

private final Logger logger;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,8 @@ default void initialize(O context) {

default void cleanup(O context) {
}

default boolean isActive() {
return true;
}
}
Loading

0 comments on commit 5b602bd

Please sign in to comment.