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

Disable switch without removing variables #455

Merged
merged 27 commits into from
Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from 26 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
Original file line number Diff line number Diff line change
Expand Up @@ -331,14 +331,21 @@ private static void createNonImpedantBranch(LfBranch branch, LfBus bus1, LfBus b
bus1.setCalculatedV(vTerm);
// add a dummy reactive power variable to both sides of the non impedant branch and with an opposite sign
// to ensure we have the same number of equation and variables
var dummyQ = equationSystem.getVariable(branch.getNum(), AcVariableType.DUMMY_Q);
equationSystem.getEquation(bus1.getNum(), AcEquationType.BUS_TARGET_Q)
.orElseThrow()
.addTerm(equationSystem.getVariable(branch.getNum(), AcVariableType.DUMMY_Q).createTerm());
.addTerm(dummyQ.createTerm());

equationSystem.getEquation(bus2.getNum(), AcEquationType.BUS_TARGET_Q)
.orElseThrow()
.addTerm(equationSystem.getVariable(branch.getNum(), AcVariableType.DUMMY_Q).<AcEquationType>createTerm()
.addTerm(dummyQ.<AcEquationType>createTerm()
.minus());

// create an inactive dummy reactive power target equation set to zero that could be activated
// on case of switch opening
equationSystem.createEquation(branch.getNum(), AcEquationType.DUMMY_TARGET_Q)
.addTerm(dummyQ.createTerm())
.setActive(false);
} else {
// nothing to do in case of v1 and v2 are found, we just have to ensure
// target v are equals.
Expand All @@ -356,14 +363,21 @@ private static void createNonImpedantBranch(LfBranch branch, LfBus bus1, LfBus b

// add a dummy active power variable to both sides of the non impedant branch and with an opposite sign
// to ensure we have the same number of equation and variables
var dummyP = equationSystem.getVariable(branch.getNum(), AcVariableType.DUMMY_P);
equationSystem.getEquation(bus1.getNum(), AcEquationType.BUS_TARGET_P)
.orElseThrow()
.addTerm(equationSystem.getVariable(branch.getNum(), AcVariableType.DUMMY_P).createTerm());
.addTerm(dummyP.createTerm());

equationSystem.getEquation(bus2.getNum(), AcEquationType.BUS_TARGET_P)
.orElseThrow()
.addTerm(equationSystem.getVariable(branch.getNum(), AcVariableType.DUMMY_P).<AcEquationType>createTerm()
.addTerm(dummyP.<AcEquationType>createTerm()
.minus());

// create an inactive dummy active power target equation set to zero that could be activated
// on case of switch opening
equationSystem.createEquation(branch.getNum(), AcEquationType.DUMMY_TARGET_P)
.addTerm(dummyP.createTerm())
.setActive(false);
} else {
throw new IllegalStateException("Cannot happen because only there is one slack bus per model");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,38 @@ public void onShuntVoltageControlChange(LfShunt controllerShunt, boolean newVolt
}

private void updateElementEquations(LfElement element, boolean enable) {
// update all equations related to the element
for (var equation : equationSystem.getEquations(element.getType(), element.getNum())) {
if (equation.isActive() != enable) {
equation.setActive(enable);
if (element instanceof LfBranch && ((LfBranch) element).isZeroImpedanceBranch(false)) {
LfBranch branch = (LfBranch) element;
if (branch.isSpanningTreeEdge()) {
// depending on the switch status, we activate either v1 = v2, ph1 = ph2 equations
// or equations that set dummy p and q variable to zero
equationSystem.getEquation(element.getNum(), AcEquationType.ZERO_PHI)
.orElseThrow()
.setActive(enable);
equationSystem.getEquation(element.getNum(), AcEquationType.DUMMY_TARGET_P)
.orElseThrow()
.setActive(!enable);

equationSystem.getEquation(element.getNum(), AcEquationType.ZERO_V)
.orElseThrow()
.setActive(enable);
equationSystem.getEquation(element.getNum(), AcEquationType.DUMMY_TARGET_Q)
.orElseThrow()
.setActive(!enable);
}
} else {
// update all equations related to the element
for (var equation : equationSystem.getEquations(element.getType(), element.getNum())) {
if (equation.isActive() != enable) {
equation.setActive(enable);
}
}
}

// update all equation terms related to the element
for (var equationTerm : equationSystem.getEquationTerms(element.getType(), element.getNum())) {
if (equationTerm.isActive() != enable) {
equationTerm.setActive(enable);
// update all equation terms related to the element
for (var equationTerm : equationSystem.getEquationTerms(element.getType(), element.getNum())) {
if (equationTerm.isActive() != enable) {
equationTerm.setActive(enable);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ public enum AcEquationType implements Quantity {
ZERO_V("zero_v", ElementType.BRANCH), // zero impedance branch, voltage magnitude equality
ZERO_PHI("zero_\u03C6", ElementType.BRANCH), // zero impedance branch, voltage angle equality
DISTR_RHO("distr_\u03C1", ElementType.BRANCH), // remote transformer voltage control ratio distribution
DISTR_SHUNT_B("distr_b", ElementType.SHUNT_COMPENSATOR); // shunt remote voltage control susceptance distribution
DISTR_SHUNT_B("distr_b", ElementType.SHUNT_COMPENSATOR), // shunt remote voltage control susceptance distribution
DUMMY_TARGET_P("dummy_target_p", ElementType.BRANCH),
DUMMY_TARGET_Q("dummy_target_q", ElementType.BRANCH);

private final String symbol;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ public static void init(Equation<AcVariableType, AcEquationType> equation, LfNet

case DISTR_RHO:
case DISTR_SHUNT_B:
case DUMMY_TARGET_P:
case DUMMY_TARGET_Q:
targets[equation.getColumn()] = 0;
break;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* 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;

import com.powsybl.commons.reporter.Reporter;
import com.powsybl.iidm.network.Network;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.math.matrix.DenseMatrixFactory;
import com.powsybl.openloadflow.OpenLoadFlowParameters;
import com.powsybl.openloadflow.ac.outerloop.AcLoadFlowContext;
import com.powsybl.openloadflow.ac.outerloop.AcLoadFlowParameters;
import com.powsybl.openloadflow.ac.outerloop.AcloadFlowEngine;
import com.powsybl.openloadflow.graph.EvenShiloachGraphDecrementalConnectivityFactory;
import com.powsybl.openloadflow.network.LfNetwork;
import com.powsybl.openloadflow.network.NameSlackBusSelector;
import com.powsybl.openloadflow.network.NodeBreakerNetworkFactory;
import com.powsybl.openloadflow.network.impl.LfNetworkLoaderImpl;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

/**
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
*/
class NonImpedantBranchDisablingTest {

@Test
void test() {
Network network = NodeBreakerNetworkFactory.create();
network.getSwitch("B3").setRetained(false);
network.getSwitch("C").setRetained(true);
AcLoadFlowParameters parameters = OpenLoadFlowParameters.createAcParameters(new LoadFlowParameters(),
new OpenLoadFlowParameters(),
new DenseMatrixFactory(),
new EvenShiloachGraphDecrementalConnectivityFactory<>(),
Reporter.NO_OP,
true,
false);
parameters.getNetworkParameters().setSlackBusSelector(new NameSlackBusSelector("VL1_1"));
LfNetwork lfNetwork = LfNetwork.load(network, new LfNetworkLoaderImpl(), parameters.getNetworkParameters()).get(0);

try (AcLoadFlowContext context = new AcLoadFlowContext(lfNetwork, parameters)) {
var engine = new AcloadFlowEngine(context);
engine.run();
assertEquals(8, context.getEquationSystem().getSortedVariablesToFind().size());
var l1 = lfNetwork.getBranchById("L1");
var l2 = lfNetwork.getBranchById("L2");
assertEquals(3.01884, l1.getP1().eval(), 10e-5);
assertEquals(3.01884, l2.getP1().eval(), 10e-5);

lfNetwork.getBranchById("C").setDisabled(true);

engine.run();
assertEquals(8, context.getEquationSystem().getSortedVariablesToFind().size()); // we have kept same variables!!!
assertEquals(0, l1.getP1().eval(), 10e-5);
assertEquals(6.07782, l2.getP1().eval(), 10e-5);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import com.powsybl.computation.ComputationManager;
import com.powsybl.contingency.*;
import com.powsybl.ieeecdf.converter.IeeeCdfNetworkFactory;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.LoadDetailAdder;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
Expand Down Expand Up @@ -1234,4 +1235,18 @@ void testViolationsWeakenedOrEquivalent() {

assertFalse(AbstractSecurityAnalysis.violationWeakenedOrEquivalent(violation1, violation4, violationsParameters));
}

@Test
void testWithNonImpedendantLineConnectedToSlackBus() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Impedendant?

Network network = IeeeCdfNetworkFactory.create14();
network.getLine("L1-2-1").setR(0).setX(0);
network.getLine("L4-5-1").setR(0).setX(0);

List<Contingency> contingencies = allBranches(network);

List<StateMonitor> monitors = Collections.emptyList();

SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors);
assertEquals(20, result.getPostContingencyResults().size()); // assert there is no contingency simulation failure
}
}