Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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 @@ -7,13 +7,15 @@

package com.powsybl.openrao.sensitivityanalysis;

import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider;
import com.powsybl.contingency.Contingency;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.iidm.network.Network;
import com.powsybl.sensitivity.SensitivityFactor;
import com.powsybl.sensitivity.SensitivityFunctionType;

import java.util.*;

Expand Down Expand Up @@ -95,4 +97,21 @@ public void disableFactorsForBaseCaseSituation() {
public void enableFactorsForBaseCaseSituation() {
this.afterContingencyOnly = false;
}

Set<SensitivityFunctionType> getSensitivityFunctionTypes(Set<TwoSides> sides) {
Set<SensitivityFunctionType> sensitivityFunctionTypes = new HashSet<>();
if (factorsInMegawatt && sides.contains(TwoSides.ONE)) {
sensitivityFunctionTypes.add(SensitivityFunctionType.BRANCH_ACTIVE_POWER_1);
}
if (factorsInMegawatt && sides.contains(TwoSides.TWO)) {
sensitivityFunctionTypes.add(SensitivityFunctionType.BRANCH_ACTIVE_POWER_2);
}
if (factorsInAmpere && sides.contains(TwoSides.ONE)) {
sensitivityFunctionTypes.add(SensitivityFunctionType.BRANCH_CURRENT_1);
}
if (factorsInAmpere && sides.contains(TwoSides.TWO)) {
sensitivityFunctionTypes.add(SensitivityFunctionType.BRANCH_CURRENT_2);
}
return sensitivityFunctionTypes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,21 +159,4 @@ private List<Pair<String, SensitivityFunctionType>> cnecToSensitivityFunctions(N
}
}

private Set<SensitivityFunctionType> getSensitivityFunctionTypes(Set<TwoSides> sides) {
Set<SensitivityFunctionType> sensitivityFunctionTypes = new HashSet<>();
if (factorsInMegawatt && sides.contains(TwoSides.ONE)) {
sensitivityFunctionTypes.add(SensitivityFunctionType.BRANCH_ACTIVE_POWER_1);
}
if (factorsInMegawatt && sides.contains(TwoSides.TWO)) {
sensitivityFunctionTypes.add(SensitivityFunctionType.BRANCH_ACTIVE_POWER_2);
}
if (factorsInAmpere && sides.contains(TwoSides.ONE)) {
sensitivityFunctionTypes.add(SensitivityFunctionType.BRANCH_CURRENT_1);
}
if (factorsInAmpere && sides.contains(TwoSides.TWO)) {
sensitivityFunctionTypes.add(SensitivityFunctionType.BRANCH_CURRENT_2);
}
return sensitivityFunctionTypes;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
package com.powsybl.openrao.sensitivityanalysis;

import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider;
import com.powsybl.openrao.data.crac.api.NetworkElement;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.iidm.network.TwoSides;
Expand All @@ -19,7 +18,6 @@
import com.powsybl.glsk.commons.ZonalData;
import com.powsybl.iidm.network.Network;
import com.powsybl.sensitivity.SensitivityFactor;
import com.powsybl.sensitivity.SensitivityFunctionType;
import com.powsybl.sensitivity.SensitivityVariableSet;
import com.powsybl.sensitivity.SensitivityVariableType;

Expand All @@ -34,13 +32,6 @@ public class PtdfSensitivityProvider extends AbstractSimpleSensitivityProvider {

PtdfSensitivityProvider(ZonalData<SensitivityVariableSet> glsk, Set<FlowCnec> cnecs, Set<Unit> units) {
super(cnecs, units);

// todo : handle PTDFs in AMPERE
if (factorsInAmpere || !factorsInMegawatt) {
OpenRaoLoggerProvider.TECHNICAL_LOGS.warn("PtdfSensitivity provider currently only handle Megawatt unit");
factorsInMegawatt = true;
factorsInAmpere = false;
}
this.glsk = Objects.requireNonNull(glsk);
}

Expand Down Expand Up @@ -82,17 +73,20 @@ private List<SensitivityFactor> getFactors(ContingencyContext contingencyContext
Map<NetworkElement, Set<TwoSides>> networkElementsAndSides = new HashMap<>();
flowCnecsStream.forEach(cnec -> networkElementsAndSides.computeIfAbsent(cnec.getNetworkElement(), k -> new HashSet<>()).addAll(cnec.getMonitoredSides()));
networkElementsAndSides
.forEach((ne, sides) ->
sides.forEach(side ->
.forEach((ne, sides) -> {
// we allow the computation of both function types (branch_active_power and branch_current) at the same time to match loadFlowProvider behavior
getSensitivityFunctionTypes(sides).forEach(functionType ->
mapCountryLinearGlsk.values().stream()
.map(linearGlsk -> new SensitivityFactor(
sideToActivePowerFunctionType(side),
functionType,
ne.getId(),
SensitivityVariableType.INJECTION_ACTIVE_POWER,
linearGlsk.getId(),
true,
contingencyContext))
.forEach(factors::add)));
.forEach(factors::add)
);
});
return factors;
}

Expand All @@ -101,14 +95,6 @@ public Map<String, HvdcRangeAction> getHvdcs() {
return new HashMap<>();
}

private SensitivityFunctionType sideToActivePowerFunctionType(TwoSides side) {
if (side.equals(TwoSides.ONE)) {
return SensitivityFunctionType.BRANCH_ACTIVE_POWER_1;
} else {
return SensitivityFunctionType.BRANCH_ACTIVE_POWER_2;
}
}

@Override
public List<SensitivityVariableSet> getVariableSets() {
return new ArrayList<>(glsk.getDataPerZone().values());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

package com.powsybl.openrao.sensitivityanalysis;

import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.impl.utils.CommonCracCreation;
Expand All @@ -16,6 +17,7 @@
import com.powsybl.glsk.commons.ZonalDataImpl;
import com.powsybl.iidm.network.Network;
import com.powsybl.sensitivity.SensitivityFactor;
import com.powsybl.sensitivity.SensitivityFunctionType;
import com.powsybl.sensitivity.SensitivityVariableSet;
import com.powsybl.sensitivity.WeightedSensitivityVariable;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -37,7 +39,7 @@ class PtdfSensitivityProviderTest {
@BeforeEach
public void setUp() {
network = NetworkImportsUtil.import12NodesNetwork();
crac = CommonCracCreation.create();
crac = CommonCracCreation.create(Set.of(TwoSides.ONE, TwoSides.TWO));
glskMock = glsk();
}

Expand All @@ -51,15 +53,31 @@ private static ZonalData<SensitivityVariableSet> glsk() {
}

@Test
void getFactorsOnCommonCrac() {
void getFactorsOnCommonCracInMegawatt() {
PtdfSensitivityProvider ptdfSensitivityProvider = new PtdfSensitivityProvider(glskMock, crac.getFlowCnecs(), Collections.singleton(Unit.MEGAWATT));
List<SensitivityFactor> sensitivityFactors = ptdfSensitivityProvider.getBasecaseFactors(network);
assertEquals(8, sensitivityFactors.size());
assertEquals(16, sensitivityFactors.size());
assertTrue(sensitivityFactors.stream().anyMatch(sensitivityFactor -> sensitivityFactor.getFunctionId().contains("FFR2AA1 DDE3AA1 1")
&& sensitivityFactor.getVariableId().contains("10YCB-GERMANY--8")));
assertTrue(sensitivityFactors.stream().allMatch(sensitivityFactor -> sensitivityFactor.getFunctionType().equals(SensitivityFunctionType.BRANCH_ACTIVE_POWER_1) || sensitivityFactor.getFunctionType().equals(SensitivityFunctionType.BRANCH_ACTIVE_POWER_2)));

sensitivityFactors = ptdfSensitivityProvider.getContingencyFactors(network, List.of(new Contingency(crac.getContingencies().iterator().next().getId(), new ArrayList<>())));
assertEquals(8, sensitivityFactors.size());
assertEquals(12, sensitivityFactors.size()); //12 and not 16 because in contingency FR1 FR2, monitor just side one of network elemeent "FFR2AA1 DDE3AA1 1".
assertTrue(sensitivityFactors.stream().anyMatch(sensitivityFactor -> sensitivityFactor.getFunctionId().contains("FFR2AA1 DDE3AA1 1")
&& sensitivityFactor.getVariableId().contains("10YCB-GERMANY--8")));
}

@Test
void getFactorsOnCommonCracInAmpere() {
PtdfSensitivityProvider ptdfSensitivityProvider = new PtdfSensitivityProvider(glskMock, crac.getFlowCnecs(), Collections.singleton(Unit.AMPERE));
List<SensitivityFactor> sensitivityFactors = ptdfSensitivityProvider.getBasecaseFactors(network);
assertEquals(16, sensitivityFactors.size());
assertTrue(sensitivityFactors.stream().anyMatch(sensitivityFactor -> sensitivityFactor.getFunctionId().contains("FFR2AA1 DDE3AA1 1")
&& sensitivityFactor.getVariableId().contains("10YCB-GERMANY--8")));
assertTrue(sensitivityFactors.stream().allMatch(sensitivityFactor -> sensitivityFactor.getFunctionType().equals(SensitivityFunctionType.BRANCH_CURRENT_1) || sensitivityFactor.getFunctionType().equals(SensitivityFunctionType.BRANCH_CURRENT_2)));

sensitivityFactors = ptdfSensitivityProvider.getContingencyFactors(network, List.of(new Contingency(crac.getContingencies().iterator().next().getId(), new ArrayList<>())));
assertEquals(12, sensitivityFactors.size()); //12 and not 16 because in contingency FR1 FR2, monitor just side one of network elemeent "FFR2AA1 DDE3AA1 1".
assertTrue(sensitivityFactors.stream().anyMatch(sensitivityFactor -> sensitivityFactor.getFunctionId().contains("FFR2AA1 DDE3AA1 1")
&& sensitivityFactor.getVariableId().contains("10YCB-GERMANY--8")));
}
Expand All @@ -69,20 +87,21 @@ void testDisableFactorForBaseCase() {
PtdfSensitivityProvider ptdfSensitivityProvider = new PtdfSensitivityProvider(glskMock, crac.getFlowCnecs(), Collections.singleton(Unit.MEGAWATT));

// factors with basecase and contingency
assertEquals(8, ptdfSensitivityProvider.getBasecaseFactors(network).size());
assertEquals(8, ptdfSensitivityProvider.getContingencyFactors(network, List.of(new Contingency("Contingency FR1 FR3", new ArrayList<>()))).size());
assertEquals(16, ptdfSensitivityProvider.getBasecaseFactors(network).size());
assertEquals(16, ptdfSensitivityProvider.getContingencyFactors(network, List.of(new Contingency("Contingency FR1 FR3", new ArrayList<>()))).size());

ptdfSensitivityProvider.disableFactorsForBaseCaseSituation();

// factors after disabling basecase
assertEquals(0, ptdfSensitivityProvider.getBasecaseFactors(network).size());
assertEquals(8, ptdfSensitivityProvider.getContingencyFactors(network, List.of(new Contingency("Contingency FR1 FR3", new ArrayList<>()))).size());
assertEquals(16, ptdfSensitivityProvider.getContingencyFactors(network, List.of(new Contingency("Contingency FR1 FR3", new ArrayList<>()))).size());
}

@Test
void testDoNotHandleAmpere() {
PtdfSensitivityProvider ptdfSensitivityProvider = new PtdfSensitivityProvider(glskMock, crac.getFlowCnecs(), Collections.singleton(Unit.AMPERE));
assertFalse(ptdfSensitivityProvider.factorsInAmpere);
void testDoHandleAmpere() {
// Simple test to check that we can handle PDTF Sensitivity in both Ampere and MW.
PtdfSensitivityProvider ptdfSensitivityProvider = new PtdfSensitivityProvider(glskMock, crac.getFlowCnecs(), Set.of(Unit.AMPERE, Unit.MEGAWATT));
assertTrue(ptdfSensitivityProvider.factorsInAmpere);
assertTrue(ptdfSensitivityProvider.factorsInMegawatt);
}
}