Skip to content
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
59 changes: 59 additions & 0 deletions cpp/powsybl-cpp/powsybl-cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,34 @@ void deleteDynamicSimulationParameters(dynamic_simulation_parameters* ptr) {
pypowsybl::deleteCharPtrPtr(ptr->provider_parameters.provider_parameters_values, ptr->provider_parameters.provider_parameters_values_count);
}

void deleteDynamicSecurityAnalysisParameters(dynamic_security_analysis_parameters* ptr) {
pypowsybl::deleteCharPtrPtr(ptr->provider_parameters.provider_parameters_keys, ptr->provider_parameters.provider_parameters_keys_count);
pypowsybl::deleteCharPtrPtr(ptr->provider_parameters.provider_parameters_values, ptr->provider_parameters.provider_parameters_values_count);
delete[] ptr->debug_dir;
}

DynamicSecurityAnalysisParameters::DynamicSecurityAnalysisParameters(dynamic_security_analysis_parameters* src) {
start_time = (double) src->start_time;
stop_time = (double) src->stop_time;
contingencies_start_time = (double) src->contingencies_start_time;
debug_dir = toString(src->debug_dir);
providerParametersFromCStruct(src->provider_parameters, provider_parameters_keys, provider_parameters_values);
}

std::shared_ptr<dynamic_security_analysis_parameters> DynamicSecurityAnalysisParameters::to_c_struct() const {
dynamic_security_analysis_parameters* res = new dynamic_security_analysis_parameters();
res->start_time = (double) start_time;
res->stop_time = (double) stop_time;
res->contingencies_start_time = (double) contingencies_start_time;
res->debug_dir = copyStringToCharPtr(debug_dir);
providerParametersToCStruct(res->provider_parameters, provider_parameters_keys, provider_parameters_values);
//Memory has been allocated here on C side, we need to clean it up on C side (not java side)
return std::shared_ptr<dynamic_security_analysis_parameters>(res, [](dynamic_security_analysis_parameters* ptr){
deleteDynamicSecurityAnalysisParameters(ptr);
delete ptr;
});
}

