com.powsybl.flow_decomposition.FlowDecompositionResults Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of powsybl-flow-decomposition Show documentation
Show all versions of powsybl-flow-decomposition Show documentation
Implementation of ACER methodology for flow decomposition
The newest version!
/*
* 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.flow_decomposition;
import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescaler;
import com.powsybl.iidm.network.*;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.powsybl.flow_decomposition.DecomposedFlow.ALLOCATED_COLUMN_NAME;
import static com.powsybl.flow_decomposition.DecomposedFlow.NO_FLOW;
import static com.powsybl.flow_decomposition.DecomposedFlow.PST_COLUMN_NAME;
import static com.powsybl.flow_decomposition.DecomposedFlow.XNODE_COLUMN_NAME;
import static com.powsybl.flow_decomposition.NetworkUtil.LOOP_FLOWS_COLUMN_PREFIX;
/**
* This class provides flow decomposition results from a network.
* Those results are returned by a flowDecompositionComputer when run on a network.
*
* @author Sebastien Murgey {@literal }
* @author Hugo Schindler {@literal }
* @see FlowDecompositionComputer
* @see DecomposedFlow
*/
public class FlowDecompositionResults {
private static final String NO_CONTINGENCY_ID = "";
private final String networkId;
private final String id;
private final Set zoneSet;
private final Map decomposedFlowMap = new HashMap<>();
class PerStateBuilder {
private final Map xnecMap;
private final String contingencyId;
private SparseMatrixWithIndexesCSC allocatedAndLoopFlowsMatrix;
private Map> pstFlowMap;
private Map acTerminal1ReferenceFlow;
private Map acTerminal2ReferenceFlow;
private Map acCurrentTerminal1;
private Map acCurrentTerminal2;
private Map dcReferenceFlow;
PerStateBuilder(String contingencyId, Set xnecList) {
this.xnecMap = xnecList.stream().collect(Collectors.toMap(Identifiable::getId, Function.identity()));
this.contingencyId = contingencyId;
}
void saveAllocatedAndLoopFlowsMatrix(SparseMatrixWithIndexesCSC allocatedAndLoopFlowsMatrix) {
this.allocatedAndLoopFlowsMatrix = allocatedAndLoopFlowsMatrix;
}
void savePstFlowMatrix(SparseMatrixWithIndexesCSC pstFlowMatrix) {
this.pstFlowMap = pstFlowMatrix.toMap();
}
void saveAcTerminal1ReferenceFlow(Map acTerminal1ReferenceFlow) {
this.acTerminal1ReferenceFlow = acTerminal1ReferenceFlow;
}
void saveAcTerminal2ReferenceFlow(Map acTerminal2ReferenceFlow) {
this.acTerminal2ReferenceFlow = acTerminal2ReferenceFlow;
}
void saveAcCurrentTerminal1(Map acTerminal1Current) {
this.acCurrentTerminal1 = acTerminal1Current;
}
void saveAcCurrentTerminal2(Map acTerminal2Current) {
this.acCurrentTerminal2 = acTerminal2Current;
}
void saveDcReferenceFlow(Map dcReferenceFlow) {
this.dcReferenceFlow = dcReferenceFlow;
}
void build(DecomposedFlowRescaler decomposedFlowRescaler, Network network) {
allocatedAndLoopFlowsMatrix.toMap()
.forEach((branchId, decomposedFlow) -> {
String xnecId = DecomposedFlow.getXnecId(contingencyId, branchId);
decomposedFlowMap.put(xnecId, createDecomposedFlow(branchId, decomposedFlow, decomposedFlowRescaler, network));
});
}
private DecomposedFlow createDecomposedFlow(String branchId, Map allocatedAndLoopFlowMap, DecomposedFlowRescaler decomposedFlowRescaler, Network network) {
Map loopFlowsMap = allocatedAndLoopFlowMap.entrySet().stream()
.filter(entry -> entry.getKey().startsWith(LOOP_FLOWS_COLUMN_PREFIX))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
double allocatedFlow = allocatedAndLoopFlowMap.get(ALLOCATED_COLUMN_NAME);
double pstFlow = pstFlowMap.getOrDefault(branchId, Collections.emptyMap()).getOrDefault(PST_COLUMN_NAME, NO_FLOW);
double xNodeFlow = allocatedAndLoopFlowMap.getOrDefault(XNODE_COLUMN_NAME, NO_FLOW);
Country country1 = NetworkUtil.getTerminalCountry(xnecMap.get(branchId).getTerminal1());
Country country2 = NetworkUtil.getTerminalCountry(xnecMap.get(branchId).getTerminal2());
double internalFlow = extractInternalFlow(loopFlowsMap, country1, country2);
DecomposedFlow decomposedFlow = new DecomposedFlowBuilder()
.withBranchId(branchId)
.withContingencyId(contingencyId)
.withCountry1(country1)
.withCountry2(country2)
.withAcTerminal1ReferenceFlow(acTerminal1ReferenceFlow.get(branchId))
.withAcTerminal2ReferenceFlow(acTerminal2ReferenceFlow.get(branchId))
.withDcReferenceFlow(dcReferenceFlow.get(branchId))
.withAcCurrentTerminal1(acCurrentTerminal1.get(branchId))
.withAcCurrentTerminal2(acCurrentTerminal2.get(branchId))
.withAllocatedFlow(allocatedFlow)
.withXNodeFlow(xNodeFlow)
.withPstFlow(pstFlow)
.withInternalFlow(internalFlow)
.withLoopFlowsMap(loopFlowsMap)
.build();
return decomposedFlowRescaler.rescale(decomposedFlow, network);
}
private double extractInternalFlow(Map loopFlowsMap, Country country1, Country country2) {
if (Objects.equals(country1, country2)) {
return Optional.ofNullable(loopFlowsMap.remove(NetworkUtil.getLoopFlowIdFromCountry(country1)))
.orElse(NO_FLOW);
}
return NO_FLOW;
}
}
FlowDecompositionResults(Network network) {
Date date = Date.from(Instant.now());
String dateString = new SimpleDateFormat("yyyyMMdd-HHmmss").format(date);
this.networkId = network.getNameOrId();
this.id = "Flow_Decomposition_Results_of_" + dateString + "_on_network_" + networkId;
this.zoneSet = network.getCountries();
}
/**
* @return Network Id
*/
public String getNetworkId() {
return networkId;
}
/**
* @return Id composed of a time format and the network id.
*/
public String getId() {
return id;
}
/**
* @return the set of available zones in this result
*/
public Set getZoneSet() {
return zoneSet;
}
/**
* @return A rescaled flow decomposition map. The keys are the XNEC and the values are {@code DecomposedFlow} objects.
*/
public Map getDecomposedFlowMap() {
return decomposedFlowMap;
}
PerStateBuilder getBuilder(String contingencyId, Set xnecList) {
return new PerStateBuilder(contingencyId, xnecList);
}
public PerStateBuilder getBuilder(Set xnecList) {
return new PerStateBuilder(NO_CONTINGENCY_ID, xnecList);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy