diff --git a/.circleci/config.yml b/.circleci/config.yml index fedaa1d..b15ccf2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -117,8 +117,8 @@ jobs: resource_class: small steps: - checkout - - run: apt-get update && apt-get install python3-pip -y - - run: python3 -m pip install virtualenv + - run: apt-get update && apt-get install python3-pip python3-virtualenv -y + # - run: python3 -m pip install virtualenv - run: python3 -m virtualenv venv_test - run: name: "Install grid2op from source" @@ -183,7 +183,7 @@ jobs: resource_class: small steps: - checkout - - run: apt-get update && apt-get install python3-pip -y + - run: apt-get update && apt-get install python3-pip git -y - run: python3 -m pip install virtualenv - run: python3 -m virtualenv venv_test - run: @@ -201,7 +201,7 @@ jobs: resource_class: small steps: - checkout - - run: apt-get update && apt-get install python3-pip -y + - run: apt-get update && apt-get install python3-pip git -y - run: python3 -m pip install virtualenv - run: python3 -m virtualenv venv_test - run: @@ -219,7 +219,7 @@ jobs: resource_class: small steps: - checkout - - run: apt-get update && apt-get install python3-pip -y + - run: apt-get update && apt-get install python3-pip git -y - run: python3 -m pip install virtualenv - run: python3 -m virtualenv venv_test - run: @@ -237,7 +237,7 @@ jobs: resource_class: small steps: - checkout - - run: apt-get update && apt-get install python3-pip -y + - run: apt-get update && apt-get install python3-pip git -y - run: python3 -m pip install virtualenv - run: python3 -m virtualenv venv_test - run: @@ -268,11 +268,17 @@ jobs: size: medium # ("medium" "large" "xlarge" "2xlarge") steps: - checkout - # - run: - # name: "Install Python" - # command: choco install python --version=3.9 # use python 3.9 for windows test - - run: py -m pip install virtualenv - - run: py -m virtualenv venv_test + - run: choco install python --version=3.10 --force -y + - run: C:\Python310\python --version + - run: C:\Python310\python -m pip install --upgrade pip setuptools wheel + - run: C:\Python310\python -m pip install virtualenv + - run: C:\Python310\python -m virtualenv venv_test + - run: + name: "Chekc python / pip version in venv" + command: | + .\venv_test\Scripts\activate + python --version + pip --version - run: name: "Install grid2op from source" command: | @@ -286,8 +292,8 @@ jobs: pip install -U pybind11 git submodule init git submodule update - py setup.py build - py -m pip install -e .[test] + python setup.py build + python -m pip install -e .[test] - run: name: "make tests" command: | @@ -295,6 +301,7 @@ jobs: cd lightsim2grid\tests python -m unittest discover -v + workflows: version: 2.1 compile: @@ -307,4 +314,4 @@ workflows: - compile_clang11 - compile_clang13 - compile_clang14 - - compile_windows + - compile_windows \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cf497c0..7227298 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,6 +9,7 @@ on: jobs: manylinux_build: + # build wheels for some linux name: Build linux ${{ matrix.python.name }} wheel runs-on: ubuntu-latest container: quay.io/pypa/manylinux2014_x86_64 @@ -40,11 +41,16 @@ jobs: abi: cp311, version: '3.11', } + - { + name: cp312, + abi: cp312, + version: '3.12', + } steps: - name: Checkout sources - uses: actions/checkout@v1 + uses: actions/checkout@v3 with: submodules: true @@ -61,45 +67,64 @@ jobs: - name: Build wheel run: | - export __O3_OPTIM=1 + # export __O3_OPTIM=1 python3 setup.py bdist_wheel auditwheel repair dist/*.whl + - name: Build source archive + if: matrix.python.name == 'cp311' + run: python setup.py sdist + - name: Install wheel run: pip3 install wheelhouse/*.whl --user + # - name: Install GDB + # run: yum install -y gdb + - name: Check package can be imported run: | python3 -c "import lightsim2grid" python3 -c "from lightsim2grid import *" python3 -c "from lightsim2grid.newtonpf import newtonpf" + + - name: Fix urllib3 (python 3.7) + if: matrix.python.name == 'cp37' + run: + pip install urllib3==1.26.6 + # otherwise urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'OpenSSL 1.0.2k-fips 26 Jan 2017' - - name: Check LightSimBackend can be imported - run: | + - name: Check LightSimBackend can be imported (install grid2op) + run: | python3 -m pip install grid2op - python3 -c "from lightsim2grid import LightSimBackend" - python3 -c "from lightsim2grid import LightSimBackend; import grid2op; env = grid2op.make('l2rpn_case14_sandbox', test=True, backend=LightSimBackend())" + python3 -m pip freeze + + - name: Check LightSimBackend can be imported 1 + run: + python3 -v -c "from lightsim2grid import LightSimBackend" + + - name: Check LightSimBackend can be imported 2 + run: + python3 -v -c "from lightsim2grid import LightSimBackend; import grid2op; env = grid2op.make('l2rpn_case14_sandbox', test=True, backend=LightSimBackend())" - name: Upload wheel - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: lightsim2grid-wheel-linux-${{ matrix.python.name }} path: wheelhouse/*.whl - macos_windows_build: - name: Build ${{ matrix.config.name }} ${{ matrix.python.name }} wheel - runs-on: ${{ matrix.config.os }} + - name: Upload source archive + uses: actions/upload-artifact@v3 + if: matrix.python.name == 'cp311' + with: + name: lightsim2grid-sources + path: dist/*.tar.gz + + windows_build: + # build wheels for windows + name: Build windows ${{ matrix.python.name }} wheel + runs-on: windows-2019 strategy: matrix: - config: - - { - name: darwin, - os: macos-latest, - } - - { - name: windows, - os: windows-2019, - } python: - { name: cp37, @@ -121,33 +146,33 @@ jobs: name: cp311, version: '3.11', } + - { + name: cp312, + version: '3.12', + } + env: + RUNNER_OS: windows-2019 + PYTHON_VERSION: ${{ matrix.python.version }} steps: - name: Checkout sources - uses: actions/checkout@v1 + uses: actions/checkout@v3 with: submodules: true - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python.version }} - name: Install Python dependencies run: | python -m pip install --upgrade pip + python -m pip install --upgrade setuptools python -m pip install -r requirements.txt - - name: Compile SuiteSparse make - if: matrix.config.name == 'darwin' - run: | - make - export __O3_OPTIM=1 - python3 setup.py build - - name: Compile SuiteSparse cmake - if: matrix.config.name == 'windows' run: | cd build_cmake python generate_c_files.py @@ -164,10 +189,6 @@ jobs: - name: Build wheel run: python setup.py bdist_wheel - - name: Build source archive - if: matrix.config.name == 'darwin' && matrix.python.name == 'cp39' - run: python setup.py sdist - - name: Install wheel shell: bash run: python -m pip install dist/*.whl --user @@ -185,33 +206,158 @@ jobs: python -c "from lightsim2grid import LightSimBackend; import grid2op; env = grid2op.make('l2rpn_case14_sandbox', test=True, backend=LightSimBackend())" - name: Upload wheel - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: lightsim2grid-wheel-${{ matrix.config.name }}-${{ matrix.python.name }} path: dist/*.whl - - name: Upload source archive - uses: actions/upload-artifact@v2 - if: matrix.config.name == 'darwin' && matrix.python.name == 'cp39' + macos_build_37: + # build wheel for python 3.7 for macos + name: Build macos ${{ matrix.python.name }} wheel + runs-on: macos-latest + strategy: + matrix: + python: + - { + name: cp37, + version: '3.7', + } + steps: + - name: Checkout sources + uses: actions/checkout@v3 with: - name: lightsim2grid-sources - path: dist/*.tar.gz + submodules: true + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python.version }} + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + python -m pip install -r requirements.txt + + - name: Compile SuiteSparse make + run: | + make + export __O3_OPTIM=1 + python3 setup.py build + + - name: Build wheel + run: python setup.py bdist_wheel + + - name: Install wheel + shell: bash + run: python -m pip install dist/*.whl --user + + - name: Check package can be imported + run: | + python -c "import lightsim2grid" + python -c "from lightsim2grid import *" + python -c "from lightsim2grid.newtonpf import newtonpf" + + - name: Check LightSimBackend can be imported + run: | + python -m pip install grid2op + python -c "from lightsim2grid import LightSimBackend" + python -c "from lightsim2grid import LightSimBackend; import grid2op; env = grid2op.make('l2rpn_case14_sandbox', test=True, backend=LightSimBackend())" + + - name: Upload wheel + uses: actions/upload-artifact@v3 + with: + name: lightsim2grid-wheel-darwin-${{ matrix.python.name }} + path: dist/*.whl + + macos_build_38_: + # build wheel for python 3.8 and above for macos + name: Build darwin ${{ matrix.python.name }} wheel + runs-on: macos-latest + strategy: + matrix: + python: + - { + name: cp38, + version: '3.8', + } + - { + name: cp39, + version: '3.9', + } + - { + name: cp310, + version: '3.10', + } + - { + name: cp311, + version: '3.11', + } + - { + name: cp312, + version: '3.12', + } + env: + RUNNER_OS: macos-latest + PYTHON_VERSION: ${{ matrix.python.version }} + + steps: + + - name: Checkout sources + uses: actions/checkout@v3 + with: + submodules: true + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python.version }} + + - name: Set Additional Envs + shell: bash + run: | + echo "PYTHON_SUBVERSION=$(echo $PYTHON_VERSION | cut -c 3-)" >> $GITHUB_ENV + echo "DEPLOY=$( [[ $GITHUB_EVENT_NAME == 'push' && $GITHUB_REF == 'refs/tags'* ]] && echo 'True' || echo 'False' )" >> $GITHUB_ENV + + - name: Compile with cibuildwheel + uses: pypa/cibuildwheel@v2.16.2 + env: + CIBW_BUILD: "cp3${{env.PYTHON_SUBVERSION}}-*" # see https://github.com/cvxpy/cvxpy/blob/master/.github/workflows/build.yml + CIBW_ARCHS_LINUX: auto aarch64 # not used I believe + CIBW_ARCHS_MACOS: x86_64 arm64 + CIBW_ENVIRONMENT: __O3_OPTIM=1 + CIBW_BEFORE_ALL: python -m pip install --upgrade setuptools wheel pybind11 + CIBW_BEFORE_BUILD: make clean && make CC=clang CXX=clang++ # and not CIBW_BEFORE_ALL ! + CIBW_TEST_REQUIRES: grid2op pandapower + CIBW_TEST_SKIP: "cp312-* *-macosx_arm64" # to silence warning "While arm64 wheels can be built on x86_64, they cannot be tested." + CIBW_TEST_COMMAND: > + python -c "import lightsim2grid" && + python -c "from lightsim2grid import *" && + python -c "from lightsim2grid.newtonpf import newtonpf" && + python -c "from lightsim2grid.solver import KLUSolver" && + python -c "from lightsim2grid import LightSimBackend" && + python -c "from lightsim2grid import LightSimBackend; import grid2op; env = grid2op.make('l2rpn_case14_sandbox', test=True, backend=LightSimBackend())" + + - name: Upload wheel + uses: actions/upload-artifact@v3 + with: + name: wheels-darwin-${{ matrix.python.name }} + path: ./wheelhouse/*.whl package: name: Package wheels runs-on: ubuntu-latest - needs: [manylinux_build, macos_windows_build] + needs: [manylinux_build, windows_build, macos_build_37, macos_build_38_] steps: - name: Download wheels - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: path: download - name: Upload wheels - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: lightsim2grid-wheels path: | download/**/*.whl - download/**/*.tar.gz + download/**/*.tar.gz \ No newline at end of file diff --git a/.readthedocs.yml b/.readthedocs.yml index 97df330..ab6ff9c 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,4 +1,4 @@ -version: 2 +version: "2" submodules: include: @@ -6,8 +6,15 @@ submodules: - eigen recursive: true +build: + os: "ubuntu-22.04" + tools: + python: "3.10" + +sphinx: + configuration: docs/conf.py + python: - version: 3.8 install: - method: pip path: . diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 31f58a6..b704f22 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,11 @@ Change Log - easier building (get rid of the "make" part) - code NR with dense matrices +[0.7.1.post1] 2024-03-14 +-------------------------- +- [FIXED] 'forward' compatibility with grid2op 1.10.0 by making the `copy()` + implementation of lightsim2grid more generic + [0.7.1] 2023-01-11 --------------------- - [BREAKING] drop support for numpy version < 1.20 (to be consistent with grid2op) diff --git a/docs/conf.py b/docs/conf.py index 73d4b53..2e95a35 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ author = 'Benjamin DONNOT' # The full version, including alpha/beta/rc tags -release = '0.7.1' +release = '0.7.1.post1' version = '0.7' # -- General configuration --------------------------------------------------- diff --git a/lightsim2grid/__init__.py b/lightsim2grid/__init__.py index 5cfd33b..c9d1945 100644 --- a/lightsim2grid/__init__.py +++ b/lightsim2grid/__init__.py @@ -6,7 +6,7 @@ # SPDX-License-Identifier: MPL-2.0 # This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform. -__version__ = "0.7.1" +__version__ = "0.7.1.post1" __all__ = ["newtonpf", "SolverType", "ErrorType", "solver"] diff --git a/lightsim2grid/lightSimBackend.py b/lightsim2grid/lightSimBackend.py index 81ae11d..47fc1a1 100644 --- a/lightsim2grid/lightSimBackend.py +++ b/lightsim2grid/lightSimBackend.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020, RTE (https://www.rte-france.com) +# Copyright (c) 2020-2024, RTE (https://www.rte-france.com) # See AUTHORS.txt # This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0. # If a copy of the Mozilla Public License, version 2.0 was not distributed with this file, @@ -33,20 +33,17 @@ def __init__(self, max_iter: int=10, tol: float=1e-8, solver_type: Optional[SolverType] =None): - try: - # for grid2Op >= 1.7.1 - Backend.__init__(self, - detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures, - can_be_copied=can_be_copied, - solver_type=solver_type, - max_iter=max_iter, - tol=tol) - except TypeError as exc_: - warnings.warn("Please use grid2op >= 1.7.1: with older grid2op versions, " - "you cannot set max_iter, tol nor solver_type arguments.") - Backend.__init__(self, - detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) + self.max_it = max_iter + self.tol = tol # tolerance for the solver + self._check_suitable_solver_type(solver_type, check_in_avail_solver=False) + self.__current_solver_type = solver_type + self._aux_init_super(detailed_infos_for_cascading_failures, + can_be_copied, + solver_type, + max_iter, + tol) + # lazy loading because it crashes... from grid2op.Backend import PandaPowerBackend from grid2op.Space import GridObjects # lazy import @@ -55,6 +52,8 @@ def __init__(self, warnings.warn("Please upgrade your grid2Op to >= 1.5.0. You are using a backward compatibility " "feature that will be removed in further lightsim2grid version.") + self.shunts_data_available = True # needs to be self and not type(self) here + self.nb_bus_total = None self.initdc = True # does not really hurt computation time self.__nb_powerline = None @@ -78,8 +77,6 @@ def __init__(self, self.init_pp_backend = PandaPowerBackend() self.V = None - self.max_it = max_iter - self.tol = tol # tolerance for the solver self.prod_pu_to_kv = None self.load_pu_to_kv = None @@ -131,12 +128,20 @@ def __init__(self, # available solver in lightsim self.available_solvers = [] - self.comp_time = 0. # computation time of just the powerflow + + # computation time of just the powerflow (when the grid is formatted + # by the gridmodel already) + # it takes only into account the time spend in the powerflow algorithm + self.comp_time = 0. + + # computation time of the powerflow + # it takes into account everything in the gridmodel, including the mapping + # to the solver, building of Ybus and Sbus AND the time to solve the powerflow + self.timer_gridmodel_xx_pf = 0. + self._timer_postproc = 0. self._timer_preproc = 0. self._timer_solver = 0. - self._check_suitable_solver_type(solver_type, check_in_avail_solver=False) - self.__current_solver_type = solver_type # hack for the storage unit: # in grid2op, for simplicity, I suppose that if a storage is alone on a busbar, and @@ -149,6 +154,26 @@ def __init__(self, # backend SHOULD not do these kind of stuff self._idx_hack_storage = [] + def _aux_init_super(self, + detailed_infos_for_cascading_failures, + can_be_copied, + solver_type, + max_iter, + tol): + try: + # for grid2Op >= 1.7.1 + Backend.__init__(self, + detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures, + can_be_copied=can_be_copied, + solver_type=solver_type, + max_iter=max_iter + ) + except TypeError as exc_: + warnings.warn("Please use grid2op >= 1.7.1: with older grid2op versions, " + "you cannot set max_iter, tol nor solver_type arguments.") + Backend.__init__(self, + detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) + def _fill_theta(self): # line_or_theta = np.empty(self.n_line) self.line_or_theta[:self.__nb_powerline] = self._grid.get_lineor_theta() @@ -816,7 +841,16 @@ def copy(self): #################### # res = copy.deepcopy(self) # super slow res = type(self).__new__(type(self)) - + # make sure to init the "base class" + # in particular with "new" attributes in future grid2op Backend + res._aux_init_super(self.detailed_infos_for_cascading_failures, + self._can_be_copied, + self.__current_solver_type, + self.max_it, + self.tol) + res.comp_time = self.comp_time + res.timer_gridmodel_xx_pf = self.timer_gridmodel_xx_pf + # copy the regular attribute res.__has_storage = self.__has_storage res.__current_solver_type = self.__current_solver_type @@ -876,7 +910,7 @@ def copy(self): ] + type(self)._li_attr_disp for attr_nm in cls_attr: - if hasattr(self, attr_nm): + if hasattr(self, attr_nm) and not hasattr(type(self), attr_nm): # this test is needed for backward compatibility with other grid2op version setattr(res, attr_nm, copy.deepcopy(getattr(self, attr_nm))) ############### diff --git a/lightsim2grid/tests/test_DCPF.py b/lightsim2grid/tests/test_DCPF.py index 4570815..cce31e7 100644 --- a/lightsim2grid/tests/test_DCPF.py +++ b/lightsim2grid/tests/test_DCPF.py @@ -124,9 +124,13 @@ def _aux_test(self, pn_net): real_init_file = pp.from_json(case_name) backend = LightSimBackend() + type(backend)._clear_grid_dependant_class_attributes() with warnings.catch_warnings(): warnings.filterwarnings("ignore") + type(backend).env_name = pn_net backend.load_grid(case_name) + backend.assert_grid_correct() + # backend.init_pp_backend.assert_grid_correct() nb_sub = backend.n_sub pp_net = backend.init_pp_backend._grid diff --git a/lightsim2grid/tests/test_LightSimBackend.py b/lightsim2grid/tests/test_LightSimBackend.py index 5d92105..6f5fd5d 100644 --- a/lightsim2grid/tests/test_LightSimBackend.py +++ b/lightsim2grid/tests/test_LightSimBackend.py @@ -12,20 +12,58 @@ import warnings import grid2op import numpy as np +from packaging import version from grid2op.tests.helper_path_test import PATH_DATA_TEST_PP, PATH_DATA_TEST from grid2op.Space import GridObjects # lazy import __has_storage = hasattr(GridObjects, "n_storage") -from grid2op.tests.helper_path_test import HelperTests -from grid2op.tests.BaseBackendTest import BaseTestNames, BaseTestLoadingCase, BaseTestLoadingBackendFunc -from grid2op.tests.BaseBackendTest import BaseTestTopoAction, BaseTestEnvPerformsCorrectCascadingFailures -from grid2op.tests.BaseBackendTest import BaseTestChangeBusAffectRightBus, BaseTestShuntAction -from grid2op.tests.BaseBackendTest import BaseTestResetEqualsLoadGrid, BaseTestVoltageOWhenDisco, BaseTestChangeBusSlack -from grid2op.tests.BaseBackendTest import BaseIssuesTest, BaseStatusActions -from grid2op.tests.test_Environment import TestLoadingBackendPandaPower, TestResetOk -from grid2op.tests.test_Environment import TestResetAfterCascadingFailure, TestCascadingFailure +try: + # new way of doing, does not need to inherit from HelperTests but from unittest.TestCase + from grid2op._create_test_suite import create_test_suite + from grid2op.tests.helper_path_test import HelperTests as DEPRECATEDHelper + + class _Garbage: + def setUp(self): + pass + + class _SuperGarbage(DEPRECATEDHelper, _Garbage): + pass + + _garbage = _SuperGarbage() + _garbage.setUp() + + class HelperTests(unittest.TestCase): + def setUp(self) -> None: + self.tol_one = _garbage.tol_one + self.tolvect = _garbage.tolvect + return super().setUp() + + def tearDown(self) -> None: + return super().tearDown() + +except ImportError as exc_: + # old way of doing, need to inherit from that + from grid2op.tests.helper_path_test import HelperTests + +from grid2op.tests.BaseBackendTest import (BaseTestNames, + BaseTestLoadingCase, + BaseTestLoadingBackendFunc, + BaseTestTopoAction, + BaseTestEnvPerformsCorrectCascadingFailures, + BaseTestChangeBusAffectRightBus, + BaseTestShuntAction, + BaseTestResetEqualsLoadGrid, + BaseTestVoltageOWhenDisco, + BaseTestChangeBusSlack, + BaseIssuesTest, + BaseStatusActions) + +from grid2op.tests.test_Environment import (BaseTestLoadingBackendPandaPower, + BaseTestResetOk, + BaseTestResetAfterCascadingFailure, + BaseTestCascadingFailure) if __has_storage: from grid2op.tests.BaseBackendTest import BaseTestStorageAction @@ -36,32 +74,24 @@ from lightsim2grid.solver import SolverType from grid2op.Runner import Runner -class TestNames(HelperTests, BaseTestNames): + +class TestNames(BaseTestNames, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") bk = LightSimBackend(detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) return bk - def get_path(self): - return PATH_DATA_TEST_INIT - -class TestLoadingCase(HelperTests, BaseTestLoadingCase): +class TestLoadingCase(BaseTestLoadingCase, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") bk = LightSimBackend(detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) return bk - def get_path(self): - return PATH_DATA_TEST - - def get_casefile(self): - return "test_case14.json" - -class TestLoadingBackendFunc(HelperTests, BaseTestLoadingBackendFunc): +class TestLoadingBackendFunc(BaseTestLoadingBackendFunc, unittest.TestCase): def setUp(self): # TODO find something more elegant BaseTestLoadingBackendFunc.setUp(self) @@ -83,14 +113,8 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): bk = LightSimBackend(detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) return bk - def get_path(self): - return PATH_DATA_TEST - - def get_casefile(self): - return "test_case14.json" - -class TestTopoAction(HelperTests, BaseTestTopoAction): +class TestTopoAction(BaseTestTopoAction, unittest.TestCase): def setUp(self): BaseTestTopoAction.setUp(self) @@ -104,14 +128,8 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): bk = LightSimBackend(detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) return bk - def get_path(self): - return PATH_DATA_TEST - def get_casefile(self): - return "test_case14.json" - - -class TestEnvPerformsCorrectCascadingFailures(HelperTests, BaseTestEnvPerformsCorrectCascadingFailures): +class TestEnvPerformsCorrectCascadingFailures(BaseTestEnvPerformsCorrectCascadingFailures, unittest.TestCase): def setUp(self): BaseTestEnvPerformsCorrectCascadingFailures.setUp(self) @@ -124,15 +142,9 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): warnings.filterwarnings("ignore") bk = LightSimBackend(detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) return bk + - def get_casefile(self): - return "test_case14.json" - - def get_path(self): - return PATH_DATA_TEST - - -class TestChangeBusAffectRightBus(HelperTests, BaseTestChangeBusAffectRightBus): +class TestChangeBusAffectRightBus(BaseTestChangeBusAffectRightBus, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") @@ -140,7 +152,7 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): return bk -class TestShuntAction(HelperTests, BaseTestShuntAction): +class TestShuntAction(BaseTestShuntAction, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") @@ -148,7 +160,7 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): return bk -class TestResetEqualsLoadGrid(HelperTests, BaseTestResetEqualsLoadGrid): +class TestResetEqualsLoadGrid(BaseTestResetEqualsLoadGrid, unittest.TestCase): def setUp(self): BaseTestResetEqualsLoadGrid.setUp(self) @@ -159,7 +171,7 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): return bk -class TestVoltageOWhenDisco(HelperTests, BaseTestVoltageOWhenDisco): +class TestVoltageOWhenDisco(BaseTestVoltageOWhenDisco, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") @@ -167,7 +179,7 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): return bk -class TestChangeBusSlack(HelperTests, BaseTestChangeBusSlack): +class TestChangeBusSlack(BaseTestChangeBusSlack, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") @@ -175,7 +187,8 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): return bk -class TestIssuesTest(HelperTests, BaseIssuesTest): +class TestIssuesTest(BaseIssuesTest, unittest.TestCase): + tests_skipped = ["test_issue_125"] if version.parse(grid2op.__version__) < version.parse("1.9.2") else [] def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") @@ -183,7 +196,7 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): return bk -class TestStatusAction(HelperTests, BaseStatusActions): +class TestStatusAction(BaseStatusActions, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") @@ -192,8 +205,9 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): if __has_storage: - class TestStorageAction(HelperTests, BaseTestStorageAction): + class TestStorageAction(BaseTestStorageAction, unittest.TestCase): def setUp(self): + super().setUp() self.tests_skipped = ["test_storage_action_topo"] # TODO this test is super weird ! It's like we impose # TODO a behaviour from pandapower (weird one) to all backends... @@ -204,22 +218,22 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): return bk -class TestLoadingBackendLightSim(TestLoadingBackendPandaPower): - def get_backend(self): - return LightSimBackend() +class TestLoadingBackendLightSim(BaseTestLoadingBackendPandaPower, unittest.TestCase): + def get_backend(self, detailed_infos_for_cascading_failures=True): + return LightSimBackend(detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) -class TestResetOkLS(TestResetOk): +class TestResetOkLS(BaseTestResetOk, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): return LightSimBackend(detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) -class TestResetAfterCascadingFailureLS(TestResetAfterCascadingFailure): +class TestResetAfterCascadingFailureLS(BaseTestResetAfterCascadingFailure, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): return LightSimBackend(detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) -class TestCascadingFailureLS(TestCascadingFailure): +class TestCascadingFailureLS(BaseTestCascadingFailure, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): return LightSimBackend(detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) diff --git a/lightsim2grid/tests/test_RedispatchEnv.py b/lightsim2grid/tests/test_RedispatchEnv.py index f49451b..0f5b5e0 100644 --- a/lightsim2grid/tests/test_RedispatchEnv.py +++ b/lightsim2grid/tests/test_RedispatchEnv.py @@ -5,75 +5,36 @@ # you can obtain one at http://mozilla.org/MPL/2.0/. # SPDX-License-Identifier: MPL-2.0 # This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform. + import unittest import warnings -from grid2op.tests.helper_path_test import PATH_DATA_TEST_PP, PATH_DATA_TEST - -from grid2op.tests.helper_path_test import HelperTests -from grid2op.tests.BaseRedispTest import BaseTestRedispatch, BaseTestRedispatchChangeNothingEnvironment -from grid2op.tests.BaseRedispTest import BaseTestRedispTooLowHigh, BaseTestDispatchRampingIllegalETC -from grid2op.tests.BaseRedispTest import BaseTestLoadingAcceptAlmostZeroSumRedisp +from grid2op.tests.BaseRedispTest import (BaseTestRedispatch, + BaseTestRedispatchChangeNothingEnvironment, + BaseTestRedispTooLowHigh, + BaseTestDispatchRampingIllegalETC, + BaseTestLoadingAcceptAlmostZeroSumRedisp) from lightsim2grid.lightSimBackend import LightSimBackend -PATH_DATA_TEST_INIT = PATH_DATA_TEST -PATH_DATA_TEST = PATH_DATA_TEST_PP - - -class TestRedispatch(HelperTests, BaseTestRedispatch): - def setUp(self): - # TODO find something more elegant - BaseTestRedispatch.setUp(self) - - def tearDown(self): - # TODO find something more elegant - BaseTestRedispatch.tearDown(self) +class TestRedispatch(BaseTestRedispatch, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") bk = LightSimBackend(detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) return bk - def get_path(self): - return PATH_DATA_TEST_PP - - def get_casefile(self): - return "test_case14.json" - - -class TestRedispatchChangeNothingEnvironment(HelperTests, BaseTestRedispatchChangeNothingEnvironment): - def setUp(self): - # TODO find something more elegant - BaseTestRedispatchChangeNothingEnvironment.setUp(self) - - def tearDown(self): - # TODO find something more elegant - BaseTestRedispatchChangeNothingEnvironment.tearDown(self) +class TestRedispatchChangeNothingEnvironment(BaseTestRedispatchChangeNothingEnvironment, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") bk = LightSimBackend(detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) return bk - def get_path(self): - return PATH_DATA_TEST_PP - - def get_casefile(self): - return "test_case14.json" - - -class TestRedispTooLowHigh(HelperTests, BaseTestRedispTooLowHigh): - def setUp(self): - # TODO find something more elegant - BaseTestRedispTooLowHigh.setUp(self) - - def tearDown(self): - # TODO find something more elegant - BaseTestRedispTooLowHigh.tearDown(self) +class TestRedispTooLowHigh(BaseTestRedispTooLowHigh, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") @@ -81,15 +42,7 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): return bk -class TestDispatchRampingIllegalETC(HelperTests, BaseTestDispatchRampingIllegalETC): - def setUp(self): - # TODO find something more elegant - BaseTestDispatchRampingIllegalETC.setUp(self) - - def tearDown(self): - # TODO find something more elegant - BaseTestDispatchRampingIllegalETC.tearDown(self) - +class TestDispatchRampingIllegalETC(BaseTestDispatchRampingIllegalETC, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") @@ -97,15 +50,7 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): return bk -class TestLoadingAcceptAlmostZeroSumRedisp(HelperTests, BaseTestLoadingAcceptAlmostZeroSumRedisp): - def setUp(self): - # TODO find something more elegant - BaseTestLoadingAcceptAlmostZeroSumRedisp.setUp(self) - - def tearDown(self): - # TODO find something more elegant - BaseTestLoadingAcceptAlmostZeroSumRedisp.tearDown(self) - +class TestLoadingAcceptAlmostZeroSumRedisp(BaseTestLoadingAcceptAlmostZeroSumRedisp, unittest.TestCase): def make_backend(self, detailed_infos_for_cascading_failures=False): with warnings.catch_warnings(): warnings.filterwarnings("ignore") @@ -114,4 +59,4 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/lightsim2grid/tests/test_Runner.py b/lightsim2grid/tests/test_Runner.py index e998a8d..9f7a497 100644 --- a/lightsim2grid/tests/test_Runner.py +++ b/lightsim2grid/tests/test_Runner.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020, RTE (https://www.rte-france.com) +# Copyright (c) 2020-2024, RTE (https://www.rte-france.com) # See AUTHORS.txt # This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0. # If a copy of the Mozilla Public License, version 2.0 was not distributed with this file, @@ -11,7 +11,7 @@ import grid2op from grid2op.tests.test_Runner import TestRunner as TestRunner_glop from grid2op.tests.test_RunnerFast import TestRunner as TestRunnerFast_glop -from grid2op.tests.test_Runner import HelperTests, L2RPNReward, make +from grid2op.tests.test_Runner import L2RPNReward from grid2op.Runner import Runner from lightsim2grid.lightSimBackend import LightSimBackend @@ -79,4 +79,4 @@ def setUp(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/setup.py b/setup.py index 6fc31a9..4209319 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ from pybind11.setup_helpers import Pybind11Extension, build_ext -__version__ = "0.7.1" +__version__ = "0.7.1.post1" KLU_SOLVER_AVAILABLE = False # Try to link against SuiteSparse (if available) diff --git a/src/DataGeneric.h b/src/DataGeneric.h index 048ee31..735bb77 100644 --- a/src/DataGeneric.h +++ b/src/DataGeneric.h @@ -132,7 +132,7 @@ class DataGeneric : public BaseConstants template void check_size(const T & container, intType size, const std::string & container_name) { - if(container.size() != size) throw std::runtime_error(container_name + " do not have the proper size"); + if(static_cast(container.size()) != size) throw std::runtime_error(container_name + " do not have the proper size"); } /** diff --git a/src/Solvers.h b/src/Solvers.h index d0b60a2..179d34a 100644 --- a/src/Solvers.h +++ b/src/Solvers.h @@ -6,6 +6,9 @@ // SPDX-License-Identifier: MPL-2.0 // This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform. +#ifndef SOLVERS_H +#define SOLVERS_H + #include "BaseNRSolver.h" #include "BaseNRSolverSingleSlack.h" #include "DCSolver.h" @@ -54,3 +57,5 @@ typedef BaseDCSolver DCSolver; /** Solver based on Newton Raphson, using the KLU linear solver, only suitable for the DC approximation**/ class NICSLUDCSolver : public DCSolver{}; #endif // NICSLU_SOLVER_AVAILABLE + +#endif // SOLVERS_H