Skip to content

Commit

Permalink
Allows providing a custom GLSK provider to compute nodal injections f…
Browse files Browse the repository at this point in the history
…or allocated flows (#85)

* Allows providing a custom GLSK provider to compute nodal injections for allocated flows

Signed-off-by: Sébastien Murgey <sebastien.murgey@rte-france.com>
  • Loading branch information
murgeyseb authored Feb 22, 2023
1 parent 68d9da7 commit 254bb93
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package com.powsybl.flow_decomposition;

import com.powsybl.flow_decomposition.glsk_provider.AutoGlskProvider;
import com.powsybl.iidm.network.Branch;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Identifiable;
Expand Down Expand Up @@ -58,28 +59,32 @@ public FlowDecompositionComputer(FlowDecompositionParameters flowDecompositionPa
}

public FlowDecompositionResults run(XnecProvider xnecProvider, Network network) {
return run(xnecProvider, new AutoGlskProvider(), network);
}

public FlowDecompositionResults run(XnecProvider xnecProvider, GlskProvider glskProvider, Network network) {
NetworkStateManager networkStateManager = new NetworkStateManager(network, xnecProvider);

LoadFlowRunningService.Result loadFlowServiceAcResult = runAcLoadFlow(network);

Map<Country, Map<String, Double>> glsks = getGlsks(network);
Map<Country, Map<String, Double>> glsks = glskProvider.getGlsk(network);
Map<Country, Double> netPositions = getZonesNetPosition(network);

FlowDecompositionResults flowDecompositionResults = new FlowDecompositionResults(network);
decomposeFlowForNState(network,
flowDecompositionResults,
xnecProvider.getNetworkElements(network),
netPositions,
glsks,
loadFlowServiceAcResult);
xnecProvider.getNetworkElementsPerContingency(network)
.forEach((contingencyId, xnecList) -> decomposeFlowForContingencyState(network,
flowDecompositionResults,
networkStateManager,
contingencyId,
xnecList,
xnecProvider.getNetworkElements(network),
netPositions,
glsks));
glsks,
loadFlowServiceAcResult);
xnecProvider.getNetworkElementsPerContingency(network)
.forEach((contingencyId, xnecList) -> decomposeFlowForContingencyState(network,
flowDecompositionResults,
networkStateManager,
contingencyId,
xnecList,
netPositions,
glsks));
networkStateManager.deleteAllContingencyVariants();
return flowDecompositionResults;
}
Expand Down Expand Up @@ -155,11 +160,6 @@ private void saveAcReferenceFlow(FlowDecompositionResults.PerStateBuilder flowDe
flowDecompositionResultBuilder.saveAcReferenceFlow(acReferenceFlows);
}

private Map<Country, Map<String, Double>> getGlsks(Network network) {
GlskComputer glskComputer = new GlskComputer();
return glskComputer.run(network);
}

