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

DC security analysis: remove call to sensitivity API #927

Merged
merged 16 commits into from
Jan 8, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -1573,7 +1573,8 @@ public static DcLoadFlowParameters createDcParameters(LoadFlowParameters paramet
.setUpdateFlows(true)
.setForcePhaseControlOffAndAddAngle1Var(forcePhaseControlOffAndAddAngle1Var)
.setUseTransformerRatio(parameters.isDcUseTransformerRatio())
.setDcApproximationType(parametersExt.getDcApproximationType());
.setDcApproximationType(parametersExt.getDcApproximationType())
.setDcPowerFactor(parameters.getDcPowerFactor());

return new DcLoadFlowParameters()
.setNetworkParameters(networkParameters)
Expand Down
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 @@ -169,7 +169,7 @@ private LoadFlowResult runAc(Network network, LoadFlowParameters parameters, Ope
result.getDistributedActivePower() * PerUnit.SB));
}

boolean ok = results.stream().anyMatch(AcLoadFlowResult::isOk);
boolean ok = results.stream().anyMatch(AcLoadFlowResult::isSuccess);
return new LoadFlowResultImpl(ok, Collections.emptyMap(), null, componentResults);
}

Expand Down Expand Up @@ -208,16 +208,16 @@ private LoadFlowResult runDc(Network network, LoadFlowParameters parameters, Ope
Networks.resetState(network);

List<LoadFlowResult.ComponentResult> componentsResult = results.stream().map(r -> processResult(network, r, parameters, dcParameters.getNetworkParameters().isBreakers())).toList();
boolean ok = results.stream().anyMatch(DcLoadFlowResult::isSucceeded);
boolean ok = results.stream().anyMatch(DcLoadFlowResult::isSuccess);
return new LoadFlowResultImpl(ok, Collections.emptyMap(), null, componentsResult);
}

