Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
murgeyseb marked this conversation as resolved.
Show resolved Hide resolved

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 {
murgeyseb marked this conversation as resolved.
Show resolved Hide resolved
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) {
murgeyseb marked this conversation as resolved.
Show resolved Hide resolved
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 {
murgeyseb marked this conversation as resolved.
Show resolved Hide resolved
@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;
murgeyseb marked this conversation as resolved.
Show resolved Hide resolved

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