private Map<Country, Double> getZonesNetPosition(Network network) {
NetPositionComputer netPositionComputer = new NetPositionComputer();
return netPositionComputer.run(network);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2023, 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 com.powsybl.iidm.network.Network;

import java.util.Map;

/**
* @author Sebastien Murgey {@literal <sebastien.murgey at rte-france.com>}
*/
public interface GlskProvider {
Map<Country, Map<String, Double>> getGlsk(Network network);
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ public static Country getTerminalCountry(Terminal terminal) {
return optionalCountry.get();
}

static Country getInjectionCountry(Injection<?> injection) {
return getTerminalCountry(injection.getTerminal());
}

static String getLoopFlowIdFromCountry(Network network, String identifiableId) {
Identifiable<?> identifiable = network.getIdentifiable(identifiableId);
if (identifiable instanceof Injection) {
Expand All @@ -67,6 +63,10 @@ static Map<String, Integer> getIndex(List<String> idList) {
));
}

public static Country getInjectionCountry(Injection<?> injection) {
return getTerminalCountry(injection.getTerminal());
}

public static List<Branch> getAllValidBranches(Network network) {
return network.getBranchStream()
.filter(NetworkUtil::isConnected)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
* 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;
package com.powsybl.flow_decomposition.glsk_provider;

import com.powsybl.flow_decomposition.GlskProvider;
import com.powsybl.flow_decomposition.NetworkUtil;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Network;

Expand All @@ -18,8 +20,9 @@
* @author Hugo Schindler {@literal <hugo.schindler at rte-france.com>}
* @author Sebastien Murgey {@literal <sebastien.murgey at rte-france.com>}
*/
public class GlskComputer {
public Map<Country, Map<String, Double>> run(Network network) {
public class AutoGlskProvider implements GlskProvider {
@Override
public Map<Country, Map<String, Double>> getGlsk(Network network) {
Map<Country, Map<String, Double>> glsks = network.getCountries().stream().collect(Collectors.toMap(
Function.identity(),
country -> new HashMap<>()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
package com.powsybl.flow_decomposition.xnec_provider;

import com.powsybl.contingency.Contingency;
import com.powsybl.flow_decomposition.GlskComputer;
import com.powsybl.flow_decomposition.NetworkUtil;
import com.powsybl.flow_decomposition.XnecProvider;
import com.powsybl.flow_decomposition.ZonalSensitivityAnalyser;
import com.powsybl.flow_decomposition.*;
import com.powsybl.flow_decomposition.glsk_provider.AutoGlskProvider;
import com.powsybl.iidm.network.Branch;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Network;
Expand All @@ -32,6 +30,11 @@
*/
public class XnecProvider5percPtdf implements XnecProvider {
public static final double MAX_ZONE_TO_ZONE_PTDF_THRESHOLD = 0.05;
private final GlskProvider glskProvider;

public XnecProvider5percPtdf() {
this.glskProvider = new AutoGlskProvider();
}

private static boolean isAXnec(Branch branch, Map<String, Map<Country, Double>> zonalPtdf) {
return XnecProviderInterconnection.isAnInterconnection(branch) || hasMoreThan5PercentPtdf(getZonalPtdf(branch, zonalPtdf));
Expand All @@ -46,9 +49,8 @@ private static boolean hasMoreThan5PercentPtdf(Collection<Double> countryPtdfLis
&& (Collections.max(countryPtdfList) - Collections.min(countryPtdfList)) >= MAX_ZONE_TO_ZONE_PTDF_THRESHOLD;
}

public static Set<Branch> getBranches(Network network) {
GlskComputer glskComputer = new GlskComputer();
Map<Country, Map<String, Double>> glsks = glskComputer.run(network);
public Set<Branch> getBranches(Network network) {
Map<Country, Map<String, Double>> glsks = glskProvider.getGlsk(network);
ZonalSensitivityAnalyser zonalSensitivityAnalyser = new ZonalSensitivityAnalyser(LoadFlowParameters.load(), SensitivityAnalysis.find());
Map<String, Map<Country, Double>> zonalPtdf = zonalSensitivityAnalyser.run(network, glsks, SensitivityVariableType.INJECTION_ACTIVE_POWER);
return NetworkUtil.getAllValidBranches(network)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2023, 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.flow_decomposition.glsk_provider.AutoGlskProvider;
import com.powsybl.flow_decomposition.xnec_provider.XnecProviderByIds;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Network;
import org.junit.jupiter.api.Test;

import java.util.Map;
import java.util.Set;

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

/**
* @author Sebastien Murgey {@literal <sebastien.murgey at rte-france.com>}
*/
class CustomGlskProviderTests {
private static final String NETWORK_FILE_FOR_CUSTOM_GLSK_TEST = "customGlskProviderTestNetwork.uct";
private static final String NETWORK_ELEMENT_DECOMPOSED = "FGEN2 11 FINTER11 1";
private static final double EPSILON = 1e-3;

@Test
void checkThatDefaultGlskProviderIsAutoCountryGlsk() {
FlowDecompositionComputer computer = new FlowDecompositionComputer();
XnecProvider xnecProvider = XnecProviderByIds.builder()
.addNetworkElementsOnBasecase(Set.of(NETWORK_ELEMENT_DECOMPOSED))
.build();
Network network = TestUtils.importNetwork(NETWORK_FILE_FOR_CUSTOM_GLSK_TEST);
FlowDecompositionResults results = computer.run(xnecProvider, network);
assertEquals(0., results.getDecomposedFlowMap().get(NETWORK_ELEMENT_DECOMPOSED).getAllocatedFlow(), EPSILON);
}

@Test
void checkThatDefaultGlskProviderCanBeProvided() {
FlowDecompositionComputer computer = new FlowDecompositionComputer();
XnecProvider xnecProvider = XnecProviderByIds.builder()
.addNetworkElementsOnBasecase(Set.of(NETWORK_ELEMENT_DECOMPOSED))
.build();
GlskProvider glskProvider = new AutoGlskProvider();
Network network = TestUtils.importNetwork(NETWORK_FILE_FOR_CUSTOM_GLSK_TEST);
FlowDecompositionResults results = computer.run(xnecProvider, glskProvider, network);
assertEquals(0., results.getDecomposedFlowMap().get(NETWORK_ELEMENT_DECOMPOSED).getAllocatedFlow(), EPSILON);
}

@Test
void checkThatOtherGlskProviderGivesOtherCorrectResults() {
FlowDecompositionComputer computer = new FlowDecompositionComputer();
XnecProvider xnecProvider = XnecProviderByIds.builder()
.addNetworkElementsOnBasecase(Set.of(NETWORK_ELEMENT_DECOMPOSED))
.build();
GlskProvider glskProvider = network -> Map.of(Country.FR, Map.of("FGEN2 11_generator", 1.0),
Country.BE, Map.of("BGEN 11_generator", 1.0));
Network network = TestUtils.importNetwork(NETWORK_FILE_FOR_CUSTOM_GLSK_TEST);
FlowDecompositionResults results = computer.run(xnecProvider, glskProvider, network);
assertEquals(-100., results.getDecomposedFlowMap().get(NETWORK_ELEMENT_DECOMPOSED).getAllocatedFlow(), EPSILON);
}

@Test
void checkThatLskInGlskProviderGivesOtherCorrectResults() {
FlowDecompositionComputer computer = new FlowDecompositionComputer();
XnecProvider xnecProvider = XnecProviderByIds.builder()
.addNetworkElementsOnBasecase(Set.of(NETWORK_ELEMENT_DECOMPOSED))
.build();
GlskProvider glskProvider = network -> Map.of(Country.FR, Map.of("FGEN2 11_load", 1.0),
Country.BE, Map.of("BGEN 11_generator", 1.0));
Network network = TestUtils.importNetwork(NETWORK_FILE_FOR_CUSTOM_GLSK_TEST);
FlowDecompositionResults results = computer.run(xnecProvider, glskProvider, network);
assertEquals(-100., results.getDecomposedFlowMap().get(NETWORK_ELEMENT_DECOMPOSED).getAllocatedFlow(), EPSILON);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package com.powsybl.flow_decomposition;

import com.powsybl.flow_decomposition.glsk_provider.AutoGlskProvider;
import com.powsybl.iidm.network.Branch;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Network;
Expand Down Expand Up @@ -96,8 +97,8 @@ private static Map<String, Map<String, Double>> getNodalInjections(String networ
if (!loadFlowResult.isOk()) {
LoadFlow.run(network, LoadFlowParameters.load().setDc(true));
}
GlskComputer glskComputer = new GlskComputer();
Map<Country, Map<String, Double>> glsks = glskComputer.run(network);
AutoGlskProvider glskProvider = new AutoGlskProvider();
Map<Country, Map<String, Double>> glsks = glskProvider.getGlsk(network);
Map<Country, Double> netPositions = NetPositionComputer.computeNetPositions(network);
List<Branch> xnecList = network.getBranchStream().collect(Collectors.toList());
NetworkMatrixIndexes networkMatrixIndexes = new NetworkMatrixIndexes(network, xnecList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package com.powsybl.flow_decomposition;

import com.powsybl.flow_decomposition.glsk_provider.AutoGlskProvider;
import com.powsybl.iidm.network.Branch;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Network;
Expand Down Expand Up @@ -70,8 +71,8 @@ void testThatZonalPtdfAreWellComputed() {
String line7 = "FGEN 11 FLOAD 11 7";
String line8 = "FGEN 11 FLOAD 11 8";
String line9 = "FGEN 11 FLOAD 11 9";
GlskComputer glskComputer = new GlskComputer();
Map<Country, Map<String, Double>> glsks = glskComputer.run(network);
AutoGlskProvider glskProvider = new AutoGlskProvider();
Map<Country, Map<String, Double>> glsks = glskProvider.getGlsk(network);
LoadFlowParameters loadFlowParameters = LoadFlowParameters.load();
SensitivityAnalysis.Runner sensitivityAnalysisRunner = SensitivityAnalysis.find();
ZonalSensitivityAnalyser zonalSensitivityAnalyser = new ZonalSensitivityAnalyser(loadFlowParameters, sensitivityAnalysisRunner);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* 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;
package com.powsybl.flow_decomposition.glsk_provider;

import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Network;
Expand All @@ -19,7 +19,7 @@
/**
* @author Hugo Schindler {@literal <hugo.schindler at rte-france.com>}
*/
class GlskTests {
class AutoGlskProviderTests {
private static final double EPSILON = 1e-3;

@Test
Expand All @@ -29,8 +29,8 @@ void testThatGlskAreWellComputed() {
String loadBe = "BLOAD 11_load";
String genFr = "FGEN1 11_generator";
Network network = importNetwork(networkFileName);
GlskComputer glskComputer = new GlskComputer();
Map<Country, Map<String, Double>> glsks = glskComputer.run(network);
AutoGlskProvider autoGlskProvider = new AutoGlskProvider();
Map<Country, Map<String, Double>> glsks = autoGlskProvider.getGlsk(network);
assertEquals(1.0, glsks.get(Country.FR).get(genFr), EPSILON);
assertEquals(1.0, glsks.get(Country.BE).get(genBe), EPSILON);
assertNull(glsks.get(Country.BE).get(loadBe));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
##C 2007.05.01
This is a test network with only two branches.
Each branch is linking a generator with a central load.
Used to validate:
- Basic network importer
- XNEC automatic selection
- GLSK automatic generation
- Zone automatic extraction
##N
##ZFR
FGEN1 11 FGEN1 0 2 400.00 0.00000 0.00000 -200.00 0.00000 1000.00 -1000.0 1000.00 -1000.0
FINTER11 FINTER11 0 0 400.00 0.00000 0.00000
FGEN2 11 FGEN2 0 2 400.00 100.000 0.00000 0.00000 0.00000 1000.00 -1000.0 1000.00 -1000.0
##ZBE
BGEN 11 BGEN1 0 3 400.00 200.000 0.00000 -100.00 0.00000 1000.00 -1000.0 1000.00 -1000.0
##L
FGEN1 11 BGEN 11 1 0 1.0000 0.0500 0.000000 480 LINE
FGEN2 11 FINTER11 1 0 1.0000 0.0500 0.000000 480 LINE
FINTER11 BGEN 11 1 0 1.0000 0.0500 0.000000 480 LINE

0 comments on commit 254bb93

Please sign in to comment.