From 248d9273f28a763599f5593a05ff50ca48820842 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Fri, 27 Oct 2023 12:12:10 +0200 Subject: [PATCH 01/45] GraalVM JDK 21 Signed-off-by: Geoffroy Jamgotchian --- .github/workflows/dev-ci.yml | 4 ++-- .github/workflows/full-ci.yml | 4 ++-- cpp/CMakeLists.txt | 2 +- java/pom.xml | 10 ++-------- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/.github/workflows/dev-ci.yml b/.github/workflows/dev-ci.yml index 2566eb762..0aa9ac606 100644 --- a/.github/workflows/dev-ci.yml +++ b/.github/workflows/dev-ci.yml @@ -28,7 +28,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '17' + java-version: '21' distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -109,7 +109,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '17' + java-version: '21' distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/full-ci.yml b/.github/workflows/full-ci.yml index ccd701577..e24f6c5e3 100644 --- a/.github/workflows/full-ci.yml +++ b/.github/workflows/full-ci.yml @@ -48,7 +48,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '17' + java-version: '21' distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -155,7 +155,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '17' + java-version: '21' distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 948448fce..5361bf65a 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -76,7 +76,7 @@ ExternalProject_Add(native-image DEPENDS mvn SOURCE_DIR ${PYPOWSYBL_JAVA_BIN_DIR} DOWNLOAD_COMMAND "" - PATCH_COMMAND $ENV{JAVA_HOME}/bin/native-image ${NATIVE_IMAGE_BUILD_OPTIONS} --class-path ${PYPOWSYBL_JAVA_SRC_DIR}/target/pypowsybl-java.jar${EXTRA_JARS} -march=compatibility --no-fallback --shared --gc=${NATIVE_IMAGE_GC} -H:Name=pypowsybl-java -H:CLibraryPath=${CMAKE_CURRENT_SOURCE_DIR}/src + PATCH_COMMAND $ENV{JAVA_HOME}/bin/native-image ${NATIVE_IMAGE_BUILD_OPTIONS} --class-path ${PYPOWSYBL_JAVA_SRC_DIR}/target/pypowsybl-java.jar${EXTRA_JARS} --pgo-instrument -H:+ProfilingEnableProfileDumpHooks -march=compatibility --no-fallback --shared --gc=${NATIVE_IMAGE_GC} -H:Name=pypowsybl-java -H:CLibraryPath=${CMAKE_CURRENT_SOURCE_DIR}/src CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_OLD_LIB} ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_LIB} ${NATIVE_IMAGE_INSTALL_EXTRA_COMMAND} diff --git a/java/pom.xml b/java/pom.xml index b36647194..0fd0c479d 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -61,9 +61,9 @@ 1.1.0-SNAPSHOT - 17 + 21 4.4 - 23.0.0 + 23.1.1 3.1.0 5.5.2 3.0.8 @@ -186,12 +186,6 @@ janino ${janino.version} - - org.graalvm.sdk - graal-sdk - ${graalvm.version} - provided - org.graalvm.nativeimage svm From 9fda9c177365b803714a714745b295859385bdc2 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Fri, 27 Oct 2023 12:18:33 +0200 Subject: [PATCH 02/45] Wip Signed-off-by: Geoffroy Jamgotchian --- cpp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 5361bf65a..948448fce 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -76,7 +76,7 @@ ExternalProject_Add(native-image DEPENDS mvn SOURCE_DIR ${PYPOWSYBL_JAVA_BIN_DIR} DOWNLOAD_COMMAND "" - PATCH_COMMAND $ENV{JAVA_HOME}/bin/native-image ${NATIVE_IMAGE_BUILD_OPTIONS} --class-path ${PYPOWSYBL_JAVA_SRC_DIR}/target/pypowsybl-java.jar${EXTRA_JARS} --pgo-instrument -H:+ProfilingEnableProfileDumpHooks -march=compatibility --no-fallback --shared --gc=${NATIVE_IMAGE_GC} -H:Name=pypowsybl-java -H:CLibraryPath=${CMAKE_CURRENT_SOURCE_DIR}/src + PATCH_COMMAND $ENV{JAVA_HOME}/bin/native-image ${NATIVE_IMAGE_BUILD_OPTIONS} --class-path ${PYPOWSYBL_JAVA_SRC_DIR}/target/pypowsybl-java.jar${EXTRA_JARS} -march=compatibility --no-fallback --shared --gc=${NATIVE_IMAGE_GC} -H:Name=pypowsybl-java -H:CLibraryPath=${CMAKE_CURRENT_SOURCE_DIR}/src CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_OLD_LIB} ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_LIB} ${NATIVE_IMAGE_INSTALL_EXTRA_COMMAND} From 0adb2ca86036beb363b1b8e47b7d2e46b5ec4bf0 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Fri, 27 Oct 2023 12:19:16 +0200 Subject: [PATCH 03/45] Wip Signed-off-by: Geoffroy Jamgotchian --- java/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/java/pom.xml b/java/pom.xml index 0fd0c479d..bda60c8c2 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -186,6 +186,12 @@ janino ${janino.version} + + org.graalvm.sdk + graal-sdk + ${graalvm.version} + provided + org.graalvm.nativeimage svm From 139e2dee249509b45af77e8000149e6eb636709c Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Fri, 27 Oct 2023 13:34:50 +0200 Subject: [PATCH 04/45] Wip Signed-off-by: Geoffroy Jamgotchian --- java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/pom.xml b/java/pom.xml index bda60c8c2..9299a2e83 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -188,7 +188,7 @@ org.graalvm.sdk - graal-sdk + nativeimage ${graalvm.version} provided From 65bba7f8072fb6b706b82158f646fe9439a52e71 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 1 Nov 2023 14:24:01 +0100 Subject: [PATCH 05/45] Wip Signed-off-by: Geoffroy Jamgotchian --- cpp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 948448fce..189b15c28 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -76,7 +76,7 @@ ExternalProject_Add(native-image DEPENDS mvn SOURCE_DIR ${PYPOWSYBL_JAVA_BIN_DIR} DOWNLOAD_COMMAND "" - PATCH_COMMAND $ENV{JAVA_HOME}/bin/native-image ${NATIVE_IMAGE_BUILD_OPTIONS} --class-path ${PYPOWSYBL_JAVA_SRC_DIR}/target/pypowsybl-java.jar${EXTRA_JARS} -march=compatibility --no-fallback --shared --gc=${NATIVE_IMAGE_GC} -H:Name=pypowsybl-java -H:CLibraryPath=${CMAKE_CURRENT_SOURCE_DIR}/src + PATCH_COMMAND $ENV{JAVA_HOME}/bin/native-image ${NATIVE_IMAGE_BUILD_OPTIONS} --class-path ${PYPOWSYBL_JAVA_SRC_DIR}/target/pypowsybl-java.jar${EXTRA_JARS} -march=compatibility --no-fallback --shared --gc=${NATIVE_IMAGE_GC} -o pypowsybl-java -H:CLibraryPath=${CMAKE_CURRENT_SOURCE_DIR}/src CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_OLD_LIB} ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_LIB} ${NATIVE_IMAGE_INSTALL_EXTRA_COMMAND} From 970136d7ae310e5a7f9d7f45d682f85950e6fe86 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 1 Nov 2023 14:25:11 +0100 Subject: [PATCH 06/45] Wip Signed-off-by: Geoffroy Jamgotchian --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ec449f0e..9c6110f2f 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ Requirements: - C++11 compiler - Python >= 3.7 for Linux, Windows and MacOS amd64 - Python >= 3.8 for MacOS arm64 -- [Oracle GraalVM Java 17](https://www.graalvm.org/downloads/) +- [Oracle GraalVM Java 21](https://www.graalvm.org/downloads/) To build from sources and install PyPowSyBl package: From 6f80e05d7d9275164de6cf5ba8db26dc71b3745c Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Thu, 2 Nov 2023 21:11:52 +0100 Subject: [PATCH 07/45] Wip Signed-off-by: Geoffroy Jamgotchian --- java/pom.xml | 6 ------ .../src/main/java/com/powsybl/python/commons/CTypeUtil.java | 4 +--- .../main/java/com/powsybl/python/commons/Directives.java | 4 +--- setup.py | 1 - 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/java/pom.xml b/java/pom.xml index 9299a2e83..04d814991 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -192,12 +192,6 @@ ${graalvm.version} provided - - org.graalvm.nativeimage - svm - ${graalvm.version} - provided - - - com.powsybl - powsybl-math-native - ${powsybl-math-native.version} - diff --git a/tests/test_loadflow.py b/tests/test_loadflow.py index c37d04347..7d458c412 100644 --- a/tests/test_loadflow.py +++ b/tests/test_loadflow.py @@ -270,11 +270,12 @@ def test_get_provider_parameters_names(): 'newtonKrylovLineSearch', 'referenceBusSelectionMode', 'writeReferenceTerminals', - 'voltageTargetPriorities'] + 'voltageTargetPriorities', + 'generatorVoltageControlMinNominalVoltage'] def test_get_provider_parameters(): specific_parameters = pp.loadflow.get_provider_parameters('OpenLoadFlow') - assert 65 == len(specific_parameters) + assert 66 == len(specific_parameters) assert 'Slack bus selection mode' == specific_parameters['description']['slackBusSelectionMode'] assert 'STRING' == specific_parameters['type']['slackBusSelectionMode'] assert 'MOST_MESHED' == specific_parameters['default']['slackBusSelectionMode'] From 6f652f981f87a3bde980f214c9c2fd1a916eb997 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 26 Jun 2024 12:58:18 +0200 Subject: [PATCH 17/45] Clean doc setup (#784) Signed-off-by: Geoffroy Jamgotchian --- docs/conf.py | 18 +++++++++++++----- docs/user_guide/dynamic.rst | 6 ------ docs/user_guide/flowdecomposition.rst | 14 -------------- docs/user_guide/loadflow.rst | 4 ---- docs/user_guide/network.rst | 7 ------- docs/user_guide/per_unit.rst | 7 ------- docs/user_guide/security.rst | 11 +---------- docs/user_guide/voltage_initializer.rst | 6 ------ pypowsybl/security/__init__.py | 2 +- 9 files changed, 15 insertions(+), 60 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index ff0ba9725..55b83f06a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -89,11 +89,19 @@ html_css_files = ['styles/styles.css'] doctest_global_setup = ''' -try: - import pypowsybl as pp - pp.set_config_read(False) -except ImportError: - pp = None +import pypowsybl as pp +pp.set_config_read(False) + +import pathlib + +import pandas as pd +pd.options.display.max_columns = None +pd.options.display.expand_frame_repr = False + +import os +cwd = os.getcwd() +PROJECT_DIR = pathlib.Path(cwd).parent +DATA_DIR = PROJECT_DIR.joinpath('data') ''' on_rtd = os.environ.get('READTHEDOCS') == 'True' diff --git a/docs/user_guide/dynamic.rst b/docs/user_guide/dynamic.rst index 416fea755..f445276e4 100644 --- a/docs/user_guide/dynamic.rst +++ b/docs/user_guide/dynamic.rst @@ -3,12 +3,6 @@ Running a dynamic simulation with dynawaltz .. currentmodule:: pypowsybl.dynamic -.. testsetup:: * - - import pypowsybl as pp - import pypowsybl.dynamic as dyn - import pypowsybl.network as pn - You can use the module :mod:`pypowsybl.dynamic` in order to run time domain simulation on networks. Start by importing the module: diff --git a/docs/user_guide/flowdecomposition.rst b/docs/user_guide/flowdecomposition.rst index fedb7cf38..c15390360 100644 --- a/docs/user_guide/flowdecomposition.rst +++ b/docs/user_guide/flowdecomposition.rst @@ -1,20 +1,6 @@ Running a flow decomposition ============================ -.. testsetup:: * - - import pathlib - import pandas as pd - - import pypowsybl as pp - - pd.options.display.max_columns = None - pd.options.display.expand_frame_repr = False - import os - cwd = os.getcwd() - PROJECT_DIR = pathlib.Path(cwd).parent - DATA_DIR = PROJECT_DIR.joinpath('data') - You can use the module :mod:`pypowsybl.flowdecomposition` in order to run flow decomposition on networks. Please check out the examples below. diff --git a/docs/user_guide/loadflow.rst b/docs/user_guide/loadflow.rst index 0f9297316..abe722b8d 100644 --- a/docs/user_guide/loadflow.rst +++ b/docs/user_guide/loadflow.rst @@ -5,12 +5,8 @@ Running a load flow .. testsetup:: * - import pypowsybl as pp import pypowsybl.loadflow as lf import pypowsybl.network as pn - import pandas as pd - pd.options.display.max_columns = None - pd.options.display.expand_frame_repr = False You can use the module :mod:`pypowsybl.loadflow` in order to run load flows on networks. diff --git a/docs/user_guide/network.rst b/docs/user_guide/network.rst index d14ab7a1e..ab709cbdd 100644 --- a/docs/user_guide/network.rst +++ b/docs/user_guide/network.rst @@ -3,13 +3,6 @@ The network model .. currentmodule:: pypowsybl.network -.. testsetup:: * - - import pandas as pd - pd.set_option('display.max_columns', None) - pd.set_option('display.expand_frame_repr', False) - - The :class:`Network` object is the main data structure of pypowsybl. It contains all the data of a power network: substations, generators, lines, transformers, ... diff --git a/docs/user_guide/per_unit.rst b/docs/user_guide/per_unit.rst index 762d35343..b9a7d6e06 100644 --- a/docs/user_guide/per_unit.rst +++ b/docs/user_guide/per_unit.rst @@ -1,13 +1,6 @@ Per Unit data ------------- -.. testsetup:: * - - import pypowsybl as pp - import pandas as pd - pd.options.display.max_columns = None - pd.options.display.expand_frame_repr = False - PyPowSyBl provides methods to per unit the scientific data. They are part of the network api. To per-unit the data, the attribute per_unit of the network has to be set. diff --git a/docs/user_guide/security.rst b/docs/user_guide/security.rst index b2af80c09..95094519b 100644 --- a/docs/user_guide/security.rst +++ b/docs/user_guide/security.rst @@ -1,14 +1,6 @@ Running a security analysis =========================== -.. testsetup:: * - - import pypowsybl as pp - import pandas as pd - pd.options.display.max_columns = None - pd.options.display.expand_frame_repr = False - from pypowsybl._pypowsybl import ConditionType - You can use the module :mod:`pypowsybl.security` in order to perform a security analysis on a network. Please check out the examples below. @@ -55,7 +47,6 @@ Information can be obtained on buses, branches and three windings transformers. .. testsetup:: security.monitored_elements - import pandas as pd pd.options.display.float_format = '{:,.2f}'.format .. doctest:: security.monitored_elements @@ -131,7 +122,7 @@ The following operator strategy define the application of the switch action 'Swi >>> sa = pp.security.create_analysis() >>> sa.add_single_element_contingency(element_id='S4VL1_BBS_LD6_DISCONNECTOR', contingency_id='Breaker contingency') >>> sa.add_switch_action(action_id='SwitchAction', switch_id='S4VL1_BBS_LD6_DISCONNECTOR', open=False) - >>> sa.add_operator_strategy(operator_strategy_id='OperatorStrategy1', contingency_id='Breaker contingency', action_ids=['SwitchAction'], condition_type=ConditionType.TRUE_CONDITION) + >>> sa.add_operator_strategy(operator_strategy_id='OperatorStrategy1', contingency_id='Breaker contingency', action_ids=['SwitchAction'], condition_type=pp.security.ConditionType.TRUE_CONDITION) >>> sa.add_monitored_elements(branch_ids=['LINE_S3S4']) >>> sa_result = sa.run_ac(n) >>> df = sa_result.branch_results diff --git a/docs/user_guide/voltage_initializer.rst b/docs/user_guide/voltage_initializer.rst index 6dc82aeff..be1ae654b 100644 --- a/docs/user_guide/voltage_initializer.rst +++ b/docs/user_guide/voltage_initializer.rst @@ -3,12 +3,6 @@ Run the voltage initializer .. currentmodule:: pypowsybl.voltage_initializer -.. testsetup:: * - - import pypowsybl as pp - import pypowsybl.voltage_initializer as v_init - - Prerequisites ------------- diff --git a/pypowsybl/security/__init__.py b/pypowsybl/security/__init__.py index 3700422f2..31c0bf960 100644 --- a/pypowsybl/security/__init__.py +++ b/pypowsybl/security/__init__.py @@ -8,7 +8,7 @@ from .impl.increased_violations_parameters import IncreasedViolationsParameters from .impl.parameters import Parameters from .impl.security_analysis_result import SecurityAnalysisResult -from .impl.security import SecurityAnalysis, ComputationStatus, ContingencyContextType +from .impl.security import SecurityAnalysis, ComputationStatus, ContingencyContextType, ConditionType from .impl.util import ( create_analysis, set_default_provider, From ca23cfd10e704c3f3dca18543ed4cb45030d068c Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 26 Jun 2024 15:37:49 +0200 Subject: [PATCH 18/45] CI should fail in case of doc generation warnings (#787) Signed-off-by: Geoffroy Jamgotchian --- .github/workflows/dev-ci.yml | 4 ++-- .github/workflows/full-ci.yml | 4 ++-- docs/conf.py | 8 -------- docs/user_guide/network_visualization.rst | 23 ++++++++++++++++------- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/.github/workflows/dev-ci.yml b/.github/workflows/dev-ci.yml index 86a62d60a..549afc478 100644 --- a/.github/workflows/dev-ci.yml +++ b/.github/workflows/dev-ci.yml @@ -93,7 +93,7 @@ jobs: - name: Run doc examples working-directory: ./docs - run: make doctest + run: make html doctest SPHINXOPTS="-W" macos_windows_build: name: Build ${{ matrix.config.name }} ${{ matrix.python.name }} wheel @@ -160,4 +160,4 @@ jobs: - name: Run doc examples working-directory: ./docs - run: make doctest + run: make html doctest SPHINXOPTS="-W" diff --git a/.github/workflows/full-ci.yml b/.github/workflows/full-ci.yml index 92053d0ef..6bcef29bf 100644 --- a/.github/workflows/full-ci.yml +++ b/.github/workflows/full-ci.yml @@ -117,7 +117,7 @@ jobs: - name: Run doc examples working-directory: ./docs - run: make doctest + run: make html doctest SPHINXOPTS="-W" - name: Upload wheel uses: actions/upload-artifact@v3 @@ -206,7 +206,7 @@ jobs: - name: Run doc examples working-directory: ./docs - run: make doctest + run: make html doctest SPHINXOPTS="-W" - name: Upload wheel uses: actions/upload-artifact@v3 diff --git a/docs/conf.py b/docs/conf.py index 55b83f06a..2b1a721cb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -68,14 +68,6 @@ html_favicon = "_static/favicon.ico" html_theme_options = { - "icon_links": [ - { - "name": "GitHub", - "url": "https://github.com/powsybl/pypowsybl", - "icon": "fab fa-github-square", - } - ], - "navbar_start": ["navbar-brand-pypowsybl"], # the following 3 lines enable edit button "source_repository": "https://github.com/powsybl/pypowsybl/", "source_branch": "main", diff --git a/docs/user_guide/network_visualization.rst b/docs/user_guide/network_visualization.rst index fa8f15b5f..18f12b40b 100644 --- a/docs/user_guide/network_visualization.rst +++ b/docs/user_guide/network_visualization.rst @@ -36,17 +36,18 @@ Single-line diagrams can be customized through SldParameters: >>> result = pp.loadflow.run_ac(network) >>> network.get_single_line_diagram('VL4',parameters = pp.network.SldParameters(use_name = False, center_name = False, diagonal_label = False, nodes_infos = False, tooltip_enabled = False, topological_coloring = True, component_library = 'Convergence')) - - use_name: if true, display components names instead of their id (default value false) - - center_name: if true, center the names of feeders (default value false) - - diagonal_label: if true, display labels diagonally (default value false) - - nodes_infos: if true, display nodes infos (caption on bottom left) (default value false) - - tooltip_enabled: if true, display the name of the component pointed by the cursor (default value false) - - topological_coloring: if true, set each electrical nodes with a different colour (default value true) - - component_library: choose component library (default value 'Convergence') +- use_name: if true, display components names instead of their id (default value false) +- center_name: if true, center the names of feeders (default value false) +- diagonal_label: if true, display labels diagonally (default value false) +- nodes_infos: if true, display nodes infos (caption on bottom left) (default value false) +- tooltip_enabled: if true, display the name of the component pointed by the cursor (default value false) +- topological_coloring: if true, set each electrical nodes with a different colour (default value true) +- component_library: choose component library (default value 'Convergence') Let's see some examples down below: - with default parameters + .. code-block:: python >>> import pypowsybl.network as pn @@ -57,6 +58,7 @@ Let's see some examples down below: :class: forced-white-background - with use_name = true + .. code-block:: python >>> param = pn.SldParameters(use_name = True) @@ -66,6 +68,7 @@ Let's see some examples down below: :class: forced-white-background - with center_name = true + .. code-block:: python >>> param = pn.SldParameters(center_name = True) @@ -75,6 +78,7 @@ Let's see some examples down below: :class: forced-white-background - with diagonal_label = true + .. code-block:: python >>> param = pn.SldParameters(diagonal_label = True) @@ -84,6 +88,7 @@ Let's see some examples down below: :class: forced-white-background - with nodes_infos = true + .. code-block:: python >>> param = pn.SldParameters(nodes_infos = True) @@ -93,6 +98,7 @@ Let's see some examples down below: :class: forced-white-background - with tooltip enabled + .. code-block:: python >>> param = pn.SldParameters(tooltip_enabled = True) @@ -102,6 +108,7 @@ Let's see some examples down below: :class: forced-white-background - with topological coloring = true + .. code-block:: python >>> network = pn.create_four_substations_node_breaker_network() @@ -113,6 +120,7 @@ Let's see some examples down below: :class: forced-white-background - with topological coloring = false + .. code-block:: python >>> param = pn.SldParameters(topological_coloring = False) @@ -122,6 +130,7 @@ Let's see some examples down below: :class: forced-white-background - with component_library = "FlatDesign" + .. code-block:: python >>> network = pn.create_ieee14() From 260fc9550d2201baadb609bd40f239cb4029e10f Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 26 Jun 2024 17:25:39 +0200 Subject: [PATCH 19/45] Remove debug prints (#788) Signed-off-by: Geoffroy Jamgotchian --- pypowsybl/sensitivity/impl/util.py | 3 --- tests/test_sensitivity_analysis.py | 3 --- 2 files changed, 6 deletions(-) diff --git a/pypowsybl/sensitivity/impl/util.py b/pypowsybl/sensitivity/impl/util.py index d3604e628..be9baa3f6 100644 --- a/pypowsybl/sensitivity/impl/util.py +++ b/pypowsybl/sensitivity/impl/util.py @@ -32,9 +32,6 @@ def create_country_zone(network: Network, country: str, key_type: ZoneKeyType = ZoneKeyType.GENERATOR_TARGET_P) -> Zone: substations = network.get_substations() voltage_levels = network.get_voltage_levels() - print(key_type.__class__) - print(ZoneKeyType.GENERATOR_MAX_P.__class__) - print(key_type == ZoneKeyType.GENERATOR_TARGET_P) if key_type in (ZoneKeyType.GENERATOR_MAX_P, ZoneKeyType.GENERATOR_TARGET_P): # join generators, voltage levels and substations to get generators with countries generators = network.get_generators() diff --git a/tests/test_sensitivity_analysis.py b/tests/test_sensitivity_analysis.py index bcd816ee5..92692ec74 100644 --- a/tests/test_sensitivity_analysis.py +++ b/tests/test_sensitivity_analysis.py @@ -337,9 +337,6 @@ def test_add_branch_factor_matrix(): def test_busbar_section_sensi(): network = pp.network.create_four_substations_node_breaker_network() analysis = pp.sensitivity.create_ac_analysis() - print(network.get_busbar_sections()) - print(network.get_lines()) - print(network.get_generators()) analysis.add_factor_matrix(['LINE_S2S3'], ['S2VL1_BBS'], [], ContingencyContextType.NONE, SensitivityFunctionType.BRANCH_ACTIVE_POWER_2, SensitivityVariableType.INJECTION_ACTIVE_POWER, 'm1') result = analysis.run(network) From 3901818e95b92649c9325043b45d94c1423a5867 Mon Sep 17 00:00:00 2001 From: jeandemanged Date: Mon, 1 Jul 2024 10:46:46 +0200 Subject: [PATCH 20/45] Add support of dc_power_factor Load Flow Parameter (#756) Signed-off-by: Damien Jeandemange --- cpp/powsybl-cpp/powsybl-api.h | 1 + cpp/powsybl-cpp/powsybl-cpp.cpp | 3 +++ cpp/powsybl-cpp/powsybl-cpp.h | 1 + cpp/pypowsybl-cpp/bindings.cpp | 1 + docs/user_guide/loadflow.rst | 2 +- .../com/powsybl/python/commons/PyPowsyblApiHeader.java | 6 ++++++ .../com/powsybl/python/loadflow/LoadFlowCFunctions.java | 1 + .../java/com/powsybl/python/loadflow/LoadFlowCUtils.java | 3 ++- pypowsybl/_pypowsybl.pyi | 1 + pypowsybl/loadflow/impl/parameters.py | 7 +++++++ tests/test_loadflow.py | 3 ++- 11 files changed, 26 insertions(+), 3 deletions(-) diff --git a/cpp/powsybl-cpp/powsybl-api.h b/cpp/powsybl-cpp/powsybl-api.h index 178314a7c..1d2f6023d 100644 --- a/cpp/powsybl-cpp/powsybl-api.h +++ b/cpp/powsybl-cpp/powsybl-api.h @@ -62,6 +62,7 @@ typedef struct loadflow_parameters_struct { char** countries_to_balance; int countries_to_balance_count; int connected_component_mode; + double dc_power_factor; char** provider_parameters_keys; int provider_parameters_keys_count; char** provider_parameters_values; diff --git a/cpp/powsybl-cpp/powsybl-cpp.cpp b/cpp/powsybl-cpp/powsybl-cpp.cpp index f75f89df2..14508fe0b 100644 --- a/cpp/powsybl-cpp/powsybl-cpp.cpp +++ b/cpp/powsybl-cpp/powsybl-cpp.cpp @@ -240,6 +240,7 @@ LoadFlowParameters::LoadFlowParameters(loadflow_parameters* src) { balance_type = static_cast(src->balance_type); dc_use_transformer_ratio = (bool) src->dc_use_transformer_ratio; connected_component_mode = static_cast(src->connected_component_mode); + dc_power_factor = (double) src->dc_power_factor; copyCharPtrPtrToVector(src->countries_to_balance, src->countries_to_balance_count, countries_to_balance); copyCharPtrPtrToVector(src->provider_parameters_keys, src->provider_parameters_keys_count, provider_parameters_keys); copyCharPtrPtrToVector(src->provider_parameters_values, src->provider_parameters_values_count, provider_parameters_values); @@ -260,6 +261,7 @@ void LoadFlowParameters::load_to_c_struct(loadflow_parameters& res) const { res.connected_component_mode = connected_component_mode; res.countries_to_balance = pypowsybl::copyVectorStringToCharPtrPtr(countries_to_balance); res.countries_to_balance_count = countries_to_balance.size(); + res.dc_power_factor = dc_power_factor; res.provider_parameters_keys = pypowsybl::copyVectorStringToCharPtrPtr(provider_parameters_keys); res.provider_parameters_keys_count = provider_parameters_keys.size(); res.provider_parameters_values = pypowsybl::copyVectorStringToCharPtrPtr(provider_parameters_values); @@ -310,6 +312,7 @@ void LoadFlowValidationParameters::load_to_c_struct(loadflow_validation_paramete std::shared_ptr LoadFlowValidationParameters::to_c_struct() const { loadflow_validation_parameters* res = new loadflow_validation_parameters(); + loadflow_parameters.load_to_c_struct(res->loadflow_parameters); load_to_c_struct(*res); //Memory has been allocated here on C side, we need to clean it up on C side (not java side) return std::shared_ptr(res, [](loadflow_validation_parameters* ptr){ diff --git a/cpp/powsybl-cpp/powsybl-cpp.h b/cpp/powsybl-cpp/powsybl-cpp.h index fad3939ac..b20789d13 100644 --- a/cpp/powsybl-cpp/powsybl-cpp.h +++ b/cpp/powsybl-cpp/powsybl-cpp.h @@ -318,6 +318,7 @@ class LoadFlowParameters { bool dc_use_transformer_ratio; std::vector countries_to_balance; ConnectedComponentMode connected_component_mode; + double dc_power_factor; std::vector provider_parameters_keys; std::vector provider_parameters_values; }; diff --git a/cpp/pypowsybl-cpp/bindings.cpp b/cpp/pypowsybl-cpp/bindings.cpp index 9e77112cb..d5fd1db0a 100644 --- a/cpp/pypowsybl-cpp/bindings.cpp +++ b/cpp/pypowsybl-cpp/bindings.cpp @@ -498,6 +498,7 @@ PYBIND11_MODULE(_pypowsybl, m) { .def_readwrite("dc_use_transformer_ratio", &pypowsybl::LoadFlowParameters::dc_use_transformer_ratio) .def_readwrite("countries_to_balance", &pypowsybl::LoadFlowParameters::countries_to_balance) .def_readwrite("connected_component_mode", &pypowsybl::LoadFlowParameters::connected_component_mode) + .def_readwrite("dc_power_factor", &pypowsybl::LoadFlowParameters::dc_power_factor) .def_readwrite("provider_parameters_keys", &pypowsybl::LoadFlowParameters::provider_parameters_keys) .def_readwrite("provider_parameters_values", &pypowsybl::LoadFlowParameters::provider_parameters_values); diff --git a/docs/user_guide/loadflow.rst b/docs/user_guide/loadflow.rst index abe722b8d..efaa05b56 100644 --- a/docs/user_guide/loadflow.rst +++ b/docs/user_guide/loadflow.rst @@ -47,7 +47,7 @@ Let's have a look at the default ones: .. doctest:: >>> lf.Parameters() - Parameters(voltage_init_mode=UNIFORM_VALUES, transformer_voltage_control_on=False, use_reactive_limits=True, phase_shifter_regulation_on=False, twt_split_shunt_admittance=False, shunt_compensator_voltage_control_on=False, read_slack_bus=True, write_slack_bus=True, distributed_slack=True, balance_type=PROPORTIONAL_TO_GENERATION_P_MAX, dc_use_transformer_ratio=True, countries_to_balance=[], connected_component_mode=, provider_parameters={}) + Parameters(voltage_init_mode=UNIFORM_VALUES, transformer_voltage_control_on=False, use_reactive_limits=True, phase_shifter_regulation_on=False, twt_split_shunt_admittance=False, shunt_compensator_voltage_control_on=False, read_slack_bus=True, write_slack_bus=True, distributed_slack=True, balance_type=PROPORTIONAL_TO_GENERATION_P_MAX, dc_use_transformer_ratio=True, countries_to_balance=[], connected_component_mode=, dc_power_factor=1.0, provider_parameters={}) For more details on each parameter, please refer to the :doc:`API reference `. diff --git a/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java b/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java index c2f1b765a..f79c056ee 100644 --- a/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java +++ b/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java @@ -283,6 +283,12 @@ public interface LoadFlowParametersPointer extends PointerBase { @CField("connected_component_mode") void setConnectedComponentMode(int connectedComponentMode); + @CField("dc_power_factor") + double getDcPowerFactor(); + + @CField("dc_power_factor") + void setDcPowerFactor(double dcPowerFactor); + @CField("provider_parameters_keys") void setProviderParametersKeys(CCharPointerPointer providerParametersKeys); diff --git a/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCFunctions.java b/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCFunctions.java index 613d7efed..6e72b626a 100644 --- a/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCFunctions.java +++ b/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCFunctions.java @@ -174,6 +174,7 @@ public static void copyToCLoadFlowParameters(LoadFlowParameters parameters, Load cParameters.setCountriesToBalance(calloc); cParameters.setCountriesToBalanceCount(countries.size()); cParameters.setConnectedComponentMode(parameters.getConnectedComponentMode().ordinal()); + cParameters.setDcPowerFactor(parameters.getDcPowerFactor()); cParameters.setProviderParametersValuesCount(0); cParameters.setProviderParametersKeysCount(0); } diff --git a/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCUtils.java b/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCUtils.java index ecd2756ed..644906828 100644 --- a/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCUtils.java +++ b/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCUtils.java @@ -78,7 +78,8 @@ public static LoadFlowParameters convertLoadFlowParameters(boolean dc, .setDcUseTransformerRatio(loadFlowParametersPtr.isDcUseTransformerRatio()) .setCountriesToBalance(CTypeUtil.toStringList(loadFlowParametersPtr.getCountriesToBalance(), loadFlowParametersPtr.getCountriesToBalanceCount()) .stream().map(Country::valueOf).collect(Collectors.toSet())) - .setConnectedComponentMode(LoadFlowParameters.ConnectedComponentMode.values()[loadFlowParametersPtr.getConnectedComponentMode()]); + .setConnectedComponentMode(LoadFlowParameters.ConnectedComponentMode.values()[loadFlowParametersPtr.getConnectedComponentMode()]) + .setDcPowerFactor(loadFlowParametersPtr.getDcPowerFactor()); } /** diff --git a/pypowsybl/_pypowsybl.pyi b/pypowsybl/_pypowsybl.pyi index e58285565..2c3eb79b8 100644 --- a/pypowsybl/_pypowsybl.pyi +++ b/pypowsybl/_pypowsybl.pyi @@ -430,6 +430,7 @@ class LoadFlowParameters: twt_split_shunt_admittance: bool voltage_init_mode: VoltageInitMode write_slack_bus: bool + dc_power_factor: float provider_parameters_keys: List[str] provider_parameters_values: List[str] def __init__(self) -> None: ... diff --git a/pypowsybl/loadflow/impl/parameters.py b/pypowsybl/loadflow/impl/parameters.py index 33ae21e99..d34bf5cc8 100644 --- a/pypowsybl/loadflow/impl/parameters.py +++ b/pypowsybl/loadflow/impl/parameters.py @@ -63,6 +63,7 @@ class Parameters: # pylint: disable=too-few-public-methods connected_component_mode: Define which connected components should be computed. Use ``MAIN`` to computes flows only on the main connected component, or prefer ``ALL`` for a run on all connected component. + dc_power_factor: Power factor used to convert current limits into active power limits in DC calculations. provider_parameters: Define parameters linked to the loadflow provider the names of the existing parameters can be found with method ``get_provider_parameters_names`` """ @@ -80,6 +81,7 @@ def __init__(self, voltage_init_mode: VoltageInitMode = None, dc_use_transformer_ratio: bool = None, countries_to_balance: Sequence[str] = None, connected_component_mode: ConnectedComponentMode = None, + dc_power_factor: float = None, provider_parameters: Dict[str, str] = None): self._init_with_default_values() if voltage_init_mode is not None: @@ -108,6 +110,8 @@ def __init__(self, voltage_init_mode: VoltageInitMode = None, self.countries_to_balance = countries_to_balance if connected_component_mode is not None: self.connected_component_mode = connected_component_mode + if dc_power_factor is not None: + self.dc_power_factor = dc_power_factor if provider_parameters is not None: self.provider_parameters = provider_parameters @@ -125,6 +129,7 @@ def _init_from_c(self, c_parameters: LoadFlowParameters) -> None: self.dc_use_transformer_ratio = c_parameters.dc_use_transformer_ratio self.countries_to_balance = c_parameters.countries_to_balance self.connected_component_mode = c_parameters.connected_component_mode + self.dc_power_factor = c_parameters.dc_power_factor self.provider_parameters = dict( zip(c_parameters.provider_parameters_keys, c_parameters.provider_parameters_values)) @@ -146,6 +151,7 @@ def _to_c_parameters(self) -> LoadFlowParameters: c_parameters.dc_use_transformer_ratio = self.dc_use_transformer_ratio c_parameters.countries_to_balance = self.countries_to_balance c_parameters.connected_component_mode = self.connected_component_mode + c_parameters.dc_power_factor = self.dc_power_factor c_parameters.provider_parameters_keys = list(self.provider_parameters.keys()) c_parameters.provider_parameters_values = list(self.provider_parameters.values()) return c_parameters @@ -165,5 +171,6 @@ def __repr__(self) -> str: f", dc_use_transformer_ratio={self.dc_use_transformer_ratio!r}" \ f", countries_to_balance={self.countries_to_balance}" \ f", connected_component_mode={self.connected_component_mode!r}" \ + f", dc_power_factor={self.dc_power_factor!r}" \ f", provider_parameters={self.provider_parameters!r}" \ f")" diff --git a/tests/test_loadflow.py b/tests/test_loadflow.py index 7d458c412..23fa381de 100644 --- a/tests/test_loadflow.py +++ b/tests/test_loadflow.py @@ -92,7 +92,8 @@ def test_lf_parameters(): 'balance_type': [lf.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD, lf.BalanceType.PROPORTIONAL_TO_GENERATION_P], 'dc_use_transformer_ratio': [True, False], 'countries_to_balance': [['FR'], ['BE']], - 'connected_component_mode': [lf.ConnectedComponentMode.MAIN, lf.ConnectedComponentMode.ALL] + 'connected_component_mode': [lf.ConnectedComponentMode.MAIN, lf.ConnectedComponentMode.ALL], + 'dc_power_factor': [1.0, 0.95] } for attribute, values in attributes.items(): From 432b5974ef153309bfbcb16f201367f134bfa5da Mon Sep 17 00:00:00 2001 From: jeandemanged Date: Mon, 1 Jul 2024 16:07:11 +0200 Subject: [PATCH 21/45] Fix CI manylinux (#794) Signed-off-by: Damien Jeandemange --- .github/workflows/dev-ci.yml | 7 ++----- .github/workflows/full-ci.yml | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/workflows/dev-ci.yml b/.github/workflows/dev-ci.yml index 549afc478..be59b640c 100644 --- a/.github/workflows/dev-ci.yml +++ b/.github/workflows/dev-ci.yml @@ -11,7 +11,7 @@ jobs: manylinux_build: name: Build linux ${{ matrix.python.name }} wheel runs-on: ubuntu-latest - container: quay.io/pypa/manylinux2014_x86_64:2024-05-27-2f0b25d + container: quay.io/pypa/manylinux2014_x86_64:2024-07-01-8dac23b strategy: matrix: python: @@ -22,12 +22,9 @@ jobs: } steps: - - name: Install Linux packages - run: yum install -y wget - - name: Install Maven run: | - wget https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz -P /tmp + curl --fail --silent --show-error https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz -o /tmp/apache-maven-3.9.6-bin.tar.gz tar xf /tmp/apache-maven-*.tar.gz -C /opt echo /opt/apache-maven-3.9.6/bin >> $GITHUB_PATH diff --git a/.github/workflows/full-ci.yml b/.github/workflows/full-ci.yml index 6bcef29bf..b31d91c1b 100644 --- a/.github/workflows/full-ci.yml +++ b/.github/workflows/full-ci.yml @@ -11,7 +11,7 @@ jobs: manylinux_build: name: Build linux ${{ matrix.python.name }} wheel runs-on: ubuntu-latest - container: quay.io/pypa/manylinux2014_x86_64:2024-05-27-2f0b25d + container: quay.io/pypa/manylinux2014_x86_64:2024-07-01-8dac23b strategy: matrix: python: @@ -42,12 +42,9 @@ jobs: } steps: - - name: Install Linux packages - run: yum install -y wget - - name: Install Maven run: | - wget https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz -P /tmp + curl --fail --silent --show-error https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz -o /tmp/apache-maven-3.9.6-bin.tar.gz tar xf /tmp/apache-maven-*.tar.gz -C /opt echo /opt/apache-maven-3.9.6/bin >> $GITHUB_PATH From c326d29a9c0957cdb32374ba83cd0fa236f35ef3 Mon Sep 17 00:00:00 2001 From: jeandemanged Date: Mon, 1 Jul 2024 16:38:38 +0200 Subject: [PATCH 22/45] Add DanglingLine boundary side P, Q, Vmag, Vangle (#792) Signed-off-by: Damien Jeandemange --- .../dataframe/network/NetworkDataframes.java | 4 ++++ .../network/NetworkDataframesTest.java | 1 + pypowsybl/network/impl/network.py | 4 ++++ tests/test_network.py | 18 ++++++++++++++++++ 4 files changed, 27 insertions(+) diff --git a/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java b/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java index 144af1899..35d3777f6 100644 --- a/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java +++ b/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java @@ -594,6 +594,10 @@ static NetworkDataframeMapper danglingLines() { .doubles("p", getPerUnitP(), setPerUnitP()) .doubles("q", getPerUnitQ(), setPerUnitQ()) .doubles("i", (dl, context) -> perUnitI(context, dl.getTerminal())) + .doubles("boundary_p", (dl, context) -> perUnitPQ(context, dl.getBoundary().getP()), false) + .doubles("boundary_q", (dl, context) -> perUnitPQ(context, dl.getBoundary().getQ()), false) + .doubles("boundary_v_mag", (dl, context) -> perUnitV(context, dl.getBoundary().getV(), dl.getTerminal()), false) + .doubles("boundary_v_angle", (dl, context) -> perUnitAngle(context, dl.getBoundary().getAngle()), false) .strings("voltage_level_id", getVoltageLevelId()) .strings("bus_id", dl -> getBusId(dl.getTerminal())) .strings("bus_breaker_bus_id", getBusBreakerViewBusId(), NetworkDataframes::setBusBreakerViewBusId, false) diff --git a/java/src/test/java/com/powsybl/dataframe/network/NetworkDataframesTest.java b/java/src/test/java/com/powsybl/dataframe/network/NetworkDataframesTest.java index 7f39c2942..acafc9910 100644 --- a/java/src/test/java/com/powsybl/dataframe/network/NetworkDataframesTest.java +++ b/java/src/test/java/com/powsybl/dataframe/network/NetworkDataframesTest.java @@ -268,6 +268,7 @@ void danglingLines() { assertThat(allAttributeSeries) .extracting(Series::getName) .containsExactly("id", "name", "r", "x", "g", "b", "p0", "q0", "p", "q", "i", + "boundary_p", "boundary_q", "boundary_v_mag", "boundary_v_angle", "voltage_level_id", "bus_id", "bus_breaker_bus_id", "node", "connected", "pairing_key", "ucte_xnode_code", "fictitious", "tie_line_id"); } diff --git a/pypowsybl/network/impl/network.py b/pypowsybl/network/impl/network.py index dac12c946..1be7433fe 100644 --- a/pypowsybl/network/impl/network.py +++ b/pypowsybl/network/impl/network.py @@ -1196,6 +1196,10 @@ def get_dangling_lines(self, all_attributes: bool = False, attributes: List[str] - **p**: active flow on the dangling line, ``NaN`` if no loadflow has been computed (in MW) - **q**: the reactive flow on the dangling line, ``NaN`` if no loadflow has been computed (in MVAr) - **i**: The current on the dangling line, ``NaN`` if no loadflow has been computed (in A) + - **boundary_p** (optional): active flow on the dangling line at boundary bus side, ``NaN`` if no loadflow has been computed (in MW) + - **boundary_q** (optional): reactive flow on the dangling line at boundary bus side, ``NaN`` if no loadflow has been computed (in MW) + - **boundary_v_mag** (optional): voltage magnitude of the boundary bus, ``NaN`` if no loadflow has been computed (in kV) + - **boundary_v_angle** (optional): voltage angle of the boundary bus, ``NaN`` if no loadflow has been computed (in degree) - **voltage_level_id**: at which substation the dangling line is connected - **bus_id**: bus where this line is connected - **bus_breaker_bus_id** (optional): bus of the bus-breaker view where this line is connected diff --git a/tests/test_network.py b/tests/test_network.py index f3a7a8965..263810dc6 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -986,6 +986,24 @@ def test_dangling_lines(): data=[['BUS', -1]]) pd.testing.assert_frame_equal(expected, dangling_lines, check_dtype=False, atol=1e-2) + # test boundary point columns + n = pp.network.create_micro_grid_be_network() + dangling_lines = n.get_dangling_lines(attributes=['p', 'q', + 'boundary_p', 'boundary_q', 'boundary_v_mag', 'boundary_v_angle']) + expected = pd.DataFrame( + index=pd.Series(name='id', data=['17086487-56ba-4979-b8de-064025a6b4da', + '78736387-5f60-4832-b3fe-d50daf81b0a6', + 'b18cd1aa-7808-49b9-a7cf-605eaf07b006', + 'a16b4a6c-70b1-4abf-9a9d-bd0fa47f9fe4', + 'ed0c5d75-4a54-43c8-b782-b20d7431630b']), + columns=['p', 'q', 'boundary_p', 'boundary_q', 'boundary_v_mag', 'boundary_v_angle'], + data=[[-25.77, -2.82, 27.36, -0.42, 225.49, -5.58], + [-36.59, 54.18, 46.81, -79.19, 411.15, -6.58], + [-82.84, 138.45, 90.03, -148.60, 410.88, -6.57], + [-23.83, 1.27, 26.80, -1.48, 224.96, -5.63], + [-36.85, 80.68, 43.68, -84.87, 412.61, -6.74]]) + pd.testing.assert_frame_equal(expected, dangling_lines, check_dtype=False, atol=1e-2) + def test_batteries(): n = util.create_battery_network() From 6cf3c619df29ceec3eb656687e615564f0ebf37c Mon Sep 17 00:00:00 2001 From: EtienneLt <32468651+EtienneLt@users.noreply.github.com> Date: Tue, 2 Jul 2024 12:50:30 +0200 Subject: [PATCH 23/45] adding documentation for reduce function (#791) --------- Signed-off-by: Etienne LESOT --- docs/user_guide/network.rst | 57 +++++++++++++++++++++++++++++++ pypowsybl/network/impl/network.py | 9 +++++ 2 files changed, 66 insertions(+) diff --git a/docs/user_guide/network.rst b/docs/user_guide/network.rst index ab709cbdd..f2596a8bf 100644 --- a/docs/user_guide/network.rst +++ b/docs/user_guide/network.rst @@ -877,3 +877,60 @@ parent network and become again a standalone network. :options: +NORMALIZE_WHITESPACE >>> nl_sub.detach() + +Reducing a network +------------------ + +Pypowsybl provides methods to reduce a network to a smaller one. It can be done with different parameters. +It can be decided according to the voltage with the parameters v_min and v_max. It can also be by indicating the +Voltage Levels that will be kept and also indicating the depth around these voltage levels. + +For this example we will keep only voltage levels with voltage superior or equal to 400 kV + +.. doctest:: + :options: +NORMALIZE_WHITESPACE + + >>> net = pp.network.create_four_substations_node_breaker_network() + >>> net.get_voltage_levels() + name substation_id nominal_v high_voltage_limit low_voltage_limit + id + S1VL1 S1 225.0 240.0 220.0 + S1VL2 S1 400.0 440.0 390.0 + S2VL1 S2 400.0 440.0 390.0 + S3VL1 S3 400.0 440.0 390.0 + S4VL1 S4 400.0 440.0 390.0 + + >>> net.reduce(v_min=400) + >>> net.get_voltage_levels() + name substation_id nominal_v high_voltage_limit low_voltage_limit + id + S1VL2 S1 400.0 440.0 390.0 + S2VL1 S2 400.0 440.0 390.0 + S3VL1 S3 400.0 440.0 390.0 + S4VL1 S4 400.0 440.0 390.0 + +For the next example we will keep voltage level S1VL1 with a depth of 1. + +.. doctest:: + :options: +NORMALIZE_WHITESPACE + + >>> net = pp.network.create_four_substations_node_breaker_network() + >>> net.get_voltage_levels() + name substation_id nominal_v high_voltage_limit low_voltage_limit + id + S1VL1 S1 225.0 240.0 220.0 + S1VL2 S1 400.0 440.0 390.0 + S2VL1 S2 400.0 440.0 390.0 + S3VL1 S3 400.0 440.0 390.0 + S4VL1 S4 400.0 440.0 390.0 + >>> net.reduce(vl_depths=[['S1VL1', 1]]) + >>> net.get_voltage_levels() + name substation_id nominal_v high_voltage_limit low_voltage_limit + id + S1VL1 S1 225.0 240.0 220.0 + S1VL2 S1 400.0 440.0 390.0 + +S1VL1 is connected to S1VL2 by the transformer TWT, so it is kept after the network reduction. +It is the only voltage level connected to S1VL1 by one branch. + +the parameter "ids" can be used to specify the exact voltage levels that will be kept diff --git a/pypowsybl/network/impl/network.py b/pypowsybl/network/impl/network.py index 1be7433fe..90a388de0 100644 --- a/pypowsybl/network/impl/network.py +++ b/pypowsybl/network/impl/network.py @@ -252,6 +252,15 @@ def save_to_binary_buffer(self, format: str = 'XIIDM', parameters: ParamsDict = def reduce(self, v_min: float = 0, v_max: float = sys.float_info.max, ids: List[str] = None, vl_depths: tuple = (), with_dangling_lines: bool = False) -> None: + """ + Reduce to a smaller network according to the following parameters + + :param v_min: minimum voltage of the voltage levels kept after reducing + :param v_max: voltage maximum of the voltage levels kept after reducing + :param ids: ids of the voltage levels that will be kept + :param vl_depths: depth around voltage levels which are indicated by their id, that will be kept + :param with_dangling_lines: keeping the dangling lines + """ if ids is None: ids = [] vls = [] From 293d066997a5fb00f918cde9af5ad5f18037b094 Mon Sep 17 00:00:00 2001 From: Choco <97348238+unetablettedechocolat@users.noreply.github.com> Date: Tue, 2 Jul 2024 13:46:23 +0200 Subject: [PATCH 24/45] Add get_matrix_multi_substation_single_line_diagram (#781) Signed-off-by: Tiphaine Mouminous Co-authored-by: Sophie Frasnedo <93923177+So-Fras@users.noreply.github.com> --- cpp/powsybl-cpp/powsybl-cpp.cpp | 16 ++++++++++++++++ cpp/powsybl-cpp/powsybl-cpp.h | 2 ++ cpp/pypowsybl-cpp/bindings.cpp | 3 +++ docs/reference/network.rst | 1 + docs/user_guide/network_visualization.rst | 7 +++++++ .../python/network/NetworkCFunctions.java | 13 +++++++++++++ .../python/network/SingleLineDiagramUtil.java | 11 +++++++++++ pypowsybl/_pypowsybl.pyi | 3 ++- pypowsybl/network/impl/network.py | 17 +++++++++++++++++ tests/test_network.py | 17 +++++++++++++++++ 10 files changed, 89 insertions(+), 1 deletion(-) diff --git a/cpp/powsybl-cpp/powsybl-cpp.cpp b/cpp/powsybl-cpp/powsybl-cpp.cpp index 14508fe0b..342f249f8 100644 --- a/cpp/powsybl-cpp/powsybl-cpp.cpp +++ b/cpp/powsybl-cpp/powsybl-cpp.cpp @@ -691,6 +691,22 @@ std::vector getSingleLineDiagramSvgAndMetadata(const JavaHandle& ne return svgAndMetadata.get(); } +std::vector getMatrixMultiSubstationSvgAndMetadata(const JavaHandle& network, const std::vector>& matrixIds, const SldParameters& parameters){ + auto c_parameters = parameters.to_c_struct(); + int nbRows = matrixIds.size(); + std::vector substationIds; + for (int row = 0; row < nbRows; ++row) { + const std::vector& colIds = matrixIds[row]; + for (int col = 0; col < matrixIds[row].size(); ++col) { + substationIds.push_back(colIds[col]); + } + } + ToCharPtrPtr substationIdPtr(substationIds); + auto svgAndMetadataArrayPtr = PowsyblCaller::get()->callJava(::getMatrixMultiSubstationSvgAndMetadata, network, substationIdPtr.get(), substationIds.size(), nbRows, c_parameters.get()); + ToStringVector svgAndMetadata(svgAndMetadataArrayPtr); + return svgAndMetadata.get(); +} + void writeNetworkAreaDiagramSvg(const JavaHandle& network, const std::string& svgFile, const std::vector& voltageLevelIds, int depth, double highNominalVoltageBound, double lowNominalVoltageBound, const NadParameters& parameters) { auto c_parameters = parameters.to_c_struct(); ToCharPtrPtr voltageLevelIdPtr(voltageLevelIds); diff --git a/cpp/powsybl-cpp/powsybl-cpp.h b/cpp/powsybl-cpp/powsybl-cpp.h index b20789d13..ba020c383 100644 --- a/cpp/powsybl-cpp/powsybl-cpp.h +++ b/cpp/powsybl-cpp/powsybl-cpp.h @@ -552,6 +552,8 @@ std::string getSingleLineDiagramSvg(const JavaHandle& network, const std::string std::vector getSingleLineDiagramSvgAndMetadata(const JavaHandle& network, const std::string& containerId, const SldParameters& parameters); +std::vector getMatrixMultiSubstationSvgAndMetadata(const JavaHandle& network, const std::vector>& matrixIds, const SldParameters& parameters); + std::vector getSingleLineDiagramComponentLibraryNames(); void writeNetworkAreaDiagramSvg(const JavaHandle& network, const std::string& svgFile, const std::vector& voltageLevelIds, int depth, double highNominalVoltageBound, double lowNominalVoltageBound, const NadParameters& parameters); diff --git a/cpp/pypowsybl-cpp/bindings.cpp b/cpp/pypowsybl-cpp/bindings.cpp index d5fd1db0a..983090256 100644 --- a/cpp/pypowsybl-cpp/bindings.cpp +++ b/cpp/pypowsybl-cpp/bindings.cpp @@ -586,6 +586,9 @@ PYBIND11_MODULE(_pypowsybl, m) { m.def("get_single_line_diagram_svg_and_metadata", &pypowsybl::getSingleLineDiagramSvgAndMetadata, "Get single line diagram SVG and its metadata as a list of strings", py::arg("network"), py::arg("container_id"), py::arg("sld_parameters")); + m.def("get_matrix_multi_substation_single_line_diagram_svg_and_metadata", &pypowsybl::getMatrixMultiSubstationSvgAndMetadata, "Get matrix multi-substation single line diagram SVG and its metadata as a list of strings", + py::arg("network"), py::arg("matrix_ids"), py::arg("sld_parameters")); + m.def("get_single_line_diagram_component_library_names", &pypowsybl::getSingleLineDiagramComponentLibraryNames, "Get supported component library providers for single line diagram"); m.def("write_network_area_diagram_svg", &pypowsybl::writeNetworkAreaDiagramSvg, "Write network area diagram SVG", diff --git a/docs/reference/network.rst b/docs/reference/network.rst index a025f9cd2..ec9260b7a 100644 --- a/docs/reference/network.rst +++ b/docs/reference/network.rst @@ -217,6 +217,7 @@ Miscellaneous network functions Network.merge Network.get_single_line_diagram Network.write_single_line_diagram_svg + Network.get_matrix_multi_substation_single_line_diagram Network.write_matrix_multi_substation_single_line_diagram_svg Network.get_network_area_diagram Network.write_network_area_diagram_svg diff --git a/docs/user_guide/network_visualization.rst b/docs/user_guide/network_visualization.rst index 18f12b40b..bfaf24ca4 100644 --- a/docs/user_guide/network_visualization.rst +++ b/docs/user_guide/network_visualization.rst @@ -152,6 +152,13 @@ It is also possible to display a multi-substation single line diagram (currently .. image:: ../_static/images/ieee14_s1_s2_s3_s4.svg :class: forced-white-background +Or in a Jupyter Notebook: + +.. code-block:: python + + >>> network.get_matrix_multi_substation_single_line_diagram([['S1', 'S2'],['S3','S4']]) + + Network area diagram -------------------- diff --git a/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java b/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java index 8a5024cf3..bbbd3202c 100644 --- a/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java +++ b/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java @@ -1036,6 +1036,19 @@ public static ArrayPointer getSingleLineDiagramSvgAndMetada }); } + @CEntryPoint(name = "getMatrixMultiSubstationSvgAndMetadata") + public static ArrayPointer getMatrixMultiSubstationSvgAndMetadata(IsolateThread thread, ObjectHandle networkHandle, CCharPointerPointer substationIdsPointer, + int substationIdCount, int substationIdRowCount, + SldParametersPointer sldParametersPtr, ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, () -> { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String[][] matrixIds = CTypeUtil.toString2DArray(substationIdsPointer, substationIdCount, substationIdRowCount); + SldParameters sldParameters = convertSldParameters(sldParametersPtr); + List svgAndMeta = SingleLineDiagramUtil.getMatrixMultiSubstationSvgAndMetadata(network, matrixIds, sldParameters); + return createCharPtrArray(svgAndMeta); + }); + } + @CEntryPoint(name = "getSingleLineDiagramComponentLibraryNames") public static PyPowsyblApiHeader.ArrayPointer getSingleLineDiagramComponentLibraryNames(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { return doCatch(exceptionHandlerPtr, () -> createCharPtrArray(SingleLineDiagramUtil.getComponentLibraryNames())); diff --git a/java/src/main/java/com/powsybl/python/network/SingleLineDiagramUtil.java b/java/src/main/java/com/powsybl/python/network/SingleLineDiagramUtil.java index 49b27547c..998a73801 100644 --- a/java/src/main/java/com/powsybl/python/network/SingleLineDiagramUtil.java +++ b/java/src/main/java/com/powsybl/python/network/SingleLineDiagramUtil.java @@ -69,6 +69,17 @@ static List getSvgAndMetadata(Network network, String containerId, SldPa } } + static List getMatrixMultiSubstationSvgAndMetadata(Network network, String[][] matrixIds, SldParameters sldParameters) { + try (StringWriter writer = new StringWriter(); StringWriter writerMeta = new StringWriter()) { + writeMatrixMultiSubstationSvg(network, matrixIds, writer, writerMeta, sldParameters); + writer.flush(); + writerMeta.flush(); + return List.of(writer.toString(), writerMeta.toString()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + static SldParameters createSldParameters() { SldParameters sldParameters = new SldParameters(); sldParameters.getSvgParameters().setSvgWidthAndHeightAdded(true); diff --git a/pypowsybl/_pypowsybl.pyi b/pypowsybl/_pypowsybl.pyi index 2c3eb79b8..0ce887cd7 100644 --- a/pypowsybl/_pypowsybl.pyi +++ b/pypowsybl/_pypowsybl.pyi @@ -768,8 +768,9 @@ def get_network_elements_dataframe_metadata(element_type: ElementType) -> List[S def get_network_elements_creation_dataframes_metadata(element_type: ElementType) -> List[List[SeriesMetadata]]: ... def get_single_line_diagram_svg(network: JavaHandle, container_id: str) -> str: ... def get_single_line_diagram_svg_and_metadata(network: JavaHandle, container_id: str, parameters: SldParameters ) -> List[str]: ... -def get_three_windings_transformer_results(result: JavaHandle) -> SeriesArray: ... +def get_matrix_multi_substation_single_line_diagram_svg_and_metadata(network: JavaHandle, matrix_ids: List[List[str]], parameters: SldParameters) -> List[str]: ... def get_validation_level(network: JavaHandle) -> ValidationLevel: ... +def get_three_windings_transformer_results(result: JavaHandle) -> SeriesArray: ... def get_variant_ids(network: JavaHandle) -> List[str]: ... def get_version_table() -> str: ... def get_working_variant_id(network: JavaHandle) -> str: ... diff --git a/pypowsybl/network/impl/network.py b/pypowsybl/network/impl/network.py index 90a388de0..5ea817bbc 100644 --- a/pypowsybl/network/impl/network.py +++ b/pypowsybl/network/impl/network.py @@ -326,6 +326,23 @@ def get_single_line_diagram(self, container_id: str, parameters: SldParameters = svg_and_metadata: List[str] = _pp.get_single_line_diagram_svg_and_metadata(self._handle, container_id, p) return Svg(svg_and_metadata[0], svg_and_metadata[1]) + def get_matrix_multi_substation_single_line_diagram(self, matrix_ids: List[List[str]], parameters: SldParameters = None) -> Svg: + """ + Create a single line diagram from multiple substations + + Args: + matrix_ids: a two-dimensional list of substation id + parameters:single-line diagram parameters to adjust the rendering of the diagram + + Returns: + the single line diagram + """ + + p = parameters._to_c_parameters() if parameters is not None else _pp.SldParameters() # pylint: disable=protected-access + + svg_and_metadata: List[str] = _pp.get_matrix_multi_substation_single_line_diagram_svg_and_metadata(self._handle, matrix_ids, p) + return Svg(svg_and_metadata[0], svg_and_metadata[1]) + def write_network_area_diagram_svg(self, svg_file: PathOrStr, voltage_level_ids: Union[str, List[str]] = None, depth: int = 0, high_nominal_voltage_bound: float = -1, low_nominal_voltage_bound: float = -1, diff --git a/tests/test_network.py b/tests/test_network.py index 263810dc6..beb91a527 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -828,6 +828,23 @@ def test_sld_svg(): assert re.search('.* 0 + sld_multi_substation = n.get_matrix_multi_substation_single_line_diagram([['S1', 'S2'], ['S3', 'S4']]) + assert re.search('.* 0 + + sld_multi_substation1 = n.get_matrix_multi_substation_single_line_diagram([['S1', 'S2'], ['S3', 'S4']], + SldParameters(use_name=True, center_name=True, + diagonal_label=True, topological_coloring=False, + tooltip_enabled=True)) + assert re.search('.* 0 + + sld_multi_substation2 = n.get_matrix_multi_substation_single_line_diagram([['S1', 'S2'], ['S3', 'S4']], + SldParameters(use_name=True, center_name=True, + diagonal_label=True, nodes_infos=True, topological_coloring=True, + tooltip_enabled=True)) + assert re.search('.* 0 def test_sld_svg_backward_compatibility(): n = pp.network.create_four_substations_node_breaker_network() From 212530cb717e5219849421ded520367fcaa2c37c Mon Sep 17 00:00:00 2001 From: Hugo KULESZA Date: Tue, 2 Jul 2024 14:09:44 +0200 Subject: [PATCH 25/45] Bump to v1.6.0 Signed-off-by: Hugo KULESZA --- java/pom.xml | 2 +- pypowsybl/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/pom.xml b/java/pom.xml index 6cf1946c7..6c453d420 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -58,7 +58,7 @@ jar - 1.6.0-SNAPSHOT + 1.6.0 21 diff --git a/pypowsybl/__init__.py b/pypowsybl/__init__.py index 37bee8889..d9884249a 100644 --- a/pypowsybl/__init__.py +++ b/pypowsybl/__init__.py @@ -22,7 +22,7 @@ ) from pypowsybl.network import per_unit_view -__version__ = '1.6.0.dev1' +__version__ = '1.6.0' # set JVM java.library.path to pypowsybl module installation directory to be able to load math library _pypowsybl.set_java_library_path(_os.path.dirname(_inspect.getfile(_pypowsybl))) From 462e81aa58fbc193e50f1d365450a4d977b193bf Mon Sep 17 00:00:00 2001 From: Hugo KULESZA Date: Tue, 2 Jul 2024 14:10:34 +0200 Subject: [PATCH 26/45] Bump to v1.7.0-SNAPSHOT Signed-off-by: Hugo KULESZA --- java/pom.xml | 2 +- pypowsybl/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/pom.xml b/java/pom.xml index 6c453d420..d408f6c18 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -58,7 +58,7 @@ jar - 1.6.0 + 1.7.0-SNAPSHOT 21 diff --git a/pypowsybl/__init__.py b/pypowsybl/__init__.py index d9884249a..debb1e9a4 100644 --- a/pypowsybl/__init__.py +++ b/pypowsybl/__init__.py @@ -22,7 +22,7 @@ ) from pypowsybl.network import per_unit_view -__version__ = '1.6.0' +__version__ = '1.7.0.dev1' # set JVM java.library.path to pypowsybl module installation directory to be able to load math library _pypowsybl.set_java_library_path(_os.path.dirname(_inspect.getfile(_pypowsybl))) From 9548e8853d9c01789296b2a731703caf226fc06b Mon Sep 17 00:00:00 2001 From: Choco <97348238+unetablettedechocolat@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:42:49 +0200 Subject: [PATCH 27/45] Adding current feeder info parameter for SLD (#785) Signed-off-by: Tiphaine Mouminous Co-authored-by: Sophie Frasnedo <93923177+So-Fras@users.noreply.github.com> --- cpp/powsybl-cpp/powsybl-api.h | 1 + cpp/powsybl-cpp/powsybl-cpp.cpp | 2 + cpp/powsybl-cpp/powsybl-cpp.h | 1 + cpp/pypowsybl-cpp/bindings.cpp | 3 +- ...ee14_SldParam_displaycurrentfeederinfo.svg | 394 ++++++++++++++++++ docs/user_guide/network_visualization.rst | 15 +- .../python/commons/PyPowsyblApiHeader.java | 6 + .../python/network/NetworkCFunctions.java | 4 +- pypowsybl/_pypowsybl.pyi | 1 + pypowsybl/network/impl/sld_parameters.py | 9 +- tests/test_network.py | 4 +- 11 files changed, 435 insertions(+), 5 deletions(-) create mode 100644 docs/_static/images/ieee14_SldParam_displaycurrentfeederinfo.svg diff --git a/cpp/powsybl-cpp/powsybl-api.h b/cpp/powsybl-cpp/powsybl-api.h index 1d2f6023d..d1eab1ba1 100644 --- a/cpp/powsybl-cpp/powsybl-api.h +++ b/cpp/powsybl-cpp/powsybl-api.h @@ -341,6 +341,7 @@ typedef struct sld_parameters_struct { unsigned char tooltip_enabled; unsigned char topological_coloring; char* component_library; + unsigned char display_current_feeder_info; } sld_parameters; typedef struct nad_parameters_struct { diff --git a/cpp/powsybl-cpp/powsybl-cpp.cpp b/cpp/powsybl-cpp/powsybl-cpp.cpp index 342f249f8..f1bc03325 100644 --- a/cpp/powsybl-cpp/powsybl-cpp.cpp +++ b/cpp/powsybl-cpp/powsybl-cpp.cpp @@ -1199,6 +1199,7 @@ SldParameters::SldParameters(sld_parameters* src) { tooltip_enabled = (bool) src->tooltip_enabled; topological_coloring = (bool) src->topological_coloring; component_library = toString(src->component_library); + display_current_feeder_info = (bool) src->display_current_feeder_info; } NadParameters::NadParameters(nad_parameters* src) { @@ -1225,6 +1226,7 @@ void SldParameters::sld_to_c_struct(sld_parameters& res) const { res.tooltip_enabled = (unsigned char) tooltip_enabled; res.topological_coloring = (unsigned char) topological_coloring; res.component_library = copyStringToCharPtr(component_library); + res.display_current_feeder_info = (unsigned char) display_current_feeder_info; } void NadParameters::nad_to_c_struct(nad_parameters& res) const { diff --git a/cpp/powsybl-cpp/powsybl-cpp.h b/cpp/powsybl-cpp/powsybl-cpp.h index ba020c383..8fdcc2b3d 100644 --- a/cpp/powsybl-cpp/powsybl-cpp.h +++ b/cpp/powsybl-cpp/powsybl-cpp.h @@ -393,6 +393,7 @@ class SldParameters { bool tooltip_enabled; bool topological_coloring; std::string component_library; + bool display_current_feeder_info; }; enum class NadLayoutType { diff --git a/cpp/pypowsybl-cpp/bindings.cpp b/cpp/pypowsybl-cpp/bindings.cpp index 983090256..ea374fbfd 100644 --- a/cpp/pypowsybl-cpp/bindings.cpp +++ b/cpp/pypowsybl-cpp/bindings.cpp @@ -547,7 +547,8 @@ PYBIND11_MODULE(_pypowsybl, m) { .def_readwrite("nodes_infos", &pypowsybl::SldParameters::nodes_infos) .def_readwrite("tooltip_enabled", &pypowsybl::SldParameters::tooltip_enabled) .def_readwrite("topological_coloring", &pypowsybl::SldParameters::topological_coloring) - .def_readwrite("component_library", &pypowsybl::SldParameters::component_library); + .def_readwrite("component_library", &pypowsybl::SldParameters::component_library) + .def_readwrite("display_current_feeder_info", &pypowsybl::SldParameters::display_current_feeder_info); py::enum_(m, "NadLayoutType") .value("FORCE_LAYOUT", pypowsybl::NadLayoutType::FORCE_LAYOUT) diff --git a/docs/_static/images/ieee14_SldParam_displaycurrentfeederinfo.svg b/docs/_static/images/ieee14_SldParam_displaycurrentfeederinfo.svg new file mode 100644 index 000000000..a2b165b95 --- /dev/null +++ b/docs/_static/images/ieee14_SldParam_displaycurrentfeederinfo.svg @@ -0,0 +1,394 @@ + + + + + + + + B4 + + + + + + + + + + + + + + + 48 + + + + + -4 + + + + + 202 + + + + + + + + + + + + + + + B4-L + + + + + + + + + + + + + + + + 229 + + + + + 3 + + + + + -54 + + + + + + + + + + + + L2-4-1 + + + + + + + + + + + + + + + + 24 + + + + + -5 + + + + + 101 + + + + + + + + + + + + L3-4-1 + + + + + + + + + + + + + + + + 265 + + + + + 16 + + + + + -61 + + + + + + + + + + + + L4-5-1 + + + + + + + + + + + + + + + + 28 + + + + + -10 + + + + + 125 + + + + + + + + + + + + + + T4-7-1 + + + + + + + + + + + + + + + + 68 + + + + + -0 + + + + + 16 + + + + + + + + + + + + + + T4-9-1 + + + + diff --git a/docs/user_guide/network_visualization.rst b/docs/user_guide/network_visualization.rst index bfaf24ca4..0bfa25182 100644 --- a/docs/user_guide/network_visualization.rst +++ b/docs/user_guide/network_visualization.rst @@ -34,7 +34,8 @@ Single-line diagrams can be customized through SldParameters: >>> network = pp.network.create_ieee14() >>> result = pp.loadflow.run_ac(network) - >>> network.get_single_line_diagram('VL4',parameters = pp.network.SldParameters(use_name = False, center_name = False, diagonal_label = False, nodes_infos = False, tooltip_enabled = False, topological_coloring = True, component_library = 'Convergence')) + >>> network.get_single_line_diagram('VL4',parameters = pp.network.SldParameters(use_name = False, center_name = False, diagonal_label = False, nodes_infos = False, tooltip_enabled = False, topological_coloring = True, component_library = 'Convergence', display_current_feeder_info = False)) + - use_name: if true, display components names instead of their id (default value false) - center_name: if true, center the names of feeders (default value false) @@ -43,6 +44,8 @@ Single-line diagrams can be customized through SldParameters: - tooltip_enabled: if true, display the name of the component pointed by the cursor (default value false) - topological_coloring: if true, set each electrical nodes with a different colour (default value true) - component_library: choose component library (default value 'Convergence') +- display_current_feeder_info: if true, display current feeder value (default value False) + Let's see some examples down below: @@ -140,6 +143,16 @@ Let's see some examples down below: .. image:: ../_static/images/ieee14_SldParam_complib_flatdesign.svg :class: forced-white-background +- with display current feeder info + +.. code-block:: python + + >>> param = pn.SldParameters(display_current_feeder_info = True) + >>> network.get_single_line_diagram('VL4', parameters = param) + +.. image:: ../_static/images/ieee14_SldParam_displaycurrentfeederinfo.svg + :class: forced-white-background + It is also possible to display a multi-substation single line diagram (currently a beta feature): diff --git a/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java b/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java index f79c056ee..f4ed6e184 100644 --- a/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java +++ b/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java @@ -1068,6 +1068,12 @@ public interface SldParametersPointer extends PointerBase { @CField("component_library") void setComponentLibrary(CCharPointer componentLibrary); + + @CField("display_current_feeder_info") + boolean isDisplayCurrentFeederInfo(); + + @CField("display_current_feeder_info") + void setDisplayCurrentFeederInfo(boolean displayCurrentInfo); } @CStruct("nad_parameters") diff --git a/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java b/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java index bbbd3202c..0acdd1c98 100644 --- a/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java +++ b/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java @@ -878,6 +878,7 @@ public static void copyToCSldParameters(SldParameters parameters, SldParametersP cParameters.setAddNodesInfos(parameters.getSvgParameters().isAddNodesInfos()); cParameters.setTooltipEnabled(parameters.getSvgParameters().isTooltipEnabled()); cParameters.setComponentLibrary(CTypeUtil.toCharPtr(parameters.getComponentLibrary().getName())); + cParameters.setDisplayCurrentFeederInfo(parameters.getSvgParameters().isDisplayCurrentFeederInfo()); } public static SldParametersPointer convertToSldParametersPointer(SldParameters parameters) { @@ -952,7 +953,8 @@ public static SldParameters convertSldParameters(SldParametersPointer sldParamet .setLabelCentered(sldParametersPtr.isCenterName()) .setLabelDiagonal(sldParametersPtr.isDiagonalLabel()) .setAddNodesInfos(sldParametersPtr.isAddNodesInfos()) - .setTooltipEnabled(sldParametersPtr.getTooltipEnabled()); + .setTooltipEnabled(sldParametersPtr.getTooltipEnabled()) + .setDisplayCurrentFeederInfo(sldParametersPtr.isDisplayCurrentFeederInfo()); return sldParameters; } diff --git a/pypowsybl/_pypowsybl.pyi b/pypowsybl/_pypowsybl.pyi index 0ce887cd7..2f0a1e7e9 100644 --- a/pypowsybl/_pypowsybl.pyi +++ b/pypowsybl/_pypowsybl.pyi @@ -266,6 +266,7 @@ class SldParameters: tooltip_enabled: bool topological_coloring: bool component_library: str + display_current_feeder_info: bool def __init__(self) -> None: ... class NadLayoutType: diff --git a/pypowsybl/network/impl/sld_parameters.py b/pypowsybl/network/impl/sld_parameters.py index 82d642464..1083d5837 100644 --- a/pypowsybl/network/impl/sld_parameters.py +++ b/pypowsybl/network/impl/sld_parameters.py @@ -13,7 +13,7 @@ class SldParameters: def __init__(self, use_name: bool = False, center_name: bool = False, diagonal_label: bool = False, nodes_infos: bool = False, tooltip_enabled: bool = False, topological_coloring: bool = True, - component_library: str = 'Convergence'): + component_library: str = 'Convergence', display_current_feeder_info: bool = False): self._use_name = use_name self._center_name = center_name self._diagonal_label = diagonal_label @@ -21,6 +21,7 @@ def __init__(self, use_name: bool = False, center_name: bool = False, diagonal_l self._tooltip_enabled = tooltip_enabled self._topological_coloring = topological_coloring self._component_library = component_library + self._display_current_feeder_info = display_current_feeder_info @property def use_name(self) -> bool: @@ -57,6 +58,11 @@ def component_library(self) -> str: """name of the library used for component""" return self._component_library + @property + def display_current_feeder_info(self) -> bool: + """when True display current feeder info""" + return self._display_current_feeder_info + def _to_c_parameters(self) -> _pp.SldParameters: c_parameters = _pp.SldParameters() c_parameters.use_name = self._use_name @@ -66,4 +72,5 @@ def _to_c_parameters(self) -> _pp.SldParameters: c_parameters.nodes_infos = self._nodes_infos c_parameters.tooltip_enabled = self._tooltip_enabled c_parameters.component_library = self._component_library + c_parameters.display_current_feeder_info = self._display_current_feeder_info return c_parameters diff --git a/tests/test_network.py b/tests/test_network.py index beb91a527..824e3859f 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -782,17 +782,19 @@ def test_sld_parameters(): assert not parameters.center_name assert not parameters.diagonal_label assert not parameters.nodes_infos + assert not parameters.display_current_feeder_info assert parameters.topological_coloring assert parameters.component_library == 'Convergence' parameters = SldParameters(use_name=True, center_name=True, diagonal_label=True, nodes_infos=True, tooltip_enabled=True, topological_coloring=False, - component_library='FlatDesign') + component_library='FlatDesign', display_current_feeder_info=True) assert parameters.use_name assert parameters.center_name assert parameters.diagonal_label assert parameters.nodes_infos assert parameters.tool_tip_enabled + assert parameters.display_current_feeder_info assert not parameters.topological_coloring assert parameters.component_library == 'FlatDesign' From c066f581c5ab221695831d8aa079f16a06ee1c2a Mon Sep 17 00:00:00 2001 From: HugoKulesza <94374655+HugoKulesza@users.noreply.github.com> Date: Tue, 9 Jul 2024 10:12:58 +0200 Subject: [PATCH 28/45] Fix CI : regain compatibility with node16 for the CI (#798) Signed-off-by: Hugo KULESZA --- .github/workflows/dev-ci.yml | 2 ++ .github/workflows/full-ci.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/dev-ci.yml b/.github/workflows/dev-ci.yml index be59b640c..efedb0b96 100644 --- a/.github/workflows/dev-ci.yml +++ b/.github/workflows/dev-ci.yml @@ -12,6 +12,8 @@ jobs: name: Build linux ${{ matrix.python.name }} wheel runs-on: ubuntu-latest container: quay.io/pypa/manylinux2014_x86_64:2024-07-01-8dac23b + env: + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true strategy: matrix: python: diff --git a/.github/workflows/full-ci.yml b/.github/workflows/full-ci.yml index b31d91c1b..a5663dc05 100644 --- a/.github/workflows/full-ci.yml +++ b/.github/workflows/full-ci.yml @@ -12,6 +12,8 @@ jobs: name: Build linux ${{ matrix.python.name }} wheel runs-on: ubuntu-latest container: quay.io/pypa/manylinux2014_x86_64:2024-07-01-8dac23b + env: + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true strategy: matrix: python: From 597cddf94f76a6606618e016a3b67e531702d722 Mon Sep 17 00:00:00 2001 From: HugoKulesza <94374655+HugoKulesza@users.noreply.github.com> Date: Thu, 11 Jul 2024 12:44:00 +0200 Subject: [PATCH 29/45] Fix Windows CI : set matplotlib to 3.9.0 for python > 3.8 (#801) Signed-off-by: Hugo KULESZA --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 03b77b341..d4575435b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,8 @@ pandas==2.2.2; python_version >= "3.9" pandas==2.0.3; python_version <= "3.8" prettytable==2.0.0 networkx -matplotlib +matplotlib==3.9.0; python_version >= "3.9" +matplotlib; python_version <= "3.8" # documentation dependencies sphinx==7.1.2 From f25270c33383064835220e654aab9530338b1e7b Mon Sep 17 00:00:00 2001 From: Bertrand Rix Date: Mon, 15 Jul 2024 15:10:40 +0200 Subject: [PATCH 30/45] Fix MSVC runtime binaries incompatibility issues (#803) Signed-off-by: Bertrand Rix --- cpp/powsybl-cpp/CMakeLists.txt | 13 +++++++++++++ cpp/pypowsybl-cpp/CMakeLists.txt | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/cpp/powsybl-cpp/CMakeLists.txt b/cpp/powsybl-cpp/CMakeLists.txt index 399dba82e..63cfa517e 100644 --- a/cpp/powsybl-cpp/CMakeLists.txt +++ b/cpp/powsybl-cpp/CMakeLists.txt @@ -7,6 +7,12 @@ cmake_minimum_required(VERSION 3.14) project(powsybl-cpp) +# Enable static linkage to prevent any future runtime binary compatibility issue +if(MSVC) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") +endif() + include(ExternalProject) set(POWSYBL_CPP_LIB ${CMAKE_SHARED_LIBRARY_PREFIX}powsybl-cpp${CMAKE_SHARED_LIBRARY_SUFFIX}) @@ -95,4 +101,11 @@ if(DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY) add_custom_command(TARGET powsybl-cpp POST_BUILD ${POWSYBL_CPP_INSTALL_EXTRA_COMMAND} COMMAND ${CMAKE_COMMAND} -E copy $ ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${POWSYBL_MATH_NATIVE_JAR_ENTRY_DIR}/${POWSYBL_MATH_NATIVE_LIB} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) endif(DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY) +# Fix related to issue describred here https://github.com/actions/runner-images/issues/10004#issuecomment-2156109231 +# Should fix incompatibility between MSVC runtime 14.40.XXX and previous version +if(MSVC) + target_compile_definitions(powsybl-cpp + PRIVATE _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR) +endif() + target_link_libraries(powsybl-cpp PUBLIC ${PYPOWSYBL_JAVA_LIB}) diff --git a/cpp/pypowsybl-cpp/CMakeLists.txt b/cpp/pypowsybl-cpp/CMakeLists.txt index 3d2980d68..57081648a 100644 --- a/cpp/pypowsybl-cpp/CMakeLists.txt +++ b/cpp/pypowsybl-cpp/CMakeLists.txt @@ -7,6 +7,12 @@ cmake_minimum_required(VERSION 3.14) project(pypowsybl-cpp) +# Enable static linkage to prevent any future runtime binary compatibility issue +if(MSVC) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") +endif() + set(POWSYBL_CPP_SOURCE_DIR "../powsybl-cpp") set(PYPOWSYBL_JAVA_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}/../java) include_directories(${POWSYBL_CPP_SOURCE_DIR} ${PYPOWSYBL_JAVA_BIN_DIR}) @@ -16,4 +22,12 @@ pybind11_add_module(_pypowsybl pylogging.cpp bindings.cpp) add_dependencies(_pypowsybl native-image math-native) add_dependencies(math-native native-image) # because mvn command also copy math native jar + +# Fix related to issue describred here https://github.com/actions/runner-images/issues/10004#issuecomment-2156109231 +# Should fix incompatibility between MSVC runtime 14.40.XXX and previous version +if(MSVC) + target_compile_definitions(_pypowsybl + PRIVATE _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR) +endif() + target_link_libraries(_pypowsybl PRIVATE powsybl-cpp) From d80e776d16550da46107bc4dbe5126727c67bb42 Mon Sep 17 00:00:00 2001 From: Bertrand Rix Date: Tue, 16 Jul 2024 10:22:22 +0200 Subject: [PATCH 31/45] Do not use a constructor triggering a c++ call from within a default parameters list, is evaluated at declaration and can trigger a call before proper pypowsybl init. (#804) Signed-off-by: Bertrand Rix Co-authored-by: HugoKulesza <94374655+HugoKulesza@users.noreply.github.com> --- pypowsybl/voltage_initializer/impl/voltage_initializer.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pypowsybl/voltage_initializer/impl/voltage_initializer.py b/pypowsybl/voltage_initializer/impl/voltage_initializer.py index 54fd4ecae..9f72126ca 100644 --- a/pypowsybl/voltage_initializer/impl/voltage_initializer.py +++ b/pypowsybl/voltage_initializer/impl/voltage_initializer.py @@ -10,7 +10,7 @@ from .voltage_initializer_results import VoltageInitializerResults -def run(network: Network, params: VoltageInitializerParameters = VoltageInitializerParameters(), debug: bool = False) \ +def run(network: Network, params: VoltageInitializerParameters, debug: bool = False) \ -> VoltageInitializerResults: """ Run voltage initializer on the network with the given params. @@ -20,5 +20,7 @@ def run(network: Network, params: VoltageInitializerParameters = VoltageInitiali params: The parameters used to customize the run debug: if true, the tmp directory of the voltage initializer run will not be erased. """ + if params is None: + params = VoltageInitializerParameters() result_handle = run_voltage_initializer(debug, network._handle, params._handle) return VoltageInitializerResults(result_handle) From 146e4e12d688c808d57e2d39737506213ea22f0b Mon Sep 17 00:00:00 2001 From: Christian Biasuzzi Date: Tue, 16 Jul 2024 10:46:16 +0200 Subject: [PATCH 32/45] Fix multi substation sld svg (#797) Signed-off-by: Christian Biasuzzi Co-authored-by: Sophie Frasnedo <93923177+So-Fras@users.noreply.github.com> Co-authored-by: HugoKulesza <94374655+HugoKulesza@users.noreply.github.com> --- .../main/java/com/powsybl/python/commons/CTypeUtil.java | 2 +- tests/test_network.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/java/src/main/java/com/powsybl/python/commons/CTypeUtil.java b/java/src/main/java/com/powsybl/python/commons/CTypeUtil.java index 184f21c6e..6035a65e7 100644 --- a/java/src/main/java/com/powsybl/python/commons/CTypeUtil.java +++ b/java/src/main/java/com/powsybl/python/commons/CTypeUtil.java @@ -73,7 +73,7 @@ public static String toStringOrNull(CCharPointer charPtr) { public static String[][] toString2DArray(CCharPointerPointer charPtrPtr, int length, int rows) { int cols = length / rows; - String[][] string2DArray = new String[rows][length / cols]; + String[][] string2DArray = new String[rows][cols]; int index = 0; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { diff --git a/tests/test_network.py b/tests/test_network.py index 824e3859f..1dba0a891 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -848,6 +848,14 @@ def test_sld_svg(): assert re.search('.* 0 + sld_multi_substation3 = n.get_matrix_multi_substation_single_line_diagram([['S1'],['S2']]) + assert re.search('.* 0 + + sld_multi_substation4 = n.get_matrix_multi_substation_single_line_diagram([['S1', 'S2']]) + assert re.search('.* 0 + def test_sld_svg_backward_compatibility(): n = pp.network.create_four_substations_node_breaker_network() sld = n.get_single_line_diagram('S1VL1', LayoutParameters(use_name=True, center_name=True, diagonal_label=True, From ece090ed13248cf2d7d1a09c499fa905fbe216bf Mon Sep 17 00:00:00 2001 From: EtienneLt <32468651+EtienneLt@users.noreply.github.com> Date: Tue, 16 Jul 2024 12:59:27 +0200 Subject: [PATCH 33/45] add documentation for hvdc lines (#805) --------- Signed-off-by: Etienne LESOT --- pypowsybl/network/impl/network.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pypowsybl/network/impl/network.py b/pypowsybl/network/impl/network.py index 5ea817bbc..f8a20914b 100644 --- a/pypowsybl/network/impl/network.py +++ b/pypowsybl/network/impl/network.py @@ -1776,8 +1776,8 @@ def get_hvdc_lines(self, all_attributes: bool = False, attributes: List[str] = N Notes: The resulting dataframe, depending on the parameters, will include the following columns: - - **converters_mode**: - - **target_p**: (in MW) + - **converters_mode**: the mode of the converter stations. It can be either SIDE_1_RECTIFIER_SIDE_2_INVERTER or SIDE_1_INVERTER_SIDE_2_RECTIFIER + - **target_p**: active power target (in MW) - **max_p**: the maximum of active power that can pass through the hvdc line (in MW) - **nominal_v**: nominal voltage (in kV) - **r**: the resistance of the hvdc line (in Ohm) From 076162e39a82d17e0b67453126c0cad0502ce44f Mon Sep 17 00:00:00 2001 From: Bertrand Rix Date: Tue, 30 Jul 2024 13:43:11 +0200 Subject: [PATCH 34/45] Rename enum related to ampl logging (#812) Signed-off-by: Bertrand Rix --- cpp/powsybl-cpp/powsybl-api.h | 8 ++++---- cpp/pypowsybl-cpp/bindings.cpp | 8 ++++---- .../com/powsybl/python/commons/PyPowsyblApiHeader.java | 8 ++++---- java/src/main/java/com/powsybl/python/commons/Util.java | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cpp/powsybl-cpp/powsybl-api.h b/cpp/powsybl-cpp/powsybl-api.h index d1eab1ba1..aa86e00a6 100644 --- a/cpp/powsybl-cpp/powsybl-api.h +++ b/cpp/powsybl-cpp/powsybl-api.h @@ -403,10 +403,10 @@ typedef enum { } VoltageInitializerObjective; typedef enum { - DEBUG = 0, - INFO, - WARNING, - ERROR, + LOG_AMPL_DEBUG = 0, + LOG_AMPL_INFO, + LOG_AMPL_WARNING, + LOG_AMPL_ERROR, } VoltageInitializerLogLevelAmpl; typedef enum { diff --git a/cpp/pypowsybl-cpp/bindings.cpp b/cpp/pypowsybl-cpp/bindings.cpp index ea374fbfd..ee7034447 100644 --- a/cpp/pypowsybl-cpp/bindings.cpp +++ b/cpp/pypowsybl-cpp/bindings.cpp @@ -189,10 +189,10 @@ void voltageInitializerBinding(py::module_& m) { .value("SPECIFIC_VOLTAGE_PROFILE", VoltageInitializerObjective::SPECIFIC_VOLTAGE_PROFILE); py::enum_(m, "VoltageInitializerLogLevelAmpl") - .value("DEBUG", VoltageInitializerLogLevelAmpl::DEBUG) - .value("INFO", VoltageInitializerLogLevelAmpl::INFO) - .value("WARNING", VoltageInitializerLogLevelAmpl::WARNING) - .value("ERROR", VoltageInitializerLogLevelAmpl::ERROR); + .value("DEBUG", VoltageInitializerLogLevelAmpl::LOG_AMPL_DEBUG) + .value("INFO", VoltageInitializerLogLevelAmpl::LOG_AMPL_INFO) + .value("WARNING", VoltageInitializerLogLevelAmpl::LOG_AMPL_WARNING) + .value("ERROR", VoltageInitializerLogLevelAmpl::LOG_AMPL_ERROR); py::enum_(m, "VoltageInitializerLogLevelSolver") .value("NOTHING", VoltageInitializerLogLevelSolver::NOTHING) diff --git a/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java b/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java index f4ed6e184..372d32b1e 100644 --- a/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java +++ b/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java @@ -1282,10 +1282,10 @@ public enum VoltageInitializerObjective { @CEnum("VoltageInitializerLogLevelAmpl") public enum VoltageInitializerLogLevelAmpl { - DEBUG, - INFO, - WARNING, - ERROR; + LOG_AMPL_DEBUG, + LOG_AMPL_INFO, + LOG_AMPL_WARNING, + LOG_AMPL_ERROR; @CEnumValue public native int getCValue(); diff --git a/java/src/main/java/com/powsybl/python/commons/Util.java b/java/src/main/java/com/powsybl/python/commons/Util.java index 2693a9a1e..28e97d1b1 100644 --- a/java/src/main/java/com/powsybl/python/commons/Util.java +++ b/java/src/main/java/com/powsybl/python/commons/Util.java @@ -346,10 +346,10 @@ public static OpenReacOptimisationObjective convert(VoltageInitializerObjective public static OpenReacAmplLogLevel convert(VoltageInitializerLogLevelAmpl obj) { return switch (obj) { - case DEBUG -> OpenReacAmplLogLevel.DEBUG; - case INFO -> OpenReacAmplLogLevel.INFO; - case WARNING -> OpenReacAmplLogLevel.WARNING; - case ERROR -> OpenReacAmplLogLevel.ERROR; + case LOG_AMPL_DEBUG -> OpenReacAmplLogLevel.DEBUG; + case LOG_AMPL_INFO -> OpenReacAmplLogLevel.INFO; + case LOG_AMPL_WARNING -> OpenReacAmplLogLevel.WARNING; + case LOG_AMPL_ERROR -> OpenReacAmplLogLevel.ERROR; }; } From 493dbdc6f71d850fee6ab749be831722069f35a6 Mon Sep 17 00:00:00 2001 From: Coline Piloquet <55250145+colinepiloquet@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:30:35 +0200 Subject: [PATCH 35/45] Make pairing key of dangling lines updatable (#811) Signed-off-by: Coline PILOQUET --- .../com/powsybl/dataframe/network/NetworkDataframes.java | 2 +- pypowsybl/network/impl/network.py | 2 ++ tests/test_network.py | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java b/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java index 35d3777f6..7389f2e4f 100644 --- a/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java +++ b/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java @@ -603,7 +603,7 @@ static NetworkDataframeMapper danglingLines() { .strings("bus_breaker_bus_id", getBusBreakerViewBusId(), NetworkDataframes::setBusBreakerViewBusId, false) .ints("node", dl -> getNode(dl.getTerminal()), false) .booleans("connected", dl -> dl.getTerminal().isConnected(), connectInjection()) - .strings("pairing_key", dl -> Objects.toString(dl.getPairingKey(), "")) + .strings("pairing_key", dl -> Objects.toString(dl.getPairingKey(), ""), DanglingLine::setPairingKey) .strings("ucte_xnode_code", dl -> Objects.toString(dl.getPairingKey(), "")) .booleans("fictitious", Identifiable::isFictitious, Identifiable::setFictitious, false) .strings("tie_line_id", dl -> dl.getTieLine().map(Identifiable::getId).orElse("")) diff --git a/pypowsybl/network/impl/network.py b/pypowsybl/network/impl/network.py index f8a20914b..d5869e010 100644 --- a/pypowsybl/network/impl/network.py +++ b/pypowsybl/network/impl/network.py @@ -2584,6 +2584,8 @@ def update_dangling_lines(self, df: DataFrame = None, **kwargs: ArrayLike) -> No - `q` - `connected` - `fictitious` + - `pairing_key` + - `bus_breaker_bus_id` if the dangling line is in a voltage level with `BUS_BREAKER` topology See Also: :meth:`get_dangling_lines` diff --git a/tests/test_network.py b/tests/test_network.py index 1dba0a891..a829ef23c 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -2092,6 +2092,12 @@ def test_nad_parameters(): assert nad_parameters.radius_factor == 120.0 assert nad_parameters.edge_info_displayed == EdgeInfoType.CURRENT +def test_update_dangling_line(): + network = pp.network.create_eurostag_tutorial_example1_network() + network.create_dangling_lines(id='dangling_line', voltage_level_id='VLGEN', bus_id='NGEN', p0=100, q0=100, r=0, x=0, g=0, b=0) + network.update_dangling_lines(id=['dangling_line'], pairing_key=['XNODE']) + assert network.get_dangling_lines().loc['dangling_line'].pairing_key == 'XNODE' + if __name__ == '__main__': unittest.main() From eb1661ec2bc31a0df1d677653659bfe33ee05750 Mon Sep 17 00:00:00 2001 From: Choco <97348238+unetablettedechocolat@users.noreply.github.com> Date: Wed, 31 Jul 2024 10:29:33 +0200 Subject: [PATCH 36/45] Display units feeder info (#799) Signed-off-by: Tiphaine Mouminous --- cpp/powsybl-cpp/powsybl-api.h | 3 + cpp/powsybl-cpp/powsybl-cpp.cpp | 6 + cpp/powsybl-cpp/powsybl-cpp.h | 3 + cpp/pypowsybl-cpp/bindings.cpp | 5 +- .../ieee14_SldParam_activepowerunit.svg | 364 ++++++++++++++++ .../images/ieee14_SldParam_currentunit.svg | 394 ++++++++++++++++++ .../ieee14_SldParam_reactivepowerunit.svg | 364 ++++++++++++++++ docs/user_guide/network_visualization.rst | 52 ++- .../python/commons/PyPowsyblApiHeader.java | 19 + .../python/network/NetworkCFunctions.java | 9 +- pypowsybl/_pypowsybl.pyi | 3 + pypowsybl/network/impl/sld_parameters.py | 24 +- tests/test_network.py | 9 +- 13 files changed, 1241 insertions(+), 14 deletions(-) create mode 100644 docs/_static/images/ieee14_SldParam_activepowerunit.svg create mode 100644 docs/_static/images/ieee14_SldParam_currentunit.svg create mode 100644 docs/_static/images/ieee14_SldParam_reactivepowerunit.svg diff --git a/cpp/powsybl-cpp/powsybl-api.h b/cpp/powsybl-cpp/powsybl-api.h index aa86e00a6..399677322 100644 --- a/cpp/powsybl-cpp/powsybl-api.h +++ b/cpp/powsybl-cpp/powsybl-api.h @@ -342,6 +342,9 @@ typedef struct sld_parameters_struct { unsigned char topological_coloring; char* component_library; unsigned char display_current_feeder_info; + char* active_power_unit; + char* reactive_power_unit; + char* current_unit; } sld_parameters; typedef struct nad_parameters_struct { diff --git a/cpp/powsybl-cpp/powsybl-cpp.cpp b/cpp/powsybl-cpp/powsybl-cpp.cpp index f1bc03325..4930eba5d 100644 --- a/cpp/powsybl-cpp/powsybl-cpp.cpp +++ b/cpp/powsybl-cpp/powsybl-cpp.cpp @@ -1200,6 +1200,9 @@ SldParameters::SldParameters(sld_parameters* src) { topological_coloring = (bool) src->topological_coloring; component_library = toString(src->component_library); display_current_feeder_info = (bool) src->display_current_feeder_info; + active_power_unit = toString(src->active_power_unit); + reactive_power_unit = toString(src->reactive_power_unit); + current_unit = toString(src->current_unit); } NadParameters::NadParameters(nad_parameters* src) { @@ -1227,6 +1230,9 @@ void SldParameters::sld_to_c_struct(sld_parameters& res) const { res.topological_coloring = (unsigned char) topological_coloring; res.component_library = copyStringToCharPtr(component_library); res.display_current_feeder_info = (unsigned char) display_current_feeder_info; + res.active_power_unit = copyStringToCharPtr(active_power_unit); + res.reactive_power_unit = copyStringToCharPtr(reactive_power_unit); + res.current_unit = copyStringToCharPtr(current_unit); } void NadParameters::nad_to_c_struct(nad_parameters& res) const { diff --git a/cpp/powsybl-cpp/powsybl-cpp.h b/cpp/powsybl-cpp/powsybl-cpp.h index 8fdcc2b3d..2e6e93020 100644 --- a/cpp/powsybl-cpp/powsybl-cpp.h +++ b/cpp/powsybl-cpp/powsybl-cpp.h @@ -394,6 +394,9 @@ class SldParameters { bool topological_coloring; std::string component_library; bool display_current_feeder_info; + std::string active_power_unit; + std::string reactive_power_unit; + std::string current_unit; }; enum class NadLayoutType { diff --git a/cpp/pypowsybl-cpp/bindings.cpp b/cpp/pypowsybl-cpp/bindings.cpp index ee7034447..3a6219c70 100644 --- a/cpp/pypowsybl-cpp/bindings.cpp +++ b/cpp/pypowsybl-cpp/bindings.cpp @@ -548,7 +548,10 @@ PYBIND11_MODULE(_pypowsybl, m) { .def_readwrite("tooltip_enabled", &pypowsybl::SldParameters::tooltip_enabled) .def_readwrite("topological_coloring", &pypowsybl::SldParameters::topological_coloring) .def_readwrite("component_library", &pypowsybl::SldParameters::component_library) - .def_readwrite("display_current_feeder_info", &pypowsybl::SldParameters::display_current_feeder_info); + .def_readwrite("display_current_feeder_info", &pypowsybl::SldParameters::display_current_feeder_info) + .def_readwrite("active_power_unit", &pypowsybl::SldParameters::active_power_unit) + .def_readwrite("reactive_power_unit", &pypowsybl::SldParameters::reactive_power_unit) + .def_readwrite("current_unit", &pypowsybl::SldParameters::current_unit); py::enum_(m, "NadLayoutType") .value("FORCE_LAYOUT", pypowsybl::NadLayoutType::FORCE_LAYOUT) diff --git a/docs/_static/images/ieee14_SldParam_activepowerunit.svg b/docs/_static/images/ieee14_SldParam_activepowerunit.svg new file mode 100644 index 000000000..bba403129 --- /dev/null +++ b/docs/_static/images/ieee14_SldParam_activepowerunit.svg @@ -0,0 +1,364 @@ + + + + + + + + B4 + + + + + + + + + + + + + + + 48 MW + + + + + -4 + + + + + + + + + + + + + + + B4-L + + + + + + + + + + + + + + + + 3 + + + + + -54 MW + + + + + + + + + + + + L2-4-1 + + + + + + + + + + + + + + + + 24 MW + + + + + -5 + + + + + + + + + + + + L3-4-1 + + + + + + + + + + + + + + + + 16 + + + + + -61 MW + + + + + + + + + + + + L4-5-1 + + + + + + + + + + + + + + + + 28 MW + + + + + -10 + + + + + + + + + + + + + + T4-7-1 + + + + + + + + + + + + + + + + -0 + + + + + 16 MW + + + + + + + + + + + + + + T4-9-1 + + + + diff --git a/docs/_static/images/ieee14_SldParam_currentunit.svg b/docs/_static/images/ieee14_SldParam_currentunit.svg new file mode 100644 index 000000000..f26f7c180 --- /dev/null +++ b/docs/_static/images/ieee14_SldParam_currentunit.svg @@ -0,0 +1,394 @@ + + + + + + + + B4 + + + + + + + + + + + + + + + 48 + + + + + -4 + + + + + 202 A + + + + + + + + + + + + + + + B4-L + + + + + + + + + + + + + + + + 229 A + + + + + 3 + + + + + -54 + + + + + + + + + + + + L2-4-1 + + + + + + + + + + + + + + + + 24 + + + + + -5 + + + + + 101 A + + + + + + + + + + + + L3-4-1 + + + + + + + + + + + + + + + + 265 A + + + + + 16 + + + + + -61 + + + + + + + + + + + + L4-5-1 + + + + + + + + + + + + + + + + 28 + + + + + -10 + + + + + 125 A + + + + + + + + + + + + + + T4-7-1 + + + + + + + + + + + + + + + + 68 A + + + + + -0 + + + + + 16 + + + + + + + + + + + + + + T4-9-1 + + + + diff --git a/docs/_static/images/ieee14_SldParam_reactivepowerunit.svg b/docs/_static/images/ieee14_SldParam_reactivepowerunit.svg new file mode 100644 index 000000000..4bb779231 --- /dev/null +++ b/docs/_static/images/ieee14_SldParam_reactivepowerunit.svg @@ -0,0 +1,364 @@ + + + + + + + + B4 + + + + + + + + + + + + + + + 48 + + + + + -4 MVAR + + + + + + + + + + + + + + + B4-L + + + + + + + + + + + + + + + + 3 MVAR + + + + + -54 + + + + + + + + + + + + L2-4-1 + + + + + + + + + + + + + + + + 24 + + + + + -5 MVAR + + + + + + + + + + + + L3-4-1 + + + + + + + + + + + + + + + + 16 MVAR + + + + + -61 + + + + + + + + + + + + L4-5-1 + + + + + + + + + + + + + + + + 28 + + + + + -10 MVAR + + + + + + + + + + + + + + T4-7-1 + + + + + + + + + + + + + + + + -0 MVAR + + + + + 16 + + + + + + + + + + + + + + T4-9-1 + + + + diff --git a/docs/user_guide/network_visualization.rst b/docs/user_guide/network_visualization.rst index 0bfa25182..44b7760ae 100644 --- a/docs/user_guide/network_visualization.rst +++ b/docs/user_guide/network_visualization.rst @@ -34,8 +34,7 @@ Single-line diagrams can be customized through SldParameters: >>> network = pp.network.create_ieee14() >>> result = pp.loadflow.run_ac(network) - >>> network.get_single_line_diagram('VL4',parameters = pp.network.SldParameters(use_name = False, center_name = False, diagonal_label = False, nodes_infos = False, tooltip_enabled = False, topological_coloring = True, component_library = 'Convergence', display_current_feeder_info = False)) - + >>> network.get_single_line_diagram('VL4',parameters = pp.network.SldParameters(use_name = False, center_name = False, diagonal_label = False, nodes_infos = False, tooltip_enabled = False, topological_coloring = True, component_library = 'Convergence')) - use_name: if true, display components names instead of their id (default value false) - center_name: if true, center the names of feeders (default value false) @@ -44,6 +43,9 @@ Single-line diagrams can be customized through SldParameters: - tooltip_enabled: if true, display the name of the component pointed by the cursor (default value false) - topological_coloring: if true, set each electrical nodes with a different colour (default value true) - component_library: choose component library (default value 'Convergence') +- active_power_unit: display unit of active power (default value "") +- reactive_power_unit: display unit of reactive power (default value "") +- current_unit: display unit of current (default value "") - display_current_feeder_info: if true, display current feeder value (default value False) @@ -60,7 +62,7 @@ Let's see some examples down below: .. image:: ../_static/images/ieee14_SldParam_default.svg :class: forced-white-background -- with use_name = true +- with use_name = True .. code-block:: python @@ -70,7 +72,7 @@ Let's see some examples down below: .. image:: ../_static/images/ieee14_SldParam_usename.svg :class: forced-white-background -- with center_name = true +- with center_name = True .. code-block:: python @@ -80,7 +82,7 @@ Let's see some examples down below: .. image:: ../_static/images/ieee14_SldParam_centername.svg :class: forced-white-background -- with diagonal_label = true +- with diagonal_label = True .. code-block:: python @@ -90,7 +92,7 @@ Let's see some examples down below: .. image:: ../_static/images/ieee14_SldParam_diagonallabel.svg :class: forced-white-background -- with nodes_infos = true +- with nodes_infos = True .. code-block:: python @@ -100,7 +102,7 @@ Let's see some examples down below: .. image:: ../_static/images/ieee14_SldParam_nodesinfos.svg :class: forced-white-background -- with tooltip enabled +- with tooltip_enabled = True .. code-block:: python @@ -110,7 +112,7 @@ Let's see some examples down below: .. image:: ../_static/images/ieee14_SldParam_tooltipenabledtrue.png :class: forced-white-background -- with topological coloring = true +- with topological_coloring = True .. code-block:: python @@ -122,7 +124,7 @@ Let's see some examples down below: .. image:: ../_static/images/SldParam_topologicalcoloringtrue.svg :class: forced-white-background -- with topological coloring = false +- with topological_coloring = False .. code-block:: python @@ -143,7 +145,7 @@ Let's see some examples down below: .. image:: ../_static/images/ieee14_SldParam_complib_flatdesign.svg :class: forced-white-background -- with display current feeder info +- with display_current_feeder_info = True .. code-block:: python @@ -153,6 +155,36 @@ Let's see some examples down below: .. image:: ../_static/images/ieee14_SldParam_displaycurrentfeederinfo.svg :class: forced-white-background +- with active_power_unit = "MW" + +.. code-block:: python + + >>> param = pn.SldParameters(active_power_unit = "MW") + >>> network.get_single_line_diagram('VL4', parameters = param) + +.. image:: ../_static/images/ieee14_SldParam_activepowerunit.svg + :class: forced-white-background + +- with reactive_power_unit = "MVAR" + +.. code-block:: python + + >>> param = pn.SldParameters(reactive_power_unit = "MVAR") + >>> network.get_single_line_diagram('VL4', parameters = param) + +.. image:: ../_static/images/ieee14_SldParam_reactivepowerunit.svg + :class: forced-white-background + + +- with current_unit = "A" + +.. code-block:: python + + >>> param = pn.SldParameters(display_current_feeder_info = True, current_unit = "A") + >>> network.get_single_line_diagram('VL4', parameters = param) + +.. image:: ../_static/images/ieee14_SldParam_currentunit.svg + :class: forced-white-background It is also possible to display a multi-substation single line diagram (currently a beta feature): diff --git a/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java b/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java index 372d32b1e..0b4b72f95 100644 --- a/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java +++ b/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java @@ -1074,6 +1074,25 @@ public interface SldParametersPointer extends PointerBase { @CField("display_current_feeder_info") void setDisplayCurrentFeederInfo(boolean displayCurrentInfo); + + @CField("active_power_unit") + CCharPointer getActivePowerUnit(); + + @CField("active_power_unit") + void setActivePowerUnit(CCharPointer activePowerUnit); + + @CField("reactive_power_unit") + CCharPointer getReactivePowerUnit(); + + @CField("reactive_power_unit") + void setReactivePowerUnit(CCharPointer reactivePowerUnit); + + @CField("current_unit") + CCharPointer getCurrentUnit(); + + @CField("current_unit") + void setCurrentUnit(CCharPointer currentUnit); + } @CStruct("nad_parameters") diff --git a/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java b/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java index 0acdd1c98..d37b946c6 100644 --- a/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java +++ b/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java @@ -879,6 +879,9 @@ public static void copyToCSldParameters(SldParameters parameters, SldParametersP cParameters.setTooltipEnabled(parameters.getSvgParameters().isTooltipEnabled()); cParameters.setComponentLibrary(CTypeUtil.toCharPtr(parameters.getComponentLibrary().getName())); cParameters.setDisplayCurrentFeederInfo(parameters.getSvgParameters().isDisplayCurrentFeederInfo()); + cParameters.setActivePowerUnit(CTypeUtil.toCharPtr(parameters.getSvgParameters().getActivePowerUnit())); + cParameters.setReactivePowerUnit(CTypeUtil.toCharPtr(parameters.getSvgParameters().getReactivePowerUnit())); + cParameters.setCurrentUnit(CTypeUtil.toCharPtr(parameters.getSvgParameters().getCurrentUnit())); } public static SldParametersPointer convertToSldParametersPointer(SldParameters parameters) { @@ -954,7 +957,11 @@ public static SldParameters convertSldParameters(SldParametersPointer sldParamet .setLabelDiagonal(sldParametersPtr.isDiagonalLabel()) .setAddNodesInfos(sldParametersPtr.isAddNodesInfos()) .setTooltipEnabled(sldParametersPtr.getTooltipEnabled()) - .setDisplayCurrentFeederInfo(sldParametersPtr.isDisplayCurrentFeederInfo()); + .setDisplayCurrentFeederInfo(sldParametersPtr.isDisplayCurrentFeederInfo()) + .setTooltipEnabled(sldParametersPtr.getTooltipEnabled()) + .setActivePowerUnit(CTypeUtil.toString(sldParametersPtr.getActivePowerUnit())) + .setReactivePowerUnit(CTypeUtil.toString(sldParametersPtr.getReactivePowerUnit())) + .setCurrentUnit(CTypeUtil.toString(sldParametersPtr.getCurrentUnit())); return sldParameters; } diff --git a/pypowsybl/_pypowsybl.pyi b/pypowsybl/_pypowsybl.pyi index 2f0a1e7e9..b3ed28dd7 100644 --- a/pypowsybl/_pypowsybl.pyi +++ b/pypowsybl/_pypowsybl.pyi @@ -267,6 +267,9 @@ class SldParameters: topological_coloring: bool component_library: str display_current_feeder_info: bool + active_power_unit: str + reactive_power_unit: str + current_unit: str def __init__(self) -> None: ... class NadLayoutType: diff --git a/pypowsybl/network/impl/sld_parameters.py b/pypowsybl/network/impl/sld_parameters.py index 1083d5837..6a4283ce6 100644 --- a/pypowsybl/network/impl/sld_parameters.py +++ b/pypowsybl/network/impl/sld_parameters.py @@ -13,7 +13,8 @@ class SldParameters: def __init__(self, use_name: bool = False, center_name: bool = False, diagonal_label: bool = False, nodes_infos: bool = False, tooltip_enabled: bool = False, topological_coloring: bool = True, - component_library: str = 'Convergence', display_current_feeder_info: bool = False): + component_library: str = 'Convergence', display_current_feeder_info: bool = False, + active_power_unit: str = "", reactive_power_unit: str = "", current_unit: str = ""): self._use_name = use_name self._center_name = center_name self._diagonal_label = diagonal_label @@ -22,6 +23,9 @@ def __init__(self, use_name: bool = False, center_name: bool = False, diagonal_l self._topological_coloring = topological_coloring self._component_library = component_library self._display_current_feeder_info = display_current_feeder_info + self._active_power_unit = active_power_unit + self._reactive_power_unit = reactive_power_unit + self._current_unit = current_unit @property def use_name(self) -> bool: @@ -63,6 +67,21 @@ def display_current_feeder_info(self) -> bool: """when True display current feeder info""" return self._display_current_feeder_info + @property + def active_power_unit(self) -> str: + """unit of active power""" + return self._active_power_unit + + @property + def reactive_power_unit(self) -> str: + """unit of reactive power""" + return self._reactive_power_unit + + @property + def current_unit(self) -> str: + """unit of current""" + return self._current_unit + def _to_c_parameters(self) -> _pp.SldParameters: c_parameters = _pp.SldParameters() c_parameters.use_name = self._use_name @@ -73,4 +92,7 @@ def _to_c_parameters(self) -> _pp.SldParameters: c_parameters.tooltip_enabled = self._tooltip_enabled c_parameters.component_library = self._component_library c_parameters.display_current_feeder_info = self._display_current_feeder_info + c_parameters.active_power_unit = self._active_power_unit + c_parameters.reactive_power_unit = self._reactive_power_unit + c_parameters.current_unit = self._current_unit return c_parameters diff --git a/tests/test_network.py b/tests/test_network.py index a829ef23c..fcec7ccfb 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -785,10 +785,14 @@ def test_sld_parameters(): assert not parameters.display_current_feeder_info assert parameters.topological_coloring assert parameters.component_library == 'Convergence' + assert parameters.active_power_unit == "" + assert parameters.reactive_power_unit == "" + assert parameters.current_unit == "" parameters = SldParameters(use_name=True, center_name=True, diagonal_label=True, nodes_infos=True, tooltip_enabled=True, topological_coloring=False, - component_library='FlatDesign', display_current_feeder_info=True) + component_library='FlatDesign', display_current_feeder_info=True, + active_power_unit='a', reactive_power_unit='b', current_unit='c') assert parameters.use_name assert parameters.center_name assert parameters.diagonal_label @@ -797,6 +801,9 @@ def test_sld_parameters(): assert parameters.display_current_feeder_info assert not parameters.topological_coloring assert parameters.component_library == 'FlatDesign' + assert parameters.active_power_unit == 'a' + assert parameters.reactive_power_unit == 'b' + assert parameters.current_unit == 'c' def test_layout_parameters(): From e3fd8f2a1f9fc519692ff1dd6169fe7e116b31a4 Mon Sep 17 00:00:00 2001 From: Christian Biasuzzi Date: Wed, 31 Jul 2024 10:49:54 +0200 Subject: [PATCH 37/45] Allows empty strings in the multi-substation SLD functions' matrix parameter (#806) Signed-off-by: Christian Biasuzzi --- docs/user_guide/network_visualization.rst | 1 + .../python/network/SingleLineDiagramUtil.java | 3 ++- .../python/network/SingleLineDiagramUtilTest.java | 12 ++++++++++++ tests/test_network.py | 4 ++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/user_guide/network_visualization.rst b/docs/user_guide/network_visualization.rst index 44b7760ae..058751883 100644 --- a/docs/user_guide/network_visualization.rst +++ b/docs/user_guide/network_visualization.rst @@ -203,6 +203,7 @@ Or in a Jupyter Notebook: >>> network.get_matrix_multi_substation_single_line_diagram([['S1', 'S2'],['S3','S4']]) +The substation diagrams will be arranged in a grid, based on the content of the matrix parameter. An empty string in the matrix will result in an empty spot in the grid. Network area diagram -------------------- diff --git a/java/src/main/java/com/powsybl/python/network/SingleLineDiagramUtil.java b/java/src/main/java/com/powsybl/python/network/SingleLineDiagramUtil.java index 998a73801..a2891dfb1 100644 --- a/java/src/main/java/com/powsybl/python/network/SingleLineDiagramUtil.java +++ b/java/src/main/java/com/powsybl/python/network/SingleLineDiagramUtil.java @@ -21,6 +21,7 @@ import java.nio.file.Paths; import java.util.Arrays; import java.util.List; +import java.util.function.Predicate; /** * @author Geoffroy Jamgotchian {@literal } @@ -96,7 +97,7 @@ static void writeSvg(Network network, String containerId, Writer writer, Writer static void writeMatrixMultiSubstationSvg(Network network, String[][] matrixIds, Writer writer, Writer metadataWriter, SldParameters sldParameters) { sldParameters.setZoneLayoutFactory(new MatrixZoneLayoutFactory(matrixIds)); - List substationIds = Arrays.stream(matrixIds).flatMap(Arrays::stream).toList(); + List substationIds = Arrays.stream(matrixIds).flatMap(Arrays::stream).filter(Predicate.not(String::isEmpty)).toList(); SingleLineDiagram.drawMultiSubstations(network, substationIds, writer, metadataWriter, sldParameters); } diff --git a/java/src/test/java/com/powsybl/python/network/SingleLineDiagramUtilTest.java b/java/src/test/java/com/powsybl/python/network/SingleLineDiagramUtilTest.java index 8cf88d28e..8b7515a3b 100644 --- a/java/src/test/java/com/powsybl/python/network/SingleLineDiagramUtilTest.java +++ b/java/src/test/java/com/powsybl/python/network/SingleLineDiagramUtilTest.java @@ -47,4 +47,16 @@ void testSvgAndMetadata() throws IOException { TestUtil.normalizeLineSeparator(svgAndMeta.get(0))); assertFalse(svgAndMeta.get(1).isEmpty()); } + + @Test + void testWriteMatrixMultiSubstationSvg() throws IOException { + Network network = FourSubstationsNodeBreakerFactory.create(); + SldParameters sldParameters = SingleLineDiagramUtil.createSldParameters(); + String[][] matrixIds = {{"S1", "" }, {"", "S2"}}; + try (StringWriter writer = new StringWriter(); StringWriter writerMeta = new StringWriter()) { + SingleLineDiagramUtil.writeMatrixMultiSubstationSvg(network, matrixIds, writer, writerMeta, sldParameters); + assertFalse(writer.toString().isEmpty()); + assertFalse(writerMeta.toString().isEmpty()); + } + } } diff --git a/tests/test_network.py b/tests/test_network.py index fcec7ccfb..f2d6b3278 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -863,6 +863,10 @@ def test_sld_svg(): assert re.search('.* 0 + sld_multi_substation5 = n.get_matrix_multi_substation_single_line_diagram([['S1', ''], ['', 'S2']]) + assert re.search('.* 0 + def test_sld_svg_backward_compatibility(): n = pp.network.create_four_substations_node_breaker_network() sld = n.get_single_line_diagram('S1VL1', LayoutParameters(use_name=True, center_name=True, diagonal_label=True, From 21c71f81dd096704d4e85ba8f84ef5e9cb00639b Mon Sep 17 00:00:00 2001 From: Coline Piloquet <55250145+colinepiloquet@users.noreply.github.com> Date: Wed, 31 Jul 2024 14:49:16 +0200 Subject: [PATCH 38/45] Add initial voltage plan parameter for short-circuit analysis (#809) Signed-off-by: Etienne LESOT Signed-off-by: Coline PILOQUET --- cpp/powsybl-cpp/powsybl-api.h | 3 ++- cpp/powsybl-cpp/powsybl-cpp.cpp | 2 ++ cpp/powsybl-cpp/powsybl-cpp.h | 6 ++++++ cpp/pypowsybl-cpp/bindings.cpp | 7 +++++++ docs/user_guide/shortcircuit.rst | 3 +++ .../powsybl/python/commons/PyPowsyblApiHeader.java | 6 ++++++ .../ShortCircuitAnalysisCFunctions.java | 1 + .../shortcircuit/ShortCircuitAnalysisCUtils.java | 2 ++ pypowsybl/_pypowsybl.pyi | 6 ++++++ pypowsybl/shortcircuit/__init__.py | 2 +- pypowsybl/shortcircuit/impl/parameters.py | 14 ++++++++++++-- tests/test_shortcircuit_analysis.py | 4 +++- 12 files changed, 51 insertions(+), 5 deletions(-) diff --git a/cpp/powsybl-cpp/powsybl-api.h b/cpp/powsybl-cpp/powsybl-api.h index 399677322..da1613bf5 100644 --- a/cpp/powsybl-cpp/powsybl-api.h +++ b/cpp/powsybl-cpp/powsybl-api.h @@ -388,6 +388,7 @@ typedef struct shortcircuit_analysis_parameters_struct { int study_type; unsigned char with_fortescue_result; double min_voltage_drop_proportional_threshold; + int initial_voltage_profile_mode; char** provider_parameters_keys; int provider_parameters_keys_count; char** provider_parameters_values; @@ -422,4 +423,4 @@ typedef enum { CONFIGURED = 0, NO_GENERATION, ALL_BUSES, -} VoltageInitializerReactiveSlackBusesMode; \ No newline at end of file +} VoltageInitializerReactiveSlackBusesMode; diff --git a/cpp/powsybl-cpp/powsybl-cpp.cpp b/cpp/powsybl-cpp/powsybl-cpp.cpp index 4930eba5d..e6da30fd2 100644 --- a/cpp/powsybl-cpp/powsybl-cpp.cpp +++ b/cpp/powsybl-cpp/powsybl-cpp.cpp @@ -1381,6 +1381,7 @@ ShortCircuitAnalysisParameters::ShortCircuitAnalysisParameters(shortcircuit_anal with_fortescue_result = (bool) src->with_fortescue_result; with_voltage_result = (bool) src->with_voltage_result; min_voltage_drop_proportional_threshold = (double) src->min_voltage_drop_proportional_threshold; + initial_voltage_profile_mode = static_cast(src->initial_voltage_profile_mode); copyCharPtrPtrToVector(src->provider_parameters_keys, src->provider_parameters_keys_count, provider_parameters_keys); copyCharPtrPtrToVector(src->provider_parameters_values, src->provider_parameters_values_count, provider_parameters_values); @@ -1394,6 +1395,7 @@ std::shared_ptr ShortCircuitAnalysisParameters res->study_type = study_type; res->with_fortescue_result = (bool) with_fortescue_result; res->min_voltage_drop_proportional_threshold = min_voltage_drop_proportional_threshold; + res->initial_voltage_profile_mode = initial_voltage_profile_mode; res->provider_parameters_keys = pypowsybl::copyVectorStringToCharPtrPtr(provider_parameters_keys); res->provider_parameters_keys_count = provider_parameters_keys.size(); diff --git a/cpp/powsybl-cpp/powsybl-cpp.h b/cpp/powsybl-cpp/powsybl-cpp.h index 2e6e93020..8b7e4b51a 100644 --- a/cpp/powsybl-cpp/powsybl-cpp.h +++ b/cpp/powsybl-cpp/powsybl-cpp.h @@ -438,6 +438,11 @@ enum ShortCircuitStudyType { STEADY_STATE }; +enum InitialVoltageProfileMode { + NOMINAL = 0, + PREVIOUS_VALUE +}; + class ShortCircuitAnalysisParameters { public: ShortCircuitAnalysisParameters(shortcircuit_analysis_parameters* src); @@ -449,6 +454,7 @@ class ShortCircuitAnalysisParameters { ShortCircuitStudyType study_type; bool with_fortescue_result; double min_voltage_drop_proportional_threshold; + InitialVoltageProfileMode initial_voltage_profile_mode; std::vector provider_parameters_keys; std::vector provider_parameters_values; diff --git a/cpp/pypowsybl-cpp/bindings.cpp b/cpp/pypowsybl-cpp/bindings.cpp index 3a6219c70..968b63df7 100644 --- a/cpp/pypowsybl-cpp/bindings.cpp +++ b/cpp/pypowsybl-cpp/bindings.cpp @@ -996,6 +996,12 @@ PYBIND11_MODULE(_pypowsybl, m) { m.def("create_network_modification", ::createNetworkModificationBind, "Create and apply network modification", py::arg("network"), py::arg("dataframe"), py::arg("network_modification_type"), py::arg("raise_exception"), py::arg("report_node")); + py::enum_(m, "InitialVoltageProfileMode", "configure the voltage profile to use for the short-circuit study") + .value("NOMINAL", pypowsybl::InitialVoltageProfileMode::NOMINAL, + "Nominal voltages are used for the calculation.") + .value("PREVIOUS_VALUE", pypowsybl::InitialVoltageProfileMode::PREVIOUS_VALUE, + "Voltage profile calculated by the load flow is used for the calculation."); + py::enum_(m, "ShortCircuitStudyType", "Indicates the type of short circuit study") .value("SUB_TRANSIENT", pypowsybl::ShortCircuitStudyType::SUB_TRANSIENT, "It is the first stage of the short circuit, right when the fault happens. The subtransient reactance of generators will be used.") @@ -1012,6 +1018,7 @@ PYBIND11_MODULE(_pypowsybl, m) { .def_readwrite("study_type", &pypowsybl::ShortCircuitAnalysisParameters::study_type) .def_readwrite("with_fortescue_result", &pypowsybl::ShortCircuitAnalysisParameters::with_fortescue_result) .def_readwrite("min_voltage_drop_proportional_threshold", &pypowsybl::ShortCircuitAnalysisParameters::min_voltage_drop_proportional_threshold) + .def_readwrite("initial_voltage_profile_mode", &pypowsybl::ShortCircuitAnalysisParameters::initial_voltage_profile_mode) .def_readwrite("provider_parameters_keys", &pypowsybl::ShortCircuitAnalysisParameters::provider_parameters_keys) .def_readwrite("provider_parameters_values", &pypowsybl::ShortCircuitAnalysisParameters::provider_parameters_values); diff --git a/docs/user_guide/shortcircuit.rst b/docs/user_guide/shortcircuit.rst index 246524f23..793096780 100644 --- a/docs/user_guide/shortcircuit.rst +++ b/docs/user_guide/shortcircuit.rst @@ -41,6 +41,9 @@ The parameters available to run a shortcircuit analysis are: - min_voltage_drop_proportional_threshold: specifies a threshold for filtering the voltage results. Only nodes where the voltage drop due to the short circuit is greater than this property are retained. - study_type: specifies the type of short circuit study. It can be SUB_TRANSIENT, TRANSIENT or STEADY_STATE. + - initial_voltage_profile_mode: specifies the voltage profile to be used for the calculation. It can be either + `NOMINAL`, in which case the nominal voltages are used, or `PREVIOUS_VALUE`, in which case the calculated voltages + are used. +----------------------------------------+---------------+ diff --git a/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java b/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java index 0b4b72f95..ba29af752 100644 --- a/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java +++ b/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java @@ -1261,6 +1261,12 @@ public interface ShortCircuitAnalysisParametersPointer extends PointerBase { @CField("min_voltage_drop_proportional_threshold") void setMinVoltageDropProportionalThreshold(double minVoltageDropProportionalThreshold); + @CField("initial_voltage_profile_mode") + int getInitialVoltageProfileMode(); + + @CField("initial_voltage_profile_mode") + void setInitialVoltageProfileMode(int initialVoltageProfileMode); + @CField("provider_parameters_keys") void setProviderParametersKeys(CCharPointerPointer providerParametersKeys); diff --git a/java/src/main/java/com/powsybl/python/shortcircuit/ShortCircuitAnalysisCFunctions.java b/java/src/main/java/com/powsybl/python/shortcircuit/ShortCircuitAnalysisCFunctions.java index f39849b7c..1d3087b7f 100644 --- a/java/src/main/java/com/powsybl/python/shortcircuit/ShortCircuitAnalysisCFunctions.java +++ b/java/src/main/java/com/powsybl/python/shortcircuit/ShortCircuitAnalysisCFunctions.java @@ -124,6 +124,7 @@ private static ShortCircuitAnalysisParametersPointer convertToShortCircuitAnalys paramsPtr.setWithFortescueResult(parameters.isWithFortescueResult()); paramsPtr.setMinVoltageDropProportionalThreshold(parameters.getMinVoltageDropProportionalThreshold()); paramsPtr.setStudyType(parameters.getStudyType().ordinal()); + paramsPtr.setInitialVoltageProfileMode(parameters.getInitialVoltageProfileMode().ordinal()); paramsPtr.setProviderParametersValuesCount(0); paramsPtr.setProviderParametersKeysCount(0); return paramsPtr; diff --git a/java/src/main/java/com/powsybl/python/shortcircuit/ShortCircuitAnalysisCUtils.java b/java/src/main/java/com/powsybl/python/shortcircuit/ShortCircuitAnalysisCUtils.java index 0402ab66d..b7edd8bb4 100644 --- a/java/src/main/java/com/powsybl/python/shortcircuit/ShortCircuitAnalysisCUtils.java +++ b/java/src/main/java/com/powsybl/python/shortcircuit/ShortCircuitAnalysisCUtils.java @@ -12,6 +12,7 @@ import com.powsybl.python.commons.CTypeUtil; import com.powsybl.python.commons.PyPowsyblApiHeader; import com.powsybl.python.commons.PyPowsyblConfiguration; +import com.powsybl.shortcircuit.InitialVoltageProfileMode; import com.powsybl.shortcircuit.ShortCircuitAnalysisProvider; import com.powsybl.shortcircuit.ShortCircuitParameters; import com.powsybl.shortcircuit.StudyType; @@ -61,6 +62,7 @@ private static ShortCircuitParameters createShortCircuitAnalysisParameters(PyPow .setWithFortescueResult(shortCircuitAnalysisParametersPointer.isWithFortescueResult()) .setWithLimitViolations(shortCircuitAnalysisParametersPointer.isWithLimitViolations()) .setMinVoltageDropProportionalThreshold(shortCircuitAnalysisParametersPointer.getMinVoltageDropProportionalThreshold()) + .setInitialVoltageProfileMode(InitialVoltageProfileMode.values()[shortCircuitAnalysisParametersPointer.getInitialVoltageProfileMode()]) .setStudyType(StudyType.values()[shortCircuitAnalysisParametersPointer.getStudyType()]); } diff --git a/pypowsybl/_pypowsybl.pyi b/pypowsybl/_pypowsybl.pyi index b3ed28dd7..7fbf6ccf4 100644 --- a/pypowsybl/_pypowsybl.pyi +++ b/pypowsybl/_pypowsybl.pyi @@ -705,6 +705,11 @@ class ShortCircuitStudyType: TRANSIENT: ClassVar[ShortCircuitStudyType] = ... STEADY_STATE: ClassVar[ShortCircuitStudyType] = ... +class InitialVoltageProfileMode: + __members__: ClassVar[Dict[str, InitialVoltageProfileMode]] = ... # read-only + NOMINAL: ClassVar[InitialVoltageProfileMode] = ... + PREVIOUS_VALUE: ClassVar[InitialVoltageProfileMode] = ... + class ShortCircuitAnalysisParameters: with_voltage_result: bool with_feeder_result: bool @@ -714,6 +719,7 @@ class ShortCircuitAnalysisParameters: min_voltage_drop_proportional_threshold: float provider_parameters_keys: List[str] provider_parameters_values: List[str] + initial_voltage_profile_mode: InitialVoltageProfileMode def __init__(self) -> None: ... def add_contingency(analysis_context: JavaHandle, contingency_id: str, elements_ids: List[str]) -> None: ... diff --git a/pypowsybl/shortcircuit/__init__.py b/pypowsybl/shortcircuit/__init__.py index a6c5ccb6d..656b829b4 100644 --- a/pypowsybl/shortcircuit/__init__.py +++ b/pypowsybl/shortcircuit/__init__.py @@ -4,7 +4,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. # SPDX-License-Identifier: MPL-2.0 # -from .impl.parameters import Parameters, ShortCircuitStudyType +from .impl.parameters import Parameters, ShortCircuitStudyType, InitialVoltageProfileMode from .impl.short_circuit_analysis import ShortCircuitAnalysis from .impl.short_circuit_analysis_result import ShortCircuitAnalysisResult from .impl.util import (create_analysis, diff --git a/pypowsybl/shortcircuit/impl/parameters.py b/pypowsybl/shortcircuit/impl/parameters.py index ab4ec7e16..26713f77e 100644 --- a/pypowsybl/shortcircuit/impl/parameters.py +++ b/pypowsybl/shortcircuit/impl/parameters.py @@ -7,10 +7,12 @@ from typing import Dict from pypowsybl import _pypowsybl -from pypowsybl._pypowsybl import ShortCircuitStudyType +from pypowsybl._pypowsybl import ShortCircuitStudyType, InitialVoltageProfileMode ShortCircuitStudyType.__module__ = __name__ ShortCircuitStudyType.__name__ = 'ShortCircuitStudyType' +InitialVoltageProfileMode.__module__ = __name__ +InitialVoltageProfileMode.__name__ = 'InitialVoltageProfileMode' class Parameters: # pylint: disable=too-few-public-methods @@ -35,6 +37,7 @@ class Parameters: # pylint: disable=too-few-public-methods min_voltage_drop_proportional_threshold: specifies a threshold for filtering the voltage results. Only nodes where the voltage drop due to the short circuit is greater than this property are retained. study_type: specifies the type of short-circuit study. It can be SUB_TRANSIENT, TRANSIENT or STEADY_STATE. + initial_voltage_profile_mode: specify how the computation is initialized. It can be NOMINAL, CONFIGURED or PREVIOUS_VALUE """ def __init__(self, @@ -44,7 +47,8 @@ def __init__(self, min_voltage_drop_proportional_threshold: float = None, study_type: ShortCircuitStudyType = None, provider_parameters: Dict[str, str] = None, - with_fortescue_result: bool = None): + with_fortescue_result: bool = None, + initial_voltage_profile_mode: InitialVoltageProfileMode = None): self._init_with_default_values() if with_feeder_result is not None: self.with_feeder_result = with_feeder_result @@ -60,6 +64,8 @@ def __init__(self, self.provider_parameters = provider_parameters if with_fortescue_result is not None: self.with_fortescue_result = with_fortescue_result + if initial_voltage_profile_mode is not None: + self.initial_voltage_profile_mode = initial_voltage_profile_mode def _init_from_c(self, c_parameters: _pypowsybl.ShortCircuitAnalysisParameters) -> None: self.with_feeder_result = c_parameters.with_feeder_result @@ -70,6 +76,7 @@ def _init_from_c(self, c_parameters: _pypowsybl.ShortCircuitAnalysisParameters) self.provider_parameters = dict( zip(c_parameters.provider_parameters_keys, c_parameters.provider_parameters_values)) self.with_fortescue_result = c_parameters.with_fortescue_result + self.initial_voltage_profile_mode = c_parameters.initial_voltage_profile_mode def _init_with_default_values(self) -> None: self._init_from_c(_pypowsybl.ShortCircuitAnalysisParameters()) @@ -79,6 +86,7 @@ def _init_with_default_values(self) -> None: self.min_voltage_drop_proportional_threshold = 0 self.study_type = ShortCircuitStudyType.TRANSIENT self.with_fortescue_result = False + self.initial_voltage_profile_mode = InitialVoltageProfileMode.NOMINAL def _to_c_parameters(self) -> _pypowsybl.ShortCircuitAnalysisParameters: c_parameters = _pypowsybl.ShortCircuitAnalysisParameters() @@ -88,6 +96,7 @@ def _to_c_parameters(self) -> _pypowsybl.ShortCircuitAnalysisParameters: c_parameters.study_type = self.study_type c_parameters.with_fortescue_result = self.with_fortescue_result c_parameters.min_voltage_drop_proportional_threshold = self.min_voltage_drop_proportional_threshold + c_parameters.initial_voltage_profile_mode = self.initial_voltage_profile_mode c_parameters.provider_parameters_keys = [] c_parameters.provider_parameters_values = [] return c_parameters @@ -100,4 +109,5 @@ def __repr__(self) -> str: f", min_voltage_drop_proportional_threshold={self.min_voltage_drop_proportional_threshold!r}" \ f", study_type={self.study_type!r}" \ f", with_fortescue_result={self.with_fortescue_result!r}" \ + f", initial_voltage_profile_mode={self.initial_voltage_profile_mode!r}" \ f")" diff --git a/tests/test_shortcircuit_analysis.py b/tests/test_shortcircuit_analysis.py index 54eae7a92..7fb45cc84 100644 --- a/tests/test_shortcircuit_analysis.py +++ b/tests/test_shortcircuit_analysis.py @@ -57,7 +57,8 @@ def test_run_analysis(): pars = pp.shortcircuit.Parameters(with_feeder_result=False, with_limit_violations=False, with_voltage_result=False, min_voltage_drop_proportional_threshold=0, study_type=pp.shortcircuit.ShortCircuitStudyType.TRANSIENT, - with_fortescue_result=True) + with_fortescue_result=True, + initial_voltage_profile_mode=pp.shortcircuit.InitialVoltageProfileMode.PREVIOUS_VALUE) assert pars is not None assert not pars.with_feeder_result assert not pars.with_limit_violations @@ -65,6 +66,7 @@ def test_run_analysis(): assert pars.min_voltage_drop_proportional_threshold == 0 assert pars.study_type == pp.shortcircuit.ShortCircuitStudyType.TRANSIENT assert pars.with_fortescue_result + assert pars.initial_voltage_profile_mode == pp.shortcircuit.InitialVoltageProfileMode.PREVIOUS_VALUE # create a short-circuit analysis context sc = pp.shortcircuit.create_analysis() From f82238901c7090b8d3f74d34bd9c004b00ec7d94 Mon Sep 17 00:00:00 2001 From: EtienneLt <32468651+EtienneLt@users.noreply.github.com> Date: Tue, 6 Aug 2024 08:39:56 +0200 Subject: [PATCH 39/45] Add attribute "paired" for dangling lines (#815) Signed-off-by: Etienne LESOT --- .../com/powsybl/dataframe/network/NetworkDataframes.java | 1 + .../powsybl/dataframe/network/NetworkDataframesTest.java | 4 ++-- pypowsybl/network/impl/network.py | 1 + tests/test_java_perunit.py | 8 ++++---- tests/test_network.py | 8 ++++---- tests/test_per_unit.py | 8 ++++---- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java b/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java index 7389f2e4f..703b0b30e 100644 --- a/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java +++ b/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java @@ -605,6 +605,7 @@ static NetworkDataframeMapper danglingLines() { .booleans("connected", dl -> dl.getTerminal().isConnected(), connectInjection()) .strings("pairing_key", dl -> Objects.toString(dl.getPairingKey(), ""), DanglingLine::setPairingKey) .strings("ucte_xnode_code", dl -> Objects.toString(dl.getPairingKey(), "")) + .booleans("paired", DanglingLine::isPaired) .booleans("fictitious", Identifiable::isFictitious, Identifiable::setFictitious, false) .strings("tie_line_id", dl -> dl.getTieLine().map(Identifiable::getId).orElse("")) .addProperties() diff --git a/java/src/test/java/com/powsybl/dataframe/network/NetworkDataframesTest.java b/java/src/test/java/com/powsybl/dataframe/network/NetworkDataframesTest.java index acafc9910..5b23d91e4 100644 --- a/java/src/test/java/com/powsybl/dataframe/network/NetworkDataframesTest.java +++ b/java/src/test/java/com/powsybl/dataframe/network/NetworkDataframesTest.java @@ -263,13 +263,13 @@ void danglingLines() { assertThat(series) .extracting(Series::getName) .containsExactly("id", "name", "r", "x", "g", "b", "p0", "q0", "p", "q", "i", "voltage_level_id", "bus_id", - "connected", "pairing_key", "ucte_xnode_code", "tie_line_id"); + "connected", "pairing_key", "ucte_xnode_code", "paired", "tie_line_id"); List allAttributeSeries = createDataFrame(DANGLING_LINE, network, new DataframeFilter(ALL_ATTRIBUTES, Collections.emptyList())); assertThat(allAttributeSeries) .extracting(Series::getName) .containsExactly("id", "name", "r", "x", "g", "b", "p0", "q0", "p", "q", "i", "boundary_p", "boundary_q", "boundary_v_mag", "boundary_v_angle", - "voltage_level_id", "bus_id", "bus_breaker_bus_id", "node", "connected", "pairing_key", "ucte_xnode_code", "fictitious", "tie_line_id"); + "voltage_level_id", "bus_id", "bus_breaker_bus_id", "node", "connected", "pairing_key", "ucte_xnode_code", "paired", "fictitious", "tie_line_id"); } @Test diff --git a/pypowsybl/network/impl/network.py b/pypowsybl/network/impl/network.py index d5869e010..e4ceea188 100644 --- a/pypowsybl/network/impl/network.py +++ b/pypowsybl/network/impl/network.py @@ -1234,6 +1234,7 @@ def get_dangling_lines(self, all_attributes: bool = False, attributes: List[str] - **fictitious** (optional): ``True`` if the dangling line is part of the model and not of the actual network - **pairing_key**: the pairing key associated to the dangling line, to be used for creating tie lines. - **ucte-xnode-code**: deprecated for pairing key. + - **paired**: if the dangling line is paired with a tie line - **tie_line_id**: the ID of the tie line if the dangling line is paired This dataframe is indexed by the id of the dangling lines diff --git a/tests/test_java_perunit.py b/tests/test_java_perunit.py index 9d908c230..35e55f907 100644 --- a/tests/test_java_perunit.py +++ b/tests/test_java_perunit.py @@ -144,17 +144,17 @@ def test_dangling_lines_per_unit(): expected = pd.DataFrame(index=pd.Series(name='id', data=['DL']), columns=['name', 'r', 'x', 'g', 'b', 'p0', 'q0', 'p', 'q', 'i', 'voltage_level_id', - 'bus_id', 'connected', 'pairing_key', 'ucte_xnode_code', 'tie_line_id'], + 'bus_id', 'connected', 'pairing_key', 'ucte_xnode_code', 'paired', 'tie_line_id'], data=[['', 0.1, 0.01, 0.01, 0.001, 0.5, 0.3, 0.5482, 0.3029, 0.6263, 'VL', 'VL_0', - True, '', '', '']]) + True, '', '', False, '']]) dangling_lines = n.get_dangling_lines() pd.testing.assert_frame_equal(expected, dangling_lines, check_dtype=False, atol=10 ** -4) n.update_dangling_lines(pd.DataFrame(index=['DL'], columns=['p0', 'q0'], data=[[0.75, 0.25]])) expected = pd.DataFrame(index=pd.Series(name='id', data=['DL']), columns=['name', 'r', 'x', 'g', 'b', 'p0', 'q0', 'p', 'q', 'i', 'voltage_level_id', - 'bus_id', 'connected', 'pairing_key', 'ucte_xnode_code', 'tie_line_id'], + 'bus_id', 'connected', 'pairing_key', 'ucte_xnode_code', 'paired', 'tie_line_id'], data=[['', 0.1, 0.01, 0.01, 0.001, 0.75, 0.25, 0.5482, 0.3029, 0.6263, 'VL', 'VL_0', - True, '', '', '']]) + True, '', '', False, '']]) dangling_lines = n.get_dangling_lines() pd.testing.assert_frame_equal(expected, dangling_lines, check_dtype=False, atol=10 ** -4) diff --git a/tests/test_network.py b/tests/test_network.py index f2d6b3278..893b833e8 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -1003,18 +1003,18 @@ def test_dangling_lines(): expected = pd.DataFrame(index=pd.Series(name='id', data=['DL']), columns=['name', 'r', 'x', 'g', 'b', 'p0', 'q0', 'p', 'q', 'i', 'voltage_level_id', 'bus_id', - 'connected', 'pairing_key', 'ucte_xnode_code', 'tie_line_id'], + 'connected', 'pairing_key', 'ucte_xnode_code', 'paired', 'tie_line_id'], data=[['', 10.0, 1.0, 0.0001, 0.00001, 50.0, 30.0, nan, nan, nan, 'VL', 'VL_0', True, - '', '', '']]) + '', '', False, '']]) pd.testing.assert_frame_equal(expected, n.get_dangling_lines(), check_dtype=False) n.update_dangling_lines( pd.DataFrame(index=['DL'], columns=['r', 'x', 'g', 'b', 'p0', 'q0', 'connected'], data=[[11.0, 1.1, 0.0002, 0.00002, 40.0, 40.0, False]])) updated = pd.DataFrame(index=pd.Series(name='id', data=['DL']), columns=['name', 'r', 'x', 'g', 'b', 'p0', 'q0', 'p', 'q', 'i', 'voltage_level_id', - 'bus_id', 'connected', 'pairing_key', 'ucte_xnode_code', 'tie_line_id'], + 'bus_id', 'connected', 'pairing_key', 'ucte_xnode_code', 'paired', 'tie_line_id'], data=[['', 11.0, 1.1, 0.0002, 0.00002, 40.0, 40.0, nan, nan, nan, 'VL', '', False, - '', '', '']]) + '', '', False, '']]) pd.testing.assert_frame_equal(updated, n.get_dangling_lines(), check_dtype=False) n = util.create_dangling_lines_network() dangling_lines = n.get_dangling_lines(attributes=['bus_breaker_bus_id', 'node']) diff --git a/tests/test_per_unit.py b/tests/test_per_unit.py index 6f037043b..2cdbbbb0c 100644 --- a/tests/test_per_unit.py +++ b/tests/test_per_unit.py @@ -199,17 +199,17 @@ def test_dangling_lines_per_unit(): expected = pd.DataFrame(index=pd.Series(name='id', data=['DL']), columns=['name', 'r', 'x', 'g', 'b', 'p0', 'q0', 'p', 'q', 'i', 'voltage_level_id', - 'bus_id', 'connected', 'pairing_key', 'ucte_xnode_code', 'tie_line_id'], + 'bus_id', 'connected', 'pairing_key', 'ucte_xnode_code', 'paired', 'tie_line_id'], data=[['', 0.1, 0.01, 0.01, 0.001, 0.5, 0.3, 0.5482, 0.3029, 0.6263, 'VL', 'VL_0', - True, '', '', '']]) + True, '', '', False, '']]) dangling_lines = n.get_dangling_lines() pd.testing.assert_frame_equal(expected, dangling_lines, check_dtype=False, atol=10 ** -4) n.update_dangling_lines(pd.DataFrame(index=['DL'], columns=['p0', 'q0'], data=[[0.75, 0.25]])) expected = pd.DataFrame(index=pd.Series(name='id', data=['DL']), columns=['name', 'r', 'x', 'g', 'b', 'p0', 'q0', 'p', 'q', 'i', 'voltage_level_id', - 'bus_id', 'connected', 'pairing_key', 'ucte_xnode_code', 'tie_line_id'], + 'bus_id', 'connected', 'pairing_key', 'ucte_xnode_code', 'paired', 'tie_line_id'], data=[['', 0.1, 0.01, 0.01, 0.001, 0.75, 0.25, 0.5482, 0.3029, 0.6263, 'VL', 'VL_0', - True, '', '', '']]) + True, '', '', False, '']]) dangling_lines = n.get_dangling_lines() pd.testing.assert_frame_equal(expected, dangling_lines, check_dtype=False, atol=10 ** -4) From 0e337eb881ac194b26f4d542975402d7961d22b8 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Sat, 24 Aug 2024 17:20:11 +0200 Subject: [PATCH 40/45] Update Signed-off-by: Geoffroy Jamgotchian --- .github/workflows/dev-ci.yml | 4 ++-- .github/workflows/full-ci.yml | 4 ++-- cpp/powsybl-cpp/CMakeLists.txt | 2 +- java/pom.xml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/dev-ci.yml b/.github/workflows/dev-ci.yml index efedb0b96..8dd93ce10 100644 --- a/.github/workflows/dev-ci.yml +++ b/.github/workflows/dev-ci.yml @@ -33,7 +33,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1.1.5 # !!! this is last version compatible with manylinux 2014 with: - java-version: '21' + java-version: '22' distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -118,7 +118,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '21' + java-version: '22' distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/full-ci.yml b/.github/workflows/full-ci.yml index a5663dc05..2192ab5ac 100644 --- a/.github/workflows/full-ci.yml +++ b/.github/workflows/full-ci.yml @@ -53,7 +53,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1.1.5 # !!! this is last version compatible with manylinux 2014 with: - java-version: '21' + java-version: '22' distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -164,7 +164,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '21' + java-version: '22' distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/cpp/powsybl-cpp/CMakeLists.txt b/cpp/powsybl-cpp/CMakeLists.txt index 63cfa517e..7cfeb7fc1 100644 --- a/cpp/powsybl-cpp/CMakeLists.txt +++ b/cpp/powsybl-cpp/CMakeLists.txt @@ -78,7 +78,7 @@ ExternalProject_Add(native-image DEPENDS mvn SOURCE_DIR ${PYPOWSYBL_JAVA_BIN_DIR} DOWNLOAD_COMMAND "" - PATCH_COMMAND $ENV{JAVA_HOME}/bin/native-image ${NATIVE_IMAGE_BUILD_OPTIONS} --class-path ${PYPOWSYBL_JAVA_SRC_DIR}/target/pypowsybl-java.jar${EXTRA_JARS} -march=compatibility --no-fallback --shared --gc=${NATIVE_IMAGE_GC} -o pypowsybl-java -H:CLibraryPath=${CMAKE_CURRENT_SOURCE_DIR}/src --add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.c=ALL-UNNAMED + PATCH_COMMAND $ENV{JAVA_HOME}/bin/native-image ${NATIVE_IMAGE_BUILD_OPTIONS} --class-path ${PYPOWSYBL_JAVA_SRC_DIR}/target/pypowsybl-java.jar${EXTRA_JARS} -march=compatibility --no-fallback --shared --gc=${NATIVE_IMAGE_GC} -o pypowsybl-java -H:CLibraryPath=${CMAKE_CURRENT_SOURCE_DIR} --add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.c=ALL-UNNAMED CONFIGURE_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_OLD_LIB} ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_LIB} ${NATIVE_IMAGE_INSTALL_EXTRA_COMMAND} diff --git a/java/pom.xml b/java/pom.xml index d408f6c18..1f1017098 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -61,9 +61,9 @@ 1.7.0-SNAPSHOT - 21 + 22 4.4 - 23.1.1 + 24.0.2 3.1.0 5.10.0 3.0.8 From 5b6be191819561751af376a46895d6295e34bd12 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Sat, 24 Aug 2024 17:22:21 +0200 Subject: [PATCH 41/45] Wip Signed-off-by: Geoffroy Jamgotchian --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c63af0cdf..44cf8c99c 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Requirements: - Cmake >= 3.14 - C++11 compiler - Python >= 3.8 for Linux, Windows and MacOS (amd64 and arm64) -- [Oracle GraalVM Java 21](https://www.graalvm.org/downloads/) +- [Oracle GraalVM Java 22](https://www.graalvm.org/downloads/) To build from sources and install PyPowSyBl package: From f2399dda019e5cfb1003ef77338714bc96dc9dd4 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Tue, 10 Sep 2024 14:56:07 +0200 Subject: [PATCH 42/45] Wip Signed-off-by: Geoffroy Jamgotchian --- .github/workflows/dev-ci.yml | 4 +- .github/workflows/full-ci.yml | 4 +- java/pom.xml | 4 +- .../python/commons/CommonCFunctions.java | 83 +- .../python/dataframe/CDataframeHandler.java | 43 +- .../dynamic/DynamicSimulationCFunctions.java | 137 ++- .../FlowDecompositionCFunctions.java | 129 +- .../powsybl/python/glsk/GlskCFunctions.java | 69 +- .../python/loadflow/LoadFlowCFunctions.java | 134 +- .../LoadFlowValidationCFunctions.java | 30 +- .../python/logging/LoggingCFunctions.java | 18 +- .../python/network/NetworkCFunctions.java | 1085 ++++++++++------- .../NetworkModificationsCFunctions.java | 136 ++- .../python/report/ReportCFunctions.java | 53 +- .../security/SecurityAnalysisCFunctions.java | 438 ++++--- .../SensitivityAnalysisCFunctions.java | 166 ++- .../ShortCircuitAnalysisCFunctions.java | 171 ++- .../VoltageInitializerCFunctions.java | 339 +++-- .../powsybl-iidm-api/resource-config.json | 3 +- .../resource-config.json | 7 - 20 files changed, 1921 insertions(+), 1132 deletions(-) delete mode 100644 java/src/main/resources/META-INF/native-image/com.powsybl/powsybl-iidm-converter-api/resource-config.json diff --git a/.github/workflows/dev-ci.yml b/.github/workflows/dev-ci.yml index caee0bb33..6c8743a14 100644 --- a/.github/workflows/dev-ci.yml +++ b/.github/workflows/dev-ci.yml @@ -33,7 +33,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1.1.5 # !!! this is last version compatible with manylinux 2014 with: - java-version: '22' + java-version: '21' distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -126,7 +126,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '22' + java-version: '21' distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/full-ci.yml b/.github/workflows/full-ci.yml index 1c655fd9b..3b11be7b2 100644 --- a/.github/workflows/full-ci.yml +++ b/.github/workflows/full-ci.yml @@ -53,7 +53,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1.1.5 # !!! this is last version compatible with manylinux 2014 with: - java-version: '22' + java-version: '21' distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -172,7 +172,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '22' + java-version: '21' distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/java/pom.xml b/java/pom.xml index 1f1017098..e49ab5c7e 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -61,9 +61,9 @@ 1.7.0-SNAPSHOT - 22 + 21 4.4 - 24.0.2 + 23.1.2 3.1.0 5.10.0 3.0.8 diff --git a/java/src/main/java/com/powsybl/python/commons/CommonCFunctions.java b/java/src/main/java/com/powsybl/python/commons/CommonCFunctions.java index 65b5bd05b..f35795879 100644 --- a/java/src/main/java/com/powsybl/python/commons/CommonCFunctions.java +++ b/java/src/main/java/com/powsybl/python/commons/CommonCFunctions.java @@ -8,6 +8,7 @@ package com.powsybl.python.commons; import com.powsybl.iidm.network.Network; +import com.powsybl.python.commons.Util.PointerProvider; import com.powsybl.python.dataframe.CDataframeHandler; import com.powsybl.tools.Version; import org.graalvm.nativeimage.IsolateThread; @@ -26,6 +27,7 @@ /** * @author Geoffroy Jamgotchian {@literal } */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class CommonCFunctions { @@ -34,12 +36,22 @@ private CommonCFunctions() { @CEntryPoint(name = "setJavaLibraryPath") public static void setJavaLibraryPath(IsolateThread thread, CCharPointer javaLibraryPath, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> System.setProperty("java.library.path", CTypeUtil.toString(javaLibraryPath))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + System.setProperty("java.library.path", CTypeUtil.toString(javaLibraryPath)); + } + }); } @CEntryPoint(name = "setConfigRead") public static void setConfigRead(IsolateThread thread, boolean read, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> PyPowsyblConfiguration.setReadConfig(read)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + PyPowsyblConfiguration.setReadConfig(read); + } + }); } @CEntryPoint(name = "isConfigRead") @@ -49,30 +61,45 @@ public static boolean isConfigRead(IsolateThread thread, ExceptionHandlerPointer @CEntryPoint(name = "getVersionTable") public static CCharPointer getVersionTable(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> CTypeUtil.toCharPtr(Version.getTableString())); + return doCatch(exceptionHandlerPtr, () -> { + return CTypeUtil.toCharPtr(Version.getTableString()); + }); } @CEntryPoint(name = "freeStringArray") public static void freeStringArray(IsolateThread thread, ArrayPointer arrayPtr, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> freeArrayContent(arrayPtr)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + freeArrayContent(arrayPtr); + } + }); } @CEntryPoint(name = "freeArray") public static void freeArray(IsolateThread thread, ArrayPointer arrayPointer, ExceptionHandlerPointer exceptionHandlerPtr) { - UnmanagedMemory.free(arrayPointer.getPtr()); - UnmanagedMemory.free(arrayPointer); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + UnmanagedMemory.free(arrayPointer.getPtr()); + UnmanagedMemory.free(arrayPointer); + } + }); } @CEntryPoint(name = "freeSeriesArray") public static void freeSeriesArray(IsolateThread thread, ArrayPointer seriesPtrArrayPtr, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - for (int i = 0; i < seriesPtrArrayPtr.getLength(); i++) { - freeSeries(seriesPtrArrayPtr.getPtr().addressOf(i)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + for (int i = 0; i < seriesPtrArrayPtr.getLength(); i++) { + freeSeries(seriesPtrArrayPtr.getPtr().addressOf(i)); + } + freeArrayPointer(seriesPtrArrayPtr); } - freeArrayPointer(seriesPtrArrayPtr); }); } @@ -97,20 +124,33 @@ private static void freeArrayContent(ArrayPointer array) { @CEntryPoint(name = "destroyObjectHandle") public static void destroyObjectHandle(IsolateThread thread, ObjectHandle objectHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> ObjectHandles.getGlobal().destroy(objectHandle)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + ObjectHandles.getGlobal().destroy(objectHandle); + } + }); } @CEntryPoint(name = "getWorkingVariantId") public static CCharPointer getWorkingVariantId(IsolateThread thread, ObjectHandle networkHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - return CTypeUtil.toCharPtr(network.getVariantManager().getWorkingVariantId()); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public CCharPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + return CTypeUtil.toCharPtr(network.getVariantManager().getWorkingVariantId()); + } }); } @CEntryPoint(name = "freeString") public static void freeString(IsolateThread thread, CCharPointer string, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.free(string)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + UnmanagedMemory.free(string); + } + }); } @CEntryPoint(name = "closePypowsybl") @@ -120,12 +160,15 @@ public static void closePypowsybl(IsolateThread thread, ExceptionHandlerPointer @CEntryPoint(name = "freeStringMap") public static void freeStringMap(IsolateThread thread, StringMap map, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - for (int i = 0; i < map.getLength(); i++) { - UnmanagedMemory.free(map.getKeys().read(i)); - UnmanagedMemory.free(map.getValues().read(i)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + for (int i = 0; i < map.getLength(); i++) { + UnmanagedMemory.free(map.getKeys().read(i)); + UnmanagedMemory.free(map.getValues().read(i)); + } + UnmanagedMemory.free(map); } - UnmanagedMemory.free(map); }); } } diff --git a/java/src/main/java/com/powsybl/python/dataframe/CDataframeHandler.java b/java/src/main/java/com/powsybl/python/dataframe/CDataframeHandler.java index 2a767cec9..956bfae8e 100644 --- a/java/src/main/java/com/powsybl/python/dataframe/CDataframeHandler.java +++ b/java/src/main/java/com/powsybl/python/dataframe/CDataframeHandler.java @@ -26,6 +26,7 @@ * * @author Sylvain Leclerc */ +@SuppressWarnings({"java:S1602", "java:S1604"}) public class CDataframeHandler implements DataframeHandler { public static final int STRING_SERIES_TYPE = 0; @@ -55,42 +56,72 @@ public void allocate(int seriesCount) { public StringSeriesWriter newStringIndex(String name, int size) { CCharPointerPointer dataPtr = UnmanagedMemory.calloc(size * SizeOf.get(CCharPointerPointer.class)); addIndex(name, size, dataPtr, STRING_SERIES_TYPE); - return (i, v) -> dataPtr.addressOf(i).write(CTypeUtil.toCharPtr(v)); + return new StringSeriesWriter() { + @Override + public void set(int i, String v) { + dataPtr.addressOf(i).write(CTypeUtil.toCharPtr(v)); + } + }; } @Override public IntSeriesWriter newIntIndex(String name, int size) { CIntPointer dataPtr = UnmanagedMemory.calloc(size * SizeOf.get(CIntPointer.class)); addIndex(name, size, dataPtr, INT_SERIES_TYPE); - return (i, v) -> dataPtr.addressOf(i).write(v); + return new IntSeriesWriter() { + @Override + public void set(int i, int v) { + dataPtr.addressOf(i).write(v); + } + }; } @Override public StringSeriesWriter newStringSeries(String name, int size) { CCharPointerPointer dataPtr = UnmanagedMemory.calloc(size * SizeOf.get(CCharPointerPointer.class)); addSeries(name, size, dataPtr, STRING_SERIES_TYPE); - return (i, v) -> dataPtr.addressOf(i).write(CTypeUtil.toCharPtr(v)); + return new StringSeriesWriter() { + @Override + public void set(int i, String v) { + dataPtr.addressOf(i).write(CTypeUtil.toCharPtr(v)); + } + }; } @Override public IntSeriesWriter newIntSeries(String name, int size) { CIntPointer dataPtr = UnmanagedMemory.calloc(size * SizeOf.get(CIntPointer.class)); addSeries(name, size, dataPtr, INT_SERIES_TYPE); - return (i, v) -> dataPtr.addressOf(i).write(v); + return new IntSeriesWriter() { + @Override + public void set(int i, int v) { + dataPtr.addressOf(i).write(v); + } + }; } @Override public BooleanSeriesWriter newBooleanSeries(String name, int size) { CCharPointer dataPtr = UnmanagedMemory.calloc(size * SizeOf.get(CCharPointer.class)); addSeries(name, size, dataPtr, BOOLEAN_SERIES_TYPE); - return (i, v) -> dataPtr.addressOf(i).write(v ? (byte) 1 : 0); + return new BooleanSeriesWriter() { + @Override + public void set(int i, boolean v) { + dataPtr.addressOf(i).write(v ? (byte) 1 : 0); + } + }; } @Override public DoubleSeriesWriter newDoubleSeries(String name, int size) { CDoublePointer dataPtr = UnmanagedMemory.calloc(size * SizeOf.get(CDoublePointer.class)); addSeries(name, size, dataPtr, DOUBLE_SERIES_TYPE); - return (i, v) -> dataPtr.addressOf(i).write(v); + return new DoubleSeriesWriter() { + @Override + public void set(int i, double v) { + dataPtr.addressOf(i).write(v); + } + }; } private void addSeries(String name, int count, PointerBase dataPtr, int type) { diff --git a/java/src/main/java/com/powsybl/python/dynamic/DynamicSimulationCFunctions.java b/java/src/main/java/com/powsybl/python/dynamic/DynamicSimulationCFunctions.java index 433ae8c68..1805b9444 100644 --- a/java/src/main/java/com/powsybl/python/dynamic/DynamicSimulationCFunctions.java +++ b/java/src/main/java/com/powsybl/python/dynamic/DynamicSimulationCFunctions.java @@ -9,8 +9,10 @@ import static com.powsybl.python.commons.Util.doCatch; +import java.io.IOException; import java.util.ArrayList; +import com.powsybl.python.commons.Util.PointerProvider; import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.ObjectHandle; import org.graalvm.nativeimage.ObjectHandles; @@ -46,6 +48,7 @@ /** * @author Nicolas Pierre */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class DynamicSimulationCFunctions { @@ -59,25 +62,45 @@ private static Logger logger() { @CEntryPoint(name = "createDynamicSimulationContext") public static ObjectHandle createDynamicSimulationContext(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> ObjectHandles.getGlobal().create(new DynamicSimulationContext())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() throws IOException { + return ObjectHandles.getGlobal().create(new DynamicSimulationContext()); + } + }); } @CEntryPoint(name = "createDynamicModelMapping") public static ObjectHandle createDynamicModelMapping(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> ObjectHandles.getGlobal().create(new PythonDynamicModelsSupplier())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + return ObjectHandles.getGlobal().create(new PythonDynamicModelsSupplier()); + } + }); } @CEntryPoint(name = "createTimeseriesMapping") public static ObjectHandle createTimeseriesMapping(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> ObjectHandles.getGlobal().create(new CurveMappingSupplier())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() throws IOException { + return ObjectHandles.getGlobal().create(new CurveMappingSupplier()); + } + }); } @CEntryPoint(name = "createEventMapping") public static ObjectHandle createEventMapping(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> ObjectHandles.getGlobal().create(new EventSupplier())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() throws IOException { + return ObjectHandles.getGlobal().create(new EventSupplier()); + } + }); } @CEntryPoint(name = "runDynamicModel") @@ -89,21 +112,24 @@ public static ObjectHandle runDynamicModel(IsolateThread thread, ObjectHandle curvesSupplierHandle, int startTime, int stopTime, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - DynamicSimulationContext dynamicContext = ObjectHandles.getGlobal().get(dynamicContextHandle); - Network network = ObjectHandles.getGlobal().get(networkHandle); - PythonDynamicModelsSupplier dynamicMapping = ObjectHandles.getGlobal().get(dynamicMappingHandle); - EventModelsSupplier eventModelsSupplier = ObjectHandles.getGlobal().get(eventModelsSupplierHandle); - CurvesSupplier curvesSupplier = ObjectHandles.getGlobal().get(curvesSupplierHandle); - DynamicSimulationParameters dynamicSimulationParameters = new DynamicSimulationParameters(startTime, - stopTime); - DynamicSimulationResult result = dynamicContext.run(network, - dynamicMapping, - eventModelsSupplier, - curvesSupplier, - dynamicSimulationParameters); - logger().info("Dynamic simulation ran successfully in java"); - return ObjectHandles.getGlobal().create(result); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() throws IOException { + DynamicSimulationContext dynamicContext = ObjectHandles.getGlobal().get(dynamicContextHandle); + Network network = ObjectHandles.getGlobal().get(networkHandle); + PythonDynamicModelsSupplier dynamicMapping = ObjectHandles.getGlobal().get(dynamicMappingHandle); + EventModelsSupplier eventModelsSupplier = ObjectHandles.getGlobal().get(eventModelsSupplierHandle); + CurvesSupplier curvesSupplier = ObjectHandles.getGlobal().get(curvesSupplierHandle); + DynamicSimulationParameters dynamicSimulationParameters = new DynamicSimulationParameters(startTime, + stopTime); + DynamicSimulationResult result = dynamicContext.run(network, + dynamicMapping, + eventModelsSupplier, + curvesSupplier, + dynamicSimulationParameters); + logger().info("Dynamic simulation ran successfully in java"); + return ObjectHandles.getGlobal().create(result); + } }); } @@ -112,10 +138,13 @@ public static void addDynamicMapping(IsolateThread thread, ObjectHandle dynamicM DynamicMappingType mappingType, DataframePointer mappingDataframePtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - PythonDynamicModelsSupplier dynamicMapping = ObjectHandles.getGlobal().get(dynamicMappingHandle); - UpdatingDataframe mappingDataframe = NetworkCFunctions.createDataframe(mappingDataframePtr); - DynamicMappingAdderFactory.getAdder(mappingType).addElements(dynamicMapping, mappingDataframe); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + PythonDynamicModelsSupplier dynamicMapping = ObjectHandles.getGlobal().get(dynamicMappingHandle); + UpdatingDataframe mappingDataframe = NetworkCFunctions.createDataframe(mappingDataframePtr); + DynamicMappingAdderFactory.getAdder(mappingType).addElements(dynamicMapping, mappingDataframe); + } }); } @@ -123,7 +152,12 @@ public static void addDynamicMapping(IsolateThread thread, ObjectHandle dynamicM public static DataframeMetadataPointer getDynamicMappingsMetaData(IsolateThread thread, DynamicMappingType mappingType, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> CTypeUtil.createSeriesMetadata(DynamicMappingAdderFactory.getAdder(mappingType).getMetadata())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public DataframeMetadataPointer get() throws IOException { + return CTypeUtil.createSeriesMetadata(DynamicMappingAdderFactory.getAdder(mappingType).getMetadata()); + } + }); } @CEntryPoint(name = "addCurve") @@ -132,11 +166,14 @@ public static void addCurve(IsolateThread thread, CCharPointer dynamicIdPtr, CCharPointer variablePtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - String dynamicId = CTypeUtil.toString(dynamicIdPtr); - String variable = CTypeUtil.toString(variablePtr); - CurveMappingSupplier timeSeriesSupplier = ObjectHandles.getGlobal().get(timeseriesSupplier); - timeSeriesSupplier.addCurve(dynamicId, variable); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + String dynamicId = CTypeUtil.toString(dynamicIdPtr); + String variable = CTypeUtil.toString(variablePtr); + CurveMappingSupplier timeSeriesSupplier = ObjectHandles.getGlobal().get(timeseriesSupplier); + timeSeriesSupplier.addCurve(dynamicId, variable); + } }); } @@ -147,10 +184,13 @@ public static void addEventDisconnection(IsolateThread thread, double eventTime, int disconnectOnly, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - String staticId = CTypeUtil.toString(staticIdPtr); - EventSupplier eventSupplier = ObjectHandles.getGlobal().get(eventSupplierHandle); - eventSupplier.addEventDisconnection(staticId, eventTime, Util.convert(PyPowsyblApiHeader.ThreeSideType.fromCValue(disconnectOnly)).toTwoSides()); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + String staticId = CTypeUtil.toString(staticIdPtr); + EventSupplier eventSupplier = ObjectHandles.getGlobal().get(eventSupplierHandle); + eventSupplier.addEventDisconnection(staticId, eventTime, Util.convert(PyPowsyblApiHeader.ThreeSideType.fromCValue(disconnectOnly)).toTwoSides()); + } }); } @@ -158,9 +198,12 @@ public static void addEventDisconnection(IsolateThread thread, public static CCharPointer getDynamicSimulationResultsStatus(IsolateThread thread, ObjectHandle dynamicSimulationResultsHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - DynamicSimulationResult simulationResult = ObjectHandles.getGlobal().get(dynamicSimulationResultsHandle); - return CTypeUtil.toCharPtr(simulationResult.isOk() ? "Ok" : "Not OK"); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public CCharPointer get() throws IOException { + DynamicSimulationResult simulationResult = ObjectHandles.getGlobal().get(dynamicSimulationResultsHandle); + return CTypeUtil.toCharPtr(simulationResult.isOk() ? "Ok" : "Not OK"); + } }); } @@ -169,11 +212,14 @@ public static ArrayPointer getDynamicCurve(IsolateThread thread, ObjectHandle resultHandle, CCharPointer curveNamePtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - DynamicSimulationResult result = ObjectHandles.getGlobal().get(resultHandle); - String curveName = CTypeUtil.toString(curveNamePtr); - TimeSeries curve = result.getCurve(curveName); - return Dataframes.createCDataframe(CurvesSeries.curvesDataFrameMapper(curveName), curve); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() throws IOException { + DynamicSimulationResult result = ObjectHandles.getGlobal().get(resultHandle); + String curveName = CTypeUtil.toString(curveNamePtr); + TimeSeries curve = result.getCurve(curveName); + return Dataframes.createCDataframe(CurvesSeries.curvesDataFrameMapper(curveName), curve); + } }); } @@ -181,9 +227,12 @@ public static ArrayPointer getDynamicCurve(IsolateThread thread, public static ArrayPointer getAllDynamicCurvesIds(IsolateThread thread, ObjectHandle resultHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - DynamicSimulationResult result = ObjectHandles.getGlobal().get(resultHandle); - return Util.createCharPtrArray(new ArrayList<>(result.getCurves().keySet())); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() throws IOException { + DynamicSimulationResult result = ObjectHandles.getGlobal().get(resultHandle); + return Util.createCharPtrArray(new ArrayList<>(result.getCurves().keySet())); + } }); } diff --git a/java/src/main/java/com/powsybl/python/flow_decomposition/FlowDecompositionCFunctions.java b/java/src/main/java/com/powsybl/python/flow_decomposition/FlowDecompositionCFunctions.java index 1a8cc89df..205c22f2a 100644 --- a/java/src/main/java/com/powsybl/python/flow_decomposition/FlowDecompositionCFunctions.java +++ b/java/src/main/java/com/powsybl/python/flow_decomposition/FlowDecompositionCFunctions.java @@ -14,11 +14,10 @@ import com.powsybl.iidm.network.Network; import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.loadflow.LoadFlowProvider; -import com.powsybl.python.commons.CTypeUtil; -import com.powsybl.python.commons.CommonCFunctions; -import com.powsybl.python.commons.Directives; -import com.powsybl.python.commons.PyPowsyblApiHeader; -import com.powsybl.python.commons.PyPowsyblConfiguration; +import com.powsybl.python.commons.*; +import com.powsybl.python.commons.PyPowsyblApiHeader.ArrayPointer; +import com.powsybl.python.commons.PyPowsyblApiHeader.SeriesPointer; +import com.powsybl.python.commons.Util.PointerProvider; import com.powsybl.python.loadflow.LoadFlowCUtils; import com.powsybl.python.network.Dataframes; import org.graalvm.nativeimage.IsolateThread; @@ -33,6 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.HashSet; import java.util.Set; @@ -42,6 +42,7 @@ /** * @author Hugo Schindler {@literal } */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class FlowDecompositionCFunctions { @@ -52,7 +53,9 @@ private FlowDecompositionCFunctions() { @CEntryPoint(name = "createFlowDecomposition") public static ObjectHandle createFlowDecomposition(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> ObjectHandles.getGlobal().create(new FlowDecompositionContext())); + return doCatch(exceptionHandlerPtr, () -> { + return ObjectHandles.getGlobal().create(new FlowDecompositionContext()); + }); } @CEntryPoint(name = "addContingencyForFlowDecomposition") @@ -60,11 +63,14 @@ public static void addContingency(IsolateThread thread, ObjectHandle flowDecompo CCharPointer contingencyIdPtr, CCharPointerPointer elementIdPtrPtr, int elementCount, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - FlowDecompositionContext flowDecompositionContext = ObjectHandles.getGlobal().get(flowDecompositionContextHandle); - Set elementsIds = new HashSet<>(toStringList(elementIdPtrPtr, elementCount)); - String contingencyId = CTypeUtil.toString(contingencyIdPtr); - flowDecompositionContext.getXnecProviderByIdsBuilder().addContingency(contingencyId, elementsIds); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + FlowDecompositionContext flowDecompositionContext = ObjectHandles.getGlobal().get(flowDecompositionContextHandle); + Set elementsIds = new HashSet<>(toStringList(elementIdPtrPtr, elementCount)); + String contingencyId = CTypeUtil.toString(contingencyIdPtr); + flowDecompositionContext.getXnecProviderByIdsBuilder().addContingency(contingencyId, elementsIds); + } }); } @@ -72,10 +78,13 @@ public static void addContingency(IsolateThread thread, ObjectHandle flowDecompo public static void addPrecontingencyMonitoredElements(IsolateThread thread, ObjectHandle flowDecompositionContextHandle, CCharPointerPointer elementIdPtrPtr, int elementCount, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - FlowDecompositionContext flowDecompositionContext = ObjectHandles.getGlobal().get(flowDecompositionContextHandle); - Set elementsIds = new HashSet<>(toStringList(elementIdPtrPtr, elementCount)); - flowDecompositionContext.getXnecProviderByIdsBuilder().addNetworkElementsOnBasecase(elementsIds); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + FlowDecompositionContext flowDecompositionContext = ObjectHandles.getGlobal().get(flowDecompositionContextHandle); + Set elementsIds = new HashSet<>(toStringList(elementIdPtrPtr, elementCount)); + flowDecompositionContext.getXnecProviderByIdsBuilder().addNetworkElementsOnBasecase(elementsIds); + } }); } @@ -84,11 +93,14 @@ public static void addPostcontingencyMonitoredElements(IsolateThread thread, Obj CCharPointerPointer elementIdPtrPtr, int elementCount, CCharPointerPointer contingenciesIdPtrPtr, int contingenciesCount, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - FlowDecompositionContext flowDecompositionContext = ObjectHandles.getGlobal().get(flowDecompositionContextHandle); - Set elementsIds = new HashSet<>(toStringList(elementIdPtrPtr, elementCount)); - Set contingenciesIds = new HashSet<>(toStringList(contingenciesIdPtrPtr, contingenciesCount)); - flowDecompositionContext.getXnecProviderByIdsBuilder().addNetworkElementsAfterContingencies(elementsIds, contingenciesIds); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + FlowDecompositionContext flowDecompositionContext = ObjectHandles.getGlobal().get(flowDecompositionContextHandle); + Set elementsIds = new HashSet<>(toStringList(elementIdPtrPtr, elementCount)); + Set contingenciesIds = new HashSet<>(toStringList(contingenciesIdPtrPtr, contingenciesCount)); + flowDecompositionContext.getXnecProviderByIdsBuilder().addNetworkElementsAfterContingencies(elementsIds, contingenciesIds); + } }); } @@ -96,49 +108,62 @@ public static void addPostcontingencyMonitoredElements(IsolateThread thread, Obj public static void addAdditionalXnecProvider(IsolateThread thread, ObjectHandle flowDecompositionContextHandle, int additionalXnecProviderId, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - FlowDecompositionContext flowDecompositionContext = ObjectHandles.getGlobal().get(flowDecompositionContextHandle); - flowDecompositionContext.addAdditionalXnecProviderList(FlowDecompositionContext.DefaultXnecProvider.values()[additionalXnecProviderId]); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + FlowDecompositionContext flowDecompositionContext = ObjectHandles.getGlobal().get(flowDecompositionContextHandle); + flowDecompositionContext.addAdditionalXnecProviderList(FlowDecompositionContext.DefaultXnecProvider.values()[additionalXnecProviderId]); + } + }); } @CEntryPoint(name = "runFlowDecomposition") - public static PyPowsyblApiHeader.ArrayPointer runFlowDecomposition(IsolateThread thread, - ObjectHandle flowDecompositionContextHandle, - ObjectHandle networkHandle, - PyPowsyblApiHeader.FlowDecompositionParametersPointer flowDecompositionParametersPtr, - PyPowsyblApiHeader.LoadFlowParametersPointer loadFlowParametersPtr, - PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - FlowDecompositionContext flowDecompositionContext = ObjectHandles.getGlobal().get(flowDecompositionContextHandle); - Network network = ObjectHandles.getGlobal().get(networkHandle); - - String lfProviderName = PyPowsyblConfiguration.getDefaultLoadFlowProvider(); - LoadFlowProvider loadFlowProvider = LoadFlowCUtils.getLoadFlowProvider(lfProviderName); - String sensiProviderName = PyPowsyblConfiguration.getDefaultSensitivityAnalysisProvider(); - LoadFlowParameters loadFlowParameters = LoadFlowCUtils.createLoadFlowParameters(DC, loadFlowParametersPtr, loadFlowProvider); - FlowDecompositionParameters flowDecompositionParameters = FlowDecompositionCUtils.createFlowDecompositionParameters(flowDecompositionParametersPtr); - - logger().debug("Loadflow provider used is : {}", loadFlowProvider.getName()); - logger().debug("Sensitivity analysis provider used is : {}", sensiProviderName); - logger().debug("Load flow parameters : {}", loadFlowParameters); - logger().debug("Flow decomposition parameters : {}", flowDecompositionParameters); - - FlowDecompositionComputer flowDecompositionComputer = new FlowDecompositionComputer(flowDecompositionParameters, loadFlowParameters, lfProviderName, sensiProviderName); - XnecProvider xnecProvider = flowDecompositionContext.getXnecProvider(); - FlowDecompositionResults flowDecompositionResults = flowDecompositionComputer.run(xnecProvider, network); - - return Dataframes.createCDataframe(Dataframes.flowDecompositionMapper(flowDecompositionResults.getZoneSet()), flowDecompositionResults); + public static ArrayPointer runFlowDecomposition(IsolateThread thread, + ObjectHandle flowDecompositionContextHandle, + ObjectHandle networkHandle, + PyPowsyblApiHeader.FlowDecompositionParametersPointer flowDecompositionParametersPtr, + PyPowsyblApiHeader.LoadFlowParametersPointer loadFlowParametersPtr, + PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() throws IOException { + FlowDecompositionContext flowDecompositionContext = ObjectHandles.getGlobal().get(flowDecompositionContextHandle); + Network network = ObjectHandles.getGlobal().get(networkHandle); + + String lfProviderName = PyPowsyblConfiguration.getDefaultLoadFlowProvider(); + LoadFlowProvider loadFlowProvider = LoadFlowCUtils.getLoadFlowProvider(lfProviderName); + String sensiProviderName = PyPowsyblConfiguration.getDefaultSensitivityAnalysisProvider(); + LoadFlowParameters loadFlowParameters = LoadFlowCUtils.createLoadFlowParameters(DC, loadFlowParametersPtr, loadFlowProvider); + FlowDecompositionParameters flowDecompositionParameters = FlowDecompositionCUtils.createFlowDecompositionParameters(flowDecompositionParametersPtr); + + logger().debug("Loadflow provider used is : {}", loadFlowProvider.getName()); + logger().debug("Sensitivity analysis provider used is : {}", sensiProviderName); + logger().debug("Load flow parameters : {}", loadFlowParameters); + logger().debug("Flow decomposition parameters : {}", flowDecompositionParameters); + + FlowDecompositionComputer flowDecompositionComputer = new FlowDecompositionComputer(flowDecompositionParameters, loadFlowParameters, lfProviderName, sensiProviderName); + XnecProvider xnecProvider = flowDecompositionContext.getXnecProvider(); + FlowDecompositionResults flowDecompositionResults = flowDecompositionComputer.run(xnecProvider, network); + + return Dataframes.createCDataframe(Dataframes.flowDecompositionMapper(flowDecompositionResults.getZoneSet()), flowDecompositionResults); + } }); } @CEntryPoint(name = "createFlowDecompositionParameters") public static PyPowsyblApiHeader.FlowDecompositionParametersPointer createFlowDecompositionParameters(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> convertToFlowDecompositionParametersPointer(FlowDecompositionCUtils.createFlowDecompositionParameters())); + return doCatch(exceptionHandlerPtr, FlowDecompositionCFunctions::get); } @CEntryPoint(name = "freeFlowDecompositionParameters") public static void freeFlowDecompositionParameters(IsolateThread thread, PyPowsyblApiHeader.FlowDecompositionParametersPointer flowDecompositionParametersPtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.free(flowDecompositionParametersPtr)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + UnmanagedMemory.free(flowDecompositionParametersPtr); + } + }); } private static PyPowsyblApiHeader.FlowDecompositionParametersPointer convertToFlowDecompositionParametersPointer(FlowDecompositionParameters parameters) { @@ -155,4 +180,8 @@ private static PyPowsyblApiHeader.FlowDecompositionParametersPointer convertToFl private static Logger logger() { return LoggerFactory.getLogger(CommonCFunctions.class); } + + private static PyPowsyblApiHeader.FlowDecompositionParametersPointer get() { + return convertToFlowDecompositionParametersPointer(FlowDecompositionCUtils.createFlowDecompositionParameters()); + } } diff --git a/java/src/main/java/com/powsybl/python/glsk/GlskCFunctions.java b/java/src/main/java/com/powsybl/python/glsk/GlskCFunctions.java index a6acfc68e..7ac2ba70d 100644 --- a/java/src/main/java/com/powsybl/python/glsk/GlskCFunctions.java +++ b/java/src/main/java/com/powsybl/python/glsk/GlskCFunctions.java @@ -23,6 +23,7 @@ import java.time.Instant; import java.util.List; +import java.util.function.LongSupplier; import static com.powsybl.python.commons.Util.*; @@ -39,56 +40,74 @@ private GlskCFunctions() { @CEntryPoint(name = "createGLSKdocument") public static ObjectHandle createGLSKdocument(IsolateThread thread, CCharPointer fileNamePtr, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - GlskDocumentContext importer = new GlskDocumentContext(); - String filename = CTypeUtil.toString(fileNamePtr); - importer.load(filename); - return ObjectHandles.getGlobal().create(importer); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + GlskDocumentContext importer = new GlskDocumentContext(); + String filename = CTypeUtil.toString(fileNamePtr); + importer.load(filename); + return ObjectHandles.getGlobal().create(importer); + } }); } @CEntryPoint(name = "getGLSKinjectionkeys") public static ArrayPointer getGLSKinjectionkeys(IsolateThread thread, ObjectHandle networkHandle, ObjectHandle importerHandle, CCharPointer countryPtr, long instant, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - GlskDocumentContext importer = ObjectHandles.getGlobal().get(importerHandle); - Network network = ObjectHandles.getGlobal().get(networkHandle); - String country = CTypeUtil.toString(countryPtr); - return createCharPtrArray(importer.getInjectionIdForCountry(network, country, Instant.ofEpochSecond(instant))); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + GlskDocumentContext importer = ObjectHandles.getGlobal().get(importerHandle); + Network network = ObjectHandles.getGlobal().get(networkHandle); + String country = CTypeUtil.toString(countryPtr); + return createCharPtrArray(importer.getInjectionIdForCountry(network, country, Instant.ofEpochSecond(instant))); + } }); } @CEntryPoint(name = "getGLSKcountries") public static ArrayPointer getGLSKcountries(IsolateThread thread, ObjectHandle importerHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - GlskDocumentContext importer = ObjectHandles.getGlobal().get(importerHandle); - return createCharPtrArray(importer.getCountries()); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + GlskDocumentContext importer = ObjectHandles.getGlobal().get(importerHandle); + return createCharPtrArray(importer.getCountries()); + } }); } @CEntryPoint(name = "getInjectionFactor") public static ArrayPointer getInjectionFactor(IsolateThread thread, ObjectHandle networkHandle, ObjectHandle importerHandle, CCharPointer countryPtr, long instant, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - GlskDocumentContext importer = ObjectHandles.getGlobal().get(importerHandle); - String country = CTypeUtil.toString(countryPtr); - List values = importer.getInjectionFactorForCountryTimeinterval(network, country, Instant.ofEpochSecond(instant)); - return createDoubleArray(values); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + GlskDocumentContext importer = ObjectHandles.getGlobal().get(importerHandle); + String country = CTypeUtil.toString(countryPtr); + List values = importer.getInjectionFactorForCountryTimeinterval(network, country, Instant.ofEpochSecond(instant)); + return createDoubleArray(values); + } }); } @CEntryPoint(name = "getInjectionFactorStartTimestamp") public static long getInjectionFactorStartTimestamp(IsolateThread thread, ObjectHandle importerHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - GlskDocumentContext importer = ObjectHandles.getGlobal().get(importerHandle); - return importer.getInjectionFactorStart().getEpochSecond(); + return doCatch(exceptionHandlerPtr, new LongSupplier() { + @Override + public long getAsLong() { + GlskDocumentContext importer = ObjectHandles.getGlobal().get(importerHandle); + return importer.getInjectionFactorStart().getEpochSecond(); + } }); } @CEntryPoint(name = "getInjectionFactorEndTimestamp") public static long getInjectionFactorEndTimestamp(IsolateThread thread, ObjectHandle importerHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - GlskDocumentContext importer = ObjectHandles.getGlobal().get(importerHandle); - return importer.getInjectionFactorEnd().getEpochSecond(); + return doCatch(exceptionHandlerPtr, new LongSupplier() { + @Override + public long getAsLong() { + GlskDocumentContext importer = ObjectHandles.getGlobal().get(importerHandle); + return importer.getInjectionFactorEnd().getEpochSecond(); + } }); } } diff --git a/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCFunctions.java b/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCFunctions.java index 6e72b626a..5aec174a6 100644 --- a/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCFunctions.java +++ b/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCFunctions.java @@ -16,7 +16,11 @@ import com.powsybl.loadflow.LoadFlowProvider; import com.powsybl.loadflow.LoadFlowResult; import com.powsybl.python.commons.*; +import com.powsybl.python.commons.PyPowsyblApiHeader.ArrayPointer; +import com.powsybl.python.commons.PyPowsyblApiHeader.LoadFlowComponentResultPointer; import com.powsybl.python.commons.PyPowsyblApiHeader.LoadFlowParametersPointer; +import com.powsybl.python.commons.PyPowsyblApiHeader.SeriesPointer; +import com.powsybl.python.commons.Util.PointerProvider; import com.powsybl.python.network.Dataframes; import com.powsybl.python.report.ReportCUtils; import org.graalvm.nativeimage.IsolateThread; @@ -45,6 +49,7 @@ * * @author Sylvain Leclerc */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class LoadFlowCFunctions { @@ -53,67 +58,96 @@ private LoadFlowCFunctions() { @CEntryPoint(name = "setDefaultLoadFlowProvider") public static void setDefaultLoadFlowProvider(IsolateThread thread, CCharPointer provider, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> PyPowsyblConfiguration.setDefaultLoadFlowProvider(CTypeUtil.toString(provider))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + PyPowsyblConfiguration.setDefaultLoadFlowProvider(CTypeUtil.toString(provider)); + } + }); } @CEntryPoint(name = "getDefaultLoadFlowProvider") public static CCharPointer getDefaultLoadFlowProvider(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> CTypeUtil.toCharPtr(PyPowsyblConfiguration.getDefaultLoadFlowProvider())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public CCharPointer get() { + return CTypeUtil.toCharPtr(PyPowsyblConfiguration.getDefaultLoadFlowProvider()); + } + }); } @CEntryPoint(name = "freeLoadFlowComponentResultPointer") - public static void freeLoadFlowComponentResultPointer(IsolateThread thread, PyPowsyblApiHeader.ArrayPointer componentResultArrayPtr, + public static void freeLoadFlowComponentResultPointer(IsolateThread thread, ArrayPointer componentResultArrayPtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - for (int i = 0; i < componentResultArrayPtr.getLength(); i++) { - PyPowsyblApiHeader.LoadFlowComponentResultPointer loadFlowComponentResultPointer = componentResultArrayPtr.getPtr().addressOf(i); - UnmanagedMemory.free(loadFlowComponentResultPointer.getStatusText()); - UnmanagedMemory.free(loadFlowComponentResultPointer.getReferenceBusId()); - for (int j = 0; j < loadFlowComponentResultPointer.slackBusResults().getLength(); j++) { - PyPowsyblApiHeader.SlackBusResultPointer slackBusResultPointer = loadFlowComponentResultPointer.slackBusResults().getPtr().addressOf(j); - UnmanagedMemory.free(slackBusResultPointer.getId()); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + for (int i = 0; i < componentResultArrayPtr.getLength(); i++) { + LoadFlowComponentResultPointer loadFlowComponentResultPointer = componentResultArrayPtr.getPtr().addressOf(i); + UnmanagedMemory.free(loadFlowComponentResultPointer.getStatusText()); + UnmanagedMemory.free(loadFlowComponentResultPointer.getReferenceBusId()); + for (int j = 0; j < loadFlowComponentResultPointer.slackBusResults().getLength(); j++) { + PyPowsyblApiHeader.SlackBusResultPointer slackBusResultPointer = loadFlowComponentResultPointer.slackBusResults().getPtr().addressOf(j); + UnmanagedMemory.free(slackBusResultPointer.getId()); + } } + freeArrayPointer(componentResultArrayPtr); } - freeArrayPointer(componentResultArrayPtr); }); } @CEntryPoint(name = "getLoadFlowProviderNames") - public static PyPowsyblApiHeader.ArrayPointer getLoadFlowProviderNames(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> createCharPtrArray(LoadFlowProvider.findAll() - .stream().map(LoadFlowProvider::getName).collect(Collectors.toList()))); + public static ArrayPointer getLoadFlowProviderNames(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + return createCharPtrArray(LoadFlowProvider.findAll() + .stream().map(LoadFlowProvider::getName).collect(Collectors.toList())); + } + }); } @CEntryPoint(name = "runLoadFlow") - public static PyPowsyblApiHeader.ArrayPointer runLoadFlow(IsolateThread thread, ObjectHandle networkHandle, boolean dc, - LoadFlowParametersPointer loadFlowParametersPtr, - CCharPointer provider, ObjectHandle reportNodeHandle, - PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return Util.doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String providerStr = CTypeUtil.toString(provider); - LoadFlowProvider loadFlowProvider = LoadFlowCUtils.getLoadFlowProvider(providerStr); - logger().info("loadflow provider used is : {}", loadFlowProvider.getName()); - - LoadFlowParameters parameters = LoadFlowCUtils.createLoadFlowParameters(dc, loadFlowParametersPtr, loadFlowProvider); - LoadFlow.Runner runner = new LoadFlow.Runner(loadFlowProvider); - ReportNode reportNode = ReportCUtils.getReportNode(reportNodeHandle); - LoadFlowResult result = runner.run(network, network.getVariantManager().getWorkingVariantId(), + public static ArrayPointer runLoadFlow(IsolateThread thread, ObjectHandle networkHandle, boolean dc, + LoadFlowParametersPointer loadFlowParametersPtr, + CCharPointer provider, ObjectHandle reportNodeHandle, + PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return Util.doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String providerStr = CTypeUtil.toString(provider); + LoadFlowProvider loadFlowProvider = LoadFlowCUtils.getLoadFlowProvider(providerStr); + logger().info("loadflow provider used is : {}", loadFlowProvider.getName()); + + LoadFlowParameters parameters = LoadFlowCUtils.createLoadFlowParameters(dc, loadFlowParametersPtr, loadFlowProvider); + LoadFlow.Runner runner = new LoadFlow.Runner(loadFlowProvider); + ReportNode reportNode = ReportCUtils.getReportNode(reportNodeHandle); + LoadFlowResult result = runner.run(network, network.getVariantManager().getWorkingVariantId(), CommonObjects.getComputationManager(), parameters, reportNode); - return createLoadFlowComponentResultArrayPointer(result); + return createLoadFlowComponentResultArrayPointer(result); + } }); } @CEntryPoint(name = "createLoadFlowParameters") public static LoadFlowParametersPointer createLoadFlowParameters(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> convertToLoadFlowParametersPointer(LoadFlowCUtils.createLoadFlowParameters())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public LoadFlowParametersPointer get() { + return convertToLoadFlowParametersPointer(LoadFlowCUtils.createLoadFlowParameters()); + } + }); } @CEntryPoint(name = "freeLoadFlowParameters") public static void freeLoadFlowParameters(IsolateThread thread, LoadFlowParametersPointer loadFlowParametersPtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - freeLoadFlowParametersPointer(loadFlowParametersPtr); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + freeLoadFlowParametersPointer(loadFlowParametersPtr); + } }); } @@ -122,12 +156,12 @@ public static void freeLoadFlowParametersPointer(LoadFlowParametersPointer loadF UnmanagedMemory.free(loadFlowParametersPtr); } - private static PyPowsyblApiHeader.ArrayPointer createLoadFlowComponentResultArrayPointer(LoadFlowResult result) { + private static ArrayPointer createLoadFlowComponentResultArrayPointer(LoadFlowResult result) { List componentResults = result.getComponentResults(); - PyPowsyblApiHeader.LoadFlowComponentResultPointer componentResultPtr = UnmanagedMemory.calloc(componentResults.size() * SizeOf.get(PyPowsyblApiHeader.LoadFlowComponentResultPointer.class)); + LoadFlowComponentResultPointer componentResultPtr = UnmanagedMemory.calloc(componentResults.size() * SizeOf.get(LoadFlowComponentResultPointer.class)); for (int index = 0; index < componentResults.size(); index++) { LoadFlowResult.ComponentResult componentResult = componentResults.get(index); - PyPowsyblApiHeader.LoadFlowComponentResultPointer ptr = componentResultPtr.addressOf(index); + LoadFlowComponentResultPointer ptr = componentResultPtr.addressOf(index); ptr.setConnectedComponentNum(componentResult.getConnectedComponentNum()); ptr.setSynchronousComponentNum(componentResult.getSynchronousComponentNum()); ptr.setStatus(componentResult.getStatus().ordinal()); @@ -140,7 +174,7 @@ private static PyPowsyblApiHeader.ArrayPointer slackBusResults) { + private static void createSlackBusResultPtr(LoadFlowComponentResultPointer ptr, List slackBusResults) { PyPowsyblApiHeader.SlackBusResultPointer slackBusResultPointer = UnmanagedMemory.calloc(slackBusResults.size() * SizeOf.get(PyPowsyblApiHeader.SlackBusResultPointer.class)); for (int i = 0; i < slackBusResults.size(); i++) { LoadFlowResult.SlackBusResult slackBusResult = slackBusResults.get(i); @@ -186,20 +220,26 @@ public static LoadFlowParametersPointer convertToLoadFlowParametersPointer(LoadF } @CEntryPoint(name = "getLoadFlowProviderParametersNames") - public static PyPowsyblApiHeader.ArrayPointer getProviderParametersNames(IsolateThread thread, CCharPointer provider, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String providerStr = CTypeUtil.toString(provider); - return Util.createCharPtrArray(LoadFlowCUtils.getLoadFlowProvider(providerStr).getSpecificParameters().stream().map(Parameter::getName).collect(Collectors.toList())); + public static ArrayPointer getProviderParametersNames(IsolateThread thread, CCharPointer provider, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + String providerStr = CTypeUtil.toString(provider); + return Util.createCharPtrArray(LoadFlowCUtils.getLoadFlowProvider(providerStr).getSpecificParameters().stream().map(Parameter::getName).collect(Collectors.toList())); + } }); } @CEntryPoint(name = "createLoadFlowProviderParametersSeriesArray") - static PyPowsyblApiHeader.ArrayPointer createLoadFlowProviderParametersSeriesArray(IsolateThread thread, CCharPointer providerNamePtr, - PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String providerName = CTypeUtil.toString(providerNamePtr); - LoadFlowProvider provider = LoadFlowCUtils.getLoadFlowProvider(providerName); - return Dataframes.createCDataframe(LoadFlowCUtils.SPECIFIC_PARAMETERS_MAPPER, provider); + static ArrayPointer createLoadFlowProviderParametersSeriesArray(IsolateThread thread, CCharPointer providerNamePtr, + PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + String providerName = CTypeUtil.toString(providerNamePtr); + LoadFlowProvider provider = LoadFlowCUtils.getLoadFlowProvider(providerName); + return Dataframes.createCDataframe(LoadFlowCUtils.SPECIFIC_PARAMETERS_MAPPER, provider); + } }); } diff --git a/java/src/main/java/com/powsybl/python/loadflow/validation/LoadFlowValidationCFunctions.java b/java/src/main/java/com/powsybl/python/loadflow/validation/LoadFlowValidationCFunctions.java index 945ef005f..b56d62db9 100644 --- a/java/src/main/java/com/powsybl/python/loadflow/validation/LoadFlowValidationCFunctions.java +++ b/java/src/main/java/com/powsybl/python/loadflow/validation/LoadFlowValidationCFunctions.java @@ -14,9 +14,8 @@ import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.loadflow.validation.ValidationConfig; import com.powsybl.loadflow.validation.ValidationType; -import com.powsybl.python.commons.Directives; -import com.powsybl.python.commons.PyPowsyblApiHeader; -import com.powsybl.python.commons.PyPowsyblConfiguration; +import com.powsybl.python.commons.*; +import com.powsybl.python.commons.Util.PointerProvider; import com.powsybl.python.network.Dataframes; import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.ObjectHandle; @@ -25,7 +24,6 @@ import org.graalvm.nativeimage.c.function.CEntryPoint; import org.graalvm.nativeimage.UnmanagedMemory; import org.graalvm.nativeimage.c.struct.SizeOf; -import com.powsybl.python.commons.CTypeUtil; import com.powsybl.python.loadflow.LoadFlowCUtils; import com.powsybl.python.loadflow.LoadFlowCFunctions; @@ -37,6 +35,7 @@ * * @author Yichen TANG */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class LoadFlowValidationCFunctions { @@ -48,9 +47,12 @@ public static ArrayPointer createLoadFlowValidationSeriesArray(Is PyPowsyblApiHeader.ValidationType validationType, PyPowsyblApiHeader.LoadFlowValidationParametersPointer loadFlowValidationParametersPtr, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - return createLoadFlowValidationSeriesArray(network, validationType, loadFlowValidationParametersPtr); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + return createLoadFlowValidationSeriesArray(network, validationType, loadFlowValidationParametersPtr); + } }); } @@ -110,7 +112,12 @@ private static ArrayPointer createCDataFrame(InMemoryValidationWr @CEntryPoint(name = "createValidationConfig") public static LoadFlowValidationParametersPointer createValidationConfig(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> convertToLoadFlowValidationParametersPointer(createValidationConfig())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public LoadFlowValidationParametersPointer get() { + return convertToLoadFlowValidationParametersPointer(createValidationConfig()); + } + }); } public static void copyToCLoadFlowValidationParameters(ValidationConfig parameters, LoadFlowValidationParametersPointer cParameters) { @@ -140,7 +147,12 @@ public static LoadFlowValidationParametersPointer convertToLoadFlowValidationPar @CEntryPoint(name = "freeValidationConfig") public static void freeValidationConfig(IsolateThread thread, LoadFlowValidationParametersPointer loadFlowValidationParametersPtr, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> freeLoadFlowValidationParametersPointer(loadFlowValidationParametersPtr)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + freeLoadFlowValidationParametersPointer(loadFlowValidationParametersPtr); + } + }); } public static void freeLoadFlowValidationParametersPointer(LoadFlowValidationParametersPointer loadFlowValidationParametersPtr) { diff --git a/java/src/main/java/com/powsybl/python/logging/LoggingCFunctions.java b/java/src/main/java/com/powsybl/python/logging/LoggingCFunctions.java index 16f4762a5..f4936f8f3 100644 --- a/java/src/main/java/com/powsybl/python/logging/LoggingCFunctions.java +++ b/java/src/main/java/com/powsybl/python/logging/LoggingCFunctions.java @@ -10,6 +10,7 @@ import ch.qos.logback.classic.Logger; import com.powsybl.python.commons.Directives; import com.powsybl.python.commons.PyPowsyblApiHeader; +import com.powsybl.python.commons.Util.PointerProvider; import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.c.CContext; import org.graalvm.nativeimage.c.function.CEntryPoint; @@ -25,6 +26,7 @@ * * @author Sylvain Leclerc */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class LoggingCFunctions { @@ -40,14 +42,22 @@ public interface LoggerCallback extends CFunctionPointer { @CEntryPoint(name = "setupLoggerCallback") public static void setupLoggerCallback(IsolateThread thread, LoggerCallback fpointer, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> loggerCallback = fpointer); + doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public CFunctionPointer get() { + return loggerCallback = fpointer; + } + }); } @CEntryPoint(name = "setLogLevel") public static void setLogLevel(IsolateThread thread, int logLevel, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Logger powsyblLogger = (Logger) LoggerFactory.getLogger("com.powsybl"); - powsyblLogger.setLevel(PyLoggingUtil.pythonLevelToLogbackLevel(logLevel)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Logger powsyblLogger = (Logger) LoggerFactory.getLogger("com.powsybl"); + powsyblLogger.setLevel(PyLoggingUtil.pythonLevelToLogbackLevel(logLevel)); + } }); } } diff --git a/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java b/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java index d37b946c6..85c720e5f 100644 --- a/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java +++ b/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java @@ -17,9 +17,9 @@ import com.powsybl.dataframe.DataframeFilter.AttributeFilterType; import com.powsybl.dataframe.SeriesDataType; import com.powsybl.dataframe.SeriesMetadata; +import com.powsybl.dataframe.network.NetworkDataframeContext; import com.powsybl.dataframe.network.NetworkDataframeMapper; import com.powsybl.dataframe.network.NetworkDataframes; -import com.powsybl.dataframe.network.NetworkDataframeContext; import com.powsybl.dataframe.network.adders.AliasDataframeAdder; import com.powsybl.dataframe.network.adders.NetworkElementAdders; import com.powsybl.dataframe.network.extensions.NetworkExtensions; @@ -66,6 +66,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Paths; import java.util.*; +import java.util.function.BooleanSupplier; import java.util.zip.ZipOutputStream; import static com.powsybl.nad.svg.SvgParameters.EdgeInfoEnum.*; @@ -79,48 +80,67 @@ * * @author Etienne Lesot */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class NetworkCFunctions { - private static final ExportersLoader EXPORTERS_LOADER_SUPPLIER = new ExportersServiceLoader(); - private static final ImportersLoader IMPORTERS_LOADER_SUPPLIER = new ImportersServiceLoader(); - private NetworkCFunctions() { } @CEntryPoint(name = "getNetworkImportFormats") public static ArrayPointer getNetworkImportFormats(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> createCharPtrArray(new ArrayList<>(Importer.getFormats()))); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + return createCharPtrArray(new ArrayList<>(Importer.getFormats())); + } + }); } @CEntryPoint(name = "getNetworkExportFormats") public static ArrayPointer getNetworkExportFormats(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> createCharPtrArray(new ArrayList<>(Exporter.getFormats()))); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + return createCharPtrArray(new ArrayList<>(Exporter.getFormats())); + } + }); } @CEntryPoint(name = "createNetwork") public static ObjectHandle createNetwork(IsolateThread thread, CCharPointer name, CCharPointer id, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String networkName = CTypeUtil.toString(name); - String networkId = CTypeUtil.toString(id); - Network network = Networks.create(networkName, networkId); - return ObjectHandles.getGlobal().create(network); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + String networkName = CTypeUtil.toString(name); + String networkId = CTypeUtil.toString(id); + Network network = Networks.create(networkName, networkId); + return ObjectHandles.getGlobal().create(network); + } }); } @CEntryPoint(name = "getNetworkMetadata") public static NetworkMetadataPointer getNetworkMetadata(IsolateThread thread, ObjectHandle networkHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - return createNetworkMetadata(network); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public NetworkMetadataPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + return createNetworkMetadata(network); + } }); } @CEntryPoint(name = "freeNetworkMetadata") public static void freeNetworkMetadata(IsolateThread thread, NetworkMetadataPointer ptr, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> freeNetworkMetadata(ptr)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + freeNetworkMetadata(ptr); + } + }); } private static NetworkMetadataPointer createNetworkMetadata(Network network) { @@ -144,15 +164,18 @@ private static void freeNetworkMetadata(NetworkMetadataPointer networkMetadataPo public static ObjectHandle loadNetwork(IsolateThread thread, CCharPointer file, CCharPointerPointer parameterNamesPtrPtr, int parameterNamesCount, CCharPointerPointer parameterValuesPtrPtr, int parameterValuesCount, ObjectHandle reportNodeHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String fileStr = CTypeUtil.toString(file); - Properties parameters = createParameters(parameterNamesPtrPtr, parameterNamesCount, parameterValuesPtrPtr, parameterValuesCount); - ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); - if (reportNode == null) { - reportNode = ReportNode.NO_OP; + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + String fileStr = CTypeUtil.toString(file); + Properties parameters = createParameters(parameterNamesPtrPtr, parameterNamesCount, parameterValuesPtrPtr, parameterValuesCount); + ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); + if (reportNode == null) { + reportNode = ReportNode.NO_OP; + } + Network network = Network.read(Paths.get(fileStr), LocalComputationManager.getDefault(), ImportConfig.load(), parameters, new ImportersServiceLoader(), reportNode); + return ObjectHandles.getGlobal().create(network); } - Network network = Network.read(Paths.get(fileStr), LocalComputationManager.getDefault(), ImportConfig.load(), parameters, IMPORTERS_LOADER_SUPPLIER, reportNode); - return ObjectHandles.getGlobal().create(network); }); } @@ -161,19 +184,22 @@ public static ObjectHandle loadNetworkFromString(IsolateThread thread, CCharPoin CCharPointerPointer parameterNamesPtrPtr, int parameterNamesCount, CCharPointerPointer parameterValuesPtrPtr, int parameterValuesCount, ObjectHandle reportNodeHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String fileNameStr = CTypeUtil.toString(fileName); - String fileContentStr = CTypeUtil.toString(fileContent); - Properties parameters = createParameters(parameterNamesPtrPtr, parameterNamesCount, parameterValuesPtrPtr, parameterValuesCount); - ReportNode reportNode = ReportCUtils.getReportNode(reportNodeHandle); - try (InputStream is = new ByteArrayInputStream(fileContentStr.getBytes(StandardCharsets.UTF_8))) { - if (reportNode == null) { - reportNode = ReportNode.NO_OP; + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + String fileNameStr = CTypeUtil.toString(fileName); + String fileContentStr = CTypeUtil.toString(fileContent); + Properties parameters = createParameters(parameterNamesPtrPtr, parameterNamesCount, parameterValuesPtrPtr, parameterValuesCount); + ReportNode reportNode = ReportCUtils.getReportNode(reportNodeHandle); + try (InputStream is = new ByteArrayInputStream(fileContentStr.getBytes(StandardCharsets.UTF_8))) { + if (reportNode == null) { + reportNode = ReportNode.NO_OP; + } + Network network = Network.read(fileNameStr, is, LocalComputationManager.getDefault(), ImportConfig.load(), parameters, new ImportersServiceLoader(), reportNode); + return ObjectHandles.getGlobal().create(network); + } catch (IOException e) { + throw new UncheckedIOException(e); } - Network network = Network.read(fileNameStr, is, LocalComputationManager.getDefault(), ImportConfig.load(), parameters, IMPORTERS_LOADER_SUPPLIER, reportNode); - return ObjectHandles.getGlobal().create(network); - } catch (IOException e) { - throw new UncheckedIOException(e); } }); } @@ -182,39 +208,42 @@ public static ObjectHandle loadNetworkFromString(IsolateThread thread, CCharPoin public static ObjectHandle loadNetworkFromBinaryBuffers(IsolateThread thread, CCharPointerPointer data, CIntPointer dataSizes, int bufferCount, CCharPointerPointer parameterNamesPtrPtr, int parameterNamesCount, CCharPointerPointer parameterValuesPtrPtr, int parameterValuesCount, ObjectHandle reportNodeHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Properties parameters = createParameters(parameterNamesPtrPtr, parameterNamesCount, parameterValuesPtrPtr, parameterValuesCount); - ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); - List bufferSizes = CTypeUtil.toIntegerList(dataSizes, bufferCount); - List dataSourceList = new ArrayList<>(); - for (int i = 0; i < bufferCount; ++i) { - ByteBuffer buffer = CTypeConversion.asByteBuffer(data.read(i), bufferSizes.get(i)); - Optional format = detectCompressionFormat(buffer); - if (format.isPresent() && CompressionFormat.ZIP.equals(format.get())) { - InMemoryZipFileDataSource ds = new InMemoryZipFileDataSource(binaryBufferToBytes(buffer)); - String commonBasename = null; - try { - for (String filename : ds.listNames(".*")) { - String basename = DataSourceUtil.getBaseName(filename); - commonBasename = commonBasename == null ? basename : StringUtils.getCommonPrefix(commonBasename, basename); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + Properties parameters = createParameters(parameterNamesPtrPtr, parameterNamesCount, parameterValuesPtrPtr, parameterValuesCount); + ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); + List bufferSizes = CTypeUtil.toIntegerList(dataSizes, bufferCount); + List dataSourceList = new ArrayList<>(); + for (int i = 0; i < bufferCount; ++i) { + ByteBuffer buffer = CTypeConversion.asByteBuffer(data.read(i), bufferSizes.get(i)); + Optional format = detectCompressionFormat(buffer); + if (format.isPresent() && CompressionFormat.ZIP.equals(format.get())) { + InMemoryZipFileDataSource ds = new InMemoryZipFileDataSource(binaryBufferToBytes(buffer)); + String commonBasename = null; + try { + for (String filename : ds.listNames(".*")) { + String basename = DataSourceUtil.getBaseName(filename); + commonBasename = commonBasename == null ? basename : StringUtils.getCommonPrefix(commonBasename, basename); + } + } catch (IOException e) { + throw new PowsyblException("Unsupported network data format in zip buffer."); } - } catch (IOException e) { - throw new PowsyblException("Unsupported network data format in zip buffer."); - } - if (commonBasename != null) { - ds.setBaseName(commonBasename); + if (commonBasename != null) { + ds.setBaseName(commonBasename); + } + dataSourceList.add(ds); + } else { + throw new PowsyblException("Network loading from memory buffer only supported with zipped networks."); } - dataSourceList.add(ds); - } else { - throw new PowsyblException("Network loading from memory buffer only supported with zipped networks."); } + if (reportNode == null) { + reportNode = ReportNode.NO_OP; + } + MultipleReadOnlyDataSource dataSource = new MultipleReadOnlyDataSource(dataSourceList); + Network network = Network.read(dataSource, parameters, reportNode); + return ObjectHandles.getGlobal().create(network); } - if (reportNode == null) { - reportNode = ReportNode.NO_OP; - } - MultipleReadOnlyDataSource dataSource = new MultipleReadOnlyDataSource(dataSourceList); - Network network = Network.read(dataSource, parameters, reportNode); - return ObjectHandles.getGlobal().create(network); }); } @@ -223,16 +252,19 @@ public static void saveNetwork(IsolateThread thread, ObjectHandle networkHandle, CCharPointerPointer parameterNamesPtrPtr, int parameterNamesCount, CCharPointerPointer parameterValuesPtrPtr, int parameterValuesCount, ObjectHandle reportNodeHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String fileStr = CTypeUtil.toString(file); - String formatStr = CTypeUtil.toString(format); - Properties parameters = createParameters(parameterNamesPtrPtr, parameterNamesCount, parameterValuesPtrPtr, parameterValuesCount); - ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); - if (reportNode == null) { - reportNode = ReportNode.NO_OP; + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String fileStr = CTypeUtil.toString(file); + String formatStr = CTypeUtil.toString(format); + Properties parameters = createParameters(parameterNamesPtrPtr, parameterNamesCount, parameterValuesPtrPtr, parameterValuesCount); + ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); + if (reportNode == null) { + reportNode = ReportNode.NO_OP; + } + network.write(new ExportersServiceLoader(), formatStr, parameters, Paths.get(fileStr), reportNode); } - network.write(EXPORTERS_LOADER_SUPPLIER, formatStr, parameters, Paths.get(fileStr), reportNode); }); } @@ -241,29 +273,32 @@ public static CCharPointer saveNetworkToString(IsolateThread thread, ObjectHandl CCharPointerPointer parameterNamesPtrPtr, int parameterNamesCount, CCharPointerPointer parameterValuesPtrPtr, int parameterValuesCount, ObjectHandle reportNodeHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String formatStr = CTypeUtil.toString(format); - Properties parameters = createParameters(parameterNamesPtrPtr, parameterNamesCount, parameterValuesPtrPtr, parameterValuesCount); - MemDataSource dataSource = new MemDataSource(); - var exporter = Exporter.find(formatStr); - if (exporter == null) { - throw new PowsyblException("No exporter found for '" + formatStr + "' to export as a string"); - } - ReportNode reportNode = ReportCUtils.getReportNode(reportNodeHandle); - exporter.export(network, parameters, dataSource, reportNode); - try { - var names = dataSource.listNames(".*?"); - if (names.size() != 1) { - throw new PowsyblException("Currently we only support string export for single file format(ex, 'XIIDM')."); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public CCharPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String formatStr = CTypeUtil.toString(format); + Properties parameters = createParameters(parameterNamesPtrPtr, parameterNamesCount, parameterValuesPtrPtr, parameterValuesCount); + MemDataSource dataSource = new MemDataSource(); + var exporter = Exporter.find(formatStr); + if (exporter == null) { + throw new PowsyblException("No exporter found for '" + formatStr + "' to export as a string"); } - try (InputStream is = new ByteArrayInputStream(dataSource.getData(Iterables.getOnlyElement(names))); - ByteArrayOutputStream os = new ByteArrayOutputStream()) { - IOUtils.copy(is, os); - return CTypeUtil.toCharPtr(os.toString()); + ReportNode reportNode = ReportCUtils.getReportNode(reportNodeHandle); + exporter.export(network, parameters, dataSource, reportNode); + try { + var names = dataSource.listNames(".*?"); + if (names.size() != 1) { + throw new PowsyblException("Currently we only support string export for single file format(ex, 'XIIDM')."); + } + try (InputStream is = new ByteArrayInputStream(dataSource.getData(Iterables.getOnlyElement(names))); + ByteArrayOutputStream os = new ByteArrayOutputStream()) { + IOUtils.copy(is, os); + return CTypeUtil.toCharPtr(os.toString()); + } + } catch (IOException e) { + throw new UncheckedIOException(e); } - } catch (IOException e) { - throw new UncheckedIOException(e); } }); } @@ -273,33 +308,41 @@ public static ArrayPointer saveNetworkToBinaryBuffer(IsolateThread CCharPointerPointer parameterNamesPtrPtr, int parameterNamesCount, CCharPointerPointer parameterValuesPtrPtr, int parameterValuesCount, ObjectHandle reportNodeHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String formatStr = CTypeUtil.toString(format); - Properties parameters = createParameters(parameterNamesPtrPtr, parameterNamesCount, parameterValuesPtrPtr, parameterValuesCount); - var exporter = Exporter.find(formatStr); - if (exporter == null) { - throw new PowsyblException("No exporter found for '" + formatStr + "' to export as a string"); - } - ReportNode reportNode = ReportCUtils.getReportNode(reportNodeHandle); - // to support all kind of export: simple file or multiple to an archive, - // best is to write to a zip file - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try (ZipOutputStream zos = new ZipOutputStream(bos)) { - DataSource dataSource = new ZipMemDataSource("file", zos); - exporter.export(network, parameters, dataSource, reportNode); - } catch (IOException e) { - throw new UncheckedIOException(e); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String formatStr = CTypeUtil.toString(format); + Properties parameters = createParameters(parameterNamesPtrPtr, parameterNamesCount, parameterValuesPtrPtr, parameterValuesCount); + var exporter = Exporter.find(formatStr); + if (exporter == null) { + throw new PowsyblException("No exporter found for '" + formatStr + "' to export as a string"); + } + ReportNode reportNode = ReportCUtils.getReportNode(reportNodeHandle); + // to support all kind of export: simple file or multiple to an archive, + // best is to write to a zip file + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try (ZipOutputStream zos = new ZipOutputStream(bos)) { + DataSource dataSource = new ZipMemDataSource("file", zos); + exporter.export(network, parameters, dataSource, reportNode); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + byte[] bytes = bos.toByteArray(); + return Util.createByteArray(bytes); } - byte[] bytes = bos.toByteArray(); - return Util.createByteArray(bytes); }); } @CEntryPoint(name = "freeNetworkBinaryBuffer") public static void freeNetworkBinaryBuffer(IsolateThread thread, PyPowsyblApiHeader.ArrayPointer byteArrayPtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> freeArrayPointer(byteArrayPtr)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + freeArrayPointer(byteArrayPtr); + } + }); } @CEntryPoint(name = "reduceNetwork") @@ -310,31 +353,34 @@ public static void reduceNetwork(IsolateThread thread, ObjectHandle networkHandl CIntPointer depthsPtr, int depthsCount, boolean withDanglingLines, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - ReductionOptions options = new ReductionOptions(); - options.withDanglingLlines(withDanglingLines); - List predicates = new ArrayList<>(); - if (vMax != Double.MAX_VALUE || vMin != 0) { - predicates.add(new NominalVoltageNetworkPredicate(vMin, vMax)); - } - if (idsCount != 0) { - List ids = toStringList(idsPtrPtr, idsCount); - predicates.add(new IdentifierNetworkPredicate(ids)); - } - if (depthsCount != 0) { - final List depths = CTypeUtil.toIntegerList(depthsPtr, depthsCount); - final List voltageLeveles = toStringList(vlsPtrPtr, vlsCount); - for (int i = 0; i < depths.size(); i++) { - predicates.add(new SubNetworkPredicate(network.getVoltageLevel(voltageLeveles.get(i)), depths.get(i))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + ReductionOptions options = new ReductionOptions(); + options.withDanglingLlines(withDanglingLines); + List predicates = new ArrayList<>(); + if (vMax != Double.MAX_VALUE || vMin != 0) { + predicates.add(new NominalVoltageNetworkPredicate(vMin, vMax)); + } + if (idsCount != 0) { + List ids = toStringList(idsPtrPtr, idsCount); + predicates.add(new IdentifierNetworkPredicate(ids)); + } + if (depthsCount != 0) { + final List depths = CTypeUtil.toIntegerList(depthsPtr, depthsCount); + final List voltageLeveles = toStringList(vlsPtrPtr, vlsCount); + for (int i = 0; i < depths.size(); i++) { + predicates.add(new SubNetworkPredicate(network.getVoltageLevel(voltageLeveles.get(i)), depths.get(i))); + } } + final OrNetworkPredicate orNetworkPredicate = new OrNetworkPredicate(predicates); + NetworkReducer.builder() + .withNetworkPredicate(orNetworkPredicate) + .withReductionOptions(options) + .build() + .reduce(network); } - final OrNetworkPredicate orNetworkPredicate = new OrNetworkPredicate(predicates); - NetworkReducer.builder() - .withNetworkPredicate(orNetworkPredicate) - .withReductionOptions(options) - .build() - .reduce(network); }); } @@ -354,44 +400,59 @@ public static ArrayPointer getNetworkElementsIds(IsolateThr CDoublePointer nominalVoltagePtr, int nominalVoltageCount, CCharPointerPointer countryPtr, int countryCount, boolean mainCc, boolean mainSc, boolean notConnectedToSameBusAtBothSides, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - Set nominalVoltages = new HashSet<>(CTypeUtil.toDoubleList(nominalVoltagePtr, nominalVoltageCount)); - Set countries = new HashSet<>(toStringList(countryPtr, countryCount)); - List elementsIds = NetworkUtil.getElementsIds(network, elementType, nominalVoltages, countries, mainCc, mainSc, notConnectedToSameBusAtBothSides); - return createCharPtrArray(elementsIds); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + Set nominalVoltages = new HashSet<>(CTypeUtil.toDoubleList(nominalVoltagePtr, nominalVoltageCount)); + Set countries = new HashSet<>(toStringList(countryPtr, countryCount)); + List elementsIds = NetworkUtil.getElementsIds(network, elementType, nominalVoltages, countries, mainCc, mainSc, notConnectedToSameBusAtBothSides); + return createCharPtrArray(elementsIds); + } }); } @CEntryPoint(name = "cloneVariant") public static void cloneVariant(IsolateThread thread, ObjectHandle networkHandle, CCharPointer src, CCharPointer variant, boolean mayOverwrite, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - network.getVariantManager().cloneVariant(CTypeUtil.toString(src), CTypeUtil.toString(variant), mayOverwrite); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + network.getVariantManager().cloneVariant(CTypeUtil.toString(src), CTypeUtil.toString(variant), mayOverwrite); + } }); } @CEntryPoint(name = "setWorkingVariant") public static void setWorkingVariant(IsolateThread thread, ObjectHandle networkHandle, CCharPointer variant, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - network.getVariantManager().setWorkingVariant(CTypeUtil.toString(variant)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + network.getVariantManager().setWorkingVariant(CTypeUtil.toString(variant)); + } }); } @CEntryPoint(name = "removeVariant") public static void removeVariant(IsolateThread thread, ObjectHandle networkHandle, CCharPointer variant, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - network.getVariantManager().removeVariant(CTypeUtil.toString(variant)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + network.getVariantManager().removeVariant(CTypeUtil.toString(variant)); + } }); } @CEntryPoint(name = "getVariantsIds") public static ArrayPointer getVariantsIds(IsolateThread thread, ObjectHandle networkHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - return createCharPtrArray(List.copyOf(network.getVariantManager().getVariantIds())); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + return createCharPtrArray(List.copyOf(network.getVariantManager().getVariantIds())); + } }); } @@ -417,11 +478,14 @@ public static ArrayPointer createNetworkElementsSeriesArray(Isola boolean perUnit, double nominalApparentPower, ExceptionHandlerPointer exceptionHandlerPtr) { - return Util.doCatch(exceptionHandlerPtr, () -> { - NetworkDataframeMapper mapper = NetworkDataframes.getDataframeMapper(convert(elementType)); - Network network = ObjectHandles.getGlobal().get(networkHandle); - DataframeFilter dataframeFilter = createDataframeFilter(filterAttributesType, attributesPtrPtr, attributesCount, selectedElementsDataframe); - return Dataframes.createCDataframe(mapper, network, dataframeFilter, new NetworkDataframeContext(perUnit, nominalApparentPower)); + return Util.doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + NetworkDataframeMapper mapper = NetworkDataframes.getDataframeMapper(convert(elementType)); + Network network = ObjectHandles.getGlobal().get(networkHandle); + DataframeFilter dataframeFilter = createDataframeFilter(filterAttributesType, attributesPtrPtr, attributesCount, selectedElementsDataframe); + return Dataframes.createCDataframe(mapper, network, dataframeFilter, new NetworkDataframeContext(perUnit, nominalApparentPower)); + } }); } @@ -433,25 +497,32 @@ public static ArrayPointer createNetworkElemen String name = CTypeUtil.toString(extensionName); String tempName = CTypeUtil.toString(cTableName); String tableName = tempName.isEmpty() ? null : tempName; - return doCatch(exceptionHandlerPtr, () -> { - NetworkDataframeMapper mapper = NetworkDataframes.getExtensionDataframeMapper(name, tableName); - if (mapper != null) { - Network network = ObjectHandles.getGlobal().get(networkHandle); - return Dataframes.createCDataframe(mapper, network, new DataframeFilter(), NetworkDataframeContext.DEFAULT); - } else { - throw new PowsyblException("extension " + name + " not found"); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + NetworkDataframeMapper mapper = NetworkDataframes.getExtensionDataframeMapper(name, tableName); + if (mapper != null) { + Network network = ObjectHandles.getGlobal().get(networkHandle); + return Dataframes.createCDataframe(mapper, network, new DataframeFilter(), NetworkDataframeContext.DEFAULT); + } else { + throw new PowsyblException("extension " + name + " not found"); + } } }); } @CEntryPoint(name = "getExtensionsNames") public static ArrayPointer getExtensionsNames(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> createCharPtrArray(List.copyOf(NetworkExtensions.getExtensionsNames()))); + return doCatch(exceptionHandlerPtr, () -> { + return createCharPtrArray(List.copyOf(NetworkExtensions.getExtensionsNames())); + }); } @CEntryPoint(name = "getExtensionsInformation") public static ArrayPointer getExtensionsInformation(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> NetworkExtensions.getExtensionInformation(NetworkDataframeContext.DEFAULT)); + return doCatch(exceptionHandlerPtr, () -> { + return NetworkExtensions.getExtensionInformation(NetworkDataframeContext.DEFAULT); + }); } @CEntryPoint(name = "createElement") @@ -459,14 +530,17 @@ public static void createElement(IsolateThread thread, ObjectHandle networkHandl ElementType elementType, DataframeArrayPointer cDataframes, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - DataframeElementType type = convert(elementType); - List dataframes = new ArrayList<>(); - for (int i = 0; i < cDataframes.getDataframesCount(); i++) { - dataframes.add(createDataframe(cDataframes.getDataframes().addressOf(i))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + DataframeElementType type = convert(elementType); + List dataframes = new ArrayList<>(); + for (int i = 0; i < cDataframes.getDataframesCount(); i++) { + dataframes.add(createDataframe(cDataframes.getDataframes().addressOf(i))); + } + NetworkElementAdders.addElements(type, network, dataframes); } - NetworkElementAdders.addElements(type, network, dataframes); }); } @@ -475,11 +549,14 @@ public static void updateNetworkElementsWithSeries(IsolateThread thread, ObjectH DataframePointer dataframe, boolean perUnit, double nominalApparentPower, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - UpdatingDataframe updatingDataframe = createDataframe(dataframe); - NetworkDataframes.getDataframeMapper(convert(elementType)) - .updateSeries(network, updatingDataframe, new NetworkDataframeContext(perUnit, nominalApparentPower)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + UpdatingDataframe updatingDataframe = createDataframe(dataframe); + NetworkDataframes.getDataframeMapper(convert(elementType)) + .updateSeries(network, updatingDataframe, new NetworkDataframeContext(perUnit, nominalApparentPower)); + } }); } @@ -487,46 +564,52 @@ public static void updateNetworkElementsWithSeries(IsolateThread thread, ObjectH public static void removeAliases(IsolateThread thread, ObjectHandle networkHandle, DataframePointer cDataframe, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - UpdatingDataframe dataframe = createDataframe(cDataframe); - AliasDataframeAdder.deleteElements(network, dataframe); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + UpdatingDataframe dataframe = createDataframe(cDataframe); + AliasDataframeAdder.deleteElements(network, dataframe); + } }); } @CEntryPoint(name = "removeNetworkElements") public static void removeNetworkElements(IsolateThread thread, ObjectHandle networkHandle, CCharPointerPointer cElementIds, int elementCount, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - List elementIds = CTypeUtil.toStringList(cElementIds, elementCount); - elementIds.forEach(elementId -> { - Identifiable identifiable = network.getIdentifiable(elementId); - if (identifiable == null) { - throw new PowsyblException(String.format("identifiable with id : %s was not found", elementId)); - } - if (identifiable instanceof Connectable) { - ((Connectable) identifiable).remove(); - } else if (identifiable instanceof HvdcLine hvdcLine) { - hvdcLine.remove(); - } else if (identifiable instanceof VoltageLevel voltageLevel) { - voltageLevel.remove(); - } else if (identifiable instanceof Substation substation) { - substation.remove(); - } else if (identifiable instanceof Switch sw) { - VoltageLevel voltageLevel = sw.getVoltageLevel(); - switch (voltageLevel.getTopologyKind()) { - case NODE_BREAKER -> voltageLevel.getNodeBreakerView().removeSwitch(identifiable.getId()); - case BUS_BREAKER -> voltageLevel.getBusBreakerView().removeSwitch(identifiable.getId()); - default -> - throw new PowsyblException("this voltage level does not have a proper topology kind"); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + List elementIds = CTypeUtil.toStringList(cElementIds, elementCount); + elementIds.forEach(elementId -> { + Identifiable identifiable = network.getIdentifiable(elementId); + if (identifiable == null) { + throw new PowsyblException(String.format("identifiable with id : %s was not found", elementId)); } - } else if (identifiable instanceof TieLine tieLine) { - tieLine.remove(); - } else { - throw new PowsyblException(String.format("identifiable with id : %s can't be removed", identifiable.getId())); - } - }); + if (identifiable instanceof Connectable) { + ((Connectable) identifiable).remove(); + } else if (identifiable instanceof HvdcLine hvdcLine) { + hvdcLine.remove(); + } else if (identifiable instanceof VoltageLevel voltageLevel) { + voltageLevel.remove(); + } else if (identifiable instanceof Substation substation) { + substation.remove(); + } else if (identifiable instanceof Switch sw) { + VoltageLevel voltageLevel = sw.getVoltageLevel(); + switch (voltageLevel.getTopologyKind()) { + case NODE_BREAKER -> voltageLevel.getNodeBreakerView().removeSwitch(identifiable.getId()); + case BUS_BREAKER -> voltageLevel.getBusBreakerView().removeSwitch(identifiable.getId()); + default -> + throw new PowsyblException("this voltage level does not have a proper topology kind"); + } + } else if (identifiable instanceof TieLine tieLine) { + tieLine.remove(); + } else { + throw new PowsyblException(String.format("identifiable with id : %s can't be removed", identifiable.getId())); + } + }); + } }); } @@ -555,89 +638,116 @@ public static UpdatingDataframe createDataframe(DataframePointer dataframe) { @CEntryPoint(name = "getNodeBreakerViewSwitches") public static ArrayPointer getNodeBreakerViewSwitches(IsolateThread thread, ObjectHandle networkHandle, CCharPointer voltageLevel, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - VoltageLevel.NodeBreakerView nodeBreakerView = network.getVoltageLevel(CTypeUtil.toString(voltageLevel)).getNodeBreakerView(); - return Dataframes.createCDataframe(Dataframes.nodeBreakerViewSwitches(), nodeBreakerView); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + VoltageLevel.NodeBreakerView nodeBreakerView = network.getVoltageLevel(CTypeUtil.toString(voltageLevel)).getNodeBreakerView(); + return Dataframes.createCDataframe(Dataframes.nodeBreakerViewSwitches(), nodeBreakerView); + } }); } @CEntryPoint(name = "getNodeBreakerViewNodes") public static ArrayPointer getNodeBreakerViewNodes(IsolateThread thread, ObjectHandle networkHandle, CCharPointer voltageLevel, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - VoltageLevel.NodeBreakerView nodeBreakerView = network.getVoltageLevel(CTypeUtil.toString(voltageLevel)).getNodeBreakerView(); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + VoltageLevel.NodeBreakerView nodeBreakerView = network.getVoltageLevel(CTypeUtil.toString(voltageLevel)).getNodeBreakerView(); - return Dataframes.createCDataframe(Dataframes.nodeBreakerViewNodes(), nodeBreakerView); + return Dataframes.createCDataframe(Dataframes.nodeBreakerViewNodes(), nodeBreakerView); + } }); } @CEntryPoint(name = "getNodeBreakerViewInternalConnections") public static ArrayPointer getNodeBreakerViewInternalConnections(IsolateThread thread, ObjectHandle networkHandle, CCharPointer voltageLevel, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - VoltageLevel.NodeBreakerView nodeBreakerView = network.getVoltageLevel(CTypeUtil.toString(voltageLevel)).getNodeBreakerView(); - return Dataframes.createCDataframe(Dataframes.nodeBreakerViewInternalConnection(), nodeBreakerView); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + VoltageLevel.NodeBreakerView nodeBreakerView = network.getVoltageLevel(CTypeUtil.toString(voltageLevel)).getNodeBreakerView(); + return Dataframes.createCDataframe(Dataframes.nodeBreakerViewInternalConnection(), nodeBreakerView); + } }); } @CEntryPoint(name = "getBusBreakerViewSwitches") public static PyPowsyblApiHeader.ArrayPointer getBusBreakerViewSwitches(IsolateThread thread, ObjectHandle networkHandle, CCharPointer voltageLevel, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - VoltageLevel.BusBreakerView busBreakerView = network.getVoltageLevel(CTypeUtil.toString(voltageLevel)).getBusBreakerView(); - return Dataframes.createCDataframe(Dataframes.busBreakerViewSwitches(), busBreakerView); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + VoltageLevel.BusBreakerView busBreakerView = network.getVoltageLevel(CTypeUtil.toString(voltageLevel)).getBusBreakerView(); + return Dataframes.createCDataframe(Dataframes.busBreakerViewSwitches(), busBreakerView); + } }); } @CEntryPoint(name = "getBusBreakerViewBuses") public static PyPowsyblApiHeader.ArrayPointer getBusBreakerViewBuses(IsolateThread thread, ObjectHandle networkHandle, CCharPointer voltageLevel, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - VoltageLevel voltageLevel1 = network.getVoltageLevel(CTypeUtil.toString(voltageLevel)); - return Dataframes.createCDataframe(Dataframes.busBreakerViewBuses(), voltageLevel1); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + VoltageLevel voltageLevel1 = network.getVoltageLevel(CTypeUtil.toString(voltageLevel)); + return Dataframes.createCDataframe(Dataframes.busBreakerViewBuses(), voltageLevel1); + } }); } @CEntryPoint(name = "getBusBreakerViewElements") public static PyPowsyblApiHeader.ArrayPointer getBusBreakerViewElements(IsolateThread thread, ObjectHandle networkHandle, CCharPointer voltageLevel, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - VoltageLevel voltageLevel1 = network.getVoltageLevel(CTypeUtil.toString(voltageLevel)); - return Dataframes.createCDataframe(Dataframes.busBreakerViewElements(), voltageLevel1); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + VoltageLevel voltageLevel1 = network.getVoltageLevel(CTypeUtil.toString(voltageLevel)); + return Dataframes.createCDataframe(Dataframes.busBreakerViewElements(), voltageLevel1); + } }); } @CEntryPoint(name = "merge") public static ObjectHandle merge(IsolateThread thread, VoidPointerPointer networkHandles, int networkCount, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network[] networks = new Network[networkCount]; - for (int i = 0; i < networkCount; ++i) { - ObjectHandle networkHandle = networkHandles.read(i); - Network network = ObjectHandles.getGlobal().get(networkHandle); - networks[i] = network; + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + Network[] networks = new Network[networkCount]; + for (int i = 0; i < networkCount; ++i) { + ObjectHandle networkHandle = networkHandles.read(i); + Network network = ObjectHandles.getGlobal().get(networkHandle); + networks[i] = network; + } + return ObjectHandles.getGlobal().create(Network.merge(networks)); } - return ObjectHandles.getGlobal().create(Network.merge(networks)); }); } @CEntryPoint(name = "getSeriesMetadata") public static DataframeMetadataPointer getSeriesMetadata(IsolateThread thread, ElementType elementType, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - DataframeElementType type = convert(elementType); - List seriesMetadata = NetworkDataframes.getDataframeMapper(type).getSeriesMetadata(); - return CTypeUtil.createSeriesMetadata(seriesMetadata); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public DataframeMetadataPointer get() { + DataframeElementType type = convert(elementType); + List seriesMetadata = NetworkDataframes.getDataframeMapper(type).getSeriesMetadata(); + return CTypeUtil.createSeriesMetadata(seriesMetadata); + } }); } @CEntryPoint(name = "freeDataframeMetadata") public static void freeDataframeMetadata(IsolateThread thread, DataframeMetadataPointer metadata, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - freeDataframeMetadataContent(metadata); - UnmanagedMemory.free(metadata); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + freeDataframeMetadataContent(metadata); + UnmanagedMemory.free(metadata); + } }); } @@ -645,56 +755,65 @@ public static void freeDataframeMetadata(IsolateThread thread, DataframeMetadata public static DataframesMetadataPointer getCreationMetadata(IsolateThread thread, ElementType elementType, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - DataframeElementType type = convert(elementType); - List> metadata = NetworkElementAdders.getAdder(type).getMetadata(); - DataframeMetadataPointer dataframeMetadataArray = UnmanagedMemory.calloc(metadata.size() * SizeOf.get(DataframeMetadataPointer.class)); - int i = 0; - for (List dataframeMetadata : metadata) { - CTypeUtil.createSeriesMetadata(dataframeMetadata, dataframeMetadataArray.addressOf(i)); - i++; - } + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public DataframesMetadataPointer get() { + DataframeElementType type = convert(elementType); + List> metadata = NetworkElementAdders.getAdder(type).getMetadata(); + DataframeMetadataPointer dataframeMetadataArray = UnmanagedMemory.calloc(metadata.size() * SizeOf.get(DataframeMetadataPointer.class)); + int i = 0; + for (List dataframeMetadata : metadata) { + CTypeUtil.createSeriesMetadata(dataframeMetadata, dataframeMetadataArray.addressOf(i)); + i++; + } - DataframesMetadataPointer res = UnmanagedMemory.calloc(SizeOf.get(DataframesMetadataPointer.class)); - res.setDataframesMetadata(dataframeMetadataArray); - res.setDataframesCount(metadata.size()); - return res; + DataframesMetadataPointer res = UnmanagedMemory.calloc(SizeOf.get(DataframesMetadataPointer.class)); + res.setDataframesMetadata(dataframeMetadataArray); + res.setDataframesCount(metadata.size()); + return res; + } }); } @CEntryPoint(name = "freeDataframesMetadata") public static void freeDataframesMetadata(IsolateThread thread, DataframesMetadataPointer cMetadata, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - for (int i = 0; i < cMetadata.getDataframesCount(); i++) { - DataframeMetadataPointer cDataframeMetadata = cMetadata.getDataframesMetadata().addressOf(i); - freeDataframeMetadataContent(cDataframeMetadata); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + for (int i = 0; i < cMetadata.getDataframesCount(); i++) { + DataframeMetadataPointer cDataframeMetadata = cMetadata.getDataframesMetadata().addressOf(i); + freeDataframeMetadataContent(cDataframeMetadata); + } + UnmanagedMemory.free(cMetadata.getDataframesMetadata()); + UnmanagedMemory.free(cMetadata); } - UnmanagedMemory.free(cMetadata.getDataframesMetadata()); - UnmanagedMemory.free(cMetadata); }); } @CEntryPoint(name = "addNetworkElementProperties") public static void addNetworkElementProperties(IsolateThread thread, ObjectHandle networkHandle, DataframePointer properties, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - UpdatingDataframe propertiesDataframe = createDataframe(properties); - Objects.requireNonNull(propertiesDataframe); - Network network = ObjectHandles.getGlobal().get(networkHandle); - StringSeries idSerie = propertiesDataframe.getStrings("id"); - if (idSerie == null) { - throw new PowsyblException("id is missing"); - } - for (SeriesMetadata column : propertiesDataframe.getSeriesMetadata()) { - if (!column.isIndex() && column.getType() == SeriesDataType.STRING) { - String seriesName = column.getName(); - StringSeries columnSerie = propertiesDataframe.getStrings(seriesName); - for (int i = 0; i < propertiesDataframe.getRowCount(); i++) { - String id = idSerie.get(i); - Identifiable identifiable = network.getIdentifiable(id); - if (identifiable != null) { - identifiable.setProperty(seriesName, columnSerie.get(i)); - } else { - throw new PowsyblException(String.format("identifiable with id : %s does not exist", id)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + UpdatingDataframe propertiesDataframe = createDataframe(properties); + Objects.requireNonNull(propertiesDataframe); + Network network = ObjectHandles.getGlobal().get(networkHandle); + StringSeries idSerie = propertiesDataframe.getStrings("id"); + if (idSerie == null) { + throw new PowsyblException("id is missing"); + } + for (SeriesMetadata column : propertiesDataframe.getSeriesMetadata()) { + if (!column.isIndex() && column.getType() == SeriesDataType.STRING) { + String seriesName = column.getName(); + StringSeries columnSerie = propertiesDataframe.getStrings(seriesName); + for (int i = 0; i < propertiesDataframe.getRowCount(); i++) { + String id = idSerie.get(i); + Identifiable identifiable = network.getIdentifiable(id); + if (identifiable != null) { + identifiable.setProperty(seriesName, columnSerie.get(i)); + } else { + throw new PowsyblException(String.format("identifiable with id : %s does not exist", id)); + } } } } @@ -704,11 +823,14 @@ public static void addNetworkElementProperties(IsolateThread thread, ObjectHandl @CEntryPoint(name = "removeNetworkElementProperties") public static void removeNetworkElementProperties(IsolateThread thread, ObjectHandle networkHandle, CCharPointerPointer idsPointer, int idsCount, CCharPointerPointer propertiesPointer, int propertiesCount, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - List ids = CTypeUtil.toStringList(idsPointer, idsCount); - List properties = CTypeUtil.toStringList(propertiesPointer, propertiesCount); - ids.forEach(id -> properties.forEach(property -> network.getIdentifiable(id).removeProperty(property))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + List ids = CTypeUtil.toStringList(idsPointer, idsCount); + List properties = CTypeUtil.toStringList(propertiesPointer, propertiesCount); + ids.forEach(id -> properties.forEach(property -> network.getIdentifiable(id).removeProperty(property))); + } }); } @@ -739,20 +861,23 @@ private static void createSeriesMetadata(List metadata, Datafram public static void updateNetworkElementsExtensionsWithSeries(IsolateThread thread, ObjectHandle networkHandle, CCharPointer namePtr, CCharPointer tableNamePtr, DataframePointer dataframe, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - String name = CTypeUtil.toString(namePtr); - String tmpName = CTypeUtil.toString(tableNamePtr); - String tableName = tmpName.isEmpty() ? null : tmpName; - NetworkDataframeMapper mapper = NetworkDataframes.getExtensionDataframeMapper(name, tableName); - if (mapper != null) { - Network network = ObjectHandles.getGlobal().get(networkHandle); - UpdatingDataframe updatingDataframe = createDataframe(dataframe); - mapper.updateSeries(network, updatingDataframe, NetworkDataframeContext.DEFAULT); - } else { - if (tableName != null) { - throw new PowsyblException("table " + tableName + " of extension " + name + " not found"); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + String name = CTypeUtil.toString(namePtr); + String tmpName = CTypeUtil.toString(tableNamePtr); + String tableName = tmpName.isEmpty() ? null : tmpName; + NetworkDataframeMapper mapper = NetworkDataframes.getExtensionDataframeMapper(name, tableName); + if (mapper != null) { + Network network = ObjectHandles.getGlobal().get(networkHandle); + UpdatingDataframe updatingDataframe = createDataframe(dataframe); + mapper.updateSeries(network, updatingDataframe, NetworkDataframeContext.DEFAULT); + } else { + if (tableName != null) { + throw new PowsyblException("table " + tableName + " of extension " + name + " not found"); + } + throw new PowsyblException("extension " + name + " not found"); } - throw new PowsyblException("extension " + name + " not found"); } }); } @@ -762,27 +887,33 @@ public static void removeExtensions(IsolateThread thread, ObjectHandle networkHa CCharPointer namePtr, CCharPointerPointer idsPtr, int idsCount, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String name = CTypeUtil.toString(namePtr); - List ids = CTypeUtil.toStringList(idsPtr, idsCount); - NetworkExtensions.removeExtensions(network, name, ids); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String name = CTypeUtil.toString(namePtr); + List ids = CTypeUtil.toStringList(idsPtr, idsCount); + NetworkExtensions.removeExtensions(network, name, ids); + } }); } @CEntryPoint(name = "getExtensionSeriesMetadata") public static DataframeMetadataPointer getExtensionSeriesMetadata(IsolateThread thread, CCharPointer namePtr, CCharPointer tableNamePtr, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String name = CTypeUtil.toString(namePtr); - String tmpName = CTypeUtil.toString(tableNamePtr); - String tableName = tmpName.equals("") ? null : tmpName; - NetworkDataframeMapper mapper = NetworkDataframes.getExtensionDataframeMapper(name, tableName); - if (mapper != null) { - List seriesMetadata = mapper.getSeriesMetadata(); - return CTypeUtil.createSeriesMetadata(seriesMetadata); - } else { - throw new PowsyblException("extension " + name + " not found"); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public DataframeMetadataPointer get() { + String name = CTypeUtil.toString(namePtr); + String tmpName = CTypeUtil.toString(tableNamePtr); + String tableName = tmpName.equals("") ? null : tmpName; + NetworkDataframeMapper mapper = NetworkDataframes.getExtensionDataframeMapper(name, tableName); + if (mapper != null) { + List seriesMetadata = mapper.getSeriesMetadata(); + return CTypeUtil.createSeriesMetadata(seriesMetadata); + } else { + throw new PowsyblException("extension " + name + " not found"); + } } }); } @@ -792,14 +923,17 @@ public static void createExtensions(IsolateThread thread, ObjectHandle networkHa CCharPointer namePtr, DataframeArrayPointer cDataframes, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String name = CTypeUtil.toString(namePtr); - List dataframes = new ArrayList<>(); - for (int i = 0; i < cDataframes.getDataframesCount(); i++) { - dataframes.add(createDataframe(cDataframes.getDataframes().addressOf(i))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String name = CTypeUtil.toString(namePtr); + List dataframes = new ArrayList<>(); + for (int i = 0; i < cDataframes.getDataframesCount(); i++) { + dataframes.add(createDataframe(cDataframes.getDataframes().addressOf(i))); + } + NetworkElementAdders.addExtensions(name, network, dataframes); } - NetworkElementAdders.addExtensions(name, network, dataframes); }); } @@ -807,66 +941,81 @@ public static void createExtensions(IsolateThread thread, ObjectHandle networkHa public static DataframesMetadataPointer getExtensionsCreationMetadata(IsolateThread thread, CCharPointer namePtr, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String name = CTypeUtil.toString(namePtr); - List> metadata = NetworkElementAdders.getExtensionAdder(name).getMetadata(); - DataframeMetadataPointer dataframeMetadataArray = UnmanagedMemory.calloc(metadata.size() * SizeOf.get(DataframeMetadataPointer.class)); - int i = 0; - for (List dataframeMetadata : metadata) { - CTypeUtil.createSeriesMetadata(dataframeMetadata, dataframeMetadataArray.addressOf(i)); - i++; - } + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public DataframesMetadataPointer get() { + String name = CTypeUtil.toString(namePtr); + List> metadata = NetworkElementAdders.getExtensionAdder(name).getMetadata(); + DataframeMetadataPointer dataframeMetadataArray = UnmanagedMemory.calloc(metadata.size() * SizeOf.get(DataframeMetadataPointer.class)); + int i = 0; + for (List dataframeMetadata : metadata) { + CTypeUtil.createSeriesMetadata(dataframeMetadata, dataframeMetadataArray.addressOf(i)); + i++; + } - DataframesMetadataPointer res = UnmanagedMemory.calloc(SizeOf.get(DataframesMetadataPointer.class)); - res.setDataframesMetadata(dataframeMetadataArray); - res.setDataframesCount(metadata.size()); - return res; + DataframesMetadataPointer res = UnmanagedMemory.calloc(SizeOf.get(DataframesMetadataPointer.class)); + res.setDataframesMetadata(dataframeMetadataArray); + res.setDataframesCount(metadata.size()); + return res; + } }); } @CEntryPoint(name = "createImporterParametersSeriesArray") static ArrayPointer createImporterParametersSeriesArray(IsolateThread thread, CCharPointer formatPtr, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String format = CTypeUtil.toString(formatPtr); - Importer importer = Importer.find(format); - if (importer == null) { - throw new PowsyblException("Format '" + format + "' not supported"); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + String format = CTypeUtil.toString(formatPtr); + Importer importer = Importer.find(format); + if (importer == null) { + throw new PowsyblException("Format '" + format + "' not supported"); + } + return Dataframes.createCDataframe(Dataframes.importerParametersMapper(), importer); } - return Dataframes.createCDataframe(Dataframes.importerParametersMapper(), importer); }); } @CEntryPoint(name = "createExporterParametersSeriesArray") static ArrayPointer createExporterParametersSeriesArray(IsolateThread thread, CCharPointer formatPtr, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String format = CTypeUtil.toString(formatPtr); - var exporter = Exporter.find(format); - if (exporter == null) { - throw new PowsyblException("Format '" + format + "' not supported"); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + String format = CTypeUtil.toString(formatPtr); + var exporter = Exporter.find(format); + if (exporter == null) { + throw new PowsyblException("Format '" + format + "' not supported"); + } + return Dataframes.createCDataframe(Dataframes.exporterParametersMapper(), exporter); } - return Dataframes.createCDataframe(Dataframes.exporterParametersMapper(), exporter); }); } @CEntryPoint(name = "updateSwitchPosition") public static boolean updateSwitchPosition(IsolateThread thread, ObjectHandle networkHandle, CCharPointer id, boolean open, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String idStr = CTypeUtil.toString(id); - return NetworkUtil.updateSwitchPosition(network, idStr, open); + return doCatch(exceptionHandlerPtr, new BooleanSupplier() { + @Override + public boolean getAsBoolean() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String idStr = CTypeUtil.toString(id); + return NetworkUtil.updateSwitchPosition(network, idStr, open); + } }); } @CEntryPoint(name = "updateConnectableStatus") public static boolean updateConnectableStatus(IsolateThread thread, ObjectHandle networkHandle, CCharPointer id, boolean connected, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String idStr = CTypeUtil.toString(id); - return NetworkUtil.updateConnectableStatus(network, idStr, connected); + return doCatch(exceptionHandlerPtr, new BooleanSupplier() { + @Override + public boolean getAsBoolean() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String idStr = CTypeUtil.toString(id); + return NetworkUtil.updateConnectableStatus(network, idStr, connected); + } }); } @@ -892,7 +1041,9 @@ public static SldParametersPointer convertToSldParametersPointer(SldParameters p @CEntryPoint(name = "createSldParameters") public static SldParametersPointer createSldParameters(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> convertToSldParametersPointer(SingleLineDiagramUtil.createSldParameters())); + return doCatch(exceptionHandlerPtr, () -> { + return convertToSldParametersPointer(SingleLineDiagramUtil.createSldParameters()); + }); } public static NadParametersPointer convertToNadParametersPointer(NadParameters parameters) { @@ -922,7 +1073,9 @@ public static void copyToCNadParameters(NadParameters parameters, NadParametersP @CEntryPoint(name = "createNadParameters") public static NadParametersPointer createNadParameters(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> convertToNadParametersPointer(NetworkAreaDiagramUtil.createNadParameters())); + return doCatch(exceptionHandlerPtr, () -> { + return convertToNadParametersPointer(NetworkAreaDiagramUtil.createNadParameters()); + }); } public static void freeSldParametersPointer(SldParametersPointer sldParametersPtr) { @@ -932,16 +1085,22 @@ public static void freeSldParametersPointer(SldParametersPointer sldParametersPt @CEntryPoint(name = "freeSldParameters") public static void freeSldParameters(IsolateThread thread, SldParametersPointer sldParametersPtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - freeSldParametersPointer(sldParametersPtr); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + freeSldParametersPointer(sldParametersPtr); + } }); } @CEntryPoint(name = "freeNadParameters") public static void freeNadParameters(IsolateThread thread, NadParametersPointer nadParametersPointer, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - UnmanagedMemory.free(nadParametersPointer); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + UnmanagedMemory.free(nadParametersPointer); + } }); } @@ -996,13 +1155,16 @@ public static NadParameters convertNadParameters(NadParametersPointer nadParamet public static void writeSingleLineDiagramSvg(IsolateThread thread, ObjectHandle networkHandle, CCharPointer containerId, CCharPointer svgFile, CCharPointer metadataFile, SldParametersPointer sldParametersPtr, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String containerIdStr = CTypeUtil.toString(containerId); - String svgFileStr = CTypeUtil.toString(svgFile); - String metadataFileStr = metadataFile.isNonNull() ? CTypeUtil.toString(metadataFile) : null; - SldParameters sldParameters = convertSldParameters(sldParametersPtr); - SingleLineDiagramUtil.writeSvg(network, containerIdStr, svgFileStr, metadataFileStr, sldParameters); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String containerIdStr = CTypeUtil.toString(containerId); + String svgFileStr = CTypeUtil.toString(svgFile); + String metadataFileStr = metadataFile.isNonNull() ? CTypeUtil.toString(metadataFile) : null; + SldParameters sldParameters = convertSldParameters(sldParametersPtr); + SingleLineDiagramUtil.writeSvg(network, containerIdStr, svgFileStr, metadataFileStr, sldParameters); + } }); } @@ -1011,37 +1173,46 @@ public static void writeMatrixMultiSubstationSingleLineDiagramSvg(IsolateThread int substationIdCount, int substationIdRowCount, CCharPointer svgFile, CCharPointer metadataFile, SldParametersPointer sldParametersPtr, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String[][] matrixIds = CTypeUtil.toString2DArray(substationIdsPointer, substationIdCount, substationIdRowCount); - String svgFileStr = CTypeUtil.toString(svgFile); - String metadataFileStr = metadataFile.isNonNull() ? CTypeUtil.toString(metadataFile) : null; - SldParameters sldParameters = convertSldParameters(sldParametersPtr); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String[][] matrixIds = CTypeUtil.toString2DArray(substationIdsPointer, substationIdCount, substationIdRowCount); + String svgFileStr = CTypeUtil.toString(svgFile); + String metadataFileStr = metadataFile.isNonNull() ? CTypeUtil.toString(metadataFile) : null; + SldParameters sldParameters = convertSldParameters(sldParametersPtr); - SingleLineDiagramUtil.writeMatrixMultiSubstationSvg(network, matrixIds, svgFileStr, metadataFileStr, sldParameters); + SingleLineDiagramUtil.writeMatrixMultiSubstationSvg(network, matrixIds, svgFileStr, metadataFileStr, sldParameters); + } }); } @CEntryPoint(name = "getSingleLineDiagramSvg") public static CCharPointer getSingleLineDiagramSvg(IsolateThread thread, ObjectHandle networkHandle, CCharPointer containerId, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String containerIdStr = CTypeUtil.toString(containerId); - String svg = SingleLineDiagramUtil.getSvg(network, containerIdStr); - return CTypeUtil.toCharPtr(svg); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public CCharPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String containerIdStr = CTypeUtil.toString(containerId); + String svg = SingleLineDiagramUtil.getSvg(network, containerIdStr); + return CTypeUtil.toCharPtr(svg); + } }); } @CEntryPoint(name = "getSingleLineDiagramSvgAndMetadata") public static ArrayPointer getSingleLineDiagramSvgAndMetadata(IsolateThread thread, ObjectHandle networkHandle, CCharPointer containerId, SldParametersPointer sldParametersPtr, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String containerIdStr = CTypeUtil.toString(containerId); - SldParameters sldParameters = convertSldParameters(sldParametersPtr); - List svgAndMeta = SingleLineDiagramUtil.getSvgAndMetadata(network, containerIdStr, sldParameters); - return createCharPtrArray(svgAndMeta); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String containerIdStr = CTypeUtil.toString(containerId); + SldParameters sldParameters = convertSldParameters(sldParametersPtr); + List svgAndMeta = SingleLineDiagramUtil.getSvgAndMetadata(network, containerIdStr, sldParameters); + return createCharPtrArray(svgAndMeta); + } }); } @@ -1049,18 +1220,23 @@ public static ArrayPointer getSingleLineDiagramSvgAndMetada public static ArrayPointer getMatrixMultiSubstationSvgAndMetadata(IsolateThread thread, ObjectHandle networkHandle, CCharPointerPointer substationIdsPointer, int substationIdCount, int substationIdRowCount, SldParametersPointer sldParametersPtr, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String[][] matrixIds = CTypeUtil.toString2DArray(substationIdsPointer, substationIdCount, substationIdRowCount); - SldParameters sldParameters = convertSldParameters(sldParametersPtr); - List svgAndMeta = SingleLineDiagramUtil.getMatrixMultiSubstationSvgAndMetadata(network, matrixIds, sldParameters); - return createCharPtrArray(svgAndMeta); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String[][] matrixIds = CTypeUtil.toString2DArray(substationIdsPointer, substationIdCount, substationIdRowCount); + SldParameters sldParameters = convertSldParameters(sldParametersPtr); + List svgAndMeta = SingleLineDiagramUtil.getMatrixMultiSubstationSvgAndMetadata(network, matrixIds, sldParameters); + return createCharPtrArray(svgAndMeta); + } }); } @CEntryPoint(name = "getSingleLineDiagramComponentLibraryNames") public static PyPowsyblApiHeader.ArrayPointer getSingleLineDiagramComponentLibraryNames(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> createCharPtrArray(SingleLineDiagramUtil.getComponentLibraryNames())); + return doCatch(exceptionHandlerPtr, () -> { + return createCharPtrArray(SingleLineDiagramUtil.getComponentLibraryNames()); + }); } @CEntryPoint(name = "writeNetworkAreaDiagramSvg") @@ -1068,12 +1244,15 @@ public static void writeNetworkAreaDiagramSvg(IsolateThread thread, ObjectHandle CCharPointerPointer voltageLevelIdsPointer, int voltageLevelIdCount, int depth, double highNominalVoltageBound, double lowNominalVoltageBound, NadParametersPointer nadParametersPointer, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String svgFileStr = CTypeUtil.toString(svgFile); - List voltageLevelIds = toStringList(voltageLevelIdsPointer, voltageLevelIdCount); - NadParameters nadParameters = convertNadParameters(nadParametersPointer, network); - NetworkAreaDiagramUtil.writeSvg(network, voltageLevelIds, depth, svgFileStr, highNominalVoltageBound, lowNominalVoltageBound, nadParameters); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String svgFileStr = CTypeUtil.toString(svgFile); + List voltageLevelIds = toStringList(voltageLevelIdsPointer, voltageLevelIdCount); + NadParameters nadParameters = convertNadParameters(nadParametersPointer, network); + NetworkAreaDiagramUtil.writeSvg(network, voltageLevelIds, depth, svgFileStr, highNominalVoltageBound, lowNominalVoltageBound, nadParameters); + } }); } @@ -1081,22 +1260,28 @@ public static void writeNetworkAreaDiagramSvg(IsolateThread thread, ObjectHandle public static CCharPointer getNetworkAreaDiagramSvg(IsolateThread thread, ObjectHandle networkHandle, CCharPointerPointer voltageLevelIdsPointer, int voltageLevelIdCount, int depth, double highNominalVoltageBound, double lowNominalVoltageBound, NadParametersPointer nadParametersPointer, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - List voltageLevelIds = toStringList(voltageLevelIdsPointer, voltageLevelIdCount); - NadParameters nadParameters = convertNadParameters(nadParametersPointer, network); - String svg = NetworkAreaDiagramUtil.getSvg(network, voltageLevelIds, depth, highNominalVoltageBound, lowNominalVoltageBound, nadParameters); - return CTypeUtil.toCharPtr(svg); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public CCharPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + List voltageLevelIds = toStringList(voltageLevelIdsPointer, voltageLevelIdCount); + NadParameters nadParameters = convertNadParameters(nadParametersPointer, network); + String svg = NetworkAreaDiagramUtil.getSvg(network, voltageLevelIds, depth, highNominalVoltageBound, lowNominalVoltageBound, nadParameters); + return CTypeUtil.toCharPtr(svg); + } }); } @CEntryPoint(name = "getNetworkAreaDiagramDisplayedVoltageLevels") public static PyPowsyblApiHeader.ArrayPointer getNetworkAreaDiagramDisplayedVoltageLevels(IsolateThread thread, ObjectHandle networkHandle, CCharPointerPointer voltageLevelIdsPointer, int voltageLevelIdCount, int depth, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - List voltageLevelIds = toStringList(voltageLevelIdsPointer, voltageLevelIdCount); - return createCharPtrArray(NetworkAreaDiagramUtil.getDisplayedVoltageLevels(network, voltageLevelIds, depth)); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + List voltageLevelIds = toStringList(voltageLevelIdsPointer, voltageLevelIdCount); + return createCharPtrArray(NetworkAreaDiagramUtil.getDisplayedVoltageLevels(network, voltageLevelIds, depth)); + } }); } @@ -1128,9 +1313,12 @@ public static ValidationLevelType validate(IsolateThread thread, ObjectHandle ne public static void setMinValidationLevel(IsolateThread thread, ObjectHandle networkHandle, ValidationLevelType levelType, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - network.setMinimumAcceptableValidationLevel(Util.convert(levelType)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + network.setMinimumAcceptableValidationLevel(Util.convert(levelType)); + } }); } @@ -1139,42 +1327,51 @@ public static DataframesMetadataPointer getModificationMetadataWithElementType(I NetworkModificationType networkModificationType, ElementType elementType, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - DataframeNetworkModificationType modificationType = convert(networkModificationType); - DataframeElementType type = convert(elementType); - List> metadata = NetworkModifications.getModification(modificationType).getMetadata(type); - DataframeMetadataPointer dataframeMetadataArray = UnmanagedMemory.calloc(metadata.size() * SizeOf.get(DataframeMetadataPointer.class)); - int i = 0; - for (List dataframeMetadata : metadata) { - createSeriesMetadata(dataframeMetadata, dataframeMetadataArray.addressOf(i)); - i++; + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public DataframesMetadataPointer get() { + DataframeNetworkModificationType modificationType = convert(networkModificationType); + DataframeElementType type = convert(elementType); + List> metadata = NetworkModifications.getModification(modificationType).getMetadata(type); + DataframeMetadataPointer dataframeMetadataArray = UnmanagedMemory.calloc(metadata.size() * SizeOf.get(DataframeMetadataPointer.class)); + int i = 0; + for (List dataframeMetadata : metadata) { + createSeriesMetadata(dataframeMetadata, dataframeMetadataArray.addressOf(i)); + i++; + } + DataframesMetadataPointer res = UnmanagedMemory.calloc(SizeOf.get(DataframesMetadataPointer.class)); + res.setDataframesMetadata(dataframeMetadataArray); + res.setDataframesCount(metadata.size()); + return res; } - DataframesMetadataPointer res = UnmanagedMemory.calloc(SizeOf.get(DataframesMetadataPointer.class)); - res.setDataframesMetadata(dataframeMetadataArray); - res.setDataframesCount(metadata.size()); - return res; }); } @CEntryPoint(name = "getSubNetwork") public static ObjectHandle getSubNetwork(IsolateThread thread, ObjectHandle networkHandle, CCharPointer subNetworkId, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String subNetworkIdStr = CTypeUtil.toString(subNetworkId); - Network subnetwork = network.getSubnetwork(subNetworkIdStr); - if (subnetwork == null) { - throw new PowsyblException("Sub network '" + subNetworkIdStr + "' not found"); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String subNetworkIdStr = CTypeUtil.toString(subNetworkId); + Network subnetwork = network.getSubnetwork(subNetworkIdStr); + if (subnetwork == null) { + throw new PowsyblException("Sub network '" + subNetworkIdStr + "' not found"); + } + return ObjectHandles.getGlobal().create(subnetwork); } - return ObjectHandles.getGlobal().create(subnetwork); }); } @CEntryPoint(name = "detachSubNetwork") public static ObjectHandle detachSubNetwork(IsolateThread thread, ObjectHandle subNetworkHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network subNetwork = ObjectHandles.getGlobal().get(subNetworkHandle); - Network detachNetwork = subNetwork.detach(); - return ObjectHandles.getGlobal().create(detachNetwork); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + Network subNetwork = ObjectHandles.getGlobal().get(subNetworkHandle); + Network detachNetwork = subNetwork.detach(); + return ObjectHandles.getGlobal().create(detachNetwork); + } }); } } diff --git a/java/src/main/java/com/powsybl/python/network/NetworkModificationsCFunctions.java b/java/src/main/java/com/powsybl/python/network/NetworkModificationsCFunctions.java index 953ae1284..5431529ec 100644 --- a/java/src/main/java/com/powsybl/python/network/NetworkModificationsCFunctions.java +++ b/java/src/main/java/com/powsybl/python/network/NetworkModificationsCFunctions.java @@ -22,6 +22,9 @@ import com.powsybl.python.commons.CTypeUtil; import com.powsybl.python.commons.Directives; import com.powsybl.python.commons.PyPowsyblApiHeader; +import com.powsybl.python.commons.PyPowsyblApiHeader.ArrayPointer; +import com.powsybl.python.commons.PyPowsyblApiHeader.DataframeMetadataPointer; +import com.powsybl.python.commons.PyPowsyblApiHeader.SeriesPointer; import org.apache.commons.lang3.Range; import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.ObjectHandle; @@ -32,6 +35,7 @@ import org.graalvm.nativeimage.c.type.CCharPointerPointer; import org.graalvm.nativeimage.c.type.CIntPointer; +import java.io.IOException; import java.util.*; import static com.powsybl.iidm.modification.topology.TopologyModificationUtils.*; @@ -44,6 +48,7 @@ * * @author Sylvain Leclerc */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class NetworkModificationsCFunctions { @@ -51,38 +56,44 @@ private NetworkModificationsCFunctions() { } @CEntryPoint(name = "getConnectablesOrderPositions") - public static PyPowsyblApiHeader.ArrayPointer getConnectablesOrderPositions(IsolateThread thread, ObjectHandle networkHandle, - CCharPointer voltageLevelId, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String voltageLevelIdStr = CTypeUtil.toString(voltageLevelId); - Network network = ObjectHandles.getGlobal().get(networkHandle); + public static ArrayPointer getConnectablesOrderPositions(IsolateThread thread, ObjectHandle networkHandle, + CCharPointer voltageLevelId, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() throws IOException { + String voltageLevelIdStr = CTypeUtil.toString(voltageLevelId); + Network network = ObjectHandles.getGlobal().get(networkHandle); - VoltageLevel voltageLevel = network.getVoltageLevel(voltageLevelIdStr); - Map> feederPositionsOrders = getFeedersByConnectable(voltageLevel); - return Dataframes.createCDataframe(Dataframes.feederMapMapper(), feederPositionsOrders); + VoltageLevel voltageLevel = network.getVoltageLevel(voltageLevelIdStr); + Map> feederPositionsOrders = getFeedersByConnectable(voltageLevel); + return Dataframes.createCDataframe(Dataframes.feederMapMapper(), feederPositionsOrders); + } }); } @CEntryPoint(name = "getUnusedConnectableOrderPositions") - public static PyPowsyblApiHeader.ArrayPointer getUnusedConnectableOrderPositions(IsolateThread thread, ObjectHandle networkHandle, + public static ArrayPointer getUnusedConnectableOrderPositions(IsolateThread thread, ObjectHandle networkHandle, CCharPointer busbarSectionId, CCharPointer beforeOrAfter, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - String busbarSectionIdStr = CTypeUtil.toString(busbarSectionId); - BusbarSection busbarSection = network.getBusbarSection(busbarSectionIdStr); - Optional> positionsOrders; - if (CTypeUtil.toString(beforeOrAfter).equals("BEFORE")) { - positionsOrders = getUnusedOrderPositionsBefore(busbarSection); - } else { - positionsOrders = getUnusedOrderPositionsAfter(busbarSection); - } - if (positionsOrders.isPresent()) { - int max = positionsOrders.get().getMaximum(); - int min = positionsOrders.get().getMinimum(); - return createIntegerArray(Arrays.asList(min, max)); - } else { - return createIntegerArray(Collections.emptyList()); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() throws IOException { + Network network = ObjectHandles.getGlobal().get(networkHandle); + String busbarSectionIdStr = CTypeUtil.toString(busbarSectionId); + BusbarSection busbarSection = network.getBusbarSection(busbarSectionIdStr); + Optional> positionsOrders; + if (CTypeUtil.toString(beforeOrAfter).equals("BEFORE")) { + positionsOrders = getUnusedOrderPositionsBefore(busbarSection); + } else { + positionsOrders = getUnusedOrderPositionsAfter(busbarSection); + } + if (positionsOrders.isPresent()) { + int max = positionsOrders.get().getMaximum(); + int min = positionsOrders.get().getMinimum(); + return createIntegerArray(Arrays.asList(min, max)); + } else { + return createIntegerArray(Collections.emptyList()); + } } }); } @@ -93,26 +104,32 @@ public static void createNetworkModification(IsolateThread thread, ObjectHandle PyPowsyblApiHeader.NetworkModificationType networkModificationType, boolean throwException, ObjectHandle reportNodeHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); - List dfs = new ArrayList<>(); - for (int i = 0; i < cDataframes.getDataframesCount(); i++) { - dfs.add(createDataframe(cDataframes.getDataframes().addressOf(i))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); + List dfs = new ArrayList<>(); + for (int i = 0; i < cDataframes.getDataframesCount(); i++) { + dfs.add(createDataframe(cDataframes.getDataframes().addressOf(i))); + } + DataframeNetworkModificationType type = convert(networkModificationType); + NetworkModifications.applyModification(type, network, dfs, throwException, reportNode); } - DataframeNetworkModificationType type = convert(networkModificationType); - NetworkModifications.applyModification(type, network, dfs, throwException, reportNode); }); } @CEntryPoint(name = "getModificationMetadata") - public static PyPowsyblApiHeader.DataframeMetadataPointer getModificationMetadata(IsolateThread thread, + public static DataframeMetadataPointer getModificationMetadata(IsolateThread thread, PyPowsyblApiHeader.NetworkModificationType networkModificationType, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - DataframeNetworkModificationType type = convert(networkModificationType); - List metadata = NetworkModifications.getModification(type).getMetadata(); - return CTypeUtil.createSeriesMetadata(metadata); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public DataframeMetadataPointer get() throws IOException { + DataframeNetworkModificationType type = convert(networkModificationType); + List metadata = NetworkModifications.getModification(type).getMetadata(); + return CTypeUtil.createSeriesMetadata(metadata); + } }); } @@ -123,27 +140,30 @@ public static void removeElementsModification(IsolateThread thread, ObjectHandle PyPowsyblApiHeader.RemoveModificationType removeModificationType, boolean throwException, ObjectHandle reportNodeHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - List ids = toStringList(connectableIdsPtrPtr, connectableIdsCount); - Network network = ObjectHandles.getGlobal().get(networkHandle); - ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); - if (removeModificationType == PyPowsyblApiHeader.RemoveModificationType.REMOVE_FEEDER) { - ids.forEach(id -> new RemoveFeederBayBuilder().withConnectableId(id).build().apply(network, throwException, reportNode == null ? ReportNode.NO_OP : reportNode)); - } else if (removeModificationType == PyPowsyblApiHeader.RemoveModificationType.REMOVE_VOLTAGE_LEVEL) { - ids.forEach(id -> new RemoveVoltageLevelBuilder().withVoltageLevelId(id).build().apply(network, throwException, reportNode == null ? ReportNode.NO_OP : reportNode)); - } else if (removeModificationType == PyPowsyblApiHeader.RemoveModificationType.REMOVE_HVDC_LINE) { - UpdatingDataframe extraDataDf = createDataframe(extraDataDfPtr); - ids.forEach(hvdcId -> { - List shuntCompensatorList = Collections.emptyList(); - if (extraDataDf != null) { - Optional shuntCompensatorOptional = extraDataDf.getStringValue(hvdcId, 0); - String shuntCompensator = shuntCompensatorOptional.isEmpty() || shuntCompensatorOptional.get().isEmpty() ? "," : - shuntCompensatorOptional.get(); - shuntCompensatorList = Arrays.stream(shuntCompensator.split(",")).toList(); - } - new RemoveHvdcLineBuilder().withHvdcLineId(hvdcId).withShuntCompensatorIds(shuntCompensatorList).build().apply(network, throwException, reportNode == null ? ReportNode.NO_OP : reportNode); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + List ids = toStringList(connectableIdsPtrPtr, connectableIdsCount); + Network network = ObjectHandles.getGlobal().get(networkHandle); + ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); + if (removeModificationType == PyPowsyblApiHeader.RemoveModificationType.REMOVE_FEEDER) { + ids.forEach(id -> new RemoveFeederBayBuilder().withConnectableId(id).build().apply(network, throwException, reportNode == null ? ReportNode.NO_OP : reportNode)); + } else if (removeModificationType == PyPowsyblApiHeader.RemoveModificationType.REMOVE_VOLTAGE_LEVEL) { + ids.forEach(id -> new RemoveVoltageLevelBuilder().withVoltageLevelId(id).build().apply(network, throwException, reportNode == null ? ReportNode.NO_OP : reportNode)); + } else if (removeModificationType == PyPowsyblApiHeader.RemoveModificationType.REMOVE_HVDC_LINE) { + UpdatingDataframe extraDataDf = createDataframe(extraDataDfPtr); + ids.forEach(hvdcId -> { + List shuntCompensatorList = Collections.emptyList(); + if (extraDataDf != null) { + Optional shuntCompensatorOptional = extraDataDf.getStringValue(hvdcId, 0); + String shuntCompensator = shuntCompensatorOptional.isEmpty() || shuntCompensatorOptional.get().isEmpty() ? "," : + shuntCompensatorOptional.get(); + shuntCompensatorList = Arrays.stream(shuntCompensator.split(",")).toList(); + } + new RemoveHvdcLineBuilder().withHvdcLineId(hvdcId).withShuntCompensatorIds(shuntCompensatorList).build().apply(network, throwException, reportNode == null ? ReportNode.NO_OP : reportNode); - }); + }); + } } }); } diff --git a/java/src/main/java/com/powsybl/python/report/ReportCFunctions.java b/java/src/main/java/com/powsybl/python/report/ReportCFunctions.java index 2860e4186..d99325feb 100644 --- a/java/src/main/java/com/powsybl/python/report/ReportCFunctions.java +++ b/java/src/main/java/com/powsybl/python/report/ReportCFunctions.java @@ -13,6 +13,7 @@ import com.powsybl.python.commons.CTypeUtil; import com.powsybl.python.commons.Directives; import com.powsybl.python.commons.PyPowsyblApiHeader; +import com.powsybl.python.commons.Util.PointerProvider; import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.ObjectHandle; import org.graalvm.nativeimage.ObjectHandles; @@ -29,6 +30,7 @@ /** * @author Sylvain Leclerc */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class ReportCFunctions { @@ -37,38 +39,47 @@ private ReportCFunctions() { @CEntryPoint(name = "createReportNode") public static ObjectHandle createReportNode(IsolateThread thread, CCharPointer taskKeyPtr, CCharPointer defaultNamePtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String taskKey = CTypeUtil.toString(taskKeyPtr); - String defaultName = CTypeUtil.toString(defaultNamePtr); - ReportNode reportNode = ReportNode.newRootReportNode() - .withMessageTemplate(taskKey, defaultName) - .build(); - return ObjectHandles.getGlobal().create(reportNode); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + String taskKey = CTypeUtil.toString(taskKeyPtr); + String defaultName = CTypeUtil.toString(defaultNamePtr); + ReportNode reportNode = ReportNode.newRootReportNode() + .withMessageTemplate(taskKey, defaultName) + .build(); + return ObjectHandles.getGlobal().create(reportNode); + } }); } @CEntryPoint(name = "printReport") public static CCharPointer printReport(IsolateThread thread, ObjectHandle reportNodeHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); - StringWriter reportNodeOut = new StringWriter(); - reportNode.print(reportNodeOut); - return CTypeUtil.toCharPtr(reportNodeOut.toString()); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public CCharPointer get() throws IOException { + ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); + StringWriter reportNodeOut = new StringWriter(); + reportNode.print(reportNodeOut); + return CTypeUtil.toCharPtr(reportNodeOut.toString()); + } }); } @CEntryPoint(name = "jsonReport") public static CCharPointer jsonReport(IsolateThread thread, ObjectHandle reportNodeHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); - StringWriter reportNodeOut = new StringWriter(); - ObjectMapper objectMapper = new ObjectMapper().registerModule(new ReportNodeJsonModule()); - try { - objectMapper.writerWithDefaultPrettyPrinter().writeValue(reportNodeOut, reportNode); - } catch (IOException e) { - throw new UncheckedIOException(e); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public CCharPointer get() { + ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); + StringWriter reportNodeOut = new StringWriter(); + ObjectMapper objectMapper = new ObjectMapper().registerModule(new ReportNodeJsonModule()); + try { + objectMapper.writerWithDefaultPrettyPrinter().writeValue(reportNodeOut, reportNode); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return CTypeUtil.toCharPtr(reportNodeOut.toString()); } - return CTypeUtil.toCharPtr(reportNodeOut.toString()); }); } } diff --git a/java/src/main/java/com/powsybl/python/security/SecurityAnalysisCFunctions.java b/java/src/main/java/com/powsybl/python/security/SecurityAnalysisCFunctions.java index 87f150ded..be3d047f3 100644 --- a/java/src/main/java/com/powsybl/python/security/SecurityAnalysisCFunctions.java +++ b/java/src/main/java/com/powsybl/python/security/SecurityAnalysisCFunctions.java @@ -13,12 +13,13 @@ import com.powsybl.contingency.ContingencyContext; import com.powsybl.iidm.network.Network; import com.powsybl.python.commons.*; -import com.powsybl.python.commons.PyPowsyblApiHeader.SecurityAnalysisParametersPointer; +import com.powsybl.python.commons.PyPowsyblApiHeader.*; import com.powsybl.python.contingency.ContingencyContainer; import com.powsybl.python.loadflow.LoadFlowCFunctions; import com.powsybl.python.loadflow.LoadFlowCUtils; import com.powsybl.python.network.Dataframes; import com.powsybl.security.*; +import com.powsybl.security.LimitViolationType; import com.powsybl.security.condition.*; import com.powsybl.security.monitor.StateMonitor; import com.powsybl.security.results.OperatorStrategyResult; @@ -53,6 +54,7 @@ * * @author Sylvain Leclerc */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class SecurityAnalysisCFunctions { @@ -64,20 +66,34 @@ private static Logger logger() { } @CEntryPoint(name = "getSecurityAnalysisProviderNames") - public static PyPowsyblApiHeader.ArrayPointer getSecurityAnalysisProviderNames(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> createCharPtrArray(SecurityAnalysisProvider.findAll() - .stream().map(SecurityAnalysisProvider::getName).toList())); + public static ArrayPointer getSecurityAnalysisProviderNames(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + return createCharPtrArray(SecurityAnalysisProvider.findAll() + .stream().map(SecurityAnalysisProvider::getName).toList()); + } + }); } @CEntryPoint(name = "setDefaultSecurityAnalysisProvider") public static void setDefaultSecurityAnalysisProvider(IsolateThread thread, CCharPointer provider, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> - PyPowsyblConfiguration.setDefaultSecurityAnalysisProvider(CTypeUtil.toString(provider))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + PyPowsyblConfiguration.setDefaultSecurityAnalysisProvider(CTypeUtil.toString(provider)); + } + }); } @CEntryPoint(name = "getDefaultSecurityAnalysisProvider") public static CCharPointer getDefaultSecurityAnalysisProvider(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> CTypeUtil.toCharPtr(PyPowsyblConfiguration.getDefaultSecurityAnalysisProvider())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public CCharPointer get() { + return CTypeUtil.toCharPtr(PyPowsyblConfiguration.getDefaultSecurityAnalysisProvider()); + } + }); } @CEntryPoint(name = "addMonitoredElements") @@ -87,56 +103,80 @@ public static void addMonitoredElements(IsolateThread thread, ObjectHandle secur CCharPointerPointer threeWindingsTransformerIds, int threeWindingsTransformerIdsCount, CCharPointerPointer contingencyIds, int contingencyIdsCount, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); - List contingencies = toStringList(contingencyIds, contingencyIdsCount); - contingencies.forEach(contingency -> analysisContext.addMonitor(new StateMonitor(new ContingencyContext(contingency.isEmpty() ? null : contingency, convert(contingencyContextType)), - Set.copyOf(toStringList(branchIds, branchIdsCount)), Set.copyOf(toStringList(voltageLevelIds, voltageLevelIdCount)), - Set.copyOf(toStringList(threeWindingsTransformerIds, threeWindingsTransformerIdsCount))))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); + List contingencies = toStringList(contingencyIds, contingencyIdsCount); + Set branchIdsJava = Set.copyOf(toStringList(branchIds, branchIdsCount)); + Set voltageLevelIdsJava = Set.copyOf(toStringList(voltageLevelIds, voltageLevelIdCount)); + Set threeWindingsTransformerIdsJava = Set.copyOf(toStringList(threeWindingsTransformerIds, threeWindingsTransformerIdsCount)); + contingencies.forEach(contingency -> { + analysisContext.addMonitor(new StateMonitor(new ContingencyContext(contingency.isEmpty() ? null : contingency, convert(contingencyContextType)), + branchIdsJava, voltageLevelIdsJava, threeWindingsTransformerIdsJava)); + }); + } }); } @CEntryPoint(name = "getBranchResults") - public static PyPowsyblApiHeader.ArrayPointer getBranchResults(IsolateThread thread, ObjectHandle securityAnalysisResult, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResult); - return Dataframes.createCDataframe(Dataframes.branchResultsMapper(), result); + public static ArrayPointer getBranchResults(IsolateThread thread, ObjectHandle securityAnalysisResult, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResult); + return Dataframes.createCDataframe(Dataframes.branchResultsMapper(), result); + } }); } @CEntryPoint(name = "getBusResults") - public static PyPowsyblApiHeader.ArrayPointer getBusResults(IsolateThread thread, ObjectHandle securityAnalysisResult, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResult); - return Dataframes.createCDataframe(Dataframes.busResultsMapper(), result); + public static ArrayPointer getBusResults(IsolateThread thread, ObjectHandle securityAnalysisResult, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResult); + return Dataframes.createCDataframe(Dataframes.busResultsMapper(), result); + } }); } @CEntryPoint(name = "getThreeWindingsTransformerResults") - public static PyPowsyblApiHeader.ArrayPointer getThreeWindingsTransformerResults(IsolateThread thread, ObjectHandle securityAnalysisResult, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResult); - return Dataframes.createCDataframe(Dataframes.threeWindingsTransformerResultsMapper(), result); + public static ArrayPointer getThreeWindingsTransformerResults(IsolateThread thread, ObjectHandle securityAnalysisResult, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResult); + return Dataframes.createCDataframe(Dataframes.threeWindingsTransformerResultsMapper(), result); + } }); } @CEntryPoint(name = "createSecurityAnalysis") public static ObjectHandle createSecurityAnalysis(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> ObjectHandles.getGlobal().create(new SecurityAnalysisContext())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + return ObjectHandles.getGlobal().create(new SecurityAnalysisContext()); + } + }); } @CEntryPoint(name = "addContingency") public static void addContingency(IsolateThread thread, ObjectHandle contingencyContainerHandle, CCharPointer contingencyIdPtr, CCharPointerPointer elementIdPtrPtr, int elementCount, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - ContingencyContainer contingencyContainer = ObjectHandles.getGlobal().get(contingencyContainerHandle); - String contingencyId = CTypeUtil.toString(contingencyIdPtr); - List elementIds = toStringList(elementIdPtrPtr, elementCount); - contingencyContainer.addContingency(contingencyId, elementIds); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + ContingencyContainer contingencyContainer = ObjectHandles.getGlobal().get(contingencyContainerHandle); + String contingencyId = CTypeUtil.toString(contingencyIdPtr); + List elementIds = toStringList(elementIdPtrPtr, elementCount); + contingencyContainer.addContingency(contingencyId, elementIds); + } }); } - private static void setPostContingencyResultInSecurityAnalysisResultPointer(PyPowsyblApiHeader.PostContingencyResultPointer contingencyPtr, PostContingencyResult postContingencyResult) { + private static void setPostContingencyResultInSecurityAnalysisResultPointer(PostContingencyResultPointer contingencyPtr, PostContingencyResult postContingencyResult) { contingencyPtr.setContingencyId(CTypeUtil.toCharPtr(postContingencyResult.getContingency().getId())); contingencyPtr.setStatus(postContingencyResult.getStatus().ordinal()); List limitViolations = postContingencyResult.getLimitViolationsResult().getLimitViolations(); @@ -146,7 +186,7 @@ private static void setPostContingencyResultInSecurityAnalysisResultPointer(PyPo contingencyPtr.limitViolations().setPtr(limitViolationPtr); } - private static void setOperatorStrategyResultInSecurityAnalysisResultPointer(PyPowsyblApiHeader.OperatorStrategyResultPointer operatorStrategyPtr, OperatorStrategyResult result) { + private static void setOperatorStrategyResultInSecurityAnalysisResultPointer(OperatorStrategyResultPointer operatorStrategyPtr, OperatorStrategyResult result) { operatorStrategyPtr.setOperatorStrategyId(CTypeUtil.toCharPtr(result.getOperatorStrategy().getId())); operatorStrategyPtr.setStatus(result.getStatus().ordinal()); List limitViolations = result.getLimitViolationsResult().getLimitViolations(); @@ -156,7 +196,7 @@ private static void setOperatorStrategyResultInSecurityAnalysisResultPointer(PyP operatorStrategyPtr.limitViolations().setPtr(limitViolationPtr); } - private static void setPreContingencyResultInSecurityAnalysisResultPointer(PyPowsyblApiHeader.PreContingencyResultPointer contingencyPtr, PreContingencyResult preContingencyResult) { + private static void setPreContingencyResultInSecurityAnalysisResultPointer(PreContingencyResultPointer contingencyPtr, PreContingencyResult preContingencyResult) { contingencyPtr.setStatus(preContingencyResult.getStatus().ordinal()); List limitViolations = preContingencyResult.getLimitViolationsResult().getLimitViolations(); PyPowsyblApiHeader.LimitViolationPointer limitViolationPtr = UnmanagedMemory.calloc(limitViolations.size() * SizeOf.get(PyPowsyblApiHeader.LimitViolationPointer.class)); @@ -181,141 +221,162 @@ private static void createLimitViolationPtr(PyPowsyblApiHeader.LimitViolationPoi } } - private static PyPowsyblApiHeader.PreContingencyResultPointer createPreContingencyResultArrayPointer(SecurityAnalysisResult result) { - PyPowsyblApiHeader.PreContingencyResultPointer contingencyPtr = UnmanagedMemory.calloc(SizeOf.get(PyPowsyblApiHeader.PreContingencyResultPointer.class)); + private static PreContingencyResultPointer createPreContingencyResultArrayPointer(SecurityAnalysisResult result) { + PreContingencyResultPointer contingencyPtr = UnmanagedMemory.calloc(SizeOf.get(PreContingencyResultPointer.class)); setPreContingencyResultInSecurityAnalysisResultPointer(contingencyPtr, result.getPreContingencyResult()); return contingencyPtr; } - private static PyPowsyblApiHeader.ArrayPointer createPostContingencyResultArrayPointer(SecurityAnalysisResult result) { + private static ArrayPointer createPostContingencyResultArrayPointer(SecurityAnalysisResult result) { int resultCount = result.getPostContingencyResults().size(); // + 1 for pre-contingency result - PyPowsyblApiHeader.PostContingencyResultPointer contingencyPtr = UnmanagedMemory.calloc(resultCount * SizeOf.get(PyPowsyblApiHeader.PostContingencyResultPointer.class)); + PostContingencyResultPointer contingencyPtr = UnmanagedMemory.calloc(resultCount * SizeOf.get(PostContingencyResultPointer.class)); for (int i = 0; i < result.getPostContingencyResults().size(); i++) { PostContingencyResult postContingencyResult = result.getPostContingencyResults().get(i); - PyPowsyblApiHeader.PostContingencyResultPointer contingencyPtrPlus = contingencyPtr.addressOf(i); + PostContingencyResultPointer contingencyPtrPlus = contingencyPtr.addressOf(i); setPostContingencyResultInSecurityAnalysisResultPointer(contingencyPtrPlus, postContingencyResult); } return allocArrayPointer(contingencyPtr, resultCount); } - private static PyPowsyblApiHeader.ArrayPointer createOperatorStrategyResultsArrayPointer(SecurityAnalysisResult result) { + private static ArrayPointer createOperatorStrategyResultsArrayPointer(SecurityAnalysisResult result) { int resultCount = result.getOperatorStrategyResults().size(); - PyPowsyblApiHeader.OperatorStrategyResultPointer strategyPtr = UnmanagedMemory.calloc(resultCount * SizeOf.get(PyPowsyblApiHeader.OperatorStrategyResultPointer.class)); + OperatorStrategyResultPointer strategyPtr = UnmanagedMemory.calloc(resultCount * SizeOf.get(OperatorStrategyResultPointer.class)); for (int i = 0; i < result.getOperatorStrategyResults().size(); i++) { OperatorStrategyResult resultOp = result.getOperatorStrategyResults().get(i); - PyPowsyblApiHeader.OperatorStrategyResultPointer operatorStrategyPlus = strategyPtr.addressOf(i); + OperatorStrategyResultPointer operatorStrategyPlus = strategyPtr.addressOf(i); setOperatorStrategyResultInSecurityAnalysisResultPointer(operatorStrategyPlus, resultOp); } return allocArrayPointer(strategyPtr, resultCount); } - private static SecurityAnalysisProvider getProvider(String name) { - String actualName = name.isEmpty() ? PyPowsyblConfiguration.getDefaultSecurityAnalysisProvider() : name; - return SecurityAnalysisProvider.findAll().stream() - .filter(provider -> provider.getName().equals(actualName)) - .findFirst() - .orElseThrow(() -> new PowsyblException("No security analysis provider for name '" + actualName + "'")); - } - @CEntryPoint(name = "runSecurityAnalysis") public static ObjectHandle runSecurityAnalysis(IsolateThread thread, ObjectHandle securityAnalysisContextHandle, ObjectHandle networkHandle, SecurityAnalysisParametersPointer securityAnalysisParametersPointer, CCharPointer providerName, boolean dc, ObjectHandle reportNodeHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); - Network network = ObjectHandles.getGlobal().get(networkHandle); - SecurityAnalysisProvider provider = getProvider(CTypeUtil.toString(providerName)); - logger().info("Security analysis provider used for security analysis is : {}", provider.getName()); - SecurityAnalysisParameters securityAnalysisParameters = SecurityAnalysisCUtils.createSecurityAnalysisParameters(dc, securityAnalysisParametersPointer, provider); - ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); - SecurityAnalysisResult result = analysisContext.run(network, securityAnalysisParameters, provider.getName(), reportNode); - return ObjectHandles.getGlobal().create(result); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); + Network network = ObjectHandles.getGlobal().get(networkHandle); + SecurityAnalysisProvider provider = SecurityAnalysisCUtils.getSecurityAnalysisProvider(CTypeUtil.toString(providerName)); + logger().info("Security analysis provider used for security analysis is : {}", provider.getName()); + SecurityAnalysisParameters securityAnalysisParameters = SecurityAnalysisCUtils.createSecurityAnalysisParameters(dc, securityAnalysisParametersPointer, provider); + ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); + SecurityAnalysisResult result = analysisContext.run(network, securityAnalysisParameters, provider.getName(), reportNode); + return ObjectHandles.getGlobal().create(result); + } }); } @CEntryPoint(name = "getPostContingencyResults") - public static PyPowsyblApiHeader.ArrayPointer getPostContingencyResults(IsolateThread thread, ObjectHandle securityAnalysisResultHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResultHandle); - return createPostContingencyResultArrayPointer(result); + public static ArrayPointer getPostContingencyResults(IsolateThread thread, ObjectHandle securityAnalysisResultHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResultHandle); + return createPostContingencyResultArrayPointer(result); + } }); } @CEntryPoint(name = "getOperatorStrategyResults") - public static PyPowsyblApiHeader.ArrayPointer getOperatorStrategyResults(IsolateThread thread, ObjectHandle securityAnalysisResultHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResultHandle); - return createOperatorStrategyResultsArrayPointer(result); + public static ArrayPointer getOperatorStrategyResults(IsolateThread thread, ObjectHandle securityAnalysisResultHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResultHandle); + return createOperatorStrategyResultsArrayPointer(result); + } }); } @CEntryPoint(name = "getPreContingencyResult") - public static PyPowsyblApiHeader.PreContingencyResultPointer getPreContingencyResult(IsolateThread thread, ObjectHandle securityAnalysisResultHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResultHandle); - return createPreContingencyResultArrayPointer(result); + public static PreContingencyResultPointer getPreContingencyResult(IsolateThread thread, ObjectHandle securityAnalysisResultHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public PreContingencyResultPointer get() { + SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResultHandle); + return createPreContingencyResultArrayPointer(result); + } }); } @CEntryPoint(name = "getLimitViolations") - public static PyPowsyblApiHeader.ArrayPointer getLimitViolations(IsolateThread thread, ObjectHandle securityAnalysisResultHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResultHandle); - return Dataframes.createCDataframe(Dataframes.limitViolationsMapper(), result); + public static ArrayPointer getLimitViolations(IsolateThread thread, ObjectHandle securityAnalysisResultHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + SecurityAnalysisResult result = ObjectHandles.getGlobal().get(securityAnalysisResultHandle); + return Dataframes.createCDataframe(Dataframes.limitViolationsMapper(), result); + } }); } @CEntryPoint(name = "freeContingencyResultArrayPointer") - public static void freeContingencyResultArrayPointer(IsolateThread thread, PyPowsyblApiHeader.ArrayPointer contingencyResultArrayPtr, + public static void freeContingencyResultArrayPointer(IsolateThread thread, ArrayPointer contingencyResultArrayPtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - for (int i = 0; i < contingencyResultArrayPtr.getLength(); i++) { - PyPowsyblApiHeader.PostContingencyResultPointer contingencyResultPtrPlus = contingencyResultArrayPtr.getPtr().addressOf(i); - UnmanagedMemory.free(contingencyResultPtrPlus.getContingencyId()); - for (int l = 0; l < contingencyResultPtrPlus.limitViolations().getLength(); l++) { - PyPowsyblApiHeader.LimitViolationPointer violation = contingencyResultPtrPlus.limitViolations().getPtr().addressOf(l); - UnmanagedMemory.free(violation.getSubjectId()); - UnmanagedMemory.free(violation.getSubjectName()); - UnmanagedMemory.free(violation.getLimitName()); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + for (int i = 0; i < contingencyResultArrayPtr.getLength(); i++) { + PostContingencyResultPointer contingencyResultPtrPlus = contingencyResultArrayPtr.getPtr().addressOf(i); + UnmanagedMemory.free(contingencyResultPtrPlus.getContingencyId()); + for (int l = 0; l < contingencyResultPtrPlus.limitViolations().getLength(); l++) { + PyPowsyblApiHeader.LimitViolationPointer violation = contingencyResultPtrPlus.limitViolations().getPtr().addressOf(l); + UnmanagedMemory.free(violation.getSubjectId()); + UnmanagedMemory.free(violation.getSubjectName()); + UnmanagedMemory.free(violation.getLimitName()); + } + UnmanagedMemory.free(contingencyResultPtrPlus.limitViolations().getPtr()); } - UnmanagedMemory.free(contingencyResultPtrPlus.limitViolations().getPtr()); + freeArrayPointer(contingencyResultArrayPtr); } - freeArrayPointer(contingencyResultArrayPtr); }); } @CEntryPoint(name = "freeOperatorStrategyResultArrayPointer") - public static void freeOperatorStrategyResultArrayPointer(IsolateThread thread, PyPowsyblApiHeader.ArrayPointer operatorStrategyResultArrayPtr, + public static void freeOperatorStrategyResultArrayPointer(IsolateThread thread, ArrayPointer operatorStrategyResultArrayPtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - for (int i = 0; i < operatorStrategyResultArrayPtr.getLength(); i++) { - PyPowsyblApiHeader.OperatorStrategyResultPointer strategyResultPtrPlus = operatorStrategyResultArrayPtr.getPtr().addressOf(i); - UnmanagedMemory.free(strategyResultPtrPlus.getOperatorStrategyId()); - for (int l = 0; l < strategyResultPtrPlus.limitViolations().getLength(); l++) { - PyPowsyblApiHeader.LimitViolationPointer violation = strategyResultPtrPlus.limitViolations().getPtr().addressOf(l); - UnmanagedMemory.free(violation.getSubjectId()); - UnmanagedMemory.free(violation.getSubjectName()); - UnmanagedMemory.free(violation.getLimitName()); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + for (int i = 0; i < operatorStrategyResultArrayPtr.getLength(); i++) { + OperatorStrategyResultPointer strategyResultPtrPlus = operatorStrategyResultArrayPtr.getPtr().addressOf(i); + UnmanagedMemory.free(strategyResultPtrPlus.getOperatorStrategyId()); + for (int l = 0; l < strategyResultPtrPlus.limitViolations().getLength(); l++) { + PyPowsyblApiHeader.LimitViolationPointer violation = strategyResultPtrPlus.limitViolations().getPtr().addressOf(l); + UnmanagedMemory.free(violation.getSubjectId()); + UnmanagedMemory.free(violation.getSubjectName()); + UnmanagedMemory.free(violation.getLimitName()); + } + UnmanagedMemory.free(strategyResultPtrPlus.limitViolations().getPtr()); } - UnmanagedMemory.free(strategyResultPtrPlus.limitViolations().getPtr()); + freeArrayPointer(operatorStrategyResultArrayPtr); } - freeArrayPointer(operatorStrategyResultArrayPtr); }); } @CEntryPoint(name = "freeSecurityAnalysisParameters") public static void freeSecurityAnalysisParameters(IsolateThread thread, SecurityAnalysisParametersPointer parameters, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - LoadFlowCUtils.freeLoadFlowParametersContent(parameters.getLoadFlowParameters()); - UnmanagedMemory.free(parameters); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + LoadFlowCUtils.freeLoadFlowParametersContent(parameters.getLoadFlowParameters()); + UnmanagedMemory.free(parameters); + } }); } @CEntryPoint(name = "createSecurityAnalysisParameters") public static SecurityAnalysisParametersPointer createSecurityAnalysisParameters(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> convertToSecurityAnalysisParametersPointer(SecurityAnalysisCUtils.createSecurityAnalysisParameters())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public SecurityAnalysisParametersPointer get() { + return convertToSecurityAnalysisParametersPointer(SecurityAnalysisCUtils.createSecurityAnalysisParameters()); + } + }); } private static SecurityAnalysisParametersPointer convertToSecurityAnalysisParametersPointer(SecurityAnalysisParameters parameters) { @@ -332,10 +393,13 @@ private static SecurityAnalysisParametersPointer convertToSecurityAnalysisParame } @CEntryPoint(name = "getSecurityAnalysisProviderParametersNames") - public static PyPowsyblApiHeader.ArrayPointer getProviderParametersNames(IsolateThread thread, CCharPointer provider, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String providerStr = CTypeUtil.toString(provider); - return Util.createCharPtrArray(SecurityAnalysisCUtils.getSecurityAnalysisProvider(providerStr).getSpecificParametersNames()); + public static ArrayPointer getProviderParametersNames(IsolateThread thread, CCharPointer provider, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + String providerStr = CTypeUtil.toString(provider); + return Util.createCharPtrArray(SecurityAnalysisCUtils.getSecurityAnalysisProvider(providerStr).getSpecificParametersNames()); + } }); } @@ -344,16 +408,19 @@ public static void addLoadActivePowerAction(IsolateThread thread, ObjectHandle s CCharPointer actionId, CCharPointer loadId, boolean relativeValue, double activePowerValue, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); - String actionIdStr = CTypeUtil.toString(actionId); - String loadIdStr = CTypeUtil.toString(loadId); - LoadAction action = new LoadActionBuilder().withId(actionIdStr) - .withLoadId(loadIdStr) - .withRelativeValue(relativeValue) - .withActivePowerValue(activePowerValue) - .build(); - analysisContext.addAction(action); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); + String actionIdStr = CTypeUtil.toString(actionId); + String loadIdStr = CTypeUtil.toString(loadId); + LoadAction action = new LoadActionBuilder().withId(actionIdStr) + .withLoadId(loadIdStr) + .withRelativeValue(relativeValue) + .withActivePowerValue(activePowerValue) + .build(); + analysisContext.addAction(action); + } }); } @@ -362,16 +429,19 @@ public static void addLoadReactivePowerAction(IsolateThread thread, ObjectHandle CCharPointer actionId, CCharPointer loadId, boolean relativeValue, double reactivePowerValue, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); - String actionIdStr = CTypeUtil.toString(actionId); - String loadIdStr = CTypeUtil.toString(loadId); - LoadAction action = new LoadActionBuilder().withId(actionIdStr) - .withLoadId(loadIdStr) - .withRelativeValue(relativeValue) - .withReactivePowerValue(reactivePowerValue) - .build(); - analysisContext.addAction(action); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); + String actionIdStr = CTypeUtil.toString(actionId); + String loadIdStr = CTypeUtil.toString(loadId); + LoadAction action = new LoadActionBuilder().withId(actionIdStr) + .withLoadId(loadIdStr) + .withRelativeValue(relativeValue) + .withReactivePowerValue(reactivePowerValue) + .build(); + analysisContext.addAction(action); + } }); } @@ -379,15 +449,18 @@ public static void addLoadReactivePowerAction(IsolateThread thread, ObjectHandle public static void addGeneratorActivePowerAction(IsolateThread thread, ObjectHandle securityAnalysisContextHandle, CCharPointer actionId, CCharPointer generatorId, boolean relativeValue, double activePower, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); - String actionIdStr = CTypeUtil.toString(actionId); - String generatorIdStr = CTypeUtil.toString(generatorId); - GeneratorActionBuilder builder = new GeneratorActionBuilder().withId(actionIdStr) - .withGeneratorId(generatorIdStr) - .withActivePowerRelativeValue(relativeValue) - .withActivePowerValue(activePower); - analysisContext.addAction(builder.build()); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); + String actionIdStr = CTypeUtil.toString(actionId); + String generatorIdStr = CTypeUtil.toString(generatorId); + GeneratorActionBuilder builder = new GeneratorActionBuilder().withId(actionIdStr) + .withGeneratorId(generatorIdStr) + .withActivePowerRelativeValue(relativeValue) + .withActivePowerValue(activePower); + analysisContext.addAction(builder.build()); + } }); } @@ -395,12 +468,15 @@ public static void addGeneratorActivePowerAction(IsolateThread thread, ObjectHan public static void addSwitchAction(IsolateThread thread, ObjectHandle securityAnalysisContextHandle, CCharPointer actionId, CCharPointer switchId, boolean open, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); - String actionIdStr = CTypeUtil.toString(actionId); - String switchIdStr = CTypeUtil.toString(switchId); - SwitchAction action = new SwitchAction(actionIdStr, switchIdStr, open); - analysisContext.addAction(action); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); + String actionIdStr = CTypeUtil.toString(actionId); + String switchIdStr = CTypeUtil.toString(switchId); + SwitchAction action = new SwitchAction(actionIdStr, switchIdStr, open); + analysisContext.addAction(action); + } }); } @@ -408,12 +484,15 @@ public static void addSwitchAction(IsolateThread thread, ObjectHandle securityAn public static void addPhaseTapChangerPositionAction(IsolateThread thread, ObjectHandle securityAnalysisContextHandle, CCharPointer actionId, CCharPointer transformerId, boolean isRelative, int tapPosition, PyPowsyblApiHeader.ThreeSideType side, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); - String actionIdStr = CTypeUtil.toString(actionId); - String transformerIdStr = CTypeUtil.toString(transformerId); - PhaseTapChangerTapPositionAction pstAction = new PhaseTapChangerTapPositionAction(actionIdStr, transformerIdStr, isRelative, tapPosition, Util.convert(side)); - analysisContext.addAction(pstAction); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); + String actionIdStr = CTypeUtil.toString(actionId); + String transformerIdStr = CTypeUtil.toString(transformerId); + PhaseTapChangerTapPositionAction pstAction = new PhaseTapChangerTapPositionAction(actionIdStr, transformerIdStr, isRelative, tapPosition, Util.convert(side)); + analysisContext.addAction(pstAction); + } }); } @@ -421,12 +500,15 @@ public static void addPhaseTapChangerPositionAction(IsolateThread thread, Object public static void addRatioTapChangerPositionAction(IsolateThread thread, ObjectHandle securityAnalysisContextHandle, CCharPointer actionId, CCharPointer transformerId, boolean isRelative, int tapPosition, PyPowsyblApiHeader.ThreeSideType side, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); - String actionIdStr = CTypeUtil.toString(actionId); - String transformerIdStr = CTypeUtil.toString(transformerId); - RatioTapChangerTapPositionAction ratioTapChangerAction = new RatioTapChangerTapPositionAction(actionIdStr, transformerIdStr, isRelative, tapPosition, Util.convert(side)); - analysisContext.addAction(ratioTapChangerAction); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); + String actionIdStr = CTypeUtil.toString(actionId); + String transformerIdStr = CTypeUtil.toString(transformerId); + RatioTapChangerTapPositionAction ratioTapChangerAction = new RatioTapChangerTapPositionAction(actionIdStr, transformerIdStr, isRelative, tapPosition, Util.convert(side)); + analysisContext.addAction(ratioTapChangerAction); + } }); } @@ -434,16 +516,19 @@ public static void addRatioTapChangerPositionAction(IsolateThread thread, Object public static void addShuntCompensatorPositionAction(IsolateThread thread, ObjectHandle securityAnalysisContextHandle, CCharPointer actionId, CCharPointer shuntCompensatorId, int sectionCount, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); - String actionIdStr = CTypeUtil.toString(actionId); - String shuntCompensatorIdStr = CTypeUtil.toString(shuntCompensatorId); - ShuntCompensatorPositionActionBuilder builder = new ShuntCompensatorPositionActionBuilder(); - ShuntCompensatorPositionAction action = builder.withId(actionIdStr) - .withShuntCompensatorId(shuntCompensatorIdStr) - .withSectionCount(sectionCount) - .build(); - analysisContext.addAction(action); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); + String actionIdStr = CTypeUtil.toString(actionId); + String shuntCompensatorIdStr = CTypeUtil.toString(shuntCompensatorId); + ShuntCompensatorPositionActionBuilder builder = new ShuntCompensatorPositionActionBuilder(); + ShuntCompensatorPositionAction action = builder.withId(actionIdStr) + .withShuntCompensatorId(shuntCompensatorIdStr) + .withSectionCount(sectionCount) + .build(); + analysisContext.addAction(action); + } }); } @@ -455,17 +540,20 @@ public static void addOperatorStrategy(IsolateThread thread, ObjectHandle securi CCharPointerPointer subjectIds, int subjectIdsCount, CIntPointer violationTypes, int violationTypesCount, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); - String operationStrategyIdStr = CTypeUtil.toString(operationStrategyId); - String contingencyIdStr = CTypeUtil.toString(contingencyId); - List actionsStrList = CTypeUtil.toStringList(actions, actionCount); - - Condition condition = buildCondition(conditionType, subjectIds, subjectIdsCount, violationTypes, violationTypesCount); - - OperatorStrategy op = new OperatorStrategy(operationStrategyIdStr, - ContingencyContext.specificContingency(contingencyIdStr), condition, actionsStrList); - analysisContext.addOperatorStrategy(op); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + SecurityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(securityAnalysisContextHandle); + String operationStrategyIdStr = CTypeUtil.toString(operationStrategyId); + String contingencyIdStr = CTypeUtil.toString(contingencyId); + List actionsStrList = CTypeUtil.toStringList(actions, actionCount); + + Condition condition = buildCondition(conditionType, subjectIds, subjectIdsCount, violationTypes, violationTypesCount); + + OperatorStrategy op = new OperatorStrategy(operationStrategyIdStr, + ContingencyContext.specificContingency(contingencyIdStr), condition, actionsStrList); + analysisContext.addOperatorStrategy(op); + } }); } diff --git a/java/src/main/java/com/powsybl/python/sensitivity/SensitivityAnalysisCFunctions.java b/java/src/main/java/com/powsybl/python/sensitivity/SensitivityAnalysisCFunctions.java index 9b436c851..53068249e 100644 --- a/java/src/main/java/com/powsybl/python/sensitivity/SensitivityAnalysisCFunctions.java +++ b/java/src/main/java/com/powsybl/python/sensitivity/SensitivityAnalysisCFunctions.java @@ -7,12 +7,13 @@ */ package com.powsybl.python.sensitivity; -import com.powsybl.commons.PowsyblException; import com.powsybl.commons.report.ReportNode; import com.powsybl.iidm.network.Network; import com.powsybl.python.commons.*; +import com.powsybl.python.commons.PyPowsyblApiHeader.ArrayPointer; import com.powsybl.python.commons.PyPowsyblApiHeader.ExceptionHandlerPointer; import com.powsybl.python.commons.PyPowsyblApiHeader.SensitivityAnalysisParametersPointer; +import com.powsybl.python.commons.Util.PointerProvider; import com.powsybl.python.loadflow.LoadFlowCFunctions; import com.powsybl.python.loadflow.LoadFlowCUtils; import com.powsybl.python.report.ReportCUtils; @@ -45,6 +46,7 @@ * * @author Sylvain Leclerc */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class SensitivityAnalysisCFunctions { @@ -56,47 +58,68 @@ private static Logger logger() { } @CEntryPoint(name = "getSensitivityAnalysisProviderNames") - public static PyPowsyblApiHeader.ArrayPointer getSensitivityAnalysisProviderNames(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> createCharPtrArray(SensitivityAnalysisProvider.findAll() - .stream().map(SensitivityAnalysisProvider::getName).collect(Collectors.toList()))); + public static ArrayPointer getSensitivityAnalysisProviderNames(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + return createCharPtrArray(SensitivityAnalysisProvider.findAll() + .stream().map(SensitivityAnalysisProvider::getName).collect(Collectors.toList())); + } + }); } @CEntryPoint(name = "setDefaultSensitivityAnalysisProvider") public static void setDefaultSensitivityAnalysisProvider(IsolateThread thread, CCharPointer provider, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - PyPowsyblConfiguration.setDefaultSensitivityAnalysisProvider(CTypeUtil.toString(provider)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + PyPowsyblConfiguration.setDefaultSensitivityAnalysisProvider(CTypeUtil.toString(provider)); + } }); } @CEntryPoint(name = "getDefaultSensitivityAnalysisProvider") public static CCharPointer getDefaultSensitivityAnalysisProvider(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> CTypeUtil.toCharPtr(PyPowsyblConfiguration.getDefaultSensitivityAnalysisProvider())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public CCharPointer get() { + return CTypeUtil.toCharPtr(PyPowsyblConfiguration.getDefaultSensitivityAnalysisProvider()); + } + }); } @CEntryPoint(name = "createSensitivityAnalysis") public static ObjectHandle createSensitivityAnalysis(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> ObjectHandles.getGlobal().create(new SensitivityAnalysisContext())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + return ObjectHandles.getGlobal().create(new SensitivityAnalysisContext()); + } + }); } @CEntryPoint(name = "setZones") public static void setZones(IsolateThread thread, ObjectHandle sensitivityAnalysisContextHandle, PyPowsyblApiHeader.ZonePointerPointer zonePtrPtr, int zoneCount, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - SensitivityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(sensitivityAnalysisContextHandle); - List variableSets = new ArrayList<>(zoneCount); - for (int zoneIndex = 0; zoneIndex < zoneCount; zoneIndex++) { - PyPowsyblApiHeader.ZonePointer zonePtrI = zonePtrPtr.read(zoneIndex); - String zoneId = CTypeUtil.toString(zonePtrI.getId()); - List injectionsIds = toStringList(zonePtrI.getInjectionsIds(), zonePtrI.getLength()); - List injectionsShiftKeys = CTypeUtil.toDoubleList(zonePtrI.getinjectionsShiftKeys(), zonePtrI.getLength()); - List variables = new ArrayList<>(injectionsIds.size()); - for (int injectionIndex = 0; injectionIndex < injectionsIds.size(); injectionIndex++) { - variables.add(new WeightedSensitivityVariable(injectionsIds.get(injectionIndex), injectionsShiftKeys.get(injectionIndex))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + SensitivityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(sensitivityAnalysisContextHandle); + List variableSets = new ArrayList<>(zoneCount); + for (int zoneIndex = 0; zoneIndex < zoneCount; zoneIndex++) { + PyPowsyblApiHeader.ZonePointer zonePtrI = zonePtrPtr.read(zoneIndex); + String zoneId = CTypeUtil.toString(zonePtrI.getId()); + List injectionsIds = toStringList(zonePtrI.getInjectionsIds(), zonePtrI.getLength()); + List injectionsShiftKeys = CTypeUtil.toDoubleList(zonePtrI.getinjectionsShiftKeys(), zonePtrI.getLength()); + List variables = new ArrayList<>(injectionsIds.size()); + for (int injectionIndex = 0; injectionIndex < injectionsIds.size(); injectionIndex++) { + variables.add(new WeightedSensitivityVariable(injectionsIds.get(injectionIndex), injectionsShiftKeys.get(injectionIndex))); + } + variableSets.add(new SensitivityVariableSet(zoneId, variables)); } - variableSets.add(new SensitivityVariableSet(zoneId, variables)); + analysisContext.setVariableSets(variableSets); } - analysisContext.setVariableSets(variableSets); }); } @@ -110,14 +133,17 @@ public static void addFactorMatrix(IsolateThread thread, ObjectHandle sensitivit PyPowsyblApiHeader.SensitivityFunctionType sensitivityFunctionType, PyPowsyblApiHeader.SensitivityVariableType sensitivityVariableType, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - SensitivityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(sensitivityAnalysisContextHandle); - List branchesIds = toStringList(branchIdPtrPtr, branchIdCount); - List variablesIds = toStringList(variableIdPtrPtr, variableIdCount); - String matrixId = CTypeUtil.toString(matrixIdPtr); - List contingencies = toStringList(contingenciesIdPtrPtr, contingenciesIdCount); - analysisContext.addFactorMatrix(matrixId, branchesIds, variablesIds, contingencies, Util.convert(contingencyContextType), Util.convert(sensitivityFunctionType), - Util.convert(sensitivityVariableType)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + SensitivityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(sensitivityAnalysisContextHandle); + List branchesIds = toStringList(branchIdPtrPtr, branchIdCount); + List variablesIds = toStringList(variableIdPtrPtr, variableIdCount); + String matrixId = CTypeUtil.toString(matrixIdPtr); + List contingencies = toStringList(contingenciesIdPtrPtr, contingenciesIdCount); + analysisContext.addFactorMatrix(matrixId, branchesIds, variablesIds, contingencies, Util.convert(contingencyContextType), Util.convert(sensitivityFunctionType), + Util.convert(sensitivityVariableType)); + } }); } @@ -126,15 +152,18 @@ public static ObjectHandle runSensitivityAnalysis(IsolateThread thread, ObjectHa ObjectHandle networkHandle, boolean dc, SensitivityAnalysisParametersPointer sensitivityAnalysisParametersPtr, CCharPointer providerName, ObjectHandle reportNodeHandle, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - SensitivityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(sensitivityAnalysisContextHandle); - Network network = ObjectHandles.getGlobal().get(networkHandle); - SensitivityAnalysisProvider provider = getProvider(CTypeUtil.toString(providerName)); - logger().info("Sensitivity analysis provider used for sensitivity analysis is : {}", provider.getName()); - SensitivityAnalysisParameters sensitivityAnalysisParameters = SensitivityAnalysisCUtils.createSensitivityAnalysisParameters(dc, sensitivityAnalysisParametersPtr, provider); - ReportNode reportNode = ReportCUtils.getReportNode(reportNodeHandle); - SensitivityAnalysisResultContext resultContext = analysisContext.run(network, sensitivityAnalysisParameters, provider.getName(), reportNode); - return ObjectHandles.getGlobal().create(resultContext); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + SensitivityAnalysisContext analysisContext = ObjectHandles.getGlobal().get(sensitivityAnalysisContextHandle); + Network network = ObjectHandles.getGlobal().get(networkHandle); + SensitivityAnalysisProvider provider = SensitivityAnalysisCUtils.getSensitivityAnalysisProvider(CTypeUtil.toString(providerName)); + logger().info("Sensitivity analysis provider used for sensitivity analysis is : {}", provider.getName()); + SensitivityAnalysisParameters sensitivityAnalysisParameters = SensitivityAnalysisCUtils.createSensitivityAnalysisParameters(dc, sensitivityAnalysisParametersPtr, provider); + ReportNode reportNode = ReportCUtils.getReportNode(reportNodeHandle); + SensitivityAnalysisResultContext resultContext = analysisContext.run(network, sensitivityAnalysisParameters, provider.getName(), reportNode); + return ObjectHandles.getGlobal().create(resultContext); + } }); } @@ -142,11 +171,14 @@ public static ObjectHandle runSensitivityAnalysis(IsolateThread thread, ObjectHa public static PyPowsyblApiHeader.MatrixPointer getSensitivityMatrix(IsolateThread thread, ObjectHandle sensitivityAnalysisResultContextHandle, CCharPointer matrixIdPtr, CCharPointer contingencyIdPtr, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - SensitivityAnalysisResultContext resultContext = ObjectHandles.getGlobal().get(sensitivityAnalysisResultContextHandle); - String contingencyId = CTypeUtil.toString(contingencyIdPtr); - String matrixId = CTypeUtil.toString(matrixIdPtr); - return resultContext.createSensitivityMatrix(matrixId, contingencyId); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public PyPowsyblApiHeader.MatrixPointer get() { + SensitivityAnalysisResultContext resultContext = ObjectHandles.getGlobal().get(sensitivityAnalysisResultContextHandle); + String contingencyId = CTypeUtil.toString(contingencyIdPtr); + String matrixId = CTypeUtil.toString(matrixIdPtr); + return resultContext.createSensitivityMatrix(matrixId, contingencyId); + } }); } @@ -154,34 +186,37 @@ public static PyPowsyblApiHeader.MatrixPointer getSensitivityMatrix(IsolateThrea public static PyPowsyblApiHeader.MatrixPointer getReferenceMatrix(IsolateThread thread, ObjectHandle sensitivityAnalysisResultContextHandle, CCharPointer matrixIdPtr, CCharPointer contingencyIdPtr, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - SensitivityAnalysisResultContext resultContext = ObjectHandles.getGlobal().get(sensitivityAnalysisResultContextHandle); - String contingencyId = CTypeUtil.toString(contingencyIdPtr); - String matrixId = CTypeUtil.toString(matrixIdPtr); - return resultContext.createReferenceMatrix(matrixId, contingencyId); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public PyPowsyblApiHeader.MatrixPointer get() { + SensitivityAnalysisResultContext resultContext = ObjectHandles.getGlobal().get(sensitivityAnalysisResultContextHandle); + String contingencyId = CTypeUtil.toString(contingencyIdPtr); + String matrixId = CTypeUtil.toString(matrixIdPtr); + return resultContext.createReferenceMatrix(matrixId, contingencyId); + } }); } - private static SensitivityAnalysisProvider getProvider(String name) { - String actualName = name.isEmpty() ? PyPowsyblConfiguration.getDefaultSensitivityAnalysisProvider() : name; - return SensitivityAnalysisProvider.findAll().stream() - .filter(provider -> provider.getName().equals(actualName)) - .findFirst() - .orElseThrow(() -> new PowsyblException("No sensitivity analysis provider for name '" + actualName + "'")); - } - @CEntryPoint(name = "freeSensitivityAnalysisParameters") public static void freeSensitivityAnalysisParameters(IsolateThread thread, SensitivityAnalysisParametersPointer parameters, ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - LoadFlowCUtils.freeLoadFlowParametersContent(parameters.getLoadFlowParameters()); - UnmanagedMemory.free(parameters); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + LoadFlowCUtils.freeLoadFlowParametersContent(parameters.getLoadFlowParameters()); + UnmanagedMemory.free(parameters); + } }); } @CEntryPoint(name = "createSensitivityAnalysisParameters") public static SensitivityAnalysisParametersPointer createSensitivityAnalysisParameters(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> convertToSensitivityAnalysisParametersPointer(SensitivityAnalysisCUtils.createSensitivityAnalysisParameters())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public SensitivityAnalysisParametersPointer get() { + return convertToSensitivityAnalysisParametersPointer(SensitivityAnalysisCUtils.createSensitivityAnalysisParameters()); + } + }); } private static SensitivityAnalysisParametersPointer convertToSensitivityAnalysisParametersPointer(SensitivityAnalysisParameters parameters) { @@ -193,10 +228,13 @@ private static SensitivityAnalysisParametersPointer convertToSensitivityAnalysis } @CEntryPoint(name = "getSensitivityAnalysisProviderParametersNames") - public static PyPowsyblApiHeader.ArrayPointer getProviderParametersNames(IsolateThread thread, CCharPointer provider, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String providerStr = CTypeUtil.toString(provider); - return Util.createCharPtrArray(SensitivityAnalysisCUtils.getSensitivityAnalysisProvider(providerStr).getSpecificParametersNames()); + public static ArrayPointer getProviderParametersNames(IsolateThread thread, CCharPointer provider, ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + String providerStr = CTypeUtil.toString(provider); + return Util.createCharPtrArray(SensitivityAnalysisCUtils.getSensitivityAnalysisProvider(providerStr).getSpecificParametersNames()); + } }); } } diff --git a/java/src/main/java/com/powsybl/python/shortcircuit/ShortCircuitAnalysisCFunctions.java b/java/src/main/java/com/powsybl/python/shortcircuit/ShortCircuitAnalysisCFunctions.java index 1d3087b7f..37dbfff2a 100644 --- a/java/src/main/java/com/powsybl/python/shortcircuit/ShortCircuitAnalysisCFunctions.java +++ b/java/src/main/java/com/powsybl/python/shortcircuit/ShortCircuitAnalysisCFunctions.java @@ -7,14 +7,16 @@ */ package com.powsybl.python.shortcircuit; -import com.powsybl.commons.PowsyblException; import com.powsybl.commons.report.ReportNode; import com.powsybl.dataframe.shortcircuit.adders.FaultDataframeAdder; import com.powsybl.dataframe.update.UpdatingDataframe; import com.powsybl.iidm.network.Network; import com.powsybl.python.commons.*; +import com.powsybl.python.commons.PyPowsyblApiHeader.ArrayPointer; import com.powsybl.python.commons.PyPowsyblApiHeader.DataframeMetadataPointer; +import com.powsybl.python.commons.PyPowsyblApiHeader.SeriesPointer; import com.powsybl.python.commons.PyPowsyblApiHeader.ShortCircuitAnalysisParametersPointer; +import com.powsybl.python.commons.Util.PointerProvider; import com.powsybl.python.network.Dataframes; import com.powsybl.python.network.NetworkCFunctions; import com.powsybl.shortcircuit.ShortCircuitAnalysisProvider; @@ -44,6 +46,7 @@ * * @author Christian Biasuzzi */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class ShortCircuitAnalysisCFunctions { @@ -55,34 +58,44 @@ private static Logger logger() { } @CEntryPoint(name = "getShortCircuitAnalysisProviderNames") - public static PyPowsyblApiHeader.ArrayPointer getShortCircuitAnalysisProviderNames(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> createCharPtrArray(ShortCircuitAnalysisProvider.findAll() - .stream().map(ShortCircuitAnalysisProvider::getName).collect(Collectors.toList()))); + public static ArrayPointer getShortCircuitAnalysisProviderNames(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + return createCharPtrArray(ShortCircuitAnalysisProvider.findAll() + .stream().map(ShortCircuitAnalysisProvider::getName).collect(Collectors.toList())); + } + }); } @CEntryPoint(name = "setDefaultShortCircuitAnalysisProvider") public static void setDefaultShortCircuitAnalysisProvider(IsolateThread thread, CCharPointer provider, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - PyPowsyblConfiguration.setDefaultShortCircuitAnalysisProvider(CTypeUtil.toString(provider)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + PyPowsyblConfiguration.setDefaultShortCircuitAnalysisProvider(CTypeUtil.toString(provider)); + } }); } @CEntryPoint(name = "getDefaultShortCircuitAnalysisProvider") public static CCharPointer getDefaultShortCircuitAnalysisProvider(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> CTypeUtil.toCharPtr(PyPowsyblConfiguration.getDefaultShortCircuitAnalysisProvider())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public CCharPointer get() { + return CTypeUtil.toCharPtr(PyPowsyblConfiguration.getDefaultShortCircuitAnalysisProvider()); + } + }); } @CEntryPoint(name = "createShortCircuitAnalysis") public static ObjectHandle createShortCircuitAnalysis(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> ObjectHandles.getGlobal().create(new ShortCircuitAnalysisContext())); - } - - private static ShortCircuitAnalysisProvider getProvider(String name) { - String actualName = name.isEmpty() ? PyPowsyblConfiguration.getDefaultShortCircuitAnalysisProvider() : name; - return ShortCircuitAnalysisProvider.findAll().stream() - .filter(provider -> provider.getName().equals(actualName)) - .findFirst() - .orElseThrow(() -> new PowsyblException("No short-circuit analysis provider for name '" + actualName + "'")); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + return ObjectHandles.getGlobal().create(new ShortCircuitAnalysisContext()); + } + }); } @CEntryPoint(name = "runShortCircuitAnalysis") @@ -90,30 +103,43 @@ public static ObjectHandle runShortCircuitAnalysis(IsolateThread thread, ObjectH ObjectHandle networkHandle, ShortCircuitAnalysisParametersPointer shortCircuitAnalysisParametersPointer, CCharPointer providerName, ObjectHandle reportNodeHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - ShortCircuitAnalysisContext analysisContext = ObjectHandles.getGlobal().get(shortCircuitAnalysisContextHandle); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + ShortCircuitAnalysisContext analysisContext = ObjectHandles.getGlobal().get(shortCircuitAnalysisContextHandle); - Network network = ObjectHandles.getGlobal().get(networkHandle); + Network network = ObjectHandles.getGlobal().get(networkHandle); - ShortCircuitAnalysisProvider provider = getProvider(CTypeUtil.toString(providerName)); - logger().info("Short-circuit analysis provider used for short-circuit analysis is : {}", provider.getName()); - ShortCircuitParameters shortCircuitAnalysisParameters = ShortCircuitAnalysisCUtils.createShortCircuitAnalysisParameters(shortCircuitAnalysisParametersPointer, provider); + ShortCircuitAnalysisProvider provider = ShortCircuitAnalysisCUtils.getShortCircuitAnalysisProvider(CTypeUtil.toString(providerName)); + logger().info("Short-circuit analysis provider used for short-circuit analysis is : {}", provider.getName()); + ShortCircuitParameters shortCircuitAnalysisParameters = ShortCircuitAnalysisCUtils.createShortCircuitAnalysisParameters(shortCircuitAnalysisParametersPointer, provider); - ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); - ShortCircuitAnalysisResult results = analysisContext.run(network, shortCircuitAnalysisParameters, provider.getName(), reportNode); - return ObjectHandles.getGlobal().create(results); + ReportNode reportNode = ObjectHandles.getGlobal().get(reportNodeHandle); + ShortCircuitAnalysisResult results = analysisContext.run(network, shortCircuitAnalysisParameters, provider.getName(), reportNode); + return ObjectHandles.getGlobal().create(results); + } }); } @CEntryPoint(name = "freeShortCircuitAnalysisParameters") public static void freeShortCircuitAnalysisParameters(IsolateThread thread, ShortCircuitAnalysisParametersPointer parameters, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.free(parameters)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + UnmanagedMemory.free(parameters); + } + }); } @CEntryPoint(name = "createShortCircuitAnalysisParameters") public static ShortCircuitAnalysisParametersPointer createShortCircuitAnalysisParameters(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> convertToShortCircuitAnalysisParametersPointer(ShortCircuitAnalysisCUtils.createShortCircuitAnalysisParameters())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ShortCircuitAnalysisParametersPointer get() { + return convertToShortCircuitAnalysisParametersPointer(ShortCircuitAnalysisCUtils.createShortCircuitAnalysisParameters()); + } + }); } private static ShortCircuitAnalysisParametersPointer convertToShortCircuitAnalysisParametersPointer(ShortCircuitParameters parameters) { @@ -137,68 +163,91 @@ static List getSpecificParametersNames(ShortCircuitAnalysisProvider prov } @CEntryPoint(name = "getShortCircuitAnalysisProviderParametersNames") - public static PyPowsyblApiHeader.ArrayPointer getProviderParametersNames(IsolateThread thread, CCharPointer provider, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - String providerStr = CTypeUtil.toString(provider); - return Util.createCharPtrArray(getSpecificParametersNames(ShortCircuitAnalysisCUtils.getShortCircuitAnalysisProvider(providerStr))); + public static ArrayPointer getProviderParametersNames(IsolateThread thread, CCharPointer provider, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + String providerStr = CTypeUtil.toString(provider); + return Util.createCharPtrArray(getSpecificParametersNames(ShortCircuitAnalysisCUtils.getShortCircuitAnalysisProvider(providerStr))); + } }); } @CEntryPoint(name = "getFaultsDataframeMetaData") public static DataframeMetadataPointer getFaultsDataframeMetaData(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> CTypeUtil.createSeriesMetadata(new FaultDataframeAdder().getMetadata())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public DataframeMetadataPointer get() { + return CTypeUtil.createSeriesMetadata(new FaultDataframeAdder().getMetadata()); + } + }); } @CEntryPoint(name = "setFaults") public static void setFaults(IsolateThread thread, ObjectHandle contextHandle, PyPowsyblApiHeader.DataframePointer cDataframe, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - doCatch(exceptionHandlerPtr, () -> { - ShortCircuitAnalysisContext context = ObjectHandles.getGlobal().get(contextHandle); - UpdatingDataframe faultDataframe = NetworkCFunctions.createDataframe(cDataframe); - new FaultDataframeAdder().addElements(context, faultDataframe); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + ShortCircuitAnalysisContext context = ObjectHandles.getGlobal().get(contextHandle); + UpdatingDataframe faultDataframe = NetworkCFunctions.createDataframe(cDataframe); + new FaultDataframeAdder().addElements(context, faultDataframe); + } }); } @CEntryPoint(name = "getShortCircuitAnalysisFaultResults") - public static PyPowsyblApiHeader.ArrayPointer getShortCircuitAnalysisFaultResults(IsolateThread thread, - ObjectHandle shortCircuitAnalysisResult, - boolean withFortescueResult, - PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - ShortCircuitAnalysisResult result = ObjectHandles.getGlobal().get(shortCircuitAnalysisResult); - return Dataframes.createCDataframe(Dataframes.shortCircuitAnalysisFaultResultsMapper(withFortescueResult), result); + public static ArrayPointer getShortCircuitAnalysisFaultResults(IsolateThread thread, + ObjectHandle shortCircuitAnalysisResult, + boolean withFortescueResult, + PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + ShortCircuitAnalysisResult result = ObjectHandles.getGlobal().get(shortCircuitAnalysisResult); + return Dataframes.createCDataframe(Dataframes.shortCircuitAnalysisFaultResultsMapper(withFortescueResult), result); + } }); } @CEntryPoint(name = "getShortCircuitAnalysisFeederResults") - public static PyPowsyblApiHeader.ArrayPointer getShortCircuitAnalysisFeederResults(IsolateThread thread, - ObjectHandle shortCircuitAnalysisResult, - boolean withFortescueResult, - PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - ShortCircuitAnalysisResult result = ObjectHandles.getGlobal().get(shortCircuitAnalysisResult); - return Dataframes.createCDataframe(Dataframes.shortCircuitAnalysisMagnitudeFeederResultsMapper(withFortescueResult), result); + public static ArrayPointer getShortCircuitAnalysisFeederResults(IsolateThread thread, + ObjectHandle shortCircuitAnalysisResult, + boolean withFortescueResult, + PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + ShortCircuitAnalysisResult result = ObjectHandles.getGlobal().get(shortCircuitAnalysisResult); + return Dataframes.createCDataframe(Dataframes.shortCircuitAnalysisMagnitudeFeederResultsMapper(withFortescueResult), result); + } }); } @CEntryPoint(name = "getShortCircuitAnalysisLimitViolationsResults") - public static PyPowsyblApiHeader.ArrayPointer getShortCircuitAnalysisLimitViolationsResults(IsolateThread thread, ObjectHandle shortCircuitAnalysisResult, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - ShortCircuitAnalysisResult result = ObjectHandles.getGlobal().get(shortCircuitAnalysisResult); - return Dataframes.createCDataframe(Dataframes.shortCircuitAnalysisLimitViolationsResultsMapper(), result); + public static ArrayPointer getShortCircuitAnalysisLimitViolationsResults(IsolateThread thread, ObjectHandle shortCircuitAnalysisResult, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + ShortCircuitAnalysisResult result = ObjectHandles.getGlobal().get(shortCircuitAnalysisResult); + return Dataframes.createCDataframe(Dataframes.shortCircuitAnalysisLimitViolationsResultsMapper(), result); + } }); } @CEntryPoint(name = "getShortCircuitAnalysisBusResults") - public static PyPowsyblApiHeader.ArrayPointer getShortCircuitAnalysisBusResults(IsolateThread thread, - ObjectHandle shortCircuitAnalysisResult, - boolean withFortescueResult, - PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> { - ShortCircuitAnalysisResult result = ObjectHandles.getGlobal().get(shortCircuitAnalysisResult); - return Dataframes.createCDataframe(Dataframes.shortCircuitAnalysisMagnitudeBusResultsMapper(withFortescueResult), result); + public static ArrayPointer getShortCircuitAnalysisBusResults(IsolateThread thread, + ObjectHandle shortCircuitAnalysisResult, + boolean withFortescueResult, + PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + ShortCircuitAnalysisResult result = ObjectHandles.getGlobal().get(shortCircuitAnalysisResult); + return Dataframes.createCDataframe(Dataframes.shortCircuitAnalysisMagnitudeBusResultsMapper(withFortescueResult), result); + } }); } } diff --git a/java/src/main/java/com/powsybl/python/voltageinit/VoltageInitializerCFunctions.java b/java/src/main/java/com/powsybl/python/voltageinit/VoltageInitializerCFunctions.java index 889687177..e263aaa79 100644 --- a/java/src/main/java/com/powsybl/python/voltageinit/VoltageInitializerCFunctions.java +++ b/java/src/main/java/com/powsybl/python/voltageinit/VoltageInitializerCFunctions.java @@ -10,7 +10,9 @@ import static com.powsybl.python.commons.Util.doCatch; import java.util.List; +import java.util.function.Supplier; +import com.powsybl.python.commons.Util.PointerProvider; import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.ObjectHandle; import org.graalvm.nativeimage.ObjectHandles; @@ -41,6 +43,7 @@ /** * @author Nicolas Pierre */ +@SuppressWarnings({"java:S1602", "java:S1604"}) @CContext(Directives.class) public final class VoltageInitializerCFunctions { private VoltageInitializerCFunctions() { @@ -53,253 +56,409 @@ private static Logger logger() { @CEntryPoint(name = "createVoltageInitializerParams") public static ObjectHandle createVoltageInitializerParams(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> ObjectHandles.getGlobal().create(new OpenReacParameters())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + return ObjectHandles.getGlobal().create(new OpenReacParameters()); + } + }); } @CEntryPoint(name = "voltageInitializerAddSpecificLowVoltageLimits") public static void addSpecificLowVoltageLimits(IsolateThread thread, ObjectHandle paramsHandle, CCharPointer idPtr, boolean isRelative, double limit, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - String voltageLevelId = CTypeUtil.toString(idPtr); - doCatch(exceptionHandlerPtr, () -> params - .addSpecificVoltageLimits(List.of( - new VoltageLimitOverride(voltageLevelId, - VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT, - isRelative, - limit) - ))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + String voltageLevelId = CTypeUtil.toString(idPtr); + params.addSpecificVoltageLimits(List.of( + new VoltageLimitOverride(voltageLevelId, + VoltageLimitOverride.VoltageLimitType.LOW_VOLTAGE_LIMIT, + isRelative, + limit) + )); + } + }); } @CEntryPoint(name = "voltageInitializerAddSpecificHighVoltageLimits") public static void addSpecificHighVoltageLimits(IsolateThread thread, ObjectHandle paramsHandle, CCharPointer idPtr, boolean isRelative, double limit, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - String voltageLevelId = CTypeUtil.toString(idPtr); - doCatch(exceptionHandlerPtr, () -> params - .addSpecificVoltageLimits(List.of( - new VoltageLimitOverride(voltageLevelId, - VoltageLimitOverride.VoltageLimitType.HIGH_VOLTAGE_LIMIT, - isRelative, - limit) - ))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + String voltageLevelId = CTypeUtil.toString(idPtr); + params.addSpecificVoltageLimits(List.of( + new VoltageLimitOverride(voltageLevelId, + VoltageLimitOverride.VoltageLimitType.HIGH_VOLTAGE_LIMIT, + isRelative, + limit) + )); + } + }); } @CEntryPoint(name = "voltageInitializerAddVariableShuntCompensators") public static void addVariableShuntCompensators(IsolateThread thread, ObjectHandle paramsHandle, CCharPointer idPtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - String id = CTypeUtil.toString(idPtr); - doCatch(exceptionHandlerPtr, () -> params.addVariableShuntCompensators(List.of(id))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + String id = CTypeUtil.toString(idPtr); + params.addVariableShuntCompensators(List.of(id)); + } + }); } @CEntryPoint(name = "voltageInitializerAddConstantQGenerators") public static void addConstantQGenerators(IsolateThread thread, ObjectHandle paramsHandle, CCharPointer idPtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - String id = CTypeUtil.toString(idPtr); - doCatch(exceptionHandlerPtr, () -> params.addConstantQGenerators(List.of(id))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + String id = CTypeUtil.toString(idPtr); + params.addConstantQGenerators(List.of(id)); + } + }); } @CEntryPoint(name = "voltageInitializerAddVariableTwoWindingsTransformers") public static void addVariableTwoWindingsTransformers(IsolateThread thread, ObjectHandle paramsHandle, CCharPointer idPtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - String id = CTypeUtil.toString(idPtr); - doCatch(exceptionHandlerPtr, () -> params.addVariableTwoWindingsTransformers(List.of(id))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + String id = CTypeUtil.toString(idPtr); + params.addVariableTwoWindingsTransformers(List.of(id)); + } + }); } @CEntryPoint(name = "voltageInitializerAddConfiguredReactiveSlackBuses") public static void addConfiguredReactiveSlackBuses(IsolateThread thread, ObjectHandle paramsHandle, CCharPointer idPtr, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - String id = CTypeUtil.toString(idPtr); - doCatch(exceptionHandlerPtr, () -> params.addConfiguredReactiveSlackBuses(List.of(id))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + String id = CTypeUtil.toString(idPtr); + params.addConfiguredReactiveSlackBuses(List.of(id)); + } + }); } @CEntryPoint(name = "voltageInitializerSetObjective") public static void setObjective(IsolateThread thread, ObjectHandle paramsHandle, VoltageInitializerObjective cObjective, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setObjective(Util.convert(cObjective))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setObjective(Util.convert(cObjective)); + } + }); } @CEntryPoint(name = "voltageInitializerSetObjectiveDistance") public static void setObjectiveDistance(IsolateThread thread, ObjectHandle paramsHandle, double dist, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setObjectiveDistance(dist)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setObjectiveDistance(dist); + } + }); } @CEntryPoint(name = "voltageInitializerSetLogLevelAmpl") public static void setLogLevelAmpl(IsolateThread thread, ObjectHandle paramsHandle, VoltageInitializerLogLevelAmpl logLevelAmpl, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setLogLevelAmpl(Util.convert(logLevelAmpl))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setLogLevelAmpl(Util.convert(logLevelAmpl)); + } + }); } @CEntryPoint(name = "voltageInitializerSetLogLevelSolver") public static void setLogLevelSolver(IsolateThread thread, ObjectHandle paramsHandle, VoltageInitializerLogLevelSolver logLevelSolver, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setLogLevelSolver(Util.convert(logLevelSolver))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setLogLevelSolver(Util.convert(logLevelSolver)); + } + }); } @CEntryPoint(name = "voltageInitializerSetReactiveSlackBusesMode") public static void setReactiveSlackBusesMode(IsolateThread thread, ObjectHandle paramsHandle, VoltageInitializerReactiveSlackBusesMode reactiveSlackBusesMode, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setReactiveSlackBusesMode(Util.convert(reactiveSlackBusesMode))); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setReactiveSlackBusesMode(Util.convert(reactiveSlackBusesMode)); + } + }); } @CEntryPoint(name = "voltageInitializerSetMinPlausibleLowVoltageLimit") public static void voltageInitializerSetMinPlausibleLowVoltageLimit(IsolateThread thread, ObjectHandle paramsHandle, double minPlausibleLowVoltageLimit, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setMinPlausibleLowVoltageLimit(minPlausibleLowVoltageLimit)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setMinPlausibleLowVoltageLimit(minPlausibleLowVoltageLimit); + } + }); } @CEntryPoint(name = "voltageInitializerSetMaxPlausibleHighVoltageLimit") public static void voltageInitializerSetMaxPlausibleHighVoltageLimit(IsolateThread thread, ObjectHandle paramsHandle, double maxPlausibleHighVoltageLimit, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setMaxPlausibleHighVoltageLimit(maxPlausibleHighVoltageLimit)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setMaxPlausibleHighVoltageLimit(maxPlausibleHighVoltageLimit); + } + }); } @CEntryPoint(name = "voltageInitializerSetActivePowerVariationRate") public static void voltageInitializerSetActivePowerVariationRate(IsolateThread thread, ObjectHandle paramsHandle, double activePowerVariationRate, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setActivePowerVariationRate(activePowerVariationRate)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setActivePowerVariationRate(activePowerVariationRate); + } + }); } @CEntryPoint(name = "voltageInitializerSetMinPlausibleActivePowerThreshold") public static void voltageInitializerSetMinPlausibleActivePowerThreshold(IsolateThread thread, ObjectHandle paramsHandle, double minPlausibleActivePowerThreshold, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setMinPlausibleActivePowerThreshold(minPlausibleActivePowerThreshold)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setMinPlausibleActivePowerThreshold(minPlausibleActivePowerThreshold); + } + }); } @CEntryPoint(name = "voltageInitializerSetLowImpedanceThreshold") public static void voltageInitializerSetLowImpedanceThreshold(IsolateThread thread, ObjectHandle paramsHandle, double lowImpedanceThreshold, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setLowImpedanceThreshold(lowImpedanceThreshold)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setLowImpedanceThreshold(lowImpedanceThreshold); + } + }); } @CEntryPoint(name = "voltageInitializerSetMinNominalVoltageIgnoredBus") public static void voltageInitializerSetMinNominalVoltageIgnoredBus(IsolateThread thread, ObjectHandle paramsHandle, double minNominalVoltageIgnoredBus, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setMinNominalVoltageIgnoredBus(minNominalVoltageIgnoredBus)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setMinNominalVoltageIgnoredBus(minNominalVoltageIgnoredBus); + } + }); } @CEntryPoint(name = "voltageInitializerSetMinNominalVoltageIgnoredVoltageBounds") public static void voltageInitializerSetMinNominalVoltageIgnoredVoltageBounds(IsolateThread thread, ObjectHandle paramsHandle, double minNominalVoltageIgnoredVoltageBounds, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setMinNominalVoltageIgnoredVoltageBounds(minNominalVoltageIgnoredVoltageBounds)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setMinNominalVoltageIgnoredVoltageBounds(minNominalVoltageIgnoredVoltageBounds); + } + }); } @CEntryPoint(name = "voltageInitializerSetMaxPlausiblePowerLimit") public static void voltageInitializerSetMaxPlausiblePowerLimit(IsolateThread thread, ObjectHandle paramsHandle, double maxPlausiblePowerLimit, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setPQMax(maxPlausiblePowerLimit)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setPQMax(maxPlausiblePowerLimit); + } + }); } @CEntryPoint(name = "voltageInitializerSetDefaultMinimalQPRange") public static void voltageInitializerSetDefaultMinimalQPRange(IsolateThread thread, ObjectHandle paramsHandle, double defaultMinimalQPRange, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setDefaultMinimalQPRange(defaultMinimalQPRange)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setDefaultMinimalQPRange(defaultMinimalQPRange); + } + }); } @CEntryPoint(name = "voltageInitializerSetHighActivePowerDefaultLimit") public static void voltageInitializerSetHighActivePowerDefaultLimit(IsolateThread thread, ObjectHandle paramsHandle, double highActivePowerDefaultLimit, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setHighActivePowerDefaultLimit(highActivePowerDefaultLimit)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setHighActivePowerDefaultLimit(highActivePowerDefaultLimit); + } + }); } @CEntryPoint(name = "voltageInitializerSetLowActivePowerDefaultLimit") public static void voltageInitializerSetLowActivePowerDefaultLimit(IsolateThread thread, ObjectHandle paramsHandle, double lowActivePowerDefaultLimit, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setLowActivePowerDefaultLimit(lowActivePowerDefaultLimit)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setLowActivePowerDefaultLimit(lowActivePowerDefaultLimit); + } + }); } @CEntryPoint(name = "voltageInitializerSetDefaultQmaxPmaxRatio") public static void voltageInitializerSetDefaultQmaxPmaxRatio(IsolateThread thread, ObjectHandle paramsHandle, double defaultQmaxPmaxRatio, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setDefaultQmaxPmaxRatio(defaultQmaxPmaxRatio)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setDefaultQmaxPmaxRatio(defaultQmaxPmaxRatio); + } + }); } @CEntryPoint(name = "voltageInitializerSetDefaultVariableScalingFactor") public static void setDefaultVariableScalingFactor(IsolateThread thread, ObjectHandle paramsHandle, double defaultVariableScalingFactor, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setDefaultVariableScalingFactor(defaultVariableScalingFactor)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setDefaultVariableScalingFactor(defaultVariableScalingFactor); + } + }); } @CEntryPoint(name = "voltageInitializerSetDefaultConstraintScalingFactor") public static void setDefaultConstraintScalingFactor(IsolateThread thread, ObjectHandle paramsHandle, double defaultConstraintScalingFactor, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setDefaultConstraintScalingFactor(defaultConstraintScalingFactor)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setDefaultConstraintScalingFactor(defaultConstraintScalingFactor); + } + }); } @CEntryPoint(name = "voltageInitializerSetReactiveSlackVariableScalingFactor") public static void setReactiveSlackVariableScalingFactor(IsolateThread thread, ObjectHandle paramsHandle, double reactiveSlackVariableScalingFactor, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setReactiveSlackVariableScalingFactor(reactiveSlackVariableScalingFactor)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setReactiveSlackVariableScalingFactor(reactiveSlackVariableScalingFactor); + } + }); } @CEntryPoint(name = "voltageInitializerSetTwoWindingTransformerRatioVariableScalingFactor") public static void setTwoWindingTransformerRatioVariableScalingFactor(IsolateThread thread, ObjectHandle paramsHandle, double twoWindingTransformerRatioVariableScalingFactor, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - doCatch(exceptionHandlerPtr, () -> params.setTwoWindingTransformerRatioVariableScalingFactor(twoWindingTransformerRatioVariableScalingFactor)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + params.setTwoWindingTransformerRatioVariableScalingFactor(twoWindingTransformerRatioVariableScalingFactor); + } + }); } @CEntryPoint(name = "voltageInitializerApplyAllModifications") public static void applyAllModifications(IsolateThread thread, ObjectHandle resultHandle, ObjectHandle networkHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacResult result = ObjectHandles.getGlobal().get(resultHandle); - Network network = ObjectHandles.getGlobal().get(networkHandle); - doCatch(exceptionHandlerPtr, () -> result.applyAllModifications(network)); + doCatch(exceptionHandlerPtr, new Runnable() { + @Override + public void run() { + OpenReacResult result = ObjectHandles.getGlobal().get(resultHandle); + Network network = ObjectHandles.getGlobal().get(networkHandle); + result.applyAllModifications(network); + } + }); } @CEntryPoint(name = "voltageInitializerGetStatus") public static VoltageInitializerStatus getStatus(IsolateThread thread, ObjectHandle resultHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacResult result = ObjectHandles.getGlobal().get(resultHandle); - return doCatch(exceptionHandlerPtr, () -> Util.convert(result.getStatus())); + return doCatch(exceptionHandlerPtr, new Supplier() { + @Override + public VoltageInitializerStatus get() { + OpenReacResult result = ObjectHandles.getGlobal().get(resultHandle); + return Util.convert(result.getStatus()); + } + }); } @CEntryPoint(name = "voltageInitializerGetIndicators") public static StringMap getIndicators(IsolateThread thread, ObjectHandle resultHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - OpenReacResult result = ObjectHandles.getGlobal().get(resultHandle); - return doCatch(exceptionHandlerPtr, () -> CTypeUtil.fromStringMap(result.getIndicators())); + return doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public StringMap get() { + OpenReacResult result = ObjectHandles.getGlobal().get(resultHandle); + return CTypeUtil.fromStringMap(result.getIndicators()); + } + }); } @CEntryPoint(name = "runVoltageInitializer") public static ObjectHandle runVoltageInitializer(IsolateThread thread, boolean debug, ObjectHandle networkHandle, ObjectHandle paramsHandle, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { - return Util.doCatch(exceptionHandlerPtr, () -> { - Network network = ObjectHandles.getGlobal().get(networkHandle); - OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); - - logger().info("Running voltage initializer"); - OpenReacResult result = OpenReacRunner.run(network, network.getVariantManager().getWorkingVariantId(), params, - new OpenReacConfig(debug), LocalComputationManager.getDefault()); - logger().info("Voltage initializer run done"); - - return ObjectHandles.getGlobal().create(result); + return Util.doCatch(exceptionHandlerPtr, new PointerProvider() { + @Override + public ObjectHandle get() { + Network network = ObjectHandles.getGlobal().get(networkHandle); + OpenReacParameters params = ObjectHandles.getGlobal().get(paramsHandle); + + logger().info("Running voltage initializer"); + OpenReacResult result = OpenReacRunner.run(network, network.getVariantManager().getWorkingVariantId(), params, + new OpenReacConfig(debug), LocalComputationManager.getDefault()); + logger().info("Voltage initializer run done"); + + return ObjectHandles.getGlobal().create(result); + } }); } diff --git a/java/src/main/resources/META-INF/native-image/com.powsybl/powsybl-iidm-api/resource-config.json b/java/src/main/resources/META-INF/native-image/com.powsybl/powsybl-iidm-api/resource-config.json index 2fb37a1b4..8c96a4cda 100644 --- a/java/src/main/resources/META-INF/native-image/com.powsybl/powsybl-iidm-api/resource-config.json +++ b/java/src/main/resources/META-INF/native-image/com.powsybl/powsybl-iidm-api/resource-config.json @@ -2,6 +2,7 @@ "resources":{ "includes":[ {"pattern":"\\QMETA-INF/services/com.powsybl.iidm.network.NetworkFactoryService\\E"}, - {"pattern":"\\QMETA-INF/services/com.powsybl.iidm.network.Importer\\E"} + {"pattern":"\\QMETA-INF/services/com.powsybl.iidm.network.Importer\\E"}, + {"pattern":"\\QMETA-INF/services/com.powsybl.iidm.network.Exporter\\E"} ]} } diff --git a/java/src/main/resources/META-INF/native-image/com.powsybl/powsybl-iidm-converter-api/resource-config.json b/java/src/main/resources/META-INF/native-image/com.powsybl/powsybl-iidm-converter-api/resource-config.json deleted file mode 100644 index bec778e91..000000000 --- a/java/src/main/resources/META-INF/native-image/com.powsybl/powsybl-iidm-converter-api/resource-config.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "resources":{ - "includes":[ - {"pattern":"\\QMETA-INF/services/com.powsybl.iidm.export.Exporter\\E"}, - {"pattern":"\\QMETA-INF/services/com.powsybl.iidm.import_.Importer\\E"} - ]} -} From 29887a0cbe35100c9310adfad6c3e01dcc6a215f Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Tue, 10 Sep 2024 14:57:30 +0200 Subject: [PATCH 43/45] Wip Signed-off-by: Geoffroy Jamgotchian --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 44cf8c99c..c63af0cdf 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Requirements: - Cmake >= 3.14 - C++11 compiler - Python >= 3.8 for Linux, Windows and MacOS (amd64 and arm64) -- [Oracle GraalVM Java 22](https://www.graalvm.org/downloads/) +- [Oracle GraalVM Java 21](https://www.graalvm.org/downloads/) To build from sources and install PyPowSyBl package: From 603aeef24facff98d4316ac1e97f8ca78a8e0173 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Tue, 10 Sep 2024 15:18:34 +0200 Subject: [PATCH 44/45] Wip Signed-off-by: Geoffroy Jamgotchian --- cpp/powsybl-cpp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/powsybl-cpp/CMakeLists.txt b/cpp/powsybl-cpp/CMakeLists.txt index 7cfeb7fc1..a1da86b6f 100644 --- a/cpp/powsybl-cpp/CMakeLists.txt +++ b/cpp/powsybl-cpp/CMakeLists.txt @@ -78,7 +78,7 @@ ExternalProject_Add(native-image DEPENDS mvn SOURCE_DIR ${PYPOWSYBL_JAVA_BIN_DIR} DOWNLOAD_COMMAND "" - PATCH_COMMAND $ENV{JAVA_HOME}/bin/native-image ${NATIVE_IMAGE_BUILD_OPTIONS} --class-path ${PYPOWSYBL_JAVA_SRC_DIR}/target/pypowsybl-java.jar${EXTRA_JARS} -march=compatibility --no-fallback --shared --gc=${NATIVE_IMAGE_GC} -o pypowsybl-java -H:CLibraryPath=${CMAKE_CURRENT_SOURCE_DIR} --add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.c=ALL-UNNAMED CONFIGURE_COMMAND "" + PATCH_COMMAND $ENV{JAVA_HOME}/bin/native-image ${NATIVE_IMAGE_BUILD_OPTIONS} --class-path ${PYPOWSYBL_JAVA_SRC_DIR}/target/pypowsybl-java.jar${EXTRA_JARS} -march=compatibility --no-fallback --shared --gc=${NATIVE_IMAGE_GC} -o pypowsybl-java -H:CLibraryPath=${CMAKE_CURRENT_SOURCE_DIR} --add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.c=ALL-UNNAMED CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_OLD_LIB} ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_LIB} ${NATIVE_IMAGE_INSTALL_EXTRA_COMMAND} From 30a396c5bf2ddb0fc3a3d4268bc1cfb114aab5c8 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 11 Sep 2024 16:34:18 +0200 Subject: [PATCH 45/45] Fix Signed-off-by: Geoffroy Jamgotchian --- cpp/pypowsybl-java/CMakeLists.txt | 2 +- .../powsybl/python/network/NetworkCFunctions.java | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/cpp/pypowsybl-java/CMakeLists.txt b/cpp/pypowsybl-java/CMakeLists.txt index 7678717a7..39ecd7b1f 100644 --- a/cpp/pypowsybl-java/CMakeLists.txt +++ b/cpp/pypowsybl-java/CMakeLists.txt @@ -72,7 +72,7 @@ ExternalProject_Add(native-image DEPENDS mvn SOURCE_DIR ${PYPOWSYBL_JAVA_BIN_DIR} DOWNLOAD_COMMAND "" - PATCH_COMMAND $ENV{JAVA_HOME}/bin/native-image ${NATIVE_IMAGE_BUILD_OPTIONS} --class-path ${PYPOWSYBL_JAVA_SRC_DIR}/target/pypowsybl-java.jar${EXTRA_JARS} -march=compatibility --no-fallback --shared --gc=${NATIVE_IMAGE_GC} -H:Name=pypowsybl-java -H:CLibraryPath=${CMAKE_CURRENT_SOURCE_DIR} + PATCH_COMMAND $ENV{JAVA_HOME}/bin/native-image ${NATIVE_IMAGE_BUILD_OPTIONS} --class-path ${PYPOWSYBL_JAVA_SRC_DIR}/target/pypowsybl-java.jar${EXTRA_JARS} -march=compatibility --no-fallback --shared --gc=${NATIVE_IMAGE_GC} -o pypowsybl-java -H:CLibraryPath=${CMAKE_CURRENT_SOURCE_DIR} --add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.c=ALL-UNNAMED CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_OLD_LIB} ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_LIB} ${NATIVE_IMAGE_INSTALL_EXTRA_COMMAND} diff --git a/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java b/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java index 87cce2905..a87b24e5c 100644 --- a/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java +++ b/java/src/main/java/com/powsybl/python/network/NetworkCFunctions.java @@ -89,12 +89,22 @@ private NetworkCFunctions() { @CEntryPoint(name = "getNetworkImportFormats") public static ArrayPointer getNetworkImportFormats(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> createCharPtrArray(Importer.getFormats().stream().sorted().toList())); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + return createCharPtrArray(Importer.getFormats().stream().sorted().toList()); + } + }); } @CEntryPoint(name = "getNetworkExportFormats") public static ArrayPointer getNetworkExportFormats(IsolateThread thread, ExceptionHandlerPointer exceptionHandlerPtr) { - return doCatch(exceptionHandlerPtr, () -> createCharPtrArray(Exporter.getFormats().stream().sorted().toList())); + return doCatch(exceptionHandlerPtr, new PointerProvider>() { + @Override + public ArrayPointer get() { + return createCharPtrArray(Exporter.getFormats().stream().sorted().toList()); + } + }); } @CEntryPoint(name = "createNetwork")