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

Contingency Load Flow parameters extension #1139

Open
wants to merge 9 commits into
base: feature/refactor-outer-loops
Choose a base branch
from
Open
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
11 changes: 11 additions & 0 deletions docs/security/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,14 @@ open-security-analysis-default-parameters:
```

At the moment, overriding the parameters by a JSON file is not supported by Open Load Flow.

## Contingency Parameters

Some load flow related parameters can be configured per contingency. This can be done by adding to the `Contingency` object an extension of the `ContingencyLoadFlowParameters` class.
Those parameters correspond to parameters present in [`LoadFlowParameters`](inv:powsyblcore:*:*#simulation/loadflow/configuration) and [`OpenLoadFlowParameters`](../loadflow/parameters.md#specific-parameters) :

- `distributedSlack` (see [distributedSlack](inv:powsyblcore:*:*#simulation/loadflow/configuration))
- `areaInterchangeControl` (see [areaInterchangeControl](../loadflow/parameters.md#specific-parameters))
- `balanceType` (see [balanceType](inv:powsyblcore:*:*#simulation/loadflow/configuration))

If the extension is added to a contingency, the values of these parameters will override their equivalent of the SA input parameters for post contingency and post remedial actions states calculations.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/)
* 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.openloadflow.sa.extensions;

import com.powsybl.commons.extensions.AbstractExtension;
import com.powsybl.contingency.Contingency;
import com.powsybl.loadflow.LoadFlowParameters;

/**
* @author Valentin Mouradian {@literal <valentin.mouradian at artelys.com>}
*/
public class ContingencyLoadFlowParameters extends AbstractExtension<Contingency> {

private boolean distributedSlack;

private boolean areaInterchangeControl;

private LoadFlowParameters.BalanceType balanceType;

public ContingencyLoadFlowParameters(boolean distributedSlack, boolean areaInterchangeControl, LoadFlowParameters.BalanceType balanceType) {
this.distributedSlack = distributedSlack;
this.areaInterchangeControl = areaInterchangeControl;
this.balanceType = balanceType;
}

@Override
public String getName() {
return "contingency-parameters";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adapt it to the new class name

}

public boolean isDistributedSlack() {
return distributedSlack;
}

public boolean isAreaInterchangeControl() {
return areaInterchangeControl;
}

public LoadFlowParameters.BalanceType getBalanceType() {
return balanceType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.powsybl.openloadflow.sa.extensions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add copyright


import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.google.auto.service.AutoService;
import com.powsybl.commons.extensions.ExtensionJsonSerializer;
import com.powsybl.commons.json.JsonUtil;
import com.powsybl.contingency.Contingency;

import java.io.IOException;

@AutoService(ExtensionJsonSerializer.class)
public class ContingencyLoadFlowParametersJsonSerializer implements ExtensionJsonSerializer<Contingency, ContingencyLoadFlowParameters> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add docstring with the author's name


@Override
public String getExtensionName() {
return "contingency-parameters";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adapt it to new class name "contingency-load-flow-parameters"

}

@Override
public String getCategoryName() {
return "contingency";
}

@Override
public Class<? super ContingencyLoadFlowParameters> getExtensionClass() {
return ContingencyLoadFlowParameters.class;
}

/**
* Specifies serialization for our extension: ignore name and extendable
*/
private interface SerializationSpec {

@JsonIgnore
String getName();

@JsonIgnore
Contingency getExtendable();
}

private static ObjectMapper createMapper() {
return JsonUtil.createObjectMapper()
.addMixIn(ContingencyLoadFlowParameters.class, SerializationSpec.class);
}

@Override
public void serialize(ContingencyLoadFlowParameters extension, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
createMapper().writeValue(jsonGenerator, extension);
}

@Override
public ContingencyLoadFlowParameters deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
return createMapper().readValue(jsonParser, ContingencyLoadFlowParameters.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* Copyright (c) 2024, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/)
* 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.openloadflow.sa.extensions;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.powsybl.commons.json.JsonUtil;
import com.powsybl.commons.test.AbstractSerDeTest;
import com.powsybl.contingency.BranchContingency;
import com.powsybl.contingency.Contingency;
import com.powsybl.contingency.json.ContingencyJsonModule;
import com.powsybl.loadflow.LoadFlowParameters;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;

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

/**
* @author Valentin Mouradian {@literal <valentin.mouradian at artelys.com>}
*/
class OpenSecurityAnalysisExtensionsTest extends AbstractSerDeTest {

@Test
void testContingencyLoadFlowParametersExtension() {
Contingency contingency = new Contingency("L2", new BranchContingency("L2"));
contingency.addExtension(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD));

ContingencyLoadFlowParameters contingencyLoadFlowParameters = contingency.getExtension(ContingencyLoadFlowParameters.class);

assertEquals(contingencyLoadFlowParameters, contingency.getExtensionByName("contingency-parameters"));
assertFalse(contingencyLoadFlowParameters.isDistributedSlack());
assertTrue(contingencyLoadFlowParameters.isAreaInterchangeControl());
assertEquals(LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD, contingencyLoadFlowParameters.getBalanceType());
}

@Test
void testContingencyLoadFlowParametersExtensionJson() throws IOException {
Contingency contingency = new Contingency("L2", new BranchContingency("L2"));
contingency.addExtension(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParameters(false, true, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD));
assertEquals(ContingencyLoadFlowParameters.class, new ContingencyLoadFlowParametersJsonSerializer().getExtensionClass());
roundTripTest(contingency, OpenSecurityAnalysisExtensionsTest::writeContingency, OpenSecurityAnalysisExtensionsTest::readContingency, "/contingencies.json");
}

public static Contingency readContingency(Path jsonFile) {
Objects.requireNonNull(jsonFile);

try (InputStream is = Files.newInputStream(jsonFile)) {
ObjectMapper objectMapper = JsonUtil.createObjectMapper();
ContingencyJsonModule module = new ContingencyJsonModule();
objectMapper.registerModule(module);

return objectMapper.readValue(is, Contingency.class);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

public static void writeContingency(Contingency contingency, Path jsonFile) {
Objects.requireNonNull(contingency);
Objects.requireNonNull(jsonFile);

try (OutputStream os = Files.newOutputStream(jsonFile)) {
ObjectMapper mapper = JsonUtil.createObjectMapper();
ContingencyJsonModule module = new ContingencyJsonModule();
mapper.registerModule(module);

ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
writer.writeValue(os, contingency);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

}
14 changes: 14 additions & 0 deletions src/test/resources/contingencies.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id" : "L2",
"elements" : [ {
"id" : "L2",
"type" : "BRANCH"
} ],
"extensions" : {
"contingency-parameters" : {
"distributedSlack" : false,
"areaInterchangeControl" : true,
"balanceType" : "PROPORTIONAL_TO_LOAD"
}
}
}
Loading