com.powsybl.openloadflow.equations.EquationSystem Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of powsybl-open-loadflow Show documentation
Show all versions of powsybl-open-loadflow Show documentation
An open source loadflow based on PowSyBl
The newest version!
/**
* 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.openloadflow.network.ElementType;
import com.powsybl.openloadflow.network.LfElement;
import com.powsybl.openloadflow.network.LfNetwork;
import org.apache.commons.lang3.tuple.Pair;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UncheckedIOException;
import java.io.Writer;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Geoffroy Jamgotchian {@literal }
*/
public class EquationSystem & Quantity, E extends Enum & Quantity> {
private final Map, Equation> equations = new HashMap<>();
private final Map, List>> equationsByElement = new HashMap<>();
private Map, List>> equationTermsByElement;
private final List> listeners = new ArrayList<>();
private final VariableSet variableSet;
private final StateVector stateVector = new StateVector();
private final EquationSystemIndex index;
public EquationSystem() {
this(new VariableSet<>());
}
public EquationSystem(VariableSet variableSet) {
this.variableSet = Objects.requireNonNull(variableSet);
index = new EquationSystemIndex<>(this);
}
public VariableSet getVariableSet() {
return variableSet;
}
public Variable getVariable(int elementNum, V type) {
return variableSet.getVariable(elementNum, type);
}
public StateVector getStateVector() {
return stateVector;
}
public EquationSystemIndex getIndex() {
return index;
}
public Collection> getEquations() {
return equations.values();
}
private void indexTerm(EquationTerm equationTerm) {
if (equationTermsByElement != null) {
if (equationTerm.getElementType() != null && equationTerm.getElementNum() != -1) {
Pair element = Pair.of(equationTerm.getElementType(), equationTerm.getElementNum());
equationTermsByElement.computeIfAbsent(element, k -> new ArrayList<>())
.add(equationTerm);
}
for (EquationTerm child : equationTerm.getChildren()) {
indexTerm(child);
}
}
}
private void indexAllTerms() {
if (equationTermsByElement == null) {
equationTermsByElement = new HashMap<>();
for (var equation : equations.values()) {
for (var term : equation.getTerms()) {
indexTerm(term);
}
}
}
}
void addEquationTerm(EquationTerm equationTerm) {
indexTerm(equationTerm);
attach(equationTerm);
}
public List> getEquationTerms(ElementType elementType, int elementNum) {
Objects.requireNonNull(elementType);
indexAllTerms();
Pair element = Pair.of(elementType, elementNum);
return equationTermsByElement.getOrDefault(element, Collections.emptyList());
}
public > T getEquationTerm(ElementType elementType, int elementNum, Class clazz) {
return getEquationTerms(elementType, elementNum)
.stream()
.filter(term -> clazz.isAssignableFrom(term.getClass()))
.map(clazz::cast)
.findFirst()
.orElseThrow(() -> new PowsyblException("Equation term not found"));
}
public Equation createEquation(LfElement element, E type) {
Objects.requireNonNull(element);
Objects.requireNonNull(type);
if (element.getType() != type.getElementType()) {
throw new PowsyblException("Incorrect equation type: " + type);
}
Pair p = Pair.of(element.getNum(), type);
Equation equation = equations.get(p);
if (equation == null) {
equation = addEquation(p)
.setActive(!element.isDisabled());
}
return equation;
}
public Equation createEquation(int num, E type) {
Pair p = Pair.of(num, type);
Equation equation = equations.get(p);
if (equation == null) {
equation = addEquation(p);
}
return equation;
}
public Optional> getEquation(int num, E type) {
Pair p = Pair.of(num, type);
return Optional.ofNullable(equations.get(p));
}
public boolean hasEquation(int num, E type) {
Pair p = Pair.of(num, type);
return equations.containsKey(p);
}
private void deindexTerm(EquationTerm term) {
if (term.getElementType() != null && term.getElementNum() != -1) {
List> termsForThisElement = equationTermsByElement.get(Pair.of(term.getElementType(), term.getElementNum()));
if (termsForThisElement != null) {
termsForThisElement.remove(term);
}
}
for (EquationTerm child : term.getChildren()) {
deindexTerm(child);
}
}
public Equation removeEquation(int num, E type) {
Pair p = Pair.of(num, type);
Equation equation = equations.remove(p);
if (equation != null) {
Pair element = Pair.of(type.getElementType(), num);
equationsByElement.get(element).remove(equation);
if (equationTermsByElement != null) {
for (EquationTerm term : equation.getTerms()) {
deindexTerm(term);
}
}
equation.setRemoved(); // to ensure it is not used anymore
notifyEquationChange(equation, EquationEventType.EQUATION_REMOVED);
}
return equation;
}
private Equation addEquation(Pair p) {
Equation equation = new Equation<>(p.getLeft(), p.getRight(), EquationSystem.this);
equations.put(p, equation);
Pair element = Pair.of(p.getRight().getElementType(), p.getLeft());
equationsByElement.computeIfAbsent(element, k -> new ArrayList<>())
.add(equation);
notifyEquationChange(equation, EquationEventType.EQUATION_CREATED);
return equation;
}
public List> getEquations(ElementType elementType, int elementNum) {
Objects.requireNonNull(elementType);
Pair element = Pair.of(elementType, elementNum);
return equationsByElement.getOrDefault(element, Collections.emptyList());
}
public void attach(EquationTerm term) {
Objects.requireNonNull(term);
term.setStateVector(stateVector);
}
public List getRowNames(LfNetwork network) {
return index.getSortedVariablesToFind().stream()
.map(eq -> network.getBus(eq.getElementNum()).getId() + "/" + eq.getType())
.collect(Collectors.toList());
}
public List getColumnNames(LfNetwork network) {
return index.getSortedEquationsToSolve().stream()
.map(v -> network.getBus(v.getElementNum()).getId() + "/" + v.getType())
.collect(Collectors.toList());
}
public void addListener(EquationSystemListener listener) {
Objects.requireNonNull(listener);
listeners.add(listener);
}
public void removeListener(EquationSystemListener listener) {
listeners.remove(listener);
}
void notifyEquationChange(Equation equation, EquationEventType eventType) {
Objects.requireNonNull(equation);
Objects.requireNonNull(eventType);
listeners.forEach(listener -> listener.onEquationChange(equation, eventType));
}
void notifyEquationTermChange(EquationTerm term, EquationTermEventType eventType) {
Objects.requireNonNull(term);
Objects.requireNonNull(eventType);
listeners.forEach(listener -> listener.onEquationTermChange(term, eventType));
}
public void write(Writer writer, boolean writeInactiveEquations) {
try {
for (Equation equation : equations.values().stream().sorted().collect(Collectors.toList())) {
if (writeInactiveEquations || equation.isActive()) {
if (!equation.isActive()) {
writer.write("[ ");
}
equation.write(writer, writeInactiveEquations);
if (!equation.isActive()) {
writer.write(" ]");
}
writer.write(System.lineSeparator());
}
}
writer.flush();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public String writeToString(boolean writeInactiveEquations) {
try (StringWriter writer = new StringWriter()) {
write(writer, writeInactiveEquations);
writer.flush();
return writer.toString();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public String writeToString() {
return writeToString(false);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy