Skip to content

Commit

Permalink
HVDC AC emulation (#466)
Browse files Browse the repository at this point in the history
Signed-off-by: Anne Tilloy <[email protected]>
  • Loading branch information
annetill authored Mar 15, 2022
1 parent f6359e6 commit d0de89c
Show file tree
Hide file tree
Showing 25 changed files with 744 additions and 13 deletions.
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 @@ -64,6 +64,8 @@ public class OpenLoadFlowParameters extends AbstractExtension<LoadFlowParameters

public static final boolean VOLTAGE_PER_REACTIVE_POWER_CONTROL_DEFAULT_VALUE = false;

public static final boolean HVDC_AC_EMULATION_DEFAULT_VALUE = false;

public enum VoltageInitModeOverride {
NONE,
VOLTAGE_MAGNITUDE,
Expand Down Expand Up @@ -114,6 +116,8 @@ public enum LowImpedanceBranchMode {

private TransformerVoltageControlMode transformerVoltageControlMode = TRANSFORMER_VOLTAGE_CONTROL_MODE_DEFAULT_VALUE;

private boolean hvdcAcEmulation = HVDC_AC_EMULATION_DEFAULT_VALUE;

@Override
public String getName() {
return "open-load-flow-parameters";
Expand Down Expand Up @@ -262,6 +266,14 @@ public OpenLoadFlowParameters setTransformerVoltageControlMode(TransformerVoltag
return this;
}

public boolean isHvdcAcEmulation() {
return hvdcAcEmulation; }

public OpenLoadFlowParameters setHvdcAcEmulation(boolean hvdcAcEmulation) {
this.hvdcAcEmulation = hvdcAcEmulation;
return this;
}

public static OpenLoadFlowParameters load() {
return new OpenLoadFlowConfigLoader().load(PlatformConfig.defaultConfig());
}
Expand All @@ -284,6 +296,7 @@ public String toString() {
", newtonRaphsonConvEpsPerEq=" + newtonRaphsonConvEpsPerEq +
", voltageInitModeOverride=" + voltageInitModeOverride +
", transformerVoltageControlMode=" + transformerVoltageControlMode +
", hvdcAcEmulation=" + hvdcAcEmulation +
')';
}

Expand Down Expand Up @@ -320,6 +333,8 @@ public static class OpenLoadFlowConfigLoader implements LoadFlowParameters.Confi

public static final String TRANSFORMER_VOLTAGE_CONTROL_MODE_NAME = "transformerVoltageControlMode";

public static final String HVDC_AC_EMULATION_PARAM_NAME = "hvdcAcEmulation";

@Override
public OpenLoadFlowParameters load(PlatformConfig platformConfig) {
OpenLoadFlowParameters parameters = new OpenLoadFlowParameters();
Expand All @@ -343,6 +358,7 @@ public OpenLoadFlowParameters load(PlatformConfig platformConfig) {
.setNewtonRaphsonConvEpsPerEq(config.getDoubleProperty(NEWTON_RAPHSON_CONV_EPS_PER_EQ_NAME, DefaultNewtonRaphsonStoppingCriteria.DEFAULT_CONV_EPS_PER_EQ))
.setVoltageInitModeOverride(config.getEnumProperty(VOLTAGE_INIT_MODE_OVERRIDE_NAME, VoltageInitModeOverride.class, VOLTAGE_INIT_MODE_OVERRIDE_DEFAULT_VALUE))
.setTransformerVoltageControlMode(config.getEnumProperty(TRANSFORMER_VOLTAGE_CONTROL_MODE_NAME, TransformerVoltageControlMode.class, TRANSFORMER_VOLTAGE_CONTROL_MODE_DEFAULT_VALUE))
.setHvdcAcEmulation(config.getBooleanProperty(HVDC_AC_EMULATION_PARAM_NAME, HVDC_AC_EMULATION_DEFAULT_VALUE))
);
return parameters;
}
Expand Down Expand Up @@ -420,6 +436,7 @@ public static void logAc(LoadFlowParameters parameters, OpenLoadFlowParameters p
LOGGER.info("Voltage per reactive power control: {}", parametersExt.isVoltagePerReactivePowerControl());
LOGGER.info("Reactive Power Remote control: {}", parametersExt.hasReactivePowerRemoteControl());
LOGGER.info("Shunt voltage control: {}", parameters.isShuntCompensatorVoltageControlOn());
LOGGER.info("Hvdc Ac emulation: {}", parametersExt.isHvdcAcEmulation());
}

static VoltageInitializer getVoltageInitializer(LoadFlowParameters parameters, LfNetworkParameters networkParameters, MatrixFactory matrixFactory, Reporter reporter) {
Expand Down Expand Up @@ -478,7 +495,8 @@ static LfNetworkParameters getNetworkParameters(LoadFlowParameters parameters, O
parametersExt.hasReactivePowerRemoteControl(),
parameters.isDc(),
parameters.isShuntCompensatorVoltageControlOn(),
!parameters.isNoGeneratorReactiveLimits());
!parameters.isNoGeneratorReactiveLimits(),
parametersExt.isHvdcAcEmulation());
}

public static AcLoadFlowParameters createAcParameters(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt,
Expand Down Expand Up @@ -554,7 +572,8 @@ public static DcLoadFlowParameters createDcParameters(LoadFlowParameters paramet
false,
true,
false,
false);
false,
false); // FIXME

var equationSystemCreationParameters = new DcEquationSystemCreationParameters(true,
false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* Copyright (c) 2022, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* 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.ac.equations;

import com.powsybl.openloadflow.equations.AbstractNamedEquationTerm;
import com.powsybl.openloadflow.equations.Variable;
import com.powsybl.openloadflow.equations.VariableSet;
import com.powsybl.openloadflow.network.ElementType;
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.network.LfHvdc;

import java.util.List;

/**
* @author Anne Tilloy <anne.tilloy at rte-france.com>
*/
public abstract class AbstractHvdcAcEmulationFlowEquationTerm extends AbstractNamedEquationTerm<AcVariableType, AcEquationType> {

protected final Variable<AcVariableType> ph1Var;

protected final Variable<AcVariableType> ph2Var;

protected final List<Variable<AcVariableType>> variables;

protected final double k;

protected final double p0;

protected final LfHvdc hvdc;

protected final double lossFactor1;

protected final double lossFactor2;

protected AbstractHvdcAcEmulationFlowEquationTerm(LfHvdc hvdc, LfBus bus1, LfBus bus2, VariableSet<AcVariableType> variableSet) {
ph1Var = variableSet.getVariable(bus1.getNum(), AcVariableType.BUS_PHI);
ph2Var = variableSet.getVariable(bus2.getNum(), AcVariableType.BUS_PHI);
variables = List.of(ph1Var, ph2Var);
this.hvdc = hvdc;
k = hvdc.getDroop() * 180 / Math.PI;
p0 = hvdc.getP0();
lossFactor1 = hvdc.getConverterStation1().getLossFactor() / 100;
lossFactor2 = hvdc.getConverterStation2().getLossFactor() / 100;
}

protected double ph1() {
return stateVector.get(ph1Var.getRow());
}

protected double ph2() {
return stateVector.get(ph2Var.getRow());
}

protected double getLossMultiplier() {
return (1 - lossFactor1) * (1 - lossFactor2);
}

@Override
public List<Variable<AcVariableType>> getVariables() {
return variables;
}

@Override
public boolean hasRhs() {
return false;
}

@Override
public ElementType getElementType() {
return ElementType.HVDC;
}

@Override
public int getElementNum() {
return hvdc.getNum();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,30 @@ private static void createImpedantBranch(LfBranch branch, LfBus bus1, LfBus bus2
}
}

private static void createHvdcAcEmulationEquations(LfHvdc hvdc, EquationSystem<AcVariableType, AcEquationType> equationSystem) {
EquationTerm<AcVariableType, AcEquationType> p1 = null;
EquationTerm<AcVariableType, AcEquationType> p2 = null;
if (hvdc.getBus1() != null && hvdc.getBus2() != null) {
p1 = new HvdcAcEmulationSide1ActiveFlowEquationTerm(hvdc, hvdc.getBus1(), hvdc.getBus2(), equationSystem.getVariableSet());
p2 = new HvdcAcEmulationSide2ActiveFlowEquationTerm(hvdc, hvdc.getBus1(), hvdc.getBus2(), equationSystem.getVariableSet());
} else {
// nothing to do
}

if (p1 != null) {
equationSystem.getEquation(hvdc.getBus1().getNum(), AcEquationType.BUS_TARGET_P)
.orElseThrow()
.addTerm(p1);
hvdc.setP1(p1);
}
if (p2 != null) {
equationSystem.getEquation(hvdc.getBus2().getNum(), AcEquationType.BUS_TARGET_P)
.orElseThrow()
.addTerm(p2);
hvdc.setP2(p2);
}
}

private static void createBranchEquations(LfBranch branch, LfNetworkParameters networkParameters,
EquationSystem<AcVariableType, AcEquationType> equationSystem,
AcEquationSystemCreationParameters creationParameters) {
Expand Down Expand Up @@ -756,6 +780,10 @@ public static EquationSystem<AcVariableType, AcEquationType> create(LfNetwork ne
createBusesEquations(network, networkParameters, equationSystem, creationParameters);
createBranchesEquations(network, networkParameters, equationSystem, creationParameters);

for (LfHvdc hvdc : network.getHvdcs()) {
createHvdcAcEmulationEquations(hvdc, equationSystem);
}

EquationSystemPostProcessor.findAll().forEach(pp -> pp.onCreate(equationSystem));

network.addListener(new AcEquationSystemUpdater(equationSystem));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Copyright (c) 2022, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* 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.ac.equations;

import com.powsybl.openloadflow.equations.Variable;
import com.powsybl.openloadflow.equations.VariableSet;
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.network.LfHvdc;

import java.util.Objects;

/**
* @author Anne Tilloy <anne.tilloy at rte-france.com>
*/
public class HvdcAcEmulationSide1ActiveFlowEquationTerm extends AbstractHvdcAcEmulationFlowEquationTerm {

public HvdcAcEmulationSide1ActiveFlowEquationTerm(LfHvdc hvdc, LfBus bus1, LfBus bus2, VariableSet<AcVariableType> variableSet) {
super(hvdc, bus1, bus2, variableSet);
}

private double p1() {
return (isController() ? 1 : getLossMultiplier()) * (p0 + k * (ph1() - ph2()));
}

private boolean isController() {
return (ph1() - ph2()) >= 0;
}

private double dp1dph1() {
return (isController() ? 1 : getLossMultiplier()) * k;
}

private double dp1dph2() {
return -dp1dph1();
}

@Override
public double eval() {
return p1();
}

@Override
public double der(Variable<AcVariableType> variable) {
Objects.requireNonNull(variable);
if (variable.equals(ph1Var)) {
return dp1dph1();
} else if (variable.equals(ph2Var)) {
return dp1dph2();
} else {
throw new IllegalStateException("Unknown variable: " + variable);
}
}

@Override
protected String getName() {
return "ac_emulation_p_1";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Copyright (c) 2022, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* 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.ac.equations;

import com.powsybl.openloadflow.equations.Variable;
import com.powsybl.openloadflow.equations.VariableSet;
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.network.LfHvdc;

import java.util.Objects;

/**
* @author Anne Tilloy <anne.tilloy at rte-france.com>
*/
public class HvdcAcEmulationSide2ActiveFlowEquationTerm extends AbstractHvdcAcEmulationFlowEquationTerm {

public HvdcAcEmulationSide2ActiveFlowEquationTerm(LfHvdc hvdc, LfBus bus1, LfBus bus2, VariableSet<AcVariableType> variableSet) {
super(hvdc, bus1, bus2, variableSet);
}

private double p2() {
return -(isController() ? 1 : getLossMultiplier()) * (p0 + k * (ph1() - ph2()));
}

private boolean isController() {
return (ph1() - ph2()) < 0;
}

private double dp2dph1() {
return -(isController() ? 1 : getLossMultiplier()) * k;
}

private double dp2dph2() {
return -dp2dph1();
}

@Override
public double eval() {
return p2();
}

@Override
public double der(Variable<AcVariableType> variable) {
Objects.requireNonNull(variable);
if (variable.equals(ph1Var)) {
return dp2dph1();
} else if (variable.equals(ph2Var)) {
return dp2dph2();
} else {
throw new IllegalStateException("Unknown variable: " + variable);
}
}

@Override
protected String getName() {
return "ac_emulation_p_2";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ public enum ElementType {
BUS,
BRANCH,
SHUNT_COMPENSATOR,
HVDC
}
2 changes: 2 additions & 0 deletions src/main/java/com/powsybl/openloadflow/network/LfBus.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ default double getHighVoltageLimit() {

void addBranch(LfBranch branch);

void addHvdc(LfHvdc hvdc);

void updateState(boolean reactiveLimits, boolean writeSlackBus, boolean distributedOnConformLoad, boolean loadPowerFactorConstant);

Optional<TransformerVoltageControl> getTransformerVoltageControl();
Expand Down
42 changes: 42 additions & 0 deletions src/main/java/com/powsybl/openloadflow/network/LfHvdc.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (c) 2022, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* 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;

import com.powsybl.openloadflow.network.impl.LfVscConverterStationImpl;
import com.powsybl.openloadflow.util.Evaluable;

/**
* @author Anne Tilloy <anne.tilloy at rte-france.com>
*/
public interface LfHvdc extends LfElement {

LfBus getBus1();

LfBus getBus2();

void setP1(Evaluable p1);

Evaluable getP1();

void setP2(Evaluable p2);

Evaluable getP2();

double getDroop();

double getP0();

LfVscConverterStationImpl getConverterStation1();

LfVscConverterStationImpl getConverterStation2();

void setConverterStation1(LfVscConverterStationImpl converterStation1);

void setConverterStation2(LfVscConverterStationImpl converterStation2);

void updateState();
}
Loading

0 comments on commit d0de89c

Please sign in to comment.