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

Support dangling line action in Operator Strategies #939

Open
wants to merge 3 commits into
base: main
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
8 changes: 8 additions & 0 deletions cpp/powsybl-cpp/powsybl-cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,14 @@ void addLoadReactivePowerAction(const JavaHandle& analysisContext, const std::st
PowsyblCaller::get()->callJava(::addLoadReactivePowerAction, analysisContext, (char*) actionId.data(), (char*) loadId.data(), relativeValue, reactivePower);
}

void addDanglingLineActivePowerAction(const JavaHandle& analysisContext, const std::string& actionId, const std::string& loadId, bool relativeValue, double activePower) {
PowsyblCaller::get()->callJava(::addDanglingLineActivePowerAction, analysisContext, (char*) actionId.data(), (char*) loadId.data(), relativeValue, activePower);
}

void addDanglingLineReactivePowerAction(const JavaHandle& analysisContext, const std::string& actionId, const std::string& loadId, bool relativeValue, double reactivePower) {
PowsyblCaller::get()->callJava(::addDanglingLineReactivePowerAction, analysisContext, (char*) actionId.data(), (char*) loadId.data(), relativeValue, reactivePower);
}

void addGeneratorActivePowerAction(const JavaHandle& analysisContext, const std::string& actionId, const std::string& generatorId, bool relativeValue, double activePower) {
PowsyblCaller::get()->callJava(::addGeneratorActivePowerAction, analysisContext, (char*) actionId.data(), (char*) generatorId.data(), relativeValue, activePower);
}
Expand Down
4 changes: 4 additions & 0 deletions cpp/powsybl-cpp/powsybl-cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,10 @@ void addLoadActivePowerAction(const JavaHandle& analysisContext, const std::stri

void addLoadReactivePowerAction(const JavaHandle& analysisContext, const std::string& actionId, const std::string& loadId, bool relativeValue, double reactivePower);

void addDanglingLineActivePowerAction(const JavaHandle& analysisContext, const std::string& actionId, const std::string& loadId, bool relativeValue, double activePower);

void addDanglingLineReactivePowerAction(const JavaHandle& analysisContext, const std::string& actionId, const std::string& loadId, bool relativeValue, double reactivePower);

void addGeneratorActivePowerAction(const JavaHandle& analysisContext, const std::string& actionId, const std::string& generatorId, bool relativeValue, double activePower);

void addSwitchAction(const JavaHandle& analysisContext, const std::string& actionId, const std::string& switchId, bool open);
Expand Down
6 changes: 6 additions & 0 deletions cpp/pypowsybl-cpp/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,12 @@ PYBIND11_MODULE(_pypowsybl, m) {
m.def("add_load_reactive_power_action", &pypowsybl::addLoadReactivePowerAction, "Add a load reactive power remedial action",
py::arg("analysis_context"), py::arg("action_id"), py::arg("load_id"), py::arg("is_relative"), py::arg("reactive_power"));

m.def("add_dangling_line_active_power_action", &pypowsybl::addDanglingLineActivePowerAction, "Add a dangling line active power remedial action",
py::arg("analysis_context"), py::arg("action_id"), py::arg("dangling_line_id"), py::arg("is_relative"), py::arg("active_power"));

m.def("add_dangling_line_reactive_power_action", &pypowsybl::addDanglingLineReactivePowerAction, "Add a dangling line reactive power remedial action",
py::arg("analysis_context"), py::arg("action_id"), py::arg("dangling_line_id"), py::arg("is_relative"), py::arg("reactive_power"));

m.def("add_generator_active_power_action", &pypowsybl::addGeneratorActivePowerAction, "Add a generator active power remedial action",
py::arg("analysis_context"), py::arg("action_id"), py::arg("generator_id"), py::arg("is_relative"), py::arg("active_power"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,42 @@ public static void addLoadReactivePowerAction(IsolateThread thread, ObjectHandle
});
}

@CEntryPoint(name = "addDanglingLineActivePowerAction")
public static void addDanglingLineActivePowerAction(IsolateThread thread, ObjectHandle securityAnalysisContextHandle,
CCharPointer actionId, CCharPointer danglingLineId, boolean relativeValue,
double activePowerValue,
PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) {
doCatch(exceptionHandlerPtr, () -> {
SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle);
String actionIdStr = CTypeUtil.toString(actionId);
String danglingLineIdStr = CTypeUtil.toString(danglingLineId);
LoadAction action = new LoadActionBuilder().withId(actionIdStr)
.withLoadId(danglingLineIdStr)
.withRelativeValue(relativeValue)
.withActivePowerValue(activePowerValue)
.build();
analysisContext.addAction(action);
});
}

@CEntryPoint(name = "addDanglingLineReactivePowerAction")
public static void addDanglingLineReactivePowerAction(IsolateThread thread, ObjectHandle securityAnalysisContextHandle,
CCharPointer actionId, CCharPointer danglingLineId, boolean relativeValue,
double reactivePowerValue,
PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) {
doCatch(exceptionHandlerPtr, () -> {
SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle);
String actionIdStr = CTypeUtil.toString(actionId);
String danglingLineIdStr = CTypeUtil.toString(danglingLineId);
LoadAction action = new LoadActionBuilder().withId(actionIdStr)
.withLoadId(danglingLineIdStr)
.withRelativeValue(relativeValue)
.withReactivePowerValue(reactivePowerValue)
.build();
analysisContext.addAction(action);
});
}

