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

[WIP] SA : Reconfigure power distribution per contingency using an extension #1156

Open
wants to merge 7 commits into
base: feature/contingency-parameters-extension
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.openloadflow.ac.outerloop.*;
import com.powsybl.openloadflow.network.util.ActivePowerDistribution;
import com.powsybl.openloadflow.util.PerUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -29,16 +28,16 @@ protected AbstractAcOuterLoopConfig() {

protected static Optional<AcOuterLoop> createDistributedSlackOuterLoop(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
if (parameters.isDistributedSlack()) {
ActivePowerDistribution activePowerDistribution = ActivePowerDistribution.create(parameters.getBalanceType(), parametersExt.isLoadPowerFactorConstant(), parametersExt.isUseActiveLimits());
return Optional.of(new DistributedSlackOuterLoop(activePowerDistribution, parametersExt.getSlackBusPMaxMismatch()));
return Optional.of(DistributedSlackOuterLoop.create(parameters.getBalanceType(), parametersExt.isLoadPowerFactorConstant(), parametersExt.isUseActiveLimits(),
parametersExt.getSlackBusPMaxMismatch()));
}
return Optional.empty();
}

protected static Optional<AcOuterLoop> createAreaInterchangeControlOuterLoop(LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt) {
if (parametersExt.isAreaInterchangeControl()) {
ActivePowerDistribution activePowerDistribution = ActivePowerDistribution.create(parameters.getBalanceType(), parametersExt.isLoadPowerFactorConstant(), parametersExt.isUseActiveLimits());
return Optional.of(new AcAreaInterchangeControlOuterLoop(activePowerDistribution, parametersExt.getSlackBusPMaxMismatch(), parametersExt.getAreaInterchangePMaxMismatch()));
return Optional.of(AcAreaInterchangeControlOuterLoop.create(parameters.getBalanceType(), parametersExt.isLoadPowerFactorConstant(), parametersExt.isUseActiveLimits(),
parametersExt.getSlackBusPMaxMismatch(), parametersExt.getAreaInterchangePMaxMismatch()));
}
return Optional.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
package com.powsybl.openloadflow.ac.outerloop;

import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.openloadflow.ac.AcLoadFlowContext;
import com.powsybl.openloadflow.ac.AcLoadFlowParameters;
import com.powsybl.openloadflow.ac.AcOuterLoopContext;
Expand All @@ -32,6 +33,12 @@ public AcAreaInterchangeControlOuterLoop(ActivePowerDistribution activePowerDist
super(activePowerDistribution, new DistributedSlackOuterLoop(activePowerDistribution, slackBusPMaxMismatch), slackBusPMaxMismatch, areaInterchangePMaxMismatch, LOGGER);
}

public static AcAreaInterchangeControlOuterLoop create(LoadFlowParameters.BalanceType balanceType, boolean loadPowerFactorConstant, boolean useActiveLimits,
double slackBusPMaxMismatch, double areaInterchangePMaxMismatch) {
ActivePowerDistribution activePowerDistribution = ActivePowerDistribution.create(balanceType, loadPowerFactorConstant, useActiveLimits);
return new AcAreaInterchangeControlOuterLoop(activePowerDistribution, slackBusPMaxMismatch, areaInterchangePMaxMismatch);
}

@Override
public String getName() {
return NAME;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.powsybl.openloadflow.ac.outerloop;

import com.powsybl.commons.report.ReportNode;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.openloadflow.ac.AcLoadFlowContext;
import com.powsybl.openloadflow.ac.AcLoadFlowParameters;
import com.powsybl.openloadflow.ac.AcOuterLoopContext;
Expand Down Expand Up @@ -45,6 +46,12 @@ public DistributedSlackOuterLoop(ActivePowerDistribution activePowerDistribution
this.slackBusPMaxMismatch = slackBusPMaxMismatch;
}

public static DistributedSlackOuterLoop create(LoadFlowParameters.BalanceType balanceType, boolean loadPowerFactorConstant, boolean useActiveLimits,
double slackBusPMaxMismatch) {
ActivePowerDistribution activePowerDistribution = ActivePowerDistribution.create(balanceType, loadPowerFactorConstant, useActiveLimits);
return new DistributedSlackOuterLoop(activePowerDistribution, slackBusPMaxMismatch);
}

@Override
public String getName() {
return NAME;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
package com.powsybl.openloadflow.dc;

import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.openloadflow.dc.equations.DcEquationType;
import com.powsybl.openloadflow.dc.equations.DcVariableType;
import com.powsybl.openloadflow.lf.outerloop.AbstractAreaInterchangeControlOuterLoop;
Expand All @@ -28,6 +29,12 @@ public DcAreaInterchangeControlOuterLoop(ActivePowerDistribution activePowerDist
super(activePowerDistribution, null, slackBusPMaxMismatch, areaInterchangePMaxMismatch, LOGGER);
}

public static DcAreaInterchangeControlOuterLoop create(LoadFlowParameters.BalanceType balanceType, boolean loadPowerFactorConstant, boolean useActiveLimits,
double slackBusPMaxMismatch, double areaInterchangePMaxMismatch) {
ActivePowerDistribution activePowerDistribution = ActivePowerDistribution.create(balanceType, loadPowerFactorConstant, useActiveLimits);
return new DcAreaInterchangeControlOuterLoop(activePowerDistribution, slackBusPMaxMismatch, areaInterchangePMaxMismatch);
}

@Override
public String getName() {
return "AreaInterchangeControl";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,19 +515,17 @@ private static void createBranches(List<LfBus> lfBuses, LfNetwork lfNetwork, LfT
}

private static void updateArea(Bus bus, LfBus lfBus, LfNetworkParameters parameters, LoadingContext loadingContext) {
if (parameters.isAreaInterchangeControl()) {
// Consider only the area type that should be used for area interchange control
Optional<Area> areaOpt = bus.getVoltageLevel().getArea(parameters.getAreaInterchangeControlAreaType());
areaOpt.ifPresent(area ->
loadingContext.areaBusMap.computeIfAbsent(area, k -> {
area.getAreaBoundaryStream().forEach(boundary -> {
boundary.getTerminal().ifPresent(t -> loadingContext.areaTerminalMap.put(t, area));
boundary.getBoundary().ifPresent(b -> loadingContext.areaTerminalMap.put(b.getDanglingLine().getTerminal(), area));
});
return new HashSet<>();
}).add(lfBus)
);
}
// Consider only the area type that should be used for area interchange control
Optional<Area> areaOpt = bus.getVoltageLevel().getArea(parameters.getAreaInterchangeControlAreaType());
areaOpt.ifPresent(area ->
loadingContext.areaBusMap.computeIfAbsent(area, k -> {
area.getAreaBoundaryStream().forEach(boundary -> {
boundary.getTerminal().ifPresent(t -> loadingContext.areaTerminalMap.put(t, area));
boundary.getBoundary().ifPresent(b -> loadingContext.areaTerminalMap.put(b.getDanglingLine().getTerminal(), area));
});
return new HashSet<>();
}).add(lfBus)
);
}

/**
Expand Down Expand Up @@ -556,36 +554,34 @@ private static void addAreaBoundary(Terminal terminal, LfBranch branch, TwoSides
}

private static void createAreas(LfNetwork network, LoadingContext loadingContext, List<LfNetworkLoaderPostProcessor> postProcessors, LfNetworkParameters parameters) {
if (parameters.isAreaInterchangeControl()) {
loadingContext.areaBusMap
.entrySet()
.stream()
.filter(e -> {
if (e.getKey().getAreaBoundaryStream().findAny().isEmpty()) {
Reports.reportAreaNoInterchangeControl(network.getReportNode(), e.getKey().getId(), "Area does not have any area boundary");
LOGGER.warn("Network {}: Area {} does not have any area boundary. The area will not be considered for area interchange control", network, e.getKey().getId());
return false;
}
return true;
})
.filter(e -> {
if (e.getKey().getInterchangeTarget().isEmpty()) {
Reports.reportAreaNoInterchangeControl(network.getReportNode(), e.getKey().getId(), "Area does not have an interchange target");
LOGGER.warn("Network {}: Area {} does not have an interchange target. The area will not be considered for area interchange control", network, e.getKey().getId());
return false;
}
return true;
})
.filter(e -> checkBoundariesComponent(network, e.getKey()))
.forEach(e -> {
Area area = e.getKey();
Set<LfBus> lfBuses = e.getValue();
Set<LfArea.Boundary> boundaries = loadingContext.areaBoundaries.getOrDefault(area, new HashSet<>());
LfArea lfArea = LfAreaImpl.create(area, lfBuses, boundaries, network, parameters);
network.addArea(lfArea);
postProcessors.forEach(pp -> pp.onAreaAdded(area, lfArea));
});
}
loadingContext.areaBusMap
.entrySet()
.stream()
.filter(e -> {
if (e.getKey().getAreaBoundaryStream().findAny().isEmpty()) {
Reports.reportAreaNoInterchangeControl(network.getReportNode(), e.getKey().getId(), "Area does not have any area boundary");
LOGGER.warn("Network {}: Area {} does not have any area boundary. The area will not be considered for area interchange control", network, e.getKey().getId());
return false;
}
return true;
})
.filter(e -> {
if (e.getKey().getInterchangeTarget().isEmpty()) {
Reports.reportAreaNoInterchangeControl(network.getReportNode(), e.getKey().getId(), "Area does not have an interchange target");
LOGGER.warn("Network {}: Area {} does not have an interchange target. The area will not be considered for area interchange control", network, e.getKey().getId());
return false;
}
return true;
})
.filter(e -> checkBoundariesComponent(network, e.getKey()))
.forEach(e -> {
Area area = e.getKey();
Set<LfBus> lfBuses = e.getValue();
Set<LfArea.Boundary> boundaries = loadingContext.areaBoundaries.getOrDefault(area, new HashSet<>());
LfArea lfArea = LfAreaImpl.create(area, lfBuses, boundaries, network, parameters);
network.addArea(lfArea);
postProcessors.forEach(pp -> pp.onAreaAdded(area, lfArea));
});
}

private static boolean checkBoundariesComponent(LfNetwork network, Area area) {
Expand Down
Loading
Loading