DynamicSimulationParameters::DynamicSimulationParameters(dynamic_simulation_parameters* src) {
start_time = (double) src->start_time;
stop_time = (double) src->stop_time;
Expand Down Expand Up @@ -1846,6 +1874,37 @@ SeriesArray* getTimeline(JavaHandle resultHandle) {
return new SeriesArray(PowsyblCaller::get()->callJava<array*>(::getTimeline, resultHandle));
}

JavaHandle createDynamicSecurityAnalysis() {
return PowsyblCaller::get()->callJava<JavaHandle>(::createDynamicSecurityAnalysis);
}

void addDynamicMonitoredElements(const JavaHandle& dynamicSecurityAnalysisContext, contingency_context_type contingencyContextType,
const std::vector<std::string>& branchIds, const std::vector<std::string>& voltageLevelIds,
const std::vector<std::string>& threeWindingsTransformerIds, const std::vector<std::string>& contingencyIds) {
ToCharPtrPtr branchIdsPtr(branchIds);
ToCharPtrPtr voltageLevelIdsPtr(voltageLevelIds);
ToCharPtrPtr threeWindingsTransformerIdsPtr(threeWindingsTransformerIds);
ToCharPtrPtr contingencyIdsPtr(contingencyIds);
PowsyblCaller::get()->callJava<>(::addDynamicMonitoredElements, dynamicSecurityAnalysisContext, contingencyContextType, branchIdsPtr.get(), branchIds.size(),
voltageLevelIdsPtr.get(), voltageLevelIds.size(), threeWindingsTransformerIdsPtr.get(),
threeWindingsTransformerIds.size(), contingencyIdsPtr.get(), contingencyIds.size());
}

DynamicSecurityAnalysisParameters* createDynamicSecurityAnalysisParameters() {
dynamic_security_analysis_parameters* parameters_ptr = PowsyblCaller::get()->callJava<dynamic_security_analysis_parameters*>(::createDynamicSecurityAnalysisParameters);
auto parameters = std::shared_ptr<dynamic_security_analysis_parameters>(parameters_ptr, [](dynamic_security_analysis_parameters* ptr){
PowsyblCaller::get()->callJava(::freeDynamicSecurityAnalysisParameters, ptr);
});
return new DynamicSecurityAnalysisParameters(parameters.get());
}

JavaHandle runDynamicSecurityAnalysis(JavaHandle dynamicSecurityAnalysisContext, JavaHandle network, JavaHandle dynamicMapping,
JavaHandle* eventMapping, DynamicSecurityAnalysisParameters& parameters, const std::string& provider, JavaHandle* reportNode) {
auto c_parameters = parameters.to_c_struct();
return PowsyblCaller::get()->callJava<JavaHandle>(::runDynamicSecurityAnalysis, dynamicSecurityAnalysisContext, network, dynamicMapping,
(eventMapping == nullptr) ? nullptr : *eventMapping, c_parameters.get(), (char*) provider.data(), (reportNode == nullptr) ? nullptr : *reportNode);
}

std::vector<std::string> getCategories() {
ToStringVector vector(PowsyblCaller::get()->callJava<array*>(::getCategories));
return vector.get();
Expand Down
23 changes: 23 additions & 0 deletions cpp/powsybl-cpp/powsybl-cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,19 @@ class DynamicSimulationParameters {
std::vector<std::string> provider_parameters_values;
};

class DynamicSecurityAnalysisParameters {
public:
DynamicSecurityAnalysisParameters(dynamic_security_analysis_parameters* src);
std::shared_ptr<dynamic_security_analysis_parameters> to_c_struct() const;

double start_time;
double stop_time;
double contingencies_start_time;
std::string debug_dir;
std::vector<std::string> provider_parameters_keys;
std::vector<std::string> provider_parameters_values;
};

enum class RescaleMode {
NONE = 0,
ACER_METHODOLOGY,
Expand Down Expand Up @@ -1023,6 +1036,16 @@ SeriesArray* getDynamicCurves(JavaHandle resultHandle);
SeriesArray* getFinalStateValues(JavaHandle resultHandle);
SeriesArray* getTimeline(JavaHandle resultHandle);

// dynamic security analysis
JavaHandle createDynamicSecurityAnalysis();
void addDynamicMonitoredElements(const JavaHandle& dynamicSecurityAnalysisContext, contingency_context_type contingencyContextType,
const std::vector<std::string>& branchIds, const std::vector<std::string>& voltageLevelIds,
const std::vector<std::string>& threeWindingsTransformerIds, const std::vector<std::string>& contingencyIds);
JavaHandle runDynamicSecurityAnalysis(JavaHandle dynamicSecurityAnalysisContext, JavaHandle network, JavaHandle dynamicMapping,
JavaHandle* eventMapping, DynamicSecurityAnalysisParameters& parameters, const std::string& provider, JavaHandle* reportNode);

DynamicSecurityAnalysisParameters* createDynamicSecurityAnalysisParameters();

//=======END OF dynamic modeling for dynawo package==========

//=======Voltage initializer mapping========
Expand Down
19 changes: 19 additions & 0 deletions cpp/pypowsybl-cpp/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,16 @@ void dynamicSimulationBindings(py::module_& m) {
m.def("get_dynamic_curves", &pypowsybl::getDynamicCurves, py::arg("report_handle"));
m.def("get_final_state_values", &pypowsybl::getFinalStateValues, py::arg("result_handle"));
m.def("get_timeline", &pypowsybl::getTimeline, py::arg("result_handle"));

// dynamic security analysis
m.def("create_dynamic_security_analysis", &pypowsybl::createDynamicSecurityAnalysis, "Create a dynamic security analysis");
m.def("add_dynamic_monitored_elements", &pypowsybl::addDynamicMonitoredElements,
"Add monitors to get specific results on network after dynamic security analysis process",
py::arg("dynamic_security_analysis_context"), py::arg("contingency_context_type"), py::arg("branch_ids"),
py::arg("voltage_level_ids"), py::arg("three_windings_transformer_ids"), py::arg("contingency_ids"));
m.def("run_dynamic_security_analysis", &pypowsybl::runDynamicSecurityAnalysis, "Run a dynamic security analysis",
py::call_guard<py::gil_scoped_release>(), py::arg("dynamic_security_analysis_context"), py::arg("network"),
py::arg("dynamic_mapping"), py::arg("event_mapping"), py::arg("parameters"), py::arg("provider"), py::arg("report_node"));
}

void voltageInitializerBinding(py::module_& m) {
Expand Down Expand Up @@ -653,6 +663,15 @@ PYBIND11_MODULE(_pypowsybl, m) {
.def_readwrite("provider_parameters_keys", &pypowsybl::DynamicSimulationParameters::provider_parameters_keys)
.def_readwrite("provider_parameters_values", &pypowsybl::DynamicSimulationParameters::provider_parameters_values);

py::class_<pypowsybl::DynamicSecurityAnalysisParameters>(m, "DynamicSecurityAnalysisParameters")
.def(py::init(&pypowsybl::createDynamicSecurityAnalysisParameters))
.def_readwrite("start_time", &pypowsybl::DynamicSecurityAnalysisParameters::start_time)
.def_readwrite("stop_time", &pypowsybl::DynamicSecurityAnalysisParameters::stop_time)
.def_readwrite("contingencies_start_time", &pypowsybl::DynamicSecurityAnalysisParameters::contingencies_start_time)
.def_readwrite("debug_dir", &pypowsybl::DynamicSecurityAnalysisParameters::debug_dir)
.def_readwrite("provider_parameters_keys", &pypowsybl::DynamicSecurityAnalysisParameters::provider_parameters_keys)
.def_readwrite("provider_parameters_values", &pypowsybl::DynamicSecurityAnalysisParameters::provider_parameters_values);

m.def("check_loadflow_parameters", &pypowsybl::checkLoadFlowParameters, "Check load flow parameters",
py::arg("parameters"), py::arg("provider"), py::arg("report_node"));

Expand Down
8 changes: 8 additions & 0 deletions cpp/pypowsybl-java/powsybl-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ typedef struct dynamic_simulation_parameters_struct {
double stop_time;
} dynamic_simulation_parameters;

typedef struct dynamic_security_analysis_parameters_struct {
struct provider_parameters_struct provider_parameters;
double start_time;
double stop_time;
double contingencies_start_time;
char* debug_dir;
} dynamic_security_analysis_parameters;

typedef struct limit_violation_struct {
char* subject_id;
char* subject_name;
Expand Down
16 changes: 16 additions & 0 deletions docs/reference/dynamic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,22 @@ Simulation
Simulation
Simulation.run

DynamicSecurityAnalysis
-----------------------
.. autosummary::
:toctree: api/

DynamicSecurityAnalysisParameters
DynamicSecurityAnalysis
DynamicSecurityAnalysis.run
DynamicSecurityAnalysis.add_single_element_contingency
DynamicSecurityAnalysis.add_multiple_elements_contingency
DynamicSecurityAnalysis.add_single_element_contingencies
DynamicSecurityAnalysis.add_contingencies_from_json_file
DynamicSecurityAnalysis.add_monitored_elements
DynamicSecurityAnalysis.add_precontingency_monitored_elements
DynamicSecurityAnalysis.add_postcontingency_monitored_elements

Results
-------
.. autosummary::
Expand Down
43 changes: 43 additions & 0 deletions integration_tests/test_dynawo.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,46 @@ def test_provider_parameters_list():
assert 'Simulation step precision' == parameters['description']['precision']
assert 'DOUBLE' == parameters['type']['precision']
assert '1.0E-6' == parameters['default']['precision']

def test_security_analysis():
"""
Running that test requires to have installed dynawo,
and configured its path in your config.yml.
"""
network = pp.network.create_ieee14()
report_node = rp.ReportNode()

model_mapping = dyn.ModelMapping()
generator_mapping_df = pd.DataFrame(
index=pd.Series(name='static_id', data=['B6-G', 'B8-G']),
data={
'parameter_set_id': ['GSTWPR_6', 'GSTWPR_8'],
'model_name': 'GeneratorSynchronousThreeWindingsProportionalRegulations'
}
)
model_mapping.add_synchronous_generator(generator_mapping_df)

event_mapping = dyn.EventMapping()
event_mapping.add_disconnection(static_id='L1-2-1', start_time=5, disconnect_only='TWO')

testPath = Path(__file__).parent
dynawo_param = {
'parametersFile': str(testPath.joinpath('models.par')),
'network.parametersFile': str(testPath.joinpath('network.par')),
'network.parametersId': 'Network',
'solver.parametersFile': str(testPath.joinpath('solvers.par')),
'solver.parametersId': 'IDA',
'solver.type': 'IDA',
}
param = dyn.DynamicSecurityAnalysisParameters(start_time=0, stop_time=100,
contingencies_start_time=10,
provider_parameters=dynawo_param)

dsa = dyn.DynamicSecurityAnalysis()
dsa.add_single_element_contingency(element_id='L4-5-1', contingency_id='contingency1')
dsa.add_monitored_elements(branch_ids=['L1-5-1'])
res = dsa.run(network, model_mapping, event_mapping, param, report_node=report_node)

assert report_node
assert res.pre_contingency_result is not None
assert 'contingency1' in res.post_contingency_results
15 changes: 15 additions & 0 deletions java/pypowsybl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,21 @@
<groupId>com.powsybl</groupId>
<artifactId>powsybl-dynawo-simulation</artifactId>
</dependency>
<dependency>
<groupId>com.powsybl</groupId>
<artifactId>powsybl-dynawo-security-analysis</artifactId>
<!-- pypowsybl provides contingencies and dynamic models as dataframes/JSON, not through the Groovy DSL -->
<exclusions>
<exclusion>
<groupId>com.powsybl</groupId>
<artifactId>powsybl-contingency-dsl</artifactId>
</exclusion>
<exclusion>
<groupId>com.powsybl</groupId>
<artifactId>powsybl-dynamic-simulation-dsl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.powsybl</groupId>
<artifactId>powsybl-dynawo-extensions-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,37 @@ public interface DynamicSimulationParametersPointer extends PointerBase {
void setStopTime(double stopTime);
}

@CStruct("dynamic_security_analysis_parameters")
public interface DynamicSecurityAnalysisParametersPointer extends PointerBase {

@CFieldAddress("provider_parameters")
ProviderParameters getProviderParameters();

@CField("start_time")
double getStartTime();

@CField("start_time")
void setStartTime(double startTime);

@CField("stop_time")
double getStopTime();

@CField("stop_time")
void setStopTime(double stopTime);

@CField("contingencies_start_time")
double getContingenciesStartTime();

@CField("contingencies_start_time")
void setContingenciesStartTime(double contingenciesStartTime);

@CField("debug_dir")
CCharPointer getDebugDir();

@CField("debug_dir")
void setDebugDir(CCharPointer debugDir);
}

@CEnum("OutputVariableType")
public enum OutputVariableType {
CURVE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,8 @@
public static String getDefaultDynamicSimulationProvider() {
return DEFAULT_DYNAMIC_SIMULATION_PROVIDER;
}

public static String getDefaultDynamicSecurityAnalysisProvider() {

Check warning on line 72 in java/pypowsybl/src/main/java/com/powsybl/python/commons/PyPowsyblConfiguration.java

View check run for this annotation

SonarQubeCloud / [pypowsybl-parent] SonarCloud Code Analysis

Update this method so that its implementation is not identical to "getDefaultDynamicSimulationProvider" on line 68.

See more on https://sonarcloud.io/project/issues?id=powsybl_pypowsybl-java&issues=AZ9-xqqAeMxePgH0BTC8&open=AZ9-xqqAeMxePgH0BTC8&pullRequest=1263
return DEFAULT_DYNAMIC_SIMULATION_PROVIDER;
}
}
Loading
Loading