Skip to content
Draft
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
32 changes: 28 additions & 4 deletions src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.math.matrix.MatrixException;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.dc.equations.DcApproximationType;
import com.powsybl.openloadflow.dc.equations.DcEquationType;
import com.powsybl.openloadflow.dc.equations.DcVariableType;
import com.powsybl.openloadflow.equations.*;
import com.powsybl.openloadflow.lf.LoadFlowEngine;
import com.powsybl.openloadflow.lf.outerloop.OuterLoopResult;
import com.powsybl.openloadflow.lf.outerloop.OuterLoopStatus;
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.network.LfGenerator;
import com.powsybl.openloadflow.network.LfNetwork;
import com.powsybl.openloadflow.network.LfNetworkLoader;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.network.impl.LfBranchImpl;
import com.powsybl.openloadflow.network.impl.LfBusImpl;
import com.powsybl.openloadflow.network.util.ActivePowerDistribution;
import com.powsybl.openloadflow.network.util.UniformValueVoltageInitializer;
import com.powsybl.openloadflow.network.util.VoltageInitializer;
Expand Down Expand Up @@ -200,6 +200,30 @@ public DcLoadFlowResult run() {

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

if (context.getParameters().getEquationSystemCreationParameters().getDcApproximationType() == DcApproximationType.HOT_START) {
double totalLoss = 0.;
for (LfBranch branch : network.getBranches()) {
LfBranchImpl lfbranch = (LfBranchImpl) branch;
double p1 = lfbranch.getBranch().getTerminal1().getP();
double p2 = lfbranch.getBranch().getTerminal2().getP();
double loss = (p1 + p2) / PerUnit.SB;
totalLoss += loss;
LfBusImpl lfbus1 = (LfBusImpl) lfbranch.getBus1();
lfbus1.addLossInjectionTargetP(loss / 2.);
LfBusImpl lfbus2 = (LfBusImpl) lfbranch.getBus2();
lfbus2.addLossInjectionTargetP(loss / 2);
}

for (LfHvdc hvdc : network.getHvdcs()) {
double loss = (hvdc.getP10() + hvdc.getP20()) / PerUnit.SB;
totalLoss += loss;
hvdc.getConverterStation1().getBus().addLossInjectionTargetP(loss / 2.);
hvdc.getConverterStation2().getBus().addLossInjectionTargetP(loss / 2.);
}

Reports.reporDcLossCompensation(reportNode, totalLoss * PerUnit.SB);
}

double initialSlackBusActivePowerMismatch = getActivePowerMismatch(network.getBuses());
double distributedActivePower = 0.0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.network.PiModel;
import com.powsybl.openloadflow.network.PiModelArray;
import com.powsybl.openloadflow.util.PerUnit;

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

import static com.powsybl.openloadflow.dc.equations.DcApproximationType.HOT_START;
import static com.powsybl.openloadflow.network.PiModel.R2;

/**
Expand Down Expand Up @@ -56,7 +58,20 @@ protected AbstractClosedBranchDcFlowEquationTerm(LfBranch branch, LfBus bus1, Lf
this.useTransformerRatio = useTransformerRatio;
this.dcApproximationType = dcApproximationType;
isPowerPreComputed = !(piModel instanceof PiModelArray);
power = isPowerPreComputed ? computePower(useTransformerRatio, dcApproximationType, piModel) : Double.NaN;
double nominalV2 = bus2.getNominalV();
double zb = PerUnit.zb(nominalV2);
double v1 = bus1.getV();
double v2 = bus2.getV();
double angle1 = bus1.getAngle();
double angle2 = bus2.getAngle();
double deltaTheta = angle1 - angle2;
double angular;
if (deltaTheta == 0.) {
angular = 1.;
} else {
angular = Math.sin(deltaTheta) / deltaTheta;
}
power = isPowerPreComputed ? computePower(useTransformerRatio, dcApproximationType, piModel, v1, v2, angular, zb) : Double.NaN;
if (a1Var != null) {
variables = List.of(ph1Var, ph2Var, a1Var);
} else {
Expand All @@ -68,17 +83,24 @@ protected AbstractClosedBranchDcFlowEquationTerm(LfBranch branch, LfBus bus1, Lf
* Update power only if the branch is a PiModelArray.
*/
protected double getPower() {
return isPowerPreComputed ? power : computePower(useTransformerRatio, dcApproximationType, element.getPiModel());
return isPowerPreComputed ? power : computePower(useTransformerRatio, dcApproximationType, element.getPiModel(), 1., 1., 1., 1.);
}

public static double computePower(boolean useTransformerRatio, DcApproximationType dcApproximationType, PiModel piModel) {
public static double computePower(boolean useTransformerRatio, DcApproximationType dcApproximationType, PiModel piModel, double v1, double v2, double angular, double zb) {
double b = switch (dcApproximationType) {
case IGNORE_R -> 1d / piModel.getX();
case IGNORE_G -> {
double r = piModel.getR();
double x = piModel.getX();
yield x / (r * r + x * x);
}
case HOT_START -> {
double r = piModel.getR() * zb;
double x = piModel.getX() * zb;
double susceptance = -x / (r * r + x * x);
double admittance = -v1 * v2 * susceptance * angular;
yield admittance * zb;
}
};
return b * (useTransformerRatio ? piModel.getR1() * R2 : 1);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
*/
public enum DcApproximationType {
IGNORE_R,
IGNORE_G
IGNORE_G,
HOT_START
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ private double calculatePower(LfBranch lfBranch) {
}

private double calculatePower(PiModel piModel) {
return AbstractClosedBranchDcFlowEquationTerm.computePower(creationParameters.isUseTransformerRatio(), creationParameters.getDcApproximationType(), piModel);
return AbstractClosedBranchDcFlowEquationTerm.computePower(creationParameters.isUseTransformerRatio(), creationParameters.getDcApproximationType(), piModel, 1, 1, 1, 1);
}

/**
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/com/powsybl/openloadflow/network/LfBus.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ public boolean isMaxLimit() {
*/
double getFictitiousInjectionTargetQ();

/**
* Returns the part of getLoadTargetP that does not come from a load but from the loss bus injection
*/
double getLossInjectionTargetP();

void invalidateLoadTargetP();

double getLoadTargetP();
Expand Down Expand Up @@ -263,4 +268,6 @@ default Optional<Country> getCountry() {
void setArea(LfArea area);

ViolationLocation getViolationLocation();

void addLossInjectionTargetP(double lossInjectionTargetP);
}
7 changes: 7 additions & 0 deletions src/main/java/com/powsybl/openloadflow/network/LfHvdc.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
package com.powsybl.openloadflow.network;

import com.powsybl.iidm.network.HvdcLine;
import com.powsybl.openloadflow.util.Evaluable;

/**
Expand Down Expand Up @@ -62,4 +63,10 @@ public interface LfHvdc extends LfElement {

void setAngleDifferenceToFreeze(double angleToFreeze);

HvdcLine.ConvertersMode getConvertersMode();

double getP10();

double getP20();

}
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,15 @@ public abstract class AbstractLfBus extends AbstractElement implements LfBus {

protected boolean forceTargetQInReactiveLimits;

protected double lossInjectionTargetP;

protected AbstractLfBus(LfNetwork network, double v, double angle, LfNetworkParameters parameters) {
super(network);
this.v = v;
this.angle = angle;
this.distributedOnConformLoad = parameters.isDistributedOnConformLoad();
this.forceTargetQInReactiveLimits = parameters.isForceTargetQInReactiveLimits() && parameters.isReactiveLimits();
this.lossInjectionTargetP = 0.;
}

@Override
Expand Down Expand Up @@ -477,7 +480,7 @@ public double getLoadTargetP() {
loadTargetP += load.getTargetP() * load.getLoadModel().flatMap(lm -> lm.getExpTermP(0).map(LfLoadModel.ExpTerm::c)).orElse(1d);
}
}
return loadTargetP + getFictitiousInjectionTargetP();
return loadTargetP + getFictitiousInjectionTargetP() + getLossInjectionTargetP();
}

@Override
Expand Down Expand Up @@ -929,4 +932,14 @@ public double getFictitiousInjectionTargetQ() {
return 0;
}

@Override
public double getLossInjectionTargetP() {
return this.lossInjectionTargetP;
}

@Override
public void addLossInjectionTargetP(double lossInjectionTargetP) {
this.lossInjectionTargetP += lossInjectionTargetP;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public static LfBranchImpl create(Branch<?> branch, LfNetwork network, LfBus bus
return lfBranch;
}

private Branch<?> getBranch() {
public Branch<?> getBranch() {
return branchRef.get();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ public class LfHvdcImpl extends AbstractElement implements LfHvdc {

private boolean acEmulationFrozen = false;

private HvdcLine.ConvertersMode mode;

private double p10;

private double p20;

public LfHvdcImpl(String id, LfBus bus1, LfBus bus2, LfNetwork network, HvdcLine hvdcLine, boolean acEmulation) {
super(network);
this.id = Objects.requireNonNull(id);
Expand All @@ -76,6 +82,9 @@ public LfHvdcImpl(String id, LfBus bus1, LfBus bus2, LfNetwork network, HvdcLine
pMaxFromCS2toCS1 = hvdcLine.getMaxP();
pMaxFromCS1toCS2 = hvdcLine.getMaxP();
}
this.mode = hvdcLine.getConvertersMode();
this.p10 = hvdcLine.getConverterStation1().getTerminal().getP();
this.p20 = hvdcLine.getConverterStation2().getTerminal().getP();
}

@Override
Expand Down Expand Up @@ -229,4 +238,20 @@ public double getAngleDifferenceToFreeze() {
public void setAngleDifferenceToFreeze(double frozenP) {
this.angleToFreeze = frozenP;
}

@Override
public HvdcLine.ConvertersMode getConvertersMode() {
return mode;
}

@Override
public double getP10() {
return p10;
}

@Override
public double getP20() {
return p20;
}

}
8 changes: 8 additions & 0 deletions src/main/java/com/powsybl/openloadflow/util/Reports.java
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ public static void reportComponentsWithoutGenerators(ReportNode reportNode, int
.add();
}

public static void reporDcLossCompensation(ReportNode reportNode, double totalLoss) {
reportNode.newReportNode()
.withMessageTemplate("olf.dcLossCompensation")
.withUntypedValue("totalLossCompensation", totalLoss)
.withSeverity(TypedValue.DEBUG_SEVERITY)
.add();
}

public static void reportMismatchDistributionFailure(ReportNode reportNode, double remainingMismatch) {
reportNode.newReportNode()
.withMessageTemplate("olf.mismatchDistributionFailure")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ olf.controllerShuntAlreadyInVoltageControl = Controller shunt ${controllerShuntI
olf.currentLimiterPstsChangedTaps = ${numOfCurrentLimiterPstsThatChangedTap} current limiter PST(s) changed taps
olf.dcLfComplete = DC load flow completed (solverSuccess=${succeeded}, outerloopStatus=${outerloopStatus})
olf.dcLfFailure = Failed to solve linear system for DC load flow: ${errorMessage}
olf.dcLossCompensation = DC loss compensation {totalLossCompensation} MW
olf.dcSecurityAnalysis = DC security analysis on network '${networkId}'
olf.fictitiousInjectionTotal = Network has a total absolute sum of ${totalP} MW and ${totalQ} MVar fictitious injection across ${busCount} buses
olf.fixVoltageTargets = Checking voltage targets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ olf.controllerShuntAlreadyInVoltageControl = La shunt ${controllerShuntId} sur l
olf.currentLimiterPstsChangedTaps = ${numOfCurrentLimiterPstsThatChangedTap} déphaseurs limiteurs de courant ont changé de prise
olf.dcLfComplete = Calcul de répartition DC terminé (solverSuccess=${succeeded}, outerloopStatus=${outerloopStatus})
olf.dcLfFailure = Échec de la résolution du système linéaire pour le flux de charge DC : ${errorMessage}
olf.dcLossCompensation = DC compensation des pertes {totalLossCompensation} MW
olf.dcSecurityAnalysis = Analyse de sécurité DC sur le réseau '${networkId}'
olf.fixVoltageTargets = Vérification des consignes de tension
olf.fictitiousInjectionTotal = Le réseau comporte un cumul absolu de ${totalP} MW et ${totalQ} MVar d'injections fictives réparties sur ${busCount} noeuds
Expand Down