From 2d9cf289ba5406d3f0c68f26c662f7a907fbdfd9 Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Wed, 22 May 2024 16:03:14 +0200 Subject: [PATCH 01/13] Replace rescaleEnabled by rescaleMode Signed-off-by: Caio Luke --- .../AcReferenceFlowComputer.java | 30 --------- .../flow_decomposition/DecomposedFlow.java | 8 ++- .../DecomposedFlowsRescaler.java | 56 ++++++++++++----- .../flow_decomposition/FlowComputerUtils.java | 62 +++++++++++++++++++ .../FlowDecompositionComputer.java | 16 ++--- .../FlowDecompositionObserverList.java | 8 +-- .../FlowDecompositionParameters.java | 25 +++++--- .../FlowDecompositionResults.java | 20 +++--- .../ReferenceFlowComputer.java | 32 ---------- .../AllocatedFlowTests.java | 4 +- .../CgmesIntegrationTests.java | 4 +- .../FlowDecompositionParametersTests.java | 8 +-- .../FlowDecompositionResultsTests.java | 9 ++- ...FlowDecompositionWithContingencyTests.java | 16 ++--- .../flow_decomposition/InternalFlowTests.java | 4 +- .../flow_decomposition/LoopFlowTests.java | 2 +- .../flow_decomposition/PstFlowTests.java | 4 +- .../flow_decomposition/RescalingTests.java | 25 +++++--- .../powsybl/flow_decomposition/TestUtils.java | 10 +-- .../flow_decomposition/XnodeFlowTests.java | 4 +- 20 files changed, 202 insertions(+), 145 deletions(-) delete mode 100644 flow-decomposition/src/main/java/com/powsybl/flow_decomposition/AcReferenceFlowComputer.java create mode 100644 flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowComputerUtils.java delete mode 100644 flow-decomposition/src/main/java/com/powsybl/flow_decomposition/ReferenceFlowComputer.java diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/AcReferenceFlowComputer.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/AcReferenceFlowComputer.java deleted file mode 100644 index cb342b82..00000000 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/AcReferenceFlowComputer.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/) - * 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.flow_decomposition; - -import com.powsybl.iidm.network.Branch; -import com.powsybl.iidm.network.Identifiable; - -import java.util.Collection; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * @author Guillaume Verger {@literal } - */ -class AcReferenceFlowComputer { - private static ReferenceFlowComputer flowComputer = new ReferenceFlowComputer(); - - Map run(Collection xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) { - if (loadFlowServiceAcResult.fallbackHasBeenActivated()) { - return xnecList.stream().collect(Collectors.toMap(Identifiable::getId, branch -> Double.NaN)); - } - - return flowComputer.run(xnecList); - } -} diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java index 6fbe1aec..d9df85cf 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java @@ -20,6 +20,7 @@ public class DecomposedFlow { private final Country country1; private final Country country2; private final double acReferenceFlow; + private final double acMaxFlow; private final double dcReferenceFlow; private final double allocatedFlow; private final double xNodeFlow; @@ -34,12 +35,13 @@ public class DecomposedFlow { static final String PST_COLUMN_NAME = "PST Flow"; static final String INTERNAL_COLUMN_NAME = "Internal Flow"; - protected DecomposedFlow(String branchId, String contingencyId, Country country1, Country country2, double acReferenceFlow, double dcReferenceFlow, double allocatedFlow, double xNodeFlow, double pstFlow, double internalFlow, Map loopFlowsMap) { + protected DecomposedFlow(String branchId, String contingencyId, Country country1, Country country2, double acReferenceFlow, double acMaxFlow, double dcReferenceFlow, double allocatedFlow, double xNodeFlow, double pstFlow, double internalFlow, Map loopFlowsMap) { this.branchId = branchId; this.contingencyId = contingencyId; this.country1 = country1; this.country2 = country2; this.acReferenceFlow = acReferenceFlow; + this.acMaxFlow = acMaxFlow; this.dcReferenceFlow = dcReferenceFlow; this.allocatedFlow = allocatedFlow; this.xNodeFlow = xNodeFlow; @@ -72,6 +74,10 @@ public double getAcReferenceFlow() { return acReferenceFlow; } + public double getAcMaxFlow() { + return acMaxFlow; + } + public double getDcReferenceFlow() { return dcReferenceFlow; } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowsRescaler.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowsRescaler.java index 3e2f1af4..81167861 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowsRescaler.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowsRescaler.java @@ -6,6 +6,7 @@ */ package com.powsybl.flow_decomposition; +import com.powsybl.commons.PowsyblException; import com.powsybl.iidm.network.Country; import java.util.Map; @@ -14,8 +15,12 @@ /** * @author Sebastien Murgey {@literal } * @author Hugo Schindler {@literal } + * @author Caio Luke {@literal } */ final class DecomposedFlowsRescaler { + + private static final double MIN_FLOW_TOLERANCE = 1E-6; // min flow in MW to rescale + private DecomposedFlowsRescaler() { } @@ -27,13 +32,19 @@ private static double rescaleValue(double initialValue, double delta, double sum return initialValue + delta * reLU(initialValue) / sumOfReLUFlows; } - static DecomposedFlow rescale(DecomposedFlow decomposedFlow) { + static DecomposedFlow rescale(DecomposedFlow decomposedFlow, FlowDecompositionParameters.RescaleMode rescaleMode) { + double acReferenceFlow = decomposedFlow.getAcReferenceFlow(); + + if (Double.isNaN(acReferenceFlow)) { + return decomposedFlow; + } + String branchId = decomposedFlow.getBranchId(); String contingencyId = decomposedFlow.getContingencyId(); Country country1 = decomposedFlow.getCountry1(); Country country2 = decomposedFlow.getCountry2(); - double acReferenceFlow = decomposedFlow.getAcReferenceFlow(); + double acMaxFlow = decomposedFlow.getAcMaxFlow(); double dcReferenceFlow = decomposedFlow.getDcReferenceFlow(); double allocatedFlow = decomposedFlow.getAllocatedFlow(); double xNodeFlow = decomposedFlow.getXNodeFlow(); @@ -41,20 +52,37 @@ static DecomposedFlow rescale(DecomposedFlow decomposedFlow) { double internalFlow = decomposedFlow.getInternalFlow(); Map loopFlows = decomposedFlow.getLoopFlows(); - if (Double.isNaN(acReferenceFlow)) { - return decomposedFlow; - } + switch (rescaleMode) { + case RELU -> { + double deltaToRescale = acReferenceFlow * Math.signum(acReferenceFlow) - decomposedFlow.getTotalFlow(); + double sumOfReLUFlows = reLU(allocatedFlow) + reLU(pstFlow) + reLU(xNodeFlow) + loopFlows.values().stream().mapToDouble(DecomposedFlowsRescaler::reLU).sum() + reLU(internalFlow); + + double rescaledAllocatedFlow = rescaleValue(allocatedFlow, deltaToRescale, sumOfReLUFlows); + double rescaledXNodeFlow = rescaleValue(xNodeFlow, deltaToRescale, sumOfReLUFlows); + double rescaledPstFlow = rescaleValue(pstFlow, deltaToRescale, sumOfReLUFlows); + double rescaleInternalFlow = rescaleValue(internalFlow, deltaToRescale, sumOfReLUFlows); + Map rescaledLoopFlows = loopFlows.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, entry -> rescaleValue(entry.getValue(), deltaToRescale, sumOfReLUFlows))); - double deltaToRescale = acReferenceFlow * Math.signum(acReferenceFlow) - decomposedFlow.getTotalFlow(); - double sumOfReLUFlows = reLU(allocatedFlow) + reLU(pstFlow) + reLU(xNodeFlow) + loopFlows.values().stream().mapToDouble(DecomposedFlowsRescaler::reLU).sum() + reLU(internalFlow); + return new DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow, acMaxFlow, dcReferenceFlow, rescaledAllocatedFlow, rescaledXNodeFlow, rescaledPstFlow, rescaleInternalFlow, rescaledLoopFlows); + } + case PROPORTIONAL -> { + // if dcReferenceFlow is too small, do not rescale + if (Math.abs(dcReferenceFlow) < MIN_FLOW_TOLERANCE) { + return decomposedFlow; + } + double rescaleFactor = Math.abs(acMaxFlow / dcReferenceFlow); - double rescaledAllocatedFlow = rescaleValue(allocatedFlow, deltaToRescale, sumOfReLUFlows); - double rescaledXNodeFlow = rescaleValue(xNodeFlow, deltaToRescale, sumOfReLUFlows); - double rescaledPstFlow = rescaleValue(pstFlow, deltaToRescale, sumOfReLUFlows); - double rescaleInternalFlow = rescaleValue(internalFlow, deltaToRescale, sumOfReLUFlows); - Map rescaledLoopFlows = loopFlows.entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, entry -> rescaleValue(entry.getValue(), deltaToRescale, sumOfReLUFlows))); + double rescaledAllocatedFlow = rescaleFactor * allocatedFlow; + double rescaledXNodeFlow = rescaleFactor * xNodeFlow; + double rescaledPstFlow = rescaleFactor * pstFlow; + double rescaleInternalFlow = rescaleFactor * internalFlow; + Map rescaledLoopFlows = loopFlows.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, entry -> rescaleFactor * entry.getValue())); - return new DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow, dcReferenceFlow, rescaledAllocatedFlow, rescaledXNodeFlow, rescaledPstFlow, rescaleInternalFlow, rescaledLoopFlows); + return new DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow, acMaxFlow, dcReferenceFlow, rescaledAllocatedFlow, rescaledXNodeFlow, rescaledPstFlow, rescaleInternalFlow, rescaledLoopFlows); + } + default -> throw new PowsyblException("Rescale mode not defined: " + rescaleMode); + } } } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowComputerUtils.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowComputerUtils.java new file mode 100644 index 00000000..a3b55485 --- /dev/null +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowComputerUtils.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/) + * 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.flow_decomposition; + +import com.powsybl.iidm.network.Branch; +import com.powsybl.iidm.network.Identifiable; + +import java.util.Collection; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author Sebastien Murgey {@literal } + * @author Hugo Schindler {@literal } + * @author Guillaume Verger {@literal } + * @author Caio Luke {@literal } + */ +public final class FlowComputerUtils { + + private FlowComputerUtils() { + // empty constructor + } + + public static Map calculateAcReferenceFlows(Collection xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) { + if (loadFlowServiceAcResult.fallbackHasBeenActivated()) { + return xnecList.stream().collect(Collectors.toMap(Identifiable::getId, branch -> Double.NaN)); + } + return getReferenceFlow(xnecList); + } + + public static Map calculateAcMaxFlows(Collection xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) { + if (loadFlowServiceAcResult.fallbackHasBeenActivated()) { + return xnecList.stream().collect(Collectors.toMap(Identifiable::getId, branch -> Double.NaN)); + } + return getMaxFlow(xnecList); + } + + public static Map getReferenceFlow(Collection xnecList) { + return xnecList.stream() + .collect(Collectors.toMap( + Identifiable::getId, + FlowComputerUtils::getReferenceP + )); + } + + public static Map getMaxFlow(Collection xnecList) { + return xnecList.stream() + .collect(Collectors.toMap( + Identifiable::getId, + branch -> Math.max(Math.abs(branch.getTerminal1().getP()), Math.abs(branch.getTerminal2().getP())) + )); + } + + private static double getReferenceP(Branch branch) { + return branch.getTerminal1().getP(); + } +} diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java index 99d35078..9c7b0c26 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java @@ -135,6 +135,7 @@ private void decomposeFlowForState(Network network, Map> glsks, LoadFlowRunningService.Result loadFlowServiceAcResult) { saveAcReferenceFlow(flowDecompositionResultsBuilder, xnecList, loadFlowServiceAcResult); + saveAcMaxFlow(flowDecompositionResultsBuilder, xnecList, loadFlowServiceAcResult); compensateLosses(network); observers.computedAcFlows(network, loadFlowServiceAcResult); @@ -162,7 +163,7 @@ private void decomposeFlowForState(Network network, computeAllocatedAndLoopFlows(flowDecompositionResultsBuilder, nodalInjectionsMatrix, ptdfMatrix); computePstFlows(network, flowDecompositionResultsBuilder, networkMatrixIndexes, psdfMatrix); - flowDecompositionResultsBuilder.build(parameters.isRescaleEnabled()); + flowDecompositionResultsBuilder.build(parameters.getRescaleMode()); } public void addObserver(FlowDecompositionObserver observer) { @@ -178,19 +179,20 @@ private LoadFlowRunningService.Result runAcLoadFlow(Network network) { } private void saveAcReferenceFlow(FlowDecompositionResults.PerStateBuilder flowDecompositionResultBuilder, Set xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) { - Map acReferenceFlows = new AcReferenceFlowComputer().run(xnecList, loadFlowServiceAcResult); + Map acReferenceFlows = FlowComputerUtils.calculateAcReferenceFlows(xnecList, loadFlowServiceAcResult); flowDecompositionResultBuilder.saveAcReferenceFlow(acReferenceFlows); } + private void saveAcMaxFlow(FlowDecompositionResults.PerStateBuilder flowDecompositionResultBuilder, Set xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) { + Map acMaxFlow = FlowComputerUtils.calculateAcMaxFlows(xnecList, loadFlowServiceAcResult); + flowDecompositionResultBuilder.saveAcMaxFlow(acMaxFlow); + } + private Map getZonesNetPosition(Network network) { NetPositionComputer netPositionComputer = new NetPositionComputer(); return netPositionComputer.run(network); } - private Map getBranchReferenceFlows(Set branches) { - return new ReferenceFlowComputer().run(branches); - } - private void compensateLosses(Network network) { if (parameters.isLossesCompensationEnabled()) { lossesCompensator.run(network); @@ -210,7 +212,7 @@ private SparseMatrixWithIndexesTriplet getNodalInjectionsMatrix(Network network, } private void saveDcReferenceFlow(FlowDecompositionResults.PerStateBuilder flowDecompositionResultBuilder, Set xnecList) { - flowDecompositionResultBuilder.saveDcReferenceFlow(getBranchReferenceFlows(xnecList)); + flowDecompositionResultBuilder.saveDcReferenceFlow(FlowComputerUtils.getReferenceFlow(xnecList)); } private SensitivityAnalyser getSensitivityAnalyser(Network network, NetworkMatrixIndexes networkMatrixIndexes) { diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionObserverList.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionObserverList.java index 4f55bd14..63ae1d56 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionObserverList.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionObserverList.java @@ -19,6 +19,7 @@ * @author Guillaume Verger {@literal } */ public class FlowDecompositionObserverList { + private final List observers; public FlowDecompositionObserverList() { @@ -86,8 +87,7 @@ public void computedAcFlows(Network network, Result loadFlowServiceAcResult) { return; } - Map acFlows = - new AcReferenceFlowComputer().run(network.getBranchStream().toList(), loadFlowServiceAcResult); + Map acFlows = FlowComputerUtils.calculateAcReferenceFlows(network.getBranchStream().toList(), loadFlowServiceAcResult); for (FlowDecompositionObserver o : observers) { o.computedAcFlows(acFlows); @@ -99,7 +99,7 @@ public void computedDcFlows(Network network) { return; } - Map dcFlows = new ReferenceFlowComputer().run(network.getBranchStream().toList()); + Map dcFlows = FlowComputerUtils.getReferenceFlow(network.getBranchStream().toList()); for (FlowDecompositionObserver o : observers) { o.computedDcFlows(dcFlows); @@ -143,6 +143,6 @@ private void sendMatrix(MatrixNotification notification, SparseMatrixWithIndexes @FunctionalInterface private interface MatrixNotification { - public void sendMatrix(FlowDecompositionObserver o, Map> matrix); + void sendMatrix(FlowDecompositionObserver o, Map> matrix); } } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionParameters.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionParameters.java index edd5f18b..e7c2f881 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionParameters.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionParameters.java @@ -15,8 +15,6 @@ * @author Hugo Schindler {@literal } */ public class FlowDecompositionParameters { - public static final boolean ENABLE_RESCALED_RESULTS = true; - public static final boolean DISABLE_RESCALED_RESULTS = false; public static final double DISABLE_SENSITIVITY_EPSILON = -1; public static final boolean DISABLE_LOSSES_COMPENSATION = false; public static final boolean ENABLE_LOSSES_COMPENSATION = true; @@ -24,15 +22,22 @@ public class FlowDecompositionParameters { public static final boolean DEFAULT_ENABLE_LOSSES_COMPENSATION = DISABLE_LOSSES_COMPENSATION; public static final double DEFAULT_LOSSES_COMPENSATION_EPSILON = 1e-5; public static final double DEFAULT_SENSITIVITY_EPSILON = 1e-5; - public static final boolean DEFAULT_RESCALE_ENABLED = DISABLE_RESCALED_RESULTS; public static final boolean DISABLE_DC_FALLBACK_AFTER_AC_DIVERGENCE = false; public static final boolean ENABLE_DC_FALLBACK_AFTER_AC_DIVERGENCE = true; public static final boolean DEFAULT_DC_FALLBACK_ENABLED_AFTER_AC_DIVERGENCE = ENABLE_DC_FALLBACK_AFTER_AC_DIVERGENCE; private static final int DEFAULT_SENSITIVITY_VARIABLE_BATCH_SIZE = 15000; + + public enum RescaleMode { + NONE, + RELU, + PROPORTIONAL + } + + public static final RescaleMode DEFAULT_RESCALE_MODE = RescaleMode.NONE; private boolean enableLossesCompensation; private double lossesCompensationEpsilon; private double sensitivityEpsilon; - private boolean rescaleEnabled; + private RescaleMode rescaleMode; private boolean dcFallbackEnabledAfterAcDivergence; private int sensitivityVariableBatchSize; @@ -53,7 +58,7 @@ private static void load(FlowDecompositionParameters parameters, PlatformConfig parameters.setEnableLossesCompensation(moduleConfig.getBooleanProperty("enable-losses-compensation", DEFAULT_ENABLE_LOSSES_COMPENSATION)); parameters.setLossesCompensationEpsilon(moduleConfig.getDoubleProperty("losses-compensation-epsilon", DEFAULT_LOSSES_COMPENSATION_EPSILON)); parameters.setSensitivityEpsilon(moduleConfig.getDoubleProperty("sensitivity-epsilon", DEFAULT_SENSITIVITY_EPSILON)); - parameters.setRescaleEnabled(moduleConfig.getBooleanProperty("rescale-enabled", DEFAULT_RESCALE_ENABLED)); + parameters.setRescaleMode(moduleConfig.getEnumProperty("rescale-mode", RescaleMode.class, DEFAULT_RESCALE_MODE)); parameters.setDcFallbackEnabledAfterAcDivergence(moduleConfig.getBooleanProperty("dc-fallback-enabled-after-ac-divergence", DEFAULT_DC_FALLBACK_ENABLED_AFTER_AC_DIVERGENCE)); parameters.setSensitivityVariableBatchSize(moduleConfig.getIntProperty("sensitivity-variable-batch-size", DEFAULT_SENSITIVITY_VARIABLE_BATCH_SIZE)); }); @@ -63,7 +68,7 @@ public FlowDecompositionParameters() { this.enableLossesCompensation = DEFAULT_ENABLE_LOSSES_COMPENSATION; this.lossesCompensationEpsilon = DEFAULT_LOSSES_COMPENSATION_EPSILON; this.sensitivityEpsilon = DEFAULT_SENSITIVITY_EPSILON; - this.rescaleEnabled = DEFAULT_RESCALE_ENABLED; + this.rescaleMode = DEFAULT_RESCALE_MODE; this.dcFallbackEnabledAfterAcDivergence = DEFAULT_DC_FALLBACK_ENABLED_AFTER_AC_DIVERGENCE; this.sensitivityVariableBatchSize = DEFAULT_SENSITIVITY_VARIABLE_BATCH_SIZE; } @@ -95,12 +100,12 @@ public FlowDecompositionParameters setSensitivityEpsilon(double sensitivityEpsil return this; } - public boolean isRescaleEnabled() { - return rescaleEnabled; + public RescaleMode getRescaleMode() { + return rescaleMode; } - public FlowDecompositionParameters setRescaleEnabled(boolean rescaleEnabled) { - this.rescaleEnabled = rescaleEnabled; + public FlowDecompositionParameters setRescaleMode(RescaleMode rescaleMode) { + this.rescaleMode = rescaleMode; return this; } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java index 10b1a42e..862dda91 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java @@ -45,6 +45,7 @@ class PerStateBuilder { private SparseMatrixWithIndexesCSC allocatedAndLoopFlowsMatrix; private Map> pstFlowMap; private Map acReferenceFlow; + private Map acMaxFlow; private Map dcReferenceFlow; PerStateBuilder(String contingencyId, Set xnecList) { @@ -64,19 +65,23 @@ void saveAcReferenceFlow(Map acReferenceFlow) { this.acReferenceFlow = acReferenceFlow; } + void saveAcMaxFlow(Map acMaxFlow) { + this.acMaxFlow = acMaxFlow; + } + void saveDcReferenceFlow(Map dcReferenceFlow) { this.dcReferenceFlow = dcReferenceFlow; } - void build(boolean isRescaleEnable) { + void build(FlowDecompositionParameters.RescaleMode rescaleMode) { allocatedAndLoopFlowsMatrix.toMap() .forEach((branchId, decomposedFlow) -> { String xnecId = NetworkUtil.getXnecId(contingencyId, branchId); - decomposedFlowMap.put(xnecId, createDecomposedFlow(branchId, decomposedFlow, isRescaleEnable)); + decomposedFlowMap.put(xnecId, createDecomposedFlow(branchId, decomposedFlow, rescaleMode)); }); } - private DecomposedFlow createDecomposedFlow(String branchId, Map allocatedAndLoopFlowMap, boolean isRescaleEnable) { + private DecomposedFlow createDecomposedFlow(String branchId, Map allocatedAndLoopFlowMap, FlowDecompositionParameters.RescaleMode rescaleMode) { Map loopFlowsMap = allocatedAndLoopFlowMap.entrySet().stream() .filter(entry -> entry.getKey().startsWith(LOOP_FLOWS_COLUMN_PREFIX)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); @@ -86,11 +91,12 @@ private DecomposedFlow createDecomposedFlow(String branchId, Map 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 DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow.get(branchId), dcReferenceFlow.get(branchId), allocatedFlow, xNodeFlow, pstFlow, internalFlow, loopFlowsMap); - if (isRescaleEnable) { - return DecomposedFlowsRescaler.rescale(decomposedFlow); + DecomposedFlow decomposedFlow = new DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow.get(branchId), acMaxFlow.get(branchId), dcReferenceFlow.get(branchId), allocatedFlow, xNodeFlow, pstFlow, internalFlow, loopFlowsMap); + if (rescaleMode.equals(FlowDecompositionParameters.RescaleMode.NONE)) { + return decomposedFlow; + } else { + return DecomposedFlowsRescaler.rescale(decomposedFlow, rescaleMode); } - return decomposedFlow; } private double extractInternalFlow(Map loopFlowsMap, Country country1, Country country2) { diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/ReferenceFlowComputer.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/ReferenceFlowComputer.java deleted file mode 100644 index 68fb4061..00000000 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/ReferenceFlowComputer.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.iidm.network.Branch; -import com.powsybl.iidm.network.Identifiable; - -import java.util.Collection; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * @author Sebastien Murgey {@literal } - * @author Hugo Schindler {@literal } - */ -class ReferenceFlowComputer { - Map run(Collection xnecList) { - return xnecList.stream() - .collect(Collectors.toMap( - Identifiable::getId, - this::getP - )); - } - - private double getP(Branch branch) { - return branch.getTerminal1().getP(); - } -} diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/AllocatedFlowTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/AllocatedFlowTests.java index 9dcb0b22..69b7634b 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/AllocatedFlowTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/AllocatedFlowTests.java @@ -45,7 +45,7 @@ void checkThatAllocatedFlowAreExtractedForEachXnecGivenABasicNetwork() { Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); assertEquals(100.0935, decomposedFlowMap.get(xnecFrBee).getAllocatedFlow(), EPSILON); - TestUtils.assertCoherenceTotalFlow(FlowDecompositionParameters.DEFAULT_RESCALE_ENABLED, flowDecompositionResults); + TestUtils.assertCoherenceTotalFlow(FlowDecompositionParameters.DEFAULT_RESCALE_MODE, flowDecompositionResults); } @Test @@ -60,6 +60,6 @@ void checkThatAllocatedFlowAreExtractedForEachXnecGivenABasicNetworkWithInverted Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); assertEquals(100.0935, decomposedFlowMap.get(xnecFrBee).getAllocatedFlow(), EPSILON); - TestUtils.assertCoherenceTotalFlow(FlowDecompositionParameters.DEFAULT_RESCALE_ENABLED, flowDecompositionResults); + TestUtils.assertCoherenceTotalFlow(FlowDecompositionParameters.DEFAULT_RESCALE_MODE, flowDecompositionResults); } } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/CgmesIntegrationTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/CgmesIntegrationTests.java index dcb00100..a9afd729 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/CgmesIntegrationTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/CgmesIntegrationTests.java @@ -59,13 +59,13 @@ void checkFlowDecompositionWorksOnCgmesFile() { .setEnableLossesCompensation(FlowDecompositionParameters.ENABLE_LOSSES_COMPENSATION) .setLossesCompensationEpsilon(FlowDecompositionParameters.DISABLE_LOSSES_COMPENSATION_EPSILON) .setSensitivityEpsilon(FlowDecompositionParameters.DISABLE_SENSITIVITY_EPSILON) - .setRescaleEnabled(FlowDecompositionParameters.ENABLE_RESCALED_RESULTS); + .setRescaleMode(FlowDecompositionParameters.RescaleMode.RELU); String xnecId = "044cd006-c766-11e1-8775-005056c00008"; XnecProvider xnecProvider = XnecProviderByIds.builder().addNetworkElementsOnBasecase(Set.of(xnecId)).build(); FlowDecompositionComputer flowDecompositionComputer = new FlowDecompositionComputer(flowDecompositionParameters); FlowDecompositionResults flowDecompositionResults = flowDecompositionComputer.run(xnecProvider, network); assertNotNull(flowDecompositionResults.getDecomposedFlowMap().get(xnecId)); assertEquals(1, flowDecompositionResults.getDecomposedFlowMap().size()); - TestUtils.assertCoherenceTotalFlow(flowDecompositionParameters.isRescaleEnabled(), flowDecompositionResults); + TestUtils.assertCoherenceTotalFlow(flowDecompositionParameters.getRescaleMode(), flowDecompositionResults); } } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionParametersTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionParametersTests.java index 9d176bd4..f1b35826 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionParametersTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionParametersTests.java @@ -50,7 +50,7 @@ void checkDefaultParameters() { assertFalse(parameters.isLossesCompensationEnabled()); assertEquals(1e-5, parameters.getLossesCompensationEpsilon(), EPSILON); assertEquals(1e-5, parameters.getSensitivityEpsilon(), EPSILON); - assertFalse(parameters.isRescaleEnabled()); + assertEquals(FlowDecompositionParameters.RescaleMode.NONE, parameters.getRescaleMode()); assertTrue(parameters.isDcFallbackEnabledAfterAcDivergence()); assertEquals(15000, parameters.getSensitivityVariableBatchSize()); } @@ -61,7 +61,7 @@ void checkCompleteConfigurationOfParameters() { mapModuleConfig.setStringProperty("enable-losses-compensation", Boolean.toString(true)); mapModuleConfig.setStringProperty("losses-compensation-epsilon", Double.toString(2e-5)); mapModuleConfig.setStringProperty("sensitivity-epsilon", Double.toString(3e-3)); - mapModuleConfig.setStringProperty("rescale-enabled", Boolean.toString(true)); + mapModuleConfig.setStringProperty("rescale-mode", FlowDecompositionParameters.RescaleMode.RELU.name()); mapModuleConfig.setStringProperty("dc-fallback-enabled-after-ac-divergence", Boolean.toString(false)); mapModuleConfig.setStringProperty("sensitivity-variable-batch-size", Integer.toString(1234)); @@ -69,7 +69,7 @@ void checkCompleteConfigurationOfParameters() { assertTrue(parameters.isLossesCompensationEnabled()); assertEquals(2e-5, parameters.getLossesCompensationEpsilon(), EPSILON); assertEquals(3e-3, parameters.getSensitivityEpsilon(), EPSILON); - assertTrue(parameters.isRescaleEnabled()); + assertEquals(FlowDecompositionParameters.RescaleMode.RELU, parameters.getRescaleMode()); assertFalse(parameters.isDcFallbackEnabledAfterAcDivergence()); assertEquals(1234, parameters.getSensitivityVariableBatchSize()); } @@ -83,7 +83,7 @@ void checkIncompleteConfigurationOfParameters() { assertFalse(parameters.isLossesCompensationEnabled()); assertEquals(2e-5, parameters.getLossesCompensationEpsilon(), EPSILON); assertEquals(1e-5, parameters.getSensitivityEpsilon(), EPSILON); - assertFalse(parameters.isRescaleEnabled()); + assertEquals(FlowDecompositionParameters.RescaleMode.NONE, parameters.getRescaleMode()); assertTrue(parameters.isDcFallbackEnabledAfterAcDivergence()); } } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java index a46e136c..aa2cc9f4 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java @@ -83,10 +83,11 @@ void testBuilderNState() { FlowDecompositionResults.PerStateBuilder nStateBuilder = flowDecompositionResults.getBuilder(nStateXnecList); nStateBuilder.saveAcReferenceFlow(Map.of(branchId, 10.0)); + nStateBuilder.saveAcMaxFlow(Map.of(branchId, 10.0)); nStateBuilder.saveDcReferenceFlow(Map.of(branchId, 11.0)); nStateBuilder.saveAllocatedAndLoopFlowsMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(ALLOCATED_COLUMN_NAME, 0, NetworkUtil.getLoopFlowIdFromCountry(FR), 1), alloMatrix)); nStateBuilder.savePstFlowMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(PST_COLUMN_NAME, 0), pstMatrix)); - nStateBuilder.build(FlowDecompositionParameters.DISABLE_RESCALED_RESULTS); + nStateBuilder.build(FlowDecompositionParameters.RescaleMode.NONE); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); assertEquals(1, decomposedFlowMap.size()); @@ -109,10 +110,11 @@ void testBuilderN1State() { String xnecId = "DB000011 DF000011 1_DD000011 DF000011 1"; n1StateBuilder.saveAcReferenceFlow(Map.of(branchId, 10.0)); + n1StateBuilder.saveAcMaxFlow(Map.of(branchId, 10.0)); n1StateBuilder.saveDcReferenceFlow(Map.of(branchId, 11.0)); n1StateBuilder.saveAllocatedAndLoopFlowsMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(ALLOCATED_COLUMN_NAME, 0, NetworkUtil.getLoopFlowIdFromCountry(FR), 1), alloMatrix)); n1StateBuilder.savePstFlowMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(PST_COLUMN_NAME, 0), pstMatrix)); - n1StateBuilder.build(FlowDecompositionParameters.DISABLE_RESCALED_RESULTS); + n1StateBuilder.build(FlowDecompositionParameters.RescaleMode.NONE); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); assertEquals(1, decomposedFlowMap.size()); @@ -135,10 +137,11 @@ void testBuilderN2State() { String xnecId = "DB000011 DF000011 1_FB000011 FD000011 1_FB000021 FD000021 1"; n2StateBuilder.saveAcReferenceFlow(Map.of(branchId, 10.0)); + n2StateBuilder.saveAcMaxFlow(Map.of(branchId, 10.0)); n2StateBuilder.saveDcReferenceFlow(Map.of(branchId, 11.0)); n2StateBuilder.saveAllocatedAndLoopFlowsMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(ALLOCATED_COLUMN_NAME, 0, NetworkUtil.getLoopFlowIdFromCountry(FR), 1), alloMatrix)); n2StateBuilder.savePstFlowMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(PST_COLUMN_NAME, 0), pstMatrix)); - n2StateBuilder.build(FlowDecompositionParameters.DISABLE_RESCALED_RESULTS); + n2StateBuilder.build(FlowDecompositionParameters.RescaleMode.NONE); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); assertEquals(1, decomposedFlowMap.size()); diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionWithContingencyTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionWithContingencyTests.java index 7716cbae..95c4d3af 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionWithContingencyTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionWithContingencyTests.java @@ -37,10 +37,10 @@ void testSingleN1PostContingencyState() { .build(); FlowDecompositionParameters flowDecompositionParameters = FlowDecompositionParameters.load() .setEnableLossesCompensation(FlowDecompositionParameters.ENABLE_LOSSES_COMPENSATION) - .setRescaleEnabled(FlowDecompositionParameters.DISABLE_RESCALED_RESULTS); + .setRescaleMode(FlowDecompositionParameters.RescaleMode.NONE); FlowDecompositionComputer flowComputer = new FlowDecompositionComputer(flowDecompositionParameters); FlowDecompositionResults flowDecompositionResults = flowComputer.run(xnecProvider, network); - TestUtils.assertCoherenceTotalFlow(flowDecompositionParameters.isRescaleEnabled(), flowDecompositionResults); + TestUtils.assertCoherenceTotalFlow(flowDecompositionParameters.getRescaleMode(), flowDecompositionResults); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); validateFlowDecompositionOnXnec(xnecId, branchId, contingencyId, decomposedFlowMap.get(xnecId), -1269.932, 31.943); @@ -63,10 +63,10 @@ void testNStateAndN1PostContingencyState() { .build(); FlowDecompositionParameters flowDecompositionParameters = FlowDecompositionParameters.load() .setEnableLossesCompensation(FlowDecompositionParameters.ENABLE_LOSSES_COMPENSATION) - .setRescaleEnabled(FlowDecompositionParameters.DISABLE_RESCALED_RESULTS); + .setRescaleMode(FlowDecompositionParameters.RescaleMode.NONE); FlowDecompositionComputer flowComputer = new FlowDecompositionComputer(flowDecompositionParameters); FlowDecompositionResults flowDecompositionResults = flowComputer.run(xnecProvider, network); - TestUtils.assertCoherenceTotalFlow(flowDecompositionParameters.isRescaleEnabled(), flowDecompositionResults); + TestUtils.assertCoherenceTotalFlow(flowDecompositionParameters.getRescaleMode(), flowDecompositionResults); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); validateFlowDecompositionOnXnec(xnecId1, branchId, contingencyId1, decomposedFlowMap.get(xnecId1), -300.420, 22.472); @@ -89,10 +89,10 @@ void testSingleN2PostContingencyState() { .build(); FlowDecompositionParameters flowDecompositionParameters = FlowDecompositionParameters.load() .setEnableLossesCompensation(FlowDecompositionParameters.ENABLE_LOSSES_COMPENSATION) - .setRescaleEnabled(FlowDecompositionParameters.DISABLE_RESCALED_RESULTS); + .setRescaleMode(FlowDecompositionParameters.RescaleMode.NONE); FlowDecompositionComputer flowComputer = new FlowDecompositionComputer(flowDecompositionParameters); FlowDecompositionResults flowDecompositionResults = flowComputer.run(xnecProvider, network); - TestUtils.assertCoherenceTotalFlow(flowDecompositionParameters.isRescaleEnabled(), flowDecompositionResults); + TestUtils.assertCoherenceTotalFlow(flowDecompositionParameters.getRescaleMode(), flowDecompositionResults); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); validateFlowDecompositionOnXnec(xnecId, branchId, contingencyId, decomposedFlowMap.get(xnecId), -406.204, 48.362); @@ -119,10 +119,10 @@ void testNStateN1AndN2PostContingencyState() { .build(); FlowDecompositionParameters flowDecompositionParameters = FlowDecompositionParameters.load() .setEnableLossesCompensation(FlowDecompositionParameters.ENABLE_LOSSES_COMPENSATION) - .setRescaleEnabled(FlowDecompositionParameters.DISABLE_RESCALED_RESULTS); + .setRescaleMode(FlowDecompositionParameters.RescaleMode.NONE); FlowDecompositionComputer flowComputer = new FlowDecompositionComputer(flowDecompositionParameters); FlowDecompositionResults flowDecompositionResults = flowComputer.run(xnecProvider, network); - TestUtils.assertCoherenceTotalFlow(flowDecompositionParameters.isRescaleEnabled(), flowDecompositionResults); + TestUtils.assertCoherenceTotalFlow(flowDecompositionParameters.getRescaleMode(), flowDecompositionResults); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); validateFlowDecompositionOnXnec(xnecId1, branchId, contingencyId1, decomposedFlowMap.get(xnecId1), -300.420, 22.472); diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java index ea109903..a2138660 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java @@ -90,14 +90,14 @@ private DecomposedFlow getDecomposedFlow(double internalFlow, double acReference loopFlows.put(NetworkUtil.getLoopFlowIdFromCountry(Country.ES), 700.); Country country1 = Country.FR; Country country2 = Country.FR; - return new DecomposedFlow("", "", country1, country2, acReferenceFlow, dcReferenceFlow, allocatedFlow, 0, pstFlow, internalFlow, loopFlows); + return new DecomposedFlow("", "", country1, country2, acReferenceFlow, acReferenceFlow, dcReferenceFlow, allocatedFlow, 0, pstFlow, internalFlow, loopFlows); } private DecomposedFlow getRescaledFlow(double internalFlow, double acReferenceFlow, double dcReferenceFlow) { DecomposedFlow decomposedFlow = getDecomposedFlow(internalFlow, acReferenceFlow, dcReferenceFlow); assertEquals(Math.abs(dcReferenceFlow), decomposedFlow.getTotalFlow(), EPSILON); - return DecomposedFlowsRescaler.rescale(decomposedFlow); + return DecomposedFlowsRescaler.rescale(decomposedFlow, FlowDecompositionParameters.RescaleMode.RELU); } private void checkRescaleAcReference(double acReferenceFlow, double dcReferenceFlow, DecomposedFlow rescaledFlow, double expectedAllocatedFlow, double expectedInternalFlow, double expectedPstFlow, double expectedLoopFlowBE, double expectedLoopFlowES) { diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/LoopFlowTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/LoopFlowTests.java index cde60489..a2b5728f 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/LoopFlowTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/LoopFlowTests.java @@ -35,7 +35,7 @@ void checkThatLoopFlowsAreExtractedForEachXnecAndForEachCountryGivenABasicNetwor XnecProvider xnecProvider = XnecProviderByIds.builder().addNetworkElementsOnBasecase(Set.of(x1, x2, x4, x5)).build(); FlowDecompositionComputer flowComputer = new FlowDecompositionComputer(); FlowDecompositionResults flowDecompositionResults = flowComputer.run(xnecProvider, network); - TestUtils.assertCoherenceTotalFlow(FlowDecompositionParameters.DEFAULT_RESCALE_ENABLED, flowDecompositionResults); + TestUtils.assertCoherenceTotalFlow(FlowDecompositionParameters.RescaleMode.NONE, flowDecompositionResults); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); assertEquals(0, decomposedFlowMap.get(x1).getAllocatedFlow(), EPSILON); diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/PstFlowTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/PstFlowTests.java index 5fce73d5..25bc5eb4 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/PstFlowTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/PstFlowTests.java @@ -32,7 +32,7 @@ void checkThatPSTFlowsAreExtractedForEachXnecAndForEachPSTGivenABasicNetworkWith FlowDecompositionComputer flowComputer = new FlowDecompositionComputer(); XnecProvider xnecProvider = XnecProviderByIds.builder().addNetworkElementsOnBasecase(Set.of(x1, x2)).build(); FlowDecompositionResults flowDecompositionResults = flowComputer.run(xnecProvider, network); - TestUtils.assertCoherenceTotalFlow(FlowDecompositionParameters.DEFAULT_RESCALE_ENABLED, flowDecompositionResults); + TestUtils.assertCoherenceTotalFlow(FlowDecompositionParameters.RescaleMode.NONE, flowDecompositionResults); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); assertEquals(0, decomposedFlowMap.get(x1).getPstFlow(), EPSILON); @@ -49,7 +49,7 @@ void checkThatPSTFlowsAreExtractedForEachXnecAndForEachPSTGivenABasicNetworkWith FlowDecompositionComputer flowComputer = new FlowDecompositionComputer(); XnecProvider xnecProvider = XnecProviderByIds.builder().addNetworkElementsOnBasecase(Set.of(x1, x2)).build(); FlowDecompositionResults flowDecompositionResults = flowComputer.run(xnecProvider, network); - TestUtils.assertCoherenceTotalFlow(FlowDecompositionParameters.DEFAULT_RESCALE_ENABLED, flowDecompositionResults); + TestUtils.assertCoherenceTotalFlow(FlowDecompositionParameters.RescaleMode.NONE, flowDecompositionResults); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); assertEquals(163.652702605, decomposedFlowMap.get(x1).getPstFlow(), EPSILON); diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java index 92bf9714..4419c580 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java @@ -23,6 +23,7 @@ /** * @author Sebastien Murgey {@literal } * @author Hugo Schindler {@literal } + * @author Caio Luke {@literal } */ class RescalingTests { private static final double EPSILON = 1e-5; @@ -59,14 +60,14 @@ private DecomposedFlow getDecomposedFlow(double acReferenceFlow, double dcRefere loopFlows.put(NetworkUtil.getLoopFlowIdFromCountry(Country.ES), 700.); Country country1 = Country.FR; Country country2 = Country.FR; - return new DecomposedFlow("", "", country1, country2, acReferenceFlow, dcReferenceFlow, allocatedFlow, 0, pstFlow, internalFlow, loopFlows); + return new DecomposedFlow("", "", country1, country2, acReferenceFlow, acReferenceFlow, dcReferenceFlow, allocatedFlow, 0, pstFlow, internalFlow, loopFlows); } private DecomposedFlow getRescaledFlow(double acReferenceFlow, double dcReferenceFlow) { DecomposedFlow decomposedFlow = getDecomposedFlow(acReferenceFlow, dcReferenceFlow); assertEquals(Math.abs(dcReferenceFlow), decomposedFlow.getTotalFlow(), EPSILON); - return DecomposedFlowsRescaler.rescale(decomposedFlow); + return DecomposedFlowsRescaler.rescale(decomposedFlow, FlowDecompositionParameters.RescaleMode.RELU); } @Test @@ -134,31 +135,37 @@ void testAcerNormalizationWithPositiveAbsoluteSmallerReferenceFlows() { } @Test - void testNormalizationWithFlowDecompositionResultsWithPstNetwork() { + void testReLUNormalizationWithFlowDecompositionResultsWithPstNetwork() { String networkFileName = "NETWORK_PST_FLOW_WITH_COUNTRIES.uct"; - testNormalizationWithFlowDecompositionResults(networkFileName, FlowDecompositionParameters.ENABLE_RESCALED_RESULTS); + testNormalizationWithFlowDecompositionResults(networkFileName, FlowDecompositionParameters.RescaleMode.RELU); } @Test void testNoNormalizationWithFlowDecompositionResultsWithPstNetwork() { String networkFileName = "NETWORK_PST_FLOW_WITH_COUNTRIES.uct"; - testNormalizationWithFlowDecompositionResults(networkFileName, FlowDecompositionParameters.DISABLE_RESCALED_RESULTS); + testNormalizationWithFlowDecompositionResults(networkFileName, FlowDecompositionParameters.RescaleMode.NONE); } - static void testNormalizationWithFlowDecompositionResults(String networkFileName, boolean enableRescaledResults) { + @Test + void testProportionalNormalizationWithFlowDecompositionResultsWithPstNetwork() { + String networkFileName = "NETWORK_PST_FLOW_WITH_COUNTRIES.uct"; + testNormalizationWithFlowDecompositionResults(networkFileName, FlowDecompositionParameters.RescaleMode.PROPORTIONAL); + } + + static void testNormalizationWithFlowDecompositionResults(String networkFileName, FlowDecompositionParameters.RescaleMode rescaleMode) { Network network = TestUtils.importNetwork(networkFileName); FlowDecompositionParameters flowDecompositionParameters = new FlowDecompositionParameters() .setEnableLossesCompensation(FlowDecompositionParameters.ENABLE_LOSSES_COMPENSATION) .setLossesCompensationEpsilon(FlowDecompositionParameters.DISABLE_LOSSES_COMPENSATION_EPSILON) .setSensitivityEpsilon(FlowDecompositionParameters.DISABLE_SENSITIVITY_EPSILON) - .setRescaleEnabled(enableRescaledResults); + .setRescaleMode(rescaleMode); FlowDecompositionComputer flowDecompositionComputer = new FlowDecompositionComputer(flowDecompositionParameters); XnecProvider xnecProvider = new XnecProviderAllBranches(); FlowDecompositionResults flowDecompositionResults = flowDecompositionComputer.run(xnecProvider, network); - TestUtils.assertCoherenceTotalFlow(enableRescaledResults, flowDecompositionResults); + TestUtils.assertCoherenceTotalFlow(rescaleMode, flowDecompositionResults); } @Test @@ -171,7 +178,7 @@ void testRescalingDoesNotOccurWhenAcDiverge() { .setEnableLossesCompensation(FlowDecompositionParameters.ENABLE_LOSSES_COMPENSATION) .setLossesCompensationEpsilon(FlowDecompositionParameters.DISABLE_LOSSES_COMPENSATION_EPSILON) .setSensitivityEpsilon(FlowDecompositionParameters.DISABLE_SENSITIVITY_EPSILON) - .setRescaleEnabled(FlowDecompositionParameters.ENABLE_RESCALED_RESULTS); + .setRescaleMode(FlowDecompositionParameters.RescaleMode.RELU); FlowDecompositionComputer flowDecompositionComputer = new FlowDecompositionComputer(flowDecompositionParameters); XnecProvider xnecProvider = XnecProviderByIds.builder().addNetworkElementsOnBasecase(Set.of(xnecId)).build(); diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java index acb00c3f..b6fd7df4 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java @@ -37,13 +37,13 @@ public static GlskDocument importGlskDocument(String glskFileName) { return GlskDocumentImporters.importGlsk(TestUtils.class.getResourceAsStream(glskName)); } - public static void assertCoherenceTotalFlow(boolean enableRescaledResults, FlowDecompositionResults flowDecompositionResults) { + public static void assertCoherenceTotalFlow(FlowDecompositionParameters.RescaleMode rescaleMode, FlowDecompositionResults flowDecompositionResults) { for (String xnec : flowDecompositionResults.getDecomposedFlowMap().keySet()) { DecomposedFlow decomposedFlow = flowDecompositionResults.getDecomposedFlowMap().get(xnec); - if (enableRescaledResults) { - assertEquals(Math.abs(decomposedFlow.getAcReferenceFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); - } else { - assertEquals(Math.abs(decomposedFlow.getDcReferenceFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); + switch (rescaleMode) { + case RELU -> assertEquals(Math.abs(decomposedFlow.getAcReferenceFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); + case PROPORTIONAL -> assertEquals(Math.abs(decomposedFlow.getAcMaxFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); + default -> assertEquals(Math.abs(decomposedFlow.getDcReferenceFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); } } } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/XnodeFlowTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/XnodeFlowTests.java index b91d4161..8293a0d8 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/XnodeFlowTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/XnodeFlowTests.java @@ -38,10 +38,10 @@ void testXnodeFlowDecomposition() { .build(); FlowDecompositionParameters flowDecompositionParameters = FlowDecompositionParameters.load() .setEnableLossesCompensation(FlowDecompositionParameters.DISABLE_LOSSES_COMPENSATION) - .setRescaleEnabled(FlowDecompositionParameters.DISABLE_RESCALED_RESULTS); + .setRescaleMode(FlowDecompositionParameters.RescaleMode.NONE); FlowDecompositionComputer flowComputer = new FlowDecompositionComputer(flowDecompositionParameters); FlowDecompositionResults flowDecompositionResults = flowComputer.run(xnecProvider, network); - TestUtils.assertCoherenceTotalFlow(flowDecompositionParameters.isRescaleEnabled(), flowDecompositionResults); + TestUtils.assertCoherenceTotalFlow(flowDecompositionParameters.getRescaleMode(), flowDecompositionResults); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); assertEquals(44.109, decomposedFlowMap.get(branchId1).getXNodeFlow(), EPSILON); From 31a66d2f4e90a108794e1354b972cfe04a6cd035 Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Thu, 23 May 2024 14:57:01 +0200 Subject: [PATCH 02/13] create interface for DecomposedFlowRescaler Signed-off-by: Caio Luke --- .../DecomposedFlowRescaler.java | 17 ++++ ...DecomposedFlowRescalerAcerMethodology.java | 65 ++++++++++++++ .../DecomposedFlowRescalerNoOp.java | 25 ++++++ .../DecomposedFlowRescalerProportional.java | 62 +++++++++++++ .../DecomposedFlowsRescaler.java | 88 ------------------- .../FlowDecompositionComputer.java | 21 ++++- .../FlowDecompositionParameters.java | 2 +- .../FlowDecompositionResults.java | 12 +-- .../CgmesIntegrationTests.java | 2 +- .../FlowDecompositionParametersTests.java | 4 +- .../FlowDecompositionResultsTests.java | 9 +- .../flow_decomposition/InternalFlowTests.java | 2 +- .../flow_decomposition/RescalingTests.java | 6 +- .../powsybl/flow_decomposition/TestUtils.java | 2 +- 14 files changed, 207 insertions(+), 110 deletions(-) create mode 100644 flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescaler.java create mode 100644 flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java create mode 100644 flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerNoOp.java create mode 100644 flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java delete mode 100644 flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowsRescaler.java diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescaler.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescaler.java new file mode 100644 index 00000000..52e51cbb --- /dev/null +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescaler.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2024, 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.flow_decomposition; + +/** + * @author Sebastien Murgey {@literal } + * @author Hugo Schindler {@literal } + * @author Caio Luke {@literal } + */ +public interface DecomposedFlowRescaler { + DecomposedFlow rescale(DecomposedFlow decomposedFlow); +} diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java new file mode 100644 index 00000000..7305d101 --- /dev/null +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2024, 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.flow_decomposition; + +import com.powsybl.iidm.network.Country; + +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author Sebastien Murgey {@literal } + * @author Hugo Schindler {@literal } + * @author Caio Luke {@literal } + */ +public class DecomposedFlowRescalerAcerMethodology implements DecomposedFlowRescaler { + + public DecomposedFlowRescalerAcerMethodology() { + // empty constructor + } + + private static double reLU(double value) { + return value > 0 ? value : 0.; + } + + private static double rescaleValue(double initialValue, double delta, double sumOfReLUFlows) { + return initialValue + delta * reLU(initialValue) / sumOfReLUFlows; + } + + @Override + public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { + double acReferenceFlow = decomposedFlow.getAcReferenceFlow(); + if (Double.isNaN(acReferenceFlow)) { + return decomposedFlow; + } + + String branchId = decomposedFlow.getBranchId(); + String contingencyId = decomposedFlow.getContingencyId(); + Country country1 = decomposedFlow.getCountry1(); + Country country2 = decomposedFlow.getCountry2(); + double acMaxFlow = decomposedFlow.getAcMaxFlow(); + double dcReferenceFlow = decomposedFlow.getDcReferenceFlow(); + double allocatedFlow = decomposedFlow.getAllocatedFlow(); + double xNodeFlow = decomposedFlow.getXNodeFlow(); + double pstFlow = decomposedFlow.getPstFlow(); + double internalFlow = decomposedFlow.getInternalFlow(); + Map loopFlows = decomposedFlow.getLoopFlows(); + + double deltaToRescale = acReferenceFlow * Math.signum(acReferenceFlow) - decomposedFlow.getTotalFlow(); + double sumOfReLUFlows = reLU(allocatedFlow) + reLU(pstFlow) + reLU(xNodeFlow) + loopFlows.values().stream().mapToDouble(DecomposedFlowRescalerAcerMethodology::reLU).sum() + reLU(internalFlow); + + double rescaledAllocatedFlow = rescaleValue(allocatedFlow, deltaToRescale, sumOfReLUFlows); + double rescaledXNodeFlow = rescaleValue(xNodeFlow, deltaToRescale, sumOfReLUFlows); + double rescaledPstFlow = rescaleValue(pstFlow, deltaToRescale, sumOfReLUFlows); + double rescaleInternalFlow = rescaleValue(internalFlow, deltaToRescale, sumOfReLUFlows); + Map rescaledLoopFlows = loopFlows.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, entry -> rescaleValue(entry.getValue(), deltaToRescale, sumOfReLUFlows))); + + return new DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow, acMaxFlow, dcReferenceFlow, rescaledAllocatedFlow, rescaledXNodeFlow, rescaledPstFlow, rescaleInternalFlow, rescaledLoopFlows); + } +} diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerNoOp.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerNoOp.java new file mode 100644 index 00000000..5ade5174 --- /dev/null +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerNoOp.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2024, 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.flow_decomposition; + +/** + * @author Sebastien Murgey {@literal } + * @author Hugo Schindler {@literal } + * @author Caio Luke {@literal } + */ +public class DecomposedFlowRescalerNoOp implements DecomposedFlowRescaler { + + public DecomposedFlowRescalerNoOp() { + // empty constructor + } + + @Override + public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { + return decomposedFlow; + } +} diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java new file mode 100644 index 00000000..fd6a2d0b --- /dev/null +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2024, 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.flow_decomposition; + +import com.powsybl.iidm.network.Country; + +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author Sebastien Murgey {@literal } + * @author Hugo Schindler {@literal } + * @author Caio Luke {@literal } + */ +public class DecomposedFlowRescalerProportional implements DecomposedFlowRescaler { + private static final double MIN_FLOW_TOLERANCE = 1E-6; // min flow in MW to rescale + + public DecomposedFlowRescalerProportional() { + // empty constructor + } + + @Override + public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { + double acReferenceFlow = decomposedFlow.getAcReferenceFlow(); + if (Double.isNaN(acReferenceFlow)) { + return decomposedFlow; + } + + // if dcReferenceFlow is too small, do not rescale + double dcReferenceFlow = decomposedFlow.getDcReferenceFlow(); + if (Math.abs(dcReferenceFlow) < MIN_FLOW_TOLERANCE) { + return decomposedFlow; + } + + String branchId = decomposedFlow.getBranchId(); + String contingencyId = decomposedFlow.getContingencyId(); + Country country1 = decomposedFlow.getCountry1(); + Country country2 = decomposedFlow.getCountry2(); + double acMaxFlow = decomposedFlow.getAcMaxFlow(); + double allocatedFlow = decomposedFlow.getAllocatedFlow(); + double xNodeFlow = decomposedFlow.getXNodeFlow(); + double pstFlow = decomposedFlow.getPstFlow(); + double internalFlow = decomposedFlow.getInternalFlow(); + Map loopFlows = decomposedFlow.getLoopFlows(); + + double rescaleFactor = Math.abs(acMaxFlow / dcReferenceFlow); + + double rescaledAllocatedFlow = rescaleFactor * allocatedFlow; + double rescaledXNodeFlow = rescaleFactor * xNodeFlow; + double rescaledPstFlow = rescaleFactor * pstFlow; + double rescaleInternalFlow = rescaleFactor * internalFlow; + Map rescaledLoopFlows = loopFlows.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, entry -> rescaleFactor * entry.getValue())); + + return new DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow, acMaxFlow, dcReferenceFlow, rescaledAllocatedFlow, rescaledXNodeFlow, rescaledPstFlow, rescaleInternalFlow, rescaledLoopFlows); + } +} diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowsRescaler.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowsRescaler.java deleted file mode 100644 index 81167861..00000000 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowsRescaler.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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.commons.PowsyblException; -import com.powsybl.iidm.network.Country; - -import java.util.Map; -import java.util.stream.Collectors; - -/** - * @author Sebastien Murgey {@literal } - * @author Hugo Schindler {@literal } - * @author Caio Luke {@literal } - */ -final class DecomposedFlowsRescaler { - - private static final double MIN_FLOW_TOLERANCE = 1E-6; // min flow in MW to rescale - - private DecomposedFlowsRescaler() { - } - - private static double reLU(double value) { - return value > 0 ? value : 0.; - } - - private static double rescaleValue(double initialValue, double delta, double sumOfReLUFlows) { - return initialValue + delta * reLU(initialValue) / sumOfReLUFlows; - } - - static DecomposedFlow rescale(DecomposedFlow decomposedFlow, FlowDecompositionParameters.RescaleMode rescaleMode) { - double acReferenceFlow = decomposedFlow.getAcReferenceFlow(); - - if (Double.isNaN(acReferenceFlow)) { - return decomposedFlow; - } - - String branchId = decomposedFlow.getBranchId(); - String contingencyId = decomposedFlow.getContingencyId(); - Country country1 = decomposedFlow.getCountry1(); - Country country2 = decomposedFlow.getCountry2(); - - double acMaxFlow = decomposedFlow.getAcMaxFlow(); - double dcReferenceFlow = decomposedFlow.getDcReferenceFlow(); - double allocatedFlow = decomposedFlow.getAllocatedFlow(); - double xNodeFlow = decomposedFlow.getXNodeFlow(); - double pstFlow = decomposedFlow.getPstFlow(); - double internalFlow = decomposedFlow.getInternalFlow(); - Map loopFlows = decomposedFlow.getLoopFlows(); - - switch (rescaleMode) { - case RELU -> { - double deltaToRescale = acReferenceFlow * Math.signum(acReferenceFlow) - decomposedFlow.getTotalFlow(); - double sumOfReLUFlows = reLU(allocatedFlow) + reLU(pstFlow) + reLU(xNodeFlow) + loopFlows.values().stream().mapToDouble(DecomposedFlowsRescaler::reLU).sum() + reLU(internalFlow); - - double rescaledAllocatedFlow = rescaleValue(allocatedFlow, deltaToRescale, sumOfReLUFlows); - double rescaledXNodeFlow = rescaleValue(xNodeFlow, deltaToRescale, sumOfReLUFlows); - double rescaledPstFlow = rescaleValue(pstFlow, deltaToRescale, sumOfReLUFlows); - double rescaleInternalFlow = rescaleValue(internalFlow, deltaToRescale, sumOfReLUFlows); - Map rescaledLoopFlows = loopFlows.entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, entry -> rescaleValue(entry.getValue(), deltaToRescale, sumOfReLUFlows))); - - return new DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow, acMaxFlow, dcReferenceFlow, rescaledAllocatedFlow, rescaledXNodeFlow, rescaledPstFlow, rescaleInternalFlow, rescaledLoopFlows); - } - case PROPORTIONAL -> { - // if dcReferenceFlow is too small, do not rescale - if (Math.abs(dcReferenceFlow) < MIN_FLOW_TOLERANCE) { - return decomposedFlow; - } - double rescaleFactor = Math.abs(acMaxFlow / dcReferenceFlow); - - double rescaledAllocatedFlow = rescaleFactor * allocatedFlow; - double rescaledXNodeFlow = rescaleFactor * xNodeFlow; - double rescaledPstFlow = rescaleFactor * pstFlow; - double rescaleInternalFlow = rescaleFactor * internalFlow; - Map rescaledLoopFlows = loopFlows.entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, entry -> rescaleFactor * entry.getValue())); - - return new DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow, acMaxFlow, dcReferenceFlow, rescaledAllocatedFlow, rescaledXNodeFlow, rescaledPstFlow, rescaleInternalFlow, rescaledLoopFlows); - } - default -> throw new PowsyblException("Rescale mode not defined: " + rescaleMode); - } - } -} diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java index 9c7b0c26..f880e048 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java @@ -6,6 +6,7 @@ */ package com.powsybl.flow_decomposition; +import com.powsybl.commons.PowsyblException; import com.powsybl.flow_decomposition.glsk_provider.AutoGlskProvider; import com.powsybl.iidm.network.Branch; import com.powsybl.iidm.network.Country; @@ -32,7 +33,7 @@ public class FlowDecompositionComputer { private final LoadFlowRunningService loadFlowRunningService; private final SensitivityAnalysis.Runner sensitivityAnalysisRunner; private final LossesCompensator lossesCompensator; - + private final DecomposedFlowRescaler decomposedFlowRescaler; private final FlowDecompositionObserverList observers; public FlowDecompositionComputer() { @@ -47,6 +48,7 @@ public FlowDecompositionComputer(FlowDecompositionParameters flowDecompositionPa this.loadFlowRunningService = new LoadFlowRunningService(LoadFlow.find(loadFlowProvider)); this.sensitivityAnalysisRunner = SensitivityAnalysis.find(sensitivityAnalysisProvider); this.lossesCompensator = parameters.isLossesCompensationEnabled() ? new LossesCompensator(parameters) : null; + this.decomposedFlowRescaler = getDecomposedFlowRescaler(); this.observers = new FlowDecompositionObserverList(); } @@ -163,7 +165,7 @@ private void decomposeFlowForState(Network network, computeAllocatedAndLoopFlows(flowDecompositionResultsBuilder, nodalInjectionsMatrix, ptdfMatrix); computePstFlows(network, flowDecompositionResultsBuilder, networkMatrixIndexes, psdfMatrix); - flowDecompositionResultsBuilder.build(parameters.getRescaleMode()); + flowDecompositionResultsBuilder.build(decomposedFlowRescaler); } public void addObserver(FlowDecompositionObserver observer) { @@ -199,6 +201,21 @@ private void compensateLosses(Network network) { } } + private DecomposedFlowRescaler getDecomposedFlowRescaler() { + switch (parameters.getRescaleMode()) { + case NONE -> { + return new DecomposedFlowRescalerNoOp(); + } + case ACER_METHODOLOGY -> { + return new DecomposedFlowRescalerAcerMethodology(); + } + case PROPORTIONAL -> { + return new DecomposedFlowRescalerProportional(); + } + default -> throw new PowsyblException("DecomposedFlowRescaler not defined for mode: " + parameters.getRescaleMode()); + } + } + private LoadFlowRunningService.Result runDcLoadFlow(Network network) { return loadFlowRunningService.runDcLoadflow(network, loadFlowParameters); } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionParameters.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionParameters.java index e7c2f881..b06904ce 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionParameters.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionParameters.java @@ -29,7 +29,7 @@ public class FlowDecompositionParameters { public enum RescaleMode { NONE, - RELU, + ACER_METHODOLOGY, PROPORTIONAL } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java index 862dda91..0b5b555b 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java @@ -73,15 +73,15 @@ void saveDcReferenceFlow(Map dcReferenceFlow) { this.dcReferenceFlow = dcReferenceFlow; } - void build(FlowDecompositionParameters.RescaleMode rescaleMode) { + void build(DecomposedFlowRescaler decomposedFlowRescaler) { allocatedAndLoopFlowsMatrix.toMap() .forEach((branchId, decomposedFlow) -> { String xnecId = NetworkUtil.getXnecId(contingencyId, branchId); - decomposedFlowMap.put(xnecId, createDecomposedFlow(branchId, decomposedFlow, rescaleMode)); + decomposedFlowMap.put(xnecId, createDecomposedFlow(branchId, decomposedFlow, decomposedFlowRescaler)); }); } - private DecomposedFlow createDecomposedFlow(String branchId, Map allocatedAndLoopFlowMap, FlowDecompositionParameters.RescaleMode rescaleMode) { + private DecomposedFlow createDecomposedFlow(String branchId, Map allocatedAndLoopFlowMap, DecomposedFlowRescaler decomposedFlowRescaler) { Map loopFlowsMap = allocatedAndLoopFlowMap.entrySet().stream() .filter(entry -> entry.getKey().startsWith(LOOP_FLOWS_COLUMN_PREFIX)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); @@ -92,11 +92,7 @@ private DecomposedFlow createDecomposedFlow(String branchId, Map Country country2 = NetworkUtil.getTerminalCountry(xnecMap.get(branchId).getTerminal2()); double internalFlow = extractInternalFlow(loopFlowsMap, country1, country2); DecomposedFlow decomposedFlow = new DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow.get(branchId), acMaxFlow.get(branchId), dcReferenceFlow.get(branchId), allocatedFlow, xNodeFlow, pstFlow, internalFlow, loopFlowsMap); - if (rescaleMode.equals(FlowDecompositionParameters.RescaleMode.NONE)) { - return decomposedFlow; - } else { - return DecomposedFlowsRescaler.rescale(decomposedFlow, rescaleMode); - } + return decomposedFlowRescaler.rescale(decomposedFlow); } private double extractInternalFlow(Map loopFlowsMap, Country country1, Country country2) { diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/CgmesIntegrationTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/CgmesIntegrationTests.java index a9afd729..016b96c9 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/CgmesIntegrationTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/CgmesIntegrationTests.java @@ -59,7 +59,7 @@ void checkFlowDecompositionWorksOnCgmesFile() { .setEnableLossesCompensation(FlowDecompositionParameters.ENABLE_LOSSES_COMPENSATION) .setLossesCompensationEpsilon(FlowDecompositionParameters.DISABLE_LOSSES_COMPENSATION_EPSILON) .setSensitivityEpsilon(FlowDecompositionParameters.DISABLE_SENSITIVITY_EPSILON) - .setRescaleMode(FlowDecompositionParameters.RescaleMode.RELU); + .setRescaleMode(FlowDecompositionParameters.RescaleMode.ACER_METHODOLOGY); String xnecId = "044cd006-c766-11e1-8775-005056c00008"; XnecProvider xnecProvider = XnecProviderByIds.builder().addNetworkElementsOnBasecase(Set.of(xnecId)).build(); FlowDecompositionComputer flowDecompositionComputer = new FlowDecompositionComputer(flowDecompositionParameters); diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionParametersTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionParametersTests.java index f1b35826..3095dc88 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionParametersTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionParametersTests.java @@ -61,7 +61,7 @@ void checkCompleteConfigurationOfParameters() { mapModuleConfig.setStringProperty("enable-losses-compensation", Boolean.toString(true)); mapModuleConfig.setStringProperty("losses-compensation-epsilon", Double.toString(2e-5)); mapModuleConfig.setStringProperty("sensitivity-epsilon", Double.toString(3e-3)); - mapModuleConfig.setStringProperty("rescale-mode", FlowDecompositionParameters.RescaleMode.RELU.name()); + mapModuleConfig.setStringProperty("rescale-mode", FlowDecompositionParameters.RescaleMode.ACER_METHODOLOGY.name()); mapModuleConfig.setStringProperty("dc-fallback-enabled-after-ac-divergence", Boolean.toString(false)); mapModuleConfig.setStringProperty("sensitivity-variable-batch-size", Integer.toString(1234)); @@ -69,7 +69,7 @@ void checkCompleteConfigurationOfParameters() { assertTrue(parameters.isLossesCompensationEnabled()); assertEquals(2e-5, parameters.getLossesCompensationEpsilon(), EPSILON); assertEquals(3e-3, parameters.getSensitivityEpsilon(), EPSILON); - assertEquals(FlowDecompositionParameters.RescaleMode.RELU, parameters.getRescaleMode()); + assertEquals(FlowDecompositionParameters.RescaleMode.ACER_METHODOLOGY, parameters.getRescaleMode()); assertFalse(parameters.isDcFallbackEnabledAfterAcDivergence()); assertEquals(1234, parameters.getSensitivityVariableBatchSize()); } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java index aa2cc9f4..fefc579b 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java @@ -81,13 +81,14 @@ void testResultMetadata() { void testBuilderNState() { Set nStateXnecList = xnecProvider.getNetworkElements(network); FlowDecompositionResults.PerStateBuilder nStateBuilder = flowDecompositionResults.getBuilder(nStateXnecList); + DecomposedFlowRescaler decomposedFlowRescaler = new DecomposedFlowRescalerNoOp(); nStateBuilder.saveAcReferenceFlow(Map.of(branchId, 10.0)); nStateBuilder.saveAcMaxFlow(Map.of(branchId, 10.0)); nStateBuilder.saveDcReferenceFlow(Map.of(branchId, 11.0)); nStateBuilder.saveAllocatedAndLoopFlowsMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(ALLOCATED_COLUMN_NAME, 0, NetworkUtil.getLoopFlowIdFromCountry(FR), 1), alloMatrix)); nStateBuilder.savePstFlowMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(PST_COLUMN_NAME, 0), pstMatrix)); - nStateBuilder.build(FlowDecompositionParameters.RescaleMode.NONE); + nStateBuilder.build(decomposedFlowRescaler); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); assertEquals(1, decomposedFlowMap.size()); @@ -108,13 +109,14 @@ void testBuilderN1State() { Set n1StateContingency2XnecList = xnecProvider.getNetworkElements(contingencyId2, network); FlowDecompositionResults.PerStateBuilder n1StateBuilder = flowDecompositionResults.getBuilder(contingencyId2, n1StateContingency2XnecList); String xnecId = "DB000011 DF000011 1_DD000011 DF000011 1"; + DecomposedFlowRescaler decomposedFlowRescaler = new DecomposedFlowRescalerNoOp(); n1StateBuilder.saveAcReferenceFlow(Map.of(branchId, 10.0)); n1StateBuilder.saveAcMaxFlow(Map.of(branchId, 10.0)); n1StateBuilder.saveDcReferenceFlow(Map.of(branchId, 11.0)); n1StateBuilder.saveAllocatedAndLoopFlowsMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(ALLOCATED_COLUMN_NAME, 0, NetworkUtil.getLoopFlowIdFromCountry(FR), 1), alloMatrix)); n1StateBuilder.savePstFlowMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(PST_COLUMN_NAME, 0), pstMatrix)); - n1StateBuilder.build(FlowDecompositionParameters.RescaleMode.NONE); + n1StateBuilder.build(decomposedFlowRescaler); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); assertEquals(1, decomposedFlowMap.size()); @@ -135,13 +137,14 @@ void testBuilderN2State() { Set n1StateContingency3XnecList = xnecProvider.getNetworkElements(contingencyId3, network); FlowDecompositionResults.PerStateBuilder n2StateBuilder = flowDecompositionResults.getBuilder(contingencyId3, n1StateContingency3XnecList); String xnecId = "DB000011 DF000011 1_FB000011 FD000011 1_FB000021 FD000021 1"; + DecomposedFlowRescaler decomposedFlowRescaler = new DecomposedFlowRescalerNoOp(); n2StateBuilder.saveAcReferenceFlow(Map.of(branchId, 10.0)); n2StateBuilder.saveAcMaxFlow(Map.of(branchId, 10.0)); n2StateBuilder.saveDcReferenceFlow(Map.of(branchId, 11.0)); n2StateBuilder.saveAllocatedAndLoopFlowsMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(ALLOCATED_COLUMN_NAME, 0, NetworkUtil.getLoopFlowIdFromCountry(FR), 1), alloMatrix)); n2StateBuilder.savePstFlowMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(PST_COLUMN_NAME, 0), pstMatrix)); - n2StateBuilder.build(FlowDecompositionParameters.RescaleMode.NONE); + n2StateBuilder.build(decomposedFlowRescaler); Map decomposedFlowMap = flowDecompositionResults.getDecomposedFlowMap(); assertEquals(1, decomposedFlowMap.size()); diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java index a2138660..acf5efee 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java @@ -97,7 +97,7 @@ private DecomposedFlow getRescaledFlow(double internalFlow, double acReferenceFl DecomposedFlow decomposedFlow = getDecomposedFlow(internalFlow, acReferenceFlow, dcReferenceFlow); assertEquals(Math.abs(dcReferenceFlow), decomposedFlow.getTotalFlow(), EPSILON); - return DecomposedFlowsRescaler.rescale(decomposedFlow, FlowDecompositionParameters.RescaleMode.RELU); + return new DecomposedFlowRescalerAcerMethodology().rescale(decomposedFlow); } private void checkRescaleAcReference(double acReferenceFlow, double dcReferenceFlow, DecomposedFlow rescaledFlow, double expectedAllocatedFlow, double expectedInternalFlow, double expectedPstFlow, double expectedLoopFlowBE, double expectedLoopFlowES) { diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java index 4419c580..2854f9d2 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java @@ -67,7 +67,7 @@ private DecomposedFlow getRescaledFlow(double acReferenceFlow, double dcReferenc DecomposedFlow decomposedFlow = getDecomposedFlow(acReferenceFlow, dcReferenceFlow); assertEquals(Math.abs(dcReferenceFlow), decomposedFlow.getTotalFlow(), EPSILON); - return DecomposedFlowsRescaler.rescale(decomposedFlow, FlowDecompositionParameters.RescaleMode.RELU); + return new DecomposedFlowRescalerAcerMethodology().rescale(decomposedFlow); } @Test @@ -137,7 +137,7 @@ void testAcerNormalizationWithPositiveAbsoluteSmallerReferenceFlows() { @Test void testReLUNormalizationWithFlowDecompositionResultsWithPstNetwork() { String networkFileName = "NETWORK_PST_FLOW_WITH_COUNTRIES.uct"; - testNormalizationWithFlowDecompositionResults(networkFileName, FlowDecompositionParameters.RescaleMode.RELU); + testNormalizationWithFlowDecompositionResults(networkFileName, FlowDecompositionParameters.RescaleMode.ACER_METHODOLOGY); } @Test @@ -178,7 +178,7 @@ void testRescalingDoesNotOccurWhenAcDiverge() { .setEnableLossesCompensation(FlowDecompositionParameters.ENABLE_LOSSES_COMPENSATION) .setLossesCompensationEpsilon(FlowDecompositionParameters.DISABLE_LOSSES_COMPENSATION_EPSILON) .setSensitivityEpsilon(FlowDecompositionParameters.DISABLE_SENSITIVITY_EPSILON) - .setRescaleMode(FlowDecompositionParameters.RescaleMode.RELU); + .setRescaleMode(FlowDecompositionParameters.RescaleMode.ACER_METHODOLOGY); FlowDecompositionComputer flowDecompositionComputer = new FlowDecompositionComputer(flowDecompositionParameters); XnecProvider xnecProvider = XnecProviderByIds.builder().addNetworkElementsOnBasecase(Set.of(xnecId)).build(); diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java index b6fd7df4..8f2a8b5b 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java @@ -41,7 +41,7 @@ public static void assertCoherenceTotalFlow(FlowDecompositionParameters.RescaleM for (String xnec : flowDecompositionResults.getDecomposedFlowMap().keySet()) { DecomposedFlow decomposedFlow = flowDecompositionResults.getDecomposedFlowMap().get(xnec); switch (rescaleMode) { - case RELU -> assertEquals(Math.abs(decomposedFlow.getAcReferenceFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); + case ACER_METHODOLOGY -> assertEquals(Math.abs(decomposedFlow.getAcReferenceFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); case PROPORTIONAL -> assertEquals(Math.abs(decomposedFlow.getAcMaxFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); default -> assertEquals(Math.abs(decomposedFlow.getDcReferenceFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); } From 0e35b7e80db7216c8a5014f17e120a761261f932 Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Thu, 23 May 2024 15:41:04 +0200 Subject: [PATCH 03/13] create builder for DecomposedFlow Signed-off-by: Caio Luke --- .../flow_decomposition/DecomposedFlow.java | 26 ++--- .../DecomposedFlowBuilder.java | 99 +++++++++++++++++++ ...DecomposedFlowRescalerAcerMethodology.java | 15 ++- .../DecomposedFlowRescalerProportional.java | 15 ++- .../FlowDecompositionResults.java | 15 ++- .../flow_decomposition/InternalFlowTests.java | 15 ++- .../flow_decomposition/RescalingTests.java | 15 ++- 7 files changed, 182 insertions(+), 18 deletions(-) create mode 100644 flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowBuilder.java diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java index d9df85cf..ad45c258 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java @@ -35,19 +35,19 @@ public class DecomposedFlow { static final String PST_COLUMN_NAME = "PST Flow"; static final String INTERNAL_COLUMN_NAME = "Internal Flow"; - protected DecomposedFlow(String branchId, String contingencyId, Country country1, Country country2, double acReferenceFlow, double acMaxFlow, double dcReferenceFlow, double allocatedFlow, double xNodeFlow, double pstFlow, double internalFlow, Map loopFlowsMap) { - this.branchId = branchId; - this.contingencyId = contingencyId; - this.country1 = country1; - this.country2 = country2; - this.acReferenceFlow = acReferenceFlow; - this.acMaxFlow = acMaxFlow; - this.dcReferenceFlow = dcReferenceFlow; - this.allocatedFlow = allocatedFlow; - this.xNodeFlow = xNodeFlow; - this.pstFlow = pstFlow; - this.internalFlow = internalFlow; - this.loopFlowsMap.putAll(loopFlowsMap); + protected DecomposedFlow(DecomposedFlowBuilder builder) { + this.branchId = builder.branchId; + this.contingencyId = builder.contingencyId; + this.country1 = builder.country1; + this.country2 = builder.country2; + this.acReferenceFlow = builder.acReferenceFlow; + this.acMaxFlow = builder.acMaxFlow; + this.dcReferenceFlow = builder.dcReferenceFlow; + this.allocatedFlow = builder.allocatedFlow; + this.xNodeFlow = builder.xNodeFlow; + this.pstFlow = builder.pstFlow; + this.internalFlow = builder.internalFlow; + this.loopFlowsMap.putAll(builder.loopFlowsMap); } public String getBranchId() { diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowBuilder.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowBuilder.java new file mode 100644 index 00000000..33097efe --- /dev/null +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowBuilder.java @@ -0,0 +1,99 @@ +/* + * 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.iidm.network.Country; + +import java.util.Map; + +/** + * @author Caio Luke {@literal } + * @author Sebastien Murgey {@literal } + * @author Hugo Schindler {@literal } + */ +public class DecomposedFlowBuilder { + protected String branchId; + protected String contingencyId; + protected Country country1; + protected Country country2; + protected double acReferenceFlow; + protected double acMaxFlow; + protected double dcReferenceFlow; + protected double allocatedFlow; + protected double xNodeFlow; + protected double pstFlow; + protected double internalFlow; + protected Map loopFlowsMap; + + public DecomposedFlowBuilder() { + // empty constructor + } + + public DecomposedFlowBuilder addBranchId(String branchId) { + this.branchId = branchId; + return this; + } + + public DecomposedFlowBuilder addContingencyId(String contingencyId) { + this.contingencyId = contingencyId; + return this; + } + + public DecomposedFlowBuilder addCountry1(Country country1) { + this.country1 = country1; + return this; + } + + public DecomposedFlowBuilder addCountry2(Country country2) { + this.country2 = country2; + return this; + } + + public DecomposedFlowBuilder addAcReferenceFlow(double acReferenceFlow) { + this.acReferenceFlow = acReferenceFlow; + return this; + } + + public DecomposedFlowBuilder addAcMaxFlow(double acMaxFlow) { + this.acMaxFlow = acMaxFlow; + return this; + } + + public DecomposedFlowBuilder addDcReferenceFlow(double dcReferenceFlow) { + this.dcReferenceFlow = dcReferenceFlow; + return this; + } + + public DecomposedFlowBuilder addAllocatedFlow(double allocatedFlow) { + this.allocatedFlow = allocatedFlow; + return this; + } + + public DecomposedFlowBuilder addXNodeFlow(double xNodeFlow) { + this.xNodeFlow = xNodeFlow; + return this; + } + + public DecomposedFlowBuilder addPstFlow(double pstFlow) { + this.pstFlow = pstFlow; + return this; + } + + public DecomposedFlowBuilder addInternalFlow(double internalFlow) { + this.internalFlow = internalFlow; + return this; + } + + public DecomposedFlowBuilder addLoopFlowsMap(Map loopFlowsMap) { + this.loopFlowsMap = loopFlowsMap; + return this; + } + + public DecomposedFlow build() { + return new DecomposedFlow(this); + } +} diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java index 7305d101..4fdadd56 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java @@ -60,6 +60,19 @@ public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { Map rescaledLoopFlows = loopFlows.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, entry -> rescaleValue(entry.getValue(), deltaToRescale, sumOfReLUFlows))); - return new DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow, acMaxFlow, dcReferenceFlow, rescaledAllocatedFlow, rescaledXNodeFlow, rescaledPstFlow, rescaleInternalFlow, rescaledLoopFlows); + return new DecomposedFlowBuilder() + .addBranchId(branchId) + .addContingencyId(contingencyId) + .addCountry1(country1) + .addCountry2(country2) + .addAcReferenceFlow(acReferenceFlow) + .addAcMaxFlow(acMaxFlow) + .addDcReferenceFlow(dcReferenceFlow) + .addAllocatedFlow(rescaledAllocatedFlow) + .addXNodeFlow(rescaledXNodeFlow) + .addPstFlow(rescaledPstFlow) + .addInternalFlow(rescaleInternalFlow) + .addLoopFlowsMap(rescaledLoopFlows) + .build(); } } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java index fd6a2d0b..a2fc3c70 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java @@ -57,6 +57,19 @@ public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { Map rescaledLoopFlows = loopFlows.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, entry -> rescaleFactor * entry.getValue())); - return new DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow, acMaxFlow, dcReferenceFlow, rescaledAllocatedFlow, rescaledXNodeFlow, rescaledPstFlow, rescaleInternalFlow, rescaledLoopFlows); + return new DecomposedFlowBuilder() + .addBranchId(branchId) + .addContingencyId(contingencyId) + .addCountry1(country1) + .addCountry2(country2) + .addAcReferenceFlow(acReferenceFlow) + .addAcMaxFlow(acMaxFlow) + .addDcReferenceFlow(dcReferenceFlow) + .addAllocatedFlow(rescaledAllocatedFlow) + .addXNodeFlow(rescaledXNodeFlow) + .addPstFlow(rescaledPstFlow) + .addInternalFlow(rescaleInternalFlow) + .addLoopFlowsMap(rescaledLoopFlows) + .build(); } } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java index 0b5b555b..33b039a4 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java @@ -91,7 +91,20 @@ private DecomposedFlow createDecomposedFlow(String branchId, Map 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 DecomposedFlow(branchId, contingencyId, country1, country2, acReferenceFlow.get(branchId), acMaxFlow.get(branchId), dcReferenceFlow.get(branchId), allocatedFlow, xNodeFlow, pstFlow, internalFlow, loopFlowsMap); + DecomposedFlow decomposedFlow = new DecomposedFlowBuilder() + .addBranchId(branchId) + .addContingencyId(contingencyId) + .addCountry1(country1) + .addCountry2(country2) + .addAcReferenceFlow(acReferenceFlow.get(branchId)) + .addAcMaxFlow(acMaxFlow.get(branchId)) + .addDcReferenceFlow(dcReferenceFlow.get(branchId)) + .addAllocatedFlow(allocatedFlow) + .addXNodeFlow(xNodeFlow) + .addPstFlow(pstFlow) + .addInternalFlow(internalFlow) + .addLoopFlowsMap(loopFlowsMap) + .build(); return decomposedFlowRescaler.rescale(decomposedFlow); } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java index acf5efee..ed286070 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java @@ -90,7 +90,20 @@ private DecomposedFlow getDecomposedFlow(double internalFlow, double acReference loopFlows.put(NetworkUtil.getLoopFlowIdFromCountry(Country.ES), 700.); Country country1 = Country.FR; Country country2 = Country.FR; - return new DecomposedFlow("", "", country1, country2, acReferenceFlow, acReferenceFlow, dcReferenceFlow, allocatedFlow, 0, pstFlow, internalFlow, loopFlows); + return new DecomposedFlowBuilder() + .addBranchId("") + .addContingencyId("") + .addCountry1(country1) + .addCountry2(country2) + .addAcReferenceFlow(acReferenceFlow) + .addAcMaxFlow(acReferenceFlow) + .addDcReferenceFlow(dcReferenceFlow) + .addAllocatedFlow(allocatedFlow) + .addXNodeFlow(0) + .addPstFlow(pstFlow) + .addInternalFlow(internalFlow) + .addLoopFlowsMap(loopFlows) + .build(); } private DecomposedFlow getRescaledFlow(double internalFlow, double acReferenceFlow, double dcReferenceFlow) { diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java index 2854f9d2..846559a1 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java @@ -60,7 +60,20 @@ private DecomposedFlow getDecomposedFlow(double acReferenceFlow, double dcRefere loopFlows.put(NetworkUtil.getLoopFlowIdFromCountry(Country.ES), 700.); Country country1 = Country.FR; Country country2 = Country.FR; - return new DecomposedFlow("", "", country1, country2, acReferenceFlow, acReferenceFlow, dcReferenceFlow, allocatedFlow, 0, pstFlow, internalFlow, loopFlows); + return new DecomposedFlowBuilder() + .addBranchId("") + .addContingencyId("") + .addCountry1(country1) + .addCountry2(country2) + .addAcReferenceFlow(acReferenceFlow) + .addAcMaxFlow(acReferenceFlow) + .addDcReferenceFlow(dcReferenceFlow) + .addAllocatedFlow(allocatedFlow) + .addXNodeFlow(0) + .addPstFlow(pstFlow) + .addInternalFlow(internalFlow) + .addLoopFlowsMap(loopFlows) + .build(); } private DecomposedFlow getRescaledFlow(double acReferenceFlow, double dcReferenceFlow) { From 1a043b7474d63503b2aea91542c61223b452bb15 Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Thu, 23 May 2024 15:44:25 +0200 Subject: [PATCH 04/13] change modifier in FlowComputerUtils Signed-off-by: Caio Luke --- .../java/com/powsybl/flow_decomposition/FlowComputerUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowComputerUtils.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowComputerUtils.java index a3b55485..ae956139 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowComputerUtils.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowComputerUtils.java @@ -48,7 +48,7 @@ public static Map getReferenceFlow(Collection xnecList) )); } - public static Map getMaxFlow(Collection xnecList) { + private static Map getMaxFlow(Collection xnecList) { return xnecList.stream() .collect(Collectors.toMap( Identifiable::getId, From 896e87ff3bca572d1727acdf6f23b593006d5a66 Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Thu, 23 May 2024 16:21:30 +0200 Subject: [PATCH 05/13] remove acMaxFlow and add acTerminal2ReferenceFlow instead Signed-off-by: Caio Luke --- .../flow_decomposition/CsvExporter.java | 6 ++-- .../flow_decomposition/DecomposedFlow.java | 26 ++++++++++------- .../DecomposedFlowBuilder.java | 12 ++++---- ...DecomposedFlowRescalerAcerMethodology.java | 12 ++++---- .../DecomposedFlowRescalerProportional.java | 14 ++++++---- .../flow_decomposition/FlowComputerUtils.java | 28 ++++--------------- .../FlowDecompositionComputer.java | 19 ++++++------- .../FlowDecompositionObserverList.java | 5 ++-- .../FlowDecompositionResults.java | 16 +++++------ .../FlowDecompositionResultsTests.java | 18 ++++++------ .../flow_decomposition/InternalFlowTests.java | 6 ++-- .../flow_decomposition/LoopFlowTests.java | 8 +++--- .../flow_decomposition/RescalingTests.java | 8 +++--- .../powsybl/flow_decomposition/TestUtils.java | 4 +-- 14 files changed, 86 insertions(+), 96 deletions(-) diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/CsvExporter.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/CsvExporter.java index e5065529..04008736 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/CsvExporter.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/CsvExporter.java @@ -85,7 +85,8 @@ private void printHeaderRow(Set loopFlowKeys, CSVPrinter printer) { failSilentlyPrint(printer, DecomposedFlow.INTERNAL_COLUMN_NAME); failSilentlyPrint(printer, DecomposedFlow.PST_COLUMN_NAME); loopFlowKeys.stream().sorted().forEach(loopFlowKey -> failSilentlyPrint(printer, loopFlowKey)); - failSilentlyPrint(printer, DecomposedFlow.AC_REFERENCE_FLOW_COLUMN_NAME); + failSilentlyPrint(printer, DecomposedFlow.AC_REFERENCE_FLOW_1_COLUMN_NAME); + failSilentlyPrint(printer, DecomposedFlow.AC_REFERENCE_FLOW_2_COLUMN_NAME); failSilentlyPrint(printer, DecomposedFlow.DC_REFERENCE_FLOW_COLUMN_NAME); failSilentlyPrintLn(printer); } @@ -100,7 +101,8 @@ private void printContentRow(String xnecId, DecomposedFlow decomposedFlow, Set failSilentlyPrint(printer, decomposedFlow.getLoopFlows().getOrDefault(loopFlowKey, NO_FLOW))); - failSilentlyPrint(printer, decomposedFlow.getAcReferenceFlow()); + failSilentlyPrint(printer, decomposedFlow.getAcTerminal1ReferenceFlow()); + failSilentlyPrint(printer, decomposedFlow.getAcTerminal2ReferenceFlow()); failSilentlyPrint(printer, decomposedFlow.getDcReferenceFlow()); failSilentlyPrintLn(printer); } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java index ad45c258..c920a149 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java @@ -19,8 +19,8 @@ public class DecomposedFlow { private final String contingencyId; private final Country country1; private final Country country2; - private final double acReferenceFlow; - private final double acMaxFlow; + private final double acTerminal1ReferenceFlow; + private final double acTerminal2ReferenceFlow; private final double dcReferenceFlow; private final double allocatedFlow; private final double xNodeFlow; @@ -28,7 +28,8 @@ public class DecomposedFlow { private final double internalFlow; private final Map loopFlowsMap = new TreeMap<>(); static final double NO_FLOW = 0.; - static final String AC_REFERENCE_FLOW_COLUMN_NAME = "Reference AC Flow"; + static final String AC_REFERENCE_FLOW_1_COLUMN_NAME = "Reference AC Flow 1"; + static final String AC_REFERENCE_FLOW_2_COLUMN_NAME = "Reference AC Flow 2"; static final String DC_REFERENCE_FLOW_COLUMN_NAME = "Reference DC Flow"; static final String ALLOCATED_COLUMN_NAME = "Allocated Flow"; static final String XNODE_COLUMN_NAME = "Xnode Flow"; @@ -40,8 +41,8 @@ protected DecomposedFlow(DecomposedFlowBuilder builder) { this.contingencyId = builder.contingencyId; this.country1 = builder.country1; this.country2 = builder.country2; - this.acReferenceFlow = builder.acReferenceFlow; - this.acMaxFlow = builder.acMaxFlow; + this.acTerminal1ReferenceFlow = builder.acTerminal1ReferenceFlow; + this.acTerminal2ReferenceFlow = builder.acTerminal2ReferenceFlow; this.dcReferenceFlow = builder.dcReferenceFlow; this.allocatedFlow = builder.allocatedFlow; this.xNodeFlow = builder.xNodeFlow; @@ -70,12 +71,12 @@ public Country getCountry2() { return country2; } - public double getAcReferenceFlow() { - return acReferenceFlow; + public double getAcTerminal1ReferenceFlow() { + return acTerminal1ReferenceFlow; } - public double getAcMaxFlow() { - return acMaxFlow; + public double getAcTerminal2ReferenceFlow() { + return acTerminal2ReferenceFlow; } public double getDcReferenceFlow() { @@ -118,6 +119,10 @@ public double getTotalFlow() { return getAllocatedFlow() + getXNodeFlow() + getPstFlow() + getInternalFlow() + getTotalLoopFlow(); } + public double getMaxAbsAcFlow() { + return Math.max(Math.abs(acTerminal1ReferenceFlow), Math.abs(acTerminal2ReferenceFlow)); + } + @Override public String toString() { return String.format("branchId: %s, contingencyId: %s, decomposition: %s", branchId, contingencyId, getAllKeyMap()); @@ -125,7 +130,8 @@ public String toString() { private TreeMap getAllKeyMap() { TreeMap localDecomposedFlowMap = new TreeMap<>(); - localDecomposedFlowMap.put(AC_REFERENCE_FLOW_COLUMN_NAME, getAcReferenceFlow()); + localDecomposedFlowMap.put(AC_REFERENCE_FLOW_1_COLUMN_NAME, getAcTerminal1ReferenceFlow()); + localDecomposedFlowMap.put(AC_REFERENCE_FLOW_2_COLUMN_NAME, getAcTerminal2ReferenceFlow()); localDecomposedFlowMap.put(DC_REFERENCE_FLOW_COLUMN_NAME, getDcReferenceFlow()); localDecomposedFlowMap.put(ALLOCATED_COLUMN_NAME, getAllocatedFlow()); localDecomposedFlowMap.put(XNODE_COLUMN_NAME, getXNodeFlow()); diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowBuilder.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowBuilder.java index 33097efe..3fc6396c 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowBuilder.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowBuilder.java @@ -20,8 +20,8 @@ public class DecomposedFlowBuilder { protected String contingencyId; protected Country country1; protected Country country2; - protected double acReferenceFlow; - protected double acMaxFlow; + protected double acTerminal1ReferenceFlow; + protected double acTerminal2ReferenceFlow; protected double dcReferenceFlow; protected double allocatedFlow; protected double xNodeFlow; @@ -53,13 +53,13 @@ public DecomposedFlowBuilder addCountry2(Country country2) { return this; } - public DecomposedFlowBuilder addAcReferenceFlow(double acReferenceFlow) { - this.acReferenceFlow = acReferenceFlow; + public DecomposedFlowBuilder addAcTerminal1ReferenceFlow(double acTerminal1ReferenceFlow) { + this.acTerminal1ReferenceFlow = acTerminal1ReferenceFlow; return this; } - public DecomposedFlowBuilder addAcMaxFlow(double acMaxFlow) { - this.acMaxFlow = acMaxFlow; + public DecomposedFlowBuilder addAcTerminal2ReferenceFlow(double acTerminal2ReferenceFlow) { + this.acTerminal2ReferenceFlow = acTerminal2ReferenceFlow; return this; } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java index 4fdadd56..618b9aa4 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java @@ -33,8 +33,8 @@ private static double rescaleValue(double initialValue, double delta, double sum @Override public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { - double acReferenceFlow = decomposedFlow.getAcReferenceFlow(); - if (Double.isNaN(acReferenceFlow)) { + double acTerminal1ReferenceFlow = decomposedFlow.getAcTerminal1ReferenceFlow(); + if (Double.isNaN(acTerminal1ReferenceFlow)) { return decomposedFlow; } @@ -42,7 +42,7 @@ public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { String contingencyId = decomposedFlow.getContingencyId(); Country country1 = decomposedFlow.getCountry1(); Country country2 = decomposedFlow.getCountry2(); - double acMaxFlow = decomposedFlow.getAcMaxFlow(); + double acTerminal2ReferenceFlow = decomposedFlow.getAcTerminal2ReferenceFlow(); double dcReferenceFlow = decomposedFlow.getDcReferenceFlow(); double allocatedFlow = decomposedFlow.getAllocatedFlow(); double xNodeFlow = decomposedFlow.getXNodeFlow(); @@ -50,7 +50,7 @@ public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { double internalFlow = decomposedFlow.getInternalFlow(); Map loopFlows = decomposedFlow.getLoopFlows(); - double deltaToRescale = acReferenceFlow * Math.signum(acReferenceFlow) - decomposedFlow.getTotalFlow(); + double deltaToRescale = acTerminal1ReferenceFlow * Math.signum(acTerminal1ReferenceFlow) - decomposedFlow.getTotalFlow(); double sumOfReLUFlows = reLU(allocatedFlow) + reLU(pstFlow) + reLU(xNodeFlow) + loopFlows.values().stream().mapToDouble(DecomposedFlowRescalerAcerMethodology::reLU).sum() + reLU(internalFlow); double rescaledAllocatedFlow = rescaleValue(allocatedFlow, deltaToRescale, sumOfReLUFlows); @@ -65,8 +65,8 @@ public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { .addContingencyId(contingencyId) .addCountry1(country1) .addCountry2(country2) - .addAcReferenceFlow(acReferenceFlow) - .addAcMaxFlow(acMaxFlow) + .addAcTerminal1ReferenceFlow(acTerminal1ReferenceFlow) + .addAcTerminal2ReferenceFlow(acTerminal2ReferenceFlow) .addDcReferenceFlow(dcReferenceFlow) .addAllocatedFlow(rescaledAllocatedFlow) .addXNodeFlow(rescaledXNodeFlow) diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java index a2fc3c70..d34b1f65 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java @@ -26,8 +26,9 @@ public DecomposedFlowRescalerProportional() { @Override public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { - double acReferenceFlow = decomposedFlow.getAcReferenceFlow(); - if (Double.isNaN(acReferenceFlow)) { + double acTerminal1ReferenceFlow = decomposedFlow.getAcTerminal1ReferenceFlow(); + double acTerminal2ReferenceFlow = decomposedFlow.getAcTerminal2ReferenceFlow(); + if (Double.isNaN(acTerminal1ReferenceFlow) || Double.isNaN(acTerminal2ReferenceFlow)) { return decomposedFlow; } @@ -41,14 +42,15 @@ public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { String contingencyId = decomposedFlow.getContingencyId(); Country country1 = decomposedFlow.getCountry1(); Country country2 = decomposedFlow.getCountry2(); - double acMaxFlow = decomposedFlow.getAcMaxFlow(); double allocatedFlow = decomposedFlow.getAllocatedFlow(); double xNodeFlow = decomposedFlow.getXNodeFlow(); double pstFlow = decomposedFlow.getPstFlow(); double internalFlow = decomposedFlow.getInternalFlow(); Map loopFlows = decomposedFlow.getLoopFlows(); - double rescaleFactor = Math.abs(acMaxFlow / dcReferenceFlow); + // rescale proportionally to max (abs) ac flow + double acMaxAbsFlow = decomposedFlow.getMaxAbsAcFlow(); + double rescaleFactor = Math.abs(acMaxAbsFlow / dcReferenceFlow); double rescaledAllocatedFlow = rescaleFactor * allocatedFlow; double rescaledXNodeFlow = rescaleFactor * xNodeFlow; @@ -62,8 +64,8 @@ public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { .addContingencyId(contingencyId) .addCountry1(country1) .addCountry2(country2) - .addAcReferenceFlow(acReferenceFlow) - .addAcMaxFlow(acMaxFlow) + .addAcTerminal1ReferenceFlow(acTerminal1ReferenceFlow) + .addAcTerminal2ReferenceFlow(acTerminal2ReferenceFlow) .addDcReferenceFlow(dcReferenceFlow) .addAllocatedFlow(rescaledAllocatedFlow) .addXNodeFlow(rescaledXNodeFlow) diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowComputerUtils.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowComputerUtils.java index ae956139..206e5d75 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowComputerUtils.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowComputerUtils.java @@ -9,6 +9,7 @@ import com.powsybl.iidm.network.Branch; import com.powsybl.iidm.network.Identifiable; +import com.powsybl.iidm.network.TwoSides; import java.util.Collection; import java.util.Map; @@ -26,37 +27,18 @@ private FlowComputerUtils() { // empty constructor } - public static Map calculateAcReferenceFlows(Collection xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) { + public static Map calculateAcTerminalReferenceFlows(Collection xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult, TwoSides side) { if (loadFlowServiceAcResult.fallbackHasBeenActivated()) { return xnecList.stream().collect(Collectors.toMap(Identifiable::getId, branch -> Double.NaN)); } - return getReferenceFlow(xnecList); + return getTerminalReferenceFlow(xnecList, side); } - public static Map calculateAcMaxFlows(Collection xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) { - if (loadFlowServiceAcResult.fallbackHasBeenActivated()) { - return xnecList.stream().collect(Collectors.toMap(Identifiable::getId, branch -> Double.NaN)); - } - return getMaxFlow(xnecList); - } - - public static Map getReferenceFlow(Collection xnecList) { + public static Map getTerminalReferenceFlow(Collection xnecList, TwoSides side) { return xnecList.stream() .collect(Collectors.toMap( Identifiable::getId, - FlowComputerUtils::getReferenceP + branch -> branch.getTerminal(side).getP() )); } - - private static Map getMaxFlow(Collection xnecList) { - return xnecList.stream() - .collect(Collectors.toMap( - Identifiable::getId, - branch -> Math.max(Math.abs(branch.getTerminal1().getP()), Math.abs(branch.getTerminal2().getP())) - )); - } - - private static double getReferenceP(Branch branch) { - return branch.getTerminal1().getP(); - } } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java index f880e048..02b87dad 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java @@ -11,6 +11,7 @@ import com.powsybl.iidm.network.Branch; import com.powsybl.iidm.network.Country; import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.TwoSides; import com.powsybl.loadflow.LoadFlow; import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.sensitivity.SensitivityAnalysis; @@ -136,8 +137,7 @@ private void decomposeFlowForState(Network network, Map netPositions, Map> glsks, LoadFlowRunningService.Result loadFlowServiceAcResult) { - saveAcReferenceFlow(flowDecompositionResultsBuilder, xnecList, loadFlowServiceAcResult); - saveAcMaxFlow(flowDecompositionResultsBuilder, xnecList, loadFlowServiceAcResult); + saveAcReferenceFlows(flowDecompositionResultsBuilder, xnecList, loadFlowServiceAcResult); compensateLosses(network); observers.computedAcFlows(network, loadFlowServiceAcResult); @@ -180,14 +180,11 @@ private LoadFlowRunningService.Result runAcLoadFlow(Network network) { return loadFlowRunningService.runAcLoadflow(network, loadFlowParameters, parameters.isDcFallbackEnabledAfterAcDivergence()); } - private void saveAcReferenceFlow(FlowDecompositionResults.PerStateBuilder flowDecompositionResultBuilder, Set xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) { - Map acReferenceFlows = FlowComputerUtils.calculateAcReferenceFlows(xnecList, loadFlowServiceAcResult); - flowDecompositionResultBuilder.saveAcReferenceFlow(acReferenceFlows); - } - - private void saveAcMaxFlow(FlowDecompositionResults.PerStateBuilder flowDecompositionResultBuilder, Set xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) { - Map acMaxFlow = FlowComputerUtils.calculateAcMaxFlows(xnecList, loadFlowServiceAcResult); - flowDecompositionResultBuilder.saveAcMaxFlow(acMaxFlow); + private void saveAcReferenceFlows(FlowDecompositionResults.PerStateBuilder flowDecompositionResultBuilder, Set xnecList, LoadFlowRunningService.Result loadFlowServiceAcResult) { + Map acTerminal1ReferenceFlows = FlowComputerUtils.calculateAcTerminalReferenceFlows(xnecList, loadFlowServiceAcResult, TwoSides.ONE); + Map acTerminal2ReferenceFlows = FlowComputerUtils.calculateAcTerminalReferenceFlows(xnecList, loadFlowServiceAcResult, TwoSides.TWO); + flowDecompositionResultBuilder.saveAcTerminal1ReferenceFlow(acTerminal1ReferenceFlows); + flowDecompositionResultBuilder.saveAcTerminal2ReferenceFlow(acTerminal2ReferenceFlows); } private Map getZonesNetPosition(Network network) { @@ -229,7 +226,7 @@ private SparseMatrixWithIndexesTriplet getNodalInjectionsMatrix(Network network, } private void saveDcReferenceFlow(FlowDecompositionResults.PerStateBuilder flowDecompositionResultBuilder, Set xnecList) { - flowDecompositionResultBuilder.saveDcReferenceFlow(FlowComputerUtils.getReferenceFlow(xnecList)); + flowDecompositionResultBuilder.saveDcReferenceFlow(FlowComputerUtils.getTerminalReferenceFlow(xnecList, TwoSides.ONE)); } private SensitivityAnalyser getSensitivityAnalyser(Network network, NetworkMatrixIndexes networkMatrixIndexes) { diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionObserverList.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionObserverList.java index 63ae1d56..4a56c9a3 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionObserverList.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionObserverList.java @@ -10,6 +10,7 @@ import com.powsybl.flow_decomposition.LoadFlowRunningService.Result; import com.powsybl.iidm.network.Country; import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.TwoSides; import java.util.ArrayList; import java.util.List; @@ -87,7 +88,7 @@ public void computedAcFlows(Network network, Result loadFlowServiceAcResult) { return; } - Map acFlows = FlowComputerUtils.calculateAcReferenceFlows(network.getBranchStream().toList(), loadFlowServiceAcResult); + Map acFlows = FlowComputerUtils.calculateAcTerminalReferenceFlows(network.getBranchStream().toList(), loadFlowServiceAcResult, TwoSides.ONE); for (FlowDecompositionObserver o : observers) { o.computedAcFlows(acFlows); @@ -99,7 +100,7 @@ public void computedDcFlows(Network network) { return; } - Map dcFlows = FlowComputerUtils.getReferenceFlow(network.getBranchStream().toList()); + Map dcFlows = FlowComputerUtils.getTerminalReferenceFlow(network.getBranchStream().toList(), TwoSides.ONE); for (FlowDecompositionObserver o : observers) { o.computedDcFlows(dcFlows); diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java index 33b039a4..e8c8d1dd 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java @@ -44,8 +44,8 @@ class PerStateBuilder { private final String contingencyId; private SparseMatrixWithIndexesCSC allocatedAndLoopFlowsMatrix; private Map> pstFlowMap; - private Map acReferenceFlow; - private Map acMaxFlow; + private Map acTerminal1ReferenceFlow; + private Map acTerminal2ReferenceFlow; private Map dcReferenceFlow; PerStateBuilder(String contingencyId, Set xnecList) { @@ -61,12 +61,12 @@ void savePstFlowMatrix(SparseMatrixWithIndexesCSC pstFlowMatrix) { this.pstFlowMap = pstFlowMatrix.toMap(); } - void saveAcReferenceFlow(Map acReferenceFlow) { - this.acReferenceFlow = acReferenceFlow; + void saveAcTerminal1ReferenceFlow(Map acTerminal1ReferenceFlow) { + this.acTerminal1ReferenceFlow = acTerminal1ReferenceFlow; } - void saveAcMaxFlow(Map acMaxFlow) { - this.acMaxFlow = acMaxFlow; + void saveAcTerminal2ReferenceFlow(Map acTerminal2ReferenceFlow) { + this.acTerminal2ReferenceFlow = acTerminal2ReferenceFlow; } void saveDcReferenceFlow(Map dcReferenceFlow) { @@ -96,8 +96,8 @@ private DecomposedFlow createDecomposedFlow(String branchId, Map .addContingencyId(contingencyId) .addCountry1(country1) .addCountry2(country2) - .addAcReferenceFlow(acReferenceFlow.get(branchId)) - .addAcMaxFlow(acMaxFlow.get(branchId)) + .addAcTerminal1ReferenceFlow(acTerminal1ReferenceFlow.get(branchId)) + .addAcTerminal2ReferenceFlow(acTerminal2ReferenceFlow.get(branchId)) .addDcReferenceFlow(dcReferenceFlow.get(branchId)) .addAllocatedFlow(allocatedFlow) .addXNodeFlow(xNodeFlow) diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java index fefc579b..4001a2d6 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java @@ -83,8 +83,8 @@ void testBuilderNState() { FlowDecompositionResults.PerStateBuilder nStateBuilder = flowDecompositionResults.getBuilder(nStateXnecList); DecomposedFlowRescaler decomposedFlowRescaler = new DecomposedFlowRescalerNoOp(); - nStateBuilder.saveAcReferenceFlow(Map.of(branchId, 10.0)); - nStateBuilder.saveAcMaxFlow(Map.of(branchId, 10.0)); + nStateBuilder.saveAcTerminal1ReferenceFlow(Map.of(branchId, 10.0)); + nStateBuilder.saveAcTerminal2ReferenceFlow(Map.of(branchId, 10.0)); nStateBuilder.saveDcReferenceFlow(Map.of(branchId, 11.0)); nStateBuilder.saveAllocatedAndLoopFlowsMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(ALLOCATED_COLUMN_NAME, 0, NetworkUtil.getLoopFlowIdFromCountry(FR), 1), alloMatrix)); nStateBuilder.savePstFlowMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(PST_COLUMN_NAME, 0), pstMatrix)); @@ -97,7 +97,7 @@ void testBuilderNState() { assertEquals(branchId, decomposedFlow.getBranchId()); assertEquals("", decomposedFlow.getContingencyId()); assertEquals(branchId, decomposedFlow.getId()); - assertEquals(10.0, decomposedFlow.getAcReferenceFlow()); + assertEquals(10.0, decomposedFlow.getAcTerminal1ReferenceFlow()); assertEquals(11.0, decomposedFlow.getDcReferenceFlow()); assertEquals(20.0, decomposedFlow.getAllocatedFlow()); assertEquals(12.0, decomposedFlow.getLoopFlow(FR)); @@ -111,8 +111,8 @@ void testBuilderN1State() { String xnecId = "DB000011 DF000011 1_DD000011 DF000011 1"; DecomposedFlowRescaler decomposedFlowRescaler = new DecomposedFlowRescalerNoOp(); - n1StateBuilder.saveAcReferenceFlow(Map.of(branchId, 10.0)); - n1StateBuilder.saveAcMaxFlow(Map.of(branchId, 10.0)); + n1StateBuilder.saveAcTerminal1ReferenceFlow(Map.of(branchId, 10.0)); + n1StateBuilder.saveAcTerminal2ReferenceFlow(Map.of(branchId, 10.0)); n1StateBuilder.saveDcReferenceFlow(Map.of(branchId, 11.0)); n1StateBuilder.saveAllocatedAndLoopFlowsMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(ALLOCATED_COLUMN_NAME, 0, NetworkUtil.getLoopFlowIdFromCountry(FR), 1), alloMatrix)); n1StateBuilder.savePstFlowMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(PST_COLUMN_NAME, 0), pstMatrix)); @@ -125,7 +125,7 @@ void testBuilderN1State() { assertEquals(branchId, decomposedFlow.getBranchId()); assertEquals(contingencyId2, decomposedFlow.getContingencyId()); assertEquals(xnecId, decomposedFlow.getId()); - assertEquals(10.0, decomposedFlow.getAcReferenceFlow()); + assertEquals(10.0, decomposedFlow.getAcTerminal1ReferenceFlow()); assertEquals(11.0, decomposedFlow.getDcReferenceFlow()); assertEquals(20.0, decomposedFlow.getAllocatedFlow()); assertEquals(12.0, decomposedFlow.getLoopFlow(FR)); @@ -139,8 +139,8 @@ void testBuilderN2State() { String xnecId = "DB000011 DF000011 1_FB000011 FD000011 1_FB000021 FD000021 1"; DecomposedFlowRescaler decomposedFlowRescaler = new DecomposedFlowRescalerNoOp(); - n2StateBuilder.saveAcReferenceFlow(Map.of(branchId, 10.0)); - n2StateBuilder.saveAcMaxFlow(Map.of(branchId, 10.0)); + n2StateBuilder.saveAcTerminal1ReferenceFlow(Map.of(branchId, 10.0)); + n2StateBuilder.saveAcTerminal2ReferenceFlow(Map.of(branchId, 10.0)); n2StateBuilder.saveDcReferenceFlow(Map.of(branchId, 11.0)); n2StateBuilder.saveAllocatedAndLoopFlowsMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(ALLOCATED_COLUMN_NAME, 0, NetworkUtil.getLoopFlowIdFromCountry(FR), 1), alloMatrix)); n2StateBuilder.savePstFlowMatrix(new SparseMatrixWithIndexesCSC(xnecMap, Map.of(PST_COLUMN_NAME, 0), pstMatrix)); @@ -153,7 +153,7 @@ void testBuilderN2State() { assertEquals(branchId, decomposedFlow.getBranchId()); assertEquals(contingencyId3, decomposedFlow.getContingencyId()); assertEquals(xnecId, decomposedFlow.getId()); - assertEquals(10.0, decomposedFlow.getAcReferenceFlow()); + assertEquals(10.0, decomposedFlow.getAcTerminal1ReferenceFlow()); assertEquals(11.0, decomposedFlow.getDcReferenceFlow()); assertEquals(20.0, decomposedFlow.getAllocatedFlow()); assertEquals(12.0, decomposedFlow.getLoopFlow(FR)); diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java index ed286070..75b0f204 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java @@ -95,8 +95,8 @@ private DecomposedFlow getDecomposedFlow(double internalFlow, double acReference .addContingencyId("") .addCountry1(country1) .addCountry2(country2) - .addAcReferenceFlow(acReferenceFlow) - .addAcMaxFlow(acReferenceFlow) + .addAcTerminal1ReferenceFlow(acReferenceFlow) + .addAcTerminal2ReferenceFlow(acReferenceFlow) .addDcReferenceFlow(dcReferenceFlow) .addAllocatedFlow(allocatedFlow) .addXNodeFlow(0) @@ -122,7 +122,7 @@ private void checkRescaleAcReference(double acReferenceFlow, double dcReferenceF assertEquals(expectedLoopFlowGE, rescaledFlow.getLoopFlow(Country.GE), EPSILON); assertEquals(expectedLoopFlowES, rescaledFlow.getLoopFlow(Country.ES), EPSILON); assertEquals(expectedInternalFlow, rescaledFlow.getInternalFlow(), EPSILON); - assertEquals(acReferenceFlow, rescaledFlow.getAcReferenceFlow(), EPSILON); + assertEquals(acReferenceFlow, rescaledFlow.getAcTerminal1ReferenceFlow(), EPSILON); assertEquals(dcReferenceFlow, rescaledFlow.getDcReferenceFlow(), EPSILON); } } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/LoopFlowTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/LoopFlowTests.java index a2b5728f..5e3ee61d 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/LoopFlowTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/LoopFlowTests.java @@ -55,10 +55,10 @@ void checkThatLoopFlowsAreExtractedForEachXnecAndForEachCountryGivenABasicNetwor assertEquals(100, decomposedFlowMap.get(x5).getLoopFlow(Country.ES), EPSILON); assertEquals(0, decomposedFlowMap.get(x5).getLoopFlow(Country.FR), EPSILON); - assertTrue(Double.isNaN(decomposedFlowMap.get(x1).getAcReferenceFlow())); - assertTrue(Double.isNaN(decomposedFlowMap.get(x2).getAcReferenceFlow())); - assertTrue(Double.isNaN(decomposedFlowMap.get(x4).getAcReferenceFlow())); - assertTrue(Double.isNaN(decomposedFlowMap.get(x5).getAcReferenceFlow())); + assertTrue(Double.isNaN(decomposedFlowMap.get(x1).getAcTerminal1ReferenceFlow())); + assertTrue(Double.isNaN(decomposedFlowMap.get(x2).getAcTerminal1ReferenceFlow())); + assertTrue(Double.isNaN(decomposedFlowMap.get(x4).getAcTerminal1ReferenceFlow())); + assertTrue(Double.isNaN(decomposedFlowMap.get(x5).getAcTerminal1ReferenceFlow())); assertEquals(100, decomposedFlowMap.get(x1).getDcReferenceFlow(), EPSILON); assertEquals(200, decomposedFlowMap.get(x2).getDcReferenceFlow(), EPSILON); diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java index 846559a1..3f38d7bc 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java @@ -38,7 +38,7 @@ private void checkRescaleAcReference(double acReferenceFlow, double dcReferenceF assertEquals(expectedLoopFlowGE, rescaledFlow.getLoopFlow(Country.GE), EPSILON); assertEquals(expectedLoopFlowES, rescaledFlow.getLoopFlow(Country.ES), EPSILON); assertEquals(expectedInternalFlow, rescaledFlow.getInternalFlow(), EPSILON); - assertEquals(acReferenceFlow, rescaledFlow.getAcReferenceFlow(), EPSILON); + assertEquals(acReferenceFlow, rescaledFlow.getAcTerminal1ReferenceFlow(), EPSILON); assertEquals(dcReferenceFlow, rescaledFlow.getDcReferenceFlow(), EPSILON); } @@ -65,8 +65,8 @@ private DecomposedFlow getDecomposedFlow(double acReferenceFlow, double dcRefere .addContingencyId("") .addCountry1(country1) .addCountry2(country2) - .addAcReferenceFlow(acReferenceFlow) - .addAcMaxFlow(acReferenceFlow) + .addAcTerminal1ReferenceFlow(acReferenceFlow) + .addAcTerminal2ReferenceFlow(acReferenceFlow) .addDcReferenceFlow(dcReferenceFlow) .addAllocatedFlow(allocatedFlow) .addXNodeFlow(0) @@ -197,7 +197,7 @@ void testRescalingDoesNotOccurWhenAcDiverge() { XnecProvider xnecProvider = XnecProviderByIds.builder().addNetworkElementsOnBasecase(Set.of(xnecId)).build(); FlowDecompositionResults flowDecompositionResults = flowDecompositionComputer.run(xnecProvider, network); - assertTrue(Double.isNaN(flowDecompositionResults.getDecomposedFlowMap().get(xnecId).getAcReferenceFlow())); + assertTrue(Double.isNaN(flowDecompositionResults.getDecomposedFlowMap().get(xnecId).getAcTerminal1ReferenceFlow())); assertFalse(Double.isNaN(flowDecompositionResults.getDecomposedFlowMap().get(xnecId).getAllocatedFlow())); } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java index 8f2a8b5b..d2f0eb6c 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java @@ -41,8 +41,8 @@ public static void assertCoherenceTotalFlow(FlowDecompositionParameters.RescaleM for (String xnec : flowDecompositionResults.getDecomposedFlowMap().keySet()) { DecomposedFlow decomposedFlow = flowDecompositionResults.getDecomposedFlowMap().get(xnec); switch (rescaleMode) { - case ACER_METHODOLOGY -> assertEquals(Math.abs(decomposedFlow.getAcReferenceFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); - case PROPORTIONAL -> assertEquals(Math.abs(decomposedFlow.getAcMaxFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); + case ACER_METHODOLOGY -> assertEquals(Math.abs(decomposedFlow.getAcTerminal1ReferenceFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); + case PROPORTIONAL -> assertEquals(decomposedFlow.getMaxAbsAcFlow(), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); default -> assertEquals(Math.abs(decomposedFlow.getDcReferenceFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); } } From c883982f198e8c66189c96eb722dd0d56465157b Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Fri, 24 May 2024 10:15:24 +0200 Subject: [PATCH 06/13] add test rescaling proportional does nothing if the flow is small Signed-off-by: Caio Luke --- .../DecomposedFlowRescalerProportional.java | 2 +- .../com/powsybl/flow_decomposition/RescalingTests.java | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java index d34b1f65..87de2e96 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java @@ -18,7 +18,7 @@ * @author Caio Luke {@literal } */ public class DecomposedFlowRescalerProportional implements DecomposedFlowRescaler { - private static final double MIN_FLOW_TOLERANCE = 1E-6; // min flow in MW to rescale + public static final double MIN_FLOW_TOLERANCE = 1E-6; // min flow in MW to rescale public DecomposedFlowRescalerProportional() { // empty constructor diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java index 3f38d7bc..5fc17b8f 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java @@ -201,4 +201,13 @@ void testRescalingDoesNotOccurWhenAcDiverge() { assertFalse(Double.isNaN(flowDecompositionResults.getDecomposedFlowMap().get(xnecId).getAllocatedFlow())); } + + @Test + void testRescalingProportionalDoesNotRescaleWithSmallFlow() { + double acReferenceFlow = 1.0; + double dcReferenceFlow = DecomposedFlowRescalerProportional.MIN_FLOW_TOLERANCE / 10; + DecomposedFlow decomposedFlow = getDecomposedFlow(acReferenceFlow, dcReferenceFlow); + DecomposedFlow decomposedFlowRescaled = new DecomposedFlowRescalerProportional().rescale(decomposedFlow); + assertEquals(decomposedFlow, decomposedFlowRescaled); + } } From e957ff7053c11f4afbf683bc053a50dea6aedbd4 Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Fri, 24 May 2024 10:39:56 +0200 Subject: [PATCH 07/13] add test no op rescaler Signed-off-by: Caio Luke --- .../flow_decomposition/RescalingTests.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java index 5fc17b8f..ef1bef40 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java @@ -16,9 +16,7 @@ import java.util.Set; import java.util.TreeMap; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; /** * @author Sebastien Murgey {@literal } @@ -202,12 +200,23 @@ void testRescalingDoesNotOccurWhenAcDiverge() { } + @Test + void testRescalingNoOpDoesNotRescale() { + double acReferenceFlow = 1.0; + double dcReferenceFlow = 0.9; + DecomposedFlow decomposedFlow = getDecomposedFlow(acReferenceFlow, dcReferenceFlow); + DecomposedFlow decomposedFlowRescaled = new DecomposedFlowRescalerNoOp().rescale(decomposedFlow); + // check that same object is returned by rescaler + assertSame(decomposedFlow, decomposedFlowRescaled); + } + @Test void testRescalingProportionalDoesNotRescaleWithSmallFlow() { double acReferenceFlow = 1.0; double dcReferenceFlow = DecomposedFlowRescalerProportional.MIN_FLOW_TOLERANCE / 10; DecomposedFlow decomposedFlow = getDecomposedFlow(acReferenceFlow, dcReferenceFlow); DecomposedFlow decomposedFlowRescaled = new DecomposedFlowRescalerProportional().rescale(decomposedFlow); - assertEquals(decomposedFlow, decomposedFlowRescaled); + // check that same object is returned by rescaler + assertSame(decomposedFlow, decomposedFlowRescaled); } } From e66a81fbe89fdf1061a831d633ae5cbd02df294b Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Fri, 24 May 2024 10:42:12 +0200 Subject: [PATCH 08/13] add test rescaler nan Signed-off-by: Caio Luke --- .../flow_decomposition/RescalingTests.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java index ef1bef40..95e146b8 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java @@ -210,6 +210,26 @@ void testRescalingNoOpDoesNotRescale() { assertSame(decomposedFlow, decomposedFlowRescaled); } + @Test + void testRescalingAcerMethodologyDoesNotRescaleNaN() { + double acReferenceFlow = Double.NaN; + double dcReferenceFlow = 0.9; + DecomposedFlow decomposedFlow = getDecomposedFlow(acReferenceFlow, dcReferenceFlow); + DecomposedFlow decomposedFlowRescaled = new DecomposedFlowRescalerAcerMethodology().rescale(decomposedFlow); + // check that same object is returned by rescaler + assertSame(decomposedFlow, decomposedFlowRescaled); + } + + @Test + void testRescalingProportionalDoesNotRescaleNaN() { + double acReferenceFlow = Double.NaN; + double dcReferenceFlow = 0.9; + DecomposedFlow decomposedFlow = getDecomposedFlow(acReferenceFlow, dcReferenceFlow); + DecomposedFlow decomposedFlowRescaled = new DecomposedFlowRescalerProportional().rescale(decomposedFlow); + // check that same object is returned by rescaler + assertSame(decomposedFlow, decomposedFlowRescaled); + } + @Test void testRescalingProportionalDoesNotRescaleWithSmallFlow() { double acReferenceFlow = 1.0; From de33a42acba34be0d029dc38a67eaa4425aac2c1 Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Fri, 24 May 2024 15:32:30 +0200 Subject: [PATCH 09/13] require non null, remove abs in assert, move rescaler to another package Signed-off-by: Caio Luke --- .../com/powsybl/flow_decomposition/DecomposedFlow.java | 10 +++++----- .../flow_decomposition/FlowDecompositionComputer.java | 4 ++++ .../flow_decomposition/FlowDecompositionResults.java | 1 + .../{ => rescaler}/DecomposedFlowRescaler.java | 4 +++- .../DecomposedFlowRescalerAcerMethodology.java | 4 +++- .../{ => rescaler}/DecomposedFlowRescalerNoOp.java | 4 +++- .../DecomposedFlowRescalerProportional.java | 4 +++- .../FlowDecompositionResultsTests.java | 5 +++++ .../powsybl/flow_decomposition/InternalFlowTests.java | 1 + .../com/powsybl/flow_decomposition/RescalingTests.java | 3 +++ .../java/com/powsybl/flow_decomposition/TestUtils.java | 6 +++--- 11 files changed, 34 insertions(+), 12 deletions(-) rename flow-decomposition/src/main/java/com/powsybl/flow_decomposition/{ => rescaler}/DecomposedFlowRescaler.java (85%) rename flow-decomposition/src/main/java/com/powsybl/flow_decomposition/{ => rescaler}/DecomposedFlowRescalerAcerMethodology.java (95%) rename flow-decomposition/src/main/java/com/powsybl/flow_decomposition/{ => rescaler}/DecomposedFlowRescalerNoOp.java (88%) rename flow-decomposition/src/main/java/com/powsybl/flow_decomposition/{ => rescaler}/DecomposedFlowRescalerProportional.java (95%) diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java index c920a149..edceba81 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlow.java @@ -37,10 +37,10 @@ public class DecomposedFlow { static final String INTERNAL_COLUMN_NAME = "Internal Flow"; protected DecomposedFlow(DecomposedFlowBuilder builder) { - this.branchId = builder.branchId; - this.contingencyId = builder.contingencyId; - this.country1 = builder.country1; - this.country2 = builder.country2; + this.branchId = Objects.requireNonNull(builder.branchId); + this.contingencyId = Objects.requireNonNull(builder.contingencyId); + this.country1 = Objects.requireNonNull(builder.country1); + this.country2 = Objects.requireNonNull(builder.country2); this.acTerminal1ReferenceFlow = builder.acTerminal1ReferenceFlow; this.acTerminal2ReferenceFlow = builder.acTerminal2ReferenceFlow; this.dcReferenceFlow = builder.dcReferenceFlow; @@ -48,7 +48,7 @@ protected DecomposedFlow(DecomposedFlowBuilder builder) { this.xNodeFlow = builder.xNodeFlow; this.pstFlow = builder.pstFlow; this.internalFlow = builder.internalFlow; - this.loopFlowsMap.putAll(builder.loopFlowsMap); + this.loopFlowsMap.putAll(Objects.requireNonNull(builder.loopFlowsMap)); } public String getBranchId() { diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java index 02b87dad..396b62b4 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java @@ -8,6 +8,10 @@ import com.powsybl.commons.PowsyblException; import com.powsybl.flow_decomposition.glsk_provider.AutoGlskProvider; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescaler; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescalerAcerMethodology; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescalerNoOp; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescalerProportional; import com.powsybl.iidm.network.Branch; import com.powsybl.iidm.network.Country; import com.powsybl.iidm.network.Network; diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java index e8c8d1dd..219d7399 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java @@ -6,6 +6,7 @@ */ package com.powsybl.flow_decomposition; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescaler; import com.powsybl.iidm.network.Branch; import com.powsybl.iidm.network.Country; import com.powsybl.iidm.network.Identifiable; diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescaler.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescaler.java similarity index 85% rename from flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescaler.java rename to flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescaler.java index 52e51cbb..0051eeca 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescaler.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescaler.java @@ -5,7 +5,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * SPDX-License-Identifier: MPL-2.0 */ -package com.powsybl.flow_decomposition; +package com.powsybl.flow_decomposition.rescaler; + +import com.powsybl.flow_decomposition.DecomposedFlow; /** * @author Sebastien Murgey {@literal } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerAcerMethodology.java similarity index 95% rename from flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java rename to flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerAcerMethodology.java index 618b9aa4..802ef634 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerAcerMethodology.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerAcerMethodology.java @@ -5,8 +5,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * SPDX-License-Identifier: MPL-2.0 */ -package com.powsybl.flow_decomposition; +package com.powsybl.flow_decomposition.rescaler; +import com.powsybl.flow_decomposition.DecomposedFlow; +import com.powsybl.flow_decomposition.DecomposedFlowBuilder; import com.powsybl.iidm.network.Country; import java.util.Map; diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerNoOp.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerNoOp.java similarity index 88% rename from flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerNoOp.java rename to flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerNoOp.java index 5ade5174..64e1bdca 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerNoOp.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerNoOp.java @@ -5,7 +5,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * SPDX-License-Identifier: MPL-2.0 */ -package com.powsybl.flow_decomposition; +package com.powsybl.flow_decomposition.rescaler; + +import com.powsybl.flow_decomposition.DecomposedFlow; /** * @author Sebastien Murgey {@literal } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerProportional.java similarity index 95% rename from flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java rename to flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerProportional.java index 87de2e96..5927e1fc 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowRescalerProportional.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerProportional.java @@ -5,8 +5,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * SPDX-License-Identifier: MPL-2.0 */ -package com.powsybl.flow_decomposition; +package com.powsybl.flow_decomposition.rescaler; +import com.powsybl.flow_decomposition.DecomposedFlow; +import com.powsybl.flow_decomposition.DecomposedFlowBuilder; import com.powsybl.iidm.network.Country; import java.util.Map; diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java index 4001a2d6..3a4226e3 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionResultsTests.java @@ -7,6 +7,8 @@ */ package com.powsybl.flow_decomposition; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescaler; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescalerNoOp; import com.powsybl.flow_decomposition.xnec_provider.XnecProviderByIds; import com.powsybl.iidm.network.Branch; import com.powsybl.iidm.network.Country; @@ -98,6 +100,7 @@ void testBuilderNState() { assertEquals("", decomposedFlow.getContingencyId()); assertEquals(branchId, decomposedFlow.getId()); assertEquals(10.0, decomposedFlow.getAcTerminal1ReferenceFlow()); + assertEquals(10.0, decomposedFlow.getAcTerminal2ReferenceFlow()); assertEquals(11.0, decomposedFlow.getDcReferenceFlow()); assertEquals(20.0, decomposedFlow.getAllocatedFlow()); assertEquals(12.0, decomposedFlow.getLoopFlow(FR)); @@ -126,6 +129,7 @@ void testBuilderN1State() { assertEquals(contingencyId2, decomposedFlow.getContingencyId()); assertEquals(xnecId, decomposedFlow.getId()); assertEquals(10.0, decomposedFlow.getAcTerminal1ReferenceFlow()); + assertEquals(10.0, decomposedFlow.getAcTerminal2ReferenceFlow()); assertEquals(11.0, decomposedFlow.getDcReferenceFlow()); assertEquals(20.0, decomposedFlow.getAllocatedFlow()); assertEquals(12.0, decomposedFlow.getLoopFlow(FR)); @@ -154,6 +158,7 @@ void testBuilderN2State() { assertEquals(contingencyId3, decomposedFlow.getContingencyId()); assertEquals(xnecId, decomposedFlow.getId()); assertEquals(10.0, decomposedFlow.getAcTerminal1ReferenceFlow()); + assertEquals(10.0, decomposedFlow.getAcTerminal2ReferenceFlow()); assertEquals(11.0, decomposedFlow.getDcReferenceFlow()); assertEquals(20.0, decomposedFlow.getAllocatedFlow()); assertEquals(12.0, decomposedFlow.getLoopFlow(FR)); diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java index 75b0f204..b0418693 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java @@ -6,6 +6,7 @@ */ package com.powsybl.flow_decomposition; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescalerAcerMethodology; import com.powsybl.flow_decomposition.xnec_provider.XnecProviderAllBranches; import com.powsybl.iidm.network.Country; import com.powsybl.iidm.network.Network; diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java index 95e146b8..9a2686f8 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java @@ -6,6 +6,9 @@ */ package com.powsybl.flow_decomposition; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescalerAcerMethodology; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescalerNoOp; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescalerProportional; import com.powsybl.flow_decomposition.xnec_provider.XnecProviderAllBranches; import com.powsybl.flow_decomposition.xnec_provider.XnecProviderByIds; import com.powsybl.iidm.network.Country; diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java index d2f0eb6c..d977eaef 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/TestUtils.java @@ -41,9 +41,9 @@ public static void assertCoherenceTotalFlow(FlowDecompositionParameters.RescaleM for (String xnec : flowDecompositionResults.getDecomposedFlowMap().keySet()) { DecomposedFlow decomposedFlow = flowDecompositionResults.getDecomposedFlowMap().get(xnec); switch (rescaleMode) { - case ACER_METHODOLOGY -> assertEquals(Math.abs(decomposedFlow.getAcTerminal1ReferenceFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); - case PROPORTIONAL -> assertEquals(decomposedFlow.getMaxAbsAcFlow(), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); - default -> assertEquals(Math.abs(decomposedFlow.getDcReferenceFlow()), Math.abs(decomposedFlow.getTotalFlow()), EPSILON); + case ACER_METHODOLOGY -> assertEquals(Math.abs(decomposedFlow.getAcTerminal1ReferenceFlow()), decomposedFlow.getTotalFlow(), EPSILON); + case PROPORTIONAL -> assertEquals(decomposedFlow.getMaxAbsAcFlow(), decomposedFlow.getTotalFlow(), EPSILON); + default -> assertEquals(Math.abs(decomposedFlow.getDcReferenceFlow()), decomposedFlow.getTotalFlow(), EPSILON); } } } From f8a167a40a7890024d65487b51ff8c8f4c9a9798 Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Fri, 24 May 2024 15:51:54 +0200 Subject: [PATCH 10/13] parameterize min flow to rescale Signed-off-by: Caio Luke --- .../rescaler/DecomposedFlowRescalerProportional.java | 11 ++++++++--- .../powsybl/flow_decomposition/RescalingTests.java | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerProportional.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerProportional.java index 5927e1fc..79ef8e1b 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerProportional.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerProportional.java @@ -20,10 +20,15 @@ * @author Caio Luke {@literal } */ public class DecomposedFlowRescalerProportional implements DecomposedFlowRescaler { - public static final double MIN_FLOW_TOLERANCE = 1E-6; // min flow in MW to rescale + private final double minFlowTolerance; // min flow in MW to rescale + public static final double DEFAULT_MIN_FLOW_TOLERANCE = 1E-6; // default min tolerance is 1 W = 1E-6 MW + + public DecomposedFlowRescalerProportional(double minFlowTolerance) { + this.minFlowTolerance = minFlowTolerance; + } public DecomposedFlowRescalerProportional() { - // empty constructor + this(DEFAULT_MIN_FLOW_TOLERANCE); } @Override @@ -36,7 +41,7 @@ public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { // if dcReferenceFlow is too small, do not rescale double dcReferenceFlow = decomposedFlow.getDcReferenceFlow(); - if (Math.abs(dcReferenceFlow) < MIN_FLOW_TOLERANCE) { + if (Math.abs(dcReferenceFlow) < minFlowTolerance) { return decomposedFlow; } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java index 9a2686f8..8c5a7f0e 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java @@ -236,7 +236,7 @@ void testRescalingProportionalDoesNotRescaleNaN() { @Test void testRescalingProportionalDoesNotRescaleWithSmallFlow() { double acReferenceFlow = 1.0; - double dcReferenceFlow = DecomposedFlowRescalerProportional.MIN_FLOW_TOLERANCE / 10; + double dcReferenceFlow = DecomposedFlowRescalerProportional.DEFAULT_MIN_FLOW_TOLERANCE / 10; DecomposedFlow decomposedFlow = getDecomposedFlow(acReferenceFlow, dcReferenceFlow); DecomposedFlow decomposedFlowRescaled = new DecomposedFlowRescalerProportional().rescale(decomposedFlow); // check that same object is returned by rescaler From b450a0a67eb16e259523b2f27fa24b6f1d1e783e Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Mon, 27 May 2024 12:01:08 +0200 Subject: [PATCH 11/13] add proportional recaler min flow tolerance in FlowDecompositionParameters, add tests Signed-off-by: Caio Luke --- .../FlowDecompositionComputer.java | 2 +- .../FlowDecompositionParameters.java | 12 ++++++++++++ .../FlowDecompositionParametersTests.java | 5 +++++ .../powsybl/flow_decomposition/RescalingTests.java | 4 ++-- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java index 396b62b4..64456da0 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java @@ -211,7 +211,7 @@ private DecomposedFlowRescaler getDecomposedFlowRescaler() { return new DecomposedFlowRescalerAcerMethodology(); } case PROPORTIONAL -> { - return new DecomposedFlowRescalerProportional(); + return new DecomposedFlowRescalerProportional(parameters.getProportionalRescalerMinFlowTolerance()); } default -> throw new PowsyblException("DecomposedFlowRescaler not defined for mode: " + parameters.getRescaleMode()); } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionParameters.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionParameters.java index b06904ce..8386ec57 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionParameters.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionParameters.java @@ -7,6 +7,7 @@ package com.powsybl.flow_decomposition; import com.powsybl.commons.config.PlatformConfig; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescalerProportional; import java.util.Objects; @@ -38,6 +39,7 @@ public enum RescaleMode { private double lossesCompensationEpsilon; private double sensitivityEpsilon; private RescaleMode rescaleMode; + private double proportionalRescalerMinFlowTolerance; private boolean dcFallbackEnabledAfterAcDivergence; private int sensitivityVariableBatchSize; @@ -59,6 +61,7 @@ private static void load(FlowDecompositionParameters parameters, PlatformConfig parameters.setLossesCompensationEpsilon(moduleConfig.getDoubleProperty("losses-compensation-epsilon", DEFAULT_LOSSES_COMPENSATION_EPSILON)); parameters.setSensitivityEpsilon(moduleConfig.getDoubleProperty("sensitivity-epsilon", DEFAULT_SENSITIVITY_EPSILON)); parameters.setRescaleMode(moduleConfig.getEnumProperty("rescale-mode", RescaleMode.class, DEFAULT_RESCALE_MODE)); + parameters.setProportionalRescalerMinFlowTolerance(moduleConfig.getDoubleProperty("proportional-rescaler-min-flow-tolerance", DecomposedFlowRescalerProportional.DEFAULT_MIN_FLOW_TOLERANCE)); parameters.setDcFallbackEnabledAfterAcDivergence(moduleConfig.getBooleanProperty("dc-fallback-enabled-after-ac-divergence", DEFAULT_DC_FALLBACK_ENABLED_AFTER_AC_DIVERGENCE)); parameters.setSensitivityVariableBatchSize(moduleConfig.getIntProperty("sensitivity-variable-batch-size", DEFAULT_SENSITIVITY_VARIABLE_BATCH_SIZE)); }); @@ -69,6 +72,7 @@ public FlowDecompositionParameters() { this.lossesCompensationEpsilon = DEFAULT_LOSSES_COMPENSATION_EPSILON; this.sensitivityEpsilon = DEFAULT_SENSITIVITY_EPSILON; this.rescaleMode = DEFAULT_RESCALE_MODE; + this.proportionalRescalerMinFlowTolerance = DecomposedFlowRescalerProportional.DEFAULT_MIN_FLOW_TOLERANCE; this.dcFallbackEnabledAfterAcDivergence = DEFAULT_DC_FALLBACK_ENABLED_AFTER_AC_DIVERGENCE; this.sensitivityVariableBatchSize = DEFAULT_SENSITIVITY_VARIABLE_BATCH_SIZE; } @@ -109,6 +113,14 @@ public FlowDecompositionParameters setRescaleMode(RescaleMode rescaleMode) { return this; } + public void setProportionalRescalerMinFlowTolerance(double proportionalRescalerMinFlowTolerance) { + this.proportionalRescalerMinFlowTolerance = proportionalRescalerMinFlowTolerance; + } + + public double getProportionalRescalerMinFlowTolerance() { + return proportionalRescalerMinFlowTolerance; + } + public boolean isDcFallbackEnabledAfterAcDivergence() { return this.dcFallbackEnabledAfterAcDivergence; } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionParametersTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionParametersTests.java index 3095dc88..c166d390 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionParametersTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/FlowDecompositionParametersTests.java @@ -10,6 +10,7 @@ import com.google.common.jimfs.Jimfs; import com.powsybl.commons.config.InMemoryPlatformConfig; import com.powsybl.commons.config.MapModuleConfig; +import com.powsybl.flow_decomposition.rescaler.DecomposedFlowRescalerProportional; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -51,6 +52,7 @@ void checkDefaultParameters() { assertEquals(1e-5, parameters.getLossesCompensationEpsilon(), EPSILON); assertEquals(1e-5, parameters.getSensitivityEpsilon(), EPSILON); assertEquals(FlowDecompositionParameters.RescaleMode.NONE, parameters.getRescaleMode()); + assertEquals(DecomposedFlowRescalerProportional.DEFAULT_MIN_FLOW_TOLERANCE, parameters.getProportionalRescalerMinFlowTolerance(), EPSILON / 100); assertTrue(parameters.isDcFallbackEnabledAfterAcDivergence()); assertEquals(15000, parameters.getSensitivityVariableBatchSize()); } @@ -62,6 +64,7 @@ void checkCompleteConfigurationOfParameters() { mapModuleConfig.setStringProperty("losses-compensation-epsilon", Double.toString(2e-5)); mapModuleConfig.setStringProperty("sensitivity-epsilon", Double.toString(3e-3)); mapModuleConfig.setStringProperty("rescale-mode", FlowDecompositionParameters.RescaleMode.ACER_METHODOLOGY.name()); + mapModuleConfig.setStringProperty("proportional-rescaler-min-flow-tolerance", Double.toString(1e-2)); mapModuleConfig.setStringProperty("dc-fallback-enabled-after-ac-divergence", Boolean.toString(false)); mapModuleConfig.setStringProperty("sensitivity-variable-batch-size", Integer.toString(1234)); @@ -70,6 +73,7 @@ void checkCompleteConfigurationOfParameters() { assertEquals(2e-5, parameters.getLossesCompensationEpsilon(), EPSILON); assertEquals(3e-3, parameters.getSensitivityEpsilon(), EPSILON); assertEquals(FlowDecompositionParameters.RescaleMode.ACER_METHODOLOGY, parameters.getRescaleMode()); + assertEquals(1e-2, parameters.getProportionalRescalerMinFlowTolerance(), EPSILON); assertFalse(parameters.isDcFallbackEnabledAfterAcDivergence()); assertEquals(1234, parameters.getSensitivityVariableBatchSize()); } @@ -84,6 +88,7 @@ void checkIncompleteConfigurationOfParameters() { assertEquals(2e-5, parameters.getLossesCompensationEpsilon(), EPSILON); assertEquals(1e-5, parameters.getSensitivityEpsilon(), EPSILON); assertEquals(FlowDecompositionParameters.RescaleMode.NONE, parameters.getRescaleMode()); + assertEquals(DecomposedFlowRescalerProportional.DEFAULT_MIN_FLOW_TOLERANCE, parameters.getProportionalRescalerMinFlowTolerance(), EPSILON / 100); assertTrue(parameters.isDcFallbackEnabledAfterAcDivergence()); } } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java index 8c5a7f0e..fbe85d0d 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java @@ -236,9 +236,9 @@ void testRescalingProportionalDoesNotRescaleNaN() { @Test void testRescalingProportionalDoesNotRescaleWithSmallFlow() { double acReferenceFlow = 1.0; - double dcReferenceFlow = DecomposedFlowRescalerProportional.DEFAULT_MIN_FLOW_TOLERANCE / 10; + double dcReferenceFlow = 0.001; DecomposedFlow decomposedFlow = getDecomposedFlow(acReferenceFlow, dcReferenceFlow); - DecomposedFlow decomposedFlowRescaled = new DecomposedFlowRescalerProportional().rescale(decomposedFlow); + DecomposedFlow decomposedFlowRescaled = new DecomposedFlowRescalerProportional(0.5).rescale(decomposedFlow); // check that same object is returned by rescaler assertSame(decomposedFlow, decomposedFlowRescaled); } From 4d9e2b82d32ce36d3b8f12a90c243bc46981505a Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Tue, 28 May 2024 10:34:16 +0200 Subject: [PATCH 12/13] update docs Signed-off-by: Caio Luke --- .../flow_decomposition/algorithm-description.md | 12 +++++++++++- docs/flow_decomposition/configuration.md | 17 +++++++++-------- .../flow-decomposition-outputs.md | 4 +++- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/docs/flow_decomposition/algorithm-description.md b/docs/flow_decomposition/algorithm-description.md index cd827706..f1d392db 100644 --- a/docs/flow_decomposition/algorithm-description.md +++ b/docs/flow_decomposition/algorithm-description.md @@ -99,5 +99,15 @@ calculated by the DC power flow. However, the flow reference is the one calculated using AC power flow which is different. The final step of the algorithm is though to rescale the different flow parts in order to ensure that the sum of the parts is equal to the initially calculated AC flow. +By default, no rescaling to the AC flow is done on the flow decomposition results. + +Available rescaling modes are defined here below. + +#### ACER methodology-based rescaling The difference between reference AC flow and the sum of the parts of the decomposition is redispatched on the different -parts proportionally to their rectified linear unit ($\mathrm{ReLU}(x) = \mathrm{max}(x, 0)$). \ No newline at end of file +parts proportionally to their rectified linear unit ($\mathrm{ReLU}(x) = \mathrm{max}(x, 0)$). + +#### Proportional rescaling +Each flow is rescaled with a proportional coefficient. The coefficient is defined by $$\alpha_{\text{rescale}} = \frac{max(|AC p1|, |AC p2|)}{|DC p1|}$$. +In this way, the DC flow will have the same magnitude as the AC flow. +Since we divide by the DC flow to calculate the coefficient, lines with a too small DC flow are not rescaled. \ No newline at end of file diff --git a/docs/flow_decomposition/configuration.md b/docs/flow_decomposition/configuration.md index c8332ba9..9682852a 100644 --- a/docs/flow_decomposition/configuration.md +++ b/docs/flow_decomposition/configuration.md @@ -2,14 +2,15 @@ ## Dedicated parameters -| Name | Type | Default value | Description | -|-----------------------------------------|---------|---------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| enable-losses-compensation | boolean | false | When set to true, adds losses compensation step of the algorithm. Otherwise, all losses will be compensated using chosen power flow compensation strategy. | -| losses-compensation-epsilon | double | 1e-5 | Threshold used in losses compensation step of the algorihm. If actual losses are below the given threshold on a branch, no injection is created in the network to compensate these losses. Used to avoid creating too many injections in the network. May have an impact in overall algorithm performance and memory usage. | -| sensitivity-epsilon | double | 1e-5 | Threshold used when filling PTDF and PSDF matrices. If a sensitivity is below the given threshold, it is set to zero. Used to keep sparse matrices in the algorithm. May have an impact in overall algorithm performance and memory usage. | -| rescale-enabled | boolean | false | When set to true, rescaling step is done to ensure that the sum of all flow parts is equal to the AC reference flow. | -| dc-fallback-enabled-after-ac-divergence | boolean | true | Defines the fallback behavior after an AC divergence Use True to run DC loadflow if an AC loadflow diverges (default). Use False to throw an exception if an AC loadflow diverges. | -| sensitivity-variable-batch-size | int | 15000 | When set to a lower value, this parameter will reduce memory usage, but it might increase computation time | +| Name | Type | Default value | Description | +|-------------------------------------------|---------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| enable-losses-compensation | boolean | false | When set to true, adds losses compensation step of the algorithm. Otherwise, all losses will be compensated using chosen power flow compensation strategy. | +| losses-compensation-epsilon | double | 1e-5 | Threshold used in losses compensation step of the algorihm. If actual losses are below the given threshold on a branch, no injection is created in the network to compensate these losses. Used to avoid creating too many injections in the network. May have an impact in overall algorithm performance and memory usage. | +| sensitivity-epsilon | double | 1e-5 | Threshold used when filling PTDF and PSDF matrices. If a sensitivity is below the given threshold, it is set to zero. Used to keep sparse matrices in the algorithm. May have an impact in overall algorithm performance and memory usage. | +| rescale-mode | enum | NONE | Use NONE if you don't want to rescale flow decomposition results. Use ACER_METHODOLOGY for the ACER methodology rescaling strategy. Use PROPORTIONAL for a proportional rescaling. See [Flow parts rescaling](../flow_decomposition/algorithm-description.md#flow-parts-rescaling) for more details. | +| proportional-rescaler-min-flow-tolerance | double | 1e-6 | Option only used if rescale-mode is PROPORTIONAL. Defines the minimum DC flow required in MW for the rescaling to happen. | +| dc-fallback-enabled-after-ac-divergence | boolean | true | Defines the fallback behavior after an AC divergence Use True to run DC loadflow if an AC loadflow diverges (default). Use False to throw an exception if an AC loadflow diverges. | +| sensitivity-variable-batch-size | int | 15000 | When set to a lower value, this parameter will reduce memory usage, but it might increase computation time | ## Impact of existing parameters diff --git a/docs/flow_decomposition/flow-decomposition-outputs.md b/docs/flow_decomposition/flow-decomposition-outputs.md index b2de9ae4..a61c222a 100644 --- a/docs/flow_decomposition/flow-decomposition-outputs.md +++ b/docs/flow_decomposition/flow-decomposition-outputs.md @@ -4,7 +4,8 @@ For each network element of interest, flow decomposition outputs contain the following elements: - Reference flow : active power flow that is considered as the reference for the decomposition. It is actually equal - to the sum of all the flow parts calculated by the algorithm. + to the sum of all the flow parts calculated by the algorithm. to the sum of all the flow parts calculated by the algorithm. + Reference AC flows are available on terminal 1 and 2. - Allocated flow : allocated flow part of the network element's flow. - Internal flow : internal flow part of the network element's flow. It is calculated as the loop flow from the country which network element is part of (interconnections are considered as part of no specific country, so will always have an internal flow to 0). @@ -16,6 +17,7 @@ For each network element of interest, flow decomposition outputs contain the fol On one hand, the reference flows are oriented from side 1 to side 2 of the associated IIDM branch. A positive reference flow implies a flow from side 1 to side 2, while a negative one means a flow from side 2 to side 1. +For coherence and simplicity purposes, the entire algorithm (except [proportional rescaling](../flow_decomposition/algorithm-description.md#proportional-rescaling)) is based on the side 1. On the other hand, all flow parts (allocated flow, internal flow, loop flows and PST flow) are oriented in the branch flow convention. A positive flow part tends to increase the absolute flow on the branch (i.e. a burdening flow), while a From a26d6039e19adbda784cfd9dc92aca2d61155d1a Mon Sep 17 00:00:00 2001 From: Caio Luke Date: Thu, 30 May 2024 17:13:57 +0200 Subject: [PATCH 13/13] rename DecomposedFlowBuilder methods, adjust javadoc, return switch instead of switch return Signed-off-by: Caio Luke --- .../DecomposedFlowBuilder.java | 24 ++++++++-------- .../FlowDecompositionComputer.java | 16 ++++------- .../FlowDecompositionResults.java | 24 ++++++++-------- ...DecomposedFlowRescalerAcerMethodology.java | 28 +++++++++---------- .../DecomposedFlowRescalerProportional.java | 26 ++++++++--------- .../flow_decomposition/InternalFlowTests.java | 24 ++++++++-------- .../flow_decomposition/RescalingTests.java | 24 ++++++++-------- 7 files changed, 79 insertions(+), 87 deletions(-) diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowBuilder.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowBuilder.java index 3fc6396c..409ba388 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowBuilder.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/DecomposedFlowBuilder.java @@ -33,62 +33,62 @@ public DecomposedFlowBuilder() { // empty constructor } - public DecomposedFlowBuilder addBranchId(String branchId) { + public DecomposedFlowBuilder withBranchId(String branchId) { this.branchId = branchId; return this; } - public DecomposedFlowBuilder addContingencyId(String contingencyId) { + public DecomposedFlowBuilder withContingencyId(String contingencyId) { this.contingencyId = contingencyId; return this; } - public DecomposedFlowBuilder addCountry1(Country country1) { + public DecomposedFlowBuilder withCountry1(Country country1) { this.country1 = country1; return this; } - public DecomposedFlowBuilder addCountry2(Country country2) { + public DecomposedFlowBuilder withCountry2(Country country2) { this.country2 = country2; return this; } - public DecomposedFlowBuilder addAcTerminal1ReferenceFlow(double acTerminal1ReferenceFlow) { + public DecomposedFlowBuilder withAcTerminal1ReferenceFlow(double acTerminal1ReferenceFlow) { this.acTerminal1ReferenceFlow = acTerminal1ReferenceFlow; return this; } - public DecomposedFlowBuilder addAcTerminal2ReferenceFlow(double acTerminal2ReferenceFlow) { + public DecomposedFlowBuilder withAcTerminal2ReferenceFlow(double acTerminal2ReferenceFlow) { this.acTerminal2ReferenceFlow = acTerminal2ReferenceFlow; return this; } - public DecomposedFlowBuilder addDcReferenceFlow(double dcReferenceFlow) { + public DecomposedFlowBuilder withDcReferenceFlow(double dcReferenceFlow) { this.dcReferenceFlow = dcReferenceFlow; return this; } - public DecomposedFlowBuilder addAllocatedFlow(double allocatedFlow) { + public DecomposedFlowBuilder withAllocatedFlow(double allocatedFlow) { this.allocatedFlow = allocatedFlow; return this; } - public DecomposedFlowBuilder addXNodeFlow(double xNodeFlow) { + public DecomposedFlowBuilder withXNodeFlow(double xNodeFlow) { this.xNodeFlow = xNodeFlow; return this; } - public DecomposedFlowBuilder addPstFlow(double pstFlow) { + public DecomposedFlowBuilder withPstFlow(double pstFlow) { this.pstFlow = pstFlow; return this; } - public DecomposedFlowBuilder addInternalFlow(double internalFlow) { + public DecomposedFlowBuilder withInternalFlow(double internalFlow) { this.internalFlow = internalFlow; return this; } - public DecomposedFlowBuilder addLoopFlowsMap(Map loopFlowsMap) { + public DecomposedFlowBuilder withLoopFlowsMap(Map loopFlowsMap) { this.loopFlowsMap = loopFlowsMap; return this; } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java index 64456da0..0dd0c290 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionComputer.java @@ -203,18 +203,12 @@ private void compensateLosses(Network network) { } private DecomposedFlowRescaler getDecomposedFlowRescaler() { - switch (parameters.getRescaleMode()) { - case NONE -> { - return new DecomposedFlowRescalerNoOp(); - } - case ACER_METHODOLOGY -> { - return new DecomposedFlowRescalerAcerMethodology(); - } - case PROPORTIONAL -> { - return new DecomposedFlowRescalerProportional(parameters.getProportionalRescalerMinFlowTolerance()); - } + return switch (parameters.getRescaleMode()) { + case NONE -> new DecomposedFlowRescalerNoOp(); + case ACER_METHODOLOGY -> new DecomposedFlowRescalerAcerMethodology(); + case PROPORTIONAL -> new DecomposedFlowRescalerProportional(parameters.getProportionalRescalerMinFlowTolerance()); default -> throw new PowsyblException("DecomposedFlowRescaler not defined for mode: " + parameters.getRescaleMode()); - } + }; } private LoadFlowRunningService.Result runDcLoadFlow(Network network) { diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java index 219d7399..f6329f9b 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/FlowDecompositionResults.java @@ -93,18 +93,18 @@ private DecomposedFlow createDecomposedFlow(String branchId, Map Country country2 = NetworkUtil.getTerminalCountry(xnecMap.get(branchId).getTerminal2()); double internalFlow = extractInternalFlow(loopFlowsMap, country1, country2); DecomposedFlow decomposedFlow = new DecomposedFlowBuilder() - .addBranchId(branchId) - .addContingencyId(contingencyId) - .addCountry1(country1) - .addCountry2(country2) - .addAcTerminal1ReferenceFlow(acTerminal1ReferenceFlow.get(branchId)) - .addAcTerminal2ReferenceFlow(acTerminal2ReferenceFlow.get(branchId)) - .addDcReferenceFlow(dcReferenceFlow.get(branchId)) - .addAllocatedFlow(allocatedFlow) - .addXNodeFlow(xNodeFlow) - .addPstFlow(pstFlow) - .addInternalFlow(internalFlow) - .addLoopFlowsMap(loopFlowsMap) + .withBranchId(branchId) + .withContingencyId(contingencyId) + .withCountry1(country1) + .withCountry2(country2) + .withAcTerminal1ReferenceFlow(acTerminal1ReferenceFlow.get(branchId)) + .withAcTerminal2ReferenceFlow(acTerminal2ReferenceFlow.get(branchId)) + .withDcReferenceFlow(dcReferenceFlow.get(branchId)) + .withAllocatedFlow(allocatedFlow) + .withXNodeFlow(xNodeFlow) + .withPstFlow(pstFlow) + .withInternalFlow(internalFlow) + .withLoopFlowsMap(loopFlowsMap) .build(); return decomposedFlowRescaler.rescale(decomposedFlow); } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerAcerMethodology.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerAcerMethodology.java index 802ef634..fc72f893 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerAcerMethodology.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerAcerMethodology.java @@ -36,7 +36,8 @@ private static double rescaleValue(double initialValue, double delta, double sum @Override public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { double acTerminal1ReferenceFlow = decomposedFlow.getAcTerminal1ReferenceFlow(); - if (Double.isNaN(acTerminal1ReferenceFlow)) { + double acTerminal2ReferenceFlow = decomposedFlow.getAcTerminal2ReferenceFlow(); + if (Double.isNaN(acTerminal1ReferenceFlow) || Double.isNaN(acTerminal2ReferenceFlow)) { return decomposedFlow; } @@ -44,7 +45,6 @@ public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { String contingencyId = decomposedFlow.getContingencyId(); Country country1 = decomposedFlow.getCountry1(); Country country2 = decomposedFlow.getCountry2(); - double acTerminal2ReferenceFlow = decomposedFlow.getAcTerminal2ReferenceFlow(); double dcReferenceFlow = decomposedFlow.getDcReferenceFlow(); double allocatedFlow = decomposedFlow.getAllocatedFlow(); double xNodeFlow = decomposedFlow.getXNodeFlow(); @@ -63,18 +63,18 @@ public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { .collect(Collectors.toMap(Map.Entry::getKey, entry -> rescaleValue(entry.getValue(), deltaToRescale, sumOfReLUFlows))); return new DecomposedFlowBuilder() - .addBranchId(branchId) - .addContingencyId(contingencyId) - .addCountry1(country1) - .addCountry2(country2) - .addAcTerminal1ReferenceFlow(acTerminal1ReferenceFlow) - .addAcTerminal2ReferenceFlow(acTerminal2ReferenceFlow) - .addDcReferenceFlow(dcReferenceFlow) - .addAllocatedFlow(rescaledAllocatedFlow) - .addXNodeFlow(rescaledXNodeFlow) - .addPstFlow(rescaledPstFlow) - .addInternalFlow(rescaleInternalFlow) - .addLoopFlowsMap(rescaledLoopFlows) + .withBranchId(branchId) + .withContingencyId(contingencyId) + .withCountry1(country1) + .withCountry2(country2) + .withAcTerminal1ReferenceFlow(acTerminal1ReferenceFlow) + .withAcTerminal2ReferenceFlow(acTerminal2ReferenceFlow) + .withDcReferenceFlow(dcReferenceFlow) + .withAllocatedFlow(rescaledAllocatedFlow) + .withXNodeFlow(rescaledXNodeFlow) + .withPstFlow(rescaledPstFlow) + .withInternalFlow(rescaleInternalFlow) + .withLoopFlowsMap(rescaledLoopFlows) .build(); } } diff --git a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerProportional.java b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerProportional.java index 79ef8e1b..5aaac833 100644 --- a/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerProportional.java +++ b/flow-decomposition/src/main/java/com/powsybl/flow_decomposition/rescaler/DecomposedFlowRescalerProportional.java @@ -15,8 +15,6 @@ import java.util.stream.Collectors; /** - * @author Sebastien Murgey {@literal } - * @author Hugo Schindler {@literal } * @author Caio Luke {@literal } */ public class DecomposedFlowRescalerProportional implements DecomposedFlowRescaler { @@ -67,18 +65,18 @@ public DecomposedFlow rescale(DecomposedFlow decomposedFlow) { .collect(Collectors.toMap(Map.Entry::getKey, entry -> rescaleFactor * entry.getValue())); return new DecomposedFlowBuilder() - .addBranchId(branchId) - .addContingencyId(contingencyId) - .addCountry1(country1) - .addCountry2(country2) - .addAcTerminal1ReferenceFlow(acTerminal1ReferenceFlow) - .addAcTerminal2ReferenceFlow(acTerminal2ReferenceFlow) - .addDcReferenceFlow(dcReferenceFlow) - .addAllocatedFlow(rescaledAllocatedFlow) - .addXNodeFlow(rescaledXNodeFlow) - .addPstFlow(rescaledPstFlow) - .addInternalFlow(rescaleInternalFlow) - .addLoopFlowsMap(rescaledLoopFlows) + .withBranchId(branchId) + .withContingencyId(contingencyId) + .withCountry1(country1) + .withCountry2(country2) + .withAcTerminal1ReferenceFlow(acTerminal1ReferenceFlow) + .withAcTerminal2ReferenceFlow(acTerminal2ReferenceFlow) + .withDcReferenceFlow(dcReferenceFlow) + .withAllocatedFlow(rescaledAllocatedFlow) + .withXNodeFlow(rescaledXNodeFlow) + .withPstFlow(rescaledPstFlow) + .withInternalFlow(rescaleInternalFlow) + .withLoopFlowsMap(rescaledLoopFlows) .build(); } } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java index b0418693..0ecf0ceb 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/InternalFlowTests.java @@ -92,18 +92,18 @@ private DecomposedFlow getDecomposedFlow(double internalFlow, double acReference Country country1 = Country.FR; Country country2 = Country.FR; return new DecomposedFlowBuilder() - .addBranchId("") - .addContingencyId("") - .addCountry1(country1) - .addCountry2(country2) - .addAcTerminal1ReferenceFlow(acReferenceFlow) - .addAcTerminal2ReferenceFlow(acReferenceFlow) - .addDcReferenceFlow(dcReferenceFlow) - .addAllocatedFlow(allocatedFlow) - .addXNodeFlow(0) - .addPstFlow(pstFlow) - .addInternalFlow(internalFlow) - .addLoopFlowsMap(loopFlows) + .withBranchId("") + .withContingencyId("") + .withCountry1(country1) + .withCountry2(country2) + .withAcTerminal1ReferenceFlow(acReferenceFlow) + .withAcTerminal2ReferenceFlow(acReferenceFlow) + .withDcReferenceFlow(dcReferenceFlow) + .withAllocatedFlow(allocatedFlow) + .withXNodeFlow(0) + .withPstFlow(pstFlow) + .withInternalFlow(internalFlow) + .withLoopFlowsMap(loopFlows) .build(); } diff --git a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java index fbe85d0d..f70899d6 100644 --- a/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java +++ b/flow-decomposition/src/test/java/com/powsybl/flow_decomposition/RescalingTests.java @@ -62,18 +62,18 @@ private DecomposedFlow getDecomposedFlow(double acReferenceFlow, double dcRefere Country country1 = Country.FR; Country country2 = Country.FR; return new DecomposedFlowBuilder() - .addBranchId("") - .addContingencyId("") - .addCountry1(country1) - .addCountry2(country2) - .addAcTerminal1ReferenceFlow(acReferenceFlow) - .addAcTerminal2ReferenceFlow(acReferenceFlow) - .addDcReferenceFlow(dcReferenceFlow) - .addAllocatedFlow(allocatedFlow) - .addXNodeFlow(0) - .addPstFlow(pstFlow) - .addInternalFlow(internalFlow) - .addLoopFlowsMap(loopFlows) + .withBranchId("") + .withContingencyId("") + .withCountry1(country1) + .withCountry2(country2) + .withAcTerminal1ReferenceFlow(acReferenceFlow) + .withAcTerminal2ReferenceFlow(acReferenceFlow) + .withDcReferenceFlow(dcReferenceFlow) + .withAllocatedFlow(allocatedFlow) + .withXNodeFlow(0) + .withPstFlow(pstFlow) + .withInternalFlow(internalFlow) + .withLoopFlowsMap(loopFlows) .build(); }