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

Fix invalid factors in specific contingency context #837

Merged
merged 5 commits into from
Sep 28, 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 @@ -9,6 +9,7 @@
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.reporter.Reporter;
import com.powsybl.contingency.ContingencyContext;
import com.powsybl.contingency.ContingencyContextType;
import com.powsybl.iidm.network.*;
import com.powsybl.loadflow.LoadFlowParameters;
import com.powsybl.math.matrix.DenseMatrix;
Expand Down Expand Up @@ -706,25 +707,41 @@ protected boolean rescaleGlsk(SensitivityFactorGroupList<V, E> factorGroups, Set
/**
* Write zero or skip factors to output and send a new factor holder containing only other valid ones.
* IMPORTANT: this is only a base case test (factor status only deal with base case). We do not output anything
* on post contingency if factor is already invalid (skip o zero) on base case.
* on post contingency if factor is already invalid (skip o zero) on base case. Except for factors with specific
* contingency context, we output the invalid status found during base case analysis.
*/
protected SensitivityFactorHolder<V, E> writeInvalidFactors(SensitivityFactorHolder<V, E> factorHolder, SensitivityResultWriter resultWriter) {
protected SensitivityFactorHolder<V, E> writeInvalidFactors(SensitivityFactorHolder<V, E> factorHolder, SensitivityResultWriter resultWriter,
List<PropagatedContingency> contingencies) {
Set<String> skippedVariables = new LinkedHashSet<>();
SensitivityFactorHolder<V, E> validFactorHolder = new SensitivityFactorHolder<>();
Map<String, Integer> contingencyIndexById = new HashMap<>();
contingencies.stream().forEach(contingency -> contingencyIndexById.put(contingency.getContingency().getId(), contingency.getIndex()));
for (var factor : factorHolder.getAllFactors()) {
// directly write output for zero and invalid factors
Optional<Double> sensitivityVariableToWrite = Optional.empty();
if (factor.getStatus() == LfSensitivityFactor.Status.ZERO) {
// ZERO status is for factors where variable element is in the main connected component and reference element is not.
// Therefore, the sensitivity is known to value 0, but the reference cannot be known and is set to NaN.
if (!filterSensitivityValue(0, factor.getVariableType(), factor.getFunctionType(), parameters)) {
resultWriter.writeSensitivityValue(factor.getIndex(), -1, 0, Double.NaN);
sensitivityVariableToWrite = Optional.of(0.0);
}
} else if (factor.getStatus() == LfSensitivityFactor.Status.SKIP) {
resultWriter.writeSensitivityValue(factor.getIndex(), -1, Double.NaN, Double.NaN);
sensitivityVariableToWrite = Optional.of(Double.NaN);
skippedVariables.add(factor.getVariableId());
} else {
validFactorHolder.addFactor(factor);
}
if (sensitivityVariableToWrite.isPresent()) {
// directly write output for zero and invalid factors
double value = sensitivityVariableToWrite.get();
if (factor.getContingencyContext().getContextType() == ContingencyContextType.NONE) {
resultWriter.writeSensitivityValue(factor.getIndex(), -1, value, Double.NaN);
} else if (factor.getContingencyContext().getContextType() == ContingencyContextType.SPECIFIC) {
resultWriter.writeSensitivityValue(factor.getIndex(), contingencyIndexById.get(factor.getContingencyContext().getContingencyId()), value, Double.NaN);
} else if (factor.getContingencyContext().getContextType() == ContingencyContextType.ALL) {
resultWriter.writeSensitivityValue(factor.getIndex(), -1, value, Double.NaN);
contingencyIndexById.values().forEach(index -> resultWriter.writeSensitivityValue(factor.getIndex(), index, value, Double.NaN));
}
}
}
if (!skippedVariables.isEmpty() && LOGGER.isWarnEnabled()) {
LOGGER.warn("Skipping all factors with variables: '{}', as they cannot be found in the network",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ public void analyse(Network network, List<PropagatedContingency> contingencies,
LOGGER.info("Running AC sensitivity analysis with {} factors and {} contingencies", allLfFactors.size(), contingencies.size());

// next we only work with valid and valid only for function factors
var validFactorHolder = writeInvalidFactors(allFactorHolder, resultWriter);
var validFactorHolder = writeInvalidFactors(allFactorHolder, resultWriter, contingencies);
var validLfFactors = validFactorHolder.getAllFactors();

// create AC engine
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ public void analyse(Network network, List<PropagatedContingency> contingencies,
var dcLoadFlowParameters = createDcLoadFlowParameters(lfNetworkParameters, matrixFactory, lfParameters, lfParametersExt);

// next we only work with valid factors
var validFactorHolder = writeInvalidFactors(allFactorHolder, resultWriter);
var validFactorHolder = writeInvalidFactors(allFactorHolder, resultWriter, contingencies);
var validLfFactors = validFactorHolder.getAllFactors();
LOGGER.info("{}/{} factors are valid", validLfFactors.size(), allLfFactors.size());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,28 @@ void testPredefinedResults4() {
assertEquals(Double.NaN, result.getBranchFlow1SensitivityValue("l23", "l23", "l23", SensitivityVariableType.TRANSFORMER_PHASE), LoadFlowAssert.DELTA_POWER);
}

@Test
void testPredefinedResults5() {
Network network = HvdcNetworkFactory.createNetworkWithGenerators();
network.getLine("l25").getTerminal1().disconnect();
network.getLine("l25").getTerminal2().disconnect();
SensitivityAnalysisParameters sensiParameters = createParameters(true, "b1_vl_0", true);
// with contingency context all
List<Contingency> contingencies = Collections.singletonList(new Contingency("l12", new BranchContingency("l12")));
List<SensitivityFactor> factors = List.of(createBranchFlowPerInjectionIncrease("l46", "g1")); // all contingency context.
SensitivityAnalysisResult result = sensiRunner.run(network, factors, contingencies, Collections.emptyList(), sensiParameters);
assertEquals(0.0, result.getBranchFlow1SensitivityValue("g1", "l46", SensitivityVariableType.INJECTION_ACTIVE_POWER), LoadFlowAssert.DELTA_POWER);
assertEquals(Double.NaN, result.getBranchFlow1FunctionReferenceValue("l46"), LoadFlowAssert.DELTA_POWER);
assertEquals(0.0, result.getBranchFlow1SensitivityValue("l12", "g1", "l46", SensitivityVariableType.INJECTION_ACTIVE_POWER), LoadFlowAssert.DELTA_POWER);
assertEquals(Double.NaN, result.getBranchFlow1FunctionReferenceValue("l12", "l46"), LoadFlowAssert.DELTA_POWER);
// with contingency context specific (no pre contingency state asked...)
factors = List.of(createBranchFlowPerInjectionIncrease("l46", "g1", "l12")); // specific contingency context.
result = sensiRunner.run(network, factors, contingencies, Collections.emptyList(), sensiParameters);
assertEquals(0.0, result.getBranchFlow1SensitivityValue("l12", "g1", "l46", SensitivityVariableType.INJECTION_ACTIVE_POWER), LoadFlowAssert.DELTA_POWER);
assertEquals(Double.NaN, result.getBranchFlow1FunctionReferenceValue("l12", "l46"), LoadFlowAssert.DELTA_POWER);
assertTrue(result.getValues(null).isEmpty()); // nothing because invalid factor in pre contingency state.
}

@Test
void testRestoreAfterContingencyOnHvdc() {
Network network = HvdcNetworkFactory.createWithHvdcInAcEmulation();
Expand Down