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

Features/inter temporal sensitivity #1235

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c784265
create class InterTemporalRaoInput
Dec 10, 2024
4a3ee38
removed parameters from input class
Dec 11, 2024
218582b
Merge branch 'main' into features/InterTemporalSensitivity
Dec 11, 2024
cb1b85d
WIP Beginning of InterTemporal Sensitivity Analysis
Dec 11, 2024
d14c18a
add LF and sensi values in test
bqth29 Dec 12, 2024
1a0e329
Fixed sensi computation in parallel
Dec 12, 2024
ff7c80a
add InterTemporalParameters
Dec 12, 2024
f590971
Merge branch 'main' into features/InterTemporalSensitivity
bqth29 Dec 12, 2024
18eda9c
more relevant tests
bqth29 Dec 12, 2024
9118bf0
merge head
Dec 12, 2024
5db3cbe
add json for inter temporal parameter
Dec 12, 2024
2d0d2a0
fix conflict
Dec 12, 2024
751ec91
fix style
Dec 13, 2024
5f81d1f
fix tests
bqth29 Dec 13, 2024
73ad3a8
parallel RAOs
bqth29 Dec 13, 2024
4c9b880
use right Pait class
bqth29 Dec 13, 2024
44e255f
intertemporal pool
bqth29 Dec 13, 2024
481fe3e
Merge branch 'feature/multi-ts-topological-optimization' into feature…
bqth29 Dec 13, 2024
ee64c9c
use of inter-temporal pool for parallel computation
bqth29 Dec 13, 2024
e2e0dd4
Merge branch 'main' into features/InterTemporalSensitivity
bqth29 Jan 2, 2025
49129bd
some fixes
bqth29 Jan 2, 2025
c9f5777
refactored inputs
bqth29 Jan 2, 2025
ae8b9ff
changes after comments
bqth29 Jan 3, 2025
c9a1419
Merge branch 'main' into features/InterTemporalSensitivity
bqth29 Jan 6, 2025
0819feb
use ThreadPoolExecutor for more relevant nested inter temporal pools
bqth29 Jan 6, 2025
ec84aac
Merge branch 'features/InterTemporalSensitivity' of https://github.co…
bqth29 Jan 6, 2025
e6b0dbb
Merge branch 'main' into features/InterTemporalSensitivity
bqth29 Jan 6, 2025
d5abe3a
remove inter-temporal extension of parameters
bqth29 Jan 6, 2025
2e31413
fix tests
bqth29 Jan 6, 2025
8d00373
add unit test
Jan 14, 2025
d6730df
fix style
Jan 14, 2025
c32b8c9
use ForkJoinPool again
bqth29 Jan 14, 2025
7d36b3f
Merge branch 'main' into features/InterTemporalSensitivity
bqth29 Jan 15, 2025
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,12 +7,14 @@

package com.powsybl.openrao.raoapi;

import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.TemporalData;
import com.powsybl.openrao.data.intertemporalconstraint.PowerGradientConstraint;

import java.time.OffsetDateTime;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author Thomas Bouquet {@literal <thomas.bouquet at rte-france.com>}
Expand All @@ -27,6 +29,7 @@ public InterTemporalRaoInput(TemporalData<RaoInput> raoInputs, Set<OffsetDateTim
this.raoInputs = raoInputs;
this.timestampsToRun = timestampsToRun;
this.powerGradientConstraints = powerGradientConstraints;
checkTimestampsToRun();
}

