Skip to content

Commit

Permalink
Fix PTC action support and support of RTC action (#862)
Browse files Browse the repository at this point in the history
Signed-off-by: Hadrien <[email protected]>
Co-authored-by: Anne Tilloy <[email protected]>
Co-authored-by: Damien Jeandemange <[email protected]>
  • Loading branch information
3 people authored and geofjamg committed Oct 17, 2023
1 parent 18ecfc6 commit 875cd78
Show file tree
Hide file tree
Showing 23 changed files with 207 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import com.powsybl.openloadflow.ac.nr.NewtonRaphsonStatus;
import com.powsybl.openloadflow.lf.outerloop.OuterLoopStatus;
import com.powsybl.openloadflow.network.impl.LfNetworkList;
import com.powsybl.openloadflow.network.impl.LfTopoConfig;
import com.powsybl.openloadflow.network.LfTopoConfig;
import com.powsybl.openloadflow.network.impl.Networks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down
19 changes: 16 additions & 3 deletions src/main/java/com/powsybl/openloadflow/network/LfAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ public static Optional<LfAction> create(Action action, LfNetwork lfNetwork, Netw
case PhaseTapChangerTapPositionAction.NAME:
return create((PhaseTapChangerTapPositionAction) action, lfNetwork);

case RatioTapChangerTapPositionAction.NAME:
return create((RatioTapChangerTapPositionAction) action, lfNetwork);

case LoadAction.NAME:
return create((LoadAction) action, lfNetwork, network, breakers);

Expand Down Expand Up @@ -185,12 +188,22 @@ private static Optional<LfAction> create(LoadAction action, LfNetwork lfNetwork,
private static Optional<LfAction> create(PhaseTapChangerTapPositionAction action, LfNetwork lfNetwork) {
String branchId = action.getSide().map(side -> LfLegBranch.getId(side, action.getTransformerId())).orElseGet(action::getTransformerId);
LfBranch branch = lfNetwork.getBranchById(branchId);
return create(branch, action.getId(), action.isRelativeValue(), action.getTapPosition(), lfNetwork);
}

private static Optional<LfAction> create(RatioTapChangerTapPositionAction action, LfNetwork lfNetwork) {
String branchId = action.getSide().map(side -> LfLegBranch.getId(side, action.getTransformerId())).orElseGet(action::getTransformerId);
LfBranch branch = lfNetwork.getBranchById(branchId);
return create(branch, action.getId(), action.isRelativeValue(), action.getTapPosition(), lfNetwork);
}

private static Optional<LfAction> create(LfBranch branch, String actionId, boolean isRelative, int tapPosition, LfNetwork lfNetwork) {
if (branch != null) {
if (branch.getPiModel() instanceof SimplePiModel) {
throw new UnsupportedOperationException("Phase tap changer tap connection action: only one tap in branch " + branch.getId());
throw new UnsupportedOperationException("Tap position action: only one tap in branch " + branch.getId());
} else {
var tapPositionChange = new TapPositionChange(branch, action.getTapPosition(), action.isRelativeValue());
return Optional.of(new LfAction(action.getId(), null, null, tapPositionChange, null, null, null));
var tapPositionChange = new TapPositionChange(branch, tapPosition, isRelative);
return Optional.of(new LfAction(actionId, null, null, tapPositionChange, null, null, null));
}
}
return Optional.empty(); // could be in another component
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/com/powsybl/openloadflow/network/LfNetwork.java
Original file line number Diff line number Diff line change
Expand Up @@ -561,15 +561,15 @@ public static <T> List<LfNetwork> load(T network, LfNetworkLoader<T> networkLoad
return load(network, networkLoader, parameters, Reporter.NO_OP);
}

public static <T> List<LfNetwork> load(T network, LfNetworkLoader<T> networkLoader, SlackBusSelector slackBusSelector, Reporter reporter) {
return load(network, networkLoader, new LfNetworkParameters().setSlackBusSelector(slackBusSelector), reporter);
public static <T> List<LfNetwork> load(T network, LfNetworkLoader<T> networkLoader, LfNetworkParameters parameters, Reporter reporter) {
return load(network, networkLoader, new LfTopoConfig(), parameters, reporter);
}

public static <T> List<LfNetwork> load(T network, LfNetworkLoader<T> networkLoader, LfNetworkParameters parameters, Reporter reporter) {
public static <T> List<LfNetwork> load(T network, LfNetworkLoader<T> networkLoader, LfTopoConfig topoConfig, LfNetworkParameters parameters, Reporter reporter) {
Objects.requireNonNull(network);
Objects.requireNonNull(networkLoader);
Objects.requireNonNull(parameters);
List<LfNetwork> lfNetworks = networkLoader.load(network, parameters, reporter);
List<LfNetwork> lfNetworks = networkLoader.load(network, topoConfig, parameters, reporter);
for (LfNetwork lfNetwork : lfNetworks) {
Reporter reporterNetwork = Reports.createPostLoadingProcessingReporter(lfNetwork.getReporter());
lfNetwork.fix(parameters.isMinImpedance(), parameters.getLowImpedanceThreshold());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ public interface LfNetworkLoader<T> {
* components number (hence sorted by descending connected components size then by descending synchronous components
* size)
*/
List<LfNetwork> load(T network, LfNetworkParameters parameters, Reporter reporter);
List<LfNetwork> load(T network, LfTopoConfig topoConfig, LfNetworkParameters parameters, Reporter reporter);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* 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.impl;
package com.powsybl.openloadflow.network;

import com.powsybl.iidm.network.Switch;

Expand All @@ -22,6 +22,10 @@ public class LfTopoConfig {

private final Set<String> busIdsToLose = new HashSet<>();

private final Set<String> branchIdsWithPtcToRetain = new HashSet<>();

private final Set<String> branchIdsWithRtcToRetain = new HashSet<>();

public Set<Switch> getSwitchesToOpen() {
return switchesToOpen;
}
Expand All @@ -34,7 +38,23 @@ public Set<String> getBusIdsToLose() {
return busIdsToLose;
}

public void addBranchIdsWithPtcToRetain(String branchId) {
branchIdsWithPtcToRetain.add(branchId);
}

public void addBranchIdsWithRtcToRetain(String branchId) {
branchIdsWithRtcToRetain.add(branchId);
}

public boolean isBreaker() {
return !(switchesToOpen.isEmpty() && switchesToClose.isEmpty() && busIdsToLose.isEmpty());
}

public boolean isRetainedPtc(String branchId) {
return branchIdsWithPtcToRetain.contains(branchId);
}

public boolean isRetainedRtc(String branchId) {
return branchIdsWithRtcToRetain.contains(branchId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ private static LfBranchImpl createLine(Line line, LfNetwork network, LfBus bus1,
}

private static LfBranchImpl createTransformer(TwoWindingsTransformer twt, LfNetwork network, LfBus bus1, LfBus bus2,
LfNetworkParameters parameters) {
boolean retainPtc, boolean retainRtc, LfNetworkParameters parameters) {
PiModel piModel = null;

double baseRatio = Transformers.getRatioPerUnitBase(twt);
Expand All @@ -122,8 +122,8 @@ private static LfBranchImpl createTransformer(TwoWindingsTransformer twt, LfNetw

PhaseTapChanger ptc = twt.getPhaseTapChanger();
if (ptc != null
&& ptc.isRegulating()
&& ptc.getRegulationMode() != PhaseTapChanger.RegulationMode.FIXED_TAP) {
&& (ptc.isRegulating()
&& ptc.getRegulationMode() != PhaseTapChanger.RegulationMode.FIXED_TAP || retainPtc)) {
// we have a phase control, whatever we also have a voltage control or not, we create a pi model array
// based on phase taps mixed with voltage current tap
Integer rtcPosition = Transformers.getCurrentPosition(twt.getRatioTapChanger());
Expand All @@ -136,7 +136,7 @@ private static LfBranchImpl createTransformer(TwoWindingsTransformer twt, LfNetw
}

RatioTapChanger rtc = twt.getRatioTapChanger();
if (rtc != null && rtc.isRegulating() && rtc.hasLoadTapChangingCapabilities()) {
if (rtc != null && (rtc.isRegulating() && rtc.hasLoadTapChangingCapabilities() || retainRtc)) {
if (piModel == null) {
// we have a voltage control, we create a pi model array based on voltage taps mixed with phase current
// tap
Expand All @@ -162,14 +162,16 @@ private static LfBranchImpl createTransformer(TwoWindingsTransformer twt, LfNetw
return new LfBranchImpl(network, bus1, bus2, piModel, twt, parameters);
}

public static LfBranchImpl create(Branch<?> branch, LfNetwork network, LfBus bus1, LfBus bus2, LfNetworkParameters parameters) {
public static LfBranchImpl create(Branch<?> branch, LfNetwork network, LfBus bus1, LfBus bus2, LfTopoConfig topoConfig,
LfNetworkParameters parameters) {
Objects.requireNonNull(branch);
Objects.requireNonNull(network);
Objects.requireNonNull(parameters);
if (branch instanceof Line line) {
return createLine(line, network, bus1, bus2, parameters);
} else if (branch instanceof TwoWindingsTransformer twt) {
return createTransformer(twt, network, bus1, bus2, parameters);
return createTransformer(twt, network, bus1, bus2, topoConfig.isRetainedPtc(twt.getId()),
topoConfig.isRetainedRtc(twt.getId()), parameters);
} else {
throw new PowsyblException("Unsupported type of branch for flow equations of branch: " + branch.getId());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ private ThreeWindingsTransformer.Leg getLeg() {
return legRef.get();
}

public static LfLegBranch create(LfNetwork network, LfBus bus1, LfBus bus0, ThreeWindingsTransformer twt, ThreeWindingsTransformer.Leg leg,
LfNetworkParameters parameters) {
public static LfLegBranch create(LfNetwork network, LfBus bus1, LfBus bus0, ThreeWindingsTransformer twt,
ThreeWindingsTransformer.Leg leg, boolean retainPtc, boolean retainRtc, LfNetworkParameters parameters) {
Objects.requireNonNull(bus0);
Objects.requireNonNull(twt);
Objects.requireNonNull(leg);
Expand All @@ -52,8 +52,8 @@ public static LfLegBranch create(LfNetwork network, LfBus bus1, LfBus bus0, Thre
double baseRatio = Transformers.getRatioPerUnitBase(leg, twt);
PhaseTapChanger ptc = leg.getPhaseTapChanger();
if (ptc != null
&& ptc.isRegulating()
&& ptc.getRegulationMode() != PhaseTapChanger.RegulationMode.FIXED_TAP) {
&& (ptc.isRegulating()
&& ptc.getRegulationMode() != PhaseTapChanger.RegulationMode.FIXED_TAP || retainPtc)) {
// we have a phase control, whatever we also have a voltage control or not, we create a pi model array
// based on phase taps mixed with voltage current tap
Integer rtcPosition = Transformers.getCurrentPosition(leg.getRatioTapChanger());
Expand All @@ -66,7 +66,7 @@ public static LfLegBranch create(LfNetwork network, LfBus bus1, LfBus bus0, Thre
}

RatioTapChanger rtc = leg.getRatioTapChanger();
if (rtc != null && rtc.isRegulating() && rtc.hasLoadTapChangingCapabilities()) {
if (rtc != null && (rtc.isRegulating() && rtc.hasLoadTapChangingCapabilities() || retainRtc)) {
if (piModel == null) {
// we have a voltage control, we create a pi model array based on voltage taps mixed with phase current
// tap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,12 +360,13 @@ private static void addBranch(LfNetwork lfNetwork, LfBranch lfBranch, LfNetworkL
}
}

private static void createBranches(List<LfBus> lfBuses, LfNetwork lfNetwork, LoadingContext loadingContext, LfNetworkLoadingReport report,
LfNetworkParameters parameters, List<LfNetworkLoaderPostProcessor> postProcessors) {
private static void createBranches(List<LfBus> lfBuses, LfNetwork lfNetwork, LfTopoConfig topoConfig, LoadingContext loadingContext,
LfNetworkLoadingReport report, LfNetworkParameters parameters,
List<LfNetworkLoaderPostProcessor> postProcessors) {
for (Branch<?> branch : loadingContext.branchSet) {
LfBus lfBus1 = getLfBus(branch.getTerminal1(), lfNetwork, parameters.isBreakers());
LfBus lfBus2 = getLfBus(branch.getTerminal2(), lfNetwork, parameters.isBreakers());
LfBranchImpl lfBranch = LfBranchImpl.create(branch, lfNetwork, lfBus1, lfBus2, parameters);
LfBranchImpl lfBranch = LfBranchImpl.create(branch, lfNetwork, lfBus1, lfBus2, topoConfig, parameters);
addBranch(lfNetwork, lfBranch, report);
postProcessors.forEach(pp -> pp.onBranchAdded(branch, lfBranch));
}
Expand Down Expand Up @@ -393,27 +394,23 @@ private static void createBranches(List<LfBus> lfBuses, LfNetwork lfNetwork, Loa
pp.onBusAdded(danglingLine, lfBus2);
pp.onBranchAdded(danglingLine, lfBranch);
});
});
});
}

for (ThreeWindingsTransformer t3wt : loadingContext.t3wtSet) {
LfStarBus lfBus0 = new LfStarBus(lfNetwork, t3wt, parameters);
lfNetwork.addBus(lfBus0);
LfBus lfBus1 = getLfBus(t3wt.getLeg1().getTerminal(), lfNetwork, parameters.isBreakers());
LfBus lfBus2 = getLfBus(t3wt.getLeg2().getTerminal(), lfNetwork, parameters.isBreakers());
LfBus lfBus3 = getLfBus(t3wt.getLeg3().getTerminal(), lfNetwork, parameters.isBreakers());
LfLegBranch lfBranch1 = LfLegBranch.create(lfNetwork, lfBus1, lfBus0, t3wt, t3wt.getLeg1(), parameters);
LfLegBranch lfBranch2 = LfLegBranch.create(lfNetwork, lfBus2, lfBus0, t3wt, t3wt.getLeg2(), parameters);
LfLegBranch lfBranch3 = LfLegBranch.create(lfNetwork, lfBus3, lfBus0, t3wt, t3wt.getLeg3(), parameters);
addBranch(lfNetwork, lfBranch1, report);
addBranch(lfNetwork, lfBranch2, report);
addBranch(lfNetwork, lfBranch3, report);
postProcessors.forEach(pp -> {
pp.onBusAdded(t3wt, lfBus0);
pp.onBranchAdded(t3wt, lfBranch1);
pp.onBranchAdded(t3wt, lfBranch2);
pp.onBranchAdded(t3wt, lfBranch3);
});
postProcessors.forEach(pp -> pp.onBusAdded(t3wt, lfBus0));
for (ThreeWindingsTransformer.Side side : ThreeWindingsTransformer.Side.values()) {
ThreeWindingsTransformer.Leg leg = t3wt.getLeg(side);
LfBus lfBus = getLfBus(leg.getTerminal(), lfNetwork, parameters.isBreakers());
LfLegBranch lfBranch = LfLegBranch.create(lfNetwork, lfBus, lfBus0, t3wt, leg,
topoConfig.isRetainedPtc(LfLegBranch.getId(side, t3wt.getId())),
topoConfig.isRetainedRtc(LfLegBranch.getId(side, t3wt.getId())),
parameters);
addBranch(lfNetwork, lfBranch, report);
postProcessors.forEach(pp -> pp.onBranchAdded(t3wt, lfBranch));
}
}

if (parameters.isPhaseControl()) {
Expand Down Expand Up @@ -648,7 +645,7 @@ private static LfBus getLfBus(Terminal terminal, LfNetwork lfNetwork, boolean br
return bus != null ? lfNetwork.getBusById(bus.getId()) : null;
}

private LfNetwork create(int numCC, int numSC, Network network, List<Bus> buses, List<Switch> switches, LfNetworkParameters parameters, Reporter reporter) {
private LfNetwork create(int numCC, int numSC, Network network, List<Bus> buses, List<Switch> switches, LfTopoConfig topoConfig, LfNetworkParameters parameters, Reporter reporter) {
LfNetwork lfNetwork = new LfNetwork(numCC, numSC, parameters.getSlackBusSelector(), parameters.getMaxSlackBusCount(),
parameters.getConnectivityFactory(), reporter);

Expand All @@ -661,7 +658,7 @@ private LfNetwork create(int numCC, int numSC, Network network, List<Bus> buses,

List<LfBus> lfBuses = new ArrayList<>();
createBuses(buses, parameters, lfNetwork, lfBuses, loadingContext, report, postProcessors);
createBranches(lfBuses, lfNetwork, loadingContext, report, parameters, postProcessors);
createBranches(lfBuses, lfNetwork, topoConfig, loadingContext, report, parameters, postProcessors);

if (parameters.getLoadFlowModel() == LoadFlowModel.AC) {
createVoltageControls(lfBuses, parameters);
Expand Down Expand Up @@ -849,7 +846,7 @@ private static void createVoltageAngleLimits(Network network, LfNetwork lfNetwor
}

@Override
public List<LfNetwork> load(Network network, LfNetworkParameters parameters, Reporter reporter) {
public List<LfNetwork> load(Network network, LfTopoConfig topoConfig, LfNetworkParameters parameters, Reporter reporter) {
Objects.requireNonNull(network);
Objects.requireNonNull(parameters);

Expand Down Expand Up @@ -895,8 +892,8 @@ public List<LfNetwork> load(Network network, LfNetworkParameters parameters, Rep
int numCc = networkKey.getLeft();
int numSc = networkKey.getRight();
List<Bus> lfBuses = e.getValue();
return create(numCc, numSc, network, lfBuses, switchesByCc.get(networkKey), parameters,
Reports.createLfNetworkReporter(reporter, numCc, numSc));
return create(numCc, numSc, network, lfBuses, switchesByCc.get(networkKey), topoConfig,
parameters, Reports.createLfNetworkReporter(reporter, numCc, numSc));
})
.collect(Collectors.toList());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ public static List<LfNetwork> load(Network network, LfNetworkParameters paramete
return LfNetwork.load(network, new LfNetworkLoaderImpl(), parameters, reporter);
}

public static List<LfNetwork> load(Network network, LfTopoConfig topoConfig, LfNetworkParameters parameters, Reporter reporter) {
return LfNetwork.load(network, new LfNetworkLoaderImpl(), topoConfig, parameters, reporter);
}

private static void retainAndCloseNecessarySwitches(Network network, LfTopoConfig topoConfig) {
network.getSwitchStream()
.filter(sw -> sw.getVoltageLevel().getTopologyKind() == TopologyKind.NODE_BREAKER)
Expand Down Expand Up @@ -145,7 +149,7 @@ public static LfNetworkList load(Network network, LfNetworkParameters networkPar
public static LfNetworkList load(Network network, LfNetworkParameters networkParameters, LfTopoConfig topoConfig,
LfNetworkList.VariantCleanerFactory variantCleanerFactory, Reporter reporter) {
if (!topoConfig.isBreaker()) {
return new LfNetworkList(load(network, networkParameters, reporter));
return new LfNetworkList(load(network, topoConfig, networkParameters, reporter));
} else {
if (!networkParameters.isBreakers()) {
throw new PowsyblException("LF networks have to be built from bus/breaker view");
Expand All @@ -160,7 +164,7 @@ public static LfNetworkList load(Network network, LfNetworkParameters networkPar
// and close switches that could be closed during the simulation
retainAndCloseNecessarySwitches(network, topoConfig);

List<LfNetwork> lfNetworks = load(network, networkParameters, reporter);
List<LfNetwork> lfNetworks = load(network, topoConfig, networkParameters, reporter);

if (!topoConfig.getSwitchesToClose().isEmpty()) {
for (LfNetwork lfNetwork : lfNetworks) {
Expand Down
Loading

0 comments on commit 875cd78

Please sign in to comment.