@CEntryPoint(name = "addGeneratorActivePowerAction")
public static void addGeneratorActivePowerAction(IsolateThread thread, ObjectHandle securityAnalysisContextHandle,
CCharPointer actionId, CCharPointer generatorId, boolean relativeValue, double activePower,
Expand Down
2 changes: 2 additions & 0 deletions pypowsybl/_pypowsybl.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,8 @@ def add_contingency(analysis_context: JavaHandle, contingency_id: str, elements_
def add_monitored_elements(security_analysis_context: JavaHandle, contingency_context_type: ContingencyContextType, branch_ids: List[str], voltage_level_ids: List[str], three_windings_transformer_ids: List[str], contingency_ids: List[str]) -> None: ...
def add_load_active_power_action(security_analysis_context: JavaHandle, action_id: str, load_id: str, is_relative: bool, active_power: float) -> None: ...
def add_load_reactive_power_action(security_analysis_context: JavaHandle, action_id: str, load_id: str, is_relative: bool, reactive_power: float) -> None: ...
def add_dangling_line_active_power_action(security_analysis_context: JavaHandle, action_id: str, dangling_line_id: str, is_relative: bool, active_power: float) -> None : ...
def add_dangling_line_reactive_power_action(security_analysis_context: JavaHandle, action_id: str, dangling_line_id: str, is_relative: bool, reactive_power: float) -> None: ...
def add_generator_active_power_action(security_analysis_context: JavaHandle, action_id: str, generator_id: str, is_relative: bool, active_power: float) -> None: ...
def add_switch_action(security_analysis_context: JavaHandle, action_id: str, switch_id: str, open: bool) -> None: ...
def add_phase_tap_changer_position_action(security_analysis_context: JavaHandle, action_id: str, transformer_id: str, is_relative: bool, tap_position: int, side: Side) -> None: ...
Expand Down
27 changes: 27 additions & 0 deletions pypowsybl/security/impl/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,32 @@ def add_load_reactive_power_action(self, action_id: str, load_id: str, is_relati
"""
_pypowsybl.add_load_reactive_power_action(self._handle, action_id, load_id, is_relative, reactive_power)

def add_dangling_line_active_power_action(self, action_id: str, dangling_line_id: str, is_relative: bool,
active_power: float) -> None:
""" Add a dangling line action, modifying the dangling line active power

Args:
action_id: unique ID for the action
dangling_line_id: dangling line identifier
is_relative: whether the active power change specified is absolute, or relative to current dangling line active power
active_power: the active power change

"""
_pypowsybl.add_dangling_line_active_power_action(self._handle, action_id, dangling_line_id, is_relative, active_power)

def add_dangling_line_reactive_power_action(self, action_id: str, dangling_line_id: str, is_relative: bool,
reactive_power: float) -> None:
""" Add a dangling line action, modifying the dangling line reactive power

Args:
action_id: unique ID for the action
dangling_line_id: dangling line identifier
is_relative: whether the reactive power change specified is absolute, or relative to current dangling line reactive power
reactive_power: the reactive power change

"""
_pypowsybl.add_dangling_line_reactive_power_action(self._handle, action_id, dangling_line_id, is_relative, reactive_power)

def add_generator_active_power_action(self, action_id: str, generator_id: str, is_relative: bool, active_power: float) -> None:
""" Add a generator action, modifying the generator active power

Expand Down Expand Up @@ -246,3 +272,4 @@ def add_operator_strategy(self, operator_strategy_id: str, contingency_id: str,
if violation_subject_ids is None:
violation_subject_ids = []
_pypowsybl.add_operator_strategy(self._handle, operator_strategy_id, contingency_id, action_ids, condition_type, violation_subject_ids, violation_types)

8 changes: 8 additions & 0 deletions tests/test_security_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,14 @@ def test_load_action_with_all_violation_condition():
assert len(sa_result.find_operator_strategy_results('OperatorStrategy1').limit_violations) == 3
assert 'OperatorStrategy2' not in sa_result.operator_strategy_results.keys()

def test_dangling_action():
n = pp.network.create_eurostag_tutorial_example1_with_tie_lines_and_areas()
sa = pp.security.create_analysis()

sa.add_dangling_line_active_power_action('id', 'NHV1_XNODE1', False, 5.0 )
sa.add_dangling_line_reactive_power_action('id', 'NHV1_XNODE1', True, 2.0 )


def test_generator_action():
n = pp.network.create_eurostag_tutorial_example1_network()
sa = pp.security.create_analysis()
Expand Down
Loading