private LoadFlowResult.ComponentResult processResult(Network network, DcLoadFlowResult result, LoadFlowParameters parameters, boolean breakers) {
if (result.isSucceeded() && parameters.isWriteSlackBus()) {
if (result.isSuccess() && parameters.isWriteSlackBus()) {
SlackTerminal.reset(network);
}

if (result.isSucceeded()) {
if (result.isSuccess()) {
var updateParameters = new LfNetworkStateUpdateParameters(false,
parameters.isWriteSlackBus(),
parameters.isPhaseShifterRegulationOn(),
Expand All @@ -233,7 +233,7 @@ private LoadFlowResult.ComponentResult processResult(Network network, DcLoadFlow
}

var referenceBusAndSlackBusesResults = buildReferenceBusAndSlackBusesResults(result);
LoadFlowResult.ComponentResult.Status status = result.isSucceeded() ? LoadFlowResult.ComponentResult.Status.CONVERGED : LoadFlowResult.ComponentResult.Status.FAILED;
LoadFlowResult.ComponentResult.Status status = result.isSuccess() ? LoadFlowResult.ComponentResult.Status.CONVERGED : LoadFlowResult.ComponentResult.Status.FAILED;
return new LoadFlowResultImpl.ComponentResultImpl(
result.getNetwork().getNumCC(),
result.getNetwork().getNumSC(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,18 @@ public double getDistributedActivePower() {
return distributedActivePower;
}

public boolean isOk() {
@Override
public boolean isSuccess() {
return solverStatus == AcSolverStatus.CONVERGED && outerLoopStatus == OuterLoopStatus.STABLE;
}

public boolean isWithNetworkUpdate() {
// do not reset state in case all results are ok and no NR iterations because it means that the network was
// not changed and no calculation update was needed.
return isOk() && solverIterations > 0;
return isSuccess() && solverIterations > 0;
}

@Override
public LoadFlowResult.ComponentResult.Status toComponentResultStatus() {
if (getOuterLoopStatus() == OuterLoopStatus.UNSTABLE) {
return LoadFlowResult.ComponentResult.Status.MAX_ITERATION_REACHED;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static com.powsybl.openloadflow.equations.EquationTerm.setActive;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
Expand Down Expand Up @@ -839,12 +841,6 @@ protected static void createImpedantBranchEquations(LfBranch branch, LfBus bus1,
}
}

private static void setActive(Evaluable evaluable, boolean active) {
if (evaluable instanceof EquationTerm<?, ?> term) {
term.setActive(active);
}
}

static void updateBranchEquations(LfBranch branch) {
if (!branch.isDisabled() && !branch.isZeroImpedance(LoadFlowModel.AC)) {
if (branch.isConnectedSide1() && branch.isConnectedSide2()) {
Expand Down
22 changes: 11 additions & 11 deletions src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ private boolean runPhaseControlOuterLoop(DcIncrementalPhaseControlOuterLoop oute
Reporter olReporter = Reports.createOuterLoopReporter(outerLoopContext.getNetwork().getReporter(), outerLoop.getName());
OuterLoopStatus outerLoopStatus;
int outerLoopIteration = 0;
boolean succeeded = true;
boolean success = true;

// re-run linear system solving until stabilization
do {
Expand All @@ -127,20 +127,20 @@ private boolean runPhaseControlOuterLoop(DcIncrementalPhaseControlOuterLoop oute

// if not yet stable, restart linear system solving
double[] targetVectorArray = context.getTargetVector().getArray().clone();
succeeded = solve(targetVectorArray, context.getJacobianMatrix(), olReporter);
success = solve(targetVectorArray, context.getJacobianMatrix(), olReporter);

if (succeeded) {
if (success) {
context.getEquationSystem().getStateVector().set(targetVectorArray);
updateNetwork(outerLoopContext.getNetwork(), context.getEquationSystem(), targetVectorArray);
}

outerLoopIteration++;
}
} while (outerLoopStatus == OuterLoopStatus.UNSTABLE
&& succeeded
&& success
&& outerLoopIteration < context.getParameters().getMaxOuterLoopIterations());

return succeeded;
return success;
}

public static boolean solve(double[] targetVectorArray,
Expand Down Expand Up @@ -182,14 +182,14 @@ public DcLoadFlowResult run() {
var targetVectorArray = targetVector.getArray().clone();

// First linear system solution
boolean succeeded = solve(targetVectorArray, context.getJacobianMatrix(), reporter);
boolean success = solve(targetVectorArray, context.getJacobianMatrix(), reporter);

equationSystem.getStateVector().set(targetVectorArray);
updateNetwork(network, equationSystem, targetVectorArray);

// continue with PST active power control outer loop only if first linear system solution has succeeded
if (succeeded && parameters.getNetworkParameters().isPhaseControl()) {
succeeded = runPhaseControlOuterLoop(phaseShifterControlOuterLoop, outerLoopContext);
if (success && parameters.getNetworkParameters().isPhaseControl()) {
success = runPhaseControlOuterLoop(phaseShifterControlOuterLoop, outerLoopContext);
}

// set all calculated voltages to NaN
Expand All @@ -199,10 +199,10 @@ public DcLoadFlowResult run() {
}
}

Reports.reportDcLfComplete(reporter, succeeded);
LOGGER.info("DC load flow completed (succeed={})", succeeded);
Reports.reportDcLfComplete(reporter, success);
LOGGER.info("DC load flow completed (success={})", success);

return new DcLoadFlowResult(context.getNetwork(), getActivePowerMismatch(context.getNetwork().getBuses()), succeeded);
return new DcLoadFlowResult(context.getNetwork(), getActivePowerMismatch(context.getNetwork().getBuses()), success);
}

public static <T> List<DcLoadFlowResult> run(T network, LfNetworkLoader<T> networkLoader, DcLoadFlowParameters parameters, Reporter reporter) {
Expand Down
17 changes: 12 additions & 5 deletions src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package com.powsybl.openloadflow.dc;

import com.powsybl.loadflow.LoadFlowResult;
import com.powsybl.openloadflow.lf.AbstractLoadFlowResult;
import com.powsybl.openloadflow.network.LfNetwork;

Expand All @@ -14,14 +15,20 @@
*/
public class DcLoadFlowResult extends AbstractLoadFlowResult {

private final boolean succeeded;
private final boolean success;

public DcLoadFlowResult(LfNetwork network, double slackBusActivePowerMismatch, boolean succeeded) {
public DcLoadFlowResult(LfNetwork network, double slackBusActivePowerMismatch, boolean success) {
super(network, slackBusActivePowerMismatch);
this.succeeded = succeeded;
this.success = success;
}

public boolean isSucceeded() {
return succeeded;
@Override
public boolean isSuccess() {
return success;
}

@Override
public LoadFlowResult.ComponentResult.Status toComponentResultStatus() {
return success ? LoadFlowResult.ComponentResult.Status.CONVERGED : LoadFlowResult.ComponentResult.Status.FAILED;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public void prepare(LfNetwork network) {

try (DcLoadFlowContext context = new DcLoadFlowContext(network, parameters)) {
DcLoadFlowEngine engine = new DcLoadFlowEngine(context);
if (!engine.run().isSucceeded()) {
if (!engine.run().isSuccess()) {
throw new PowsyblException("DC loadflow failed, impossible to initialize voltage angle from DC values");
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) 2023, 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.dc.equations;

import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openloadflow.network.LfBranch;
import com.powsybl.openloadflow.util.Evaluable;

import java.util.Objects;

/**
* @author Anne Tilloy {@literal <anne.tilloy at rte-france.com>}
*/
public final class ClosedBranchDcCurrent implements Evaluable {

private final LfBranch branch;

private final TwoSides side;

private final double dcPowerFactor;

public ClosedBranchDcCurrent(LfBranch branch, TwoSides side, double dcPowerFactor) {
this.branch = Objects.requireNonNull(branch);
this.side = Objects.requireNonNull(side);
this.dcPowerFactor = dcPowerFactor;
}

public double eval() {
double p = side == TwoSides.ONE ? branch.getP1().eval() : branch.getP2().eval();
return Math.abs(p) / dcPowerFactor;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public class DcEquationSystemCreationParameters {

private DcApproximationType dcApproximationType = DC_APPROXIMATION_TYPE_DEFAULT_VALUE;

private double dcPowerFactor = LoadFlowParameters.DEFAULT_DC_POWER_FACTOR;

public boolean isUpdateFlows() {
return updateFlows;
}
Expand Down Expand Up @@ -65,6 +67,15 @@ public DcEquationSystemCreationParameters setDcApproximationType(DcApproximation
return this;
}

public DcEquationSystemCreationParameters setDcPowerFactor(double dcPowerFactor) {
this.dcPowerFactor = dcPowerFactor;
return this;
}

public double getDcPowerFactor() {
return dcPowerFactor;
}

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

import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openloadflow.equations.EquationSystem;
import com.powsybl.openloadflow.equations.EquationSystemPostProcessor;
import com.powsybl.openloadflow.equations.EquationTerm;
Expand Down Expand Up @@ -102,7 +103,13 @@ private static void createImpedantBranch(EquationSystem<DcVariableType, DcEquati
}
if (creationParameters.isUpdateFlows()) {
branch.setP1(p1);
branch.setClosedP1(p1);
branch.setP2(p2);
branch.setClosedP2(p2);
ClosedBranchDcCurrent i1 = new ClosedBranchDcCurrent(branch, TwoSides.ONE, creationParameters.getDcPowerFactor());
ClosedBranchDcCurrent i2 = new ClosedBranchDcCurrent(branch, TwoSides.TWO, creationParameters.getDcPowerFactor());
branch.setI1(i1);
branch.setI2(i2);
}
} else if (bus1 != null && creationParameters.isUpdateFlows()) {
branch.setP1(EvaluableConstants.ZERO);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@
*/
package com.powsybl.openloadflow.dc.equations;

import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openloadflow.equations.EquationSystem;
import com.powsybl.openloadflow.lf.AbstractEquationSystemUpdater;
import com.powsybl.openloadflow.network.LfBranch;
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.network.LfElement;
import com.powsybl.openloadflow.network.LoadFlowModel;
import com.powsybl.openloadflow.util.EvaluableConstants;

import static com.powsybl.openloadflow.equations.EquationTerm.setActive;

/**
* @author Anne Tilloy {@literal <anne.tilloy at rte-france.com>}
Expand Down Expand Up @@ -47,10 +51,34 @@ public void onDisableChange(LfElement element, boolean disabled) {
.ifPresent(eq -> eq.setActive(!bus.isDisabled() && !bus.isSlack()));
break;
case BRANCH, HVDC, SHUNT_COMPENSATOR:
// nothing to do.
// nothing to do
break;
default:
throw new IllegalStateException("Unknown element type: " + element.getType());
}
}

@Override
public void onBranchConnectionStatusChange(LfBranch branch, TwoSides side, boolean connected) {
super.onBranchConnectionStatusChange(branch, side, connected);
if (!branch.isDisabled() && !branch.isZeroImpedance(LoadFlowModel.DC)) {
if (branch.isConnectedSide1() && branch.isConnectedSide2()) {
setActive(branch.getClosedP1(), true);
setActive(branch.getClosedP2(), true);
branch.setP1(branch.getClosedP1());
branch.setP2(branch.getClosedP2());
} else if (!branch.isConnectedSide1() && branch.isConnectedSide2()
|| branch.isConnectedSide1() && !branch.isConnectedSide2()) {
setActive(branch.getClosedP1(), false);
setActive(branch.getClosedP2(), false);
branch.setP1(EvaluableConstants.ZERO);
branch.setP2(EvaluableConstants.ZERO);
} else {
setActive(branch.getClosedP1(), false);
setActive(branch.getClosedP2(), false);
branch.setP1(EvaluableConstants.NAN);
branch.setP2(EvaluableConstants.NAN);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
*/
public interface EquationTerm<V extends Enum<V> & Quantity, E extends Enum<E> & Quantity> extends Evaluable {

static void setActive(Evaluable evaluable, boolean active) {
if (evaluable instanceof EquationTerm<?, ?> term) {
term.setActive(active);
}
}

class MultiplyByScalarEquationTerm<V extends Enum<V> & Quantity, E extends Enum<E> & Quantity> implements EquationTerm<V, E> {

private final EquationTerm<V, E> term;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/
public interface LoadFlowEngine<V extends Enum<V> & Quantity,
E extends Enum<E> & Quantity,
P extends AbstractLoadFlowParameters,
P extends AbstractLoadFlowParameters<P>,
R extends LoadFlowResult> {

LoadFlowContext<V, E, P> getContext();
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/powsybl/openloadflow/lf/LoadFlowResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
*/
public interface LoadFlowResult {

boolean isSuccess();

LfNetwork getNetwork();

double getSlackBusActivePowerMismatch();

com.powsybl.loadflow.LoadFlowResult.ComponentResult.Status toComponentResultStatus();
}
Loading
Loading