EquationSystemTest.java
/**
* Copyright (c) 2019, 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.openloadflow.equations;
import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.Line;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
import com.powsybl.openloadflow.ac.AcTargetVector;
import com.powsybl.openloadflow.ac.equations.AcEquationSystemCreator;
import com.powsybl.openloadflow.ac.equations.AcEquationType;
import com.powsybl.openloadflow.ac.equations.AcVariableType;
import com.powsybl.openloadflow.ac.solver.AcSolverUtil;
import com.powsybl.openloadflow.ac.solver.NewtonRaphson;
import com.powsybl.openloadflow.dc.equations.*;
import com.powsybl.openloadflow.network.*;
import com.powsybl.openloadflow.network.impl.Networks;
import com.powsybl.openloadflow.network.util.UniformValueVoltageInitializer;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
class EquationSystemTest {
private final List<Equation<AcVariableType, AcEquationType>> equations = new ArrayList<>();
private final List<EquationEventType> equationEventTypes = new ArrayList<>();
private final List<EquationTermEventType> equationTermEventTypes = new ArrayList<>();
private void clearEvents() {
equations.clear();
equationEventTypes.clear();
equationTermEventTypes.clear();
}
@Test
void test() {
List<LfNetwork> lfNetworks = Networks.load(EurostagTutorialExample1Factory.create(), new FirstSlackBusSelector());
LfNetwork network = lfNetworks.get(0);
LfBus bus = network.getBus(0);
EquationSystem<AcVariableType, AcEquationType> equationSystem = new EquationSystem<>();
equationSystem.addListener(new EquationSystemListener<>() {
@Override
public void onEquationChange(Equation<AcVariableType, AcEquationType> equation, EquationEventType eventType) {
equations.add(equation);
equationEventTypes.add(eventType);
}
@Override
public void onEquationTermChange(EquationTerm<AcVariableType, AcEquationType> term, EquationTermEventType eventType) {
equationTermEventTypes.add(eventType);
}
});
assertTrue(equations.isEmpty());
assertTrue(equationEventTypes.isEmpty());
assertTrue(equationSystem.getIndex().getSortedEquationsToSolve().isEmpty());
equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_TARGET_V).addTerm(equationSystem.getVariable(bus.getNum(), AcVariableType.BUS_V).createTerm());
assertEquals(1, equations.size());
assertEquals(1, equationEventTypes.size());
assertEquals(1, equationTermEventTypes.size());
assertEquals(EquationEventType.EQUATION_CREATED, equationEventTypes.get(0));
assertEquals(EquationTermEventType.EQUATION_TERM_ADDED, equationTermEventTypes.get(0));
assertEquals(1, equationSystem.getIndex().getSortedEquationsToSolve().size());
clearEvents();
equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_TARGET_V).setActive(true);
assertTrue(equations.isEmpty());
assertTrue(equationEventTypes.isEmpty());
equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_TARGET_V).setActive(false);
assertEquals(1, equations.size());
assertEquals(1, equationEventTypes.size());
assertEquals(EquationEventType.EQUATION_DEACTIVATED, equationEventTypes.get(0));
assertTrue(equationSystem.getIndex().getSortedEquationsToSolve().isEmpty());
clearEvents();
equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_TARGET_V).setActive(true);
assertEquals(1, equations.size());
assertEquals(1, equationEventTypes.size());
assertEquals(EquationEventType.EQUATION_ACTIVATED, equationEventTypes.get(0));
assertEquals(1, equationSystem.getIndex().getSortedEquationsToSolve().size());
assertTrue(equationSystem.getEquation(bus.getNum(), AcEquationType.BUS_TARGET_V).isPresent());
assertEquals(1, equationSystem.getEquations(ElementType.BUS, bus.getNum()).size());
assertFalse(equationSystem.getEquation(99, AcEquationType.BUS_TARGET_V).isPresent());
assertTrue(equationSystem.getEquations(ElementType.BUS, 99).isEmpty());
assertEquals(1, equationSystem.getEquationTerms(ElementType.BUS, bus.getNum()).size());
assertTrue(equationSystem.getEquationTerms(ElementType.BRANCH, 0).isEmpty());
clearEvents();
EquationTerm<AcVariableType, AcEquationType> equationTerm = equationSystem.getVariable(bus.getNum(), AcVariableType.BUS_V)
.createTerm();
bus.setCalculatedV(equationTerm);
equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_TARGET_V).addTerm(equationTerm);
assertEquals(2, equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_TARGET_V).getTerms().size());
assertEquals(0, equations.size());
assertEquals(0, equationEventTypes.size());
assertEquals(1, equationTermEventTypes.size());
assertEquals(EquationTermEventType.EQUATION_TERM_ADDED, equationTermEventTypes.get(0));
clearEvents();
equationTerm.setActive(false);
assertEquals(0, equations.size());
assertEquals(0, equationEventTypes.size());
assertEquals(1, equationTermEventTypes.size());
assertEquals(EquationTermEventType.EQUATION_TERM_DEACTIVATED, equationTermEventTypes.get(0));
assertEquals(1, equationSystem.getVariableSet().getVariables().size());
}
@Test
void writeAcSystemTest() {
List<LfNetwork> lfNetworks = Networks.load(EurostagTutorialExample1Factory.create(), new FirstSlackBusSelector());
LfNetwork network = lfNetworks.get(0);
EquationSystem<AcVariableType, AcEquationType> equationSystem = new AcEquationSystemCreator(network).create();
String ref = String.join(System.lineSeparator(),
"bus_target_v0 = v0",
"bus_target_��0 = ��0",
"bus_target_p1 = ac_p_closed_2(v0, v1, ��0, ��1) + ac_p_closed_1(v1, v2, ��1, ��2) + ac_p_closed_1(v1, v2, ��1, ��2)",
"bus_target_q1 = ac_q_closed_2(v0, v1, ��0, ��1) + ac_q_closed_1(v1, v2, ��1, ��2) + ac_q_closed_1(v1, v2, ��1, ��2)",
"bus_target_p2 = ac_p_closed_2(v1, v2, ��1, ��2) + ac_p_closed_2(v1, v2, ��1, ��2) + ac_p_closed_1(v2, v3, ��2, ��3)",
"bus_target_q2 = ac_q_closed_2(v1, v2, ��1, ��2) + ac_q_closed_2(v1, v2, ��1, ��2) + ac_q_closed_1(v2, v3, ��2, ��3)",
"bus_target_p3 = ac_p_closed_2(v2, v3, ��2, ��3)",
"bus_target_q3 = ac_q_closed_2(v2, v3, ��2, ��3)")
+ System.lineSeparator();
assertEquals(ref, equationSystem.writeToString());
}
@Test
void writeAllEquationsAcSystemTest() {
List<LfNetwork> lfNetworks = Networks.load(EurostagTutorialExample1Factory.create(), new FirstSlackBusSelector());
LfNetwork network = lfNetworks.get(0);
EquationSystem<AcVariableType, AcEquationType> equationSystem = new AcEquationSystemCreator(network).create();
// just to test inactive term writing
for (var equationTerm : equationSystem.getEquationTerms(ElementType.BRANCH, network.getBranchById("NHV1_NHV2_1").getNum())) {
equationTerm.setActive(false);
}
String ref = String.join(System.lineSeparator(),
"[ bus_target_p0 = ac_p_closed_1(v0, v1, ��0, ��1) ]",
"[ bus_target_q0 = ac_q_closed_1(v0, v1, ��0, ��1) ]",
"bus_target_v0 = v0",
"bus_target_��0 = ��0",
"bus_target_p1 = ac_p_closed_2(v0, v1, ��0, ��1) + [ ac_p_closed_1(v1, v2, ��1, ��2) ] + ac_p_closed_1(v1, v2, ��1, ��2)",
"bus_target_q1 = ac_q_closed_2(v0, v1, ��0, ��1) + [ ac_q_closed_1(v1, v2, ��1, ��2) ] + ac_q_closed_1(v1, v2, ��1, ��2)",
"[ bus_target_v1 = v1 ]",
"bus_target_p2 = [ ac_p_closed_2(v1, v2, ��1, ��2) ] + ac_p_closed_2(v1, v2, ��1, ��2) + ac_p_closed_1(v2, v3, ��2, ��3)",
"bus_target_q2 = [ ac_q_closed_2(v1, v2, ��1, ��2) ] + ac_q_closed_2(v1, v2, ��1, ��2) + ac_q_closed_1(v2, v3, ��2, ��3)",
"[ bus_target_v2 = v2 ]",
"bus_target_p3 = ac_p_closed_2(v2, v3, ��2, ��3)",
"bus_target_q3 = ac_q_closed_2(v2, v3, ��2, ��3)",
"[ bus_target_v3 = v3 ]")
+ System.lineSeparator();
assertEquals(ref, equationSystem.writeToString(true));
}
@Test
void writeDcSystemTest() {
List<LfNetwork> lfNetworks = Networks.load(EurostagTutorialExample1Factory.create(), new FirstSlackBusSelector());
LfNetwork network = lfNetworks.get(0);
EquationSystem<DcVariableType, DcEquationType> equationSystem = new DcEquationSystemCreator(network).create(false);
String ref = String.join(System.lineSeparator(),
"bus_target_��0 = ��0",
"bus_target_p1 = dc_p_2(��0, ��1) + dc_p_1(��1, ��2) + dc_p_1(��1, ��2)",
"bus_target_p2 = dc_p_2(��1, ��2) + dc_p_2(��1, ��2) + dc_p_1(��2, ��3)",
"bus_target_p3 = dc_p_2(��2, ��3)")
+ System.lineSeparator();
assertEquals(ref, equationSystem.writeToString());
}
@Test
void findLargestMismatchesTest() {
Network network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
List<LfNetwork> lfNetworks = Networks.load(network, new FirstSlackBusSelector());
LfNetwork mainNetwork = lfNetworks.get(0);
EquationSystem<AcVariableType, AcEquationType> equationSystem = new AcEquationSystemCreator(mainNetwork).create();
AcSolverUtil.initStateVector(mainNetwork, equationSystem, new UniformValueVoltageInitializer());
double[] targets = TargetVector.createArray(mainNetwork, equationSystem, AcTargetVector::init);
try (var equationVector = new EquationVector<>(equationSystem)) {
Vectors.minus(equationVector.getArray(), targets);
var largestMismatches = NewtonRaphson.findLargestMismatches(equationSystem, equationVector.getArray(), 3);
assertEquals(3, largestMismatches.size());
assertEquals(-7.397518453004565, largestMismatches.get(0).getValue(), 0);
assertEquals(5.999135514403292, largestMismatches.get(1).getValue(), 0);
assertEquals(1.9259062775721603, largestMismatches.get(2).getValue(), 0);
}
}
@Test
void currentMagnitudeTest() {
Network network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
List<LfNetwork> lfNetworks = Networks.load(network, new FirstSlackBusSelector());
LfNetwork mainNetwork = lfNetworks.get(0);
EquationSystem<AcVariableType, AcEquationType> equationSystem = new AcEquationSystemCreator(mainNetwork).create();
AcSolverUtil.initStateVector(mainNetwork, equationSystem, new UniformValueVoltageInitializer());
LfBranch branch = mainNetwork.getBranchById("NHV1_NHV2_1");
EquationTerm<AcVariableType, AcEquationType> i1 = (EquationTerm<AcVariableType, AcEquationType>) branch.getI1();
EquationTerm<AcVariableType, AcEquationType> i2 = (EquationTerm<AcVariableType, AcEquationType>) branch.getI2();
Variable<AcVariableType> v1var = equationSystem.getVariableSet().getVariable(branch.getBus1().getNum(), AcVariableType.BUS_V);
Variable<AcVariableType> v2var = equationSystem.getVariableSet().getVariable(branch.getBus2().getNum(), AcVariableType.BUS_V);
Variable<AcVariableType> ph1var = equationSystem.getVariableSet().getVariable(branch.getBus1().getNum(), AcVariableType.BUS_PHI);
Variable<AcVariableType> ph2var = equationSystem.getVariableSet().getVariable(branch.getBus2().getNum(), AcVariableType.BUS_PHI);
assertEquals(-43.120215, i1.der(v1var), 10E-6);
assertEquals(43.398907, i1.der(v2var), 10E-6);
assertEquals(3.945355, i1.der(ph1var), 10E-6);
assertEquals(-3.945355, i1.der(ph2var), 10E-6);
assertEquals(43.398907, i2.der(v1var), 10E-6);
assertEquals(-43.120215, i2.der(v2var), 10E-6);
assertEquals(-3.945355, i2.der(ph1var), 10E-6);
assertEquals(3.945355, i2.der(ph2var), 10E-6);
}
@Test
void currentMagnitudeOpenBranchSide2Test() {
Network network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
Line line1 = network.getLine("NHV1_NHV2_1");
line1.getTerminal2().disconnect();
List<LfNetwork> lfNetworks = Networks.load(network, new FirstSlackBusSelector());
LfNetwork mainNetwork = lfNetworks.get(0);
EquationSystem<AcVariableType, AcEquationType> equationSystem = new AcEquationSystemCreator(mainNetwork).create();
AcSolverUtil.initStateVector(mainNetwork, equationSystem, new UniformValueVoltageInitializer());
LfBranch branch = mainNetwork.getBranchById("NHV1_NHV2_1");
EquationTerm<AcVariableType, AcEquationType> i1 = (EquationTerm<AcVariableType, AcEquationType>) branch.getI1();
Variable<AcVariableType> v1var = equationSystem.getVariableSet().getVariable(branch.getBus1().getNum(), AcVariableType.BUS_V);
Variable<AcVariableType> ph1var = equationSystem.getVariableSet().getVariable(branch.getBus1().getNum(), AcVariableType.BUS_PHI);
assertEquals(0.559170, i1.der(v1var), 10E-6);
assertThrows(IllegalArgumentException.class, () -> i1.der(ph1var));
}
@Test
void currentMagnitudeOpenBranchSide1Test() {
Network network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
Line line1 = network.getLine("NHV1_NHV2_1");
line1.getTerminal1().disconnect();
List<LfNetwork> lfNetworks = Networks.load(network, new FirstSlackBusSelector());
LfNetwork mainNetwork = lfNetworks.get(0);
EquationSystem<AcVariableType, AcEquationType> equationSystem = new AcEquationSystemCreator(mainNetwork).create();
AcSolverUtil.initStateVector(mainNetwork, equationSystem, new UniformValueVoltageInitializer());
LfBranch branch = mainNetwork.getBranchById("NHV1_NHV2_1");
EquationTerm<AcVariableType, AcEquationType> i2 = (EquationTerm<AcVariableType, AcEquationType>) branch.getI2();
Variable<AcVariableType> v2var = equationSystem.getVariableSet().getVariable(branch.getBus2().getNum(), AcVariableType.BUS_V);
Variable<AcVariableType> ph2var = equationSystem.getVariableSet().getVariable(branch.getBus2().getNum(), AcVariableType.BUS_PHI);
assertEquals(0.55917, i2.der(v2var), 10E-6);
assertThrows(IllegalArgumentException.class, () -> i2.der(ph2var));
}
@Test
void removeEquationTest() {
Network network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
List<LfNetwork> lfNetworks = Networks.load(network, new FirstSlackBusSelector());
LfNetwork mainNetwork = lfNetworks.get(0);
EquationSystem<AcVariableType, AcEquationType> equationSystem = new AcEquationSystemCreator(mainNetwork)
.create();
assertEquals(13, equationSystem.getEquations().size());
assertEquals(3, equationSystem.getEquations(ElementType.BUS, 1).size());
assertEquals(4, equationSystem.getEquationTerms(ElementType.BRANCH, 0).size());
assertEquals(4, equationSystem.getEquationTerms(ElementType.BRANCH, 1).size());
assertEquals(4, equationSystem.getEquationTerms(ElementType.BRANCH, 2).size());
assertEquals(4, equationSystem.getEquationTerms(ElementType.BRANCH, 3).size());
equationSystem.removeEquation(1, AcEquationType.BUS_TARGET_P);
assertEquals(12, equationSystem.getEquations().size());
assertEquals(2, equationSystem.getEquations(ElementType.BUS, 1).size());
assertEquals(3, equationSystem.getEquationTerms(ElementType.BRANCH, 0).size());
assertEquals(3, equationSystem.getEquationTerms(ElementType.BRANCH, 1).size());
assertEquals(3, equationSystem.getEquationTerms(ElementType.BRANCH, 2).size());
assertEquals(4, equationSystem.getEquationTerms(ElementType.BRANCH, 3).size());
}
@Test
void removeEquationIllegalAccessTest() {
Network network = EurostagFactory.fix(EurostagTutorialExample1Factory.create());
List<LfNetwork> lfNetworks = Networks.load(network, new FirstSlackBusSelector());
LfNetwork mainNetwork = lfNetworks.get(0);
EquationSystem<AcVariableType, AcEquationType> equationSystem = new AcEquationSystemCreator(mainNetwork)
.create();
var removedEq = equationSystem.removeEquation(1, AcEquationType.BUS_TARGET_P);
assertThrows(PowsyblException.class, () -> removedEq.setActive(false));
}
}