Skip to content
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
10 changes: 5 additions & 5 deletions src/main/java/com/powsybl/openloadflow/OpenLoadFlowProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ private void updateAcState(Network network, LoadFlowParameters parameters, OpenL
result.getNetwork().updateState(updateParameters);

// zero or low impedance branch flows computation
computeZeroImpedanceFlows(result.getNetwork(), LoadFlowModel.AC);
computeZeroImpedanceFlows(result.getNetwork(), LoadFlowModel.AC, parameters.getDcPowerFactor());
}
} finally {
if (parametersExt.isNetworkCacheEnabled()) {
Expand Down Expand Up @@ -197,10 +197,10 @@ private static ReferenceBusAndSlackBusesResults buildReferenceBusAndSlackBusesRe
private record ReferenceBusAndSlackBusesResults(String referenceBusId, List<LoadFlowResult.SlackBusResult> slackBusResultList) {
}

private void computeZeroImpedanceFlows(LfNetwork network, LoadFlowModel loadFlowModel) {
private void computeZeroImpedanceFlows(LfNetwork network, LoadFlowModel loadFlowModel, double dcPowerFactor) {
for (LfZeroImpedanceNetwork zeroImpedanceNetwork : network.getZeroImpedanceNetworks(loadFlowModel)) {
new ZeroImpedanceFlows(zeroImpedanceNetwork.getGraph(), zeroImpedanceNetwork.getSpanningTree(), loadFlowModel)
.compute();
new ZeroImpedanceFlows(zeroImpedanceNetwork.getGraph(), zeroImpedanceNetwork.getSpanningTree(), loadFlowModel, dcPowerFactor)
.computeWithFlowsUpdate();
}
}

Expand Down Expand Up @@ -240,7 +240,7 @@ private LoadFlowResult.ComponentResult processResult(Network network, DcLoadFlow
result.getNetwork().updateState(updateParameters);

// zero or low impedance branch flows computation
computeZeroImpedanceFlows(result.getNetwork(), LoadFlowModel.DC);
computeZeroImpedanceFlows(result.getNetwork(), LoadFlowModel.DC, parameters.getDcPowerFactor());
}

var referenceBusAndSlackBusesResults = buildReferenceBusAndSlackBusesResults(result);
Expand Down
12 changes: 7 additions & 5 deletions src/main/java/com/powsybl/openloadflow/network/LfBranch.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@
import com.powsybl.openloadflow.util.Evaluable;
import com.powsybl.security.results.BranchResult;

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

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
Expand All @@ -38,6 +35,9 @@ enum BranchType {
TIE_LINE
}

record LfBranchResults(double p1, double p2, double q1, double q2, double i1, double i2) {
}

class LfLimit {

private final String name;
Expand Down Expand Up @@ -261,7 +261,9 @@ default List<LfLimit> getLimits2(LimitType type, LimitReductionManager limitRedu

boolean isTransformerReactivePowerControlled();

List<BranchResult> createBranchResult(double preContingencyBranchP1, double preContingencyBranchOfContingencyP1, boolean createExtension);
List<BranchResult> createBranchResult(double preContingencyBranchP1, double preContingencyBranchOfContingencyP1,
boolean createExtension, Map<String, LfBranchResults> zeroImpedanceFlows,
LoadFlowModel loadFlowModel);

double computeApparentPower1();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.util.Evaluable;
import com.powsybl.openloadflow.util.PerUnit;
import com.powsybl.security.results.BranchResult;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.powsybl.openloadflow.util.EvaluableConstants.NAN;
Expand Down Expand Up @@ -498,4 +501,27 @@ protected double getAngle1() {
protected double getAngle2() {
return getBus2() != null ? getBus2().getAngle() : Double.NaN;
}

protected LfBranchResults getImpedantLfBranchResults() {
return new LfBranchResults(p1.eval(), p2.eval(), q1.eval(), q2.eval(), i1.eval(), i2.eval());
}

protected BranchResult buildBranchResult(LoadFlowModel loadFlowModel, Map<String, LfBranchResults> zeroImpedanceFlows, double currentScale1, double currentScale2,
double preContingencyBranchP1, double preContingencyBranchOfContingencyP1) {
LfBranchResults lfBranchResults = this.isZeroImpedance(loadFlowModel) ? zeroImpedanceFlows.get(this.getId())
: getImpedantLfBranchResults();

double flowP1 = lfBranchResults.p1() * PerUnit.SB;
double flowQ1 = lfBranchResults.q1() * PerUnit.SB;
double flowP2 = lfBranchResults.p2() * PerUnit.SB;
double flowQ2 = lfBranchResults.q2() * PerUnit.SB;
double currentI1 = lfBranchResults.i1() * currentScale1;
double currentI2 = lfBranchResults.i2() * currentScale2;

double flowTransfer = Double.NaN;
if (!Double.isNaN(preContingencyBranchP1) && !Double.isNaN(preContingencyBranchOfContingencyP1)) {
flowTransfer = (flowP1 - preContingencyBranchP1) / preContingencyBranchOfContingencyP1;
}
return new BranchResult(getId(), flowP1, flowQ1, currentI1, flowP2, flowQ2, currentI2, flowTransfer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -210,16 +210,14 @@ public boolean hasPhaseControllerCapability() {
}

@Override
public List<BranchResult> createBranchResult(double preContingencyBranchP1, double preContingencyBranchOfContingencyP1, boolean createExtension) {
public List<BranchResult> createBranchResult(double preContingencyBranchP1, double preContingencyBranchOfContingencyP1,
boolean createExtension, Map<String, LfBranch.LfBranchResults> zeroImpedanceFlows,
LoadFlowModel loadFlowModel) {
var branch = getBranch();
double flowTransfer = Double.NaN;
if (!Double.isNaN(preContingencyBranchP1) && !Double.isNaN(preContingencyBranchOfContingencyP1)) {
flowTransfer = (p1.eval() * PerUnit.SB - preContingencyBranchP1) / preContingencyBranchOfContingencyP1;
}
double currentScale1 = PerUnit.ib(branch.getTerminal1().getVoltageLevel().getNominalV());
double currentScale2 = PerUnit.ib(branch.getTerminal2().getVoltageLevel().getNominalV());
var branchResult = new BranchResult(getId(), p1.eval() * PerUnit.SB, q1.eval() * PerUnit.SB, currentScale1 * i1.eval(),
p2.eval() * PerUnit.SB, q2.eval() * PerUnit.SB, currentScale2 * i2.eval(), flowTransfer);

var branchResult = buildBranchResult(loadFlowModel, zeroImpedanceFlows, currentScale1, currentScale2, preContingencyBranchP1, preContingencyBranchOfContingencyP1);
if (createExtension) {
branchResult.addExtension(OlfBranchResult.class, new OlfBranchResult(piModel.getR1(), piModel.getContinuousR1(),
getV1() * branch.getTerminal1().getVoltageLevel().getNominalV(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.powsybl.security.results.BranchResult;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
Expand Down Expand Up @@ -70,12 +71,13 @@ public boolean hasPhaseControllerCapability() {
}

@Override
public List<BranchResult> createBranchResult(double preContingencyBranchP1, double preContingencyBranchOfContingencyP1, boolean createExtension) {
public List<BranchResult> createBranchResult(double preContingencyBranchP1, double preContingencyBranchOfContingencyP1,
boolean createExtension, Map<String, LfBranchResults> zeroImpedanceFlows,
LoadFlowModel loadFlowModel) {
// in a security analysis, we don't have any way to monitor the flows at boundary side. So in the branch result,
// we follow the convention side 1 for network side and side 2 for boundary side.
double currentScale = PerUnit.ib(getDanglingLine().getTerminal().getVoltageLevel().getNominalV());
return List.of(new BranchResult(getId(), p1.eval() * PerUnit.SB, q1.eval() * PerUnit.SB, currentScale * i1.eval(),
p2.eval() * PerUnit.SB, q2.eval() * PerUnit.SB, currentScale * i2.eval(), Double.NaN));
return List.of(buildBranchResult(loadFlowModel, zeroImpedanceFlows, currentScale, currentScale, Double.NaN, Double.NaN));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ private LfLegBranch(LfNetwork network, LfBus bus1, LfBus bus0, PiModel piModel,
this.legRef = Ref.create(leg, parameters.isCacheEnabled());
}

private ThreeWindingsTransformer getTwt() {
public ThreeWindingsTransformer getTwt() {
return twtRef.get();
}

Expand Down Expand Up @@ -139,7 +139,9 @@ public boolean hasPhaseControllerCapability() {
}

@Override
public List<BranchResult> createBranchResult(double preContingencyBranchP1, double preContingencyBranchOfContingencyP1, boolean createExtension) {
public List<BranchResult> createBranchResult(double preContingencyBranchP1, double preContingencyBranchOfContingencyP1,
boolean createExtension, Map<String, LfBranch.LfBranchResults> zeroImpedanceFlows,
LoadFlowModel loadFlowModel) {
throw new PowsyblException("Unsupported type of branch for branch result: " + getId());
}

Expand Down Expand Up @@ -201,18 +203,39 @@ public void updateFlows(double p1, double q1, double p2, double q2) {
.setQ(q1 * PerUnit.SB);
}

public static ThreeWindingsTransformerResult createThreeWindingsTransformerResult(LfNetwork network, String threeWindingsTransformerId, boolean createResultExtension) {
private static LfBranchResults extractLegBranchResults(LfLegBranch leg) {
return new LfBranchResults(leg.p1.eval(), Double.NaN, leg.q1.eval(), Double.NaN, leg.i1.eval(), Double.NaN);
}

public static ThreeWindingsTransformerResult createThreeWindingsTransformerResult(LfNetwork network, String threeWindingsTransformerId, boolean createResultExtension,
Map<String, LfBranch.LfBranchResults> zeroImpedanceFlows, LoadFlowModel loadFlowModel) {
LfLegBranch leg1 = (LfLegBranch) network.getBranchById(LfLegBranch.getId(threeWindingsTransformerId, 1));
LfLegBranch leg2 = (LfLegBranch) network.getBranchById(LfLegBranch.getId(threeWindingsTransformerId, 2));
LfLegBranch leg3 = (LfLegBranch) network.getBranchById(LfLegBranch.getId(threeWindingsTransformerId, 3));

double i1Base = PerUnit.ib(leg1.legRef.get().getTerminal().getVoltageLevel().getNominalV());
double i2Base = PerUnit.ib(leg2.legRef.get().getTerminal().getVoltageLevel().getNominalV());
double i3Base = PerUnit.ib(leg3.legRef.get().getTerminal().getVoltageLevel().getNominalV());

LfBranchResults legBranchResults1 = leg1.isZeroImpedance(loadFlowModel) ? zeroImpedanceFlows.get(leg1.getId())
: extractLegBranchResults(leg1);
LfBranchResults legBranchResults2 = leg2.isZeroImpedance(loadFlowModel) ? zeroImpedanceFlows.get(leg2.getId())
: extractLegBranchResults(leg2);
LfBranchResults legBranchResults3 = leg3.isZeroImpedance(loadFlowModel) ? zeroImpedanceFlows.get(leg3.getId())
: extractLegBranchResults(leg3);

double flowP1 = legBranchResults1.p1() * PerUnit.SB;
double flowP2 = legBranchResults2.p1() * PerUnit.SB;
double flowP3 = legBranchResults3.p1() * PerUnit.SB;
double flowQ1 = legBranchResults1.q1() * PerUnit.SB;
double flowQ2 = legBranchResults2.q1() * PerUnit.SB;
double flowQ3 = legBranchResults3.q1() * PerUnit.SB;
double currentI1 = legBranchResults1.i1() * i1Base;
double currentI2 = legBranchResults2.i1() * i2Base;
double currentI3 = legBranchResults3.i1() * i3Base;

ThreeWindingsTransformerResult result = new ThreeWindingsTransformerResult(threeWindingsTransformerId,
leg1.getP1().eval() * PerUnit.SB, leg1.getQ1().eval() * PerUnit.SB, leg1.getI1().eval() * i1Base,
leg2.getP1().eval() * PerUnit.SB, leg2.getQ1().eval() * PerUnit.SB, leg2.getI1().eval() * i2Base,
leg3.getP1().eval() * PerUnit.SB, leg3.getQ1().eval() * PerUnit.SB, leg3.getI1().eval() * i3Base);
flowP1, flowQ1, currentI1, flowP2, flowQ2, currentI2, flowP3, flowQ3, currentI3);

if (createResultExtension) {
result.addExtension(OlfThreeWindingsTransformerResult.class, new OlfThreeWindingsTransformerResult(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

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

import static com.powsybl.openloadflow.util.EvaluableConstants.NAN;
Expand Down Expand Up @@ -359,7 +360,9 @@ public List<Evaluable> getAdditionalClosedQ2() {
}

@Override
public List<BranchResult> createBranchResult(double preContingencyBranchP1, double preContingencyBranchOfContingencyP1, boolean createExtension) {
public List<BranchResult> createBranchResult(double preContingencyBranchP1, double preContingencyBranchOfContingencyP1,
boolean createExtension, Map<String, LfBranchResults> zeroImpedanceFlows,
LoadFlowModel loadFlowModel) {
throw new PowsyblException("Unsupported type of branch for branch result: " + getSwitch().getId());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.powsybl.security.results.BranchResult;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
Expand Down Expand Up @@ -75,21 +76,18 @@ public DanglingLine getHalf2() {
}

@Override
public List<BranchResult> createBranchResult(double preContingencyBranchP1, double preContingencyBranchOfContingencyP1, boolean createExtension) {
double flowTransfer = Double.NaN;
if (!Double.isNaN(preContingencyBranchP1) && !Double.isNaN(preContingencyBranchOfContingencyP1)) {
flowTransfer = (p1.eval() * PerUnit.SB - preContingencyBranchP1) / preContingencyBranchOfContingencyP1;
}
public List<BranchResult> createBranchResult(double preContingencyBranchP1, double preContingencyBranchOfContingencyP1,
boolean createExtension, Map<String, LfBranchResults> zeroImpedanceFlows,
LoadFlowModel loadFlowModel) {
double nominalV1 = getHalf1().getTerminal().getVoltageLevel().getNominalV();
double nominalV2 = getHalf2().getTerminal().getVoltageLevel().getNominalV();
double currentScale1 = PerUnit.ib(nominalV1);
double currentScale2 = PerUnit.ib(nominalV2);
var branchResult = new BranchResult(getId(), p1.eval() * PerUnit.SB, q1.eval() * PerUnit.SB, currentScale1 * i1.eval(),
p2.eval() * PerUnit.SB, q2.eval() * PerUnit.SB, currentScale2 * i2.eval(), flowTransfer);
var half1Result = new BranchResult(getHalf1().getId(), p1.eval() * PerUnit.SB, q1.eval() * PerUnit.SB, currentScale1 * i1.eval(),
Double.NaN, Double.NaN, Double.NaN, flowTransfer);
var half2Result = new BranchResult(getHalf2().getId(), p2.eval() * PerUnit.SB, q2.eval() * PerUnit.SB, currentScale2 * i2.eval(),
Double.NaN, Double.NaN, Double.NaN, flowTransfer);

var branchResult = buildBranchResult(loadFlowModel, zeroImpedanceFlows, currentScale1, currentScale2, preContingencyBranchP1, preContingencyBranchOfContingencyP1);

var half1Result = new BranchResult(getHalf1().getId(), branchResult.getP1(), branchResult.getQ1(), branchResult.getI1(), Double.NaN, Double.NaN, Double.NaN, branchResult.getFlowTransfer());
var half2Result = new BranchResult(getHalf2().getId(), branchResult.getP2(), branchResult.getQ2(), branchResult.getI2(), Double.NaN, Double.NaN, Double.NaN, branchResult.getFlowTransfer());
if (createExtension) {
branchResult.addExtension(OlfBranchResult.class, new OlfBranchResult(piModel.getR1(), piModel.getContinuousR1(),
getV1() * nominalV1, getV2() * nominalV2, Math.toDegrees(getAngle1()), Math.toDegrees(getAngle2())));
Expand Down
Loading