public InterTemporalRaoInput(TemporalData<RaoInput> raoInputs, Set<PowerGradientConstraint> powerGradientConstraints) {
Expand All @@ -44,4 +47,11 @@ public Set<OffsetDateTime> getTimestampsToRun() {
public Set<PowerGradientConstraint> getPowerGradientConstraints() {
return powerGradientConstraints;
}

private void checkTimestampsToRun() {
bqth29 marked this conversation as resolved.
Show resolved Hide resolved
Set<String> invalidTimestampsToRun = timestampsToRun.stream().filter(timestamp -> !raoInputs.getTimestamps().contains(timestamp)).map(OffsetDateTime::toString).collect(Collectors.toSet());
if (!invalidTimestampsToRun.isEmpty()) {
throw new OpenRaoException("Timestamp(s) '" + String.join("', '", invalidTimestampsToRun) + "' are not defined in the inputs.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ private RaoParametersCommons() {
public static final String PTDF_BOUNDARIES = "ptdf-boundaries";
public static final String PTDF_SUM_LOWER_BOUND = "ptdf-sum-lower-bound";

// -- Inter Temporal parameters
public static final String INTER_TEMPORAL_PARAMETERS = "inter-temporal-parameters";
public static final String INTER_TEMPORAL_PARAMETERS_SECTION = "rao-inter-temporal-parameters";
public static final String SENSITIVITY_COMPUTATIONS_IN_PARALLEL = "sensitivity-computations-in-parallel";

public static PtdfApproximation stringToPtdfApproximation(String string) {
try {
return PtdfApproximation.valueOf(string);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

package com.powsybl.openrao.raoapi;

import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.TemporalData;
import com.powsybl.openrao.commons.TemporalDataImpl;
import com.powsybl.openrao.data.crac.api.rangeaction.VariationDirection;
Expand All @@ -21,6 +22,7 @@
import java.util.Set;

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

/**
* @author Thomas Bouquet {@literal <thomas.bouquet at rte-france.com>}
Expand Down Expand Up @@ -60,4 +62,16 @@ void testInstantiateInterTemporalRaoInputAllTimestamps() {
assertEquals(Set.of(timestamp1, timestamp2, timestamp3), input.getTimestampsToRun());
assertEquals(powerGradientConstraints, input.getPowerGradientConstraints());
}

@Test
void testInstantiateWithMissingTimestamp() {
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> new InterTemporalRaoInput(temporalData, Set.of(OffsetDateTime.of(2024, 12, 11, 14, 29, 0, 0, ZoneOffset.UTC)), Set.of()));
assertEquals("Timestamp(s) '2024-12-11T14:29Z' are not defined in the inputs.", exception.getMessage());
}

@Test
bqth29 marked this conversation as resolved.
Show resolved Hide resolved
void testInstantiateWithMissingTimestamps() {
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> new InterTemporalRaoInput(temporalData, Set.of(OffsetDateTime.of(2024, 12, 11, 14, 29, 0, 0, ZoneOffset.UTC), OffsetDateTime.of(2024, 11, 11, 14, 29, 0, 0, ZoneOffset.UTC)), Set.of()));
assertEquals("Timestamp(s) '2024-11-11T14:29Z', '2024-12-11T14:29Z' are not defined in the inputs.", exception.getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
import com.powsybl.openrao.raoapi.parameters.RangeActionsOptimizationParameters;
import com.powsybl.openrao.raoapi.parameters.RaoParameters;
import com.powsybl.openrao.raoapi.parameters.SecondPreventiveRaoParameters;
import com.powsybl.openrao.raoapi.parameters.extensions.LoopFlowParametersExtension;
import com.powsybl.openrao.raoapi.parameters.extensions.MnecParametersExtension;
import com.powsybl.openrao.raoapi.parameters.extensions.PtdfApproximation;
import com.powsybl.openrao.raoapi.parameters.extensions.RelativeMarginsParametersExtension;
import com.powsybl.openrao.raoapi.parameters.extensions.*;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* 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/.
*/

package com.powsybl.openrao.searchtreerao.castor.algorithm;

import com.powsybl.iidm.network.Network;
import com.powsybl.openrao.commons.TemporalData;
import com.powsybl.openrao.data.crac.api.Instant;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.openrao.data.crac.api.rangeaction.RangeAction;
import com.powsybl.openrao.raoapi.InterTemporalRaoInput;
import com.powsybl.openrao.raoapi.RaoInput;
import com.powsybl.openrao.raoapi.parameters.RaoParameters;
import com.powsybl.openrao.raoapi.parameters.extensions.LoopFlowParametersExtension;
import com.powsybl.openrao.searchtreerao.commons.SensitivityComputer;
import com.powsybl.openrao.searchtreerao.commons.ToolProvider;
import com.powsybl.openrao.searchtreerao.result.api.LoadFlowAndSensitivityResult;
import com.powsybl.openrao.util.InterTemporalPool;

import java.time.OffsetDateTime;
import java.util.*;

/**
* @author Thomas Bouquet {@literal <thomas.bouquet at rte-france.com>}
* @author Roxane Chen {@literal <roxane.chen at rte-france.com>}
*/
public class InterTemporalSensitivityAnalysis {
private final InterTemporalRaoInput input;
private final RaoParameters parameters;
private final TemporalData<Set<RangeAction<?>>> rangeActionsPerTimestamp;
private final TemporalData<Set<FlowCnec>> flowCnecsPerTimestamp;

public InterTemporalSensitivityAnalysis(InterTemporalRaoInput input, RaoParameters parameters) {
InterTemporalSensitivityAnalysisHelper helper = new InterTemporalSensitivityAnalysisHelper(input);
this.input = input;
this.parameters = parameters;
this.rangeActionsPerTimestamp = helper.getRangeActions();
this.flowCnecsPerTimestamp = helper.getFlowCnecs();
}

public TemporalData<LoadFlowAndSensitivityResult> runInitialSensitivityAnalysis() throws InterruptedException {
return new InterTemporalPool(input.getTimestampsToRun()).runTasks(this::runForTimestamp);
}

private LoadFlowAndSensitivityResult runForTimestamp(OffsetDateTime timestamp) {
RaoInput raoInput = input.getRaoInputs().getData(timestamp).orElseThrow();
Network network = raoInput.getNetwork();
ToolProvider toolProvider = ToolProvider.buildFromRaoInputAndParameters(raoInput, parameters);
SensitivityComputer sensitivityComputer = buildSensitivityComputer(flowCnecsPerTimestamp.getData(timestamp).orElse(Set.of()), rangeActionsPerTimestamp.getData(timestamp).orElse(Set.of()), raoInput.getCrac().getOutageInstant(), toolProvider);
sensitivityComputer.compute(network);
return new LoadFlowAndSensitivityResult(sensitivityComputer.getBranchResult(network), sensitivityComputer.getSensitivityResult());
}

private SensitivityComputer buildSensitivityComputer(Set<FlowCnec> flowCnecs, Set<RangeAction<?>> rangeActions, Instant outageInstant, ToolProvider toolProvider) {
SensitivityComputer.SensitivityComputerBuilder sensitivityComputerBuilder = SensitivityComputer.create()
.withToolProvider(toolProvider)
.withCnecs(flowCnecs)
.withRangeActions(rangeActions)
.withOutageInstant(outageInstant);

if (parameters.hasExtension(LoopFlowParametersExtension.class)) {
sensitivityComputerBuilder.withCommercialFlowsResults(toolProvider.getLoopFlowComputation(), toolProvider.getLoopFlowCnecs(flowCnecs));
}
if (parameters.getObjectiveFunctionParameters().getType().relativePositiveMargins()) {
sensitivityComputerBuilder.withPtdfsResults(toolProvider.getAbsolutePtdfSumsComputation(), flowCnecs);
}

return sensitivityComputerBuilder.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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/.
*/

package com.powsybl.openrao.searchtreerao.castor.algorithm;

import com.powsybl.openrao.commons.TemporalData;
import com.powsybl.openrao.commons.TemporalDataImpl;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.openrao.data.crac.api.rangeaction.RangeAction;
import com.powsybl.openrao.data.crac.api.usagerule.UsageMethod;
import com.powsybl.openrao.raoapi.InterTemporalRaoInput;
import com.powsybl.openrao.raoapi.RaoInput;

import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author Thomas Bouquet {@literal <thomas.bouquet at rte-france.com>}
* @author Roxane Chen {@literal <roxane.chen at rte-france.com>}
*/
public class InterTemporalSensitivityAnalysisHelper {
private InterTemporalRaoInput input;

public InterTemporalSensitivityAnalysisHelper(InterTemporalRaoInput input) {
this.input = input;
}

public TemporalData<Set<RangeAction<?>>> getRangeActions() {
Map<OffsetDateTime, Set<RangeAction<?>>> rangeActions = new HashMap<>();
Set<RangeAction<?>> allRangeActions = new HashSet<>();

// TODO: see what to do if RAs have same id across timestamps (same object from RemedialAction::equals)
input.getRaoInputs().getTimestamps().forEach(timestamp -> {
Crac crac = input.getRaoInputs().getData(timestamp).orElseThrow().getCrac();
allRangeActions.addAll(crac.getRangeActions(crac.getPreventiveState(), UsageMethod.AVAILABLE, UsageMethod.FORCED));
rangeActions.put(timestamp, new HashSet<>(allRangeActions));
});

return new TemporalDataImpl<>(rangeActions);
}

public TemporalData<Set<FlowCnec>> getFlowCnecs() {
return input.getRaoInputs().map(RaoInput::getCrac).map(crac -> crac.getFlowCnecs().stream().filter(flowCnec -> flowCnec.getState().isPreventive() || flowCnec.getState().getInstant().isOutage()).collect(Collectors.toSet()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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/.
*/

package com.powsybl.openrao.searchtreerao.result.api;

/**
* @author Thomas Bouquet {@literal <thomas.bouquet at rte-france.com>}
* @author Roxane Chen {@literal <roxane.chen at rte-france.com>}
*/
public record LoadFlowAndSensitivityResult(FlowResult flowResult, SensitivityResult sensitivityResult) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* 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/.
*/

package com.powsybl.openrao.searchtreerao.castor.algorithm;

import com.powsybl.iidm.network.Network;
import com.powsybl.openrao.commons.TemporalDataImpl;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.raoapi.InterTemporalRaoInput;
import com.powsybl.openrao.raoapi.RaoInput;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Map;
import java.util.Set;

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

/**
* @author Thomas Bouquet {@literal <thomas.bouquet at rte-france.com>}
* @author Roxane Chen {@literal <roxane.chen at rte-france.com>}
*/
class InterTemporalSensitivityAnalysisHelperTest {
private Crac crac1;
private Crac crac2;
private Crac crac3;
private final OffsetDateTime timestamp1 = OffsetDateTime.of(2024, 12, 10, 16, 21, 0, 0, ZoneOffset.UTC);
private final OffsetDateTime timestamp2 = OffsetDateTime.of(2024, 12, 10, 17, 21, 0, 0, ZoneOffset.UTC);
private final OffsetDateTime timestamp3 = OffsetDateTime.of(2024, 12, 10, 18, 21, 0, 0, ZoneOffset.UTC);
private InterTemporalSensitivityAnalysisHelper helper;

@BeforeEach
void setUp() throws IOException {
Network network1 = Network.read("12Nodes_2_pst.uct", InterTemporalSensitivityAnalysisHelperTest.class.getResourceAsStream("/network/12Nodes_2_pst.uct"));
Network network2 = Network.read("12Nodes_2_pst.uct", InterTemporalSensitivityAnalysisHelperTest.class.getResourceAsStream("/network/12Nodes_2_pst.uct"));
Network network3 = Network.read("12Nodes_2_pst.uct", InterTemporalSensitivityAnalysisHelperTest.class.getResourceAsStream("/network/12Nodes_2_pst.uct"));

crac1 = Crac.read("small-crac-2pst-1600.json", InterTemporalSensitivityAnalysisHelperTest.class.getResourceAsStream("/crac/small-crac-2pst-1600.json"), network1);
crac2 = Crac.read("small-crac-2pst-1700.json", InterTemporalSensitivityAnalysisHelperTest.class.getResourceAsStream("/crac/small-crac-2pst-1700.json"), network2);
crac3 = Crac.read("small-crac-2pst-1800.json", InterTemporalSensitivityAnalysisHelperTest.class.getResourceAsStream("/crac/small-crac-2pst-1800.json"), network3);

RaoInput raoInput1 = RaoInput.build(network1, crac1).build();
RaoInput raoInput2 = RaoInput.build(network2, crac2).build();
RaoInput raoInput3 = RaoInput.build(network3, crac3).build();

InterTemporalRaoInput input = new InterTemporalRaoInput(new TemporalDataImpl<>(Map.of(timestamp1, raoInput1, timestamp2, raoInput2, timestamp3, raoInput3)), Set.of());
helper = new InterTemporalSensitivityAnalysisHelper(input);
}

@Test
void getRangeActionsPerTimestamp() {
assertEquals(
Map.of(timestamp1, Set.of(crac1.getRangeAction("pstBe - 1600")),
timestamp2, Set.of(crac1.getRangeAction("pstBe - 1600"), crac2.getRangeAction("pstBe - 1700")),
timestamp3, Set.of(crac1.getRangeAction("pstBe - 1600"), crac2.getRangeAction("pstBe - 1700"), crac3.getRangeAction("pstBe - 1800"), crac3.getRangeAction("pstDe - 1800"))),
helper.getRangeActions().getDataPerTimestamp());

}

@Test
void getFlowCnecsPerTimestamp() {
assertEquals(
Map.of(timestamp1, Set.of(crac1.getFlowCnec("cnecDeNlPrev - 1600"), crac1.getFlowCnec("cnecDeNlOut - 1600")),
timestamp2, Set.of(crac2.getFlowCnec("cnecDeNlPrev - 1700"), crac2.getFlowCnec("cnecDeNlOut - 1700")),
timestamp3, Set.of(crac3.getFlowCnec("cnecDeNlPrev - 1800"), crac3.getFlowCnec("cnecDeNlOut - 1800"))),
helper.getFlowCnecs().getDataPerTimestamp());

}
}
Loading
Loading